source: account.c @ 5b52a48

Last change on this file since 5b52a48 was 5b52a48, checked in by Wilmer van der Gaast <wilmer@…>, at 2006-07-03T21:22:45Z

Implemented per-account nick lists instead of per-protocol nick lists.
nick_t is dead, instead nicks are just saves in a per-account_t GLib
hash table. While doing this, the import_buddies command finally died
and text_save() disappeared, because the old file format can't handle
most of the new features in this branch anyway.

Still have to implement support for the new nick lists in text_load()!

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