summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbrian <brian@cvs.openbsd.org>2001-05-21 16:47:52 +0000
committerbrian <brian@cvs.openbsd.org>2001-05-21 16:47:52 +0000
commitaad2a6c418139e1da3a58ef93fbbeae080c9e731 (patch)
treeedcf9ef0a91c5b4abc9d056a0885b5bdc0e82955
parenta5606b2fb03ff304f7d5fed756690e7cb8b579e7 (diff)
Add pkg_version from FreeBSD (modulo the PORT_REVISION stuff)
-rw-r--r--usr.sbin/pkg_install/Makefile4
-rw-r--r--usr.sbin/pkg_install/version/Makefile10
-rw-r--r--usr.sbin/pkg_install/version/pkg_version.1238
-rw-r--r--usr.sbin/pkg_install/version/pkg_version.pl516
4 files changed, 766 insertions, 2 deletions
diff --git a/usr.sbin/pkg_install/Makefile b/usr.sbin/pkg_install/Makefile
index f4b94ac24bb..14336491b2e 100644
--- a/usr.sbin/pkg_install/Makefile
+++ b/usr.sbin/pkg_install/Makefile
@@ -1,5 +1,5 @@
-# $OpenBSD: Makefile,v 1.4 1999/10/05 22:34:44 espie Exp $
+# $OpenBSD: Makefile,v 1.5 2001/05/21 16:47:50 brian Exp $
-SUBDIR=lib add create delete info
+SUBDIR=lib add create delete info version
.include <bsd.subdir.mk>
diff --git a/usr.sbin/pkg_install/version/Makefile b/usr.sbin/pkg_install/version/Makefile
new file mode 100644
index 00000000000..0d1bbbd8508
--- /dev/null
+++ b/usr.sbin/pkg_install/version/Makefile
@@ -0,0 +1,10 @@
+# $OpenBSD: Makefile,v 1.1 2001/05/21 16:47:51 brian Exp $
+
+NOPROG=
+MAN= pkg_version.1
+
+afterinstall:
+ ${INSTALL} ${INSTALL_COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
+ ${.CURDIR}/pkg_version.pl ${DESTDIR}${BINDIR}/pkg_version
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/pkg_install/version/pkg_version.1 b/usr.sbin/pkg_install/version/pkg_version.1
new file mode 100644
index 00000000000..4ebf7257add
--- /dev/null
+++ b/usr.sbin/pkg_install/version/pkg_version.1
@@ -0,0 +1,238 @@
+.\"
+.\" 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.
+.\"
+.\" $FreeBSD: src/usr.sbin/pkg_install/version/pkg_version.1,v 1.16 2001/04/04 11:19:09 ru Exp $
+.Dd July 17, 1998
+.Dt PKG_VERSION 1
+.Os FreeBSD
+.Sh NAME
+.Nm pkg_version
+.Nd summarize installed versions of packages
+.Sh SYNOPSIS
+.Nm
+.Op Fl cdhv
+.Op Fl l Ar limchar
+.Op Fl L Ar limchar
+.Op Ar index
+.Nm
+.Op Fl t Ar version1 version2
+.Sh DESCRIPTION
+The
+.Nm
+command is used to produce a report of non-base software packages
+installed using the
+.Xr pkg_add 1
+command.
+.Pp
+Each package's version number is checked against one of two sources to
+see if that package may require updating. If the package contains
+information about its origin in the
+.Fx
+ports tree, and a version number can be determined from the port's
+.Pa Makefile ,
+then the version number from the
+.Pa Makefile
+will be used to determine whether the installed package is up-to-date
+or requires updating.
+.Pp
+If no origin for a package can be found, or if the port's
+.Pa Makefile
+cannot be located,
+.Nm
+will search for the package in the ports collection index file
+(typically
+.Pa /usr/ports/INDEX ) .
+Any matching version number(s) there will be used to determine whether
+the installed package is up-to-date or requires updating.
+.Pp
+Generally, using the version number from a port's
+.Pa Makefile
+will provide a more accurate result, since, unlike the index file, it
+provides an unambiguous current version number, even when multiple
+versions of a port exist in the ports collection.
+Moreover, the ports collection index file is only updated at
+intervals, meaning that it may not completely reflect the version
+numbers of the software contained in the ports collection.
+.Pp
+Each package name is printed, along with a one-character status flag:
+.Bl -tag -width indent
+.It Li =
+The installed version of the package is current.
+.It Li \&<
+The installed version of the package is older than the current version.
+.It Li \&>
+The installed version of the package is newer than the current version.
+This situation can arise with an out-of-date index file, or when
+testing new ports.
+.It Li \&?
+The installed package does not appear in the index.
+This could be due to an out of date index or a package taken from a PR
+that has not yet been committed.
+.It Li *
+There are multiple versions of a particular software package
+listed in the index file.
+Examples from the
+.Fx
+ports collection are the Tcl toolkit or the
+.Tn EMACS
+editor.
+.It Li \&!
+The installed package exists in the index but for some reason,
+.Nm
+was unable to compare the version number of the installed package
+with the corresponding entry in the index.
+.El
+.Sh OPTIONS
+.Nm
+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
+Limit the output to those packages whose status flag matches the
+character(s) in
+.Ar limchar .
+More than one character can be specified in
+.Ar limchar .
+Note that because some of the status flag characters are also special
+to the shell, it is best to quote
+.Ar limchar
+with single quotes.
+.It Fl L
+Limit the output to those packages whose status flag doesn't match
+.Ar limchar .
+You may specify more than one character to match in
+.Ar limchar .
+Note that because some of the status flag characters are also special
+to the shell, it is best to quote
+.Ar limchar
+with single quotes.
+.It Fl t
+Test a pair of version number strings and exit.
+The output consists of one of the single characters
+.Li =
+(equal),
+.Li \&<
+(right-hand number greater), or
+.Li \&>
+(left-hand number greater) on standard output.
+This flag is mostly useful for scripts or for testing.
+.It Fl v
+Enable verbose output. Verbose output includes some English-text
+interpretations of the version number comparisons, as well as the
+version numbers compared for each package. Non-verbose output is
+probably easier for programs or scripts to parse.
+.It Ar index
+Specify the index to be used as a basis of comparison. This index can
+be specified as a filename (in the local filesystem) or a URL. Any
+URL understandable by
+.Xr fetch 1
+can be used here. If no
+.Ar index
+file is specified on the command line,
+.Pa /usr/ports/INDEX
+is used.
+.El
+.Sh SEE ALSO
+.Xr fetch 1 ,
+.Xr pkg_add 1 ,
+.Xr pkg_create 1 ,
+.Xr pkg_delete 1 ,
+.Xr pkg_info 1
+.Sh FILES
+.Bl -tag -width /usr/ports/INDEX -compact
+.It Pa /usr/ports/INDEX
+Default index file.
+.El
+.Sh EXAMPLES
+The following is a typical invocation of the
+.Nm
+command, which checks the installed packages against the local ports
+index file:
+.Pp
+.Dl % pkg_version -v
+.Pp
+The command below generates a report against
+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
+.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
+.Pp
+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 .
diff --git a/usr.sbin/pkg_install/version/pkg_version.pl b/usr.sbin/pkg_install/version/pkg_version.pl
new file mode 100644
index 00000000000..41e046a2252
--- /dev/null
+++ b/usr.sbin/pkg_install/version/pkg_version.pl
@@ -0,0 +1,516 @@
+#! /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: src/usr.sbin/pkg_install/version/pkg_version.pl,v 1.20 2001/05/15 18:37:23 bmah Exp $
+#
+
+use Cwd;
+use Getopt::Std;
+
+#
+# Configuration global variables
+#
+$CurrentPackagesCommand = '/usr/sbin/pkg_info -aI';
+$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 = '/usr/ports';
+$IndexFile = '/usr/ports/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.
+ # 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);
+
+ # 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 debug] [-h] [-l limchar] [-L limchar] [-v] [index]
+ pkg_version [-d debug] -t v1 v2
+-c Show commands to update installed packages
+-d debug Debugging output (debug controls level of 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
+-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: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_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 ($DebugFlag) {
+ print STDERR "$CurrentPackagesCommand\n";
+}
+
+open CURRENT, "$CurrentPackagesCommand|";
+while (<CURRENT>) {
+ ($packageString, $rest) = split;
+
+ ($packageName, $packageFullversion) = &GetNameAndVersion($packageString);
+ $currentPackages{$packageString}{'name'} = $packageName;
+ $currentPackages{$packageString}{'fullversion'} = $packageFullversion;
+}
+close CURRENT;
+
+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 (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
+
+.
+ ;