diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | bcb704366cb5e333a626c18c308c7e0448a8e69f (patch) | |
tree | f0d6ab7d78ecdd9207cf46536376b44b91a1ca71 /krfb/srvloc | |
download | tdenetwork-bcb704366cb5e333a626c18c308c7e0448a8e69f.tar.gz tdenetwork-bcb704366cb5e333a626c18c308c7e0448a8e69f.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdenetwork@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'krfb/srvloc')
-rw-r--r-- | krfb/srvloc/Makefile.am | 17 | ||||
-rw-r--r-- | krfb/srvloc/getifaddrs.cpp | 261 | ||||
-rw-r--r-- | krfb/srvloc/getifaddrs.h | 96 | ||||
-rw-r--r-- | krfb/srvloc/kinetinterface.cpp | 277 | ||||
-rw-r--r-- | krfb/srvloc/kinetinterface.h | 186 | ||||
-rw-r--r-- | krfb/srvloc/kinetinterfacewatcher.cpp | 59 | ||||
-rw-r--r-- | krfb/srvloc/kinetinterfacewatcher.h | 122 | ||||
-rw-r--r-- | krfb/srvloc/kserviceregistry.cpp | 181 | ||||
-rw-r--r-- | krfb/srvloc/kserviceregistry.h | 161 | ||||
-rw-r--r-- | krfb/srvloc/uuid.cpp | 245 | ||||
-rw-r--r-- | krfb/srvloc/uuid.h | 29 |
11 files changed, 1634 insertions, 0 deletions
diff --git a/krfb/srvloc/Makefile.am b/krfb/srvloc/Makefile.am new file mode 100644 index 00000000..162e2062 --- /dev/null +++ b/krfb/srvloc/Makefile.am @@ -0,0 +1,17 @@ +METASOURCES = AUTO + +# Code +noinst_LTLIBRARIES = libsrvloc.la + +libsrvloc_la_SOURCES = kserviceregistry.cpp uuid.cpp \ + kinetinterface.cpp kinetinterfacewatcher.cpp \ + getifaddrs.cpp + +libsrvloc_la_LIBADD = $(LIB_QT) $(LIB_KDECORE) $(LIB_SLP) +libsrvloc_la_LDFLAGS = $(all_libraries) -no-undefined +noinst_HEADERS = kserviceregistry.h uuid.h \ + getifaddrs.h kinetinterface.h kinetinterfacewatcher.h + +# set the include path for X, qt and KDE +INCLUDES= $(all_includes) + diff --git a/krfb/srvloc/getifaddrs.cpp b/krfb/srvloc/getifaddrs.cpp new file mode 100644 index 00000000..cff9e81e --- /dev/null +++ b/krfb/srvloc/getifaddrs.cpp @@ -0,0 +1,261 @@ +/* getifaddrs -- get names and addresses of all network interfaces + Copyright (C) 1999,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/** + * 02-12-26, tim@tjansen.de: put in kde_ namespace, C++ fixes, + * included ifreq.h + * removed glibc dependencies + */ + +#include "config.h" + +#ifndef HAVE_GETIFADDRS + +#include "getifaddrs.h" +#include <net/if.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <netinet/in.h> +#include <stdio.h> + +#ifndef IF_NAMESIZE +#define IF_NAMESIZE IFNAMSIZ +#endif + +#ifdef SIOCGIFCONF + +#define old_siocgifconf 0 + +static inline void +__ifreq (struct ifreq **ifreqs, int *num_ifs, int sockfd) +{ + int fd = sockfd; + struct ifconf ifc; + int rq_len; + int nifs; +# define RQ_IFS 4 + + if (fd < 0) + fd = socket (AF_INET, SOCK_DGRAM, 0); + if (fd < 0) + { + *num_ifs = 0; + *ifreqs = NULL; + return; + } + + ifc.ifc_buf = NULL; + + /* We may be able to get the needed buffer size directly, rather than + guessing. */ + if (! old_siocgifconf) + { + ifc.ifc_buf = NULL; + ifc.ifc_len = 0; + if (ioctl (fd, SIOCGIFCONF, &ifc) < 0 || ifc.ifc_len == 0) + { + rq_len = RQ_IFS * sizeof (struct ifreq); + } + else + rq_len = ifc.ifc_len; + } + else + rq_len = RQ_IFS * sizeof (struct ifreq); + + /* Read all the interfaces out of the kernel. */ + while (1) + { + ifc.ifc_len = rq_len; + ifc.ifc_buf = (char*) realloc (ifc.ifc_buf, ifc.ifc_len); + if (ifc.ifc_buf == NULL || ioctl (fd, SIOCGIFCONF, &ifc) < 0) + { + if (ifc.ifc_buf) + free (ifc.ifc_buf); + + if (fd != sockfd) + close (fd); + + *num_ifs = 0; + *ifreqs = NULL; + return; + } + + if (!old_siocgifconf || ifc.ifc_len < rq_len) + break; + + rq_len *= 2; + } + + nifs = ifc.ifc_len / sizeof (struct ifreq); + + if (fd != sockfd) + close (fd); + + *num_ifs = nifs; + *ifreqs = (ifreq*)realloc (ifc.ifc_buf, nifs * sizeof (struct ifreq)); +} + +static inline struct ifreq * +__if_nextreq (struct ifreq *ifr) +{ + return ifr + 1; +} + +static inline void +__if_freereq (struct ifreq *ifreqs, int num_ifs) +{ + free (ifreqs); +} + +/* Create a linked list of `struct kde_ifaddrs' structures, one for each + network interface on the host machine. If successful, store the + list in *IFAP and return 0. On errors, return -1 and set `errno'. */ +int +kde_getifaddrs (struct kde_ifaddrs **ifap) +{ + /* This implementation handles only IPv4 interfaces. + The various ioctls below will only work on an AF_INET socket. + Some different mechanism entirely must be used for IPv6. */ + int fd = socket (AF_INET, SOCK_DGRAM, 0); + struct ifreq *ifreqs; + int nifs; + + if (fd < 0) + return -1; + + __ifreq (&ifreqs, &nifs, fd); + if (ifreqs == NULL) /* XXX doesn't distinguish error vs none */ + { + close (fd); + return -1; + } + + /* Now we have the list of interfaces and each one's address. + Put it into the expected format and fill in the remaining details. */ + if (nifs == 0) + *ifap = NULL; + else + { + struct Storage + { + struct kde_ifaddrs ia; + struct sockaddr addr, netmask, broadaddr; + char name[IF_NAMESIZE]; + } *storage; + struct ifreq *ifr; + int i; + + storage = (Storage*) malloc (nifs * sizeof storage[0]); + if (storage == NULL) + { + close (fd); + __if_freereq (ifreqs, nifs); + return -1; + } + + i = 0; + ifr = ifreqs; + do + { + /* Fill in all pointers to the storage we've already allocated. */ + storage[i].ia.ifa_next = &storage[i + 1].ia; + storage[i].ia.ifa_addr = &storage[i].addr; + storage[i].ia.ifa_netmask = &storage[i].netmask; + storage[i].ia.ifa_broadaddr = &storage[i].broadaddr; /* & dstaddr */ + + /* Now copy the information we already have from SIOCGIFCONF. */ + storage[i].ia.ifa_name = strncpy (storage[i].name, ifr->ifr_name, + sizeof storage[i].name); + storage[i].addr = ifr->ifr_addr; + + /* The SIOCGIFCONF call filled in only the name and address. + Now we must also ask for the other information we need. */ + + if (ioctl (fd, SIOCGIFFLAGS, ifr) < 0) + break; + storage[i].ia.ifa_flags = ifr->ifr_flags; + + ifr->ifr_addr = storage[i].addr; + + if (ioctl (fd, SIOCGIFNETMASK, ifr) < 0) + break; + storage[i].netmask = ifr->ifr_netmask; + + if (ifr->ifr_flags & IFF_BROADCAST) + { + ifr->ifr_addr = storage[i].addr; + if (ioctl (fd, SIOCGIFBRDADDR, ifr) < 0) + break; + storage[i].broadaddr = ifr->ifr_broadaddr; + } + else if (ifr->ifr_flags & IFF_POINTOPOINT) + { + ifr->ifr_addr = storage[i].addr; + if (ioctl (fd, SIOCGIFDSTADDR, ifr) < 0) + break; + storage[i].broadaddr = ifr->ifr_dstaddr; + } + else + /* Just 'cause. */ + memset (&storage[i].broadaddr, 0, sizeof storage[i].broadaddr); + + storage[i].ia.ifa_data = NULL; /* Nothing here for now. */ + + ifr = __if_nextreq (ifr); + } while (++i < nifs); + if (i < nifs) /* Broke out early on error. */ + { + close (fd); + free (storage); + __if_freereq (ifreqs, nifs); + return -1; + } + + storage[i - 1].ia.ifa_next = NULL; + + *ifap = &storage[0].ia; + + close (fd); + __if_freereq (ifreqs, nifs); + } + + return 0; +} + +void +kde_freeifaddrs (struct kde_ifaddrs *ifa) +{ + free (ifa); +} + +#else +int kde_getifaddrs(struct kde_ifaddrs **) { + return 1; +} +void kde_freeifaddrs(struct kde_ifaddrs *) { +} +struct { } kde_ifaddrs; + +#endif + +#endif diff --git a/krfb/srvloc/getifaddrs.h b/krfb/srvloc/getifaddrs.h new file mode 100644 index 00000000..65d40c01 --- /dev/null +++ b/krfb/srvloc/getifaddrs.h @@ -0,0 +1,96 @@ +/* ifaddrs.h -- declarations for getting network interface addresses + Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/** + * 02-12-26, tim@tjansen.de: added kde_ prefix, fallback-code, + * removed glibs dependencies + */ + +#include "config.h" + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#include <sys/socket.h> +#include <net/if.h> + +#ifdef HAVE_GETIFADDRS + #include <ifaddrs.h> + +#define kde_getifaddrs(a) getifaddrs(a) +#define kde_freeifaddrs(a) freeifaddrs(a) +#define kde_ifaddrs ifaddrs + +#else + +#ifndef _GETIFADDRS_H +#define _GETIFADDRS_H + + +#include <sys/socket.h> + +/* The `getifaddrs' function generates a linked list of these structures. + Each element of the list describes one network interface. */ +struct kde_ifaddrs +{ + struct kde_ifaddrs *ifa_next; /* Pointer to the next structure. */ + + char *ifa_name; /* Name of this network interface. */ + unsigned int ifa_flags; /* Flags as from SIOCGIFFLAGS ioctl. */ + + struct sockaddr *ifa_addr; /* Network address of this interface. */ + struct sockaddr *ifa_netmask; /* Netmask of this interface. */ + union + { + /* At most one of the following two is valid. If the IFF_BROADCAST + bit is set in `ifa_flags', then `ifa_broadaddr' is valid. If the + IFF_POINTOPOINT bit is set, then `ifa_dstaddr' is valid. + It is never the case that both these bits are set at once. */ + struct sockaddr *ifu_broadaddr; /* Broadcast address of this interface. */ + struct sockaddr *ifu_dstaddr; /* Point-to-point destination address. */ + } ifa_ifu; + /* These very same macros are defined by <net/if.h> for `struct ifaddr'. + So if they are defined already, the existing definitions will be fine. */ +# ifndef ifa_broadaddr +# define ifa_broadaddr ifa_ifu.ifu_broadaddr +# endif +# ifndef ifa_dstaddr +# define ifa_dstaddr ifa_ifu.ifu_dstaddr +# endif + + void *ifa_data; /* Address-specific data (may be unused). */ +}; + + +/* Create a linked list of `struct kde_ifaddrs' structures, one for each + network interface on the host machine. If successful, store the + list in *IFAP and return 0. On errors, return -1 and set `errno'. + + The storage returned in *IFAP is allocated dynamically and can + only be properly freed by passing it to `freeifaddrs'. */ +extern int kde_getifaddrs (struct kde_ifaddrs **__ifap); + +/* Reclaim the storage allocated by a previous `getifaddrs' call. */ +extern void kde_freeifaddrs (struct kde_ifaddrs *__ifa); + +#endif + +#endif + diff --git a/krfb/srvloc/kinetinterface.cpp b/krfb/srvloc/kinetinterface.cpp new file mode 100644 index 00000000..7ba5c15b --- /dev/null +++ b/krfb/srvloc/kinetinterface.cpp @@ -0,0 +1,277 @@ +/* + * Represents an Inet interface + * Copyright (C) 2002 Tim Jansen <tim@tjansen.de> + * + * $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 "kinetinterface.h" + +#include "getifaddrs.h" + +#include <netinet/in.h> +#include <ksockaddr.h> + + +class KInetInterfacePrivate { +public: + QString name; + int flags; + KInetSocketAddress *address; + KInetSocketAddress *netmask; + KInetSocketAddress *broadcast; + KInetSocketAddress *destination; + + KInetInterfacePrivate() : + flags(0), + address(0), + netmask(0), + broadcast(0), + destination(0) { + } + + KInetInterfacePrivate(const QString _name, + int _flags, + KInetSocketAddress *_address, + KInetSocketAddress *_netmask, + KInetSocketAddress *_broadcast, + KInetSocketAddress *_destination) : + name(_name), + flags(_flags), + address(_address), + netmask(_netmask), + broadcast(_broadcast), + destination(_destination) { + } + + ~KInetInterfacePrivate() { + if (address) + delete address; + if (netmask) + delete netmask; + if (broadcast) + delete broadcast; + if (destination) + delete destination; + } + + KInetInterfacePrivate& operator =(const KInetInterfacePrivate& i) { + name = i.name; + flags = i.flags; + if (i.address) + address = new KInetSocketAddress(*i.address); + else + address = 0; + if (i.netmask) + netmask = new KInetSocketAddress(*i.netmask); + else + netmask = 0; + if (i.broadcast) + broadcast = new KInetSocketAddress(*i.broadcast); + else + broadcast = 0; + if (i.destination) + destination = new KInetSocketAddress(*i.destination); + else + destination = 0; + return *this; + } + +}; + + +KInetInterface::KInetInterface() : + d(0) { +} + +KInetInterface::KInetInterface(const QString &_name, + int _flags, + KInetSocketAddress *_address, + KInetSocketAddress *_netmask, + KInetSocketAddress *_broadcast, + KInetSocketAddress *_destination) { + d = new KInetInterfacePrivate(_name, _flags, + _address, _netmask, + _broadcast, _destination); +} + +KInetInterface::KInetInterface(const KInetInterface &i) : + d(0) { + if (!i.d) + return; + + d = new KInetInterfacePrivate(); + *d = *i.d; +} + +KInetInterface::~KInetInterface() { + if (d) + delete d; +} + +KInetInterface& KInetInterface::operator =(const KInetInterface& i) { + if (this == &i) + return *this; + + if (d) + delete d; + d = 0; + if (!i.d) + return *this; + + d = new KInetInterfacePrivate(); + *d = *i.d; + return *this; +} + +bool KInetInterface::isValid() const { + return d == 0; +} + +QString KInetInterface::displayName() const { + return d->name; +} + +QString KInetInterface::name() const { + return d->name; +} + +int KInetInterface::flags() const { + return d->flags; +} + +KInetSocketAddress *KInetInterface::address() const { + return d->address; +} + +KInetSocketAddress *KInetInterface::netmask() const { + return d->netmask; +} + +KInetSocketAddress *KInetInterface::broadcastAddress() const { + return d->broadcast; +} + +KInetSocketAddress *KInetInterface::destinationAddress() const { + return d->destination; +} + +KInetSocketAddress *KInetInterface::getPublicInetAddress() { + QValueVector<KInetInterface> v = getAllInterfaces(true); + + // TODO: first step: take the default route interface + + // try to find point-2-point interface, because it may be + // a dial-up connection. Take it. + QValueVector<KInetInterface>::const_iterator it = v.begin(); + while (it != v.end()) { + if (((*it).flags() & (PointToPoint | Up | Running)) && + (!((*it).flags() & Loopback)) && + (*it).address() && + ((*it).address()->family() == AF_INET)) + return new KInetSocketAddress(*(*it).address()); + it++; + } + + // otherwise, just take the first non-loopback interface + it = v.begin(); + while (it != v.end()) { + if (((*it).flags() & (Up | Running)) && + (!((*it).flags() & Loopback)) && + (*it).address() && + ((*it).address()->family() == AF_INET)) + return new KInetSocketAddress(*(*it).address()); + it++; + } + + // ok, giving up, try to take loopback + it = v.begin(); + while (it != v.end()) { + if (((*it).flags() & (Up | Running)) && + (*it).address()) + return new KInetSocketAddress(*(*it).address()); + it++; + } + + // not even loopback.. + return 0; +} + +namespace { + KInetSocketAddress *createAddress(struct sockaddr *a) { + if (!a) + return 0; + else if (a->sa_family == AF_INET) + return new KInetSocketAddress((struct sockaddr_in*) a, + sizeof(struct sockaddr_in)); +#ifdef AF_INET6 + else if (a->sa_family == AF_INET6) + return new KInetSocketAddress((struct sockaddr_in6*) a, + sizeof(struct sockaddr_in6)); +#endif + else + return 0; + } + + int convertFlags(int flags) { + int r = 0; + if (flags & IFF_UP) + r |= KInetInterface::Up; + if (flags & IFF_BROADCAST) + r |= KInetInterface::Broadcast; + if (flags & IFF_LOOPBACK) + r |= KInetInterface::Loopback; + if (flags & IFF_POINTOPOINT) + r |= KInetInterface::PointToPoint; + if (flags & IFF_RUNNING) + r |= KInetInterface::Running; + if (flags & IFF_MULTICAST) + r |= KInetInterface::Multicast; + + return r; + } +} + +QValueVector<KInetInterface> KInetInterface::getAllInterfaces(bool includeLoopback) { + struct kde_ifaddrs *ads; + struct kde_ifaddrs *a; + QValueVector<KInetInterface> r; + if (kde_getifaddrs(&ads)) + return r; + + a = ads; + while (a) { + if ((a->ifa_flags & IFF_LOOPBACK) && !includeLoopback) { + a = a->ifa_next; + continue; + } + r.push_back(KInetInterface(QString::fromUtf8(a->ifa_name), + convertFlags(a->ifa_flags), + createAddress(a->ifa_addr), + createAddress(a->ifa_netmask), + (a->ifa_flags & IFF_BROADCAST) ? + createAddress(a->ifa_broadaddr) : 0, + (a->ifa_flags & IFF_POINTOPOINT) ? + createAddress(a->ifa_dstaddr) : 0)); + a = a->ifa_next; + } + + kde_freeifaddrs(ads); + return r; +} + diff --git a/krfb/srvloc/kinetinterface.h b/krfb/srvloc/kinetinterface.h new file mode 100644 index 00000000..30005547 --- /dev/null +++ b/krfb/srvloc/kinetinterface.h @@ -0,0 +1,186 @@ +/* + * Represents an Inet interface + * Copyright (C) 2002 Tim Jansen <tim@tjansen.de> + * + * $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 KINETINTERFACE_H +#define KINETINTERFACE_H + +#include <qvaluevector.h> +#include <qcstring.h> +#include <qstring.h> + + +class KInetInterfacePrivate; +class KInetSocketAddress; + +/** + * An Internet (IPv4 or IPv6) network interface. + * + * Represents a snapshot of the network interface's state. It is + * not possible to modify the interface using this class, only + * to read it. Note that the interfaces can change it any time + * (for example when the internet connection goes up or down), + * so when you use it in a server you may want to use it together + * with a @ref KInetInterfaceWatcher. + * Use @ref getAllInterfaces() to get all interfaces of a system. + * + * @author Tim Jansen <tim@tjansen.de> + * @short Represents an IPv4 or IPv6 Network Interface + * @see KInetInterfaceWatcher + * @since 3.2 + */ +class KInetInterface { +private: + KInetInterface(const QString &name, + int flags, + KInetSocketAddress *address, + KInetSocketAddress *netmask, + KInetSocketAddress *broadcast, + KInetSocketAddress *destination); + +public: + /** + * Default constructor. Creates an uninitialized KInetInterface. + * @see isValid() + */ + KInetInterface(); + + /** + * Copy constructor. Makes a deep copy. + * @param i the KInetInterface to copy + */ + KInetInterface(const KInetInterface &i); + + /** + * Destructor + */ + virtual ~KInetInterface(); + + /** + * Assignment, makes a deep copy of @p i. + * @param i the KInetInterface to copy + * @return this KInetInterface + */ + KInetInterface& operator =(const KInetInterface& i); + + /** + * Checks whether the object is valid. Only interfaces that + * have been created using the default constructor are invalid. + * @return true if valid, false if invalid + */ + bool isValid() const; + + /** + * Returns a user-readable name of the interface, if available. + * Otherwise it returns the same value as @ref name(). + * @return the display name of the interface + * @see name() + */ + QString displayName() const; + + /** + * Returns the name of the interface, e.g. 'eth0'. + * @return the name of the interface + * @see displayName() + */ + QString name() const; + + /** + * Flags describing the interface. These flags + * can be ORed. + */ + enum Flags { + Up = 1, ///< Interface is up. + Broadcast = 2, ///< Broadcast address (@ref broadcastAddress()) is valid.. + Loopback = 8, ///< Interface is a loopback interface. + PointToPoint = 16, ///< Interface is a point-to-point interface. + Running = 128, ///< Interface is running. + Multicast = 65536 ///< Interface is multicast-capable. + }; + + /** + * A set of ORed flags describing the interface. See + * @ref Flags for description of the flags. + * @return the ORed @ref Flags of the interface + */ + int flags() const; + + /** + * Returns the address of the interface. + * The returned object is valid as long as this object + * exists. + * @return the address of this interface, can be 0 if the interface + * does not have an address + */ + KInetSocketAddress *address() const; + + /** + * Returns the netmask of the interface. + * The returned object is valid as long as this object + * exists. + * @return the netmask of this interface, can be 0 if the interface + * does not have an address + */ + KInetSocketAddress *netmask() const; + + /** + * Returns the broadcast address of the interface. + * The returned object is valid as long as this object + * exists. + * @return the broadcast address of this interface. Can be 0 if + * the interface is a peer-to-peer interface (like PPP) + */ + KInetSocketAddress *broadcastAddress() const; + + /** + * Returns the destination / peer address of the interface. + * It is used for peer-to-peer interfaces like PPP. + * The returned object is valid as long as this object + * exists. + * @return the destination address of this interface. Can be 0 + * if the interface is not a peer-to-peer interface + */ + KInetSocketAddress *destinationAddress() const; + + /** + * Tries to guess the public internet address of this computer. + * This is not always successful, especially when the computer + * is behind a firewall or NAT gateway. In the worst case, it + * returns localhost. + * @return a KInetAddress object that contains the best match. + * The caller takes ownership of the object and is + * responsible for freeing it + */ + static KInetSocketAddress *getPublicInetAddress(); + + /** + * Returns all active interfaces of the system. + * + * @param includeLoopback if true, include the loopback interface's + * name + * @return the list of IP addresses + */ + static QValueVector<KInetInterface> getAllInterfaces(bool includeLoopback = false); + +private: + KInetInterfacePrivate* d; +}; + +#endif diff --git a/krfb/srvloc/kinetinterfacewatcher.cpp b/krfb/srvloc/kinetinterfacewatcher.cpp new file mode 100644 index 00000000..31b972f5 --- /dev/null +++ b/krfb/srvloc/kinetinterfacewatcher.cpp @@ -0,0 +1,59 @@ +/* + * Watches Inet interfaces + * Copyright (C) 2002 Tim Jansen <tim@tjansen.de> + * + * $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 "kinetinterfacewatcher.h" +#include "kinetinterfacewatcher.moc" + +class KInetInterfaceWatcherPrivate { +public: + QString interface; + int minInterval; // not used yet, but my be when a daemon watches + + + KInetInterfaceWatcherPrivate(const QString &iface, + int minIntv) : + interface(iface), + minInterval(minIntv) { + } +}; + +/* + * or all network interfaces. + * @param interface the name of the interface to watch (e.g.'eth0') + * or QString::null to watch all interfaces + * @param minInterval the minimum interval between two checks in + * seconds. Be careful not to check too often, to + * avoid unneccessary wasting of CPU time + */ +KInetInterfaceWatcher::KInetInterfaceWatcher(const QString &interface, + int minInterval) { + d = new KInetInterfaceWatcherPrivate(interface, minInterval); +} + +QString KInetInterfaceWatcher::interface() const { + return d->interface; +} + +KInetInterfaceWatcher::~KInetInterfaceWatcher() { + delete d; +} + diff --git a/krfb/srvloc/kinetinterfacewatcher.h b/krfb/srvloc/kinetinterfacewatcher.h new file mode 100644 index 00000000..3651b87d --- /dev/null +++ b/krfb/srvloc/kinetinterfacewatcher.h @@ -0,0 +1,122 @@ +/* + * Watches Inet interfaces + * Copyright (C) 2002 Tim Jansen <tim@tjansen.de> + * + * $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 KINETINTERFACEWATCHER_H +#define KINETINTERFACEWATCHER_H + +#include <kinetinterface.h> +#include <qobject.h> +#include <qvaluevector.h> +#include <qcstring.h> +#include <qstring.h> + + +class KInetInterfaceWatcherPrivate; + + +/** + * KInetInterfaceWatcher can watch the state of one or all + * of the system's network interfaces. + * The watcher will emit the signal @ref changed() when an + * interface changed or a interface has been added or removed. + * + * @author Tim Jansen <tim@tjansen.de> + * @short Watches the state of the network interfaces + * @see KInetInterface + * @since 3.2 + */ +class KInetInterfaceWatcher : public QObject { + Q_OBJECT +public: + /** + * Creates a new KInetInterfaceWatcher. Before you can use it, + * you must @ref start() it. + * + * @param interface the name of the interface to watch (e.g.'eth0') + * or QString::null to watch all interfaces + * @param minInterval the minimum interval between two checks in + * seconds. Be careful not to check too often, to + * avoid unneccessary wasting of CPU time + */ + KInetInterfaceWatcher(const QString &interface = QString::null, + int minInterval = 60); + + /** + * Returns the name of the interface that is being watched. + * @return the name of the interface, or QString::null if all + * interfaces are watched + */ + QString interface() const; + + /** + * Starts the KInetInterfaceWatcher. It watches either one + * or all network interfaces. When one of them changed. + * it emits a @ref changed() signal. + * @param interface the name of the interface to watch (e.g.'eth0') + * or QString::null to watch all interfaces + * @param minInterval the minimum interval between two checks in + * seconds. Be careful not to check too often, to + * avoid unneccessary wasting of CPU time + * @see changed() + * @see stop() + */ + void start(const QString &interface = QString::null, + int minInterval = 60); + + /** + * Stops watching the interfaces. + * @see start() + */ + void stop(); + + /** + * Destructor + */ + virtual ~KInetInterfaceWatcher(); + +signals: + /** + * Emitted when one or more watched interfaces have changed. The + * @p interfaceName is the name of the interface being watched, not + * the interface that has changed (because more than one interface + * may have changed). + * A change occurred, when + * @li a new interface has been added (when watching a single interface, + * only when an interface of that name has been added) + * @li an interface has been removed (when watching a single interface, + * only when this interface has been removed) + * @li the address or netmask of the interface changed + * + * No change will be emitted when the broadcast address or destination + * address has changed. + * + * @param interfaceName the name of the interface that is watched, + * by the emitter, or QString::null if all + * interfaces are being watched + * @see start() + */ + void changed(QString interfaceName); + +private: + KInetInterfaceWatcherPrivate* d; +}; + +#endif diff --git a/krfb/srvloc/kserviceregistry.cpp b/krfb/srvloc/kserviceregistry.cpp new file mode 100644 index 00000000..1a14f9b0 --- /dev/null +++ b/krfb/srvloc/kserviceregistry.cpp @@ -0,0 +1,181 @@ +/* + * Interface to register SLP services. + * 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. + */ +/** + * TODO: see below.. + */ + +#include "config.h" +#include "kserviceregistry.h" +#include <kdebug.h> + + +#ifdef HAVE_SLP +#include <slp.h> + +class KServiceRegistryPrivate { +public: + KServiceRegistryPrivate(const QString &lang) : + m_opened(false), + m_lang(lang) { + } + bool ensureOpen(); + + bool m_opened; + QString m_lang; + + SLPHandle m_handle; + friend void KServiceRegistryRegReport(SLPHandle slp, + SLPError errcode, + void* cookie); + bool m_cbSuccess; +}; + +void KServiceRegistryRegReport(SLPHandle, + SLPError errcode, + void* cookie) { + KServiceRegistryPrivate *s = (KServiceRegistryPrivate*) cookie; + s->m_cbSuccess = (errcode == SLP_OK); + if (errcode < 0) + kdDebug() << "KServiceRegistry: error in callback:" << errcode <<endl; +} + + +KServiceRegistry::KServiceRegistry(const QString &lang) { + d = new KServiceRegistryPrivate(lang); +} + +KServiceRegistry::~KServiceRegistry() { + if (d->m_opened) + SLPClose(d->m_handle); + delete d; +} + +bool KServiceRegistryPrivate::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 d->ensureOpen(); +} + +bool KServiceRegistry::registerService(const QString &serviceURL, + QString attributes, + unsigned short lifetime) { + if (!d->ensureOpen()) + return false; + + d->m_cbSuccess = true; + SLPError e = SLPReg(d->m_handle, + serviceURL.latin1(), + lifetime > 0 ? lifetime : SLP_LIFETIME_MAXIMUM, + 0, + attributes.isNull() ? "" : attributes.latin1(), + SLP_TRUE, + KServiceRegistryRegReport, + d); + if (e != SLP_OK) { + kdDebug() << "KServiceRegistry: error in registerService:" << e <<endl; + return false; + } + return d->m_cbSuccess; +} + +bool KServiceRegistry::registerService(const QString &serviceURL, + QMap<QString,QString> attributes, + unsigned short lifetime) { + if (!d->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 (!d->m_opened) + return; + SLPDereg(d->m_handle, serviceURL.latin1(), + KServiceRegistryRegReport, + d); +} + +QString KServiceRegistry::encodeAttributeValue(const QString &value) { + char *n; + if (SLPEscape(value.latin1(), &n, SLP_TRUE) == SLP_OK) { + QString r(n); + SLPFree(n); + return r; + } + return QString::null; +} + +#else + +KServiceRegistry::KServiceRegistry(const QString &lang) : + d(0) { +} + +KServiceRegistry::~KServiceRegistry() { +} + +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 &) { +} + +QString KServiceRegistry::encodeAttributeValue(const QString &value) { + return value; +} + +#endif + +QString KServiceRegistry::createCommaList(const QStringList &values) { + return values.join(","); +} + + + diff --git a/krfb/srvloc/kserviceregistry.h b/krfb/srvloc/kserviceregistry.h new file mode 100644 index 00000000..f017b129 --- /dev/null +++ b/krfb/srvloc/kserviceregistry.h @@ -0,0 +1,161 @@ +/* + * Interface to register SLP services. + * 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. + */ + +/* + * TODO: put private variables and SLP-dependencies in private class + */ + +#ifndef __KSERVICEREGISTRY_H +#define __KSERVICEREGISTRY_H + +#include <qstring.h> +#include <qstringlist.h> +#include <qmap.h> + +class KServiceRegistryPrivate; + +/** + * 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 . + * + * Example: + * <pre> + * KServiceRegistry ksr; + * KInetAddress kia = KInetAddress->getLocalAddress(); + * ksr.registerService(QString("service:remotedesktop.kde:vnc://%1:0").arg(kia->nodeName()), + * "(type=shared)"); + * delete kia; + * </pre> + * + * @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(); + + /** + * Creates a comma-separated string of lists, as required by many functions. + * @param map the items of this list will be converted + * @return the comma-separated list + */ + static QString createCommaList(const QStringList &values); + + /** + * Encodes an QString for use as a attribute value. This will escape + * all characters that are not allowed. This method is only available + * when a SLP library is available, otherwise it will return the + * given value. + * @param value the value string to encode + * @return the encoded value string + */ + static QString encodeAttributeValue(const QString &value); + + /** + * 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: + KServiceRegistryPrivate *d; +}; + +#endif diff --git a/krfb/srvloc/uuid.cpp b/krfb/srvloc/uuid.cpp new file mode 100644 index 00000000..61f78d86 --- /dev/null +++ b/krfb/srvloc/uuid.cpp @@ -0,0 +1,245 @@ +/* + * libuuid - library for generating UUIDs + * + * Copyright (C) 1996, 1997, 1998, 1999 Theodore Ts'o. + * Copyright (C) 2002 Tim Jansen + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU + * Library General Public License. + * %End-Header% + * + * 2002-12-15, tim@tjansen.de: + * merged all *.c files, + * replaced all function that are not needed to generate a time uuid, + * added createUUID() + */ + +#include "uuid.h" + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <ctype.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/time.h> +#include <time.h> + +#ifndef _SVID_SOURCE +#define _SVID_SOURCE +#endif + +#include <fcntl.h> +#include <errno.h> +#ifdef HAVE_SRANDOM +#define srand(x) srandom(x) +#define rand() random() +#endif + +typedef unsigned char uuid_t[16]; +typedef unsigned char __u8; +typedef unsigned short __u16; +typedef unsigned int __u32; + + +struct uuid { + __u32 time_low; + __u16 time_mid; + __u16 time_hi_and_version; + __u16 clock_seq; + __u8 node[6]; +}; + +void uuid_unpack(const uuid_t in, struct uuid *uu) +{ + const __u8 *ptr = in; + __u32 tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + tmp = (tmp << 8) | *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->time_low = tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->time_mid = tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->time_hi_and_version = tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->clock_seq = tmp; + + memcpy(uu->node, ptr, 6); +} + +static int get_random_fd(void) +{ + struct timeval tv; + static int fd = -2; + int i; + + if (fd == -2) { + gettimeofday(&tv, 0); + fd = open("/dev/urandom", O_RDONLY); + if (fd == -1) + fd = open("/dev/random", O_RDONLY | O_NONBLOCK); + srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec); + } + /* Crank the random number generator a few times */ + gettimeofday(&tv, 0); + for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--) + rand(); + return fd; +} + + +/* + * Generate a series of random bytes. Use /dev/urandom if possible, + * and if not, use srandom/random. + */ +static void get_random_bytes(void *buf, int nbytes) +{ + int i, fd = get_random_fd(); + int lose_counter = 0; + char *cp = (char *) buf; + + if (fd >= 0) { + while (nbytes > 0) { + i = read(fd, cp, nbytes); + if (i <= 0) { + if (lose_counter++ > 16) + break; + continue; + } + nbytes -= i; + cp += i; + lose_counter = 0; + } + } + + /* XXX put something better here if no /dev/random! */ + for (i = 0; i < nbytes; i++) + *cp++ = rand() & 0xFF; + return; +} + + +/* Assume that the gettimeofday() has microsecond granularity */ +#define MAX_ADJUSTMENT 10 + +static int get_clock(__u32 *clock_high, __u32 *clock_low, __u16 *ret_clock_seq) +{ + static int adjustment = 0; + static struct timeval last = {0, 0}; + static __u16 clock_seq; + struct timeval tv; + unsigned long long clock_reg; + +try_again: + gettimeofday(&tv, 0); + if ((last.tv_sec == 0) && (last.tv_usec == 0)) { + get_random_bytes(&clock_seq, sizeof(clock_seq)); + clock_seq &= 0x1FFF; + last = tv; + last.tv_sec--; + } + if ((tv.tv_sec < last.tv_sec) || + ((tv.tv_sec == last.tv_sec) && + (tv.tv_usec < last.tv_usec))) { + clock_seq = (clock_seq+1) & 0x1FFF; + adjustment = 0; + last = tv; + } else if ((tv.tv_sec == last.tv_sec) && + (tv.tv_usec == last.tv_usec)) { + if (adjustment >= MAX_ADJUSTMENT) + goto try_again; + adjustment++; + } else { + adjustment = 0; + last = tv; + } + + clock_reg = tv.tv_usec*10 + adjustment; + clock_reg += ((unsigned long long) tv.tv_sec)*10000000; + clock_reg += (((unsigned long long) 0x01B21DD2) << 32) + 0x13814000; + + *clock_high = clock_reg >> 32; + *clock_low = clock_reg; + *ret_clock_seq = clock_seq; + return 0; +} + +static void uuid_pack(const struct uuid *uu, uuid_t ptr) +{ + __u32 tmp; + unsigned char *out = ptr; + + tmp = uu->time_low; + out[3] = (unsigned char) tmp; + tmp >>= 8; + out[2] = (unsigned char) tmp; + tmp >>= 8; + out[1] = (unsigned char) tmp; + tmp >>= 8; + out[0] = (unsigned char) tmp; + + tmp = uu->time_mid; + out[5] = (unsigned char) tmp; + tmp >>= 8; + out[4] = (unsigned char) tmp; + + tmp = uu->time_hi_and_version; + out[7] = (unsigned char) tmp; + tmp >>= 8; + out[6] = (unsigned char) tmp; + + tmp = uu->clock_seq; + out[9] = (unsigned char) tmp; + tmp >>= 8; + out[8] = (unsigned char) tmp; + + memcpy(out+10, uu->node, 6); +} + +static void uuid_generate_time(uuid_t out) +{ + static unsigned char node_id[6]; + struct uuid uu; + __u32 clock_mid; + + get_random_bytes(node_id, 6); + get_clock(&clock_mid, &uu.time_low, &uu.clock_seq); + uu.clock_seq |= 0x8000; + uu.time_mid = (__u16) clock_mid; + uu.time_hi_and_version = (clock_mid >> 16) | 0x1000; + memcpy(uu.node, node_id, 6); + uuid_pack(&uu, out); +} + +static void uuid_unparse(const uuid_t uu, char *out) +{ + struct uuid uuid; + + uuid_unpack(uu, &uuid); + sprintf(out, + "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + uuid.time_low, uuid.time_mid, uuid.time_hi_and_version, + uuid.clock_seq >> 8, uuid.clock_seq & 0xFF, + uuid.node[0], uuid.node[1], uuid.node[2], + uuid.node[3], uuid.node[4], uuid.node[5]); +} + +QString createUUID() { + char s[37]; + uuid_t uu; + uuid_generate_time(uu); + uuid_unparse(uu, s); + return QString(s); +} + diff --git a/krfb/srvloc/uuid.h b/krfb/srvloc/uuid.h new file mode 100644 index 00000000..c566a7db --- /dev/null +++ b/krfb/srvloc/uuid.h @@ -0,0 +1,29 @@ +/* + * Micro UUID library, based on libuuid + * Copyright (C) 1996, 1997, 1998, 1999 Theodore Ts'o. + * 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 UUID_H +#define UUID_H + +#include <qstring.h> + +QString createUUID(); + +#endif /* UUID_H */ |