- 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:
parent
ac68d688b1
commit
f3fa78b0b5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=84750
@ -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.
|
||||
|
@ -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));
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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",
|
||||
|
48
usr.sbin/pkg_install/lib/version.c
Normal file
48
usr.sbin/pkg_install/lib/version.c
Normal 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user