From 7125cb3775a0e384c0f2fc08fd56df9582199502 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 24 Aug 2008 19:01:05 +0100 Subject: Added SET_INVALID, which set evaluators should now return instead of NULL when the given value is not accepted. This to allow certain variables actually be set to NULL (server, for example). This should fully close #444. --- root_commands.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'root_commands.c') diff --git a/root_commands.c b/root_commands.c index f55c4b5e..56a405a3 100644 --- a/root_commands.c +++ b/root_commands.c @@ -609,6 +609,8 @@ static void cmd_rename( irc_t *irc, char **cmd ) g_free( irc->mynick ); irc->mynick = g_strdup( cmd[2] ); + /* If we're called internally (user did "set root_nick"), + let's not go O(INF). :-) */ if( strcmp( cmd[0], "set_rename" ) != 0 ) set_setstr( &irc->set, "root_nick", cmd[2] ); } @@ -632,7 +634,7 @@ char *set_eval_root_nick( set_t *set, char *new_nick ) cmd_rename( irc, cmd ); } - return strcmp( irc->mynick, new_nick ) == 0 ? new_nick : NULL; + return strcmp( irc->mynick, new_nick ) == 0 ? new_nick : SET_INVALID; } static void cmd_remove( irc_t *irc, char **cmd ) -- cgit v1.2.3 From f3579fd061746fe88c53330a2b9002da4193b37a Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 24 Aug 2008 21:52:31 +0100 Subject: Clearer feedback after set/account set commands. --- root_commands.c | 75 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 24 deletions(-) (limited to 'root_commands.c') diff --git a/root_commands.c b/root_commands.c index 56a405a3..7e84ddf6 100644 --- a/root_commands.c +++ b/root_commands.c @@ -237,6 +237,16 @@ void cmd_account_del_no( void *data ) g_free( data ); } +static void cmd_showset( irc_t *irc, set_t *set ) +{ + char *s; + + if( set && ( s = set_getstr( &set, set->key ) ) ) /* HACK! */ + irc_usermsg( irc, "%s = `%s'", set->key, s ); + else + irc_usermsg( irc, "%s is empty", set->key ); +} + static void cmd_account( irc_t *irc, char **cmd ) { account_t *a; @@ -444,6 +454,7 @@ static void cmd_account( irc_t *irc, char **cmd ) if( cmd[3] && set_name ) { set_t *s = set_find( &a->set, set_name ); + int st; if( a->ic && s && s->flags & ACC_SET_OFFLINE_ONLY ) { @@ -459,27 +470,32 @@ static void cmd_account( irc_t *irc, char **cmd ) } if( g_strncasecmp( cmd[2], "-del", 4 ) == 0 ) - set_reset( &a->set, set_name ); + st = set_reset( &a->set, set_name ); else - set_setstr( &a->set, set_name, cmd[3] ); + st = set_setstr( &a->set, set_name, cmd[3] ); + + if( set_getstr( &a->set, set_name ) == NULL ) + { + if( st ) + irc_usermsg( irc, "Setting changed successfully" ); + else + irc_usermsg( irc, "Failed to change setting" ); + } + else + { + cmd_showset( irc, set_find( &a->set, set_name ) ); + } } - if( set_name ) /* else 'forgotten' on purpose.. Must show new value after changing */ + else if( set_name ) { - char *s = set_getstr( &a->set, set_name ); - if( s ) - irc_usermsg( irc, "%s = `%s'", set_name, s ); - else - irc_usermsg( irc, "%s is empty", set_name ); + cmd_showset( irc, set_find( &a->set, set_name ) ); } else { set_t *s = a->set; while( s ) { - if( s->value || s->def ) - irc_usermsg( irc, "%s = `%s'", s->key, s->value ? s->value : s->def ); - else - irc_usermsg( irc, "%s is empty", s->key ); + cmd_showset( irc, s ); s = s->next; } } @@ -822,23 +838,37 @@ static void cmd_set( irc_t *irc, char **cmd ) if( cmd[1] && cmd[2] ) { + int st; + if( g_strncasecmp( cmd[1], "-del", 4 ) == 0 ) { - set_reset( &irc->set, cmd[2] ); + st = set_reset( &irc->set, cmd[2] ); set_name = cmd[2]; } else { - set_setstr( &irc->set, cmd[1], cmd[2] ); + st = set_setstr( &irc->set, cmd[1], cmd[2] ); + } + + /* Normally we just show the variable's new/unchanged + value as feedback to the user, but this has always + caused confusion when changing the password. Give + other feedback instead: */ + if( set_getstr( &irc->set, set_name ) == NULL ) + { + if( st ) + irc_usermsg( irc, "Setting changed successfully" ); + else + irc_usermsg( irc, "Failed to change setting" ); + } + else + { + cmd_showset( irc, set_find( &irc->set, set_name ) ); } } - if( set_name ) /* else 'forgotten' on purpose.. Must show new value after changing */ + else if( set_name ) { - char *s = set_getstr( &irc->set, set_name ); - if( s ) - irc_usermsg( irc, "%s = `%s'", set_name, s ); - else - irc_usermsg( irc, "%s is empty", set_name ); + cmd_showset( irc, set_find( &irc->set, set_name ) ); if( strchr( set_name, '/' ) ) irc_usermsg( irc, "Warning: / found in setting name, you're probably looking for the `account set' command." ); @@ -848,10 +878,7 @@ static void cmd_set( irc_t *irc, char **cmd ) set_t *s = irc->set; while( s ) { - if( s->value || s->def ) - irc_usermsg( irc, "%s = `%s'", s->key, s->value ? s->value : s->def ); - else - irc_usermsg( irc, "%s is empty", s->key ); + cmd_showset( irc, s ); s = s->next; } } -- cgit v1.2.3 From f536a99f4541af0252dff3991ec608e3d3469117 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Mon, 25 Aug 2008 21:48:48 +0100 Subject: Fixed NULL pointer dereference on trying to read non-existent settings. --- root_commands.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'root_commands.c') diff --git a/root_commands.c b/root_commands.c index 7e84ddf6..88127acb 100644 --- a/root_commands.c +++ b/root_commands.c @@ -237,14 +237,14 @@ void cmd_account_del_no( void *data ) g_free( data ); } -static void cmd_showset( irc_t *irc, set_t *set ) +static void cmd_showset( irc_t *irc, set_t **head, char *key ) { - char *s; + char *val; - if( set && ( s = set_getstr( &set, set->key ) ) ) /* HACK! */ - irc_usermsg( irc, "%s = `%s'", set->key, s ); + if( ( val = set_getstr( head, key ) ) ) + irc_usermsg( irc, "%s = `%s'", key, val ); else - irc_usermsg( irc, "%s is empty", set->key ); + irc_usermsg( irc, "%s is empty", key ); } static void cmd_account( irc_t *irc, char **cmd ) @@ -483,19 +483,19 @@ static void cmd_account( irc_t *irc, char **cmd ) } else { - cmd_showset( irc, set_find( &a->set, set_name ) ); + cmd_showset( irc, &a->set, set_name ); } } else if( set_name ) { - cmd_showset( irc, set_find( &a->set, set_name ) ); + cmd_showset( irc, &a->set, set_name ); } else { set_t *s = a->set; while( s ) { - cmd_showset( irc, s ); + cmd_showset( irc, &s, s->key ); s = s->next; } } @@ -863,12 +863,12 @@ static void cmd_set( irc_t *irc, char **cmd ) } else { - cmd_showset( irc, set_find( &irc->set, set_name ) ); + cmd_showset( irc, &irc->set, set_name ); } } else if( set_name ) { - cmd_showset( irc, set_find( &irc->set, set_name ) ); + cmd_showset( irc, &irc->set, set_name ); if( strchr( set_name, '/' ) ) irc_usermsg( irc, "Warning: / found in setting name, you're probably looking for the `account set' command." ); @@ -878,7 +878,7 @@ static void cmd_set( irc_t *irc, char **cmd ) set_t *s = irc->set; while( s ) { - cmd_showset( irc, s ); + cmd_showset( irc, &s, s->key ); s = s->next; } } -- cgit v1.2.3 From a9a7287a9698aa6038958da5074da1169d63ea9d Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 30 Aug 2008 23:04:29 +0100 Subject: Added "chat" command, deprecated join_chat. Stuff is still incomplete, have to figure out a sane way to implement "chat set". --- root_commands.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) (limited to 'root_commands.c') diff --git a/root_commands.c b/root_commands.c index 88127acb..4f45c6d9 100644 --- a/root_commands.c +++ b/root_commands.c @@ -267,7 +267,7 @@ static void cmd_account( irc_t *irc, char **cmd ) return; } - prpl = find_protocol(cmd[2]); + prpl = find_protocol( cmd[2] ); if( prpl == NULL ) { @@ -504,7 +504,7 @@ static void cmd_account( irc_t *irc, char **cmd ) } else { - irc_usermsg( irc, "Unknown command: account %s. Please use \x02help commands\x02 to get a list of available commands.", cmd[1] ); + irc_usermsg( irc, "Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "account", cmd[1] ); } } @@ -1002,6 +1002,58 @@ static void cmd_qlist( irc_t *irc, char **cmd ) static void cmd_join_chat( irc_t *irc, char **cmd ) { + irc_usermsg( irc, "This command is now obsolete. " + "Please try the `chat' command instead." ); +} + +static void cmd_chat( irc_t *irc, char **cmd ) +{ + account_t *acc; + struct chat *c; + + if( g_strcasecmp( cmd[1], "add" ) == 0 ) + { + if( !( cmd[2] && cmd[3] && cmd[4] ) ) + { + irc_usermsg( irc, "Not enough parameters given (need %d)", 4 ); + return; + } + + if( !( acc = account_get( irc, cmd[2] ) ) ) + { + irc_usermsg( irc, "Invalid account" ); + return; + } + + if( ( c = chat_add( irc, acc, cmd[3], cmd[4] ) ) ) + irc_usermsg( irc, "Chatroom added successfully." ); + else + irc_usermsg( irc, "Could not add chatroom." ); + } + else if( g_strcasecmp( cmd[1], "list" ) == 0 ) + { + int i = 0; + + if( strchr( irc->umode, 'b' ) ) + irc_usermsg( irc, "Chatroom list:" ); + + for( c = irc->chatrooms; c; c = c->next ) + { + irc_usermsg( irc, "%2d. %s(%s) %s, %s", i, c->acc->prpl->name, + c->acc->user, c->handle, c->channel ); + + i ++; + } + irc_usermsg( irc, "End of chatroom list" ); + } + else + { + irc_usermsg( irc, "Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "chat", cmd[1] ); + } + + + +#if 0 account_t *a; struct im_connection *ic; char *chat, *channel, *nick = NULL, *password = NULL; @@ -1070,6 +1122,7 @@ static void cmd_join_chat( irc_t *irc, char **cmd ) irc_usermsg( irc, "Tried to join chat, not sure if this was successful" ); g_free( channel ); } +#endif } const command_t commands[] = { @@ -1092,5 +1145,6 @@ const command_t commands[] = { { "nick", 1, cmd_nick, 0 }, { "qlist", 0, cmd_qlist, 0 }, { "join_chat", 2, cmd_join_chat, 0 }, + { "chat", 1, cmd_chat, 0 }, { NULL } }; -- cgit v1.2.3 From e7bc722f096562914f54da2e1f8a0f3614763c1d Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 31 Aug 2008 01:04:53 +0100 Subject: Integrated cmd_set() and the "account set" into one fully unreadable cmd_set_real() function and using this to get a proper "chat set" command. --- root_commands.c | 250 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 126 insertions(+), 124 deletions(-) (limited to 'root_commands.c') diff --git a/root_commands.c b/root_commands.c index 4f45c6d9..89fc4776 100644 --- a/root_commands.c +++ b/root_commands.c @@ -247,6 +247,116 @@ static void cmd_showset( irc_t *irc, set_t **head, char *key ) irc_usermsg( irc, "%s is empty", key ); } +typedef set_t** (*cmd_set_findhead)( irc_t*, char* ); + +static int cmd_set_real( irc_t *irc, char **cmd, cmd_set_findhead findhead ) +{ + char *set_full = NULL, *set_name = NULL, *tmp; + set_t **head; + + if( cmd[1] && g_strncasecmp( cmd[1], "-del", 4 ) == 0 ) + set_full = cmd[2]; + else + set_full = cmd[1]; + + if( findhead == NULL ) + { + set_name = set_full; + + head = &irc->set; + } + else + { + char *id; + + if( !set_full ) + { + /* FIXME: Broken # */ + irc_usermsg( irc, "Not enough parameters given (need %d)", 3 ); + return 0; + } + + if( ( tmp = strchr( set_full, '/' ) ) ) + { + id = g_strndup( set_full, ( tmp - set_full ) ); + set_name = tmp + 1; + } + else + { + id = g_strdup( set_full ); + } + + if( ( head = findhead( irc, id ) ) == NULL ) + { + g_free( id ); + irc_usermsg( irc, "Could not find setting." ); + return 0; + } + g_free( id ); + } + + if( cmd[1] && cmd[2] && set_name ) + { + set_t *s = set_find( head, set_name ); + int st; + + /* + if( a->ic && s && s->flags & ACC_SET_OFFLINE_ONLY ) + { + irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "off" ); + return 0; + } + else if( !a->ic && s && s->flags & ACC_SET_ONLINE_ONLY ) + { + irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "on" ); + return 0; + } + */ + + if( g_strncasecmp( cmd[1], "-del", 4 ) == 0 ) + st = set_reset( head, set_name ); + else + st = set_setstr( head, set_name, cmd[2] ); + + if( set_getstr( head, set_name ) == NULL ) + { + if( st ) + irc_usermsg( irc, "Setting changed successfully" ); + else + irc_usermsg( irc, "Failed to change setting" ); + } + else + { + cmd_showset( irc, head, set_name ); + } + } + else if( set_name ) + { + cmd_showset( irc, head, set_name ); + } + else + { + set_t *s = *head; + while( s ) + { + cmd_showset( irc, &s, s->key ); + s = s->next; + } + } + + return 1; +} + +static set_t **cmd_account_set_findhead( irc_t *irc, char *id ) +{ + account_t *a; + + if( ( a = account_get( irc, id ) ) ) + return &a->set; + else + return NULL; +} + static void cmd_account( irc_t *irc, char **cmd ) { account_t *a; @@ -419,88 +529,13 @@ static void cmd_account( irc_t *irc, char **cmd ) } else if( g_strcasecmp( cmd[1], "set" ) == 0 ) { - char *acc_handle, *set_name = NULL, *tmp; - if( !cmd[2] ) { irc_usermsg( irc, "Not enough parameters given (need %d)", 2 ); return; } - if( g_strncasecmp( cmd[2], "-del", 4 ) == 0 ) - acc_handle = g_strdup( cmd[3] ); - else - acc_handle = g_strdup( cmd[2] ); - - if( !acc_handle ) - { - irc_usermsg( irc, "Not enough parameters given (need %d)", 3 ); - return; - } - - if( ( tmp = strchr( acc_handle, '/' ) ) ) - { - *tmp = 0; - set_name = tmp + 1; - } - - if( ( a = account_get( irc, acc_handle ) ) == NULL ) - { - g_free( acc_handle ); - irc_usermsg( irc, "Invalid account" ); - return; - } - - if( cmd[3] && set_name ) - { - set_t *s = set_find( &a->set, set_name ); - int st; - - if( a->ic && s && s->flags & ACC_SET_OFFLINE_ONLY ) - { - g_free( acc_handle ); - irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "off" ); - return; - } - else if( !a->ic && s && s->flags & ACC_SET_ONLINE_ONLY ) - { - g_free( acc_handle ); - irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "on" ); - return; - } - - if( g_strncasecmp( cmd[2], "-del", 4 ) == 0 ) - st = set_reset( &a->set, set_name ); - else - st = set_setstr( &a->set, set_name, cmd[3] ); - - if( set_getstr( &a->set, set_name ) == NULL ) - { - if( st ) - irc_usermsg( irc, "Setting changed successfully" ); - else - irc_usermsg( irc, "Failed to change setting" ); - } - else - { - cmd_showset( irc, &a->set, set_name ); - } - } - else if( set_name ) - { - cmd_showset( irc, &a->set, set_name ); - } - else - { - set_t *s = a->set; - while( s ) - { - cmd_showset( irc, &s, s->key ); - s = s->next; - } - } - - g_free( acc_handle ); + cmd_set_real( irc, cmd + 1, cmd_account_set_findhead ); } else { @@ -834,54 +869,7 @@ static void cmd_yesno( irc_t *irc, char **cmd ) static void cmd_set( irc_t *irc, char **cmd ) { - char *set_name = cmd[1]; - - if( cmd[1] && cmd[2] ) - { - int st; - - if( g_strncasecmp( cmd[1], "-del", 4 ) == 0 ) - { - st = set_reset( &irc->set, cmd[2] ); - set_name = cmd[2]; - } - else - { - st = set_setstr( &irc->set, cmd[1], cmd[2] ); - } - - /* Normally we just show the variable's new/unchanged - value as feedback to the user, but this has always - caused confusion when changing the password. Give - other feedback instead: */ - if( set_getstr( &irc->set, set_name ) == NULL ) - { - if( st ) - irc_usermsg( irc, "Setting changed successfully" ); - else - irc_usermsg( irc, "Failed to change setting" ); - } - else - { - cmd_showset( irc, &irc->set, set_name ); - } - } - else if( set_name ) - { - cmd_showset( irc, &irc->set, set_name ); - - if( strchr( set_name, '/' ) ) - irc_usermsg( irc, "Warning: / found in setting name, you're probably looking for the `account set' command." ); - } - else - { - set_t *s = irc->set; - while( s ) - { - cmd_showset( irc, &s, s->key ); - s = s->next; - } - } + cmd_set_real( irc, cmd, NULL ); } static void cmd_save( irc_t *irc, char **cmd ) @@ -1006,6 +994,16 @@ static void cmd_join_chat( irc_t *irc, char **cmd ) "Please try the `chat' command instead." ); } +static set_t **cmd_chat_set_findhead( irc_t *irc, char *id ) +{ + struct chat *c; + + if( ( c = chat_get( irc, id ) ) ) + return &c->set; + else + return NULL; +} + static void cmd_chat( irc_t *irc, char **cmd ) { account_t *acc; @@ -1046,6 +1044,10 @@ static void cmd_chat( irc_t *irc, char **cmd ) } irc_usermsg( irc, "End of chatroom list" ); } + else if( g_strcasecmp( cmd[1], "set" ) == 0 ) + { + cmd_set_real( irc, cmd + 1, cmd_chat_set_findhead ); + } else { irc_usermsg( irc, "Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "chat", cmd[1] ); -- cgit v1.2.3 From 0e639f5e5245aa807764162b7f1928b641947658 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 31 Aug 2008 10:13:56 +0100 Subject: Added one TODO, and also dupe-check channel names against the control channel. --- root_commands.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'root_commands.c') diff --git a/root_commands.c b/root_commands.c index 89fc4776..83620173 100644 --- a/root_commands.c +++ b/root_commands.c @@ -301,6 +301,8 @@ static int cmd_set_real( irc_t *irc, char **cmd, cmd_set_findhead findhead ) int st; /* + FIXME: Make these work again. Probably a gross hack. + if( a->ic && s && s->flags & ACC_SET_OFFLINE_ONLY ) { irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "off" ); -- cgit v1.2.3 From 39f93f0ce1c0a179b51f5ff6474d57509e9e0d17 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 31 Aug 2008 14:42:33 +0100 Subject: /join can now be used to join chatrooms, join_chat should not be used anymore. /join should not be used for unnamed groupchats anymore, use "chat with" instead. --- root_commands.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'root_commands.c') diff --git a/root_commands.c b/root_commands.c index 83620173..97cadffe 100644 --- a/root_commands.c +++ b/root_commands.c @@ -1050,6 +1050,29 @@ static void cmd_chat( irc_t *irc, char **cmd ) { cmd_set_real( irc, cmd + 1, cmd_chat_set_findhead ); } + else if( g_strcasecmp( cmd[1], "with" ) == 0 ) + { + user_t *u; + + if( !cmd[2] ) + { + irc_usermsg( irc, "Not enough parameters given (need %d)", 2 ); + return; + } + + if( ( u = user_find( irc, cmd[2] ) ) && u->ic && u->ic->acc->prpl->chat_with ) + { + if( !u->ic->acc->prpl->chat_with( u->ic, u->handle ) ) + { + irc_usermsg( irc, "(Possible) failure while trying to open " + "a groupchat with %s.", u->nick ); + } + } + else + { + irc_usermsg( irc, "Can't open a groupchat with %s.", cmd[2] ); + } + } else { irc_usermsg( irc, "Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "chat", cmd[1] ); @@ -1083,7 +1106,7 @@ static void cmd_chat( irc_t *irc, char **cmd ) chat = cmd[2]; if( cmd[3] ) { - if( cmd[3][0] != '#' && cmd[3][0] != '&' ) + if( strchr( CTYPES, cmd[3][0] ) == NULL ) channel = g_strdup_printf( "&%s", cmd[3] ); else channel = g_strdup( cmd[3] ); -- cgit v1.2.3 From d995c9b5de1bff5e3eb5de47b7ffbd3e92e2ac3d Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 31 Aug 2008 15:54:39 +0100 Subject: Added cleanup code. --- root_commands.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'root_commands.c') diff --git a/root_commands.c b/root_commands.c index 97cadffe..5b709b0e 100644 --- a/root_commands.c +++ b/root_commands.c @@ -1050,6 +1050,23 @@ static void cmd_chat( irc_t *irc, char **cmd ) { cmd_set_real( irc, cmd + 1, cmd_chat_set_findhead ); } + else if( g_strcasecmp( cmd[1], "del" ) == 0 ) + { + if( !cmd[2] ) + { + irc_usermsg( irc, "Not enough parameters given (need %d)", 2 ); + return; + } + + if( ( c = chat_get( irc, cmd[2] ) ) ) + { + chat_del( irc, c ); + } + else + { + irc_usermsg( irc, "Could not remove chat." ); + } + } else if( g_strcasecmp( cmd[1], "with" ) == 0 ) { user_t *u; -- cgit v1.2.3 From 3b99524d537183f74f34be8fef4e02324707f34e Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 31 Aug 2008 16:41:51 +0100 Subject: Added a MIN_ARGS() macro instead of stupidly copy-pasting the same if-statement ten times. --- root_commands.c | 66 +++++++++++++++++++++------------------------------------ 1 file changed, 24 insertions(+), 42 deletions(-) (limited to 'root_commands.c') diff --git a/root_commands.c b/root_commands.c index 5b709b0e..b6ae5c7a 100644 --- a/root_commands.c +++ b/root_commands.c @@ -77,6 +77,18 @@ void root_command_string( irc_t *irc, user_t *u, char *command, int flags ) root_command( irc, cmd ); } +#define MIN_ARGS( x, y... ) \ + do \ + { \ + int i; \ + for( i = 1; i <= x; i ++ ) \ + if( cmd[i] == NULL ) \ + { \ + irc_usermsg( irc, "Not enough parameters given (need %d).", x ); \ + return y; \ + } \ + } while( 0 ) + void root_command( irc_t *irc, char *cmd[] ) { int i; @@ -87,11 +99,8 @@ void root_command( irc_t *irc, char *cmd[] ) for( i = 0; commands[i].command; i++ ) if( g_strcasecmp( commands[i].command, cmd[0] ) == 0 ) { - if( !cmd[commands[i].required_parameters] ) - { - irc_usermsg( irc, "Not enough parameters given (need %d)", commands[i].required_parameters ); - return; - } + MIN_ARGS( commands[i].required_parameters ); + commands[i].execute( irc, cmd ); return; } @@ -269,12 +278,7 @@ static int cmd_set_real( irc_t *irc, char **cmd, cmd_set_findhead findhead ) { char *id; - if( !set_full ) - { - /* FIXME: Broken # */ - irc_usermsg( irc, "Not enough parameters given (need %d)", 3 ); - return 0; - } + MIN_ARGS( 3, 0 ); if( ( tmp = strchr( set_full, '/' ) ) ) { @@ -373,11 +377,7 @@ static void cmd_account( irc_t *irc, char **cmd ) { struct prpl *prpl; - if( cmd[2] == NULL || cmd[3] == NULL || cmd[4] == NULL ) - { - irc_usermsg( irc, "Not enough parameters" ); - return; - } + MIN_ARGS( 4 ); prpl = find_protocol( cmd[2] ); @@ -399,11 +399,9 @@ static void cmd_account( irc_t *irc, char **cmd ) } else if( g_strcasecmp( cmd[1], "del" ) == 0 ) { - if( !cmd[2] ) - { - irc_usermsg( irc, "Not enough parameters given (need %d)", 2 ); - } - else if( !( a = account_get( irc, cmd[2] ) ) ) + MIN_ARGS( 2 ); + + if( !( a = account_get( irc, cmd[2] ) ) ) { irc_usermsg( irc, "Invalid account" ); } @@ -531,11 +529,7 @@ static void cmd_account( irc_t *irc, char **cmd ) } else if( g_strcasecmp( cmd[1], "set" ) == 0 ) { - if( !cmd[2] ) - { - irc_usermsg( irc, "Not enough parameters given (need %d)", 2 ); - return; - } + MIN_ARGS( 2 ); cmd_set_real( irc, cmd + 1, cmd_account_set_findhead ); } @@ -1013,11 +1007,7 @@ static void cmd_chat( irc_t *irc, char **cmd ) if( g_strcasecmp( cmd[1], "add" ) == 0 ) { - if( !( cmd[2] && cmd[3] && cmd[4] ) ) - { - irc_usermsg( irc, "Not enough parameters given (need %d)", 4 ); - return; - } + MIN_ARGS( 4 ); if( !( acc = account_get( irc, cmd[2] ) ) ) { @@ -1052,11 +1042,7 @@ static void cmd_chat( irc_t *irc, char **cmd ) } else if( g_strcasecmp( cmd[1], "del" ) == 0 ) { - if( !cmd[2] ) - { - irc_usermsg( irc, "Not enough parameters given (need %d)", 2 ); - return; - } + MIN_ARGS( 2 ); if( ( c = chat_get( irc, cmd[2] ) ) ) { @@ -1070,12 +1056,8 @@ static void cmd_chat( irc_t *irc, char **cmd ) else if( g_strcasecmp( cmd[1], "with" ) == 0 ) { user_t *u; - - if( !cmd[2] ) - { - irc_usermsg( irc, "Not enough parameters given (need %d)", 2 ); - return; - } + + MIN_ARGS( 2 ); if( ( u = user_find( irc, cmd[2] ) ) && u->ic && u->ic->acc->prpl->chat_with ) { -- cgit v1.2.3 From 07054a511479f070a274b4c8a488cc79b79abe1f Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 31 Aug 2008 23:49:32 +0100 Subject: "chat add" can generate a channel name by itself if necessary. Also fixed MIN_ARGS, using a variable named i showed why precompiler macros really are evil. :-) --- root_commands.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) (limited to 'root_commands.c') diff --git a/root_commands.c b/root_commands.c index b6ae5c7a..f65bdc65 100644 --- a/root_commands.c +++ b/root_commands.c @@ -80,9 +80,9 @@ void root_command_string( irc_t *irc, user_t *u, char *command, int flags ) #define MIN_ARGS( x, y... ) \ do \ { \ - int i; \ - for( i = 1; i <= x; i ++ ) \ - if( cmd[i] == NULL ) \ + int blaat; \ + for( blaat = 0; blaat <= x; blaat ++ ) \ + if( cmd[blaat] == NULL ) \ { \ irc_usermsg( irc, "Not enough parameters given (need %d).", x ); \ return y; \ @@ -1007,7 +1007,9 @@ static void cmd_chat( irc_t *irc, char **cmd ) if( g_strcasecmp( cmd[1], "add" ) == 0 ) { - MIN_ARGS( 4 ); + char *channel, *s; + + MIN_ARGS( 3 ); if( !( acc = account_get( irc, cmd[2] ) ) ) { @@ -1015,10 +1017,30 @@ static void cmd_chat( irc_t *irc, char **cmd ) return; } - if( ( c = chat_add( irc, acc, cmd[3], cmd[4] ) ) ) + if( cmd[4] == NULL ) + { + channel = g_strdup( cmd[3] ); + if( ( s = strchr( channel, '@' ) ) ) + *s = 0; + } + else + { + channel = g_strdup( cmd[4] ); + } + + if( strchr( CTYPES, channel[0] ) == NULL ) + { + s = g_strdup_printf( "%c%s", CTYPES[0], channel ); + g_free( channel ); + channel = s; + } + + if( ( c = chat_add( irc, acc, cmd[3], channel ) ) ) irc_usermsg( irc, "Chatroom added successfully." ); else irc_usermsg( irc, "Could not add chatroom." ); + + g_free( channel ); } else if( g_strcasecmp( cmd[1], "list" ) == 0 ) { -- cgit v1.2.3 From d4810dff26f128061d122cf120e1e0174d9df1f2 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Tue, 2 Sep 2008 08:48:56 +0100 Subject: Fixed check for set -del arguments. --- root_commands.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'root_commands.c') diff --git a/root_commands.c b/root_commands.c index f65bdc65..67847650 100644 --- a/root_commands.c +++ b/root_commands.c @@ -264,7 +264,10 @@ static int cmd_set_real( irc_t *irc, char **cmd, cmd_set_findhead findhead ) set_t **head; if( cmd[1] && g_strncasecmp( cmd[1], "-del", 4 ) == 0 ) + { + MIN_ARGS( 2, 0 ); set_full = cmd[2]; + } else set_full = cmd[1]; @@ -278,8 +281,6 @@ static int cmd_set_real( irc_t *irc, char **cmd, cmd_set_findhead findhead ) { char *id; - MIN_ARGS( 3, 0 ); - if( ( tmp = strchr( set_full, '/' ) ) ) { id = g_strndup( set_full, ( tmp - set_full ) ); -- cgit v1.2.3 From 3183c21afa7700ebc4dac02367653d1398a5b14a Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 6 Sep 2008 23:59:32 +0100 Subject: Completely reviewed all uses of irc->password, irc_setpass() and USTATUS_IDENTIFIED after another account overwriting vulnerability was found by Tero Marttila. --- root_commands.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'root_commands.c') diff --git a/root_commands.c b/root_commands.c index 88127acb..57d5c91a 100644 --- a/root_commands.c +++ b/root_commands.c @@ -130,7 +130,7 @@ static void cmd_account( irc_t *irc, char **cmd ); static void cmd_identify( irc_t *irc, char **cmd ) { - storage_status_t status = storage_load( irc->nick, cmd[1], irc ); + storage_status_t status = storage_load( irc, cmd[1] ); char *account_on[] = { "account", "on", NULL }; switch (status) { @@ -142,6 +142,8 @@ static void cmd_identify( irc_t *irc, char **cmd ) break; case STORAGE_OK: irc_usermsg( irc, "Password accepted, settings and accounts loaded" ); + irc_setpass( irc, cmd[1] ); + irc->status |= USTATUS_IDENTIFIED; irc_umode_set( irc, "+R", 1 ); if( set_getbool( &irc->set, "auto_connect" ) ) cmd_account( irc, account_on ); @@ -161,14 +163,14 @@ static void cmd_register( irc_t *irc, char **cmd ) return; } - irc_setpass( irc, cmd[1] ); - switch( storage_save( irc, FALSE )) { + switch( storage_save( irc, cmd[1], FALSE ) ) { case STORAGE_ALREADY_EXISTS: irc_usermsg( irc, "Nick is already registered" ); break; case STORAGE_OK: irc_usermsg( irc, "Account successfully created" ); + irc_setpass( irc, cmd[1] ); irc->status |= USTATUS_IDENTIFIED; irc_umode_set( irc, "+R", 1 ); break; @@ -886,7 +888,9 @@ static void cmd_set( irc_t *irc, char **cmd ) static void cmd_save( irc_t *irc, char **cmd ) { - if( storage_save( irc, TRUE ) == STORAGE_OK ) + if( ( irc->status & USTATUS_IDENTIFIED ) == 0 ) + irc_usermsg( irc, "Please create an account first" ); + else if( storage_save( irc, NULL, TRUE ) == STORAGE_OK ) irc_usermsg( irc, "Configuration saved" ); else irc_usermsg( irc, "Configuration could not be saved!" ); -- cgit v1.2.3 From c05eb5b4711774c4274adafdf21558c3ea0492e4 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Mon, 29 Sep 2008 22:53:05 +0100 Subject: Checking account setting's flags again before changing them. --- root_commands.c | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) (limited to 'root_commands.c') diff --git a/root_commands.c b/root_commands.c index 8770e707..68561a17 100644 --- a/root_commands.c +++ b/root_commands.c @@ -259,8 +259,9 @@ static void cmd_showset( irc_t *irc, set_t **head, char *key ) } typedef set_t** (*cmd_set_findhead)( irc_t*, char* ); +typedef int (*cmd_set_checkflags)( irc_t*, set_t *set ); -static int cmd_set_real( irc_t *irc, char **cmd, cmd_set_findhead findhead ) +static int cmd_set_real( irc_t *irc, char **cmd, cmd_set_findhead findhead, cmd_set_checkflags checkflags ) { char *set_full = NULL, *set_name = NULL, *tmp; set_t **head; @@ -307,20 +308,8 @@ static int cmd_set_real( irc_t *irc, char **cmd, cmd_set_findhead findhead ) set_t *s = set_find( head, set_name ); int st; - /* - FIXME: Make these work again. Probably a gross hack. - - if( a->ic && s && s->flags & ACC_SET_OFFLINE_ONLY ) - { - irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "off" ); - return 0; - } - else if( !a->ic && s && s->flags & ACC_SET_ONLINE_ONLY ) - { - irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "on" ); + if( checkflags && checkflags( irc, s ) == 0 ) return 0; - } - */ if( g_strncasecmp( cmd[1], "-del", 4 ) == 0 ) st = set_reset( head, set_name ); @@ -366,6 +355,24 @@ static set_t **cmd_account_set_findhead( irc_t *irc, char *id ) return NULL; } +static int cmd_account_set_checkflags( irc_t *irc, set_t *s ) +{ + account_t *a = s->data; + + if( a->ic && s && s->flags & ACC_SET_OFFLINE_ONLY ) + { + irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "off" ); + return 0; + } + else if( !a->ic && s && s->flags & ACC_SET_ONLINE_ONLY ) + { + irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "on" ); + return 0; + } + + return 1; +} + static void cmd_account( irc_t *irc, char **cmd ) { account_t *a; @@ -534,7 +541,7 @@ static void cmd_account( irc_t *irc, char **cmd ) { MIN_ARGS( 2 ); - cmd_set_real( irc, cmd + 1, cmd_account_set_findhead ); + cmd_set_real( irc, cmd + 1, cmd_account_set_findhead, cmd_account_set_checkflags ); } else { @@ -868,7 +875,7 @@ static void cmd_yesno( irc_t *irc, char **cmd ) static void cmd_set( irc_t *irc, char **cmd ) { - cmd_set_real( irc, cmd, NULL ); + cmd_set_real( irc, cmd, NULL, NULL ); } static void cmd_save( irc_t *irc, char **cmd ) @@ -1065,7 +1072,7 @@ static void cmd_chat( irc_t *irc, char **cmd ) } else if( g_strcasecmp( cmd[1], "set" ) == 0 ) { - cmd_set_real( irc, cmd + 1, cmd_chat_set_findhead ); + cmd_set_real( irc, cmd + 1, cmd_chat_set_findhead, NULL ); } else if( g_strcasecmp( cmd[1], "del" ) == 0 ) { -- cgit v1.2.3 From 77fc000cf5248e3c82d21ee20c02db25191d0f0f Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 13 Dec 2008 19:46:56 +0000 Subject: Added argument count check to "add -tmp" to prevent NULL dereference. --- root_commands.c | 1 + 1 file changed, 1 insertion(+) (limited to 'root_commands.c') diff --git a/root_commands.c b/root_commands.c index 68561a17..d90531eb 100644 --- a/root_commands.c +++ b/root_commands.c @@ -556,6 +556,7 @@ static void cmd_add( irc_t *irc, char **cmd ) if( g_strcasecmp( cmd[1], "-tmp" ) == 0 ) { + MIN_ARGS( 3 ); add_on_server = 0; cmd ++; } -- cgit v1.2.3