Logo Search packages:      
Sourcecode: maildrop version File versions  Download package

gdbmobj.c

/*
** Copyright 1998 - 2000 Double Precision, Inc.  See COPYING for
** distribution information.
*/

#if   HAVE_CONFIG_H
#include    "config.h"
#endif

#include    "gdbmobj.h"
#include    <stdlib.h>
#if   HAVE_FCNTL_H
#include    <fcntl.h>
#endif
#if   HAVE_UNISTD_H
#include    <unistd.h>
#endif

static const char rcsid[]="$Id: gdbmobj.c,v 1.8 2000/03/13 13:03:13 mrsam Exp $";

void gdbmobj_init(struct gdbmobj *obj)
{
      obj->has_dbf=0;
      obj->prev_key=0;
      obj->prev_key_len=0;
}

void gdbmobj_close(struct gdbmobj *obj)
{
      if (obj->has_dbf)
      {
            obj->has_dbf=0;
            gdbm_close(obj->dbf);
      }
      if (obj->prev_key)
      {
            free(obj->prev_key);
            obj->prev_key=0;
      }
}

int gdbmobj_open(struct gdbmobj *obj, const char *filename, const char *modestr)
{
int   mode=GDBM_READER;

      for ( ; *modestr; *modestr++)
            switch (*modestr) {
            case 'c':
            case 'C':
                  mode=GDBM_WRCREAT;
                  break;
            case 'w':
            case 'W':
                  mode=GDBM_WRITER;
                  break;
            case 'n':
            case 'N':
                  mode=GDBM_NEWDB;
                  break;
      }

      gdbmobj_close(obj);
      if ((obj->dbf=gdbm_open((char *)filename, 0, mode, 0664, 0)) != 0)
      {
            /* Where possible, set the close-on-exec bit */

#if   HAVE_GDBM_FDESC
#ifdef  FD_CLOEXEC

      int   fd=gdbm_fdesc(obj->dbf);

            if (fd >= 0)      fcntl(fd, F_SETFD, FD_CLOEXEC);
#endif
#endif

            obj->has_dbf=1;
            return (0);
      }
      return (-1);
}

int gdbmobj_store(struct gdbmobj *obj, const char *key, size_t keylen,
            const char *data,
            size_t      datalen,
            const char *mode)
{
datum dkey;
datum dval;

      dkey.dptr=(char *)key;
      dkey.dsize=keylen;

      dval.dptr=(char *)data;
      dval.dsize=datalen;

      return (obj->has_dbf ? gdbm_store(obj->dbf, dkey, dval, (
                  *mode == 'i' || *mode == 'I' ?
                        GDBM_INSERT:GDBM_REPLACE)):-1);
}

int   gdbmobj_exists(struct gdbmobj *obj, const char *key, size_t keylen)
{
datum dkey;

      if (!obj->has_dbf)      return (0);

      dkey.dptr=(char *)key;
      dkey.dsize=keylen;

      if (gdbm_exists(obj->dbf, dkey))    return (1);
      return (0);
}

char *gdbm_dofetch(struct gdbmobj *, const char *, size_t, size_t *);

char  *gdbmobj_fetch(struct gdbmobj *obj, const char *key, size_t keylen,
            size_t *datalen, const char *options)
{
char  *p;

      for (;;)
      {
            if ((p=gdbm_dofetch(obj, key, keylen, datalen)) != 0)
                  return (p);
            if (!options)     break;
            if (*options == 'I')
            {
                  while (keylen && key[--keylen] != '.')
                        ;
                  if (!keylen)      break;
                  continue;
            }
            if (*options == 'D')
            {
            size_t      i;

                  for (i=0; i<keylen; i++)
                        if (key[i] == '@') { ++i; break; }
                  if (i < keylen)
                  {
                        if ((p=gdbm_dofetch(obj, key, i, datalen)) != 0)
                              return (p);
                        key += i;
                        keylen -= i;
                        continue;
                  }

                  for (i=0; i<keylen; i++)
                        if (key[i] == '.') { ++i; break; }
                  if (i < keylen)
                  {
                        key += i;
                        keylen -= i;
                        continue;
                  }
                  break;
            }
            break;
      }
      return (0);
}

char *gdbm_dofetch(struct gdbmobj *obj,
      const char *key, size_t keylen, size_t *datalen)
{
datum dkey, val;

      if (!obj->has_dbf)      return (0);

      dkey.dptr=(char *)key;
      dkey.dsize=keylen;

      val=gdbm_fetch(obj->dbf, dkey);

      if (!val.dptr)    return (0);
      *datalen=val.dsize;
      return (val.dptr);
}

Generated by  Doxygen 1.6.0   Back to index