diff options
Diffstat (limited to 'kdialogd4/kdialogd.cpp')
| -rw-r--r-- | kdialogd4/kdialogd.cpp | 759 |
1 files changed, 0 insertions, 759 deletions
diff --git a/kdialogd4/kdialogd.cpp b/kdialogd4/kdialogd.cpp deleted file mode 100644 index ddd1142..0000000 --- a/kdialogd4/kdialogd.cpp +++ /dev/null @@ -1,759 +0,0 @@ -#define USE_KWIN - -#include "kdialogd.h" -#include <iostream> -#include <kdiroperator.h> -#include <kuniqueapplication.h> -#include <QtCore/QSocketNotifier> -#include <QtGui/QX11Info> -#include <kio/netaccess.h> -#include <kmessagebox.h> -#include <klocale.h> -#include <kconfig.h> -#include <kurlcombobox.h> -#ifdef USE_KWIN -#include <kwindowsystem.h> -#else -#include <X11/Xlib.h> -#include <X11/Xatom.h> -#include <fixx11h.h> -#endif -#include <sys/un.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/errno.h> -#include <kdebug.h> -#include <kdeversion.h> -#ifdef KDIALOGD_APP -#include <QtCore/QTimer> -#include <kcmdlineargs.h> -#include <kaboutdata.h> -#endif -#include <kabstractfilewidget.h> -#include <fstream> - -KConfig *KDialogD::theirConfig=NULL; - -#define CFG_KEY_DIALOG_SIZE "KDialogDSize" -#define CFG_TIMEOUT_GROUP "General" -#ifdef KDIALOGD_APP -#define CFG_TIMEOUT_KEY "Timeout" -#define DEFAULT_TIMEOUT 30 -#endif - -static QString groupName(const QString &app, bool fileDialog=true) -{ - return QString(fileDialog ? "KFileDialog " : "KDirSelectDialog ")+app; -} - -// from kdebase/kdesu -typedef unsigned ksocklen_t; - -static int createSocket() -{ - int socketFd; - ksocklen_t addrlen; - struct stat s; - const char *sock=getSockName(); - int stat_err=lstat(sock, &s); - - if(!stat_err && S_ISLNK(s.st_mode)) - { - kWarning() << "Someone is running a symlink attack on you" ; - if(unlink(sock)) - { - kWarning() << "Could not delete symlink" ; - return -1; - } - } - - if (!access(sock, R_OK|W_OK)) - { - kWarning() << "stale socket exists" ; - if (unlink(sock)) - { - kWarning() << "Could not delete stale socket" ; - return -1; - } - } - - socketFd = socket(PF_UNIX, SOCK_STREAM, 0); - if (socketFd < 0) - { - kError() << "socket(): " << strerror(errno); - return -1; - } - - struct sockaddr_un addr; - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, sock, sizeof(addr.sun_path)-1); - addr.sun_path[sizeof(addr.sun_path)-1] = '\000'; - addrlen = SUN_LEN(&addr); - if (bind(socketFd, (struct sockaddr *)&addr, addrlen) < 0) - { - kError() << "bind(): " << strerror(errno); - return -1; - } - - struct linger lin; - lin.l_onoff = lin.l_linger = 0; - if (setsockopt(socketFd, SOL_SOCKET, SO_LINGER, (char *) &lin, - sizeof(linger)) < 0) - { - kError() << "setsockopt(SO_LINGER): " << strerror(errno); - return -1; - } - - int opt = 1; - if (setsockopt(socketFd, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, - sizeof(opt)) < 0) - { - kError() << "setsockopt(SO_REUSEADDR): " << strerror(errno); - return -1; - } - opt = 1; - if (setsockopt(socketFd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt, - sizeof(opt)) < 0) - { - kError() << "setsockopt(SO_KEEPALIVE): " << strerror(errno); - return -1; - } - chmod(sock, 0600); - if (listen(socketFd, 1) < 0) - { - kError() << "listen(): " << strerror(errno); - return -1; - } - - return socketFd; -} - -static void urls2Local(KUrl::List &urls, QStringList &items, QWidget *parent) -{ - KUrl::List::Iterator it(urls.begin()), - end(urls.end()); - - for(; it!=end; ++it) - { - kDebug() << "URL:" << *it << " local? " << (*it).isLocalFile(); - if((*it).isLocalFile()) - items.append((*it).path()); - else - { - KUrl url(KIO::NetAccess::mostLocalUrl(*it, parent)); - - kDebug() << "mostLocal:" << url << " local? " << url.isLocalFile(); - if(url.isLocalFile()) - items.append(url.path()); - else - break; - } - } -} - -KDialogD::KDialogD(QObject *parent) - : QObject(parent), -#ifdef KDIALOGD_APP - itsTimer(NULL), - itsTimeoutVal(DEFAULT_TIMEOUT), -#endif - itsFd(::createSocket()), - itsNumConnections(0) -{ - if(itsFd<0) - { - kError() << "KDialogD could not create socket"; -#ifdef KDIALOGD_APP - kapp->exit(); -#endif - } - else - { - std::ofstream f(getPidFileName()); - - if(f) - { - f << getpid(); - f.close(); - } - if(!theirConfig) - theirConfig=new KConfig("kdialogd4rc"); // , KConfig::OnlyLocal); - - connect(new QSocketNotifier(itsFd, QSocketNotifier::Read, this), - SIGNAL(activated(int)), this, SLOT(newConnection())); - -#ifdef KDIALOGD_APP - if(theirConfig->hasGroup(CFG_TIMEOUT_GROUP)) - { - itsTimeoutVal=KConfigGroup(theirConfig, CFG_TIMEOUT_GROUP).readEntry(CFG_TIMEOUT_KEY, DEFAULT_TIMEOUT); - if(itsTimeoutVal<0) - itsTimeoutVal=DEFAULT_TIMEOUT; - } - kDebug() << "Timeout:" << itsTimeoutVal; - if(itsTimeoutVal) - { - connect(itsTimer=new QTimer(this), SIGNAL(timeout()), this, SLOT(timeout())); - itsTimer->setSingleShot(true); - } -#endif - } -} - -KDialogD::~KDialogD() -{ - if(-1!=itsFd) - close(itsFd); - if(theirConfig) - delete theirConfig; - theirConfig=NULL; -} - -void KDialogD::newConnection() -{ - kDebug() << "New connection"; - - ksocklen_t addrlen = 64; - struct sockaddr_un clientname; - int connectedFD; - - if((connectedFD=::accept(itsFd, (struct sockaddr *) &clientname, &addrlen))>=0) - { - int appNameLen; - - if(readBlock(connectedFD, (char *)&appNameLen, 4)) - { - bool ok=true; - QByteArray appName; - - if(0==appNameLen) - appName="Generic"; - else - { - appName.resize(appNameLen); - ok=readBlock(connectedFD, appName.data(), appNameLen); - } - - if(ok) - { - itsNumConnections++; -#ifdef KDIALOGD_APP - if(itsTimer) - itsTimer->stop(); -#endif - connect(new KDialogDClient(connectedFD, appName, this), - SIGNAL(error(KDialogDClient *)), - this, SLOT(deleteConnection(KDialogDClient *))); - } - } - } -} - -void KDialogD::deleteConnection(KDialogDClient *client) -{ - kDebug() << "Delete client"; - delete client; - -#ifdef KDIALOGD_APP - if(0==--itsNumConnections) - if(itsTimeoutVal) - itsTimer->start(itsTimeoutVal*1000); // Only single shot... - else - timeout(); -#endif -} - -void KDialogD::timeout() -{ -#ifdef KDIALOGD_APP - if(0==itsNumConnections) - if(grabLock(0)>0) // 0=> no wait... - { - kDebug() << "Timeout occured, and no connections, so exit"; - kapp->exit(); - } - else //...unlock lock file... - { - kDebug() << "Timeout occured, but unable to grab lock file - app must be connecting"; - releaseLock(); - } -#endif -} - -KDialogDClient::KDialogDClient(int sock, const QString &an, QObject *parent) - : QObject(parent), - itsFd(sock), - itsDlg(NULL), - itsXid(0), - itsAccepted(false), - itsAppName(an) -{ - kDebug() << "new client..." << itsAppName << " (" << itsFd << ")"; - connect(new QSocketNotifier(itsFd, QSocketNotifier::Read, this), SIGNAL(activated(int)), this, SLOT(read())); - connect(new QSocketNotifier(itsFd, QSocketNotifier::Exception, this), SIGNAL(activated(int)), this, SLOT(close())); -} - -KDialogDClient::~KDialogDClient() -{ - kDebug() << "Deleted client"; - if(-1!=itsFd) - ::close(itsFd); - itsDlg=NULL; - if(KDialogD::config()) - KDialogD::config()->sync(); -} - -void KDialogDClient::close() -{ - kDebug() << "close" << itsFd; - - ::close(itsFd); - itsFd=-1; - if(itsDlg) - { - itsDlg->close(); - itsDlg->delayedDestruct(); - itsDlg=NULL; - itsXid=0; - } - - emit error(this); -} - -void KDialogDClient::read() -{ - kDebug() << "read" << itsFd; - - if(-1==itsFd) - return; - - char request; - QString caption; - - if(!itsDlg && readData(&request, 1) && request>=(char)OP_FILE_OPEN && request<=(char)OP_FOLDER && - readData((char *)&itsXid, 4) && readString(caption)) - { - if("."==caption) - switch((Operation)request) - { - case OP_FILE_OPEN: - case OP_FILE_OPEN_MULTIPLE: - caption=i18n("Open"); - break; - case OP_FILE_SAVE: - caption=i18n("Save As"); - break; - case OP_FOLDER: - caption=i18n("Select Folder"); - break; - default: - break; - } - - if(OP_FOLDER==(Operation)request) - { - QString intialFolder; - - if(readString(intialFolder)) - { - initDialog(caption, new KDialogDDirSelectDialog(itsAppName, intialFolder, true, NULL, false)); - return; - } - } - else - { - QString intialFolder, - filter; - char overW=0; - - if(readString(intialFolder) && readString(filter) && - (OP_FILE_SAVE!=(Operation)request || readData(&overW, 1))) - { - initDialog(caption, new KDialogDFileDialog(itsAppName, (Operation)request, intialFolder, - filter, overW ? true : false)); - return; - } - } - } - - kDebug() << "Comms error, closing connection..." << itsFd; - // If we get here something was wrong, close connection... - close(); -} - -void KDialogDClient::finished() -{ - if(-1==itsFd) - return; - - // - // * finished is emitted when a dialog is ok'ed/cancel'ed/closed - // * if the user just closes the dialog - neither ok nor cancel are emitted - // * the dir select dialog doesnt seem to set the QDialog result parameter - // when it is accepted - so for this reason if ok is clicked we store an - // 'accepted' value there, and check for that after the dialog is finished. - kDebug() << "finished " << (void *)itsDlg << itsAccepted << (itsDlg ? QDialog::Accepted==itsDlg->result() : false); - - if(itsDlg && !(itsAccepted || QDialog::Accepted==itsDlg->result())) - cancel(); -} - -void KDialogDClient::ok(const QStringList &items) -{ - kDebug() << "ok"; - - int num=items.count(); - QStringList::ConstIterator it(items.begin()), - end(items.end()); - bool error=!writeData((char *)&num, 4); - - for(; !error && it!=end; ++it) - { - kDebug() << "writeString " << *it; - error=!writeString(*it); - } - - if(error) - close(); - else - itsAccepted=true; - if(itsDlg) - itsDlg->delayedDestruct(); - itsDlg=NULL; -} - -void KDialogDClient::cancel() -{ - kDebug() << "cancel"; - - if(itsDlg) - { - kDebug() << "send cancel"; - - int rv=0; - - if(!writeData((char *)&rv, 4)) - { - kDebug() << "failed to write data!"; - close(); - } - if(itsDlg) - itsDlg->delayedDestruct(); - itsDlg=NULL; - } -} - -bool KDialogDClient::readData(QByteArray &buffer, int size) -{ - kDebug() << "readData" << itsFd; - buffer.resize(size); - return ::readBlock(itsFd, buffer.data(), size); -} - -bool KDialogDClient::readString(QString &str) -{ - kDebug() << "readString" << itsFd; - - int size; - - if(!readData((char *)&size, 4)) - return false; - - QByteArray buffer; - buffer.resize(size); - - if(!readData(buffer.data(), size)) - return false; - - str=QString::fromUtf8(buffer.data()); - return true; -} - -bool KDialogDClient::writeString(const QString &str) -{ - kDebug() << "writeString" << itsFd; - - QByteArray utf8(str.toUtf8()); - - int size=utf8.length()+1; - - return writeData((char *)&size, 4) && writeData(utf8.data(), size); -} - -void KDialogDClient::initDialog(const QString &caption, KDialog *d) -{ - kDebug() << "initDialog" << itsFd; - - itsAccepted=false; - itsDlg=d; - - if(!caption.isEmpty()) - itsDlg->setPlainCaption(caption); - - if(itsXid) - itsDlg->installEventFilter(this); - - connect(itsDlg, SIGNAL(okClicked()), itsDlg, SLOT(slotOk())); - connect(itsDlg, SIGNAL(ok(const QStringList &)), this, SLOT(ok(const QStringList &))); - connect(itsDlg, SIGNAL(finished()), this, SLOT(finished())); - itsDlg->show(); -} - -bool KDialogDClient::eventFilter(QObject *object, QEvent *event) -{ - if(object==itsDlg && QEvent::ShowToParent==event->type()) - { -#ifdef USE_KWIN - KWindowSystem::setMainWindow(itsDlg, itsXid); - KWindowSystem::setState(itsDlg->winId(), NET::Modal|NET::SkipTaskbar|NET::SkipPager); - -#if 0 - KWindowInfo wi(KWindowSystem::windowInfo(itsXid, NET::WMGeometry, NET::WM2UserTime)); - QRect geom(wi.geometry()); - int rx=geom.x(), - ry=geom.y(); - - rx=(rx+(geom.width()/2))-(itsDlg->width()/2); - if(rx<0) - rx=0; - ry=(ry+(geom.height()/2))-(itsDlg->height()/2); - if(ry<0) - ry=0; - itsDlg->move(rx, ry); -#endif - QPixmap icon=KWindowSystem::icon(itsXid, 16, 16, true, KWindowSystem::NETWM | KWindowSystem::WMHints); - if(!icon.isNull()) - itsDlg->setWindowIcon(QIcon(icon)); -#else - XSetTransientForHint(QX11Info::display(), itsDlg->winId(), itsXid); -#if 0 - XWindowAttributes attr; - int rx, ry; - Window junkwin; - - if(XGetWindowAttributes(QX11Info::display(), itsXid, &attr)) - { - XTranslateCoordinates(QX11Info::display(), itsXid, attr.root, - -attr.border_width, -16, - &rx, &ry, &junkwin); - - rx=(rx+(attr.width/2))-(itsDlg->width()/2); - if(rx<0) - rx=0; - ry=(ry+(attr.height/2))-(itsDlg->height()/2); - if(ry<0) - ry=0; - itsDlg->move(rx, ry); - } -#endif - -// unsigned long num; -// unsigned long *data = NULL; -// Atom prop = XInternAtom(QX11Info::display(), "_NET_WM_ICON", False); -// Atom typeRet; -// int formatRet; -// unsigned long afterRet; -// if(XGetWindowProperty(QX11Info::display(), itsXid, prop, 0, 0x7FFFFFFF, False, XA_CARDINAL, -// &typeRet, &formatRet, &num, &afterRet, (unsigned char **)&data)) -// { -// kDebug() << "GOT ICON!!!"; -// } -// else -// kDebug() << "FAILED TO GET ICON!!!"; -#endif - itsDlg->removeEventFilter(this); - } - - return false; -} - -KDialogDFileDialog::KDialogDFileDialog(QString &an, Operation op, const QString &startDir, - const QString &filter, bool confirmOw) - : KFileDialog(KUrl(startDir.isEmpty() || "~"==startDir ? QDir::homePath() : startDir), - filter, NULL), - itsConfirmOw(confirmOw), - itsDone(false), - itsAppName(an) -{ - setModal(false); - setSelection(startDir); - kDebug() << "startDir:" << startDir; - - switch(op) - { - case OP_FILE_OPEN: - setOperationMode(KFileDialog::Opening); - setMode(KFile::File|KFile::ExistingOnly); - break; - case OP_FILE_OPEN_MULTIPLE: - setOperationMode(KFileDialog::Opening); - setMode(KFile::Files|KFile::ExistingOnly); - break; - case OP_FILE_SAVE: - setOperationMode(KFileDialog::Saving); - setMode(KFile::File); - break; - default: - break; - } - - if(KDialogD::config()) - { - KConfigGroup cfg(KDialogD::config(), groupName(itsAppName)); - - //TODO !!! readConfig(KDialogD::config(), grp); - resize(cfg.readEntry(CFG_KEY_DIALOG_SIZE, QSize(600, 400))); - } - - //TODO !!! ops->clearHistory(); -} - -void KDialogDFileDialog::accept() -{ - fileWidget()->accept(); - - kDebug() << "KDialogDFileDialog::slotOk" << selectedUrls().count() << ' ' << mode() << ' ' << selectedUrl().prettyUrl(); - KUrl::List urls(selectedUrls()); - QStringList items; - bool good=true; - - if(urls.count()) - { - urls2Local(urls, items, this); - - if(urls.count()!=items.count()) - { - KMessageBox::sorry(this, i18n("You can only select local files."), - i18n("Remote Files Not Accepted")); - good=false; - } - else if(itsConfirmOw && KFileDialog::Saving==operationMode()) - good=!KIO::NetAccess::exists(urls.first(), KIO::NetAccess::DestinationSide, this) || - KMessageBox::Continue==KMessageBox::warningContinueCancel(this, - i18n("File %1 exits.\nDo you want to replace it?") - .arg(urls.first().prettyUrl()), - i18n("File Exists"), - KGuiItem(i18n("Replace"), "filesaveas"), KStandardGuiItem::cancel(), QString(), - KMessageBox::Notify|KMessageBox::PlainCaption); - - if(good) - { - QString filter(currentFilter()); - - if(!filter.isEmpty()) - items.append(filter); - - emit ok(items); - hide(); - //KFileDialog::accept(); - } - else - setResult(QDialog::Rejected); - } -} - -KDialogDFileDialog::~KDialogDFileDialog() -{ - kDebug() << "~KDialogDFileDialog"; - - if(KDialogD::config()) - { - KConfigGroup cfg(KDialogD::config(), groupName(itsAppName)); - - //TODO !!! writeConfig(KDialogD::config(), grp); - cfg.writeEntry(CFG_KEY_DIALOG_SIZE, size()); - } -} - -KDialogDDirSelectDialog::KDialogDDirSelectDialog(QString &an, const QString &startDir, bool localOnly, - QWidget *parent, bool modal) - : KDirSelectDialog(KUrl(startDir.isEmpty() || "~"==startDir - ? QDir::homePath() : startDir), - localOnly, parent), - itsAppName(an) -{ - kDebug() << "startDir:" << startDir; - - setModal(false); - if(KDialogD::config()) - { - KConfigGroup cfg(KDialogD::config(), groupName(itsAppName, false)); - - //TODO !!! readConfig(KDialogD::config(), grp); - resize(cfg.readEntry(CFG_KEY_DIALOG_SIZE, QSize(600, 400))); - } -} - -KDialogDDirSelectDialog::~KDialogDDirSelectDialog() -{ - kDebug() << "~KDialogDDirSelectDialog"; - - if(KDialogD::config()) - { - KConfigGroup cfg(KDialogD::config(), groupName(itsAppName, false)); - - //TODO !!! writeConfig(KDialogD::config(), grp); - cfg.writeEntry(CFG_KEY_DIALOG_SIZE, size()); - } -} - -void KDialogDDirSelectDialog::slotOk() -{ - kDebug() << "KDialogDDirSelectDialog::slotOk"; - - KUrl::List urls; - QStringList items; - - urls.append(url()); - urls2Local(urls, items, this); - - if(urls.count()!=items.count()) - KMessageBox::sorry(this, i18n("You can only select local folders."), - i18n("Remote Folders Not Accepted")); - else - { - emit ok(items); - hide(); - } -} - -#ifdef KDIALOGD_APP -static KAboutData aboutData("kdialogd4", "kdialogd4", ki18n("KDialog Daemon"), VERSION, - ki18n("Use KDE dialogs from non-KDE apps."), - KAboutData::License_GPL, - ki18n("(c) Craig Drummond, 2006-2007")); - -int main(int argc, char **argv) -{ - KCmdLineArgs::init(argc, argv, &aboutData); - - KUniqueApplication *app=new KUniqueApplication; - KDialogD kdialogd; - - QApplication::setQuitOnLastWindowClosed(false); - - int rv=app->exec(); - - delete app; - - unlink(getSockName()); - releaseLock(); - return rv; -} -#else -extern "C" -{ - KDE_EXPORT KDEDModule *create_kdialogd() - { - return new KDialogDKDED(); - } -}; - -KDialogDKDED::KDialogDKDED() - : KDEDModule() -{ - new KDialogD(this); -} -#endif - -#include "kdialogd.moc" - |
