C replacement for the Perl5 code.
Submitted by: reg
This commit is contained in:
parent
8ba3d077ff
commit
8360b6af14
@ -203,6 +203,8 @@ int requiredby(const char *, struct reqr_by_head **, Boolean, Boolean);
|
||||
|
||||
/* Version */
|
||||
int verscmp(Package *, int, int);
|
||||
const char *version_of(const char *, int *, int *);
|
||||
int version_cmp(const char *, const char *);
|
||||
|
||||
/* Externs */
|
||||
extern Boolean Verbose;
|
||||
|
@ -14,6 +14,15 @@
|
||||
* Maxim Sobolev
|
||||
* 31 July 2001
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "lib.h"
|
||||
#include <err.h>
|
||||
|
||||
/*
|
||||
* Routines to assist with PLIST_FMT_VER numbers in the packing
|
||||
* lists.
|
||||
*
|
||||
@ -23,13 +32,6 @@
|
||||
* value insted of the hash of an object this links points to.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "lib.h"
|
||||
#include <err.h>
|
||||
|
||||
int
|
||||
verscmp(Package *pkg, int major, int minor)
|
||||
{
|
||||
@ -44,3 +46,126 @@ verscmp(Package *pkg, int major, int minor)
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* version_of(pkgname, epoch, revision) returns a pointer to the version
|
||||
* portion of a package name and the two special components.
|
||||
*
|
||||
* Jeremy D. Lea.
|
||||
*/
|
||||
const char *
|
||||
version_of(const char *pkgname, int *epoch, int *revision)
|
||||
{
|
||||
char *ch;
|
||||
|
||||
if (pkgname == NULL)
|
||||
errx(2, "%s: Passed NULL pkgname.", __func__);
|
||||
if (epoch != NULL) {
|
||||
if ((ch = strrchr(pkgname, ',')) == NULL)
|
||||
*epoch = 0;
|
||||
else
|
||||
*epoch = atoi(&ch[1]);
|
||||
}
|
||||
if (revision != NULL) {
|
||||
if ((ch = strrchr(pkgname, '_')) == NULL)
|
||||
*revision = 0;
|
||||
else
|
||||
*revision = atoi(&ch[1]);
|
||||
}
|
||||
/* Cheat if we are just passed a version, not a valid package name */
|
||||
if ((ch = strrchr(pkgname, '-')) == NULL)
|
||||
return pkgname;
|
||||
else
|
||||
return &ch[1];
|
||||
}
|
||||
|
||||
/*
|
||||
* version_cmp(pkg1, pkg2) returns -1, 0 or 1 depending on if the version
|
||||
* components of pkg1 is less than, equal to or greater than pkg2. No
|
||||
* comparision of the basenames is done.
|
||||
*
|
||||
* The port verison is defined by:
|
||||
* ${PORTVERSION}[_${PORTREVISION}][,${PORTEPOCH}]
|
||||
* ${PORTEPOCH} supercedes ${PORTVERSION} supercedes ${PORTREVISION}.
|
||||
* See the commit log for revision 1.349 of ports/Mk/bsd.port.mk
|
||||
* for more information.
|
||||
*
|
||||
* The epoch and revision are defined to be a single number, while the rest
|
||||
* of the version should conform to the porting guidelines. It can contain
|
||||
* multiple components, seperated by a period, including letters.
|
||||
*
|
||||
* The tests below allow for significantly more latitude in the version
|
||||
* numbers than is allowed in the guidelines. No point in wasting user's
|
||||
* time enforcing them here. That's what flamewars are for.
|
||||
*
|
||||
* Jeremy D. Lea.
|
||||
*/
|
||||
int
|
||||
version_cmp(const char *pkg1, const char *pkg2)
|
||||
{
|
||||
const char *c1, *c2, *v1, *v2;
|
||||
char *t1, *t2;
|
||||
int e1, e2, r1, r2, n1, n2;
|
||||
|
||||
v1 = version_of(pkg1, &e1, &r1);
|
||||
v2 = version_of(pkg2, &e2, &r2);
|
||||
/* Minor optimisation. */
|
||||
if (strcmp(v1, v2) == 0)
|
||||
return 0;
|
||||
/* First compare epoch. */
|
||||
if (e1 != e2)
|
||||
return (e1 < e2 ? -1 : 1);
|
||||
else {
|
||||
/*
|
||||
* We walk down the versions, trying to convert to numbers.
|
||||
* We terminate when we reach an underscore, a comma or the
|
||||
* string terminator, thanks to a nasty trick with strchr().
|
||||
* strtol() conveniently gobbles up the chars it converts.
|
||||
*/
|
||||
c1 = strchr("_,", v1[0]);
|
||||
c2 = strchr("_,", v2[0]);
|
||||
while (c1 == NULL && c2 == NULL) {
|
||||
n1 = strtol(v1, &t1, 10);
|
||||
n2 = strtol(v2, &t2, 10);
|
||||
if (n1 != n2)
|
||||
return (n1 < n2 ? -1 : 1);
|
||||
/*
|
||||
* The numbers are equal, check for letters. Assume they're
|
||||
* letters purely because strtol() didn't chomp them.
|
||||
*/
|
||||
c1 = strchr("_,.", t1[0]);
|
||||
c2 = strchr("_,.", t2[0]);
|
||||
if (c1 == NULL && c2 == NULL) {
|
||||
/* Both have letters. Compare them. */
|
||||
if (t1[0] != t2[0])
|
||||
return (t1[0] < t2[0] ? -1 : 1);
|
||||
/* Boring. The letters are equal. Carry on. */
|
||||
v1 = &t1[1], v2 = &t2[1];
|
||||
} else if (c1 == NULL) {
|
||||
/*
|
||||
* Letters are strange. After a number, a letter counts
|
||||
* as greater, but after a period it's less.
|
||||
*/
|
||||
return (isdigit(v1[0]) ? 1 : -1);
|
||||
} else if (c2 == NULL) {
|
||||
return (isdigit(v2[0]) ? -1 : 1);
|
||||
} else {
|
||||
/* Neither were letters. Advance over the period. */
|
||||
v1 = (t1[0] == '.' ? &t1[1] : t1);
|
||||
v2 = (t2[0] == '.' ? &t2[1] : t2);
|
||||
}
|
||||
c1 = strchr("_,", v1[0]);
|
||||
c2 = strchr("_,", v2[0]);
|
||||
}
|
||||
/* If we got here, check if one version has something left. */
|
||||
if (c1 == NULL)
|
||||
return (isdigit(v1[0]) ? 1 : -1);
|
||||
if (c2 == NULL)
|
||||
return (isdigit(v2[0]) ? -1 : 1);
|
||||
/* We've run out of version. Try the revision... */
|
||||
if (r1 != r2)
|
||||
return (r1 < r2 ? -1 : 1);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,19 @@
|
||||
# $FreeBSD$
|
||||
|
||||
SCRIPTS= pkg_version.pl
|
||||
MAN= pkg_version.1
|
||||
PROG= pkg_version
|
||||
SRCS= main.c perform.c
|
||||
|
||||
CFLAGS+= ${DEBUG} -I${.CURDIR}/../lib
|
||||
|
||||
WARNS?= 2
|
||||
|
||||
DPADD= ${LIBINSTALL} ${LIBFETCH} ${LIBMD}
|
||||
LDADD= ${LIBINSTALL} -lfetch -lmd
|
||||
|
||||
.if !defined(NOCRYPT) && !defined(NOSECURE) && !defined(NO_OPENSSL)
|
||||
DPADD+= ${LIBSSL} ${LIBCRYPTO}
|
||||
LDADD+= -lssl -lcrypto
|
||||
.endif
|
||||
|
||||
test:
|
||||
./test-pkg_version.sh
|
||||
|
89
usr.sbin/pkg_install/version/main.c
Normal file
89
usr.sbin/pkg_install/version/main.c
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Jeremy D. Lea.
|
||||
* 11 May 2002
|
||||
*
|
||||
* This is the version module. Based on pkg_version.pl by Bruce A. Mah.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "lib.h"
|
||||
#include "version.h"
|
||||
#include <err.h>
|
||||
|
||||
static char Options[] = "dhl:L:s:tv";
|
||||
|
||||
char *LimitChars = NULL;
|
||||
char *PreventChars = NULL;
|
||||
char *MatchName = NULL;
|
||||
|
||||
static void usage __P((void));
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int ch, cmp = 0;
|
||||
|
||||
if (argc == 4 && !strcmp(argv[1], "-t")) {
|
||||
cmp = version_cmp(argv[2], argv[3]);
|
||||
printf(cmp > 0 ? ">\n" : (cmp < 0 ? "<\n" : "=\n"));
|
||||
exit(0);
|
||||
}
|
||||
else while ((ch = getopt(argc, argv, Options)) != -1) {
|
||||
switch(ch) {
|
||||
case 'v':
|
||||
Verbose = TRUE;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
LimitChars = optarg;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
PreventChars = optarg;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
MatchName = optarg;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
errx(2, "Invalid -t usage.");
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
return pkg_perform(argv);
|
||||
}
|
||||
|
||||
static void
|
||||
usage()
|
||||
{
|
||||
fprintf(stderr, "%s\n%s\n",
|
||||
"usage: pkg_version [-hv] [-l limchar] [-L limchar] [-s string] index",
|
||||
" pkg_version -t v1 v2");
|
||||
exit(1);
|
||||
}
|
281
usr.sbin/pkg_install/version/perform.c
Normal file
281
usr.sbin/pkg_install/version/perform.c
Normal file
@ -0,0 +1,281 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Jeremy D. Lea.
|
||||
* 11 May 2002
|
||||
*
|
||||
* This is the version module. Based on pkg_version.pl by Bruce A. Mah.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "lib.h"
|
||||
#include "version.h"
|
||||
#include <err.h>
|
||||
#include <fetch.h>
|
||||
#include <signal.h>
|
||||
|
||||
FILE *IndexFile;
|
||||
struct index_head Index = SLIST_HEAD_INITIALIZER(Index);
|
||||
|
||||
static int pkg_do(char *);
|
||||
static void show_version(const char *, const char *, const char *);
|
||||
|
||||
/*
|
||||
* This is the traditional pkg_perform, except that the argument is _not_
|
||||
* a list of packages. It is the index file from the command line.
|
||||
*
|
||||
* We loop over the installed packages, matching them with the -s flag
|
||||
* if needed and calling pkg_do(). Before hand we set up a few things,
|
||||
* and after we tear them down...
|
||||
*/
|
||||
int
|
||||
pkg_perform(char **indexarg)
|
||||
{
|
||||
char tmp[PATH_MAX], **pkgs;
|
||||
struct index_entry *ie;
|
||||
int i, err_cnt = 0;
|
||||
|
||||
/*
|
||||
* Try to find and open the INDEX. We only check IndexFile != NULL
|
||||
* later, if we actually need the INDEX.
|
||||
*/
|
||||
if (*indexarg == NULL)
|
||||
snprintf(tmp, PATH_MAX, "%s/INDEX", PORTS_DIR);
|
||||
else
|
||||
strlcpy(tmp, *indexarg, PATH_MAX);
|
||||
if (isURL(tmp))
|
||||
IndexFile = fetchGetURL(tmp, "");
|
||||
else
|
||||
IndexFile = fopen(tmp, "r");
|
||||
|
||||
/* Get a list of all the installed packages */
|
||||
pkgs = matchinstalled(MATCH_ALL, NULL, &err_cnt);
|
||||
if (err_cnt != 0)
|
||||
errx(2, "Unable to find package database directory!");
|
||||
i = -1;
|
||||
while (pkgs[++i] != NULL) {
|
||||
if (MatchName == NULL || strstr(pkgs[i], MatchName))
|
||||
err_cnt += pkg_do(pkgs[i]);
|
||||
}
|
||||
|
||||
/* If we opened the INDEX in pkg_do(), clean up. */
|
||||
while (!SLIST_EMPTY(&Index)) {
|
||||
ie = SLIST_FIRST(&Index);
|
||||
SLIST_REMOVE_HEAD(&Index, next);
|
||||
free(ie);
|
||||
}
|
||||
if (IndexFile != NULL)
|
||||
fclose(IndexFile);
|
||||
|
||||
return err_cnt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Traditional pkg_do(). We take the package name we are passed and
|
||||
* first slurp in the CONTENTS file, getting name and origin, then
|
||||
* we look for it's corresponding Makefile. If that fails we pull in
|
||||
* the INDEX, and check there.
|
||||
*/
|
||||
static int
|
||||
pkg_do(char *pkg)
|
||||
{
|
||||
char *ch, tmp[PATH_MAX], tmp2[PATH_MAX], *latest = NULL;
|
||||
Package plist;
|
||||
struct index_entry *ie;
|
||||
FILE *fp;
|
||||
size_t len;
|
||||
|
||||
/* Suck in the contents list. */
|
||||
plist.head = plist.tail = NULL;
|
||||
plist.name = plist.origin = NULL;
|
||||
snprintf(tmp, PATH_MAX, "%s/%s/%s", LOG_DIR, pkg, CONTENTS_FNAME);
|
||||
fp = fopen(tmp, "r");
|
||||
if (!fp) {
|
||||
warnx("unable to open %s file", CONTENTS_FNAME);
|
||||
return 1;
|
||||
}
|
||||
read_plist(&plist, fp);
|
||||
fclose(fp);
|
||||
|
||||
/*
|
||||
* First we check if the installed package has an origin, and try
|
||||
* looking for it's Makefile. If we find the Makefile we get the
|
||||
* latest version from there. If we fail, we start looking in the
|
||||
* INDEX, first matching the origin and then the package name.
|
||||
*/
|
||||
if (plist.origin != NULL) {
|
||||
snprintf(tmp, PATH_MAX, "%s/%s", PORTS_DIR, plist.origin);
|
||||
if (isdir(tmp) && chdir(tmp) != FAIL && isfile("Makefile")) {
|
||||
if ((latest = vpipe("make -V PKGNAME", tmp)) == NULL)
|
||||
warnx("Failed to get PKGNAME from %s/Makefile!", tmp);
|
||||
else
|
||||
show_version(plist.name, latest, "port");
|
||||
}
|
||||
}
|
||||
if (latest == NULL) {
|
||||
/* We only pull in the INDEX once, if needed. */
|
||||
if (SLIST_EMPTY(&Index)) {
|
||||
if (!IndexFile)
|
||||
errx(2, "Unable to open INDEX in %s.", __func__);
|
||||
while ((ch = fgetln(IndexFile, &len)) != NULL) {
|
||||
/*
|
||||
* Don't use strlcpy() because fgetln() doesn't
|
||||
* return a valid C string.
|
||||
*/
|
||||
strncpy(tmp, ch, MIN(len, PATH_MAX));
|
||||
tmp[PATH_MAX-1] = '\0';
|
||||
/* The INDEX has pkgname|portdir|... */
|
||||
if ((ch = strchr(tmp, '|')) != NULL)
|
||||
ch[0] = '\0';
|
||||
if (ch != NULL && (ch = strchr(&ch[1], '|')) != NULL)
|
||||
ch[0] = '\0';
|
||||
/* Look backwards for the last two dirs = origin */
|
||||
while (ch != NULL && *--ch != '/')
|
||||
if (ch[0] == '\0')
|
||||
ch = NULL;
|
||||
while (ch != NULL && *--ch != '/')
|
||||
if (ch[0] == '\0')
|
||||
ch = NULL;
|
||||
if (ch == NULL)
|
||||
errx(2, "The INDEX does not appear to be valid!");
|
||||
if ((ie = malloc(sizeof(struct index_entry))) == NULL)
|
||||
errx(2, "Unable to allocate memory in %s.", __func__);
|
||||
strlcpy(ie->name, tmp, PATH_MAX);
|
||||
strlcpy(ie->origin, &ch[1], PATH_MAX);
|
||||
/* Who really cares if we reverse the index... */
|
||||
SLIST_INSERT_HEAD(&Index, ie, next);
|
||||
}
|
||||
}
|
||||
/* Now that we've slurped in the INDEX... */
|
||||
SLIST_FOREACH(ie, &Index, next) {
|
||||
if (plist.origin != NULL) {
|
||||
if (strcmp(plist.origin, ie->origin) == 0)
|
||||
latest = strdup(ie->name);
|
||||
} else {
|
||||
strlcpy(tmp, ie->name, PATH_MAX);
|
||||
strlcpy(tmp2, plist.name, PATH_MAX);
|
||||
/* Chop off the versions and compare. */
|
||||
if ((ch = strrchr(tmp, '-')) == NULL)
|
||||
errx(2, "The INDEX does not appear to be valid!");
|
||||
ch[0] = '\0';
|
||||
if ((ch = strrchr(tmp2, '-')) == NULL)
|
||||
warnx("%s is not a valid package!", plist.name);
|
||||
else
|
||||
ch[0] = '\0';
|
||||
if (strcmp(tmp2, tmp) == 0) {
|
||||
if (latest != NULL) {
|
||||
/* Multiple matches */
|
||||
snprintf(tmp, PATH_MAX, "%s|%s", latest, ie->name);
|
||||
free(latest);
|
||||
latest = strdup(tmp);
|
||||
} else
|
||||
latest = strdup(ie->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (latest == NULL)
|
||||
show_version(plist.name, NULL, plist.origin);
|
||||
else
|
||||
show_version(plist.name, latest, "index");
|
||||
}
|
||||
if (latest != NULL)
|
||||
free(latest);
|
||||
free_plist(&plist);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define OUTPUT(c) ((PreventChars != NULL && !strchr(PreventChars, (c))) || \
|
||||
(LimitChars != NULL && strchr(LimitChars, (c))) || \
|
||||
(PreventChars == NULL && LimitChars == NULL))
|
||||
|
||||
/*
|
||||
* Do the work of comparing and outputing. Ugly, but well that's what
|
||||
* You get when you try to match perl output in C ;-).
|
||||
*/
|
||||
void
|
||||
show_version(const char *installed, const char *latest, const char *source)
|
||||
{
|
||||
char *ch, tmp[PATH_MAX];
|
||||
const char *ver;
|
||||
int cmp = 0;
|
||||
|
||||
if (!installed || strlen(installed) == 0)
|
||||
return;
|
||||
strlcpy(tmp, installed, PATH_MAX);
|
||||
if (!Verbose) {
|
||||
if ((ch = strrchr(tmp, '-')) != NULL)
|
||||
ch[0] = '\0';
|
||||
}
|
||||
if (latest == NULL) {
|
||||
if (source == NULL && OUTPUT('!')) {
|
||||
printf("%-34s !", tmp);
|
||||
if (Verbose)
|
||||
printf(" Comparison failed");
|
||||
printf("\n");
|
||||
} else if (source != NULL && OUTPUT('?')) {
|
||||
printf("%-34s ?", tmp);
|
||||
if (Verbose)
|
||||
printf(" orphaned: %s", source);
|
||||
printf("\n");
|
||||
}
|
||||
} else if (strchr(latest,'|') != NULL) {
|
||||
if (OUTPUT('*')) {
|
||||
printf("%-34s *", tmp);
|
||||
if (Verbose) {
|
||||
strlcpy(tmp, latest, PATH_MAX);
|
||||
ch = strchr(tmp, '|');
|
||||
ch[0] = '\0';
|
||||
|
||||
ver = version_of(tmp, NULL, NULL);
|
||||
printf(" multiple versions (index has %s", ver);
|
||||
do {
|
||||
ver = version_of(&ch[1], NULL, NULL);
|
||||
if ((ch = strchr(&ch[1], '|')) != NULL)
|
||||
ch[0] = '\0';
|
||||
printf(", %s", ver);
|
||||
} while (ch != NULL);
|
||||
printf(")");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
} else {
|
||||
cmp = version_cmp(installed, latest);
|
||||
ver = version_of(latest, NULL, NULL);
|
||||
if (cmp < 0 && OUTPUT('<')) {
|
||||
printf("%-34s <", tmp);
|
||||
if (Verbose)
|
||||
printf(" needs updating (%s has %s)", source, ver);
|
||||
printf("\n");
|
||||
} else if (cmp == 0 && OUTPUT('=')) {
|
||||
printf("%-34s =", tmp);
|
||||
if (Verbose)
|
||||
printf(" up-to-date with %s", source);
|
||||
printf("\n");
|
||||
} else if (cmp > 0 && OUTPUT('>')) {
|
||||
printf("%-34s >", tmp);
|
||||
if (Verbose)
|
||||
printf(" succeeds %s (%s has %s)", source, source, ver);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cleanup(int sig)
|
||||
{
|
||||
if (sig)
|
||||
exit(1);
|
||||
}
|
@ -32,7 +32,7 @@
|
||||
.Nd summarize installed versions of packages
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl cdhv
|
||||
.Op Fl hv
|
||||
.Op Fl l Ar limchar
|
||||
.Op Fl L Ar limchar
|
||||
.Op Fl s Ar string
|
||||
@ -110,23 +110,6 @@ The
|
||||
.Nm
|
||||
utility supports several command-line arguments:
|
||||
.Bl -tag -width indent
|
||||
.It Fl c
|
||||
Enable commands output. Commands output includes the commands you should
|
||||
type to update your installed packages to the latest versions in the ports
|
||||
system.
|
||||
This feature does
|
||||
.Bf Em
|
||||
not
|
||||
.Ef
|
||||
constitute an automated packages updating system.
|
||||
The output of this command
|
||||
.Bf Em
|
||||
must
|
||||
.Ef
|
||||
be edited, in order to avoid destroying dependencies between installed
|
||||
packages.
|
||||
.It Fl d
|
||||
Enable debugging output.
|
||||
.It Fl h
|
||||
Print help message.
|
||||
.It Fl l
|
||||
@ -201,42 +184,19 @@ the version numbers in the on-line ports collection:
|
||||
.Pp
|
||||
.Dl % pkg_version ftp://ftp.FreeBSD.org/pub/FreeBSD/branches/-current/ports/INDEX
|
||||
.Pp
|
||||
The command below generates a file of commands to run to update the installed
|
||||
files.
|
||||
These commands must
|
||||
.Bf Em
|
||||
not
|
||||
.Ef
|
||||
be run without suitable editing.
|
||||
They should be treated as suggestions, and may need to be reordered
|
||||
to account for dependencies between installed packages, or may need to
|
||||
be disregarded if multiple versions of an installed package can coexist.
|
||||
Blindly running the output of this command may leave a system in an
|
||||
unusable state.
|
||||
.Pp
|
||||
.Dl % pkg_version -c > do_update
|
||||
.Pp
|
||||
The following command compares two package version strings:
|
||||
.Pp
|
||||
.Dl % pkg_version -t 1.5 1.5.1
|
||||
.Sh AUTHORS
|
||||
.An Bruce A. Mah Aq bmah@FreeBSD.org
|
||||
The
|
||||
.Nm
|
||||
utility was written by
|
||||
.An Jeremy D. Lea Aq reg@FreeBSD.org ,
|
||||
partially based on a Perl script written by
|
||||
.An Bruce A. Mah Aq bmah@FreeBSD.org .
|
||||
.Sh CONTRIBUTORS
|
||||
.An Nik Clayton Aq nik@FreeBSD.org ,
|
||||
.An Dominic Mitchell Aq dom@palmerharvey.co.uk ,
|
||||
.An Mark Ovens Aq marko@FreeBSD.org ,
|
||||
.An Doug Barton Aq DougB@gorean.org ,
|
||||
.An Akinori MUSHA Aq knu@FreeBSD.org
|
||||
.Sh BUGS
|
||||
The commands output feature is
|
||||
.Bf Em
|
||||
not
|
||||
.Ef
|
||||
an automated ports/packages updating system.
|
||||
It does not even attempt to handle dependencies between installed
|
||||
packages correctly, and can produce incorrect results if multiple
|
||||
versions of a package can coexist on a system.
|
||||
.Pp
|
||||
Commands output assumes you install new software using the ports system,
|
||||
rather than using
|
||||
.Xr pkg_add 1 .
|
||||
|
@ -1,623 +0,0 @@
|
||||
#! /usr/bin/perl
|
||||
#
|
||||
# Copyright 1998 Bruce A. Mah
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
|
||||
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# pkg_version.pl
|
||||
#
|
||||
# A package version-checking utility for FreeBSD.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
use Cwd;
|
||||
use Getopt::Std;
|
||||
|
||||
#
|
||||
# Configuration global variables
|
||||
#
|
||||
$AllCurrentPackagesCommand = '/usr/sbin/pkg_info -aI';
|
||||
$SelectedCurrentPackagesCommand = '/usr/sbin/pkg_info -I';
|
||||
$CatProgram = "cat ";
|
||||
$FetchProgram = "fetch -o - ";
|
||||
$OriginCommand = '/usr/sbin/pkg_info -qo';
|
||||
$GetPkgNameCommand = 'make -V PKGNAME';
|
||||
|
||||
#$IndexFile = "ftp://ftp.freebsd.org/pub/FreeBSD/branches/-current/ports/INDEX";
|
||||
$PortsDirectory = $ENV{PORTSDIR} || '/usr/ports';
|
||||
$IndexFile = "$PortsDirectory/INDEX";
|
||||
$ShowCommandsFlag = 0;
|
||||
$DebugFlag = 0;
|
||||
$VerboseFlag = 0;
|
||||
$CommentChar = "#";
|
||||
$LimitFlag = "";
|
||||
$PreventFlag = "";
|
||||
|
||||
#
|
||||
# CompareNumbers
|
||||
#
|
||||
# Try to figure out the relationship between two program version numbers.
|
||||
# Detecting equality is easy, but determining order is a little difficult.
|
||||
# This function returns -1, 0, or 1, in the same manner as <=> or cmp.
|
||||
#
|
||||
sub CompareNumbers {
|
||||
my ($v1, $v2) = @_;
|
||||
|
||||
# Short-cut in case of equality
|
||||
if ($v1 eq $v2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Loop over different components (the parts separated by dots).
|
||||
# If any component differs, we have the basis for an inequality.
|
||||
my @s1 = split(/\./, $v1);
|
||||
my @s2 = split(/\./, $v2);
|
||||
my ($c1, $c2);
|
||||
do {
|
||||
last unless @s1 || @s2;
|
||||
$c1 = shift @s1;
|
||||
$c2 = shift @s2;
|
||||
} while ($c1 eq $c2);
|
||||
|
||||
# Look at the first components of the arrays that are left.
|
||||
# These will determine the result of the comparison.
|
||||
# Note that if either version doesn't have any components left,
|
||||
# it's implicitly treated as a "0".
|
||||
|
||||
# Our next set of checks looks to see if either component has a
|
||||
# leading letter (there should be at most one leading letter per
|
||||
# component, so that "4.0b1" is allowed, but "4.0beta1" is not).
|
||||
if ($c1 =~ /^\D/) {
|
||||
if ($c2 =~ /^\D/) {
|
||||
|
||||
# Both have a leading letter, so do an alpha comparison
|
||||
# on the letters. This isn't ideal, since we're assuming
|
||||
# that "1.0.b4" > "1.0.a2". But it's about the best we can do,
|
||||
# without encoding some explicit policy.
|
||||
my ($letter1, $letter2);
|
||||
$letter1 = substr($c1, 0, 1);
|
||||
$letter2 = substr($c2, 0, 1);
|
||||
|
||||
if ($letter1 ne $letter2) {
|
||||
return $letter1 cmp $letter2;
|
||||
}
|
||||
else {
|
||||
# The letters matched equally. Delete the leading
|
||||
# letters and invoke ourselves on the remainining
|
||||
# characters, which according to the Porters Handbook
|
||||
# must be digits, so for example, "1.0.a9" < "1.0.a10".
|
||||
substr($c1, 0, 1) = "";
|
||||
substr($c2, 0, 1) = "";
|
||||
return &CompareNumbers($c1, $c2);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
# $c1 begins with a letter, but $c2 doesn't. Let $c2
|
||||
# win the comparison, so that "1.0.b1" < "1.0.1".
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($c2 =~ /^\D/) {
|
||||
# $c2 begins with a letter but $c1 doesn't. Let $c1
|
||||
# win the comparison, as above.
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
# Neither component begins with a leading letter.
|
||||
# See if either component has no characters left. If so,
|
||||
# let the other component win.
|
||||
if ($c1 eq "") {
|
||||
return -1;
|
||||
}
|
||||
if ($c2 eq "") {
|
||||
return 1;
|
||||
}
|
||||
|
||||
# Check for numeric inequality. We assume here that (for example)
|
||||
# "3.09" < "3.10", and that we aren't going to be asked to
|
||||
# decide between "3.010" and "3.10".
|
||||
if ($c1 != $c2) {
|
||||
return $c1 <=> $c2;
|
||||
}
|
||||
|
||||
# String comparison, given numeric equality. This
|
||||
# handles comparisons of the form "3.4j" < "3.4k". This form
|
||||
# technically isn't allowed by the Porter's Handbook, but a
|
||||
# number of ports in the FreeBSD Ports Collection as of this
|
||||
# writing use it (graphics/jpeg and graphics/xv). So we need
|
||||
# to support it.
|
||||
#
|
||||
# What we actually do is to strip off the leading digits and
|
||||
# invoke ourselves on the remainder. This allows us to handle
|
||||
# comparisons of the form "1.1p1" < "1.1p2". Again, not
|
||||
# technically allowed by the Porters Handbook, but lots of ports
|
||||
# use it.
|
||||
else {
|
||||
$c1 =~ s/\d+//;
|
||||
$c2 =~ s/\d+//;
|
||||
if ($c1 eq $c2) {
|
||||
return 0;
|
||||
}
|
||||
elsif ($c1 eq "") {
|
||||
return -1;
|
||||
}
|
||||
elsif ($c2 eq "") {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return &CompareNumbers($c1, $c2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# CompareVersions
|
||||
#
|
||||
# Try to figure out the relationship between two program "full
|
||||
# versions", which is defined as the
|
||||
# ${PORTVERSION}[_${PORTREVISION}][,${PORTEPOCH}]
|
||||
# part of a package's name.
|
||||
#
|
||||
# Key points: ${PORTEPOCH} supercedes ${PORTVERSION}
|
||||
# supercedes ${PORTREVISION}. See the commit log for revision
|
||||
# 1.349 of ports/Mk/bsd.port.mk for more information.
|
||||
#
|
||||
sub CompareVersions {
|
||||
local($fv1, $fv2, $v1, $v2, $r1, $r2, $e1, $e2, $rc);
|
||||
|
||||
$fv1 = $_[0];
|
||||
$fv2 = $_[1];
|
||||
|
||||
# Shortcut check for equality before invoking the parsing
|
||||
# routines.
|
||||
if ($fv1 eq $fv2) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
($v1, $r1, $e1) = &GetVersionComponents($fv1);
|
||||
($v2, $r2, $e2) = &GetVersionComponents($fv2);
|
||||
|
||||
# Port revision and port epoch numbers default to zero if not
|
||||
# specified.
|
||||
if ($r1 eq "") {
|
||||
$r1 = "0";
|
||||
}
|
||||
if ($r2 eq "") {
|
||||
$r2 = "0";
|
||||
}
|
||||
if ($e1 eq "") {
|
||||
$e1 = "0";
|
||||
}
|
||||
if ($e2 eq "") {
|
||||
$e2 = "0";
|
||||
}
|
||||
|
||||
# Check epoch, port version, and port revision, in that
|
||||
# order.
|
||||
$rc = &CompareNumbers($e1, $e2);
|
||||
if ($rc == 0) {
|
||||
$rc = &CompareNumbers($v1, $v2);
|
||||
if ($rc == 0) {
|
||||
$rc = &CompareNumbers($r1, $r2);
|
||||
}
|
||||
}
|
||||
|
||||
return $rc;
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# GetVersionComponents
|
||||
#
|
||||
# Parse out the version number, revision number, and epoch number
|
||||
# of a port's version string and return them as a three-element array.
|
||||
#
|
||||
# Syntax is: ${PORTVERSION}[_${PORTREVISION}][,${PORTEPOCH}]
|
||||
#
|
||||
sub GetVersionComponents {
|
||||
local ($fullversion, $version, $revision, $epoch);
|
||||
|
||||
$fullversion = $_[0];
|
||||
|
||||
$fullversion =~ /([^_,]+)/;
|
||||
$version = $1;
|
||||
|
||||
if ($fullversion =~ /_([^_,]+)/) {
|
||||
$revision = $1;
|
||||
}
|
||||
|
||||
if ($fullversion =~ /,([^_,]+)/) {
|
||||
$epoch = $1;
|
||||
}
|
||||
|
||||
return($version, $revision, $epoch);
|
||||
}
|
||||
|
||||
#
|
||||
# GetNameAndVersion
|
||||
#
|
||||
# Get the name and version number of a package. Returns a two element
|
||||
# array, first element is name, second element is full version string.,
|
||||
#
|
||||
sub GetNameAndVersion {
|
||||
local($fullname, $name, $fullversion);
|
||||
$fullname = $_[0];
|
||||
|
||||
# If no hyphens then no version numbers
|
||||
return ($fullname, "", "", "", "") if $fullname !~ /-/;
|
||||
|
||||
# Match (and group) everything after hyphen(s). Because the
|
||||
# regexp is 'greedy', the first .* will try and match everything up
|
||||
# to (but not including) the last hyphen
|
||||
$fullname =~ /(.+)-(.+)/;
|
||||
$name = $1;
|
||||
$fullversion = $2;
|
||||
|
||||
return ($name, $fullversion);
|
||||
}
|
||||
|
||||
#
|
||||
# PrintHelp
|
||||
#
|
||||
# Print usage information
|
||||
#
|
||||
sub PrintHelp {
|
||||
print <<"EOF"
|
||||
Usage: pkg_version [-c] [-d] [-h] [-l limchar] [-L limchar] [-s string]
|
||||
[-v] [index]
|
||||
pkg_version [-d debug] -t v1 v2
|
||||
-c Show commands to update installed packages
|
||||
-d Enable debugging output
|
||||
-h Help (this message)
|
||||
-l limchar Limit output to status flags that match
|
||||
-L limchar Limit output to status flags that DON\'T match
|
||||
-s string Limit output to packages matching a string
|
||||
-v Verbose output
|
||||
index URL or filename of index file
|
||||
(Default is $IndexFile)
|
||||
|
||||
-t v1 v2 Test two version strings
|
||||
EOF
|
||||
}
|
||||
|
||||
#
|
||||
# Parse command-line arguments, deal with them
|
||||
#
|
||||
if (!getopts('cdhl:L:s:tv') || ($opt_h)) {
|
||||
&PrintHelp();
|
||||
exit;
|
||||
}
|
||||
if ($opt_c) {
|
||||
$ShowCommandsFlag = $opt_c;
|
||||
$LimitFlag = "<?"; # note that if the user specifies -l, we
|
||||
# deal with this *after* setting a default
|
||||
# for $LimitFlag
|
||||
}
|
||||
if ($opt_d) {
|
||||
$DebugFlag = $opt_d;
|
||||
}
|
||||
if ($opt_l) {
|
||||
$LimitFlag = $opt_l;
|
||||
}
|
||||
if ($opt_L) {
|
||||
$PreventFlag = $opt_L;
|
||||
}
|
||||
if ($opt_t) {
|
||||
$TestFlag = 1;
|
||||
}
|
||||
if ($opt_s) {
|
||||
$StringFlag = $opt_s;
|
||||
}
|
||||
if ($opt_v) {
|
||||
$VerboseFlag = 1;
|
||||
}
|
||||
if ($#ARGV >= 0) {
|
||||
if ($TestFlag) {
|
||||
($test1, $test2) = @ARGV;
|
||||
}
|
||||
else {
|
||||
$IndexFile = $ARGV[0];
|
||||
}
|
||||
}
|
||||
|
||||
# Handle test flag now
|
||||
if ($TestFlag) {
|
||||
my $cmp = CompareVersions($test1, $test2);
|
||||
if ($cmp < 0) {
|
||||
print "<\n";
|
||||
}
|
||||
elsif ($cmp == 0) {
|
||||
print "=\n";
|
||||
}
|
||||
else {
|
||||
print ">\n";
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
# Determine what command to use to retrieve the index file.
|
||||
if ($IndexFile =~ m-^((http|ftp)://|file:/)-) {
|
||||
$IndexPackagesCommand = $FetchProgram . $IndexFile;
|
||||
}
|
||||
else {
|
||||
$IndexPackagesCommand = $CatProgram . $IndexFile;
|
||||
}
|
||||
|
||||
#
|
||||
# Get the current list of installed packages
|
||||
#
|
||||
if ($StringFlag) {
|
||||
if ($DebugFlag) {
|
||||
print STDERR "$SelectedCurrentPackagesCommand *$StringFlag*\n";
|
||||
}
|
||||
open CURRENT, "$SelectedCurrentPackagesCommand \\*$StringFlag\\*|";
|
||||
} else {
|
||||
if ($DebugFlag) {
|
||||
print STDERR "$AllCurrentPackagesCommand\n";
|
||||
}
|
||||
open CURRENT, "$AllCurrentPackagesCommand|";
|
||||
}
|
||||
while (<CURRENT>) {
|
||||
($packageString, $rest) = split;
|
||||
|
||||
($packageName, $packageFullversion) = &GetNameAndVersion($packageString);
|
||||
$currentPackages{$packageString}{'name'} = $packageName;
|
||||
$currentPackages{$packageString}{'fullversion'} = $packageFullversion;
|
||||
}
|
||||
close CURRENT;
|
||||
|
||||
#
|
||||
# Iterate over installed packages, get origin directory (if it
|
||||
# exists) and PORTVERSION
|
||||
#
|
||||
$dir = cwd();
|
||||
foreach $packageString (sort keys %currentPackages) {
|
||||
|
||||
open ORIGIN, "$OriginCommand $packageString|";
|
||||
$origin = <ORIGIN>;
|
||||
close ORIGIN;
|
||||
|
||||
# If there is an origin variable for this package, then store it.
|
||||
if ($origin ne "") {
|
||||
chomp $origin;
|
||||
|
||||
# Try to get the version out of the makefile.
|
||||
# The chdir needs to be successful or our make -V invocation
|
||||
# will fail.
|
||||
unless (chdir "$PortsDirectory/$origin" and -r "Makefile") {
|
||||
$currentPackages{$packageString}->{orphaned} = $origin;
|
||||
next;
|
||||
}
|
||||
|
||||
open PKGNAME, "$GetPkgNameCommand|";
|
||||
$pkgname = <PKGNAME>;
|
||||
close PKGNAME;
|
||||
|
||||
if ($pkgname ne "") {
|
||||
chomp $pkgname;
|
||||
|
||||
$pkgname =~ /(.+)-(.+)/;
|
||||
$portversion = $2;
|
||||
|
||||
$currentPackages{$packageString}{'origin'} = $origin;
|
||||
$currentPackages{$packageString}{'portversion'} = $portversion;
|
||||
}
|
||||
}
|
||||
}
|
||||
chdir "$dir";
|
||||
|
||||
#
|
||||
# Slurp in the index file
|
||||
#
|
||||
if ($DebugFlag) {
|
||||
print STDERR "$IndexPackagesCommand\n";
|
||||
}
|
||||
|
||||
open INDEX, "$IndexPackagesCommand|";
|
||||
while (<INDEX>) {
|
||||
($packageString, $packagePath, $rest) = split(/\|/);
|
||||
|
||||
($packageName, $packageFullversion) = &GetNameAndVersion($packageString);
|
||||
$indexPackages{$packageName}{'name'} = $packageName;
|
||||
$indexPackages{$packageName}{'path'} = $packagePath;
|
||||
if (defined $indexPackages{$packageName}{'fullversion'}) {
|
||||
$indexPackages{$packageName}{'fullversion'} .= "|" . $packageFullversion;
|
||||
}
|
||||
else {
|
||||
$indexPackages{$packageName}{'fullversion'} = $packageFullversion;
|
||||
}
|
||||
$indexPackages{$packageName}{'refcount'}++;
|
||||
}
|
||||
close INDEX;
|
||||
|
||||
#
|
||||
# If we're doing commands output, cripple the output so that users
|
||||
# can't just pipe the output to sh(1) and expect this to work.
|
||||
#
|
||||
if ($ShowCommandsFlag) {
|
||||
print<<EOF
|
||||
echo "The commands output of pkg_version cannot be executed without editing."
|
||||
echo "You MUST save this output to a file and then edit it, taking into"
|
||||
echo "account package dependencies and the fact that some packages cannot"
|
||||
echo "or should not be upgraded."
|
||||
exit 1
|
||||
EOF
|
||||
}
|
||||
|
||||
#
|
||||
# Produce reports
|
||||
#
|
||||
# Prior versions of pkg_version used commas (",") as delimiters
|
||||
# when there were multiple versions of a package installed.
|
||||
# The new package version number syntax uses commas as well,
|
||||
# so we've used vertical bars ("|") internally, and convert them
|
||||
# to commas before we output anything so the reports look the
|
||||
# same as they did before.
|
||||
#
|
||||
foreach $packageString (sort keys %currentPackages) {
|
||||
$~ = "STDOUT_VERBOSE" if $VerboseFlag;
|
||||
$~ = "STDOUT_COMMANDS" if $ShowCommandsFlag;
|
||||
|
||||
$packageNameVer = $packageString;
|
||||
$packageName = $currentPackages{$packageString}{'name'};
|
||||
|
||||
$currentVersion = $currentPackages{$packageString}{'fullversion'};
|
||||
|
||||
if ($currentPackages{$packageString}->{orphaned}) {
|
||||
|
||||
next if $ShowCommandsFlag;
|
||||
$versionCode = "?";
|
||||
$Comment = "orphaned: $currentPackages{$packageString}->{orphaned}";
|
||||
|
||||
} elsif (defined $currentPackages{$packageString}{'portversion'}) {
|
||||
|
||||
$portVersion = $currentPackages{$packageString}{'portversion'};
|
||||
|
||||
$portPath = "$PortsDirectory/$currentPackages{$packageString}{'origin'}";
|
||||
|
||||
# Do the comparison
|
||||
$rc = &CompareVersions($currentVersion, $portVersion);
|
||||
|
||||
if ($rc == 0) {
|
||||
$versionCode = "=";
|
||||
$Comment = "up-to-date with port";
|
||||
}
|
||||
elsif ($rc < 0) {
|
||||
$versionCode = "<";
|
||||
$Comment = "needs updating (port has $portVersion)";
|
||||
}
|
||||
elsif ($rc > 0) {
|
||||
$versionCode = ">";
|
||||
$Comment = "succeeds port (port has $portVersion)";
|
||||
}
|
||||
else {
|
||||
$versionCode = "!";
|
||||
$Comment = "Comparison failed";
|
||||
}
|
||||
}
|
||||
|
||||
elsif (defined $indexPackages{$packageName}{'fullversion'}) {
|
||||
|
||||
$indexVersion = $indexPackages{$packageName}{'fullversion'};
|
||||
$indexRefcount = $indexPackages{$packageName}{'refcount'};
|
||||
|
||||
$portPath = $indexPackages{$packageName}{'path'};
|
||||
|
||||
if ($indexRefcount > 1) {
|
||||
$versionCode = "*";
|
||||
$Comment = "multiple versions (index has $indexVersion)";
|
||||
$Comment =~ s/\|/,/g;
|
||||
}
|
||||
else {
|
||||
|
||||
# Do the comparison
|
||||
$rc =
|
||||
&CompareVersions($currentVersion, $indexVersion);
|
||||
|
||||
if ($rc == 0) {
|
||||
$versionCode = "=";
|
||||
$Comment = "up-to-date with index";
|
||||
}
|
||||
elsif ($rc < 0) {
|
||||
$versionCode = "<";
|
||||
$Comment = "needs updating (index has $indexVersion)"
|
||||
}
|
||||
elsif ($rc > 0) {
|
||||
$versionCode = ">";
|
||||
$Comment = "succeeds index (index has $indexVersion)";
|
||||
}
|
||||
else {
|
||||
$versionCode = "!";
|
||||
$Comment = "Comparison failed";
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
next if $ShowCommandsFlag;
|
||||
$versionCode = "?";
|
||||
$Comment = "unknown in index";
|
||||
}
|
||||
|
||||
# Having figured out what to print, now determine, based on the
|
||||
# $LimitFlag and $PreventFlag variables, if we should print or not.
|
||||
if ((not $LimitFlag) and (not $PreventFlag)) {
|
||||
write;
|
||||
} elsif ($PreventFlag) {
|
||||
if ($versionCode !~ m/[$PreventFlag]/o) {
|
||||
if (not $LimitFlag) {
|
||||
write;
|
||||
} else {
|
||||
write if $versionCode =~ m/[$LimitFlag]/o;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
# Must mean that there is a LimitFlag
|
||||
write if $versionCode =~ m/[$LimitFlag]/o;
|
||||
}
|
||||
}
|
||||
|
||||
exit 0;
|
||||
|
||||
#
|
||||
# Formats
|
||||
#
|
||||
# $CommentChar is in the formats because you can't put a literal '#' in
|
||||
# a format specification
|
||||
|
||||
# General report (no output flags)
|
||||
format STDOUT =
|
||||
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<
|
||||
$packageName, $versionCode
|
||||
.
|
||||
;
|
||||
|
||||
# Verbose report (-v flag)
|
||||
format STDOUT_VERBOSE =
|
||||
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
$packageNameVer, $versionCode, $Comment
|
||||
.
|
||||
;
|
||||
|
||||
# Report that includes commands to update program (-c flag)
|
||||
format STDOUT_COMMANDS =
|
||||
@<
|
||||
$CommentChar
|
||||
@< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
$CommentChar, $packageName
|
||||
@< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
$CommentChar, $Comment
|
||||
@<
|
||||
$CommentChar
|
||||
cd @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
$portPath
|
||||
make clean && make && pkg_delete -f @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
$packageNameVer
|
||||
make install clean
|
||||
|
||||
.
|
||||
;
|
@ -33,7 +33,7 @@
|
||||
#
|
||||
|
||||
ECHO=echo
|
||||
PKG_VERSION=./pkg_version.pl
|
||||
PKG_VERSION=./pkg_version
|
||||
|
||||
test-pv ( ) { \
|
||||
setvar v1 $1
|
||||
|
44
usr.sbin/pkg_install/version/version.h
Normal file
44
usr.sbin/pkg_install/version/version.h
Normal file
@ -0,0 +1,44 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Jeremy D. Lea.
|
||||
* 11 May 2002
|
||||
*
|
||||
* This is the version module. Based on pkg_version.pl by Bruce A. Mah.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _INST_VERSION_H_INCLUDE
|
||||
#define _INST_VERSION_H_INCLUDE
|
||||
|
||||
/* Where the ports lives by default */
|
||||
#define DEF_PORTS_DIR "/usr/ports"
|
||||
/* just in case we change the environment variable name */
|
||||
#define PORTSDIR "PORTSDIR"
|
||||
/* macro to get name of directory where we put logging information */
|
||||
#define PORTS_DIR (getenv(PORTSDIR) ? getenv(PORTSDIR) : DEF_PORTS_DIR)
|
||||
|
||||
struct index_entry {
|
||||
SLIST_ENTRY(index_entry) next;
|
||||
char name[PATH_MAX];
|
||||
char origin[PATH_MAX];
|
||||
};
|
||||
SLIST_HEAD(index_head, index_entry);
|
||||
|
||||
extern char *LimitChars;
|
||||
extern char *PreventChars;
|
||||
extern char *MatchName;
|
||||
|
||||
#endif /* _INST_VERSION_H_INCLUDE */
|
Loading…
Reference in New Issue
Block a user