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
with the Dolda Connect daemon.
[BuildPrepare]
+echo "apkg" >source
prepareBuild --without-krb5 --disable-daemon --without-gtk2
[BuildUnprepare]
daemon.
[BuildPrepare]
+echo "apkg" >source
prepareBuild --enable-gtk2ui --disable-daemon --disable-dolconf --disable-guishell
[BuildUnprepare]
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]
PackageFileName: doldaconnect-guishell-@VERSION@.package
[BuildPrepare]
+echo "apkg" >source
prepareBuild --enable-dolconf --enable-guishell --disable-gtk2ui --disable-daemon
[BuildUnprepare]
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));
}
}
if((len > 4) && !strncmp(p - 4, ".xml", 4)) {
+ /* Because using Content-Type would just be too good! */
p -= 4;
len -= 4;
handler = pubhubxmlhandler;
httest_SOURCES = httest.c
httest_LDADD = libhttp.a libcommon.a
+libcommon_a_CPPFLAGS = -D_ISOC99_SOURCE
libcommon_a_CFLAGS = -fPIC
libhttp_a_CFLAGS = -fPIC
#include <unistd.h>
#include <sys/time.h>
#include <netinet/in.h>
+#include <alloca.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
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])
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])
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])
[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
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])
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])
fi
AC_DEFINE_UNQUOTED([RELEASEINFO], ["$relinfo"])
-AC_SUBST([extlibs])
AC_OUTPUT([
Makefile
autopackage/Makefile
config/cmd/Makefile
config/util/Makefile
contrib/Makefile
+contrib/doldaconnect.spec
share/Makefile
autopackage/doldacond.apspec
autopackage/dolcon.apspec
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
-EXTRA_DIST = gentoo-init.d-doldacond \
- pam.d-doldacond
+EXTRA_DIST = fedora-init.d-doldacond gentoo-init.d-doldacond \
+ pam.d-doldacond doldaconnect.spec
--- /dev/null
+# 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.
--- /dev/null
+#!/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
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
}
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);
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)
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);
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);
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)
{
int ret;
- if(fn->fnet->setnick != NULL)
+ if((fn->fnet->setnick != NULL) && fn->connected)
ret = fn->fnet->setnick(fn, newnick);
else
ret = 0;
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);
{
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);
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;
};
struct adchub {
+ struct socket *sk;
char *inbuf;
size_t inbufdata, inbufsize;
wchar_t *sid;
#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)
{
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);
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);
static struct fnet adcnet_store = {
.connect = hubconnect,
.destroy = hubdestroy,
+ .kill = hubkill,
.setnick = hubsetnick,
.reqconn = hubreqconn,
.name = L"adc"
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;
struct dchub
{
+ struct socket *sk;
char *inbuf;
size_t inbufdata, inbufsize;
struct qcommand *queue;
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)
*(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);
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 {
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));
}
return;
*p2 = 0;
p2 += 2;
- hubrecvchat(fn->sk, fn, p, p2);
+ hubrecvchat(hub->sk, fn, p, p2);
hubhandleaction(sk, fn, cmd, args);
}
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);
{
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);
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);
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);
{
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;
+ }
}
}
}
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;
}
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)
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;
.name = L"dc",
.connect = hubconnect,
.destroy = hubdestroy,
+ .kill = hubkill,
.setnick = hubsetnick,
.reqconn = hubreqconn,
.sendchat = hubsendchat,
{
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;
* 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}
};
#include <sys/wait.h>
#include <stdarg.h>
#include <fcntl.h>
+#include <sys/select.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
{
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, '/'))
{
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;
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
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
--- /dev/null
+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
#!/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
--- /dev/null
+ 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.
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
--- /dev/null
+.\"
+.\" 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)
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__)
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)
EXTRA_DIST = makecmds uicmds
-SUBDIRS=. @extlibs@
-DIST_SUBDIRS=guile
+SUBDIRS = . guile
lib_LTLIBRARIES = libdcui.la
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
; 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)
; 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 '())
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)
moduledir=$(datadir)/guile/site/dolcon
+
+if ELIB_GUILE
module_DATA=ui.scm util.scm
+endif
EXTRA_DIST=ui.scm util.scm
(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))
)
)
)
(define fnetnodes '())
(define loop-procs '())
(define fn-procs '())
+(define msg-procs '())
+(define timeouts '())
(define-public dc-fn-update
(lambda ()
(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))))
; 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)))
(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))
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":
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":
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;
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",
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++;
} else {
if(buf != NULL)
free(buf);
+ errno = EINVAL;
return(-1);
}
} else {
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"
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"
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"
"\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"
"\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"