#!/bin/bash #.Y / 70 83 / / / / 105 / / / / / / ;A4_QUER.Y #.YT 3 2 0 0 3 3 1 / / / #.H!a!0:linux//io/tape_/ft!0.!c # # copyright : (C) 2009 by Thomas Bruecker =: tbrue # email : public0x05bf@bluewin.ch # # tbrue 12jun2006 # # ft : tape functions of a floppy tape #+++++++++++++++++++++++++++++++++++++ # # $1 in {N, NRAW, R, RAW, SCRIPT} # # MyHash("linux//io/tape_/ft") = 0x0A29 # # * for every function: # * if returned result is not commented, the function returns 0 on no-error. # # default device for ftformat: # --------------------------- # # default device for ftformat is /dev/rawft0, so use raw device. # default device for vtblc: # ------------------------ # # default device for vtblc is /dev/rawft0, so use raw device. # functions: # --------- if [ "SCRIPT" = "$1" ]; then # is part of the tape-device- # script. tape_asf() # $1: device, $2: count. # * count = 0 --> first file=volume. { ftmt -f $DeviceN_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 asf $2 return } tape_badSectors() # $1: device. { vtblc --bsm -f $DeviceNRAW_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 return } tape_bs() # $1: device, $2 device-specifier in {N, NRAW, R, RAW}. { ftmt -f $(. $1 $2) \ setblk $BS_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 return } tape_contents() # $1: device. { vtblc -f $DeviceNRAW_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 --print return } tape_ddFrom() # $1: device, $2...: parameters. # * dd with input=device --> output from tape. # * no need to give count if reading file=volume; stops automatically. { local Device0x0A29 Result0x0A29 Device0x0A29=$1 shift 1 tape_ddParameterError from $* Result0x0A29=$? if [ ! "$Result0x0A29" = "0" ]; then return $Result0x0A29; fi # else tape_bs $Device0x0A29 N Result0x0A29=$? if [ ! "$Result0x0A29" = "0" ]; then return $Result0x0A29; fi # else dd if=$DeviceN_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 \ bs=$BS_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 $* return } tape_ddTo() # $1: device, $2...: parameters. # * dd with output=device --> output to tape. # * with DeviceN, every dd_of=_operation creates a new file=volume. # * you are not allowed to append to an existing volume. # * if the file-position is at a not-emtpy-volume, the dd-operation is # not allowed, except at volume 0; this is overwritten and the follo- # wing volumes are deleted. { local Device0x0A29 Result0x0A29 Device0x0A29=$1 shift 1 tape_ddParameterError to $* Result0x0A29=$? if [ ! "$Result0x0A29" = "0" ]; then return $Result0x0A29; fi # else tape_bs $Device0x0A29 N Result0x0A29=$? if [ ! "$Result0x0A29" = "0" ]; then return $Result0x0A29; fi # else dd of=$DeviceN_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 \ bs=$BS_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 $* return # do not rewind tape, allow tape_ddTo to append to the existing # files=volumes. } tape_delete() # $1: device. # * delete last file=volume . { vtblc -f $DeviceNRAW_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 -t return } tape_emptyQ() # $1: device. # * print # 0 to stdout if tape is empty, # 1 to stdout else. { local Result0x0A29 vtbl0x0A29 Result0x0A29=$(tape_validHeaderQ $1) if [ $Result0x0A29 = "1" ]; then echo 0 # invalid header ==> tape is return # empty. fi # else vtbl0x0A29=$(vtblc \ -f $DeviceNRAW_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 \ --print) Result0x0A29=$? if [ ! "$Result0x0A29" = "0" ]; then return $Result0x0A29; fi # strip leading comments / title: vtbl0x0A29=$(echo "$vtbl0x0A29" | tail +7 -) if [ -z "$vtbl0x0A29" ]; then echo 0 else echo 1 fi return 0 } tape_eom() # $1: device. # * advance to the end of recorded area, ready to append another # file=volume. { ftmt -f $DeviceN_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 eom return } tape_erase() # $1: device. { ftmt -f $DeviceR_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 erase return } tape_flf() # $1: device. # * advance to the begin of the last recorded file=volume. ready to read # it. { local Result0x0A29 ftmt -f $DeviceN_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 eom Result0x0A29=$? if [ ! "$Result0x0A29" = "0" ]; then return $Result0x0A29; fi ftmt -f $DeviceN_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 bsf 2 return } tape_format120() # $1: device. # { local QDiscardHeader0x0A29 # ?DiscardHeader . /etc/tape/qic80/120MB # get format-parameters. # avoid error with invalid header when trying to read the old header- # segment: echo " check '$1' for a valid header." if [ $(tape_validHeaderQ $1) = "0" ]; then QDiscardHeader0x0A29="" # valid header: keep it. else QDiscardHeader0x0A29="--discard-header" # invalid header: discard it. fi # * what is intended: # * keep the old bad-sector-map, so do not use the option # "--discard-header" . # * --- but: ftformat (ftape-tools) ver. 1.09 stops after formatting # and before verifying, returning the error-code 255 and the error- # message "Error re-opening tape dev read/write: Device or resource # busy"; so the old header is lost anyway. 1*) # * to avoid the error-message "Tape drive error sending physical for- # ward command: 15 (Command Illegal or Undefined in Format Mode)", use # the option "--omit-erase" . # ftformat -f $DeviceRAW_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 \ $format_parameters_CB5853FF_382E_11DA_BABF_0000C00A45A9 \ --mode=force --omit-erase $QDiscardHeader0x0A29 # test stuff: # --no-reference-bursts return } tape_getBS() # $1: device. # * print block-size to stdout. { echo "$BS_0xCB5853FF_382E_11DA_BABF_0000C00A45A9" return } tape_retension() # $1: device. { ftmt -f $DeviceNRAW_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 retension return } tape_rewind() # $1: device, $2 device-specifier in {N, NRAW, R, RAW}. { ftmt -f $(. $1 $2) rewind return } tape_size() # $1: device. { local RealSize0x0A29 Result0x0A29 Size0x0A29 VolInfo0x0A29 # must not use raw device here ! VolInfo0x0A29=$(ftmt -f $DeviceN_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 \ --long-numbers volinfo) Result0x0A29=$? if [ ! "$Result0x0A29" = "0" ]; then return $Result0x0A29; fi # get real size: # chose correct line: # delete unwanted columns: # remove leading spaces: RealSize0x0A29=$(echo "$VolInfo0x0A29" \ | grep "real size of volume" \ | colrm 34 | colrm 1 22 \ | sed 's/ *//') # get size: # chose correct line: # delete unwanted columns: # remove leading spaces: Size0x0A29=$(echo "$VolInfo0x0A29" \ | grep "physical space used" \ | colrm 34 | colrm 1 22 \ | sed 's/ *//') # * let "l" be the nr. of the last file=volume in the volume-table. # * you may move to "a succeding file=volume" ( with nr. "l + 1" ) # of file=volume nr. "l" eg. with tape_asf ... or tape_eom . # * this file=volume nr. "l + 1" has a "Size" of the free tape space; # but actually it is emtpy, so its size should be 0 ... # * the "RealSize" of this file=volume nr. "l + 1" is an empty string. # * so adjust the "Size" according to the "RealSize" : if [ -z "$RealSize0x0A29" ]; then Size0x0A29=0 fi let "Size0x0A29 = Size0x0A29 * 1024" # blocks > bytes . echo "$Size0x0A29" } tape_space() # $1 in { b,... } : unit, $2: device. { local Result0x0A29 Space0x0A29 # must not use raw device here ! Space0x0A29=$(ftmt -f $DeviceN_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 \ --long-numbers getsize) Result0x0A29=$? if [ ! "$Result0x0A29" = "0" ]; then return $Result0x0A29; fi # chose correct line: # delete unwanted columns: # remove leading spaces: Space0x0A29=$(echo "$Space0x0A29" \ | grep "total bytes left" \ | colrm 34 | colrm 1 22 \ | sed 's/ *//') # format according to unit: case "$1" in b) let "Space0x0A29 = $Space0x0A29 * 1024" ;; K) # in 1024 byte units; it's already ok. ;; kB) # in 1000 byte units; we want to grant enough space, so round # 999 bytes down to 0 kB : let "Space0x0A29 = $Space0x0A29 * 1024 / 1000" ;; M) # in 1024 * 1024 byte units; we want to grant enough space, # so round (1024 * 1024 - 1) bytes down to 0 M : let "Space0x0A29 = $Space0x0A29 / 1024" ;; MB) # in 1,000,000 byte units; we want to grant enough space, # so round (1,000,000 - 1) bytes down to 0 MB : let "Space0x0A29 = $Space0x0A29 * 1024 / 1000000" ;; *) echo $"Usage: $0 --> tape_SPACE {???????}" return 1 esac echo $Space0x0A29 return } tape_statistics() # $1: device. { cat /proc/ftape return } tape_status() # $1: device. { ftmt -f $DeviceN_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 status return } tape_validHeaderQ() # validHeader? # $1: device. # * print # 0 to stdout if tape contains a valid header, # 1 to stdout else. { tape_badSectors $Device0x0A29 N > /dev/null 2>&1 # just simple: ...badSectors returns 0 if a valid header exists, # 1 if it is not able to read the header. if [ $? = "0" ]; then echo 0 else echo 1 fi return } tape_verify() # $1: device. # # * statistics do not correlate with bad sectors, so do not save it. # * according to tape_format120 1*), the old header is discarded anyway. # { local QDiscardHeader0x0A29 # ?DiscardHeader . /etc/tape/qic80/120MBV # avoid error with invalid header when trying to read the old header- # segment: echo " check '$1' for a valid header." if [ $(tape_validHeaderQ $1) = "0" ]; then QDiscardHeader0x0A29="" # valid header: keep it. else QDiscardHeader0x0A29="--discard-header" # invalid header: discard it. fi ftformat -f $DeviceRAW_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 \ $verify_parameters_CB5853FF_382E_11DA_BABF_0000C00A45A9 \ --mode=force --verify-only $QDiscardHeader0x0A29 # old: --verify-only=erase-bad-sector-map \ # test: # --verify-only=dont-write-header-segments --print-header > logXXX # --verify-only return } tape_vtblModify() # $1: device, $2: name, $3, $4: date. # * modify the last entry of the volume-table. # * if $3... are not specified, modify to current date. { local Device0x0A29 Name0x0A29 NumArguments0x0A29 Device0x0A29=$1; Name0x0A29=$2; NumArguments0x0A29=$# shift 2 if [ "$NumArguments0x0A29" = "2" ]; then vtblc -f $DeviceNRAW_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 \ --modify=label=$Name0x0A29 --modify=date return else vtblc -f $DeviceNRAW_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 \ --modify=label=$Name0x0A29 --modify=date="$*" return fi } fi # end of script # parameter handling: # ------------------ case "$1" in N) echo $DeviceN_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 ;; NRAW) echo $DeviceNRAW_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 ;; R) echo $DeviceR_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 ;; RAW) echo $DeviceRAW_0xCB5853FF_382E_11DA_BABF_0000C00A45A9 ;; SCRIPT) ;; *) echo "Usage: $0 {N| NRAW| R| RAW| SCRIPT}" echo " N: print non-rewinding device-name." echo " NRAW: print non-rewinding raw device-name." echo " R: print rewinding device-name." echo " RAW: print rewinding raw device-name." echo " SCRIPT: invoke it as script." exit 1 esac