#!/usr/bin/perl
#
# Description
# ~~~~~~~~~~~
# ppkg lets you search for packages on OpenBSD ftp server. For example, if you are looking for perl lib packages and you don't know the version number, you
# search for "libwww" and get a list of all packages matching /libwww/i. After this you can install a package by choosing its number.
#
# Note: For install a package you need to be logged in as root.
#
# If you get the error message: "No such file or directory" while trying to install, you are probably not root and the pkg_add command is not found.
#
# Requirements
# ~~~~~~~~~~~~
# ppkg is using Net::FTP. You can find it at [url]http://search.cpan.org/~jhi/perl-5.8.1/lib/Net/FTP.pm[/url]
# Try: perl -MCPAN -e 'install "Net::FTP"'
#
# Installation
# ~~~~~~~~~~~~
# (Save this file to your harddisk.)
#
# $ su
# $ mv ppkg.pl /usr/local/bin/ppkg
# $ chmod +x /usr/local/bin/ppkg
#
# You have to log in again for the changes to take effect.
#
# Author
# ~~~~~~
# [url]http://jaffhar.ath.cx[/url]
# jaffhar _at_ arcor _dot_ de
use strict;
use Net::FTP;
my ($i,$k,@exe,%pkgs,%count,%sv);
my $host = 'ftp.openbsd.org';
@ARGV || die "usage: ppkg <name> [<name> <name> etc.] (searches for /name/i)";
open(OS,"uname -srm|") || die "error when trying 'uname -srm': $!\n";
my ($system,$release,$machine) = split(/ /,<OS>);
close(OS);
if($system eq 'OpenBSD') {
if($release && chomp($machine)) {
my $path = '/pub/'.$system.'/'.$release.'/packages/'.$machine;
print "your system: $system $release $machine\n";
print "your ftp-dir: [url]ftp://[/url]".$host.$path."\n";
my $ftp = Net::FTP->new($host) || die "could not connect: $!\n";
print "connection OK. ";
$ftp->login('anonymous') || die $ftp->message;
print "login OK. ";
$ftp->cwd($path) || die $ftp->message;
print "cwd OK.\nsearching for matching files...\n";
foreach ($ftp->ls) {
my $file = $_;
foreach (@ARGV) {
if($file =~ /$_/i) {
$pkgs{$_} = $pkgs{$_}.":$file";
$i=1;
}
}
}
if($i)
{
$i=0;
foreach (keys(%pkgs)) {
print "total\t$_\n~~~~~\t";
print "~" x length($_);
print "\n";
my @array = split(/:/,$pkgs{$_});
my $j;
foreach (@array) { if($_) { $i++; $j++; print "$i\t$j\t$_\n"; $exe[$i] = $_; } }
$count{$_} = $j;
print "\n";
}
print "total:\t$i matches found\n";
foreach (@ARGV) {
$count{$_} = 0 if !$count{$_};
print "$_:\t$count{$_} matches found\n";
}
print "\nyou have the following options:\n";
print " - enter one 'total' package number to install [e.g. 1]\n";
print " - enter more than one 'total' package number to install [e.g. 1 2 15 8]\n";
print " - enter a range of 'total' package numbers to install [e.g. 1-5]\n";
print " - enter 'p<number>' to install all packages from one argument of your search query [e.g. p4]\n";
my $j;
foreach (keys(%pkgs)) {
$j++;
print " |- p$j > $_ ($count{$_} packages)\n";
$sv{$j} = $_;
}
print " - you can combine all these options [e.g. 1 16-21 p1 7 p2]\n";
print " * any other key to cancel\n";
print "install: "; my $input = <STDIN>;
my @pkgs = split(/ /,$input);
foreach (@pkgs) {
$k++;
if($_ =~ /^([0-9]+)$/) {
if($exe[$1]) {
my $cmd = "pkg_add [url]ftp://[/url]".$host.$path."/".$exe[$1];
print "#cmd($k) pkg($1)\ttrying: $cmd\n";
open(CMD,"$cmd|") or print "#cmd($k) pkg($1)\terror installing package: $!\n";
next unless <CMD>;
}
else { print "#cmd($k) pkg($1)\tthere is no such package number!\n" }
}
elsif($_ =~ /^([0-9]+)\-([0-9]+)$/) {
if($1 >= $2) { print "#cmd($k)\terror in package number range!\n" }
else {
for(my$m=$1;$m<=$2;$m++) {
if($exe[$m]) {
my $cmd = "pkg_add [url]ftp://[/url]".$host.$path."/".$exe[$m];
print "#cmd($k) pkg($m)\ttrying: $cmd\n";
open(CMD,"$cmd|") or print "#cmd($k) pkg($m)\terror installing package: $!\n";
next unless <CMD>;
}
else { print "#cmd($k) pkg($m)\tthere is no such package number!\n" }
}
}
}
elsif($_ =~ /^p([0-9]+)$/) {
if($sv{$1}) {
my $j;
my $hash = $pkgs{$sv{$1}};
my @array = split(/:/,$hash);
foreach (@array) {
if($_) {
$j++;
my $cmd = "pkg_add [url]ftp://[/url]".$host.$path."/".$_;
print "#cmd($k) pkg(p$1:$j)\ttrying: $cmd\n";
open(CMD,"$cmd|") or print "#cmd($k) pkg(p$1:$j)\terror installing package: $!\n";
next unless <CMD>;
}
}
}
else { print "#cmd($k) pkg(p$1)\tthere is no such option!\n" }
}
else { print "cancelled. bye!\n"; last }
}
}
else { print "sorry, no matches found.\n" }
$ftp->quit;
}
else { die "error detecting release version or machine name!\n" }
}
else { die "you need an OpenBSD system!\n" }