Beispiel #1
0
static void
breaks_check_one(struct varbuf *aemsgs, enum dep_check *ok,
                 struct deppossi *breaks, struct pkginfo *broken,
                 struct pkginfo *breaker, struct deppossi *virtbroken)
{
  struct varbuf depmsg = VARBUF_INIT;

  debug(dbg_depcondetail, "      checking breaker %s virtbroken %s",
        pkg_name(breaker, pnaw_always),
        virtbroken ? virtbroken->ed->name : "<none>");

  if (breaker->status == PKG_STAT_NOTINSTALLED ||
      breaker->status == PKG_STAT_CONFIGFILES)
    return;
  if (broken == breaker) return;
  if (!versionsatisfied(&broken->installed, breaks)) return;
  /* The test below can only trigger if dep_breaks start having
   * arch qualifiers different from “any”. */
  if (!archsatisfied(&broken->installed, breaks))
    return;
  if (ignore_depends(breaker)) return;
  if (virtbroken && ignore_depends(&virtbroken->ed->pkg))
    return;
  if (virtbroken && !pkg_virtual_deppossi_satisfied(breaks, virtbroken))
    return;

  varbufdependency(&depmsg, breaks->up);
  varbuf_end_str(&depmsg);
  varbuf_printf(aemsgs, _(" %s (%s) breaks %s and is %s.\n"),
                pkg_name(breaker, pnaw_nonambig),
                versiondescribe(&breaker->installed.version, vdew_nonambig),
                depmsg.buf, gettext(statusstrings[breaker->status]));
  varbuf_destroy(&depmsg);

  if (virtbroken) {
    varbuf_printf(aemsgs, _("  %s (%s) provides %s.\n"),
                  pkg_name(broken, pnaw_nonambig),
                  versiondescribe(&broken->installed.version, vdew_nonambig),
                  virtbroken->ed->name);
  } else if (breaks->verrel != DPKG_RELATION_NONE) {
    varbuf_printf(aemsgs, _("  Version of %s to be configured is %s.\n"),
                  pkg_name(broken, pnaw_nonambig),
                  versiondescribe(&broken->installed.version, vdew_nonambig));
    if (in_force(FORCE_DEPENDS_VERSION))
      return;
  }
  if (force_breaks(breaks)) return;
  *ok = DEP_CHECK_HALT;
}
Beispiel #2
0
void varbufversion
(struct varbuf *vb,
 const struct dpkg_version *version,
 enum versiondisplayepochwhen vdew)
{
  switch (vdew) {
  case vdew_never:
    break;
  case vdew_nonambig:
    if (!version->epoch &&
        (!version->version || !strchr(version->version,':')) &&
        (!version->revision || !strchr(version->revision,':'))) break;
    /* Fall through. */
  case vdew_always:
    varbuf_printf(vb, "%u:", version->epoch);
    break;
  default:
    internerr("unknown versiondisplayepochwhen '%d'", vdew);
  }
  if (version->version)
    varbuf_add_str(vb, version->version);
  if (str_is_set(version->revision)) {
    varbuf_add_char(vb, '-');
    varbuf_add_str(vb, version->revision);
  }
}
Beispiel #3
0
/**
 * Read a filename from the file descriptor and create a file_info struct.
 *
 * @return A file_info struct or NULL if there is nothing to read.
 */
static struct file_info *
file_info_get(const char *root, int fd)
{
  static struct varbuf fn = VARBUF_INIT;
  struct file_info *fi;
  size_t root_len;

  varbuf_reset(&fn);
  root_len = varbuf_printf(&fn, "%s/", root);

  while (1) {
    int res;

    varbuf_grow(&fn, 1);
    res = fd_read(fd, (fn.buf + fn.used), 1);
    if (res < 0)
      return NULL;
    if (res == 0) /* EOF -> parent died. */
      return NULL;
    if (fn.buf[fn.used] == '\0')
      break;

    varbuf_trunc(&fn, fn.used + 1);
    if (fn.used >= MAXFILENAME)
      ohshit(_("file name '%.50s...' is too long"), fn.buf + root_len);
  }

  fi = file_info_new(fn.buf + root_len);
  if (lstat(fn.buf, &(fi->st)) != 0)
    ohshite(_("unable to stat file name '%.250s'"), fn.buf);

  return fi;
}
Beispiel #4
0
static void
info_spew(const char *debar, const char *dir, const char *const *argv)
{
  struct dpkg_error err;
  const char *component;
  struct varbuf controlfile = VARBUF_INIT;
  int fd;
  int re= 0;

  while ((component = *argv++) != NULL) {
    varbuf_reset(&controlfile);
    varbuf_printf(&controlfile, "%s/%s", dir, component);

    fd = open(controlfile.buf, O_RDONLY);
    if (fd >= 0) {
      if (fd_fd_copy(fd, 1, -1, &err) < 0)
        ohshit(_("cannot extract control file '%s' from '%s': %s"),
               controlfile.buf, debar, err.str);
      close(fd);
    } else if (errno == ENOENT) {
      notice(_("'%.255s' contains no control component '%.255s'"),
             debar, component);
      re++;
    } else {
      ohshite(_("open component `%.255s' (in %.255s) failed in an unexpected way"),
              component, dir);
    }
  }
  varbuf_destroy(&controlfile);

  if (re > 0)
    ohshit(P_("%d requested control component is missing",
              "%d requested control components are missing", re), re);
}
Beispiel #5
0
static void
breaks_check_one(struct varbuf *aemsgs, enum dep_check *ok,
                 struct deppossi *breaks, struct pkginfo *broken,
                 struct pkginfo *breaker, struct pkgset *virtbroken)
{
  struct varbuf depmsg = VARBUF_INIT;

  debug(dbg_depcondetail, "      checking breaker %s virtbroken %s",
        pkg_name(breaker, pnaw_always),
        virtbroken ? virtbroken->name : "<none>");

  if (breaker->status == stat_notinstalled ||
      breaker->status == stat_configfiles) return;
  if (broken == breaker) return;
  if (!versionsatisfied(&broken->installed, breaks)) return;
  /* The test below can only trigger if dep_breaks start having
   * arch qualifiers different from “any”. */
  if (!archsatisfied(&broken->installed, breaks))
    return;
  if (ignore_depends(breaker)) return;
  if (virtbroken && ignore_depends(&virtbroken->pkg))
    return;

  varbufdependency(&depmsg, breaks->up);
  varbuf_end_str(&depmsg);
  varbuf_printf(aemsgs, _(" %s (%s) breaks %s and is %s.\n"),
                pkg_name(breaker, pnaw_nonambig),
                versiondescribe(&breaker->installed.version, vdew_nonambig),
                depmsg.buf, gettext(statusstrings[breaker->status]));
  varbuf_destroy(&depmsg);

  if (virtbroken) {
    varbuf_printf(aemsgs, _("  %s (%s) provides %s.\n"),
                  pkg_name(broken, pnaw_nonambig),
                  versiondescribe(&broken->installed.version, vdew_nonambig),
                  virtbroken->name);
  } else if (breaks->verrel != dpkg_relation_none) {
    varbuf_printf(aemsgs, _("  Version of %s to be configured is %s.\n"),
                  pkg_name(broken, pnaw_nonambig),
                  versiondescribe(&broken->installed.version, vdew_nonambig));
    if (fc_dependsversion) return;
  }
  if (force_breaks(breaks)) return;
  *ok = dep_check_halt;
}
Beispiel #6
0
static const char *
diversion_current(const char *filename)
{
	static struct varbuf str = VARBUF_INIT;

	if (opt_pkgname_match_any) {
		varbuf_reset(&str);

		if (opt_divertto == NULL)
			varbuf_printf(&str, _("any diversion of %s"), filename);
		else
			varbuf_printf(&str, _("any diversion of %s to %s"),
			              filename, opt_divertto);
	} else {
		return varbuf_diversion(&str, opt_pkgname, filename, opt_divertto);
	}

	return str.buf;
}
Beispiel #7
0
static const char *
varbuf_diversion(struct varbuf *str, const char *pkgname,
                 const char *filename, const char *divertto)
{
	varbuf_reset(str);

	if (pkgname == NULL) {
		if (divertto == NULL)
			varbuf_printf(str, _("local diversion of %s"), filename);
		else
			varbuf_printf(str, _("local diversion of %s to %s"),
			              filename, divertto);
	} else {
		if (divertto == NULL)
			varbuf_printf(str, _("diversion of %s by %s"),
			              filename, pkgname);
		else
			varbuf_printf(str, _("diversion of %s to %s by %s"),
			              filename, divertto, pkgname);
	}

	return str->buf;
}
Beispiel #8
0
/**
 * Check control directory and file permissions.
 */
static void
check_file_perms(const char *ctrldir)
{
  struct varbuf path = VARBUF_INIT;
  const char *const *mscriptp;
  struct stat mscriptstab;

  varbuf_printf(&path, "%s/", ctrldir);
  if (lstat(path.buf, &mscriptstab))
    ohshite(_("unable to stat control directory"));
  if (!S_ISDIR(mscriptstab.st_mode))
    ohshit(_("control directory is not a directory"));
  if ((mscriptstab.st_mode & 07757) != 0755)
    ohshit(_("control directory has bad permissions %03lo "
             "(must be >=0755 and <=0775)"),
           (unsigned long)(mscriptstab.st_mode & 07777));

  for (mscriptp = maintainerscripts; *mscriptp; mscriptp++) {
    varbuf_reset(&path);
    varbuf_printf(&path, "%s/%s", ctrldir, *mscriptp);
    if (!lstat(path.buf, &mscriptstab)) {
      if (S_ISLNK(mscriptstab.st_mode))
        continue;
      if (!S_ISREG(mscriptstab.st_mode))
        ohshit(_("maintainer script '%.50s' is not a plain file or symlink"),
               *mscriptp);
      if ((mscriptstab.st_mode & 07557) != 0555)
        ohshit(_("maintainer script '%.50s' has bad permissions %03lo "
                 "(must be >=0555 and <=0775)"),
               *mscriptp, (unsigned long)(mscriptstab.st_mode & 07777));
    } else if (errno != ENOENT) {
      ohshite(_("maintainer script '%.50s' is not stattable"), *mscriptp);
    }
  }

  varbuf_destroy(&path);
}
Beispiel #9
0
static void
test_varbuf_printf(void)
{
	struct varbuf vb;

	varbuf_init(&vb, 5);

	/* Test normal format printing. */
	varbuf_printf(&vb, "format %s number %d", "string", 10);
	test_pass(vb.used == strlen("format string number 10"));
	test_pass(vb.size >= vb.used);
	test_str(vb.buf, ==, "format string number 10");

	varbuf_reset(&vb);

	/* Test concatenated format printing. */
	varbuf_printf(&vb, "format %s number %d", "string", 10);
	varbuf_printf(&vb, " extra %s", "string");
	test_pass(vb.used == strlen("format string number 10 extra string"));
	test_pass(vb.size >= vb.used);
	test_str(vb.buf, ==, "format string number 10 extra string");

	varbuf_destroy(&vb);
}
Beispiel #10
0
static void
trk_explicit_interest_change(const char *trig,  struct pkginfo *pkg, int signum,
                             enum trig_options opts)
{
	static struct varbuf newfn;
	char buf[1024];
	FILE *nf;
	bool empty = true;

	trk_explicit_start(trig);
	varbuf_reset(&newfn);
	varbuf_printf(&newfn, "%s/%s.new", triggersdir, trig);

	nf = fopen(newfn.buf, "w");
	if (!nf)
		ohshite(_("unable to create new trigger interest file `%.250s'"),
		        newfn.buf);
	push_cleanup(cu_closestream, ~ehflag_normaltidy, NULL, 0, 1, nf);

	while (trk_explicit_f && trk_explicit_fgets(buf, sizeof(buf)) >= 0) {
		int len = strlen(pkg->name);
		if (strncmp(buf, pkg->name, len) == 0 &&
		    (buf[len] == '\0' || buf[len] == '/'))
			continue;
		fprintf(nf, "%s\n", buf);
		empty = false;
	}
	if (signum > 0) {
		fprintf(nf, "%s%s\n", pkg->name,
		        (opts == trig_noawait) ? "/noawait" : "");
		empty = false;
	}

	if (!empty)
		trk_explicit_interest_flush(newfn.buf, nf);

	pop_cleanup(ehflag_normaltidy);
	if (fclose(nf))
		ohshite(_("unable to close new trigger interest file `%.250s'"),
		        newfn.buf);

	if (empty)
		trk_explicit_interest_remove(newfn.buf);
	else
		trk_explicit_interest_commit(newfn.buf);

	dir_sync_path(triggersdir);
}
Beispiel #11
0
void describedepcon(struct varbuf *addto, struct dependency *dep) {
  const char *fmt;
  struct varbuf depstr = VARBUF_INIT;

  switch (dep->type) {
  case dep_depends:
    fmt = _("%s depends on %s");
    break;
  case dep_predepends:
    fmt = _("%s pre-depends on %s");
    break;
  case dep_recommends:
    fmt = _("%s recommends %s");
    break;
  case dep_suggests:
    fmt = _("%s suggests %s");
    break;
  case dep_breaks:
    fmt = _("%s breaks %s");
    break;
  case dep_conflicts:
    fmt = _("%s conflicts with %s");
    break;
  case dep_enhances:
    fmt = _("%s enhances %s");
    break;
  default:
    internerr("unknown deptype '%d'", dep->type);
  }

  varbufdependency(&depstr, dep);
  varbuf_end_str(&depstr);

  varbuf_printf(addto, fmt, pkg_name(dep->up, pnaw_nonambig), depstr.buf);
  varbuf_destroy(&depstr);
}
Beispiel #12
0
/*
 * Return values:
 *   0: cannot be satisfied.
 *   1: defer: may be satisfied later, when other packages are better or
 *      at higher dependtry due to --force
 *      will set *fixbytrig to package whose trigger processing would help
 *      if applicable (and leave it alone otherwise).
 *   2: not satisfied but forcing
 *      (*interestingwarnings >= 0 on exit? caller is to print oemsgs).
 *   3: satisfied now.
 */
static enum found_status
deppossi_ok_found(struct pkginfo *possdependee, struct pkginfo *requiredby,
                  struct pkginfo *removing, struct pkgset *providing,
                  struct pkginfo **fixbytrig,
                  bool *matched, struct deppossi *checkversion,
                  int *interestingwarnings, struct varbuf *oemsgs)
{
  enum found_status thisf;

  if (ignore_depends(possdependee)) {
    debug(dbg_depcondetail,"      ignoring depended package so ok and found");
    return found_ok;
  }
  thisf = found_none;
  if (possdependee == removing) {
    if (providing) {
      varbuf_printf(oemsgs,
                    _("  Package %s which provides %s is to be removed.\n"),
                    pkg_name(possdependee, pnaw_nonambig), providing->name);
    } else {
      varbuf_printf(oemsgs, _("  Package %s is to be removed.\n"),
                    pkg_name(possdependee, pnaw_nonambig));
    }

    *matched = true;
    debug(dbg_depcondetail,"      removing possdependee, returning %d",thisf);
    return thisf;
  }
  switch (possdependee->status) {
  case stat_unpacked:
  case stat_halfconfigured:
  case stat_triggersawaited:
  case stat_triggerspending:
  case stat_installed:
    if (checkversion && !versionsatisfied(&possdependee->installed,checkversion)) {
      varbuf_printf(oemsgs, _("  Version of %s on system is %s.\n"),
                    pkg_name(possdependee, pnaw_nonambig),
                    versiondescribe(&possdependee->installed.version,
                                    vdew_nonambig));
      assert(checkversion->verrel != dpkg_relation_none);
      if (fc_dependsversion)
        thisf = (dependtry >= 3) ? found_forced : found_defer;
      debug(dbg_depcondetail,"      bad version, returning %d",thisf);
      (*interestingwarnings)++;
      return thisf;
    }
    if (possdependee->status == stat_installed ||
        possdependee->status == stat_triggerspending) {
      debug(dbg_depcondetail,"      is installed, ok and found");
      return found_ok;
    }
    if (possdependee->status == stat_triggersawaited) {
      assert(possdependee->trigaw.head);
      if (removing || !(f_triggers ||
                        possdependee->clientdata->istobe == itb_installnew)) {
        if (providing) {
          varbuf_printf(oemsgs,
                        _("  Package %s which provides %s awaits trigger processing.\n"),
                        pkg_name(possdependee, pnaw_nonambig), providing->name);
        } else {
          varbuf_printf(oemsgs,
                        _("  Package %s awaits trigger processing.\n"),
                        pkg_name(possdependee, pnaw_nonambig));
        }
        debug(dbg_depcondetail, "      triggers-awaited, no fixbytrig");
        goto unsuitable;
      }
      /* We don't check the status of trigaw.head->pend here, just in case
       * we get into the pathological situation where Triggers-Awaited but
       * the named package doesn't actually have any pending triggers. In
       * that case we queue the non-pending package for trigger processing
       * anyway, and that trigger processing will be a noop except for
       * sorting out all of the packages which name it in Triggers-Awaited.
       *
       * (This situation can only arise if modstatdb_note success in
       * clearing the triggers-pending status of the pending package
       * but then fails to go on to update the awaiters.) */
      *fixbytrig = possdependee->trigaw.head->pend;
      debug(dbg_depcondetail,
            "      triggers-awaited, fixbytrig '%s', defer",
            pkg_name(*fixbytrig, pnaw_always));
      return found_defer;
    }
    if (possdependee->clientdata &&
        possdependee->clientdata->istobe == itb_installnew) {
      debug(dbg_depcondetail,"      unpacked/halfconfigured, defer");
      return found_defer;
    } else if (!removing && fc_configureany &&
               !skip_due_to_hold(possdependee) &&
               !(possdependee->status == stat_halfconfigured)) {
      notice(_("also configuring '%s' (required by '%s')"),
             pkg_name(possdependee, pnaw_nonambig),
             pkg_name(requiredby, pnaw_nonambig));
      enqueue_package(possdependee);
      sincenothing = 0;
      return found_defer;
    } else {
      if (providing) {
        varbuf_printf(oemsgs,
                      _("  Package %s which provides %s is not configured yet.\n"),
                      pkg_name(possdependee, pnaw_nonambig), providing->name);
      } else {
        varbuf_printf(oemsgs, _("  Package %s is not configured yet.\n"),
                      pkg_name(possdependee, pnaw_nonambig));
      }

      debug(dbg_depcondetail, "      not configured/able");
      goto unsuitable;
    }

  default:
    if (providing) {
      varbuf_printf(oemsgs,
                    _("  Package %s which provides %s is not installed.\n"),
                    pkg_name(possdependee, pnaw_nonambig), providing->name);
    } else {
      varbuf_printf(oemsgs, _("  Package %s is not installed.\n"),
                    pkg_name(possdependee, pnaw_nonambig));
    }

    debug(dbg_depcondetail, "      not installed");
    goto unsuitable;
  }

unsuitable:
  debug(dbg_depcondetail, "        returning %d", thisf);
  (*interestingwarnings)++;

  return thisf;
}
Beispiel #13
0
static void
info_list(const char *debar, const char *dir)
{
  char interpreter[INTERPRETER_MAX+1], *p;
  int il, lines;
  struct varbuf controlfile = VARBUF_INIT;
  struct dirent **cdlist, *cdep;
  int cdn, n;
  FILE *cc;
  struct stat stab;
  int c;

  cdn = scandir(dir, &cdlist, &ilist_select, alphasort);
  if (cdn == -1)
    ohshite(_("cannot scan directory `%.255s'"), dir);

  for (n = 0; n < cdn; n++) {
    cdep = cdlist[n];

    varbuf_reset(&controlfile);
    varbuf_printf(&controlfile, "%s/%s", dir, cdep->d_name);

    if (stat(controlfile.buf, &stab))
      ohshite(_("cannot stat `%.255s' (in `%.255s')"), cdep->d_name, dir);
    if (S_ISREG(stab.st_mode)) {
      cc = fopen(controlfile.buf, "r");
      if (!cc)
        ohshite(_("cannot open `%.255s' (in `%.255s')"), cdep->d_name, dir);
      lines = 0;
      interpreter[0] = '\0';
      if (getc(cc) == '#') {
        if (getc(cc) == '!') {
          while ((c= getc(cc))== ' ');
          p=interpreter; *p++='#'; *p++='!'; il=2;
          while (il<INTERPRETER_MAX && !isspace(c) && c!=EOF) {
            *p++= c; il++; c= getc(cc);
          }
          *p = '\0';
          if (c=='\n') lines++;
        }
      }
      while ((c= getc(cc))!= EOF) { if (c == '\n') lines++; }
      if (ferror(cc)) ohshite(_("failed to read `%.255s' (in `%.255s')"),
                              cdep->d_name, dir);
      fclose(cc);
      printf(_(" %7jd bytes, %5d lines   %c  %-20.127s %.127s\n"),
             (intmax_t)stab.st_size, lines, S_IXUSR & stab.st_mode ? '*' : ' ',
             cdep->d_name, interpreter);
    } else {
      printf(_("     not a plain file          %.255s\n"), cdep->d_name);
    }
    free(cdep);
  }
  free(cdlist);

  varbuf_reset(&controlfile);
  varbuf_printf(&controlfile, "%s/%s", dir, CONTROLFILE);
  cc = fopen(controlfile.buf, "r");
  if (!cc) {
    if (errno != ENOENT)
      ohshite(_("failed to read `%.255s' (in `%.255s')"), CONTROLFILE, dir);
    fputs(_("(no `control' file in control archive!)\n"), stdout);
  } else {
    lines= 1;
    while ((c= getc(cc))!= EOF) {
      if (lines)
        putc(' ', stdout);
      putc(c, stdout);
      lines= c=='\n';
    }
    if (!lines)
      putc('\n', stdout);

    if (ferror(cc))
      ohshite(_("failed to read `%.255s' (in `%.255s')"), CONTROLFILE, dir);
    fclose(cc);
  }

  m_output(stdout, _("<standard output>"));
  varbuf_destroy(&controlfile);
}
Beispiel #14
0
void
pkg_format_show(const struct pkg_format_node *head,
                struct pkginfo *pkg, struct pkgbin *pkgbin)
{
	struct varbuf vb = VARBUF_INIT, fb = VARBUF_INIT, wb = VARBUF_INIT;

	while (head) {
		bool ok;
		char fmt[16];

		ok = false;

		if (head->width > 0)
			snprintf(fmt, 16, "%%%s%zus",
			         ((head->pad) ? "-" : ""), head->width);
		else
			strcpy(fmt, "%s");

		if (head->type == PKG_FORMAT_STRING) {
			varbuf_printf(&fb, fmt, head->data);
			ok = true;
		} else if (head->type == PKG_FORMAT_FIELD) {
			const struct fieldinfo *fip;

			fip = find_field_info(fieldinfos, head);

			if (fip->name == NULL)
				fip = find_field_info(virtinfos, head);

			if (fip->name) {
				fip->wcall(&wb, pkg, pkgbin, 0, fip);

				varbuf_end_str(&wb);
				varbuf_printf(&fb, fmt, wb.buf);
				varbuf_reset(&wb);
				ok = true;
			} else {
				const struct arbitraryfield *afp;

				for (afp = pkgbin->arbs; afp; afp = afp->next)
					if (strcasecmp(head->data, afp->name) == 0) {
						varbuf_printf(&fb, fmt, afp->value);
						ok = true;
						break;
					}
			}
		}

		if (ok) {
			size_t len = strlen(fb.buf);
			if ((head->width > 0) && (len > head->width))
				len = head->width;
			varbuf_add_buf(&vb, fb.buf, len);
		}

		varbuf_reset(&fb);
		head = head->next;
	}

	if (vb.buf) {
		varbuf_end_str(&vb);
		fputs(vb.buf, stdout);
	}

	varbuf_destroy(&wb);
	varbuf_destroy(&fb);
	varbuf_destroy(&vb);
}
Beispiel #15
0
/**
 * Check if conffiles contains sane information.
 */
static void
check_conffiles(const char *ctrldir, const char *rootdir)
{
  FILE *cf;
  struct varbuf controlfile = VARBUF_INIT;
  char conffilename[MAXCONFFILENAME + 1];
  struct file_info *conffiles_head = NULL;
  struct file_info *conffiles_tail = NULL;

  varbuf_printf(&controlfile, "%s/%s", ctrldir, CONFFILESFILE);

  cf = fopen(controlfile.buf, "r");
  if (cf == NULL) {
    if (errno == ENOENT)
      return;

    ohshite(_("error opening conffiles file"));
  }

  while (fgets(conffilename, MAXCONFFILENAME + 1, cf)) {
    struct stat controlstab;
    int n;

    n = strlen(conffilename);
    if (!n)
      ohshite(_("empty string from fgets reading conffiles"));

    if (conffilename[n - 1] != '\n')
      ohshit(_("conffile name '%s' is too long, or missing final newline"),
             conffilename);

    conffilename[n - 1] = '\0';
    varbuf_reset(&controlfile);
    varbuf_printf(&controlfile, "%s/%s", rootdir, conffilename);
    if (lstat(controlfile.buf, &controlstab)) {
      if (errno == ENOENT) {
        if ((n > 1) && c_isspace(conffilename[n - 2]))
          warning(_("conffile filename '%s' contains trailing white spaces"),
                  conffilename);
        ohshit(_("conffile '%.250s' does not appear in package"), conffilename);
      } else
        ohshite(_("conffile '%.250s' is not stattable"), conffilename);
    } else if (!S_ISREG(controlstab.st_mode)) {
      warning(_("conffile '%s' is not a plain file"), conffilename);
    }

    if (file_info_find_name(conffiles_head, conffilename)) {
      warning(_("conffile name '%s' is duplicated"), conffilename);
    } else {
      struct file_info *conffile;

      conffile = file_info_new(conffilename);
      file_info_list_append(&conffiles_head, &conffiles_tail, conffile);
    }
  }

  file_info_list_free(conffiles_head);
  varbuf_destroy(&controlfile);

  if (ferror(cf))
    ohshite(_("error reading conffiles file"));
  fclose(cf);
}
Beispiel #16
0
/*
 * Return values:
 *   0: cannot be satisfied.
 *   1: defer: may be satisfied later, when other packages are better or
 *      at higher dependtry due to --force
 *      will set *fixbytrig to package whose trigger processing would help
 *      if applicable (and leave it alone otherwise).
 *   2: not satisfied but forcing
 *      (*interestingwarnings >= 0 on exit? caller is to print oemsgs).
 *   3: satisfied now.
 */
static enum found_status
deppossi_ok_found(struct pkginfo *possdependee, struct pkginfo *requiredby,
                  struct pkginfo *removing, struct deppossi *provider,
                  struct pkginfo **fixbytrig,
                  bool *matched, struct deppossi *checkversion,
                  int *interestingwarnings, struct varbuf *oemsgs)
{
  enum found_status thisf;

  if (ignore_depends(possdependee)) {
    debug(dbg_depcondetail,"      ignoring depended package so ok and found");
    return FOUND_OK;
  }
  thisf = FOUND_NONE;
  if (possdependee == removing) {
    if (provider) {
      varbuf_printf(oemsgs,
                    _("  Package %s which provides %s is to be removed.\n"),
                    pkg_name(possdependee, pnaw_nonambig),
                    provider->ed->name);
    } else {
      varbuf_printf(oemsgs, _("  Package %s is to be removed.\n"),
                    pkg_name(possdependee, pnaw_nonambig));
    }

    *matched = true;
    debug(dbg_depcondetail,"      removing possdependee, returning %d",thisf);
    return thisf;
  }
  switch (possdependee->status) {
  case PKG_STAT_UNPACKED:
  case PKG_STAT_HALFCONFIGURED:
  case PKG_STAT_TRIGGERSAWAITED:
  case PKG_STAT_TRIGGERSPENDING:
  case PKG_STAT_INSTALLED:
    if (checkversion) {
      if (provider) {
        debug(dbg_depcondetail, "      checking package %s provided by pkg %s",
              checkversion->ed->name, pkg_name(possdependee, pnaw_always));
        if (!pkg_virtual_deppossi_satisfied(checkversion, provider)) {
          varbuf_printf(oemsgs,
                        _("  Version of %s on system, provided by %s, is %s.\n"),
                        checkversion->ed->name,
                        pkg_name(possdependee, pnaw_always),
                        versiondescribe(&provider->version, vdew_nonambig));
          if (in_force(FORCE_DEPENDS_VERSION))
            thisf = found_forced_on(DEPEND_TRY_FORCE_DEPENDS_VERSION);
          debug(dbg_depcondetail, "      bad version");
          goto unsuitable;
        }
      } else {
        debug(dbg_depcondetail, "      checking non-provided pkg %s",
              pkg_name(possdependee, pnaw_always));
        if (!versionsatisfied(&possdependee->installed, checkversion)) {
          varbuf_printf(oemsgs, _("  Version of %s on system is %s.\n"),
                        pkg_name(possdependee, pnaw_nonambig),
                        versiondescribe(&possdependee->installed.version,
                                        vdew_nonambig));
          if (in_force(FORCE_DEPENDS_VERSION))
            thisf = found_forced_on(DEPEND_TRY_FORCE_DEPENDS_VERSION);
          debug(dbg_depcondetail, "      bad version");
          goto unsuitable;
        }
      }
    }
    if (possdependee->status == PKG_STAT_INSTALLED ||
        possdependee->status == PKG_STAT_TRIGGERSPENDING) {
      debug(dbg_depcondetail,"      is installed, ok and found");
      return FOUND_OK;
    }
    if (possdependee->status == PKG_STAT_TRIGGERSAWAITED) {
      if (possdependee->trigaw.head == NULL)
        internerr("package %s in state %s, has no awaited triggers",
                  pkg_name(possdependee, pnaw_always),
                  pkg_status_name(possdependee));

      if (removing ||
          !(f_triggers ||
            (possdependee->clientdata &&
             possdependee->clientdata->istobe == PKG_ISTOBE_INSTALLNEW))) {
        if (provider) {
          varbuf_printf(oemsgs,
                        _("  Package %s which provides %s awaits trigger processing.\n"),
                        pkg_name(possdependee, pnaw_nonambig),
                        provider->ed->name);
        } else {
          varbuf_printf(oemsgs,
                        _("  Package %s awaits trigger processing.\n"),
                        pkg_name(possdependee, pnaw_nonambig));
        }
        debug(dbg_depcondetail, "      triggers-awaited, no fixbytrig");
        goto unsuitable;
      }
      /* We don't check the status of trigaw.head->pend here, just in case
       * we get into the pathological situation where Triggers-Awaited but
       * the named package doesn't actually have any pending triggers. In
       * that case we queue the non-pending package for trigger processing
       * anyway, and that trigger processing will be a noop except for
       * sorting out all of the packages which name it in Triggers-Awaited.
       *
       * (This situation can only arise if modstatdb_note success in
       * clearing the triggers-pending status of the pending package
       * but then fails to go on to update the awaiters.) */
      *fixbytrig = possdependee->trigaw.head->pend;
      debug(dbg_depcondetail,
            "      triggers-awaited, fixbytrig '%s', defer",
            pkg_name(*fixbytrig, pnaw_always));
      return FOUND_DEFER;
    }
    if (possdependee->clientdata &&
        possdependee->clientdata->istobe == PKG_ISTOBE_INSTALLNEW) {
      debug(dbg_depcondetail,"      unpacked/halfconfigured, defer");
      return FOUND_DEFER;
    } else if (!removing && in_force(FORCE_CONFIGURE_ANY) &&
               !skip_due_to_hold(possdependee) &&
               !(possdependee->status == PKG_STAT_HALFCONFIGURED)) {
      notice(_("also configuring '%s' (required by '%s')"),
             pkg_name(possdependee, pnaw_nonambig),
             pkg_name(requiredby, pnaw_nonambig));
      enqueue_package(possdependee);
      sincenothing = 0;
      return FOUND_DEFER;
    } else {
      if (provider) {
        varbuf_printf(oemsgs,
                      _("  Package %s which provides %s is not configured yet.\n"),
                      pkg_name(possdependee, pnaw_nonambig),
                      provider->ed->name);
      } else {
        varbuf_printf(oemsgs, _("  Package %s is not configured yet.\n"),
                      pkg_name(possdependee, pnaw_nonambig));
      }

      debug(dbg_depcondetail, "      not configured/able");
      goto unsuitable;
    }

  default:
    if (provider) {
      varbuf_printf(oemsgs,
                    _("  Package %s which provides %s is not installed.\n"),
                    pkg_name(possdependee, pnaw_nonambig),
                    provider->ed->name);
    } else {
      varbuf_printf(oemsgs, _("  Package %s is not installed.\n"),
                    pkg_name(possdependee, pnaw_nonambig));
    }

    debug(dbg_depcondetail, "      not installed");
    goto unsuitable;
  }

unsuitable:
  debug(dbg_depcondetail, "        returning %d", thisf);
  (*interestingwarnings)++;

  return thisf;
}
Beispiel #17
0
static int
mksplit(const char *file_src, const char *prefix, off_t maxpartsize,
        bool msdos)
{
	int fd_src;
	struct stat st;
	char hash[MD5HASHLEN + 1];
	char *package, *version, *arch;
	int nparts, curpart;
	off_t partsize;
	off_t cur_partsize, last_partsize;
	char *prefixdir = NULL, *msdos_prefix = NULL;
	struct varbuf file_dst = VARBUF_INIT;
	struct varbuf partmagic = VARBUF_INIT;
	struct varbuf partname = VARBUF_INIT;

	fd_src = open(file_src, O_RDONLY);
	if (fd_src < 0)
		ohshite(_("unable to open source file `%.250s'"), file_src);
	if (fstat(fd_src, &st))
		ohshite(_("unable to fstat source file"));
	if (!S_ISREG(st.st_mode))
		ohshit(_("source file `%.250s' not a plain file"), file_src);

	fd_md5(fd_src, hash, -1, "md5hash");
	lseek(fd_src, 0, SEEK_SET);

	/* FIXME: Use libdpkg-deb. */
	package = deb_field(file_src, "Package");
	version = deb_field(file_src, "Version");
	arch = deb_field(file_src, "Architecture");

	partsize = maxpartsize - HEADERALLOWANCE;
	last_partsize = st.st_size % partsize;
	if (last_partsize == 0)
		last_partsize = partsize;
	nparts = (st.st_size + partsize - 1) / partsize;

	setvbuf(stdout, NULL, _IONBF, 0);

	printf(P_("Splitting package %s into %d part: ",
	          "Splitting package %s into %d parts: ", nparts),
	       package, nparts);

	if (msdos) {
		char *t;

		t = m_strdup(prefix);
		prefixdir = m_strdup(dirname(t));
		free(t);

		msdos_prefix = m_strdup(path_basename(prefix));
		prefix = clean_msdos_filename(msdos_prefix);
	}

	for (curpart = 1; curpart <= nparts; curpart++) {
		int fd_dst;

		varbuf_reset(&file_dst);
		/* Generate output filename. */
		if (msdos) {
			char *refname;
			int prefix_max;

			m_asprintf(&refname, "%dof%d", curpart, nparts);
			prefix_max = max(8 - strlen(refname), 0);
			varbuf_printf(&file_dst, "%s/%.*s%.8s.deb",
			              prefixdir, prefix_max, prefix, refname);
			free(refname);
		} else {
			varbuf_printf(&file_dst, "%s.%dof%d.deb",
			              prefix, curpart, nparts);
		}

		if (curpart == nparts)
			cur_partsize = last_partsize;
		else
			cur_partsize = partsize;

		if (cur_partsize > maxpartsize) {
			ohshit(_("Header is too long, making part too long. "
			       "Your package name or version\n"
			       "numbers must be extraordinarily long, "
			       "or something. Giving up.\n"));
		}

		/* Split the data. */
		fd_dst = creat(file_dst.buf, 0644);
		if (fd_dst < 0)
			ohshite(_("unable to open file '%s'"), file_dst.buf);

		/* Write the ar header. */
		dpkg_ar_put_magic(file_dst.buf, fd_dst);

		/* Write the debian-split part. */
		varbuf_printf(&partmagic,
		              "%s\n%s\n%s\n%s\n%jd\n%jd\n%d/%d\n%s\n",
		              SPLITVERSION, package, version, hash,
		              (intmax_t)st.st_size, (intmax_t)partsize,
		              curpart, nparts, arch);
		dpkg_ar_member_put_mem(file_dst.buf, fd_dst, PARTMAGIC,
		                       partmagic.buf, partmagic.used);
		varbuf_reset(&partmagic);

		/* Write the data part. */
		varbuf_printf(&partname, "data.%d", curpart);
		dpkg_ar_member_put_file(file_dst.buf, fd_dst, partname.buf,
		                        fd_src, cur_partsize);
		varbuf_reset(&partname);

		close(fd_dst);

		printf("%d ", curpart);
	}

	varbuf_destroy(&file_dst);
	varbuf_destroy(&partname);
	varbuf_destroy(&partmagic);

	free(prefixdir);
	free(msdos_prefix);

	close(fd_src);

	printf(_("done\n"));

	return 0;
}