A small shell script to grab audio from a CD and encode/compress it.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

393 lines
9.2 KiB

if [ "x" == "x$__SHELLUTILS__" ]
then
__SHELLUTILS__="shellUtils"
# -------------------------------
# Fehlermeldungen
_shellUtils_errMsg[1]="Fehler beim Aufruf von \${FUNCNAME}: falsche Parameteranzahl: $#"
_shellUtils_errMsg[2]="Fehler: Es läuft bereits eine Instanz (\${oldPid}) des scripts"
_shellUtils_errMsg[3]="Fehler beim Aufruf von doSmbCommand: smbCommand nicht initialisiert"
_shellUtils_errMsg[4]="Fehler: konnte keine Konfigurations-Datei (\${cName}) finden"
#_shellUtils_errMsg[2]=
# -------------------------------
# -------------------------------
# Kommandodefinitions Teil
SH="/bin/bash"
SMBCLIENT="/usr/bin/smbclient"
PS="/bin/ps"
BASENAME="/usr/bin/basename"
PWDCMD="/bin/pwd"
CONVERT="/usr/bin/convert"
ICONV="/usr/bin/iconv"
ECHO="/bin/echo"
TEST="/usr/bin/test"
SED="/usr/bin/sed"
PRINTF="/usr/bin/printf"
SORT="/usr/bin/sort"
FTP="/usr/bin/ftp"
CONVERT="/usr/bin/convert"
CJPEG="/usr/bin/cjpeg"
CAT="/bin/cat"
MKDIR="/bin/mkdir"
DATE="/bin/date"
RM="/bin/rm"
MAILCMD="/bin/bin/mailto"
CUT="/usr/bin/cut"
TR="/usr/bin/tr"
LOCALE="/usr/bin/locale"
GREP="/bin/grep"
WC="/usr/bin/wc"
MV="/usr/bin/mv"
CP="/usr/bin/cp"
EXPR="/usr/bin/expr"
UNZIP="/usr/bin/unzip"
XSLTPROC="/usr/bin/xsltproc"
GAWK="/usr/bin/gawk"
AWK="/usr/bin/awk"
LS="/bin/ls"
TOUCH="/usr/bin/touch"
RECODE="/usr/bin/recode"
GETOPT="/usr/bin/getopt"
# -------------------------------
# -------------------------------
# Variablen
_smbCommand=""
# -------------------------------
# -------------------------------
# Funktionen
# Aufruf: checkLock lockfile
function checkLock
{
if [ $# -ne 1 ]
then
eval "echo \"${_shellUtils_errMsg[1]}\" >&2"
exit 1
fi
local filename="$1"
if [ -e "$filename" ]
then
local oldPid="`$CAT "$lockFile"`"
local scriptName="`$BASENAME $0`"
local running="`$PS -p "$oldPid" | $SED '1d; /'$scriptName'/!d'`"
if [ -n "$running" ]
then
eval "echo \"${_shellUtils_errMsg[2]}\" >&2"
exit 2
fi
fi
echo $$ >"$lockFile"
return $$
}
# Aufruf: doSmbCommand share domain user pass
function initSmbCommand
{
if [ $# -ne 4 ]
then
eval "echo \"${_shellUtils_errMsg[1]}\" >&2"
exit 1
fi
_smbCommand="$SMBCLIENT $1 $4 -U $3 -W $2"
}
# Aufruf: doSmbCommand path command
function doSmbCommand
{
if [ $# -lt 1 -o $# -gt 2 ]
then
eval "echo \"${_shellUtils_errMsg[1]}\" >&2"
exit 1
fi
if [ -z "$_smbCommand" ]
then
eval "echo \"${_shellUtils_errMsg[3]}\" >&2"
exit 3
fi
if [ $# -eq 2 ]
then
eval "$_smbCommand -D $1 -c \"$2\""
else
eval "$_smbCommand -D $1" <&0
fi
}
# Meine Implementation von Hashes fuer die bash verwendet zwei Arrays,
# deren "Basisname" immer bei den aufrufen der Hash-Funktionen mit
# angegeben werden muessen. Die beiden Arrays heissen dann
# _<<Basisname>>_key und _<<Basisname>>_value und enthalten entsprechen
# jeweils zu einem Index ein key/value Paar.
# Die groesste Magie in den Funktionen liegt darin die Arraynamen
# immer richtig zu erzeugen.
# Wenn man dieses Hashes benutzt sollte man bedenken, das das
# Laufzeitverhalten O(n) ist, die Implementierung also nicht sehr
# performant.
# PS. O(n) => im unguenstigsten Fall hat man n Schleifendurchlaeufe um
# auf ein Element in einem Hash mit n Elementen zuzugreifen.
# Ich mags kaum zugeben aber an manchen Stellen ist das Laufzeitverhalten
# sogar O(2n). (Es besteht wohl noch dringender Optimirungsbedarf)
# eine Funktion um einen Hash zu leeren
# Aufruf: unsetHash hashname
function unsetHash
{
if [ $# -ne 1 ]
then
eval "echo \"${_shellUtils_errMsg[1]}\" >&2"
exit 1
fi
unset _${1}_key
unset _${1}_value
}
# eine Funktion um einen HashWert zu setzen. ein key und ein value array
# werden erzeugt. Ueber getHashVal kann man wieder Werte abfragen.
# Aufruf: setHashVal hashname key value
function setHashVal
{
if [ $# -ne 3 ]
then
eval "echo \"${_shellUtils_errMsg[1]}\" >&2"
exit 1
fi
getHashVal "${1}" "${2}" >/dev/null 2>&1
local idx=$?
eval "_${1}_key[$idx]=\"$2\""
eval "_${1}_value[$idx]=\"$3\""
}
# und eine funktion um über einen key einen Wert aus einem Hash
# (siehe setHashVal) zu bekommen.
# Aufruf: getHashVal hash key
function getHashVal
{
if [ $# -ne 2 ]
then
eval "echo \"${_shellUtils_errMsg[1]}\" >&2"
exit 1
fi
local i=0
local count=`getHashSize $1`
local key=`$ECHO $2 | $SED 's/#/\\\\#/'`
while [ $i -lt $count ]
do
if eval [ "\${_${1}_key[$i]}" = "$key" ]
then
eval "echo \${_${1}_value[$i]}"
return $i
fi
i=$((i+1));
done;
return $i
}
# Aufruf: getHashSize hash
function getHashSize
{
if [ $# -ne 1 ]
then
eval "echo \"${_shellUtils_errMsg[1]}\" >&2"
exit 1
fi
eval "count=\${#_${1}_key[*]}"
echo $count
return $count
}
# Aufruf: getHashKeys hash
function getHashKeys
{
if [ $# -ne 1 ]
then
eval "echo \"${_shellUtils_errMsg[1]}\" >&2"
exit 1
fi
eval "ret=\"\${_${1}_key[0]}\""
local i=1
local count=`getHashSize $1`
while [ $i -lt $count ]
do
eval "ret=\"$ret \${_${1}_key[$i]}\""
i=$((i+1))
done
echo $ret
return $count
}
# Funktion um die Zahlrepraesentation eines Monatsname zu bekommen.
# Also Oktober => 10
# Abhaengig davon das ein entsprechendes locale installiert ist.
# Aufruf: getMonthNum Monatsname [locale]
function getMonthNum
{
if [ $# -lt 1 ]
then
eval "echo \"${_shellUtils_errMsg[1]}\" >&2"
exit 1
fi
if [ $# -eq 2 ]
then
LC_ALL=${2}
fi
mon=`$LOCALE -c LC_TIME | $SED '5!d;y/;/\n/' |\
$GREP -n ${1} | $CUT -d\: -f1`
echo $mon
return $mon
}
# Funkktion um ein Kommando nach einem bestimmten Zeitraum abzubrechen
# Aufruf: timeout cmd t
# Retruns: >128 -> falls Timeout, return value von cmd->falls kein Timeout
function timeout
{
if [ $# -lt 2 ]
then
eval "echo \"${_shellUtils_errMsg[1]}\" >&2"
exit 1
fi
# gewuenschtes Kommando als separaten Prozess starten
$1 <&0 &
local __cPid=$!
# subshell starten die gewuenschte Zeit wartet bis sie obigen
# Prozess killt.
( sleep $2; kill -9 ${__cPid} ) >/dev/null 2>&1 &
local __tPid=$!
# neuen Trap setzen....evtl. vorhande alte Kommandos werden auch
# ausgefuehrt! (Bei Programmabbruch auch auf jeden Fall beide
# Sub-Prozesse killen)
oldTrap="`trap -p EXIT`"
oldTrapCmd="`echo $oldTrap | sed 's/^trap -- \(.*\) EXIT$/\1/'`"
trapCmd="kill -9 ${__cPid} >/dev/null 2>&1"
trapCmd="${trapCmd};kill -9 ${__cPid} >/dev/null 2>&1"
trapCmd="${trapCmd};eval $oldTrapCmd"
trap "${trapCmd}" EXIT
# warte bis Subprozess mit Kommando endet
wait ${__cPid} >/dev/null 2>&1
local __cExit=$?
# alte trap Kommandos wiederherstellen
test "$oldTrapCmd" && eval "$oldTrapCmd" || trap '-' EXIT
# falls sie noch laeuft wartende subshell killen.
kill -9 $__tPid >/dev/null 2>&1
return $__cExit
}
# -------------------------------
fi
function getCDInfo
{
local uri device cmd i hello cddb ret diskData tNum
uri="freedb.freedb.org/~cddb/cddb.cgi"
device="/dev/cdrom"
test $# -ge 1 && uri="$1"
test $# -ge 2 && device="$2"
hello="hello=${USER}+${HOSTNAME}+test+0.0.1"
# first get the genre list from server
eval "`curl -s "http://${uri}?cmd=cddb+lscat&${hello}&proto=6" |\
sed '1d;$d' | tr -d '\r' | tr '\n' ',' |\
sed 's/,$//;s/,/" "/g;s/^\(.*\)$/local -a genre=("\1")/'`"
unset cddbId dTitle dYear dGenre tTitle
diskData="`cdda2wav -D ${device} -N -J -v toc,sectors 2>&1`"
cddbId="`echo "$diskData" |\
sed '/^CDDB/!d;s/^.*0x\(.*\)$/\1/'`"
dTracks="`echo "$diskData" |\
sed '/tracks/!d;s/^.*tracks:\([0-9]*\).*$/\1/'`"
dLength="`echo "$diskData" |\
sed '/tracks/!d;s/^.*time \([0-9:\.]*\).*$/\1/'`"
dIndex="`echo "$diskData" |\
sed '/CDINDEX/!d;s/^.*: *\([a-zA-Z0-9_\.]*-\).*$/\1/'`"
dText="`echo "$diskData" | sed '
/CD-Text/!d;s/^[^:]*: *\(.*[^ ]\).*$/\1/'`"
dExtra="`echo "$diskData" | sed '
/CD-Extra/!d;s/^[^:]*: *\(.*[^ ]\).*$/\1/'`"
# search for info in all genres
for i in "${genre[@]}"
do
cmd="cmd=cddb+read+${i}+${cddbId}"
#wget -O- "http://${uri}?${cmd}&${hello}&proto=6" 2>/dev/null
cddb="`curl -s "http://${uri}?${cmd}&${hello}&proto=6"`"
ret="`echo "$cddb" | head -c 3`"
if [ "$ret" != "210" ]
then
if [ ${verbose:-0} -ge 3 ]
then
debug="`echo "$cddb" | head -n 1`"
echo $"[ERROR] cddb: ${debug}"
fi
continue
else
eval "`echo "$cddb" | tr -d '\r' | sed '
/DTITLE/s/^.*=\(\(.*\) \/ \)*\(.*\)$/dArtist="\2";dTitle="\3"/p
/DYEAR/s/^.*=\(.*\)$/dYear="\1"/p
/DGENRE/s/^.*=\(.*\)$/dGenre="\1"/p
/TTITLE/s/^TTITLE\([0-9]*\)=\(\(.*\) \/ \)*\(.*\)$/tArtist[\1]="\3";tTitle[\1]="\4"/p
d'`"
break
fi
done
# Nu pack ich in alle tArtist die leer sind den dArtist.
i=0
while [ $i -lt ${#tArtist[@]} ]
do
tNum=$((i+1))
tLength[$i]=`echo "$diskData" | sed '
/[^0-9]'$tNum'\.(.*:.*)/ !d
s/.*[^0-9]'$tNum'\.( *\([^)]*\).*$/\1/'`
tStartSec[$i]=`echo "$diskData" | sed '
/[^0-9]'$tNum'\.([^:]*)/ !d
s/.*[^0-9]'$tNum'\.( *\([^)]*\).*$/\1/'`
test $tNum -eq ${#tArtist[@]} && tNum="lead-out" || tNum=$((tNum+1))
tEndSec[$i]=`echo "$diskData" | sed '
/[^0-9]'$tNum'\.*([^:]*)/ !d
s/.*[^0-9]'$tNum'\.*( *\([^)]*\).*$/\1/'`
test -z "${tArtist[$i]}" && tArtist[$i]="$dArtist"
i=$((i+1))
done
}