source: root_commands.c @ 7125cb3

Last change on this file since 7125cb3 was 7125cb3, checked in by Wilmer van der Gaast <wilmer@…>, at 2008-08-24T18:01:05Z

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.

  • Property mode set to 100644
File size: 24.3 KB
Line 
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"
31
32#include <string.h>
33
34void root_command_string( irc_t *irc, user_t *u, char *command, int flags )
35{
36        char *cmd[IRC_MAX_ARGS];
37        char *s;
38        int k;
39        char q = 0;
40       
41        memset( cmd, 0, sizeof( cmd ) );
42        cmd[0] = command;
43        k = 1;
44        for( s = command; *s && k < ( IRC_MAX_ARGS - 1 ); s ++ )
45                if( *s == ' ' && !q )
46                {
47                        *s = 0;
48                        while( *++s == ' ' );
49                        if( *s == '"' || *s == '\'' )
50                        {
51                                q = *s;
52                                s ++;
53                        }
54                        if( *s )
55                        {
56                                cmd[k++] = s;
57                                s --;
58                        }
59                        else
60                        {
61                                break;
62                        }
63                }
64                else if( *s == '\\' && ( ( !q && s[1] ) || ( q && q == s[1] ) ) )
65                {
66                        char *cpy;
67                       
68                        for( cpy = s; *cpy; cpy ++ )
69                                cpy[0] = cpy[1];
70                }
71                else if( *s == q )
72                {
73                        q = *s = 0;
74                }
75        cmd[k] = NULL;
76       
77        root_command( irc, cmd );
78}
79
80void root_command( irc_t *irc, char *cmd[] )
81{       
82        int i;
83       
84        if( !cmd[0] )
85                return;
86       
87        for( i = 0; commands[i].command; i++ )
88                if( g_strcasecmp( commands[i].command, cmd[0] ) == 0 )
89                {
90                        if( !cmd[commands[i].required_parameters] )
91                        {
92                                irc_usermsg( irc, "Not enough parameters given (need %d)", commands[i].required_parameters );
93                                return;
94                        }
95                        commands[i].execute( irc, cmd );
96                        return;
97                }
98       
99        irc_usermsg( irc, "Unknown command: %s. Please use \x02help commands\x02 to get a list of available commands.", cmd[0] );
100}
101
102static void cmd_help( irc_t *irc, char **cmd )
103{
104        char param[80];
105        int i;
106        char *s;
107       
108        memset( param, 0, sizeof(param) );
109        for ( i = 1; (cmd[i] != NULL && ( strlen(param) < (sizeof(param)-1) ) ); i++ ) {
110                if ( i != 1 )   // prepend space except for the first parameter
111                        strcat(param, " ");
112                strncat( param, cmd[i], sizeof(param) - strlen(param) - 1 );
113        }
114
115        s = help_get( &(global.help), param );
116        if( !s ) s = help_get( &(global.help), "" );
117       
118        if( s )
119        {
120                irc_usermsg( irc, "%s", s );
121                g_free( s );
122        }
123        else
124        {
125                irc_usermsg( irc, "Error opening helpfile." );
126        }
127}
128
129static void cmd_account( irc_t *irc, char **cmd );
130
131static void cmd_identify( irc_t *irc, char **cmd )
132{
133        storage_status_t status = storage_load( irc->nick, cmd[1], irc );
134        char *account_on[] = { "account", "on", NULL };
135       
136        switch (status) {
137        case STORAGE_INVALID_PASSWORD:
138                irc_usermsg( irc, "Incorrect password" );
139                break;
140        case STORAGE_NO_SUCH_USER:
141                irc_usermsg( irc, "The nick is (probably) not registered" );
142                break;
143        case STORAGE_OK:
144                irc_usermsg( irc, "Password accepted, settings and accounts loaded" );
145                irc_umode_set( irc, "+R", 1 );
146                if( set_getbool( &irc->set, "auto_connect" ) )
147                        cmd_account( irc, account_on );
148                break;
149        case STORAGE_OTHER_ERROR:
150        default:
151                irc_usermsg( irc, "Unknown error while loading configuration" );
152                break;
153        }
154}
155
156static void cmd_register( irc_t *irc, char **cmd )
157{
158        if( global.conf->authmode == AUTHMODE_REGISTERED )
159        {
160                irc_usermsg( irc, "This server does not allow registering new accounts" );
161                return;
162        }
163
164        irc_setpass( irc, cmd[1] );
165        switch( storage_save( irc, FALSE )) {
166                case STORAGE_ALREADY_EXISTS:
167                        irc_usermsg( irc, "Nick is already registered" );
168                        break;
169                       
170                case STORAGE_OK:
171                        irc_usermsg( irc, "Account successfully created" );
172                        irc->status |= USTATUS_IDENTIFIED;
173                        irc_umode_set( irc, "+R", 1 );
174                        break;
175
176                default:
177                        irc_usermsg( irc, "Error registering" );
178                        break;
179        }
180}
181
182static void cmd_drop( irc_t *irc, char **cmd )
183{
184        storage_status_t status;
185       
186        status = storage_remove (irc->nick, cmd[1]);
187        switch (status) {
188        case STORAGE_NO_SUCH_USER:
189                irc_usermsg( irc, "That account does not exist" );
190                break;
191        case STORAGE_INVALID_PASSWORD:
192                irc_usermsg( irc, "Password invalid" );
193                break;
194        case STORAGE_OK:
195                irc_setpass( irc, NULL );
196                irc->status &= ~USTATUS_IDENTIFIED;
197                irc_umode_set( irc, "-R", 1 );
198                irc_usermsg( irc, "Account `%s' removed", irc->nick );
199                break;
200        default:
201                irc_usermsg( irc, "Error: `%d'", status );
202                break;
203        }
204}
205
206struct cmd_account_del_data
207{
208        account_t *a;
209        irc_t *irc;
210};
211
212void cmd_account_del_yes( void *data )
213{
214        struct cmd_account_del_data *cad = data;
215        account_t *a;
216       
217        for( a = cad->irc->accounts; a && a != cad->a; a = a->next );
218       
219        if( a == NULL )
220        {
221                irc_usermsg( cad->irc, "Account already deleted" );
222        }
223        else if( a->ic )
224        {
225                irc_usermsg( cad->irc, "Account is still logged in, can't delete" );
226        }
227        else
228        {
229                account_del( cad->irc, a );
230                irc_usermsg( cad->irc, "Account deleted" );
231        }
232        g_free( data );
233}
234
235void cmd_account_del_no( void *data )
236{
237        g_free( data );
238}
239
240static void cmd_account( irc_t *irc, char **cmd )
241{
242        account_t *a;
243       
244        if( global.conf->authmode == AUTHMODE_REGISTERED && !( irc->status & USTATUS_IDENTIFIED ) )
245        {
246                irc_usermsg( irc, "This server only accepts registered users" );
247                return;
248        }
249       
250        if( g_strcasecmp( cmd[1], "add" ) == 0 )
251        {
252                struct prpl *prpl;
253               
254                if( cmd[2] == NULL || cmd[3] == NULL || cmd[4] == NULL )
255                {
256                        irc_usermsg( irc, "Not enough parameters" );
257                        return;
258                }
259               
260                prpl = find_protocol(cmd[2]);
261               
262                if( prpl == NULL )
263                {
264                        irc_usermsg( irc, "Unknown protocol" );
265                        return;
266                }
267
268                a = account_add( irc, prpl, cmd[3], cmd[4] );
269                if( cmd[5] )
270                {
271                        irc_usermsg( irc, "Warning: Passing a servername/other flags to `account add' "
272                                          "is now deprecated. Use `account set' instead." );
273                        set_setstr( &a->set, "server", cmd[5] );
274                }
275               
276                irc_usermsg( irc, "Account successfully added" );
277        }
278        else if( g_strcasecmp( cmd[1], "del" ) == 0 )
279        {
280                if( !cmd[2] )
281                {
282                        irc_usermsg( irc, "Not enough parameters given (need %d)", 2 );
283                }
284                else if( !( a = account_get( irc, cmd[2] ) ) )
285                {
286                        irc_usermsg( irc, "Invalid account" );
287                }
288                else if( a->ic )
289                {
290                        irc_usermsg( irc, "Account is still logged in, can't delete" );
291                }
292                else
293                {
294                        struct cmd_account_del_data *cad;
295                        char *msg;
296                       
297                        cad = g_malloc( sizeof( struct cmd_account_del_data ) );
298                        cad->a = a;
299                        cad->irc = irc;
300                       
301                        msg = g_strdup_printf( "If you remove this account (%s(%s)), BitlBee will "
302                                               "also forget all your saved nicknames. If you want "
303                                               "to change your username/password, use the `account "
304                                               "set' command. Are you sure you want to delete this "
305                                               "account?", a->prpl->name, a->user );
306                        query_add( irc, NULL, msg, cmd_account_del_yes, cmd_account_del_no, cad );
307                        g_free( msg );
308                }
309        }
310        else if( g_strcasecmp( cmd[1], "list" ) == 0 )
311        {
312                int i = 0;
313               
314                if( strchr( irc->umode, 'b' ) )
315                        irc_usermsg( irc, "Account list:" );
316               
317                for( a = irc->accounts; a; a = a->next )
318                {
319                        char *con;
320                       
321                        if( a->ic && ( a->ic->flags & OPT_LOGGED_IN ) )
322                                con = " (connected)";
323                        else if( a->ic )
324                                con = " (connecting)";
325                        else if( a->reconnect )
326                                con = " (awaiting reconnect)";
327                        else
328                                con = "";
329                       
330                        irc_usermsg( irc, "%2d. %s, %s%s", i, a->prpl->name, a->user, con );
331                       
332                        i ++;
333                }
334                irc_usermsg( irc, "End of account list" );
335        }
336        else if( g_strcasecmp( cmd[1], "on" ) == 0 )
337        {
338                if( cmd[2] )
339                {
340                        if( ( a = account_get( irc, cmd[2] ) ) )
341                        {
342                                if( a->ic )
343                                {
344                                        irc_usermsg( irc, "Account already online" );
345                                        return;
346                                }
347                                else
348                                {
349                                        account_on( irc, a );
350                                }
351                        }
352                        else
353                        {
354                                irc_usermsg( irc, "Invalid account" );
355                                return;
356                        }
357                }
358                else
359                {
360                        if ( irc->accounts ) {
361                                irc_usermsg( irc, "Trying to get all accounts connected..." );
362                       
363                                for( a = irc->accounts; a; a = a->next )
364                                        if( !a->ic && a->auto_connect )
365                                                account_on( irc, a );
366                        } 
367                        else
368                        {
369                                irc_usermsg( irc, "No accounts known. Use `account add' to add one." );
370                        }
371                }
372        }
373        else if( g_strcasecmp( cmd[1], "off" ) == 0 )
374        {
375                if( !cmd[2] )
376                {
377                        irc_usermsg( irc, "Deactivating all active (re)connections..." );
378                       
379                        for( a = irc->accounts; a; a = a->next )
380                        {
381                                if( a->ic )
382                                        account_off( irc, a );
383                                else if( a->reconnect )
384                                        cancel_auto_reconnect( a );
385                        }
386                }
387                else if( ( a = account_get( irc, cmd[2] ) ) )
388                {
389                        if( a->ic )
390                        {
391                                account_off( irc, a );
392                        }
393                        else if( a->reconnect )
394                        {
395                                cancel_auto_reconnect( a );
396                                irc_usermsg( irc, "Reconnect cancelled" );
397                        }
398                        else
399                        {
400                                irc_usermsg( irc, "Account already offline" );
401                                return;
402                        }
403                }
404                else
405                {
406                        irc_usermsg( irc, "Invalid account" );
407                        return;
408                }
409        }
410        else if( g_strcasecmp( cmd[1], "set" ) == 0 )
411        {
412                char *acc_handle, *set_name = NULL, *tmp;
413               
414                if( !cmd[2] )
415                {
416                        irc_usermsg( irc, "Not enough parameters given (need %d)", 2 );
417                        return;
418                }
419               
420                if( g_strncasecmp( cmd[2], "-del", 4 ) == 0 )
421                        acc_handle = g_strdup( cmd[3] );
422                else
423                        acc_handle = g_strdup( cmd[2] );
424               
425                if( !acc_handle )
426                {
427                        irc_usermsg( irc, "Not enough parameters given (need %d)", 3 );
428                        return;
429                }
430               
431                if( ( tmp = strchr( acc_handle, '/' ) ) )
432                {
433                        *tmp = 0;
434                        set_name = tmp + 1;
435                }
436               
437                if( ( a = account_get( irc, acc_handle ) ) == NULL )
438                {
439                        g_free( acc_handle );
440                        irc_usermsg( irc, "Invalid account" );
441                        return;
442                }
443               
444                if( cmd[3] && set_name )
445                {
446                        set_t *s = set_find( &a->set, set_name );
447                       
448                        if( a->ic && s && s->flags & ACC_SET_OFFLINE_ONLY )
449                        {
450                                g_free( acc_handle );
451                                irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "off" );
452                                return;
453                        }
454                        else if( !a->ic && s && s->flags & ACC_SET_ONLINE_ONLY )
455                        {
456                                g_free( acc_handle );
457                                irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "on" );
458                                return;
459                        }
460                       
461                        if( g_strncasecmp( cmd[2], "-del", 4 ) == 0 )
462                                set_reset( &a->set, set_name );
463                        else
464                                set_setstr( &a->set, set_name, cmd[3] );
465                }
466                if( set_name ) /* else 'forgotten' on purpose.. Must show new value after changing */
467                {
468                        char *s = set_getstr( &a->set, set_name );
469                        if( s )
470                                irc_usermsg( irc, "%s = `%s'", set_name, s );
471                        else
472                                irc_usermsg( irc, "%s is empty", set_name );
473                }
474                else
475                {
476                        set_t *s = a->set;
477                        while( s )
478                        {
479                                if( s->value || s->def )
480                                        irc_usermsg( irc, "%s = `%s'", s->key, s->value ? s->value : s->def );
481                                else
482                                        irc_usermsg( irc, "%s is empty", s->key );
483                                s = s->next;
484                        }
485                }
486               
487                g_free( acc_handle );
488        }
489        else
490        {
491                irc_usermsg( irc, "Unknown command: account %s. Please use \x02help commands\x02 to get a list of available commands.", cmd[1] );
492        }
493}
494
495static void cmd_add( irc_t *irc, char **cmd )
496{
497        account_t *a;
498        int add_on_server = 1;
499       
500        if( g_strcasecmp( cmd[1], "-tmp" ) == 0 )
501        {
502                add_on_server = 0;
503                cmd ++;
504        }
505       
506        if( !( a = account_get( irc, cmd[1] ) ) )
507        {
508                irc_usermsg( irc, "Invalid account" );
509                return;
510        }
511        else if( !( a->ic && ( a->ic->flags & OPT_LOGGED_IN ) ) )
512        {
513                irc_usermsg( irc, "That account is not on-line" );
514                return;
515        }
516       
517        if( cmd[3] )
518        {
519                if( !nick_ok( cmd[3] ) )
520                {
521                        irc_usermsg( irc, "The requested nick `%s' is invalid", cmd[3] );
522                        return;
523                }
524                else if( user_find( irc, cmd[3] ) )
525                {
526                        irc_usermsg( irc, "The requested nick `%s' already exists", cmd[3] );
527                        return;
528                }
529                else
530                {
531                        nick_set( a, cmd[2], cmd[3] );
532                }
533        }
534       
535        if( add_on_server )
536                a->ic->acc->prpl->add_buddy( a->ic, cmd[2], NULL );
537        else
538                /* Yeah, officially this is a call-*back*... So if we just
539                   called add_buddy, we'll wait for the IM server to respond
540                   before we do this. */
541                imcb_add_buddy( a->ic, cmd[2], NULL );
542       
543        irc_usermsg( irc, "Adding `%s' to your contact list", cmd[2]  );
544}
545
546static void cmd_info( irc_t *irc, char **cmd )
547{
548        struct im_connection *ic;
549        account_t *a;
550       
551        if( !cmd[2] )
552        {
553                user_t *u = user_find( irc, cmd[1] );
554                if( !u || !u->ic )
555                {
556                        irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] );
557                        return;
558                }
559                ic = u->ic;
560                cmd[2] = u->handle;
561        }
562        else if( !( a = account_get( irc, cmd[1] ) ) )
563        {
564                irc_usermsg( irc, "Invalid account" );
565                return;
566        }
567        else if( !( ( ic = a->ic ) && ( a->ic->flags & OPT_LOGGED_IN ) ) )
568        {
569                irc_usermsg( irc, "That account is not on-line" );
570                return;
571        }
572       
573        if( !ic->acc->prpl->get_info )
574        {
575                irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
576        }
577        else
578        {
579                ic->acc->prpl->get_info( ic, cmd[2] );
580        }
581}
582
583static void cmd_rename( irc_t *irc, char **cmd )
584{
585        user_t *u;
586       
587        if( g_strcasecmp( cmd[1], irc->nick ) == 0 )
588        {
589                irc_usermsg( irc, "Nick `%s' can't be changed", cmd[1] );
590        }
591        else if( user_find( irc, cmd[2] ) && ( nick_cmp( cmd[1], cmd[2] ) != 0 ) )
592        {
593                irc_usermsg( irc, "Nick `%s' already exists", cmd[2] );
594        }
595        else if( !nick_ok( cmd[2] ) )
596        {
597                irc_usermsg( irc, "Nick `%s' is invalid", cmd[2] );
598        }
599        else if( !( u = user_find( irc, cmd[1] ) ) )
600        {
601                irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] );
602        }
603        else
604        {
605                user_rename( irc, cmd[1], cmd[2] );
606                irc_write( irc, ":%s!%s@%s NICK %s", cmd[1], u->user, u->host, cmd[2] );
607                if( g_strcasecmp( cmd[1], irc->mynick ) == 0 )
608                {
609                        g_free( irc->mynick );
610                        irc->mynick = g_strdup( cmd[2] );
611                       
612                        /* If we're called internally (user did "set root_nick"),
613                           let's not go O(INF). :-) */
614                        if( strcmp( cmd[0], "set_rename" ) != 0 )
615                                set_setstr( &irc->set, "root_nick", cmd[2] );
616                }
617                else if( u->send_handler == buddy_send_handler )
618                {
619                        nick_set( u->ic->acc, u->handle, cmd[2] );
620                }
621               
622                irc_usermsg( irc, "Nick successfully changed" );
623        }
624}
625
626char *set_eval_root_nick( set_t *set, char *new_nick )
627{
628        irc_t *irc = set->data;
629       
630        if( strcmp( irc->mynick, new_nick ) != 0 )
631        {
632                char *cmd[] = { "set_rename", irc->mynick, new_nick, NULL };
633               
634                cmd_rename( irc, cmd );
635        }
636       
637        return strcmp( irc->mynick, new_nick ) == 0 ? new_nick : SET_INVALID;
638}
639
640static void cmd_remove( irc_t *irc, char **cmd )
641{
642        user_t *u;
643        char *s;
644       
645        if( !( u = user_find( irc, cmd[1] ) ) || !u->ic )
646        {
647                irc_usermsg( irc, "Buddy `%s' not found", cmd[1] );
648                return;
649        }
650        s = g_strdup( u->handle );
651       
652        u->ic->acc->prpl->remove_buddy( u->ic, u->handle, NULL );
653        nick_del( u->ic->acc, u->handle );
654        user_del( irc, cmd[1] );
655       
656        irc_usermsg( irc, "Buddy `%s' (nick %s) removed from contact list", s, cmd[1] );
657        g_free( s );
658       
659        return;
660}
661
662static void cmd_block( irc_t *irc, char **cmd )
663{
664        struct im_connection *ic;
665        account_t *a;
666       
667        if( !cmd[2] && ( a = account_get( irc, cmd[1] ) ) && a->ic )
668        {
669                char *format;
670                GSList *l;
671               
672                if( strchr( irc->umode, 'b' ) != NULL )
673                        format = "%s\t%s";
674                else
675                        format = "%-32.32s  %-16.16s";
676               
677                irc_usermsg( irc, format, "Handle", "Nickname" );
678                for( l = a->ic->deny; l; l = l->next )
679                {
680                        user_t *u = user_findhandle( a->ic, l->data );
681                        irc_usermsg( irc, format, l->data, u ? u->nick : "(none)" );
682                }
683                irc_usermsg( irc, "End of list." );
684               
685                return;
686        }
687        else if( !cmd[2] )
688        {
689                user_t *u = user_find( irc, cmd[1] );
690                if( !u || !u->ic )
691                {
692                        irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] );
693                        return;
694                }
695                ic = u->ic;
696                cmd[2] = u->handle;
697        }
698        else if( !( a = account_get( irc, cmd[1] ) ) )
699        {
700                irc_usermsg( irc, "Invalid account" );
701                return;
702        }
703        else if( !( ( ic = a->ic ) && ( a->ic->flags & OPT_LOGGED_IN ) ) )
704        {
705                irc_usermsg( irc, "That account is not on-line" );
706                return;
707        }
708       
709        if( !ic->acc->prpl->add_deny || !ic->acc->prpl->rem_permit )
710        {
711                irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
712        }
713        else
714        {
715                imc_rem_allow( ic, cmd[2] );
716                imc_add_block( ic, cmd[2] );
717                irc_usermsg( irc, "Buddy `%s' moved from your allow- to your block-list", cmd[2] );
718        }
719}
720
721static void cmd_allow( irc_t *irc, char **cmd )
722{
723        struct im_connection *ic;
724        account_t *a;
725       
726        if( !cmd[2] && ( a = account_get( irc, cmd[1] ) ) && a->ic )
727        {
728                char *format;
729                GSList *l;
730               
731                if( strchr( irc->umode, 'b' ) != NULL )
732                        format = "%s\t%s";
733                else
734                        format = "%-32.32s  %-16.16s";
735               
736                irc_usermsg( irc, format, "Handle", "Nickname" );
737                for( l = a->ic->permit; l; l = l->next )
738                {
739                        user_t *u = user_findhandle( a->ic, l->data );
740                        irc_usermsg( irc, format, l->data, u ? u->nick : "(none)" );
741                }
742                irc_usermsg( irc, "End of list." );
743               
744                return;
745        }
746        else if( !cmd[2] )
747        {
748                user_t *u = user_find( irc, cmd[1] );
749                if( !u || !u->ic )
750                {
751                        irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] );
752                        return;
753                }
754                ic = u->ic;
755                cmd[2] = u->handle;
756        }
757        else if( !( a = account_get( irc, cmd[1] ) ) )
758        {
759                irc_usermsg( irc, "Invalid account" );
760                return;
761        }
762        else if( !( ( ic = a->ic ) && ( a->ic->flags & OPT_LOGGED_IN ) ) )
763        {
764                irc_usermsg( irc, "That account is not on-line" );
765                return;
766        }
767       
768        if( !ic->acc->prpl->rem_deny || !ic->acc->prpl->add_permit )
769        {
770                irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
771        }
772        else
773        {
774                imc_rem_block( ic, cmd[2] );
775                imc_add_allow( ic, cmd[2] );
776               
777                irc_usermsg( irc, "Buddy `%s' moved from your block- to your allow-list", cmd[2] );
778        }
779}
780
781static void cmd_yesno( irc_t *irc, char **cmd )
782{
783        query_t *q = NULL;
784        int numq = 0;
785       
786        if( irc->queries == NULL )
787        {
788                irc_usermsg( irc, "Did I ask you something?" );
789                return;
790        }
791       
792        /* If there's an argument, the user seems to want to answer another question than the
793           first/last (depending on the query_order setting) one. */
794        if( cmd[1] )
795        {
796                if( sscanf( cmd[1], "%d", &numq ) != 1 )
797                {
798                        irc_usermsg( irc, "Invalid query number" );
799                        return;
800                }
801               
802                for( q = irc->queries; q; q = q->next, numq -- )
803                        if( numq == 0 )
804                                break;
805               
806                if( !q )
807                {
808                        irc_usermsg( irc, "Uhm, I never asked you something like that..." );
809                        return;
810                }
811        }
812       
813        if( g_strcasecmp( cmd[0], "yes" ) == 0 )
814                query_answer( irc, q, 1 );
815        else if( g_strcasecmp( cmd[0], "no" ) == 0 )
816                query_answer( irc, q, 0 );
817}
818
819static void cmd_set( irc_t *irc, char **cmd )
820{
821        char *set_name = cmd[1];
822       
823        if( cmd[1] && cmd[2] )
824        {
825                if( g_strncasecmp( cmd[1], "-del", 4 ) == 0 )
826                {
827                        set_reset( &irc->set, cmd[2] );
828                        set_name = cmd[2];
829                }
830                else
831                {
832                        set_setstr( &irc->set, cmd[1], cmd[2] );
833                }
834        }
835        if( set_name ) /* else 'forgotten' on purpose.. Must show new value after changing */
836        {
837                char *s = set_getstr( &irc->set, set_name );
838                if( s )
839                        irc_usermsg( irc, "%s = `%s'", set_name, s );
840                else
841                        irc_usermsg( irc, "%s is empty", set_name );
842
843                if( strchr( set_name, '/' ) )
844                        irc_usermsg( irc, "Warning: / found in setting name, you're probably looking for the `account set' command." );
845        }
846        else
847        {
848                set_t *s = irc->set;
849                while( s )
850                {
851                        if( s->value || s->def )
852                                irc_usermsg( irc, "%s = `%s'", s->key, s->value ? s->value : s->def );
853                        else
854                                irc_usermsg( irc, "%s is empty", s->key );
855                        s = s->next;
856                }
857        }
858}
859
860static void cmd_save( irc_t *irc, char **cmd )
861{
862        if( storage_save( irc, TRUE ) == STORAGE_OK )
863                irc_usermsg( irc, "Configuration saved" );
864        else
865                irc_usermsg( irc, "Configuration could not be saved!" );
866}
867
868static void cmd_blist( irc_t *irc, char **cmd )
869{
870        int online = 0, away = 0, offline = 0;
871        user_t *u;
872        char s[256];
873        char *format;
874        int n_online = 0, n_away = 0, n_offline = 0;
875       
876        if( cmd[1] && g_strcasecmp( cmd[1], "all" ) == 0 )
877                online = offline = away = 1;
878        else if( cmd[1] && g_strcasecmp( cmd[1], "offline" ) == 0 )
879                offline = 1;
880        else if( cmd[1] && g_strcasecmp( cmd[1], "away" ) == 0 )
881                away = 1;
882        else if( cmd[1] && g_strcasecmp( cmd[1], "online" ) == 0 )
883                online = 1;
884        else
885                online =  away = 1;
886       
887        if( strchr( irc->umode, 'b' ) != NULL )
888                format = "%s\t%s\t%s";
889        else
890                format = "%-16.16s  %-40.40s  %s";
891       
892        irc_usermsg( irc, format, "Nick", "User/Host/Network", "Status" );
893       
894        for( u = irc->users; u; u = u->next ) if( u->ic && u->online && !u->away )
895        {
896                if( online == 1 )
897                {
898                        g_snprintf( s, sizeof( s ) - 1, "%s@%s %s(%s)", u->user, u->host, u->ic->acc->prpl->name, u->ic->acc->user );
899                        irc_usermsg( irc, format, u->nick, s, "Online" );
900                }
901               
902                n_online ++;
903        }
904
905        for( u = irc->users; u; u = u->next ) if( u->ic && u->online && u->away )
906        {
907                if( away == 1 )
908                {
909                        g_snprintf( s, sizeof( s ) - 1, "%s@%s %s(%s)", u->user, u->host, u->ic->acc->prpl->name, u->ic->acc->user );
910                        irc_usermsg( irc, format, u->nick, s, u->away );
911                }
912                n_away ++;
913        }
914       
915        for( u = irc->users; u; u = u->next ) if( u->ic && !u->online )
916        {
917                if( offline == 1 )
918                {
919                        g_snprintf( s, sizeof( s ) - 1, "%s@%s %s(%s)", u->user, u->host, u->ic->acc->prpl->name, u->ic->acc->user );
920                        irc_usermsg( irc, format, u->nick, s, "Offline" );
921                }
922                n_offline ++;
923        }
924       
925        irc_usermsg( irc, "%d buddies (%d available, %d away, %d offline)", n_online + n_away + n_offline, n_online, n_away, n_offline );
926}
927
928static void cmd_nick( irc_t *irc, char **cmd ) 
929{
930        account_t *a;
931
932        if( !cmd[1] || !( a = account_get( irc, cmd[1] ) ) )
933        {
934                irc_usermsg( irc, "Invalid account");
935        }
936        else if( !( a->ic && ( a->ic->flags & OPT_LOGGED_IN ) ) )
937        {
938                irc_usermsg( irc, "That account is not on-line" );
939        }
940        else if ( !cmd[2] ) 
941        {
942                irc_usermsg( irc, "Your name is `%s'" , a->ic->displayname ? a->ic->displayname : "NULL" );
943        }
944        else if ( !a->prpl->set_my_name ) 
945        {
946                irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
947        }
948        else
949        {
950                irc_usermsg( irc, "Setting your name to `%s'", cmd[2] );
951               
952                a->prpl->set_my_name( a->ic, cmd[2] );
953        }
954}
955
956static void cmd_qlist( irc_t *irc, char **cmd )
957{
958        query_t *q = irc->queries;
959        int num;
960       
961        if( !q )
962        {
963                irc_usermsg( irc, "There are no pending questions." );
964                return;
965        }
966       
967        irc_usermsg( irc, "Pending queries:" );
968       
969        for( num = 0; q; q = q->next, num ++ )
970                if( q->ic ) /* Not necessary yet, but it might come later */
971                        irc_usermsg( irc, "%d, %s(%s): %s", num, q->ic->acc->prpl->name, q->ic->acc->user, q->question );
972                else
973                        irc_usermsg( irc, "%d, BitlBee: %s", num, q->question );
974}
975
976static void cmd_join_chat( irc_t *irc, char **cmd )
977{
978        account_t *a;
979        struct im_connection *ic;
980        char *chat, *channel, *nick = NULL, *password = NULL;
981        struct groupchat *c;
982       
983        if( !( a = account_get( irc, cmd[1] ) ) )
984        {
985                irc_usermsg( irc, "Invalid account" );
986                return;
987        }
988        else if( !( a->ic && ( a->ic->flags & OPT_LOGGED_IN ) ) )
989        {
990                irc_usermsg( irc, "That account is not on-line" );
991                return;
992        }
993        else if( a->prpl->chat_join == NULL )
994        {
995                irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
996                return;
997        }
998        ic = a->ic;
999       
1000        chat = cmd[2];
1001        if( cmd[3] )
1002        {
1003                if( cmd[3][0] != '#' && cmd[3][0] != '&' )
1004                        channel = g_strdup_printf( "&%s", cmd[3] );
1005                else
1006                        channel = g_strdup( cmd[3] );
1007        }
1008        else
1009        {
1010                char *s;
1011               
1012                channel = g_strdup_printf( "&%s", chat );
1013                if( ( s = strchr( channel, '@' ) ) )
1014                        *s = 0;
1015        }
1016        if( cmd[3] && cmd[4] )
1017                nick = cmd[4];
1018        else
1019                nick = irc->nick;
1020        if( cmd[3] && cmd[4] && cmd[5] )
1021                password = cmd[5];
1022       
1023        if( !nick_ok( channel + 1 ) )
1024        {
1025                irc_usermsg( irc, "Invalid channel name: %s", channel );
1026                g_free( channel );
1027                return;
1028        }
1029        else if( g_strcasecmp( channel, irc->channel ) == 0 || irc_chat_by_channel( irc, channel ) )
1030        {
1031                irc_usermsg( irc, "Channel already exists: %s", channel );
1032                g_free( channel );
1033                return;
1034        }
1035       
1036        if( ( c = a->prpl->chat_join( ic, chat, nick, password ) ) )
1037        {
1038                g_free( c->channel );
1039                c->channel = channel;
1040        }
1041        else
1042        {
1043                irc_usermsg( irc, "Tried to join chat, not sure if this was successful" );
1044                g_free( channel );
1045        }
1046}
1047
1048const command_t commands[] = {
1049        { "help",           0, cmd_help,           0 }, 
1050        { "identify",       1, cmd_identify,       0 },
1051        { "register",       1, cmd_register,       0 },
1052        { "drop",           1, cmd_drop,           0 },
1053        { "account",        1, cmd_account,        0 },
1054        { "add",            2, cmd_add,            0 },
1055        { "info",           1, cmd_info,           0 },
1056        { "rename",         2, cmd_rename,         0 },
1057        { "remove",         1, cmd_remove,         0 },
1058        { "block",          1, cmd_block,          0 },
1059        { "allow",          1, cmd_allow,          0 },
1060        { "save",           0, cmd_save,           0 },
1061        { "set",            0, cmd_set,            0 },
1062        { "yes",            0, cmd_yesno,          0 },
1063        { "no",             0, cmd_yesno,          0 },
1064        { "blist",          0, cmd_blist,          0 },
1065        { "nick",           1, cmd_nick,           0 },
1066        { "qlist",          0, cmd_qlist,          0 },
1067        { "join_chat",      2, cmd_join_chat,      0 },
1068        { NULL }
1069};
Note: See TracBrowser for help on using the repository browser.