smdb1.c
上传用户:xu_441
上传日期:2007-01-04
资源大小:1640k
文件大小:10k
源码类别:

Email客户端

开发平台:

Unix_Linux

  1. /*
  2. ** Copyright (c) 1999 Sendmail, Inc. and its suppliers.
  3. ** All rights reserved.
  4. **
  5. ** By using this file, you agree to the terms and conditions set
  6. ** forth in the LICENSE file which can be found at the top level of
  7. ** the sendmail distribution.
  8. */
  9. #ifndef lint
  10. static char id[] = "@(#)$Id: smdb1.c,v 8.40 1999/11/23 08:42:53 gshapiro Exp $";
  11. #endif /* ! lint */
  12. #include <unistd.h>
  13. #include <stdlib.h>
  14. #include <fcntl.h>
  15. #include <sendmail/sendmail.h>
  16. #include <libsmdb/smdb.h>
  17. #if (DB_VERSION_MAJOR == 1)
  18. # define SMDB1_FILE_EXTENSION "db"
  19. struct smdb_db1_struct
  20. {
  21. DB *smdb1_db;
  22. int smdb1_lock_fd;
  23. bool smdb1_cursor_in_use;
  24. };
  25. typedef struct smdb_db1_struct SMDB_DB1_DATABASE;
  26. struct smdb_db1_cursor
  27. {
  28. SMDB_DB1_DATABASE *db;
  29. };
  30. typedef struct smdb_db1_cursor SMDB_DB1_CURSOR;
  31. /*
  32. **  SMDB_TYPE_TO_DB1_TYPE -- Translates smdb database type to db1 type.
  33. **
  34. ** Parameters:
  35. ** type -- The type to translate.
  36. **
  37. ** Returns:
  38. ** The DB1 type that corresponsds to the passed in SMDB type.
  39. ** Returns -1 if there is no equivalent type.
  40. **
  41. */
  42. DBTYPE
  43. smdb_type_to_db1_type(type)
  44. SMDB_DBTYPE type;
  45. {
  46. if (type == SMDB_TYPE_DEFAULT)
  47. return DB_HASH;
  48. if (strncmp(type, SMDB_TYPE_HASH, SMDB_TYPE_HASH_LEN) == 0)
  49. return DB_HASH;
  50. if (strncmp(type, SMDB_TYPE_BTREE, SMDB_TYPE_BTREE_LEN) == 0)
  51. return DB_BTREE;
  52. /* Should never get here thanks to test in smdb_db_open() */
  53. return DB_HASH;
  54. }
  55. /*
  56. **  SMDB_PUT_FLAGS_TO_DB1_FLAGS -- Translates smdb put flags to db1 put flags.
  57. **
  58. ** Parameters:
  59. ** flags -- The flags to translate.
  60. **
  61. ** Returns:
  62. ** The db1 flags that are equivalent to the smdb flags.
  63. **
  64. ** Notes:
  65. ** Any invalid flags are ignored.
  66. **
  67. */
  68. u_int
  69. smdb_put_flags_to_db1_flags(flags)
  70. SMDB_FLAG flags;
  71. {
  72. int return_flags;
  73. return_flags = 0;
  74. if (bitset(SMDBF_NO_OVERWRITE, flags))
  75. return_flags |= R_NOOVERWRITE;
  76. return return_flags;
  77. }
  78. /*
  79. **  SMDB_CURSOR_GET_FLAGS_TO_SMDB1
  80. **
  81. ** Parameters:
  82. ** flags -- The flags to translate.
  83. **
  84. ** Returns:
  85. ** The db1 flags that are equivalent to the smdb flags.
  86. **
  87. ** Notes:
  88. ** Returns -1 if we don't support the flag.
  89. **
  90. */
  91. int
  92. smdb_cursor_get_flags_to_smdb1(flags)
  93. SMDB_FLAG flags;
  94. {
  95. switch(flags)
  96. {
  97. case SMDB_CURSOR_GET_FIRST:
  98. return R_FIRST;
  99. case SMDB_CURSOR_GET_LAST:
  100. return R_LAST;
  101. case SMDB_CURSOR_GET_NEXT:
  102. return R_NEXT;
  103. default:
  104. return -1;
  105. }
  106. }
  107. SMDB_DB1_DATABASE *
  108. smdb1_malloc_database()
  109. {
  110. SMDB_DB1_DATABASE *db1;
  111. db1 = (SMDB_DB1_DATABASE *) malloc(sizeof(SMDB_DB1_DATABASE));
  112. if (db1 != NULL)
  113. {
  114. db1->smdb1_lock_fd = -1;
  115. db1->smdb1_cursor_in_use = FALSE;
  116. }
  117. return db1;
  118. }
  119. /*
  120. ** The rest of these function correspond to the interface laid out
  121. ** in smdb.h.
  122. */
  123. int
  124. smdb1_close(database)
  125. SMDB_DATABASE *database;
  126. {
  127. SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl;
  128. DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
  129. if (db1->smdb1_lock_fd != -1)
  130. (void) close(db1->smdb1_lock_fd);
  131. free(db1);
  132. database->smdb_impl = NULL;
  133. return db->close(db);
  134. }
  135. int
  136. smdb1_del(database, key, flags)
  137. SMDB_DATABASE *database;
  138. SMDB_DBENT *key;
  139. u_int flags;
  140. {
  141. DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
  142. return db->del(db, &key->db, flags);
  143. }
  144. int
  145. smdb1_fd(database, fd)
  146. SMDB_DATABASE *database;
  147. int *fd;
  148. {
  149. DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
  150. *fd = db->fd(db);
  151. if (*fd == -1)
  152. return errno;
  153. return SMDBE_OK;
  154. }
  155. int
  156. smdb1_get(database, key, data, flags)
  157. SMDB_DATABASE *database;
  158. SMDB_DBENT *key;
  159. SMDB_DBENT *data;
  160. u_int flags;
  161. {
  162. int result;
  163. DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
  164. result = db->get(db, &key->db, &data->db, flags);
  165. if (result != 0)
  166. {
  167. if (result == 1)
  168. return SMDBE_NOT_FOUND;
  169. return errno;
  170. }
  171. return SMDBE_OK;
  172. }
  173. int
  174. smdb1_put(database, key, data, flags)
  175. SMDB_DATABASE *database;
  176. SMDB_DBENT *key;
  177. SMDB_DBENT *data;
  178. u_int flags;
  179. {
  180. DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
  181. return db->put(db, &key->db, &data->db,
  182.     smdb_put_flags_to_db1_flags(flags));
  183. }
  184. int
  185. smdb1_set_owner(database, uid, gid)
  186. SMDB_DATABASE *database;
  187. uid_t uid;
  188. gid_t gid;
  189. {
  190. # if HASFCHOWN
  191. int fd;
  192. int result;
  193. DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
  194. fd = db->fd(db);
  195. if (fd == -1)
  196. return errno;
  197. result = fchown(fd, uid, gid);
  198. if (result < 0)
  199. return errno;
  200. # endif /* HASFCHOWN */
  201. return SMDBE_OK;
  202. }
  203. int
  204. smdb1_sync(database, flags)
  205. SMDB_DATABASE *database;
  206. u_int flags;
  207. {
  208. DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
  209. return db->sync(db, flags);
  210. }
  211. int
  212. smdb1_cursor_close(cursor)
  213. SMDB_CURSOR *cursor;
  214. {
  215. SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl;
  216. SMDB_DB1_DATABASE *db1 = db1_cursor->db;
  217. if (!db1->smdb1_cursor_in_use)
  218. return SMDBE_NOT_A_VALID_CURSOR;
  219. db1->smdb1_cursor_in_use = FALSE;
  220. free(cursor);
  221. return SMDBE_OK;
  222. }
  223. int
  224. smdb1_cursor_del(cursor, flags)
  225. SMDB_CURSOR *cursor;
  226. u_int flags;
  227. {
  228. SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl;
  229. SMDB_DB1_DATABASE *db1 = db1_cursor->db;
  230. DB *db = db1->smdb1_db;
  231. return db->del(db, NULL, R_CURSOR);
  232. }
  233. int
  234. smdb1_cursor_get(cursor, key, value, flags)
  235. SMDB_CURSOR *cursor;
  236. SMDB_DBENT *key;
  237. SMDB_DBENT *value;
  238. SMDB_FLAG flags;
  239. {
  240. int db1_flags;
  241. int result;
  242. SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl;
  243. SMDB_DB1_DATABASE *db1 = db1_cursor->db;
  244. DB *db = db1->smdb1_db;
  245. db1_flags = smdb_cursor_get_flags_to_smdb1(flags);
  246. result = db->seq(db, &key->db, &value->db, db1_flags);
  247. if (result == -1)
  248. return errno;
  249. if (result == 1)
  250. return SMDBE_LAST_ENTRY;
  251. return SMDBE_OK;
  252. }
  253. int
  254. smdb1_cursor_put(cursor, key, value, flags)
  255. SMDB_CURSOR *cursor;
  256. SMDB_DBENT *key;
  257. SMDB_DBENT *value;
  258. SMDB_FLAG flags;
  259. {
  260. SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl;
  261. SMDB_DB1_DATABASE *db1 = db1_cursor->db;
  262. DB *db = db1->smdb1_db;
  263. return db->put(db, &key->db, &value->db, R_CURSOR);
  264. }
  265. int
  266. smdb1_cursor(database, cursor, flags)
  267. SMDB_DATABASE *database;
  268. SMDB_CURSOR **cursor;
  269. u_int flags;
  270. {
  271. SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl;
  272. SMDB_CURSOR *cur;
  273. SMDB_DB1_CURSOR *db1_cursor;
  274. if (db1->smdb1_cursor_in_use)
  275. return SMDBE_ONLY_SUPPORTS_ONE_CURSOR;
  276. db1->smdb1_cursor_in_use = TRUE;
  277. db1_cursor = (SMDB_DB1_CURSOR *) malloc(sizeof(SMDB_DB1_CURSOR));
  278. db1_cursor->db = db1;
  279. cur = (SMDB_CURSOR *) malloc(sizeof(SMDB_CURSOR));
  280. if (cur == NULL)
  281. return SMDBE_MALLOC;
  282. cur->smdbc_impl = db1_cursor;
  283. cur->smdbc_close = smdb1_cursor_close;
  284. cur->smdbc_del = smdb1_cursor_del;
  285. cur->smdbc_get = smdb1_cursor_get;
  286. cur->smdbc_put = smdb1_cursor_put;
  287. *cursor = cur;
  288. return SMDBE_OK;
  289. }
  290. /*
  291. **  SMDB_DB_OPEN -- Opens a db1 database.
  292. **
  293. ** Parameters:
  294. ** database -- An unallocated database pointer to a pointer.
  295. ** db_name -- The name of the database without extension.
  296. ** mode -- File permisions on the database if created.
  297. ** mode_mask -- Mode bits that must match on an existing database.
  298. ** sff -- Flags for safefile.
  299. ** type -- The type of database to open
  300. ** See smdb_type_to_db1_type for valid types.
  301. ** user_info -- Information on the user to use for file
  302. **     permissions.
  303. ** db_params --
  304. ** An SMDB_DBPARAMS struct including params. These
  305. ** are processed according to the type of the
  306. ** database. Currently supported params (only for
  307. ** HASH type) are:
  308. **    num_elements
  309. **    cache_size
  310. **
  311. ** Returns:
  312. ** SMDBE_OK -- Success, otherwise errno.
  313. */
  314. int
  315. smdb_db_open(database, db_name, mode, mode_mask, sff, type, user_info,
  316.      db_params)
  317. SMDB_DATABASE **database;
  318. char *db_name;
  319. int mode;
  320. int mode_mask;
  321. int sff;
  322. SMDB_DBTYPE type;
  323. SMDB_USER_INFO *user_info;
  324. SMDB_DBPARAMS *db_params;
  325. {
  326. int db_fd;
  327. int lock_fd;
  328. int result;
  329. void *params;
  330. SMDB_DATABASE *smdb_db;
  331. SMDB_DB1_DATABASE *db1;
  332. DB *db;
  333. HASHINFO hash_info;
  334. BTREEINFO btree_info;
  335. DBTYPE db_type;
  336. struct stat stat_info;
  337. char db_file_name[SMDB_MAX_NAME_LEN];
  338. if (type == NULL ||
  339.     (strncmp(SMDB_TYPE_HASH, type, SMDB_TYPE_HASH_LEN) != 0 &&
  340.      strncmp(SMDB_TYPE_BTREE, type, SMDB_TYPE_BTREE_LEN) != 0))
  341. return SMDBE_UNKNOWN_DB_TYPE;
  342. result = smdb_add_extension(db_file_name, SMDB_MAX_NAME_LEN,
  343.     db_name, SMDB1_FILE_EXTENSION);
  344. if (result != SMDBE_OK)
  345. return result;
  346. result = smdb_setup_file(db_name, SMDB1_FILE_EXTENSION, mode_mask,
  347.  sff, user_info, &stat_info);
  348. if (result != SMDBE_OK)
  349. return result;
  350. lock_fd = -1;
  351. # if O_EXLOCK
  352. mode |= O_EXLOCK;
  353. # else /* O_EXLOCK */
  354. result = smdb_lock_file(&lock_fd, db_name, mode, sff,
  355. SMDB1_FILE_EXTENSION);
  356. if (result != SMDBE_OK)
  357. return result;
  358. # endif /* O_EXLOCK */
  359. *database = NULL;
  360. smdb_db = smdb_malloc_database();
  361. db1 = smdb1_malloc_database();
  362. if (smdb_db == NULL || db1 == NULL)
  363. return SMDBE_MALLOC;
  364. db1->smdb1_lock_fd = lock_fd;
  365. params = NULL;
  366. if (db_params != NULL &&
  367.     (strncmp(SMDB_TYPE_HASH, type, SMDB_TYPE_HASH_LEN) == 0))
  368. {
  369. memset(&hash_info, '', sizeof hash_info);
  370. hash_info.nelem = db_params->smdbp_num_elements;
  371. hash_info.cachesize = db_params->smdbp_cache_size;
  372. params = &hash_info;
  373. }
  374. if (db_params != NULL &&
  375.     (strncmp(SMDB_TYPE_BTREE, type, SMDB_TYPE_BTREE_LEN) == 0))
  376. {
  377. memset(&btree_info, '', sizeof btree_info);
  378. btree_info.cachesize = db_params->smdbp_cache_size;
  379. if (db_params->smdbp_allow_dup)
  380. btree_info.flags |= R_DUP;
  381. params = &btree_info;
  382. }
  383. db_type = smdb_type_to_db1_type(type);
  384. db = dbopen(db_file_name, mode, 0644, db_type, params);
  385. if (db != NULL)
  386. {
  387. db_fd = db->fd(db);
  388. result = smdb_filechanged(db_name, SMDB1_FILE_EXTENSION, db_fd,
  389.   &stat_info);
  390. }
  391. else
  392. {
  393. if (errno == 0)
  394. result = SMDBE_BAD_OPEN;
  395. else
  396. result = errno;
  397. }
  398. if (result == SMDBE_OK)
  399. {
  400. /* Everything is ok. Setup driver */
  401. db1->smdb1_db = db;
  402. smdb_db->smdb_close = smdb1_close;
  403. smdb_db->smdb_del = smdb1_del;
  404. smdb_db->smdb_fd = smdb1_fd;
  405. smdb_db->smdb_get = smdb1_get;
  406. smdb_db->smdb_put = smdb1_put;
  407. smdb_db->smdb_set_owner = smdb1_set_owner;
  408. smdb_db->smdb_sync = smdb1_sync;
  409. smdb_db->smdb_cursor = smdb1_cursor;
  410. smdb_db->smdb_impl = db1;
  411. *database = smdb_db;
  412. return SMDBE_OK;
  413. }
  414. if (db != NULL)
  415. (void) db->close(db);
  416. /* Error opening database */
  417. (void) smdb_unlock_file(db1->smdb1_lock_fd);
  418. free(db1);
  419. smdb_free_database(smdb_db);
  420. return result;
  421. }
  422. #endif /* (DB_VERSION_MAJOR == 1) */