#! /bin/sh # Copyright (c) 2003-2007 Laurence Tratt # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. PROGNAME="packagesbootstrap" VERSION="0.02 (2007/04/08) Copyright (C)Laurence Tratt 2003-2007" # # Set up the defaults # default_ftpserver="ftp://ftp.openbsd.org/pub/OpenBSD/" # Determine whether we're running -current or -stable dmesg | head -1 | egrep "OpenBSD [0-9]+\.[0-9]+-" > /dev/null if [ $? -eq 0 ]; then # -current default_osversion="snapshot" else # -stable default_osversion=`uname -r` fi # Default architecture default_arch=`arch -s` # Default dir to download packages to if [ -d /usr/ports/packages/$default_arch/all ]; then default_output=/usr/ports/packages/$default_arch/all else default_output="." fi # Whether to prompt users when multiple matches are found for a given package default_prompt=1 # # Process the program input # argserror=0 ftpserver=$default_ftpserver osversion=$default_osversion arch=$default_arch output=$default_output prompt=$default_prompt set -- `getopt f:o:a:d:lh $*` if [ $? -ne 0 ]; then argserror=1 else for i; do case "$i" in -f) ftpserver=$2; shift; shift;; -h) argserror=1; shift; break;; -p) prompt=$2; shift; shift;; -o) osversion=$2; shift; shift;; -a) arch=$2; shift; shift;; -l) prompt=0; shift;; -d) output=$2; shift; shift;; --) shift; break;; esac done fi if [ $argserror -eq 0 ]; then if [ $# -gt 1 ]; then argserror=1 else packagestmp=`mktemp` if [ $# -eq 0 ]; then pkg_info | cut -d " " -f 1 > $packagestmp else cat $1 | cut -d " " -f 1 > $packagestmp fi fi fi if [ $argserror -ne 0 ]; then os_release=`uname -r` cat << EOF $PROGNAME $VERSION Usage: $PROGNAME [] [] is either a list of package names, separated by newlines, or the output from the pkg_info command. If is not specified, the list of packages installed on this machine will be used. Options: -f Default: '$default_ftpserver' FTP server to download binary packages from. -o Default: '$default_osversion' OS version number. e.g. '$os_release' or 'snapshot' -a Default: '$default_arch' Architecture to download packages for. e.g. 'i386' or 'sparc' -d Default: '$default_output' Directory to save packages to. -l Default: Off Do not prompt if multiple matches found. EOF return 1 fi # # Download packages # function unique_package_name { if [ "$2" = "" ]; then echo $1 return fi echo "$1 $2" | sed "s/ /__unique__/" } if [ $osversion = "snapshot" ]; then ftp_dir=snapshots/packages/$arch else ftp_dir=$osversion/packages/$arch fi ftplisttmp=`mktemp` ftptmp=`mktemp` echo "cd $ftp_dir\nls *" | ftp -a -V $ftpserver/ > $ftplisttmp if [ $? -ne 0 ]; then echo "Error retrieving directory listing from $ftpserver.\n\nCheck the server name and path and try again." return 1 fi cat $ftplisttmp | egrep "^[drwx-]+" | awk 'gsub(" +", " ")' | cut -d " " -f 9 > $ftptmp rm -f $ftplisttmp to_download="" matched="" nomatches="" for complete_package_name in `cat $packagestmp`; do package_name_tmp=`echo $complete_package_name | sed "s/-[0-9][^-]*/ /"` package_name=`echo $package_name_tmp | cut -d " " -f 1` package_name_re=`echo $package_name | sed "s/[+]/[+]/g"` package_flavour=`echo "$package_name_tmp " | cut -d " " -f 2` echo $matched | egrep "[[:<:]]$package_name[[:>:]]" > /dev/null if [ $? -ne 0 ]; then matched="$matched $package_name" matches="" for match in `egrep "^$package_name_re-[0-9]" $ftptmp`; do if [ "$package_flavour" != "" ]; then echo $match | grep -e "$package_flavour.tgz\$" > /dev/null if [ $? -eq 0 ]; then matches="$matches $match" fi else potential_match_tmp=`echo $match | sed "s/.tgz$//" | sed "s/-[0-9][^-]*/ /"` potential_match_flavor=`echo "$potential_match_tmp " | cut -d " " -f 2` if [ "$potential_match_flavor" = "" ]; then matches="$matches $match" fi fi done if [ `echo $matches | wc -w` -eq 0 ]; then echo "Found no matches for $complete_package_name." nomatches="$nomatches $complete_package_name" elif [ `echo $matches | wc -w` -eq 1 ]; then echo "Matched for $complete_package_name:$matches." todownload="$todownload $matches" else echo "Multiple matches found for $complete_package_name." echo -n " " for match in `echo $matches`; do echo -n " $match" done echo for match in `echo $matches`; do if [ $prompt -eq 0 ]; then todownload="$todownload $match" else echo -n " $match... " echo -n "download? [Y/n] " read answer if [ "$answer" != "n" ]; then todownload="$todownload $match" fi fi done fi fi done for package in `echo $todownload`; do echo echo "ftp $ftpserver/$ftp_dir/$package" ftp -V -o $output/$package $ftpserver/$ftp_dir/$package done if [ "$nomatches" != "" ]; then echo "\nWarning: no matches were found for the following packages:" for complete_package_name in `echo $nomatches`; do echo " $complete_package_name" done fi rm -f $packagestmp $ftptmp $ftplisttmp