Changes in / [a87e6ba:3ab1d31]
- Files:
-
- 6 added
- 12 deleted
- 27 edited
Legend:
- Unmodified
- Added
- Removed
-
Makefile
ra87e6ba r3ab1d31 10 10 11 11 # Program variables 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) 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 14 13 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 15 14 subdirs = lib protocols -
bitlbee.h
ra87e6ba r3ab1d31 124 124 #define CONF_FILE_DEF ETCDIR "bitlbee.conf" 125 125 126 #include "bee.h"127 126 #include "irc.h" 128 127 #include "storage.h" … … 159 158 gboolean bitlbee_io_current_client_write( gpointer data, gint source, b_input_condition cond ); 160 159 161 void root_command_string( irc_t *irc, char *command);160 void root_command_string( irc_t *irc, user_t *u, char *command, int flags ); 162 161 void root_command( irc_t *irc, char *command[] ); 163 162 gboolean bitlbee_shutdown( gpointer data, gint fd, b_input_condition cond ); -
conf.c
ra87e6ba r3ab1d31 369 369 if( g_strcasecmp( ini->section, "defaults" ) == 0 ) 370 370 { 371 set_t *s = set_find( &irc-> b->set, ini->key );371 set_t *s = set_find( &irc->set, ini->key ); 372 372 373 373 if( s ) -
dcc.c
ra87e6ba r3ab1d31 61 61 unsigned int receivedchunks=0, receiveddata=0; 62 62 63 void dcc_finish( file_transfer_t *file );64 void dcc_close( file_transfer_t *file );63 static void dcc_finish( file_transfer_t *file ); 64 static 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, irc_user_t *iu, struct sockaddr_storage *saddr ); 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 ); 67 68 gboolean dccs_recv_proto( gpointer data, gint fd, b_input_condition cond); 68 69 gboolean dccs_recv_write_request( file_transfer_t *ft ); … … 70 71 gboolean dcc_abort( dcc_file_transfer_t *df, char *reason, ... ); 71 72 72 dcc_file_transfer_t *dcc_alloc_transfer( const char *file_name, size_t file_size, struct im_connection *ic ) 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 ) 73 112 { 74 113 file_transfer_t *file = g_new0( file_transfer_t, 1 ); … … 85 124 86 125 /* This is where the sending magic starts... */ 87 file_transfer_t *dccs_send_start( struct im_connection *ic, irc_user_t *iu, constchar *file_name, size_t file_size )126 file_transfer_t *dccs_send_start( struct im_connection *ic, char *user_nick, char *file_name, size_t file_size ) 88 127 { 89 128 file_transfer_t *file; 90 129 dcc_file_transfer_t *df; 91 irc_t *irc = (irc_t *) ic->bee->ui_data;92 130 struct sockaddr_storage saddr; 93 131 char *errmsg; … … 112 150 file->status = FT_STATUS_LISTENING; 113 151 114 if( !dccs_send_request( df, iu, &saddr ) )152 if( !dccs_send_request( df, user_nick, &saddr ) ) 115 153 return NULL; 116 154 … … 118 156 df->watch_in = b_input_add( df->fd, GAIM_INPUT_READ, dccs_send_proto, df ); 119 157 120 irc->file_transfers = g_slist_prepend(irc->file_transfers, file );158 df->ic->irc->file_transfers = g_slist_prepend( df->ic->irc->file_transfers, file ); 121 159 122 160 df->progress_timeout = b_timeout_add( DCC_MAX_STALL * 1000, dcc_progress, df ); … … 125 163 "Accept the file transfer if you'd like the file. If you don't, " 126 164 "issue the 'transfers reject' command.", 127 iu->nick, file_name, file_size / 1024 );165 user_nick, file_name, file_size / 1024 ); 128 166 129 167 return file; … … 178 216 179 217 /* Creates the "DCC SEND" line and sends it to the server */ 180 int dccs_send_request( struct dcc_file_transfer *df, irc_user_t *iu, struct sockaddr_storage *saddr )218 int dccs_send_request( struct dcc_file_transfer *df, char *user_nick, struct sockaddr_storage *saddr ) 181 219 { 182 220 char ipaddr[INET6_ADDRSTRLEN]; … … 212 250 df->ft->file_name, ipaddr, port, df->ft->file_size ); 213 251 214 irc_send_msg_raw( iu, "PRIVMSG", iu->irc->user->nick, cmd ); 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 ); 215 254 216 255 g_free( cmd ); … … 457 496 * Cleans up after a transfer. 458 497 */ 459 void dcc_close( file_transfer_t *file )498 static void dcc_close( file_transfer_t *file ) 460 499 { 461 500 dcc_file_transfer_t *df = file->priv; 462 irc_t *irc = (irc_t *) df->ic->bee->ui_data;463 501 464 502 if( file->free ) … … 476 514 b_event_remove( df->progress_timeout ); 477 515 478 irc->file_transfers = g_slist_remove(irc->file_transfers, file );516 df->ic->irc->file_transfers = g_slist_remove( df->ic->irc->file_transfers, file ); 479 517 480 518 g_free( df ); … … 506 544 file_transfer_t *dcc_request( struct im_connection *ic, char *line ) 507 545 { 508 irc_t *irc = (irc_t *) ic->bee->ui_data;509 546 char *pattern = "SEND" 510 547 " (([^\"][^ ]*)|\"(([^\"]|\\\")*)\")" … … 590 627 g_free( input ); 591 628 592 irc->file_transfers = g_slist_prepend(irc->file_transfers, ft );629 df->ic->irc->file_transfers = g_slist_prepend( df->ic->irc->file_transfers, ft ); 593 630 594 631 return ft; -
dcc.h
ra87e6ba r3ab1d31 95 95 } dcc_file_transfer_t; 96 96 97 file_transfer_t *dccs_send_start( struct im_connection *ic, irc_user_t *iu, const char *file_name, size_t file_size ); 97 file_transfer_t *dccs_send_start( struct im_connection *ic, char *user_nick, char *file_name, size_t file_size ); 98 98 99 void dcc_canceled( file_transfer_t *file, char *reason ); 100 99 101 gboolean dccs_send_write( file_transfer_t *file, char *data, unsigned int data_size ); 102 100 103 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 );104 105 104 #endif -
ipc.c
ra87e6ba r3ab1d31 138 138 139 139 if( strchr( irc->umode, 'w' ) ) 140 irc_write( irc, ":%s WALLOPS :%s", irc-> root->host, cmd[1] );140 irc_write( irc, ":%s WALLOPS :%s", irc->myhost, cmd[1] ); 141 141 } 142 142 … … 147 147 148 148 if( strchr( irc->umode, 's' ) ) 149 irc_write( irc, ":%s NOTICE %s :%s", irc-> root->host, irc->user->nick, cmd[1] );149 irc_write( irc, ":%s NOTICE %s :%s", irc->myhost, irc->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-> root->host, irc->user->nick, cmd[1] );158 irc_write( irc, ":%s NOTICE %s :*** OperMsg *** %s", irc->myhost, irc->nick, cmd[1] ); 159 159 } 160 160 … … 176 176 return; 177 177 178 if( nick_cmp( cmd[1], irc-> user->nick ) != 0 )178 if( nick_cmp( cmd[1], irc->nick ) != 0 ) 179 179 return; /* It's not for us. */ 180 180 181 irc_write( irc, ":%s!%s@%s KILL %s :%s", irc-> root->nick, irc->root->nick, irc->root->host, irc->user->nick, cmd[2] );181 irc_write( irc, ":%s!%s@%s KILL %s :%s", irc->mynick, irc->mynick, irc->myhost, irc->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-> user->host, irc->user->nick, irc->user->fullname );190 ipc_to_master_str( "HELLO %s %s :%s\r\n", irc->host, irc->nick, irc->realname ); 191 191 } 192 192 -
irc.c
ra87e6ba r3ab1d31 5 5 \********************************************************************/ 6 6 7 /* The IRC-based UI (for now the only one)*/7 /* The big hairy IRCd part of the project */ 8 8 9 9 /* … … 24 24 */ 25 25 26 #define BITLBEE_CORE 26 27 #include "bitlbee.h" 28 #include "sock.h" 27 29 #include "ipc.h" 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 ); 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 } 33 98 34 99 irc_t *irc_new( int fd ) … … 37 102 struct sockaddr_storage sock; 38 103 socklen_t socklen = sizeof( sock ); 39 char *host = NULL, *myhost = NULL;40 irc_user_t *iu;41 104 set_t *s; 42 bee_t *b;43 105 44 106 irc = g_new0( irc_t, 1 ); … … 52 114 irc->last_pong = gettime(); 53 115 54 irc-> nick_user_hash = g_hash_table_new( g_str_hash, g_str_equal );116 irc->userhash = g_hash_table_new( g_str_hash, g_str_equal ); 55 117 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 ); 56 122 57 123 irc->iconv = (GIConv) -1; … … 60 126 if( global.conf->hostname ) 61 127 { 62 myhost = g_strdup( global.conf->hostname );128 irc->myhost = g_strdup( global.conf->hostname ); 63 129 } 64 130 else if( getsockname( irc->fd, (struct sockaddr*) &sock, &socklen ) == 0 ) … … 69 135 NI_MAXHOST, NULL, 0, 0 ) == 0 ) 70 136 { 71 myhost = g_strdup( ipv6_unwrap( buf ) );137 irc->myhost = g_strdup( ipv6_unwrap( buf ) ); 72 138 } 73 139 } … … 80 146 NI_MAXHOST, NULL, 0, 0 ) == 0 ) 81 147 { 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" );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" ); 90 156 91 157 if( global.conf->ping_interval > 0 && global.conf->ping_timeout > 0 ) 92 158 irc->ping_source_id = b_timeout_add( global.conf->ping_interval * 1000, irc_userping, irc ); 159 160 irc_write( irc, ":%s NOTICE AUTH :%s", irc->myhost, "BitlBee-IRCd initialized, please go on" ); 93 161 94 162 irc_connection_list = g_slist_append( irc_connection_list, irc ); 95 163 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 ); 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 ); 129 192 130 193 conf_loaddefaults( irc ); 131 194 132 195 /* Evaluator sets the iconv/oconv structures. */ 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; 196 set_eval_charset( set_find( &irc->set, "charset" ), set_getstr( &irc->set, "charset" ) ); 197 198 return( irc ); 141 199 } 142 200 … … 159 217 160 218 ipc_to_master_str( "OPERMSG :Client exiting: %s@%s [%s]\r\n", 161 irc-> user->nick ? irc->user->nick : "(NONE)", irc->root->host, reason );219 irc->nick ? irc->nick : "(NONE)", irc->host, reason ); 162 220 163 221 g_free( reason ); … … 169 227 170 228 ipc_to_master_str( "OPERMSG :Client exiting: %s@%s [%s]\r\n", 171 irc-> user->nick ? irc->user->nick : "(NONE)", irc->root->host, "No reason given" );229 irc->nick ? irc->nick : "(NONE)", irc->host, "No reason given" ); 172 230 } 173 231 … … 190 248 } 191 249 192 static gboolean irc_free_hashkey( gpointer key, gpointer value, gpointer data ); 193 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 */ 194 258 void irc_free( irc_t * irc ) 195 259 { 260 user_t *user, *usertmp; 261 196 262 log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd ); 197 263 198 /* 199 if( irc->status & USTATUS_IDENTIFIED && set_getbool( &irc->b->set, "save_on_quit" ) ) 264 if( irc->status & USTATUS_IDENTIFIED && set_getbool( &irc->set, "save_on_quit" ) ) 200 265 if( storage_save( irc, NULL, TRUE ) != STORAGE_OK ) 201 266 irc_usermsg( irc, "Error while saving settings!" ); 202 */203 267 204 268 irc_connection_list = g_slist_remove( irc_connection_list, irc ); 205 269 206 /* 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 207 285 while( irc->queries != NULL ) 208 286 query_del( irc, irc->queries ); 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 ); 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 } 219 309 220 310 if( irc->ping_source_id > 0 ) … … 228 318 irc->fd = -1; 229 319 230 g_hash_table_foreach_remove( irc-> nick_user_hash, irc_free_hashkey, NULL );231 g_hash_table_destroy( irc-> nick_user_hash );320 g_hash_table_foreach_remove( irc->userhash, irc_free_hashkey, NULL ); 321 g_hash_table_destroy( irc->userhash ); 232 322 233 323 g_hash_table_foreach_remove( irc->watches, irc_free_hashkey, NULL ); … … 242 332 g_free( irc->readbuffer ); 243 333 334 g_free( irc->nick ); 335 g_free( irc->user ); 336 g_free( irc->host ); 337 g_free( irc->realname ); 244 338 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 ); 245 346 246 347 g_free( irc ); … … 254 355 } 255 356 256 static gboolean irc_free_hashkey( gpointer key, gpointer value, gpointer data )257 {258 g_free( key );259 260 return( TRUE );261 }262 263 357 /* USE WITH CAUTION! 264 358 Sets pass without checking */ 265 void irc_setpass (irc_t *irc, const char *pass) 359 void irc_setpass (irc_t *irc, const char *pass) 266 360 { 267 361 g_free (irc->password); … … 274 368 } 275 369 276 static char **irc_splitlines( char *buffer );277 278 370 void irc_process( irc_t *irc ) 279 371 { … … 283 375 if( irc->readbuffer != NULL ) 284 376 { 285 lines = irc_ splitlines( irc->readbuffer );377 lines = irc_tokenize( irc->readbuffer ); 286 378 287 379 for( i = 0; *lines[i] != '\0'; i ++ ) … … 320 412 "`help set charset' for more information. Your " 321 413 "message was ignored.", 322 set_getstr( &irc-> b->set, "charset" ) );414 set_getstr( &irc->set, "charset" ) ); 323 415 324 416 g_free( conv ); … … 327 419 else 328 420 { 329 irc_write( irc, ":%s NOTICE AUTH :%s", irc-> root->host,421 irc_write( irc, ":%s NOTICE AUTH :%s", irc->myhost, 330 422 "Warning: invalid characters received at login time." ); 331 423 … … 365 457 } 366 458 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 ) 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 ) 372 462 { 373 463 int i, j, n = 3; … … 500 590 } 501 591 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 502 622 void irc_write( irc_t *irc, char *format, ... ) 503 623 { … … 510 630 return; 511 631 } 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 }541 632 542 633 void irc_vawrite( irc_t *irc, char *format, va_list params ) … … 595 686 } 596 687 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 ) 732 { 733 irc_reply( irc, 353, "= %s :%s", channel, namelist ); 734 *namelist = 0; 735 } 736 737 if( u->ic && !u->away && set_getbool( &irc->set, "away_devoice" ) ) 738 strcat( namelist, "+" ); 739 else if( ( strcmp( u->nick, irc->mynick ) == 0 && ( strcmp( ops, "root" ) == 0 || strcmp( ops, "both" ) == 0 ) ) || 740 ( strcmp( u->nick, irc->nick ) == 0 && ( strcmp( ops, "user" ) == 0 || strcmp( ops, "both" ) == 0 ) ) ) 741 strcat( namelist, "@" ); 742 743 strcat( namelist, u->nick ); 744 strcat( namelist, " " ); 745 } 746 } 747 else if( ( c = irc_chat_by_channel( irc, channel ) ) ) 748 { 749 GList *l; 750 751 /* root and the user aren't in the channel userlist but 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 597 775 int irc_check_login( irc_t *irc ) 598 776 { 599 if( irc->user ->user && irc->user->nick )777 if( irc->user && irc->nick ) 600 778 { 601 779 if( global.conf->authmode == AUTHMODE_CLOSED && !( irc->status & USTATUS_AUTHORIZED ) ) 602 780 { 603 irc_ send_num( irc, 464, ":This server is password-protected." );781 irc_reply( irc, 464, ":This server is password-protected." ); 604 782 return 0; 605 783 } 606 784 else 607 785 { 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 ) 626 { 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] ); 632 } 633 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 786 irc_login( irc ); 645 787 return 1; 646 788 } … … 653 795 } 654 796 655 void irc_umode_set( irc_t *irc, const char *s, gboolean allow_priv ) 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 ) 656 922 { 657 923 /* allow_priv: Set to 0 if s contains user input, 1 if you want 658 924 to set a "privileged" mode (+o, +R, etc). */ 659 char m[128], st = 1; 660 const char *t; 925 char m[256], st = 1, *t; 661 926 int i; 662 927 char changes[512], *p, st2 = 2; … … 666 931 667 932 for( t = irc->umode; *t; t ++ ) 668 if( *t < sizeof( m ) ) 669 m[(int)*t] = 1; 670 933 m[(int)*t] = 1; 934 671 935 p = changes; 672 936 for( t = s; *t; t ++ ) … … 674 938 if( *t == '+' || *t == '-' ) 675 939 st = *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 ) ) ) 940 else if( st == 0 || ( strchr( UMODES, *t ) || ( allow_priv && strchr( UMODES_PRIV, *t ) ) ) ) 679 941 { 680 942 if( m[(int)*t] != st) … … 693 955 memset( irc->umode, 0, sizeof( irc->umode ) ); 694 956 695 for( i = 'A'; i <= 'z'&& strlen( irc->umode ) < ( sizeof( irc->umode ) - 1 ); i ++ )957 for( i = 0; i < 256 && strlen( irc->umode ) < ( sizeof( irc->umode ) - 1 ); i ++ ) 696 958 if( m[i] ) 697 959 irc->umode[strlen(irc->umode)] = i; 698 960 699 961 if( badflag ) 700 irc_send_num( irc, 501, ":Unknown MODE flag" ); 962 irc_reply( irc, 501, ":Unknown MODE flag" ); 963 /* Deliberately no !user@host on the prefix here */ 701 964 if( *changes ) 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 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 } 707 1290 708 1291 /* Returns 0 if everything seems to be okay, a number >0 when there was a … … 742 1325 } 743 1326 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 } 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 } -
irc.h
ra87e6ba r3ab1d31 5 5 \********************************************************************/ 6 6 7 /* The IRC-based UI (for now the only one)*/7 /* The big hairy IRCd part of the project */ 8 8 9 9 /* … … 33 33 #define IRC_PING_STRING "PinglBee" 34 34 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 */ 35 #define UMODES "abisw" 36 #define UMODES_PRIV "Ro" 37 #define CMODES "nt" 38 #define CMODE "t" 39 #define UMODE "s" 40 #define CTYPES "&#" 43 41 44 42 typedef enum … … 50 48 USTATUS_SHUTDOWN = 8 51 49 } irc_status_t; 52 53 struct irc_user;54 50 55 51 typedef struct irc … … 63 59 GIConv iconv, oconv; 64 60 65 struct irc_user *root; 66 struct irc_user *user; 67 68 char *last_root_cmd; 61 int sentbytes; 62 time_t oldtime; 69 63 64 char *nick; 65 char *user; 66 char *host; 67 char *realname; 70 68 char *password; /* HACK: Used to save the user's password, but before 71 69 logging in, this may contain a password we should … … 74 72 char umode[8]; 75 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 76 83 struct query *queries; 84 struct account *accounts; 77 85 GSList *file_transfers; 86 struct chat *chatrooms; 78 87 79 GSList *users, *channels;80 GHashTable * nick_user_hash;88 struct __USER *users; 89 GHashTable *userhash; 81 90 GHashTable *watches; 91 struct __NICK *nicks; 92 struct set *set; 82 93 83 94 gint r_watch_source_id; 84 95 gint w_watch_source_id; 85 96 gint ping_source_id; 86 87 struct bee *b;88 97 } irc_t; 89 98 90 typedef enum 91 { 92 IRC_USER_PRIVATE = 1, 93 } irc_user_flags_t; 99 #include "user.h" 94 100 95 typedef struct irc_user96 {97 irc_t *irc;98 99 char *nick;100 char *user;101 char *host;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_funcs120 {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 enum128 {129 IRC_CHANNEL_JOINED = 1,130 } irc_channel_flags_t;131 132 typedef struct irc_channel133 {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;144 struct set *set;145 146 const struct irc_channel_funcs *f;147 } irc_channel_t;148 149 struct irc_channel_funcs150 {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 */157 101 extern GSList *irc_connection_list; 158 102 … … 160 104 void irc_abort( irc_t *irc, int immed, char *format, ... ) G_GNUC_PRINTF( 3, 4 ); 161 105 void irc_free( irc_t *irc ); 162 void irc_setpass (irc_t *irc, const char *pass);163 106 107 void irc_exec( irc_t *irc, char **cmd ); 164 108 void irc_process( irc_t *irc ); 165 109 char **irc_parse_line( char *line ); 166 110 char *irc_build_line( char **cmd ); 167 111 112 void irc_vawrite( irc_t *irc, char *format, va_list params ); 168 113 void irc_write( irc_t *irc, char *format, ... ) G_GNUC_PRINTF( 2, 3 ); 169 114 void irc_write_all( int now, char *format, ... ) G_GNUC_PRINTF( 2, 3 ); 170 void irc_vawrite( irc_t *irc, char *format, va_list params ); 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 ); 171 118 119 void irc_login( irc_t *irc ); 172 120 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! */ 173 134 174 void irc_umode_set( irc_t *irc, const char *s, gboolean allow_priv ); 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 ); 175 139 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_ ); 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 ); 210 142 211 143 #endif -
irc_commands.c
ra87e6ba r3ab1d31 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * 4 * Copyright 2002-20 10Wilmer van der Gaast and others *4 * Copyright 2002-2006 Wilmer van der Gaast and others * 5 5 \********************************************************************/ 6 6 … … 53 53 else if( global.conf->auth_pass ) 54 54 { 55 irc_ send_num( irc, 464, ":Incorrect password" );55 irc_reply( 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 ->user= g_strdup( cmd[1] );68 irc-> user->fullname = g_strdup( cmd[4] );67 irc->user = g_strdup( cmd[1] ); 68 irc->realname = 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->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" ); 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" ); 82 83 } 83 84 else if( !nick_ok( cmd[1] ) ) 84 85 { 85 86 /* [SH] Invalid characters. */ 86 irc_ send_num( irc, 432, ":This nick contains invalid characters" );87 } 88 else 89 { 90 irc-> user->nick = g_strdup( cmd[1] );87 irc_reply( irc, 432, ":This nick contains invalid characters" ); 88 } 89 else 90 { 91 irc->nick = g_strdup( cmd[1] ); 91 92 92 93 irc_check_login( irc ); … … 104 105 static void irc_cmd_ping( irc_t *irc, char **cmd ) 105 106 { 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 ); 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 } 192 124 } 193 125 194 126 static void irc_cmd_mode( irc_t *irc, char **cmd ) 195 127 { 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] ) 128 if( strchr( CTYPES, *cmd[1] ) ) 129 { 130 if( cmd[2] ) 203 131 { 204 132 if( *cmd[2] == '+' || *cmd[2] == '-' ) 205 irc_ send_num( irc, 477, "%s :Can't change channel modes", cmd[1] );133 irc_reply( irc, 477, "%s :Can't change channel modes", cmd[1] ); 206 134 else if( *cmd[2] == 'b' ) 207 irc_ send_num( irc, 368, "%s :No bans possible", cmd[1] );135 irc_reply( irc, 368, "%s :No bans possible", cmd[1] ); 208 136 } 209 137 else 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 )138 irc_reply( irc, 324, "%s +%s", cmd[1], CMODE ); 139 } 140 else 141 { 142 if( nick_cmp( cmd[1], irc->nick ) == 0 ) 215 143 { 216 144 if( cmd[2] ) 217 145 irc_umode_set( irc, cmd[2], 0 ); 218 146 else 219 irc_ send_num( irc, 221, "+%s", irc->umode );147 irc_reply( irc, 221, "+%s", irc->umode ); 220 148 } 221 149 else 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 ); 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 ); 237 222 } 238 223 239 224 static void irc_cmd_privmsg( irc_t *irc, char **cmd ) 240 225 { 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 { 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] ); 268 233 } 269 234 else … … 306 271 irc_send( irc, cmd[1], cmd[2], ( g_strcasecmp( cmd[0], "NOTICE" ) == 0 ) ? OPT_AWAY : 0 ); 307 272 } 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 ); 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:"**" ); 353 305 } 354 306 … … 368 320 { 369 321 if( u->online && u->away ) 370 irc_ send_num( irc, 302, ":%s=-%s@%s", u->nick, u->user, u->host );322 irc_reply( irc, 302, ":%s=-%s@%s", u->nick, u->user, u->host ); 371 323 else 372 irc_ send_num( irc, 302, ":%s=+%s@%s", u->nick, u->user, u->host );324 irc_reply( irc, 302, ":%s=+%s@%s", u->nick, u->user, u->host ); 373 325 } 374 326 } … … 425 377 buff[strlen(buff)-1] = '\0'; 426 378 427 irc_ send_num( irc, 303, ":%s", buff );379 irc_reply( irc, 303, ":%s", buff ); 428 380 } 429 381 … … 454 406 455 407 if( u && u->online ) 456 irc_ send_num( irc, 604, "%s %s %s %d :%s", u->nick, u->user, u->host, (int) time( NULL ), "is online" );408 irc_reply( irc, 604, "%s %s %s %d :%s", u->nick, u->user, u->host, (int) time( NULL ), "is online" ); 457 409 else 458 irc_ send_num( irc, 605, "%s %s %s %d :%s", nick, "*", "*", (int) time( NULL ), "is offline" );410 irc_reply( irc, 605, "%s %s %s %d :%s", nick, "*", "*", (int) time( NULL ), "is offline" ); 459 411 } 460 412 else if( cmd[i][0] == '-' ) … … 467 419 g_free( okey ); 468 420 469 irc_ send_num( irc, 602, "%s %s %s %d :%s", nick, "*", "*", 0, "Stopped watching" );421 irc_reply( irc, 602, "%s %s %s %d :%s", nick, "*", "*", 0, "Stopped watching" ); 470 422 } 471 423 } … … 511 463 u->away[j] = 0; 512 464 513 irc_ send_num( irc, 306, ":You're now away: %s", u->away );465 irc_reply( irc, 306, ":You're now away: %s", u->away ); 514 466 /* irc_umode_set( irc, irc->myhost, "+a" ); */ 515 467 } … … 519 471 u->away = NULL; 520 472 /* irc_umode_set( irc, irc->myhost, "-a" ); */ 521 irc_ send_num( irc, 305, ":Welcome back" );473 irc_reply( irc, 305, ":Welcome back" ); 522 474 } 523 475 … … 525 477 } 526 478 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 else 493 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 else 505 { 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 can 513 ignore this, but then the user never gets a "user not found" 514 message from irssi which is a bit annoying. So just respond 515 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 in 536 fact we don't care, we're just happy he's still alive. */ 537 irc->last_pong = gettime(); 538 irc->pinging = 0; 539 } 540 527 541 static void irc_cmd_version( irc_t *irc, char **cmd ) 528 542 { 529 irc_ send_num( irc, 351, "bitlbee-%s. %s :%s/%s ", BITLBEE_VERSION, irc->myhost, ARCH, CPU );543 irc_reply( irc, 351, "bitlbee-%s. %s :%s/%s ", BITLBEE_VERSION, irc->myhost, ARCH, CPU ); 530 544 } 531 545 … … 558 572 ipc_to_master( cmd ); 559 573 560 irc_send_num( irc, 382, "%s :Rehashing", global.conf_file ); 561 } 562 #endif 574 irc_reply( irc, 382, "%s :Rehashing", global.conf_file ); 575 } 563 576 564 577 static const command_t irc_commands[] = { … … 568 581 { "quit", 0, irc_cmd_quit, 0 }, 569 582 { "ping", 0, irc_cmd_ping, 0 }, 570 { "pong", 0, irc_cmd_pong, IRC_CMD_LOGGED_IN }, 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 }, 571 587 { "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 }, 588 { "invite", 2, irc_cmd_invite, IRC_CMD_LOGGED_IN }, 589 { "privmsg", 1, irc_cmd_privmsg, IRC_CMD_LOGGED_IN }, 590 { "notice", 1, irc_cmd_privmsg, IRC_CMD_LOGGED_IN }, 578 591 { "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 0583 { "oper", 2, irc_cmd_oper, IRC_CMD_LOGGED_IN },584 { "invite", 2, irc_cmd_invite, IRC_CMD_LOGGED_IN },585 { "notice", 1, irc_cmd_privmsg, IRC_CMD_LOGGED_IN },586 592 { "userhost", 1, irc_cmd_userhost, IRC_CMD_LOGGED_IN }, 587 593 { "ison", 1, irc_cmd_ison, IRC_CMD_LOGGED_IN }, … … 589 595 { "topic", 1, irc_cmd_topic, IRC_CMD_LOGGED_IN }, 590 596 { "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 }, 591 603 { "version", 0, irc_cmd_version, IRC_CMD_LOGGED_IN }, 592 604 { "completions", 0, irc_cmd_completions, IRC_CMD_LOGGED_IN }, … … 598 610 { "restart", 0, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, 599 611 { "kill", 2, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, 600 #endif601 612 { NULL } 602 613 }; … … 617 628 if( irc_commands[i].flags & IRC_CMD_PRE_LOGIN && irc->status & USTATUS_LOGGED_IN ) 618 629 { 619 irc_ send_num( irc, 462, ":Only allowed before logging in" );630 irc_reply( irc, 462, ":Only allowed before logging in" ); 620 631 } 621 632 else if( irc_commands[i].flags & IRC_CMD_LOGGED_IN && !( irc->status & USTATUS_LOGGED_IN ) ) 622 633 { 623 irc_ send_num( irc, 451, ":Register first" );634 irc_reply( irc, 451, ":Register first" ); 624 635 } 625 636 else if( irc_commands[i].flags & IRC_CMD_OPER_ONLY && !strchr( irc->umode, 'o' ) ) 626 637 { 627 irc_ send_num( irc, 481, ":Permission denied - You're not an IRC operator" );638 irc_reply( irc, 481, ":Permission denied - You're not an IRC operator" ); 628 639 } 629 640 else if( n_arg < irc_commands[i].required_parameters ) 630 641 { 631 irc_ send_num( irc, 461, "%s :Need more parameters", cmd[0] );642 irc_reply( irc, 461, "%s :Need more parameters", cmd[0] ); 632 643 } 633 644 else if( irc_commands[i].flags & IRC_CMD_TO_MASTER ) … … 646 657 647 658 if( irc->status >= USTATUS_LOGGED_IN ) 648 irc_ send_num( irc, 421, "%s :Unknown command", cmd[0] );649 } 659 irc_reply( irc, 421, "%s :Unknown command", cmd[0] ); 660 } -
nick.c
ra87e6ba r3ab1d31 78 78 79 79 nick_strip( nick ); 80 if( set_getbool( &acc-> bee->set, "lcnicks" ) )80 if( set_getbool( &acc->irc->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;95 94 int inf_protection = 256; 96 95 97 96 /* Now, find out if the nick is already in use at the moment, and make 98 97 subtle changes to make it unique. */ 99 while( !nick_ok( nick ) || irc_user_by_name(irc, nick ) )98 while( !nick_ok( nick ) || user_find( acc->irc, nick ) ) 100 99 { 101 100 if( strlen( nick ) < ( MAX_NICK_LENGTH - 1 ) ) … … 113 112 int i; 114 113 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 );114 irc_usermsg( acc->irc, "Warning: Almost had an infinite loop in nick_get()! " 115 "This used to be a fatal BitlBee bug, but we tried to fix it. " 116 "This message should *never* appear anymore. " 117 "If it does, please *do* send us a bug report! " 118 "Please send all the following lines in your report:" ); 119 120 irc_usermsg( acc->irc, "Trying to get a sane nick for handle %s", handle ); 122 121 for( i = 0; i < MAX_NICK_LENGTH; i ++ ) 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" );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 "Good luck, and please don't forget to paste the lines up here " 126 "in #bitlbee on OFTC or in a mail to wilmer@gaast.net" ); 128 127 129 128 g_snprintf( nick, MAX_NICK_LENGTH + 1, "xx%x", rand() ); -
protocols/Makefile
ra87e6ba r3ab1d31 10 10 11 11 # [SH] Program variables 12 objects = account.o bee.o bee_ft.o bee_user.o nogaim.o 13 12 objects = nogaim.o 14 13 15 14 # [SH] The next two lines should contain the directory name (in $(subdirs)) -
protocols/ft.h
ra87e6ba r3ab1d31 168 168 * the canceled() and free() callbacks given in file will be called by this function. 169 169 */ 170 void imcb_file_canceled( struct im_connection *ic,file_transfer_t *file, char *reason );170 void imcb_file_canceled( file_transfer_t *file, char *reason ); 171 171 172 gboolean imcb_file_recv_start( struct im_connection *ic,file_transfer_t *ft );172 gboolean imcb_file_recv_start( file_transfer_t *ft ); 173 173 174 void imcb_file_finished( struct im_connection *ic,file_transfer_t *file );174 void imcb_file_finished( file_transfer_t *file ); 175 175 #endif -
protocols/jabber/iq.c
ra87e6ba r3ab1d31 392 392 if( ( strcmp( sub, "both" ) == 0 || strcmp( sub, "to" ) == 0 ) ) 393 393 { 394 if( initial || bee_user_by_handle( ic->bee,ic, jid ) == NULL )394 if( initial || imcb_find_buddy( 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( bee_user_by_handle( ic->bee,ic, jid ) == NULL )592 if( imcb_find_buddy( ic, jid ) == NULL ) 593 593 imcb_add_buddy( ic, jid, NULL ); 594 594 } -
protocols/jabber/jabber.c
ra87e6ba r3ab1d31 267 267 268 268 while( jd->filetransfers ) 269 imcb_file_canceled( ic,( ( struct jabber_transfer *) jd->filetransfers->data )->ft, "Logging out" );269 imcb_file_canceled( ( ( struct jabber_transfer *) jd->filetransfers->data )->ft, "Logging out" ); 270 270 271 271 while( jd->streamhosts ) -
protocols/jabber/jabber_util.c
ra87e6ba r3ab1d31 279 279 presence_send_request( bla->ic, bla->handle, "subscribed" ); 280 280 281 imcb_ask_add( bla->ic, bla->handle, NULL ); 281 if( imcb_find_buddy( bla->ic, bla->handle ) == NULL ) 282 imcb_ask_add( bla->ic, bla->handle, NULL ); 282 283 283 284 g_free( bla->handle ); … … 461 462 462 463 if( bud == NULL && ( flags & GET_BUDDY_CREAT ) && 463 ( bare_exists || bee_user_by_handle( ic->bee,ic, jid ) ) )464 ( bare_exists || imcb_find_buddy( ic, jid ) ) ) 464 465 { 465 466 *s = '/'; … … 482 483 if( bud == NULL ) 483 484 /* No match. Create it now? */ 484 return ( ( flags & GET_BUDDY_CREAT ) && 485 bee_user_by_handle( ic->bee, ic, jid_ ) ) ? 485 return ( ( flags & GET_BUDDY_CREAT ) && imcb_find_buddy( ic, jid_ ) ) ? 486 486 jabber_buddy_add( ic, jid_ ) : NULL; 487 487 else if( bud->resource && ( flags & GET_BUDDY_EXACT ) ) -
protocols/jabber/s5bytestream.c
ra87e6ba r3ab1d31 567 567 xt_free_node( reply ); 568 568 569 imcb_file_canceled( tf-> ic, tf->ft, "couldn't connect to any streamhosts" );569 imcb_file_canceled( 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-> ic, tf->ft, "Error transmitting bytestream response" );606 imcb_file_canceled( 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-> ic, tf->ft );646 imcb_file_finished( 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( tf->ic,ft, "BUG in jabber file transfer: write_request called when already watching for input" );662 imcb_file_canceled( 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( tf->ic,ft );708 imcb_file_finished( 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-> ic, tf->ft, "Error transmitting bytestream request" );1008 imcb_file_canceled( 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-> ic, tf->ft, error );1023 imcb_file_canceled( tf->ft, error ); 1024 1024 1025 1025 /* MUST always return FALSE! */ -
protocols/jabber/si.c
ra87e6ba r3ab1d31 91 91 92 92 if( !foundft ) 93 imcb_file_canceled( tf-> ic, tf->ft, "Buddy's client doesn't feature file transfers" );93 imcb_file_canceled( tf->ft, "Buddy's client doesn't feature file transfers" ); 94 94 else if( !foundbt ) 95 imcb_file_canceled( tf-> ic, tf->ft, "Buddy's client doesn't feature byte streams (required)" );95 imcb_file_canceled( tf->ft, "Buddy's client doesn't feature byte streams (required)" ); 96 96 else if( !foundsi ) 97 imcb_file_canceled( tf-> ic, tf->ft, "Buddy's client doesn't feature stream initiation (required)" );97 imcb_file_canceled( 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-> ic, tf->ft );111 imcb_file_recv_start( tf->ft ); 112 112 113 113 } … … 156 156 if( bud == NULL ) 157 157 { 158 imcb_file_canceled( ic,ft, "Couldn't find buddy (BUG?)" );158 imcb_file_canceled( ft, "Couldn't find buddy (BUG?)" ); 159 159 return; 160 160 } -
protocols/msn/Makefile
ra87e6ba r3ab1d31 10 10 11 11 # [SH] Program variables 12 objects = msn.o msn_util.o ns.o passport.o sb.o tables.o12 objects = invitation.o msn.o msn_util.o ns.o passport.o sb.o tables.o 13 13 14 14 CFLAGS += -Wall -
protocols/msn/msn.c
ra87e6ba r3ab1d31 81 81 if( md ) 82 82 { 83 /** Disabling MSN ft support for now.84 83 while( md->filetransfers ) { 85 84 imcb_file_canceled( md->filetransfers->data, "Closing connection" ); 86 85 } 87 */88 86 89 87 if( md->fd >= 0 ) … … 346 344 ret->send_typing = msn_send_typing; 347 345 ret->handle_cmp = g_strcasecmp; 348 //ret->transfer_request = msn_ftp_transfer_request;346 ret->transfer_request = msn_ftp_transfer_request; 349 347 350 348 register_protocol(ret); -
protocols/msn/msn_util.c
ra87e6ba r3ab1d31 96 96 msn_buddy_list_add( bla->ic, "AL", bla->handle, bla->realname ); 97 97 98 imcb_ask_add( bla->ic, bla->handle, NULL ); 98 if( imcb_find_buddy( bla->ic, bla->handle ) == NULL ) 99 imcb_ask_add( bla->ic, bla->handle, NULL ); 99 100 100 101 g_free( bla->handle ); -
protocols/msn/sb.c
ra87e6ba r3ab1d31 691 691 } 692 692 } 693 #if 0694 // Disable MSN ft support for now.695 693 else if( g_strncasecmp( ct, "text/x-msmsgsinvite", 19 ) == 0 ) 696 694 { … … 725 723 g_free( command ); 726 724 } 727 #endif728 725 else if( g_strncasecmp( ct, "application/x-msnmsgrp2p", 24 ) == 0 ) 729 726 { -
protocols/nogaim.c
ra87e6ba r3ab1d31 38 38 #include "chat.h" 39 39 40 static int remove_chat_buddy_silent( struct groupchat *b, const char *handle ); 41 40 42 GSList *connections; 41 43 … … 89 91 } 90 92 #endif 93 94 /* nogaim.c */ 91 95 92 96 GList *protocols = NULL; … … 121 125 } 122 126 127 /* nogaim.c */ 123 128 void nogaim_init() 124 129 { … … 151 156 GSList *get_connections() { return connections; } 152 157 158 /* multi.c */ 159 153 160 struct im_connection *imcb_new( account_t *acc ) 154 161 { … … 157 164 ic = g_new0( struct im_connection, 1 ); 158 165 159 ic-> bee = acc->bee;166 ic->irc = acc->irc; 160 167 ic->acc = acc; 161 168 acc->ic = ic; … … 171 178 172 179 /* Destroy the pointer to this connection from the account list */ 173 for( a = ic-> bee->accounts; a; a = a->next )180 for( a = ic->irc->accounts; a; a = a->next ) 174 181 if( a->ic == ic ) 175 182 { … … 192 199 va_end( params ); 193 200 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" ) ) )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" ) ) ) 196 203 strip_html( text ); 197 204 198 205 /* Try to find a different connection on the same protocol. */ 199 for( a = ic-> bee->accounts; a; a = a->next )206 for( a = ic->irc->accounts; a; a = a->next ) 200 207 if( a->prpl == ic->acc->prpl && a->ic != ic ) 201 208 break; … … 203 210 /* If we found one, include the screenname in the message. */ 204 211 if( a ) 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 ); 212 irc_usermsg( ic->irc, "%s(%s) - %s", ic->acc->prpl->name, ic->acc->user, text ); 207 213 else 208 irc_usermsg( ic-> bee->ui_data, "%s - %s", ic->acc->prpl->name, text );214 irc_usermsg( ic->irc, "%s - %s", ic->acc->prpl->name, text ); 209 215 210 216 g_free( text ); … … 257 263 void imcb_connected( struct im_connection *ic ) 258 264 { 265 irc_t *irc = ic->irc; 266 struct chat *c; 267 user_t *u; 268 259 269 /* MSN servers sometimes redirect you to a different server and do 260 270 the whole login sequence again, so these "late" calls to this … … 263 273 return; 264 274 275 u = user_find( ic->irc, ic->irc->nick ); 276 265 277 imcb_log( ic, "Logged in" ); 266 278 … … 275 287 ic->acc->auto_reconnect_delay = 0; 276 288 277 /*278 289 for( c = irc->chatrooms; c; c = c->next ) 279 290 { … … 284 295 chat_join( irc, c, NULL ); 285 296 } 286 */287 297 } 288 298 … … 292 302 293 303 a->reconnect = 0; 294 account_on( a-> bee, a );304 account_on( a->irc, a ); 295 305 296 306 return( FALSE ); /* Only have to run the timeout once */ … … 305 315 void imc_logout( struct im_connection *ic, int allow_reconnect ) 306 316 { 307 bee_t *bee = ic->bee; 317 irc_t *irc = ic->irc; 318 user_t *t, *u; 308 319 account_t *a; 309 GSList *l;310 320 int delay; 311 321 … … 327 337 ic->away = NULL; 328 338 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 ) 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 ) 340 355 if( a->ic == ic ) 341 356 break; … … 345 360 /* Uhm... This is very sick. */ 346 361 } 347 else if( allow_reconnect && set_getbool( & bee->set, "auto_reconnect" ) &&362 else if( allow_reconnect && set_getbool( &irc->set, "auto_reconnect" ) && 348 363 set_getbool( &a->set, "auto_reconnect" ) && 349 364 ( delay = account_reconnect_delay( a ) ) > 0 ) … … 356 371 } 357 372 373 374 /* dialogs.c */ 375 358 376 void imcb_ask( struct im_connection *ic, char *msg, void *data, 359 377 query_callback doit, query_callback dont ) 360 378 { 361 //query_add( ic->irc, ic, msg, doit, dont, data ); 362 } 379 query_add( ic->irc, ic, msg, doit, dont, data ); 380 } 381 382 383 /* list.c */ 363 384 364 385 void imcb_add_buddy( struct im_connection *ic, const char *handle, const char *group ) 365 386 { 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" ) ) 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" ) ) 372 394 imcb_log( ic, "User already exists, ignoring add request: %s", handle ); 373 395 … … 380 402 } 381 403 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 ); 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 ); 400 491 } 401 492 } … … 403 494 void imcb_remove_buddy( struct im_connection *ic, const char *handle, char *group ) 404 495 { 405 bee_user_free( ic->bee, ic, handle ); 496 user_t *u; 497 498 if( ( u = user_findhandle( ic, handle ) ) ) 499 user_del( ic->irc, u->nick ); 406 500 } 407 501 … … 410 504 void imcb_buddy_nick_hint( struct im_connection *ic, const char *handle, const char *nick ) 411 505 { 412 #if 0413 506 user_t *u = user_findhandle( ic, handle ); 414 507 char newnick[MAX_NICK_LENGTH+1], *orig_nick; … … 425 518 /* Some processing to make sure this string is a valid IRC nickname. */ 426 519 nick_strip( newnick ); 427 if( set_getbool( &ic-> bee->set, "lcnicks" ) )520 if( set_getbool( &ic->irc->set, "lcnicks" ) ) 428 521 nick_lc( newnick ); 429 522 … … 442 535 } 443 536 } 444 #endif445 537 } 446 538 … … 452 544 }; 453 545 454 #if 0455 546 static void imcb_ask_auth_cb_no( void *data ) 456 547 { … … 472 563 g_free( cbd ); 473 564 } 474 #endif475 565 476 566 void imcb_ask_auth( struct im_connection *ic, const char *handle, const char *realname ) 477 567 { 478 #if 0479 568 struct imcb_ask_cb_data *data = g_new0( struct imcb_ask_cb_data, 1 ); 480 569 char *s, *realname_ = NULL; … … 491 580 data->handle = g_strdup( handle ); 492 581 query_add( ic->irc, ic, s, imcb_ask_auth_cb_yes, imcb_ask_auth_cb_no, data ); 493 #endif 494 } 495 496 497 #if 0 582 } 583 584 498 585 static void imcb_ask_add_cb_no( void *data ) 499 586 { … … 510 597 return imcb_ask_add_cb_no( data ); 511 598 } 512 #endif513 599 514 600 void imcb_ask_add( struct im_connection *ic, const char *handle, const char *realname ) 515 601 { 516 #if 0517 602 struct imcb_ask_cb_data *data = g_new0( struct imcb_ask_cb_data, 1 ); 518 603 char *s; … … 527 612 data->handle = g_strdup( handle ); 528 613 query_add( ic->irc, ic, s, imcb_ask_add_cb_yes, imcb_ask_add_cb_no, data ); 529 #endif 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 { 621 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 ); 530 766 } 531 767 532 768 void imcb_buddy_typing( struct im_connection *ic, char *handle, uint32_t flags ) 533 769 { 534 #if 0535 770 user_t *u; 536 771 537 if( !set_getbool( &ic-> bee->set, "typing_notice" ) )772 if( !set_getbool( &ic->irc->set, "typing_notice" ) ) 538 773 return; 539 774 … … 545 780 irc_privmsg( ic->irc, u, "PRIVMSG", ic->irc->nick, NULL, buf ); 546 781 } 547 #endif548 }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 );553 782 } 554 783 555 784 struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle ) 556 785 { 557 #if 0558 786 struct groupchat *c; 559 787 … … 573 801 c->topic = g_strdup_printf( "BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!", c->title ); 574 802 575 if( set_getbool( &ic-> bee->set, "debug" ) )803 if( set_getbool( &ic->irc->set, "debug" ) ) 576 804 imcb_log( ic, "Creating new conversation: (id=%p,handle=%s)", c, handle ); 577 805 578 806 return c; 579 #endif580 return NULL;581 807 } 582 808 583 809 void imcb_chat_free( struct groupchat *c ) 584 810 { 585 #if 0586 811 struct im_connection *ic = c->ic; 587 812 struct groupchat *l; 588 813 GList *ir; 589 814 590 if( set_getbool( &ic-> bee->set, "debug" ) )815 if( set_getbool( &ic->irc->set, "debug" ) ) 591 816 imcb_log( ic, "You were removed from conversation %p", c ); 592 817 … … 621 846 g_free( c ); 622 847 } 623 #endif624 848 } 625 849 626 850 void imcb_chat_msg( struct groupchat *c, const char *who, char *msg, uint32_t flags, time_t sent_at ) 627 851 { 628 #if 0629 852 struct im_connection *ic = c->ic; 630 853 char *wrapped; … … 637 860 u = user_findhandle( ic, who ); 638 861 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" ) ) )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" ) ) ) 641 864 strip_html( msg ); 642 865 … … 651 874 } 652 875 g_free( wrapped ); 653 #endif654 876 } 655 877 656 878 void imcb_chat_log( struct groupchat *c, char *format, ... ) 657 879 { 658 #if 0659 880 irc_t *irc = c->ic->irc; 660 881 va_list params; … … 671 892 672 893 g_free( text ); 673 #endif674 894 } 675 895 676 896 void imcb_chat_topic( struct groupchat *c, char *who, char *topic, time_t set_at ) 677 897 { 678 #if 0679 898 struct im_connection *ic = c->ic; 680 899 user_t *u = NULL; … … 687 906 u = user_findhandle( ic, who ); 688 907 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" ) ) )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" ) ) ) 691 910 strip_html( topic ); 692 911 … … 696 915 if( c->joined && u ) 697 916 irc_write( ic->irc, ":%s!%s@%s TOPIC %s :%s", u->nick, u->user, u->host, c->channel, topic ); 698 #endif 699 } 917 } 918 919 920 /* buddy_chat.c */ 700 921 701 922 void imcb_chat_add_buddy( struct groupchat *b, const char *handle ) 702 923 { 703 #if 0704 924 user_t *u = user_findhandle( b->ic, handle ); 705 925 int me = 0; 706 926 707 if( set_getbool( &b->ic-> bee->set, "debug" ) )927 if( set_getbool( &b->ic->irc->set, "debug" ) ) 708 928 imcb_log( b->ic, "User %s added to conversation %p", handle, b ); 709 929 … … 732 952 b->in_room = g_list_append( b->in_room, g_strdup( handle ) ); 733 953 } 734 #endif735 954 } 736 955 … … 738 957 void imcb_chat_remove_buddy( struct groupchat *b, const char *handle, const char *reason ) 739 958 { 740 #if 0741 959 user_t *u; 742 960 int me = 0; 743 961 744 if( set_getbool( &b->ic-> bee->set, "debug" ) )962 if( set_getbool( &b->ic->irc->set, "debug" ) ) 745 963 imcb_log( b->ic, "User %s removed from conversation %p (%s)", handle, b, reason ? reason : "" ); 746 964 … … 762 980 if( me || ( remove_chat_buddy_silent( b, handle ) && b->joined && u ) ) 763 981 irc_part( b->ic->irc, u, b->channel ); 764 #endif 765 } 766 767 #if 0 982 } 983 768 984 static int remove_chat_buddy_silent( struct groupchat *b, const char *handle ) 769 985 { … … 784 1000 } 785 1001 786 return 0; 787 } 788 #endif 1002 return( 0 ); 1003 } 789 1004 790 1005 791 1006 /* Misc. BitlBee stuff which shouldn't really be here */ 792 #if 0 1007 793 1008 char *set_eval_away_devoice( set_t *set, char *value ) 794 1009 { … … 803 1018 /* Horror.... */ 804 1019 805 if( st != set_getbool( &irc-> b->set, "away_devoice" ) )1020 if( st != set_getbool( &irc->set, "away_devoice" ) ) 806 1021 { 807 1022 char list[80] = ""; … … 845 1060 return value; 846 1061 } 847 #endif 1062 848 1063 849 1064 … … 852 1067 them all from some wrappers. We'll start to define some down here: */ 853 1068 854 int imc_ chat_msg( struct groupchat *c, char *msg, int flags )1069 int imc_buddy_msg( struct im_connection *ic, char *handle, char *msg, int flags ) 855 1070 { 856 1071 char *buf = NULL; 857 858 if( ( c->ic->flags & OPT_DOES_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) ) 1072 int st; 1073 1074 if( ( ic->flags & OPT_DOES_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) ) 859 1075 { 860 1076 buf = escape_html( msg ); … … 862 1078 } 863 1079 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 864 1096 c->ic->acc->prpl->chat_msg( c, msg, flags ); 865 1097 g_free( buf ); … … 875 1107 876 1108 away = set_getstr( &ic->acc->set, "away" ) ? 877 : set_getstr( &ic-> bee->set, "away" );1109 : set_getstr( &ic->irc->set, "away" ); 878 1110 if( away && *away ) 879 1111 { … … 886 1118 away = NULL; 887 1119 msg = set_getstr( &ic->acc->set, "status" ) ? 888 : set_getstr( &ic-> bee->set, "status" );1120 : set_getstr( &ic->irc->set, "status" ); 889 1121 } 890 1122 -
protocols/nogaim.h
ra87e6ba r3ab1d31 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * 4 * Copyright 2002-20 10Wilmer van der Gaast and others *4 * Copyright 2002-2004 Wilmer van der Gaast and others * 5 5 \********************************************************************/ 6 6 … … 87 87 88 88 /* BitlBee */ 89 bee_t *bee;89 irc_t *irc; 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 ); 288 297 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 );290 298 G_MODULE_EXPORT void imcb_clean_handle( struct im_connection *ic, char *handle ); 291 299 … … 312 320 /* Actions, or whatever. */ 313 321 int imc_away_send_update( struct im_connection *ic ); 322 int imc_buddy_msg( struct im_connection *ic, char *handle, char *msg, int flags ); 314 323 int imc_chat_msg( struct groupchat *c, char *msg, int flags ); 315 324 -
protocols/oscar/oscar.c
ra87e6ba r3ab1d31 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 imcb_ask_add(data->ic, uin, NULL); 1192 if(imcb_find_buddy(data->ic, uin) == NULL) 1193 imcb_ask_add(data->ic, uin, NULL); 1193 1194 1194 1195 g_free(uin); … … 1951 1952 struct oscar_data *odata = (struct oscar_data *)g->proto_data; 1952 1953 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 */1960 1959 } else 1961 1960 aim_getinfo(odata->sess, odata->conn, who, AIM_GETINFO_AWAYMESSAGE); … … 2095 2094 switch (curitem->type) { 2096 2095 case 0x0000: /* Buddy */ 2097 if ((curitem->name) && (!imcb_ buddy_by_handle(ic, nrm))) {2096 if ((curitem->name) && (!imcb_find_buddy(ic, nrm))) { 2098 2097 char *realname = NULL; 2099 2098 -
root_commands.c
ra87e6ba r3ab1d31 32 32 #include <string.h> 33 33 34 void root_command_string( irc_t *irc, char *command)34 void root_command_string( irc_t *irc, user_t *u, char *command, int flags ) 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-> b->set, "auto_connect" ) )163 if( set_getbool( &irc->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-> user->nick, cmd[1]);203 status = storage_remove (irc->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-> user->nick );215 irc_usermsg( irc, "Account `%s' removed", irc->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 else230 irc_usermsg( irc, "Configuration could not be saved!" );231 }232 233 223 struct cmd_account_del_data 234 224 { … … 242 232 account_t *a; 243 233 244 for( a = cad->irc-> b->accounts; a && a != cad->a; a = a->next );234 for( a = cad->irc->accounts; a && a != cad->a; a = a->next ); 245 235 246 236 if( a == NULL ) … … 254 244 else 255 245 { 256 account_del( cad->irc ->b, a );246 account_del( cad->irc, a ); 257 247 irc_usermsg( cad->irc, "Account deleted" ); 258 248 } … … 295 285 set_name = set_full; 296 286 297 head = &irc-> b->set;287 head = &irc->set; 298 288 } 299 289 else … … 366 356 account_t *a; 367 357 368 if( ( a = account_get( irc ->b, id ) ) )358 if( ( a = account_get( irc, id ) ) ) 369 359 return &a->set; 370 360 else … … 414 404 } 415 405 416 a = account_add( irc ->b, prpl, cmd[3], cmd[4] );406 a = account_add( irc, prpl, cmd[3], cmd[4] ); 417 407 if( cmd[5] ) 418 408 { … … 428 418 MIN_ARGS( 2 ); 429 419 430 if( !( a = account_get( irc ->b, cmd[2] ) ) )420 if( !( a = account_get( irc, cmd[2] ) ) ) 431 421 { 432 422 irc_usermsg( irc, "Invalid account" ); … … 450 440 "set' command. Are you sure you want to delete this " 451 441 "account?", a->prpl->name, a->user ); 452 //query_add( irc, NULL, msg, cmd_account_del_yes, cmd_account_del_no, cad );442 query_add( irc, NULL, msg, cmd_account_del_yes, cmd_account_del_no, cad ); 453 443 g_free( msg ); 454 444 } … … 461 451 irc_usermsg( irc, "Account list:" ); 462 452 463 for( a = irc-> b->accounts; a; a = a->next )453 for( a = irc->accounts; a; a = a->next ) 464 454 { 465 455 char *con; … … 484 474 if( cmd[2] ) 485 475 { 486 if( ( a = account_get( irc ->b, cmd[2] ) ) )476 if( ( a = account_get( irc, cmd[2] ) ) ) 487 477 { 488 478 if( a->ic ) … … 493 483 else 494 484 { 495 account_on( irc ->b, a );485 account_on( irc, a ); 496 486 } 497 487 } … … 504 494 else 505 495 { 506 if ( irc->b->accounts ) 507 { 496 if ( irc->accounts ) { 508 497 irc_usermsg( irc, "Trying to get all accounts connected..." ); 509 498 510 for( a = irc-> b->accounts; a; a = a->next )499 for( a = irc->accounts; a; a = a->next ) 511 500 if( !a->ic && a->auto_connect ) 512 account_on( irc ->b, a );501 account_on( irc, a ); 513 502 } 514 503 else … … 524 513 irc_usermsg( irc, "Deactivating all active (re)connections..." ); 525 514 526 for( a = irc-> b->accounts; a; a = a->next )515 for( a = irc->accounts; a; a = a->next ) 527 516 { 528 517 if( a->ic ) 529 account_off( irc ->b, a );518 account_off( irc, a ); 530 519 else if( a->reconnect ) 531 520 cancel_auto_reconnect( a ); 532 521 } 533 522 } 534 else if( ( a = account_get( irc ->b, cmd[2] ) ) )523 else if( ( a = account_get( irc, cmd[2] ) ) ) 535 524 { 536 525 if( a->ic ) 537 526 { 538 account_off( irc ->b, a );527 account_off( irc, a ); 539 528 } 540 529 else if( a->reconnect ) … … 567 556 } 568 557 569 #if 0570 558 static void cmd_add( irc_t *irc, char **cmd ) 571 559 { … … 656 644 } 657 645 } 658 #endif659 646 660 647 static void cmd_rename( irc_t *irc, char **cmd ) 661 648 { 662 irc_user_t *iu; 663 664 iu = irc_user_by_name( irc, cmd[1] ); 665 666 if( iu == NULL ) 649 user_t *u; 650 651 if( g_strcasecmp( cmd[1], irc->nick ) == 0 ) 652 { 653 irc_usermsg( irc, "Nick `%s' can't be changed", cmd[1] ); 654 } 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 ) ) 671 { 672 irc_usermsg( irc, "Nick `%s' already exists", cmd[2] ); 673 } 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] ) ) ) 667 679 { 668 680 irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] ); 669 681 } 670 else if( iu == irc->user ) 671 { 672 irc_usermsg( irc, "Nick `%s' can't be changed", cmd[1] ); 673 } 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] ) ) 679 { 680 irc_usermsg( irc, "Nick `%s' already exists", cmd[2] ); 681 } 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 { 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 692 691 /* If we're called internally (user did "set root_nick"), 693 692 let's not go O(INF). :-) */ 694 693 if( strcmp( cmd[0], "set_rename" ) != 0 ) 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] );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] ); 700 699 } 701 700 … … 704 703 } 705 704 706 #if 0707 705 char *set_eval_root_nick( set_t *set, char *new_nick ) 708 706 { … … 915 913 { 916 914 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 else 924 irc_usermsg( irc, "Configuration could not be saved!" ); 917 925 } 918 926 … … 982 990 } 983 991 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 else 1013 { 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 984 1020 static void cmd_qlist( irc_t *irc, char **cmd ) 985 1021 { … … 1000 1036 else 1001 1037 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." ); 1002 1044 } 1003 1045 … … 1175 1217 } 1176 1218 } 1177 #endif1178 1219 1179 1220 const command_t commands[] = { 1180 1221 { "help", 0, cmd_help, 0 }, 1181 { "account", 1, cmd_account, 0 },1182 1222 { "identify", 1, cmd_identify, 0 }, 1183 1223 { "register", 1, cmd_register, 0 }, 1184 1224 { "drop", 1, cmd_drop, 0 }, 1185 { "save", 0, cmd_save, 0 }, 1186 #if 0 1225 { "account", 1, cmd_account, 0 }, 1187 1226 { "add", 2, cmd_add, 0 }, 1188 1227 { "info", 1, cmd_info, 0 }, 1189 #endif1190 1228 { "rename", 2, cmd_rename, 0 }, 1191 #if 01192 1229 { "remove", 1, cmd_remove, 0 }, 1193 1230 { "block", 1, cmd_block, 0 }, 1194 1231 { "allow", 1, cmd_allow, 0 }, 1232 { "save", 0, cmd_save, 0 }, 1195 1233 { "set", 0, cmd_set, 0 }, 1196 1234 { "yes", 0, cmd_yesno, 0 }, … … 1202 1240 { "chat", 1, cmd_chat, 0 }, 1203 1241 { "transfer", 0, cmd_transfer, 0 }, 1204 #endif1205 1242 { NULL } 1206 1243 }; -
set.c
ra87e6ba r3ab1d31 225 225 } 226 226 227 /*228 227 char *set_eval_ops( set_t *set, char *value ) 229 228 { … … 247 246 return value; 248 247 } 249 */ -
storage_xml.c
ra87e6ba r3ab1d31 147 147 arc_decode( pass_cr, pass_len, &password, xd->given_pass ) ) 148 148 { 149 xd->current_account = account_add( irc ->b, prpl, handle, password );149 xd->current_account = account_add( irc, 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-> b->set;183 xd->current_set_head = &xd->irc->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-> user->nick, password, XML_PASS_UNKNOWN );355 return xml_load_real( irc, irc->nick, password, XML_PASS_UNKNOWN ); 356 356 } 357 357 … … 396 396 md5_state_t md5_state; 397 397 398 path2 = g_strdup( irc-> user->nick );398 path2 = g_strdup( irc->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-> user->nick, pass_buf, XML_FORMAT_VERSION ) )424 if( !xml_printf( fd, 0, "<user nick=\"%s\" password=\"%s\" version=\"%d\">\n", irc->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-> b->set; set; set = set->next )429 for( set = irc->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-> b->accounts; acc; acc = acc->next )434 for( acc = irc->accounts; acc; acc = acc->next ) 435 435 { 436 436 unsigned char *pass_cr; … … 470 470 goto write_error; 471 471 472 #if 0473 472 for( c = irc->chatrooms; c; c = c->next ) 474 473 { … … 489 488 goto write_error; 490 489 } 491 #endif492 490 493 491 if( !xml_printf( fd, 1, "</account>\n" ) )
Note: See TracChangeset
for help on using the changeset viewer.