]>
git.ipfire.org Git - thirdparty/glibc.git/blob - nss/nss_db/db-open.c
c3a06794854a281c9475726856336fd235c013e7
1 /* Common database open/close routines for nss_db.
2 Copyright (C) 1999, 2000 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
24 #include <bits/libc-lock.h>
30 /* This file contains the functions used to open and close the databases
31 read by the rest of libnss_db. They are not thread safe; the caller
34 We dynamically load the database library, so that it does not have
35 to be present when glibc is compiled. Once loaded, libdb is never
36 unloaded again unless this library is unloaded (from the free_mem
37 routine in nsswitch.c) - we catch the unload by providing a shlib
38 destructor. (XXX Does it work?) */
40 static void *libdb_handle
;
46 static int (*libdb_db_open
) (const char *, int,
47 uint32_t, int, void *, void *, void **);
49 /* Locks the static variables in this file. */
50 __libc_lock_define_initialized (static, lock
)
52 /* Dynamically load the database library.
53 We try libdb2.so.3, maybe others in the future. */
57 static const char *libnames
[] = { "libdb.so.3" };
60 for(x
= 0; x
< sizeof (libnames
) / sizeof (libnames
[0]); ++x
)
62 libdb_handle
= dlopen (libnames
[x
], RTLD_LAZY
);
63 if (libdb_handle
== NULL
)
66 libdb_db_open
= dlsym (libdb_handle
, "db_open");
67 if (libdb_db_open
!= NULL
)
69 /* Alright, we got a library. Now find out which version it is. */
70 const char *(*db_version
) (int *, int *, int *);
72 db_version
= dlsym (libdb_handle
, "db_version");
73 if (db_version
!= NULL
)
75 /* Call the function and get the information. */
76 int major
, minor
, subminor
;
78 DL_CALL_FCT (db_version
, (&major
, &minor
, &subminor
));
81 /* We currently cannot handle other versions than the
83 if (minor
< 6 || (minor
== 6 && subminor
< 4))
90 if (libdb_version
!= nodb
)
94 dlclose (libdb_handle
);
102 /* Make sure we don't use the library anymore once we are shutting down. */
103 static void __attribute__ ((destructor
))
106 if (libdb_handle
!= NULL
)
108 libdb_db_open
= NULL
;
109 libdb_version
= nodb
;
110 dlclose (libdb_handle
);
116 internal_setent (const char *file
, NSS_DB
**dbp
)
118 enum nss_status status
= NSS_STATUS_SUCCESS
;
124 if (libdb_db_open
== NULL
)
126 __libc_lock_lock (lock
);
130 __libc_lock_unlock (lock
);
133 return NSS_STATUS_UNAVAIL
;
136 /* Open the database. Fortunately this interface seems to be the
137 same for all supported versions. */
138 err
= DL_CALL_FCT (libdb_db_open
,
139 (file
, DB_BTREE
, DB_RDONLY
, 0, NULL
, NULL
, &db
));
141 /* Construct the object we pass up. */
142 *dbp
= (NSS_DB
*) malloc (sizeof (NSS_DB
));
147 /* The functions are at different positions for the different
149 switch (libdb_version
)
153 (int (*) (void *, uint32_t)) ((struct db24
*) db
)->close
;
155 (int (*) (void *, int *)) ((struct db24
*) db
)->fd
;
157 (int (*) (void *, void *, void *, void *, uint32_t))
158 ((struct db24
*) db
)->get
;
162 (int (*) (void *, uint32_t)) ((struct db27
*) db
)->close
;
164 (int (*) (void *, int *)) ((struct db27
*) db
)->fd
;
166 (int (*) (void *, void *, void *, void *, uint32_t))
167 ((struct db27
*) db
)->get
;
178 status
= err
== EAGAIN
? NSS_STATUS_TRYAGAIN
: NSS_STATUS_UNAVAIL
;
182 /* We have to make sure the file is `closed on exec'. */
186 err
= DL_CALL_FCT ((*dbp
)->fd
, (db
, &fd
));
194 int flags
= result
= fcntl (fd
, F_GETFD
, 0);
199 result
= fcntl (fd
, F_SETFD
, flags
);
204 /* Something went wrong. Close the stream and return a
206 DL_CALL_FCT ((*dbp
)->close
, (db
, 0));
207 status
= NSS_STATUS_UNAVAIL
;
219 /* Close the database file. */
221 internal_endent (NSS_DB
**dbp
)
226 DL_CALL_FCT (db
->close
, (db
->db
, 0));