diff --git a/ChangeLog b/ChangeLog index 31d0f35..2d2b247 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ ChangeLog for pkg-get +0.4.8 - Fix pre- and post-install scripts to accommodate rootfs other + than "/", and ports with dashes in their names + - Use Perl modules where possible, to avoid spawning external processes + - Consolidate code + +0.4.7 - Fix man-page location + 0.4.6 - Fixed warnings on output of diff command - Use compression-mode defined in pkgmk.conf - pkg-repgen.pl: Improved prt-get commands and added --prtdir switch diff --git a/README b/README index 1e0eb33..1de08bf 100644 --- a/README +++ b/README @@ -1,8 +1,8 @@ INTRODUCTION ---------------------------------------------------------------------------- pkg-get is a package / repository management tool for CRUX Linux. -Syntax and features are very close (often a carbon copy) -to the ones found in the port management tool 'prt-get' +Syntax and features are very close to (often a carbon copy of) +the ones found in the port management tool 'prt-get' by Johannes Winkelmann. In fact pkg-get was developed as a prt-get/ports drop-in replacement for systems in which it is preferable to handle binary packages instead @@ -11,10 +11,10 @@ of compiling ports. ARCHITECTURE ---------------------------------------------------------------------------- -The local machines sync metadata files (available packages, -readme files, dependencies, etc) from a remote (http or ftp) +The client machines sync metadata files (available packages, +readme files, dependencies, etc) from a remote server (http or ftp) OR a local path. -Once the metadata is present on the local machine, the usual +Once the metadata files are on the client machine, the usual operations of installing, removing, getting info on packages are available. @@ -24,15 +24,17 @@ QUICK START Server: A repository can be generated using 'pkg-repgen' in a dir containing packages. It will take a while since md5sums - have to be calculated. + have to be calculated. Alternatively, you can pass one or + more arguments to 'pkg-repgen', indicating the individual + packages for which metadata will be created. Client: Adjust settings in /etc/pkg-get.conf, then use the 'pkg-get sync' command to gather metadata from the server (if remote). You can now - use the commands as described in the manual, i.e.: + use the commands as described in the manual, e.g.: pkg-get info apache - pkg-get depinst kdebase + pkg-get depinst qt6-base pkg-get listinst See the manual page for a detailed list of commands and options. @@ -40,5 +42,42 @@ See the manual page for a detailed list of commands and options. REQUIREMENTS ---------------------------------------------------------------------------- -For the client nothing outside the CRUX 'core' collection +For the client, nothing outside the CRUX 'core' collection For the server, prt-get + + +LIMITATIONS +---------------------------------------------------------------------------- +The client and the server must be configured to use the same +pkgmk compression mode, otherwise the client will try to download +a tarball with the wrong suffix. This is only a problem if you sometimes +compile ports on the client device. By allowing you to maintain your +client device solely with binary packages, pkg-get makes the contents of +/etc/pkgmk.conf mostly irrelevant. + +'pkg-get depends' and 'prt-get quickdep' do not handle more than one port, +unlike the corresponding commands in prt-get. Therefore it is not as +straightforward to preview the list of packages that would be installed, +before running a 'depinst' operation with multiple targets. + +The limitation above would have been mitigated by a --test switch. +Alas, such a switch is also absent from the design of pkg-get. Use +the --test switch with prt-get itself, for the closest approximation +of previewing the outcome from a 'pkg-get depinst' operation. + +Among the prt-get commands that have no counterpart in pkg-get +(grpinst, fsearch, deptree, listorphans, ls, cat, edit, cache), +only the 'grpinst' command is of possible interest; the remaining +commands are just as easily delegated to prt-get itself. If you want +a Perl implementation that does provide these missing commands, consider +the script written by user farkuhar [1]. + +pkg-get only makes use of the hard dependencies listed by the port +maintainer, not any of the eager linking that might have occurred on the +build machine. As a result, 'pkg-get depinst foo' might omit some of the +packages needed by 'foo'. User ppetrov^ has contributed some helper scripts +to facilitate the fixing of these broken binaries; visit the site [2] to +download them. + +[1] https://git.sdf.org/jmq/Documentation/src/branch/master/scripts/prt-auf +[2] https://github.com/slackalaxy/depsck diff --git a/TODO b/TODO index fb2bc3d..7d2f331 100644 --- a/TODO +++ b/TODO @@ -4,8 +4,10 @@ TODO file for pkg-get - add more commands: - deptree (?) - - lock/unlock/listlocked (?) + - grpinst (?) -- optimize the pkg-repgen script +- allow 'depends' and 'quickdep' to process multiple arguments + +- add a --test switch (?) - improve pkg-get help information diff --git a/doc/pkg-get.conf b/doc/pkg-get.conf index 9c42044..951c40b 100644 --- a/doc/pkg-get.conf +++ b/doc/pkg-get.conf @@ -3,7 +3,7 @@ # pkg-get configuration file # package repositories (remote) -# The first two are remote repoistories, the last is a local one +# The first two are remote repositories, the last is a local one pkgdir /usr/packages/server|http://www.somesite.com/packages pkgdir /usr/packages/java|http://www.foobar.com/java pkgdir /usr/packages/games diff --git a/scripts/pkg-get.pl b/scripts/pkg-get.pl index 090f117..fd62302 100755 --- a/scripts/pkg-get.pl +++ b/scripts/pkg-get.pl @@ -12,568 +12,452 @@ use warnings; use strict; use Getopt::Long; +use Digest::file qw(digest_file_hex); -my $VERSION = "0.4.6"; +my $VERSION = "0.4.8"; my $CFGFILE = "/etc/pkg-get.conf"; my $LOCKFILE = "/var/lib/pkg/pkg-get.locker"; my $PKGDB = "/var/lib/pkg/db" ; -$SIG{HUP} = \&trap; $SIG{INT} = \&trap; $SIG{QUIT} = \&trap; $SIG{TERM} = \&trap; +$SIG{HUP} = \&trap; $SIG{INT} = \&trap; +$SIG{QUIT} = \&trap; $SIG{TERM} = \&trap; # Global vars my @repos = (); # package repositories my @donetasks; my @failtasks; my @prevtasks; my %pptasks; my %readmetasks; -my $curraction = ""; my %installed; my %deps; my @dependencies; my %missingdeps; +my $curraction = ""; my %deps; my @dependencies; my %missingdeps; +my %locked; my %installed; # CL Options my $download_only; my $pre_install; my $post_install; my $install_scripts; my $filter = ""; my $all; my $unused; my $aargs=""; my $ignore_md5sum; my $force; my $root; GetOptions("do"=>\$download_only, - "pre-install"=>\$pre_install, "post-install"=>\$post_install, - "install-scripts"=>\$install_scripts, "all"=>\$all, - "filter=s"=>\$filter, "config=s"=>\$CFGFILE, "aargs=s"=>\$aargs, - "f"=>\$force, "im"=>\$ignore_md5sum, "margs=s"=>\$unused, - "rargs=s"=>\$unused, "r=s"=>\$root); + "pre-install"=>\$pre_install, "post-install"=>\$post_install, + "install-scripts"=>\$install_scripts, "all"=>\$all, + "filter=s"=>\$filter, "config=s"=>\$CFGFILE, "aargs=s"=>\$aargs, + "f"=>\$force, "im"=>\$ignore_md5sum, "margs=s"=>\$unused, + "rargs=s"=>\$unused, "r=s"=>\$root); # use compression-mode defined in pkgmk.conf our $compress = "gz"; open CONFIG, "/etc/pkgmk.conf" or die "Could not open /etc/pkgmk.conf"; while () { - $compress = $1 if m/^PKGMK_COMPRESSION_MODE="(.*)"\n/; + $compress = $1 if m/^PKGMK_COMPRESSION_MODE=(.*)(#|$)/; } close CONFIG; +$compress =~ s/['" ]//g; if ($root) { - $LOCKFILE = $root.$LOCKFILE ; - $PKGDB = $root.$PKGDB; + $LOCKFILE = $root.$LOCKFILE ; + $PKGDB = $root.$PKGDB; } # Get command, verify it's valid my $command = getcommand(@ARGV); if (index($command,"Error: ") eq 0 ) { - $command =~ s/Error\: //; - exiterr($command); + $command =~ s/Error\: //; + exiterr($command); } readconfig(); +get_locked() unless ($command =~ + /^(info|help|readme|search|dsearch|list|path|depend|current|isinst)$/); SWITCH: { - if ($command eq "version") { version(); last SWITCH; } - if ($command eq "sync") { sync(); last SWITCH; } - if ($command eq "info") { info(); last SWITCH; } - if ($command eq "help") { help(); last SWITCH; } - if ($command eq "readme") { readme(); last SWITCH; } - if ($command eq "search") { search(); last SWITCH; } - if ($command eq "dsearch") { dsearch(); last SWITCH; } - if ($command eq "list") { list(); last SWITCH; } - if ($command eq "path") { path(); last SWITCH; } - if ($command eq "remove") { remove(); last SWITCH; } - if ($command eq "listinst") { listinst(); last SWITCH; } - if ($command eq "lock") { dolock(); last SWITCH; } - if ($command eq "unlock") { unlock(); last SWITCH; } - if ($command eq "listlocked") { listlocked(); last SWITCH; } - if ($command eq "printf") { doprintf(); last SWITCH; } - if ($command eq "isinst") { isinst(); last SWITCH; } - if ($command eq "diff") { diff(); last SWITCH; } - if ($command eq "quickdiff") { quickdiff(); last SWITCH; } - if ($command eq "dup") { dup(); last SWITCH; } - if ($command eq "depends") { depends(); last SWITCH; } - if ($command eq "quickdep") { quickdep(); last SWITCH; } - if ($command eq "install") { install(@ARGV); last SWITCH; } - if ($command eq "update") { update(@ARGV); last SWITCH; } - if ($command eq "sysup") { sysup(); last SWITCH; } - if ($command eq "dependent") { dependent(); last SWITCH; } - if ($command eq "depinst") { depinst(); last SWITCH; } - if ($command eq "current") { current(); last SWITCH; } + if ($command eq "version") { version(); last SWITCH; } + if ($command eq "sync") { sync(); last SWITCH; } + if ($command eq "info") { info(); last SWITCH; } + if ($command eq "help") { help(); last SWITCH; } + if ($command eq "readme") { readme(); last SWITCH; } + if ($command =~ /^(d|)search$/) { search(); last SWITCH; } + if ($command eq "list") { list(); last SWITCH; } + if ($command eq "path") { path(); last SWITCH; } + if ($command eq "remove") { remove(); last SWITCH; } + if ($command eq "listinst") { listinst(); last SWITCH; } + if ($command eq "lock") { dolock(); last SWITCH; } + if ($command eq "unlock") { unlock(); last SWITCH; } + if ($command eq "listlocked") { listlocked(); last SWITCH; } + if ($command eq "printf") { doprintf(); last SWITCH; } + if ($command =~ /^(isinst|current)$/) { current(); last SWITCH; } + if ($command =~ /^(|quick)diff$/) { diff($1); last SWITCH; } + if ($command eq "dup") { dup(); last SWITCH; } + if ($command =~ /^(depends|quickdep)$/) { depends(); last SWITCH; } + if ($command =~ /^(install|update)$/) { upinst(@ARGV); last SWITCH; } + if ($command eq "sysup") { sysup(); last SWITCH; } + if ($command eq "dependent") { dependent(); last SWITCH; } + if ($command eq "depinst") { depinst(); last SWITCH; } } - ############################################################################ # Support functions ############################################################################ # Exit with error sub exiterr { - my ($msg) = @_; - print "pkg-get: $msg\n"; - exit 1; + my ($msg) = @_; + print "pkg-get: $msg\n"; + exit 1; } sub trap { - printresults(1); - die("\npkg-get: interrupted\n"); + printresults(1); + die("\npkg-get: interrupted\n"); } # Get command, return an error if not in the list of allowed commands sub getcommand { - my @args = @_; - my $givencmd = $args[0]; - my $givenarg = $args[1]; - if (not $givenarg){$givenarg = ""}; - if (not $givencmd){$givencmd = ""}; - my @allowed = ("depinst:", "install:", "sysup", "diff", "update:", "depends:", "info:", "sync", - "version", "help", "quickdep:", "dependent:", "list", "listinst", "isinst:", - "search:", "dsearch:", "lock:", "unlock:", "listlocked", "quickdiff", "printf:", - "remove:", "readme:", "dup", "path:", "current:"); + my ($givencmd, $givenarg) = @_; + if (not $givenarg){$givenarg = ""}; + if (not $givencmd){ + return "Error: no command given. try pkg-get help for more information"; + } - foreach my $valid(@allowed) { - if ($givencmd eq ""){ - return "Error: no command given. try pkg-get help for more information"; - } - if ($givencmd eq $valid) { - return $givencmd; - } elsif ($givencmd.":" eq $valid) { - if ($givenarg ne "") { - return $givencmd; - } else { - return "Error: '$givencmd' requires an argument"; - } - } - } - return "Error: unknown command '$givencmd'. try pkg-get help for more information"; + my @allowed = ("depinst:", "install:", "sysup", "diff", "update:", + "depends:", "info:", "sync", "version", "help", + "quickdep:", "dependent:", "list", "listinst", "isinst:", + "search:", "dsearch:", "lock:", "unlock:", "listlocked", + "quickdiff", "printf:", "remove:", "readme:", "dup", + "path:", "current:"); + + (grep { ($_ eq $givencmd) } @allowed) + or ((grep { ($_ eq "${givencmd}:") } @allowed) and ($givenarg ne "")) + or return "Error: improper command '$givencmd $givenarg'. Try pkg-get help for more information"; + + return $givencmd; } -# Parses the configuration file +# Parse the configuration file sub readconfig { - open(CFG, $CFGFILE) - or exiterr("could not open $CFGFILE"); - while () { - chomp; - if ( /^pkgdir\s+/ ) { - my $repo = $_; - $repo =~ s/^pkgdir\s+//; - $repo =~ s/#(.*)$//; - $repo =~ s/\s+$//; - push @repos, $repo; - } elsif (/^runscripts\s+/) { - my $rs = $_; - $rs =~ s/^runscripts\s+//; - $rs =~ s/#(.*)$//; - $rs =~ s/\s+$//; - if ($rs eq "yes") {$install_scripts = 1}; - } - } - close(CFG); + open(CFG, $CFGFILE) + or exiterr("could not open $CFGFILE"); + while () { + chomp; + if ( /^pkgdir\s+/ ) { + my $repo = $_; + $repo =~ s/^pkgdir\s+//; + $repo =~ s/#.*$//; + $repo =~ s/\s+$//; + push @repos, $repo; + } elsif (/^runscripts\s+/) { + my $rs = $_; + $rs =~ s/^runscripts\s+//; + $rs =~ s/#.*$//; + $rs =~ s/\s+$//; + if ($rs eq "yes") {$install_scripts = 1}; + } + } + close(CFG); +} + +# Populate a hash of locked packages +sub get_locked { + (-f $LOCKFILE) or system("touch $LOCKFILE"); + open (my $fL, $LOCKFILE) or return; + while (<$fL>) { $locked{$_} = 1; } + close ($fL); } # Parse a line describing a package sub parsepackage { - my @p = split(/\:/, $_[0]); - if ($#p != 6) {exiterr("$_[1]/PKGREPO appears to be in wrong format!\nAborting.")}; - my %pkg; - my $name = $p[0]; - $name =~ s/\#.*$//; - my $version = $p[0]; - $version =~ s/^.*\#//; - $version =~ s/-\w*\.pkg\.tar\.[gbx]z*//; - my $release = $p[0]; - $release =~ s/^.*-//; - $release =~ s/\.pkg\.tar\.[gbx]z*//; - if (not $_[2]) {$_[2] = $_[1]}; - $pkg{'name'} = $name; - $pkg{'version'} = $version; - $pkg{'release'} = $release; - $pkg{'path'} = $_[1]; - $pkg{'url'} = $_[2] . "/$p[0]"; - $pkg{'size'} = $p[1]; - $pkg{'md5sum'} = $p[2]; - $pkg{'description'} = $p[3]; - $pkg{'pre_install'} = $p[4]; - $pkg{'post_install'} = $p[5]; - $pkg{'readme'} = $p[6]; - if ($_[3] == 1) { - getinstalled(); - $pkg{'instversion'} = $installed{$name}; - } - return %pkg; + my @p = split(/\:/, $_[0]); + if ($#p != 6) {exiterr("$_[1]/PKGREPO appears to be in wrong format!\nAborting.")}; + my %pkg; + my $name = $p[0]; + $name =~ s/\#.*$//; + my $version = $p[0]; + $version =~ s/^.*\#//; + $version =~ s/-\w*\.pkg\.tar\.[gbx]z*//; + my $release = $p[0]; + $release =~ s/^.*-//; + $release =~ s/\.pkg\.tar\.[gbx]z*//; + if (not $_[2]) {$_[2] = $_[1]}; + $pkg{'name'} = $name; + $pkg{'version'} = $version; + $pkg{'release'} = $release; + $pkg{'path'} = $_[1]; + $pkg{'url'} = $_[2] . "/$p[0]"; + $pkg{'size'} = $p[1]; + $pkg{'md5sum'} = $p[2]; + $pkg{'description'} = $p[3]; + $pkg{'pre_install'} = $p[4]; + $pkg{'post_install'} = $p[5]; + $pkg{'readme'} = $p[6]; + if ($_[3] == 1) { + getinstalled() if (! %installed); + $pkg{'instversion'} = $installed{$name}; + } + return %pkg; } # Parse a line describing a package (just the name) sub parsepackagelight { - my @p = split(/\:/, $_[0]); - if ($#p != 6) {exiterr("$_[1]/PKGREPO appears to be in wrong format!\nAborting.")}; - my %pkg; - my $name = $p[0]; - $name =~ s/\#.*$//; - $pkg{'name'} = $name; - return %pkg; + my @p = split(/\:/, $_[0]); + if ($#p != 6) {exiterr("$_[1]/PKGREPO appears to be in wrong format!\nAborting.")}; + my %pkg; + my $name = $p[0]; + $name =~ s/\#.*$//; + $pkg{'name'} = $name; + return %pkg; } # Print info about the given package sub printinfo { - my %pkg = @_; - print "Name : " . $pkg{'name'} . "\n"; - print "Version : " . $pkg{'version'} . "\n"; - print "Release : " . $pkg{'release'} . "\n"; - print "Description : " . $pkg{'description'} . "\n"; - print "URL : " . $pkg{'url'} . "\n"; - print "Md5sum : " . $pkg{'md5sum'} . "\n"; - print "Size : " . $pkg{'size'} . "\n"; - my $deps = getdirectdeps($pkg{'name'}, $pkg{'path'}); - if ($deps ne "") { print "Depends on : $deps\n";}; - my $files = ""; - if ($pkg{'readme'} eq "yes") {$files .= "README,"}; - if ($pkg{'pre_install'} eq "yes") {$files .= "pre-install,"}; - if ($pkg{'post_install'} eq "yes") {$files .= "post-install,"}; - $files =~ s/\,$//; - if ($files ne "") { print "Files : $files\n";}; + my %pkg = @_; + print "Name : " . $pkg{'name'} . "\n"; + print "Version : " . $pkg{'version'} . "\n"; + print "Release : " . $pkg{'release'} . "\n"; + print "Description : " . $pkg{'description'} . "\n"; + print "URL : " . $pkg{'url'} . "\n"; + print "Md5sum : " . $pkg{'md5sum'} . "\n"; + print "Size : " . $pkg{'size'} . "\n"; + my $deps = getdirectdeps($pkg{'name'}, $pkg{'path'}); + if ($deps ne "") { print "Depends on : $deps\n";}; + my $files = ""; + if ($pkg{'readme'} eq "yes") {$files .= "README,"}; + if ($pkg{'pre_install'} eq "yes") {$files .= "pre-install,"}; + if ($pkg{'post_install'} eq "yes") {$files .= "post-install,"}; + $files =~ s/\,$//; + if ($files ne "") { print "Files : $files\n";}; } # Get direct dependencies for package sub getdirectdeps { - my $pkgname = $_[0]; - my $dir = $_[1]; - open(DEPS, "$dir/PKGDEPS") - or exiterr("could not open $dir/PKGDEPS"); - while () { - chomp; - if ( /^\Q$pkgname\E\s+/ ) { - my $dep = $_; - $dep =~ s/^.*\: //; - close(DEPS); - return $dep; - } - } - close(DEPS); - return ""; + my ($pkgname, $dir) = @_; + open(DEPS, "$dir/PKGDEPS") + or exiterr("could not open $dir/PKGDEPS"); + while () { + chomp; + if ( /^\Q$pkgname\E\s+/ ) { + my $dep = $_; + $dep =~ s/^.*\: //; + close(DEPS); + return $dep; + } + } + close(DEPS); + return ""; } # Prints the README file to stdout sub printreadme { - my %pkg = @_; - my $dir = $pkg{'path'}; - my $pkgname = $pkg{'name'}; - my $found = 0; - my $finished = 0; - open(READ, "$dir/PKGREAD") - or exiterr("could not open $dir/PKGREAD"); - while () { - if ($finished eq 1) {return;}; - chomp; - if ($found eq 1) { - if ( /PKGREADME\:/ ) { - $finished = 1; - close(READ); - return; - } else { - print "$_\n"; - } - } - if ($finished eq 0) { - if ( /PKGREADME: $pkgname$/ ) { - $found = 1; - } - } - } - close(READ); + my %pkg = @_; + my ($found, $finished) = (0, 0); + open(READ, "$pkg{'path'}/PKGREAD") + or exiterr("could not open $pkg{'path'}/PKGREAD"); + while () { + if ($finished eq 1) {return;}; + chomp; + if (($found eq 1) and ( /PKGREADME\:/ )) { + $finished = 1; + close(READ); + return; + } elsif ($found eq 1) { + print "$_\n"; + } elsif ( /PKGREADME: $pkg{'name'}$/ ) { + $found = 1; + } + } + close(READ); } # Print results for multiple package operations sub printresults { - my $okaction = $curraction; - my $curr = ""; - my $action; - my $pkg; - my @t; - my @readme; - my $goterror = 0; - if (@donetasks) { - print "\n-- Packages $okaction\n"; - foreach my $task(@donetasks) { - if ($readmetasks{$task}) {push(@readme, $task)} - print "$task" . $pptasks{$task}."\n"; - } - } - if (@prevtasks) { - if ($okaction eq "installed") { - print "\n-- Packages installed before this run (ignored)\n"; - } else { - print "\n-- Packages not previously installed (ignored)\n"; - } - foreach my $task(@prevtasks) { - print "$task\n"; - } - } - if (@failtasks) { - @failtasks = sort(@failtasks); - foreach my $task(@failtasks) { - @t = split(/,/,$task); - $action = $t[0]; - $pkg = $t[1]; - if ($curr ne $action) { - print "\n-- Packages $action\n"; - $curr = $action; - } - print "$pkg\n"; - } - } - if (@readme) { - print "\n-- $okaction packgages with README file\n"; - foreach my $task(@readme) { - print "$task" . $pptasks{$task}."\n"; - } - } + my $okaction = $curraction; + my $curr = ""; + my $action; my $pkg; + my @readme; + my $goterror = 0; + if (@donetasks) { + print "\n-- Packages $okaction\n"; + foreach my $task(@donetasks) { + if ($readmetasks{$task}) {push(@readme, $task)} + print "$task" . $pptasks{$task}."\n"; + } + } + if (@prevtasks) { + if ($okaction eq "installed") { + print "\n-- Packages installed before this run (ignored)\n"; + } else { + print "\n-- Packages not previously installed (ignored)\n"; + } + foreach my $task(@prevtasks) { print "$task\n"; } + } + if (@failtasks) { + foreach my $task(sort @failtasks) { + ($action, $pkg) = split(/,/,$task); + if ($curr ne $action) { + print "\n-- Packages $action\n"; + $curr = $action; + } + print "$pkg\n"; + } + } + if (@readme) { + print "\n-- $okaction packages with README file\n"; + foreach my $task(@readme) { + print "$task" . $pptasks{$task}."\n"; + } + } if(@donetasks and not @failtasks and not $_[0]) { - print "\npkg-get: $okaction successfully\n" - } + print "\npkg-get: $okaction successfully\n" + } } # Get the list of installed packages sub getinstalled { - if (%installed) { - return; - } - my $name; - my $version; - my $sec = 0; - open(DB, $PKGDB) - or exiterr("could not open ".$PKGDB); - while () { - chomp; - if ($_ ne "") { - if ($sec == 0) { - $name = $_; - $sec = 1; - } elsif ($sec == 1) { - $version = $_; - $sec = 3; - } - } - if ($sec == 3) { - if ($_ eq "") { - $sec = 0; - $installed{$name} = $version; - } - } - } - close(DB); + local $/ = ""; # read files paragraph-wise; see ``perldoc perlvar'' + open(DB, $PKGDB) + or exiterr("could not open ".$PKGDB); + while () { + my ($name, $version, @files) = split /\n/, $_; + $installed{$name} = $version; + } + close(DB); } -# Lock the given pkgname -sub lockadd { - my $pkg = $_[0]; - my @locked = (); - if (not -e $LOCKFILE) { - open(LCK, "+>> $LOCKFILE") or exiterr("could not write to lock file"); - close(LCK); - } - open(LCK, $LOCKFILE); - while () { - chomp; - if ($_ eq $pkg) { - print "Already locked: $pkg\n"; - close(LCK); - return; - } else { - push (@locked, $_); - } - } - close(LCK); - push(@locked, $pkg); - @locked = sort(@locked); - open(LCK, "> $LOCKFILE") or exiterr("could not write to lock file"); - foreach my $lock(@locked) { - print LCK "$lock\n"; - } - close(LCK); -} - -# Rrint formatted info for given package +# Print formatted info for given package sub formattedprint { - my %pkg = @_; - my $fmt = $ARGV[1]; - $fmt =~ s|%n|$pkg{'name'}|; - $fmt =~ s|%p|$pkg{'path'}|; - $fmt =~ s|%v|$pkg{'version'}|; - $fmt =~ s|%r|$pkg{'release'}|; - $fmt =~ s|%d|$pkg{'description'}|; - $fmt =~ s|%u|$pkg{'url'}|; - $fmt =~ s|%R|$pkg{'readme'}|; - $fmt =~ s|%E|$pkg{'pre_install'}|; - $fmt =~ s|%O|$pkg{'post_install'}|; - $fmt =~ s|%M|Nobody|; # for prt-get compatibility - $fmt =~ s|%P|Nobody|; # for prt-get compatibility - $fmt =~ s|\\n|\n|; - $fmt =~ s|\\t|\t|; - if (index($fmt,"%e") >=0) { - my $deps = getdirectdeps($pkg{'name'}, $pkg{'path'}); - $fmt =~ s|%e|$deps|; - } - if (index($fmt,"%l") >=0) { - my $locked = islocked($pkg{'name'}); - $fmt =~ s|%l|$locked|; - } - if (index($fmt,"%i") >=0) { - my $inst = "no"; - if ($pkg{'instversion'}) { - if ($pkg{'instversion'} eq $pkg{'version'}."-".$pkg{'release'}) { - $inst = "yes"; - } else { - $inst = "diff"; - } - } - $fmt =~ s|%i|$inst|; - } - print "$fmt"; -} - -# See if package is currently locked -sub islocked { - my $pkg = $_[0]; - open(LCK, $LOCKFILE) or return "no"; - while () { - chomp; - if ($_ eq $pkg) { - close(LCK); - return "yes"; - } - } - close(LCK); - return "no"; + my %pkg = @_; + my $fmt = $ARGV[1]; + $fmt =~ s|%n|$pkg{'name'}|; + $fmt =~ s|%p|$pkg{'path'}|; + $fmt =~ s|%v|$pkg{'version'}|; + $fmt =~ s|%r|$pkg{'release'}|; + $fmt =~ s|%d|$pkg{'description'}|; + $fmt =~ s|%u|$pkg{'url'}|; + $fmt =~ s|%R|$pkg{'readme'}|; + $fmt =~ s|%E|$pkg{'pre_install'}|; + $fmt =~ s|%O|$pkg{'post_install'}|; + $fmt =~ s|%M|Nobody|; # for prt-get compatibility + $fmt =~ s|%P|None|; # for prt-get compatibility + $fmt =~ s|\\n|\n|; + $fmt =~ s|\\t|\t|; + if (index($fmt,"%e") >=0) { + my $deps = getdirectdeps($pkg{'name'}, $pkg{'path'}); + $fmt =~ s|%e|$deps|; + } + if (index($fmt,"%l") >=0) { + my $locked = ($locked{$pkg{'name'}}) ? "yes" : "no"; + $fmt =~ s|%l|$locked|; + } + if (index($fmt,"%i") >=0) { + my $inst = ($pkg{'instversion'}) ? "yes" : "no"; + if ( ($inst eq "yes") and ($pkg{'instversion'} + ne $pkg{'version'}."-".$pkg{'release'}) ) { + $inst = "diff"; + } + $fmt =~ s|%i|$inst|; + } + print "$fmt"; } # Get package from the repo(s) sub getpackage { - my $pkgname = $_[0]; - my $checkver = $_[1]; - my %found; - my %res; - foreach my $repo(@repos) { - my @r = split(/\|/, $repo); - my $dir = $r[0]; - my $url = $r[1]; - open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); - while () { - chomp; - my %pkg = parsepackage($_, $dir, $url, $checkver); - if ($pkg{'name'} eq $pkgname) { - close (REPO); - return %pkg; - } - } - close (REPO); - } - return %res; + my ($pkgname, $checkver) = @_; + my %found; my %res; + foreach my $repo(@repos) { + my ($dir, $url) = split(/\|/, $repo); + open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); + while () { + chomp; + my %pkg = parsepackage($_, $dir, $url, $checkver); + if ($pkg{'name'} eq $pkgname) { + close (REPO); + return %pkg; + } + } + close (REPO); + } + return %res; } -# Get short status for package, ie [i] +# Get short status for package, e.g. [i] sub getshortstatus { - my %pkg = @_; - if ($pkg{'instversion'}) { - if ($pkg{'instversion'} eq $pkg{'version'}."-".$pkg{'release'}) { - return "[i]"; - } else { - return "[u]"; - } - } - return "[ ]"; + my %pkg = @_; + return "[ ]" if (! $pkg{'instversion'}); + return "[i]" if ($pkg{'instversion'} eq $pkg{'version'}."-".$pkg{'release'}); + return "[u]"; } # Get (recursive) dependencies for pkgname sub getdependencies { - my $pkgname = $_[0]; - my $checkver = $_[1]; - my $pkgparent = $_[2]; - my $depstring = ""; - if ($pkgparent eq "") { - #%deps = (); - }; - if (not $deps{$pkgname}) { - my %pkg = getpackage($pkgname, 1); - if (%pkg) { - my $ddeps = getdirectdeps($pkg{'name'}, $pkg{'path'}); - my @d = split(/,/, $ddeps); - foreach my $dep(@d) { - getdependencies($dep, $checkver, $pkgname); - } - if ($checkver) { - $depstring = getshortstatus(%pkg) . " $pkgname"; - } else { - $depstring = $pkgname; - } - $deps{$pkgname} = $depstring; - push(@dependencies, $depstring); - } else { - if ($pkgparent eq "") { - return 0; - } else { - $missingdeps{$pkgname} = $pkgparent; - } - } - } + my ($pkgname, $checkver, $pkgparent) = @_; + my $depstring = ""; + if (not $deps{$pkgname}) { + my %pkg = getpackage($pkgname, 1); + if (%pkg) { + my $ddeps = getdirectdeps($pkg{'name'}, $pkg{'path'}); + my @d = split(/,/, $ddeps); + foreach my $dep(@d) { + getdependencies($dep, $checkver, $pkgname); + } + $depstring = getshortstatus(%pkg)." " if ($checkver); + $depstring .= $pkgname; + $deps{$pkgname} = $depstring; + push(@dependencies, $depstring); + } else { + return 0 if ($pkgparent eq ""); + $missingdeps{$pkgname} = $pkgparent; + } + } } # Download given package (if needed), check md5sum sub downloadpkg { - my %pkg = @_; - my $fullpath = $pkg{'path'}."/".$pkg{'name'}."#".$pkg{'version'}."-".$pkg{'release'}.".pkg.tar.$compress"; - if (-f $fullpath) { - my $md5 = `md5sum $fullpath`; chomp; - $md5 =~ s/\s+.*$//; - $md5 =~ chop($md5); - if ($md5 ne $pkg{'md5sum'} and not $ignore_md5sum) { - print STDERR "=======> ERROR: md5sum mismatch for $pkg{'name'}:\n"; - print STDERR "required : $pkg{'md5sum'}\n"; - print STDERR "found : $md5\n"; - return 0; - } - return 1; - } else { - if ($pkg{'url'} eq "") {return 1}; # repo is local and pkg does not exist. - my $url = $pkg{'url'}; - $url =~ s/\#/\%23/; - system ("wget --no-directories --tries=3 --waitretry=3 --directory-prefix=$pkg{'path'} $url") == 0 or return 0; - my $md5 = `md5sum $fullpath`; chomp; - $md5 =~ s/\s+.*$//; - $md5 =~ chop($md5); - if ($md5 ne $pkg{'md5sum'} and not $ignore_md5sum) { - print STDERR "=======> ERROR: md5sum mismatch for $pkg{'name'}:\n"; - print STDERR "required : $pkg{'md5sum'}\n"; - print STDERR "found : $md5\n"; - return 0; - } - } - return 1; + my %pkg = @_; + my $fullpath = $pkg{'path'}."/".$pkg{'name'}."#".$pkg{'version'}."-".$pkg{'release'}.".pkg.tar.$compress"; + if (-f $fullpath) { + my $md5 = digest_file_hex($fullpath,"MD5"); + if ($md5 ne $pkg{'md5sum'} and not $ignore_md5sum) { + print STDERR "=======> ERROR: md5sum mismatch for $pkg{'name'}:\n"; + print STDERR "required : $pkg{'md5sum'}\n"; + print STDERR "found : $md5\n"; + return 0; + } + return 1; + } else { + return 1 if ($pkg{'url'} eq ""); # repo is local and pkg does not exist. + my $url = $pkg{'url'}; + $url =~ s/\#/\%23/; + system ("curl --retry 3 --retry-delay 3 -o $fullpath $url") == 0 or return 0; + my $md5 = digest_file_hex($fullpath,"MD5"); + if ($md5 ne $pkg{'md5sum'} and not $ignore_md5sum) { + print STDERR "=======> ERROR: md5sum mismatch for $pkg{'name'}:\n"; + print STDERR "required : $pkg{'md5sum'}\n"; + print STDERR "found : $md5\n"; + return 0; + } + } + return 1; } # Install given package sub installpkg { - my $upgrade = shift(@_); - my %pkg = @_; - my $aa = $aargs." "; - if ($pkg{'readme'} eq "yes") {$readmetasks{$pkg{'name'}} = 1}; - $pptasks{$pkg{'name'}} = ""; - if ($download_only) {return 1}; - if ($force){$aa = $aa."-f "}; - if ($root) {$aa = $aa."-r ".$root." "}; - if ($pkg{'pre_install'} eq "yes" and ($install_scripts or $pre_install)) {dopre(%pkg)}; - my $fullpath = $pkg{'path'}."/".$pkg{'name'}."#".$pkg{'version'}."-".$pkg{'release'}.".pkg.tar.$compress"; - print "pkg-get: /usr/bin/pkgadd $upgrade$aa$fullpath\n"; - system ("/usr/bin/pkgadd $upgrade$aa$fullpath") == 0 or return 0; - if ($pkg{'post_install'} eq "yes" and ($install_scripts or $post_install)) {dopost(%pkg)}; - return 1; + my ($upgrade, %pkg) = @_; + my $aa = $aargs." "; + if ($pkg{'readme'} eq "yes") {$readmetasks{$pkg{'name'}} = 1}; + $pptasks{$pkg{'name'}} = ""; + if ($download_only) {return 1;} + if ($force){$aa = $aa."-f ";} + if ($root) {$aa = $aa."-r ".$root." ";} + if ($pkg{'pre_install'} eq "yes" and ($install_scripts or $pre_install)) {doscript("pre",%pkg);} + my $fullpath = $pkg{'path'}."/".$pkg{'name'}."#".$pkg{'version'}."-".$pkg{'release'}.".pkg.tar.$compress"; + print "pkg-get: /usr/bin/pkgadd $upgrade $aa$fullpath\n"; + system ("/usr/bin/pkgadd $upgrade $aa$fullpath") == 0 or return 0; + if ($pkg{'post_install'} eq "yes" and ($install_scripts or $post_install)) {doscript("post",%pkg);} + return 1; } -# Execute pre-install script -sub dopre { - my %pkg = @_; - my $cmd = "/bin/bash $pkg{'path'}/PKGINST $pkg{name}_pre_install"; - if (system($cmd) == 0){ - $pptasks{$pkg{'name'}} .= " [pre: ok]"; - } else { - $pptasks{$pkg{'name'}} .= " [pre: failed]"; - } -} - -# Execute post-install script -sub dopost { - my %pkg = @_; - my $cmd = "/bin/bash $pkg{'path'}/PKGINST $pkg{name}_post_install"; - if (system($cmd) == 0){ - $pptasks{$pkg{'name'}} .= " [post: ok]"; - } else { - $pptasks{$pkg{'name'}} .= " [post: failed]"; - } +# Execute pre- or post-install script +sub doscript { + my ($when, %pkg) = @_; + my $cmd = ($root) ? "chroot $root " : ""; + $cmd .= "/bin/bash $pkg{'path'}/PKGINST $pkg{name} $when"; + if (system($cmd) == 0) { + $pptasks{$pkg{'name'}} .= " [$when: ok]"; + } else { + $pptasks{$pkg{'name'}} .= " [$when: failed]"; + } } ############################################################################ @@ -582,19 +466,19 @@ sub dopost { # No pun intended ########################################################## sub version { - print "pkg-get $VERSION "; - print "by Simone Rota \n"; + print "pkg-get $VERSION "; + print "by Simone Rota \n"; } # Show brief help ########################################################## sub help { - print "Usage: pkg-get command [package2 ... packageN] [options] + print "Usage: pkg-get command [package2 ... packageN] [options] Some command: sync synchronize with the repository - depinst install package and its dependencies; + depinst install package and its dependencies info info about package - sysup updates all outdated packages + sysup update all outdated packages diff list all outdated packages Some option: @@ -610,578 +494,372 @@ For other commands and samples, see the pkg-get(8) man page\n"; # Sync with the remote server(s) ########################################### sub sync { - my @r; - my $dir; - my $url; - my $dlerror = 0; - foreach my $repo(@repos) { - @r = split(/\|/, $repo); - $dir = $r[0]; - $url = $r[1]; - if (not $url){$url = ""}; - print "Updating collection $dir\n"; - if (not -d $dir) { - mkdir($dir) or exiterr("cannot create $dir"); - } - if ($url ne "") { - for my $f ("PKGREPO", "PKGDEPS", "PKGREAD", "PKGINST") { - if (-f "$dir/$f") {rename("$dir/$f", "$dir/$f.old") or exiterr("cannot write to $dir")}; - if (system("wget -q -P $dir $url/$f") != 0) { - print " cannot retrieve $f\n"; - $dlerror=1; - } - } - if ($dlerror) { # restore backup repo - for my $f ("PKGREPO", "PKGDEPS", "PKGREAD", "PKGINST") { - if (-f "$dir/$f.old") {rename("$dir/$f.old", "$dir/$f") or exiterr("cannot write to $dir")};}; - } else { # remove backup repo - for my $f ("PKGREPO", "PKGDEPS", "PKGREAD", "PKGINST") { - if (-f "$dir/$f.old") {unlink("$dir/$f.old") or exiterr("cannot write to $dir")};}; - } - } - } + my $dlerror = 0; + foreach my $repo(@repos) { + my ($dir, $url) = split(/\|/, $repo); + next if (not $url); + print "Updating collection $dir\n"; + (-d $dir) or mkdir($dir) or exiterr("cannot create $dir"); + for my $f ("PKGREPO", "PKGDEPS", "PKGREAD", "PKGINST") { + (! -f "$dir/$f") or rename("$dir/$f", "$dir/$f.old") or exiterr("cannot write to $dir"); + if (system("curl -s --output-dir $dir -o $f $url/$f") != 0) { + print " cannot retrieve $f\n"; + $dlerror=1; + } + } + if ($dlerror) { # restore backup repo + for my $f ("PKGREPO", "PKGDEPS", "PKGREAD", "PKGINST") { + (! -f "$dir/$f.old") or rename("$dir/$f.old", "$dir/$f") or exiterr("cannot write to $dir"); + } + } else { # remove backup repo + for my $f ("PKGREPO", "PKGDEPS", "PKGREAD", "PKGINST") { + (! -f "$dir/$f.old") or unlink("$dir/$f.old") or exiterr("cannot write to $dir"); + } + } + } } -# Show info about the package ############################################## +# Show info/path/readme for the package ##################################### sub info { - my $arg = $ARGV[1]; - foreach my $repo(@repos) { - my @r = split(/\|/, $repo); - my $dir = $r[0]; - my $url = $r[1]; - open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); - while () { - chomp; - my %pkg = parsepackage($_, $dir, $url, 0); - if ($pkg{'name'} eq $arg) { - printinfo(%pkg); - close(REPO); - return; - } - } - close(REPO); - } - print "Package '$arg' not found\n"; + my ($type, $arg) = @ARGV; + foreach my $repo(@repos) { + my ($dir, $url) = split(/\|/, $repo); + open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); + while () { + chomp; + my %pkg = parsepackage($_, $dir, $url, 0); + if ($pkg{'name'} eq $arg) { + if ($type eq "info") { printinfo(%pkg); + } elsif ($type eq "readme") { printreadme(%pkg); + } elsif ($type eq "path") { print $pkg{'path'} . "\n"; + } + close(REPO); return; + } + } + close(REPO); + } + print "Package '$arg' not found\n"; } -# List packages containing given string in their name ###################### +# List packages containing given string (name/description) ################### sub search { - my $arg = $ARGV[1]; - my %found; - foreach my $repo(@repos) { - my @r = split(/\|/, $repo); - my $dir = $r[0]; - my $url = $r[1]; - open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); - while () { - chomp; - my %pkg = parsepackage($_, $dir, $url, 0); - if (index($pkg{'name'}, $arg) > -1 and not $found{$pkg{'name'}}) { - $found{$pkg{'name'}} = 1; - } - } - close(REPO); - } - foreach my $key (sort keys %found) { - print "$key\n"; - } - if (not %found) {print "No matching packages found\n"}; -} - -# List packages containing given string (name / description) ############### -sub dsearch { - my $arg = $ARGV[1]; - my %found; - foreach my $repo(@repos) { - my @r = split(/\|/, $repo); - my $dir = $r[0]; - my $url = $r[1]; - open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); - while () { - chomp; - my %pkg = parsepackage($_, $dir, $url, 0); - if ((index($pkg{'name'}, $arg) > -1 or index($pkg{'description'}, $arg) > -1) - and not $found{$pkg{'name'}}) { - $found{$pkg{'name'}} = 1; - } - } - close(REPO); - } - foreach my $key (sort keys %found) { - print "$key\n"; - } - if (not %found) {print "No matching packages found\n";}; + my $arg = $ARGV[1]; + my $type = ($ARGV[0] =~ /^d/) ? "desc" : "name"; + my %found; + foreach my $repo(@repos) { + my ($dir, $url) = split(/\|/, $repo); + open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); + while () { + chomp; + my %pkg = parsepackage($_, $dir, $url, 0); + next if ($found{$pkg{'name'}}); + if ( (index($pkg{'name'}, $arg) >= 0) or + (($type eq "desc") and (index($pkg{'description'}, $arg) >= 0)) ) + {$found{$pkg{'name'}} = 1;} + } + close(REPO); + } + foreach my $key (sort keys %found) { print "$key\n"; } + if (not %found) { print "No matching packages found\n"; } } # List all available packages ############################################## sub list { - my $arg = $ARGV[1]; - my %found; - foreach my $repo(@repos) { - my @r = split(/\|/, $repo); - my $dir = $r[0]; - my $url = $r[1]; - open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); - while () { - chomp; - my %pkg = parsepackage($_, $dir, $url, 0); - $found{$pkg{'name'}} = 1; - } - close(REPO); - } - foreach my $key (sort keys %found) { - print "$key\n"; - } -} - -# Show path for a package ################################################## -sub path { - my $arg = $ARGV[1]; - foreach my $repo(@repos) { - my @r = split(/\|/, $repo); - my $dir = $r[0]; - my $url = $r[1]; - open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); - while () { - chomp; - my %pkg = parsepackage($_, $dir, $url, 0); - if ($pkg{'name'} eq $arg) { - print $pkg{'path'} . "\n"; - close(REPO); - return; - } - } - close(REPO); - } - print "Package '$arg' not found\n"; -} - -# Show current installed version of a package ############################## -sub current { - my $pkgname = $ARGV[1]; - getinstalled(); - if ($installed{$pkgname}) { - print "$installed{$pkgname}\n"; - } else { - print "Package $pkgname not installed\n"; - } -} - -# Print the README file for a package ###################################### -sub readme { - my $arg = $ARGV[1]; - foreach my $repo(@repos) { - my @r = split(/\|/, $repo); - my $dir = $r[0]; - my $url = $r[1]; - open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); - while () { - chomp; - my %pkg = parsepackage($_, $dir, $url, 0); - if ($pkg{'name'} eq $arg) { - printreadme(%pkg); - close(REPO); - return; - } - } - close(REPO); - } - print "Package '$arg' not found\n"; + my $arg = $ARGV[1]; + my %found; + foreach my $repo(@repos) { + my ($dir, $url) = split(/\|/, $repo); + open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); + while () { + chomp; + my %pkg = parsepackage($_, $dir, $url, 0); + $found{$pkg{'name'}} = 1; + } + close(REPO); + } + foreach my $key (sort keys %found) { print "$key\n"; } } # Remove given packages #################################################### sub remove { - $curraction = "removed"; - shift(@ARGV); - foreach my $pkg(@ARGV) { - $pptasks{$pkg} = ""; - if (system("/usr/bin/pkgrm $pkg") ==0) { - push(@donetasks, $pkg); - } else { - push(@failtasks, "where removal failed,$pkg"); - } - } - printresults(); + $curraction = "removed"; + shift(@ARGV); + my $cmd = "/usr/bin/pkgrm"; + $cmd .= " -r $root" if ($root); + foreach my $pkg(@ARGV) { + $pptasks{$pkg} = ""; + if (system("$cmd $pkg")==0) { + push(@donetasks, $pkg); + } else { + push(@failtasks, "where removal failed,$pkg"); + } + } + printresults(); } # List installed packages ################################################## sub listinst { - getinstalled(); - foreach my $key (sort keys %installed) { - print "$key\n"; - } + getinstalled() if (! %installed); + foreach my $key (sort keys %installed) { print "$key\n"; } } -# Print if package is installed ########################################### -sub isinst { - getinstalled(); - shift(@ARGV); - foreach my $pkg(@ARGV) { - if ($installed{$pkg}) { - print "package $pkg is installed\n"; - } else { - print "package $pkg is not installed\n"; - } - } +# Print package version, or install status ################################# +sub current { + getinstalled() if (! %installed); + my $type = shift(@ARGV); my $result; + foreach my $pkg(@ARGV) { + if ($installed{$pkg}) { + $result = ($type eq "current") ? ": version $installed{$pkg}\n" + : " is installed\n"; + } else { + $result = " not installed\n"; + } + print "Package " . $pkg . $result; + } } - # Lock given packages ###################################################### sub dolock { - shift(@ARGV); - foreach my $arg(@ARGV) { - my $found = 0; - foreach my $repo(@repos) { - if ($found == 0) { - my @r = split(/\|/, $repo); - my $dir = $r[0]; - my $url = $r[1]; - open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); - while () { - chomp; - my %pkg = parsepackagelight($_); - if ($pkg{'name'} eq $arg) { - $found = 1; - lockadd($arg); - } - } - close(REPO); - } - } - if ($found == 0) {print "Package '$arg' not found\n"}; - } + shift(@ARGV); + foreach my $arg(@ARGV) { + if ($locked{$arg}) { + print "Already locked: $arg\n"; next; + } + my $found = 0; + foreach my $repo(@repos) { + my ($dir, $url) = split(/\|/, $repo); + open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); + while () { + chomp; + my %pkg = parsepackagelight($_); + if ($pkg{'name'} eq $arg) { + $found = 1; + open(LCK, ">> $LOCKFILE") + or exiterr("could not write to lock file"); + print LCK "$arg\n"; + close(LCK); + } + last if ($found); + } + close(REPO); + last if ($found); + } + if ($found == 0) {print "Package '$arg' not found\n"}; + } } # Unlock given packages #################################################### sub unlock { - shift(@ARGV); - my @locked; - my $found; - foreach my $arg(@ARGV) { - $found = 0; - @locked = (); - open(LCK, $LOCKFILE) or exiterr("could not open lock file"); - while () { - chomp; - if ($_ eq $arg) { - push (@locked, "-"); - $found = 1; - } else { - push (@locked, $_); - } - } - close(LCK); - if ($found == 1) { - @locked = sort(@locked); - open(LCK, ">$LOCKFILE") or exiterr("could not write to lock file"); - foreach my $lock(@locked) { - if ($lock ne "-") {print LCK "$lock\n"}; - } - close(LCK); - } else { - print "Not locked previously: $arg\n"; - } - } + shift(@ARGV); + foreach my $arg(@ARGV) { + if (! $locked{$arg}) { + print "Not locked previously: $arg\n"; next; + } else { + delete $locked{$arg}; + } + } + open(my $fL, ">$LOCKFILE") or exiterr("could not write to lock file"); + foreach (sort keys %locked) { print $fL "$_\n"; } + close($fL); } # List locked packages ##################################################### sub listlocked { - open(LCK, $LOCKFILE) - or exit; - while () { - chomp; - print "$_\n"; - } - close(LCK); + foreach (sort keys %locked) { print "$_\n"; } } # Print formatted info ##################################################### sub doprintf { - my %found; - foreach my $repo(@repos) { - my @r = split(/\|/, $repo); - my $dir = $r[0]; - my $url = $r[1]; - open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); - while () { - chomp; - my %pkg; - if (index($ARGV[1], "%i") >=0 ) { - %pkg = parsepackage($_, $dir, $url, 1); - } else { - %pkg = parsepackage($_, $dir, $url, 0); - } - if (not $found{$pkg{'name'}}) { - if ($filter ne "") { - my $match = $pkg{'name'}; - my $cfilter = $filter; - $cfilter =~ s/\*/\.\*/; - if ($match =~ /^$cfilter$/) { - formattedprint(%pkg); - $found{$pkg{'name'}} = 1; - } - } else { - formattedprint(%pkg); - $found{$pkg{'name'}} = 1; - } - } - } - close(REPO); - } + my %found; + foreach my $repo(@repos) { + my ($dir, $url) = split(/\|/, $repo); + open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); + while () { + chomp; + my %pkg; + if (index($ARGV[1], "%i") >=0 ) { + %pkg = parsepackage($_, $dir, $url, 1); + } else { + %pkg = parsepackage($_, $dir, $url, 0); + } + if (not $found{$pkg{'name'}}) { + if ($filter ne "") { + my $match = $pkg{'name'}; + my $cfilter = $filter; + $cfilter =~ s/\*/\.\*/; + if ($match =~ /^$cfilter$/) { + formattedprint(%pkg); + $found{$pkg{'name'}} = 1; + } + } else { + formattedprint(%pkg); + $found{$pkg{'name'}} = 1; + } + } + } + close(REPO); + } } # Show differences between installed and available packages ################ sub diff { - my %found; - my $gotdiff = 0; - foreach my $repo(@repos) { - my @r = split(/\|/, $repo); - my $dir = $r[0]; - my $url = $r[1]; - open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); - while () { - chomp; - my %pkg; - %pkg = parsepackage($_, $dir, $url, 1); - if (not $found{$pkg{'name'}}) { - if ($pkg{'instversion'}) { - if ($pkg{'instversion'} ne $pkg{'version'}."-".$pkg{'release'}) { - if (islocked($pkg{'name'}) eq "no") { - if ($gotdiff == 0){ - print "Differences between installed packages and packages repo:\n\n"; - printf("%-19s %-19s %-19s\n\n","Package","Installed","Available in the repositories"); - $gotdiff = 1; - } - printf("%-19s %-19s %-19s\n", $pkg{'name'}, $pkg{'instversion'}, $pkg{'version'}."-".$pkg{'release'}); - } elsif ($all) { # yeah, it blows, at least avoid to read the locked state twice. - if ($gotdiff == 0){ - print "Differences between installed packages and packages repo:\n\n"; - printf("%-19s %-19s %-19s\n\n","Package","Installed","Available in the repositories"); - $gotdiff = 1; - } - printf("%-19s %-19s %-19s %-19s\n", $pkg{'name'}, $pkg{'instversion'}, $pkg{'version'}."-".$pkg{'release'}, "locked"); - } - } - } - $found{$pkg{'name'}} = 1; - } - } - close(REPO); - } - if ($gotdiff ==0) {print "No differences found\n"}; -} + my $format = shift; my $gotdiff = 0; my %found; -# Show differences between installed and available packages ################ -sub quickdiff { - my %found; - my $gotdiff = 0; - foreach my $repo(@repos) { - my @r = split(/\|/, $repo); - my $dir = $r[0]; - my $url = $r[1]; - open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); - while () { - chomp; - my %pkg; - %pkg = parsepackage($_, $dir, $url, 1); - if (not $found{$pkg{'name'}}) { - if ($pkg{'instversion'}) { - if ($pkg{'instversion'} ne $pkg{'version'}."-".$pkg{'release'} and islocked($pkg{'name'}) eq "no") { - if ($gotdiff == 0){ - print $pkg{'name'}; - $gotdiff = 1; - } else { - print " " . $pkg{'name'}; - } - } - } - $found{$pkg{'name'}} = 1; - } - } - close(REPO); - } - if ($gotdiff != 0) {print "\n"}; + foreach my $repo(@repos) { + my ($dir, $url) = split(/\|/, $repo); + open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); + while () { + chomp; + my %pkg = parsepackage($_, $dir, $url, 1); + next if (($found{$pkg{'name'}}) or (! $pkg{'instversion'})); + $found{$pkg{'name'}} = 1; + if ($pkg{'instversion'} ne $pkg{'version'}."-".$pkg{'release'}) { + next if (($locked{$pkg{'name'}}) and (! $all)); + if (($gotdiff == 0) and ($format ne "quick")) { + print "Differences between installed packages and packages repo:\n\n"; + printf("%-19s %-19s %-19s\n\n","Package","Installed","Available in the repositories"); + } + $gotdiff = 1; + my $lastcol = ($locked{$pkg{'name'}}) ? "locked" : $pkg{'version'}."-".$pkg{'release'}; + print "$pkg{'name'} " if ($format eq "quick"); + printf("%-19s %-19s %-19s\n", $pkg{'name'}, $pkg{'instversion'}, $lastcol) if ($format ne "quick"); + } + } + close(REPO); + } + print "\n" if (($format eq "quick") and ($gotdiff == 1)); + print "No differences found\n" if ($gotdiff == 0); } # Display duplicate packages (found in more than one repo) ################# sub dup { - my %found; - foreach my $repo(@repos) { - my @r = split(/\|/, $repo); - my $dir = $r[0]; - my $url = $r[1]; - open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); - while () { - chomp; - my %pkg; - %pkg = parsepackage($_, $dir, $url, 0); - $found{$pkg{'name'}} .= "###" . $pkg{'path'}."/". $pkg{'name'}.$pkg{'version'}."-".$pkg{'release'}; - } - close(REPO); - } - my $curr = ""; - foreach my $key (sort keys %found) { - my $value = $found{$key}; - $value =~ s/^\#\#\#//; - if (rindex($value, "###") >=0){ - print "* $key\n"; - my @d = split(/\#\#\#/, $value); - foreach my $dup(@d){ - print " $dup\n"; - } - } - } + my %found; + foreach my $repo(@repos) { + my ($dir, $url) = split(/\|/, $repo); + open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); + while () { + chomp; + my %pkg = parsepackage($_, $dir, $url, 0); + $found{$pkg{'name'}} .= "###" . $pkg{'path'}."/". $pkg{'name'}.$pkg{'version'}."-".$pkg{'release'}; + } + close(REPO); + } + foreach my $key (sort keys %found) { + my $value = $found{$key}; + $value =~ s/^\#\#\#//; + if (rindex($value, "###") >=0){ + print "* $key\n"; + my @d = split(/\#\#\#/, $value); + foreach my $dup(@d){ print " $dup\n"; } + } + } } # Show list of dependencies for package #################################### sub depends { - getdependencies($ARGV[1], 1, "") or exiterr("package '$ARGV[1]' not found"); - if (@dependencies) {print "-- dependencies ([i] = installed, [u] = updatable)\n"} - foreach my $dep(@dependencies) { - print "$dep\n"; - } - if (%missingdeps) { - print "\n-- missing packages\n"; - foreach my $dep(sort keys %missingdeps) { - print "$dep from $missingdeps{$dep}\n"; - } - } -} - -# Show compact list of dependencies for package ############################ -sub quickdep { - getdependencies($ARGV[1], 0, "") or exiterr("package '$ARGV[1]' not found"); - foreach my $dep(@dependencies) { - print "$dep "; - } - print "\n"; + my ($j, $checkver) = ($ARGV[0] =~ /^quick/) ? (" ",0) : ("\n",1); + getdependencies($ARGV[1], $checkver, "") or exiterr("package '$ARGV[1]' not found"); + if ((@dependencies) and ($checkver)) {print "-- dependencies ([i] = installed, [u] = updatable)\n"} + print join($j, @dependencies); + if ((%missingdeps) and ($j ne " ")) { + print "\n-- missing packages\n"; + foreach my $dep(sort keys %missingdeps) { + print "$dep from $missingdeps{$dep}\n"; + } + } + print "\n"; } # Show packages directly depending from given package ###################### sub dependent { - my $arg = $ARGV[1]; - my %dp; - if (not $all) { getinstalled(); } - foreach my $repo(@repos) { - my @r = split(/\|/, $repo); - my $dir = $r[0]; - my $url = $r[1]; - open(DEPS, "$dir/PKGDEPS") - or exiterr("could not open $dir/PKGDEPS"); - while () { - chomp; - my $dep = $_; - $dep =~ s/\s+\:.*$//; - s/^.*\: /\,/; - s/$/\,\$/; - if ( /\,\Q$arg\E\,/ ) { - if (not $all) { - if ($installed{$dep}) { - $dp{$dep} = 1; - } - } else { - $dp{$dep} = 1; - } - } - } - close(DEPS); - } - foreach my $res(keys %dp) { - print "$res\n"; - } + my $arg = $ARGV[1]; + my %dp; + getinstalled() unless (($all) or (%installed)); + foreach my $repo(@repos) { + my ($dir, $url) = split(/\|/, $repo); + open(DEPS, "$dir/PKGDEPS") + or exiterr("could not open $dir/PKGDEPS"); + while () { + chomp; + my ($maybe, $deplist) = split /\:/; + # collapse trailing or leading whitespace + $maybe =~ s/\s+$//; $deplist =~ s/^\s+//; + # ensure that arg is surrounded by commas, even if appearing at + # the beginning or the end of the list + $deplist =~ s/^/\,/; $deplist =~ s/$/\,/; + $dp{$maybe} = 1 if (index($deplist,",$arg,") >= 0); + } + close(DEPS); + } + foreach my $res(keys %dp) { + print "$res\n" unless ((not $all) and (! $installed{$res})); + } } -# Install given package #################################################### -sub install { - $curraction = "installed"; - my @args = @_; shift(@args); - getinstalled(); - foreach my $pkgname(@args) { - my %pkg = getpackage($pkgname, 1); - if (not %pkg) { - push(@failtasks, "not found,$pkgname"); - } elsif (getshortstatus(%pkg) ne "[ ]") { - push(@prevtasks, "$pkgname"); - } elsif (downloadpkg(%pkg) and installpkg("", %pkg)) { - push(@donetasks, $pkgname); - } else { - push(@failtasks, "where install failed,$pkgname"); - } - } - printresults(); -} +# Install or update given package ########################################## +sub upinst { + my ($cmd, @args) = @_; my $aa; + ($curraction, $aa) = ($cmd =~ /^up/) ? ("updated","-u") : ("installed",""); -# Update given package ##################################################### -sub update { - $curraction = "updated"; - my @args = @_; shift(@args); - getinstalled(); - foreach my $pkgname(@args) { - my %pkg = getpackage($pkgname, 1); - if (not %pkg) { - push(@failtasks, "not found,$pkgname"); - } elsif (getshortstatus(%pkg) eq "[ ]") { - push(@prevtasks, "$pkgname"); - } elsif (downloadpkg(%pkg) and installpkg("-u ", %pkg)) { - push(@donetasks, $pkgname); - } else { - push(@failtasks, "where update failed,$pkgname"); - } - } - printresults(); + getinstalled() if (! %installed); + if ($root) { + foreach my $repo (@repos) { + my ($dir, $url) = split(/\|/, $repo); + (! -f "$dir/PKGINST") or system("install -D $dir/PKGINST $root$dir/PKGINST"); + } + } + foreach my $pkgname(@args) { + my %pkg = getpackage($pkgname, 1); + if (not %pkg) { + push(@failtasks, "not found,$pkgname"); + } elsif ( ($cmd . getshortstatus(%pkg)) + =~ /^(update.i|update. |install.u|install.i)/ ) { + push(@prevtasks, "$pkgname"); + } elsif (downloadpkg(%pkg) and installpkg($aa, %pkg)) { + push(@donetasks, $pkgname); + } else { + push(@failtasks, "where $cmd failed,$pkgname"); + } + } + printresults(); } # Update out of date packages ############################################## sub sysup { - my %found; - my @diff; - foreach my $repo(@repos) { - my @r = split(/\|/, $repo); - my $dir = $r[0]; - my $url = $r[1]; - open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); - while () { - chomp; - my %pkg; - %pkg = parsepackage($_, $dir, $url, 1); - if (not $found{$pkg{'name'}}) { - if ($pkg{'instversion'}) { - if ($pkg{'instversion'} ne $pkg{'version'}."-".$pkg{'release'} and islocked($pkg{'name'}) eq "no") { - push(@diff, $pkg{'name'}); - } - } - $found{$pkg{'name'}} = 1; - } - } - close(REPO); - } - if (@diff) { - unshift(@diff, "dummy"); # is shifted later in update sub; - update(@diff); - } + my %found; my @diff; + foreach my $repo(@repos) { + my ($dir, $url) = split(/\|/, $repo); + open(REPO, "$dir/PKGREPO") or exiterr("could not open $dir/PKGREPO"); + while () { + chomp; + my %pkg = parsepackage($_, $dir, $url, 1); + next if ($found{$pkg{'name'}}); $found{$pkg{'name'}} = 1; + if ( ($pkg{'instversion'}) and + ($pkg{'instversion'} ne $pkg{'version'}."-".$pkg{'release'}) + and (! $locked{$pkg{'name'}}) ) { + push(@diff, $pkg{'name'}); + } + } + close(REPO); + } + upinst("update",@diff) if (@diff); } sub depinst { - my @toinst; my %seen; - $curraction = "installed"; - my @args = @ARGV; shift(@args); - getinstalled(); - foreach my $pkgname(@args) { - getdependencies($pkgname, 0, ""); - foreach my $dep(@dependencies) { - if (not $seen{$dep}) { - my %pkg = getpackage($dep, 1); - if (%pkg) { - if (getshortstatus(%pkg) eq "[ ]"){ - push(@toinst, $pkg{'name'}); - } - } - $seen{$dep} = 1; - } - } - } - if (@toinst) { - unshift(@toinst, "dummy"); # is shifted later in install sub; - install(@toinst); - } + my @toinst; my %seen; + $curraction = "installed"; + my @args = @ARGV; shift(@args); + getinstalled() if (! %installed); + foreach my $pkgname(@args) { + getdependencies($pkgname, 0, ""); + foreach my $dep(@dependencies) { + next if ($seen{$dep}); $seen{$dep} = 1; + next if ($locked{$dep}); + my %pkg = getpackage($dep, 1); + if ((%pkg) and (getshortstatus(%pkg) eq "[ ]")) { + push(@toinst, $pkg{'name'}); + } + } + } + upinst("install",@toinst) if (@toinst); } diff --git a/scripts/pkg-repgen.pl b/scripts/pkg-repgen.pl index a2d461e..633b02b 100755 --- a/scripts/pkg-repgen.pl +++ b/scripts/pkg-repgen.pl @@ -12,6 +12,7 @@ use warnings; use strict; use Getopt::Long; +use Digest::file qw(digest_file_hex); our $prtget = "/usr/bin/prt-get"; our $prtdir; our $title = "CRUX Packages"; our $header; our $footer; @@ -21,219 +22,218 @@ GetOptions("prtdir=s"=>\$prtdir, "title=s"=>\$title, "header=s"=>\$header, "foot our $compress = "gz"; open CONFIG, "/etc/pkgmk.conf" or die "Could not open /etc/pkgmk.conf"; while () { - $compress = $1 if m/^PKGMK_COMPRESSION_MODE="(.*)"\n/; + $compress = $1 if m/^PKGMK_COMPRESSION_MODE=(.*)(#|$)/; } close CONFIG; +$compress =~ s/["' ]//g; +$prtget .= " --no-std-config --config-set=\"prtdir $prtdir\"" if ($prtdir); + +my @dirlist = glob("*#*.pkg.tar.$compress"); my @packages; if ($#ARGV >= 0) { # single packages - pkgrepo_single(); - pkgdeps_single(); - pkgread(); - pkginst(); + foreach my $pkgname (@ARGV) { + my @hits = grep /^$pkgname#/ @dirlist; + push(@packages,@hits) if (@hits); + } } else { - if ($prtdir) { - $prtget = "$prtget --no-std-config --config-set=\"prtdir $prtdir\""; + @packages = @dirlist; +} + +# Populate some hashes with a single run of prt-get +our %path; our %depends; our %descrip; our %flags; +our %oldDeps; our %oldFlags; our %du; our %md5sums; +fill_hashes_from_prtget(); + +if ($#ARGV >= 0) { + pkg_single("REPO"); pkg_single("DEPS"); +} else { + pkg_dir("REPO"); pkg_dir("DEPS"); +} + +# Generate README and PKGINST +pkgread(); +pkginst(); + +sub fill_hashes_from_prtget { + my @validkeys = @packages; + map { s/#.*// } @validkeys; + open (my $ppf, "$prtget printf '%n^%p^%e^%d^%E^%O^%R\n' |"); + while (<$ppf>) { + my ($name,$repo,$deps,$desc,$haspre,$haspost,$hasreadme) = split /\^/; + next if (! grep { ($_ eq $name) } @validkeys); + $path{$name} = $repo . "/" . $name; + $depends{$name} = $deps; + $desc =~ s/\:/ /g; + $descrip{$name} = $desc; + chomp($hasreadme); + $flags{$name} = join(":", $haspre, $haspost, $hasreadme); } - pkgrepo(); - pkgdeps(); - pkgread(); - pkginst(); + close ($ppf); } -######################## single packages ######################## - -# generate dependencies -sub pkgdeps_single { - print "+ Generating dependencies\n"; - my $hasnew = 0; - foreach my $p (@ARGV) { - my @packages = glob("$p#*.pkg.tar.$compress"); - if ($#packages == 0) { - my $found = 0; - my $package = $packages[0]; - $package =~ s/#.*//; - my $deps = `$prtget printf "%e" --filter="$package"`; - if ($deps ne "") { - my $isnew = `grep "$p .*:" PKGDEPS`; - if ($isnew eq ""){ # package is new, put deps at the end. - open (my $fh, '>>PKGDEPS'); - printf $fh "%-30s : %-s\n", $package, $deps; - close $fh; - $hasnew = 1; - } else { - system("sed -i \"/^$p /s/: .*\$/: $deps/\" PKGDEPS"); - } - } - - } else { - print "Package '$p' not found or duplicate\n" - } - } - if ($hasnew == 1){system("sort -o PKGDEPS PKGDEPS")}; -} - -# generate the main repository file -sub pkgrepo_single { - print "+ Generating repository\n"; - my $hasnew = 0; - foreach my $p (@ARGV) { - my @packages = glob("$p#*.pkg.tar.$compress"); - if ($#packages == 0) { - my $found = 0; - my $package = $packages[0]; - my $name = $package; - $name =~ s/#.*//; - my $du = (-s $package); - my $md5 = `md5sum $package`; - $md5 =~ s/ .*$|\n//g; - my $des=`$prtget printf %d --filter="$name"`; - $des =~ s/:/ /g; - if ($des eq ""){$des = "N.A."}; - my $flags=`$prtget printf %E:%O:%R --filter="$name"`; - if ($flags eq "") {$flags = "no:no:no"} - my $isnew = `grep "$p#" PKGREPO`; - if ($isnew eq ""){ # package is new, put it at the end - open (my $fh, '>>PKGREPO'); - printf $fh "%-s:%-s:%-s:%-s:%-s\n", $package,$du,$md5,$des,$flags; - close $fh; - $hasnew = 1; - } else { - my $newp = "$package:$du:$md5:$des:$flags"; - system("sed -i \"s/^$p#.*\$/$newp/\" PKGREPO"); - } - #printf $fh "%-s:%-s:%-s:%-s\n", $du,$md5,$des,$flags; - } else { - print "Package '$p' not found or duplicate\n" +sub fill_hashes_from_prevrun { + my $oldRepo = shift; + open (my $fh, $oldRepo) or return; + while (<$fh>) { + chomp; + if ($oldRepo eq "PKGDEPS") { + my ($iPkg, $iDep) = split /:/; + $iPkg =~ s/\s+//g; + $iDep =~ s/,/ /g; + $oldDeps{$iPkg} = $iDep; + } elsif ($oldRepo eq "PKGREPO") { + my ($iPkg, $iSize, $iMD5, $iDesc, $iPre, $iPost, $iReadme) = split /:/; + $iPkg =~ s/\s+//g; + $oldFlags{$iPkg} = join (":", $iPre, $iPost, $iReadme); } } - if ($hasnew == 1){system("sort -o PKGREPO PKGREPO")}; + close ($fh); } +# generate dependency map or repository for individual packages +sub pkg_single { + my $db = shift; my $name; + my $status = "+ Generating "; + $status .= ($db eq "REPO") ? "repository\n" : "dependencies\n"; + print $status; + + fill_hashes_from_prevrun("PKG$db"); + my $hasnew = 0; + foreach my $p (@ARGV) { + my @matches = grep /^$p#/, @packages; + if ($#matches != 0) { + print "Package '$p' not found or duplicate\n"; next; + } + my $match = $matches[0]; + $name = $match; + $name =~ s/#.*//; + if ( ($db eq "DEPS") and + ((! $oldDeps{$name}) or ($oldDeps{$name} ne $depends{$name})) ) { + $hasnew = 1; + } elsif ($db eq "REPO") { + $du{$match} = (-s $match); + $md5sums{$match} = digest_file_hex($match,"MD5"); + if (! $descrip{$name}) {$descrip{$name} = "N.A."}; + if (! $flags{$name}) {$flags{$name} = "no:no:no"}; + if (! $oldFlags{$name}) { $hasnew = 1; } + } + } + return unless ($hasnew == 1); + + my $dict = ($db eq "DEPS") ? "depends" : "flags"; + open (my $fh, ">PKG$db.new"); + foreach my $mp (sort keys %$dict) { + $name = $mp; $name =~ s/#.*//; + if ($db eq "REPO") { + printf $fh "%-s:%-s:%-s:%-s:%-s\n", $name, $du{$mp}, + $md5sums{$mp}, $descrip{$name}, $flags{$name}; + } elsif ($db eq "DEPS") { + printf $fh "%-30s:%s\n", $name, $depends{$name}; + } + } + close ($fh); + rename("PKG$db.new", "PKG$db"); +} ######################## full repository ######################## -# generate dependencies -sub pkgdeps { - print "+ Generating dependencies\n"; - my @packages = glob("*#*.pkg.tar.$compress"); - open (my $fh, '>PKGDEPS'); - foreach my $package (@packages) { - $package =~ s/#.*//; - my $deps = `$prtget printf "%e" --filter="$package"`; - if ($deps ne "") { - printf $fh "%-30s : %-s\n", $package, $deps; +# generate dependency map or the repository/index page +sub pkg_dir { + my $db = shift; my %seen; + my $status = "+ Generating "; + $status .= ($db eq "DEPS") ? "dependencies\n" : "repository\n"; + print $status; + + open (my $fh, ">PKG$db"); + if ($db eq "DEPS") { + foreach my $name (@packages) { + $name =~ s/#.*//; next if ($seen{$name}); + if (($depends{$name}) and ($depends{$name} ne "")) { + printf $fh "%-30s : %-s\n", $name, $depends{$name}; + } + $seen{$name} = 1; } - } - close $fh; -} + } elsif ($db eq "REPO") { + our $parity = "odd"; + my $count = 0; + printheader(); + open (my $ih, '>>index.html'); + foreach my $p (@packages) { + chomp($p); + my $date = (stat($p))[9]; + $count++; + my ($name, $version, $url) = ($p, $p, $p); + $name =~ s/#.*//; + $version =~ s/^.*\#//; + $version =~ s/\.pkg\.tar\.[gbx]z*//; + $url =~ s/\#/\%23/; + my $du = (-s $p); + my $md5 = digest_file_hex($p,"MD5"); + $md5 =~ s/ .*$|\n//g; + if (! $descrip{$name}) {$descrip{$name} = "N.A.";} + if (! $flags{$name}) { $flags{$name} = "no:no:no"; } + printf $fh "%-s:%-s:%-s:%-s:%-s\n", $p,$du,$md5,$descrip{$name},$flags{$name}; + print $ih ""; + print $ih "$name"; + print $ih "$version"; + print $ih "$descrip{$name}"; + print $ih "" . isotime($date, 1) . ""; + print $ih "\n"; -# generate the main repository file and index page -sub pkgrepo { - print "+ Generating repository\n"; - my @packages = glob("*#*.pkg.tar.$compress"); - our $odd = "odd"; - my $count = 0; - open (my $fh, '>PKGREPO'); - printheader(); - open (my $ih, '>>index.html'); - foreach my $package (@packages) { - my $date = (stat($package))[9]; - $count++; - $package =~ s/\n//g; - my $name = $package; - $name =~ s/#.*//; - my $du = (-s $package); - my $md5 = `md5sum $package`; - $md5 =~ s/ .*$|\n//g; - my $des=`$prtget printf %d --filter="$name"`; - $des =~ s/:/ /g; - if ($des eq ""){$des = "N.A."}; - my $flags=`$prtget printf %E:%O:%R --filter="$name"`; - if ($flags eq "") {$flags = "no:no:no"} - printf $fh "%-s:%-s:%-s:%-s:%-s\n", $package,$du,$md5,$des,$flags; - my $version = $package; - $version =~ s/^.*\#//; - $version =~ s/\.pkg\.tar\.[gbx]z*//; - print $ih ""; - print $ih "$name"; - my $url = $package; - $url =~ s/\#/\%23/; - print $ih "$version"; - print $ih "$des"; - print $ih "" . isotime($date, 1) . ""; - print $ih "\n"; - - if ($odd eq "odd") { $odd = "even"; } - else { $odd = "odd"; } + if ($parity eq "odd") { $parity = "even"; } + else { $parity = "odd"; } + } + close $ih; + printfooter($count); } close $fh; - close $ih; - printfooter($count); } # generate README file sub pkgread { print "+ Generating README\n"; - my @packages = glob("*#*.pkg.tar.$compress"); open (my $fh, '>PKGREAD'); print $fh "# README files for repository. Do NOT remove this line.\n"; - foreach my $package (@packages) { - $package =~ s/#.*//; - my $path = `$prtget path $package`; - $path =~ s/\n//g; - if (-f "$path/README"){ - print $fh "##### PKGREADME: $package\n"; - open(my $readme, "$path/README"); - while (<$readme>){ - my $line = $_; - print $fh $line; - } + foreach my $name (@packages) { + $name =~ s/#.*//; + if (-f "$path{$name}/README"){ + print $fh "##### PKGREADME: $name\n"; + open(my $readme, "$path{$name}/README"); + while (<$readme>){ print $fh $_; } close($readme); } } close $fh; } -# generate pre-post install scripts file +# generate pre-install scripts file sub pkginst { print "+ Generating scripts\n"; open (my $fh, '>PKGINST'); - print $fh -" -#!/bin/bash + print $fh '#!/usr/bin/env bash # -# PKGINST: pre-post install scripts for CRUX packages -"; - my @packages = glob("*#*.pkg.tar.$compress"); - foreach my $package (@packages) { - $package =~ s/#.*//; - my $path = `$prtget path $package`; - $path =~ s/\n//g; - my $normal= $package; - $normal =~ s/[^[:alnum:]]/_/g; - if (-f "$path/pre-install"){ - print $fh "${normal}_pre_install() {\n"; - open(my $pre, "$path/pre-install"); - while (<$pre>){ - my $line = $_; - print $fh $line; - } - close($pre); - print $fh "}\n\n"; +# PKGINST: pre- and post-install scripts for CRUX packages +# +run_script() { + case "$1" in +'; + foreach my $name (@packages) { + $name =~ s/#.*//; + foreach my $when ("pre", "post") { + if (-f "$path{$name}/${when}-install"){ + print $fh "$name.$when)\n"; + open(my $rs, "$path{$name}/${when}-install"); + while (<$rs>){ + chomp; + if (! m/^#!.*sh/) { print $fh " $_\n"; } + } + close($rs); + print $fh " ;;\n"; } - if (-f "$path/post-install"){ - print $fh "${normal}_post_install() {\n"; - open(my $post, "$path/post-install"); - while (<$post>){ - my $line = $_; - print $fh $line; - } - close($post); - print $fh "}\n\n"; } } - print $fh "\n\n"; - print $fh 'if [ ! -z "$1" ]; then $1; fi'; + print $fh "esac\n}\n\n"; + print $fh '[ "$1" ] && [[ "$2" == @(pre|post) ]] && run_script "$1.$2"'; print $fh "\n"; close $fh; } @@ -243,16 +243,16 @@ sub pkginst { sub printheader { open (my $ih, '>index.html'); - print $ih < EOH - print $ih " $title\n"; + print $ih " $title\n"; - print $ih < body { @@ -291,55 +291,50 @@ EOH EOH - print $ih "

$title

\n"; - if ($header) { - open(FILE, $header) or die "Couldn't open header file"; - while () { - print $ih " " . $_; - } - close(FILE); - } + print $ih "

$title

\n"; + if ($header) { + open(FILE, $header) or die "Couldn't open header file"; + while () { + print $ih " " . $_; + } + close(FILE); + } - print $ih " \n"; - print $ih " "; - print $ih ""; - print $ih "\n"; - close($ih); + print $ih "
PortVersionDescriptionLast modified
\n"; + print $ih " "; + print $ih ""; + print $ih "\n"; + close($ih); } sub printfooter { - my $count = $_[0]; + my $count = $_[0]; open (my $ih, '>>index.html'); - print $ih "
PortVersionDescriptionLast modified
\n"; - print $ih "

$count packages

\n"; - if ($footer) { - open(FILE, $footer) or die "Couldn't open footer file"; - while () { - print $ih " " . $_; - } - close(FILE); - } - print $ih "

Generated by pkg-repgen on " . isotime() . ".

\n"; - print $ih <\n"; + print $ih "

$count packages

\n"; + if ($footer) { + open(FILE, $footer) or die "Couldn't open footer file"; + while () { + print $ih " " . $_; + } + close(FILE); + } + print $ih "

Generated by pkg-repgen on " . isotime() . ".

\n"; + print $ih < EOH - close($ih); - + close($ih); } sub isotime { - my $time = (shift or time); - my $accuracy = (shift or 2); - my @t = gmtime ($time); - my $year = $t[5] + 1900; - my $month = sprintf("%02d", $t[4] + 1); - my $day = sprintf("%02d", $t[3]); + my $time = (shift or time); + my $accuracy = (shift or 2); + my @t = gmtime ($time); + my $year = $t[5] + 1900; + my $month = sprintf("%02d", $t[4] + 1); + my $day = sprintf("%02d", $t[3]); - if ($accuracy == 1) { - return "$year-$month-$day"; - } - - return "$year-$month-$day " . sprintf("%02d:%02d:%02d UTC", $t[2], $t[1], $t[0]); + return "$year-$month-$day" if ($accuracy == 1); + return "$year-$month-$day " . sprintf("%02d:%02d:%02d UTC", $t[2], $t[1], $t[0]); } -