Line data Source code
1 : /** 2 : * @file 3 : * GNU dbm backend for the key/value Store 4 : * 5 : * @authors 6 : * Copyright (C) 2004 Thomas Glanzmann <sithglan@stud.uni-erlangen.de> 7 : * Copyright (C) 2004 Tobias Werth <sitowert@stud.uni-erlangen.de> 8 : * Copyright (C) 2004 Brian Fundakowski Feldman <green@FreeBSD.org> 9 : * Copyright (C) 2016 Pietro Cerutti <gahr@gahr.ch> 10 : * 11 : * @copyright 12 : * This program is free software: you can redistribute it and/or modify it under 13 : * the terms of the GNU General Public License as published by the Free Software 14 : * Foundation, either version 2 of the License, or (at your option) any later 15 : * version. 16 : * 17 : * This program is distributed in the hope that it will be useful, but WITHOUT 18 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 19 : * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 20 : * details. 21 : * 22 : * You should have received a copy of the GNU General Public License along with 23 : * this program. If not, see <http://www.gnu.org/licenses/>. 24 : */ 25 : 26 : /** 27 : * @page store_gdbm GNU dbm (GDBM) 28 : * 29 : * GNU dbm backend for the key/value Store. 30 : * https://www.gnu.org.ua/software/gdbm/ 31 : */ 32 : 33 : #include "config.h" 34 : #include <stddef.h> 35 : #include <gdbm.h> 36 : #include "mutt/lib.h" 37 : #include "lib.h" 38 : 39 : /** 40 : * store_gdbm_open - Implements StoreOps::open() - @ingroup store_open 41 : */ 42 4 : static void *store_gdbm_open(const char *path) 43 : { 44 4 : if (!path) 45 2 : return NULL; 46 : 47 2 : const int pagesize = 4096; 48 : 49 2 : GDBM_FILE db = gdbm_open((char *) path, pagesize, GDBM_WRCREAT, 00600, NULL); 50 2 : if (db) 51 2 : return db; 52 : 53 : /* if rw failed try ro */ 54 0 : return gdbm_open((char *) path, pagesize, GDBM_READER, 00600, NULL); 55 : } 56 : 57 : /** 58 : * store_gdbm_fetch - Implements StoreOps::fetch() - @ingroup store_fetch 59 : */ 60 4 : static void *store_gdbm_fetch(void *store, const char *key, size_t klen, size_t *vlen) 61 : { 62 4 : if (!store) 63 2 : return NULL; 64 : 65 : datum dkey; 66 : datum data; 67 : 68 2 : GDBM_FILE db = store; 69 : 70 2 : dkey.dptr = (char *) key; 71 2 : dkey.dsize = klen; 72 2 : data = gdbm_fetch(db, dkey); 73 : 74 2 : *vlen = data.dsize; 75 2 : return data.dptr; 76 : } 77 : 78 : /** 79 : * store_gdbm_free - Implements StoreOps::free() - @ingroup store_free 80 : */ 81 6 : static void store_gdbm_free(void *store, void **ptr) 82 : { 83 6 : FREE(ptr); 84 6 : } 85 : 86 : /** 87 : * store_gdbm_store - Implements StoreOps::store() - @ingroup store_store 88 : */ 89 4 : static int store_gdbm_store(void *store, const char *key, size_t klen, void *value, size_t vlen) 90 : { 91 4 : if (!store) 92 2 : return -1; 93 : 94 : datum dkey; 95 : datum databuf; 96 : 97 2 : GDBM_FILE db = store; 98 : 99 2 : dkey.dptr = (char *) key; 100 2 : dkey.dsize = klen; 101 : 102 2 : databuf.dsize = vlen; 103 2 : databuf.dptr = value; 104 : 105 2 : return gdbm_store(db, dkey, databuf, GDBM_REPLACE); 106 : } 107 : 108 : /** 109 : * store_gdbm_delete_record - Implements StoreOps::delete_record() - @ingroup store_delete_record 110 : */ 111 4 : static int store_gdbm_delete_record(void *store, const char *key, size_t klen) 112 : { 113 4 : if (!store) 114 2 : return -1; 115 : 116 : datum dkey; 117 : 118 2 : GDBM_FILE db = store; 119 : 120 2 : dkey.dptr = (char *) key; 121 2 : dkey.dsize = klen; 122 : 123 2 : return gdbm_delete(db, dkey); 124 : } 125 : 126 : /** 127 : * store_gdbm_close - Implements StoreOps::close() - @ingroup store_close 128 : */ 129 6 : static void store_gdbm_close(void **ptr) 130 : { 131 6 : if (!ptr || !*ptr) 132 4 : return; 133 : 134 2 : GDBM_FILE db = *ptr; 135 2 : gdbm_close(db); 136 2 : *ptr = NULL; 137 : } 138 : 139 : /** 140 : * store_gdbm_version - Implements StoreOps::version() - @ingroup store_version 141 : */ 142 2 : static const char *store_gdbm_version(void) 143 : { 144 2 : return gdbm_version; 145 : } 146 : 147 : STORE_BACKEND_OPS(gdbm)