Changeset 5ebff60 for root_commands.c
- Timestamp:
- 2015-02-20T22:50:54Z (9 years ago)
- Branches:
- master
- Children:
- 0b9daac, 3d45471, 7733b8c
- Parents:
- af359b4
- git-author:
- Indent <please@…> (19-02-15 05:47:20)
- git-committer:
- dequis <dx@…> (20-02-15 22:50:54)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
root_commands.c
raf359b4 r5ebff60 1 1 /********************************************************************\ 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * … … 30 30 #include "ipc.h" 31 31 32 void root_command_string( irc_t *irc, char *command)33 { 34 root_command( irc, split_command_parts( command, 0 ));35 } 36 37 #define MIN_ARGS( x, y...) \32 void root_command_string(irc_t *irc, char *command) 33 { 34 root_command(irc, split_command_parts(command, 0)); 35 } 36 37 #define MIN_ARGS(x, y ...) \ 38 38 do \ 39 39 { \ 40 40 int blaat; \ 41 for ( blaat = 0; blaat <= x; blaat ++ )\42 if ( cmd[blaat] == NULL) \41 for (blaat = 0; blaat <= x; blaat++) { \ 42 if (cmd[blaat] == NULL) \ 43 43 { \ 44 irc_rootmsg( irc, "Not enough parameters given (need %d).", x); \44 irc_rootmsg(irc, "Not enough parameters given (need %d).", x); \ 45 45 return y; \ 46 } \47 } while ( 0)48 49 void root_command( irc_t *irc, char *cmd[])50 { 46 } } \ 47 } while (0) 48 49 void root_command(irc_t *irc, char *cmd[]) 50 { 51 51 int i, len; 52 53 if( !cmd[0] ) 54 return; 55 56 len = strlen( cmd[0] ); 57 for( i = 0; root_commands[i].command; i++ ) 58 if( g_strncasecmp( root_commands[i].command, cmd[0], len ) == 0 ) 59 { 60 if( root_commands[i+1].command && 61 g_strncasecmp( root_commands[i+1].command, cmd[0], len ) == 0 ) 62 /* Only match on the first letters if the match is unique. */ 63 break; 64 65 MIN_ARGS( root_commands[i].required_parameters ); 66 67 root_commands[i].execute( irc, cmd ); 52 53 if (!cmd[0]) { 54 return; 55 } 56 57 len = strlen(cmd[0]); 58 for (i = 0; root_commands[i].command; i++) { 59 if (g_strncasecmp(root_commands[i].command, cmd[0], len) == 0) { 60 if (root_commands[i + 1].command && 61 g_strncasecmp(root_commands[i + 1].command, cmd[0], len) == 0) { 62 /* Only match on the first letters if the match is unique. */ 63 break; 64 } 65 66 MIN_ARGS(root_commands[i].required_parameters); 67 68 root_commands[i].execute(irc, cmd); 68 69 return; 69 70 } 70 71 irc_rootmsg( irc, "Unknown command: %s. Please use \x02help commands\x02 to get a list of available commands.", cmd[0] ); 72 } 73 74 static void cmd_help( irc_t *irc, char **cmd ) 71 } 72 73 irc_rootmsg(irc, "Unknown command: %s. Please use \x02help commands\x02 to get a list of available commands.", 74 cmd[0]); 75 } 76 77 static void cmd_help(irc_t *irc, char **cmd) 75 78 { 76 79 char param[80]; 77 80 int i; 78 81 char *s; 79 80 memset( param, 0, sizeof(param));81 for ( i = 1; (cmd[i] != NULL && ( strlen(param) < (sizeof(param)-1) ) ); i++) {82 if ( i != 1 )// prepend space except for the first parameter82 83 memset(param, 0, sizeof(param)); 84 for (i = 1; (cmd[i] != NULL && (strlen(param) < (sizeof(param) - 1))); i++) { 85 if (i != 1) { // prepend space except for the first parameter 83 86 strcat(param, " "); 84 strncat( param, cmd[i], sizeof(param) - strlen(param) - 1 );85 }86 87 s = help_get( &(global.help), param ); 88 if( !s ) s = help_get( &(global.help), "");89 90 if( s )91 {92 irc_rootmsg( irc, "%s", s ); 93 g_free( s );94 }95 else96 {97 irc_rootmsg( irc, "Error opening helpfile.");98 } 99 } 100 101 static void cmd_account( irc_t *irc, char **cmd);102 static void bitlbee_whatsnew( irc_t *irc);103 104 static void cmd_identify( irc_t *irc, char **cmd)87 } 88 strncat(param, cmd[i], sizeof(param) - strlen(param) - 1); 89 } 90 91 s = help_get(&(global.help), param); 92 if (!s) { 93 s = help_get(&(global.help), ""); 94 } 95 96 if (s) { 97 irc_rootmsg(irc, "%s", s); 98 g_free(s); 99 } else { 100 irc_rootmsg(irc, "Error opening helpfile."); 101 } 102 } 103 104 static void cmd_account(irc_t *irc, char **cmd); 105 static void bitlbee_whatsnew(irc_t *irc); 106 107 static void cmd_identify(irc_t *irc, char **cmd) 105 108 { 106 109 storage_status_t status; 107 110 gboolean load = TRUE; 108 111 char *password = cmd[1]; 109 110 if( irc->status & USTATUS_IDENTIFIED ) 111 { 112 irc_rootmsg( irc, "You're already logged in." ); 113 return; 114 } 115 116 if( cmd[1] == NULL ) 117 { 118 } 119 else if( strncmp( cmd[1], "-no", 3 ) == 0 ) 120 { 112 113 if (irc->status & USTATUS_IDENTIFIED) { 114 irc_rootmsg(irc, "You're already logged in."); 115 return; 116 } 117 118 if (cmd[1] == NULL) { 119 } else if (strncmp(cmd[1], "-no", 3) == 0) { 121 120 load = FALSE; 122 121 password = cmd[2]; 123 if ( password == NULL )122 if (password == NULL) { 124 123 irc->status |= OPER_HACK_IDENTIFY_NOLOAD; 125 } 126 else if( strncmp( cmd[1], "-force", 6 ) == 0 ) 127 { 124 } 125 } else if (strncmp(cmd[1], "-force", 6) == 0) { 128 126 password = cmd[2]; 129 if ( password == NULL )127 if (password == NULL) { 130 128 irc->status |= OPER_HACK_IDENTIFY_FORCE; 131 } 132 else if( irc->b->accounts != NULL ) 133 { 134 irc_rootmsg( irc, 135 "You're trying to identify yourself, but already have " 136 "at least one IM account set up. " 137 "Use \x02identify -noload\x02 or \x02identify -force\x02 " 138 "instead (see \x02help identify\x02)." ); 139 return; 140 } 141 142 if( password == NULL ) 143 { 144 irc_rootmsg( irc, "About to identify, use /OPER to enter the password" ); 129 } 130 } else if (irc->b->accounts != NULL) { 131 irc_rootmsg(irc, 132 "You're trying to identify yourself, but already have " 133 "at least one IM account set up. " 134 "Use \x02identify -noload\x02 or \x02identify -force\x02 " 135 "instead (see \x02help identify\x02)."); 136 return; 137 } 138 139 if (password == NULL) { 140 irc_rootmsg(irc, "About to identify, use /OPER to enter the password"); 145 141 irc->status |= OPER_HACK_IDENTIFY; 146 142 return; 147 143 } 148 149 if( load ) 150 status = storage_load( irc, password ); 151 else 152 status = storage_check_pass( irc->user->nick, password ); 153 144 145 if (load) { 146 status = storage_load(irc, password); 147 } else { 148 status = storage_check_pass(irc->user->nick, password); 149 } 150 154 151 switch (status) { 155 152 case STORAGE_INVALID_PASSWORD: 156 irc_rootmsg( irc, "Incorrect password");153 irc_rootmsg(irc, "Incorrect password"); 157 154 break; 158 155 case STORAGE_NO_SUCH_USER: 159 irc_rootmsg( irc, "The nick is (probably) not registered");156 irc_rootmsg(irc, "The nick is (probably) not registered"); 160 157 break; 161 158 case STORAGE_OK: 162 irc_rootmsg( 163 load ? ", settings and accounts loaded" : "");164 irc_setpass( irc, password);159 irc_rootmsg(irc, "Password accepted%s", 160 load ? ", settings and accounts loaded" : ""); 161 irc_setpass(irc, password); 165 162 irc->status |= USTATUS_IDENTIFIED; 166 irc_umode_set( irc, "+R", 1);167 168 bitlbee_whatsnew( irc);169 163 irc_umode_set(irc, "+R", 1); 164 165 bitlbee_whatsnew(irc); 166 170 167 /* The following code is a bit hairy now. With takeover 171 168 support, we shouldn't immediately auto_connect in case … … 173 170 Do it in 200ms since that should give the parent process 174 171 enough time to come back to us. */ 175 if( load ) 176 { 177 irc_channel_auto_joins( irc, NULL ); 178 if( !set_getbool( &irc->default_channel->set, "auto_join" ) ) 179 irc_channel_del_user( irc->default_channel, irc->user, 180 IRC_CDU_PART, "auto_join disabled " 181 "for this channel." ); 182 if( set_getbool( &irc->b->set, "auto_connect" ) ) 183 irc->login_source_id = b_timeout_add( 200, 184 cmd_identify_finish, irc ); 185 } 186 172 if (load) { 173 irc_channel_auto_joins(irc, NULL); 174 if (!set_getbool(&irc->default_channel->set, "auto_join")) { 175 irc_channel_del_user(irc->default_channel, irc->user, 176 IRC_CDU_PART, "auto_join disabled " 177 "for this channel."); 178 } 179 if (set_getbool(&irc->b->set, "auto_connect")) { 180 irc->login_source_id = b_timeout_add(200, 181 cmd_identify_finish, irc); 182 } 183 } 184 187 185 /* If ipc_child_identify() returns FALSE, it means we're 188 186 already sure that there's no takeover target (only 189 187 possible in 1-process daemon mode). Start auto_connect 190 188 immediately. */ 191 if( !ipc_child_identify( irc ) && load ) 192 cmd_identify_finish( irc, 0, 0 ); 193 189 if (!ipc_child_identify(irc) && load) { 190 cmd_identify_finish(irc, 0, 0); 191 } 192 194 193 break; 195 194 case STORAGE_OTHER_ERROR: 196 195 default: 197 irc_rootmsg( irc, "Unknown error while loading configuration");196 irc_rootmsg(irc, "Unknown error while loading configuration"); 198 197 break; 199 198 } 200 199 } 201 200 202 gboolean cmd_identify_finish( gpointer data, gint fd, b_input_condition cond)201 gboolean cmd_identify_finish(gpointer data, gint fd, b_input_condition cond) 203 202 { 204 203 char *account_on[] = { "account", "on", NULL }; 205 204 irc_t *irc = data; 206 207 if( set_getbool( &irc->b->set, "auto_connect" ) ) 208 cmd_account( irc, account_on ); 209 210 b_event_remove( irc->login_source_id ); 205 206 if (set_getbool(&irc->b->set, "auto_connect")) { 207 cmd_account(irc, account_on); 208 } 209 210 b_event_remove(irc->login_source_id); 211 211 irc->login_source_id = -1; 212 212 return FALSE; 213 213 } 214 214 215 static void cmd_register( irc_t *irc, char **cmd)215 static void cmd_register(irc_t *irc, char **cmd) 216 216 { 217 217 char s[16]; 218 219 if( global.conf->authmode == AUTHMODE_REGISTERED ) 220 { 221 irc_rootmsg( irc, "This server does not allow registering new accounts" ); 222 return; 223 } 224 225 if( cmd[1] == NULL ) 226 { 227 irc_rootmsg( irc, "About to register, use /OPER to enter the password" ); 218 219 if (global.conf->authmode == AUTHMODE_REGISTERED) { 220 irc_rootmsg(irc, "This server does not allow registering new accounts"); 221 return; 222 } 223 224 if (cmd[1] == NULL) { 225 irc_rootmsg(irc, "About to register, use /OPER to enter the password"); 228 226 irc->status |= OPER_HACK_REGISTER; 229 227 return; 230 228 } 231 229 232 switch ( storage_save( irc, cmd[1], FALSE )) {233 234 irc_rootmsg( irc, "Nick is already registered");235 236 237 238 irc_rootmsg( irc, "Account successfully created");239 irc_setpass( irc, cmd[1]);240 241 irc_umode_set( irc, "+R", 1);242 243 244 245 246 g_snprintf( s, sizeof( s ), "%d", BITLBEE_VERSION_CODE);247 set_setstr( &irc->b->set, "last_version", s);248 249 250 251 irc_rootmsg( irc, "Error registering");252 253 } 254 } 255 256 static void cmd_drop( irc_t *irc, char **cmd)230 switch (storage_save(irc, cmd[1], FALSE)) { 231 case STORAGE_ALREADY_EXISTS: 232 irc_rootmsg(irc, "Nick is already registered"); 233 break; 234 235 case STORAGE_OK: 236 irc_rootmsg(irc, "Account successfully created"); 237 irc_setpass(irc, cmd[1]); 238 irc->status |= USTATUS_IDENTIFIED; 239 irc_umode_set(irc, "+R", 1); 240 241 /* Set this var now, or anyone who logs in to his/her 242 newly created account for the first time gets the 243 whatsnew story. */ 244 g_snprintf(s, sizeof(s), "%d", BITLBEE_VERSION_CODE); 245 set_setstr(&irc->b->set, "last_version", s); 246 break; 247 248 default: 249 irc_rootmsg(irc, "Error registering"); 250 break; 251 } 252 } 253 254 static void cmd_drop(irc_t *irc, char **cmd) 257 255 { 258 256 storage_status_t status; 259 260 status = storage_remove 257 258 status = storage_remove(irc->user->nick, cmd[1]); 261 259 switch (status) { 262 260 case STORAGE_NO_SUCH_USER: 263 irc_rootmsg( irc, "That account does not exist");261 irc_rootmsg(irc, "That account does not exist"); 264 262 break; 265 263 case STORAGE_INVALID_PASSWORD: 266 irc_rootmsg( irc, "Password invalid");264 irc_rootmsg(irc, "Password invalid"); 267 265 break; 268 266 case STORAGE_OK: 269 irc_setpass( irc, NULL);267 irc_setpass(irc, NULL); 270 268 irc->status &= ~USTATUS_IDENTIFIED; 271 irc_umode_set( irc, "-R", 1);272 irc_rootmsg( irc, "Account `%s' removed", irc->user->nick);269 irc_umode_set(irc, "-R", 1); 270 irc_rootmsg(irc, "Account `%s' removed", irc->user->nick); 273 271 break; 274 272 default: 275 irc_rootmsg( irc, "Error: `%d'", status);273 irc_rootmsg(irc, "Error: `%d'", status); 276 274 break; 277 275 } 278 276 } 279 277 280 static void cmd_save( irc_t *irc, char **cmd ) 281 { 282 if( ( irc->status & USTATUS_IDENTIFIED ) == 0 ) 283 irc_rootmsg( irc, "Please create an account first (see \x02help register\x02)" ); 284 else if( storage_save( irc, NULL, TRUE ) == STORAGE_OK ) 285 irc_rootmsg( irc, "Configuration saved" ); 286 else 287 irc_rootmsg( irc, "Configuration could not be saved!" ); 288 } 289 290 static void cmd_showset( irc_t *irc, set_t **head, char *key ) 278 static void cmd_save(irc_t *irc, char **cmd) 279 { 280 if ((irc->status & USTATUS_IDENTIFIED) == 0) { 281 irc_rootmsg(irc, "Please create an account first (see \x02help register\x02)"); 282 } else if (storage_save(irc, NULL, TRUE) == STORAGE_OK) { 283 irc_rootmsg(irc, "Configuration saved"); 284 } else { 285 irc_rootmsg(irc, "Configuration could not be saved!"); 286 } 287 } 288 289 static void cmd_showset(irc_t *irc, set_t **head, char *key) 291 290 { 292 291 set_t *set; 293 292 char *val; 294 295 if ( ( val = set_getstr( head, key ) ) )296 irc_rootmsg( irc, "%s = `%s'", key, val);297 else if( !( set = set_find( head, key ) ) )298 {299 i rc_rootmsg( irc, "Setting `%s' does not exist.", key );300 if( *head == irc->b->set )301 irc_rootmsg( irc, "It might be an account or channel setting. "302 "See \x02help account set\x02 and \x02help channel set\x02." );303 } 304 else if( set->flags & SET_PASSWORD )305 irc_rootmsg( irc, "%s = `********' (hidden)", key );306 else307 irc_rootmsg( irc, "%s is empty", key );308 } 309 310 typedef set_t** (*cmd_set_findhead)( irc_t*, char*);311 typedef int (*cmd_set_checkflags)( irc_t*, set_t *set);312 313 static int cmd_set_real( irc_t *irc, char **cmd, set_t **head, cmd_set_checkflags checkflags)293 294 if ((val = set_getstr(head, key))) { 295 irc_rootmsg(irc, "%s = `%s'", key, val); 296 } else if (!(set = set_find(head, key))) { 297 irc_rootmsg(irc, "Setting `%s' does not exist.", key); 298 if (*head == irc->b->set) { 299 irc_rootmsg(irc, "It might be an account or channel setting. " 300 "See \x02help account set\x02 and \x02help channel set\x02."); 301 } 302 } else if (set->flags & SET_PASSWORD) { 303 irc_rootmsg(irc, "%s = `********' (hidden)", key); 304 } else { 305 irc_rootmsg(irc, "%s is empty", key); 306 } 307 } 308 309 typedef set_t** (*cmd_set_findhead)(irc_t*, char*); 310 typedef int (*cmd_set_checkflags)(irc_t*, set_t *set); 311 312 static int cmd_set_real(irc_t *irc, char **cmd, set_t **head, cmd_set_checkflags checkflags) 314 313 { 315 314 char *set_name = NULL, *value = NULL; 316 315 gboolean del = FALSE; 317 318 if( cmd[1] && g_strncasecmp( cmd[1], "-del", 4 ) == 0 ) 319 { 320 MIN_ARGS( 2, 0 ); 316 317 if (cmd[1] && g_strncasecmp(cmd[1], "-del", 4) == 0) { 318 MIN_ARGS(2, 0); 321 319 set_name = cmd[2]; 322 320 del = TRUE; 323 } 324 else 325 { 321 } else { 326 322 set_name = cmd[1]; 327 323 value = cmd[2]; 328 324 } 329 330 if( set_name && ( value || del ) ) 331 { 332 set_t *s = set_find( head, set_name ); 325 326 if (set_name && (value || del)) { 327 set_t *s = set_find(head, set_name); 333 328 int st; 334 335 if ( s && checkflags && checkflags( irc, s ) == 0 )329 330 if (s && checkflags && checkflags(irc, s) == 0) { 336 331 return 0; 337 338 if( del ) 339 st = set_reset( head, set_name ); 340 else 341 st = set_setstr( head, set_name, value ); 342 343 if( set_getstr( head, set_name ) == NULL && 344 set_find( head, set_name ) ) 345 { 332 } 333 334 if (del) { 335 st = set_reset(head, set_name); 336 } else { 337 st = set_setstr(head, set_name, value); 338 } 339 340 if (set_getstr(head, set_name) == NULL && 341 set_find(head, set_name)) { 346 342 /* This happens when changing the passwd, for example. 347 343 Showing these msgs instead gives slightly clearer 348 344 feedback. */ 349 if( st ) 350 irc_rootmsg( irc, "Setting changed successfully" ); 351 else 352 irc_rootmsg( irc, "Failed to change setting" ); 353 } 354 else 355 { 356 cmd_showset( irc, head, set_name ); 357 } 358 } 359 else if( set_name ) 360 { 361 cmd_showset( irc, head, set_name ); 362 } 363 else 364 { 345 if (st) { 346 irc_rootmsg(irc, "Setting changed successfully"); 347 } else { 348 irc_rootmsg(irc, "Failed to change setting"); 349 } 350 } else { 351 cmd_showset(irc, head, set_name); 352 } 353 } else if (set_name) { 354 cmd_showset(irc, head, set_name); 355 } else { 365 356 set_t *s = *head; 366 while ( s )367 {368 if( set_isvisible( s ) )369 cmd_showset( irc, &s, s->key );357 while (s) { 358 if (set_isvisible(s)) { 359 cmd_showset(irc, &s, s->key); 360 } 370 361 s = s->next; 371 362 } 372 363 } 373 364 374 365 return 1; 375 366 } 376 367 377 static int cmd_account_set_checkflags( irc_t *irc, set_t *s)368 static int cmd_account_set_checkflags(irc_t *irc, set_t *s) 378 369 { 379 370 account_t *a = s->data; 380 381 if( a->ic && s && s->flags & ACC_SET_OFFLINE_ONLY ) 382 { 383 irc_rootmsg( irc, "This setting can only be changed when the account is %s-line", "off" ); 371 372 if (a->ic && s && s->flags & ACC_SET_OFFLINE_ONLY) { 373 irc_rootmsg(irc, "This setting can only be changed when the account is %s-line", "off"); 384 374 return 0; 385 } 386 else if( !a->ic && s && s->flags & ACC_SET_ONLINE_ONLY ) 387 { 388 irc_rootmsg( irc, "This setting can only be changed when the account is %s-line", "on" ); 375 } else if (!a->ic && s && s->flags & ACC_SET_ONLINE_ONLY) { 376 irc_rootmsg(irc, "This setting can only be changed when the account is %s-line", "on"); 389 377 return 0; 390 378 } 391 379 392 380 return 1; 393 381 } 394 382 395 static void cmd_account( irc_t *irc, char **cmd)383 static void cmd_account(irc_t *irc, char **cmd) 396 384 { 397 385 account_t *a; 398 386 int len; 399 400 if( global.conf->authmode == AUTHMODE_REGISTERED && !( irc->status & USTATUS_IDENTIFIED ) ) 401 { 402 irc_rootmsg( irc, "This server only accepts registered users" ); 403 return; 404 } 405 406 len = strlen( cmd[1] ); 407 408 if( len >= 1 && g_strncasecmp( cmd[1], "add", len ) == 0 ) 409 { 387 388 if (global.conf->authmode == AUTHMODE_REGISTERED && !(irc->status & USTATUS_IDENTIFIED)) { 389 irc_rootmsg(irc, "This server only accepts registered users"); 390 return; 391 } 392 393 len = strlen(cmd[1]); 394 395 if (len >= 1 && g_strncasecmp(cmd[1], "add", len) == 0) { 410 396 struct prpl *prpl; 411 412 MIN_ARGS( 3 ); 413 414 if( cmd[4] == NULL ) 415 { 416 for( a = irc->b->accounts; a; a = a->next ) 417 if( strcmp( a->pass, PASSWORD_PENDING ) == 0 ) 418 { 419 irc_rootmsg( irc, "Enter password for account %s " 420 "first (use /OPER)", a->tag ); 397 398 MIN_ARGS(3); 399 400 if (cmd[4] == NULL) { 401 for (a = irc->b->accounts; a; a = a->next) { 402 if (strcmp(a->pass, PASSWORD_PENDING) == 0) { 403 irc_rootmsg(irc, "Enter password for account %s " 404 "first (use /OPER)", a->tag); 421 405 return; 422 406 } 423 407 } 408 424 409 irc->status |= OPER_HACK_ACCOUNT_PASSWORD; 425 410 } 426 427 prpl = find_protocol( cmd[2] ); 428 429 if( prpl == NULL ) 430 { 431 irc_rootmsg( irc, "Unknown protocol" ); 411 412 prpl = find_protocol(cmd[2]); 413 414 if (prpl == NULL) { 415 irc_rootmsg(irc, "Unknown protocol"); 432 416 return; 433 417 } 434 435 for( a = irc->b->accounts; a; a = a->next ) 436 if( a->prpl == prpl && prpl->handle_cmp( a->user, cmd[3] ) == 0 ) 437 irc_rootmsg( irc, "Warning: You already have an account with " 438 "protocol `%s' and username `%s'. Are you accidentally " 439 "trying to add it twice?", prpl->name, cmd[3] ); 440 441 a = account_add( irc->b, prpl, cmd[3], cmd[4] ? cmd[4] : PASSWORD_PENDING ); 442 if( cmd[5] ) 443 { 444 irc_rootmsg( irc, "Warning: Passing a servername/other flags to `account add' " 445 "is now deprecated. Use `account set' instead." ); 446 set_setstr( &a->set, "server", cmd[5] ); 447 } 448 449 irc_rootmsg( irc, "Account successfully added with tag %s", a->tag ); 450 451 if( cmd[4] == NULL ) 452 { 453 set_t *oauth = set_find( &a->set, "oauth" ); 454 if( oauth && bool2int( set_value( oauth ) ) ) 455 { 418 419 for (a = irc->b->accounts; a; a = a->next) { 420 if (a->prpl == prpl && prpl->handle_cmp(a->user, cmd[3]) == 0) { 421 irc_rootmsg(irc, "Warning: You already have an account with " 422 "protocol `%s' and username `%s'. Are you accidentally " 423 "trying to add it twice?", prpl->name, cmd[3]); 424 } 425 } 426 427 a = account_add(irc->b, prpl, cmd[3], cmd[4] ? cmd[4] : PASSWORD_PENDING); 428 if (cmd[5]) { 429 irc_rootmsg(irc, "Warning: Passing a servername/other flags to `account add' " 430 "is now deprecated. Use `account set' instead."); 431 set_setstr(&a->set, "server", cmd[5]); 432 } 433 434 irc_rootmsg(irc, "Account successfully added with tag %s", a->tag); 435 436 if (cmd[4] == NULL) { 437 set_t *oauth = set_find(&a->set, "oauth"); 438 if (oauth && bool2int(set_value(oauth))) { 456 439 *a->pass = '\0'; 457 irc_rootmsg( irc, "No need to enter a password for this " 458 "account since it's using OAuth" ); 459 } 460 else 461 { 462 irc_rootmsg( irc, "You can now use the /OPER command to " 463 "enter the password" ); 464 if( oauth ) 465 irc_rootmsg( irc, "Alternatively, enable OAuth if " 466 "the account supports it: account %s " 467 "set oauth on", a->tag ); 468 } 469 } 470 471 return; 472 } 473 else if( len >= 1 && g_strncasecmp( cmd[1], "list", len ) == 0 ) 474 { 440 irc_rootmsg(irc, "No need to enter a password for this " 441 "account since it's using OAuth"); 442 } else { 443 irc_rootmsg(irc, "You can now use the /OPER command to " 444 "enter the password"); 445 if (oauth) { 446 irc_rootmsg(irc, "Alternatively, enable OAuth if " 447 "the account supports it: account %s " 448 "set oauth on", a->tag); 449 } 450 } 451 } 452 453 return; 454 } else if (len >= 1 && g_strncasecmp(cmd[1], "list", len) == 0) { 475 455 int i = 0; 476 477 if ( strchr( irc->umode, 'b' ) )478 irc_rootmsg( irc, "Account list:");479 480 for( a = irc->b->accounts; a; a = a->next ) 481 {456 457 if (strchr(irc->umode, 'b')) { 458 irc_rootmsg(irc, "Account list:"); 459 } 460 461 for (a = irc->b->accounts; a; a = a->next) { 482 462 char *con; 483 484 if ( a->ic && ( a->ic->flags & OPT_LOGGED_IN ) )463 464 if (a->ic && (a->ic->flags & OPT_LOGGED_IN)) { 485 465 con = " (connected)"; 486 else if( a->ic )466 } else if (a->ic) { 487 467 con = " (connecting)"; 488 else if( a->reconnect )468 } else if (a->reconnect) { 489 469 con = " (awaiting reconnect)"; 490 else470 } else { 491 471 con = ""; 492 493 irc_rootmsg( irc, "%2d (%s): %s, %s%s", i, a->tag, a->prpl->name, a->user, con ); 494 495 i ++; 496 } 497 irc_rootmsg( irc, "End of account list" ); 498 499 return; 500 } 501 else if( cmd[2] ) 502 { 472 } 473 474 irc_rootmsg(irc, "%2d (%s): %s, %s%s", i, a->tag, a->prpl->name, a->user, con); 475 476 i++; 477 } 478 irc_rootmsg(irc, "End of account list"); 479 480 return; 481 } else if (cmd[2]) { 503 482 /* Try the following two only if cmd[2] == NULL */ 504 } 505 else if( len >= 2 && g_strncasecmp( cmd[1], "on", len ) == 0 ) 506 { 507 if ( irc->b->accounts ) 508 { 509 irc_rootmsg( irc, "Trying to get all accounts connected..." ); 510 511 for( a = irc->b->accounts; a; a = a->next ) 512 if( !a->ic && a->auto_connect ) 513 { 514 if( strcmp( a->pass, PASSWORD_PENDING ) == 0 ) 515 irc_rootmsg( irc, "Enter password for account %s " 516 "first (use /OPER)", a->tag ); 517 else 518 account_on( irc->b, a ); 483 } else if (len >= 2 && g_strncasecmp(cmd[1], "on", len) == 0) { 484 if (irc->b->accounts) { 485 irc_rootmsg(irc, "Trying to get all accounts connected..."); 486 487 for (a = irc->b->accounts; a; a = a->next) { 488 if (!a->ic && a->auto_connect) { 489 if (strcmp(a->pass, PASSWORD_PENDING) == 0) { 490 irc_rootmsg(irc, "Enter password for account %s " 491 "first (use /OPER)", a->tag); 492 } else { 493 account_on(irc->b, a); 494 } 519 495 } 520 } 521 else 522 { 523 irc_rootmsg( irc, "No accounts known. Use `account add' to add one." ); 524 } 525 526 return; 527 } 528 else if( len >= 2 && g_strncasecmp( cmd[1], "off", len ) == 0 ) 529 { 530 irc_rootmsg( irc, "Deactivating all active (re)connections..." ); 531 532 for( a = irc->b->accounts; a; a = a->next ) 533 { 534 if( a->ic ) 535 account_off( irc->b, a ); 536 else if( a->reconnect ) 537 cancel_auto_reconnect( a ); 538 } 539 540 return; 541 } 542 543 MIN_ARGS( 2 ); 544 len = strlen( cmd[2] ); 545 496 } 497 } else { 498 irc_rootmsg(irc, "No accounts known. Use `account add' to add one."); 499 } 500 501 return; 502 } else if (len >= 2 && g_strncasecmp(cmd[1], "off", len) == 0) { 503 irc_rootmsg(irc, "Deactivating all active (re)connections..."); 504 505 for (a = irc->b->accounts; a; a = a->next) { 506 if (a->ic) { 507 account_off(irc->b, a); 508 } else if (a->reconnect) { 509 cancel_auto_reconnect(a); 510 } 511 } 512 513 return; 514 } 515 516 MIN_ARGS(2); 517 len = strlen(cmd[2]); 518 546 519 /* At least right now, don't accept on/off/set/del as account IDs even 547 520 if they're a proper match, since people not familiar with the new 548 521 syntax yet may get a confusing/nasty surprise. */ 549 if( g_strcasecmp( cmd[1], "on" ) == 0 || 550 g_strcasecmp( cmd[1], "off" ) == 0 || 551 g_strcasecmp( cmd[1], "set" ) == 0 || 552 g_strcasecmp( cmd[1], "del" ) == 0 || 553 ( a = account_get( irc->b, cmd[1] ) ) == NULL ) 554 { 555 irc_rootmsg( irc, "Could not find account `%s'.", cmd[1] ); 556 557 return; 558 } 559 560 if( len >= 1 && g_strncasecmp( cmd[2], "del", len ) == 0 ) 561 { 562 if( a->ic ) 563 { 564 irc_rootmsg( irc, "Account is still logged in, can't delete" ); 565 } 566 else 567 { 568 account_del( irc->b, a ); 569 irc_rootmsg( irc, "Account deleted" ); 570 } 571 } 572 else if( len >= 2 && g_strncasecmp( cmd[2], "on", len ) == 0 ) 573 { 574 if( a->ic ) 575 irc_rootmsg( irc, "Account already online" ); 576 else if( strcmp( a->pass, PASSWORD_PENDING ) == 0 ) 577 irc_rootmsg( irc, "Enter password for account %s " 578 "first (use /OPER)", a->tag ); 579 else 580 account_on( irc->b, a ); 581 } 582 else if( len >= 2 && g_strncasecmp( cmd[2], "off", len ) == 0 ) 583 { 584 if( a->ic ) 585 { 586 account_off( irc->b, a ); 587 } 588 else if( a->reconnect ) 589 { 590 cancel_auto_reconnect( a ); 591 irc_rootmsg( irc, "Reconnect cancelled" ); 592 } 593 else 594 { 595 irc_rootmsg( irc, "Account already offline" ); 596 } 597 } 598 else if( len >= 1 && g_strncasecmp( cmd[2], "set", len ) == 0 ) 599 { 600 cmd_set_real( irc, cmd + 2, &a->set, cmd_account_set_checkflags ); 601 } 602 else 603 { 604 irc_rootmsg( irc, "Unknown command: %s [...] %s. Please use \x02help commands\x02 to get a list of available commands.", "account", cmd[2] ); 605 } 606 } 607 608 static void cmd_channel( irc_t *irc, char **cmd ) 522 if (g_strcasecmp(cmd[1], "on") == 0 || 523 g_strcasecmp(cmd[1], "off") == 0 || 524 g_strcasecmp(cmd[1], "set") == 0 || 525 g_strcasecmp(cmd[1], "del") == 0 || 526 (a = account_get(irc->b, cmd[1])) == NULL) { 527 irc_rootmsg(irc, "Could not find account `%s'.", cmd[1]); 528 529 return; 530 } 531 532 if (len >= 1 && g_strncasecmp(cmd[2], "del", len) == 0) { 533 if (a->ic) { 534 irc_rootmsg(irc, "Account is still logged in, can't delete"); 535 } else { 536 account_del(irc->b, a); 537 irc_rootmsg(irc, "Account deleted"); 538 } 539 } else if (len >= 2 && g_strncasecmp(cmd[2], "on", len) == 0) { 540 if (a->ic) { 541 irc_rootmsg(irc, "Account already online"); 542 } else if (strcmp(a->pass, PASSWORD_PENDING) == 0) { 543 irc_rootmsg(irc, "Enter password for account %s " 544 "first (use /OPER)", a->tag); 545 } else { 546 account_on(irc->b, a); 547 } 548 } else if (len >= 2 && g_strncasecmp(cmd[2], "off", len) == 0) { 549 if (a->ic) { 550 account_off(irc->b, a); 551 } else if (a->reconnect) { 552 cancel_auto_reconnect(a); 553 irc_rootmsg(irc, "Reconnect cancelled"); 554 } else { 555 irc_rootmsg(irc, "Account already offline"); 556 } 557 } else if (len >= 1 && g_strncasecmp(cmd[2], "set", len) == 0) { 558 cmd_set_real(irc, cmd + 2, &a->set, cmd_account_set_checkflags); 559 } else { 560 irc_rootmsg(irc, 561 "Unknown command: %s [...] %s. Please use \x02help commands\x02 to get a list of available commands.", "account", 562 cmd[2]); 563 } 564 } 565 566 static void cmd_channel(irc_t *irc, char **cmd) 609 567 { 610 568 irc_channel_t *ic; 611 569 int len; 612 613 len = strlen( cmd[1] ); 614 615 if( len >= 1 && g_strncasecmp( cmd[1], "list", len ) == 0 ) 616 { 570 571 len = strlen(cmd[1]); 572 573 if (len >= 1 && g_strncasecmp(cmd[1], "list", len) == 0) { 617 574 GSList *l; 618 575 int i = 0; 619 620 if ( strchr( irc->umode, 'b' ) )621 irc_rootmsg( irc, "Channel list:");622 623 for( l = irc->channels; l; l = l->next ) 624 {576 577 if (strchr(irc->umode, 'b')) { 578 irc_rootmsg(irc, "Channel list:"); 579 } 580 581 for (l = irc->channels; l; l = l->next) { 625 582 irc_channel_t *ic = l->data; 626 627 irc_rootmsg( irc, "%2d. %s, %s channel%s", i, ic->name, 628 set_getstr( &ic->set, "type" ), 629 ic->flags & IRC_CHANNEL_JOINED ? " (joined)" : "" ); 630 631 i ++; 632 } 633 irc_rootmsg( irc, "End of channel list" ); 634 635 return; 636 } 637 638 if( ( ic = irc_channel_get( irc, cmd[1] ) ) == NULL ) 639 { 583 584 irc_rootmsg(irc, "%2d. %s, %s channel%s", i, ic->name, 585 set_getstr(&ic->set, "type"), 586 ic->flags & IRC_CHANNEL_JOINED ? " (joined)" : ""); 587 588 i++; 589 } 590 irc_rootmsg(irc, "End of channel list"); 591 592 return; 593 } 594 595 if ((ic = irc_channel_get(irc, cmd[1])) == NULL) { 640 596 /* If this doesn't match any channel, maybe this is the short 641 597 syntax (only works when used inside a channel). */ 642 if( ( ic = irc->root->last_channel ) && 643 ( len = strlen( cmd[1] ) ) && 644 g_strncasecmp( cmd[1], "set", len ) == 0 ) 645 cmd_set_real( irc, cmd + 1, &ic->set, NULL ); 646 else 647 irc_rootmsg( irc, "Could not find channel `%s'", cmd[1] ); 648 649 return; 650 } 651 652 MIN_ARGS( 2 ); 653 len = strlen( cmd[2] ); 654 655 if( len >= 1 && g_strncasecmp( cmd[2], "set", len ) == 0 ) 656 { 657 cmd_set_real( irc, cmd + 2, &ic->set, NULL ); 658 } 659 else if( len >= 1 && g_strncasecmp( cmd[2], "del", len ) == 0 ) 660 { 661 if( !( ic->flags & IRC_CHANNEL_JOINED ) && 662 ic != ic->irc->default_channel ) 663 { 664 irc_rootmsg( irc, "Channel %s deleted.", ic->name ); 665 irc_channel_free( ic ); 666 } 667 else 668 irc_rootmsg( irc, "Couldn't remove channel (main channel %s or " 669 "channels you're still in cannot be deleted).", 670 irc->default_channel->name ); 671 } 672 else 673 { 674 irc_rootmsg( irc, "Unknown command: %s [...] %s. Please use \x02help commands\x02 to get a list of available commands.", "channel", cmd[1] ); 675 } 676 } 677 678 static void cmd_add( irc_t *irc, char **cmd ) 598 if ((ic = irc->root->last_channel) && 599 (len = strlen(cmd[1])) && 600 g_strncasecmp(cmd[1], "set", len) == 0) { 601 cmd_set_real(irc, cmd + 1, &ic->set, NULL); 602 } else { 603 irc_rootmsg(irc, "Could not find channel `%s'", cmd[1]); 604 } 605 606 return; 607 } 608 609 MIN_ARGS(2); 610 len = strlen(cmd[2]); 611 612 if (len >= 1 && g_strncasecmp(cmd[2], "set", len) == 0) { 613 cmd_set_real(irc, cmd + 2, &ic->set, NULL); 614 } else if (len >= 1 && g_strncasecmp(cmd[2], "del", len) == 0) { 615 if (!(ic->flags & IRC_CHANNEL_JOINED) && 616 ic != ic->irc->default_channel) { 617 irc_rootmsg(irc, "Channel %s deleted.", ic->name); 618 irc_channel_free(ic); 619 } else { 620 irc_rootmsg(irc, "Couldn't remove channel (main channel %s or " 621 "channels you're still in cannot be deleted).", 622 irc->default_channel->name); 623 } 624 } else { 625 irc_rootmsg(irc, 626 "Unknown command: %s [...] %s. Please use \x02help commands\x02 to get a list of available commands.", "channel", 627 cmd[1]); 628 } 629 } 630 631 static void cmd_add(irc_t *irc, char **cmd) 679 632 { 680 633 account_t *a; 681 634 int add_on_server = 1; 682 635 char *handle = NULL, *s; 683 684 if( g_strcasecmp( cmd[1], "-tmp" ) == 0 ) 685 { 686 MIN_ARGS( 3 ); 636 637 if (g_strcasecmp(cmd[1], "-tmp") == 0) { 638 MIN_ARGS(3); 687 639 add_on_server = 0; 688 cmd ++; 689 } 690 691 if( !( a = account_get( irc->b, cmd[1] ) ) ) 692 { 693 irc_rootmsg( irc, "Invalid account" ); 694 return; 695 } 696 else if( !( a->ic && ( a->ic->flags & OPT_LOGGED_IN ) ) ) 697 { 698 irc_rootmsg( irc, "That account is not on-line" ); 699 return; 700 } 701 702 if( cmd[3] ) 703 { 704 if( !nick_ok( irc, cmd[3] ) ) 705 { 706 irc_rootmsg( irc, "The requested nick `%s' is invalid", cmd[3] ); 640 cmd++; 641 } 642 643 if (!(a = account_get(irc->b, cmd[1]))) { 644 irc_rootmsg(irc, "Invalid account"); 645 return; 646 } else if (!(a->ic && (a->ic->flags & OPT_LOGGED_IN))) { 647 irc_rootmsg(irc, "That account is not on-line"); 648 return; 649 } 650 651 if (cmd[3]) { 652 if (!nick_ok(irc, cmd[3])) { 653 irc_rootmsg(irc, "The requested nick `%s' is invalid", cmd[3]); 707 654 return; 708 } 709 else if( irc_user_by_name( irc, cmd[3] ) ) 710 { 711 irc_rootmsg( irc, "The requested nick `%s' already exists", cmd[3] ); 655 } else if (irc_user_by_name(irc, cmd[3])) { 656 irc_rootmsg(irc, "The requested nick `%s' already exists", cmd[3]); 712 657 return; 713 } 714 else 715 { 716 nick_set_raw( a, cmd[2], cmd[3] ); 717 } 718 } 719 720 if( ( a->flags & ACC_FLAG_HANDLE_DOMAINS ) && cmd[2][0] != '_' && 721 ( !( s = strchr( cmd[2], '@' ) ) || s[1] == '\0' ) ) 722 { 658 } else { 659 nick_set_raw(a, cmd[2], cmd[3]); 660 } 661 } 662 663 if ((a->flags & ACC_FLAG_HANDLE_DOMAINS) && cmd[2][0] != '_' && 664 (!(s = strchr(cmd[2], '@')) || s[1] == '\0')) { 723 665 /* If there's no @ or it's the last char, append the user's 724 666 domain name now. Exclude handles starting with a _ so 725 667 adding _xmlconsole will keep working. */ 726 if ( s )668 if (s) { 727 669 *s = '\0'; 728 if( ( s = strchr( a->user, '@' ) ) ) 729 cmd[2] = handle = g_strconcat( cmd[2], s, NULL ); 730 } 731 732 if( add_on_server ) 733 { 670 } 671 if ((s = strchr(a->user, '@'))) { 672 cmd[2] = handle = g_strconcat(cmd[2], s, NULL); 673 } 674 } 675 676 if (add_on_server) { 734 677 irc_channel_t *ic; 735 678 char *s, *group = NULL;; 736 737 if( ( ic = irc->root->last_channel ) && 738 ( s = set_getstr( &ic->set, "fill_by" ) ) && 739 strcmp( s, "group" ) == 0 && 740 ( group = set_getstr( &ic->set, "group" ) ) ) 741 irc_rootmsg( irc, "Adding `%s' to contact list (group %s)", 742 cmd[2], group ); 743 else 744 irc_rootmsg( irc, "Adding `%s' to contact list", cmd[2] ); 745 746 a->prpl->add_buddy( a->ic, cmd[2], group ); 747 } 748 else 749 { 679 680 if ((ic = irc->root->last_channel) && 681 (s = set_getstr(&ic->set, "fill_by")) && 682 strcmp(s, "group") == 0 && 683 (group = set_getstr(&ic->set, "group"))) { 684 irc_rootmsg(irc, "Adding `%s' to contact list (group %s)", 685 cmd[2], group); 686 } else { 687 irc_rootmsg(irc, "Adding `%s' to contact list", cmd[2]); 688 } 689 690 a->prpl->add_buddy(a->ic, cmd[2], group); 691 } else { 750 692 bee_user_t *bu; 751 693 irc_user_t *iu; 752 694 753 695 /* Only for add -tmp. For regular adds, this callback will 754 696 be called once the IM server confirms. */ 755 if( ( bu = bee_user_new( irc->b, a->ic, cmd[2], BEE_USER_LOCAL ) ) && 756 ( iu = bu->ui_data ) ) 757 irc_rootmsg( irc, "Temporarily assigned nickname `%s' " 758 "to contact `%s'", iu->nick, cmd[2] ); 759 } 760 761 g_free( handle ); 762 } 763 764 static void cmd_remove( irc_t *irc, char **cmd ) 697 if ((bu = bee_user_new(irc->b, a->ic, cmd[2], BEE_USER_LOCAL)) && 698 (iu = bu->ui_data)) { 699 irc_rootmsg(irc, "Temporarily assigned nickname `%s' " 700 "to contact `%s'", iu->nick, cmd[2]); 701 } 702 } 703 704 g_free(handle); 705 } 706 707 static void cmd_remove(irc_t *irc, char **cmd) 765 708 { 766 709 irc_user_t *iu; 767 710 bee_user_t *bu; 768 711 char *s; 769 770 if ( !( iu = irc_user_by_name( irc, cmd[1] ) ) || !( bu = iu->bu ) )771 {772 irc_rootmsg( irc, "Buddy `%s' not found", cmd[1] );773 return;774 }775 s = g_strdup( bu->handle ); 776 777 bu->ic->acc->prpl->remove_buddy( bu->ic, bu->handle, NULL);778 nick_del( bu );779 if( g_slist_find( irc->users, iu ) )780 bee_user_free( irc->b, bu );781 782 irc_rootmsg( irc, "Buddy `%s' (nick %s) removed from contact list", s, cmd[1]);783 g_free( s);784 712 713 if (!(iu = irc_user_by_name(irc, cmd[1])) || !(bu = iu->bu)) { 714 irc_rootmsg(irc, "Buddy `%s' not found", cmd[1]); 715 return; 716 } 717 s = g_strdup(bu->handle); 718 719 bu->ic->acc->prpl->remove_buddy(bu->ic, bu->handle, NULL); 720 nick_del(bu); 721 if (g_slist_find(irc->users, iu)) { 722 bee_user_free(irc->b, bu); 723 } 724 725 irc_rootmsg(irc, "Buddy `%s' (nick %s) removed from contact list", s, cmd[1]); 726 g_free(s); 727 785 728 return; 786 729 } 787 730 788 static void cmd_info( irc_t *irc, char **cmd)731 static void cmd_info(irc_t *irc, char **cmd) 789 732 { 790 733 struct im_connection *ic; 791 734 account_t *a; 792 793 if( !cmd[2] ) 794 { 795 irc_user_t *iu = irc_user_by_name( irc, cmd[1] ); 796 if( !iu || !iu->bu ) 797 { 798 irc_rootmsg( irc, "Nick `%s' does not exist", cmd[1] ); 735 736 if (!cmd[2]) { 737 irc_user_t *iu = irc_user_by_name(irc, cmd[1]); 738 if (!iu || !iu->bu) { 739 irc_rootmsg(irc, "Nick `%s' does not exist", cmd[1]); 799 740 return; 800 741 } 801 742 ic = iu->bu->ic; 802 743 cmd[2] = iu->bu->handle; 803 } 804 else if( !( a = account_get( irc->b, cmd[1] ) ) ) 805 { 806 irc_rootmsg( irc, "Invalid account" ); 807 return; 808 } 809 else if( !( ( ic = a->ic ) && ( a->ic->flags & OPT_LOGGED_IN ) ) ) 810 { 811 irc_rootmsg( irc, "That account is not on-line" ); 812 return; 813 } 814 815 if( !ic->acc->prpl->get_info ) 816 { 817 irc_rootmsg( irc, "Command `%s' not supported by this protocol", cmd[0] ); 818 } 819 else 820 { 821 ic->acc->prpl->get_info( ic, cmd[2] ); 822 } 823 } 824 825 static void cmd_rename( irc_t *irc, char **cmd ) 744 } else if (!(a = account_get(irc->b, cmd[1]))) { 745 irc_rootmsg(irc, "Invalid account"); 746 return; 747 } else if (!((ic = a->ic) && (a->ic->flags & OPT_LOGGED_IN))) { 748 irc_rootmsg(irc, "That account is not on-line"); 749 return; 750 } 751 752 if (!ic->acc->prpl->get_info) { 753 irc_rootmsg(irc, "Command `%s' not supported by this protocol", cmd[0]); 754 } else { 755 ic->acc->prpl->get_info(ic, cmd[2]); 756 } 757 } 758 759 static void cmd_rename(irc_t *irc, char **cmd) 826 760 { 827 761 irc_user_t *iu, *old; 828 gboolean del = g_strcasecmp( cmd[1], "-del" ) == 0; 829 830 iu = irc_user_by_name( irc, cmd[del ? 2 : 1] ); 831 832 if( iu == NULL ) 833 { 834 irc_rootmsg( irc, "Nick `%s' does not exist", cmd[1] ); 835 } 836 else if( del ) 837 { 838 if( iu->bu ) 839 bee_irc_user_nick_reset( iu ); 840 irc_rootmsg( irc, "Nickname reset to `%s'", iu->nick ); 841 } 842 else if( iu == irc->user ) 843 { 844 irc_rootmsg( irc, "Use /nick to change your own nickname" ); 845 } 846 else if( !nick_ok( irc, cmd[2] ) ) 847 { 848 irc_rootmsg( irc, "Nick `%s' is invalid", cmd[2] ); 849 } 850 else if( ( old = irc_user_by_name( irc, cmd[2] ) ) && old != iu ) 851 { 852 irc_rootmsg( irc, "Nick `%s' already exists", cmd[2] ); 853 } 854 else 855 { 856 if( !irc_user_set_nick( iu, cmd[2] ) ) 857 { 858 irc_rootmsg( irc, "Error while changing nick" ); 762 gboolean del = g_strcasecmp(cmd[1], "-del") == 0; 763 764 iu = irc_user_by_name(irc, cmd[del ? 2 : 1]); 765 766 if (iu == NULL) { 767 irc_rootmsg(irc, "Nick `%s' does not exist", cmd[1]); 768 } else if (del) { 769 if (iu->bu) { 770 bee_irc_user_nick_reset(iu); 771 } 772 irc_rootmsg(irc, "Nickname reset to `%s'", iu->nick); 773 } else if (iu == irc->user) { 774 irc_rootmsg(irc, "Use /nick to change your own nickname"); 775 } else if (!nick_ok(irc, cmd[2])) { 776 irc_rootmsg(irc, "Nick `%s' is invalid", cmd[2]); 777 } else if ((old = irc_user_by_name(irc, cmd[2])) && old != iu) { 778 irc_rootmsg(irc, "Nick `%s' already exists", cmd[2]); 779 } else { 780 if (!irc_user_set_nick(iu, cmd[2])) { 781 irc_rootmsg(irc, "Error while changing nick"); 859 782 return; 860 783 } 861 862 if( iu == irc->root ) 863 { 784 785 if (iu == irc->root) { 864 786 /* If we're called internally (user did "set root_nick"), 865 787 let's not go O(INF). :-) */ 866 if( strcmp( cmd[0], "set_rename" ) != 0 ) 867 set_setstr( &irc->b->set, "root_nick", cmd[2] ); 868 } 869 else if( iu->bu ) 870 { 871 nick_set( iu->bu, cmd[2] ); 872 } 873 874 irc_rootmsg( irc, "Nick successfully changed" ); 875 } 876 } 877 878 char *set_eval_root_nick( set_t *set, char *new_nick ) 788 if (strcmp(cmd[0], "set_rename") != 0) { 789 set_setstr(&irc->b->set, "root_nick", cmd[2]); 790 } 791 } else if (iu->bu) { 792 nick_set(iu->bu, cmd[2]); 793 } 794 795 irc_rootmsg(irc, "Nick successfully changed"); 796 } 797 } 798 799 char *set_eval_root_nick(set_t *set, char *new_nick) 879 800 { 880 801 irc_t *irc = set->data; 881 882 if( strcmp( irc->root->nick, new_nick ) != 0 ) 883 { 802 803 if (strcmp(irc->root->nick, new_nick) != 0) { 884 804 char *cmd[] = { "set_rename", irc->root->nick, new_nick, NULL }; 885 886 cmd_rename( irc, cmd);887 } 888 889 return strcmp( irc->root->nick, new_nick) == 0 ? new_nick : SET_INVALID;890 } 891 892 static void cmd_block( irc_t *irc, char **cmd)805 806 cmd_rename(irc, cmd); 807 } 808 809 return strcmp(irc->root->nick, new_nick) == 0 ? new_nick : SET_INVALID; 810 } 811 812 static void cmd_block(irc_t *irc, char **cmd) 893 813 { 894 814 struct im_connection *ic; 895 815 account_t *a; 896 897 if( !cmd[2] && ( a = account_get( irc->b, cmd[1] ) ) && a->ic ) 898 { 816 817 if (!cmd[2] && (a = account_get(irc->b, cmd[1])) && a->ic) { 899 818 char *format; 900 819 GSList *l; 901 902 if ( strchr( irc->umode, 'b' ) != NULL )820 821 if (strchr(irc->umode, 'b') != NULL) { 903 822 format = "%s\t%s"; 904 else823 } else { 905 824 format = "%-32.32s %-16.16s"; 906 907 irc_rootmsg( irc, format, "Handle", "Nickname" ); 908 for( l = a->ic->deny; l; l = l->next )909 {910 bee_user_t *bu = bee_user_by_handle( irc->b, a->ic, l->data);825 } 826 827 irc_rootmsg(irc, format, "Handle", "Nickname"); 828 for (l = a->ic->deny; l; l = l->next) { 829 bee_user_t *bu = bee_user_by_handle(irc->b, a->ic, l->data); 911 830 irc_user_t *iu = bu ? bu->ui_data : NULL; 912 irc_rootmsg( irc, format, l->data, iu ? iu->nick : "(none)" ); 913 } 914 irc_rootmsg( irc, "End of list." ); 915 916 return; 917 } 918 else if( !cmd[2] ) 919 { 920 irc_user_t *iu = irc_user_by_name( irc, cmd[1] ); 921 if( !iu || !iu->bu ) 922 { 923 irc_rootmsg( irc, "Nick `%s' does not exist", cmd[1] ); 831 irc_rootmsg(irc, format, l->data, iu ? iu->nick : "(none)"); 832 } 833 irc_rootmsg(irc, "End of list."); 834 835 return; 836 } else if (!cmd[2]) { 837 irc_user_t *iu = irc_user_by_name(irc, cmd[1]); 838 if (!iu || !iu->bu) { 839 irc_rootmsg(irc, "Nick `%s' does not exist", cmd[1]); 924 840 return; 925 841 } 926 842 ic = iu->bu->ic; 927 843 cmd[2] = iu->bu->handle; 928 } 929 else if( !( a = account_get( irc->b, cmd[1] ) ) ) 930 { 931 irc_rootmsg( irc, "Invalid account" ); 932 return; 933 } 934 else if( !( ( ic = a->ic ) && ( a->ic->flags & OPT_LOGGED_IN ) ) ) 935 { 936 irc_rootmsg( irc, "That account is not on-line" ); 937 return; 938 } 939 940 if( !ic->acc->prpl->add_deny || !ic->acc->prpl->rem_permit ) 941 { 942 irc_rootmsg( irc, "Command `%s' not supported by this protocol", cmd[0] ); 943 } 944 else 945 { 946 imc_rem_allow( ic, cmd[2] ); 947 imc_add_block( ic, cmd[2] ); 948 irc_rootmsg( irc, "Buddy `%s' moved from allow- to block-list", cmd[2] ); 949 } 950 } 951 952 static void cmd_allow( irc_t *irc, char **cmd ) 844 } else if (!(a = account_get(irc->b, cmd[1]))) { 845 irc_rootmsg(irc, "Invalid account"); 846 return; 847 } else if (!((ic = a->ic) && (a->ic->flags & OPT_LOGGED_IN))) { 848 irc_rootmsg(irc, "That account is not on-line"); 849 return; 850 } 851 852 if (!ic->acc->prpl->add_deny || !ic->acc->prpl->rem_permit) { 853 irc_rootmsg(irc, "Command `%s' not supported by this protocol", cmd[0]); 854 } else { 855 imc_rem_allow(ic, cmd[2]); 856 imc_add_block(ic, cmd[2]); 857 irc_rootmsg(irc, "Buddy `%s' moved from allow- to block-list", cmd[2]); 858 } 859 } 860 861 static void cmd_allow(irc_t *irc, char **cmd) 953 862 { 954 863 struct im_connection *ic; 955 864 account_t *a; 956 957 if( !cmd[2] && ( a = account_get( irc->b, cmd[1] ) ) && a->ic ) 958 { 865 866 if (!cmd[2] && (a = account_get(irc->b, cmd[1])) && a->ic) { 959 867 char *format; 960 868 GSList *l; 961 962 if ( strchr( irc->umode, 'b' ) != NULL )869 870 if (strchr(irc->umode, 'b') != NULL) { 963 871 format = "%s\t%s"; 964 else872 } else { 965 873 format = "%-32.32s %-16.16s"; 966 967 irc_rootmsg( irc, format, "Handle", "Nickname" ); 968 for( l = a->ic->permit; l; l = l->next )969 {970 bee_user_t *bu = bee_user_by_handle( irc->b, a->ic, l->data);874 } 875 876 irc_rootmsg(irc, format, "Handle", "Nickname"); 877 for (l = a->ic->permit; l; l = l->next) { 878 bee_user_t *bu = bee_user_by_handle(irc->b, a->ic, l->data); 971 879 irc_user_t *iu = bu ? bu->ui_data : NULL; 972 irc_rootmsg( irc, format, l->data, iu ? iu->nick : "(none)" ); 973 } 974 irc_rootmsg( irc, "End of list." ); 975 976 return; 977 } 978 else if( !cmd[2] ) 979 { 980 irc_user_t *iu = irc_user_by_name( irc, cmd[1] ); 981 if( !iu || !iu->bu ) 982 { 983 irc_rootmsg( irc, "Nick `%s' does not exist", cmd[1] ); 880 irc_rootmsg(irc, format, l->data, iu ? iu->nick : "(none)"); 881 } 882 irc_rootmsg(irc, "End of list."); 883 884 return; 885 } else if (!cmd[2]) { 886 irc_user_t *iu = irc_user_by_name(irc, cmd[1]); 887 if (!iu || !iu->bu) { 888 irc_rootmsg(irc, "Nick `%s' does not exist", cmd[1]); 984 889 return; 985 890 } 986 891 ic = iu->bu->ic; 987 892 cmd[2] = iu->bu->handle; 988 } 989 else if( !( a = account_get( irc->b, cmd[1] ) ) ) 990 { 991 irc_rootmsg( irc, "Invalid account" ); 992 return; 993 } 994 else if( !( ( ic = a->ic ) && ( a->ic->flags & OPT_LOGGED_IN ) ) ) 995 { 996 irc_rootmsg( irc, "That account is not on-line" ); 997 return; 998 } 999 1000 if( !ic->acc->prpl->rem_deny || !ic->acc->prpl->add_permit ) 1001 { 1002 irc_rootmsg( irc, "Command `%s' not supported by this protocol", cmd[0] ); 1003 } 1004 else 1005 { 1006 imc_rem_block( ic, cmd[2] ); 1007 imc_add_allow( ic, cmd[2] ); 1008 1009 irc_rootmsg( irc, "Buddy `%s' moved from block- to allow-list", cmd[2] ); 1010 } 1011 } 1012 1013 static void cmd_yesno( irc_t *irc, char **cmd ) 893 } else if (!(a = account_get(irc->b, cmd[1]))) { 894 irc_rootmsg(irc, "Invalid account"); 895 return; 896 } else if (!((ic = a->ic) && (a->ic->flags & OPT_LOGGED_IN))) { 897 irc_rootmsg(irc, "That account is not on-line"); 898 return; 899 } 900 901 if (!ic->acc->prpl->rem_deny || !ic->acc->prpl->add_permit) { 902 irc_rootmsg(irc, "Command `%s' not supported by this protocol", cmd[0]); 903 } else { 904 imc_rem_block(ic, cmd[2]); 905 imc_add_allow(ic, cmd[2]); 906 907 irc_rootmsg(irc, "Buddy `%s' moved from block- to allow-list", cmd[2]); 908 } 909 } 910 911 static void cmd_yesno(irc_t *irc, char **cmd) 1014 912 { 1015 913 query_t *q = NULL; 1016 914 int numq = 0; 1017 1018 if( irc->queries == NULL ) 1019 { 915 916 if (irc->queries == NULL) { 1020 917 /* Alright, alright, let's add a tiny easter egg here. */ 1021 918 static irc_t *last_irc = NULL; … … 1029 926 "No?", 1030 927 }; 1031 1032 if( last_irc == irc && time( NULL ) - last_time < 15 ) 1033 { 1034 if( ( ++times >= 3 ) ) 1035 { 1036 irc_rootmsg( irc, "%s", msg[rand()%(sizeof(msg)/sizeof(char*))] ); 928 929 if (last_irc == irc && time(NULL) - last_time < 15) { 930 if ((++times >= 3)) { 931 irc_rootmsg(irc, "%s", msg[rand() % (sizeof(msg) / sizeof(char*))]); 1037 932 last_irc = NULL; 1038 933 times = 0; 1039 934 return; 1040 935 } 1041 } 1042 else 1043 { 1044 last_time = time( NULL ); 936 } else { 937 last_time = time(NULL); 1045 938 last_irc = irc; 1046 939 times = 0; 1047 940 } 1048 1049 irc_rootmsg( irc, "Did I ask you something?");1050 return; 1051 } 1052 941 942 irc_rootmsg(irc, "Did I ask you something?"); 943 return; 944 } 945 1053 946 /* If there's an argument, the user seems to want to answer another question than the 1054 947 first/last (depending on the query_order setting) one. */ 1055 if( cmd[1] ) 1056 { 1057 if( sscanf( cmd[1], "%d", &numq ) != 1 ) 1058 { 1059 irc_rootmsg( irc, "Invalid query number" ); 948 if (cmd[1]) { 949 if (sscanf(cmd[1], "%d", &numq) != 1) { 950 irc_rootmsg(irc, "Invalid query number"); 1060 951 return; 1061 952 } 1062 1063 for ( q = irc->queries; q; q = q->next, numq -- )1064 if ( numq == 0 )953 954 for (q = irc->queries; q; q = q->next, numq--) { 955 if (numq == 0) { 1065 956 break; 1066 1067 if( !q ) 1068 { 1069 irc_rootmsg( irc, "Uhm, I never asked you something like that..." ); 957 } 958 } 959 960 if (!q) { 961 irc_rootmsg(irc, "Uhm, I never asked you something like that..."); 1070 962 return; 1071 963 } 1072 964 } 1073 1074 if( g_strcasecmp( cmd[0], "yes" ) == 0 ) 1075 query_answer( irc, q, 1 ); 1076 else if( g_strcasecmp( cmd[0], "no" ) == 0 ) 1077 query_answer( irc, q, 0 ); 1078 } 1079 1080 static void cmd_set( irc_t *irc, char **cmd ) 1081 { 1082 cmd_set_real( irc, cmd, &irc->b->set, NULL ); 1083 } 1084 1085 static void cmd_blist( irc_t *irc, char **cmd ) 965 966 if (g_strcasecmp(cmd[0], "yes") == 0) { 967 query_answer(irc, q, 1); 968 } else if (g_strcasecmp(cmd[0], "no") == 0) { 969 query_answer(irc, q, 0); 970 } 971 } 972 973 static void cmd_set(irc_t *irc, char **cmd) 974 { 975 cmd_set_real(irc, cmd, &irc->b->set, NULL); 976 } 977 978 static void cmd_blist(irc_t *irc, char **cmd) 1086 979 { 1087 980 int online = 0, away = 0, offline = 0, ismatch = 0; … … 1092 985 char *format; 1093 986 int n_online = 0, n_away = 0, n_offline = 0; 1094 1095 if ( cmd[1] && g_strcasecmp( cmd[1], "all" ) == 0 )987 988 if (cmd[1] && g_strcasecmp(cmd[1], "all") == 0) { 1096 989 online = offline = away = 1; 1097 else if( cmd[1] && g_strcasecmp( cmd[1], "offline" ) == 0 )990 } else if (cmd[1] && g_strcasecmp(cmd[1], "offline") == 0) { 1098 991 offline = 1; 1099 else if( cmd[1] && g_strcasecmp( cmd[1], "away" ) == 0 )992 } else if (cmd[1] && g_strcasecmp(cmd[1], "away") == 0) { 1100 993 away = 1; 1101 else if( cmd[1] && g_strcasecmp( cmd[1], "online" ) == 0 )994 } else if (cmd[1] && g_strcasecmp(cmd[1], "online") == 0) { 1102 995 online = 1; 1103 else996 } else { 1104 997 online = away = 1; 1105 1106 if( cmd[2] ) 1107 regex = g_regex_new( cmd[2], G_REGEX_CASELESS, 0, &error ); 1108 1109 if( error ) 1110 { 1111 irc_rootmsg( irc, error->message ); 1112 g_error_free( error ); 1113 } 1114 1115 if( strchr( irc->umode, 'b' ) != NULL ) 998 } 999 1000 if (cmd[2]) { 1001 regex = g_regex_new(cmd[2], G_REGEX_CASELESS, 0, &error); 1002 } 1003 1004 if (error) { 1005 irc_rootmsg(irc, error->message); 1006 g_error_free(error); 1007 } 1008 1009 if (strchr(irc->umode, 'b') != NULL) { 1116 1010 format = "%s\t%s\t%s"; 1117 else1011 } else { 1118 1012 format = "%-16.16s %-40.40s %s"; 1119 1120 irc_rootmsg( irc, format, "Nick", "Handle/Account", "Status" ); 1121 1122 if( irc->root->last_channel && 1123 strcmp( set_getstr( &irc->root->last_channel->set, "type" ), "control" ) != 0 ) 1013 } 1014 1015 irc_rootmsg(irc, format, "Nick", "Handle/Account", "Status"); 1016 1017 if (irc->root->last_channel && 1018 strcmp(set_getstr(&irc->root->last_channel->set, "type"), "control") != 0) { 1124 1019 irc->root->last_channel = NULL; 1125 1126 for( l = irc->users; l; l = l->next ) 1127 {1020 } 1021 1022 for (l = irc->users; l; l = l->next) { 1128 1023 irc_user_t *iu = l->data; 1129 1024 bee_user_t *bu = iu->bu; 1130 1131 if ( !regex || g_regex_match( regex, iu->nick, 0, NULL ) )1025 1026 if (!regex || g_regex_match(regex, iu->nick, 0, NULL)) { 1132 1027 ismatch = 1; 1133 else1028 } else { 1134 1029 ismatch = 0; 1135 1136 if( !bu || ( irc->root->last_channel && !irc_channel_wants_user( irc->root->last_channel, iu ) ) ) 1030 } 1031 1032 if (!bu || (irc->root->last_channel && !irc_channel_wants_user(irc->root->last_channel, iu))) { 1137 1033 continue; 1138 1139 if( ( bu->flags & ( BEE_USER_ONLINE | BEE_USER_AWAY ) ) == BEE_USER_ONLINE ) 1140 { 1141 if( ismatch == 1 && online == 1 ) 1142 { 1034 } 1035 1036 if ((bu->flags & (BEE_USER_ONLINE | BEE_USER_AWAY)) == BEE_USER_ONLINE) { 1037 if (ismatch == 1 && online == 1) { 1143 1038 char st[256] = "Online"; 1144 1145 if( bu->status_msg ) 1146 g_snprintf( st, sizeof( st ) - 1, "Online (%s)", bu->status_msg ); 1147 1148 g_snprintf( s, sizeof( s ) - 1, "%s %s", bu->handle, bu->ic->acc->tag ); 1149 irc_rootmsg( irc, format, iu->nick, s, st ); 1150 } 1151 1152 n_online ++; 1153 } 1154 1155 if( ( bu->flags & BEE_USER_ONLINE ) && ( bu->flags & BEE_USER_AWAY ) ) 1156 { 1157 if( ismatch == 1 && away == 1 ) 1158 { 1159 g_snprintf( s, sizeof( s ) - 1, "%s %s", bu->handle, bu->ic->acc->tag ); 1160 irc_rootmsg( irc, format, iu->nick, s, irc_user_get_away( iu ) ); 1161 } 1162 n_away ++; 1163 } 1164 1165 if( !(bu->flags & BEE_USER_ONLINE) ) 1166 { 1167 if( ismatch == 1 && offline == 1 ) 1168 { 1169 g_snprintf( s, sizeof( s ) - 1, "%s %s", bu->handle, bu->ic->acc->tag ); 1170 irc_rootmsg( irc, format, iu->nick, s, "Offline" ); 1171 } 1172 n_offline ++; 1173 } 1174 } 1175 1176 irc_rootmsg( irc, "%d buddies (%d available, %d away, %d offline)", n_online + n_away + n_offline, n_online, n_away, n_offline ); 1177 1178 if( regex ) 1179 g_regex_unref( regex ); 1180 } 1181 1182 static void cmd_qlist( irc_t *irc, char **cmd ) 1039 1040 if (bu->status_msg) { 1041 g_snprintf(st, sizeof(st) - 1, "Online (%s)", bu->status_msg); 1042 } 1043 1044 g_snprintf(s, sizeof(s) - 1, "%s %s", bu->handle, bu->ic->acc->tag); 1045 irc_rootmsg(irc, format, iu->nick, s, st); 1046 } 1047 1048 n_online++; 1049 } 1050 1051 if ((bu->flags & BEE_USER_ONLINE) && (bu->flags & BEE_USER_AWAY)) { 1052 if (ismatch == 1 && away == 1) { 1053 g_snprintf(s, sizeof(s) - 1, "%s %s", bu->handle, bu->ic->acc->tag); 1054 irc_rootmsg(irc, format, iu->nick, s, irc_user_get_away(iu)); 1055 } 1056 n_away++; 1057 } 1058 1059 if (!(bu->flags & BEE_USER_ONLINE)) { 1060 if (ismatch == 1 && offline == 1) { 1061 g_snprintf(s, sizeof(s) - 1, "%s %s", bu->handle, bu->ic->acc->tag); 1062 irc_rootmsg(irc, format, iu->nick, s, "Offline"); 1063 } 1064 n_offline++; 1065 } 1066 } 1067 1068 irc_rootmsg(irc, "%d buddies (%d available, %d away, %d offline)", n_online + n_away + n_offline, n_online, 1069 n_away, n_offline); 1070 1071 if (regex) { 1072 g_regex_unref(regex); 1073 } 1074 } 1075 1076 static void cmd_qlist(irc_t *irc, char **cmd) 1183 1077 { 1184 1078 query_t *q = irc->queries; 1185 1079 int num; 1186 1187 if( !q ) 1188 { 1189 irc_rootmsg( irc, "There are no pending questions." ); 1190 return; 1191 } 1192 1193 irc_rootmsg( irc, "Pending queries:" ); 1194 1195 for( num = 0; q; q = q->next, num ++ ) 1196 if( q->ic ) /* Not necessary yet, but it might come later */ 1197 irc_rootmsg( irc, "%d, %s: %s", num, q->ic->acc->tag, q->question ); 1198 else 1199 irc_rootmsg( irc, "%d, BitlBee: %s", num, q->question ); 1200 } 1201 1202 static void cmd_chat( irc_t *irc, char **cmd ) 1080 1081 if (!q) { 1082 irc_rootmsg(irc, "There are no pending questions."); 1083 return; 1084 } 1085 1086 irc_rootmsg(irc, "Pending queries:"); 1087 1088 for (num = 0; q; q = q->next, num++) { 1089 if (q->ic) { /* Not necessary yet, but it might come later */ 1090 irc_rootmsg(irc, "%d, %s: %s", num, q->ic->acc->tag, q->question); 1091 } else { 1092 irc_rootmsg(irc, "%d, BitlBee: %s", num, q->question); 1093 } 1094 } 1095 } 1096 1097 static void cmd_chat(irc_t *irc, char **cmd) 1203 1098 { 1204 1099 account_t *acc; 1205 1206 if( g_strcasecmp( cmd[1], "add" ) == 0 ) 1207 { 1100 1101 if (g_strcasecmp(cmd[1], "add") == 0) { 1208 1102 char *channel, *s; 1209 1103 struct irc_channel *ic; 1210 1211 MIN_ARGS( 3 ); 1212 1213 if( !( acc = account_get( irc->b, cmd[2] ) ) ) 1214 { 1215 irc_rootmsg( irc, "Invalid account" ); 1104 1105 MIN_ARGS(3); 1106 1107 if (!(acc = account_get(irc->b, cmd[2]))) { 1108 irc_rootmsg(irc, "Invalid account"); 1216 1109 return; 1217 } 1218 else if( !acc->prpl->chat_join ) 1219 { 1220 irc_rootmsg( irc, "Named chatrooms not supported on that account." ); 1110 } else if (!acc->prpl->chat_join) { 1111 irc_rootmsg(irc, "Named chatrooms not supported on that account."); 1221 1112 return; 1222 1113 } 1223 1224 if( cmd[4] == NULL ) 1225 { 1226 channel = g_strdup( cmd[3] ); 1227 if( ( s = strchr( channel, '@' ) ) ) 1114 1115 if (cmd[4] == NULL) { 1116 channel = g_strdup(cmd[3]); 1117 if ((s = strchr(channel, '@'))) { 1228 1118 *s = 0; 1229 } 1230 else 1231 { 1232 channel = g_strdup( cmd[4] ); 1233 } 1234 1235 if( strchr( CTYPES, channel[0] ) == NULL ) 1236 { 1237 s = g_strdup_printf( "#%s", channel ); 1238 g_free( channel ); 1119 } 1120 } else { 1121 channel = g_strdup(cmd[4]); 1122 } 1123 1124 if (strchr(CTYPES, channel[0]) == NULL) { 1125 s = g_strdup_printf("#%s", channel); 1126 g_free(channel); 1239 1127 channel = s; 1240 1241 irc_channel_name_strip( channel ); 1242 } 1243 1244 if( ( ic = irc_channel_new( irc, channel ) ) && 1245 set_setstr( &ic->set, "type", "chat" ) && 1246 set_setstr( &ic->set, "chat_type", "room" ) && 1247 set_setstr( &ic->set, "account", cmd[2] ) && 1248 set_setstr( &ic->set, "room", cmd[3] ) ) 1249 { 1250 irc_rootmsg( irc, "Chatroom successfully added." ); 1251 } 1252 else 1253 { 1254 if( ic ) 1255 irc_channel_free( ic ); 1256 1257 irc_rootmsg( irc, "Could not add chatroom." ); 1258 } 1259 g_free( channel ); 1260 } 1261 else if( g_strcasecmp( cmd[1], "with" ) == 0 ) 1262 { 1128 1129 irc_channel_name_strip(channel); 1130 } 1131 1132 if ((ic = irc_channel_new(irc, channel)) && 1133 set_setstr(&ic->set, "type", "chat") && 1134 set_setstr(&ic->set, "chat_type", "room") && 1135 set_setstr(&ic->set, "account", cmd[2]) && 1136 set_setstr(&ic->set, "room", cmd[3])) { 1137 irc_rootmsg(irc, "Chatroom successfully added."); 1138 } else { 1139 if (ic) { 1140 irc_channel_free(ic); 1141 } 1142 1143 irc_rootmsg(irc, "Could not add chatroom."); 1144 } 1145 g_free(channel); 1146 } else if (g_strcasecmp(cmd[1], "with") == 0) { 1263 1147 irc_user_t *iu; 1264 1265 MIN_ARGS( 2 ); 1266 1267 if( ( iu = irc_user_by_name( irc, cmd[2] ) ) && 1268 iu->bu && iu->bu->ic->acc->prpl->chat_with ) 1269 { 1270 if( !iu->bu->ic->acc->prpl->chat_with( iu->bu->ic, iu->bu->handle ) ) 1271 { 1272 irc_rootmsg( irc, "(Possible) failure while trying to open " 1273 "a groupchat with %s.", iu->nick ); 1274 } 1275 } 1276 else 1277 { 1278 irc_rootmsg( irc, "Can't open a groupchat with %s.", cmd[2] ); 1279 } 1280 } 1281 else if( g_strcasecmp( cmd[1], "list" ) == 0 || 1282 g_strcasecmp( cmd[1], "set" ) == 0 || 1283 g_strcasecmp( cmd[1], "del" ) == 0 ) 1284 { 1285 irc_rootmsg( irc, "Warning: The \002chat\002 command was mostly replaced with the \002channel\002 command." ); 1286 cmd_channel( irc, cmd ); 1287 } 1288 else 1289 { 1290 irc_rootmsg( irc, "Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "chat", cmd[1] ); 1291 } 1292 } 1293 1294 static void cmd_group( irc_t *irc, char **cmd ) 1148 1149 MIN_ARGS(2); 1150 1151 if ((iu = irc_user_by_name(irc, cmd[2])) && 1152 iu->bu && iu->bu->ic->acc->prpl->chat_with) { 1153 if (!iu->bu->ic->acc->prpl->chat_with(iu->bu->ic, iu->bu->handle)) { 1154 irc_rootmsg(irc, "(Possible) failure while trying to open " 1155 "a groupchat with %s.", iu->nick); 1156 } 1157 } else { 1158 irc_rootmsg(irc, "Can't open a groupchat with %s.", cmd[2]); 1159 } 1160 } else if (g_strcasecmp(cmd[1], "list") == 0 || 1161 g_strcasecmp(cmd[1], "set") == 0 || 1162 g_strcasecmp(cmd[1], "del") == 0) { 1163 irc_rootmsg(irc, 1164 "Warning: The \002chat\002 command was mostly replaced with the \002channel\002 command."); 1165 cmd_channel(irc, cmd); 1166 } else { 1167 irc_rootmsg(irc, 1168 "Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "chat", 1169 cmd[1]); 1170 } 1171 } 1172 1173 static void cmd_group(irc_t *irc, char **cmd) 1295 1174 { 1296 1175 GSList *l; 1297 1176 int len; 1298 1299 len = strlen( cmd[1] ); 1300 if( g_strncasecmp( cmd[1], "list", len ) == 0 ) 1301 { 1177 1178 len = strlen(cmd[1]); 1179 if (g_strncasecmp(cmd[1], "list", len) == 0) { 1302 1180 int n = 0; 1303 1304 if ( strchr( irc->umode, 'b' ) )1305 irc_rootmsg( irc, "Group list:");1306 1307 for( l = irc->b->groups; l; l = l->next ) 1308 {1181 1182 if (strchr(irc->umode, 'b')) { 1183 irc_rootmsg(irc, "Group list:"); 1184 } 1185 1186 for (l = irc->b->groups; l; l = l->next) { 1309 1187 bee_group_t *bg = l->data; 1310 irc_rootmsg( irc, "%d. %s", n ++, bg->name ); 1311 } 1312 irc_rootmsg( irc, "End of group list" ); 1313 } 1314 else if( g_strncasecmp(cmd[1], "info", len ) == 0 ) 1315 { 1188 irc_rootmsg(irc, "%d. %s", n++, bg->name); 1189 } 1190 irc_rootmsg(irc, "End of group list"); 1191 } else if (g_strncasecmp(cmd[1], "info", len) == 0) { 1316 1192 bee_group_t *bg; 1317 1193 int n = 0; 1318 1194 1319 1195 MIN_ARGS(2); 1320 bg = bee_group_by_name( irc->b, cmd[2], FALSE ); 1321 1322 if( bg ) 1323 { 1324 if( strchr(irc->umode, 'b') ) 1325 irc_rootmsg( irc, "Members of %s:", cmd[2] ); 1326 for( l = irc->b->users; l; l = l->next ) 1327 { 1196 bg = bee_group_by_name(irc->b, cmd[2], FALSE); 1197 1198 if (bg) { 1199 if (strchr(irc->umode, 'b')) { 1200 irc_rootmsg(irc, "Members of %s:", cmd[2]); 1201 } 1202 for (l = irc->b->users; l; l = l->next) { 1328 1203 bee_user_t *bu = l->data; 1329 if( bu->group == bg ) 1330 irc_rootmsg( irc, "%d. %s", n ++, bu->nick ? : bu->handle ); 1331 } 1332 irc_rootmsg( irc, "End of member list" ); 1333 } 1334 else 1335 irc_rootmsg( irc, "Unknown group: %s. Please use \x02group list\x02 to get a list of available groups.", cmd[2] ); 1336 } 1337 else 1338 { 1339 irc_rootmsg( irc, "Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "group", cmd[1] ); 1340 } 1341 } 1342 1343 static void cmd_transfer( irc_t *irc, char **cmd ) 1204 if (bu->group == bg) { 1205 irc_rootmsg(irc, "%d. %s", n++, bu->nick ? : bu->handle); 1206 } 1207 } 1208 irc_rootmsg(irc, "End of member list"); 1209 } else { 1210 irc_rootmsg(irc, 1211 "Unknown group: %s. Please use \x02group list\x02 to get a list of available groups.", 1212 cmd[2]); 1213 } 1214 } else { 1215 irc_rootmsg(irc, 1216 "Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "group", 1217 cmd[1]); 1218 } 1219 } 1220 1221 static void cmd_transfer(irc_t *irc, char **cmd) 1344 1222 { 1345 1223 GSList *files = irc->file_transfers; 1224 1346 1225 enum { LIST, REJECT, CANCEL }; 1347 1226 int subcmd = LIST; 1348 1227 int fid; 1349 1228 1350 if( !files ) 1351 { 1352 irc_rootmsg( irc, "No pending transfers" ); 1353 return; 1354 } 1355 1356 if( cmd[1] && ( strcmp( cmd[1], "reject" ) == 0 ) ) 1357 { 1229 if (!files) { 1230 irc_rootmsg(irc, "No pending transfers"); 1231 return; 1232 } 1233 1234 if (cmd[1] && (strcmp(cmd[1], "reject") == 0)) { 1358 1235 subcmd = REJECT; 1359 } 1360 else if( cmd[1] && ( strcmp( cmd[1], "cancel" ) == 0 ) && 1361 cmd[2] && ( sscanf( cmd[2], "%d", &fid ) == 1 ) ) 1362 { 1236 } else if (cmd[1] && (strcmp(cmd[1], "cancel") == 0) && 1237 cmd[2] && (sscanf(cmd[2], "%d", &fid) == 1)) { 1363 1238 subcmd = CANCEL; 1364 1239 } 1365 1240 1366 for( ; files; files = g_slist_next( files ) ) 1367 { 1241 for (; files; files = g_slist_next(files)) { 1368 1242 file_transfer_t *file = files->data; 1369 1370 switch ( subcmd) {1243 1244 switch (subcmd) { 1371 1245 case LIST: 1372 if ( file->status == FT_STATUS_LISTENING ) 1373 irc_rootmsg( irc, 1374 "Pending file(id %d): %s (Listening...)", file->local_id, file->file_name); 1375 else 1376 { 1246 if (file->status == FT_STATUS_LISTENING) { 1247 irc_rootmsg(irc, 1248 "Pending file(id %d): %s (Listening...)", file->local_id, file->file_name); 1249 } else { 1377 1250 int kb_per_s = 0; 1378 time_t diff = time( NULL) - file->started ? : 1;1379 if ( ( file->started > 0 ) && ( file->bytes_transferred > 0 ) )1251 time_t diff = time(NULL) - file->started ? : 1; 1252 if ((file->started > 0) && (file->bytes_transferred > 0)) { 1380 1253 kb_per_s = file->bytes_transferred / 1024 / diff; 1381 1382 irc_rootmsg( irc, 1383 "Pending file(id %d): %s (%10zd/%zd kb, %d kb/s)", file->local_id, file->file_name, 1384 file->bytes_transferred/1024, file->file_size/1024, kb_per_s); 1254 } 1255 1256 irc_rootmsg(irc, 1257 "Pending file(id %d): %s (%10zd/%zd kb, %d kb/s)", file->local_id, 1258 file->file_name, 1259 file->bytes_transferred / 1024, file->file_size / 1024, kb_per_s); 1385 1260 } 1386 1261 break; 1387 1262 case REJECT: 1388 if( file->status == FT_STATUS_LISTENING ) 1389 { 1390 irc_rootmsg( irc, "Rejecting file transfer for %s", file->file_name ); 1391 imcb_file_canceled( file->ic, file, "Denied by user" ); 1263 if (file->status == FT_STATUS_LISTENING) { 1264 irc_rootmsg(irc, "Rejecting file transfer for %s", file->file_name); 1265 imcb_file_canceled(file->ic, file, "Denied by user"); 1392 1266 } 1393 1267 break; 1394 1268 case CANCEL: 1395 if( file->local_id == fid ) 1396 { 1397 irc_rootmsg( irc, "Canceling file transfer for %s", file->file_name ); 1398 imcb_file_canceled( file->ic, file, "Canceled by user" ); 1269 if (file->local_id == fid) { 1270 irc_rootmsg(irc, "Canceling file transfer for %s", file->file_name); 1271 imcb_file_canceled(file->ic, file, "Canceled by user"); 1399 1272 } 1400 1273 break; … … 1403 1276 } 1404 1277 1405 static void cmd_nick( irc_t *irc, char **cmd)1406 { 1407 irc_rootmsg( irc, "This command is deprecated. Try: account %s set display_name", cmd[1]);1278 static void cmd_nick(irc_t *irc, char **cmd) 1279 { 1280 irc_rootmsg(irc, "This command is deprecated. Try: account %s set display_name", cmd[1]); 1408 1281 } 1409 1282 1410 1283 /* Maybe this should be a stand-alone command as well? */ 1411 static void bitlbee_whatsnew( irc_t *irc)1412 { 1413 int last = set_getint( &irc->b->set, "last_version");1284 static void bitlbee_whatsnew(irc_t *irc) 1285 { 1286 int last = set_getint(&irc->b->set, "last_version"); 1414 1287 char s[16], *msg; 1415 1416 if( last >= BITLBEE_VERSION_CODE ) 1417 return; 1418 1419 msg = help_get_whatsnew( &(global.help), last ); 1420 1421 if( msg ) 1422 irc_rootmsg( irc, "%s: This seems to be your first time using this " 1423 "this version of BitlBee. Here's a list of new " 1424 "features you may like to know about:\n\n%s\n", 1425 irc->user->nick, msg ); 1426 1427 g_free( msg ); 1428 1429 g_snprintf( s, sizeof( s ), "%d", BITLBEE_VERSION_CODE ); 1430 set_setstr( &irc->b->set, "last_version", s ); 1288 1289 if (last >= BITLBEE_VERSION_CODE) { 1290 return; 1291 } 1292 1293 msg = help_get_whatsnew(&(global.help), last); 1294 1295 if (msg) { 1296 irc_rootmsg(irc, "%s: This seems to be your first time using this " 1297 "this version of BitlBee. Here's a list of new " 1298 "features you may like to know about:\n\n%s\n", 1299 irc->user->nick, msg); 1300 } 1301 1302 g_free(msg); 1303 1304 g_snprintf(s, sizeof(s), "%d", BITLBEE_VERSION_CODE); 1305 set_setstr(&irc->b->set, "last_version", s); 1431 1306 } 1432 1307 … … 1443 1318 { "ft", 0, cmd_transfer, 0 }, 1444 1319 { "group", 1, cmd_group, 0 }, 1445 { "help", 0, cmd_help, 0 }, 1320 { "help", 0, cmd_help, 0 }, 1446 1321 { "identify", 0, cmd_identify, 0 }, 1447 1322 { "info", 1, cmd_info, 0 }, … … 1468 1343 { NULL }, 1469 1344 }; 1470 static const int num_root_commands = sizeof( root_commands ) / sizeof( command_t);1471 1472 gboolean root_command_add( const char *command, int params, void (*func)(irc_t *, char **args), int flags)1345 static const int num_root_commands = sizeof(root_commands) / sizeof(command_t); 1346 1347 gboolean root_command_add(const char *command, int params, void (*func)(irc_t *, char **args), int flags) 1473 1348 { 1474 1349 int i; 1475 1476 if ( root_commands[num_root_commands-2].command )1350 1351 if (root_commands[num_root_commands - 2].command) { 1477 1352 /* Planning fail! List is full. */ 1478 1353 return FALSE; 1479 1480 for( i = 0; root_commands[i].command; i++ ) 1481 {1482 if ( g_strcasecmp( root_commands[i].command, command ) == 0 )1354 } 1355 1356 for (i = 0; root_commands[i].command; i++) { 1357 if (g_strcasecmp(root_commands[i].command, command) == 0) { 1483 1358 return FALSE; 1484 else if( g_strcasecmp( root_commands[i].command, command ) > 0 )1359 } else if (g_strcasecmp(root_commands[i].command, command) > 0) { 1485 1360 break; 1486 } 1487 memmove( root_commands + i + 1, root_commands + i, 1488 sizeof( command_t ) * ( num_root_commands - i - 1 ) ); 1489 1490 root_commands[i].command = g_strdup( command ); 1361 } 1362 } 1363 memmove(root_commands + i + 1, root_commands + i, 1364 sizeof(command_t) * (num_root_commands - i - 1)); 1365 1366 root_commands[i].command = g_strdup(command); 1491 1367 root_commands[i].required_parameters = params; 1492 1368 root_commands[i].execute = func; 1493 1369 root_commands[i].flags = flags; 1494 1370 1495 1371 return TRUE; 1496 1372 }
Note: See TracChangeset
for help on using the changeset viewer.