summaryrefslogtreecommitdiff
path: root/scripts/dvdarchive.sh
blob: 0886b6c6c67da7ccb95b1e592994afa479854e3d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
#!/bin/sh
#
# 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>

# Mountpoint, the same as in fstab
MOUNTPOINT="/media/brenner" # no trailing '/'

# Eject DVD for exit-codes 2 and 3 (no or wrong dvd). 1 = yes, 0 = no.
EJECTWRONG=1

# 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
# determine dvd-device, used by eject and isodetect if exists
DEVICE="$(awk '( $1 !~ /^#/ ) && ( $2 == "'$MOUNTPOINT'" ) { printf("%s", $1); exit; }' /etc/fstab)"
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"
		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
	fi
	# mount dvd
 	mount "$MOUNTPOINT" || { log error "dvd mount error (at: mount dvd)"; exit 1; }
 	# is mounted, find recording on dvd
	DIR="$(find "${MOUNTPOINT}/" -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
	# 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
			ln -s "${DIR}/index.vdr" "${REC}/index.vdr" || { log error "could not link index.vdr (at: link index.vdr from dvd to disk)"; }
		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 FILE in "${DIR}/"[0-9]*.vdr; do
			ln -s "$FILE" "${REC}/$(basename "$FILE")"
		done
		# error while linking [0-9]*.vdr files?
		if [ $? -ne 0 ]; then
			log error "error while linking [0-9]*.vdr"
			# umount dvd bevor unlinking
			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
			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
		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
	else
		# umount recording
		sudo umount "$REC" || { log error "sudo umount $REC"; exit 5; }
		# umount dvd at umount
		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