The KDE XmlRpc Daemon

Executive Description

This document describes the KDE XmlRpc Daemon (kxmlrpcd). This daemon permits a client implemented in nearly any language (python, perl, java, etc) on nearly any platform (Unix, Windows, MacOS, etc) to access KDE DCOP clients (servers). Neither the client nor the server need any modifications (or any extra knowledge) to take advantage of this. Since most KDE applications are or will soon be DCOP client/servers, this effectively means that all KDE apps can be remotely manipulated (scripted) by any language on any platform.

Background

XmlRpc is a standard way of implementing remote procedure calls (RPC) using XML and HTTP. It's goals are to use "commodity" tools for everything so that implementation is as simple as possible. To accomplish this, it uses XML to mark up all of the method calls (and parameters) as well as the return values. It then uses HTTP to transfer the method call.

The advantage of this approach is that nearly every single decent language (scripting or otherwise) has free and easy to use XML parsers and HTTP clients. This makes implementation relatively easy for most parts of XmlRpc. Since it is so easy to implement, there are clients and servers for many languages with more coming at a pretty constant rate.

Please check out http://www.xmlrpc.com for more info (including the spec and a list of clients and servers)

XmlRpc in KDE

As cool as XmlRpc is, it would have been pointless to expect everybody to embed a server into all of their applications when we already had a very fast, easy to use RPC/IPC protocol -- DCOP. As a result, the KDE solution to this is to have a XmlRpc-to-DCOP "gateway". The KDE XmlRpc Daemon (kxmlrpcd) is essentially a web server that "translates" XmlRpc requests to DCOP calls and vice versa.

This has a huge advantage over other possible solutions in that the translation is transparent between the two protocols. The XmlRpc client and DCOP server both think they are communicating only in their native protocol with the daemon. Neither need any modifications in order to work with the other (with one minor exception -- see below)!

Using XmlRpc as a Client

First, you will need to get one of the XmlRpc clients for your favorite language/platform. My personal favorite is the python version offered by PythonWare. It allows you to make XmlRpc calls as if they were local functions!

You need four bits of information to call a DCOP method using XmlRpc.

  1. The port kxmlrpcd is running on
  2. The auth token for authentication
  3. The DCOP server name you want to access
  4. The DCOP object you want to access

The latter two can be discovered by knowing the DCOP object you are trying to access. For instance, if you wanted to have KDesktop popup the Execute Command dialog, you would find that the server name is 'kdesktop' (the DCOPClient::registerAs() name) and the object name is 'KDesktopIface'

The port and "auth token" are both found in the file $HOME/.kxmlrpcd. Your client is responsible for getting both of them. If you are running locally, then all you need do is parse the file. If you are running remotely, then you need to get those values some other way. Some possibilities include mounting the home directory with NFS or SMB or emailing yourself the values or putting them on FTP server or writing them down... whatever it takes.

The "auth token" is a 16 byte string that needs to accompany all incoming XmlRpc requests. This is the one minor change to the "stock" XmlRpc protocol. The very first parameter in your methodCall must be a string and it must be the auth token. Beyond that, the protocol is the same as the standard.

Once that is done, you can make your XmlRpc call like any other call.

Using XmlRpc as a Server

In KDE, you don't use XmlRpc directly as a server. Instead, you create a DCOP server (technically a "client" since DCOP is peer-peer). That's it! If your app is a DCOP server, it automatically has the ability to communicate with XmlRpc clients.

There are some minor restrictions. Mainly, you must pass only QCString as the string type and your use of <struct> and <array> is restricted. See the README file in the source directory for more information on that.

An Example

First, make sure the following is running: dcopserver, kxmlrpcd, and kdesktop. All three should be running in any standard KDE 2.x desktop.

Then, download the python XmlRpc library from pythonware and install it into /usr/lib/python1.5.

Finally, run this script:

#!/usr/bin/python
from xmlrpclib import *
import os

rc = open(os.environ['HOME'] + '/.kxmlrpcd', 'r')
config = string.split(rc.read(), ',')
port = config[0]
auth = config[1]

server = Server("http://localhost:" + port +"/kdesktop")
server.KDesktopIface.popupExecuteCommand(auth);

That's all you need to do to have KDesktop popup the Execute Command dialog! Note that if you are running the python script on a different computer (even a Windows or Macintosh one), you need only change the method of getting the port and auth token.

Don't Have Python?

No problem! Like I said, you can do XmlRpc with nearly any language or platform. By this, I mean that you can do XmlRpc with any standard Unix box using only /bin/sh and telnet!

Here is a script by David Faure <[email protected]> that uses only /bin/sh, cat, wc, and telnet -- utilities found on every single Unix system.

#!/bin/sh

port=`sed -e 's/,.*//' ~/.kxmlrpcd`
auth=`sed -e 's/.*,//' ~/.kxmlrpcd`

cat > cmd.xml <<EOF
<?xml version="1.0"?>
<methodCall>
  <methodName>KDesktopIface.popupExecuteCommand</methodName>
    <params>
      <param>
        <value>$auth</value>
      </param>
  </params>
</methodCall>
EOF

length=`wc -c cmd.xml | sed -e 's/cmd.xml//;s/ //g'`

cat > head.xml <<EOF
POST /kdesktop HTTP/1.0
Content-Type: text/xml
Content-length: $length

EOF

( echo open localhost $port
  sleep 1
  cat head.xml cmd.xml
) | telnet -8E

Yes, this means that you can now script all KDE applications using only /bin/sh and telnet!


Kurt Granroth ([email protected])