Beispiel #1
0
void
trigproc_run_deferred(void)
{
	jmp_buf ejbuf;

	debug(dbg_triggers, "trigproc_run_deferred");
	while (!pkg_queue_is_empty(&deferred)) {
		struct pkginfo *pkg;

		pkg  = pkg_queue_pop(&deferred);
		if (!pkg)
			continue;

		if (setjmp(ejbuf)) {
			pop_error_context(ehflag_bombout);
			continue;
		}
		push_error_context_jump(&ejbuf, print_error_perpackage,
		                        pkg_name(pkg, pnaw_nonambig));

		pkg->clientdata->trigprocdeferred = NULL;
		trigproc(pkg, TRIGPROC_TRY);

		pop_error_context(ehflag_normaltidy);
	}
}
Beispiel #2
0
void
trigproc_run_deferred(void)
{
	jmp_buf ejbuf;
	char *pkgname;

	debug(dbg_triggers, "trigproc_run_deferred");
	while (!pkg_queue_is_empty(&deferred)) {
		struct pkginfo *pkg;

		pkg  = pkg_queue_pop(&deferred);
		if (!pkg)
			continue;

		pkgname = m_strdup(pkg_describe(pkg, pdo_foreign));
		if (setjmp(ejbuf)) {
			pop_error_context(ehflag_bombout);
			free(pkgname);
			continue;
		}
		push_error_context_jump(&ejbuf, print_error_perpackage,
		                        pkgname);

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

		pop_error_context(ehflag_normaltidy);
		free(pkgname);
	}
}
Beispiel #3
0
void process_queue(void) {
  struct pkg_list *rundown;
  struct pkginfo *volatile pkg;
  volatile enum action action_todo;
  jmp_buf ejbuf;
  enum pkg_istobe istobe = PKG_ISTOBE_NORMAL;

  if (abort_processing)
    return;

  clear_istobes();

  switch (cipaction->arg_int) {
  case act_triggers:
  case act_configure:
  case act_install:
    istobe = PKG_ISTOBE_INSTALLNEW;
    break;
  case act_remove:
  case act_purge:
    istobe = PKG_ISTOBE_REMOVE;
    break;
  default:
    internerr("unknown action '%d'", cipaction->arg_int);
  }
  for (rundown = queue.head; rundown; rundown = rundown->next) {
    ensure_package_clientdata(rundown->pkg);

    /* We have processed this package more than once. There are no duplicates
     * as we make sure of that when enqueuing them. */
    if (rundown->pkg->clientdata->cmdline_seen > 1) {
      switch (cipaction->arg_int) {
      case act_triggers:
      case act_configure: case act_remove: case act_purge:
        printf(_("Package %s listed more than once, only processing once.\n"),
               pkg_name(rundown->pkg, pnaw_nonambig));
        break;
      case act_install:
        printf(_("More than one copy of package %s has been unpacked\n"
               " in this run !  Only configuring it once.\n"),
               pkg_name(rundown->pkg, pnaw_nonambig));
        break;
      default:
        internerr("unknown action '%d'", cipaction->arg_int);
      }
    }
    rundown->pkg->clientdata->istobe = istobe;
  }

  while (!pkg_queue_is_empty(&queue)) {
    pkg = pkg_queue_pop(&queue);
    if (!pkg)
      continue; /* Duplicate, which we removed earlier. */

    ensure_package_clientdata(pkg);
    pkg->clientdata->enqueued = false;

    action_todo = cipaction->arg_int;

    if (sincenothing++ > queue.length * 3 + 2) {
      /* Make sure that even if we have exceeded the queue since not having
       * made any progress, we are not getting stuck trying to progress by
       * trigger processing, w/o jumping into the next dependtry. */
      dependtry++;
      sincenothing = 0;
      if (dependtry >= DEPEND_TRY_LAST)
        internerr("exceeded dependtry %d (sincenothing=%d; queue.length=%d)",
                  dependtry, sincenothing, queue.length);
    } else if (sincenothing > queue.length * 2 + 2) {
      if (dependtry >= DEPEND_TRY_TRIGGERS &&
          progress_bytrigproc && progress_bytrigproc->trigpend_head) {
        enqueue_package(pkg);
        pkg = progress_bytrigproc;
        progress_bytrigproc = NULL;
        action_todo = act_configure;
      } else {
        dependtry++;
        sincenothing = 0;
        if (dependtry >= DEPEND_TRY_LAST)
          internerr("exceeded dependtry %d (sincenothing=%d, queue.length=%d)",
                    dependtry, sincenothing, queue.length);
      }
    }

    debug(dbg_general, "process queue pkg %s queue.len %d progress %d, try %d",
          pkg_name(pkg, pnaw_always), queue.length, sincenothing, dependtry);

    if (pkg->status > PKG_STAT_INSTALLED)
      internerr("package %s status %d is out-of-bounds",
                pkg_name(pkg, pnaw_always), pkg->status);

    if (setjmp(ejbuf)) {
      /* Give up on it from the point of view of other packages, i.e. reset
       * istobe. */
      pkg->clientdata->istobe = PKG_ISTOBE_NORMAL;

      pop_error_context(ehflag_bombout);
      if (abort_processing)
        return;
      continue;
    }
    push_error_context_jump(&ejbuf, print_error_perpackage,
                            pkg_name(pkg, pnaw_nonambig));

    switch (action_todo) {
    case act_triggers:
      if (!pkg->trigpend_head)
        ohshit(_("package %.250s is not ready for trigger processing\n"
                 " (current status '%.250s' with no pending triggers)"),
               pkg_name(pkg, pnaw_nonambig), pkg_status_name(pkg));
      /* Fall through. */
    case act_install:
      /* Don't try to configure pkgs that we've just disappeared. */
      if (pkg->status == PKG_STAT_NOTINSTALLED)
        break;
      /* Fall through. */
    case act_configure:
      /* Do whatever is most needed. */
      if (pkg->trigpend_head)
        trigproc(pkg, TRIGPROC_TRY_QUEUED);
      else
        deferred_configure(pkg);
      break;
    case act_remove: case act_purge:
      deferred_remove(pkg);
      break;
    default:
      internerr("unknown action '%d'", cipaction->arg_int);
    }
    m_output(stdout, _("<standard output>"));
    m_output(stderr, _("<standard error>"));

    pop_error_context(ehflag_normaltidy);
  }

  if (queue.length)
    internerr("finished package processing with non-empty queue length %d",
              queue.length);
}
Beispiel #4
0
void archivefiles(const char *const *argv) {
  const char *volatile thisarg;
  const char *const *volatile argp;
  jmp_buf ejbuf;
  int pi[2], fc, nfiles, c, i, r;
  FILE *pf;
  static struct varbuf findoutput;
  const char **arglist;
  char *p;

  trigproc_install_hooks();

  modstatdb_init(admindir,
                 f_noact ?                     msdbrw_readonly
               : cipaction->arg == act_avail ? msdbrw_write
               : fc_nonroot ?                  msdbrw_write
               :                               msdbrw_needsuperuser);

  checkpath();
  log_message("startup archives %s", cipaction->olong);

  if (f_recursive) {
    if (!*argv)
      badusage(_("--%s --recursive needs at least one path argument"),cipaction->olong);

    m_pipe(pi);
    fc = subproc_fork();
    if (!fc) {
      struct command cmd;
      const char *const *ap;

      m_dup2(pi[1],1); close(pi[0]); close(pi[1]);

      command_init(&cmd, FIND, _("find for dpkg --recursive"));
      command_add_args(&cmd, FIND, "-L", NULL);

      for (ap = argv; *ap; ap++) {
        if (strchr(FIND_EXPRSTARTCHARS,(*ap)[0])) {
          char *a;
          a= m_malloc(strlen(*ap)+10);
          strcpy(a,"./");
          strcat(a,*ap);
          command_add_arg(&cmd, a);
        } else {
          command_add_arg(&cmd, (const char *)*ap);
        }
      }

      command_add_args(&cmd, "-name", "*.deb", "-type", "f", "-print0", NULL);

      command_exec(&cmd);
    }
    close(pi[1]);

    nfiles= 0;
    pf= fdopen(pi[0],"r");  if (!pf) ohshite(_("failed to fdopen find's pipe"));
    varbufreset(&findoutput);
    while ((c= fgetc(pf)) != EOF) {
      varbufaddc(&findoutput,c);
      if (!c) nfiles++;
    }
    if (ferror(pf)) ohshite(_("error reading find's pipe"));
    if (fclose(pf)) ohshite(_("error closing find's pipe"));
    r = subproc_wait_check(fc, "find", PROCNOERR);
    if (r != 0)
      ohshit(_("find for --recursive returned unhandled error %i"),r);

    if (!nfiles)
      ohshit(_("searched, but found no packages (files matching *.deb)"));

    varbufaddc(&findoutput,0);
    varbufaddc(&findoutput,0);

    arglist= m_malloc(sizeof(char*)*(nfiles+1));
    p= findoutput.buf; i=0;
    while (*p) {
      arglist[i++]= p;
      while (*p++ != '\0') ;
    }
    arglist[i] = NULL;
    argp= arglist;
  } else {
    if (!*argv) badusage(_("--%s needs at least one package archive file argument"),
                         cipaction->olong);
    argp= argv;
  }

  currenttime = time(NULL);

  /* Initialize fname variables contents. */

  varbufreset(&fnamevb);
  varbufreset(&fnametmpvb);
  varbufreset(&fnamenewvb);

  varbufaddstr(&fnamevb,instdir); varbufaddc(&fnamevb,'/');
  varbufaddstr(&fnametmpvb,instdir); varbufaddc(&fnametmpvb,'/');
  varbufaddstr(&fnamenewvb,instdir); varbufaddc(&fnamenewvb,'/');
  fnameidlu= fnamevb.used;

  ensure_diversions();
  ensure_statoverrides();

  while ((thisarg = *argp++) != NULL) {
    if (setjmp(ejbuf)) {
      pop_error_context(ehflag_bombout);
      if (abort_processing)
        break;
      continue;
    }
    push_error_context_jump(&ejbuf, print_error_perpackage, thisarg);

    process_archive(thisarg);
    onerr_abort++;
    m_output(stdout, _("<standard output>"));
    m_output(stderr, _("<standard error>"));
    onerr_abort--;

    pop_error_context(ehflag_normaltidy);
  }

  switch (cipaction->arg) {
  case act_install:
  case act_configure:
  case act_triggers:
  case act_remove:
  case act_purge:
    process_queue();
  case act_unpack:
  case act_avail:
    break;
  default:
    internerr("unknown action '%d'", cipaction->arg);
  }

  trigproc_run_deferred();
  modstatdb_shutdown();
}
Beispiel #5
0
void process_queue(void) {
  struct pkg_list *rundown;
  struct pkginfo *volatile pkg;
  volatile enum action action_todo;
  jmp_buf ejbuf;
  enum istobes istobe= itb_normal;

  if (abort_processing)
    return;

  clear_istobes();

  switch (cipaction->arg_int) {
  case act_triggers:
  case act_configure: case act_install:  istobe= itb_installnew;  break;
  case act_remove: case act_purge:       istobe= itb_remove;      break;
  default:
    internerr("unknown action '%d'", cipaction->arg_int);
  }
  for (rundown = queue.head; rundown; rundown = rundown->next) {
    ensure_package_clientdata(rundown->pkg);
    if (rundown->pkg->clientdata->istobe == istobe) {
      /* Erase the queue entry - this is a second copy! */
      switch (cipaction->arg_int) {
      case act_triggers:
      case act_configure: case act_remove: case act_purge:
        printf(_("Package %s listed more than once, only processing once.\n"),
               pkg_name(rundown->pkg, pnaw_nonambig));
        break;
      case act_install:
        printf(_("More than one copy of package %s has been unpacked\n"
               " in this run !  Only configuring it once.\n"),
               pkg_name(rundown->pkg, pnaw_nonambig));
        break;
      default:
        internerr("unknown action '%d'", cipaction->arg_int);
      }
      rundown->pkg = NULL;
   } else {
      rundown->pkg->clientdata->istobe= istobe;
    }
  }

  while (!pkg_queue_is_empty(&queue)) {
    pkg = pkg_queue_pop(&queue);
    if (!pkg)
      continue; /* Duplicate, which we removed earlier. */

    action_todo = cipaction->arg_int;

    if (sincenothing++ > queue.length * 2 + 2) {
      if (progress_bytrigproc && progress_bytrigproc->trigpend_head) {
        enqueue_package(pkg);
        pkg = progress_bytrigproc;
        action_todo = act_configure;
      } else {
        dependtry++;
        sincenothing = 0;
        assert(dependtry <= 4);
      }
    }

    assert(pkg->status <= stat_installed);

    if (setjmp(ejbuf)) {
      /* Give up on it from the point of view of other packages, i.e. reset
       * istobe. */
      pkg->clientdata->istobe= itb_normal;

      pop_error_context(ehflag_bombout);
      if (abort_processing)
        return;
      continue;
    }
    push_error_context_jump(&ejbuf, print_error_perpackage,
                            pkg_name(pkg, pnaw_nonambig));

    switch (action_todo) {
    case act_triggers:
      if (!pkg->trigpend_head)
        ohshit(_("package %.250s is not ready for trigger processing\n"
                 " (current status `%.250s' with no pending triggers)"),
               pkg_name(pkg, pnaw_nonambig), statusinfos[pkg->status].name);
      /* Fall through. */
    case act_install:
      /* Don't try to configure pkgs that we've just disappeared. */
      if (pkg->status == stat_notinstalled)
        break;
      /* Fall through. */
    case act_configure:
      /* Do whatever is most needed. */
      if (pkg->trigpend_head)
        trigproc(pkg);
      else
        deferred_configure(pkg);
      break;
    case act_remove: case act_purge:
      deferred_remove(pkg);
      break;
    default:
      internerr("unknown action '%d'", cipaction->arg_int);
    }
    m_output(stdout, _("<standard output>"));
    m_output(stderr, _("<standard error>"));

    pop_error_context(ehflag_normaltidy);
  }
  assert(!queue.length);
}