]> git.meshlink.io Git - catta/blob - avahi-utils/stdb.c
759ecbd965d7203b27182243d3aa7af15ebc665d
[catta] / avahi-utils / stdb.c
1 /* $Id$ */
2
3 /***
4   This file is part of avahi.
5
6   avahi is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License as
8   published by the Free Software Foundation; either version 2.1 of the
9   License, or (at your option) any later version.
10
11   avahi is distributed in the hope that it will be useful, but WITHOUT
12   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13   or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
14   Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with avahi; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19   USA.
20 ***/
21
22 #include <config.h>
23 #ifdef HAVE_GDBM
24 #include <gdbm.h>
25 #endif
26 #ifdef HAVE_DBM
27 #include <ndbm.h>
28 #include <fcntl.h>
29 #endif
30 #include <stdlib.h>
31 #include <string.h>
32 #include <locale.h>
33 #include <stdio.h>
34
35 #include <avahi-common/malloc.h>
36
37 #include "stdb.h"
38
39 #ifdef HAVE_GDBM
40 static GDBM_FILE gdbm_file = NULL;
41 #endif
42 #ifdef HAVE_DBM
43 static DBM *dbm_file = NULL;
44 #endif
45 static char *buffer = NULL;
46 static char *enum_key = NULL;
47
48 static int init(void) {
49
50 #ifdef HAVE_GDBM
51     if (gdbm_file)
52         return 0;
53
54     if (!(gdbm_file = gdbm_open((char*) DATABASE_FILE, 0, GDBM_READER, 0, NULL)))
55         return -1;
56 #endif
57 #ifdef HAVE_DBM
58     if (dbm_file)
59         return 0;
60
61     if (!(dbm_file = dbm_open((char*) DATABASE_FILE, O_RDONLY, 0)))
62         return -1;
63 #endif
64
65     return 0;
66 }
67
68 const char* stdb_lookup(const char *name) {
69     datum key, data;
70     const char *loc;
71
72     if (init() < 0)
73         goto fail;
74
75     data.dptr = NULL;
76     data.dsize = 0;
77
78     if ((loc = setlocale(LC_MESSAGES, NULL))) {
79         char k[256];
80
81         snprintf(k, sizeof(k), "%s[%s]", name, loc);
82         key.dptr = k;
83         key.dsize = strlen(k);
84 #ifdef HAVE_GDBM
85         data = gdbm_fetch(gdbm_file, key);
86 #endif
87 #ifdef HAVE_DBM
88         data = dbm_fetch(dbm_file, key);
89 #endif
90
91         if (!data.dptr) {
92             char l[32], *e;
93             snprintf(l, sizeof(l), "%s", loc);
94
95             if ((e = strchr(l, '@'))) {
96                 *e = 0;
97                 snprintf(k, sizeof(k), "%s[%s]", name, l);
98                 key.dptr = k;
99                 key.dsize = strlen(k);
100 #ifdef HAVE_GDBM
101                 data = gdbm_fetch(gdbm_file, key);
102 #endif
103 #ifdef HAVE_DBM
104                 data = dbm_fetch(dbm_file, key);
105 #endif
106             }
107
108             if (!data.dptr) {
109                 if ((e = strchr(l, '_'))) {
110                     *e = 0;
111                     snprintf(k, sizeof(k), "%s[%s]", name, l);
112                     key.dptr = k;
113                     key.dsize = strlen(k);
114 #ifdef HAVE_GDBM
115                     data = gdbm_fetch(gdbm_file, key);
116 #endif
117 #ifdef HAVE_DBM
118                     data = dbm_fetch(dbm_file, key);
119 #endif
120                 }
121             }
122         }
123     }
124
125     if (!data.dptr) {
126         key.dptr = (char*) name;
127         key.dsize = strlen(name);
128 #ifdef HAVE_GDBM
129         data = gdbm_fetch(gdbm_file, key);
130 #endif
131 #ifdef HAVE_DBM
132         data = dbm_fetch(dbm_file, key);
133 #endif
134     }
135
136     if (!data.dptr)
137         goto fail;
138
139     avahi_free(buffer);
140     buffer = avahi_strndup(data.dptr, data.dsize);
141     free(data.dptr);
142
143     return buffer;
144
145 fail:
146
147     return name;
148 }
149
150 void stdb_shutdown(void) {
151 #ifdef HAVE_GDBM
152     if (gdbm_file)
153         gdbm_close(gdbm_file);
154
155     gdbm_file = NULL;
156 #endif
157 #ifdef HAVE_DBM
158     if (dbm_file)
159         dbm_close(dbm_file);
160
161     dbm_file = NULL;
162 #endif
163
164     avahi_free(buffer);
165     avahi_free(enum_key);
166
167     buffer = enum_key = NULL;
168 }
169
170 char *stdb_getent(void) {
171     datum key;
172
173     if (init() < 0)
174         return NULL;
175
176     for (;;) {
177
178         if (!enum_key) {
179 #ifdef HAVE_GDBM
180             key = gdbm_firstkey(gdbm_file);
181 #endif
182 #ifdef HAVE_DBM
183             key = dbm_firstkey(dbm_file);
184 #endif
185         } else {
186             key.dptr = enum_key;
187             key.dsize = strlen(enum_key);
188
189 #ifdef HAVE_GDBM
190             key = gdbm_nextkey(gdbm_file, key);
191 #endif
192 #ifdef HAVE_DBM
193             key = dbm_nextkey(dbm_file);
194 #endif
195         }
196
197         avahi_free(enum_key);
198         enum_key = NULL;
199
200         if (!key.dptr)
201             return NULL;
202
203         enum_key = avahi_strndup(key.dptr, key.dsize);
204         free(key.dptr);
205
206         if (!strchr(enum_key, '['))
207             return enum_key;
208     }
209 }
210
211 void stdb_setent(void) {
212     avahi_free(enum_key);
213     enum_key = NULL;
214 }