source: storage.c @ e4c3041

Last change on this file since e4c3041 was 5ebff60, checked in by dequis <dx@…>, at 2015-02-20T22:50:54Z

Reindent everything to K&R style with tabs

Used uncrustify, with the configuration file in ./doc/uncrustify.cfg

Commit author set to "Indent <please@…>" so that it's easier to
skip while doing git blame.

  • 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
53        if (gl == NULL) {
54                return NULL;
55        }
56
57        if (st->init) {
58                st->init();
59        }
60
61        return st;
62}
63
64GList *storage_init(const char *primary, char **migrate)
65{
66        GList *ret = NULL;
67        int i;
68        storage_t *storage;
69
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
77        ret = g_list_append(ret, storage);
78
79        for (i = 0; migrate && migrate[i]; i++) {
80                storage = storage_init_single(migrate[i]);
81
82                if (storage) {
83                        ret = g_list_append(ret, storage);
84                }
85        }
86
87        return ret;
88}
89
90storage_status_t storage_check_pass(const char *nick, const char *password)
91{
92        GList *gl;
93
94        /* Loop until we don't get NO_SUCH_USER */
95
96        for (gl = global.storage; gl; gl = gl->next) {
97                storage_t *st = gl->data;
98                storage_status_t status;
99
100                status = st->check_pass(nick, password);
101                if (status != STORAGE_NO_SUCH_USER) {
102                        return status;
103                }
104        }
105
106        return STORAGE_NO_SUCH_USER;
107}
108
109storage_status_t storage_load(irc_t * irc, const char *password)
110{
111        GList *gl;
112
113        if (irc && irc->status & USTATUS_IDENTIFIED) {
114                return STORAGE_OTHER_ERROR;
115        }
116
117        /* Loop until we don't get NO_SUCH_USER */
118        for (gl = global.storage; gl; gl = gl->next) {
119                storage_t *st = gl->data;
120                storage_status_t status;
121
122                status = st->load(irc, password);
123                if (status == STORAGE_OK) {
124                        GSList *l;
125                        for (l = irc_plugins; l; l = l->next) {
126                                irc_plugin_t *p = l->data;
127                                if (p->storage_load) {
128                                        p->storage_load(irc);
129                                }
130                        }
131                        return status;
132                }
133
134                if (status != STORAGE_NO_SUCH_USER) {
135                        return status;
136                }
137        }
138
139        return STORAGE_NO_SUCH_USER;
140}
141
142storage_status_t storage_save(irc_t *irc, char *password, int overwrite)
143{
144        storage_status_t st;
145        GSList *l;
146
147        if (password != NULL) {
148                /* Should only use this in the "register" command. */
149                if (irc->password || overwrite) {
150                        return STORAGE_OTHER_ERROR;
151                }
152
153                irc_setpass(irc, password);
154        } else if ((irc->status & USTATUS_IDENTIFIED) == 0) {
155                return STORAGE_NO_SUCH_USER;
156        }
157
158        st = ((storage_t *) global.storage->data)->save(irc, overwrite);
159
160        for (l = irc_plugins; l; l = l->next) {
161                irc_plugin_t *p = l->data;
162                if (p->storage_save) {
163                        p->storage_save(irc);
164                }
165        }
166
167        if (password != NULL) {
168                irc_setpass(irc, NULL);
169        }
170
171        return st;
172}
173
174storage_status_t storage_remove(const char *nick, const char *password)
175{
176        GList *gl;
177        storage_status_t ret = STORAGE_OK;
178        gboolean ok = FALSE;
179        GSList *l;
180
181        /* Remove this account from all storage backends. If this isn't
182         * done, the account will still be usable, it'd just be
183         * loaded from a different backend. */
184        for (gl = global.storage; gl; gl = gl->next) {
185                storage_t *st = gl->data;
186                storage_status_t status;
187
188                status = st->remove(nick, password);
189                ok |= status == STORAGE_OK;
190                if (status != STORAGE_NO_SUCH_USER && status != STORAGE_OK) {
191                        ret = status;
192                }
193        }
194
195        /* If at least one succeeded, remove plugin data. */
196        if (ok) {
197                for (l = irc_plugins; l; l = l->next) {
198                        irc_plugin_t *p = l->data;
199                        if (p->storage_remove) {
200                                p->storage_remove(nick);
201                        }
202                }
203        }
204
205        return ret;
206}
Note: See TracBrowser for help on using the repository browser.