source: account.c @ deff040

Last change on this file since deff040 was 04026d4, checked in by Wilmer van der Gaast <wilmer@…>, at 2006-07-15T17:26:13Z

Fixed a broken call to set_get() (CRASH), shut up a compiler warning in
events_glib and now using the right evaluator for acc->"auto_reconnect".

  • Property mode set to 100644
File size: 5.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/* Account management functions                                         */
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 "bitlbee.h"
28#include "account.h"
29
30account_t *account_add( irc_t *irc, struct prpl *prpl, char *user, char *pass )
31{
32        account_t *a;
33        set_t *s;
34       
35        if( irc->accounts )
36        {
37                for( a = irc->accounts; a->next; a = a->next );
38                a = a->next = g_new0( account_t, 1 );
39        }
40        else
41        {
42                irc->accounts = a = g_new0 ( account_t, 1 );
43        }
44       
45        a->prpl = prpl;
46        a->user = g_strdup( user );
47        a->pass = g_strdup( pass );
48        a->auto_connect = 1;
49        a->irc = irc;
50       
51        s = set_add( &a->set, "auto_connect", "true", set_eval_account, a );
52        s->flags |= ACC_SET_NOSAVE;
53       
54        s = set_add( &a->set, "auto_reconnect", "true", set_eval_bool, a );
55       
56        s = set_add( &a->set, "password", NULL, set_eval_account, a );
57        s->flags |= ACC_SET_NOSAVE;
58       
59        s = set_add( &a->set, "username", NULL, set_eval_account, a );
60        s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY;
61        set_setstr( &a->set, "username", user );
62       
63        a->nicks = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, g_free );
64       
65        /* This function adds some more settings (and might want to do more
66           things that have to be done now, although I can't think of anything. */
67        if( prpl->acc_init )
68                prpl->acc_init( a );
69       
70        return( a );
71}
72
73char *set_eval_account( set_t *set, char *value )
74{
75        account_t *acc = set->data;
76       
77        /* Double-check: We refuse to edit on-line accounts. */
78        if( set->flags & ACC_SET_OFFLINE_ONLY && acc->gc )
79                return NULL;
80       
81        if( strcmp( set->key, "username" ) == 0 )
82        {
83                g_free( acc->user );
84                acc->user = g_strdup( value );
85                return value;
86        }
87        else if( strcmp( set->key, "password" ) == 0 )
88        {
89                g_free( acc->pass );
90                acc->pass = g_strdup( value );
91                return NULL;    /* password shouldn't be visible in plaintext! */
92        }
93        else if( strcmp( set->key, "server" ) == 0 )
94        {
95                g_free( acc->server );
96                if( *value )
97                        acc->server = g_strdup( value );
98                else
99                        acc->server = NULL;
100                return value;
101        }
102        else if( strcmp( set->key, "auto_connect" ) == 0 )
103        {
104                if( !is_bool( value ) )
105                        return NULL;
106               
107                acc->auto_connect = bool2int( value );
108                return value;
109        }
110       
111        return NULL;
112}
113
114account_t *account_get( irc_t *irc, char *id )
115{
116        account_t *a, *ret = NULL;
117        char *handle, *s;
118        int nr;
119       
120        /* This checks if the id string ends with (...) */
121        if( ( handle = strchr( id, '(' ) ) && ( s = strchr( handle, ')' ) ) && s[1] == 0 )
122        {
123                struct prpl *proto;
124               
125                *s = *handle = 0;
126                handle ++;
127               
128                if( ( proto = find_protocol( id ) ) )
129                {
130                        for( a = irc->accounts; a; a = a->next )
131                                if( a->prpl == proto &&
132                                    a->prpl->handle_cmp( handle, a->user ) == 0 )
133                                        ret = a;
134                }
135               
136                /* Restore the string. */
137                handle --;
138                *handle = '(';
139                *s = ')';
140               
141                if( ret )
142                        return ret;
143        }
144       
145        if( sscanf( id, "%d", &nr ) == 1 && nr < 1000 )
146        {
147                for( a = irc->accounts; a; a = a->next )
148                        if( ( nr-- ) == 0 )
149                                return( a );
150               
151                return( NULL );
152        }
153       
154        for( a = irc->accounts; a; a = a->next )
155        {
156                if( g_strcasecmp( id, a->prpl->name ) == 0 )
157                {
158                        if( !ret )
159                                ret = a;
160                        else
161                                return( NULL ); /* We don't want to match more than one... */
162                }
163                else if( strstr( a->user, id ) )
164                {
165                        if( !ret )
166                                ret = a;
167                        else
168                                return( NULL );
169                }
170        }
171       
172        return( ret );
173}
174
175void account_del( irc_t *irc, account_t *acc )
176{
177        account_t *a, *l = NULL;
178       
179        for( a = irc->accounts; a; a = (l=a)->next )
180                if( a == acc )
181                {
182                        if( a->gc ) return; /* Caller should have checked, accounts still in use can't be deleted. */
183                       
184                        if( l )
185                        {
186                                l->next = a->next;
187                        }
188                        else
189                        {
190                                irc->accounts = a->next;
191                        }
192                       
193                        while( a->set )
194                                set_del( &a->set, a->set->key );
195                       
196                        g_hash_table_destroy( a->nicks );
197                       
198                        g_free( a->user );
199                        g_free( a->pass );
200                        if( a->server ) g_free( a->server );
201                        if( a->reconnect )      /* This prevents any reconnect still queued to happen */
202                                cancel_auto_reconnect( a );
203                        g_free( a );
204                       
205                        break;
206                }
207}
208
209void account_on( irc_t *irc, account_t *a )
210{
211        if( a->gc )
212        {
213                /* Trying to enable an already-enabled account */
214                return;
215        }
216       
217        cancel_auto_reconnect( a );
218       
219        a->reconnect = 0;
220        a->prpl->login( a );
221}
222
223void account_off( irc_t *irc, account_t *a )
224{
225        a->gc->wants_to_die = TRUE;
226        signoff( a->gc );
227        a->gc = NULL;
228        if( a->reconnect )
229        {
230                /* Shouldn't happen */
231                cancel_auto_reconnect( a );
232        }
233}
Note: See TracBrowser for help on using the repository browser.