diff --git a/configure b/configure index 22989f6..82e560f 100755 --- a/configure +++ b/configure @@ -13,12 +13,13 @@ etcdir='$prefix/etc/bitlbee/' mandir='$prefix/share/man/' datadir='$prefix/share/bitlbee/' config='/var/lib/bitlbee/' -plugindir='$prefix/lib/bitlbee/' +libdir='/usr/lib' +plugindir='$libdir/bitlbee/' includedir='$prefix/include/bitlbee/' libevent='/usr/' pidfile='/var/run/bitlbee.pid' ipcsocket='/var/run/bitlbee.sock' -pcdir='$prefix/lib/pkgconfig' +pcdir='$libdir/pkgconfig' msn=1 jabber=1 @@ -54,6 +55,7 @@ Option Description Default --bindir=... $bindir --etcdir=... $etcdir --mandir=... $mandir +--libdir=... $libdir --datadir=... $datadir --plugindir=... $plugindir --pidfile=... $pidfile @@ -84,6 +86,7 @@ done bindir=`eval echo "$bindir/" | sed 's/\/\{1,\}/\//g'` etcdir=`eval echo "$etcdir/" | sed 's/\/\{1,\}/\//g'` mandir=`eval echo "$mandir/" | sed 's/\/\{1,\}/\//g'` +libdir=`eval echo "$libdir/" | sed 's/\/\{1,\}/\//g'` datadir=`eval echo "$datadir/" | sed 's/\/\{1,\}/\//g'` config=`eval echo "$config/" | sed 's/\/\{1,\}/\//g'` plugindir=`eval echo "$plugindir/" | sed 's/\/\{1,\}/\//g'` @@ -100,6 +103,7 @@ PREFIX=$prefix BINDIR=$bindir ETCDIR=$etcdir MANDIR=$mandir +LIBDIR=$libdir DATADIR=$datadir PLUGINDIR=$plugindir CONFIG=$config @@ -322,10 +326,10 @@ fi; echo 'SSL_CLIENT=ssl_'$ssl'.o' >> Makefile.settings -for i in /lib /usr/lib /usr/local/lib; do - if [ -f $i/libresolv.a ]; then +for i in /lib $libdir /usr/local/lib; do + if [ -f $i/libresolv.so ]; then echo '#define HAVE_RESOLV_A' >> config.h - echo 'EFLAGS+='$i'/libresolv.a' >> Makefile.settings + echo 'EFLAGS+=-lresolv' >> Makefile.settings break fi done diff --git a/lib/Makefile b/lib/Makefile index 03fef1a..c8b87b8 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -9,7 +9,7 @@ -include ../Makefile.settings # [SH] Program variables -objects = arc.o base64.o $(EVENT_HANDLER) http_client.o ini.o md5.o misc.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o +objects = arc.o base64.o $(EVENT_HANDLER) http_client.o ini.o md5.o misc.o proxy.o sha1.o srv.o $(SSL_CLIENT) url.o xmltree.o CFLAGS += -Wall LFLAGS += -r diff --git a/lib/misc.c b/lib/misc.c index ccf208b..c31ab57 100644 --- a/lib/misc.c +++ b/lib/misc.c @@ -43,6 +43,7 @@ #ifdef HAVE_RESOLV_A #include #include +#include #endif #include "ssl_client.h" @@ -490,58 +491,6 @@ int bool2int( char *value ) return 0; } -struct ns_srv_reply *srv_lookup( char *service, char *protocol, char *domain ) -{ - struct ns_srv_reply *reply = NULL; -#ifdef HAVE_RESOLV_A - char name[1024]; - unsigned char querybuf[1024]; - const unsigned char *buf; - ns_msg nsh; - ns_rr rr; - int i, len, size; - - g_snprintf( name, sizeof( name ), "_%s._%s.%s", service, protocol, domain ); - - if( ( size = res_query( name, ns_c_in, ns_t_srv, querybuf, sizeof( querybuf ) ) ) <= 0 ) - return NULL; - - if( ns_initparse( querybuf, size, &nsh ) != 0 ) - return NULL; - - if( ns_parserr( &nsh, ns_s_an, 0, &rr ) != 0 ) - return NULL; - - size = ns_rr_rdlen( rr ); - buf = ns_rr_rdata( rr ); - - len = 0; - for( i = 6; i < size && buf[i]; i += buf[i] + 1 ) - len += buf[i] + 1; - - if( i > size ) - return NULL; - - reply = g_malloc( sizeof( struct ns_srv_reply ) + len ); - memcpy( reply->name, buf + 7, len ); - - for( i = buf[6]; i < len && buf[7+i]; i += buf[7+i] + 1 ) - reply->name[i] = '.'; - - if( i > len ) - { - g_free( reply ); - return NULL; - } - - reply->prio = ( buf[0] << 8 ) | buf[1]; - reply->weight = ( buf[2] << 8 ) | buf[3]; - reply->port = ( buf[4] << 8 ) | buf[5]; -#endif - - return reply; -} - /* Word wrapping. Yes, I know this isn't UTF-8 clean. I'm willing to take the risk. */ char *word_wrap( char *msg, int line_len ) { diff --git a/lib/misc.h b/lib/misc.h index a2acada..1c1b97a 100644 --- a/lib/misc.h +++ b/lib/misc.h @@ -28,14 +28,7 @@ #include #include - -struct ns_srv_reply -{ - int prio; - int weight; - int port; - char name[]; -}; +#include "srv.h" G_MODULE_EXPORT void strip_linefeed( gchar *text ); G_MODULE_EXPORT char *add_cr( char *text ); diff --git a/lib/srv.c b/lib/srv.c new file mode 100644 index 0000000..2e038e9 --- /dev/null +++ b/lib/srv.c @@ -0,0 +1,237 @@ +/* srv.c - DNS SRV code + * Copyright (C) 2003 Free Software Foundation, Inc. + * + * This file is part of GNUPG. + * + * GNUPG is free software; 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 3 of the License, or + * (at your option) any later version. + * + * GNUPG 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 program; if not, see . + */ + +#undef TEST + +#ifdef TEST +#define HAVE_RESOLV_A +#endif + +#include +#include + +#include +#include +#include +#include + +#include "srv.h" +#include +#include +#include + +/* Not every installation has gotten around to supporting SRVs + yet...*/ +#ifndef T_SRV +#define T_SRV 33 +#endif + +static int priosort(const void *a, const void *b) { + const struct ns_srv_reply *sa=a, *sb=b; + if (sa->prio>sb->prio) + return 1; + else if (sa->prioprio) + return -1; + else + return 0; +} + +struct ns_srv_reply *srv_lookup(char *service, char *protocol, char *domain) { + struct ns_srv_reply *reply = NULL; + struct ns_srv_reply *list; + char name[1024]; +#ifdef HAVE_RESOLV_A + unsigned char answer[PACKETSZ]; + int r, srvcount=0; + unsigned char *pt, *emsg; + int count, dlen; + + list = NULL; + + g_snprintf(name, sizeof(name ), "_%s._%s.%s", service, protocol, domain); + + _res.options |= RES_DEBUG; + + if ( res_init() != 0 ) + return NULL; + + r=res_query(name, C_IN, T_SRV, answer, PACKETSZ); + + if (rPACKETSZ) + return NULL; + + if ((((HEADER *)answer)->rcode)==NOERROR && (count=ntohs(((HEADER *)answer)->ancount))) { + int i, rc; + + emsg=&answer[r]; /* end of message ??? */ + pt=&answer[sizeof(HEADER)]; + + /* Skip over the query */ + rc=dn_skipname(pt, emsg); + if (rc==-1) + goto fail; + + pt+=rc+QFIXEDSZ; + + while (count-->0 && ptprio=*pt++ << 8; + srv->prio|=*pt++; + srv->weight=*pt++ << 8; + srv->weight|=*pt++; + srv->port=*pt++ << 8; + srv->port|=*pt++; + + /* Get the name. 2782 doesn't allow name compression, but + dn_expand still works to pull the name out of the + packet. */ + rc=dn_expand(answer, emsg, pt, srv->name, MAXDNAME); + if (rc==1 && srv->name[0]==0) /* "." */ + goto noanswer; + if (rc==-1) + goto fail; + pt+=rc; + /* Corrupt packet? */ + if (dlen!=rc+6) + goto fail; + } + + /* Now we have an array of all the srv records. */ + + /* Order by priority */ + qsort(list, srvcount, sizeof(struct ns_srv_reply), priosort); + + /* For each priority, move the zero-weighted items first. */ + for (i=0; iprio); + printf("weight=%hu\n", srv->weight); + printf("port=%hu\n", srv->port); + printf("target=%s\n", srv->name); + printf("\n"); + g_free(srv); + + return 0; +} +#endif /* TEST */ diff --git a/lib/srv.h b/lib/srv.h new file mode 100644 index 0000000..35af753 --- /dev/null +++ b/lib/srv.h @@ -0,0 +1,49 @@ +/* srv.h + * Copyright (C) 2003, 2004 Free Software Foundation, Inc. + * + * This file is part of GNUPG. + * + * GNUPG is free software; 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 3 of the License, or + * (at your option) any later version. + * + * GNUPG 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 program; if not, see . + */ + +#ifndef GNUPG_COMMON_SRV_H +#define GNUPG_COMMON_SRV_H + +#ifdef HAVE_RESOLV_A +# ifdef _WIN32 +# include +# else +# include +# include +# include +# endif /* !_WIN32 */ +#endif /* USE_DNS_SRV */ + + +#ifndef MAXDNAME +#define MAXDNAME 1025 +#endif + +struct ns_srv_reply +{ + int prio; /* priority */ + int weight; /* weight */ + int port; /* port */ + int run_count; /* from struct srventry at gnupg's common/srv.h */ + char name[MAXDNAME]; /* target */ +}; + +struct ns_srv_reply *srv_lookup(char *service, char *protocol, char *domain); + +#endif /*GNUPG_COMMON_SRV_H*/