source: storage.c @ af97b23

Last change on this file since af97b23 was 7e3592e, checked in by Wilmer van der Gaast <wilmer@…>, at 2006-07-05T18:34:31Z

Fixed text_load(), added detection of primary storage backends without
save support (which shouldn't be allowed) and added a call to nick_lc()
to xml_save() so at least nicks should now be case-insensitive.

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