|
|
5003895 |
Patch by Matěj Cepl <mcepl@redhat.com> for bitlbee >= 3.2 to avoid static linking
|
|
|
566011b |
to a private glibc function, that is normally visible as libc.so.6(GLIBC_PRIVATE)
|
|
|
566011b |
in the binary RPM package. Glibc >= 2.9 allows dynamic linking using -lresolv for
|
|
|
566011b |
ns_initparse()/ns_parserr(), but Red Hat Enterprise Linux 5 (including derivates)
|
|
|
566011b |
is shipping glibc 2.5. A few more information and details regarding this patch in
|
|
|
566011b |
Red Hat Bugzilla ID #439047: https://bugzilla.redhat.com/show_bug.cgi?id=439047
|
|
|
566011b |
|
|
|
5003895 |
--- bitlbee-3.2.1/configure 2013-11-27 23:54:54.000000000 +0100
|
|
|
5003895 |
+++ bitlbee-3.2.1/configure.libresolv 2013-12-18 21:56:14.000000000 +0100
|
|
|
5003895 |
@@ -364,10 +364,10 @@
|
|
|
4b3d380 |
TMPFILE=$(mktemp /tmp/bitlbee-configure.XXXXXX)
|
|
|
4b3d380 |
ret=1
|
|
|
f03c519 |
for i in $systemlibdirs; do
|
|
|
f03c519 |
- if [ -f $i/libresolv.a ]; then
|
|
|
f03c519 |
+ if [ -f $i/libresolv.so ]; then
|
|
|
4b3d380 |
echo "$RESOLV_TESTCODE" | $CC -o $TMPFILE -x c - -Wl,$i/libresolv.a >/dev/null 2>/dev/null
|
|
|
f03c519 |
if [ "$?" = "0" ]; then
|
|
|
f03c519 |
- echo 'EFLAGS+='$i'/libresolv.a' >> Makefile.settings
|
|
|
f03c519 |
+ echo 'EFLAGS+=-lresolv' >> Makefile.settings
|
|
|
4b3d380 |
ret=0
|
|
|
f03c519 |
fi
|
|
|
f03c519 |
fi
|
|
|
5003895 |
--- bitlbee-3.2.1/lib/misc.c 2013-11-27 23:54:54.000000000 +0100
|
|
|
5003895 |
+++ bitlbee-3.2.1/lib/misc.c.libresolv 2013-12-18 22:10:45.000000000 +0100
|
|
|
5003895 |
--- bitlbee-3.2.1/lib/misc.c 2013-11-27 23:54:54.000000000 +0100
|
|
|
5003895 |
+++ bitlbee-3.2.1/lib/misc.c.libresolv.c 2013-12-18 22:18:29.000000000 +0100
|
|
|
d4fdeea |
@@ -30,6 +30,12 @@
|
|
|
d4fdeea |
Suite 330, Boston, MA 02111-1307 USA
|
|
|
d4fdeea |
*/
|
|
|
4ce68a1 |
|
|
|
d4fdeea |
+#undef TEST
|
|
|
d4fdeea |
+
|
|
|
d4fdeea |
+#ifdef TEST
|
|
|
d4fdeea |
+#define HAVE_RESOLV_A
|
|
|
d4fdeea |
+#endif
|
|
|
d4fdeea |
+
|
|
|
d4fdeea |
#define BITLBEE_CORE
|
|
|
d4fdeea |
#include "nogaim.h"
|
|
|
d4fdeea |
#include "base64.h"
|
|
|
d4fdeea |
@@ -42,13 +48,17 @@
|
|
|
d4fdeea |
#include <time.h>
|
|
|
72ecaea |
|
|
|
4ce68a1 |
#ifdef HAVE_RESOLV_A
|
|
|
d4fdeea |
-#include <arpa/nameser.h>
|
|
|
4ce68a1 |
#include <resolv.h>
|
|
|
4ce68a1 |
#endif
|
|
|
4ce68a1 |
|
|
|
4b3d380 |
#include "md5.h"
|
|
|
d4fdeea |
#include "ssl_client.h"
|
|
|
d4fdeea |
|
|
|
5003895 |
+/* Not every installation has gotten around to supporting SRVs yet... */
|
|
|
d4fdeea |
+#ifndef T_SRV
|
|
|
d4fdeea |
+#define T_SRV 33
|
|
|
d4fdeea |
+#endif
|
|
|
d4fdeea |
+
|
|
|
d4fdeea |
void strip_linefeed(gchar *text)
|
|
|
d4fdeea |
{
|
|
|
d4fdeea |
int i, j;
|
|
|
5003895 |
@@ -514,66 +524,6 @@
|
|
|
4ce68a1 |
return 0;
|
|
|
4ce68a1 |
}
|
|
|
4ce68a1 |
|
|
|
72ecaea |
-struct ns_srv_reply **srv_lookup( char *service, char *protocol, char *domain )
|
|
|
4ce68a1 |
-{
|
|
|
72ecaea |
- struct ns_srv_reply **replies = NULL;
|
|
|
4ce68a1 |
-#ifdef HAVE_RESOLV_A
|
|
|
72ecaea |
- struct ns_srv_reply *reply = NULL;
|
|
|
4ce68a1 |
- char name[1024];
|
|
|
4ce68a1 |
- unsigned char querybuf[1024];
|
|
|
4ce68a1 |
- const unsigned char *buf;
|
|
|
4ce68a1 |
- ns_msg nsh;
|
|
|
4ce68a1 |
- ns_rr rr;
|
|
|
72ecaea |
- int i, n, len, size;
|
|
|
4ce68a1 |
-
|
|
|
4ce68a1 |
- g_snprintf( name, sizeof( name ), "_%s._%s.%s", service, protocol, domain );
|
|
|
4ce68a1 |
-
|
|
|
4ce68a1 |
- if( ( size = res_query( name, ns_c_in, ns_t_srv, querybuf, sizeof( querybuf ) ) ) <= 0 )
|
|
|
4ce68a1 |
- return NULL;
|
|
|
4ce68a1 |
-
|
|
|
4ce68a1 |
- if( ns_initparse( querybuf, size, &nsh ) != 0 )
|
|
|
4ce68a1 |
- return NULL;
|
|
|
4ce68a1 |
-
|
|
|
72ecaea |
- n = 0;
|
|
|
72ecaea |
- while( ns_parserr( &nsh, ns_s_an, n, &rr ) == 0 )
|
|
|
4ce68a1 |
- {
|
|
|
72ecaea |
- size = ns_rr_rdlen( rr );
|
|
|
72ecaea |
- buf = ns_rr_rdata( rr );
|
|
|
72ecaea |
-
|
|
|
72ecaea |
- len = 0;
|
|
|
72ecaea |
- for( i = 6; i < size && buf[i]; i += buf[i] + 1 )
|
|
|
72ecaea |
- len += buf[i] + 1;
|
|
|
72ecaea |
-
|
|
|
72ecaea |
- if( i > size )
|
|
|
72ecaea |
- break;
|
|
|
72ecaea |
-
|
|
|
72ecaea |
- reply = g_malloc( sizeof( struct ns_srv_reply ) + len );
|
|
|
72ecaea |
- memcpy( reply->name, buf + 7, len );
|
|
|
72ecaea |
-
|
|
|
72ecaea |
- for( i = buf[6]; i < len && buf[7+i]; i += buf[7+i] + 1 )
|
|
|
72ecaea |
- reply->name[i] = '.';
|
|
|
72ecaea |
-
|
|
|
72ecaea |
- if( i > len )
|
|
|
72ecaea |
- {
|
|
|
72ecaea |
- g_free( reply );
|
|
|
72ecaea |
- break;
|
|
|
72ecaea |
- }
|
|
|
72ecaea |
-
|
|
|
72ecaea |
- reply->prio = ( buf[0] << 8 ) | buf[1];
|
|
|
72ecaea |
- reply->weight = ( buf[2] << 8 ) | buf[3];
|
|
|
72ecaea |
- reply->port = ( buf[4] << 8 ) | buf[5];
|
|
|
72ecaea |
-
|
|
|
72ecaea |
- n ++;
|
|
|
72ecaea |
- replies = g_renew( struct ns_srv_reply *, replies, n + 1 );
|
|
|
72ecaea |
- replies[n-1] = reply;
|
|
|
4ce68a1 |
- }
|
|
|
72ecaea |
- if( replies )
|
|
|
72ecaea |
- replies[n] = NULL;
|
|
|
4ce68a1 |
-#endif
|
|
|
4ce68a1 |
-
|
|
|
72ecaea |
- return replies;
|
|
|
4ce68a1 |
-}
|
|
|
4ce68a1 |
-
|
|
|
72ecaea |
void srv_free( struct ns_srv_reply **srv )
|
|
|
4ce68a1 |
{
|
|
|
72ecaea |
int i;
|
|
|
5003895 |
@@ -586,6 +536,136 @@
|
|
|
d4fdeea |
g_free( srv );
|
|
|
d4fdeea |
}
|
|
|
72ecaea |
|
|
|
5003895 |
+static int srv_compare( const void *a, const void *b )
|
|
|
5003895 |
+{
|
|
|
5003895 |
+ int prio;
|
|
|
5003895 |
+ const struct ns_srv_reply *sa = *(struct ns_srv_reply **) a;
|
|
|
5003895 |
+ const struct ns_srv_reply *sb = *(struct ns_srv_reply **) b;
|
|
|
d4fdeea |
+
|
|
|
5003895 |
+ prio = sa->prio - sb->prio;
|
|
|
5003895 |
+ if( prio == 0 )
|
|
|
5003895 |
+ {
|
|
|
5003895 |
+ /* Place weight 0 entries first. */
|
|
|
5003895 |
+ if( sa->weight == 0 )
|
|
|
5003895 |
+ return -1;
|
|
|
5003895 |
+ if( sb->weight == 0 )
|
|
|
5003895 |
+ return 1;
|
|
|
5003895 |
+ }
|
|
|
d4fdeea |
+
|
|
|
5003895 |
+ return prio;
|
|
|
4ce68a1 |
+}
|
|
|
4ce68a1 |
+
|
|
|
5003895 |
+struct ns_srv_reply **srv_lookup( char *service, char *protocol, char *domain )
|
|
|
5003895 |
+{
|
|
|
5003895 |
+ struct ns_srv_reply **results = NULL;
|
|
|
5003895 |
+ struct ns_srv_reply *reply = NULL;
|
|
|
5003895 |
+ char name[1024];
|
|
|
d4fdeea |
+
|
|
|
5003895 |
+ /* PACKETSZ is a maximum packet size and
|
|
|
5003895 |
+ defined in arpa/nameser_compat.h as 512 */
|
|
|
5003895 |
+ unsigned char answer[PACKETSZ];
|
|
|
5003895 |
+ int len;
|
|
|
5003895 |
+ HEADER *header;
|
|
|
5003895 |
+ unsigned char *p;
|
|
|
5003895 |
+ unsigned char *end;
|
|
|
5003895 |
+ unsigned int count;
|
|
|
5003895 |
+ size_t n;
|
|
|
d4fdeea |
+
|
|
|
5003895 |
+ uint16_t type;
|
|
|
5003895 |
+ uint16_t class;
|
|
|
5003895 |
+ uint32_t ttl;
|
|
|
5003895 |
+ uint16_t rdlength;
|
|
|
d4fdeea |
+
|
|
|
5003895 |
+ g_snprintf( name, sizeof( name ), "_%s._%s.%s", service, protocol, domain );
|
|
|
d4fdeea |
+
|
|
|
5003895 |
+ len = res_query( name, C_IN, T_SRV, answer, PACKETSZ );
|
|
|
5003895 |
+ if( len == -1 )
|
|
|
5003895 |
+ {
|
|
|
5003895 |
+ goto fail;
|
|
|
5003895 |
+ }
|
|
|
d4fdeea |
+
|
|
|
5003895 |
+ header = (HEADER *) answer;
|
|
|
5003895 |
+ p = answer + sizeof( HEADER );
|
|
|
5003895 |
+ end = answer + len;
|
|
|
d4fdeea |
+
|
|
|
5003895 |
+ if( header->rcode != NOERROR )
|
|
|
5003895 |
+ {
|
|
|
5003895 |
+ goto fail;
|
|
|
5003895 |
+ }
|
|
|
d4fdeea |
+
|
|
|
5003895 |
+ len = dn_skipname( p, end );
|
|
|
5003895 |
+ if( len == -1 )
|
|
|
5003895 |
+ {
|
|
|
5003895 |
+ goto fail;
|
|
|
5003895 |
+ }
|
|
|
5003895 |
+ p += len + QFIXEDSZ;
|
|
|
d4fdeea |
+
|
|
|
5003895 |
+ count = ntohs( header->ancount );
|
|
|
d4fdeea |
+
|
|
|
5003895 |
+ n = 0;
|
|
|
5003895 |
+ while( count-- > 0 && p < end )
|
|
|
5003895 |
+ {
|
|
|
5003895 |
+ len = dn_skipname( p, end );
|
|
|
5003895 |
+ if( len == -1 )
|
|
|
5003895 |
+ {
|
|
|
5003895 |
+ goto fail;
|
|
|
5003895 |
+ }
|
|
|
5003895 |
+ p += len;
|
|
|
d4fdeea |
+
|
|
|
5003895 |
+ GETSHORT( type, p );
|
|
|
5003895 |
+ GETSHORT( class, p );
|
|
|
5003895 |
+ GETLONG( ttl, p );
|
|
|
5003895 |
+ GETSHORT( rdlength, p );
|
|
|
d4fdeea |
+
|
|
|
5003895 |
+ if( type != T_SRV || class != C_IN )
|
|
|
5003895 |
+ {
|
|
|
5003895 |
+ p += rdlength;
|
|
|
5003895 |
+ continue;
|
|
|
5003895 |
+ }
|
|
|
d4fdeea |
+
|
|
|
5003895 |
+ /* This is an overestimate of the needed size. */
|
|
|
5003895 |
+ reply = g_malloc( sizeof( struct ns_srv_reply ) + rdlength + 1 );
|
|
|
d4fdeea |
+
|
|
|
5003895 |
+ GETSHORT( reply->prio, p );
|
|
|
5003895 |
+ GETSHORT( reply->weight, p );
|
|
|
5003895 |
+ GETSHORT( reply->port, p );
|
|
|
d4fdeea |
+
|
|
|
5003895 |
+ len = dn_expand( answer, end, p, reply->name, rdlength + 1 );
|
|
|
5003895 |
+ if( len == -1 )
|
|
|
5003895 |
+ {
|
|
|
5003895 |
+ g_free( reply );
|
|
|
5003895 |
+ goto fail;
|
|
|
5003895 |
+ }
|
|
|
5003895 |
+ p += len;
|
|
|
d4fdeea |
+
|
|
|
5003895 |
+ /* n + 2 includes an entry for the terminating NULL. */
|
|
|
5003895 |
+ results = g_renew( struct ns_srv_reply *, results, n + 2 );
|
|
|
5003895 |
+ results[n++] = reply;
|
|
|
5003895 |
+ }
|
|
|
d4fdeea |
+
|
|
|
5003895 |
+ if( results != NULL )
|
|
|
5003895 |
+ {
|
|
|
5003895 |
+ results[n] = NULL;
|
|
|
d4fdeea |
+
|
|
|
5003895 |
+ /* Order by priority. */
|
|
|
5003895 |
+ qsort( results, n, sizeof( struct ns_srv_reply * ), srv_compare );
|
|
|
5003895 |
+ }
|
|
|
d4fdeea |
+
|
|
|
5003895 |
+ return results;
|
|
|
d4fdeea |
+
|
|
|
d4fdeea |
+fail:
|
|
|
5003895 |
+ if( results )
|
|
|
5003895 |
+ {
|
|
|
5003895 |
+ while( n-- > 0 )
|
|
|
5003895 |
+ {
|
|
|
5003895 |
+ g_free( results[n] );
|
|
|
5003895 |
+ }
|
|
|
5003895 |
+ g_free( results );
|
|
|
5003895 |
+ }
|
|
|
d4fdeea |
+
|
|
|
5003895 |
+ return NULL;
|
|
|
4ce68a1 |
+}
|
|
|
4ce68a1 |
+
|
|
|
d4fdeea |
/* Word wrapping. Yes, I know this isn't UTF-8 clean. I'm willing to take the risk. */
|
|
|
d4fdeea |
char *word_wrap( const char *msg, int line_len )
|
|
|
d4fdeea |
{
|
|
|
5003895 |
@@ -783,3 +863,24 @@
|
|
|
d4fdeea |
|
|
|
5003895 |
return NULL;
|
|
|
d4fdeea |
}
|
|
|
4ce68a1 |
+
|
|
|
d4fdeea |
+#ifdef TEST
|
|
|
5003895 |
+int main()
|
|
|
5003895 |
+{
|
|
|
5003895 |
+ struct ns_srv_reply **srv;
|
|
|
5003895 |
+ int i;
|
|
|
d4fdeea |
+
|
|
|
5003895 |
+ srv = srv_lookup( "xmpp-client", "tcp", "jabber.org" );
|
|
|
5003895 |
+ for( i = 0; srv[i]; ++i )
|
|
|
5003895 |
+ {
|
|
|
5003895 |
+ printf( "priority=%hu\n", srv[i]->prio );
|
|
|
5003895 |
+ printf( "weight=%hu\n", srv[i]->weight );
|
|
|
5003895 |
+ printf( "port=%hu\n", srv[i]->port );
|
|
|
5003895 |
+ printf( "target=%s\n", srv[i]->name );
|
|
|
5003895 |
+ printf( "\n" );
|
|
|
5003895 |
+ }
|
|
|
5003895 |
+ srv_free( srv );
|
|
|
d4fdeea |
+
|
|
|
5003895 |
+ return 0;
|
|
|
4ce68a1 |
+}
|
|
|
4ce68a1 |
+#endif /* TEST */
|