source: storage.c @ f665dab

Last change on this file since f665dab was d9d36fc, checked in by Jelmer Vernooij <jelmer@…>, at 2005-12-21T12:13:10Z

Add initial draft of BitlBee schema

  • 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., 59 Temple Place,
25  Suite 330, Boston, MA  02111-1307  USA
26*/
27
28#define BITLBEE_CORE
29#include "bitlbee.h"
30#include "crypting.h"
31
32extern storage_t storage_text;
33
34static GList text_entry = { &storage_text, NULL, NULL };
35static GList *storage_backends = &text_entry;
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;
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        storage = storage_init_single(primary);
69        if (storage == NULL)
70                return NULL;
71
72        ret = g_list_append(ret, storage);
73
74        for (i = 0; migrate && migrate[i]; i++) {
75                storage = storage_init_single(migrate[i]);
76       
77                if (storage)
78                        ret = g_list_append(ret, storage);
79        }
80
81        return ret;
82}
83
84storage_status_t storage_check_pass (const char *nick, const char *password)
85{
86        GList *gl;
87       
88        /* Loop until we don't get NO_SUCH_USER */
89
90        for (gl = global.storage; gl; gl = gl->next) {
91                storage_t *st = gl->data;
92                storage_status_t status;
93
94                status = st->check_pass(nick, password);
95                if (status != STORAGE_NO_SUCH_USER)
96                        return status;
97        }
98       
99        return STORAGE_NO_SUCH_USER;
100}
101
102storage_status_t storage_load (const char *nick, const char *password, irc_t * irc)
103{
104        GList *gl;
105       
106        /* Loop until we don't get NO_SUCH_USER */
107        for (gl = global.storage; gl; gl = gl->next) {
108                storage_t *st = gl->data;
109                storage_status_t status;
110
111                status = st->load(nick, password, irc);
112                if (status == STORAGE_OK) {
113                        irc_setpass(irc, password);
114                        return status;
115                }
116               
117                if (status != STORAGE_NO_SUCH_USER) 
118                        return status;
119        }
120       
121        return STORAGE_NO_SUCH_USER;
122}
123
124storage_status_t storage_save (irc_t *irc, int overwrite)
125{
126        return ((storage_t *)global.storage->data)->save(irc, overwrite);
127}
128
129storage_status_t storage_remove (const char *nick, const char *password)
130{
131        GList *gl;
132        storage_status_t ret = STORAGE_OK;
133       
134        /* Remove this account from all storage backends. If this isn't
135         * done, the account will still be usable, it'd just be
136         * loaded from a different backend. */
137        for (gl = global.storage; gl; gl = gl->next) {
138                storage_t *st = gl->data;
139                storage_status_t status;
140
141                status = st->remove(nick, password);
142                if (status != STORAGE_NO_SUCH_USER && 
143                        status != STORAGE_OK)
144                        ret = status;
145        }
146       
147        return ret;
148}
149
150storage_status_t storage_rename (const char *onick, const char *nnick, const char *password)
151{
152        storage_status_t status;
153        GList *gl = global.storage;
154        storage_t *primary_storage = gl->data;
155        irc_t *irc;
156
157        /* First, try to rename in the current write backend, assuming onick
158         * is stored there */
159        status = primary_storage->rename(onick, nnick, password);
160        if (status != STORAGE_NO_SUCH_USER)
161                return status;
162
163        /* Try to load from a migration backend and save to the current backend.
164         * Explicitly remove the account from the migration backend as otherwise
165         * it'd still be usable under the old name */
166       
167        irc = g_new0(irc_t, 1);
168        status = storage_load(onick, password, irc);
169        if (status != STORAGE_OK) {
170                irc_free(irc);
171                return status;
172        }
173
174        g_free(irc->nick);
175        irc->nick = g_strdup(nnick);
176
177        status = storage_save(irc, FALSE);
178        if (status != STORAGE_OK) {
179                irc_free(irc);
180                return status;
181        }
182        irc_free(irc);
183
184        storage_remove(onick, password);
185
186        return STORAGE_OK;
187}
Note: See TracBrowser for help on using the repository browser.