#!/bin/sh

export LANG=C

if [ -f ~/.metagen.lock ];then
	echo "Another metagen.sh instance seems to be running!"
	echo "Check with ps and remove the ~/.metagen.lock file if it is leftover somehow."
	exit 1
else
	touch ~/.metagen.lock
fi

function forcedkill {
	echo "Aborting..."
	rm ~/.metagen.lock
	exit 0
}

# catch SIGINT and SIGTERM, remove metagen.lock file
trap 'forcedkill' 1 2 3 15

function gen_packages_txt {
	echo '' > PACKAGES.TXT    
	find ./slackel -type f -name '*.meta' -exec cat {} \; >> PACKAGES.TXT

	# Make sure alternative packages are always specified as deps
	# cxxlibs
	#sed -i \
	#"s/^gcc-g++/cxxlibs|gcc-g++/" \
	#PACKAGES.TXT
	#sed -i \
	#"s/,gcc-g++/,cxxlibs|gcc-g++/" \
	#PACKAGES.TXT
	# cxxlibs
	sed -i \
	"s/^cxxlibs|gcc-g++/gcc-g++/" \
	PACKAGES.TXT
	sed -i \
	"s/,cxxlibs|gcc-g++/,gcc-g++/" \
	PACKAGES.TXT
	
	
	# openssl
	sed -i \
	"s/^openssl,/openssl-solibs|openssl,/" \
	PACKAGES.TXT
	sed -i \
	"s/,openssl,/,openssl-solibs|openssl,/" \
	PACKAGES.TXT
	sed -i \
	"s/,openssl$/,openssl-solibs|openssl/" \
	PACKAGES.TXT
	sed -i \
	"s/^openssl$/openssl-solibs|openssl/" \
	PACKAGES.TXT

	# Prefer the solibs packages if none is installed
	sed -i \
	"s/seamonkey|seamonkey-solibs/seamonkey-solibs|seamonkey/" \
	PACKAGES.TXT
	sed -i \
	"s/glibc|glibc-solibs/glibc-solibs|glibc/" \
	PACKAGES.TXT
	sed -i \
	"s/openssl|openssl-solibs/openssl-solibs|openssl/" \
	PACKAGES.TXT

	cat PACKAGES.TXT | gzip -9 -c - > PACKAGES.TXT.gz
}

function gen_meta {
	unset REQUIRED CONFLICTS SUGGESTS
	if [ ! -f $1 ]; then
		echo "File not found: $1"
		exit 1;
	fi
		if [ "`echo $1|grep -E '(.*{1,})-(.*[\.\-].*[\.\-].*).t[glx]z[ ]{0,}$'`" == "" ]; then
			return;
		fi
	NAME=$(echo $1|sed -re "s/(.*\/)(.*.t[glx]z)$/\2/")
	LOCATION=$(echo $1|sed -re "s/(.*)\/(.*.t[glx]z)$/\1/")
	if [[ `echo $1 | grep "tgz$"` ]]; then
		SIZE=$( expr `gunzip -l $1 |tail -1|awk '{print $1}'` / 1024 )
		USIZE=$( expr `gunzip -l $1 |tail -1|awk '{print $2}'` / 1024 )
	elif [[ `echo $1 | grep "t[lx]z$"` ]]; then
		SIZE=$( expr `ls -l $1 | awk '{print $5}'` / 1024 )
		#USIZE is only an appoximation, nothing similar to gunzip -l for lzma yet
		USIZE=$[$SIZE * 4 ]
	fi
	
	METAFILE=${NAME%t[glx]z}meta
	
	if test -f $LOCATION/${NAME%t[glx]z}dep
	then
		REQUIRED="`cat $LOCATION/${NAME%t[glx]z}dep`"
	fi
	if test -f $LOCATION/${NAME%t[glx]z}con
	then
		CONFLICTS="`cat $LOCATION/${NAME%t[glx]z}con`"
	fi
	if test -f $LOCATION/${NAME%t[glx]z}sug
	then
		SUGGESTS="`cat $LOCATION/${NAME%t[glx]z}sug`"
	fi
	echo "PACKAGE NAME:  $NAME" > $LOCATION/$METAFILE
	if [ -n "$DL_URL" ]; then
		echo "PACKAGE MIRROR:  $DL_URL" >> $LOCATION/$METAFILE
	fi
	echo "PACKAGE LOCATION:  $LOCATION" >> $LOCATION/$METAFILE
	echo "PACKAGE SIZE (compressed):  $SIZE K" >> $LOCATION/$METAFILE
	echo "PACKAGE SIZE (uncompressed):  $USIZE K" >> $LOCATION/$METAFILE
	echo "PACKAGE REQUIRED:  $REQUIRED" >> $LOCATION/$METAFILE
	echo "PACKAGE CONFLICTS:  $CONFLICTS" >> $LOCATION/$METAFILE
	echo "PACKAGE SUGGESTS:  $SUGGESTS" >> $LOCATION/$METAFILE
	echo "PACKAGE DESCRIPTION:" >> $LOCATION/$METAFILE
	if test -f $LOCATION/${NAME%t[glx]z}txt
	then
		cat $LOCATION/${NAME%t[glx]z}txt |grep -E '[^[:space:]]*:'|grep -v '^#' >> $LOCATION/$METAFILE
	else
		if [[ `echo $1 | grep "tgz$"` ]]; then
			tar xfO $1 install/slack-desc |grep -E '[^[:space:]]*:'|grep -v '^#' >> $LOCATION/$METAFILE
			tar xfO $1 install/slack-desc |grep -E '[^[:space:]]*:'|grep -v '^#' > $LOCATION/${NAME%t[glx]z}txt
		elif [[ `echo $1 | grep "txz$"` ]]; then
			xz -c -d $1 | tar xO install/slack-desc |grep -E '[^[:space:]]*:'|grep -v '^#' >> $LOCATION/$METAFILE
			xz -c -d $1 | tar xO install/slack-desc |grep -E '[^[:space:]]*:'|grep -v '^#' > $LOCATION/${NAME%t[glx]z}txt
		elif [[ `echo $1 | grep "tlz$"` ]]; then
			lzma -c -d $1 | tar xO install/slack-desc |grep -E '[^[:space:]]*:'|grep -v '^#' >> $LOCATION/$METAFILE
			lzma -c -d $1 | tar xO install/slack-desc |grep -E '[^[:space:]]*:'|grep -v '^#' > $LOCATION/${NAME%t[glx]z}txt
		fi
	fi
	echo "" >> $LOCATION/$METAFILE
}


function gen_rss {
	RSSFILE=rss-packages.xml

	SALIXVER=$( basename `pwd` )

	echo "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
<rss version=\"2.0\">
<channel>
<title>Slackel $SALIXVER packages</title>
<link>http://www.slackel.gr</link>
<description>Slackel $SALIXVER package ChangeLog</description>
<language>en-us</language>

<image>
<title>Slackel - Hellenic Linux Distribution</title>
<url>http://www.slackel.gr</url>
<link>http://www.slackel.gr</link>
<width>64</width>
<height>64</height>
</image>
" > $RSSFILE

	sed ':a;N;$!ba;s/\n  / /g' ChangeLog.txt | \
	grep "^a/\|^ap/\|^d/\|^f\|^games\|^gnome\|^kde\|^l/\|^locale/\|^openbox/\|^mate/\|^xfce/\|^n/\|^n/\|^x/\|^xap/\|^core/\|^extra/\|^games/\|^slack_files/\|^k/\|^locale/\|^special/\|^sailors/\|^settings/" |\
	sed "s|^\(.*\)/\(.*\)\(\.t[gxbl]z\):\(.*\)|<item>\n<title>\2</title>\n<description>\n\1/\2\3:\4\n</description>\n</item>\n|" \
	>> $RSSFILE
	echo -e "</channel>\n</rss>\n" >> $RSSFILE

	# replace characters that are illegal in xml
	sed -i "s/&/\&amp;/g" $RSSFILE
	sed -i "s/'/\&apos;/g" $RSSFILE
	# replace all instances of ", < or > with &quot;, &gt; and &lt;
	#respectively, but not in tags!
	sed -i '/<?xml \|<rss /!s/"/\&quot;/g' $RSSFILE
	sed -i '/<?xml \|<image>\|<\/image>\|<url>\|<\/url>\|<width>\|<\/width>\|<height>\|<\/height>\|<item>\|<\/item>\|<rss \|<\/rss>\|<language>\|<\/language>\|<channel>\|<\/channel>\|<title>\|<\/title>\|<link>\|<\/link>\|<description>\|<\/description>\|<languages>\|<\/languages>/!s/>/\&gt;/g' $RSSFILE
	sed -i '/<?xml \|<image>\|<\/image>\|<url>\|<\/url>\|<width>\|<\/width>\|<height>\|<\/height>\|<item>\|<\/item>\|<rss \|<\/rss>\|<language>\|<\/language>\|<channel>\|<\/channel>\|<title>\|<\/title>\|<link>\|<\/link>\|<description>\|<\/description>\|<languages>\|<\/languages>/!s/</\&lt;/g' $RSSFILE
}

#////////////////
# Repository maintainer
REPOSOWNER=${REPOSOWNER:-"F2A8DB58"}
#REPOSOWNER=${REPOSOWNER:-"9E10D250"}
#REPOSOWNER=${REPOSOWNER:-"Dimitris Tzemos <dijemos@gmail.com>"}
REPOOWNER="Dimitris Tzemos <dijemos@gmail.com>"
#9E10D250"}
# You can enable this by passing the "-a" parameter to the script.
FORCEASC="no"
FORCEPKG="no"
# Either use gpg or gpg2:
GPGBIN=${GPGBIN:-"/usr/bin/gpg"}
TOUCHUP="yes"  
UPDATEDATE="$(LC_ALL=C date -u)"
# By default, no debug messages
DEBUG=0

#
# pkgcomp
#
function pkgcomp {
  # Return the compression utility used for this package,
  # based on the package's extension.
  # Determine extension:
  PEXT="$( echo $1 | rev | cut -f 1 -d . | rev)"
  # Determine compression used:
  case $PEXT in
  'tgz' )
    COMP=gzip
    ;;
  'tbz' )
    COMP=bzip2
    ;;
  'tlz' )
    COMP=lzma
    ;;
  'txz' )
    COMP=xz
    ;;
  esac
  echo ${COMP:-"gzip"}
}

#
# addman
#
function addman {
  # Add a package's content to the MANIFEST file
  # Argument #1 : full path to a package
  # Argument #2 : full path to MANIFEST file

  if [ ! -f "$1" -o ! -f "$2" ]; then
    echo "Required arguments '$1' and/or '$2' are invalid files!"
    exit 1
  fi
  PKG=$1
  MANIFESTFILE=$2

  if [ "$(echo $PKG|grep -E '(.*{1,})\-(.*[\.\-].*[\.\-].*).t[blxg]z[ ]{0,}$')" == "" ];
  then
    return;
  fi

  NAME=$(echo $PKG|sed -re "s/(.*\/)(.*.t[blxg]z)$/\2/")
  LOCATION=$(echo $PKG|sed -re "s/(.*)\/(.*.t[blxg]z)$/\1/")
  LSTFILE=${NAME%t[blxg]z}lst

  if [ "$FORCEPKG" == "yes" -o ! -f $LOCATION/$LSTFILE ]; then
    echo "--> Generating .lst file for $NAME"
   # Determine the compression tool used for this package:
    COMPEXE=$( pkgcomp $PKG )
 		
    cat << EOF > $LOCATION/$LSTFILE
++========================================
||
||   Package:  $PKG
||
++========================================
EOF

    $COMPEXE -cd $PKG | tar -tvvf - >> $LOCATION/$LSTFILE
    echo "" >> $LOCATION/$LSTFILE
    echo "" >> $LOCATION/$LSTFILE
    [ "$TOUCHUP" == "yes"  ] && touch -r $PKG $LOCATION/$LSTFILE || touch -d "$UPDATEDATE" $LOCATION/$LSTFILE
  fi

  # Compensate for partial pathnames in .lst files found in sub-repos:
  cat $LOCATION/$LSTFILE \
   | sed -e "s%^||   Package:  .*$%||   Package:  $PKG%" \
   >> $MANIFESTFILE
} # end of function 'addman'

#
# gen_checksums
#
gen_checksums() {
FOLLOW_SYMLINKS=${FOLLOW_SYMLINKS:-1}
PRUNES=""
  # Run through a repository tree, generating the checksum files.

  # Change directory to the root of the repository, so all generated
  # information is relative to here:
  local RDIR=$1

  cd $RDIR

  # Create temporary CHECKSUMS.md5 file:
  cat /dev/null > .CHECKSUMS.md5

  # Generate the overall CHECKSUMS.md5 for this (sub-)repo:
  cat << EOF > .CHECKSUMS.md5
These are the MD5 message digests for the files in this directory.
If you want to test your files, use 'md5sum' and compare the values to
the ones listed here.

To test all these files, use this command:

tail +13 CHECKSUMS.md5 | md5sum --check | less

'md5sum' can be found in the GNU coreutils package on ftp.gnu.org in
/pub/gnu, or at any GNU mirror site.

MD5 message digest                Filename
EOF
  if [ $FOLLOW_SYMLINKS -eq 1 ]; then
    find -L . -type f -print $PRUNES | grep -v CHECKSUMS | sort | xargs md5sum $1 2>/dev/null >> .CHECKSUMS.md5
  else
    find . -type f -print $PRUNES | grep -v CHECKSUMS | sort | xargs md5sum $1 2>/dev/null >> .CHECKSUMS.md5
  fi
  cat .CHECKSUMS.md5 > CHECKSUMS.md5
  gzip -9cf CHECKSUMS.md5 > CHECKSUMS.md5.gz

  rm -f .CHECKSUMS.md5 CHECKSUMS.md5.asc CHECKSUMS.md5.gz.asc
  #USEGPG="yes"
  #if [ "$USEGPG" == "yes" ]; then
    # The CHECKSUMS.md5* files need a gpg signature:
    #rm -f CHECKSUMS.md5.gz.asc
	#gpg -sba CHECKSUMS.md5.gz
	#rm -f CHECKSUMS.md5.asc
	#gpg -sba CHECKSUMS.md5
    gpg_sign CHECKSUMS.md5
    gpg_sign CHECKSUMS.md5.gz
  #fi

} # End gen_checksums()

#
# gen_filelist
#
function gen_filelist {
FOLLOW_SYMLINKS=${FOLLOW_SYMLINKS:-1}
PRUNES=""
  # Argument #1 : full path to a directory
  # Argument #2 : output filename (defaults to FILELIST.TXT) will be
  #               created in directory $1 (overwriting existing file).

  if [ ! -d "$1" ]; then
    echo "Required argument '$1' must be a directory!"
    exit 1
  fi
  DIR=$1
  LISTFILE=${2:-FILELIST.TXT}

  ( cd ${DIR}
    cat <<EOT > ${LISTFILE}
$UPDATEDATE

Here is the file list for ${DL_URL:-this directory} ,
maintained by ${REPOOWNER} .
If you are using a mirror site and find missing or extra files
in the subdirectories, please have the archive administrator
refresh the mirror.

EOT
    if [ $FOLLOW_SYMLINKS -eq 1 ]; then
      find -L . -print $PRUNES | sort | xargs ls -nld --time-style=long-iso >> ${LISTFILE}
    else
      find . -print $PRUNES | sort | xargs ls -nld --time-style=long-iso >> ${LISTFILE}
    fi
  )
} # end of function 'gen_filelist'


#
# gpg_sign
#
function gpg_sign {
  # Create a gpg signature for a file. Use either gpg or gpg2 and optionally
  # let gpg-agent provide the passphrase.
    echo $TRASK | $GPGBIN -bas -u "$REPOSOWNER" --passphrase-fd 0 --batch --quiet $1
  return $?
}

#
# genasc
#
function genasc {
  # Generate a package's GPG signature (*.asc file) if missing,
  # Argument #1 : full path to a package

  if [ ! -f "$1" ]; then
    echo "Required argument '$1' is invalid filename!"
    exit 1
  fi
  PKG=$1


  NAME=$(echo $PKG|sed -re "s/(.*\/)(.*.t[blxg]z)$/\2/")
  LOCATION=$(echo $PKG|sed -re "s/(.*)\/(.*.t[blxg]z)$/\1/")
  ASCFILE=${NAME}.asc

  if [ "$FORCEASC" == "yes" -o ! -f $LOCATION/$ASCFILE ]; then
    echo "--> Generating .asc file for $NAME"
    (cd $LOCATION
     rm -f $ASCFILE
     gpg_sign $NAME
    )
    [ "$TOUCHUP" == "yes"  ] && touch -r $PKG $LOCATION/$ASCFILE || touch -d "$UPDATEDATE" $LOCATION/$ASCFILE
  fi

} # end of function 'genasc'
#////////////////
case "$1" in
	pkg)
		if [ -n "$2" ]; then
			gen_meta $2
		else
			echo "$0 [pkg [file]|all|new|PACKAGESTXT|md5]"
		fi
	;;
	all)
		for pkg in `find ./slackel -type f -name '*.t[glx]z' -print`
		do
			gen_meta $pkg
		done
		#$0 PACKAGESTXT
		gen_packages_txt
		gen_rss
	;;
	new)
		for pkg in `find ./slackel -type f -name '*.t[glx]z' -print`
		do
			if [ ! -f ${pkg%t[glx]z}meta ]; then
				gen_meta $pkg
			fi
		done
		#$0 PACKAGESTXT
		gen_packages_txt
		gen_rss
	;;
	PACKAGESTXT)
		gen_packages_txt
	;;
	md5)
		echo '' > CHECKSUMS.md5
		PKGS=$( find ./slackel -type f -name '*.t[glx]z' -o -name '*.t[glx]z.asc' | sort )

		#for pkg in `find ./slackel -type f -name '*.t[glx]z' -print`
		for pkg in $PKGS
		do
		if [[ "${pkg##*.}" = *t[glx]z* ]]; then
			if [ ! -f ${pkg%t[glx]z}md5 ]; then
				md5sum ${pkg} | sed "s|  \.\(.*\)/\(.*\)|  \2|" > ${pkg%t[glx]z}md5
			fi
			cat ${pkg%t[glx]z}md5 | sed "s|`basename ${pkg}`|${pkg}|" >> CHECKSUMS.md5
		fi
		if [ "${pkg##*.}" = "asc" ]; then
				md5sum ${pkg} | sed "s|  \.\(.*\)/\(.*\)|  \2|" | sed "s|`basename ${pkg}`|${pkg}|" >> CHECKSUMS.md5
		fi	
		done
		cat CHECKSUMS.md5 | gzip -9 -c - > CHECKSUMS.md5.gz
		rm -f CHECKSUMS.md5.gz.asc
		gpg -sba CHECKSUMS.md5.gz
		rm -f CHECKSUMS.md5.asc
		gpg -sba CHECKSUMS.md5
	;;
	asc)
		read -ers -p "Enter your GPG passphrase: "
		TRASK=$REPLY
		echo "."
		if [ "$REPLY" == "" ]; then
			echo "Empty GPG passphrase - disabling generation of signatures."
			#exit
		else
			if [ "$2" == "-a" ]; then
				FORCEASC="yes"
			fi   
			for pkg in `find ./slackel -type f -name '*.t[glx]z' -print`
			do
				genasc $pkg
			done 
		fi
		# Clean up:
		TRASK=""
	;;
	man)
			if [ "$2" == "-a" ]; then
				FORCEPKG="yes"
			fi 
			
			echo "" > .MANIFEST
			PKGS=$( find ./slackel -type f -name '*-*-*-*.t[blxg]z' -print | sort )
			for pkg in $PKGS; do
			#for pkg in `find ./slackel -type f -name '*.t[glx]z' -print`
			#do
			# Found a filename with matching format, is it really a slackpack?
			COMPEXE=$( pkgcomp $pkg )
			if $COMPEXE -cd $pkg | tar tOf - install/slack-desc 1>/dev/null 2>&1 ; then
			[ $DEBUG -eq 1 ] && echo "+++ Found package $pkg"
				# We need to run addman for every package, to populate MANIFEST
				addman $pkg .MANIFEST
			else
				echo "*** Warning: $pkg does not contain a slack-desc file. ***"
			fi	
			done
			cat .MANIFEST > MANIFEST
			rm -f .MANIFEST
  
			bzip2 -9f MANIFEST
	;;			
	rss)
		gen_rss
	;;
	filelist)
		# generate the FILELIST.TXT 
		gen_filelist ./
	;;
	checksums)
		#if [ "$2" == "-a" ]; then
		#	USEGPG="yes"
		#fi
		read -ers -p "Enter your GPG passphrase: "
		TRASK=$REPLY
		echo "."
		if [ "$REPLY" == "" ]; then
			echo "Empty GPG passphrase - disabling generation of signatures."
			exit
		else
			gen_checksums ./
		fi
		# Clean up:
		TRASK=""	
	;;
	*)
		echo "$0 [pkg [file]|all|new|PACKAGESTXT|md5|rss|asc|filelist|checksums [-a]|man [-a]]"
		echo "$0 [miss|provide] pattern"
	;;
esac

rm ~/.metagen.lock

