#!/bin/sh
#
# This script contains code originating from multiple sources.
#
# Code from Slackware:
# Copyright 2000, 2001, 2002, 2003, 2004, 2005  Patrick Volkerding, Concord, CA  USA
#    All rights reserved.
#
# Code from swaret-tools:
# Copyright Michael G. Manry <linuxsneaker@users.sourceforge.net>
#
# Code from Slackles pkgtools and making this script version:
# Copyright (C) 2005 Lasse Collin <lasse.collin@slackware.fi>
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Last modified: Sat Apr 23 13:09:21 EEST 2005
#

# Load shared functions:
. /usr/share/pkgtools/shared_functions.sh

TMP=$(mktemp -dt slackrepo.XXXXXX) || exit

# Make sure that temp dir gets removed on exit:
trap "exit_slackrepo 1" SIGINT

usage() {
  cat << EOF

Make a Slackles compatible repository.

Usage: slackrepo [options] directory

Options:  -f, --filelist      Create FILELIST.TXT
          -p, --packages      Create PACKAGES.TXT
          -m, --md5           Create CHECKSUMS.md5
          -s, --sha1          Create CHECKSUMS.sha1

If no options are given slackrepo defaults to -fpms.

EOF
  exit_slackrepo 0
}

create_packagestxt() {
  mknod "$TMP/fifo" p
  echo "Creating PACKAGES.TXT:"
  echo "PACKAGES.TXT;  $(date)" > "$TMP/PACKAGESHEADER.TXT"
  echo >> "$TMP/PACKAGESHEADER.TXT"
  echo "This file provides details on the packages found on this site" >> "$TMP/PACKAGESHEADER.TXT"
  TOTALCSIZE=0
  TOTALUSIZE=0
  for i in $(find . -follow -name '*.tgz' -or \
                    -name '*.tlz' -or \
                    -name '*.tbz' | sed '/\/source\//d')
    do
    echo "$i"
    j=$(basename $i)
    k=$(echo "$i" | sed 's,^.*/,,;s,\.\(tgz\|tlz\|tbz\|tar\)$,,;s,-[^-]*-[^-]*-[^-]*$,,')
    echo "PACKAGE NAME:      $j" >> "$TMP/PACKAGESBODY.TXT"
    echo "PACKAGE LOCATION:  $(dirname $i)" >> "$TMP/PACKAGESBODY.TXT"
    ( uncompress_pkg "$i" | tee "$TMP/fifo" | $TAR xOf - -C "$TMP" \
        install/slack-desc 2> /dev/null | egrep '^[a-zA-Z0-9.,!@_+-]+:' > "$TMP/tmp-desc" ) &
    USIZE=$(wc -c < "$TMP/fifo" | tr -d ' ')
    # FIXME: Something weird here (race condition?), without sleeping random packages
    # are left without description. If someone knows how to do this loop with one decompress
    # command, please contact Larhzu (IRC or email). This sleep fixes the problem temporarily.
    sleep .5
    USIZE=$(($USIZE / 1024))
    CSIZE=$(ls -skL "$i" | cut -f 1 -d ' ')
    printf "PACKAGE SIZE (compressed):   %7d K\n" "$CSIZE" >> "$TMP/PACKAGESBODY.TXT"
    printf "PACKAGE SIZE (uncompressed): %7d K\n" "$USIZE" >> "$TMP/PACKAGESBODY.TXT"
    echo "PACKAGE DESCRIPTION:" >> "$TMP/PACKAGESBODY.TXT"
    uniq "$TMP/tmp-desc" 2> /dev/null >> "$TMP/PACKAGESBODY.TXT"
    echo >> "$TMP/PACKAGESBODY.TXT"
    TOTALCSIZE=$(($TOTALCSIZE + $CSIZE))
    TOTALUSIZE=$(($TOTALUSIZE + $USIZE))
  done
  TOTALCSIZE=$(($TOTALCSIZE / 1024))
  TOTALUSIZE=$(($TOTALUSIZE / 1024))
  printf "Total size of all packages (compressed) :   %5d MB\n" "$TOTALCSIZE" >> "$TMP/PACKAGESHEADER.TXT"
  printf "Total size of all packages (uncompressed) : %5d MB\n" "$TOTALUSIZE" >> "$TMP/PACKAGESHEADER.TXT"
  echo >> "$TMP/PACKAGESHEADER.TXT"
  echo >> "$TMP/PACKAGESHEADER.TXT"
  cat "$TMP/PACKAGESHEADER.TXT" "$TMP/PACKAGESBODY.TXT" | uniq > "$TMP/PACKAGES.TXT"
}

create_filelist() {
  echo "Creating FILELIST.txt"
  date > "$TMP/FILELIST.TXT"
  echo >> "$TMP/FILELIST.TXT"
  echo "Here is the file list for this directory." >> "$TMP/FILELIST.TXT"
  echo >> "$TMP/FILELIST.TXT"
  find . -follow -print | sort | xargs ls -ldL --time-style=long-iso >> "$TMP/FILELIST.TXT"
}

create_md5sums() {
  echo "Creating CHECKSUMS.md5"
  cat << EOF > "$TMP/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:

md5sum -c CHECKSUMS.md5 | 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
find . -type f -print | grep -v CHECKSUMS | grep -v isolinux/isolinux.bin \
    | sort | xargs md5sum >> "$TMP/CHECKSUMS.md5"
}

create_sha1sums() {
  echo "Creating CHECKSUMS.sha1"
  cat << EOF > "$TMP/CHECKSUMS.sha1"
These are the SHA1 message digests for the files in this directory.
If you want to test your files, use 'sha1sum' and compare the values to
the ones listed here.

To test all these files, use this command:

sha1sum -c CHECKSUMS.sha1 | less

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

SHA1 message digest                       Filename
EOF
find . -type f -print | grep -v CHECKSUMS | grep -v isolinux/isolinux.bin \
    | sort | xargs sha1sum >> "$TMP/CHECKSUMS.sha1"
}

exit_slackrepo() {
  rm -rf "$TMP"
  exit $1
}

[ $# = 0 ] && usage
ARGS=$(getopt -n slackrepo -o pfmsh -l packages,filelist,md5,sha1,help -- "$@")
[ $? != 0 ] && exit_slackrepo 99
eval set -- "$ARGS"
unset ARGS PACKAGESTXT MD5SUMS SHA1SUMS FILELISTTXT
while [ $# != 0 ]; do
  case "$1" in
    -p|--packages)         PACKAGESTXT=yes ;;
    -m|--md5)              MD5SUMS=yes ;;
    -s|--sha1)             SHA1SUMS=yes ;;
    -f|--filelist)         FILELISTTXT=yes ;;
    -h|--help)             usage ;;
    --)                    shift; break ;;
    *)                     exit_getopt_error ;;
  esac
  shift
done

if [ $# != 1 ]; then
  echo "Invalid argument count. Try 'slackrepo --help'."
  exit_slackrepo 99
fi

if [ ! -d "$1" ]; then
  echo "Directory '$1' does not exist."
  exit_slackrepo 1
fi
cd "$1"

if [ "$PACKAGESTXT$FILELISTTXT$MD5SUMS$SHA1SUMS" = "" ]; then
  create_packagestxt
  create_md5sums
  create_sha1sums
  create_filelist
else
  [ "$PACKAGESTXT" != "" ] && create_packagestxt
  [ "$MD5SUMS" != "" ] && create_md5sums
  [ "$SHA1SUMS" != "" ] && create_sha1sums
  [ "$FILELISTTXT" != "" ] && create_filelist
fi

mv -f "$TMP/FILELIST.TXT" "$TMP/CHECKSUMS.md5" "$TMP/CHECKSUMS.sha1" "$TMP/PACKAGES.TXT" . 2> /dev/null
exit_slackrepo 0
