source: root_commands.c @ 08135df

Last change on this file since 08135df was 2c2df7d, checked in by ulim <a.sporto+bee@…>, at 2007-11-28T21:07:30Z

Initial import of jabber file receive and DCC send support. This introduces
only a few changes to bitlbees code, mainly the addition of the "transfers"
command.

This is known to work with Kopete, Psi, and Pidgin (formerly known as gaim).
At least with Pidgin also over a proxy. DCC has only been tested with irssi.
IPV6 is untested but should work.

Currently, only receiving via SOCKS5BYTESREAMS is implemented. I'm not sure if
the alternative(in-band bytestreams IBB) is worth implementing since I didn't
see a client yet that can do it. Additionally, it is probably very slow and
needs support by the server as well.

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