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 40static GDBM_FILE gdbm_file = NULL; 41#endif 42#ifdef HAVE_DBM 43static DBM *dbm_file = NULL; 44#endif 45static char *buffer = NULL; 46static char *enum_key = NULL; 47 48static 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 68const 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 145fail: 146 147 return name; 148} 149 150void 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 170char *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 211void stdb_setent(void) { 212 avahi_free(enum_key); 213 enum_key = NULL; 214} 215