source: storage.c @ b95932e

Last change on this file since b95932e was ba7d16f, checked in by Wilmer van der Gaast <wilmer@…>, at 2010-03-24T17:12:53Z

Now seems like a pretty good time to finally kill crypting.c and storage_text.
This means people won't be able to upgrade from BitlBee 1.0 to this version
anymore but only via 1.2.

1.0 is old enough that I don't really expect this to be a problem.

  • Property mode set to 100644
File size: 5.1 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/* Copyright (C) 2005 Jelmer Vernooij <jelmer@samba.org> */
10
11/*
12  This program is free software; you can redistribute it and/or modify
13  it under the terms of the GNU General Public License as published by
14  the Free Software Foundation; either version 2 of the License, or
15  (at your option) any later version.
16
17  This program is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  GNU General Public License for more details.
21
22  You should have received a copy of the GNU General Public License with
23  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
24  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
25  Suite 330, Boston, MA  02111-1307  USA
26*/
27
28#define BITLBEE_CORE
29#include "bitlbee.h"
30
31extern storage_t storage_text;
32extern storage_t storage_xml;
33
34static GList *storage_backends = NULL;
35
36void register_storage_backend(storage_t *backend)
37{
38        storage_backends = g_list_append(storage_backends, backend);
39}
40
41static storage_t *storage_init_single(const char *name)
42{
43        GList *gl;
44        storage_t *st = NULL;
45
46        for (gl = storage_backends; gl; gl = gl->next) {
47                st = gl->data;
48                if (strcmp(st->name, name) == 0)
49                        break;
50        }
51
52        if (gl == NULL) 
53                return NULL;
54
55        if (st->init)
56                st->init();
57
58        return st;
59}
60
61GList *storage_init(const char *primary, char **migrate)
62{
63        GList *ret = NULL;
64        int i;
65        storage_t *storage;
66       
67        register_storage_backend(&storage_xml);
68       
69        storage = storage_init_single(primary);
70        if (storage == NULL && storage->save == NULL)
71                return NULL;
72
73        ret = g_list_append(ret, storage);
74
75        for (i = 0; migrate && migrate[i]; i++) {
76                storage = storage_init_single(migrate[i]);
77       
78                if (storage)
79                        ret = g_list_append(ret, storage);
80        }
81
82        return ret;
83}
84
85storage_status_t storage_check_pass (const char *nick, const char *password)
86{
87        GList *gl;
88       
89        /* Loop until we don't get NO_SUCH_USER */
90
91        for (gl = global.storage; gl; gl = gl->next) {
92                storage_t *st = gl->data;
93                storage_status_t status;
94
95                status = st->check_pass(nick, password);
96                if (status != STORAGE_NO_SUCH_USER)
97                        return status;
98        }
99       
100        return STORAGE_NO_SUCH_USER;
101}
102
103storage_status_t storage_load (irc_t * irc, const char *password)
104{
105        GList *gl;
106       
107        if (irc && irc->status & USTATUS_IDENTIFIED)
108                return STORAGE_OTHER_ERROR;
109       
110        /* Loop until we don't get NO_SUCH_USER */
111        for (gl = global.storage; gl; gl = gl->next) {
112                storage_t *st = gl->data;
113                storage_status_t status;
114
115                status = st->load(irc, password);
116                if (status == STORAGE_OK)
117                        return status;
118               
119                if (status != STORAGE_NO_SUCH_USER) 
120                        return status;
121        }
122       
123        return STORAGE_NO_SUCH_USER;
124}
125
126storage_status_t storage_save (irc_t *irc, char *password, int overwrite)
127{
128        storage_status_t st;
129       
130        if (password != NULL) {
131                /* Should only use this in the "register" command. */
132                if (irc->password || overwrite)
133                        return STORAGE_OTHER_ERROR;
134               
135                irc_setpass(irc, password);
136        } else if ((irc->status & USTATUS_IDENTIFIED) == 0) {
137                return STORAGE_NO_SUCH_USER;
138        }
139       
140        st = ((storage_t *)global.storage->data)->save(irc, overwrite);
141       
142        if (password != NULL) {
143                irc_setpass(irc, NULL);
144        }
145       
146        return st;
147}
148
149storage_status_t storage_remove (const char *nick, const char *password)
150{
151        GList *gl;
152        storage_status_t ret = STORAGE_OK;
153       
154        /* Remove this account from all storage backends. If this isn't
155         * done, the account will still be usable, it'd just be
156         * loaded from a different backend. */
157        for (gl = global.storage; gl; gl = gl->next) {
158                storage_t *st = gl->data;
159                storage_status_t status;
160
161                status = st->remove(nick, password);
162                if (status != STORAGE_NO_SUCH_USER && status != STORAGE_OK)
163                        ret = status;
164        }
165       
166        return ret;
167}
168
169#if 0
170Not using this yet. Test thoroughly before adding UI hooks to this function.
171
172storage_status_t storage_rename (const char *onick, const char *nnick, const char *password)
173{
174        storage_status_t status;
175        GList *gl = global.storage;
176        storage_t *primary_storage = gl->data;
177        irc_t *irc;
178
179        /* First, try to rename in the current write backend, assuming onick
180         * is stored there */
181        status = primary_storage->rename(onick, nnick, password);
182        if (status != STORAGE_NO_SUCH_USER)
183                return status;
184
185        /* Try to load from a migration backend and save to the current backend.
186         * Explicitly remove the account from the migration backend as otherwise
187         * it'd still be usable under the old name */
188       
189        irc = g_new0(irc_t, 1);
190        status = storage_load(onick, password, irc);
191        if (status != STORAGE_OK) {
192                irc_free(irc);
193                return status;
194        }
195
196        g_free(irc->nick);
197        irc->nick = g_strdup(nnick);
198
199        status = storage_save(irc, FALSE);
200        if (status != STORAGE_OK) {
201                irc_free(irc);
202                return status;
203        }
204        irc_free(irc);
205
206        storage_remove(onick, password);
207
208        return STORAGE_OK;
209}
210#endif
Note: See TracBrowser for help on using the repository browser.