aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/pkg_install/lib
diff options
context:
space:
mode:
authorJordan K. Hubbard <jkh@FreeBSD.org>1993-08-26 01:19:55 +0000
committerJordan K. Hubbard <jkh@FreeBSD.org>1993-08-26 01:19:55 +0000
commit6d946b2e52275a56dd775436f4c6b6a4c65915c8 (patch)
treeb3cb91ab036ba2deccf4af07caf09c2bf6b4b88e /usr.sbin/pkg_install/lib
parent24a82630a20b64577bcc7454bec7288b1dbdb37a (diff)
downloadsrc-6d946b2e52275a56dd775436f4c6b6a4c65915c8.tar.gz
src-6d946b2e52275a56dd775436f4c6b6a4c65915c8.zip
Notes
Diffstat (limited to 'usr.sbin/pkg_install/lib')
-rw-r--r--usr.sbin/pkg_install/lib/Makefile9
-rw-r--r--usr.sbin/pkg_install/lib/exec.c48
-rw-r--r--usr.sbin/pkg_install/lib/file.c164
-rw-r--r--usr.sbin/pkg_install/lib/global.c31
-rw-r--r--usr.sbin/pkg_install/lib/lib.h143
-rw-r--r--usr.sbin/pkg_install/lib/msg.c97
-rw-r--r--usr.sbin/pkg_install/lib/pen.c63
-rw-r--r--usr.sbin/pkg_install/lib/plist.c270
-rw-r--r--usr.sbin/pkg_install/lib/str.c85
9 files changed, 910 insertions, 0 deletions
diff --git a/usr.sbin/pkg_install/lib/Makefile b/usr.sbin/pkg_install/lib/Makefile
new file mode 100644
index 000000000000..72da09860554
--- /dev/null
+++ b/usr.sbin/pkg_install/lib/Makefile
@@ -0,0 +1,9 @@
+LIB= install
+SRCS= file.c msg.c plist.c str.c exec.c global.c pen.c
+NOPROFILE= yes
+CFLAGS+= -g -Wall
+
+install:
+ @echo -n
+
+.include <bsd.lib.mk>
diff --git a/usr.sbin/pkg_install/lib/exec.c b/usr.sbin/pkg_install/lib/exec.c
new file mode 100644
index 000000000000..6f1a67299b36
--- /dev/null
+++ b/usr.sbin/pkg_install/lib/exec.c
@@ -0,0 +1,48 @@
+#ifndef lint
+static const char *rcsid = "$Id: exec.c,v 1.3 1993/08/24 09:24:04 jkh Exp $";
+#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.
+ *
+ */
+
+#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[FILENAME_MAX * 2]; /* reasonable default for what I do */
+ int ret;
+
+ va_start(args, fmt);
+ vsprintf(cmd, fmt, args);
+#ifdef DEBUG
+printf("Executing %s\n", cmd);
+#endif
+ ret = system(cmd);
+ va_end(args);
+ return ret;
+}
+
diff --git a/usr.sbin/pkg_install/lib/file.c b/usr.sbin/pkg_install/lib/file.c
new file mode 100644
index 000000000000..ac7e4d7ac819
--- /dev/null
+++ b/usr.sbin/pkg_install/lib/file.c
@@ -0,0 +1,164 @@
+#ifndef lint
+static const char *rcsid = "$Id: file.c,v 1.5 1993/08/26 08:13:48 jkh Exp $";
+#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"
+
+/* Quick check to see if a file exists */
+Boolean
+fexists(char *fname)
+{
+ if (!access(fname, F_OK))
+ return TRUE;
+ return FALSE;
+}
+
+/* Quick check to see if something is a directory */
+Boolean
+isdir(char *fname)
+{
+ struct stat sb;
+
+ if (stat(fname, &sb) != FAIL &&
+ (sb.st_mode & S_IFDIR))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/* Check to see if file is a dir, and is empty */
+Boolean
+isempty(char *fname)
+{
+ if (isdir(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;
+}
+
+char *
+get_file_contents(char *fname)
+{
+ char *contents;
+ struct stat sb;
+ int fd;
+
+ if (stat(fname, &sb) == FAIL)
+ barf("Can't stat '%s'.", fname);
+
+ contents = (char *)malloc(sb.st_size + 1);
+ fd = open(fname, O_RDONLY, 0);
+ if (fd == FAIL)
+ barf("Unable to open '%s' for reading.", fname);
+ if (read(fd, contents, sb.st_size) != sb.st_size)
+ barf("Short read on '%s' - did not get %d bytes.", fname, sb.st_size);
+ close(fd);
+ contents[sb.st_size] = '\0';
+ return contents;
+}
+
+/* Write the contents of "str" to a file */
+void
+write_file(char *name, char *str)
+{
+ FILE *fp;
+ int len;
+
+ fp = fopen(name, "w");
+ if (!fp)
+ barf("Can't fopen '%s' for writing.", name);
+ len = strlen(str);
+ if (fwrite(str, 1, len, fp) != len)
+ barf("Short fwrite on '%s', tried to write %d bytes.", name, len);
+ if (fclose(fp))
+ barf("failure to fclose '%s'.", name);
+}
+
+void
+copy_file(char *dir, char *fname, char *to)
+{
+ if (vsystem("cp -p -r %s/%s %s", dir, fname, to))
+ barf("Couldn't copy %s/%s to %s!", dir, fname, to);
+}
+
+/*
+ * Copy a hierarchy (possibly from dir) to the current directory, or
+ * if "to" is TRUE, from the current directory to a location someplace
+ * else.
+ *
+ * Though slower, using tar to copy preserves symlinks and everything
+ * without me having to write some big hairy routine to do it.
+ */
+void
+copy_hierarchy(char *dir, char *fname, Boolean to)
+{
+ char cmd[FILENAME_MAX * 3];
+
+ if (!to) {
+ /* If absolute path, use it */
+ if (*fname == '/')
+ dir = "/";
+ sprintf(cmd, "tar cf - -C %s %s | tar xpf -", dir, fname);
+ }
+ else
+ sprintf(cmd, "tar cf - %s | tar xpf - -C %s", fname, dir);
+ if (system(cmd))
+ barf("copy_file: Couldn't perform '%s'", cmd);
+}
+
+/* Unpack a tar file */
+int
+unpack(char *pkg, char *flist)
+{
+ char args[10], suffix[80], *cp;
+
+ /*
+ * Figure out by a crude heuristic whether this or not this is probably
+ * compressed.
+ */
+ cp = rindex(pkg, '.');
+ if (cp) {
+ strcpy(suffix, cp + 1);
+ if (index(suffix, 'z') || index(suffix, 'Z'))
+ strcpy(args, "z");
+ }
+ strcat(args, "xpf");
+ if (vsystem("tar %s %s %s", args, pkg, flist ? flist : "")) {
+ whinge("Tar extract of %s failed!", pkg);
+ return 1;
+ }
+ return 0;
+}
diff --git a/usr.sbin/pkg_install/lib/global.c b/usr.sbin/pkg_install/lib/global.c
new file mode 100644
index 000000000000..f5eda0e31917
--- /dev/null
+++ b/usr.sbin/pkg_install/lib/global.c
@@ -0,0 +1,31 @@
+#ifndef lint
+static const char *rcsid = "$Id$";
+#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 two are global for all utils */
+Boolean Verbose = FALSE;
+Boolean Fake = FALSE;
+
diff --git a/usr.sbin/pkg_install/lib/lib.h b/usr.sbin/pkg_install/lib/lib.h
new file mode 100644
index 000000000000..05d43e7f54ae
--- /dev/null
+++ b/usr.sbin/pkg_install/lib/lib.h
@@ -0,0 +1,143 @@
+/* $Id: lib.h,v 1.4 1993/08/24 09:24:07 jkh 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_
+
+/* Includes */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/file.h>
+
+/* Macros */
+#define SUCCESS (0)
+#define FAIL (-1)
+
+#ifndef TRUE
+#define TRUE (1)
+#endif
+
+#ifndef FALSE
+#define FALSE (0)
+#endif
+
+/* Usually "rm", but often "echo" during debugging! */
+#define REMOVE_CMD "rm"
+
+/* Usually "rm", but often "echo" during debugging! */
+#define RMDIR_CMD "rmdir"
+
+/* Where we put logging information */
+#define LOG_DIR "/var/db/pkg"
+
+/* 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 CMD_CHAR '@' /* prefix for extended PLIST cmd */
+
+enum _plist_t {
+ PLIST_FILE, PLIST_CWD, PLIST_CMD, PLIST_CHMOD,
+ PLIST_CHOWN, PLIST_CHGRP, PLIST_COMMENT,
+ PLIST_IGNORE, PLIST_NAME
+};
+typedef enum _plist_t plist_t;
+
+/* Types */
+typedef unsigned int Boolean;
+
+struct _plist {
+ struct _plist *prev, *next;
+ char *name;
+ Boolean marked;
+ plist_t type;
+};
+typedef struct _plist *PackingList;
+
+struct _pack {
+ struct _plist *head, *tail;
+};
+typedef struct _pack Package;
+
+/* Prototypes */
+/* Misc */
+int vsystem(const char *, ...);
+void cleanup(int);
+char *make_playpen(void);
+void leave_playpen(void);
+
+/* String */
+char *get_dash_string(char **);
+char *copy_string(char *);
+Boolean suffix(char *, char *);
+void nuke_suffix(char *);
+void str_lowercase(char *);
+
+/* File */
+Boolean fexists(char *);
+Boolean isdir(char *);
+Boolean isempty(char *);
+char *get_file_contents(char *);
+void write_file(char *, char *);
+void copy_file(char *, char *, char *);
+void copy_hierarchy(char *, char *, Boolean);
+int delete_hierarchy(char *, Boolean);
+int unpack(char *, char *);
+
+/* Msg */
+void upchuck(const char *);
+void barf(const char *, ...);
+void whinge(const char *, ...);
+Boolean y_or_n(Boolean, const char *, ...);
+
+/* Packing list */
+PackingList new_plist_entry(void);
+PackingList last_plist(Package *);
+void free_plist(Package *);
+void mark_plist(Package *);
+void csum_plist_entry(char *, PackingList);
+void add_plist(Package *, int, char *);
+void write_plist(Package *, FILE *);
+void read_plist(Package *, FILE *);
+int plist_cmd(char *, char **);
+void delete_package(Boolean, Package *);
+
+/* For all */
+void usage(const char *, const char *, ...);
+int pkg_perform(char **);
+
+/* Externs */
+extern Boolean Verbose;
+extern Boolean Fake;
+
+#endif /* _INST_LIB_LIB_H_ */
diff --git a/usr.sbin/pkg_install/lib/msg.c b/usr.sbin/pkg_install/lib/msg.c
new file mode 100644
index 000000000000..4c742907cb3a
--- /dev/null
+++ b/usr.sbin/pkg_install/lib/msg.c
@@ -0,0 +1,97 @@
+#ifndef lint
+static const char *rcsid = "$Id: msg.c,v 1.2 1993/08/16 14:20:18 jkh Exp $";
+#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 message routines.
+ *
+ */
+
+#include "lib.h"
+
+/* Die a relatively simple death */
+void
+upchuck(const char *err)
+{
+ fprintf(stderr, "Fatal error during execution: ");
+ perror(err);
+ cleanup(0);
+ exit(1);
+}
+
+/* Die a more complex death */
+void
+barf(const char *err, ...)
+{
+ va_list args;
+
+ va_start(args, err);
+ vfprintf(stderr, err, args);
+ fputc('\n', stderr);
+ va_end(args);
+ cleanup(0);
+ exit(2);
+}
+
+/* Get annoyed about something but don't go to pieces over it */
+void
+whinge(const char *err, ...)
+{
+ va_list args;
+
+ va_start(args, err);
+ vfprintf(stderr, err, args);
+ fputc('\n', stderr);
+ va_end(args);
+}
+
+/*
+ * As a yes/no question, prompting from the varargs string and using
+ * default if user just hits return.
+ */
+Boolean
+y_or_n(Boolean def, const char *msg, ...)
+{
+ va_list args;
+ int ch = 0;
+ FILE *tty;
+
+ va_start(args, msg);
+ /*
+ * Need to open /dev/tty because file collection may have been
+ * collected on stdin
+ */
+ tty = fopen("/dev/tty", "r");
+ if (!tty)
+ barf("Can't open /dev/tty!\n");
+ while (ch != 'Y' && ch != 'N') {
+ vfprintf(stderr, msg, args);
+ if (def)
+ fprintf(stderr, " [yes]? ");
+ else
+ fprintf(stderr, " [no]? ");
+ fflush(stderr);
+ ch = toupper(fgetc(tty));
+ if (ch == '\n')
+ ch = (def) ? 'Y' : 'N';
+ }
+ return (ch == 'Y') ? TRUE : FALSE;
+}
+
+
diff --git a/usr.sbin/pkg_install/lib/pen.c b/usr.sbin/pkg_install/lib/pen.c
new file mode 100644
index 000000000000..8a3416f6b068
--- /dev/null
+++ b/usr.sbin/pkg_install/lib/pen.c
@@ -0,0 +1,63 @@
+#ifndef lint
+static const char *rcsid = "$Id: pen.c,v 1.1 1993/08/24 09:24:08 jkh Exp $";
+#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".
+ *
+ */
+
+#include "lib.h"
+
+/* For keeping track of where we are */
+static char Cwd[FILENAME_MAX];
+static char Pen[FILENAME_MAX];
+
+
+/*
+ * Make a temporary directory to play in and chdir() to it, returning
+ * pathname of previous working directory.
+ */
+char *
+make_playpen(void)
+{
+ if (!getcwd(Cwd, FILENAME_MAX))
+ upchuck("getcwd");
+ strcpy(Pen, "/tmp/instmp.XXXXXX");
+ if (!mktemp(Pen))
+ barf("Can't mktemp '%s'.", Pen);
+ if (mkdir(Pen, 0755) == FAIL)
+ barf("Can't mkdir '%s'.", Pen);
+ if (chdir(Pen) == FAIL)
+ barf("Can't chdir to '%s'.", Pen);
+ return Cwd;
+}
+
+/* Convenience routine for getting out of playpen */
+void
+leave_playpen(void)
+{
+ if (Cwd[0]) {
+ if (chdir(Cwd) == FAIL)
+ barf("Can't chdir back to '%s'.", Cwd);
+ if (vsystem("rm -rf %s", Pen))
+ fprintf(stderr, "Couldn't remove temporary dir '%s'\n", Pen);
+ Cwd[0] = '\0';
+ }
+}
+
diff --git a/usr.sbin/pkg_install/lib/plist.c b/usr.sbin/pkg_install/lib/plist.c
new file mode 100644
index 000000000000..f2992c6963fb
--- /dev/null
+++ b/usr.sbin/pkg_install/lib/plist.c
@@ -0,0 +1,270 @@
+#ifndef lint
+static const char *rcsid = "$Id: plist.c,v 1.5 1993/08/26 08:13:49 jkh Exp $";
+#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"
+
+/* Add an item to a packing list */
+void
+add_plist(Package *p, int type, char *arg)
+{
+ PackingList tmp;
+
+ tmp = new_plist_entry();
+ tmp->name = copy_string(arg);
+ tmp->type = type;
+
+ if (!p->head)
+ p->head = p->tail = tmp;
+ else {
+ tmp->prev = p->tail;
+ p->tail->next = tmp;
+ p->tail = tmp;
+ }
+}
+
+/* Return the last (most recent) entry in a packing list */
+PackingList
+last_plist(Package *p)
+{
+ return p->tail;
+}
+
+/* Mark all items in a packing list to prevent iteration over them */
+void
+mark_plist(Package *pkg)
+{
+ PackingList p = pkg->head;
+
+ while (p) {
+ p->marked = TRUE;
+ p = p->next;
+ }
+}
+
+/* Allocate a new packing list entry */
+PackingList
+new_plist_entry(void)
+{
+ PackingList ret;
+
+ ret = (PackingList)malloc(sizeof(struct _plist));
+ bzero(ret, sizeof(struct _plist));
+ return ret;
+}
+
+/* Free an entire packing list */
+void
+free_plist(Package *pkg)
+{
+ PackingList p = pkg->head;
+
+ while (p) {
+ PackingList 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)
+{
+ char cmd[FILENAME_MAX + 20]; /* 20 == fudge for max cmd len */
+ char *cp, *sp;
+
+ strcpy(cmd, s);
+ str_lowercase(cmd);
+ cp = cmd;
+ sp = s;
+ while (*cp) {
+ if (isspace(*cp)) {
+ *cp = '\0';
+ while (isspace(*sp)) /* Never sure if macro, increment later */
+ ++sp;
+ break;
+ }
+ ++cp, ++sp;
+ }
+ if (arg)
+ *arg = sp;
+ if (!strcmp(cmd, "cwd"))
+ return PLIST_CWD;
+ else if (!strcmp(cmd, "exec"))
+ return PLIST_CMD;
+ else if (!strcmp(cmd, "mode"))
+ return PLIST_CHMOD;
+ else if (!strcmp(cmd, "owner"))
+ return PLIST_CHOWN;
+ else if (!strcmp(cmd, "group"))
+ return PLIST_CHGRP;
+ else if (!strcmp(cmd, "comment"))
+ return PLIST_COMMENT;
+ else if (!strcmp(cmd, "ignore"))
+ return PLIST_IGNORE;
+ else if (!strcmp(cmd, "name"))
+ return PLIST_NAME;
+ else
+ return FAIL;
+}
+
+/* Read a packing list from a file */
+void
+read_plist(Package *pkg, FILE *fp)
+{
+ char *cp, pline[FILENAME_MAX];
+ int cmd;
+
+ while (fgets(pline, FILENAME_MAX, fp)) {
+ int len = strlen(pline) - 1;
+
+ while (isspace(pline[len]))
+ pline[len--] = '\0';
+ if (!len)
+ continue;
+ cp = pline;
+ if (pline[0] == CMD_CHAR) {
+ cmd = plist_cmd(pline + 1, &cp);
+ if (cmd == FAIL)
+ barf("Bad command '%s'", pline);
+ }
+ 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 *pkg, FILE *fp)
+{
+ PackingList plist = pkg->head;
+
+ while (plist) {
+ switch(plist->type) {
+ case PLIST_FILE:
+ fprintf(fp, "%s\n", plist->name);
+ break;
+
+ case PLIST_CWD:
+ fprintf(fp, "%ccwd %s\n", CMD_CHAR, plist->name);
+ break;
+
+ case PLIST_CMD:
+ fprintf(fp, "%cexec %s\n", CMD_CHAR, plist->name);
+ break;
+
+ case PLIST_CHMOD:
+ fprintf(fp, "%cchmod %s\n", CMD_CHAR,
+ plist->name ? plist->name : "");
+ break;
+
+ case PLIST_CHOWN:
+ fprintf(fp, "%cchown %s\n", CMD_CHAR,
+ plist->name ? plist->name : "");
+ break;
+
+ case PLIST_CHGRP:
+ fprintf(fp, "%cchgrp %s\n", CMD_CHAR,
+ plist->name ? plist->name : "");
+ break;
+
+ case PLIST_COMMENT:
+ fprintf(fp, "%ccomment %s\n", CMD_CHAR, plist->name);
+ break;
+
+ case PLIST_IGNORE:
+ fprintf(fp, "%cignore\n", CMD_CHAR);
+ break;
+
+ case PLIST_NAME:
+ fprintf(fp, "%cname %s\n", CMD_CHAR, plist->name);
+ break;
+
+ default:
+ barf("Unknown command type %d (%s)\n", plist->type, plist->name);
+ break;
+ }
+ plist = plist->next;
+ }
+}
+
+/* Delete the results of a package installation, not the packaging itself */
+void
+delete_package(Boolean ign_err, Package *pkg)
+{
+ PackingList p = pkg->head;
+ char *Where = ".";
+
+ while (p) {
+ if (p->type == PLIST_CWD) {
+ Where = p->name;
+ if (Verbose)
+ printf("Delete: (CWD to %s)\n", Where);
+ }
+ else if (p->type == PLIST_IGNORE)
+ p = p->next;
+ else if (p->type == PLIST_FILE) {
+ char full_name[FILENAME_MAX];
+
+ sprintf(full_name, "%s/%s", Where, p->name);
+ if (Verbose)
+ printf("Delete: %s\n", full_name);
+
+ if (!Fake && delete_hierarchy(full_name, ign_err))
+ whinge("Unable to completely remove file '%s'", full_name);
+ }
+ p = p->next;
+ }
+}
+
+/* Selectively delete a hierarchy */
+int
+delete_hierarchy(char *dir, Boolean ign_err)
+{
+ char *cp1, *cp2;
+
+ cp1 = cp2 = dir;
+ if (vsystem("%s -r%s %s", REMOVE_CMD, (ign_err ? "f" : ""), dir))
+ return 1;
+ while (cp2) {
+ if ((cp2 = rindex(cp1, '/')) != NULL)
+ *cp2 = '\0';
+ if (!isempty(dir))
+ return 0;
+ if (vsystem("%s %s", RMDIR_CMD, dir) && ign_err)
+ return 1;
+ /* Put it back */
+ if (cp2) {
+ *cp2 = '/';
+ cp1 = cp2 - 1;
+ }
+ }
+ return 0;
+}
diff --git a/usr.sbin/pkg_install/lib/str.c b/usr.sbin/pkg_install/lib/str.c
new file mode 100644
index 000000000000..8d68f9291f1d
--- /dev/null
+++ b/usr.sbin/pkg_install/lib/str.c
@@ -0,0 +1,85 @@
+#ifndef lint
+static const char *rcsid = "$Id";
+#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.
+ *
+ */
+
+#include "lib.h"
+
+char *
+get_dash_string(char **str)
+{
+ char *s = *str;
+
+ if (*s == '-')
+ *str = copy_string(s + 1);
+ else
+ *str = get_file_contents(s);
+ return *str;
+}
+
+char *
+copy_string(char *str)
+{
+ char *ret;
+
+ if (!str)
+ ret = NULL;
+ else {
+ ret = (char *)malloc(strlen(str) + 1);
+ strcpy(ret, str);
+ }
+ return ret;
+}
+
+/* Return TRUE if 'str' ends in suffix 'suff' */
+Boolean
+suffix(char *str, char *suff)
+{
+ char *idx;
+ Boolean ret = FALSE;
+
+ idx = rindex(str, '.');
+ if (idx && !strcmp(idx + 1, suff))
+ ret = TRUE;
+ return ret;
+}
+
+/* Assuming str has a suffix, brutally murder it! */
+void
+nuke_suffix(char *str)
+{
+ char *idx;
+
+ idx = rindex(str, '.');
+ if (idx)
+ *idx = '\0'; /* Yow! Don't try this on a const! */
+}
+
+/* Lowercase a whole string */
+void
+str_lowercase(char *str)
+{
+ while (*str) {
+ *str = tolower(*str);
+ ++str;
+ }
+}