gdbmobj.c
上传用户:s81996212
上传日期:2007-01-04
资源大小:722k
文件大小:3k
源码类别:

WEB邮件程序

开发平台:

C/C++

  1. /*
  2. ** Copyright 1998 - 2000 Double Precision, Inc.  See COPYING for
  3. ** distribution information.
  4. */
  5. #if HAVE_CONFIG_H
  6. #include "config.h"
  7. #endif
  8. #include "gdbmobj.h"
  9. #include <stdlib.h>
  10. #if HAVE_FCNTL_H
  11. #include <fcntl.h>
  12. #endif
  13. #if HAVE_UNISTD_H
  14. #include <unistd.h>
  15. #endif
  16. static const char rcsid[]="$Id: gdbmobj.c,v 1.8 2000/03/13 13:03:13 mrsam Exp $";
  17. void gdbmobj_init(struct gdbmobj *obj)
  18. {
  19. obj->has_dbf=0;
  20. obj->prev_key=0;
  21. obj->prev_key_len=0;
  22. }
  23. void gdbmobj_close(struct gdbmobj *obj)
  24. {
  25. if (obj->has_dbf)
  26. {
  27. obj->has_dbf=0;
  28. gdbm_close(obj->dbf);
  29. }
  30. if (obj->prev_key)
  31. {
  32. free(obj->prev_key);
  33. obj->prev_key=0;
  34. }
  35. }
  36. int gdbmobj_open(struct gdbmobj *obj, const char *filename, const char *modestr)
  37. {
  38. int mode=GDBM_READER;
  39. for ( ; *modestr; *modestr++)
  40. switch (*modestr) {
  41. case 'c':
  42. case 'C':
  43. mode=GDBM_WRCREAT;
  44. break;
  45. case 'w':
  46. case 'W':
  47. mode=GDBM_WRITER;
  48. break;
  49. case 'n':
  50. case 'N':
  51. mode=GDBM_NEWDB;
  52. break;
  53. }
  54. gdbmobj_close(obj);
  55. if ((obj->dbf=gdbm_open((char *)filename, 0, mode, 0664, 0)) != 0)
  56. {
  57. /* Where possible, set the close-on-exec bit */
  58. #if HAVE_GDBM_FDESC
  59. #ifdef  FD_CLOEXEC
  60. int fd=gdbm_fdesc(obj->dbf);
  61. if (fd >= 0) fcntl(fd, F_SETFD, FD_CLOEXEC);
  62. #endif
  63. #endif
  64. obj->has_dbf=1;
  65. return (0);
  66. }
  67. return (-1);
  68. }
  69. int gdbmobj_store(struct gdbmobj *obj, const char *key, size_t keylen,
  70. const char *data,
  71. size_t datalen,
  72. const char *mode)
  73. {
  74. datum dkey;
  75. datum dval;
  76. dkey.dptr=(char *)key;
  77. dkey.dsize=keylen;
  78. dval.dptr=(char *)data;
  79. dval.dsize=datalen;
  80. return (obj->has_dbf ? gdbm_store(obj->dbf, dkey, dval, (
  81. *mode == 'i' || *mode == 'I' ?
  82. GDBM_INSERT:GDBM_REPLACE)):-1);
  83. }
  84. int gdbmobj_exists(struct gdbmobj *obj, const char *key, size_t keylen)
  85. {
  86. datum dkey;
  87. if (!obj->has_dbf) return (0);
  88. dkey.dptr=(char *)key;
  89. dkey.dsize=keylen;
  90. if (gdbm_exists(obj->dbf, dkey)) return (1);
  91. return (0);
  92. }
  93. char *gdbm_dofetch(struct gdbmobj *, const char *, size_t, size_t *);
  94. char *gdbmobj_fetch(struct gdbmobj *obj, const char *key, size_t keylen,
  95. size_t *datalen, const char *options)
  96. {
  97. char *p;
  98. for (;;)
  99. {
  100. if ((p=gdbm_dofetch(obj, key, keylen, datalen)) != 0)
  101. return (p);
  102. if (!options) break;
  103. if (*options == 'I')
  104. {
  105. while (keylen && key[--keylen] != '.')
  106. ;
  107. if (!keylen) break;
  108. continue;
  109. }
  110. if (*options == 'D')
  111. {
  112. size_t i;
  113. for (i=0; i<keylen; i++)
  114. if (key[i] == '@') { ++i; break; }
  115. if (i < keylen)
  116. {
  117. if ((p=gdbm_dofetch(obj, key, i, datalen)) != 0)
  118. return (p);
  119. key += i;
  120. keylen -= i;
  121. continue;
  122. }
  123. for (i=0; i<keylen; i++)
  124. if (key[i] == '.') { ++i; break; }
  125. if (i < keylen)
  126. {
  127. key += i;
  128. keylen -= i;
  129. continue;
  130. }
  131. break;
  132. }
  133. break;
  134. }
  135. return (0);
  136. }
  137. char *gdbm_dofetch(struct gdbmobj *obj,
  138. const char *key, size_t keylen, size_t *datalen)
  139. {
  140. datum dkey, val;
  141. if (!obj->has_dbf) return (0);
  142. dkey.dptr=(char *)key;
  143. dkey.dsize=keylen;
  144. val=gdbm_fetch(obj->dbf, dkey);
  145. if (!val.dptr) return (0);
  146. *datalen=val.dsize;
  147. return (val.dptr);
  148. }