source: storage.c @ bb09b3c

Last change on this file since bb09b3c was 673a54c, checked in by Sven Moritz Hallberg <pesco@…>, at 2009-03-12T19:33:28Z

pretty blind try at merging in the latest trunk

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