source: storage.c @ 5eab298f

Last change on this file since 5eab298f was 6f10697, checked in by dequis <dx@…>, at 2015-01-16T19:50:23Z

Fix incorrect Free Software Foundation address

  • Property mode set to 100644
File size: 4.6 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., 51 Franklin St.,
25  Fifth Floor, Boston, MA  02110-1301  USA
26*/
27
28#define BITLBEE_CORE
29#include "bitlbee.h"
30
31extern storage_t storage_text;
32extern storage_t storage_xml;
33
34static GList *storage_backends = NULL;
35
36void register_storage_backend(storage_t *backend)
37{
38        storage_backends = g_list_append(storage_backends, backend);
39}
40
41static storage_t *storage_init_single(const char *name)
42{
43        GList *gl;
44        storage_t *st = NULL;
45
46        for (gl = storage_backends; gl; gl = gl->next) {
47                st = gl->data;
48                if (strcmp(st->name, name) == 0)
49                        break;
50        }
51
52        if (gl == NULL) 
53                return NULL;
54
55        if (st->init)
56                st->init();
57
58        return st;
59}
60
61GList *storage_init(const char *primary, char **migrate)
62{
63        GList *ret = NULL;
64        int i;
65        storage_t *storage;
66       
67        register_storage_backend(&storage_xml);
68       
69        storage = storage_init_single(primary);
70        if (storage == NULL && storage->save == NULL)
71                return NULL;
72
73        ret = g_list_append(ret, storage);
74
75        for (i = 0; migrate && migrate[i]; i++) {
76                storage = storage_init_single(migrate[i]);
77       
78                if (storage)
79                        ret = g_list_append(ret, storage);
80        }
81
82        return ret;
83}
84
85storage_status_t storage_check_pass (const char *nick, const char *password)
86{
87        GList *gl;
88       
89        /* Loop until we don't get NO_SUCH_USER */
90
91        for (gl = global.storage; gl; gl = gl->next) {
92                storage_t *st = gl->data;
93                storage_status_t status;
94
95                status = st->check_pass(nick, password);
96                if (status != STORAGE_NO_SUCH_USER)
97                        return status;
98        }
99       
100        return STORAGE_NO_SUCH_USER;
101}
102
103storage_status_t storage_load (irc_t * irc, const char *password)
104{
105        GList *gl;
106       
107        if (irc && irc->status & USTATUS_IDENTIFIED)
108                return STORAGE_OTHER_ERROR;
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(irc, password);
116                if (status == STORAGE_OK)
117                {
118                        GSList *l;
119                        for( l = irc_plugins; l; l = l->next )
120                        {
121                                irc_plugin_t *p = l->data;
122                                if( p->storage_load )
123                                        p->storage_load( irc );
124                        }
125                        return status;
126                }
127               
128                if (status != STORAGE_NO_SUCH_USER) 
129                        return status;
130        }
131       
132        return STORAGE_NO_SUCH_USER;
133}
134
135storage_status_t storage_save (irc_t *irc, char *password, int overwrite)
136{
137        storage_status_t st;
138        GSList *l;
139       
140        if (password != NULL) {
141                /* Should only use this in the "register" command. */
142                if (irc->password || overwrite)
143                        return STORAGE_OTHER_ERROR;
144               
145                irc_setpass(irc, password);
146        } else if ((irc->status & USTATUS_IDENTIFIED) == 0) {
147                return STORAGE_NO_SUCH_USER;
148        }
149       
150        st = ((storage_t *)global.storage->data)->save(irc, overwrite);
151       
152        for( l = irc_plugins; l; l = l->next )
153        {
154                irc_plugin_t *p = l->data;
155                if( p->storage_save )
156                        p->storage_save( irc );
157        }
158       
159        if (password != NULL) {
160                irc_setpass(irc, NULL);
161        }
162       
163        return st;
164}
165
166storage_status_t storage_remove (const char *nick, const char *password)
167{
168        GList *gl;
169        storage_status_t ret = STORAGE_OK;
170        gboolean ok = FALSE;
171        GSList *l;
172       
173        /* Remove this account from all storage backends. If this isn't
174         * done, the account will still be usable, it'd just be
175         * loaded from a different backend. */
176        for (gl = global.storage; gl; gl = gl->next) {
177                storage_t *st = gl->data;
178                storage_status_t status;
179
180                status = st->remove(nick, password);
181                ok |= status == STORAGE_OK;
182                if (status != STORAGE_NO_SUCH_USER && status != STORAGE_OK)
183                        ret = status;
184        }
185       
186        /* If at least one succeeded, remove plugin data. */
187        if( ok )
188                for( l = irc_plugins; l; l = l->next )
189                {
190                        irc_plugin_t *p = l->data;
191                        if( p->storage_remove )
192                                p->storage_remove( nick );
193                }
194       
195        return ret;
196}
Note: See TracBrowser for help on using the repository browser.