#!/bin/sh
version=2.2
################################################################################
#
# rpmoncd - merges files or rpm-packages into a single CD-distribution
#
# Copyright (C) 1999-2001, 2007 Dimitar Ivanov, <dimitar.ivanov@mirendom.net>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
#set -x
progname=`basename $0`
startdir=$PWD
rpmdir=$PWD
packdir=RPMS
lfile=ListOfAllSourceFiles
listofallrpms=ListOfAllFilesOnCDs
cdbase=CD
mbcdsize=640
pm=50 # echo '.' at every $pm-th step
numfile=.packagenumber
umask 077
MkList=no
MkISO=no
ext=.rpm
trap 'cd $startdir; if [ -f $numfile ]; then rm -f $numfile; fi; exit' 0 1 2 3 15
echo='/bin/echo -e'
mv=mv
#################################
gops="hb:s:lcie:p:"
set -- `getopt $gops $*`
if [ $? != 0 -o $# -eq 1 ]; then
    set -- "-h"
fi

while [ $# -gt 0 ]
do
    case $1 in
    -l) MkList=yes
        ;;
    -i) MkISO=yes
        ;;
    -b) shift
        rpmdir="$1"
        ;;
    -c) mv=cp
        ;;
    -e) shift
        ext="$1"
        if [ "$ext" = "." ]; then ext=""; fi
        if [ "$packdir" = "RPMS" -a "$ext" != ".rpm" ]; then packdir=.; fi
        ;;
    -s) shift
        mbcdsize="$1"
        ;;
    -p) shift
        packdir="$1"
        ;;
    -h)
cat << HELP
--------------------------------------------------------------------------------
rpmoncd $version: merges files or rpm-packages into a single CD-distribution
--------------------------------------------------------------------------------

Usage: $progname [-option(s)] directory-name(s)
          -b <dirname> - directory base for the distribution (will be
                         created if not existing). Default is \$CWD.
          -c           - copy the files (default is to move them)
          -e <ext>     - extension of the file names (default is "$ext").
                         "-e ." matches all files.
          -s #         - size of a single CD in Mb (default is ${mbcdsize})
          -l           - make a list of all files/packages in the directories
          -i           - make ISO-images from the prepare distribution
                         directories (needs 'mkisofs')
          -p <dirname> - name for the package directory in the CD-directory
                         (default is "$packdir" for rpm-files, and "./" otherwise)
          -h           - help

Use '-l' and '-i' after the distribution is prepared!

HELP
        exit 0;;
    --) shift
        break;;
    esac
    shift
done
#
#
for rpmpath in $*
do
    if [ ! -d $rpmpath ]; then
       echo "No such directory: $rpmpath"
       echo Bye!
       exit 1
    fi
done
#
if [ ! -d $rpmdir ]; then
   echo "Creating directory $rpmdir"
   mkdir -m 700 $rpmdir
fi

allcddir=`echo $* |sort`
if [ -z "$allcddir" ]; then
   allcddir=`find . -name "${cdbase}*" -type d -print |sort`
   if [ -z "$allcddir" ]; then
      echo "No such directories: ${cdbase}*. Give me the right names."
      exit 1
   fi
fi

if [ "$MkList" = "yes" ]; then
   find $allcddir -name "*$ext" -print > $listofallrpms
   for directory in $allcddir
   do
      if [ ! -d $directory ]; then
         echo "No such directory: $directory"
         continue
      fi
      if [ -w $directory ]; then
         echo "Copying '$listofallrpms' to $directory"
         cp $listofallrpms $directory
      else
         echo "Directory $directory is read only, skipping."
      fi
   done
   rm -f $listofallrpms
fi

if [ "$MkISO" = "yes" ]; then
   for directory in $allcddir
   do
      $echo "\nMaking iso from $directory\n"
      mkisofs -quiet -A "$directory" -L -r -p "LinuxFans" -o "$directory.iso" "$directory"
   done
   echo "Ready."
fi
if [ "$MkISO" = "yes" -o "$MkList" = "yes" ]; then
   exit 0
fi

echo Making list of packages:
cat /dev/null > $lfile
i=0
for rpmpath in $*
do
    echo $rpmpath
	for rpmfile in $rpmpath/*$ext
	do
        let i=i+1 
        if [ "$ext" = ".rpm" ]; then
           rpm -qp --queryformat "%{NAME} %{BUILDTIME} $rpmfile\n" $rpmfile >> $lfile
        else
           echo $rpmfile >> $lfile
        fi
        if [ "`echo $i%$pm |bc`" = "0" ]; then $echo ".\c"; fi
    done
	echo
done

echo Merging packages in $rpmdir
echo Trying to count...
if [ "$ext" = ".rpm" ]; then
     sort -r $lfile |sort -u |rev |cut -f1 -d" " |rev |tr '\n' '\000' |xargs -0 -i sh -c "grep -n {} $lfile > $numfile; if [ -r {} ]; then $mv {} $rpmdir; else echo can\'t read : {}; fi; grep 00: $numfile"
else
     cat $lfile |tr '\n' '\000' |xargs -0 -i -t $mv "{}" $rpmdir
fi
echo Hey! It\'s fun!
echo "$i processed packages listed in $lfile."
echo

echo "Going to base now: cd to $rpmdir"
mv $lfile $rpmdir
cd $rpmdir

echo Preparing CD-directories...
echo "Default maximum size of a CD-directory: ${mbcdsize}Mb"
# Compute Default size of one CD in bytes
cdsize=`echo "$mbcdsize*1024*1024" |bc` 
pm=20
lsize=$cdsize
j=1
i=0
allcddir=""
for rpmfile in ./*$ext
do 
   if [ "$ext" = ".rpm" ]; then
      fullpack=`basename $rpmfile |cut -f1 -d-`
   else
      fullpack=dummy.dummy
   fi
   packsize=`du -b -L "$rpmfile" |cut -f1`
   lsize=`echo "$lsize+$packsize" |bc`
   if [ "$lsize" -gt "$cdsize" ]; then
      lsize=$packsize
      cddir=$cdbase$j
      if [ $j -ne 1 ]; then
         echo
         echo "$i files of `du -k -L $lastdir |cut -f1`Kb on $lastdir"
         echo "Last file in $lastdir : $lastfile"
         echo "Next file : $rpmfile"
         lastcdsize=`du -ks $lastdir |cut -f1`; lastcdsize=`echo $lastcdsize/1024 |bc`; echo "CD size: ${lastcdsize}Mb"
         echo ""
      fi
      if [ -d $cddir ]; then
         echo "$cddir exists ..."
         echo Type new CD-directory name:
         read cddir
      fi
      mkdir -m 755 $cddir;
      if [ ! -d $cddir/$packdir ]; then
           mkdir -m 755 $cddir/$packdir
      fi
      allpackdir="$allpackdir $cddir"
      cddir=$cddir/$packdir
      if [ "$lastfullpack" = "$fullpack" ]; then
         if [ "$lastadjust" = "$lastfullpack" ]; then
            echo "Endless LOOP! Increase the default CD-size of ${mbcdsize}Mb."
            echo "You should move the package files to their original place(s)."
            exit 2
         fi
         echo "Adjusting packages on $lastdir:"
         echo "moving $lastdir/$lastfullpack-*$ext to $cddir"
         mv $lastdir/$lastfullpack-*$ext $cddir
         lsize=`du -b -L $cddir |cut -f1`
         lsize=`echo "$lsize+$packsize" |bc`
         $echo "Continuing with next directory...\n"
         lastadjust=$lastfullpack
      fi
      lastdir=$cddir
      let j=j+1
      echo Moving packages to $cddir now.
      allcddir="$allcddir $cddir"
      i=0
   fi
   mv "$rpmfile" $cddir
   lastfile=$rpmfile
   lastfullpack=`basename "$lastfile" |cut -f1 -d-`
   if [ "`echo $i%$pm |bc`" = "0" ]; then $echo ".\c"; fi
   let i=i+1
done
echo

if [ $i -eq 0 ]; then
   echo There are no packages in $*
   rm -f $lfile
   exit 3
else
   echo "$i files of `du -k -L $lastdir |cut -f1`Kb on $lastdir"
         lastcdsize=`du -ks $lastdir |cut -f1`; lastcdsize=`echo $lastcdsize/1024 |bc`; echo "CD size: ${lastcdsize}Mb"
   echo
fi

echo "Making a list of all packages on the prepared distribution." 
find $allcddir -name "*$ext" -print > $listofallrpms

echo "Setting up the right permissions for files and directories ..."
CWD=`pwd`
for i in $allcddir
do
    cd $i
    find . -name "*$ext" -exec chmod a-x+r {} \;
    find . -type f -exec chmod a+r {} \;
    find . -type d -exec chmod a+xr {} \;
#    find . -name '*.rpm' -exec chmod a-x+r {} \;
#    ls -al > ls-al
#    gzip -f ls-al
    cd $CWD
done

if [ "$ext" = ".rpm" ]; then
echo "Creating tag-links to the $packdir directories."
for i in $allpackdir
do
### A list of all packages is copied to every CD of the distribution
    cp $listofallrpms $i
    cd $i
    first=`ls -1 $packdir/*$ext |rev |cut -f1 -d/ |rev |cut -f1 -d- |head -1`
    last=`ls -1 -r $packdir/*$ext |rev |cut -f1 -d/ |rev |cut -f1 -d- |head -1`
    if [ ! -a "$first-$last" ]; then
       ln -s $packdir "$first-$last"
    else
       echo Link \'$first-$last\' does exist.
    fi
    cd $CWD
done
fi

rm -f $listofallrpms

$echo 'Done! \007\007'

exit 0
