2
* libdpkg - Debian packaging suite library routines
3
* fields.c - parsing of all the different fields, when reading in
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.
25
#include <dpkg-i18n.h>
33
#include <dpkg-priv.h>
34
#include "parsedump.h"
37
convert_string(const char *filename, int lno, const char *what, int otherwise,
38
const struct pkginfo *pigp,
39
const char *startp, const struct namevalue *ivip,
43
const struct namevalue *nvip = ivip;
46
parse_error(filename, lno, pigp, _("%s is missing"), what);
48
if (strncasecmp(nvip->name, startp, nvip->length))
54
if (otherwise != -1) return otherwise;
55
parse_error(filename, lno, pigp, _("`%.*s' is not allowed for %s"),
56
strnlen(startp, 50), startp, what);
59
ep = startp + nvip->length;
63
parse_error(filename, lno, pigp, _("junk after %s"), what);
64
if (endpp) *endpp= ep;
68
void f_name(struct pkginfo *pigp, struct pkginfoperfile *pifp, enum parsedbflags flags,
69
const char *filename, int lno, FILE *warnto, int *warncount,
70
const char *value, const struct fieldinfo *fip) {
72
if ((e= illegal_packagename(value,NULL)) != NULL)
73
parse_error(filename, lno, pigp, _("invalid package name (%.250s)"), e);
74
pigp->name= findpackage(value)->name;
75
/* We use the new name, as findpackage() may have
76
done a tolower for us.
80
void f_filecharf(struct pkginfo *pigp, struct pkginfoperfile *pifp,
81
enum parsedbflags flags,
82
const char *filename, int lno, FILE *warnto, int *warncount,
83
const char *value, const struct fieldinfo *fip) {
84
struct filedetails *fdp, **fdpp;
89
parse_error(filename, lno, pigp, _("empty file details field `%s'"), fip->name);
90
if (!(flags & pdb_recordavailable))
91
parse_error(filename, lno, pigp,
92
_("file details field `%s' not allowed in status file"),
94
allowextend= !pigp->files;
96
cpos= nfstrsave(value);
98
space= cpos; while (*space && !isspace(*space)) space++;
104
parse_error(filename, lno, pigp,
105
_("too many values in file details field `%s' "
106
"(compared to others)"), fip->name);
107
fdp= nfmalloc(sizeof(struct filedetails));
109
fdp->name= fdp->msdosname= fdp->size= fdp->md5sum= NULL;
112
FILEFFIELD(fdp,fip->integer,const char*)= cpos;
114
while (*space && isspace(*space)) space++;
118
parse_error(filename, lno, pigp,
119
_("too few values in file details field `%s' "
120
"(compared to others)"), fip->name);
123
void f_charfield(struct pkginfo *pigp, struct pkginfoperfile *pifp,
124
enum parsedbflags flags,
125
const char *filename, int lno, FILE *warnto, int *warncount,
126
const char *value, const struct fieldinfo *fip) {
127
if (*value) PKGPFIELD(pifp,fip->integer,char*)= nfstrsave(value);
130
void f_boolean(struct pkginfo *pigp, struct pkginfoperfile *pifp,
131
enum parsedbflags flags,
132
const char *filename, int lno, FILE *warnto, int *warncount,
133
const char *value, const struct fieldinfo *fip) {
139
boolean = convert_string(filename, lno, _("yes/no in boolean field"),
140
-1, pigp, value, booleaninfos, NULL);
141
PKGPFIELD(pifp, fip->integer, int) = boolean;
144
void f_section(struct pkginfo *pigp, struct pkginfoperfile *pifp,
145
enum parsedbflags flags,
146
const char *filename, int lno, FILE *warnto, int *warncount,
147
const char *value, const struct fieldinfo *fip) {
149
pigp->section= nfstrsave(value);
152
void f_priority(struct pkginfo *pigp, struct pkginfoperfile *pifp,
153
enum parsedbflags flags,
154
const char *filename, int lno, FILE *warnto, int *warncount,
155
const char *value, const struct fieldinfo *fip) {
157
pigp->priority = convert_string(filename, lno, _("word in `priority' field"),
158
pri_other, pigp, value, priorityinfos, NULL);
159
if (pigp->priority == pri_other) pigp->otherpriority= nfstrsave(value);
162
void f_status(struct pkginfo *pigp, struct pkginfoperfile *pifp,
163
enum parsedbflags flags,
164
const char *filename, int lno, FILE *warnto, int *warncount,
165
const char *value, const struct fieldinfo *fip) {
168
if (flags & pdb_rejectstatus)
169
parse_error(filename, lno, pigp,
170
_("value for `status' field not allowed in this context"));
171
if (flags & pdb_recordavailable) return;
173
pigp->want = convert_string(filename, lno,
174
_("first (want) word in `status' field"), -1,
175
pigp, value, wantinfos, &ep);
176
pigp->eflag = convert_string(filename, lno,
177
_("second (error) word in `status' field"), -1,
178
pigp, ep, eflaginfos, &ep);
179
if (pigp->eflag & eflagf_obsoletehold) {
180
pigp->want= want_hold;
181
pigp->eflag &= ~eflagf_obsoletehold;
183
pigp->status= convert_string(filename,lno,_("third (status) word in `status' field"), -1,
184
pigp, ep, statusinfos, NULL);
187
void f_version(struct pkginfo *pigp, struct pkginfoperfile *pifp,
188
enum parsedbflags flags,
189
const char *filename, int lno, FILE *warnto, int *warncount,
190
const char *value, const struct fieldinfo *fip) {
193
emsg= parseversion(&pifp->version,value);
195
parse_error(filename, lno, pigp,
196
_("error in Version string `%.250s': %.250s"), value, emsg);
199
void f_revision(struct pkginfo *pigp, struct pkginfoperfile *pifp,
200
enum parsedbflags flags,
201
const char *filename, int lno, FILE *warnto, int *warncount,
202
const char *value, const struct fieldinfo *fip) {
205
parse_warn(filename, lno, warnto, warncount, pigp,
206
_("obsolete `Revision' or `Package-Revision' field used"));
208
if (pifp->version.revision && *pifp->version.revision) {
209
newversion= nfmalloc(strlen(pifp->version.version)+strlen(pifp->version.revision)+2);
210
sprintf(newversion,"%s-%s",pifp->version.version,pifp->version.revision);
211
pifp->version.version= newversion;
213
pifp->version.revision= nfstrsave(value);
216
void f_configversion(struct pkginfo *pigp, struct pkginfoperfile *pifp,
217
enum parsedbflags flags,
218
const char *filename, int lno, FILE *warnto, int *warncount,
219
const char *value, const struct fieldinfo *fip) {
222
if (flags & pdb_rejectstatus)
223
parse_error(filename, lno, pigp,
224
_("value for `config-version' field not allowed in this context"));
225
if (flags & pdb_recordavailable) return;
227
emsg= parseversion(&pigp->configversion,value);
229
parse_error(filename, lno, pigp,
230
_("error in Config-Version string `%.250s': %.250s"),
234
static void conffvalue_lastword(const char *value, const char *from,
236
const char **word_start_r, int *word_len_r,
237
const char **new_from_r,
238
const char *filename, int lno,
239
struct pkginfo *pigp)
241
/* the code in f_conffiles ensures that value[-1]==' ', which is helpful */
244
if (from <= value+1) goto malformed;
245
for (lastspc= from-1; *lastspc != ' '; lastspc--);
246
if (lastspc <= value+1 || lastspc >= endent-1) goto malformed;
248
*new_from_r= lastspc;
249
*word_start_r= lastspc + 1;
250
*word_len_r= (int)(from - *word_start_r);
254
parse_error(filename, lno, pigp,
255
_("value for `conffiles' has malformatted line `%.*s'"),
256
(int)min(endent - value, 250), value);
259
void f_conffiles(struct pkginfo *pigp, struct pkginfoperfile *pifp,
260
enum parsedbflags flags,
261
const char *filename, int lno, FILE *warnto, int *warncount,
262
const char *value, const struct fieldinfo *fip) {
263
static const char obsolete_str[]= "obsolete";
264
struct conffile **lastp, *newlink;
265
const char *endent, *endfn, *hashstart;
266
int c, namelen, hashlen, obsolete;
269
lastp= &pifp->conffiles;
272
if (c == '\n') continue;
274
parse_error(filename, lno, pigp,
275
_("value for `conffiles' has line starting with non-space `%c'"),
277
for (endent = value; (c = *endent) != '\0' && c != '\n'; endent++) ;
278
conffvalue_lastword(value, endent, endent,
279
&hashstart, &hashlen, &endfn,
280
filename, lno, pigp);
281
obsolete= (hashlen == sizeof(obsolete_str)-1 &&
282
!memcmp(hashstart, obsolete_str, hashlen));
284
conffvalue_lastword(value, endfn, endent,
285
&hashstart, &hashlen, &endfn,
286
filename, lno, pigp);
287
newlink= nfmalloc(sizeof(struct conffile));
288
value = path_skip_slash_dotslash(value);
289
namelen= (int)(endfn-value);
291
parse_error(filename, lno, pigp,
292
_("root or null directory is listed as a conffile"));
293
newptr = nfmalloc(namelen+2);
295
memcpy(newptr+1,value,namelen);
296
newptr[namelen+1] = '\0';
297
newlink->name= newptr;
298
newptr= nfmalloc(hashlen+1);
299
memcpy(newptr, hashstart, hashlen);
300
newptr[hashlen] = '\0';
301
newlink->hash= newptr;
302
newlink->obsolete= obsolete;
305
lastp= &newlink->next;
310
void f_dependency(struct pkginfo *pigp, struct pkginfoperfile *pifp,
311
enum parsedbflags flags,
312
const char *filename, int lno, FILE *warnto, int *warncount,
313
const char *value, const struct fieldinfo *fip) {
315
const char *p, *emsg;
316
const char *depnamestart, *versionstart;
317
int depnamelength, versionlength;
318
static int depnameused= 0, versionused= 0;
319
static char *depname= NULL, *version= NULL;
321
struct dependency *dyp, **ldypp;
322
struct deppossi *dop, **ldopp;
324
if (!*value) return; /* empty fields are ignored */
326
ldypp= &pifp->depends; while (*ldypp) ldypp= &(*ldypp)->next;
327
for (;;) { /* loop creating new struct dependency's */
328
dyp= nfmalloc(sizeof(struct dependency));
329
dyp->up= NULL; /* Set this to zero for now, as we don't know what our real
330
* struct pkginfo address (in the database) is going to be yet.
332
dyp->next= NULL; *ldypp= dyp; ldypp= &dyp->next;
333
dyp->list= NULL; ldopp= &dyp->list;
334
dyp->type= fip->integer;
335
for (;;) { /* loop creating new struct deppossi's */
337
/* skip over package name characters */
338
while (*p && !isspace(*p) && *p != '(' && *p != ',' && *p != '|') {
341
depnamelength= p - depnamestart ;
342
if (depnamelength >= depnameused) {
343
depnameused= depnamelength;
344
depname = m_realloc(depname, depnamelength + 1);
346
strncpy(depname, depnamestart, depnamelength);
347
*(depname + depnamelength) = '\0';
349
parse_error(filename, lno, pigp,
350
_("`%s' field, missing package name, or garbage where "
351
"package name expected"), fip->name);
352
emsg= illegal_packagename(depname,NULL);
354
parse_error(filename, lno, pigp,
355
_("`%s' field, invalid package name `%.255s': %s"),
356
fip->name, depname, emsg);
357
dop= nfmalloc(sizeof(struct deppossi));
359
dop->ed= findpackage(depname);
360
dop->next= NULL; *ldopp= dop; ldopp= &dop->next;
361
dop->nextrev= NULL; /* Don't link this (which is after all only `newpig' from */
362
dop->backrev= NULL; /* the main parsing loop in parsedb) into the depended on
363
* packages' lists yet. This will be done later when we
364
* install this (in parse.c). For the moment we do the
365
* `forward' links in deppossi (`ed') only, and the backward
366
* links from the depended on packages to dop are left undone.
369
/* skip whitespace after packagename */
370
while (isspace(*p)) p++;
371
if (*p == '(') { /* if we have a versioned relation */
372
p++; while (isspace(*p)) p++;
374
if (c1 == '<' || c1 == '>') {
376
dop->verrel= (c1 == '<') ? dvrf_earlier : dvrf_later;
378
dop->verrel |= (dvrf_orequal | dvrf_builtup);
380
} else if (c2 == c1) {
381
dop->verrel |= (dvrf_strict | dvrf_builtup);
383
} else if (c2 == '<' || c2 == '>') {
384
parse_error(filename, lno, pigp,
385
_("`%s' field, reference to `%.255s':\n"
386
" bad version relationship %c%c"),
387
fip->name, depname, c1, c2);
388
dop->verrel= dvr_none;
390
parse_warn(filename, lno, warnto, warncount, pigp,
391
_("`%s' field, reference to `%.255s':\n"
392
" `%c' is obsolete, use `%c=' or `%c%c' instead"),
393
fip->name, depname, c1, c1, c1, c1);
394
dop->verrel |= (dvrf_orequal | dvrf_builtup);
396
} else if (c1 == '=') {
397
dop->verrel= dvr_exact;
400
parse_warn(filename, lno, warnto, warncount, pigp,
401
_("`%s' field, reference to `%.255s':\n"
402
" implicit exact match on version number, "
403
"suggest using `=' instead"),
405
dop->verrel= dvr_exact;
407
if ((dop->verrel!=dvr_exact) && (fip->integer==dep_provides))
408
parse_warn(filename, lno, warnto, warncount, pigp,
409
_("Only exact versions may be used for Provides"));
411
if (!isspace(*p) && !isalnum(*p)) {
412
parse_warn(filename, lno, warnto, warncount, pigp,
413
_("`%s' field, reference to `%.255s':\n"
414
" version value starts with non-alphanumeric, "
415
"suggest adding a space"),
418
/* skip spaces between the relation and the version */
419
while (isspace(*p)) p++;
422
while (*p && *p != ')' && *p != '(') {
423
if (isspace(*p)) break;
426
versionlength= p - versionstart;
427
while (isspace(*p)) p++;
429
parse_error(filename, lno, pigp,
430
_("`%s' field, reference to `%.255s': "
431
"version contains `%c'"), fip->name,depname, ')');
433
parse_error(filename, lno, pigp,
434
_("`%s' field, reference to `%.255s': "
435
"version contains `%c'"), fip->name,depname, ' ');
437
parse_error(filename, lno, pigp,
438
_("`%s' field, reference to `%.255s': "
439
"version unterminated"), fip->name, depname);
440
if (versionlength >= versionused) {
441
versionused= versionlength;
442
version = m_realloc(version, versionlength + 1);
444
strncpy(version, versionstart, versionlength);
445
*(version + versionlength) = '\0';
446
emsg= parseversion(&dop->version,version);
448
parse_error(filename, lno, pigp,
449
_("`%s' field, reference to `%.255s': "
450
"error in version: %.255s"), fip->name, depname, emsg);
451
p++; while (isspace(*p)) p++;
453
dop->verrel= dvr_none;
454
blankversion(&dop->version);
456
if (!*p || *p == ',') break;
458
parse_error(filename, lno, pigp,
459
_("`%s' field, syntax error after reference to package `%.255s'"),
460
fip->name, dop->ed->name);
461
if (fip->integer == dep_conflicts ||
462
fip->integer == dep_breaks ||
463
fip->integer == dep_provides ||
464
fip->integer == dep_replaces)
465
parse_error(filename, lno, pigp,
466
_("alternatives (`|') not allowed in %s field"), fip->name);
467
p++; while (isspace(*p)) p++;
470
p++; while (isspace(*p)) p++;
475
scan_word(const char **valp)
481
const char *p, *start, *end;
497
if (*p && !cisspace(*p)) {
507
buf = m_realloc(buf, avail);
509
memcpy(buf, start, l);
517
f_trigpend(struct pkginfo *pend, struct pkginfoperfile *pifp,
518
enum parsedbflags flags,
519
const char *filename, int lno, FILE *warnto, int *warncount,
520
const char *value, const struct fieldinfo *fip)
522
const char *word, *emsg;
524
if (flags & pdb_rejectstatus)
525
parse_error(filename, lno, pend,
526
_("value for `triggers-pending' field not allowed in "
529
while ((word = scan_word(&value))) {
530
emsg = illegal_triggername(word);
532
parse_error(filename, lno, pend,
533
_("illegal pending trigger name `%.255s': %s"), word, emsg);
535
if (!trig_note_pend_core(pend, nfstrsave(word)))
536
parse_error(filename, lno, pend,
537
_("duplicate pending trigger `%.255s'"), word);
542
f_trigaw(struct pkginfo *aw, struct pkginfoperfile *pifp,
543
enum parsedbflags flags,
544
const char *filename, int lno, FILE *warnto, int *warncount,
545
const char *value, const struct fieldinfo *fip)
547
const char *word, *emsg;
548
struct pkginfo *pend;
550
if (flags & pdb_rejectstatus)
551
parse_error(filename, lno, aw,
552
_("value for `triggers-awaited' field not allowed in "
555
while ((word = scan_word(&value))) {
556
emsg = illegal_packagename(word, NULL);
558
parse_error(filename, lno, aw,
559
_("illegal package name in awaited trigger `%.255s': %s"),
561
pend = findpackage(word);
563
if (!trig_note_aw(pend, aw))
564
parse_error(filename, lno, aw,
565
_("duplicate awaited trigger package `%.255s'"), word);
567
trig_enqueue_awaited_pend(pend);