2 * libdpkg - Debian packaging suite library routines
3 * dump.c - code to write in-core database to a file
5 * Copyright © 1995 Ian Jackson <ian@chiark.greenend.org.uk>
6 * Copyright © 2001 Wichert Akkerman
7 * Copyright © 2006,2008-2012 Guillem Jover <guillem@debian.org>
8 * Copyright © 2011 Linaro Limited
9 * Copyright © 2011 Raphaël Hertzog <hertzog@debian.org>
11 * This is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 /* FIXME: Don't write uninteresting packages. */
30 #include <sys/types.h>
42 #include <dpkg/i18n.h>
43 #include <dpkg/dpkg.h>
44 #include <dpkg/dpkg-db.h>
45 #include <dpkg/string.h>
47 #include <dpkg/parsedump.h>
50 w_name(struct varbuf *vb,
51 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
52 enum fwriteflags flags, const struct fieldinfo *fip)
54 assert(pkg->set->name);
55 if (flags&fw_printheader)
56 varbuf_add_str(vb, "Package: ");
57 varbuf_add_str(vb, pkg->set->name);
58 if (flags&fw_printheader)
59 varbuf_add_char(vb, '\n');
63 w_version(struct varbuf *vb,
64 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
65 enum fwriteflags flags, const struct fieldinfo *fip)
67 if (!dpkg_version_is_informative(&pkgbin->version))
69 if (flags&fw_printheader)
70 varbuf_add_str(vb, "Version: ");
71 varbufversion(vb, &pkgbin->version, vdew_nonambig);
72 if (flags&fw_printheader)
73 varbuf_add_char(vb, '\n');
77 w_configversion(struct varbuf *vb,
78 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
79 enum fwriteflags flags, const struct fieldinfo *fip)
81 if (pkgbin != &pkg->installed)
83 if (!dpkg_version_is_informative(&pkg->configversion))
85 if (pkg->status == stat_installed ||
86 pkg->status == stat_notinstalled ||
87 pkg->status == stat_triggerspending)
89 if (flags&fw_printheader)
90 varbuf_add_str(vb, "Config-Version: ");
91 varbufversion(vb, &pkg->configversion, vdew_nonambig);
92 if (flags&fw_printheader)
93 varbuf_add_char(vb, '\n');
97 w_null(struct varbuf *vb,
98 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
99 enum fwriteflags flags, const struct fieldinfo *fip)
104 w_section(struct varbuf *vb,
105 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
106 enum fwriteflags flags, const struct fieldinfo *fip)
108 const char *value = pkg->section;
110 if (str_is_unset(value))
112 if (flags&fw_printheader)
113 varbuf_add_str(vb, "Section: ");
114 varbuf_add_str(vb, value);
115 if (flags&fw_printheader)
116 varbuf_add_char(vb, '\n');
120 w_charfield(struct varbuf *vb,
121 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
122 enum fwriteflags flags, const struct fieldinfo *fip)
124 const char *value = PKGPFIELD(pkgbin, fip->integer, const char *);
126 if (str_is_unset(value))
128 if (flags&fw_printheader) {
129 varbuf_add_str(vb, fip->name);
130 varbuf_add_str(vb, ": ");
132 varbuf_add_str(vb, value);
133 if (flags&fw_printheader)
134 varbuf_add_char(vb, '\n');
138 w_filecharf(struct varbuf *vb,
139 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
140 enum fwriteflags flags, const struct fieldinfo *fip)
142 struct filedetails *fdp;
144 if (pkgbin != &pkg->available)
147 if (!fdp || !FILEFFIELD(fdp,fip->integer,const char*)) return;
149 if (flags&fw_printheader) {
150 varbuf_add_str(vb, fip->name);
151 varbuf_add_char(vb, ':');
155 varbuf_add_char(vb, ' ');
156 varbuf_add_str(vb, FILEFFIELD(fdp, fip->integer, const char *));
160 if (flags&fw_printheader)
161 varbuf_add_char(vb, '\n');
165 w_booleandefno(struct varbuf *vb,
166 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
167 enum fwriteflags flags, const struct fieldinfo *fip)
169 bool value = PKGPFIELD(pkgbin, fip->integer, bool);
171 if ((flags & fw_printheader) && !value)
174 if (flags & fw_printheader) {
175 varbuf_add_str(vb, fip->name);
176 varbuf_add_str(vb, ": ");
179 varbuf_add_str(vb, value ? "yes" : "no");
181 if (flags & fw_printheader)
182 varbuf_add_char(vb, '\n');
186 w_multiarch(struct varbuf *vb,
187 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
188 enum fwriteflags flags, const struct fieldinfo *fip)
190 int value = PKGPFIELD(pkgbin, fip->integer, int);
192 if ((flags & fw_printheader) && !value)
195 if (flags & fw_printheader) {
196 varbuf_add_str(vb, fip->name);
197 varbuf_add_str(vb, ": ");
200 varbuf_add_str(vb, multiarchinfos[value].name);
202 if (flags & fw_printheader)
203 varbuf_add_char(vb, '\n');
207 w_architecture(struct varbuf *vb,
208 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
209 enum fwriteflags flags, const struct fieldinfo *fip)
213 if (pkgbin->arch->type == arch_none)
215 if (pkgbin->arch->type == arch_empty)
218 if (flags & fw_printheader) {
219 varbuf_add_str(vb, fip->name);
220 varbuf_add_str(vb, ": ");
222 varbuf_add_str(vb, pkgbin->arch->name);
223 if (flags & fw_printheader)
224 varbuf_add_char(vb, '\n');
228 w_priority(struct varbuf *vb,
229 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
230 enum fwriteflags flags, const struct fieldinfo *fip)
232 if (pkg->priority == pri_unknown)
234 assert(pkg->priority <= pri_unknown);
235 if (flags&fw_printheader)
236 varbuf_add_str(vb, "Priority: ");
237 varbuf_add_str(vb, pkg->priority == pri_other ?
239 priorityinfos[pkg->priority].name);
240 if (flags&fw_printheader)
241 varbuf_add_char(vb, '\n');
245 w_status(struct varbuf *vb,
246 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
247 enum fwriteflags flags, const struct fieldinfo *fip)
249 if (pkgbin != &pkg->installed)
251 assert(pkg->want <= want_purge);
252 assert(pkg->eflag <= eflag_reinstreq);
254 #define PEND pkg->trigpend_head
255 #define AW pkg->trigaw.head
256 switch (pkg->status) {
257 case stat_notinstalled:
258 case stat_configfiles:
262 case stat_halfinstalled:
264 case stat_halfconfigured:
267 case stat_triggersawaited:
270 case stat_triggerspending:
279 internerr("unknown package status '%d'", pkg->status);
284 if (flags&fw_printheader)
285 varbuf_add_str(vb, "Status: ");
286 varbuf_add_str(vb, wantinfos[pkg->want].name);
287 varbuf_add_char(vb, ' ');
288 varbuf_add_str(vb, eflaginfos[pkg->eflag].name);
289 varbuf_add_char(vb, ' ');
290 varbuf_add_str(vb, statusinfos[pkg->status].name);
291 if (flags&fw_printheader)
292 varbuf_add_char(vb, '\n');
295 void varbufdependency(struct varbuf *vb, struct dependency *dep) {
296 struct deppossi *dop;
300 for (dop= dep->list; dop; dop= dop->next) {
301 assert(dop->up == dep);
302 varbuf_add_str(vb, possdel);
304 varbuf_add_str(vb, dop->ed->name);
305 if (!dop->arch_is_implicit)
306 varbuf_add_archqual(vb, dop->arch);
307 if (dop->verrel != dpkg_relation_none) {
308 varbuf_add_str(vb, " (");
309 switch (dop->verrel) {
310 case dpkg_relation_eq:
311 varbuf_add_char(vb, '=');
313 case dpkg_relation_ge:
314 varbuf_add_str(vb, ">=");
316 case dpkg_relation_le:
317 varbuf_add_str(vb, "<=");
319 case dpkg_relation_gt:
320 varbuf_add_str(vb, ">>");
322 case dpkg_relation_lt:
323 varbuf_add_str(vb, "<<");
326 internerr("unknown dpkg_relation %d", dop->verrel);
328 varbuf_add_char(vb, ' ');
329 varbufversion(vb,&dop->version,vdew_nonambig);
330 varbuf_add_char(vb, ')');
336 w_dependency(struct varbuf *vb,
337 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
338 enum fwriteflags flags, const struct fieldinfo *fip)
342 struct dependency *dyp;
344 if (flags&fw_printheader)
345 sprintf(fnbuf,"%s: ",fip->name);
350 for (dyp = pkgbin->depends; dyp; dyp = dyp->next) {
351 if (dyp->type != fip->integer) continue;
352 assert(dyp->up == pkg);
353 varbuf_add_str(vb, depdel);
355 varbufdependency(vb,dyp);
357 if ((flags&fw_printheader) && (depdel!=fnbuf))
358 varbuf_add_char(vb, '\n');
362 w_conffiles(struct varbuf *vb,
363 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
364 enum fwriteflags flags, const struct fieldinfo *fip)
368 if (!pkgbin->conffiles || pkgbin == &pkg->available)
370 if (flags&fw_printheader)
371 varbuf_add_str(vb, "Conffiles:\n");
372 for (i = pkgbin->conffiles; i; i = i->next) {
373 if (i != pkgbin->conffiles)
374 varbuf_add_char(vb, '\n');
375 varbuf_add_char(vb, ' ');
376 varbuf_add_str(vb, i->name);
377 varbuf_add_char(vb, ' ');
378 varbuf_add_str(vb, i->hash);
380 varbuf_add_str(vb, " obsolete");
382 if (flags&fw_printheader)
383 varbuf_add_char(vb, '\n');
387 w_trigpend(struct varbuf *vb,
388 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
389 enum fwriteflags flags, const struct fieldinfo *fip)
393 if (pkgbin == &pkg->available || !pkg->trigpend_head)
396 assert(pkg->status >= stat_triggersawaited &&
397 pkg->status <= stat_triggerspending);
399 if (flags & fw_printheader)
400 varbuf_add_str(vb, "Triggers-Pending:");
401 for (tp = pkg->trigpend_head; tp; tp = tp->next) {
402 varbuf_add_char(vb, ' ');
403 varbuf_add_str(vb, tp->name);
405 if (flags & fw_printheader)
406 varbuf_add_char(vb, '\n');
410 w_trigaw(struct varbuf *vb,
411 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
412 enum fwriteflags flags, const struct fieldinfo *fip)
416 if (pkgbin == &pkg->available || !pkg->trigaw.head)
419 assert(pkg->status > stat_configfiles &&
420 pkg->status <= stat_triggersawaited);
422 if (flags & fw_printheader)
423 varbuf_add_str(vb, "Triggers-Awaited:");
424 for (ta = pkg->trigaw.head; ta; ta = ta->sameaw.next) {
425 varbuf_add_char(vb, ' ');
426 varbuf_add_pkgbin_name(vb, ta->pend, &ta->pend->installed, pnaw_nonambig);
428 if (flags & fw_printheader)
429 varbuf_add_char(vb, '\n');
433 varbufrecord(struct varbuf *vb,
434 const struct pkginfo *pkg, const struct pkgbin *pkgbin)
436 const struct fieldinfo *fip;
437 const struct arbitraryfield *afp;
439 for (fip= fieldinfos; fip->name; fip++) {
440 fip->wcall(vb, pkg, pkgbin, fw_printheader, fip);
442 for (afp = pkgbin->arbs; afp; afp = afp->next) {
443 varbuf_add_str(vb, afp->name);
444 varbuf_add_str(vb, ": ");
445 varbuf_add_str(vb, afp->value);
446 varbuf_add_char(vb, '\n');
451 writerecord(FILE *file, const char *filename,
452 const struct pkginfo *pkg, const struct pkgbin *pkgbin)
454 struct varbuf vb = VARBUF_INIT;
456 varbufrecord(&vb, pkg, pkgbin);
458 if (fputs(vb.buf,file) < 0) {
459 struct varbuf pkgname = VARBUF_INIT;
460 int errno_saved = errno;
462 varbuf_add_pkgbin_name(&pkgname, pkg, pkgbin, pnaw_nonambig);
465 ohshite(_("failed to write details of `%.50s' to `%.250s'"),
466 pkgname.buf, filename);
473 writedb(const char *filename, enum writedb_flags flags)
475 static char writebuf[8192];
477 struct pkgiterator *it;
479 struct pkgbin *pkgbin;
481 struct atomic_file *file;
482 struct varbuf vb = VARBUF_INIT;
484 which = (flags & wdb_dump_available) ? "available" : "status";
486 file = atomic_file_new(filename, aff_backup);
487 atomic_file_open(file);
488 if (setvbuf(file->fp, writebuf, _IOFBF, sizeof(writebuf)))
489 ohshite(_("unable to set buffering on %s database file"), which);
491 it = pkg_db_iter_new();
492 while ((pkg = pkg_db_iter_next_pkg(it)) != NULL) {
493 pkgbin = (flags & wdb_dump_available) ? &pkg->available : &pkg->installed;
494 /* Don't dump records which have no useful content. */
495 if (!pkg_is_informative(pkg, pkgbin))
497 varbufrecord(&vb, pkg, pkgbin);
498 varbuf_add_char(&vb, '\n');
500 if (fputs(vb.buf, file->fp) < 0)
501 ohshite(_("failed to write %s database record about '%.50s' to '%.250s'"),
502 which, pkgbin_name(pkg, pkgbin, pnaw_nonambig), filename);
505 pkg_db_iter_free(it);
507 if (flags & wdb_must_sync)
508 atomic_file_sync(file);
510 atomic_file_close(file);
511 atomic_file_commit(file);
512 atomic_file_free(file);
514 if (flags & wdb_must_sync)
515 dir_sync_path_parent(filename);