Branch data Line data Source code
1 : : /*-
2 : : * Copyright (c) 2011-2022 Baptiste Daroussin <bapt@FreeBSD.org>
3 : : * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
4 : : * Copyright (c) 2011 Will Andrews <will@FreeBSD.org>
5 : : * Copyright (c) 2011 Philippe Pepiot <phil@philpep.org>
6 : : * Copyright (c) 2011-2012 Marin Atanasov Nikolov <dnaeon@gmail.com>
7 : : * Copyright (c) 2012-2013 Matthew Seaman <matthew@FreeBSD.org>
8 : : * Copyright (c) 2012 Bryan Drewery <bryan@shatow.net>
9 : : * Copyright (c) 2013 Gerald Pfeifer <gerald@pfeifer.com>
10 : : * Copyright (c) 2013-2014 Vsevolod Stakhov <vsevolod@FreeBSD.org>
11 : : * Copyright (c) 2023 Serenity Cyber Security, LLC
12 : : * Author: Gleb Popov <arrowd@FreeBSD.org>
13 : : * All rights reserved.
14 : : *
15 : : * Redistribution and use in source and binary forms, with or without
16 : : * modification, are permitted provided that the following conditions
17 : : * are met:
18 : : * 1. Redistributions of source code must retain the above copyright
19 : : * notice, this list of conditions and the following disclaimer
20 : : * in this position and unchanged.
21 : : * 2. Redistributions in binary form must reproduce the above copyright
22 : : * notice, this list of conditions and the following disclaimer in the
23 : : * documentation and/or other materials provided with the distribution.
24 : : *
25 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
26 : : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27 : : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 : : * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
29 : : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 : : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 : : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 : : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34 : : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 : : */
36 : :
37 : : #include "pkgvec.h"
38 : : #ifdef HAVE_CONFIG_H
39 : : #include "pkg_config.h"
40 : : #endif
41 : :
42 : : #include <assert.h>
43 : : #include <errno.h>
44 : : #include <regex.h>
45 : : #include <grp.h>
46 : : #ifdef HAVE_LIBUTIL_H
47 : : #include <libutil.h>
48 : : #endif
49 : : #include <stdlib.h>
50 : : #include <stdio.h>
51 : : #include <stdbool.h>
52 : : #include <string.h>
53 : : #include <unistd.h>
54 : : #include <signal.h>
55 : :
56 : : #include <sqlite3.h>
57 : :
58 : : #include "pkg.h"
59 : : #include "private/event.h"
60 : : #include "private/pkg.h"
61 : : #include "private/pkgdb.h"
62 : : #include "private/utils.h"
63 : :
64 : : const char *
65 : 1669 : pkgdb_get_pattern_query(const char *pattern, match_t match)
66 : : {
67 : 1669 : char *checkorigin = NULL;
68 : 1669 : char *checkflavor = NULL;
69 : 1669 : const char *comp = NULL;
70 : :
71 [ + + ]: 1669 : if (pattern != NULL) {
72 : 1131 : checkorigin = strchr(pattern, '/');
73 [ + + ]: 1131 : if (checkorigin != NULL)
74 : 1 : checkflavor = strchr(checkorigin, '@');
75 : 1131 : }
76 : :
77 [ + + - + : 1669 : switch (match) {
+ + ]
78 : : case MATCH_ALL:
79 : 538 : comp = "";
80 : 538 : break;
81 : : case MATCH_INTERNAL:
82 : 982 : comp = " WHERE p.name = ?1";
83 : 982 : break;
84 : : case MATCH_EXACT:
85 [ - + ]: 126 : if (pkgdb_case_sensitive()) {
86 [ # # ]: 0 : if (checkorigin == NULL)
87 : 0 : comp = " WHERE (p.name = ?1 OR p.name || '-' || version = ?1)";
88 [ # # ]: 0 : else if (checkflavor == NULL)
89 : 0 : comp = " WHERE (origin = ?1 OR categories.name || substr(origin, instr(origin, '/')) = ?1)";
90 : : else
91 : 0 : comp = "WHERE (categories.name || substr(origin, instr(origin, '/')) || '@' || flavor = ?1)";
92 : 0 : } else {
93 [ + + ]: 126 : if (checkorigin == NULL)
94 : 125 : comp = " WHERE (p.name = ?1 COLLATE NOCASE OR "
95 : : "p.name || '-' || version = ?1 COLLATE NOCASE)";
96 [ + - ]: 1 : else if (checkflavor == NULL)
97 : 1 : comp = " WHERE (origin = ?1 COLLATE NOCASE OR categories.name || substr(origin, instr(origin, '/')) = ?1 COLLATE NOCASE)";
98 : : else
99 : 0 : comp = "WHERE (categories.name || substr(origin, instr(origin, '/')) || '@' || flavor = ?1 COLLATE NOCASE)";
100 : : }
101 : 126 : break;
102 : : case MATCH_GLOB:
103 [ - + ]: 18 : if (pkgdb_case_sensitive()) {
104 [ # # ]: 0 : if (checkorigin == NULL)
105 : 0 : comp = " WHERE (p.name GLOB ?1 "
106 : : "OR p.name || '-' || version GLOB ?1)";
107 [ # # ]: 0 : else if (checkflavor == NULL)
108 : 0 : comp = " WHERE (origin GLOB ?1 OR categories.name || substr(origin, instr(origin, '/')) GLOB ?1)";
109 : : else
110 : 0 : comp = "WHERE (categories.name || substr(origin, instr(origin, '/')) || '@' || flavor GLOB ?1)";
111 : 0 : } else {
112 [ - + ]: 18 : if (checkorigin == NULL)
113 : 18 : comp = " WHERE (lower(p.name) GLOB lower(?1) "
114 : : "OR lower(p.name || '-' || version) GLOB lower(?1) )";
115 [ # # ]: 0 : else if (checkflavor == NULL)
116 : 0 : comp = " WHERE (lower(origin) GLOB lower(?1) OR lower(categories.name || substr(origin, instr(origin, '/'))) GLOB lower(?1))";
117 : : else
118 : 0 : comp = "WHERE (lower(categories.name || substr(origin, instr(origin, '/')) || '@' || flavor) GLOB lower(?1))";
119 : : }
120 : 18 : break;
121 : : case MATCH_REGEX:
122 [ - + ]: 5 : if (checkorigin == NULL)
123 : 5 : comp = " WHERE (p.name REGEXP ?1 "
124 : : "OR p.name || '-' || version REGEXP ?1)";
125 [ # # ]: 0 : else if (checkflavor == NULL)
126 : 0 : comp = " WHERE (origin REGEXP ?1 OR categories.name || substr(origin, instr(origin, '/')) REGEXP ?1)";
127 : : else
128 : 0 : comp = "WHERE (categories.name || substr(origin, instr(origin, '/')) || '@' || flavor REGEXP ?1)";
129 : 5 : break;
130 : : }
131 : :
132 : 1669 : return (comp);
133 : : }
134 : :
135 : : struct pkgdb_it *
136 : 1082 : pkgdb_query_cond(struct pkgdb *db, const char *cond, const char *pattern, match_t match)
137 : : {
138 : : char sql[BUFSIZ];
139 : : sqlite3_stmt *stmt;
140 : 1082 : const char *comp = NULL;
141 : :
142 [ + - ]: 1082 : assert(db != NULL);
143 : :
144 [ + + + - : 1082 : if (match != MATCH_ALL && (pattern == NULL || pattern[0] == '\0'))
- + ]
145 : 0 : return (NULL);
146 : :
147 : 1082 : comp = pkgdb_get_pattern_query(pattern, match);
148 : :
149 [ + + ]: 1082 : if (cond) {
150 : 494 : sqlite3_snprintf(sizeof(sql), sql,
151 : : "WITH flavors AS "
152 : : " (SELECT package_id, value.annotation AS flavor FROM pkg_annotation "
153 : : " LEFT JOIN annotation tag ON pkg_annotation.tag_id = tag.annotation_id "
154 : : " LEFT JOIN annotation value ON pkg_annotation.value_id = value.annotation_id "
155 : : " WHERE tag.annotation = 'flavor') "
156 : : "SELECT DISTINCT(p.id), origin, p.name, p.name as uniqueid, "
157 : : " version, comment, desc, "
158 : : " message, arch, maintainer, www, "
159 : : " prefix, flatsize, licenselogic, automatic, "
160 : : " locked, time, manifestdigest, vital "
161 : : " FROM packages AS p "
162 : : " LEFT JOIN pkg_categories ON p.id = pkg_categories.package_id "
163 : : " LEFT JOIN categories ON categories.id = pkg_categories.category_id "
164 : : " LEFT JOIN flavors ON flavors.package_id = p.id "
165 : : " %s %s (%s) ORDER BY p.name;",
166 : 247 : comp, pattern == NULL ? "WHERE" : "AND", cond + 7);
167 [ + + ]: 1082 : } else if (match == MATCH_INTERNAL) {
168 : 1398 : sqlite3_snprintf(sizeof(sql), sql,
169 : : "SELECT DISTINCT(p.id), origin, p.name, p.name as uniqueid, "
170 : : "version, comment, desc, "
171 : : "message, arch, maintainer, www, "
172 : : "prefix, flatsize, licenselogic, automatic, "
173 : : "locked, time, manifestdigest, vital "
174 : : "FROM packages AS p "
175 : : "%s"
176 : 699 : " ORDER BY p.name", comp);
177 : 699 : } else {
178 : 272 : sqlite3_snprintf(sizeof(sql), sql,
179 : : "WITH flavors AS "
180 : : " (SELECT package_id, value.annotation AS flavor FROM pkg_annotation "
181 : : " LEFT JOIN annotation tag ON pkg_annotation.tag_id = tag.annotation_id "
182 : : " LEFT JOIN annotation value ON pkg_annotation.value_id = value.annotation_id "
183 : : " WHERE tag.annotation = 'flavor') "
184 : : "SELECT DISTINCT(p.id), origin, p.name, p.name as uniqueid, "
185 : : "version, comment, desc, "
186 : : "message, arch, maintainer, www, "
187 : : "prefix, flatsize, licenselogic, automatic, "
188 : : "locked, time, manifestdigest, vital "
189 : : "FROM packages AS p "
190 : : "LEFT JOIN pkg_categories ON p.id = pkg_categories.package_id "
191 : : "LEFT JOIN categories ON categories.id = pkg_categories.category_id "
192 : : "LEFT JOIN flavors ON flavors.package_id = p.id "
193 : : "%s"
194 : 136 : " ORDER BY p.name", comp);
195 : : }
196 : :
197 [ - + ]: 1082 : if (sqlite3_prepare_v2(db->sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
198 : 0 : ERROR_SQLITE(db->sqlite, sql);
199 : 0 : return (NULL);
200 : : }
201 : :
202 [ + + ]: 1082 : if (match != MATCH_ALL)
203 : 786 : sqlite3_bind_text(stmt, 1, pattern, -1, SQLITE_TRANSIENT);
204 : 1082 : pkgdb_debug(4, stmt);
205 : :
206 : 1082 : return (pkgdb_it_new_sqlite(db, stmt, PKG_INSTALLED, PKGDB_IT_FLAG_ONCE));
207 : 1082 : }
208 : :
209 : : struct pkgdb_it *
210 : 819 : pkgdb_query(struct pkgdb *db, const char *pattern, match_t match)
211 : : {
212 : 819 : return pkgdb_query_cond(db, NULL, pattern, match);
213 : : }
214 : :
215 : : bool
216 : 226 : pkgdb_file_exists(struct pkgdb *db, const char *path)
217 : : {
218 : : sqlite3_stmt *stmt;
219 : : char sql[BUFSIZ];
220 : 226 : bool ret = false;
221 : :
222 [ + - ]: 226 : assert(db != NULL);
223 : :
224 [ + - ]: 226 : if (path == NULL)
225 : 0 : return (false);
226 : :
227 : 226 : sqlite3_snprintf(sizeof(sql), sql,
228 : : "select path from files where path = ?1;");
229 : :
230 [ + - ]: 226 : if (sqlite3_prepare_v2(db->sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
231 : 0 : ERROR_SQLITE(db->sqlite, sql);
232 : 0 : }
233 : :
234 : 226 : sqlite3_bind_text(stmt, 1, path, -1, SQLITE_TRANSIENT);
235 : 226 : pkgdb_debug(4, stmt);
236 : :
237 [ + + ]: 226 : if (sqlite3_step(stmt) != SQLITE_DONE) {
238 : 16 : ret = true;
239 : 16 : }
240 : :
241 : 226 : sqlite3_finalize(stmt);
242 : 226 : return (ret);
243 : 226 : }
244 : :
245 : : struct pkgdb_it *
246 : 5 : pkgdb_query_which(struct pkgdb *db, const char *path, bool glob)
247 : : {
248 : : sqlite3_stmt *stmt;
249 : : char sql[BUFSIZ];
250 : :
251 [ + - ]: 5 : assert(db != NULL);
252 : :
253 [ + - ]: 5 : if (path == NULL)
254 : 0 : return (NULL);
255 : :
256 : 10 : sqlite3_snprintf(sizeof(sql), sql,
257 : : "SELECT p.id, p.origin, p.name, p.name as uniqueid, "
258 : : "p.version, p.comment, p.desc, "
259 : : "p.message, p.arch, p.maintainer, p.www, "
260 : : "p.prefix, p.flatsize, p.time "
261 : : "FROM packages AS p "
262 : : "LEFT JOIN files AS f ON p.id = f.package_id "
263 : 5 : "WHERE f.path %s ?1 GROUP BY p.id;", glob ? "GLOB" : "=");
264 : :
265 [ - + ]: 5 : if (sqlite3_prepare_v2(db->sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
266 : 0 : ERROR_SQLITE(db->sqlite, sql);
267 : 0 : return (NULL);
268 : : }
269 : :
270 : 5 : sqlite3_bind_text(stmt, 1, path, -1, SQLITE_TRANSIENT);
271 : 5 : pkgdb_debug(4, stmt);
272 : :
273 : 5 : return (pkgdb_it_new_sqlite(db, stmt, PKG_INSTALLED, PKGDB_IT_FLAG_ONCE));
274 : 5 : }
275 : :
276 : : struct pkgdb_it *
277 : 0 : pkgdb_query_shlib_require(struct pkgdb *db, const char *shlib)
278 : : {
279 : : sqlite3_stmt *stmt;
280 : 0 : const char sql[] = ""
281 : : "SELECT p.id, p.origin, p.name, p.name as uniqueid, "
282 : : "p.version, p.comment, p.desc, "
283 : : "p.message, p.arch, p.maintainer, p.www, "
284 : : "p.prefix, p.flatsize, p.time "
285 : : "FROM packages AS p, pkg_shlibs_required AS ps, shlibs AS s "
286 : : "WHERE p.id = ps.package_id "
287 : : "AND ps.shlib_id = s.id "
288 : : "AND s.name = ?1;";
289 : :
290 [ # # ]: 0 : assert(db != NULL);
291 : :
292 [ # # ]: 0 : if (sqlite3_prepare_v2(db->sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
293 : 0 : ERROR_SQLITE(db->sqlite, sql);
294 : 0 : return (NULL);
295 : : }
296 : :
297 : 0 : sqlite3_bind_text(stmt, 1, shlib, -1, SQLITE_TRANSIENT);
298 : 0 : pkgdb_debug(4, stmt);
299 : :
300 : 0 : return (pkgdb_it_new_sqlite(db, stmt, PKG_INSTALLED, PKGDB_IT_FLAG_ONCE));
301 : 0 : }
302 : :
303 : : struct pkgdb_it *
304 : 7 : pkgdb_query_shlib_provide(struct pkgdb *db, const char *shlib)
305 : : {
306 : : sqlite3_stmt *stmt;
307 : 7 : const char sql[] = ""
308 : : "SELECT p.id, p.origin, p.name, p.name as uniqueid, "
309 : : "p.version, p.comment, p.desc, "
310 : : "p.message, p.arch, p.maintainer, p.www, "
311 : : "p.prefix, p.flatsize, p.manifestdigest, p.time "
312 : : "FROM packages AS p, pkg_shlibs_provided AS ps, shlibs AS s "
313 : : "WHERE p.id = ps.package_id "
314 : : "AND ps.shlib_id = s.id "
315 : : "AND s.name = ?1;";
316 : :
317 [ + - ]: 7 : assert(db != NULL);
318 : :
319 [ - + ]: 7 : if (sqlite3_prepare_v2(db->sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
320 : 0 : ERROR_SQLITE(db->sqlite, sql);
321 : 0 : return (NULL);
322 : : }
323 : :
324 : 7 : sqlite3_bind_text(stmt, 1, shlib, -1, SQLITE_TRANSIENT);
325 : 7 : pkgdb_debug(4, stmt);
326 : :
327 : 7 : return (pkgdb_it_new_sqlite(db, stmt, PKG_INSTALLED, PKGDB_IT_FLAG_ONCE));
328 : 7 : }
329 : :
330 : : struct pkgdb_it *
331 : 2 : pkgdb_query_require(struct pkgdb *db, const char *req)
332 : : {
333 : : sqlite3_stmt *stmt;
334 : 2 : const char sql[] = ""
335 : : "SELECT p.id, p.origin, p.name, p.name as uniqueid, "
336 : : "p.version, p.comment, p.desc, "
337 : : "p.message, p.arch, p.maintainer, p.www, "
338 : : "p.prefix, p.flatsize, p.time "
339 : : "FROM packages AS p, pkg_requires AS ps, requires AS s "
340 : : "WHERE p.id = ps.package_id "
341 : : "AND ps.require_id = s.id "
342 : : "AND s.require = ?1;";
343 : :
344 [ + - ]: 2 : assert(db != NULL);
345 : :
346 [ - + ]: 2 : if (sqlite3_prepare_v2(db->sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
347 : 0 : ERROR_SQLITE(db->sqlite, sql);
348 : 0 : return (NULL);
349 : : }
350 : :
351 : 2 : sqlite3_bind_text(stmt, 1, req, -1, SQLITE_TRANSIENT);
352 : 2 : pkgdb_debug(4, stmt);
353 : :
354 : 2 : return (pkgdb_it_new_sqlite(db, stmt, PKG_INSTALLED, PKGDB_IT_FLAG_ONCE));
355 : 2 : }
356 : :
357 : : struct pkgdb_it *
358 : 9 : pkgdb_query_provide(struct pkgdb *db, const char *req)
359 : : {
360 : : sqlite3_stmt *stmt;
361 : 9 : const char sql[] = ""
362 : : "SELECT p.id, p.origin, p.name, p.name as uniqueid, "
363 : : "p.version, p.comment, p.desc, "
364 : : "p.message, p.arch, p.maintainer, p.www, "
365 : : "p.prefix, p.flatsize, p.time "
366 : : "FROM packages AS p, pkg_provides AS ps, provides AS s "
367 : : "WHERE p.id = ps.package_id "
368 : : "AND ps.provide_id = s.id "
369 : : "AND s.provide = ?1;";
370 : :
371 [ + - ]: 9 : assert(db != NULL);
372 : :
373 [ - + ]: 9 : if (sqlite3_prepare_v2(db->sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
374 : 0 : ERROR_SQLITE(db->sqlite, sql);
375 : 0 : return (NULL);
376 : : }
377 : :
378 : 9 : sqlite3_bind_text(stmt, 1, req, -1, SQLITE_TRANSIENT);
379 : 9 : pkgdb_debug(4, stmt);
380 : :
381 : 9 : return (pkgdb_it_new_sqlite(db, stmt, PKG_INSTALLED, PKGDB_IT_FLAG_ONCE));
382 : 9 : }
383 : :
384 : : static bool
385 : 372 : consider_this_repo(c_charv_t *repos, const char *name)
386 : : {
387 : : /* All repositories */
388 [ + + ]: 372 : if (repos == NULL)
389 : 332 : return (true);
390 : :
391 [ + + ]: 40 : if (repos->len == 0)
392 : 23 : return (true);
393 : :
394 : 17 : return (c_charv_contains(repos, name, true));
395 : 372 : }
396 : :
397 : : struct pkgdb_it *
398 : 0 : pkgdb_repo_query_cond(struct pkgdb *db, const char *cond, const char *pattern, match_t match,
399 : : const char *repo)
400 : : {
401 : : c_charv_t r;
402 : : struct pkgdb_it *ret;
403 : :
404 : 0 : pkgvec_init(&r);
405 : :
406 [ # # ]: 0 : if (repo != NULL)
407 [ # # # # : 0 : pkgvec_push(&r, repo);
# # ]
408 : :
409 : 0 : ret = pkgdb_repo_query_cond2(db, cond, pattern, match, &r);
410 : 0 : pkgvec_free(&r);
411 : :
412 : 0 : return (ret);
413 : : }
414 : :
415 : : struct pkgdb_it *
416 : 297 : pkgdb_repo_query_cond2(struct pkgdb *db, const char *cond, const char *pattern, match_t match,
417 : : c_charv_t *repos)
418 : : {
419 : : struct pkgdb_it *it;
420 : : struct pkg_repo_it *rit;
421 : :
422 : 297 : it = pkgdb_it_new_repo(db);
423 [ + - ]: 297 : if (it == NULL)
424 : 0 : return (NULL);
425 : :
426 [ + + + + : 647 : tll_foreach(db->repos, cur) {
+ + ]
427 [ - + ]: 350 : if (consider_this_repo(repos, cur->item->name)) {
428 [ + + + - ]: 350 : if (pattern != NULL && *pattern == '@')
429 : 0 : rit = cur->item->ops->groupquery(cur->item, pattern + 1, match);
430 : : else
431 : 350 : rit = cur->item->ops->query(cur->item, cond, pattern, match);
432 [ - + ]: 350 : if (rit != NULL)
433 : 350 : pkgdb_it_repo_attach(it, rit);
434 : 350 : }
435 : 350 : }
436 : :
437 : 297 : return (it);
438 : 297 : }
439 : :
440 : 0 : struct pkgdb_it *pkgdb_repo_query(struct pkgdb *db, const char *pattern,
441 : : match_t match, const char *repo)
442 : : {
443 : 0 : return pkgdb_repo_query_cond(db, NULL, pattern, match, repo);
444 : : }
445 : :
446 : 285 : struct pkgdb_it *pkgdb_repo_query2(struct pkgdb *db, const char *pattern,
447 : : match_t match, c_charv_t *repos)
448 : : {
449 : 285 : return pkgdb_repo_query_cond2(db, NULL, pattern, match, repos);
450 : : }
451 : :
452 : : struct pkgdb_it *
453 : 0 : pkgdb_repo_shlib_require(struct pkgdb *db, const char *require, c_charv_t *repos)
454 : : {
455 : : struct pkgdb_it *it;
456 : : struct pkg_repo_it *rit;
457 : :
458 : 0 : it = pkgdb_it_new_repo(db);
459 [ # # ]: 0 : if (it == NULL)
460 : 0 : return (NULL);
461 : :
462 [ # # # # : 0 : tll_foreach(db->repos, cur) {
# # ]
463 [ # # ]: 0 : if (consider_this_repo(repos, cur->item->name)) {
464 [ # # ]: 0 : if (cur->item->ops->shlib_required != NULL) {
465 : 0 : rit = cur->item->ops->shlib_required(cur->item, require);
466 [ # # ]: 0 : if (rit != NULL)
467 : 0 : pkgdb_it_repo_attach(it, rit);
468 : 0 : }
469 : 0 : }
470 : 0 : }
471 : :
472 : 0 : return (it);
473 : 0 : }
474 : :
475 : : struct pkgdb_it *
476 : 7 : pkgdb_repo_shlib_provide(struct pkgdb *db, const char *require, c_charv_t *repos)
477 : : {
478 : : struct pkgdb_it *it;
479 : : struct pkg_repo_it *rit;
480 : :
481 : 7 : it = pkgdb_it_new_repo(db);
482 [ + - ]: 7 : if (it == NULL)
483 : 0 : return (NULL);
484 : :
485 [ + + + + : 12 : tll_foreach(db->repos, cur) {
- + ]
486 [ - + ]: 5 : if (consider_this_repo(repos, cur->item->name)) {
487 [ - + ]: 5 : if (cur->item->ops->shlib_required != NULL) {
488 : 5 : rit = cur->item->ops->shlib_provided(cur->item, require);
489 [ - + ]: 5 : if (rit != NULL)
490 : 5 : pkgdb_it_repo_attach(it, rit);
491 : 5 : }
492 : 5 : }
493 : 5 : }
494 : :
495 : 7 : return (it);
496 : 7 : }
497 : :
498 : : struct pkgdb_it *
499 : 0 : pkgdb_repo_require(struct pkgdb *db, const char *require, c_charv_t *repo)
500 : : {
501 : : struct pkgdb_it *it;
502 : : struct pkg_repo_it *rit;
503 : :
504 : 0 : it = pkgdb_it_new_repo(db);
505 [ # # ]: 0 : if (it == NULL)
506 : 0 : return (NULL);
507 : :
508 [ # # # # : 0 : tll_foreach(db->repos, cur) {
# # ]
509 [ # # ]: 0 : if (consider_this_repo(repo, cur->item->name)) {
510 [ # # ]: 0 : if (cur->item->ops->required != NULL) {
511 : 0 : rit = cur->item->ops->required(cur->item, require);
512 [ # # ]: 0 : if (rit != NULL)
513 : 0 : pkgdb_it_repo_attach(it, rit);
514 : 0 : }
515 : 0 : }
516 : 0 : }
517 : :
518 : 0 : return (it);
519 : 0 : }
520 : :
521 : : struct pkgdb_it *
522 : 8 : pkgdb_repo_provide(struct pkgdb *db, const char *require, c_charv_t *repo)
523 : : {
524 : : struct pkgdb_it *it;
525 : : struct pkg_repo_it *rit;
526 : :
527 : 8 : it = pkgdb_it_new_repo(db);
528 [ + - ]: 8 : if (it == NULL)
529 : 0 : return (NULL);
530 : :
531 [ + - + + : 16 : tll_foreach(db->repos, cur) {
- + ]
532 [ - + ]: 8 : if (consider_this_repo(repo, cur->item->name)) {
533 [ - + ]: 8 : if (cur->item->ops->required != NULL) {
534 : 8 : rit = cur->item->ops->provided(cur->item, require);
535 [ - + ]: 8 : if (rit != NULL)
536 : 8 : pkgdb_it_repo_attach(it, rit);
537 : 8 : }
538 : 8 : }
539 : 8 : }
540 : :
541 : 8 : return (it);
542 : 8 : }
543 : :
544 : : struct pkgdb_it *
545 : 1 : pkgdb_repo_search(struct pkgdb *db, const char *pattern, match_t match,
546 : : pkgdb_field field, pkgdb_field sort, const char *repo)
547 : : {
548 : : c_charv_t r;
549 : : struct pkgdb_it *ret;
550 : :
551 : 1 : pkgvec_init(&r);
552 [ + - ]: 1 : if (repo != NULL)
553 [ # # # # : 0 : pkgvec_push(&r, repo);
# # ]
554 : :
555 : 1 : ret = pkgdb_repo_search2(db, pattern, match, field, sort, &r);
556 : 1 : pkgvec_free(&r);
557 : :
558 : 1 : return (ret);
559 : : }
560 : :
561 : : struct pkgdb_it *
562 : 9 : pkgdb_repo_search2(struct pkgdb *db, const char *pattern, match_t match,
563 : : pkgdb_field field, pkgdb_field sort, c_charv_t *repos)
564 : : {
565 : : struct pkgdb_it *it;
566 : : struct pkg_repo_it *rit;
567 : :
568 : 9 : it = pkgdb_it_new_repo(db);
569 [ + - ]: 9 : if (it == NULL)
570 : 0 : return (NULL);
571 : :
572 [ + - + + : 18 : tll_foreach(db->repos, cur) {
- + ]
573 [ - + ]: 9 : if (consider_this_repo(repos, cur->item->name)) {
574 [ - + ]: 9 : if (cur->item->ops->search != NULL) {
575 : 18 : rit = cur->item->ops->search(cur->item, pattern, match,
576 : 9 : field, sort);
577 [ - + ]: 9 : if (rit != NULL)
578 : 9 : pkgdb_it_repo_attach(it, rit);
579 : 9 : }
580 [ - + ]: 9 : if (cur->item->ops->groupsearch != NULL) {
581 : 9 : rit = cur->item->ops->groupsearch(cur->item, pattern, match, field);
582 [ + - ]: 9 : if (rit != NULL)
583 : 0 : pkgdb_it_repo_attach(it, rit);
584 : 9 : }
585 : 9 : }
586 : 9 : }
587 : :
588 : 9 : return (it);
589 : 9 : }
590 : :
591 : : struct pkgdb_it *
592 : 0 : pkgdb_all_search(struct pkgdb *db, const char *pattern, match_t match,
593 : : pkgdb_field field, pkgdb_field sort, const char *repo)
594 : : {
595 : : c_charv_t r;
596 : : struct pkgdb_it *ret;
597 : :
598 : 0 : pkgvec_init(&r);
599 : :
600 [ # # ]: 0 : if (repo != NULL)
601 [ # # # # : 0 : pkgvec_push(&r, repo);
# # ]
602 : :
603 : 0 : ret = pkgdb_all_search2(db, pattern, match, field, sort, &r);
604 : :
605 : 0 : pkgvec_free(&r);
606 : :
607 : 0 : return (ret);
608 : : }
609 : :
610 : : struct pkgdb_it *
611 : 0 : pkgdb_all_search2(struct pkgdb *db, const char *pattern, match_t match,
612 : : pkgdb_field field, pkgdb_field sort, c_charv_t *repos)
613 : : {
614 : : struct pkgdb_it *it;
615 : : struct pkg_repo_it *rit;
616 : :
617 : :
618 : 0 : it = pkgdb_query(db, pattern, match);
619 : :
620 [ # # # # : 0 : tll_foreach(db->repos, cur) {
# # ]
621 [ # # ]: 0 : if (consider_this_repo(repos, cur->item->name)) {
622 [ # # ]: 0 : if (cur->item->ops->search != NULL) {
623 : 0 : rit = cur->item->ops->search(cur->item, pattern, match,
624 : 0 : field, sort);
625 [ # # ]: 0 : if (rit != NULL)
626 : 0 : pkgdb_it_repo_attach(it, rit);
627 : 0 : }
628 : 0 : }
629 : 0 : }
630 : :
631 : 0 : return (it);
632 : : }
|