#!/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: To 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 could not be found.
#
# Execute ppkg without arguments to display the options.
#
# See the CONFIG part at the top of the code for more options.
#
# Requirements
# ~~~~~~~~~~~~
# ppkg is using Net::FTP. You can find it at http://search.cpan.org/~jhi/perl-5.8.1/lib/Net/FTP.pm
# 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
# ~~~~~~
# http://jaffhar.ath.cx
# jaffhar _at_ arcor _dot_ de
use strict;
use Net::FTP;
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CONFIG;
my $use_random = 'no';
# use a random server? (no/yes)
my $default_host = 'ftp://ftp.openbsd.org/pub/OpenBSD/';
# your default ftp mirror (including the location of the OpenBSD directory)
# see at the bottom of this file or http://www.openbsd.org/ftp.html#ftp
# it is recommend to use your local mirror (if avaiable)
# (dns problems? use: ftp://129.128.5.191/pub/OpenBSD/)
my $pkg_add_args = '';
# specify the arguments pkg_add(1) should use
# e.g. set to '-n' to only test this script
#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< CONFIG;
my ($i,$k,$host,$rs,@exe,%pkgs,%count,%sv);
my $def = "\033[0m";
my $bold = "\033[1m";
my $uline = "\033[4m";
if(!@ARGV) {
print "usage: ".$bold."ppkg".$def." [-".$bold."r".$def."] ".$uline."name".$def
." [".$uline."name".$def." ".$uline."name".$def." etc.]\n";
print "\t".$uline."name".$def."\tsearches for /name/i\n";
print "\t-".$bold."r".$def."\tuse a random server (default: $use_random)\n";
print "\n\texample: ppkg -r xmms mp3\n";
exit(1);
}
if($ARGV[0] eq '-r') { shift(@ARGV); $use_random = 'yes' }
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 = $release.'/packages/'.$machine.'/';
if($use_random eq 'yes') { $host = random_host(); $rs = " (random)" }
else { $host = $default_host }
print "your system: $system $release $machine\n";
print "your ftp-dir: ".$host.$path.$rs."\n";
if($pkg_add_args) {
print "your pkg_add arguments: ".$pkg_add_args."\n";
$pkg_add_args = $pkg_add_args." ";
}
my ($t_host,$t_path) = $host =~ /^ftp:\/\/(.*?)\/(.*)$/;
my $ftp = Net::FTP->new($t_host) || die "could not connect: $!\n";
print "connection OK. ";
$ftp->login('anonymous') || die $ftp->message;
print "login OK. ";
$ftp->cwd($t_path.$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 ".$pkg_add_args.$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 ".$pkg_add_args.$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 ".$pkg_add_args.$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" }
sub random_host {
my @hosts = ("ftp://ftp.openbsd.org/pub/OpenBSD/", # Master Site (Canada)
"ftp://ftp.it.net.au/mirrors/OpenBSD/", # Australia (Perth)
"ftp://ftp.planetmirror.com/pub/OpenBSD/", # Australia (Sydney)
"ftp://mirror.pacific.net.au/OpenBSD/", # Australia (Sydney)
"ftp://openbsd.wiretapped.net/pub/OpenBSD/", # Australia (Sydney)
"ftp://gd.tuwien.ac.at/opsys/OpenBSD/", # Australia (Vienna)
"ftp://playboy.wu-wien.ac.at/pub/OpenBSD/", # Australia (Vienna)
"ftp://openbsd.rug.ac.be/pub/OpenBSD/", # Belgium (Ghent)
"ftp://ftp.openbsd.org.br/pub/OpenBSD/", # Brazil (Curitiba)
"ftp://ftp.das.ufsc.br/pub/OpenBSD/", # Brazil (Santa Cantarina)
"ftp://ftp.ca.openbsd.org/pub/OpenBSD/", # Canada (Edmonton)
"ftp://ftp.shellhung.org/pub/OpenBSD/", # China (Hong Kong)
"ftp://ftp.openbsd.cz/pub/OpenBSD/", # Czech Republic (Prague)
"ftp://sunsite.dk/mirrors/openbsd/", # Denmark (Aalborg)
"ftp://ftp.fi.debian.org/pub/OpenBSD/", # Finland
"ftp://ftp.jyu.fi/pub/OpenBSD/", # Finland (Jyväskylä)
"ftp://ftp.ac-creteil.fr/OpenBSD/", # France
"ftp://ftp.bsdfr.org/pub/OpenBSD/", # France (Paris)
"ftp://ftp.club-internet.fr/pub/OpenBSD/", # France (Paris)
"ftp://ftp.fr.openbsd.org/pub/OpenBSD/", # France (Paris)
"ftp://ftp.de.openbsd.org/unix/OpenBSD/", # Germany (Berlin)
"ftp://ftp.tu-clausthal.de/pub/OpenBSD/", # Germany (Clausthal)
"ftp://ftp.freenet.de/pub/ftp.openbsd.org/pub/OpenBSD/", # Germany (Düsseldorf)
"ftp://openbsd.informatik.uni-erlangen.de/pub/OpenBSD/", # Germany (Erlangen)
"ftp://ftp-stud.fht-esslingen.de/pub/OpenBSD/", # Germany (Esslingen)
"ftp://pandemonium.tiscali.de/pub/OpenBSD/", # Germany (Frankfurt)
"ftp://openbsd.bay13.net/pub/OpenBSD/", # Germany (Hamburg)
"ftp://ftp.leo.org/pub/OpenBSD/", # Germany (München)
"ftp://ftp.uni-stuttgart.de/pub/OpenBSD/", # Germany (Stuttgart)
"ftp://ftp.fh-wolfenbuettel.de/pub/os/openbsd/", # Germany (Wolfenbüttel)
"ftp://filoktitis.noc.uoa.gr/pub/OpenBSD/", # Greece (Athens)
"ftp://ftp.physics.auth.gr/pub/mirrors/OpenBSD/OpenBSD/", # Greece (Thessaloniki)
"ftp://ftp.duth.gr/pub/OpenBSD/", # Greece (Thrace)
"ftp://ftp.fsn.hu/pub/OpenBSD/", # Hungary
"ftp://ftp.esat.net/pub/OpenBSD/", # Ireland (Dublin)
"ftp://na.mirror.garr.it/mirrors/OpenBSD/", # Italy (Napoli)
"ftp://ftp.openbsd.it/pub/Unix/OpenBSD/", # Italy (Napoli)
"ftp://ftp.netlab.is.tsukuba.ac.jp/pub/os/OpenBSD/", # Japan (Ibaraki)
"ftp://ftp.iij.ad.jp/pub/OpenBSD/", # Japan (Tokyo)
"ftp://ftp.jp.openbsd.org/pub/OpenBSD/", # Japan (Tokyo)
"ftp://ftp.kddlabs.co.jp/OpenBSD/", # Japan (Tokyo)
"ftp://ftp.openbsd.lt/pub/OpenBSD/", # Lithuania
"ftp://ftp.nl.uu.net/pub/OpenBSD/", # The Netherlands (Amsterdam)
"ftp://ftp.calyx.nl/pub/OpenBSD/", # The Netherlands (Amsterdam)
"ftp://ftp.nluug.nl/pub/OpenBSD/", # The Netherlands (Utrecht)
"ftp://ftp.inet.no/pub/OpenBSD/", # Norway (Oslo)
"ftp://ftp.uninett.no/pub/OpenBSD/", # Norway (Oslo)
"ftp://sunsite.icm.edu.pl/pub/OpenBSD/", # Poland
"ftp://ftp.man.szczecin.pl/pub/BSD/OpenBSD/", # Poland (Szczecin)
"ftp://ftp.physics.uvt.ro/pub/OpenBSD/", # Romania (Timisoara)
"ftp://ftp.gamma.ru/pub/OpenBSD/", # Russia (Moscow)
"ftp://ftp.radio-msu.net/pub/OpenBSD/", # Russia (Moscow)
"ftp://ftp.isu.net.sa/pub/mirrors/ftp.openbsd.org/pub/OpenBSD/", # Saudi Arabia
"ftp://ftp.rediris.es/mirror/OpenBSD/", # Spain (Madrid)
"ftp://ftp.stacken.kth.se/pub/OpenBSD/", # Sweden (Stockholm)
"ftp://ftp.sunet.se/pub/OpenBSD/", # Sweden (Uppsala)
"ftp://ftp.solnet.ch/mirror/OpenBSD/", # Switzerland
"ftp://sunsite.cnlab-switch.ch/pub/OpenBSD/", # Switzerland (Zürich)
"ftp://openbsd.csie.nctu.edu.tw/pub/OpenBSD/", # Taiwan
"ftp://openbsd.nsysu.edu.tw/pub/OpenBSD/", # Taiwan
"ftp://ftp.tku.edu.tw/pub/OpenBSD/", # Taiwan (TamSui)
"ftp://ftp.linux.org.tr/pub/OpenBSD/", # Turkey
"ftp://ftp.openbsd.org.ua/pub/OpenBSD/", # Ukraine (Kiev)
"ftp://ftp.plig.org/pub/OpenBSD/", # United Kingdom (London)
"ftp://ftp5.usa.openbsd.org/pub/OpenBSD/", # USA (Redwood City, CA)
"ftp://ftp3.usa.openbsd.org/pub/OpenBSD/", # USA (Boulder, CO)
"ftp://ftp.lug.udel.edu/pub/OpenBSD/", # USA (Newark, DE)
"ftp://reflection.ncsa.uiuc.edu/pub/OpenBSD/", # USA (Champaign, IL)
"ftp://ftp.src.uchicago.edu/pub/openbsd/", # USA (Chicago, IL)
"ftp://rt.fm/pub/OpenBSD/", # USA (Lake in the Hills, IL)
"ftp://ftp7.usa.openbsd.org/pub/os/OpenBSD/", # USA (West Lafayette, IN)
"ftp://ftp.groupbsd.org/pub/OpenBSD/", # USA (Hillsborough, NC)
"ftp://ftp.cse.buffalo.edu/pub/OpenBSD/", # USA (Buffalo, NY)
"ftp://ftp.crimelabs.net/pub/OpenBSD/", # USA (New York, NY)
"ftp://openbsd.mirrors.pair.com/", # USA (Pittsburgh, PA)
"ftp://carroll.cac.psu.edu/pub/OpenBSD/", # USA (State College, PA)
"ftp://mirrors.rcn.net/pub/OpenBSD/", # USA (Fairfax, VA)
"ftp://openbsd.secsup.org/pub/openbsd/", # USA (Fairfax, VA)
"ftp://ftp.tux.org/bsd/openbsd/", # USA (Springfield, VA)
"ftp://mirror.cs.wisc.edu/pub/mirrors/OpenBSD/" # USA (Madison, WI)
);
my $rand_hosts = int(rand($#hosts+1));
return $hosts[$rand_hosts];
}