#!/bin/bash

SVER=0.95.1
SDATE="2009 06 18"

##############################################################################
#  smt-support - Maintains incoming SMT server archives to be uploaded
#                to Novell.
##############################################################################
# Global Variables
##############################################################################

CURRENT_SCRIPT=$(basename $0)
SMT_UPLOAD_TARGET='https://secure-www.novell.com/upload?appname=supportconfig&file={tarball}'
SMT_LOG=/var/log/smt/${CURRENT_SCRIPT}.log
SMT_CONTACT_FILE=contact-smt-support.txt
echo ${SMT_INCOMING:=/var/spool/smt-support} &> /dev/null
UPLOAD_FILEPATH=""
ARCH_FILE=""
NEW_ARCH_FILE=""
ACTION=1
REPACKAGE=0
RCODE=0
KEEP_AFTER_UPLOAD=0;
unset SRNUM

##############################################################################
# Local Functions
##############################################################################

title() {
	clear
	cat << EOTITLE >&2
=============================================================================
                      SMT Utilities - Archive Support
                           Script Version: $SVER
                          Script Date: $SDATE
=============================================================================

EOTITLE
}

show_help() {
	test -n "$1" && { echo "$1"; echo; } >&2
	cat << EOHELPT >&2
  Usage: $CURRENT_SCRIPT <-l|-r|-R|-u|-U> [OPTION [OPTION ...]]

  Maintains incoming SMT server archives to be uploaded to Novell.

  -h, --help This screen
  -i, --incoming <directory>
     Sets the incoming directory where supportconfig archives are
     uploaded. Also set with SMT_INCOMING environment variable.
  -l, --list
     Lists the uploaded supportconfig archives (This is the default action.)
  -r, --remove <archive>
     Deletes the specified archive
  -R, --empty
     Deletes all archives in the incoming directory
  -u, --upload <archive>
     Uploads the specified archive to Novell, and repackages archive with
     contact information if options -sncpe are given
  -U, --uploadall
     Uploads all archives in the incoming directory to Novell
  -s, --srnum <SR number>
     The Novell Service Request 11 digit number
  -n, --name <Name>
     First and last name of contact in quotes
  -c, --company <Company>
     Company name
  -d, --storeid <id>
     Enter the store ID if applicable
  -t, --terminalid <id>
     Enter the Terminal ID if applicable
  -p, --phone <Phone>
     The contact phone number
  -e, --email <Email>
     Contact email address
  --keep-after-upload
     Preserve archive(s) on SMT server after upload even if uploaded successfully

  Example: $CURRENT_SCRIPT --list
  Example: $CURRENT_SCRIPT --upload nts_fs01_090617_1300.tbz --srnum 21212121212 --name "Joe Customer" --email "joe@company.com" --company "Company Foo"
  Example: $CURRENT_SCRIPT --remove nts_fs02_090617_1400.tbz

EOHELPT

exit 1
}

checkIncoming() {
	logEntry Directory $SMT_INCOMING
	if [ ! -d $SMT_INCOMING ]; then
		showStatus "ERROR: Invalid or missing directory"
		echo
		exit 1;
	fi
}

logEntry() {
	printf "%-12s %s\n" "$1" "$2" | tee -a $SMT_LOG
}

logFileEntry() {
	printf "%-12s %s\n" "$1" "$2" >> $SMT_LOG
}

logFileCmd() {
	CMDLINE="$@"
	printf "%-12s %s\n" ' [Command]' "$CMDLINE" >> $SMT_LOG 2>&1
	echo "$CMDLINE" | bash  >> $SMT_LOG 2>&1
	EXIT_STATUS=$?
	return $EXIT_STATUS
}

startLogEntry() {
	echo "--------------------------" >> $SMT_LOG
	logEntry Date "$(date)"
}


showArchive() {
	logEntry Archive $ARCH_FILE
}

# Requires checkIncoming
countArchives() {
	ARCHS=$(\ls -l ${SMT_INCOMING}/*t[b,g]z 2>/dev/null | wc -l)
	logEntry Archives $ARCHS
	return $ARCHS
}

showStatus() {
	logEntry Status "$1"
}

setAction() {
	logEntry Action "$1"
}

listIncoming() {
	echo
	cd $SMT_INCOMING
	\ls -1 *t[b,g]z 2>> $SMT_LOG | tee -a $SMT_LOG
}

validateSR() {
	if [ $SRNUM ]; then
		startLogEntry
		INVALID=0
		if [ ${#SRNUM} -eq 11 ]; then
			if echo $SRNUM | grep '[[:alpha:]]' &> /dev/null; then
				((INVALID++))
			fi
		else
			((INVALID++))
		fi
		if [ $INVALID -gt 0 ]; then
			showStatus "ERROR, Invalid SR number ($SRNUM); Must be 11 digits"
			echo
			exit 5
		fi
	fi
}

secureUpload() {
	FILE=$1
	UPLOAD_ARCHIVE=$(basename ${FILE})
	unset UPLOAD_URL
	UPLOAD_URL=$(echo $SMT_UPLOAD_TARGET | sed -e "s/{[Tt][Aa][Rr][Bb][Aa][Ll][Ll]}/${UPLOAD_ARCHIVE}/g")
	logFileCmd "curl -v -s -L -A SupportConfig -T \"${FILE}\" \"${UPLOAD_URL}\""
	RC=$?
	echo >> $SMT_LOG
	return $RC
}

# Requires checkIncoming
# Sets ARCH_FILE
repackageArchive() {
	RC=0
	UUID=$(uuidgen)
	NEW_ARCH_FILE=$ARCH_FILE
	if [ $SRNUM ]; then
		if echo $ARCH_FILE | grep 'nts_SR[[:digit:]]' &> /dev/null; then
			NEW_ARCH_FILE=$(echo $ARCH_FILE | sed -e "s/_SR[[:digit:]]*_/_SR${SRNUM}_/")
		else
			NEW_ARCH_FILE=$(echo $ARCH_FILE | sed -e "s/nts_/nts_SR${SRNUM}_/")
		fi
	fi
	if echo $ARCH_FILE | egrep "_[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}." &> /dev/null; then
		TMP=$(echo $NEW_ARCH_FILE | sed -e "s/_[[:alnum:]]\{8\}-[[:alnum:]]\{4\}-[[:alnum:]]\{4\}-[[:alnum:]]\{4\}-[[:alnum:]]\{12\}/_${UUID}/g")
	else
		TAREXT=$(echo $ARCH_FILE | awk -F\. '{print $(NF-0)}')
		TMP=$(echo $NEW_ARCH_FILE | sed -e "s/\.${TAREXT}$/_${UUID}\.${TAREXT}/g")
	fi
	NEW_ARCH_FILE=$TMP
	logEntry Repackaging "${NEW_ARCH_FILE}"
	cd $SMT_INCOMING
	if echo $ARCH_FILE | grep 'tgz$' &> /dev/null; then
		TARCMP='z'
	else
		TARCMP='j'
	fi
	logEntry 'Extracting' 'In Progress'
	ARCH_DIR=$(echo $ARCH_FILE | sed -e 's/\.t[b,g]z$//')
	NEW_ARCH_DIR=$(echo $NEW_ARCH_FILE | sed -e 's/\.t[b,g]z$//')
	logFileCmd "tar ${TARCMP}xf $ARCH_FILE"
	if [ $? -gt 0 ]; then
		showStatus "${ARCH_FILE} - FAILED"
		logFileCmd "rm -rf $ARCH_DIR"
		RC=3
	else
		logFileCmd "mv $ARCH_DIR $NEW_ARCH_DIR"
		if [ ! -d $NEW_ARCH_DIR ]; then
			showStatus "ERROR, Directory conversion failed"
			echo
			RC=6
		else
			LOGCONTACT="${NEW_ARCH_DIR}/${SMT_CONTACT_FILE}"
			echo "Information Added by SMT Server" > $LOGCONTACT
			echo >> $LOGCONTACT
			echo "Date:                 $(date)" >> $LOGCONTACT
			echo "-------------------------------------------------------" >> $LOGCONTACT
			test -n "$SRNUM"           && echo "Service Request:      $SRNUM" >> $LOGCONTACT
			test -n "$CONTACT_COMPANY" && echo "Company Name:         $CONTACT_COMPANY" >> $LOGCONTACT
			test -n "$CONTACT_NAME"    && echo "Contact Name:         $CONTACT_NAME" >> $LOGCONTACT
			test -n "$CONTACT_PHONE"   && echo "Contact Phone:        $CONTACT_PHONE" >> $LOGCONTACT
			test -n "$CONTACT_EMAIL"   && echo "Contact EMail:        $CONTACT_EMAIL" >> $LOGCONTACT
			test -n "$CONTACT_STOREID" && echo "Store ID:             $CONTACT_STOREID" >> $LOGCONTACT
			test -n "$CONTACT_TERMID"  && echo "Terminal ID:          $CONTACT_TERMID" >> $LOGCONTACT
			echo >> $LOGCONTACT
			logEntry 'Details' Added

			logEntry 'Archiving' 'In Progress'
			logFileCmd "tar ${TARCMP}cf ${NEW_ARCH_FILE} ${NEW_ARCH_DIR}/*"
			if [ $? -gt 0 ]; then
				showStatus "${NEW_ARCH_FILE} - FAILED"
				ARCH_FILE="Failed"
				RC=5
			else
				md5sum ${NEW_ARCH_FILE} | cut -d' ' -f1 > ${NEW_ARCH_FILE}.md5
				rm -f ${ARCH_FILE}
				test -f ${ARCH_FILE}.md5 && rm -f ${ARCH_FILE}.md5
				rm -rf ${NEW_ARCH_DIR}
				ARCH_FILE=$NEW_ARCH_FILE
			fi
		fi
	fi
	return $RC
}

showIncoming() {
	startLogEntry
	checkIncoming
	setAction "List"
	countArchives
	listIncoming
}

removeArchive() {
	startLogEntry
	checkIncoming
	setAction "Remove One"
	showArchive
	FILEPATH=${SMT_INCOMING}/${ARCH_FILE}
	if [ -e $FILEPATH ]; then
		rm -f ${FILEPATH}*
		showStatus Removed
	else
		showStatus "ERROR, File not found"
		RCODE=2
	fi
}

emptyIncoming() {
	startLogEntry
	checkIncoming
	setAction "Remove All"
	countArchives
	RC=$?
	if [ $RC -gt 0 ]; then
		listIncoming
		rm -f ${SMT_INCOMING}/*t[b,g]z
		rm -f ${SMT_INCOMING}/*t[b,g]z.md5
		showStatus Removed
	else
		showStatus Empty
		RCODE=1
	fi
}

uploadArchive() {
	startLogEntry
	checkIncoming
	setAction "Upload One"
	showArchive
	COMPLETED=0
	if (( REPACKAGE )); then
		repackageArchive
		RPA=$?
		if [ $RPA -gt 0 ]; then
			showStatus "FAILED Repackage"
			echo
			RCODE=5
			return
		fi
	fi
	UPLOAD_FILEPATH=${SMT_INCOMING}/${ARCH_FILE}
	if [ -e ${UPLOAD_FILEPATH} ]; then
		logEntry Uploading $ARCH_FILE
		test -s ${UPLOAD_FILEPATH}.md5 && secureUpload ${UPLOAD_FILEPATH}.md5
		secureUpload ${UPLOAD_FILEPATH}
		if [ $? -eq 0 ]; then
			((COMPLETED++))
		fi
		if [ $COMPLETED -gt 0 ]; then
			showStatus "$ARCH_FILE - Success"
			if ! (( KEEP_AFTER_UPLOAD )) ; then
			    logEntry Removing $ARCH_FILE
			    test -s ${UPLOAD_FILEPATH}.md5 && logFileCmd "rm \"${UPLOAD_FILEPATH}.md5\""
			    logFileCmd "rm \"${UPLOAD_FILEPATH}\""
			fi
		else
			showStatus "$ARCH_FILE - FAILED secureUpload"
		fi
	else
		showStatus "ERROR, File not found: $UPLOAD_FILEPATH"
	fi
}

uploadIncoming() {
	startLogEntry
	checkIncoming
	setAction "Upload All"
	countArchives
	ARCH_TOTAL=$?
	if [ $ARCH_TOTAL -gt 0 ]; then
		cd $SMT_INCOMING
		COMPLETED=0
		for ARCH_FILE in *t[b,g]z
		do
			RPG_ERR=0
			if (( REPACKAGE )); then
				logEntry "Archive" $ARCH_FILE
				repackageArchive
				RPA=$?
				if [ $RPA -gt 0 ]; then
					showStatus "FAILED Repackage"
					RPG_ERR=1
				fi
			fi
			if [ $RPG_ERR -eq 0 ]; then
				UPLOAD_FILEPATH=${SMT_INCOMING}/${ARCH_FILE}
				logEntry Uploading $ARCH_FILE
				test -s ${UPLOAD_FILEPATH}.md5 && secureUpload ${UPLOAD_FILEPATH}.md5
				secureUpload ${UPLOAD_FILEPATH}
				if [ $? -eq 0 ]; then
					showStatus "$ARCH_FILE - Success"
					((COMPLETED++))
					if ! (( KEEP_AFTER_UPLOAD )) ; then
					    logEntry Removing $ARCH_FILE
					    test -s ${UPLOAD_FILEPATH}.md5 && logFileCmd "rm \"${UPLOAD_FILEPATH}.md5\""
					    logFileCmd "rm \"${UPLOAD_FILEPATH}\""
					fi
				else
					showStatus "$ARCH_FILE - FAILED secureUpload"
				fi
			fi
			echo
		done
		showStatus "Uploaded: $COMPLETED of $ARCH_TOTAL"
	else
		showStatus Empty
		RCODE=1
	fi
}

##############################################################################
# Main
##############################################################################

OPTARG=""
while true ; do
	case $1 in
	"") break ;;
	-i|--incoming) OPTARG=SMT_INCOMING ;;
	-s|--srnum) REPACKAGE=1; OPTARG=SRNUM ;;
	-n|--name) REPACKAGE=1; OPTARG=CONTACT_NAME ;;
	-c|--company) REPACKAGE=1; OPTARG=CONTACT_COMPANY ;;
	-d|--storeid) REPACKAGE=1; OPTARG=CONTACT_STOREID ;;
	-t|--terminalid) REPACKAGE=1; OPTARG=CONTACT_TERMID ;;
	-p|--phone) REPACKAGE=1; OPTARG=CONTACT_PHONE ;;
	-e|--email) REPACKAGE=1; OPTARG=CONTACT_EMAIL ;;
	-h|-H|--help) ACTION=0 ;;
	-l|--list) ACTION=1 ;;
	-r|--remove) ACTION=2; OPTARG=ARCH_FILE ;;
	-R|--empty) ACTION=3 ;;
	-u|--upload) ACTION=4; OPTARG=ARCH_FILE ;;
	-U|--uploadall) ACTION=5 ;;
	--keep-after-upload) KEEP_AFTER_UPLOAD=1;;
	*) title; show_help "ERROR: Invalid Option $1" ;;
	esac
	if [ -n "$OPTARG" ] ; then
		test -z "$2" && { title; show_help "ERROR: Missing Argument, Option $1 Needs an Argument"; }
		eval $OPTARG=\$2
		shift
		OPTARG=""
	fi
	shift
done

title
validateSR
case $ACTION in
	0) show_help ;;
	1) showIncoming ;;
	2) removeArchive ;;
	3) emptyIncoming ;;
	4) uploadArchive ;;
	5) uploadIncoming ;;
esac
echo
exit $RCODE;

