#!/bin/bash # THIS FXP PACKAGE MANAGER IS EXPERIMENTAL # YOU'VE BEEN WARNED! # ~ THE MANAGEMENT CONF=${CONF:-/etc/slackpkg} SOURCE=$(sed -e 's/^[[:blank:]]*//' $CONF/mirrors | grep -m1 -e "^\([a-z]\)") TMP=${TMP:-/tmp/freepkg} FXP_TAG=${FXP_TAG:-"_FXP"} FXP_DIR=${SOURCE}fxp PKG_LIST=PKGLIST LOCAL_PKGS=/var/log/packages ALL_REQS="" GOOD_COLOR=2 OK_COLOR=6 BAD_COLOR=1 # how are we going to communicate with the server? wget or ln? echo $SOURCE | grep -E '^\s*file:/' > /dev/null if [[ $? == 0 ]] ; then SOURCE_TYPE=DIR FXP_DIR=${FXP_DIR#*file:/} else SOURCE_TYPE=WEB fi # communication routines function message { tput setaf $GOOD_COLOR ; echo -n "[freepkg] " ; tput sgr 0 ; echo "$@" } function error { tput setaf $BAD_COLOR ; echo -n "[freepkg] " ; tput sgr 0 ; echo "$@" ; exit 1 } # other functions function getpkg { local url="$1" if [[ $SOURCE_TYPE == WEB ]] ; then wget -nv "$url" else if [ -f "$url" ] ; then ln -sv "$url" ./$(basename $1) else return 1 fi fi } function pkgName { local a=${1%-*} local b=${a%-*} echo ${b%-*} } function pkgVersion { local a=${1%-*} local b=${a%-*} echo ${b##*-} } function pkgArch { error not implemented } function pkgBuild { error not implemented } function getPackageList { mkdir -p $TMP cd $TMP rm $PKG_LIST &> /dev/null getpkg $FXP_DIR/$PKG_LIST || error "package list $FXP_DIR/$PKG_LIST not found" } function packageByName { local pname="$1" local packages="$2" local p="" for p in $packages ; do if [[ $(pkgName $p) == "$pname" ]] ; then echo "$p" break fi done } function listOfNames { local packages="$1" local p="" for p in $packages ; do echo $(pkgName $p) done } function listRepoPackages { local p="" local pname="" local packages="" local installed="" local installed_names="" local iver="" local pretty_iver="" getPackageList packages=$(cat $PKG_LIST) cd $LOCAL_PKGS installed=$(/bin/ls *$FXP_TAG) installed_names=$(listOfNames "$installed") message "available remote packages:" message "name version [installed version]" for p in $packages ; do iver="" pretty_iver="" pname=$(pkgName $p) echo $installed_names | grep $pname &> /dev/null if [[ $? == 0 ]] ; then iver=$(pkgVersion $(packageByName $pname "$installed")) pretty_iver=" [$iver]" fi echo -n $pname $(pkgVersion $p) if [[ $(pkgVersion $p) == $iver ]] ; then tput setaf $OK_COLOR else tput setaf $BAD_COLOR fi echo -n "$pretty_iver" tput sgr 0 echo done } function listLocalPackages { local p="" local packages="" cd $LOCAL_PKGS packages=$(/bin/ls *$FXP_TAG) message "installed packages:" for p in $packages ; do echo $(pkgName $p) $(pkgVersion $p) done } function installPackage { local pname="$1" local p="" local foundFlag="false" local packages="" if [ -z $pname ] ; then error "which package do you want to install?" fi cd $LOCAL_PKGS packages=$(/bin/ls *) listOfNames "$packages" | grep '^'$pname'$' > /dev/null if [[ $? == 0 ]] ; then message package $pname already installed return 0 fi cd $TMP getPackageList for p in $(cat $PKG_LIST) ; do if [[ $(pkgName "$p") == $pname ]] ; then foundFlag=true rm $p $p.asc &> /dev/null getpkg $FXP_DIR/$p || error package $p not found getpkg $FXP_DIR/$p.asc || error package $p missing signature gpg --verify $p.asc || error bad signature installpkg $p break fi done if [[ $foundFlag == false ]] ; then error package $pname not found fi } function listReqAux { local pname="$1" local reqs="" local p="" cd $TMP rm $pname.req &> /dev/null getpkg $FXP_DIR/$pname.req if [[ $? != 0 ]] ; then error "package $pname dependency record not found" fi reqs=$(cat $pname.req) if [ ! -z "$reqs" ] ; then for p in $reqs ; do ALL_REQS="$ALL_REQS $p" listReqAux "$p" done fi ALL_REQS=$(echo $ALL_REQS | xargs -n1 | sort -u | xargs) } function listReq { local pname="$1" if [ -z $pname ] ; then error "which package do you want to examine?" fi ALL_REQS="" listReqAux "$pname" if [ -z "$ALL_REQS" ] ; then message "package $pname has no prerequisites" else message "package $pname requires:" echo $ALL_REQS fi } function installReq { local pname="$1" local p="" listReq "$pname" if [ -z "$ALL_REQS" ] ; then installPackage "$pname" else message "install everything? (Y/n)" read -n 1 foo ; echo if [[ $foo == "n" || $foo == "N" ]] ; then error "installation aborted" fi for p in $ALL_REQS ; do installPackage $p done installPackage $pname fi } function freepkgHelp { message 'usage: freepkg [ i | ir | r | l | u | help ]' echo message 'i [pkg] - install package' message 'ir [pkg] - install package and its prerequisites' message 'lr [pkg] - list package prerequisites' message 'r [pkg] - list remote fxp packages' message 'l [pkg] - list locally installed fxp packages' message 'u [pkg] - upgrade package' message 'ur [pkg] - upgrade package and its prerequisites' message 'help - print this message' } #################################################################### # action #################################################################### if [[ "$1" == "i" ]] ; then installPackage "$2" elif [[ "$1" == "ir" ]] ; then installReq "$2" elif [[ "$1" == "lr" ]] ; then listReq "$2" elif [[ "$1" == "r" ]] ; then listRepoPackages elif [[ "$1" == "l" ]] ; then listLocalPackages elif [[ "$1" == "u" ]] ; then upgradePackage elif [[ "$1" == "ur" ]] ; then upgradeReq elif [[ "$1" == "help" || "$1" == "--help" ]] ; then freepkgHelp else freepkgHelp exit 1 fi exit 0