diff options
Diffstat (limited to 'lib/misc.c')
-rw-r--r-- | lib/misc.c | 104 |
1 files changed, 96 insertions, 8 deletions
@@ -78,6 +78,41 @@ time_t get_time(int year, int month, int day, int hour, int min, int sec) return mktime(&tm); } +time_t mktime_utc( struct tm *tp ) +{ + struct tm utc; + time_t res, tres; + + tp->tm_isdst = -1; + 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 ); + utc.tm_isdst = -1; + 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 ); + 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 { char code[7]; @@ -118,11 +153,11 @@ static const htmlentity_t ent[] = void strip_html( char *in ) { char *start = in; - char *out = g_malloc( strlen( in ) + 1 ); + char out[strlen(in)+1]; char *s = out, *cs; int i, matched; - memset( out, 0, strlen( in ) + 1 ); + memset( out, 0, sizeof( out ) ); while( *in ) { @@ -184,7 +219,6 @@ void strip_html( char *in ) } strcpy( start, out ); - g_free( out ); } char *escape_html( const char *html ) @@ -269,15 +303,18 @@ void http_encode( char *s ) strcpy( t, s ); for( i = j = 0; t[i]; i ++, j ++ ) { - /* if( t[i] <= ' ' || ((unsigned char *)t)[i] >= 128 || t[i] == '%' ) */ - if( !isalnum( 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; @@ -610,3 +647,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; +} |