#!/bin/sh
#
if [ $# = 0 ]; then
echo "This script 'pkg' is called in 'mc' when you press F2 and"
echo 'use the "Convert, Install, or Remove" options from the menu.' 
echo
echo "Usage: pkg -i package.tgz    <Install slackware package>"
echo "       pkg -l                <List packages in /var/log/packages>"
echo "       pkg -r package_name   <Remove package>"
echo "       pkg -c package.rpm    <Convert rpm, deb, or slp package to slack tgz>"
echo "       pkg -n package_name   <Create record of 'make install' package>"
echo "       Example: configure ; make ; pkg -n package_name ; make install ; exit"
echo "       You can see a listing for each installed package in"
echo "       /var/log/packages/package_name."
exit
fi

if [ ! "$UID" = "0" ]; then
echo
echo "[$LOGNAME] You need to run this script as root."
echo "Try one of these to run it as root: # sudo pkg -i package.tgz"
echo "                                    # su -c pkg -i package.tgz"
echo
exit 
fi

monitor() {

logdir="/var/log/packages"
search="/ /var/lib"
echo -n `mount | grep -v ' / ' | gawk '{print $3}'` >/tmp/exclude
exclude="`cat /tmp/exclude` /DOS /cdrom /initrd /mnt /root /proc /tmp /var /dev /home /usr/src /usr/spool"
fstype=`mount | grep ' / ' | gawk '{print $5}'`

if [ ! -d $logdir ]; then
mkdir -p $logdir
fi

search_exclude_normalize()
{
    for var in search exclude
    do
	eval tmp=\"\$$var\"
	tmp=$(printf " %s " "$tmp" | tr -s " /" | sed "s/\/ / /g" | sed "s/  / \/ /g" | tr " " "\n" | sort -u | tr "\n" " ")
	eval $var=\"\$tmp\"
    done
}

setup_find_args()
{
    actionargs="-cnewer /tmp/instmon.$package -print"
    excludeargs=""
    if [ -n "$fstype" ]
    then
	for type in $fstype
	do
	excludeargs="$excludeargs -not -fstype $type"
	done
	excludeargs="$excludeargs -prune -o"
    fi
    for path in $exclude
    do
	excludeargs="$excludeargs -path $path -prune -o"
    done
}

compare()
{
    echo
    printf "Detecting changes to system since i was first run...\n" 1>&2
    rm -f /tmp/instmon.files.$$
    : > /tmp/instmon.files.$$
    for path in $search
    do
    find $path -path $path \( $actionargs , -true \) -o $excludeargs $actionargs >> /tmp/instmon.files.$$ 2> /dev/null
    done
    
DATE=""
if [ -x "`type -path date`" ]; then
DATE="
DATE: `date 2>/dev/null`" 
fi
    
    rm -f /tmp/instmon.$package
    rm -f /tmp/$package
    sort -u /tmp/instmon.files.$$ > /tmp/$package
    rm -f /tmp/instmon.files.$$
    echo "MAKE_INSTALL PACKAGE NAME: $package $DATE" > /var/log/packages/$package 
    echo "FILE LIST:" >> /var/log/packages/$package 
    echo "./" >> $logdir/$package 
    cat /tmp/$package | sed "s/^\///g" >> $logdir/$package 
    rm -f /tmp/$package 

    if [ `tail -n 1 /var/log/packages/$package` = "./" ]; then
    rm -f $logdir/$package 
    echo "No changes..."
    exit
    fi    

    echo
    printf "Package Log: /var/log/packages/$package\n" 1>&2
    printf "done...\n" 1>&2
}

    if [ -s /var/log/packages/$package ]; then
    echo "There's a package named '$package' in /var/log/packages."
    echo "Chose another name 'pkg -n name'."
    exit
    fi

    : > /tmp/instmon.$package
    echo "Enter command 'make install' then 'exit' from shell when done!"
    /bin/sh 
    search_exclude_normalize
    setup_find_args
    compare
exit
}

TMP=/tmp/pkg
if [ ! -d $TMP ]; then
  rm -rf $TMP 
  mkdir -p $TMP
  chmod 700 $TMP 
fi

trap "rm -rf $TMP" EXIT

rmpkg() {
ADM_DIR=/var/log

cat_except() {
 if [ ! `ls -a "$1" | wc -l` -eq 3 ]; then
 ( cd "$1" && cat `ls * | sed "/^$2\$/d"` )
 fi
}

extract_links() {
 sed -n 's,^( *cd \([^ ;][^ ;]*\) *; *rm -rf \([^ )][^ )]*\) *) *$,\1/\2,p'
}

delete_files() {
 while read FILE ; do
  if [ ! -d "/$FILE" ]; then
   if [ -r "/$FILE" ]; then

     echo "  --> Deleting /$FILE"
     rm -f "/$FILE"
   fi
  fi
 done
}

delete_links() {
 while read LINK ; do
  if [ -L "/$LINK" ]; then
    echo "  --> Deleting symlink /$LINK"
    rm -f /$LINK
  fi
 done
}

delete_dirs() {
 sort -r | \
 while read DIR ; do
  if [ -d "/$DIR" ]; then
      if [ `ls -a "/$DIR" | wc -l` -eq 2 ]; then
        echo "  --> Deleting empty directory /$DIR"
        rmdir /$DIR 2>/dev/null
      fi
  fi
 done
}

remove_packages() {
 for package_name in $* 
 do
  PKGNAME=$package_name
  if [ ! -r $PKGNAME ]; then
    PKGNAME=`basename $PKGNAME`
  fi
  echo
    echo "Removing $ADM_DIR/packages/$PKGNAME..."
   if grep "^./" $ADM_DIR/packages/$PKGNAME 1>/dev/null 2>&1; then
    TRIGGER="^\.\/"
   else
    TRIGGER="FILE LIST:"
   fi
    echo "Removing files:"
    sed -n "/$TRIGGER/,/^$/p" < $ADM_DIR/packages/$PKGNAME | \
    grep -F -v "FILE LIST:" | sort -u > $TMP/delete_list
    cat_except $ADM_DIR/packages $PKGNAME | sort -u > $TMP/required_list
   if [ -r $ADM_DIR/scripts/$PKGNAME ]; then
    extract_links < $ADM_DIR/scripts/$PKGNAME | sort -u > $TMP/del_link_list
    cat_except $ADM_DIR/scripts $PKGNAME | extract_links | \
    sort -u > $TMP/required_links
    mv $TMP/required_list $TMP/required_files
    sort -u $TMP/required_links $TMP/required_files >$TMP/required_list
    comm -23 $TMP/del_link_list $TMP/required_list | delete_links
   fi

   comm -23 $TMP/delete_list $TMP/required_list > $TMP/uniq_list
   delete_files < $TMP/uniq_list
   delete_dirs < $TMP/uniq_list

    rm -f $TMP/delete_list $TMP/required_files $TMP/uniq_list
    rm -f $TMP/del_link_list $TMP/required_links $TMP/required_list

    for DIR in $ADM_DIR/removed_packages $ADM_DIR/removed_scripts ; do
     if [ ! -d $DIR ] ; then mkdir -p $DIR ; chmod 755 $DIR ; fi
    done
    mv $ADM_DIR/packages/$PKGNAME $ADM_DIR/removed_packages
    if [ -r $ADM_DIR/scripts/$PKGNAME ]; then
    mv $ADM_DIR/scripts/$PKGNAME $ADM_DIR/removed_scripts
    fi
 done
}

remove_packages $*
rm -rf $TMP
}

pkginstall() {	
  for package in $1 ; do
  echo
  echo "Installing package $package..."
  shortname=`basename $package .tgz`
  ADM_DIR="/var/log" 
  if [ -r $ADM_DIR/scripts/$shortname ]; then
   cat $ADM_DIR/scripts/$shortname | grep -F 'rm -rf' | sort -u > $TMP/del_link_list
   if [ ! -d $ADM_DIR/removed_scripts ]; then
    mkdir -p $ADM_DIR/removed_scripts
   fi
   mv $ADM_DIR/scripts/$shortname $ADM_DIR/removed_scripts 1> /dev/null 2>&1    
   ( cat $ADM_DIR/scripts/* 2>/dev/null ; tar xzOf $package install/doinst.sh 2>/dev/null ) | \
     grep -F 'rm -rf' | sort -u > $TMP/required_links
   comm -23 $TMP/del_link_list $TMP/required_links > $TMP/delscript
   ( cd / ; sh $TMP/delscript )
   rm -f $TMP/del_link_list $TMP/required_links $TMP/delscript
  fi

DATE=""
if [ -x "`type -path date`" ]; then
DATE="
DATE: `date 2>/dev/null`" 
fi

  echo "PACKAGE NAME: $shortname $DATE" > /var/log/packages/$shortname
  COMPRESSED=`gzip -l $package | grep -F -v uncompressed_name | cut -b0-9`
  UNCOMPRESSED=`gzip -l $package | grep -F -v uncompressed_name | cut -b10-19`
  echo "COMPRESSED PACKAGE SIZE: `expr $COMPRESSED / 1024`K" >> /var/log/packages/$shortname
  echo "UNCOMPRESSED PACKAGE SIZE: `expr $UNCOMPRESSED / 1024`K" >> /var/log/packages/$shortname
  echo "PACKAGE LOCATION: $pkg" >> /var/log/packages/$shortname
  echo "FILE LIST:" >> /var/log/packages/$shortname
 
  exclude=""
  if [ -s /etc/exclude ]; then
  exclude=" -X /etc/exclude"
  fi
 
  ( cd / ; tar -Uxzlpv$exclude -f - ) < $package >> /var/log/packages/$shortname 2>/dev/null
 
  if [ -f /install/doinst.sh ]; then
   echo
   echo "Executing install script for $package..."
   ( cd / ; sh install/doinst.sh -install 2>/dev/null; )
  fi 

   ldconfig -q 2>/dev/null
   hash -r

   if [ ! "$UPGRADEPKG" = "YES" ]; then
   rm -rf $TMP 2>/dev/null
   echo
   echo "Package contents: /var/log/packages/$shortname"
   echo
   fi
   
  if [ -d /install ]; then
   cp /install/doinst.sh /var/log/scripts/$shortname
   chmod 755 /var/log/scripts/$shortname
   (cd /install ; rm -r -f doin* 1> /dev/null 2>&1 )
   rmdir /install 1> /dev/null 2>&1
  fi
 done
}

uppkg() {
while [ ! "$1" = "" ]; do

OLD=$1 
NEW=$1 

TIMESTAMP=`date +%Y-%m-%d,%T`

( cd /var/log/packages ; cp -a $OLD $TMP/$OLD-upgraded-$TIMESTAMP )
( cd /var/log/scripts
  if [ -r $OLD ]; then
    cp -a $OLD $TMP/$OLD-script-upgraded-$TIMESTAMP
  fi )

cat << EOF

****************************************************************************
* Upgrading $OLD package using $NEW.tgz
****************************************************************************
EOF

pkginstall $NEW.tgz
unset UPGRADEPKG

if [ ! "$OLD" = "$NEW" ]; then
  rm -f /var/log/packages/$OLD
  rm -f /var/log/scripts/$OLD
fi

if [ -f $TMP/$OLD-upgraded-$TIMESTAMP ]; then
  mv $TMP/$OLD-upgraded-$TIMESTAMP /var/log/packages/$OLD-upgraded-$TIMESTAMP
fi
if [ -f $TMP/$OLD-script-upgraded-$TIMESTAMP ]; then
  mv $TMP/$OLD-script-upgraded-$TIMESTAMP /var/log/scripts/$OLD-upgraded-$TIMESTAMP
fi

   if grep "^./" /var/log/packages/$OLD-upgraded-$TIMESTAMP 1> /dev/null 2>&1; then
    TRIGGER="^\.\/"
   else
    TRIGGER="FILE LIST:"
   fi

   sed -n "/$TRIGGER/,/^$/p" < /var/log/packages/$OLD-upgraded-$TIMESTAMP | \
   grep -v "^./" | grep -v "FILE LIST:" | sort -u > $TMP/OLD

   if grep "^./" /var/log/packages/$NEW 1> /dev/null 2>&1; then
    TRIGGER="^\.\/"
   else
    TRIGGER="FILE LIST:"
   fi

   sed -n "/$TRIGGER/,/^$/p" < /var/log/packages/$NEW | \
   grep -v "^./" | grep -v "FILE LIST:" | sort -u > $TMP/NEW

cmp -s $TMP/OLD $TMP/NEW && SAME=YES

if [ ! "$SAME" = "YES" ]; then
  rmpkg $OLD-upgraded-$TIMESTAMP
  rm -f /var/log/removed_scripts/$NEW
else
rm -f /var/log/packages/$OLD-upgraded-$TIMESTAMP
rm -f /var/log/scripts/$OLD-upgraded-$TIMESTAMP
rm -f /var/log/removed_scripts/$NEW
rm -rf $TMP
fi

echo
echo "Package $OLD upgraded with $NEW.tgz."
echo

   echo "Package contents: /var/log/packages/$NEW"
   echo

shift 1
done
}

make_install_script() {
 COUNT=1
 LINE="`sed -n "$COUNT p" $1`"
 while [ ! "$LINE" = "" ]; do
  LINKGOESIN="`echo "$LINE" | cut -f 1 -d " "`" 
  LINKGOESIN="`dirname $LINKGOESIN`" 
  LINKNAMEIS="`echo "$LINE" | cut -f 1 -d ' '`"
  LINKNAMEIS="`basename "$LINKNAMEIS"`"
  LINKPOINTSTO="`echo "$LINE" | cut -f 3 -d ' '`"
  echo "( cd $LINKGOESIN ; rm -rf $LINKNAMEIS )"
  echo "( cd $LINKGOESIN ; ln -sf $LINKPOINTSTO $LINKNAMEIS )"
  COUNT=`expr $COUNT + 1`
  LINE="`sed -n "$COUNT p" $1`"
 done
}

if [ "$1" = "-l" -a -d /var/log/packages ]; then
if [ ! `ls -a /var/log/packages | wc -l` -eq 2 ]; then
if [ `ls -A /var/log/packages/* | wc -l` -gt 100 ]; then
if type -all less >/dev/null 2>&1 ; then
pager="less"
elif type -all more >/dev/null 2>&1 ; then
pager=more
else
echo "Can't find less or more pager."
exit
fi
echo "Going to list packages in /var/log/packages, press q to Quit! pager $pager."
echo -n "Press enter to continue. "
read PAUSE
ls -A -C /var/log/packages | $pager
exit
else
ls -A -C /var/log/packages 
exit
fi
fi
fi

if [ "$1" = "-n" ]; then
if [ ! "$2" = "" ]; then
package="$2"
else 
package=$(basename $(pwd))
fi
monitor
exit
fi

if [ "$1" = "-r" ]; then
if [ ! "$2" = "" ]; then

        if [ ! -s /var/log/packages/$2 ]; then 
        echo "No such package in /var/log/packages: $2"
	exit 
	fi
	echo
	echo -n "Remove? $2 (N/y) : "
	read ans
	if [ "$ans" = "y" -o "$ans" = "Y" ]; then
        rmpkg $2  
        else
	exit 
	fi	
        echo
	echo "Removed: $2" 
exit
else
exit
fi
fi

mkpkg() {

  echo "Looking for any symbolic links..."
  find . -type l -exec ls -l {} \; | cut -b58- | tee $TMP/iNsT-a.$$
 
  if [ -s $TMP/iNsT-a.$$ ]; then
  
  if [ ! -d install ]; then
   mkdir install
  fi
  
  echo
  echo "Making install script: install/doinst.sh"
  make_install_script $TMP/iNsT-a.$$ | tee install/doinst.sh
  rm -f $TMP/iNsT-a.$$
  echo
  echo "Removing the symbolic links..."
  find . -type l -print -exec rm {} \;
  fi
  
  echo
  if [ "$D" = "" ]; then
  echo "Making $2.tgz..."
  tar --create --gzip --exclude $2.tgz --file $2.tgz *
  else
  echo "Making $D.tgz..."
  tar --create --gzip --exclude $D.tgz --file $D.tgz *
  fi
  echo "Done..."
  rm -rf $TMP
}

        if [ "$1" = "-c" ]; then
        
	if [ "$2" = "" ]; then
	exit
	fi
	 
        if [ ! -s "$2" ]; then          
        echo "Can't find '$2' package."
        exit
        fi
	        
	if echo $2 | grep -v -E "\.src.rpm$" | grep -E -q "\.rpm$" ; then
	if [ ! -x "`type -path unrpm`" ]; then
	echo
	echo "Can't find 'unrpm' to check rpm package!"
	exit
	fi
        echo
	echo "Checking rpm package for errors '$2'..."
	unrpm < $2 | gzip -d | cpio -i --only-verify-crc 2>/tmp/rpm.error 
	if [ $? -gt 0 ]; then
	echo
	echo "ERROR! reported for '$2'..." 
	echo "There's something wrong with the package, you probably shouldn't convert it." 
	echo
	rm -f /tmp/rpm.error
	exit 
        elif `grep -q "checksum error" /tmp/rpm.error` ; then
	echo
	echo "ERROR! reported for '$2'..." 
	echo "There's something wrong with the package, you probably shouldn't convert it." 
	echo
	rm -f /tmp/rpm.error
	exit 
	fi
	rm -f /tmp/rpm.error
        D="`basename $2 .rpm`"
	echo
        echo "Converting '$2' to '`basename $2 .rpm`.tgz'..."
        echo
	dir=$PWD
	mkdir -p /tmp/$D 
	cd /tmp/$D || exit 
	unrpm < $dir/$2 | gzip -d | cpio -iumd --quiet 
	find . -type d -perm 700 -exec chmod 755 {} \; 2>/dev/null
        mkpkg $D 
	if [ $? -gt 0 ]; then
        cd $dir && rm -rf /tmp/$D
	exit 
	else
	mv $D.tgz $dir && cd $dir && rm -rf /tmp/$D
	exit
	fi
        elif echo $2 | grep -E -q "\.deb$" ; then
	if [ ! -x "`type -path undeb`" ]; then
	echo
	echo "Can't find 'undeb' to check deb package!"
	exit
	fi
        echo
	echo "Checking deb package for errors '$2'..."
	undeb -p $2 data.tar.gz | tar -tz >/dev/null 2>&1
	if [ $? -gt 0 ]; then
	echo
	echo "ERROR! reported for '$2'..." 
	echo "There's something wrong with the package, you probably shouldn't convert it." 
	echo
	exit 
	fi
        D="`basename $2 .deb`"
        echo
	echo "Converting '$2' to '`basename $2 .deb`.tgz'..."
        echo
	dir=$PWD
        mkdir -p /tmp/$D && undeb -p $2 data.tar.gz | tar -xzpf - -C /tmp/$D && cd /tmp/$D && mkpkg $D 
	if [ $? -gt 0 ]; then
        cd $dir && rm -rf /tmp/$D
	exit 
	else
	mv $D.tgz $dir && cd $dir && rm -rf /tmp/$D
	exit
	fi
        elif echo $2 | grep -E -q "\.slp$" ; then
        D="`basename $2 .slp`"
	echo
        echo "Converting '$2' to '`basename $2 .slp`.tgz' ..."
        echo
	dir=$PWD
	mkdir -p /tmp/$D && tar -xpf $2 -C /tmp/$D --use-compress-program bzip2 2>/dev/null  
	cd /tmp/$D && mkpkg $D 
        if [ $? -gt 0 ]; then
        cd $dir && rm -rf /tmp/$D
	exit 
	else
	mv $D.tgz $dir && cd $dir && rm -rf /tmp/$D
	exit
	fi
	else
	echo
	echo "$2" 
	echo "Doesn't have a .rpm, .deb, or .slp extension."
	echo
	exit
        fi
	fi

       if [ "$1" = "-i" ]; then
         
       if [ "$2" = "" ]; then
       exit
       fi

        if [ ! -s "$2" ]; then          
        echo "Can't find '$2' package."
        exit
        fi
	
	if [ `dirname $2` = "." ]; then
	pkg=$PWD/$2
	else
	pkg=$2
	fi
	
	if [ ! "$UPGRADEPKG" = "YES" ]; then
        
        if ! echo $2 | grep -q -E "\.tgz$" ; then
	echo
	echo "$2" 
	echo "Doesn't have a .tgz extension, it can't be a slackware package!"
	echo
	exit
        fi

        if [ ! -d /var/log/packages ]; then
        mkdir -p /var/log/packages
        fi

        if [ ! -d /var/log/scripts ]; then
        mkdir -p /var/log/scripts
        fi

        if [ -s "/var/log/packages/`basename $2 .tgz`" ]; then
        if ( head -1 /var/log/packages/`basename $2 .tgz` 2>/dev/null | grep -q "MAKE_INSTALL PACKAGE NAME:" ); then
	echo
        echo "You have a 'make install' package named '`basename $2 .tgz`'"
	echo "listed in /var/log/packages."
	echo
	echo "You could rename /var/log/packages/`basename $2 .tgz`."
	echo
	exit
        fi
        fi
		
	echo
	echo "Checking package for errors: gzip -tv $2" 
	gzip -tv $2 
	if [ $? -gt 0 ]; then
	echo
	echo "ERROR! reported for: $2" 
	echo "There's something wrong with the package," 
	echo "you probably shouldn't install it." 
	echo
	exit 
	fi

        if [ -s "/var/log/packages/`basename $2 .tgz`" ]; then
	echo
        echo "You already have a package named '`basename $2 .tgz`'"
	echo "listed in /var/log/packages."
	echo
	echo "If you continue i'll assume it's a newer version of"
	echo "the package, and install it as an upgrade package."
	echo
	echo -n "Install? (N/y) : "
	read ans
	if [ "$ans" = "y" -o "$ans" = "Y" ]; then
	export UPGRADEPKG=YES
	uppkg `basename $2 .tgz`
	exit
	else
	exit 
	fi
	fi
	pkginstall $2 
	fi
	fi
         
	 
