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/>.
28 #include <sys/types.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>
45 #include <dpkg/parsedump.h>
48 varbuf_add_fieldname(struct varbuf
*vb
, const struct fieldinfo
*fip
)
50 varbuf_add_str(vb
, fip
->name
);
51 varbuf_add_str(vb
, ": ");
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');
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
))
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');
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
)
90 if (!dpkg_version_is_informative(&pkg
->configversion
))
92 if (pkg
->status
== PKG_STAT_INSTALLED
||
93 pkg
->status
== PKG_STAT_NOTINSTALLED
||
94 pkg
->status
== PKG_STAT_TRIGGERSPENDING
)
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');
104 w_null(struct varbuf
*vb
,
105 const struct pkginfo
*pkg
, const struct pkgbin
*pkgbin
,
106 enum fwriteflags flags
, const struct fieldinfo
*fip
)
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
))
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');
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
))
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');
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
)
151 archive
= pkg
->archives
;
152 if (!archive
|| !STRUCTFIELD(archive
, fip
->integer
, const char *))
155 if (flags
&fw_printheader
) {
156 varbuf_add_str(vb
, fip
->name
);
157 varbuf_add_char(vb
, ':');
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');
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
)
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');
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
)
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');
209 w_architecture(struct varbuf
*vb
,
210 const struct pkginfo
*pkg
, const struct pkgbin
*pkgbin
,
211 enum fwriteflags flags
, const struct fieldinfo
*fip
)
215 if (pkgbin
->arch
->type
== DPKG_ARCH_NONE
)
217 if (pkgbin
->arch
->type
== DPKG_ARCH_EMPTY
)
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');
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
)
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');
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
)
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
));
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
));
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
));
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
));
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
));
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
;
310 for (dop
= dep
->list
; dop
; dop
= dop
->next
) {
312 internerr("dependency and deppossi not linked properly");
314 varbuf_add_str(vb
, 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
, '=');
325 case DPKG_RELATION_GE
:
326 varbuf_add_str(vb
, ">=");
328 case DPKG_RELATION_LE
:
329 varbuf_add_str(vb
, "<=");
331 case DPKG_RELATION_GT
:
332 varbuf_add_str(vb
, ">>");
334 case DPKG_RELATION_LT
:
335 varbuf_add_str(vb
, "<<");
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
, ')');
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;
359 internerr("dependency and package %s not linked properly",
360 pkgbin_name_const(pkg
, pkgbin
, pnaw_always
));
363 varbuf_add_str(vb
, ", ");
365 if (flags
& fw_printheader
)
366 varbuf_add_fieldname(vb
, fip
);
369 varbufdependency(vb
,dyp
);
371 if ((flags
& fw_printheader
) && dep_found
)
372 varbuf_add_char(vb
, '\n');
376 w_conffiles(struct varbuf
*vb
,
377 const struct pkginfo
*pkg
, const struct pkgbin
*pkgbin
,
378 enum fwriteflags flags
, const struct fieldinfo
*fip
)
382 if (!pkgbin
->conffiles
|| pkgbin
== &pkg
->available
)
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
->flags
& CONFFILE_OBSOLETE
)
394 varbuf_add_str(vb
, " obsolete");
395 if (i
->flags
& CONFFILE_REMOVE_ON_UPGRADE
)
396 varbuf_add_str(vb
, " remove-on-upgrade");
398 if (flags
&fw_printheader
)
399 varbuf_add_char(vb
, '\n');
403 w_trigpend(struct varbuf
*vb
,
404 const struct pkginfo
*pkg
, const struct pkgbin
*pkgbin
,
405 enum fwriteflags flags
, const struct fieldinfo
*fip
)
409 if (pkgbin
== &pkg
->available
|| !pkg
->trigpend_head
)
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');
428 w_trigaw(struct varbuf
*vb
,
429 const struct pkginfo
*pkg
, const struct pkgbin
*pkgbin
,
430 enum fwriteflags flags
, const struct fieldinfo
*fip
)
434 if (pkgbin
== &pkg
->available
|| !pkg
->trigaw
.head
)
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');
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');
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
);
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
);
488 if (fputs(varbuf_str(&vb
), file
) < 0)
489 ohshite(_("failed to write details of '%.50s' to '%.250s'"),
490 pkgbin_name_const(pkg
, pkgbin
, pnaw_nonambig
), filename
);
496 writedb_stanzas(FILE *fp
, const char *filename
, enum writedb_flags flags
)
498 static char writebuf
[8192];
500 struct pkg_array array
;
502 struct varbuf vb
= VARBUF_INIT
;
505 which
= (flags
& wdb_dump_available
) ? "available" : "status";
507 if (setvbuf(fp
, writebuf
, _IOFBF
, sizeof(writebuf
)))
508 ohshite(_("unable to set buffering on %s database file"), which
);
510 pkg_array_init_from_hash(&array
);
511 pkg_array_sort(&array
, pkg_sorter_by_nonambig_name_arch
);
513 for (i
= 0; i
< array
.n_pkgs
; i
++) {
515 struct pkgbin
*pkgbin
;
518 pkgbin
= (flags
& wdb_dump_available
) ? &pkg
->available
: &pkg
->installed
;
520 /* Don't dump stanzas which have no useful content. */
521 if (!pkg_is_informative(pkg
, pkgbin
))
524 varbuf_stanza(&vb
, pkg
, pkgbin
);
525 varbuf_add_char(&vb
, '\n');
526 if (fputs(varbuf_str(&vb
), fp
) < 0)
527 ohshite(_("failed to write %s database stanza about '%s' to '%s'"),
528 which
, pkgbin_name(pkg
, pkgbin
, pnaw_nonambig
), filename
);
532 pkg_array_destroy(&array
);
537 writedb(const char *filename
, enum writedb_flags flags
)
539 struct atomic_file
*file
;
540 enum atomic_file_flags atomic_flags
= ATOMIC_FILE_BACKUP
;
542 if (flags
& wdb_dump_available
)
545 file
= atomic_file_new(filename
, atomic_flags
);
546 atomic_file_open(file
);
548 writedb_stanzas(file
->fp
, filename
, flags
);
550 if (flags
& wdb_must_sync
)
551 atomic_file_sync(file
);
553 atomic_file_close(file
);
554 atomic_file_commit(file
);
555 atomic_file_free(file
);
557 if (flags
& wdb_must_sync
)
558 dir_sync_path_parent(filename
);