triglib.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956
  1. /*
  2. * libdpkg - Debian packaging suite library routines
  3. * triglib.c - trigger handling
  4. *
  5. * Copyright © 2007 Canonical Ltd
  6. * Written by Ian Jackson <ian@chiark.greenend.org.uk>
  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 <sys/types.h>
  24. #include <sys/stat.h>
  25. #include <assert.h>
  26. #include <errno.h>
  27. #include <stdlib.h>
  28. #include <unistd.h>
  29. #include <dpkg/i18n.h>
  30. #include <dpkg/dpkg.h>
  31. #include <dpkg/dpkg-db.h>
  32. #include <dpkg/pkg-list.h>
  33. #include <dpkg/dlist.h>
  34. #include <dpkg/dir.h>
  35. #include <dpkg/trigdeferred.h>
  36. #include <dpkg/triglib.h>
  37. const char *
  38. trig_name_is_illegal(const char *p)
  39. {
  40. int c;
  41. if (!*p)
  42. return _("empty trigger names are not permitted");
  43. while ((c = *p++)) {
  44. if (c <= ' ' || c >= 0177)
  45. return _("trigger name contains invalid character");
  46. }
  47. return NULL;
  48. }
  49. /*========== Recording triggers. ==========*/
  50. static char *triggersdir, *triggersfilefile, *triggersnewfilefile;
  51. static char *
  52. trig_get_filename(const char *dir, const char *filename)
  53. {
  54. char *path;
  55. m_asprintf(&path, "%s/%s", dir, filename);
  56. return path;
  57. }
  58. static struct trig_hooks trigh;
  59. /*---------- Noting trigger activation in memory. ----------*/
  60. /*
  61. * Called via trig_*activate* et al from:
  62. * - trig_incorporate: reading of Unincorp (explicit trigger activations)
  63. * - various places: processing start (‘activate’ in triggers ci file)
  64. * - namenodetouse: file triggers during unpack / remove
  65. * - deferred_configure: file triggers during config file processing
  66. *
  67. * Not called from trig_transitional_activation; that runs
  68. * trig_note_pend directly which means that (a) awaiters are not
  69. * recorded (how would we know?) and (b) we don't enqueue them for
  70. * deferred processing in this run.
  71. *
  72. * We add the trigger to Triggers-Pending first. This makes it
  73. * harder to get into the state where Triggers-Awaited for aw lists
  74. * pend but Triggers-Pending for pend is empty. (See also the
  75. * comment in deppossi_ok_found regarding this situation.)
  76. */
  77. /*
  78. * aw might be NULL.
  79. * trig is not copied!
  80. */
  81. static void
  82. trig_record_activation(struct pkginfo *pend, struct pkginfo *aw, const char *trig)
  83. {
  84. if (pend->status < stat_triggersawaited)
  85. return; /* Not interested then. */
  86. if (trig_note_pend(pend, trig))
  87. modstatdb_note_ifwrite(pend);
  88. if (trigh.enqueue_deferred)
  89. trigh.enqueue_deferred(pend);
  90. if (aw && pend->status > stat_configfiles)
  91. if (trig_note_aw(pend, aw)) {
  92. if (aw->status > stat_triggersawaited)
  93. aw->status = stat_triggersawaited;
  94. modstatdb_note_ifwrite(aw);
  95. }
  96. }
  97. /*
  98. * Note: This is also called from fields.c where *pend is a temporary!
  99. *
  100. * trig is not copied!
  101. */
  102. bool
  103. trig_note_pend_core(struct pkginfo *pend, const char *trig)
  104. {
  105. struct trigpend *tp;
  106. for (tp = pend->trigpend_head; tp; tp = tp->next)
  107. if (!strcmp(tp->name, trig))
  108. return false;
  109. tp = nfmalloc(sizeof(*tp));
  110. tp->name = trig;
  111. tp->next = pend->trigpend_head;
  112. pend->trigpend_head = tp;
  113. return true;
  114. }
  115. /*
  116. * trig is not copied!
  117. *
  118. * @retval true For done.
  119. * @retval false For already noted.
  120. */
  121. bool
  122. trig_note_pend(struct pkginfo *pend, const char *trig)
  123. {
  124. if (!trig_note_pend_core(pend, trig))
  125. return false;
  126. pend->status = pend->trigaw.head ? stat_triggersawaited :
  127. stat_triggerspending;
  128. return true;
  129. }
  130. /*
  131. * Note: This is called also from fields.c where *aw is a temporary
  132. * but pend is from pkg_db_find()!
  133. *
  134. * @retval true For done.
  135. * @retval false For already noted.
  136. */
  137. bool
  138. trig_note_aw(struct pkginfo *pend, struct pkginfo *aw)
  139. {
  140. struct trigaw *ta;
  141. /* We search through aw's list because that's probably shorter. */
  142. for (ta = aw->trigaw.head; ta; ta = ta->sameaw.next)
  143. if (ta->pend == pend)
  144. return false;
  145. ta = nfmalloc(sizeof(*ta));
  146. ta->aw = aw;
  147. ta->pend = pend;
  148. ta->samepend_next = pend->othertrigaw_head;
  149. pend->othertrigaw_head = ta;
  150. LIST_LINK_TAIL_PART(aw->trigaw, ta, sameaw.);
  151. return true;
  152. }
  153. void
  154. trig_clear_awaiters(struct pkginfo *notpend)
  155. {
  156. struct trigaw *ta;
  157. struct pkginfo *aw;
  158. assert(!notpend->trigpend_head);
  159. ta = notpend->othertrigaw_head;
  160. notpend->othertrigaw_head = NULL;
  161. for (; ta; ta = ta->samepend_next) {
  162. aw = ta->aw;
  163. if (!aw)
  164. continue;
  165. LIST_UNLINK_PART(aw->trigaw, ta, sameaw.);
  166. if (!aw->trigaw.head && aw->status == stat_triggersawaited) {
  167. aw->status = aw->trigpend_head ? stat_triggerspending :
  168. stat_installed;
  169. modstatdb_note(aw);
  170. }
  171. }
  172. }
  173. static struct pkg_list *trig_awaited_pend_head;
  174. void
  175. trig_enqueue_awaited_pend(struct pkginfo *pend)
  176. {
  177. struct pkg_list *tp;
  178. for (tp = trig_awaited_pend_head; tp; tp = tp->next)
  179. if (tp->pkg == pend)
  180. return;
  181. pkg_list_prepend(&trig_awaited_pend_head, pend);
  182. }
  183. /*
  184. * Fix up packages in state triggers-awaited w/o the corresponding package
  185. * with pending triggers. This can happen when dpkg was interrupted
  186. * while in modstatdb_note, and the package in triggers-pending had its
  187. * state modified but dpkg could not finish clearing the awaiters.
  188. *
  189. * XXX: Possibly get rid of some of the checks done somewhere else for
  190. * this condition at run-time.
  191. */
  192. void
  193. trig_fixup_awaiters(enum modstatdb_rw cstatus)
  194. {
  195. struct pkg_list *tp;
  196. if (cstatus < msdbrw_write)
  197. return;
  198. for (tp = trig_awaited_pend_head; tp; tp = tp->next)
  199. if (!tp->pkg->trigpend_head)
  200. trig_clear_awaiters(tp->pkg);
  201. pkg_list_free(trig_awaited_pend_head);
  202. trig_awaited_pend_head = NULL;
  203. }
  204. /*---------- Generalized handling of trigger kinds. ----------*/
  205. struct trigkindinfo {
  206. /* Only for trig_activate_start. */
  207. void (*activate_start)(void);
  208. /* Rest are for everyone: */
  209. void (*activate_awaiter)(struct pkginfo *pkg /* may be NULL */);
  210. void (*activate_done)(void);
  211. void (*interest_change)(const char *name, struct pkginfo *pkg, int signum,
  212. enum trig_options opts);
  213. };
  214. static const struct trigkindinfo tki_explicit, tki_file, tki_unknown;
  215. static const struct trigkindinfo *dtki;
  216. /* As passed into activate_start. */
  217. static const char *trig_activating_name;
  218. static const struct trigkindinfo *
  219. trig_classify_byname(const char *name)
  220. {
  221. if (name[0] == '/') {
  222. const char *slash;
  223. slash = name;
  224. while (slash) {
  225. if (slash[1] == '\0' || slash[1] == '/')
  226. goto invalid;
  227. slash = strchr(slash + 2, '/');
  228. }
  229. return &tki_file;
  230. }
  231. if (!pkg_name_is_illegal(name, NULL) && !strchr(name, '_'))
  232. return &tki_explicit;
  233. invalid:
  234. return &tki_unknown;
  235. }
  236. /*
  237. * Calling sequence is:
  238. * trig_activate_start(triggername)
  239. * dtki->activate_awaiter(awaiting_package) } zero or more times
  240. * dtki->activate_awaiter(0) } in any order
  241. * dtki->activate_done(0)
  242. */
  243. static void
  244. trig_activate_start(const char *name)
  245. {
  246. dtki = trig_classify_byname(name);
  247. trig_activating_name = name;
  248. dtki->activate_start();
  249. }
  250. /*---------- Unknown trigger kinds. ----------*/
  251. static void
  252. trk_unknown_activate_start(void)
  253. {
  254. }
  255. static void
  256. trk_unknown_activate_awaiter(struct pkginfo *aw)
  257. {
  258. }
  259. static void
  260. trk_unknown_activate_done(void)
  261. {
  262. }
  263. static void DPKG_ATTR_NORET
  264. trk_unknown_interest_change(const char *trig, struct pkginfo *pkg, int signum,
  265. enum trig_options opts)
  266. {
  267. ohshit(_("invalid or unknown syntax in trigger name `%.250s'"
  268. " (in trigger interests for package `%.250s')"),
  269. trig, pkg->name);
  270. }
  271. static const struct trigkindinfo tki_unknown = {
  272. .activate_start = trk_unknown_activate_start,
  273. .activate_awaiter = trk_unknown_activate_awaiter,
  274. .activate_done = trk_unknown_activate_done,
  275. .interest_change = trk_unknown_interest_change,
  276. };
  277. /*---------- Explicit triggers. ----------*/
  278. static FILE *trk_explicit_f;
  279. static struct varbuf trk_explicit_fn;
  280. static char *trk_explicit_trig;
  281. static void
  282. trk_explicit_activate_done(void)
  283. {
  284. if (trk_explicit_f) {
  285. fclose(trk_explicit_f);
  286. trk_explicit_f = NULL;
  287. }
  288. }
  289. static void
  290. trk_explicit_start(const char *trig)
  291. {
  292. trk_explicit_activate_done();
  293. varbuf_reset(&trk_explicit_fn);
  294. varbuf_add_str(&trk_explicit_fn, triggersdir);
  295. varbuf_add_str(&trk_explicit_fn, trig);
  296. varbuf_end_str(&trk_explicit_fn);
  297. trk_explicit_f = fopen(trk_explicit_fn.buf, "r");
  298. if (!trk_explicit_f) {
  299. if (errno != ENOENT)
  300. ohshite(_("failed to open trigger interest list file `%.250s'"),
  301. trk_explicit_fn.buf);
  302. }
  303. }
  304. static int
  305. trk_explicit_fgets(char *buf, size_t sz)
  306. {
  307. return fgets_checked(buf, sz, trk_explicit_f, trk_explicit_fn.buf);
  308. }
  309. static void
  310. trk_explicit_activate_start(void)
  311. {
  312. trk_explicit_start(trig_activating_name);
  313. trk_explicit_trig = nfstrsave(trig_activating_name);
  314. }
  315. static void
  316. trk_explicit_activate_awaiter(struct pkginfo *aw)
  317. {
  318. char buf[1024];
  319. const char *emsg;
  320. struct pkginfo *pend;
  321. if (!trk_explicit_f)
  322. return;
  323. if (fseek(trk_explicit_f, 0, SEEK_SET))
  324. ohshite(_("failed to rewind trigger interest file `%.250s'"),
  325. trk_explicit_fn.buf);
  326. while (trk_explicit_fgets(buf, sizeof(buf)) >= 0) {
  327. char *slash;
  328. bool noawait = false;
  329. slash = strchr(buf, '/');
  330. if (slash && strcmp("/noawait", slash) == 0) {
  331. noawait = true;
  332. *slash = '\0';
  333. }
  334. emsg = pkg_name_is_illegal(buf, NULL);
  335. if (emsg)
  336. ohshit(_("trigger interest file `%.250s' syntax error; "
  337. "illegal package name `%.250s': %.250s"),
  338. trk_explicit_fn.buf, buf, emsg);
  339. pend = pkg_db_find(buf);
  340. trig_record_activation(pend, noawait ? NULL : aw,
  341. trk_explicit_trig);
  342. }
  343. }
  344. static void
  345. trk_explicit_interest_flush(const char *newfilename, FILE *nf)
  346. {
  347. if (ferror(nf))
  348. ohshite(_("unable to write new trigger interest file `%.250s'"),
  349. newfilename);
  350. if (fflush(nf))
  351. ohshite(_("unable to flush new trigger interest file '%.250s'"),
  352. newfilename);
  353. if (fsync(fileno(nf)))
  354. ohshite(_("unable to sync new trigger interest file '%.250s'"),
  355. newfilename);
  356. }
  357. static void
  358. trk_explicit_interest_commit(const char *newfilename)
  359. {
  360. if (rename(newfilename, trk_explicit_fn.buf))
  361. ohshite(_("unable to install new trigger interest file `%.250s'"),
  362. trk_explicit_fn.buf);
  363. }
  364. static void
  365. trk_explicit_interest_remove(const char *newfilename)
  366. {
  367. if (unlink(newfilename))
  368. ohshite(_("cannot remove `%.250s'"), newfilename);
  369. if (unlink(trk_explicit_fn.buf) && errno != ENOENT)
  370. ohshite(_("cannot remove `%.250s'"), trk_explicit_fn.buf);
  371. }
  372. static void
  373. trk_explicit_interest_change(const char *trig, struct pkginfo *pkg, int signum,
  374. enum trig_options opts)
  375. {
  376. static struct varbuf newfn;
  377. char buf[1024];
  378. FILE *nf;
  379. bool empty = true;
  380. trk_explicit_start(trig);
  381. varbuf_reset(&newfn);
  382. varbuf_printf(&newfn, "%s/%s.new", triggersdir, trig);
  383. nf = fopen(newfn.buf, "w");
  384. if (!nf)
  385. ohshite(_("unable to create new trigger interest file `%.250s'"),
  386. newfn.buf);
  387. push_cleanup(cu_closestream, ~ehflag_normaltidy, NULL, 0, 1, nf);
  388. while (trk_explicit_f && trk_explicit_fgets(buf, sizeof(buf)) >= 0) {
  389. int len = strlen(pkg->name);
  390. if (strncmp(buf, pkg->name, len) == 0 &&
  391. (buf[len] == '\0' || buf[len] == '/'))
  392. continue;
  393. fprintf(nf, "%s\n", buf);
  394. empty = false;
  395. }
  396. if (signum > 0) {
  397. fprintf(nf, "%s%s\n", pkg->name,
  398. (opts == trig_noawait) ? "/noawait" : "");
  399. empty = false;
  400. }
  401. if (!empty)
  402. trk_explicit_interest_flush(newfn.buf, nf);
  403. pop_cleanup(ehflag_normaltidy);
  404. if (fclose(nf))
  405. ohshite(_("unable to close new trigger interest file `%.250s'"),
  406. newfn.buf);
  407. if (empty)
  408. trk_explicit_interest_remove(newfn.buf);
  409. else
  410. trk_explicit_interest_commit(newfn.buf);
  411. dir_sync_path(triggersdir);
  412. }
  413. static const struct trigkindinfo tki_explicit = {
  414. .activate_start = trk_explicit_activate_start,
  415. .activate_awaiter = trk_explicit_activate_awaiter,
  416. .activate_done = trk_explicit_activate_done,
  417. .interest_change = trk_explicit_interest_change,
  418. };
  419. /*---------- File triggers. ----------*/
  420. static struct {
  421. struct trigfileint *head, *tail;
  422. } filetriggers;
  423. /*
  424. * Values:
  425. * -1: Not read.
  426. * 0: Not edited.
  427. * 1: Edited
  428. */
  429. static int filetriggers_edited = -1;
  430. /*
  431. * Called by various people with signum -1 and +1 to mean remove and add
  432. * and also by trig_file_interests_ensure() with signum +2 meaning add
  433. * but die if already present.
  434. */
  435. static void
  436. trk_file_interest_change(const char *trig, struct pkginfo *pkg, int signum,
  437. enum trig_options opts)
  438. {
  439. struct filenamenode *fnn;
  440. struct trigfileint **search, *tfi;
  441. fnn = trigh.namenode_find(trig, signum <= 0);
  442. if (!fnn) {
  443. assert(signum < 0);
  444. return;
  445. }
  446. for (search = trigh.namenode_interested(fnn);
  447. (tfi = *search);
  448. search = &tfi->samefile_next)
  449. if (tfi->pkg == pkg)
  450. goto found;
  451. /* Not found. */
  452. if (signum < 0)
  453. return;
  454. tfi = nfmalloc(sizeof(*tfi));
  455. tfi->pkg = pkg;
  456. tfi->fnn = fnn;
  457. tfi->options = opts;
  458. tfi->samefile_next = *trigh.namenode_interested(fnn);
  459. *trigh.namenode_interested(fnn) = tfi;
  460. LIST_LINK_TAIL_PART(filetriggers, tfi, inoverall.);
  461. goto edited;
  462. found:
  463. tfi->options = opts;
  464. if (signum > 1)
  465. ohshit(_("duplicate file trigger interest for filename `%.250s' "
  466. "and package `%.250s'"), trig, pkg->name);
  467. if (signum > 0)
  468. return;
  469. /* Remove it: */
  470. *search = tfi->samefile_next;
  471. LIST_UNLINK_PART(filetriggers, tfi, inoverall.);
  472. edited:
  473. filetriggers_edited = 1;
  474. }
  475. static void
  476. trig_file_interests_remove(void)
  477. {
  478. if (unlink(triggersfilefile) && errno != ENOENT)
  479. ohshite(_("cannot remove `%.250s'"), triggersfilefile);
  480. }
  481. static void
  482. trig_file_interests_update(void)
  483. {
  484. struct trigfileint *tfi;
  485. FILE *nf;
  486. nf = fopen(triggersnewfilefile, "w");
  487. if (!nf)
  488. ohshite(_("unable to create new file triggers file `%.250s'"),
  489. triggersnewfilefile);
  490. push_cleanup(cu_closestream, ~ehflag_normaltidy, NULL, 0, 1, nf);
  491. for (tfi = filetriggers.head; tfi; tfi = tfi->inoverall.next)
  492. fprintf(nf, "%s %s%s\n", trigh.namenode_name(tfi->fnn),
  493. tfi->pkg->name,
  494. (tfi->options == trig_noawait) ? "/noawait" : "");
  495. if (ferror(nf))
  496. ohshite(_("unable to write new file triggers file `%.250s'"),
  497. triggersnewfilefile);
  498. if (fflush(nf))
  499. ohshite(_("unable to flush new file triggers file '%.250s'"),
  500. triggersnewfilefile);
  501. if (fsync(fileno(nf)))
  502. ohshite(_("unable to sync new file triggers file '%.250s'"),
  503. triggersnewfilefile);
  504. pop_cleanup(ehflag_normaltidy);
  505. if (fclose(nf))
  506. ohshite(_("unable to close new file triggers file `%.250s'"),
  507. triggersnewfilefile);
  508. if (rename(triggersnewfilefile, triggersfilefile))
  509. ohshite(_("unable to install new file triggers file as `%.250s'"),
  510. triggersfilefile);
  511. }
  512. void
  513. trig_file_interests_save(void)
  514. {
  515. if (filetriggers_edited <= 0)
  516. return;
  517. if (!filetriggers.head)
  518. trig_file_interests_remove();
  519. else
  520. trig_file_interests_update();
  521. dir_sync_path(triggersdir);
  522. filetriggers_edited = 0;
  523. }
  524. void
  525. trig_file_interests_ensure(void)
  526. {
  527. FILE *f;
  528. char linebuf[1024], *space;
  529. struct pkginfo *pkg;
  530. const char *emsg;
  531. if (filetriggers_edited >= 0)
  532. return;
  533. f = fopen(triggersfilefile, "r");
  534. if (!f) {
  535. if (errno == ENOENT)
  536. goto ok;
  537. ohshite(_("unable to read file triggers file `%.250s'"),
  538. triggersfilefile);
  539. }
  540. push_cleanup(cu_closestream, ~0, NULL, 0, 1, f);
  541. while (fgets_checked(linebuf, sizeof(linebuf), f, triggersfilefile) >= 0) {
  542. char *slash;
  543. enum trig_options trig_opts = trig_await;
  544. space = strchr(linebuf, ' ');
  545. if (!space || linebuf[0] != '/')
  546. ohshit(_("syntax error in file triggers file `%.250s'"),
  547. triggersfilefile);
  548. *space++ = '\0';
  549. slash = strchr(space, '/');
  550. if (slash && strcmp("/noawait", slash) == 0) {
  551. trig_opts = trig_noawait;
  552. *slash = '\0';
  553. }
  554. emsg = pkg_name_is_illegal(space, NULL);
  555. if (emsg)
  556. ohshit(_("file triggers record mentions illegal "
  557. "package name `%.250s' (for interest in file "
  558. "`%.250s'): %.250s"), space, linebuf, emsg);
  559. pkg = pkg_db_find(space);
  560. trk_file_interest_change(linebuf, pkg, +2, trig_opts);
  561. }
  562. pop_cleanup(ehflag_normaltidy);
  563. ok:
  564. filetriggers_edited = 0;
  565. }
  566. static struct filenamenode *filetriggers_activating;
  567. void
  568. trig_file_activate_byname(const char *trig, struct pkginfo *aw)
  569. {
  570. struct filenamenode *fnn = trigh.namenode_find(trig, 1);
  571. if (fnn)
  572. trig_file_activate(fnn, aw);
  573. }
  574. void
  575. trig_file_activate(struct filenamenode *trig, struct pkginfo *aw)
  576. {
  577. struct trigfileint *tfi;
  578. for (tfi = *trigh.namenode_interested(trig); tfi;
  579. tfi = tfi->samefile_next)
  580. trig_record_activation(tfi->pkg, (tfi->options == trig_noawait) ?
  581. NULL : aw, trigh.namenode_name(trig));
  582. }
  583. static void
  584. trk_file_activate_start(void)
  585. {
  586. filetriggers_activating = trigh.namenode_find(trig_activating_name, 1);
  587. }
  588. static void
  589. trk_file_activate_awaiter(struct pkginfo *aw)
  590. {
  591. if (!filetriggers_activating)
  592. return;
  593. trig_file_activate(filetriggers_activating, aw);
  594. }
  595. static void
  596. trk_file_activate_done(void)
  597. {
  598. }
  599. static const struct trigkindinfo tki_file = {
  600. .activate_start = trk_file_activate_start,
  601. .activate_awaiter = trk_file_activate_awaiter,
  602. .activate_done = trk_file_activate_done,
  603. .interest_change = trk_file_interest_change,
  604. };
  605. /*---------- Trigger control info file. ----------*/
  606. static void
  607. trig_cicb_interest_change(const char *trig, struct pkginfo *pkg, int signum,
  608. enum trig_options opts)
  609. {
  610. const struct trigkindinfo *tki = trig_classify_byname(trig);
  611. assert(filetriggers_edited >= 0);
  612. tki->interest_change(trig, pkg, signum, opts);
  613. }
  614. void
  615. trig_cicb_interest_delete(const char *trig, void *user, enum trig_options opts)
  616. {
  617. trig_cicb_interest_change(trig, user, -1, opts);
  618. }
  619. void
  620. trig_cicb_interest_add(const char *trig, void *user, enum trig_options opts)
  621. {
  622. trig_cicb_interest_change(trig, user, +1, opts);
  623. }
  624. void
  625. trig_cicb_statuschange_activate(const char *trig, void *user,
  626. enum trig_options opts)
  627. {
  628. struct pkginfo *aw = user;
  629. trig_activate_start(trig);
  630. dtki->activate_awaiter((opts == trig_noawait) ? NULL : aw);
  631. dtki->activate_done();
  632. }
  633. static void
  634. parse_ci_call(const char *file, const char *cmd, trig_parse_cicb *cb,
  635. const char *trig, void *user, enum trig_options opts)
  636. {
  637. const char *emsg;
  638. emsg = trig_name_is_illegal(trig);
  639. if (emsg)
  640. ohshit(_("triggers ci file `%.250s' contains illegal trigger "
  641. "syntax in trigger name `%.250s': %.250s"),
  642. file, trig, emsg);
  643. if (cb)
  644. cb(trig, user, opts);
  645. }
  646. void
  647. trig_parse_ci(const char *file, trig_parse_cicb *interest,
  648. trig_parse_cicb *activate, void *user)
  649. {
  650. FILE *f;
  651. char linebuf[MAXTRIGDIRECTIVE], *cmd, *spc, *eol;
  652. int l;
  653. f = fopen(file, "r");
  654. if (!f) {
  655. if (errno == ENOENT)
  656. return; /* No file is just like an empty one. */
  657. ohshite(_("unable to open triggers ci file `%.250s'"), file);
  658. }
  659. push_cleanup(cu_closestream, ~0, NULL, 0, 1, f);
  660. while ((l = fgets_checked(linebuf, sizeof(linebuf), f, file)) >= 0) {
  661. for (cmd = linebuf; cisspace(*cmd); cmd++);
  662. if (*cmd == '#')
  663. continue;
  664. for (eol = linebuf + l; eol > cmd && cisspace(eol[-1]); eol--);
  665. if (eol == cmd)
  666. continue;
  667. *eol = '\0';
  668. for (spc = cmd; *spc && !cisspace(*spc); spc++);
  669. if (!*spc)
  670. ohshit(_("triggers ci file contains unknown directive syntax"));
  671. *spc++ = '\0';
  672. while (cisspace(*spc))
  673. spc++;
  674. if (!strcmp(cmd, "interest")) {
  675. parse_ci_call(file, cmd, interest, spc, user, trig_await);
  676. } else if (!strcmp(cmd, "interest-noawait")) {
  677. parse_ci_call(file, cmd, interest, spc, user, trig_noawait);
  678. } else if (!strcmp(cmd, "activate")) {
  679. parse_ci_call(file, cmd, activate, spc, user, trig_await);
  680. } else if (!strcmp(cmd, "activate-noawait")) {
  681. parse_ci_call(file, cmd, activate, spc, user, trig_noawait);
  682. } else {
  683. ohshit(_("triggers ci file contains unknown directive `%.250s'"),
  684. cmd);
  685. }
  686. }
  687. pop_cleanup(ehflag_normaltidy); /* fclose() */
  688. }
  689. /*---------- Unincorp file incorporation. ----------*/
  690. static void
  691. tdm_incorp_trig_begin(const char *trig)
  692. {
  693. trig_activate_start(trig);
  694. }
  695. static void
  696. tdm_incorp_package(const char *awname)
  697. {
  698. struct pkginfo *aw = strcmp(awname, "-") ? pkg_db_find(awname) : NULL;
  699. dtki->activate_awaiter(aw);
  700. }
  701. static void
  702. tdm_incorp_trig_end(void)
  703. {
  704. dtki->activate_done();
  705. }
  706. static const struct trigdefmeths tdm_incorp = {
  707. .trig_begin = tdm_incorp_trig_begin,
  708. .package = tdm_incorp_package,
  709. .trig_end = tdm_incorp_trig_end
  710. };
  711. void
  712. trig_incorporate(enum modstatdb_rw cstatus)
  713. {
  714. enum trigdef_update_status ur;
  715. enum trigdef_updateflags tduf;
  716. free(triggersdir);
  717. triggersdir = dpkg_db_get_path(TRIGGERSDIR);
  718. free(triggersfilefile);
  719. triggersfilefile = trig_get_filename(triggersdir, "File");
  720. free(triggersnewfilefile);
  721. triggersnewfilefile = trig_get_filename(triggersdir, "File.new");
  722. trigdef_set_methods(&tdm_incorp);
  723. trig_file_interests_ensure();
  724. tduf = tduf_nolockok;
  725. if (cstatus >= msdbrw_write) {
  726. tduf |= tduf_write;
  727. if (trigh.transitional_activate)
  728. tduf |= tduf_writeifenoent;
  729. }
  730. ur = trigdef_update_start(tduf);
  731. if (ur == tdus_error_no_dir && cstatus >= msdbrw_write) {
  732. if (mkdir(triggersdir, 0755)) {
  733. if (errno != EEXIST)
  734. ohshite(_("unable to create triggers state"
  735. " directory `%.250s'"), triggersdir);
  736. } else if (chown(triggersdir, 0, 0)) {
  737. ohshite(_("unable to set ownership of triggers state"
  738. " directory `%.250s'"), triggersdir);
  739. }
  740. ur = trigdef_update_start(tduf);
  741. }
  742. switch (ur) {
  743. case tdus_error_empty_deferred:
  744. return;
  745. case tdus_error_no_dir:
  746. case tdus_error_no_deferred:
  747. if (!trigh.transitional_activate)
  748. return;
  749. /* Fall through. */
  750. case tdus_no_deferred:
  751. trigh.transitional_activate(cstatus);
  752. break;
  753. case tdus_ok:
  754. /* Read and incorporate triggers. */
  755. trigdef_parse();
  756. break;
  757. default:
  758. internerr("unknown trigdef_update_start return value '%d'", ur);
  759. }
  760. /* Right, that's it. New (empty) Unincorp can be installed. */
  761. trigdef_process_done();
  762. }
  763. /*---------- Default hooks. ----------*/
  764. struct filenamenode {
  765. struct filenamenode *next;
  766. const char *name;
  767. struct trigfileint *trig_interested;
  768. };
  769. static struct filenamenode *trigger_files;
  770. static struct filenamenode *
  771. th_simple_nn_find(const char *name, bool nonew)
  772. {
  773. struct filenamenode *search;
  774. for (search = trigger_files; search; search = search->next)
  775. if (!strcmp(search->name, name))
  776. return search;
  777. /* Not found. */
  778. if (nonew)
  779. return NULL;
  780. search = nfmalloc(sizeof(*search));
  781. search->name = nfstrsave(name);
  782. search->trig_interested = NULL;
  783. search->next = trigger_files;
  784. trigger_files = search;
  785. return search;
  786. }
  787. TRIGHOOKS_DEFINE_NAMENODE_ACCESSORS
  788. static struct trig_hooks trigh = {
  789. .enqueue_deferred = NULL,
  790. .transitional_activate = NULL,
  791. .namenode_find = th_simple_nn_find,
  792. .namenode_interested = th_nn_interested,
  793. .namenode_name = th_nn_name,
  794. };
  795. void
  796. trig_override_hooks(const struct trig_hooks *hooks)
  797. {
  798. trigh = *hooks;
  799. }