diff options
author | sobomax <sobomax@FreeBSD.org> | 2001-10-10 08:21:41 +0000 |
---|---|---|
committer | sobomax <sobomax@FreeBSD.org> | 2001-10-10 08:21:41 +0000 |
commit | 5ef9bb01d5f61e4f52a539ac2ceb0ab6f60cac11 (patch) | |
tree | f9075d260c6d242b36af96fc1bd51e6ead2a7632 /usr.sbin | |
parent | 3ecc09960218d1a88e9cd4b7428a640ca3cef599 (diff) | |
download | FreeBSD-src-5ef9bb01d5f61e4f52a539ac2ceb0ab6f60cac11.zip FreeBSD-src-5ef9bb01d5f61e4f52a539ac2ceb0ab6f60cac11.tar.gz |
- Introduce a notion of `packing list format version'. This allows making
non-backward compatible changes in the format of packing list and handle
them gracefully;
- fix a longstanding issue with symlinks handling. Instead of recording
checksum for the file symlink points to, record checksum for the value
returned by readlink(2). For backward compatibility increase packing list
format minor version number and provide a fallback to a previous behaviour,
if package in question was created with older version of pkg_* tools;
Submitted by: Alec Wolman <wolman@cs.washington.edu>, sobomax
- don't record MD5 checksum for device nodes, fifo's and other non-regular
files.
Submitted by: nbm
MFC in: 2 weeks
Diffstat (limited to 'usr.sbin')
-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; +} |