#! /bin/bash
#*****************************************************************************
#    GNS Systems burning script CD/CDRW/DVD/DVDRW                            *
#         V.II                                                               *
#    author       Norman Krebs (nkr) norman.krebs@gns-systems.de             *
#    created          Sat Feb 09 2008 23:31:22                               *
#    last change      Tue Sep 11 2009                                        *
#*****************************************************************************

VERSION=2.012

SCN=${0##*/}

# WORKMODE=TEST
WORKMODE=HOT

SRC=void
ISO=void
TMPISOIMG=/usr2/tmpburn.iso
CFGUDIR=${HOME}/.b2
CFGUSER=${CFGUDIR}/b2rc
CFGMAIN=/etc/burnscript.cfg
SAVECFG=1
SHOWCFG=0
SILENT=0
CLBEFORE=void
DELISO=0
EJECT=1
AUDIO=0

GROWISOFS=growisofs
GENISOIMAGE=genisoimage
CDRECORD=wodim
MKISOFS=mkisofs
DVDRWFORMAT=dvd+rw-format

MODE=void
EDITOR=${EDITOR}

SPEED=void
DEV=void
NDV=void
CLM=void

typeset -i N=-1
typeset -i RESULT=0

CMDLNE="${0} ${*}"

#=======SET CFG================================
CD_DEV=${DEV}     ; CD_SPEED=${SPEED}    ; CD_NDV=${NDV}
CDRW_DEV=${DEV}   ; CDRW_SPEED=${SPEED}  ; CDRW_NDV=${NDV}   ; CDRW_CLM=${CLM}
DVD_DEV=${DEV}    ; DVD_SPEED=${SPEED}   ; DVD_NDV=${NDV}
DVDRW_DEV=${DEV}  ; DVDRW_SPEED=${SPEED} ; DVDRW_NDV=${NDV}  ; DVDRW_CLM=${CLM}

function usage {
    echo "${0##*/} - the burning utility"
    echo "version   ${VERSION}"
    for i in ${CFGUSER} ${CFGMAIN} ; do [ -f ${i} ] && msg "config file [${i}] found" ; done
    echo "Usage:"
    echo "      ${0##*/} <mode> [speed=<speed>] [src=<src>] [iso=<iso>] [dev=<dev>]"
    echo "              [ndv=<ndv>] [{clr|cla|clf}] [blank={all|fast}] [showcfg]"
    echo "              [editcfg] [{test|hot}] [{audio|-au}]"
    echo ""
    echo "            mode        {CD|CDRW|DVD|DVDRW}"
    echo "            speed       1..?"
    echo "            src         source dir"
    echo "            iso         iso file"
    echo "            dev         device"
    echo "            ndv         native device"
    echo "            clr         clear mode"
    echo "            clf         clear before blank=fast"
    echo "            cla         clear before blank=all"
    echo "            blank       all|fast"
    echo "            showcfg     show configuration"
    echo "            editcfg     edit config file"
    echo "            audio       burn audio CD (CD/CDRW only)"
    echo "            test        workmode test"
    echo "            silent      silent mode"
    echo ""
}

function msg {
    echo "${SCN}: ${1}"
}

# params: <TMPISO> <SRC>
function checkspace {
    local FREE NEED R
    FREE=$(df -k "$(dirname ${1})" | sed -n "2,$ p" | awk '{print $4}')
    NEED=$(du -sk "${SRC}" | awk '{print $1}')
    [ ${FREE} -gt ${NEED} ] && R=0 || R=1
    return ${R}
}

function execute {
    [ ${SILENT} -eq 1 ] && TGT=/dev/null || TGT=/dev/stdout
    case ${WORKMODE} in
        HOT)
            [ ${SILENT} -eq 1 ] && msg "[${1}]"
            ${1} > ${TGT} 2>&1 ; RESULT=${?}
            ;;
        *) msg "[${1}]"        ; RESULT=0
            ;;
    esac
    [ ${SILENT} -eq 1 -a ${RESULT} -ne 0 ] && msg "execute [${1}] returned code [${RESULT}]"
    return ${RESULT}
}

function checkcmd {
    for k ; do
        if echo "${k}" | grep -q "void" ; then
            msg "uninitialized parameters in"
            msg ""
            msg "    ${k}"
            msg ""
            for i in ${k} ; do
                echo ${i} | grep -q 'void' && msg "        ${i//=void/?}"
            done
            for V in SPEED DEV NDV CLM ; do
                msg "${V}="$(eval "echo \${${V}}")
            done
            msg ""
            msg "bye."
            return 9
        fi
    done
    return 0
}

#=======STORE CFG==============================
function storecfg {
    [ -d ${1%/*} ] || mkdir -p ${1%/*}
    [ -f ${1} ] && rm -f ${1}
    [ ${SHOWCFG} -eq 1 ] && msg "store config to [${1}]"
    for V in SPEED DEV NDV ; do
        for M in CD CDRW DVD DVDRW ; do
            P=$(eval "echo \$${M}_${V}")
            echo "${M}_${V}=${P}" >> ${1}
        done
    done
    for V in CLM ; do
        for M in CDRW DVDRW ; do
            P=$(eval "echo \$${M}_${V}")
            echo "${M}_${V}=${P}" >> ${1}
        done
    done
}

function showcfg {
    for M in CD CDRW DVD DVDRW ; do
        for V in SPEED DEV NDV ; do
            P=$(eval "echo \$${M}_${V}")
            echo "${M}_${V} ${P}"
        done
    done | awk '{printf("%14s  %s\n", $1, $2)}'
    for M in CDRW DVDRW ; do
        for V in CLM ; do
            P=$(eval "echo \$${M}_${V}")
            echo "${M}_${V} ${P}"
        done
    done | awk '{printf("%14s  %s\n", $1, $2)}'
    for V in SPEED DEV NDV CLM ; do
        P=$(eval "echo \$${V}")
        echo "${V} ${P}"
    done | awk '{printf("%14s  %s\n", $1, $2)}'
}


#==========MAIN==============================================

if [ $# -lt 1 ] ; then
    usage
    exit 0
fi

for i in ${GROWISOFS} ${CDRECORD} ${MKISOFS} ${DVDRWFORMAT} ${GENISOIMAGE} ; do
    if ! which ${i} > /dev/null ; then
        msg "[${i}] not found"
        exit 8
    fi
done

for i ; do
    case ${i} in
        CD|CDRW|DVD|DVDRW|cd|cdrw|dvd|dvdrw)
                    MODE=$(echo "${i}" | tr "a-z" "A-Z") ;;
        speed=*)    [ ! "${i##*=}" = "" ] && SPEED=${i##*=}
            ;;
        src=*)      if [ ! "${i##*=}" = "" ] ; then
                        SUBM=SRC
                        ISO=${TMPISOIMG}
                        SRC=${i##*=}
                    fi
            ;;
        iso=*)      if [ ! "${i##*=}" = "" ] ; then
                        SUBM=ISO
                        ISO=${i##*=}
                    fi
            ;;
        dev=*)      [ ! "${i##*=}" = "" ] && DEV=${i##*=}
            ;;
        ndv=*)      [ ! "${i##*=}" = "" ] && NDV=${i##*=}
            ;;
        clr)        SUBM=CLR ;;
        clf|cla)    [ "${i}" = "clf" ] && CLBEFORE=fast || CLBEFORE=all ;;
        blank=*)    [ ! "${i##*=}" = "" ] && CLM=${i##*=}
            ;;
        audio|-au)  case ${MODE} in
                        CD|CDRW) AUDIO=1 ;;
                        *) msg ""
                           msg "burning audio CDs is possible only in mode [CD/CDRW]"
                           msg ""
                           exit 1
                           ;;
                    esac
            ;;
        showcfg|-sc)    SHOWCFG=1
            ;;
        editcfg|-ec)    ${EDITOR} ${CFGUSER} ; exit 0
            ;;
        test|TEST|-t)   WORKMODE=TEST
            ;;
        noeject|-ne)    EJECT=0
            ;;
        silent|-S)      SILENT=1
            ;;
    esac
done

for i in ${CFGUSER} ${CFGMAIN} ; do
    if [ -f ${i} -a ${SILENT} -eq 0 ] ; then
        msg "config file [${i}] found"
        . ${i}
    fi
done

for V in SPEED DEV NDV CLM ; do
    [ "$(eval echo \$${V})" = "void" ] && eval "${V}=\${${MODE}_${V}}" || eval "${MODE}_${V}=\$${V}"
done

case ${MODE} in
    CD|CDRW|DVD|DVDRW) :
        ;;
    *)  if [ ${SHOWCFG} -eq 1 ] ; then
            showcfg
            exit 0
        else
            msg ""
            msg "no mode!"
            msg ""
            exit 9
        fi
        ;;
esac

case ${CLBEFORE} in
    fast|all)   N=N+1 ; CMD[${N}]="${0} ${MODE} clr blank=${CLBEFORE} speed=${SPEED} dev=${DEV} ndv=${NDV} ${WORKMODE} noeject"
                ;;
    *)          msg "[ $MODE/$SUBM ]"
                ;;
esac

case ${SUBM} in
    ISO)    if [ ! -e "${ISO}" ] ; then
                msg "[${ISO}] does not exist."
                exit 1
            fi
            if [ ! -f "${ISO}" ] ; then
                msg "[${ISO}] must be a file."
                exit 2
            fi
            case ${MODE} in
                CD|CDRW)    N=N+1 ; CMD[${N}]="${CDRECORD} -v dev=${DEV} speed=${SPEED} -overburn driveropts=burn-proof ${ISO}"
                    ;;
                DVD|DVDRW)  N=N+1 ; CMD[${N}]="${GROWISOFS} -dvd-compat -Z ${DEV}=${ISO} -speed=${SPEED}"
                    ;;
            esac
            ;;
    SRC)    if [ ! -e "${SRC}" ] ; then
                msg "[${SRC}] does not exist."
                exit 1
            fi
            if [ ! -d "${SRC}" ] ; then
                msg "[${SRC}] must be a directory."
                exit 2
            fi
            case ${MODE} in
                CD|CDRW)    case "${AUDIO}" in
                                0)  N=N+1 ; CMD[${N}]="checkspace ${ISO} ${SRC}"
                                    N=N+1 ; CMD[${N}]="${MKISOFS} -r -joliet-long -o ${ISO} ${SRC}"
                                    N=N+1 ; CMD[${N}]="${CDRECORD} -v dev=${DEV} speed=${SPEED} -overburn driveropts=burn-proof ${ISO}"
                                    ;;
                                1)  N=N+1 ; CMD[${N}]="${CDRECORD} -v -audio -pad dev=${DEV} speed=${SPEED} ${SRC}/*.wav"
                                    ;;
                            esac
                    ;;
                DVD|DVDRW)  N=N+1 ; CMD[${N}]="checkspace ${ISO} ${SRC}"
                            N=N+1 ; CMD[${N}]="${GENISOIMAGE} -o ${ISO} -r -l -J ${SRC}"
                            N=N+1 ; CMD[${N}]="${GROWISOFS} -dvd-compat -Z ${DEV}=${ISO} -speed=${SPEED}"
                    ;;
            esac
            ;;
    CLR)    case ${MODE} in
                CDRW)       N=N+1 ; CMD[${N}]="${CDRECORD} -v dev=${DEV} speed=${SPEED} blank=${CLM}"
                    ;;
                DVDRW)      N=N+1 ; CMD[${N}]="${DVDRWFORMAT} ${NDV} -force"
                    ;;
                *)          msg "cannot clear [${MODE}]"
                    ;;
            esac
            ;;
    *)  msg ""
        msg "no submode!"
        msg ""
        exit 9
        ;;
esac

case ${EJECT} in
    1)  N=N+1 ; CMD[${N}]="eject ${NDV}"
        ;;
    *)  msg "wrong value EJECT=[${EJECT}]"
        EJECT=0
        ;;
esac

[ ${SHOWCFG} -eq 1 ] && showcfg
[ ${SAVECFG} -eq 1 ] && storecfg ${CFGUSER}

for i in $(seq 0 ${N}) ; do
    if checkcmd "${CMD[${i}]}" ; then
        :
#        [ ${SILENT} -eq 0 ] && echo "CMD[${i}]=[${CMD[${i}]}]"
    else
        exit ${?}
    fi
done

for i in $(seq 0 ${N}) ; do
    execute "${CMD[${i}]}" ; R=${?}
    msg "[${CMD[${i}]}]:[${R}]"
    RESULT=RESULT+${R}
done

msg "RESULT=[${RESULT}]"

[ ${DELISO} -eq 1 -a -f ${TMPISOIMG} -a ${RESULT} -eq 0 ] && rm ${TMPISOIMG}

exit ${RESULT}


