Dpkg::Vendor::Debian: Add support for new hardening branch feature
[dpkg.git] / lib / dpkg / dump.c
blobb27e5db9091c25fc171c81014ae6458851dd602c
1 /*
2 * libdpkg - Debian packaging suite library routines
3 * dump.c - code to write in-core database to a file
5 * Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
6 * Copyright © 2001 Wichert Akkerman
7 * Copyright © 2006,2008-2014 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 <https://www.gnu.org/licenses/>.
25 #include <config.h>
26 #include <compat.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
31 #include <errno.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <stdbool.h>
38 #include <dpkg/i18n.h>
39 #include <dpkg/dpkg.h>
40 #include <dpkg/dpkg-db.h>
41 #include <dpkg/pkg-array.h>
42 #include <dpkg/pkg-show.h>
43 #include <dpkg/string.h>
44 #include <dpkg/dir.h>
45 #include <dpkg/parsedump.h>
47 static inline void
48 varbuf_add_fieldname(struct varbuf *vb, const struct fieldinfo *fip)
50 varbuf_add_str(vb, fip->name);
51 varbuf_add_str(vb, ": ");
54 void
55 w_name(struct varbuf *vb,
56 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
57 enum fwriteflags flags, const struct fieldinfo *fip)
59 if (pkg->set->name == NULL)
60 internerr("pkgset has no name");
62 if (flags&fw_printheader)
63 varbuf_add_str(vb, "Package: ");
64 varbuf_add_str(vb, pkg->set->name);
65 if (flags&fw_printheader)
66 varbuf_add_char(vb, '\n');
69 void
70 w_version(struct varbuf *vb,
71 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
72 enum fwriteflags flags, const struct fieldinfo *fip)
74 if (!dpkg_version_is_informative(&pkgbin->version))
75 return;
76 if (flags&fw_printheader)
77 varbuf_add_str(vb, "Version: ");
78 varbufversion(vb, &pkgbin->version, vdew_nonambig);
79 if (flags&fw_printheader)
80 varbuf_add_char(vb, '\n');
83 void
84 w_configversion(struct varbuf *vb,
85 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
86 enum fwriteflags flags, const struct fieldinfo *fip)
88 if (pkgbin != &pkg->installed)
89 return;
90 if (!dpkg_version_is_informative(&pkg->configversion))
91 return;
92 if (pkg->status == PKG_STAT_INSTALLED ||
93 pkg->status == PKG_STAT_NOTINSTALLED ||
94 pkg->status == PKG_STAT_TRIGGERSPENDING)
95 return;
96 if (flags&fw_printheader)
97 varbuf_add_str(vb, "Config-Version: ");
98 varbufversion(vb, &pkg->configversion, vdew_nonambig);
99 if (flags&fw_printheader)
100 varbuf_add_char(vb, '\n');
103 void
104 w_null(struct varbuf *vb,
105 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
106 enum fwriteflags flags, const struct fieldinfo *fip)
110 void
111 w_section(struct varbuf *vb,
112 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
113 enum fwriteflags flags, const struct fieldinfo *fip)
115 const char *value = pkg->section;
117 if (str_is_unset(value))
118 return;
119 if (flags&fw_printheader)
120 varbuf_add_str(vb, "Section: ");
121 varbuf_add_str(vb, value);
122 if (flags&fw_printheader)
123 varbuf_add_char(vb, '\n');
126 void
127 w_charfield(struct varbuf *vb,
128 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
129 enum fwriteflags flags, const struct fieldinfo *fip)
131 const char *value = STRUCTFIELD(pkgbin, fip->integer, const char *);
133 if (str_is_unset(value))
134 return;
135 if (flags & fw_printheader)
136 varbuf_add_fieldname(vb, fip);
137 varbuf_add_str(vb, value);
138 if (flags&fw_printheader)
139 varbuf_add_char(vb, '\n');
142 void
143 w_archives(struct varbuf *vb,
144 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
145 enum fwriteflags flags, const struct fieldinfo *fip)
147 struct archivedetails *archive;
149 if (pkgbin != &pkg->available)
150 return;
151 archive = pkg->archives;
152 if (!archive || !STRUCTFIELD(archive, fip->integer, const char *))
153 return;
155 if (flags&fw_printheader) {
156 varbuf_add_str(vb, fip->name);
157 varbuf_add_char(vb, ':');
160 while (archive) {
161 varbuf_add_char(vb, ' ');
162 varbuf_add_str(vb, STRUCTFIELD(archive, fip->integer, const char *));
163 archive = archive->next;
166 if (flags&fw_printheader)
167 varbuf_add_char(vb, '\n');
170 void
171 w_booleandefno(struct varbuf *vb,
172 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
173 enum fwriteflags flags, const struct fieldinfo *fip)
175 bool value = STRUCTFIELD(pkgbin, fip->integer, bool);
177 if ((flags & fw_printheader) && !value)
178 return;
180 if (flags & fw_printheader)
181 varbuf_add_fieldname(vb, fip);
183 varbuf_add_str(vb, value ? "yes" : "no");
185 if (flags & fw_printheader)
186 varbuf_add_char(vb, '\n');
189 void
190 w_multiarch(struct varbuf *vb,
191 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
192 enum fwriteflags flags, const struct fieldinfo *fip)
194 int value = STRUCTFIELD(pkgbin, fip->integer, int);
196 if ((flags & fw_printheader) && !value)
197 return;
199 if (flags & fw_printheader)
200 varbuf_add_fieldname(vb, fip);
202 varbuf_add_str(vb, multiarchinfos[value].name);
204 if (flags & fw_printheader)
205 varbuf_add_char(vb, '\n');
208 void
209 w_architecture(struct varbuf *vb,
210 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
211 enum fwriteflags flags, const struct fieldinfo *fip)
213 if (!pkgbin->arch)
214 return;
215 if (pkgbin->arch->type == DPKG_ARCH_NONE)
216 return;
217 if (pkgbin->arch->type == DPKG_ARCH_EMPTY)
218 return;
220 if (flags & fw_printheader)
221 varbuf_add_fieldname(vb, fip);
222 varbuf_add_str(vb, pkgbin->arch->name);
223 if (flags & fw_printheader)
224 varbuf_add_char(vb, '\n');
227 void
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 == PKG_PRIO_UNKNOWN)
233 return;
235 if (pkg->priority > PKG_PRIO_UNKNOWN)
236 internerr("package %s has out-of-range priority %d",
237 pkgbin_name_const(pkg, pkgbin, pnaw_always), pkg->priority);
239 if (flags&fw_printheader)
240 varbuf_add_str(vb, "Priority: ");
241 varbuf_add_str(vb, pkg_priority_name(pkg));
242 if (flags&fw_printheader)
243 varbuf_add_char(vb, '\n');
246 void
247 w_status(struct varbuf *vb,
248 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
249 enum fwriteflags flags, const struct fieldinfo *fip)
251 if (pkgbin != &pkg->installed)
252 return;
254 if (pkg->want > PKG_WANT_PURGE)
255 internerr("package %s has unknown want state %d",
256 pkgbin_name_const(pkg, pkgbin, pnaw_always), pkg->want);
257 if (pkg->eflag > PKG_EFLAG_REINSTREQ)
258 internerr("package %s has unknown error state %d",
259 pkgbin_name_const(pkg, pkgbin, pnaw_always), pkg->eflag);
261 switch (pkg->status) {
262 case PKG_STAT_NOTINSTALLED:
263 case PKG_STAT_CONFIGFILES:
264 if (pkg->trigpend_head || pkg->trigaw.head)
265 internerr("package %s in state %s, has awaited or pending triggers",
266 pkgbin_name_const(pkg, pkgbin, pnaw_always), pkg_status_name(pkg));
267 break;
268 case PKG_STAT_HALFINSTALLED:
269 case PKG_STAT_UNPACKED:
270 case PKG_STAT_HALFCONFIGURED:
271 if (pkg->trigpend_head)
272 internerr("package %s in state %s, has pending triggers",
273 pkgbin_name_const(pkg, pkgbin, pnaw_always), pkg_status_name(pkg));
274 break;
275 case PKG_STAT_TRIGGERSAWAITED:
276 if (pkg->trigaw.head == NULL)
277 internerr("package %s in state %s, has no awaited triggers",
278 pkgbin_name_const(pkg, pkgbin, pnaw_always), pkg_status_name(pkg));
279 break;
280 case PKG_STAT_TRIGGERSPENDING:
281 if (pkg->trigpend_head == NULL || pkg->trigaw.head)
282 internerr("package %s in stata %s, has awaited or no pending triggers",
283 pkgbin_name_const(pkg, pkgbin, pnaw_always), pkg_status_name(pkg));
284 break;
285 case PKG_STAT_INSTALLED:
286 if (pkg->trigpend_head || pkg->trigaw.head)
287 internerr("package %s in state %s, has awaited or pending triggers",
288 pkgbin_name_const(pkg, pkgbin, pnaw_always), pkg_status_name(pkg));
289 break;
290 default:
291 internerr("unknown package status '%d'", pkg->status);
294 if (flags&fw_printheader)
295 varbuf_add_str(vb, "Status: ");
296 varbuf_add_str(vb, pkg_want_name(pkg));
297 varbuf_add_char(vb, ' ');
298 varbuf_add_str(vb, pkg_eflag_name(pkg));
299 varbuf_add_char(vb, ' ');
300 varbuf_add_str(vb, pkg_status_name(pkg));
301 if (flags&fw_printheader)
302 varbuf_add_char(vb, '\n');
305 void varbufdependency(struct varbuf *vb, struct dependency *dep) {
306 struct deppossi *dop;
307 const char *possdel;
309 possdel= "";
310 for (dop= dep->list; dop; dop= dop->next) {
311 if (dop->up != dep)
312 internerr("dependency and deppossi not linked properly");
314 varbuf_add_str(vb, possdel);
315 possdel = " | ";
316 varbuf_add_str(vb, dop->ed->name);
317 if (!dop->arch_is_implicit)
318 varbuf_add_archqual(vb, dop->arch);
319 if (dop->verrel != DPKG_RELATION_NONE) {
320 varbuf_add_str(vb, " (");
321 switch (dop->verrel) {
322 case DPKG_RELATION_EQ:
323 varbuf_add_char(vb, '=');
324 break;
325 case DPKG_RELATION_GE:
326 varbuf_add_str(vb, ">=");
327 break;
328 case DPKG_RELATION_LE:
329 varbuf_add_str(vb, "<=");
330 break;
331 case DPKG_RELATION_GT:
332 varbuf_add_str(vb, ">>");
333 break;
334 case DPKG_RELATION_LT:
335 varbuf_add_str(vb, "<<");
336 break;
337 default:
338 internerr("unknown dpkg_relation %d", dop->verrel);
340 varbuf_add_char(vb, ' ');
341 varbufversion(vb,&dop->version,vdew_nonambig);
342 varbuf_add_char(vb, ')');
347 void
348 w_dependency(struct varbuf *vb,
349 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
350 enum fwriteflags flags, const struct fieldinfo *fip)
352 struct dependency *dyp;
353 bool dep_found = false;
355 for (dyp = pkgbin->depends; dyp; dyp = dyp->next) {
356 if (dyp->type != fip->integer) continue;
358 if (dyp->up != pkg)
359 internerr("dependency and package %s not linked properly",
360 pkgbin_name_const(pkg, pkgbin, pnaw_always));
362 if (dep_found) {
363 varbuf_add_str(vb, ", ");
364 } else {
365 if (flags & fw_printheader)
366 varbuf_add_fieldname(vb, fip);
367 dep_found = true;
369 varbufdependency(vb,dyp);
371 if ((flags & fw_printheader) && dep_found)
372 varbuf_add_char(vb, '\n');
375 void
376 w_conffiles(struct varbuf *vb,
377 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
378 enum fwriteflags flags, const struct fieldinfo *fip)
380 struct conffile *i;
382 if (!pkgbin->conffiles || pkgbin == &pkg->available)
383 return;
384 if (flags&fw_printheader)
385 varbuf_add_str(vb, "Conffiles:\n");
386 for (i = pkgbin->conffiles; i; i = i->next) {
387 if (i != pkgbin->conffiles)
388 varbuf_add_char(vb, '\n');
389 varbuf_add_char(vb, ' ');
390 varbuf_add_str(vb, i->name);
391 varbuf_add_char(vb, ' ');
392 varbuf_add_str(vb, i->hash);
393 if (i->obsolete)
394 varbuf_add_str(vb, " obsolete");
395 if (i->remove_on_upgrade)
396 varbuf_add_str(vb, " remove-on-upgrade");
398 if (flags&fw_printheader)
399 varbuf_add_char(vb, '\n');
402 void
403 w_trigpend(struct varbuf *vb,
404 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
405 enum fwriteflags flags, const struct fieldinfo *fip)
407 struct trigpend *tp;
409 if (pkgbin == &pkg->available || !pkg->trigpend_head)
410 return;
412 if (pkg->status < PKG_STAT_TRIGGERSAWAITED ||
413 pkg->status > PKG_STAT_TRIGGERSPENDING)
414 internerr("package %s in non-trigger state %s, has pending triggers",
415 pkgbin_name_const(pkg, pkgbin, pnaw_always), pkg_status_name(pkg));
417 if (flags & fw_printheader)
418 varbuf_add_str(vb, "Triggers-Pending:");
419 for (tp = pkg->trigpend_head; tp; tp = tp->next) {
420 varbuf_add_char(vb, ' ');
421 varbuf_add_str(vb, tp->name);
423 if (flags & fw_printheader)
424 varbuf_add_char(vb, '\n');
427 void
428 w_trigaw(struct varbuf *vb,
429 const struct pkginfo *pkg, const struct pkgbin *pkgbin,
430 enum fwriteflags flags, const struct fieldinfo *fip)
432 struct trigaw *ta;
434 if (pkgbin == &pkg->available || !pkg->trigaw.head)
435 return;
437 if (pkg->status <= PKG_STAT_CONFIGFILES ||
438 pkg->status > PKG_STAT_TRIGGERSAWAITED)
439 internerr("package %s in state %s, has awaited triggers",
440 pkgbin_name_const(pkg, pkgbin, pnaw_always), pkg_status_name(pkg));
442 if (flags & fw_printheader)
443 varbuf_add_str(vb, "Triggers-Awaited:");
444 for (ta = pkg->trigaw.head; ta; ta = ta->sameaw.next) {
445 varbuf_add_char(vb, ' ');
446 varbuf_add_pkgbin_name(vb, ta->pend, &ta->pend->installed, pnaw_nonambig);
448 if (flags & fw_printheader)
449 varbuf_add_char(vb, '\n');
452 void
453 varbuf_add_arbfield(struct varbuf *vb, const struct arbitraryfield *arbfield,
454 enum fwriteflags flags)
456 if (flags & fw_printheader) {
457 varbuf_add_str(vb, arbfield->name);
458 varbuf_add_str(vb, ": ");
460 varbuf_add_str(vb, arbfield->value);
461 if (flags & fw_printheader)
462 varbuf_add_char(vb, '\n');
465 void
466 varbuf_stanza(struct varbuf *vb,
467 const struct pkginfo *pkg, const struct pkgbin *pkgbin)
469 const struct fieldinfo *fip;
470 const struct arbitraryfield *afp;
472 for (fip= fieldinfos; fip->name; fip++) {
473 fip->wcall(vb, pkg, pkgbin, fw_printheader, fip);
475 for (afp = pkgbin->arbs; afp; afp = afp->next) {
476 varbuf_add_arbfield(vb, afp, fw_printheader);
480 void
481 write_stanza(FILE *file, const char *filename,
482 const struct pkginfo *pkg, const struct pkgbin *pkgbin)
484 struct varbuf vb = VARBUF_INIT;
486 varbuf_stanza(&vb, pkg, pkgbin);
487 varbuf_end_str(&vb);
489 if (fputs(vb.buf, file) < 0)
490 ohshite(_("failed to write details of '%.50s' to '%.250s'"),
491 pkgbin_name_const(pkg, pkgbin, pnaw_nonambig), filename);
493 varbuf_destroy(&vb);
496 void
497 writedb_stanzas(FILE *fp, const char *filename, enum writedb_flags flags)
499 static char writebuf[8192];
501 struct pkg_array array;
502 const char *which;
503 struct varbuf vb = VARBUF_INIT;
504 int i;
506 which = (flags & wdb_dump_available) ? "available" : "status";
508 if (setvbuf(fp, writebuf, _IOFBF, sizeof(writebuf)))
509 ohshite(_("unable to set buffering on %s database file"), which);
511 pkg_array_init_from_hash(&array);
512 pkg_array_sort(&array, pkg_sorter_by_nonambig_name_arch);
514 for (i = 0; i < array.n_pkgs; i++) {
515 struct pkginfo *pkg;
516 struct pkgbin *pkgbin;
518 pkg = array.pkgs[i];
519 pkgbin = (flags & wdb_dump_available) ? &pkg->available : &pkg->installed;
521 /* Don't dump stanzas which have no useful content. */
522 if (!pkg_is_informative(pkg, pkgbin))
523 continue;
525 varbuf_stanza(&vb, pkg, pkgbin);
526 varbuf_add_char(&vb, '\n');
527 varbuf_end_str(&vb);
528 if (fputs(vb.buf, fp) < 0)
529 ohshite(_("failed to write %s database stanza about '%s' to '%s'"),
530 which, pkgbin_name(pkg, pkgbin, pnaw_nonambig), filename);
531 varbuf_reset(&vb);
534 pkg_array_destroy(&array);
535 varbuf_destroy(&vb);
538 void
539 writedb(const char *filename, enum writedb_flags flags)
541 struct atomic_file *file;
542 enum atomic_file_flags atomic_flags = ATOMIC_FILE_BACKUP;
544 if (flags & wdb_dump_available)
545 atomic_flags = 0;
547 file = atomic_file_new(filename, atomic_flags);
548 atomic_file_open(file);
550 writedb_stanzas(file->fp, filename, flags);
552 if (flags & wdb_must_sync)
553 atomic_file_sync(file);
555 atomic_file_close(file);
556 atomic_file_commit(file);
557 atomic_file_free(file);
559 if (flags & wdb_must_sync)
560 dir_sync_path_parent(filename);