Changeset 3ddb7477
- Timestamp:
- 2010-03-26T12:14:37Z (15 years ago)
- Branches:
- master
- Children:
- ebaebfe
- Parents:
- ba7d16f
- Files:
-
- 11 edited
- 6 moved
Legend:
- Unmodified
- Added
- Removed
-
Makefile
rba7d16f r3ddb7477 10 10 11 11 # Program variables 12 objects = account.o bitlbee.o chat.o dcc.o help.o ipc.o irc.o irc_commands.o nick.o query.o root_commands.o set.o storage.o $(STORAGE_OBJS) user.o 12 #objects = bitlbee.o chat.o dcc.o help.o ipc.o irc.o irc_commands.o nick.o query.o root_commands.o set.o storage.o $(STORAGE_OBJS) 13 objects = bitlbee.o help.o ipc.o irc.o irc_commands.o irc_send.o irc_user.o nick.o set.o 13 14 headers = account.h bitlbee.h commands.h conf.h config.h help.h ipc.h irc.h log.h nick.h query.h set.h sock.h storage.h user.h lib/events.h lib/ftutil.h lib/http_client.h lib/ini.h lib/md5.h lib/misc.h lib/proxy.h lib/sha1.h lib/ssl_client.h lib/url.h protocols/ft.h protocols/nogaim.h 14 15 subdirs = lib protocols -
bitlbee.h
rba7d16f r3ddb7477 124 124 #define CONF_FILE_DEF ETCDIR "bitlbee.conf" 125 125 126 #include "bee.h" 126 127 #include "irc.h" 127 128 #include "storage.h" … … 158 159 gboolean bitlbee_io_current_client_write( gpointer data, gint source, b_input_condition cond ); 159 160 160 void root_command_string( irc_t *irc, user_t *u, char *command, int flags );161 //void root_command_string( irc_t *irc, user_t *u, char *command, int flags ); 161 162 void root_command( irc_t *irc, char *command[] ); 162 163 gboolean bitlbee_shutdown( gpointer data, gint fd, b_input_condition cond ); -
conf.c
rba7d16f r3ddb7477 369 369 if( g_strcasecmp( ini->section, "defaults" ) == 0 ) 370 370 { 371 set_t *s = set_find( &irc-> set, ini->key );371 set_t *s = set_find( &irc->b->set, ini->key ); 372 372 373 373 if( s ) -
ipc.c
rba7d16f r3ddb7477 138 138 139 139 if( strchr( irc->umode, 'w' ) ) 140 irc_write( irc, ":%s WALLOPS :%s", irc-> myhost, cmd[1] );140 irc_write( irc, ":%s WALLOPS :%s", irc->root->host, cmd[1] ); 141 141 } 142 142 … … 147 147 148 148 if( strchr( irc->umode, 's' ) ) 149 irc_write( irc, ":%s NOTICE %s :%s", irc-> myhost, irc->nick, cmd[1] );149 irc_write( irc, ":%s NOTICE %s :%s", irc->root->host, irc->user->nick, cmd[1] ); 150 150 } 151 151 … … 156 156 157 157 if( strchr( irc->umode, 'o' ) ) 158 irc_write( irc, ":%s NOTICE %s :*** OperMsg *** %s", irc-> myhost, irc->nick, cmd[1] );158 irc_write( irc, ":%s NOTICE %s :*** OperMsg *** %s", irc->root->host, irc->user->nick, cmd[1] ); 159 159 } 160 160 … … 176 176 return; 177 177 178 if( nick_cmp( cmd[1], irc-> nick ) != 0 )178 if( nick_cmp( cmd[1], irc->user->nick ) != 0 ) 179 179 return; /* It's not for us. */ 180 180 181 irc_write( irc, ":%s!%s@%s KILL %s :%s", irc-> mynick, irc->mynick, irc->myhost, irc->nick, cmd[2] );181 irc_write( irc, ":%s!%s@%s KILL %s :%s", irc->root->nick, irc->root->nick, irc->root->host, irc->user->nick, cmd[2] ); 182 182 irc_abort( irc, 0, "Killed by operator: %s", cmd[2] ); 183 183 } … … 188 188 ipc_to_master_str( "HELLO\r\n" ); 189 189 else 190 ipc_to_master_str( "HELLO %s %s :%s\r\n", irc-> host, irc->nick, irc->realname );190 ipc_to_master_str( "HELLO %s %s :%s\r\n", irc->user->host, irc->user->nick, irc->user->fullname ); 191 191 } 192 192 -
irc.c
rba7d16f r3ddb7477 5 5 \********************************************************************/ 6 6 7 /* The big hairy IRCd part of the project*/7 /* The IRC-based UI (for now the only one) */ 8 8 9 9 /* … … 24 24 */ 25 25 26 #define BITLBEE_CORE27 26 #include "bitlbee.h" 28 #include "sock.h" 29 #include "ipc.h" 30 #include "dcc.h" 31 32 static gboolean irc_userping( gpointer _irc, int fd, b_input_condition cond ); 33 34 GSList *irc_connection_list = NULL; 35 36 static char *set_eval_password( set_t *set, char *value ) 37 { 38 irc_t *irc = set->data; 39 40 if( irc->status & USTATUS_IDENTIFIED && value ) 41 { 42 irc_setpass( irc, value ); 43 return NULL; 44 } 45 else 46 { 47 return SET_INVALID; 48 } 49 } 50 51 static char *set_eval_charset( set_t *set, char *value ) 52 { 53 irc_t *irc = set->data; 54 GIConv ic, oc; 55 56 if( g_strcasecmp( value, "none" ) == 0 ) 57 value = g_strdup( "utf-8" ); 58 59 if( ( ic = g_iconv_open( "utf-8", value ) ) == (GIConv) -1 ) 60 { 61 return NULL; 62 } 63 if( ( oc = g_iconv_open( value, "utf-8" ) ) == (GIConv) -1 ) 64 { 65 g_iconv_close( ic ); 66 return NULL; 67 } 68 69 if( irc->iconv != (GIConv) -1 ) 70 g_iconv_close( irc->iconv ); 71 if( irc->oconv != (GIConv) -1 ) 72 g_iconv_close( irc->oconv ); 73 74 irc->iconv = ic; 75 irc->oconv = oc; 76 77 return value; 78 } 79 80 static char *set_eval_away_status( set_t *set, char *value ) 81 { 82 irc_t *irc = set->data; 83 account_t *a; 84 85 g_free( set->value ); 86 set->value = g_strdup( value ); 87 88 for( a = irc->accounts; a; a = a->next ) 89 { 90 struct im_connection *ic = a->ic; 91 92 if( ic && ic->flags & OPT_LOGGED_IN ) 93 imc_away_send_update( ic ); 94 } 95 96 return value; 97 } 27 28 GSList *irc_connection_list; 29 30 static char *set_eval_charset( set_t *set, char *value ); 98 31 99 32 irc_t *irc_new( int fd ) … … 102 35 struct sockaddr_storage sock; 103 36 socklen_t socklen = sizeof( sock ); 37 char *host = NULL, *myhost = NULL; 38 irc_user_t *iu; 104 39 set_t *s; 40 bee_t *b; 105 41 106 42 irc = g_new0( irc_t, 1 ); … … 114 50 irc->last_pong = gettime(); 115 51 116 irc-> userhash = g_hash_table_new( g_str_hash, g_str_equal );52 irc->nick_user_hash = g_hash_table_new( g_str_hash, g_str_equal ); 117 53 irc->watches = g_hash_table_new( g_str_hash, g_str_equal ); 118 54 119 55 strcpy( irc->umode, UMODE ); 120 irc->mynick = g_strdup( ROOT_NICK );121 irc->channel = g_strdup( ROOT_CHAN );122 56 123 57 irc->iconv = (GIConv) -1; … … 126 60 if( global.conf->hostname ) 127 61 { 128 irc->myhost = g_strdup( global.conf->hostname );62 myhost = g_strdup( global.conf->hostname ); 129 63 } 130 64 else if( getsockname( irc->fd, (struct sockaddr*) &sock, &socklen ) == 0 ) … … 135 69 NI_MAXHOST, NULL, 0, 0 ) == 0 ) 136 70 { 137 irc->myhost = g_strdup( ipv6_unwrap( buf ) );71 myhost = g_strdup( ipv6_unwrap( buf ) ); 138 72 } 139 73 } … … 146 80 NI_MAXHOST, NULL, 0, 0 ) == 0 ) 147 81 { 148 irc->host = g_strdup( ipv6_unwrap( buf ) ); 149 } 150 } 151 152 if( irc->host == NULL ) 153 irc->host = g_strdup( "localhost.localdomain" ); 154 if( irc->myhost == NULL ) 155 irc->myhost = g_strdup( "localhost.localdomain" ); 156 157 if( global.conf->ping_interval > 0 && global.conf->ping_timeout > 0 ) 158 irc->ping_source_id = b_timeout_add( global.conf->ping_interval * 1000, irc_userping, irc ); 159 160 irc_write( irc, ":%s NOTICE AUTH :%s", irc->myhost, "BitlBee-IRCd initialized, please go on" ); 82 host = g_strdup( ipv6_unwrap( buf ) ); 83 } 84 } 85 86 if( host == NULL ) 87 host = g_strdup( "localhost.localdomain" ); 88 if( myhost == NULL ) 89 myhost = g_strdup( "localhost.localdomain" ); 90 91 //if( global.conf->ping_interval > 0 && global.conf->ping_timeout > 0 ) 92 // irc->ping_source_id = b_timeout_add( global.conf->ping_interval * 1000, irc_userping, irc ); 161 93 162 94 irc_connection_list = g_slist_append( irc_connection_list, irc ); 163 95 164 s = set_add( &irc->set, "away", NULL, set_eval_away_status, irc ); 165 s->flags |= SET_NULL_OK; 166 s = set_add( &irc->set, "away_devoice", "true", set_eval_away_devoice, irc ); 167 s = set_add( &irc->set, "auto_connect", "true", set_eval_bool, irc ); 168 s = set_add( &irc->set, "auto_reconnect", "true", set_eval_bool, irc ); 169 s = set_add( &irc->set, "auto_reconnect_delay", "5*3<900", set_eval_account_reconnect_delay, irc ); 170 s = set_add( &irc->set, "buddy_sendbuffer", "false", set_eval_bool, irc ); 171 s = set_add( &irc->set, "buddy_sendbuffer_delay", "200", set_eval_int, irc ); 172 s = set_add( &irc->set, "charset", "utf-8", set_eval_charset, irc ); 173 s = set_add( &irc->set, "control_channel", irc->channel, set_eval_control_channel, irc ); 174 s = set_add( &irc->set, "debug", "false", set_eval_bool, irc ); 175 s = set_add( &irc->set, "default_target", "root", NULL, irc ); 176 s = set_add( &irc->set, "display_namechanges", "false", set_eval_bool, irc ); 177 s = set_add( &irc->set, "handle_unknown", "root", NULL, irc ); 178 s = set_add( &irc->set, "lcnicks", "true", set_eval_bool, irc ); 179 s = set_add( &irc->set, "ops", "both", set_eval_ops, irc ); 180 s = set_add( &irc->set, "password", NULL, set_eval_password, irc ); 181 s->flags |= SET_NULL_OK; 182 s = set_add( &irc->set, "private", "true", set_eval_bool, irc ); 183 s = set_add( &irc->set, "query_order", "lifo", NULL, irc ); 184 s = set_add( &irc->set, "root_nick", irc->mynick, set_eval_root_nick, irc ); 185 s = set_add( &irc->set, "save_on_quit", "true", set_eval_bool, irc ); 186 s = set_add( &irc->set, "simulate_netsplit", "true", set_eval_bool, irc ); 187 s = set_add( &irc->set, "status", NULL, set_eval_away_status, irc ); 188 s->flags |= SET_NULL_OK; 189 s = set_add( &irc->set, "strip_html", "true", NULL, irc ); 190 s = set_add( &irc->set, "to_char", ": ", set_eval_to_char, irc ); 191 s = set_add( &irc->set, "typing_notice", "false", set_eval_bool, irc ); 192 193 conf_loaddefaults( irc ); 96 b = irc->b = bee_new(); 97 98 s = set_add( &b->set, "away_devoice", "true", NULL/*set_eval_away_devoice*/, irc ); 99 s = set_add( &b->set, "buddy_sendbuffer", "false", set_eval_bool, irc ); 100 s = set_add( &b->set, "buddy_sendbuffer_delay", "200", set_eval_int, irc ); 101 s = set_add( &b->set, "charset", "utf-8", set_eval_charset, irc ); 102 //s = set_add( &b->set, "control_channel", irc->channel, NULL/*set_eval_control_channel*/, irc ); 103 s = set_add( &b->set, "default_target", "root", NULL, irc ); 104 s = set_add( &b->set, "display_namechanges", "false", set_eval_bool, irc ); 105 s = set_add( &b->set, "handle_unknown", "root", NULL, irc ); 106 s = set_add( &b->set, "lcnicks", "true", set_eval_bool, irc ); 107 s = set_add( &b->set, "ops", "both", NULL/*set_eval_ops*/, irc ); 108 s = set_add( &b->set, "private", "true", set_eval_bool, irc ); 109 s = set_add( &b->set, "query_order", "lifo", NULL, irc ); 110 s = set_add( &b->set, "root_nick", ROOT_NICK, NULL/*set_eval_root_nick*/, irc ); 111 s = set_add( &b->set, "simulate_netsplit", "true", set_eval_bool, irc ); 112 s = set_add( &b->set, "to_char", ": ", set_eval_to_char, irc ); 113 s = set_add( &b->set, "typing_notice", "false", set_eval_bool, irc ); 114 115 irc->root = iu = irc_user_new( irc, ROOT_NICK ); 116 iu->host = g_strdup( myhost ); 117 iu->fullname = g_strdup( ROOT_FN ); 118 119 iu = irc_user_new( irc, NS_NICK ); 120 iu->host = g_strdup( myhost ); 121 iu->fullname = g_strdup( ROOT_FN ); 122 123 irc->user = g_new0( irc_user_t, 1 ); 124 irc->user->host = g_strdup( host ); 125 126 conf_loaddefaults( b ); 194 127 195 128 /* Evaluator sets the iconv/oconv structures. */ 196 set_eval_charset( set_find( &irc->set, "charset" ), set_getstr( &irc->set, "charset" ) ); 197 198 return( irc ); 129 set_eval_charset( set_find( &b->set, "charset" ), set_getstr( &b->set, "charset" ) ); 130 131 irc_write( irc, ":%s NOTICE AUTH :%s", irc->root->host, "BitlBee-IRCd initialized, please go on" ); 132 133 return irc; 199 134 } 200 135 … … 217 152 218 153 ipc_to_master_str( "OPERMSG :Client exiting: %s@%s [%s]\r\n", 219 irc-> nick ? irc->nick : "(NONE)", irc->host, reason );154 irc->user->nick ? irc->user->nick : "(NONE)", irc->root->host, reason ); 220 155 221 156 g_free( reason ); … … 227 162 228 163 ipc_to_master_str( "OPERMSG :Client exiting: %s@%s [%s]\r\n", 229 irc-> nick ? irc->nick : "(NONE)", irc->host, "No reason given" );164 irc->user->nick ? irc->user->nick : "(NONE)", irc->root->host, "No reason given" ); 230 165 } 231 166 … … 248 183 } 249 184 250 static gboolean irc_free_hashkey( gpointer key, gpointer value, gpointer data ) 251 { 252 g_free( key ); 253 254 return( TRUE ); 255 } 256 257 /* Because we have no garbage collection, this is quite annoying */ 185 static gboolean irc_free_hashkey( gpointer key, gpointer value, gpointer data ); 186 258 187 void irc_free( irc_t * irc ) 259 188 { 260 user_t *user, *usertmp;261 262 189 log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd ); 263 190 264 if( irc->status & USTATUS_IDENTIFIED && set_getbool( &irc->set, "save_on_quit" ) ) 191 /* 192 if( irc->status & USTATUS_IDENTIFIED && set_getbool( &irc->b->set, "save_on_quit" ) ) 265 193 if( storage_save( irc, NULL, TRUE ) != STORAGE_OK ) 266 194 irc_usermsg( irc, "Error while saving settings!" ); 195 */ 267 196 268 197 irc_connection_list = g_slist_remove( irc_connection_list, irc ); 269 198 270 while( irc->accounts ) 271 { 272 if( irc->accounts->ic ) 273 imc_logout( irc->accounts->ic, FALSE ); 274 else if( irc->accounts->reconnect ) 275 cancel_auto_reconnect( irc->accounts ); 276 277 if( irc->accounts->ic == NULL ) 278 account_del( irc, irc->accounts ); 279 else 280 /* Nasty hack, but account_del() doesn't work in this 281 case and we don't want infinite loops, do we? ;-) */ 282 irc->accounts = irc->accounts->next; 283 } 284 199 /* 285 200 while( irc->queries != NULL ) 286 201 query_del( irc, irc->queries ); 287 288 while( irc->set ) 289 set_del( &irc->set, irc->set->key ); 290 291 if (irc->users != NULL) 292 { 293 user = irc->users; 294 while( user != NULL ) 295 { 296 g_free( user->nick ); 297 g_free( user->away ); 298 g_free( user->handle ); 299 if( user->user != user->nick ) g_free( user->user ); 300 if( user->host != user->nick ) g_free( user->host ); 301 if( user->realname != user->nick ) g_free( user->realname ); 302 b_event_remove( user->sendbuf_timer ); 303 304 usertmp = user; 305 user = user->next; 306 g_free( usertmp ); 307 } 308 } 202 */ 203 204 while( irc->users ) 205 irc_user_free( irc, irc->users->data ); 309 206 310 207 if( irc->ping_source_id > 0 ) … … 318 215 irc->fd = -1; 319 216 320 g_hash_table_foreach_remove( irc-> userhash, irc_free_hashkey, NULL );321 g_hash_table_destroy( irc-> userhash );217 g_hash_table_foreach_remove( irc->nick_user_hash, irc_free_hashkey, NULL ); 218 g_hash_table_destroy( irc->nick_user_hash ); 322 219 323 220 g_hash_table_foreach_remove( irc->watches, irc_free_hashkey, NULL ); … … 332 229 g_free( irc->readbuffer ); 333 230 334 g_free( irc->nick );335 g_free( irc->user );336 g_free( irc->host );337 g_free( irc->realname );338 231 g_free( irc->password ); 339 340 g_free( irc->myhost );341 g_free( irc->mynick );342 343 g_free( irc->channel );344 345 g_free( irc->last_target );346 232 347 233 g_free( irc ); … … 355 241 } 356 242 357 /* USE WITH CAUTION! 358 Sets pass without checking */ 359 void irc_setpass (irc_t *irc, const char *pass) 360 { 361 g_free (irc->password); 362 363 if (pass) { 364 irc->password = g_strdup (pass); 365 } else { 366 irc->password = NULL; 367 } 368 } 243 static gboolean irc_free_hashkey( gpointer key, gpointer value, gpointer data ) 244 { 245 g_free( key ); 246 247 return( TRUE ); 248 } 249 250 static char **irc_splitlines( char *buffer ); 369 251 370 252 void irc_process( irc_t *irc ) … … 375 257 if( irc->readbuffer != NULL ) 376 258 { 377 lines = irc_ tokenize( irc->readbuffer );259 lines = irc_splitlines( irc->readbuffer ); 378 260 379 261 for( i = 0; *lines[i] != '\0'; i ++ ) … … 412 294 "`help set charset' for more information. Your " 413 295 "message was ignored.", 414 set_getstr( &irc-> set, "charset" ) );296 set_getstr( &irc->b->set, "charset" ) ); 415 297 416 298 g_free( conv ); … … 419 301 else 420 302 { 421 irc_write( irc, ":%s NOTICE AUTH :%s", irc-> myhost,303 irc_write( irc, ":%s NOTICE AUTH :%s", irc->root->host, 422 304 "Warning: invalid characters received at login time." ); 423 305 … … 457 339 } 458 340 459 /* Splits a long string into separate lines. The array is NULL-terminated and, unless the string 460 contains an incomplete line at the end, ends with an empty string. */ 461 char **irc_tokenize( char *buffer ) 341 /* Splits a long string into separate lines. The array is NULL-terminated 342 and, unless the string contains an incomplete line at the end, ends with 343 an empty string. Could use g_strsplit() but this one does it in-place. 344 (So yes, it's destructive.) */ 345 static char **irc_splitlines( char *buffer ) 462 346 { 463 347 int i, j, n = 3; … … 590 474 } 591 475 592 void irc_reply( irc_t *irc, int code, char *format, ... )593 {594 char text[IRC_MAX_LINE];595 va_list params;596 597 va_start( params, format );598 g_vsnprintf( text, IRC_MAX_LINE, format, params );599 va_end( params );600 irc_write( irc, ":%s %03d %s %s", irc->myhost, code, irc->nick?irc->nick:"*", text );601 602 return;603 }604 605 int irc_usermsg( irc_t *irc, char *format, ... )606 {607 char text[1024];608 va_list params;609 char is_private = 0;610 user_t *u;611 612 u = user_find( irc, irc->mynick );613 is_private = u->is_private;614 615 va_start( params, format );616 g_vsnprintf( text, sizeof( text ), format, params );617 va_end( params );618 619 return( irc_msgfrom( irc, u->nick, text ) );620 }621 622 476 void irc_write( irc_t *irc, char *format, ... ) 623 477 { … … 630 484 return; 631 485 } 486 487 void irc_write_all( int now, char *format, ... ) 488 { 489 va_list params; 490 GSList *temp; 491 492 va_start( params, format ); 493 494 temp = irc_connection_list; 495 while( temp != NULL ) 496 { 497 irc_t *irc = temp->data; 498 499 if( now ) 500 { 501 g_free( irc->sendbuffer ); 502 irc->sendbuffer = g_strdup( "\r\n" ); 503 } 504 irc_vawrite( temp->data, format, params ); 505 if( now ) 506 { 507 bitlbee_io_current_client_write( irc, irc->fd, GAIM_INPUT_WRITE ); 508 } 509 temp = temp->next; 510 } 511 512 va_end( params ); 513 return; 514 } 632 515 633 516 void irc_vawrite( irc_t *irc, char *format, va_list params ) … … 686 569 } 687 570 688 void irc_write_all( int now, char *format, ... )689 {690 va_list params;691 GSList *temp;692 693 va_start( params, format );694 695 temp = irc_connection_list;696 while( temp != NULL )697 {698 irc_t *irc = temp->data;699 700 if( now )701 {702 g_free( irc->sendbuffer );703 irc->sendbuffer = g_strdup( "\r\n" );704 }705 irc_vawrite( temp->data, format, params );706 if( now )707 {708 bitlbee_io_current_client_write( irc, irc->fd, GAIM_INPUT_WRITE );709 }710 temp = temp->next;711 }712 713 va_end( params );714 return;715 }716 717 void irc_names( irc_t *irc, char *channel )718 {719 user_t *u;720 char namelist[385] = "";721 struct groupchat *c = NULL;722 char *ops = set_getstr( &irc->set, "ops" );723 724 /* RFCs say there is no error reply allowed on NAMES, so when the725 channel is invalid, just give an empty reply. */726 727 if( g_strcasecmp( channel, irc->channel ) == 0 )728 {729 for( u = irc->users; u; u = u->next ) if( u->online )730 {731 if( strlen( namelist ) + strlen( u->nick ) > sizeof( namelist ) - 4 )732 {733 irc_reply( irc, 353, "= %s :%s", channel, namelist );734 *namelist = 0;735 }736 737 if( u->ic && !u->away && set_getbool( &irc->set, "away_devoice" ) )738 strcat( namelist, "+" );739 else if( ( strcmp( u->nick, irc->mynick ) == 0 && ( strcmp( ops, "root" ) == 0 || strcmp( ops, "both" ) == 0 ) ) ||740 ( strcmp( u->nick, irc->nick ) == 0 && ( strcmp( ops, "user" ) == 0 || strcmp( ops, "both" ) == 0 ) ) )741 strcat( namelist, "@" );742 743 strcat( namelist, u->nick );744 strcat( namelist, " " );745 }746 }747 else if( ( c = irc_chat_by_channel( irc, channel ) ) )748 {749 GList *l;750 751 /* root and the user aren't in the channel userlist but should752 show up in /NAMES, so list them first: */753 sprintf( namelist, "%s%s %s%s ", strcmp( ops, "root" ) == 0 || strcmp( ops, "both" ) ? "@" : "", irc->mynick,754 strcmp( ops, "user" ) == 0 || strcmp( ops, "both" ) ? "@" : "", irc->nick );755 756 for( l = c->in_room; l; l = l->next ) if( ( u = user_findhandle( c->ic, l->data ) ) )757 {758 if( strlen( namelist ) + strlen( u->nick ) > sizeof( namelist ) - 4 )759 {760 irc_reply( irc, 353, "= %s :%s", channel, namelist );761 *namelist = 0;762 }763 764 strcat( namelist, u->nick );765 strcat( namelist, " " );766 }767 }768 769 if( *namelist )770 irc_reply( irc, 353, "= %s :%s", channel, namelist );771 772 irc_reply( irc, 366, "%s :End of /NAMES list", channel );773 }774 775 571 int irc_check_login( irc_t *irc ) 776 572 { 777 if( irc->user && irc->nick )573 if( irc->user->user && irc->user->nick ) 778 574 { 779 575 if( global.conf->authmode == AUTHMODE_CLOSED && !( irc->status & USTATUS_AUTHORIZED ) ) 780 576 { 781 irc_ reply( irc, 464, ":This server is password-protected." );577 irc_send_num( irc, 464, ":This server is password-protected." ); 782 578 return 0; 783 579 } 784 580 else 785 581 { 786 irc_ login( irc );582 irc_send_login( irc ); 787 583 return 1; 788 584 } … … 795 591 } 796 592 797 void irc_login( irc_t *irc ) 798 { 799 user_t *u; 800 801 irc_reply( irc, 1, ":Welcome to the BitlBee gateway, %s", irc->nick ); 802 irc_reply( irc, 2, ":Host %s is running BitlBee " BITLBEE_VERSION " " ARCH "/" CPU ".", irc->myhost ); 803 irc_reply( irc, 3, ":%s", IRCD_INFO ); 804 irc_reply( irc, 4, "%s %s %s %s", irc->myhost, BITLBEE_VERSION, UMODES UMODES_PRIV, CMODES ); 805 irc_reply( irc, 5, "PREFIX=(ov)@+ CHANTYPES=%s CHANMODES=,,,%s NICKLEN=%d NETWORK=BitlBee " 806 "CASEMAPPING=rfc1459 MAXTARGETS=1 WATCH=128 :are supported by this server", 807 CTYPES, CMODES, MAX_NICK_LENGTH - 1 ); 808 irc_motd( irc ); 809 irc->umode[0] = '\0'; 810 irc_umode_set( irc, "+" UMODE, 1 ); 811 812 u = user_add( irc, irc->mynick ); 813 u->host = g_strdup( irc->myhost ); 814 u->realname = g_strdup( ROOT_FN ); 815 u->online = 1; 816 u->send_handler = root_command_string; 817 u->is_private = 0; /* [SH] The channel is root's personal playground. */ 818 irc_spawn( irc, u ); 819 820 u = user_add( irc, NS_NICK ); 821 u->host = g_strdup( irc->myhost ); 822 u->realname = g_strdup( ROOT_FN ); 823 u->online = 0; 824 u->send_handler = root_command_string; 825 u->is_private = 1; /* [SH] NickServ is not in the channel, so should always /query. */ 826 827 u = user_add( irc, irc->nick ); 828 u->user = g_strdup( irc->user ); 829 u->host = g_strdup( irc->host ); 830 u->realname = g_strdup( irc->realname ); 831 u->online = 1; 832 irc_spawn( irc, u ); 833 834 irc_usermsg( irc, "Welcome to the BitlBee gateway!\n\n" 835 "If you've never used BitlBee before, please do read the help " 836 "information using the \x02help\x02 command. Lots of FAQs are " 837 "answered there.\n" 838 "If you already have an account on this server, just use the " 839 "\x02identify\x02 command to identify yourself." ); 840 841 if( global.conf->runmode == RUNMODE_FORKDAEMON || global.conf->runmode == RUNMODE_DAEMON ) 842 ipc_to_master_str( "CLIENT %s %s :%s\r\n", irc->host, irc->nick, irc->realname ); 843 844 irc->status |= USTATUS_LOGGED_IN; 845 846 /* This is for bug #209 (use PASS to identify to NickServ). */ 847 if( irc->password != NULL ) 848 { 849 char *send_cmd[] = { "identify", g_strdup( irc->password ), NULL }; 850 851 irc_setpass( irc, NULL ); 852 root_command( irc, send_cmd ); 853 g_free( send_cmd[1] ); 854 } 855 } 856 857 void irc_motd( irc_t *irc ) 858 { 859 int fd; 860 861 fd = open( global.conf->motdfile, O_RDONLY ); 862 if( fd == -1 ) 863 { 864 irc_reply( irc, 422, ":We don't need MOTDs." ); 865 } 866 else 867 { 868 char linebuf[80]; /* Max. line length for MOTD's is 79 chars. It's what most IRC networks seem to do. */ 869 char *add, max; 870 int len; 871 872 linebuf[79] = len = 0; 873 max = sizeof( linebuf ) - 1; 874 875 irc_reply( irc, 375, ":- %s Message Of The Day - ", irc->myhost ); 876 while( read( fd, linebuf + len, 1 ) == 1 ) 877 { 878 if( linebuf[len] == '\n' || len == max ) 879 { 880 linebuf[len] = 0; 881 irc_reply( irc, 372, ":- %s", linebuf ); 882 len = 0; 883 } 884 else if( linebuf[len] == '%' ) 885 { 886 read( fd, linebuf + len, 1 ); 887 if( linebuf[len] == 'h' ) 888 add = irc->myhost; 889 else if( linebuf[len] == 'v' ) 890 add = BITLBEE_VERSION; 891 else if( linebuf[len] == 'n' ) 892 add = irc->nick; 893 else 894 add = "%"; 895 896 strncpy( linebuf + len, add, max - len ); 897 while( linebuf[++len] ); 898 } 899 else if( len < max ) 900 { 901 len ++; 902 } 903 } 904 irc_reply( irc, 376, ":End of MOTD" ); 905 close( fd ); 906 } 907 } 908 909 void irc_topic( irc_t *irc, char *channel ) 910 { 911 struct groupchat *c = irc_chat_by_channel( irc, channel ); 912 913 if( c && c->topic ) 914 irc_reply( irc, 332, "%s :%s", channel, c->topic ); 915 else if( g_strcasecmp( channel, irc->channel ) == 0 ) 916 irc_reply( irc, 332, "%s :%s", channel, CONTROL_TOPIC ); 917 else 918 irc_reply( irc, 331, "%s :No topic for this channel", channel ); 919 } 920 921 void irc_umode_set( irc_t *irc, char *s, int allow_priv ) 922 { 923 /* allow_priv: Set to 0 if s contains user input, 1 if you want 924 to set a "privileged" mode (+o, +R, etc). */ 925 char m[256], st = 1, *t; 926 int i; 927 char changes[512], *p, st2 = 2; 928 char badflag = 0; 929 930 memset( m, 0, sizeof( m ) ); 931 932 for( t = irc->umode; *t; t ++ ) 933 m[(int)*t] = 1; 934 935 p = changes; 936 for( t = s; *t; t ++ ) 937 { 938 if( *t == '+' || *t == '-' ) 939 st = *t == '+'; 940 else if( st == 0 || ( strchr( UMODES, *t ) || ( allow_priv && strchr( UMODES_PRIV, *t ) ) ) ) 941 { 942 if( m[(int)*t] != st) 943 { 944 if( st != st2 ) 945 st2 = st, *p++ = st ? '+' : '-'; 946 *p++ = *t; 947 } 948 m[(int)*t] = st; 949 } 950 else 951 badflag = 1; 952 } 953 *p = '\0'; 954 955 memset( irc->umode, 0, sizeof( irc->umode ) ); 956 957 for( i = 0; i < 256 && strlen( irc->umode ) < ( sizeof( irc->umode ) - 1 ); i ++ ) 958 if( m[i] ) 959 irc->umode[strlen(irc->umode)] = i; 960 961 if( badflag ) 962 irc_reply( irc, 501, ":Unknown MODE flag" ); 963 /* Deliberately no !user@host on the prefix here */ 964 if( *changes ) 965 irc_write( irc, ":%s MODE %s %s", irc->nick, irc->nick, changes ); 966 } 967 968 void irc_spawn( irc_t *irc, user_t *u ) 969 { 970 irc_join( irc, u, irc->channel ); 971 } 972 973 void irc_join( irc_t *irc, user_t *u, char *channel ) 974 { 975 char *nick; 976 977 if( ( g_strcasecmp( channel, irc->channel ) != 0 ) || user_find( irc, irc->nick ) ) 978 irc_write( irc, ":%s!%s@%s JOIN :%s", u->nick, u->user, u->host, channel ); 979 980 if( nick_cmp( u->nick, irc->nick ) == 0 ) 981 { 982 irc_write( irc, ":%s MODE %s +%s", irc->myhost, channel, CMODE ); 983 irc_names( irc, channel ); 984 irc_topic( irc, channel ); 985 } 986 987 nick = g_strdup( u->nick ); 988 nick_lc( nick ); 989 if( g_hash_table_lookup( irc->watches, nick ) ) 990 { 991 irc_reply( irc, 600, "%s %s %s %d :%s", u->nick, u->user, u->host, (int) time( NULL ), "logged online" ); 992 } 993 g_free( nick ); 994 } 995 996 void irc_part( irc_t *irc, user_t *u, char *channel ) 997 { 998 irc_write( irc, ":%s!%s@%s PART %s :%s", u->nick, u->user, u->host, channel, "" ); 999 } 1000 1001 void irc_kick( irc_t *irc, user_t *u, char *channel, user_t *kicker ) 1002 { 1003 irc_write( irc, ":%s!%s@%s KICK %s %s :%s", kicker->nick, kicker->user, kicker->host, channel, u->nick, "" ); 1004 } 1005 1006 void irc_kill( irc_t *irc, user_t *u ) 1007 { 1008 char *nick, *s; 1009 char reason[128]; 1010 1011 if( u->ic && u->ic->flags & OPT_LOGGING_OUT && set_getbool( &irc->set, "simulate_netsplit" ) ) 1012 { 1013 if( u->ic->acc->server ) 1014 g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost, 1015 u->ic->acc->server ); 1016 else if( ( s = strchr( u->ic->acc->user, '@' ) ) ) 1017 g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost, 1018 s + 1 ); 1019 else 1020 g_snprintf( reason, sizeof( reason ), "%s %s.%s", irc->myhost, 1021 u->ic->acc->prpl->name, irc->myhost ); 1022 1023 /* proto_opt might contain garbage after the : */ 1024 if( ( s = strchr( reason, ':' ) ) ) 1025 *s = 0; 1026 } 1027 else 1028 { 1029 strcpy( reason, "Leaving..." ); 1030 } 1031 1032 irc_write( irc, ":%s!%s@%s QUIT :%s", u->nick, u->user, u->host, reason ); 1033 1034 nick = g_strdup( u->nick ); 1035 nick_lc( nick ); 1036 if( g_hash_table_lookup( irc->watches, nick ) ) 1037 { 1038 irc_reply( irc, 601, "%s %s %s %d :%s", u->nick, u->user, u->host, (int) time( NULL ), "logged offline" ); 1039 } 1040 g_free( nick ); 1041 } 1042 1043 int irc_send( irc_t *irc, char *nick, char *s, int flags ) 1044 { 1045 struct groupchat *c = NULL; 1046 user_t *u = NULL; 1047 1048 if( strchr( CTYPES, *nick ) ) 1049 { 1050 if( !( c = irc_chat_by_channel( irc, nick ) ) ) 1051 { 1052 irc_reply( irc, 403, "%s :Channel does not exist", nick ); 1053 return( 0 ); 1054 } 1055 } 1056 else 1057 { 1058 u = user_find( irc, nick ); 1059 1060 if( !u ) 1061 { 1062 if( irc->is_private ) 1063 irc_reply( irc, 401, "%s :Nick does not exist", nick ); 1064 else 1065 irc_usermsg( irc, "Nick `%s' does not exist!", nick ); 1066 return( 0 ); 1067 } 1068 } 1069 1070 if( *s == 1 && s[strlen(s)-1] == 1 ) 1071 { 1072 if( g_strncasecmp( s + 1, "ACTION", 6 ) == 0 ) 1073 { 1074 if( s[7] == ' ' ) s ++; 1075 s += 3; 1076 *(s++) = '/'; 1077 *(s++) = 'm'; 1078 *(s++) = 'e'; 1079 *(s++) = ' '; 1080 s -= 4; 1081 s[strlen(s)-1] = 0; 1082 } 1083 else if( g_strncasecmp( s + 1, "VERSION", 7 ) == 0 ) 1084 { 1085 u = user_find( irc, irc->mynick ); 1086 irc_privmsg( irc, u, "NOTICE", irc->nick, "", "\001VERSION BitlBee " BITLBEE_VERSION " " ARCH "/" CPU "\001" ); 1087 return( 1 ); 1088 } 1089 else if( g_strncasecmp( s + 1, "PING", 4 ) == 0 ) 1090 { 1091 u = user_find( irc, irc->mynick ); 1092 irc_privmsg( irc, u, "NOTICE", irc->nick, "", s ); 1093 return( 1 ); 1094 } 1095 else if( g_strncasecmp( s + 1, "TYPING", 6 ) == 0 ) 1096 { 1097 if( u && u->ic && u->ic->acc->prpl->send_typing && strlen( s ) >= 10 ) 1098 { 1099 time_t current_typing_notice = time( NULL ); 1100 1101 if( current_typing_notice - u->last_typing_notice >= 5 ) 1102 { 1103 u->ic->acc->prpl->send_typing( u->ic, u->handle, ( s[8] - '0' ) << 8 ); 1104 u->last_typing_notice = current_typing_notice; 1105 } 1106 } 1107 return( 1 ); 1108 } 1109 else if( g_strncasecmp( s + 1, "DCC", 3 ) == 0 ) 1110 { 1111 if( u && u->ic && u->ic->acc->prpl->transfer_request ) 1112 { 1113 file_transfer_t *ft = dcc_request( u->ic, s + 5 ); 1114 if ( ft ) 1115 u->ic->acc->prpl->transfer_request( u->ic, ft, u->handle ); 1116 } 1117 return( 1 ); 1118 } 1119 else 1120 { 1121 irc_usermsg( irc, "Supported CTCPs are ACTION, VERSION, PING, TYPING, DCC" ); 1122 return( 0 ); 1123 } 1124 } 1125 1126 if( u ) 1127 { 1128 /* For the next message, we probably do have to send new notices... */ 1129 u->last_typing_notice = 0; 1130 u->is_private = irc->is_private; 1131 1132 if( u->is_private ) 1133 { 1134 if( !u->online ) 1135 irc_reply( irc, 301, "%s :%s", u->nick, "User is offline" ); 1136 else if( u->away ) 1137 irc_reply( irc, 301, "%s :%s", u->nick, u->away ); 1138 } 1139 1140 if( u->send_handler ) 1141 { 1142 u->send_handler( irc, u, s, flags ); 1143 return 1; 1144 } 1145 } 1146 else if( c && c->ic && c->ic->acc && c->ic->acc->prpl ) 1147 { 1148 return( imc_chat_msg( c, s, 0 ) ); 1149 } 1150 1151 return( 0 ); 1152 } 1153 1154 static gboolean buddy_send_handler_delayed( gpointer data, gint fd, b_input_condition cond ) 1155 { 1156 user_t *u = data; 1157 1158 /* Shouldn't happen, but just to be sure. */ 1159 if( u->sendbuf_len < 2 ) 1160 return FALSE; 1161 1162 u->sendbuf[u->sendbuf_len-2] = 0; /* Cut off the last newline */ 1163 imc_buddy_msg( u->ic, u->handle, u->sendbuf, u->sendbuf_flags ); 1164 1165 g_free( u->sendbuf ); 1166 u->sendbuf = NULL; 1167 u->sendbuf_len = 0; 1168 u->sendbuf_timer = 0; 1169 u->sendbuf_flags = 0; 1170 1171 return FALSE; 1172 } 1173 1174 void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags ) 1175 { 1176 if( !u || !u->ic ) return; 1177 1178 if( set_getbool( &irc->set, "buddy_sendbuffer" ) && set_getint( &irc->set, "buddy_sendbuffer_delay" ) > 0 ) 1179 { 1180 int delay; 1181 1182 if( u->sendbuf_len > 0 && u->sendbuf_flags != flags) 1183 { 1184 /* Flush the buffer */ 1185 b_event_remove( u->sendbuf_timer ); 1186 buddy_send_handler_delayed( u, -1, 0 ); 1187 } 1188 1189 if( u->sendbuf_len == 0 ) 1190 { 1191 u->sendbuf_len = strlen( msg ) + 2; 1192 u->sendbuf = g_new( char, u->sendbuf_len ); 1193 u->sendbuf[0] = 0; 1194 u->sendbuf_flags = flags; 1195 } 1196 else 1197 { 1198 u->sendbuf_len += strlen( msg ) + 1; 1199 u->sendbuf = g_renew( char, u->sendbuf, u->sendbuf_len ); 1200 } 1201 1202 strcat( u->sendbuf, msg ); 1203 strcat( u->sendbuf, "\n" ); 1204 1205 delay = set_getint( &irc->set, "buddy_sendbuffer_delay" ); 1206 if( delay <= 5 ) 1207 delay *= 1000; 1208 1209 if( u->sendbuf_timer > 0 ) 1210 b_event_remove( u->sendbuf_timer ); 1211 u->sendbuf_timer = b_timeout_add( delay, buddy_send_handler_delayed, u ); 1212 } 1213 else 1214 { 1215 imc_buddy_msg( u->ic, u->handle, msg, flags ); 1216 } 1217 } 1218 1219 int irc_privmsg( irc_t *irc, user_t *u, char *type, char *to, char *prefix, char *msg ) 1220 { 1221 char last = 0; 1222 char *s = msg, *line = msg; 1223 1224 /* The almighty linesplitter .. woohoo!! */ 1225 while( !last ) 1226 { 1227 if( *s == '\r' && *(s+1) == '\n' ) 1228 *(s++) = 0; 1229 if( *s == '\n' ) 1230 { 1231 last = s[1] == 0; 1232 *s = 0; 1233 } 1234 else 1235 { 1236 last = s[0] == 0; 1237 } 1238 if( *s == 0 ) 1239 { 1240 if( g_strncasecmp( line, "/me ", 4 ) == 0 && ( !prefix || !*prefix ) && g_strcasecmp( type, "PRIVMSG" ) == 0 ) 1241 { 1242 irc_write( irc, ":%s!%s@%s %s %s :\001ACTION %s\001", u->nick, u->user, u->host, 1243 type, to, line + 4 ); 1244 } 1245 else 1246 { 1247 irc_write( irc, ":%s!%s@%s %s %s :%s%s", u->nick, u->user, u->host, 1248 type, to, prefix ? prefix : "", line ); 1249 } 1250 line = s + 1; 1251 } 1252 s ++; 1253 } 1254 1255 return( 1 ); 1256 } 1257 1258 int irc_msgfrom( irc_t *irc, char *nick, char *msg ) 1259 { 1260 user_t *u = user_find( irc, nick ); 1261 static char *prefix = NULL; 1262 1263 if( !u ) return( 0 ); 1264 if( prefix && *prefix ) g_free( prefix ); 1265 1266 if( !u->is_private && nick_cmp( u->nick, irc->mynick ) != 0 ) 1267 { 1268 int len = strlen( irc->nick) + 3; 1269 prefix = g_new (char, len ); 1270 g_snprintf( prefix, len, "%s%s", irc->nick, set_getstr( &irc->set, "to_char" ) ); 1271 prefix[len-1] = 0; 1272 } 1273 else 1274 { 1275 prefix = ""; 1276 } 1277 1278 return( irc_privmsg( irc, u, "PRIVMSG", u->is_private ? irc->nick : irc->channel, prefix, msg ) ); 1279 } 1280 1281 int irc_noticefrom( irc_t *irc, char *nick, char *msg ) 1282 { 1283 user_t *u = user_find( irc, nick ); 1284 1285 if( u ) 1286 return( irc_privmsg( irc, u, "NOTICE", irc->nick, "", msg ) ); 1287 else 1288 return( 0 ); 1289 } 1290 1291 /* Returns 0 if everything seems to be okay, a number >0 when there was a 1292 timeout. The number returned is the number of seconds we received no 1293 pongs from the user. When not connected yet, we don't ping but drop the 1294 connection when the user fails to connect in IRC_LOGIN_TIMEOUT secs. */ 1295 static gboolean irc_userping( gpointer _irc, gint fd, b_input_condition cond ) 1296 { 1297 irc_t *irc = _irc; 1298 int rv = 0; 1299 1300 if( !( irc->status & USTATUS_LOGGED_IN ) ) 1301 { 1302 if( gettime() > ( irc->last_pong + IRC_LOGIN_TIMEOUT ) ) 1303 rv = gettime() - irc->last_pong; 1304 } 1305 else 1306 { 1307 if( ( gettime() > ( irc->last_pong + global.conf->ping_interval ) ) && !irc->pinging ) 1308 { 1309 irc_write( irc, "PING :%s", IRC_PING_STRING ); 1310 irc->pinging = 1; 1311 } 1312 else if( gettime() > ( irc->last_pong + global.conf->ping_timeout ) ) 1313 { 1314 rv = gettime() - irc->last_pong; 1315 } 1316 } 1317 1318 if( rv > 0 ) 1319 { 1320 irc_abort( irc, 0, "Ping Timeout: %d seconds", rv ); 1321 return FALSE; 1322 } 1323 1324 return TRUE; 1325 } 1326 1327 struct groupchat *irc_chat_by_channel( irc_t *irc, char *channel ) 1328 { 1329 struct groupchat *c; 1330 account_t *a; 1331 1332 /* This finds the connection which has a conversation which belongs to this channel */ 1333 for( a = irc->accounts; a; a = a->next ) 1334 { 1335 if( a->ic == NULL ) 1336 continue; 1337 1338 c = a->ic->groupchats; 1339 while( c ) 1340 { 1341 if( c->channel && g_strcasecmp( c->channel, channel ) == 0 ) 1342 return c; 1343 1344 c = c->next; 1345 } 1346 } 1347 1348 return NULL; 1349 } 593 594 595 static char *set_eval_charset( set_t *set, char *value ) 596 { 597 irc_t *irc = set->data; 598 GIConv ic, oc; 599 600 if( g_strcasecmp( value, "none" ) == 0 ) 601 value = g_strdup( "utf-8" ); 602 603 if( ( ic = g_iconv_open( "utf-8", value ) ) == (GIConv) -1 ) 604 { 605 return NULL; 606 } 607 if( ( oc = g_iconv_open( value, "utf-8" ) ) == (GIConv) -1 ) 608 { 609 g_iconv_close( ic ); 610 return NULL; 611 } 612 613 if( irc->iconv != (GIConv) -1 ) 614 g_iconv_close( irc->iconv ); 615 if( irc->oconv != (GIConv) -1 ) 616 g_iconv_close( irc->oconv ); 617 618 irc->iconv = ic; 619 irc->oconv = oc; 620 621 return value; 622 } -
irc.h
rba7d16f r3ddb7477 5 5 \********************************************************************/ 6 6 7 /* The big hairy IRCd part of the project*/7 /* The IRC-based UI (for now the only one) */ 8 8 9 9 /* … … 49 49 } irc_status_t; 50 50 51 struct irc_user; 52 51 53 typedef struct irc 52 54 { … … 59 61 GIConv iconv, oconv; 60 62 61 int sentbytes;62 time_t oldtime;63 struct irc_user *root; 64 struct irc_user *user; 63 65 64 char *nick;65 char *user;66 char *host;67 char *realname;68 66 char *password; /* HACK: Used to save the user's password, but before 69 67 logging in, this may contain a password we should … … 72 70 char umode[8]; 73 71 74 char *myhost;75 char *mynick;76 77 char *channel;78 int c_id;79 80 char is_private; /* Not too nice... */81 char *last_target;82 83 72 struct query *queries; 84 73 struct account *accounts; … … 86 75 struct chat *chatrooms; 87 76 88 struct __USER*users;89 GHashTable * userhash;77 GSList *users; 78 GHashTable *nick_user_hash; 90 79 GHashTable *watches; 91 struct __NICK *nicks;92 struct set *set;93 80 94 81 gint r_watch_source_id; 95 82 gint w_watch_source_id; 96 83 gint ping_source_id; 84 85 struct bee *b; 97 86 } irc_t; 87 88 typedef struct irc_user 89 { 90 char *nick; 91 char *user; 92 char *host; 93 char *fullname; 94 95 /* Nickname in lowercase for case sensitive searches */ 96 char *key; 97 98 char is_private; 99 100 char *sendbuf; 101 int sendbuf_len; 102 guint sendbuf_timer; 103 int sendbuf_flags; 104 105 //struct user *b; 106 } irc_user_t; 98 107 99 108 #include "user.h" 100 109 110 /* irc.c */ 101 111 extern GSList *irc_connection_list; 102 112 … … 105 115 void irc_free( irc_t *irc ); 106 116 107 void irc_exec( irc_t *irc, char **cmd );108 117 void irc_process( irc_t *irc ); 109 118 char **irc_parse_line( char *line ); 110 119 char *irc_build_line( char **cmd ); 111 120 112 void irc_vawrite( irc_t *irc, char *format, va_list params );113 121 void irc_write( irc_t *irc, char *format, ... ) G_GNUC_PRINTF( 2, 3 ); 114 122 void irc_write_all( int now, char *format, ... ) G_GNUC_PRINTF( 2, 3 ); 115 void irc_reply( irc_t *irc, int code, char *format, ... ) G_GNUC_PRINTF( 3, 4 ); 116 G_MODULE_EXPORT int irc_usermsg( irc_t *irc, char *format, ... ) G_GNUC_PRINTF( 2, 3 ); 117 char **irc_tokenize( char *buffer ); 123 void irc_vawrite( irc_t *irc, char *format, va_list params ); 118 124 119 void irc_login( irc_t *irc );120 125 int irc_check_login( irc_t *irc ); 121 void irc_motd( irc_t *irc );122 void irc_names( irc_t *irc, char *channel );123 void irc_topic( irc_t *irc, char *channel );124 void irc_umode_set( irc_t *irc, char *s, int allow_priv );125 void irc_who( irc_t *irc, char *channel );126 void irc_spawn( irc_t *irc, user_t *u );127 void irc_join( irc_t *irc, user_t *u, char *channel );128 void irc_part( irc_t *irc, user_t *u, char *channel );129 void irc_kick( irc_t *irc, user_t *u, char *channel, user_t *kicker );130 void irc_kill( irc_t *irc, user_t *u );131 void irc_invite( irc_t *irc, char *nick, char *channel );132 void irc_whois( irc_t *irc, char *nick );133 void irc_setpass( irc_t *irc, const char *pass ); /* USE WITH CAUTION! */134 126 135 int irc_send( irc_t *irc, char *nick, char *s, int flags ); 136 int irc_privmsg( irc_t *irc, user_t *u, char *type, char *to, char *prefix, char *msg ); 137 int irc_msgfrom( irc_t *irc, char *nick, char *msg ); 138 int irc_noticefrom( irc_t *irc, char *nick, char *msg ); 127 /* irc_commands.c */ 128 void irc_exec( irc_t *irc, char **cmd ); 139 129 140 void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags ); 141 struct groupchat *irc_chat_by_channel( irc_t *irc, char *channel ); 130 /* irc_send.c */ 131 void irc_send_num( irc_t *irc, int code, char *format, ... ) G_GNUC_PRINTF( 3, 4 ); 132 void irc_send_login( irc_t *irc ); 133 void irc_send_motd( irc_t *irc ); 134 int irc_usermsg( irc_t *irc, char *format, ... ); 135 136 /* irc_user.c */ 137 irc_user_t *irc_user_new( irc_t *irc, const char *nick ); 138 int irc_user_free( irc_t *irc, const char *nick ); 139 irc_user_t *irc_user_find( irc_t *irc, const char *nick ); 140 int irc_user_rename( irc_t *irc, const char *old, const char *new ); 142 141 143 142 #endif -
irc_commands.c
rba7d16f r3ddb7477 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * 4 * Copyright 2002-20 06Wilmer van der Gaast and others *4 * Copyright 2002-2010 Wilmer van der Gaast and others * 5 5 \********************************************************************/ 6 6 … … 39 39 out we don't require it, which will break this feature.) 40 40 Try to identify using the given password. */ 41 return root_command( irc, send_cmd );41 /*return root_command( irc, send_cmd );*/ 42 42 } 43 43 /* Handling in pre-logged-in state, first see if this server is … … 53 53 else if( global.conf->auth_pass ) 54 54 { 55 irc_ reply( irc, 464, ":Incorrect password" );55 irc_send_num( irc, 464, ":Incorrect password" ); 56 56 } 57 57 else 58 58 { 59 59 /* Remember the password and try to identify after USER/NICK. */ 60 irc_setpass( irc, cmd[1] );60 /*irc_setpass( irc, cmd[1] ); */ 61 61 irc_check_login( irc ); 62 62 } … … 65 65 static void irc_cmd_user( irc_t *irc, char **cmd ) 66 66 { 67 irc->user = g_strdup( cmd[1] );68 irc-> realname = g_strdup( cmd[4] );67 irc->user->user = g_strdup( cmd[1] ); 68 irc->user->fullname = g_strdup( cmd[4] ); 69 69 70 70 irc_check_login( irc ); … … 73 73 static void irc_cmd_nick( irc_t *irc, char **cmd ) 74 74 { 75 if( irc->nick ) 76 { 77 irc_reply( irc, 438, ":The hand of the deity is upon thee, thy nick may not change" ); 78 } 79 /* This is not clean, but for now it'll have to be like this... */ 80 else if( ( nick_cmp( cmd[1], irc->mynick ) == 0 ) || ( nick_cmp( cmd[1], NS_NICK ) == 0 ) ) 81 { 82 irc_reply( irc, 433, ":This nick is already in use" ); 75 if( irc->user->nick ) 76 { 77 irc_send_num( irc, 438, ":The hand of the deity is upon thee, thy nick may not change" ); 78 } 79 else if( irc_user_find( irc, cmd[1] ) ) 80 { 81 irc_send_num( irc, 433, ":This nick is already in use" ); 83 82 } 84 83 else if( !nick_ok( cmd[1] ) ) 85 84 { 86 85 /* [SH] Invalid characters. */ 87 irc_ reply( irc, 432, ":This nick contains invalid characters" );88 } 89 else 90 { 91 irc-> nick = g_strdup( cmd[1] );86 irc_send_num( irc, 432, ":This nick contains invalid characters" ); 87 } 88 else 89 { 90 irc->user->nick = g_strdup( cmd[1] ); 92 91 93 92 irc_check_login( irc ); … … 95 94 } 96 95 96 #if 0 97 97 static void irc_cmd_quit( irc_t *irc, char **cmd ) 98 98 { … … 116 116 { 117 117 irc_umode_set( irc, "+o", 1 ); 118 irc_ reply( irc, 381, ":Password accepted" );119 } 120 else 121 { 122 irc_ reply( irc, 432, ":Incorrect password" );118 irc_send_num( irc, 381, ":Password accepted" ); 119 } 120 else 121 { 122 irc_send_num( irc, 432, ":Incorrect password" ); 123 123 } 124 124 } … … 131 131 { 132 132 if( *cmd[2] == '+' || *cmd[2] == '-' ) 133 irc_ reply( irc, 477, "%s :Can't change channel modes", cmd[1] );133 irc_send_num( irc, 477, "%s :Can't change channel modes", cmd[1] ); 134 134 else if( *cmd[2] == 'b' ) 135 irc_ reply( irc, 368, "%s :No bans possible", cmd[1] );135 irc_send_num( irc, 368, "%s :No bans possible", cmd[1] ); 136 136 } 137 137 else 138 irc_ reply( irc, 324, "%s +%s", cmd[1], CMODE );138 irc_send_num( irc, 324, "%s +%s", cmd[1], CMODE ); 139 139 } 140 140 else … … 145 145 irc_umode_set( irc, cmd[2], 0 ); 146 146 else 147 irc_ reply( irc, 221, "+%s", irc->umode );147 irc_send_num( irc, 221, "+%s", irc->umode ); 148 148 } 149 149 else 150 irc_ reply( irc, 502, ":Don't touch their modes" );150 irc_send_num( irc, 502, ":Don't touch their modes" ); 151 151 } 152 152 } … … 183 183 else 184 184 { 185 irc_ reply( irc, 403, "%s :No such channel", cmd[1] );185 irc_send_num( irc, 403, "%s :No such channel", cmd[1] ); 186 186 } 187 187 } … … 197 197 198 198 if( strchr( CTYPES, cmd[1][0] ) == NULL || cmd[1][1] == 0 ) 199 irc_ reply( irc, 479, "%s :Invalid channel name", cmd[1] );199 irc_send_num( irc, 479, "%s :Invalid channel name", cmd[1] ); 200 200 else if( ( c = chat_bychannel( irc, cmd[1] ) ) && c->acc && c->acc->ic ) 201 201 chat_join( irc, c, cmd[2] ); 202 202 else 203 irc_ reply( irc, 403, "%s :No such channel", cmd[1] );203 irc_send_num( irc, 403, "%s :No such channel", cmd[1] ); 204 204 } 205 205 } … … 215 215 { 216 216 c->ic->acc->prpl->chat_invite( c, u->handle, NULL ); 217 irc_ reply( irc, 341, "%s %s", nick, channel );217 irc_send_num( irc, 341, "%s %s", nick, channel ); 218 218 return; 219 219 } 220 220 221 irc_ reply( irc, 482, "%s :Invite impossible; User/Channel non-existent or incompatible", channel );221 irc_send_num( irc, 482, "%s :Invite impossible; User/Channel non-existent or incompatible", channel ); 222 222 } 223 223 … … 226 226 if ( !cmd[2] ) 227 227 { 228 irc_ reply( irc, 412, ":No text to send" );228 irc_send_num( irc, 412, ":No text to send" ); 229 229 } 230 230 else if ( irc->nick && g_strcasecmp( cmd[1], irc->nick ) == 0 ) … … 283 283 while( u ) 284 284 { 285 irc_ reply( irc, 352, "%s %s %s %s %s %c :0 %s", u->online ? irc->channel : "*", u->user, u->host, irc->myhost, u->nick, u->online ? ( u->away ? 'G' : 'H' ) : 'G', u->realname );285 irc_send_num( irc, 352, "%s %s %s %s %s %c :0 %s", u->online ? irc->channel : "*", u->user, u->host, irc->myhost, u->nick, u->online ? ( u->away ? 'G' : 'H' ) : 'G', u->realname ); 286 286 u = u->next; 287 287 } … … 290 290 { 291 291 if( u->online ) 292 irc_ reply( irc, 352, "%s %s %s %s %s %c :0 %s", channel, u->user, u->host, irc->myhost, u->nick, u->away ? 'G' : 'H', u->realname );292 irc_send_num( irc, 352, "%s %s %s %s %s %c :0 %s", channel, u->user, u->host, irc->myhost, u->nick, u->away ? 'G' : 'H', u->realname ); 293 293 u = u->next; 294 294 } … … 297 297 { 298 298 if( ( u = user_findhandle( c->ic, l->data ) ) ) 299 irc_ reply( irc, 352, "%s %s %s %s %s %c :0 %s", channel, u->user, u->host, irc->myhost, u->nick, u->away ? 'G' : 'H', u->realname );299 irc_send_num( irc, 352, "%s %s %s %s %s %c :0 %s", channel, u->user, u->host, irc->myhost, u->nick, u->away ? 'G' : 'H', u->realname ); 300 300 } 301 301 else if( ( u = user_find( irc, channel ) ) ) 302 irc_ reply( irc, 352, "%s %s %s %s %s %c :0 %s", channel, u->user, u->host, irc->myhost, u->nick, u->online ? ( u->away ? 'G' : 'H' ) : 'G', u->realname );303 304 irc_ reply( irc, 315, "%s :End of /WHO list", channel?channel:"**" );302 irc_send_num( irc, 352, "%s %s %s %s %s %c :0 %s", channel, u->user, u->host, irc->myhost, u->nick, u->online ? ( u->away ? 'G' : 'H' ) : 'G', u->realname ); 303 304 irc_send_num( irc, 315, "%s :End of /WHO list", channel?channel:"**" ); 305 305 } 306 306 … … 320 320 { 321 321 if( u->online && u->away ) 322 irc_ reply( irc, 302, ":%s=-%s@%s", u->nick, u->user, u->host );322 irc_send_num( irc, 302, ":%s=-%s@%s", u->nick, u->user, u->host ); 323 323 else 324 irc_ reply( irc, 302, ":%s=+%s@%s", u->nick, u->user, u->host );324 irc_send_num( irc, 302, ":%s=+%s@%s", u->nick, u->user, u->host ); 325 325 } 326 326 } … … 377 377 buff[strlen(buff)-1] = '\0'; 378 378 379 irc_ reply( irc, 303, ":%s", buff );379 irc_send_num( irc, 303, ":%s", buff ); 380 380 } 381 381 … … 406 406 407 407 if( u && u->online ) 408 irc_ reply( irc, 604, "%s %s %s %d :%s", u->nick, u->user, u->host, (int) time( NULL ), "is online" );408 irc_send_num( irc, 604, "%s %s %s %d :%s", u->nick, u->user, u->host, (int) time( NULL ), "is online" ); 409 409 else 410 irc_ reply( irc, 605, "%s %s %s %d :%s", nick, "*", "*", (int) time( NULL ), "is offline" );410 irc_send_num( irc, 605, "%s %s %s %d :%s", nick, "*", "*", (int) time( NULL ), "is offline" ); 411 411 } 412 412 else if( cmd[i][0] == '-' ) … … 419 419 g_free( okey ); 420 420 421 irc_ reply( irc, 602, "%s %s %s %d :%s", nick, "*", "*", 0, "Stopped watching" );421 irc_send_num( irc, 602, "%s %s %s %d :%s", nick, "*", "*", 0, "Stopped watching" ); 422 422 } 423 423 } … … 463 463 u->away[j] = 0; 464 464 465 irc_ reply( irc, 306, ":You're now away: %s", u->away );465 irc_send_num( irc, 306, ":You're now away: %s", u->away ); 466 466 /* irc_umode_set( irc, irc->myhost, "+a" ); */ 467 467 } … … 471 471 u->away = NULL; 472 472 /* irc_umode_set( irc, irc->myhost, "-a" ); */ 473 irc_ reply( irc, 305, ":Welcome back" );473 irc_send_num( irc, 305, ":Welcome back" ); 474 474 } 475 475 … … 484 484 if( u ) 485 485 { 486 irc_ reply( irc, 311, "%s %s %s * :%s", u->nick, u->user, u->host, u->realname );486 irc_send_num( irc, 311, "%s %s %s * :%s", u->nick, u->user, u->host, u->realname ); 487 487 488 488 if( u->ic ) 489 irc_ reply( irc, 312, "%s %s.%s :%s network", u->nick, u->ic->acc->user,489 irc_send_num( irc, 312, "%s %s.%s :%s network", u->nick, u->ic->acc->user, 490 490 u->ic->acc->server && *u->ic->acc->server ? u->ic->acc->server : "", 491 491 u->ic->acc->prpl->name ); 492 492 else 493 irc_ reply( irc, 312, "%s %s :%s", u->nick, irc->myhost, IRCD_INFO );493 irc_send_num( irc, 312, "%s %s :%s", u->nick, irc->myhost, IRCD_INFO ); 494 494 495 495 if( !u->online ) 496 irc_ reply( irc, 301, "%s :%s", u->nick, "User is offline" );496 irc_send_num( irc, 301, "%s :%s", u->nick, "User is offline" ); 497 497 else if( u->away ) 498 irc_ reply( irc, 301, "%s :%s", u->nick, u->away );498 irc_send_num( irc, 301, "%s :%s", u->nick, u->away ); 499 499 if( u->status_msg ) 500 irc_ reply( irc, 333, "%s :Status: %s", u->nick, u->status_msg );501 502 irc_ reply( irc, 318, "%s :End of /WHOIS list", nick );503 } 504 else 505 { 506 irc_ reply( irc, 401, "%s :Nick does not exist", nick );500 irc_send_num( irc, 333, "%s :Status: %s", u->nick, u->status_msg ); 501 502 irc_send_num( irc, 318, "%s :End of /WHOIS list", nick ); 503 } 504 else 505 { 506 irc_send_num( irc, 401, "%s :Nick does not exist", nick ); 507 507 } 508 508 } … … 515 515 with not-found and irssi users will get better error messages */ 516 516 517 irc_ reply( irc, 406, "%s :Nick does not exist", cmd[1] );518 irc_ reply( irc, 369, "%s :End of WHOWAS", cmd[1] );517 irc_send_num( irc, 406, "%s :Nick does not exist", cmd[1] ); 518 irc_send_num( irc, 369, "%s :End of WHOWAS", cmd[1] ); 519 519 } 520 520 … … 541 541 static void irc_cmd_version( irc_t *irc, char **cmd ) 542 542 { 543 irc_ reply( irc, 351, "bitlbee-%s. %s :%s/%s ", BITLBEE_VERSION, irc->myhost, ARCH, CPU );543 irc_send_num( irc, 351, "bitlbee-%s. %s :%s/%s ", BITLBEE_VERSION, irc->myhost, ARCH, CPU ); 544 544 } 545 545 … … 572 572 ipc_to_master( cmd ); 573 573 574 irc_reply( irc, 382, "%s :Rehashing", global.conf_file ); 575 } 574 irc_send_num( irc, 382, "%s :Rehashing", global.conf_file ); 575 } 576 #endif 576 577 577 578 static const command_t irc_commands[] = { … … 579 580 { "user", 4, irc_cmd_user, IRC_CMD_PRE_LOGIN }, 580 581 { "nick", 1, irc_cmd_nick, 0 }, 582 #if 0 581 583 { "quit", 0, irc_cmd_quit, 0 }, 582 584 { "ping", 0, irc_cmd_ping, 0 }, … … 610 612 { "restart", 0, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, 611 613 { "kill", 2, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, 614 #endif 612 615 { NULL } 613 616 }; … … 628 631 if( irc_commands[i].flags & IRC_CMD_PRE_LOGIN && irc->status & USTATUS_LOGGED_IN ) 629 632 { 630 irc_ reply( irc, 462, ":Only allowed before logging in" );633 irc_send_num( irc, 462, ":Only allowed before logging in" ); 631 634 } 632 635 else if( irc_commands[i].flags & IRC_CMD_LOGGED_IN && !( irc->status & USTATUS_LOGGED_IN ) ) 633 636 { 634 irc_ reply( irc, 451, ":Register first" );637 irc_send_num( irc, 451, ":Register first" ); 635 638 } 636 639 else if( irc_commands[i].flags & IRC_CMD_OPER_ONLY && !strchr( irc->umode, 'o' ) ) 637 640 { 638 irc_ reply( irc, 481, ":Permission denied - You're not an IRC operator" );641 irc_send_num( irc, 481, ":Permission denied - You're not an IRC operator" ); 639 642 } 640 643 else if( n_arg < irc_commands[i].required_parameters ) 641 644 { 642 irc_ reply( irc, 461, "%s :Need more parameters", cmd[0] );645 irc_send_num( irc, 461, "%s :Need more parameters", cmd[0] ); 643 646 } 644 647 else if( irc_commands[i].flags & IRC_CMD_TO_MASTER ) … … 657 660 658 661 if( irc->status >= USTATUS_LOGGED_IN ) 659 irc_ reply( irc, 421, "%s :Unknown command", cmd[0] );660 } 662 irc_send_num( irc, 421, "%s :Unknown command", cmd[0] ); 663 } -
nick.c
rba7d16f r3ddb7477 78 78 79 79 nick_strip( nick ); 80 if( set_getbool( &acc->irc-> set, "lcnicks" ) )80 if( set_getbool( &acc->irc->b->set, "lcnicks" ) ) 81 81 nick_lc( nick ); 82 82 } … … 96 96 /* Now, find out if the nick is already in use at the moment, and make 97 97 subtle changes to make it unique. */ 98 while( !nick_ok( nick ) || user_find( acc->irc, nick ) )98 while( !nick_ok( nick ) || irc_user_find( acc->irc, nick ) ) 99 99 { 100 100 if( strlen( nick ) < ( MAX_NICK_LENGTH - 1 ) ) -
protocols/Makefile
rba7d16f r3ddb7477 10 10 11 11 # [SH] Program variables 12 objects = nogaim.o 12 #objects = account.o nogaim.o user.o 13 objects = bee.o 14 13 15 14 16 # [SH] The next two lines should contain the directory name (in $(subdirs)) -
protocols/account.c
rba7d16f r3ddb7477 336 336 int account_reconnect_delay( account_t *a ) 337 337 { 338 char *setting = set_getstr( &a->irc-> set, "auto_reconnect_delay" );338 char *setting = set_getstr( &a->irc->b->set, "auto_reconnect_delay" ); 339 339 struct account_reconnect_delay p; 340 340 -
protocols/user.c
rba7d16f r3ddb7477 37 37 if( user_find( irc, nick ) != NULL ) 38 38 return( NULL ); 39 40 if( ( u = irc->users ) )41 {42 while( u )43 {44 if( nick_cmp( nick, u->nick ) < 0 )45 break;46 47 lu = u;48 u = u->next;49 }50 51 u = g_new0( user_t, 1 );52 if( lu )53 {54 u->next = lu->next;55 lu->next = u;56 }57 else58 {59 u->next = irc->users;60 irc->users = u;61 }62 }63 else64 {65 irc->users = u = g_new0( user_t, 1 );66 }67 68 u->user = u->realname = u->host = u->nick = g_strdup( nick );69 u->is_private = set_getbool( &irc->set, "private" );70 71 key = g_strdup( nick );72 nick_lc( key );73 g_hash_table_insert( irc->userhash, key, u );74 39 75 40 return( u ); … … 113 78 g_free( u ); 114 79 115 if( !g_hash_table_lookup_extended( irc->userhash, key, &okey, &ovalue ) || ovalue != u )116 {117 g_free( key );118 return( 1 ); /* Although this is a severe error, the user is removed from the list... */119 }120 g_hash_table_remove( irc->userhash, key );121 g_free( key );122 g_free( okey );123 124 80 return( 1 ); 125 81 } … … 128 84 129 85 return( 0 ); 130 }131 132 user_t *user_find( irc_t *irc, char *nick )133 {134 char key[512] = "";135 136 strncpy( key, nick, sizeof( key ) - 1 );137 if( nick_lc( key ) )138 return( g_hash_table_lookup( irc->userhash, key ) );139 else140 return( NULL );141 86 } 142 87 … … 160 105 return NULL; 161 106 } 162 163 /* DO NOT PASS u->nick FOR oldnick !!! */164 void user_rename( irc_t *irc, char *oldnick, char *newnick )165 {166 user_t *u = user_find( irc, oldnick );167 gpointer okey, ovalue;168 char *key;169 170 if( !u ) return; /* Should've been checked by the caller... */171 172 g_free( u->nick );173 if( u->nick == u->user ) u->user = NULL;174 if( u->nick == u->host ) u->host = NULL;175 if( u->nick == u->realname ) u->realname = NULL;176 u->nick = g_strdup( newnick );177 if( !u->user ) u->user = u->nick;178 if( !u->host ) u->host = u->nick;179 if( !u->realname ) u->realname = u->nick;180 181 /* Remove the old reference to this user from the hash and create a182 new one with the new nick. This is indeed a bit messy. */183 key = g_strdup( oldnick );184 nick_lc( key );185 if( !g_hash_table_lookup_extended( irc->userhash, key, &okey, &ovalue ) || ovalue != u )186 {187 g_free( key );188 return; /* This really shouldn't happen! */189 }190 g_hash_table_remove( irc->userhash, key );191 g_free( key );192 g_free( okey );193 194 key = g_strdup( newnick );195 nick_lc( key );196 g_hash_table_insert( irc->userhash, key, u );197 198 /* Also, let's try to keep the linked list nicely sorted. Fear this199 code. If my teacher would see this, she would cry. ;-) */200 {201 user_t *u1, *lu1;202 203 /* Remove the user from the old position in the chain. */204 if( u == irc->users )205 {206 irc->users = u->next;207 }208 else209 {210 u1 = u;211 for( lu1 = irc->users; lu1->next != u1; lu1 = lu1->next );212 lu1->next = u1->next;213 }214 215 /* Search for the new position. */216 for( lu1 = NULL, u1 = irc->users; u1; u1 = u1->next )217 {218 if( nick_cmp( newnick, u1->nick ) < 0 )219 break;220 221 lu1 = u1;222 }223 224 /* Insert it at this new position. */225 u->next = u1;226 if( lu1 )227 lu1->next = u;228 else229 irc->users = u;230 }231 } -
protocols/user.h
rba7d16f r3ddb7477 23 23 Suite 330, Boston, MA 02111-1307 USA 24 24 */ 25 25 26 #ifndef __USER_H__ 26 27 #define __USER_H__ 27 28 28 typedefstruct __USER29 struct __USER 29 30 { 30 char *nick;31 char * user;32 char * host;33 char * realname;34 31 struct im_connection *ic; 32 char *handle; 33 char *fullname; 34 char *group; 35 35 36 char *away; 36 char *status_msg; /* Non-IRC extension, but nice on IM. */ 37 38 char is_private; 39 char online; 40 41 char *handle; 42 char *group; 43 struct im_connection *ic; 44 45 char *sendbuf; 46 time_t last_typing_notice; 47 int sendbuf_len; 48 guint sendbuf_timer; 49 int sendbuf_flags; 50 51 void (*send_handler) ( irc_t *irc, struct __USER *u, char *msg, int flags ); 52 53 struct __USER *next; 37 char *status_msg; 54 38 } user_t; 55 39 56 user_t *user_add( struct irc *irc, char *nick );57 int user_del( irc_t *irc, char *nick );58 G_MODULE_EXPORT user_t *user_find( irc_t *irc, char *nick );59 G_MODULE_EXPORT user_t *user_findhandle( struct im_connection *ic, const char *handle );60 void user_rename( irc_t *irc, char *oldnick, char *newnick );61 62 40 #endif /* __USER_H__ */ -
set.c
rba7d16f r3ddb7477 225 225 } 226 226 227 /* 227 228 char *set_eval_ops( set_t *set, char *value ) 228 229 { … … 246 247 return value; 247 248 } 249 */ -
unix.c
rba7d16f r3ddb7477 62 62 63 63 b_main_init(); 64 nogaim_init();64 //nogaim_init(); 65 65 66 66 srand( time( NULL ) ^ getpid() ); … … 115 115 } 116 116 117 /* 117 118 global.storage = storage_init( global.conf->primary_storage, global.conf->migrate_storage ); 118 119 if( global.storage == NULL ) … … 121 122 return( 1 ); 122 123 } 124 */ 123 125 124 126 /* Catch some signals to tell the user what's happening before quitting */
Note: See TracChangeset
for help on using the changeset viewer.