diff options
-rw-r--r-- | usr.sbin/pkg_install/create/perform.c | 7 | ||||
-rw-r--r-- | usr.sbin/pkg_install/create/pl.c | 14 | ||||
-rw-r--r-- | usr.sbin/pkg_install/info/info.h | 2 | ||||
-rw-r--r-- | usr.sbin/pkg_install/info/main.c | 8 | ||||
-rw-r--r-- | usr.sbin/pkg_install/info/perform.c | 2 | ||||
-rw-r--r-- | usr.sbin/pkg_install/info/pkg_info.1 | 4 | ||||
-rw-r--r-- | usr.sbin/pkg_install/info/show.c | 9 | ||||
-rw-r--r-- | usr.sbin/pkg_install/lib/Makefile | 3 | ||||
-rw-r--r-- | usr.sbin/pkg_install/lib/lib.h | 8 | ||||
-rw-r--r-- | usr.sbin/pkg_install/lib/plist.c | 58 | ||||
-rw-r--r-- | usr.sbin/pkg_install/lib/version.c | 48 |
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; +} |