Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/pkg
Path: blob/main/src/autoremove.c
2065 views
1
/*-
2
* Copyright (c) 2011-2012 Baptiste Daroussin <[email protected]>
3
* Copyright (c) 2011-2012 Marin Atanasov Nikolov <[email protected]>
4
* Copyright (c) 2013-2014 Matthew Seaman <[email protected]>
5
* Copyright (c) 2016 Vsevolod Stakhov <[email protected]>
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
usage_autoremove(void)
41
{
42
fprintf(stderr, "Usage: pkg autoremove [-Dynq]\n\n");
43
fprintf(stderr, "For more information see 'pkg help autoremove'.\n");
44
}
45
46
int
47
exec_autoremove(int argc, char **argv)
48
{
49
struct pkgdb *db = NULL;
50
struct pkg_jobs *jobs = NULL;
51
int retcode = EXIT_SUCCESS;
52
int ch;
53
int nbactions = 0;
54
pkg_flags f = PKG_FLAG_FORCE;
55
bool rc = false;
56
int lock_type = PKGDB_LOCK_ADVISORY;
57
58
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
while ((ch = getopt_long(argc, argv, "+Dnqy", longopts, NULL)) != -1) {
67
switch (ch) {
68
case 'n':
69
f |= PKG_FLAG_DRY_RUN;
70
dry_run = true;
71
lock_type = PKGDB_LOCK_READONLY;
72
break;
73
case 'D':
74
f |= PKG_FLAG_NOSCRIPT;
75
break;
76
case 'q':
77
quiet = true;
78
break;
79
case 'y':
80
yes = true;
81
break;
82
default:
83
usage_autoremove();
84
return (EXIT_FAILURE);
85
}
86
}
87
argc -= optind;
88
89
if (argc != 0) {
90
usage_autoremove();
91
return (EXIT_FAILURE);
92
}
93
94
if (dry_run)
95
retcode = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL);
96
else
97
retcode = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE,
98
PKGDB_DB_LOCAL);
99
100
if (retcode == EPKG_ENOACCESS) {
101
warnx("Insufficient privileges to autoremove packages");
102
return (EXIT_FAILURE);
103
} else if (retcode == EPKG_ENODB) {
104
warnx("No packages installed. Nothing to do!");
105
return (EXIT_SUCCESS);
106
} else if (retcode != EPKG_OK) {
107
warnx("Error accessing the package database");
108
return (EXIT_FAILURE);
109
}
110
111
if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) {
112
return (EXIT_FAILURE);
113
}
114
115
if (pkgdb_obtain_lock(db, lock_type) != EPKG_OK) {
116
pkgdb_close(db);
117
warnx("Cannot get an advisory lock on a database, it is locked by another process");
118
return (EXIT_FAILURE);
119
}
120
/* Always force packages to be removed */
121
if (pkg_jobs_new(&jobs, PKG_JOBS_AUTOREMOVE, db) != EPKG_OK) {
122
pkgdb_close(db);
123
return (EXIT_FAILURE);
124
}
125
126
pkg_jobs_set_flags(jobs, f);
127
128
if ((retcode = pkg_jobs_solve(jobs)) != EPKG_OK) {
129
retcode = EXIT_FAILURE;
130
goto cleanup;
131
}
132
133
if ((nbactions = pkg_jobs_count(jobs)) == 0) {
134
if (!quiet)
135
printf("Nothing to do.\n");
136
goto cleanup;
137
}
138
139
if (!quiet || dry_run) {
140
print_jobs_summary(jobs,
141
"Deinstallation has been requested for the following %d packages:\n\n", nbactions);
142
if (!dry_run)
143
rc = query_yesno(false,
144
"\nProceed with deinstalling packages? ");
145
}
146
if ((yes || rc ) && !dry_run && ((retcode = pkg_jobs_apply(jobs)) != EPKG_OK)) {
147
goto cleanup;
148
}
149
150
if (!yes && !rc)
151
retcode = EXIT_FAILURE;
152
153
pkgdb_compact(db);
154
155
cleanup:
156
pkg_jobs_free(jobs);
157
pkgdb_release_lock(db, lock_type);
158
pkgdb_close(db);
159
160
return (retcode);
161
}
162
163