1
0
mirror of https://invent.kde.org/network/krfb synced 2024-07-01 07:24:29 +00:00

LAN-Browsing support for krfb using OpenSLP (krdc will follow).

SLP (RFC 2608) allows searching your LAN for services and works either
peer-to-peer or with one or more directory servers. Unlike other browsing
methods it can also work over several subnets (at least if your router can
route multicast traffic). You can get the library and instructions (you
need to run a small daemon on each system that announces services) at
www.openslp.org.

This patch adds:
- a generic class for registering SLP services
- a class to find your computer's LAN and non-public Internet address
  (replaces the code in configuration_hostname.cpp, should be more
   reliable and work better on non-Linux-machines)
- generic SLP support for kinetd
- SLP announcements when krfb/kinetd is open for uninvited connections
  (invited connections will not be announced)

If OpenSLP is not installed configure should disable the feature. The code
uses the SLP API as specified in RFC 2614 and it would be interesting to know
whether it also supports the SLP library that ships with Solaris - maybe
the configure script has to be tweaked for this...

(wow, i'm really communicative today)

svn path=/trunk/kdenetwork/krfb/; revision=166638
This commit is contained in:
Tim Jansen 2002-07-14 15:14:19 +00:00
parent 2214dbbc98
commit 41a9dc2161
20 changed files with 1082 additions and 202 deletions

View File

@ -1,4 +1,4 @@
SUBDIRS = kinetd libvncserver krfb kcm_krfb
SUBDIRS = srvloc kinetd libvncserver krfb kcm_krfb
EXTRA_DIST = AUTHORS COPYING ChangeLog INSTALL README TODO NOTES \
ROADMAP DCOP-INTERFACE krfb.lsm

11
TODO
View File

@ -1,14 +1,17 @@
For 3.1:
- SLP support
- NAT traversal support if I can find an acceptable implementation (using DTCP, probably)
- write SLP service template for remote desktop protocols
Todo (unscheduled features):
- split krfb into 2 seperate programs (server and invitation)
- NAT traversal support if I can find an acceptable implementation
(probably using STUN as described in
draft-simu-midcom-stun-aware-nat-00.txt)
- split krfb into 2 separate programs (server and invitation)
- user/password authentication mechanism (kerberos)?
- SSL/TLS support?
- look into adding an extension to xfree to improve speed (get noticed of
screen updates) or maybe use the translucency extensino if finished
- cut&paste support
- cut & paste support
Known bugs/problems:
- the IP address sent in invitation may be wrong on multi-homed machines, and it

View File

@ -3,6 +3,19 @@ KDE_CHECK_HEADER(X11/extensions/XTest.h,
AC_MSG_ERROR([XTest extension header not found / no xlib headers]))
#check for SLP
AC_MSG_CHECKING(for SLP support)
save_krfb_LIBS="$LIBS"
LIBS="-lslp"
AC_TRY_LINK( [
#include <slp.h>
],[
SLPOpen(0, SLP_FALSE, (SLPHandle*) 0);
],[
AC_DEFINE(HAVE_SLP,1,[Define if SLP is available])
AC_MSG_RESULT(yes)
],[
AC_MSG_RESULT(no)
AC_MSG_WARN([Browsing in krfb not possible. Install OpenSLP (www.openslp.org).])
])
LIBS=$save_krfb_LIBS

View File

@ -5,7 +5,8 @@ lib_LTLIBRARIES = libkded_kinetd.la
libkded_kinetd_la_SOURCES = kinetd.cpp kinetd.skel
libkded_kinetd_la_LDFLAGS = $(all_libraries) -module -avoid-version
libkded_kinetd_la_LIBADD = $(LIB_QT) $(LIB_KDECORE) $(LIB_KDEUI)
libkded_kinetd_la_LIBADD = ../srvloc/libsrvloc.la $(LIB_QT) $(LIB_KDECORE) \
$(LIB_KDEUI) -lslp
# Services
kde_servicetypes_DATA = kinetdmodule.desktop
@ -24,6 +25,6 @@ install-data-local:
$(INSTALL_DATA) $(srcdir)/eventsrc $(DESTDIR)$(kde_datadir)/kinetd/eventsrc
# set the include path for X, qt and KDE
INCLUDES= $(all_includes)
INCLUDES= $(all_includes) -I$(top_srcdir)/krfb/srvloc

View File

@ -18,6 +18,8 @@
#include "kinetd.h"
#include "kinetd.moc"
#include "kinetaddr.h"
#include <qregexp.h>
#include <kservicetype.h>
#include <kdebug.h>
#include <kstandarddirs.h>
@ -27,10 +29,14 @@
#include <kextsock.h>
#include <klocale.h>
PortListener::PortListener(KService::Ptr s, KConfig *config) :
PortListener::PortListener(KService::Ptr s,
KConfig *config,
KServiceRegistry *srvreg) :
m_port(-1),
m_serviceRegistered(false),
m_socket(0),
m_config(config)
m_config(config),
m_srvreg(srvreg)
{
loadConfig(s);
@ -63,9 +69,21 @@ bool PortListener::acquirePort() {
}
connect(m_socket, SIGNAL(accepted(KSocket*)),
SLOT(accepted(KSocket*)));
bool s = m_registerService;
setServiceRegistrationEnabledInternal(false);
setServiceRegistrationEnabledInternal(s);
return true;
}
void PortListener::freePort() {
m_port = -1;
if (m_socket)
delete m_socket;
m_socket = 0;
setServiceRegistrationEnabledInternal(m_registerService);
}
void PortListener::loadConfig(KService::Ptr s) {
m_valid = true;
m_autoPortRange = 0;
@ -73,7 +91,7 @@ void PortListener::loadConfig(KService::Ptr s) {
m_argument = QString::null;
m_multiInstance = false;
QVariant vid, vport, vautoport, venabled, vargument, vmultiInstance;
QVariant vid, vport, vautoport, venabled, vargument, vmultiInstance, vurl, vsattributes;
m_execPath = s->exec().utf8();
vid = s->property("X-KDE-KINETD-id");
@ -82,6 +100,8 @@ void PortListener::loadConfig(KService::Ptr s) {
venabled = s->property("X-KDE-KINETD-enabled");
vargument = s->property("X-KDE-KINETD-argument");
vmultiInstance = s->property("X-KDE-KINETD-multiInstance");
vurl = s->property("X-KDE-KINETD-serviceURL");
vsattributes = s->property("X-KDE-KINETD-serviceAttributes");
if (!vid.isValid()) {
kdDebug() << "Kinetd cannot load service "<<m_serviceName
@ -107,6 +127,19 @@ void PortListener::loadConfig(KService::Ptr s) {
m_argument = vargument.toString();
if (vmultiInstance.isValid())
m_multiInstance = vmultiInstance.toBool();
if (vurl.isValid()) {
m_serviceURL = vurl.toString();
m_registerService = true;
}
else {
m_serviceURL = QString::null;
m_registerService = false;
}
if (vsattributes.isValid()) {
m_serviceAttributes = vsattributes.toString();
}
else
m_serviceAttributes = "";
m_defaultPortBase = m_portBase;
m_defaultAutoPortRange = m_autoPortRange;
@ -119,10 +152,12 @@ void PortListener::loadConfig(KService::Ptr s) {
m_autoPortRange = m_config->readNumEntry("auto_port_range_" + m_serviceName,
m_autoPortRange);
QDateTime nullTime;
m_expirationTime = m_config->readDateTimeEntry("enabled_expiration_"+m_serviceName,
m_expirationTime = m_config->readDateTimeEntry("enabled_expiration_"+m_serviceName,
&nullTime);
if ((!m_expirationTime.isNull()) && (m_expirationTime < QDateTime::currentDateTime()))
m_enabled = false;
m_registerService = m_config->readBoolEntry("enabled_srvreg_"+m_serviceName,
m_registerService);
}
void PortListener::accepted(KSocket *sock) {
@ -163,6 +198,14 @@ int PortListener::port() {
return m_port;
}
QString PortListener::serviceURL() {
KInetAddress *a = KInetAddress::getLocalAddress();
QString hostName = a->nodeName();
delete a;
return m_serviceURL.replace(QRegExp("%h"), hostName)
.replace(QRegExp("%p"), QString::number(m_port));
}
bool PortListener::setPort(int port, int autoPortRange) {
if ((port == m_portBase) && (autoPortRange == m_autoPortRange))
return (m_port != -1);
@ -195,34 +238,58 @@ void PortListener::setEnabled(bool e) {
}
void PortListener::setEnabledInternal(bool e, const QDateTime &ex) {
m_config->setGroup("ListenerConfig");
m_config->writeEntry("enabled_" + m_serviceName, e);
m_config->writeEntry("enabled_expiration_"+m_serviceName, ex);
m_config->sync();
m_expirationTime = ex;
if (e) {
if (m_port < 0)
acquirePort();
if (m_port < 0) {
m_enabled = false;
return;
}
m_enabled = m_port >= 0;
}
else {
m_port = -1;
if (m_socket)
delete m_socket;
m_socket = 0;
freePort();
m_enabled = false;
}
m_enabled = e;
m_config->setGroup("ListenerConfig");
m_config->writeEntry("enabled_" + m_serviceName, m_enabled);
m_config->writeEntry("enabled_expiration_"+m_serviceName, ex);
m_config->sync();
}
void PortListener::setEnabled(const QDateTime &ex) {
setEnabledInternal(true, ex);
}
bool PortListener::isServiceRegistrationEnabled() {
return m_registerService;
}
void PortListener::setServiceRegistrationEnabled(bool e) {
setServiceRegistrationEnabledInternal(e);
m_config->setGroup("ListenerConfig");
m_config->writeEntry("enable_srvreg_" + m_serviceName, e);
m_config->sync();
}
void PortListener::setServiceRegistrationEnabledInternal(bool e) {
m_registerService = e;
if ((!m_srvreg) || m_serviceURL.isNull())
return;
if (m_serviceRegistered == (m_enabled && e))
return;
if (m_enabled && e) {
m_serviceRegistered = m_srvreg->registerService(serviceURL(),
m_serviceAttributes);
if (!m_serviceRegistered)
kdDebug(7021) << "Failure registering SLP service (no slpd running?)"<< endl;
} else {
m_srvreg->unregisterService(serviceURL());
m_serviceRegistered = false;
}
}
QDateTime PortListener::expiration() {
return m_expirationTime;
}
@ -232,6 +299,7 @@ QString PortListener::name() {
}
PortListener::~PortListener() {
setServiceRegistrationEnabledInternal(false);
if (m_socket)
delete m_socket;
if (m_config)
@ -243,6 +311,12 @@ KInetD::KInetD(QCString &n) :
KDEDModule(n)
{
m_config = new KConfig("kinetdrc");
m_srvreg = new KServiceRegistry();
if (!m_srvreg->available()) {
kdDebug(7021) << "SLP not available"<< endl;
delete m_srvreg;
m_srvreg = 0;
}
m_portListeners.setAutoDelete(true);
connect(&m_expirationTimer, SIGNAL(timeout()), SLOT(setExpirationTimer()));
connect(&m_portRetryTimer, SIGNAL(timeout()), SLOT(portRetryTimer()));
@ -260,7 +334,7 @@ void KInetD::loadServiceList()
it != kinetdModules.end();
it++) {
KService::Ptr s = *it;
PortListener *pl = new PortListener(s, m_config);
PortListener *pl = new PortListener(s, m_config, m_srvreg);
if (pl->isValid())
m_portListeners.append(pl);
}
@ -398,6 +472,30 @@ void KInetD::setEnabled(QString service, QDateTime expiration)
setExpirationTimer();
}
void KInetD::setServiceRegistrationEnabled(QString service, bool enable)
{
PortListener *pl = getListenerByName(service);
if (!pl)
return;
pl->setServiceRegistrationEnabled(enable);
}
bool KInetD::isServiceRegistrationEnabled(QString service)
{
PortListener *pl = getListenerByName(service);
if (!pl)
return false;
return pl->isServiceRegistrationEnabled();
}
KInetD::~KInetD() {
m_portListeners.clear();
delete m_config;
if (m_srvreg)
delete m_srvreg;
}
extern "C" {
KDEDModule *create_kinetd(QCString &name)

View File

@ -28,11 +28,14 @@
#include <qdatetime.h>
#include <qtimer.h>
#include "kserviceregistry.h"
class PortListener : public QObject {
Q_OBJECT
private:
bool m_valid;
QString m_serviceName;
QString m_serviceURL, m_serviceAttributes;
int m_port;
int m_portBase, m_autoPortRange;
int m_defaultPortBase, m_defaultAutoPortRange;
@ -40,17 +43,22 @@ private:
QString m_execPath;
QString m_argument;
bool m_enabled;
bool m_serviceRegistered, m_registerService;
QDateTime m_expirationTime;
KServerSocket *m_socket;
KProcess m_process;
KConfig *m_config;
KServiceRegistry *m_srvreg;
void freePort();
void loadConfig(KService::Ptr s);
void setEnabledInternal(bool e, const QDateTime &ex);
void setServiceRegistrationEnabledInternal(bool enabled);
public:
PortListener(KService::Ptr s, KConfig *c);
PortListener(KService::Ptr s, KConfig *c, KServiceRegistry *srvreg);
~PortListener();
bool acquirePort();
@ -58,9 +66,12 @@ public:
QString name();
void setEnabled(bool enabled);
void setEnabled(const QDateTime &expiration);
void setServiceRegistrationEnabled(bool enabled);
bool isServiceRegistrationEnabled();
QDateTime expiration();
bool isEnabled();
int port();
QString serviceURL();
bool setPort(int port = -1, int autoProbeRange = 1);
private slots:
@ -130,11 +141,30 @@ k_dcop:
*/
bool isInstalled(QString service);
/**
* Enables or disables the SLP registration. Ignored if the service does
* not have a service URL. If the service is disabled the service will
* registered as soon as it is enabled.
* @param service name of a service as specified in its .desktop file
* @param enable true to enable, false to disable.
*/
void setServiceRegistrationEnabled(QString service, bool enabled);
/**
* Returns true if service registration for the given service is enabled.
* Note that this does not mean that the service is currently registered,
* because the service may be disabled.
* @param service name of a service as specified in its .desktop file
* @return true if service registration is enabled
*/
bool isServiceRegistrationEnabled(QString service);
private:
QDateTime getNextExpirationTime();
void setPortRetryTimer(bool retry);
KConfig *m_config;
KServiceRegistry *m_srvreg;
QPtrList<PortListener> m_portListeners;
QTimer m_expirationTimer;
QTimer m_portRetryTimer;
@ -145,6 +175,7 @@ k_dcop:
public:
KInetD(QCString &n);
virtual ~KInetD();
void loadServiceList();
PortListener *getListenerByName(QString name);
};

View File

@ -4,6 +4,17 @@
Type=ServiceType
X-KDE-ServiceType=KInetDModule
Name=KInetD Module Type
Name[bs]=KInetD tip modula
Name[da]=KInetD-modultype
Name[el]=Τύπος αρθρώματος KInetD
Name[es]=Tipo de módulo KInetD
Name[fi]=KInetD modulityyppi
Name[he]=סוג מודול של KInetD
Name[hr]=Tip KInetD Modula
Name[pt_BR]=Módulo KInetD
Name[ro]=Tip modul KInetD
Name[sv]=Kinetd-modultyp
Name[tr]=KDED Modül Türü
# id to manipulate the service
[PropertyDef::X-KDE-KINETD-id]
@ -13,22 +24,36 @@ Type=QString
[PropertyDef::X-KDE-KINETD-port]
Type=int
# if set and >0 the number of ports kinetd should probe if the port is in use
# if set and >0, the number of ports kinetd should probe if the port is in use
[PropertyDef::X-KDE-KINETD-autoPortRange]
Type=int
# if enabled kinetd will listen on the port. Can be overridden using the
# if enabled, kinetd will listen on the port. Can be overridden using the
# dcop interface.
[PropertyDef::X-KDE-KINETD-enabled]
Type=bool
# if set this argument if given to the app to start, followed by the number
# if set, this argument is given to the app to start, followed by the number
# of the socket's fd
[PropertyDef::X-KDE-KINETD-argument]
Type=QString
# if true kinetd can accepts several connections at the same time. Otherwise
# if true, kinetd can accepts several connections at the same time. Otherwise
# it will block the port when a connection has been established.
[PropertyDef::X-KDE-KINETD-multiInstance]
Type=bool
# if set, kinetd will register the given URL at the local SLP SA while
# the port is open. The following strings will be substituted:
# %h with the local IP address
# %p with the port number
[PropertyDef::X-KDE-KINETD-serviceURL]
Type=QString
# if kinetd registers a service URL, this string will be used for its attributes.
# The following strings will be substituted:
# %h with the local IP address
# %p with the port number
[PropertyDef::X-KDE-KINETD-serviceAttributes]
Type=QString

View File

@ -4,15 +4,14 @@ METASOURCES = AUTO
noinst_LTLIBRARIES = libkrfbconfig.la
libkrfbconfig_la_SOURCES = configuration.cc manageinvitations.ui \
personalinvitation.ui invite.ui invitation.cc \
configuration_hostname.cpp
personalinvitation.ui invite.ui invitation.cc
libkrfbconfig_la_LIBADD = ../srvloc/libsrvloc.la -lslp $(LIB_KDEUI)
bin_PROGRAMS = krfb
krfb_SOURCES = rfbcontroller.cc xupdatescanner.cc main.cpp \
newconnectiondialog.ui krfbifaceimpl.cc krfbiface.skel \
trayicon.cpp
krfb_LDADD = libkrfbconfig.la ../libvncserver/libvncserver.la -lXtst $(LIB_KDEUI) $(LIBJPEG)
krfb_LDADD = libkrfbconfig.la ../libvncserver/libvncserver.la ../srvloc/libsrvloc.la -lXtst $(LIB_KDEUI) $(LIBJPEG) -lslp
krfb_LDFLAGS = $(all_libraries) $(KDE_RPATH)
noinst_HEADER = configuration.h invitation.h invite.h krfbiface.h \
@ -32,7 +31,8 @@ app_DATA = eventsrc
KDE_ICON = krfb
INCLUDES= -I$(top_srcdir)/krfb/libvncserver $(all_includes)
INCLUDES= -I$(top_srcdir)/krfb/libvncserver -I$(top_srcdir)/krfb/srvloc \
$(all_includes)
messages: rc.cpp
$(XGETTEXT) rc.cpp *.cpp *.cc -o $(podir)/krfb.pot

View File

@ -16,6 +16,7 @@
***************************************************************************/
#include "configuration.h"
#include "kinetaddr.h"
#include <kglobal.h>
#include <klocale.h>
@ -110,6 +111,16 @@ void Configuration::setKInetdEnabled(const QDateTime &date) {
d->send ("kded", "kinetd", "setEnabled(QString,QDateTime)", sdata);
}
void Configuration::setKInetdServiceRegistrationEnabled(bool enabled) {
DCOPClient *d = KApplication::dcopClient();
QByteArray sdata;
QDataStream arg(sdata, IO_WriteOnly);
arg << QString("krfb");
arg << enabled;
d->send ("kded", "kinetd", "setServiceRegistrationEnabled(QString,bool)", sdata);
}
void Configuration::getPortFromKInetd() {
DCOPClient *d = KApplication::dcopClient();
@ -148,6 +159,7 @@ void Configuration::doKinetdConf() {
if (allowUninvitedFlag) {
setKInetdEnabled(true);
setKInetdServiceRegistrationEnabled(true);
getPortFromKInetd();
return;
}
@ -166,23 +178,12 @@ void Configuration::doKinetdConf() {
portNum = -1;
}
else {
setKInetdServiceRegistrationEnabled(false);
setKInetdEnabled(lastExpiration);
getPortFromKInetd();
}
}
/*
* Function for (en/de)crypting strings for config file, taken from KMail
* Author: Stefan Taferner <taferner@alpin.or.at>
*/
QString cryptStr(const QString &aStr) {
QString result;
for (unsigned int i = 0; i < aStr.length(); i++)
result += (aStr[i].unicode() < 0x20) ? aStr[i] :
QChar(0x1001F - aStr[i].unicode());
return result;
}
void Configuration::loadFromKConfig() {
KConfig c("krfbrc");
@ -195,7 +196,6 @@ void Configuration::loadFromKConfig() {
else
passwordString = c.readEntry("uninvitedPassword", "");
unsigned int invNum = invitationList.size();
invitationList.clear();
c.setGroup("invitations");
@ -277,6 +277,14 @@ void Configuration::refreshTimeout() {
}
}
QString Configuration::hostname() const
{
KInetAddress *a = KInetAddress::getPrivateInetAddress();
QString hostName = a->nodeName();
delete a;
return hostName;
}
///////// properties ///////////////////////////
krfb_mode Configuration::mode() const {

View File

@ -112,6 +112,7 @@ private:
void invalidateOldInvitations();
void setKInetdEnabled(const QDateTime &date);
void setKInetdEnabled(bool enabled);
void setKInetdServiceRegistrationEnabled(bool enabled);
void getPortFromKInetd();
void setKInetdPort(int port);
void doKinetdConf();

View File

@ -1,146 +0,0 @@
#include "configuration.h"
/*
* Most of this code has been taken from KPhone/libdissipate's SIPUtil class.
* Copyright (c) 2000 Billy Biggs <bbiggs@div8.net>
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/utsname.h>
#include <sys/socket.h>
#include <sys/time.h>
/* WirLab 29.1.2002 */
#include <sys/errno.h>
/* WirLab 31.1.2002 */
#include <net/if.h>
#include <net/if_arp.h>
#include <net/route.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <qmessagebox.h>
#include <qstring.h>
/*--*/
#include <netdb.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#ifdef USE_SOLARIS
#include <sys/sockio.h>
#endif
static char *dissipate_our_fqdn = NULL;
/* max number of network interfaces*/
#define MAX_IF 5
/* Path to the route entry in proc filesystem */
#define PROCROUTE "/proc/net/route"
/* file containing the hostname of the machine */
/* This is the name for slackware and redhat */
#define HOSTFILE "/etc/HOSTNAME"
/* and this is the name for debian */
/* #define HOSTFILE "/etc/HOSTNAME" */
#ifndef SIOCGIFCOUNT
#define SIOCGIFCOUNT 0x8935
#endif
char iface[16];
/* This searches the proc routing entry for the interface the default gateway
 * is on, and returns the name of that interface.
 */
char *getdefaultdev()
{
FILE *fp = fopen( PROCROUTE, "r");
char buff[4096], gate_addr[128], net_addr[128];
char mask_addr[128];
int irtt, window, mss, num, metric, iflags, refcnt, use;
char i;
if( !fp ) {
return NULL;
}
i=0;
// cruise through the list, and find the gateway interface
while( fgets(buff, 1023, fp) ) {
num = sscanf(buff, "%s %s %s %X %d %d %d %s %d %d %d\n",
iface, net_addr, gate_addr, &iflags, &refcnt, &use, &metric,
&mask_addr, &mss, &window, &irtt);
i++;
if( i == 1) continue;
if( iflags & RTF_GATEWAY )
return iface;
}
fclose(fp);
/* didn't find a default gateway */
return NULL;
}
void findFqdn( void )
{
int sock, err, if_count, i, j = 0;
struct ifconf netconf;
char buffer[32*MAX_IF];
char if_name[10][21];
char if_addr[10][21];
char *default_ifName;
netconf.ifc_len = 32 * MAX_IF;
netconf.ifc_buf = buffer;
sock=socket( PF_INET, SOCK_DGRAM, 0 );
err=ioctl( sock, SIOCGIFCONF, &netconf );
if ( err < 0 ) printf( "Error in ioctl: %i.\n", errno );
close( sock );
if_count = netconf.ifc_len / 32;
for( i = 0; i < if_count; i++ ) {
if( strcmp( netconf.ifc_req[i].ifr_name, "lo" ) != 0 ) {
strncpy( if_name[j], netconf.ifc_req[i].ifr_name, 20 );
strncpy( if_addr[j], inet_ntoa(((struct sockaddr_in*)(&netconf.ifc_req[i].ifr_addr))->sin_addr), 20 );
j++;
}
}
if(j == 0) {
dissipate_our_fqdn = NULL;
return;
}
if(j == 1) {
dissipate_our_fqdn = strdup( if_addr[0] );
return;
}
default_ifName = getdefaultdev();
if( default_ifName != NULL) {
for( i = 0; i < j; i++ ) {
if( strcmp( if_name[i], default_ifName ) == 0 ) {
dissipate_our_fqdn = strdup( if_addr[i] );
return;
}
}
}
dissipate_our_fqdn = strdup( if_addr[0] );
}
QString Configuration::hostname() const
{
if ( dissipate_our_fqdn == NULL ) {
findFqdn();
}
return QString(dissipate_our_fqdn);
}

View File

@ -3,6 +3,7 @@
-------------------
begin : Sat Mar 30 2002
copyright : (C) 2002 by Tim Jansen
(C) Stefan Taferner (password encryption)
email : tim@tjansen.de
***************************************************************************/
@ -17,6 +18,19 @@
#include "invitation.h"
/*
* Function for (en/de)crypting strings for config file, taken from KMail
* Author: Stefan Taferner <taferner@alpin.or.at>
*/
QString cryptStr(const QString &aStr) {
QString result;
for (unsigned int i = 0; i < aStr.length(); i++)
result += (aStr[i].unicode() < 0x20) ? aStr[i] :
QChar(0x1001F - aStr[i].unicode());
return result;
}
Invitation::Invitation() :
m_viewItem(0) {
m_password = KApplication::randomString(4)+
@ -34,7 +48,7 @@ Invitation::Invitation(const Invitation &x) :
}
Invitation::Invitation(KConfig* config, int num) {
m_password = config->readEntry(QString("password%1").arg(num), "");
m_password = cryptStr(config->readEntry(QString("password%1").arg(num), ""));
m_creationTime = config->readDateTimeEntry(QString("creation%1").arg(num));
m_expirationTime = config->readDateTimeEntry(QString("expiration%1").arg(num));
m_viewItem = 0;
@ -56,7 +70,7 @@ Invitation &Invitation::operator= (const Invitation&x) {
}
void Invitation::save(KConfig *config, int num) const {
config->writeEntry(QString("password%1").arg(num), m_password);
config->writeEntry(QString("password%1").arg(num), cryptStr(m_password));
config->writeEntry(QString("creation%1").arg(num), m_creationTime);
config->writeEntry(QString("expiration%1").arg(num), m_expirationTime);
}

View File

@ -28,6 +28,8 @@
const int INVITATION_DURATION = 60*60;
QString cryptStr(const QString &aStr);
class Invitation {
public:
Invitation();

View File

@ -11,13 +11,28 @@ X-KDE-KINETD-autoPortRange=100
X-KDE-KINETD-enabled=false
X-KDE-KINETD-argument=--kinetd
X-KDE-KINETD-multiInstance=false
X-KDE-KINETD-serviceURL=service:remotedesktop.kde:vnc://%h:%p
Name=KRfb Desktop Sharing
Name[da]=KRfb Skrivebords-deling
Name[bs]=KRfb dijeljenje desktopa
Name[da]=KRfb Skrivebordsdeling
Name[el]=KRfb μοίρασμα επιφάνειας εργασίας
Name[es]=Compartición de escritorio KRfb
Name[fi]=KRfb työpöytien jako
Name[he]=שיתוף שולחנות עבודה של KRfb
Name[hr]=KRfb dijeljenje radne površine
Name[pt_BR]=Compartilhamento do Ambiente de Trabalho KRfb
Name[ro]=Partajare ecran KRfb
Name[sv]=Krfb dela ut skrivbord
Comment=A daemon that allows you to share your desktop
Comment[af]='n bediener wat laat toe jy aan deel jou werkskerm
Comment[bs]=Daemon koji vam omogućuje da dijelite vaš desktop
Comment[da]=En dæmon der tillader dig at dele dit skrivebord
Comment[el]=Ένας δαίμονας που σας επιτρέπει να μοιραστείτε την επιφάνεια εργασίας σας
Comment[es]=Un demonio que le permite compartir su escritorio
Comment[fi]=Palvelin joka mahdollistaa työpöytien jaon
Comment[he]=תהליך שירות שמאפשר לך לשתף את שולחן העבודה שלך
Comment[hr]=Daemon koji vam omogućuje da dijelite svoju radnu površinu s drugima
Comment[pt_BR]=Um servidor que permite a você compartilhar o seu ambiente de trabalho
Comment[ro]=Un demon care vă permite saă partajaţi sistemul dumneavoastră
Comment[sv]=Demon som låter dig dela ut skrivbordet

13
srvloc/Makefile.am Normal file
View File

@ -0,0 +1,13 @@
METASOURCES = AUTO
# Code
lib_LTLIBRARIES = libsrvloc.la
libsrvloc_la_SOURCES = kinetaddr.cpp kinetaddr_ipfinder.cpp \
kserviceregistry.cpp
libsrvloc_la_LIBADD = $(LIB_QT) $(LIB_KDECORE)
noinst_HEADERS = kinetaddr.h kserviceregistry.h
# set the include path for X, qt and KDE
INCLUDES= $(all_includes)

167
srvloc/kinetaddr.cpp Normal file
View File

@ -0,0 +1,167 @@
/*
* This file is part of the KDE libraries
* Copyright (C) 2002 Tim Jansen <tim@tjansen.de>
* based on code from KInetSocketAddress:
* Copyright (C) 2000,2001 Thiago Macieira <thiagom@mail.com>
*
* $Id$
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
**/
#include <config.h>
#include <limits.h>
#include <string.h>
#include <kdebug.h>
#include <klocale.h>
#include "kinetaddr.h"
#include <netdb.h>
#define V6_CAN_CONVERT_TO_V4(addr) (KDE_IN6_IS_ADDR_V4MAPPED(addr) || KDE_IN6_IS_ADDR_V4COMPAT(addr))
// This is how it is
// 46 == strlen("1234:5678:9abc:def0:1234:5678:255.255.255.255")
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 46
#endif
class KInetAddressPrivate
{
public:
int sockfamily;
struct in_addr in;
#ifdef AF_INET6
struct in6_addr in6;
#endif
KInetAddressPrivate() : sockfamily(AF_UNSPEC)
{
bzero((void*)&in, sizeof(in));
#ifdef AF_INET6
bzero((void*)&in6, sizeof(in6));
#endif
}
};
KInetAddress::KInetAddress(const KInetAddress &other) :
d(new KInetAddressPrivate)
{
d->sockfamily = other.d->sockfamily;
memcpy(&d->in, &other.d->in, sizeof(d->in));
#ifdef AF_INET6
memcpy(&d->in6, &other.d->in6, sizeof(d->in6));
#endif
}
KInetAddress::KInetAddress(const struct in_addr& in) :
d(new KInetAddressPrivate)
{
d->sockfamily = AF_INET;
memcpy(&d->in, &in, sizeof(in));
}
KInetAddress::KInetAddress(const struct in6_addr& in6) :
d(new KInetAddressPrivate)
{
#ifdef AF_INET6
d->sockfamily = AF_INET6;
memcpy(&d->in6, &in6, sizeof(in6));
#else
d->sockfamily = AF_UNSPEC;
#endif
}
KInetAddress::KInetAddress(const QString &host) :
d(new KInetAddressPrivate)
{
struct hostent *h = gethostbyname(host.latin1());
if ((!h) || (!h->h_addr_list) || (!h->h_addr_list[0])) {
d->sockfamily = AF_UNSPEC;
return;
}
d->sockfamily = h->h_addrtype;
#ifdef AF_INET6
if (h->h_addrtype == AF_INET6)
memcpy(&d->in6, h->h_addr_list[0], h->h_length);
else
memcpy(&d->in, h->h_addr_list[0], h->h_length);
#else
memcpy(&d->in, h->h_addr_list[0], h->h_length);
#endif
}
KInetAddress::~KInetAddress()
{
delete d;
}
const struct in_addr *KInetAddress::addressV4() const {
if (d->sockfamily != AF_INET)
return 0;
return &d->in;
}
const struct in6_addr *KInetAddress::addressV6() const {
if (d->sockfamily != AF_INET6)
return 0;
return &d->in6;
}
QString KInetAddress::nodeName() const
{
char buf[INET6_ADDRSTRLEN+1]; // INET6_ADDRSTRLEN > INET_ADDRSTRLEN
if (d->sockfamily == AF_INET)
inet_ntop(d->sockfamily, (void*)&d->in, buf, sizeof(buf));
#ifdef AF_INET6
else if (d->sockfamily == AF_INET6)
inet_ntop(d->sockfamily, (void*)&d->in6, buf, sizeof(buf));
#endif
else {
kdWarning() << "KInetAddress::nodeName() called on uninitialized class\n";
return i18n("<empty>");
}
return QString::fromLatin1(buf); // FIXME! What's the encoding?
}
bool KInetAddress::areEqual(const KInetAddress &a1, const KInetAddress &a2)
{
if (a1.d->sockfamily != a2.d->sockfamily)
return false;
if (a1.d->sockfamily == AF_INET) {
return (memcmp(&a1.d->in.s_addr, &a2.d->in.s_addr,
sizeof(a1.d->in.s_addr)) == 0);
}
#ifdef AF_INET6
if (a1.d->sockfamily == AF_INET6) {
return (memcmp(&a1.d->in6.s6_addr, &a2.d->in6.s6_addr,
sizeof(a1.d->in6.s6_addr)) == 0);
}
#endif
return true;
}

151
srvloc/kinetaddr.h Normal file
View File

@ -0,0 +1,151 @@
/*
* This file is part of the KDE libraries
* Copyright (C) 2002 Tim Jansen <tim@tjansen.de>
* based on code from KInetSocketAddress:
* Copyright (C) 2000,2001 Thiago Macieira <thiagom@mail.com>
*
* $Id$
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef KINETADDR_H
#define KINETADDR_H
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <qobject.h>
#include <qcstring.h>
#include <qstring.h>
class KInetAddressPrivate;
/**
* An Inet (IPv4 or IPv6) address.
*
* This class represents an internet (IPv4 or IPv6) address. The difference
* between KInetAddress and KInetSocketAddress is that the socket address
* consists of the address and the port, KInetAddress peresents only the
* address itself.
*
* @author Tim Jansen <tim@tjansen.de>
* @short an Internet Address
*/
class KInetAddress {
public:
/**
* Copy constructor
*/
KInetAddress(const KInetAddress&);
/**
* Creates an IPv4 socket from in_addr
* @param in a in_addr structure to copy from
* @param len the socket address length
*/
KInetAddress(const struct in_addr& in);
/**
* Creates an IPv6 socket from in6_addr
* @param in6 a in_addr6 structure to copy from
* @param len the socket address length
*/
KInetAddress(const struct in6_addr& in6);
/**
* Creates a socket from text representation. Be careful with names
* as they may require a name server lookup which can block for a
* long time.
*
* @param addr a text representation of the address
*/
KInetAddress(const QString& addr);
/**
* Destructor
*/
virtual ~KInetAddress();
/**
* Returns a text representation of the host address
*/
virtual QString nodeName() const;
bool isEqual(const KInetAddress* other) const
{ return areEqual(*this, *other); }
bool operator==(const KInetAddress& other) const
{ return areEqual(*this, other); }
static bool areEqual(const KInetAddress &a1, const KInetAddress &a2);
/**
* Returns the in_addr structure. The pointer is valid as long as
* the KInetAddress object lives.
* This will be NULL if this is not a v4 address.
* @see addressV6
*/
const struct in_addr* addressV4() const;
/**
* Returns the in6_addr structure. The pointer is valid as long as
* the KInetAddress object lives.
* This will be NULL if this is not a v6 address.
* @see addressV4
*/
const struct in6_addr* addressV6() const;
operator const struct in_addr*() const
{ return addressV4(); }
operator const struct in6_addr*() const
{ return addressV6(); }
/**
* Returns an address that can be used for communication with
* other computers on the internet.
* Note that the returned address is not always a real
* internet address, because the computer may not be able to connect
* to the internet or is behind a NAT gateway.
* In the worst case you will get the address of the local loopback
* interface.
* The user is responsible for freeing the object.
* @return a new KInetAddress object that contains the address
*/
static KInetAddress* getPrivateInetAddress();
/**
* Returns the address of the interface that should be used
* to announce local services.
* Note that the returned address is not always a real internet address,
* because the computer may be behind a NAT gateway, or
* it is no connected to the internet. In the worst case you
* will get the address of the local loopback interface.
* The user is responsible for freeing the object.
* @return a new KInetAddress object that contains the address
*/
static KInetAddress* getLocalAddress();
private:
KInetAddressPrivate* d;
};
#endif

View File

@ -0,0 +1,195 @@
/*
* This file is part of the KDE libraries
* Copyright (C) 2002 Tim Jansen <tim@tjansen.de>
* based on code from KInetSocketAddress:
* Copyright (C) 2000,2001 Thiago Macieira <thiagom@mail.com>
*
* $Id$
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
**/
#include <config.h>
#include <kdebug.h>
#include "kinetaddr.h"
/*
* This code is based on KPhone/libdissipate's SIPUtil class.
* Copyright (c) 2000 Billy Biggs <bbiggs@div8.net>
*
* The code is far from being perfect, and gateway detection only works on
* Linux. Later there should be a way to configure the addresses using
* a KCM.
*
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/utsname.h>
#include <sys/socket.h>
#include <sys/time.h>
/* WirLab 29.1.2002 */
#include <sys/errno.h>
/* WirLab 31.1.2002 */
#include <net/if.h>
#include <net/if_arp.h>
#include <net/route.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
/*--*/
#include <netdb.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#ifdef USE_SOLARIS
#include <sys/sockio.h>
#endif
static char *local_address = NULL;
static char *inet_address = NULL;
/* max number of network interfaces*/
#define MAX_IF 8
/* Path to the route entry in proc filesystem */
#define PROCROUTE "/proc/net/route"
#ifndef SIOCGIFCOUNT
#define SIOCGIFCOUNT 0x8935
#endif
char iface[16];
/* This searches the proc routing entry for the interface the default gateway
 * is on, and returns the name of that interface.
 */
char *getdefaultdev()
{
FILE *fp = fopen( PROCROUTE, "r");
char buff[4096], gate_addr[128], net_addr[128];
char mask_addr[128];
int irtt, window, mss, num, metric, iflags, refcnt, use;
char i;
if( !fp ) {
return NULL;
}
i=0;
// cruise through the list, and find the gateway interface
while( fgets(buff, 1023, fp) ) {
num = sscanf(buff, "%s %s %s %X %d %d %d %s %d %d %d\n",
iface, net_addr, gate_addr, &iflags, &refcnt, &use, &metric,
&mask_addr, &mss, &window, &irtt);
i++;
if( i == 1) continue;
if( iflags & RTF_GATEWAY )
return iface;
}
fclose(fp);
/* didn't find a default gateway */
return NULL;
}
static void findAddresses( void )
{
int sock, err, if_count, i, j = 0;
struct ifconf netconf;
char buffer[32*MAX_IF];
char if_name[10][21];
char if_addr[10][21];
char *default_ifName;
netconf.ifc_len = 32 * MAX_IF;
netconf.ifc_buf = buffer;
sock=socket( PF_INET, SOCK_DGRAM, 0 );
err=ioctl( sock, SIOCGIFCONF, &netconf );
if ( err < 0 )
kdDebug() << "KInetAddress: Error in ioctl: "<<errno<<"." << endl;
close( sock );
if_count = netconf.ifc_len / 32;
for( i = 0; i < if_count; i++ ) {
if( strcmp( netconf.ifc_req[i].ifr_name, "lo" ) != 0 ) {
strncpy( if_name[j], netconf.ifc_req[i].ifr_name, 20 );
strncpy( if_addr[j], inet_ntoa(((struct sockaddr_in*)(&netconf.ifc_req[i].ifr_addr))->sin_addr), 20 );
j++;
}
}
if(j == 0) {
local_address = "localhost";
inet_address = "localhost";
return;
}
if(j == 1) {
local_address = strdup( if_addr[0] );
inet_address = local_address;
return;
}
/* take default gateway interface for inet address if available */
default_ifName = getdefaultdev();
if( default_ifName) {
for( i = 0; i < j; i++ ) {
if( strcmp(if_name[i], default_ifName) == 0 ) {
inet_address = strdup(if_addr[i]);
break;
}
}
}
/* use first ppp connection for inet, first non-ppp for local */
for( i = 0; i < j; i++ ) {
if((strncmp(if_name[i], "ppp", 3) == 0) ||
(strncmp(if_name[i], "ippp", 4) == 0)) {
if (!inet_address) {
inet_address = strdup(if_addr[i]);
}
}
else if (!local_address) {
local_address = strdup(if_addr[i]);
}
}
/* if nothing did work, just take anything */
if (!inet_address)
inet_address = strdup(if_addr[0]);
if (!local_address)
local_address = strdup(if_addr[0]);
}
KInetAddress* KInetAddress::getPrivateInetAddress() {
if ( inet_address == NULL ) {
findAddresses();
}
return new KInetAddress(QString(inet_address));
}
KInetAddress* KInetAddress::getLocalAddress() {
if ( local_address == NULL ) {
findAddresses();
}
return new KInetAddress(QString(local_address));
}

142
srvloc/kserviceregistry.cpp Normal file
View File

@ -0,0 +1,142 @@
/*
* This file is part of the KDE libraries
* Copyright (C) 2002 Tim Jansen <tim@tjansen.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include "kserviceregistry.h"
#include <kdebug.h>
#ifdef HAVE_SLP
void KServiceRegistryRegReport(SLPHandle,
SLPError errcode,
void* cookie) {
KServiceRegistry *s = (KServiceRegistry*) cookie;
s->m_cbSuccess = (errcode == SLP_OK);
if (errcode < 0)
kdDebug() << "KServiceRegistry: error in callback:" << errcode <<endl;
}
KServiceRegistry::KServiceRegistry(const QString &lang) :
m_opened(false),
m_lang(lang) {
}
KServiceRegistry::~KServiceRegistry() {
if (m_opened)
SLPClose(m_handle);
}
bool KServiceRegistry::ensureOpen() {
SLPError e;
if (m_opened)
return true;
e = SLPOpen(m_lang.latin1(), SLP_FALSE, &m_handle);
if (e != SLP_OK) {
kdDebug() << "KServiceRegistry: error while opening:" << e <<endl;
return false;
}
m_opened = true;
return true;
}
bool KServiceRegistry::available() {
return ensureOpen();
}
bool KServiceRegistry::registerService(const QString &serviceURL,
QString attributes,
unsigned short lifetime) {
if (!ensureOpen())
return false;
m_cbSuccess = true;
SLPError e = SLPReg(m_handle,
serviceURL.latin1(),
lifetime > 0 ? lifetime : SLP_LIFETIME_MAXIMUM,
0,
attributes.isNull() ? "" : attributes.latin1(),
SLP_TRUE,
KServiceRegistryRegReport,
this);
if (e != SLP_OK) {
kdDebug() << "KServiceRegistry: error in registerService:" << e <<endl;
return false;
}
return m_cbSuccess;
}
bool KServiceRegistry::registerService(const QString &serviceURL,
QMap<QString,QString> attributes,
unsigned short lifetime) {
if (!ensureOpen())
return false;
// TODO: encode strings in map?
QString s;
QMap<QString,QString>::iterator it = attributes.begin();
while (it != attributes.end()) {
if (!s.isEmpty())
s += ",";
s += QString("(%1=%2)").arg(it.key()).arg(it.data());
it++;
}
return registerService(serviceURL, s, lifetime);
}
void KServiceRegistry::unregisterService(const QString &serviceURL) {
if (!m_opened)
return;
SLPDereg(m_handle, serviceURL.latin1(),
KServiceRegistryRegReport,
this);
}
#else
KServiceRegistry::KServiceRegistry(const QString &lang) :
m_opened(false),
m_lang(lang) {
}
KServiceRegistry::~KServiceRegistry() {
}
bool KServiceRegistry::ensureOpen() {
return false;
}
bool KServiceRegistry::available() {
return false;
}
bool KServiceRegistry::registerService(const QString &, QString, unsigned short ) {
return false;
}
bool KServiceRegistry::registerService(const QString &, QMap<QString,QString>, unsigned short) {
return false;
}
void KServiceRegistry::unregisterService(const QString &) {
}
#endif

147
srvloc/kserviceregistry.h Normal file
View File

@ -0,0 +1,147 @@
/*
* This file is part of the KDE libraries
* Copyright (C) 2002 Tim Jansen <tim@tjansen.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __KSERVICEREGISTRY_H
#define __KSERVICEREGISTRY_H
#ifdef HAVE_SLP
#include <slp.h>
#endif
#include <qstring.h>
#include <qmap.h>
#include <qvaluelist.h>
/**
* KServiceRegistry allows you to announce your service using SLP (RFC 2608).
*
* Use KServiceRegistry to announce a service. The service will be valid
* until its lifespan ends, you unregister it or delete the KServiceRegistry,
* whatever comes first.
* A service will be described using a Service URL and an optional list of
* attributes. The syntax for a simple Service URL is
* <pre>
* service:%srvtype%://%addrspec%
* </pre>
* where "%srvtype%" specifies the protocol and "%addrspec5" the address.
* Examples of valid Service URLs are "service:http://www.kde.org",
* "service:lpr://printer.example.org/myqueure" and
* "service:http://your.server.org:8080".
* To provide more information about your service than just the protocol,
* port and address you can use abstract service types.
* A Service URL that uses an abstract service type has the form
* <pre>
* service:%abstract-type%:%concrete-type%
* </pre>
* where %abstract-type% describes the kind of service and %concrete-type% specifies
* the protocol and address. Examples are
* "service:printer:lpr://printer.example.com/lp0" and
* "service:printer:ipp://printer.example.com/".
* Note that you cannot invent you own types but only take those that are
* registered at IANA. To create your own service type you must become a naming
* authority. Then you can use service types of the form
* "%srvtype%.%naming-authority%". Assuming that "kde" is the id of a
* IANA-registered naming authority, a valid Service URL would be
* "service:weatherp.kde://weather.example.com". You can find more information
* about Service URLs in the IETF RFCs 2608 and 3224.
* Additionally each service can have one or more attributes to carry
* additional information about the service. Attributes are a simple pair of
* strings, one for the attributes name and one for the value. They can be
* used, for example, to describe the type of a printer or the email address
* of an administrator.
*
* Service templates can be used to describe an abstract type, including the
* syntax of the concrete type and the attributes. The use of service
* templates is described in RFC 2609, you can find the existing service
* templates at http://www.iana.org/assignments/svrloc-templates.htm .
*
*
* TODO: example of obtaining host address and registering service
*
* @version $Id$
* @author Tim Jansen, tim@tjansen.de
*/
class KServiceRegistry {
public:
/**
* Creates a new service registration instance for the given
* language.
* @param lang the language as two letter code, or QString::null for the
* system default
*/
KServiceRegistry(const QString &lang = QString::null);
virtual ~KServiceRegistry();
/**
* Returns true if service registration is generally possible.
* Reasons for a failure could be that the SLP libraries are not
* installed or no SA daemon (slpd) is installed
* @return true if service registration seems to be possible
*/
bool available();
/**
* Registers the given service.
* @param serviceURL the service URL to register
* @param attributes a list of the attributes to register, encoded in
* the format "(attr1=val1),(attr2=val2),(attr3=val3)"
* Use an empty string if you dont want to set attributes
* @param lifetime the lifetime of the service in seconds, or 0 for infinite
* @return true if successful, false otherwise. False usually means that no
* SA daemon (slpd) is running.
*/
bool registerService(const QString &serviceURL,
QString attributes = QString::null,
unsigned short lifetime = 0);
/**
* Registers the given service.
* @param serviceURL the service URL to register
* @param attributes a map of all attributes
* @param lifetime the lifetime of the service in seconds, or 0 for infinite
* @return true if successful, false otherwise. False usually means that no
* SA daemon is running (slpd).
*/
bool registerService(const QString &serviceURL,
QMap<QString,QString> attributes,
unsigned short lifetime = 0);
/**
* Unregisters the given service.
* @param serviceURL the service URL to unregister
*/
void unregisterService(const QString &serviceURL);
private:
bool ensureOpen();
bool m_opened;
QString m_lang;
#ifdef HAVE_SLP
SLPHandle m_handle;
friend void KServiceRegistryRegReport(SLPHandle slp,
SLPError errcode,
void* cookie);
#endif
bool m_cbSuccess;
};
#endif