source: storage.c @ be999a5

Last change on this file since be999a5 was be999a5, checked in by Wilmer van der Gaast <wilmer@…>, at 2010-08-23T23:12:24Z

First step in this merge. Mostly a bzr merge and then a cleanup of conflicts
and parts I want to/have to redo (because of ui-fix).

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