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