Changes in irc.c [c84e31a:fa75134]
Legend:
- Unmodified
- Added
- Removed
-
irc.c
rc84e31a rfa75134 42 42 } 43 43 44 static char *set_eval_charset( set_t *set, char *value ) 45 { 46 irc_t *irc = set->data; 47 GIConv ic, oc; 48 49 if( g_strcasecmp( value, "none" ) == 0 ) 50 value = g_strdup( "utf-8" ); 51 52 if( ( ic = g_iconv_open( "utf-8", value ) ) == (GIConv) -1 ) 53 { 54 return NULL; 55 } 56 if( ( oc = g_iconv_open( value, "utf-8" ) ) == (GIConv) -1 ) 57 { 58 g_iconv_close( ic ); 59 return NULL; 60 } 61 62 if( irc->iconv != (GIConv) -1 ) 63 g_iconv_close( irc->iconv ); 64 if( irc->oconv != (GIConv) -1 ) 65 g_iconv_close( irc->oconv ); 66 67 irc->iconv = ic; 68 irc->oconv = oc; 69 70 return value; 71 } 72 44 73 irc_t *irc_new( int fd ) 45 74 { … … 64 93 irc->mynick = g_strdup( ROOT_NICK ); 65 94 irc->channel = g_strdup( ROOT_CHAN ); 95 96 irc->iconv = (GIConv) -1; 97 irc->oconv = (GIConv) -1; 66 98 67 99 if( global.conf->hostname ) … … 127 159 conf_loaddefaults( irc ); 128 160 161 /* Evaluator sets the iconv/oconv structures. */ 162 set_eval_charset( set_find( &irc->set, "charset" ), set_getstr( &irc->set, "charset" ) ); 163 129 164 return( irc ); 130 165 } … … 185 220 186 221 /* Because we have no garbage collection, this is quite annoying */ 187 void irc_free(irc_t * irc) 188 { 189 account_t *account; 222 void irc_free( irc_t * irc ) 223 { 190 224 user_t *user, *usertmp; 191 225 … … 196 230 irc_usermsg( irc, "Error while saving settings!" ); 197 231 198 closesocket( irc->fd ); 232 irc_connection_list = g_slist_remove( irc_connection_list, irc ); 233 234 while( irc->accounts ) 235 { 236 if( irc->accounts->ic ) 237 imc_logout( irc->accounts->ic, FALSE ); 238 else if( irc->accounts->reconnect ) 239 cancel_auto_reconnect( irc->accounts ); 240 241 if( irc->accounts->ic == NULL ) 242 account_del( irc, irc->accounts ); 243 else 244 /* Nasty hack, but account_del() doesn't work in this 245 case and we don't want infinite loops, do we? ;-) */ 246 irc->accounts = irc->accounts->next; 247 } 248 249 while( irc->queries != NULL ) 250 query_del( irc, irc->queries ); 251 252 while( irc->set ) 253 set_del( &irc->set, irc->set->key ); 254 255 if (irc->users != NULL) 256 { 257 user = irc->users; 258 while( user != NULL ) 259 { 260 g_free( user->nick ); 261 g_free( user->away ); 262 g_free( user->handle ); 263 if( user->user != user->nick ) g_free( user->user ); 264 if( user->host != user->nick ) g_free( user->host ); 265 if( user->realname != user->nick ) g_free( user->realname ); 266 b_event_remove( user->sendbuf_timer ); 267 268 usertmp = user; 269 user = user->next; 270 g_free( usertmp ); 271 } 272 } 199 273 200 274 if( irc->ping_source_id > 0 ) … … 204 278 b_event_remove( irc->w_watch_source_id ); 205 279 206 irc_connection_list = g_slist_remove( irc_connection_list, irc ); 207 208 for (account = irc->accounts; account; account = account->next) { 209 if (account->ic) { 210 imc_logout(account->ic, TRUE); 211 } else if (account->reconnect) { 212 cancel_auto_reconnect(account); 213 } 214 } 215 216 g_free(irc->sendbuffer); 217 g_free(irc->readbuffer); 218 219 g_free(irc->nick); 220 g_free(irc->user); 221 g_free(irc->host); 222 g_free(irc->realname); 223 g_free(irc->password); 224 225 g_free(irc->myhost); 226 g_free(irc->mynick); 227 228 g_free(irc->channel); 229 230 while (irc->queries != NULL) 231 query_del(irc, irc->queries); 232 233 while (irc->accounts) 234 if (irc->accounts->ic == NULL) 235 account_del(irc, irc->accounts); 236 else 237 /* Nasty hack, but account_del() doesn't work in this 238 case and we don't want infinite loops, do we? ;-) */ 239 irc->accounts = irc->accounts->next; 240 241 while (irc->set) 242 set_del(&irc->set, irc->set->key); 243 244 if (irc->users != NULL) { 245 user = irc->users; 246 while (user != NULL) { 247 g_free(user->nick); 248 g_free(user->away); 249 g_free(user->handle); 250 if(user->user!=user->nick) g_free(user->user); 251 if(user->host!=user->nick) g_free(user->host); 252 if(user->realname!=user->nick) g_free(user->realname); 253 b_event_remove(user->sendbuf_timer); 254 255 usertmp = user; 256 user = user->next; 257 g_free(usertmp); 258 } 259 } 260 261 g_hash_table_foreach_remove(irc->userhash, irc_free_hashkey, NULL); 262 g_hash_table_destroy(irc->userhash); 263 264 g_hash_table_foreach_remove(irc->watches, irc_free_hashkey, NULL); 265 g_hash_table_destroy(irc->watches); 266 267 g_free(irc); 280 closesocket( irc->fd ); 281 irc->fd = -1; 282 283 g_hash_table_foreach_remove( irc->userhash, irc_free_hashkey, NULL ); 284 g_hash_table_destroy( irc->userhash ); 285 286 g_hash_table_foreach_remove( irc->watches, irc_free_hashkey, NULL ); 287 g_hash_table_destroy( irc->watches ); 288 289 if( irc->iconv != (GIConv) -1 ) 290 g_iconv_close( irc->iconv ); 291 if( irc->oconv != (GIConv) -1 ) 292 g_iconv_close( irc->oconv ); 293 294 g_free( irc->sendbuffer ); 295 g_free( irc->readbuffer ); 296 297 g_free( irc->nick ); 298 g_free( irc->user ); 299 g_free( irc->host ); 300 g_free( irc->realname ); 301 g_free( irc->password ); 302 303 g_free( irc->myhost ); 304 g_free( irc->mynick ); 305 306 g_free( irc->channel ); 307 308 g_free( irc->last_target ); 309 310 g_free( irc ); 268 311 269 312 if( global.conf->runmode == RUNMODE_INETD || global.conf->runmode == RUNMODE_FORKDAEMON ) … … 286 329 void irc_process( irc_t *irc ) 287 330 { 288 char **lines, *temp, **cmd , *cs;331 char **lines, *temp, **cmd; 289 332 int i; 290 333 … … 295 338 for( i = 0; *lines[i] != '\0'; i ++ ) 296 339 { 297 char conv[IRC_MAX_LINE+1];340 char *conv = NULL; 298 341 299 /* [WvG] Because irc_tokenize splits at every newline, the lines[] list 300 should end with an empty string. This is why this actually works. 301 Took me a while to figure out, Maurits. :-P */ 342 /* [WvG] If the last line isn't empty, it's an incomplete line and we 343 should wait for the rest to come in before processing it. */ 302 344 if( lines[i+1] == NULL ) 303 345 { … … 309 351 } 310 352 311 if( ( cs = set_getstr( &irc->set, "charset" ) ) ) 312 { 313 conv[IRC_MAX_LINE] = 0; 314 if( do_iconv( cs, "UTF-8", lines[i], conv, 0, IRC_MAX_LINE - 2 ) == -1 ) 353 if( irc->iconv != (GIConv) -1 ) 354 { 355 gsize bytes_read, bytes_written; 356 357 conv = g_convert_with_iconv( lines[i], -1, irc->iconv, 358 &bytes_read, &bytes_written, NULL ); 359 360 if( conv == NULL || bytes_read != strlen( lines[i] ) ) 315 361 { 316 362 /* GLib can do strange things if things are not in the expected charset, … … 324 370 "expect by changing the charset setting. See " 325 371 "`help set charset' for more information. Your " 326 "message was ignored.", cs ); 327 *conv = 0; 372 "message was ignored.", 373 set_getstr( &irc->set, "charset" ) ); 374 375 g_free( conv ); 376 conv = NULL; 328 377 } 329 378 else 330 379 { 331 380 irc_write( irc, ":%s NOTICE AUTH :%s", irc->myhost, 332 "Warning: invalid (non-UTF8)characters received at login time." );381 "Warning: invalid characters received at login time." ); 333 382 334 strncpy( conv, lines[i], IRC_MAX_LINE);383 conv = g_strdup( lines[i] ); 335 384 for( temp = conv; *temp; temp ++ ) 336 385 if( *temp & 0x80 ) … … 341 390 } 342 391 343 if( ( cmd = irc_parse_line( lines[i] ) ) == NULL ) 344 continue; 345 irc_exec( irc, cmd ); 392 if( lines[i] ) 393 { 394 if( ( cmd = irc_parse_line( lines[i] ) ) == NULL ) 395 continue; 396 irc_exec( irc, cmd ); 397 g_free( cmd ); 398 } 346 399 347 g_free( c md);400 g_free( conv ); 348 401 349 402 /* Shouldn't really happen, but just in case... */ … … 369 422 char **irc_tokenize( char *buffer ) 370 423 { 371 int i, j ;424 int i, j, n = 3; 372 425 char **lines; 373 426 374 /* Count the number of elements we're gonna need. */ 375 for( i = 0, j = 1; buffer[i] != '\0'; i ++ ) 376 { 377 if( buffer[i] == '\n' ) 378 if( buffer[i+1] != '\r' && buffer[i+1] != '\n' ) 379 j ++; 380 } 381 382 /* Allocate j+1 elements. */ 383 lines = g_new( char *, j + 1 ); 427 /* Allocate n+1 elements. */ 428 lines = g_new( char *, n + 1 ); 429 430 lines[0] = buffer; 431 432 /* Split the buffer in several strings, and accept any kind of line endings, 433 * knowing that ERC on Windows may send something interesting like \r\r\n, 434 * and surely there must be clients that think just \n is enough... */ 435 for( i = 0, j = 0; buffer[i] != '\0'; i ++ ) 436 { 437 if( buffer[i] == '\r' || buffer[i] == '\n' ) 438 { 439 while( buffer[i] == '\r' || buffer[i] == '\n' ) 440 buffer[i++] = '\0'; 441 442 lines[++j] = buffer + i; 443 444 if( j >= n ) 445 { 446 n *= 2; 447 lines = g_renew( char *, lines, n + 1 ); 448 } 449 450 if( buffer[i] == '\0' ) 451 break; 452 } 453 } 384 454 385 455 /* NULL terminate our list. */ 386 lines[j] = NULL; 387 388 lines[0] = buffer; 389 390 /* Split the buffer in several strings, using \r\n as our seperator, where \r is optional. 391 * Although this is not in the RFC, some braindead ircds (newnet's) use this, so some clients might too. 392 */ 393 for( i = 0, j = 0; buffer[i] != '\0'; i ++) 394 { 395 if( buffer[i] == '\n' ) 396 { 397 buffer[i] = '\0'; 398 399 if( i > 0 && buffer[i-1] == '\r' ) 400 buffer[i-1] = '\0'; 401 if( buffer[i+1] != '\r' && buffer[i+1] != '\n' ) 402 lines[++j] = buffer + i + 1; 403 } 404 } 405 406 return( lines ); 456 lines[++j] = NULL; 457 458 return lines; 407 459 } 408 460 … … 538 590 539 591 return; 540 541 592 } 542 593 … … 544 595 { 545 596 int size; 546 char line[IRC_MAX_LINE+1] , *cs;597 char line[IRC_MAX_LINE+1]; 547 598 548 599 /* Don't try to write anything new anymore when shutting down. */ … … 550 601 return; 551 602 552 line[IRC_MAX_LINE] = 0;603 memset( line, 0, sizeof( line ) ); 553 604 g_vsnprintf( line, IRC_MAX_LINE - 2, format, params ); 554 555 605 strip_newlines( line ); 556 if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) ) 557 { 558 char conv[IRC_MAX_LINE+1]; 559 560 conv[IRC_MAX_LINE] = 0; 561 if( do_iconv( "UTF-8", cs, line, conv, 0, IRC_MAX_LINE - 2 ) != -1 ) 562 strcpy( line, conv ); 563 } 564 strcat( line, "\r\n" ); 606 607 if( irc->oconv != (GIConv) -1 ) 608 { 609 gsize bytes_read, bytes_written; 610 char *conv; 611 612 conv = g_convert_with_iconv( line, -1, irc->oconv, 613 &bytes_read, &bytes_written, NULL ); 614 615 if( bytes_read == strlen( line ) ) 616 strncpy( line, conv, IRC_MAX_LINE - 2 ); 617 618 g_free( conv ); 619 } 620 g_strlcat( line, "\r\n", IRC_MAX_LINE + 1 ); 565 621 566 622 if( irc->sendbuffer != NULL ) … … 735 791 irc_spawn( irc, u ); 736 792 737 irc_usermsg( irc, "Welcome to the BitlBee gateway!\n\nIf you've never used BitlBee before, please do read the help information using the \x02help\x02 command. Lots of FAQs are answered there." ); 793 irc_usermsg( irc, "Welcome to the BitlBee gateway!\n\n" 794 "If you've never used BitlBee before, please do read the help " 795 "information using the \x02help\x02 command. Lots of FAQs are " 796 "answered there.\n" 797 "If you already have an account on this server, just use the " 798 "\x02identify\x02 command to identify yourself." ); 738 799 739 800 if( global.conf->runmode == RUNMODE_FORKDAEMON || global.conf->runmode == RUNMODE_DAEMON ) … … 741 802 742 803 irc->status |= USTATUS_LOGGED_IN; 804 805 /* This is for bug #209 (use PASS to identify to NickServ). */ 806 if( irc->password != NULL ) 807 { 808 char *send_cmd[] = { "identify", g_strdup( irc->password ), NULL }; 809 810 irc_setpass( irc, NULL ); 811 root_command( irc, send_cmd ); 812 g_free( send_cmd[1] ); 813 } 743 814 } 744 815
Note: See TracChangeset
for help on using the changeset viewer.