#!/bin/sh
# @vasm: vpkg
# @level: root
# @description: install package from the internet
#
# (c) Kocil, 2003
# (c) Vector Linux, 2003

## This is a self called script to make a pkglist
if [ "$1" = "--download" ]; then
    echo "============================================================"
    echo "Downloading ..." 
    echo "Hit <OK> after finished" 
    sleep 2
    shift
    cd $1
    shift
    DOWNLOAD_URL=$1
    shift
    echo "DOWNLOAD URL = $DOWNLOAD_URL"
    while [ "$1" ]; do
	DNAME=`dirname $1`
	BNAME=`basename $1 .tgz`
        echo
	echo "----------------------------------------------------------------"
	echo "DOWNLOAD FILE =  $DNAME/$BNAME.*"
	wget --passive-ftp -nv -N -P $DNAME $DOWNLOAD_URL/$DNAME/$BNAME.*
	if [ $? != 0 ]; then
	    echo "##### ERROR ERROR ERROR ERROR ERROR ERROR #####"
	    sleep 3
	fi
	shift
    done
    echo
    echo "Downloading is finished."
    echo "Press <OK> to continue with install"
    echo "or <Cancel> if you see any ERROR"
    exit 0
elif [ "$1" = "--super-vecpkg" ]; then
   echo -n "Waiting super-vecpkg to finish ... "
   export PATH="$PATH:/sbin:/usr/sbin:/usr/X11R6/bin:/usr/bin:/usr/bin"
   $0
   exit 0
elif [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
   echo "vecpkg - Vector Linux package installaer & remover"
   echo "usage : vecpkg"
   echo ""
   echo "See /etc/vecpkg.conf for the global configuration"
   exit 0
fi

if [ ! $UID = 0 ]; then
    if [ "$DISPLAY" ]; then
	xhost +si:localuser:root
	exec xterm -geometry 60x1 -title "Super-VECPKG" -e su root $0 --super-vecpkg
	xhost -si:localuser:root
    else
	echoc "Running Super-VECPKG" yellow
	su root $0 --super-vecpkg
	exit 0
    fi
fi

###################################################
# Normal service begin here

VDIR=`dirname $0`
. $VDIR/vasm-functions

## Read /etc/vector-version to determine the version
VERSION=5.0
if [ -f /etc/vector-version ]; then
    RELEASE=`cat /etc/vector-version`
    VERSION=${RELEASE##* }
    VERSION=${VERSION%rc*}
fi

SKIP_CURRENT=${SKIP_CURRENT:-yes}

URL_LIST="
ftp://ibiblio.org/pub/linux/distributions/vectorlinux/veclinux-$VERSION/packages
ftp://ibiblio.org/pub/linux/distributions/vectorlinux/veclinux-$VERSION/updates
ftp://ftp.nluug.nl/pub/metalab/distributions/vectorlinux/veclinux-$VERSION/packages
ftp://ftp.nluug.nl/pub/metalab/distributions/vectorlinux/veclinux-$VERSION/updates
ftp://ftp-linux.cc.gatech.edu/pub/linux/distributions/vectorlinux/veclinux-$VERSION/packages/
ftp://ftp-linux.cc.gatech.edu/pub/linux/distributions/vectorlinux/veclinux-$VERSION/updates/
ftp://public.planetmirror.com.au/pub/vectorlinux/veclinux-$VERSION/packages/
ftp://public.planetmirror.com.au/pub/vectorlinux/veclinux-$VERSION/updates/"

DOWNLOAD_URL="ftp://127.0.0.1/pub/veclinux$VERSION/packages"
DOWNLOAD_DIR="/home/ftp/pub/veclinux-$VERSION/packages"
LOCAL_DIR="$DOWNLOAD_DIR"
WGET_LOG="/var/log/wget.log"
CDROM_MNT=/mnt/cdrom

## READ another URLs from configuration if exist
if [ -f /etc/vecpkg.conf ]; then
    . /etc/vecpkg.conf
fi

TMP_DIR=/var/tmp
PKGLOG_DIR="/var/log/packages"
PKGLIST="$LOCAL_DIR/PKGLIST.TXT"
DOWNLOAD_PKG=""
LIB_LIST=""
PKG_LIST=""
PKG_FILES=""

mkdir -p $LOCAL_DIR
mkdir -p $PKGLOG_DIR
mkdir -p $DOWNLOAD_DIR

# count the selections
count_list()
{
    NUM=0
    while [ "$1" ]; do
	NUM=`expr $NUM '+' 1`
	shift
    done
    echo $NUM
}

echo_gauge() {
    if [ "$CMD" ]; then
	echo $1
	echo "XXX"
	echo $2
	echo "XXX"
    else
	echo $1
	echo "XXX"
	echo "\n$2"
	echo "XXX"
    fi
}

remove_pkg()
{
    PKG_NUM=`count_list $PKG_LIST`
    (
    PROGRESS=0
    for PKG in $PKG_LIST; do
	PROGRESS=`expr $PROGRESS '+' 1`
	pct=`expr 100 '*' $PROGRESS '/' $PKG_NUM`
	msg="Removing $PKG ($PROGRESS of $PKG_NUM)"
	echo_gauge $pct "$msg"
	sleep 2
	removepkg $PKG &>/dev/null
    done
    ) | $DCMD --backtitle "$BACKTITLE" --title "Please wait ..." --gauge "" 8 66 0
}

build_remove_menu()
{
    (
    cd $PKGLOG_DIR
    PKG_NUM=`ls -1 * | grep -c ""`
    PROGRESS=0
    for PLONG in *; do
	PNAME=`pkgname $PLONG`
	PDESC=`cat $PLONG | grep -m 1 -e "^$PNAME:" | cut -f2- -d:`
	if [ "$PDESC" ]; then
	    PDESC1=`echo $PDESC | cut -f2- -d '(' | cut -f1 -d ')'`
	    if [ "$PDESC1" ]; then
		PDESC=$PDESC1    
	    fi
	else
	    PDESC=$PNAME
	fi
	PDESC=`echo $PDESC | sed "s/'//"`
	echo "'$PLONG' '$PDESC' off \\" >> $fmenu
	PROGRESS=`expr $PROGRESS '+' 1`
	pct=`expr 100 '*' $PROGRESS '/' $PKG_NUM`
	echo_gauge $pct "Analyzing installed packages ($PROGRESS of $PKG_NUM) ..."
    done
    ) | $DCMD --backtitle "$BACKTITLE" --title "Please wait" --gauge "" 8 66 0
}

menu_remove()
{
TITLE="REMOVE PACKAGES"
TEXT="\n
Please select the packages you want to remove:"
DIMENSION="20 76 12"

    echo '$WCMD --backtitle "$BACKTITLE" --title "$TITLE" \' > $fmenu
    if [ "$CMD" ]; then
	echo '--separator " " \' >> $fmenu
    fi
    echo '--checklist "$TEXT" $DIMENSION \' >> $fmenu
    build_remove_menu $fmenu
    echo '2> $freply' >> $fmenu

    . $fmenu
        
    status=$?
    [ $status != 0 ] && return $status

    PKG_LIST=`cat $freply`
    remove_pkg
    return 0
}

## Ask a directory
media_local()
{
TITLE="PLEASE SHOW ME THE PKGLIST.TXT"
    if [ "$DISPLAY" ]; then
	$DCMD --backtitle "$BACKTITLE" --title "$TITLE" --fselect \
	$LOCAL_DIR/PKGLIST.TXT 0 0 2> $freply || return $?
    else
	$DCMD --backtitle "$BACKTITLE" --title "$TITLE" --fselect \
	$LOCAL_DIR/PKGLIST.TXT 10 60 2> $freply || return $?
    fi
        
    LOCAL_DIR=`cat $freply`
    BASENAME=`basename $LOCAL_DIR`
    if [ "$BASENAME" = "PKGLIST.TXT" ]; then
	LOCAL_DIR=`dirname $LOCAL_DIR`
    fi
    if [ -d $LOCAL_DIR ] && [ -f $LOCAL_DIR/PKGLIST.TXT ]; then
	(cd $LOCAL_DIR; pkglist -u)
	PKGLIST=$LOCAL_DIR/PKGLIST.TXT
	PKGLIST_NUM=`cat $PKGLIST | grep -c ""`
	return 0
    fi
    msgbox "Wrong package directory" "ERROR"
    return 1
}

media_cdrom()
{
    infobox "Mounting CDROM ..."
    
    ## Mount the CDROM
    if ! mount | grep -qe "on *$CDROM_MNT "; then
	mkdir -p $CDROM_MNT
	if ! mount $CDROM_MNT; then
	    msgbox "Cannot mount CDROM" "ERROR"
	    return 1
	fi
    fi

    ## find the packages
    if [ -d $CDROM_MNT/packages ]; then
        if [ -f $CDROM_MNT/packages/PKGLIST.TXT ]; then
	    PKGLIST=$CDROM_MNT/packages/PKGLIST.TXT
	    PKGLIST_NUM=`cat $PKGLIST | grep -c ""`
	    LOCAL_DIR=$CDROM_MNT/packages
	    return 0
	fi
    fi
    msgbox "Cannot find packages in the CDROM" "ERROR"
    umount $CDROM_MNT
    return 1
}

function media_ftp () {
  DIMENSION="12 60 8"
  TITLE="SELECT FTP SITE"
  TEXT="\n
Select the FTP site to download the packages,\n
or select EDIT if it is not in the list."

echo '$DCMD --backtitle "$BACKTITLE" --title "$TITLE" --menu "$TEXT" 20 74 10 \' > $fmenu
echo '"EDIT" " " \' >> $fmenu
for URL in $URL_LIST; do
   echo "'$URL' ' ' \\" >> $fmenu
done
echo '2> $freply' >> $fmenu

  source $fmenu

  result=$?
  [ $result != 0 ] && return $result

  REPLY=`cat $freply`

  if [ "$REPLY" = "EDIT" ]; then

    TITLE="ENTER FTP SITE"
    TEXT="\n
Please enter the FTP/HTTP site URL:"
    $DCMD --backtitle "$BACKTITLE" --title "$TITLE" --inputbox \
    "$TEXT" 9 60 "$DOWNLOAD_URL" 2> $freply || return $?

    DOWNLOAD_URL=`cat $freply`
  else
    DOWNLOAD_URL=$REPLY
  fi
  
  infobox "Contacting `echo $DOWNLOAD_URL | cut -f1-3 -d '/'` ..."

  mkdir -p $DOWNLOAD_DIR
  # download PKGLIST, overwrite
  (
  cd $TMP_DIR
  rm -f PKGLIST.TXT
  wget -nv -nd --passive-ftp $DOWNLOAD_URL/PKGLIST.TXT.bz2 > $WGET_LOG 2>&1
  if [ $? != 0 ] || [ ! -f PKGLIST.TXT.bz2 ]; then
     wget -r -nv -nd --passive-ftp $DOWNLOAD_URL/PKGLIST.TXT > $WGET_LOG 2>&1
  else
     bunzip2 -f PKGLIST.TXT.bz2
  fi
  )
  if [ -f $TMP_DIR/PKGLIST.TXT ]; then
     PKGLIST=$TMP_DIR/PKGLIST.TXT
     PKGLIST_NUM=`cat $PKGLIST | grep -cve "^#"`
     DOWNLOAD_PKG="yes"
     return 0
  fi
  msgbox "Cannot get PKGLIST from the FTP site" "ERROR"
  return 1
}


###################################################
menu_media()
{

while [ 0 ]; do

TITLE="VECTOR LINUX PACKAGES"
TEXT="\n
This menu allows you to install some new software packages,
or remove the installed ones.\n
Please choose the menu:"
DIMENSION="18 60 5"

$DCMD --backtitle "$BACKTITLE" --title "$TITLE" --menu \
"$TEXT" $DIMENSION \
FTP   "install from a remote FTP site"  \
CDROM "install from the local CDROM" \
LOCAL  "install from a local directory" \
REMOVE "uninstall one or more packages" \
2> $freply || return $?

MEDIA_SITE=`cat $freply`

DOWNLOAD_PKG=""
case $MEDIA_SITE in
  LOCAL)
     media_local && return 0
     ;;
  CDROM)
     media_cdrom && return 0
     ;;
  FTP)
     media_ftp && return 0
     ;;
  REMOVE)
     menu_remove
     ;;
esac
done
}

check_pkg()
{
    for PNAME in $*; do
	if ! ls $PKGLOG_DIR/$PNAME-* >/dev/null 2>&1; then
	    echo "off"
	    return 0
	fi
    done
    echo "on"
}

check_lib()
{

case $1 in
    cli)
	echo "on"
	;;
    x11)
	check_pkg x11 x11-devel
	;;
    gtk)
	check_pkg glib gtk+
	;;
    gtk2)
	check_pkg glib2 atk pango gtk+2
	;;
    gnome)
	check_pkg gnome-ui
	;;
    qt)
	check_pkg qt
	;;
    kde)
	check_pkg kde-base
	;;
    sdl)
	check_pkg SDL
	;;
    *)
	echo "off"
	;;
esac
}

lib_desc()
{
    case $1 in
	cli) 
	echo "Command line interface (most basic)"
	;;
	x11) 
	echo "X-Window system (basic, requires cli)"
	;;
	gtk) 
	echo "Gimp Toolkit (light, requires x11)"
	;;
	gtk2) 
	echo "Gimp Toolkit 2 (medium, requires x11)"
	;;
	gnome) 
	echo "GNOME desktop system (heavy, requires gtk2)"
	;;
	qt) 
	echo "QT toolkit (medium, requires x11)"
	;;
	kde) 
	echo "K desktop system (heavy, requires qt)"
	;;
	sdl) 
	echo "Games library (light, requires x11)"
	;;
	fltk) 
	echo "Fast Light toolkit (light, requires x11)"
	;;
	wxwindows) 
	echo "WxWindows toolkit (medium, requires gtk2)"
	;;
	vdk) 
	echo "VDK toolkit (medium, requires gtk2)"
	;;
	python) 
	echo "Python development kit (medium, requires cli+gtk2)" 
	;;
	java) 
	echo "Java development kit (heavy, requires x11)"
	;;
	*) 
	echo "$1 library"
	;;
    esac
}

build_lib_menu() {
    local LIST=""
    PROGRESS=0
    (
    while read LINE; do
	PFULL=`echo $LINE | cut -f1 -d ' '`
	PPATH=`dirname $PFULL`
	PPATH=`dirname $PPATH`
	if ! echo $LIST | grep -qw $PPATH; then
	    LIST="$LIST $PPATH"
	fi
	pct=`expr 100 '*' $PROGRESS '/' $PKGLIST_NUM`
	PROGRESS=`expr $PROGRESS + 1`
	echo_gauge $pct "Finding libraries"
    done
    for LIB in $LIST; do
      BLIB=`basename $LIB`
      echo "'$LIB' '`lib_desc $BLIB`' `check_lib $BLIB` \\" >> $fmenu
    done
    ) | $DCMD --backtitle "$BACKTITLE" --title "Please wait ..." --gauge "" 8 66 0
}

###################################################
menu_lib()
{
TITLE="CHOOSE BASE LIBRARIES"
TEXT="\n
Vector Linux organizes the packages in a tree structure according to
their library. Thus, you may make a slim install by choosing the 
required libraries only.\n
These are the available libraries. Items marked are already installed 
on the system. Add more as you wish:"
DIMENSION="20 74 8"

echo '$DCMD --backtitle "$BACKTITLE" --title "$TITLE" \
--checklist "$TEXT" $DIMENSION \' > $fmenu
grep -e "^[a-z,A-Z]" $PKGLIST | build_lib_menu 
echo '2> $freply' >> $fmenu

    . $fmenu

    status=$?
    [ $status != 0 ] && return $status

    if [ "$CMD" = "" ]; then
	LIB_LIST=`cat $freply | sed -e 's/"//g'`
    else
	LIB_LIST=`cat $freply | sed -e 's!/! !g'`
    fi
    return 0
}

# Find the package in a directory
# $1 = path
# $2 = pkgname
# $3 = extension (.tgz)
pkgfind()
{
    local LINE
    ls -1r $1/$2-*$3 2>/dev/null | while read LINE; do
	local B2=`basename $LINE`
	local P2=`pkgname $B2`
	if [ "$2" = "$P2" ]; then
	    echo $B2
	    return 0
	fi
    done
}

# Return on if a package has not been installed
# otherwise off
# $1 = PLONG
is_installed() {
    PNAME1=`pkgname $1`
    PVER1=`pkgversion $1`
    PLONG2=`pkgfind $PKGLOG_DIR $PNAME1`
    if [ "$PLONG2" ]; then
	PBASE2=`basename $PLONG2`
	PVER2=`pkgversion $PBASE2`
	if expr "$PVER2" '>=' "$PVER" &>/dev/null; then
	    return 0
	fi
    fi
    return 1
}

short_size()
{
    local S1=$1
    if [ $S1 -lt 10240 ]; then
	echo $S1
    else
	S1=`expr $S1 '/' 1024`
	if [ $S1 -lt 10240 ]; then
	    echo ${S1}K
	else
	    S1=`expr $S1 '/' 1024`
	    echo ${S1}M
	fi    
    fi
}

## Make pkg menu from PKGLIST.TXT
build_pkg_menu()
{
    PROGRESS=0
    (
    while read LINE; do
	PFULL=`echo $LINE | cut -f1 -d ' '`
	PSIZE=`echo $LINE | cut -f2 -d ' '`
	PDESC=`echo $LINE | cut -f2 -d:`
	PLONG=`basename $PFULL`
	PPATH=`dirname $PFULL`
	PGROUP=`basename $PPATH`
	PPATH=`dirname $PPATH`
	PLIB=`basename $PPATH`
	if echo $LIB_LIST | grep -qw $PLIB; then
	    PSTATE="Off"
	    PSIZE=`short_size $PSIZE`
	    PNAME=`pkgname $PLONG`
	    if [ "$PGROUP" = "BASE" ]; then
		PSTATE="on"
	    fi
	    if is_installed $PLONG; then
		PSTATE="off"
		PSIZE="installed"
	    fi
	    echo "'$PLIB/$PGROUP/$PNAME' '$PDESC($PSIZE)' $PSTATE \\" >> $fmenu
	fi    
	pct=`expr 100 '*' $PROGRESS '/' $PKGLIST_NUM`
	PROGRESS=`expr $PROGRESS + 1`
	echo_gauge $pct "Finding packages ..."
    done
    ) | $DCMD --backtitle "$BACKTITLE" --title "Please wait ..." --gauge "" 8 66 0

}

menu_pkg()
{
TITLE="CHOOSE PACKAGES"
TEXT="\n
The packages are organized in library/GROUP. If you want to install\n
for example package  : /x11/gtk/NET/apackage-1.0-i586-vl5.tgz\n
it requires all from : /x11/BASE/*.tgz and x11/gtk/BASE/*.tgz\n
Hopefully, dependency couldn't be easier."
DIMENSION="20 76 10"

    echo '$WCMD --backtitle "$BACKTITLE" --title "$TITLE" \' > $fmenu
    if [ "$CMD" ]; then
	echo '--separator " " \' >> $fmenu
    fi
    echo '--checklist "$TEXT" $DIMENSION \' >> $fmenu
    grep -e "^[a-z,A-Z]" $PKGLIST | build_pkg_menu 
    echo '2> $freply' >> $fmenu

    #cat $fmenu
    #read pause

    . $fmenu
        
    status=$?
    [ $status != 0 ] && return $status

    #if [ "$CMD" = "" ]; then
#	PKG_LIST=`cat $freply | sed -e 's/"//g'`
#    else
#	PKG_LIST=`cat $freply | sed -e 's!/! !g'`
#    fi
    PKG_LIST=`cat $freply`

    return 0
}

## Find pkg  in the PKGLIST
## $1 = /lib/GROUP/PNAME
pkglistfind()
{
    PN1=`basename $1`
    grep -e "$1-" $PKGLIST | while read LINE; do
	PF2=`echo $LINE | cut -f1 -d ' '`
	PL2=`basename $PF2`
	PN2=`pkgname $PL2`
	if [ "$PN2" = "$PN1" ]; then
	    echo $PF2
	fi
    done
}

build_confirm_menu()
{
    PROGRESS=0
    (
    PKG_NUM=`count_list $PKG_LIST`
    for PKG in $PKG_LIST; do
	PLONG=`pkglistfind $PKG`
	if [ "$PLONG" ]; then
	    PBASE=`basename $PLONG`
	    PVER=`pkgversion $PBASE`
	    PNAME=`pkgname $PBASE`
	    PLONG2=`pkgfind $PKGLOG_DIR $PNAME`
	    if [ "$PLONG2" ]; then
		PBASE2=`basename $PLONG2`
		PVER2=`pkgversion $PBASE2`
		if expr "$PVER2" '<' "$PVER" &>/dev/null; then
		    echo "'$PLONG' 'UPGRADE over $PNAME-$PVER2' on \\" >> $fmenu
		else
		    echo "'$PLONG' 'REINSTALL' off \\"  >> $fmenu
		fi
	    else
		echo "'$PLONG' 'INSTALL new' on \\" >> $fmenu
	    fi
	fi
	pct=`expr 100 '*' $PROGRESS '/' $PKG_NUM`
	PROGRESS=`expr $PROGRESS + 1`
	echo_gauge $pct "Analyzing selection ..."
    done
    ) | $DCMD --backtitle "$BACKTITLE" --title "Please wait ..." --gauge "" 8 66 0
}

menu_confirm()
{
    infobox "Analizing the selections ..."
    
TITLE="CONFIRM PACKAGES"
TEXT="\n
According to your selection, this is our job list.
Please confirm it before we start:"
DIMENSION="20 74 10"

    echo '$WCMD --backtitle "$BACKTITLE" --title "$TITLE" \' > $fmenu
    if [ "$CMD" ]; then
	echo '--separator " " \' >> $fmenu
    fi
    echo '--checklist "$TEXT" $DIMENSION \' >> $fmenu
    build_confirm_menu 
    echo '2> $freply' >> $fmenu

    . $fmenu
        
    status=$?
    [ $status != 0 ] && return $status

    CONFIRM_LIST=`cat $freply`

}

install_pkg()
{
    (
    cd $LOCAL_DIR
    PKG_NUM=`count_list $CONFIRM_LIST`
    PROGRESS=0
    pct=0
    for PKG in $CONFIRM_LIST; do
	msg="\nInstalling $PKG ($PROGRESS of $PKG_NUM)"
	if [ "$CMD" ] ; then
	    echo $pct
	    echo "XXX"
	    echo $msg
	    echo "XXX"
	else
	    echo "XXX"
	    echo $pct
	    echo $msg
	    echo "XXX"
	fi
    	pkg -o $PKG >> $WGET_LOG 2>&1
	PROGRESS=`expr $PROGRESS '+' 1`
	pct=`expr 100 '*' $PROGRESS '/' $PKG_NUM`
	msg="\nInstalled $PKG ($PROGRESS of $PKG_NUM)"
        if [ "$CMD" ] ; then
	    echo $pct
	    echo "XXX"
	    echo $msg
	    echo "XXX"
	else
    	    echo "XXX"
    	    echo $pct
    	    echo $msg
    	    echo "XXX"
	fi
	sleep 3
    done
    ) | $DCMD --backtitle "$BACKTITLE" --title "Installing ..." --gauge "" 8 74 0
}

download_pkg()
{
    ($0 --download $DOWNLOAD_DIR $DOWNLOAD_URL $CONFIRM_LIST >> $WGET_LOG 2>&1 &) &>/dev/null
    PID1=$!
    
    $DCMD --backtitle "$BACKTITLE" --title "DOWNLOADING" \
    --tailbox $WGET_LOG 20 76 2> $freply 
    status=$?
    kill $PID1 &> /dev/null
    LOCAL_DIR=$DOWNLOAD_DIR
    return $status
}

menu_install()
{
    echo "VECPKG LOG" > /tmp/vecpkg.log
    if [ "$DOWNLOAD_PKG" ]; then
	download_pkg
	[ $? != 0 ] && return 255
	## upgrade PKGLIST at 
	(cd $DOWNLOAD_DIR; pkglist -u)
    fi
    install_pkg
    infobox "Installation is DONE"
    sleep 2
    clean_exit 0
}

########################################################
# MAIN PROGRAM


wizard menu_media menu_lib menu_pkg menu_confirm menu_install
clean_exit 0
