Branch data Line data Source code
1 : : /*-
2 : : * Copyright (c) 2011-2012 Baptiste Daroussin <bapt@FreeBSD.org>
3 : : * Copyright (c) 2011-2012 Marin Atanasov Nikolov <dnaeon@gmail.com>
4 : : * Copyright (c) 2014 Matthew Seaman <matthew@FreeBSD.org>
5 : : * Copyright (c) 2016 Vsevolod Stakhov <vsevolod@FreeBSD.org>
6 : : * All rights reserved.
7 : : *
8 : : * Redistribution and use in source and binary forms, with or without
9 : : * modification, are permitted provided that the following conditions
10 : : * are met:
11 : : * 1. Redistributions of source code must retain the above copyright
12 : : * notice, this list of conditions and the following disclaimer
13 : : * in this position and unchanged.
14 : : * 2. Redistributions in binary form must reproduce the above copyright
15 : : * notice, this list of conditions and the following disclaimer in the
16 : : * documentation and/or other materials provided with the distribution.
17 : : *
18 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
19 : : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 : : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 : : * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
22 : : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 : : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 : : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 : : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 : : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 : : */
29 : :
30 : : #include <sys/param.h>
31 : : #include <sys/queue.h>
32 : :
33 : : #include <err.h>
34 : : #include <assert.h>
35 : : #include <getopt.h>
36 : : #include <stdbool.h>
37 : : #include <stdio.h>
38 : : #include <stdlib.h>
39 : : #include <string.h>
40 : : #include <unistd.h>
41 : : #include <utlist.h>
42 : :
43 : : #include <pkg.h>
44 : :
45 : : #include "pkgcli.h"
46 : :
47 : : struct deps_entry {
48 : : char *name;
49 : : struct deps_entry *next;
50 : : struct deps_entry *prev;
51 : : };
52 : :
53 : : static int check_deps(struct pkgdb *db, struct pkg *pkg, struct deps_entry **dh,
54 : : bool noinstall, xstring *out);
55 : : static void add_missing_dep(struct pkg_dep *d, struct deps_entry **dh, int *nbpkgs);
56 : : static void deps_free(struct deps_entry *dh);
57 : : static int fix_deps(struct pkgdb *db, struct deps_entry *dh, int nbpkgs);
58 : : static void check_summary(struct pkgdb *db, struct deps_entry *dh);
59 : :
60 : : static int
61 : 0 : check_deps(struct pkgdb *db, struct pkg *p, struct deps_entry **dh, bool noinstall, xstring *out)
62 : : {
63 : 0 : struct pkg_dep *dep = NULL;
64 : : struct pkgdb_it *it;
65 : 0 : char *buf = NULL;
66 : 0 : int nbpkgs = 0;
67 : :
68 [ # # ]: 0 : assert(db != NULL);
69 [ # # ]: 0 : assert(p != NULL);
70 : :
71 [ # # ]: 0 : while (pkg_deps(p, &dep) == EPKG_OK) {
72 : : /* do we have a missing dependency? */
73 [ # # ]: 0 : if (pkg_is_installed(db, pkg_dep_name(dep)) != EPKG_OK) {
74 [ # # ]: 0 : if (quiet)
75 : 0 : pkg_fprintf(out->fp, "%n\t%sn\n", p, dep);
76 : : else
77 : 0 : pkg_fprintf(out->fp, "%n has a missing dependency: %dn\n",
78 : 0 : p, dep);
79 [ # # ]: 0 : if (!noinstall)
80 : 0 : add_missing_dep(dep, dh, &nbpkgs);
81 : 0 : }
82 : : }
83 : :
84 : : /* checking libraries required */
85 : 0 : buf = NULL;
86 [ # # ]: 0 : while (pkg_shlibs_required(p, &buf) == EPKG_OK) {
87 : 0 : it = pkgdb_query_shlib_provide(db, buf);
88 [ # # # # ]: 0 : if (it != NULL && pkgdb_it_count(it) > 0) {
89 : 0 : pkgdb_it_free(it);
90 : 0 : continue;
91 : : }
92 : 0 : pkgdb_it_free(it);
93 [ # # ]: 0 : if (quiet)
94 : 0 : pkg_fprintf(out->fp, "%n\t%S\n", p, buf);
95 : : else
96 : 0 : pkg_fprintf(out->fp, "%n is missing a required shared library: %S\n",
97 : 0 : p, buf);
98 : : }
99 : :
100 : : /* checking requires */
101 : 0 : buf = NULL;
102 [ # # ]: 0 : while (pkg_requires(p, &buf) == EPKG_OK) {
103 : 0 : it = pkgdb_query_provide(db, buf);
104 [ # # # # ]: 0 : if (it != NULL && pkgdb_it_count(it) > 0) {
105 : 0 : pkgdb_it_free(it);
106 : 0 : continue;
107 : : }
108 : 0 : pkgdb_it_free(it);
109 [ # # ]: 0 : if (quiet)
110 : 0 : pkg_fprintf(out->fp, "%n\tS\n", p, buf);
111 : : else
112 : 0 : pkg_fprintf(out->fp, "%n has a missing requirement: %S\n",
113 : 0 : p, buf);
114 : : }
115 : :
116 : 0 : return (nbpkgs);
117 : : }
118 : :
119 : : static void
120 : 0 : add_missing_dep(struct pkg_dep *d, struct deps_entry **dh, int *nbpkgs)
121 : : {
122 : 0 : struct deps_entry *e = NULL;
123 : 0 : const char *name = NULL;
124 : :
125 [ # # ]: 0 : assert(d != NULL);
126 : :
127 : : /* do not add duplicate entries in the queue */
128 : 0 : name = pkg_dep_name(d);
129 : :
130 [ # # ]: 0 : DL_FOREACH(*dh, e) {
131 [ # # ]: 0 : if (strcmp(e->name, name) == 0)
132 : 0 : return;
133 : 0 : }
134 : :
135 [ # # ]: 0 : if ((e = calloc(1, sizeof(struct deps_entry))) == NULL)
136 : 0 : err(1, "calloc(deps_entry)");
137 : :
138 : 0 : e->name = strdup(name);
139 : :
140 : 0 : (*nbpkgs)++;
141 : :
142 [ # # ]: 0 : DL_APPEND(*dh, e);
143 : 0 : }
144 : :
145 : : static void
146 : 0 : deps_free(struct deps_entry *dh)
147 : : {
148 : : struct deps_entry *e, *etmp;
149 : :
150 [ # # # # ]: 0 : DL_FOREACH_SAFE(dh, e, etmp) {
151 [ # # # # : 0 : DL_DELETE(dh, e);
# # # # ]
152 : 0 : free(e->name);
153 : 0 : free(e);
154 : 0 : }
155 : 0 : }
156 : :
157 : : static int
158 : 0 : fix_deps(struct pkgdb *db, struct deps_entry *dh, int nbpkgs)
159 : : {
160 : 0 : struct pkg_jobs *jobs = NULL;
161 : 0 : struct deps_entry *e = NULL;
162 : 0 : char **pkgs = NULL;
163 : 0 : int i = 0;
164 : : bool rc;
165 : 0 : pkg_flags f = PKG_FLAG_AUTOMATIC;
166 : :
167 [ # # ]: 0 : assert(db != NULL);
168 [ # # ]: 0 : assert(nbpkgs > 0);
169 : :
170 [ # # ]: 0 : if ((pkgs = calloc(nbpkgs, sizeof (char *))) == NULL)
171 : 0 : err(1, "calloc()");
172 : :
173 [ # # ]: 0 : DL_FOREACH(dh, e)
174 : 0 : pkgs[i++] = e->name;
175 : :
176 [ # # ]: 0 : if (pkgdb_open(&db, PKGDB_REMOTE) != EPKG_OK) {
177 : 0 : free(pkgs);
178 : 0 : return (EPKG_ENODB);
179 : : }
180 : :
181 [ # # ]: 0 : if (pkg_jobs_new(&jobs, PKG_JOBS_INSTALL, db) != EPKG_OK) {
182 : 0 : goto cleanup;
183 : : }
184 : :
185 : 0 : pkg_jobs_set_flags(jobs, f);
186 : :
187 [ # # ]: 0 : if (pkg_jobs_add(jobs, MATCH_EXACT, pkgs, nbpkgs) == EPKG_FATAL) {
188 : 0 : goto cleanup;
189 : : }
190 : :
191 [ # # ]: 0 : if (pkg_jobs_solve(jobs) != EPKG_OK) {
192 : 0 : goto cleanup;
193 : : }
194 : :
195 [ # # ]: 0 : if (pkg_jobs_count(jobs) == 0) {
196 : 0 : printf("\nUnable to find packages for installation.\n\n");
197 : 0 : goto cleanup;
198 : : }
199 : :
200 : : /* print a summary before applying the jobs */
201 : 0 : print_jobs_summary(jobs,
202 : : "The following packages will be installed:\n\n");
203 : :
204 : 0 : rc = query_yesno(false, "\n>>> Try to fix the missing dependencies? ");
205 : :
206 [ # # ]: 0 : if (rc) {
207 [ # # ]: 0 : if (pkgdb_access(PKGDB_MODE_WRITE, PKGDB_DB_LOCAL) ==
208 : : EPKG_ENOACCESS) {
209 : 0 : warnx("Insufficient privileges to modify the package "
210 : : "database");
211 : :
212 : 0 : goto cleanup;
213 : : }
214 : :
215 : 0 : pkg_jobs_apply(jobs);
216 : 0 : }
217 : :
218 : : cleanup:
219 : 0 : free(pkgs);
220 [ # # ]: 0 : if (jobs != NULL)
221 : 0 : pkg_jobs_free(jobs);
222 : :
223 : 0 : return (EPKG_OK);
224 : 0 : }
225 : :
226 : : static void
227 : 0 : check_summary(struct pkgdb *db, struct deps_entry *dh)
228 : : {
229 : 0 : struct deps_entry *e = NULL;
230 : 0 : struct pkg *pkg = NULL;
231 : 0 : struct pkgdb_it *it = NULL;
232 : 0 : bool fixed = true;
233 : :
234 [ # # ]: 0 : assert(db != NULL);
235 : :
236 : 0 : printf(">>> Summary of actions performed:\n\n");
237 : :
238 [ # # ]: 0 : DL_FOREACH(dh, e) {
239 [ # # ]: 0 : if ((it = pkgdb_query(db, e->name, MATCH_EXACT)) == NULL)
240 : 0 : return;
241 : :
242 [ # # ]: 0 : if (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) != EPKG_OK) {
243 : 0 : fixed = false;
244 : 0 : printf("%s dependency failed to be fixed\n", e->name);
245 : 0 : } else
246 : 0 : printf("%s dependency has been fixed\n", e->name);
247 : :
248 : 0 : pkgdb_it_free(it);
249 : 0 : }
250 : :
251 [ # # ]: 0 : if (fixed) {
252 : 0 : printf("\n>>> Missing dependencies were fixed successfully.\n");
253 : 0 : } else {
254 : 0 : printf("\n>>> There are still missing dependencies.\n");
255 : 0 : printf(">>> Try fixing them manually.\n");
256 : 0 : printf("\n>>> Also make sure to check 'pkg updating' for known issues.\n");
257 : : }
258 : :
259 : 0 : pkg_free(pkg);
260 : 0 : }
261 : :
262 : : void
263 : 0 : usage_check(void)
264 : : {
265 : 0 : fprintf(stderr,
266 : : "Usage: pkg check -B|-d|-s|-r [-qvy] -a\n");
267 : 0 : fprintf(stderr,
268 : : " pkg check -B|-d|-s|-r [-qvy] [-Cgix] <pattern>\n\n");
269 : 0 : fprintf(stderr, "For more information see 'pkg help check'.\n");
270 : 0 : }
271 : :
272 : : int
273 : 0 : exec_check(int argc, char **argv)
274 : : {
275 : 0 : struct pkg *pkg = NULL;
276 : 0 : struct pkgdb_it *it = NULL;
277 : 0 : struct pkgdb *db = NULL;
278 : 0 : xstring *msg = NULL;
279 : 0 : match_t match = MATCH_EXACT;
280 : 0 : int flags = PKG_LOAD_BASIC;
281 : 0 : int ret, rc = EXIT_SUCCESS;
282 : : int ch;
283 : 0 : bool dcheck = false;
284 : 0 : bool checksums = false;
285 : 0 : bool recompute = false;
286 : 0 : bool reanalyse_shlibs = false;
287 : 0 : bool noinstall = false;
288 : 0 : int nbpkgs = 0;
289 : 0 : int i, processed, total = 0;
290 : 0 : int verbose = 0;
291 : :
292 : 0 : struct option longopts[] = {
293 : : { "all", no_argument, NULL, 'a' },
294 : : { "shlibs", no_argument, NULL, 'B' },
295 : : { "case-sensitive", no_argument, NULL, 'C' },
296 : : { "dependencies", no_argument, NULL, 'd' },
297 : : { "glob", no_argument, NULL, 'g' },
298 : : { "case-insensitive", no_argument, NULL, 'i' },
299 : : { "dry-run", no_argument, NULL, 'n' },
300 : : { "recompute", no_argument, NULL, 'r' },
301 : : { "checksums", no_argument, NULL, 's' },
302 : : { "verbose", no_argument, NULL, 'v' },
303 : : { "quiet", no_argument, NULL, 'q' },
304 : : { "regex", no_argument, NULL, 'x' },
305 : : { "yes", no_argument, NULL, 'y' },
306 : : { NULL, 0, NULL, 0 },
307 : : };
308 : :
309 : 0 : struct deps_entry *dh = NULL;
310 : :
311 : 0 : processed = 0;
312 : :
313 [ # # ]: 0 : while ((ch = getopt_long(argc, argv, "+aBCdginqrsvxy", longopts, NULL)) != -1) {
314 [ # # # # : 0 : switch (ch) {
# # # # #
# # # #
# ]
315 : : case 'a':
316 : 0 : match = MATCH_ALL;
317 : 0 : break;
318 : : case 'B':
319 : 0 : reanalyse_shlibs = true;
320 : 0 : flags |= PKG_LOAD_FILES;
321 : 0 : break;
322 : : case 'C':
323 : 0 : pkgdb_set_case_sensitivity(true);
324 : 0 : break;
325 : : case 'd':
326 : 0 : dcheck = true;
327 : 0 : flags |= PKG_LOAD_DEPS|PKG_LOAD_REQUIRES|PKG_LOAD_SHLIBS_REQUIRED;
328 : 0 : break;
329 : : case 'g':
330 : 0 : match = MATCH_GLOB;
331 : 0 : break;
332 : : case 'i':
333 : 0 : pkgdb_set_case_sensitivity(false);
334 : 0 : break;
335 : : case 'n':
336 : 0 : noinstall = true;
337 : 0 : break;
338 : : case 'q':
339 : 0 : quiet = true;
340 : 0 : break;
341 : : case 'r':
342 : 0 : recompute = true;
343 : 0 : flags |= PKG_LOAD_FILES;
344 : 0 : break;
345 : : case 's':
346 : 0 : checksums = true;
347 : 0 : flags |= PKG_LOAD_FILES;
348 : 0 : break;
349 : : case 'v':
350 : 0 : verbose = 1;
351 : 0 : break;
352 : : case 'x':
353 : 0 : match = MATCH_REGEX;
354 : 0 : break;
355 : : case 'y':
356 : 0 : yes = true;
357 : 0 : break;
358 : : default:
359 : 0 : usage_check();
360 : 0 : return (EXIT_FAILURE);
361 : : }
362 : : }
363 : 0 : argc -= optind;
364 : 0 : argv += optind;
365 : :
366 : : /* Default to all packages if no pkg provided */
367 [ # # # # : 0 : if (argc == 0 && (dcheck || checksums || recompute || reanalyse_shlibs)) {
# # # # #
# ]
368 : 0 : match = MATCH_ALL;
369 [ # # # # : 0 : } else if ((argc == 0 && match != MATCH_ALL) || !(dcheck || checksums || recompute || reanalyse_shlibs)) {
# # # # #
# ]
370 : 0 : usage_check();
371 : 0 : return (EXIT_FAILURE);
372 : : }
373 : :
374 [ # # # # ]: 0 : if (recompute || reanalyse_shlibs)
375 : 0 : ret = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE,
376 : : PKGDB_DB_LOCAL);
377 : : else
378 : 0 : ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL);
379 : :
380 [ # # ]: 0 : if (ret == EPKG_ENODB) {
381 [ # # ]: 0 : if (!quiet)
382 : 0 : warnx("No packages installed. Nothing to do!");
383 : 0 : return (EXIT_SUCCESS);
384 [ # # ]: 0 : } else if (ret == EPKG_ENOACCESS) {
385 : 0 : warnx("Insufficient privileges to access the package database");
386 : 0 : return (EXIT_FAILURE);
387 [ # # ]: 0 : } else if (ret != EPKG_OK) {
388 : 0 : warnx("Error accessing the package database");
389 : 0 : return (EXIT_FAILURE);
390 : : }
391 : :
392 [ # # ]: 0 : if (pkgdb_access(PKGDB_MODE_WRITE, PKGDB_DB_LOCAL) == EPKG_ENOACCESS) {
393 : 0 : warnx("Insufficient privileges");
394 : 0 : return (EXIT_FAILURE);
395 : : }
396 : :
397 : 0 : ret = pkgdb_open(&db, PKGDB_DEFAULT);
398 [ # # ]: 0 : if (ret != EPKG_OK)
399 : 0 : return (EXIT_FAILURE);
400 : :
401 [ # # ]: 0 : if (pkgdb_obtain_lock(db, PKGDB_LOCK_ADVISORY) != EPKG_OK) {
402 : 0 : pkgdb_close(db);
403 : 0 : warnx("Cannot get an advisory lock on a database, it is locked by another process");
404 : 0 : return (EXIT_FAILURE);
405 : : }
406 : :
407 : 0 : i = 0;
408 : 0 : nbdone = 0;
409 : 0 : do {
410 : : /* XXX: This is really quirky, it would be cleaner to pass
411 : : * in multiple matches and only run this top-loop once. */
412 [ # # ]: 0 : if ((it = pkgdb_query(db, argv[i], match)) == NULL) {
413 : 0 : rc = EXIT_FAILURE;
414 : 0 : goto cleanup;
415 : : }
416 : 0 : nbactions = pkgdb_it_count(it);
417 [ # # # # ]: 0 : if (nbactions == 0 && match != MATCH_ALL) {
418 : 0 : warnx("No packages matching: %s", argv[i]);
419 : 0 : rc = EXIT_FAILURE;
420 : 0 : goto cleanup;
421 : : }
422 : :
423 [ # # ]: 0 : if (msg == NULL)
424 : 0 : msg = xstring_new();
425 [ # # ]: 0 : if (!verbose) {
426 [ # # ]: 0 : if (!quiet) {
427 [ # # ]: 0 : if (match == MATCH_ALL)
428 : 0 : progressbar_start("Checking all packages");
429 : : else {
430 : 0 : fprintf(msg->fp, "Checking %s", argv[i]);
431 : 0 : fflush(msg->fp);
432 : 0 : progressbar_start(msg->buf);
433 : : }
434 : 0 : }
435 : 0 : processed = 0;
436 : 0 : total = pkgdb_it_count(it);
437 : 0 : }
438 : :
439 : 0 : xstring *out = xstring_new();
440 [ # # ]: 0 : while (pkgdb_it_next(it, &pkg, flags) == EPKG_OK) {
441 [ # # ]: 0 : if (!quiet) {
442 [ # # ]: 0 : if (!verbose)
443 : 0 : progressbar_tick(processed, total);
444 : : else {
445 : 0 : ++nbdone;
446 : 0 : job_status_begin(msg);
447 : 0 : pkg_fprintf(msg->fp, "Checking %n-%v:",
448 : 0 : pkg, pkg);
449 : 0 : fflush(msg->fp);
450 : 0 : printf("%s", msg->buf);
451 : 0 : xstring_reset(msg);
452 : : }
453 : 0 : }
454 : :
455 : : /* check for missing dependencies */
456 [ # # ]: 0 : if (dcheck) {
457 [ # # # # ]: 0 : if (!quiet && verbose)
458 : 0 : printf(" dependencies...");
459 : 0 : nbpkgs += check_deps(db, pkg, &dh, noinstall, out);
460 [ # # # # ]: 0 : if (noinstall && nbpkgs > 0) {
461 : 0 : rc = EXIT_FAILURE;
462 : 0 : }
463 : 0 : }
464 [ # # ]: 0 : if (checksums) {
465 [ # # # # ]: 0 : if (!quiet && verbose)
466 : 0 : printf(" checksums...");
467 [ # # ]: 0 : if (pkg_test_filesum(pkg) != EPKG_OK) {
468 : 0 : rc = EXIT_FAILURE;
469 : 0 : }
470 : 0 : }
471 [ # # ]: 0 : if (recompute) {
472 [ # # # # ]: 0 : if (pkgdb_upgrade_lock(db, PKGDB_LOCK_ADVISORY,
473 : 0 : PKGDB_LOCK_EXCLUSIVE) == EPKG_OK) {
474 [ # # # # ]: 0 : if (!quiet && verbose)
475 : 0 : printf(" recomputing...");
476 [ # # ]: 0 : if (pkg_recompute(db, pkg) != EPKG_OK) {
477 : 0 : rc = EXIT_FAILURE;
478 : 0 : }
479 : 0 : pkgdb_downgrade_lock(db,
480 : : PKGDB_LOCK_EXCLUSIVE,
481 : : PKGDB_LOCK_ADVISORY);
482 : 0 : }
483 : : else {
484 : 0 : rc = EXIT_FAILURE;
485 : : }
486 : 0 : }
487 [ # # ]: 0 : if (reanalyse_shlibs) {
488 [ # # # # ]: 0 : if (pkgdb_upgrade_lock(db, PKGDB_LOCK_ADVISORY,
489 : 0 : PKGDB_LOCK_EXCLUSIVE) == EPKG_OK) {
490 [ # # # # ]: 0 : if (!quiet && verbose)
491 : 0 : printf(" shared libraries...");
492 [ # # ]: 0 : if (pkgdb_reanalyse_shlibs(db, pkg) != EPKG_OK) {
493 : 0 : pkg_fprintf(stderr, "Failed to "
494 : : "reanalyse for shlibs: "
495 : 0 : "%n-%v\n", pkg, pkg);
496 : 0 : rc = EXIT_FAILURE;
497 : 0 : }
498 : 0 : pkgdb_downgrade_lock(db,
499 : : PKGDB_LOCK_EXCLUSIVE,
500 : : PKGDB_LOCK_ADVISORY);
501 : 0 : }
502 : : else {
503 : 0 : rc = EXIT_FAILURE;
504 : : }
505 : 0 : }
506 : :
507 [ # # ]: 0 : if (!quiet) {
508 [ # # ]: 0 : if (!verbose)
509 : 0 : ++processed;
510 : : else
511 : 0 : printf(" done\n");
512 : 0 : }
513 : : }
514 [ # # # # ]: 0 : if (!quiet && !verbose)
515 : 0 : progressbar_tick(processed, total);
516 : 0 : fflush(out->fp);
517 [ # # ]: 0 : if (out->buf[0] != '\0') {
518 : 0 : printf("%s", out->buf);
519 : 0 : }
520 : 0 : xstring_free(out);
521 : 0 : xstring_free(msg);
522 : 0 : msg = NULL;
523 : :
524 [ # # # # : 0 : if (dcheck && nbpkgs > 0 && !noinstall) {
# # ]
525 : 0 : printf("\n>>> Missing package dependencies were detected.\n");
526 : 0 : printf(">>> Found %d issue(s) in the package database.\n\n", nbpkgs);
527 [ # # # # ]: 0 : if (pkgdb_upgrade_lock(db, PKGDB_LOCK_ADVISORY,
528 : 0 : PKGDB_LOCK_EXCLUSIVE) == EPKG_OK) {
529 : 0 : ret = fix_deps(db, dh, nbpkgs);
530 [ # # ]: 0 : if (ret == EPKG_OK)
531 : 0 : check_summary(db, dh);
532 [ # # ]: 0 : else if (ret == EPKG_ENODB) {
533 : 0 : db = NULL;
534 : 0 : rc = EXIT_FAILURE;
535 : 0 : }
536 [ # # ]: 0 : if (rc == EXIT_FAILURE)
537 : 0 : goto cleanup;
538 : 0 : pkgdb_downgrade_lock(db, PKGDB_LOCK_EXCLUSIVE,
539 : : PKGDB_LOCK_ADVISORY);
540 : 0 : }
541 : : else {
542 : 0 : rc = EXIT_FAILURE;
543 : 0 : goto cleanup;
544 : : }
545 : 0 : }
546 : 0 : pkgdb_it_free(it);
547 : 0 : i++;
548 [ # # ]: 0 : } while (i < argc);
549 : :
550 : : cleanup:
551 [ # # ]: 0 : if (!verbose)
552 : 0 : progressbar_stop();
553 : 0 : xstring_free(msg);
554 : 0 : deps_free(dh);
555 : 0 : pkg_free(pkg);
556 : 0 : pkgdb_release_lock(db, PKGDB_LOCK_ADVISORY);
557 : 0 : pkgdb_close(db);
558 : :
559 : 0 : return (rc);
560 : 0 : }
|