From 5f4287e56dd5c1feecc08843aae1d4e4b8835d1e Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Fri, 19 Apr 2013 12:50:40 -0500 Subject: [PATCH] Fix Documents folder creation dialog This resolves Bug 976 Prevent multiple kdesktop_lock processes from spawning per user --- kdesktop/kdiconview.cc | 9 ++-- kdesktop/kxdglauncher.cpp | 79 +++++++++++++++++++++--------------- kdesktop/lock/lockdlg.cc | 46 ++++++++++++--------- kdesktop/lock/lockprocess.cc | 29 ++++++++++--- kdesktop/lock/lockprocess.h | 5 +-- kdesktop/lock/main.cc | 41 +++++++++++++++++++ 6 files changed, 144 insertions(+), 65 deletions(-) diff --git a/kdesktop/kdiconview.cc b/kdesktop/kdiconview.cc index 7aa500162..cc2f0ba07 100644 --- a/kdesktop/kdiconview.cc +++ b/kdesktop/kdiconview.cc @@ -198,8 +198,9 @@ KDIconView::KDIconView( TQWidget *parent, const char* name ) KDIconView::~KDIconView() { - if (m_dotDirectory && !m_bEditableDesktopIcons) + if (m_dotDirectory && !m_bEditableDesktopIcons) { m_dotDirectory->rollback(false); // Don't save positions + } delete m_dotDirectory; delete m_dirLister; @@ -210,8 +211,9 @@ void KDIconView::initDotDirectories() { TQStringList dirs = m_desktopDirs; KURL u = desktopURL(); - if (u.isLocalFile()) + if (u.isLocalFile()) { dirs.prepend(u.path()); + } TQString prefix = iconPositionGroupPrefix(); TQString dotFileName = locateLocal("appdata", "IconPositions"); @@ -1552,8 +1554,9 @@ void KDIconView::slotItemRenamed(TQIconViewItem* _item, const TQString &name) || (type->name() == "media/builtin-webbrowser") ) { bDesktopFile = true; - if (!newName.endsWith(".desktop")) + if (!newName.endsWith(".desktop")) { newName += ".desktop"; + } } else if(type->name() == "inode/directory") { desktopFile += "/.directory"; diff --git a/kdesktop/kxdglauncher.cpp b/kdesktop/kxdglauncher.cpp index 6ee3a03f3..2ef042ed9 100644 --- a/kdesktop/kxdglauncher.cpp +++ b/kdesktop/kxdglauncher.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -31,6 +32,8 @@ #include #include #include +#include +#include #include @@ -51,10 +54,12 @@ void readXdgUserDirs(TQString *desktop, TQString *documents) TQString line = s.readLine(); while (!line.isNull()) { - if (line.startsWith("XDG_DESKTOP_DIR=")) + if (line.startsWith("XDG_DESKTOP_DIR=")) { *desktop = TQString(line.remove("XDG_DESKTOP_DIR=").remove("\"")).replace("$HOME", TQDir::homeDirPath()); - else if (line.startsWith("XDG_DOCUMENTS_DIR=")) + } + else if (line.startsWith("XDG_DOCUMENTS_DIR=")) { *documents = TQString(line.remove("XDG_DOCUMENTS_DIR=").remove("\"")).replace("$HOME", TQDir::homeDirPath()); + } line = s.readLine(); } @@ -115,51 +120,59 @@ int main( int argc, char **argv) } } else { - TQString newDirectory = KInputDialog::text("Create Documents directory", "Please confirm your Documents directory location
Upon confimation a new directory will be created", getDocumentPath()); - if (newDirectory == TQString::null) { + KURLRequesterDlg newDirectoryRequester(getDocumentPath(), i18n("Please confirm your Documents directory location
Upon confimation a new directory will be created"), 0, NULL, true); + newDirectoryRequester.setCaption(i18n("Create Documents directory")); + newDirectoryRequester.urlRequester()->setMode(KFile::Directory); + if (newDirectoryRequester.exec() != TQDialog::Accepted) { return 1; } else { - if (newDirectory.length() < 4096) { - bool directoryOk = false; - if (myqdir.exists(newDirectory, TRUE) == false) { - if (myqdir.mkdir(newDirectory, TRUE) == true) { - directoryOk = TRUE; + TQString newDirectory = newDirectoryRequester.urlRequester()->url(); + if (newDirectory == TQString::null) { + return 1; + } + else { + if (newDirectory.length() < 4096) { + bool directoryOk = false; + if (myqdir.exists(newDirectory, TRUE) == false) { + if (myqdir.mkdir(newDirectory, TRUE) == true) { + directoryOk = TRUE; + } } - } - else { - directoryOk = TRUE; - } - if (directoryOk == true) { - TQString xdgModifiedDirectory = newDirectory; - xdgModifiedDirectory = xdgModifiedDirectory.replace(TQDir::homeDirPath(), "$HOME"); - while (xdgModifiedDirectory.endsWith("/")) { - xdgModifiedDirectory.truncate(xdgModifiedDirectory.length()-1); + else { + directoryOk = TRUE; } - TDEConfig config(TQDir::homeDirPath() + "/.config/user-dirs.dirs", false, false); - config.writeEntry("XDG_DOCUMENTS_DIR", TQString("\"") + xdgModifiedDirectory + TQString("\""), true); - config.sync(); - if (args->isSet( "getpath" ) == true) { - printf("%s\n\r", (const char *)getDocumentPath().local8Bit()); + if (directoryOk == true) { + TQString xdgModifiedDirectory = newDirectory; + xdgModifiedDirectory = xdgModifiedDirectory.replace(TQDir::homeDirPath(), "$HOME"); + while (xdgModifiedDirectory.endsWith("/")) { + xdgModifiedDirectory.truncate(xdgModifiedDirectory.length()-1); + } + TDEConfig config(TQDir::homeDirPath() + "/.config/user-dirs.dirs", false, false); + config.writeEntry("XDG_DOCUMENTS_DIR", TQString("\"") + xdgModifiedDirectory + TQString("\""), true); + config.sync(); + if (args->isSet( "getpath" ) == true) { + printf("%s\n\r", (const char *)getDocumentPath().local8Bit()); + return 0; + } + else { + KRun * run = new KRun( getDocumentPath(), 0, false, false ); + TQObject::connect( run, TQT_SIGNAL( finished() ), &app, TQT_SLOT( quit() )); + TQObject::connect( run, TQT_SIGNAL( error() ), &app, TQT_SLOT( quit() )); + app.exec(); + } return 0; } else { - KRun * run = new KRun( getDocumentPath(), 0, false, false ); - TQObject::connect( run, TQT_SIGNAL( finished() ), &app, TQT_SLOT( quit() )); - TQObject::connect( run, TQT_SIGNAL( error() ), &app, TQT_SLOT( quit() )); - app.exec(); + KMessageBox::error(0, i18n("Unable to create directory ") + TQString("\"") + newDirectory + TQString("\"\n") + i18n("Please check folder permissions and try again"), i18n("Unable to create directory")); + return 1; } - return 0; } else { - KMessageBox::error(0, i18n("Unable to create directory ") + TQString("\"") + newDirectory + TQString("\"\n") + i18n("Please check folder permissions and try again"), i18n("Unable to create directory")); + KMessageBox::error(0, i18n("Unable to create the directory ") + newDirectory + TQString("\n") + i18n("Directory path cannot be longer than 4096 characters"), i18n("Unable to create directory")); return 1; } } - else { - KMessageBox::error(0, i18n("Unable to create the directory ") + newDirectory + TQString("\n") + i18n("Directory path cannot be longer than 4096 characters"), i18n("Unable to create directory")); - return 1; - } } } } diff --git a/kdesktop/lock/lockdlg.cc b/kdesktop/lock/lockdlg.cc index d401f0b2f..252ade384 100644 --- a/kdesktop/lock/lockdlg.cc +++ b/kdesktop/lock/lockdlg.cc @@ -423,29 +423,35 @@ void PasswordDlg::reapVerify() ::close( sFd ); int status; pid_t retpid = ::waitpid( sPid, &status, 0 ); - if (WIFEXITED(status)) { - switch (WEXITSTATUS(status)) { - case AuthOk: - greet->succeeded(); - accept(); - return; - case AuthBad: - greet->failed(); - mUnlockingFailed = true; - updateLabel(); - mFailedTimerId = startTimer(1500); - ok->setEnabled(false); - cancel->setEnabled(false); - mNewSessButton->setEnabled( false ); - return; - case AuthAbort: - return; - } - } - else if (WIFSIGNALED(status)) { + if (retpid < 0) { // FIXME // ERROR } + else { + if (WIFEXITED(status)) { + switch (WEXITSTATUS(status)) { + case AuthOk: + greet->succeeded(); + accept(); + return; + case AuthBad: + greet->failed(); + mUnlockingFailed = true; + updateLabel(); + mFailedTimerId = startTimer(1500); + ok->setEnabled(false); + cancel->setEnabled(false); + mNewSessButton->setEnabled( false ); + return; + case AuthAbort: + return; + } + } + else if (WIFSIGNALED(status)) { + // FIXME + // ERROR + } + } cantCheck(); } diff --git a/kdesktop/lock/lockprocess.cc b/kdesktop/lock/lockprocess.cc index 8d840983e..d1cf95212 100644 --- a/kdesktop/lock/lockprocess.cc +++ b/kdesktop/lock/lockprocess.cc @@ -2698,25 +2698,42 @@ ControlPipeHandlerObject::~ControlPipeHandlerObject() { } void ControlPipeHandlerObject::run(void) { + int display_number = atoi(TQString(XDisplayString(tqt_xdisplay())).replace(":","").ascii()); + + if (display_number < 0) { + printf("[kdesktop_lock] Warning: unable to create control socket. Interactive logon modules may not function properly.\n\r"); + return; + } + + char fifo_file[PATH_MAX]; + char fifo_file_out[PATH_MAX]; + snprintf(fifo_file, PATH_MAX, FIFO_FILE, display_number); + snprintf(fifo_file_out, PATH_MAX, FIFO_FILE_OUT, display_number); + /* Create the FIFOs if they do not exist */ umask(0); mkdir(FIFO_DIR,0644); - mknod(FIFO_FILE, S_IFIFO|0644, 0); - chmod(FIFO_FILE, 0644); + mknod(fifo_file, S_IFIFO|0644, 0); + chmod(fifo_file, 0644); - mParent->mPipe_fd = open(FIFO_FILE, O_RDONLY | O_NONBLOCK); + mParent->mPipe_fd = open(fifo_file, O_RDONLY | O_NONBLOCK); if (mParent->mPipe_fd > -1) { mParent->mPipeOpen = true; } - mknod(FIFO_FILE_OUT, S_IFIFO|0600, 0); - chmod(FIFO_FILE_OUT, 0600); + mknod(fifo_file_out, S_IFIFO|0600, 0); + chmod(fifo_file_out, 0600); - mParent->mPipe_fd_out = open(FIFO_FILE_OUT, O_RDWR | O_NONBLOCK); + mParent->mPipe_fd_out = open(fifo_file_out, O_RDWR | O_NONBLOCK); if (mParent->mPipe_fd_out > -1) { mParent->mPipeOpen_out = true; } + if (!mParent->mPipeOpen) { + printf("[kdesktop_lock] Warning: unable to create control socket '%s'. Interactive logon modules may not function properly.\n\r", fifo_file); + return; + } + int numread; int retval; fd_set rfds; diff --git a/kdesktop/lock/lockprocess.h b/kdesktop/lock/lockprocess.h index 3ef08c91b..749cd794a 100644 --- a/kdesktop/lock/lockprocess.h +++ b/kdesktop/lock/lockprocess.h @@ -37,9 +37,8 @@ struct GreeterPluginHandle { }; #define FIFO_DIR "/tmp/tdesocket-global" -#define FIFO_FILE "/tmp/tdesocket-global/kdesktoplockcontrol" -#define FIFO_FILE_OUT "/tmp/tdesocket-global/kdesktoplockcontrol_out" -#define PIPE_CHECK_INTERVAL 50 +#define FIFO_FILE "/tmp/tdesocket-global/kdesktoplockcontrol-%d" +#define FIFO_FILE_OUT "/tmp/tdesocket-global/kdesktoplockcontrol_out-%d" typedef TQValueList TQXLibWindowList; diff --git a/kdesktop/lock/main.cc b/kdesktop/lock/main.cc index 0659217a0..792764da1 100644 --- a/kdesktop/lock/main.cc +++ b/kdesktop/lock/main.cc @@ -25,6 +25,8 @@ #include "main.h" #include "kdesktopsettings.h" +#include + #include #include #include @@ -32,6 +34,7 @@ #include #include #include +#include #include @@ -314,6 +317,44 @@ int main( int argc, char **argv ) MyApp app; #endif + TDELockFile lock(locateLocal("tmp", "kdesktop_lock_lockfile")); + lock.setStaleTime(0); + TDELockFile::LockResult lockRet = lock.lock(); + if (lockRet != TDELockFile::LockOK) { + // Terminate existing (stale) process if needed + int pid; + TQString hostName; + TQString appName; + if (lock.getLockInfo(pid, hostName, appName)) { + // Verify that the pid in question is an instance of kdesktop_lock + int len; + char procpath[PATH_MAX]; + char fullpath[PATH_MAX]; + snprintf(procpath, sizeof(procpath), "/proc/%d/exe", pid); + len = readlink( procpath, fullpath, sizeof(fullpath) ); + if (len >= 0) { + fullpath[len] = 0; + TQFileInfo fileInfo(fullpath); + if (fileInfo.baseName() == "kdesktop_lock") { + // Verify that pid in question is owned by current user before killing it + uid_t current_uid = geteuid(); + + struct stat info; + if (lstat(procpath, &info) == 0) { + if (info.st_uid == current_uid) { + kill(pid, SIGKILL); + } + } + } + } + } + } + + // Force a relock as a stale lockfile or process may have been dealt with above + if (!lock.isLocked()) { + lockRet = lock.lock(TDELockFile::LockNoBlock | TDELockFile::LockForce); + } + kdDebug() << "app " << kdesktop_screen_number << " " << starting_screen << " " << child << " " << child_sockets.count() << " " << parent_connection << endl; app.disableSessionManagement(); TDEGlobal::locale()->insertCatalogue("libdmctl");