diff options
Diffstat (limited to 'lib/misc.c')
| -rw-r--r-- | lib/misc.c | 692 | 
1 files changed, 354 insertions, 338 deletions
| @@ -1,4 +1,4 @@ -  /********************************************************************\ +/********************************************************************\    * BitlBee -- An IRC to other IM-networks gateway                     *    *                                                                    *    * Copyright 2002-2012 Wilmer van der Gaast and others                * @@ -54,9 +54,11 @@ 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') +	for (i = 0, j = 0; text[i]; i++) { +		if (text[i] != '\r') {  			text2[j++] = text[i]; +		} +	}  	text2[j] = '\0';  	strcpy(text, text2); @@ -74,47 +76,47 @@ time_t get_time(int year, int month, int day, int hour, int min, int sec)  	tm.tm_hour = hour;  	tm.tm_min = min;  	tm.tm_sec = sec >= 0 ? sec : time(NULL) % 60; -	 +  	return mktime(&tm);  } -time_t mktime_utc( struct tm *tp ) +time_t mktime_utc(struct tm *tp)  {  	struct tm utc;  	time_t res, tres; -	 +  	tp->tm_isdst = -1; -	res = mktime( tp ); +	res = mktime(tp);  	/* Problem is, mktime() just gave us the GMT timestamp for the  	   given local time... While the given time WAS NOT local. So  	   we should fix this now. -	    +  	   Now I could choose between messing with environment variables  	   (kludgy) or using timegm() (not portable)... Or doing the  	   following, which I actually prefer... -	    +  	   tzset() may also work but in other places I actually want to  	   use local time. -	    +  	   FFFFFFFFFFFFFFFFFFFFFUUUUUUUUUUUUUUUUUUUU!! */ -	gmtime_r( &res, &utc ); +	gmtime_r(&res, &utc);  	utc.tm_isdst = -1; -	if( utc.tm_hour == tp->tm_hour && utc.tm_min == tp->tm_min ) +	if (utc.tm_hour == tp->tm_hour && utc.tm_min == tp->tm_min) {  		/* Sweet! We're in UTC right now... */  		return res; -	 -	tres = mktime( &utc ); +	} + +	tres = mktime(&utc);  	res += res - tres; -	 +  	/* Yes, this is a hack. And it will go wrong around DST changes.  	   BUT this is more likely to be threadsafe than messing with  	   environment variables, and possibly more portable... */ -	 +  	return res;  } -typedef struct htmlentity -{ +typedef struct htmlentity {  	char code[7];  	char is[3];  } htmlentity_t; @@ -150,322 +152,330 @@ static const htmlentity_t ent[] =  	{ "",        ""  }  }; -void strip_html( char *in ) +void strip_html(char *in)  {  	char *start = in; -	char out[strlen(in)+1]; +	char out[strlen(in) + 1];  	char *s = out, *cs;  	int i, matched;  	int taglen; -	 -	memset( out, 0, sizeof( out ) ); -	 -	while( *in ) -	{ -		if( *in == '<' && ( g_ascii_isalpha( *(in+1) ) || *(in+1) == '/' ) ) -		{ + +	memset(out, 0, sizeof(out)); + +	while (*in) { +		if (*in == '<' && (g_ascii_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 ++; -			 + +			while (*in && *in != '>') { +				in++; +			} +  			taglen = in - cs - 1;   /* not <0 because the above loop runs at least once */ -			if( *in ) -			{ -				if( g_strncasecmp( cs+1, "b", taglen) == 0 ) +			if (*in) { +				if (g_strncasecmp(cs + 1, "b", taglen) == 0) {  					*(s++) = '\x02'; -				else if( g_strncasecmp( cs+1, "/b", taglen) == 0 ) +				} else if (g_strncasecmp(cs + 1, "/b", taglen) == 0) {  					*(s++) = '\x02'; -				else if( g_strncasecmp( cs+1, "i", taglen) == 0 ) +				} else if (g_strncasecmp(cs + 1, "i", taglen) == 0) {  					*(s++) = '\x1f'; -				else if( g_strncasecmp( cs+1, "/i", taglen) == 0 ) +				} else if (g_strncasecmp(cs + 1, "/i", taglen) == 0) {  					*(s++) = '\x1f'; -				else if( g_strncasecmp( cs+1, "br", taglen) == 0 ) +				} else if (g_strncasecmp(cs + 1, "br", taglen) == 0) {  					*(s++) = '\n'; -				in ++; -			} -			else -			{ +				} +				in++; +			} else {  				in = cs;  				*(s++) = *(in++);  			} -		} -		else if( *in == '&' ) -		{ +		} else if (*in == '&') {  			cs = ++in; -			while( *in && g_ascii_isalpha( *in ) ) -				in ++; -			 -			if( *in == ';' ) in ++; +			while (*in && g_ascii_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 ) -				{ + +			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 ++ ) + +					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 ) -			{ +			if (!matched) {  				in = cs - 1;  				*(s++) = *(in++);  			} -		} -		else -		{ +		} else {  			*(s++) = *(in++);  		}  	} -	 -	strcpy( start, out ); + +	strcpy(start, out);  } -char *escape_html( const char *html ) +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 ); + +	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 ++; +		c++;  	} -	 +  	str = ret->str; -	g_string_free( ret, FALSE ); -	return( str ); +	g_string_free(ret, FALSE); +	return(str);  }  /* Decode%20a%20file%20name						*/ -void http_decode( char *s ) +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 = 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 -			{ +			} else {  				*t = 0;  				break;  			} -		} -		else -		{ +		} else {  			t[j] = s[i];  		}  	}  	t[j] = 0; -	 -	strcpy( s, t ); -	g_free( t ); + +	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 ) +void http_encode(char *s)  { -	char t[strlen(s)+1]; +	char t[strlen(s) + 1];  	int i, j; -	 -	strcpy( t, s ); -	for( i = j = 0; t[i]; i ++, j ++ ) -	{ + +	strcpy(t, s); +	for (i = j = 0; t[i]; i++, j++) {  		/* Warning: g_ascii_isalnum() is locale-aware, so don't use it here! */ -		if( ( t[i] >= 'A' && t[i] <= 'Z' ) || -		    ( t[i] >= 'a' && t[i] <= 'z' ) || -		    ( t[i] >= '0' && t[i] <= '9' ) || -		    strchr( "._-~", t[i] ) ) -		{ +		if ((t[i] >= 'A' && t[i] <= 'Z') || +		    (t[i] >= 'a' && t[i] <= 'z') || +		    (t[i] >= '0' && t[i] <= '9') || +		    strchr("._-~", t[i])) {  			s[j] = t[i]; -		} -		else -		{ -			sprintf( s + j, "%%%02X", ((unsigned char*)t)[i] ); +		} else { +			sprintf(s + j, "%%%02X", ((unsigned char *) t)[i]);  			j += 2;  		}  	}  	s[j] = 0;  } -/* Strip newlines from a string. Modifies the string passed to it. */  -char *strip_newlines( char *source ) +/* Strip newlines from a string. Modifies the string passed to it. */ +char *strip_newlines(char *source)  { -	int i;	 +	int i; -	for( i = 0; source[i] != '\0'; i ++ ) -		if( source[i] == '\n' || source[i] == '\r' ) +	for (i = 0; source[i] != '\0'; i++) { +		if (source[i] == '\n' || source[i] == '\r') {  			source[i] = ' '; -	 +		} +	} +  	return source;  }  /* Wrap an IPv4 address into IPv6 space. Not thread-safe... */ -char *ipv6_wrap( char *src ) +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] != '.' ) + +	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] ) +	if (src[i]) {  		return src; -	 -	g_snprintf( dst, sizeof( dst ), "::ffff:%s", 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 ) +char *ipv6_unwrap(char *src)  {  	int i; -	 -	if( g_strncasecmp( src, "::ffff:", 7 ) != 0 ) + +	if (g_strncasecmp(src, "::ffff:", 7) != 0) {  		return src; -	 -	for( i = 7; src[i]; i ++ ) -		if( ( src[i] < '0' || src[i] > '9' ) && src[i] != '.' ) +	} + +	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] ) +	if (src[i]) {  		return src; -	 -	return ( src + 7 ); +	} + +	return (src + 7);  }  /* 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 ) +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 ) + +	cd = g_iconv_open(to_cs, from_cs); +	if (cd == (GIConv) - 1) {  		return -1; -	 -	inbytesleft = size ? size : strlen( src ); +	} + +	inbytesleft = size ? size : strlen(src);  	outbytesleft = maxbuf - 1; -	res = g_iconv( cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft ); +	res = g_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);  	*outbuf = '\0'; -	g_iconv_close( cd ); -	 -	if( res != 0 ) +	g_iconv_close(cd); + +	if (res != 0) {  		return -1; -	else +	} else {  		return outbuf - dst; +	}  }  /* A wrapper for /dev/urandom.   * If /dev/urandom is not present or not usable, it calls abort()   * to prevent bitlbee from working without a decent entropy source */ -void random_bytes( unsigned char *buf, int count ) +void random_bytes(unsigned char *buf, int count)  {  	int fd; -	if( ( ( fd = open( "/dev/urandom", O_RDONLY ) ) == -1 ) || -	    ( read( fd, buf, count ) == -1 ) ) -	{ -		log_message( LOGLVL_ERROR, "/dev/urandom not present - aborting" ); + +	if (((fd = open("/dev/urandom", O_RDONLY)) == -1) || +	    (read(fd, buf, count) == -1)) { +		log_message(LOGLVL_ERROR, "/dev/urandom not present - aborting");  		abort();  	} -	close( fd ); +	close(fd);  } -int is_bool( char *value ) +int is_bool(char *value)  { -	if( *value == 0 ) +	if (*value == 0) {  		return 0; -	 -	if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 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 ) ) +	} +	if ((g_strcasecmp(value, +	                  "false") == 0) || (g_strcasecmp(value, "no") == 0) || (g_strcasecmp(value, "off") == 0)) {  		return 1; -	 -	while( *value ) -		if( !g_ascii_isdigit( *value ) ) +	} + +	while (*value) { +		if (!g_ascii_isdigit(*value)) {  			return 0; -		else -			value ++; -	 +		} else { +			value++; +		} +	} +  	return 1;  } -int bool2int( char *value ) +int bool2int(char *value)  {  	int i; -	 -	if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 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 ) ) +	} +	if ((g_strcasecmp(value, +	                  "false") == 0) || (g_strcasecmp(value, "no") == 0) || (g_strcasecmp(value, "off") == 0)) {  		return 0; -	 -	if( sscanf( value, "%d", &i ) == 1 ) +	} + +	if (sscanf(value, "%d", &i) == 1) {  		return i; -	 +	} +  	return 0;  } -struct ns_srv_reply **srv_lookup( char *service, char *protocol, char *domain ) -{	 +struct ns_srv_reply **srv_lookup(char *service, char *protocol, char *domain) +{  	struct ns_srv_reply **replies = NULL; +  #ifdef HAVE_RESOLV_A  	struct ns_srv_reply *reply = NULL;  	char name[1024]; @@ -474,148 +484,148 @@ struct ns_srv_reply **srv_lookup( char *service, char *protocol, char *domain )  	ns_msg nsh;  	ns_rr rr;  	int n, 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 ) + +	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 ) +	} + +	if (ns_initparse(querybuf, size, &nsh) != 0) {  		return NULL; -	 +	} +  	n = 0; -	while( ns_parserr( &nsh, ns_s_an, n, &rr ) == 0 ) -	{ +	while (ns_parserr(&nsh, ns_s_an, n, &rr) == 0) {  		char name[NS_MAXDNAME]; -		if( ns_rr_rdlen( rr ) < 7) -		    break; +		if (ns_rr_rdlen(rr) < 7) { +			break; +		} -		buf = ns_rr_rdata( rr ); -		 -		if( dn_expand(querybuf, querybuf + size, &buf[6], name, NS_MAXDNAME) == -1 ) +		buf = ns_rr_rdata(rr); + +		if (dn_expand(querybuf, querybuf + size, &buf[6], name, NS_MAXDNAME) == -1) {  			break; +		}  		len = strlen(name) + 1; -		 -		reply = g_malloc( sizeof( struct ns_srv_reply ) + len ); -		memcpy( reply->name, name, len ); -		 -		reply->prio = ( buf[0] << 8 ) | buf[1]; -		reply->weight = ( buf[2] << 8 ) | buf[3]; -		reply->port = ( buf[4] << 8 ) | buf[5]; -		 -		n ++; -		replies = g_renew( struct ns_srv_reply *, replies, n + 1 ); -		replies[n-1] = reply; -	} -	if( replies ) + +		reply = g_malloc(sizeof(struct ns_srv_reply) + len); +		memcpy(reply->name, name, len); + +		reply->prio = (buf[0] << 8) | buf[1]; +		reply->weight = (buf[2] << 8) | buf[3]; +		reply->port = (buf[4] << 8) | buf[5]; + +		n++; +		replies = g_renew(struct ns_srv_reply *, replies, n + 1); +		replies[n - 1] = reply; +	} +	if (replies) {  		replies[n] = NULL; +	}  #endif -	 +  	return replies;  } -void srv_free( struct ns_srv_reply **srv ) +void srv_free(struct ns_srv_reply **srv)  {  	int i; -	 -	if( srv == NULL ) + +	if (srv == NULL) {  		return; -	 -	for( i = 0; srv[i]; i ++ ) -		g_free( srv[i] ); -	g_free( srv ); +	} + +	for (i = 0; srv[i]; i++) { +		g_free(srv[i]); +	} +	g_free(srv);  }  /* Word wrapping. Yes, I know this isn't UTF-8 clean. I'm willing to take the risk. */ -char *word_wrap( const char *msg, int line_len ) +char *word_wrap(const char *msg, int line_len)  { -	GString *ret = g_string_sized_new( strlen( msg ) + 16 ); -	 -	while( strlen( msg ) > 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 ); +		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' ); + +		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' ); +			} 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' ); +		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 ); +	g_string_append(ret, msg); + +	return g_string_free(ret, FALSE);  } -gboolean ssl_sockerr_again( void *ssl ) +gboolean ssl_sockerr_again(void *ssl)  { -	if( ssl ) +	if (ssl) {  		return ssl_errno == SSL_AGAIN; -	else +	} 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 ) +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 = -1, i; -	 -	if( base64_decode( hash, &pass_dec ) == 21 ) -	{ -		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] ) -			{ + +	if (base64_decode(hash, &pass_dec) == 21) { +		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 ) +		if (i == 16) {  			ret = 0; +		}  	} -	 -	g_free( pass_dec ); + +	g_free(pass_dec);  	return ret;  } @@ -623,119 +633,125 @@ int md5_verify_password( char *password, char *hash )  /* Split commands (root-style, *not* IRC-style). Handles "quoting of"     white\ space in 'various ways'. Returns a NULL-terminated static     char** so watch out with nested use! Definitely not thread-safe. */ -char **split_command_parts( char *command, int limit ) +char **split_command_parts(char *command, int limit)  { -	static char *cmd[IRC_MAX_ARGS+1]; +	static char *cmd[IRC_MAX_ARGS + 1];  	char *s, q = 0;  	int k; -	 -	memset( cmd, 0, sizeof( cmd ) ); + +	memset(cmd, 0, sizeof(cmd));  	cmd[0] = command;  	k = 1; -	for( s = command; *s && k < IRC_MAX_ARGS; s ++ ) -	{ -		if( *s == ' ' && !q ) -		{ +	for (s = command; *s && k < IRC_MAX_ARGS; s++) { +		if (*s == ' ' && !q) {  			*s = 0; -			while( *++s == ' ' ); -			if( k != limit && (*s == '"' || *s == '\'') ) -			{ +			while (*++s == ' ') { +				; +			} +			if (k != limit && (*s == '"' || *s == '\'')) {  				q = *s; -				s ++; +				s++;  			} -			if( *s ) -			{ +			if (*s) {  				cmd[k++] = s;  				if (limit && k > limit) {  					break;  				} -				s --; -			} -			else -			{ +				s--; +			} else {  				break;  			} -		} -		else if( *s == '\\' && ( ( !q && s[1] ) || ( q && q == s[1] ) ) ) -		{ +		} else if (*s == '\\' && ((!q && s[1]) || (q && q == s[1]))) {  			char *cpy; -			 -			for( cpy = s; *cpy; cpy ++ ) + +			for (cpy = s; *cpy; cpy++) {  				cpy[0] = cpy[1]; -		} -		else if( *s == q ) -		{ +			} +		} else if (*s == q) {  			q = *s = 0;  		}  	} -	 +  	/* Full zero-padding for easier argc checking. */ -	while( k <= IRC_MAX_ARGS ) +	while (k <= IRC_MAX_ARGS) {  		cmd[k++] = NULL; -	 +	} +  	return cmd;  } -char *get_rfc822_header( const char *text, const char *header, int len ) +char *get_rfc822_header(const char *text, const char *header, int len)  { -	int hlen = strlen( header ), i; +	int hlen = strlen(header), i;  	const char *ret; -	 -	if( text == NULL ) + +	if (text == NULL) {  		return NULL; -	 -	if( len == 0 ) -		len = strlen( text ); -	 +	} + +	if (len == 0) { +		len = strlen(text); +	} +  	i = 0; -	while( ( i + hlen ) < len ) -	{ +	while ((i + hlen) < len) {  		/* Maybe this is a bit over-commented, but I just hate this part... */ -		if( g_strncasecmp( text + i, header, hlen ) == 0 ) -		{ +		if (g_strncasecmp(text + i, header, hlen) == 0) {  			/* Skip to the (probable) end of the header */  			i += hlen; -			 +  			/* Find the first non-[: \t] character */ -			while( i < len && ( text[i] == ':' || text[i] == ' ' || text[i] == '\t' ) ) i ++; -			 +			while (i < len && (text[i] == ':' || text[i] == ' ' || text[i] == '\t')) { +				i++; +			} +  			/* Make sure we're still inside the string */ -			if( i >= len ) return( NULL ); -			 +			if (i >= len) { +				return(NULL); +			} +  			/* Save the position */  			ret = text + i; -			 +  			/* Search for the end of this line */ -			while( i < len && text[i] != '\r' && text[i] != '\n' ) i ++; -			 +			while (i < len && text[i] != '\r' && text[i] != '\n') { +				i++; +			} +  			/* Make sure we're still inside the string */ -			if( i >= len ) return( NULL ); -			 +			if (i >= len) { +				return(NULL); +			} +  			/* Copy the found data */ -			return( g_strndup( ret, text + i - ret ) ); +			return(g_strndup(ret, text + i - ret));  		} -		 +  		/* This wasn't the header we were looking for, skip to the next line. */ -		while( i < len && ( text[i] != '\r' && text[i] != '\n' ) ) i ++; -		while( i < len && ( text[i] == '\r' || text[i] == '\n' ) ) i ++; -		 +		while (i < len && (text[i] != '\r' && text[i] != '\n')) { +			i++; +		} +		while (i < len && (text[i] == '\r' || text[i] == '\n')) { +			i++; +		} +  		/* End of headers? */ -		if( ( i >= 4 && strncmp( text + i - 4, "\r\n\r\n", 4 ) == 0 ) || -		    ( i >= 2 && ( strncmp( text + i - 2, "\n\n", 2 ) == 0 ||    -		                  strncmp( text + i - 2, "\r\r", 2 ) == 0 ) ) ) -		{ +		if ((i >= 4 && strncmp(text + i - 4, "\r\n\r\n", 4) == 0) || +		    (i >= 2 && (strncmp(text + i - 2, "\n\n", 2) == 0 || +		                strncmp(text + i - 2, "\r\r", 2) == 0))) {  			break;  		}  	} -	 +  	return NULL;  }  /* Takes a string, truncates it where it's safe, returns the new length */ -int truncate_utf8( char *string, int maxlen ) +int truncate_utf8(char *string, int maxlen)  {  	char *end; -	g_utf8_validate( (const gchar *) string, maxlen, (const gchar **) &end ); + +	g_utf8_validate((const gchar *) string, maxlen, (const gchar **) &end);  	*end = '\0';  	return end - string;  } | 
