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