Home | History | Annotate | Download | only in avahi-utils
      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