Changeset 5ebff60 for lib/misc.c
- Timestamp:
- 2015-02-20T22:50:54Z (9 years ago)
- Branches:
- master
- Children:
- 0b9daac, 3d45471, 7733b8c
- Parents:
- af359b4
- git-author:
- Indent <please@…> (19-02-15 05:47:20)
- git-committer:
- dequis <dx@…> (20-02-15 22:50:54)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lib/misc.c
raf359b4 r5ebff60 1 1 /********************************************************************\ 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * … … 55 55 gchar *text2 = g_malloc(strlen(text) + 1); 56 56 57 for (i = 0, j = 0; text[i]; i++) 58 if (text[i] != '\r') 57 for (i = 0, j = 0; text[i]; i++) { 58 if (text[i] != '\r') { 59 59 text2[j++] = text[i]; 60 } 61 } 60 62 text2[j] = '\0'; 61 63 … … 75 77 tm.tm_min = min; 76 78 tm.tm_sec = sec >= 0 ? sec : time(NULL) % 60; 77 79 78 80 return mktime(&tm); 79 81 } 80 82 81 time_t mktime_utc( struct tm *tp)83 time_t mktime_utc(struct tm *tp) 82 84 { 83 85 struct tm utc; 84 86 time_t res, tres; 85 87 86 88 tp->tm_isdst = -1; 87 res = mktime( tp);89 res = mktime(tp); 88 90 /* Problem is, mktime() just gave us the GMT timestamp for the 89 91 given local time... While the given time WAS NOT local. So 90 92 we should fix this now. 91 93 92 94 Now I could choose between messing with environment variables 93 95 (kludgy) or using timegm() (not portable)... Or doing the 94 96 following, which I actually prefer... 95 97 96 98 tzset() may also work but in other places I actually want to 97 99 use local time. 98 100 99 101 FFFFFFFFFFFFFFFFFFFFFUUUUUUUUUUUUUUUUUUUU!! */ 100 gmtime_r( &res, &utc);102 gmtime_r(&res, &utc); 101 103 utc.tm_isdst = -1; 102 if ( utc.tm_hour == tp->tm_hour && utc.tm_min == tp->tm_min )104 if (utc.tm_hour == tp->tm_hour && utc.tm_min == tp->tm_min) { 103 105 /* Sweet! We're in UTC right now... */ 104 106 return res; 105 106 tres = mktime( &utc ); 107 } 108 109 tres = mktime(&utc); 107 110 res += res - tres; 108 111 109 112 /* Yes, this is a hack. And it will go wrong around DST changes. 110 113 BUT this is more likely to be threadsafe than messing with 111 114 environment variables, and possibly more portable... */ 112 115 113 116 return res; 114 117 } 115 118 116 typedef struct htmlentity 117 { 119 typedef struct htmlentity { 118 120 char code[7]; 119 121 char is[3]; … … 151 153 }; 152 154 153 void strip_html( char *in)155 void strip_html(char *in) 154 156 { 155 157 char *start = in; 156 char out[strlen(in) +1];158 char out[strlen(in) + 1]; 157 159 char *s = out, *cs; 158 160 int i, matched; 159 161 int taglen; 160 161 memset( out, 0, sizeof( out ) ); 162 163 while( *in ) 164 { 165 if( *in == '<' && ( g_ascii_isalpha( *(in+1) ) || *(in+1) == '/' ) ) 166 { 162 163 memset(out, 0, sizeof(out)); 164 165 while (*in) { 166 if (*in == '<' && (g_ascii_isalpha(*(in + 1)) || *(in + 1) == '/')) { 167 167 /* If in points at a < and in+1 points at a letter or a slash, this is probably 168 168 a HTML-tag. Try to find a closing > and continue there. If the > can't be 169 169 found, assume that it wasn't a HTML-tag after all. */ 170 170 171 171 cs = in; 172 173 while( *in && *in != '>' ) 174 in ++; 175 172 173 while (*in && *in != '>') { 174 in++; 175 } 176 176 177 taglen = in - cs - 1; /* not <0 because the above loop runs at least once */ 177 if( *in ) 178 { 179 if( g_strncasecmp( cs+1, "b", taglen) == 0 ) 178 if (*in) { 179 if (g_strncasecmp(cs + 1, "b", taglen) == 0) { 180 180 *(s++) = '\x02'; 181 else if( g_strncasecmp( cs+1, "/b", taglen) == 0 )181 } else if (g_strncasecmp(cs + 1, "/b", taglen) == 0) { 182 182 *(s++) = '\x02'; 183 else if( g_strncasecmp( cs+1, "i", taglen) == 0 )183 } else if (g_strncasecmp(cs + 1, "i", taglen) == 0) { 184 184 *(s++) = '\x1f'; 185 else if( g_strncasecmp( cs+1, "/i", taglen) == 0 )185 } else if (g_strncasecmp(cs + 1, "/i", taglen) == 0) { 186 186 *(s++) = '\x1f'; 187 else if( g_strncasecmp( cs+1, "br", taglen) == 0 )187 } else if (g_strncasecmp(cs + 1, "br", taglen) == 0) { 188 188 *(s++) = '\n'; 189 in ++; 190 } 191 else 192 { 189 } 190 in++; 191 } else { 193 192 in = cs; 194 193 *(s++) = *(in++); 195 194 } 196 } 197 else if( *in == '&' ) 198 { 195 } else if (*in == '&') { 199 196 cs = ++in; 200 while( *in && g_ascii_isalpha( *in ) ) 201 in ++; 202 203 if( *in == ';' ) in ++; 197 while (*in && g_ascii_isalpha(*in)) { 198 in++; 199 } 200 201 if (*in == ';') { 202 in++; 203 } 204 204 matched = 0; 205 206 for( i = 0; *ent[i].code; i ++ ) 207 if( g_strncasecmp( ent[i].code, cs, strlen( ent[i].code ) ) == 0 ) 208 { 205 206 for (i = 0; *ent[i].code; i++) { 207 if (g_strncasecmp(ent[i].code, cs, strlen(ent[i].code)) == 0) { 209 208 int j; 210 211 for ( j = 0; ent[i].is[j]; j ++ )209 210 for (j = 0; ent[i].is[j]; j++) { 212 211 *(s++) = ent[i].is[j]; 213 212 } 213 214 214 matched = 1; 215 215 break; 216 216 } 217 } 217 218 218 219 /* None of the entities were matched, so return the string */ 219 if( !matched ) 220 { 220 if (!matched) { 221 221 in = cs - 1; 222 222 *(s++) = *(in++); 223 223 } 224 } 225 else 226 { 224 } else { 227 225 *(s++) = *(in++); 228 226 } 229 227 } 230 231 strcpy( start, out);232 } 233 234 char *escape_html( const char *html)228 229 strcpy(start, out); 230 } 231 232 char *escape_html(const char *html) 235 233 { 236 234 const char *c = html; 237 235 GString *ret; 238 236 char *str; 239 240 if( html == NULL ) 241 return( NULL ); 242 243 ret = g_string_new( "" ); 244 245 while( *c ) 246 { 247 switch( *c ) 248 { 249 case '&': 250 ret = g_string_append( ret, "&" ); 251 break; 252 case '<': 253 ret = g_string_append( ret, "<" ); 254 break; 255 case '>': 256 ret = g_string_append( ret, ">" ); 257 break; 258 case '"': 259 ret = g_string_append( ret, """ ); 260 break; 261 default: 262 ret = g_string_append_c( ret, *c ); 263 } 264 c ++; 265 } 266 237 238 if (html == NULL) { 239 return(NULL); 240 } 241 242 ret = g_string_new(""); 243 244 while (*c) { 245 switch (*c) { 246 case '&': 247 ret = g_string_append(ret, "&"); 248 break; 249 case '<': 250 ret = g_string_append(ret, "<"); 251 break; 252 case '>': 253 ret = g_string_append(ret, ">"); 254 break; 255 case '"': 256 ret = g_string_append(ret, """); 257 break; 258 default: 259 ret = g_string_append_c(ret, *c); 260 } 261 c++; 262 } 263 267 264 str = ret->str; 268 g_string_free( ret, FALSE);269 return( str);265 g_string_free(ret, FALSE); 266 return(str); 270 267 } 271 268 272 269 /* Decode%20a%20file%20name */ 273 void http_decode( char *s)270 void http_decode(char *s) 274 271 { 275 272 char *t; 276 273 int i, j, k; 277 278 t = g_new( char, strlen( s ) + 1 ); 279 280 for( i = j = 0; s[i]; i ++, j ++ ) 281 { 282 if( s[i] == '%' ) 283 { 284 if( sscanf( s + i + 1, "%2x", &k ) ) 285 { 274 275 t = g_new(char, strlen(s) + 1); 276 277 for (i = j = 0; s[i]; i++, j++) { 278 if (s[i] == '%') { 279 if (sscanf(s + i + 1, "%2x", &k)) { 286 280 t[j] = k; 287 281 i += 2; 288 } 289 else 290 { 282 } else { 291 283 *t = 0; 292 284 break; 293 285 } 294 } 295 else 296 { 286 } else { 297 287 t[j] = s[i]; 298 288 } 299 289 } 300 290 t[j] = 0; 301 302 strcpy( s, t);303 g_free( t);291 292 strcpy(s, t); 293 g_free(t); 304 294 } 305 295 306 296 /* Warning: This one explodes the string. Worst-cases can make the string 3x its original size! */ 307 297 /* This fuction is safe, but make sure you call it safely as well! */ 308 void http_encode( char *s)309 { 310 char t[strlen(s) +1];298 void http_encode(char *s) 299 { 300 char t[strlen(s) + 1]; 311 301 int i, j; 312 313 strcpy( t, s ); 314 for( i = j = 0; t[i]; i ++, j ++ ) 315 { 302 303 strcpy(t, s); 304 for (i = j = 0; t[i]; i++, j++) { 316 305 /* Warning: g_ascii_isalnum() is locale-aware, so don't use it here! */ 317 if( ( t[i] >= 'A' && t[i] <= 'Z' ) || 318 ( t[i] >= 'a' && t[i] <= 'z' ) || 319 ( t[i] >= '0' && t[i] <= '9' ) || 320 strchr( "._-~", t[i] ) ) 321 { 306 if ((t[i] >= 'A' && t[i] <= 'Z') || 307 (t[i] >= 'a' && t[i] <= 'z') || 308 (t[i] >= '0' && t[i] <= '9') || 309 strchr("._-~", t[i])) { 322 310 s[j] = t[i]; 323 } 324 else 325 { 326 sprintf( s + j, "%%%02X", ((unsigned char*)t)[i] ); 311 } else { 312 sprintf(s + j, "%%%02X", ((unsigned char *) t)[i]); 327 313 j += 2; 328 314 } … … 331 317 } 332 318 333 /* Strip newlines from a string. Modifies the string passed to it. */ 334 char *strip_newlines( char *source)335 { 336 int i; 337 338 for ( i = 0; source[i] != '\0'; i ++ )339 if ( source[i] == '\n' || source[i] == '\r' )319 /* Strip newlines from a string. Modifies the string passed to it. */ 320 char *strip_newlines(char *source) 321 { 322 int i; 323 324 for (i = 0; source[i] != '\0'; i++) { 325 if (source[i] == '\n' || source[i] == '\r') { 340 326 source[i] = ' '; 341 327 } 328 } 329 342 330 return source; 343 331 } 344 332 345 333 /* Wrap an IPv4 address into IPv6 space. Not thread-safe... */ 346 char *ipv6_wrap( char *src)334 char *ipv6_wrap(char *src) 347 335 { 348 336 static char dst[64]; 349 337 int i; 350 351 for( i = 0; src[i]; i ++ ) 352 if( ( src[i] < '0' || src[i] > '9' ) && src[i] != '.' ) 353 break; 354 338 339 for (i = 0; src[i]; i++) { 340 if ((src[i] < '0' || src[i] > '9') && src[i] != '.') { 341 break; 342 } 343 } 344 355 345 /* Hmm, it's not even an IP... */ 356 if ( src[i] )346 if (src[i]) { 357 347 return src; 358 359 g_snprintf( dst, sizeof( dst ), "::ffff:%s", src ); 360 348 } 349 350 g_snprintf(dst, sizeof(dst), "::ffff:%s", src); 351 361 352 return dst; 362 353 } 363 354 364 355 /* Unwrap an IPv4 address into IPv6 space. Thread-safe, because it's very simple. :-) */ 365 char *ipv6_unwrap( char *src)356 char *ipv6_unwrap(char *src) 366 357 { 367 358 int i; 368 369 if ( g_strncasecmp( src, "::ffff:", 7 ) != 0 )359 360 if (g_strncasecmp(src, "::ffff:", 7) != 0) { 370 361 return src; 371 372 for( i = 7; src[i]; i ++ ) 373 if( ( src[i] < '0' || src[i] > '9' ) && src[i] != '.' ) 374 break; 375 362 } 363 364 for (i = 7; src[i]; i++) { 365 if ((src[i] < '0' || src[i] > '9') && src[i] != '.') { 366 break; 367 } 368 } 369 376 370 /* Hmm, it's not even an IP... */ 377 if ( src[i] )371 if (src[i]) { 378 372 return src; 379 380 return ( src + 7 ); 373 } 374 375 return (src + 7); 381 376 } 382 377 383 378 /* Convert from one charset to another. 384 379 385 380 from_cs, to_cs: Source and destination charsets 386 381 src, dst: Source and destination strings 387 382 size: Size if src. 0 == use strlen(). strlen() is not reliable for UNICODE/UTF16 strings though. 388 383 maxbuf: Maximum number of bytes to write to dst 389 384 390 385 Returns the number of bytes written to maxbuf or -1 on an error. 391 386 */ 392 signed int do_iconv( char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf)387 signed int do_iconv(char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf) 393 388 { 394 389 GIConv cd; … … 397 392 char *inbuf = src; 398 393 char *outbuf = dst; 399 400 cd = g_iconv_open( to_cs, from_cs);401 if ( cd == (GIConv) -1 )394 395 cd = g_iconv_open(to_cs, from_cs); 396 if (cd == (GIConv) - 1) { 402 397 return -1; 403 404 inbytesleft = size ? size : strlen( src ); 398 } 399 400 inbytesleft = size ? size : strlen(src); 405 401 outbytesleft = maxbuf - 1; 406 res = g_iconv( cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);402 res = g_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); 407 403 *outbuf = '\0'; 408 g_iconv_close( cd);409 410 if ( res != 0 )404 g_iconv_close(cd); 405 406 if (res != 0) { 411 407 return -1; 412 else408 } else { 413 409 return outbuf - dst; 410 } 414 411 } 415 412 … … 417 414 * If /dev/urandom is not present or not usable, it calls abort() 418 415 * to prevent bitlbee from working without a decent entropy source */ 419 void random_bytes( unsigned char *buf, int count)416 void random_bytes(unsigned char *buf, int count) 420 417 { 421 418 int fd; 422 if( ( ( fd = open( "/dev/urandom", O_RDONLY ) ) == -1 ) || 423 ( read( fd, buf, count ) == -1 ) )424 {425 log_message( LOGLVL_ERROR, "/dev/urandom not present - aborting");419 420 if (((fd = open("/dev/urandom", O_RDONLY)) == -1) || 421 (read(fd, buf, count) == -1)) { 422 log_message(LOGLVL_ERROR, "/dev/urandom not present - aborting"); 426 423 abort(); 427 424 } 428 425 429 close( fd);430 } 431 432 int is_bool( char *value)433 { 434 if ( *value == 0 )426 close(fd); 427 } 428 429 int is_bool(char *value) 430 { 431 if (*value == 0) { 435 432 return 0; 436 437 if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 0 ) ) 433 } 434 435 if ((g_strcasecmp(value, 436 "true") == 0) || (g_strcasecmp(value, "yes") == 0) || (g_strcasecmp(value, "on") == 0)) { 438 437 return 1; 439 if( ( g_strcasecmp( value, "false" ) == 0 ) || ( g_strcasecmp( value, "no" ) == 0 ) || ( g_strcasecmp( value, "off" ) == 0 ) ) 438 } 439 if ((g_strcasecmp(value, 440 "false") == 0) || (g_strcasecmp(value, "no") == 0) || (g_strcasecmp(value, "off") == 0)) { 440 441 return 1; 441 442 while( *value ) 443 if( !g_ascii_isdigit( *value ) ) 442 } 443 444 while (*value) { 445 if (!g_ascii_isdigit(*value)) { 444 446 return 0; 445 else 446 value ++; 447 447 } else { 448 value++; 449 } 450 } 451 448 452 return 1; 449 453 } 450 454 451 int bool2int( char *value)455 int bool2int(char *value) 452 456 { 453 457 int i; 454 455 if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 0 ) ) 458 459 if ((g_strcasecmp(value, 460 "true") == 0) || (g_strcasecmp(value, "yes") == 0) || (g_strcasecmp(value, "on") == 0)) { 456 461 return 1; 457 if( ( g_strcasecmp( value, "false" ) == 0 ) || ( g_strcasecmp( value, "no" ) == 0 ) || ( g_strcasecmp( value, "off" ) == 0 ) ) 462 } 463 if ((g_strcasecmp(value, 464 "false") == 0) || (g_strcasecmp(value, "no") == 0) || (g_strcasecmp(value, "off") == 0)) { 458 465 return 0; 459 460 if( sscanf( value, "%d", &i ) == 1 ) 466 } 467 468 if (sscanf(value, "%d", &i) == 1) { 461 469 return i; 462 470 } 471 463 472 return 0; 464 473 } 465 474 466 struct ns_srv_reply **srv_lookup( char *service, char *protocol, char *domain)467 { 475 struct ns_srv_reply **srv_lookup(char *service, char *protocol, char *domain) 476 { 468 477 struct ns_srv_reply **replies = NULL; 478 469 479 #ifdef HAVE_RESOLV_A 470 480 struct ns_srv_reply *reply = NULL; … … 475 485 ns_rr rr; 476 486 int n, len, size; 477 478 g_snprintf( name, sizeof( name ), "_%s._%s.%s", service, protocol, domain);479 480 if ( ( size = res_query( name, ns_c_in, ns_t_srv, querybuf, sizeof( querybuf ) ) ) <= 0 )487 488 g_snprintf(name, sizeof(name), "_%s._%s.%s", service, protocol, domain); 489 490 if ((size = res_query(name, ns_c_in, ns_t_srv, querybuf, sizeof(querybuf))) <= 0) { 481 491 return NULL; 482 483 if( ns_initparse( querybuf, size, &nsh ) != 0 ) 492 } 493 494 if (ns_initparse(querybuf, size, &nsh) != 0) { 484 495 return NULL; 485 496 } 497 486 498 n = 0; 487 while( ns_parserr( &nsh, ns_s_an, n, &rr ) == 0 ) 488 { 499 while (ns_parserr(&nsh, ns_s_an, n, &rr) == 0) { 489 500 char name[NS_MAXDNAME]; 490 501 491 if( ns_rr_rdlen( rr ) < 7) 492 break; 493 494 buf = ns_rr_rdata( rr ); 495 496 if( dn_expand(querybuf, querybuf + size, &buf[6], name, NS_MAXDNAME) == -1 ) 497 break; 502 if (ns_rr_rdlen(rr) < 7) { 503 break; 504 } 505 506 buf = ns_rr_rdata(rr); 507 508 if (dn_expand(querybuf, querybuf + size, &buf[6], name, NS_MAXDNAME) == -1) { 509 break; 510 } 498 511 499 512 len = strlen(name) + 1; 500 501 reply = g_malloc( sizeof( struct ns_srv_reply ) + len);502 memcpy( reply->name, name, len);503 504 reply->prio = ( buf[0] << 8) | buf[1];505 reply->weight = ( buf[2] << 8) | buf[3];506 reply->port = ( buf[4] << 8) | buf[5];507 508 n 509 replies = g_renew( struct ns_srv_reply *, replies, n + 1);510 replies[n -1] = reply;511 } 512 if ( replies )513 514 reply = g_malloc(sizeof(struct ns_srv_reply) + len); 515 memcpy(reply->name, name, len); 516 517 reply->prio = (buf[0] << 8) | buf[1]; 518 reply->weight = (buf[2] << 8) | buf[3]; 519 reply->port = (buf[4] << 8) | buf[5]; 520 521 n++; 522 replies = g_renew(struct ns_srv_reply *, replies, n + 1); 523 replies[n - 1] = reply; 524 } 525 if (replies) { 513 526 replies[n] = NULL; 527 } 514 528 #endif 515 529 516 530 return replies; 517 531 } 518 532 519 void srv_free( struct ns_srv_reply **srv)533 void srv_free(struct ns_srv_reply **srv) 520 534 { 521 535 int i; 522 523 if ( srv == NULL )536 537 if (srv == NULL) { 524 538 return; 525 526 for( i = 0; srv[i]; i ++ ) 527 g_free( srv[i] ); 528 g_free( srv ); 539 } 540 541 for (i = 0; srv[i]; i++) { 542 g_free(srv[i]); 543 } 544 g_free(srv); 529 545 } 530 546 531 547 /* Word wrapping. Yes, I know this isn't UTF-8 clean. I'm willing to take the risk. */ 532 char *word_wrap( const char *msg, int line_len ) 533 { 534 GString *ret = g_string_sized_new( strlen( msg ) + 16 ); 535 536 while( strlen( msg ) > line_len ) 537 { 548 char *word_wrap(const char *msg, int line_len) 549 { 550 GString *ret = g_string_sized_new(strlen(msg) + 16); 551 552 while (strlen(msg) > line_len) { 538 553 int i; 539 554 540 555 /* First try to find out if there's a newline already. Don't 541 556 want to add more splits than necessary. */ 542 for( i = line_len; i > 0 && msg[i] != '\n'; i -- ); 543 if( msg[i] == '\n' ) 544 { 545 g_string_append_len( ret, msg, i + 1 ); 557 for (i = line_len; i > 0 && msg[i] != '\n'; i--) { 558 ; 559 } 560 if (msg[i] == '\n') { 561 g_string_append_len(ret, msg, i + 1); 546 562 msg += i + 1; 547 563 continue; 548 564 } 549 550 for( i = line_len; i > 0; i -- ) 551 { 552 if( msg[i] == '-' ) 553 { 554 g_string_append_len( ret, msg, i + 1 ); 555 g_string_append_c( ret, '\n' ); 565 566 for (i = line_len; i > 0; i--) { 567 if (msg[i] == '-') { 568 g_string_append_len(ret, msg, i + 1); 569 g_string_append_c(ret, '\n'); 556 570 msg += i + 1; 557 571 break; 558 } 559 else if( msg[i] == ' ' ) 560 { 561 g_string_append_len( ret, msg, i ); 562 g_string_append_c( ret, '\n' ); 572 } else if (msg[i] == ' ') { 573 g_string_append_len(ret, msg, i); 574 g_string_append_c(ret, '\n'); 563 575 msg += i + 1; 564 576 break; 565 577 } 566 578 } 567 if( i == 0 ) 568 { 569 g_string_append_len( ret, msg, line_len ); 570 g_string_append_c( ret, '\n' ); 579 if (i == 0) { 580 g_string_append_len(ret, msg, line_len); 581 g_string_append_c(ret, '\n'); 571 582 msg += line_len; 572 583 } 573 584 } 574 g_string_append( ret, msg);575 576 return g_string_free( ret, FALSE);577 } 578 579 gboolean ssl_sockerr_again( void *ssl)580 { 581 if ( ssl )585 g_string_append(ret, msg); 586 587 return g_string_free(ret, FALSE); 588 } 589 590 gboolean ssl_sockerr_again(void *ssl) 591 { 592 if (ssl) { 582 593 return ssl_errno == SSL_AGAIN; 583 else594 } else { 584 595 return sockerr_again(); 596 } 585 597 } 586 598 … … 588 600 0 == Okay 589 601 1 == Password doesn't match the hash. */ 590 int md5_verify_password( char *password, char *hash)602 int md5_verify_password(char *password, char *hash) 591 603 { 592 604 md5_byte_t *pass_dec = NULL; … … 594 606 md5_state_t md5_state; 595 607 int ret = -1, i; 596 597 if( base64_decode( hash, &pass_dec ) == 21 ) 598 { 599 md5_init( &md5_state ); 600 md5_append( &md5_state, (md5_byte_t*) password, strlen( password ) ); 601 md5_append( &md5_state, (md5_byte_t*) pass_dec + 16, 5 ); /* Hmmm, salt! */ 602 md5_finish( &md5_state, pass_md5 ); 603 604 for( i = 0; i < 16; i ++ ) 605 { 606 if( pass_dec[i] != pass_md5[i] ) 607 { 608 609 if (base64_decode(hash, &pass_dec) == 21) { 610 md5_init(&md5_state); 611 md5_append(&md5_state, (md5_byte_t *) password, strlen(password)); 612 md5_append(&md5_state, (md5_byte_t *) pass_dec + 16, 5); /* Hmmm, salt! */ 613 md5_finish(&md5_state, pass_md5); 614 615 for (i = 0; i < 16; i++) { 616 if (pass_dec[i] != pass_md5[i]) { 608 617 ret = 1; 609 618 break; 610 619 } 611 620 } 612 621 613 622 /* If we reached the end of the loop, it was a match! */ 614 if ( i == 16 )623 if (i == 16) { 615 624 ret = 0; 616 } 617 618 g_free( pass_dec ); 625 } 626 } 627 628 g_free(pass_dec); 619 629 620 630 return ret; … … 624 634 white\ space in 'various ways'. Returns a NULL-terminated static 625 635 char** so watch out with nested use! Definitely not thread-safe. */ 626 char **split_command_parts( char *command, int limit)627 { 628 static char *cmd[IRC_MAX_ARGS +1];636 char **split_command_parts(char *command, int limit) 637 { 638 static char *cmd[IRC_MAX_ARGS + 1]; 629 639 char *s, q = 0; 630 640 int k; 631 632 memset( cmd, 0, sizeof( cmd ));641 642 memset(cmd, 0, sizeof(cmd)); 633 643 cmd[0] = command; 634 644 k = 1; 635 for( s = command; *s && k < IRC_MAX_ARGS; s ++ ) 636 { 637 if( *s == ' ' && !q ) 638 { 645 for (s = command; *s && k < IRC_MAX_ARGS; s++) { 646 if (*s == ' ' && !q) { 639 647 *s = 0; 640 while( *++s == ' ' ); 641 if( k != limit && (*s == '"' || *s == '\'') ) 642 { 648 while (*++s == ' ') { 649 ; 650 } 651 if (k != limit && (*s == '"' || *s == '\'')) { 643 652 q = *s; 644 s ++; 645 } 646 if( *s ) 647 { 653 s++; 654 } 655 if (*s) { 648 656 cmd[k++] = s; 649 657 if (limit && k > limit) { 650 658 break; 651 659 } 652 s --; 653 } 654 else 655 { 660 s--; 661 } else { 656 662 break; 657 663 } 658 } 659 else if( *s == '\\' && ( ( !q && s[1] ) || ( q && q == s[1] ) ) ) 660 { 664 } else if (*s == '\\' && ((!q && s[1]) || (q && q == s[1]))) { 661 665 char *cpy; 662 663 for ( cpy = s; *cpy; cpy ++ )666 667 for (cpy = s; *cpy; cpy++) { 664 668 cpy[0] = cpy[1]; 665 } 666 else if( *s == q ) 667 { 669 } 670 } else if (*s == q) { 668 671 q = *s = 0; 669 672 } 670 673 } 671 674 672 675 /* Full zero-padding for easier argc checking. */ 673 while ( k <= IRC_MAX_ARGS )676 while (k <= IRC_MAX_ARGS) { 674 677 cmd[k++] = NULL; 675 678 } 679 676 680 return cmd; 677 681 } 678 682 679 char *get_rfc822_header( const char *text, const char *header, int len)680 { 681 int hlen = strlen( header), i;683 char *get_rfc822_header(const char *text, const char *header, int len) 684 { 685 int hlen = strlen(header), i; 682 686 const char *ret; 683 684 if ( text == NULL )687 688 if (text == NULL) { 685 689 return NULL; 686 687 if( len == 0 ) 688 len = strlen( text ); 689 690 } 691 692 if (len == 0) { 693 len = strlen(text); 694 } 695 690 696 i = 0; 691 while( ( i + hlen ) < len ) 692 { 697 while ((i + hlen) < len) { 693 698 /* Maybe this is a bit over-commented, but I just hate this part... */ 694 if( g_strncasecmp( text + i, header, hlen ) == 0 ) 695 { 699 if (g_strncasecmp(text + i, header, hlen) == 0) { 696 700 /* Skip to the (probable) end of the header */ 697 701 i += hlen; 698 702 699 703 /* Find the first non-[: \t] character */ 700 while( i < len && ( text[i] == ':' || text[i] == ' ' || text[i] == '\t' ) ) i ++; 701 704 while (i < len && (text[i] == ':' || text[i] == ' ' || text[i] == '\t')) { 705 i++; 706 } 707 702 708 /* Make sure we're still inside the string */ 703 if( i >= len ) return( NULL ); 704 709 if (i >= len) { 710 return(NULL); 711 } 712 705 713 /* Save the position */ 706 714 ret = text + i; 707 715 708 716 /* Search for the end of this line */ 709 while( i < len && text[i] != '\r' && text[i] != '\n' ) i ++; 710 717 while (i < len && text[i] != '\r' && text[i] != '\n') { 718 i++; 719 } 720 711 721 /* Make sure we're still inside the string */ 712 if( i >= len ) return( NULL ); 713 722 if (i >= len) { 723 return(NULL); 724 } 725 714 726 /* Copy the found data */ 715 return( g_strndup( ret, text + i - ret ));716 } 717 727 return(g_strndup(ret, text + i - ret)); 728 } 729 718 730 /* This wasn't the header we were looking for, skip to the next line. */ 719 while( i < len && ( text[i] != '\r' && text[i] != '\n' ) ) i ++; 720 while( i < len && ( text[i] == '\r' || text[i] == '\n' ) ) i ++; 721 731 while (i < len && (text[i] != '\r' && text[i] != '\n')) { 732 i++; 733 } 734 while (i < len && (text[i] == '\r' || text[i] == '\n')) { 735 i++; 736 } 737 722 738 /* End of headers? */ 723 if( ( i >= 4 && strncmp( text + i - 4, "\r\n\r\n", 4 ) == 0 ) || 724 ( i >= 2 && ( strncmp( text + i - 2, "\n\n", 2 ) == 0 || 725 strncmp( text + i - 2, "\r\r", 2 ) == 0 ) ) ) 726 { 727 break; 728 } 729 } 730 739 if ((i >= 4 && strncmp(text + i - 4, "\r\n\r\n", 4) == 0) || 740 (i >= 2 && (strncmp(text + i - 2, "\n\n", 2) == 0 || 741 strncmp(text + i - 2, "\r\r", 2) == 0))) { 742 break; 743 } 744 } 745 731 746 return NULL; 732 747 } 733 748 734 749 /* Takes a string, truncates it where it's safe, returns the new length */ 735 int truncate_utf8( char *string, int maxlen)750 int truncate_utf8(char *string, int maxlen) 736 751 { 737 752 char *end; 738 g_utf8_validate( (const gchar *) string, maxlen, (const gchar **) &end ); 753 754 g_utf8_validate((const gchar *) string, maxlen, (const gchar **) &end); 739 755 *end = '\0'; 740 756 return end - string;
Note: See TracChangeset
for help on using the changeset viewer.