1 /*
2 * dpkg - main program for package management
3 * infodb.c - package control information database
4 *
5 * Copyright © 1995 Ian Jackson <ian@chiark.greenend.org.uk>
6 * Copyright © 2011 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 <http://www.gnu.org/licenses/>.
20 */
22 #include <config.h>
23 #include <compat.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
28 #include <errno.h>
29 #include <dirent.h>
30 #include <unistd.h>
32 #include <dpkg/i18n.h>
33 #include <dpkg/dpkg.h>
34 #include <dpkg/dpkg-db.h>
35 #include <dpkg/debug.h>
37 #include "filesdb.h"
38 #include "infodb.h"
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;
47 filename = pkgadminfile(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 }
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 db_path = VARBUF_INIT;
63 size_t db_path_len;
65 varbuf_add_str(&db_path, pkgadmindir());
66 varbuf_add_char(&db_path, '/');
67 db_path_len = db_path.used;
68 varbuf_add_char(&db_path, '\0');
70 db_dir = opendir(db_path.buf);
71 if (!db_dir)
72 ohshite(_("cannot read info directory"));
74 push_cleanup(cu_closedir, ~0, NULL, 0, 1, (void *)db_dir);
75 while ((db_de = readdir(db_dir)) != NULL) {
76 const char *filename, *filetype, *dot;
78 debug(dbg_veryverbose, "infodb foreach info file '%s'",
79 db_de->d_name);
81 /* Ignore dotfiles, including ‘.’ and ‘..’. */
82 if (db_de->d_name[0] == '.')
83 continue;
85 /* Ignore anything odd. */
86 dot = strrchr(db_de->d_name, '.');
87 if (dot == NULL)
88 continue;
90 /* Ignore files from other packages. */
91 if (strlen(pkg->set->name) != (size_t)(dot - db_de->d_name) ||
92 strncmp(db_de->d_name, pkg->set->name, dot - db_de->d_name))
93 continue;
95 debug(dbg_stupidlyverbose, "infodb foreach file this pkg");
97 /* Skip past the full stop. */
98 filetype = dot + 1;
100 varbuf_trunc(&db_path, db_path_len);
101 varbuf_add_str(&db_path, db_de->d_name);
102 varbuf_end_str(&db_path);
103 filename = db_path.buf;
105 func(filename, filetype);
106 }
107 pop_cleanup(ehflag_normaltidy); /* closedir */
109 varbuf_destroy(&db_path);
110 }
