merge db wrap code 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 2 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, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 /*
24   the stupidity of the unix fcntl locking design forces us to never
25   allow a database file to be opened twice in the same process. These
26   wrappers provide convenient access to a tdb or ldb, taking advantage
27   of talloc destructors to ensure that only a single open is done
28 */
29
30 #include "includes.h"
31 #include "lib/util/dlinklist.h"
32 #include "lib/events/events.h"
33 #include "lib/tdb/include/tdb.h"
34 #include "db_wrap.h"
35
36 static struct tdb_wrap *tdb_list;
37
38
39
40 /* destroy the last connection to a tdb */
41 static int tdb_wrap_destructor(struct tdb_wrap *w)
42 {
43         tdb_close(w->tdb);
44         DLIST_REMOVE(tdb_list, w);
45         return 0;
46 }                                
47
48 /*
49   wrapped connection to a tdb database
50   to close just talloc_free() the tdb_wrap pointer
51  */
52 struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx,
53                                const char *name, int hash_size, int tdb_flags,
54                                int open_flags, mode_t mode)
55 {
56         struct tdb_wrap *w;
57
58         for (w=tdb_list;w;w=w->next) {
59                 if (strcmp(name, w->name) == 0) {
60                         return talloc_reference(mem_ctx, w);
61                 }
62         }
63
64         w = talloc(mem_ctx, struct tdb_wrap);
65         if (w == NULL) {
66                 return NULL;
67         }
68
69         w->name = talloc_strdup(w, name);
70
71         w->tdb = tdb_open(name, hash_size, tdb_flags, 
72                           open_flags, mode);
73         if (w->tdb == NULL) {
74                 talloc_free(w);
75                 return NULL;
76         }
77
78         talloc_set_destructor(w, tdb_wrap_destructor);
79
80         DLIST_ADD(tdb_list, w);
81
82         return w;
83 }