|
|
|
/*
|
|
|
|
This file is part of the KDE libraries
|
|
|
|
Copyright (c) 1999 Pietro Iglio <iglio@kde.org>
|
|
|
|
Copyright (c) 1999 Preston Brown <pbrown@kde.org>
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
// $Id$
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#include <tqfile.h>
|
|
|
|
#include <tqdir.h>
|
|
|
|
#include <tqtextstream.h>
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include "kurl.h"
|
|
|
|
#include "kconfigbackend.h"
|
|
|
|
#include "kapplication.h"
|
|
|
|
#include "kstandarddirs.h"
|
|
|
|
#include "kmountpoint.h"
|
|
|
|
#include "kcatalogue.h"
|
|
|
|
#include "klocale.h"
|
|
|
|
|
|
|
|
#include "kdesktopfile.h"
|
|
|
|
#include "kdesktopfile.moc"
|
|
|
|
|
|
|
|
KDesktopFile::KDesktopFile(const TQString &fileName, bool bReadOnly,
|
|
|
|
const char * resType)
|
|
|
|
: KConfig(TQString::tqfromLatin1(""), bReadOnly, false)
|
|
|
|
{
|
|
|
|
// KConfigBackEnd will try to locate the filename that is provided
|
|
|
|
// based on the resource type specified, _only_ if the filename
|
|
|
|
// is not an absolute path.
|
|
|
|
backEnd->changeFileName(fileName, resType, false);
|
|
|
|
setReadOnly(bReadOnly);
|
|
|
|
reparseConfiguration();
|
|
|
|
setDesktopGroup();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDesktopFile::~KDesktopFile()
|
|
|
|
{
|
|
|
|
// no need to do anything
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString KDesktopFile::locateLocal(const TQString &path)
|
|
|
|
{
|
|
|
|
TQString local;
|
|
|
|
if (path.endsWith(".directory"))
|
|
|
|
{
|
|
|
|
local = path;
|
|
|
|
if (!TQDir::isRelativePath(local))
|
|
|
|
{
|
|
|
|
// Relative wrt apps?
|
|
|
|
local = KGlobal::dirs()->relativeLocation("apps", path);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TQDir::isRelativePath(local))
|
|
|
|
{
|
|
|
|
local = ::locateLocal("apps", local); // Relative to apps
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// XDG Desktop menu items come with absolute paths, we need to
|
|
|
|
// extract their relative path and then build a local path.
|
|
|
|
local = KGlobal::dirs()->relativeLocation("xdgdata-dirs", local);
|
|
|
|
if (!TQDir::isRelativePath(local))
|
|
|
|
{
|
|
|
|
// Hm, that didn't work...
|
|
|
|
// What now? Use filename only and hope for the best.
|
|
|
|
local = path.mid(path.findRev('/')+1);
|
|
|
|
}
|
|
|
|
local = ::locateLocal("xdgdata-dirs", local);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (TQDir::isRelativePath(path))
|
|
|
|
{
|
|
|
|
local = ::locateLocal("apps", path); // Relative to apps
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// XDG Desktop menu items come with absolute paths, we need to
|
|
|
|
// extract their relative path and then build a local path.
|
|
|
|
local = KGlobal::dirs()->relativeLocation("xdgdata-apps", path);
|
|
|
|
if (!TQDir::isRelativePath(local))
|
|
|
|
{
|
|
|
|
// What now? Use filename only and hope for the best.
|
|
|
|
local = path.mid(path.findRev('/')+1);
|
|
|
|
}
|
|
|
|
local = ::locateLocal("xdgdata-apps", local);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return local;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KDesktopFile::isDesktopFile(const TQString& path)
|
|
|
|
{
|
|
|
|
int len = path.length();
|
|
|
|
|
|
|
|
if(len > 8 && path.right(8) == TQString::tqfromLatin1(".desktop"))
|
|
|
|
return true;
|
|
|
|
else if(len > 7 && path.right(7) == TQString::tqfromLatin1(".kdelnk"))
|
|
|
|
return true;
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KDesktopFile::isAuthorizedDesktopFile(const TQString& path)
|
|
|
|
{
|
|
|
|
if (!kapp || kapp->authorize("run_desktop_files"))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (path.isEmpty())
|
|
|
|
return false; // Empty paths are not ok.
|
|
|
|
|
|
|
|
if (TQDir::isRelativePath(path))
|
|
|
|
return true; // Relative paths are ok.
|
|
|
|
|
|
|
|
KStandardDirs *dirs = KGlobal::dirs();
|
|
|
|
if (TQDir::isRelativePath( dirs->relativeLocation("apps", path) ))
|
|
|
|
return true;
|
|
|
|
if (TQDir::isRelativePath( dirs->relativeLocation("xdgdata-apps", path) ))
|
|
|
|
return true;
|
|
|
|
if (TQDir::isRelativePath( dirs->relativeLocation("services", path) ))
|
|
|
|
return true;
|
|
|
|
if (dirs->relativeLocation("data", path).startsWith("kdesktop/Desktop"))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
kdWarning() << "Access to '" << path << "' denied because of 'run_desktop_files' restriction." << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString KDesktopFile::translatedEntry(const char* key) const
|
|
|
|
{
|
|
|
|
if (hasTranslatedKey(key))
|
|
|
|
return readEntry(key);
|
|
|
|
|
|
|
|
if (hasKey(key)) {
|
|
|
|
TQString value = readEntryUntranslated(key);
|
|
|
|
TQString fName = fileName();
|
|
|
|
fName = fName.mid(fName.findRev('/')+1);
|
|
|
|
TQString po_lookup_key = TQString::tqfromLatin1(key) + "(" + fName + "): " + value;
|
|
|
|
TQString po_value = KGlobal::locale()->translate(po_lookup_key.utf8().data());
|
|
|
|
|
|
|
|
if (po_value == po_lookup_key)
|
|
|
|
return value;
|
|
|
|
|
|
|
|
return po_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TQString::null;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString KDesktopFile::readType() const
|
|
|
|
{
|
|
|
|
return readEntry("Type");
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString KDesktopFile::readIcon() const
|
|
|
|
{
|
|
|
|
return readEntry("Icon");
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString KDesktopFile::readName() const
|
|
|
|
{
|
|
|
|
return translatedEntry("Name");
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString KDesktopFile::readComment() const
|
|
|
|
{
|
|
|
|
return translatedEntry("Comment");
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString KDesktopFile::readGenericName() const
|
|
|
|
{
|
|
|
|
return translatedEntry("GenericName");
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString KDesktopFile::readPath() const
|
|
|
|
{
|
|
|
|
return readPathEntry("Path");
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString KDesktopFile::readDevice() const
|
|
|
|
{
|
|
|
|
return readEntry("Dev");
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString KDesktopFile::readURL() const
|
|
|
|
{
|
|
|
|
if (hasDeviceType()) {
|
|
|
|
TQString device = readDevice();
|
|
|
|
KMountPoint::List mountPoints = KMountPoint::possibleMountPoints();
|
|
|
|
|
|
|
|
for(KMountPoint::List::ConstIterator it = mountPoints.begin();
|
|
|
|
it != mountPoints.end(); ++it)
|
|
|
|
{
|
|
|
|
KMountPoint *mp = *it;
|
|
|
|
if (mp->mountedFrom() == device)
|
|
|
|
{
|
|
|
|
KURL u;
|
|
|
|
u.setPath( mp->mountPoint() );
|
|
|
|
return u.url();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return TQString::null;
|
|
|
|
} else {
|
|
|
|
TQString url = readPathEntry("URL");
|
|
|
|
if ( !url.isEmpty() && !TQDir::isRelativePath(url) )
|
|
|
|
{
|
|
|
|
// Handle absolute paths as such (i.e. we need to escape them)
|
|
|
|
KURL u;
|
|
|
|
u.setPath( url );
|
|
|
|
return u.url();
|
|
|
|
}
|
|
|
|
return url;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TQStringList KDesktopFile::readActions() const
|
|
|
|
{
|
|
|
|
return readListEntry("Actions", ';');
|
|
|
|
}
|
|
|
|
|
|
|
|
void KDesktopFile::setActionGroup(const TQString &group)
|
|
|
|
{
|
|
|
|
setGroup(TQString::tqfromLatin1("Desktop Action ") + group);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KDesktopFile::hasActionGroup(const TQString &group) const
|
|
|
|
{
|
|
|
|
return hasGroup(TQString::tqfromLatin1("Desktop Action ") + group);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KDesktopFile::hasLinkType() const
|
|
|
|
{
|
|
|
|
return readEntry("Type") == TQString::tqfromLatin1("Link");
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KDesktopFile::hasApplicationType() const
|
|
|
|
{
|
|
|
|
return readEntry("Type") == TQString::tqfromLatin1("Application");
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KDesktopFile::hasMimeTypeType() const
|
|
|
|
{
|
|
|
|
return readEntry("Type") == TQString::tqfromLatin1("MimeType");
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KDesktopFile::hasDeviceType() const
|
|
|
|
{
|
|
|
|
return readEntry("Type") == TQString::tqfromLatin1("FSDev") ||
|
|
|
|
readEntry("Type") == TQString::tqfromLatin1("FSDevice");
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KDesktopFile::tryExec() const
|
|
|
|
{
|
|
|
|
// Test for TryExec and "X-KDE-AuthorizeAction"
|
|
|
|
TQString te = readPathEntry("TryExec");
|
|
|
|
|
|
|
|
if (!te.isEmpty()) {
|
|
|
|
if (!TQDir::isRelativePath(te)) {
|
|
|
|
if (::access(TQFile::encodeName(te), X_OK))
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
// !!! Sergey A. Sukiyazov <corwin@micom.don.ru> !!!
|
|
|
|
// Environment PATH may contain filenames in 8bit locale cpecified
|
|
|
|
// encoding (Like a filenames).
|
|
|
|
TQStringList dirs = TQStringList::split(':', TQFile::decodeName(::getenv("PATH")));
|
|
|
|
TQStringList::Iterator it(dirs.begin());
|
|
|
|
bool match = false;
|
|
|
|
for (; it != dirs.end(); ++it) {
|
|
|
|
TQString fName = *it + "/" + te;
|
|
|
|
if (::access(TQFile::encodeName(fName), X_OK) == 0)
|
|
|
|
{
|
|
|
|
match = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// didn't match at all
|
|
|
|
if (!match)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
TQStringList list = readListEntry("X-KDE-AuthorizeAction");
|
|
|
|
if (kapp && !list.isEmpty())
|
|
|
|
{
|
|
|
|
for(TQStringList::ConstIterator it = list.begin();
|
|
|
|
it != list.end();
|
|
|
|
++it)
|
|
|
|
{
|
|
|
|
if (!kapp->authorize((*it).stripWhiteSpace()))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// See also KService::username()
|
|
|
|
bool su = readBoolEntry("X-KDE-SubstituteUID");
|
|
|
|
if (su)
|
|
|
|
{
|
|
|
|
TQString user = readEntry("X-KDE-Username");
|
|
|
|
if (user.isEmpty())
|
|
|
|
user = ::getenv("ADMIN_ACCOUNT");
|
|
|
|
if (user.isEmpty())
|
|
|
|
user = "root";
|
|
|
|
if (!kapp->authorize("user/"+user))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return the filename as passed to the constructor.
|
|
|
|
*/
|
|
|
|
TQString
|
|
|
|
KDesktopFile::fileName() const { return backEnd->fileName(); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return the resource type as passed to the constructor.
|
|
|
|
*/
|
|
|
|
TQString
|
|
|
|
KDesktopFile::resource() const { return backEnd->resource(); }
|
|
|
|
|
|
|
|
TQStringList
|
|
|
|
KDesktopFile::sortOrder() const
|
|
|
|
{
|
|
|
|
return readListEntry("SortOrder");
|
|
|
|
}
|
|
|
|
|
|
|
|
void KDesktopFile::virtual_hook( int id, void* data )
|
|
|
|
{ KConfig::virtual_hook( id, data ); }
|
|
|
|
|
|
|
|
TQString KDesktopFile::readDocPath() const
|
|
|
|
{
|
|
|
|
// Depreciated, remove in KDE4 or 5?
|
|
|
|
// See: http://www.freedesktop.org/Standards/desktop-entry-spec
|
|
|
|
if(hasKey( "DocPath" ))
|
|
|
|
return readPathEntry( "DocPath" );
|
|
|
|
|
|
|
|
return readPathEntry( "X-DocPath" );
|
|
|
|
}
|
|
|
|
|
|
|
|
KDesktopFile* KDesktopFile::copyTo(const TQString &file) const
|
|
|
|
{
|
|
|
|
KDesktopFile *config = new KDesktopFile(TQString::null, false);
|
|
|
|
KConfig::copyTo(file, config);
|
|
|
|
config->setDesktopGroup();
|
|
|
|
return config;
|
|
|
|
}
|