source: storage.c @ 537d9b9

Last change on this file since 537d9b9 was 537d9b9, checked in by dequis <dx@…>, at 2016-11-20T08:40:36Z

Merge master up to commit '9f03c47' into parson

  • Property mode set to 100644
File size: 4.6 KB
RevLine 
[5ebff60]1/********************************************************************\
[1ee6c18]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
[d9d36fc]9/* Copyright (C) 2005 Jelmer Vernooij <jelmer@samba.org> */
10
[1ee6c18]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;
[6f10697]24  if not, write to the Free Software Foundation, Inc., 51 Franklin St.,
25  Fifth Floor, Boston, MA  02110-1301  USA
[1ee6c18]26*/
27
28#define BITLBEE_CORE
29#include "bitlbee.h"
30
[c121f89]31extern storage_t storage_xml;
[1ee6c18]32
[c121f89]33static GList *storage_backends = NULL;
[1ee6c18]34
[d628339]35const struct prpl protocol_missing = {
36        .name = "_unknown",
37};
38
[1ee6c18]39void register_storage_backend(storage_t *backend)
40{
41        storage_backends = g_list_append(storage_backends, backend);
42}
43
[b73ac9c]44static storage_t *storage_init_single(const char *name)
[1ee6c18]45{
46        GList *gl;
[b3c467b]47        storage_t *st = NULL;
[1ee6c18]48
49        for (gl = storage_backends; gl; gl = gl->next) {
50                st = gl->data;
[5ebff60]51                if (strcmp(st->name, name) == 0) {
[1ee6c18]52                        break;
[5ebff60]53                }
[1ee6c18]54        }
55
[5ebff60]56        if (gl == NULL) {
[1ee6c18]57                return NULL;
[5ebff60]58        }
[1ee6c18]59
[5ebff60]60        if (st->init) {
[1ee6c18]61                st->init();
[5ebff60]62        }
[1ee6c18]63
64        return st;
65}
[ab49fdc]66
[b73ac9c]67GList *storage_init(const char *primary, char **migrate)
68{
69        GList *ret = NULL;
70        int i;
71        storage_t *storage;
[5ebff60]72
[c121f89]73        register_storage_backend(&storage_xml);
[5ebff60]74
[b73ac9c]75        storage = storage_init_single(primary);
[5ebff60]76        if (storage == NULL && storage->save == NULL) {
[b73ac9c]77                return NULL;
[5ebff60]78        }
[b73ac9c]79
80        ret = g_list_append(ret, storage);
81
82        for (i = 0; migrate && migrate[i]; i++) {
83                storage = storage_init_single(migrate[i]);
[5ebff60]84
85                if (storage) {
[b73ac9c]86                        ret = g_list_append(ret, storage);
[5ebff60]87                }
[b73ac9c]88        }
89
90        return ret;
91}
92
[8e6ecfe]93storage_status_t storage_check_pass(irc_t *irc, const char *nick, const char *password)
[ab49fdc]94{
[b73ac9c]95        GList *gl;
[5ebff60]96
[b73ac9c]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
[8e6ecfe]103                status = st->check_pass(irc, nick, password);
[5ebff60]104                if (status != STORAGE_NO_SUCH_USER) {
[b73ac9c]105                        return status;
[5ebff60]106                }
[b73ac9c]107        }
[5ebff60]108
[b73ac9c]109        return STORAGE_NO_SUCH_USER;
[ab49fdc]110}
111
[5ebff60]112storage_status_t storage_load(irc_t * irc, const char *password)
[ab49fdc]113{
[b73ac9c]114        GList *gl;
[5ebff60]115
116        if (irc && irc->status & USTATUS_IDENTIFIED) {
[3183c21]117                return STORAGE_OTHER_ERROR;
[5ebff60]118        }
119
[b73ac9c]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
[3183c21]125                status = st->load(irc, password);
[5ebff60]126                if (status == STORAGE_OK) {
[2dcaf9a]127                        GSList *l;
[5ebff60]128                        for (l = irc_plugins; l; l = l->next) {
[2dcaf9a]129                                irc_plugin_t *p = l->data;
[5ebff60]130                                if (p->storage_load) {
131                                        p->storage_load(irc);
132                                }
[2dcaf9a]133                        }
[b73ac9c]134                        return status;
[2dcaf9a]135                }
[5ebff60]136
137                if (status != STORAGE_NO_SUCH_USER) {
[b73ac9c]138                        return status;
[5ebff60]139                }
[b73ac9c]140        }
[5ebff60]141
[b73ac9c]142        return STORAGE_NO_SUCH_USER;
[ab49fdc]143}
144
[5ebff60]145storage_status_t storage_save(irc_t *irc, char *password, int overwrite)
[ab49fdc]146{
[3183c21]147        storage_status_t st;
[2dcaf9a]148        GSList *l;
[5ebff60]149
[3183c21]150        if (password != NULL) {
151                /* Should only use this in the "register" command. */
[5ebff60]152                if (irc->password || overwrite) {
[3183c21]153                        return STORAGE_OTHER_ERROR;
[5ebff60]154                }
155
[3183c21]156                irc_setpass(irc, password);
157        } else if ((irc->status & USTATUS_IDENTIFIED) == 0) {
158                return STORAGE_NO_SUCH_USER;
159        }
[5ebff60]160
161        st = ((storage_t *) global.storage->data)->save(irc, overwrite);
162
163        for (l = irc_plugins; l; l = l->next) {
[2dcaf9a]164                irc_plugin_t *p = l->data;
[5ebff60]165                if (p->storage_save) {
166                        p->storage_save(irc);
167                }
[2dcaf9a]168        }
[5ebff60]169
[3183c21]170        if (password != NULL) {
171                irc_setpass(irc, NULL);
172        }
[5ebff60]173
[3183c21]174        return st;
[ab49fdc]175}
176
[8e6ecfe]177storage_status_t storage_remove(const char *nick)
[ab49fdc]178{
[b73ac9c]179        GList *gl;
180        storage_status_t ret = STORAGE_OK;
[2dcaf9a]181        gboolean ok = FALSE;
182        GSList *l;
[5ebff60]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
[b73ac9c]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
[8e6ecfe]191                status = st->remove(nick);
[2dcaf9a]192                ok |= status == STORAGE_OK;
[5ebff60]193                if (status != STORAGE_NO_SUCH_USER && status != STORAGE_OK) {
[b73ac9c]194                        ret = status;
[5ebff60]195                }
[b73ac9c]196        }
[5ebff60]197
[2dcaf9a]198        /* If at least one succeeded, remove plugin data. */
[5ebff60]199        if (ok) {
200                for (l = irc_plugins; l; l = l->next) {
[2dcaf9a]201                        irc_plugin_t *p = l->data;
[5ebff60]202                        if (p->storage_remove) {
203                                p->storage_remove(nick);
204                        }
[2dcaf9a]205                }
[5ebff60]206        }
207
[b73ac9c]208        return ret;
[ab49fdc]209}
Note: See TracBrowser for help on using the repository browser.