You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdelibs/kdecore/kdesktopfile.cpp

368 lines
9.4 KiB

/*
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.tqfindRev('/')+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.tqfindRev('/')+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.tqfindRev('/')+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.
*/
QString
KDesktopFile::fileName() const { return backEnd->fileName(); }
/**
* @return the resource type as passed to the constructor.
*/
QString
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;
}