source: root_commands.c @ 990d5fd

Last change on this file since 990d5fd was 7f421d6, checked in by Wilmer van der Gaast <wilmer@…>, at 2008-03-03T23:18:36Z

BitlBee <= 1.0 didn't have "account set" and allowed one to delete an account
and re-create it with new login settings if necessary, without losing custom
nicknames. Now, nicknames are connected to an account instead of just the
protocol, and they're flushed together with the account. So I added a warning
to make sure nobody accidentally loses any settings while just changing the
password. This will probably go after a few releases, since it's slightly
annoying.

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