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 : * All rights reserved.
6 : *
7 : * Redistribution and use in source and binary forms, with or without
8 : * modification, are permitted provided that the following conditions
9 : * are met:
10 : * 1. Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer
12 : * in this position and unchanged.
13 : * 2. Redistributions in binary form must reproduce the above copyright
14 : * notice, this list of conditions and the following disclaimer in the
15 : * documentation and/or other materials provided with the distribution.
16 : *
17 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
18 : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 : * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
21 : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 : */
28 :
29 : #include <err.h>
30 : #include <getopt.h>
31 : #include <stdio.h>
32 : #include <sysexits.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 [-ynq]\n\n");
43 0 : fprintf(stderr, "For more information see 'pkg help autoremove'.\n");
44 0 : }
45 :
46 : int
47 0 : exec_autoremove(int argc, char **argv)
48 : {
49 0 : struct pkgdb *db = NULL;
50 0 : struct pkg_jobs *jobs = NULL;
51 0 : int retcode = EX_OK;
52 : int ch;
53 0 : nbactions = nbdone = 0;
54 0 : pkg_flags f = PKG_FLAG_FORCE;
55 0 : bool rc = false;
56 0 : int lock_type = PKGDB_LOCK_ADVISORY;
57 :
58 0 : struct option longopts[] = {
59 : { "dry-run", no_argument, NULL, 'n' },
60 : { "quiet", no_argument, NULL, 'q' },
61 : { "yes", no_argument, NULL, 'y' },
62 : { NULL, 0, NULL, 0 },
63 : };
64 :
65 0 : while ((ch = getopt_long(argc, argv, "+nqy", longopts, NULL)) != -1) {
66 0 : switch (ch) {
67 : case 'n':
68 0 : f |= PKG_FLAG_DRY_RUN;
69 0 : dry_run = true;
70 0 : lock_type = PKGDB_LOCK_READONLY;
71 0 : break;
72 : case 'q':
73 0 : quiet = true;
74 0 : break;
75 : case 'y':
76 0 : yes = true;
77 0 : break;
78 : default:
79 0 : break;
80 : }
81 : }
82 0 : argc -= optind;
83 0 : argv += optind;
84 :
85 0 : if (argc != 0) {
86 0 : usage_autoremove();
87 0 : return (EX_USAGE);
88 : }
89 :
90 0 : if (dry_run)
91 0 : retcode = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL);
92 : else
93 0 : retcode = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE,
94 : PKGDB_DB_LOCAL);
95 :
96 0 : if (retcode == EPKG_ENOACCESS) {
97 0 : warnx("Insufficient privileges to autoremove packages");
98 0 : return (EX_NOPERM);
99 0 : } else if (retcode == EPKG_ENODB) {
100 0 : warnx("No packages installed. Nothing to do!");
101 0 : return (EX_OK);
102 0 : } else if (retcode != EPKG_OK) {
103 0 : warnx("Error accessing the package database");
104 0 : return (EX_SOFTWARE);
105 : }
106 :
107 0 : if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) {
108 0 : return (EX_IOERR);
109 : }
110 :
111 0 : if (pkgdb_obtain_lock(db, lock_type) != EPKG_OK) {
112 0 : pkgdb_close(db);
113 0 : warnx("Cannot get an advisory lock on a database, it is locked by another process");
114 0 : return (EX_TEMPFAIL);
115 : }
116 : /* Always force packages to be removed */
117 0 : if (pkg_jobs_new(&jobs, PKG_JOBS_AUTOREMOVE, db) != EPKG_OK) {
118 0 : pkgdb_close(db);
119 0 : return (EX_IOERR);
120 : }
121 :
122 0 : pkg_jobs_set_flags(jobs, f);
123 :
124 0 : if ((retcode = pkg_jobs_solve(jobs)) != EPKG_OK) {
125 0 : retcode = EX_SOFTWARE;
126 0 : goto cleanup;
127 : }
128 :
129 0 : if ((nbactions = pkg_jobs_count(jobs)) == 0) {
130 0 : printf("Nothing to do.\n");
131 0 : goto cleanup;
132 : }
133 :
134 0 : if (!quiet || dry_run) {
135 0 : print_jobs_summary(jobs,
136 : "Deinstallation has been requested for the following %d packages:\n\n", nbactions);
137 0 : if (!dry_run)
138 0 : rc = query_yesno(false,
139 : "\nProceed with deinstalling packages? ");
140 : }
141 0 : if (!rc || dry_run || (retcode = pkg_jobs_apply(jobs)) != EPKG_OK) {
142 : goto cleanup;
143 : }
144 :
145 0 : pkgdb_compact(db);
146 :
147 : cleanup:
148 0 : pkg_jobs_free(jobs);
149 0 : pkgdb_release_lock(db, lock_type);
150 0 : pkgdb_close(db);
151 :
152 0 : return (retcode);
153 : }
|