2
* dpkg - main program for package management
3
* infodb.c - package control information database
5
* Copyright © 1995 Ian Jackson <ian@chiark.greenend.org.uk>
6
* Copyright © 2011 Guillem Jover <guillem@debian.org>
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.
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.
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/>.
25
#include <sys/types.h>
34
#include <dpkg/i18n.h>
35
#include <dpkg/dpkg.h>
36
#include <dpkg/dpkg-db.h>
38
#include <dpkg/fdio.h>
39
#include <dpkg/debug.h>
40
#include <dpkg/varbuf.h>
45
/* Forward declarations of static functions */
46
static void pkg_infodb_upgrade_to_multiarch(void);
48
/* Global variables */
50
static char *db_format_file;
53
pkg_infodb_init(const enum modstatdb_rw flags)
59
db_format_file = dpkg_db_get_path("format");
60
fd = open(db_format_file, O_RDONLY);
61
if (fd < 0 && errno == ENOENT) {
62
db_format = 0; /* Lack of file means old format */
64
ohshite(_("error trying to open %.250s"), db_format_file);
66
char format[16], *endptr = NULL;
69
size = fd_read(fd, format, sizeof(format) - 1);
71
ohshite(_("error while reading %s"), db_format_file);
74
db_format = strtol(format, &endptr, 10);
75
if (endptr && *endptr != '\0' && *endptr != '\n')
76
ohshit(_("%s is corrupted, it should contain the "
77
"database format version (an integer)"),
81
if (flags >= msdbrw_write && db_format < 2)
82
pkg_infodb_upgrade_to_multiarch();
86
pkg_infodb_format(void)
92
struct match_node *next;
97
static struct match_node *match_head = NULL;
99
static struct match_node *
100
match_node_new(const char *old, const char *new, struct match_node *next)
102
struct match_node *node;
104
node = m_malloc(sizeof(*node));
106
node->old = m_strdup(old);
107
node->new = m_strdup(new);
113
match_node_free(struct match_node *node)
121
pkg_infodb_setup_multiarch_path(const char *filename, const char *filetype)
123
static struct varbuf pkgname;
124
const char *name, *dot;
128
dot = strrchr(filename, '.');
129
name = strrchr(filename, '/');
135
varbuf_reset(&pkgname);
136
varbuf_add_buf(&pkgname, name, dot - name);
137
varbuf_end_str(&pkgname);
139
if (strchr(pkgname.buf, ':'))
140
return; /* Skip files already converted */
142
set = pkg_db_find_set(pkgname.buf);
145
if (pkg->status != stat_notinstalled)
147
pkg = pkg->arch_next;
150
warning(_("Info file %s not associated to any package"), filename);
153
if (pkg->installed.multiarch == multiarch_same) {
154
/* We found one to ugprade */
155
struct varbuf new = VARBUF_INIT;
158
varbuf_add_str(&new, pkgadmindir());
159
varbuf_pkg(&new, pkg, pdo_always);
160
varbuf_add_char(&new, '.');
161
varbuf_add_str(&new, filetype);
162
varbuf_end_str(&new);
163
if (stat(new.buf, &st) && errno == ENOENT) {
164
if (link(filename, new.buf))
165
ohshite(_("error creating hard link `%.255s'"),
168
match_head = match_node_new(filename, new.buf, match_head);
169
varbuf_destroy(&new);
174
pkg_infodb_record_format(int version)
180
size = snprintf(format, sizeof(format), "%d", version);
181
fd = open(db_format_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
183
ohshite(_("unable to open/create '%s'"), db_format_file);
184
written = fd_write(fd, format, size);
186
ohshite(_("error while writing '%s'"), db_format_file);
189
ohshite(_("unable to sync file '%s'"), db_format_file);
191
ohshite(_("unable to close file '%s'"), db_format_file);
192
dir_sync_path_parent(db_format_file);
197
cu_abort_db_upgrade(int argc, void **argv)
199
struct match_node *next;
202
/* Restore the old files if needed and drop the newly created files */
204
next = match_head->next;
205
if (stat(match_head->old, &st) && errno == ENOENT)
206
if (link(match_head->new, match_head->old))
207
ohshite(_("error creating hard link `%.255s'"),
209
if (unlink(match_head->new))
210
ohshite(_("cannot remove `%.250s'"), match_head->new);
211
match_node_free(match_head);
214
pkg_infodb_record_format(0);
218
pkg_infodb_upgrade_to_multiarch(void)
220
struct match_node *next;
222
push_cleanup(cu_abort_db_upgrade, ehflag_bombout, NULL, 0, 0);
223
pkg_infodb_foreach(NULL, NULL, pkg_infodb_setup_multiarch_path);
224
pkg_infodb_record_format(1);
226
next = match_head->next;
227
if (unlink(match_head->old))
228
ohshite(_("cannot remove `%.250s'"), match_head->old);
229
match_node_free(match_head);
232
pkg_infodb_record_format(2);
233
pop_cleanup(ehflag_normaltidy);
237
pkg_infodb_has_file(struct pkginfo *pkg, struct pkgbin *pkgbin,
240
const char *filename;
243
filename = pkgadminfile(pkg, pkgbin, name);
244
if (lstat(filename, &stab) == 0)
246
else if (errno == ENOENT)
249
ohshite(_("unable to check existence of `%.250s'"), filename);
253
pkg_infodb_foreach(struct pkginfo *pkg, struct pkgbin *pkgbin,
254
pkg_infodb_file_func *func)
257
struct dirent *db_de;
258
struct varbuf db_path = VARBUF_INIT;
259
struct varbuf pkgname = VARBUF_INIT;
263
varbuf_add_str(&pkgname, pkg->set->name);
264
if (pkgbin->multiarch == multiarch_same &&
265
pkg_infodb_format() > 0) {
266
varbuf_add_char(&pkgname, ':');
267
varbuf_add_str(&pkgname, pkgbin->arch->name);
269
varbuf_end_str(&pkgname);
272
varbuf_add_str(&db_path, pkgadmindir());
273
db_path_len = db_path.used;
274
varbuf_add_char(&db_path, '\0');
276
db_dir = opendir(db_path.buf);
278
ohshite(_("cannot read info directory"));
280
push_cleanup(cu_closedir, ~0, NULL, 0, 1, (void *)db_dir);
281
while ((db_de = readdir(db_dir)) != NULL) {
282
const char *filename, *filetype, *dot;
284
debug(dbg_veryverbose, "infodb foreach info file '%s'",
287
/* Ignore dotfiles, including ‘.’ and ‘..’. */
288
if (db_de->d_name[0] == '.')
291
/* Ignore anything odd. */
292
dot = strrchr(db_de->d_name, '.');
296
/* Ignore files from other packages if pkg is supplied. */
298
if (pkgname.used != (size_t)(dot - db_de->d_name) ||
299
strncmp(db_de->d_name, pkgname.buf, pkgname.used))
301
debug(dbg_stupidlyverbose,
302
"infodb foreach file this pkg");
305
/* Skip past the full stop. */
308
varbuf_trunc(&db_path, db_path_len);
309
varbuf_add_str(&db_path, db_de->d_name);
310
varbuf_end_str(&db_path);
311
filename = db_path.buf;
313
func(filename, filetype);
315
pop_cleanup(ehflag_normaltidy); /* closedir */
317
varbuf_destroy(&db_path);
318
varbuf_destroy(&pkgname);