#!/bin/sh # # Rebuild SuSE DVD, ver. 1.1.1 # # May-Dec 2004, Aleksey Barabanov # Jan 2005, fix relative path to directories # Mar 2005, smal fix, thnx Yashar Aslanov # # todo # 1. ImageMagic++ problem ;) # # ##################################################### setup VER="ver. 1.1.1" PGM=`basename $0` DEBUG="" NOCLEAN="" NOAPTATE="" NOFRESH="" DRYRUN="" PAUSE="" BOOTABLE="" # updates dir UPDATES="" # linuxrc info file INFOFILE="" # working dir TMP="/tmp" # mount point DMNT=/mnt # devices CDDEV="/dev/sr0" NULL=/dev/null ZERO=/dev/zero # misc HOME=`pwd` # ##################################################### get options CDAPP="SuSE-Linux-DVD-9.2#0" CDVOL="SU920.001" #CDPUB="SuSE DVD remake" CDPUB="SuSE Linux AG, suse@suse.de" #CDPRE="RebuildSuSEDVD 1.1.1" CDPRE="CD-Team, http://www.suse.de/feedback" CDSYS="LINUX" CTYME=`date +"%Y%m%d%H%M%S"` usage() { cat < ISO header application ID --cdvol ISO header volume ID --cdpub ISO header publisher ID --cdpre ISO header preparer ID --comp Use as component base name for repository. Default original. --compile Make command list insted executing. --debug Make verbose output. --dev Use devname as cd-drive device. Default /dev/sr0. --iso Use filename as original iso image. --linuxrc Add to loadable initrd. --mount Use dirname as mount point. Default /mnt. --noaptate Dont create APT package index. --noclean Dont remove temporary files. --nofresh Dont recreate SuSE DVD indexes. --pause Make pause after copying before building. --source Use dirname as root of iso repository. --tmp Use dirname for temporary files. Default /tmp. --updates Made autoupdate from list of directories where placed lates packages. EOT } # OISO="" TREP="" TISO="" CNAME="original" DVER="9.2" DNAM="SUSE" while [ $# -gt 0 ] ; do case $1 in --noclean) NOCLEAN="1" ;; --noaptate) NOAPTATE="1" ;; --nofresh) NOFRESH="1" ;; --compile) DRYRUN="1" ;; --pause) PAUSE="1" ;; --debug) DEBUG="1" ;; --boot) BOOTABLE="1" ;; --iso) shift OISO=$1 ;; --source) shift TREP=$1 ;; --tmp) shift TMP=$1 ;; --mount) shift DMNT=$1 ;; --dev) shift CDDEV=$1 ;; --comp) shift CNAME=$1 ;; --updates) shift UPDATES=$1 ;; --linuxrc) shift INFOFILE=$1 ;; --cdapp) shift CDAPP=$1 ;; --cdvol) shift CDVOL=$1 ;; --cdpub) shift CDPUB=$1 ;; --cdpre) shift CDPRE=$1 ;; --*) echo -e "Bad option \"$1\"." usage exit 1 ;; -*) echo -e "Bad option \"$1\"." usage exit 1 ;; *) TISO=$1 ;; esac shift done WTMP=$TMP/$PGM-$$ OINFO=$TMP/$PGM-info-$$ ITMP=$TMP/$PGM-initrd-$$ [ -z "$TREP" ] || { WTMP="$TREP" [ -z "$OISO" ] || { echo -e "You must use ISO or Repository. Abort" usage exit 1 } } [ -n "$DEBUG" ] && [ -z "$DRYRUN" ] && { echo -en "Tmp\t\t" ; echo "==$TMP==" echo -en "ISO\t\t" ; echo "==$OISO==" echo -en "CDDEV\t\t" ; echo "==$CDDEV==" echo -en "DMNT\t\t" ; echo "==$DMNT==" echo -en "Target\t\t" ; echo "==$TISO==" echo -en "Component name\t" ; echo "==$CNAME==" echo -en "Updates\t\t" ; echo "==$UPDATES==" } [ "$TISO" == "" ] && { echo -e "Target ISO must applayed. Abort" usage exit 1 } # off nofresh if use autoupdates [ -n "$UPDATES" ] && NOFRESH="" # set noclean if use "source" [ -n "$TREP" ] && NOCLEAN="1" # ##################################################### setup environment # utilities CD=cd READ=read ERRMES="" DD=`which dd` || ERRMES=dd GREP=`which grep` || ERRMES=grep CAT=`which cat` || ERRMES=cat RM=`which rm` || ERRMES=rm MKDIR=`which mkdir` || ERRMES=mkdir ECHO=`which echo` || ERRMES=echo MOUNT=`which mount` || ERRMES=mount UMOUNT=`which umount` || ERRMES=umount KILL=`which kill` || ERRMES=kill CP=`which cp` || ERRMES=cp FIND=`which find` || ERRMES=find LN=`which ln` || ERRMES=ln AWK=`which awk` || ERRMES=awk SED=`which sed` || ERRMES=sed STAT=`which stat` || ERRMES=stat MKISO=`which mkisofs` || ERRMES=mkisofs MD5=`which md5sum` || ERRMES=md5sum LS=`which ls` || ERRMES=ls GZIP=`which gzip` || ERRMES=gzip ZCAT=`which zcat` || ERRMES=zcat FILE=`which file` || ERRMES=file MV=`which mv` || ERRMES=mv CPDESCR=`which create_package_descr` || ERRMES=create_package_descr # only for apt-disk APTATE=`which aptate` || { [ "$NOAPTATE" != "" ] && ERRMES=aptate } if [ "$ERRMES" != "" ]; then echo -e "Not found \"$ERRMES\". Abort" exit 1 fi oWTMP=$WTMP oHOME=$HOME oUPDATES=$UPDATES oFIND=$FIND oCD=$CD oCAT=$CAT oSED=$SED oAWK=$AWK oECHO=$ECHO oSTAT=$STAT [ -z "$TREP" ] && { # ##################################################### get vars from original iso # choose original source i="$CDDEV" ; [ -n "$OISO" ] && i="$OISO" # Read the entire header - actually sector 16 of the disc (2K sectors) # All character codes in the "control" region (0-31 decimal) are folded # into the character '.' - these control codes seem to upset bash's # variable sub-string functions (${var:start:length}) quite badly )-: $DD if=$i bs=1 skip=32768 count=2048 >$OINFO 2>/dev/null if [ $? -ne 0 ] ; then $RM -rf $OINFO $ECHO "Error: unable to open \"$i\". Abort" exit 1 fi data=`$CAT $OINFO |tr '[\\000-\\037]' '.*'` $RM -rf $OINFO # Define some useful functions for prettifying the output tidy_print() { # Really cheap way of folding whitespace echo $* } [ "${data:1:5}" == "CD001" ] && { CDVOL=`tidy_print ${data:40:32}` CDPUB=`tidy_print ${data:318:128}` CDPRE=`tidy_print ${data:446:128}` CDAPP=`tidy_print ${data:574:128}` CDSYS=`tidy_print ${data:8:32}` } [ -n "$DEBUG" ] && [ -z "$DRYRUN" ] && { echo -en "SysID\t\t" ; echo "==$CDSYS==" echo -en "VolNAME\t\t" ; echo "==$CDVOL==" echo -en "PublisherID\t" ; echo "==$CDPUB==" echo -en "PreparerID\t" ; echo "==$CDPRE==" echo -en "ApplicationID\t" ; echo "==$CDAPP==" } } # ##################################################### setup compiler do_cat() { T=$1 [ ! -t 0 ] && { if [ -n "$DRYRUN" ] ; then ## compile echo "cat >>$T <>$T fi } } SCAT=do_cat # choose original source OSRC="$CDDEV" ; [ -n "$OISO" ] && OSRC="-o loop $OISO" # [ -n "$DRYRUN" ] && { echo -e "#!/bin/sh\n# Rebuild SuSE DVD, $VER" echo -e "# compiled at `date`\n#-----------------------" echo -e "WTMP=\"$WTMP\"" WTMP="\$WTMP" echo -e "ITMP=\"$ITMP\"" ITMP="\$ITMP" echo -e "OSRC=\"$OSRC\"" OSRC="\$OSRC" echo -e "TISO=\"$TISO\"" TISO="\$TISO" # [ -z "$UPDATES" ] || { # echo -e "UPDATES=\"$UPDATES\"" # UPDATES="\$UPDATES" # } [ -n "$INFOFILE" ] && { echo -e "INFOFILE=\"$INFOFILE\"" INFOFILE="\$INFOFILE" } echo -e "HOME=\`pwd\`" HOME="\$HOME" DD="echo $DD" LO="echo $LO" MKDIR="echo $MKDIR" MOUNT="echo $MOUNT" CP="echo $CP" CD="echo $CD" ECHO="echo -e $ECHO" CAT="echo $CAT" UMOUNT="echo $UMOUNT" MKISO="echo -e $MKISO" RM="echo $RM" AWK="echo $AWK" LN="echo $LN" APTATE="echo $APTATE" READ="echo $READ" CPDESCR="echo $CPDESCR" FIND="echo $FIND" LS="echo $LS" GZIP="echo $GZIP" MV="echo $MV" MD5="echo $MD5" } # ##################################################### some magic passes # cleaning up temporary resources cleanup() { [ -n "$NOCLEAN" ] || { $ECHO "Cleaning up." $MOUNT | $GREP "on $DMNT" >$NULL && { $ECHO "Unmount image"; $UMOUNT $DMNT; } [ -z "$TREP" ] && { ( [ -n "$DRYRUN" ] || [ -d $WTMP ] ) && $RM -rf $WTMP } ( [ -n "$DRYRUN" ] || [ -d $ITMP ] ) && $RM -rf $ITMP } } # make trap for clean after_error() { cleanup $ECHO "Abort." exit 1 } [ -n "$DRYRUN" ] || trap after_error 1 2 3 15 if [ -z "$TREP" ] ; then # ##################################################### copy cd files [ -n "$DEBUG" ] && [ -z "$DRYRUN" ] && $ECHO "=======copy cd files========" # $MOUNT -t iso9660 $OSRC $DMNT || { echo "Error: cant mount \"$i\""; $KILL -INT $$;} [ -d $WTMP ] && $RM -rf $WTMP $MKDIR -p $WTMP || { $ECHO -e "Error: cant make \"$WTMP\""; $KILL -INT $$;} $CD $HOME $CD $DMNT i="" ; [ -n "$DEBUG" ] && i="v" $CP -ax$i . $WTMP || { $ECHO -e "Error: cant copy files"; $KILL -INT $$;} $CD $HOME $UMOUNT $DMNT else # ##################################################### some fixes $oCD $oHOME for i in 2 3 4 5 ; do [ -d $oWTMP/media.$i ] && $RM -rf $WTMP/media.$i done $oCD $oHOME [ -r $oWTMP/media.1/media ] && { L1=`$oCAT $oWTMP/media.1/media | $oSED -n '1p'` L2=`$oCAT $oWTMP/media.1/media | $oSED -n '2p'` if [ -z "$DRYRUN" ] ; then $ECHO "$L1" >$WTMP/media.1/media $ECHO "$L2" >>$WTMP/media.1/media $ECHO "1" >>$WTMP/media.1/media else $ECHO "$L1" \>$WTMP/media.1/media $ECHO "$L2" \>\>$WTMP/media.1/media $ECHO "1" \>\>$WTMP/media.1/media fi } fi # force suse/i386 $oCD $oHOME [ -d $oWTMP/suse/i386 ] || { $CD $HOME $MKDIR -p $WTMP/suse/i386 || { $ECHO -e "Error: cant make \"$WTMP/suse/i386\""; $KILL -INT $$;} } # force media.1 $oCD $oHOME [ -d $oWTMP/media.1 ] || { $CD $HOME $MKDIR -p $WTMP/media.1 || { $ECHO -e "Error: cant make \"$WTMP/media.1\""; $KILL -INT $$;} } # force media.1/media $oCD $oHOME [ -r $oWTMP/media.1/media ] || { $CD $HOME if [ -z "$DRYRUN" ] ; then $ECHO "$CDPUB" > $WTMP/media.1/media || { $ECHO -e "Error: cant write to \"$WTMP/media.1/media\""; $KILL -INT $$;} $ECHO "$CTYME" >> $WTMP/media.1/media || { $ECHO -e "Error: cant write to \"$WTMP/media.1/media\""; $KILL -INT $$;} $ECHO "1" >> $WTMP/media.1/media || { $ECHO -e "Error: cant write to \"$WTMP/media.1/media\""; $KILL -INT $$;} else $ECHO "\"$CDPUB\"" \> $WTMP/media.1/media $ECHO "\"$CTYME\"" \>\> $WTMP/media.1/media $ECHO "\"1\"" \>\> $WTMP/media.1/media fi } # force media.1/products $oCD $oHOME [ -r $oWTMP/media.1/products ] || { $CD $HOME if [ -z "$DRYRUN" ] ; then $ECHO "/ $CDAPP" > $WTMP/media.1/products || { $ECHO -e "Error: cant write to \"$WTMP/media.1/media\""; $KILL -INT $$;} else $ECHO "\"/ $CDAPP\"" \> $WTMP/media.1/products fi } # ##################################################### setup repository # suse specific tuning [ -z "$DRYRUN" ] && [ -r $WTMP/content ] && { DVER=`$CAT $WTMP/content | $GREP -i ^version | $AWK '{print $2}'` DNAM=`$CAT $WTMP/content | $GREP -i ^product | $AWK '{print $2}'` } [ -z "$NOAPTATE" ] && { [ -n "$DEBUG" ] && [ -z "$DRYRUN" ] && $ECHO "=======setup repository========" # make apt configuration $MKDIR -p $WTMP/apt || { $ECHO -e "Error: cant make \"$WTMP/apt\""; $KILL -INT $$;} $SCAT $WTMP/apt/aptate.conf < $WTMP $DNAM $DVER i586 $CNAME-i586 suse/i586 $CNAME-noarch suse/noarch EOT } # ##################################################### autoupdates [ -z "$oUPDATES" ] || { [ -n "$DEBUG" ] && $ECHO "=======autoupdates========" v="" ; [ -n "$DEBUG" ] && v="-v" for UPDATES in $oUPDATES ; do ##################################################### updatelist ooUPDATES=$UPDATES [ -n "$DRYRUN" ] && { [ -z "$UPDATES" ] || { echo -e "UPDATES=\"$UPDATES\"" UPDATES="\$UPDATES" } } # updates list, full path $ooUPDATES/$i ## LUPD=`$oFIND $ooUPDATES -regex ".*\(noarch\|i586\)\.rpm$" -printf "%P\n"` LUPD=`$oFIND $ooUPDATES -regex ".*\(noarch\|i586\|i386\)\.rpm$" -printf "%P\n"` for i in $LUPD ; do # get leader part of basename bi=`basename $i | $oAWK -F. '{print $1}'` # find package with equal leader part, full path $oWTMP/suse/$oi ## cbi="$oFIND $oWTMP/suse -regex \".*/$bi.*\(noarch\|i586\)\.rpm$\" -printf \"%P\\n\"" cbi="$oFIND $oWTMP/suse -regex \".*/$bi.[a-z0-9A-Z].*\(noarch\|i586\|i386\)\.rpm$\" -printf \"%P\\n\"" oi=`eval $cbi` # and get first oi1=`$oECHO "$oi" | $oAWK '{print $1}'` if [ "$oi1" != "" ] ; then # compare package age if [ "`$oSTAT -c "%Y" $ooUPDATES/$i`" -gt "`$oSTAT -c "%Y" $oWTMP/suse/$oi1`" ] ; then # copy update if [ -z "$DRYRUN" ] ; then $CP $v $ooUPDATES/$i $oWTMP/suse/`dirname $oi` || { $ECHO -e "Error: cant copy \"$i\""; $KILL -INT $$;} $RM $v -f $oWTMP/suse/$oi || { $ECHO -e "Error: cant erase \"$oi\""; $KILL -INT $$;} else $CP $v $UPDATES/$i $WTMP/suse/`dirname $oi` $RM $v -f $WTMP/suse/$oi fi fi else if [ -z "$DRYRUN" ] ; then $CP $v $ooUPDATES/$i $oWTMP/suse/`dirname $i` || { $ECHO -e "Error: cant copy \"$i\""; $KILL -INT $$;} else $CP $v $UPDATES/$i $WTMP/suse/`dirname $i` fi fi done ##################################################### done } # UPDATES # ##################################################### unzip initrd, add info FST="" [ -n "$INFOFILE" ] && { [ -n "$DEBUG" ] && [ -z "$DRYRUN" ] && $ECHO "=======unzip initrd, add info========" $MKDIR -p $ITMP || { $ECHO -e "Error: cant make \"$ITMP\"" ; $KILL -INT $$; } if [ -n "$DRYRUN" ] ; then echo "$ZCAT $WTMP/boot/loader/initrd >$ITMP/initrd" else $ZCAT $WTMP/boot/loader/initrd >$ITMP/initrd || { $ECHO "Error: cant unzip initrd" ; $KILL -INT $$; } fi if [ -z "$DRYRUN" ] ; then i=`$FILE $ITMP/initrd` FST="" [ -n "`$ECHO "$i" | $GREP Minix`" ] && FST="minix" [ -n "`$ECHO "$i" | $GREP ext2`" ] && FST="ext2" else # default Minix FST="minix" fi [ -n $FST ] && { $MOUNT -o loop,rw -t $FST $ITMP/initrd $DMNT || { $ECHO "Error: cant moun initrd" ; $KILL -INT $$; } $CP $INFOFILE $DMNT/info || { $ECHO -e "Error: cant copy \"$INFOFILE\"" ; $KILL -INT $$; } } } # ##################################################### pause [ -n "$PAUSE" ] && { $ECHO -e "ISO Root ready for modification. Press \"Enter\" for continue." $READ j } # ##################################################### zip initrd [ -n "$INFOFILE" ] && { [ -n "$DEBUG" ] && [ -z "$DRYRUN" ] && $ECHO "=======zip initrd========" [ -n $FST ] && { $UMOUNT $DMNT || { $ECHO -e "Error: cant umount \"$DMNT\"" ; $KILL -INT $$; } } $GZIP -9 $ITMP/initrd || { $ECHO "Error: cant zip initrd" ; $KILL -INT $$; } $MV -f $ITMP/initrd.gz $WTMP/boot/loader/initrd || { $ECHO "Error: cant return initrd" ; $KILL -INT $$; } $RM -rf $ITMP || { $ECHO -e "Error: cant remove \"$ITMP\"" ; $KILL -INT $$; } } # ##################################################### fresh SuSE DVD indexes [ -z "$NOFRESH" ] && { [ -n "$DEBUG" ] && [ -z "$DRYRUN" ] && $ECHO "=======fresh SuSE DVD indexes========" # ################################################## remove old indexes MD5DIR=`$oCD $oHOME ; $oCD $oWTMP ; $oFIND suse -name MD5SUMS` for i in $MD5DIR ; do if [ -z "$DRYRUN" ] ; then $RM -f $WTMP/$i || { $ECHO "Error: cant remove MD5SUMS" ; $KILL -INT $$; } else $RM -f $WTMP/$i fi done # ################################################## create new indexes # create package index $CD $HOME $CD $WTMP/suse if [ -r $oWTMP/suse/setup/descr/EXTRA_PROV ] ; then i="-x $WTMP/suse/setup/descr/EXTRA_PROV" $CPDESCR -l czech -l english -l french -l german -l italian -l spanish -l hungarian $i \ || { $ECHO "Error: cant make package index" ; $KILL -INT $$; } else # if EXTRA_PROV is needed but it not found - ABORT! $oECHO "Error: cant find EXTRA_PROV" $KILL -INT $$; fi # create directory.yast LDIR=`$oCD $oHOME ; $oCD $oWTMP ; $oFIND . -name directory.yast` for i in $LDIR ; do if [ -z "$DRYRUN" ] ; then $CD $HOME $CD $WTMP/`dirname $i` || { $ECHO "Error: cant walk to \"`dirname $i`\"" ; $KILL -INT $$; } $RM -f directory.yast || { $ECHO "Error: cant remove directory.yast" ; $KILL -INT $$; } $LS -A > directory.yast || { $ECHO "Error: cant make directory.yast" ; $KILL -INT $$; } else $CD $HOME $CD $WTMP/`dirname $i` $RM -f directory.yast $LS -A \> directory.yast fi done # force directory.yast $oCD $oHOME [ -r $oWTMP/directory.yast ] || { $CD $WTMP if [ -z "$DRYRUN" ] ; then $LS -A > directory.yast || { $ECHO "Error: cant make directory.yast" ; $KILL -INT $$; } else $LS -A \> directory.yast fi } $oCD $oHOME [ -r $oWTMP/media.1/directory.yast ] || { $CD $WTMP/media.1 if [ -z "$DRYRUN" ] ; then $LS -A > directory.yast || { $ECHO "Error: cant make directory.yast" ; $KILL -INT $$; } else $LS -A \> directory.yast fi } # create main indexes if [ -z "$DRYRUN" ] ; then $CD $HOME $CD $WTMP $RM -f INDEX.gz ls-lR.gz || { $ECHO "Error: cant remove INDEX.gz ls-lR.gz" ; $KILL -INT $$; } # { unset LANG $LS -lR >ls-lR || { $ECHO "Error: cant make ls-lR" ; $KILL -INT $$; } } $GZIP ls-lR || { $ECHO "Error: cant zip ls-lR" ; $KILL -INT $$; } # $FIND . >INDEX || { $ECHO "Error: cant make INDEX" ; $KILL -INT $$; } $GZIP INDEX || { $ECHO "Error: cant zip INDEX" ; $KILL -INT $$; } else $CD $HOME $CD $WTMP $RM -f INDEX.gz ls-lR.gz # $oECHO "{ unset LANG" $LS -lR \>ls-lR $oECHO "}" $GZIP ls-lR # $FIND \. \>INDEX $GZIP INDEX fi # create md5sums for i in $MD5DIR ; do if [ -z "$DRYRUN" ] ; then $CD $HOME $CD $WTMP/`dirname $i` || { $ECHO -e "Error: cant walk to \"`dirname $i`\"" ; $KILL -INT $$; } $MD5 * > MD5SUMS else $CD $HOME $CD $WTMP/`dirname $i` $MD5 \* \> MD5SUMS fi done #=# # force md5sums $CD $HOME } # !NOFRESH # ##################################################### build apt indexes [ -z "$NOAPTATE" ] && { i="--quiet qq" ; [ -n "$DEBUG" ] && i="--debug" $APTATE $i --config-file $WTMP/apt/aptate.conf || { $ECHO "Error: cant buil apt" ; $KILL -INT $$; } } # ##################################################### make iso image [ -n "$DEBUG" ] && [ -z "$DRYRUN" ] && $ECHO "=======make iso image========" ISOBOOT="" # looking for isolinux ( [ -r $WTMP/boot/loader/isolinux.bin ] || [ -n "$BOOTABLE" ] ) && { ISOBOOT="-no-emul-boot -boot-load-size 4 -boot-info-table -b boot/loader/isolinux.bin -c boot/boot.catalog" ISOBOOT="$ISOBOOT -hide boot/boot.catalog -hide-joliet boot/boot.catalog" } # make iso i="-quiet" ; [ -n "$DEBUG" ] && i="-v" ISOOPT="$i -r -J -pad -allow-lowercase -allow-multidot -iso-level 3" i="-A \"$CDAPP\" -V \"$CDVOL\" -P \"$CDPUB\" -p \"$CDPRE\" -sysid \"$CDSYS\" $ISOOPT -o $TISO $ISOBOOT $WTMP" #=# if [ -n "$DRYRUN" ] ; then $MKISO $i else eval "$MKISO $i" || { $ECHO "Error: cant make iso" ; $KILL -INT $$; } fi # ##################################################### finish [ -n "$DRYRUN" ] || trap 1 2 3 15 cleanup $ECHO "Done." exit # ##################################################### done # #####################################################