Beispiel #1
0
/**
 * Return the singleton package instance from a package set.
 *
 * This means, if none are installed either an instance with native or
 * all arch or the first if none found, the single installed instance,
 * or NULL if more than one instance is installed.
 *
 * @param set The package set to use.
 *
 * @return The singleton package instance.
 */
struct pkginfo *
pkg_hash_get_singleton(struct pkgset *set)
{
  struct pkginfo *pkg;

  switch (pkgset_installed_instances(set)) {
  case 0:
    /* Pick an available candidate. */
    for (pkg = &set->pkg; pkg; pkg = pkg->arch_next) {
      const struct dpkg_arch *arch = pkg->available.arch;

      if (arch->type == DPKG_ARCH_NATIVE || arch->type == DPKG_ARCH_ALL)
        return pkg;
    }
    /* Or failing that, the first entry. */
    return &set->pkg;
  case 1:
    for (pkg = &set->pkg; pkg; pkg = pkg->arch_next) {
      if (pkg->status > PKG_STAT_NOTINSTALLED)
        return pkg;
    }
    internerr("pkgset '%s' should have one installed instance", set->name);
  default:
    return NULL;
  }
}
Beispiel #2
0
const char *
pkg_spec_is_illegal(struct pkg_spec *ps)
{
	static char msg[1024];
	const char *emsg;

	if (!ps->name_is_pattern &&
	    (emsg = pkg_name_is_illegal(ps->name))) {
		const char *arch_sep;

		/* Only check for DPKG_ARCH_NONE, because for everything else
		 * we want to see the passed package specification, even if
		 * the architecture is empty. */
		if (ps->arch->type == DPKG_ARCH_NONE)
			arch_sep = "";
		else
			arch_sep = ":";

		snprintf(msg, sizeof(msg),
		         _("illegal package name in specifier '%s%s%s': %s"),
		         ps->name, arch_sep, ps->arch->name, emsg);
		return msg;
	}

	if ((!ps->arch_is_pattern && ps->arch->type == DPKG_ARCH_ILLEGAL) ||
	    ps->arch->type == DPKG_ARCH_EMPTY) {
		emsg = dpkg_arch_name_is_illegal(ps->arch->name);
		snprintf(msg, sizeof(msg),
		         _("illegal architecture name in specifier '%s:%s': %s"),
		         ps->name, ps->arch->name, emsg);
		return msg;
	}

	/* If we have been requested a single instance, check that the
	 * package does not contain other instances. */
	if (!ps->arch_is_pattern && ps->flags & PKG_SPEC_ARCH_SINGLE) {
		struct pkgset *set;

		set = pkg_db_find_set(ps->name);

		/* Single instancing only applies with no architecture. */
		if (ps->arch->type == DPKG_ARCH_NONE &&
		    pkgset_installed_instances(set) > 1) {
			snprintf(msg, sizeof(msg),
			         _("ambiguous package name '%s' with more "
			           "than one installed instance"), ps->name);
			return msg;
		}
	}

	return NULL;
}
Beispiel #3
0
const char *
pkg_spec_is_illegal(struct pkg_spec *ps)
{
	static char msg[1024];
	const char *emsg;

	if (!ps->name_is_pattern &&
	    (emsg = pkg_name_is_illegal(ps->name))) {
		snprintf(msg, sizeof(msg),
		         _("illegal package name in specifier '%s%s%s': %s"),
		         ps->name,
		         (ps->arch->type != DPKG_ARCH_NONE) ? ":" : "",
		         ps->arch->name, emsg);
		return msg;
	}

	if ((!ps->arch_is_pattern && ps->arch->type == DPKG_ARCH_ILLEGAL) ||
	    ps->arch->type == DPKG_ARCH_EMPTY) {
		emsg = dpkg_arch_name_is_illegal(ps->arch->name);
		snprintf(msg, sizeof(msg),
		         _("illegal architecture name in specifier '%s:%s': %s"),
		         ps->name, ps->arch->name, emsg);
		return msg;
	}

	/* If we have been requested a single instance, check that the
	 * package does not contain other instances. */
	if (!ps->arch_is_pattern && ps->flags & PKG_SPEC_ARCH_SINGLE) {
		struct pkgset *set;

		set = pkg_db_find_set(ps->name);

		/* Single instancing only applies with no architecture. */
		if (ps->arch->type == DPKG_ARCH_NONE &&
		    pkgset_installed_instances(set) > 1) {
			snprintf(msg, sizeof(msg),
			         _("ambiguous package name '%s' with more "
			           "than one installed instance"), ps->name);
			return msg;
		}
	}

	return NULL;
}
Beispiel #4
0
static bool
pkg_spec_match_arch(struct pkg_spec *ps, struct pkginfo *pkg,
                    const struct dpkg_arch *arch)
{
	if (ps->arch_is_pattern)
		return (fnmatch(ps->arch->name, arch->name, 0) == 0);
	else if (ps->arch->type != DPKG_ARCH_NONE) /* !arch_is_pattern */
		return (ps->arch == arch);

	/* No arch specified. */
	switch (ps->flags & PKG_SPEC_ARCH_MASK) {
	case PKG_SPEC_ARCH_SINGLE:
		return pkgset_installed_instances(pkg->set) <= 1;
	case PKG_SPEC_ARCH_WILDCARD:
		return true;
	default:
		internerr("unknown PKG_SPEC_ARCH_* flags %d in pkg_spec",
		          ps->flags & PKG_SPEC_ARCH_MASK);
	}
}