#!/bin/bash
###########################################################################
# Program: slackdtxt
# Purpose: Create package-ver-arch-build.txt files from slack-desc files.
#          For use after running a SlackBuild script - you do not need to
#          use this program for a .tgz produced by slacktrack -- use its
#          -c switch instead.
# Author : Stuart Winter <mozes@armedslack.org>
# Date...: 28-Sep-2003
# Version: 1.02
###########################################################################
# History
##########
# 02-Mar-2003 - v1.00
#             * Created
# 11-Jul-2003 - v1.01
#             * Fixed problem with checking the exit code from getopt.
#               (reported by Emanuele Vicentini).
# 28-Sep-2003 - v1.02
#             * Added option -G, --gpg-sign to sign the .tgz package
#               (Patch from Emanuele Vicentini)
#             * Removed -t option.  You may now do specify the file after
#               as before (but without -t) or specify more than one package
#               at once: eg  slackdtxt *.tgz
###########################################################################

# Program name
PROGNAME=slackdtxt

# Version
VERSION="${PROGNAME} v1.02 by Stuart Winter <stuart@polplex.co.uk>"

# Temporary store for the slack-desc file
DESCTMPFILE="/var/tmp/$$.slackdtxt.desc.$$"

############################## Functions###################################
function display_usage () {
printf "Usage: ${PROGNAME} [options] <tgz file/list of tgz files>\n"
if [ ! -z "$1" ]; then
   echo "Use $( basename $0 ) --help for a list of options"
fi
}

function display_help () {
printf "${VERSION}\n\n$(display_usage)

Startup:
 -h,   --help                   Display this help
 -v,   --version                Display version information

Main options:
 -s,   --slackdescfile <file>   'slack-desc' file (cannot be used when
                                specifying more than one .tgz package file)
 -d,   --destdir   <directory>  The directory in which to store the .tgz & create
                                the .txt description file within
                                Omitting this flag implies --nodeletetgz
 -n,   --nodeletetgz            Do not delete the original .tgz
                                once moved into destination directory
 -G,   --gpg-sign [<id>]        Sign the .tgz with GnuPG
"
}

###############################################################################

############################## Configuration variables #########################
# These can be changed via the command line switches
#
DELETETGZ="Yes"
################################################################################

PARAMS="$( getopt -qn "$( basename $0 )" -o s:d:nhvG:: -l slackdescfile:,destdir:,nodeletetgz,help,version,gpg-sign:: -- "$@" )"

# If params are incorrect then
if [ $? -gt 0 ]; then display_help ; exit 2 ; fi
eval set -- "${PARAMS}"
for param in $* ; do
  case "$param" in

     -s|--slackdescfile) SLACKDESCFILE="$2"
                         shift 2;;

     -d|--destdir)       DESTDIR="$2"
			 shift 2;;

     -n|--nodeletetgz)   DELETETGZ="No"
                         shift 1;;

     -G|--gpg-sign)      SIGNPACKAGE="Yes"
                         SIGNINGKEY="$2"
                         shift 2;;

     -h|--help)          display_help ; exit ;;

     -v|--version)       printf "${VERSION}\n" ; exit;;   
 
     --) shift; break;;
esac done

# Do we have the relevant information to proceed?
if [ -z "${1}" ]; then
   display_usage help
   exit 2
fi

# Do we have too *much* information to proceed?
if [ $# -gt 1 -a ! -z "${SLACKDESCFILE}" ]; then
   echo "Error: You cannot specify a slack-desc file when"
   echo "       specifying more than one .tgz package file"
   display_usage help
   exit 2
fi

# Let's check if user really has gpg.
if [ "${SIGNPACKAGE}" = "Yes" ]; then
   which gpg >/dev/null 2>&1 || { echo "${PROGNAME}: Warning: Cannot find gpg; disabling signature creation"; unset SIGNPACKAGE; }
fi

# Main loop, handle any number (well, not really but you know..)
# of tgz files specified at the command line.
for TGZFILE in $*; do

# If we were given a destination dir then check whether it exists
# Now giving a dest dir allows us to do
#  # for i in *.tgz ; do slackdtxt -t $i ; done
# and create .txt files for all the .tgz files in a dir.
if [ ! -z "${DESTDIR}" ]; then
   DESTDIR="${DESTDIR}/" # otherwise when we tar without specifying a dest dir, it becomes /package-blah.tgz
   if [ ! -d "${DESTDIR}" ]; then
      echo "${PROGNAME}: ERROR: The destination directory does not exist"
      exit 6
   fi
  else
   DELETETGZ="No" # otherwise we'd delete our only copy
fi

# Does the specified .tgz package exist?
if [ ! -s "${TGZFILE}" ]; then
   echo "${PROGNAME}: ERROR: The specified package .tgz does not exist"
   exit 7
fi

# Does the specified slack-desc file exist ?
if [ ! -z "${SLACKDESCFILE}" ]; then
   if [ ! -s "${SLACKDESCFILE}" ]; then
      echo "${PROGNAME}: Warning: The specified slack-desc file (${SLACKDESCFILE} does not exist;"
      echo "                    will try and extract from the .tgz"
      unset SLACKDESCFILE
  else
     # .. the file is fine.
     # copy the slack-desc file to the temp location so I don't have
     # to code around having the user specify one and having to take one
     # from the .tgz then delete it.
     cp -f "${SLACKDESCFILE}" "${DESCTMPFILE}" 
     # .. but if copying it fails then we'll take it from the .tgz anyway.
     if [ $? -gt 0 ]; then
        unset SLACKDESCFILE
      else
        SLACKDESCFILE="${DESCTMPFILE}" # we'll use the /var/tmp version now
     fi
  fi
fi
############################## Main program###################################

# Move the .tgz file to the dest dir if we were given one
if [ ! -z "${DESTDIR}" ]; then
   echo -n "${PROGNAME}: Copying .tgz to destination directory"
   cp -fa "${TGZFILE}" "${DESTDIR}"
   if [ $? -gt 0 ]; then
      printf "\n${PROGNAME}: ERROR: Failed to copy the .tgz\n"
      exit 8
    else
      echo " ... done"
   fi
fi

# Test the copied .tgz -- it probably isn't corrupt (eg no disk space on $DESTDIR)
# as the cp would have errored, but I'd like to check anyway
if [ ! -z "${DESTDIR}" ]; then
   echo -n "${PROGNAME}: Verifying the version of the .tgz in the destination directory"
   tar ftz "${DESTDIR}$( basename ${TGZFILE} )" >/dev/null 2>&1
   if [ $? -gt 0 ]; then
      printf "\n${PROGNAME}: ERROR: The .tgz in ${DESTDIR} is corrupt\n"
      exit 8
    else
      echo " ... done"
   fi
fi

# If we weren't given a slack-desc file then try and pull one from the
# .tgz
if [ -z "${SLACKDESCFILE}" ]; then
   SLACKDESCFILE="${DESCTMPFILE}"
   echo -n "${PROGNAME}: Attempting to extract install/slack-desc from the .tgz"
   tar fOxz "${TGZFILE}" install/slack-desc > "${SLACKDESCFILE}" 
   if [ ! -s "${SLACKDESCFILE}" ]; then
      printf "\n${PROGNAME}: ERROR: Failed to extract the slack-desc file from the .tgz\n"
      rm -f "${SLACKDESCFILE}" # it may be zero bytes/empty
      exit 8
    else
      echo " ... done"
   fi
fi

# Turn the slack-desc file into a .txt file 
egrep -v '^($|#| *\|)' "${SLACKDESCFILE}" > "${DESTDIR}$( echo $( basename $TGZFILE ) | rev | cut -d. -f2- | rev ).txt"
rm -f "${SLACKDESCFILE}"
echo "${PROGNAME}: $( echo $( basename $TGZFILE ) | rev | cut -d. -f2- | rev ).txt created"

# Let's sign the original .tgz with user's gpg key
if [ ! -z "${SIGNPACKAGE}" ]; then
   echo "${PROGNAME}: signing ${TGZFILE} with ${SIGNINGKEY:-your default} key"
   GPG_OPTIONS="--detach-sign --armor"
   if [ "${SIGNINGKEY}" ]; then
      GPG_OPTIONS="${GPG_OPTIONS} --local-user $SIGNINGKEY"
   fi
   gpg ${GPG_OPTIONS} --output ${DESTDIR}${TGZFILE}.asc ${TGZFILE}
   if [ $? -ne 0 ]; then
      echo "${PROGNAME}: ERROR: Signature has not been correctly generated"
    else
      echo " ... done"
   fi
fi

# Delete the .tgz ?
if [ "${DELETETGZ}" = "Yes" ]; then
   echo -n "${PROGNAME}: Deleting the original .tgz"
   rm -f "${TGZFILE}"
   if [ $? -gt 0 ]; then
      printf "\n${PROGNAME}: Warning: unable to delete .tgz\n"
    else
      echo " ... done"
   fi
fi

unset SLACKDESCFILE

# Exit from main loop
done
