379 lines
11 KiB
Bash
Executable File
379 lines
11 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# Version 2.3-beta 2006-07-14
|
|
#
|
|
# Author: Mike Constabel
|
|
# VDR-Portal.de: vejoun
|
|
# EMail: vejoun at toppoint dot de
|
|
# WWW: http://www.constabel.net/vdr/scripts.de.htm
|
|
#
|
|
# ---> CONFIGURATION AT LINE 83 <---
|
|
#
|
|
# MANUAL:
|
|
# -------
|
|
# 1.
|
|
# If you run VDR as user, you need in /etc/fstab the option "user" for your DVD mountpoint.
|
|
#
|
|
# Example:
|
|
# /dev/hdc /media/cdrom iso9660 defaults,ro,user,noauto 0 0
|
|
#
|
|
# 2.
|
|
# If you use a VFAT partition for your video-data, you must configure sudo to allow the
|
|
# VDR-user to execute mount and umount as root. To edit sudoers run 'visudo' command as root.
|
|
#
|
|
# Example:
|
|
# # Cmnd alias specification
|
|
# Cmnd_Alias SYSTEM = /bin/mount, /bin/umount
|
|
# # User privilege specification
|
|
# vdr ALL=(root) NOPASSWD: SYSTEM
|
|
#
|
|
# With a vfat partition some things doesn't work: resume, marks
|
|
#
|
|
# 3.
|
|
# For dvd-in-drive detection compile isodetect.c and put it into the $PATH,
|
|
# usually /usr/local/bin/
|
|
# You find isodetect.c in the extrecmenu plugin source package.
|
|
#
|
|
# 4.
|
|
# Tools needed: mount, awk, find, test, stat, sed
|
|
# Optional tools: isodetect
|
|
#
|
|
# 5.
|
|
# If you have some DVDs with the index.vdr only on DVD, you don't use vfat and you
|
|
# want to see the recording length in the menu, you can switch GETLENGTH to 1 and
|
|
# the script will create a length.vdr for you.
|
|
#
|
|
# 6.
|
|
# If something went wrong, set DEBUG=1 and send me the file which is defined in $DEBUGLOG.
|
|
# Use VDR-Portal or EMail.
|
|
#
|
|
# 7.
|
|
# Exitcodes:
|
|
#
|
|
# exit 0 - no error
|
|
# exit 1 - mount/umount error
|
|
# exit 2 - no dvd in drive
|
|
# exit 3 - wrong dvd in drive / recording not found
|
|
# exit 4 - error while linking [0-9]*.vdr
|
|
# exit 5 - sudo or mount --bind / umount error (vfat system)
|
|
#
|
|
# HISTORY:
|
|
# --------
|
|
# 2006-07-14: Version 2.3-beta
|
|
#
|
|
# - should be compatible with ash, busybox
|
|
# stays beta until someone confirm this or 2.4 comes
|
|
#
|
|
# 2006-06-13: Version 2.2
|
|
#
|
|
# - at mount, if third parameter is not given, take last part of path
|
|
#
|
|
# Version 2.1
|
|
#
|
|
# - Fixed bug in testing if dvd is mounted
|
|
# - more DEBUG=1 output
|
|
#
|
|
# Version 2.0
|
|
#
|
|
# - more logging
|
|
# - check if mountpoint and device exists
|
|
# - Debug Log in file $DEBUGLOG if $DEBUG is 1, for easier error reporting
|
|
#
|
|
# Version 1.9
|
|
#
|
|
# - use "sudo mount --bind" for mounting if filesystem is vfat
|
|
# - automatic fallback to 'sudo' and 'mount --bind' if filesystem is vfat
|
|
# - mounting more failure tolerant
|
|
# - added MANUAL part in script
|
|
# - length.vdr creation, you must not use it ;)
|
|
#
|
|
# Version 1.8
|
|
#
|
|
# - remove sudo, is not necessary
|
|
# - on mount, if already mounted try to umount first
|
|
# - logging per syslog, see $SYSLOG
|
|
#
|
|
# CONFIGURATION
|
|
# -------------
|
|
#<Configuration>
|
|
|
|
set -x
|
|
exec 2>/tmp/da.log
|
|
|
|
# Mountpoint, the same as in fstab
|
|
MOUNTPOINT="/media/hdext" # no trailing '/'
|
|
|
|
# Eject DVD for exit-codes 2 and 3 (no or wrong dvd). 1 = yes, 0 = no.
|
|
EJECTWRONG=0
|
|
|
|
# Eject DVD after unmounting. 1 = yes, 0 = no.
|
|
EJECTUMOUNT=0
|
|
|
|
# Log warnings/errors in syslog. 1 = yes, 0 = no.
|
|
SYSLOG=1
|
|
|
|
# Create a length.vdr after mounting the dvd for the played recording. 1 = yes, 0 = no.
|
|
# Only for non-vfat and with index.vdr only on dvd.
|
|
GETLENGTH=1
|
|
|
|
# Put debug infos in file $DEBUGLOG. Only if $DEBUG=1.
|
|
DEBUG=0
|
|
DEBUGLOG="/tmp/dvdarchive.sh-debug.log"
|
|
|
|
#</Configuration>
|
|
|
|
# read config file
|
|
. /etc/vdr/dvdarchive.conf
|
|
|
|
#
|
|
# No changes needed after this mark
|
|
|
|
# Remove trailing slash
|
|
MOUNTPOINT="$(echo "${MOUNTPOINT}" | sed -e 's/\/$//')"
|
|
|
|
if [ -L "$MOUNTPOINT" ]; then
|
|
MOUNTPOINTT="$(find "$MOUNTPOINT" -printf "%l")"
|
|
else
|
|
MOUNTPOINTT="$MOUNTPOINT"
|
|
fi
|
|
|
|
# Search a device mounted on $MOUNTPOINT or not mounted
|
|
DEVICE=$(mount | grep $MOUNTPOINT | awk '{print $1}')
|
|
|
|
if [ -Z $DEVICE ]; then
|
|
disks=$(cat /proc/partitions | egrep "sd[a-z][0-9]" | awk '{printf("/dev/%s\n", $4)}')
|
|
mounted=$(mount | grep /dev/sd | awk '{print $1}')
|
|
|
|
for d in $disks; do
|
|
found=0
|
|
for m in $mounted; do
|
|
if [ $d == $m ]; then
|
|
found=1
|
|
break
|
|
fi
|
|
done
|
|
if [ $found == 0 ]; then
|
|
echo "not found: $d -> mounting"
|
|
DEVICE=$d
|
|
fi
|
|
done
|
|
fi
|
|
|
|
if [ -Z $DEVICE ]; then
|
|
# determine dvd-device, used by eject and isodetect if exists
|
|
DEVICE="$(awk '( $1 !~ /^#/ ) && ( $2 == "'$MOUNTPOINT'" ) { printf("%s", $1); exit; }' /etc/fstab)"
|
|
fi
|
|
if [ -L "$DEVICE" ]; then
|
|
DEVICET="$(find "$DEVICE" -printf "%l")"
|
|
else
|
|
DEVICET="$DEVICE"
|
|
fi
|
|
|
|
ACTION="$1"
|
|
REC="$2"
|
|
NAME="$3"
|
|
|
|
if [ "$ACTION" = "mount" -a -z "$NAME" ]; then
|
|
NAME="basename ${REC})"
|
|
fi
|
|
|
|
# function to print help
|
|
call() {
|
|
echo -e "\nScript $0 needs three parameters for mount and two for umount. The first must be mount or umount, the second is the full path.\n"
|
|
echo -e "Only for mounting the script needs a third parameter, the last part of the recording path.\n"
|
|
echo -e "Example: dvdarchive.sh mount '/video0/Music/%Riverdance/2004-06-06.00:10.50.99.rec' '2004-06-06.00:10.50.99.rec'\n"
|
|
echo -e "Example: dvdarchive.sh umount '/video0/Music/%Riverdance/2004-06-06.00:10.50.99.rec'\n"
|
|
echo -e "For more information read the MANUAL part inside this script.\n"
|
|
}
|
|
|
|
|
|
# function to log messages
|
|
log() {
|
|
case "$1" in
|
|
info)
|
|
echo -e "INFO: $2"
|
|
[ $SYSLOG -eq 1 ] && logger -t "$0" "INFO: $2"
|
|
;;
|
|
warning)
|
|
echo -e "WARNING: $2"
|
|
[ $SYSLOG -eq 1 ] && logger -t "$0" "WARNING: $2"
|
|
;;
|
|
error)
|
|
echo -e "ERROR: $2"
|
|
[ $SYSLOG -eq 1 ] && logger -t "$0" "ERROR: $2"
|
|
if [ $DEBUG -eq 1 ]; then
|
|
echo "-------" >> $DEBUGLOG
|
|
echo -e "Parameters: $ACTION $REC $NAME\n" >> $DEBUGLOG
|
|
echo -e "ERROR: $2\n\n" >> $DEBUGLOG
|
|
echo -e "Mountpoint: $MOUNTPOINT\nDevice: $DEVICE\n" >> $DEBUGLOG
|
|
echo -e "MountpointT: $MOUNTPOINTT\nDeviceT: $DEVICET\n" >> $DEBUGLOG
|
|
FSTAB="$(awk '( $1 !~ /^#/ ) && ( $2 == "'$MOUNTPOINT'" || $2 == "'$MOUNTPOINTT'" ) { printf("%s", $0); }' /etc/fstab)"
|
|
echo -e "fstab: ${FSTAB}\n" >>$DEBUGLOG
|
|
echo -e "Filesystem: $(stat -f -c %T "$REC")\n" >> $DEBUGLOG
|
|
mount >> $DEBUGLOG
|
|
echo >> $DEBUGLOG
|
|
cat /proc/mounts >> $DEBUGLOG
|
|
echo >> $DEBUGLOG
|
|
sudo -l >> $DEBUGLOG
|
|
fi
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Some checks before doing something
|
|
[ "$ACTION" = "mount" -o "$ACTION" = "umount" ] || { call; exit 10; }
|
|
[ -z "$REC" -o ! -d "$REC" ] && { call; exit 10; }
|
|
[ "$ACTION" = "mount" -a -z "$NAME" ] && { call; exit 10; }
|
|
[ ! -d "$MOUNTPOINT" ] && { log error "Mountpoint $MOUNTPOINT doesn't exist"; exit 10; }
|
|
[ ! -e "$DEVICE" ] && { log error "Device >$DEVICE< doesn't exist"; exit 10; }
|
|
|
|
|
|
|
|
case "$ACTION" in
|
|
mount)
|
|
# check if dvd is in drive, only if isodetect exists
|
|
if [ -n "$(which isodetect)" -a -n "$DEVICE" ]; then
|
|
isodetect -d "$DEVICE" >/dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
log warning "no dvd in drive"
|
|
[ $EJECTWRONG -eq 1 ] && { eject "$DEVICE"; }
|
|
exit 2
|
|
fi
|
|
fi
|
|
# check if not mounted
|
|
if mount | egrep -q " $MOUNTPOINTT "; then
|
|
# check if dvd is in use
|
|
if mount | egrep -q "^$DEVICET"; then
|
|
log warning "dvd in use (at: check if dvd is in use)"
|
|
fi
|
|
# if already mountet, try to umount
|
|
log warning "dvd already mounted, try to umount"
|
|
sudo umount "$MOUNTPOINT" || { log error "dvd umount error (at: dvd already mounted, try to umount)"; exit 1; }
|
|
# unlink broken existing links
|
|
for LINK in "${REC}/"*.vdr; do
|
|
if [ -L "$LINK" -a ! -s "$LINK" ]; then
|
|
rm "$LINK"
|
|
fi
|
|
done
|
|
for LINK in "${REC}/"*.ts; do
|
|
if [ -L "$LINK" -a ! -s "$LINK" ]; then
|
|
rm "$LINK"
|
|
fi
|
|
done
|
|
fi
|
|
# mount dvd
|
|
sudo mount $DEVICE "$MOUNTPOINT" || { log error "dvd mount error (at: mount dvd)"; exit 1; }
|
|
# is mounted, find recording on dvd
|
|
DIR="$(find "${MOUNTPOINT}/links/" -maxdepth 2 -name "$NAME")"
|
|
if [ -z "$DIR" ]; then
|
|
# not found in links - try root
|
|
DIR="$(find "${MOUNTPOINT}/" -maxdepth 2 -name "$NAME")"
|
|
# if not found, umount
|
|
if [ -z "$DIR" ]; then
|
|
log error "wrong dvd in drive / recording not found on dvd"
|
|
umount "$MOUNTPOINT" || { log error "dvd umount error (at: wrong dvd in drive / recording not found on dvd)"; exit 1; }
|
|
# If wanted, eject dvd
|
|
[ $EJECTWRONG -eq 1 ] && { eject "$DEVICE"; }
|
|
exit 3
|
|
fi
|
|
fi
|
|
# check if video partition is vfat
|
|
if [ "$(stat -f -c %T "$REC")" != "vfat" ]; then
|
|
# link index.vdr if not exist
|
|
if [ ! -e "${REC}/index.vdr" ]; then
|
|
if [ -e "${DIR}/index.vdr" ]; then
|
|
ln -s "${DIR}/index.vdr" "${REC}/index.vdr" || { log error "could not link index.vdr (at: link index.vdr from dvd to disk)"; }
|
|
fi
|
|
fi
|
|
if [ ! -e "${REC}/index" ]; then
|
|
if [ -e "${DIR}/index" ]; then
|
|
ln -s "${DIR}/index" "${REC}/index" || { log error "could not link index (at: link index.vdr from dvd to disk)"; }
|
|
fi
|
|
fi
|
|
# link [0-9]*.vdr files
|
|
#cp -s "${DIR}"/[0-9]*.vdr "${REC}/"
|
|
#find "${DIR}"/ -name "[0-9]*.vdr" -exec ln -s "${REC}/$(basename "{}")"
|
|
for f in "${DIR}/"[0-9]*.vdr; do
|
|
if [ -e $f ]; then
|
|
ln -s "$f" "${REC}/$(basename "$f")"
|
|
fi
|
|
done
|
|
for f in "${DIR}/"[0-9]*.ts; do
|
|
if [ -e $f ]; then
|
|
ln -s "$f" "${REC}/$(basename "$f")"
|
|
fi
|
|
done
|
|
# error while linking [0-9]*.vdr files?
|
|
if [ $? -ne 0 ]; then
|
|
log error "error while linking [0-9]*.vdr"
|
|
# umount dvd bevor unlinking
|
|
sudo umount "$MOUNTPOINT" || { log error "dvd umount error (at: error while linking)"; exit 1; }
|
|
# unlink broken links
|
|
for LINK in "${REC}/"*.vdr; do
|
|
if [ -L "$LINK" -a ! -s "$LINK" ]; then
|
|
rm "$LINK"
|
|
fi
|
|
done
|
|
for LINK in "${REC}/"*.ts; do
|
|
if [ -L "$LINK" -a ! -s "$LINK" ]; then
|
|
rm "$LINK"
|
|
fi
|
|
done
|
|
exit 4
|
|
fi
|
|
# If wanted, create length.vdr
|
|
#if [ $GETLENGTH -eq 1 -a ! -s "${REC}/length.vdr" -a -L "${REC}/index.vdr" ]; then
|
|
# echo $(( $(stat -L -c %s "${REC}/index.vdr")/12000 )) > "${REC}/length.vdr"
|
|
#fi
|
|
else
|
|
if [ ! "$(sudo -l | egrep "\(root\) NOPASSWD: /bin/mount")" -o ! "$(sudo -l | egrep "\(root\) NOPASSWD: /bin/umount")" ]; then
|
|
log error "you must configure sudo and allow $(whoami) to use mount/umount!"
|
|
log info "$(sudo -l)"
|
|
umount "$MOUNTPOINT" || { log error "dvd umount error (at: you must configure sudo)"; exit 1; }
|
|
exit 5
|
|
fi
|
|
# mount recording
|
|
sudo mount --bind "$DIR" "$REC"
|
|
if [ $? -ne 0 ]; then
|
|
log error "sudo mount --bind $DIR $REC"
|
|
umount "$MOUNTPOINT" || { log error "dvd umount error (at: sudo mount --bind)"; exit 1; }
|
|
exit 5
|
|
fi
|
|
fi
|
|
;;
|
|
umount)
|
|
# check if dvd is mounted
|
|
mount | egrep -q " $MOUNTPOINTT " || { log error "dvd not mounted (at: check if dvd is mounted)"; exit 1; }
|
|
# check if video partition is vfat
|
|
if [ "$(stat -f -c %T "$REC")" != "vfat" ]; then
|
|
# is mounted, umount dvd bevor unlinking
|
|
sudo umount "$MOUNTPOINT" || { log error "dvd umount error (at: is mounted, umount dvd bevor unlinking)"; exit 1; }
|
|
# unlink broken links
|
|
for LINK in "${REC}/"*.vdr; do
|
|
if [ -L "$LINK" -a ! -s "$LINK" ]; then
|
|
rm "$LINK"
|
|
fi
|
|
done
|
|
for LINK in "${REC}/"*.ts; do
|
|
if [ -L "$LINK" -a ! -s "$LINK" ]; then
|
|
rm "$LINK"
|
|
fi
|
|
done
|
|
else
|
|
# umount recording
|
|
sudo umount "$REC" || { log error "sudo umount $REC"; exit 5; }
|
|
# umount dvd at umount
|
|
sudo umount "$MOUNTPOINT" || { log error "dvd umount error (at: umount dvd at umount)"; exit 1; }
|
|
fi
|
|
# If wanted, eject dvd
|
|
[ $EJECTUMOUNT -eq 1 ] && { eject "$DEVICE"; }
|
|
;;
|
|
*)
|
|
# Output help
|
|
log error "\nWrong action $ACTION."
|
|
call
|
|
;;
|
|
esac
|
|
|
|
exit 0
|