source: storage.c @ 9730d72

Last change on this file since 9730d72 was 764c7d1, checked in by Sven Moritz Hallberg <sm@…>, at 2008-02-03T21:30:03Z

OTR support, first checkin

  • Property mode set to 100644
File size: 4.9 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 (const char *nick, const char *password, irc_t * irc)
107{
108        GList *gl;
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(nick, password, irc);
116                if (status == STORAGE_OK) {
117                        irc_setpass(irc, password);
118                        otr_load(irc);          /* load our OTR userstate */
119                        return status;
120                }
121               
122                if (status != STORAGE_NO_SUCH_USER) {
123                        return status;
124                }
125        }
126       
127        return STORAGE_NO_SUCH_USER;
128}
129
130storage_status_t storage_save (irc_t *irc, int overwrite)
131{
132        storage_status_t st;
133       
134        otr_save(irc);
135        st = ((storage_t *)global.storage->data)->save(irc, overwrite);
136        return st;
137}
138
139storage_status_t storage_remove (const char *nick, const char *password)
140{
141        GList *gl;
142        storage_status_t ret = STORAGE_OK;
143       
144        /* Remove this account from all storage backends. If this isn't
145         * done, the account will still be usable, it'd just be
146         * loaded from a different backend. */
147        for (gl = global.storage; gl; gl = gl->next) {
148                storage_t *st = gl->data;
149                storage_status_t status;
150
151                status = st->remove(nick, password);
152                if (status != STORAGE_NO_SUCH_USER && 
153                        status != STORAGE_OK)
154                        ret = status;
155        }
156        if (ret == STORAGE_OK) {
157                otr_remove(nick);
158        }
159       
160        return ret;
161}
162
163storage_status_t storage_rename (const char *onick, const char *nnick, const char *password)
164{
165        storage_status_t status;
166        GList *gl = global.storage;
167        storage_t *primary_storage = gl->data;
168        irc_t *irc;
169       
170        /* First, try to rename in the current write backend, assuming onick
171         * is stored there */
172        status = primary_storage->rename(onick, nnick, password);
173        if (status != STORAGE_NO_SUCH_USER) {
174                otr_rename(onick, nnick);
175                return status;
176        }
177
178        /* Try to load from a migration backend and save to the current backend.
179         * Explicitly remove the account from the migration backend as otherwise
180         * it'd still be usable under the old name */
181       
182        irc = g_new0(irc_t, 1);
183        status = storage_load(onick, password, irc);
184        if (status != STORAGE_OK) {
185                irc_free(irc);
186                return status;
187        }
188
189        g_free(irc->nick);
190        irc->nick = g_strdup(nnick);
191
192        status = storage_save(irc, FALSE);
193        if (status != STORAGE_OK) {
194                irc_free(irc);
195                return status;
196        }
197        irc_free(irc);
198
199        storage_remove(onick, password);
200        otr_rename(onick, nnick);
201
202        return STORAGE_OK;
203}
Note: See TracBrowser for help on using the repository browser.