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

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 "bdbobj.h"
  9. #include <fcntl.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #if HAVE_FCNTL_H
  13. #include <fcntl.h>
  14. #endif
  15. #if HAVE_UNISTD_H
  16. #include <unistd.h>
  17. #endif
  18. void bdbobj_init(struct bdbobj *obj)
  19. {
  20. obj->has_dbf=0;
  21. #if DB_VERSION_MAJOR >= 2
  22. obj->has_dbc=0;
  23. #endif
  24. }
  25. void bdbobj_close(struct bdbobj *obj)
  26. {
  27. #if DB_VERSION_MAJOR >= 2
  28. if (obj->has_dbc)
  29. {
  30. (*obj->dbc->c_close)(obj->dbc);
  31. obj->has_dbc=0;
  32. }
  33. #endif
  34. if ( obj->has_dbf )
  35. {
  36. #if DB_VERSION_MAJOR < 2
  37. (*obj->dbf->close)(obj->dbf);
  38. #else
  39. (*obj->dbf->close)(obj->dbf, 0);
  40. #endif
  41. obj->has_dbf=0;
  42. }
  43. }
  44. int bdbobj_open(struct bdbobj *obj, const char *filename, const char *modestr)
  45. {
  46. #if DB_VERSION_MAJOR < 2
  47. int flags=O_RDONLY;
  48. #else
  49. int flags=DB_RDONLY;
  50. #endif
  51. DBTYPE dbtype=DB_HASH;
  52. for ( ; *modestr; modestr++)
  53. switch (*modestr) {
  54. case 'c':
  55. case 'C':
  56. #if DB_VERSION_MAJOR < 2
  57. flags=O_RDWR|O_CREAT;
  58. #else
  59. flags=DB_CREATE;
  60. #endif
  61. break;
  62. case 'w':
  63. case 'W':
  64. #if DB_VERSION_MAJOR < 2
  65. flags=O_RDWR;
  66. #else
  67. flags=0;
  68. #endif
  69. break;
  70. case 'n':
  71. case 'N':
  72. #if DB_VERSION_MAJOR < 2
  73. flags=O_RDWR|O_CREAT|O_TRUNC;
  74. #else
  75. flags=DB_CREATE|DB_TRUNCATE;
  76. #endif
  77. break;
  78. case 'b':
  79. case 'B':
  80. dbtype=DB_BTREE;
  81. break;
  82. case 'e':
  83. case 'E':
  84. dbtype=DB_RECNO;
  85. break;
  86. }
  87. bdbobj_close(obj);
  88. #if DB_VERSION_MAJOR < 3
  89. #if DB_VERSION_MAJOR < 2
  90. if ( (obj->dbf=dbopen(filename, flags, 0664, dbtype, 0)) != 0)
  91. #else
  92. if ( db_open(filename, dbtype, flags, 0664, 0, 0, &obj->dbf) == 0)
  93. #endif
  94. #else
  95. obj->dbf=0;
  96. if (db_create(&obj->dbf, NULL, 0) == 0)
  97. {
  98. if ( (*obj->dbf->open)(obj->dbf, filename, NULL,
  99. dbtype, flags, 0664))
  100. {
  101. (*obj->dbf->close)(obj->dbf, DB_NOSYNC);
  102. obj->dbf=0;
  103. }
  104. }
  105. if (obj->dbf)
  106. #endif
  107. {
  108. #ifdef  FD_CLOEXEC
  109. #if DB_VERSION_MAJOR < 2
  110.         int     fd=(*obj->dbf->fd)(obj->dbf);
  111. #else
  112. int fd;
  113. if ((*obj->dbf->fd)(obj->dbf, &fd))
  114. fd= -1;
  115. #endif
  116.                 if (fd >= 0)    fcntl(fd, F_SETFD, FD_CLOEXEC);
  117. #endif
  118. obj->has_dbf=1;
  119. return (0);
  120. }
  121. return (-1);
  122. }
  123. int bdbobj_store(struct bdbobj *obj, const char *key, size_t keylen,
  124. const char *data,
  125. size_t datalen,
  126. const char *mode)
  127. {
  128. DBT dkey, dval;
  129. memset(&dkey, 0, sizeof(dkey));
  130. memset(&dval, 0, sizeof(dval));
  131. dkey.data=(void *)key;
  132. dkey.size=keylen;
  133. dval.data=(void *)data;
  134. dval.size=datalen;
  135. #if DB_VERSION_MAJOR < 2
  136. return (obj->has_dbf ? (*obj->dbf->put)(obj->dbf, &dkey, &dval, (
  137. *mode == 'i' || *mode == 'I' ?  R_NOOVERWRITE:0)):-1);
  138. #else
  139. return (obj->has_dbf ? (*obj->dbf->put)(obj->dbf, 0, &dkey, &dval, (
  140. *mode == 'i' || *mode == 'I' ? DB_NOOVERWRITE:0)):-1);
  141. #endif
  142. }
  143. static char *doquery(struct bdbobj *obj,
  144. const char *, size_t, size_t *, const char *);
  145. char *bdbobj_fetch(struct bdbobj *obj, const char *key, size_t keylen,
  146. size_t *datalen, const char *options)
  147. {
  148. char *p=doquery(obj, key, keylen, datalen, options);
  149. char *q;
  150. if (!p) return (0);
  151. q=(char *)malloc(*datalen);
  152. if (!q) return (0);
  153. memcpy(q, p, *datalen);
  154. return (q);
  155. }
  156. char    *dofetch(struct bdbobj *, const char *, size_t, size_t *);
  157. static char *doquery(struct bdbobj *obj, const char *key, size_t keylen,
  158. size_t *datalen, const char *options)
  159. {
  160. char *p;
  161. for (;;)
  162. {
  163. if ((p=dofetch(obj, key, keylen, datalen)) != 0)
  164. return (p);
  165. if (!options) break;
  166. if (*options == 'I')
  167. {
  168. while (keylen && key[--keylen] != '.')
  169. ;
  170. if (!keylen) break;
  171. continue;
  172. }
  173. if (*options == 'D')
  174. {
  175. size_t i;
  176. for (i=0; i<keylen; i++)
  177. if (key[i] == '@') { ++i; break; }
  178. if (i < keylen)
  179. {
  180. if ((p=dofetch(obj, key, i, datalen)) != 0)
  181. return (p);
  182. key += i;
  183. keylen -= i;
  184. continue;
  185. }
  186. for (i=0; i<keylen; i++)
  187. if (key[i] == '.') { ++i; break; }
  188. if (i < keylen)
  189. {
  190. key += i;
  191. keylen -= i;
  192. continue;
  193. }
  194. break;
  195. }
  196. break;
  197. }
  198. return (0);
  199. }
  200. char *dofetch(struct bdbobj *obj, const char *key, size_t keylen,
  201. size_t *datalen)
  202. {
  203. DBT dkey, val;
  204. if (!obj->has_dbf) return (0);
  205. memset(&dkey, 0, sizeof(dkey));
  206. memset(&val, 0, sizeof(val));
  207. dkey.data=(void *)key;
  208. dkey.size=keylen;
  209. #if DB_VERSION_MAJOR < 2
  210. if ( (*obj->dbf->get)(obj->dbf, &dkey, &val, 0)) return (0);
  211. #else
  212. if ( (*obj->dbf->get)(obj->dbf, 0, &dkey, &val, 0)) return (0);
  213. #endif
  214. *datalen=val.size;
  215. return ((char *)val.data);
  216. }
  217. int bdbobj_exists(struct bdbobj *obj, const char *key, size_t keylen)
  218. {
  219. size_t datalen;
  220. char *p=doquery(obj, key, keylen, &datalen, 0);
  221. return (p ? 1:0);
  222. }