summaryrefslogtreecommitdiffstats
path: root/usr.sbin/pkg_install/delete
diff options
context:
space:
mode:
authorsobomax <sobomax@FreeBSD.org>2001-09-19 08:06:48 +0000
committersobomax <sobomax@FreeBSD.org>2001-09-19 08:06:48 +0000
commit7942a4e1d2c7f9c821cae968af1b156019372d2a (patch)
tree983c446512bc26a2723c915739303dcac0da1570 /usr.sbin/pkg_install/delete
parentde49b782662799d33adbe3450f5c4cbdb697a7f0 (diff)
downloadFreeBSD-src-7942a4e1d2c7f9c821cae968af1b156019372d2a.zip
FreeBSD-src-7942a4e1d2c7f9c821cae968af1b156019372d2a.tar.gz
Various fixes and improvements:
- fix harmless compiler's warnings (unused variables and missed prototype); - before refusing to delete package because "there are packages installed that require this package" check that packages in question is actually installed; - add new `-r' option to pkg_delete(8), which instructs it to delete not only packages specified at command line, but all packages that depend on specified packages as well. MFC after: 2 weeks
Diffstat (limited to 'usr.sbin/pkg_install/delete')
-rw-r--r--usr.sbin/pkg_install/delete/delete.h1
-rw-r--r--usr.sbin/pkg_install/delete/main.c9
-rw-r--r--usr.sbin/pkg_install/delete/perform.c152
-rw-r--r--usr.sbin/pkg_install/delete/pkg_delete.15
4 files changed, 99 insertions, 68 deletions
diff --git a/usr.sbin/pkg_install/delete/delete.h b/usr.sbin/pkg_install/delete/delete.h
index faa2e06..a973642 100644
--- a/usr.sbin/pkg_install/delete/delete.h
+++ b/usr.sbin/pkg_install/delete/delete.h
@@ -28,6 +28,7 @@ extern Boolean CleanDirs;
extern Boolean Interactive;
extern Boolean NoDeInstall;
extern Boolean Force;
+extern Boolean Recursive;
extern char *Directory;
extern char *PkgName;
extern match_t MatchType;
diff --git a/usr.sbin/pkg_install/delete/main.c b/usr.sbin/pkg_install/delete/main.c
index 2dba240..5538838e 100644
--- a/usr.sbin/pkg_install/delete/main.c
+++ b/usr.sbin/pkg_install/delete/main.c
@@ -30,12 +30,13 @@ static const char rcsid[] =
#include "lib.h"
#include "delete.h"
-static char Options[] = "adDfGhinp:vx";
+static char Options[] = "adDfGhinp:rvx";
char *Prefix = NULL;
Boolean CleanDirs = FALSE;
Boolean Interactive = FALSE;
Boolean NoDeInstall = FALSE;
+Boolean Recursive = FALSE;
match_t MatchType = MATCH_GLOB;
static void usage __P((void));
@@ -93,6 +94,10 @@ main(int argc, char **argv)
Interactive = TRUE;
break;
+ case 'r':
+ Recursive = TRUE;
+ break;
+
case 'h':
case '?':
default:
@@ -148,7 +153,7 @@ static void
usage()
{
fprintf(stderr, "%s\n%s\n",
- "usage: pkg_delete [-dDfGinvx] [-p prefix] pkg-name ...",
+ "usage: pkg_delete [-dDfGinrvx] [-p prefix] pkg-name ...",
" pkg_delete -a [flags]");
exit(1);
}
diff --git a/usr.sbin/pkg_install/delete/perform.c b/usr.sbin/pkg_install/delete/perform.c
index 21815f6..dfe7c91 100644
--- a/usr.sbin/pkg_install/delete/perform.c
+++ b/usr.sbin/pkg_install/delete/perform.c
@@ -36,10 +36,11 @@ static char LogDir[FILENAME_MAX];
int
pkg_perform(char **pkgs)
{
- char **matched;
- int i;
+ char **matched, **rb, **rbtmp;
+ int errcode, i, j;
int err_cnt = 0;
- int errcode;
+ struct reqr_by_entry *rb_entry;
+ struct reqr_by_head *rb_list;
if (MatchType != MATCH_EXACT) {
matched = matchinstalled(MatchType, pkgs, &errcode);
@@ -65,6 +66,40 @@ pkg_perform(char **pkgs)
err_cnt += sortdeps(pkgs);
for (i = 0; pkgs[i]; i++) {
+ if (Recursive == TRUE) {
+ errcode = requiredby(pkgs[i], &rb_list, FALSE, TRUE);
+ if (errcode < 0) {
+ err_cnt++;
+ } else if (errcode > 0) {
+ /*
+ * Copy values from the rb_list queue into argv-like NULL
+ * terminated list because requiredby() uses some static
+ * storage, while pkg_do() below will call this function,
+ * thus blowing our rb_list away.
+ */
+ rbtmp = rb = alloca((errcode + 1) * sizeof(*rb));
+ if (rb == NULL) {
+ warnx("%s(): alloca() failed", __FUNCTION__);
+ err_cnt++;
+ continue;
+ }
+ STAILQ_FOREACH(rb_entry, rb_list, link) {
+ *rbtmp = alloca(strlen(rb_entry->pkgname) + 1);
+ if (*rbtmp == NULL) {
+ warnx("%s(): alloca() failed", __FUNCTION__);
+ err_cnt++;
+ continue;
+ }
+ strcpy(*rbtmp, rb_entry->pkgname);
+ rbtmp++;
+ }
+ *rbtmp = NULL;
+
+ err_cnt += sortdeps(rb);
+ for (j = 0; rb[j]; j++)
+ err_cnt += pkg_do(rb[j]);
+ }
+ }
err_cnt += pkg_do(pkgs[i]);
}
@@ -80,13 +115,14 @@ pkg_do(char *pkg)
FILE *cfile;
char home[FILENAME_MAX];
PackingList p;
- char *tmp;
int len;
/* support for separate pre/post install scripts */
int new_m = 0;
char pre_script[FILENAME_MAX] = DEINSTALL_FNAME;
char post_script[FILENAME_MAX];
char pre_arg[FILENAME_MAX], post_arg[FILENAME_MAX];
+ struct reqr_by_entry *rb_entry;
+ struct reqr_by_head *rb_list;
if (!pkg || !(len = strlen(pkg)))
return 1;
@@ -127,18 +163,14 @@ pkg_do(char *pkg)
/* Not reached */
}
- if (!isemptyfile(REQUIRED_BY_FNAME)) {
- char buf[512];
+ if (requiredby(pkg, &rb_list, FALSE, TRUE) < 0)
+ return 1;
+ if (!STAILQ_EMPTY(rb_list)) {
warnx("package '%s' is required by these other packages\n"
- "and may not be deinstalled%s:",
- pkg, Force ? " (but I'll delete it anyway)" : "" );
- cfile = fopen(REQUIRED_BY_FNAME, "r");
- if (cfile) {
- while (fgets(buf, sizeof(buf), cfile))
- fprintf(stderr, "%s", buf);
- fclose(cfile);
- } else
- warnx("cannot open requirements file '%s'", REQUIRED_BY_FNAME);
+ "and may not be deinstalled%s:",
+ pkg, Force ? " (but I'll delete it anyway)" : "");
+ STAILQ_FOREACH(rb_entry, rb_list, link)
+ fprintf(stderr, "%s\n", rb_entry->pkgname);
if (!Force)
return 1;
}
@@ -283,54 +315,44 @@ cleanup(int sig)
static void
undepend(PackingList p, char *pkgname)
{
- char fname[FILENAME_MAX], ftmp[FILENAME_MAX];
- char fbuf[FILENAME_MAX];
- FILE *fp, *fpwr;
- char *tmp;
- int s;
-
- sprintf(fname, "%s/%s/%s", LOG_DIR, p->name, REQUIRED_BY_FNAME);
- fp = fopen(fname, "r");
- if (fp == NULL) {
- warnx("couldn't open dependency file '%s'", fname);
- return;
- }
- sprintf(ftmp, "%s.XXXXXX", fname);
- s = mkstemp(ftmp);
- if (s == -1) {
- fclose(fp);
- warnx("couldn't open temp file '%s'", ftmp);
- return;
- }
- fpwr = fdopen(s, "w");
- if (fpwr == NULL) {
- close(s);
- fclose(fp);
- warnx("couldn't fdopen temp file '%s'", ftmp);
- remove(ftmp);
- return;
- }
- while (fgets(fbuf, sizeof(fbuf), fp) != NULL) {
- if (fbuf[strlen(fbuf)-1] == '\n')
- fbuf[strlen(fbuf)-1] = '\0';
- if (strcmp(fbuf, pkgname)) /* no match */
- fputs(fbuf, fpwr), putc('\n', fpwr);
- }
- (void) fclose(fp);
- if (fchmod(s, 0644) == FAIL) {
- warnx("error changing permission of temp file '%s'", ftmp);
- fclose(fpwr);
- remove(ftmp);
- return;
- }
- if (fclose(fpwr) == EOF) {
- warnx("error closing temp file '%s'", ftmp);
- remove(ftmp);
- return;
- }
- if (rename(ftmp, fname) == -1)
- warnx("error renaming '%s' to '%s'", ftmp, fname);
- remove(ftmp); /* just in case */
- return;
+ char fname[FILENAME_MAX], ftmp[FILENAME_MAX];
+ FILE *fpwr;
+ int s;
+ struct reqr_by_entry *rb_entry;
+ struct reqr_by_head *rb_list;
+
+
+ if (requiredby(p->name, &rb_list, Verbose, FALSE) <= 0)
+ return;
+ snprintf(fname, sizeof(fname), "%s/%s/%s", LOG_DIR, p->name,
+ REQUIRED_BY_FNAME);
+ snprintf(ftmp, sizeof(ftmp), "%s.XXXXXX", fname);
+ s = mkstemp(ftmp);
+ if (s == -1) {
+ warnx("couldn't open temp file '%s'", ftmp);
+ return;
+ }
+ fpwr = fdopen(s, "w");
+ if (fpwr == NULL) {
+ close(s);
+ warnx("couldn't fdopen temp file '%s'", ftmp);
+ goto cleanexit;
+ }
+ STAILQ_FOREACH(rb_entry, rb_list, link)
+ if (strcmp(rb_entry->pkgname, pkgname)) /* no match */
+ fputs(rb_entry->pkgname, fpwr), putc('\n', fpwr);
+ if (fchmod(s, 0644) == FAIL) {
+ warnx("error changing permission of temp file '%s'", ftmp);
+ fclose(fpwr);
+ goto cleanexit;
+ }
+ if (fclose(fpwr) == EOF) {
+ warnx("error closing temp file '%s'", ftmp);
+ goto cleanexit;
+ }
+ if (rename(ftmp, fname) == -1)
+ warnx("error renaming '%s' to '%s'", ftmp, fname);
+cleanexit:
+ remove(ftmp);
+ return;
}
-
diff --git a/usr.sbin/pkg_install/delete/pkg_delete.1 b/usr.sbin/pkg_install/delete/pkg_delete.1
index c998bb3..947939b 100644
--- a/usr.sbin/pkg_install/delete/pkg_delete.1
+++ b/usr.sbin/pkg_install/delete/pkg_delete.1
@@ -25,7 +25,7 @@
.Nd a utility for deleting previously installed software package distributions
.Sh SYNOPSIS
.Nm
-.Op Fl dDfGinvx
+.Op Fl dDfGinrvx
.Op Fl p Ar prefix
.Ar pkg-name ...
.Nm
@@ -119,6 +119,9 @@ provided, in that case
.Nm
deletes all packages that match at least one
regular expression from the list.
+.It Fl r
+Recursive removal. In addition to specified packages, delete all
+packages that depend on those packages as well.
.El
.Sh TECHNICAL DETAILS
.Nm
OpenPOWER on IntegriCloud