update lib/replace from samba4
[vlendec/samba-autobuild/.git] / ctdb / lib / util / db_wrap.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    database wrap functions
5
6    Copyright (C) Andrew Tridgell 2004
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, see <http://www.gnu.org/licenses/>.
20 */
21
22 /*
23   the stupidity of the unix fcntl locking design forces us to never
24   allow a database file to be opened twice in the same process. These
25   wrappers provide convenient access to a tdb or ldb, taking advantage
26   of talloc destructors to ensure that only a single open is done
27 */
28
29 #include "includes.h"
30 #include "lib/util/dlinklist.h"
31 #include "lib/events/events.h"
32 #include "lib/tdb/include/tdb.h"
33 #include "db_wrap.h"
34
35 static struct tdb_wrap *tdb_list;
36
37
38
39 /* destroy the last connection to a tdb */
40 static int tdb_wrap_destructor(struct tdb_wrap *w)
41 {
42         tdb_close(w->tdb);
43         DLIST_REMOVE(tdb_list, w);
44         return 0;
45 }                                
46
47 /*
48   wrapped connection to a tdb database
49   to close just talloc_free() the tdb_wrap pointer
50  */
51 struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx,
52                                const char *name, int hash_size, int tdb_flags,
53                                int open_flags, mode_t mode)
54 {
55         struct tdb_wrap *w;
56
57         for (w=tdb_list;w;w=w->next) {
58                 if (strcmp(name, w->name) == 0) {
59                         return talloc_reference(mem_ctx, w);
60                 }
61         }
62
63         w = talloc(mem_ctx, struct tdb_wrap);
64         if (w == NULL) {
65                 return NULL;
66         }
67
68         w->name = talloc_strdup(w, name);
69
70         w->tdb = tdb_open(name, hash_size, tdb_flags, 
71                           open_flags, mode);
72         if (w->tdb == NULL) {
73                 talloc_free(w);
74                 return NULL;
75         }
76
77         talloc_set_destructor(w, tdb_wrap_destructor);
78
79         DLIST_ADD(tdb_list, w);
80
81         return w;
82 }