Branch data Line data Source code
1 : : /*
2 : : * libdpkg - Debian packaging suite library routines
3 : : * db-fsys-load.c - (re)loading of database of files installed on system
4 : : *
5 : : * Copyright © 2008-2024 Guillem Jover <guillem@debian.org>
6 : : * Copyright © 2022 Simon Richter <sjr@debian.org>
7 : : *
8 : : * This 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 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, see <https://www.gnu.org/licenses/>.
20 : : */
21 : :
22 : : #include <config.h>
23 : : #include <compat.h>
24 : :
25 : : #include <sys/types.h>
26 : : #include <sys/stat.h>
27 : :
28 : : #include <errno.h>
29 : :
30 : : #include <dpkg/dpkg.h>
31 : : #include <dpkg/dpkg-db.h>
32 : : #include <dpkg/db-fsys.h>
33 : : #include <dpkg/i18n.h>
34 : : #include <dpkg/debug.h>
35 : :
36 : : enum dpkg_db_error
37 : 74 : dpkg_db_reopen(struct dpkg_db *db)
38 : : {
39 : : struct stat st_next;
40 : : FILE *file_next;
41 : :
42 [ + - ]: 74 : if (db->pathname == NULL)
43 : 74 : db->pathname = dpkg_db_get_path(db->name);
44 : :
45 : 74 : onerr_abort++;
46 : :
47 : 74 : file_next = fopen(db->pathname, "r");
48 [ + + ]: 74 : if (!file_next) {
49 [ + + ]: 2 : if (errno != ENOENT)
50 : 1 : ohshite(_("cannot open %s file"), db->pathname);
51 : : } else {
52 : 72 : setcloexec(fileno(file_next), db->pathname);
53 : :
54 [ - + ]: 72 : if (fstat(fileno(file_next), &st_next))
55 : 0 : ohshite(_("cannot get %s file metadata"), db->pathname);
56 : :
57 : : /*
58 : : * We need to keep the database file open so that the
59 : : * filesystem cannot reuse the inode number (f.ex. during
60 : : * multiple dpkg-divert invocations in a maintainer script),
61 : : * otherwise the following check might turn true, and we
62 : : * would skip reloading a modified database.
63 : : */
64 [ - + ]: 72 : if (db->file &&
65 [ # # ]: 0 : db->st.st_dev == st_next.st_dev &&
66 [ # # ]: 0 : db->st.st_ino == st_next.st_ino) {
67 : 0 : fclose(file_next);
68 : 0 : onerr_abort--;
69 : :
70 : 0 : debug(dbg_general, "%s: unchanged %s, skipping",
71 : : __func__, db->pathname);
72 : 0 : return DPKG_DB_SAME;
73 : : }
74 : 72 : db->st = st_next;
75 : : }
76 [ - + ]: 73 : if (db->file)
77 : 0 : fclose(db->file);
78 : 73 : db->file = file_next;
79 : :
80 : 73 : onerr_abort--;
81 : :
82 [ + + ]: 73 : if (db->file) {
83 : 72 : debug(dbg_general, "%s: new %s, (re)loading",
84 : : __func__, db->pathname);
85 : 72 : return DPKG_DB_LOAD;
86 : : } else {
87 : 1 : debug(dbg_general, "%s: missing %s, resetting",
88 : : __func__, db->pathname);
89 : 1 : return DPKG_DB_NONE;
90 : : }
91 : : }
|