Commit | Line | Data |
---|---|---|
1479465f GJ |
1 | /* |
2 | * dpkg - main program for package management | |
3 | * infodb.c - package control information database | |
4 | * | |
5 | * Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk> | |
6 | * Copyright © 2011-2014 Guillem Jover <guillem@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 | #include <dirent.h> | |
30 | #include <unistd.h> | |
31 | ||
32 | #include <dpkg/i18n.h> | |
33 | #include <dpkg/dpkg.h> | |
34 | #include <dpkg/dpkg-db.h> | |
35 | #include <dpkg/debug.h> | |
36 | ||
37 | #include "filesdb.h" | |
38 | #include "infodb.h" | |
39 | ||
40 | bool | |
41 | pkg_infodb_has_file(struct pkginfo *pkg, struct pkgbin *pkgbin, | |
42 | const char *name) | |
43 | { | |
44 | const char *filename; | |
45 | struct stat stab; | |
46 | ||
47 | filename = pkg_infodb_get_file(pkg, pkgbin, name); | |
48 | if (lstat(filename, &stab) == 0) | |
49 | return true; | |
50 | else if (errno == ENOENT) | |
51 | return false; | |
52 | else | |
53 | ohshite(_("unable to check existence of '%.250s'"), filename); | |
54 | } | |
55 | ||
56 | void | |
57 | pkg_infodb_foreach(struct pkginfo *pkg, struct pkgbin *pkgbin, | |
58 | pkg_infodb_file_func *func) | |
59 | { | |
60 | DIR *db_dir; | |
61 | struct dirent *db_de; | |
62 | struct varbuf_state db_path_state; | |
63 | struct varbuf db_path = VARBUF_INIT; | |
64 | const char *pkgname; | |
65 | enum pkg_infodb_format db_format; | |
66 | ||
67 | /* Make sure to always read and verify the format version. */ | |
68 | db_format = pkg_infodb_get_format(); | |
69 | ||
70 | if (pkgbin->multiarch == PKG_MULTIARCH_SAME && | |
71 | db_format == PKG_INFODB_FORMAT_MULTIARCH) | |
72 | pkgname = pkgbin_name(pkg, pkgbin, pnaw_always); | |
73 | else | |
74 | pkgname = pkgbin_name(pkg, pkgbin, pnaw_never); | |
75 | ||
76 | varbuf_add_str(&db_path, pkg_infodb_get_dir()); | |
77 | varbuf_add_char(&db_path, '/'); | |
78 | varbuf_end_str(&db_path); | |
79 | varbuf_snapshot(&db_path, &db_path_state); | |
80 | ||
81 | db_dir = opendir(db_path.buf); | |
82 | if (!db_dir) | |
83 | ohshite(_("cannot read info directory")); | |
84 | ||
85 | push_cleanup(cu_closedir, ~0, NULL, 0, 1, (void *)db_dir); | |
86 | while ((db_de = readdir(db_dir)) != NULL) { | |
87 | const char *filename, *filetype, *dot; | |
88 | ||
89 | debug(dbg_veryverbose, "infodb foreach info file '%s'", | |
90 | db_de->d_name); | |
91 | ||
92 | /* Ignore dotfiles, including ‘.’ and ‘..’. */ | |
93 | if (db_de->d_name[0] == '.') | |
94 | continue; | |
95 | ||
96 | /* Ignore anything odd. */ | |
97 | dot = strrchr(db_de->d_name, '.'); | |
98 | if (dot == NULL) | |
99 | continue; | |
100 | ||
101 | /* Ignore files from other packages. */ | |
102 | if (strlen(pkgname) != (size_t)(dot - db_de->d_name) || | |
103 | strncmp(db_de->d_name, pkgname, dot - db_de->d_name)) | |
104 | continue; | |
105 | ||
106 | debug(dbg_stupidlyverbose, "infodb foreach file this pkg"); | |
107 | ||
108 | /* Skip past the full stop. */ | |
109 | filetype = dot + 1; | |
110 | ||
111 | varbuf_rollback(&db_path, &db_path_state); | |
112 | varbuf_add_str(&db_path, db_de->d_name); | |
113 | varbuf_end_str(&db_path); | |
114 | filename = db_path.buf; | |
115 | ||
116 | func(filename, filetype); | |
117 | } | |
118 | pop_cleanup(ehflag_normaltidy); /* closedir */ | |
119 | ||
120 | varbuf_destroy(&db_path); | |
121 | } |