summaryrefslogtreecommitdiffstats
path: root/ksmserver/client.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ksmserver/client.cpp')
-rw-r--r--ksmserver/client.cpp190
1 files changed, 190 insertions, 0 deletions
diff --git a/ksmserver/client.cpp b/ksmserver/client.cpp
new file mode 100644
index 000000000..784de496c
--- /dev/null
+++ b/ksmserver/client.cpp
@@ -0,0 +1,190 @@
+/*****************************************************************
+ksmserver - the KDE session management server
+
+Copyright (C) 2000 Matthias Ettrich <[email protected]>
+Copyright (C) 2005 Lubos Lunak <[email protected]>
+
+relatively small extensions by Oswald Buddenhagen <[email protected]>
+
+some code taken from the dcopserver (part of the KDE libraries), which is
+Copyright (c) 1999 Matthias Ettrich <[email protected]>
+Copyright (c) 1999 Preston Brown <[email protected]>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "client.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#include <time.h>
+
+#include <kstaticdeleter.h>
+
+#include "server.h"
+
+KSMClient::KSMClient( SmsConn conn)
+{
+ smsConn = conn;
+ id = 0;
+ resetState();
+}
+
+KSMClient::~KSMClient()
+{
+ for ( SmProp* prop = properties.first(); prop; prop = properties.next() )
+ SmFreeProperty( prop );
+ if (id) free((void*)id);
+}
+
+SmProp* KSMClient::property( const char* name ) const
+{
+ for ( QPtrListIterator<SmProp> it( properties ); it.current(); ++it ) {
+ if ( !qstrcmp( it.current()->name, name ) )
+ return it.current();
+ }
+ return 0;
+}
+
+void KSMClient::resetState()
+{
+ saveYourselfDone = false;
+ pendingInteraction = false;
+ waitForPhase2 = false;
+ wasPhase2 = false;
+}
+
+/*
+ * This fakes SmsGenerateClientID() in case we can't read our own hostname.
+ * In this case SmsGenerateClientID() returns NULL, but we really want a
+ * client ID, so we fake one.
+ */
+static KStaticDeleter<QString> smy_addr;
+static char * safeSmsGenerateClientID( SmsConn /*c*/ )
+{
+// Causes delays with misconfigured network :-/.
+// char *ret = SmsGenerateClientID(c);
+ char* ret = NULL;
+ if (!ret) {
+ static QString *my_addr = 0;
+ if (!my_addr) {
+// qWarning("Can't get own host name. Your system is severely misconfigured\n");
+ smy_addr.setObject(my_addr,new QString);
+
+ /* Faking our IP address, the 0 below is "unknown" address format
+ (1 would be IP, 2 would be DEC-NET format) */
+ char hostname[ 256 ];
+ if( gethostname( hostname, 255 ) != 0 )
+ my_addr->sprintf("0%.8x", KApplication::random());
+ else {
+ // create some kind of hash for the hostname
+ int addr[ 4 ] = { 0, 0, 0, 0 };
+ int pos = 0;
+ for( unsigned int i = 0;
+ i < strlen( hostname );
+ ++i, ++pos )
+ addr[ pos % 4 ] += hostname[ i ];
+ *my_addr = "0";
+ for( int i = 0;
+ i < 4;
+ ++i )
+ *my_addr += QString::number( addr[ i ], 16 );
+ }
+ }
+ /* Needs to be malloc(), to look the same as libSM */
+ ret = (char *)malloc(1+my_addr->length()+13+10+4+1 + /*safeness*/ 10);
+ static int sequence = 0;
+
+ if (ret == NULL)
+ return NULL;
+
+ sprintf(ret, "1%s%.13ld%.10d%.4d", my_addr->latin1(), (long)time(NULL),
+ getpid(), sequence);
+ sequence = (sequence + 1) % 10000;
+ }
+ return ret;
+}
+
+void KSMClient::registerClient( const char* previousId )
+{
+ id = previousId;
+ if ( !id )
+ id = safeSmsGenerateClientID( smsConn );
+ SmsRegisterClientReply( smsConn, (char*) id );
+ SmsSaveYourself( smsConn, SmSaveLocal, false, SmInteractStyleNone, false );
+ SmsSaveComplete( smsConn );
+ KSMServer::self()->clientRegistered( previousId );
+}
+
+
+QString KSMClient::program() const
+{
+ SmProp* p = property( SmProgram );
+ if ( !p || qstrcmp( p->type, SmARRAY8) || p->num_vals < 1)
+ return QString::null;
+ return QString::fromLatin1( (const char*) p->vals[0].value );
+}
+
+QStringList KSMClient::restartCommand() const
+{
+ QStringList result;
+ SmProp* p = property( SmRestartCommand );
+ if ( !p || qstrcmp( p->type, SmLISTofARRAY8) || p->num_vals < 1)
+ return result;
+ for ( int i = 0; i < p->num_vals; i++ )
+ result +=QString::fromLatin1( (const char*) p->vals[i].value );
+ return result;
+}
+
+QStringList KSMClient::discardCommand() const
+{
+ QStringList result;
+ SmProp* p = property( SmDiscardCommand );
+ if ( !p || qstrcmp( p->type, SmLISTofARRAY8) || p->num_vals < 1)
+ return result;
+ for ( int i = 0; i < p->num_vals; i++ )
+ result +=QString::fromLatin1( (const char*) p->vals[i].value );
+ return result;
+}
+
+int KSMClient::restartStyleHint() const
+{
+ SmProp* p = property( SmRestartStyleHint );
+ if ( !p || qstrcmp( p->type, SmCARD8) || p->num_vals < 1)
+ return SmRestartIfRunning;
+ return *((int*)p->vals[0].value);
+}
+
+QString KSMClient::userId() const
+{
+ SmProp* p = property( SmUserID );
+ if ( !p || qstrcmp( p->type, SmARRAY8) || p->num_vals < 1)
+ return QString::null;
+ return QString::fromLatin1( (const char*) p->vals[0].value );
+}
+
+