]> arthur.barton.de Git - netatalk.git/blob - libatalk/cnid/db3/cnid_db3_close.c
b309c947f04128a69b25d251f88f75ddfb4802fc
[netatalk.git] / libatalk / cnid / db3 / cnid_db3_close.c
1 /*
2  * $Id: cnid_db3_close.c,v 1.2 2005-04-28 20:49:59 bfernhomberg Exp $
3  */
4
5 #ifdef HAVE_CONFIG_H
6 #include "config.h"
7 #endif /* HAVE_CONFIG_H */
8
9 #ifdef CNID_BACKEND_DB3
10
11 #ifdef HAVE_UNISTD_H
12 #include <unistd.h>
13 #endif /* HAVE_UNISTD_H */
14 #ifdef HAVE_FCNTL_H
15 #include <fcntl.h>
16 #endif /* HAVE_FCNTL_H */
17 #include <stdlib.h>
18 #include <atalk/logger.h>
19 #ifdef HAVE_DB4_DB_H
20 #include <db4/db.h>
21 #else
22 #include <db.h>
23 #endif
24 #include <errno.h>
25 #include <string.h>
26
27 #include "cnid_db3_private.h"
28 #include "cnid_db3.h"
29
30 void cnid_db3_close(struct _cnid_db *cdb) {
31     CNID_private *db;
32     int rc;
33
34     if (!cdb) {
35             LOG(log_error, logtype_afpd, "cnid_close called with NULL argument !");
36             return;
37     }
38
39     if (!(db = cdb->_private)) {
40         return;
41     }
42
43     /* Flush the transaction log and delete the log file if we can. */
44     if ((db->lockfd > -1) && ((db->flags & CNIDFLAG_DB_RO) == 0)) {
45         struct flock lock;
46
47     lock.l_type = F_WRLCK;
48     lock.l_whence = SEEK_SET;
49     lock.l_start = lock.l_len = 0;
50     if (fcntl(db->lockfd, F_SETLK, &lock) == 0) {
51             char **list, **first;
52
53
54             /* Checkpoint the databases until we can checkpoint no
55              * more. */
56 #if DB_VERSION_MAJOR >= 4
57 #if DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1
58             db->dbenv->txn_checkpoint(db->dbenv, 0, 0, 0);
59 #else
60             rc = db->dbenv->txn_checkpoint(db->dbenv, 0, 0, 0);
61 #endif /* DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1 */
62 #else
63             rc = txn_checkpoint(db->dbenv, 0, 0, 0);
64 #endif /* DB_VERSION_MAJOR >= 4 */
65 #if DB_VERSION_MAJOR < 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 1)
66             while (rc == DB_INCOMPLETE) {
67 #if DB_VERSION_MAJOR >= 4
68                 rc = db->dbenv->txn_checkpoint(db->dbenv, 0, 0, 0);
69 #else
70                 rc = txn_checkpoint(db->dbenv, 0, 0, 0);
71 #endif /* DB_VERSION_MAJOR >= 4 */
72             }
73 #endif /* DB_VERSION_MAJOR < 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 1) */
74
75 #if DB_VERSION_MAJOR >= 4
76             if ((rc = db->dbenv->log_archive(db->dbenv, &list, DB_ARCH_ABS)) != 0) {
77 #elif DB_VERSION_MINOR > 2
78             if ((rc = log_archive(db->dbenv, &list, DB_ARCH_ABS)) != 0) {
79 #else /* DB_VERSION_MINOR < 2 */
80             if ((rc = log_archive(db->dbenv, &list, DB_ARCH_ABS, NULL)) != 0) {
81 #endif /* DB_VERSION_MINOR */
82                 LOG(log_error, logtype_default, "cnid_close: Unable to archive logfiles: %s", db_strerror(rc));
83             }
84
85             if (list != NULL) {
86                 for (first = list; *list != NULL; ++list) {
87                     if ((rc = remove(*list)) != 0) {
88 #ifdef DEBUG
89                             LOG(log_info, logtype_default, "cnid_close: failed to remove %s: %s", *list, strerror(rc));
90 #endif
91                         }
92                 }
93                 free(first);
94             }
95         }
96         (void)remove(db->lock_file);
97     }
98
99     db->db_didname->close(db->db_didname, 0);
100     db->db_devino->close(db->db_devino, 0);
101     db->db_cnid->close(db->db_cnid, 0);
102     db->dbenv->close(db->dbenv, 0);
103
104     if (db->lockfd > -1) {
105         close(db->lockfd); /* This will also release any locks we have. */
106     }
107
108     free(db);
109     free(cdb->volpath);
110     free(cdb);
111 }
112
113 #endif /* CNID_BACKEND_DB3 */