dpkg (1.18.25) stretch; urgency=medium
[dpkg] / lib / dpkg / pkg-db.c
CommitLineData
1479465f
GJ
1/*
2 * libdpkg - Debian packaging suite library routines
3 * pkg-db.c - low level package database routines (hash tables, etc.)
4 *
5 * Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
6 * Copyright © 2008-2014 Guillem Jover <guillem@debian.org>
7 * Copyright © 2011 Linaro Limited
8 * Copyright © 2011 Raphaël Hertzog <hertzog@debian.org>
9 *
10 * This is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
24#include <config.h>
25#include <compat.h>
26
27#include <assert.h>
28#include <string.h>
29#include <stdlib.h>
30
31#include <dpkg/i18n.h>
32#include <dpkg/c-ctype.h>
33#include <dpkg/dpkg.h>
34#include <dpkg/dpkg-db.h>
35#include <dpkg/string.h>
36#include <dpkg/arch.h>
37
38/* This must always be a prime for optimal performance.
39 * With 4093 buckets, we glean a 20% speedup, for 8191 buckets
40 * we get 23%. The nominal increase in memory usage is a mere
41 * sizeof(void *) * 8191 (i.e. less than 32 KiB on 32bit systems). */
42#define BINS 8191
43
44static struct pkgset *bins[BINS];
45static int npkg, nset;
46
47/**
48 * Return the package set with the given name.
49 *
50 * If the package already exists in the internal database, then it returns
51 * the existing structure. Otherwise it allocates a new one and will return
52 * it. The actual name associated to the package set is a lowercase version
53 * of the name given in parameter.
54 *
55 * A package set (struct pkgset) can be composed of multiple package instances
56 * (struct pkginfo) where each instance is distinguished by its architecture
57 * (as recorded in pkg.installed.arch and pkg.available.arch).
58 *
59 * @param inname Name of the package set.
60 *
61 * @return The package set.
62 */
63struct pkgset *
64pkg_db_find_set(const char *inname)
65{
66 struct pkgset **setp, *new_set;
67 char *name = m_strdup(inname), *p;
68
69 p= name;
70 while (*p) {
71 *p = c_tolower(*p);
72 p++;
73 }
74
75 setp = bins + (str_fnv_hash(name) % (BINS));
76 while (*setp && strcasecmp((*setp)->name, name))
77 setp = &(*setp)->next;
78 if (*setp) {
79 free(name);
80 return *setp;
81 }
82
83 new_set = nfmalloc(sizeof(struct pkgset));
84 pkgset_blank(new_set);
85 new_set->name = nfstrsave(name);
86 new_set->next = NULL;
87 *setp = new_set;
88 nset++;
89 npkg++;
90
91 free(name);
92
93 return new_set;
94}
95
96/**
97 * Return the singleton package instance from a package set.
98 *
99 * This means, if none are installed either an instance with native or
100 * all arch or the first if none found, the single installed instance,
101 * or NULL if more than one instance is installed.
102 *
103 * @param set The package set to use.
104 *
105 * @return The singleton package instance.
106 */
107struct pkginfo *
108pkg_db_get_singleton(struct pkgset *set)
109{
110 struct pkginfo *pkg;
111
112 switch (pkgset_installed_instances(set)) {
113 case 0:
114 /* Pick an available candidate. */
115 for (pkg = &set->pkg; pkg; pkg = pkg->arch_next) {
116 const struct dpkg_arch *arch = pkg->available.arch;
117
118 if (arch->type == DPKG_ARCH_NATIVE || arch->type == DPKG_ARCH_ALL)
119 return pkg;
120 }
121 /* Or failing that, the first entry. */
122 return &set->pkg;
123 case 1:
124 for (pkg = &set->pkg; pkg; pkg = pkg->arch_next) {
125 if (pkg->status > PKG_STAT_NOTINSTALLED)
126 return pkg;
127 }
128 internerr("pkgset '%s' should have one installed instance", set->name);
129 default:
130 return NULL;
131 }
132}
133
134/**
135 * Return the singleton package instance with the given name.
136 *
137 * @param name The package name.
138 *
139 * @return The package instance.
140 */
141struct pkginfo *
142pkg_db_find_singleton(const char *name)
143{
144 struct pkgset *set;
145 struct pkginfo *pkg;
146
147 set = pkg_db_find_set(name);
148 pkg = pkg_db_get_singleton(set);
149 if (pkg == NULL)
150 ohshit(_("ambiguous package name '%s' with more "
151 "than one installed instance"), set->name);
152
153 return pkg;
154}
155
156/**
157 * Return the package instance in a set with the given architecture.
158 *
159 * It traverse the various instances to find out whether there's one
160 * matching the given architecture. If found, it returns it. Otherwise it
161 * allocates a new instance and registers it in the package set before
162 * returning it.
163 *
164 * @param set The package set to use.
165 * @param arch The requested architecture.
166 *
167 * @return The package instance.
168 */
169struct pkginfo *
170pkg_db_get_pkg(struct pkgset *set, const struct dpkg_arch *arch)
171{
172 struct pkginfo *pkg, **pkgp;
173
174 assert(arch);
175 assert(arch->type != DPKG_ARCH_NONE);
176
177 pkg = &set->pkg;
178
179 /* If there's a single unused slot, let's use that. */
180 if (pkg->installed.arch->type == DPKG_ARCH_NONE && pkg->arch_next == NULL) {
181 pkg->installed.arch = arch;
182 pkg->available.arch = arch;
183 return pkg;
184 }
185
186 /* Match the slot with the most appropriate architecture. The installed
187 * architecture always has preference over the available one, as there's
188 * a small time window on cross-grades, where they might differ. */
189 for (pkgp = &pkg; *pkgp; pkgp = &(*pkgp)->arch_next) {
190 if ((*pkgp)->installed.arch == arch)
191 return *pkgp;
192 }
193
194 /* Need to create a new instance for the wanted architecture. */
195 pkg = nfmalloc(sizeof(struct pkginfo));
196 pkg_blank(pkg);
197 pkg->set = set;
198 pkg->arch_next = NULL;
199 pkg->installed.arch = arch;
200 pkg->available.arch = arch;
201 *pkgp = pkg;
202 npkg++;
203
204 return pkg;
205}
206
207/**
208 * Return the package instance with the given name and architecture.
209 *
210 * @param name The package name.
211 * @param arch The requested architecture.
212 *
213 * @return The package instance.
214 */
215struct pkginfo *
216pkg_db_find_pkg(const char *name, const struct dpkg_arch *arch)
217{
218 struct pkgset *set;
219 struct pkginfo *pkg;
220
221 set = pkg_db_find_set(name);
222 pkg = pkg_db_get_pkg(set, arch);
223
224 return pkg;
225}
226
227/**
228 * Return the number of package sets available in the database.
229 *
230 * @return The number of package sets.
231 */
232int
233pkg_db_count_set(void)
234{
235 return nset;
236}
237
238/**
239 * Return the number of package instances available in the database.
240 *
241 * @return The number of package instances.
242 */
243int
244pkg_db_count_pkg(void)
245{
246 return npkg;
247}
248
249struct pkgiterator {
250 struct pkginfo *pkg;
251 int nbinn;
252};
253
254/**
255 * Create a new package iterator.
256 *
257 * It can iterate either over package sets or over package instances.
258 *
259 * @return The iterator.
260 */
261struct pkgiterator *
262pkg_db_iter_new(void)
263{
264 struct pkgiterator *iter;
265
266 iter = m_malloc(sizeof(struct pkgiterator));
267 iter->pkg = NULL;
268 iter->nbinn = 0;
269
270 return iter;
271}
272
273/**
274 * Return the next package set in the database.
275 *
276 * If no further package set is available, it will return NULL.
277 *
278 * @name iter The iterator.
279 *
280 * @return A package set.
281 */
282struct pkgset *
283pkg_db_iter_next_set(struct pkgiterator *iter)
284{
285 struct pkgset *set;
286
287 while (!iter->pkg) {
288 if (iter->nbinn >= BINS)
289 return NULL;
290 if (bins[iter->nbinn])
291 iter->pkg = &bins[iter->nbinn]->pkg;
292 iter->nbinn++;
293 }
294
295 set = iter->pkg->set;
296 if (set->next)
297 iter->pkg = &set->next->pkg;
298 else
299 iter->pkg = NULL;
300
301 return set;
302}
303
304/**
305 * Return the next package instance in the database.
306 *
307 * If no further package instance is available, it will return NULL. Note
308 * that it will return all instances of a given package set in sequential
309 * order. The first instance for a given package set will always correspond
310 * to the native architecture even if that package is not installed or
311 * available.
312 *
313 * @name iter The iterator.
314 *
315 * @return A package instance.
316 */
317struct pkginfo *
318pkg_db_iter_next_pkg(struct pkgiterator *iter)
319{
320 struct pkginfo *pkg;
321
322 while (!iter->pkg) {
323 if (iter->nbinn >= BINS)
324 return NULL;
325 if (bins[iter->nbinn])
326 iter->pkg = &bins[iter->nbinn]->pkg;
327 iter->nbinn++;
328 }
329
330 pkg = iter->pkg;
331 if (pkg->arch_next)
332 iter->pkg = pkg->arch_next;
333 else if (pkg->set->next)
334 iter->pkg = &pkg->set->next->pkg;
335 else
336 iter->pkg = NULL;
337
338 return pkg;
339}
340
341/**
342 * Free the package database iterator.
343 *
344 * @name iter The iterator.
345 */
346void
347pkg_db_iter_free(struct pkgiterator *iter)
348{
349 free(iter);
350}
351
352void
353pkg_db_reset(void)
354{
355 int i;
356
357 dpkg_arch_reset_list();
358 nffreeall();
359 nset = 0;
360 npkg = 0;
361 for (i=0; i<BINS; i++) bins[i]= NULL;
362}
363
364void
365pkg_db_report(FILE *file)
366{
367 int i, c;
368 struct pkgset *pkg;
369 int *freq;
370
371 freq = m_malloc(sizeof(int) * nset + 1);
372 for (i = 0; i <= nset; i++)
373 freq[i] = 0;
374 for (i=0; i<BINS; i++) {
375 for (c=0, pkg= bins[i]; pkg; c++, pkg= pkg->next);
376 fprintf(file,"bin %5d has %7d\n",i,c);
377 freq[c]++;
378 }
379 for (i = nset; i > 0 && freq[i] == 0; i--);
380 while (i >= 0) {
381 fprintf(file, "size %7d occurs %5d times\n", i, freq[i]);
382 i--;
383 }
384
385 m_output(file, "<hash report>");
386
387 free(freq);
388}