source: storage.c @ 911f2eb

Last change on this file since 911f2eb was b3c467b, checked in by Wilmer van der Gaast <wilmer@…>, at 2006-06-28T09:59:33Z

Cleaned up Makefiles + configure: Cleaning up bitlbee.pc, removed the second
piece of libevent probing code that mysteriously appeared (?), better handling
of storage backends, an SSL module is now always included (so BitlBee can be
compiled again when building without MSN- and Jabber-support (http_client also
depends on SSL libs and can't be disabled)), oh, and fixed a compiler warning.

  • 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)
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.