| Home | Site Map | | ||
| CUBISTCODE | ||
|
Linux Disk Editor
#!/bin/sh
#++++++++++++++++++++++++++++++++++++++++++++++++++++#
# #
# MC_HxEd V 0.0.1-1 #
# #
# Copyright (C) 2008 CMDR 08-11-11(18) #
# #
# Hexadecimal Editor for Boot Records #
# with "Xdialog" treeview menu, #
# intended as Tool for "GpartedLive" #
# #
#++++++++++++++++++++++++++++++++++++++++++++++++++++#
# #
# W A R N I N G : #
# THIS SCRIPT MAY SEVERELY DAMAGE YOUR SYSTEM, IF #
# YOU ARE NOT QUITE SURE ABOUT THE CONSEQUENCES, #
# YOUR ACTIONS MAY HAVE. IN DOUBT, DO N O T APPLY #
# ANY CHANGES ! ASK FOR PROFESSIONAL SUPPORT. #
# #
#++++++++++++++++++++++++++++++++++++++++++++++++++++#
#
# You can get support from "GParted" Forum:
# http://gparted-forum.surf4.info/
#
# Report bugs to :
# http://bugzilla.gnome.org/simple-bug-guide.cgi?product=gparted
#
#
# LL II CCCC EEEE NN N CCCC EEEE
# LL II C E N N N C E
# LL II C EEE N N N C EEE
# LL II C E N N N C E
# LLLLL II CCCC EEEE N NN CCCC EEEE
#
# ========================================
#
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# This program is free software; you can redistribute
# it and/or modify it under the terms of the GNU
# General Public License as published by the Free Soft-
# ware Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope, that it will
# be useful, but WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General
# Public License along with this program; if not, write
# to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111 USA.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
clear
#***** Check Resources *****
Dlg="Xdialog"
tm="mlterm"
xm="xmessage"
f1="/root/f1"
f2="/root/f2"
mc -V >/dev/null 2>&1
[ $? != 0 ] && echo "Midnight Commander (/usr/bin/mc)" > ${f2}
${tm} --version > /dev/null
[ $? != 1 ] && echo "${tm} (/usr/bin/${tm})" >> ${f2}
${xm} > /dev/null 2>&1
[ $? != 1 ] && echo "${xm} (/usr/bin/${xm})" >> ${f2}
${Dlg} -v > /dev/null 2>&1
[ $? != 0 ] && echo "${Dlg} (/usr/bin/${Dlg})" >> ${f2}
if [ -e ${f2} ]
then echo "This script needs" > ${f1}
cat ${f2} >> ${f1}
echo "for proper function. Script aborted." >> ${f1}
echo >> ${f1}
echo "Hit any key ..." >> ${f1}
clear
cat ${f1}
for x in ${f1} ${f2}; do
rm $x
done
read -n 1
clear
exit
fi
#***** Common Variables *****
ml=""
p1=$0
#Mountpoint for stick
bpth="/mnt/usb"
#Storage folder
bup="${bpth}/BootRec"
prog="MC_HxEd"
vers="0.0.1-1"
nohelp=0
ctr=1
s_cut=""
s_rest=""
#Device pattern for USB stick (always 1st partition),
#multi-partitioned sticks allowed.
ptrn="/dev/sd?1"
nmnted=0
#Progress bar 100% value
rds=32
#Xdialog variables
item=""
sz=""
unit=""
smp=""
fsid=""
extdflag=0
extddrv=""
pxtstart=""
lbl=""
fxctr=0
remctr=0
#DriveInfo variables
prog1="DriveInfo"
pth=""
dvc=""
pstrt=""
pstrt1=""
pend=""
pend1=""
psize=""
psize1=""
ctr2=0
cyl=""
head=""
sec=""
did=""
cyl1=""
head1=""
sec1=""
res=""
blpc=""
bypc=""
fs=""
fsn=""
fsid=""
fsall=""
bf=""
fle="/root/drvs.dat"
fixctr1=0
remctr1=0
lbl0=""
maxblk=0
#********** End variables *********************
#**************** Subroutines ******************
#***********************************************
#************* Help / Info *************
help()
{
#Show Help text
#Parameters : $1 (qwzx=hit any key; wqxz=hit x)
#Input : $tm=Terminal name; $p1=complete path to this program
#Output : Info text
${tm} -s=false -b "lightyellow" -9 "lightyellow" -0 "lightyellow" -f "black" -g 65x32+0+80 -title "${prog} Hexadecimal Editor Version ${vers}" -e $p1 $1
echo > /tmp/xxx
}
usage()
{
#Create Info text with variable end, waiting for key stroke
#Parameters : $1 ( qwzx=hit any key; wqxz=hit key [x] )
#Input : $prog=Program name; $vers=Version
#Output : $ml=formatted Info text; file "/tmp/xxx" as exit flag
echo "$$" > /tmp/info.tmp
m1=${m1}" Usage (e.g. /dev/sda /dev/sda1):"$'\n'
m1=${m1}" ${prog} \"Xdialog\"-Treeview"$'\n'
m1=${m1}" ${prog} -[-]i[nfo] Create DriveInfo file"$'\n'
m1=${m1}" ${prog} [/dev/]sda Show MBR in HexViewer"$'\n'
m1=${m1}" ${prog} [/dev/]sda1 Show PBR in HexViewer"$'\n'
m1=${m1}" (= 1st primary partition)"$'\n'
m1=${m1}" ${prog} [path/]sda1.PBR Show stored PBR in Viewer"$'\n'
m1=${m1}" ${prog} -[-]l[oc]=sda Show selected Block on sda"$'\n'
m1=${m1}" ${prog} -[-]d[id]=sda Change Windows Drive ID"$'\n'
m1=${m1}" ${prog} -[-]nohelp Suppress help (1st arg.!)"$'\n'
m1=${m1}" ${prog} -[-]h[elp] Show this information"$'\n\n'
m1=${m1}" Console:"$'\n'
m1=${m1}" [F5] Goto Byte (e.g 0x1b8 = Drive ID in MBR)"$'\n'
m1=${m1}" [F2] Open for Editing"$'\n'
m1=${m1}" [F6] Save changes to given file"$'\n'
m1=${m1}" [TAB] Toggle active cursor (ASCII<>HEX)"$'\n\n'
m1=${m1}" Interesting addresses on MBR:"$'\n'
m1=${m1}" 0x1b8 (4 Bytes) Drive ID (important for Windows)"$'\n'
m1=${m1}" 0x1be (16 Bytes) Table of 1st primary partition"$'\n'
m1=${m1}" (Values : 0x1be=Bootflag; 0x80/0x00=active/inactive"$'\n'
m1=${m1}" 0x1c2=Filesystem ID)"$'\n'
m1=${m1}" 0x1ce (16 Bytes); 0x1de (16 Bytes); 0x1ee (16 Bytes)"$'\n'
m1=${m1}" (Tables of 2nd to 4th partition, if used)"$'\n\n'
m1=${m1}" Preconfigured backup folder : ${bup}"$'\n'
m1=${m1}" Filename : e.g. sda.MBR / sda1.PBR / sda5.XBR"$'\n'
m1=${m1}" (File extensions are linked to HexViewer !)"$'\n\n'
if [ "${1}" != "" ]
then [ "${1}" = "qwzx" ] && m1=${m1}" --> Hit any key to continue"$'\n'
[ "${1}" = "wqxz" ] && m1=${m1}" --> Exit with [x]"$'\n'
clear
echo -n "${m1}"
if [ "${1}" = "qwzx" ]
then read -s -n 1
fi
if [ "${1}" = "wqxz" ]
then rpl=""
while [ "${rpl}" != "x" ]; do
read -n 1 rpl
[ "${rpl}" = "X" ] && break
done
fi
rm /tmp/info.tmp
fi
echo > /tmp/xxx
}
show_fst()
{
#Tricky display and backup of "fdisk"-FileSystemList
#Parameter : $1=Device
#Output : xmessage or fle
fsst="/home/fsID_table"
btn="Store as temporary file"
if [ -d ${bup} ]
then fsst="${bup}/fsID_table"
btn="Backup as file"
fi
`echo "l"$'\n'"q" | fdisk /dev/${1} | sed -e 's/Command (m for help)://g' | ${xm} -center -geometry 730x430 -title "Known File system IDs" -buttons "${btn}":2,Close:1 -file - > /dev/null 2>&1`
[ "$?" = "2" ] && `echo "l"$'\n'"q" | fdisk /dev/${1} | sed -e 's/Command (m for help)://g' > ${fsst}`
clear
}
#********* Mounting Wizard *************
stick_alive()
{
#Detecting sticks and irregular conditions (e.g. removed mounted sticks)
#Parameter : none
#Input : $ptrn=Device pattern; $bpth=Mountpoint backup device
#Output : $nmounted (0=no mounted devices with pattern $ptrn found;
# 1-99=number of available unmounted devices with fitting pattern;
# 100=device already mounted for backup
mnted1=`mount | grep ${bpth} | awk '{print $1}'`
[ "${mnted1}" != "" ] && mnted2=`echo ${ptrn} | grep ${mnted1} | awk '{printf $1}'`
#Stick removed without unmounting it
if [ "${mnted2}" = "" ]
then if [ "${mnted1}" != "" ]
then mtrue=`mount | grep $bpth | awk '{printf $3}'`
[ "$mtrue" != "" ] && umount $bpth > /dev/null 2>&1
fi
nmnted=`echo ${ptrn} | wc -w`
#Correction for no stick
[ "`echo ${ptrn}`" = "${ptrn}" ] && nmnted=0
mnted1=`mount | grep ${bpth} | awk '{print $1}'`
else nmnted=100
fi
}
mount_stick()
{
#Mounting routine detects and mounts first sd?1 device, if yet unmounted.
#Parameter : none
#Input : $nmnted=(0=no available unmounted devices; 1-99=number of available devices;
# 100=device already mounted)
# $Dlg=Xdialog; $ctr1=counter; $rds=100% value for progress bar,
# $ptrn=Device pattern; $bpth=Mountpoint backup device
#Output : periods for progress bar
#Actions : Seeking and mounting fitting device; error messages
stick_alive
[ "$nmnted" = "100" ] && return
mtrue=
echo -n .
while [ : ]; do
declare -i ctr1=2
while [ : ]; do
ctr1=$(( $ctr1 + 1 ))
echo -n .
if [ $ctr1 -eq $(( $rds + 1 )) ]
then echo -n ${rds}
fi
if [ "`echo ${ptrn}`" != "${ptrn}" ]
then mnted=`echo ${ptrn}`
for m in ${mnted}; do
if [ "${m}" != "" ]
then if [ `mount | grep ${m} | wc -l` = 0 ]
then echo -n .
pd=`echo ${m} | awk -F"/" '{printf $3}' | cut -c -3`
[ "`cat /sys/block/${pd}/removable`" = "0" ] && continue
declare -i cnt=0
[ ! -d ${bpth} ] && mkdir ${bpth}
mtrue=""
while [ "${mtrue}" = "" ]; do
mount ${m} ${bpth} > /dev/null 2>&1
sleep 1
echo -n .
cnt=$(( $cnt + 1 ))
mtrue=`mount | grep ${bpth} | awk '{printf $3}'`
if [ "${mtrue}" = "" -a $cnt = 10 ]
then echo $(( $rds +1 ))
${Dlg} --title "Mount Stick" --msgbox "\n Failure : USB Stick could not be mounted. \n" 0 0
echo > /tmp/xxx
fi
done
${Dlg} --timeout 4 --title "Mount Stick" --msgbox "\n USB Stick \"${m}\" successfully mounted on \"${mtrue}\". \n" 0 0
stick_alive
echo > /tmp/success
return
fi
fi
done
fi
sleep 1
echo -n .
done
done
}
seekstick()
{
#Loop for seeking USB Stick as often as user wants
#Parameters : none
#Input : $Dlg=Xdialog; $rds=100% value for progress bar
#Output : return (0=end: 255=reset and continue)
#Progress Bar !
mount_stick | `${Dlg} --title "Mount Stick" --progress "\n Waiting for USB stick ... \n" 0 0 ${rds}`
#Communication via file; variable not possible (child process)!
if [ -e /tmp/success ]
then rm /tmp/success
return 0
fi
${Dlg} --title "Mount Stick" --backtitle "Mounting Wizard" --yesno "No mountable USB stick detected.\
\n\nTry it again ?\n" 0 0
[ $? != 0 ] && return 0
#Reset
ctr1=2
rds=32
return 255
}
#******************* HexViewer ******************
start_hex()
{
#Prepares HexEditor's extension link file to start hex view
#Parameters : none
#Output : new "mc.ext" with linked .MBR, .PBR, .XPR, .BLK and
# .JP(E)G" extension
#Note: You can confirm highlighted file and thus starting
# the linked program (Sorry, mouse is not working !).
# This function gets installed with the first use.
#MBR PBR XBR BLK
mcx="/etc/mc/mc"
mcext=${mcx}".ext"
#Configuration already run ?
[ `cat $mcext | grep -e '# MBR' | wc -w` != 0 ] && return 2
mcaa="${mcx}aa"
mcab="${mcx}ab"
mcadd="${mcx}add"
splt=`cat $mcext | grep -b -e '### Default ###' | awk -F ':' '{printf $1}'`
split -b $splt $mcext $mcx
echo "# MBR / PBR / XBR / BLK" > $mcadd
echo "regex/\.(MBR|PBR|XBR|BLK)$">> $mcadd
echo " Open=%view{hex}" >> $mcadd
echo " View=%view{hex}"$'\n' >> $mcadd
cat $mcadd >> $mcaa
sleep 0.5
cat $mcab >> $mcaa
sleep 0.5
sudo cp $mcaa $mcext
sleep 0.5
#JP(E)G for screenshots !
rxp1="type/\^JPEG"
lrxp=`echo "$rxp1" | wc -c`
lrxp=$(( $lrxp - 1 ))
splt=`cat $mcext | grep -b -e $rxp1 | awk -F ':' '{printf $1}'`
splt=$(( $splt + $lrxp ))
split -b $splt $mcext $mcx
echo " Open=feh %d/%f" > $mcadd
echo " View=feh %d/%f"$'\n' >> $mcadd
cat $mcadd >> $mcaa
sleep 0.5
cat $mcaa > $mcadd
sleep 0.5
#rxp2 may change in the future !
#Last part of the splitted file
rxp2="type/\^PC"
splt=`cat $mcext | grep -b -e $rxp2 | awk -F ':' '{printf $1}'`
split -b $splt $mcext $mcx
cat $mcab >> $mcadd
sleep 0.5
sudo cp $mcadd $mcext
sleep 0.5
for y in ${mcaa} ${mcab} ${mcadd}; do
[ -e $y ] && rm $y
done
}
show()
{
#Start "Midnight Commander", show Boot record and detect changes.
#Parameters : $1=Boot record to show
# $2=Backuped Boot record
#Input : $prog=Program name; $btr=Temporarily stored boot record;
# $bup=Backup folder; $tm=Terminal name; $dev=Device to work on;
# $fext=File extension; bpth=Mountpoint backup device
# Action : Write changed Boot record to device, if backup exists, abortable.
#Output : Dialog and messages
if [ "${1}" != "" -a "${2}" != "" ]
then shw=$1
bp=$2
s_loop "." ${bp}
fext=${s_cut}
s_loop "/" ${s_rest}
dev=${s_cut}
s_loop "." ${shw}
fext3=${s_cut}
else shw="$btr"
bp="${bup}/${dev}.${fext}"
fi
start_hex
${tm} -s=false -title ${prog} -g 80x24+200+200 -e /usr/bin/mc -v $shw
if [ "${fext3}" = "BLK" ]
then ${Dlg} --backtitle "H I N T" --title "Block Viewer" \
--msgbox "Block files (.BLK) are not stored permanently.\n But you can do it manually with Midnight Commander. \n" 0 0
return
fi
if [ "`echo ${bpth}/*`" != "${bpth}/*" ]
then if [ -e ${shw} -a -e ${bp} ]
then diff ${shw} ${bp} > /dev/null 2>&1
if [ $? != 0 ]
then ${Dlg} --backtitle "${fext} HAS BEEN CHANGED !" --title "Overwrite ${fext} on ${dev}" --defaultno \
--yesno " Do you really want to overwrite\n ${fext} from \"/dev/${dev}\" ?" 0 0
[ "$?" = "0" ] && dd if=${shw} of=/dev/${dev} bs=512 count=1 > /dev/null 2>&1
return
fi
else ${Dlg} --backtitle "H I N T" --title "Overwrite ${fext} on ${dev}" \
--msgbox "Boot record was not stored !\n\nOverwriting stays disabled,\n unless you agree to store a backup ! \n" 0 0
fi
else ${Dlg} --backtitle "H I N T" --title "Overwrite ${fext} on ${dev}" \
--msgbox "Use the built-in Mounting Wizard,\n if you want to store Boot Record files permanently. \n\nAs long as there is no Backup possible,\noverwriting is disabled !" 0 0
fi
}
cpy()
{
#Copy Boot record to USB stick
#Parameters : none
#Input : $bup=Backup folder
# $dev=device
# $fext=file extension of backup file
# $btr=temporarily stored boot record
#Action : copy
if [ -e ${bup}/${dev}.${fext} ]
then ${Dlg} --title "$prog" --backtitle "\nOverwrite existing Backup file" --defaultno --yesno " Do you want to overwrite file \n"\
"${bup}/${dev}.${fext} ?\n\n" 0 0
[ $? != 0 ] && return
sudo rm ${bup}/${dev}.${fext}
sleep 2
else if [ -d ${bup} ]
then ${Dlg} --title "$prog" --backtitle "\nStore Backup file" --defaultno --yesno " Do you want to permanetly store file \n"\
"${dev}.${fext} on ${bup} ?\n\n" 0 0
[ $? != 0 ] && return
fi
fi
[ -d $bup ] && sudo cp ${btr} ${bup}
}
#********* Xdialog "treeview" ***************
create_tree()
{
#Create treeview
#Parameter: none
#Output : $item = everything that appears in the treeview of "Xdialog"
item=""
mdepth=1
fxctr=0
remctr=0
drvs="`fdisk -l | grep -e '^/dev' | awk '{printf $1" "}' | sed -e 's/\/dev\///g'`"
ctr2=0
for d in ${drvs}; do
#Fixed/Removable Disks
if [ "$smp" != "`echo "$d" | cut -c -3`" ]
then smp="`echo "$d" | cut -c -3`"
extdflag=0; extddrv=""
if [ "`cat /sys/block/$smp/removable`" = "0" ]
then fxctr=$(( $fxctr + 1))
item="${item}-info Fixed_Disk_${fxctr} off 2 "
mdepth=3
ctr2=$(( remctr + $fxctr ))
else remctr=$(( remctr +1 ))
item="${item}-info Removable_Disk_${remctr} off 1 "
mdepth=2
ctr2=$(( $fxctr + $remctr ))
fi
#Well, ... handling of the "treeview" seems to be very special.
#... and Regular Expressions and me, we are not just friends !
#Xdialog doesn't really like spaces.
dmodel="`cat /sys/block/$smp/device/model \
| sed -r -e 's/\s+/\_/g' | sed -e 's/\_$//g'`"
disk_size $smp
item="${item}$smp $smp($sz) off $mdepth "
mdepth=$(( $mdepth + 1 ))
item="${item}0 Model:$dmodel off $mdepth "
mdepth=$(( $mdepth + 1 ))
ctr2=$(( $ctr2 - 1 ))
drv_data
parm $did
did="$res"
parm $cyl
cyl="$res"
parm $head
head="$res"
parm $sec
sec="$res"
if [ "$bf" = "*" ]
then item="${item}-d=${smp} (Set)_DriveID:${did} off $mdepth "
else item="${item}0 DriveID:${did} off $mdepth "
fi
item="${item}0 Cylinders:${cyl} off $mdepth "
item="${item}0 Heads:${head} off $mdepth "
item="${item}0 Sectors:${sec} off $mdepth "
maxblk=$(( $cyl * $head * $sec ))
item="${item}0 Blocks:${maxblk} off $mdepth "
item="${item}-loc=${smp} Show_Block(s) off $mdepth "
mdepth=3
disk_size $d
item="${item}$d $d($sz) off $mdepth "
pstart $d
mdepth=4
fsi="-f=${smp} "
item="${item}${fsi}Filesystem:${fsinfo} off $mdepth "
mdepth=3
continue
fi
disk_size $d
item="${item}$d $d($sz) off $mdepth "
pstart $d
mdepth=$(( $mdepth + 1 ))
[ "$extdflag" = "1" -a "$extddrv" != "$d" ] && item="${item}#${d} Ext.PBR off $mdepth "
fsi="-f=`echo "${d}" | cut -c -3` "
item="${item}${fsi}Filesystem:${fsinfo} off $mdepth "
mdepth=$(( $mdepth - 1 ))
done
}
disk_size()
{
#Calculates Disk size of primary and extended partitions
#Parameters : $1 = Device name
#Output : $sz = $lbl_$size$unit_bf_mf
# $lbl = Volume name
# $size = Volume size
# $unit = Size unit
# $bf = bootflag; $mf = mountflag
ds1="$1"
sz=""
#Physical or Logical Drive ?
phys="`echo "$ds1" | cut -c -3`"
#Extended Drive ?
fsid="`fdisk -l -u | grep -e '^/dev/'${1} | awk '{printf $5}'`"
if [ "$fsid" = "f" ]
then pstrt=`cat /sys/block/$phys/$ds1/start`
pend="`fdisk -l -u | grep -e '^/dev/'${ds1} | awk '{printf $3}'`"
sz=$(( $pend - $pstrt +1 ))
disk_unit
sz="${sz}${unit}_Ext'd"
extdflag=1
extddrv="$ds1"
return
fi
if [ "$ds1" = "$phys" ]
then sz=`cat /sys/block/$ds1/size`
else sz=`cat /sys/block/$phys/$ds1/size`
fi
#Bootflag (*) ?
bf="`fdisk -l | grep -e '^/dev/'$ds1 | awk '{printf $2}' | cut -c -1`"
[ "$bf" != "*" ] && bf=""
#Mounted (<>) ?
if [ "`echo "$ds1" | grep -e [0-9]`" != "" ]
then mfa="`mount | sed -e 's/\/dev\///g' | grep -e $ds1 | awk '{printf $1" "}'`"
if [ "$mfa" = "$ds1 " ]
then mf="<>"
else mf=""
fi
fi
mfa=""
disk_unit
disk_lbl $ds1
sz="${lbl}${sz}${unit}$bf$mf"
}
disk_unit()
{
#Calculates the disk size unit
#Parameters : $sz=Disk size in blocks
#Output : $unit= disk size unit (raw)
unit=""
unit0="KB MB GB TB PB"
#Disk size in Bytes
sz=$(( $sz * 512 ))
while [ : ]; do
ct=`echo "$sz" | wc -c`
[ $ct -le 5 ] && break
unit=`echo "$unit0" | awk '{printf $1}'`
unit0=`echo "$unit0" | cut -c 4-`
ct=$(( $ct - 4 ))
#Very simple division by 1,000
sz=`echo "$sz" | cut -c -$ct`
done
}
disk_lbl()
{
#Seek Volume name (Disk label)
#Parameter: $1=device name
#Output: $lbl=volume name
lbl=""
lbl0=""
dlph="/dev/disk/by-label"
olddir=$PWD
#Cuts the path off !
cd $dlph
dlbls=`echo *`
for dl in $dlbls; do
devl=`dir -l $dlph/$dl | tail -c 5 `
if [ "$devl" = "$1" ]
then lbl0="${dl}"
lbl="${lbl0}_"
break
fi
done
cd $olddir
}
extd_view()
{
#Calculates address of Extended Drive Record
#Parameter : $1=Device name of extended logical drive
#Output : $pxtstart = starting block
lw="$1"
lwp="`echo "$1" | cut -c -3`"
pxtstart=`cat /sys/block/$lwp/$lw/start `
pxtstart="$(( $pxtstart - 63 ))"
}
show_block()
{
#Show selected block(s) / cylinder(s); hexadecimal input allowed;
#only dialog - no parameter steering !
#Parameter : none
#Input : Xdialog
#Output : HexViewer; (non-permanent) file
$Dlg --icon "/usr/share/pixmaps/gparted-live/gparted.xpm" --title ${prog}\
--backtitle "BLock Viewer\n- Block/Cylinder input (Drive \"${1}\") -"\
--inputbox "Type
Tags: linux, scripts
|
| Home | Site Map | |