- 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
This commit is contained in:
Maxim Sobolev 2001-10-10 08:21:41 +00:00
parent ac68d688b1
commit f3fa78b0b5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=84750
11 changed files with 147 additions and 18 deletions

View File

@ -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.

View File

@ -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));

View File

@ -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 */

View File

@ -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);

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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}

View File

@ -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;

View File

@ -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) {
cleanup(0);
errx(2, __FUNCTION__ ": bad command '%s'", pline);
}
if (*cp == '\0')
cp = NULL;
}
else
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);
exit(2);
}
}
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];
char *cp = NULL, buf[33];
if ((cp = MD5File(tmp, buf)) != NULL) {
/*
* 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",

View File

@ -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;
}