kdesktopfile.cpp
00001 /* 00002 This file is part of the KDE libraries 00003 Copyright (c) 1999 Pietro Iglio <iglio@kde.org> 00004 Copyright (c) 1999 Preston Brown <pbrown@kde.org> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License as published by the Free Software Foundation; either 00009 version 2 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 Boston, MA 02110-1301, USA. 00020 */ 00021 00022 // $Id$ 00023 00024 #include <stdlib.h> 00025 #include <unistd.h> 00026 00027 #include <tqfile.h> 00028 #include <tqdir.h> 00029 #include <tqtextstream.h> 00030 00031 #include <kdebug.h> 00032 #include "kurl.h" 00033 #include "kconfigbackend.h" 00034 #include "kapplication.h" 00035 #include "kstandarddirs.h" 00036 #include "kmountpoint.h" 00037 #include "kcatalogue.h" 00038 #include "klocale.h" 00039 00040 #include "kdesktopfile.h" 00041 #include "kdesktopfile.moc" 00042 00043 KDesktopFile::KDesktopFile(const TQString &fileName, bool bReadOnly, 00044 const char * resType) 00045 : KConfig(TQString::fromLatin1(""), bReadOnly, false) 00046 { 00047 // KConfigBackEnd will try to locate the filename that is provided 00048 // based on the resource type specified, _only_ if the filename 00049 // is not an absolute path. 00050 backEnd->changeFileName(fileName, resType, false); 00051 setReadOnly(bReadOnly); 00052 reparseConfiguration(); 00053 setDesktopGroup(); 00054 } 00055 00056 KDesktopFile::~KDesktopFile() 00057 { 00058 // no need to do anything 00059 } 00060 00061 TQString KDesktopFile::locateLocal(const TQString &path) 00062 { 00063 TQString local; 00064 if (path.endsWith(".directory")) 00065 { 00066 local = path; 00067 if (!TQDir::isRelativePath(local)) 00068 { 00069 // Relative wrt apps? 00070 local = KGlobal::dirs()->relativeLocation("apps", path); 00071 } 00072 00073 if (TQDir::isRelativePath(local)) 00074 { 00075 local = ::locateLocal("apps", local); // Relative to apps 00076 } 00077 else 00078 { 00079 // XDG Desktop menu items come with absolute paths, we need to 00080 // extract their relative path and then build a local path. 00081 local = KGlobal::dirs()->relativeLocation("xdgdata-dirs", local); 00082 if (!TQDir::isRelativePath(local)) 00083 { 00084 // Hm, that didn't work... 00085 // What now? Use filename only and hope for the best. 00086 local = path.mid(path.findRev('/')+1); 00087 } 00088 local = ::locateLocal("xdgdata-dirs", local); 00089 } 00090 } 00091 else 00092 { 00093 if (TQDir::isRelativePath(path)) 00094 { 00095 local = ::locateLocal("apps", path); // Relative to apps 00096 } 00097 else 00098 { 00099 // XDG Desktop menu items come with absolute paths, we need to 00100 // extract their relative path and then build a local path. 00101 local = KGlobal::dirs()->relativeLocation("xdgdata-apps", path); 00102 if (!TQDir::isRelativePath(local)) 00103 { 00104 // What now? Use filename only and hope for the best. 00105 local = path.mid(path.findRev('/')+1); 00106 } 00107 local = ::locateLocal("xdgdata-apps", local); 00108 } 00109 } 00110 return local; 00111 } 00112 00113 bool KDesktopFile::isDesktopFile(const TQString& path) 00114 { 00115 int len = path.length(); 00116 00117 if(len > 8 && path.right(8) == TQString::fromLatin1(".desktop")) 00118 return true; 00119 else if(len > 7 && path.right(7) == TQString::fromLatin1(".kdelnk")) 00120 return true; 00121 else 00122 return false; 00123 } 00124 00125 bool KDesktopFile::isAuthorizedDesktopFile(const TQString& path) 00126 { 00127 if (!kapp || kapp->authorize("run_desktop_files")) 00128 return true; 00129 00130 if (path.isEmpty()) 00131 return false; // Empty paths are not ok. 00132 00133 if (TQDir::isRelativePath(path)) 00134 return true; // Relative paths are ok. 00135 00136 KStandardDirs *dirs = KGlobal::dirs(); 00137 if (TQDir::isRelativePath( dirs->relativeLocation("apps", path) )) 00138 return true; 00139 if (TQDir::isRelativePath( dirs->relativeLocation("xdgdata-apps", path) )) 00140 return true; 00141 if (TQDir::isRelativePath( dirs->relativeLocation("services", path) )) 00142 return true; 00143 if (dirs->relativeLocation("data", path).startsWith("kdesktop/Desktop")) 00144 return true; 00145 00146 kdWarning() << "Access to '" << path << "' denied because of 'run_desktop_files' restriction." << endl; 00147 return false; 00148 } 00149 00150 TQString KDesktopFile::translatedEntry(const char* key) const 00151 { 00152 if (hasTranslatedKey(key)) 00153 return readEntry(key); 00154 00155 if (hasKey(key)) { 00156 TQString value = readEntryUntranslated(key); 00157 TQString fName = fileName(); 00158 fName = fName.mid(fName.findRev('/')+1); 00159 TQString po_lookup_key = TQString::fromLatin1(key) + "(" + fName + "): " + value; 00160 TQString po_value = KGlobal::locale()->translate(po_lookup_key.utf8().data()); 00161 00162 if (po_value == po_lookup_key) 00163 return value; 00164 00165 return po_value; 00166 } 00167 00168 return TQString::null; 00169 } 00170 00171 TQString KDesktopFile::readType() const 00172 { 00173 return readEntry("Type"); 00174 } 00175 00176 TQString KDesktopFile::readIcon() const 00177 { 00178 return readEntry("Icon"); 00179 } 00180 00181 TQString KDesktopFile::readName() const 00182 { 00183 return translatedEntry("Name"); 00184 } 00185 00186 TQString KDesktopFile::readComment() const 00187 { 00188 return translatedEntry("Comment"); 00189 } 00190 00191 TQString KDesktopFile::readGenericName() const 00192 { 00193 return translatedEntry("GenericName"); 00194 } 00195 00196 TQString KDesktopFile::readPath() const 00197 { 00198 return readPathEntry("Path"); 00199 } 00200 00201 TQString KDesktopFile::readDevice() const 00202 { 00203 return readEntry("Dev"); 00204 } 00205 00206 TQString KDesktopFile::readURL() const 00207 { 00208 if (hasDeviceType()) { 00209 TQString device = readDevice(); 00210 KMountPoint::List mountPoints = KMountPoint::possibleMountPoints(); 00211 00212 for(KMountPoint::List::ConstIterator it = mountPoints.begin(); 00213 it != mountPoints.end(); ++it) 00214 { 00215 KMountPoint *mp = *it; 00216 if (mp->mountedFrom() == device) 00217 { 00218 KURL u; 00219 u.setPath( mp->mountPoint() ); 00220 return u.url(); 00221 } 00222 } 00223 return TQString::null; 00224 } else { 00225 TQString url = readPathEntry("URL"); 00226 if ( !url.isEmpty() && !TQDir::isRelativePath(url) ) 00227 { 00228 // Handle absolute paths as such (i.e. we need to escape them) 00229 KURL u; 00230 u.setPath( url ); 00231 return u.url(); 00232 } 00233 return url; 00234 } 00235 } 00236 00237 TQStringList KDesktopFile::readActions() const 00238 { 00239 return readListEntry("Actions", ';'); 00240 } 00241 00242 void KDesktopFile::setActionGroup(const TQString &group) 00243 { 00244 setGroup(TQString::fromLatin1("Desktop Action ") + group); 00245 } 00246 00247 bool KDesktopFile::hasActionGroup(const TQString &group) const 00248 { 00249 return hasGroup(TQString::fromLatin1("Desktop Action ") + group); 00250 } 00251 00252 bool KDesktopFile::hasLinkType() const 00253 { 00254 return readEntry("Type") == TQString::fromLatin1("Link"); 00255 } 00256 00257 bool KDesktopFile::hasApplicationType() const 00258 { 00259 return readEntry("Type") == TQString::fromLatin1("Application"); 00260 } 00261 00262 bool KDesktopFile::hasMimeTypeType() const 00263 { 00264 return readEntry("Type") == TQString::fromLatin1("MimeType"); 00265 } 00266 00267 bool KDesktopFile::hasDeviceType() const 00268 { 00269 return readEntry("Type") == TQString::fromLatin1("FSDev") || 00270 readEntry("Type") == TQString::fromLatin1("FSDevice"); 00271 } 00272 00273 bool KDesktopFile::tryExec() const 00274 { 00275 // Test for TryExec and "X-KDE-AuthorizeAction" 00276 TQString te = readPathEntry("TryExec"); 00277 00278 if (!te.isEmpty()) { 00279 if (!TQDir::isRelativePath(te)) { 00280 if (::access(TQFile::encodeName(te), X_OK)) 00281 return false; 00282 } else { 00283 // !!! Sergey A. Sukiyazov <corwin@micom.don.ru> !!! 00284 // Environment PATH may contain filenames in 8bit locale cpecified 00285 // encoding (Like a filenames). 00286 TQStringList dirs = TQStringList::split(':', TQFile::decodeName(::getenv("PATH"))); 00287 TQStringList::Iterator it(dirs.begin()); 00288 bool match = false; 00289 for (; it != dirs.end(); ++it) { 00290 TQString fName = *it + "/" + te; 00291 if (::access(TQFile::encodeName(fName), X_OK) == 0) 00292 { 00293 match = true; 00294 break; 00295 } 00296 } 00297 // didn't match at all 00298 if (!match) 00299 return false; 00300 } 00301 } 00302 TQStringList list = readListEntry("X-KDE-AuthorizeAction"); 00303 if (kapp && !list.isEmpty()) 00304 { 00305 for(TQStringList::ConstIterator it = list.begin(); 00306 it != list.end(); 00307 ++it) 00308 { 00309 if (!kapp->authorize((*it).stripWhiteSpace())) 00310 return false; 00311 } 00312 } 00313 00314 // See also KService::username() 00315 bool su = readBoolEntry("X-KDE-SubstituteUID"); 00316 if (su) 00317 { 00318 TQString user = readEntry("X-KDE-Username"); 00319 if (user.isEmpty()) 00320 user = ::getenv("ADMIN_ACCOUNT"); 00321 if (user.isEmpty()) 00322 user = "root"; 00323 if (!kapp->authorize("user/"+user)) 00324 return false; 00325 } 00326 00327 return true; 00328 } 00329 00333 TQString 00334 KDesktopFile::fileName() const { return backEnd->fileName(); } 00335 00339 TQString 00340 KDesktopFile::resource() const { return backEnd->resource(); } 00341 00342 TQStringList 00343 KDesktopFile::sortOrder() const 00344 { 00345 return readListEntry("SortOrder"); 00346 } 00347 00348 void KDesktopFile::virtual_hook( int id, void* data ) 00349 { KConfig::virtual_hook( id, data ); } 00350 00351 TQString KDesktopFile::readDocPath() const 00352 { 00353 // Depreciated, remove in KDE4 or 5? 00354 // See: http://www.freedesktop.org/Standards/desktop-entry-spec 00355 if(hasKey( "DocPath" )) 00356 return readPathEntry( "DocPath" ); 00357 00358 return readPathEntry( "X-DocPath" ); 00359 } 00360 00361 KDesktopFile* KDesktopFile::copyTo(const TQString &file) const 00362 { 00363 KDesktopFile *config = new KDesktopFile(TQString::null, false); 00364 KConfig::copyTo(file, config); 00365 config->setDesktopGroup(); 00366 return config; 00367 }