source: storage.c @ fa1bc1d

Last change on this file since fa1bc1d was 90a45b8, checked in by dequis <dx@…>, at 2016-12-26T22:38:32Z

Fix some clang static analyzer warnings

Nothing interesting.

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