summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/pkg_install/README5
-rw-r--r--usr.sbin/pkg_install/add/add.h3
-rw-r--r--usr.sbin/pkg_install/add/extract.c85
-rw-r--r--usr.sbin/pkg_install/add/futil.c38
-rw-r--r--usr.sbin/pkg_install/add/main.c9
-rw-r--r--usr.sbin/pkg_install/add/perform.c129
-rw-r--r--usr.sbin/pkg_install/create/create.h4
-rw-r--r--usr.sbin/pkg_install/create/main.c20
-rw-r--r--usr.sbin/pkg_install/create/perform.c16
-rw-r--r--usr.sbin/pkg_install/create/pl.c133
-rw-r--r--usr.sbin/pkg_install/delete/delete.h4
-rw-r--r--usr.sbin/pkg_install/delete/main.c27
-rw-r--r--usr.sbin/pkg_install/delete/perform.c90
-rw-r--r--usr.sbin/pkg_install/info/info.h23
-rw-r--r--usr.sbin/pkg_install/info/main.c26
-rw-r--r--usr.sbin/pkg_install/info/perform.c12
-rw-r--r--usr.sbin/pkg_install/info/pkg_info.1147
-rw-r--r--usr.sbin/pkg_install/info/show.c28
-rw-r--r--usr.sbin/pkg_install/lib/exec.c20
-rw-r--r--usr.sbin/pkg_install/lib/file.c22
-rw-r--r--usr.sbin/pkg_install/lib/lib.h12
-rw-r--r--usr.sbin/pkg_install/lib/plist.c73
-rwxr-xr-xusr.sbin/pkg_install/tkpkg32
23 files changed, 782 insertions, 176 deletions
diff --git a/usr.sbin/pkg_install/README b/usr.sbin/pkg_install/README
index dd42917cec0a..dabd52a8a2fd 100644
--- a/usr.sbin/pkg_install/README
+++ b/usr.sbin/pkg_install/README
@@ -2,4 +2,7 @@ This is the pkg_install suite of tools for doing maintainance of
software "packages". More documentation is available in the man pages
for each individual command.
-This is pkg_install version 0.5.
+This code was written by Jordan Hubbard for FreeBSD, snatched and
+mildly reshaped by John Kohl in NetBSD and the changes taken back into
+FreeBSD again by Jordan. Whee! :-)
+
diff --git a/usr.sbin/pkg_install/add/add.h b/usr.sbin/pkg_install/add/add.h
index 019fc925737f..5bbaa2e9ebdc 100644
--- a/usr.sbin/pkg_install/add/add.h
+++ b/usr.sbin/pkg_install/add/add.h
@@ -1,4 +1,4 @@
-/* $Id: add.h,v 1.4 1993/09/04 05:06:25 jkh Exp $ */
+/* $Id: add.h,v 1.3 1993/09/05 04:53:47 jkh Exp $ */
/*
* FreeBSD install - a package for the installation and maintainance
@@ -28,6 +28,7 @@ typedef enum { NORMAL, MASTER, SLAVE } add_mode_t;
extern char *Prefix;
extern Boolean NoInstall;
extern Boolean NoRecord;
+extern Boolean Force;
extern char *Mode;
extern char *Owner;
extern char *Group;
diff --git a/usr.sbin/pkg_install/add/extract.c b/usr.sbin/pkg_install/add/extract.c
index d5db041e6a06..6a48ba6d4598 100644
--- a/usr.sbin/pkg_install/add/extract.c
+++ b/usr.sbin/pkg_install/add/extract.c
@@ -1,5 +1,5 @@
#ifndef lint
-static const char *rcsid = "$Id: extract.c,v 1.4 1993/09/06 23:26:21 jkh Exp $";
+static const char *rcsid = "$Id: extract.c,v 1.5 1993/09/18 03:38:47 jkh Exp $";
#endif
/*
@@ -25,11 +25,49 @@ static const char *rcsid = "$Id: extract.c,v 1.4 1993/09/06 23:26:21 jkh Exp $";
#include "lib.h"
#include "add.h"
+
+#define STARTSTRING "tar cf -"
+#define TOOBIG(str) ((strlen(str) + 6 + strlen(home) + where_count > maxargs) \
+ || (strlen(str) + 6 + strlen(home) + perm_count > maxargs))
+
+#define PUSHOUT(todir) /* push out string */ \
+ if (strlen(where_args) > sizeof(STARTSTRING)-1) { \
+ strcat(where_args, "|tar xpf - -C "); \
+ strcat(where_args, todir); \
+ if (system(where_args)) \
+ barf("can't invoke tar pipeline"); \
+ strcpy(where_args, STARTSTRING); \
+ where_count = sizeof(STARTSTRING)-1; \
+ } \
+ if (perm_count) { \
+ apply_perms(todir, perm_args); \
+ perm_args[0] = 0;\
+ perm_count = 0; \
+ }
+
void
extract_plist(char *home, Package *pkg)
{
PackingList p = pkg->head;
char *last_file;
+ char *where_args, *perm_args, *last_chdir;
+ int maxargs, where_count = 0, perm_count = 0, add_count;
+
+ maxargs = sysconf(_SC_ARG_MAX);
+ maxargs -= 64; /* some slop for the tar cmd text,
+ and sh -c */
+ where_args = malloc(maxargs);
+ if (!where_args)
+ barf("can't get argument list space");
+ perm_args = malloc(maxargs);
+ if (!perm_args)
+ barf("can't get argument list space");
+
+ strcpy(where_args, STARTSTRING);
+ where_count = sizeof(STARTSTRING)-1;
+ perm_args[0] = 0;
+
+ last_chdir = 0;
/* Reset the world */
Owner = NULL;
@@ -58,15 +96,49 @@ extract_plist(char *home, Package *pkg)
/* first try to rename it into place */
sprintf(try, "%s/%s", Directory, p->name);
- if (rename(p->name, try) == FAIL)
- copy_hierarchy(Directory, p->name, TRUE);
- apply_perms(Directory, p->name);
+ if (rename(p->name, try) == 0) {
+ /* try to add to list of perms to be changed,
+ and run in bulk. */
+ add_count = snprintf(&perm_args[perm_count],
+ maxargs - perm_count,
+ "%s ", p->name);
+ if (add_count > maxargs - perm_count)
+ barf("oops, miscounted strings!");
+ perm_count += add_count;
+ if (p->name[0] == '/') {
+ PUSHOUT(Directory);
+ }
+ } else {
+ /* rename failed, try copying with a big tar command */
+ if (p->name[0] == '/' ||
+ TOOBIG(p->name) ||
+ last_chdir != Directory) {
+ PUSHOUT(last_chdir);
+ last_chdir = Directory;
+ }
+ add_count = snprintf(&where_args[where_count],
+ maxargs - where_count,
+ " %s", p->name);
+ if (add_count > maxargs - where_count)
+ barf("oops, miscounted strings!");
+ where_count += add_count;
+ add_count = snprintf(&perm_args[perm_count],
+ maxargs - perm_count,
+ "%s ", p->name);
+ if (add_count > maxargs - perm_count)
+ barf("oops, miscounted strings!");
+ perm_count += add_count;
+ if (p->name[0] == '/') {
+ PUSHOUT(Directory);
+ }
+ }
}
break;
case PLIST_CWD:
if (Verbose)
printf("extract: CWD to %s\n", p->name);
+ PUSHOUT(Directory);
if (strcmp(p->name, ".")) {
if (!Fake && make_hierarchy(p->name) == FAIL)
barf("Unable make directory '%s'.", p->name);
@@ -78,6 +150,7 @@ extract_plist(char *home, Package *pkg)
case PLIST_CMD:
format_cmd(cmd, p->name, Directory, last_file);
+ PUSHOUT(Directory);
if (Verbose)
printf("extract: execute '%s'\n", cmd);
if (!Fake && system(cmd))
@@ -85,14 +158,17 @@ extract_plist(char *home, Package *pkg)
break;
case PLIST_CHMOD:
+ PUSHOUT(Directory);
Mode = p->name;
break;
case PLIST_CHOWN:
+ PUSHOUT(Directory);
Owner = p->name;
break;
case PLIST_CHGRP:
+ PUSHOUT(Directory);
Group = p->name;
break;
@@ -105,4 +181,5 @@ extract_plist(char *home, Package *pkg)
}
p = p->next;
}
+ PUSHOUT(Directory);
}
diff --git a/usr.sbin/pkg_install/add/futil.c b/usr.sbin/pkg_install/add/futil.c
index 423f69694427..3bda0b449480 100644
--- a/usr.sbin/pkg_install/add/futil.c
+++ b/usr.sbin/pkg_install/add/futil.c
@@ -1,5 +1,5 @@
#ifndef lint
-static const char *rcsid = "$Id: futil.c,v 1.4 1993/09/04 05:06:27 jkh Exp $";
+static const char *rcsid = "$Id: futil.c,v 1.2 1993/09/03 23:00:34 jkh Exp $";
#endif
/*
@@ -62,25 +62,33 @@ make_hierarchy(char *dir)
/* Using permission defaults, apply them as necessary */
void
-apply_perms(char *dir, char *file)
+apply_perms(char *dir, char *arg)
{
- char fname[FILENAME_MAX];
+ char *cd_to;
- if (!dir || *file == '/') /* absolute path? */
- strcpy(fname, file);
+ if (!dir || *arg == '/') /* absolute path? */
+ cd_to = "/";
else
- sprintf(fname, "%s/%s", dir, file);
+ cd_to = dir;
+
if (Mode)
- if (vsystem("chmod -R %s %s", Mode, fname))
- whinge("Couldn't change mode of '%s' to '%s'.",
- fname, Mode);
- if (Owner)
- if (vsystem("chown -R %s %s", Owner, fname))
+ if (vsystem("cd %s && chmod -R %s %s", cd_to, Mode, arg))
+ whinge("Couldn't change modes of '%s' to '%s'.",
+ arg, Mode);
+ if (Owner && Group) {
+ if (vsystem("cd %s && chown -R %s.%s %s", cd_to, Owner, Group, arg))
+ whinge("Couldn't change owner/group of '%s' to '%s.%s'.",
+ arg, Owner, Group);
+ return;
+ }
+ if (Owner) {
+ if (vsystem("cd %s && chown -R %s %s", cd_to, Owner, arg))
whinge("Couldn't change owner of '%s' to '%s'.",
- fname, Owner);
- if (Group)
- if (vsystem("chgrp -R %s %s", Group, fname))
+ arg, Owner);
+ return;
+ } else if (Group)
+ if (vsystem("cd %s && chgrp -R %s %s", cd_to, Group, arg))
whinge("Couldn't change group of '%s' to '%s'.",
- fname, Group);
+ arg, Group);
}
diff --git a/usr.sbin/pkg_install/add/main.c b/usr.sbin/pkg_install/add/main.c
index 710fd7021a29..341b700b46eb 100644
--- a/usr.sbin/pkg_install/add/main.c
+++ b/usr.sbin/pkg_install/add/main.c
@@ -1,5 +1,5 @@
#ifndef lint
-static char *rcsid = "$Id: main.c,v 1.3 1993/09/05 04:53:49 jkh Exp $";
+static char *rcsid = "$Id: main.c,v 1.4 1993/09/14 19:53:01 jkh Exp $";
#endif
/*
@@ -26,11 +26,12 @@ static char *rcsid = "$Id: main.c,v 1.3 1993/09/05 04:53:49 jkh Exp $";
#include "lib.h"
#include "add.h"
-static char Options[] = "hvIRnp:SMt:";
+static char Options[] = "hvIRfnp:SMt:";
char *Prefix = NULL;
Boolean NoInstall = FALSE;
Boolean NoRecord = FALSE;
+Boolean Force = FALSE;
char *Mode = NULL;
char *Owner = NULL;
@@ -66,6 +67,10 @@ main(int argc, char **argv)
NoRecord = TRUE;
break;
+ case 'f':
+ Force = TRUE;
+ break;
+
case 'n':
Fake = TRUE;
Verbose = TRUE;
diff --git a/usr.sbin/pkg_install/add/perform.c b/usr.sbin/pkg_install/add/perform.c
index 684a8187068b..f5f5f07ca9c3 100644
--- a/usr.sbin/pkg_install/add/perform.c
+++ b/usr.sbin/pkg_install/add/perform.c
@@ -1,5 +1,5 @@
#ifndef lint
-static const char *rcsid = "$Id: perform.c,v 1.11 1994/10/14 05:43:41 jkh Exp $";
+static const char *rcsid = "$Id: perform.c,v 1.12 1994/11/17 10:53:21 jkh Exp $";
#endif
/*
@@ -26,6 +26,7 @@ static const char *rcsid = "$Id: perform.c,v 1.11 1994/10/14 05:43:41 jkh Exp $"
#include "add.h"
#include <signal.h>
+#include <sys/wait.h>
static int pkg_do(char *);
static int sanity_check(char *);
@@ -131,14 +132,40 @@ pkg_do(char *pkg)
setenv(PKG_PREFIX_VNAME,
(p = find_plist(&Plist, PLIST_CWD)) ? p->name : NULL, 1);
PkgName = (p = find_plist(&Plist, PLIST_NAME)) ? p->name : "anonymous";
+ /* Protect against old packages with bogus @name fields */
+ sprintf(LogDir, "%s/%s", LOG_DIR, basename_of(PkgName));
+ if (isdir(LogDir)) {
+ whinge("Package `%s' already recorded as installed.\n", PkgName);
+ code = 1;
+ goto success; /* close enough for government work */
+ }
+ for (p = Plist.head; p ; p = p->next) {
+ if (p->type != PLIST_PKGDEP)
+ continue;
+ if (Verbose)
+ printf("Checking dependency on package list `%s'\n", p->name);
+ if (!Fake && vsystem("pkg_info -e %s", p->name)) {
+ whinge("Package `%s' depends on missing package `%s'%s.", PkgName,
+ p->name, Force ? " (proceeding anyway)" : "");
+ if (!Force)
+ code++;
+ }
+ }
+ if (code != 0)
+ goto success; /* close enough for government work */
+
if (fexists(REQUIRE_FNAME)) {
vsystem("chmod +x %s", REQUIRE_FNAME); /* be sure */
if (Verbose)
printf("Running requirements file first for %s..\n", PkgName);
if (!Fake && vsystem("./%s %s INSTALL", REQUIRE_FNAME, PkgName)) {
- whinge("Package %s fails requirements - not installed.",
- pkg_fullname);
- return 1;
+ whinge("Package %s fails requirements %s",
+ pkg_fullname,
+ Force ? "installing anyway" : "- not installed.");
+ if (!Force) {
+ code = 1;
+ goto success; /* close enough for government work */
+ }
}
}
if (!NoInstall && fexists(INSTALL_FNAME)) {
@@ -147,15 +174,65 @@ pkg_do(char *pkg)
printf("Running install with PRE-INSTALL for %s..\n", PkgName);
if (!Fake && vsystem("./%s %s PRE-INSTALL", INSTALL_FNAME, PkgName)) {
whinge("Install script returned error status.");
- goto fail;
+ code = 1;
+ goto success; /* nothing to uninstall yet */
}
}
extract_plist(home, &Plist);
+ if (!NoInstall && fexists(MTREE_FNAME)) {
+ if (Verbose)
+ printf("Running mtree for %s..\n", PkgName);
+ p = find_plist(&Plist, PLIST_CWD);
+ if (Verbose)
+ printf("mtree -u -f %s -d -e -p %s\n", MTREE_FNAME,
+ p ? p->name : "/");
+ if (!Fake) {
+ pid_t chpid;
+ int rval, status;
+ chpid = fork();
+ if (chpid == 0) {
+ execl("/usr/sbin/mtree", "mtree", "-u", "-f", MTREE_FNAME,
+ "-d", "-e", "-p", p ? p->name : "/");
+ perror("cannot execute mtree");
+ exit(3);
+ }
+ if (chpid == (pid_t) -1) {
+ warn("Cannot fork mtree");
+ code = 1;
+ goto fail;
+ }
+ if (waitpid(chpid, &status, 0) == -1) {
+ warn("Cannot wait for mtree");
+ code = 1;
+ goto fail;
+ }
+ if (!WIFEXITED(status)) {
+ whinge("Strange exit from mtree: %x", status);
+ code = 1;
+ goto fail;
+ }
+#ifdef DEBUG
+ whinge("mtree exits %d\n", WEXITSTATUS(status));
+#endif
+ switch (WEXITSTATUS(status)) {
+ case 0:
+ break; /* normal */
+ case 2:
+ whinge("\nWARNING: Mtree attempted some work which may not have completed.\n\tExamine the above output.\n\t(most likely it changed directory permissions)\n");
+ break;
+ default:
+ whinge("Error status %d from mtree.", WEXITSTATUS(status));
+ code = 1;
+ goto fail;
+ }
+ }
+ }
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)) {
whinge("Install script returned error status.");
+ code = 1;
goto fail;
}
}
@@ -163,6 +240,7 @@ pkg_do(char *pkg)
char contents[FILENAME_MAX];
FILE *cfile;
+ umask(022);
if (getuid() != 0)
whinge("Not running as root - trying to record install anyway.");
if (!PkgName) {
@@ -198,15 +276,50 @@ pkg_do(char *pkg)
fclose(cfile);
copy_file(".", DESC_FNAME, LogDir);
copy_file(".", COMMENT_FNAME, LogDir);
+ if (fexists(DISPLAY_FNAME))
+ copy_file(".", DISPLAY_FNAME, LogDir);
+ for (p = Plist.head; p ; p = p->next) {
+ if (p->type != PLIST_PKGDEP)
+ continue;
+ if (Verbose)
+ printf("Attempting to record dependency on package `%s'\n",
+ p->name);
+ sprintf(contents, "%s/%s/%s", LOG_DIR, basename_of(p->name),
+ REQUIRED_BY_FNAME);
+ cfile = fopen(contents, "a");
+ if (!cfile) {
+ whinge("Can't open dependency file '%s'!\n\tDependency registration incomplete.",
+ contents);
+ continue;
+ }
+ fprintf(cfile, "%s\n", basename_of(PkgName));
+ if (fclose(cfile) == EOF)
+ warn("Cannot properly close file %s", contents);
+ }
if (Verbose)
printf("Package %s registered in %s\n", PkgName, LogDir);
}
+
+ if (p = find_plist(&Plist, PLIST_DISPLAY)) {
+ FILE *fp;
+ char buf[BUFSIZ];
+ fp = fopen(p->name, "r");
+ if (fp) {
+ putc('\n', stdout);
+ while (fgets(buf, sizeof(buf), fp))
+ fputs(buf, stdout);
+ putc('\n', stdout);
+ (void) fclose(fp);
+ } else
+ warn("Cannot open display file `%s'.", p->name);
+ }
+
goto success;
fail:
- /* Nuke the whole (installed) show */
+ /* Nuke the whole (installed) show, XXX but don't clean directories */
if (!Fake)
- delete_package(FALSE, &Plist);
+ delete_package(FALSE, FALSE, &Plist);
success:
/* delete the packing list contents */
@@ -240,7 +353,7 @@ cleanup(int signo)
printf("Signal %d received, cleaning up..\n", signo);
if (Plist.head) {
if (!Fake)
- delete_package(FALSE, &Plist);
+ delete_package(FALSE, FALSE, &Plist);
free_plist(&Plist);
}
if (!Fake && LogDir[0])
diff --git a/usr.sbin/pkg_install/create/create.h b/usr.sbin/pkg_install/create/create.h
index d45c177c5c46..e0ee4ccacefa 100644
--- a/usr.sbin/pkg_install/create/create.h
+++ b/usr.sbin/pkg_install/create/create.h
@@ -1,4 +1,4 @@
-/* $Id: create.h,v 1.4 1993/09/12 20:45:28 jkh Exp $ */
+/* $Id: create.h,v 1.5 1994/05/19 18:27:38 alm Exp $ */
/*
* FreeBSD install - a package for the installation and maintainance
@@ -26,12 +26,14 @@
extern char *Prefix;
extern char *Comment;
extern char *Desc;
+extern char *Display;
extern char *Install;
extern char *DeInstall;
extern char *Contents;
extern char *Require;
extern char *PlayPen;
extern char *ExcludeFrom;
+extern char *Mtree;
extern int Dereference;
void check_list(char *, Package *);
diff --git a/usr.sbin/pkg_install/create/main.c b/usr.sbin/pkg_install/create/main.c
index e7805ca46e83..623d7d117a6d 100644
--- a/usr.sbin/pkg_install/create/main.c
+++ b/usr.sbin/pkg_install/create/main.c
@@ -1,5 +1,5 @@
#ifndef lint
-static const char *rcsid = "$Id: main.c,v 1.6 1994/04/16 21:50:53 jkh Exp $";
+static const char *rcsid = "$Id: main.c,v 1.7 1994/05/19 18:27:40 alm Exp $";
#endif
/*
@@ -16,17 +16,19 @@ static const char *rcsid = "$Id: main.c,v 1.6 1994/04/16 21:50:53 jkh Exp $";
#include "lib.h"
#include "create.h"
-static char Options[] = "YNhvf:p:c:d:i:k:r:t:X:";
+static char Options[] = "YNhvf:p:c:d:i:k:r:t:X:D:m:";
char *Prefix = NULL;
char *Comment = NULL;
char *Desc = NULL;
+char *Display = NULL;
char *Install = NULL;
char *DeInstall = NULL;
char *Contents = NULL;
char *Require = NULL;
char *PlayPen = NULL;
char *ExcludeFrom = NULL;
+char *Mtree = NULL;
int Dereference = 0;
int
@@ -91,6 +93,14 @@ main(int argc, char **argv)
Dereference = 1;
break;
+ case 'D':
+ Display = optarg;
+ break;
+
+ case 'm':
+ Mtree = optarg;
+ break;
+
case '?':
default:
usage(prog_name, NULL);
@@ -140,11 +150,15 @@ usage(const char *name, const char *fmt, ...)
fprintf(stderr, "-f file get list of files from file (- for stdin)\n");
fprintf(stderr, "-h follow symbolic links\n");
fprintf(stderr, "-i script install script\n");
- fprintf(stderr, "-p arg install prefix will be arg\n");
fprintf(stderr, "-k script de-install script\n");
+ fprintf(stderr, "-D file install notice\n");
+ fprintf(stderr, "-m file mtree spec for directories\n");
+ fprintf(stderr, "-p prefix install prefix will be arg\n");
fprintf(stderr, "-r script pre/post requirements script\n");
fprintf(stderr, "-t temp use temp as template for mktemp()\n");
fprintf(stderr, "-X file exclude files listed in file\n");
fprintf(stderr, "-v verbose\n");
+ fprintf(stderr, "-Y assume `yes' answer to all questions\n");
+ fprintf(stderr, "-N assume `no' answer to all questions\n");
exit(1);
}
diff --git a/usr.sbin/pkg_install/create/perform.c b/usr.sbin/pkg_install/create/perform.c
index 36d6d5f20265..6d15ef8e3864 100644
--- a/usr.sbin/pkg_install/create/perform.c
+++ b/usr.sbin/pkg_install/create/perform.c
@@ -1,5 +1,5 @@
#ifndef lint
-static const char *rcsid = "$Id: perform.c,v 1.12 1994/10/14 05:55:46 jkh Exp $";
+static const char *rcsid = "$Id: perform.c,v 1.13 1994/11/17 10:54:11 jkh Exp $";
#endif
/*
@@ -84,6 +84,8 @@ pkg_perform(char **pkgs)
/* Make first "real contents" pass over it */
check_list(home, &plist);
+ (void) umask(022); /* make sure gen'ed directories, files don't have
+ group or other write bits. */
copy_plist(home, &plist);
mark_plist(&plist);
@@ -111,6 +113,18 @@ pkg_perform(char **pkgs)
add_plist(&plist, PLIST_IGNORE, NULL);
add_plist(&plist, PLIST_FILE, REQUIRE_FNAME);
}
+ if (Display) {
+ copy_file(home, Display, DISPLAY_FNAME);
+ add_plist(&plist, PLIST_IGNORE, NULL);
+ add_plist(&plist, PLIST_FILE, DISPLAY_FNAME);
+ add_plist(&plist, PLIST_DISPLAY, DISPLAY_FNAME);
+ }
+ if (Mtree) {
+ copy_file(home, Mtree, MTREE_FNAME);
+ add_plist(&plist, PLIST_IGNORE, NULL);
+ add_plist(&plist, PLIST_FILE, MTREE_FNAME);
+ add_plist(&plist, PLIST_MTREE, MTREE_FNAME);
+ }
/* Run through the list again, picking up extra "local" items */
check_list(".", &plist);
diff --git a/usr.sbin/pkg_install/create/pl.c b/usr.sbin/pkg_install/create/pl.c
index 0d877795e5e8..f50bd8fb0926 100644
--- a/usr.sbin/pkg_install/create/pl.c
+++ b/usr.sbin/pkg_install/create/pl.c
@@ -1,5 +1,5 @@
#ifndef lint
-static const char *rcsid = "$Id: pl.c,v 1.4 1994/08/29 16:31:38 adam Exp $";
+static const char *rcsid = "$Id: pl.c,v 1.5 1994/11/17 10:35:04 jkh Exp $";
#endif
/*
@@ -24,6 +24,7 @@ static const char *rcsid = "$Id: pl.c,v 1.4 1994/08/29 16:31:38 adam Exp $";
#include "lib.h"
#include "create.h"
+#include <errno.h>
/* Check a list for files that require preconversion */
void
@@ -59,6 +60,35 @@ check_list(char *home, Package *pkg)
}
}
+static int
+trylink(const char *from, const char *to)
+{
+ if (link(from, to) == 0)
+ return 0;
+ if (errno == ENOENT) {
+ /* try making the container directory */
+ char *cp = strrchr(to, '/');
+ if (cp)
+ vsystem("mkdir -p %.*s", cp - to,
+ to);
+ return link(from, to);
+ }
+ return -1;
+}
+
+#define STARTSTRING "tar cf -"
+#define TOOBIG(str) strlen(str) + 6 + strlen(home) + where_count > maxargs
+#define PUSHOUT() /* push out string */ \
+ if (where_count > sizeof(STARTSTRING)-1) { \
+ strcat(where_args, "|tar xpf -"); \
+ if (system(where_args)) \
+ barf("can't invoke tar pipeline"); \
+ memset(where_args, 0, maxargs); \
+ last_chdir = NULL; \
+ strcpy(where_args, STARTSTRING); \
+ where_count = sizeof(STARTSTRING)-1; \
+ }
+
/*
* Copy unmarked files in packing list to playpen - marked files
* have already been copied in an earlier pass through the list.
@@ -68,7 +98,30 @@ copy_plist(char *home, Package *plist)
{
PackingList p = plist->head;
char *where = home;
- char *there = NULL;
+ char *there = NULL, *mythere;
+ char *where_args, *last_chdir, *root = "/";
+ int maxargs, where_count = 0, add_count;
+ struct stat stb;
+ dev_t curdir;
+
+ maxargs = sysconf(_SC_ARG_MAX);
+ maxargs -= 64; /* some slop for the tar cmd text,
+ and sh -c */
+ where_args = malloc(maxargs);
+ if (!where_args)
+ barf("can't get argument list space");
+
+ memset(where_args, 0, maxargs);
+ strcpy(where_args, STARTSTRING);
+ where_count = sizeof(STARTSTRING)-1;
+ last_chdir = 0;
+
+ if (stat(".", &stb) == 0)
+ curdir = stb.st_dev;
+ else
+ curdir = (dev_t) -1; /* It's ok if this is a valid dev_t;
+ this is just a hint for an
+ optimization. */
while (p) {
if (p->type == PLIST_CWD)
@@ -80,16 +133,84 @@ copy_plist(char *home, Package *plist)
else if (p->type == PLIST_FILE && !p->marked) {
char fn[FILENAME_MAX];
+
/* First, look for it in the "home" dir */
sprintf(fn, "%s/%s", home, p->name);
- if (fexists(fn))
- copy_hierarchy(home, p->name, FALSE);
+ if (fexists(fn)) {
+ if (lstat(fn, &stb) == 0 && stb.st_dev == curdir &&
+ S_ISREG(stb.st_mode)) {
+ /* if we can link it to the playpen, that avoids a copy
+ and saves time. */
+ if (p->name[0] != '/') {
+ /* don't link abspn stuff--it doesn't come from
+ local dir! */
+ if (trylink(fn, p->name) == 0) {
+ p = p->next;
+ continue;
+ }
+ }
+ }
+ if (TOOBIG(fn)) {
+ PUSHOUT();
+ }
+ if (p->name[0] == '/') {
+ add_count = snprintf(&where_args[where_count],
+ maxargs - where_count,
+ " %s %s",
+ last_chdir == root ? "" : "-C /",
+ p->name);
+ last_chdir = root;
+ } else {
+ add_count = snprintf(&where_args[where_count],
+ maxargs - where_count,
+ " %s%s %s",
+ last_chdir == home ? "" : "-C ",
+ last_chdir == home ? "" : home,
+ p->name);
+ last_chdir = home;
+ }
+ if (add_count > maxargs - where_count)
+ barf("oops, miscounted strings!");
+ where_count += add_count;
+ }
/*
* Otherwise, try along the actual extraction path..
*/
- else
- copy_hierarchy(there ? there : where, p->name, FALSE);
+ else {
+ if (p->name[0] == '/')
+ mythere = root;
+ else mythere = there;
+ sprintf(fn, "%s/%s", mythere ? mythere : where, p->name);
+ if (lstat(fn, &stb) == 0 && stb.st_dev == curdir &&
+ S_ISREG(stb.st_mode)) {
+ /* if we can link it to the playpen, that avoids a copy
+ and saves time. */
+ if (trylink(fn, p->name) == 0) {
+ p = p->next;
+ continue;
+ }
+ }
+ if (TOOBIG(p->name)) {
+ PUSHOUT();
+ }
+ if (last_chdir == (mythere ? mythere : where))
+ add_count = snprintf(&where_args[where_count],
+ maxargs - where_count,
+ " %s", p->name);
+ else
+ add_count = snprintf(&where_args[where_count],
+ maxargs - where_count,
+ " -C %s %s",
+ mythere ? mythere : where,
+ p->name);
+ if (add_count > maxargs - where_count)
+ barf("oops, miscounted strings!");
+ where_count += add_count;
+ last_chdir = (mythere ? mythere : where);
+ }
}
p = p->next;
}
+ PUSHOUT();
+ free(where_args);
}
diff --git a/usr.sbin/pkg_install/delete/delete.h b/usr.sbin/pkg_install/delete/delete.h
index 2828cdf3d327..e618d182611c 100644
--- a/usr.sbin/pkg_install/delete/delete.h
+++ b/usr.sbin/pkg_install/delete/delete.h
@@ -1,4 +1,4 @@
-/* $Id$ */
+/* $Id: delete.h,v 1.1.1.1 1993/08/26 01:19:54 jkh Exp $ */
/*
* FreeBSD install - a package for the installation and maintainance
@@ -25,6 +25,8 @@
extern char *Prefix;
extern Boolean NoDeInstall;
+extern Boolean CleanDirs;
+extern Boolean Force;
extern char *Directory;
extern char *PkgName;
diff --git a/usr.sbin/pkg_install/delete/main.c b/usr.sbin/pkg_install/delete/main.c
index a66edfd5967d..c59f94bfc30b 100644
--- a/usr.sbin/pkg_install/delete/main.c
+++ b/usr.sbin/pkg_install/delete/main.c
@@ -1,5 +1,5 @@
#ifndef lint
-static char *rcsid = "$Id: main.c,v 1.5 1993/09/04 05:06:38 jkh Exp $";
+static char *rcsid = "$Id: main.c,v 1.2 1993/09/03 23:01:00 jkh Exp $";
#endif
/*
@@ -26,15 +26,17 @@ static char *rcsid = "$Id: main.c,v 1.5 1993/09/04 05:06:38 jkh Exp $";
#include "lib.h"
#include "delete.h"
-static char Options[] = "hvDnp:";
+static char Options[] = "hvDdnfp:";
char *Prefix = NULL;
Boolean NoDeInstall = FALSE;
+Boolean CleanDirs = FALSE;
+Boolean Force = FALSE;
int
main(int argc, char **argv)
{
- int ch, err;
+ int ch, error;
char **pkgs, **start;
char *prog_name = argv[0];
@@ -45,6 +47,10 @@ main(int argc, char **argv)
Verbose = TRUE;
break;
+ case 'f':
+ Force = TRUE;
+ break;
+
case 'p':
Prefix = optarg;
break;
@@ -53,6 +59,10 @@ main(int argc, char **argv)
NoDeInstall = TRUE;
break;
+ case 'd':
+ CleanDirs = TRUE;
+ break;
+
case 'n':
Fake = TRUE;
Verbose = TRUE;
@@ -77,10 +87,12 @@ main(int argc, char **argv)
if (pkgs == start)
usage(prog_name, "Missing package name(s)");
*pkgs = NULL;
- if ((err = pkg_perform(start)) != NULL) {
+ if (!Fake && getuid() != 0)
+ errx(1, "You must be root to delete packages.");
+ if ((error = pkg_perform(start)) != NULL) {
if (Verbose)
- fprintf(stderr, "%d package deletion(s) failed.\n", err);
- return err;
+ fprintf(stderr, "%d package deletion(s) failed.\n", error);
+ return error;
}
else
return 0;
@@ -102,6 +114,9 @@ usage(const char *name, const char *fmt, ...)
fprintf(stderr, "Where args are one or more of:\n\n");
fprintf(stderr, "-v verbose\n");
fprintf(stderr, "-p arg override prefix with arg\n");
+ fprintf(stderr, "-d delete empty directories when deinstalling\n");
+ fprintf(stderr, "-f force delete even if dependencies exist\n");
+ fprintf(stderr, " or deinstall/requirement checks fail\n");
fprintf(stderr, "-D don't execute pkg de-install script, if any\n");
fprintf(stderr, "-n don't actually de-install, just show steps\n");
exit(1);
diff --git a/usr.sbin/pkg_install/delete/perform.c b/usr.sbin/pkg_install/delete/perform.c
index 0b94b2c5c87b..9986ee15d497 100644
--- a/usr.sbin/pkg_install/delete/perform.c
+++ b/usr.sbin/pkg_install/delete/perform.c
@@ -1,5 +1,5 @@
#ifndef lint
-static const char *rcsid = "$Id: perform.c,v 1.4 1994/05/25 18:00:02 asami Exp $";
+static const char *rcsid = "$Id: perform.c,v 1.5 1994/09/29 13:19:39 jkh Exp $";
#endif
/*
@@ -27,6 +27,7 @@ static const char *rcsid = "$Id: perform.c,v 1.4 1994/05/25 18:00:02 asami Exp $
static int pkg_do(char *);
static void sanity_check(char *);
+static void undepend(PackingList, char *);
static char LogDir[FILENAME_MAX];
@@ -65,6 +66,20 @@ pkg_do(char *pkg)
whinge("Unable to change directory to %s! Deinstall failed.", LogDir);
return 1;
}
+ if (!isemptyfile(REQUIRED_BY_FNAME)) {
+ char buf[512];
+ whinge("Package `%s' is required by these other packages", pkg);
+ whinge("and may not be deinstalled%s:", 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
+ whinge("cannot open requirements file `%s'", REQUIRED_BY_FNAME);
+ if (!Force)
+ return 1;
+ }
sanity_check(LogDir);
cfile = fopen(CONTENTS_FNAME, "r");
if (!cfile) {
@@ -83,8 +98,10 @@ pkg_do(char *pkg)
printf("Executing 'require' script.\n");
vsystem("chmod +x %s", REQUIRE_FNAME); /* be sure */
if (vsystem("./%s %s DEINSTALL", REQUIRE_FNAME, pkg)) {
- whinge("Package %s fails requirements - not deleted.", pkg);
- return 1;
+ whinge("Package %s fails requirements %s", pkg,
+ Force ? "." : "- not deleted.");
+ if (!Force)
+ return 1;
}
}
if (!NoDeInstall && fexists(DEINSTALL_FNAME)) {
@@ -94,17 +111,27 @@ pkg_do(char *pkg)
vsystem("chmod +x %s", DEINSTALL_FNAME); /* make sure */
if (vsystem("./%s %s DEINSTALL", DEINSTALL_FNAME, pkg)) {
whinge("De-Install script returned error status.");
- return 1;
+ if (!Force)
+ return 1;
}
}
}
if (chdir(home) == FAIL)
barf("Toto! This doesn't look like Kansas anymore!");
- if (!Fake && delete_package(FALSE, &Plist) != FAIL &&
+ if (!Fake && delete_package(FALSE, CleanDirs, &Plist) != FAIL &&
vsystem("%s -r %s", REMOVE_CMD, LogDir)) {
whinge("Couldn't remove log entry in %s, de-install failed.", LogDir);
return 1;
}
+ for (p = Plist.head; p ; p = p->next) {
+ if (p->type != PLIST_PKGDEP)
+ continue;
+ if (Verbose)
+ printf("Attempting to remove dependency on package `%s'\n",
+ p->name);
+ if (!Fake)
+ undepend(p, pkg);
+ }
return 0;
}
@@ -120,3 +147,56 @@ cleanup(int sig)
{
/* Nothing to do */
}
+
+static void
+undepend(PackingList p, char *pkgname)
+{
+ char fname[FILENAME_MAX], ftmp[FILENAME_MAX];
+ char fbuf[FILENAME_MAX];
+ FILE *fp, *fpwr;
+ int s;
+
+ sprintf(fname, "%s/%s/%s", LOG_DIR, p->name, REQUIRED_BY_FNAME);
+ fp = fopen(fname, "r");
+ if (fp == NULL) {
+ whinge("Couldn't open dependency file `%s'", fname);
+ return;
+ }
+ sprintf(ftmp, "%s.XXXXXX", fname);
+ s = mkstemp(ftmp);
+ if (s == -1) {
+ fclose(fp);
+ whinge("Couldn't open temp file `%s'", ftmp);
+ return;
+ }
+ fpwr = fdopen(s, "w");
+ if (fpwr == NULL) {
+ close(s);
+ fclose(fp);
+ whinge("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) {
+ whinge("Error changing permission of temp file `%s'", ftmp);
+ fclose(fpwr);
+ remove(ftmp);
+ return;
+ }
+ if (fclose(fpwr) == EOF) {
+ whinge("Error closing temp file `%s'", ftmp);
+ remove(ftmp);
+ return;
+ }
+ if (rename(ftmp, fname) == -1)
+ warn("Error renaming `%s' to `%s'", ftmp, fname);
+ remove(ftmp); /* just in case */
+ return;
+}
diff --git a/usr.sbin/pkg_install/info/info.h b/usr.sbin/pkg_install/info/info.h
index b978bd495bd3..6feb73e69671 100644
--- a/usr.sbin/pkg_install/info/info.h
+++ b/usr.sbin/pkg_install/info/info.h
@@ -1,4 +1,4 @@
-/* $Id: info.h,v 1.4 1993/09/04 05:06:40 jkh Exp $ */
+/* $Id: info.h,v 1.5 1993/09/08 01:46:56 jkh Exp $ */
/*
* FreeBSD install - a package for the installation and maintainance
@@ -23,15 +23,18 @@
#ifndef _INST_INFO_H_INCLUDE
#define _INST_INFO_H_INCLUDE
-#define SHOW_COMMENT 0x1
-#define SHOW_DESC 0x2
-#define SHOW_PLIST 0x4
-#define SHOW_INSTALL 0x8
-#define SHOW_DEINSTALL 0x10
-#define SHOW_REQUIRE 0x20
-#define SHOW_PREFIX 0x40
-#define SHOW_INDEX 0x80
-#define SHOW_FILES 0x100
+#define SHOW_COMMENT 0x0001
+#define SHOW_DESC 0x0002
+#define SHOW_PLIST 0x0004
+#define SHOW_INSTALL 0x0008
+#define SHOW_DEINSTALL 0x0010
+#define SHOW_REQUIRE 0x0020
+#define SHOW_PREFIX 0x0040
+#define SHOW_INDEX 0x0080
+#define SHOW_FILES 0x0100
+#define SHOW_DISPLAY 0x0200
+#define SHOW_REQBY 0x0400
+#define SHOW_MTREE 0x0800
extern int Flags;
extern Boolean AllInstalled;
diff --git a/usr.sbin/pkg_install/info/main.c b/usr.sbin/pkg_install/info/main.c
index 6132fab26262..ce8449e32943 100644
--- a/usr.sbin/pkg_install/info/main.c
+++ b/usr.sbin/pkg_install/info/main.c
@@ -1,5 +1,5 @@
#ifndef lint
-static char *rcsid = "$Id: main.c,v 1.6 1994/05/25 06:28:14 jkh Exp $";
+static char *rcsid = "$Id: main.c,v 1.7 1994/06/01 05:15:00 asami Exp $";
#endif
/*
@@ -26,7 +26,7 @@ static char *rcsid = "$Id: main.c,v 1.6 1994/05/25 06:28:14 jkh Exp $";
#include "lib.h"
#include "info.h"
-static char Options[] = "acde:fikrpLqIvhl:";
+static char Options[] = "acdDe:fikrRpLqImvhl:";
int Flags = 0;
Boolean AllInstalled = FALSE;
@@ -53,7 +53,7 @@ main(int argc, char **argv)
Verbose = TRUE;
/* Reasonable definition of 'everything' */
Flags = SHOW_COMMENT | SHOW_DESC | SHOW_PLIST | SHOW_INSTALL |
- SHOW_DEINSTALL | SHOW_REQUIRE;
+ SHOW_DEINSTALL | SHOW_REQUIRE | SHOW_DISPLAY | SHOW_MTREE;
break;
case 'I':
@@ -72,6 +72,10 @@ main(int argc, char **argv)
Flags |= SHOW_DESC;
break;
+ case 'D':
+ Flags |= SHOW_DISPLAY;
+ break;
+
case 'f':
Flags |= SHOW_PLIST;
break;
@@ -88,10 +92,18 @@ main(int argc, char **argv)
Flags |= SHOW_REQUIRE;
break;
+ case 'R':
+ Flags |= SHOW_REQBY;
+ break;
+
case 'L':
Flags |= SHOW_FILES;
break;
+ case 'm':
+ Flags |= SHOW_MTREE;
+ break;
+
case 'l':
InfoPrefix = optarg;
break;
@@ -120,7 +132,7 @@ main(int argc, char **argv)
/* Set some reasonable defaults */
if (!Flags)
- Flags = SHOW_COMMENT | SHOW_DESC;
+ Flags = SHOW_COMMENT | SHOW_DESC | SHOW_REQBY;
/* Get all the remaining package names, if any */
while (*argv)
@@ -151,15 +163,19 @@ usage(const char *name, const char *fmt, ...)
fprintf(stderr, "-I print 'index' of packages\n");
fprintf(stderr, "-c print `one line comment'\n");
fprintf(stderr, "-d print description\n");
+ fprintf(stderr, "-D print install notice\n");
fprintf(stderr, "-f show packing list\n");
fprintf(stderr, "-i show install script\n");
fprintf(stderr, "-k show deinstall script\n");
fprintf(stderr, "-r show requirements script\n");
+ fprintf(stderr, "-R show packages depending on this package\n");
fprintf(stderr, "-p show prefix\n");
fprintf(stderr, "-l <str> Prefix each info catagory with <str>\n");
+ fprintf(stderr, "-L show intalled files\n");
+ fprintf(stderr, "-q minimal output (``quiet'' mode)\n");
fprintf(stderr, "-v show all information\n");
fprintf(stderr, "-t temp use temp as template for mktemp()\n");
fprintf(stderr, "-e pkg returns 0 if pkg is installed, 1 otherwise\n");
- fprintf(stderr, "\n[no args = -c -d]\n");
+ fprintf(stderr, "\n[no args = -c -d -R]\n");
exit(1);
}
diff --git a/usr.sbin/pkg_install/info/perform.c b/usr.sbin/pkg_install/info/perform.c
index b537f172526f..a28f2a0f9fd7 100644
--- a/usr.sbin/pkg_install/info/perform.c
+++ b/usr.sbin/pkg_install/info/perform.c
@@ -1,5 +1,5 @@
#ifndef lint
-static const char *rcsid = "$Id: perform.c,v 1.8 1994/10/14 05:55:57 jkh Exp $";
+static const char *rcsid = "$Id: perform.c,v 1.9 1994/10/14 05:57:49 jkh Exp $";
#endif
/*
@@ -60,7 +60,9 @@ pkg_perform(char **pkgs)
}
else
++err_cnt;
- }
+ } else if (CheckPkg)
+ return 1; /* no dir -> not installed! */
+
}
for (i = 0; pkgs[i]; i++)
err_cnt += pkg_do(pkgs[i]);
@@ -143,14 +145,20 @@ pkg_do(char *pkg)
printf("%sInformation for %s:\n\n", InfoPrefix, pkg);
if (Flags & SHOW_COMMENT)
show_file("Comment:\n", COMMENT_FNAME);
+ if ((Flags & SHOW_REQBY) && !isemptyfile(REQUIRED_BY_FNAME))
+ show_file("Required by:\n", REQUIRED_BY_FNAME);
if (Flags & SHOW_DESC)
show_file("Description:\n", DESC_FNAME);
+ if ((Flags & SHOW_DISPLAY) && fexists(DISPLAY_FNAME))
+ show_file("Install notice:\n", DISPLAY_FNAME);
if (Flags & SHOW_PLIST)
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_DEINSTALL) && fexists(DEINSTALL_FNAME))
show_file("De-Install script:\n", DEINSTALL_FNAME);
+ if ((Flags & SHOW_MTREE) && fexists(MTREE_FNAME))
+ show_file("mtree file:\n", MTREE_FNAME);
if (Flags & SHOW_PREFIX)
show_plist("Prefix(s):\n", &plist, PLIST_CWD);
if (Flags & SHOW_FILES)
diff --git a/usr.sbin/pkg_install/info/pkg_info.1 b/usr.sbin/pkg_install/info/pkg_info.1
index 1f28c17bc322..df996ceca048 100644
--- a/usr.sbin/pkg_install/info/pkg_info.1
+++ b/usr.sbin/pkg_install/info/pkg_info.1
@@ -16,108 +16,119 @@
.\"
.\" @(#)pkg_info.1
.\"
-.TH pkg_info 1 "July 18, 1993" "" "FreeBSD"
-
-.SH NAME
-pkg_info - a utility for getting information on software package distributions.
-.SH SYNOPSIS
-.na
-.B pkg_info
-.RB [options]
-.RB "pkg-file|pkg-name\ [.. pkg-file|pkg-name]"
-
-.SH DESCRIPTION
+.Dd November 25, 1994
+.Dt pkg_info 1
+.Os NetBSD 1.0
+.Sh NAME
+.Nm pkg_info
+.Nd a utility for displaying information on software packages.
+.Sh SYNOPSIS
+.Nm pkg_info
+.Op Fl cdDikrRpLqImv
+.Op Fl e Ar package
+.Op Fl l Ar prefix
+.Ar pkg-name ...
+.Nm pkg_info
+.Fl a
+.Op Ar flags
+.Sh DESCRIPTION
The
-.B pkg_info
+.Nm
command is used to dump out information for packages, either packed up in
files or already installed on the system
with the
-.B pkg_create
+.Xr pkg_create 8
command.
-
-.SH OPTIONS
-.TP
+.Sh OPTIONS
The following command line options are supported.
-.TP
-.B \-a
+.Bl -tag -width indent
+.It Ar pkg-name ...
+The named packages are described. Names may either be installed package
+names or pathnames to package distribution files.
+.It Fl a
Show all currently installed packages.
-.TP
-.B \-v
+.It Fl v
Turns on verbose output.
-.TP
-.B \-p
+.It Fl p
Show the installation prefix for each package.
-.TP
-.B \-q
-Be "quiet" in emitting report headers and such, just dump the
+.It Fl q
+Be ``quiet'' in emitting report headers and such, just dump the
raw info (basically, assume a non-human reading).
-.TP
-.B \-c
+.It Fl c
Show the comment (one liner) field for each package.
-.TP
-.B \-d
+.It Fl d
Show the long description field for each package.
-.TP
-.B \-f
+.It Fl D
+Show the install-message file for each package.
+.It Fl f
Show the packing list instructions for each package.
-.TP
-.B \-i
+.It Fl i
Show the install script (if any) for each package.
-.TP
-.B \-k
+.It Fl k
Show the de-install script (if any) for each package.
-.TP
-.B \-r
+.It Fl r
Show the requirements script (if any) for each package.
-.TP
-.B \-L
+.It Fl m
+Show the mtree file (if any) for each package.
+.It Fl L
Show the files within each package. This is different from just
viewing the packing list, since full pathnames for everything
are generated.
-.TP
-.BI "\-e\ " pkg-name
+.It Fl e Ar pkg-name
If the package identified by
-.I pkg-name
+.Ar pkg-name
is currently installed, return 0, otherwise return 1. This option
allows you to easily test for the presence of another (perhaps
prerequisite) package from a script.
-.TP
-.BI "\-l\ " str
+.It Fl l Ar str
Prefix each information catagory header (see
-.I \-q)
+.Fl q )
shown with
-.I str.
+.Ar str .
This is primarily of use to front-end programs who want to request a
lot of different information fields at once for a package, but don't
necessary want the output intermingled in such a way that they can't
organize it. This lets you add a special token to the start of
each field.
-.TP
-.BI "\-t\ " template
+.Fl t Ar template
Use
-.I template
-as the input to mktemp(3). By default, this is the string
-.B /tmp/instmp.XXXXXX
-, but it may be necessary to override it in the situation where
+.Ar template
+as the input to
+.Xr mktemp 3
+when creating a ``staging area.''
+By default, this is the string
+.Pa /tmp/instmp.XXXXXX ,
+but it may be necessary to override it in the situation where
space in your
-.B /tmp
+.Pa /tmp
directory is limited. Be sure to leave some number of `X' characters
-for mktemp(3) to fill in with a unique ID.
+for
+.Xr mktemp 3
+to fill in with a unique ID.
+.Bd -filled -offset indent -compact
Note: This should really not be necessary with pkg_info,
since very little information is extracted from each package
-and one would have to have a very small /tmp indeed to overflow
-it.
-.PP
-.SH "TECHNICAL DETAILS"
-Package info is either extracted from files supplied on the
+and one would have to have a very small
+.Pa /tmp
+indeed to overflow it.
+.Ed
+.Sh TECHNICAL DETAILS
+Package info is either extracted from package files named on the
command line, or from already installed package information
-in /var/db/pkg/<pkg-name>.
-.SH BUGS
+in
+.Pa /var/db/pkg/<pkg-name> .
+.Sh SEE ALSO
+.Xr mktemp 3 ,
+.Xr mtree 8 ,
+.Xr pkg_add 1 ,
+.Xr pkg_create 1 ,
+.Xr pkg_delete 1 .
+.Sh AUTHORS
+.Bl -tag -width indent -compact
+.It "Jordan Hubbard"
+most of the work
+.It "John Kohl"
+refined it for NetBSD
+.El
+.Sh BUGS
Sure to be some.
-.SH "SEE ALSO"
-.BR pkg_add "(" 1 "),"
-.BR pkg_create "(" 1 "),"
-.BR pkg_delete "(" 1 "),"
-.SH AUTHORS
-Jordan Hubbard
-
diff --git a/usr.sbin/pkg_install/info/show.c b/usr.sbin/pkg_install/info/show.c
index 3000ccf8f6d4..93efd0e94722 100644
--- a/usr.sbin/pkg_install/info/show.c
+++ b/usr.sbin/pkg_install/info/show.c
@@ -1,5 +1,5 @@
#ifndef lint
-static const char *rcsid = "$Id: show.c,v 1.4 1993/09/04 05:06:44 jkh Exp $";
+static const char *rcsid = "$Id: show.c,v 1.3 1993/09/08 01:46:59 jkh Exp $";
#endif
/*
@@ -74,6 +74,10 @@ show_plist(char *title, Package *plist, plist_t type)
printf(Quiet ? "@cwd %s\n" : "\tCWD to %s\n", p->name);
break;
+ case PLIST_SRC:
+ printf(Quiet ? "@srcdir %s\n" : "\tSRCDIR to %s\n", p->name);
+ break;
+
case PLIST_CMD:
printf(Quiet ? "@exec %s\n" : "\tEXEC '%s'\n", p->name);
break;
@@ -101,10 +105,32 @@ show_plist(char *title, Package *plist, plist_t type)
ign = TRUE;
break;
+ case PLIST_IGNORE_INST:
+ printf(Quiet ? "@ignore_inst ??? doesn't belong here.\n" :
+ "\tIgnore next file installation directive (doesn't belong)\n");
+ ign = TRUE;
+ break;
+
case PLIST_NAME:
printf(Quiet ? "@name %s\n" : "\tPackage name: %s\n", p->name);
break;
+ case PLIST_DISPLAY:
+ printf(Quiet ? "@display %s\n" : "\tInstall message file: %s\n", p->name);
+ break;
+
+ case PLIST_PKGDEP:
+ printf(Quiet ? "@pkgdep %s\n" : "\tPackage depends on: %s\n", p->name);
+ break;
+
+ case PLIST_MTREE:
+ printf(Quiet ? "@mtree %s\n" : "\tPackage mtree file: %s\n", p->name);
+ break;
+
+ case PLIST_DIR_RM:
+ printf(Quiet ? "@dirrm %s\n" : "\tDeinstall directory remove: %s\n", p->name);
+ break;
+
default:
barf("Unknown command type %d (%s)\n", p->type, p->name);
break;
diff --git a/usr.sbin/pkg_install/lib/exec.c b/usr.sbin/pkg_install/lib/exec.c
index 5232dd2b4dcf..dd6b184fffd8 100644
--- a/usr.sbin/pkg_install/lib/exec.c
+++ b/usr.sbin/pkg_install/lib/exec.c
@@ -1,5 +1,5 @@
#ifndef lint
-static const char *rcsid = "$Id: exec.c,v 1.4 1993/09/04 05:06:47 jkh Exp $";
+static const char *rcsid = "$Id: exec.c,v 1.2 1993/09/03 23:01:12 jkh Exp $";
#endif
/*
@@ -33,16 +33,28 @@ int
vsystem(const char *fmt, ...)
{
va_list args;
- char cmd[FILENAME_MAX * 2]; /* reasonable default for what I do */
- int ret;
+ char *cmd;
+ int ret, maxargs;
+
+ maxargs = sysconf(_SC_ARG_MAX);
+ maxargs -= 32; /* some slop for the sh -c */
+ cmd = malloc(maxargs);
+ if (!cmd) {
+ whinge("vsystem can't alloc arg space");
+ return 1;
+ }
va_start(args, fmt);
- vsprintf(cmd, fmt, args);
+ if (vsnprintf(cmd, maxargs, fmt, args) > maxargs) {
+ whinge("vsystem args are too long");
+ return 1;
+ }
#ifdef DEBUG
printf("Executing %s\n", cmd);
#endif
ret = system(cmd);
va_end(args);
+ free(cmd);
return ret;
}
diff --git a/usr.sbin/pkg_install/lib/file.c b/usr.sbin/pkg_install/lib/file.c
index 698fd8754382..e2c26688a0f5 100644
--- a/usr.sbin/pkg_install/lib/file.c
+++ b/usr.sbin/pkg_install/lib/file.c
@@ -1,5 +1,5 @@
#ifndef lint
-static const char *rcsid = "$Id: file.c,v 1.4 1993/09/06 23:28:42 jkh Exp $";
+static const char *rcsid = "$Id: file.c,v 1.5 1993/09/18 03:39:48 jkh Exp $";
#endif
/*
@@ -39,8 +39,7 @@ isdir(char *fname)
{
struct stat sb;
- if (stat(fname, &sb) != FAIL &&
- (sb.st_mode & S_IFDIR))
+ if (stat(fname, &sb) != FAIL && S_ISDIR(sb.st_mode))
return TRUE;
else
return FALSE;
@@ -48,7 +47,7 @@ isdir(char *fname)
/* Check to see if file is a dir, and is empty */
Boolean
-isempty(char *fname)
+isemptydir(char *fname)
{
if (isdir(fname)) {
DIR *dirp;
@@ -69,6 +68,19 @@ isempty(char *fname)
return FALSE;
}
+/* Check to see if file is a file and is empty. If nonexistent or not
+ a file, say "it's empty", otherwise return TRUE if zero sized. */
+Boolean
+isemptyfile(char *fname)
+{
+ struct stat sb;
+ if (stat(fname, &sb) != FAIL && S_ISREG(sb.st_mode)) {
+ if (sb.st_size != 0)
+ return FALSE;
+ }
+ return TRUE;
+}
+
char *
get_file_contents(char *fname)
{
@@ -84,7 +96,7 @@ get_file_contents(char *fname)
if (fd == FAIL)
barf("Unable to open '%s' for reading.", fname);
if (read(fd, contents, sb.st_size) != sb.st_size)
- barf("Short read on '%s' - did not get %d bytes.", fname, sb.st_size);
+ barf("Short read on '%s' - did not get %qd bytes.", fname, sb.st_size);
close(fd);
contents[sb.st_size] = '\0';
return contents;
diff --git a/usr.sbin/pkg_install/lib/lib.h b/usr.sbin/pkg_install/lib/lib.h
index b9f6a15efec2..abcfed741169 100644
--- a/usr.sbin/pkg_install/lib/lib.h
+++ b/usr.sbin/pkg_install/lib/lib.h
@@ -1,4 +1,4 @@
-/* $Id: lib.h,v 1.10 1994/10/04 16:07:50 jkh Exp $ */
+/* $Id: lib.h,v 1.11 1994/11/17 10:51:46 jkh Exp $ */
/*
* FreeBSD install - a package for the installation and maintainance
@@ -66,6 +66,9 @@
#define INSTALL_FNAME "+INSTALL"
#define DEINSTALL_FNAME "+DEINSTALL"
#define REQUIRE_FNAME "+REQUIRE"
+#define REQUIRED_BY_FNAME "+REQUIRED_BY"
+#define DISPLAY_FNAME "+DISPLAY"
+#define MTREE_FNAME "+MTREE_DIRS"
#define CMD_CHAR '@' /* prefix for extended PLIST cmd */
@@ -75,7 +78,8 @@
enum _plist_t {
PLIST_FILE, PLIST_CWD, PLIST_CMD, PLIST_CHMOD,
PLIST_CHOWN, PLIST_CHGRP, PLIST_COMMENT,
- PLIST_IGNORE, PLIST_NAME, PLIST_UNEXEC, PLIST_SRC
+ PLIST_IGNORE, PLIST_NAME, PLIST_UNEXEC, PLIST_SRC, PLIST_DISPLAY,
+ PLIST_PKGDEP, PLIST_MTREE, PLIST_DIR_RM, PLIST_IGNORE_INST
};
typedef enum _plist_t plist_t;
@@ -119,7 +123,7 @@ char *get_file_contents(char *);
void write_file(char *, char *);
void copy_file(char *, char *, char *);
void copy_hierarchy(char *, char *, Boolean);
-int delete_hierarchy(char *, Boolean);
+int delete_hierarchy(char *, Boolean, Boolean);
int unpack(char *, char *);
void format_cmd(char *, char *, char *, char *);
@@ -142,7 +146,7 @@ void add_plist_top(Package *, plist_t, char *);
void write_plist(Package *, FILE *);
void read_plist(Package *, FILE *);
int plist_cmd(char *, char **);
-int delete_package(Boolean, Package *);
+int delete_package(Boolean, Boolean, Package *);
/* For all */
void usage(const char *, const char *, ...);
diff --git a/usr.sbin/pkg_install/lib/plist.c b/usr.sbin/pkg_install/lib/plist.c
index 577ae5ee8b9d..282f3d04e25b 100644
--- a/usr.sbin/pkg_install/lib/plist.c
+++ b/usr.sbin/pkg_install/lib/plist.c
@@ -1,5 +1,5 @@
#ifndef lint
-static const char *rcsid = "$Id: plist.c,v 1.8 1994/08/28 14:15:30 jkh Exp $";
+static const char *rcsid = "$Id: plist.c,v 1.9 1994/09/29 13:19:43 jkh Exp $";
#endif
/*
@@ -198,8 +198,18 @@ plist_cmd(char *s, char **arg)
return PLIST_COMMENT;
else if (!strcmp(cmd, "ignore"))
return PLIST_IGNORE;
+ else if (!strcmp(cmd, "ignore_inst"))
+ return PLIST_IGNORE_INST;
else if (!strcmp(cmd, "name"))
return PLIST_NAME;
+ else if (!strcmp(cmd, "display"))
+ return PLIST_DISPLAY;
+ else if (!strcmp(cmd, "pkgdep"))
+ return PLIST_PKGDEP;
+ else if (!strcmp(cmd, "mtree"))
+ return PLIST_MTREE;
+ else if (!strcmp(cmd, "dirrm"))
+ return PLIST_DIR_RM;
else
return FAIL;
}
@@ -280,6 +290,7 @@ write_plist(Package *pkg, FILE *fp)
break;
case PLIST_IGNORE:
+ case PLIST_IGNORE_INST: /* a one-time non-ignored file */
fprintf(fp, "%cignore\n", CMD_CHAR);
break;
@@ -287,6 +298,22 @@ write_plist(Package *pkg, FILE *fp)
fprintf(fp, "%cname %s\n", CMD_CHAR, plist->name);
break;
+ case PLIST_DISPLAY:
+ fprintf(fp, "%cdisplay %s\n", CMD_CHAR, plist->name);
+ break;
+
+ case PLIST_PKGDEP:
+ fprintf(fp, "%cpkgdep %s\n", CMD_CHAR, plist->name);
+ break;
+
+ case PLIST_MTREE:
+ fprintf(fp, "%cmtree %s\n", CMD_CHAR, plist->name);
+ break;
+
+ case PLIST_DIR_RM:
+ fprintf(fp, "%cdirrm %s\n", CMD_CHAR, plist->name);
+ break;
+
default:
barf("Unknown command type %d (%s)\n", plist->type, plist->name);
break;
@@ -297,7 +324,7 @@ write_plist(Package *pkg, FILE *fp)
/* Delete the results of a package installation, not the packaging itself */
int
-delete_package(Boolean ign_err, Package *pkg)
+delete_package(Boolean ign_err, Boolean nukedirs, Package *pkg)
{
PackingList p = pkg->head;
char *Where = ".", *last_file = "";
@@ -322,14 +349,16 @@ delete_package(Boolean ign_err, Package *pkg)
}
else if (p->type == PLIST_IGNORE)
p = p->next;
- else if (p->type == PLIST_FILE) {
+ else if (p->type == PLIST_FILE || p->type == PLIST_DIR_RM) {
char full_name[FILENAME_MAX];
sprintf(full_name, "%s/%s", Where, p->name);
if (Verbose)
- printf("Delete: %s\n", full_name);
+ printf("Delete%s: %s\n",
+ p->type == PLIST_FILE ? "" : " directory", full_name);
- if (!Fake && delete_hierarchy(full_name, ign_err)) {
+ if (!Fake && delete_hierarchy(full_name, ign_err,
+ p->type == PLIST_DIR_RM ? FALSE : nukedirs)) {
whinge("Unable to completely remove file '%s'", full_name);
fail = FAIL;
}
@@ -340,26 +369,44 @@ delete_package(Boolean ign_err, Package *pkg)
return fail;
}
+#ifdef DEBUG
+#define RMDIR(dir) vsystem("%s %s", RMDIR_CMD, dir)
+#define REMOVE(dir,ie) vsystem("%s %s%s", REMOVE_CMD, (ie ? "-f " : ""), dir)
+#else
+#define RMDIR rmdir
+#define REMOVE(file,ie) remove(file)
+#endif
+
/* Selectively delete a hierarchy */
int
-delete_hierarchy(char *dir, Boolean ign_err)
+delete_hierarchy(char *dir, Boolean ign_err, Boolean nukedirs)
{
char *cp1, *cp2;
cp1 = cp2 = dir;
- if (vsystem("%s -r%s %s", REMOVE_CMD, (ign_err ? "f" : ""), dir))
- return 1;
+ if (nukedirs) {
+ if (vsystem("%s -r%s %s", REMOVE_CMD, (ign_err ? "f" : ""), dir))
+ return 1;
+ } else if (isdir(dir)) {
+ if (RMDIR(dir))
+ return 1;
+ } else {
+ if (REMOVE(dir, ign_err))
+ return 1;
+ }
+
+ if (!nukedirs)
+ return 0;
while (cp2) {
if ((cp2 = rindex(cp1, '/')) != NULL)
*cp2 = '\0';
- if (!isempty(dir))
+ if (!isemptydir(dir))
return 0;
- if (vsystem("%s %s", RMDIR_CMD, dir) && ign_err)
+ if (RMDIR(dir) && ign_err)
return 1;
- /* Put it back */
+ /* back up the pathname one component */
if (cp2) {
- *cp2 = '/';
- cp1 = cp2 - 1;
+ cp1 = dir;
}
}
return 0;
diff --git a/usr.sbin/pkg_install/tkpkg b/usr.sbin/pkg_install/tkpkg
index c4c9273be241..5a3e500ae776 100755
--- a/usr.sbin/pkg_install/tkpkg
+++ b/usr.sbin/pkg_install/tkpkg
@@ -1,7 +1,10 @@
#!/usr/local/bin/wish -f
-#$Id: pkg,v 1.1 1993/09/04 17:06:09 jkh Exp $
+#$Id: tkpkg,v 1.1 1994/01/06 08:16:20 jkh Exp $
+#
+#$Log: tkpkg,v $
+# Revision 1.1 1994/01/06 08:16:20 jkh
+# Cleaning house.
#
-#$Log: pkg,v $
# Revision 1.1 1993/09/04 17:06:09 jkh
# Added Rich's wish front-end.
#
@@ -41,7 +44,7 @@ text .f.t -width 80 -height 20 -yscrollcommand ".f.s set" -relief sunken
# instructions and show the package description when the user clicks
# on a package.
#
-.f.t insert end "Double click on a package above to see it's
+.f.t insert end "Double click on a package above to see its
complete description here."
scrollbar .f.s -relief sunken -command ".f.t yview"
pack append .f .f.s {right filly} .f.t {left expand fill}
@@ -64,7 +67,7 @@ button .menu.installed -text "What is Installed?" \
button .menu.available -text "What can I install?" \
-command "list_pkgs \"pkg_info -I -c [glob -nocomplain *.{tgz,tar.z,tar.gz,tar.Z}] |tr ' ' ' '\""
button .menu.cont -text "Contents?" \
- -command "global pkgname; apply_to_pkg \"pkg_info -d -v |tr -d ' '\""
+ -command "apply_to_pkg \"pkg_info -d -v\""
button .menu.quit -text "Quit" -command "destroy ."
button .menu.help -text "Help" -command "do_help"
@@ -81,7 +84,7 @@ pack append .menu \
#-------------------------------------------------------
proc list_pkgs {s} {
set line ""
- set f [eval "open {| csh -c \"$s\" } r"]
+ set f [eval "open {| sh -c \"$s\" } r"]
.frame.list delete 0 end
while {[gets $f line] > 0} {
.frame.list insert end $line
@@ -91,7 +94,7 @@ proc list_pkgs {s} {
# display the list of available packages
set archives [glob -nocomplain *.{tgz,tar.z,tar.gz,tar.Z}]
-if {$pkgname == ""} {
+if {$archives == ""} {
.frame.list delete 0 end
.frame.list insert end "Warning: no compressed tar archives files found."
} else {
@@ -122,25 +125,34 @@ proc do_help {{w .help}} {
wm iconname $w "Help"
button $w.ok -text OK -command "destroy $w"
message $w.t -relief raised -bd 2 \
- -text "You can install, deinstall and list info on the available packages. To select a package and see it's complete description, press mouse button 1 over the package name. To install a selected package, press the Install button. To exit, press the \"Quit\" button."
+ -text "You can install, deinstall and list info on the available packages. To select a package and see its complete description, press mouse button 1 over the package name. To install a selected package, press the Install button. To exit, press the \"Quit\" button."
pack append $w $w.ok {bottom fillx} $w.t {expand fill}
}
#-------------------------------------------------------
# Apply a command to a package.
#-------------------------------------------------------
proc apply_to_pkg {s} {
+ apply_to_pkg_err $s ""
+}
+#-------------------------------------------------------
+# Apply a command to a package, with error stream redirection instructions.
+#-------------------------------------------------------
+proc apply_to_pkg_err {s errredir} {
global pkgname
.f.t delete 0.0 end
if {$pkgname == ""} {
.f.t insert end "You must double click on a package name first!"
} else {
+ apply_to_pkg_int "$s $pkgname" "2>&1"
+ }
+}
+proc apply_to_pkg_int {s errredir} {
.f.t delete 0.0 end
- .f.t insert end "Running: $s $pkgname\n"
- set f [eval "open {| $s $pkgname} r"]
+ .f.t insert end "Running: $s\n"
+ set f [eval "open {| sh -c \"$s $errredir\" } r"]
while {![eof $f]} {
.f.t insert end [read $f 64]
}
- }
}
#-------------------------------------------------------
# Invoke an arbitrary command.