Back to index

courier  0.68.2
gdbmobj.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 1998 - 2000 Double Precision, Inc.  See COPYING for
00003 ** distribution information.
00004 */
00005 
00006 #if    HAVE_CONFIG_H
00007 #include      "config.h"
00008 #endif
00009 
00010 #include      "gdbmobj.h"
00011 #include      <stdlib.h>
00012 #if    HAVE_FCNTL_H
00013 #include      <fcntl.h>
00014 #endif
00015 #if    HAVE_UNISTD_H
00016 #include      <unistd.h>
00017 #endif
00018 
00019 
00020 void gdbmobj_init(struct gdbmobj *obj)
00021 {
00022        obj->has_dbf=0;
00023        obj->prev_key=0;
00024        obj->prev_key_len=0;
00025 }
00026 
00027 void gdbmobj_close(struct gdbmobj *obj)
00028 {
00029        if (obj->has_dbf)
00030        {
00031               obj->has_dbf=0;
00032               gdbm_close(obj->dbf);
00033        }
00034        if (obj->prev_key)
00035        {
00036               free(obj->prev_key);
00037               obj->prev_key=0;
00038        }
00039 }
00040 
00041 int gdbmobj_open(struct gdbmobj *obj, const char *filename, const char *modestr)
00042 {
00043 int    mode=GDBM_READER;
00044 
00045        for ( ; *modestr; modestr++)
00046               switch (*modestr)    {
00047               case 'c':
00048               case 'C':
00049                      mode=GDBM_WRCREAT;
00050                      break;
00051               case 'w':
00052               case 'W':
00053                      mode=GDBM_WRITER;
00054                      break;
00055               case 'n':
00056               case 'N':
00057                      mode=GDBM_NEWDB;
00058                      break;
00059        }
00060 
00061        gdbmobj_close(obj);
00062        if ((obj->dbf=gdbm_open((char *)filename, 0, mode, 0664, 0)) != 0)
00063        {
00064               /* Where possible, set the close-on-exec bit */
00065 
00066 #if    HAVE_GDBM_FDESC
00067 #ifdef  FD_CLOEXEC
00068 
00069        int    fd=gdbm_fdesc(obj->dbf);
00070 
00071               if (fd >= 0)  fcntl(fd, F_SETFD, FD_CLOEXEC);
00072 #endif
00073 #endif
00074 
00075               obj->has_dbf=1;
00076               return (0);
00077        }
00078        return (-1);
00079 }
00080 
00081 int gdbmobj_store(struct gdbmobj *obj, const char *key, size_t keylen,
00082               const char *data,
00083               size_t datalen,
00084               const  char *mode)
00085 {
00086 datum dkey;
00087 datum dval;
00088 
00089        dkey.dptr=(char *)key;
00090        dkey.dsize=keylen;
00091 
00092        dval.dptr=(char *)data;
00093        dval.dsize=datalen;
00094 
00095        return (obj->has_dbf ? gdbm_store(obj->dbf, dkey, dval, (
00096                      *mode == 'i' || *mode == 'I' ?
00097                             GDBM_INSERT:GDBM_REPLACE)):-1);
00098 }
00099 
00100 int    gdbmobj_exists(struct gdbmobj *obj, const char *key, size_t keylen)
00101 {
00102 datum  dkey;
00103 
00104        if (!obj->has_dbf)   return (0);
00105 
00106        dkey.dptr=(char *)key;
00107        dkey.dsize=keylen;
00108 
00109        if (gdbm_exists(obj->dbf, dkey))   return (1);
00110        return (0);
00111 }
00112 
00113 char *gdbm_dofetch(struct gdbmobj *, const char *, size_t, size_t *);
00114 
00115 char   *gdbmobj_fetch(struct gdbmobj *obj, const char *key, size_t keylen,
00116               size_t *datalen, const char *options)
00117 {
00118 char   *p;
00119 
00120        for (;;)
00121        {
00122               if ((p=gdbm_dofetch(obj, key, keylen, datalen)) != 0)
00123                      return (p);
00124               if (!options) break;
00125               if (*options == 'I')
00126               {
00127                      while (keylen && key[--keylen] != '.')
00128                             ;
00129                      if (!keylen)  break;
00130                      continue;
00131               }
00132               if (*options == 'D')
00133               {
00134               size_t i;
00135 
00136                      for (i=0; i<keylen; i++)
00137                             if (key[i] == '@') { ++i; break; }
00138                      if (i < keylen)
00139                      {
00140                             if ((p=gdbm_dofetch(obj, key, i, datalen)) != 0)
00141                                    return (p);
00142                             key += i;
00143                             keylen -= i;
00144                             continue;
00145                      }
00146 
00147                      for (i=0; i<keylen; i++)
00148                             if (key[i] == '.') { ++i; break; }
00149                      if (i < keylen)
00150                      {
00151                             key += i;
00152                             keylen -= i;
00153                             continue;
00154                      }
00155                      break;
00156               }
00157               break;
00158        }
00159        return (0);
00160 }
00161 
00162 char *gdbm_dofetch(struct gdbmobj *obj,
00163        const char *key, size_t keylen, size_t *datalen)
00164 {
00165 datum  dkey, val;
00166 
00167        if (!obj->has_dbf)   return (0);
00168 
00169        dkey.dptr=(char *)key;
00170        dkey.dsize=keylen;
00171 
00172        val=gdbm_fetch(obj->dbf, dkey);
00173 
00174        if (!val.dptr)       return (0);
00175        *datalen=val.dsize;
00176        return (val.dptr);
00177 }