source: root_commands.c @ a81d679

Last change on this file since a81d679 was b8a491d, checked in by Wilmer van der Gaast <wilmer@…>, at 2010-03-18T00:30:38Z

Some compiler warning fixes and renamed "transfers" command to just
"transfer" since all root commands are singular so far.

  • Property mode set to 100644
File size: 27.6 KB
RevLine 
[b7d3cc34]1  /********************************************************************\
2  * BitlBee -- An IRC to other IM-networks gateway                     *
3  *                                                                    *
4  * Copyright 2002-2004 Wilmer van der Gaast and others                *
5  \********************************************************************/
6
7/* User manager (root) commands                                         */
8
9/*
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2 of the License, or
13  (at your option) any later version.
14
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU General Public License for more details.
19
20  You should have received a copy of the GNU General Public License with
21  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
22  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
23  Suite 330, Boston, MA  02111-1307  USA
24*/
25
26#define BITLBEE_CORE
27#include "commands.h"
28#include "crypting.h"
29#include "bitlbee.h"
30#include "help.h"
[b75acf6]31#include "chat.h"
[b7d3cc34]32
33#include <string.h>
34
[f73b969]35void root_command_string( irc_t *irc, user_t *u, char *command, int flags )
[7e563ed]36{
37        char *cmd[IRC_MAX_ARGS];
38        char *s;
39        int k;
40        char q = 0;
41       
42        memset( cmd, 0, sizeof( cmd ) );
43        cmd[0] = command;
44        k = 1;
45        for( s = command; *s && k < ( IRC_MAX_ARGS - 1 ); s ++ )
46                if( *s == ' ' && !q )
47                {
48                        *s = 0;
49                        while( *++s == ' ' );
50                        if( *s == '"' || *s == '\'' )
51                        {
52                                q = *s;
53                                s ++;
54                        }
55                        if( *s )
56                        {
57                                cmd[k++] = s;
58                                s --;
59                        }
[619a681]60                        else
61                        {
62                                break;
63                        }
[7e563ed]64                }
[79c6f9f]65                else if( *s == '\\' && ( ( !q && s[1] ) || ( q && q == s[1] ) ) )
66                {
67                        char *cpy;
68                       
69                        for( cpy = s; *cpy; cpy ++ )
70                                cpy[0] = cpy[1];
71                }
[7e563ed]72                else if( *s == q )
73                {
74                        q = *s = 0;
75                }
76        cmd[k] = NULL;
77       
[f73b969]78        root_command( irc, cmd );
[7e563ed]79}
80
[3b99524]81#define MIN_ARGS( x, y... )                                                    \
82        do                                                                     \
83        {                                                                      \
[07054a5]84                int blaat;                                                     \
85                for( blaat = 0; blaat <= x; blaat ++ )                         \
86                        if( cmd[blaat] == NULL )                               \
[3b99524]87                        {                                                      \
88                                irc_usermsg( irc, "Not enough parameters given (need %d).", x ); \
89                                return y;                                      \
90                        }                                                      \
91        } while( 0 )
92
[f73b969]93void root_command( irc_t *irc, char *cmd[] )
[7e563ed]94{       
95        int i;
96       
97        if( !cmd[0] )
[f73b969]98                return;
[7e563ed]99       
100        for( i = 0; commands[i].command; i++ )
101                if( g_strcasecmp( commands[i].command, cmd[0] ) == 0 )
102                {
[3b99524]103                        MIN_ARGS( commands[i].required_parameters );
104                       
[7e563ed]105                        commands[i].execute( irc, cmd );
[f73b969]106                        return;
[7e563ed]107                }
108       
109        irc_usermsg( irc, "Unknown command: %s. Please use \x02help commands\x02 to get a list of available commands.", cmd[0] );
110}
111
[f73b969]112static void cmd_help( irc_t *irc, char **cmd )
[b7d3cc34]113{
114        char param[80];
115        int i;
116        char *s;
117       
118        memset( param, 0, sizeof(param) );
119        for ( i = 1; (cmd[i] != NULL && ( strlen(param) < (sizeof(param)-1) ) ); i++ ) {
120                if ( i != 1 )   // prepend space except for the first parameter
121                        strcat(param, " ");
122                strncat( param, cmd[i], sizeof(param) - strlen(param) - 1 );
123        }
124
125        s = help_get( &(global.help), param );
126        if( !s ) s = help_get( &(global.help), "" );
127       
128        if( s )
129        {
130                irc_usermsg( irc, "%s", s );
131                g_free( s );
132        }
133        else
134        {
135                irc_usermsg( irc, "Error opening helpfile." );
136        }
137}
138
[90bbb0e]139static void cmd_account( irc_t *irc, char **cmd );
140
[f73b969]141static void cmd_identify( irc_t *irc, char **cmd )
[b7d3cc34]142{
[3183c21]143        storage_status_t status = storage_load( irc, cmd[1] );
[90bbb0e]144        char *account_on[] = { "account", "on", NULL };
[b7d3cc34]145       
[e9cf291]146        if( strchr( irc->umode, 'R' ) != NULL )
147        {
148                irc_usermsg( irc, "You're already logged in." );
149                return;
150        }
151       
[09adf08]152        switch (status) {
153        case STORAGE_INVALID_PASSWORD:
[b7d3cc34]154                irc_usermsg( irc, "Incorrect password" );
[09adf08]155                break;
156        case STORAGE_NO_SUCH_USER:
[b7d3cc34]157                irc_usermsg( irc, "The nick is (probably) not registered" );
[09adf08]158                break;
159        case STORAGE_OK:
[6ee9d2d]160                irc_usermsg( irc, "Password accepted, settings and accounts loaded" );
[3183c21]161                irc_setpass( irc, cmd[1] );
162                irc->status |= USTATUS_IDENTIFIED;
[238f828]163                irc_umode_set( irc, "+R", 1 );
[d5ccd83]164                if( set_getbool( &irc->set, "auto_connect" ) )
[90bbb0e]165                        cmd_account( irc, account_on );
[09adf08]166                break;
[c121f89]167        case STORAGE_OTHER_ERROR:
[09adf08]168        default:
[c121f89]169                irc_usermsg( irc, "Unknown error while loading configuration" );
[09adf08]170                break;
[b7d3cc34]171        }
172}
173
[f73b969]174static void cmd_register( irc_t *irc, char **cmd )
[b7d3cc34]175{
176        if( global.conf->authmode == AUTHMODE_REGISTERED )
177        {
178                irc_usermsg( irc, "This server does not allow registering new accounts" );
[f73b969]179                return;
[b7d3cc34]180        }
[1ee6c18]181
[3183c21]182        switch( storage_save( irc, cmd[1], FALSE ) ) {
[a1f17d4]183                case STORAGE_ALREADY_EXISTS:
184                        irc_usermsg( irc, "Nick is already registered" );
185                        break;
186                       
187                case STORAGE_OK:
[0383943]188                        irc_usermsg( irc, "Account successfully created" );
[3183c21]189                        irc_setpass( irc, cmd[1] );
[79e826a]190                        irc->status |= USTATUS_IDENTIFIED;
[238f828]191                        irc_umode_set( irc, "+R", 1 );
[a1f17d4]192                        break;
193
194                default:
195                        irc_usermsg( irc, "Error registering" );
196                        break;
[b7d3cc34]197        }
198}
199
[f73b969]200static void cmd_drop( irc_t *irc, char **cmd )
[b7d3cc34]201{
[a1f17d4]202        storage_status_t status;
203       
[ab49fdc]204        status = storage_remove (irc->nick, cmd[1]);
[a1f17d4]205        switch (status) {
206        case STORAGE_NO_SUCH_USER:
[b7d3cc34]207                irc_usermsg( irc, "That account does not exist" );
[f73b969]208                break;
[a1f17d4]209        case STORAGE_INVALID_PASSWORD:
[1ee6c18]210                irc_usermsg( irc, "Password invalid" );
[f73b969]211                break;
[a1f17d4]212        case STORAGE_OK:
[7cad7b4]213                irc_setpass( irc, NULL );
[79e826a]214                irc->status &= ~USTATUS_IDENTIFIED;
[238f828]215                irc_umode_set( irc, "-R", 1 );
[a1f17d4]216                irc_usermsg( irc, "Account `%s' removed", irc->nick );
[f73b969]217                break;
[a1f17d4]218        default:
[eded1f7]219                irc_usermsg( irc, "Error: `%d'", status );
[f73b969]220                break;
[b7d3cc34]221        }
222}
223
[f35aee7]224struct cmd_account_del_data
[7f421d6]225{
[f35aee7]226        account_t *a;
227        irc_t *irc;
228};
229
230void cmd_account_del_yes( void *data )
231{
232        struct cmd_account_del_data *cad = data;
233        account_t *a;
[7f421d6]234       
[f35aee7]235        for( a = cad->irc->accounts; a && a != cad->a; a = a->next );
236       
237        if( a == NULL )
238        {
239                irc_usermsg( cad->irc, "Account already deleted" );
240        }
241        else if( a->ic )
[7f421d6]242        {
[f35aee7]243                irc_usermsg( cad->irc, "Account is still logged in, can't delete" );
[7f421d6]244        }
245        else
246        {
[f35aee7]247                account_del( cad->irc, a );
248                irc_usermsg( cad->irc, "Account deleted" );
[7f421d6]249        }
[f35aee7]250        g_free( data );
[7f421d6]251}
252
[f35aee7]253void cmd_account_del_no( void *data )
[7f421d6]254{
[8dbe021f]255        g_free( data );
[7f421d6]256}
257
[f536a99]258static void cmd_showset( irc_t *irc, set_t **head, char *key )
[f3579fd]259{
[f536a99]260        char *val;
[f3579fd]261       
[f536a99]262        if( ( val = set_getstr( head, key ) ) )
263                irc_usermsg( irc, "%s = `%s'", key, val );
[f3579fd]264        else
[f536a99]265                irc_usermsg( irc, "%s is empty", key );
[f3579fd]266}
267
[e7bc722]268typedef set_t** (*cmd_set_findhead)( irc_t*, char* );
[c05eb5b]269typedef int (*cmd_set_checkflags)( irc_t*, set_t *set );
[e7bc722]270
[c05eb5b]271static int cmd_set_real( irc_t *irc, char **cmd, cmd_set_findhead findhead, cmd_set_checkflags checkflags )
[e7bc722]272{
273        char *set_full = NULL, *set_name = NULL, *tmp;
274        set_t **head;
275       
276        if( cmd[1] && g_strncasecmp( cmd[1], "-del", 4 ) == 0 )
[d4810df]277        {
278                MIN_ARGS( 2, 0 );
[e7bc722]279                set_full = cmd[2];
[d4810df]280        }
[e7bc722]281        else
282                set_full = cmd[1];
283       
284        if( findhead == NULL )
285        {
286                set_name = set_full;
287               
288                head = &irc->set;
289        }
290        else 
291        {
292                char *id;
293               
294                if( ( tmp = strchr( set_full, '/' ) ) )
295                {
296                        id = g_strndup( set_full, ( tmp - set_full ) );
297                        set_name = tmp + 1;
298                }
299                else
300                {
301                        id = g_strdup( set_full );
302                }
303               
304                if( ( head = findhead( irc, id ) ) == NULL )
305                {
306                        g_free( id );
307                        irc_usermsg( irc, "Could not find setting." );
308                        return 0;
309                }
310                g_free( id );
311        }
312       
313        if( cmd[1] && cmd[2] && set_name )
314        {
315                set_t *s = set_find( head, set_name );
316                int st;
317               
[8a08d92]318                if( s && checkflags && checkflags( irc, s ) == 0 )
[e7bc722]319                        return 0;
320               
321                if( g_strncasecmp( cmd[1], "-del", 4 ) == 0 )
322                        st = set_reset( head, set_name );
323                else
324                        st = set_setstr( head, set_name, cmd[2] );
325               
326                if( set_getstr( head, set_name ) == NULL )
327                {
328                        if( st )
329                                irc_usermsg( irc, "Setting changed successfully" );
330                        else
331                                irc_usermsg( irc, "Failed to change setting" );
332                }
333                else
334                {
335                        cmd_showset( irc, head, set_name );
336                }
337        }
338        else if( set_name )
339        {
340                cmd_showset( irc, head, set_name );
341        }
342        else
343        {
344                set_t *s = *head;
345                while( s )
346                {
347                        cmd_showset( irc, &s, s->key );
348                        s = s->next;
349                }
350        }
351       
352        return 1;
353}
354
355static set_t **cmd_account_set_findhead( irc_t *irc, char *id )
356{
357        account_t *a;
358       
359        if( ( a = account_get( irc, id ) ) )
360                return &a->set;
361        else
362                return NULL;
363}
364
[c05eb5b]365static int cmd_account_set_checkflags( irc_t *irc, set_t *s )
366{
367        account_t *a = s->data;
368       
369        if( a->ic && s && s->flags & ACC_SET_OFFLINE_ONLY )
370        {
371                irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "off" );
372                return 0;
373        }
374        else if( !a->ic && s && s->flags & ACC_SET_ONLINE_ONLY )
375        {
376                irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "on" );
377                return 0;
378        }
379       
380        return 1;
381}
382
[f73b969]383static void cmd_account( irc_t *irc, char **cmd )
[b7d3cc34]384{
385        account_t *a;
386       
[3af70b0]387        if( global.conf->authmode == AUTHMODE_REGISTERED && !( irc->status & USTATUS_IDENTIFIED ) )
[b7d3cc34]388        {
389                irc_usermsg( irc, "This server only accepts registered users" );
[f73b969]390                return;
[b7d3cc34]391        }
392       
393        if( g_strcasecmp( cmd[1], "add" ) == 0 )
394        {
[7b23afd]395                struct prpl *prpl;
[b7d3cc34]396               
[3b99524]397                MIN_ARGS( 4 );
[b7d3cc34]398               
[a9a7287]399                prpl = find_protocol( cmd[2] );
[b7d3cc34]400               
[7b23afd]401                if( prpl == NULL )
[b7d3cc34]402                {
403                        irc_usermsg( irc, "Unknown protocol" );
[f73b969]404                        return;
[b7d3cc34]405                }
406
[7b23afd]407                a = account_add( irc, prpl, cmd[3], cmd[4] );
[b7d3cc34]408                if( cmd[5] )
[eded1f7]409                {
410                        irc_usermsg( irc, "Warning: Passing a servername/other flags to `account add' "
411                                          "is now deprecated. Use `account set' instead." );
[5100caa]412                        set_setstr( &a->set, "server", cmd[5] );
[eded1f7]413                }
[b7d3cc34]414               
415                irc_usermsg( irc, "Account successfully added" );
416        }
417        else if( g_strcasecmp( cmd[1], "del" ) == 0 )
418        {
[3b99524]419                MIN_ARGS( 2 );
420
421                if( !( a = account_get( irc, cmd[2] ) ) )
[b7d3cc34]422                {
423                        irc_usermsg( irc, "Invalid account" );
424                }
[0da65d5]425                else if( a->ic )
[b7d3cc34]426                {
427                        irc_usermsg( irc, "Account is still logged in, can't delete" );
428                }
429                else
430                {
[f35aee7]431                        struct cmd_account_del_data *cad;
[7f421d6]432                        char *msg;
433                       
[f35aee7]434                        cad = g_malloc( sizeof( struct cmd_account_del_data ) );
435                        cad->a = a;
436                        cad->irc = irc;
[8dbe021f]437                       
[7f421d6]438                        msg = g_strdup_printf( "If you remove this account (%s(%s)), BitlBee will "
439                                               "also forget all your saved nicknames. If you want "
440                                               "to change your username/password, use the `account "
441                                               "set' command. Are you sure you want to delete this "
442                                               "account?", a->prpl->name, a->user );
[f35aee7]443                        query_add( irc, NULL, msg, cmd_account_del_yes, cmd_account_del_no, cad );
[7f421d6]444                        g_free( msg );
[b7d3cc34]445                }
446        }
447        else if( g_strcasecmp( cmd[1], "list" ) == 0 )
448        {
449                int i = 0;
450               
[e6e1f18]451                if( strchr( irc->umode, 'b' ) )
452                        irc_usermsg( irc, "Account list:" );
453               
[b7d3cc34]454                for( a = irc->accounts; a; a = a->next )
455                {
456                        char *con;
457                       
[0da65d5]458                        if( a->ic && ( a->ic->flags & OPT_LOGGED_IN ) )
[b7d3cc34]459                                con = " (connected)";
[0da65d5]460                        else if( a->ic )
[b7d3cc34]461                                con = " (connecting)";
462                        else if( a->reconnect )
463                                con = " (awaiting reconnect)";
464                        else
465                                con = "";
466                       
[7b23afd]467                        irc_usermsg( irc, "%2d. %s, %s%s", i, a->prpl->name, a->user, con );
[b7d3cc34]468                       
469                        i ++;
470                }
471                irc_usermsg( irc, "End of account list" );
472        }
473        else if( g_strcasecmp( cmd[1], "on" ) == 0 )
474        {
475                if( cmd[2] )
476                {
477                        if( ( a = account_get( irc, cmd[2] ) ) )
478                        {
[0da65d5]479                                if( a->ic )
[b7d3cc34]480                                {
481                                        irc_usermsg( irc, "Account already online" );
[f73b969]482                                        return;
[b7d3cc34]483                                }
484                                else
485                                {
486                                        account_on( irc, a );
487                                }
488                        }
489                        else
490                        {
491                                irc_usermsg( irc, "Invalid account" );
[f73b969]492                                return;
[b7d3cc34]493                        }
494                }
495                else
496                {
497                        if ( irc->accounts ) {
498                                irc_usermsg( irc, "Trying to get all accounts connected..." );
499                       
500                                for( a = irc->accounts; a; a = a->next )
[0da65d5]501                                        if( !a->ic && a->auto_connect )
[b7d3cc34]502                                                account_on( irc, a );
503                        } 
504                        else
505                        {
[eded1f7]506                                irc_usermsg( irc, "No accounts known. Use `account add' to add one." );
[b7d3cc34]507                        }
508                }
509        }
510        else if( g_strcasecmp( cmd[1], "off" ) == 0 )
511        {
512                if( !cmd[2] )
513                {
514                        irc_usermsg( irc, "Deactivating all active (re)connections..." );
515                       
516                        for( a = irc->accounts; a; a = a->next )
517                        {
[0da65d5]518                                if( a->ic )
[b7d3cc34]519                                        account_off( irc, a );
520                                else if( a->reconnect )
521                                        cancel_auto_reconnect( a );
522                        }
523                }
524                else if( ( a = account_get( irc, cmd[2] ) ) )
525                {
[0da65d5]526                        if( a->ic )
[b7d3cc34]527                        {
528                                account_off( irc, a );
529                        }
530                        else if( a->reconnect )
531                        {
532                                cancel_auto_reconnect( a );
533                                irc_usermsg( irc, "Reconnect cancelled" );
534                        }
535                        else
536                        {
537                                irc_usermsg( irc, "Account already offline" );
[f73b969]538                                return;
[b7d3cc34]539                        }
540                }
541                else
542                {
543                        irc_usermsg( irc, "Invalid account" );
[f73b969]544                        return;
[b7d3cc34]545                }
546        }
[5100caa]547        else if( g_strcasecmp( cmd[1], "set" ) == 0 )
548        {
[3b99524]549                MIN_ARGS( 2 );
[5100caa]550               
[c05eb5b]551                cmd_set_real( irc, cmd + 1, cmd_account_set_findhead, cmd_account_set_checkflags );
[5100caa]552        }
[b7d3cc34]553        else
554        {
[a9a7287]555                irc_usermsg( irc, "Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "account", cmd[1] );
[b7d3cc34]556        }
557}
558
[f73b969]559static void cmd_add( irc_t *irc, char **cmd )
[b7d3cc34]560{
561        account_t *a;
[f0cb961]562        int add_on_server = 1;
[f8de26f]563       
564        if( g_strcasecmp( cmd[1], "-tmp" ) == 0 )
565        {
[77fc000c]566                MIN_ARGS( 3 );
[f0cb961]567                add_on_server = 0;
[7adc657]568                cmd ++;
[f8de26f]569        }
[b7d3cc34]570       
571        if( !( a = account_get( irc, cmd[1] ) ) )
572        {
573                irc_usermsg( irc, "Invalid account" );
[f73b969]574                return;
[b7d3cc34]575        }
[0da65d5]576        else if( !( a->ic && ( a->ic->flags & OPT_LOGGED_IN ) ) )
[b7d3cc34]577        {
578                irc_usermsg( irc, "That account is not on-line" );
[f73b969]579                return;
[b7d3cc34]580        }
581       
582        if( cmd[3] )
583        {
584                if( !nick_ok( cmd[3] ) )
585                {
586                        irc_usermsg( irc, "The requested nick `%s' is invalid", cmd[3] );
[f73b969]587                        return;
[b7d3cc34]588                }
589                else if( user_find( irc, cmd[3] ) )
590                {
591                        irc_usermsg( irc, "The requested nick `%s' already exists", cmd[3] );
[f73b969]592                        return;
[b7d3cc34]593                }
594                else
595                {
[5b52a48]596                        nick_set( a, cmd[2], cmd[3] );
[b7d3cc34]597                }
598        }
[f8de26f]599       
[f0cb961]600        if( add_on_server )
[0da65d5]601                a->ic->acc->prpl->add_buddy( a->ic, cmd[2], NULL );
[7adc657]602        else
603                /* Yeah, officially this is a call-*back*... So if we just
604                   called add_buddy, we'll wait for the IM server to respond
605                   before we do this. */
606                imcb_add_buddy( a->ic, cmd[2], NULL );
[f0cb961]607       
608        irc_usermsg( irc, "Adding `%s' to your contact list", cmd[2]  );
[b7d3cc34]609}
610
[f73b969]611static void cmd_info( irc_t *irc, char **cmd )
[b7d3cc34]612{
[0da65d5]613        struct im_connection *ic;
[b7d3cc34]614        account_t *a;
615       
616        if( !cmd[2] )
617        {
618                user_t *u = user_find( irc, cmd[1] );
[0da65d5]619                if( !u || !u->ic )
[b7d3cc34]620                {
621                        irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] );
[f73b969]622                        return;
[b7d3cc34]623                }
[0da65d5]624                ic = u->ic;
[b7d3cc34]625                cmd[2] = u->handle;
626        }
627        else if( !( a = account_get( irc, cmd[1] ) ) )
628        {
629                irc_usermsg( irc, "Invalid account" );
[f73b969]630                return;
[b7d3cc34]631        }
[0da65d5]632        else if( !( ( ic = a->ic ) && ( a->ic->flags & OPT_LOGGED_IN ) ) )
[b7d3cc34]633        {
634                irc_usermsg( irc, "That account is not on-line" );
[f73b969]635                return;
[b7d3cc34]636        }
637       
[0da65d5]638        if( !ic->acc->prpl->get_info )
[b7d3cc34]639        {
640                irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
641        }
[f73b969]642        else
643        {
[0da65d5]644                ic->acc->prpl->get_info( ic, cmd[2] );
[f73b969]645        }
[b7d3cc34]646}
647
[f73b969]648static void cmd_rename( irc_t *irc, char **cmd )
[b7d3cc34]649{
650        user_t *u;
651       
652        if( g_strcasecmp( cmd[1], irc->nick ) == 0 )
653        {
654                irc_usermsg( irc, "Nick `%s' can't be changed", cmd[1] );
655        }
[f73b969]656        else if( user_find( irc, cmd[2] ) && ( nick_cmp( cmd[1], cmd[2] ) != 0 ) )
[b7d3cc34]657        {
658                irc_usermsg( irc, "Nick `%s' already exists", cmd[2] );
659        }
[f73b969]660        else if( !nick_ok( cmd[2] ) )
[b7d3cc34]661        {
662                irc_usermsg( irc, "Nick `%s' is invalid", cmd[2] );
663        }
[f73b969]664        else if( !( u = user_find( irc, cmd[1] ) ) )
[b7d3cc34]665        {
666                irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] );
667        }
[f73b969]668        else
[b7d3cc34]669        {
[f73b969]670                user_rename( irc, cmd[1], cmd[2] );
671                irc_write( irc, ":%s!%s@%s NICK %s", cmd[1], u->user, u->host, cmd[2] );
672                if( g_strcasecmp( cmd[1], irc->mynick ) == 0 )
673                {
674                        g_free( irc->mynick );
675                        irc->mynick = g_strdup( cmd[2] );
[1195cec]676                       
[7125cb3]677                        /* If we're called internally (user did "set root_nick"),
678                           let's not go O(INF). :-) */
[1195cec]679                        if( strcmp( cmd[0], "set_rename" ) != 0 )
680                                set_setstr( &irc->set, "root_nick", cmd[2] );
[f73b969]681                }
682                else if( u->send_handler == buddy_send_handler )
683                {
[0da65d5]684                        nick_set( u->ic->acc, u->handle, cmd[2] );
[f73b969]685                }
686               
687                irc_usermsg( irc, "Nick successfully changed" );
[b7d3cc34]688        }
689}
690
[1195cec]691char *set_eval_root_nick( set_t *set, char *new_nick )
692{
693        irc_t *irc = set->data;
694       
695        if( strcmp( irc->mynick, new_nick ) != 0 )
696        {
697                char *cmd[] = { "set_rename", irc->mynick, new_nick, NULL };
698               
699                cmd_rename( irc, cmd );
700        }
701       
[7125cb3]702        return strcmp( irc->mynick, new_nick ) == 0 ? new_nick : SET_INVALID;
[1195cec]703}
704
[f73b969]705static void cmd_remove( irc_t *irc, char **cmd )
[b7d3cc34]706{
707        user_t *u;
708        char *s;
709       
[0da65d5]710        if( !( u = user_find( irc, cmd[1] ) ) || !u->ic )
[b7d3cc34]711        {
712                irc_usermsg( irc, "Buddy `%s' not found", cmd[1] );
[f73b969]713                return;
[b7d3cc34]714        }
715        s = g_strdup( u->handle );
716       
[0da65d5]717        u->ic->acc->prpl->remove_buddy( u->ic, u->handle, NULL );
718        nick_del( u->ic->acc, u->handle );
[b7d3cc34]719        user_del( irc, cmd[1] );
720       
721        irc_usermsg( irc, "Buddy `%s' (nick %s) removed from contact list", s, cmd[1] );
722        g_free( s );
723       
[f73b969]724        return;
[b7d3cc34]725}
726
[f73b969]727static void cmd_block( irc_t *irc, char **cmd )
[b7d3cc34]728{
[0da65d5]729        struct im_connection *ic;
[b7d3cc34]730        account_t *a;
731       
[0da65d5]732        if( !cmd[2] && ( a = account_get( irc, cmd[1] ) ) && a->ic )
[87b6a3e]733        {
734                char *format;
735                GSList *l;
736               
737                if( strchr( irc->umode, 'b' ) != NULL )
738                        format = "%s\t%s";
739                else
[57ef864]740                        format = "%-32.32s  %-16.16s";
[87b6a3e]741               
742                irc_usermsg( irc, format, "Handle", "Nickname" );
[0da65d5]743                for( l = a->ic->deny; l; l = l->next )
[87b6a3e]744                {
[0da65d5]745                        user_t *u = user_findhandle( a->ic, l->data );
[87b6a3e]746                        irc_usermsg( irc, format, l->data, u ? u->nick : "(none)" );
747                }
748                irc_usermsg( irc, "End of list." );
749               
750                return;
751        }
752        else if( !cmd[2] )
[b7d3cc34]753        {
754                user_t *u = user_find( irc, cmd[1] );
[0da65d5]755                if( !u || !u->ic )
[b7d3cc34]756                {
757                        irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] );
[f73b969]758                        return;
[b7d3cc34]759                }
[0da65d5]760                ic = u->ic;
[b7d3cc34]761                cmd[2] = u->handle;
762        }
763        else if( !( a = account_get( irc, cmd[1] ) ) )
764        {
765                irc_usermsg( irc, "Invalid account" );
[f73b969]766                return;
[b7d3cc34]767        }
[0da65d5]768        else if( !( ( ic = a->ic ) && ( a->ic->flags & OPT_LOGGED_IN ) ) )
[b7d3cc34]769        {
770                irc_usermsg( irc, "That account is not on-line" );
[f73b969]771                return;
[b7d3cc34]772        }
773       
[0da65d5]774        if( !ic->acc->prpl->add_deny || !ic->acc->prpl->rem_permit )
[b7d3cc34]775        {
776                irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
777        }
778        else
779        {
[84b045d]780                imc_rem_allow( ic, cmd[2] );
781                imc_add_block( ic, cmd[2] );
[da3b536]782                irc_usermsg( irc, "Buddy `%s' moved from your allow- to your block-list", cmd[2] );
[b7d3cc34]783        }
784}
785
[f73b969]786static void cmd_allow( irc_t *irc, char **cmd )
[b7d3cc34]787{
[0da65d5]788        struct im_connection *ic;
[b7d3cc34]789        account_t *a;
790       
[0da65d5]791        if( !cmd[2] && ( a = account_get( irc, cmd[1] ) ) && a->ic )
[87b6a3e]792        {
793                char *format;
794                GSList *l;
795               
796                if( strchr( irc->umode, 'b' ) != NULL )
797                        format = "%s\t%s";
798                else
[57ef864]799                        format = "%-32.32s  %-16.16s";
[87b6a3e]800               
801                irc_usermsg( irc, format, "Handle", "Nickname" );
[0da65d5]802                for( l = a->ic->permit; l; l = l->next )
[87b6a3e]803                {
[0da65d5]804                        user_t *u = user_findhandle( a->ic, l->data );
[87b6a3e]805                        irc_usermsg( irc, format, l->data, u ? u->nick : "(none)" );
806                }
807                irc_usermsg( irc, "End of list." );
808               
809                return;
810        }
811        else if( !cmd[2] )
[b7d3cc34]812        {
813                user_t *u = user_find( irc, cmd[1] );
[0da65d5]814                if( !u || !u->ic )
[b7d3cc34]815                {
816                        irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] );
[f73b969]817                        return;
[b7d3cc34]818                }
[0da65d5]819                ic = u->ic;
[b7d3cc34]820                cmd[2] = u->handle;
821        }
822        else if( !( a = account_get( irc, cmd[1] ) ) )
823        {
824                irc_usermsg( irc, "Invalid account" );
[f73b969]825                return;
[b7d3cc34]826        }
[0da65d5]827        else if( !( ( ic = a->ic ) && ( a->ic->flags & OPT_LOGGED_IN ) ) )
[b7d3cc34]828        {
829                irc_usermsg( irc, "That account is not on-line" );
[f73b969]830                return;
[b7d3cc34]831        }
832       
[0da65d5]833        if( !ic->acc->prpl->rem_deny || !ic->acc->prpl->add_permit )
[b7d3cc34]834        {
835                irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
836        }
837        else
838        {
[84b045d]839                imc_rem_block( ic, cmd[2] );
840                imc_add_allow( ic, cmd[2] );
[b7d3cc34]841               
[da3b536]842                irc_usermsg( irc, "Buddy `%s' moved from your block- to your allow-list", cmd[2] );
[b7d3cc34]843        }
844}
845
[f73b969]846static void cmd_yesno( irc_t *irc, char **cmd )
[b7d3cc34]847{
848        query_t *q = NULL;
849        int numq = 0;
850       
851        if( irc->queries == NULL )
852        {
853                irc_usermsg( irc, "Did I ask you something?" );
[f73b969]854                return;
[b7d3cc34]855        }
856       
857        /* If there's an argument, the user seems to want to answer another question than the
858           first/last (depending on the query_order setting) one. */
859        if( cmd[1] )
860        {
861                if( sscanf( cmd[1], "%d", &numq ) != 1 )
862                {
863                        irc_usermsg( irc, "Invalid query number" );
[f73b969]864                        return;
[b7d3cc34]865                }
866               
867                for( q = irc->queries; q; q = q->next, numq -- )
868                        if( numq == 0 )
869                                break;
870               
871                if( !q )
872                {
873                        irc_usermsg( irc, "Uhm, I never asked you something like that..." );
[f73b969]874                        return;
[b7d3cc34]875                }
876        }
877       
878        if( g_strcasecmp( cmd[0], "yes" ) == 0 )
879                query_answer( irc, q, 1 );
880        else if( g_strcasecmp( cmd[0], "no" ) == 0 )
881                query_answer( irc, q, 0 );
882}
883
[f73b969]884static void cmd_set( irc_t *irc, char **cmd )
[b7d3cc34]885{
[c05eb5b]886        cmd_set_real( irc, cmd, NULL, NULL );
[b7d3cc34]887}
888
[f73b969]889static void cmd_save( irc_t *irc, char **cmd )
[b7d3cc34]890{
[3183c21]891        if( ( irc->status & USTATUS_IDENTIFIED ) == 0 )
892                irc_usermsg( irc, "Please create an account first" );
893        else if( storage_save( irc, NULL, TRUE ) == STORAGE_OK )
[b7d3cc34]894                irc_usermsg( irc, "Configuration saved" );
895        else
896                irc_usermsg( irc, "Configuration could not be saved!" );
897}
898
[f73b969]899static void cmd_blist( irc_t *irc, char **cmd )
[b7d3cc34]900{
901        int online = 0, away = 0, offline = 0;
902        user_t *u;
[aefa533e]903        char s[256];
904        char *format;
[b7d3cc34]905        int n_online = 0, n_away = 0, n_offline = 0;
906       
907        if( cmd[1] && g_strcasecmp( cmd[1], "all" ) == 0 )
908                online = offline = away = 1;
909        else if( cmd[1] && g_strcasecmp( cmd[1], "offline" ) == 0 )
910                offline = 1;
911        else if( cmd[1] && g_strcasecmp( cmd[1], "away" ) == 0 )
912                away = 1;
913        else if( cmd[1] && g_strcasecmp( cmd[1], "online" ) == 0 )
914                online = 1;
915        else
[449a51d]916                online = away = 1;
[b7d3cc34]917       
[aefa533e]918        if( strchr( irc->umode, 'b' ) != NULL )
919                format = "%s\t%s\t%s";
920        else
921                format = "%-16.16s  %-40.40s  %s";
922       
923        irc_usermsg( irc, format, "Nick", "User/Host/Network", "Status" );
[b7d3cc34]924       
[0da65d5]925        for( u = irc->users; u; u = u->next ) if( u->ic && u->online && !u->away )
[b7d3cc34]926        {
[aefa533e]927                if( online == 1 )
928                {
[449a51d]929                        char st[256] = "Online";
930                       
931                        if( u->status_msg )
932                                g_snprintf( st, sizeof( st ) - 1, "Online (%s)", u->status_msg );
933                       
[e731120]934                        g_snprintf( s, sizeof( s ) - 1, "%s@%s %s(%s)", u->user, u->host, u->ic->acc->prpl->name, u->ic->acc->user );
[449a51d]935                        irc_usermsg( irc, format, u->nick, s, st );
[aefa533e]936                }
937               
[b7d3cc34]938                n_online ++;
939        }
940
[0da65d5]941        for( u = irc->users; u; u = u->next ) if( u->ic && u->online && u->away )
[b7d3cc34]942        {
[aefa533e]943                if( away == 1 )
944                {
[e731120]945                        g_snprintf( s, sizeof( s ) - 1, "%s@%s %s(%s)", u->user, u->host, u->ic->acc->prpl->name, u->ic->acc->user );
[aefa533e]946                        irc_usermsg( irc, format, u->nick, s, u->away );
947                }
[b7d3cc34]948                n_away ++;
949        }
950       
[0da65d5]951        for( u = irc->users; u; u = u->next ) if( u->ic && !u->online )
[b7d3cc34]952        {
[aefa533e]953                if( offline == 1 )
954                {
[e731120]955                        g_snprintf( s, sizeof( s ) - 1, "%s@%s %s(%s)", u->user, u->host, u->ic->acc->prpl->name, u->ic->acc->user );
[aefa533e]956                        irc_usermsg( irc, format, u->nick, s, "Offline" );
957                }
[b7d3cc34]958                n_offline ++;
959        }
960       
[aa5ac01]961        irc_usermsg( irc, "%d buddies (%d available, %d away, %d offline)", n_online + n_away + n_offline, n_online, n_away, n_offline );
[b7d3cc34]962}
963
[f73b969]964static void cmd_nick( irc_t *irc, char **cmd ) 
[b7d3cc34]965{
966        account_t *a;
967
968        if( !cmd[1] || !( a = account_get( irc, cmd[1] ) ) )
969        {
970                irc_usermsg( irc, "Invalid account");
971        }
[0da65d5]972        else if( !( a->ic && ( a->ic->flags & OPT_LOGGED_IN ) ) )
[b7d3cc34]973        {
974                irc_usermsg( irc, "That account is not on-line" );
975        }
976        else if ( !cmd[2] ) 
977        {
[0da65d5]978                irc_usermsg( irc, "Your name is `%s'" , a->ic->displayname ? a->ic->displayname : "NULL" );
[b7d3cc34]979        }
[0da65d5]980        else if ( !a->prpl->set_my_name ) 
[b7d3cc34]981        {
982                irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
983        }
984        else
985        {
986                irc_usermsg( irc, "Setting your name to `%s'", cmd[2] );
987               
[0da65d5]988                a->prpl->set_my_name( a->ic, cmd[2] );
[b7d3cc34]989        }
990}
991
[f73b969]992static void cmd_qlist( irc_t *irc, char **cmd )
[b7d3cc34]993{
994        query_t *q = irc->queries;
995        int num;
996       
997        if( !q )
998        {
999                irc_usermsg( irc, "There are no pending questions." );
[f73b969]1000                return;
[b7d3cc34]1001        }
1002       
1003        irc_usermsg( irc, "Pending queries:" );
1004       
1005        for( num = 0; q; q = q->next, num ++ )
[0da65d5]1006                if( q->ic ) /* Not necessary yet, but it might come later */
[c2fb3809]1007                        irc_usermsg( irc, "%d, %s(%s): %s", num, q->ic->acc->prpl->name, q->ic->acc->user, q->question );
[5c09a59]1008                else
1009                        irc_usermsg( irc, "%d, BitlBee: %s", num, q->question );
[b7d3cc34]1010}
1011
[fa29d093]1012static void cmd_join_chat( irc_t *irc, char **cmd )
1013{
[a9a7287]1014        irc_usermsg( irc, "This command is now obsolete. "
1015                          "Please try the `chat' command instead." );
1016}
1017
[e7bc722]1018static set_t **cmd_chat_set_findhead( irc_t *irc, char *id )
1019{
1020        struct chat *c;
1021       
1022        if( ( c = chat_get( irc, id ) ) )
1023                return &c->set;
1024        else
1025                return NULL;
1026}
1027
[a9a7287]1028static void cmd_chat( irc_t *irc, char **cmd )
1029{
1030        account_t *acc;
1031        struct chat *c;
1032       
1033        if( g_strcasecmp( cmd[1], "add" ) == 0 )
1034        {
[07054a5]1035                char *channel, *s;
1036               
1037                MIN_ARGS( 3 );
[a9a7287]1038               
1039                if( !( acc = account_get( irc, cmd[2] ) ) )
1040                {
1041                        irc_usermsg( irc, "Invalid account" );
1042                        return;
1043                }
1044               
[07054a5]1045                if( cmd[4] == NULL )
1046                {
1047                        channel = g_strdup( cmd[3] );
1048                        if( ( s = strchr( channel, '@' ) ) )
1049                                *s = 0;
1050                }
1051                else
1052                {
1053                        channel = g_strdup( cmd[4] );
1054                }
1055               
1056                if( strchr( CTYPES, channel[0] ) == NULL )
1057                {
1058                        s = g_strdup_printf( "%c%s", CTYPES[0], channel );
1059                        g_free( channel );
1060                        channel = s;
1061                }
1062               
1063                if( ( c = chat_add( irc, acc, cmd[3], channel ) ) )
[a9a7287]1064                        irc_usermsg( irc, "Chatroom added successfully." );
1065                else
1066                        irc_usermsg( irc, "Could not add chatroom." );
[07054a5]1067               
1068                g_free( channel );
[a9a7287]1069        }
1070        else if( g_strcasecmp( cmd[1], "list" ) == 0 )
1071        {
1072                int i = 0;
1073               
1074                if( strchr( irc->umode, 'b' ) )
1075                        irc_usermsg( irc, "Chatroom list:" );
1076               
1077                for( c = irc->chatrooms; c; c = c->next )
1078                {
1079                        irc_usermsg( irc, "%2d. %s(%s) %s, %s", i, c->acc->prpl->name,
1080                                          c->acc->user, c->handle, c->channel );
1081                       
1082                        i ++;
1083                }
1084                irc_usermsg( irc, "End of chatroom list" );
1085        }
[e7bc722]1086        else if( g_strcasecmp( cmd[1], "set" ) == 0 )
1087        {
[2ea8736]1088                MIN_ARGS( 2 );
1089               
[c05eb5b]1090                cmd_set_real( irc, cmd + 1, cmd_chat_set_findhead, NULL );
[e7bc722]1091        }
[d995c9b]1092        else if( g_strcasecmp( cmd[1], "del" ) == 0 )
1093        {
[3b99524]1094                MIN_ARGS( 2 );
[d995c9b]1095               
1096                if( ( c = chat_get( irc, cmd[2] ) ) )
1097                {
1098                        chat_del( irc, c );
1099                }
1100                else
1101                {
1102                        irc_usermsg( irc, "Could not remove chat." );
1103                }
1104        }
[39f93f0]1105        else if( g_strcasecmp( cmd[1], "with" ) == 0 )
1106        {
1107                user_t *u;
[3b99524]1108               
1109                MIN_ARGS( 2 );
[39f93f0]1110               
1111                if( ( u = user_find( irc, cmd[2] ) ) && u->ic && u->ic->acc->prpl->chat_with )
1112                {
1113                        if( !u->ic->acc->prpl->chat_with( u->ic, u->handle ) )
1114                        {
1115                                irc_usermsg( irc, "(Possible) failure while trying to open "
1116                                                  "a groupchat with %s.", u->nick );
1117                        }
1118                }
1119                else
1120                {
1121                        irc_usermsg( irc, "Can't open a groupchat with %s.", cmd[2] );
1122                }
1123        }
[a9a7287]1124        else
1125        {
1126                irc_usermsg( irc, "Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "chat", cmd[1] );
1127        }
[fa29d093]1128}
1129
[b8a491d]1130static void cmd_transfer( irc_t *irc, char **cmd )
[2c2df7d]1131{
1132        GSList *files = irc->file_transfers;
1133        enum { LIST, REJECT, CANCEL };
1134        int subcmd = LIST;
1135        int fid;
1136
1137        if( !files )
1138        {
1139                irc_usermsg( irc, "No pending transfers" );
1140                return;
1141        }
1142
[b8a491d]1143        if( cmd[1] && ( strcmp( cmd[1], "reject" ) == 0 ) )
[2c2df7d]1144        {
1145                subcmd = REJECT;
1146        }
[b8a491d]1147        else if( cmd[1] && ( strcmp( cmd[1], "cancel" ) == 0 ) && 
1148                 cmd[2] && ( sscanf( cmd[2], "%d", &fid ) == 1 ) )
[2c2df7d]1149        {
1150                subcmd = CANCEL;
1151        }
1152
1153        for( ; files; files = g_slist_next( files ) )
1154        {
1155                file_transfer_t *file = files->data;
1156               
1157                switch( subcmd ) {
1158                case LIST:
1159                        if ( file->status == FT_STATUS_LISTENING )
1160                                irc_usermsg( irc, 
1161                                        "Pending file(id %d): %s (Listening...)", file->local_id, file->file_name);
1162                        else 
1163                        {
1164                                int kb_per_s = 0;
[44961cb]1165                                time_t diff = time( NULL ) - file->started ? : 1;
[2c2df7d]1166                                if ( ( file->started > 0 ) && ( file->bytes_transferred > 0 ) )
1167                                        kb_per_s = file->bytes_transferred / 1024 / diff;
1168                                       
1169                                irc_usermsg( irc, 
1170                                        "Pending file(id %d): %s (%10zd/%zd kb, %d kb/s)", file->local_id, file->file_name, 
1171                                        file->bytes_transferred/1024, file->file_size/1024, kb_per_s);
1172                        }
1173                        break;
1174                case REJECT:
1175                        if( file->status == FT_STATUS_LISTENING )
1176                        {
1177                                irc_usermsg( irc, "Rejecting file transfer for %s", file->file_name );
1178                                imcb_file_canceled( file, "Denied by user" );
1179                        }
1180                        break;
1181                case CANCEL:
1182                        if( file->local_id == fid )
1183                        {
1184                                irc_usermsg( irc, "Canceling file transfer for %s", file->file_name );
1185                                imcb_file_canceled( file, "Canceled by user" );
1186                        }
1187                        break;
1188                }
1189        }
1190}
1191
[0298d11]1192const command_t commands[] = {
1193        { "help",           0, cmd_help,           0 }, 
1194        { "identify",       1, cmd_identify,       0 },
1195        { "register",       1, cmd_register,       0 },
1196        { "drop",           1, cmd_drop,           0 },
1197        { "account",        1, cmd_account,        0 },
1198        { "add",            2, cmd_add,            0 },
1199        { "info",           1, cmd_info,           0 },
1200        { "rename",         2, cmd_rename,         0 },
1201        { "remove",         1, cmd_remove,         0 },
1202        { "block",          1, cmd_block,          0 },
1203        { "allow",          1, cmd_allow,          0 },
1204        { "save",           0, cmd_save,           0 },
1205        { "set",            0, cmd_set,            0 },
1206        { "yes",            0, cmd_yesno,          0 },
1207        { "no",             0, cmd_yesno,          0 },
1208        { "blist",          0, cmd_blist,          0 },
1209        { "nick",           1, cmd_nick,           0 },
1210        { "qlist",          0, cmd_qlist,          0 },
[fa29d093]1211        { "join_chat",      2, cmd_join_chat,      0 },
[a9a7287]1212        { "chat",           1, cmd_chat,           0 },
[b8a491d]1213        { "transfer",       0, cmd_transfer,       0 },
[0298d11]1214        { NULL }
1215};
Note: See TracBrowser for help on using the repository browser.