2 * libdpkg - Debian packaging suite library routines
3 * pkg-spec.c - primitives for pkg specifier handling
5 * Copyright © 2011 Linaro Limited
6 * Copyright © 2011 Raphaël Hertzog <hertzog@debian.org>
7 * Copyright © 2011-2015 Guillem Jover <guillem@debian.org>
9 * This is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
30 #include <dpkg/i18n.h>
31 #include <dpkg/dpkg.h>
32 #include <dpkg/dpkg-db.h>
33 #include <dpkg/arch.h>
34 #include <dpkg/pkg-spec.h>
37 pkg_spec_blank(struct pkg_spec
*ps
)
42 ps
->name_is_pattern
= false;
43 ps
->arch_is_pattern
= false;
47 pkg_spec_iter_blank(struct pkg_spec
*ps
)
54 pkg_spec_init(struct pkg_spec
*ps
, enum pkg_spec_flags flags
)
59 pkg_spec_iter_blank(ps
);
63 pkg_spec_is_illegal(struct pkg_spec
*ps
)
65 static char msg
[1024];
68 if (!ps
->name_is_pattern
&&
69 (emsg
= pkg_name_is_illegal(ps
->name
))) {
72 /* Only check for DPKG_ARCH_NONE, because for everything else
73 * we want to see the passed package specification, even if
74 * the architecture is empty. */
75 if (ps
->arch
->type
== DPKG_ARCH_NONE
)
80 snprintf(msg
, sizeof(msg
),
81 _("illegal package name in specifier '%s%s%s': %s"),
82 ps
->name
, arch_sep
, ps
->arch
->name
, emsg
);
86 if ((!ps
->arch_is_pattern
&& ps
->arch
->type
== DPKG_ARCH_ILLEGAL
) ||
87 ps
->arch
->type
== DPKG_ARCH_EMPTY
) {
88 emsg
= dpkg_arch_name_is_illegal(ps
->arch
->name
);
89 snprintf(msg
, sizeof(msg
),
90 _("illegal architecture name in specifier '%s:%s': %s"),
91 ps
->name
, ps
->arch
->name
, emsg
);
95 /* If we have been requested a single instance, check that the
96 * package does not contain other instances. */
97 if (!ps
->arch_is_pattern
&& ps
->flags
& PKG_SPEC_ARCH_SINGLE
) {
100 set
= pkg_hash_find_set(ps
->name
);
102 /* Single instancing only applies with no architecture. */
103 if (ps
->arch
->type
== DPKG_ARCH_NONE
&&
104 pkgset_installed_instances(set
) > 1) {
105 snprintf(msg
, sizeof(msg
),
106 _("ambiguous package name '%s' with more "
107 "than one installed instance"), ps
->name
);
116 pkg_spec_prep(struct pkg_spec
*ps
, char *pkgname
, const char *archname
)
119 ps
->arch
= dpkg_arch_find(archname
);
121 ps
->name_is_pattern
= false;
122 ps
->arch_is_pattern
= false;
124 /* Detect if we have patterns and/or illegal names. */
125 if ((ps
->flags
& PKG_SPEC_PATTERNS
) && strpbrk(ps
->name
, "*[?\\"))
126 ps
->name_is_pattern
= true;
128 if ((ps
->flags
& PKG_SPEC_PATTERNS
) && strpbrk(ps
->arch
->name
, "*[?\\"))
129 ps
->arch_is_pattern
= true;
131 return pkg_spec_is_illegal(ps
);
135 pkg_spec_set(struct pkg_spec
*ps
, const char *pkgname
, const char *archname
)
137 return pkg_spec_prep(ps
, m_strdup(pkgname
), archname
);
141 pkg_spec_parse(struct pkg_spec
*ps
, const char *str
)
143 char *pkgname
, *archname
;
145 archname
= strchr(str
, ':');
146 if (archname
== NULL
) {
147 pkgname
= m_strdup(str
);
149 pkgname
= m_strndup(str
, archname
- str
);
153 return pkg_spec_prep(ps
, pkgname
, archname
);
157 pkg_spec_match_name(struct pkg_spec
*ps
, const char *name
)
159 if (ps
->name_is_pattern
)
160 return (fnmatch(ps
->name
, name
, 0) == 0);
162 return (strcmp(ps
->name
, name
) == 0);
166 pkg_spec_match_arch(struct pkg_spec
*ps
, struct pkginfo
*pkg
,
167 const struct dpkg_arch
*arch
)
169 if (ps
->arch_is_pattern
)
170 return (fnmatch(ps
->arch
->name
, arch
->name
, 0) == 0);
171 else if (ps
->arch
->type
!= DPKG_ARCH_NONE
) /* !arch_is_pattern */
172 return (ps
->arch
== arch
);
174 /* No arch specified. */
175 switch (ps
->flags
& PKG_SPEC_ARCH_MASK
) {
176 case PKG_SPEC_ARCH_SINGLE
:
177 return pkgset_installed_instances(pkg
->set
) <= 1;
178 case PKG_SPEC_ARCH_WILDCARD
:
181 internerr("unknown PKG_SPEC_ARCH_* flags %d in pkg_spec",
182 ps
->flags
& PKG_SPEC_ARCH_MASK
);
187 pkg_spec_match_pkg(struct pkg_spec
*ps
, struct pkginfo
*pkg
,
188 struct pkgbin
*pkgbin
)
190 return (pkg_spec_match_name(ps
, pkg
->set
->name
) &&
191 pkg_spec_match_arch(ps
, pkg
, pkgbin
->arch
));
194 static struct pkginfo
*
195 pkg_spec_get_pkg(struct pkg_spec
*ps
)
197 if (ps
->arch
->type
== DPKG_ARCH_NONE
)
198 return pkg_hash_find_singleton(ps
->name
);
200 return pkg_hash_find_pkg(ps
->name
, ps
->arch
);
204 pkg_spec_parse_pkg(const char *str
, struct dpkg_error
*err
)
210 pkg_spec_init(&ps
, PKG_SPEC_ARCH_SINGLE
);
211 emsg
= pkg_spec_parse(&ps
, str
);
213 dpkg_put_error(err
, "%s", emsg
);
216 pkg
= pkg_spec_get_pkg(&ps
);
218 pkg_spec_destroy(&ps
);
224 pkg_spec_find_pkg(const char *pkgname
, const char *archname
,
225 struct dpkg_error
*err
)
231 pkg_spec_init(&ps
, PKG_SPEC_ARCH_SINGLE
);
232 emsg
= pkg_spec_set(&ps
, pkgname
, archname
);
234 dpkg_put_error(err
, "%s", emsg
);
237 pkg
= pkg_spec_get_pkg(&ps
);
239 pkg_spec_destroy(&ps
);
245 pkg_spec_iter_init(struct pkg_spec
*ps
)
247 if (ps
->name_is_pattern
)
248 ps
->pkg_iter
= pkg_hash_iter_new();
250 ps
->pkg_next
= &pkg_hash_find_set(ps
->name
)->pkg
;
253 static struct pkginfo
*
254 pkg_spec_iter_next_pkgname(struct pkg_spec
*ps
)
258 while ((pkg
= pkg_hash_iter_next_pkg(ps
->pkg_iter
))) {
259 if (pkg_spec_match_pkg(ps
, pkg
, &pkg
->installed
))
266 static struct pkginfo
*
267 pkg_spec_iter_next_pkgarch(struct pkg_spec
*ps
)
271 while ((pkg
= ps
->pkg_next
)) {
272 ps
->pkg_next
= pkg
->arch_next
;
274 if (pkg_spec_match_arch(ps
, pkg
, pkg
->installed
.arch
))
282 pkg_spec_iter_next_pkg(struct pkg_spec
*ps
)
284 if (ps
->name_is_pattern
)
285 return pkg_spec_iter_next_pkgname(ps
);
287 return pkg_spec_iter_next_pkgarch(ps
);
291 pkg_spec_iter_destroy(struct pkg_spec
*ps
)
293 pkg_hash_iter_free(ps
->pkg_iter
);
294 pkg_spec_iter_blank(ps
);
298 pkg_spec_destroy(struct pkg_spec
*ps
)
302 pkg_spec_iter_destroy(ps
);