]> arthur.barton.de Git - netatalk.git/blob - libatalk/cnid/cnid_close.c
5edd65d8ba65141e2e595fbffc40eeae028a0266
[netatalk.git] / libatalk / cnid / cnid_close.c
1 /*
2  * $Id: cnid_close.c,v 1.19 2002-01-04 04:45:48 sibaz 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     /* Flush the transaction log and delete the log file if we can. */
35     if ((db->lockfd > -1) && ((db->flags & CNIDFLAG_DB_RO) == 0)) {
36         struct flock lock;
37
38         lock.l_type = F_WRLCK;
39         lock.l_whence = SEEK_SET;
40         lock.l_start = lock.l_len = 0;
41         if (fcntl(db->lockfd, F_SETLK, &lock) == 0) {
42             char **list, **first;
43             int cfd = -1;
44
45             if ((cfd = open(db->close_file, O_RDWR | O_CREAT, 0666)) > -1) {
46
47                 /* Checkpoint the databases until we can checkpoint no
48                  * more. */
49                 rc = txn_checkpoint(db->dbenv, 0, 0, 0);
50                 while (rc == DB_INCOMPLETE) {
51                     rc = txn_checkpoint(db->dbenv, 0, 0, 0);
52                 }
53
54 #if DB_VERSION_MINOR > 2
55                 if ((rc = log_archive(db->dbenv, &list, DB_ARCH_LOG | DB_ARCH_ABS)) != 0) {
56 #else /* DB_VERSION_MINOR < 2 */
57                 if ((rc = log_archive(db->dbenv, &list, DB_ARCH_LOG | DB_ARCH_ABS, NULL)) != 0) {
58 #endif /* DB_VERSION_MINOR */
59                     LOG(log_error, logtype_default, "cnid_close: Unable to archive logfiles: %s",
60                            db_strerror(rc));
61                 }
62
63                 if (list != NULL) {
64                     for (first = list; *list != NULL; ++list) {
65                         if ((rc = remove(*list)) != 0) {
66 #ifdef DEBUG
67                             LOG(log_info, logtype_default, "cnid_close: failed to remove %s: %s",
68                                    *list, strerror(rc));
69 #endif
70                         }
71                     }
72                     free(first);
73                 }
74                 (void)remove(db->close_file);
75                 close(cfd);
76             }
77             else {
78                 LOG(log_error, logtype_default, "cnid_close: Failed to open database closing lock file: %s", strerror(errno));
79             }
80         }
81     }
82
83     db->db_didname->close(db->db_didname, 0);
84     db->db_devino->close(db->db_devino, 0);
85     db->db_cnid->close(db->db_cnid, 0);
86     db->dbenv->close(db->dbenv, 0);
87
88     if (db->lockfd > -1) {
89         close(db->lockfd); /* This will also release any locks we have. */
90     }
91
92     free(db);
93 }
94 #endif /* CNID_DB */