예제 #1
0
파일: trigproc.c 프로젝트: pexip/os-dpkg
/*
 * Does cycle checking. Doesn't mind if pkg has no triggers pending - in
 * that case does nothing but fix up any stale awaiters.
 */
void
trigproc(struct pkginfo *pkg)
{
	static struct varbuf namesarg;

	struct trigpend *tp;
	struct pkginfo *gaveup;

	debug(dbg_triggers, "trigproc %s", pkg_describe(pkg, pdo_foreign));

	if (pkg->clientdata->trigprocdeferred)
		pkg->clientdata->trigprocdeferred->pkg = NULL;
	pkg->clientdata->trigprocdeferred = NULL;

	if (pkg->trigpend_head) {
		assert(pkg->status == stat_triggerspending ||
		       pkg->status == stat_triggersawaited);

		gaveup = check_trigger_cycle(pkg);
		if (gaveup == pkg)
			return;

		printf(_("Processing triggers for %s ...\n"),
		       pkg_describe(pkg, pdo_foreign));
		log_action("trigproc", pkg);

		varbuf_reset(&namesarg);
		for (tp = pkg->trigpend_head; tp; tp = tp->next) {
			varbuf_add_char(&namesarg, ' ');
			varbuf_add_str(&namesarg, tp->name);
		}
		varbuf_end_str(&namesarg);

		/* Setting the status to half-configured
		 * causes modstatdb_note to clear pending triggers. */
		pkg->status = stat_halfconfigured;
		modstatdb_note(pkg);

		if (!f_noact) {
			sincenothing = 0;
			maintainer_script_postinst(pkg, "triggered",
			                           namesarg.buf + 1, NULL);
		}

		/* This is to cope if the package triggers itself: */
		pkg->status = pkg->trigaw.head ? stat_triggersawaited :
		              pkg->trigpend_head ? stat_triggerspending :
		              stat_installed;

		post_postinst_tasks_core(pkg);
	} else {
		/* In other branch is done by modstatdb_note. */
		trig_clear_awaiters(pkg);
	}
}
예제 #2
0
파일: trigproc.c 프로젝트: nisc-code/dpkg
/*
 * Does cycle checking. Doesn't mind if pkg has no triggers pending - in
 * that case does nothing but fix up any stale awaiters.
 */
void
trigproc(struct pkginfo *pkg)
{
	static struct varbuf namesarg;

	struct trigpend *tp;
	struct pkginfo *gaveup;

	debug(dbg_triggers, "trigproc %s", pkg_name(pkg, pnaw_always));

	if (pkg->clientdata->trigprocdeferred)
		pkg->clientdata->trigprocdeferred->pkg = NULL;
	pkg->clientdata->trigprocdeferred = NULL;

	if (pkg->trigpend_head) {
		assert(pkg->status == stat_triggerspending ||
		       pkg->status == stat_triggersawaited);

		gaveup = check_trigger_cycle(pkg);
		if (gaveup == pkg)
			return;

		printf(_("Processing triggers for %s (%s) ...\n"),
		       pkg_name(pkg, pnaw_nonambig),
		       versiondescribe(&pkg->installed.version, vdew_nonambig));
		log_action("trigproc", pkg, &pkg->installed);

		varbuf_reset(&namesarg);
		for (tp = pkg->trigpend_head; tp; tp = tp->next) {
			varbuf_add_char(&namesarg, ' ');
			varbuf_add_str(&namesarg, tp->name);
		}
		varbuf_end_str(&namesarg);

		/* Setting the status to half-configured
		 * causes modstatdb_note to clear pending triggers. */
		pkg_set_status(pkg, stat_halfconfigured);
		modstatdb_note(pkg);

		if (!f_noact) {
			sincenothing = 0;
			maintscript_postinst(pkg, "triggered",
			                     namesarg.buf + 1, NULL);
		}

		post_postinst_tasks(pkg, stat_installed);
	} else {
		/* In other branch is done by modstatdb_note(), from inside
		 * post_postinst_tasks(). */
		trig_clear_awaiters(pkg);
	}
}
예제 #3
0
/*
 * Fix up packages in state triggers-awaited w/o the corresponding package
 * with pending triggers. This can happen when dpkg was interrupted
 * while in modstatdb_note, and the package in triggers-pending had its
 * state modified but dpkg could not finish clearing the awaiters.
 *
 * XXX: Possibly get rid of some of the checks done somewhere else for
 *      this condition at run-time.
 */
void
trig_fixup_awaiters(enum modstatdb_rw cstatus)
{
	struct pkg_list *tp;

	if (cstatus < msdbrw_write)
		return;

	for (tp = trig_awaited_pend_head; tp; tp = tp->next)
		if (!tp->pkg->trigpend_head)
			trig_clear_awaiters(tp->pkg);

	pkg_list_free(trig_awaited_pend_head);
	trig_awaited_pend_head = NULL;
}
예제 #4
0
/* Note: If anyone wants to set some triggers-pending, they must also
 * set status appropriately, or we will undo it. That is, it is legal
 * to call this when pkg->status and pkg->trigpend_head disagree and
 * in that case pkg->status takes precedence and pkg->trigpend_head
 * will be adjusted.
 */
void modstatdb_note(struct pkginfo *pkg) {
  struct trigaw *ta;

  onerr_abort++;

  /* Clear pending triggers here so that only code that sets the status
   * to interesting (for triggers) values has to care about triggers.
   */
  if (pkg->status != stat_triggerspending &&
      pkg->status != stat_triggersawaited)
    pkg->trigpend_head = NULL;

  if (pkg->status <= stat_configfiles) {
    for (ta = pkg->trigaw.head; ta; ta = ta->sameaw.next)
      ta->aw = NULL;
    pkg->trigaw.head = pkg->trigaw.tail = NULL;
  }

  log_message("status %s %s %s", statusinfos[pkg->status].name, pkg->name,
	      versiondescribe(&pkg->installed.version, vdew_nonambig));
  statusfd_send("status: %s: %s", pkg->name, statusinfos[pkg->status].name);

  if (cstatus >= msdbrw_write)
    modstatdb_note_core(pkg);

  if (!pkg->trigpend_head && pkg->othertrigaw_head) {
    /* Automatically remove us from other packages' Triggers-Awaited.
     * We do this last because we want to maximise our chances of
     * successfully recording the status of the package we were
     * pointed at by our caller, although there is some risk of
     * leaving us in a slightly odd situation which is cleared up
     * by the trigger handling logic in deppossi_ok_found.
     */
    trig_clear_awaiters(pkg);
  }

  onerr_abort--;
}
예제 #5
0
파일: trigproc.c 프로젝트: CharizTeam/dpkg
/*
 * Does cycle checking. Doesn't mind if pkg has no triggers pending - in
 * that case does nothing but fix up any stale awaiters.
 */
void
trigproc(struct pkginfo *pkg, enum trigproc_type type)
{
	static struct varbuf namesarg;

	struct varbuf depwhynot = VARBUF_INIT;
	struct trigpend *tp;
	struct pkginfo *gaveup;

	debug(dbg_triggers, "trigproc %s", pkg_name(pkg, pnaw_always));

	if (pkg->clientdata->trigprocdeferred)
		pkg->clientdata->trigprocdeferred->pkg = NULL;
	pkg->clientdata->trigprocdeferred = NULL;

	if (pkg->trigpend_head) {
		enum dep_check ok;

		assert(pkg->status == PKG_STAT_TRIGGERSPENDING ||
		       pkg->status == PKG_STAT_TRIGGERSAWAITED);

		if (dependtry > 1) {
			gaveup = check_trigger_cycle(pkg);
			if (gaveup == pkg)
				return;

			if (findbreakcycle(pkg))
				sincenothing = 0;
		}

		ok = dependencies_ok(pkg, NULL, &depwhynot);
		if (ok == DEP_CHECK_DEFER) {
			varbuf_destroy(&depwhynot);
			enqueue_package(pkg);
			return;
		} else if (ok == DEP_CHECK_HALT) {
			/* We cannot process this package on this dpkg run,
			 * and we can get here repeatedly if this package is
			 * required to make progress for other packages. So
			 * reset the trigger cycles tracking to avoid bogus
			 * cycle detections. */
			trigproc_reset_cycle();

			/* When doing opportunistic trigger processig, nothing
			 * requires us to be able to make progress; skip the
			 * package and silently ignore the error due to
			 * unsatisfiable dependencies. */
			if (type == TRIGPROC_TRY) {
				varbuf_destroy(&depwhynot);
				return;
			}

			sincenothing = 0;
			varbuf_end_str(&depwhynot);
			notice(_("dependency problems prevent processing "
			         "triggers for %s:\n%s"),
			       pkg_name(pkg, pnaw_nonambig), depwhynot.buf);
			varbuf_destroy(&depwhynot);
			ohshit(_("dependency problems - leaving triggers unprocessed"));
		} else if (depwhynot.used) {
			varbuf_end_str(&depwhynot);
			notice(_("%s: dependency problems, but processing "
			         "triggers anyway as you requested:\n%s"),
			       pkg_name(pkg, pnaw_nonambig), depwhynot.buf);
			varbuf_destroy(&depwhynot);
		}

		if (dependtry <= 1) {
			gaveup = check_trigger_cycle(pkg);
			if (gaveup == pkg)
				return;
		}

		printf(_("Processing triggers for %s (%s) ...\n"),
		       pkg_name(pkg, pnaw_nonambig),
		       versiondescribe(&pkg->installed.version, vdew_nonambig));
		log_action("trigproc", pkg, &pkg->installed);

		varbuf_reset(&namesarg);
		for (tp = pkg->trigpend_head; tp; tp = tp->next) {
			varbuf_add_char(&namesarg, ' ');
			varbuf_add_str(&namesarg, tp->name);
		}
		varbuf_end_str(&namesarg);

		/* Setting the status to half-configured
		 * causes modstatdb_note to clear pending triggers. */
		pkg_set_status(pkg, PKG_STAT_HALFCONFIGURED);
		modstatdb_note(pkg);

		if (!f_noact) {
			sincenothing = 0;
			maintscript_postinst(pkg, "triggered",
			                     namesarg.buf + 1, NULL);
		}

		post_postinst_tasks(pkg, PKG_STAT_INSTALLED);
	} else {
		/* In other branch is done by modstatdb_note(), from inside
		 * post_postinst_tasks(). */
		trig_clear_awaiters(pkg);
	}
}