From 33b668b529841d2407b239a299b7fb227797af3a Mon Sep 17 00:00:00 2001 From: Bill Fumerola Date: Fri, 26 Nov 1999 20:31:58 +0000 Subject: [PATCH] Welcome pkg_version into the FreeBSD source tree. pkg_version (as you may well know) matches the existing packages/ports installed on your system with the ports INDEX and reports which ports differ from the current INDEX. Submitted by: Bruce A. Mah Reviewed by: ports --- usr.sbin/pkg_install/Makefile | 4 +- usr.sbin/pkg_install/version/Makefile | 10 + usr.sbin/pkg_install/version/pkg_version.1 | 149 ++++++++++ usr.sbin/pkg_install/version/pkg_version.pl | 304 ++++++++++++++++++++ 4 files changed, 466 insertions(+), 1 deletion(-) create mode 100644 usr.sbin/pkg_install/version/Makefile create mode 100644 usr.sbin/pkg_install/version/pkg_version.1 create mode 100755 usr.sbin/pkg_install/version/pkg_version.pl diff --git a/usr.sbin/pkg_install/Makefile b/usr.sbin/pkg_install/Makefile index 37a1f05783a..5ee77481af8 100644 --- a/usr.sbin/pkg_install/Makefile +++ b/usr.sbin/pkg_install/Makefile @@ -1,3 +1,5 @@ -SUBDIR=lib add create delete info +# $FreeBSD$ + +SUBDIR=lib add create delete info version .include diff --git a/usr.sbin/pkg_install/version/Makefile b/usr.sbin/pkg_install/version/Makefile new file mode 100644 index 00000000000..888a4fbfc06 --- /dev/null +++ b/usr.sbin/pkg_install/version/Makefile @@ -0,0 +1,10 @@ +# $FreeBSD$ + +MAINTAINER= billf@FreeBSD.org +MAN8= pkg_version.1 + +beforeinstall: + ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \ + ${.CURDIR}/pkg_version.pl ${DESTDIR}${BINDIR}/pkg_version + +.include 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..9007b8b2b20 --- /dev/null +++ b/usr.sbin/pkg_install/version/pkg_version.1 @@ -0,0 +1,149 @@ +.\" +.\" 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$ +.Dd July 17, 1998 +.Dt PKG_VERSION 1 +.Os FreeBSD +.Sh NAME +.Nm pkg_version +.Nd summarize installed versions of packages +.Sh SYNOPSIS +.Nm pkg_version +.Op Fl cdhv +.Op Ar index +.Sh DESCRIPTION +The +.Nm +command is used to produce a report of non-base software packages +installed using the +.Xr pkg_add 1 +command. Version numbers are compared against an +index file, to see which packages might need updating. +.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 matches the index. +.It Li < +The installed version of the package is older than the version listed +in the index. +.It Li > +The installed version of the package is newer than listed in the +index. +.It Li ? +The relationship between the installed version of a package and the +index file could not be determined. A common reason for this message +is that there are multiple versions of a particular software package +installed, or that multiple versions are listed in the index file. +Examples from the +.Fx 2.2.6 +ports collection are the Tcl toolkit or the +.Tn EMACS +editor. +.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. +.It Fl d +Enable debugging output. +.It Fl h +Print help message. +.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 . +.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/ports-current/INDEX +.Pp +The command below generates a file of commands to run to update the installed +files. It is +.Bf Em +not +.Ef +suggested that you run these commands automatically. Always review the +suggestions, and then cut-and-paste (or retype) the commands you want to run. +.Pp +.Dl % pkg_version -c > do_update +.Sh AUTHOR +.An Bruce A. Mah Aq bmah@ca.sandia.gov +.Sh CONTRIBUTORS +.An Nik Clayton Aq nik@freebsd.org +.Sh BUGS +There should be a better way of dealing with packages that +can have more than one installed version. +.Pp +Patch levels aren't handled +very well (i.e. version numbers of the form 1.2p3 or 1.2pl3). +.Pp +Updates to packages +that don't change the version number (e.g. small delta bugfixes in the +package/port itself) aren't detected. +.Pp +Commands output doesn't know about dependencies between packages. For +example, you might have two versions of Tcl installed because two other +packages require the different versions. +.Nm +will suggest removing the out-of-date version. +.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 100755 index 00000000000..b1079f63be4 --- /dev/null +++ b/usr.sbin/pkg_install/version/pkg_version.pl @@ -0,0 +1,304 @@ +#! /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 Getopt::Std; + +# +# Configuration global variables +# +$Version = '0.1'; +$CurrentPackagesCommand = '/usr/sbin/pkg_info -aI'; +$CatProgram = "cat "; +$FetchProgram = "fetch -o - "; + +#$indexFile = "ftp://ftp.freebsd.org/pub/FreeBSD/ports-current/INDEX"; +$IndexFile = 'file:/usr/ports/INDEX'; +$ShowCommandsFlag = 0; +$DebugFlag = 0; +$VerboseFlag = 0; +$CommentChar = "#"; + +# +# CompareVersions +# +# 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 CompareVersions { + local($v1, $v2); + $v1 = $_[0]; + $v2 = $_[1]; + + # 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. + while (1) { + ($p1, $v1) = split(/\./, $v1, 2); + ($p2, $v2) = split(/\./, $v2, 2); + + # If we\'re out of components, they\'re equal (this probably won\'t + # happen, since the short-cut case above should get this). + if (($p1 eq "") && ($p2 eq "")) { + return 0; + } + # Check for numeric inequality. We assume here that (for example) + # 3.09 < 3.10. + elsif ($p1 != $p2) { + return $p1 <=> $p2; + } + # Check for string inequality, given numeric equality. This + # handles version numbers of the form 3.4j < 3.4k. + elsif ($p1 ne $p2) { + return $p1 cmp $p2; + } + } + +} + +# +# GetNameAndVersion +# +# Get the name and version number of a package. Returns a two element +# array, first element is name, second element is version number. +# +sub GetNameAndVersion { + local($string); + $string = $_[0]; + + # If no hyphens then no version number + return ($string, "") if $string !~ /-/; + + # Match (and group) everything in between two hyphens. Because the + # regexp is 'greedy', the first .* will try and match everything up + # to (but not including) the last hyphen + $string =~ /(.*)-(.*)/; + return ($1, $2); +} + +# +# PrintHelp +# +# Print usage information +# +sub PrintHelp { + print <<"EOF" +pkg_version $Version +Bruce A. Mah + +Usage: pkg_version [-c] [-d debug] [-h] [-v] [index] +-c Show commands to update installed packages +-d debug Debugging output (debug controls level of output) +-h Help (this message) +-v Verbose output +index URL or filename of index file + (Default is $IndexFile) +EOF +} + +# +# Parse command-line arguments, deal with them +# +if (!getopts('cdhv') || ($opt_h)) { + &PrintHelp(); + exit; +} +if ($opt_c) { + $ShowCommandsFlag = $opt_c; +} +if ($opt_d) { + $DebugFlag = $opt_d; +} +if ($opt_v) { + $VerboseFlag = 1; +} +if ($#ARGV >= 0) { + $IndexFile = $ARGV[0]; +} + +# Gross hack to get around a bug in fetch(1). When PR bin/7203 gets fixed, +# we can make a lot of this code go away...basically the problem is that +# we can't depend on "fetch -o -" to do the right thing with files in the +# filesystem. +if ($IndexFile =~ s-^file:/-/-) { + $IndexPackagesCommand = $CatProgram . $IndexFile; +} +elsif ($IndexFile =~ m-^(http|ftp)://-) { + $IndexPackagesCommand = $FetchProgram . $IndexFile; +} +else { + $IndexPackagesCommand = $CatProgram . $IndexFile; +} + +# +# Slurp in files +# +if ($DebugFlag) { + print STDERR "$CurrentPackagesCommand\n"; +} + +open CURRENT, "$CurrentPackagesCommand|"; +while () { + ($packageString, $rest) = split; + ($packageName, $packageVersion) = &GetNameAndVersion($packageString); + $currentPackages{$packageName}{'name'} = $packageName; + if (defined $currentPackages{$packageName}{'version'}) { + $currentPackages{$packageName}{'version'} .= "," . $packageVersion; + } + else { + $currentPackages{$packageName}{'version'} = $packageVersion; + } + $currentPackages{$packageName}{'refcount'}++; +} +close CURRENT; + +if ($DebugFlag) { + print STDERR "$IndexPackagesCommand\n"; +} + +open INDEX, "$IndexPackagesCommand|"; +while () { + ($packageString, $packagePath, $rest) = split(/\|/); + ($packageName, $packageVersion) = &GetNameAndVersion($packageString); + $indexPackages{$packageName}{'name'} = $packageName; + $indexPackages{$packageName}{'path'} = $packagePath; + if (defined $indexPackages{$packageName}{'version'}) { + $indexPackages{$packageName}{'version'} .= "," . $packageVersion; + } + else { + $indexPackages{$packageName}{'version'} = $packageVersion; + } + $indexPackages{$packageName}{'refcount'}++; +} +close INDEX; + +# +# Produce reports +# +foreach $packageName (sort keys %currentPackages) { + $~ = "STDOUT_VERBOSE" if $VerboseFlag; + $~ = "STDOUT_COMMANDS" if $ShowCommandsFlag; + + $packageNameVer = "$packageName-$currentPackages{$packageName}{'version'}"; + + if (defined $indexPackages{$packageName}{'version'}) { + + $indexVersion = $indexPackages{$packageName}{'version'}; + $currentVersion = $currentPackages{$packageName}{'version'}; + + $indexRefcount = $indexPackages{$packageName}{'refcount'}; + $currentRefcount = $currentPackages{$packageName}{'refcount'}; + + $packagePath = $indexPackages{$packageName}{'path'}; + + if (($indexRefcount > 1) || ($currentRefcount > 1)) { + $versionCode = "?"; + $Comment = "multiple versions (index has $indexVersion)"; + } + else { + + $rc = &CompareVersions($currentVersion, $indexVersion); + + if ($rc == 0) { + next if $ShowCommandsFlag; + $versionCode = "="; + $Comment = "up-to-date"; + } + elsif ($rc < 0) { + $versionCode = "<"; + $Comment = "needs updating (index has $indexVersion)" + } + elsif ($rc > 0) { + next if $ShowCommandsFlag; + $versionCode = ">"; + $Comment = "succeeds index (index has $indexVersion)"; + } + else { + $versionCode = "?"; + $Comment = "Comparison failed"; + } + } + } + else { + $versionCode = "?"; + $Comment = "unknown in index"; + } + + write; +} + +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 @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +$packagePath +make +pkg_delete -f @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + $packageNameVer +make install + +. + ;