source: storage.c @ 5d9b792

Last change on this file since 5d9b792 was b73ac9c, checked in by Jelmer Vernooij <jelmer@…>, at 2005-12-13T23:05:27Z

Add support for 'primary' and 'migrate' account storages.
Fix two bugs in the text storage backend that were introduced by my previous
changes.

  • Property mode set to 100644
File size: 4.5 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/* Support for multiple storage backends */
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 "crypting.h"
29
30extern storage_t storage_text;
31
32static GList text_entry = { &storage_text, NULL, NULL };
33static GList *storage_backends = &text_entry;
34
35void register_storage_backend(storage_t *backend)
36{
37        storage_backends = g_list_append(storage_backends, backend);
38}
39
40static storage_t *storage_init_single(const char *name)
41{
42        GList *gl;
43        storage_t *st;
44
45        for (gl = storage_backends; gl; gl = gl->next) {
46                st = gl->data;
47                if (strcmp(st->name, name) == 0)
48                        break;
49        }
50
51        if (gl == NULL) 
52                return NULL;
53
54        if (st->init)
55                st->init();
56
57        return st;
58}
59
60GList *storage_init(const char *primary, char **migrate)
61{
62        GList *ret = NULL;
63        int i;
64        storage_t *storage;
65
66        storage = storage_init_single(primary);
67        if (storage == NULL)
68                return NULL;
69
70        ret = g_list_append(ret, storage);
71
72        for (i = 0; migrate && migrate[i]; i++) {
73                storage = storage_init_single(migrate[i]);
74       
75                if (storage)
76                        ret = g_list_append(ret, storage);
77        }
78
79        return ret;
80}
81
82storage_status_t storage_check_pass (const char *nick, const char *password)
83{
84        GList *gl;
85       
86        /* Loop until we don't get NO_SUCH_USER */
87
88        for (gl = global.storage; gl; gl = gl->next) {
89                storage_t *st = gl->data;
90                storage_status_t status;
91
92                status = st->check_pass(nick, password);
93                if (status != STORAGE_NO_SUCH_USER)
94                        return status;
95        }
96       
97        return STORAGE_NO_SUCH_USER;
98}
99
100storage_status_t storage_load (const char *nick, const char *password, irc_t * irc)
101{
102        GList *gl;
103       
104        /* Loop until we don't get NO_SUCH_USER */
105        for (gl = global.storage; gl; gl = gl->next) {
106                storage_t *st = gl->data;
107                storage_status_t status;
108
109                status = st->load(nick, password, irc);
110                if (status == STORAGE_OK) {
111                        irc_setpass(irc, password);
112                        return status;
113                }
114               
115                if (status != STORAGE_NO_SUCH_USER) 
116                        return status;
117        }
118       
119        return STORAGE_NO_SUCH_USER;
120}
121
122storage_status_t storage_save (irc_t *irc, int overwrite)
123{
124        return ((storage_t *)global.storage->data)->save(irc, overwrite);
125}
126
127storage_status_t storage_remove (const char *nick, const char *password)
128{
129        GList *gl;
130        storage_status_t ret = STORAGE_OK;
131       
132        /* Remove this account from all storage backends. If this isn't
133         * done, the account will still be usable, it'd just be
134         * loaded from a different backend. */
135        for (gl = global.storage; gl; gl = gl->next) {
136                storage_t *st = gl->data;
137                storage_status_t status;
138
139                status = st->remove(nick, password);
140                if (status != STORAGE_NO_SUCH_USER && 
141                        status != STORAGE_OK)
142                        ret = status;
143        }
144       
145        return ret;
146}
147
148storage_status_t storage_rename (const char *onick, const char *nnick, const char *password)
149{
150        storage_status_t status;
151        GList *gl = global.storage;
152        storage_t *primary_storage = gl->data;
153        irc_t *irc;
154
155        /* First, try to rename in the current write backend, assuming onick
156         * is stored there */
157        status = primary_storage->rename(onick, nnick, password);
158        if (status != STORAGE_NO_SUCH_USER)
159                return status;
160
161        /* Try to load from a migration backend and save to the current backend.
162         * Explicitly remove the account from the migration backend as otherwise
163         * it'd still be usable under the old name */
164       
165        irc = g_new0(irc_t, 1);
166        status = storage_load(onick, password, irc);
167        if (status != STORAGE_OK) {
168                irc_free(irc);
169                return status;
170        }
171
172        g_free(irc->nick);
173        irc->nick = g_strdup(nnick);
174
175        status = storage_save(irc, FALSE);
176        if (status != STORAGE_OK) {
177                irc_free(irc);
178                return status;
179        }
180        irc_free(irc);
181
182        storage_remove(onick, password);
183
184        return STORAGE_OK;
185}
Note: See TracBrowser for help on using the repository browser.