summaryrefslogtreecommitdiff
path: root/usr.sbin/pkg_install/lib
diff options
context:
space:
mode:
authorMarco S Hyman <marc@cvs.openbsd.org>1998-09-07 22:30:18 +0000
committerMarco S Hyman <marc@cvs.openbsd.org>1998-09-07 22:30:18 +0000
commitb7191a530a228038c0867ad6aedd90f5b534d1e9 (patch)
treedff11f7b0f8e66c2c0a6b6dbf273127ef93423cd /usr.sbin/pkg_install/lib
parentd772ee662c59d0c57ee6ec091bcc1b5d284fb641 (diff)
updated pkg_* tools. Merged in many changes/improvements from NetBSD.
New features include md5 hash so pkg_delete won't remove files that have changed and the ability to define conflicting packages, e.g. you can't install both mh and nmh. The ports tree will have to be updated to take advantage of this. Let me know of any problems, real or imagined :-)
Diffstat (limited to 'usr.sbin/pkg_install/lib')
-rw-r--r--usr.sbin/pkg_install/lib/exec.c11
-rw-r--r--usr.sbin/pkg_install/lib/file.c252
-rw-r--r--usr.sbin/pkg_install/lib/global.c5
-rw-r--r--usr.sbin/pkg_install/lib/lib.h46
-rw-r--r--usr.sbin/pkg_install/lib/msg.c43
-rw-r--r--usr.sbin/pkg_install/lib/pen.c60
-rw-r--r--usr.sbin/pkg_install/lib/plist.c150
7 files changed, 367 insertions, 200 deletions
diff --git a/usr.sbin/pkg_install/lib/exec.c b/usr.sbin/pkg_install/lib/exec.c
index 175925c28ed..bf7d614d845 100644
--- a/usr.sbin/pkg_install/lib/exec.c
+++ b/usr.sbin/pkg_install/lib/exec.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: exec.c,v 1.3 1998/06/23 23:17:20 millert Exp $ */
+/* $OpenBSD: exec.c,v 1.4 1998/09/07 22:30:16 marc Exp $ */
#ifndef lint
-static const char *rcsid = "$OpenBSD: exec.c,v 1.3 1998/06/23 23:17:20 millert Exp $";
+static const char *rcsid = "$OpenBSD: exec.c,v 1.4 1998/09/07 22:30:16 marc Exp $";
#endif
/*
@@ -24,6 +24,7 @@ static const char *rcsid = "$OpenBSD: exec.c,v 1.3 1998/06/23 23:17:20 millert E
*
*/
+#include <err.h>
#include "lib.h"
/*
@@ -42,13 +43,13 @@ vsystem(const char *fmt, ...)
maxargs -= 32; /* some slop for the sh -c */
cmd = malloc(maxargs);
if (!cmd) {
- whinge("vsystem can't alloc arg space");
+ warnx("vsystem can't alloc arg space");
return 1;
}
va_start(args, fmt);
- if (vsnprintf(cmd, maxargs, fmt, args) >= maxargs) {
- whinge("vsystem args are too long");
+ if (vsnprintf(cmd, maxargs, fmt, args) > maxargs) {
+ warnx("vsystem args are too long");
return 1;
}
#ifdef DEBUG
diff --git a/usr.sbin/pkg_install/lib/file.c b/usr.sbin/pkg_install/lib/file.c
index ce62da5ee69..8f8ac44328c 100644
--- a/usr.sbin/pkg_install/lib/file.c
+++ b/usr.sbin/pkg_install/lib/file.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: file.c,v 1.5 1998/04/07 07:11:33 deraadt Exp $ */
+/* $OpenBSD: file.c,v 1.6 1998/09/07 22:30:16 marc Exp $ */
#ifndef lint
-static const char *rcsid = "$OpenBSD: file.c,v 1.5 1998/04/07 07:11:33 deraadt Exp $";
+static const char *rcsid = "$OpenBSD: file.c,v 1.6 1998/09/07 22:30:16 marc Exp $";
#endif
/*
@@ -25,10 +25,17 @@ static const char *rcsid = "$OpenBSD: file.c,v 1.5 1998/04/07 07:11:33 deraadt E
*/
#include "lib.h"
-#include "ftp.h"
+
+#include <sys/wait.h>
+
+#include <err.h>
+#include <netdb.h>
#include <pwd.h>
#include <time.h>
+FILE *
+ftpGetURL(char *url, char *user, char *passwd, int *retcode);
+
/* Quick check to see if a file exists */
Boolean
fexists(char *fname)
@@ -45,17 +52,32 @@ isdir(char *fname)
{
struct stat sb;
- if (stat(fname, &sb) != FAIL && S_ISDIR(sb.st_mode))
+ 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(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(char *fname)
{
- if (isdir(fname)) {
+ if (isdir(fname) || islinktodir(fname)) {
DIR *dirp;
struct dirent *dp;
@@ -125,7 +147,7 @@ fileURLHost(char *fname, char *where, int max)
/* Don't ever call this on a bad URL! */
fname += strlen("ftp://");
/* Do we have a place to stick our work? */
- if (ret = where) {
+ if ((ret = where) != NULL) {
while (*fname && *fname != '/' && max--)
*where++ = *fname++;
*where = '\0';
@@ -150,7 +172,7 @@ fileURLFilename(char *fname, char *where, int max)
/* Don't ever call this on a bad URL! */
fname += strlen("ftp://");
/* Do we have a place to stick our work? */
- if (ret = where) {
+ if ((ret = where) != NULL) {
while (*fname && *fname != '/')
++fname;
if (*fname == '/') {
@@ -166,7 +188,6 @@ fileURLFilename(char *fname, char *where, int max)
return fname;
}
-#define HOSTNAME_MAX 64
/*
* Try and fetch a file by URL, returning the directory name for where
* it's unpacked, if successful.
@@ -174,24 +195,20 @@ fileURLFilename(char *fname, char *where, int max)
char *
fileGetURL(char *base, char *spec)
{
- char host[HOSTNAME_MAX], file[FILENAME_MAX], dir[FILENAME_MAX];
- char pword[HOSTNAME_MAX + 40], *uname, *cp, *rp, *tmp;
+ char host[MAXHOSTNAMELEN], file[FILENAME_MAX];
+ char pword[MAXHOSTNAMELEN + 40], *uname, *cp, *rp;
char fname[FILENAME_MAX];
char pen[FILENAME_MAX];
struct passwd *pw;
- FTP_t ftp;
+ FILE *ftp;
pid_t tpid;
- int fd, fd2, i, len = 0;
- char ch;
- time_t start, stop;
+ int i, status;
char *hint;
rp = NULL;
/* Special tip that sysinstall left for us */
hint = getenv("PKG_ADD_BASE");
if (!isURL(spec)) {
- int len;
-
if (!base && !hint)
return NULL;
/* We've been given an existing URL (that's known-good) and now we need
@@ -209,6 +226,7 @@ fileGetURL(char *base, char *spec)
*(cp + 1) = '\0';
strcat(cp, "All/");
strcat(cp, spec);
+ strcat(cp, ".tgz");
}
else
return NULL;
@@ -221,16 +239,15 @@ fileGetURL(char *base, char *spec)
}
else
strcpy(fname, spec);
- ftp = FtpInit();
- cp = fileURLHost(fname, host, HOSTNAME_MAX);
+ cp = fileURLHost(fname, host, MAXHOSTNAMELEN);
if (!*cp) {
- whinge("URL `%s' has bad host part!", fname);
+ warnx("URL `%s' has bad host part!", fname);
return NULL;
}
cp = fileURLFilename(fname, file, FILENAME_MAX);
if (!*cp) {
- whinge("URL `%s' has bad filename part!", fname);
+ warnx("URL `%s' has bad filename part!", fname);
return NULL;
}
@@ -240,59 +257,49 @@ fileGetURL(char *base, char *spec)
/* Make up a convincing "password" */
pw = getpwuid(getuid());
if (!pw) {
- whinge("Can't get user name for ID %d\n.", getuid());
+ warnx("can't get user name for ID %d", getuid());
strcpy(pword, "joe@");
}
- else
- snprintf(pword, HOSTNAME_MAX + 40, "%s@%s", pw->pw_name, host);
+ else {
+ char me[MAXHOSTNAMELEN + 1];
- if (Verbose)
- printf("Trying to log into %s as %s.\n", host, uname);
- FtpOpen(ftp, host, uname, pword);
- if (getenv("FTP_ACTIVE_MODE") == NULL)
- FtpPassive(ftp, TRUE);
-
- strcpy(dir, file);
- for (i = strlen(dir); i && dir[i] != '/'; i--);
- dir[i] = '\0';
-
- if (dir[0]) {
- if (Verbose) printf("FTP: chdir to %s\n", dir);
- FtpChdir(ftp, dir);
+ gethostname(me, sizeof me);
+ me[sizeof(me) - 1] = '\0';
+ snprintf(pword, sizeof pword, "%s@%s", pw->pw_name, me);
}
- FtpBinary(ftp, TRUE);
- if (Verbose) printf("FTP: trying to get %s\n", basename_of(file));
- tmp = basename_of(file);
- if (!strstr(tmp, ".tgz"))
- tmp = strconcat(tmp, ".tgz");
- fd = FtpGet(ftp, tmp);
- if (fd >= 0) {
+ if (Verbose)
+ printf("Trying to fetch %s.\n", fname);
+ ftp = ftpGetURL(fname, uname, pword, &status);
+ if (ftp) {
pen[0] = '\0';
- if (rp = make_playpen(pen, 0)) {
+ if ((rp = make_playpen(pen, 0)) != NULL) {
+ rp=pen; /* XXX - pen is dynamic; make static? */
if (Verbose)
printf("Extracting from FTP connection into %s\n", pen);
tpid = fork();
if (!tpid) {
- dup2(fd, 0);
+ dup2(fileno(ftp), 0);
i = execl("/bin/tar", "tar", Verbose ? "-xzvf" : "-xzf", "-", 0);
- if (Verbose)
- printf("tar command returns %d status\n", i);
exit(i);
}
else {
int pstat;
- close(fd);
+ fclose(ftp);
tpid = waitpid(tpid, &pstat, 0);
+ if (Verbose)
+ printf("tar command returns %d status\n", WEXITSTATUS(pstat));
}
}
else
printf("Error: Unable to construct a new playpen for FTP!\n");
+ fclose(ftp);
}
else
- printf("Error: FTP Unable to get %s\n", basename_of(file));
- FtpEOF(ftp);
- FtpClose(ftp);
+ printf("Error: FTP Unable to get %s: %s\n",
+ fname,
+ status ? "Error while performing FTP" :
+ hstrerror(h_errno));
return rp;
}
@@ -309,15 +316,16 @@ fileFindByPath(char *base, char *fname)
if (base) {
strcpy(tmp, base);
- cp = strrchr(fname, '/');
+ cp = strrchr(tmp, '/');
if (cp) {
*cp = '\0'; /* chop name */
- cp = strrchr(fname, '/');
+ cp = strrchr(tmp, '/');
}
if (cp) {
*(cp + 1) = '\0';
strcat(cp, "All/");
strcat(cp, fname);
+ strcat(cp, ".tgz");
if (fexists(tmp))
return tmp;
}
@@ -341,20 +349,61 @@ fileGetContents(char *fname)
struct stat sb;
int fd;
- if (stat(fname, &sb) == FAIL)
- barf("Can't stat '%s'.", fname);
+ if (stat(fname, &sb) == FAIL) {
+ cleanup(0);
+ errx(2, "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 %qd bytes.", fname, sb.st_size);
+ if (fd == FAIL) {
+ cleanup(0);
+ errx(2, "unable to open '%s' for reading", fname);
+ }
+ if (read(fd, contents, sb.st_size) != sb.st_size) {
+ cleanup(0);
+ errx(2, "short read on '%s' - did not get %qd bytes",
+ fname, (long long)sb.st_size);
+ }
close(fd);
contents[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, int 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)
@@ -363,13 +412,20 @@ write_file(char *name, char *str)
int len;
fp = fopen(name, "w");
- if (!fp)
- barf("Can't fopen '%s' for writing.", name);
+ if (!fp) {
+ cleanup(0);
+ errx(2, "cannot 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);
+ if (fwrite(str, 1, len, fp) != len) {
+ cleanup(0);
+ errx(2, "short fwrite on '%s', tried to write %d bytes",
+ name, len);
+ }
+ if (fclose(fp)) {
+ cleanup(0);
+ errx(2, "failure to fclose '%s'", name);
+ }
}
void
@@ -381,8 +437,10 @@ copy_file(char *dir, char *fname, char *to)
snprintf(cmd, FILENAME_MAX, "cp -p -r %s %s", fname, to);
else
snprintf(cmd, FILENAME_MAX, "cp -p -r %s/%s %s", dir, fname, to);
- if (vsystem(cmd))
- barf("Couldn't perform '%s'", cmd);
+ if (vsystem(cmd)) {
+ cleanup(0);
+ errx(2, "could not perform '%s'", cmd);
+ }
}
void
@@ -394,8 +452,10 @@ move_file(char *dir, char *fname, char *to)
snprintf(cmd, FILENAME_MAX, "mv %s %s", fname, to);
else
snprintf(cmd, FILENAME_MAX, "mv %s/%s %s", dir, fname, to);
- if (vsystem(cmd))
- barf("Couldn't perform '%s'", cmd);
+ if (vsystem(cmd)) {
+ cleanup(0);
+ errx(2, "could not perform '%s'", cmd);
+ }
}
/*
@@ -424,8 +484,10 @@ copy_hierarchy(char *dir, char *fname, Boolean to)
#ifdef DEBUG
printf("Using '%s' to copy trees.\n", cmd);
#endif
- if (system(cmd))
- barf("copy_file: Couldn't perform '%s'", cmd);
+ if (system(cmd)) {
+ cleanup(0);
+ errx(2, "copy_file: could not perform '%s'", cmd);
+ }
}
/* Unpack a tar file */
@@ -451,7 +513,7 @@ unpack(char *pkg, char *flist)
strcpy(args, "z");
strcat(args, "xpf");
if (vsystem("tar %s %s %s", args, pkg, flist ? flist : "")) {
- whinge("Tar extract of %s failed!", pkg);
+ warnx("tar extract of %s failed!", pkg);
return 1;
}
return 0;
@@ -515,3 +577,49 @@ format_cmd(char *buf, char *fmt, char *dir, char *name)
}
*buf = '\0';
}
+
+
+/* This is as ftpGetURL from FreeBSD's ftpio.c, except that it uses
+ * OpenBSD's ftp command to do all FTP, which will DTRT for proxies,
+ * etc.
+ */
+FILE *
+ftpGetURL(char *url, char *user, char *passwd, int *retcode)
+{
+ FILE *ftp;
+ pid_t pid_ftp;
+ int p[2];
+
+ *retcode=0;
+
+ if( pipe(p) < 0){
+ *retcode = 1;
+ return NULL;
+ }
+
+ pid_ftp = fork();
+ if(pid_ftp < 0){
+ *retcode = 1;
+ return NULL;
+ }
+ if(pid_ftp == 0){
+ /* child */
+ dup2(p[1],1);
+ close(p[1]);
+
+ execl("/usr/bin/ftp","ftp","-V","-o","-",url,NULL);
+ exit(1);
+ }else{
+ /* parent */
+ ftp = fdopen(p[0],"r");
+
+ close(p[1]);
+
+ if(ftp < 0){
+ *retcode = 1;
+ return NULL;
+ }
+ }
+
+ return ftp;
+}
diff --git a/usr.sbin/pkg_install/lib/global.c b/usr.sbin/pkg_install/lib/global.c
index c5137e6bb37..c86f21a7934 100644
--- a/usr.sbin/pkg_install/lib/global.c
+++ b/usr.sbin/pkg_install/lib/global.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: global.c,v 1.2 1996/06/04 08:43:44 niklas Exp $ */
+/* $OpenBSD: global.c,v 1.3 1998/09/07 22:30:16 marc Exp $ */
#ifndef lint
-static const char *rcsid = "$OpenBSD: global.c,v 1.2 1996/06/04 08:43:44 niklas Exp $";
+static const char *rcsid = "$OpenBSD: global.c,v 1.3 1998/09/07 22:30:16 marc Exp $";
#endif
/*
@@ -30,6 +30,7 @@ static const char *rcsid = "$OpenBSD: global.c,v 1.2 1996/06/04 08:43:44 niklas
/* These are global for all utils */
Boolean Verbose = FALSE;
Boolean Fake = FALSE;
+Boolean Force = FALSE;
int AutoAnswer = FALSE;
diff --git a/usr.sbin/pkg_install/lib/lib.h b/usr.sbin/pkg_install/lib/lib.h
index f09d8228033..15d31a40d28 100644
--- a/usr.sbin/pkg_install/lib/lib.h
+++ b/usr.sbin/pkg_install/lib/lib.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: lib.h,v 1.1 1996/06/04 07:56:13 niklas Exp $ */
+/* $OpenBSD: lib.h,v 1.2 1998/09/07 22:30:16 marc Exp $ */
/*
* FreeBSD install - a package for the installation and maintainance
@@ -24,16 +24,17 @@
#define _INST_LIB_LIB_H_
/* Includes */
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+
+#include <ctype.h>
+#include <dirent.h>
#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)
@@ -62,27 +63,27 @@
#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 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 DISPLAY_FNAME "+DISPLAY"
+#define MTREE_FNAME "+MTREE_DIRS"
-#define CMD_CHAR '@' /* prefix for extended PLIST cmd */
+#define CMD_CHAR '@' /* prefix for extended PLIST cmd */
/* The name of the "prefix" environment variable given to scripts */
#define PKG_PREFIX_VNAME "PKG_PREFIX"
enum _plist_t {
PLIST_FILE, PLIST_CWD, PLIST_CMD, PLIST_CHMOD,
- PLIST_CHOWN, PLIST_CHGRP, PLIST_COMMENT,
- PLIST_IGNORE, PLIST_NAME, PLIST_UNEXEC, PLIST_SRC, PLIST_DISPLAY,
+ PLIST_CHOWN, PLIST_CHGRP, PLIST_COMMENT, PLIST_IGNORE,
+ PLIST_NAME, PLIST_UNEXEC, PLIST_SRC, PLIST_DISPLAY,
PLIST_PKGDEP, PLIST_MTREE, PLIST_DIR_RM, PLIST_IGNORE_INST,
- PLIST_OPTION
+ PLIST_OPTION, PLIST_PKGCFL
};
typedef enum _plist_t plist_t;
@@ -109,7 +110,7 @@ void cleanup(int);
char *make_playpen(char *, size_t);
char *where_playpen(void);
void leave_playpen(char *);
-size_t min_free(char *);
+off_t min_free(char *);
/* String */
char *get_dash_string(char **);
@@ -123,6 +124,9 @@ char *strconcat(char *, char *);
/* File */
Boolean fexists(char *);
Boolean isdir(char *);
+Boolean islinktodir(char *);
+Boolean isemptydir(char *fname);
+Boolean isemptyfile(char *fname);
Boolean isfile(char *);
Boolean isempty(char *);
Boolean isURL(char *);
@@ -131,6 +135,7 @@ char *fileURLFilename(char *, char *, int);
char *fileURLHost(char *, char *, int);
char *fileFindByPath(char *, char *);
char *fileGetContents(char *);
+Boolean make_preserve_name(char *, int, char *, char *);
void write_file(char *, char *);
void copy_file(char *, char *, char *);
void move_file(char *, char *, char *);
@@ -156,18 +161,19 @@ void mark_plist(Package *);
void csum_plist_entry(char *, PackingList);
void add_plist(Package *, plist_t, char *);
void add_plist_top(Package *, plist_t, char *);
+void delete_plist(Package *pkg, Boolean all, plist_t type, char *name);
void write_plist(Package *, FILE *);
void read_plist(Package *, FILE *);
int plist_cmd(char *, char **);
int delete_package(Boolean, Boolean, Package *);
/* For all */
-void usage(const char *, const char *, ...);
int pkg_perform(char **);
/* Externs */
extern Boolean Verbose;
extern Boolean Fake;
+extern Boolean Force;
extern int AutoAnswer;
#endif /* _INST_LIB_LIB_H_ */
diff --git a/usr.sbin/pkg_install/lib/msg.c b/usr.sbin/pkg_install/lib/msg.c
index 999bfaea477..2c8a839e9e3 100644
--- a/usr.sbin/pkg_install/lib/msg.c
+++ b/usr.sbin/pkg_install/lib/msg.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: msg.c,v 1.2 1996/06/04 08:43:44 niklas Exp $ */
+/* $OpenBSD: msg.c,v 1.3 1998/09/07 22:30:17 marc Exp $ */
#ifndef lint
-static const char *rcsid = "$OpenBSD: msg.c,v 1.2 1996/06/04 08:43:44 niklas Exp $";
+static const char *rcsid = "$OpenBSD: msg.c,v 1.3 1998/09/07 22:30:17 marc Exp $";
#endif
/*
@@ -25,42 +25,15 @@ static const char *rcsid = "$OpenBSD: msg.c,v 1.2 1996/06/04 08:43:44 niklas Exp
*
*/
+#include <err.h>
#include "lib.h"
/* Die a relatively simple death */
void
-upchuck(const char *err)
+upchuck(const char *errstr)
{
- 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);
+ err(1, "fatal error during execution: %s", errstr);
}
/*
@@ -80,8 +53,10 @@ y_or_n(Boolean def, const char *msg, ...)
* collected on stdin
*/
tty = fopen("/dev/tty", "r");
- if (!tty)
- barf("Can't open /dev/tty!\n");
+ if (!tty) {
+ cleanup(0);
+ errx(1, "can't open /dev/tty!");
+ }
while (ch != 'Y' && ch != 'N') {
vfprintf(stderr, msg, args);
if (def)
diff --git a/usr.sbin/pkg_install/lib/pen.c b/usr.sbin/pkg_install/lib/pen.c
index 31b35e22f5f..893b6bbf60e 100644
--- a/usr.sbin/pkg_install/lib/pen.c
+++ b/usr.sbin/pkg_install/lib/pen.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: pen.c,v 1.6 1998/04/25 05:09:07 millert Exp $ */
+/* $OpenBSD: pen.c,v 1.7 1998/09/07 22:30:17 marc Exp $ */
#ifndef lint
-static const char *rcsid = "$OpenBSD: pen.c,v 1.6 1998/04/25 05:09:07 millert Exp $";
+static const char *rcsid = "$OpenBSD: pen.c,v 1.7 1998/09/07 22:30:17 marc Exp $";
#endif
/*
@@ -24,6 +24,7 @@ static const char *rcsid = "$OpenBSD: pen.c,v 1.6 1998/04/25 05:09:07 millert Ex
*
*/
+#include <err.h>
#include "lib.h"
#include <sys/signal.h>
#include <sys/param.h>
@@ -59,9 +60,11 @@ find_play_pen(char *pen, size_t sz)
else if ((stat("/usr/tmp", &sb) == SUCCESS || mkdir("/usr/tmp", 01777) == SUCCESS) && min_free("/usr/tmp") >= sz)
strcpy(pen, "/usr/tmp/instmp.XXXXXXXXXX");
else {
- barf("Can't find enough temporary space to extract the files, please set\n"
- "your PKG_TMPDIR environment variable to a location with at least %d bytes\n"
- "free.", sz);
+ 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;
@@ -74,29 +77,27 @@ find_play_pen(char *pen, size_t sz)
char *
make_playpen(char *pen, size_t sz)
{
-
- if (!find_play_pen(pen, sz)) {
+ if (!find_play_pen(pen, sz))
return NULL;
- }
+
if (!mkdtemp(pen)) {
- barf("Can't mkdtemp '%s'.", pen);
- return NULL;
+ cleanup(0);
+ errx(2, "can't mkdtemp '%s'", pen);
}
if (chmod(pen, 0755) == FAIL) {
- barf("Can't chmod 0755 '%s'.", pen);
- return NULL;
+ cleanup(0);
+ errx(2, "can't chmod '%s'", pen);
}
-
if (Verbose) {
if (sz)
- fprintf(stderr, "Requested space: %d bytes, free space: %d bytes in %s\n", (int)sz, min_free(pen), pen);
+ fprintf(stderr, "Requested space: %lu bytes, free space: %qd bytes in %s\n", (u_long)sz, (long long)min_free(pen), pen);
}
if (min_free(pen) < sz) {
rmdir(pen);
- barf("Not enough free space to create: `%s'\n"
+ 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);
- return NULL;
+ "with more space and\ntry the command again", pen);
}
if (Current[0])
strcpy(Previous, Current);
@@ -104,8 +105,10 @@ make_playpen(char *pen, size_t sz)
upchuck("getcwd");
return NULL;
}
- if (chdir(pen) == FAIL)
- barf("Can't chdir to '%s'.", pen);
+ if (chdir(pen) == FAIL) {
+ cleanup(0);
+ errx(2, "can't chdir to '%s'", pen);
+ }
strcpy(Current, pen);
return Previous;
}
@@ -118,11 +121,16 @@ leave_playpen(char *save)
/* Don't interrupt while we're cleaning up */
oldsig = signal(SIGINT, SIG_IGN);
- if (Previous[0] && chdir(Previous) == FAIL)
- barf("Can't chdir back to '%s'.", Previous);
- else if (Current[0] && strcmp(Current, Previous)) {
+ if (Previous[0] && chdir(Previous) == FAIL) {
+ cleanup(0);
+ errx(2, "can't chdir back to '%s'", Previous);
+ } else if (Current[0] && strcmp(Current, Previous)) {
+ if (strcmp(Current,"/")==0) {
+ fprintf(stderr,"PANIC: About to rm -rf / (not doing so, aborting)\n");
+ abort();
+ }
if (vsystem("rm -rf %s", Current))
- whinge("Couldn't remove temporary dir '%s'", Current);
+ warnx("couldn't remove temporary dir '%s'", Current);
strcpy(Current, Previous);
}
if (save)
@@ -132,14 +140,14 @@ leave_playpen(char *save)
signal(SIGINT, oldsig);
}
-size_t
+off_t
min_free(char *tmpdir)
{
struct statfs buf;
if (statfs(tmpdir, &buf) != 0) {
- perror("Error in statfs");
+ warn("statfs");
return -1;
}
- return buf.f_bavail * buf.f_bsize;
+ return (off_t)buf.f_bavail * (off_t)buf.f_bsize;
}
diff --git a/usr.sbin/pkg_install/lib/plist.c b/usr.sbin/pkg_install/lib/plist.c
index b901fc28cdf..e3844ed5721 100644
--- a/usr.sbin/pkg_install/lib/plist.c
+++ b/usr.sbin/pkg_install/lib/plist.c
@@ -1,6 +1,6 @@
-/* $OpenBSD: plist.c,v 1.3 1997/01/17 07:14:16 millert Exp $ */
+/* $OpenBSD: plist.c,v 1.4 1998/09/07 22:30:17 marc Exp $ */
#ifndef lint
-static const char *rcsid = "$OpenBSD: plist.c,v 1.3 1997/01/17 07:14:16 millert Exp $";
+static const char *rcsid = "$OpenBSD: plist.c,v 1.4 1998/09/07 22:30:17 marc Exp $";
#endif
/*
@@ -24,6 +24,8 @@ static const char *rcsid = "$OpenBSD: plist.c,v 1.3 1997/01/17 07:14:16 millert
*/
#include "lib.h"
+#include <err.h>
+#include <md5.h>
/* Add an item to a packing list */
void
@@ -148,7 +150,7 @@ new_plist_entry(void)
PackingList ret;
ret = (PackingList)malloc(sizeof(struct _plist));
- bzero(ret, sizeof(struct _plist));
+ memset(ret, 0, sizeof(struct _plist));
return ret;
}
@@ -221,6 +223,8 @@ plist_cmd(char *s, char **arg)
return PLIST_DISPLAY;
else if (!strcmp(cmd, "pkgdep"))
return PLIST_PKGDEP;
+ else if (!strcmp(cmd, "pkgcfl"))
+ return PLIST_PKGCFL;
else if (!strcmp(cmd, "mtree"))
return PLIST_MTREE;
else if (!strcmp(cmd, "dirrm"))
@@ -239,17 +243,19 @@ read_plist(Package *pkg, FILE *fp)
int cmd;
while (fgets(pline, FILENAME_MAX, fp)) {
- int len = strlen(pline) - 1;
+ int len = strlen(pline);
- while (isspace(pline[len]))
- pline[len--] = '\0';
- if (len <= 0)
+ while (len && isspace(pline[len - 1]))
+ 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);
+ if (cmd == FAIL) {
+ warnx("Unrecognised PLIST command `%s'", pline);
+ continue;
+ }
if (*cp == '\0')
cp = NULL;
}
@@ -320,6 +326,10 @@ write_plist(Package *pkg, FILE *fp)
fprintf(fp, "%cpkgdep %s\n", CMD_CHAR, plist->name);
break;
+ case PLIST_PKGCFL:
+ fprintf(fp, "%cpkgcfl %s\n", CMD_CHAR, plist->name);
+ break;
+
case PLIST_MTREE:
fprintf(fp, "%cmtree %s\n", CMD_CHAR, plist->name);
break;
@@ -333,7 +343,8 @@ write_plist(Package *pkg, FILE *fp)
break;
default:
- barf("Unknown command type %d (%s)\n", plist->type, plist->name);
+ cleanup(0);
+ errx(2, "unknown command type %d (%s)", plist->type, plist->name);
break;
}
plist = plist->next;
@@ -349,51 +360,102 @@ write_plist(Package *pkg, FILE *fp)
int
delete_package(Boolean ign_err, Boolean nukedirs, Package *pkg)
{
- PackingList p = pkg->head;
+ PackingList p;
char *Where = ".", *last_file = "";
Boolean fail = SUCCESS;
+ Boolean preserve;
+ char tmp[FILENAME_MAX], *name = NULL;
- if (!p)
- return FAIL;
- while (p) {
- if (p->type == PLIST_CWD) {
+ 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);
- }
- else if (p->type == PLIST_UNEXEC) {
- char cmd[FILENAME_MAX];
+ break;
- format_cmd(cmd, p->name, Where, last_file);
+ case PLIST_UNEXEC:
+ format_cmd(tmp, p->name, Where, last_file);
if (Verbose)
- printf("Execute `%s'\n", cmd);
- if (!Fake && system(cmd)) {
- whinge("unexec command for `%s' failed.", cmd);
+ printf("Execute `%s'\n", tmp);
+ if (!Fake && system(tmp)) {
+ warnx("unexec command for `%s' failed", tmp);
fail = FAIL;
}
- }
- else if (p->type == PLIST_IGNORE)
- p = p->next;
- else if (p->type == PLIST_FILE || p->type == PLIST_DIR_RM) {
- char full_name[FILENAME_MAX];
+ break;
- sprintf(full_name, "%s/%s", Where, p->name);
- if (isdir(full_name) && p->type == PLIST_FILE) {
- warn("Attempting to delete directory `%s' as a file\n"
- "This packing list is incorrect - ignoring delete request.\n", full_name);
+ case PLIST_FILE:
+ last_file = p->name;
+ sprintf(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 && !strncmp(p->next->name, "MD5:", 4)) {
+ char *cp, buf[33];
+
+ if ((cp = MD5File(tmp, buf)) != NULL) {
+ /* Mismatch? */
+ if (strcmp(cp, p->next->name + 4)) {
+ 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 %s %s\n", !isdir(full_name) ? "file" : " directory", full_name);
+ printf("Delete file %s\n", tmp);
+ if (!Fake) {
+ 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);
+ }
+ }
+ }
+ }
+ }
+ break;
- if (!Fake && delete_hierarchy(full_name, ign_err, p->type == PLIST_DIR_RM ? FALSE : nukedirs)) {
- whinge("Unable to completely remove file '%s'", full_name);
+ case PLIST_DIR_RM:
+ sprintf(tmp, "%s/%s", Where, p->name);
+ if (!isdir(tmp)) {
+ warnx("attempting to delete file `%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;
}
}
last_file = p->name;
+ break;
+ default:
+ break;
}
- p = p->next;
}
return fail;
}
@@ -415,14 +477,19 @@ delete_hierarchy(char *dir, Boolean ign_err, Boolean nukedirs)
cp1 = cp2 = dir;
if (!fexists(dir)) {
if (!ign_err)
- whinge("%s `%s' doesn't really exist.", isdir(dir) ? "Directory" : "File", dir);
- } else if (nukedirs) {
+ warnx("%s `%s' doesn't really exist",
+ isdir(dir) ? "directory" : "file", dir);
+ return !ign_err;
+ }
+ else if (nukedirs) {
if (vsystem("%s -r%s %s", REMOVE_CMD, (ign_err ? "f" : ""), dir))
return 1;
- } else if (isdir(dir)) {
+ }
+ else if (isdir(dir)) {
if (RMDIR(dir) && !ign_err)
return 1;
- } else {
+ }
+ else {
if (REMOVE(dir, ign_err))
return 1;
}
@@ -434,11 +501,12 @@ delete_hierarchy(char *dir, Boolean ign_err, Boolean nukedirs)
*cp2 = '\0';
if (!isemptydir(dir))
return 0;
- if (RMDIR(dir) && !ign_err)
+ if (RMDIR(dir) && !ign_err) {
if (!fexists(dir))
- whinge("Directory `%s' doesn't really exist.", dir);
+ warnx("directory `%s' doesn't really exist", dir);
else
return 1;
+ }
/* back up the pathname one component */
if (cp2) {
cp1 = dir;