From nobody  Mon Dec  7 19:00:42 1998
Received: (from nobody@localhost)
          by hub.freebsd.org (8.8.8/8.8.8) id TAA26785;
          Mon, 7 Dec 1998 19:00:42 -0800 (PST)
          (envelope-from nobody)
Message-Id: <199812080300.TAA26785@hub.freebsd.org>
Date: Mon, 7 Dec 1998 19:00:42 -0800 (PST)
From: rv@fore.com
To: freebsd-gnats-submit@freebsd.org
Subject: pkg_delete is insufficient. no post-remove script functionality present
X-Send-Pr-Version: www-1.0

>Number:         9005
>Category:       bin
>Synopsis:       pkg_delete is insufficient. no post-remove script functionality present
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    jkh
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon Dec  7 19:10:00 PST 1998
>Closed-Date:    Mon Feb 1 11:11:53 PST 1999
>Last-Modified:  Mon Feb  1 11:12:08 PST 1999
>Originator:     Rajesh Vaidheeswarran
>Release:        3.0-CURRENT
>Organization:
>Environment:
FreeBSD freebsd.eng.fore.com 3.0-CURRENT FreeBSD 3.0-CURRENT #0: Thu Nov 12 10:4
6:44 EST 1998     rv@freebsd.eng.fore.com:/usr/src/sys/compile/FB30  i386

>Description:
pkg_add in freebsd provides both preinstall and postinstall 
scripting functionality but the equivalent functionality is absent
in pkg_delete (preremove and postremove).

pkg_delete provides only preremove funcionality which is 
insufficient.

Ideally, all packaging scripts should be separate (i.e., without
the need to pass keywords to scripts like PRE-INSTALL POST-INSTALL
DEINSTALL, and such. Solaris pkg* utilities provide an interface
such as that.)

I would, however be happy with keyword passing if atleast all the
required functionality is provided. What is still required is a
POST-DEINSTALL functionality.

>How-To-Repeat:

>Fix:
I have included a patch for this. If the maintainers are
interested in the idea of creating a pkg_* utility package that
uses multiple install scripts, I'd be more than glad to provide
a patch to the current package that does just that.

The patch has been uploaded to 
ftp.freebsd.org/pub/FreeBSD/incoming/pkg_install.patch

-rw-rw----  1 801  207  9060 Dec  8 02:57 pkg_install.patch

Unfortunately, the permissions seem to be set so that it cannot be
downloaded by anyone other than users of the machine it is on.

So, if you are unable to retrieve it and want to get hold of a copy
of the patch, e-mail me.

Thanks

rv

(PS: I'm using a Windoze NuT machine to send this PR, which is 
why cut and paste of the patch into this windows gets messed up).

>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->jkh 
Responsible-Changed-By: asami 
Responsible-Changed-When: Mon Dec 7 21:19:36 PST 1998 
Responsible-Changed-Why:  
This is very useful, therefore dump it to Jordan (mr. pkg_*). 

From: Rajesh Vaidheeswarran <rv@fore.com>
To: jkh@freebsd.org
Cc: rv@fore.com, freebsd-bugs@freebsd.org
Subject: Re: bin/9005: new functionality patch.
Date: Fri, 11 Dec 1998 19:21:56 -0500

 Hi Jordan:
 
 I'm attaching a diff for the separation of the [de]installation scripts.
 
 Let me know what you think.
 
 rv
 diff -cr /usr/src/usr.sbin/pkg_install/add/perform.c pkg_install/add/perform.c
 *** /usr/src/usr.sbin/pkg_install/add/perform.c	Fri Sep 11 03:26:54 1998
 --- pkg_install/add/perform.c	Fri Dec 11 17:34:06 1998
 ***************
 *** 72,77 ****
 --- 72,82 ----
       PackingList p;
       struct stat sb;
       int inPlace;
 +     /* support for separate pre/post install scripts */
 +     int new_m = 0;
 +     char pre_script[FILENAME_MAX] = INSTALL_FNAME;
 +     char post_script[FILENAME_MAX];
 +     char pre_arg[FILENAME_MAX], post_arg[FILENAME_MAX];
   
       code = 0;
       zapLogDir = 0;
 ***************
 *** 318,334 ****
   	}
       }
   
       /* If we're really installing, and have an installation file, run it */
 !     if (!NoInstall && fexists(INSTALL_FNAME)) {
 ! 	vsystem("chmod +x %s", INSTALL_FNAME);	/* make sure */
   	if (Verbose)
 ! 	    printf("Running install with PRE-INSTALL for %s..\n", PkgName);
 ! 	if (!Fake && vsystem("./%s %s PRE-INSTALL", INSTALL_FNAME, PkgName)) {
   	    warnx("install script returned error status");
 ! 	    unlink(INSTALL_FNAME);
   	    code = 1;
   	    goto success;		/* nothing to uninstall yet */
   	}
       }
   
       /* Now finally extract the entire show if we're not going direct */
 --- 323,357 ----
   	}
       }
   
 +     /* Test whether to use the old method of passing tokens to installation
 +      * scripts, and set appropriate variables..
 +      */
 + 
 +     if (fexists(POST_INSTALL_FNAME)) {
 + 	new_m = 1;
 + 	sprintf(post_script, "%s", POST_INSTALL_FNAME);
 + 	sprintf(pre_arg, "");
 + 	sprintf(post_arg, "");
 +     } else {
 + 	if (fexists(INSTALL_FNAME)) {
 + 	    sprintf(post_script, "%s", INSTALL_FNAME);
 + 	    sprintf(pre_arg, "PRE-INSTALL");
 + 	    sprintf(post_arg, "POST-INSTALL");
 + 	}
 +     }
 + 
       /* If we're really installing, and have an installation file, run it */
 !     if (!NoInstall && fexists(pre_script)) {
 ! 	vsystem("chmod +x %s", pre_script);	/* make sure */
   	if (Verbose)
 ! 	    printf("Running pre-install for %s..\n", PkgName);
 ! 	if (!Fake && vsystem("./%s %s %s", pre_script, PkgName, pre_arg)) {
   	    warnx("install script returned error status");
 ! 	    unlink(pre_script);
   	    code = 1;
   	    goto success;		/* nothing to uninstall yet */
   	}
 + 	if (new_m) unlink(pre_script);
       }
   
       /* Now finally extract the entire show if we're not going direct */
 ***************
 *** 349,364 ****
       }
   
       /* Run the installation script one last time? */
 !     if (!NoInstall && fexists(INSTALL_FNAME)) {
   	if (Verbose)
 ! 	    printf("Running install with POST-INSTALL for %s..\n", PkgName);
 ! 	if (!Fake && vsystem("./%s %s POST-INSTALL", INSTALL_FNAME, PkgName)) {
   	    warnx("install script returned error status");
 ! 	    unlink(INSTALL_FNAME);
   	    code = 1;
   	    goto fail;
   	}
 ! 	unlink(INSTALL_FNAME);
       }
   
       /* Time to record the deed? */
 --- 372,388 ----
       }
   
       /* Run the installation script one last time? */
 !     if (!NoInstall && fexists(post_script)) {
 ! 	vsystem("chmod +x %s", post_script);	/* make sure */
   	if (Verbose)
 ! 	    printf("Running post-install for %s..\n", PkgName);
 ! 	if (!Fake && vsystem("./%s %s %s", post_script, PkgName, post_arg)) {
   	    warnx("install script returned error status");
 ! 	    unlink(post_script);
   	    code = 1;
   	    goto fail;
   	}
 ! 	unlink(post_script);
       }
   
       /* Time to record the deed? */
 ***************
 *** 389,394 ****
 --- 413,420 ----
   	vsystem("chmod a+rx %s", LogDir);
   	if (fexists(DEINSTALL_FNAME))
   	    move_file(".", DEINSTALL_FNAME, LogDir);
 + 	if (fexists(POST_DEINSTALL_FNAME))
 + 	    move_file(".", POST_DEINSTALL_FNAME, LogDir);
   	if (fexists(REQUIRE_FNAME))
   	    move_file(".", REQUIRE_FNAME, LogDir);
   	sprintf(contents, "%s/%s", LogDir, CONTENTS_FNAME);
 diff -cr /usr/src/usr.sbin/pkg_install/add/pkg_add.1 pkg_install/add/pkg_add.1
 *** /usr/src/usr.sbin/pkg_install/add/pkg_add.1	Tue Jul 14 04:27:58 1998
 --- pkg_install/add/pkg_add.1	Fri Dec 11 19:07:23 1998
 ***************
 *** 48,57 ****
   You are advised to verify the competence and identity of those who
   provide installable package files.  For extra protection, use the
   .Fl M
 ! flag to extract the package file, and inspect its contents and scripts
 ! to insure it poses no danger to your system's integrity.  Pay particular
 ! attention to any +INSTALL, +DEINSTALL, +REQUIRE or +MTREE_DIRS files,
 ! and inspect the +CONTENTS file for
   .Cm @cwd ,
   .Cm @mode 
   (check for setuid),
 --- 48,57 ----
   You are advised to verify the competence and identity of those who
   provide installable package files.  For extra protection, use the
   .Fl M
 ! flag to extract the package file, and inspect its contents and scripts to
 ! insure it poses no danger to your system's integrity.  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),
 ***************
 *** 78,84 ****
   .It Fl v
   Turn on verbose output.
   .It Fl I
 ! If an installation script exists for a given package, do not execute it.
   .It Fl n
   Don't actually install a package, just report the steps that
   would be taken if it was.
 --- 78,85 ----
   .It Fl v
   Turn on verbose output.
   .It Fl I
 ! If a installation scripts (pre-install or post-install) exist for a given
 ! package, do not execute them.
   .It Fl n
   Don't actually install a package, just report the steps that
   would be taken if it was.
 ***************
 *** 197,203 ****
   .Ef
   ftp.
   .Sh TECHNICAL DETAILS
 ! .Nm Pkg_add
   is fairly simple.  It extracts each package's "packing list"
   into a special staging directory, parses it,
   and then runs through the following sequence to fully extract the contents:
 --- 198,204 ----
   .Ef
   ftp.
   .Sh TECHNICAL DETAILS
 ! .Nm pkg_add
   is fairly simple.  It extracts each package's "packing list"
   into a special staging directory, parses it,
   and then runs through the following sequence to fully extract the contents:
 ***************
 *** 244,261 ****
   keyword denotes this as an installation requirements check (useful if
   you want to have one script serving multiple functions).
   .It
 ! If an
 ! .Ar install
 ! script exists for the package, it is then executed with the following arguments:
   .Bd -filled -offset indent -compact
   .Ar pkg-name
 ! .Ar PRE-INSTALL 
   .Ed
   where
   .Ar pkg-name
   is the name of the package in question and
   .Ar PRE-INSTALL
   is a keyword denoting this as the preinstallation phase.
   .It
   If
   .Cm @option extract-in-place
 --- 245,276 ----
   keyword denotes this as an installation requirements check (useful if
   you want to have one script serving multiple functions).
   .It
 ! If a
 ! .Ar pre-install
 ! script exists for the package, it is then executed with the following
 ! arguments:
   .Bd -filled -offset indent -compact
 + .Cm script
   .Ar pkg-name
 ! .Ar PRE-INSTALL
   .Ed
 + 
   where
   .Ar pkg-name
   is the name of the package in question and
   .Ar PRE-INSTALL
   is a keyword denoting this as the preinstallation phase.
 + 
 + .Cm Note:
 + The
 + .Ar PRE-INSTALL
 + keyword will not appear if separate scripts for pre-install and post-install
 + are given during package creation time (using the
 + .Cm Fl i
 + and 
 + .Cm Fl I
 + flags to 
 + .Xr pkg_create 1 ).
   .It
   If
   .Cm @option extract-in-place
 ***************
 *** 289,305 ****
   .Cm @cwd
   directive within this package.
   .It
 ! If an
 ! .Ar install
   script exists for the package, it is then executed as 
   .Bd -filled -offset indent -compact
   .Cm script
   .Ar pkg-name
   .Ar POST-INSTALL 
   .Ed
 ! This all allows you to write a single
   .Ar install
 ! script that does both ``before and after'' actions.
   .It
   After installation is complete, a copy of the packing list,
   .Ar deinstall
 --- 304,342 ----
   .Cm @cwd
   directive within this package.
   .It
 ! If a
 ! .Ar post-install
   script exists for the package, it is then executed as 
   .Bd -filled -offset indent -compact
   .Cm script
   .Ar pkg-name
   .Ar POST-INSTALL 
   .Ed
 ! where
 ! .Ar pkg-name
 ! is the name of the package in question and
 ! .Ar POST-INSTALL
 ! is a keyword denoting this as the post-installation phase.
 ! 
 ! .Cm Note:
 ! The
 ! .Ar POST-INSTALL
 ! keyword will not appear if separate scripts for pre-install and post-install
 ! are given during package creation time (using the
 ! .Cm Fl i
 ! and 
 ! .Cm Fl I
 ! flags to 
 ! .Xr pkg_create 1 ).
 ! 
 ! Reasoning behind passing keywords such as
 ! .Ar POST-INSTALL
 ! and
 ! .Ar PRE-INSTALL
 ! is that this allows you to write a single
   .Ar install
 ! script that does both ``before and after'' actions. But, separating the
 ! functionality is more advantageous and easier from a maintainence viewpoint.
   .It
   After installation is complete, a copy of the packing list,
   .Ar deinstall
 diff -cr /usr/src/usr.sbin/pkg_install/create/create.h pkg_install/create/create.h
 *** /usr/src/usr.sbin/pkg_install/create/create.h	Wed Oct  8 03:46:19 1997
 --- pkg_install/create/create.h	Fri Dec 11 17:25:19 1998
 ***************
 *** 28,34 ****
 --- 28,36 ----
   extern char	*Desc;
   extern char	*Display;
   extern char	*Install;
 + extern char	*PostInstall;
   extern char	*DeInstall;
 + extern char	*PostDeInstall;
   extern char	*Contents;
   extern char	*Require;
   extern char	*SrcDir;
 diff -cr /usr/src/usr.sbin/pkg_install/create/main.c pkg_install/create/main.c
 *** /usr/src/usr.sbin/pkg_install/create/main.c	Wed Oct  8 03:46:23 1997
 --- pkg_install/create/main.c	Fri Dec 11 17:32:43 1998
 ***************
 *** 18,24 ****
   #include "lib.h"
   #include "create.h"
   
 ! static char Options[] = "YNOhvf:p:P:c:d:i:k:r:t:X:D:m:s:";
   
   char	*Prefix		= NULL;
   char	*Comment        = NULL;
 --- 18,24 ----
   #include "lib.h"
   #include "create.h"
   
 ! static char Options[] = "YNOhvf:p:P:c:d:i:I:k:K:r:t:X:D:m:s:";
   
   char	*Prefix		= NULL;
   char	*Comment        = NULL;
 ***************
 *** 26,32 ****
 --- 26,34 ----
   char	*SrcDir		= NULL;
   char	*Display	= NULL;
   char	*Install	= NULL;
 + char	*PostInstall	= NULL;
   char	*DeInstall	= NULL;
 + char	*PostDeInstall	= NULL;
   char	*Contents	= NULL;
   char	*Require	= NULL;
   char	*ExcludeFrom	= NULL;
 ***************
 *** 87,96 ****
 --- 89,106 ----
   	    Install = optarg;
   	    break;
   
 + 	case 'I':
 + 	    PostInstall = optarg;
 + 	    break;
 + 
   	case 'k':
   	    DeInstall = optarg;
   	    break;
   
 + 	case 'K':
 + 	    PostDeInstall = optarg;
 + 	    break;
 + 
   	case 'r':
   	    Require = optarg;
   	    break;
 ***************
 *** 151,160 ****
   static void
   usage()
   {
 !     fprintf(stderr, "%s\n%s\n%s\n%s\n",
   "usage: pkg_create [-YNOhv] [-P pkgs] [-p prefix] [-f contents] [-i iscript]",
 ! "                  [-k dscript] [-r rscript] [-t template] [-X excludefile]",
 ! "                  [-D displayfile] [-m mtreefile] -c comment -d description",
 ! "                  -f packlist pkg-name");
       exit(1);
   }
 --- 161,171 ----
   static void
   usage()
   {
 !     fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
   "usage: pkg_create [-YNOhv] [-P pkgs] [-p prefix] [-f contents] [-i iscript]",
 ! "                  [-I piscript] [-k dscript] [-K pdscript] [-r rscript] ",
 ! "                  [-t template] [-X excludefile] [-D displayfile] ",
 ! "                  [-m mtreefile] -c comment -d description -f packlist ",
 ! "                  pkg-name");
       exit(1);
   }
 diff -cr /usr/src/usr.sbin/pkg_install/create/perform.c pkg_install/create/perform.c
 *** /usr/src/usr.sbin/pkg_install/create/perform.c	Sun Dec  6 19:04:05 1998
 --- pkg_install/create/perform.c	Fri Dec 11 16:48:45 1998
 ***************
 *** 156,166 ****
 --- 156,176 ----
   	add_plist(&plist, PLIST_IGNORE, NULL);
   	add_plist(&plist, PLIST_FILE, INSTALL_FNAME);
       }
 +     if (PostInstall) {
 + 	copy_file(home, PostInstall, POST_INSTALL_FNAME);
 + 	add_plist(&plist, PLIST_IGNORE, NULL);
 + 	add_plist(&plist, PLIST_FILE, POST_INSTALL_FNAME);
 +     }
       if (DeInstall) {
   	copy_file(home, DeInstall, DEINSTALL_FNAME);
   	add_plist(&plist, PLIST_IGNORE, NULL);
   	add_plist(&plist, PLIST_FILE, DEINSTALL_FNAME);
       }
 +     if (PostDeInstall) {
 + 	copy_file(home, PostDeInstall, POST_DEINSTALL_FNAME);
 + 	add_plist(&plist, PLIST_IGNORE, NULL);
 + 	add_plist(&plist, PLIST_FILE, POST_DEINSTALL_FNAME);
 +     }
       if (Require) {
   	copy_file(home, Require, REQUIRE_FNAME);
   	add_plist(&plist, PLIST_IGNORE, NULL);
 ***************
 *** 270,277 ****
 --- 280,291 ----
   
       if (Install)
   	fprintf(totar, "%s\n", INSTALL_FNAME);
 +     if (PostInstall)
 + 	fprintf(totar, "%s\n", POST_INSTALL_FNAME);
       if (DeInstall)
   	fprintf(totar, "%s\n", DEINSTALL_FNAME);
 +     if (PostDeInstall)
 + 	fprintf(totar, "%s\n", POST_DEINSTALL_FNAME);
       if (Require)
   	fprintf(totar, "%s\n", REQUIRE_FNAME);
       if (Display)
 diff -cr /usr/src/usr.sbin/pkg_install/create/pkg_create.1 pkg_install/create/pkg_create.1
 *** /usr/src/usr.sbin/pkg_install/create/pkg_create.1	Fri Jun 26 03:15:37 1998
 --- pkg_install/create/pkg_create.1	Fri Dec 11 18:54:23 1998
 ***************
 *** 36,42 ****
 --- 36,44 ----
   .Op Fl p Ar prefix
   .Op Fl f Ar contents
   .Op Fl i Ar iscript
 + .Op Fl I Ar piscript
   .Op Fl k Ar dscript
 + .Op Fl K Ar pdscript
   .Op Fl r Ar rscript
   .Op Fl s Ar srcdir
   .Op Fl t Ar template
 ***************
 *** 102,110 ****
   .It Fl i Ar iscript
   Set
   .Ar iscript
 ! to be the install procedure for the package.  This can be any
   executable program (or shell script).  It will be invoked automatically
 ! when the package is later installed.
   .It Fl P Ar pkgs
   Set the initial package dependency list to
   .Ar pkgs .
 --- 104,131 ----
   .It Fl i Ar iscript
   Set
   .Ar iscript
 ! to be the pre-install procedure for the package.  This can be any executable
 ! program (or shell script).  It will be invoked automatically when the
 ! package is later installed. It will be passed the package's name as the
 ! first argument.
 ! 
 ! .Cm Note:
 ! if the
 ! .Cm Fl I
 ! option is not given, this script will serve as both the pre-install and the
 ! post-install script for the package, differentiating between the
 ! functionality by passing the keywords
 ! .Ar PRE-INSTALL
 ! and
 ! .Ar POST-INSTALL
 ! respectively, along with the package's name.
 ! .It Fl I Ar piscript
 ! Set
 ! .Ar piscript
 ! to be the post-install procedure for the package.  This can be any
   executable program (or shell script).  It will be invoked automatically
 ! when the package is later installed. It will be passed the package's name as
 ! the first argument.
   .It Fl P Ar pkgs
   Set the initial package dependency list to
   .Ar pkgs .
 ***************
 *** 120,128 ****
   .It Fl k Ar dscript
   Set
   .Ar dscript
 ! to be the de-install procedure for the package.  This can be any
 ! executable program (or shell script).  It will be invoked automatically
 ! when the package is later (if ever) de-installed.
   .It Fl r Ar rscript
   Set
   .Ar rscript
 --- 141,169 ----
   .It Fl k Ar dscript
   Set
   .Ar dscript
 ! to be the de-install procedure for the package.  This can be any executable
 ! program (or shell script).  It will be invoked automatically when the
 ! package is later (if ever) de-installed. It will be passed the package's
 ! name as the first argument.
 ! 
 ! .Cm Note:
 ! if the
 ! .Cm Fl K
 ! option is not given, this script will serve as both the de-install and the
 ! post-deinstall script for the package, differentiating between the
 ! functionality by passing the keywords
 ! .Ar DEINSTALL
 ! and
 ! .Ar POST-DEINSTALL
 ! respectively, along with the package's name.
 ! .It Fl K Ar pdscript
 ! Set
 ! .Ar pdscript
 ! to be the post-deinstall procedure for the package.  This can be any
 ! executable program (or shell script).  It will be invoked automatically when
 ! the package is later de-installed. It will be passed the package's name as
 ! the first argument.
 ! 
   .It Fl r Ar rscript
   Set
   .Ar rscript
 diff -cr /usr/src/usr.sbin/pkg_install/delete/perform.c pkg_install/delete/perform.c
 *** /usr/src/usr.sbin/pkg_install/delete/perform.c	Wed Nov 11 18:18:25 1998
 --- pkg_install/delete/perform.c	Fri Dec 11 17:30:50 1998
 ***************
 *** 54,59 ****
 --- 54,64 ----
       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,83 ****
 --- 71,92 ----
   
       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,115 ****
 --- 102,130 ----
   	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,154 ****
   		return 1;
   	}
       }
 !     if (!NoDeInstall && fexists(DEINSTALL_FNAME)) {
   	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)) {
   		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 (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;
 --- 136,216 ----
   		return 1;
   	}
       }
 ! 
 !     /* 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", 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 -cr /usr/src/usr.sbin/pkg_install/delete/pkg_delete.1 pkg_install/delete/pkg_delete.1
 *** /usr/src/usr.sbin/pkg_install/delete/pkg_delete.1	Mon Mar 23 03:27:25 1998
 --- pkg_install/delete/pkg_delete.1	Fri Dec 11 19:16:50 1998
 ***************
 *** 47,55 ****
   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
   .Cm @cwd ,
   .Cm @mode 
   (check for setuid),
 --- 47,55 ----
   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, +POST-INSTALL, +DEINSTALL,
 ! +POST-DEINSTALL, +REQUIRE or +MTREE_DIRS files, and inspect the +CONTENTS
 ! file for
   .Cm @cwd ,
   .Cm @mode 
   (check for setuid),
 ***************
 *** 97,103 ****
   
   .Pp
   .Sh TECHNICAL DETAILS
 ! .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.
 --- 97,103 ----
   
   .Pp
   .Sh TECHNICAL DETAILS
 ! .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,153 ****
   .Nm deinstall
   script is called as:
   .Bd -filled -offset indent -compact
 ! .Cm deinstall
   .Ar <pkg-name>
   .Ar DEINSTALL
   .Ed
 ! Passing the keyword
   .Ar DEINSTALL
 ! lets you potentially write only one program/script that handles all
 ! aspects of installation and deletion.
   .Pp
   All scripts are called with the environment variable
   .Ev PKG_PREFIX
 --- 140,210 ----
   .Nm deinstall
   script is called as:
   .Bd -filled -offset indent -compact
 ! .Cm script
   .Ar <pkg-name>
   .Ar DEINSTALL
   .Ed
 ! 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
 ! 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
 diff -cr /usr/src/usr.sbin/pkg_install/info/perform.c pkg_install/info/perform.c
 *** /usr/src/usr.sbin/pkg_install/info/perform.c	Fri Sep 11 03:26:58 1998
 --- pkg_install/info/perform.c	Fri Dec 11 17:18:56 1998
 ***************
 *** 179,186 ****
 --- 179,190 ----
   	    show_plist("Packing list:\n", &plist, (plist_t)-1);
   	if ((Flags & SHOW_INSTALL) && fexists(INSTALL_FNAME))
   	    show_file("Install script:\n", INSTALL_FNAME);
 + 	if ((Flags & SHOW_INSTALL) && fexists(POST_INSTALL_FNAME))
 + 	    show_file("Post-Install script:\n", POST_INSTALL_FNAME);
   	if ((Flags & SHOW_DEINSTALL) && fexists(DEINSTALL_FNAME))
   	    show_file("De-Install script:\n", DEINSTALL_FNAME);
 + 	if ((Flags & SHOW_DEINSTALL) && fexists(POST_DEINSTALL_FNAME))
 + 	    show_file("Post-DeInstall script:\n", POST_DEINSTALL_FNAME);
   	if ((Flags & SHOW_MTREE) && fexists(MTREE_FNAME))
   	    show_file("mtree file:\n", MTREE_FNAME);
   	if (Flags & SHOW_PREFIX)
 diff -cr /usr/src/usr.sbin/pkg_install/lib/lib.h pkg_install/lib/lib.h
 *** /usr/src/usr.sbin/pkg_install/lib/lib.h	Mon Feb 16 12:16:47 1998
 --- pkg_install/lib/lib.h	Fri Dec 11 16:46:22 1998
 ***************
 *** 66,72 ****
 --- 66,74 ----
   #define COMMENT_FNAME		"+COMMENT"
   #define DESC_FNAME		"+DESC"
   #define INSTALL_FNAME		"+INSTALL"
 + #define POST_INSTALL_FNAME	"+POST-INSTALL"
   #define DEINSTALL_FNAME		"+DEINSTALL"
 + #define POST_DEINSTALL_FNAME	"+POST-DEINSTALL"
   #define REQUIRE_FNAME		"+REQUIRE"
   #define REQUIRED_BY_FNAME	"+REQUIRED_BY"
   #define DISPLAY_FNAME		"+DISPLAY"
 
State-Changed-From-To: open->closed 
State-Changed-By: jkh 
State-Changed-When: Mon Feb 1 11:11:53 PST 1999 
State-Changed-Why:  
This was committed. 
>Unformatted:
