summaryrefslogtreecommitdiff
path: root/pkgtools/pkg_install
diff options
context:
space:
mode:
authorschmonz <schmonz@pkgsrc.org>2002-12-20 18:13:52 +0000
committerschmonz <schmonz@pkgsrc.org>2002-12-20 18:13:52 +0000
commit55c0604b89b34ae6d16219723abcde3111975fed (patch)
tree78c74b24300afe90e8e1596d6cb82ecb3f530138 /pkgtools/pkg_install
parentc7a5a7d2fb3005ea184ee858e63fdde9c9ce1226 (diff)
downloadpkgsrc-55c0604b89b34ae6d16219723abcde3111975fed.tar.gz
Import autoconf'd pkg_install source from
othersrc/bootstrap-pkgsrc/pkg_install into ${FILESDIR}. Using autoconf greatly simplifies maintenance of this package across multiple platforms. Placing the extracted source under ${FILESDIR} will eventually let us use the same source for bootstrapping as well, though we're not ready for this yet.
Diffstat (limited to 'pkgtools/pkg_install')
-rw-r--r--pkgtools/pkg_install/files/Makefile.in39
-rw-r--r--pkgtools/pkg_install/files/README18
-rw-r--r--pkgtools/pkg_install/files/TODO16
-rw-r--r--pkgtools/pkg_install/files/add/Makefile.in40
-rw-r--r--pkgtools/pkg_install/files/add/add.h48
-rw-r--r--pkgtools/pkg_install/files/add/extract.c353
-rw-r--r--pkgtools/pkg_install/files/add/futil.c107
-rw-r--r--pkgtools/pkg_install/files/add/main.c197
-rw-r--r--pkgtools/pkg_install/files/add/perform.c752
-rw-r--r--pkgtools/pkg_install/files/add/pkg_add.1512
-rw-r--r--pkgtools/pkg_install/files/add/pkg_add.cat1305
-rw-r--r--pkgtools/pkg_install/files/add/verify.c172
-rw-r--r--pkgtools/pkg_install/files/add/verify.h40
-rw-r--r--pkgtools/pkg_install/files/admin/Makefile.in39
-rw-r--r--pkgtools/pkg_install/files/admin/README9
-rw-r--r--pkgtools/pkg_install/files/admin/main.c630
-rw-r--r--pkgtools/pkg_install/files/admin/pkg_admin.1147
-rw-r--r--pkgtools/pkg_install/files/admin/pkg_admin.cat192
-rwxr-xr-xpkgtools/pkg_install/files/configure3084
-rw-r--r--pkgtools/pkg_install/files/configure.in64
-rw-r--r--pkgtools/pkg_install/files/create/Makefile.in39
-rw-r--r--pkgtools/pkg_install/files/create/create.h57
-rw-r--r--pkgtools/pkg_install/files/create/main.c225
-rw-r--r--pkgtools/pkg_install/files/create/perform.c417
-rw-r--r--pkgtools/pkg_install/files/create/pkg_create.1528
-rw-r--r--pkgtools/pkg_install/files/create/pkg_create.cat1298
-rw-r--r--pkgtools/pkg_install/files/create/pl.c238
-rw-r--r--pkgtools/pkg_install/files/delete/Makefile.in40
-rw-r--r--pkgtools/pkg_install/files/delete/delete.h37
-rw-r--r--pkgtools/pkg_install/files/delete/main.c225
-rw-r--r--pkgtools/pkg_install/files/delete/perform.c697
-rw-r--r--pkgtools/pkg_install/files/delete/pkg_delete.1241
-rw-r--r--pkgtools/pkg_install/files/delete/pkg_delete.cat1135
-rw-r--r--pkgtools/pkg_install/files/info/Makefile.in39
-rw-r--r--pkgtools/pkg_install/files/info/info.h71
-rw-r--r--pkgtools/pkg_install/files/info/main.c287
-rw-r--r--pkgtools/pkg_install/files/info/perform.c381
-rw-r--r--pkgtools/pkg_install/files/info/pkg_info.1262
-rw-r--r--pkgtools/pkg_install/files/info/pkg_info.cat1157
-rw-r--r--pkgtools/pkg_install/files/info/show.c290
-rwxr-xr-xpkgtools/pkg_install/files/install-sh238
-rw-r--r--pkgtools/pkg_install/files/lib/Makefile.in38
-rw-r--r--pkgtools/pkg_install/files/lib/config.h.in169
-rw-r--r--pkgtools/pkg_install/files/lib/defs.h92
-rw-r--r--pkgtools/pkg_install/files/lib/digest.c90
-rw-r--r--pkgtools/pkg_install/files/lib/err.c108
-rw-r--r--pkgtools/pkg_install/files/lib/exec.c75
-rw-r--r--pkgtools/pkg_install/files/lib/fgetln.c88
-rw-r--r--pkgtools/pkg_install/files/lib/file.c634
-rw-r--r--pkgtools/pkg_install/files/lib/ftpio.c943
-rw-r--r--pkgtools/pkg_install/files/lib/global.c40
-rw-r--r--pkgtools/pkg_install/files/lib/lib.h.in448
-rw-r--r--pkgtools/pkg_install/files/lib/lpkg.c72
-rw-r--r--pkgtools/pkg_install/files/lib/path.c208
-rw-r--r--pkgtools/pkg_install/files/lib/path.h40
-rw-r--r--pkgtools/pkg_install/files/lib/pen.c417
-rw-r--r--pkgtools/pkg_install/files/lib/pkgdb.c275
-rw-r--r--pkgtools/pkg_install/files/lib/plist.c524
-rw-r--r--pkgtools/pkg_install/files/lib/setenv.c74
-rw-r--r--pkgtools/pkg_install/files/lib/setprogname.c63
-rw-r--r--pkgtools/pkg_install/files/lib/str.c741
-rw-r--r--pkgtools/pkg_install/files/lib/unsetenv.c63
-rw-r--r--pkgtools/pkg_install/files/lib/version.c51
-rw-r--r--pkgtools/pkg_install/files/lib/version.h38
-rw-r--r--pkgtools/pkg_install/files/tkpkg152
65 files changed, 17009 insertions, 0 deletions
diff --git a/pkgtools/pkg_install/files/Makefile.in b/pkgtools/pkg_install/files/Makefile.in
new file mode 100644
index 00000000000..9aa6d5409b3
--- /dev/null
+++ b/pkgtools/pkg_install/files/Makefile.in
@@ -0,0 +1,39 @@
+# $NetBSD: Makefile.in,v 1.1.1.1 2002/12/20 18:13:52 schmonz Exp $
+# Original from FreeBSD, no rcs id.
+
+all: libdir adddir admindir createdir deletedir infodir
+
+libdir:
+ cd lib && ${MAKE}
+adddir:
+ cd add && ${MAKE}
+admindir:
+ cd admin && ${MAKE}
+createdir:
+ cd create && ${MAKE}
+deletedir:
+ cd delete && ${MAKE}
+infodir:
+ cd info && ${MAKE}
+
+install: all
+ @MKDIR@ -p @prefix@/sbin
+ cd add && ${MAKE} install
+ cd admin && ${MAKE} install
+ cd create && ${MAKE} install
+ cd delete && ${MAKE} install
+ cd info && ${MAKE} install
+
+clean:
+ cd lib && ${MAKE} clean
+ cd add && ${MAKE} clean
+ cd admin && ${MAKE} clean
+ cd create && ${MAKE} clean
+ cd delete && ${MAKE} clean
+ cd info && ${MAKE} clean
+
+distclean: clean
+ rm -f config.log config.status config.cache
+ rm -f Makefile */Makefile
+ rm -f lib/lib.h lib/config.h
+
diff --git a/pkgtools/pkg_install/files/README b/pkgtools/pkg_install/files/README
new file mode 100644
index 00000000000..d9690897850
--- /dev/null
+++ b/pkgtools/pkg_install/files/README
@@ -0,0 +1,18 @@
+# $NetBSD: README,v 1.1.1.1 2002/12/20 18:13:52 schmonz Exp $
+# Original from FreeBSD, no rcs id.
+
+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 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, who then proceeded to add another couple
+of dozen features on top. Whee! :-)
+
+In another round of enhancements, NetBSD changes were added by
+Alistair Crooks and Hubert Feyrer, Thorsten Frueauf and Christian E.
+Hopps.
+
+When making snapshots, please modify PKGTOOLS_VERSION in lib/version.h
+to that day's date.
diff --git a/pkgtools/pkg_install/files/TODO b/pkgtools/pkg_install/files/TODO
new file mode 100644
index 00000000000..9234464024a
--- /dev/null
+++ b/pkgtools/pkg_install/files/TODO
@@ -0,0 +1,16 @@
+To Do
+=====
+add man page installation
+
+Done
+====
+Do correct GNU Makefile-ish things
+make a real mkdtemp thing
+get rid of BINDIR
+get rid of TAR_CMD
+REMOVE_CMD -> RM
+RMDIR_CMD -> RMDIR
+use MKDIR for mkdir -p uses via vsystem. Use mkdir(2) for all other uses.
+add digest files if MD5File not in -lc or -lmd
+try it on Darwin
+use full pathnames for utilities which are executed by vsystem()
diff --git a/pkgtools/pkg_install/files/add/Makefile.in b/pkgtools/pkg_install/files/add/Makefile.in
new file mode 100644
index 00000000000..c12c60c41c9
--- /dev/null
+++ b/pkgtools/pkg_install/files/add/Makefile.in
@@ -0,0 +1,40 @@
+# $NetBSD: Makefile.in,v 1.1.1.1 2002/12/20 18:13:54 schmonz Exp $
+# Original from FreeBSD, no rcs id.
+
+PREFIX= @prefix@
+INSTALL= @INSTALL@
+
+mandir= ${PREFIX}/man
+mandircat1= ${mandir}/cat1
+
+CC= @CC@
+CCLD= $(CC)
+LIBS= @LIBS@ -linstall
+CPPFLAGS= @CPPFLAGS@
+DEFS= @DEFS@ -I. -I@srcdir@ -I../lib
+CFLAGS= @CFLAGS@
+LDFLAGS= @LDFLAGS@ -L../lib
+
+LINK= $(CCLD) $(CFLAGS) $(LDFLAGS) -o $@
+COMPILE= $(CC) $(DEFS) $(CPPFLAGS) $(CFLAGS)
+
+PROG= pkg_add
+
+SRCS= main.c perform.c futil.c extract.c verify.c
+OBJS= main.o perform.o futil.o extract.o verify.o
+
+all: ${PROG}
+
+${PROG}: ${OBJS}
+ ${LINK} ${OBJS} ${LIBS}
+
+.c.o:
+ $(COMPILE) -c $< -o $@
+
+clean:
+ rm -f ${OBJS} ${PROG}
+
+install:
+ ${INSTALL} ${PROG} ${PREFIX}/sbin
+ ${INSTALL} -m 755 -d ${mandircat1}
+ ${INSTALL} -m 444 ${PROG}.cat1 ${mandircat1}/${PROG}.1
diff --git a/pkgtools/pkg_install/files/add/add.h b/pkgtools/pkg_install/files/add/add.h
new file mode 100644
index 00000000000..6452a2a7e9c
--- /dev/null
+++ b/pkgtools/pkg_install/files/add/add.h
@@ -0,0 +1,48 @@
+/* $NetBSD: add.h,v 1.1.1.1 2002/12/20 18:13:54 schmonz Exp $ */
+
+/* from FreeBSD Id: add.h,v 1.8 1997/02/22 16:09:15 peter Exp */
+
+/*
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 18 July 1993
+ *
+ * Include and define various things wanted by the add command.
+ *
+ */
+
+#ifndef _INST_ADD_H_INCLUDE
+#define _INST_ADD_H_INCLUDE
+
+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;
+extern char *Directory;
+extern char *PkgName;
+extern char FirstPen[];
+extern add_mode_t AddMode;
+
+int make_hierarchy(char *);
+int extract_plist(char *, package_t *);
+void apply_perms(char *, char *);
+
+#endif /* _INST_ADD_H_INCLUDE */
diff --git a/pkgtools/pkg_install/files/add/extract.c b/pkgtools/pkg_install/files/add/extract.c
new file mode 100644
index 00000000000..911dd696ae0
--- /dev/null
+++ b/pkgtools/pkg_install/files/add/extract.c
@@ -0,0 +1,353 @@
+/* $NetBSD: extract.c,v 1.1.1.1 2002/12/20 18:13:55 schmonz Exp $ */
+
+#if 0
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static const char *rcsid = "FreeBSD - Id: extract.c,v 1.17 1997/10/08 07:45:35 charnier Exp";
+#else
+__RCSID("$NetBSD: extract.c,v 1.1.1.1 2002/12/20 18:13:55 schmonz Exp $");
+#endif
+#endif
+#endif
+
+/*
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 18 July 1993
+ *
+ * This is the package extraction code for the add module.
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#include "lib.h"
+#include "add.h"
+
+#define TAR_ARGS " cf - "
+#define TARX_CMD "|" TAR_FULLPATHNAME " xpf - -C "
+
+/*
+ * This macro is used to determine if the 'where_args' buffer is big enough to add the
+ * current string (usually a filename) plus some extra commands (the contents of TARX_CMD, and
+ * the directory name stored in 'Directory').
+ *
+ * The string " 'str'" will be added so we need room for the string plus 3 chars plus the other arguments.
+ *
+ * In addition, we will add " 'srt'" to the perm_args buffer so we need to ensure that there is room
+ * for that.
+ */
+#define TOOBIG(str) ((strlen(str) + 3 + strlen(TARX_CMD) + strlen(Directory) + where_count >= maxargs) \
+ || (strlen(str) + 3 + perm_count >= maxargs))
+
+#define PUSHOUT(todir) /* push out string */ \
+ if (where_count > sizeof(TAR_FULLPATHNAME) + sizeof(TAR_ARGS)-1) { \
+ strcat(where_args, TARX_CMD); \
+ strcat(where_args, todir); \
+ if (system(where_args)) { \
+ cleanup(0); \
+ errx(2, "can not invoke %lu byte %s pipeline: %s", \
+ (u_long)strlen(where_args), TAR_FULLPATHNAME, \
+ where_args); \
+ } \
+ strcpy(where_args, TAR_FULLPATHNAME TAR_ARGS); \
+ where_count = strlen(where_args); \
+ } \
+ if (perm_count) { \
+ apply_perms(todir, perm_args); \
+ perm_args[0] = 0; \
+ perm_count = 0; \
+ }
+
+
+static void
+rollback(char *name, char *home, plist_t *start, plist_t *stop)
+{
+ plist_t *q;
+ char try[FILENAME_MAX], bup[FILENAME_MAX], *dir;
+
+ dir = home;
+ for (q = start; q != stop; q = q->next) {
+ if (q->type == PLIST_FILE) {
+ (void) snprintf(try, sizeof(try), "%s/%s", dir, q->name);
+ if (make_preserve_name(bup, sizeof(bup), name, try) && fexists(bup)) {
+#ifdef HAVE_CHFLAGS
+ (void) chflags(try, 0);
+#endif
+ (void) unlink(try);
+ if (rename(bup, try))
+ warnx("rollback: unable to rename %s back to %s", bup, try);
+ }
+ } else if (q->type == PLIST_CWD) {
+ if (strcmp(q->name, "."))
+ dir = q->name;
+ else
+ dir = home;
+ }
+ }
+}
+
+
+/*
+ * Return 0 on error, 1 for success.
+ */
+int
+extract_plist(char *home, package_t *pkg)
+{
+ plist_t *p = pkg->head;
+ char *last_file;
+ char *where_args, *perm_args, *last_chdir;
+ int maxargs, where_count = 0, perm_count = 0, add_count;
+ Boolean preserve;
+
+ maxargs = sysconf(_SC_ARG_MAX) / 2; /* Just use half the argument space */
+ where_args = malloc(maxargs);
+ if (!where_args) {
+ cleanup(0);
+ errx(2, "can't get argument list space");
+ }
+ perm_args = malloc(maxargs);
+ if (!perm_args) {
+ cleanup(0);
+ errx(2, "can't get argument list space");
+ }
+ strcpy(where_args, TAR_FULLPATHNAME TAR_ARGS);
+ /*
+ * we keep track of how many characters are stored in 'where_args' with 'where_count'.
+ * Note this doesn't include the trailing null character.
+ */
+ where_count = strlen(where_args);
+
+ perm_args[0] = 0;
+ /*
+ * we keep track of how many characters are stored in 'perm__args' with 'perm_count'.
+ * Note this doesn't include the trailing null character.
+ */
+ perm_count = 0;
+
+ last_chdir = 0;
+ preserve = find_plist_option(pkg, "preserve") ? TRUE : FALSE;
+
+ /* Reset the world */
+ Owner = NULL;
+ Group = NULL;
+ Mode = NULL;
+ last_file = NULL;
+ Directory = home;
+
+ /* Open Package Database for writing */
+ if (pkgdb_open(0) == -1) {
+ cleanup(0);
+ err(1, "can't open pkgdb");
+ }
+ /* Do it */
+ while (p) {
+ char cmd[FILENAME_MAX];
+
+ switch (p->type) {
+ case PLIST_NAME:
+ PkgName = p->name;
+ if (Verbose)
+ printf("extract: Package name is %s\n", p->name);
+ break;
+
+ case PLIST_FILE:
+ last_file = p->name;
+ if (Verbose)
+ printf("extract: %s/%s\n", Directory, p->name);
+ if (!Fake) {
+ char try[FILENAME_MAX];
+
+ if (strrchr(p->name, '\'')) {
+ cleanup(0);
+ errx(2, "Bogus filename \"%s\"", p->name);
+ }
+
+ /* first try to rename it into place */
+ (void) snprintf(try, sizeof(try), "%s/%s", Directory, p->name);
+ if (fexists(try)) {
+#ifdef HAVE_CHFLAGS
+ (void) chflags(try, 0); /* XXX hack - if truly immutable, rename fails */
+#endif
+ if (preserve && PkgName) {
+ char pf[FILENAME_MAX];
+
+ if (make_preserve_name(pf, sizeof(pf), PkgName, try)) {
+ if (rename(try, pf)) {
+ warnx(
+ "unable to back up %s to %s, aborting pkg_add",
+ try, pf);
+ rollback(PkgName, home, pkg->head, p);
+ return 0;
+ }
+ }
+ }
+ }
+ if (rename(p->name, try) == 0) {
+ /* note in pkgdb */
+ {
+ char *s, t[FILENAME_MAX];
+ int rc;
+
+ (void) snprintf(t, sizeof(t), "%s/%s", Directory, p->name);
+
+ s = pkgdb_retrieve(t);
+#ifdef PKGDB_DEBUG
+ printf("pkgdb_retrieve(\"%s\")=\"%s\"\n", t, s); /* pkgdb-debug - HF */
+#endif
+ if (s)
+ warnx("Overwriting %s - pkg %s bogus/conflicting?", t, s);
+ else {
+ rc = pkgdb_store(t, PkgName);
+#ifdef PKGDB_DEBUG
+ printf("pkgdb_store(\"%s\", \"%s\") = %d\n", t, PkgName, rc); /* pkgdb-debug - HF */
+#endif
+
+ }
+ }
+
+ /* try to add to list of perms to be changed and run in bulk. */
+ if (p->name[0] == '/' || TOOBIG(p->name)) {
+ PUSHOUT(Directory);
+ }
+ /* note, if the following line is modified, TOOBIG must be adjusted accordingly */
+ add_count = snprintf(&perm_args[perm_count], maxargs - perm_count, "'%s' ", p->name);
+ if (add_count > maxargs - perm_count) {
+ cleanup(0);
+ errx(2, "oops, miscounted strings!");
+ }
+ perm_count += add_count;
+ } else {
+ /* rename failed, try copying with a big tar command */
+ if (last_chdir != Directory) {
+ PUSHOUT(last_chdir);
+ last_chdir = Directory;
+ } else if (p->name[0] == '/' || TOOBIG(p->name)) {
+ PUSHOUT(Directory);
+ }
+ /* note, if the following line is modified, TOOBIG must be adjusted accordingly */
+ add_count = snprintf(&where_args[where_count], maxargs - where_count, " '%s'", p->name);
+ if (add_count > maxargs - where_count) {
+ cleanup(0);
+ errx(2, "oops, miscounted strings!");
+ }
+ where_count += add_count;
+ /* note, if the following line is modified, TOOBIG must be adjusted accordingly */
+ add_count = snprintf(&perm_args[perm_count],
+ maxargs - perm_count,
+ "'%s' ", p->name);
+ if (add_count > maxargs - perm_count) {
+ cleanup(0);
+ errx(2, "oops, miscounted strings!");
+ }
+ perm_count += add_count;
+
+ /* note in pkgdb */
+ /* XXX would be better to store in PUSHOUT, but
+ * that would probably affect too much code I prefer
+ * not to touch - HF */
+ {
+ char *s, t[FILENAME_MAX], *u;
+ int rc;
+
+ if (p->name[0] == '/')
+ u = p->name;
+ else {
+ (void) snprintf(t, sizeof(t), "%s/%s", Directory, p->name);
+ u = t;
+ }
+
+ s = pkgdb_retrieve(t);
+#ifdef PKGDB_DEBUG
+ printf("pkgdb_retrieve(\"%s\")=\"%s\"\n", t, s); /* pkgdb-debug - HF */
+#endif
+ if (s)
+ warnx("Overwriting %s - pkg %s bogus/conflicting?", t, s);
+ else {
+ rc = pkgdb_store(t, PkgName);
+#ifdef PKGDB_DEBUG
+ printf("pkgdb_store(\"%s\", \"%s\") = %d\n", t, PkgName, rc); /* pkgdb-debug - HF */
+#endif
+ }
+ }
+ }
+ }
+ 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) {
+ cleanup(0);
+ errx(2, "unable to make directory '%s'", p->name);
+ }
+ Directory = p->name;
+ } else
+ Directory = home;
+ break;
+
+ case PLIST_CMD:
+ if (last_file == NULL && strchr(p->name, '%') != NULL) {
+ cleanup(0);
+ errx(2, "no last file specified for '%s' command", p->name);
+ }
+ format_cmd(cmd, sizeof(cmd), p->name, Directory, last_file);
+ PUSHOUT(Directory);
+ if (Verbose)
+ printf("extract: execute '%s'\n", cmd);
+ if (!Fake && system(cmd))
+ warnx("command '%s' failed", cmd);
+ 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;
+
+ case PLIST_COMMENT:
+ break;
+
+ case PLIST_IGNORE:
+ p = p->next;
+ break;
+
+ default:
+ break;
+ }
+ p = p->next;
+ }
+ PUSHOUT(Directory);
+ pkgdb_close();
+ free(perm_args);
+ free(where_args);
+ return 1;
+}
diff --git a/pkgtools/pkg_install/files/add/futil.c b/pkgtools/pkg_install/files/add/futil.c
new file mode 100644
index 00000000000..2cbbfee9603
--- /dev/null
+++ b/pkgtools/pkg_install/files/add/futil.c
@@ -0,0 +1,107 @@
+/* $NetBSD: futil.c,v 1.1.1.1 2002/12/20 18:13:55 schmonz Exp $ */
+
+#if 0
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static const char *rcsid = "from FreeBSD Id: futil.c,v 1.7 1997/10/08 07:45:39 charnier Exp";
+#else
+__RCSID("$NetBSD: futil.c,v 1.1.1.1 2002/12/20 18:13:55 schmonz Exp $");
+#endif
+#endif
+#endif
+
+/*
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 18 July 1993
+ *
+ * Miscellaneous file access utilities.
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#include "lib.h"
+#include "add.h"
+
+/*
+ * Assuming dir is a desired directory name, make it and all intervening
+ * directories necessary.
+ */
+int
+make_hierarchy(char *dir)
+{
+ char *cp1, *cp2;
+
+ if (dir[0] == '/')
+ cp1 = cp2 = dir + 1;
+ else
+ cp1 = cp2 = dir;
+ while (cp2) {
+ if ((cp2 = strchr(cp1, '/')) != NULL)
+ *cp2 = '\0';
+ if (fexists(dir)) {
+ if (!(isdir(dir) || islinktodir(dir)))
+ return FAIL;
+ } else {
+ if (mkdir(dir, 0755) < 0) {
+ return FAIL;
+ }
+ apply_perms(NULL, dir);
+ }
+ /* Put it back */
+ if (cp2) {
+ *cp2 = '/';
+ cp1 = cp2 + 1;
+ }
+ }
+ return SUCCESS;
+}
+
+/*
+ * Using permission defaults, apply them as necessary
+ */
+void
+apply_perms(char *dir, char *arg)
+{
+ char *cd_to;
+
+ if (!dir || *arg == '/')/* absolute path? */
+ cd_to = "/";
+ else
+ cd_to = dir;
+
+ if (Mode)
+ if (vsystem("cd %s && %s -R %s %s", cd_to, CHMOD_CMD, Mode, arg))
+ warnx("couldn't change modes of '%s' to '%s'", arg, Mode);
+ if (Owner && Group) {
+ if (vsystem("cd %s && %s -R %s.%s %s", cd_to, CHOWN_CMD, Owner, Group, arg))
+ warnx("couldn't change owner/group of '%s' to '%s.%s'",
+ arg, Owner, Group);
+ return;
+ }
+ if (Owner) {
+ if (vsystem("cd %s && %s -R %s %s", cd_to, CHOWN_CMD, Owner, arg))
+ warnx("couldn't change owner of '%s' to '%s'", arg, Owner);
+ return;
+ } else if (Group)
+ if (vsystem("cd %s && %s -R %s %s", cd_to, CHGRP_CMD, Group, arg))
+ warnx("couldn't change group of '%s' to '%s'", arg, Group);
+}
diff --git a/pkgtools/pkg_install/files/add/main.c b/pkgtools/pkg_install/files/add/main.c
new file mode 100644
index 00000000000..8a4bb49fff9
--- /dev/null
+++ b/pkgtools/pkg_install/files/add/main.c
@@ -0,0 +1,197 @@
+/* $NetBSD: main.c,v 1.1.1.1 2002/12/20 18:13:55 schmonz Exp $ */
+
+#if 0
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char *rcsid = "from FreeBSD Id: main.c,v 1.16 1997/10/08 07:45:43 charnier Exp";
+#else
+__RCSID("$NetBSD: main.c,v 1.1.1.1 2002/12/20 18:13:55 schmonz Exp $");
+#endif
+#endif
+#endif
+
+/*
+ *
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 18 July 1993
+ *
+ * This is the add module.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+#include "lib.h"
+#include "add.h"
+#include "verify.h"
+
+static char Options[] = "hVvIRfnp:SMs:t:u";
+
+char *Prefix = NULL;
+Boolean NoInstall = FALSE;
+Boolean NoRecord = FALSE;
+
+char *Mode = NULL;
+char *Owner = NULL;
+char *Group = NULL;
+char *PkgName = NULL;
+char *Directory = NULL;
+char FirstPen[FILENAME_MAX];
+add_mode_t AddMode = NORMAL;
+int upgrade = 0;
+
+static void
+usage(void)
+{
+ (void) fprintf(stderr, "%s\n%s\n",
+ "usage: pkg_add [-hVvInfRMSu] [-t template] [-p prefix]",
+ " [-s verification-type] pkg-name [pkg-name ...]");
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ int ch, error=0;
+ lpkg_head_t pkgs;
+ struct rlimit rlim;
+ int rc;
+
+ setprogname(argv[0]);
+
+ while ((ch = getopt(argc, argv, Options)) != -1) {
+ switch (ch) {
+ case 'v':
+ Verbose = TRUE;
+ break;
+
+ case 'p':
+ Prefix = optarg;
+ break;
+
+ case 'I':
+ NoInstall = TRUE;
+ break;
+
+ case 'R':
+ NoRecord = TRUE;
+ break;
+
+ case 'f':
+ Force = TRUE;
+ break;
+
+ case 'n':
+ Fake = TRUE;
+ Verbose = TRUE;
+ break;
+
+ case 's':
+ set_verification(optarg);
+ break;
+
+ case 't':
+ strcpy(FirstPen, optarg);
+ break;
+
+ case 'S':
+ AddMode = SLAVE;
+ break;
+
+ case 'M':
+ AddMode = MASTER;
+ break;
+
+ case 'V':
+ show_version();
+ /* NOTREACHED */
+
+ case 'u':
+ upgrade = 1;
+ break;
+ case 'h':
+ case '?':
+ default:
+ usage();
+ break;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ path_create(getenv("PKG_PATH"));
+ TAILQ_INIT(&pkgs);
+
+ if (AddMode != SLAVE) {
+ /* Get all the remaining package names, if any */
+ for (ch = 0; *argv; ch++, argv++) {
+ lpkg_t *lpp;
+
+ if (IS_STDIN(*argv))
+ lpp = alloc_lpkg("-");
+ else
+ lpp = alloc_lpkg(*argv);
+
+ TAILQ_INSERT_TAIL(&pkgs, lpp, lp_link);
+ }
+ } else if (!ch)
+ /* If no packages, yelp */
+ warnx("missing package name(s)"), usage();
+ else if (ch > 1 && AddMode == MASTER)
+ warnx("only one package name may be specified with master mode"),
+ usage();
+
+ /* Increase # of max. open file descriptors as high as possible */
+ rc = getrlimit(RLIMIT_NOFILE, &rlim);
+ if (rc == -1) {
+ warn("cannot retrieve max. number of open files resource limit");
+ } else {
+ rlim.rlim_cur = rlim.rlim_max;
+ rc = setrlimit(RLIMIT_NOFILE, &rlim);
+ if (rc == -1) {
+ warn("cannot increase max. number of open files resource limit, try 'ulimit'");
+ } else {
+ if (Verbose)
+ printf("increasing RLIMIT_NOFILE to max. %ld open files\n", (long)rlim.rlim_cur);
+ }
+ }
+
+ error += pkg_perform(&pkgs);
+ if (error != 0) {
+ if (Verbose)
+ warnx("%d package addition(s) failed", error);
+ exit(1);
+ }
+ exit(0);
+}
diff --git a/pkgtools/pkg_install/files/add/perform.c b/pkgtools/pkg_install/files/add/perform.c
new file mode 100644
index 00000000000..2d3b9ccd62c
--- /dev/null
+++ b/pkgtools/pkg_install/files/add/perform.c
@@ -0,0 +1,752 @@
+/* $NetBSD: perform.c,v 1.1.1.1 2002/12/20 18:13:56 schmonz Exp $ */
+
+#if 0
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static const char *rcsid = "from FreeBSD Id: perform.c,v 1.44 1997/10/13 15:03:46 jkh Exp";
+#else
+__RCSID("$NetBSD: perform.c,v 1.1.1.1 2002/12/20 18:13:56 schmonz Exp $");
+#endif
+#endif
+#endif
+
+/*
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 18 July 1993
+ *
+ * This is the main body of the add module.
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_ASSERT_H
+#include <assert.h>
+#endif
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#include "lib.h"
+#include "add.h"
+#include "verify.h"
+
+#include <signal.h>
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+static char LogDir[FILENAME_MAX];
+static int zapLogDir; /* Should we delete LogDir? */
+
+static package_t Plist;
+static char *Home;
+
+static int
+sanity_check(const char *pkg)
+{
+ int errc = 0;
+
+ if (!fexists(CONTENTS_FNAME)) {
+ warnx("package %s has no CONTENTS file!", pkg);
+ errc = 1;
+ } else if (!fexists(COMMENT_FNAME)) {
+ warnx("package %s has no COMMENT file!", pkg);
+ errc = 1;
+ } else if (!fexists(DESC_FNAME)) {
+ warnx("package %s has no DESC file!", pkg);
+ errc = 1;
+ }
+ return errc;
+}
+
+/* install a pre-requisite package. Returns 1 if it installed it */
+static int
+installprereq(const char *name, int *errc)
+{
+ int ret;
+ ret = 0;
+
+ if (Verbose)
+ printf("Loading it from %s.\n", name);
+ path_setenv("PKG_PATH");
+ if (vsystem("%s -s %s %s%s%s %s%s",
+ ADD_CMD,
+ get_verification(),
+ Force ? "-f " : "",
+ Prefix ? "-p " : "",
+ Prefix ? Prefix : "",
+ Verbose ? "-v " : "",
+ name)) {
+ warnx("autoload of dependency `%s' failed%s",
+ name, Force ? " (proceeding anyway)" : "!");
+ if (!Force)
+ ++(*errc);
+ } else {
+ ret = 1;
+ }
+
+ return ret;
+}
+
+/*
+ * Install a single package
+ * Returns 0 if everything is ok, >0 else
+ */
+static int
+pkg_do(const char *pkg)
+{
+ char playpen[FILENAME_MAX];
+ char extract_contents[FILENAME_MAX];
+ char upgrade_from[FILENAME_MAX];
+ char upgrade_via[FILENAME_MAX];
+ char upgrade_to[FILENAME_MAX];
+ int upgrading = 0;
+ char *where_to, *tmp, *extract;
+ char *dbdir;
+ const char *exact;
+ FILE *cfile;
+ int errc;
+ plist_t *p;
+ struct stat sb;
+ int inPlace;
+ int rc;
+
+ errc = 0;
+ zapLogDir = 0;
+ LogDir[0] = '\0';
+ strcpy(playpen, FirstPen);
+ inPlace = 0;
+ dbdir = (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR;
+
+ /* make sure dbdir actually exists! */
+ if (!(isdir(dbdir) || islinktodir(dbdir))) {
+ if (vsystem("%s -p -m 755 %s", MKDIR, dbdir)) {
+ errx(1, "Database-dir %s cannot be generated, aborting.",
+ dbdir);
+ }
+ }
+
+ /* Are we coming in for a second pass, everything already extracted?
+ * (Slave mode) */
+ if (!pkg) {
+ fgets(playpen, FILENAME_MAX, stdin);
+ playpen[strlen(playpen) - 1] = '\0'; /* remove newline! */
+ if (chdir(playpen) == FAIL) {
+ warnx("add in SLAVE mode can't chdir to %s", playpen);
+ return 1;
+ }
+ read_plist(&Plist, stdin);
+ where_to = playpen;
+ }
+ /* Nope - do it now */
+ else {
+ const char *tmppkg;
+
+ tmppkg = fileFindByPath(pkg);
+ if (tmppkg == NULL) {
+ warnx("no pkg found for '%s', sorry.", pkg);
+ return 1;
+ }
+
+ pkg = tmppkg;
+
+ if (IS_URL(pkg)) {
+ Home = fileGetURL(pkg);
+ if (Home == NULL) {
+ warnx("unable to fetch `%s' by URL", pkg);
+ }
+ where_to = Home;
+
+ /* make sure the pkg is verified */
+ if (!verify(pkg)) {
+ warnx("Package %s will not be extracted", pkg);
+ goto bomb;
+ }
+ }
+ else { /* local */
+ if (!IS_STDIN(pkg)) {
+ /* not stdin */
+ if (!ispkgpattern(pkg)) {
+ if (stat(pkg, &sb) == FAIL) {
+ warnx("can't stat package file '%s'", pkg);
+ goto bomb;
+ }
+ /* make sure the pkg is verified */
+ if (!verify(pkg)) {
+ warnx("Package %s will not be extracted", pkg);
+ goto bomb;
+ }
+ }
+#if defined(HAVE_TAR__FAST_READ)
+ (void) snprintf(extract_contents, sizeof(extract_contents), "--fast-read %s", CONTENTS_FNAME);
+#else
+ (void) snprintf(extract_contents, sizeof(extract_contents), "%s", CONTENTS_FNAME);
+#endif
+ extract = extract_contents;
+ } else {
+ /* some values for stdin */
+ extract = NULL;
+ sb.st_size = 100000; /* Make up a plausible average size */
+ }
+ Home = make_playpen(playpen, sizeof(playpen), sb.st_size * 4);
+ if (!Home)
+ warnx("unable to make playpen for %ld bytes",
+ (long) (sb.st_size * 4));
+ where_to = Home;
+ if (unpack(pkg, extract)) {
+ warnx("unable to extract table of contents file from `%s' - not a package?",
+ pkg);
+ goto bomb;
+ }
+ }
+
+ cfile = fopen(CONTENTS_FNAME, "r");
+ if (!cfile) {
+ warnx("unable to open table of contents file `%s' - not a package?",
+ CONTENTS_FNAME);
+ goto bomb;
+ }
+ read_plist(&Plist, cfile);
+ fclose(cfile);
+
+ if (!IS_URL(pkg)) {
+ /* Extract directly rather than moving? Oh goodie! */
+ if (find_plist_option(&Plist, "extract-in-place")) {
+ if (Verbose)
+ printf("Doing in-place extraction for %s\n", pkg);
+ p = find_plist(&Plist, PLIST_CWD);
+ if (p) {
+ if (!(isdir(p->name) || islinktodir(p->name)) && !Fake) {
+ if (Verbose)
+ printf("Desired prefix of %s does not exist, creating.\n", p->name);
+ (void) vsystem("%s -p %s", MKDIR, p->name);
+ }
+ if (chdir(p->name) == -1) {
+ warn("unable to change directory to `%s'", p->name);
+ goto bomb;
+ }
+ where_to = p->name;
+ inPlace = 1;
+ } else {
+ warnx(
+ "no prefix specified in `%s' - this is a bad package!",
+ pkg);
+ goto bomb;
+ }
+ }
+
+ /*
+ * Apply a crude heuristic to see how much space the package will
+ * take up once it's unpacked. I've noticed that most packages
+ * compress an average of 75%, so multiply by 4 for good measure.
+ */
+
+ if (!inPlace && min_free(playpen) < sb.st_size * 4) {
+ warnx("projected size of %ld exceeds available free space.\n"
+ "Please set your PKG_TMPDIR variable to point to a location with more\n"
+ "free space and try again", (long) (sb.st_size * 4));
+ warnx("not extracting %s\ninto %s, sorry!",
+ pkg, where_to);
+ goto bomb;
+ }
+
+ /* If this is a direct extract and we didn't want it, stop now */
+ if (inPlace && Fake)
+ goto success;
+
+ /* Finally unpack the whole mess */
+ if (unpack(pkg, NULL)) {
+ warnx("unable to extract `%s'!", pkg);
+ goto bomb;
+ }
+ }
+
+ /* Check for sanity */
+ if (sanity_check(pkg))
+ goto bomb;
+
+ /* If we're running in MASTER mode, just output the plist and return */
+ if (AddMode == MASTER) {
+ printf("%s\n", where_playpen());
+ write_plist(&Plist, stdout, NULL);
+ return 0;
+ }
+ }
+
+ /*
+ * If we have a prefix, delete the first one we see and add this
+ * one in place of it.
+ */
+ if (Prefix) {
+ delete_plist(&Plist, FALSE, PLIST_CWD, NULL);
+ add_plist_top(&Plist, PLIST_CWD, Prefix);
+ }
+
+ setenv(PKG_PREFIX_VNAME, (p = find_plist(&Plist, PLIST_CWD)) ? p->name : ".", 1);
+ /* Protect against old packages with bogus @name fields */
+ PkgName = (p = find_plist(&Plist, PLIST_NAME)) ? p->name : "anonymous";
+
+ /* See if this package (exact version) is already registered */
+ (void) snprintf(LogDir, sizeof(LogDir), "%s/%s", dbdir, PkgName);
+ if ((isdir(LogDir) || islinktodir(LogDir)) && !Force) {
+ warnx("package `%s' already recorded as installed", PkgName);
+ goto success; /* close enough for government work */
+ }
+
+ /* See if some other version of us is already installed */
+ {
+ char *s;
+
+ if ((s = strrchr(PkgName, '-')) != NULL) {
+ char buf[FILENAME_MAX];
+ char installed[FILENAME_MAX];
+
+ /*
+ * See if the pkg is already installed. If so, we might
+ * want to upgrade it.
+ */
+ (void) snprintf(buf, sizeof(buf), "%.*s[0-9]*",
+ (int)(s - PkgName) + 1, PkgName);
+ if (findmatchingname(dbdir, buf, note_whats_installed, installed) > 0) {
+ if (upgrade) {
+ /*
+ * Upgrade step 1/4: Check if the new version is ok with all pkgs
+ * that require this pkg
+ */
+ /* TODO */
+
+ /*
+ * Upgrade step 2/4: Do the actual update by moving aside
+ * the +REQUIRED_BY file, deinstalling the old pkg, adding
+ * the new one and moving the +REQUIRED_BY file back
+ * into place (finished in step 3/4)
+ */
+ snprintf(upgrade_from, sizeof(upgrade_from), "%s/%s/" REQUIRED_BY_FNAME,
+ dbdir, installed);
+ snprintf(upgrade_via, sizeof(upgrade_via), "%s/.%s." REQUIRED_BY_FNAME,
+ dbdir, installed);
+ snprintf(upgrade_to, sizeof(upgrade_to), "%s/%s/" REQUIRED_BY_FNAME,
+ dbdir, PkgName);
+
+ if (Verbose)
+ printf("Upgrading %s to %s.\n", installed, PkgName);
+
+ if (fexists(upgrade_from)) { /* Are there any dependencies? */
+ if (Verbose)
+ printf("mv %s %s\n", upgrade_from, upgrade_via);
+ rc = rename(upgrade_from, upgrade_via);
+ assert(rc == 0);
+
+ upgrading = 1;
+ }
+
+ if (Verbose)
+ printf("pkg_delete '%s'\n", installed);
+ vsystem("%s/sbin/pkg_delete '%s'\n", PREFIX, installed);
+
+ } else {
+ warnx("other version '%s' already installed", installed);
+
+ errc = 1;
+ goto success; /* close enough for government work */
+ }
+ }
+ }
+ }
+
+ /* See if there are conflicting packages installed */
+ for (p = Plist.head; p; p = p->next) {
+ char installed[FILENAME_MAX];
+
+ if (p->type != PLIST_PKGCFL)
+ continue;
+ if (Verbose)
+ printf("Package `%s' conflicts with `%s'.\n", PkgName, p->name);
+
+ /* was: */
+ /* if (!vsystem("/usr/sbin/pkg_info -qe '%s'", p->name)) { */
+ if (findmatchingname(dbdir, p->name, note_whats_installed, installed) > 0) {
+ warnx("Conflicting package `%s'installed, please use\n"
+ "\t\"pkg_delete %s\" first to remove it!", installed, installed);
+ ++errc;
+ }
+ }
+
+ /* Quick pre-check if any conflicting dependencies are installed
+ * (e.g. version X is installed, but version Y is required)
+ */
+ for (p = Plist.head; p; p = p->next) {
+ char installed[FILENAME_MAX];
+
+ if (p->type != PLIST_PKGDEP)
+ continue;
+ if (Verbose)
+ printf("Depends pre-scan: `%s' required.\n", p->name);
+ /* if (vsystem("/usr/sbin/pkg_info -qe '%s'", p->name)) { */
+ if (findmatchingname(dbdir, p->name, note_whats_installed, installed) <= 0) {
+ /*
+ * required pkg not found. look if it's available with a more liberal
+ * pattern. If so, this will lead to problems later (check on "some
+ * other version of us is already installed" will fail, see above),
+ * and we better stop right now.
+ */
+ char *s;
+ int skip = -1;
+
+ /* doing this right required to parse the full version(s),
+ * do a 99% solution here for now */
+ if (strchr(p->name, '{'))
+ continue; /* would remove trailing '}' else */
+
+ if ((s = strpbrk(p->name, "<>")) != NULL) {
+ skip = 0;
+ } else if ((s = strrchr(p->name, '-')) != NULL) {
+ skip = 1;
+ }
+
+ if (skip >= 0) {
+ char buf[FILENAME_MAX];
+
+ (void) snprintf(buf, sizeof(buf),
+ skip ? "%.*s[0-9]*" : "%.*s-[0-9]*",
+ (int)(s - p->name) + skip, p->name);
+ if (findmatchingname(dbdir, buf, note_whats_installed, installed) > 0) {
+ warnx("pkg `%s' required, but `%s' found installed.",
+ p->name, installed);
+
+ if (upgrading) {
+ printf("HF: upgrade note -- could 'pkg_delete %s', and let the normal\n"
+ "dependency handling reinstall the updated package, assuming one IS\n"
+ "available. But then I'd expect proper binary pkgs being available for\n"
+ "the upgrade case.\n", installed);
+ }
+
+ if (Force) {
+ warnx("Proceeding anyways.");
+ } else {
+ warnx("Please resolve this conflict!");
+ errc = 1;
+ goto success; /* close enough */
+ }
+ }
+ }
+ }
+ }
+
+
+ /* Now check the packing list for dependencies */
+ for (exact = NULL, p = Plist.head; p; p = p->next) {
+ char installed[FILENAME_MAX];
+
+ if (p->type == PLIST_BLDDEP) {
+ exact = p->name;
+ continue;
+ }
+ if (p->type != PLIST_PKGDEP) {
+ exact = NULL;
+ continue;
+ }
+ if (Verbose)
+ printf("Package `%s' depends on `%s'.\n", PkgName, p->name);
+
+ if (findmatchingname(dbdir, p->name, note_whats_installed, installed) != 1) {
+ /* required pkg not found - need to pull in */
+ if (Fake) {
+ /* fake install (???) */
+ if (Verbose)
+ printf("Package dependency %s for %s not installed%s\n", p->name, pkg,
+ Force ? " (proceeding anyway)" : "!");
+ } else {
+ int done = 0;
+ int errc0 = 0;
+
+ if (exact != NULL) {
+ /* first try the exact name, from the @blddep */
+ done = installprereq(exact, &errc0);
+ }
+ if (!done) {
+ done = installprereq(p->name, &errc0);
+ }
+ if (!done && !Force) {
+ errc += errc0;
+ }
+ }
+ } else if (Verbose) {
+ printf(" - %s already installed.\n", installed);
+ }
+ }
+
+ if (errc != 0)
+ goto bomb;
+
+ /* Look for the requirements file */
+ if (fexists(REQUIRE_FNAME)) {
+ vsystem("%s +x %s", CHMOD_CMD, REQUIRE_FNAME); /* be sure */
+ if (Verbose)
+ printf("Running requirements file first for %s.\n", PkgName);
+ if (!Fake && vsystem("./%s %s INSTALL", REQUIRE_FNAME, PkgName)) {
+ warnx("package %s fails requirements %s", pkg,
+ Force ? "installing anyway" : "- not installed");
+ if (!Force) {
+ errc = 1;
+ goto success; /* close enough for government work */
+ }
+ }
+ }
+
+ /* If we're really installing, and have an installation file, run it */
+ if (!NoInstall && fexists(INSTALL_FNAME)) {
+ vsystem("%s +x %s", CHMOD_CMD, 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");
+ errc = 1;
+ goto success; /* nothing to uninstall yet */
+ }
+ }
+
+ /* Now finally extract the entire show if we're not going direct */
+ if (!inPlace && !Fake)
+ if (!extract_plist(".", &Plist)) {
+ errc = 1;
+ goto fail;
+ }
+
+ if (!Fake && fexists(MTREE_FNAME)) {
+ if (Verbose)
+ printf("Running mtree for %s.\n", PkgName);
+ p = find_plist(&Plist, PLIST_CWD);
+ if (Verbose)
+ printf("%s -U -f %s -d -e -p %s\n", MTREE, MTREE_FNAME, p ? p->name : "/");
+ if (!Fake) {
+ if (vsystem("%s -U -f %s -d -e -p %s", MTREE, MTREE_FNAME, p ? p->name : "/"))
+ warnx("mtree returned a non-zero status - continuing");
+ }
+ unlink(MTREE_FNAME); /* remove this line to tar up pkg later - HF */
+ }
+
+ /* 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");
+ errc = 1;
+ goto fail;
+ }
+ }
+
+ /* Time to record the deed? */
+ if (!NoRecord && !Fake) {
+ char contents[FILENAME_MAX];
+
+ umask(022);
+ if (getuid() != 0)
+ warnx("not running as root - trying to record install anyway");
+ if (!PkgName) {
+ warnx("no package name! can't record package, sorry");
+ errc = 1;
+ goto success; /* well, partial anyway */
+ }
+ (void) snprintf(LogDir, sizeof(LogDir), "%s/%s", dbdir, PkgName);
+ zapLogDir = 1; /* LogDir contains something valid now */
+ if (Verbose)
+ printf("Attempting to record package into %s.\n", LogDir);
+ if (make_hierarchy(LogDir)) {
+ warnx("can't record package into '%s', you're on your own!",
+ LogDir);
+ memset(LogDir, 0, sizeof(LogDir));
+ errc = 1;
+ goto success; /* close enough for government work */
+ }
+ /* Make sure pkg_info can read the entry */
+ vsystem("%s a+rx %s", CHMOD_CMD, LogDir);
+ if (fexists(DEINSTALL_FNAME))
+ move_file(".", DEINSTALL_FNAME, LogDir);
+ if (fexists(REQUIRE_FNAME))
+ move_file(".", REQUIRE_FNAME, LogDir);
+ if (fexists(SIZE_PKG_FNAME))
+ move_file(".", SIZE_PKG_FNAME, LogDir);
+ if (fexists(SIZE_ALL_FNAME))
+ move_file(".", SIZE_ALL_FNAME, LogDir);
+ (void) snprintf(contents, sizeof(contents), "%s/%s", LogDir, CONTENTS_FNAME);
+ cfile = fopen(contents, "w");
+ if (!cfile) {
+ warnx("can't open new contents file '%s'! can't register pkg",
+ contents);
+ goto success; /* can't log, but still keep pkg */
+ }
+ write_plist(&Plist, cfile, NULL);
+ fclose(cfile);
+ move_file(".", DESC_FNAME, LogDir);
+ move_file(".", COMMENT_FNAME, LogDir);
+ if (fexists(BUILD_VERSION_FNAME))
+ move_file(".", BUILD_VERSION_FNAME, LogDir);
+ if (fexists(BUILD_INFO_FNAME))
+ move_file(".", BUILD_INFO_FNAME, LogDir);
+ if (fexists(DISPLAY_FNAME))
+ move_file(".", DISPLAY_FNAME, LogDir);
+
+ /* register dependencies */
+ /* we could save some cycles here if we remembered what we
+ * installed above (in case we got a wildcard dependency) */
+ /* XXX remembering in p->name would NOT be good! */
+ 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);
+ (void) snprintf(contents, sizeof(contents), "%s/%s", dbdir,
+ basename_of(p->name));
+ if (ispkgpattern(p->name)) {
+ char *s;
+ s = findbestmatchingname(dirname_of(contents),
+ basename_of(contents));
+ if (s != NULL) {
+ char *t;
+ t = strrchr(contents, '/');
+ strcpy(t + 1, s);
+ free(s);
+ } else {
+ errx(1, "Where did our dependency go?!");
+ /* this shouldn't happen... X-) */
+ }
+ }
+ strcat(contents, "/");
+ strcat(contents, REQUIRED_BY_FNAME);
+
+ cfile = fopen(contents, "a");
+ if (!cfile)
+ warnx("can't open dependency file '%s'!\n"
+ "dependency registration is incomplete", contents);
+ else {
+ fprintf(cfile, "%s\n", PkgName);
+ if (fclose(cfile) == EOF)
+ warnx("cannot properly close file %s", contents);
+ }
+ }
+ if (Verbose)
+ printf("Package %s registered in %s\n", PkgName, LogDir);
+ }
+
+ if ((p = find_plist(&Plist, PLIST_DISPLAY)) != NULL) {
+ FILE *fp;
+ char buf[BUFSIZ];
+
+ (void) snprintf(buf, sizeof(buf), "%s/%s", LogDir, p->name);
+ fp = fopen(buf, "r");
+ if (fp) {
+ putc('\n', stdout);
+ while (fgets(buf, sizeof(buf), fp))
+ fputs(buf, stdout);
+ putc('\n', stdout);
+ (void) fclose(fp);
+ } else
+ warnx("cannot open %s as display file", buf);
+ }
+
+ goto success;
+
+bomb:
+ errc = 1;
+ goto success;
+
+fail:
+ /* Nuke the whole (installed) show, XXX but don't clean directories */
+ if (!Fake)
+ delete_package(FALSE, FALSE, &Plist);
+
+success:
+ /* delete the packing list contents */
+ free_plist(&Plist);
+ leave_playpen(Home);
+
+ if (upgrading) {
+ /*
+ * Upgrade step 3/4: move back +REQUIRED_BY file
+ * (see also step 2/4)
+ */
+ rc = rename(upgrade_via, upgrade_to);
+ assert(rc == 0);
+
+ /*
+ * Upgrade step 4/4: Fix pkgs that depend on us to
+ * depend on the new version instead of the old
+ * one by fixing @pkgdep lines in +CONTENTS files.
+ */
+ /* TODO */
+ }
+
+ return errc;
+}
+
+void
+cleanup(int signo)
+{
+ static int alreadyCleaning;
+ void (*oldint) (int);
+ void (*oldhup) (int);
+ oldint = signal(SIGINT, SIG_IGN);
+ oldhup = signal(SIGHUP, SIG_IGN);
+
+ if (!alreadyCleaning) {
+ alreadyCleaning = 1;
+ if (signo)
+ printf("Signal %d received, cleaning up.\n", signo);
+ if (!Fake && zapLogDir && LogDir[0])
+ vsystem("%s -rf %s", RM, LogDir);
+ leave_playpen(Home);
+ if (signo)
+ exit(1);
+ }
+ signal(SIGINT, oldint);
+ signal(SIGHUP, oldhup);
+}
+
+int
+pkg_perform(lpkg_head_t *pkgs)
+{
+ int err_cnt = 0;
+ lpkg_t *lpp;
+
+ signal(SIGINT, cleanup);
+ signal(SIGHUP, cleanup);
+
+ if (AddMode == SLAVE)
+ err_cnt = pkg_do(NULL);
+ else {
+ while ((lpp = TAILQ_FIRST(pkgs)) != NULL) {
+ path_prepend_from_pkgname(lpp->lp_name);
+ err_cnt += pkg_do(lpp->lp_name);
+ path_prepend_clear();
+ TAILQ_REMOVE(pkgs, lpp, lp_link);
+ free_lpkg(lpp);
+ }
+ }
+
+ ftp_stop();
+
+ return err_cnt;
+}
diff --git a/pkgtools/pkg_install/files/add/pkg_add.1 b/pkgtools/pkg_install/files/add/pkg_add.1
new file mode 100644
index 00000000000..3771adf407d
--- /dev/null
+++ b/pkgtools/pkg_install/files/add/pkg_add.1
@@ -0,0 +1,512 @@
+.\" $NetBSD: pkg_add.1,v 1.1.1.1 2002/12/20 18:13:57 schmonz Exp $
+.\"
+.\" FreeBSD install - a package for the installation and maintainance
+.\" of non-core utilities.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" Jordan K. Hubbard
+.\"
+.\"
+.\" @(#)pkg_add.1
+.\"
+.Dd August 15, 2002
+.Dt PKG_ADD 1
+.Os
+.Sh NAME
+.Nm pkg_add
+.Nd a utility for installing and upgrading software package distributions
+.Sh SYNOPSIS
+.Nm ""
+.Op Fl fIMnRSuVv
+.Bk -words
+.Op Fl s Ar verification-type
+.Ek
+.Bk -words
+.Op Fl t Ar template
+.Ek
+.Bk -words
+.Op Fl p Ar prefix
+.Ek
+.Ar \fR[ftp://[\fIuser\fR[:\fIpassword]\fR@]\fIhost\fR[:\fIport\fR]][/\fIpath/\fR]pkg-name ...
+.Sh DESCRIPTION
+The
+.Nm
+command is used to extract and upgrade packages that have been
+previously created with the
+.Xr pkg_create 1
+command.
+Packages are prepared collections of pre-built binaries, documentation,
+configurations, installation instructions and/or other files.
+.Nm
+can recursively install other packages that the current package
+depends on or requires from both local disk and via FTP.
+.Sh WARNING
+.Bf -emphasis
+Since the
+.Nm
+command may execute scripts or programs contained within a package file,
+your system may be susceptible to ``Trojan horses'' or other subtle
+attacks from miscreants who create dangerous package files.
+.Pp
+You are advised to verify the competence and identity of those who
+provide installable package files.
+For extra protection, use the digital signatures provided where possible
+(see the
+.Fl s
+option), or, failing that, use the
+.Fl M
+flag to extract the package file, and inspect its contents and scripts
+to ensure 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),
+.Cm @dirrm ,
+.Cm @exec ,
+and
+.Cm @unexec
+directives, and/or use the
+.Xr pkg_info 1
+command to examine the package file.
+.Ef
+.Sh OPTIONS
+The following command line arguments are supported:
+.Bl -tag -width indent
+.It Ar pkg-name [ ... ]
+The named packages are installed.
+.Ar pkg-name
+may be either a URL or a local pathname,
+a package name of "-" will cause
+.Nm
+to read from stdin.
+If the packages are not found in the current
+working directory,
+.Nm
+will search them in each directory named by the
+.Ev PKG_PATH
+environment variable.
+Any dependencies required by the installed package will be searched
+in the same location that the original package was installed from.
+.It Fl f
+Force installation to proceed even if prerequisite packages are not
+installed or the requirements script fails.
+Although
+.Nm
+will still try to find and auto-install missing prerequisite packages,
+a failure to find one will not be fatal.
+.It Fl I
+If an installation script exists for a given package, do not execute it.
+.It Fl M
+Run in
+.Cm MASTER
+mode.
+This is a very specialized mode for running
+.Nm
+and is meant to be run in conjunction with
+.Cm SLAVE
+mode.
+When run in this mode,
+.Nm
+does no work beyond extracting the package into a temporary staging
+area (see the
+.Fl t
+option), reading in the packing list, and then dumping it (prefaced by
+the current staging area) to stdout where it may be filtered by a
+program such as
+.Xr sed 1 .
+When used in conjunction with
+.Cm SLAVE
+mode, it allows you to make radical changes to the package structure
+before acting on its contents.
+.It Fl n
+Don't actually install a package, just report the steps that
+would be taken if it was.
+.It Fl p Ar prefix
+Set
+.Ar prefix
+as the directory in which to extract files from a package.
+If a package has set its default directory, it will be overridden
+by this flag.
+Note that only the first
+.Cm @cwd
+directive will be replaced, since
+.Nm
+has no way of knowing which directory settings are relative and
+which are absolute.
+It is rare in any case to see more than one directory transition made,
+but when such does happen and you wish to have control over *all* directory
+transitions, then you may then wish to look into the use of
+.Cm MASTER
+and
+.Cm SLAVE
+modes (see the
+.Fl M
+and
+.Fl S
+options).
+.It Fl R
+Do not record the installation of a package.
+This means that you cannot deinstall it later, so only use this option if
+you know what you are doing!
+.It Fl S
+Run in
+.Cm SLAVE
+mode.
+This is a very specialized mode for running
+.Nm
+and is meant to be run in conjunction with
+.Cm MASTER
+mode.
+When run in this mode,
+.Nm
+expects the release contents to be already extracted and waiting
+in the staging area, the location of which is read as a string
+from stdin.
+The complete packing list is also read from stdin,
+and the contents then acted on as normal.
+.It Fl s Ar verification-type
+Use a callout to an external program to verify the binary package
+being installed against an existing detached signature file.
+The signature file must reside in the same directory
+as the binary package.
+At the present time, the following verification types
+are defined: none, gpg and pgp5.
+The signature will be verified at install time, and the results
+will be displayed.
+If the signature type is anything other than none, the user will be asked if
+.Nm
+should proceed to install the binary package.
+The user must then take the decision whether to proceed or not, depending
+upon the amount of trust that is placed in the signatory of the binary
+package.
+Please note that, at the current time, it is not possible to use
+the verification feature when using
+.Nm
+to add a binary package via a URL - the package, and the related
+detached signature file, must be local
+for the verification to work.
+.It Fl t Ar template
+Use
+.Ar template
+as the input to
+.Xr mktemp 3
+when creating a ``staging area.''
+By default, this is the string
+.Pa /var/tmp/instmp.XXXXXX ,
+but it may be necessary to override it in the situation where
+space in your
+.Pa /var/tmp
+directory is limited.
+Be sure to leave some number of `X' characters for
+.Xr mktemp 3
+to fill in with a unique ID.
+.Pp
+You can get a performance boost by setting the staging area
+.Ar template
+to reside on the same disk partition as target directories for package
+file installation; often this is
+.Pa /usr .
+.It Fl u
+If the package that's being installed is already installed, either
+in the same or a different version, an update is performed.
+See below for a more detailed description of the process.
+.It Fl V
+Print version number and exit.
+.It Fl v
+Turn on verbose output.
+.El
+.Pp
+One or more
+.Ar pkg-name
+arguments may be specified, each being either a file containing the
+package (these usually ending with the ``.tgz'' suffix) or a
+URL pointing at a file available on an ftp or web site.
+Thus you may extract files directly from their anonymous ftp or WWW
+locations (e.g.
+.Nm
+ftp://ftp.netbsd.org/pub/NetBSD/packages/1.5/i386/shells/bash-2.04.tgz).
+Note: If you wish to use
+.Bf -emphasis
+passive mode
+.Ef
+ftp in such transfers, set
+the variable
+.Bf -emphasis
+FTP_PASSIVE_MODE
+.Ef
+to some value in your environment.
+Otherwise, the more standard ACTIVE mode may be used.
+If
+.Nm
+consistently fails to fetch a package from a site known to work,
+it may be because you have a firewall that demands the usage of
+.Bf -emphasis
+passive mode
+.Ef
+ftp.
+.Sh TECHNICAL DETAILS
+.Nm
+extracts each package's "packing list"
+into a special staging directory in /var/tmp (or $PKG_TMPDIR if set)
+and then runs through the following sequence to fully extract the contents
+of the package:
+.Bl -enum -offset indent
+.It
+A check is made to determine if the package or another version of it
+is already recorded as installed.
+If it is,
+installation is terminated if the
+.Fl u
+option is not given.
+.Pp
+If the
+.Fl u
+option is given, it's assumed the package should be upgraded instead.
+This is prepared by moving an existing
+.Pa +REQUIRED_BY
+file aside (if it exists), and by running
+.Xr pkg_delete 1
+on the installed package.
+Installation then proceeds as if the package
+was not installed, and restores the
+.Pa +REQUIRED_BY
+file afterwards.
+.It
+A check is made to determine if the package conflicts (from
+.Cm @pkgcfl
+directives, see
+.Xr pkg_create 1 )
+with an already recorded as installed package.
+If it is, installation is terminated.
+.It
+All package dependencies (from
+.Cm @pkgdep
+directives, see
+.Xr pkg_create 1 )
+are read from the packing list.
+If any of these required packages are not currently installed,
+an attempt is made to find and install it;
+if the missing package cannot be found or installed,
+the installation is terminated.
+.It
+A search is made for any
+.Cm @option
+directives which control how the package is added to the system.
+The only currently implemented option is
+.Cm @option extract-in-place ,
+which causes the package to be extracted directly into its
+prefix directory rather than moving it through a staging area in
+.Pa /var/tmp .
+.It
+If
+.Cm @option extract-in-place
+is enabled, the package is now extracted directly into its
+final location, otherwise it is extracted into the staging area.
+.It
+If the package contains a
+.Ar require
+script (see
+.Xr pkg_create 1 ) ,
+it is executed with the following arguments:
+.Bl -tag -width indentindent
+.It Ar pkg-name
+The name of the package being installed
+.It Cm INSTALL
+Keyword denoting to the script that it is to run an installation requirements
+check.
+(The keyword is useful only to scripts which serve multiple functions).
+.El
+.Pp
+If the
+.Ar require
+script exits with a non-zero status code, the installation is terminated.
+.It
+If the package contains an
+.Ar install
+script, it is executed with the following arguments:
+.Bl -tag -width indentindent
+.It Ar pkg-name
+The name of the package being installed.
+.It Cm PRE-INSTALL
+Keyword denoting that the script is to perform any actions needed before
+the package is installed.
+.El
+.Pp
+If the
+.Ar install
+script exits with a non-zero status code, the installation is terminated.
+.It
+If
+.Cm @option extract-in-place
+is not present in the packing list,
+then it is used as a guide for moving (or copying, as necessary) files from
+the staging area into their final locations.
+.It
+If the package contains an
+.Ar mtreefile
+file (see
+.Xr pkg_create 1 ) ,
+then mtree is invoked as:
+.Bd -filled -offset indent -compact
+.Cm mtree
+.Fl u
+.Fl f
+.Ar mtreefile
+.Fl d
+.Fl e
+.Fl p
+.Pa prefix
+.Ed
+where
+.Pa prefix
+is either the prefix specified with the
+.Fl p
+flag or, if no
+.Fl p
+flag was specified, the name of the first directory named by a
+.Cm @cwd
+directive within this package.
+.It
+If an
+.Ar install
+script exists for the package, it is executed with the following arguments:
+.Bl -tag -width indentindent
+.It Ar pkg_name
+The name of the package being installed.
+.It Cm POST-INSTALL
+Keyword denoting that the script is to perform any actions needed
+after the package has been installed.
+.El
+.It
+After installation is complete, a copy of the packing list,
+.Ar deinstall
+script, description, and display files are copied into
+.Pa /var/db/pkg/\*[Lt]pkg-name\*[Gt]
+for subsequent possible use by
+.Xr pkg_delete 1 .
+Any package dependencies are recorded in the other packages'
+.Pa /var/db/pkg/\*[Lt]other-pkg\*[Gt]/+REQUIRED_BY
+file
+(if the environment variable PKG_DBDIR is set, this overrides the
+.Pa /var/db/pkg/
+path shown above).
+.It
+The staging area is deleted and the program terminates.
+.It
+Finally, if we were upgrading a package, any
+.Pa +REQUIRED_BY
+file that was moved aside before upgrading was started is now moved
+back into place.
+.El
+.Pp
+The
+.Ar install
+and
+.Ar require
+scripts are called with the environment variable
+.Ev PKG_PREFIX
+set to the installation prefix (see the
+.Fl p
+option above).
+This allows a package author to write a script
+that reliably performs some action on the directory where the package
+is installed, even if the user might change it with the
+.Fl p
+flag to
+.Cm pkg_add .
+.Sh ENVIRONMENT
+.Ss PKG_PATH
+The value of the
+.Ev PKG_PATH
+is used if a given package can't be found, it's usually set to
+.Pa /usr/pkgsrc/packages/All .
+The environment variable
+should be a series of entries separated by semicolons.
+Each entry consists of a directory name or URL.
+The current directory may be indicated implicitly by an empty directory
+name, or explicitly by a single period.
+FTP URLs may not end with a slash.
+.Ss PKG_DBDIR
+Where to register packages instead of
+.Pa /var/db/pkg .
+.Ss PKG_TMPDIR
+Staging directory for installing packages, defaults to /var/tmp.
+Set to directory with lots of free disk if you run out of
+space when installing a binary package.
+.Sh EXAMPLES
+In all cases,
+.Nm
+will try to install binary packages listed in dependencies list.
+.Pp
+You can specify a compiled binary package explicitly on the command line.
+.Bd -literal
+# pkg_add /usr/pkgsrc/packages/All/tcsh-6.10.00.tgz
+.Ed
+.Pp
+If you omit the version number,
+.Nm
+will install the latest version available.
+With
+.Fl v ,
+.Nm
+emits more messages to terminal.
+.Bd -literal
+# pkg_add -v /usr/pkgsrc/packages/All/unzip
+.Ed
+.Pp
+You can grab a compiled binary package from remote location, by specifying
+a URL.
+The URL can be put into an environment variable,
+.Ev PKG_PATH .
+.Bd -literal
+# pkg_add -v ftp://ftp.netbsd.org/pub/NetBSD/packages/1.5/i386/All/mozilla-0.8.1.tgz
+
+# export PKG_PATH=ftp://ftp.netbsd.org/pub/NetBSD/packages/1.5/i386/All
+# pkg_add -v mozilla
+.Ed
+.Sh SEE ALSO
+.Xr pkg_admin 1 ,
+.Xr pkg_create 1 ,
+.Xr pkg_delete 1 ,
+.Xr pkg_info 1 ,
+.Xr mktemp 3 ,
+.Xr sysconf 3 ,
+.Xr packages 7 ,
+.Xr mtree 8
+.Sh AUTHORS
+.Bl -tag -width indent -compact
+.It "Jordan Hubbard"
+Initial work and ongoing development.
+.It "John Kohl"
+.Nx
+refinements.
+.It "Hubert Feyrer"
+.Nx
+wildcard dependency processing, pkgdb, upgrading, etc.
+.El
+.Sh BUGS
+Hard links between files in a distribution are only preserved if either
+(1) the staging area is on the same file system as the target directory of
+all the links to the file, or (2) all the links to the file are bracketed by
+.Cm @cwd
+directives in the contents file,
+.Em and
+and the link names are extracted with a single
+.Cm tar
+command (not split between
+invocations due to exec argument-space limitations--this depends on the
+value returned by
+.Fn sysconf _SC_ARG_MAX ) .
+.Pp
+Pkg upgrading needs a lot more work to be really universal.
+.Pp
+Sure to be others.
diff --git a/pkgtools/pkg_install/files/add/pkg_add.cat1 b/pkgtools/pkg_install/files/add/pkg_add.cat1
new file mode 100644
index 00000000000..0ced1555a5d
--- /dev/null
+++ b/pkgtools/pkg_install/files/add/pkg_add.cat1
@@ -0,0 +1,305 @@
+PKG_ADD(1) NetBSD Reference Manual PKG_ADD(1)
+
+NNAAMMEE
+ ppkkgg__aadddd - a utility for installing and upgrading software package distri-
+ butions
+
+SSYYNNOOPPSSIISS
+ ppkkgg__aadddd [--ffIIMMnnRRSSuuVVvv] [--ss _v_e_r_i_f_i_c_a_t_i_o_n_-_t_y_p_e] [--tt _t_e_m_p_l_a_t_e] [--pp _p_r_e_f_i_x]
+ [ftp://[_u_s_e_r[:_p_a_s_s_w_o_r_d_]@]_h_o_s_t[:_p_o_r_t]][/_p_a_t_h_/]pkg-name ...
+
+DDEESSCCRRIIPPTTIIOONN
+ The ppkkgg__aadddd command is used to extract and upgrade packages that have
+ been previously created with the pkg_create(1) command. Packages are
+ prepared collections of pre-built binaries, documentation, configura-
+ tions, installation instructions and/or other files. ppkkgg__aadddd can recur-
+ sively install other packages that the current package depends on or re-
+ quires from both local disk and via FTP.
+
+WWAARRNNIINNGG
+ _S_i_n_c_e _t_h_e ppkkgg__aadddd _c_o_m_m_a_n_d _m_a_y _e_x_e_c_u_t_e _s_c_r_i_p_t_s _o_r _p_r_o_g_r_a_m_s _c_o_n_t_a_i_n_e_d _w_i_t_h_-
+ _i_n _a _p_a_c_k_a_g_e _f_i_l_e_, _y_o_u_r _s_y_s_t_e_m _m_a_y _b_e _s_u_s_c_e_p_t_i_b_l_e _t_o _`_`_T_r_o_j_a_n _h_o_r_s_e_s_'_' _o_r
+ _o_t_h_e_r _s_u_b_t_l_e _a_t_t_a_c_k_s _f_r_o_m _m_i_s_c_r_e_a_n_t_s _w_h_o _c_r_e_a_t_e _d_a_n_g_e_r_o_u_s _p_a_c_k_a_g_e _f_i_l_e_s_.
+
+ _Y_o_u _a_r_e _a_d_v_i_s_e_d _t_o _v_e_r_i_f_y _t_h_e _c_o_m_p_e_t_e_n_c_e _a_n_d _i_d_e_n_t_i_t_y _o_f _t_h_o_s_e _w_h_o _p_r_o_-
+ _v_i_d_e _i_n_s_t_a_l_l_a_b_l_e _p_a_c_k_a_g_e _f_i_l_e_s_. _F_o_r _e_x_t_r_a _p_r_o_t_e_c_t_i_o_n_, _u_s_e _t_h_e _d_i_g_i_t_a_l
+ _s_i_g_n_a_t_u_r_e_s _p_r_o_v_i_d_e_d _w_h_e_r_e _p_o_s_s_i_b_l_e _(_s_e_e _t_h_e --ss _o_p_t_i_o_n_)_, _o_r_, _f_a_i_l_i_n_g _t_h_a_t_,
+ _u_s_e _t_h_e --MM _f_l_a_g _t_o _e_x_t_r_a_c_t _t_h_e _p_a_c_k_a_g_e _f_i_l_e_, _a_n_d _i_n_s_p_e_c_t _i_t_s _c_o_n_t_e_n_t_s _a_n_d
+ _s_c_r_i_p_t_s _t_o _e_n_s_u_r_e _i_t _p_o_s_e_s _n_o _d_a_n_g_e_r _t_o _y_o_u_r _s_y_s_t_e_m_'_s _i_n_t_e_g_r_i_t_y_. _P_a_y
+ _p_a_r_t_i_c_u_l_a_r _a_t_t_e_n_t_i_o_n _t_o _a_n_y _+_I_N_S_T_A_L_L_, _+_D_E_I_N_S_T_A_L_L_, _+_R_E_Q_U_I_R_E _o_r _+_M_T_R_E_E___D_I_R_S
+ _f_i_l_e_s_, _a_n_d _i_n_s_p_e_c_t _t_h_e _+_C_O_N_T_E_N_T_S _f_i_l_e _f_o_r @@ccwwdd_, @@mmooddee _(_c_h_e_c_k _f_o_r _s_e_t_u_i_d_)_,
+ @@ddiirrrrmm_, @@eexxeecc_, _a_n_d @@uunneexxeecc _d_i_r_e_c_t_i_v_e_s_, _a_n_d_/_o_r _u_s_e _t_h_e pkg_info(_1) _c_o_m_m_a_n_d
+ _t_o _e_x_a_m_i_n_e _t_h_e _p_a_c_k_a_g_e _f_i_l_e_.
+
+OOPPTTIIOONNSS
+ The following command line arguments are supported:
+
+ _p_k_g_-_n_a_m_e [_._._.]
+ The named packages are installed. _p_k_g_-_n_a_m_e may be either a URL
+ or a local pathname, a package name of "-" will cause ppkkgg__aadddd to
+ read from stdin. If the packages are not found in the current
+ working directory, ppkkgg__aadddd will search them in each directory
+ named by the PKG_PATH environment variable. Any dependencies re-
+ quired by the installed package will be searched in the same lo-
+ cation that the original package was installed from.
+
+ --ff Force installation to proceed even if prerequisite packages are
+ not installed or the requirements script fails. Although ppkkgg__aadddd
+ will still try to find and auto-install missing prerequisite
+ packages, a failure to find one will not be fatal.
+
+ --II If an installation script exists for a given package, do not exe-
+ cute it.
+
+ --MM Run in MMAASSTTEERR mode. This is a very specialized mode for running
+ ppkkgg__aadddd and is meant to be run in conjunction with SSLLAAVVEE mode.
+ When run in this mode, ppkkgg__aadddd does no work beyond extracting the
+ package into a temporary staging area (see the --tt option), read-
+ ing in the packing list, and then dumping it (prefaced by the
+ current staging area) to stdout where it may be filtered by a
+ program such as sed(1). When used in conjunction with SSLLAAVVEE
+ mode, it allows you to make radical changes to the package struc-
+ ture before acting on its contents.
+
+ --nn Don't actually install a package, just report the steps that
+ would be taken if it was.
+
+ --pp _p_r_e_f_i_x
+ Set _p_r_e_f_i_x as the directory in which to extract files from a
+ package. If a package has set its default directory, it will be
+ overridden by this flag. Note that only the first @@ccwwdd directive
+ will be replaced, since ppkkgg__aadddd has no way of knowing which di-
+ rectory settings are relative and which are absolute. It is rare
+ in any case to see more than one directory transition made, but
+ when such does happen and you wish to have control over *all* di-
+ rectory transitions, then you may then wish to look into the use
+ of MMAASSTTEERR and SSLLAAVVEE modes (see the --MM and --SS options).
+
+ --RR Do not record the installation of a package. This means that you
+ cannot deinstall it later, so only use this option if you know
+ what you are doing!
+
+ --SS Run in SSLLAAVVEE mode. This is a very specialized mode for running
+ ppkkgg__aadddd and is meant to be run in conjunction with MMAASSTTEERR mode.
+ When run in this mode, ppkkgg__aadddd expects the release contents to be
+ already extracted and waiting in the staging area, the location
+ of which is read as a string from stdin. The complete packing
+ list is also read from stdin, and the contents then acted on as
+ normal.
+
+ --ss _v_e_r_i_f_i_c_a_t_i_o_n_-_t_y_p_e
+ Use a callout to an external program to verify the binary package
+ being installed against an existing detached signature file. The
+ signature file must reside in the same directory as the binary
+ package. At the present time, the following verification types
+ are defined: none, gpg and pgp5. The signature will be verified
+ at install time, and the results will be displayed. If the sig-
+ nature type is anything other than none, the user will be asked
+ if ppkkgg__aadddd should proceed to install the binary package. The us-
+ er must then take the decision whether to proceed or not, depend-
+ ing upon the amount of trust that is placed in the signatory of
+ the binary package. Please note that, at the current time, it is
+ not possible to use the verification feature when using ppkkgg__aadddd
+ to add a binary package via a URL - the package, and the related
+ detached signature file, must be local for the verification to
+ work.
+
+ --tt _t_e_m_p_l_a_t_e
+ Use _t_e_m_p_l_a_t_e as the input to mktemp(3) when creating a ``staging
+ area.'' By default, this is the string _/_v_a_r_/_t_m_p_/_i_n_s_t_m_p_._X_X_X_X_X_X,
+ but it may be necessary to override it in the situation where
+ space in your _/_v_a_r_/_t_m_p directory is limited. Be sure to leave
+ some number of `X' characters for mktemp(3) to fill in with a
+ unique ID.
+
+ You can get a performance boost by setting the staging area
+ _t_e_m_p_l_a_t_e to reside on the same disk partition as target directo-
+ ries for package file installation; often this is _/_u_s_r.
+
+ --uu If the package that's being installed is already installed, ei-
+ ther in the same or a different version, an update is performed.
+ See below for a more detailed description of the process.
+
+ --VV Print version number and exit.
+
+ --vv Turn on verbose output.
+
+ One or more _p_k_g_-_n_a_m_e arguments may be specified, each being either a file
+ containing the package (these usually ending with the ``.tgz'' suffix) or
+ a URL pointing at a file available on an ftp or web site. Thus you may
+ extract files directly from their anonymous ftp or WWW locations (e.g.
+ ppkkgg__aadddd ftp://ftp.netbsd.org/pub/NetBSD/pack-
+ ages/1.5/i386/shells/bash-2.04.tgz). Note: If you wish to use _p_a_s_s_i_v_e
+ _m_o_d_e ftp in such transfers, set the variable _F_T_P___P_A_S_S_I_V_E___M_O_D_E to some
+ value in your environment. Otherwise, the more standard ACTIVE mode may
+ be used. If ppkkgg__aadddd consistently fails to fetch a package from a site
+ known to work, it may be because you have a firewall that demands the us-
+ age of _p_a_s_s_i_v_e _m_o_d_e ftp.
+
+TTEECCHHNNIICCAALL DDEETTAAIILLSS
+ ppkkgg__aadddd extracts each package's "packing list" into a special staging di-
+ rectory in /var/tmp (or $PKG_TMPDIR if set) and then runs through the
+ following sequence to fully extract the contents of the package:
+
+ 1. A check is made to determine if the package or another version
+ of it is already recorded as installed. If it is, installa-
+ tion is terminated if the --uu option is not given.
+
+ If the --uu option is given, it's assumed the package should be
+ upgraded instead. This is prepared by moving an existing
+ _+_R_E_Q_U_I_R_E_D___B_Y file aside (if it exists), and by running
+ pkg_delete(1) on the installed package. Installation then
+ proceeds as if the package was not installed, and restores the
+ _+_R_E_Q_U_I_R_E_D___B_Y file afterwards.
+
+ 2. A check is made to determine if the package conflicts (from
+ @@ppkkggccffll directives, see pkg_create(1)) with an already record-
+ ed as installed package. If it is, installation is terminat-
+ ed.
+
+ 3. All package dependencies (from @@ppkkggddeepp directives, see
+ pkg_create(1)) are read from the packing list. If any of
+ these required packages are not currently installed, an at-
+ tempt is made to find and install it; if the missing package
+ cannot be found or installed, the installation is terminated.
+
+ 4. A search is made for any @@ooppttiioonn directives which control how
+ the package is added to the system. The only currently imple-
+ mented option is @@ooppttiioonn eexxttrraacctt--iinn--ppllaaccee, which causes the
+ package to be extracted directly into its prefix directory
+ rather than moving it through a staging area in _/_v_a_r_/_t_m_p.
+
+ 5. If @@ooppttiioonn eexxttrraacctt--iinn--ppllaaccee is enabled, the package is now ex-
+ tracted directly into its final location, otherwise it is ex-
+ tracted into the staging area.
+
+ 6. If the package contains a _r_e_q_u_i_r_e script (see pkg_create(1)),
+ it is executed with the following arguments:
+
+ _p_k_g_-_n_a_m_e The name of the package being installed
+
+ IINNSSTTAALLLL Keyword denoting to the script that it is to run
+ an installation requirements check. (The key-
+ word is useful only to scripts which serve mul-
+ tiple functions).
+
+ If the _r_e_q_u_i_r_e script exits with a non-zero status code, the
+ installation is terminated.
+
+ 7. If the package contains an _i_n_s_t_a_l_l script, it is executed with
+ the following arguments:
+
+ _p_k_g_-_n_a_m_e The name of the package being installed.
+
+ PPRREE--IINNSSTTAALLLL Keyword denoting that the script is to perform
+ any actions needed before the package is in-
+ stalled.
+
+ If the _i_n_s_t_a_l_l script exits with a non-zero status code, the
+ installation is terminated.
+
+ 8. If @@ooppttiioonn eexxttrraacctt--iinn--ppllaaccee is not present in the packing
+ list, then it is used as a guide for moving (or copying, as
+ necessary) files from the staging area into their final loca-
+ tions.
+
+ 9. If the package contains an _m_t_r_e_e_f_i_l_e file (see pkg_create(1)),
+ then mtree is invoked as:
+ mmttrreeee --uu --ff _m_t_r_e_e_f_i_l_e --dd --ee --pp _p_r_e_f_i_x
+ where _p_r_e_f_i_x is either the prefix specified with the --pp flag
+ or, if no --pp flag was specified, the name of the first direc-
+ tory named by a @@ccwwdd directive within this package.
+
+ 10. If an _i_n_s_t_a_l_l script exists for the package, it is executed
+ with the following arguments:
+
+ _p_k_g___n_a_m_e The name of the package being installed.
+
+ PPOOSSTT--IINNSSTTAALLLL Keyword denoting that the script is to perform
+ any actions needed after the package has been
+ installed.
+
+ 11. After installation is complete, a copy of the packing list,
+ _d_e_i_n_s_t_a_l_l script, description, and display files are copied
+ into _/_v_a_r_/_d_b_/_p_k_g_/_<_p_k_g_-_n_a_m_e_> for subsequent possible use by
+ pkg_delete(1). Any package dependencies are recorded in the
+ other packages' _/_v_a_r_/_d_b_/_p_k_g_/_<_o_t_h_e_r_-_p_k_g_>_/_+_R_E_Q_U_I_R_E_D___B_Y file (if
+ the environment variable PKG_DBDIR is set, this overrides the
+ _/_v_a_r_/_d_b_/_p_k_g_/ path shown above).
+
+ 12. The staging area is deleted and the program terminates.
+
+ 13. Finally, if we were upgrading a package, any _+_R_E_Q_U_I_R_E_D___B_Y file
+ that was moved aside before upgrading was started is now moved
+ back into place.
+
+ The _i_n_s_t_a_l_l and _r_e_q_u_i_r_e scripts are called with the environment variable
+ PKG_PREFIX set to the installation prefix (see the --pp option above).
+ This allows a package author to write a script that reliably performs
+ some action on the directory where the package is installed, even if the
+ user might change it with the --pp flag to ppkkgg__aadddd.
+
+EENNVVIIRROONNMMEENNTT
+ PPKKGG__PPAATTHH
+ The value of the PKG_PATH is used if a given package can't be found, it's
+ usually set to _/_u_s_r_/_p_k_g_s_r_c_/_p_a_c_k_a_g_e_s_/_A_l_l. The environment variable should
+ be a series of entries separated by semicolons. Each entry consists of a
+ directory name or URL. The current directory may be indicated implicitly
+ by an empty directory name, or explicitly by a single period. FTP URLs
+ may not end with a slash.
+
+ PPKKGG__DDBBDDIIRR
+ Where to register packages instead of _/_v_a_r_/_d_b_/_p_k_g.
+
+ PPKKGG__TTMMPPDDIIRR
+ Staging directory for installing packages, defaults to /var/tmp. Set to
+ directory with lots of free disk if you run out of space when installing
+ a binary package.
+
+EEXXAAMMPPLLEESS
+ In all cases, ppkkgg__aadddd will try to install binary packages listed in de-
+ pendencies list.
+
+ You can specify a compiled binary package explicitly on the command line.
+
+ # pkg_add /usr/pkgsrc/packages/All/tcsh-6.10.00.tgz
+
+ If you omit the version number, ppkkgg__aadddd will install the latest version
+ available. With --vv, ppkkgg__aadddd emits more messages to terminal.
+
+ # pkg_add -v /usr/pkgsrc/packages/All/unzip
+
+ You can grab a compiled binary package from remote location, by specify-
+ ing a URL. The URL can be put into an environment variable, PKG_PATH.
+
+ # pkg_add -v ftp://ftp.netbsd.org/pub/NetBSD/packages/1.5/i386/All/mozilla-0.8.1.tgz
+
+ # export PKG_PATH=ftp://ftp.netbsd.org/pub/NetBSD/packages/1.5/i386/All
+ # pkg_add -v mozilla
+
+SSEEEE AALLSSOO
+ pkg_admin(1), pkg_create(1), pkg_delete(1), pkg_info(1), mktemp(3),
+ sysconf(3), packages(7), mtree(8)
+
+AAUUTTHHOORRSS
+ Jordan Hubbard
+ Initial work and ongoing development.
+ John Kohl
+ NetBSD refinements.
+ Hubert Feyrer
+ NetBSD wildcard dependency processing, pkgdb, upgrading, etc.
+
+BBUUGGSS
+ Hard links between files in a distribution are only preserved if either
+ (1) the staging area is on the same file system as the target directory
+ of all the links to the file, or (2) all the links to the file are brack-
+ eted by @@ccwwdd directives in the contents file, _a_n_d and the link names are
+ extracted with a single ttaarr command (not split between invocations due to
+ exec argument-space limitations--this depends on the value returned by
+ ssyyssccoonnff(___S_C___A_R_G___M_A_X)).
+
+ Pkg upgrading needs a lot more work to be really universal.
+
+ Sure to be others.
+
+NetBSD 1.6 August 15, 2002 5
diff --git a/pkgtools/pkg_install/files/add/verify.c b/pkgtools/pkg_install/files/add/verify.c
new file mode 100644
index 00000000000..278d8da01fe
--- /dev/null
+++ b/pkgtools/pkg_install/files/add/verify.c
@@ -0,0 +1,172 @@
+/* $NetBSD: verify.c,v 1.1.1.1 2002/12/20 18:13:57 schmonz Exp $ */
+
+/*
+ * Copyright (c) 2001 Alistair G. Crooks. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Alistair G. Crooks.
+ * 4. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#if 0
+#include <sys/cdefs.h>
+
+#ifndef lint
+__COPYRIGHT("@(#) Copyright (c) 1999 \
+ The NetBSD Foundation, Inc. All rights reserved.");
+__RCSID("$NetBSD: verify.c,v 1.1.1.1 2002/12/20 18:13:57 schmonz Exp $");
+#endif
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <unistd.h>
+
+#include "verify.h"
+#include "lib.h"
+
+enum {
+ MaxExtensions = 10
+};
+
+/* this struct defines a verification type */
+typedef struct ver_t {
+ const char *name; /* name of type */
+ const char *command; /* command to execute to verify */
+ const char *extensions[MaxExtensions]; /* signature file extensions */
+} ver_t;
+
+static char *verification_type; /* the verification type which has been selected */
+
+/* called when gpg verification type is selected */
+static int
+do_verify(const char *pkgname, const char *cmd, const char *const *extensions)
+{
+ struct stat st;
+ const char *const *ep;
+ char buf[BUFSIZ];
+ char f[FILENAME_MAX];
+ int i;
+
+ if (cmd == NULL) {
+ return 1;
+ }
+ for (i = 0, ep = extensions ; i < MaxExtensions && *ep ; ep++, i++) {
+ (void) snprintf(f, sizeof(f), "%s%s", pkgname, *ep);
+ if (stat(f, &st) == 0) {
+ (void) fprintf(stderr, "pkg_add: Using signature file: %s\n", f);
+ if (vsystem(cmd, f) != 0) {
+ (void) fprintf(stderr, "*** WARNING ***: `%s' has a bad signature\n", f);
+ return 0;
+ }
+ (void) fprintf(stderr, "Proceed with addition of %s: [y/n]? ", pkgname);
+ if (fgets(buf, sizeof(buf), stdin) == NULL) {
+ (void) fprintf(stderr, "Exiting now...");
+ exit(EXIT_FAILURE);
+ }
+ switch(buf[0]) {
+ case 'Y':
+ case 'y':
+ case '1':
+ return 1;
+ }
+ (void) fprintf(stderr, "Package `%s' will not be added\n", pkgname);
+ return 0;
+ }
+ }
+ (void) fprintf(stderr, "No valid signature file found for `%s'\n", pkgname);
+ return 0;
+}
+
+/* table holding possible verifications which can be made */
+static const ver_t vertab[] = {
+ { "none", NULL, { NULL } },
+ { "gpg", "gpg --verify %s", { ".sig", ".asc", NULL } },
+ { "pgp5", "pgpv %s", { ".sig", ".asc", ".pgp", NULL } },
+ { NULL }
+};
+
+/* set the verification type - usually called during command line processing */
+void
+set_verification(const char *type)
+{
+ if (verification_type) {
+ (void) free(verification_type);
+ }
+ verification_type = strdup(type);
+}
+
+/* return the type of verification that is being used */
+char *
+get_verification(void)
+{
+ const ver_t *vp;
+
+ if (verification_type != NULL) {
+ for (vp = vertab ; vp->name ; vp++) {
+ if (strcasecmp(verification_type, vp->name) == 0) {
+ return verification_type;
+ }
+ }
+ }
+ return "none";
+}
+
+/* verify the digital signature (if any) on a package */
+int
+verify(const char *pkg)
+{
+ const ver_t *vp;
+
+ if (verification_type == NULL) {
+ return do_verify(pkg, NULL, NULL);
+ }
+ for (vp = vertab ; vp->name ; vp++) {
+ if (strcasecmp(verification_type, vp->name) == 0) {
+ return do_verify(pkg, vp->command, vp->extensions);
+ }
+ }
+ (void) fprintf(stderr, "Can't find `%s' verification details\n", verification_type);
+ return 0;
+}
diff --git a/pkgtools/pkg_install/files/add/verify.h b/pkgtools/pkg_install/files/add/verify.h
new file mode 100644
index 00000000000..ef155a24896
--- /dev/null
+++ b/pkgtools/pkg_install/files/add/verify.h
@@ -0,0 +1,40 @@
+/* $NetBSD: verify.h,v 1.1.1.1 2002/12/20 18:13:57 schmonz Exp $ */
+
+/*
+ * Copyright (c) 2001 Alistair G. Crooks. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Alistair G. Crooks.
+ * 4. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef VERIFY_H_
+#define VERIFY_H_
+
+void set_verification(const char *);
+char *get_verification(void);
+int verify(const char *);
+
+#endif /* VERIFY_H_ */
diff --git a/pkgtools/pkg_install/files/admin/Makefile.in b/pkgtools/pkg_install/files/admin/Makefile.in
new file mode 100644
index 00000000000..b62d831d155
--- /dev/null
+++ b/pkgtools/pkg_install/files/admin/Makefile.in
@@ -0,0 +1,39 @@
+# From NetBSD: Makefile,v 1.1 1999/01/19 17:01:58 hubertf Exp
+
+PREFIX= @prefix@
+INSTALL= @INSTALL@
+
+mandir= ${PREFIX}/man
+mandircat1= ${mandir}/cat1
+
+CC= @CC@
+CCLD= $(CC)
+LIBS= @LIBS@ -linstall
+CPPFLAGS= @CPPFLAGS@
+DEFS= @DEFS@ -I. -I@srcdir@ -I../lib
+CFLAGS= @CFLAGS@
+LDFLAGS= @LDFLAGS@ -L../lib
+
+LINK= $(CCLD) $(CFLAGS) $(LDFLAGS) -o $@
+COMPILE= $(CC) $(DEFS) $(CPPFLAGS) $(CFLAGS)
+
+PROG= pkg_admin
+
+SRCS= main.c
+OBJS= main.o
+
+all: ${PROG}
+
+${PROG}: ${OBJS}
+ ${LINK} ${OBJS} ${LIBS}
+
+.c.o:
+ $(COMPILE) -c $< -o $@
+
+clean:
+ rm -f ${OBJS} ${PROG}
+
+install:
+ ${INSTALL} ${PROG} ${PREFIX}/sbin
+ ${INSTALL} -m 755 -d ${mandircat1}
+ ${INSTALL} -m 444 ${PROG}.cat1 ${mandircat1}/${PROG}.1
diff --git a/pkgtools/pkg_install/files/admin/README b/pkgtools/pkg_install/files/admin/README
new file mode 100644
index 00000000000..74c13e0f1ed
--- /dev/null
+++ b/pkgtools/pkg_install/files/admin/README
@@ -0,0 +1,9 @@
+Some of the options of this utility (add, delete) are *not* intended for
+public release. Any work regarding the consistancy of the pkgdb should
+be put into pkg_add/pkg_delete, instead of a brute-force "rebuild".
+
+The "rebuild" should be only needed wen upgrading from non-pkgdb-
+pkg_* tools to pkgdb-pkg_* tools.
+
+
+ - hubertf
diff --git a/pkgtools/pkg_install/files/admin/main.c b/pkgtools/pkg_install/files/admin/main.c
new file mode 100644
index 00000000000..14e5a886ea0
--- /dev/null
+++ b/pkgtools/pkg_install/files/admin/main.c
@@ -0,0 +1,630 @@
+/* $NetBSD: main.c,v 1.1.1.1 2002/12/20 18:13:53 schmonz Exp $ */
+
+#if 0
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: main.c,v 1.1.1.1 2002/12/20 18:13:53 schmonz Exp $");
+#endif
+#endif
+
+/*
+ * Copyright (c) 1999 Hubert Feyrer. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Hubert Feyrer for
+ * the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#include <errno.h>
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_MD5GLOBAL_H
+#include <md5global.h>
+#endif
+
+#ifdef HAVE_MD5_H
+#include <md5.h>
+#endif
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include <stdio.h>
+
+#include "lib.h"
+
+void usage(void);
+
+int filecnt;
+int pkgcnt;
+
+static int checkpattern_fn(const char *, void *);
+
+/*
+ * Assumes CWD is in /var/db/pkg/<pkg>!
+ */
+static void
+check1pkg(const char *pkgdir)
+{
+ FILE *f;
+ plist_t *p;
+ package_t Plist;
+ char *PkgName, *dirp = NULL, *md5file;
+ char file[FILENAME_MAX];
+ char dir[FILENAME_MAX];
+
+ f = fopen(CONTENTS_FNAME, "r");
+ if (f == NULL)
+ err(1, "can't open %s/%s/%s", _pkgdb_getPKGDB_DIR(), pkgdir, CONTENTS_FNAME);
+
+ Plist.head = Plist.tail = NULL;
+ read_plist(&Plist, f);
+ p = find_plist(&Plist, PLIST_NAME);
+ if (p == NULL)
+ errx(1, "Package %s has no @name, aborting.",
+ pkgdir);
+ PkgName = p->name;
+ for (p = Plist.head; p; p = p->next) {
+ switch (p->type) {
+ case PLIST_FILE:
+ if (dirp == NULL) {
+ warnx("dirp not initialized, please send-pr!");
+ abort();
+ }
+
+ (void) snprintf(file, sizeof(file), "%s/%s", dirp, p->name);
+
+ if (!(isfile(file) || islinktodir(file)))
+ warnx("%s: File %s is in %s but not on filesystem!", PkgName, file, CONTENTS_FNAME);
+ else {
+ if (p->next &&
+ p->next->type == PLIST_COMMENT &&
+ strncmp(p->next->name, CHECKSUM_HEADER, ChecksumHeaderLen) == 0) { /* || PLIST_MD5 - HF */
+ if ((md5file = MD5File(file, NULL)) != NULL) {
+ /* Mismatch? */
+#ifdef PKGDB_DEBUG
+ printf("%s: md5 should=<%s>, is=<%s>\n",
+ file, p->next->name + ChecksumHeaderLen, md5file);
+#endif
+ if (strcmp(md5file, p->next->name + ChecksumHeaderLen) != 0)
+ printf("%s fails MD5 checksum\n", file);
+
+ free(md5file);
+ }
+ }
+
+ filecnt++;
+ }
+ break;
+ case PLIST_CWD:
+ if (strcmp(p->name, ".") != 0)
+ dirp = p->name;
+ else {
+ (void) snprintf(dir, sizeof(dir), "%s/%s", _pkgdb_getPKGDB_DIR(), pkgdir);
+ dirp = dir;
+ }
+ break;
+ case PLIST_IGNORE:
+ p = p->next;
+ break;
+ case PLIST_SHOW_ALL:
+ case PLIST_SRC:
+ case PLIST_CMD:
+ case PLIST_CHMOD:
+ case PLIST_CHOWN:
+ case PLIST_CHGRP:
+ case PLIST_COMMENT:
+ case PLIST_NAME:
+ case PLIST_UNEXEC:
+ case PLIST_DISPLAY:
+ case PLIST_PKGDEP:
+ case PLIST_MTREE:
+ case PLIST_DIR_RM:
+ case PLIST_IGNORE_INST:
+ case PLIST_OPTION:
+ case PLIST_PKGCFL:
+ case PLIST_BLDDEP:
+ break;
+ }
+ }
+ free_plist(&Plist);
+ fclose(f);
+ pkgcnt++;
+}
+
+static void
+rebuild(void)
+{
+ DIR *dp;
+ struct dirent *de;
+ FILE *f;
+ plist_t *p;
+ char *PkgName, dir[FILENAME_MAX], *dirp = NULL;
+ char *PkgDBDir = NULL, file[FILENAME_MAX];
+
+ pkgcnt = 0;
+ filecnt = 0;
+
+ if (unlink(_pkgdb_getPKGDB_FILE()) != 0 && errno != ENOENT)
+ err(1, "unlink %s", _pkgdb_getPKGDB_FILE());
+
+ if (pkgdb_open(0) == -1)
+ err(1, "cannot open pkgdb");
+
+ setbuf(stdout, NULL);
+ PkgDBDir = _pkgdb_getPKGDB_DIR();
+ chdir(PkgDBDir);
+#ifdef PKGDB_DEBUG
+ printf("PkgDBDir='%s'\n", PkgDBDir);
+#endif
+ dp = opendir(".");
+ if (dp == NULL)
+ err(1, "opendir failed");
+ while ((de = readdir(dp))) {
+ package_t Plist;
+
+ if (!isdir(de->d_name))
+ continue;
+
+ if (strcmp(de->d_name, ".") == 0 ||
+ strcmp(de->d_name, "..") == 0)
+ continue;
+
+#ifdef PKGDB_DEBUG
+ printf("%s\n", de->d_name);
+#else
+ printf(".");
+#endif
+
+ chdir(de->d_name);
+
+ f = fopen(CONTENTS_FNAME, "r");
+ if (f == NULL)
+ err(1, "can't open %s/%s", de->d_name, CONTENTS_FNAME);
+
+ Plist.head = Plist.tail = NULL;
+ read_plist(&Plist, f);
+ p = find_plist(&Plist, PLIST_NAME);
+ if (p == NULL)
+ errx(1, "Package %s has no @name, aborting.",
+ de->d_name);
+ PkgName = p->name;
+ for (p = Plist.head; p; p = p->next) {
+ switch (p->type) {
+ case PLIST_FILE:
+ if (dirp == NULL) {
+ warnx("dirp not initialized, please send-pr!");
+ abort();
+ }
+
+ (void) snprintf(file, sizeof(file), "%s/%s", dirp, p->name);
+
+ if (!(isfile(file) || islinktodir(file)))
+ warnx("%s: File %s is in %s but not on filesystem!",
+ PkgName, file, CONTENTS_FNAME);
+ else {
+ pkgdb_store(file, PkgName);
+ filecnt++;
+ }
+ break;
+ case PLIST_CWD:
+ if (strcmp(p->name, ".") != 0)
+ dirp = p->name;
+ else {
+ (void) snprintf(dir, sizeof(dir), "%s/%s", PkgDBDir, de->d_name);
+ dirp = dir;
+ }
+ break;
+ case PLIST_IGNORE:
+ p = p->next;
+ break;
+ case PLIST_SHOW_ALL:
+ case PLIST_SRC:
+ case PLIST_CMD:
+ case PLIST_CHMOD:
+ case PLIST_CHOWN:
+ case PLIST_CHGRP:
+ case PLIST_COMMENT:
+ case PLIST_NAME:
+ case PLIST_UNEXEC:
+ case PLIST_DISPLAY:
+ case PLIST_PKGDEP:
+ case PLIST_MTREE:
+ case PLIST_DIR_RM:
+ case PLIST_IGNORE_INST:
+ case PLIST_OPTION:
+ case PLIST_PKGCFL:
+ case PLIST_BLDDEP:
+ break;
+ }
+ }
+ free_plist(&Plist);
+ fclose(f);
+ pkgcnt++;
+
+ chdir("..");
+ }
+ closedir(dp);
+ pkgdb_close();
+
+ printf("\n");
+ printf("Stored %d file%s from %d package%s in %s.\n",
+ filecnt, filecnt == 1 ? "" : "s",
+ pkgcnt, pkgcnt == 1 ? "" : "s",
+ _pkgdb_getPKGDB_FILE());
+}
+
+static void
+checkall(void)
+{
+ DIR *dp;
+ struct dirent *de;
+
+ pkgcnt = 0;
+ filecnt = 0;
+
+ setbuf(stdout, NULL);
+ chdir(_pkgdb_getPKGDB_DIR());
+
+ dp = opendir(".");
+ if (dp == NULL)
+ err(1, "opendir failed");
+ while ((de = readdir(dp))) {
+ if (!isdir(de->d_name))
+ continue;
+
+ if (strcmp(de->d_name, ".") == 0 ||
+ strcmp(de->d_name, "..") == 0)
+ continue;
+
+ chdir(de->d_name);
+
+ check1pkg(de->d_name);
+ printf(".");
+
+ chdir("..");
+ }
+ closedir(dp);
+ pkgdb_close();
+
+
+ printf("\n");
+ printf("Checked %d file%s from %d package%s.\n",
+ filecnt, (filecnt == 1) ? "" : "s",
+ pkgcnt, (pkgcnt == 1) ? "" : "s");
+}
+
+static int
+checkpattern_fn(const char *pkg, void *vp)
+{
+ int rc;
+
+ rc = chdir(pkg);
+ if (rc == -1)
+ err(1, "Cannot chdir to %s/%s", _pkgdb_getPKGDB_DIR(), pkg);
+
+ check1pkg(pkg);
+ printf(".");
+
+ chdir("..");
+
+ return 0;
+}
+
+static int
+lspattern_fn(const char *pkg, void *vp)
+{
+ char *data = vp;
+ printf("%s/%s\n", data, pkg);
+
+ return 0;
+}
+
+int
+main(int argc, char *argv[])
+{
+ setprogname(argv[0]);
+
+ if (argc < 2)
+ usage();
+
+ if (strcmp(argv[1], "-V") == 0) {
+
+ show_version();
+ /* NOTREACHED */
+
+ } else if (strcasecmp(argv[1], "pmatch") == 0) {
+
+ char *pattern, *pkg;
+
+ argv++; /* argv[0] */
+ argv++; /* "pmatch" */
+
+ pattern = argv[0];
+ pkg = argv[1];
+
+ if (pattern == NULL || pkg == NULL) {
+ usage();
+ }
+
+ if (pmatch(pattern, pkg)){
+ return 0;
+ } else {
+ return 1;
+ }
+
+ } else if (strcasecmp(argv[1], "rebuild") == 0) {
+
+ rebuild();
+ printf("Done.\n");
+
+ } else if (strcasecmp(argv[1], "check") == 0) {
+
+ argv++; /* argv[0] */
+ argv++; /* "check" */
+
+ if (*argv != NULL) {
+ /* args specified */
+ int rc;
+
+ filecnt = 0;
+
+ setbuf(stdout, NULL);
+
+ rc = chdir(_pkgdb_getPKGDB_DIR());
+ if (rc == -1)
+ err(1, "Cannot chdir to %s", _pkgdb_getPKGDB_DIR());
+
+ while (*argv != NULL) {
+ if (ispkgpattern(*argv)) {
+ if (findmatchingname(_pkgdb_getPKGDB_DIR(), *argv, checkpattern_fn, NULL) == 0)
+ errx(1, "No matching pkg for %s.", *argv);
+ } else {
+ rc = chdir(*argv);
+ if (rc == -1) {
+ /* found nothing - try 'pkg-[0-9]*' */
+ char try[FILENAME_MAX];
+
+ snprintf(try, sizeof(try), "%s-[0-9]*", *argv);
+ if (findmatchingname(_pkgdb_getPKGDB_DIR(), try,
+ checkpattern_fn, NULL) <= 0) {
+
+ errx(1, "cannot find package %s", *argv);
+ } else {
+ /* nothing to do - all the work is/was
+ * done in checkpattern_fn() */
+ }
+ } else {
+ check1pkg(*argv);
+ printf(".");
+
+ chdir("..");
+ }
+ }
+
+ argv++;
+ }
+
+ printf("\n");
+ printf("Checked %d file%s from %d package%s.\n",
+ filecnt, (filecnt == 1) ? "" : "s",
+ pkgcnt, (pkgcnt == 1) ? "" : "s");
+ } else {
+ checkall();
+ }
+ printf("Done.\n");
+
+ } else if (strcasecmp(argv[1], "lsall") == 0) {
+ int saved_wd;
+
+ argv++; /* argv[0] */
+ argv++; /* "check" */
+
+ /* preserve cwd */
+ saved_wd=open(".", O_RDONLY);
+ if (saved_wd == -1)
+ err(1, "Cannot save working dir");
+
+ while (*argv != NULL) {
+ /* args specified */
+ int rc;
+ const char *basep, *dir;
+ char *cwd;
+ char base[FILENAME_MAX];
+
+ dir = dirname_of(*argv);
+ basep = basename_of(*argv);
+ snprintf(base, sizeof(base), "%s.t[bg]z", basep);
+
+ fchdir(saved_wd);
+ rc = chdir(dir);
+ if (rc == -1)
+ err(1, "Cannot chdir to %s", _pkgdb_getPKGDB_DIR());
+
+ cwd = getcwd(NULL, 0);
+ if (findmatchingname(cwd, base, lspattern_fn, cwd) == -1)
+ errx(1, "Error in findmatchingname(\"%s\", \"%s\", ...)",
+ cwd, base);
+ free(cwd);
+
+ argv++;
+ }
+
+ close(saved_wd);
+
+ } else if (strcasecmp(argv[1], "lsbest") == 0) {
+ int saved_wd;
+
+ argv++; /* argv[0] */
+ argv++; /* "check" */
+
+ /* preserve cwd */
+ saved_wd=open(".", O_RDONLY);
+ if (saved_wd == -1)
+ err(1, "Cannot save working dir");
+
+ while (*argv != NULL) {
+ /* args specified */
+ int rc;
+ const char *basep, *dir;
+ char *cwd;
+ char base[FILENAME_MAX];
+ char *p;
+
+ dir = dirname_of(*argv);
+ basep = basename_of(*argv);
+ snprintf(base, sizeof(base), "%s.t[bg]z", basep);
+
+ fchdir(saved_wd);
+ rc = chdir(dir);
+ if (rc == -1)
+ err(1, "Cannot chdir to %s", _pkgdb_getPKGDB_DIR());
+
+ cwd = getcwd(NULL, 0);
+ p = findbestmatchingname(cwd, base);
+ if (p) {
+ printf("%s/%s\n", cwd, p);
+ free(p);
+ }
+ free(cwd);
+
+ argv++;
+ }
+
+ close(saved_wd);
+
+ } else if (strcasecmp(argv[1], "list") == 0 ||
+ strcasecmp(argv[1], "dump") == 0) {
+
+ char *key, *val;
+
+ printf("Dumping pkgdb %s:\n", _pkgdb_getPKGDB_FILE());
+
+ if (pkgdb_open(1) == -1) {
+ err(1, "cannot open %s", _pkgdb_getPKGDB_FILE());
+ }
+ while ((key = pkgdb_iter())) {
+ val = pkgdb_retrieve(key);
+
+ printf("file: %-50s pkg: %s\n", key, val);
+ }
+ pkgdb_close();
+
+ }
+#ifdef PKGDB_DEBUG
+ else if (strcasecmp(argv[1], "del") == 0 ||
+ strcasecmp(argv[1], "delete") == 0) {
+
+ int rc;
+
+ if (pkgdb_open(0) == -1)
+ err(1, "cannot open pkgdb");
+
+ rc = pkgdb_remove(argv[2]);
+ if (rc) {
+ if (errno)
+ perror("pkgdb_remove");
+ else
+ printf("Key not present in pkgdb.\n");
+ }
+
+ pkgdb_close();
+
+ } else if (strcasecmp(argv[1], "add") == 0) {
+
+ int rc;
+
+ if (pkgdb_open(0) == -1) {
+ err(1, "cannot open pkgdb");
+ }
+
+ rc = pkgdb_store(argv[2], argv[3]);
+ switch (rc) {
+ case -1:
+ perror("pkgdb_store");
+ break;
+ case 1:
+ printf("Key already present.\n");
+ break;
+ default:
+ /* 0: everything ok */
+ break;
+ }
+
+ pkgdb_close();
+
+ }
+#endif
+ else {
+ usage();
+ }
+
+ return 0;
+}
+
+void
+usage(void)
+{
+ printf("usage: pkg_admin [-V] command args ...\n"
+ "Where 'commands' and 'args' are:\n"
+ " rebuild - rebuild pkgdb from +CONTENTS files\n"
+ " check [pkg ...] - check md5 checksum of installed files\n"
+#ifdef PKGDB_DEBUG
+ " add key value - add key & value\n"
+ " delete key - delete reference to key\n"
+#endif
+ " lsall /path/to/pkgpattern - list all pkgs matching the pattern\n"
+ " lsbest /path/to/pkgpattern - list pkgs matching the pattern best\n"
+ " dump - dump database\n"
+ " pmatch pattern pkg - returns true if pkg matches pattern, false else\n");
+ exit(1);
+}
+
+void
+cleanup(int signo)
+{
+ ;
+}
diff --git a/pkgtools/pkg_install/files/admin/pkg_admin.1 b/pkgtools/pkg_install/files/admin/pkg_admin.1
new file mode 100644
index 00000000000..91c405b3557
--- /dev/null
+++ b/pkgtools/pkg_install/files/admin/pkg_admin.1
@@ -0,0 +1,147 @@
+.\" $NetBSD: pkg_admin.1,v 1.1.1.1 2002/12/20 18:13:54 schmonz Exp $
+.\"
+.\" Copyright (c) 1999 Hubert Feyrer. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by Hubert Feyrer for
+.\" the NetBSD Project.
+.\" 4. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd August 4, 2002
+.Dt PKG_ADMIN 1
+.Os
+.Sh NAME
+.Nm pkg_admin
+.Nd perform various administrative tasks to the pkg system
+.Sh SYNOPSIS
+.Nm
+.Op Fl V
+.Ar command Op args ...
+.Sh DESCRIPTION
+This command performs various administrative tasks around the
+.Nx
+Packages System.
+Available commands are:
+.Pp
+.Bl -tag -width check
+.It Fl V
+Print version number and exit.
+.It Cm check Op Ar pkg ...
+Use this command to check the files belonging to some or all of the
+packages installed on the local machine against their MD5 checksum
+noted in their +CONTENTS files.
+If no additional argument is given, the files of all installed packages
+are checked, else only the named packages will be checked (wildcards can
+be used here, see
+.Xr pkg_info 1 ) .
+.Pp
+The packages' +CONTENTS files will be parsed and the MD5
+checksum will be checked for every file found.
+A warning message is printed if the expected checksum differs from the
+checksum of the file on disk.
+.Pp
+.It Cm dump
+Dump the contents of the package database, similar to
+.Cm pkg_info -F .
+Columns are printed for the keyfield used in the pkgdb - the filename -,
+and the data field - the package the file belongs to.
+.It Cm lsall /dir/pkgpattern
+.It Cm lsbest /dir/pkgpattern
+List all/best package matching pattern in the given directory.
+Can be used to work around limitations of /bin/sh and other
+filename globbing mechanisms.
+This option implements matching of
+pkg-wildcards against arbitrary files, useful mainly in the build
+system itself.
+See
+.Xr pkg_info 1
+for a description of the pattern.
+.Pp
+Example:
+.Bd -literal
+yui# cd /usr/pkgsrc/packages/i386ELF/All/
+yui# ls unzip*
+unzip-5.40.tgz unzip-5.41.tgz
+yui# pkg_admin lsall 'unzip*'
+unzip-5.40.tgz
+unzip-5.41.tgz
+yui# pkg_admin lsall 'unzip\*[Ge]5.40'
+unzip-5.40.tgz
+unzip-5.41.tgz
+yui# pkg_admin lsall 'unzip\*[Ge]5.41'
+unzip-5.41.tgz
+yui# pkg_admin lsbest 'unzip\*[Ge]5.40'
+unzip-5.41.tgz
+yui# pkg_admin lsall /usr/pkgsrc/packages/i386ELF/All/'{mit,unproven}-pthread*'
+/usr/pkgsrc/packages/i386ELF/All/mit-pthreads-1.60b6.tgz
+/usr/pkgsrc/packages/i386ELF/All/unproven-pthreads-0.15.tgz
+.Ed
+.It Cm pmatch pattern pkg
+Returns true if pkg matches pattern, false else.
+.It Cm rebuild
+Rebuild the package database mapping from scratch, scanning
+subdirectories in
+.Pa /var/db/pkg
+for
+.Pa +CONTENTS
+files, parsing them and writing the resulting absolute pathnames
+together with the package they belong to into the package database.
+.Pp
+This option is intended to be used for upgrading from non-pkgdb-pkg_*
+tools to pkgdb-pkg_* tools, further manipulation of the pkgdb will be
+done by
+.Xr pkg_add 1 ,
+.Xr pkg_delete 1 ,
+and
+.Xr pkg_create 1 .
+.Pp
+Needs to be run as root.
+.Pp
+.El
+.Sh ENVIRONMENT
+.Bl -tag -width PKG_DBDIR -compact
+.It Ev PKG_DBDIR
+Where to register packages instead of
+.Pa /var/db/pkg .
+.El
+.Sh FILES
+.Bl -tag -width /var/db/pkg/pkgdb.byfile.db -compact
+.It Pa /var/db/pkg/pkgdb.byfile.db
+.It Pa /var/db/pkg/\*[Lt]pkg\*[Gt]/+CONTENTS
+.El
+.Sh SEE ALSO
+.Xr pkg_add 1 ,
+.Xr pkg_create 1 ,
+.Xr pkg_delete 1 ,
+.Xr pkg_info 1 ,
+.Xr packages 7
+.Sh HISTORY
+The
+.Nm
+command first appeared in
+.Nx 1.4 .
+.Sh AUTHORS
+The
+.Nm
+command was written by Hubert Feyrer.
diff --git a/pkgtools/pkg_install/files/admin/pkg_admin.cat1 b/pkgtools/pkg_install/files/admin/pkg_admin.cat1
new file mode 100644
index 00000000000..b8b348004dc
--- /dev/null
+++ b/pkgtools/pkg_install/files/admin/pkg_admin.cat1
@@ -0,0 +1,92 @@
+PKG_ADMIN(1) NetBSD Reference Manual PKG_ADMIN(1)
+
+NNAAMMEE
+ ppkkgg__aaddmmiinn - perform various administrative tasks to the pkg system
+
+SSYYNNOOPPSSIISS
+ ppkkgg__aaddmmiinn [--VV] _c_o_m_m_a_n_d [args ...]
+
+DDEESSCCRRIIPPTTIIOONN
+ This command performs various administrative tasks around the NetBSD
+ Packages System. Available commands are:
+
+ --VV Print version number and exit.
+
+ cchheecckk [_p_k_g _._._.]
+ Use this command to check the files belonging to some or all of
+ the packages installed on the local machine against their MD5
+ checksum noted in their +CONTENTS files. If no additional argu-
+ ment is given, the files of all installed packages are checked,
+ else only the named packages will be checked (wildcards can be
+ used here, see pkg_info(1)).
+
+ The packages' +CONTENTS files will be parsed and the MD5 checksum
+ will be checked for every file found. A warning message is print-
+ ed if the expected checksum differs from the checksum of the file
+ on disk.
+
+ dduummpp Dump the contents of the package database, similar to ppkkgg__iinnffoo --FF.
+ Columns are printed for the keyfield used in the pkgdb - the file-
+ name -, and the data field - the package the file belongs to.
+
+ llssaallll //ddiirr//ppkkggppaatttteerrnn
+
+ llssbbeesstt //ddiirr//ppkkggppaatttteerrnn
+ List all/best package matching pattern in the given directory.
+ Can be used to work around limitations of /bin/sh and other file-
+ name globbing mechanisms. This option implements matching of pkg-
+ wildcards against arbitrary files, useful mainly in the build sys-
+ tem itself. See pkg_info(1) for a description of the pattern.
+
+ Example:
+
+ yui# cd /usr/pkgsrc/packages/i386ELF/All/
+ yui# ls unzip*
+ unzip-5.40.tgz unzip-5.41.tgz
+ yui# pkg_admin lsall 'unzip*'
+ unzip-5.40.tgz
+ unzip-5.41.tgz
+ yui# pkg_admin lsall 'unzip>=5.40'
+ unzip-5.40.tgz
+ unzip-5.41.tgz
+ yui# pkg_admin lsall 'unzip>=5.41'
+ unzip-5.41.tgz
+ yui# pkg_admin lsbest 'unzip>=5.40'
+ unzip-5.41.tgz
+ yui# pkg_admin lsall /usr/pkgsrc/packages/i386ELF/All/'{mit,unproven}-pthread*'
+ /usr/pkgsrc/packages/i386ELF/All/mit-pthreads-1.60b6.tgz
+ /usr/pkgsrc/packages/i386ELF/All/unproven-pthreads-0.15.tgz
+
+ ppmmaattcchh ppaatttteerrnn ppkkgg
+ Returns true if pkg matches pattern, false else.
+
+ rreebbuuiilldd
+ Rebuild the package database mapping from scratch, scanning subdi-
+ rectories in _/_v_a_r_/_d_b_/_p_k_g for _+_C_O_N_T_E_N_T_S files, parsing them and
+ writing the resulting absolute pathnames together with the package
+ they belong to into the package database.
+
+ This option is intended to be used for upgrading from non-pkgdb-
+ pkg_* tools to pkgdb-pkg_* tools, further manipulation of the
+ pkgdb will be done by pkg_add(1), pkg_delete(1), and
+ pkg_create(1).
+
+ Needs to be run as root.
+
+EENNVVIIRROONNMMEENNTT
+ PKG_DBDIR Where to register packages instead of _/_v_a_r_/_d_b_/_p_k_g.
+
+FFIILLEESS
+ /var/db/pkg/pkgdb.byfile.db
+ /var/db/pkg/<pkg>/+CONTENTS
+
+SSEEEE AALLSSOO
+ pkg_add(1), pkg_create(1), pkg_delete(1), pkg_info(1), packages(7)
+
+HHIISSTTOORRYY
+ The ppkkgg__aaddmmiinn command first appeared in NetBSD 1.4.
+
+AAUUTTHHOORRSS
+ The ppkkgg__aaddmmiinn command was written by Hubert Feyrer.
+
+NetBSD 1.6 August 4, 2002 2
diff --git a/pkgtools/pkg_install/files/configure b/pkgtools/pkg_install/files/configure
new file mode 100755
index 00000000000..10500cf59c4
--- /dev/null
+++ b/pkgtools/pkg_install/files/configure
@@ -0,0 +1,3084 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_default_prefix=/usr/pkg
+ac_help="$ac_help
+ --with-pkgdbdir=DIR Where to put the pkg database (/var/db/pkg)"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=add/add.h
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+
+
+
+# Check whether --with-pkgdbdir or --without-pkgdbdir was given.
+if test "${with_pkgdbdir+set}" = set; then
+ withval="$with_pkgdbdir"
+ pkgdbdir="$with_pkgdbdir"
+else
+ pkgdbdir="/var/db/pkg"
+fi
+
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:573: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:628: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:658: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:709: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:741: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 752 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:757: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:783: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:788: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:797: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:816: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:850: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+for ac_prog in ar
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:882: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AR="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+AR="$ac_cv_prog_AR"
+if test -n "$AR"; then
+ echo "$ac_t""$AR" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$AR" && break
+done
+
+for ac_prog in chmod
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:916: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_CHMOD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$CHMOD" in
+ /*)
+ ac_cv_path_CHMOD="$CHMOD" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_CHMOD="$CHMOD" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_CHMOD="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+CHMOD="$ac_cv_path_CHMOD"
+if test -n "$CHMOD"; then
+ echo "$ac_t""$CHMOD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CHMOD" && break
+done
+
+for ac_prog in chown
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:956: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_CHOWN'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$CHOWN" in
+ /*)
+ ac_cv_path_CHOWN="$CHOWN" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_CHOWN="$CHOWN" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_CHOWN="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+CHOWN="$ac_cv_path_CHOWN"
+if test -n "$CHOWN"; then
+ echo "$ac_t""$CHOWN" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CHOWN" && break
+done
+
+for ac_prog in chgrp
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:996: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_CHGRP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$CHGRP" in
+ /*)
+ ac_cv_path_CHGRP="$CHGRP" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_CHGRP="$CHGRP" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_CHGRP="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+CHGRP="$ac_cv_path_CHGRP"
+if test -n "$CHGRP"; then
+ echo "$ac_t""$CHGRP" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CHGRP" && break
+done
+
+for ac_prog in digest
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1036: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_DIGEST'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$DIGEST" in
+ /*)
+ ac_cv_path_DIGEST="$DIGEST" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_DIGEST="$DIGEST" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_DIGEST="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+DIGEST="$ac_cv_path_DIGEST"
+if test -n "$DIGEST"; then
+ echo "$ac_t""$DIGEST" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$DIGEST" && break
+done
+
+for ac_prog in mkdir
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1076: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MKDIR'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MKDIR" in
+ /*)
+ ac_cv_path_MKDIR="$MKDIR" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_MKDIR="$MKDIR" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_MKDIR="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+MKDIR="$ac_cv_path_MKDIR"
+if test -n "$MKDIR"; then
+ echo "$ac_t""$MKDIR" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$MKDIR" && break
+done
+
+for ac_prog in mtree
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1116: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MTREE'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MTREE" in
+ /*)
+ ac_cv_path_MTREE="$MTREE" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_MTREE="$MTREE" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_MTREE="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+MTREE="$ac_cv_path_MTREE"
+if test -n "$MTREE"; then
+ echo "$ac_t""$MTREE" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$MTREE" && break
+done
+
+for ac_prog in rm
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1156: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_RM'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$RM" in
+ /*)
+ ac_cv_path_RM="$RM" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_RM="$RM" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_RM="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+RM="$ac_cv_path_RM"
+if test -n "$RM"; then
+ echo "$ac_t""$RM" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$RM" && break
+done
+
+for ac_prog in rmdir
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1196: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_RMDIR'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$RMDIR" in
+ /*)
+ ac_cv_path_RMDIR="$RMDIR" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_RMDIR="$RMDIR" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_RMDIR="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+RMDIR="$ac_cv_path_RMDIR"
+if test -n "$RMDIR"; then
+ echo "$ac_t""$RMDIR" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$RMDIR" && break
+done
+
+for ac_prog in tar
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1236: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_TAR_FULLPATHNAME'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$TAR_FULLPATHNAME" in
+ /*)
+ ac_cv_path_TAR_FULLPATHNAME="$TAR_FULLPATHNAME" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_TAR_FULLPATHNAME="$TAR_FULLPATHNAME" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_TAR_FULLPATHNAME="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+TAR_FULLPATHNAME="$ac_cv_path_TAR_FULLPATHNAME"
+if test -n "$TAR_FULLPATHNAME"; then
+ echo "$ac_t""$TAR_FULLPATHNAME" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$TAR_FULLPATHNAME" && break
+done
+
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1273: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 1288 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1294: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 1305 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1311: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 1322 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1328: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1353: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1358 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1366: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1383 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1401 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1422 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1433: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+for ac_hdr in db1/db.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1460: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1465 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1470: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_hdr in assert.h db.h dirent.h err.h fcntl.h fnmatch.h limits.h md5.h md5global.h netdb.h pwd.h regex.h signal.h stdlib.h string.h termios.h time.h unistd.h vis.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1500: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1505 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1510: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_hdr in sys/file.h sys/ioctl.h sys/mount.h sys/param.h sys/queue.h sys/resource.h sys/stat.h sys/time.h sys/types.h sys/vfs.h sys/wait.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1540: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1545 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1550: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking for MD5File in -lmd""... $ac_c" 1>&6
+echo "configure:1578: checking for MD5File in -lmd" >&5
+ac_lib_var=`echo md'_'MD5File | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lmd $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1586 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char MD5File();
+
+int main() {
+MD5File()
+; return 0; }
+EOF
+if { (eval echo configure:1597: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo md | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lmd $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for dbopen in -ldb1""... $ac_c" 1>&6
+echo "configure:1625: checking for dbopen in -ldb1" >&5
+ac_lib_var=`echo db1'_'dbopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldb1 $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1633 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dbopen();
+
+int main() {
+dbopen()
+; return 0; }
+EOF
+if { (eval echo configure:1644: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo db1 | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-ldb1 $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+for ac_func in chflags
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1675: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1680 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1703: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in dbopen
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1730: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1735 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1758: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in err
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1785: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1790 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1813: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in errx
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1840: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1845 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1868: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in fgetln
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1895: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1900 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1923: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in getprogname
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1950: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1955 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1978: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in mkdtemp
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2005: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2010 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2033: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in setenv
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2060: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2065 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2088: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in setprogname
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2115: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2120 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2143: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in statfs
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2170: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2175 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2198: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in statvfs
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2225: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2230 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2253: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in strsep
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2280: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2285 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2308: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in strlcpy
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2335: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2340 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2363: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in unsetenv
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2390: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2395 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2418: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in warn
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2445: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2450 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2473: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in warnx
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2500: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2505 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2528: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in MD5File
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2555: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2560 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2583: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:2609: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2614 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:2663: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:2684: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2689 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile lib/Makefile lib/lib.h add/Makefile admin/Makefile create/Makefile delete/Makefile info/Makefile lib/config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@pkgdbdir@%$pkgdbdir%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@CC@%$CC%g
+s%@RANLIB@%$RANLIB%g
+s%@AR@%$AR%g
+s%@CHMOD@%$CHMOD%g
+s%@CHOWN@%$CHOWN%g
+s%@CHGRP@%$CHGRP%g
+s%@DIGEST@%$DIGEST%g
+s%@MKDIR@%$MKDIR%g
+s%@MTREE@%$MTREE%g
+s%@RM@%$RM%g
+s%@RMDIR@%$RMDIR%g
+s%@TAR_FULLPATHNAME@%$TAR_FULLPATHNAME%g
+s%@CPP@%$CPP%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile lib/Makefile lib/lib.h add/Makefile admin/Makefile create/Makefile delete/Makefile info/Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="lib/config.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/pkgtools/pkg_install/files/configure.in b/pkgtools/pkg_install/files/configure.in
new file mode 100644
index 00000000000..c0d3b6ec96f
--- /dev/null
+++ b/pkgtools/pkg_install/files/configure.in
@@ -0,0 +1,64 @@
+enl Process this file with autoconf to produce a configure script.
+AC_INIT(add/add.h)
+AC_CONFIG_HEADER(lib/config.h)
+
+dnl Set the prefix
+AC_PREFIX_DEFAULT(/usr/pkg)
+
+dnl Set the default pkg database dir
+AC_ARG_WITH(pkgdbdir,
+[ --with-pkgdbdir=DIR Where to put the pkg database (/var/db/pkg)],
+[ pkgdbdir="$with_pkgdbdir" ],
+[ pkgdbdir="/var/db/pkg" ])
+AC_SUBST(pkgdbdir)
+
+dnl Checks for programs.
+AC_PROG_INSTALL
+AC_PROG_CC
+AC_PROG_RANLIB
+AC_CHECK_PROGS(AR, ar)
+AC_PATH_PROGS(CHMOD, chmod)
+AC_PATH_PROGS(CHOWN, chown)
+AC_PATH_PROGS(CHGRP, chgrp)
+AC_PATH_PROGS(DIGEST, digest)
+AC_PATH_PROGS(MKDIR, mkdir)
+AC_PATH_PROGS(MTREE, mtree)
+AC_PATH_PROGS(RM, rm)
+AC_PATH_PROGS(RMDIR, rmdir)
+AC_PATH_PROGS(TAR_FULLPATHNAME, tar)
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS(db1/db.h)
+AC_CHECK_HEADERS(assert.h db.h dirent.h err.h fcntl.h fnmatch.h limits.h md5.h md5global.h netdb.h pwd.h regex.h signal.h stdlib.h string.h termios.h time.h unistd.h vis.h)
+AC_CHECK_HEADERS(sys/file.h sys/ioctl.h sys/mount.h sys/param.h sys/queue.h sys/resource.h sys/stat.h sys/time.h sys/types.h sys/vfs.h sys/wait.h)
+
+dnl Check for libraries
+AC_CHECK_LIB(md, MD5File)
+AC_CHECK_LIB(db1, dbopen)
+
+dnl Check for functions
+AC_CHECK_FUNCS(chflags)
+AC_CHECK_FUNCS(dbopen)
+AC_CHECK_FUNCS(err)
+AC_CHECK_FUNCS(errx)
+AC_CHECK_FUNCS(fgetln)
+AC_CHECK_FUNCS(getprogname)
+AC_CHECK_FUNCS(mkdtemp)
+AC_CHECK_FUNCS(setenv)
+AC_CHECK_FUNCS(setprogname)
+AC_CHECK_FUNCS(statfs)
+AC_CHECK_FUNCS(statvfs)
+AC_CHECK_FUNCS(strsep)
+AC_CHECK_FUNCS(strlcpy)
+AC_CHECK_FUNCS(unsetenv)
+AC_CHECK_FUNCS(warn)
+AC_CHECK_FUNCS(warnx)
+AC_CHECK_FUNCS(MD5File)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_SIZE_T
+
+dnl that's it for now...
+AC_OUTPUT(Makefile lib/Makefile lib/lib.h add/Makefile admin/Makefile create/Makefile delete/Makefile info/Makefile)
diff --git a/pkgtools/pkg_install/files/create/Makefile.in b/pkgtools/pkg_install/files/create/Makefile.in
new file mode 100644
index 00000000000..cd01e38ffa4
--- /dev/null
+++ b/pkgtools/pkg_install/files/create/Makefile.in
@@ -0,0 +1,39 @@
+# From NetBSD: Makefile,v 1.4 1997/10/17 14:53:47 lukem Exp $
+
+PREFIX= @prefix@
+INSTALL= @INSTALL@
+
+mandir= ${PREFIX}/man
+mandircat1= ${mandir}/cat1
+
+CC= @CC@
+CCLD= $(CC)
+LIBS= @LIBS@ -linstall
+CPPFLAGS= @CPPFLAGS@
+DEFS= @DEFS@ -I. -I@srcdir@ -I../lib
+CFLAGS= @CFLAGS@
+LDFLAGS= @LDFLAGS@ -L../lib
+
+LINK= $(CCLD) $(CFLAGS) $(LDFLAGS) -o $@
+COMPILE= $(CC) $(DEFS) $(CPPFLAGS) $(CFLAGS)
+
+PROG= pkg_create
+
+SRCS= main.c perform.c pl.c
+OBJS= main.o perform.o pl.o
+
+all: ${PROG}
+
+${PROG}: ${OBJS}
+ ${LINK} ${OBJS} ${LIBS}
+
+.c.o:
+ $(COMPILE) -c $< -o $@
+
+clean:
+ rm -f ${OBJS} ${PROG}
+
+install:
+ ${INSTALL} ${PROG} ${PREFIX}/sbin
+ ${INSTALL} -m 755 -d ${mandircat1}
+ ${INSTALL} -m 444 ${PROG}.cat1 ${mandircat1}/${PROG}.1
diff --git a/pkgtools/pkg_install/files/create/create.h b/pkgtools/pkg_install/files/create/create.h
new file mode 100644
index 00000000000..1877f7ac7cc
--- /dev/null
+++ b/pkgtools/pkg_install/files/create/create.h
@@ -0,0 +1,57 @@
+/* $NetBSD: create.h,v 1.1.1.1 2002/12/20 18:14:09 schmonz Exp $ */
+
+/* from FreeBSD Id: create.h,v 1.13 1997/10/08 07:46:19 charnier Exp */
+
+/*
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 18 July 1993
+ *
+ * Include and define various things wanted by the create command.
+ *
+ */
+
+#ifndef _INST_CREATE_H_INCLUDE
+#define _INST_CREATE_H_INCLUDE
+
+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 *ExcludeFrom;
+extern char *Mtree;
+extern char *Pkgdeps;
+extern char *Pkgcfl;
+extern char *BuildVersion;
+extern char *BuildInfo;
+extern char *SizePkg;
+extern char *SizeAll;
+extern char *SrcDir;
+extern char *realprefix;
+extern char PlayPen[];
+extern size_t PlayPenSize;
+extern int Dereference;
+extern int PlistOnly;
+extern int RelativeLinks;
+extern int ReorderDirs;
+extern int update_pkgdb;
+
+void check_list(char *, package_t *, const char *);
+void copy_plist(char *, package_t *);
+
+#endif /* _INST_CREATE_H_INCLUDE */
diff --git a/pkgtools/pkg_install/files/create/main.c b/pkgtools/pkg_install/files/create/main.c
new file mode 100644
index 00000000000..c4d94393d64
--- /dev/null
+++ b/pkgtools/pkg_install/files/create/main.c
@@ -0,0 +1,225 @@
+/* $NetBSD: main.c,v 1.1.1.1 2002/12/20 18:14:09 schmonz Exp $ */
+
+#if 0
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static const char *rcsid = "from FreeBSD Id: main.c,v 1.17 1997/10/08 07:46:23 charnier Exp";
+#else
+__RCSID("$NetBSD: main.c,v 1.1.1.1 2002/12/20 18:14:09 schmonz Exp $");
+#endif
+#endif
+#endif
+
+/*
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Jordan K. Hubbard
+ * 18 July 1993
+ *
+ * This is the create module.
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#include "lib.h"
+#include "create.h"
+
+static const char Options[] = "ORhlVvFf:p:P:C:c:d:i:k:L:r:t:X:D:m:s:S:b:B:UI:";
+
+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 *ExcludeFrom = NULL;
+char *Mtree = NULL;
+char *Pkgdeps = NULL;
+char *Pkgcfl = NULL;
+char *BuildVersion = NULL;
+char *BuildInfo = NULL;
+char *SizePkg = NULL;
+char *SizeAll = NULL;
+char *SrcDir = NULL;
+char *realprefix = NULL;
+char PlayPen[FILENAME_MAX];
+size_t PlayPenSize = sizeof(PlayPen);
+int update_pkgdb = 1;
+int Dereference = 0;
+int PlistOnly = 0;
+int RelativeLinks = 0;
+int ReorderDirs = 0;
+Boolean File2Pkg = FALSE;
+
+static void
+usage(void)
+{
+ fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n",
+ "usage: pkg_create [-ORUhlVv] [-P dpkgs] [-C cpkgs] [-p prefix] [-f contents]",
+ " [-i iscript] [-k dscript] [-r rscript] [-t template]",
+ " [-X excludefile] [-D displayfile] [-m mtreefile]",
+ " [-b build-version-file] [-B build-info-file]",
+ " [-I realprefix]",
+ " -c comment -d description -f packlist pkg-name");
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ int ch;
+ lpkg_head_t pkgs;
+ lpkg_t *lpp;
+
+ setprogname(argv[0]);
+
+ while ((ch = getopt(argc, argv, Options)) != -1)
+ switch (ch) {
+ case 'v':
+ Verbose = TRUE;
+ break;
+
+ case 'I':
+ realprefix = optarg;
+ break;
+
+ case 'O':
+ PlistOnly = 1;
+ break;
+
+ case 'R':
+ ReorderDirs = 1;
+ break;
+
+ case 'U':
+ update_pkgdb = 0;
+ break;
+
+ case 'p':
+ Prefix = optarg;
+ break;
+
+ case 's':
+ SizePkg = optarg;
+ break;
+
+ case 'S':
+ SizeAll = optarg;
+ break;
+
+ case 'f':
+ Contents = optarg;
+ break;
+
+ case 'c':
+ Comment = optarg;
+ break;
+
+ case 'd':
+ Desc = optarg;
+ break;
+
+ case 'i':
+ Install = optarg;
+ break;
+
+ case 'k':
+ DeInstall = optarg;
+ break;
+
+ case 'l':
+ RelativeLinks = 1;
+ break;
+
+ case 'L':
+ SrcDir = optarg;
+ break;
+
+ case 'r':
+ Require = optarg;
+ break;
+
+ case 't':
+ strcpy(PlayPen, optarg);
+ break;
+
+ case 'X':
+ ExcludeFrom = optarg;
+ break;
+
+ case 'h':
+ Dereference = 1;
+ break;
+
+ case 'D':
+ Display = optarg;
+ break;
+
+ case 'm':
+ Mtree = optarg;
+ break;
+
+ case 'P':
+ Pkgdeps = optarg;
+ break;
+
+ case 'C':
+ Pkgcfl = optarg;
+ break;
+
+ case 'b':
+ BuildVersion = optarg;
+ break;
+
+ case 'B':
+ BuildInfo = optarg;
+ break;
+
+ case 'V':
+ show_version();
+ /* NOTREACHED */
+
+ case '?':
+ default:
+ usage();
+ break;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ TAILQ_INIT(&pkgs);
+
+ /* Get all the remaining package names, if any */
+ while (*argv) {
+ lpp = alloc_lpkg(*argv);
+ TAILQ_INSERT_TAIL(&pkgs, lpp, lp_link);
+ argv++;
+ }
+
+ /* If no packages, yelp */
+ lpp = TAILQ_FIRST(&pkgs);
+ if (lpp == NULL)
+ warnx("missing package name"), usage();
+ lpp = TAILQ_NEXT(lpp, lp_link);
+ if (lpp != NULL)
+ warnx("only one package name allowed ('%s' extraneous)",
+ lpp->lp_name),
+ usage();
+ if (!pkg_perform(&pkgs)) {
+ if (Verbose)
+ warnx("package creation failed");
+ return 1;
+ } else
+ return 0;
+}
diff --git a/pkgtools/pkg_install/files/create/perform.c b/pkgtools/pkg_install/files/create/perform.c
new file mode 100644
index 00000000000..7e61890175a
--- /dev/null
+++ b/pkgtools/pkg_install/files/create/perform.c
@@ -0,0 +1,417 @@
+/* $NetBSD: perform.c,v 1.1.1.1 2002/12/20 18:14:10 schmonz Exp $ */
+
+#if 0
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static const char *rcsid = "from FreeBSD Id: perform.c,v 1.38 1997/10/13 15:03:51 jkh Exp";
+#else
+__RCSID("$NetBSD: perform.c,v 1.1.1.1 2002/12/20 18:14:10 schmonz Exp $");
+#endif
+#endif
+#endif
+
+/*
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 18 July 1993
+ *
+ * This is the main body of the create module.
+ *
+ */
+
+#include "lib.h"
+#include "create.h"
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#include <signal.h>
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#include <unistd.h>
+
+static char *Home;
+
+static void
+make_dist(const char *home, const char *pkg, const char *suffix, const package_t *plist)
+{
+ char tball[FILENAME_MAX];
+ const plist_t *p;
+ int ret;
+ char *args[50]; /* Much more than enough. */
+ int nargs = 1;
+ int pipefds[2];
+ FILE *totar;
+ pid_t pid;
+
+ if ((args[0] = strrchr(TAR_FULLPATHNAME, '/')) == NULL)
+ args[0] = TAR_FULLPATHNAME;
+ else
+ args[0]++;
+
+ if (*pkg == '/')
+ (void) snprintf(tball, sizeof(tball), "%s.%s", pkg, suffix);
+ else
+ (void) snprintf(tball, sizeof(tball), "%s/%s.%s", home, pkg, suffix);
+
+ args[nargs++] = "-c";
+ args[nargs++] = "-f";
+ args[nargs++] = tball;
+ if (strstr(suffix, "bz")) {
+ args[nargs++] = "--use-compress-program";
+ args[nargs++] = "bzip2";
+ } else if (strchr(suffix, 'z'))/* Compress/gzip? */
+ args[nargs++] = "-z";
+ if (Dereference)
+ args[nargs++] = "-h";
+ if (ExcludeFrom) {
+ args[nargs++] = "-X";
+ args[nargs++] = ExcludeFrom;
+ }
+ args[nargs++] = "-T"; /* Take filenames from file instead of args. */
+ args[nargs++] = "-"; /* Use stdin for the file. */
+ args[nargs] = NULL;
+
+ if (Verbose)
+ printf("Creating gzip'd binary package in '%s'\n", tball);
+
+ /* Set up a pipe for passing the filenames, and fork off a tar process. */
+ if (pipe(pipefds) == -1) {
+ cleanup(0);
+ errx(2, "cannot create pipe");
+ }
+ if ((pid = fork()) == -1) {
+ cleanup(0);
+ errx(2, "cannot fork process for %s", TAR_FULLPATHNAME);
+ }
+ if (pid == 0) { /* The child */
+ dup2(pipefds[0], 0);
+ close(pipefds[0]);
+ close(pipefds[1]);
+ execvp(TAR_FULLPATHNAME, args);
+ cleanup(0);
+ errx(2, "failed to execute %s command", TAR_FULLPATHNAME);
+ }
+
+ /* Meanwhile, back in the parent process ... */
+ close(pipefds[0]);
+ if ((totar = fdopen(pipefds[1], "w")) == NULL) {
+ cleanup(0);
+ errx(2, "fdopen failed");
+ }
+
+ fprintf(totar, "%s\n", CONTENTS_FNAME);
+ fprintf(totar, "%s\n", COMMENT_FNAME);
+ fprintf(totar, "%s\n", DESC_FNAME);
+
+ if (Install) {
+ fprintf(totar, "%s\n", INSTALL_FNAME);
+ }
+ if (DeInstall) {
+ fprintf(totar, "%s\n", DEINSTALL_FNAME);
+ }
+ if (Require) {
+ fprintf(totar, "%s\n", REQUIRE_FNAME);
+ }
+ if (Display) {
+ fprintf(totar, "%s\n", DISPLAY_FNAME);
+ }
+ if (Mtree) {
+ fprintf(totar, "%s\n", MTREE_FNAME);
+ }
+ if (BuildVersion) {
+ (void) fprintf(totar, "%s\n", BUILD_VERSION_FNAME);
+ }
+ if (BuildInfo) {
+ (void) fprintf(totar, "%s\n", BUILD_INFO_FNAME);
+ }
+ if (SizePkg) {
+ (void) fprintf(totar, "%s\n", SIZE_PKG_FNAME);
+ }
+ if (SizeAll) {
+ (void) fprintf(totar, "%s\n", SIZE_ALL_FNAME);
+ }
+
+ for (p = plist->head; p; p = p->next) {
+ if (p->type == PLIST_FILE) {
+ fprintf(totar, "%s\n", p->name);
+ } else if (p->type == PLIST_CWD || p->type == PLIST_SRC) {
+
+ /* XXX let PLIST_SRC override PLIST_CWD */
+ if (p->type == PLIST_CWD && p->next != NULL &&
+ p->next->type == PLIST_SRC) {
+ continue;
+ }
+
+ fprintf(totar, "-C\n%s\n", p->name);
+ } else if (p->type == PLIST_IGNORE) {
+ p = p->next;
+ }
+ }
+
+ fclose(totar);
+ wait(&ret);
+ /* assume either signal or bad exit is enough for us */
+ if (ret) {
+ cleanup(0);
+ errx(2, "%s command failed with code %d", TAR_FULLPATHNAME, ret);
+ }
+}
+
+static void
+sanity_check(void)
+{
+ if (!Comment) {
+ cleanup(0);
+ errx(2, "required package comment string is missing (-c comment)");
+ }
+ if (!Desc) {
+ cleanup(0);
+ errx(2, "required package description string is missing (-d desc)");
+ }
+ if (!Contents) {
+ cleanup(0);
+ errx(2, "required package contents list is missing (-f [-]file)");
+ }
+}
+
+
+/*
+ * Clean up those things that would otherwise hang around
+ */
+void
+cleanup(int sig)
+{
+ static int alreadyCleaning;
+ void (*oldint) (int);
+ void (*oldhup) (int);
+ oldint = signal(SIGINT, SIG_IGN);
+ oldhup = signal(SIGHUP, SIG_IGN);
+
+ if (!alreadyCleaning) {
+ alreadyCleaning = 1;
+ if (sig)
+ printf("Signal %d received, cleaning up.\n", sig);
+ leave_playpen(Home);
+ if (sig)
+ exit(1);
+ }
+ signal(SIGINT, oldint);
+ signal(SIGHUP, oldhup);
+}
+
+int
+pkg_perform(lpkg_head_t *pkgs)
+{
+ const char *pkg;
+ char *cp;
+ FILE *pkg_in, *fp;
+ package_t plist;
+ char *suffix; /* What we tack on to the end of the finished package */
+ lpkg_t *lpp;
+ char installed[FILENAME_MAX];
+
+ lpp = TAILQ_FIRST(pkgs);
+ pkg = lpp->lp_name; /* Only one arg to create */
+
+ /* Preliminary setup */
+ sanity_check();
+ if (Verbose && !PlistOnly)
+ printf("Creating package %s\n", pkg);
+ get_dash_string(&Comment);
+ get_dash_string(&Desc);
+ if (IS_STDIN(Contents))
+ pkg_in = stdin;
+ else {
+ pkg_in = fopen(Contents, "r");
+ if (!pkg_in) {
+ cleanup(0);
+ errx(2, "unable to open contents file '%s' for input", Contents);
+ }
+ }
+ plist.head = plist.tail = NULL;
+
+ /* Break the package name into base and desired suffix (if any) */
+ if ((cp = strrchr(pkg, '.')) != NULL) {
+ suffix = cp + 1;
+ *cp = '\0';
+ } else
+ suffix = "tgz";
+
+ /* If a SrcDir override is set, add it now */
+ if (SrcDir) {
+ if (Verbose && !PlistOnly)
+ printf("Using SrcDir value of %s\n", (realprefix) ? realprefix : SrcDir);
+ add_plist(&plist, PLIST_SRC, SrcDir);
+ }
+
+ /* Stick the dependencies, if any, at the top */
+ if (Pkgdeps) {
+ if (Verbose && !PlistOnly)
+ printf("Registering depends:");
+ while (Pkgdeps) {
+ cp = strsep(&Pkgdeps, " \t\n");
+ if (*cp) {
+ if (findmatchingname(_pkgdb_getPKGDB_DIR(), cp, note_whats_installed, installed) > 0) {
+ add_plist(&plist, PLIST_BLDDEP, installed);
+ }
+ add_plist(&plist, PLIST_PKGDEP, cp);
+ if (Verbose && !PlistOnly)
+ printf(" %s", cp);
+ }
+ }
+ if (Verbose && !PlistOnly)
+ printf(".\n");
+ }
+
+ /* Put the conflicts directly after the dependencies, if any */
+ if (Pkgcfl) {
+ if (Verbose && !PlistOnly)
+ printf("Registering conflicts:");
+ while (Pkgcfl) {
+ cp = strsep(&Pkgcfl, " \t\n");
+ if (*cp) {
+ add_plist(&plist, PLIST_PKGCFL, cp);
+ if (Verbose && !PlistOnly)
+ printf(" %s", cp);
+ }
+ }
+ if (Verbose && !PlistOnly)
+ printf(".\n");
+ }
+
+ /* Slurp in the packing list */
+ read_plist(&plist, pkg_in);
+
+ if (pkg_in != stdin)
+ fclose(pkg_in);
+
+ /* Prefix should override the packing list */
+ if (Prefix) {
+ delete_plist(&plist, FALSE, PLIST_CWD, NULL);
+ add_plist_top(&plist, PLIST_CWD, Prefix);
+ }
+ /*
+ * Run down the list and see if we've named it, if not stick in a name
+ * at the top.
+ */
+ if (find_plist(&plist, PLIST_NAME) == NULL) {
+ add_plist_top(&plist, PLIST_NAME, basename_of(pkg));
+ }
+
+ /*
+ * We're just here for to dump out a revised plist for the FreeBSD ports
+ * hack. It's not a real create in progress.
+ */
+ if (PlistOnly) {
+ check_list(Home, &plist, basename_of(pkg));
+ write_plist(&plist, stdout, realprefix);
+ exit(0);
+ }
+
+ /* Make a directory to stomp around in */
+ Home = make_playpen(PlayPen, PlayPenSize, 0);
+ signal(SIGINT, cleanup);
+ signal(SIGHUP, cleanup);
+
+ /* Make first "real contents" pass over it */
+ check_list(Home, &plist, basename_of(pkg));
+ (void) umask(022); /* make sure gen'ed directories, files
+ * don't have group or other write bits. */
+
+ /* Now put the release specific items in */
+ add_plist(&plist, PLIST_CWD, ".");
+ write_file(COMMENT_FNAME, Comment);
+ add_plist(&plist, PLIST_IGNORE, NULL);
+ add_plist(&plist, PLIST_FILE, COMMENT_FNAME);
+ write_file(DESC_FNAME, Desc);
+ add_plist(&plist, PLIST_IGNORE, NULL);
+ add_plist(&plist, PLIST_FILE, DESC_FNAME);
+
+ if (Install) {
+ copy_file(Home, Install, INSTALL_FNAME);
+ add_plist(&plist, PLIST_IGNORE, NULL);
+ add_plist(&plist, PLIST_FILE, INSTALL_FNAME);
+ }
+ if (DeInstall) {
+ copy_file(Home, DeInstall, DEINSTALL_FNAME);
+ add_plist(&plist, PLIST_IGNORE, NULL);
+ add_plist(&plist, PLIST_FILE, DEINSTALL_FNAME);
+ }
+ if (Require) {
+ copy_file(Home, Require, REQUIRE_FNAME);
+ 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);
+ }
+ if (BuildVersion) {
+ copy_file(Home, BuildVersion, BUILD_VERSION_FNAME);
+ add_plist(&plist, PLIST_IGNORE, NULL);
+ add_plist(&plist, PLIST_FILE, BUILD_VERSION_FNAME);
+ }
+ if (BuildInfo) {
+ copy_file(Home, BuildInfo, BUILD_INFO_FNAME);
+ add_plist(&plist, PLIST_IGNORE, NULL);
+ add_plist(&plist, PLIST_FILE, BUILD_INFO_FNAME);
+ }
+ if (SizePkg) {
+ copy_file(Home, SizePkg, SIZE_PKG_FNAME);
+ add_plist(&plist, PLIST_IGNORE, NULL);
+ add_plist(&plist, PLIST_FILE, SIZE_PKG_FNAME);
+ }
+ if (SizeAll) {
+ copy_file(Home, SizeAll, SIZE_ALL_FNAME);
+ add_plist(&plist, PLIST_IGNORE, NULL);
+ add_plist(&plist, PLIST_FILE, SIZE_ALL_FNAME);
+ }
+
+ /* Finally, write out the packing list */
+ fp = fopen(CONTENTS_FNAME, "w");
+ if (!fp) {
+ cleanup(0);
+ errx(2, "can't open file %s for writing", CONTENTS_FNAME);
+ }
+ write_plist(&plist, fp, realprefix);
+ if (fclose(fp)) {
+ cleanup(0);
+ errx(2, "error while closing %s", CONTENTS_FNAME);
+ }
+
+ /* And stick it into a tar ball */
+ make_dist(Home, pkg, suffix, &plist);
+
+ /* Cleanup */
+ free(Comment);
+ free(Desc);
+ free_plist(&plist);
+ leave_playpen(Home);
+
+ return TRUE; /* Success */
+}
diff --git a/pkgtools/pkg_install/files/create/pkg_create.1 b/pkgtools/pkg_install/files/create/pkg_create.1
new file mode 100644
index 00000000000..71c07f0421d
--- /dev/null
+++ b/pkgtools/pkg_install/files/create/pkg_create.1
@@ -0,0 +1,528 @@
+.\" $NetBSD: pkg_create.1,v 1.1.1.1 2002/12/20 18:14:10 schmonz Exp $
+.\"
+.\" FreeBSD install - a package for the installation and maintainance
+.\" of non-core utilities.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" Jordan K. Hubbard
+.\"
+.\"
+.\" @(#)pkg_create.1
+.\" from FreeBSD Id: pkg_create.1,v 1.19 1997/05/02 22:00:05 max Exp
+.\"
+.\" hacked up by John Kohl for NetBSD--fixed a few bugs, extended keywords,
+.\" added dependency tracking, etc.
+.\"
+.\" [jkh] Took John's changes back and made some additional extensions for
+.\" better integration with FreeBSD's new ports collection.
+.\"
+.Dd April 21, 1995
+.Dt PKG_CREATE 1
+.Os
+.Sh NAME
+.Nm pkg_create
+.Nd a utility for creating software package distributions
+.Sh SYNOPSIS
+.Nm
+.Op Fl hlORUVv
+.Bk -words
+.Op Fl B Ar build-info-file
+.Ek
+.Bk -words
+.Op Fl C Ar cpkgs
+.Ek
+.Bk -words
+.Op Fl D Ar displayfile
+.Ek
+.Bk -words
+.Op Fl P Ar dpkgs
+.Ek
+.Bk -words
+.Op Fl X Ar excludefile
+.Ek
+.Bk -words
+.Op Fl b Ar build-version-file
+.Ek
+.Bk -words
+.Op Fl f Ar contents
+.Ek
+.Bk -words
+.Op Fl i Ar iscript
+.Ek
+.Bk -words
+.Op Fl I Ar realprefix
+.Ek
+.Bk -words
+.Op Fl k Ar dscript
+.Ek
+.Bk -words
+.Op Fl L Ar SrcDir
+.Ek
+.Bk -words
+.Op Fl m Ar mtreefile
+.Ek
+.Bk -words
+.Op Fl p Ar prefix
+.Ek
+.Bk -words
+.Op Fl r Ar rscript
+.Ek
+.Bk -words
+.Op Fl s Ar size-pkg-file
+.Ek
+.Bk -words
+.Op Fl S Ar size-all-file
+.Ek
+.Bk -words
+.Op Fl t Ar template
+.Ek
+.Bk -words
+.Fl c Ar comment
+.Ek
+.Bk -words
+.Fl d Ar description
+.Ek
+.Bk -words
+.Fl f Ar packlist
+.Ek
+.Ar pkg-name
+.Sh DESCRIPTION
+The
+.Nm
+command is used to create packages that will subsequently be fed to
+one of the package extraction/info utilities.
+The input description and command line arguments for the creation of a
+package are not really meant to be human-generated, though it is easy
+enough to do so.
+It is more expected that you will use a front-end tool for
+the job rather than muddling through it yourself.
+Nonetheless, a short description of the input syntax is included in this
+document.
+.Sh OPTIONS
+The following command line options are supported:
+.Bl -tag -width indent
+.It Fl B Ar build-info-file
+Install the file
+.Ar build-info-file
+so that users of binary packages can see what
+.Xr make 1
+definitions
+were used to control the build when creating the
+binary package.
+This allows various build definitions to be retained in a binary package
+and viewed wherever it is installed, using
+.Xr pkg_info 1 .
+.It Fl b Ar build-version-file
+Install the file
+.Ar build-version-file
+so that users of binary packages can see what versions of
+the files used to control the build were used when creating the
+binary package.
+This allows some fine-grained version control information to be retained
+in a binary package and viewed wherever it is installed, using
+.Xr pkg_info 1 .
+.It Fl C Ar cpkgs
+Set the initial package conflict list to
+.Ar cpkgs .
+This is assumed to be a whitespace separated list of package names
+and is meant as a convenient shorthand for specifying multiple
+.Cm @pkgcfl
+directives in the packing list (see PACKING LIST DETAILS section below).
+.It Fl c Ar [-]desc
+Fetch package ``one line description'' from file
+.Ar desc
+or, if preceded by
+.Cm - ,
+the argument itself.
+This string should also give some idea of which version of the product
+(if any) the package represents.
+.It Fl D Ar displayfile
+Display the file after installing the package.
+Useful for things like legal notices on almost-free software, etc.
+.It Fl d Ar [-]desc
+Fetch long description for package from file
+.Ar desc
+or, if preceded by
+.Cm - ,
+the argument itself.
+.It Fl f Ar packinglist
+Fetch ``packing list'' for package from the file
+.Ar packinglist
+or
+.Cm stdin
+if
+.Ar packinglist
+is a
+.Cm -
+(dash).
+.It Fl h
+Force tar to follow symbolic links, so that the files they point to
+are dumped, rather than the links themselves.
+.It Fl I Ar realprefix
+Provide the real prefix, as opposed to the staging prefix, for use in
+staged installations of packages.
+.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 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 L Ar SrcDir
+This sets the package's @src directive; see below for a description
+of what this does.
+.It Fl l
+Check that any symbolic links which are to be placed in the package are
+relative to the current prefix.
+This means using
+.Xr unlink 2
+and
+.Xr symlink 2
+to remove and re-link
+any symbolic links which are targeted at full path names.
+.It Fl m Ar mtreefile
+Run
+.Xr mtree 8
+with input from mtreefile before the package is installed.
+Mtree is invoked as
+.Cm mtree
+.Fl u
+.Fl f
+.Ar mtreefile
+.Fl d
+.Fl e
+.Fl p
+.Pa prefix ,
+where
+.Pa prefix
+is the name of the first directory named by a
+.Cm @cwd
+directive.
+.It Fl O
+Go into a `packing list Only' mode.
+This is used to do `fake pkg_add' operations when a package is installed.
+In such cases, it is necessary to know what the final, adjusted packing
+list will look like.
+.It Fl P Ar dpkgs
+Set the initial package dependency list to
+.Ar dpkgs .
+This is assumed to be a whitespace separated list of package names
+and is meant as a convenient shorthand for specifying multiple
+.Cm @pkgdep
+directives in the packing list (see PACKING LIST DETAILS section below).
+In addition, the exact versions of the packages referred to in the
+.Ar dpkgs
+list will be added to the packing list in the form of
+.Cm @blddep
+directives.
+.It Fl p Ar prefix
+Set
+.Ar prefix
+as the initial directory ``base'' to start from in selecting files for
+the package.
+.It Fl R
+Re-order any directories in the pkg/PLIST file into reverse alphabetic
+order, so that child directories will automatically be removed before
+parent directories.
+.It Fl r Ar rscript
+Set
+.Ar rscript
+to be the ``requirements'' procedure for the package.
+This can be any executable program (or shell script).
+It will be invoked automatically at installation/deinstallation time to
+determine whether or not installation/deinstallation should proceed.
+.It Fl S Ar size-all-file
+Store the given file for later querying with the
+.Xr pkg_info 1
+.Ar -S
+flag.
+The file is expected to contain the size (in bytes) of all files of
+this package plus any required packages added up and stored as a
+ASCII string, terminated by a newline.
+.It Fl s Ar size-pkg-file
+Store the given file for later querying with the
+.Xr pkg_info 1
+.Ar -s
+flag.
+The file is expected to contain the the size (in bytes) of all files of
+this package added up and stored as a ASCII string, terminated by a newline.
+.It Fl t Ar template
+Use
+.Ar template
+as the input to
+.Xr mktemp 3 .
+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
+.Pa /tmp
+directory is limited.
+Be sure to leave some number of `X' characters for
+.Xr mktemp 3
+to fill in with a unique ID.
+.It Fl U
+Do not update the package file database with any file information.
+.It Fl V
+Print version number and exit.
+.It Fl v
+Turn on verbose output.
+.It Fl X Ar excludefile
+Pass
+.Ar excludefile
+as a
+.Fl -exclude-from
+argument to
+.Cm tar
+when creating final package.
+See
+.Cm tar
+man page (or run
+.Cm tar
+with
+.Fl -help
+flag) for further information on using this flag.
+.El
+.Sh PACKING LIST DETAILS
+The ``packing list'' format (see
+.Fl f )
+is fairly simple, being
+nothing more than a single column of filenames to include in the
+package.
+However, since absolute pathnames are generally a bad idea
+for a package that could be installed potentially anywhere, there is
+another method of specifying where things are supposed to go
+and, optionally, what ownership and mode information they should be
+installed with.
+This is done by embedding specialized command sequences
+in the packing list.
+Briefly described, these sequences are:
+.Bl -tag -width indent -compact
+.It Cm @cwd Ar directory
+Set the internal directory pointer to point to
+.Ar directory .
+All subsequent filenames will be assumed relative to this directory.
+Note:
+.Cm @cd
+is also an alias for this command.
+.It Cm @src Ar directory
+Set the internal directory pointer for _creation only_ to
+.Ar directory .
+That is to say that it overrides
+.Cm @cwd
+for package creation but not extraction.
+.It Cm @exec Ar command
+Execute
+.Ar command
+as part of the unpacking process.
+If
+.Ar command
+contains any of the following sequences somewhere in it, they will
+be expanded inline.
+For the following examples, assume that
+.Cm @cwd
+is set to
+.Pa /usr/local
+and the last extracted file was
+.Pa bin/emacs .
+.Bl -tag -width indent -compact
+.It Cm "%F"
+Expands to the last filename extracted (as specified), in the example case
+.Pa bin/emacs
+.It Cm "%D"
+Expand to the current directory prefix, as set with
+.Cm @cwd ,
+in the example case
+.Pa /usr/local .
+.It Cm "%B"
+Expand to the ``basename'' of the fully qualified filename, that
+is the current directory prefix, plus the last filespec, minus
+the trailing filename.
+In the example case, that would be
+.Pa /usr/local/bin .
+.It Cm "%f"
+Expand to the ``filename'' part of the fully qualified name, or
+the converse of
+.Cm %B ,
+being in the example case,
+.Pa emacs .
+.El
+.It Cm @unexec Ar command
+Execute
+.Ar command
+as part of the deinstallation process.
+Expansion of special
+.Cm %
+sequences is the same as for
+.Cm @exec .
+This command is not executed during the package add, as
+.Cm @exec
+is, but rather when the package is deleted.
+This is useful for deleting links and other ancillary files that were created
+as a result of adding the package, but not directly known to the package's
+table of contents (and hence not automatically removable).
+The advantage of using
+.Cm @unexec
+over a deinstallation script is that you can use the ``special
+sequence expansion'' to get at files regardless of where they've
+been potentially redirected (see
+.Fl p ) .
+.It Cm @mode Ar mode
+Set default permission for all subsequently extracted files to
+.Ar mode .
+Format is the same as that used by the
+.Cm chmod
+command (well, considering that it's later handed off to it, that's
+no surprise).
+Use without an arg to set back to default (extraction) permissions.
+.It Cm @option Ar option
+Set internal package options, the only two currently supported ones
+being
+.Ar extract-in-place ,
+which tells the pkg_add command not to extract the package's tarball
+into a staging area but rather directly into the target
+hierarchy (this is typically meant to be used only by distributions
+or other special package types), and
+.Ar preserve ,
+which tells pkg_add to move any existing files out of the way,
+preserving the previous contents (which are also resurrected on
+pkg_delete, so caveat emptor).
+.It Cm @owner Ar user
+Set default ownership for all subsequently extracted files to
+.Ar user .
+Use without an arg to set back to default (extraction)
+ownership.
+.It Cm @group Ar group
+Set default group ownership for all subsequently extracted files to
+.Ar group .
+Use without an arg to set back to default (extraction)
+group ownership.
+.It Cm @comment Ar string
+Imbed a comment in the packing list.
+Useful in trying to document some particularly hairy sequence that
+may trip someone up later.
+.It Cm @ignore
+Used internally to tell extraction to ignore the next file (don't
+copy it anywhere), as it's used for some special purpose.
+.It Cm @ignore_inst
+Similar to
+.Cm @ignore ,
+but the ignoring of the next file is delayed one evaluation cycle.
+This makes it possible to use this directive in the
+.Ar packinglist
+file, so you can pack a
+specialized datafile in with a distribution for your install script (or
+something) yet have the installer ignore it.
+.It Cm @name Ar name
+Set the name of the package.
+This is mandatory and is usually put at the top.
+This name is potentially different than the name of the file it came in,
+and is used when keeping track of the package for later deinstallation.
+Note that
+.Nm
+will derive this field from the package name and add it automatically
+if none is given.
+.It Cm @dirrm Ar name
+Declare directory
+.Pa name
+to be deleted at deinstall time.
+By default, directories created by a package installation are not deleted
+when the package is deinstalled; this provides an explicit directory cleanup
+method.
+This directive should appear at the end of the package list.
+If more than one
+.Cm @dirrm
+directives are used, the directories are removed in the order specified.
+The
+.Pa name
+directory will not be removed unless it is empty.
+.It Cm @mtree Ar name
+Declare
+.Pa name
+as an
+.Xr mtree 8
+input file to be used at install time (see
+.Fl m
+above).
+Only the first
+.Cm @mtree
+directive is honored.
+.It Cm @display Ar name
+Declare
+.Pa name
+as the file to be displayed at install time (see
+.Fl D
+above).
+.It Cm @pkgdep Ar pkgname
+Declare a dependency on the
+.Ar pkgname
+package.
+The
+.Ar pkgname
+package must be installed before this package may be
+installed, and this package must be deinstalled before the
+.Ar pkgname
+package is deinstalled.
+Multiple
+.Cm @pkgdep
+directives may be used if the package depends on multiple other packages.
+.It Cm @blddep Ar pkgname
+Declare that this package was built with the exact version
+of
+.Ar pkgname
+(since the
+.Cm @pkgdep
+directive may contain wildcards or relational
+package version information).
+.It Cm @pkgcfl Ar pkgcflname
+Declare a conflict with the
+.Ar pkgcflname
+package, as the two packages contain references to the same files,
+and so cannot co-exist on the same system.
+.El
+.Sh SEE ALSO
+.Xr pkg_add 1 ,
+.Xr pkg_admin 1 ,
+.Xr pkg_delete 1 ,
+.Xr pkg_info 1 ,
+.Xr sysconf 3 ,
+.Xr packages 7
+.Sh HISTORY
+The
+.Nm
+command first appeared in
+.Fx .
+.Sh AUTHORS
+.Bl -tag -width indent -compact
+.It "Jordan Hubbard"
+most of the work
+.It "John Kohl"
+refined it for
+.Nx
+.It "Hubert Feyrer"
+.Nx
+wildcard dependency processing, pkgdb, pkg size recording etc.
+.El
+.Sh BUGS
+Hard links between files in a distribution must be bracketed by
+.Cm @cwd
+directives in order to be preserved as hard links when the package is
+extracted.
+They additionally must not end up being split between
+.Cm tar
+invocations due to exec argument-space limitations (this depends on the
+value returned by
+.Fn sysconf _SC_ARG_MAX ) .
diff --git a/pkgtools/pkg_install/files/create/pkg_create.cat1 b/pkgtools/pkg_install/files/create/pkg_create.cat1
new file mode 100644
index 00000000000..7ba95b827a2
--- /dev/null
+++ b/pkgtools/pkg_install/files/create/pkg_create.cat1
@@ -0,0 +1,298 @@
+PKG_CREATE(1) NetBSD Reference Manual PKG_CREATE(1)
+
+NNAAMMEE
+ ppkkgg__ccrreeaattee - a utility for creating software package distributions
+
+SSYYNNOOPPSSIISS
+ ppkkgg__ccrreeaattee [--hhllOORRUUVVvv] [--BB _b_u_i_l_d_-_i_n_f_o_-_f_i_l_e] [--CC _c_p_k_g_s] [--DD _d_i_s_p_l_a_y_f_i_l_e]
+ [--PP _d_p_k_g_s] [--XX _e_x_c_l_u_d_e_f_i_l_e] [--bb _b_u_i_l_d_-_v_e_r_s_i_o_n_-_f_i_l_e] [--ff _c_o_n_t_e_n_t_s]
+ [--ii _i_s_c_r_i_p_t] [--II _r_e_a_l_p_r_e_f_i_x] [--kk _d_s_c_r_i_p_t] [--LL _S_r_c_D_i_r] [--mm _m_t_r_e_e_f_i_l_e]
+ [--pp _p_r_e_f_i_x] [--rr _r_s_c_r_i_p_t] [--ss _s_i_z_e_-_p_k_g_-_f_i_l_e] [--SS _s_i_z_e_-_a_l_l_-_f_i_l_e]
+ [--tt _t_e_m_p_l_a_t_e] --cc _c_o_m_m_e_n_t --dd _d_e_s_c_r_i_p_t_i_o_n --ff _p_a_c_k_l_i_s_t _p_k_g_-_n_a_m_e
+
+DDEESSCCRRIIPPTTIIOONN
+ The ppkkgg__ccrreeaattee command is used to create packages that will subsequently
+ be fed to one of the package extraction/info utilities. The input de-
+ scription and command line arguments for the creation of a package are
+ not really meant to be human-generated, though it is easy enough to do
+ so. It is more expected that you will use a front-end tool for the job
+ rather than muddling through it yourself. Nonetheless, a short descrip-
+ tion of the input syntax is included in this document.
+
+OOPPTTIIOONNSS
+ The following command line options are supported:
+
+ --BB _b_u_i_l_d_-_i_n_f_o_-_f_i_l_e
+ Install the file _b_u_i_l_d_-_i_n_f_o_-_f_i_l_e so that users of binary packages
+ can see what make(1) definitions were used to control the build
+ when creating the binary package. This allows various build def-
+ initions to be retained in a binary package and viewed wherever
+ it is installed, using pkg_info(1).
+
+ --bb _b_u_i_l_d_-_v_e_r_s_i_o_n_-_f_i_l_e
+ Install the file _b_u_i_l_d_-_v_e_r_s_i_o_n_-_f_i_l_e so that users of binary pack-
+ ages can see what versions of the files used to control the build
+ were used when creating the binary package. This allows some
+ fine-grained version control information to be retained in a bi-
+ nary package and viewed wherever it is installed, using
+ pkg_info(1).
+
+ --CC _c_p_k_g_s
+ Set the initial package conflict list to _c_p_k_g_s. This is assumed
+ to be a whitespace separated list of package names and is meant
+ as a convenient shorthand for specifying multiple @@ppkkggccffll direc-
+ tives in the packing list (see PACKING LIST DETAILS section be-
+ low).
+
+ --cc _[_-_]_d_e_s_c
+ Fetch package ``one line description'' from file _d_e_s_c or, if pre-
+ ceded by --, the argument itself. This string should also give
+ some idea of which version of the product (if any) the package
+ represents.
+
+ --DD _d_i_s_p_l_a_y_f_i_l_e
+ Display the file after installing the package. Useful for things
+ like legal notices on almost-free software, etc.
+
+ --dd _[_-_]_d_e_s_c
+ Fetch long description for package from file _d_e_s_c or, if preceded
+ by --, the argument itself.
+
+ --ff _p_a_c_k_i_n_g_l_i_s_t
+ Fetch ``packing list'' for package from the file _p_a_c_k_i_n_g_l_i_s_t or
+ ssttddiinn if _p_a_c_k_i_n_g_l_i_s_t is a -- (dash).
+
+ --hh Force tar to follow symbolic links, so that the files they point
+ to are dumped, rather than the links themselves.
+
+ --II _r_e_a_l_p_r_e_f_i_x
+ Provide the real prefix, as opposed to the staging prefix, for
+ use in staged installations of packages.
+
+ --ii _i_s_c_r_i_p_t
+ Set _i_s_c_r_i_p_t to be the install procedure for the package. This
+ can be any executable program (or shell script). It will be in-
+ voked automatically when the package is later installed.
+
+ --kk _d_s_c_r_i_p_t
+ Set _d_s_c_r_i_p_t to be the de-install procedure for the package. This
+ can be any executable program (or shell script). It will be in-
+ voked automatically when the package is later (if ever) de-in-
+ stalled.
+
+ --LL _S_r_c_D_i_r
+ This sets the package's @src directive; see below for a descrip-
+ tion of what this does.
+
+ --ll Check that any symbolic links which are to be placed in the pack-
+ age are relative to the current prefix. This means using
+ unlink(2) and symlink(2) to remove and re-link any symbolic links
+ which are targeted at full path names.
+
+ --mm _m_t_r_e_e_f_i_l_e
+ Run mtree(8) with input from mtreefile before the package is in-
+ stalled. Mtree is invoked as mmttrreeee --uu --ff _m_t_r_e_e_f_i_l_e --dd --ee --pp
+ _p_r_e_f_i_x, where _p_r_e_f_i_x is the name of the first directory named by
+ a @@ccwwdd directive.
+
+ --OO Go into a `packing list Only' mode. This is used to do `fake
+ pkg_add' operations when a package is installed. In such cases,
+ it is necessary to know what the final, adjusted packing list
+ will look like.
+
+ --PP _d_p_k_g_s
+ Set the initial package dependency list to _d_p_k_g_s. This is as-
+ sumed to be a whitespace separated list of package names and is
+ meant as a convenient shorthand for specifying multiple @@ppkkggddeepp
+ directives in the packing list (see PACKING LIST DETAILS section
+ below). In addition, the exact versions of the packages referred
+ to in the _d_p_k_g_s list will be added to the packing list in the
+ form of @@bbllddddeepp directives.
+
+ --pp _p_r_e_f_i_x
+ Set _p_r_e_f_i_x as the initial directory ``base'' to start from in se-
+ lecting files for the package.
+
+ --RR Re-order any directories in the pkg/PLIST file into reverse al-
+ phabetic order, so that child directories will automatically be
+ removed before parent directories.
+
+ --rr _r_s_c_r_i_p_t
+ Set _r_s_c_r_i_p_t to be the ``requirements'' procedure for the package.
+ This can be any executable program (or shell script). It will be
+ invoked automatically at installation/deinstallation time to de-
+ termine whether or not installation/deinstallation should pro-
+ ceed.
+
+ --SS _s_i_z_e_-_a_l_l_-_f_i_l_e
+ Store the given file for later querying with the pkg_info(1) _-_S
+ flag. The file is expected to contain the size (in bytes) of all
+ files of this package plus any required packages added up and
+ stored as a ASCII string, terminated by a newline.
+
+ --ss _s_i_z_e_-_p_k_g_-_f_i_l_e
+ Store the given file for later querying with the pkg_info(1) _-_s
+ flag. The file is expected to contain the the size (in bytes) of
+ all files of this package added up and stored as a ASCII string,
+ terminated by a newline.
+
+ --tt _t_e_m_p_l_a_t_e
+ Use _t_e_m_p_l_a_t_e as the input to mktemp(3). By default, this is the
+ string _/_t_m_p_/_i_n_s_t_m_p_._X_X_X_X_X_X, but it may be necessary to override it
+ in the situation where space in your _/_t_m_p directory is limited.
+ Be sure to leave some number of `X' characters for mktemp(3) to
+ fill in with a unique ID.
+
+ --UU Do not update the package file database with any file informa-
+ tion.
+
+ --VV Print version number and exit.
+
+ --vv Turn on verbose output.
+
+ --XX _e_x_c_l_u_d_e_f_i_l_e
+ Pass _e_x_c_l_u_d_e_f_i_l_e as a ----eexxcclluuddee--ffrroomm argument to ttaarr when creat-
+ ing final package. See ttaarr man page (or run ttaarr with ----hheellpp
+ flag) for further information on using this flag.
+
+PPAACCKKIINNGG LLIISSTT DDEETTAAIILLSS
+ The ``packing list'' format (see --ff) is fairly simple, being nothing more
+ than a single column of filenames to include in the package. However,
+ since absolute pathnames are generally a bad idea for a package that
+ could be installed potentially anywhere, there is another method of spec-
+ ifying where things are supposed to go and, optionally, what ownership
+ and mode information they should be installed with. This is done by em-
+ bedding specialized command sequences in the packing list. Briefly de-
+ scribed, these sequences are:
+ @@ccwwdd _d_i_r_e_c_t_o_r_y
+ Set the internal directory pointer to point to _d_i_r_e_c_t_o_r_y. All
+ subsequent filenames will be assumed relative to this directory.
+ Note: @@ccdd is also an alias for this command.
+ @@ssrrcc _d_i_r_e_c_t_o_r_y
+ Set the internal directory pointer for _creation only_ to
+ _d_i_r_e_c_t_o_r_y. That is to say that it overrides @@ccwwdd for package
+ creation but not extraction.
+ @@eexxeecc _c_o_m_m_a_n_d
+ Execute _c_o_m_m_a_n_d as part of the unpacking process. If _c_o_m_m_a_n_d
+ contains any of the following sequences somewhere in it, they
+ will be expanded inline. For the following examples, assume that
+ @@ccwwdd is set to _/_u_s_r_/_l_o_c_a_l and the last extracted file was
+ _b_i_n_/_e_m_a_c_s.
+ %%FF Expands to the last filename extracted (as specified), in
+ the example case _b_i_n_/_e_m_a_c_s
+ %%DD Expand to the current directory prefix, as set with @@ccwwdd,
+ in the example case _/_u_s_r_/_l_o_c_a_l.
+ %%BB Expand to the ``basename'' of the fully qualified file-
+ name, that is the current directory prefix, plus the last
+ filespec, minus the trailing filename. In the example
+ case, that would be _/_u_s_r_/_l_o_c_a_l_/_b_i_n.
+ %%ff Expand to the ``filename'' part of the fully qualified
+ name, or the converse of %%BB, being in the example case,
+ _e_m_a_c_s.
+ @@uunneexxeecc _c_o_m_m_a_n_d
+ Execute _c_o_m_m_a_n_d as part of the deinstallation process. Expansion
+ of special %% sequences is the same as for @@eexxeecc. This command is
+ not executed during the package add, as @@eexxeecc is, but rather when
+ the package is deleted. This is useful for deleting links and
+ other ancillary files that were created as a result of adding the
+ package, but not directly known to the package's table of con-
+ tents (and hence not automatically removable). The advantage of
+ using @@uunneexxeecc over a deinstallation script is that you can use
+ the ``special sequence expansion'' to get at files regardless of
+ where they've been potentially redirected (see --pp).
+ @@mmooddee _m_o_d_e
+ Set default permission for all subsequently extracted files to
+ _m_o_d_e. Format is the same as that used by the cchhmmoodd command
+ (well, considering that it's later handed off to it, that's no
+ surprise). Use without an arg to set back to default (extrac-
+ tion) permissions.
+ @@ooppttiioonn _o_p_t_i_o_n
+ Set internal package options, the only two currently supported
+ ones being _e_x_t_r_a_c_t_-_i_n_-_p_l_a_c_e, which tells the pkg_add command not
+ to extract the package's tarball into a staging area but rather
+ directly into the target hierarchy (this is typically meant to be
+ used only by distributions or other special package types), and
+ _p_r_e_s_e_r_v_e, which tells pkg_add to move any existing files out of
+ the way, preserving the previous contents (which are also resur-
+ rected on pkg_delete, so caveat emptor).
+ @@oowwnneerr _u_s_e_r
+ Set default ownership for all subsequently extracted files to
+ _u_s_e_r. Use without an arg to set back to default (extraction)
+ ownership.
+ @@ggrroouupp _g_r_o_u_p
+ Set default group ownership for all subsequently extracted files
+ to _g_r_o_u_p. Use without an arg to set back to default (extraction)
+ group ownership.
+ @@ccoommmmeenntt _s_t_r_i_n_g
+ Imbed a comment in the packing list. Useful in trying to docu-
+ ment some particularly hairy sequence that may trip someone up
+ later.
+ @@iiggnnoorree
+ Used internally to tell extraction to ignore the next file (don't
+ copy it anywhere), as it's used for some special purpose.
+ @@iiggnnoorree__iinnsstt
+ Similar to @@iiggnnoorree, but the ignoring of the next file is delayed
+ one evaluation cycle. This makes it possible to use this direc-
+ tive in the _p_a_c_k_i_n_g_l_i_s_t file, so you can pack a specialized
+ datafile in with a distribution for your install script (or some-
+ thing) yet have the installer ignore it.
+ @@nnaammee _n_a_m_e
+ Set the name of the package. This is mandatory and is usually
+ put at the top. This name is potentially different than the name
+ of the file it came in, and is used when keeping track of the
+ package for later deinstallation. Note that ppkkgg__ccrreeaattee will de-
+ rive this field from the package name and add it automatically if
+ none is given.
+ @@ddiirrrrmm _n_a_m_e
+ Declare directory _n_a_m_e to be deleted at deinstall time. By de-
+ fault, directories created by a package installation are not
+ deleted when the package is deinstalled; this provides an explic-
+ it directory cleanup method. This directive should appear at the
+ end of the package list. If more than one @@ddiirrrrmm directives are
+ used, the directories are removed in the order specified. The
+ _n_a_m_e directory will not be removed unless it is empty.
+ @@mmttrreeee _n_a_m_e
+ Declare _n_a_m_e as an mtree(8) input file to be used at install time
+ (see --mm above). Only the first @@mmttrreeee directive is honored.
+ @@ddiissppllaayy _n_a_m_e
+ Declare _n_a_m_e as the file to be displayed at install time (see --DD
+ above).
+ @@ppkkggddeepp _p_k_g_n_a_m_e
+ Declare a dependency on the _p_k_g_n_a_m_e package. The _p_k_g_n_a_m_e package
+ must be installed before this package may be installed, and this
+ package must be deinstalled before the _p_k_g_n_a_m_e package is dein-
+ stalled. Multiple @@ppkkggddeepp directives may be used if the package
+ depends on multiple other packages.
+ @@bbllddddeepp _p_k_g_n_a_m_e
+ Declare that this package was built with the exact version of
+ _p_k_g_n_a_m_e (since the @@ppkkggddeepp directive may contain wildcards or re-
+ lational package version information).
+ @@ppkkggccffll _p_k_g_c_f_l_n_a_m_e
+ Declare a conflict with the _p_k_g_c_f_l_n_a_m_e package, as the two pack-
+ ages contain references to the same files, and so cannot co-exist
+ on the same system.
+
+SSEEEE AALLSSOO
+ pkg_add(1), pkg_admin(1), pkg_delete(1), pkg_info(1), sysconf(3),
+ packages(7)
+
+HHIISSTTOORRYY
+ The ppkkgg__ccrreeaattee command first appeared in FreeBSD.
+
+AAUUTTHHOORRSS
+ Jordan Hubbard
+ most of the work
+ John Kohl
+ refined it for NetBSD
+ Hubert Feyrer
+ NetBSD wildcard dependency processing, pkgdb, pkg size recording
+ etc.
+
+BBUUGGSS
+ Hard links between files in a distribution must be bracketed by @@ccwwdd di-
+ rectives in order to be preserved as hard links when the package is ex-
+ tracted. They additionally must not end up being split between ttaarr invo-
+ cations due to exec argument-space limitations (this depends on the value
+ returned by ssyyssccoonnff(___S_C___A_R_G___M_A_X)).
+
+NetBSD 1.6 April 21, 1995 5
diff --git a/pkgtools/pkg_install/files/create/pl.c b/pkgtools/pkg_install/files/create/pl.c
new file mode 100644
index 00000000000..54b763d3337
--- /dev/null
+++ b/pkgtools/pkg_install/files/create/pl.c
@@ -0,0 +1,238 @@
+/* $NetBSD: pl.c,v 1.1.1.1 2002/12/20 18:14:11 schmonz Exp $ */
+
+#if 0
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static const char *rcsid = "from FreeBSD Id: pl.c,v 1.11 1997/10/08 07:46:35 charnier Exp";
+#else
+__RCSID("$NetBSD: pl.c,v 1.1.1.1 2002/12/20 18:14:11 schmonz Exp $");
+#endif
+#endif
+#endif
+
+/*
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 18 July 1993
+ *
+ * Routines for dealing with the packing list.
+ *
+ */
+
+#include "lib.h"
+#include "create.h"
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#ifdef HAVE_MD5GLOBAL_H
+#include <md5global.h>
+#endif
+
+#ifdef HAVE_MD5_H
+#include <md5.h>
+#endif
+
+/*
+ * Check that any symbolic link is relative to the prefix
+ */
+static void
+CheckSymlink(char *name, char *prefix, size_t prefixcc)
+{
+ char newtgt[MAXPATHLEN];
+ char oldtgt[MAXPATHLEN];
+ char *slash;
+ int slashc;
+ int cc;
+ int i;
+
+ if ((cc = readlink(name, oldtgt, sizeof(oldtgt) - 1)) > 0) {
+ oldtgt[cc] = 0;
+ if (strncmp(oldtgt, prefix, prefixcc) == 0 && oldtgt[prefixcc] == '/') {
+ for (slashc = 0, slash = &name[prefixcc + 1]; (slash = strchr(slash, '/')) != (char *) NULL; slash++, slashc++) {
+ }
+ for (cc = i = 0; i < slashc; i++) {
+ strnncpy(&newtgt[cc], sizeof(newtgt) - cc, "../", 3);
+ cc += 3;
+ }
+ strnncpy(&newtgt[cc], sizeof(newtgt) - cc, &oldtgt[prefixcc + 1], strlen(&oldtgt[prefixcc + 1]));
+ (void) fprintf(stderr, "Full pathname symlink `%s' is target of `%s' - adjusting to `%s'\n", oldtgt, name, newtgt);
+ if (unlink(name) != 0) {
+ warn("can't unlink `%s'", name);
+ } else if (symlink(newtgt, name) != 0) {
+ warn("can't symlink `%s' called `%s'", newtgt, name);
+ }
+ }
+ }
+}
+
+/*
+ * (Reversed) comparison routine for directory name sorting
+ */
+static int
+dircmp(const void *vp1, const void *vp2)
+{
+ return strcmp((const char *) vp2, (const char *) vp1);
+}
+
+/*
+ * Re-order the PLIST_DIR_RM entries into reverse alphabetic order
+ */
+static void
+reorder(package_t *pkg, int dirc)
+{
+ plist_t *p;
+ char **dirv;
+ int i;
+
+ if ((dirv = (char **) calloc(dirc, sizeof(char *))) == (char **) NULL) {
+ warn("No directory re-ordering will be done");
+ } else {
+ for (p = pkg->head, i = 0; p; p = p->next) {
+ if (p->type == PLIST_DIR_RM) {
+ dirv[i++] = p->name;
+ }
+ }
+ qsort(dirv, dirc, sizeof(char *), dircmp);
+ for (p = pkg->head, i = 0; p; p = p->next) {
+ if (p->type == PLIST_DIR_RM) {
+ p->name = dirv[i++];
+ }
+ }
+ (void) free(dirv);
+ }
+}
+
+/*
+ * Check a list for files that require preconversion
+ */
+void
+check_list(char *home, package_t *pkg, const char *PkgName)
+{
+ struct stat st;
+ plist_t *tmp;
+ plist_t *p;
+ char name[FILENAME_MAX];
+ char buf[ChecksumHeaderLen + LegibleChecksumLen];
+ char *cwd = home;
+ char *srcdir = NULL;
+ int dirc;
+
+ /* Open Package Database for writing */
+ if (update_pkgdb && pkgdb_open(0) == -1) {
+ cleanup(0);
+ err(1, "can't open pkgdb");
+ }
+
+ for (dirc = 0, p = pkg->head; p; p = p->next) {
+ switch (p->type) {
+ case PLIST_CWD:
+ cwd = p->name;
+ break;
+ case PLIST_IGNORE:
+ p = p->next;
+ break;
+ case PLIST_SRC:
+ srcdir = p->name;
+ break;
+ case PLIST_DIR_RM:
+ dirc++;
+ break;
+ case PLIST_FILE:
+ /*
+ * pkgdb handling - usually, we enter files
+ * into the pkgdb as soon as they hit the disk,
+ * but as they are present before pkg_create
+ * starts, it's ok to do this somewhere here
+ */
+ if (update_pkgdb) {
+ char *s, t[FILENAME_MAX];
+
+ (void) snprintf(t, sizeof(t), "%s/%s", cwd, p->name);
+
+ s = pkgdb_retrieve(t);
+#ifdef PKGDB_DEBUG
+ fprintf(stderr, "pkgdb_retrieve(\"%s\")=\"%s\"\n", t, s); /* pkgdb-debug - HF */
+#endif
+ if (s && PlistOnly)
+ warnx("Overwriting %s - "
+ "pkg %s bogus/conflicting?", t, s);
+ else {
+ pkgdb_store(t, PkgName);
+#ifdef PKGDB_DEBUG
+ fprintf(stderr, "pkgdb_store(\"%s\", \"%s\")\n", t, PkgName); /* pkgdb-debug - HF */
+#endif
+ }
+ }
+
+ if (cwd == home) {
+ /* no @cwd yet */
+ (void) snprintf(name, sizeof(name), "%s/%s", srcdir ? srcdir : cwd, p->name);
+ } else {
+ /* after @cwd */
+ /* prepend DESTDIR if set? - HF */
+ (void) snprintf(name, sizeof(name), "%s/%s", cwd, p->name);
+ }
+ if (lstat(name, &st) < 0) {
+ warnx("can't stat `%s'", name);
+ continue;
+ }
+ switch (st.st_mode & S_IFMT) {
+ case S_IFDIR:
+ p->type = PLIST_DIR_RM;
+ dirc++;
+ continue;
+ case S_IFLNK:
+ if (RelativeLinks) {
+ CheckSymlink(name, cwd, strlen(cwd));
+ }
+ break;
+ case S_IFCHR:
+ warnx("Warning - char special device `%s' in PLIST", name);
+ break;
+ case S_IFBLK:
+ warnx("Warning - block special device `%s' in PLIST", name);
+ break;
+ default:
+ (void) strcpy(buf, CHECKSUM_HEADER);
+ if (MD5File(name, &buf[ChecksumHeaderLen]) != (char *) NULL) {
+ tmp = new_plist_entry();
+ tmp->name = strdup(buf);
+ tmp->type = PLIST_COMMENT; /* PLIST_MD5 - HF */
+ tmp->next = p->next;
+ tmp->prev = p;
+ if (p == pkg->tail) {
+ pkg->tail = tmp;
+ }
+ p->next = tmp;
+ p = tmp;
+ }
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (update_pkgdb) {
+ pkgdb_close();
+ }
+
+ if (ReorderDirs && dirc > 0) {
+ reorder(pkg, dirc);
+ }
+}
diff --git a/pkgtools/pkg_install/files/delete/Makefile.in b/pkgtools/pkg_install/files/delete/Makefile.in
new file mode 100644
index 00000000000..37acb9ac73d
--- /dev/null
+++ b/pkgtools/pkg_install/files/delete/Makefile.in
@@ -0,0 +1,40 @@
+# From NetBSD: Makefile,v 1.4 1997/10/17 14:53:59 lukem Exp $
+# Original from FreeBSD, no rcs id.
+
+PREFIX= @prefix@
+INSTALL= @INSTALL@
+
+mandir= ${PREFIX}/man
+mandircat1= ${mandir}/cat1
+
+CC= @CC@
+CCLD= $(CC)
+LIBS= @LIBS@ -linstall
+CPPFLAGS= @CPPFLAGS@
+DEFS= @DEFS@ -I. -I@srcdir@ -I../lib
+CFLAGS= @CFLAGS@
+LDFLAGS= @LDFLAGS@ -L../lib
+
+LINK= $(CCLD) $(CFLAGS) $(LDFLAGS) -o $@
+COMPILE= $(CC) $(DEFS) $(CPPFLAGS) $(CFLAGS)
+
+PROG= pkg_delete
+
+SRCS= main.c perform.c
+OBJS= main.o perform.o
+
+all: ${PROG}
+
+${PROG}: ${OBJS}
+ ${LINK} ${OBJS} ${LIBS}
+
+.c.o:
+ $(COMPILE) -c $< -o $@
+
+clean:
+ rm -f ${OBJS} ${PROG}
+
+install:
+ ${INSTALL} ${PROG} ${PREFIX}/sbin
+ ${INSTALL} -m 755 -d ${mandircat1}
+ ${INSTALL} -m 444 ${PROG}.cat1 ${mandircat1}/${PROG}.1
diff --git a/pkgtools/pkg_install/files/delete/delete.h b/pkgtools/pkg_install/files/delete/delete.h
new file mode 100644
index 00000000000..62823872942
--- /dev/null
+++ b/pkgtools/pkg_install/files/delete/delete.h
@@ -0,0 +1,37 @@
+/* $NetBSD: delete.h,v 1.1.1.1 2002/12/20 18:14:07 schmonz Exp $ */
+
+/* from FreeBSD Id: delete.h,v 1.4 1997/02/22 16:09:35 peter Exp */
+
+/*
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 18 July 1993
+ *
+ * Include and define various things wanted by the delete command.
+ *
+ */
+
+#ifndef _INST_DELETE_H_INCLUDE
+#define _INST_DELETE_H_INCLUDE
+
+extern char *Prefix;
+extern char *ProgramPath;
+extern Boolean NoDeInstall;
+extern Boolean CleanDirs;
+extern Boolean Force;
+extern Boolean Recurse_up;
+extern Boolean Recurse_down;
+extern lpkg_head_t pkgs;
+
+#endif /* _INST_DELETE_H_INCLUDE */
diff --git a/pkgtools/pkg_install/files/delete/main.c b/pkgtools/pkg_install/files/delete/main.c
new file mode 100644
index 00000000000..32dacc7e3e4
--- /dev/null
+++ b/pkgtools/pkg_install/files/delete/main.c
@@ -0,0 +1,225 @@
+/* $NetBSD: main.c,v 1.1.1.1 2002/12/20 18:14:09 schmonz Exp $ */
+
+#if 0
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char *rcsid = "from FreeBSD Id: main.c,v 1.11 1997/10/08 07:46:48 charnier Exp";
+#else
+__RCSID("$NetBSD: main.c,v 1.1.1.1 2002/12/20 18:14:09 schmonz Exp $");
+#endif
+#endif
+#endif
+
+/*
+ *
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 18 July 1993
+ *
+ * This is the delete module.
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#include <errno.h>
+#include "lib.h"
+#include "delete.h"
+
+static char Options[] = "hVvDdnfFp:OrR";
+
+char *Prefix = NULL;
+char *ProgramPath = NULL;
+Boolean NoDeInstall = FALSE;
+Boolean CleanDirs = FALSE;
+Boolean File2Pkg = FALSE;
+Boolean Recurse_up = FALSE;
+Boolean Recurse_down = FALSE;
+Boolean OnlyDeleteFromPkgDB = FALSE;
+lpkg_head_t pkgs;
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: pkg_delete [-vVDdnFfOrR] [-p prefix] pkg-name ...\n");
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ int ch, error;
+ lpkg_t *lpp;
+
+ setprogname(argv[0]);
+
+ ProgramPath = argv[0];
+
+ while ((ch = getopt(argc, argv, Options)) != -1)
+ switch (ch) {
+ case 'v':
+ Verbose = TRUE;
+ break;
+
+ case 'f':
+ Force = TRUE;
+ break;
+
+ case 'F':
+ File2Pkg = TRUE;
+ break;
+
+ case 'p':
+ Prefix = optarg;
+ break;
+
+ case 'D':
+ NoDeInstall = TRUE;
+ break;
+
+ case 'd':
+ CleanDirs = TRUE;
+ break;
+
+ case 'n':
+ Fake = TRUE;
+ Verbose = TRUE;
+ break;
+
+ case 'r':
+ Recurse_up = TRUE;
+ break;
+
+ case 'R':
+ Recurse_down = TRUE;
+ break;
+
+ case 'O':
+ OnlyDeleteFromPkgDB = TRUE;
+ break;
+
+ case 'V':
+ show_version();
+ /* NOTREACHED */
+
+ case 'h':
+ case '?':
+ default:
+ usage();
+ break;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ TAILQ_INIT(&pkgs);
+
+ /* Get all the remaining package names, if any */
+ if (File2Pkg)
+ if (pkgdb_open(1) == -1) {
+ err(1, "cannot open pkgdb");
+ }
+ /* Get all the remaining package names, if any */
+ while (*argv) {
+ /* pkgdb: if -F flag given, don't add pkgnames to pkgs but
+ * rather resolve the given filenames to pkgnames using
+ * pkgdb_retrieve, then add these. */
+ if (File2Pkg) {
+ char *s;
+
+ s = pkgdb_retrieve(*argv);
+
+ if (s) {
+ lpp = alloc_lpkg(s);
+ TAILQ_INSERT_TAIL(&pkgs, lpp, lp_link);
+ } else
+ errx(1, "No matching pkg for %s in pkgdb.", *argv);
+ } else {
+ if (ispkgpattern(*argv)) {
+ int rc;
+ rc = findmatchingname(_pkgdb_getPKGDB_DIR(), *argv, add_to_list_fn, &pkgs);
+ if (rc == 0)
+ errx(1, "No matching pkg for %s.", *argv);
+ else if (rc == -1)
+ errx(1, "error expanding '%s' ('%s' nonexistant?)", *argv, _pkgdb_getPKGDB_DIR());
+ } else {
+ lpp = alloc_lpkg(*argv);
+ TAILQ_INSERT_TAIL(&pkgs, lpp, lp_link);
+ }
+ }
+ argv++;
+ }
+
+ if (File2Pkg)
+ pkgdb_close();
+
+ /* If no packages, yelp */
+ if (TAILQ_FIRST(&pkgs) == NULL)
+ warnx("missing package name(s)"), usage();
+ if (!Fake && getuid() != 0)
+ errx(1, "you must be root to delete packages");
+ if (OnlyDeleteFromPkgDB) {
+ /* Only delete the given packages' files from pkgdb, do not
+ * touch the pkg itself. Used by "make reinstall" in
+ * bsd.pkg.mk */
+ char *key, *val;
+
+ if (pkgdb_open(0) == -1) {
+ err(1, "cannot open %s", _pkgdb_getPKGDB_FILE());
+ }
+
+ error = 0;
+ while ((key = pkgdb_iter())) {
+ val = pkgdb_retrieve(key);
+ if (val == NULL || *val == '\0')
+ continue;
+
+ lpp = TAILQ_FIRST(&pkgs);
+ if (lpp != NULL) {
+ do {
+ if (strcmp(val, lpp->lp_name) == 0) {
+ if (Verbose)
+ printf("Removing file %s from pkgdb\n", key);
+
+ errno = 0;
+ if (pkgdb_remove(key)) {
+ if (errno)
+ printf("Error removing %s from pkgdb: %s\n", key, strerror(errno));
+ else
+ printf("Key %s not present in pkgdb?!\n", key);
+ error = 1;
+ }
+ }
+
+ lpp = TAILQ_NEXT(lpp, lp_link);
+ } while (lpp != NULL);
+ }
+ }
+ pkgdb_close();
+
+ return error;
+
+ } else if ((error = pkg_perform(&pkgs)) != 0) {
+ if (Verbose)
+ warnx("%d package deletion(s) failed", error);
+ return error;
+ } else
+ return 0;
+}
diff --git a/pkgtools/pkg_install/files/delete/perform.c b/pkgtools/pkg_install/files/delete/perform.c
new file mode 100644
index 00000000000..cb7bfa04d70
--- /dev/null
+++ b/pkgtools/pkg_install/files/delete/perform.c
@@ -0,0 +1,697 @@
+/* $NetBSD: perform.c,v 1.1.1.1 2002/12/20 18:14:08 schmonz Exp $ */
+
+#if 0
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static const char *rcsid = "from FreeBSD Id: perform.c,v 1.15 1997/10/13 15:03:52 jkh Exp";
+#else
+__RCSID("$NetBSD: perform.c,v 1.1.1.1 2002/12/20 18:14:08 schmonz Exp $");
+#endif
+#endif
+#endif
+
+/*
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 18 July 1993
+ *
+ * This is the main body of the delete module.
+ *
+ */
+/*
+ * Copyright (c) 1999 Christian E. Hopps
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Added the require find and require delete code
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include "lib.h"
+#include "delete.h"
+
+
+/* In which direction to search in require_find() */
+typedef enum {
+ FIND_UP, FIND_DOWN
+} rec_find_t;
+
+static int require_find_recursive_up(lpkg_t *);
+static int require_find_recursive_down(lpkg_t *, package_t *);
+static int require_find(char *, rec_find_t);
+static int require_delete(char *, int);
+static void require_print(void);
+static int undepend(const char *, void *);
+
+static char LogDir[FILENAME_MAX];
+static char linebuf[FILENAME_MAX];
+static char pkgdir[FILENAME_MAX];
+
+static package_t Plist;
+
+static lpkg_head_t lpfindq;
+static lpkg_head_t lpdelq;
+
+static void
+sanity_check(char *pkg)
+{
+ if (!fexists(CONTENTS_FNAME)) {
+ cleanup(0);
+ errx(2, "installed package %s has no %s file!",
+ pkg, CONTENTS_FNAME);
+ }
+}
+
+void
+cleanup(int sig)
+{
+ /* Nothing to do */
+ if (sig) /* in case this is ever used as a signal handler */
+ exit(1);
+}
+
+/*
+ * deppkgname is the pkg from which's +REQUIRED_BY file we are
+ * about to remove pkg2delname. This function is called from
+ * findmatchingname(), deppkgname is expanded from a (possible) pattern.
+ */
+static int
+undepend(const char *deppkgname, void *vp)
+{
+ char *pkg2delname = vp;
+ char fname[FILENAME_MAX], ftmp[FILENAME_MAX];
+ char fbuf[FILENAME_MAX];
+ FILE *fp, *fpwr;
+ char *tmp;
+ int s;
+
+ (void) snprintf(fname, sizeof(fname), "%s/%s/%s",
+ (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR,
+ deppkgname, REQUIRED_BY_FNAME);
+ fp = fopen(fname, "r");
+ if (fp == NULL) {
+ warnx("couldn't open dependency file `%s'", fname);
+ return 0;
+ }
+ (void) snprintf(ftmp, sizeof(ftmp), "%s.XXXXXX", fname);
+ s = mkstemp(ftmp);
+ if (s == -1) {
+ fclose(fp);
+ warnx("couldn't open temp file `%s'", ftmp);
+ return 0;
+ }
+ fpwr = fdopen(s, "w");
+ if (fpwr == NULL) {
+ close(s);
+ fclose(fp);
+ warnx("couldn't fdopen temp file `%s'", ftmp);
+ remove(ftmp);
+ return 0;
+ }
+ while (fgets(fbuf, sizeof(fbuf), fp) != NULL) {
+ if (fbuf[strlen(fbuf) - 1] == '\n')
+ fbuf[strlen(fbuf) - 1] = '\0';
+ if (strcmp(fbuf, pkg2delname)) /* 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 0;
+ }
+ if (fclose(fpwr) == EOF) {
+ warnx("error closing temp file `%s'", ftmp);
+ remove(ftmp);
+ return 0;
+ }
+ if (rename(ftmp, fname) == -1)
+ warnx("error renaming `%s' to `%s'", ftmp, fname);
+ remove(ftmp); /* just in case */
+
+ return 0;
+}
+
+/*
+ * Delete from directory 'home' all packages on lpkg_list.
+ * If tryall is set, ignore errors from pkg_delete(1).
+ */
+int
+require_delete(char *home, int tryall)
+{
+ lpkg_t *lpp;
+ int rv, fail;
+ char *tmp;
+ int oldcwd;
+
+ /* save cwd */
+ oldcwd = open(".", O_RDONLY, 0);
+ if (oldcwd == -1)
+ err(1, "cannot open \".\"");
+
+ (void) snprintf(pkgdir, sizeof(pkgdir), "%s",
+ (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR);
+
+ /* walk list of things to delete */
+ fail = 0;
+ lpp = TAILQ_FIRST(&lpdelq);
+ for (; lpp; lpp = TAILQ_NEXT(lpp, lp_link)) {
+ int rm_installed; /* delete expanded pkg, not @pkgdep value */
+ char installed[FILENAME_MAX];
+
+ /* go to the db dir */
+ if (chdir(pkgdir) == FAIL) {
+ warnx("unable to change directory to %s, deinstall failed (1)",
+ pkgdir);
+ fail = 1;
+ break;
+ }
+
+ /* look to see if package was already deleted */
+ rm_installed = 0;
+ if (ispkgpattern(lpp->lp_name)) {
+ if (findmatchingname(".", lpp->lp_name, note_whats_installed, installed) != 1) {
+ warnx("%s appears to have been deleted", lpp->lp_name);
+ continue;
+ }
+ rm_installed = 1;
+ } else {
+ if (!fexists(lpp->lp_name)) {
+ warnx("%s appears to have been deleted", lpp->lp_name);
+ continue;
+ }
+ }
+
+ /* return home for execution of command */
+ if (chdir(home) == FAIL) {
+ warnx("unable to change directory to %s, deinstall failed (2)", home);
+ fail = 1;
+ break;
+ }
+
+ if (Verbose)
+ printf("deinstalling %s\n", rm_installed?installed:lpp->lp_name);
+
+ /* delete the package */
+ if (Fake)
+ rv = 0;
+ else
+ rv = vsystem("%s %s %s %s %s %s %s %s %s", ProgramPath,
+ Prefix ? "-p" : "",
+ Prefix ? Prefix : "",
+ Verbose ? "-v" : "",
+ Force ? "-f" : "",
+ NoDeInstall ? "-D" : "",
+ CleanDirs ? "-d" : "",
+ Fake ? "-n" : "",
+ rm_installed?installed:lpp->lp_name);
+
+ /* check for delete failure */
+ if (rv && !tryall) {
+ fail = 1;
+ warnx("had problem removing %s%s", rm_installed?installed:lpp->lp_name,
+ Force ? ", continuing" : "");
+ if (!Force)
+ break;
+ }
+ }
+
+ /* cleanup list */
+ while ((lpp = TAILQ_FIRST(&lpdelq))) {
+ TAILQ_REMOVE(&lpdelq, lpp, lp_link);
+ free_lpkg(lpp);
+ }
+
+ /* return to the log dir */
+ if (fchdir(oldcwd) == FAIL) {
+ warnx("unable to change to previous directory, deinstall failed");
+ fail = 1;
+ }
+ close(oldcwd);
+
+ return (fail);
+}
+
+/*
+ * Recursively find all packages "up" the tree (follow +REQUIRED_BY).
+ * Return 1 on errors
+ */
+int
+require_find_recursive_up(lpkg_t *thislpp)
+{
+ lpkg_head_t reqq;
+ lpkg_t *lpp = NULL;
+ FILE *cfile;
+ char *nl, *tmp;
+
+ /* see if we are on the find queue -- circular dependency */
+ if ((lpp = find_on_queue(&lpfindq, thislpp->lp_name))) {
+ warnx("circular dependency found for pkg %s", lpp->lp_name);
+ return (1);
+ }
+
+ TAILQ_INIT(&reqq);
+
+ (void) snprintf(pkgdir, sizeof(pkgdir), "%s/%s",
+ (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, thislpp->lp_name);
+
+ /* change to package's dir */
+ if (chdir(pkgdir) == FAIL) {
+ warnx("unable to change directory to %s! deinstall failed", pkgdir);
+ return (1);
+ }
+
+ /* terminate recursion if no required by's */
+ if (isemptyfile(REQUIRED_BY_FNAME))
+ return (0);
+
+ /* get packages that directly require us */
+ cfile = fopen(REQUIRED_BY_FNAME, "r");
+ if (!cfile) {
+ warnx("cannot open requirements file `%s'", REQUIRED_BY_FNAME);
+ return (1);
+ }
+ while (fgets(linebuf, sizeof(linebuf), cfile)) {
+ if ((nl = strrchr(linebuf, '\n')))
+ *nl = 0;
+ lpp = alloc_lpkg(linebuf);
+ TAILQ_INSERT_TAIL(&reqq, lpp, lp_link);
+ }
+ fclose(cfile);
+
+ /* put ourselves on the top of the find queue */
+ TAILQ_INSERT_HEAD(&lpfindq, thislpp, lp_link);
+
+ while ((lpp = TAILQ_FIRST(&reqq))) {
+ /* remove a direct req from our queue */
+ TAILQ_REMOVE(&reqq, lpp, lp_link);
+
+ /* find direct required requires */
+ if (require_find_recursive_up(lpp))
+ goto fail;
+
+ /* all requires taken care of, add to tail of delete queue
+ * if not already there */
+ if (find_on_queue(&lpdelq, lpp->lp_name))
+ free_lpkg(lpp);
+ else
+ TAILQ_INSERT_TAIL(&lpdelq, lpp, lp_link);
+ }
+
+ /* take ourselves off the find queue */
+ TAILQ_REMOVE(&lpfindq, thislpp, lp_link);
+
+ return (0);
+
+fail:
+ while ((lpp = TAILQ_FIRST(&reqq))) {
+ TAILQ_REMOVE(&reqq, lpp, lp_link);
+ free_lpkg(lpp);
+ }
+ return (1);
+}
+
+/*
+ * Recursively find all packages "down" the tree (follow @pkgdep).
+ * Return 1 on errors
+ */
+int
+require_find_recursive_down(lpkg_t *thislpp, package_t *plist)
+{
+ plist_t *p;
+ lpkg_t *lpp, *lpp2;
+ lpkg_head_t reqq;
+ int rc, fail = 0;
+
+ /* see if we are on the find queue -- circular dependency */
+ if ((lpp = find_on_queue(&lpfindq, thislpp->lp_name))) {
+ warnx("circular dependency found for pkg %s", lpp->lp_name);
+ return (1);
+ }
+
+ TAILQ_INIT(&reqq);
+
+ /* width-first scan */
+ /* first enqueue all @pkgdep's to lpdelq, then (further below)
+ * go in recursively */
+ for (p = plist->head; p; p = p->next) {
+ switch (p->type) {
+ case PLIST_PKGDEP:
+ lpp = alloc_lpkg(p->name);
+ TAILQ_INSERT_TAIL(&reqq, lpp, lp_link);
+
+ lpp2 = find_on_queue(&lpdelq, p->name);
+ if (lpp2) {
+ TAILQ_REMOVE(&lpdelq, lpp2, lp_link);
+ free_lpkg(lpp2);
+ }
+ lpp = alloc_lpkg(p->name);
+ TAILQ_INSERT_TAIL(&lpdelq, lpp, lp_link);
+
+ break;
+ default:
+ break;
+ }
+ }
+
+ while ((lpp = TAILQ_FIRST(&reqq))) {
+ FILE *cfile;
+ package_t rPlist;
+ char *tmp;
+
+ /* remove a direct req from our queue */
+ TAILQ_REMOVE(&reqq, lpp, lp_link);
+
+ /* Reset some state */
+ rPlist.head = NULL;
+ rPlist.tail = NULL;
+
+ /* prepare for recursion */
+ chdir ((tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR);
+ if (ispkgpattern(lpp->lp_name)) {
+ char installed[FILENAME_MAX];
+ if (findmatchingname(".", lpp->lp_name, note_whats_installed, installed) != 1) {
+ warnx("cannot remove dependency for pkg-pattern %s", lpp->lp_name);
+ fail = 1;
+ goto fail;
+ }
+ if (chdir(installed) == -1) {
+ warnx("can't chdir to %s", installed);
+ fail = 1;
+ goto fail;
+ }
+ sanity_check(installed);
+ } else {
+ if (chdir(lpp->lp_name) == -1) {
+ warnx("cannot remove dependency from %s", lpp->lp_name);
+ fail = 1;
+ goto fail;
+ }
+ sanity_check(lpp->lp_name);
+ }
+
+ cfile = fopen(CONTENTS_FNAME, "r");
+ if (!cfile) {
+ warn("unable to open '%s' file", CONTENTS_FNAME);
+ fail = 1;
+ goto fail;
+ }
+ /* If we have a prefix, add it now */
+ if (Prefix)
+ add_plist(&rPlist, PLIST_CWD, Prefix);
+ read_plist(&rPlist, cfile);
+ fclose(cfile);
+ p = find_plist(&rPlist, PLIST_CWD);
+ if (!p) {
+ warnx("package '%s' doesn't have a prefix", lpp->lp_name);
+ free_plist(&rPlist);
+ fail = 1;
+ goto fail;
+ }
+
+ /* put ourselves on the top of the find queue */
+ TAILQ_INSERT_HEAD(&lpfindq, thislpp, lp_link);
+
+ rc = require_find_recursive_down(lpp, &rPlist);
+ free_plist(&rPlist);
+ if (rc) {
+ fail = 1;
+ goto fail;
+ }
+
+ /* take ourselves off the find queue */
+ TAILQ_REMOVE(&lpfindq, thislpp, lp_link);
+ free_lpkg(lpp);
+ }
+
+fail:
+ /* Clean out reqq */
+ while ((lpp = TAILQ_FIRST(&reqq))) {
+ TAILQ_REMOVE(&reqq, lpp, lp_link);
+ free_lpkg(lpp);
+ }
+
+ return fail;
+}
+
+/*
+ * Start recursion in the one or other direction.
+ */
+int
+require_find(char *pkg, rec_find_t updown)
+{
+ lpkg_t *lpp;
+ int rv = 0;
+
+ TAILQ_INIT(&lpfindq);
+ TAILQ_INIT(&lpdelq);
+
+ lpp = alloc_lpkg(pkg);
+ switch (updown) {
+ case FIND_UP:
+ rv = require_find_recursive_up(lpp);
+ break;
+ case FIND_DOWN:
+ rv = require_find_recursive_down(lpp, &Plist);
+ break;
+ }
+ free_lpkg(lpp);
+
+ return (rv);
+}
+
+void
+require_print(void)
+{
+ lpkg_t *lpp;
+
+ /* print all but last -- deleting if requested */
+ while ((lpp = TAILQ_FIRST(&lpdelq))) {
+ TAILQ_REMOVE(&lpdelq, lpp, lp_link);
+ fprintf(stderr, "\t%s\n", lpp->lp_name);
+ free_lpkg(lpp);
+ }
+}
+
+/*
+ * This is seriously ugly code following. Written very fast!
+ */
+static int
+pkg_do(char *pkg)
+{
+ FILE *cfile;
+ char home[FILENAME_MAX];
+ plist_t *p;
+ char *tmp;
+
+ /* Reset some state */
+ if (Plist.head)
+ free_plist(&Plist);
+
+ (void) snprintf(LogDir, sizeof(LogDir), "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR,
+ pkg);
+ if (!fexists(LogDir) || !isdir(LogDir)) {
+ {
+ /* Check if the given package name matches something
+ * with 'pkg-[0-9]*' */
+ char try[FILENAME_MAX];
+ snprintf(try, FILENAME_MAX, "%s-[0-9]*", pkg);
+ if (findmatchingname(_pkgdb_getPKGDB_DIR(), try,
+ add_to_list_fn, &pkgs) != 0) {
+ return 0; /* we've just appended some names to the pkgs list,
+ * they will be processed after this package. */
+ }
+ }
+
+ /* No match */
+ warnx("package '%s' not 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)) {
+ /* This package is required by others. Either nuke
+ * them (-r), or stop. */
+ if (!Recurse_up)
+ warnx("package `%s' is required by other packages:", pkg);
+ else if (Verbose)
+ printf("Building list of packages that require `%s'"
+ " to deinstall\n", pkg);
+ if (require_find(pkg, FIND_UP)) {
+ if (!Force || Recurse_up)
+ return (1);
+ }
+ chdir(LogDir); /* CWD was changed by require_find() */
+ if (!Recurse_up) {
+ require_print();
+ if (!Force)
+ return 1;
+ } else
+ require_delete(home, 0);
+ }
+ 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");
+ vsystem("%s +x %s", CHMOD_CMD, REQUIRE_FNAME); /* be sure */
+ if (vsystem("./%s %s DEINSTALL", REQUIRE_FNAME, pkg)) {
+ warnx("package %s fails requirements %s", pkg,
+ Force ? "" : "- not deleted");
+ if (!Force)
+ return 1;
+ }
+ }
+ if (!NoDeInstall && fexists(DEINSTALL_FNAME)) {
+ if (Fake)
+ printf("Would execute de-install script at this point (arg: DEINSTALL).\n");
+ else {
+ vsystem("%s +x %s", CHMOD_CMD, DEINSTALL_FNAME); /* make sure */
+ if (vsystem("./%s %s DEINSTALL", DEINSTALL_FNAME, pkg)) {
+ warnx("deinstall script returned error status");
+ if (!Force)
+ return 1;
+ }
+ }
+ }
+ 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 `%s'\n"
+ "(perhaps the packing list is incorrectly specified?)", pkg);
+ }
+ /* Remove this package from the +REQUIRED_BY list of the packages this depends on */
+ 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)
+ findmatchingname((tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR,
+ p->name, undepend, pkg);
+ }
+ if (Recurse_down) {
+ /* Also remove the packages further down, now that there's
+ * (most likely) nothing left which requires them. */
+ if (Verbose)
+ printf("Building list of packages that `%s' required\n", pkg);
+ if (require_find(pkg, FIND_DOWN))
+ return (1);
+
+ require_delete(home, 1);
+ }
+ if (!NoDeInstall && fexists(DEINSTALL_FNAME)) {
+ if (Fake)
+ printf("Would execute post-de-install script at this point (arg: POST-DEINSTALL).\n");
+ else {
+ vsystem("chmod +x %s", DEINSTALL_FNAME); /* make sure */
+ if (vsystem("./%s %s POST-DEINSTALL", DEINSTALL_FNAME, pkg)) {
+ warnx("post-deinstall script returned error status");
+ if (!Force)
+ return 1;
+ }
+ }
+ }
+ /* Change out of LogDir before we remove it.
+ * Do not fail here, as the package is not yet completely deleted! */
+ if (chdir(home) == FAIL)
+ warnx("Oops - removed current working directory. Oh, well.");
+ if (!Fake) {
+ /* Finally nuke the +-files and the pkgdb-dir (/var/db/pkg/foo) */
+ if (vsystem("%s -r %s", RM, LogDir)) {
+ warnx("couldn't remove log entry in %s, deinstall failed", LogDir);
+ if (!Force)
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int
+pkg_perform(lpkg_head_t *pkghead)
+{
+ int err_cnt = 0;
+ int oldcwd;
+ lpkg_t *lpp;
+
+ /* save cwd */
+ oldcwd = open(".", O_RDONLY, 0);
+ if (oldcwd == -1)
+ err(1, "cannot open \".\"");
+
+ while ((lpp = TAILQ_FIRST(pkghead))) {
+ err_cnt += pkg_do(lpp->lp_name);
+ TAILQ_REMOVE(pkghead, lpp, lp_link);
+ free_lpkg(lpp);
+ if (fchdir(oldcwd) == FAIL)
+ err(1, "unable to change to previous directory");
+ }
+ close(oldcwd);
+ return err_cnt;
+}
diff --git a/pkgtools/pkg_install/files/delete/pkg_delete.1 b/pkgtools/pkg_install/files/delete/pkg_delete.1
new file mode 100644
index 00000000000..39569ff3c7d
--- /dev/null
+++ b/pkgtools/pkg_install/files/delete/pkg_delete.1
@@ -0,0 +1,241 @@
+.\" $NetBSD: pkg_delete.1,v 1.1.1.1 2002/12/20 18:14:08 schmonz Exp $
+.\"
+.\" FreeBSD install - a package for the installation and maintainance
+.\" of non-core utilities.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" Jordan K. Hubbard
+.\"
+.\"
+.\" from FreeBSD: @(#)pkg_delete.1
+.\"
+.Dd March 8, 1999
+.Dt PKG_DELETE 1
+.Os
+.Sh NAME
+.Nm pkg_delete
+.Nd a utility for deleting previously installed software package distributions
+.Sh SYNOPSIS
+.Nm
+.Op Fl DdFfnORrVv
+.Bk -words
+.Op Fl p Ar prefix
+.Ek
+.Ar pkg-name ...
+.Sh DESCRIPTION
+The
+.Nm
+command is used to delete packages that have been previously installed
+with the
+.Xr pkg_add 1
+command.
+.Sh WARNING
+.Bf -emphasis
+Since the
+.Nm
+command may execute scripts or programs provided by a package file,
+your system may be susceptible to ``Trojan horses'' or other subtle
+attacks from miscreants who create dangerous package files.
+.Pp
+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/\*[Lt]pkg-name\*[Gt]/ ) .
+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),
+.Cm @dirrm ,
+.Cm @exec ,
+and
+.Cm @unexec
+directives, and/or use the
+.Xr pkg_info 1
+command to examine the installed package control files.
+.Ef
+.Sh OPTIONS
+The following command line options are supported:
+.Bl -tag -width indent
+.It Ar pkg-name ...
+The named packages are deinstalled, wildcards can be used, see
+.Xr pkg_info 1 .
+If no version is given, the one currently installed
+will be removed.
+If the
+.Fl F
+flag is given, one or more (absolute) filenames may be specified and
+the Package Database will be consulted for the package to which the
+given file belongs.
+These packages are then deinstalled.
+.It Fl D
+If a deinstallation script exists for a given package, do not execute it.
+.It Fl d
+Remove empty directories created by file cleanup.
+By default, only files/directories explicitly listed in a package's
+contents (either as normal files/directories or with the
+.Cm @dirrm
+directive) will be removed at deinstallation time.
+This option tells
+.Nm
+to also remove any directories that were emptied as a result of removing
+the package.
+.It Fl F
+Any pkg-name given will be interpreted as pathname which is
+subsequently transformed in a (real) package name via the Package
+Database.
+That way, packages can be deleted by giving a filename
+instead of the package-name.
+.It Fl f
+Force removal of the package, even if a dependency is recorded or the
+deinstall or require script fails.
+.It Fl n
+Don't actually deinstall a package, just report the steps that
+would be taken if it were.
+.It Fl O
+Only delete the package's entries from the package database, do not
+touch the package or its files itself.
+.It Fl p Ar prefix
+Set
+.Ar prefix
+as the directory in which to delete files from any installed packages
+which do not explicitly set theirs.
+For most packages, the prefix will
+be set automatically to the installed location by
+.Xr pkg_add 1 .
+.It Fl R
+Like the
+.Fl r
+option, this does a recursive delete.
+The
+.Fl R
+option deletes the given package and any packages required by
+it, unless some other package still needs them.
+This can be used to delete a package and all the packages it needs.
+.It Fl r
+.Nm
+first builds a list of all packages that require (directly and indirectly)
+the one being deleted.
+It then deletes these packages using
+.Nm
+with the given options before deleting the user specified package.
+.It Fl V
+Print version number and exit.
+.It Fl v
+Turn on verbose output.
+.El
+.Sh TECHNICAL DETAILS
+.Nm
+does pretty much what it says.
+It examines installed package records in
+.Pa /var/db/pkg/\*[Lt]pkg-name\*[Gt] ,
+deletes the package contents, and finally removes the package records.
+.Pp
+If a package is required by other installed packages,
+.Nm
+will list those dependent packages and refuse to delete the package
+(unless the
+.Fl f
+option is given).
+.Pp
+If a filename is given instead of a package name, the package of which
+the given file belongs to can be deleted if the
+.Fl F
+Flag is given.
+The filename needs to be absolute, see the output produced by the pkg_info
+.Fl aF
+command.
+.Pp
+If the package contains a
+.Ar require
+file (see
+.Xr pkg_create 1 ) ,
+then this is executed first as
+.Bd -filled -offset indent -compact
+.Cm require
+.Ar \*[Lt]pkg-name\*[Gt]
+.Ar DEINSTALL
+.Ed
+(where
+.Ar pkg-name
+is the name of the package in question and
+.Ar DEINSTALL
+is a keyword denoting that this is a deinstallation)
+to see whether or not deinstallation should continue.
+A non-zero exit status means no, unless the
+.Fl f
+option is specified.
+.Pp
+If a
+.Cm deinstall
+script exists for the package, it is executed before and after
+any files are removed.
+It is this script's responsibility to clean up any additional messy details
+around the package's installation, since all
+.Nm
+knows how to do is delete the files created in the original distribution.
+The
+.Ic deinstall
+script is called as:
+.Bd -filled -offset indent -compact
+.Cm deinstall
+.Ar \*[Lt]pkg-name\*[Gt]
+.Ar DEINSTALL
+.Ed
+before deleting all files and as:
+.Bd -filled -offset indent -compact
+.Cm deinstall
+.Ar \*[Lt]pkg-name\*[Gt]
+.Ar POST-DEINSTALL
+.Ed
+after deleting them.
+Passing the keywords
+.Ar DEINSTALL
+and
+.Ar POST-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
+set to the installation prefix (see the
+.Fl p
+option above).
+This allows a package author to write a script
+that reliably performs some action on the directory where the package
+is installed, even if the user might have changed it by specifying the
+.Fl p
+option when running
+.Nm
+or
+.Xr pkg_add 1 .
+.Sh SEE ALSO
+.Xr pkg_add 1 ,
+.Xr pkg_admin 1 ,
+.Xr pkg_create 1 ,
+.Xr pkg_info 1 ,
+.Xr mktemp 3 ,
+.Xr packages 7 ,
+.Xr mtree 8
+.Sh AUTHORS
+.Bl -tag -width indent -compact
+.It "Jordan Hubbard"
+most of the work
+.It "John Kohl"
+refined it for
+.Nx
+.It "Hubert Feyrer"
+.Nx
+wildcard dependency processing, pkgdb, recursive "down"
+delete, etc.
+.El
diff --git a/pkgtools/pkg_install/files/delete/pkg_delete.cat1 b/pkgtools/pkg_install/files/delete/pkg_delete.cat1
new file mode 100644
index 00000000000..1f08bf8ae84
--- /dev/null
+++ b/pkgtools/pkg_install/files/delete/pkg_delete.cat1
@@ -0,0 +1,135 @@
+PKG_DELETE(1) NetBSD Reference Manual PKG_DELETE(1)
+
+NNAAMMEE
+ ppkkgg__ddeelleettee - a utility for deleting previously installed software package
+ distributions
+
+SSYYNNOOPPSSIISS
+ ppkkgg__ddeelleettee [--DDddFFffnnOORRrrVVvv] [--pp _p_r_e_f_i_x] _p_k_g_-_n_a_m_e _._._.
+
+DDEESSCCRRIIPPTTIIOONN
+ The ppkkgg__ddeelleettee command is used to delete packages that have been previ-
+ ously installed with the pkg_add(1) command.
+
+WWAARRNNIINNGG
+ _S_i_n_c_e _t_h_e ppkkgg__ddeelleettee _c_o_m_m_a_n_d _m_a_y _e_x_e_c_u_t_e _s_c_r_i_p_t_s _o_r _p_r_o_g_r_a_m_s _p_r_o_v_i_d_e_d _b_y
+ _a _p_a_c_k_a_g_e _f_i_l_e_, _y_o_u_r _s_y_s_t_e_m _m_a_y _b_e _s_u_s_c_e_p_t_i_b_l_e _t_o _`_`_T_r_o_j_a_n _h_o_r_s_e_s_'_' _o_r
+ _o_t_h_e_r _s_u_b_t_l_e _a_t_t_a_c_k_s _f_r_o_m _m_i_s_c_r_e_a_n_t_s _w_h_o _c_r_e_a_t_e _d_a_n_g_e_r_o_u_s _p_a_c_k_a_g_e _f_i_l_e_s_.
+
+ _Y_o_u _a_r_e _a_d_v_i_s_e_d _t_o _v_e_r_i_f_y _t_h_e _c_o_m_p_e_t_e_n_c_e _a_n_d _i_d_e_n_t_i_t_y _o_f _t_h_o_s_e _w_h_o _p_r_o_-
+ _v_i_d_e _i_n_s_t_a_l_l_a_b_l_e _p_a_c_k_a_g_e _f_i_l_e_s_. _F_o_r _e_x_t_r_a _p_r_o_t_e_c_t_i_o_n_, _e_x_a_m_i_n_e _a_l_l _t_h_e
+ _p_a_c_k_a_g_e _c_o_n_t_r_o_l _f_i_l_e_s _i_n _t_h_e _p_a_c_k_a_g_e _r_e_c_o_r_d _d_i_r_e_c_t_o_r_y _(_/_v_a_r_/_d_b_/_p_k_g_/_<_p_k_g_-
+ _n_a_m_e_>_/_)_. _P_a_y _p_a_r_t_i_c_u_l_a_r _a_t_t_e_n_t_i_o_n _t_o _a_n_y _+_I_N_S_T_A_L_L_, _+_D_E_I_N_S_T_A_L_L_, _+_R_E_Q_U_I_R_E
+ _o_r _+_M_T_R_E_E___D_I_R_S _f_i_l_e_s_, _a_n_d _i_n_s_p_e_c_t _t_h_e _+_C_O_N_T_E_N_T_S _f_i_l_e _f_o_r @@ccwwdd_, @@mmooddee
+ _(_c_h_e_c_k _f_o_r _s_e_t_u_i_d_)_, @@ddiirrrrmm_, @@eexxeecc_, _a_n_d @@uunneexxeecc _d_i_r_e_c_t_i_v_e_s_, _a_n_d_/_o_r _u_s_e _t_h_e
+ pkg_info(_1) _c_o_m_m_a_n_d _t_o _e_x_a_m_i_n_e _t_h_e _i_n_s_t_a_l_l_e_d _p_a_c_k_a_g_e _c_o_n_t_r_o_l _f_i_l_e_s_.
+
+OOPPTTIIOONNSS
+ The following command line options are supported:
+
+ _p_k_g_-_n_a_m_e _._._.
+ The named packages are deinstalled, wildcards can be used, see
+ pkg_info(1). If no version is given, the one currently installed
+ will be removed. If the --FF flag is given, one or more (absolute)
+ filenames may be specified and the Package Database will be con-
+ sulted for the package to which the given file belongs. These
+ packages are then deinstalled.
+
+ --DD If a deinstallation script exists for a given package, do not ex-
+ ecute it.
+
+ --dd Remove empty directories created by file cleanup. By default,
+ only files/directories explicitly listed in a package's contents
+ (either as normal files/directories or with the @@ddiirrrrmm directive)
+ will be removed at deinstallation time. This option tells
+ ppkkgg__ddeelleettee to also remove any directories that were emptied as a
+ result of removing the package.
+
+ --FF Any pkg-name given will be interpreted as pathname which is sub-
+ sequently transformed in a (real) package name via the Package
+ Database. That way, packages can be deleted by giving a filename
+ instead of the package-name.
+
+ --ff Force removal of the package, even if a dependency is recorded or
+ the deinstall or require script fails.
+
+ --nn Don't actually deinstall a package, just report the steps that
+ would be taken if it were.
+
+ --OO Only delete the package's entries from the package database, do
+ not touch the package or its files itself.
+
+ --pp _p_r_e_f_i_x
+ Set _p_r_e_f_i_x as the directory in which to delete files from any in-
+ stalled packages which do not explicitly set theirs. For most
+ packages, the prefix will be set automatically to the installed
+ location by pkg_add(1).
+
+ --RR Like the --rr option, this does a recursive delete. The --RR option
+ deletes the given package and any packages required by it, unless
+ some other package still needs them. This can be used to delete
+ a package and all the packages it needs.
+
+ --rr ppkkgg__ddeelleettee first builds a list of all packages that require (di-
+ rectly and indirectly) the one being deleted. It then deletes
+ these packages using ppkkgg__ddeelleettee with the given options before
+ deleting the user specified package.
+
+ --VV Print version number and exit.
+
+ --vv Turn on verbose output.
+
+TTEECCHHNNIICCAALL DDEETTAAIILLSS
+ ppkkgg__ddeelleettee does pretty much what it says. It examines installed package
+ records in _/_v_a_r_/_d_b_/_p_k_g_/_<_p_k_g_-_n_a_m_e_>, deletes the package contents, and fi-
+ nally removes the package records.
+
+ If a package is required by other installed packages, ppkkgg__ddeelleettee will
+ list those dependent packages and refuse to delete the package (unless
+ the --ff option is given).
+
+ If a filename is given instead of a package name, the package of which
+ the given file belongs to can be deleted if the --FF Flag is given. The
+ filename needs to be absolute, see the output produced by the pkg_info
+ --aaFF command.
+
+ If the package contains a _r_e_q_u_i_r_e file (see pkg_create(1)), then this is
+ executed first as
+ rreeqquuiirree _<_p_k_g_-_n_a_m_e_> _D_E_I_N_S_T_A_L_L
+ (where _p_k_g_-_n_a_m_e is the name of the package in question and _D_E_I_N_S_T_A_L_L is a
+ keyword denoting that this is a deinstallation) to see whether or not de-
+ installation should continue. A non-zero exit status means no, unless
+ the --ff option is specified.
+
+ If a ddeeiinnssttaallll script exists for the package, it is executed before and
+ after any files are removed. It is this script's responsibility to clean
+ up any additional messy details around the package's installation, since
+ all ppkkgg__ddeelleettee knows how to do is delete the files created in the origi-
+ nal distribution. The ddeeiinnssttaallll script is called as:
+ ddeeiinnssttaallll _<_p_k_g_-_n_a_m_e_> _D_E_I_N_S_T_A_L_L
+ before deleting all files and as:
+ ddeeiinnssttaallll _<_p_k_g_-_n_a_m_e_> _P_O_S_T_-_D_E_I_N_S_T_A_L_L
+ after deleting them. Passing the keywords _D_E_I_N_S_T_A_L_L and _P_O_S_T_-_D_E_I_N_S_T_A_L_L
+ lets you potentially write only one program/script that handles all as-
+ pects of installation and deletion.
+
+ All scripts are called with the environment variable PKG_PREFIX set to
+ the installation prefix (see the --pp option above). This allows a package
+ author to write a script that reliably performs some action on the direc-
+ tory where the package is installed, even if the user might have changed
+ it by specifying the --pp option when running ppkkgg__ddeelleettee or pkg_add(1).
+
+SSEEEE AALLSSOO
+ pkg_add(1), pkg_admin(1), pkg_create(1), pkg_info(1), mktemp(3),
+ packages(7), mtree(8)
+
+AAUUTTHHOORRSS
+ Jordan Hubbard
+ most of the work
+ John Kohl
+ refined it for NetBSD
+ Hubert Feyrer
+ NetBSD wildcard dependency processing, pkgdb, recursive "down"
+ delete, etc.
+
+NetBSD 1.6 March 8, 1999 3
diff --git a/pkgtools/pkg_install/files/info/Makefile.in b/pkgtools/pkg_install/files/info/Makefile.in
new file mode 100644
index 00000000000..5d7460dd40f
--- /dev/null
+++ b/pkgtools/pkg_install/files/info/Makefile.in
@@ -0,0 +1,39 @@
+# From NetBSD: Makefile,v 1.1 1999/01/19 17:01:58 hubertf Exp
+
+PREFIX= @prefix@
+INSTALL= @INSTALL@
+
+mandir= ${PREFIX}/man
+mandircat1= ${mandir}/cat1
+
+CC= @CC@
+CCLD= $(CC)
+LIBS= @LIBS@ -linstall
+CPPFLAGS= @CPPFLAGS@
+DEFS= @DEFS@ -I. -I@srcdir@ -I../lib
+CFLAGS= @CFLAGS@
+LDFLAGS= @LDFLAGS@ -L../lib
+
+LINK= $(CCLD) $(CFLAGS) $(LDFLAGS) -o $@
+COMPILE= $(CC) $(DEFS) $(CPPFLAGS) $(CFLAGS)
+
+PROG= pkg_info
+
+SRCS= main.c perform.c show.c
+OBJS= main.o perform.o show.o
+
+all: ${PROG}
+
+${PROG}: ${OBJS}
+ ${LINK} ${OBJS} ${LIBS}
+
+.c.o:
+ $(COMPILE) -c $< -o $@
+
+clean:
+ rm -f ${OBJS} ${PROG}
+
+install:
+ ${INSTALL} ${PROG} ${PREFIX}/sbin
+ ${INSTALL} -m 755 -d ${mandircat1}
+ ${INSTALL} -m 444 ${PROG}.cat1 ${mandircat1}/${PROG}.1
diff --git a/pkgtools/pkg_install/files/info/info.h b/pkgtools/pkg_install/files/info/info.h
new file mode 100644
index 00000000000..a18d450e195
--- /dev/null
+++ b/pkgtools/pkg_install/files/info/info.h
@@ -0,0 +1,71 @@
+/* $NetBSD: info.h,v 1.1.1.1 2002/12/20 18:14:12 schmonz Exp $ */
+
+/* from FreeBSD Id: info.h,v 1.10 1997/02/22 16:09:40 peter Exp */
+
+/*
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 23 August 1993
+ *
+ * Include and define various things wanted by the info command.
+ *
+ */
+
+#ifndef _INST_INFO_H_INCLUDE
+#define _INST_INFO_H_INCLUDE
+
+#ifndef MAXINDEXSIZE
+#define MAXINDEXSIZE 60
+#endif
+
+#ifndef MAXNAMESIZE
+#define MAXNAMESIZE 20
+#endif
+
+#define SHOW_COMMENT 0x00001
+#define SHOW_DESC 0x00002
+#define SHOW_PLIST 0x00004
+#define SHOW_INSTALL 0x00008
+#define SHOW_DEINSTALL 0x00010
+#define SHOW_REQUIRE 0x00020
+#define SHOW_PREFIX 0x00040
+#define SHOW_INDEX 0x00080
+#define SHOW_FILES 0x00100
+#define SHOW_DISPLAY 0x00200
+#define SHOW_REQBY 0x00400
+#define SHOW_MTREE 0x00800
+#define SHOW_BUILD_VERSION 0x01000
+#define SHOW_BUILD_INFO 0x02000
+#define SHOW_DEPENDS 0x04000
+#define SHOW_PKG_SIZE 0x08000
+#define SHOW_ALL_SIZE 0x10000
+
+extern int Flags;
+extern Boolean AllInstalled;
+extern Boolean File2Pkg;
+extern Boolean Quiet;
+extern char *InfoPrefix;
+extern char PlayPen[];
+extern size_t PlayPenSize;
+extern char *CheckPkg;
+extern size_t termwidth;
+extern lpkg_head_t pkgs;
+
+extern void show_file(char *, char *);
+extern void show_plist(char *, package_t *, pl_ent_t);
+extern void show_files(char *, package_t *);
+extern void show_depends(char *, package_t *);
+extern void show_index(char *, char *);
+
+#endif /* _INST_INFO_H_INCLUDE */
diff --git a/pkgtools/pkg_install/files/info/main.c b/pkgtools/pkg_install/files/info/main.c
new file mode 100644
index 00000000000..27e17085533
--- /dev/null
+++ b/pkgtools/pkg_install/files/info/main.c
@@ -0,0 +1,287 @@
+/* $NetBSD: main.c,v 1.1.1.1 2002/12/20 18:14:12 schmonz Exp $ */
+
+#if 0
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char *rcsid = "from FreeBSD Id: main.c,v 1.14 1997/10/08 07:47:26 charnier Exp";
+#else
+__RCSID("$NetBSD: main.c,v 1.1.1.1 2002/12/20 18:14:12 schmonz Exp $");
+#endif
+#endif
+#endif
+
+/*
+ *
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 18 July 1993
+ *
+ * This is the add module.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#endif
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#include "lib.h"
+#include "info.h"
+
+static const char Options[] = "aBbcDde:fFhIikLl:mnpqRrsSvV";
+
+int Flags = 0;
+Boolean AllInstalled = FALSE;
+Boolean File2Pkg = FALSE;
+Boolean Quiet = FALSE;
+char *InfoPrefix = "";
+char PlayPen[FILENAME_MAX];
+size_t PlayPenSize = sizeof(PlayPen);
+char *CheckPkg = NULL;
+size_t termwidth = 0;
+lpkg_head_t pkgs;
+
+static void
+usage(void)
+{
+ fprintf(stderr, "%s\n%s\n%s\n",
+ "usage: pkg_info [-BbcDdFfIikLmnpqRrSsVvh] [-e package] [-l prefix]",
+ " pkg-name [pkg-name ...]",
+ " pkg_info -a [flags]");
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ int ch, rc;
+ lpkg_t *lpp;
+
+ setprogname(argv[0]);
+
+ while ((ch = getopt(argc, argv, Options)) != -1)
+ switch (ch) {
+ case 'a':
+ AllInstalled = TRUE;
+ break;
+
+ case 'B':
+ Flags |= SHOW_BUILD_INFO;
+ break;
+
+ case 'b':
+ Flags |= SHOW_BUILD_VERSION;
+ break;
+
+ case 'c':
+ Flags |= SHOW_COMMENT;
+ break;
+
+ case 'D':
+ Flags |= SHOW_DISPLAY;
+ break;
+
+ case 'd':
+ Flags |= SHOW_DESC;
+ break;
+
+ case 'e':
+ CheckPkg = optarg;
+ break;
+
+ case 'f':
+ Flags |= SHOW_PLIST;
+ break;
+
+ case 'F':
+ File2Pkg = 1;
+ break;
+
+ case 'I':
+ Flags |= SHOW_INDEX;
+ break;
+
+ case 'i':
+ Flags |= SHOW_INSTALL;
+ break;
+
+ case 'k':
+ Flags |= SHOW_DEINSTALL;
+ break;
+
+ case 'L':
+ Flags |= SHOW_FILES;
+ break;
+
+ case 'l':
+ InfoPrefix = optarg;
+ break;
+
+ case 'm':
+ Flags |= SHOW_MTREE;
+ break;
+
+ case 'n':
+ Flags |= SHOW_DEPENDS;
+ break;
+
+ case 'p':
+ Flags |= SHOW_PREFIX;
+ break;
+
+ case 'q':
+ Quiet = TRUE;
+ break;
+
+ case 'R':
+ Flags |= SHOW_REQBY;
+ break;
+
+ case 'r':
+ Flags |= SHOW_REQUIRE;
+ break;
+
+ case 's':
+ Flags |= SHOW_PKG_SIZE;
+ break;
+
+ case 'S':
+ Flags |= SHOW_ALL_SIZE;
+ break;
+
+ case 'v':
+ Verbose = TRUE;
+ /* Reasonable definition of 'everything' */
+ Flags = SHOW_COMMENT | SHOW_DESC | SHOW_PLIST | SHOW_INSTALL |
+ SHOW_DEINSTALL | SHOW_REQUIRE | SHOW_DISPLAY | SHOW_MTREE |
+ SHOW_REQBY | SHOW_DEPENDS | SHOW_PKG_SIZE | SHOW_ALL_SIZE;
+ break;
+
+ case 'V':
+ show_version();
+ /* NOTREACHED */
+
+ case 'h':
+ case '?':
+ default:
+ usage();
+ /* NOTREACHED */
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc == 0 && !Flags && !CheckPkg) {
+ /* No argument or flags specified - assume -Ia */
+ Flags = SHOW_INDEX;
+ AllInstalled = TRUE;
+ }
+
+ /* Don't do FTP stuff when operating on all pkgs */
+ if (AllInstalled && getenv("PKG_PATH") != 0) {
+ warnx("disabling PKG_PATH when operating on all packages.");
+ unsetenv("PKG_PATH");
+ }
+
+ path_create(getenv("PKG_PATH"));
+
+ /* Set some reasonable defaults */
+ if (!Flags)
+ Flags = SHOW_COMMENT | SHOW_DESC | SHOW_REQBY | SHOW_DEPENDS;
+
+ /* -Fe /filename -> change CheckPkg to real packagename */
+ if (CheckPkg && File2Pkg) {
+ char *s;
+
+ if (pkgdb_open(1) == -1)
+ err(1, "cannot open pkgdb");
+
+ s = pkgdb_retrieve(CheckPkg);
+
+ if (s) {
+ CheckPkg = strdup(s);
+ } else {
+ errx(1, "No matching pkg for %s.", CheckPkg);
+ }
+
+ pkgdb_close();
+ }
+
+ TAILQ_INIT(&pkgs);
+
+ /* Get all the remaining package names, if any */
+ if (File2Pkg && !AllInstalled)
+ if (pkgdb_open(1) == -1) {
+ err(1, "cannot open pkgdb");
+ }
+ while (*argv) {
+ /* pkgdb: if -F flag given, don't add pkgnames to the "pkgs"
+ * queue but rather resolve the given filenames to pkgnames
+ * using pkgdb_retrieve, then add them. */
+ if (File2Pkg) {
+ char *s;
+
+ s = pkgdb_retrieve(*argv);
+
+ if (s) {
+ lpp = alloc_lpkg(s);
+ TAILQ_INSERT_TAIL(&pkgs, lpp, lp_link);
+ } else
+ errx(1, "No matching pkg for %s.", *argv);
+ } else {
+ if (ispkgpattern(*argv)) {
+ if (findmatchingname(_pkgdb_getPKGDB_DIR(), *argv, add_to_list_fn, &pkgs) == 0)
+ errx(1, "No matching pkg for %s.", *argv);
+ } else {
+ lpp = alloc_lpkg(*argv);
+ TAILQ_INSERT_TAIL(&pkgs, lpp, lp_link);
+ }
+ }
+ argv++;
+ }
+
+ if (File2Pkg)
+ pkgdb_close();
+
+ /* If no packages, yelp */
+ if (TAILQ_FIRST(&pkgs) == NULL && !AllInstalled && !CheckPkg)
+ warnx("missing package name(s)"), usage();
+
+ if (isatty(STDOUT_FILENO)) {
+ const char *p;
+ struct winsize win;
+
+ if ((p = getenv("COLUMNS")) != NULL)
+ termwidth = atoi(p);
+ else if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == 0 &&
+ win.ws_col > 0)
+ termwidth = win.ws_col;
+ }
+
+ rc = pkg_perform(&pkgs);
+ exit(rc);
+ /* NOTREACHED */
+}
diff --git a/pkgtools/pkg_install/files/info/perform.c b/pkgtools/pkg_install/files/info/perform.c
new file mode 100644
index 00000000000..c8dddc7b3b2
--- /dev/null
+++ b/pkgtools/pkg_install/files/info/perform.c
@@ -0,0 +1,381 @@
+/* $NetBSD: perform.c,v 1.1.1.1 2002/12/20 18:14:13 schmonz Exp $ */
+
+#if 0
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static const char *rcsid = "from FreeBSD Id: perform.c,v 1.23 1997/10/13 15:03:53 jkh Exp";
+#else
+__RCSID("$NetBSD: perform.c,v 1.1.1.1 2002/12/20 18:14:13 schmonz Exp $");
+#endif
+#endif
+#endif
+
+/*
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 23 Aug 1993
+ *
+ * This is the main body of the info module.
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "lib.h"
+#include "info.h"
+
+#include <sys/types.h>
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#include <signal.h>
+
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+
+#include <ctype.h>
+
+static char *Home;
+
+static int
+pkg_do(char *pkg)
+{
+ Boolean installed = FALSE, isTMP = FALSE;
+ char log_dir[FILENAME_MAX];
+ char fname[FILENAME_MAX];
+ struct stat sb;
+ char *cp = NULL;
+ int code = 0;
+
+ if (IS_URL(pkg)) {
+ if ((cp = fileGetURL(pkg)) != NULL) {
+ strcpy(fname, cp);
+ isTMP = TRUE;
+ }
+ } else if (fexists(pkg) && isfile(pkg)) {
+ int len;
+
+ if (*pkg != '/') {
+ if (!getcwd(fname, FILENAME_MAX)) {
+ cleanup(0);
+ err(1, "fatal error during execution: getcwd");
+ }
+ len = strlen(fname);
+ (void) snprintf(&fname[len], sizeof(fname) - len, "/%s", pkg);
+ } else {
+ strcpy(fname, pkg);
+ }
+ cp = fname;
+ } else {
+ if ((cp = fileFindByPath(pkg)) != NULL) {
+ strncpy(fname, cp, FILENAME_MAX);
+ }
+ }
+
+ if (cp) {
+ if (IS_URL(pkg)) {
+ /* file is already unpacked by fileGetURL() */
+ strcpy(PlayPen, cp);
+ } else {
+ if (IS_URL(cp)) {
+ /* only a package name was given, and it was expanded to a
+ * full URL by fileFindByPath. Now extract...
+ */
+ char *cp2;
+
+ if ((cp2 = fileGetURL(cp)) != NULL) {
+ strcpy(fname, cp2);
+ isTMP = TRUE;
+ }
+ strcpy(PlayPen, cp2);
+ } else {
+ /*
+ * Apply a crude heuristic to see how much space the package will
+ * take up once it's unpacked. I've noticed that most packages
+ * compress an average of 75%, but we're only unpacking the + files so
+ * be very optimistic.
+ */
+ if (stat(fname, &sb) == FAIL) {
+ warnx("can't stat package file '%s'", fname);
+ code = 1;
+ goto bail;
+ }
+ Home = make_playpen(PlayPen, PlayPenSize, sb.st_size / 2);
+ if (unpack(fname, "+*")) {
+ warnx("error during unpacking, no info for '%s' available", pkg);
+ code = 1;
+ goto bail;
+ }
+ }
+ }
+ } else {
+ /*
+ * It's not an uninstalled package, try and find it among the
+ * installed
+ */
+ char *tmp;
+
+ (void) snprintf(log_dir, sizeof(log_dir), "%s/%s",
+ (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR,
+ pkg);
+ if (!fexists(log_dir) || !isdir(log_dir)) {
+ {
+ /* Check if the given package name matches
+ * something with 'pkg-[0-9]*' */
+ char try[FILENAME_MAX];
+ snprintf(try, FILENAME_MAX, "%s-[0-9]*", pkg);
+ if (findmatchingname(_pkgdb_getPKGDB_DIR(), try,
+ add_to_list_fn, &pkgs) != 0) {
+ return 0; /* we've just appended some names to the pkgs list,
+ * they will be processed after this package. */
+ }
+ }
+
+ /* No match */
+ warnx("can't find package `%s' installed or in a file!", pkg);
+ return 1;
+ }
+ if (chdir(log_dir) == FAIL) {
+ warnx("can't change directory to '%s'!", log_dir);
+ return 1;
+ }
+ installed = TRUE;
+ }
+
+ /*
+ * Index is special info type that has to override all others to make
+ * any sense.
+ */
+ if (Flags & SHOW_INDEX) {
+ char tmp[FILENAME_MAX];
+
+ (void) snprintf(tmp, sizeof(tmp), "%-19s ", pkg);
+ show_index(tmp, COMMENT_FNAME);
+ } else {
+ FILE *fp;
+ package_t plist;
+
+ /* Read the contents list */
+ plist.head = plist.tail = NULL;
+ fp = fopen(CONTENTS_FNAME, "r");
+ if (!fp) {
+ warnx("unable to open %s file", CONTENTS_FNAME);
+ code = 1;
+ goto bail;
+ }
+ /* If we have a prefix, add it now */
+ read_plist(&plist, fp);
+ fclose(fp);
+
+ /* Start showing the package contents */
+ if (!Quiet) {
+ printf("%sInformation for %s:\n\n", InfoPrefix, pkg);
+ }
+ if (Flags & SHOW_COMMENT) {
+ show_file("Comment:\n", COMMENT_FNAME);
+ }
+ if (Flags & SHOW_DEPENDS) {
+ show_depends("Requires:\n", &plist);
+ }
+ 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_SHOW_ALL);
+ }
+ 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_REQUIRE) && fexists(REQUIRE_FNAME)) {
+ show_file("Require script:\n", REQUIRE_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) {
+ show_files("Files:\n", &plist);
+ }
+ if ((Flags & SHOW_BUILD_VERSION) && fexists(BUILD_VERSION_FNAME)) {
+ show_file("Build version:\n", BUILD_VERSION_FNAME);
+ }
+ if ((Flags & SHOW_BUILD_INFO) && fexists(BUILD_INFO_FNAME)) {
+ show_file("Build information:\n", BUILD_INFO_FNAME);
+ }
+ if ((Flags & SHOW_PKG_SIZE) && fexists(SIZE_PKG_FNAME)) {
+ show_file("Size of this package in bytes: ", SIZE_PKG_FNAME);
+ }
+ if ((Flags & SHOW_ALL_SIZE) && fexists(SIZE_ALL_FNAME)) {
+ show_file("Size in bytes including required pkgs: ", SIZE_ALL_FNAME);
+ }
+ if (!Quiet) {
+ puts(InfoPrefix);
+ }
+ free_plist(&plist);
+ }
+bail:
+ leave_playpen(Home);
+ if (isTMP)
+ unlink(fname);
+ return code;
+}
+
+/*
+ * Function to be called for pkgs found
+ */
+static int
+foundpkg(const char *found, void *vp)
+{
+ char *data = vp;
+ char buf[FILENAME_MAX+1];
+
+ /* we only want to display this if it really is a directory */
+ snprintf(buf, sizeof(buf), "%s/%s", data, found);
+ if (!isdir(buf)) {
+ /* return value seems to be ignored for now */
+ return -1;
+ }
+
+ if (!Quiet) {
+ printf("%s\n", found);
+ }
+
+ return 0;
+}
+
+/*
+ * Check if a package "pkgspec" (which can be a pattern) is installed.
+ * dbdir contains the return value of _pkgdb_getPKGDB_DIR(), for reading only.
+ * Return 0 if found, 1 otherwise (indicating an error).
+ */
+static int
+CheckForPkg(char *pkgspec, char *dbdir)
+{
+ char buf[FILENAME_MAX];
+ int error;
+
+ if (strpbrk(pkgspec, "<>[]?*{")) {
+ /* expensive (pattern) match */
+ return !findmatchingname(dbdir, pkgspec, foundpkg, dbdir);
+ }
+ /* simple match */
+ (void) snprintf(buf, sizeof(buf), "%s/%s", dbdir, pkgspec);
+ error = !isdir(buf);
+ if (!error && !Quiet) {
+ printf("%s\n", pkgspec);
+ }
+ if (error) {
+ /* found nothing - try 'pkg-[0-9]*' */
+
+ char try[FILENAME_MAX];
+ snprintf(try, FILENAME_MAX, "%s-[0-9]*", pkgspec);
+ if (findmatchingname(dbdir, try, foundpkg, dbdir) != 0) {
+ error = 0;
+ }
+ }
+ return error;
+}
+
+void
+cleanup(int sig)
+{
+ leave_playpen(Home);
+ exit(1);
+}
+
+int
+pkg_perform(lpkg_head_t *pkghead)
+{
+ struct dirent *dp;
+ char *tmp;
+ DIR *dirp;
+ int err_cnt = 0;
+
+ signal(SIGINT, cleanup);
+
+ tmp = _pkgdb_getPKGDB_DIR();
+
+ /* Overriding action? */
+ if (CheckPkg) {
+ err_cnt += CheckForPkg(CheckPkg, tmp);
+ } else if (AllInstalled) {
+ if (!(isdir(tmp) || islinktodir(tmp)))
+ return 1;
+
+ if (File2Pkg) {
+ /* Show all files with the package they belong to */
+ char *file, *pkg;
+
+ /* pkg_info -Fa => Dump pkgdb */
+ if (pkgdb_open(1) == -1) {
+ err(1, "cannot open pkgdb");
+ }
+ while ((file = pkgdb_iter())) {
+ pkg = pkgdb_retrieve(file);
+ printf("%-50s %s\n", file, pkg);
+ }
+ pkgdb_close();
+ } else {
+ /* Show all packges with description */
+ if ((dirp = opendir(tmp)) != (DIR *) NULL) {
+ while ((dp = readdir(dirp)) != (struct dirent *) NULL) {
+ char tmp2[FILENAME_MAX];
+
+ if (strcmp(dp->d_name, ".") == 0 ||
+ strcmp(dp->d_name, "..") == 0)
+ continue;
+
+ (void) snprintf(tmp2, sizeof(tmp2), "%s/%s",
+ tmp, dp->d_name);
+ if (isfile(tmp2))
+ continue;
+
+ err_cnt += pkg_do(dp->d_name);
+ }
+ (void) closedir(dirp);
+ }
+ }
+ } else {
+ /* Show info on individual pkg(s) */
+ lpkg_t *lpp;
+
+ while ((lpp = TAILQ_FIRST(pkghead))) {
+ TAILQ_REMOVE(pkghead, lpp, lp_link);
+ err_cnt += pkg_do(lpp->lp_name);
+ free_lpkg(lpp);
+ }
+ }
+ ftp_stop();
+ return err_cnt;
+}
diff --git a/pkgtools/pkg_install/files/info/pkg_info.1 b/pkgtools/pkg_install/files/info/pkg_info.1
new file mode 100644
index 00000000000..70494bceab6
--- /dev/null
+++ b/pkgtools/pkg_install/files/info/pkg_info.1
@@ -0,0 +1,262 @@
+.\" $NetBSD: pkg_info.1,v 1.1.1.1 2002/12/20 18:14:13 schmonz Exp $
+.\"
+.\" FreeBSD install - a package for the installation and maintainance
+.\" of non-core utilities.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" Jordan K. Hubbard
+.\"
+.\"
+.\" @(#)pkg_info.1
+.\"
+.Dd March 4, 1999
+.Dt PKG_INFO 1
+.Os
+.Sh NAME
+.Nm pkg_info
+.Nd a utility for displaying information on software packages
+.Sh SYNOPSIS
+.Nm
+.Op Fl BbcDdFfhIikLmnpqRrSsVv
+.Bk -words
+.Op Fl e Ar package
+.Ek
+.Bk -words
+.Op Fl l Ar prefix
+.Ek
+.Ar pkg-name ...
+.Nm
+.Bk -words
+.Op Fl a Ar flags
+.Ek
+.Sh DESCRIPTION
+The
+.Nm
+command is used to dump out information for packages, which may be either
+packed up in files or already installed on the system with the
+.Xr pkg_create 1
+command.
+.Pp
+The
+.Ar pkg-name
+may be the name of an installed package (with our without version), a
+pattern matching several installed packages (see the
+.Fl e
+switch for a description of possible patterns),
+the pathname to a
+package distribution file, a filename belonging to an installed
+package (if
+.Fl F
+is also given), or a URL to an ftp-available package.
+.Pp
+The following command-line options are supported:
+.Bl -tag -width indent
+.It Fl a
+Show information for all currently installed packages.
+.It Fl B
+Show some of the important definitions used when building
+the binary package (the "Build information") for each package.
+.It Fl b
+Show the
+.Nx
+RCS Id strings from the files used in the construction
+of the binary package (the "Build version") for each package.
+These files are the package Makefile, any patch files, any checksum
+files, and the packing list file.
+.It Fl c
+Show the one-line comment field for each package.
+.It Fl D
+Show the install-message file (if any) for each package.
+.It Fl d
+Show the long-description field for each package.
+.It Fl e Ar pkg-name
+This option
+allows you to test for the presence of another (perhaps
+prerequisite) package from a script.
+If the package identified by
+.Ar pkg-name
+is currently installed, return 0, otherwise return 1.
+In addition, the names of any package(s) found installed are printed to
+stdout unless turned off using the
+.Fl q
+option.
+.Pp
+If the given
+.Ar pkg-name
+contains a
+shell meta character, it will be matched against all installed
+packages using
+.Xr fnmatch 3 .
+.Xr csh 1
+style {,} alternates have also been implemented in addition to this.
+Package version numbers can also be matched in a relational manner
+using the
+.Pa \*[Ge], \*[Le], \*[Gt]
+and
+.Pa \*[Lt]
+operators.
+For example,
+.Pa pkg_info -e 'name\*[Ge]1.3'
+will match versions 1.3 and later of the
+.Pa name
+package.
+The collating sequence of the various package version numbers is
+unusual, but strives to be consistent.
+The magic string ``rc'' equates to
+.Pa release candidate
+and sorts before a release.
+For example,
+.Pa name-1.3rc3
+will sort before
+.Pa name-1.3
+and after
+.Pa name-1.2.9
+In addition, alphabetic characters sort in the same place as
+their numeric counterparts, so that
+.Pa name-1.2e
+has the same sorting value as
+.Pa name-1.2.5
+The magic string ``pl'' equates to a
+.Pa patch level
+and has the same value as a dot in the dewey-decimal ordering schemes.
+.It Fl F
+Interpret any pkg-name given as filename, and translate it to a
+package name using the Package Database.
+This can be used to query information on a per-file basis, e.g. in
+conjunction with the
+.Fl e
+flag to find out which package a file belongs to.
+.It Fl f
+Show the packing list instructions for each package.
+.It Fl I
+Show the index entry for each package.
+.It Fl i
+Show the install script (if any) for each package.
+.It Fl k
+Show the de-install script (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.
+.It Fl l Ar str
+Prefix each information category header (see
+.Fl q )
+shown with
+.Ar str .
+This is primarily of use to front-end programs that 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.
+.It Fl m
+Show the mtree file (if any) for each package.
+.It Fl n
+Show which packages each package needs (depends upon), if any.
+.It Fl p
+Show the installation prefix for each package.
+.It Fl q
+Be ``quiet'' in emitting report headers and such, just dump the
+raw info (basically, assume a non-human reading).
+.It Fl R
+Show which packages are required by each package.
+.It Fl r
+Show the requirements script (if any) for each package.
+.It Fl S
+Show the size of this package and all the packages it requires,
+in bytes.
+.It Fl s
+Show the size of this package in bytes.
+The size is calculated by adding up the size of each file of the package.
+.It Fl V
+Print version number and exit.
+.It Fl v
+Turn on verbose output.
+.El
+.Sh ENVIRONMENT
+.Bl -tag -width PKG_DBDIR
+.It Ev PKG_DBDIR
+The standard package database directory,
+.Pa /var/db/pkg ,
+can be overridden by specifying an alternative directory in the
+.Ev PKG_DBDIR
+environment variable.
+.It Ev PKG_PATH
+This can be used to specify a semicolon-separated list of paths and URLs to search for
+package files.
+If
+.Ev PKG_PATH
+is used, the suffix
+.Pa .tgz
+is automatically appended to the
+.Ar pkg-name ,
+whereas searching in the current directory uses
+.Ar pkg-name
+literally.
+.It Ev PKG_TMPDIR , Ev TMPDIR
+These are tried in turn (if set) as candidate directories in which
+to create a ``staging area'' for any files extracted by
+.Nm
+from package files.
+If neither
+.Ev PKG_TMPDIR
+nor
+.Ev TMPDIR
+yields a suitable scratch directory,
+.Pa /var/tmp ,
+.Pa /tmp ,
+and
+.Pa /usr/tmp
+are tried in turn.
+Note that
+.Pa /usr/tmp
+may be created, if it doesn't already exist.
+.Pp
+Since
+.Nm
+requires very little information to be extracted from any package
+files examined, it is unlikely that these environment variables would
+ever need to be used to work around limited available space in the
+default locations.
+.El
+.Sh TECHNICAL DETAILS
+Package info is either extracted from package files named on the
+command line, or from already installed package information
+in
+.Pa /var/db/pkg/\*[Lt]pkg-name\*[Gt] .
+.Pp
+A filename can be given instead of a (installed) package name to query
+information on the package this file belongs to.
+This filename is then resolved to a package name using the Package Database.
+For this translation to take place, the
+.Fl F
+flag must be given.
+The filename must be absolute, compare the output of pkg_info
+.Fl aF .
+.Sh SEE ALSO
+.Xr pkg_add 1 ,
+.Xr pkg_admin 1 ,
+.Xr pkg_create 1 ,
+.Xr pkg_delete 1 ,
+.Xr mktemp 3 ,
+.Xr packages 7 ,
+.Xr mtree 8
+.Sh AUTHORS
+.Bl -tag -width indent -compact
+.It "Jordan Hubbard"
+most of the work
+.It "John Kohl"
+refined it for
+.Nx
+.It "Hubert Feyrer"
+.Nx
+wildcard dependency processing, pkgdb, depends displaying,
+pkg size display etc.
+.El
diff --git a/pkgtools/pkg_install/files/info/pkg_info.cat1 b/pkgtools/pkg_install/files/info/pkg_info.cat1
new file mode 100644
index 00000000000..3dba143ceca
--- /dev/null
+++ b/pkgtools/pkg_install/files/info/pkg_info.cat1
@@ -0,0 +1,157 @@
+PKG_INFO(1) NetBSD Reference Manual PKG_INFO(1)
+
+NNAAMMEE
+ ppkkgg__iinnffoo - a utility for displaying information on software packages
+
+SSYYNNOOPPSSIISS
+ ppkkgg__iinnffoo [--BBbbccDDddFFffhhIIiikkLLmmnnppqqRRrrSSssVVvv] [--ee _p_a_c_k_a_g_e] [--ll _p_r_e_f_i_x] _p_k_g_-_n_a_m_e _._._.
+ ppkkgg__iinnffoo [--aa _f_l_a_g_s]
+
+DDEESSCCRRIIPPTTIIOONN
+ The ppkkgg__iinnffoo command is used to dump out information for packages, which
+ may be either packed up in files or already installed on the system with
+ the pkg_create(1) command.
+
+ The _p_k_g_-_n_a_m_e may be the name of an installed package (with our without
+ version), a pattern matching several installed packages (see the --ee
+ switch for a description of possible patterns), the pathname to a package
+ distribution file, a filename belonging to an installed package (if --FF is
+ also given), or a URL to an ftp-available package.
+
+ The following command-line options are supported:
+
+ --aa Show information for all currently installed packages.
+
+ --BB Show some of the important definitions used when building the bi-
+ nary package (the "Build information") for each package.
+
+ --bb Show the NetBSD RCS Id strings from the files used in the con-
+ struction of the binary package (the "Build version") for each
+ package. These files are the package Makefile, any patch files,
+ any checksum files, and the packing list file.
+
+ --cc Show the one-line comment field for each package.
+
+ --DD Show the install-message file (if any) for each package.
+
+ --dd Show the long-description field for each package.
+
+ --ee _p_k_g_-_n_a_m_e
+ This option allows you to test for the presence of another (per-
+ haps prerequisite) package from a script. If the package identi-
+ fied by _p_k_g_-_n_a_m_e is currently installed, return 0, otherwise re-
+ turn 1. In addition, the names of any package(s) found installed
+ are printed to stdout unless turned off using the --qq option.
+
+ If the given _p_k_g_-_n_a_m_e contains a shell meta character, it will be
+ matched against all installed packages using fnmatch(3). csh(1)
+ style {,} alternates have also been implemented in addition to
+ this. Package version numbers can also be matched in a relation-
+ al manner using the _>_=_, _<_=_, _> and _< operators. For example,
+ _p_k_g___i_n_f_o _-_e _'_n_a_m_e_>_=_1_._3_' will match versions 1.3 and later of the
+ _n_a_m_e package. The collating sequence of the various package ver-
+ sion numbers is unusual, but strives to be consistent. The magic
+ string ``rc'' equates to _r_e_l_e_a_s_e _c_a_n_d_i_d_a_t_e and sorts before a re-
+ lease. For example, _n_a_m_e_-_1_._3_r_c_3 will sort before _n_a_m_e_-_1_._3 and
+ after _n_a_m_e_-_1_._2_._9 In addition, alphabetic characters sort in the
+ same place as their numeric counterparts, so that _n_a_m_e_-_1_._2_e has
+ the same sorting value as _n_a_m_e_-_1_._2_._5 The magic string ``pl''
+ equates to a _p_a_t_c_h _l_e_v_e_l and has the same value as a dot in the
+ dewey-decimal ordering schemes.
+
+ --FF Interpret any pkg-name given as filename, and translate it to a
+ package name using the Package Database. This can be used to
+ query information on a per-file basis, e.g. in conjunction with
+ the --ee flag to find out which package a file belongs to.
+
+ --ff Show the packing list instructions for each package.
+
+ --II Show the index entry for each package.
+
+ --ii Show the install script (if any) for each package.
+
+ --kk Show the de-install script (if any) for each package.
+
+ --LL Show the files within each package. This is different from just
+ viewing the packing list, since full pathnames for everything are
+ generated.
+
+ --ll _s_t_r Prefix each information category header (see --qq) shown with _s_t_r.
+ This is primarily of use to front-end programs that want to re-
+ quest a lot of different information fields at once for a pack-
+ age, but don't necessary want the output intermingled in such a
+ way that they can't organize it. This lets you add a special to-
+ ken to the start of each field.
+
+ --mm Show the mtree file (if any) for each package.
+
+ --nn Show which packages each package needs (depends upon), if any.
+
+ --pp Show the installation prefix for each package.
+
+ --qq Be ``quiet'' in emitting report headers and such, just dump the
+ raw info (basically, assume a non-human reading).
+
+ --RR Show which packages are required by each package.
+
+ --rr Show the requirements script (if any) for each package.
+
+ --SS Show the size of this package and all the packages it requires,
+ in bytes.
+
+ --ss Show the size of this package in bytes. The size is calculated
+ by adding up the size of each file of the package.
+
+ --VV Print version number and exit.
+
+ --vv Turn on verbose output.
+
+EENNVVIIRROONNMMEENNTT
+ PKG_DBDIR The standard package database directory, _/_v_a_r_/_d_b_/_p_k_g, can be
+ overridden by specifying an alternative directory in the
+ PKG_DBDIR environment variable.
+
+ PKG_PATH This can be used to specify a semicolon-separated list of
+ paths and URLs to search for package files. If PKG_PATH is
+ used, the suffix _._t_g_z is automatically appended to the _p_k_g_-
+ _n_a_m_e, whereas searching in the current directory uses _p_k_g_-_n_a_m_e
+ literally.
+
+ PKG_TMPDIR, TMPDIR
+ These are tried in turn (if set) as candidate directories in
+ which to create a ``staging area'' for any files extracted by
+ ppkkgg__iinnffoo from package files. If neither PKG_TMPDIR nor TMPDIR
+ yields a suitable scratch directory, _/_v_a_r_/_t_m_p, _/_t_m_p, and
+ _/_u_s_r_/_t_m_p are tried in turn. Note that _/_u_s_r_/_t_m_p may be creat-
+ ed, if it doesn't already exist.
+
+ Since ppkkgg__iinnffoo requires very little information to be extract-
+ ed from any package files examined, it is unlikely that these
+ environment variables would ever need to be used to work
+ around limited available space in the default locations.
+
+TTEECCHHNNIICCAALL DDEETTAAIILLSS
+ Package info is either extracted from package files named on the command
+ line, or from already installed package information in _/_v_a_r_/_d_b_/_p_k_g_/_<_p_k_g_-
+ _n_a_m_e_>.
+
+ A filename can be given instead of a (installed) package name to query
+ information on the package this file belongs to. This filename is then
+ resolved to a package name using the Package Database. For this transla-
+ tion to take place, the --FF flag must be given. The filename must be ab-
+ solute, compare the output of pkg_info --aaFF.
+
+SSEEEE AALLSSOO
+ pkg_add(1), pkg_admin(1), pkg_create(1), pkg_delete(1), mktemp(3),
+ packages(7), mtree(8)
+
+AAUUTTHHOORRSS
+ Jordan Hubbard
+ most of the work
+ John Kohl
+ refined it for NetBSD
+ Hubert Feyrer
+ NetBSD wildcard dependency processing, pkgdb, depends displaying,
+ pkg size display etc.
+
+NetBSD 1.6 March 4, 1999 3
diff --git a/pkgtools/pkg_install/files/info/show.c b/pkgtools/pkg_install/files/info/show.c
new file mode 100644
index 00000000000..29c4b5a56cd
--- /dev/null
+++ b/pkgtools/pkg_install/files/info/show.c
@@ -0,0 +1,290 @@
+/* $NetBSD: show.c,v 1.1.1.1 2002/12/20 18:14:14 schmonz Exp $ */
+
+#if 0
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static const char *rcsid = "from FreeBSD Id: show.c,v 1.11 1997/10/08 07:47:38 charnier Exp";
+#else
+__RCSID("$NetBSD: show.c,v 1.1.1.1 2002/12/20 18:14:14 schmonz Exp $");
+#endif
+#endif
+#endif
+
+/*
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 23 Aug 1993
+ *
+ * Various display routines for the info module.
+ *
+ */
+/*
+ * Copyright (c) 1999 Hubert Feyrer. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Hubert Feyrer for
+ * the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#include "lib.h"
+#include "info.h"
+
+/* Structure to define entries for the "show table" */
+typedef struct show_t {
+ pl_ent_t sh_type; /* type of entry */
+ char *sh_quiet; /* message when quiet */
+ char *sh_verbose; /* message when verbose */
+} show_t;
+
+/*
+ * The entries in this table must be ordered the same as
+ * pl_ent_t constants
+ */
+static const show_t showv[] = {
+ {PLIST_FILE, "%s", "\tFile: %s"},
+ {PLIST_CWD, "@cwd %s", "\tCWD to: %s"},
+ {PLIST_CMD, "@exec %s", "\tEXEC '%s'"},
+ {PLIST_CHMOD, "@chmod %s", "\tCHMOD to %s"},
+ {PLIST_CHOWN, "@chown %s", "\tCHOWN to %s"},
+ {PLIST_CHGRP, "@chgrp %s", "\tCHGRP to %s"},
+ {PLIST_COMMENT, "@comment %s", "\tComment: %s"},
+ {PLIST_IGNORE, "@ignore", "Ignore next file:"},
+ {PLIST_NAME, "@name %s", "\tPackage name: %s"},
+ {PLIST_UNEXEC, "@unexec %s", "\tUNEXEC '%s'"},
+ {PLIST_SRC, "@src: %s", "\tSRC to: %s"},
+ {PLIST_DISPLAY, "@display %s", "\tInstall message file: %s"},
+ {PLIST_PKGDEP, "@pkgdep %s", "\tPackage depends on: %s"},
+ {PLIST_MTREE, "@mtree %s", "\tPackage mtree file: %s"},
+ {PLIST_DIR_RM, "@dirrm %s", "\tDeinstall directory remove: %s"},
+ {PLIST_IGNORE_INST, "@ignore_inst ??? doesn't belong here",
+ "\tIgnore next file installation directive (doesn't belong)"},
+ {PLIST_OPTION, "@option %s", "\tPackage has option: %s"},
+ {PLIST_PKGCFL, "@pkgcfl %s", "\tPackage conflicts with: %s"},
+ {PLIST_BLDDEP, "@blddep %s", "\tPackage depends exactly on: %s"},
+ {-1, NULL, NULL}
+};
+
+void
+show_file(char *title, char *fname)
+{
+ FILE *fp;
+ char line[1024];
+ int n;
+
+ if (!Quiet) {
+ printf("%s%s", InfoPrefix, title);
+ }
+ if ((fp = fopen(fname, "r")) == (FILE *) NULL) {
+ printf("ERROR: show_file: Can't open '%s' for reading!\n", fname);
+ } else {
+ int append_nl = 0;
+ while ((n = fread(line, 1, sizeof(line), fp)) != 0) {
+ fwrite(line, 1, n, stdout);
+ append_nl = (line[n - 1] != '\n');
+ }
+ (void) fclose(fp);
+ if (append_nl)
+ printf("\n");
+ }
+ printf("\n"); /* just in case */
+}
+
+void
+show_index(char *title, char *fname)
+{
+ FILE *fp;
+ char *line;
+ size_t linelen;
+ size_t maxline = termwidth;
+
+ if (!Quiet) {
+ printf("%s%s", InfoPrefix, title);
+ maxline -= MAXNAMESIZE;
+ }
+ if ((fp = fopen(fname, "r")) == (FILE *) NULL) {
+ warnx("show_file: can't open '%s' for reading", fname);
+ return;
+ }
+ if ((line = fgetln(fp, &linelen))) {
+ line[linelen - 1] = '\0'; /* tromp newline & terminate string */
+ if (termwidth && (linelen > maxline)) {
+ /* XXX -1 if term does NOT have xn (or xenl) quirk */
+ line[maxline] = '\0';
+ }
+ (void) printf("%s\n", line);
+ }
+ (void) fclose(fp);
+}
+
+/*
+ * Show a packing list item type. If type is PLIST_SHOW_ALL, show all
+ */
+void
+show_plist(char *title, package_t *plist, pl_ent_t type)
+{
+ plist_t *p;
+ Boolean ign;
+
+ if (!Quiet) {
+ printf("%s%s", InfoPrefix, title);
+ }
+ for (ign = FALSE, p = plist->head; p; p = p->next) {
+ if (p->type == type || type == PLIST_SHOW_ALL) {
+ switch (p->type) {
+ case PLIST_FILE:
+ printf(Quiet ? showv[p->type].sh_quiet : showv[p->type].sh_verbose, p->name);
+ if (ign) {
+ if (!Quiet) {
+ printf(" (ignored)");
+ }
+ ign = FALSE;
+ }
+ break;
+ case PLIST_CHMOD:
+ case PLIST_CHOWN:
+ case PLIST_CHGRP:
+ printf(Quiet ? showv[p->type].sh_quiet : showv[p->type].sh_verbose,
+ p->name ? p->name : "(clear default)");
+ break;
+ case PLIST_IGNORE:
+ printf(Quiet ? showv[p->type].sh_quiet : showv[p->type].sh_verbose);
+ ign = TRUE;
+ break;
+ case PLIST_IGNORE_INST:
+ printf(Quiet ? showv[p->type].sh_quiet : showv[p->type].sh_verbose, p->name);
+ ign = TRUE;
+ break;
+ case PLIST_CWD:
+ case PLIST_CMD:
+ case PLIST_SRC:
+ case PLIST_UNEXEC:
+ case PLIST_COMMENT:
+ case PLIST_NAME:
+ case PLIST_DISPLAY:
+ case PLIST_PKGDEP:
+ case PLIST_MTREE:
+ case PLIST_DIR_RM:
+ case PLIST_OPTION:
+ case PLIST_PKGCFL:
+ case PLIST_BLDDEP:
+ printf(Quiet ? showv[p->type].sh_quiet : showv[p->type].sh_verbose, p->name);
+ break;
+ default:
+ warnx("unknown command type %d (%s)", p->type, p->name);
+ }
+ (void) fputc('\n', stdout);
+ }
+ }
+}
+
+/*
+ * Show all files in the packing list (except ignored ones)
+ */
+void
+show_files(char *title, package_t *plist)
+{
+ plist_t *p;
+ Boolean ign;
+ char *dir = ".";
+
+ if (!Quiet) {
+ printf("%s%s", InfoPrefix, title);
+ }
+ for (ign = FALSE, p = plist->head; p; p = p->next) {
+ switch (p->type) {
+ case PLIST_FILE:
+ if (!ign) {
+ printf("%s/%s\n", dir, p->name);
+ }
+ ign = FALSE;
+ break;
+ case PLIST_CWD:
+ dir = p->name;
+ break;
+ case PLIST_IGNORE:
+ ign = TRUE;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+/*
+ * Show dependencies (packages this pkg requires)
+ */
+void
+show_depends(char *title, package_t *plist)
+{
+ plist_t *p;
+ int nodepends;
+
+ nodepends = 1;
+ for (p = plist->head; p && nodepends; p = p->next) {
+ switch (p->type) {
+ case PLIST_PKGDEP:
+ nodepends = 0;
+ break;
+ default:
+ break;
+ }
+ }
+ if (nodepends)
+ return;
+
+ if (!Quiet) {
+ printf("%s%s", InfoPrefix, title);
+ }
+ for (p = plist->head; p; p = p->next) {
+ switch (p->type) {
+ case PLIST_PKGDEP:
+ printf("%s\n", p->name);
+ break;
+ default:
+ break;
+ }
+ }
+
+ printf("\n");
+}
diff --git a/pkgtools/pkg_install/files/install-sh b/pkgtools/pkg_install/files/install-sh
new file mode 100755
index 00000000000..89fc9b098b8
--- /dev/null
+++ b/pkgtools/pkg_install/files/install-sh
@@ -0,0 +1,238 @@
+#! /bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+tranformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ true
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ else
+ instcmd=mkdir
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ true
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ true
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ true
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ true
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ true
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
diff --git a/pkgtools/pkg_install/files/lib/Makefile.in b/pkgtools/pkg_install/files/lib/Makefile.in
new file mode 100644
index 00000000000..102f099345e
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/Makefile.in
@@ -0,0 +1,38 @@
+# Based on NetBSD: Makefile,v 1.17 2001/12/12 01:48:54 tv Exp
+# Original from FreeBSD, no rcs id.
+
+RANLIB= @RANLIB@
+AR= @AR@
+CC= @CC@
+CCLD= $(CC)
+LIBS= @LIBS@ -linstall
+CPPFLAGS= @CPPFLAGS@
+DEFS= @DEFS@ -I. -I@srcdir@
+CFLAGS= @CFLAGS@
+LDFLAGS= @LDFLAGS@ -L../lib
+
+LINK= $(CCLD) $(CFLAGS) $(LDFLAGS) -o $@
+COMPILE= $(CC) $(DEFS) $(CPPFLAGS) $(CFLAGS)
+
+LIBINSTALL= libinstall.a
+
+SRCS= digest.c exec.c file.c fgetln.c ftpio.c global.c lpkg.c \
+ pen.c pkgdb.c plist.c str.c version.c path.c \
+ err.c setprogname.c setenv.c unsetenv.c
+OBJS= digest.o exec.o file.o fgetln.o ftpio.o global.o lpkg.o \
+ pen.o pkgdb.o plist.o str.o version.o path.o \
+ err.o setprogname.o setenv.o unsetenv.o
+
+libinstall.a: ${OBJS}
+ ${AR} crv ${LIBINSTALL} ${OBJS}
+ ${RANLIB} ${LIBINSTALL}
+
+version.o: version.h version.c
+
+.c.o:
+ $(COMPILE) -c $< -o $@
+
+clean:
+ rm -f ${OBJS} ${LIBINSTALL}
+
+install:
diff --git a/pkgtools/pkg_install/files/lib/config.h.in b/pkgtools/pkg_install/files/lib/config.h.in
new file mode 100644
index 00000000000..1d52c9fa8b5
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/config.h.in
@@ -0,0 +1,169 @@
+/* lib/config.h.in. Generated automatically from configure.in by autoheader. */
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if you have the MD5File function. */
+#undef HAVE_MD5FILE
+
+/* Define if you have the chflags function. */
+#undef HAVE_CHFLAGS
+
+/* Define if you have the dbopen function. */
+#undef HAVE_DBOPEN
+
+/* Define if you have the err function. */
+#undef HAVE_ERR
+
+/* Define if you have the errx function. */
+#undef HAVE_ERRX
+
+/* Define if you have the fgetln function. */
+#undef HAVE_FGETLN
+
+/* Define if you have the getprogname function. */
+#undef HAVE_GETPROGNAME
+
+/* Define if you have the mkdtemp function. */
+#undef HAVE_MKDTEMP
+
+/* Define if you have the setenv function. */
+#undef HAVE_SETENV
+
+/* Define if you have the setprogname function. */
+#undef HAVE_SETPROGNAME
+
+/* Define if you have the statfs function. */
+#undef HAVE_STATFS
+
+/* Define if you have the statvfs function. */
+#undef HAVE_STATVFS
+
+/* Define if you have the strlcpy function. */
+#undef HAVE_STRLCPY
+
+/* Define if you have the strsep function. */
+#undef HAVE_STRSEP
+
+/* Define if you have the unsetenv function. */
+#undef HAVE_UNSETENV
+
+/* Define if you have the warn function. */
+#undef HAVE_WARN
+
+/* Define if you have the warnx function. */
+#undef HAVE_WARNX
+
+/* Define if you have the <assert.h> header file. */
+#undef HAVE_ASSERT_H
+
+/* Define if you have the <db.h> header file. */
+#undef HAVE_DB_H
+
+/* Define if you have the <db1/db.h> header file. */
+#undef HAVE_DB1_DB_H
+
+/* Define if you have the <dirent.h> header file. */
+#undef HAVE_DIRENT_H
+
+/* Define if you have the <err.h> header file. */
+#undef HAVE_ERR_H
+
+/* Define if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the <fnmatch.h> header file. */
+#undef HAVE_FNMATCH_H
+
+/* Define if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <md5.h> header file. */
+#undef HAVE_MD5_H
+
+/* Define if you have the <md5global.h> header file. */
+#undef HAVE_MD5GLOBAL_H
+
+/* Define if you have the <netdb.h> header file. */
+#undef HAVE_NETDB_H
+
+/* Define if you have the <pwd.h> header file. */
+#undef HAVE_PWD_H
+
+/* Define if you have the <regex.h> header file. */
+#undef HAVE_REGEX_H
+
+/* Define if you have the <signal.h> header file. */
+#undef HAVE_SIGNAL_H
+
+/* Define if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define if you have the <sys/ioctl.h> header file. */
+#undef HAVE_SYS_IOCTL_H
+
+/* Define if you have the <sys/mount.h> header file. */
+#undef HAVE_SYS_MOUNT_H
+
+/* Define if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define if you have the <sys/queue.h> header file. */
+#undef HAVE_SYS_QUEUE_H
+
+/* Define if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
+
+/* Define if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define if you have the <sys/vfs.h> header file. */
+#undef HAVE_SYS_VFS_H
+
+/* Define if you have the <sys/wait.h> header file. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define if you have the <termios.h> header file. */
+#undef HAVE_TERMIOS_H
+
+/* Define if you have the <time.h> header file. */
+#undef HAVE_TIME_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the <vis.h> header file. */
+#undef HAVE_VIS_H
+
+/* Define if you have the db1 library (-ldb1). */
+#undef HAVE_LIBDB1
+
+/* Define if you have the md library (-lmd). */
+#undef HAVE_LIBMD
+
+#ifndef HAVE___ATTRIBUTE__
+# define __attribute__(x)
+#endif
+
+#ifndef HAVE_GETPROGNAME
+const char *getprogname(void);
+#endif
+
diff --git a/pkgtools/pkg_install/files/lib/defs.h b/pkgtools/pkg_install/files/lib/defs.h
new file mode 100644
index 00000000000..0a076049242
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/defs.h
@@ -0,0 +1,92 @@
+/* $NetBSD: defs.h,v 1.1.1.1 2002/12/20 18:13:59 schmonz Exp $ */
+
+/*
+ * Copyright (c) 1999-2000 Alistair G. Crooks. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Alistair G. Crooks.
+ * 4. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef DEFS_H_
+#define DEFS_H_
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#define NEWARRAY(type,ptr,size,where,action) do { \
+ if ((ptr = (type *) calloc(sizeof(type), (unsigned)(size))) == NULL) { \
+ warn("%s: can't allocate %lu bytes", where, \
+ (unsigned long)(size * sizeof(type))); \
+ action; \
+ } \
+} while( /* CONSTCOND */ 0)
+
+#define RENEW(type,ptr,size,where,action) do { \
+ type *newptr; \
+ if ((newptr = (type *) realloc(ptr, sizeof(type) * (size))) == NULL) { \
+ warn("%s: can't realloc %lu bytes", where, \
+ (unsigned long)(size * sizeof(type))); \
+ action; \
+ } \
+ ptr = newptr; \
+} while( /* CONSTCOND */ 0)
+
+#define NEW(type, ptr, where, action) NEWARRAY(type, ptr, 1, where, action)
+
+#define FREE(ptr) (void) free(ptr)
+
+#define ALLOC(type, v, size, c, init, where, action) do { \
+ if (size == 0) { \
+ size = init; \
+ NEWARRAY(type, v, size, where ": new", action); \
+ } else if (c == size) { \
+ size *= 2; \
+ RENEW(type, v, size, where ": renew", action); \
+ } \
+} while( /* CONSTCOND */ 0)
+
+#ifndef MIN
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef MAX
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+
+#ifndef ABS
+#define ABS(a) (((a) < 0) ? -(a) : (a))
+#endif
+
+#define STRNCPY(to, from, size) do { \
+ (void) strncpy(to, from, size); \
+ to[(size) - 1] = 0; \
+} while( /* CONSTCOND */ 0)
+
+#endif /* !DEFS_H_ */
diff --git a/pkgtools/pkg_install/files/lib/digest.c b/pkgtools/pkg_install/files/lib/digest.c
new file mode 100644
index 00000000000..53a623796fc
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/digest.c
@@ -0,0 +1,90 @@
+/* $NetBSD: digest.c,v 1.1.1.1 2002/12/20 18:13:59 schmonz Exp $ */
+
+/*
+ * Copyright (c) 2002 Alistair G. Crooks. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Alistair G. Crooks.
+ * 4. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#if 0
+#include <sys/cdefs.h>
+
+#ifndef lint
+__COPYRIGHT("@(#) Copyright (c) 2002 \
+ The NetBSD Foundation, Inc. All rights reserved.");
+__RCSID("$NetBSD: digest.c,v 1.1.1.1 2002/12/20 18:13:59 schmonz Exp $");
+#endif
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <unistd.h>
+
+#include "lib.h"
+
+#ifndef HAVE_MD5FILE
+
+#define _MD5_ASCII_BUF_SIZE 33
+
+char *
+MD5File(char *filename, char *buf)
+{
+ char cmd[1024];
+ char in[1024];
+ FILE *pp;
+ char *cp;
+
+ (void) snprintf(cmd, sizeof(cmd), "%s md5 %s", DIGEST, filename);
+ if ((pp = popen(cmd, "r")) == NULL) {
+ warn("MD5File: can't popen `%s'", cmd);
+ return NULL;
+ }
+ if (fgets(in, sizeof(in), pp) == NULL) {
+ warn("MD5File: can't read from `%s'", cmd);
+ (void) pclose(pp);
+ return NULL;
+ }
+ (void) pclose(pp);
+ cp = strrchr(in, ' ');
+ (void) strcpy(buf, cp + 1);
+ buf[_MD5_ASCII_BUF_SIZE - 1] = 0;
+ return buf;
+}
+#endif
diff --git a/pkgtools/pkg_install/files/lib/err.c b/pkgtools/pkg_install/files/lib/err.c
new file mode 100644
index 00000000000..fc3a007097a
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/err.c
@@ -0,0 +1,108 @@
+/* $Id: err.c,v 1.1.1.1 2002/12/20 18:14:06 schmonz Exp $ */
+
+/*
+ * Copyright 1997-2000 Luke Mewburn <lukem@netbsd.org>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef HAVE_ERR
+void
+err(int eval, const char *fmt, ...)
+{
+ va_list ap;
+ int sverrno;
+
+ sverrno = errno;
+ (void)fprintf(stderr, "%s: ", getprogname());
+ va_start(ap, fmt);
+ if (fmt != NULL) {
+ (void)vfprintf(stderr, fmt, ap);
+ (void)fprintf(stderr, ": ");
+ }
+ va_end(ap);
+ (void)fprintf(stderr, "%s\n", strerror(sverrno));
+ exit(eval);
+}
+#endif
+
+#ifndef HAVE_ERRX
+void
+errx(int eval, const char *fmt, ...)
+{
+ va_list ap;
+
+ (void)fprintf(stderr, "%s: ", getprogname());
+ va_start(ap, fmt);
+ if (fmt != NULL)
+ (void)vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ (void)fprintf(stderr, "\n");
+ exit(eval);
+}
+#endif
+
+#ifndef HAVE_WARN
+void
+warn(const char *fmt, ...)
+{
+ va_list ap;
+ int sverrno;
+
+ sverrno = errno;
+ (void)fprintf(stderr, "%s: ", getprogname());
+ va_start(ap, fmt);
+ if (fmt != NULL) {
+ (void)vfprintf(stderr, fmt, ap);
+ (void)fprintf(stderr, ": ");
+ }
+ va_end(ap);
+ (void)fprintf(stderr, "%s\n", strerror(sverrno));
+}
+#endif
+
+#ifndef HAVE_WARNX
+void
+warnx(const char *fmt, ...)
+{
+ va_list ap;
+
+ (void)fprintf(stderr, "%s: ", getprogname());
+ va_start(ap, fmt);
+ if (fmt != NULL)
+ (void)vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ (void)fprintf(stderr, "\n");
+}
+#endif
diff --git a/pkgtools/pkg_install/files/lib/exec.c b/pkgtools/pkg_install/files/lib/exec.c
new file mode 100644
index 00000000000..a7a3af172f8
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/exec.c
@@ -0,0 +1,75 @@
+/* $NetBSD: exec.c,v 1.1.1.1 2002/12/20 18:13:59 schmonz Exp $ */
+
+#if 0
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static const char *rcsid = "from FreeBSD Id: exec.c,v 1.6 1997/10/08 07:47:50 charnier Exp";
+#else
+__RCSID("$NetBSD: exec.c,v 1.1.1.1 2002/12/20 18:13:59 schmonz Exp $");
+#endif
+#endif
+#endif
+
+/*
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 18 July 1993
+ *
+ * Miscellaneous system routines.
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#include "lib.h"
+
+/*
+ * Unusual system() substitute. Accepts format string and args,
+ * builds and executes command. Returns exit code.
+ */
+int
+vsystem(const char *fmt,...)
+{
+ va_list args;
+ char *cmd;
+ size_t maxargs;
+ int ret;
+
+ maxargs = (size_t) sysconf(_SC_ARG_MAX);
+ maxargs -= 32; /* some slop for the sh -c */
+ if ((cmd = (char *) malloc(maxargs)) == (char *) NULL) {
+ warnx("vsystem can't alloc arg space");
+ return 1;
+ }
+
+ va_start(args, fmt);
+ if (vsnprintf(cmd, maxargs, fmt, args) >= maxargs) {
+ warnx("vsystem args are too long");
+ va_end(args);
+ return 1;
+ }
+#ifdef VSYSTEM_DEBUG
+ printf("vsystem(\"%s\")\n", cmd);
+#endif
+ ret = system(cmd);
+ va_end(args);
+ free(cmd);
+ return ret;
+}
diff --git a/pkgtools/pkg_install/files/lib/fgetln.c b/pkgtools/pkg_install/files/lib/fgetln.c
new file mode 100644
index 00000000000..fb8f6cbffc5
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/fgetln.c
@@ -0,0 +1,88 @@
+/* $Id: fgetln.c,v 1.1.1.1 2002/12/20 18:13:59 schmonz Exp $ */
+
+/*
+ * Copyright 1999 Luke Mewburn <lukem@netbsd.org>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef HAVE_FGETLN
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <unistd.h>
+
+#define BUFCHUNKS BUFSIZ
+
+char *
+fgetln(FILE *fp, size_t *len)
+{
+ static char *buf;
+ static size_t bufsize;
+ size_t buflen;
+ char curbuf[BUFCHUNKS];
+ char *p;
+
+ if (buf == NULL) {
+ bufsize = BUFCHUNKS;
+ buf = (char *)malloc(bufsize);
+ if (buf == NULL)
+ err(1, "Unable to allocate buffer for fgetln()");
+ }
+
+ *buf = '\0';
+ buflen = 0;
+ while ((p = fgets(curbuf, sizeof(curbuf), fp)) != NULL) {
+ size_t l;
+
+ l = strlen(p);
+ if (bufsize < buflen + l) {
+ bufsize += BUFCHUNKS;
+ if ((buf = (char *)realloc(buf, bufsize)) == NULL)
+ err(1, "Unable to allocate %ld bytes of memory",
+ (long)bufsize);
+ }
+ strcpy(buf + buflen, p);
+ buflen += l;
+ if (p[l - 1] == '\n')
+ break;
+ }
+ if (p == NULL && *buf == '\0')
+ return (NULL);
+ *len = strlen(buf);
+ return (buf);
+}
+#endif
diff --git a/pkgtools/pkg_install/files/lib/file.c b/pkgtools/pkg_install/files/lib/file.c
new file mode 100644
index 00000000000..96a71b4b376
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/file.c
@@ -0,0 +1,634 @@
+/* $NetBSD: file.c,v 1.1.1.1 2002/12/20 18:14:00 schmonz Exp $ */
+
+#if 0
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static const char *rcsid = "from FreeBSD Id: file.c,v 1.29 1997/10/08 07:47:54 charnier Exp";
+#else
+__RCSID("$NetBSD: file.c,v 1.1.1.1 2002/12/20 18:14:00 schmonz Exp $");
+#endif
+#endif
+#endif
+
+/*
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 18 July 1993
+ *
+ * Miscellaneous file access utilities.
+ *
+ */
+
+#include "lib.h"
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#ifdef HAVE_ASSERT_H
+#include <assert.h>
+#endif
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+
+/*
+ * Quick check to see if a file (or dir ...) exists
+ */
+Boolean
+fexists(const char *fname)
+{
+ struct stat dummy;
+ if (!lstat(fname, &dummy))
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * Quick check to see if something is a directory
+ */
+Boolean
+isdir(const char *fname)
+{
+ struct stat sb;
+
+ if (lstat(fname, &sb) != FAIL && S_ISDIR(sb.st_mode))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/*
+ * Check if something is a link to a directory
+ */
+Boolean
+islinktodir(const char *fname)
+{
+ struct stat sb;
+
+ if (lstat(fname, &sb) != FAIL && S_ISLNK(sb.st_mode)) {
+ if (stat(fname, &sb) != FAIL && S_ISDIR(sb.st_mode))
+ return TRUE; /* link to dir! */
+ else
+ return FALSE; /* link to non-dir */
+ } else
+ return FALSE; /* non-link */
+}
+
+/*
+ * Check to see if file is a dir, and is empty
+ */
+Boolean
+isemptydir(const char *fname)
+{
+ if (isdir(fname) || islinktodir(fname)) {
+ DIR *dirp;
+ struct dirent *dp;
+
+ dirp = opendir(fname);
+ if (!dirp)
+ return FALSE; /* no perms, leave it alone */
+ for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
+ if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
+ closedir(dirp);
+ return FALSE;
+ }
+ }
+ (void) closedir(dirp);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * Check if something is a regular file
+ */
+Boolean
+isfile(const char *fname)
+{
+ struct stat sb;
+ if (stat(fname, &sb) != FAIL && S_ISREG(sb.st_mode))
+ return TRUE;
+ 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(const char *fname)
+{
+ struct stat sb;
+ if (stat(fname, &sb) != FAIL && S_ISREG(sb.st_mode)) {
+ if (sb.st_size != 0)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* This struct defines the leading part of a valid URL name */
+typedef struct url_t {
+ char *u_s; /* the leading part of the URL */
+ int u_len; /* its length */
+} url_t;
+
+/* A table of valid leading strings for URLs */
+static const url_t urls[] = {
+ {"ftp://", 6},
+ {"http://", 7},
+ {NULL}
+};
+
+/*
+ * Returns length of leading part of any URL from urls table, or -1
+ */
+int
+URLlength(const char *fname)
+{
+ const url_t *up;
+ int i;
+
+ if (fname != (char *) NULL) {
+ for (i = 0; isspace((unsigned char) *fname); i++) {
+ fname++;
+ }
+ for (up = urls; up->u_s; up++) {
+ if (strncmp(fname, up->u_s, up->u_len) == 0) {
+ return i + up->u_len; /* ... + sizeof(up->u_s); - HF */
+ }
+ }
+ }
+ return -1;
+}
+
+/*
+ * Returns the host part of a URL
+ */
+const char *
+fileURLHost(const char *fname, char *where, int max)
+{
+ const char *ret;
+ int i;
+
+ assert(where != NULL);
+ assert(max > 0);
+
+ if ((i = URLlength(fname)) < 0) { /* invalid URL? */
+ errx(1, "fileURLhost called with a bad URL: `%s'", fname);
+ }
+ fname += i;
+ /* Do we have a place to stick our work? */
+ ret = where;
+ while (*fname && *fname != '/' && --max)
+ *where++ = *fname++;
+ *where = '\0';
+
+ return ret;
+}
+
+/*
+ * Returns the filename part of a URL
+ */
+const char *
+fileURLFilename(const char *fname, char *where, int max)
+{
+ const char *ret;
+ int i;
+
+ assert(where != NULL);
+ assert(max > 0);
+
+ if ((i = URLlength(fname)) < 0) { /* invalid URL? */
+ errx(1, "fileURLFilename called with a bad URL: `%s'", fname);
+ }
+ fname += i;
+ /* Do we have a place to stick our work? */
+ ret = where;
+ while (*fname && *fname != '/')
+ ++fname;
+ if (*fname == '/') {
+ while (*fname && --max)
+ *where++ = *fname++;
+ }
+ *where = '\0';
+
+ return ret;
+}
+
+/*
+ * Try and fetch a file by URL, returning the directory name for where
+ * it's unpacked, if successful. To be handed to leave_playpen() later.
+ */
+char *
+fileGetURL(const char *spec)
+{
+ char host[MAXHOSTNAMELEN], file[FILENAME_MAX];
+ const char *cp;
+ char *rp;
+ char pen[FILENAME_MAX];
+ int rc;
+
+ rp = NULL;
+ if (!IS_URL(spec)) {
+ errx(1, "fileGetURL was called with non-url arg '%s'", spec);
+ }
+
+ /* Some sanity checks on the URL */
+ cp = fileURLHost(spec, host, MAXHOSTNAMELEN);
+ if (!*cp) {
+ warnx("URL `%s' has bad host part!", spec);
+ return NULL;
+ }
+ cp = fileURLFilename(spec, file, FILENAME_MAX);
+ if (!*cp) {
+ warnx("URL `%s' has bad filename part!", spec);
+ return NULL;
+ }
+
+ if (Verbose)
+ printf("Trying to fetch %s.\n", spec);
+
+ pen[0] = '\0';
+ rp = make_playpen(pen, sizeof(pen), 0);
+ if (rp == NULL) {
+ printf("Error: Unable to construct a new playpen for FTP!\n");
+ return NULL;
+ }
+
+ rp = strdup(pen);
+ rc = unpackURL(spec, pen);
+ if (rc < 0) {
+ leave_playpen(rp); /* Don't leave dir hang around! */
+
+ printf("Error on unpackURL('%s', '%s')\n", spec, pen);
+ return NULL;
+ }
+ return rp;
+}
+
+static char *
+resolvepattern1(const char *name)
+{
+ static char tmp[FILENAME_MAX];
+ char *cp;
+
+ if (IS_URL(name)) {
+ /* some package depends on a wildcard pkg */
+ int rc;
+
+ rc = expandURL(tmp, name);
+ if (rc < 0) {
+ return NULL;
+ }
+ if (Verbose)
+ printf("'%s' expanded to '%s'\n", name, tmp);
+ return tmp; /* return expanded URL w/ corrent pkg */
+ }
+ else if (ispkgpattern(name)) {
+ cp = findbestmatchingname(
+ dirname_of(name), basename_of(name));
+ if (cp) {
+ snprintf(tmp, sizeof(tmp), "%s/%s", dirname_of(name), cp);
+ free(cp);
+ return tmp;
+ }
+ } else {
+ if (isfile(name)) {
+ strlcpy(tmp, name, sizeof(tmp));
+ return tmp;
+ }
+ }
+
+ return NULL;
+}
+
+static char *
+resolvepattern(const char *name)
+{
+ char tmp[FILENAME_MAX];
+ char *cp;
+ const char *suf;
+
+ cp = resolvepattern1(name);
+ if (cp != NULL)
+ return cp;
+
+ if (ispkgpattern(name))
+ return NULL;
+
+ suf = suffix_of(name);
+ if (!strcmp(suf, "tbz") || !strcmp(suf, "tgz"))
+ return NULL;
+
+ /* add suffix and try */
+ snprintf(tmp, sizeof(tmp), "%s.tbz", name);
+ cp = resolvepattern1(tmp);
+ if (cp != NULL)
+ return cp;
+ snprintf(tmp, sizeof(tmp), "%s.tgz", name);
+ cp = resolvepattern1(tmp);
+ if (cp != NULL)
+ return cp;
+
+ /* add version number wildcard and try */
+ snprintf(tmp, sizeof(tmp), "%s-[0-9]*.t[bg]z", name);
+ return resolvepattern1(tmp);
+}
+
+/*
+ * Look for filename/pattern "fname" in
+ * Returns a full path/URL where the pkg can be found
+ */
+char *
+fileFindByPath(const char *fname)
+{
+ char tmp[FILENAME_MAX];
+ struct path *path;
+
+ /*
+ * 1. if fname is an absolute pathname or a url,
+ * just use it.
+ */
+ if (IS_FULLPATH(fname) || IS_URL(fname))
+ return resolvepattern(fname);
+
+ /*
+ * 2. otherwise, use PKG_PATH.
+ */
+ TAILQ_FOREACH(path, &PkgPath, pl_entry) {
+ char *cp;
+ const char *cp2 = path->pl_path;
+
+ if (Verbose)
+ printf("trying PKG_PATH %s\n", cp2);
+
+ if (IS_FULLPATH(cp2) || IS_URL(cp2)) {
+ snprintf(tmp, sizeof(tmp), "%s/%s", cp2, fname);
+ }
+ else {
+ char cwdtmp[MAXPATHLEN];
+ if (getcwd(cwdtmp, sizeof(cwdtmp)) == NULL)
+ errx(1, "getcwd");
+ snprintf(tmp, sizeof(tmp), "%s/%s/%s", cwdtmp, cp2, fname);
+ }
+ cp = resolvepattern(tmp);
+ if (cp)
+ return cp;
+ }
+
+#if 0
+ /*
+ * 3. finally, search current directory.
+ */
+ snprintf(tmp, sizeof(tmp), "./%s", fname);
+ return resolvepattern(tmp);
+#else
+ return NULL;
+#endif
+}
+
+/*
+ * Expect "fname" to point at a file, and read it into
+ * the buffer returned.
+ */
+char *
+fileGetContents(char *fname)
+{
+ char *contents;
+ struct stat sb;
+ int fd;
+
+ if (stat(fname, &sb) == FAIL) {
+ cleanup(0);
+ errx(2, "can't stat '%s'", fname);
+ }
+
+ contents = (char *) malloc((size_t) (sb.st_size) + 1);
+ fd = open(fname, O_RDONLY, 0);
+ if (fd == FAIL) {
+ cleanup(0);
+ errx(2, "unable to open '%s' for reading", fname);
+ }
+ if (read(fd, contents, (size_t) sb.st_size) != (size_t) sb.st_size) {
+ cleanup(0);
+ errx(2, "short read on '%s' - did not get %lld bytes",
+ fname, (long long) sb.st_size);
+ }
+ close(fd);
+ contents[(size_t) sb.st_size] = '\0';
+ return contents;
+}
+
+/*
+ * Takes a filename and package name, returning (in "try") the canonical
+ * "preserve" name for it.
+ */
+Boolean
+make_preserve_name(char *try, size_t max, char *name, char *file)
+{
+ int len, i;
+
+ if ((len = strlen(file)) == 0)
+ return FALSE;
+ else
+ i = len - 1;
+ strncpy(try, file, max);
+ if (try[i] == '/') /* Catch trailing slash early and save checking in the loop */
+ --i;
+ for (; i; i--) {
+ if (try[i] == '/') {
+ try[i + 1] = '.';
+ strncpy(&try[i + 2], &file[i + 1], max - i - 2);
+ break;
+ }
+ }
+ if (!i) {
+ try[0] = '.';
+ strncpy(try + 1, file, max - 1);
+ }
+ /* I should probably be called rude names for these inline assignments */
+ strncat(try, ".", max -= strlen(try));
+ strncat(try, name, max -= strlen(name));
+ strncat(try, ".", max--);
+ strncat(try, "backup", max -= 6);
+ return TRUE;
+}
+
+/*
+ * Write the contents of "str" to a file
+ */
+void
+write_file(char *name, char *str)
+{
+ size_t len;
+ FILE *fp;
+
+ if ((fp = fopen(name, "w")) == (FILE *) NULL) {
+ cleanup(0);
+ errx(2, "cannot fopen '%s' for writing", name);
+ }
+ len = strlen(str);
+ if (fwrite(str, 1, len, fp) != len) {
+ cleanup(0);
+ errx(2, "short fwrite on '%s', tried to write %ld bytes",
+ name, (long) len);
+ }
+ if (fclose(fp)) {
+ cleanup(0);
+ errx(2, "failure to fclose '%s'", name);
+ }
+}
+
+void
+copy_file(char *dir, char *fname, char *to)
+{
+ char cmd[FILENAME_MAX];
+
+ if (fname[0] == '/')
+ (void) snprintf(cmd, sizeof(cmd), "cp -r %s %s", fname, to);
+ else
+ (void) snprintf(cmd, sizeof(cmd), "cp -r %s/%s %s", dir, fname, to);
+ if (vsystem("%s", cmd)) {
+ cleanup(0);
+ errx(2, "could not perform '%s'", cmd);
+ }
+}
+
+void
+move_file(char *dir, char *fname, char *to)
+{
+ char cmd[FILENAME_MAX];
+
+ if (fname[0] == '/')
+ (void) snprintf(cmd, sizeof(cmd), "mv %s %s", fname, to);
+ else
+ (void) snprintf(cmd, sizeof(cmd), "mv %s/%s %s", dir, fname, to);
+ if (vsystem("%s", cmd)) {
+ cleanup(0);
+ errx(2, "could not perform '%s'", cmd);
+ }
+}
+
+/*
+ * Unpack a tar file
+ */
+int
+unpack(const char *pkg, const char *flist)
+{
+ char args[10] = "-";
+ char *cp;
+
+ /*
+ * Figure out by a crude heuristic whether this or not this is probably
+ * compressed.
+ */
+ if (!IS_STDIN(pkg)) {
+ cp = strrchr(pkg, '.');
+ if (cp) {
+ cp++;
+ if (strchr(cp, 'z') || strchr(cp, 'Z'))
+ strcat(args, "z");
+ }
+ } else
+ strcat(args, "z");
+ strcat(args, "xpf");
+ if (vsystem("%s %s %s %s", TAR_FULLPATHNAME, args, pkg, flist ? flist : "")) {
+ warnx("%s extract of %s failed!", TAR_FULLPATHNAME, pkg);
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Using fmt, replace all instances of:
+ *
+ * %F With the parameter "name"
+ * %D With the parameter "dir"
+ * %B Return the directory part ("base") of %D/%F
+ * %f Return the filename part of %D/%F
+ *
+ * Check that no overflows can occur.
+ */
+void
+format_cmd(char *buf, size_t size, char *fmt, char *dir, char *name)
+{
+ char scratch[FILENAME_MAX * 2];
+ char *bufp;
+ char *cp;
+
+ for (bufp = buf; (int) (bufp - buf) < size && *fmt;) {
+ if (*fmt == '%') {
+ switch (*++fmt) {
+ case 'F':
+ strnncpy(bufp, size - (int) (bufp - buf), name, strlen(name));
+ bufp += strlen(bufp);
+ break;
+
+ case 'D':
+ strnncpy(bufp, size - (int) (bufp - buf), dir, strlen(dir));
+ bufp += strlen(bufp);
+ break;
+
+ case 'B':
+ (void) snprintf(scratch, sizeof(scratch), "%s/%s", dir, name);
+ if ((cp = strrchr(scratch, '/')) == (char *) NULL) {
+ cp = scratch;
+ }
+ strnncpy(bufp, size - (int) (bufp - buf), scratch, (size_t) (cp - scratch));
+ bufp += strlen(bufp);
+ break;
+
+ case 'f':
+ (void) snprintf(scratch, sizeof(scratch), "%s/%s", dir, name);
+ if ((cp = strrchr(scratch, '/')) == (char *) NULL) {
+ cp = scratch;
+ } else {
+ cp++;
+ }
+ strnncpy(bufp, size - (int) (bufp - buf), cp, strlen(cp));
+ bufp += strlen(bufp);
+ break;
+
+ default:
+ *bufp++ = '%';
+ *bufp++ = *fmt;
+ break;
+ }
+ ++fmt;
+ } else {
+ *bufp++ = *fmt++;
+ }
+ }
+ *bufp = '\0';
+}
diff --git a/pkgtools/pkg_install/files/lib/ftpio.c b/pkgtools/pkg_install/files/lib/ftpio.c
new file mode 100644
index 00000000000..02e6339ee9f
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/ftpio.c
@@ -0,0 +1,943 @@
+/* $NetBSD: ftpio.c,v 1.1.1.1 2002/12/20 18:14:01 schmonz Exp $ */
+
+#if 0
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: ftpio.c,v 1.1.1.1 2002/12/20 18:14:01 schmonz Exp $");
+#endif
+#endif
+
+/*
+ * Copyright (c) 1999 Hubert Feyrer. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Hubert Feyrer for
+ * the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#ifdef HAVE_ASSERT_H
+#include <assert.h>
+#endif
+
+#include <ctype.h>
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#include <errno.h>
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_REGEX_H
+#include <regex.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef EXPECT_DEBUG
+#ifdef HAVE_VIS_H
+#include <vis.h>
+#endif
+#endif
+
+#include "../lib/lib.h"
+
+/*
+ * Names of environment variables used to pass things to
+ * subprocesses, for connection caching.
+ */
+#define PKG_FTPIO_COMMAND "PKG_FTPIO_COMMAND"
+#define PKG_FTPIO_ANSWER "PKG_FTPIO_ANSWER"
+#define PKG_FTPIO_CNT "PKG_FTPIO_CNT"
+#define PKG_FTPIO_CURRENTHOST "PKG_FTPIO_CURRENTHOST"
+#define PKG_FTPIO_CURRENTDIR "PKG_FTPIO_CURRENTDIR"
+
+#undef STANDALONE /* define for standalone debugging */
+
+/* File descriptors */
+typedef struct {
+ int command;
+ int answer;
+} fds;
+
+
+#if EXPECT_DEBUG
+static int expect_debug = 1;
+#endif /* EXPECT_DEBUG */
+#ifdef STANDALONE
+int Verbose=1;
+#endif
+static int needclose=0;
+static int ftp_started=0;
+static fds ftpio;
+static int ftp_pid;
+static char term[1024];
+static char bold_on[1024];
+static char bold_off[1024];
+
+/*
+ * expect "str" (a regular expression) on file descriptor "fd", storing
+ * the FTP return code of the command in the integer "ftprc". The "str"
+ * string is expected to match some FTP return codes after a '\n', e.g.
+ * "\n(550|226).*\n"
+ */
+static int
+expect(int fd, const char *str, int *ftprc)
+{
+ int rc;
+ char buf[90];
+#if EXPECT_DEBUG
+ char *vstr;
+#endif /* EXPECT_DEBUG */
+ regex_t rstr;
+ int done;
+ struct timeval timeout;
+ int retval;
+ regmatch_t match;
+ int verbose_expect=0;
+
+#if EXPECT_DEBUG
+ vstr=malloc(2*sizeof(buf));
+ if (vstr == NULL)
+ err(1, "expect: malloc() failed");
+ strvis(vstr, str, VIS_NL|VIS_SAFE|VIS_CSTYLE);
+#endif /* EXPECT_DEBUG */
+
+ if (regcomp(&rstr, str, REG_EXTENDED) != 0)
+ err(1, "expect: regcomp() failed");
+
+#if EXPECT_DEBUG
+ if (expect_debug)
+ printf("expecting \"%s\" on fd %d ...\n", vstr, fd);
+#endif /* EXPECT_DEBUG */
+
+ if(0) setbuf(stdout, NULL);
+
+ memset(buf, '\n', sizeof(buf));
+
+ timeout.tv_sec=10*60; /* seconds until next message from tar */
+ timeout.tv_usec=0;
+ done=0;
+ retval=0;
+ while(!done) {
+ fd_set fdset;
+
+ FD_ZERO(&fdset);
+ FD_SET(fd, &fdset);
+ rc = select(FD_SETSIZE, &fdset, NULL, NULL, &timeout);
+ switch (rc) {
+ case -1:
+ if (errno == EINTR)
+ break;
+ warn("expect: select() failed (probably ftp died because of bad args)");
+ done = 1;
+ retval = -1;
+ break;
+ case 0:
+ warnx("expect: select() timeout");
+ /* need to send ftp coprocess SIGINT to make it stop
+ * downloading into dir that we'll blow away in a second */
+ kill(ftp_pid, SIGINT);
+
+ /* Wait until ftp coprocess is responsive again
+ * XXX Entering recursion here!
+ */
+ rc = ftp_cmd("cd .\n", "\n(550|250).*\n");
+ if (rc != 250) {
+ /* now we have a really good reason to bail out ;) */
+ }
+ /* ftp is at command prompt again, and will wait for our
+ * next command. If we were downloading, we can now safely
+ * continue and remove the dir that the tar command was
+ * expanding to */
+
+ done = 1; /* hope that's ok */
+ retval = -1;
+ break;
+ default:
+ rc=read(fd,&buf[sizeof(buf)-1],1);
+
+ if (verbose_expect)
+ putchar(buf[sizeof(buf)-1]);
+
+#if EXPECT_DEBUG
+ {
+ char *v=malloc(2*sizeof(buf));
+ strvis(v, buf, VIS_NL|VIS_SAFE|VIS_CSTYLE);
+ if (expect_debug)
+ printf("expect=<%s>, buf=<%*s>\n", vstr, strlen(v), v);
+ free(v);
+ }
+#endif /* EXPECT_DEBUG */
+
+ if (regexec(&rstr, buf, 1, &match, 0) == 0) {
+#if EXPECT_DEBUG
+ if (expect_debug)
+ printf("Gotcha -> %s!\n", buf+match.rm_so+1);
+ fflush(stdout);
+#endif /* EXPECT_DEBUG */
+
+ if (ftprc && isdigit(buf[match.rm_so+1]))
+ *ftprc = atoi(buf+match.rm_so+1);
+
+ done=1;
+ retval=0;
+ }
+
+ memmove(buf, buf+1, sizeof(buf)-1); /* yes, this is non-performant */
+ break;
+ }
+ }
+
+#if EXPECT_DEBUG
+ printf("done.\n");
+
+ if (str)
+ free(vstr);
+#endif /* EXPECT_DEBUG */
+
+ return retval;
+}
+
+/*
+ * send a certain ftp-command "cmd" to our FTP coprocess, and wait for
+ * "expectstr" to be returned. Return numeric FTP return code or -1
+ * in case of an error (usually expect() timeout)
+ */
+int
+ftp_cmd(const char *cmd, const char *expectstr)
+{
+ int rc=0, verbose_ftp=0;
+ int len;
+
+ if (Verbose)
+ verbose_ftp=1;
+
+ if (verbose_ftp)
+ fprintf(stderr, "\n%sftp> %s%s", bold_on, cmd, bold_off);
+
+ fflush(stdout);
+ len = write(ftpio.command, cmd, strlen(cmd));
+ if (len == strlen(cmd)) {
+ if (expectstr) {
+ /* set "rc" to the FTP error code: */
+ if (expect(ftpio.answer, expectstr, &rc) == -1)
+ rc = -1; /* some error occurred */
+ }
+ } else {
+ if (Verbose)
+ warn("short write");
+ }
+
+ return rc;
+}
+
+
+/*
+ * Really fire up FTP coprocess
+ */
+static int
+setupCoproc(const char *base)
+{
+ int command_pipe[2];
+ int answer_pipe[2];
+ int rc1, rc2;
+ char buf[20];
+ char *argv0 = strrchr(FTP_CMD, '/');
+ if (argv0 == NULL)
+ argv0 = FTP_CMD;
+ else
+ argv0++;
+
+ rc1 = pipe(command_pipe);
+ rc2 = pipe(answer_pipe);
+
+ if(rc1==-1 || rc2==-1) {
+ warn("setupCoproc: pipe() failed");
+ return -1;
+ }
+
+ if (command_pipe[0] == -1 || command_pipe[1] == -1 ||
+ answer_pipe[0] == -1 || answer_pipe[1] == -1 ) {
+ warn("setupCoproc: pipe() returned bogus descriptor");
+ return -1;
+ }
+
+ rc1 = fork();
+ switch (rc1) {
+ case -1:
+ /* Error */
+
+ warn("setupCoproc: fork() failed");
+ return -1;
+ break;
+
+ case 0:
+ /* Child */
+
+ (void) close(command_pipe[1]);
+ rc1 = dup2(command_pipe[0], 0);
+ if (rc1 == -1) {
+ err(1, "setupCoproc: dup2 failed (command_pipe[0])");
+ }
+ (void) close(command_pipe[0]);
+
+ (void) close(answer_pipe[0]);
+ rc1 = dup2(answer_pipe[1], 1);
+ if (rc1 == -1) {
+ err(1, "setupCoproc: dup2 failed (answer_pipe[1])");
+ }
+ (void) close(answer_pipe[1]);
+
+ setbuf(stdout, NULL);
+
+ if (Verbose)
+ fprintf(stderr, "%sftp -detv %s%s\n", bold_on, base, bold_off);
+ rc1 = execlp(FTP_CMD, argv0, "-detv", base, NULL);
+ warn("setupCoproc: execlp() failed");
+ exit(1);
+ break;
+ default:
+ /* Parent */
+ (void) close(command_pipe[0]);
+ (void) close(answer_pipe[1]);
+
+ (void) snprintf(buf, sizeof(buf), "%d", command_pipe[1]);
+ setenv(PKG_FTPIO_COMMAND, buf, 1);
+ (void) snprintf(buf, sizeof(buf), "%d", answer_pipe[0]);
+ setenv(PKG_FTPIO_ANSWER, buf, 1);
+
+ ftpio.command = command_pipe[1];
+ ftpio.answer = answer_pipe[0];
+ ftp_pid = rc1; /* to ^C transfers */
+
+ fcntl(ftpio.command, F_SETFL, O_NONBLOCK);
+ fcntl(ftpio.answer , F_SETFL, O_NONBLOCK);
+
+ break;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Dummy signal handler to detect if the ftp(1) coprocess or
+ * and of the processes of the tar/gzip pipeline dies.
+ */
+static void
+sigchld_handler (int n)
+{
+ /* Make select(2) return EINTR */
+}
+
+
+/*
+ * SIGPIPE only happens when there's something wrong with the FTP
+ * coprocess. In that case, set mark to not try to close shut down
+ * the coprocess.
+ */
+static void
+sigpipe_handler(int n)
+{
+ /* aparently our ftp companion died */
+ if (Verbose)
+ fprintf(stderr, "SIGPIPE!\n");
+ needclose = 0;
+}
+
+
+/*
+ * Close the FTP coprocess' current connection, but
+ * keep the process itself alive.
+ */
+void
+ftp_stop(void)
+{
+#if defined(__svr4__) && defined(__sun__)
+ char env[BUFSIZ];
+#endif
+ const char *tmp1, *tmp2;
+
+ if (!ftp_started)
+ return;
+
+ tmp1=getenv(PKG_FTPIO_COMMAND);
+ tmp2=getenv(PKG_FTPIO_ANSWER);
+
+ /* (Only) the last one closes the link */
+ if (tmp1 != NULL && tmp2 != NULL) {
+ if (needclose)
+ ftp_cmd("close\n", "\n(221 .*|Not connected.)\n");
+
+ (void) close(ftpio.command);
+ (void) close(ftpio.answer);
+ }
+
+#if defined(__svr4__) && defined(__sun__)
+ (void) snprintf(env, sizeof(env), "%s=", PKG_FTPIO_COMMAND);
+ putenv(env);
+ (void) snprintf(env, sizeof(env), "%s=", PKG_FTPIO_ANSWER);
+ putenv(env);
+#else
+ unsetenv(PKG_FTPIO_COMMAND);
+ unsetenv(PKG_FTPIO_ANSWER);
+#endif
+}
+
+
+/*
+ * (Start and re-)Connect the FTP coprocess to some host/dir.
+ * If the requested host/dir is different than the one that the
+ * coprocess is currently at, close first.
+ */
+int
+ftp_start(char *base)
+{
+ const char *tmp1, *tmp2;
+ char *p;
+ int rc;
+ char newHost[MAXHOSTNAMELEN];
+ const char *newDir;
+ const char *currentHost=getenv(PKG_FTPIO_CURRENTHOST);
+ const char *currentDir=getenv(PKG_FTPIO_CURRENTDIR);
+ int urllen;
+
+ /* talk to termcap for bold on/off escape sequences */
+#if 0
+ if (tgetent(term, getenv("TERM")) < 0) {
+ bold_on[0] = '\0';
+ bold_off[0] = '\0';
+ } else {
+ p = bold_on; tgetstr("md", &p);
+ p = bold_off; tgetstr("me", &p);
+ }
+#else
+ bold_on[0] = '\0';
+ bold_off[0] = '\0';
+#endif
+
+ fileURLHost(base, newHost, sizeof(newHost));
+ urllen = URLlength(base);
+ if (urllen < 0 || !(newDir = strchr(base + URLlength(base), '/')))
+ errx(1, "ftp_start: bad URL '%s'", base);
+ newDir++;
+ if (currentHost
+ && currentDir
+ && ( strcmp(newHost, currentHost) != 0
+ || strcmp(newDir, currentDir) != 0)) { /* could handle new dir case better here, w/o reconnect */
+ if (Verbose) {
+ printf("ftp_start: new host or dir, stopping previous connect...\n");
+ printf("currentHost='%s', newHost='%s'\n", currentHost, newHost);
+ printf("currentDir='%s', newDir='%s'\n", currentDir, newDir);
+ }
+
+ ftp_stop();
+
+ if (Verbose)
+ printf("ftp stopped\n");
+ }
+ setenv(PKG_FTPIO_CURRENTHOST, newHost, 1); /* need to update this in the environment */
+ setenv(PKG_FTPIO_CURRENTDIR, newDir, 1); /* for subprocesses to have this available */
+
+ tmp1=getenv(PKG_FTPIO_COMMAND);
+ tmp2=getenv(PKG_FTPIO_ANSWER);
+ if(tmp1==NULL || tmp2==NULL || *tmp1=='\0' || *tmp2=='\0') {
+ /* no FTP coprocess running yet */
+
+ if (Verbose)
+ printf("Spawning FTP coprocess\n");
+
+ rc = setupCoproc(base);
+ if (rc == -1) {
+ warnx("setupCoproc() failed");
+ return -1;
+ }
+
+ needclose=1;
+ signal(SIGPIPE, sigpipe_handler);
+ signal(SIGCHLD, sigchld_handler);
+
+ if ((expect(ftpio.answer, "\n(221|250|221|550).*\n", &rc) != 0)
+ || rc != 250) {
+ warnx("expect1 failed, rc=%d", rc);
+ return -1;
+ }
+
+ /* lukemftp now issues a CWD for each part of the path
+ * and will return a code for each of them. No idea how to
+ * deal with that other than to issue a 'prompt off' to
+ * get something that we can wait for and that does NOT
+ * look like a CWD command's output */
+ rc = ftp_cmd("prompt off\n", "\n(Interactive mode off|221).*\n");
+ if ((rc == 221) || (rc == -1)) {
+ /* something is wrong */
+ ftp_started=1; /* not really, but for ftp_stop() */
+ ftp_stop();
+ warnx("prompt failed - wrong dir?");
+ return -1;
+ }
+
+ ftp_started=1;
+ } else {
+ /* get FDs of our coprocess */
+
+ ftpio.command = dup(atoi(tmp1));
+ if (ftpio.command == -1 ) {
+ warnx("command dup() failed, increase 'descriptors' limit");
+ return -1;
+ }
+ ftpio.answer = dup(atoi(tmp2));
+ if (ftpio.answer == -1 ) {
+ warnx("answer dup() failed, increase 'descriptors' limit");
+ return -1;
+ }
+
+ if (Verbose)
+ printf("Reusing FDs %s/%s for communication to FTP coprocess\n", tmp1, tmp2);
+
+ fcntl(ftpio.command, F_SETFL, O_NONBLOCK);
+ fcntl(ftpio.answer , F_SETFL, O_NONBLOCK);
+ }
+
+ return 0;
+}
+
+
+/*
+ * Expand the given wildcard URL "wildcardurl" if possible, and store the
+ * expanded value into "expandedurl". return 0 if successful, -1 else.
+ */
+int
+expandURL(char *expandedurl, const char *wildcardurl)
+{
+ char *pkg;
+ int rc;
+ char base[FILENAME_MAX];
+
+ pkg=strrchr(wildcardurl, '/');
+ if (pkg == NULL){
+ warnx("expandURL: no '/' in url %s?!", wildcardurl);
+ return -1;
+ }
+ (void) snprintf(base, sizeof(base), "%*.*s/", (int)(pkg-wildcardurl),
+ (int)(pkg-wildcardurl), wildcardurl);
+ pkg++;
+
+ rc = ftp_start(base);
+ if (rc == -1) {
+ warnx("ftp_start() failed");
+ return -1; /* error */
+ }
+
+ /* for a given wildcard URL, find the best matching pkg */
+ {
+ char *s, buf[FILENAME_MAX];
+ char tmpname[FILENAME_MAX];
+ char best[FILENAME_MAX];
+ int tfd;
+
+ strcpy(tmpname, "/var/tmp/pkg.XXXXXX");
+ tfd=mkstemp(tmpname);
+ if (tfd == -1) {
+ warnx("Cannot generate temp file for ftp(1)'s nlist output");
+ return -1; /* error */
+ }
+ close(tfd); /* We don't need the file descriptor, but will use
+ the file in a second */
+
+ s=strpbrk(pkg, "<>[]?*{"); /* Could leave out "[]?*" here;
+ * ftp(1) is not that stupid */
+ if (!s) {
+ /* This should only happen when getting here with (only) a package
+ * name specified to pkg_add, and PKG_PATH containing some URL.
+ */
+ (void) snprintf(buf, sizeof(buf), "nlist %s %s\n", pkg, tmpname);
+ } else {
+ /* replace possible version(wildcard) given with "-*".
+ * we can't use the pkg wildcards here as dewey compare
+ * and alternates won't be handled by ftp(1); sort
+ * out later, using pmatch() */
+ (void) snprintf(buf, sizeof(buf), "nlist %*.*s*.t[bg]z %s\n",
+ (int)(s-pkg), (int)(s-pkg), pkg, tmpname);
+ }
+
+ rc = ftp_cmd(buf, "\n(550|226).*\n"); /* catch errors */
+ if (rc != 226) {
+ if (Verbose)
+ warnx("nlist failed!");
+ unlink(tmpname); /* remove clutter */
+ return -1;
+ }
+
+ /* Sync - don't remove */
+ rc = ftp_cmd("cd .\n", "\n(550|250).*\n");
+ if (rc != 250) {
+ warnx("chdir failed!");
+ unlink(tmpname); /* remove clutter */
+ return -1;
+ }
+
+ best[0]='\0';
+ if (access(tmpname, R_OK)==0) {
+ int matches;
+ FILE *f;
+ char filename[FILENAME_MAX];
+
+ f=fopen(tmpname, "r");
+ if (f == NULL) {
+ warn("fopen");
+ unlink(tmpname); /* remove clutter */
+ return -1;
+ }
+ matches=0;
+ /* The following loop is basically the same as the readdir() loop
+ * in findmatchingname() */
+ while (fgets(filename, sizeof(filename), f)) {
+
+ /*
+ * We need to stripp of any .t[bg]z etc.
+ * suffix here
+ */
+
+ char s_filename[FILENAME_MAX];
+ char s_pkg[FILENAME_MAX];
+
+ filename[strlen(filename)-1] = '\0';
+
+ strip_txz(s_filename, NULL, filename);
+ strip_txz(s_pkg, NULL, pkg);
+
+ if (pmatch(s_pkg, s_filename)) {
+ matches++;
+
+ /* compare findbestmatchingname() */
+ findbestmatchingname_fn(filename, best);
+ }
+ }
+ (void) fclose(f);
+
+ if (matches == 0 && Verbose)
+ warnx("nothing appropriate found");
+ }
+
+ unlink(tmpname);
+
+ if (best[0] != '\0') {
+ if (Verbose)
+ printf("best match: '%s%s'\n", base, best);
+ snprintf(expandedurl, FILENAME_MAX, "%s%s", base, best);
+ }
+ else
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/*
+ * extract the given (expanded) URL "url" to the given directory "dir"
+ * return -1 on error, 0 else;
+ */
+int
+unpackURL(const char *url, const char *dir)
+{
+ char *pkg;
+ int rc;
+ char base[FILENAME_MAX];
+ char pkg_path[FILENAME_MAX];
+
+ {
+ /* Verify if the url is really ok */
+ char expnd[FILENAME_MAX];
+
+ rc=expandURL(expnd, url);
+ if (rc == -1) {
+ warnx("unpackURL: verification expandURL failed");
+ return -1;
+ }
+ if (strcmp(expnd, url) != 0) {
+ warnx("unpackURL: verification expandURL failed, '%s'!='%s'",
+ expnd, url);
+ return -1;
+ }
+ }
+
+ pkg=strrchr(url, '/');
+ if (pkg == NULL){
+ warnx("unpackURL: no '/' in url %s?!", url);
+ return -1;
+ }
+ (void) snprintf(base, sizeof(base), "%*.*s/", (int)(pkg-url),
+ (int)(pkg-url), url);
+ (void) snprintf(pkg_path, sizeof(pkg_path), "%*.*s", (int)(pkg-url),
+ (int)(pkg-url), url); /* no trailing '/' */
+ pkg++;
+
+ /* Leave a hint for any depending pkgs that may need it */
+ if (getenv("PKG_PATH") == NULL) {
+ setenv("PKG_PATH", pkg_path, 1);
+#if 0
+ path_create(pkg_path); /* XXX */
+#endif
+ printf("setenv PKG_PATH='%s'\n",pkg_path);
+ }
+
+ rc = ftp_start(base);
+ if (rc == -1) {
+ warnx("ftp_start() failed");
+ return -1; /* error */
+ }
+
+ {
+ char cmd[1024];
+
+ if (Verbose)
+ printf("unpackURL '%s' to '%s'\n", url, dir);
+
+ /* yes, this is gross, but needed for borken ftp(1) */
+ (void) snprintf(cmd, sizeof(cmd), "get %s \"| ( cd %s ; gunzip 2>/dev/null | " TAR_FULLPATHNAME " -%sx -f - | tee /dev/stderr )\"\n", pkg, dir, Verbose?"vv":"");
+ rc = ftp_cmd(cmd, "\n(226|550).*\n");
+ if (rc != 226) {
+ warnx("Cannot fetch file (%d!=226)!", rc);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+#if 0
+/*
+ * Some misc stuff not needed yet, but maybe later
+ */
+int
+miscstuff(const char *url)
+{
+ char *pkg;
+ int rc;
+ char base[FILENAME_MAX];
+
+ pkg=strrchr(url, '/');
+ if (pkg == NULL){
+ warnx("miscstuff: no '/' in url %s?!", url);
+ return -1;
+ }
+ (void) snprintf(base, sizeof(base), "%*.*s/", (int)(pkg-url), (int)(pkg-url),
+ url);
+ pkg++;
+
+ rc = ftp_start(base);
+ if (rc == -1) {
+ warnx("ftp_start() failed");
+ return -1; /* error */
+ }
+
+ /* basic operation */
+ if (0) {
+ rc = ftp_cmd("cd ../All\n", "\n(550|250).*\n");
+ if (rc != 250) {
+ warnx("chdir failed!");
+ return -1;
+ }
+ }
+
+ /* get and extract a file to tmpdir */
+ if (0) {
+ char cmd[256];
+ char tmpdir[256];
+
+ (void) snprintf(tmpdir, sizeof(tmpdir), "/var/tmp/dir%s",
+ (getenv(PKG_FTPIO_CNT))?getenv(PKG_FTPIO_CNT):"");
+
+ mkdir(tmpdir, 0755);
+
+ /* yes, this is gross, but needed for borken ftp(1) */
+ (void) snprintf(cmd, sizeof(cmd), "get xpmroot-1.01.tgz \"| ( cd %s ; gunzip 2>/dev/null | tar -vvx -f - )\"\n", tmpdir);
+ rc = ftp_cmd(cmd, "\n(226|550).*\n");
+ if (rc != 226) {
+ warnx("Cannot fetch file (%d != 226)!", rc);
+ return -1;
+ }
+ }
+
+ /* check if one more file(s) exist */
+ if (0) {
+ char buf[FILENAME_MAX];
+ (void) snprintf(buf, sizeof(buf), "nlist %s /var/tmp/xxx\n", pkg);
+ rc = ftp_cmd(buf, "\n(226|550).*\n"); /* catch errors */
+ if (rc != 226) {
+ if (Verbose)
+ warnx("nlist failed!");
+ return -1;
+ }
+
+ /* Sync - don't remove */
+ rc = ftp_cmd("cd .\n", "\n(550|250).*\n");
+ if (rc != 250) {
+ warnx("chdir failed!");
+ return -1;
+ }
+
+ if (access("/var/tmp/xxx", R_OK)==0) {
+ system("cat /var/tmp/xxx");
+
+ {
+ /* count lines - >0 -> fexists() == true */
+ int len, count;
+ FILE *f;
+
+ f=fopen("/var/tmp/xxx", "r");
+ if (f == NULL) {
+ warn("fopen");
+ return -1;
+ }
+ count=0;
+ while (fgetln(f, &len))
+ count++;
+ (void) fclose(f);
+
+ printf("#lines = %d\n", count);
+ }
+ } else
+ printf("NO MATCH\n");
+
+ unlink("/var/tmp/xxx");
+ }
+
+ /* for a given wildcard URL, find the best matching pkg */
+ /* spawn child - like pkg_add'ing another package */
+ /* Here's where the connection caching kicks in */
+#if 0
+ if (0) {
+ char *s, buf[FILENAME_MAX];
+
+ if ((s=getenv(PKG_FTPIO_CNT)) && atoi(s)>0){
+ (void) snprintf(buf, sizeof(buf),"%d", atoi(s)-1);
+ setenv(PKG_FTPIO_CNT, buf, 1);
+
+ (void) snprintf(buf, sizeof(buf), "%s \"%s/%s\"", argv0, url, pkg);
+ printf("%s>>> %s\n", s, buf);
+ system(buf);
+ }
+ }
+#endif
+
+ return 0;
+
+}
+#endif
+
+
+#ifdef STANDALONE
+static void
+usage(void)
+{
+ errx(1, "Usage: foo [-v] ftp://-pattern");
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ int rc, ch;
+ char *argv0 = argv[0];
+
+ while ((ch = getopt(argc, argv, "v")) != -1) {
+ switch (ch) {
+ case 'v':
+ Verbose=1;
+ break;
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc<1)
+ usage();
+
+ while(argv[0] != NULL) {
+ char newurl[FILENAME_MAX];
+
+ printf("Expand %s:\n", argv[0]);
+ rc = expandURL(newurl, argv[0]);
+ if (rc==-1)
+ warnx("Cannot expand %s", argv[0]);
+ else
+ printf("Expanded URL: %s\n", newurl);
+
+ /* test out connection caching */
+ if (1) {
+ char *s, buf[FILENAME_MAX];
+
+ if ((s=getenv(PKG_FTPIO_CNT)) && atoi(s)>0){
+ (void) snprintf(buf, sizeof(buf),"%d", atoi(s)-1);
+ setenv(PKG_FTPIO_CNT, buf, 1);
+
+ (void) snprintf(buf, sizeof(buf), "%s -v '%s'", argv0, argv[0]);
+ printf("%s>>> %s\n", s, buf);
+ system(buf);
+ }
+ }
+
+ printf("\n\n\n");
+ argv++;
+ }
+
+ ftp_stop();
+
+ return 0;
+}
+#endif /* STANDALONE */
diff --git a/pkgtools/pkg_install/files/lib/global.c b/pkgtools/pkg_install/files/lib/global.c
new file mode 100644
index 00000000000..0c8b14806a8
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/global.c
@@ -0,0 +1,40 @@
+/* $NetBSD: global.c,v 1.1.1.1 2002/12/20 18:14:01 schmonz Exp $ */
+
+#if 0
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static const char *rcsid = "from FreeBSD Id: global.c,v 1.6 1997/10/08 07:47:58 charnier Exp";
+#else
+__RCSID("$NetBSD: global.c,v 1.1.1.1 2002/12/20 18:14:01 schmonz Exp $");
+#endif
+#endif
+#endif
+
+/*
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+
+ * 18 July 1993
+ *
+ * Semi-convenient place to stick some needed globals.
+ *
+ */
+
+#include "lib.h"
+
+/* These are global for all utils */
+Boolean Verbose = FALSE;
+Boolean Fake = FALSE;
+Boolean Force = FALSE;
diff --git a/pkgtools/pkg_install/files/lib/lib.h.in b/pkgtools/pkg_install/files/lib/lib.h.in
new file mode 100644
index 00000000000..69b9fd50579
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/lib.h.in
@@ -0,0 +1,448 @@
+/* $NetBSD: lib.h.in,v 1.1.1.1 2002/12/20 18:14:02 schmonz Exp $ */
+
+/* from FreeBSD Id: lib.h,v 1.25 1997/10/08 07:48:03 charnier Exp */
+
+/*
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 18 July 1993
+ *
+ * Include and define various things wanted by the library routines.
+ *
+ */
+
+#ifndef _INST_LIB_LIB_H_
+#define _INST_LIB_LIB_H_
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+
+#if defined(HAVE_SYS_PARAM_H)
+#include <sys/param.h>
+#endif
+
+#if defined(HAVE_SYS_STAT_H)
+#include <sys/stat.h>
+#endif
+
+#if defined(HAVE_SYS_FILE_H)
+#include <sys/file.h>
+#endif
+
+#if defined(HAVE_SYS_QUEUE_H)
+#include <sys/queue.h>
+#endif
+
+#include <ctype.h>
+
+#if defined(HAVE_DIRENT_H)
+#include <dirent.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#if defined(HAVE_STRING_H)
+#include <string.h>
+#endif
+
+#include <unistd.h>
+
+/* Macros */
+#define SUCCESS (0)
+#define FAIL (-1)
+
+#ifndef TRUE
+#define TRUE (1)
+#endif
+
+#ifndef FALSE
+#define FALSE (0)
+#endif
+
+#ifndef TAR_FULLPATHNAME
+#define TAR_FULLPATHNAME "@TAR_FULLPATHNAME@"
+#endif
+/* Define ftp as a string, in case the ftp client is called something else */
+#ifndef FTP_CMD
+#define FTP_CMD "ftp"
+#endif
+#ifndef ADD_CMD
+#define ADD_CMD "@prefix@/sbin/pkg_add"
+#endif
+#ifndef CHMOD_CMD
+#define CHMOD_CMD "@CHMOD@"
+#endif
+#ifndef CHOWN_CMD
+#define CHOWN_CMD "@CHOWN@"
+#endif
+#ifndef CHGRP_CMD
+#define CHGRP_CMD "@CHGRP@"
+#endif
+#ifndef DIGEST
+#define DIGEST "@DIGEST@"
+#endif
+#ifndef MKDIR
+#define MKDIR "@MKDIR@"
+#endif
+#ifndef MTREE
+#define MTREE "@MTREE@"
+#endif
+#ifndef PREFIX
+#define PREFIX "@prefix@"
+#endif
+#ifndef RM
+#define RM "@RM@"
+#endif
+#ifndef RMDIR_CMD
+#define RMDIR_CMD "@RMDIR@"
+#endif
+
+#if defined(BSD4_4)
+/* the BSD derivatives have added --fast-read to their tar(1) commands */
+#define HAVE_TAR__FAST_READ 1
+#endif
+
+
+/* Where we put logging information by default, else ${PKG_DBDIR} if set */
+#ifndef DEF_LOG_DIR
+#define DEF_LOG_DIR "@pkgdbdir@"
+#endif
+/* just in case we change the environment variable name */
+#define PKG_DBDIR "PKG_DBDIR"
+
+/* The names of our "special" files */
+#define CONTENTS_FNAME "+CONTENTS"
+#define COMMENT_FNAME "+COMMENT"
+#define DESC_FNAME "+DESC"
+#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 BUILD_VERSION_FNAME "+BUILD_VERSION"
+#define BUILD_INFO_FNAME "+BUILD_INFO"
+#define SIZE_PKG_FNAME "+SIZE_PKG"
+#define SIZE_ALL_FNAME "+SIZE_ALL"
+
+#define CMD_CHAR '@' /* prefix for extended PLIST cmd */
+
+/* The name of the "prefix" environment variable given to scripts */
+#define PKG_PREFIX_VNAME "PKG_PREFIX"
+
+#define PKG_PATTERN_MAX FILENAME_MAX /* max length of pattern, including nul */
+#define PKG_SUFFIX_MAX 10 /* max length of suffix, including nul */
+
+
+/* This should only happen on 1.3 and 1.3.1, not 1.3.2 and up */
+#ifndef TAILQ_FIRST
+#define TAILQ_FIRST(head) ((head)->tqh_first)
+#endif
+
+#ifndef TAILQ_NEXT
+#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+#endif
+
+/*
+ * Tail queue definitions.
+ */
+#ifndef QUEUEDEBUG_TAILQ_INSERT_HEAD
+#define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)
+#endif
+
+#ifndef QUEUEDEBUG_TAILQ_INSERT_TAIL
+#define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)
+#endif
+
+#ifndef QUEUEDEBUG_TAILQ_OP
+#define QUEUEDEBUG_TAILQ_OP(elm, field)
+#endif
+
+#ifndef QUEUEDEBUG_TAILQ_POSTREMOVE
+#define QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)
+#endif
+
+#ifndef TAILQ_INIT
+#define TAILQ_INIT(head) do { \
+ (head)->tqh_first = NULL; \
+ (head)->tqh_last = &(head)->tqh_first; \
+} while (/*CONSTCOND*/0)
+#endif
+
+#ifndef TAILQ_HEAD
+#define TAILQ_HEAD(name, type) \
+struct name { \
+ struct type *tqh_first; /* first element */ \
+ struct type **tqh_last; /* addr of last next element */ \
+}
+#endif
+
+#ifndef TAILQ_HEAD_INITIALIZER
+#define TAILQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).tqh_first }
+#endif
+
+#ifndef TAILQ_ENTRY
+#define TAILQ_ENTRY(type) \
+struct { \
+ struct type *tqe_next; /* next element */ \
+ struct type **tqe_prev; /* address of previous next element */ \
+}
+#endif
+
+#ifndef TAILQ_INSERT_HEAD
+#define TAILQ_INSERT_HEAD(head, elm, field) do { \
+ QUEUEDEBUG_TAILQ_INSERT_HEAD((head), (elm), field) \
+ if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
+ (head)->tqh_first->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (head)->tqh_first = (elm); \
+ (elm)->field.tqe_prev = &(head)->tqh_first; \
+} while (/*CONSTCOND*/0)
+#endif
+
+#ifndef TAILQ_INSERT_TAIL
+#define TAILQ_INSERT_TAIL(head, elm, field) do { \
+ QUEUEDEBUG_TAILQ_INSERT_TAIL((head), (elm), field) \
+ (elm)->field.tqe_next = NULL; \
+ (elm)->field.tqe_prev = (head)->tqh_last; \
+ *(head)->tqh_last = (elm); \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+} while (/*CONSTCOND*/0)
+#endif /* !TAILQ_INSERT_TAIL */
+
+#ifndef TAILQ_REMOVE
+#define TAILQ_REMOVE(head, elm, field) do { \
+ QUEUEDEBUG_TAILQ_OP((elm), field) \
+ if (((elm)->field.tqe_next) != NULL) \
+ (elm)->field.tqe_next->field.tqe_prev = \
+ (elm)->field.tqe_prev; \
+ else \
+ (head)->tqh_last = (elm)->field.tqe_prev; \
+ *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
+ QUEUEDEBUG_TAILQ_POSTREMOVE((elm), field); \
+} while (/*CONSTCOND*/0)
+#endif
+
+#ifndef TAILQ_FOREACH
+#define TAILQ_FOREACH(var, head, field) \
+ for ((var) = ((head)->tqh_first); \
+ (var); \
+ (var) = ((var)->field.tqe_next))
+#endif
+
+#ifndef TAILQ_FOREACH_REVERSE
+#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
+ for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
+ (var); \
+ (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
+#endif
+
+
+/* Enumerated constants for plist entry types */
+typedef enum pl_ent_t {
+ PLIST_SHOW_ALL = -1,
+ PLIST_FILE, /* 0 */
+ PLIST_CWD, /* 1 */
+ PLIST_CMD, /* 2 */
+ PLIST_CHMOD, /* 3 */
+ PLIST_CHOWN, /* 4 */
+ PLIST_CHGRP, /* 5 */
+ PLIST_COMMENT, /* 6 */
+ PLIST_IGNORE, /* 7 */
+ PLIST_NAME, /* 8 */
+ PLIST_UNEXEC, /* 9 */
+ PLIST_SRC, /* 10 */
+ PLIST_DISPLAY, /* 11 */
+ PLIST_PKGDEP, /* 12 */
+ PLIST_MTREE, /* 13 */
+ PLIST_DIR_RM, /* 14 */
+ PLIST_IGNORE_INST, /* 15 */
+ PLIST_OPTION, /* 16 */
+ PLIST_PKGCFL, /* 17 */
+ PLIST_BLDDEP /* 18 */
+} pl_ent_t;
+
+/* Types */
+typedef unsigned int Boolean;
+
+/* This structure describes a packing list entry */
+typedef struct plist_t {
+ struct plist_t *prev; /* previous entry */
+ struct plist_t *next; /* next entry */
+ char *name; /* name of entry */
+ Boolean marked; /* whether entry has been marked */
+ pl_ent_t type; /* type of entry */
+} plist_t;
+
+/* This structure describes a package's complete packing list */
+typedef struct package_t {
+ plist_t *head; /* head of list */
+ plist_t *tail; /* tail of list */
+} package_t;
+
+#define CHECKSUM_HEADER "MD5:"
+
+enum {
+ ChecksumHeaderLen = 4, /* strlen(CHECKSUM_HEADER) */
+ ChecksumLen = 16,
+ LegibleChecksumLen = 33
+};
+
+/* List of packages */
+typedef struct _lpkg_t {
+ TAILQ_ENTRY(_lpkg_t) lp_link;
+ char *lp_name;
+} lpkg_t;
+TAILQ_HEAD(_lpkg_head_t, _lpkg_t);
+typedef struct _lpkg_head_t lpkg_head_t;
+
+/* Type of function to be handed to findmatchingname; return value of this
+ * is currently ignored */
+typedef int (*matchfn) (const char *, void *);
+
+/* If URLlength()>0, then there is a ftp:// or http:// in the string,
+ * and this must be an URL. Hide this behind a more obvious name. */
+#define IS_URL(str) (URLlength(str) > 0)
+#define IS_STDIN(str) ((str) != NULL && !strcmp((str), "-"))
+#define IS_FULLPATH(str) ((str) != NULL && (str)[0] == '/')
+
+/* Prototypes */
+/* Misc */
+int vsystem(const char *,...)
+ __attribute__((__format__(__printf__, 1, 2)));
+void cleanup(int);
+char *make_playpen(char *, size_t, size_t);
+char *where_playpen(void);
+void leave_playpen(char *);
+off_t min_free(char *);
+void save_dirs(char **c, char **p);
+void restore_dirs(char *c, char *p);
+void show_version(void);
+
+#ifndef HAVE_MD5FILE
+char *MD5File(char *, char *);
+#endif
+
+#ifndef HAVE_FGETLN
+char *fgetln(FILE *, size_t *);
+#endif
+
+/* String */
+char *get_dash_string(char **);
+void str_lowercase(char *);
+const char *basename_of(const char *);
+const char *dirname_of(const char *);
+const char *suffix_of(const char *);
+int pmatch(const char *, const char *);
+int findmatchingname(const char *, const char *, matchfn, void *); /* doesn't really belong to "strings" */
+char *findbestmatchingname(const char *, const char *); /* neither */
+int ispkgpattern(const char *);
+char *strnncpy(char *to, size_t tosize, char *from, size_t cc);
+void strip_txz(char *buf, char *sfx, const char *fname);
+
+/* callback functions for findmatchingname */
+int findbestmatchingname_fn(const char *, void *); /* neither */
+int note_whats_installed(const char *, void *);
+int add_to_list_fn(const char *, void *);
+
+
+#ifndef HAVE_STRSEP
+char *strsep(char **, const char *);
+#endif
+
+#ifndef HAVE_STRLCPY
+size_t strlcpy(char *, const char *, size_t);
+#endif
+
+/* File */
+Boolean fexists(const char *);
+Boolean isdir(const char *);
+Boolean islinktodir(const char *);
+Boolean isemptydir(const char *fname);
+Boolean isemptyfile(const char *fname);
+Boolean isfile(const char *);
+Boolean isempty(const char *);
+int URLlength(const char *);
+char *fileGetURL(const char *);
+const char *fileURLFilename(const char *, char *, int);
+char *fileFindByPath(const char *);
+const char *fileURLHost(const char *, char *, int);
+char *fileGetContents(char *);
+Boolean make_preserve_name(char *, size_t, char *, char *);
+void write_file(char *, char *);
+void copy_file(char *, char *, char *);
+void move_file(char *, char *, char *);
+int delete_hierarchy(char *, Boolean, Boolean);
+int unpack(const char *,const char *);
+void format_cmd(char *, size_t, char *, char *, char *);
+
+/* ftpio.c: FTP handling */
+int expandURL(char *expandedurl, const char *wildcardurl);
+int unpackURL(const char *url, const char *dir);
+int ftp_cmd(const char *cmd, const char *expectstr);
+int ftp_start(char *base);
+void ftp_stop(void);
+
+/* Packing list */
+plist_t *new_plist_entry(void);
+plist_t *last_plist(package_t *);
+plist_t *find_plist(package_t *, pl_ent_t);
+char *find_plist_option(package_t *, char *name);
+void plist_delete(package_t *, Boolean, pl_ent_t, char *);
+void free_plist(package_t *);
+void mark_plist(package_t *);
+void csum_plist_entry(char *, plist_t *);
+void add_plist(package_t *, pl_ent_t, const char *);
+void add_plist_top(package_t *, pl_ent_t, const char *);
+void delete_plist(package_t *pkg, Boolean all, pl_ent_t type, char *name);
+void write_plist(package_t *, FILE *, char *);
+void read_plist(package_t *, FILE *);
+int plist_cmd(char *, char **);
+int delete_package(Boolean, Boolean, package_t *);
+
+/* Package Database */
+int pkgdb_open(int);
+void pkgdb_close(void);
+int pkgdb_store(const char *, const char *);
+char *pkgdb_retrieve(const char *);
+int pkgdb_remove(const char *);
+char *pkgdb_iter(void);
+char *_pkgdb_getPKGDB_FILE(void);
+char *_pkgdb_getPKGDB_DIR(void);
+
+/* List of packages functions */
+lpkg_t *alloc_lpkg(const char *);
+lpkg_t *find_on_queue(lpkg_head_t *, const char *);
+void free_lpkg(lpkg_t *);
+
+/* For all */
+int pkg_perform(lpkg_head_t *);
+
+/* Externs */
+extern Boolean Verbose;
+extern Boolean Fake;
+extern Boolean Force;
+extern int upgrade;
+
+/* We include it at the end, because it uses TAILQ_* */
+#include "path.h"
+#endif /* _INST_LIB_LIB_H_ */
diff --git a/pkgtools/pkg_install/files/lib/lpkg.c b/pkgtools/pkg_install/files/lib/lpkg.c
new file mode 100644
index 00000000000..ff759c24405
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/lpkg.c
@@ -0,0 +1,72 @@
+/* $NetBSD: lpkg.c,v 1.1.1.1 2002/12/20 18:14:02 schmonz Exp $ */
+
+/*
+ * Copyright (c) 1999 Christian E. Hopps
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Package-list auxiliary functions
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#include "lib.h"
+
+/*
+ * Add a package to the (add/recursive delete) list
+ */
+lpkg_t *
+alloc_lpkg(const char *pkgname)
+{
+ lpkg_t *lpp;
+
+ if ((lpp = malloc(sizeof(*lpp))) == 0)
+ err(1, "cannot allocate recursion data");
+ if ((lpp->lp_name = strdup(pkgname)) == 0)
+ err(1, "cannot allocate recursion data");
+ return (lpp);
+}
+
+void
+free_lpkg(lpkg_t *lpp)
+{
+ free(lpp->lp_name);
+ free(lpp);
+}
+
+lpkg_t *
+find_on_queue(lpkg_head_t *qp, const char *name)
+{
+ lpkg_t *lpp;
+
+ for (lpp = TAILQ_FIRST(qp); lpp; lpp = TAILQ_NEXT(lpp, lp_link))
+ if (!strcmp(name, lpp->lp_name))
+ return (lpp);
+ return (0);
+}
diff --git a/pkgtools/pkg_install/files/lib/path.c b/pkgtools/pkg_install/files/lib/path.c
new file mode 100644
index 00000000000..abb84ae798b
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/path.c
@@ -0,0 +1,208 @@
+/* $NetBSD: path.c,v 1.1.1.1 2002/12/20 18:14:06 schmonz Exp $ */
+
+/*-
+ * Copyright (c)2002 YAMAMOTO Takashi,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if 0
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: path.c,v 1.1.1.1 2002/12/20 18:14:06 schmonz Exp $");
+#endif
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#include "lib.h"
+
+struct pathhead PkgPath = TAILQ_HEAD_INITIALIZER(PkgPath);
+static struct path *prepend = 0;
+
+static struct path *path_new_entry(const char *cp, size_t len);
+
+/*
+ * path_create: make PkgPath from a given string.
+ *
+ * => relative pathes are resolved to absolute ones.
+ * => if NULL is passed, use "." instead. XXX
+ */
+void
+path_create(const char *path)
+{
+ const char *cp;
+ size_t len;
+
+ path_free();
+
+ if (path == NULL) {
+ path = "."; /* XXX */
+ }
+
+ if (Verbose)
+ printf("parsing: %s\n", path);
+
+ cp = path;
+ while (*cp) {
+ len = strcspn(cp, ";");
+ if (len > 0) {
+ /* add a new path */
+ struct path *new;
+
+ new = path_new_entry(cp, len);
+ if (Verbose)
+ printf("path: %s\n", new->pl_path);
+ TAILQ_INSERT_TAIL(&PkgPath, new, pl_entry);
+ }
+
+ cp += len;
+ if (*cp == '\0')
+ break;
+ cp++;
+ }
+}
+
+/*
+ * path_free: free PkgPath.
+ */
+void
+path_free()
+{
+ struct path *p;
+
+ while ((p = TAILQ_FIRST(&PkgPath)) != NULL) {
+ TAILQ_REMOVE(&PkgPath, p, pl_entry);
+ free(p->pl_path);
+ free(p);
+ }
+}
+
+/*
+ * path_new_entry: Generate a new 'struct path' entry to be included in
+ * 'PkgPath' using the first 'len' characters of 'cp'.
+ */
+static struct path *
+path_new_entry(const char *cp, size_t len)
+{
+ struct path *new;
+
+ new = malloc(sizeof(*new));
+ if (new == NULL)
+ err(1, "path_create");
+
+ if (!IS_FULLPATH(cp) && !IS_URL(cp)) {
+ /* this is a relative path */
+ size_t total;
+ char cwd[MAXPATHLEN];
+ size_t cwdlen;
+
+ if (getcwd(cwd, sizeof(cwd)) == NULL)
+ err(1, "getcwd");
+ cwdlen = strlen(cwd);
+ total = cwdlen + 1 + len + 1;
+ new->pl_path = malloc(total);
+ if (new->pl_path == NULL)
+ err(1, "path_create");
+ snprintf(new->pl_path, total, "%s/%*.*s", cwd, (int)len, (int)len, cp);
+ }
+ else {
+ new->pl_path = malloc(len + 1);
+ if (new->pl_path == NULL)
+ err(1, "path_create");
+ memcpy(new->pl_path, cp, len);
+ new->pl_path[len] = '\0';
+ }
+ return new;
+}
+
+/*
+ * path_prepend_from_pkgname: prepend the path for a package onto 'PkgPath'
+ */
+void
+path_prepend_from_pkgname(const char *pkgname)
+{
+ char *ptr;
+ if ((ptr = strrchr(pkgname , '/'))) {
+ prepend = path_new_entry(pkgname, ptr - pkgname);
+ TAILQ_INSERT_HEAD(&PkgPath, prepend, pl_entry);
+ }
+}
+
+/*
+ * path_prepend_clear: Remove any prepended entry from 'PkgPath'
+ */
+void
+path_prepend_clear()
+{
+ if (prepend) {
+ TAILQ_REMOVE(&PkgPath, prepend, pl_entry);
+ prepend = 0;
+ }
+}
+
+/*
+ * path_setenv: construct string from PkgPath and set it to a environment.
+ *
+ * => the environment name is given by envname.
+ */
+void
+path_setenv(const char *envname)
+{
+ struct path *p;
+ ssize_t len = 0;
+ char *env, *env0, *envend;
+ char *sep;
+
+ TAILQ_FOREACH(p, &PkgPath, pl_entry)
+ len += strlen(p->pl_path) + 1;
+
+ env = malloc(len);
+ if (env == NULL)
+ err(1, "path_setenv");
+
+ env0 = env;
+ envend = env + len;
+ sep = "";
+ TAILQ_FOREACH(p, &PkgPath, pl_entry) {
+ int r;
+
+ r = snprintf(env, envend - env, "%s%s", sep, p->pl_path);
+ if (r < 0 || r >= envend - env)
+ err(1, "snprintf");
+ env += r;
+ sep = ";";
+ }
+
+ if (Verbose)
+ printf("%s = %s\n", envname, env0);
+ if (setenv(envname, env0, 1) != 0)
+ err(1, "setenv");
+ free(env0);
+}
diff --git a/pkgtools/pkg_install/files/lib/path.h b/pkgtools/pkg_install/files/lib/path.h
new file mode 100644
index 00000000000..1b7a301e251
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/path.h
@@ -0,0 +1,40 @@
+/* $NetBSD: path.h,v 1.1.1.1 2002/12/20 18:14:06 schmonz Exp $ */
+
+/*-
+ * Copyright (c)2002 YAMAMOTO Takashi,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+struct path {
+ TAILQ_ENTRY(path) pl_entry;
+ char *pl_path;
+};
+
+TAILQ_HEAD(pathhead, path);
+extern struct pathhead PkgPath;
+void path_create(const char *);
+void path_free(void);
+void path_prepend_from_pkgname(const char *);
+void path_prepend_clear(void);
+void path_setenv(const char *);
diff --git a/pkgtools/pkg_install/files/lib/pen.c b/pkgtools/pkg_install/files/lib/pen.c
new file mode 100644
index 00000000000..7373f5a1df6
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/pen.c
@@ -0,0 +1,417 @@
+/* $NetBSD: pen.c,v 1.1.1.1 2002/12/20 18:14:03 schmonz Exp $ */
+
+#if 0
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static const char *rcsid = "from FreeBSD Id: pen.c,v 1.25 1997/10/08 07:48:12 charnier Exp";
+#else
+__RCSID("$NetBSD: pen.c,v 1.1.1.1 2002/12/20 18:14:03 schmonz Exp $");
+#endif
+#endif
+#endif
+
+/*
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 18 July 1993
+ *
+ * Routines for managing the "play pen".
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#include "lib.h"
+
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
+
+#ifdef HAVE_SYS_VFS_H
+#include <sys/vfs.h>
+#endif
+
+/* For keeping track of where we are */
+static char Current[FILENAME_MAX];
+static char Previous[FILENAME_MAX];
+static int CurrentSet; /* rm -rf Current only if it's really set! */
+ /* CurrentSet is set to 0 before strcpy()s
+ * to prevent rm'ing of a partial string
+ * when interrupted by ^C */
+
+#if 0
+/*
+ * Backup Current and Previous into temp. strings that are later
+ * restored & freed by restore_dirs
+ * This is to make nested calls to make_playpen/leave_playpen work
+ */
+void
+save_dirs(char **c, char **p)
+{
+ *c = strdup(Current); /* XXX */
+ *p = strdup(Previous);
+}
+
+/*
+ * Restore Current and Previous from temp strings that were created
+ * by safe_dirs.
+ * This is to make nested calls to make_playpen/leave_playpen work
+ */
+void
+restore_dirs(char *c, char *p)
+{
+ CurrentSet = 0; /* prevent from deleting */
+ strcpy(Current, c);
+ CurrentSet = 1; /* rm -fr Current is safe now */
+ free(c);
+
+ strcpy(Previous, p);
+ free(p);
+}
+#endif
+
+char *
+where_playpen(void)
+{
+ return Current;
+}
+
+/*
+ * Find a good place to play.
+ */
+static char *
+find_play_pen(char *pen, size_t pensize, size_t sz)
+{
+ char *cp;
+ struct stat sb;
+
+ if (pen && pen[0] && stat(pen, &sb) != FAIL && (min_free(pen) >= sz))
+ return pen;
+ else if ((cp = getenv("PKG_TMPDIR")) != NULL && stat(cp, &sb) != FAIL && (min_free(cp) >= sz))
+ (void) snprintf(pen, pensize, "%s/instmp.XXXXXX", cp);
+ else if ((cp = getenv("TMPDIR")) != NULL && stat(cp, &sb) != FAIL && (min_free(cp) >= sz))
+ (void) snprintf(pen, pensize, "%s/instmp.XXXXXX", cp);
+ else if (stat("/var/tmp", &sb) != FAIL && min_free("/var/tmp") >= sz)
+ strcpy(pen, "/var/tmp/instmp.XXXXXX");
+ else if (stat("/tmp", &sb) != FAIL && min_free("/tmp") >= sz)
+ strcpy(pen, "/tmp/instmp.XXXXXX");
+ else if (stat("/usr/tmp", &sb) != FAIL && min_free("/usr/tmp") >= sz)
+ strcpy(pen, "/usr/tmp/instmp.XXXXXX");
+ else {
+ cleanup(0);
+ errx(2,
+ "can't find enough temporary space to extract the files, please set your\n"
+ "PKG_TMPDIR environment variable to a location with at least %lu bytes\n"
+ "free", (u_long) sz);
+ return NULL;
+ }
+ return pen;
+}
+
+#if !defined(HAVE_MKDTEMP)
+static char *
+mkdtemp(char *template)
+{
+ /* mkdtemp(3) is not present on 1.3.3 and below */
+ if (!mktemp(template)) {
+ cleanup(0);
+ errx(2, "can't mktemp '%s'", template);
+ }
+ if (mkdir(template, 0700) < 0) {
+ cleanup(0);
+ errx(2, "can't mkdir '%s'", template);
+ }
+ return template;
+}
+#endif
+
+/*
+ * Make a temporary directory to play in and chdir() to it, returning
+ * pathname of previous working directory.
+ */
+char *
+make_playpen(char *pen, size_t pensize, size_t sz)
+{
+ if (!find_play_pen(pen, pensize, sz))
+ return NULL;
+
+ if (!mkdtemp(pen)) {
+ cleanup(0);
+ errx(2, "can't mkdtemp '%s'", pen);
+ }
+ if (Verbose) {
+ if (sz)
+ fprintf(stderr,
+ "Requested space: %lu bytes, free space: %lld bytes in %s\n",
+ (u_long) sz, (long long) min_free(pen), pen);
+ }
+ if (min_free(pen) < sz) {
+ rmdir(pen);
+ cleanup(0);
+ errx(2, "not enough free space to create '%s'.\n"
+ "Please set your PKG_TMPDIR environment variable to a location\n"
+ "with more space and\ntry the command again", pen);
+ }
+ if (Current[0])
+ strcpy(Previous, Current);
+ else if (!getcwd(Previous, FILENAME_MAX)) {
+ cleanup(0);
+ err(1, "fatal error during execution: getcwd");
+ }
+ if (chdir(pen) == FAIL) {
+ cleanup(0);
+ errx(2, "can't chdir to '%s'", pen);
+ }
+ strcpy(Current, pen); CurrentSet = 1;
+
+ return Previous;
+}
+
+/*
+ * Convenience routine for getting out of playpen
+ */
+void
+leave_playpen(char *save)
+{
+ void (*oldsig) (int);
+
+ /* Make us interruptable while we're cleaning up - just in case... */
+ oldsig = signal(SIGINT, SIG_DFL);
+ if (Previous[0] && chdir(Previous) == FAIL) {
+ cleanup(0);
+ errx(2, "can't chdir back to '%s'", Previous);
+ } else if (CurrentSet && Current[0] && strcmp(Current, Previous)) {
+ if (strcmp(Current, "/") == 0) {
+ fprintf(stderr, "PANIC: About to rm -rf / (not doing so, aborting)\n");
+ abort();
+ }
+ if (vsystem("%s -rf %s", RM, Current))
+ warnx("couldn't remove temporary dir '%s'", Current);
+ strcpy(Current, Previous);
+ }
+ if (save)
+ strcpy(Previous, save);
+ else
+ Previous[0] = '\0';
+ signal(SIGINT, oldsig);
+}
+
+/*
+ * Solaris 2.7 and 2.8 have statfs(2), but it is deprecated, and has a
+ * different interface to NetBSD's statfs.
+ * We do this autoconf dance here to get around the old interface (it's
+ * in libc on 2.7 and 2.8, but not in 2.9)
+ */
+#if !defined(HAVE_STATFS) || (defined(HAVE_STATFS) && defined(HAVE_STATVFS))
+/* $NetBSD: pen.c,v 1.1.1.1 2002/12/20 18:14:03 schmonz Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <sys/statvfs.h>
+
+#define MFSNAMELEN 16 /* length of fs type name, including nul */
+#define MNAMELEN 90 /* length of buffer for returned name */
+
+struct statfs {
+ short f_type; /* type of file system */
+ u_short f_flags; /* copy of mount flags */
+ long f_bsize; /* fundamental file system block size */
+ long f_iosize; /* optimal transfer block size */
+ long f_blocks; /* total data blocks in file system */
+ long f_bfree; /* free blocks in fs */
+ long f_bavail; /* free blocks avail to non-superuser */
+ long f_files; /* total file nodes in file system */
+ long f_ffree; /* free file nodes in fs */
+ fsid_t f_fsid; /* file system id */
+ uid_t f_owner; /* user that mounted the file system */
+ long f_spare[4]; /* spare for later */
+ char f_fstypename[MFSNAMELEN]; /* fs type name */
+ char f_mntonname[MNAMELEN]; /* directory on which mounted */
+ char f_mntfromname[MNAMELEN]; /* mounted file system */
+};
+
+#ifndef MNT_RDONLY
+#define MNT_RDONLY 0x00000001 /* read only filesystem */
+#endif
+
+#ifndef MNT_NOSUID
+#define MNT_NOSUID 0x00000008 /* don't honor setuid bits on fs */
+#endif
+
+static void vfs2fs(struct statfs *, const struct statvfs *);
+
+static void
+vfs2fs(struct statfs *sfs, const struct statvfs *vfs)
+{
+ sfs->f_type = 0; /* ok */
+ sfs->f_flags = 0;
+ if (vfs->f_flag & ST_RDONLY)
+ sfs->f_flags |= MNT_RDONLY;
+ if (vfs->f_flag & ST_NOSUID)
+ sfs->f_flags |= MNT_NOSUID;
+
+ /*
+ * From a quick survey of f_bsize, f_iosize, and f_frsize on
+ * various NetBSD and Solaris systems, with varying fragment and
+ * block sizes:
+ *
+ * f_bsize f_iosize f_frsize
+ * netbsd 1k/8k 1024 8192
+ * netbsd 2k/16k 2048 16384
+ * solaris 1k/8k 8192 1024
+ * solaris 2k/8k 8192 2048
+ * solaris 512/4k 4096 512
+ *
+ * It is apparent that:
+ *
+ * - netbsd's f_bsize is equivalent to the fragment size of the
+ * underlying filesystem
+ * - netbsd's f_iosize is equivalent to the block size of the
+ * underlying filesystem
+ * - solaris's f_bsize is equivalent to the block size of the
+ * underlying filesystem
+ * - solaris's f_frsize is equivalent to the fragment size of the
+ * underlying filesystem
+ *
+ * NetBSD's statfs(2) man page (and sys/mount.h header file) says:
+ *
+ * long f_bsize; /* fundamental file system block size * /
+ * long f_iosize; /* optimal transfer block size * /
+ *
+ * and Solaris's statvfs(2) man page says:
+ *
+ * u_long f_bsize; /* preferred file system block size * /
+ * u_long f_frsize; /* fundamental filesystem block
+ * (size if supported) * /
+ *
+ * so it makes sense that their f_frsize == our f_bsize.
+ *
+ * I see that Solaris's sys/statvfs.h says:
+ *
+ * unsigned long f_bsize; /* fundamental file system block size * /
+ * unsigned long f_frsize; /* fragment size * /
+ *
+ * but empiric testing (above) seems to indicate that the comments
+ * in their code are wrong. The following two assignments, even
+ * though they may look wrong, are actually correct.
+ */
+ sfs->f_bsize = vfs->f_frsize;
+ sfs->f_iosize = vfs->f_bsize;
+ sfs->f_blocks = vfs->f_blocks;
+ sfs->f_bfree = vfs->f_bfree;
+ sfs->f_bavail = vfs->f_bavail;
+ sfs->f_files = vfs->f_files;
+ sfs->f_ffree = vfs->f_ffree;
+ (void) memcpy(&sfs->f_fsid.val[0], &vfs->f_fsid, sizeof(fsid_t));
+ sfs->f_owner = 0; /* XXX: root always here */
+ (void)strncpy(sfs->f_fstypename,
+ vfs->f_basetype, sizeof(sfs->f_fstypename));
+ sfs->f_mntonname[0] = '\0'; /* XXX: */
+ sfs->f_mntfromname[0] = '\0'; /* XXX: */
+}
+
+int
+statfs(path, sfs)
+ const char *path;
+ struct statfs *sfs;
+{
+ struct statvfs vfs;
+
+ if (statvfs(path, &vfs) == -1)
+ return -1;
+ vfs2fs(sfs, &vfs);
+ return 0;
+
+}
+
+int
+fstatfs(fd, sfs)
+ int fd;
+ struct statfs *sfs;
+{
+ struct statvfs vfs;
+
+ if (fstatvfs(fd, &vfs) == -1)
+ return -1;
+
+ vfs2fs(sfs, &vfs);
+ return 0;
+}
+#endif
+
+/*
+ * Return free disk space (in bytes) on given file system
+ */
+off_t
+min_free(char *tmpdir)
+{
+ struct statfs buf;
+
+ if (statfs(tmpdir, &buf) != 0) {
+ warn("statfs");
+ return -1;
+ }
+ return (off_t) buf.f_bavail * (off_t) buf.f_bsize;
+}
diff --git a/pkgtools/pkg_install/files/lib/pkgdb.c b/pkgtools/pkg_install/files/lib/pkgdb.c
new file mode 100644
index 00000000000..1ae6d622307
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/pkgdb.c
@@ -0,0 +1,275 @@
+/* $NetBSD: pkgdb.c,v 1.1.1.1 2002/12/20 18:14:03 schmonz Exp $ */
+
+#if 0
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: pkgdb.c,v 1.1.1.1 2002/12/20 18:14:03 schmonz Exp $");
+#endif
+#endif
+
+/*
+ * Copyright (c) 1999 Hubert Feyrer. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Hubert Feyrer for
+ * the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_DB1_DB_H
+#include <db1/db.h>
+#elif defined(HAVE_DB_H)
+#include <db.h>
+#endif
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#include <errno.h>
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "lib.h"
+
+#define PKGDB_FILE "pkgdb.byfile.db" /* indexed by filename */
+
+#if defined(HAVE_DBOPEN)
+static DB *pkgdbp;
+static int pkgdb_iter_flag;
+#endif /* HAVE_DBOPEN */
+
+/*
+ * Open the pkg-database
+ * Return value:
+ * 0: everything ok
+ * -1: error, see errno
+ */
+int
+pkgdb_open(int ro)
+{
+#if defined(HAVE_DBOPEN)
+ BTREEINFO info;
+
+ pkgdb_iter_flag = 0; /* used in pkgdb_iter() */
+
+ /* try our btree format first */
+ info.flags = 0;
+ info.cachesize = 2*1024*1024;
+ info.maxkeypage = 0;
+ info.minkeypage = 0;
+ info.psize = 4096;
+ info.compare = NULL;
+ info.prefix = NULL;
+ info.lorder = 0;
+ pkgdbp = (DB *) dbopen(_pkgdb_getPKGDB_FILE(),
+ ro ? O_RDONLY : O_RDWR | O_CREAT,
+ 0644, DB_BTREE, (void *) &info);
+ return (pkgdbp == NULL) ? -1 : 0;
+#else
+ return 1;
+#endif /* HAVE_DBOPEN */
+}
+
+/*
+ * Close the pkg database
+ */
+void
+pkgdb_close(void)
+{
+#if defined(HAVE_DBOPEN)
+ if (pkgdbp != NULL) {
+ (void) (pkgdbp->close) (pkgdbp);
+ pkgdbp = NULL;
+ }
+#endif /* HAVE_DBOPEN */
+}
+
+/*
+ * Store value "val" with key "key" in database
+ * Return value is as from ypdb_store:
+ * 0: ok
+ * 1: key already present
+ * -1: some other error, see errno
+ */
+int
+pkgdb_store(const char *key, const char *val)
+{
+#if defined(HAVE_DBOPEN)
+ DBT keyd, vald;
+
+ if (pkgdbp == NULL)
+ return -1;
+
+ keyd.data = (void *) key;
+ keyd.size = strlen(key) + 1;
+ vald.data = (void *) val;
+ vald.size = strlen(val) + 1;
+
+ if (keyd.size > FILENAME_MAX || vald.size > FILENAME_MAX)
+ return -1;
+
+ return (pkgdbp->put) (pkgdbp, &keyd, &vald, R_NOOVERWRITE);
+#else
+ return 0;
+#endif /* HAVE_DBOPEN */
+}
+
+/*
+ * Recall value for given key
+ * Return value:
+ * NULL if some error occurred or value for key not found (check errno!)
+ * String for "value" else
+ */
+char *
+pkgdb_retrieve(const char *key)
+{
+#if defined(HAVE_DBOPEN)
+ DBT keyd, vald;
+ int status;
+
+ if (pkgdbp == NULL)
+ return NULL;
+
+ keyd.data = (void *) key;
+ keyd.size = strlen(key) + 1;
+ errno = 0; /* to be sure it's 0 if the key doesn't match anything */
+
+ vald.data = (void *)NULL;
+ vald.size = 0;
+ status = (pkgdbp->get) (pkgdbp, &keyd, &vald, 0);
+ if (status) {
+ vald.data = NULL;
+ vald.size = 0;
+ }
+
+ return vald.data;
+#else
+ return NULL;
+#endif /* HAVE_DBOPEN */
+}
+
+/*
+ * Remove data set from pkgdb
+ * Return value as ypdb_delete:
+ * 0: everything ok
+ * 1: key not present
+ * -1: some error occurred (see errno)
+ */
+int
+pkgdb_remove(const char *key)
+{
+#if defined(HAVE_DBOPEN)
+ DBT keyd;
+ int status;
+
+ if (pkgdbp == NULL)
+ return -1;
+
+ keyd.data = (char *) key;
+ keyd.size = strlen(key) + 1;
+ if (keyd.size > FILENAME_MAX)
+ return -1;
+
+ errno = 0;
+ status = (pkgdbp->del) (pkgdbp, &keyd, 0);
+ if (status) {
+ if (errno)
+ return -1; /* error */
+ else
+ return 1; /* key not present */
+ } else
+ return 0; /* everything fine */
+#else
+ return 0;
+#endif /* HAVE_DBOPEN */
+}
+
+/*
+ * Iterate all pkgdb keys (which can then be handled to pkgdb_retrieve())
+ * Return value:
+ * NULL if no more data is available
+ * !NULL else
+ */
+char *
+pkgdb_iter(void)
+{
+#if defined(HAVE_DBOPEN)
+ DBT key, val;
+ int status;
+
+ if (pkgdb_iter_flag == 0) {
+ pkgdb_iter_flag = 1;
+
+ status = (pkgdbp->seq) (pkgdbp, &key, &val, R_FIRST);
+ } else
+ status = (pkgdbp->seq) (pkgdbp, &key, &val, R_NEXT);
+
+ if (status)
+ key.data = NULL;
+
+ return (char *) key.data;
+#else
+ return NULL;
+#endif /* HAVE_DBOPEN */
+}
+
+/*
+ * Return filename as string that can be passed to free(3)
+ */
+char *
+_pkgdb_getPKGDB_FILE(void)
+{
+ char *tmp;
+
+ tmp = malloc(FILENAME_MAX);
+ if (tmp == NULL)
+ errx(1, "_pkgdb_getPKGDB_FILE: out of memory");
+ snprintf(tmp, FILENAME_MAX, "%s/%s", _pkgdb_getPKGDB_DIR(), PKGDB_FILE);
+ return tmp;
+}
+
+/*
+ * Return directory where pkgdb is stored
+ * as string that can be passed to free(3)
+ */
+char *
+_pkgdb_getPKGDB_DIR(void)
+{
+ char *tmp;
+ static char *cache = NULL;
+
+ if (cache == NULL)
+ cache = (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR;
+
+ return cache;
+}
diff --git a/pkgtools/pkg_install/files/lib/plist.c b/pkgtools/pkg_install/files/lib/plist.c
new file mode 100644
index 00000000000..c0466cc4d4d
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/plist.c
@@ -0,0 +1,524 @@
+/* $NetBSD: plist.c,v 1.1.1.1 2002/12/20 18:14:04 schmonz Exp $ */
+
+#if 0
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static const char *rcsid = "from FreeBSD Id: plist.c,v 1.24 1997/10/08 07:48:15 charnier Exp";
+#else
+__RCSID("$NetBSD: plist.c,v 1.1.1.1 2002/12/20 18:14:04 schmonz Exp $");
+#endif
+#endif
+#endif
+
+/*
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 18 July 1993
+ *
+ * General packing list routines.
+ *
+ */
+
+#include "lib.h"
+#include <errno.h>
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#ifdef HAVE_MD5GLOBAL_H
+#include <md5global.h>
+#endif
+
+#ifdef HAVE_MD5_H
+#include <md5.h>
+#endif
+
+/* This struct defines a plist command type */
+typedef struct cmd_t {
+ char *c_s; /* string to recognise */
+ pl_ent_t c_type; /* type of command */
+ int c_argc; /* # of arguments */
+ int c_subst; /* can substitute real prefix */
+} cmd_t;
+
+/* Commands to recognise */
+static const cmd_t cmdv[] = {
+ {"cwd", PLIST_CWD, 1, 1},
+ {"src", PLIST_SRC, 1, 1},
+ {"cd", PLIST_CWD, 1, 1},
+ {"exec", PLIST_CMD, 1, 0},
+ {"unexec", PLIST_UNEXEC, 1, 0},
+ {"mode", PLIST_CHMOD, 1, 0},
+ {"owner", PLIST_CHOWN, 1, 0},
+ {"group", PLIST_CHGRP, 1, 0},
+ {"comment", PLIST_COMMENT, 1, 0},
+ {"ignore", PLIST_IGNORE, 0, 0},
+ {"ignore_inst", PLIST_IGNORE_INST, 0, 0},
+ {"name", PLIST_NAME, 1, 0},
+ {"display", PLIST_DISPLAY, 1, 0},
+ {"pkgdep", PLIST_PKGDEP, 1, 0},
+ {"pkgcfl", PLIST_PKGCFL, 1, 0},
+ {"mtree", PLIST_MTREE, 1, 0},
+ {"dirrm", PLIST_DIR_RM, 1, 0},
+ {"option", PLIST_OPTION, 1, 0},
+ {"blddep", PLIST_BLDDEP, 1, 0},
+ {NULL, FAIL, 0, 0}
+};
+
+/*
+ * Add an item to the end of a packing list
+ */
+void
+add_plist(package_t *p, pl_ent_t type, const char *arg)
+{
+ plist_t *tmp;
+
+ tmp = new_plist_entry();
+ tmp->name = (arg == (char *) NULL) ? (char *) NULL : strdup(arg);
+ tmp->type = type;
+ if (!p->head) {
+ p->head = p->tail = tmp;
+ } else {
+ tmp->prev = p->tail;
+ p->tail->next = tmp;
+ p->tail = tmp;
+ }
+}
+
+/*
+ * Add an item to the start of a packing list
+ */
+void
+add_plist_top(package_t *p, pl_ent_t type, const char *arg)
+{
+ plist_t *tmp;
+
+ tmp = new_plist_entry();
+ tmp->name = (arg == (char *) NULL) ? (char *) NULL : strdup(arg);
+ tmp->type = type;
+ if (!p->head) {
+ p->head = p->tail = tmp;
+ } else {
+ tmp->next = p->head;
+ p->head->prev = tmp;
+ p->head = tmp;
+ }
+}
+
+/*
+ * Return the last (most recent) entry in a packing list
+ */
+plist_t *
+last_plist(package_t *p)
+{
+ return p->tail;
+}
+
+/*
+ * Mark all items in a packing list to prevent iteration over them
+ */
+void
+mark_plist(package_t *pkg)
+{
+ plist_t *pp;
+
+ for (pp = pkg->head; pp; pp = pp->next) {
+ pp->marked = TRUE;
+ }
+}
+
+/*
+ * Find a given item in a packing list and, if so, return it (else NULL)
+ */
+plist_t *
+find_plist(package_t *pkg, pl_ent_t type)
+{
+ plist_t *pp;
+
+ for (pp = pkg->head; pp && pp->type != type; pp = pp->next) {
+ }
+ return pp;
+}
+
+/*
+ * Look for a specific boolean option argument in the list
+ */
+char *
+find_plist_option(package_t *pkg, char *name)
+{
+ plist_t *p;
+
+ for (p = pkg->head; p; p = p->next) {
+ if (p->type == PLIST_OPTION
+ && strcmp(p->name, name) == 0) {
+ return p->name;
+ }
+ }
+
+ return (char *) NULL;
+}
+
+/*
+ * Delete plist item 'type' in the list (if 'name' is non-null, match it
+ * too.) If 'all' is set, delete all items, not just the first occurance.
+ */
+void
+delete_plist(package_t *pkg, Boolean all, pl_ent_t type, char *name)
+{
+ plist_t *p = pkg->head;
+
+ while (p) {
+ plist_t *pnext = p->next;
+
+ if (p->type == type && (!name || !strcmp(name, p->name))) {
+ free(p->name);
+ if (p->prev)
+ p->prev->next = pnext;
+ else
+ pkg->head = pnext;
+ if (pnext)
+ pnext->prev = p->prev;
+ else
+ pkg->tail = p->prev;
+ free(p);
+ if (!all)
+ return;
+ p = pnext;
+ } else
+ p = p->next;
+ }
+}
+
+/*
+ * Allocate a new packing list entry, and return a pointer to it.
+ */
+plist_t *
+new_plist_entry(void)
+{
+ plist_t *ret;
+
+ if ((ret = (plist_t *) malloc(sizeof(plist_t))) == (plist_t *) NULL) {
+ err(EXIT_FAILURE, "can't allocate %ld bytes", (long) sizeof(plist_t));
+ }
+ memset(ret, 0, sizeof(plist_t));
+ return ret;
+}
+
+/*
+ * Free an entire packing list
+ */
+void
+free_plist(package_t *pkg)
+{
+ plist_t *p = pkg->head;
+
+ while (p) {
+ plist_t *p1 = p->next;
+
+ free(p->name);
+ free(p);
+ p = p1;
+ }
+ pkg->head = pkg->tail = NULL;
+}
+
+/*
+ * For an ASCII string denoting a plist command, return its code and
+ * optionally its argument(s)
+ */
+int
+plist_cmd(char *s, char **arg)
+{
+ const cmd_t *cmdp;
+ char cmd[FILENAME_MAX + 20]; /* 20 == fudge for max cmd len */
+ char *cp;
+ char *sp;
+
+ (void) strcpy(cmd, s);
+ str_lowercase(cmd);
+ for (cp = cmd, sp = s; *cp; cp++, sp++) {
+ if (isspace((unsigned char) *cp)) {
+ for (*cp = '\0'; isspace((unsigned char) *sp); sp++) {
+ }
+ break;
+ }
+ }
+ if (arg) {
+ *arg = sp;
+ }
+ for (cmdp = cmdv; cmdp->c_s && strcmp(cmdp->c_s, cmd) != 0; cmdp++) {
+ }
+ return cmdp->c_type;
+}
+
+/*
+ * Read a packing list from a file
+ */
+void
+read_plist(package_t *pkg, FILE * fp)
+{
+ char pline[FILENAME_MAX];
+ char *cp;
+ int cmd;
+ int len;
+
+ while (fgets(pline, FILENAME_MAX, fp) != (char *) NULL) {
+ for (len = strlen(pline); len &&
+ isspace((unsigned char) pline[len - 1]);) {
+ pline[--len] = '\0';
+ }
+ if (len == 0) {
+ continue;
+ }
+ if (*(cp = pline) == CMD_CHAR) {
+ if ((cmd = plist_cmd(pline + 1, &cp)) == FAIL) {
+ warnx("Unrecognised PLIST command `%s'", pline);
+ continue;
+ }
+ if (*cp == '\0') {
+ cp = NULL;
+ }
+ } else {
+ cmd = PLIST_FILE;
+ }
+ add_plist(pkg, cmd, cp);
+ }
+}
+
+/*
+ * Write a packing list to a file, converting commands to ASCII equivs
+ */
+void
+write_plist(package_t *pkg, FILE * fp, char *realprefix)
+{
+ plist_t *p;
+ const cmd_t *cmdp;
+
+ for (p = pkg->head; p; p = p->next) {
+ if (p->type == PLIST_FILE) {
+ /* Fast-track files - these are the most common */
+ (void) fprintf(fp, "%s\n", p->name);
+ continue;
+ }
+ for (cmdp = cmdv; cmdp->c_type != FAIL && cmdp->c_type != p->type; cmdp++) {
+ }
+ if (cmdp->c_type == FAIL) {
+ warnx("Unknown PLIST command type %d (%s)", p->type, p->name);
+ } else if (cmdp->c_argc == 0) {
+ (void) fprintf(fp, "%c%s\n", CMD_CHAR, cmdp->c_s);
+ } else if (cmdp->c_subst && realprefix) {
+ (void) fprintf(fp, "%c%s %s\n", CMD_CHAR, cmdp->c_s, realprefix);
+ } else {
+ (void) fprintf(fp, "%c%s %s\n", CMD_CHAR, cmdp->c_s,
+ (p->name) ? p->name : "");
+ }
+ }
+}
+
+/*
+ * Delete the results of a package installation.
+ *
+ * This is here rather than in the pkg_delete code because pkg_add needs to
+ * run it too in cases of failure.
+ */
+int
+delete_package(Boolean ign_err, Boolean nukedirs, package_t *pkg)
+{
+ plist_t *p;
+ char *Where = ".", *last_file = "";
+ int fail = SUCCESS;
+ Boolean preserve;
+ char tmp[FILENAME_MAX], *name = NULL;
+
+ if (pkgdb_open(0) == -1) {
+ err(1, "cannot open pkgdb");
+ }
+
+ preserve = find_plist_option(pkg, "preserve") ? TRUE : FALSE;
+ for (p = pkg->head; p; p = p->next) {
+ switch (p->type) {
+ case PLIST_NAME:
+ name = p->name;
+ break;
+
+ case PLIST_IGNORE:
+ p = p->next;
+ break;
+
+ case PLIST_CWD:
+ Where = p->name;
+ if (Verbose)
+ printf("Change working directory to %s\n", Where);
+ break;
+
+ case PLIST_UNEXEC:
+ format_cmd(tmp, sizeof(tmp), p->name, Where, last_file);
+ if (Verbose)
+ printf("Execute `%s'\n", tmp);
+ if (!Fake && system(tmp)) {
+ warnx("unexec command for `%s' failed", tmp);
+ fail = FAIL;
+ }
+ break;
+
+ case PLIST_FILE:
+ last_file = p->name;
+ (void) snprintf(tmp, sizeof(tmp), "%s/%s", Where, p->name);
+ if (isdir(tmp)) {
+ warnx("attempting to delete directory `%s' as a file\n"
+ "this packing list is incorrect - ignoring delete request", tmp);
+ } else {
+ if (p->next &&
+ p->next->type == PLIST_COMMENT && /* || PLIST_MD5 - HF */
+ strncmp(p->next->name, CHECKSUM_HEADER, ChecksumHeaderLen) == 0) {
+ char *cp, buf[LegibleChecksumLen];
+
+ if ((cp = MD5File(tmp, buf)) != NULL) {
+ /* Mismatch? */
+ if (strcmp(cp, p->next->name + ChecksumHeaderLen) != 0) {
+ if (Verbose) {
+ printf("%s fails original MD5 checksum - %s\n",
+ tmp, Force ? "deleted anyway." : "not deleted.");
+ }
+ if (!Force) {
+ fail = FAIL;
+ continue;
+ }
+ }
+ }
+ }
+ if (Verbose)
+ printf("Delete file %s\n", tmp);
+ if (!Fake) {
+ int restored = 0; /* restored from preserve? */
+
+ if (delete_hierarchy(tmp, ign_err, nukedirs))
+ fail = FAIL;
+ if (preserve && name) {
+ char tmp2[FILENAME_MAX];
+
+ if (make_preserve_name(tmp2, FILENAME_MAX, name, tmp)) {
+ if (fexists(tmp2)) {
+ if (rename(tmp2, tmp))
+ warn("preserve: unable to restore %s as %s",
+ tmp2, tmp);
+ else
+ restored = 1;
+ }
+ }
+ }
+
+ if (!restored) {
+#ifdef PKGDB_DEBUG
+ printf("pkgdb_remove(\"%s\")\n", tmp); /* HF */
+#endif
+ errno = 0;
+ if (pkgdb_remove(tmp)) {
+ if (errno) {
+ perror("pkgdb_remove");
+ }
+ } else {
+#ifdef PKGDB_DEBUG
+ printf("pkgdb_remove: ok\n");
+#endif
+ }
+ }
+ }
+ }
+ break;
+
+ case PLIST_DIR_RM:
+ (void) snprintf(tmp, sizeof(tmp), "%s/%s", Where, p->name);
+ if (fexists(tmp)) {
+ if (!isdir(tmp)) {
+ warnx("cannot remove `%s' as a directory\n"
+ "this packing list is incorrect - ignoring delete request", tmp);
+ } else {
+ if (Verbose)
+ printf("Delete directory %s\n", tmp);
+ if (!Fake && delete_hierarchy(tmp, ign_err, FALSE)) {
+ warnx("unable to completely remove directory '%s'", tmp);
+ fail = FAIL;
+ }
+ }
+ } else {
+ warnx("cannot remove non-existent directory `%s'\n"
+ "this packing list is incorrect - ignoring delete request", tmp);
+ }
+ last_file = p->name;
+ break;
+ default:
+ break;
+ }
+ }
+ pkgdb_close();
+ return fail;
+}
+
+#ifdef DEBUG
+#define RMDIR(dir) vsystem("%s %s", RMDIR, dir)
+#define REMOVE(dir,ie) vsystem("%s %s%s", RM, (ie ? "-f " : ""), dir)
+#else
+#define RMDIR rmdir
+#define REMOVE(file,ie) (remove(file) && !(ie))
+#endif
+
+/*
+ * Selectively delete a hierarchy
+ * Returns 1 on error, 0 else.
+ */
+int
+delete_hierarchy(char *dir, Boolean ign_err, Boolean nukedirs)
+{
+ char *cp1, *cp2;
+
+ cp1 = cp2 = dir;
+ if (!fexists(dir)) {
+ if (!ign_err)
+ warnx("%s `%s' doesn't really exist",
+ isdir(dir) ? "directory" : "file", dir);
+ return !ign_err;
+ } else if (nukedirs) {
+ if (vsystem("%s -r%s %s", RM, (ign_err ? "f" : ""), dir))
+ return 1;
+ } else if (isdir(dir)) {
+ if (RMDIR(dir) && !ign_err)
+ return 1;
+ } else {
+ if (REMOVE(dir, ign_err))
+ return 1;
+ }
+
+ if (!nukedirs)
+ return 0;
+ while (cp2) {
+ if ((cp2 = strrchr(cp1, '/')) != NULL)
+ *cp2 = '\0';
+ if (!isemptydir(dir))
+ return 0;
+ if (RMDIR(dir) && !ign_err) {
+ if (!fexists(dir))
+ warnx("directory `%s' doesn't really exist", dir);
+ else
+ return 1;
+ }
+ /* back up the pathname one component */
+ if (cp2) {
+ cp1 = dir;
+ }
+ }
+ return 0;
+}
diff --git a/pkgtools/pkg_install/files/lib/setenv.c b/pkgtools/pkg_install/files/lib/setenv.c
new file mode 100644
index 00000000000..bce4c082930
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/setenv.c
@@ -0,0 +1,74 @@
+/* $NetBSD: setenv.c,v 1.1.1.1 2002/12/20 18:14:06 schmonz Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <syslog.h>
+
+#ifndef HAVE_SETENV
+int
+setenv(name, value, overwrite)
+ const char *name;
+ const char *value;
+ int overwrite;
+{
+ size_t len;
+ int ret;
+ char *p;
+
+ if (overwrite == 0 && getenv(name))
+ return 0;
+
+ if (value == NULL)
+ value = "";
+
+ len = strlen(name) + strlen(value) + 2;
+ p = (char *) malloc(len);
+ if (p == NULL)
+ return -1;
+
+ (void) sprintf(p, "%s=%s", name, value);
+ ret = putenv(p);
+ return ret;
+}
+#endif
diff --git a/pkgtools/pkg_install/files/lib/setprogname.c b/pkgtools/pkg_install/files/lib/setprogname.c
new file mode 100644
index 00000000000..1de44d32f4b
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/setprogname.c
@@ -0,0 +1,63 @@
+/* $Id: setprogname.c,v 1.1.1.1 2002/12/20 18:14:06 schmonz Exp $ */
+/* $NetBSD: setprogname.c,v 1.1.1.1 2002/12/20 18:14:06 schmonz Exp $ */
+
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Todd Vierling.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+static const char *__progname = "<unset_progname>";
+
+#ifndef HAVE_SETPROGNAME
+void
+setprogname(const char *progname)
+{
+ __progname = strrchr(progname, '/');
+ if (__progname == NULL)
+ __progname = progname;
+ else
+ __progname++;
+}
+#endif
+
+#ifndef HAVE_GETPROGNAME
+const char *
+getprogname(void)
+{
+ return __progname;
+}
+#endif
diff --git a/pkgtools/pkg_install/files/lib/str.c b/pkgtools/pkg_install/files/lib/str.c
new file mode 100644
index 00000000000..a994728892f
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/str.c
@@ -0,0 +1,741 @@
+/* $NetBSD: str.c,v 1.1.1.1 2002/12/20 18:14:05 schmonz Exp $ */
+
+#if 0
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static const char *rcsid = "Id: str.c,v 1.5 1997/10/08 07:48:21 charnier Exp";
+#else
+__RCSID("$NetBSD: str.c,v 1.1.1.1 2002/12/20 18:14:05 schmonz Exp $");
+#endif
+#endif
+#endif
+
+/*
+ * FreeBSD install - a package for the installation and maintainance
+ * of non-core utilities.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Jordan K. Hubbard
+ * 18 July 1993
+ *
+ * Miscellaneous string utilities.
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_ASSERT_H
+#include <assert.h>
+#endif
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#endif
+
+#ifdef HAVE_FNMATCH_H
+#include <fnmatch.h>
+#endif
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include "lib.h"
+
+/*
+ * Return the suffix portion of a path
+ */
+const char *
+suffix_of(const char *str)
+{
+ const char *dot;
+
+ return ((dot = strrchr(basename_of(str), '.')) == NULL) ? "" : dot + 1;
+}
+
+/*
+ * Return the filename portion of a path
+ */
+const char *
+basename_of(const char *str)
+{
+ const char *slash;
+
+ return ((slash = strrchr(str, '/')) == NULL) ? str : slash + 1;
+}
+
+/*
+ * Return the dirname portion of a path
+ */
+const char *
+dirname_of(const char *path)
+{
+ size_t cc;
+ char *s;
+ static char buf[PATH_MAX];
+
+ if ((s = strrchr(path, '/')) == NULL) {
+ return ".";
+ }
+ if (s == path) {
+ /* "/foo" -> return "/" */
+ return "/";
+ }
+ cc = (size_t) (s - path);
+ if (cc >= sizeof(buf))
+ errx(1, "dirname_of: too long dirname: '%s'", path);
+ (void) memcpy(buf, path, cc);
+ buf[cc] = 0;
+ return buf;
+}
+
+/*
+ * Get a string parameter as a file spec or as a "contents follow -" spec
+ */
+char *
+get_dash_string(char **s)
+{
+ return *s = (**s == '-') ? strdup(*s + 1) : fileGetContents(*s);
+}
+
+/*
+ * Lowercase a whole string
+ */
+void
+str_lowercase(char *s)
+{
+ for (; *s; s++) {
+ *s = tolower(*s);
+ }
+}
+
+/* pull in definitions and macros for resizing arrays as we go */
+#include "defs.h"
+
+/* do not modify these values, or things will NOT work */
+enum {
+ RC = -1,
+ Dot = 0,
+ Patch = 1
+};
+
+/* this struct defines a version number */
+typedef struct arr_t {
+ unsigned c; /* # of version numbers */
+ unsigned size; /* size of array */
+ int64_t *v; /* array of decimal numbers */
+ int64_t netbsd; /* any "nb" suffix */
+} arr_t;
+
+/* this struct describes a test */
+typedef struct test_t {
+ const char *s; /* string representation */
+ unsigned len; /* length of string */
+ int t; /* enumerated type of test */
+} test_t;
+
+enum {
+ LT,
+ LE,
+ EQ,
+ GE,
+ GT,
+ NE
+};
+
+/* the tests that are recognised. */
+static const test_t tests[] = {
+ { "<=", 2, LE },
+ { "<", 1, LT },
+ { ">=", 2, GE },
+ { ">", 1, GT },
+ { "==", 2, EQ },
+ { "!=", 2, NE },
+ { NULL, 0, 0 }
+};
+
+
+/* locate the test in the tests array */
+static int
+mktest(int *op, char *test)
+{
+ const test_t *tp;
+
+ for (tp = tests ; tp->s ; tp++) {
+ if (strncasecmp(test, tp->s, tp->len) == 0) {
+ *op = tp->t;
+ return tp->len;
+ }
+ }
+ warnx("relational test not found `%.10s'", test);
+ return -1;
+}
+
+/*
+ * make a component of a version number.
+ * '.' encodes as Dot which is '0'
+ * '_' encodes as 'patch level', or 'Dot', which is 0.
+ * 'pl' encodes as 'patch level', or 'Dot', which is 0.
+ * 'rc' encodes as 'release candidate', or RC, which is -1.
+ * 'nb' encodes as 'netbsd version', which is used after all other tests
+ */
+static int
+mkcomponent(arr_t *ap, char *num)
+{
+ static const char alphas[] = "abcdefghijklmnopqrstuvwxyz";
+ int64_t n;
+ char *cp;
+
+ if (*num == 0) {
+ return 0;
+ }
+ ALLOC(int64_t, ap->v, ap->size, ap->c, 62, "mkver", exit(EXIT_FAILURE));
+ if (*num == '_') {
+ num += 1;
+ if (isdigit(*(num + 1))) {
+ ap->v[ap->c++] = Dot;
+ return 1;
+ }
+ }
+ if (isdigit(*num)) {
+ for (cp = num, n = 0 ; isdigit(*num) ; num++) {
+ n = (n * 10) + (*num - '0');
+ }
+ ap->v[ap->c++] = n;
+ return (int)(num - cp);
+ }
+ if (strncasecmp(num, "rc", 2) == 0) {
+ ap->v[ap->c++] = RC;
+ return 2;
+ }
+ if (strncasecmp(num, "pl", 2) == 0) {
+ ap->v[ap->c++] = Dot;
+ return 2;
+ }
+ if (strncasecmp(num, "nb", 2) == 0) {
+ for (cp = num, num += 2, n = 0 ; isdigit(*num) ; num++) {
+ n = (n * 10) + (*num - '0');
+ }
+ ap->netbsd = n;
+ return (int)(num - cp);
+ }
+ if (*num == '.') {
+ ap->v[ap->c++] = Dot;
+ return 1;
+ }
+ if (isalpha(*num)) {
+ ap->v[ap->c++] = Dot;
+ cp = strchr(alphas, tolower(*num));
+ ALLOC(int64_t, ap->v, ap->size, ap->c, 62, "mkver", exit(EXIT_FAILURE));
+ ap->v[ap->c++] = (int64_t)(cp - alphas) + 1;
+ return 1;
+ }
+ warnx("`%c' not recognised", *num);
+ return 1;
+}
+
+/* make a version number string into an array of comparable 64bit ints */
+static int
+mkversion(arr_t *ap, char *num)
+{
+ (void) memset(ap, 0, sizeof(arr_t));
+ while (*num) {
+ num += mkcomponent(ap, num);
+ }
+ return 1;
+}
+
+#define DIGIT(v, c, n) (((n) < (c)) ? v[n] : 0)
+
+/* compare the result against the test we were expecting */
+static int
+result(int64_t cmp, int tst)
+{
+ switch(tst) {
+ case LT:
+ return cmp < 0;
+ case LE:
+ return cmp <= 0;
+ case GT:
+ return cmp > 0;
+ case GE:
+ return cmp >= 0;
+ case EQ:
+ return cmp == 0;
+ case NE:
+ return cmp != 0;
+ default:
+ warnx("result: unknown test %d", tst);
+ return 0;
+ }
+}
+
+/* do the test on the 2 vectors */
+static int
+vtest(arr_t *lhs, int tst, arr_t *rhs)
+{
+ int64_t cmp;
+ int c;
+ int i;
+
+ for (i = 0, c = MAX(lhs->c, rhs->c) ; i < c ; i++) {
+ if ((cmp = DIGIT(lhs->v, lhs->c, i) - DIGIT(rhs->v, rhs->c, i)) != 0) {
+ return result(cmp, tst);
+ }
+ }
+ return result(lhs->netbsd - rhs->netbsd, tst);
+}
+
+/*
+ * Compare two dewey decimal numbers
+ */
+static int
+deweycmp(char *lhs, int op, char *rhs)
+{
+ arr_t right;
+ arr_t left;
+
+ (void) memset(&left, 0, sizeof(left));
+ if (!mkversion(&left, lhs)) {
+ warnx("Bad lhs version `%s'", lhs);
+ return 0;
+ }
+ (void) memset(&right, 0, sizeof(right));
+ if (!mkversion(&right, rhs)) {
+ warnx("Bad rhs version `%s'", rhs);
+ return 0;
+ }
+ return vtest(&left, op, &right);
+}
+
+/*
+ * Perform alternate match on "pkg" against "pattern",
+ * calling pmatch (recursively) to resolve any other patterns.
+ * Return 1 on match, 0 otherwise
+ */
+static int
+alternate_match(const char *pattern, const char *pkg)
+{
+ char *sep;
+ char buf[FILENAME_MAX];
+ char *last;
+ char *alt;
+ char *cp;
+ int cnt;
+ int found;
+
+ if ((sep = strchr(pattern, '{')) == (char *) NULL) {
+ errx(1, "alternate_match(): '{' expected in `%s'", pattern);
+ }
+ (void) strncpy(buf, pattern, (size_t) (sep - pattern));
+ alt = &buf[sep - pattern];
+ last = (char *) NULL;
+ for (cnt = 0, cp = sep; *cp && last == (char *) NULL; cp++) {
+ if (*cp == '{') {
+ cnt++;
+ } else if (*cp == '}' && --cnt == 0 && last == (char *) NULL) {
+ last = cp + 1;
+ }
+ }
+ if (cnt != 0) {
+ errx(1, "Malformed alternate `%s'", pattern);
+ }
+ for (found = 0, cp = sep + 1; *sep != '}'; cp = sep + 1) {
+ for (cnt = 0, sep = cp; cnt > 0 || (cnt == 0 && *sep != '}' && *sep != ','); sep++) {
+ if (*sep == '{') {
+ cnt++;
+ } else if (*sep == '}') {
+ cnt--;
+ }
+ }
+ (void) snprintf(alt, sizeof(buf) - (alt - buf), "%.*s%s", (int) (sep - cp), cp, last);
+ if (pmatch(buf, pkg) == 1) {
+ found = 1;
+ }
+ }
+ return found;
+}
+
+/*
+ * Perform dewey match on "pkg" against "pattern".
+ * Return 1 on match, 0 otherwise
+ */
+static int
+dewey_match(const char *pattern, const char *pkg)
+{
+ char *cp;
+ char *sep;
+ char *ver;
+ char name[FILENAME_MAX];
+ int op;
+ int n;
+
+ if ((sep = strpbrk(pattern, "<>")) == NULL) {
+ errx(1, "dewey_match(): '<' or '>' expected in `%s'", pattern);
+ }
+ (void) snprintf(name, sizeof(name), "%.*s", (int) (sep - pattern), pattern);
+ if ((n = mktest(&op, sep)) < 0) {
+ warnx("Bad comparison `%s'", sep);
+ return 0;
+ }
+ ver = sep + n;
+ n = (int) (sep - pattern);
+ if ((cp = strrchr(pkg, '-')) != (char *) NULL) {
+ if (strncmp(pkg, name, (size_t) (cp - pkg)) == 0 &&
+ n == (int)(cp - pkg)) {
+ if (deweycmp(cp + 1, op, ver)) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+ * Perform glob match on "pkg" against "pattern".
+ * Return 1 on match, 0 otherwise
+ */
+static int
+glob_match(const char *pattern, const char *pkg)
+{
+ return fnmatch(pattern, pkg, FNM_PERIOD) == 0;
+}
+
+/*
+ * Perform simple match on "pkg" against "pattern".
+ * Return 1 on match, 0 otherwise
+ */
+static int
+simple_match(const char *pattern, const char *pkg)
+{
+ return strcmp(pattern, pkg) == 0;
+}
+
+/*
+ * Match pkg against pattern, return 1 if matching, 0 else
+ */
+int
+pmatch(const char *pattern, const char *pkg)
+{
+ if (strchr(pattern, '{') != (char *) NULL) {
+ /* emulate csh-type alternates */
+ return alternate_match(pattern, pkg);
+ }
+ if (strpbrk(pattern, "<>") != (char *) NULL) {
+ /* perform relational dewey match on version number */
+ return dewey_match(pattern, pkg);
+ }
+ if (strpbrk(pattern, "*?[]") != (char *) NULL) {
+ /* glob match */
+ return glob_match(pattern, pkg);
+ }
+
+ /* no alternate, dewey or glob match -> simple compare */
+ return simple_match(pattern, pkg);
+}
+
+/*
+ * Search dir for pattern, calling match(pkg_found, data) for every match.
+ * Returns -1 on error, 1 if found, 0 otherwise.
+ */
+int
+findmatchingname(const char *dir, const char *pattern, matchfn match, void *data)
+{
+ struct dirent *dp;
+ char tmp_pattern[PKG_PATTERN_MAX];
+ DIR *dirp;
+ int found;
+ char pat_sfx[PKG_SUFFIX_MAX], file_sfx[PKG_SUFFIX_MAX]; /* suffixes */
+
+ if (strlen(pattern) >= PKG_PATTERN_MAX)
+ errx(1, "too long pattern '%s'", pattern);
+
+ found = 0;
+ if ((dirp = opendir(dir)) == (DIR *) NULL) {
+ /* warnx("can't opendir dir '%s'", dir); */
+ return -1;
+ }
+
+ /* chop any possible suffix off of 'pattern' and
+ * store it in pat_sfx
+ */
+ strip_txz(tmp_pattern, pat_sfx, pattern);
+
+ while ((dp = readdir(dirp)) != (struct dirent *) NULL) {
+ char tmp_file[FILENAME_MAX];
+
+ if (strcmp(dp->d_name, ".") == 0 ||
+ strcmp(dp->d_name, "..") == 0)
+ continue;
+
+ /* chop any possible suffix off of 'tmp_file' and
+ * store it in file_sfx
+ */
+ strip_txz(tmp_file, file_sfx, dp->d_name);
+
+ /* we need to match pattern and suffix separately, in case
+ * each is a different pattern class (e.g. dewey and
+ * character class (.t[bg]z)) */
+ if (pmatch(tmp_pattern, tmp_file)
+ && pmatch(pat_sfx, file_sfx)) {
+ if (match) {
+ match(dp->d_name, data);
+ /* return value ignored for now */
+ }
+ found = 1;
+ }
+ }
+ (void) closedir(dirp);
+ return found;
+}
+
+/*
+ * Does the pkgname contain any of the special chars ("{[]?*<>")?
+ * If so, return 1, else 0
+ */
+int
+ispkgpattern(const char *pkg)
+{
+ return strpbrk(pkg, "<>[]?*{") != NULL;
+}
+
+/*
+ * Auxiliary function called by findbestmatchingname() if pkg > data
+ * Also called for FTP matching
+ */
+int
+findbestmatchingname_fn(const char *found, void *vp)
+{
+ char *best = vp;
+ char *found_version, *best_version;
+ char found_no_sfx[PKG_PATTERN_MAX];
+ char best_no_sfx[PKG_PATTERN_MAX];
+
+ /* The same suffix-hack-off again, but we can't do it
+ * otherwise without changing the function call interface
+ */
+ found_version = strrchr(found, '-');
+ if (found_version) {
+ /* skip '-', if any version found */
+ found_version++;
+ }
+ strip_txz(found_no_sfx, NULL, found_version);
+ found_version = found_no_sfx;
+
+ best_version=NULL;
+ if (best && best[0] != '\0') {
+ best_version = strrchr(best, '-');
+ if (best_version) {
+ /* skip '-' if any version found */
+ best_version++;
+ }
+ strip_txz(best_no_sfx, NULL, best_version);
+ best_version = best_no_sfx;
+ }
+
+ if (found_version == NULL) {
+ fprintf(stderr, "'%s' is not a usable package(version)\n",
+ found);
+ } else {
+ /* if best_version==NULL only if best==NULL
+ * (or best[0]='\0') */
+ if (best == NULL || best[0] == '\0' || deweycmp(found_version, GT, best_version)) {
+ /* found pkg(version) is bigger than current "best"
+ * version - remember! */
+ strcpy(best, found);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Find best matching filename, i.e. the pkg with the highest
+ * matching(!) version.
+ * Returns pointer to pkg name (which can be free(3)ed),
+ * or NULL if no match is available.
+ */
+char *
+findbestmatchingname(const char *dir, const char *pattern)
+{
+ char buf[FILENAME_MAX];
+
+ buf[0] = '\0';
+ if (findmatchingname(dir, pattern, findbestmatchingname_fn, buf) > 0
+ && buf[0] != '\0') {
+ return strdup(buf);
+ }
+ return NULL;
+}
+
+/*
+ * Bounds-checking strncpy()
+ */
+char *
+strnncpy(char *to, size_t tosize, char *from, size_t cc)
+{
+ size_t len;
+
+ if ((len = cc) >= tosize - 1) {
+ len = tosize - 1;
+ }
+ (void) strncpy(to, from, len);
+ to[len] = 0;
+ return to;
+}
+
+/*
+ * Strip off any .tgz, .tbz or .t[bg]z suffix from fname,
+ * and copy into buffer "buf", the suffix is stored in "sfx"
+ * if "sfx" is not NULL. If no suffix is found, "sfx" is set
+ * to an empty string.
+ */
+void
+strip_txz(char *buf, char *sfx, const char *fname)
+{
+ static const char *const suffixes[] = {
+ ".tgz", ".tbz", ".t[bg]z", 0};
+ const char *const *suffixp;
+ size_t len;
+
+ len = strlen(fname);
+ assert(len < PKG_PATTERN_MAX);
+
+ if (sfx)
+ sfx[0] = '\0';
+
+ for (suffixp = suffixes; *suffixp; suffixp++) {
+ size_t suffixlen = strlen(*suffixp);
+
+ if (memcmp(&fname[len - suffixlen], *suffixp, suffixlen))
+ continue;
+
+ /* matched! */
+ memcpy(buf, fname, len - suffixlen);
+ buf[len - suffixlen] = 0;
+ if (sfx) {
+ if (suffixlen >= PKG_SUFFIX_MAX)
+ errx(1, "too long suffix '%s'", fname);
+ memcpy(sfx, *suffixp, suffixlen+1);
+ return;
+ }
+ }
+
+ /* not found */
+ memcpy(buf, fname, len+1);
+}
+
+/*
+ * Called to see if pkg is already installed as some other version,
+ * note found version in "note".
+ */
+int
+note_whats_installed(const char *found, void *vp)
+{
+ char *note = vp;
+
+ (void) strlcpy(note, found, FILENAME_MAX);
+ return 0;
+}
+
+/*
+ * alloc lpkg for pkg and add it to list.
+ */
+int
+add_to_list_fn(const char *pkg, void *vp)
+{
+ lpkg_head_t *pkgs = vp;
+ lpkg_t *lpp;
+ char fn[FILENAME_MAX];
+
+ snprintf(fn, sizeof(fn), "%s/%s", _pkgdb_getPKGDB_DIR(), pkg);
+ if (!isfile(fn)) { /* might as well use sanity_check() */
+ lpp = alloc_lpkg(pkg);
+ TAILQ_INSERT_TAIL(pkgs, lpp, lp_link);
+ }
+
+ return 0;
+}
+
+#ifndef HAVE_STRSEP
+/*
+ * Get next token from string *stringp, where tokens are possibly-empty
+ * strings separated by characters from delim.
+ *
+ * Writes NULs into the string at *stringp to end tokens.
+ * delim need not remain constant from call to call.
+ * On return, *stringp points past the last NUL written (if there might
+ * be further tokens), or is NULL (if there are definitely no more tokens).
+ *
+ * If *stringp is NULL, strsep returns NULL.
+ */
+char *
+strsep(char **stringp, const char *delim)
+{
+ char *s;
+ const char *spanp;
+ int c, sc;
+ char *tok;
+
+ if ((s = *stringp) == NULL)
+ return (NULL);
+ for (tok = s;;) {
+ c = *s++;
+ spanp = delim;
+ do {
+ if ((sc = *spanp++) == c) {
+ if (c == 0)
+ s = NULL;
+ else
+ s[-1] = 0;
+ *stringp = s;
+ return (tok);
+ }
+ } while (sc != 0);
+ }
+ /* NOTREACHED */
+}
+#endif
+
+#ifndef HAVE_STRLCPY
+/*
+ * Copy src to string dst of size siz. At most siz-1 characters
+ * will be copied. Always NUL terminates (unless siz == 0).
+ * Returns strlen(src); if retval >= siz, truncation occurred.
+ */
+size_t
+strlcpy(char *dst, const char *src, size_t siz)
+{
+ char *d = dst;
+ const char *s = src;
+ size_t n = siz;
+
+ /* Copy as many bytes as will fit */
+ if (n != 0 && --n != 0) {
+ do {
+ if ((*d++ = *s++) == 0)
+ break;
+ } while (--n != 0);
+ }
+
+ /* Not enough room in dst, add NUL and traverse rest of src */
+ if (n == 0) {
+ if (siz != 0)
+ *d = '\0'; /* NUL-terminate dst */
+ while (*s++)
+ ;
+ }
+
+ return(s - src - 1); /* count does not include NUL */
+}
+#endif
diff --git a/pkgtools/pkg_install/files/lib/unsetenv.c b/pkgtools/pkg_install/files/lib/unsetenv.c
new file mode 100644
index 00000000000..e713732239b
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/unsetenv.c
@@ -0,0 +1,63 @@
+/* $NetBSD: unsetenv.c,v 1.1.1.1 2002/12/20 18:14:06 schmonz Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+extern char **environ;
+
+#ifndef HAVE_UNSETENV
+void
+unsetenv(name)
+ const char *name;
+{
+ size_t len = strlen(name);
+ char **ptr, **p;
+
+ for (ptr = environ; *ptr; ptr++)
+ if (strncmp(name, *ptr, len) == 0 && (*ptr)[len] == '=') {
+ for (p = ptr;; ++p)
+ if (!(*p = *(p + 1)))
+ break;
+ }
+}
+#endif
diff --git a/pkgtools/pkg_install/files/lib/version.c b/pkgtools/pkg_install/files/lib/version.c
new file mode 100644
index 00000000000..f90ee301c5f
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/version.c
@@ -0,0 +1,51 @@
+/* $NetBSD: version.c,v 1.1.1.1 2002/12/20 18:14:05 schmonz Exp $ */
+
+#if 0
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: version.c,v 1.1.1.1 2002/12/20 18:14:05 schmonz Exp $");
+#endif
+#endif
+
+/*
+ * Copyright (c) 2001 Thomas Klausner. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Thomas Klausner for
+ * the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+
+#include "lib.h"
+#include "version.h"
+
+void
+show_version(void)
+{
+ printf("%s\n", PKGTOOLS_VERSION);
+ exit (0);
+}
+
diff --git a/pkgtools/pkg_install/files/lib/version.h b/pkgtools/pkg_install/files/lib/version.h
new file mode 100644
index 00000000000..78017071760
--- /dev/null
+++ b/pkgtools/pkg_install/files/lib/version.h
@@ -0,0 +1,38 @@
+/* $NetBSD: version.h,v 1.1.1.1 2002/12/20 18:14:05 schmonz Exp $ */
+
+/*
+ * Copyright (c) 2001 Thomas Klausner. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Thomas Klausner for
+ * the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _INST_LIB_VERSION_H_
+#define _INST_LIB_VERSION_H_
+
+#define PKGTOOLS_VERSION "20021123"
+
+#endif /* _INST_LIB_VERSION_H_ */
diff --git a/pkgtools/pkg_install/files/tkpkg b/pkgtools/pkg_install/files/tkpkg
new file mode 100644
index 00000000000..73f2f2907e3
--- /dev/null
+++ b/pkgtools/pkg_install/files/tkpkg
@@ -0,0 +1,152 @@
+#!/usr/pkg/bin/wish -f
+# from FreeBSD Id: tkpkg,v 1.4 1997/02/22 16:09:13 peter Exp
+#
+set pkgname ""
+wm title . "Package Installation"
+#--------------------------------------------------------------
+# The top level main window, consisting of a bar of buttons and a list
+# of packages and a description of the current package.
+#--------------------------------------------------------------
+frame .menu -relief raised -borderwidth 1
+frame .frame -borderwidth 4
+
+scrollbar .frame.scroll -relief sunken -command ".frame.list yview"
+listbox .frame.list -yscroll ".frame.scroll set" -relief sunken -setgrid 1
+pack append .frame .frame.scroll {right filly} \
+ .frame.list {left expand fill}
+
+# build the lower window shoing the complete description of a pacage
+frame .f -borderwidth 4
+text .f.t -width 80 -height 20 -yscrollcommand ".f.s set" -relief sunken
+
+# Initially display instructions in this window. Erase the
+# 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 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}
+
+bind .frame.list <Double-Button-1> \
+ { do_description [selection get] }
+pack append . .menu {top fill} \
+ .f {bottom expand fill} \
+ .frame {bottom expand fill}
+
+#----------------------------------------------------------------
+# Make menu bar:
+#----------------------------------------------------------------
+button .menu.inst -text "Install" \
+ -command "apply_to_pkg \"pkg_add -v\""
+button .menu.dein -text "Deinstall" \
+ -command "apply_to_pkg \"pkg_delete -v\""
+button .menu.installed -text "What is Installed?" \
+ -command "list_pkgs \"pkg_info -I -a |tr ' ' ' '\""
+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 "apply_to_pkg \"pkg_info -d -v\""
+button .menu.quit -text "Quit" -command "destroy ."
+button .menu.help -text "Help" -command "do_help"
+
+pack append .menu \
+ .menu.inst left \
+ .menu.dein left \
+ .menu.installed left \
+ .menu.available left \
+ .menu.cont left \
+ .menu.quit left \
+ .menu.help right
+#-------------------------------------------------------
+# Display the package description.
+#-------------------------------------------------------
+proc list_pkgs {s} {
+ set line ""
+ set f [eval "open {| sh -c \"$s\" } r"]
+ .frame.list delete 0 end
+ while {[gets $f line] > 0} {
+ .frame.list insert end $line
+ }
+ close $f
+}
+
+# display the list of available packages
+set archives [glob -nocomplain *.{tgz,tar.z,tar.gz,tar.Z}]
+if {$archives == ""} {
+ .frame.list delete 0 end
+ .frame.list insert end "Warning: no compressed tar archives files found."
+} else {
+ list_pkgs "pkg_info -I -c $archives |tr ' ' ' '"
+}
+
+#-------------------------------------------------------
+# Display the package description.
+#-------------------------------------------------------
+proc do_description {s} {
+ global pkgname
+ regexp {[^ ]*} $s filename
+ set pkgname $filename
+ .f.t delete 0.0 end
+ set cmd "pkg_info -d $filename |tr -d ' '"
+ set f [eval "open {| csh -c \"$cmd\" } r"]
+ while {![eof $f]} {
+ .f.t insert end [read $f]
+ }
+}
+#-------------------------------------------------------
+# package install window.
+#-------------------------------------------------------
+proc do_help {{w .help}} {
+ catch {destroy $w}
+ toplevel $w
+ wm title $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 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\n"
+ set f [eval "open {| sh -c \"$s $errredir\" } r"]
+ while {![eof $f]} {
+ .f.t insert end [read $f 64]
+ }
+}
+#-------------------------------------------------------
+# Invoke an arbitrary command.
+#-------------------------------------------------------
+proc do_command {s} {
+ .f.t delete 0.0 end
+ .f.t insert end "Running: $s\n"
+ set f [eval "open {| $s} r"]
+ while {![eof $f]} {
+ .f.t insert end [read $f 64]
+ }
+}
+# local variables:
+# mode: csh
+# compile-command: ""
+# comment-start: "# "
+# comment-start-skip: "# "
+# end: