diff options
author | sobomax <sobomax@FreeBSD.org> | 2001-09-19 08:06:48 +0000 |
---|---|---|
committer | sobomax <sobomax@FreeBSD.org> | 2001-09-19 08:06:48 +0000 |
commit | 7942a4e1d2c7f9c821cae968af1b156019372d2a (patch) | |
tree | 983c446512bc26a2723c915739303dcac0da1570 /usr.sbin/pkg_install/delete | |
parent | de49b782662799d33adbe3450f5c4cbdb697a7f0 (diff) | |
download | FreeBSD-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.h | 1 | ||||
-rw-r--r-- | usr.sbin/pkg_install/delete/main.c | 9 | ||||
-rw-r--r-- | usr.sbin/pkg_install/delete/perform.c | 152 | ||||
-rw-r--r-- | usr.sbin/pkg_install/delete/pkg_delete.1 | 5 |
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 |