Merge branch 'dpkg' of pc18:/srv/git/r/doldaconnect into dpkg dpkg
authorFredrik Tolf <fredrik@dolda2000.com>
Thu, 14 Feb 2008 18:08:40 +0000 (19:08 +0100)
committerFredrik Tolf <fredrik@dolda2000.com>
Thu, 14 Feb 2008 18:08:40 +0000 (19:08 +0100)
Conflicts:

debian/changelog
debian/control
debian/rules

nothing to commit (working directory clean)

44 files changed:
acinclude.m4
autopackage/dcuilib.apspec.in
autopackage/dolcon.apspec.in
autopackage/doldacond.apspec.in
autopackage/guishell.apspec.in
clients/gtk2/hublist.c
common/Makefile.am
common/utils.c
configure.in
contrib/.gitignore [new file with mode: 0644]
contrib/Makefile.am
contrib/doldaconnect.spec.in [new file with mode: 0644]
contrib/fedora-init.d-doldacond [new file with mode: 0755]
daemon/Makefile.am
daemon/auth-krb5.c
daemon/filenet.c
daemon/filenet.h
daemon/fnet-adc.c
daemon/fnet-dc.c
daemon/main.c
daemon/net.c
daemon/transfer.c
debian/changelog
debian/control
debian/doldacond.install [new file with mode: 0644]
debian/rules [changed mode: 0644->0755]
doc/INSTALL.guile [new file with mode: 0644]
doc/man/Makefile.am
doc/man/hubmgr.1 [new file with mode: 0644]
include/utils.h
lib/Makefile.am
lib/guile/Makefile.am
lib/guile/autodl
lib/guile/chatlog
lib/guile/dolcon-guile.c
lib/guile/dolcon/Makefile.am
lib/guile/dolcon/ui.scm
lib/guile/dolcon/util.scm
lib/guile/hubmgr
lib/python/dolcon/__init__.py
lib/python/dolmod.c
lib/python/setup.py
lib/uilib.c
po/sv.po

index 5589ce6..493f374 100644 (file)
@@ -30,6 +30,22 @@ AC_CHECK_HEADER($1, $2, $3)
 CPPFLAGS="$cpp_bak"
 ])
 
+# DOLDA_CHECK_FUNC(FUNCTION, ACTION-IF-FOUND, ACTION-IF-NOT-FOUND,
+#       [EXTRA-CFLAGS], [EXTRA-LDFLAGS])
+#
+# Augmented version of AC_CHECK_HEADER that overrides CPPFLAGS and
+# LDFLAGS
+
+AC_DEFUN([DOLDA_CHECK_FUNC],[dnl
+cpp_bak="$CPPFLAGS"
+ld_bak="$LDFLAGS"
+ifelse([$4], , , [CPPFLAGS="$CPPFLAGS $4"])
+ifelse([$5], , , [LDFLAGS="$LDFLAGS $5"])
+AC_CHECK_FUNC($1, $2, $3)
+CPPFLAGS="$cpp_bak"
+LDFLAGS="$ldflags"
+])
+
 # DOLDA_ENABLE(NAME, HELP, DEFAULT, DEPS)
 #
 # DEPS is a space-separated listing of required variables that must be
index da8653b..af911ba 100644 (file)
@@ -20,6 +20,7 @@ The Dolda Connect interface library is used by programs for talking
 with the Dolda Connect daemon.
 
 [BuildPrepare]
+echo "apkg" >source
 prepareBuild --without-krb5 --disable-daemon --without-gtk2
 
 [BuildUnprepare]
index ef45655..3e11773 100644 (file)
@@ -30,6 +30,7 @@ it is the daemon that does that. This program only controls the
 daemon.
 
 [BuildPrepare]
+echo "apkg" >source
 prepareBuild --enable-gtk2ui --disable-daemon --disable-dolconf --disable-guishell
 
 [BuildUnprepare]
index 5644e0f..ffa13dc 100644 (file)
@@ -28,6 +28,7 @@ Note that, unless you really want to talk to the daemon using telnet,
 you will also want a user interface program to control it.
 
 [BuildPrepare]
+echo "apkg" >source
 prepareBuild --without-gtk2 --without-krb5 --without-keyutils --without-pam
 
 [BuildUnprepare]
index 1d0b058..3a65484 100644 (file)
@@ -15,6 +15,7 @@ AutopackageTarget: 1.2
 PackageFileName: doldaconnect-guishell-@VERSION@.package
 
 [BuildPrepare]
+echo "apkg" >source
 prepareBuild --enable-dolconf --enable-guishell --disable-gtk2ui --disable-daemon
 
 [BuildUnprepare]
index 7342945..74910e5 100644 (file)
@@ -210,6 +210,7 @@ void fetchhublist(char *url, regex_t *flt)
     len = strlen(url);
     p = url + len;
     if((len > 4) && !strncmp(p - 4, ".bz2", 4)) {
+       /* Because using Transfer-Encoding would just be too good! */
        p -= 4;
        len -= 4;
        bzs = memset(smalloc(sizeof(*bzs)), 0, sizeof(*bzs));
@@ -222,6 +223,7 @@ void fetchhublist(char *url, regex_t *flt)
        }
     }
     if((len > 4) && !strncmp(p - 4, ".xml", 4)) {
+       /* Because using Content-Type would just be too good! */
        p -= 4;
        len -= 4;
        handler = pubhubxmlhandler;
index 8030f44..2c6b0b7 100644 (file)
@@ -11,6 +11,7 @@ libhttp_a_SOURCES =   http.c
 httest_SOURCES =       httest.c
 httest_LDADD =         libhttp.a libcommon.a
 
+libcommon_a_CPPFLAGS = -D_ISOC99_SOURCE
 libcommon_a_CFLAGS = -fPIC
 libhttp_a_CFLAGS = -fPIC
 
index d82f3c3..49fb11b 100644 (file)
@@ -29,6 +29,7 @@
 #include <unistd.h>
 #include <sys/time.h>
 #include <netinet/in.h>
+#include <alloca.h>
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
index f96f016..b8d1d88 100644 (file)
@@ -1,5 +1,5 @@
 AC_INIT(daemon/main.c)
-AM_INIT_AUTOMAKE([doldaconnect], [1.0])
+AM_INIT_AUTOMAKE([doldaconnect], [1.1])
 AM_CONFIG_HEADER(config.h)
 
 DOLDA_AC_GROUP([Checking build chain])
@@ -21,17 +21,15 @@ m4_defun([_LT_AC_LANG_CXX_CONFIG], true)
 m4_defun([_LT_AC_LANG_F77_CONFIG], true)
 AC_PROG_LIBTOOL
 
-DOLDA_AC_GROUP([Checking required libraries])
-
-AC_CHECK_LIB(z, deflate, [:], AC_MSG_ERROR([*** must have zlib]))
-AC_CHECK_LIB(bz2, BZ2_bzWriteOpen, [:], AC_MSG_ERROR([*** must have bzlib]))
-AC_CHECK_LIB(gdbm, gdbm_open, [:], AC_MSG_ERROR([*** must have gdbm]))
-
-extlibs=
 experimental=no
 
 DOLDA_AC_GROUP([Checking optional libraries])
 
+# Standard libraries
+AC_CHECK_LIB(z, deflate, [HAS_LIBZ=yes], [HAS_LIBZ=no])
+AC_CHECK_LIB(bz2, BZ2_bzWriteOpen, [HAS_LIBBZ2=yes], [HAS_LIBBZ2=no])
+AC_CHECK_LIB(gdbm, gdbm_open, [HAS_GDBM=yes], [HAS_GDBM=no])
+
 # PAM check
 pam_msg=no
 AH_TEMPLATE(HAVE_PAM, [define to compile support for PAM authentication])
@@ -57,6 +55,10 @@ DOLDA_PKG([HAS_GTK2], [test "$with_gtk2" = no && HAS_GTK2=no],
 if test "$with_gtk2" = yes -a "$HAS_GTK2" = no; then
        AC_MSG_ERROR([*** cannot find GTK2 on this system])
 fi
+DOLDA_PKG([HAS_GTK2SI], [test "$HAS_GTK2" = no && HAS_GTK2SI=no],
+                       [DOLDA_CHECK_FUNC(gtk_status_icon_new_from_pixbuf, [], [HAS_GTK2SI=no], $GTK2_CFLAGS, $GTK2_LIBS)])
+DOLDA_PKG([HAS_GTK2ASS], [test "$HAS_GTK2" = no && HAS_GTK2ASS=no],
+                        [DOLDA_CHECK_FUNC(gtk_assistant_new, [], [HAS_GTK2ASS=no], $GTK2_CFLAGS, $GTK2_LIBS)])
 
 # libxml2 check
 AC_ARG_WITH(libxml2, [  --with-libxml2          Enable libxml2 support])
@@ -91,22 +93,23 @@ DOLDA_PKG([HAS_LIBPURPLE], [PKG_CHECK_MODULES(PURPLE, purple, [], [HAS_LIBPURPLE
                           [DOLDA_CHECK_HEADER(plugin.h, [], [HAS_LIBPURPLE=no], $PURPLE_CFLAGS)])
 
 # Daemon check
-DOLDA_ENABLE(daemon, [  --enable-daemon         Enable the daemon], yes, [])
+DOLDA_ENABLE(daemon, [  --enable-daemon         Enable the daemon], yes,
+                    [HAS_LIBZ HAS_LIBBZ2 HAS_GDBM])
 AM_CONDITIONAL(DAEMON, test "$enable_daemon" = yes)
 
 # Gtk GUI check
 DOLDA_ENABLE(gtk2ui, [  --enable-gtk2ui         Enable the GTK2 user interface], yes,
-                    [HAS_GTK2 HAS_LIBXML])
+                    [HAS_GTK2 HAS_LIBBZ2 HAS_LIBXML])
 AM_CONDITIONAL(CLI_GTK2, test "$enable_gtk2ui" = yes)
 
 # Dolconf check
 DOLDA_ENABLE(dolconf, [  --enable-dolconf        Build the configuration helper], yes,
-                     [HAS_GTK2])
+                     [HAS_GTK2], [HAS_GTK2ASS])
 AM_CONDITIONAL(DOLCONF, test "$enable_dolconf" = yes)
 
 # GUI shell check
 DOLDA_ENABLE(guishell, [  --enable-guishell       Build the GUI shell programs], yes,
-                      [HAS_GTK2])
+                      [HAS_GTK2], [HAS_GTK2SI])
 AM_CONDITIONAL(GUISHELL, test "$enable_guishell" = yes)
 
 # Gnome applet check
@@ -138,12 +141,12 @@ if test -z "$gaimplugin_msg"; then
 fi
 
 # Guile check (XXX: Shouldn't have to be enabled manually)
-guile_msg=no
+enable_guile=no
 if test "$with_guile" = yes; then
        GUILE_FLAGS
-       extlibs="$extlibs guile"
-       guile_msg=yes
+       enable_guile=yes
 fi
+AM_CONDITIONAL(ELIB_GUILE, test "$enable_guile" = yes)
 
 # Check whether to install baseconv
 AC_ARG_ENABLE(baseconv, [  --enable-baseconv       Install the baseconv utility])
@@ -203,6 +206,8 @@ AC_CHECK_MEMBER(struct sockaddr_in6.sin6_family, [ AC_DEFINE(HAVE_IPV6) ], , [#i
 AH_TEMPLATE(HAVE_RESOLVER, [define if your system supports the res_* functions to fetch DNS RRs])
 AC_CHECK_LIB(resolv, res_query, [ AC_DEFINE(HAVE_RESOLVER)
                                  LDFLAGS="$LDFLAGS -lresolv" ])
+AC_CHECK_LIB(resolv, __res_query, [ AC_DEFINE(HAVE_RESOLVER)
+                                   LDFLAGS="$LDFLAGS -lresolv" ])
 
 # Unix credentials selector
 AH_TEMPLATE(UNIX_AUTH_STYLE, [undefine for no Unix auth, 1 for Linux style, 2 for BSD style])
@@ -246,7 +251,6 @@ else
 fi
 AC_DEFINE_UNQUOTED([RELEASEINFO], ["$relinfo"])
 
-AC_SUBST([extlibs])
 AC_OUTPUT([
 Makefile
 autopackage/Makefile
@@ -270,6 +274,7 @@ config/Makefile
 config/cmd/Makefile
 config/util/Makefile
 contrib/Makefile
+contrib/doldaconnect.spec
 share/Makefile
 autopackage/doldacond.apspec
 autopackage/dolcon.apspec
@@ -287,7 +292,7 @@ echo "    Kerberos 5 support:      $krb_msg"
 echo "    GTK2 user interface:     $enable_gtk2ui"
 echo "    Dolconf configurator:    $enable_dolconf"
 echo "    GUI shell:               $enable_guishell"
-echo "    Guile extension library: $guile_msg"
+echo "    Guile extension library: $enable_guile"
 echo "    GNOME transfer applet:   $enable_gnomeapplet"
 echo "    Gaim chat plugin:        $gaimplugin_msg"
 echo
diff --git a/contrib/.gitignore b/contrib/.gitignore
new file mode 100644 (file)
index 0000000..612654b
--- /dev/null
@@ -0,0 +1 @@
+*.spec
index a985bbc..26f7c63 100644 (file)
@@ -1,2 +1,2 @@
-EXTRA_DIST =   gentoo-init.d-doldacond \
-               pam.d-doldacond
+EXTRA_DIST =   fedora-init.d-doldacond gentoo-init.d-doldacond \
+               pam.d-doldacond doldaconnect.spec
diff --git a/contrib/doldaconnect.spec.in b/contrib/doldaconnect.spec.in
new file mode 100644 (file)
index 0000000..4b8596e
--- /dev/null
@@ -0,0 +1,184 @@
+# RPC specfile for Fedora
+Name:          doldaconnect
+Version:       @VERSION@
+Release:       1
+License:       GPL v2+
+Group:         Applications/Internet
+Summary:       Direct Connect client
+Source0:       http://www.dolda2000.com/~fredrik/doldaconnect/%{name}-%{version}.tar.gz
+URL:           http://www.dolda2000.com/~fredrik/doldaconnect/
+BuildRoot:     %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+Requires:      %{name}-libs = %{version}-%{release}
+Requires:      %{name}-data = %{version}-%{release}
+Requires:      doldacond = %{version}-%{release}
+
+%description
+Dolda Connect is a client program for the Direct Connect peer-to-peer
+filesharing network. It is written so that the user interface is
+separated from the actual filesharing program, so that the user
+interface can run on a different computer over the network, and can be
+shut down temporarily (or only started temporarily), and can be
+replaced altogether.
+
+The protocol with which the user interface talks with the actual
+client is also quite well defined, so that other kinds of clients can
+be written as well, such as an automatic downloader, a chatbot,
+etc. It can also be used in secure multiuser operation.
+
+%package libs
+Summary:       %{name} libraries
+Group:         Libraries
+Requires:      krb5-libs >= 1.5
+
+%description libs
+Shared libraries for %{name}.
+
+%package devel
+Summary:       Development files for %{name}.
+Group:         Development/Libraries
+Requires:      %{name}-libs = %{version}-%{release}
+
+%description devel
+Header files and development libraries for %{name}.
+
+%package guile
+Summary:       Guile module for %{name}.
+Group:         Libraries
+Requires:      %{name}-libs = %{version}-%{release}
+Requires:      guile >= 1.8.0
+
+%description guile
+Guile module for using the %{name} library in Scheme programs.
+
+%package applet
+Summary:       GNOME applet for %{name}
+Group:         Applications/Internet
+Requires:      %{name}-libs = %{version}-%{release}
+Requires:      %{name}-data = %{version}-%{release}
+
+%description applet
+A GNOME applet for checking the status of transfers in %{name}.
+
+%package data
+Summary:       Common data files for %{name}
+Group:         Applications/Internet
+
+%description data
+This package contains common data files for other %{name} packages.
+
+%package -n dolcon
+Summary:       The Gtk client in %{name}.
+Group:         Applications/Internet
+Requires:      %{name}-libs = %{version}-%{release}
+Requires:      %{name}-data = %{version}-%{release}
+Conflicts:     %{name}
+
+%description -n dolcon
+This package contains only the Gtk client for %{name}, so that it can
+be used without using a local server.
+
+%package -n doldacond
+Summary:       The daemon in %{name}.
+Group:         Daemons
+Requires(post,preun):  /sbin/chkconfig
+Requires:      initscripts
+Requires:      krb5-libs >= 1.5
+Requires:      gdbm >= 1.8.0
+
+%description -n doldacond
+Daemon for %{name} that does all the actual work of filesharing.
+
+%prep
+%setup
+
+%build
+echo "rpm" %{release} >source
+%configure --disable-rpath --with-guile \
+               --enable-gtk2ui --enable-guishell --with-pam \
+               --with-krb5 --enable-gnomeapplet --without-keyutils
+%{__make}
+
+%install
+rm -rf "$RPM_BUILD_ROOT"
+mkdir "$RPM_BUILD_ROOT"
+make install DESTDIR="$RPM_BUILD_ROOT"
+install -D -m 644 contrib/pam.d-doldacond "$RPM_BUILD_ROOT"%{_sysconfdir}/pam.d/doldacond
+install -D contrib/fedora-init.d-doldacond "$RPM_BUILD_ROOT"%{_initrddir}/doldacond
+rm -f "$RPM_BUILD_ROOT"%{_libdir}/gaim/*.a
+rm -f "$RPM_BUILD_ROOT"%{_libdir}/libdolcon-guile.a
+rm -f "$RPM_BUILD_ROOT"%{_libdir}/libdolcon-guile.la
+
+%find_lang %{name}
+
+%clean
+rm -rf "$RPM_BUILD_ROOT"
+
+%post  libs -p /sbin/ldconfig
+%postun        libs -p /sbin/ldconfig
+
+%files
+%defattr(-,root,root)
+%{_bindir}/dolcon
+%{_bindir}/dolconf
+%{_bindir}/dolcon-launch
+%{_bindir}/doldacond-shell
+%{_desktopdir}/dolcon.desktop
+%{_mandir}/man1/dolcon.1.gz
+
+%files applet
+%{_libdir}/bonobo/servers/*.server
+%{_libexecdir}/dolcon-trans-applet
+
+%files data
+%{_iconsdir}/*
+%{_datadir}/locale/*/LC_MESSAGES/doldaconnect.mo
+%doc AUTHORS ChangeLog README doc/INSTALL doc/gui-shell doc/TODO doc/protorev
+
+%files libs
+%defattr(-,root,root)
+%{_libdir}/libdcui.so.1
+%{_libdir}/libdcui.so.1.1.0
+
+%files devel
+%defattr(-,root,root)
+%{_libdir}/libdcui.so
+%{_libdir}/libdcui.la
+%{_libdir}/libdcui.a
+%dir %{_includedir}/doldaconnect
+%{_includedir}/doldaconnect/*.h
+
+%files guile
+%defattr(-,root,root)
+%{_libdir}/libdolcon-guile.so
+%dir %{_datadir}/guile/site/dolcon
+%{_datadir}/guile/site/dolcon/ui.scm
+%{_datadir}/guile/site/dolcon/util.scm
+%{_bindir}/autodl
+%{_bindir}/chatlog
+%{_bindir}/dcruncmd
+%{_bindir}/hubmgr
+
+%files -n doldacond
+%dir %{_sysconfdir}
+%config(noreplace) %{_sysconfdir}/*
+%{_bindir}/doldacond
+%{_bindir}/locktouch
+%{_bindir}/tthsum
+%{_libexecdir}/speedrec
+%{_mandir}/man5/doldacond.conf.5.gz
+%{_mandir}/man8/doldacond.8.gz
+
+%post -n doldacond
+/sbin/chkconfig --add doldacond
+
+%preun -n doldacond
+%service doldacond stop
+/sbin/chkconfig --del doldacond
+
+%files -n dolcon
+%{_bindir}/dolcon
+%{_mandir}/man1/dolcon.1.gz
+
+%changelog
+* Tue Oct 16 2007 Fredrik Tolf <fredrik@dolda2000.com>
+- Initial spec file. Quite a lot taken from the PLD specfile.
diff --git a/contrib/fedora-init.d-doldacond b/contrib/fedora-init.d-doldacond
new file mode 100755 (executable)
index 0000000..6ed4174
--- /dev/null
@@ -0,0 +1,71 @@
+#!/bin/sh
+# Stolen from PLD Linux
+#
+# doldacond:   Direct Connect client as daemon
+#
+#
+# chkconfig:    345 91 09
+# description:  doldacond
+#
+# config:       /etc/sysconfig/doldacond
+
+# Source function library
+. /etc/rc.d/init.d/functions
+
+# Get service config
+if [ -f /etc/sysconfig/doldacond ]; then
+       . /etc/sysconfig/doldacond
+fi
+
+# Check that networking is up.
+if [ ! -f /var/lock/subsys/network -a "$1" != stop -a "$1" != status ]; then
+       msg_network_down doldacon
+       exit 1
+fi
+
+# See how we were called.
+case "$1" in
+       start)
+               # Check if service is already running?
+               if [ ! -f /var/lock/subsys/doldacond ]; then
+                       msg_starting doldacond
+                       daemon doldacond -C /etc/doldaconnect/doldacond.conf -p /var/run/doldacond.pid ${ADD_OPT}
+                       RETVAL=$?
+                       [ $RETVAL -eq 0 ] && touch /var/lock/subsys/doldacond
+               else
+                       msg_already_running doldacond
+               fi
+               ;;
+       stop)
+               if [ -f /var/lock/subsys/doldacond ]; then
+                       msg_stopping doldacond
+                       killproc --pidfile /var/run/doldacond.pid doldacond
+                       rm -f /var/lock/subsys/doldacond
+               else
+                       msg_not_running doldacond
+               fi
+               ;;
+       status)
+               status doldacond
+               RESULT=$?
+               ;;
+       reload)
+               if [ -f /var/lock/subsys/doldacond ]; then
+                       msg_reloading doldacond
+                       killproc --pidfile /var/run/doldacond.pid doldacond -HUP
+                       RETVAL=$?
+               else
+                       msg_not_running doldacond
+                       exit 7
+               fi
+               ;;
+       restart|force-reload)
+               $0 stop
+               $0 start
+               ;;
+       *)
+               msg_usage "$0 {start|stop|restart|force-reload|status}"
+               exit 3
+esac
+
+exit 0
index 9d8f77c..1ff686c 100644 (file)
@@ -30,4 +30,4 @@ doldacond_SOURCES=    main.c \
 EXTRA_DIST=emacs-local
 doldacond_LDADD=$(top_srcdir)/common/libcommon.a \
                @KRB5_LIBS@ -lbz2 -lz -lgdbm @PAM_LIBS@ @KEYUTILS_LIBS@
-doldacond_CPPFLAGS=-I$(top_srcdir)/include -DDAEMON @KRB5_CFLAGS@
+doldacond_CPPFLAGS=-I$(top_srcdir)/include -DDAEMON @KRB5_CFLAGS@ -D_ISOC99_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE
index 069413d..7b88af3 100644 (file)
@@ -468,7 +468,7 @@ static int opensess(struct authhandle *auth)
            }
            if((ret = krb5_cc_resolve(k5context, buf, &data->ccache)) != 0)
            {
-               flog(LOG_ERR, "could not resolve ccache name \"%s\": %s", buf2, error_message(ret));
+               flog(LOG_ERR, "could not resolve ccache name \"%s\": %s", buf, error_message(ret));
                return(AUTH_ERR);
            }
            setenv("KRB5CCNAME", buf, 1);
index f11836f..82ed1d2 100644 (file)
@@ -64,17 +64,8 @@ static struct fnetnode *newfn(struct fnet *fnet)
 void killfnetnode(struct fnetnode *fn)
 {
     fnetsetstate(fn, FNN_DEAD);
-    if(fn->sk != NULL)
-    {
-       fn->sk->close = 1;
-       if(fn->sk->data == fn)
-       {
-           fn->sk->data = NULL;
-           putfnetnode(fn);
-       }
-       putsock(fn->sk);
-       fn->sk = NULL;
-    }
+    if(fn->connected)
+       fn->fnet->kill(fn);
 }
 
 void getfnetnode(struct fnetnode *fn)
@@ -107,7 +98,7 @@ void putfnetnode(struct fnetnode *fn)
     CBCHAINFREE(fn, fnetpeer_new);
     CBCHAINFREE(fn, fnetpeer_del);
     CBCHAINFREE(fn, fnetpeer_chdi);
-    if(fn->fnet->destroy != NULL)
+    if((fn->fnet->destroy != NULL) && fn->connected)
        fn->fnet->destroy(fn);
     while(fn->args != NULL)
        freewcspair(fn->args, &fn->args);
@@ -119,8 +110,6 @@ void putfnetnode(struct fnetnode *fn)
        free(fn->pubid);
     if(fn->name != NULL)
        free(fn->name);
-    if(fn->sk != NULL)
-       putsock(fn->sk);
     if(fn->owner != NULL)
        free(fn->owner);
     free(fn);
@@ -171,11 +160,12 @@ static void conncb(struct socket *sk, int err, struct fnetnode *data)
        putfnetnode(data);
        return;
     }
-    data->sk = sk;
     fnetsetstate(data, FNN_HS);
     socksettos(sk, confgetint("fnet", "fntos"));
-    data->fnet->connect(data);
+    data->fnet->connect(data, sk);
+    data->connected = 1;
     putfnetnode(data);
+    putsock(sk);
 }
 
 static void resolvecb(struct sockaddr *addr, int addrlen, struct fnetnode *data)
@@ -387,7 +377,7 @@ int fnetsetnick(struct fnetnode *fn, wchar_t *newnick)
 {
     int ret;
     
-    if(fn->fnet->setnick != NULL)
+    if((fn->fnet->setnick != NULL) && fn->connected)
        ret = fn->fnet->setnick(fn, newnick);
     else
        ret = 0;
@@ -402,7 +392,7 @@ int fnetsetnick(struct fnetnode *fn, wchar_t *newnick)
 
 int fnetsendchat(struct fnetnode *fn, int public, wchar_t *to, wchar_t *string)
 {
-    if(fn->fnet->sendchat == NULL)
+    if((fn->fnet->sendchat == NULL) || !fn->connected)
     {
        errno = ENOTSUP;
        return(-1);
index 4c49dfa..d6a73dd 100644 (file)
@@ -44,8 +44,9 @@ struct fnet
 {
     struct fnet *next;
     wchar_t *name;
-    void (*connect)(struct fnetnode *fn);
+    void (*connect)(struct fnetnode *fn, struct socket *sk);
     void (*destroy)(struct fnetnode *fn);
+    void (*kill)(struct fnetnode *fn);
     int (*setnick)(struct fnetnode *fn, wchar_t *newnick);
     int (*reqconn)(struct fnetpeer *peer);
     int (*sendchat)(struct fnetnode *fn, int public, wchar_t *to, wchar_t *string);
@@ -99,12 +100,12 @@ struct fnetnode
     int state;
     int linked;
     int regstatus;
+    int connected;
     time_t srchwait, lastsrch;
     wchar_t *name, *pubid;
     wchar_t *mynick;
     wchar_t *owner;
     struct fnet *fnet;
-    struct socket *sk;
     struct fnetpeerdatum *peerdata;
     struct fnetpeer *peers;
     struct wcspair *args;
index 98d760f..5c609f8 100644 (file)
@@ -59,6 +59,7 @@ struct qcmd {
 };
 
 struct adchub {
+    struct socket *sk;
     char *inbuf;
     size_t inbufdata, inbufsize;
     wchar_t *sid;
@@ -198,8 +199,8 @@ static void freeqcmd(struct qcmd *qcmd)
 #define UNUSED
 #endif
 #define ADC_CMDCOM \
-       struct socket *sk UNUSED = fn->sk; \
-       struct adchub *hub UNUSED = fn->data;
+       struct adchub *hub UNUSED = fn->data; \
+       struct socket *sk UNUSED = hub->sk;
 
 ADC_CMDFN(cmd_sup)
 {
@@ -351,32 +352,31 @@ static void huberr(struct socket *sk, int err, struct fnetnode *fn)
     killfnetnode(fn);
 }
 
-static void hubconnect(struct fnetnode *fn)
+static void hubconnect(struct fnetnode *fn, struct socket *sk)
 {
     struct adchub *hub;
     
-    fn->sk->readcb = (void (*)(struct socket *, void *))hubread;
-    fn->sk->errcb = (void (*)(struct socket *, int, void *))huberr;
-    fn->sk->data = fn;
-    getfnetnode(fn);
+    sk->readcb = (void (*)(struct socket *, void *))hubread;
+    sk->errcb = (void (*)(struct socket *, int, void *))huberr;
+    sk->data = fn;
     
     hub = smalloc(sizeof(*hub));
     memset(hub, 0, sizeof(*hub));
+    getsock(hub->sk = sk);
     if((hub->ich = iconv_open("wchar_t", "utf-8")) == (iconv_t)-1) {
        flog(LOG_CRIT, "iconv cannot handle UTF-8: %s", strerror(errno));
        killfnetnode(fn);
        return;
     }
     fn->data = hub;
-    sendadc(fn->sk, 0, L"HSUP", L"ADBASE", eoc, NULL);
+    sendadc(sk, 0, L"HSUP", L"ADBASE", eoc, NULL);
 }
 
 static void hubdestroy(struct fnetnode *fn)
 {
     struct adchub *hub;
     
-    if((hub = fn->data) == NULL)
-       return;
+    hub = fn->data;
     iconv_close(hub->ich);
     if(hub->inbuf != NULL)
        free(hub->inbuf);
@@ -385,6 +385,14 @@ static void hubdestroy(struct fnetnode *fn)
     free(hub);
 }
 
+static void hubkill(struct fnetnode *fn)
+{
+    struct adchub *hub;
+    
+    hub = fn->data;
+    hub->sk->close = 1;
+}
+
 static int hubsetnick(struct fnetnode *fn, wchar_t *newnick)
 {
     return(0);
@@ -398,6 +406,7 @@ static int hubreqconn(struct fnetpeer *peer)
 static struct fnet adcnet_store = {
     .connect = hubconnect,
     .destroy = hubdestroy,
+    .kill = hubkill,
     .setnick = hubsetnick,
     .reqconn = hubreqconn,
     .name = L"adc"
@@ -420,7 +429,7 @@ static int run(void)
        if((hub = fn->data) == NULL)
            continue;
        if((qcmd = ulqcmd(&hub->queue)) != NULL) {
-           if((fn->sk != NULL) && (fn->sk->state == SOCK_EST))
+           if((hub->sk != NULL) && (hub->sk->state == SOCK_EST))
                dispatch(qcmd, fn);
            freeqcmd(qcmd);
            ret = 1;
index 880b1e3..01592c6 100644 (file)
@@ -101,6 +101,7 @@ struct qcommand
 
 struct dchub
 {
+    struct socket *sk;
     char *inbuf;
     size_t inbufdata, inbufsize;
     struct qcommand *queue;
@@ -666,10 +667,14 @@ static void sendpeerlock(struct dcpeer *peer)
 
 static void sendsupports(struct dcpeer *peer)
 {
-    if(peer->dcppemu)
+    if(peer->dcppemu) {
        qstr(peer->sk, "$Supports MiniSlots XmlBZList ADCGet TTHL TTHF GetZBlock ZLIG |");
-    else
-       qstr(peer->sk, "$Supports MiniSlots XmlBZList ADCGet TTHL TTHF GetZBlock ZLIG|");
+    } else {
+       qstr(peer->sk, "$Supports MiniSlots XmlBZList ADCGet TTHL TTHF");
+       if(!confgetint("dc", "hidedeflate"))
+           qstr(peer->sk, " GetZBlock ZLIG");
+       qstr(peer->sk, "|");
+    }
 }
 
 static void requestfile(struct dcpeer *peer)
@@ -831,10 +836,14 @@ static void cmd_lock(struct socket *sk, struct fnetnode *fn, char *cmd, char *ar
        *(p++) = 0;
     if(hub->extended)
     {
-       if(hub->dcppemu)
+       if(hub->dcppemu) {
            qstrf(sk, "$Supports UserCommand NoGetINFO NoHello UserIP2 TTHSearch GetZBlock |");
-       else
-           qstrf(sk, "$Supports UserCommand NoGetINFO NoHello UserIP2 TTHSearch GetZBlock|");
+       } else {
+           qstrf(sk, "$Supports UserCommand NoGetINFO NoHello UserIP2 TTHSearch");
+           if(!confgetint("dc", "hidedeflate"))
+               qstr(sk, " GetZBlock");
+           qstr(sk, "|");
+       }
     }
     key = dcmakekey(args);
     qstrf(sk, "$Key %s|", key);
@@ -1127,7 +1136,7 @@ static void cmd_search(struct socket *sk, struct fnetnode *fn, char *cmd, char *
            goto out;
        prefix = sprintf2("$SR %s ", hub->nativenick);
        infix = sprintf2(" %i/%i\005", slotsleft(), confgetint("transfer", "slots"));
-       postfix = sprintf2(" (%s)\005%s|", formataddress(fn->sk->remote, fn->sk->remotelen), args + 4);
+       postfix = sprintf2(" (%s)\005%s|", formataddress(hub->sk->remote, hub->sk->remotelen), args + 4);
        dsk = sk;
        getsock(dsk);
     } else {
@@ -1140,7 +1149,7 @@ static void cmd_search(struct socket *sk, struct fnetnode *fn, char *cmd, char *
        addr.sin_port = htons(atoi(p2));
        prefix = sprintf2("$SR %s ", hub->nativenick);
        infix = sprintf2(" %i/%i\005", slotsleft(), confgetint("transfer", "slots"));
-       postfix = sprintf2(" (%s)|", formataddress(fn->sk->remote, fn->sk->remotelen));
+       postfix = sprintf2(" (%s)|", formataddress(hub->sk->remote, hub->sk->remotelen));
        netdgramconn(dsk = netdupsock(udpsock), (struct sockaddr *)&addr, sizeof(addr));
     }
     
@@ -1392,7 +1401,7 @@ static void cmd_to(struct socket *sk, struct fnetnode *fn, char *cmd, char *args
        return;
     *p2 = 0;
     p2 += 2;
-    hubrecvchat(fn->sk, fn, p, p2);
+    hubrecvchat(hub->sk, fn, p, p2);
     hubhandleaction(sk, fn, cmd, args);
 }
 
@@ -2339,10 +2348,10 @@ static int hubreqconn(struct fnetpeer *peer)
        return(1); /* Shouldn't happen, of course, but who knows... */
     if(tcpsock != NULL)
     {
-       sendctm(peer->fn->sk, mbsnick);
+       sendctm(hub->sk, mbsnick);
        expectpeer(mbsnick, peer->fn);
     } else {
-       qstrf(peer->fn->sk, "$RevConnectToMe %s %s|", hub->nativenick, mbsnick);
+       qstrf(hub->sk, "$RevConnectToMe %s %s|", hub->nativenick, mbsnick);
     }
     free(mbsnick);
     return(0);
@@ -2382,12 +2391,12 @@ static int hubsendchat(struct fnetnode *fn, int public, wchar_t *to, wchar_t *st
     {
        if(*to == L'\0')
        {
-           qstrf(fn->sk, "<%s> %s|", hub->nativenick, mbsstring);
+           qstrf(hub->sk, "<%s> %s|", hub->nativenick, mbsstring);
        } else {
-           qstrf(fn->sk, "$To: %s From: %s $<%s> %s|", mbsto, hub->nativenick, hub->nativenick, mbsstring);
+           qstrf(hub->sk, "$To: %s From: %s $<%s> %s|", mbsto, hub->nativenick, hub->nativenick, mbsstring);
        }
     } else {
-       qstrf(fn->sk, "$To: %s From: %s $<%s> %s|", mbsto, hub->nativenick, hub->nativenick, mbsstring);
+       qstrf(hub->sk, "$To: %s From: %s $<%s> %s|", mbsto, hub->nativenick, hub->nativenick, mbsstring);
     }
     free(mbsto);
     free(mbsstring);
@@ -2502,7 +2511,7 @@ static int hubsearch(struct fnetnode *fn, struct search *srch, struct srchfnnlis
     struct hash *hash;
     
     hub = fn->data;
-    if((fn->state != FNN_EST) || (fn->sk == NULL) || (fn->sk->state != SOCK_EST))
+    if((fn->state != FNN_EST) || (hub->sk == NULL) || (hub->sk->state != SOCK_EST))
        return(1);
     list = findsexprstrs(srch->sexpr);
     findsizelimit(srch->sexpr, &minsize, &maxsize);
@@ -2580,15 +2589,15 @@ static int hubsearch(struct fnetnode *fn, struct search *srch, struct srchfnnlis
     addtobuf(sstr, 0);
     if(tcpsock != NULL)
     {
-       if(sockgetremotename2(udpsock, fn->sk, &name, &namelen) < 0)
+       if(sockgetremotename2(udpsock, hub->sk, &name, &namelen) < 0)
        {
            flog(LOG_WARNING, "cannot get address of UDP socket");
        } else {
-           qstrf(fn->sk, "$Search %s %s|", formataddress(name, namelen), sstr);
+           qstrf(hub->sk, "$Search %s %s|", formataddress(name, namelen), sstr);
            free(name);
        }
     } else {
-       qstrf(fn->sk, "$Search Hub:%s %s|", hub->nativenick, sstr);
+       qstrf(hub->sk, "$Search Hub:%s %s|", hub->nativenick, sstr);
     }
     free(sstr);
     freesl(&list);
@@ -2920,10 +2929,13 @@ static void udpread(struct socket *sk, void *data)
        {
            for(fn = fnetnodes; fn != NULL; fn = fn->next)
            {
-               if((fn->fnet == &dcnet) && (fn->sk != NULL) && addreq(fn->sk->remote, (struct sockaddr *)&hubaddr))
+               if((fn->fnet == &dcnet) && ((hub = fn->data) != NULL))
                {
-                   myfn = fn;
-                   break;
+                   if((hub->sk != NULL) && addreq(hub->sk->remote, (struct sockaddr *)&hubaddr))
+                   {
+                       myfn = fn;
+                       break;
+                   }
                }
            }
        }
@@ -3123,13 +3135,15 @@ static void freedcpeer(struct dcpeer *peer)
     numdcpeers--;
 }
 
-static void hubconnect(struct fnetnode *fn)
+static void hubconnect(struct fnetnode *fn, struct socket *sk)
 {
-    fn->sk->readcb = (void (*)(struct socket *, void *))hubread;
-    fn->sk->errcb = (void (*)(struct socket *, int, void *))huberr;
-    getfnetnode(fn);
-    fn->data = newdchub(fn);
-    fn->sk->data = fn;
+    struct dchub *hub;
+    
+    sk->readcb = (void (*)(struct socket *, void *))hubread;
+    sk->errcb = (void (*)(struct socket *, int, void *))huberr;
+    fn->data = hub = newdchub(fn);
+    sk->data = fn;
+    getsock(hub->sk = sk);
     return;
 }
 
@@ -3140,15 +3154,7 @@ static void hubdestroy(struct fnetnode *fn)
     struct qcommand *qcmd;
     
     hub = (struct dchub *)fn->data;
-    if((fn->sk != NULL) && (fn->sk->data == fn))
-    {
-       fn->sk->data = NULL;
-       fn->sk->readcb = NULL;
-       fn->sk->errcb = NULL;
-       putfnetnode(fn);
-    }
-    if(hub == NULL)
-       return;
+    putsock(hub->sk);
     while((qcmd = ulqcmd(&hub->queue)) != NULL)
        freeqcmd(qcmd);
     if(hub->supports != NULL)
@@ -3168,6 +3174,14 @@ static void hubdestroy(struct fnetnode *fn)
     free(hub);
 }
 
+static void hubkill(struct fnetnode *fn)
+{
+    struct dchub *hub;
+    
+    hub = (struct dchub *)fn->data;
+    hub->sk->close = 1;
+}
+
 static wchar_t *dcbasename(wchar_t *filename)
 {
     wchar_t *ret;
@@ -3190,6 +3204,7 @@ static struct fnet dcnet =
     .name = L"dc",
     .connect = hubconnect,
     .destroy = hubdestroy,
+    .kill = hubkill,
     .setnick = hubsetnick,
     .reqconn = hubreqconn,
     .sendchat = hubsendchat,
@@ -3721,10 +3736,10 @@ static int run(void)
        {
            if(*qcmd->string == '$')
            {
-               if((fn->sk != NULL) && (fn->sk->state == SOCK_EST))
-                   dispatchcommand(qcmd, hubcmds, fn->sk, fn);
+               if((hub->sk != NULL) && (hub->sk->state == SOCK_EST))
+                   dispatchcommand(qcmd, hubcmds, hub->sk, fn);
            } else if(*qcmd->string != 0) {
-               hubrecvchat(fn->sk, fn, NULL, qcmd->string);
+               hubrecvchat(hub->sk, fn, NULL, qcmd->string);
            }
            freeqcmd(qcmd);
            ret = 1;
@@ -3873,6 +3888,11 @@ static struct configvar myvars[] =
      * unknown commands it receives, and their arguments, to
      * /tmp/dc-unimpl. */
     {CONF_VAR_BOOL, "logunimpl", {.num = 0}},
+    /** If set to true, doldacond will hide its support for deflate
+     * compression of transfers from other clients, so that they will
+     * not request compressed uploads. Compressed transfers may
+     * consume a non-trivial amount of CPU time on slower machines. */
+    {CONF_VAR_BOOL, "hidedeflate", {.num = 0}},
     {CONF_VAR_END}
 };
 
index 551ed5c..58d1c6c 100644 (file)
@@ -30,6 +30,7 @@
 #include <sys/wait.h>
 #include <stdarg.h>
 #include <fcntl.h>
+#include <sys/select.h>
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
index 6af0e0a..9b5a34a 100644 (file)
@@ -549,7 +549,7 @@ void closesock(struct socket *sk)
 {
     struct sockaddr_un *un;
     
-    if((sk->family == AF_UNIX) && !sockgetlocalname(sk, (struct sockaddr **)&un, NULL) && (un->sun_family == PF_UNIX))
+    if((sk->family == AF_UNIX) && !sockgetlocalname(sk, (struct sockaddr **)(void *)&un, NULL) && (un->sun_family == PF_UNIX))
     {
        if((sk->state == SOCK_LST) && strchr(un->sun_path, '/'))
        {
index bebe011..e2fe54e 100644 (file)
@@ -292,8 +292,12 @@ void *transfergetdata(struct transfer *transfer, size_t *size)
        return(NULL);
     if((transfer->endpos >= 0) && (transfer->curpos + *size >= transfer->endpos))
     {
-       *size = transfer->endpos - transfer->curpos;
-       buf = srealloc(buf, *size);
+       if((*size = transfer->endpos - transfer->curpos) == 0) {
+           free(buf);
+           buf = NULL;
+       } else {
+           buf = srealloc(buf, *size);
+       }
     }
     transfer->curpos += *size;
     bytesupload += *size;
index c18dff3..df3c4f6 100644 (file)
@@ -1,5 +1,5 @@
 doldaconnect (1.0-1) unstable; urgency=low
 
-       * Initial dpkg release.
+  * Initial dpkg release.
 
--- Fredrik Tolf <fredrik@dolda2000.com>  Wed, 17 Oct 2007 19:19:42 +0200
+ -- Fredrik Tolf <fredrik@dolda2000.com>  Wed, 17 Oct 2007 19:19:42 +0200
index d4d3644..fee040d 100644 (file)
@@ -2,17 +2,18 @@ Source: doldaconnect
 Section: network
 Priority: optional
 Maintainer: Fredrik Tolf <fredrik@dolda2000.com>
+Build-Depends: debhelper, cdbs
 Standards-Version: 3.6.1
 
-Package: doldaconnect
+Package: doldacond
 Architecture: any
 Depends: ${shlibs:Depends}
-Description: Dolda Connect is a client program for the Direct Connect peer-to-peer
- filesharing network. It is written so that the user interface is
- separated from the actual filesharing program, so that the user
- interface can run on a different computer over the network, and can be
- shut down temporarily (or only started temporarily), and can be
- replaced altogether.
+Description: Dolda Connect is a client program for the Direct Connect
+ peer-to-peer filesharing network. It is written so that the user
+ interface is separated from the actual filesharing program, so that
+ the user interface can run on a different computer over the network,
+ and can be shut down temporarily (or only started temporarily), and
can be replaced altogether.
  .
  The protocol with which the user interface talks with the actual
  client is also quite well defined, so that other kinds of clients can
diff --git a/debian/doldacond.install b/debian/doldacond.install
new file mode 100644 (file)
index 0000000..24f99e6
--- /dev/null
@@ -0,0 +1,6 @@
+usr/bin/doldacond
+usr/bin/locktouch
+usr/bin/tthsum
+usr/libexec/speedrec
+usr/share/man/man5/doldacond.conf.5
+usr/share/man/man8/doldacond.8
old mode 100644 (file)
new mode 100755 (executable)
index f549901..d1e7451
@@ -1 +1,9 @@
 #!/usr/bin/make -f
+
+include /usr/share/cdbs/1/rules/debhelper.mk
+include /usr/share/cdbs/1/class/autotools.mk
+
+DEB_CONFIGURE_EXTRA_FLAGS = \
+       --enable-daemon --enable-gtk2ui --enable-guishell \
+       --enable-dolconf --enable-gnomeapplet --enable-pidginplugin \
+       --with-guile
diff --git a/doc/INSTALL.guile b/doc/INSTALL.guile
new file mode 100644 (file)
index 0000000..0894ef6
--- /dev/null
@@ -0,0 +1,21 @@
+                    Guile extension installation
+
+The Guile  extension library for  Dolda Connect requires  some special
+attention when installing, because of  how Guile looks for modules. If
+Dolda Connect  is installed into the  prefix /usr, there  should be no
+problem  and  everything  should  work automatically.   However,  when
+installing into any  other prefix, such as /usr/local,  Guile needs to
+be  told to  look for  modules  there.  That  is done  by setting  the
+environment  variable  GUILE_LOAD_PATH   to  include  the  directories
+$PREFIX/share/guile and $PREFIX/share/guile/site.
+
+Some versions  of Guile,  but not all,  are compiled against  a custom
+dynamic linker  as well, which also  needs to be told  where to locate
+the shared  libraries also required  for the Dolda Connect  module. If
+this is the case for your version  of Guile, you will also need to set
+the environment variable LTDL_LIBRARY_PATH to $PREFIX/lib.
+
+
+
+This document was last updated 2008-01-14, reflecting release 1.1 of
+Dolda Connect.
index 07bce28..1f19dc7 100644 (file)
@@ -5,6 +5,9 @@ endif
 if CLI_GTK2
 man_MANS += dolcon.1
 endif
+if ELIB_GUILE
+man_MANS += hubmgr.1
+endif
 BUILT_SOURCES = doldacond.conf.5
 
 doldacond.conf.5: doldacond.conf.5.in ../../daemon/*.c mkcvman
diff --git a/doc/man/hubmgr.1 b/doc/man/hubmgr.1
new file mode 100644 (file)
index 0000000..9292bb3
--- /dev/null
@@ -0,0 +1,110 @@
+.\"
+.\" Copyright (C) 2007 Fredrik Tolf <fredrik@dolda2000.com>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual 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 General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
+.\" USA.
+.\"
+.TH HUBMGR 1 "2007-11-18" "" "Dolda Connect manual"
+.SH NAME
+hubmgr \- Automatic hub manager for Dolda Connect
+.SH SYNOPSIS
+.B hubmgr
+[ \fB-dq\fP ] [ \fB-s\fP \fIserver\fP ]
+.SH DESCRIPTION
+The \fBhubmgr\fP program will read a list of Direct Connect hubs, and
+try to ensure that they are connected to at all times. That involves
+both connecting to them initially, and reconnecting to them, should
+they later disconnect for any reason. If a hub is unreachable,
+\fBhubmgr\fP will keep trying to connect to it in intervals until
+successful.
+.P
+\fBhubmgr\fP handles the SIGINT, SIGHUP and SIGTERM signals and exit
+upon receipt of either one of them. It will also listen for messages
+on the name \fBhubmgr\fP and exit if it receives a message with the
+first token being \fBexit\fP. Upon exit, it will disconnect all
+managed hubs.
+.SH OPTIONS
+.TP
+.B -d
+Normally, \fBhubmgr\fP will daemonize after it has connected and
+authenticated to the daemon successfully. Giving the -d option will
+cause it to continue running in the foreground instead.
+.TP
+.B -q
+Signals more quiet operation. Only error messages will be displayed.
+.TP
+.BI -s " server"
+Connect to \fIserver\fP instead of the default server.
+.SH FILES
+The configuration file for \fBhubmgr\fP is named ~/.hublist. It needs
+to be formatted as follows:
+.P
+The file format is line oriented. A line may be empty, causing it to
+be ignored. There is no syntax for comments. Each non-empty line will
+be divided into words, separated by spaces. Spaces within a word may
+be quoted by enclosing the word in citation marks. The first word on
+each line is the protocol the hub uses. Currently, only the \fBdc\fP
+protocol is supported, signalling a normal Direct Connect hub. The
+second word is the address to the hub, using either a domain name or
+an IP address, followed by a colon, followed by the port number of the
+hub. The port number must always be specified.
+.P
+After the protocol and address words, an arbitrary number of optional
+arguments may follow, to specify such things as the nickname to use,
+or a password to supply to the hub. An argument is two words; one word
+to specify what argument it is, and another for the actual value. The
+following arguments are currently available:
+.TP
+.BI nick " nickname"
+Use \fInickname\fP instead of the server-wide default nickname when
+connecting to the hub.
+.TP
+.BI password " password"
+If the hub requests a password when connecting, use the given
+\fIpassword\fP for that purpose.
+.TP
+.BI charset " charset"
+Use the given charset when communicating with the hub. If this
+argument is not given, the Microsoft CP1252 charset will be used. Most
+hubs will expect the default charset. This option is somewhat
+experimental, and, due to the inherent non-internationalized nature of
+the Direct Connect protocol, may not work quite as one would expect.
+.TP
+.BI dcppemu " emulation"
+Override the \fBdc.dcppemu\fP option configured in the daemon for this
+specific hub, if \fIemulation\fP is \fBy\fP or \fBn\fP. See the
+\fBdoldacond.conf\fP(5) manual page for further information about
+\fBdc.dcppemu\fP.
+.SS Examples
+The following example, if copied into the ~/.hublist file, will
+connect to three hubs. The first one will be connected to normally,
+without any special processing. The second one requires a
+password. The third one requires both a special nickname and a
+password, which contains a space.
+.P
+.nf
+dc hub1.somenet.org:411
+dc dc.someother.net:555 password s3cr3t
+dc a.thirdnet.com:411 nick Cooldude password "Very Secret"
+.fi
+.SH AUTHOR
+Fredrik Tolf <fredrik@dolda2000.com>
+.SH SEE ALSO
+\fBdoldacond.conf\fP(5), \fBdoldacond\fP(8)
index 1c634d8..fdcd0c3 100644 (file)
@@ -70,12 +70,6 @@ extern struct cbchain_ ## name { \
     void *data; \
 } * name
 
-extern int vswprintf (wchar_t *__restrict __s, size_t __n,
-                     __const wchar_t *__restrict __format,
-                     __gnuc_va_list __arg);
-extern int swprintf (wchar_t *__restrict __s, size_t __n,
-                    __const wchar_t *__restrict __format, ...);
-
 char *vsprintf2(char *format, va_list al);
 char *sprintf2(char *format, ...)
 #if defined(__GNUC__)
@@ -113,18 +107,18 @@ struct wcspair *newwcspair(wchar_t *key, wchar_t *val, struct wcspair **list);
 void freewcspair(struct wcspair *pair, struct wcspair **list);
 wchar_t *wpfind(struct wcspair *list, wchar_t *key);
 
-#define sizebuf(b, bs, rs, es, a) _sizebuf((void **)(b), (bs), (rs), (es), (a))
-#define sizebuf2(b, rs, a) _sizebuf((void **)(&(b)), &(b ## size), (rs), sizeof(*(b)), (a))
+#define sizebuf(b, bs, rs, es, a) _sizebuf((void **)(void *)(b), (bs), (rs), (es), (a))
+#define sizebuf2(b, rs, a) _sizebuf((void **)(void *)(&(b)), &(b ## size), (rs), sizeof(*(b)), (a))
 #define addtobuf(b, c) \
 do { \
-    _sizebuf((void **)(&(b)), &(b ## size), (b ## data) + 1, sizeof(*(b)), 1); \
+    _sizebuf((void **)(void *)(&(b)), &(b ## size), (b ## data) + 1, sizeof(*(b)), 1); \
     (b)[(b ## data)++] = (c); \
 } while(0)
 #define bufcat(d, s, n) \
 do { \
     size_t __bufcat_size__; \
     __bufcat_size__ = (n); \
-    _sizebuf((void **)(&(d)), &(d ## size), (d ## data) + __bufcat_size__, sizeof(*(d)), 1); \
+    _sizebuf((void **)(void *)(&(d)), &(d ## size), (d ## data) + __bufcat_size__, sizeof(*(d)), 1); \
     memcpy((d) + (d ## data), (s), sizeof(*(d)) * __bufcat_size__); \
     (d ## data) += __bufcat_size__; \
 } while (0)
index 01c8cfa..a1f677d 100644 (file)
@@ -1,7 +1,6 @@
 EXTRA_DIST = makecmds uicmds
 
-SUBDIRS=. @extlibs@
-DIST_SUBDIRS=guile
+SUBDIRS = . guile
 
 lib_LTLIBRARIES = libdcui.la
 
index 8f4096e..7863f14 100644 (file)
@@ -1,8 +1,9 @@
 SUBDIRS=dolcon
 
-EXTRA_DIST=autodl chatlog hubmgr dcruncmd
-
+if ELIB_GUILE
+dist_bin_SCRIPTS=autodl chatlog hubmgr dcruncmd
 lib_LTLIBRARIES=libdolcon-guile.la
+endif
 
 libdolcon_guile_la_SOURCES=dolcon-guile.c
 libdolcon_guile_la_LDFLAGS=-module -avoid-version
index ff21b84..b6498de 100755 (executable)
@@ -19,7 +19,7 @@
 ;  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 (use-modules (dolcon ui))
-(use-modules (ice-9 pretty-print))
+(use-modules (ice-9 pretty-print) (ice-9 rdelim))
 
 (define sr '())
 (define lastsearch 0)
index 950aa07..d66489e 100755 (executable)
@@ -19,7 +19,7 @@
 ;  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 (use-modules (dolcon ui))
-(use-modules (ice-9 pretty-print))
+(use-modules (ice-9 pretty-print) (ice-9 rdelim))
 
 (define fnetnodes '())
 
index 2b3de3b..e3e6db8 100644 (file)
@@ -262,7 +262,17 @@ static SCM scm_dc_qcmd(SCM argv, SCM callback)
     dc_freewcsarr(toks);
     if(cmd != NULL)
        free(cmd);
-    return(scm_from_int(tag));
+    if(tag == -1) {
+       if(errno == ENOSYS) {
+           scm_error(scm_str2symbol("no-such-cmd"), "dc-qcmd", "Invalid command name", SCM_EOL, SCM_BOOL_F);
+       } else if(errno == EINVAL) {
+           scm_error(scm_str2symbol("illegal-escape"), "dc-qcmd", "Invalid escape sequence", SCM_EOL, SCM_BOOL_F);
+       } else {
+           scm_syserror("dc-qcmd");
+       }
+    } else {
+       return(scm_from_int(tag));
+    }
 }
 
 static void login_scmcb(int err, wchar_t *reason, struct scmcb *scmcb)
index 0dbf180..76ced14 100644 (file)
@@ -1,4 +1,7 @@
 moduledir=$(datadir)/guile/site/dolcon
+
+if ELIB_GUILE
 module_DATA=ui.scm util.scm
+endif
 
 EXTRA_DIST=ui.scm util.scm
index bf57b06..b8ec63f 100644 (file)
 (define-public dc-ecmd
   (lambda args
     (let ((tag (dc-qcmd args)))
-      (if (>= tag 0)
-         (do ((resp (dc-getresp tag) (dc-getresp tag)))
-             (resp resp)
-           (dc-select)))
+      (do ((resp (dc-getresp tag) (dc-getresp tag)))
+         (resp resp)
+       (dc-select))
       )
     )
   )
index 5680338..bd09a23 100644 (file)
@@ -21,6 +21,8 @@
 (define fnetnodes '())
 (define loop-procs '())
 (define fn-procs '())
+(define msg-procs '())
+(define timeouts '())
 
 (define-public dc-fn-update
   (lambda ()
@@ -71,7 +73,7 @@
     (set! fn-procs (cons (list event proc)
                         fn-procs))))
 
-(define-public dc-handle-fn
+(define dc-handle-fn
   (lambda ()
     (dc-fn-update)
     (let* ((notify (lambda (event data) (for-each (lambda (o) (if (eq? event (car o)) ((cadr o) data))) fn-procs)))
                                     (notify 'dstr (cdr nform))
                                     (set! fnetnodes (delq nform fnetnodes))))))))
 
+(define-public dc-msgproc-reg
+  (lambda (proc)
+    (set! msg-procs (cons proc msg-procs))))
+
+(define dc-handle-msg
+  (lambda ()
+    (dc-loop-reg ".notify" 640 (lambda (r er)
+                                (let ((sender (cadadr (assq 'resp er)))
+                                      (message (cddadr (assq 'resp er))))
+                                  (for-each (lambda (o) (o sender message))
+                                            msg-procs))))))
+
+(define-public dc-util-handle
+  (lambda what
+    (for-each (lambda (o)
+               (case o
+                 ((fn) (dc-handle-fn))
+                 ((msg) (dc-handle-msg))))
+             what)))
+
+(define-public dc-timeout
+  (lambda (rel timeout proc)
+    (let* ((tf (gettimeofday))
+          (t (+ (car tf) (/ (cdr tf) 1000000))))
+      (set! timeouts (merge timeouts (list (cons (if rel (+ timeout t) timeout) proc))
+                           (lambda (a b) (< (car a) (car b))))))))
+
 (define-public dc-loop-reg
   (lambda (cmd code proc)
     (set! loop-procs (cons (cons (cons cmd code) proc)
 (define-public dc-loop
   (lambda ()
     (while #t
-          (dc-select 10000)
+          (dc-select (if (eq? timeouts '())
+                         10000
+                         (let* ((tf (gettimeofday))
+                                (t (+ (car tf) (/ (cdr tf) 1000000)))
+                                (dt (- (caar timeouts) t)))
+                           (if (< dt 0) 0 (truncate (inexact->exact (* dt 1000)))))))
           (while (let ((resp (dc-getresp)))
                    (if resp
                        (let* ((er (dc-extract resp)) (code (cdr (assq 'code er))) (cmd (cdr (assq 'cmd er))))
                           loop-procs))
                        #f))
                  #f)
+          (while (and (not (eq? timeouts '()))
+                      (let* ((tf (gettimeofday))
+                            (t (+ (car tf) (/ (cdr tf) 1000000))))
+                        (>= t (caar timeouts))))
+                 ((cdar timeouts))
+                 (set! timeouts (cdr timeouts)))
           (for-each (lambda (o)
                       (if (equal? (caar o) ".periodic")
                           ((cdr o))))
index 39b4f43..8da04f5 100755 (executable)
@@ -19,7 +19,7 @@
 ;  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 (use-modules (dolcon ui) (dolcon util))
-(use-modules (ice-9 format))
+(use-modules (ice-9 format) (ice-9 rdelim) (ice-9 getopt-long))
 
 (define max-hubs 6)
 (define hub-list '())
 (define hublist '())
 (define connlist '())
 (define statelist '())
+(define logdest #t)
 
 (define (logf . args)
   (let ((fmt (car args)) (args (cdr args)))
-    (apply format (cons* #t (string-append fmt "~%") args))))
+    (if logdest
+       (apply format (cons* logdest (string-append fmt "~%") args)))))
 
 (define (list-delta l1 l2)
   (let ((r1 '()) (r2 '()))
     (list r1 r2 l2)))
 
 (define (read-hl)
-  (catch 'system-error
-        (lambda () 
-          (let ((p (open-input-file hl-file)))
-            (catch 'eof
-                   (lambda ()
-                     (let ((lines '()))
-                       (while #t
-                              (let ((line (read-line p)))
-                                (if (eof-object? line)
-                                    (throw 'eof lines)
-                                    (let ((lexed (dc-lexsexpr line)))
-                                      (if (> (length lexed) 0)
-                                          (set! lines (append lines (list lexed))))))))))
-                   (lambda (s a) (close-port p) a))))
-        (lambda (key . args)
-          '())))
+  (letrec ((read-lines (lambda (lines p)
+                        (let ((line (read-line p)))
+                          (if (eof-object? line)
+                              (begin (close-port p)
+                                     lines)
+                              (read-lines (let ((lexed (dc-lexsexpr line)))
+                                            (if (> (length lexed) 0)
+                                                (append lines (list lexed))
+                                                lines)) p))))))
+    (catch 'system-error
+          (lambda () (read-lines '() (open-input-file hl-file)))
+          (lambda (key . args) '()))))
 
 (define (cklist)
   (set! statelist (let ((nl '()) (ct (current-time)))
@@ -77,7 +75,7 @@
                       (not (assq o statelist)))
                  (begin (logf "connecting to ~a" (cadr o))
                         (set! connlist (cons (cons o 'pend) connlist))
-                        (dc-qcmd (list* "cnct" o)
+                        (dc-qcmd (cons* "cnct" o)
                                  (let ((hub o))
                                    (lambda (resp)
                                      (let ((er (dc-extract resp)) (ir (dc-intresp resp)))
            hublist))
 
 (define (hubmgr-main args)
-  (let ((dc-server #f))
+  (let ((opts (getopt-long args '((nodaemon (single-char #\d) (value #f))
+                                 (server (single-char #\s) (value #t))
+                                 (quiet (single-char #\q) (value #f))))))
+    (if (option-ref opts 'quiet #f) (set! logdest #f))
     (set! hublist (read-hl))
     (logf "read ~a hubs" (length hublist))
-    (dc-c&l #t dc-server #t)
-    (dc-ecmd-assert 200 "notify" "fn:act" "on")
-    (dc-handle-fn)
+    (dc-c&l (not (option-ref opts 'quiet #f)) (option-ref opts 'server #f) #t)
+    (dc-ecmd-assert 200 "notify" "fn:act" "on" "msg" "on")
+    (dc-ecmd-assert 200 "register" "hubmgr")
+    (dc-util-handle 'fn 'msg)
     (dc-fnproc-reg 'state (lambda (fn)
                            (if (and (eq? (cdr (assq 'state fn)) 'dead)
                                     (assq (cdr (assq 'id fn)) (map (lambda (o) (cons (cdr o) (car o))) connlist)))
                                   (set! connlist (delq (assq hlf connlist) connlist))
                                   (set! statelist (cons (list hlf (current-time) 10) statelist)))))
                           (cklist)))
+    (dc-msgproc-reg (lambda (sender msg)
+                     (if (equal? (car msg) "exit")
+                         (throw 'quit 0))))
     (dc-loop-reg ".periodic" #f cklist)
     
+    (if (not (option-ref opts 'nodaemon #f))
+       (begin (logf "daemonizing...")
+              (if (= (primitive-fork) 0)
+                  (set! logdest #f)
+                  (primitive-exit 0))))
+    
+    (for-each (lambda (sig) (sigaction sig (lambda (sig) (throw 'quit 0)))) (list SIGINT SIGTERM SIGHUP))
     (cklist)
-    (dc-loop)))
+    (catch 'quit dc-loop
+          (lambda (sig ret)
+            (catch 'quit
+                   (lambda ()
+                     (for-each (lambda (o)
+                                 (if (not (eq? (cdr o) 'pend))
+                                     (dc-ecmd "dcnct" (cdr o))))
+                               connlist)
+                     )
+                   (lambda (sig ret) ret))
+            ret))))
 
 (setlocale LC_ALL "")
 (hubmgr-main (command-line))
index 5ee9e40..c007e01 100644 (file)
@@ -50,7 +50,10 @@ def mustconnect(host, revision = latest):
     any of these steps fail, an exception is raised. If successful,
     the file descriptor for the server connection is returned.
     """
-    fd = connect(host)
+    if host is None:
+        fd = connect()
+    else:
+        fd = connect(host)
     while True:
         resp = getresp()
         if resp is not None and resp.getcmd() == u".connect":
@@ -65,15 +68,10 @@ def mustconnect(host, revision = latest):
 def cnl(host = None, useauthless = True, revision = latest, **kw):
     """A convenience function for connect and loginasync.
 
-    This function will connect to the given server, or the server in
-    the environment variable $DCSERVER if none is given, or, if that
-    fails, localhost, and authenticate to the server. If any of the
-    steps fail, an exception is raised.
+    This function will connect to the given server, or try the default
+    servers if none given, and authenticate to the server. If any of
+    the steps fail, an exception is raised.
     """
-    if host is None:
-        host = os.getenv("DCSERVER")
-    if host is None:
-        host = "localhost"
     fd = mustconnect(host, revision)
     err, reason = login(useauthless, **kw)
     if err != "success":
index 238f886..1418174 100644 (file)
@@ -189,11 +189,11 @@ static PyObject *mod_select(PyObject *self, PyObject *args)
        return(NULL);
     }
     if(((pfd.revents & POLLIN) && dc_handleread()) || ((pfd.revents & POLLOUT) && dc_handlewrite())) {
-       if(errno == 0) {
-           fd = -1;
+       fd = -1;
+       if(errno == 0)
            Py_RETURN_FALSE;
-       }
        PyErr_SetFromErrno(PyExc_OSError);
+       return(NULL);
     }
     if(ret > 0)
        Py_RETURN_TRUE;
index 27b74e7..3b3973b 100755 (executable)
@@ -6,7 +6,7 @@ dolmod = Extension("dolmod", ["dolmod.c"],
                    libraries = ["dcui"])
 
 setup(name = "dolcon-py",
-      version = "0.3.1",
+      version = "1.0r1",
       description = "Python glue module for libdcui",
       author = "Fredrik Tolf",
       author_email = "fredrik@dolda2000.com",
index b235105..26429f8 100644 (file)
@@ -212,8 +212,10 @@ static struct qcmd *makeqcmd(wchar_t *name)
            if((cmd->name != NULL) && !wcscmp(cmd->name, name))
                break;
        }
-       if(cmd == NULL)
+       if(cmd == NULL) {
+           errno = ENOSYS; /* Bleh */
            return(NULL);
+       }
     }
     new = smalloc(sizeof(*new));
     new->tag = tag++;
@@ -497,6 +499,7 @@ int dc_queuecmd(int (*callback)(struct dc_response *), void *data, ...)
                } else {
                    if(buf != NULL)
                        free(buf);
+                   errno = EINVAL;
                    return(-1);
                }
            } else {
index 05fb117..bd4cfae 100644 (file)
--- a/po/sv.po
+++ b/po/sv.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: doldaconnect 0.1.1\n"
 "Report-Msgid-Bugs-To: fredrik@dolda2000.com\n"
-"POT-Creation-Date: 2007-10-15 02:19+0200\n"
+"POT-Creation-Date: 2007-10-22 00:12+0200\n"
 "PO-Revision-Date: 2007-08-31 03:37+0200\n"
 "Last-Translator: Fredrik Tolf <fredrik@dolda2000.com>\n"
 "Language-Team: Swedish <sv@li.org>\n"
@@ -41,7 +41,7 @@ msgstr "%H:%M:%S"
 msgid "%s (reported at %s)"
 msgstr "%s (rapporterades kl. %s)"
 
-#: clients/gtk2/dolcon.c:624 clients/gtk2/dolcon.c:2312
+#: clients/gtk2/dolcon.c:624 clients/gtk2/dolcon.c:2315
 msgid "Disconnected"
 msgstr "Frånkopplad"
 
@@ -78,23 +78,23 @@ msgstr "Inloggningsförsöket misslyckades!"
 msgid "Discrete sizes"
 msgstr "Enskilda storlekar"
 
-#: clients/gtk2/dolcon.c:1027 clients/gui-shell/dsh.c:351
+#: clients/gtk2/dolcon.c:1028 clients/gui-shell/dsh.c:351
 msgid "The server refused the connection"
 msgstr "Servern vägrade förbindelsen"
 
-#: clients/gtk2/dolcon.c:1031 clients/gui-shell/dsh.c:354
+#: clients/gtk2/dolcon.c:1032 clients/gui-shell/dsh.c:354
 msgid "Server protocol revision mismatch"
 msgstr "Fel protokoll-revision hos servern"
 
-#: clients/gtk2/dolcon.c:1037
+#: clients/gtk2/dolcon.c:1038
 msgid "Connected"
 msgstr "Ansluten"
 
-#: clients/gtk2/dolcon.c:1265
+#: clients/gtk2/dolcon.c:1266
 msgid "The server has closed the connection"
 msgstr "Servern har stängt förbindelsen"
 
-#: clients/gtk2/dolcon.c:1267
+#: clients/gtk2/dolcon.c:1268
 #, c-format
 msgid ""
 "The connection to the server failed:\n"
@@ -105,11 +105,11 @@ msgstr ""
 "\n"
 "%s"
 
-#: clients/gtk2/dolcon.c:1287
+#: clients/gtk2/dolcon.c:1288
 msgid "Preferences"
 msgstr "Inställningar"
 
-#: clients/gtk2/dolcon.c:1326
+#: clients/gtk2/dolcon.c:1328
 #, c-format
 msgid ""
 "Could not connect:\n"
@@ -120,107 +120,107 @@ msgstr ""
 "\n"
 "%s"
 
-#: clients/gtk2/dolcon.c:1333 clients/gtk2/hublist.c:206
+#: clients/gtk2/dolcon.c:1335 clients/gtk2/hublist.c:206
 #: clients/gnome-trans-applet/dolcon-trans-applet.c:113
 msgid "Connecting..."
 msgstr "Ansluter..."
 
-#: clients/gtk2/dolcon.c:1342
+#: clients/gtk2/dolcon.c:1344
 msgid "Connect"
 msgstr "Anslut"
 
-#: clients/gtk2/dolcon.c:1342
+#: clients/gtk2/dolcon.c:1344
 msgid "Server address:"
 msgstr "Serverns adress:"
 
-#: clients/gtk2/dolcon.c:1355 clients/gtk2/dolcon.c:1376
-#: clients/gtk2/dolcon.c:1474 clients/gtk2/dolcon.c:1516
-#: clients/gtk2/dolcon.c:1580 clients/gtk2/dolcon.c:1668
-#: clients/gtk2/dolcon.c:1765
+#: clients/gtk2/dolcon.c:1357 clients/gtk2/dolcon.c:1378
+#: clients/gtk2/dolcon.c:1476 clients/gtk2/dolcon.c:1518
+#: clients/gtk2/dolcon.c:1582 clients/gtk2/dolcon.c:1670
+#: clients/gtk2/dolcon.c:1767
 msgid "Not connected to DC server"
 msgstr "Ej ansluten till DC-servern"
 
-#: clients/gtk2/dolcon.c:1362 clients/gtk2/dolcon.c:1395
-#: clients/gtk2/dolcon.c:1487 clients/gtk2/dolcon.c:1534
-#: clients/gtk2/dolcon.c:1593 clients/gtk2/dolcon.c:1686
-#: clients/gtk2/dolcon.c:1741 clients/gtk2/dolcon.c:1812
-#: clients/gtk2/dolcon.c:1937 clients/gtk2/dolcon.c:1964
+#: clients/gtk2/dolcon.c:1364 clients/gtk2/dolcon.c:1397
+#: clients/gtk2/dolcon.c:1489 clients/gtk2/dolcon.c:1536
+#: clients/gtk2/dolcon.c:1595 clients/gtk2/dolcon.c:1688
+#: clients/gtk2/dolcon.c:1743 clients/gtk2/dolcon.c:1814
+#: clients/gtk2/dolcon.c:1939 clients/gtk2/dolcon.c:1966
 msgid "You do not have permission to do that"
 msgstr "Du har inte tillstånd att göra det"
 
-#: clients/gtk2/dolcon.c:1382
+#: clients/gtk2/dolcon.c:1384
 msgid "Illegal address entered"
 msgstr "Ogiltig adress"
 
-#: clients/gtk2/dolcon.c:1397 clients/gtk2/dolcon.c:1536
+#: clients/gtk2/dolcon.c:1399 clients/gtk2/dolcon.c:1538
 msgid "The server could not parse that address"
 msgstr "Servern kunde inte tolka den adressen"
 
-#: clients/gtk2/dolcon.c:1399 clients/gtk2/dolcon.c:1538
+#: clients/gtk2/dolcon.c:1401 clients/gtk2/dolcon.c:1540
 msgid "There are too many hubs connected"
 msgstr "För många hubbar är anslutna"
 
-#: clients/gtk2/dolcon.c:1479 clients/gtk2/dolcon.c:1585
+#: clients/gtk2/dolcon.c:1481 clients/gtk2/dolcon.c:1587
 msgid "No hub selected"
 msgstr "Ingen hub vald"
 
-#: clients/gtk2/dolcon.c:1595
+#: clients/gtk2/dolcon.c:1597
 msgid ""
 "This hub could not support all the types of characters in your chat message"
 msgstr "Den här hubben klarar inte av alla sorters bokstäver i ditt meddelande"
 
-#: clients/gtk2/dolcon.c:1597
+#: clients/gtk2/dolcon.c:1599
 msgid "This hub does not support chatting"
 msgstr "Den här hubben klarar inte av att chatta"
 
-#: clients/gtk2/dolcon.c:1599
+#: clients/gtk2/dolcon.c:1601
 #, c-format
 msgid "An error occurred while trying to chat (%i)"
 msgstr "Ett fel uppstod under försöket att chatta (%i)"
 
-#: clients/gtk2/dolcon.c:1676
+#: clients/gtk2/dolcon.c:1678
 msgid "Please enter a search expression before searching"
 msgstr "Skriv in ett sökuttryck först"
 
-#: clients/gtk2/dolcon.c:1684
+#: clients/gtk2/dolcon.c:1686
 msgid "Could not find any hubs to search on"
 msgstr "Kunde inte hitta någon hub att söka på"
 
-#: clients/gtk2/dolcon.c:1688
+#: clients/gtk2/dolcon.c:1690
 msgid "The server could not parse your search expression"
 msgstr "Servern kunde inte tolka ditt sökuttryck"
 
-#: clients/gtk2/dolcon.c:1690
+#: clients/gtk2/dolcon.c:1692
 #, c-format
 msgid "An error occurred while trying to search (%i)"
 msgstr "Ett fel uppstod under försöket att söka (%i)"
 
-#: clients/gtk2/dolcon.c:1743 clients/gtk2/dolcon.c:1966
+#: clients/gtk2/dolcon.c:1745 clients/gtk2/dolcon.c:1968
 #, c-format
 msgid "An error occurred while trying to cancel (%i)"
 msgstr "Ett fel uppstod under försöket att avbryta (%i)"
 
-#: clients/gtk2/dolcon.c:1814
+#: clients/gtk2/dolcon.c:1816
 #, c-format
 msgid "An error occurred while trying to queue the download (%i)"
 msgstr "Ett fel uppstod under försöket att lägga till nerladdningen (%i)"
 
-#: clients/gtk2/dolcon.c:1939
+#: clients/gtk2/dolcon.c:1941
 #, c-format
 msgid "An error occurred while trying to reset (%i)"
 msgstr "Ett fel uppstod under försöket att återställa (%i)"
 
-#: clients/gtk2/dolcon.c:2074
+#: clients/gtk2/dolcon.c:2077
 #, c-format
 msgid "An error occurred (%ls)"
 msgstr "Ett fel uppstod (%ls)"
 
-#: clients/gtk2/dolcon.c:2192 clients/gtk2/mainwnd.gtk:470
+#: clients/gtk2/dolcon.c:2195 clients/gtk2/mainwnd.gtk:470
 #, c-format
 msgid "Ready to search"
 msgstr "Redo att söka"
 
-#: clients/gtk2/dolcon.c:2194
+#: clients/gtk2/dolcon.c:2197
 #, c-format
 msgid "Search scheduled and will be submitted in %i seconds"
 msgstr "Sökningen är schemalagd och kommer genomföras om %i sekunder"