summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/pkg_install/create/perform.c7
-rw-r--r--usr.sbin/pkg_install/create/pl.c14
-rw-r--r--usr.sbin/pkg_install/info/info.h2
-rw-r--r--usr.sbin/pkg_install/info/main.c8
-rw-r--r--usr.sbin/pkg_install/info/perform.c2
-rw-r--r--usr.sbin/pkg_install/info/pkg_info.14
-rw-r--r--usr.sbin/pkg_install/info/show.c9
-rw-r--r--usr.sbin/pkg_install/lib/Makefile3
-rw-r--r--usr.sbin/pkg_install/lib/lib.h8
-rw-r--r--usr.sbin/pkg_install/lib/plist.c58
-rw-r--r--usr.sbin/pkg_install/lib/version.c48
11 files changed, 146 insertions, 17 deletions
diff --git a/usr.sbin/pkg_install/create/perform.c b/usr.sbin/pkg_install/create/perform.c
index cd1f8a5..8265e26 100644
--- a/usr.sbin/pkg_install/create/perform.c
+++ b/usr.sbin/pkg_install/create/perform.c
@@ -163,6 +163,13 @@ pkg_perform(char **pkgs)
if (find_plist(&plist, PLIST_NAME) == NULL)
add_plist_top(&plist, PLIST_NAME, basename(pkg));
+ if (asprintf(&cp, "PKG_FORMAT_REVISION:%d.%d", PLIST_FMT_VER_MAJOR,
+ PLIST_FMT_VER_MINOR) == -1) {
+ errx(2, "%s: asprintf() failed", __FUNCTION__);
+ }
+ add_plist_top(&plist, PLIST_COMMENT, cp);
+ free(cp);
+
/*
* We're just here for to dump out a revised plist for the FreeBSD ports
* hack. It's not a real create in progress.
diff --git a/usr.sbin/pkg_install/create/pl.c b/usr.sbin/pkg_install/create/pl.c
index 028b49c..a12ce62 100644
--- a/usr.sbin/pkg_install/create/pl.c
+++ b/usr.sbin/pkg_install/create/pl.c
@@ -50,8 +50,20 @@ check_list(const char *home, Package *pkg)
there = p->name;
break;
case PLIST_FILE:
+ cp = NULL;
sprintf(name, "%s/%s", there ? there : where, p->name);
- if ((cp = MD5File(name, buf)) != NULL) {
+ if (issymlink(name)) {
+ int len;
+ char lnk[FILENAME_MAX];
+
+ if ((len = readlink(name, lnk, FILENAME_MAX)) > 0)
+ cp = MD5Data((unsigned char *)lnk, len, buf);
+ } else if (isfile(name)) {
+ /* Don't record MD5 checksum for device nodes and such */
+ cp = MD5File(name, buf);
+ }
+
+ if (cp != NULL) {
PackingList tmp = new_plist_entry();
tmp->name = copy_string(strconcat("MD5:", cp));
diff --git a/usr.sbin/pkg_install/info/info.h b/usr.sbin/pkg_install/info/info.h
index 9b3804a..3f0bb9a 100644
--- a/usr.sbin/pkg_install/info/info.h
+++ b/usr.sbin/pkg_install/info/info.h
@@ -48,6 +48,7 @@
#define SHOW_SIZE 0x1000
#define SHOW_ORIGIN 0x2000
#define SHOW_CKSUM 0x4000
+#define SHOW_FMTREV 0x8000
struct which_entry {
TAILQ_ENTRY(which_entry) next;
@@ -72,5 +73,6 @@ extern void show_index(const char *, const char *);
extern void show_size(const char *, Package *);
extern void show_cksum(const char *, Package *);
extern void show_origin(const char *, Package *);
+extern void show_fmtrev(const char *, Package *);
#endif /* _INST_INFO_H_INCLUDE */
diff --git a/usr.sbin/pkg_install/info/main.c b/usr.sbin/pkg_install/info/main.c
index 6e4e855..3c78c2f 100644
--- a/usr.sbin/pkg_install/info/main.c
+++ b/usr.sbin/pkg_install/info/main.c
@@ -28,7 +28,7 @@ static const char rcsid[] =
"$FreeBSD$";
#endif
-static char Options[] = "acdDe:fgGhiIkl:LmopqrRst:vW:x";
+static char Options[] = "acdDe:fgGhiIkl:LmopqrRst:vVW:x";
int Flags = 0;
match_t MatchType = MATCH_GLOB;
@@ -134,6 +134,10 @@ main(int argc, char **argv)
Flags |= SHOW_ORIGIN;
break;
+ case 'V':
+ Flags |= SHOW_FMTREV;
+ break;
+
case 'l':
InfoPrefix = optarg;
break;
@@ -216,7 +220,7 @@ static void
usage()
{
fprintf(stderr, "%s\n%s\n%s\n",
- "usage: pkg_info [-cdDfGiIkLmopqrRsvx] [-e package] [-l prefix]",
+ "usage: pkg_info [-cdDfGiIkLmopqrRsvVx] [-e package] [-l prefix]",
" [-t template] [-W filename] [pkg-name ...]",
" pkg_info -a [flags]");
exit(1);
diff --git a/usr.sbin/pkg_install/info/perform.c b/usr.sbin/pkg_install/info/perform.c
index 1b5d2d8..9c5c927 100644
--- a/usr.sbin/pkg_install/info/perform.c
+++ b/usr.sbin/pkg_install/info/perform.c
@@ -214,6 +214,8 @@ pkg_do(char *pkg)
show_cksum("Mismatched Checksums:\n", &plist);
if (Flags & SHOW_ORIGIN)
show_origin("Origin:\n", &plist);
+ if (Flags & SHOW_FMTREV)
+ show_fmtrev("Packing list format revision:\n", &plist);
if (!Quiet)
puts(InfoPrefix);
}
diff --git a/usr.sbin/pkg_install/info/pkg_info.1 b/usr.sbin/pkg_install/info/pkg_info.1
index ac2d448..37b5253 100644
--- a/usr.sbin/pkg_install/info/pkg_info.1
+++ b/usr.sbin/pkg_install/info/pkg_info.1
@@ -25,7 +25,7 @@
.Nd a utility for displaying information on software packages
.Sh SYNOPSIS
.Nm
-.Op Fl cdDfgGiIkLmopqrRsvx
+.Op Fl cdDfgGiIkLmopqrRsvVx
.Op Fl e Ar package
.Op Fl l Ar prefix
.Op Fl t Ar template
@@ -163,6 +163,8 @@ and one would have to have a very small
.Pa /tmp
indeed to overflow it.
.Ed
+.It Fl V
+Show revision number of the packing list format.
.El
.Sh TECHNICAL DETAILS
Package info is either extracted from package files named on the
diff --git a/usr.sbin/pkg_install/info/show.c b/usr.sbin/pkg_install/info/show.c
index 91432e5..03b1a53 100644
--- a/usr.sbin/pkg_install/info/show.c
+++ b/usr.sbin/pkg_install/info/show.c
@@ -307,3 +307,12 @@ show_origin(const char *title, Package *plist)
break;
}
}
+
+/* Show revision number of the packing list */
+void
+show_fmtrev(const char *title, Package *plist)
+{
+ if (!Quiet)
+ printf("%s%s", InfoPrefix, title);
+ printf("%d.%d\n", plist->fmtver_maj, plist->fmtver_mnr);
+}
diff --git a/usr.sbin/pkg_install/lib/Makefile b/usr.sbin/pkg_install/lib/Makefile
index 78bedc4..5d78e2c 100644
--- a/usr.sbin/pkg_install/lib/Makefile
+++ b/usr.sbin/pkg_install/lib/Makefile
@@ -3,7 +3,8 @@
LIB= install
NOPROFILE= yes
NOPIC= yes
-SRCS= file.c msg.c plist.c str.c exec.c global.c pen.c match.c deps.c
+SRCS= file.c msg.c plist.c str.c exec.c global.c pen.c match.c \
+ deps.c version.c
CFLAGS+= ${DEBUG}
diff --git a/usr.sbin/pkg_install/lib/lib.h b/usr.sbin/pkg_install/lib/lib.h
index 70a1408..55fd2fa 100644
--- a/usr.sbin/pkg_install/lib/lib.h
+++ b/usr.sbin/pkg_install/lib/lib.h
@@ -82,6 +82,10 @@
/* The name of the "prefix" environment variable given to scripts */
#define PKG_PREFIX_VNAME "PKG_PREFIX"
+/* Version numbers to assist with changes in package file format */
+#define PLIST_FMT_VER_MAJOR 1
+#define PLIST_FMT_VER_MINOR 1
+
enum _plist_t {
PLIST_FILE, PLIST_CWD, PLIST_CMD, PLIST_CHMOD,
PLIST_CHOWN, PLIST_CHGRP, PLIST_COMMENT, PLIST_IGNORE,
@@ -109,6 +113,7 @@ typedef struct _plist *PackingList;
struct _pack {
struct _plist *head, *tail;
+ int fmtver_maj, fmtver_mnr;
};
typedef struct _pack Package;
@@ -192,6 +197,9 @@ int sortdeps(char **);
int chkifdepends(const char *, const char *);
int requiredby(const char *, struct reqr_by_head **, Boolean, Boolean);
+/* Version */
+int verscmp(Package *, int, int);
+
/* Externs */
extern Boolean Verbose;
extern Boolean Fake;
diff --git a/usr.sbin/pkg_install/lib/plist.c b/usr.sbin/pkg_install/lib/plist.c
index c7b3738..4e3fd46 100644
--- a/usr.sbin/pkg_install/lib/plist.c
+++ b/usr.sbin/pkg_install/lib/plist.c
@@ -239,8 +239,10 @@ void
read_plist(Package *pkg, FILE *fp)
{
char *cp, pline[FILENAME_MAX];
- int cmd;
+ int cmd, major, minor;
+ pkg->fmtver_maj = 1;
+ pkg->fmtver_mnr = 0;
while (fgets(pline, FILENAME_MAX, fp)) {
int len = strlen(pline);
@@ -249,17 +251,35 @@ read_plist(Package *pkg, FILE *fp)
if (!len)
continue;
cp = pline;
- if (pline[0] == CMD_CHAR) {
- cmd = plist_cmd(pline + 1, &cp);
- if (cmd == FAIL) {
+ if (pline[0] != CMD_CHAR) {
+ cmd = PLIST_FILE;
+ goto bottom;
+ }
+ cmd = plist_cmd(pline + 1, &cp);
+ if (cmd == FAIL) {
+ cleanup(0);
+ errx(2, __FUNCTION__ ": bad command '%s'", pline);
+ }
+ if (*cp == '\0') {
+ cp = NULL;
+ goto bottom;
+ }
+ if (cmd == PLIST_COMMENT && sscanf(cp, "PKG_FORMAT_REVISION:%d.%d\n",
+ &major, &minor) == 2) {
+ pkg->fmtver_maj = major;
+ pkg->fmtver_mnr = minor;
+ if (verscmp(pkg, PLIST_FMT_VER_MAJOR, PLIST_FMT_VER_MINOR) <= 0)
+ goto bottom;
+
+ warnx("plist format revision (%d.%d) is higher than supported"
+ "(%d.%d)", pkg->fmtver_maj, pkg->fmtver_mnr,
+ PLIST_FMT_VER_MAJOR, PLIST_FMT_VER_MINOR);
+ if (pkg->fmtver_maj > PLIST_FMT_VER_MAJOR) {
cleanup(0);
- errx(2, __FUNCTION__ ": bad command '%s'", pline);
+ exit(2);
}
- if (*cp == '\0')
- cp = NULL;
}
- else
- cmd = PLIST_FILE;
+bottom:
add_plist(pkg, cmd, cp);
}
}
@@ -397,9 +417,23 @@ delete_package(Boolean ign_err, Boolean nukedirs, Package *pkg)
}
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) {
+ char *cp = NULL, buf[33];
+
+ /*
+ * For packing lists whose version is 1.1 or greater, the md5
+ * hash for a symlink is calculated on the string returned
+ * by readlink().
+ */
+ if (issymlink(tmp) && verscmp(pkg, 1, 0) > 0) {
+ int len;
+ char linkbuf[FILENAME_MAX];
+
+ if ((len = readlink(tmp, linkbuf, FILENAME_MAX)) > 0)
+ cp = MD5Data((unsigned char *)linkbuf, len, buf);
+ } else if (isfile(tmp) || verscmp(pkg, 1, 1) < 0)
+ cp = MD5File(tmp, buf);
+
+ if (cp != NULL) {
/* Mismatch? */
if (strcmp(cp, p->next->name + 4)) {
warnx("'%s' fails original MD5 checksum - %s",
diff --git a/usr.sbin/pkg_install/lib/version.c b/usr.sbin/pkg_install/lib/version.c
new file mode 100644
index 0000000..1348fe8
--- /dev/null
+++ b/usr.sbin/pkg_install/lib/version.c
@@ -0,0 +1,48 @@
+#ifndef lint
+static const char rcsid[] =
+ "$FreeBSD$";
+#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.
+ *
+ * Maxim Sobolev
+ * 31 July 2001
+ *
+ * Routines to assist with PLIST_FMT_VER numbers in the packing
+ * lists.
+ *
+ * Following is the PLIST_FMT_VER history:
+ * 1.0 - Initial revision;
+ * 1.1 - When recording/checking checksum of symlink use hash of readlink()
+ * value insted of the hash of an object this links points to.
+ *
+ */
+
+#include "lib.h"
+#include <err.h>
+
+int
+verscmp(Package *pkg, int major, int minor)
+{
+ int rval = 0;
+
+ if ((pkg->fmtver_maj < major) || (pkg->fmtver_maj == major &&
+ pkg->fmtver_mnr < minor))
+ rval = -1;
+ else if ((pkg->fmtver_maj > major) || (pkg->fmtver_maj == major &&
+ pkg->fmtver_mnr > minor))
+ rval = 1;
+
+ return rval;
+}
OpenPOWER on IntegriCloud