• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.10.5 API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • kdecore
  • config
kdesktopfile.cpp
Go to the documentation of this file.
1 /*
2  This file is part of the KDE libraries
3  Copyright (c) 1999 Pietro Iglio <iglio@kde.org>
4  Copyright (c) 1999 Preston Brown <pbrown@kde.org>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License as published by the Free Software Foundation; either
9  version 2 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Library General Public License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to
18  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  Boston, MA 02110-1301, USA.
20 */
21 
22 #include "kdesktopfile.h"
23 
24 #include <unistd.h>
25 
26 #include <QtCore/QDir>
27 #include <QtCore/QFileInfo>
28 
29 #include "kconfig_p.h"
30 #include "kdebug.h"
31 #include "kurl.h"
32 #include "kconfiggroup.h"
33 #include "kauthorized.h"
34 #include "kstandarddirs.h"
35 #include "kconfigini_p.h"
36 #include "kde_file.h"
37 
38 class KDesktopFilePrivate : public KConfigPrivate
39 {
40  public:
41  KDesktopFilePrivate(const char * resourceType, const QString &fileName);
42  KConfigGroup desktopGroup;
43 };
44 
45 KDesktopFilePrivate::KDesktopFilePrivate(const char * resourceType, const QString &fileName)
46  : KConfigPrivate(KGlobal::mainComponent(), KConfig::NoGlobals, resourceType)
47 {
48  mBackend = new KConfigIniBackend();
49  bDynamicBackend = false;
50  changeFileName(fileName, resourceType);
51 }
52 
53 KDesktopFile::KDesktopFile(const char * resourceType, const QString &fileName)
54  : KConfig(*new KDesktopFilePrivate(resourceType, fileName))
55 {
56  Q_D(KDesktopFile);
57  reparseConfiguration();
58  d->desktopGroup = KConfigGroup(this, "Desktop Entry");
59 }
60 
61 KDesktopFile::KDesktopFile(const QString &fileName)
62  : KConfig(*new KDesktopFilePrivate("apps", fileName)) // TODO KDE5: default to xdgdata-apps instead of apps
63 {
64  Q_D(KDesktopFile);
65  reparseConfiguration();
66  d->desktopGroup = KConfigGroup(this, "Desktop Entry");
67 }
68 
69 KDesktopFile::~KDesktopFile()
70 {
71 }
72 
73 KConfigGroup KDesktopFile::desktopGroup() const
74 {
75  Q_D(const KDesktopFile);
76  return d->desktopGroup;
77 }
78 
79 QString KDesktopFile::locateLocal(const QString &path)
80 {
81  QString local;
82  if (path.endsWith(QLatin1String(".directory")))
83  {
84  local = path;
85  if (!QDir::isRelativePath(local))
86  {
87  // Relative wrt apps?
88  local = KGlobal::dirs()->relativeLocation("apps", path);
89  }
90 
91  if (QDir::isRelativePath(local))
92  {
93  local = KStandardDirs::locateLocal("apps", local); // Relative to apps
94  }
95  else
96  {
97  // XDG Desktop menu items come with absolute paths, we need to
98  // extract their relative path and then build a local path.
99  local = KGlobal::dirs()->relativeLocation("xdgdata-dirs", local);
100  if (!QDir::isRelativePath(local))
101  {
102  // Hm, that didn't work...
103  // What now? Use filename only and hope for the best.
104  local = path.mid(path.lastIndexOf(QLatin1Char('/'))+1);
105  }
106  local = KStandardDirs::locateLocal("xdgdata-dirs", local);
107  }
108  }
109  else
110  {
111  if (QDir::isRelativePath(path))
112  {
113  local = KStandardDirs::locateLocal("apps", path); // Relative to apps
114  }
115  else
116  {
117  // XDG Desktop menu items come with absolute paths, we need to
118  // extract their relative path and then build a local path.
119  local = KGlobal::dirs()->relativeLocation("xdgdata-apps", path);
120  if (!QDir::isRelativePath(local))
121  {
122  // What now? Use filename only and hope for the best.
123  local = path.mid(path.lastIndexOf(QLatin1Char('/'))+1);
124  }
125  local = KStandardDirs::locateLocal("xdgdata-apps", local);
126  }
127  }
128  return local;
129 }
130 
131 bool KDesktopFile::isDesktopFile(const QString& path)
132 {
133  return (path.length() > 8
134  && path.endsWith(QLatin1String(".desktop")));
135 }
136 
137 bool KDesktopFile::isAuthorizedDesktopFile(const QString& path)
138 {
139  if (path.isEmpty())
140  return false; // Empty paths are not ok.
141 
142  if (QDir::isRelativePath(path))
143  return true; // Relative paths are ok.
144 
145  KStandardDirs *dirs = KGlobal::dirs();
146  QStringList kdePrefixes;
147  kdePrefixes += dirs->resourceDirs("apps");
148  kdePrefixes += dirs->resourceDirs("services");
149  kdePrefixes += dirs->resourceDirs("xdgdata-apps");
150  kdePrefixes += dirs->resourceDirs("autostart");
151 
152  const QString realPath = KStandardDirs::realPath(path);
153 
154  // Check if the .desktop file is installed as part of KDE or XDG.
155  foreach (const QString &prefix, kdePrefixes) {
156  if (realPath.startsWith(prefix))
157  return true;
158  }
159 
160  // Forbid desktop files outside of standard locations if kiosk is set so
161  if (!KAuthorized::authorize(QLatin1String("run_desktop_files"))) {
162  kWarning() << "Access to '" << path << "' denied because of 'run_desktop_files' restriction." << endl;
163  return false;
164  }
165 
166  // Not otherwise permitted, so only allow if the file is executable, or if
167  // owned by root (uid == 0)
168  QFileInfo entryInfo( path );
169  if (entryInfo.isExecutable() || entryInfo.ownerId() == 0)
170  return true;
171 
172  kWarning() << "Access to '" << path << "' denied, not owned by root, executable flag not set." << endl;
173  return false;
174 }
175 
176 QString KDesktopFile::readType() const
177 {
178  Q_D(const KDesktopFile);
179  return d->desktopGroup.readEntry("Type", QString());
180 }
181 
182 QString KDesktopFile::readIcon() const
183 {
184  Q_D(const KDesktopFile);
185  return d->desktopGroup.readEntry("Icon", QString());
186 }
187 
188 QString KDesktopFile::readName() const
189 {
190  Q_D(const KDesktopFile);
191  return d->desktopGroup.readEntry("Name", QString());
192 }
193 
194 QString KDesktopFile::readComment() const
195 {
196  Q_D(const KDesktopFile);
197  return d->desktopGroup.readEntry("Comment", QString());
198 }
199 
200 QString KDesktopFile::readGenericName() const
201 {
202  Q_D(const KDesktopFile);
203  return d->desktopGroup.readEntry("GenericName", QString());
204 }
205 
206 QString KDesktopFile::readPath() const
207 {
208  Q_D(const KDesktopFile);
209  // NOT readPathEntry, it is not XDG-compliant. Path entries written by
210  // KDE4 will be still treated as such, though.
211  return d->desktopGroup.readEntry("Path", QString());
212 }
213 
214 QString KDesktopFile::readDevice() const
215 {
216  Q_D(const KDesktopFile);
217  return d->desktopGroup.readEntry("Dev", QString());
218 }
219 
220 QString KDesktopFile::readUrl() const
221 {
222  Q_D(const KDesktopFile);
223  if (hasDeviceType()) {
224  return d->desktopGroup.readEntry("MountPoint", QString());
225  } else {
226  // NOT readPathEntry (see readPath())
227  QString url = d->desktopGroup.readEntry("URL", QString());
228  if ( !url.isEmpty() && !QDir::isRelativePath(url) )
229  {
230  // Handle absolute paths as such (i.e. we need to escape them)
231  return KUrl(url).url();
232  }
233  return url;
234  }
235 }
236 
237 QStringList KDesktopFile::readActions() const
238 {
239  Q_D(const KDesktopFile);
240  return d->desktopGroup.readXdgListEntry("Actions");
241 }
242 
243 KConfigGroup KDesktopFile::actionGroup(const QString &group)
244 {
245  return KConfigGroup(this, QLatin1String("Desktop Action ") + group);
246 }
247 
248 const KConfigGroup KDesktopFile::actionGroup(const QString& group) const
249 {
250  return const_cast<KDesktopFile*>(this)->actionGroup(group);
251 }
252 
253 bool KDesktopFile::hasActionGroup(const QString &group) const
254 {
255  return hasGroup(QString(QLatin1String("Desktop Action ") + group).toUtf8().constData());
256 }
257 
258 bool KDesktopFile::hasLinkType() const
259 {
260  return readType() == QLatin1String("Link");
261 }
262 
263 bool KDesktopFile::hasApplicationType() const
264 {
265  return readType() == QLatin1String("Application");
266 }
267 
268 bool KDesktopFile::hasMimeTypeType() const
269 {
270  return readType() == QLatin1String("MimeType");
271 }
272 
273 bool KDesktopFile::hasDeviceType() const
274 {
275  return readType() == QLatin1String("FSDevice");
276 }
277 
278 bool KDesktopFile::tryExec() const
279 {
280  Q_D(const KDesktopFile);
281  // Test for TryExec and "X-KDE-AuthorizeAction"
282  // NOT readPathEntry (see readPath())
283  QString te = d->desktopGroup.readEntry("TryExec", QString());
284 
285  if (!te.isEmpty()) {
286  if (!QDir::isRelativePath(te)) {
287  if (KDE::access(te, X_OK))
288  return false;
289  } else {
290  // !!! Sergey A. Sukiyazov <corwin@micom.don.ru> !!!
291  // Environment PATH may contain filenames in 8bit locale specified
292  // encoding (Like a filenames).
293  const QStringList dirs = QFile::decodeName(qgetenv("PATH"))
294  .split(QLatin1Char(KPATH_SEPARATOR), QString::SkipEmptyParts);
295  QStringList::ConstIterator it(dirs.begin());
296  bool match = false;
297  for (; it != dirs.end(); ++it) {
298  QString fName = *it + QLatin1Char(KDIR_SEPARATOR) + te;
299  if (KDE::access(fName, X_OK) == 0)
300  {
301  match = true;
302  break;
303  }
304  }
305  // didn't match at all
306  if (!match)
307  return false;
308  }
309  }
310  const QStringList list = d->desktopGroup.readEntry("X-KDE-AuthorizeAction", QStringList());
311  if (!list.isEmpty())
312  {
313  for(QStringList::ConstIterator it = list.begin();
314  it != list.end();
315  ++it)
316  {
317  if (!KAuthorized::authorize((*it).trimmed()))
318  return false;
319  }
320  }
321 
322  // See also KService::username()
323  bool su = d->desktopGroup.readEntry("X-KDE-SubstituteUID", false);
324  if (su)
325  {
326  QString user = d->desktopGroup.readEntry("X-KDE-Username", QString());
327  if (user.isEmpty())
328  user = QString::fromLocal8Bit(qgetenv("ADMIN_ACCOUNT"));
329  if (user.isEmpty())
330  user = QString::fromLatin1("root");
331  if (!KAuthorized::authorize(QString::fromLatin1("user/")+user))
332  return false;
333  }
334 
335  return true;
336 }
337 
341 //QString KDesktopFile::fileName() const { return backEnd->fileName(); }
342 
346 //QString
347 //KDesktopFile::resource() const { return backEnd->resource(); }
348 
349 QStringList
350 KDesktopFile::sortOrder() const
351 {
352  Q_D(const KDesktopFile);
353  return d->desktopGroup.readEntry("SortOrder", QStringList());
354 }
355 
356 //void KDesktopFile::virtual_hook( int id, void* data )
357 //{ KConfig::virtual_hook( id, data ); }
358 
359 QString KDesktopFile::readDocPath() const
360 {
361  Q_D(const KDesktopFile);
362  //legacy entry in kde3 apps
363  if(d->desktopGroup.hasKey( "DocPath" ))
364  return d->desktopGroup.readPathEntry( "DocPath", QString() );
365  return d->desktopGroup.readPathEntry( "X-DocPath", QString() );
366 }
367 
368 KDesktopFile* KDesktopFile::copyTo(const QString &file) const
369 {
370  KDesktopFile *config = new KDesktopFile(QString());
371  this->KConfig::copyTo(file, config);
372 // config->setDesktopGroup();
373  return config;
374 }
375 
376 const char *KDesktopFile::resource() const
377 {
378  Q_D(const KDesktopFile);
379  return d->resourceType;
380 }
381 
382 QString KDesktopFile::fileName() const
383 {
384  return name();
385 }
386 
387 bool KDesktopFile::noDisplay() const
388 {
389  Q_D(const KDesktopFile);
390  if (d->desktopGroup.readEntry("NoDisplay", false)) {
391  return true;
392  }
393  if (d->desktopGroup.hasKey("OnlyShowIn")) {
394  if (!d->desktopGroup.readXdgListEntry("OnlyShowIn").contains(QLatin1String("KDE")))
395  return true;
396  }
397  if (d->desktopGroup.hasKey("NotShowIn")) {
398  if (d->desktopGroup.readXdgListEntry("NotShowIn").contains(QLatin1String("KDE")))
399  return true;
400  }
401  return false;
402 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2013 The KDE developers.
Generated on Mon Jul 15 2013 13:00:53 by doxygen 1.8.3.1 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.10.5 API Reference

Skip menu "kdelibs-4.10.5 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal