fields.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. /*
  2. * libdpkg - Debian packaging suite library routines
  3. * fields.c - parsing of all the different fields, when reading in
  4. *
  5. * Copyright © 1995 Ian Jackson <ian@chiark.greenend.org.uk>
  6. * Copyright © 2001 Wichert Akkerman
  7. *
  8. * This is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This is distributed in the hope that it will be useful,
  14. * but 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.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. #include <config.h>
  22. #include <compat.h>
  23. #include <ctype.h>
  24. #include <string.h>
  25. #include <stdio.h>
  26. #include <dpkg/i18n.h>
  27. #include <dpkg/dpkg.h>
  28. #include <dpkg/dpkg-db.h>
  29. #include <dpkg/path.h>
  30. #include <dpkg/parsedump.h>
  31. #include <dpkg/triglib.h>
  32. static int
  33. parse_nv_next(struct parsedb_state *ps,
  34. const char *what, const struct namevalue *nv_head,
  35. const char **strp)
  36. {
  37. const char *str_start = *strp, *str_end;
  38. const struct namevalue *nv;
  39. if (str_start[0] == '\0')
  40. parse_error(ps, _("%s is missing"), what);
  41. nv = namevalue_find_by_name(nv_head, str_start);
  42. if (nv == NULL)
  43. parse_error(ps, _("'%.50s' is not allowed for %s"), str_start, what);
  44. /* We got the fallback value, skip further string validation. */
  45. if (nv->length == 0) {
  46. str_end = NULL;
  47. } else {
  48. str_end = str_start + nv->length;
  49. while (isspace(str_end[0]))
  50. str_end++;
  51. }
  52. *strp = str_end;
  53. return nv->value;
  54. }
  55. static int
  56. parse_nv_last(struct parsedb_state *ps,
  57. const char *what, const struct namevalue *nv_head,
  58. const char *str)
  59. {
  60. int value;
  61. value = parse_nv_next(ps, what, nv_head, &str);
  62. if (str != NULL && str[0] != '\0')
  63. parse_error(ps, _("junk after %s"), what);
  64. return value;
  65. }
  66. void
  67. f_name(struct pkginfo *pigp, struct pkgbin *pifp,
  68. struct parsedb_state *ps,
  69. const char *value, const struct fieldinfo *fip)
  70. {
  71. const char *e;
  72. e = pkg_name_is_illegal(value, NULL);
  73. if (e != NULL)
  74. parse_error(ps, _("invalid package name (%.250s)"), e);
  75. /* We use the new name, as pkg_db_find() may have done a tolower for us. */
  76. pigp->name = pkg_db_find(value)->name;
  77. }
  78. void
  79. f_filecharf(struct pkginfo *pigp, struct pkgbin *pifp,
  80. struct parsedb_state *ps,
  81. const char *value, const struct fieldinfo *fip)
  82. {
  83. struct filedetails *fdp, **fdpp;
  84. char *cpos, *space;
  85. int allowextend;
  86. if (!*value)
  87. parse_error(ps, _("empty file details field `%s'"), fip->name);
  88. if (!(ps->flags & pdb_recordavailable))
  89. parse_error(ps,
  90. _("file details field `%s' not allowed in status file"),
  91. fip->name);
  92. allowextend= !pigp->files;
  93. fdpp= &pigp->files;
  94. cpos= nfstrsave(value);
  95. while (*cpos) {
  96. space= cpos; while (*space && !isspace(*space)) space++;
  97. if (*space)
  98. *space++ = '\0';
  99. fdp= *fdpp;
  100. if (!fdp) {
  101. if (!allowextend)
  102. parse_error(ps,
  103. _("too many values in file details field `%s' "
  104. "(compared to others)"), fip->name);
  105. fdp= nfmalloc(sizeof(struct filedetails));
  106. fdp->next= NULL;
  107. fdp->name= fdp->msdosname= fdp->size= fdp->md5sum= NULL;
  108. *fdpp= fdp;
  109. }
  110. FILEFFIELD(fdp,fip->integer,const char*)= cpos;
  111. fdpp= &fdp->next;
  112. while (*space && isspace(*space)) space++;
  113. cpos= space;
  114. }
  115. if (*fdpp)
  116. parse_error(ps,
  117. _("too few values in file details field `%s' "
  118. "(compared to others)"), fip->name);
  119. }
  120. void
  121. f_charfield(struct pkginfo *pigp, struct pkgbin *pifp,
  122. struct parsedb_state *ps,
  123. const char *value, const struct fieldinfo *fip)
  124. {
  125. if (*value) PKGPFIELD(pifp,fip->integer,char*)= nfstrsave(value);
  126. }
  127. void
  128. f_boolean(struct pkginfo *pigp, struct pkgbin *pifp,
  129. struct parsedb_state *ps,
  130. const char *value, const struct fieldinfo *fip)
  131. {
  132. bool boolean;
  133. if (!*value)
  134. return;
  135. boolean = parse_nv_last(ps, _("yes/no in boolean field"),
  136. booleaninfos, value);
  137. PKGPFIELD(pifp, fip->integer, bool) = boolean;
  138. }
  139. void
  140. f_section(struct pkginfo *pigp, struct pkgbin *pifp,
  141. struct parsedb_state *ps,
  142. const char *value, const struct fieldinfo *fip)
  143. {
  144. if (!*value) return;
  145. pigp->section= nfstrsave(value);
  146. }
  147. void
  148. f_priority(struct pkginfo *pigp, struct pkgbin *pifp,
  149. struct parsedb_state *ps,
  150. const char *value, const struct fieldinfo *fip)
  151. {
  152. if (!*value) return;
  153. pigp->priority = parse_nv_last(ps, _("word in `priority' field"),
  154. priorityinfos, value);
  155. if (pigp->priority == pri_other) pigp->otherpriority= nfstrsave(value);
  156. }
  157. void
  158. f_status(struct pkginfo *pigp, struct pkgbin *pifp,
  159. struct parsedb_state *ps,
  160. const char *value, const struct fieldinfo *fip)
  161. {
  162. if (ps->flags & pdb_rejectstatus)
  163. parse_error(ps,
  164. _("value for `status' field not allowed in this context"));
  165. if (ps->flags & pdb_recordavailable)
  166. return;
  167. pigp->want = parse_nv_next(ps,
  168. _("first (want) word in `status' field"),
  169. wantinfos, &value);
  170. pigp->eflag = parse_nv_next(ps,
  171. _("second (error) word in `status' field"),
  172. eflaginfos, &value);
  173. pigp->status = parse_nv_last(ps,
  174. _("third (status) word in `status' field"),
  175. statusinfos, value);
  176. }
  177. void
  178. f_version(struct pkginfo *pigp, struct pkgbin *pifp,
  179. struct parsedb_state *ps,
  180. const char *value, const struct fieldinfo *fip)
  181. {
  182. parse_db_version(ps, &pifp->version, value,
  183. _("error in Version string '%.250s'"), value);
  184. }
  185. void
  186. f_revision(struct pkginfo *pigp, struct pkgbin *pifp,
  187. struct parsedb_state *ps,
  188. const char *value, const struct fieldinfo *fip)
  189. {
  190. char *newversion;
  191. parse_warn(ps,
  192. _("obsolete `Revision' or `Package-Revision' field used"));
  193. if (!*value) return;
  194. if (pifp->version.revision && *pifp->version.revision) {
  195. newversion= nfmalloc(strlen(pifp->version.version)+strlen(pifp->version.revision)+2);
  196. sprintf(newversion,"%s-%s",pifp->version.version,pifp->version.revision);
  197. pifp->version.version= newversion;
  198. }
  199. pifp->version.revision= nfstrsave(value);
  200. }
  201. void
  202. f_configversion(struct pkginfo *pigp, struct pkgbin *pifp,
  203. struct parsedb_state *ps,
  204. const char *value, const struct fieldinfo *fip)
  205. {
  206. if (ps->flags & pdb_rejectstatus)
  207. parse_error(ps,
  208. _("value for `config-version' field not allowed in this context"));
  209. if (ps->flags & pdb_recordavailable)
  210. return;
  211. parse_db_version(ps, &pigp->configversion, value,
  212. _("error in Config-Version string '%.250s'"), value);
  213. }
  214. /*
  215. * The code in f_conffiles ensures that value[-1] == ' ', which is helpful.
  216. */
  217. static void conffvalue_lastword(const char *value, const char *from,
  218. const char *endent,
  219. const char **word_start_r, int *word_len_r,
  220. const char **new_from_r,
  221. struct parsedb_state *ps)
  222. {
  223. const char *lastspc;
  224. if (from <= value+1) goto malformed;
  225. for (lastspc= from-1; *lastspc != ' '; lastspc--);
  226. if (lastspc <= value+1 || lastspc >= endent-1) goto malformed;
  227. *new_from_r= lastspc;
  228. *word_start_r= lastspc + 1;
  229. *word_len_r= (int)(from - *word_start_r);
  230. return;
  231. malformed:
  232. parse_error(ps,
  233. _("value for `conffiles' has malformatted line `%.*s'"),
  234. (int)min(endent - value, 250), value);
  235. }
  236. void
  237. f_conffiles(struct pkginfo *pigp, struct pkgbin *pifp,
  238. struct parsedb_state *ps,
  239. const char *value, const struct fieldinfo *fip)
  240. {
  241. static const char obsolete_str[]= "obsolete";
  242. struct conffile **lastp, *newlink;
  243. const char *endent, *endfn, *hashstart;
  244. int c, namelen, hashlen, obsolete;
  245. char *newptr;
  246. lastp= &pifp->conffiles;
  247. while (*value) {
  248. c= *value++;
  249. if (c == '\n') continue;
  250. if (c != ' ')
  251. parse_error(ps,
  252. _("value for `conffiles' has line starting with non-space `%c'"),
  253. c);
  254. for (endent = value; (c = *endent) != '\0' && c != '\n'; endent++) ;
  255. conffvalue_lastword(value, endent, endent,
  256. &hashstart, &hashlen, &endfn,
  257. ps);
  258. obsolete= (hashlen == sizeof(obsolete_str)-1 &&
  259. !memcmp(hashstart, obsolete_str, hashlen));
  260. if (obsolete)
  261. conffvalue_lastword(value, endfn, endent,
  262. &hashstart, &hashlen, &endfn,
  263. ps);
  264. newlink= nfmalloc(sizeof(struct conffile));
  265. value = path_skip_slash_dotslash(value);
  266. namelen= (int)(endfn-value);
  267. if (namelen <= 0)
  268. parse_error(ps,
  269. _("root or null directory is listed as a conffile"));
  270. newptr = nfmalloc(namelen+2);
  271. newptr[0]= '/';
  272. memcpy(newptr+1,value,namelen);
  273. newptr[namelen+1] = '\0';
  274. newlink->name= newptr;
  275. newptr= nfmalloc(hashlen+1);
  276. memcpy(newptr, hashstart, hashlen);
  277. newptr[hashlen] = '\0';
  278. newlink->hash= newptr;
  279. newlink->obsolete= obsolete;
  280. newlink->next =NULL;
  281. *lastp= newlink;
  282. lastp= &newlink->next;
  283. value= endent;
  284. }
  285. }
  286. void
  287. f_dependency(struct pkginfo *pigp, struct pkgbin *pifp,
  288. struct parsedb_state *ps,
  289. const char *value, const struct fieldinfo *fip)
  290. {
  291. char c1, c2;
  292. const char *p, *emsg;
  293. const char *depnamestart, *versionstart;
  294. int depnamelength, versionlength;
  295. static struct varbuf depname, version;
  296. struct dependency *dyp, **ldypp;
  297. struct deppossi *dop, **ldopp;
  298. /* Empty fields are ignored. */
  299. if (!*value)
  300. return;
  301. p= value;
  302. ldypp= &pifp->depends; while (*ldypp) ldypp= &(*ldypp)->next;
  303. /* Loop creating new struct dependency's. */
  304. for (;;) {
  305. dyp= nfmalloc(sizeof(struct dependency));
  306. /* Set this to NULL for now, as we don't know what our real
  307. * struct pkginfo address (in the database) is going to be yet. */
  308. dyp->up = NULL;
  309. dyp->next= NULL; *ldypp= dyp; ldypp= &dyp->next;
  310. dyp->list= NULL; ldopp= &dyp->list;
  311. dyp->type= fip->integer;
  312. /* Loop creating new struct deppossi's. */
  313. for (;;) {
  314. depnamestart= p;
  315. /* Skip over package name characters. */
  316. while (*p && !isspace(*p) && *p != '(' && *p != ',' && *p != '|') {
  317. p++;
  318. }
  319. depnamelength= p - depnamestart ;
  320. varbuf_reset(&depname);
  321. varbuf_add_buf(&depname, depnamestart, depnamelength);
  322. varbuf_end_str(&depname);
  323. if (!depname.buf[0])
  324. parse_error(ps,
  325. _("`%s' field, missing package name, or garbage where "
  326. "package name expected"), fip->name);
  327. emsg = pkg_name_is_illegal(depname.buf, NULL);
  328. if (emsg)
  329. parse_error(ps,
  330. _("`%s' field, invalid package name `%.255s': %s"),
  331. fip->name, depname.buf, emsg);
  332. dop= nfmalloc(sizeof(struct deppossi));
  333. dop->up= dyp;
  334. dop->ed = pkg_db_find(depname.buf);
  335. dop->next= NULL; *ldopp= dop; ldopp= &dop->next;
  336. /* Don't link this (which is after all only ‘newpig’ from
  337. * the main parsing loop in parsedb) into the depended on
  338. * packages' lists yet. This will be done later when we
  339. * install this (in parse.c). For the moment we do the
  340. * ‘forward’ links in deppossi (‘ed’) only, and the ‘backward’
  341. * links from the depended on packages to dop are left undone. */
  342. dop->rev_next = NULL;
  343. dop->rev_prev = NULL;
  344. dop->cyclebreak = false;
  345. /* Skip whitespace after package name. */
  346. while (isspace(*p)) p++;
  347. /* See if we have a versioned relation. */
  348. if (*p == '(') {
  349. p++; while (isspace(*p)) p++;
  350. c1= *p;
  351. if (c1 == '<' || c1 == '>') {
  352. c2= *++p;
  353. dop->verrel= (c1 == '<') ? dvrf_earlier : dvrf_later;
  354. if (c2 == '=') {
  355. dop->verrel |= (dvrf_orequal | dvrf_builtup);
  356. p++;
  357. } else if (c2 == c1) {
  358. dop->verrel |= (dvrf_strict | dvrf_builtup);
  359. p++;
  360. } else if (c2 == '<' || c2 == '>') {
  361. parse_error(ps,
  362. _("`%s' field, reference to `%.255s':\n"
  363. " bad version relationship %c%c"),
  364. fip->name, depname.buf, c1, c2);
  365. dop->verrel= dvr_none;
  366. } else {
  367. parse_warn(ps,
  368. _("`%s' field, reference to `%.255s':\n"
  369. " `%c' is obsolete, use `%c=' or `%c%c' instead"),
  370. fip->name, depname.buf, c1, c1, c1, c1);
  371. dop->verrel |= (dvrf_orequal | dvrf_builtup);
  372. }
  373. } else if (c1 == '=') {
  374. dop->verrel= dvr_exact;
  375. p++;
  376. } else {
  377. parse_warn(ps,
  378. _("`%s' field, reference to `%.255s':\n"
  379. " implicit exact match on version number, "
  380. "suggest using `=' instead"),
  381. fip->name, depname.buf);
  382. dop->verrel= dvr_exact;
  383. }
  384. if ((dop->verrel!=dvr_exact) && (fip->integer==dep_provides))
  385. parse_warn(ps,
  386. _("Only exact versions may be used for Provides"));
  387. if (!isspace(*p) && !isalnum(*p)) {
  388. parse_warn(ps,
  389. _("`%s' field, reference to `%.255s':\n"
  390. " version value starts with non-alphanumeric, "
  391. "suggest adding a space"),
  392. fip->name, depname.buf);
  393. }
  394. /* Skip spaces between the relation and the version. */
  395. while (isspace(*p)) p++;
  396. versionstart= p;
  397. while (*p && *p != ')' && *p != '(') {
  398. if (isspace(*p)) break;
  399. p++;
  400. }
  401. versionlength= p - versionstart;
  402. while (isspace(*p)) p++;
  403. if (*p == '(')
  404. parse_error(ps,
  405. _("`%s' field, reference to `%.255s': "
  406. "version contains `%c'"), fip->name, depname.buf, ')');
  407. else if (*p != ')')
  408. parse_error(ps,
  409. _("`%s' field, reference to `%.255s': "
  410. "version contains `%c'"), fip->name, depname.buf, ' ');
  411. else if (*p == '\0')
  412. parse_error(ps,
  413. _("`%s' field, reference to `%.255s': "
  414. "version unterminated"), fip->name, depname.buf);
  415. varbuf_reset(&version);
  416. varbuf_add_buf(&version, versionstart, versionlength);
  417. varbuf_end_str(&version);
  418. parse_db_version(ps, &dop->version, version.buf,
  419. _("'%s' field, reference to '%.255s': "
  420. "error in version"), fip->name, depname.buf);
  421. p++; while (isspace(*p)) p++;
  422. } else {
  423. dop->verrel= dvr_none;
  424. blankversion(&dop->version);
  425. }
  426. if (!*p || *p == ',') break;
  427. if (*p != '|')
  428. parse_error(ps,
  429. _("`%s' field, syntax error after reference to package `%.255s'"),
  430. fip->name, dop->ed->name);
  431. if (fip->integer == dep_conflicts ||
  432. fip->integer == dep_breaks ||
  433. fip->integer == dep_provides ||
  434. fip->integer == dep_replaces)
  435. parse_error(ps,
  436. _("alternatives (`|') not allowed in %s field"), fip->name);
  437. p++; while (isspace(*p)) p++;
  438. }
  439. if (!*p) break;
  440. p++; while (isspace(*p)) p++;
  441. }
  442. }
  443. static const char *
  444. scan_word(const char **valp)
  445. {
  446. static struct varbuf word;
  447. const char *p, *start, *end;
  448. p = *valp;
  449. for (;;) {
  450. if (!*p) {
  451. *valp = p;
  452. return NULL;
  453. }
  454. if (cisspace(*p)) {
  455. p++;
  456. continue;
  457. }
  458. start = p;
  459. break;
  460. }
  461. for (;;) {
  462. if (*p && !cisspace(*p)) {
  463. p++;
  464. continue;
  465. }
  466. end = p;
  467. break;
  468. }
  469. varbuf_reset(&word);
  470. varbuf_add_buf(&word, start, end - start);
  471. varbuf_end_str(&word);
  472. *valp = p;
  473. return word.buf;
  474. }
  475. void
  476. f_trigpend(struct pkginfo *pend, struct pkgbin *pifp,
  477. struct parsedb_state *ps,
  478. const char *value, const struct fieldinfo *fip)
  479. {
  480. const char *word, *emsg;
  481. if (ps->flags & pdb_rejectstatus)
  482. parse_error(ps,
  483. _("value for `triggers-pending' field not allowed in "
  484. "this context"));
  485. while ((word = scan_word(&value))) {
  486. emsg = trig_name_is_illegal(word);
  487. if (emsg)
  488. parse_error(ps,
  489. _("illegal pending trigger name `%.255s': %s"), word, emsg);
  490. if (!trig_note_pend_core(pend, nfstrsave(word)))
  491. parse_error(ps,
  492. _("duplicate pending trigger `%.255s'"), word);
  493. }
  494. }
  495. void
  496. f_trigaw(struct pkginfo *aw, struct pkgbin *pifp,
  497. struct parsedb_state *ps,
  498. const char *value, const struct fieldinfo *fip)
  499. {
  500. const char *word, *emsg;
  501. struct pkginfo *pend;
  502. if (ps->flags & pdb_rejectstatus)
  503. parse_error(ps,
  504. _("value for `triggers-awaited' field not allowed in "
  505. "this context"));
  506. while ((word = scan_word(&value))) {
  507. emsg = pkg_name_is_illegal(word, NULL);
  508. if (emsg)
  509. parse_error(ps,
  510. _("illegal package name in awaited trigger `%.255s': %s"),
  511. word, emsg);
  512. pend = pkg_db_find(word);
  513. if (!trig_note_aw(pend, aw))
  514. parse_error(ps,
  515. _("duplicate awaited trigger package `%.255s'"), word);
  516. trig_enqueue_awaited_pend(pend);
  517. }
  518. }