diff options
author | jkh <jkh@FreeBSD.org> | 1998-12-16 13:59:31 +0000 |
---|---|---|
committer | jkh <jkh@FreeBSD.org> | 1998-12-16 13:59:31 +0000 |
commit | 14bdf1c6c014d051678254cec508ab3065989050 (patch) | |
tree | a10438d747dc77ce05c457ecf05e6feef939cda0 /usr.sbin/pkg_install/delete | |
parent | 76e92ae7047e57dd24ddfebbb87c0a80517d99c6 (diff) | |
download | FreeBSD-src-14bdf1c6c014d051678254cec508ab3065989050.zip FreeBSD-src-14bdf1c6c014d051678254cec508ab3065989050.tar.gz |
Make it possible to have separate install scripts as well as have
an on-delete script.
Submitted by: Rajesh Vaidheeswarran <rv@fore.com>
Diffstat (limited to 'usr.sbin/pkg_install/delete')
-rw-r--r-- | usr.sbin/pkg_install/delete/perform.c | 70 | ||||
-rw-r--r-- | usr.sbin/pkg_install/delete/pkg_delete.1 | 73 |
2 files changed, 131 insertions, 12 deletions
diff --git a/usr.sbin/pkg_install/delete/perform.c b/usr.sbin/pkg_install/delete/perform.c index f5de2b2..dc85e02 100644 --- a/usr.sbin/pkg_install/delete/perform.c +++ b/usr.sbin/pkg_install/delete/perform.c @@ -1,6 +1,6 @@ #ifndef lint static const char rcsid[] = - "$Id: perform.c,v 1.16 1998/09/11 07:26:58 jkh Exp $"; + "$Id: perform.c,v 1.17 1998/11/11 06:09:04 jkh Exp $"; #endif /* @@ -54,6 +54,11 @@ pkg_do(char *pkg) 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]; if (!pkg || !(len = strlen(pkg))) return 1; @@ -66,18 +71,22 @@ pkg_do(char *pkg) sprintf(LogDir, "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, pkg); + if (!fexists(LogDir)) { warnx("no such package '%s' installed", pkg); return 1; } + if (!getcwd(home, FILENAME_MAX)) { cleanup(0); errx(2, "unable to get current working directory!"); } + if (chdir(LogDir) == FAIL) { warnx("unable to change directory to %s! deinstall failed", LogDir); return 1; } + if (!isemptyfile(REQUIRED_BY_FNAME)) { char buf[512]; warnx("package `%s' is required by these other packages\n" @@ -93,23 +102,29 @@ pkg_do(char *pkg) if (!Force) return 1; } + sanity_check(LogDir); cfile = fopen(CONTENTS_FNAME, "r"); + if (!cfile) { warnx("unable to open '%s' file", CONTENTS_FNAME); return 1; } + /* If we have a prefix, add it now */ if (Prefix) add_plist(&Plist, PLIST_CWD, Prefix); read_plist(&Plist, cfile); fclose(cfile); p = find_plist(&Plist, PLIST_CWD); + if (!p) { warnx("package '%s' doesn't have a prefix", pkg); return 1; } + setenv(PKG_PREFIX_VNAME, p->name, 1); + if (fexists(REQUIRE_FNAME)) { if (Verbose) printf("Executing 'require' script.\n"); @@ -121,34 +136,81 @@ pkg_do(char *pkg) return 1; } } - if (!NoDeInstall && fexists(DEINSTALL_FNAME)) { + + /* Test whether to use the old method of passing tokens to deinstallation + * scripts, and set appropriate variables.. + */ + + if (fexists(POST_DEINSTALL_FNAME)) { + new_m = 1; + sprintf(post_script, "%s", POST_DEINSTALL_FNAME); + sprintf(pre_arg, ""); + sprintf(post_arg, ""); + } else { + if (fexists(DEINSTALL_FNAME)) { + sprintf(post_script, "%s", DEINSTALL_FNAME); + sprintf(pre_arg, "DEINSTALL"); + sprintf(post_arg, "POST-DEINSTALL"); + } + } + + if (!NoDeInstall && fexists(pre_script)) { if (Fake) printf("Would execute de-install script at this point.\n"); else { - vsystem("chmod +x %s", DEINSTALL_FNAME); /* make sure */ - if (vsystem("./%s %s DEINSTALL", DEINSTALL_FNAME, pkg)) { + vsystem("chmod +x %s", pre_script); /* make sure */ + if (vsystem("./%s %s %s", pre_script, pkg, pre_arg)) { warnx("deinstall script returned error status"); if (!Force) return 1; } } } + if (chdir(home) == FAIL) { cleanup(0); errx(2, "Toto! This doesn't look like Kansas anymore!"); } + if (!Fake) { /* Some packages aren't packed right, so we need to just ignore delete_package()'s status. Ugh! :-( */ if (delete_package(FALSE, CleanDirs, &Plist) == FAIL) warnx( "couldn't entirely delete package (perhaps the packing list is\n" "incorrectly specified?)"); + } + + if (chdir(LogDir) == FAIL) { + warnx("unable to change directory to %s! deinstall failed", LogDir); + return 1; + } + + if (!NoDeInstall && fexists(post_script)) { + if (Fake) + printf("Would execute post-deinstall script at this point.\n"); + else { + vsystem("chmod +x %s", post_script); /* make sure */ + if (vsystem("./%s %s %s", post_script, pkg, post_arg)) { + warnx("post-deinstall script returned error status"); + if (!Force) + return 1; + } + } + } + + if (chdir(home) == FAIL) { + cleanup(0); + errx(2, "Toto! This doesn't look like Kansas anymore!"); + } + + if (!Fake) { if (vsystem("%s -r %s", REMOVE_CMD, LogDir)) { warnx("couldn't remove log entry in %s, deinstall failed", LogDir); if (!Force) return 1; } } + for (p = Plist.head; p ; p = p->next) { if (p->type != PLIST_PKGDEP) continue; diff --git a/usr.sbin/pkg_install/delete/pkg_delete.1 b/usr.sbin/pkg_install/delete/pkg_delete.1 index 31888e7..8307525 100644 --- a/usr.sbin/pkg_install/delete/pkg_delete.1 +++ b/usr.sbin/pkg_install/delete/pkg_delete.1 @@ -47,9 +47,9 @@ You are advised to verify the competence and identity of those who provide installable package files. For extra protection, examine all the package control files in the package record directory ( .Pa /var/db/pkg/<pkg-name>/ ). -Pay particular -attention to any +INSTALL, +DEINSTALL, +REQUIRE or +MTREE_DIRS files, -and inspect the +CONTENTS file for +Pay particular attention to any +INSTALL, +POST-INSTALL, +DEINSTALL, ++POST-DEINSTALL, +REQUIRE or +MTREE_DIRS files, and inspect the +CONTENTS +file for .Cm @cwd , .Cm @mode (check for setuid), @@ -97,7 +97,7 @@ deinstall or require script fails. .Pp .Sh TECHNICAL DETAILS -.Nm Pkg_delete +.Nm pkg_delete does pretty much what it says. It examines installed package records in .Pa /var/db/pkg/<pkg-name> , deletes the package contents, and finally removes the package records. @@ -140,14 +140,71 @@ The .Nm deinstall script is called as: .Bd -filled -offset indent -compact -.Cm deinstall +.Cm script .Ar <pkg-name> .Ar DEINSTALL .Ed -Passing the keyword +where +.Ar pkg-name +is the name of the package in question and +.Ar DEINSTALL +is a keyword denoting this as the pre-deinstallation phase. + +.Cm Note: +The .Ar DEINSTALL -lets you potentially write only one program/script that handles all -aspects of installation and deletion. +keyword will not appear if separate scripts for deinstall and post-deinstall +are given during package creation time (using the +.Cm Fl k +and +.Cm Fl K +flags to +.Xr pkg_create 1 ). +.Pp +If a +.Cm post-deinstall +script exists for the package, it is executed +.Cm after +all files are removed. It is this script's responsibility to clean up any +additional messy details around the package's installation, and leave the +system (hopefully) in the same state that it was prior to the installation +of the package. + +The +.Nm post-deinstall +script is called as: +.Bd -filled -offset indent -compact +.Cm script +.Ar <pkg-name> +.Ar POST-DEINSTALL +.Ed +where +.Ar pkg-name +is the name of the package in question and +.Ar POST-DEINSTALL +is a keyword denoting this as the post-deinstallation phase. + +.Cm Note: +The +.Ar POST-DEINSTALL +keyword will not appear if separate scripts for deinstall and post-deinstall +are given during package creation time (using the +.Cm Fl k +and +.Cm Fl K +flags to +.Xr pkg_create 1 ). + +Reasoning behind passing keywords such as +.Ar DEINSTALL +and +.Ar POST-DEINSTALL +is that it lets you potentially write only one program/script that handles +all aspects of installation and deletion. + +But experience has proved that this is a lot more difficult to maintain and +is not as advantageous as having separate scripts that handle each aspect of +installation and deinstallation. .Pp All scripts are called with the environment variable .Ev PKG_PREFIX |