aboutsummaryrefslogtreecommitdiffstats
path: root/lib/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/misc.c')
-rw-r--r--lib/misc.c147
1 files changed, 111 insertions, 36 deletions
diff --git a/lib/misc.c b/lib/misc.c
index 9f8e496d..c37996fc 100644
--- a/lib/misc.c
+++ b/lib/misc.c
@@ -173,7 +173,7 @@ void strip_html( char *in )
while( *in && *in != '>' )
in ++;
- taglen = in-cs-1; /* not <0 because the above loop runs at least once */
+ taglen = in - cs - 1; /* not <0 because the above loop runs at least once */
if( *in )
{
if( g_strncasecmp( cs+1, "b", taglen) == 0 )
@@ -184,7 +184,7 @@ void strip_html( char *in )
*(s++) = '\x1f';
else if( g_strncasecmp( cs+1, "/i", taglen) == 0 )
*(s++) = '\x1f';
- else if( g_strncasecmp( cs+1, "br", 2) == 0 )
+ else if( g_strncasecmp( cs+1, "br", taglen) == 0 )
*(s++) = '\n';
in ++;
}
@@ -314,14 +314,18 @@ void http_encode( char *s )
for( i = j = 0; t[i]; i ++, j ++ )
{
- if( !isalnum( t[i] ) && !strchr( "._-~", t[i] ) )
+ /* Warning: 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] ) )
{
- sprintf( s + j, "%%%02X", ((unsigned char*)t)[i] );
- j += 2;
+ s[j] = t[i];
}
else
{
- s[j] = t[i];
+ sprintf( s + j, "%%%02X", ((unsigned char*)t)[i] );
+ j += 2;
}
}
s[j] = 0;
@@ -513,16 +517,17 @@ int bool2int( char *value )
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 *reply = NULL;
+ struct ns_srv_reply **replies = NULL;
#ifdef HAVE_RESOLV_A
+ struct ns_srv_reply *reply = NULL;
char name[1024];
unsigned char querybuf[1024];
const unsigned char *buf;
ns_msg nsh;
ns_rr rr;
- int i, len, size;
+ int i, n, len, size;
g_snprintf( name, sizeof( name ), "_%s._%s.%s", service, protocol, domain );
@@ -532,37 +537,56 @@ struct ns_srv_reply *srv_lookup( char *service, char *protocol, char *domain )
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 )
+ n = 0;
+ while( ns_parserr( &nsh, ns_s_an, n, &rr ) == 0 )
{
- g_free( reply );
- 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 )
+ break;
+
+ 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 );
+ break;
+ }
+
+ 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;
}
-
- reply->prio = ( buf[0] << 8 ) | buf[1];
- reply->weight = ( buf[2] << 8 ) | buf[3];
- reply->port = ( buf[4] << 8 ) | buf[5];
+ if( replies )
+ replies[n] = NULL;
#endif
- return reply;
+ return replies;
+}
+
+void srv_free( struct ns_srv_reply **srv )
+{
+ int i;
+
+ if( srv == NULL )
+ return;
+
+ 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. */
@@ -656,3 +680,54 @@ int md5_verify_password( char *password, char *hash )
return ret;
}
+
+/* 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 )
+{
+ static char *cmd[IRC_MAX_ARGS+1];
+ char *s, q = 0;
+ int k;
+
+ memset( cmd, 0, sizeof( cmd ) );
+ cmd[0] = command;
+ k = 1;
+ for( s = command; *s && k < IRC_MAX_ARGS; s ++ )
+ if( *s == ' ' && !q )
+ {
+ *s = 0;
+ while( *++s == ' ' );
+ if( *s == '"' || *s == '\'' )
+ {
+ q = *s;
+ s ++;
+ }
+ if( *s )
+ {
+ cmd[k++] = s;
+ s --;
+ }
+ else
+ {
+ break;
+ }
+ }
+ else if( *s == '\\' && ( ( !q && s[1] ) || ( q && q == s[1] ) ) )
+ {
+ char *cpy;
+
+ for( cpy = s; *cpy; cpy ++ )
+ cpy[0] = cpy[1];
+ }
+ else if( *s == q )
+ {
+ q = *s = 0;
+ }
+
+ /* Full zero-padding for easier argc checking. */
+ while( k <= IRC_MAX_ARGS )
+ cmd[k++] = NULL;
+
+ return cmd;
+}