/** * 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; } }
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; }
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; }
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); } }