Changes in / [3ab1d31:a87e6ba]
- Files:
-
- 12 added
- 6 deleted
- 27 edited
Legend:
- Unmodified
- Added
- Removed
-
Makefile
r3ab1d31 ra87e6ba 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 dcc.o help.o ipc.o irc.o irc_im.o irc_channel.o irc_commands.o irc_send.o irc_user.o nick.o root_commands.o set.o storage.o $(STORAGE_OBJS) 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
r3ab1d31 ra87e6ba 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, char *command ); 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
r3ab1d31 ra87e6ba 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 ) -
dcc.c
r3ab1d31 ra87e6ba 61 61 unsigned int receivedchunks=0, receiveddata=0; 62 62 63 staticvoid dcc_finish( file_transfer_t *file );64 staticvoid dcc_close( file_transfer_t *file );63 void dcc_finish( file_transfer_t *file ); 64 void dcc_close( file_transfer_t *file ); 65 65 gboolean dccs_send_proto( gpointer data, gint fd, b_input_condition cond ); 66 int dccs_send_request( struct dcc_file_transfer *df, char *user_nick, struct sockaddr_storage *saddr ); 67 gboolean dccs_recv_start( file_transfer_t *ft ); 66 int dccs_send_request( struct dcc_file_transfer *df, irc_user_t *iu, struct sockaddr_storage *saddr ); 68 67 gboolean dccs_recv_proto( gpointer data, gint fd, b_input_condition cond); 69 68 gboolean dccs_recv_write_request( file_transfer_t *ft ); … … 71 70 gboolean dcc_abort( dcc_file_transfer_t *df, char *reason, ... ); 72 71 73 /* As defined in ft.h */ 74 file_transfer_t *imcb_file_send_start( struct im_connection *ic, char *handle, char *file_name, size_t file_size ) 75 { 76 user_t *u = user_findhandle( ic, handle ); 77 /* one could handle this more intelligent like imcb_buddy_msg. 78 * can't call it directly though cause it does some wrapping. 79 * Maybe give imcb_buddy_msg a parameter NO_WRAPPING? */ 80 if (!u) return NULL; 81 82 return dccs_send_start( ic, u->nick, file_name, file_size ); 83 }; 84 85 /* As defined in ft.h */ 86 void imcb_file_canceled( file_transfer_t *file, char *reason ) 87 { 88 if( file->canceled ) 89 file->canceled( file, reason ); 90 91 dcc_close( file ); 92 } 93 94 /* As defined in ft.h */ 95 gboolean imcb_file_recv_start( file_transfer_t *ft ) 96 { 97 return dccs_recv_start( ft ); 98 } 99 100 /* As defined in ft.h */ 101 void imcb_file_finished( file_transfer_t *file ) 102 { 103 dcc_file_transfer_t *df = file->priv; 104 105 if( file->bytes_transferred >= file->file_size ) 106 dcc_finish( file ); 107 else 108 df->proto_finished = TRUE; 109 } 110 111 dcc_file_transfer_t *dcc_alloc_transfer( char *file_name, size_t file_size, struct im_connection *ic ) 72 dcc_file_transfer_t *dcc_alloc_transfer( const char *file_name, size_t file_size, struct im_connection *ic ) 112 73 { 113 74 file_transfer_t *file = g_new0( file_transfer_t, 1 ); … … 124 85 125 86 /* This is where the sending magic starts... */ 126 file_transfer_t *dccs_send_start( struct im_connection *ic, char *user_nick,char *file_name, size_t file_size )87 file_transfer_t *dccs_send_start( struct im_connection *ic, irc_user_t *iu, const char *file_name, size_t file_size ) 127 88 { 128 89 file_transfer_t *file; 129 90 dcc_file_transfer_t *df; 91 irc_t *irc = (irc_t *) ic->bee->ui_data; 130 92 struct sockaddr_storage saddr; 131 93 char *errmsg; … … 150 112 file->status = FT_STATUS_LISTENING; 151 113 152 if( !dccs_send_request( df, user_nick, &saddr ) )114 if( !dccs_send_request( df, iu, &saddr ) ) 153 115 return NULL; 154 116 … … 156 118 df->watch_in = b_input_add( df->fd, GAIM_INPUT_READ, dccs_send_proto, df ); 157 119 158 df->ic->irc->file_transfers = g_slist_prepend( df->ic->irc->file_transfers, file );120 irc->file_transfers = g_slist_prepend( irc->file_transfers, file ); 159 121 160 122 df->progress_timeout = b_timeout_add( DCC_MAX_STALL * 1000, dcc_progress, df ); … … 163 125 "Accept the file transfer if you'd like the file. If you don't, " 164 126 "issue the 'transfers reject' command.", 165 user_nick, file_name, file_size / 1024 );127 iu->nick, file_name, file_size / 1024 ); 166 128 167 129 return file; … … 216 178 217 179 /* Creates the "DCC SEND" line and sends it to the server */ 218 int dccs_send_request( struct dcc_file_transfer *df, char *user_nick, struct sockaddr_storage *saddr )180 int dccs_send_request( struct dcc_file_transfer *df, irc_user_t *iu, struct sockaddr_storage *saddr ) 219 181 { 220 182 char ipaddr[INET6_ADDRSTRLEN]; … … 250 212 df->ft->file_name, ipaddr, port, df->ft->file_size ); 251 213 252 if ( !irc_msgfrom( df->ic->irc, user_nick, cmd ) ) 253 return dcc_abort( df, "Couldn't send `DCC SEND' message to %s.", user_nick ); 214 irc_send_msg_raw( iu, "PRIVMSG", iu->irc->user->nick, cmd ); 254 215 255 216 g_free( cmd ); … … 496 457 * Cleans up after a transfer. 497 458 */ 498 staticvoid dcc_close( file_transfer_t *file )459 void dcc_close( file_transfer_t *file ) 499 460 { 500 461 dcc_file_transfer_t *df = file->priv; 462 irc_t *irc = (irc_t *) df->ic->bee->ui_data; 501 463 502 464 if( file->free ) … … 514 476 b_event_remove( df->progress_timeout ); 515 477 516 df->ic->irc->file_transfers = g_slist_remove( df->ic->irc->file_transfers, file );478 irc->file_transfers = g_slist_remove( irc->file_transfers, file ); 517 479 518 480 g_free( df ); … … 544 506 file_transfer_t *dcc_request( struct im_connection *ic, char *line ) 545 507 { 508 irc_t *irc = (irc_t *) ic->bee->ui_data; 546 509 char *pattern = "SEND" 547 510 " (([^\"][^ ]*)|\"(([^\"]|\\\")*)\")" … … 627 590 g_free( input ); 628 591 629 df->ic->irc->file_transfers = g_slist_prepend( df->ic->irc->file_transfers, ft );592 irc->file_transfers = g_slist_prepend( irc->file_transfers, ft ); 630 593 631 594 return ft; -
dcc.h
r3ab1d31 ra87e6ba 95 95 } dcc_file_transfer_t; 96 96 97 file_transfer_t *dccs_send_start( struct im_connection *ic, char *user_nick, char *file_name, size_t file_size ); 97 file_transfer_t *dccs_send_start( struct im_connection *ic, irc_user_t *iu, const char *file_name, size_t file_size ); 98 void dcc_canceled( file_transfer_t *file, char *reason ); 99 gboolean dccs_send_write( file_transfer_t *file, char *data, unsigned int data_size ); 100 file_transfer_t *dcc_request( struct im_connection *ic, char *line ); 101 void dcc_finish( file_transfer_t *file ); 102 void dcc_close( file_transfer_t *file ); 103 gboolean dccs_recv_start( file_transfer_t *ft ); 98 104 99 void dcc_canceled( file_transfer_t *file, char *reason );100 101 gboolean dccs_send_write( file_transfer_t *file, char *data, unsigned int data_size );102 103 file_transfer_t *dcc_request( struct im_connection *ic, char *line );104 105 #endif -
ipc.c
r3ab1d31 ra87e6ba 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
r3ab1d31 ra87e6ba 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 27 #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 } 28 29 GSList *irc_connection_list; 30 31 static gboolean irc_userping( gpointer _irc, gint fd, b_input_condition cond ); 32 static char *set_eval_charset( set_t *set, char *value ); 98 33 99 34 irc_t *irc_new( int fd ) … … 102 37 struct sockaddr_storage sock; 103 38 socklen_t socklen = sizeof( sock ); 39 char *host = NULL, *myhost = NULL; 40 irc_user_t *iu; 104 41 set_t *s; 42 bee_t *b; 105 43 106 44 irc = g_new0( irc_t, 1 ); … … 114 52 irc->last_pong = gettime(); 115 53 116 irc-> userhash = g_hash_table_new( g_str_hash, g_str_equal );54 irc->nick_user_hash = g_hash_table_new( g_str_hash, g_str_equal ); 117 55 irc->watches = g_hash_table_new( g_str_hash, g_str_equal ); 118 119 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" );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" ); 156 90 157 91 if( global.conf->ping_interval > 0 && global.conf->ping_timeout > 0 ) 158 92 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" );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 ); 96 b = irc->b = bee_new(); 97 b->ui_data = irc; 98 b->ui = &irc_ui_funcs; 99 100 s = set_add( &b->set, "away_devoice", "true", NULL/*set_eval_away_devoice*/, irc ); 101 s = set_add( &b->set, "buddy_sendbuffer", "false", set_eval_bool, irc ); 102 s = set_add( &b->set, "buddy_sendbuffer_delay", "200", set_eval_int, irc ); 103 s = set_add( &b->set, "charset", "utf-8", set_eval_charset, irc ); 104 //s = set_add( &b->set, "control_channel", irc->channel, NULL/*set_eval_control_channel*/, irc ); 105 s = set_add( &b->set, "default_target", "root", NULL, irc ); 106 s = set_add( &b->set, "display_namechanges", "false", set_eval_bool, irc ); 107 s = set_add( &b->set, "handle_unknown", "root", NULL, irc ); 108 s = set_add( &b->set, "lcnicks", "true", set_eval_bool, irc ); 109 s = set_add( &b->set, "ops", "both", NULL/*set_eval_ops*/, irc ); 110 s = set_add( &b->set, "private", "true", set_eval_bool, irc ); 111 s = set_add( &b->set, "query_order", "lifo", NULL, irc ); 112 s = set_add( &b->set, "root_nick", ROOT_NICK, NULL/*set_eval_root_nick*/, irc ); 113 s = set_add( &b->set, "simulate_netsplit", "true", set_eval_bool, irc ); 114 s = set_add( &b->set, "to_char", ": ", set_eval_to_char, irc ); 115 s = set_add( &b->set, "typing_notice", "false", set_eval_bool, irc ); 116 117 irc->root = iu = irc_user_new( irc, ROOT_NICK ); 118 iu->host = g_strdup( myhost ); 119 iu->fullname = g_strdup( ROOT_FN ); 120 iu->f = &irc_user_root_funcs; 121 122 iu = irc_user_new( irc, NS_NICK ); 123 iu->host = g_strdup( myhost ); 124 iu->fullname = g_strdup( ROOT_FN ); 125 iu->f = &irc_user_root_funcs; 126 127 irc->user = g_new0( irc_user_t, 1 ); 128 irc->user->host = g_strdup( host ); 192 129 193 130 conf_loaddefaults( irc ); 194 131 195 132 /* Evaluator sets the iconv/oconv structures. */ 196 set_eval_charset( set_find( &irc->set, "charset" ), set_getstr( &irc->set, "charset" ) ); 197 198 return( irc ); 133 set_eval_charset( set_find( &b->set, "charset" ), set_getstr( &b->set, "charset" ) ); 134 135 irc_write( irc, ":%s NOTICE AUTH :%s", irc->root->host, "BitlBee-IRCd initialized, please go on" ); 136 137 g_free( myhost ); 138 g_free( host ); 139 140 return irc; 199 141 } 200 142 … … 217 159 218 160 ipc_to_master_str( "OPERMSG :Client exiting: %s@%s [%s]\r\n", 219 irc-> nick ? irc->nick : "(NONE)", irc->host, reason );161 irc->user->nick ? irc->user->nick : "(NONE)", irc->root->host, reason ); 220 162 221 163 g_free( reason ); … … 227 169 228 170 ipc_to_master_str( "OPERMSG :Client exiting: %s@%s [%s]\r\n", 229 irc-> nick ? irc->nick : "(NONE)", irc->host, "No reason given" );171 irc->user->nick ? irc->user->nick : "(NONE)", irc->root->host, "No reason given" ); 230 172 } 231 173 … … 248 190 } 249 191 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 */ 192 static gboolean irc_free_hashkey( gpointer key, gpointer value, gpointer data ); 193 258 194 void irc_free( irc_t * irc ) 259 195 { 260 user_t *user, *usertmp;261 262 196 log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd ); 263 197 264 if( irc->status & USTATUS_IDENTIFIED && set_getbool( &irc->set, "save_on_quit" ) ) 198 /* 199 if( irc->status & USTATUS_IDENTIFIED && set_getbool( &irc->b->set, "save_on_quit" ) ) 265 200 if( storage_save( irc, NULL, TRUE ) != STORAGE_OK ) 266 201 irc_usermsg( irc, "Error while saving settings!" ); 202 */ 267 203 268 204 irc_connection_list = g_slist_remove( irc_connection_list, irc ); 269 205 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 206 /* 285 207 while( irc->queries != NULL ) 286 208 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 } 209 */ 210 211 while( irc->users ) 212 { 213 irc_user_t *iu = irc->users->data; 214 irc_user_free( irc, iu->nick ); 215 } 216 217 while( irc->channels ) 218 irc_channel_free( irc->channels->data ); 309 219 310 220 if( irc->ping_source_id > 0 ) … … 318 228 irc->fd = -1; 319 229 320 g_hash_table_foreach_remove( irc-> userhash, irc_free_hashkey, NULL );321 g_hash_table_destroy( irc-> userhash );230 g_hash_table_foreach_remove( irc->nick_user_hash, irc_free_hashkey, NULL ); 231 g_hash_table_destroy( irc->nick_user_hash ); 322 232 323 233 g_hash_table_foreach_remove( irc->watches, irc_free_hashkey, NULL ); … … 332 242 g_free( irc->readbuffer ); 333 243 334 g_free( irc->nick );335 g_free( irc->user );336 g_free( irc->host );337 g_free( irc->realname );338 244 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 245 347 246 g_free( irc ); … … 355 254 } 356 255 256 static gboolean irc_free_hashkey( gpointer key, gpointer value, gpointer data ) 257 { 258 g_free( key ); 259 260 return( TRUE ); 261 } 262 357 263 /* USE WITH CAUTION! 358 264 Sets pass without checking */ 359 void irc_setpass (irc_t *irc, const char *pass) 265 void irc_setpass (irc_t *irc, const char *pass) 360 266 { 361 267 g_free (irc->password); … … 368 274 } 369 275 276 static char **irc_splitlines( char *buffer ); 277 370 278 void irc_process( irc_t *irc ) 371 279 { … … 375 283 if( irc->readbuffer != NULL ) 376 284 { 377 lines = irc_ tokenize( irc->readbuffer );285 lines = irc_splitlines( irc->readbuffer ); 378 286 379 287 for( i = 0; *lines[i] != '\0'; i ++ ) … … 412 320 "`help set charset' for more information. Your " 413 321 "message was ignored.", 414 set_getstr( &irc-> set, "charset" ) );322 set_getstr( &irc->b->set, "charset" ) ); 415 323 416 324 g_free( conv ); … … 419 327 else 420 328 { 421 irc_write( irc, ":%s NOTICE AUTH :%s", irc-> myhost,329 irc_write( irc, ":%s NOTICE AUTH :%s", irc->root->host, 422 330 "Warning: invalid characters received at login time." ); 423 331 … … 457 365 } 458 366 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 ) 367 /* Splits a long string into separate lines. The array is NULL-terminated 368 and, unless the string contains an incomplete line at the end, ends with 369 an empty string. Could use g_strsplit() but this one does it in-place. 370 (So yes, it's destructive.) */ 371 static char **irc_splitlines( char *buffer ) 462 372 { 463 373 int i, j, n = 3; … … 590 500 } 591 501 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 502 void irc_write( irc_t *irc, char *format, ... ) 623 503 { … … 630 510 return; 631 511 } 512 513 void irc_write_all( int now, char *format, ... ) 514 { 515 va_list params; 516 GSList *temp; 517 518 va_start( params, format ); 519 520 temp = irc_connection_list; 521 while( temp != NULL ) 522 { 523 irc_t *irc = temp->data; 524 525 if( now ) 526 { 527 g_free( irc->sendbuffer ); 528 irc->sendbuffer = g_strdup( "\r\n" ); 529 } 530 irc_vawrite( temp->data, format, params ); 531 if( now ) 532 { 533 bitlbee_io_current_client_write( irc, irc->fd, GAIM_INPUT_WRITE ); 534 } 535 temp = temp->next; 536 } 537 538 va_end( params ); 539 return; 540 } 632 541 633 542 void irc_vawrite( irc_t *irc, char *format, va_list params ) … … 686 595 } 687 596 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 the 725 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 ) 597 int irc_check_login( irc_t *irc ) 598 { 599 if( irc->user->user && irc->user->nick ) 600 { 601 if( global.conf->authmode == AUTHMODE_CLOSED && !( irc->status & USTATUS_AUTHORIZED ) ) 602 { 603 irc_send_num( irc, 464, ":This server is password-protected." ); 604 return 0; 605 } 606 else 607 { 608 irc_channel_t *ic; 609 irc_user_t *iu = irc->user; 610 611 irc->user = irc_user_new( irc, iu->nick ); 612 irc->user->user = iu->user; 613 irc->user->host = iu->host; 614 irc->user->fullname = iu->fullname; 615 irc->user->f = &irc_user_self_funcs; 616 g_free( iu->nick ); 617 g_free( iu ); 618 619 if( global.conf->runmode == RUNMODE_FORKDAEMON || global.conf->runmode == RUNMODE_DAEMON ) 620 ipc_to_master_str( "CLIENT %s %s :%s\r\n", irc->user->host, irc->user->nick, irc->user->fullname ); 621 622 irc->status |= USTATUS_LOGGED_IN; 623 624 /* This is for bug #209 (use PASS to identify to NickServ). */ 625 if( irc->password != NULL ) 732 626 { 733 irc_reply( irc, 353, "= %s :%s", channel, namelist ); 734 *namelist = 0; 627 char *send_cmd[] = { "identify", g_strdup( irc->password ), NULL }; 628 629 /*irc_setpass( irc, NULL );*/ 630 /*root_command( irc, send_cmd );*/ 631 g_free( send_cmd[1] ); 735 632 } 736 633 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 should 752 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 int irc_check_login( irc_t *irc ) 776 { 777 if( irc->user && irc->nick ) 778 { 779 if( global.conf->authmode == AUTHMODE_CLOSED && !( irc->status & USTATUS_AUTHORIZED ) ) 780 { 781 irc_reply( irc, 464, ":This server is password-protected." ); 782 return 0; 783 } 784 else 785 { 786 irc_login( irc ); 634 irc_send_login( irc ); 635 636 irc->umode[0] = '\0'; 637 irc_umode_set( irc, "+" UMODE, TRUE ); 638 639 ic = irc_channel_new( irc, ROOT_CHAN ); 640 irc_channel_set_topic( ic, CONTROL_TOPIC, irc->root ); 641 irc_channel_add_user( ic, irc->user ); 642 643 irc->last_root_cmd = g_strdup( ROOT_CHAN ); 644 787 645 return 1; 788 646 } … … 795 653 } 796 654 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 ) 655 void irc_umode_set( irc_t *irc, const char *s, gboolean allow_priv ) 922 656 { 923 657 /* allow_priv: Set to 0 if s contains user input, 1 if you want 924 658 to set a "privileged" mode (+o, +R, etc). */ 925 char m[256], st = 1, *t; 659 char m[128], st = 1; 660 const char *t; 926 661 int i; 927 662 char changes[512], *p, st2 = 2; … … 931 666 932 667 for( t = irc->umode; *t; t ++ ) 933 m[(int)*t] = 1; 934 668 if( *t < sizeof( m ) ) 669 m[(int)*t] = 1; 670 935 671 p = changes; 936 672 for( t = s; *t; t ++ ) … … 938 674 if( *t == '+' || *t == '-' ) 939 675 st = *t == '+'; 940 else if( st == 0 || ( strchr( UMODES, *t ) || ( allow_priv && strchr( UMODES_PRIV, *t ) ) ) ) 676 else if( ( st == 0 && ( !strchr( UMODES_KEEP, *t ) || allow_priv ) ) || 677 ( st == 1 && strchr( UMODES, *t ) ) || 678 ( st == 1 && allow_priv && strchr( UMODES_PRIV, *t ) ) ) 941 679 { 942 680 if( m[(int)*t] != st) … … 955 693 memset( irc->umode, 0, sizeof( irc->umode ) ); 956 694 957 for( i = 0; i < 256&& strlen( irc->umode ) < ( sizeof( irc->umode ) - 1 ); i ++ )695 for( i = 'A'; i <= 'z' && strlen( irc->umode ) < ( sizeof( irc->umode ) - 1 ); i ++ ) 958 696 if( m[i] ) 959 697 irc->umode[strlen(irc->umode)] = i; 960 698 961 699 if( badflag ) 962 irc_reply( irc, 501, ":Unknown MODE flag" ); 963 /* Deliberately no !user@host on the prefix here */ 700 irc_send_num( irc, 501, ":Unknown MODE flag" ); 964 701 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 } 702 irc_write( irc, ":%s!%s@%s MODE %s :%s", irc->user->nick, 703 irc->user->user, irc->user->host, irc->user->nick, 704 changes ); 705 } 706 1290 707 1291 708 /* Returns 0 if everything seems to be okay, a number >0 when there was a … … 1325 742 } 1326 743 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 } 744 745 static char *set_eval_charset( set_t *set, char *value ) 746 { 747 irc_t *irc = set->data; 748 GIConv ic, oc; 749 750 if( g_strcasecmp( value, "none" ) == 0 ) 751 value = g_strdup( "utf-8" ); 752 753 if( ( ic = g_iconv_open( "utf-8", value ) ) == (GIConv) -1 ) 754 { 755 return NULL; 756 } 757 if( ( oc = g_iconv_open( value, "utf-8" ) ) == (GIConv) -1 ) 758 { 759 g_iconv_close( ic ); 760 return NULL; 761 } 762 763 if( irc->iconv != (GIConv) -1 ) 764 g_iconv_close( irc->iconv ); 765 if( irc->oconv != (GIConv) -1 ) 766 g_iconv_close( irc->oconv ); 767 768 irc->iconv = ic; 769 irc->oconv = oc; 770 771 return value; 772 } -
irc.h
r3ab1d31 ra87e6ba 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 /* … … 33 33 #define IRC_PING_STRING "PinglBee" 34 34 35 #define UMODES "abisw" 36 #define UMODES_PRIV "Ro" 37 #define CMODES "nt" 38 #define CMODE "t" 39 #define UMODE "s" 40 #define CTYPES "&#" 35 #define UMODES "abisw" /* Allowed umodes (although they mostly do nothing) */ 36 #define UMODES_PRIV "Ro" /* Allowed, but not by user directly */ 37 #define UMODES_KEEP "R" /* Don't allow unsetting using /MODE */ 38 #define CMODES "nt" /* Allowed modes */ 39 #define CMODE "t" /* Default mode */ 40 #define UMODE "s" /* Default mode */ 41 42 #define CTYPES "&#" /* Valid channel name prefixes */ 41 43 42 44 typedef enum … … 48 50 USTATUS_SHUTDOWN = 8 49 51 } irc_status_t; 52 53 struct irc_user; 50 54 51 55 typedef struct irc … … 59 63 GIConv iconv, oconv; 60 64 61 int sentbytes; 62 time_t oldtime; 63 65 struct irc_user *root; 66 struct irc_user *user; 67 68 char *last_root_cmd; 69 70 char *password; /* HACK: Used to save the user's password, but before 71 logging in, this may contain a password we should 72 send to identify after USER/NICK are received. */ 73 74 char umode[8]; 75 76 struct query *queries; 77 GSList *file_transfers; 78 79 GSList *users, *channels; 80 GHashTable *nick_user_hash; 81 GHashTable *watches; 82 83 gint r_watch_source_id; 84 gint w_watch_source_id; 85 gint ping_source_id; 86 87 struct bee *b; 88 } irc_t; 89 90 typedef enum 91 { 92 IRC_USER_PRIVATE = 1, 93 } irc_user_flags_t; 94 95 typedef struct irc_user 96 { 97 irc_t *irc; 98 64 99 char *nick; 65 100 char *user; 66 101 char *host; 67 char *realname; 68 char *password; /* HACK: Used to save the user's password, but before 69 logging in, this may contain a password we should 70 send to identify after USER/NICK are received. */ 71 72 char umode[8]; 73 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 struct query *queries; 84 struct account *accounts; 85 GSList *file_transfers; 86 struct chat *chatrooms; 87 88 struct __USER *users; 89 GHashTable *userhash; 90 GHashTable *watches; 91 struct __NICK *nicks; 102 char *fullname; 103 104 /* Nickname in lowercase for case sensitive searches */ 105 char *key; 106 107 irc_user_flags_t flags; 108 109 char *sendbuf; 110 int sendbuf_len; 111 guint sendbuf_timer; 112 //int sendbuf_flags; 113 114 struct bee_user *bu; 115 116 const struct irc_user_funcs *f; 117 } irc_user_t; 118 119 struct irc_user_funcs 120 { 121 gboolean (*privmsg)( irc_user_t *iu, const char *msg ); 122 }; 123 124 extern const struct irc_user_funcs irc_user_root_funcs; 125 extern const struct irc_user_funcs irc_user_self_funcs; 126 127 typedef enum 128 { 129 IRC_CHANNEL_JOINED = 1, 130 } irc_channel_flags_t; 131 132 typedef struct irc_channel 133 { 134 irc_t *irc; 135 char *name; 136 char mode[8]; 137 int flags; 138 139 char *topic; 140 char *topic_who; 141 time_t topic_time; 142 143 GSList *users; 92 144 struct set *set; 93 94 gint r_watch_source_id; 95 gint w_watch_source_id; 96 gint ping_source_id; 97 } irc_t; 98 99 #include "user.h" 100 145 146 const struct irc_channel_funcs *f; 147 } irc_channel_t; 148 149 struct irc_channel_funcs 150 { 151 gboolean (*privmsg)( irc_channel_t *iu, const char *msg ); 152 }; 153 154 extern const struct bee_ui_funcs irc_ui_funcs; 155 156 /* irc.c */ 101 157 extern GSList *irc_connection_list; 102 158 … … 104 160 void irc_abort( irc_t *irc, int immed, char *format, ... ) G_GNUC_PRINTF( 3, 4 ); 105 161 void irc_free( irc_t *irc ); 106 107 void irc_exec( irc_t *irc, char **cmd ); 162 void irc_setpass (irc_t *irc, const char *pass); 163 108 164 void irc_process( irc_t *irc ); 109 165 char **irc_parse_line( char *line ); 110 166 char *irc_build_line( char **cmd ); 111 167 112 void irc_vawrite( irc_t *irc, char *format, va_list params );113 168 void irc_write( irc_t *irc, char *format, ... ) G_GNUC_PRINTF( 2, 3 ); 114 169 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 ); 118 119 void irc_login( irc_t *irc ); 170 void irc_vawrite( irc_t *irc, char *format, va_list params ); 171 120 172 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 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 ); 139 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 ); 173 174 void irc_umode_set( irc_t *irc, const char *s, gboolean allow_priv ); 175 176 /* irc_channel.c */ 177 irc_channel_t *irc_channel_new( irc_t *irc, const char *name ); 178 irc_channel_t *irc_channel_by_name( irc_t *irc, const char *name ); 179 int irc_channel_free( irc_channel_t *ic ); 180 int irc_channel_add_user( irc_channel_t *ic, irc_user_t *iu ); 181 int irc_channel_del_user( irc_channel_t *ic, irc_user_t *iu ); 182 gboolean irc_channel_has_user( irc_channel_t *ic, irc_user_t *iu ); 183 int irc_channel_set_topic( irc_channel_t *ic, const char *topic, const irc_user_t *who ); 184 gboolean irc_channel_name_ok( const char *name ); 185 186 /* irc_commands.c */ 187 void irc_exec( irc_t *irc, char **cmd ); 188 189 /* irc_send.c */ 190 void irc_send_num( irc_t *irc, int code, char *format, ... ) G_GNUC_PRINTF( 3, 4 ); 191 void irc_send_login( irc_t *irc ); 192 void irc_send_motd( irc_t *irc ); 193 void irc_usermsg( irc_t *irc, char *format, ... ); 194 void irc_send_join( irc_channel_t *ic, irc_user_t *iu ); 195 void irc_send_part( irc_channel_t *ic, irc_user_t *iu, const char *reason ); 196 void irc_send_names( irc_channel_t *ic ); 197 void irc_send_topic( irc_channel_t *ic, gboolean topic_change ); 198 void irc_send_whois( irc_user_t *iu ); 199 void irc_send_who( irc_t *irc, GSList *l, const char *channel ); 200 void irc_send_msg( irc_user_t *iu, const char *type, const char *dst, const char *msg, const char *prefix ); 201 void irc_send_msg_raw( irc_user_t *iu, const char *type, const char *dst, const char *msg ); 202 void irc_send_nick( irc_user_t *iu, const char *new ); 203 204 /* irc_user.c */ 205 irc_user_t *irc_user_new( irc_t *irc, const char *nick ); 206 int irc_user_free( irc_t *irc, const char *nick ); 207 irc_user_t *irc_user_by_name( irc_t *irc, const char *nick ); 208 int irc_user_set_nick( irc_user_t *iu, const char *new ); 209 gint irc_user_cmp( gconstpointer a_, gconstpointer b_ ); 142 210 143 211 #endif -
irc_commands.c
r3ab1d31 ra87e6ba 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 … … 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_by_name( 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 ); … … 105 104 static void irc_cmd_ping( irc_t *irc, char **cmd ) 106 105 { 107 irc_write( irc, ":%s PONG %s :%s", irc->myhost, irc->myhost, cmd[1]?cmd[1]:irc->myhost ); 108 } 109 110 static void irc_cmd_oper( irc_t *irc, char **cmd ) 111 { 112 if( global.conf->oper_pass && 113 ( strncmp( global.conf->oper_pass, "md5:", 4 ) == 0 ? 114 md5_verify_password( cmd[2], global.conf->oper_pass + 4 ) == 0 : 115 strcmp( cmd[2], global.conf->oper_pass ) == 0 ) ) 116 { 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" ); 123 } 106 irc_write( irc, ":%s PONG %s :%s", irc->root->host, 107 irc->root->host, cmd[1]?cmd[1]:irc->root->host ); 108 } 109 110 static void irc_cmd_pong( irc_t *irc, char **cmd ) 111 { 112 /* We could check the value we get back from the user, but in 113 fact we don't care, we're just happy s/he's still alive. */ 114 irc->last_pong = gettime(); 115 irc->pinging = 0; 116 } 117 118 static void irc_cmd_join( irc_t *irc, char **cmd ) 119 { 120 irc_channel_t *ic; 121 122 if( ( ic = irc_channel_by_name( irc, cmd[1] ) ) == NULL ) 123 ic = irc_channel_new( irc, cmd[1] ); 124 125 if( ic == NULL ) 126 irc_send_num( irc, 479, "%s :Invalid channel name", cmd[1] ); 127 128 if( ic->flags & IRC_CHANNEL_JOINED ) 129 return; /* Dude, you're already there... 130 RFC doesn't have any reply for that though? */ 131 132 irc_channel_add_user( ic, irc->user ); 133 } 134 135 static void irc_cmd_names( irc_t *irc, char **cmd ) 136 { 137 irc_channel_t *ic; 138 139 if( cmd[1] && ( ic = irc_channel_by_name( irc, cmd[1] ) ) ) 140 irc_send_names( ic ); 141 /* With no args, we should show /names of all chans. Make the code 142 below work well if necessary. 143 else 144 { 145 GSList *l; 146 147 for( l = irc->channels; l; l = l->next ) 148 irc_send_names( l->data ); 149 } 150 */ 151 } 152 153 static void irc_cmd_part( irc_t *irc, char **cmd ) 154 { 155 irc_channel_t *ic; 156 157 if( ( ic = irc_channel_by_name( irc, cmd[1] ) ) == NULL ) 158 { 159 irc_send_num( irc, 403, "%s :No such channel", cmd[1] ); 160 } 161 else if( !irc_channel_del_user( ic, irc->user ) ) 162 { 163 irc_send_num( irc, 442, "%s :You're not on that channel", cmd[1] ); 164 } 165 } 166 167 static void irc_cmd_whois( irc_t *irc, char **cmd ) 168 { 169 char *nick = cmd[1]; 170 irc_user_t *iu = irc_user_by_name( irc, nick ); 171 172 if( iu ) 173 irc_send_whois( iu ); 174 else 175 irc_send_num( irc, 401, "%s :Nick does not exist", nick ); 176 } 177 178 static void irc_cmd_whowas( irc_t *irc, char **cmd ) 179 { 180 /* For some reason irssi tries a whowas when whois fails. We can 181 ignore this, but then the user never gets a "user not found" 182 message from irssi which is a bit annoying. So just respond 183 with not-found and irssi users will get better error messages */ 184 185 irc_send_num( irc, 406, "%s :Nick does not exist", cmd[1] ); 186 irc_send_num( irc, 369, "%s :End of WHOWAS", cmd[1] ); 187 } 188 189 static void irc_cmd_motd( irc_t *irc, char **cmd ) 190 { 191 irc_send_motd( irc ); 124 192 } 125 193 126 194 static void irc_cmd_mode( irc_t *irc, char **cmd ) 127 195 { 128 if( strchr( CTYPES, *cmd[1] ) ) 129 { 130 if( cmd[2] ) 196 if( irc_channel_name_ok( cmd[1] ) ) 197 { 198 irc_channel_t *ic; 199 200 if( ( ic = irc_channel_by_name( irc, cmd[1] ) ) == NULL ) 201 irc_send_num( irc, 403, "%s :No such channel", cmd[1] ); 202 else if( cmd[2] ) 131 203 { 132 204 if( *cmd[2] == '+' || *cmd[2] == '-' ) 133 irc_ reply( irc, 477, "%s :Can't change channel modes", cmd[1] );205 irc_send_num( irc, 477, "%s :Can't change channel modes", cmd[1] ); 134 206 else if( *cmd[2] == 'b' ) 135 irc_ reply( irc, 368, "%s :No bans possible", cmd[1] );207 irc_send_num( irc, 368, "%s :No bans possible", cmd[1] ); 136 208 } 137 209 else 138 irc_ reply( irc, 324, "%s +%s", cmd[1], CMODE);139 } 140 else 141 { 142 if( nick_cmp( cmd[1], irc-> nick ) == 0 )210 irc_send_num( irc, 324, "%s +%s", cmd[1], ic->mode ); 211 } 212 else 213 { 214 if( nick_cmp( cmd[1], irc->user->nick ) == 0 ) 143 215 { 144 216 if( cmd[2] ) 145 217 irc_umode_set( irc, cmd[2], 0 ); 146 218 else 147 irc_ reply( irc, 221, "+%s", irc->umode );219 irc_send_num( irc, 221, "+%s", irc->umode ); 148 220 } 149 221 else 150 irc_reply( irc, 502, ":Don't touch their modes" ); 151 } 152 } 153 154 static void irc_cmd_names( irc_t *irc, char **cmd ) 155 { 156 irc_names( irc, cmd[1]?cmd[1]:irc->channel ); 157 } 158 159 static void irc_cmd_part( irc_t *irc, char **cmd ) 160 { 161 struct groupchat *c; 162 163 if( g_strcasecmp( cmd[1], irc->channel ) == 0 ) 164 { 165 user_t *u = user_find( irc, irc->nick ); 166 167 /* Not allowed to leave control channel */ 168 irc_part( irc, u, irc->channel ); 169 irc_join( irc, u, irc->channel ); 170 } 171 else if( ( c = irc_chat_by_channel( irc, cmd[1] ) ) ) 172 { 173 user_t *u = user_find( irc, irc->nick ); 174 175 irc_part( irc, u, c->channel ); 176 177 if( c->ic ) 178 { 179 c->joined = 0; 180 c->ic->acc->prpl->chat_leave( c ); 181 } 182 } 183 else 184 { 185 irc_reply( irc, 403, "%s :No such channel", cmd[1] ); 186 } 187 } 188 189 static void irc_cmd_join( irc_t *irc, char **cmd ) 190 { 191 if( g_strcasecmp( cmd[1], irc->channel ) == 0 ) 192 ; /* Dude, you're already there... 193 RFC doesn't have any reply for that though? */ 194 else if( cmd[1] ) 195 { 196 struct chat *c; 197 198 if( strchr( CTYPES, cmd[1][0] ) == NULL || cmd[1][1] == 0 ) 199 irc_reply( irc, 479, "%s :Invalid channel name", cmd[1] ); 200 else if( ( c = chat_bychannel( irc, cmd[1] ) ) && c->acc && c->acc->ic ) 201 chat_join( irc, c, cmd[2] ); 202 else 203 irc_reply( irc, 403, "%s :No such channel", cmd[1] ); 204 } 205 } 206 207 static void irc_cmd_invite( irc_t *irc, char **cmd ) 208 { 209 char *nick = cmd[1], *channel = cmd[2]; 210 struct groupchat *c = irc_chat_by_channel( irc, channel ); 211 user_t *u = user_find( irc, nick ); 212 213 if( u && c && ( u->ic == c->ic ) ) 214 if( c->ic && c->ic->acc->prpl->chat_invite ) 215 { 216 c->ic->acc->prpl->chat_invite( c, u->handle, NULL ); 217 irc_reply( irc, 341, "%s %s", nick, channel ); 218 return; 219 } 220 221 irc_reply( irc, 482, "%s :Invite impossible; User/Channel non-existent or incompatible", channel ); 222 irc_send_num( irc, 502, ":Don't touch their modes" ); 223 } 224 } 225 226 static void irc_cmd_who( irc_t *irc, char **cmd ) 227 { 228 char *channel = cmd[1]; 229 irc_channel_t *ic; 230 231 if( !channel || *channel == '0' || *channel == '*' || !*channel ) 232 irc_send_who( irc, irc->users, "**" ); 233 else if( ( ic = irc_channel_by_name( irc, channel ) ) ) 234 irc_send_who( irc, ic->users, channel ); 235 else 236 irc_send_num( irc, 403, "%s :No such channel", channel ); 222 237 } 223 238 224 239 static void irc_cmd_privmsg( irc_t *irc, char **cmd ) 225 240 { 226 if ( !cmd[2] ) 227 { 228 irc_reply( irc, 412, ":No text to send" ); 229 } 230 else if ( irc->nick && g_strcasecmp( cmd[1], irc->nick ) == 0 ) 231 { 232 irc_write( irc, ":%s!%s@%s %s %s :%s", irc->nick, irc->user, irc->host, cmd[0], cmd[1], cmd[2] ); 241 irc_channel_t *ic; 242 irc_user_t *iu; 243 244 if( !cmd[2] ) 245 { 246 irc_send_num( irc, 412, ":No text to send" ); 247 } 248 else if( irc_channel_name_ok( cmd[1] ) && 249 ( ic = irc_channel_by_name( irc, cmd[1] ) ) ) 250 { 251 if( ic->f->privmsg ) 252 ic->f->privmsg( ic, cmd[2] ); 253 } 254 else if( ( iu = irc_user_by_name( irc, cmd[1] ) ) ) 255 { 256 if( iu->f->privmsg ) 257 iu->f->privmsg( iu, cmd[2] ); 258 } 259 else 260 { 261 irc_send_num( irc, 401, "%s :No such nick/channel", cmd[1] ); 262 } 263 264 265 #if 0 266 else if( irc->nick && g_strcasecmp( cmd[1], irc->nick ) == 0 ) 267 { 233 268 } 234 269 else … … 271 306 irc_send( irc, cmd[1], cmd[2], ( g_strcasecmp( cmd[0], "NOTICE" ) == 0 ) ? OPT_AWAY : 0 ); 272 307 } 273 } 274 275 static void irc_cmd_who( irc_t *irc, char **cmd ) 276 { 277 char *channel = cmd[1]; 278 user_t *u = irc->users; 279 struct groupchat *c; 280 GList *l; 281 282 if( !channel || *channel == '0' || *channel == '*' || !*channel ) 283 while( u ) 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 ); 286 u = u->next; 287 } 288 else if( g_strcasecmp( channel, irc->channel ) == 0 ) 289 while( u ) 290 { 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 ); 293 u = u->next; 294 } 295 else if( ( c = irc_chat_by_channel( irc, channel ) ) ) 296 for( l = c->in_room; l; l = l->next ) 297 { 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 ); 300 } 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:"**" ); 308 #endif 309 } 310 311 static void irc_cmd_nickserv( irc_t *irc, char **cmd ) 312 { 313 /* [SH] This aliases the NickServ command to PRIVMSG root */ 314 /* [TV] This aliases the NS command to PRIVMSG root as well */ 315 root_command( irc, cmd + 1 ); 316 } 317 318 319 320 #if 0 321 //#if 0 322 static void irc_cmd_oper( irc_t *irc, char **cmd ) 323 { 324 if( global.conf->oper_pass && 325 ( strncmp( global.conf->oper_pass, "md5:", 4 ) == 0 ? 326 md5_verify_password( cmd[2], global.conf->oper_pass + 4 ) == 0 : 327 strcmp( cmd[2], global.conf->oper_pass ) == 0 ) ) 328 { 329 irc_umode_set( irc, "+o", 1 ); 330 irc_send_num( irc, 381, ":Password accepted" ); 331 } 332 else 333 { 334 irc_send_num( irc, 432, ":Incorrect password" ); 335 } 336 } 337 338 static void irc_cmd_invite( irc_t *irc, char **cmd ) 339 { 340 char *nick = cmd[1], *channel = cmd[2]; 341 struct groupchat *c = irc_chat_by_channel( irc, channel ); 342 user_t *u = user_find( irc, nick ); 343 344 if( u && c && ( u->ic == c->ic ) ) 345 if( c->ic && c->ic->acc->prpl->chat_invite ) 346 { 347 c->ic->acc->prpl->chat_invite( c, u->handle, NULL ); 348 irc_send_num( irc, 341, "%s %s", nick, channel ); 349 return; 350 } 351 352 irc_send_num( irc, 482, "%s :Invite impossible; User/Channel non-existent or incompatible", channel ); 305 353 } 306 354 … … 320 368 { 321 369 if( u->online && u->away ) 322 irc_ reply( irc, 302, ":%s=-%s@%s", u->nick, u->user, u->host );370 irc_send_num( irc, 302, ":%s=-%s@%s", u->nick, u->user, u->host ); 323 371 else 324 irc_ reply( irc, 302, ":%s=+%s@%s", u->nick, u->user, u->host );372 irc_send_num( irc, 302, ":%s=+%s@%s", u->nick, u->user, u->host ); 325 373 } 326 374 } … … 377 425 buff[strlen(buff)-1] = '\0'; 378 426 379 irc_ reply( irc, 303, ":%s", buff );427 irc_send_num( irc, 303, ":%s", buff ); 380 428 } 381 429 … … 406 454 407 455 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" );456 irc_send_num( irc, 604, "%s %s %s %d :%s", u->nick, u->user, u->host, (int) time( NULL ), "is online" ); 409 457 else 410 irc_ reply( irc, 605, "%s %s %s %d :%s", nick, "*", "*", (int) time( NULL ), "is offline" );458 irc_send_num( irc, 605, "%s %s %s %d :%s", nick, "*", "*", (int) time( NULL ), "is offline" ); 411 459 } 412 460 else if( cmd[i][0] == '-' ) … … 419 467 g_free( okey ); 420 468 421 irc_ reply( irc, 602, "%s %s %s %d :%s", nick, "*", "*", 0, "Stopped watching" );469 irc_send_num( irc, 602, "%s %s %s %d :%s", nick, "*", "*", 0, "Stopped watching" ); 422 470 } 423 471 } … … 463 511 u->away[j] = 0; 464 512 465 irc_ reply( irc, 306, ":You're now away: %s", u->away );513 irc_send_num( irc, 306, ":You're now away: %s", u->away ); 466 514 /* irc_umode_set( irc, irc->myhost, "+a" ); */ 467 515 } … … 471 519 u->away = NULL; 472 520 /* irc_umode_set( irc, irc->myhost, "-a" ); */ 473 irc_ reply( irc, 305, ":Welcome back" );521 irc_send_num( irc, 305, ":Welcome back" ); 474 522 } 475 523 … … 477 525 } 478 526 479 static void irc_cmd_whois( irc_t *irc, char **cmd )480 {481 char *nick = cmd[1];482 user_t *u = user_find( irc, nick );483 484 if( u )485 {486 irc_reply( irc, 311, "%s %s %s * :%s", u->nick, u->user, u->host, u->realname );487 488 if( u->ic )489 irc_reply( irc, 312, "%s %s.%s :%s network", u->nick, u->ic->acc->user,490 u->ic->acc->server && *u->ic->acc->server ? u->ic->acc->server : "",491 u->ic->acc->prpl->name );492 else493 irc_reply( irc, 312, "%s %s :%s", u->nick, irc->myhost, IRCD_INFO );494 495 if( !u->online )496 irc_reply( irc, 301, "%s :%s", u->nick, "User is offline" );497 else if( u->away )498 irc_reply( irc, 301, "%s :%s", u->nick, u->away );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 else505 {506 irc_reply( irc, 401, "%s :Nick does not exist", nick );507 }508 }509 510 static void irc_cmd_whowas( irc_t *irc, char **cmd )511 {512 /* For some reason irssi tries a whowas when whois fails. We can513 ignore this, but then the user never gets a "user not found"514 message from irssi which is a bit annoying. So just respond515 with not-found and irssi users will get better error messages */516 517 irc_reply( irc, 406, "%s :Nick does not exist", cmd[1] );518 irc_reply( irc, 369, "%s :End of WHOWAS", cmd[1] );519 }520 521 static void irc_cmd_nickserv( irc_t *irc, char **cmd )522 {523 /* [SH] This aliases the NickServ command to PRIVMSG root */524 /* [TV] This aliases the NS command to PRIVMSG root as well */525 root_command( irc, cmd + 1 );526 }527 528 static void irc_cmd_motd( irc_t *irc, char **cmd )529 {530 irc_motd( irc );531 }532 533 static void irc_cmd_pong( irc_t *irc, char **cmd )534 {535 /* We could check the value we get back from the user, but in536 fact we don't care, we're just happy he's still alive. */537 irc->last_pong = gettime();538 irc->pinging = 0;539 }540 541 527 static void irc_cmd_version( irc_t *irc, char **cmd ) 542 528 { 543 irc_ reply( irc, 351, "bitlbee-%s. %s :%s/%s ", BITLBEE_VERSION, irc->myhost, ARCH, CPU );529 irc_send_num( irc, 351, "bitlbee-%s. %s :%s/%s ", BITLBEE_VERSION, irc->myhost, ARCH, CPU ); 544 530 } 545 531 … … 572 558 ipc_to_master( cmd ); 573 559 574 irc_reply( irc, 382, "%s :Rehashing", global.conf_file ); 575 } 560 irc_send_num( irc, 382, "%s :Rehashing", global.conf_file ); 561 } 562 #endif 576 563 577 564 static const command_t irc_commands[] = { … … 581 568 { "quit", 0, irc_cmd_quit, 0 }, 582 569 { "ping", 0, irc_cmd_ping, 0 }, 570 { "pong", 0, irc_cmd_pong, IRC_CMD_LOGGED_IN }, 571 { "join", 1, irc_cmd_join, IRC_CMD_LOGGED_IN }, 572 { "names", 1, irc_cmd_names, IRC_CMD_LOGGED_IN }, 573 { "part", 1, irc_cmd_part, IRC_CMD_LOGGED_IN }, 574 { "whois", 1, irc_cmd_whois, IRC_CMD_LOGGED_IN }, 575 { "whowas", 1, irc_cmd_whowas, IRC_CMD_LOGGED_IN }, 576 { "motd", 0, irc_cmd_motd, IRC_CMD_LOGGED_IN }, 577 { "mode", 1, irc_cmd_mode, IRC_CMD_LOGGED_IN }, 578 { "who", 0, irc_cmd_who, IRC_CMD_LOGGED_IN }, 579 { "privmsg", 1, irc_cmd_privmsg, IRC_CMD_LOGGED_IN }, 580 { "nickserv", 1, irc_cmd_nickserv, IRC_CMD_LOGGED_IN }, 581 { "ns", 1, irc_cmd_nickserv, IRC_CMD_LOGGED_IN }, 582 #if 0 583 583 { "oper", 2, irc_cmd_oper, IRC_CMD_LOGGED_IN }, 584 { "mode", 1, irc_cmd_mode, IRC_CMD_LOGGED_IN },585 { "names", 0, irc_cmd_names, IRC_CMD_LOGGED_IN },586 { "part", 1, irc_cmd_part, IRC_CMD_LOGGED_IN },587 { "join", 1, irc_cmd_join, IRC_CMD_LOGGED_IN },588 584 { "invite", 2, irc_cmd_invite, IRC_CMD_LOGGED_IN }, 589 { "privmsg", 1, irc_cmd_privmsg, IRC_CMD_LOGGED_IN },590 585 { "notice", 1, irc_cmd_privmsg, IRC_CMD_LOGGED_IN }, 591 { "who", 0, irc_cmd_who, IRC_CMD_LOGGED_IN },592 586 { "userhost", 1, irc_cmd_userhost, IRC_CMD_LOGGED_IN }, 593 587 { "ison", 1, irc_cmd_ison, IRC_CMD_LOGGED_IN }, … … 595 589 { "topic", 1, irc_cmd_topic, IRC_CMD_LOGGED_IN }, 596 590 { "away", 0, irc_cmd_away, IRC_CMD_LOGGED_IN }, 597 { "whois", 1, irc_cmd_whois, IRC_CMD_LOGGED_IN },598 { "whowas", 1, irc_cmd_whowas, IRC_CMD_LOGGED_IN },599 { "nickserv", 1, irc_cmd_nickserv, IRC_CMD_LOGGED_IN },600 { "ns", 1, irc_cmd_nickserv, IRC_CMD_LOGGED_IN },601 { "motd", 0, irc_cmd_motd, IRC_CMD_LOGGED_IN },602 { "pong", 0, irc_cmd_pong, IRC_CMD_LOGGED_IN },603 591 { "version", 0, irc_cmd_version, IRC_CMD_LOGGED_IN }, 604 592 { "completions", 0, irc_cmd_completions, IRC_CMD_LOGGED_IN }, … … 610 598 { "restart", 0, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, 611 599 { "kill", 2, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, 600 #endif 612 601 { NULL } 613 602 }; … … 628 617 if( irc_commands[i].flags & IRC_CMD_PRE_LOGIN && irc->status & USTATUS_LOGGED_IN ) 629 618 { 630 irc_ reply( irc, 462, ":Only allowed before logging in" );619 irc_send_num( irc, 462, ":Only allowed before logging in" ); 631 620 } 632 621 else if( irc_commands[i].flags & IRC_CMD_LOGGED_IN && !( irc->status & USTATUS_LOGGED_IN ) ) 633 622 { 634 irc_ reply( irc, 451, ":Register first" );623 irc_send_num( irc, 451, ":Register first" ); 635 624 } 636 625 else if( irc_commands[i].flags & IRC_CMD_OPER_ONLY && !strchr( irc->umode, 'o' ) ) 637 626 { 638 irc_ reply( irc, 481, ":Permission denied - You're not an IRC operator" );627 irc_send_num( irc, 481, ":Permission denied - You're not an IRC operator" ); 639 628 } 640 629 else if( n_arg < irc_commands[i].required_parameters ) 641 630 { 642 irc_ reply( irc, 461, "%s :Need more parameters", cmd[0] );631 irc_send_num( irc, 461, "%s :Need more parameters", cmd[0] ); 643 632 } 644 633 else if( irc_commands[i].flags & IRC_CMD_TO_MASTER ) … … 657 646 658 647 if( irc->status >= USTATUS_LOGGED_IN ) 659 irc_ reply( irc, 421, "%s :Unknown command", cmd[0] );660 } 648 irc_send_num( irc, 421, "%s :Unknown command", cmd[0] ); 649 } -
nick.c
r3ab1d31 ra87e6ba 78 78 79 79 nick_strip( nick ); 80 if( set_getbool( &acc-> irc->set, "lcnicks" ) )80 if( set_getbool( &acc->bee->set, "lcnicks" ) ) 81 81 nick_lc( nick ); 82 82 } … … 92 92 void nick_dedupe( account_t *acc, const char *handle, char nick[MAX_NICK_LENGTH+1] ) 93 93 { 94 irc_t *irc = (irc_t*) acc->bee->ui_data; 94 95 int inf_protection = 256; 95 96 96 97 /* Now, find out if the nick is already in use at the moment, and make 97 98 subtle changes to make it unique. */ 98 while( !nick_ok( nick ) || user_find( acc->irc, nick ) )99 while( !nick_ok( nick ) || irc_user_by_name( irc, nick ) ) 99 100 { 100 101 if( strlen( nick ) < ( MAX_NICK_LENGTH - 1 ) ) … … 112 113 int i; 113 114 114 irc_usermsg( acc->irc, "Warning: Almost had an infinite loop in nick_get()! "115 116 117 118 119 120 irc_usermsg( acc->irc, "Trying to get a sane nick for handle %s", handle );115 irc_usermsg( irc, "Warning: Almost had an infinite loop in nick_get()! " 116 "This used to be a fatal BitlBee bug, but we tried to fix it. " 117 "This message should *never* appear anymore. " 118 "If it does, please *do* send us a bug report! " 119 "Please send all the following lines in your report:" ); 120 121 irc_usermsg( irc, "Trying to get a sane nick for handle %s", handle ); 121 122 for( i = 0; i < MAX_NICK_LENGTH; i ++ ) 122 irc_usermsg( acc->irc, "Char %d: %c/%d", i, nick[i], nick[i] );123 124 irc_usermsg( acc->irc, "FAILED. Returning an insane nick now. Things might break. "125 126 123 irc_usermsg( irc, "Char %d: %c/%d", i, nick[i], nick[i] ); 124 125 irc_usermsg( irc, "FAILED. Returning an insane nick now. Things might break. " 126 "Good luck, and please don't forget to paste the lines up here " 127 "in #bitlbee on OFTC or in a mail to wilmer@gaast.net" ); 127 128 128 129 g_snprintf( nick, MAX_NICK_LENGTH + 1, "xx%x", rand() ); -
protocols/Makefile
r3ab1d31 ra87e6ba 10 10 11 11 # [SH] Program variables 12 objects = nogaim.o 12 objects = account.o bee.o bee_ft.o bee_user.o nogaim.o 13 13 14 14 15 # [SH] The next two lines should contain the directory name (in $(subdirs)) -
protocols/ft.h
r3ab1d31 ra87e6ba 168 168 * the canceled() and free() callbacks given in file will be called by this function. 169 169 */ 170 void imcb_file_canceled( file_transfer_t *file, char *reason );170 void imcb_file_canceled( struct im_connection *ic, file_transfer_t *file, char *reason ); 171 171 172 gboolean imcb_file_recv_start( file_transfer_t *ft );172 gboolean imcb_file_recv_start( struct im_connection *ic, file_transfer_t *ft ); 173 173 174 void imcb_file_finished( file_transfer_t *file );174 void imcb_file_finished( struct im_connection *ic, file_transfer_t *file ); 175 175 #endif -
protocols/jabber/iq.c
r3ab1d31 ra87e6ba 392 392 if( ( strcmp( sub, "both" ) == 0 || strcmp( sub, "to" ) == 0 ) ) 393 393 { 394 if( initial || imcb_find_buddy(ic, jid ) == NULL )394 if( initial || bee_user_by_handle( ic->bee, ic, jid ) == NULL ) 395 395 imcb_add_buddy( ic, jid, ( group && group->text_len ) ? 396 396 group->text : NULL ); … … 590 590 strcmp( s, "result" ) == 0 ) 591 591 { 592 if( imcb_find_buddy(ic, jid ) == NULL )592 if( bee_user_by_handle( ic->bee, ic, jid ) == NULL ) 593 593 imcb_add_buddy( ic, jid, NULL ); 594 594 } -
protocols/jabber/jabber.c
r3ab1d31 ra87e6ba 267 267 268 268 while( jd->filetransfers ) 269 imcb_file_canceled( ( ( struct jabber_transfer *) jd->filetransfers->data )->ft, "Logging out" );269 imcb_file_canceled( ic, ( ( struct jabber_transfer *) jd->filetransfers->data )->ft, "Logging out" ); 270 270 271 271 while( jd->streamhosts ) -
protocols/jabber/jabber_util.c
r3ab1d31 ra87e6ba 279 279 presence_send_request( bla->ic, bla->handle, "subscribed" ); 280 280 281 if( imcb_find_buddy( bla->ic, bla->handle ) == NULL ) 282 imcb_ask_add( bla->ic, bla->handle, NULL ); 281 imcb_ask_add( bla->ic, bla->handle, NULL ); 283 282 284 283 g_free( bla->handle ); … … 462 461 463 462 if( bud == NULL && ( flags & GET_BUDDY_CREAT ) && 464 ( bare_exists || imcb_find_buddy(ic, jid ) ) )463 ( bare_exists || bee_user_by_handle( ic->bee, ic, jid ) ) ) 465 464 { 466 465 *s = '/'; … … 483 482 if( bud == NULL ) 484 483 /* No match. Create it now? */ 485 return ( ( flags & GET_BUDDY_CREAT ) && imcb_find_buddy( ic, jid_ ) ) ? 484 return ( ( flags & GET_BUDDY_CREAT ) && 485 bee_user_by_handle( ic->bee, ic, jid_ ) ) ? 486 486 jabber_buddy_add( ic, jid_ ) : NULL; 487 487 else if( bud->resource && ( flags & GET_BUDDY_EXACT ) ) -
protocols/jabber/s5bytestream.c
r3ab1d31 ra87e6ba 567 567 xt_free_node( reply ); 568 568 569 imcb_file_canceled( tf-> ft, "couldn't connect to any streamhosts" );569 imcb_file_canceled( tf->ic, tf->ft, "couldn't connect to any streamhosts" ); 570 570 571 571 bt->tf->watch_in = 0; … … 604 604 605 605 if( !jabber_write_packet( tf->ic, reply ) ) 606 imcb_file_canceled( tf-> ft, "Error transmitting bytestream response" );606 imcb_file_canceled( tf->ic, tf->ft, "Error transmitting bytestream response" ); 607 607 xt_free_node( reply ); 608 608 } … … 644 644 645 645 if( tf->bytesread >= tf->ft->file_size ) 646 imcb_file_finished( tf-> ft );646 imcb_file_finished( tf->ic, tf->ft ); 647 647 648 648 tf->ft->write( tf->ft, tf->ft->buffer, ret ); … … 660 660 if( tf->watch_in ) 661 661 { 662 imcb_file_canceled( ft, "BUG in jabber file transfer: write_request called when already watching for input" );662 imcb_file_canceled( tf->ic, ft, "BUG in jabber file transfer: write_request called when already watching for input" ); 663 663 return FALSE; 664 664 } … … 706 706 707 707 if( tf->byteswritten >= ft->file_size ) 708 imcb_file_finished( ft );708 imcb_file_finished( tf->ic, ft ); 709 709 else 710 710 bt->tf->watch_out = b_input_add( tf->fd, GAIM_INPUT_WRITE, jabber_bs_send_can_write, bt ); … … 1006 1006 1007 1007 if( !jabber_write_packet( tf->ic, iq ) ) 1008 imcb_file_canceled( tf-> ft, "Error transmitting bytestream request" );1008 imcb_file_canceled( tf->ic, tf->ft, "Error transmitting bytestream request" ); 1009 1009 return TRUE; 1010 1010 } … … 1021 1021 1022 1022 if( jd->streamhosts==NULL ) /* we're done here unless we have a proxy to try */ 1023 imcb_file_canceled( tf-> ft, error );1023 imcb_file_canceled( tf->ic, tf->ft, error ); 1024 1024 1025 1025 /* MUST always return FALSE! */ -
protocols/jabber/si.c
r3ab1d31 ra87e6ba 91 91 92 92 if( !foundft ) 93 imcb_file_canceled( tf-> ft, "Buddy's client doesn't feature file transfers" );93 imcb_file_canceled( tf->ic, tf->ft, "Buddy's client doesn't feature file transfers" ); 94 94 else if( !foundbt ) 95 imcb_file_canceled( tf-> ft, "Buddy's client doesn't feature byte streams (required)" );95 imcb_file_canceled( tf->ic, tf->ft, "Buddy's client doesn't feature byte streams (required)" ); 96 96 else if( !foundsi ) 97 imcb_file_canceled( tf-> ft, "Buddy's client doesn't feature stream initiation (required)" );97 imcb_file_canceled( tf->ic, tf->ft, "Buddy's client doesn't feature stream initiation (required)" ); 98 98 99 99 return foundft && foundbt && foundsi; … … 109 109 110 110 /* and start the receive logic */ 111 imcb_file_recv_start( tf-> ft );111 imcb_file_recv_start( tf->ic, tf->ft ); 112 112 113 113 } … … 156 156 if( bud == NULL ) 157 157 { 158 imcb_file_canceled( ft, "Couldn't find buddy (BUG?)" );158 imcb_file_canceled( ic, ft, "Couldn't find buddy (BUG?)" ); 159 159 return; 160 160 } -
protocols/msn/Makefile
r3ab1d31 ra87e6ba 10 10 11 11 # [SH] Program variables 12 objects = invitation.omsn.o msn_util.o ns.o passport.o sb.o tables.o12 objects = msn.o msn_util.o ns.o passport.o sb.o tables.o 13 13 14 14 CFLAGS += -Wall -
protocols/msn/msn.c
r3ab1d31 ra87e6ba 81 81 if( md ) 82 82 { 83 /** Disabling MSN ft support for now. 83 84 while( md->filetransfers ) { 84 85 imcb_file_canceled( md->filetransfers->data, "Closing connection" ); 85 86 } 87 */ 86 88 87 89 if( md->fd >= 0 ) … … 344 346 ret->send_typing = msn_send_typing; 345 347 ret->handle_cmp = g_strcasecmp; 346 ret->transfer_request = msn_ftp_transfer_request;348 //ret->transfer_request = msn_ftp_transfer_request; 347 349 348 350 register_protocol(ret); -
protocols/msn/msn_util.c
r3ab1d31 ra87e6ba 96 96 msn_buddy_list_add( bla->ic, "AL", bla->handle, bla->realname ); 97 97 98 if( imcb_find_buddy( bla->ic, bla->handle ) == NULL ) 99 imcb_ask_add( bla->ic, bla->handle, NULL ); 98 imcb_ask_add( bla->ic, bla->handle, NULL ); 100 99 101 100 g_free( bla->handle ); -
protocols/msn/sb.c
r3ab1d31 ra87e6ba 691 691 } 692 692 } 693 #if 0 694 // Disable MSN ft support for now. 693 695 else if( g_strncasecmp( ct, "text/x-msmsgsinvite", 19 ) == 0 ) 694 696 { … … 723 725 g_free( command ); 724 726 } 727 #endif 725 728 else if( g_strncasecmp( ct, "application/x-msnmsgrp2p", 24 ) == 0 ) 726 729 { -
protocols/nogaim.c
r3ab1d31 ra87e6ba 38 38 #include "chat.h" 39 39 40 static int remove_chat_buddy_silent( struct groupchat *b, const char *handle );41 42 40 GSList *connections; 43 41 … … 91 89 } 92 90 #endif 93 94 /* nogaim.c */95 91 96 92 GList *protocols = NULL; … … 125 121 } 126 122 127 /* nogaim.c */128 123 void nogaim_init() 129 124 { … … 156 151 GSList *get_connections() { return connections; } 157 152 158 /* multi.c */159 160 153 struct im_connection *imcb_new( account_t *acc ) 161 154 { … … 164 157 ic = g_new0( struct im_connection, 1 ); 165 158 166 ic-> irc = acc->irc;159 ic->bee = acc->bee; 167 160 ic->acc = acc; 168 161 acc->ic = ic; … … 178 171 179 172 /* Destroy the pointer to this connection from the account list */ 180 for( a = ic-> irc->accounts; a; a = a->next )173 for( a = ic->bee->accounts; a; a = a->next ) 181 174 if( a->ic == ic ) 182 175 { … … 199 192 va_end( params ); 200 193 201 if( ( g_strcasecmp( set_getstr( &ic-> irc->set, "strip_html" ), "always" ) == 0 ) ||202 ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic-> irc->set, "strip_html" ) ) )194 if( ( g_strcasecmp( set_getstr( &ic->bee->set, "strip_html" ), "always" ) == 0 ) || 195 ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->bee->set, "strip_html" ) ) ) 203 196 strip_html( text ); 204 197 205 198 /* Try to find a different connection on the same protocol. */ 206 for( a = ic-> irc->accounts; a; a = a->next )199 for( a = ic->bee->accounts; a; a = a->next ) 207 200 if( a->prpl == ic->acc->prpl && a->ic != ic ) 208 201 break; … … 210 203 /* If we found one, include the screenname in the message. */ 211 204 if( a ) 212 irc_usermsg( ic->irc, "%s(%s) - %s", ic->acc->prpl->name, ic->acc->user, text ); 205 /* FIXME(wilmer): ui_log callback or so */ 206 irc_usermsg( ic->bee->ui_data, "%s(%s) - %s", ic->acc->prpl->name, ic->acc->user, text ); 213 207 else 214 irc_usermsg( ic-> irc, "%s - %s", ic->acc->prpl->name, text );208 irc_usermsg( ic->bee->ui_data, "%s - %s", ic->acc->prpl->name, text ); 215 209 216 210 g_free( text ); … … 263 257 void imcb_connected( struct im_connection *ic ) 264 258 { 265 irc_t *irc = ic->irc;266 struct chat *c;267 user_t *u;268 269 259 /* MSN servers sometimes redirect you to a different server and do 270 260 the whole login sequence again, so these "late" calls to this … … 273 263 return; 274 264 275 u = user_find( ic->irc, ic->irc->nick );276 277 265 imcb_log( ic, "Logged in" ); 278 266 … … 287 275 ic->acc->auto_reconnect_delay = 0; 288 276 277 /* 289 278 for( c = irc->chatrooms; c; c = c->next ) 290 279 { … … 295 284 chat_join( irc, c, NULL ); 296 285 } 286 */ 297 287 } 298 288 … … 302 292 303 293 a->reconnect = 0; 304 account_on( a-> irc, a );294 account_on( a->bee, a ); 305 295 306 296 return( FALSE ); /* Only have to run the timeout once */ … … 315 305 void imc_logout( struct im_connection *ic, int allow_reconnect ) 316 306 { 317 irc_t *irc = ic->irc; 318 user_t *t, *u; 307 bee_t *bee = ic->bee; 319 308 account_t *a; 309 GSList *l; 320 310 int delay; 321 311 … … 337 327 ic->away = NULL; 338 328 339 u = irc->users; 340 while( u ) 341 { 342 if( u->ic == ic ) 343 { 344 t = u->next; 345 user_del( irc, u->nick ); 346 u = t; 347 } 348 else 349 u = u->next; 350 } 351 352 query_del_by_conn( ic->irc, ic ); 353 354 for( a = irc->accounts; a; a = a->next ) 329 for( l = bee->users; l; l = l->next ) 330 { 331 bee_user_t *bu = l->data; 332 333 if( bu->ic == ic ) 334 bee_user_free( bee, ic, bu->handle ); 335 } 336 337 //query_del_by_conn( ic->irc, ic ); 338 339 for( a = bee->accounts; a; a = a->next ) 355 340 if( a->ic == ic ) 356 341 break; … … 360 345 /* Uhm... This is very sick. */ 361 346 } 362 else if( allow_reconnect && set_getbool( & irc->set, "auto_reconnect" ) &&347 else if( allow_reconnect && set_getbool( &bee->set, "auto_reconnect" ) && 363 348 set_getbool( &a->set, "auto_reconnect" ) && 364 349 ( delay = account_reconnect_delay( a ) ) > 0 ) … … 371 356 } 372 357 373 374 /* dialogs.c */375 376 358 void imcb_ask( struct im_connection *ic, char *msg, void *data, 377 359 query_callback doit, query_callback dont ) 378 360 { 379 query_add( ic->irc, ic, msg, doit, dont, data ); 380 } 381 382 383 /* list.c */ 361 //query_add( ic->irc, ic, msg, doit, dont, data ); 362 } 384 363 385 364 void imcb_add_buddy( struct im_connection *ic, const char *handle, const char *group ) 386 365 { 387 user_t *u; 388 char nick[MAX_NICK_LENGTH+1], *s; 389 irc_t *irc = ic->irc; 390 391 if( user_findhandle( ic, handle ) ) 392 { 393 if( set_getbool( &irc->set, "debug" ) ) 366 bee_user_t *bu; 367 bee_t *bee = ic->bee; 368 369 if( bee_user_by_handle( bee, ic, handle ) ) 370 { 371 if( set_getbool( &bee->set, "debug" ) ) 394 372 imcb_log( ic, "User already exists, ignoring add request: %s", handle ); 395 373 … … 402 380 } 403 381 404 memset( nick, 0, MAX_NICK_LENGTH + 1 ); 405 strcpy( nick, nick_get( ic->acc, handle ) ); 406 407 u = user_add( ic->irc, nick ); 408 409 // if( !realname || !*realname ) realname = nick; 410 // u->realname = g_strdup( realname ); 411 412 if( ( s = strchr( handle, '@' ) ) ) 413 { 414 u->host = g_strdup( s + 1 ); 415 u->user = g_strndup( handle, s - handle ); 416 } 417 else if( ic->acc->server ) 418 { 419 u->host = g_strdup( ic->acc->server ); 420 u->user = g_strdup( handle ); 421 422 /* s/ /_/ ... important for AOL screennames */ 423 for( s = u->user; *s; s ++ ) 424 if( *s == ' ' ) 425 *s = '_'; 426 } 427 else 428 { 429 u->host = g_strdup( ic->acc->prpl->name ); 430 u->user = g_strdup( handle ); 431 } 432 433 u->ic = ic; 434 u->handle = g_strdup( handle ); 435 if( group ) u->group = g_strdup( group ); 436 u->send_handler = buddy_send_handler; 437 u->last_typing_notice = 0; 438 } 439 440 struct buddy *imcb_find_buddy( struct im_connection *ic, char *handle ) 441 { 442 static struct buddy b[1]; 443 user_t *u; 444 445 u = user_findhandle( ic, handle ); 446 447 if( !u ) 448 return( NULL ); 449 450 memset( b, 0, sizeof( b ) ); 451 strncpy( b->name, handle, 80 ); 452 strncpy( b->show, u->realname, BUDDY_ALIAS_MAXLEN ); 453 b->present = u->online; 454 b->ic = u->ic; 455 456 return( b ); 457 } 458 459 void imcb_rename_buddy( struct im_connection *ic, const char *handle, const char *realname ) 460 { 461 user_t *u = user_findhandle( ic, handle ); 462 char *set; 463 464 if( !u || !realname ) return; 465 466 if( g_strcasecmp( u->realname, realname ) != 0 ) 467 { 468 if( u->realname != u->nick ) g_free( u->realname ); 469 470 u->realname = g_strdup( realname ); 471 472 if( ( ic->flags & OPT_LOGGED_IN ) && set_getbool( &ic->irc->set, "display_namechanges" ) ) 473 imcb_log( ic, "User `%s' changed name to `%s'", u->nick, u->realname ); 474 } 475 476 set = set_getstr( &ic->acc->set, "nick_source" ); 477 if( strcmp( set, "handle" ) != 0 ) 478 { 479 char *name = g_strdup( realname ); 480 481 if( strcmp( set, "first_name" ) == 0 ) 482 { 483 int i; 484 for( i = 0; name[i] && !isspace( name[i] ); i ++ ) {} 485 name[i] = '\0'; 486 } 487 488 imcb_buddy_nick_hint( ic, handle, name ); 489 490 g_free( name ); 382 bu = bee_user_new( bee, ic, handle ); 383 bu->group = g_strdup( group ); 384 } 385 386 void imcb_rename_buddy( struct im_connection *ic, const char *handle, const char *fullname ) 387 { 388 bee_t *bee = ic->bee; 389 bee_user_t *bu = bee_user_by_handle( bee, ic, handle ); 390 391 if( !bu || !fullname ) return; 392 393 if( !bu->fullname || strcmp( bu->fullname, fullname ) != 0 ) 394 { 395 g_free( bu->fullname ); 396 bu->fullname = g_strdup( fullname ); 397 398 if( bee->ui->user_fullname ) 399 bee->ui->user_fullname( bee, bu ); 491 400 } 492 401 } … … 494 403 void imcb_remove_buddy( struct im_connection *ic, const char *handle, char *group ) 495 404 { 496 user_t *u; 497 498 if( ( u = user_findhandle( ic, handle ) ) ) 499 user_del( ic->irc, u->nick ); 405 bee_user_free( ic->bee, ic, handle ); 500 406 } 501 407 … … 504 410 void imcb_buddy_nick_hint( struct im_connection *ic, const char *handle, const char *nick ) 505 411 { 412 #if 0 506 413 user_t *u = user_findhandle( ic, handle ); 507 414 char newnick[MAX_NICK_LENGTH+1], *orig_nick; … … 518 425 /* Some processing to make sure this string is a valid IRC nickname. */ 519 426 nick_strip( newnick ); 520 if( set_getbool( &ic-> irc->set, "lcnicks" ) )427 if( set_getbool( &ic->bee->set, "lcnicks" ) ) 521 428 nick_lc( newnick ); 522 429 … … 535 442 } 536 443 } 444 #endif 537 445 } 538 446 … … 544 452 }; 545 453 454 #if 0 546 455 static void imcb_ask_auth_cb_no( void *data ) 547 456 { … … 563 472 g_free( cbd ); 564 473 } 474 #endif 565 475 566 476 void imcb_ask_auth( struct im_connection *ic, const char *handle, const char *realname ) 567 477 { 478 #if 0 568 479 struct imcb_ask_cb_data *data = g_new0( struct imcb_ask_cb_data, 1 ); 569 480 char *s, *realname_ = NULL; … … 580 491 data->handle = g_strdup( handle ); 581 492 query_add( ic->irc, ic, s, imcb_ask_auth_cb_yes, imcb_ask_auth_cb_no, data ); 582 } 583 584 493 #endif 494 } 495 496 497 #if 0 585 498 static void imcb_ask_add_cb_no( void *data ) 586 499 { … … 597 510 return imcb_ask_add_cb_no( data ); 598 511 } 512 #endif 599 513 600 514 void imcb_ask_add( struct im_connection *ic, const char *handle, const char *realname ) 601 515 { 516 #if 0 602 517 struct imcb_ask_cb_data *data = g_new0( struct imcb_ask_cb_data, 1 ); 603 518 char *s; … … 612 527 data->handle = g_strdup( handle ); 613 528 query_add( ic->irc, ic, s, imcb_ask_add_cb_yes, imcb_ask_add_cb_no, data ); 614 } 615 616 617 /* server.c */ 618 619 void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags, const char *state, const char *message ) 620 { 529 #endif 530 } 531 532 void imcb_buddy_typing( struct im_connection *ic, char *handle, uint32_t flags ) 533 { 534 #if 0 621 535 user_t *u; 622 int oa, oo; 623 624 u = user_findhandle( ic, (char*) handle ); 625 626 if( !u ) 627 { 628 if( g_strcasecmp( set_getstr( &ic->irc->set, "handle_unknown" ), "add" ) == 0 ) 629 { 630 imcb_add_buddy( ic, (char*) handle, NULL ); 631 u = user_findhandle( ic, (char*) handle ); 632 } 633 else 634 { 635 if( set_getbool( &ic->irc->set, "debug" ) || g_strcasecmp( set_getstr( &ic->irc->set, "handle_unknown" ), "ignore" ) != 0 ) 636 { 637 imcb_log( ic, "imcb_buddy_status() for unknown handle %s:", handle ); 638 imcb_log( ic, "flags = %d, state = %s, message = %s", flags, 639 state ? state : "NULL", message ? message : "NULL" ); 640 } 641 642 return; 643 } 644 } 645 646 oa = u->away != NULL; 647 oo = u->online; 648 649 g_free( u->away ); 650 g_free( u->status_msg ); 651 u->away = u->status_msg = NULL; 652 653 if( ( flags & OPT_LOGGED_IN ) && !u->online ) 654 { 655 irc_spawn( ic->irc, u ); 656 u->online = 1; 657 } 658 else if( !( flags & OPT_LOGGED_IN ) && u->online ) 659 { 660 struct groupchat *c; 661 662 irc_kill( ic->irc, u ); 663 u->online = 0; 664 665 /* Remove him/her from the groupchats to prevent PART messages after he/she QUIT already */ 666 for( c = ic->groupchats; c; c = c->next ) 667 remove_chat_buddy_silent( c, handle ); 668 } 669 670 if( flags & OPT_AWAY ) 671 { 672 if( state && message ) 673 { 674 u->away = g_strdup_printf( "%s (%s)", state, message ); 675 } 676 else if( state ) 677 { 678 u->away = g_strdup( state ); 679 } 680 else if( message ) 681 { 682 u->away = g_strdup( message ); 683 } 684 else 685 { 686 u->away = g_strdup( "Away" ); 687 } 688 } 689 else 690 { 691 u->status_msg = g_strdup( message ); 692 } 693 694 /* LISPy... */ 695 if( ( set_getbool( &ic->irc->set, "away_devoice" ) ) && /* Don't do a thing when user doesn't want it */ 696 ( u->online ) && /* Don't touch offline people */ 697 ( ( ( u->online != oo ) && !u->away ) || /* Voice joining people */ 698 ( ( u->online == oo ) && ( oa == !u->away ) ) ) ) /* (De)voice people changing state */ 699 { 700 char *from; 701 702 if( set_getbool( &ic->irc->set, "simulate_netsplit" ) ) 703 { 704 from = g_strdup( ic->irc->myhost ); 705 } 706 else 707 { 708 from = g_strdup_printf( "%s!%s@%s", ic->irc->mynick, ic->irc->mynick, 709 ic->irc->myhost ); 710 } 711 irc_write( ic->irc, ":%s MODE %s %cv %s", from, ic->irc->channel, 712 u->away?'-':'+', u->nick ); 713 g_free( from ); 714 } 715 } 716 717 void imcb_buddy_msg( struct im_connection *ic, const char *handle, char *msg, uint32_t flags, time_t sent_at ) 718 { 719 irc_t *irc = ic->irc; 720 char *wrapped; 721 user_t *u; 722 723 u = user_findhandle( ic, handle ); 724 725 if( !u ) 726 { 727 char *h = set_getstr( &irc->set, "handle_unknown" ); 728 729 if( g_strcasecmp( h, "ignore" ) == 0 ) 730 { 731 if( set_getbool( &irc->set, "debug" ) ) 732 imcb_log( ic, "Ignoring message from unknown handle %s", handle ); 733 734 return; 735 } 736 else if( g_strncasecmp( h, "add", 3 ) == 0 ) 737 { 738 int private = set_getbool( &irc->set, "private" ); 739 740 if( h[3] ) 741 { 742 if( g_strcasecmp( h + 3, "_private" ) == 0 ) 743 private = 1; 744 else if( g_strcasecmp( h + 3, "_channel" ) == 0 ) 745 private = 0; 746 } 747 748 imcb_add_buddy( ic, handle, NULL ); 749 u = user_findhandle( ic, handle ); 750 u->is_private = private; 751 } 752 else 753 { 754 imcb_log( ic, "Message from unknown handle %s:", handle ); 755 u = user_find( irc, irc->mynick ); 756 } 757 } 758 759 if( ( g_strcasecmp( set_getstr( &ic->irc->set, "strip_html" ), "always" ) == 0 ) || 760 ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) ) 761 strip_html( msg ); 762 763 wrapped = word_wrap( msg, 425 ); 764 irc_msgfrom( irc, u->nick, wrapped ); 765 g_free( wrapped ); 766 } 767 768 void imcb_buddy_typing( struct im_connection *ic, char *handle, uint32_t flags ) 769 { 770 user_t *u; 771 772 if( !set_getbool( &ic->irc->set, "typing_notice" ) ) 536 537 if( !set_getbool( &ic->bee->set, "typing_notice" ) ) 773 538 return; 774 539 … … 780 545 irc_privmsg( ic->irc, u, "PRIVMSG", ic->irc->nick, NULL, buf ); 781 546 } 547 #endif 548 } 549 550 struct bee_user *imcb_buddy_by_handle( struct im_connection *ic, const char *handle ) 551 { 552 return bee_user_by_handle( ic->bee, ic, handle ); 782 553 } 783 554 784 555 struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle ) 785 556 { 557 #if 0 786 558 struct groupchat *c; 787 559 … … 801 573 c->topic = g_strdup_printf( "BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!", c->title ); 802 574 803 if( set_getbool( &ic-> irc->set, "debug" ) )575 if( set_getbool( &ic->bee->set, "debug" ) ) 804 576 imcb_log( ic, "Creating new conversation: (id=%p,handle=%s)", c, handle ); 805 577 806 578 return c; 579 #endif 580 return NULL; 807 581 } 808 582 809 583 void imcb_chat_free( struct groupchat *c ) 810 584 { 585 #if 0 811 586 struct im_connection *ic = c->ic; 812 587 struct groupchat *l; 813 588 GList *ir; 814 589 815 if( set_getbool( &ic-> irc->set, "debug" ) )590 if( set_getbool( &ic->bee->set, "debug" ) ) 816 591 imcb_log( ic, "You were removed from conversation %p", c ); 817 592 … … 846 621 g_free( c ); 847 622 } 623 #endif 848 624 } 849 625 850 626 void imcb_chat_msg( struct groupchat *c, const char *who, char *msg, uint32_t flags, time_t sent_at ) 851 627 { 628 #if 0 852 629 struct im_connection *ic = c->ic; 853 630 char *wrapped; … … 860 637 u = user_findhandle( ic, who ); 861 638 862 if( ( g_strcasecmp( set_getstr( &ic-> irc->set, "strip_html" ), "always" ) == 0 ) ||863 ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic-> irc->set, "strip_html" ) ) )639 if( ( g_strcasecmp( set_getstr( &ic->bee->set, "strip_html" ), "always" ) == 0 ) || 640 ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->bee->set, "strip_html" ) ) ) 864 641 strip_html( msg ); 865 642 … … 874 651 } 875 652 g_free( wrapped ); 653 #endif 876 654 } 877 655 878 656 void imcb_chat_log( struct groupchat *c, char *format, ... ) 879 657 { 658 #if 0 880 659 irc_t *irc = c->ic->irc; 881 660 va_list params; … … 892 671 893 672 g_free( text ); 673 #endif 894 674 } 895 675 896 676 void imcb_chat_topic( struct groupchat *c, char *who, char *topic, time_t set_at ) 897 677 { 678 #if 0 898 679 struct im_connection *ic = c->ic; 899 680 user_t *u = NULL; … … 906 687 u = user_findhandle( ic, who ); 907 688 908 if( ( g_strcasecmp( set_getstr( &ic-> irc->set, "strip_html" ), "always" ) == 0 ) ||909 ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic-> irc->set, "strip_html" ) ) )689 if( ( g_strcasecmp( set_getstr( &ic->bee->set, "strip_html" ), "always" ) == 0 ) || 690 ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->bee->set, "strip_html" ) ) ) 910 691 strip_html( topic ); 911 692 … … 915 696 if( c->joined && u ) 916 697 irc_write( ic->irc, ":%s!%s@%s TOPIC %s :%s", u->nick, u->user, u->host, c->channel, topic ); 917 } 918 919 920 /* buddy_chat.c */ 698 #endif 699 } 921 700 922 701 void imcb_chat_add_buddy( struct groupchat *b, const char *handle ) 923 702 { 703 #if 0 924 704 user_t *u = user_findhandle( b->ic, handle ); 925 705 int me = 0; 926 706 927 if( set_getbool( &b->ic-> irc->set, "debug" ) )707 if( set_getbool( &b->ic->bee->set, "debug" ) ) 928 708 imcb_log( b->ic, "User %s added to conversation %p", handle, b ); 929 709 … … 952 732 b->in_room = g_list_append( b->in_room, g_strdup( handle ) ); 953 733 } 734 #endif 954 735 } 955 736 … … 957 738 void imcb_chat_remove_buddy( struct groupchat *b, const char *handle, const char *reason ) 958 739 { 740 #if 0 959 741 user_t *u; 960 742 int me = 0; 961 743 962 if( set_getbool( &b->ic-> irc->set, "debug" ) )744 if( set_getbool( &b->ic->bee->set, "debug" ) ) 963 745 imcb_log( b->ic, "User %s removed from conversation %p (%s)", handle, b, reason ? reason : "" ); 964 746 … … 980 762 if( me || ( remove_chat_buddy_silent( b, handle ) && b->joined && u ) ) 981 763 irc_part( b->ic->irc, u, b->channel ); 982 } 983 764 #endif 765 } 766 767 #if 0 984 768 static int remove_chat_buddy_silent( struct groupchat *b, const char *handle ) 985 769 { … … 1000 784 } 1001 785 1002 return( 0 ); 1003 } 786 return 0; 787 } 788 #endif 1004 789 1005 790 1006 791 /* Misc. BitlBee stuff which shouldn't really be here */ 1007 792 #if 0 1008 793 char *set_eval_away_devoice( set_t *set, char *value ) 1009 794 { … … 1018 803 /* Horror.... */ 1019 804 1020 if( st != set_getbool( &irc-> set, "away_devoice" ) )805 if( st != set_getbool( &irc->b->set, "away_devoice" ) ) 1021 806 { 1022 807 char list[80] = ""; … … 1060 845 return value; 1061 846 } 1062 847 #endif 1063 848 1064 849 … … 1067 852 them all from some wrappers. We'll start to define some down here: */ 1068 853 1069 int imc_ buddy_msg( struct im_connection *ic, char *handle, char *msg, int flags )854 int imc_chat_msg( struct groupchat *c, char *msg, int flags ) 1070 855 { 1071 856 char *buf = NULL; 1072 int st; 1073 1074 if( ( ic->flags & OPT_DOES_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) ) 857 858 if( ( c->ic->flags & OPT_DOES_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) ) 1075 859 { 1076 860 buf = escape_html( msg ); … … 1078 862 } 1079 863 1080 st = ic->acc->prpl->buddy_msg( ic, handle, msg, flags );1081 g_free( buf );1082 1083 return st;1084 }1085 1086 int imc_chat_msg( struct groupchat *c, char *msg, int flags )1087 {1088 char *buf = NULL;1089 1090 if( ( c->ic->flags & OPT_DOES_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) )1091 {1092 buf = escape_html( msg );1093 msg = buf;1094 }1095 1096 864 c->ic->acc->prpl->chat_msg( c, msg, flags ); 1097 865 g_free( buf ); … … 1107 875 1108 876 away = set_getstr( &ic->acc->set, "away" ) ? 1109 : set_getstr( &ic-> irc->set, "away" );877 : set_getstr( &ic->bee->set, "away" ); 1110 878 if( away && *away ) 1111 879 { … … 1118 886 away = NULL; 1119 887 msg = set_getstr( &ic->acc->set, "status" ) ? 1120 : set_getstr( &ic-> irc->set, "status" );888 : set_getstr( &ic->bee->set, "status" ); 1121 889 } 1122 890 -
protocols/nogaim.h
r3ab1d31 ra87e6ba 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * 4 * Copyright 2002-20 04Wilmer van der Gaast and others *4 * Copyright 2002-2010 Wilmer van der Gaast and others * 5 5 \********************************************************************/ 6 6 … … 87 87 88 88 /* BitlBee */ 89 irc_t *irc;89 bee_t *bee; 90 90 91 91 struct groupchat *groupchats; … … 286 286 G_MODULE_EXPORT void imcb_buddy_nick_hint( struct im_connection *ic, const char *handle, const char *nick ); 287 287 288 /* Buddy activity */289 /* To manipulate the status of a handle.290 * - flags can be |='d with OPT_* constants. You will need at least:291 * OPT_LOGGED_IN and OPT_AWAY.292 * - 'state' and 'message' can be NULL */293 G_MODULE_EXPORT void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags, const char *state, const char *message );294 /* Not implemented yet! */ G_MODULE_EXPORT void imcb_buddy_times( struct im_connection *ic, const char *handle, time_t login, time_t idle );295 /* Call when a handle says something. 'flags' and 'sent_at may be just 0. */296 G_MODULE_EXPORT void imcb_buddy_msg( struct im_connection *ic, const char *handle, char *msg, uint32_t flags, time_t sent_at );297 288 G_MODULE_EXPORT void imcb_buddy_typing( struct im_connection *ic, char *handle, uint32_t flags ); 289 G_MODULE_EXPORT struct bee_user *imcb_buddy_by_handle( struct im_connection *ic, const char *handle ); 298 290 G_MODULE_EXPORT void imcb_clean_handle( struct im_connection *ic, char *handle ); 299 291 … … 320 312 /* Actions, or whatever. */ 321 313 int imc_away_send_update( struct im_connection *ic ); 322 int imc_buddy_msg( struct im_connection *ic, char *handle, char *msg, int flags );323 314 int imc_chat_msg( struct groupchat *c, char *msg, int flags ); 324 315 -
protocols/oscar/oscar.c
r3ab1d31 ra87e6ba 1190 1190 aim_ssi_auth_reply(od->sess, od->conn, uin, 1, ""); 1191 1191 // aim_send_im_ch4(od->sess, uin, AIM_ICQMSG_AUTHGRANTED, &message); 1192 if(imcb_find_buddy(data->ic, uin) == NULL) 1193 imcb_ask_add(data->ic, uin, NULL); 1192 imcb_ask_add(data->ic, uin, NULL); 1194 1193 1195 1194 g_free(uin); … … 1952 1951 struct oscar_data *odata = (struct oscar_data *)g->proto_data; 1953 1952 if (odata->icq) { 1953 /** FIXME(wilmer): Hmm, lost the ability to get away msgs here, do we care to get that back? 1954 1954 struct buddy *budlight = imcb_find_buddy(g, who); 1955 1955 if (budlight) … … 1957 1957 if (budlight->caps & AIM_CAPS_ICQSERVERRELAY) 1958 1958 aim_send_im_ch2_geticqmessage(odata->sess, who, (budlight->uc & 0xff80) >> 7); 1959 */ 1959 1960 } else 1960 1961 aim_getinfo(odata->sess, odata->conn, who, AIM_GETINFO_AWAYMESSAGE); … … 2094 2095 switch (curitem->type) { 2095 2096 case 0x0000: /* Buddy */ 2096 if ((curitem->name) && (!imcb_ find_buddy(ic, nrm))) {2097 if ((curitem->name) && (!imcb_buddy_by_handle(ic, nrm))) { 2097 2098 char *realname = NULL; 2098 2099 -
root_commands.c
r3ab1d31 ra87e6ba 32 32 #include <string.h> 33 33 34 void root_command_string( irc_t *irc, user_t *u, char *command, int flags)34 void root_command_string( irc_t *irc, char *command ) 35 35 { 36 36 char *cmd[IRC_MAX_ARGS]; … … 161 161 irc->status |= USTATUS_IDENTIFIED; 162 162 irc_umode_set( irc, "+R", 1 ); 163 if( set_getbool( &irc-> set, "auto_connect" ) )163 if( set_getbool( &irc->b->set, "auto_connect" ) ) 164 164 cmd_account( irc, account_on ); 165 165 break; … … 201 201 storage_status_t status; 202 202 203 status = storage_remove (irc-> nick, cmd[1]);203 status = storage_remove (irc->user->nick, cmd[1]); 204 204 switch (status) { 205 205 case STORAGE_NO_SUCH_USER: … … 213 213 irc->status &= ~USTATUS_IDENTIFIED; 214 214 irc_umode_set( irc, "-R", 1 ); 215 irc_usermsg( irc, "Account `%s' removed", irc-> nick );215 irc_usermsg( irc, "Account `%s' removed", irc->user->nick ); 216 216 break; 217 217 default: … … 221 221 } 222 222 223 static void cmd_save( irc_t *irc, char **cmd ) 224 { 225 if( ( irc->status & USTATUS_IDENTIFIED ) == 0 ) 226 irc_usermsg( irc, "Please create an account first" ); 227 else if( storage_save( irc, NULL, TRUE ) == STORAGE_OK ) 228 irc_usermsg( irc, "Configuration saved" ); 229 else 230 irc_usermsg( irc, "Configuration could not be saved!" ); 231 } 232 223 233 struct cmd_account_del_data 224 234 { … … 232 242 account_t *a; 233 243 234 for( a = cad->irc-> accounts; a && a != cad->a; a = a->next );244 for( a = cad->irc->b->accounts; a && a != cad->a; a = a->next ); 235 245 236 246 if( a == NULL ) … … 244 254 else 245 255 { 246 account_del( cad->irc , a );256 account_del( cad->irc->b, a ); 247 257 irc_usermsg( cad->irc, "Account deleted" ); 248 258 } … … 285 295 set_name = set_full; 286 296 287 head = &irc-> set;297 head = &irc->b->set; 288 298 } 289 299 else … … 356 366 account_t *a; 357 367 358 if( ( a = account_get( irc , id ) ) )368 if( ( a = account_get( irc->b, id ) ) ) 359 369 return &a->set; 360 370 else … … 404 414 } 405 415 406 a = account_add( irc , prpl, cmd[3], cmd[4] );416 a = account_add( irc->b, prpl, cmd[3], cmd[4] ); 407 417 if( cmd[5] ) 408 418 { … … 418 428 MIN_ARGS( 2 ); 419 429 420 if( !( a = account_get( irc , cmd[2] ) ) )430 if( !( a = account_get( irc->b, cmd[2] ) ) ) 421 431 { 422 432 irc_usermsg( irc, "Invalid account" ); … … 440 450 "set' command. Are you sure you want to delete this " 441 451 "account?", a->prpl->name, a->user ); 442 query_add( irc, NULL, msg, cmd_account_del_yes, cmd_account_del_no, cad );452 //query_add( irc, NULL, msg, cmd_account_del_yes, cmd_account_del_no, cad ); 443 453 g_free( msg ); 444 454 } … … 451 461 irc_usermsg( irc, "Account list:" ); 452 462 453 for( a = irc-> accounts; a; a = a->next )463 for( a = irc->b->accounts; a; a = a->next ) 454 464 { 455 465 char *con; … … 474 484 if( cmd[2] ) 475 485 { 476 if( ( a = account_get( irc , cmd[2] ) ) )486 if( ( a = account_get( irc->b, cmd[2] ) ) ) 477 487 { 478 488 if( a->ic ) … … 483 493 else 484 494 { 485 account_on( irc , a );495 account_on( irc->b, a ); 486 496 } 487 497 } … … 494 504 else 495 505 { 496 if ( irc->accounts ) { 506 if ( irc->b->accounts ) 507 { 497 508 irc_usermsg( irc, "Trying to get all accounts connected..." ); 498 509 499 for( a = irc-> accounts; a; a = a->next )510 for( a = irc->b->accounts; a; a = a->next ) 500 511 if( !a->ic && a->auto_connect ) 501 account_on( irc , a );512 account_on( irc->b, a ); 502 513 } 503 514 else … … 513 524 irc_usermsg( irc, "Deactivating all active (re)connections..." ); 514 525 515 for( a = irc-> accounts; a; a = a->next )526 for( a = irc->b->accounts; a; a = a->next ) 516 527 { 517 528 if( a->ic ) 518 account_off( irc , a );529 account_off( irc->b, a ); 519 530 else if( a->reconnect ) 520 531 cancel_auto_reconnect( a ); 521 532 } 522 533 } 523 else if( ( a = account_get( irc , cmd[2] ) ) )534 else if( ( a = account_get( irc->b, cmd[2] ) ) ) 524 535 { 525 536 if( a->ic ) 526 537 { 527 account_off( irc , a );538 account_off( irc->b, a ); 528 539 } 529 540 else if( a->reconnect ) … … 556 567 } 557 568 569 #if 0 558 570 static void cmd_add( irc_t *irc, char **cmd ) 559 571 { … … 644 656 } 645 657 } 658 #endif 646 659 647 660 static void cmd_rename( irc_t *irc, char **cmd ) 648 661 { 649 user_t *u; 650 651 if( g_strcasecmp( cmd[1], irc->nick ) == 0 ) 662 irc_user_t *iu; 663 664 iu = irc_user_by_name( irc, cmd[1] ); 665 666 if( iu == NULL ) 667 { 668 irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] ); 669 } 670 else if( iu == irc->user ) 652 671 { 653 672 irc_usermsg( irc, "Nick `%s' can't be changed", cmd[1] ); 654 673 } 655 else if( g_strcasecmp( cmd[1], irc->channel ) == 0 ) 656 { 657 if( strchr( CTYPES, cmd[2][0] ) && nick_ok( cmd[2] + 1 ) ) 658 { 659 u = user_find( irc, irc->nick ); 660 661 irc_part( irc, u, irc->channel ); 662 g_free( irc->channel ); 663 irc->channel = g_strdup( cmd[2] ); 664 irc_join( irc, u, irc->channel ); 665 666 if( strcmp( cmd[0], "set_rename" ) != 0 ) 667 set_setstr( &irc->set, "control_channel", cmd[2] ); 668 } 669 } 670 else if( user_find( irc, cmd[2] ) && ( nick_cmp( cmd[1], cmd[2] ) != 0 ) ) 674 else if( !nick_ok( cmd[2] ) ) 675 { 676 irc_usermsg( irc, "Nick `%s' is invalid", cmd[2] ); 677 } 678 else if( irc_user_by_name( irc, cmd[2] ) ) 671 679 { 672 680 irc_usermsg( irc, "Nick `%s' already exists", cmd[2] ); 673 681 } 674 else if( !nick_ok( cmd[2] ) ) 675 { 676 irc_usermsg( irc, "Nick `%s' is invalid", cmd[2] ); 677 } 678 else if( !( u = user_find( irc, cmd[1] ) ) ) 679 { 680 irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] ); 681 } 682 else 683 { 684 user_rename( irc, cmd[1], cmd[2] ); 685 irc_write( irc, ":%s!%s@%s NICK %s", cmd[1], u->user, u->host, cmd[2] ); 686 if( g_strcasecmp( cmd[1], irc->mynick ) == 0 ) 687 { 688 g_free( irc->mynick ); 689 irc->mynick = g_strdup( cmd[2] ); 690 682 else 683 { 684 if( !irc_user_set_nick( iu, cmd[2] ) ) 685 { 686 irc_usermsg( irc, "Error while changing nick" ); 687 return; 688 } 689 690 if( iu == irc->root ) 691 { 691 692 /* If we're called internally (user did "set root_nick"), 692 693 let's not go O(INF). :-) */ 693 694 if( strcmp( cmd[0], "set_rename" ) != 0 ) 694 set_setstr( &irc-> set, "root_nick", cmd[2] );695 } 696 else if( u->send_handler == buddy_send_handler)697 { 698 nick_set( u->ic->acc,u->handle, cmd[2] );695 set_setstr( &irc->b->set, "root_nick", cmd[2] ); 696 } 697 else if( iu->bu ) 698 { 699 nick_set( iu->bu->ic->acc, iu->bu->handle, cmd[2] ); 699 700 } 700 701 … … 703 704 } 704 705 706 #if 0 705 707 char *set_eval_root_nick( set_t *set, char *new_nick ) 706 708 { … … 913 915 { 914 916 cmd_set_real( irc, cmd, NULL, NULL ); 915 }916 917 static void cmd_save( irc_t *irc, char **cmd )918 {919 if( ( irc->status & USTATUS_IDENTIFIED ) == 0 )920 irc_usermsg( irc, "Please create an account first" );921 else if( storage_save( irc, NULL, TRUE ) == STORAGE_OK )922 irc_usermsg( irc, "Configuration saved" );923 else924 irc_usermsg( irc, "Configuration could not be saved!" );925 917 } 926 918 … … 990 982 } 991 983 992 static void cmd_nick( irc_t *irc, char **cmd )993 {994 account_t *a;995 996 if( !cmd[1] || !( a = account_get( irc, cmd[1] ) ) )997 {998 irc_usermsg( irc, "Invalid account");999 }1000 else if( !( a->ic && ( a->ic->flags & OPT_LOGGED_IN ) ) )1001 {1002 irc_usermsg( irc, "That account is not on-line" );1003 }1004 else if ( !cmd[2] )1005 {1006 irc_usermsg( irc, "Your name is `%s'" , a->ic->displayname ? a->ic->displayname : "NULL" );1007 }1008 else if ( !a->prpl->set_my_name )1009 {1010 irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );1011 }1012 else1013 {1014 irc_usermsg( irc, "Setting your name to `%s'", cmd[2] );1015 1016 a->prpl->set_my_name( a->ic, cmd[2] );1017 }1018 }1019 1020 984 static void cmd_qlist( irc_t *irc, char **cmd ) 1021 985 { … … 1036 1000 else 1037 1001 irc_usermsg( irc, "%d, BitlBee: %s", num, q->question ); 1038 }1039 1040 static void cmd_join_chat( irc_t *irc, char **cmd )1041 {1042 irc_usermsg( irc, "This command is now obsolete. "1043 "Please try the `chat' command instead." );1044 1002 } 1045 1003 … … 1217 1175 } 1218 1176 } 1177 #endif 1219 1178 1220 1179 const command_t commands[] = { 1221 1180 { "help", 0, cmd_help, 0 }, 1181 { "account", 1, cmd_account, 0 }, 1222 1182 { "identify", 1, cmd_identify, 0 }, 1223 1183 { "register", 1, cmd_register, 0 }, 1224 1184 { "drop", 1, cmd_drop, 0 }, 1225 { "account", 1, cmd_account, 0 }, 1185 { "save", 0, cmd_save, 0 }, 1186 #if 0 1226 1187 { "add", 2, cmd_add, 0 }, 1227 1188 { "info", 1, cmd_info, 0 }, 1189 #endif 1228 1190 { "rename", 2, cmd_rename, 0 }, 1191 #if 0 1229 1192 { "remove", 1, cmd_remove, 0 }, 1230 1193 { "block", 1, cmd_block, 0 }, 1231 1194 { "allow", 1, cmd_allow, 0 }, 1232 { "save", 0, cmd_save, 0 },1233 1195 { "set", 0, cmd_set, 0 }, 1234 1196 { "yes", 0, cmd_yesno, 0 }, … … 1240 1202 { "chat", 1, cmd_chat, 0 }, 1241 1203 { "transfer", 0, cmd_transfer, 0 }, 1204 #endif 1242 1205 { NULL } 1243 1206 }; -
set.c
r3ab1d31 ra87e6ba 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 */ -
storage_xml.c
r3ab1d31 ra87e6ba 147 147 arc_decode( pass_cr, pass_len, &password, xd->given_pass ) ) 148 148 { 149 xd->current_account = account_add( irc , prpl, handle, password );149 xd->current_account = account_add( irc->b, prpl, handle, password ); 150 150 if( server ) 151 151 set_setstr( &xd->current_account->set, "server", server ); … … 181 181 xd->current_set_head = &xd->current_account->set; 182 182 else 183 xd->current_set_head = &xd->irc-> set;183 xd->current_set_head = &xd->irc->b->set; 184 184 185 185 xd->current_setting = g_strdup( setting ); … … 215 215 if( xd->current_account && handle && channel ) 216 216 { 217 xd->current_chat = chat_add( xd->irc, xd->current_account, handle, channel );217 //xd->current_chat = chat_add( xd->irc, xd->current_account, handle, channel ); 218 218 } 219 219 else … … 353 353 static storage_status_t xml_load( irc_t *irc, const char *password ) 354 354 { 355 return xml_load_real( irc, irc-> nick, password, XML_PASS_UNKNOWN );355 return xml_load_real( irc, irc->user->nick, password, XML_PASS_UNKNOWN ); 356 356 } 357 357 … … 396 396 md5_state_t md5_state; 397 397 398 path2 = g_strdup( irc-> nick );398 path2 = g_strdup( irc->user->nick ); 399 399 nick_lc( path2 ); 400 400 g_snprintf( path, sizeof( path ) - 2, "%s%s%s", global.conf->configdir, path2, ".xml" ); … … 422 422 pass_buf = base64_encode( pass_md5, 21 ); 423 423 424 if( !xml_printf( fd, 0, "<user nick=\"%s\" password=\"%s\" version=\"%d\">\n", irc-> nick, pass_buf, XML_FORMAT_VERSION ) )424 if( !xml_printf( fd, 0, "<user nick=\"%s\" password=\"%s\" version=\"%d\">\n", irc->user->nick, pass_buf, XML_FORMAT_VERSION ) ) 425 425 goto write_error; 426 426 427 427 g_free( pass_buf ); 428 428 429 for( set = irc-> set; set; set = set->next )429 for( set = irc->b->set; set; set = set->next ) 430 430 if( set->value ) 431 431 if( !xml_printf( fd, 1, "<setting name=\"%s\">%s</setting>\n", set->key, set->value ) ) 432 432 goto write_error; 433 433 434 for( acc = irc-> accounts; acc; acc = acc->next )434 for( acc = irc->b->accounts; acc; acc = acc->next ) 435 435 { 436 436 unsigned char *pass_cr; … … 470 470 goto write_error; 471 471 472 #if 0 472 473 for( c = irc->chatrooms; c; c = c->next ) 473 474 { … … 488 489 goto write_error; 489 490 } 491 #endif 490 492 491 493 if( !xml_printf( fd, 1, "</account>\n" ) )
Note: See TracChangeset
for help on using the changeset viewer.