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
8
* This is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as
10
* published by the Free Software Foundation; either version 2,
11
* or (at your option) any later version.
13
* This is distributed in the hope that it will be useful, but
14
* 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
19
* License along with dpkg; if not, write to the Free Software
20
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
/* FIXME: don't write uninteresting packages */
27
#include <dpkg-i18n.h>
36
#include <sys/types.h>
41
#include "parsedump.h"
43
void w_name(struct varbuf *vb,
44
const struct pkginfo *pigp, const struct pkginfoperfile *pifp,
45
enum fwriteflags flags, const struct fieldinfo *fip) {
47
if (flags&fw_printheader)
48
varbufaddstr(vb,"Package: ");
49
varbufaddstr(vb, pigp->name);
50
if (flags&fw_printheader)
54
void w_version(struct varbuf *vb,
55
const struct pkginfo *pigp, const struct pkginfoperfile *pifp,
56
enum fwriteflags flags, const struct fieldinfo *fip) {
57
/* Epoch and revision information is printed in version field too. */
58
if (!informativeversion(&pifp->version)) return;
59
if (flags&fw_printheader)
60
varbufaddstr(vb,"Version: ");
61
varbufversion(vb,&pifp->version,vdew_nonambig);
62
if (flags&fw_printheader)
66
void w_configversion(struct varbuf *vb,
67
const struct pkginfo *pigp, const struct pkginfoperfile *pifp,
68
enum fwriteflags flags, const struct fieldinfo *fip) {
69
if (pifp != &pigp->installed) return;
70
if (!informativeversion(&pigp->configversion)) return;
71
if (pigp->status == stat_installed ||
72
pigp->status == stat_notinstalled ||
73
pigp->status == stat_triggerspending ||
74
pigp->status == stat_triggersawaited)
76
if (flags&fw_printheader)
77
varbufaddstr(vb,"Config-Version: ");
78
varbufversion(vb,&pigp->configversion,vdew_nonambig);
79
if (flags&fw_printheader)
83
void w_null(struct varbuf *vb,
84
const struct pkginfo *pigp, const struct pkginfoperfile *pifp,
85
enum fwriteflags flags, const struct fieldinfo *fip) {
88
void w_section(struct varbuf *vb,
89
const struct pkginfo *pigp, const struct pkginfoperfile *pifp,
90
enum fwriteflags flags, const struct fieldinfo *fip) {
91
const char *value= pigp->section;
92
if (!value || !*value) return;
93
if (flags&fw_printheader)
94
varbufaddstr(vb,"Section: ");
95
varbufaddstr(vb,value);
96
if (flags&fw_printheader)
100
void w_charfield(struct varbuf *vb,
101
const struct pkginfo *pigp, const struct pkginfoperfile *pifp,
102
enum fwriteflags flags, const struct fieldinfo *fip) {
103
const char *value= pifp->valid ? PKGPFIELD(pifp,fip->integer,const char*) : NULL;
104
if (!value || !*value) return;
105
if (flags&fw_printheader) {
106
varbufaddstr(vb,fip->name);
107
varbufaddstr(vb, ": ");
109
varbufaddstr(vb,value);
110
if (flags&fw_printheader)
114
void w_filecharf(struct varbuf *vb,
115
const struct pkginfo *pigp, const struct pkginfoperfile *pifp,
116
enum fwriteflags flags, const struct fieldinfo *fip) {
117
struct filedetails *fdp;
119
if (pifp != &pigp->available) return;
121
if (!fdp || !FILEFFIELD(fdp,fip->integer,const char*)) return;
123
if (flags&fw_printheader) {
124
varbufaddstr(vb,fip->name);
130
varbufaddstr(vb,FILEFFIELD(fdp,fip->integer,const char*));
134
if (flags&fw_printheader)
138
void w_booleandefno(struct varbuf *vb,
139
const struct pkginfo *pigp, const struct pkginfoperfile *pifp,
140
enum fwriteflags flags, const struct fieldinfo *fip) {
141
int value= pifp->valid ? PKGPFIELD(pifp,fip->integer,int) : -1;
142
if (!(flags&fw_printheader)) {
143
varbufaddstr(vb, (value==1) ? "yes" : "no");
148
varbufaddstr(vb,fip->name); varbufaddstr(vb, ": yes\n");
151
void w_priority(struct varbuf *vb,
152
const struct pkginfo *pigp, const struct pkginfoperfile *pifp,
153
enum fwriteflags flags, const struct fieldinfo *fip) {
154
if (pigp->priority == pri_unknown) return;
155
assert(pigp->priority <= pri_unknown);
156
if (flags&fw_printheader)
157
varbufaddstr(vb,"Priority: ");
159
pigp->priority == pri_other
160
? pigp->otherpriority
161
: priorityinfos[pigp->priority].name);
162
if (flags&fw_printheader)
166
void w_status(struct varbuf *vb,
167
const struct pkginfo *pigp, const struct pkginfoperfile *pifp,
168
enum fwriteflags flags, const struct fieldinfo *fip) {
169
if (pifp != &pigp->installed) return;
170
assert(pigp->want <= want_purge);
171
assert(pigp->eflag <= eflagv_reinstreq); /* hold and hold-reinstreq NOT allowed */
173
#define PEND pigp->trigpend_head
174
#define AW pigp->trigaw.head
175
switch (pigp->status) {
176
case stat_notinstalled:
177
case stat_configfiles:
181
case stat_halfinstalled:
183
case stat_halfconfigured:
186
case stat_triggersawaited:
189
case stat_triggerspending:
198
internerr("unknown package status '%d'", pigp->status);
203
if (flags&fw_printheader)
204
varbufaddstr(vb,"Status: ");
205
varbufaddstr(vb,wantinfos[pigp->want].name); varbufaddc(vb,' ');
206
varbufaddstr(vb,eflaginfos[pigp->eflag].name); varbufaddc(vb,' ');
207
varbufaddstr(vb,statusinfos[pigp->status].name);
208
if (flags&fw_printheader)
212
void varbufdependency(struct varbuf *vb, struct dependency *dep) {
213
struct deppossi *dop;
217
for (dop= dep->list; dop; dop= dop->next) {
218
assert(dop->up == dep);
219
varbufaddstr(vb,possdel); possdel= " | ";
220
varbufaddstr(vb,dop->ed->name);
221
if (dop->verrel != dvr_none) {
222
varbufaddstr(vb," (");
223
switch (dop->verrel) {
224
case dvr_exact: varbufaddc(vb,'='); break;
225
case dvr_laterequal: varbufaddstr(vb,">="); break;
226
case dvr_earlierequal: varbufaddstr(vb,"<="); break;
227
case dvr_laterstrict: varbufaddstr(vb,">>"); break;
228
case dvr_earlierstrict: varbufaddstr(vb,"<<"); break;
230
internerr("unknown verrel '%d'", dop->verrel);
233
varbufversion(vb,&dop->version,vdew_nonambig);
239
void w_dependency(struct varbuf *vb,
240
const struct pkginfo *pigp, const struct pkginfoperfile *pifp,
241
enum fwriteflags flags, const struct fieldinfo *fip) {
244
struct dependency *dyp;
246
if (!pifp->valid) return;
247
if (flags&fw_printheader)
248
sprintf(fnbuf,"%s: ",fip->name);
253
for (dyp= pifp->depends; dyp; dyp= dyp->next) {
254
if (dyp->type != fip->integer) continue;
255
assert(dyp->up == pigp);
256
varbufaddstr(vb,depdel); depdel= ", ";
257
varbufdependency(vb,dyp);
259
if ((flags&fw_printheader) && (depdel!=fnbuf))
263
void w_conffiles(struct varbuf *vb,
264
const struct pkginfo *pigp, const struct pkginfoperfile *pifp,
265
enum fwriteflags flags, const struct fieldinfo *fip) {
268
if (!pifp->valid || !pifp->conffiles || pifp == &pigp->available) return;
269
if (flags&fw_printheader)
270
varbufaddstr(vb,"Conffiles:\n");
271
for (i=pifp->conffiles; i; i= i->next) {
272
if (i!=pifp->conffiles) varbufaddc(vb,'\n');
273
varbufaddc(vb,' '); varbufaddstr(vb,i->name); varbufaddc(vb,' ');
274
varbufaddstr(vb,i->hash);
275
if (i->obsolete) varbufaddstr(vb," obsolete");
277
if (flags&fw_printheader)
282
w_trigpend(struct varbuf *vb,
283
const struct pkginfo *pigp, const struct pkginfoperfile *pifp,
284
enum fwriteflags flags, const struct fieldinfo *fip)
288
if (!pifp->valid || pifp == &pigp->available || !pigp->trigpend_head)
291
assert(pigp->status >= stat_triggersawaited &&
292
pigp->status <= stat_triggerspending);
294
if (flags & fw_printheader)
295
varbufaddstr(vb, "Triggers-Pending:");
296
for (tp = pigp->trigpend_head; tp; tp = tp->next) {
298
varbufaddstr(vb, tp->name);
300
if (flags & fw_printheader)
301
varbufaddc(vb, '\n');
305
w_trigaw(struct varbuf *vb,
306
const struct pkginfo *pigp, const struct pkginfoperfile *pifp,
307
enum fwriteflags flags, const struct fieldinfo *fip)
311
if (!pifp->valid || pifp == &pigp->available || !pigp->trigaw.head)
314
assert(pigp->status > stat_configfiles &&
315
pigp->status <= stat_triggersawaited);
317
if (flags & fw_printheader)
318
varbufaddstr(vb, "Triggers-Awaited:");
319
for (ta = pigp->trigaw.head; ta; ta = ta->sameaw.next) {
321
varbufaddstr(vb, ta->pend->name);
323
if (flags & fw_printheader)
324
varbufaddc(vb, '\n');
327
void varbufrecord(struct varbuf *vb,
328
const struct pkginfo *pigp, const struct pkginfoperfile *pifp) {
329
const struct fieldinfo *fip;
330
const struct arbitraryfield *afp;
332
for (fip= fieldinfos; fip->name; fip++) {
333
fip->wcall(vb,pigp,pifp,fw_printheader,fip);
336
for (afp= pifp->arbs; afp; afp= afp->next) {
337
varbufaddstr(vb,afp->name); varbufaddstr(vb,": ");
338
varbufaddstr(vb,afp->value); varbufaddc(vb,'\n');
343
void writerecord(FILE *file, const char *filename,
344
const struct pkginfo *pigp, const struct pkginfoperfile *pifp) {
345
struct varbuf vb = VARBUF_INIT;
347
varbufrecord(&vb,pigp,pifp);
348
varbufaddc(&vb,'\0');
349
if (fputs(vb.buf,file) < 0)
350
ohshite(_("failed to write details of `%.50s' to `%.250s'"), pigp->name,
355
void writedb(const char *filename, int available, int mustsync) {
356
static char writebuf[8192];
358
struct pkgiterator *it;
359
struct pkginfo *pigp;
360
struct pkginfoperfile *pifp;
364
struct varbuf vb = VARBUF_INIT;
367
which= available ? "available" : "status";
368
oldfn= m_malloc(strlen(filename)+sizeof(OLDDBEXT));
369
strcpy(oldfn,filename); strcat(oldfn,OLDDBEXT);
370
newfn= m_malloc(strlen(filename)+sizeof(NEWDBEXT));
371
strcpy(newfn,filename); strcat(newfn,NEWDBEXT);
373
old_umask = umask(022);
374
file= fopen(newfn,"w");
376
if (!file) ohshite(_("failed to open `%s' for writing %s information"),filename,which);
378
if (setvbuf(file,writebuf,_IOFBF,sizeof(writebuf)))
379
ohshite(_("unable to set buffering on status file"));
382
while ((pigp= iterpkgnext(it)) != NULL) {
383
pifp= available ? &pigp->available : &pigp->installed;
384
/* Don't dump records which have no useful content. */
385
if (!informative(pigp,pifp)) continue;
386
if (!pifp->valid) blankpackageperfile(pifp);
387
varbufrecord(&vb,pigp,pifp);
388
varbufaddc(&vb,'\n'); varbufaddc(&vb,0);
389
if (fputs(vb.buf,file) < 0)
390
ohshite(_("failed to write %s record about `%.50s' to `%.250s'"),
391
which, pigp->name, filename);
398
ohshite(_("failed to flush %s information to `%.250s'"), which, filename);
399
if (fsync(fileno(file)))
400
ohshite(_("failed to fsync %s information to `%.250s'"), which, filename);
402
if (fclose(file)) ohshite(_("failed to close `%.250s' after writing %s information"),
405
if (link(filename,oldfn) && errno != ENOENT)
406
ohshite(_("failed to link `%.250s' to `%.250s' for backup of %s info"),
407
filename, oldfn, which);
408
if (rename(newfn,filename))
409
ohshite(_("failed to install `%.250s' as `%.250s' containing %s info"),
410
newfn, filename, which);