diff --git a/kcms/kfontinst/dbus/Helper.cpp b/kcms/kfontinst/dbus/Helper.cpp index 1e03f310b..3dad7596c 100644 --- a/kcms/kfontinst/dbus/Helper.cpp +++ b/kcms/kfontinst/dbus/Helper.cpp @@ -1,443 +1,443 @@ /* * KHelper - KDE Font Installer * * Copyright 2003-2010 Craig Drummond * * ---- * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "Helper.h" #include "Folder.h" #include "FontInst.h" #include "Misc.h" #include "Utils.h" #include #include #include #include #include #include #include #include #include -#define KFI_DBUG qDebug() << time(0L) +#define KFI_DBUG qDebug() << time(nullptr) KAUTH_HELPER_MAIN("org.kde.fontinst", KFI::Helper) namespace KFI { static Folder theFontFolder; typedef void (*SignalHandler)(int); static void registerSignalHandler(SignalHandler handler) { if (!handler) handler = SIG_DFL; sigset_t mask; sigemptyset(&mask); #ifdef SIGSEGV signal(SIGSEGV, handler); sigaddset(&mask, SIGSEGV); #endif #ifdef SIGFPE signal(SIGFPE, handler); sigaddset(&mask, SIGFPE); #endif #ifdef SIGILL signal(SIGILL, handler); sigaddset(&mask, SIGILL); #endif #ifdef SIGABRT signal(SIGABRT, handler); sigaddset(&mask, SIGABRT); #endif sigprocmask(SIG_UNBLOCK, &mask, nullptr); } static void signalHander(int) { static bool inHandler=false; if(!inHandler) { inHandler=true; theFontFolder.saveDisabled(); inHandler=false; } } static void cleanup() { theFontFolder.saveDisabled(); } Helper::Helper() { KFI_DBUG; QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); registerSignalHandler(signalHander); qAddPostRoutine(cleanup); theFontFolder.init(true, true); theFontFolder.loadDisabled(); } Helper::~Helper() { theFontFolder.saveDisabled(); } ActionReply Helper::manage(const QVariantMap &args) { int result=KIO::ERR_UNSUPPORTED_ACTION; QString method=args["method"].toString(); KFI_DBUG << method; if("install"==method) result=install(args); else if("uninstall"==method) result=uninstall(args); else if("move"==method) result=move(args); else if("toggle"==method) result=toggle(args); else if("removeFile"==method) result=removeFile(args); else if("reconfigure"==method) result=reconfigure(); else if("saveDisabled"==method) result=saveDisabled(); else KFI_DBUG << "Uknown action"; if(FontInst::STATUS_OK==result) return ActionReply::SuccessReply(); ActionReply reply(ActionReply::HelperErrorType); reply.setErrorCode(static_cast(result)); return reply; } int Helper::install(const QVariantMap &args) { QString file(args["file"].toString()), name(args["name"].toString()), destFolder(args["destFolder"].toString()); bool createAfm(args["createAfm"].toBool()); int type(args["type"].toInt()); KFI_DBUG << file << destFolder << name << createAfm; int result=FontInst::STATUS_OK; if(!Misc::dExists(destFolder)) result=Misc::createDir(destFolder) ? (int)FontInst::STATUS_OK : (int)KIO::ERR_WRITE_ACCESS_DENIED; if(FontInst::STATUS_OK==result) result=QFile::copy(file, destFolder+name) ? (int)FontInst::STATUS_OK : (int)KIO::ERR_WRITE_ACCESS_DENIED; if(FontInst::STATUS_OK==result) { Misc::setFilePerms(QFile::encodeName(destFolder+name)); if((Utils::FILE_SCALABLE==type || Utils::FILE_PFM==type) && createAfm) Utils::createAfm(destFolder+name, (KFI::Utils::EFileType)type); theFontFolder.addModifiedDir(destFolder); } return result; } int Helper::uninstall(const QVariantMap &args) { QStringList files(args["files"].toStringList()); int result=checkWriteAction(files); if(FontInst::STATUS_OK==result) { QStringList::ConstIterator it(files.constBegin()), end(files.constEnd()); for(; it!=end; ++it) if(!Misc::fExists(*it) || QFile::remove(*it)) { // Also remove any AFM or PFM files... QStringList other; Misc::getAssociatedFiles(*it, other); QStringList::ConstIterator oit(other.constBegin()), oend(other.constEnd()); for(; oit!=oend; ++oit) QFile::remove(*oit); theFontFolder.addModifiedDir(Misc::getDir(*it)); } } return result; } static bool renameFontFile(const QString &from, const QString &to, int uid=-1, int gid=-1) { if(!QFile::rename(from, to)) return false; QByteArray dest(QFile::encodeName(to)); Misc::setFilePerms(dest); if(-1!=uid && -1!=gid) ::chown(dest.data(), uid, gid); return true; } int Helper::move(const QVariantMap &args) { QStringList files(args["files"].toStringList()); bool toSystem(args["toSystem"].toBool()); QString dest(args["dest"].toString()); int uid(args["uid"].toInt()), gid(args["gid"].toInt()); KFI_DBUG << files << dest << toSystem; int result=FontInst::STATUS_OK; QStringList::ConstIterator it(files.constBegin()), end(files.constEnd()); // Cant move hidden fonts - need to unhide first. for(; it!=end && FontInst::STATUS_OK==result; ++it) if(Misc::isHidden(Misc::getFile(*it))) result=KIO::ERR_UNSUPPORTED_ACTION; if(FontInst::STATUS_OK==result) { QHash movedFiles; int toUid=toSystem ? getuid() : uid, fromUid=toSystem ? uid : getuid(), toGid=toSystem ? getgid() : gid, fromGid=toSystem ? gid : getgid(); // Move fonts! for(it=files.constBegin(); it!=end && FontInst::STATUS_OK==result; ++it) { QString name(Misc::modifyName(Misc::getFile(*it))), destFolder(Misc::getDestFolder(dest, name)); if(!Misc::dExists(destFolder)) { result=Misc::createDir(destFolder) ? (int)FontInst::STATUS_OK : (int)KIO::ERR_WRITE_ACCESS_DENIED; if(FontInst::STATUS_OK==result) ::chown(QFile::encodeName(destFolder).data(), toUid, toGid); } if(renameFontFile(*it, destFolder+name, toUid, toGid)) { movedFiles[*it]=destFolder+name; // Now try to move an associated AFM or PFM files... QStringList assoc; Misc::getAssociatedFiles(*it, assoc); QStringList::ConstIterator ait(assoc.constBegin()), aend(assoc.constEnd()); for(; ait!=aend && FontInst::STATUS_OK==result; ++ait) { name=Misc::getFile(*ait); if(renameFontFile(*ait, destFolder+name, toUid, toGid)) movedFiles[*ait]=destFolder+name; else result=KIO::ERR_WRITE_ACCESS_DENIED; } if(toSystem) theFontFolder.addModifiedDir(theFontFolder.location()); } else result=KIO::ERR_WRITE_ACCESS_DENIED; } if(FontInst::STATUS_OK!=result) // un-move fonts! { QHash::ConstIterator it(movedFiles.constBegin()), end(movedFiles.constEnd()); for(; it!=end; ++it) renameFontFile(it.value(), it.key(), fromUid, fromGid); } } return result; } int Helper::toggle(const QVariantMap &args) { QDomDocument doc; doc.setContent(args["xml"].toString()); Family font(doc.documentElement(), true); bool enable(args["enable"].toBool()); KFI_DBUG << font.name() << enable; if(1!=font.styles().count()) return KIO::ERR_WRITE_ACCESS_DENIED; int result=FontInst::STATUS_OK; FileCont files((*font.styles().begin()).files()), toggledFiles; FileCont::ConstIterator it(files.constBegin()), end(files.constEnd()); QHash movedFonts; QHash movedAssoc; QSet modifiedDirs; // Move fonts! for(; it!=end && FontInst::STATUS_OK==result; ++it) { QString to=Misc::getDir((*it).path())+ QString(enable ? Misc::unhide(Misc::getFile((*it).path())) : Misc::hide(Misc::getFile((*it).path()))); if(to!=(*it).path()) { KFI_DBUG << "MOVE:" << (*it).path() << " to " << to; if(renameFontFile((*it).path(), to)) { modifiedDirs.insert(Misc::getDir(enable ? to : (*it).path())); toggledFiles.insert(File(to, (*it).foundry(), (*it).index())); // Now try to move an associated AFM or PFM files... QStringList assoc; movedFonts[*it]=to; Misc::getAssociatedFiles((*it).path(), assoc); QStringList::ConstIterator ait(assoc.constBegin()), aend(assoc.constEnd()); for(; ait!=aend && FontInst::STATUS_OK==result; ++ait) { to=Misc::getDir(*ait)+ QString(enable ? Misc::unhide(Misc::getFile(*ait)) : Misc::hide(Misc::getFile(*ait))); if(to!=*ait) { if(renameFontFile(*ait, to)) movedAssoc[*ait]=to; else result=KIO::ERR_WRITE_ACCESS_DENIED; } } } else result=KIO::ERR_WRITE_ACCESS_DENIED; } } theFontFolder.addModifiedDirs(modifiedDirs); if(FontInst::STATUS_OK==result) { FamilyCont::ConstIterator f=theFontFolder.fonts().find(font); if(theFontFolder.fonts().end()==f) f=theFontFolder.addFont(font); StyleCont::ConstIterator st=(*f).styles().find(*font.styles().begin()); if((*f).styles().end()==st) st=(*f).add(*font.styles().begin()); // This helper only needs to store list of disabled fonts, // for writing back to disk - therefore no need to store // list of enabled font files. FileCont empty; (*st).setFiles(enable ? empty : toggledFiles); if((*st).files().isEmpty()) (*f).remove(*st); if((*f).styles().isEmpty()) theFontFolder.removeFont(*f); theFontFolder.setDisabledDirty(); } else { QHash::ConstIterator fit(movedFonts.constBegin()), fend(movedFonts.constEnd()); QHash::ConstIterator ait(movedAssoc.constBegin()), aend(movedAssoc.constEnd()); for(; fit!=fend; ++fit) renameFontFile(fit.value(), fit.key().path()); for(; ait!=aend; ++ait) renameFontFile(ait.value(), ait.key()); } return result; } int Helper::removeFile(const QVariantMap &args) { QString file(args["file"].toString()); KFI_DBUG << file; QString dir(Misc::getDir(file)); int result=Misc::fExists(file) ? QFile::remove(file) ? (int)FontInst::STATUS_OK : (int)KIO::ERR_WRITE_ACCESS_DENIED : (int)KIO::ERR_DOES_NOT_EXIST; if(FontInst::STATUS_OK==result) theFontFolder.addModifiedDir(dir); return result; } int Helper::reconfigure() { KFI_DBUG; saveDisabled(); KFI_DBUG << theFontFolder.isModified(); if(theFontFolder.isModified()) theFontFolder.configure(); return FontInst::STATUS_OK; } int Helper::saveDisabled() { KFI_DBUG; // Load internally calls save! theFontFolder.loadDisabled(); return FontInst::STATUS_OK; } int Helper::checkWriteAction(const QStringList &files) { QStringList::ConstIterator it(files.constBegin()), end(files.constEnd()); for(; it!=end; ++it) if(!Misc::dWritable(Misc::getDir(*it))) return KIO::ERR_WRITE_ACCESS_DENIED; return FontInst::STATUS_OK; } }