-#!/usr/bin/python
+#!@PYTHON@
#
# Check the free space available on a writable DVD
# Should always exit with 0 status, otherwise it indicates a serious error.
#
# called: dvd-handler <dvd-device-name> operation args
#
-# where operation is one of
-# free
-# write
+# operations used by Bacula:
#
-# further arguments:
-# free: one argument: 0 to keep the existing data on disk, i.e.
-# free space is measured
-# anything else: overwrite entire disk, so
-# free space is always maximum space
+# free (no arguments)
+# Scan the device and report the available space. It returns:
+# Prints on the first output line the free space available in bytes.
+# If an error occurs, prints a negative number (-errno), followed,
+# on the second line, by an error message.
+#
+# write op filename
+# Write a part file to disk.
+# This operation needs two additional arguments.
+# The first (op) indicates to
+# 0 -- append
+# 1 -- first write to a blank disk
+# 2 -- blank or truncate a disk
+#
+# The second is the filename to write
+#
+# operations available but not used by Bacula:
+#
+# test Scan the device and report the information found.
+# This operation needs no further arguments.
+# prepare Prepare a DVD+/-RW for being used by Bacula.
+# Note: This is only useful if you already have some
+# non-Bacula data on a medium, and you want to use
+# it with Bacula. Don't run this on blank media, it
+# is useless.
#
-# in case of operation ``free'' returns:
-# Prints on the first output line the free space available in bytes.
-# If an error occurs, prints a negative number (-errno), followed,
-# on the second line, by an error message.
#
# $Id$
#
-# end of configurable values
-
import popen2
import os
+import os.path
import errno
import sys
import re
import signal
import time
+import array
class disk:
- # Configurable values:
- df = "@DF@ -P"
+# Configurable values:
+
dvdrwmediainfo = "@DVDRWMEDIAINFO@"
- growisofs = "@GROWISOFS@"
+ growcmd = "@GROWISOFS@"
+ dvdrwformat = "@DVDRWFORMAT@"
+ dd = "@DD@"
margin = 10485760 # 10 mb security margin
- # We disable 4GB boundary checking - function free should handle this
- # already, and it doesn't seem to work anyway (here: 2.6.8-24.18 from SuSE,
- # LG GSA-5163D, dvd+rw-tools 5.21
- growcmd = growisofs + " -use-the-force-luke=notray -use-the-force-luke=4gms "
- growcmd += "-A 'Bacula Data' -input-charset=default -iso-level 3 -pad " + \
- "-publisher 'ITS Lehmann info@its-lehmann.de' " + \
- "-p 'dvd-handler / growisofs' -sysid 'BACULADATA'"
+
+ # Comment the following line if you want the tray to be reloaded
+ # when writing ends.
+ growcmd += " -use-the-force-luke=notray"
+
+# end of configurable values
###############################################################################
#
-# This class represents a DVD disk (various flavours).
+# This class represents DVD disk informations.
# When instantiated, it needs a device name.
-# Status information about the device and the disk loaded is collected.
+# Status information about the device and the disk loaded is collected only when
+# asked for (for example dvd-freespace doesn't need to know the media type, and
+# dvd-writepart doesn't not always need to know the free space).
#
# The following methods are implemented:
-# __init__ we need that...
-# NOTE: Currently, this class only works with DVD+RW
-# and simply refuses to work with anything else.
-# This is because I had to start with some sort of disk,
-# and I learned that +RW and -RW are quite different, so
-# I decided to play it safe.
-# __repr__ this seems to be a good idea to have.
-# Quite minimalistic implementation, though.
-# __str__ For casts to string. Return the current disk information
-# is_empty Returns TRUE if the disk is empty, blank... this needs more
-# work, especially concerning non-RW media and blank vs. no
-# filesystem considerations. Here, we should also look for
-# other filesystems - probably we don't want to silently
-# overwrite UDF or ext2 or anything not mentioned in fstab...
-# is_RW TRUE if disk is rewritable. We need that to determine if
-# a new filesystem can be written onto a used disk.
-# lasterr returns a string describing the last error in the class.
-# Valuable after creating the object and after free()
-# free Returns the available free space, distinguishing between
-# new volume disks (overwrite everything) and appending
-# There are some assumtions about disk status and usage that
-# need work.
-# write Writes one part file to disk, either starting a new file
-# system on disk, or appending to it.
-# This method should also prepare a blank disk so that a
-# certain part of the disk is used to allow detection of a
-# used disk by all / more disk drives.
-# blank NOT IMPLEMENTED
+# __init__ we need that...
+# __repr__ this seems to be a good idea to have.
+# Quite minimalistic implementation, though.
+# __str__ For casts to string. Return the current disk information
+# is_empty Returns TRUE if the disk is empty, blank... this needs more
+# work, especially concerning non-RW media and blank vs. no
+# filesystem considerations. Here, we should also look for
+# other filesystems - probably we don't want to silently
+# overwrite UDF or ext2 or anything not mentioned in fstab...
+# (NB: I don't think it is a problem)
+# free Returns the available free space.
+# write Writes one part file to disk, either starting a new file
+# system on disk, or appending to it.
+# This method should also prepare a blank disk so that a
+# certain part of the disk is used to allow detection of a
+# used disk by all / more disk drives.
+# prepare Blank the device
#
###############################################################################
def __init__(self, devicename):
- self.device = "none"
+ self.device = devicename
self.disktype = "none"
- self.leadout = -1
- self.track = -1
- self.maximum = -1
- self.used = 0
- self.lasterror = "none"
+ self.diskmode = "none"
+ self.diskstatus = "none"
self.hardwaredevice = "none"
self.pid = 0
+ self.next_session = -1
+ self.capacity = -1
- # first, we collect information about the media as reported by
- # dvd+rw-mediainfo
- # we need an indication of the usable total size.
+ self.freespace_collected = 0
+ self.mediumtype_collected = 0
+
+ self.growcmd += " -quiet"
+
+ if self.is4gbsupported():
+ self.growcmd += " -use-the-force-luke=4gms"
+
+ self.growparams = " -A 'Bacula Data' -input-charset=default -iso-level 3 -pad " + \
+ "-p 'dvd-handler / growisofs' -sysid 'BACULADATA' -R"
- self.cmd = self.dvdrwmediainfo + " " + devicename
- self.processi = popen2.Popen4(self.cmd)
- self.status = self.processi.wait()
- if not os.WIFEXITED(self.status):
- self.lasterror = self.dvdrwmediainfo + " process did not exit correctly."
- return
- if os.WEXITSTATUS(self.status) != 0:
- self.lasterror = "Cannot get media info from " + self.dvdrwmediainfo
- return
- self.device = str(devicename)
- self.result = self.processi.fromchild.read()
- self.hardware = re.search(r"INQUIRY:\s+(.*)\n", self.result, re.MULTILINE)
- self.mediatype = re.search(r"\sMounted Media:\s+([0-9A-F]{2})h, (\S*)\s",
- self.result, re.MULTILINE)
- self.tracksize = re.search(r"\sTrack Size:\s+(\d+)\*2KB\s",
- self.result, re.MULTILINE)
- self.leadout = re.search(r"\sLegacy lead-out at:\s+(\d+)\*2KB=(\d+)\s",
- self.result, re.MULTILINE)
- if self.hardware:
- self.hardwaredevice = self.hardware.group(1)
- if self.mediatype:
- self.disktype = self.mediatype.group(2)
- else:
- self.lasterror = "Media type not found."
- if self.leadout:
- self.leadout = long(self.leadout.group(1))*2048
- else:
- self.lasterror = "Lead-out block not found."
- if self.tracksize:
- self.track = long(self.tracksize.group(1))*2048
- else:
- self.lasterror = "Track size not found."
- self.result = 0
- if ( "DVD+RW" == self.disktype ):
- if self.leadout > self.track:
- self.result = self.leadout
- else:
- self.result = self.track
- else:
- self.lasterror = "Unsupported media: " + self.disktype
- self.maximum = self.result - self.margin
- if self.maximum < 0:
- self.maximum = 0
-
- # now, the actual size used on the disk.
- # here, we use what df reports, although the
- # current track size should give us the necessary information,
- # too. Well, depending on the media type, it seems.
- # We should see if the media is mounted, try to mount, if possible
- # proceed and, if necessary, unmount. Otherwise assume 0 used bytes.
- # __init__ and __del__ would be the right places to mount and
- # unmount - mounting before df'ing is always a good idea,
- # and setting the previos state might be important.
-
- self.cmd = self.df + " " + self.device
- self.process = popen2.Popen4(self.cmd)
- self.status = self.process.wait()
- if not os.WIFEXITED(self.status):
- self.lasterror = self.df + " process did not not exit correctly."
- return
- self.exitstat = os.WEXITSTATUS(self.status) & ~0x80
- if self.exitstat == errno.ENOSPC:
- self.used = 0
- elif self.exitstat != 0:
- self.lasterror = os.strerror(self.exitstat)
- return
- self.dftext = self.process.fromchild.read()
- self.blocks = re.search(self.device + r"\s+(\d+)\s+",
- self.dftext, re.MULTILINE)
- if self.blocks:
- self.used = long(self.blocks.group(1))*1024
- else:
- self.used = 0
- self.lasterror = "No blocks found in " + self.cmd + " output:\n"
- self.lasterror += self.dftext
return
def __repr__(self):
return "disk(" + self.device + ") # This is an instance of class disk"
def __str__(self):
- self.me = "Class disk, initialized with device " + self.device + "\n"
- self.me += "type = " + self.disktype + " leadout = " + str(self.leadout)
- self.me += " track = " + str(self.track) + " maximum = " + str(self.maximum) + "\n"
- self.me += "used = " + str(self.used) + "\n"
- self.me += "Hardware device is " + self.hardwaredevice + "\n"
- self.me += "last error = " + self.lasterror + "\n"
+ if not self.freespace_collected:
+ self.collect_freespace();
+ if not self.mediumtype_collected:
+ self.collect_mediumtype();
+
+ self.me = "Class disk, initialized with device '" + self.device + "'\n"
+ self.me += "type = '" + self.disktype + "' mode='" + self.diskmode + "' status = '" + self.diskstatus + "'\n"
+ self.me += " next_session = " + str(self.next_session) + " capacity = " + str(self.capacity) + "\n"
+ self.me += "Hardware device is '" + self.hardwaredevice + "'\n"
+ self.me += "growcmd = '" + self.growcmd + "'\ngrowparams = '" + self.growparams + "'\n"
return self.me
+ ## Check if we want to allow growisofs to cross the 4gb boundary
+ def is4gbsupported(self):
+ processi = popen2.Popen4("uname -s -r")
+ status = processi.wait()
+ if not os.WIFEXITED(status):
+ return 1
+ if os.WEXITSTATUS(status) != 0:
+ return 1
+ strres = processi.fromchild.readline()[0:-1]
+ version = re.search(r"Linux (\d+)\.(\d+)\.(\d+)", strres)
+ if not version: # Non-Linux: allow
+ return 1
+
+ if (int(version.group(1)) > 2) or (int(version.group(2)) > 6) or ((int(version.group(1)) == 2) and (int(version.group(2)) == 6) and (int(version.group(3)) >= 8)):
+ return 1
+ else:
+ return 0
+
+ def collect_freespace(self): # Collects current free space
+ self.cmd = self.growcmd + " -F " + self.device
+ processi = popen2.Popen4(self.cmd)
+ status = processi.wait()
+ if not os.WIFEXITED(status):
+ raise DVDError(0, "growisofs process did not exit correctly.")
+ result = processi.fromchild.read()
+ if os.WEXITSTATUS(status) != 0:
+ if (os.WEXITSTATUS(status) & 0x7F) == errno.ENOSPC:
+ # Kludge to force dvd-handler to return a free space of 0
+ self.next_session = 1
+ self.capacity = 1
+ self.freespace_collected = 1
+ return
+ else:
+ raise DVDError(os.WEXITSTATUS(status), "growisofs returned with an error " + result + ". Please check your are using a patched version of dvd+rw-tools.")
+ next_sess = re.search(r"\snext_session=(\d+)\s", result, re.MULTILINE)
+ capa = re.search(r"\scapacity=(\d+)\s", result, re.MULTILINE)
+
+ if next_sess and capa:
+ self.next_session = long(next_sess.group(1))
+ self.capacity = long(capa.group(1))
+
+ # testing cheat (emulate 4GB boundary at 100MB)
+ #if self.next_session > 100000000:
+ # self.capacity = self.next_session
+ else:
+ raise DVDError(0, "Cannot get next_session and capacity from growisofs.\nReturned: " + result)
+
+ self.freespace_collected = 1
+ return
+
+ def collect_mediumtype(self): # Collects current medium type
+ self.lasterror = ""
+ cmd = self.dvdrwmediainfo + " " + self.device
+ processi = popen2.Popen4(cmd)
+ status = processi.wait()
+ if not os.WIFEXITED(status):
+ raise DVDError(0, self.dvdrwmediainfo + " process did not exit correctly.")
+ if os.WEXITSTATUS(status) != 0:
+ raise DVDError(0, "Cannot get media info from " + self.dvdrwmediainfo)
+ return
+ result = processi.fromchild.read()
+
+ hardware = re.search(r"INQUIRY:\s+(.*)\n", result, re.MULTILINE)
+ mediatype = re.search(r"\sMounted Media:\s+([0-9A-F]{2})h, (\S*)\s", result, re.MULTILINE)
+ mediamode = re.search(r"\sMounted Media:\s+[0-9A-F]{2}h, \S* (.*)\n", result, re.MULTILINE)
+ status = re.search(r"\sDisc status:\s+(.*)\n", result, re.MULTILINE)
+
+ if hardware:
+ self.hardwaredevice = hardware.group(1)
+
+ if mediatype:
+ self.disktype = mediatype.group(2)
+ else:
+ raise DVDError(0, "Media type not found in " + self.dvdrwmediainfo + " output")
+
+ if self.disktype == "DVD-RW":
+ if mediamode:
+ self.diskmode = mediamode.group(1)
+ else:
+ raise DVDError(0, "Media mode not found for DVD-RW in " + self.dvdrwmediainfo + " output")
+
+ if status:
+ self.diskstatus = status.group(1)
+ else:
+ raise DVDError(0, "Disc status not found in " + self.dvdrwmediainfo + " output")
+
+
+ self.mediumtype_collected = 1
+ return
+
def is_empty(self):
- return 0 == self.used
- # This works for DVD+RW, probably for all rewritable media. self.blank for -R?
- # This is quite definitely not the best method. I need something
- # that detects if a session exists on disk, but I didn't do any
- # experiments with non-RW media yet.
+ if not self.freespace_collected:
+ self.collect_freespace();
+
+ return 0 == self.next_session
def is_RW(self):
+ if not self.mediumtype_collected:
+ self.collect_mediumtype();
return "DVD-RW" == self.disktype or "DVD+RW" == self.disktype or "DVD-RAM" == self.disktype
- def free(self, newvol):
- if self.used < 0 or self.maximum <= 0:
- return -1
- elif newvol:
- self.ret = self.maximum
- if not self.is_empty() and not self.is_RW():
- # better check real disks usage state as read from dvd+rw-mediainfo.
- # introduce self.blank
- self.ret = -1
- self.lasterror = self.disktype + " can not be overwritten and is already used"
- else:
- self.ret = self.maximum - self.used
- if self.used > 4278190080: # if more than 4GB-16MB are already used
- self.ret = 0
- return self.ret
+ def is_plus_RW(self):
+ if not self.mediumtype_collected:
+ self.collect_mediumtype();
+ return "DVD+RW" == self.disktype
+
+ def is_minus_RW(self):
+ if not self.mediumtype_collected:
+ self.collect_mediumtype();
+ return "DVD-RW" == self.disktype
+
+ def is_restricted_overwrite(self):
+ if not self.mediumtype_collected:
+ self.collect_mediumtype();
+ return self.diskmode == "Restricted Overwrite"
- def lasterr(self):
- return self.lasterror
+ def is_blank(self):
+ if not self.mediumtype_collected:
+ self.collect_mediumtype();
+
+ return self.diskstatus == "blank"
+
+ def free(self):
+ if not self.freespace_collected:
+ self.collect_freespace();
+
+ fr = self.capacity-self.next_session-self.margin
+ if fr < 0:
+ return 0
+ else:
+ return fr
def term_handler(self, signum, frame):
print 'dvd-handler: Signal term_handler called with signal', signum
sys.exit(1)
def write(self, newvol, partfile):
- self.lasterror = "none"
- self.partstat = os.stat(partfile)
- if not self.partstat:
- self.lasterror = "Could not stat " + str(partfile) + " which is a fatal error."
- return
- if self.partstat.st_size > self.free(newvol):
- self.lasterror = "Part " + str(partfile) + " is too big: " \
- + str(self.partstat.st_size) + ", free " + str(self.free(newvol))
+ # Blank DVD+RW when there is no data on it
+ if newvol and self.is_plus_RW() and self.is_blank():
+ print "DVD+RW looks brand-new, blank it to fix some DVD-writers bugs."
+ self.blank()
+ print "Done, now writing the part file."
+
+ if newvol and self.is_minus_RW() and (not self.is_restricted_overwrite()):
+ print "DVD-RW is in " + self.diskmode + " mode, reformating it to Restricted Overwrite"
+ self.reformat_minus_RW()
+ print "Done, now writing the part file."
+
+ cmd = self.growcmd + self.growparams
+ if newvol:
+ # Ignore any existing iso9660 filesystem - used for truncate
+ if newvol == 2:
+ cmd += " -use-the-force-luke=tty"
+ cmd += " -Z "
+ else:
+ cmd += " -M "
+ cmd += self.device + " " + str(partfile)
+ print "Running " + cmd
+ oldsig = signal.signal(signal.SIGTERM, self.term_handler)
+ proc = popen2.Popen4(cmd)
+ self.pid = proc.pid
+ status = proc.poll()
+ while status == -1:
+ line = proc.fromchild.readline()
+ while len(line) > 0:
+ print line,
+ line = proc.fromchild.readline()
+ time.sleep(1)
+ status = proc.poll()
+ self.pid = 0
+ print
+ signal.signal(signal.SIGTERM, oldsig)
+ if not os.WIFEXITED(status):
+ raise DVDError(0, cmd + " process did not exit correctly, signal/status " + str(status))
+ if os.WEXITSTATUS(status) != 0:
+ raise DVDError(os.WEXITSTATUS(status), cmd + " exited with status " + str(os.WEXITSTATUS(status)) + ", signal/status " + str(status))
+
+ def prepare(self):
+ if not self.is_RW():
+ raise DVDError(0, "I won't prepare a non-rewritable medium")
+
+ # Blank DVD+RW when there is no data on it
+ if self.is_plus_RW() and self.is_blank():
+ print "DVD+RW looks brand-new, blank it to fix some DVD-writers bugs."
+ self.blank()
+ return # It has been completely blanked: Medium is ready to be used by Bacula
+
+ if self.is_minus_RW() and (not self.is_restricted_overwrite()):
+ print "DVD-RW is in " + self.diskmode + " mode, reformating it to Restricted Overwrite"
+ self.reformat_minus_RW()
+ return # Reformated: Medium is ready to be used by Bacula
+
+ # TODO: Check if /dev/fd/0 and /dev/zero exists, otherwise, run self.blank()
+ if not os.path.exists("/dev/fd/0") or not os.path.exists("/dev/zero"):
+ print "/dev/fd/0 or /dev/zero doesn't exist, blank the medium completely."
+ self.blank()
return
- if "DVD-RW" == self.disktype:
- self.cmd = self.growcmd + " -R "
- if newvol:
- self.cmd += "-Z "
- else:
- self.cmd += "-M "
- self.cmd += self.device + " " + str(partfile)
- self.oldsig = signal.signal(signal.SIGTERM, self.term_handler)
- self.proc = popen2.Popen4(self.cmd)
- self.pid = self.proc.pid
- self.status = self.proc.poll()
- while -1 == self.status:
- self.out = self.proc.fromchild.read(512)
- while "" != self.out:
- sys.stdout.write(self.out)
- self.out = self.proc.fromchild.read(512)
- time.sleep(1)
- self.status = self.proc.poll()
- self.pid = 0
- print
- signal.signal(signal.SIGTERM, self.oldsig)
- if 0 != os.WEXITSTATUS(self.status):
- self.lasterror = self.cmd + " exited with status " + str(os.WEXITSTATUS(self.status))
- print self.cmd + " exited with signal/status " + hex(self.status)
- else: # Other disk type
- self.lasterror = "Can't write to " + self.disktype
+
+ cmd = self.dd + " if=/dev/zero bs=1024 count=512 | " + self.growcmd + " -Z " + self.device + "=/dev/fd/0"
+ print "Running " + cmd
+ oldsig = signal.signal(signal.SIGTERM, self.term_handler)
+ proc = popen2.Popen4(cmd)
+ self.pid = proc.pid
+ status = proc.poll()
+ while status == -1:
+ line = proc.fromchild.readline()
+ while len(line) > 0:
+ print line,
+ line = proc.fromchild.readline()
+ time.sleep(1)
+ status = proc.poll()
+ self.pid = 0
+ print
+ signal.signal(signal.SIGTERM, oldsig)
+ if os.WEXITSTATUS(status) != 0:
+ raise DVDError(os.WEXITSTATUS(status), cmd + " exited with status " + str(os.WEXITSTATUS(status)) + ", signal/status " + str(status))
+
+ def blank(self):
+ cmd = self.growcmd + " -Z " + self.device + "=/dev/zero"
+ print "Running " + cmd
+ oldsig = signal.signal(signal.SIGTERM, self.term_handler)
+ proc = popen2.Popen4(cmd)
+ self.pid = proc.pid
+ status = proc.poll()
+ while status == -1:
+ line = proc.fromchild.readline()
+ while len(line) > 0:
+ print line,
+ line = proc.fromchild.readline()
+ time.sleep(1)
+ status = proc.poll()
+ self.pid = 0
+ print
+ signal.signal(signal.SIGTERM, oldsig)
+ if os.WEXITSTATUS(status) != 0:
+ raise DVDError(os.WEXITSTATUS(status), cmd + " exited with status " + str(os.WEXITSTATUS(status)) + ", signal/status " + str(status))
+
+ def reformat_minus_RW(self):
+ cmd = self.dvdrwformat + " -force " + self.device
+ print "Running " + cmd
+ oldsig = signal.signal(signal.SIGTERM, self.term_handler)
+ proc = popen2.Popen4(cmd)
+ self.pid = proc.pid
+ status = proc.poll()
+ while status == -1:
+ line = proc.fromchild.readline()
+ while len(line) > 0:
+ print line,
+ line = proc.fromchild.readline()
+ time.sleep(1)
+ status = proc.poll()
+ self.pid = 0
+ print
+ signal.signal(signal.SIGTERM, oldsig)
+ if os.WEXITSTATUS(status) != 0:
+ raise DVDError(os.WEXITSTATUS(status), cmd + " exited with status " + str(os.WEXITSTATUS(status)) + ", signal/status " + str(status))
+
# class disk ends here.
+class DVDError(Exception):
+ def __init__(self, errno, value):
+ self.errno = errno
+ self.value = value
+ if self.value[-1] == '\n':
+ self.value = self.value[0:-1]
+ def __str__(self):
+ return str(self.value) + " || errno = " + str(self.errno) + " (" + os.strerror(self.errno & 0x7F) + ")"
-if len(sys.argv) < 3:
+def usage():
print "Wrong number of arguments."
print """
-This program needs to be called with the following parameters.
+Usage:
-device operation [more arguments]
+dvd-handler DEVICE test
+dvd-handler DEVICE free
+dvd-handler DEVICE write APPEND FILE
+dvd-handler DEVICE prepare
-where device is a device name like /dev/sr0 or /dev/dvd and
-operation can be "test", "free" or "write".
+where DEVICE is a device name like /dev/sr0 or /dev/dvd.
Operations:
-test Scan the device and report the information found.
+test Scan the device and report the information found.
This operation needs no further arguments.
-free Scan the device and report the available space.
- "free" needs one additional argument to determine
- if data is to be appended or if the disk will be
- started from the beginning: "0" means append,
- everything else indicates a new volume.
-write Write a part file to disk.
+free Scan the device and report the available space.
+write Write a part file to disk.
This operation needs two additional arguments.
- The first indicates to append or restart the
- disk; see above. The second is the file to write.
+ The first indicates to append (0), restart the
+ disk (1) or restart existing disk (2). The second
+ is the file to write.
+prepare Prepare a DVD+/-RW for being used by Bacula.
+ Note: This is only useful if you already have some
+ non-Bacula data on a medium, and you want to use
+ it with Bacula. Don't run this on blank media, it
+ is useless.
"""
sys.exit(1)
+if len(sys.argv) < 3:
+ usage()
+
dvd = disk(sys.argv[1])
if "free" == sys.argv[2]:
- if len(sys.argv) == 4:
- newvol = 1
- if "0" == sys.argv[3]:
- newvol = 0
- free = dvd.free(newvol)
- print free
- if free >= 0:
+ if len(sys.argv) == 3:
+ try:
+ free = dvd.free()
+ except DVDError, e:
+ if e.errno != 0:
+ print -e.errno
+ else:
+ print errno.EPIPE
+ print str(e)
+ else:
+ print free
print "No Error reported."
+ else:
+ print "Wrong number of arguments for free operation. Wanted 3 got", len(sys.argv)
+ usage()
+elif "prepare" == sys.argv[2]:
+ if len(sys.argv) == 3:
+ try:
+ dvd.prepare()
+ except DVDError, e:
+ print "Error while preparing medium: ", str(e)
+ if e.errno != 0:
+ sys.exit(e.errno & 0x7F)
+ else:
+ sys.exit(errno.EPIPE)
else:
- print dvd.lasterr()
+ print "Medium prepared successfully."
else:
- print "Wrong number of arguments."
- sys.exit(1)
+ print "Wrong number of arguments for prepare operation. Wanted 3 got", len(sys.argv)
+ usage()
elif "test" == sys.argv[2]:
- print str(dvd)
- print "Empty disk: " + str(dvd.is_empty()) + " ReWritable disk: " + str(dvd.is_RW())
- print "Free for new volume: " + str(dvd.free(1))
- print "Free for append: " + str(dvd.free(0))
+ try:
+ print str(dvd)
+ print "Blank disk: " + str(dvd.is_blank()) + " ReWritable disk: " + str(dvd.is_RW())
+ print "Free space: " + str(dvd.free())
+ except DVDError, e:
+ print "Error while getting informations: ", str(e)
elif "write" == sys.argv[2]:
if len(sys.argv) == 5:
- newvol = 1
- if "0" == sys.argv[3]:
- newvol = 0
- dvd.write(newvol, sys.argv[4])
- if "none" != dvd.lasterr():
- print str(dvd.lasterr())
- sys.exit(1)
+ try:
+ dvd.write(long(sys.argv[3]), sys.argv[4])
+ except DVDError, e:
+ print "Error while writing part file: ", str(e)
+ if e.errno != 0:
+ sys.exit(e.errno & 0x7F)
+ else:
+ sys.exit(errno.EPIPE)
else:
print "Part file " + sys.argv[4] + " successfully written to disk."
else:
- print "Wrong number of arguments."
+ print "Wrong number of arguments for write operation. Wanted 5 got", len(sys.argv)
+ usage()
sys.exit(1)
else:
- print "No operation - use test, free or write."
+ print "No operation - use test, free, prepare or write."
print "THIS MIGHT BE A CASE OF DEBUGGING BACULA OR AN ERROR!"
sys.exit(0)