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) 2013-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 <err.h>
31 : : #include <getopt.h>
32 : : #include <stdio.h>
33 : : #include <unistd.h>
34 : :
35 : : #include <pkg.h>
36 : :
37 : : #include "pkgcli.h"
38 : :
39 : : void
40 : 0 : usage_autoremove(void)
41 : : {
42 : 0 : fprintf(stderr, "Usage: pkg autoremove [-Dynq]\n\n");
43 : 0 : fprintf(stderr, "For more information see 'pkg help autoremove'.\n");
44 : 0 : }
45 : :
46 : : int
47 : 30 : exec_autoremove(int argc, char **argv)
48 : : {
49 : 30 : struct pkgdb *db = NULL;
50 : 30 : struct pkg_jobs *jobs = NULL;
51 : 30 : int retcode = EXIT_SUCCESS;
52 : : int ch;
53 : 30 : nbactions = nbdone = 0;
54 : 30 : pkg_flags f = PKG_FLAG_FORCE;
55 : 30 : bool rc = false;
56 : 30 : int lock_type = PKGDB_LOCK_ADVISORY;
57 : :
58 : 30 : struct option longopts[] = {
59 : : { "dry-run", no_argument, NULL, 'n' },
60 : : { "no-scripts", no_argument, NULL, 'D' },
61 : : { "quiet", no_argument, NULL, 'q' },
62 : : { "yes", no_argument, NULL, 'y' },
63 : : { NULL, 0, NULL, 0 },
64 : : };
65 : :
66 [ + + ]: 77 : while ((ch = getopt_long(argc, argv, "+Dnqy", longopts, NULL)) != -1) {
67 [ + - + + : 47 : switch (ch) {
- ]
68 : : case 'n':
69 : 9 : f |= PKG_FLAG_DRY_RUN;
70 : 9 : dry_run = true;
71 : 9 : lock_type = PKGDB_LOCK_READONLY;
72 : 9 : break;
73 : : case 'D':
74 : 0 : f |= PKG_FLAG_NOSCRIPT;
75 : 0 : break;
76 : : case 'q':
77 : 8 : quiet = true;
78 : 8 : break;
79 : : case 'y':
80 : 30 : yes = true;
81 : 30 : break;
82 : : default:
83 : 0 : usage_autoremove();
84 : 0 : return (EXIT_FAILURE);
85 : : }
86 : : }
87 : 30 : argc -= optind;
88 : :
89 [ - + ]: 30 : if (argc != 0) {
90 : 0 : usage_autoremove();
91 : 0 : return (EXIT_FAILURE);
92 : : }
93 : :
94 [ + + ]: 30 : if (dry_run)
95 : 9 : retcode = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL);
96 : : else
97 : 21 : retcode = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE,
98 : : PKGDB_DB_LOCAL);
99 : :
100 [ - + ]: 30 : if (retcode == EPKG_ENOACCESS) {
101 : 0 : warnx("Insufficient privileges to autoremove packages");
102 : 0 : return (EXIT_FAILURE);
103 [ - + ]: 30 : } else if (retcode == EPKG_ENODB) {
104 : 0 : warnx("No packages installed. Nothing to do!");
105 : 0 : return (EXIT_SUCCESS);
106 [ - + ]: 30 : } else if (retcode != EPKG_OK) {
107 : 0 : warnx("Error accessing the package database");
108 : 0 : return (EXIT_FAILURE);
109 : : }
110 : :
111 [ - + ]: 30 : if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) {
112 : 0 : return (EXIT_FAILURE);
113 : : }
114 : :
115 [ - + ]: 30 : if (pkgdb_obtain_lock(db, lock_type) != EPKG_OK) {
116 : 0 : pkgdb_close(db);
117 : 0 : warnx("Cannot get an advisory lock on a database, it is locked by another process");
118 : 0 : return (EXIT_FAILURE);
119 : : }
120 : : /* Always force packages to be removed */
121 [ - + ]: 30 : if (pkg_jobs_new(&jobs, PKG_JOBS_AUTOREMOVE, db) != EPKG_OK) {
122 : 0 : pkgdb_close(db);
123 : 0 : return (EXIT_FAILURE);
124 : : }
125 : :
126 : 30 : pkg_jobs_set_flags(jobs, f);
127 : :
128 [ - + ]: 30 : if ((retcode = pkg_jobs_solve(jobs)) != EPKG_OK) {
129 : 0 : retcode = EXIT_FAILURE;
130 : 0 : goto cleanup;
131 : : }
132 : :
133 [ + - ]: 30 : if ((nbactions = pkg_jobs_count(jobs)) == 0) {
134 [ # # ]: 0 : if (!quiet)
135 : 0 : printf("Nothing to do.\n");
136 : 0 : goto cleanup;
137 : : }
138 : :
139 [ + + - + ]: 30 : if (!quiet || dry_run) {
140 : 44 : print_jobs_summary(jobs,
141 : 22 : "Deinstallation has been requested for the following %d packages:\n\n", nbactions);
142 [ + + ]: 22 : if (!dry_run)
143 : 13 : rc = query_yesno(false,
144 : : "\nProceed with deinstalling packages? ");
145 : 22 : }
146 [ - + + + : 30 : if ((yes || rc ) && !dry_run && ((retcode = pkg_jobs_apply(jobs)) != EPKG_OK)) {
+ - ]
147 : 0 : goto cleanup;
148 : : }
149 : :
150 [ - + # # ]: 30 : if (!yes && !rc)
151 : 0 : retcode = EXIT_FAILURE;
152 : :
153 : 30 : pkgdb_compact(db);
154 : :
155 : : cleanup:
156 : 30 : pkg_jobs_free(jobs);
157 : 30 : pkgdb_release_lock(db, lock_type);
158 : 30 : pkgdb_close(db);
159 : :
160 : 30 : return (retcode);
161 : 30 : }
|