File r1132903-kinit-xauth.diff of Package kdelibs4

--- trunk/KDE/kdelibs/kinit/kinit.cpp	2010/05/31 17:23:24	1132902
+++ trunk/KDE/kdelibs/kinit/kinit.cpp	2010/05/31 17:23:36	1132903
@@ -64,6 +64,7 @@
 #include <klocale.h>
 #include <kdebug.h>
 #include <kde_file.h>
+#include <ksavefile.h>
 
 #ifdef Q_OS_LINUX
 #include <sys/prctl.h>
@@ -1574,6 +1575,42 @@
 {
     XSetIOErrorHandler(kdeinit_xio_errhandler);
     XSetErrorHandler(kdeinit_x_errhandler);
+/*
+    Handle the tricky case of running via kdesu/su/sudo/etc. There the usual case
+    is that kdesu (etc.) creates a file with xauth information, sets XAUTHORITY,
+    runs the command and removes the xauth file after the command finishes. However,
+    dbus and kdeinit daemon currently don't clean up properly and keeping running.
+    Which means that running a KDE app via kdesu the second time talks to kdeinit
+    with obsolete xauth information, which makes it unable to connect to X or launch
+    any X11 applications.
+    Even fixing the cleanup probably wouldn't be sufficient, since it'd be possible to
+    launch one kdesu session, another one, exit the first one and the app from the second
+    session would be using kdeinit from the first one.
+    So the trick here is to duplicate the xauth file to another file in KDE's tmp
+    location, make the file have a consistent name so that future sessions will use it
+    as well, point XAUTHORITY there and never remove the file (except for possible
+    tmp cleanup).
+*/
+    if( !qgetenv( "XAUTHORITY" ).isEmpty()) {
+        QByteArray display = qgetenv( DISPLAY );
+        int i;
+        if((i = display.lastIndexOf('.')) > display.lastIndexOf(':') && i >= 0)
+            display.truncate(i);
+        display.replace(':','_');
+#ifdef __APPLE__
+        display.replace('/','_');
+#endif
+        QString xauth = s_instance->dirs()->saveLocation( "tmp" ) + QLatin1String( "xauth-" )
+            + QString::number( getuid()) + QLatin1String( "-" ) + QString::fromLocal8Bit( display );
+        KSaveFile xauthfile( xauth );
+        QFile xauthfrom( QFile::decodeName( qgetenv( "XAUTHORITY" )));
+        if( !xauthfrom.open( QFile::ReadOnly ) || !xauthfile.open( QFile::WriteOnly )
+            || xauthfile.write( xauthfrom.readAll()) != xauthfrom.size() || !xauthfile.finalize()) {
+            xauthfile.abort();
+        } else {
+            setenv( "XAUTHORITY", QFile::encodeName( xauth ), true );
+        }
+    }
 }
 
 // Borrowed from kdebase/kaudio/kaudioserver.cpp
openSUSE Build Service is sponsored by