From df1694b9559d4abec748b0506b5f44e684d022a8 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 25 Jun 2006 14:15:42 +0200 Subject: Moving all generic files to lib/ instead of having some in / and some in protocols/, and adding RC4 code. --- lib/misc.c | 481 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 481 insertions(+) create mode 100644 lib/misc.c (limited to 'lib/misc.c') diff --git a/lib/misc.c b/lib/misc.c new file mode 100644 index 00000000..d8d6a4c7 --- /dev/null +++ b/lib/misc.c @@ -0,0 +1,481 @@ + /********************************************************************\ + * BitlBee -- An IRC to other IM-networks gateway * + * * + * Copyright 2002-2004 Wilmer van der Gaast and others * + \********************************************************************/ + +/* + * Various utility functions. Some are copied from Gaim to support the + * IM-modules, most are from BitlBee. + * + * Copyright (C) 1998-1999, Mark Spencer + * (and possibly other members of the Gaim team) + * Copyright 2002-2005 Wilmer van der Gaast + */ + +/* + This program 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 2 of the License, or + (at your option) any later version. + + This program 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 with + the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL; + if not, write to the Free Software Foundation, Inc., 59 Temple Place, + Suite 330, Boston, MA 02111-1307 USA +*/ + +#define BITLBEE_CORE +#include "nogaim.h" +#include +#include +#include +#include +#include +#include + +void strip_linefeed(gchar *text) +{ + int i, j; + gchar *text2 = g_malloc(strlen(text) + 1); + + for (i = 0, j = 0; text[i]; i++) + if (text[i] != '\r') + text2[j++] = text[i]; + text2[j] = '\0'; + + strcpy(text, text2); + g_free(text2); +} + +char *add_cr(char *text) +{ + char *ret = NULL; + int count = 0, j; + unsigned int i; + + if (text[0] == '\n') + count++; + for (i = 1; i < strlen(text); i++) + if (text[i] == '\n' && text[i - 1] != '\r') + count++; + + if (count == 0) + return g_strdup(text); + + ret = g_malloc0(strlen(text) + count + 1); + + i = 0; j = 0; + if (text[i] == '\n') + ret[j++] = '\r'; + ret[j++] = text[i++]; + for (; i < strlen(text); i++) { + if (text[i] == '\n' && text[i - 1] != '\r') + ret[j++] = '\r'; + ret[j++] = text[i]; + } + + return ret; +} + +char *tobase64(const char *text) +{ + char *out; + int len; + + len = strlen(text); + out = g_malloc((len + 2) /* the == padding */ + / 3 /* every 3-byte block */ + * 4 /* becomes a 4-byte one */ + + 1); /* and of course, ASCIIZ! */ + + base64_encode_real(text, len, out, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="); + + return out; +} + +void base64_encode_real(const unsigned char *in, int inlen, unsigned char *out, char *b64digits) +{ + for (; inlen >= 3; inlen -= 3) + { + *out++ = b64digits[in[0] >> 2]; + *out++ = b64digits[((in[0]<<4) & 0x30) | (in[1]>>4)]; + *out++ = b64digits[((in[1]<<2) & 0x3c) | (in[2]>>6)]; + *out++ = b64digits[in[2] & 0x3f]; + in += 3; + } + if (inlen > 0) + { + *out++ = b64digits[in[0] >> 2]; + if (inlen > 1) + { + *out++ = b64digits[((in[0]<<4) & 0x30) | (in[1]>>4)]; + *out++ = b64digits[((in[1]<<2) & 0x3c)]; + } + else + { + *out++ = b64digits[((in[0]<<4) & 0x30) | (in[1]>>4)]; + *out++ = b64digits[64]; + } + *out++ = b64digits[64]; + } + *out = '\0'; +} + +char *normalize(const char *s) +{ + static char buf[BUF_LEN]; + char *t, *u; + int x = 0; + + g_return_val_if_fail((s != NULL), NULL); + + u = t = g_strdup(s); + + strcpy(t, s); + g_strdown(t); + + while (*t && (x < BUF_LEN - 1)) { + if (*t != ' ') { + buf[x] = *t; + x++; + } + t++; + } + buf[x] = '\0'; + g_free(u); + return buf; +} + +time_t get_time(int year, int month, int day, int hour, int min, int sec) +{ + struct tm tm; + + tm.tm_year = year - 1900; + tm.tm_mon = month - 1; + tm.tm_mday = day; + tm.tm_hour = hour; + tm.tm_min = min; + tm.tm_sec = sec >= 0 ? sec : time(NULL) % 60; + return mktime(&tm); +} + +typedef struct htmlentity +{ + char code[8]; + char is[4]; +} htmlentity_t; + +/* FIXME: This is ISO8859-1(5) centric, so might cause problems with other charsets. */ + +static const htmlentity_t ent[] = +{ + { "lt", "<" }, + { "gt", ">" }, + { "amp", "&" }, + { "quot", "\"" }, + { "aacute", "á" }, + { "eacute", "é" }, + { "iacute", "é" }, + { "oacute", "ó" }, + { "uacute", "ú" }, + { "agrave", "à" }, + { "egrave", "è" }, + { "igrave", "ì" }, + { "ograve", "ò" }, + { "ugrave", "ù" }, + { "acirc", "â" }, + { "ecirc", "ê" }, + { "icirc", "î" }, + { "ocirc", "ô" }, + { "ucirc", "û" }, + { "auml", "ä" }, + { "euml", "ë" }, + { "iuml", "ï" }, + { "ouml", "ö" }, + { "uuml", "ü" }, + { "nbsp", " " }, + { "", "" } +}; + +void strip_html( char *in ) +{ + char *start = in; + char *out = g_malloc( strlen( in ) + 1 ); + char *s = out, *cs; + int i, matched; + + memset( out, 0, strlen( in ) + 1 ); + + while( *in ) + { + if( *in == '<' && ( isalpha( *(in+1) ) || *(in+1) == '/' ) ) + { + /* If in points at a < and in+1 points at a letter or a slash, this is probably + a HTML-tag. Try to find a closing > and continue there. If the > can't be + found, assume that it wasn't a HTML-tag after all. */ + + cs = in; + + while( *in && *in != '>' ) + in ++; + + if( *in ) + { + if( g_strncasecmp( cs+1, "br", 2) == 0 ) + *(s++) = '\n'; + in ++; + } + else + { + in = cs; + *(s++) = *(in++); + } + } + else if( *in == '&' ) + { + cs = ++in; + while( *in && isalpha( *in ) ) + in ++; + + if( *in == ';' ) in ++; + matched = 0; + + for( i = 0; *ent[i].code; i ++ ) + if( g_strncasecmp( ent[i].code, cs, strlen( ent[i].code ) ) == 0 ) + { + int j; + + for( j = 0; ent[i].is[j]; j ++ ) + *(s++) = ent[i].is[j]; + + matched = 1; + break; + } + + /* None of the entities were matched, so return the string */ + if( !matched ) + { + in = cs - 1; + *(s++) = *(in++); + } + } + else + { + *(s++) = *(in++); + } + } + + strcpy( start, out ); + g_free( out ); +} + +char *escape_html( const char *html ) +{ + const char *c = html; + GString *ret; + char *str; + + if( html == NULL ) + return( NULL ); + + ret = g_string_new( "" ); + + while( *c ) + { + switch( *c ) + { + case '&': + ret = g_string_append( ret, "&" ); + break; + case '<': + ret = g_string_append( ret, "<" ); + break; + case '>': + ret = g_string_append( ret, ">" ); + break; + case '"': + ret = g_string_append( ret, """ ); + break; + default: + ret = g_string_append_c( ret, *c ); + } + c ++; + } + + str = ret->str; + g_string_free( ret, FALSE ); + return( str ); +} + +void info_string_append(GString *str, char *newline, char *name, char *value) +{ + if( value && value[0] ) + g_string_sprintfa( str, "%s%s: %s", newline, name, value ); +} + +/* Decode%20a%20file%20name */ +void http_decode( char *s ) +{ + char *t; + int i, j, k; + + t = g_new( char, strlen( s ) + 1 ); + + for( i = j = 0; s[i]; i ++, j ++ ) + { + if( s[i] == '%' ) + { + if( sscanf( s + i + 1, "%2x", &k ) ) + { + t[j] = k; + i += 2; + } + else + { + *t = 0; + break; + } + } + else + { + t[j] = s[i]; + } + } + t[j] = 0; + + strcpy( s, t ); + g_free( t ); +} + +/* Warning: This one explodes the string. Worst-cases can make the string 3x its original size! */ +/* This fuction is safe, but make sure you call it safely as well! */ +void http_encode( char *s ) +{ + char *t; + int i, j; + + t = g_strdup( s ); + + for( i = j = 0; t[i]; i ++, j ++ ) + { + /* if( t[i] <= ' ' || ((unsigned char *)t)[i] >= 128 || t[i] == '%' ) */ + if( !isalnum( t[i] ) ) + { + sprintf( s + j, "%%%02X", ((unsigned char*)t)[i] ); + j += 2; + } + else + { + s[j] = t[i]; + } + } + s[j] = 0; + + g_free( t ); +} + +/* Strip newlines from a string. Modifies the string passed to it. */ +char *strip_newlines( char *source ) +{ + int i; + + for( i = 0; source[i] != '\0'; i ++ ) + if( source[i] == '\n' || source[i] == '\r' ) + source[i] = ' '; + + return source; +} + +#ifdef IPV6 +/* Wrap an IPv4 address into IPv6 space. Not thread-safe... */ +char *ipv6_wrap( char *src ) +{ + static char dst[64]; + int i; + + for( i = 0; src[i]; i ++ ) + if( ( src[i] < '0' || src[i] > '9' ) && src[i] != '.' ) + break; + + /* Hmm, it's not even an IP... */ + if( src[i] ) + return src; + + g_snprintf( dst, sizeof( dst ), "::ffff:%s", src ); + + return dst; +} + +/* Unwrap an IPv4 address into IPv6 space. Thread-safe, because it's very simple. :-) */ +char *ipv6_unwrap( char *src ) +{ + int i; + + if( g_strncasecmp( src, "::ffff:", 7 ) != 0 ) + return src; + + for( i = 7; src[i]; i ++ ) + if( ( src[i] < '0' || src[i] > '9' ) && src[i] != '.' ) + break; + + /* Hmm, it's not even an IP... */ + if( src[i] ) + return src; + + return ( src + 7 ); +} +#endif + +/* Convert from one charset to another. + + from_cs, to_cs: Source and destination charsets + src, dst: Source and destination strings + size: Size if src. 0 == use strlen(). strlen() is not reliable for UNICODE/UTF16 strings though. + maxbuf: Maximum number of bytes to write to dst + + Returns the number of bytes written to maxbuf or -1 on an error. +*/ +signed int do_iconv( char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf ) +{ + GIConv cd; + size_t res; + size_t inbytesleft, outbytesleft; + char *inbuf = src; + char *outbuf = dst; + + cd = g_iconv_open( to_cs, from_cs ); + if( cd == (GIConv) -1 ) + return( -1 ); + + inbytesleft = size ? size : strlen( src ); + outbytesleft = maxbuf - 1; + res = g_iconv( cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft ); + *outbuf = '\0'; + g_iconv_close( cd ); + + if( res == (size_t) -1 ) + return( -1 ); + else + return( outbuf - dst ); +} + +char *set_eval_charset( irc_t *irc, set_t *set, char *value ) +{ + GIConv cd; + + if ( g_strncasecmp( value, "none", 4 ) == 0 ) + return( value ); + + cd = g_iconv_open( "UTF-8", value ); + if( cd == (GIConv) -1 ) + return( NULL ); + + g_iconv_close( cd ); + return( value ); +} -- cgit v1.2.3 From 7ed3199067034b4fda4055778e02274f83bcfcb8 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 25 Jun 2006 16:07:01 +0200 Subject: Moved Base64-related functions to a separate file and added decode funtions. --- lib/misc.c | 44 -------------------------------------------- 1 file changed, 44 deletions(-) (limited to 'lib/misc.c') diff --git a/lib/misc.c b/lib/misc.c index d8d6a4c7..9f592289 100644 --- a/lib/misc.c +++ b/lib/misc.c @@ -83,50 +83,6 @@ char *add_cr(char *text) return ret; } -char *tobase64(const char *text) -{ - char *out; - int len; - - len = strlen(text); - out = g_malloc((len + 2) /* the == padding */ - / 3 /* every 3-byte block */ - * 4 /* becomes a 4-byte one */ - + 1); /* and of course, ASCIIZ! */ - - base64_encode_real(text, len, out, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="); - - return out; -} - -void base64_encode_real(const unsigned char *in, int inlen, unsigned char *out, char *b64digits) -{ - for (; inlen >= 3; inlen -= 3) - { - *out++ = b64digits[in[0] >> 2]; - *out++ = b64digits[((in[0]<<4) & 0x30) | (in[1]>>4)]; - *out++ = b64digits[((in[1]<<2) & 0x3c) | (in[2]>>6)]; - *out++ = b64digits[in[2] & 0x3f]; - in += 3; - } - if (inlen > 0) - { - *out++ = b64digits[in[0] >> 2]; - if (inlen > 1) - { - *out++ = b64digits[((in[0]<<4) & 0x30) | (in[1]>>4)]; - *out++ = b64digits[((in[1]<<2) & 0x3c)]; - } - else - { - *out++ = b64digits[((in[0]<<4) & 0x30) | (in[1]>>4)]; - *out++ = b64digits[64]; - } - *out++ = b64digits[64]; - } - *out = '\0'; -} - char *normalize(const char *s) { static char buf[BUF_LEN]; -- cgit v1.2.3 From 171946457cccb7280f0918201093e79bbc9eac72 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Wed, 28 Jun 2006 16:47:05 +0200 Subject: Added random_bytes() function for better/more reliable randomization and moved set_eval_ops() to a slightly more suitable place. --- lib/misc.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 64 insertions(+), 14 deletions(-) (limited to 'lib/misc.c') diff --git a/lib/misc.c b/lib/misc.c index 9f592289..784d80d6 100644 --- a/lib/misc.c +++ b/lib/misc.c @@ -1,7 +1,7 @@ /********************************************************************\ * BitlBee -- An IRC to other IM-networks gateway * * * - * Copyright 2002-2004 Wilmer van der Gaast and others * + * Copyright 2002-2006 Wilmer van der Gaast and others * \********************************************************************/ /* @@ -10,7 +10,7 @@ * * Copyright (C) 1998-1999, Mark Spencer * (and possibly other members of the Gaim team) - * Copyright 2002-2005 Wilmer van der Gaast + * Copyright 2002-2006 Wilmer van der Gaast */ /* @@ -421,17 +421,67 @@ signed int do_iconv( char *from_cs, char *to_cs, char *src, char *dst, size_t si return( outbuf - dst ); } -char *set_eval_charset( irc_t *irc, set_t *set, char *value ) +/* A pretty reliable random number generator. Tries to use the /dev/random + devices first, and falls back to the random number generator from libc + when it fails. Opens randomizer devices with O_NONBLOCK to make sure a + lack of entropy won't halt BitlBee. */ +void random_bytes( unsigned char *buf, int count ) { - GIConv cd; - - if ( g_strncasecmp( value, "none", 4 ) == 0 ) - return( value ); - - cd = g_iconv_open( "UTF-8", value ); - if( cd == (GIConv) -1 ) - return( NULL ); - - g_iconv_close( cd ); - return( value ); + static int use_dev = -1; + + /* Actually this probing code isn't really necessary, is it? */ + if( use_dev == -1 ) + { + if( access( "/dev/random", R_OK ) == 0 || access( "/dev/urandom", R_OK ) == 0 ) + use_dev = 1; + else + { + use_dev = 0; + srand( ( getpid() << 16 ) ^ time( NULL ) ); + } + } + + if( use_dev ) + { + int fd; + + /* At least on Linux, /dev/random can block if there's not + enough entropy. We really don't want that, so if it can't + give anything, use /dev/urandom instead. */ + if( ( fd = open( "/dev/random", O_RDONLY | O_NONBLOCK ) ) >= 0 ) + if( read( fd, buf, count ) == count ) + { + close( fd ); + return; + } + close( fd ); + + /* urandom isn't supposed to block at all, but just to be + sure. If it blocks, we'll disable use_dev and use the libc + randomizer instead. */ + if( ( fd = open( "/dev/urandom", O_RDONLY | O_NONBLOCK ) ) >= 0 ) + if( read( fd, buf, count ) == count ) + { + close( fd ); + return; + } + close( fd ); + + /* If /dev/random blocks once, we'll still try to use it + again next time. If /dev/urandom also fails for some + reason, stick with libc during this session. */ + + use_dev = 0; + srand( ( getpid() << 16 ) ^ time( NULL ) ); + } + + if( !use_dev ) + { + int i; + + /* Possibly the LSB of rand() isn't very random on some + platforms. Seems okay on at least Linux and OSX though. */ + for( i = 0; i < count; i ++ ) + buf[i] = rand() & 0xff; + } } -- cgit v1.2.3 From 5100caa16bb707d89f1873aca99b5f87abc1dd56 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 1 Jul 2006 17:52:05 +0200 Subject: Added "account set" command. --- lib/misc.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'lib/misc.c') diff --git a/lib/misc.c b/lib/misc.c index 784d80d6..17599946 100644 --- a/lib/misc.c +++ b/lib/misc.c @@ -485,3 +485,37 @@ void random_bytes( unsigned char *buf, int count ) buf[i] = rand() & 0xff; } } + +int is_bool( char *value ) +{ + if( *value == 0 ) + return 0; + + if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 0 ) ) + return 1; + if( ( g_strcasecmp( value, "false" ) == 0 ) || ( g_strcasecmp( value, "no" ) == 0 ) || ( g_strcasecmp( value, "off" ) == 0 ) ) + return 1; + + while( *value ) + if( !isdigit( *value ) ) + return 0; + else + value ++; + + return 1; +} + +int bool2int( char *value ) +{ + int i; + + if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 0 ) ) + return 1; + if( ( g_strcasecmp( value, "false" ) == 0 ) || ( g_strcasecmp( value, "no" ) == 0 ) || ( g_strcasecmp( value, "off" ) == 0 ) ) + return 0; + + if( sscanf( value, "%d", &i ) == 1 ) + return i; + + return 0; +} -- cgit v1.2.3 From 51fdc4512cc77fd6b59b582f27887657d7c3721e Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 17 Sep 2006 17:56:16 +0200 Subject: add_cr() is not used anymore, and HTML entity handling got UTFized some time ago already, so no need for that FIXME comment. --- lib/misc.c | 36 ++---------------------------------- 1 file changed, 2 insertions(+), 34 deletions(-) (limited to 'lib/misc.c') diff --git a/lib/misc.c b/lib/misc.c index 17599946..64666492 100644 --- a/lib/misc.c +++ b/lib/misc.c @@ -53,36 +53,6 @@ void strip_linefeed(gchar *text) g_free(text2); } -char *add_cr(char *text) -{ - char *ret = NULL; - int count = 0, j; - unsigned int i; - - if (text[0] == '\n') - count++; - for (i = 1; i < strlen(text); i++) - if (text[i] == '\n' && text[i - 1] != '\r') - count++; - - if (count == 0) - return g_strdup(text); - - ret = g_malloc0(strlen(text) + count + 1); - - i = 0; j = 0; - if (text[i] == '\n') - ret[j++] = '\r'; - ret[j++] = text[i++]; - for (; i < strlen(text); i++) { - if (text[i] == '\n' && text[i - 1] != '\r') - ret[j++] = '\r'; - ret[j++] = text[i]; - } - - return ret; -} - char *normalize(const char *s) { static char buf[BUF_LEN]; @@ -123,12 +93,10 @@ time_t get_time(int year, int month, int day, int hour, int min, int sec) typedef struct htmlentity { - char code[8]; - char is[4]; + char code[7]; + char is[3]; } htmlentity_t; -/* FIXME: This is ISO8859-1(5) centric, so might cause problems with other charsets. */ - static const htmlentity_t ent[] = { { "lt", "<" }, -- cgit v1.2.3 From 36e9f62a6e6fdb1217b3b819320ac5a94025c448 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 7 Oct 2006 19:46:28 +0200 Subject: Added SRV lookups to automatically find out the correct server for a domain. --- lib/misc.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'lib/misc.c') diff --git a/lib/misc.c b/lib/misc.c index 64666492..9061af39 100644 --- a/lib/misc.c +++ b/lib/misc.c @@ -39,6 +39,11 @@ #include #include +#ifdef HAVE_RESOLV_A +#include +#include +#endif + void strip_linefeed(gchar *text) { int i, j; @@ -487,3 +492,55 @@ 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; +} -- cgit v1.2.3 From d444c09e6c7ac6fc3c1686af0e63c09805d8cd00 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Fri, 12 Oct 2007 01:06:50 +0100 Subject: Added word_wrap() function to misc.c and using it at the right places so that long messages in groupchats also get wrapped properly (instead of truncated). --- lib/misc.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'lib/misc.c') diff --git a/lib/misc.c b/lib/misc.c index 9061af39..5e385d4a 100644 --- a/lib/misc.c +++ b/lib/misc.c @@ -544,3 +544,51 @@ struct ns_srv_reply *srv_lookup( char *service, char *protocol, char *domain ) 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 ) +{ + GString *ret = g_string_sized_new( strlen( msg ) + 16 ); + + while( strlen( msg ) > line_len ) + { + int i; + + /* First try to find out if there's a newline already. Don't + want to add more splits than necessary. */ + for( i = line_len; i > 0 && msg[i] != '\n'; i -- ); + if( msg[i] == '\n' ) + { + g_string_append_len( ret, msg, i + 1 ); + msg += i + 1; + continue; + } + + for( i = line_len; i > 0; i -- ) + { + if( msg[i] == '-' ) + { + g_string_append_len( ret, msg, i + 1 ); + g_string_append_c( ret, '\n' ); + msg += i + 1; + break; + } + else if( msg[i] == ' ' ) + { + g_string_append_len( ret, msg, i ); + g_string_append_c( ret, '\n' ); + msg += i + 1; + break; + } + } + if( i == 0 ) + { + g_string_append_len( ret, msg, line_len ); + g_string_append_c( ret, '\n' ); + msg += line_len; + } + } + g_string_append( ret, msg ); + + return g_string_free( ret, FALSE ); +} -- cgit v1.2.3 From e9b755e3726fa41ac2d4ed1c3a6192d1af68edbc Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 18 Oct 2007 18:44:25 +0200 Subject: Use standard functions for dealing with both IPv6 and IPv4. --- lib/misc.c | 40 ---------------------------------------- 1 file changed, 40 deletions(-) (limited to 'lib/misc.c') diff --git a/lib/misc.c b/lib/misc.c index 5e385d4a..ceba9d95 100644 --- a/lib/misc.c +++ b/lib/misc.c @@ -321,46 +321,6 @@ char *strip_newlines( char *source ) return source; } -#ifdef IPV6 -/* Wrap an IPv4 address into IPv6 space. Not thread-safe... */ -char *ipv6_wrap( char *src ) -{ - static char dst[64]; - int i; - - for( i = 0; src[i]; i ++ ) - if( ( src[i] < '0' || src[i] > '9' ) && src[i] != '.' ) - break; - - /* Hmm, it's not even an IP... */ - if( src[i] ) - return src; - - g_snprintf( dst, sizeof( dst ), "::ffff:%s", src ); - - return dst; -} - -/* Unwrap an IPv4 address into IPv6 space. Thread-safe, because it's very simple. :-) */ -char *ipv6_unwrap( char *src ) -{ - int i; - - if( g_strncasecmp( src, "::ffff:", 7 ) != 0 ) - return src; - - for( i = 7; src[i]; i ++ ) - if( ( src[i] < '0' || src[i] > '9' ) && src[i] != '.' ) - break; - - /* Hmm, it's not even an IP... */ - if( src[i] ) - return src; - - return ( src + 7 ); -} -#endif - /* Convert from one charset to another. from_cs, to_cs: Source and destination charsets -- cgit v1.2.3 From d52111a7b05657e4a4fa8417e6655389a50769cf Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Wed, 12 Dec 2007 21:36:33 +0000 Subject: Fixed sockerr_again() usage in Jabber module to (hopefully) fix a 100% CPU usage bug. --- lib/misc.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'lib/misc.c') diff --git a/lib/misc.c b/lib/misc.c index c977029f..d6795ec9 100644 --- a/lib/misc.c +++ b/lib/misc.c @@ -44,6 +44,8 @@ #include #endif +#include "ssl_client.h" + void strip_linefeed(gchar *text) { int i, j; @@ -590,3 +592,11 @@ char *word_wrap( char *msg, int line_len ) return g_string_free( ret, FALSE ); } + +gboolean ssl_sockerr_again( void *ssl ) +{ + if( ssl ) + return ssl_errno == SSL_AGAIN; + else + return sockerr_again(); +} -- cgit v1.2.3 From e64de00bf2d99962182243983e8c09decaa36eb4 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 12 Jan 2008 00:24:46 +0000 Subject: Killed info_string_append() and now showing the IP address of ICQ users in the "info" command response. --- lib/misc.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'lib/misc.c') diff --git a/lib/misc.c b/lib/misc.c index d6795ec9..c2dd966e 100644 --- a/lib/misc.c +++ b/lib/misc.c @@ -244,12 +244,6 @@ char *escape_html( const char *html ) return( str ); } -void info_string_append(GString *str, char *newline, char *name, char *value) -{ - if( value && value[0] ) - g_string_sprintfa( str, "%s%s: %s", newline, name, value ); -} - /* Decode%20a%20file%20name */ void http_decode( char *s ) { -- cgit v1.2.3 From 613cc5583465b2fa35288a2f28d0e408904c4fd9 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Thu, 24 Jan 2008 22:22:46 +0000 Subject: Fixed two valgrind warnings (partially uninitialized "struct tm" vars.) --- lib/misc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/misc.c') diff --git a/lib/misc.c b/lib/misc.c index c2dd966e..18d98f9e 100644 --- a/lib/misc.c +++ b/lib/misc.c @@ -89,12 +89,14 @@ time_t get_time(int year, int month, int day, int hour, int min, int sec) { struct tm tm; + memset(&tm, 0, sizeof(struct tm)); tm.tm_year = year - 1900; tm.tm_mon = month - 1; tm.tm_mday = day; tm.tm_hour = hour; tm.tm_min = min; tm.tm_sec = sec >= 0 ? sec : time(NULL) % 60; + return mktime(&tm); } -- cgit v1.2.3 From 4e8db1c0141f74dc6156a57739613483344b358d Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 16 Mar 2008 16:03:52 +0000 Subject: Moved password hash verification to md5_verify_password() so this can be reused for IRC/OPER passwords (to have encrypted in bitlbee.conf). --- lib/misc.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'lib/misc.c') diff --git a/lib/misc.c b/lib/misc.c index 18d98f9e..ccf208b5 100644 --- a/lib/misc.c +++ b/lib/misc.c @@ -32,6 +32,7 @@ #define BITLBEE_CORE #include "nogaim.h" +#include "base64.h" #include #include #include @@ -596,3 +597,43 @@ gboolean ssl_sockerr_again( void *ssl ) else return sockerr_again(); } + +/* Returns values: -1 == Failure (base64-decoded to something unexpected) + 0 == Okay + 1 == Password doesn't match the hash. */ +int md5_verify_password( char *password, char *hash ) +{ + md5_byte_t *pass_dec = NULL; + md5_byte_t pass_md5[16]; + md5_state_t md5_state; + int ret, i; + + if( base64_decode( hash, &pass_dec ) != 21 ) + { + ret = -1; + } + else + { + md5_init( &md5_state ); + md5_append( &md5_state, (md5_byte_t*) password, strlen( password ) ); + md5_append( &md5_state, (md5_byte_t*) pass_dec + 16, 5 ); /* Hmmm, salt! */ + md5_finish( &md5_state, pass_md5 ); + + for( i = 0; i < 16; i ++ ) + { + if( pass_dec[i] != pass_md5[i] ) + { + ret = 1; + break; + } + } + + /* If we reached the end of the loop, it was a match! */ + if( i == 16 ) + ret = 0; + } + + g_free( pass_dec ); + + return ret; +} -- cgit v1.2.3