parse.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. /*
  2. * libdpkg - Debian packaging suite library routines
  3. * parse.c - database file parsing, main package/field loop
  4. *
  5. * Copyright © 1995 Ian Jackson <ian@chiark.greenend.org.uk>
  6. *
  7. * This is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2,
  10. * or (at your option) any later version.
  11. *
  12. * This is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #include <config.h>
  21. #include <compat.h>
  22. #include <sys/types.h>
  23. #include <sys/stat.h>
  24. #ifdef HAVE_MMAP
  25. #include <sys/mman.h>
  26. #endif
  27. #include <assert.h>
  28. #include <fcntl.h>
  29. #include <ctype.h>
  30. #include <string.h>
  31. #include <unistd.h>
  32. #include <stdarg.h>
  33. #include <stdlib.h>
  34. #include <stdio.h>
  35. #include <dpkg/macros.h>
  36. #include <dpkg/i18n.h>
  37. #include <dpkg/dpkg.h>
  38. #include <dpkg/dpkg-db.h>
  39. #include <dpkg/parsedump.h>
  40. #include <dpkg/buffer.h>
  41. const struct fieldinfo fieldinfos[]= {
  42. /* NB: capitalisation of these strings is important. */
  43. { "Package", f_name, w_name },
  44. { "Essential", f_boolean, w_booleandefno, PKGIFPOFF(essential) },
  45. { "Status", f_status, w_status },
  46. { "Priority", f_priority, w_priority },
  47. { "Section", f_section, w_section },
  48. { "Installed-Size", f_charfield, w_charfield, PKGIFPOFF(installedsize) },
  49. { "Origin", f_charfield, w_charfield, PKGIFPOFF(origin) },
  50. { "Maintainer", f_charfield, w_charfield, PKGIFPOFF(maintainer) },
  51. { "Bugs", f_charfield, w_charfield, PKGIFPOFF(bugs) },
  52. { "Architecture", f_charfield, w_charfield, PKGIFPOFF(architecture) },
  53. { "Source", f_charfield, w_charfield, PKGIFPOFF(source) },
  54. { "Version", f_version, w_version, PKGIFPOFF(version) },
  55. { "Revision", f_revision, w_null },
  56. { "Config-Version", f_configversion, w_configversion },
  57. { "Replaces", f_dependency, w_dependency, dep_replaces },
  58. { "Provides", f_dependency, w_dependency, dep_provides },
  59. { "Depends", f_dependency, w_dependency, dep_depends },
  60. { "Pre-Depends", f_dependency, w_dependency, dep_predepends },
  61. { "Recommends", f_dependency, w_dependency, dep_recommends },
  62. { "Suggests", f_dependency, w_dependency, dep_suggests },
  63. { "Breaks", f_dependency, w_dependency, dep_breaks },
  64. { "Conflicts", f_dependency, w_dependency, dep_conflicts },
  65. { "Enhances", f_dependency, w_dependency, dep_enhances },
  66. { "Conffiles", f_conffiles, w_conffiles },
  67. { "Filename", f_filecharf, w_filecharf, FILEFOFF(name) },
  68. { "Size", f_filecharf, w_filecharf, FILEFOFF(size) },
  69. { "MD5sum", f_filecharf, w_filecharf, FILEFOFF(md5sum) },
  70. { "MSDOS-Filename", f_filecharf, w_filecharf, FILEFOFF(msdosname) },
  71. { "Description", f_charfield, w_charfield, PKGIFPOFF(description) },
  72. { "Triggers-Pending", f_trigpend, w_trigpend },
  73. { "Triggers-Awaited", f_trigaw, w_trigaw },
  74. /* Note that aliases are added to the nicknames table in parsehelp.c. */
  75. { NULL /* sentinel - tells code that list is ended */ }
  76. };
  77. const int nfields = sizeof_array(fieldinfos);
  78. int parsedb(const char *filename, enum parsedbflags flags,
  79. struct pkginfo **donep, FILE *warnto, int *warncount) {
  80. /* warnto, warncount and donep may be null.
  81. * If donep is not null only one package's information is expected.
  82. */
  83. static int fd;
  84. struct pkginfo newpig, *pigp;
  85. struct pkginfoperfile *newpifp, *pifp;
  86. struct arbitraryfield *arp, **larpp;
  87. struct trigaw *ta;
  88. int pdone;
  89. int fieldencountered[sizeof_array(fieldinfos)];
  90. const struct fieldinfo *fip;
  91. const struct nickname *nick;
  92. char *data, *dataptr, *endptr;
  93. const char *fieldstart, *valuestart;
  94. char *value= NULL;
  95. int fieldlen= 0, valuelen= 0;
  96. int *ip, c;
  97. struct stat stat;
  98. struct parsedb_state ps;
  99. ps.filename = filename;
  100. ps.flags = flags;
  101. ps.lno = 0;
  102. ps.warnto = warnto;
  103. ps.warncount = 0;
  104. newpifp= (flags & pdb_recordavailable) ? &newpig.available : &newpig.installed;
  105. fd= open(filename, O_RDONLY);
  106. if (fd == -1) ohshite(_("failed to open package info file `%.255s' for reading"),filename);
  107. push_cleanup(cu_closefd, ~ehflag_normaltidy, NULL, 0, 1, &fd);
  108. if (fstat(fd, &stat) == -1)
  109. ohshite(_("can't stat package info file `%.255s'"),filename);
  110. if (stat.st_size > 0) {
  111. #ifdef HAVE_MMAP
  112. if ((dataptr= (char *)mmap(NULL, stat.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED)
  113. ohshite(_("can't mmap package info file `%.255s'"),filename);
  114. #else
  115. dataptr = m_malloc(stat.st_size);
  116. fd_buf_copy(fd, dataptr, stat.st_size, _("copy info file `%.255s'"),filename);
  117. #endif
  118. data= dataptr;
  119. endptr= dataptr + stat.st_size;
  120. } else {
  121. data= dataptr= endptr= NULL;
  122. }
  123. pdone= 0;
  124. #define EOF_mmap(dataptr, endptr) (dataptr >= endptr)
  125. #define getc_mmap(dataptr) *dataptr++;
  126. #define ungetc_mmap(c, dataptr, data) dataptr--;
  127. for (;;) { /* loop per package */
  128. memset(fieldencountered, 0, sizeof(fieldencountered));
  129. blankpackage(&newpig);
  130. blankpackageperfile(newpifp);
  131. /* Skip adjacent new lines */
  132. while(!EOF_mmap(dataptr, endptr)) {
  133. c= getc_mmap(dataptr); if (c!='\n' && c!=MSDOS_EOF_CHAR ) break;
  134. ps.lno++;
  135. }
  136. if (EOF_mmap(dataptr, endptr)) break;
  137. for (;;) { /* loop per field */
  138. fieldstart= dataptr - 1;
  139. while (!EOF_mmap(dataptr, endptr) && !isspace(c) && c!=':' && c!=MSDOS_EOF_CHAR)
  140. c= getc_mmap(dataptr);
  141. fieldlen= dataptr - fieldstart - 1;
  142. while (!EOF_mmap(dataptr, endptr) && c != '\n' && isspace(c)) c= getc_mmap(dataptr);
  143. if (EOF_mmap(dataptr, endptr))
  144. parse_error(&ps, &newpig,
  145. _("EOF after field name `%.*s'"), fieldlen, fieldstart);
  146. if (c == '\n')
  147. parse_error(&ps, &newpig,
  148. _("newline in field name `%.*s'"), fieldlen, fieldstart);
  149. if (c == MSDOS_EOF_CHAR)
  150. parse_error(&ps, &newpig,
  151. _("MSDOS EOF (^Z) in field name `%.*s'"),
  152. fieldlen, fieldstart);
  153. if (c != ':')
  154. parse_error(&ps, &newpig,
  155. _("field name `%.*s' must be followed by colon"),
  156. fieldlen, fieldstart);
  157. /* Skip space after ':' but before value and eol */
  158. while(!EOF_mmap(dataptr, endptr)) {
  159. c= getc_mmap(dataptr);
  160. if (c == '\n' || !isspace(c)) break;
  161. }
  162. if (EOF_mmap(dataptr, endptr))
  163. parse_error(&ps, &newpig,
  164. _("EOF before value of field `%.*s' (missing final newline)"),
  165. fieldlen,fieldstart);
  166. if (c == MSDOS_EOF_CHAR)
  167. parse_error(&ps, &newpig,
  168. _("MSDOS EOF char in value of field `%.*s' (missing newline?)"),
  169. fieldlen,fieldstart);
  170. valuestart= dataptr - 1;
  171. for (;;) {
  172. if (c == '\n' || c == MSDOS_EOF_CHAR) {
  173. ps.lno++;
  174. if (EOF_mmap(dataptr, endptr)) break;
  175. c= getc_mmap(dataptr);
  176. /* Found double eol, or start of new field */
  177. if (EOF_mmap(dataptr, endptr) || c == '\n' || !isspace(c)) break;
  178. ungetc_mmap(c,dataptr, data);
  179. c= '\n';
  180. } else if (EOF_mmap(dataptr, endptr)) {
  181. parse_error(&ps, &newpig,
  182. _("EOF during value of field `%.*s' (missing final newline)"),
  183. fieldlen,fieldstart);
  184. }
  185. c= getc_mmap(dataptr);
  186. }
  187. valuelen= dataptr - valuestart - 1;
  188. /* trim ending space on value */
  189. while (valuelen && isspace(*(valuestart+valuelen-1)))
  190. valuelen--;
  191. for (nick = nicknames;
  192. nick->nick && (strncasecmp(nick->nick, fieldstart, fieldlen) ||
  193. nick->nick[fieldlen] != '\0'); nick++) ;
  194. if (nick->nick) {
  195. fieldstart= nick->canon;
  196. fieldlen= strlen(fieldstart);
  197. }
  198. for (fip= fieldinfos, ip= fieldencountered;
  199. fip->name && strncasecmp(fieldstart,fip->name, fieldlen);
  200. fip++, ip++);
  201. if (fip->name) {
  202. value = m_realloc(value, valuelen + 1);
  203. memcpy(value,valuestart,valuelen);
  204. *(value + valuelen) = '\0';
  205. if (*ip++)
  206. parse_error(&ps, &newpig,
  207. _("duplicate value for `%s' field"), fip->name);
  208. fip->rcall(&newpig, newpifp, &ps, value, fip);
  209. } else {
  210. if (fieldlen<2)
  211. parse_error(&ps, &newpig,
  212. _("user-defined field name `%.*s' too short"),
  213. fieldlen, fieldstart);
  214. larpp= &newpifp->arbs;
  215. while ((arp= *larpp) != NULL) {
  216. if (!strncasecmp(arp->name,fieldstart,fieldlen))
  217. parse_error(&ps, &newpig,
  218. _("duplicate value for user-defined field `%.*s'"),
  219. fieldlen, fieldstart);
  220. larpp= &arp->next;
  221. }
  222. arp= nfmalloc(sizeof(struct arbitraryfield));
  223. arp->name= nfstrnsave(fieldstart,fieldlen);
  224. arp->value= nfstrnsave(valuestart,valuelen);
  225. arp->next= NULL;
  226. *larpp= arp;
  227. }
  228. if (EOF_mmap(dataptr, endptr) || c == '\n' || c == MSDOS_EOF_CHAR) break;
  229. } /* loop per field */
  230. if (pdone && donep)
  231. parse_error(&ps, &newpig,
  232. _("several package info entries found, only one allowed"));
  233. parse_must_have_field(&ps, &newpig, newpig.name, "package name");
  234. if ((flags & pdb_recordavailable) || newpig.status != stat_notinstalled) {
  235. parse_ensure_have_field(&ps, &newpig,
  236. &newpifp->description, "description");
  237. parse_ensure_have_field(&ps, &newpig,
  238. &newpifp->maintainer, "maintainer");
  239. if (newpig.status != stat_halfinstalled)
  240. parse_must_have_field(&ps, &newpig,
  241. newpifp->version.version, "version");
  242. }
  243. if (flags & pdb_recordavailable)
  244. parse_ensure_have_field(&ps, &newpig,
  245. &newpifp->architecture, "architecture");
  246. /* Check the Config-Version information:
  247. * If there is a Config-Version it is definitely to be used, but
  248. * there shouldn't be one if the package is `installed' (in which case
  249. * the Version and/or Revision will be copied) or if the package is
  250. * `not-installed' (in which case there is no Config-Version).
  251. */
  252. if (!(flags & pdb_recordavailable)) {
  253. if (newpig.configversion.version) {
  254. if (newpig.status == stat_installed || newpig.status == stat_notinstalled)
  255. parse_error(&ps, &newpig,
  256. _("Configured-Version for package with inappropriate Status"));
  257. } else {
  258. if (newpig.status == stat_installed) newpig.configversion= newpifp->version;
  259. }
  260. }
  261. if (newpig.trigaw.head &&
  262. (newpig.status <= stat_configfiles ||
  263. newpig.status >= stat_triggerspending))
  264. parse_error(&ps, &newpig,
  265. _("package has status %s but triggers are awaited"),
  266. statusinfos[newpig.status].name);
  267. else if (newpig.status == stat_triggersawaited && !newpig.trigaw.head)
  268. parse_error(&ps, &newpig,
  269. _("package has status triggers-awaited but no triggers "
  270. "awaited"));
  271. if (!(newpig.status == stat_triggerspending ||
  272. newpig.status == stat_triggersawaited) &&
  273. newpig.trigpend_head)
  274. parse_error(&ps, &newpig,
  275. _("package has status %s but triggers are pending"),
  276. statusinfos[newpig.status].name);
  277. else if (newpig.status == stat_triggerspending && !newpig.trigpend_head)
  278. parse_error(&ps, &newpig,
  279. _("package has status triggers-pending but no triggers "
  280. "pending"));
  281. /* FIXME: There was a bug that could make a not-installed package have
  282. * conffiles, so we check for them here and remove them (rather than
  283. * calling it an error, which will do at some point).
  284. */
  285. if (!(flags & pdb_recordavailable) &&
  286. newpig.status == stat_notinstalled &&
  287. newpifp->conffiles) {
  288. parse_warn(&ps, &newpig,
  289. _("Package which in state not-installed has conffiles, "
  290. "forgetting them"));
  291. newpifp->conffiles= NULL;
  292. }
  293. /* XXX: Mark not-installed leftover packages for automatic removal on
  294. * next database dump. This code can be removed after dpkg 1.16.x, when
  295. * there's guarantee that no leftover is found on the status file on
  296. * major distributions. */
  297. if (!(flags & pdb_recordavailable) &&
  298. newpig.status == stat_notinstalled &&
  299. newpig.eflag == eflag_ok &&
  300. (newpig.want == want_purge ||
  301. newpig.want == want_deinstall ||
  302. newpig.want == want_hold)) {
  303. newpig.want = want_unknown;
  304. }
  305. pigp= findpackage(newpig.name);
  306. pifp= (flags & pdb_recordavailable) ? &pigp->available : &pigp->installed;
  307. if ((flags & pdb_ignoreolder) &&
  308. versioncompare(&newpifp->version, &pifp->version) < 0)
  309. continue;
  310. if (!pifp->valid) blankpackageperfile(pifp);
  311. /* Copy the priority and section across, but don't overwrite existing
  312. * values if the pdb_weakclassification flag is set.
  313. */
  314. if (newpig.section && *newpig.section &&
  315. !((flags & pdb_weakclassification) && pigp->section && *pigp->section))
  316. pigp->section= newpig.section;
  317. if (newpig.priority != pri_unknown &&
  318. !((flags & pdb_weakclassification) && pigp->priority != pri_unknown)) {
  319. pigp->priority= newpig.priority;
  320. if (newpig.priority == pri_other) pigp->otherpriority= newpig.otherpriority;
  321. }
  322. /* Sort out the dependency mess. */
  323. copy_dependency_links(pigp,&pifp->depends,newpifp->depends,
  324. (flags & pdb_recordavailable) ? 1 : 0);
  325. /* Leave the `depended' pointer alone, we've just gone to such
  326. * trouble to get it right :-). The `depends' pointer in
  327. * pifp was indeed also updated by copy_dependency_links,
  328. * but since the value was that from newpifp anyway there's
  329. * no need to copy it back.
  330. */
  331. newpifp->depended= pifp->depended;
  332. /* Copy across data */
  333. memcpy(pifp,newpifp,sizeof(struct pkginfoperfile));
  334. if (!(flags & pdb_recordavailable)) {
  335. pigp->want= newpig.want;
  336. pigp->eflag= newpig.eflag;
  337. pigp->status= newpig.status;
  338. pigp->configversion= newpig.configversion;
  339. pigp->files= NULL;
  340. pigp->trigpend_head = newpig.trigpend_head;
  341. pigp->trigaw = newpig.trigaw;
  342. for (ta = pigp->trigaw.head; ta; ta = ta->sameaw.next) {
  343. assert(ta->aw == &newpig);
  344. ta->aw = pigp;
  345. /* ->othertrigaw_head is updated by trig_note_aw in *(findpackage())
  346. * rather than in newpig */
  347. }
  348. } else if (!(flags & pdb_ignorefiles)) {
  349. pigp->files= newpig.files;
  350. }
  351. if (donep) *donep= pigp;
  352. pdone++;
  353. if (EOF_mmap(dataptr, endptr)) break;
  354. if (c == '\n')
  355. ps.lno++;
  356. }
  357. if (data != NULL) {
  358. #ifdef HAVE_MMAP
  359. munmap(data, stat.st_size);
  360. #else
  361. free(data);
  362. #endif
  363. }
  364. free(value);
  365. pop_cleanup(ehflag_normaltidy);
  366. if (close(fd)) ohshite(_("failed to close after read: `%.255s'"),filename);
  367. if (donep && !pdone) ohshit(_("no package information in `%.255s'"),filename);
  368. if (warncount)
  369. *warncount = ps.warncount;
  370. return pdone;
  371. }
  372. void copy_dependency_links(struct pkginfo *pkg,
  373. struct dependency **updateme,
  374. struct dependency *newdepends,
  375. int available) {
  376. /* This routine is used to update the `reverse' dependency pointers
  377. * when new `forwards' information has been constructed. It first
  378. * removes all the links based on the old information. The old
  379. * information starts in *updateme; after much brou-ha-ha
  380. * the reverse structures are created and *updateme is set
  381. * to the value from newdepends.
  382. *
  383. * Parameters are:
  384. * pkg - the package we're doing this for. This is used to
  385. * construct correct uplinks.
  386. * updateme - the forwards dependency pointer that we are to
  387. * update. This starts out containing the old forwards
  388. * info, which we use to unthread the old reverse
  389. * links. After we're done it is updated.
  390. * newdepends - the value that we ultimately want to have in
  391. * updateme.
  392. * It is likely that the backward pointer for the package in
  393. * question (`depended') will be updated by this routine,
  394. * but this will happen by the routine traversing the dependency
  395. * data structures. It doesn't need to be told where to update
  396. * that; I just mention it as something that one should be
  397. * cautious about.
  398. */
  399. struct dependency *dyp;
  400. struct deppossi *dop;
  401. struct pkginfoperfile *addtopifp;
  402. /* Delete `backward' (`depended') links from other packages to
  403. * dependencies listed in old version of this one. We do this by
  404. * going through all the dependencies in the old version of this
  405. * one and following them down to find which deppossi nodes to
  406. * remove.
  407. */
  408. for (dyp= *updateme; dyp; dyp= dyp->next) {
  409. for (dop= dyp->list; dop; dop= dop->next) {
  410. if (dop->backrev)
  411. dop->backrev->nextrev= dop->nextrev;
  412. else
  413. if (available)
  414. dop->ed->available.depended= dop->nextrev;
  415. else
  416. dop->ed->installed.depended= dop->nextrev;
  417. if (dop->nextrev)
  418. dop->nextrev->backrev= dop->backrev;
  419. }
  420. }
  421. /* Now fill in new `ed' links from other packages to dependencies listed
  422. * in new version of this one, and set our uplinks correctly.
  423. */
  424. for (dyp= newdepends; dyp; dyp= dyp->next) {
  425. dyp->up= pkg;
  426. for (dop= dyp->list; dop; dop= dop->next) {
  427. addtopifp= available ? &dop->ed->available : &dop->ed->installed;
  428. if (!addtopifp->valid) blankpackageperfile(addtopifp);
  429. dop->nextrev= addtopifp->depended;
  430. dop->backrev= NULL;
  431. if (addtopifp->depended)
  432. addtopifp->depended->backrev= dop;
  433. addtopifp->depended= dop;
  434. }
  435. }
  436. /* Finally, we fill in the new value. */
  437. *updateme= newdepends;
  438. }