mirror of
https://github.com/Llewellynvdm/Tomb.git
synced 2024-11-05 04:47:56 +00:00
Merge pull request #18 from boyska/only_optparsing
New CLI option parsing supports contextual options following commands. ZSH functions are used to parse options. Further testing will follow.
This commit is contained in:
commit
21be9e204e
267
src/tomb
267
src/tomb
@ -24,20 +24,28 @@ VERSION=1.1
|
||||
DATE=May/2011
|
||||
TOMBEXEC=$0
|
||||
TOMBOPENEXEC="tomb-open"
|
||||
typeset -a OLDARGS
|
||||
for arg in ${argv}; do OLDARGS+=($arg); done
|
||||
STEGHIDE=1
|
||||
MOUNTOPTS="rw,noatime,nodev"
|
||||
|
||||
#declare global variables
|
||||
QUIET=0
|
||||
DEBUG=0
|
||||
typeset -A global_opts
|
||||
typeset -A opts
|
||||
|
||||
# PATH=/usr/bin:/usr/sbin:/bin:/sbin
|
||||
|
||||
autoload colors; colors
|
||||
|
||||
# standard output message routines
|
||||
# it's always useful to wrap them, in case we change behaviour later
|
||||
notice() { if ! [ $QUIET ]; then print "$fg_bold[green][*]$fg_no_bold[white] $1" >&2; fi }
|
||||
error() { if ! [ $QUIET ]; then print "$fg[red][!]$fg[white] $1" >&2; fi }
|
||||
func() { if [ $DEBUG ]; then print "$fg[blue][D]$fg[white] $1" >&2; fi }
|
||||
notice() { if [[ $QUIET == 0 ]]; then print "$fg_bold[green][*]$fg_no_bold[white] $1" >&2; fi }
|
||||
error() { if [[ $QUIET == 0 ]]; then print "$fg[red][!]$fg[white] $1" >&2; fi }
|
||||
func() { if [[ $DEBUG == 1 ]]; then print "$fg[blue][D]$fg[white] $1" >&2; fi }
|
||||
act() {
|
||||
if ! [ $QUIET ]; then
|
||||
if [[ $QUIET == 0 ]]; then
|
||||
if [ "$1" = "-n" ]; then
|
||||
print -n "$fg_bold[white] . $fg_no_bold[white] $2" >&2;
|
||||
else
|
||||
@ -156,7 +164,7 @@ exec_as_user() {
|
||||
# escalate privileges
|
||||
check_priv() {
|
||||
if [ $UID != 0 ]; then
|
||||
func "Using sudo for root execution of 'tomb ${(f)ARGS}'"
|
||||
func "Using sudo for root execution of 'tomb ${(f)OLDARGS}'"
|
||||
# check if sudo has a timestamp active
|
||||
sudok=false
|
||||
sudo -n ${TOMBEXEC} 2> /dev/null
|
||||
@ -165,12 +173,12 @@ check_priv() {
|
||||
OPTION ttyname=$TTY
|
||||
OPTION lc-ctype=$LANG
|
||||
SETTITLE Super user privileges required
|
||||
SETDESC Sudo execution of Tomb ${ARGS[@]}
|
||||
SETDESC Sudo execution of Tomb ${OLDARGS[@]}
|
||||
SETPROMPT Insert your USER password:
|
||||
GETPIN
|
||||
EOF
|
||||
fi
|
||||
sudo "${TOMBEXEC}" ${(s: :)ARGS}
|
||||
sudo "${TOMBEXEC}" "${(@)OLDARGS}"
|
||||
exit $?
|
||||
fi # are we root already
|
||||
return 0
|
||||
@ -312,8 +320,8 @@ EOF
|
||||
|
||||
create_tomb() {
|
||||
if ! [ ${CMD2} ]; then
|
||||
error "no tomb name specified for creation"
|
||||
return 1
|
||||
error "no tomb name specified for creation"
|
||||
return 1
|
||||
fi
|
||||
|
||||
tombfile=`basename ${CMD2}`
|
||||
@ -321,6 +329,7 @@ create_tomb() {
|
||||
# make sure the file has a .tomb extension
|
||||
tombname=${tombfile%%\.*}
|
||||
tombfile=${tombname}.tomb
|
||||
tombsize=$opts[-s]
|
||||
|
||||
if [ -e ${tombdir}/${tombfile} ]; then
|
||||
error "tomb exists already. I'm not digging here:"
|
||||
@ -336,17 +345,11 @@ create_tomb() {
|
||||
|
||||
notice "Creating a new tomb in ${tombdir}/${tombfile}"
|
||||
|
||||
if [ -z $SIZE ]; then
|
||||
if [ $CMD3 ]; then
|
||||
tombsize=${CMD3}
|
||||
else
|
||||
act "No size specified, summoning the Tomb Undertaker to guide us in the creation."
|
||||
"$TOMBOPENEXEC" &
|
||||
wait $!
|
||||
return 0
|
||||
fi
|
||||
else
|
||||
tombsize=${SIZE}
|
||||
if [ -z $tombsize ]; then
|
||||
act "No size specified, summoning the Tomb Undertaker to guide us in the creation."
|
||||
"$TOMBOPENEXEC" &
|
||||
wait $!
|
||||
return 0
|
||||
fi
|
||||
|
||||
tombsize_4k=`expr $tombsize \* 1024 / 4`
|
||||
@ -480,38 +483,45 @@ create_tomb() {
|
||||
mount_tomb() {
|
||||
notice "Commanded to open tomb $CMD2"
|
||||
get_arg_tomb $CMD2
|
||||
local tombkey
|
||||
if option_is_set -k ; then
|
||||
tombkey=`option_value -k`
|
||||
else
|
||||
tombkey="${PARAM[1]}.key"
|
||||
fi
|
||||
echo the key used is $tombkey
|
||||
if [ $? != 0 ]; then
|
||||
error "operation aborted."
|
||||
return 1
|
||||
error "operation aborted."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! [ $CMD3 ]; then
|
||||
tombmount=/media/${tombfile}
|
||||
act "mountpoint not specified, using default: $tombmount"
|
||||
tombmount=/media/${tombfile}
|
||||
act "mountpoint not specified, using default: $tombmount"
|
||||
elif ! [ -x $CMD3 ]; then
|
||||
error "mountpoint $CMD3 doesn't exist, operation aborted."
|
||||
if [ -n "$usbkey_mount" ]; then
|
||||
umount $usbkey_mount
|
||||
rmdir $usbkey_mount
|
||||
unset usbkey_mount
|
||||
fi
|
||||
return 1
|
||||
error "mountpoint $CMD3 doesn't exist, operation aborted."
|
||||
if [ -n "$usbkey_mount" ]; then
|
||||
umount $usbkey_mount
|
||||
rmdir $usbkey_mount
|
||||
unset usbkey_mount
|
||||
fi
|
||||
return 1
|
||||
else
|
||||
tombmount=$CMD3
|
||||
tombmount=$CMD3
|
||||
fi
|
||||
|
||||
# check if its already open
|
||||
mount -l | grep "${tombname}.tomb.*\[$tombname\]$" 2>&1 > /dev/null
|
||||
if [ $? = 0 ]; then
|
||||
error "$tombname is already mounted on $tombmount"
|
||||
act "tomb list - show all tombs currently open"
|
||||
if [ -n "$usbkey_mount" ]; then
|
||||
umount $usbkey_mount
|
||||
rmdir $usbkey_mount
|
||||
unset usbkey_mount
|
||||
fi
|
||||
error "operation aborted."
|
||||
return 1
|
||||
error "$tombname is already mounted on $tombmount"
|
||||
act "tomb list - show all tombs currently open"
|
||||
if [ -n "$usbkey_mount" ]; then
|
||||
umount $usbkey_mount
|
||||
rmdir $usbkey_mount
|
||||
unset usbkey_mount
|
||||
fi
|
||||
error "operation aborted."
|
||||
return 1
|
||||
fi
|
||||
|
||||
notice "mounting $tombfile on mountpoint $tombmount"
|
||||
@ -522,18 +532,18 @@ mount_tomb() {
|
||||
|
||||
nstloop=`losetup -f`
|
||||
if [ $? = 255 ]; then
|
||||
error "too many tomb opened. Please close any of them to open another tomb"
|
||||
exit 1
|
||||
error "too many tomb opened. Please close any of them to open another tomb"
|
||||
exit 1
|
||||
fi
|
||||
losetup -f ${tombdir}/${tombfile}
|
||||
|
||||
act "check for a valid LUKS encrypted device"
|
||||
cryptsetup isLuks ${nstloop}
|
||||
if [ $? != 0 ]; then
|
||||
# is it a LUKS encrypted nest? see cryptsetup(1)
|
||||
error "$tombfile is not a valid Luks encrypted storage file"
|
||||
$norm || rmdir $tombmount 2>/dev/null
|
||||
return 1
|
||||
# is it a LUKS encrypted nest? see cryptsetup(1)
|
||||
error "$tombfile is not a valid Luks encrypted storage file"
|
||||
$norm || rmdir $tombmount 2>/dev/null
|
||||
return 1
|
||||
fi
|
||||
|
||||
# save date of mount in minutes since 1970
|
||||
@ -562,10 +572,10 @@ mount_tomb() {
|
||||
done
|
||||
|
||||
if ! [ -r /dev/mapper/${mapper} ]; then
|
||||
error "failure mounting the encrypted file"
|
||||
losetup -d ${nstloop}
|
||||
$norm || rmdir ${tombmount} 2>/dev/null
|
||||
return 1
|
||||
error "failure mounting the encrypted file"
|
||||
losetup -d ${nstloop}
|
||||
$norm || rmdir ${tombmount} 2>/dev/null
|
||||
return 1
|
||||
fi
|
||||
|
||||
act "encrypted storage filesystem check"
|
||||
@ -582,8 +592,8 @@ mount_tomb() {
|
||||
|
||||
notice "encrypted storage $tombfile succesfully mounted on $tombmount"
|
||||
if ! [ $NOBIND ]; then
|
||||
exec_safe_bind_hooks ${tombmount}
|
||||
exec_safe_post_hooks ${tombmount} open
|
||||
exec_safe_bind_hooks ${tombmount}
|
||||
exec_safe_post_hooks ${tombmount} open
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
@ -689,6 +699,9 @@ print "-----END PGP MESSAGE-----"
|
||||
}
|
||||
|
||||
exec_safe_bind_hooks() {
|
||||
if [[ -n ${(k)opts[-o]} ]]; then
|
||||
MOUNTOPTS=${opts[-o]}
|
||||
fi
|
||||
local MOUNTPOINT="${1}"
|
||||
local ME=${SUDO_USER:-$(whoami)}
|
||||
local HOME=$(grep $ME /etc/passwd | sed "s/^${ME}:.*:.*:.*:.*:\([\/a-z]*\):.*$/\1/" 2>/dev/null)
|
||||
@ -1061,53 +1074,121 @@ EOF
|
||||
act "Tomb is now installed."
|
||||
}
|
||||
|
||||
main () {
|
||||
echo $@ | grep '\-D' 2>&1 > /dev/null
|
||||
# ?????
|
||||
if [ $? = 0 ]; then
|
||||
option_is_set() {
|
||||
#First argument, the option (something like "-s")
|
||||
#Second (optional) argument: if it's "out", command will print it out 'set'/'unset'
|
||||
# This is useful for if conditions
|
||||
#Return 0 if is set, 1 otherwise
|
||||
[[ -n ${(k)opts[$1]} ]];
|
||||
r=$?
|
||||
if [[ $2 == out ]]; then
|
||||
if [[ $r == 0 ]]; then
|
||||
echo 'set'
|
||||
else
|
||||
echo 'unset'
|
||||
fi
|
||||
fi
|
||||
return $r;
|
||||
}
|
||||
option_value() {
|
||||
#First argument, the option (something like "-s")
|
||||
echo ${opts[$1]}
|
||||
}
|
||||
|
||||
ARGS=$@[@]
|
||||
|
||||
OPTS=`getopt -o hvqDs:k:no: -n 'tomb' -- "$@"`
|
||||
while true; do
|
||||
case "$1" in
|
||||
-h)
|
||||
usage
|
||||
exit 0 ;;
|
||||
-v)
|
||||
notice "Tomb - simple commandline tool for encrypted storage"
|
||||
act "version $VERSION ($DATE) by Jaromil @ dyne.org"
|
||||
# print out the GPL license in this file
|
||||
act ""
|
||||
cat ${TOMBEXEC} | awk 'BEGIN { license=0 } /^# This source/ { license=1 } { if(license==1) print " " $0 }
|
||||
/MA 02139, USA.$/ { license=0 }'
|
||||
act ""
|
||||
exit 0 ;;
|
||||
-q) QUIET=1; shift 1 ;;
|
||||
-D)
|
||||
print "[D] Tomb invoked with args \"${(f)@}\" "
|
||||
print "[D] running on `date`"
|
||||
DEBUG=1; shift 1 ;;
|
||||
-s) SIZE=$2; shift 2 ;;
|
||||
-k) KEY=$2; shift 2 ;;
|
||||
-n) NOBIND=1; shift 1 ;;
|
||||
-o) MOUNTOPTS=$2; shift 2;;
|
||||
--) shift; break ;;
|
||||
*) CMD=$1;
|
||||
FILE=$2; MOUNT=$3; # compat with old args
|
||||
CMD2=${2}; CMD3=${3}; break ;;
|
||||
esac
|
||||
main() {
|
||||
local -A subcommands_opts
|
||||
### Options configuration
|
||||
#Hi, dear developer! Are you trying to add a new subcommand, or to add some options?
|
||||
#Well, keep in mind that:
|
||||
# 1. An option CAN'T have differente meanings/behaviour in different subcommands.
|
||||
# For example, "-s" means "size" and accept an argument. If you are tempted to add
|
||||
# an option "-s" (that means, for example "silent", and doesn't accept an argument)
|
||||
# DON'T DO IT!
|
||||
# There are two reasons for that:
|
||||
# I. usability; user expect that "-s" is "size
|
||||
# II. Option parsing WILL EXPLODE if you do this kind of bad things
|
||||
# (it will say "option defined more than once, and he's right)
|
||||
main_opts=(q -quiet=q D -debug=D h -help=h v -verbose=v)
|
||||
subcommands_opts[open]="n -nohook=n k: -key=k o: -mount-options=o"
|
||||
subcommands_opts[mount]=${subcommands_opts[open]}
|
||||
subcommands_opts[create]="s: -size=s"
|
||||
subcommands_opts[close]=""
|
||||
subcommands_opts[help]=""
|
||||
subcommands_opts[slam]=""
|
||||
subcommands_opts[list]=""
|
||||
subcommands_opts[help]=""
|
||||
subcommands_opts[bury]=""
|
||||
subcommands_opts[exhume]=""
|
||||
subcommands_opts[decompose]=""
|
||||
subcommands_opts[recompose]=""
|
||||
subcommands_opts[install]=""
|
||||
subcommands_opts[askpass]=""
|
||||
subcommands_opts[mktemp]=""
|
||||
### Detect subcommand
|
||||
local -aU every_opts #every_opts behave like a set; that is, an array with unique elements
|
||||
for optspec in $subcommands_opts$main_opts; do
|
||||
for opt in ${=optspec}; do
|
||||
every_opts+=${opt}
|
||||
done
|
||||
done
|
||||
|
||||
if ! [ $CMD ]; then
|
||||
error "first argument missing, use -h for help"
|
||||
exit 0
|
||||
local -a oldstar
|
||||
oldstar=($argv)
|
||||
zparseopts -M -E -D -Adiscardme ${every_opts}
|
||||
unset discardme
|
||||
subcommand=$1
|
||||
if [[ -z ${(k)subcommands_opts[$subcommand]} ]]; then #there's no such subcommand
|
||||
error "Subcommand '$subcommand' doesn't exist"
|
||||
exit 127
|
||||
fi
|
||||
argv=(${oldstar})
|
||||
unset oldstar
|
||||
|
||||
### Parsing global + command-specific options
|
||||
# zsh magic: ${=string} will split to multiple arguments when spaces occur
|
||||
set -A cmd_opts ${main_opts} ${=subcommands_opts[$subcommand]}
|
||||
if [[ -n $cmd_opts ]]; then #if there is no option, we don't need parsing
|
||||
zparseopts -M -E -D -Aopts ${cmd_opts}
|
||||
if [[ $? != 0 ]]; then
|
||||
error "Some error occurred during option processing. See \"tomb help\" for more info"
|
||||
exit 127
|
||||
fi
|
||||
fi
|
||||
#build PARAM (array of arguments) and check if there are unrecognized options
|
||||
ok=0
|
||||
PARAM=()
|
||||
for arg in $*; do
|
||||
if [[ $arg == '--' || $arg == '-' ]]; then
|
||||
ok=1
|
||||
continue #it shouldnt be appended to PARAM
|
||||
elif [[ $arg[1] == '-' ]]; then
|
||||
if [[ $ok == 0 ]]; then
|
||||
error "unrecognized option $arg"
|
||||
exit 127
|
||||
fi
|
||||
fi
|
||||
PARAM+=$arg
|
||||
done
|
||||
#first parameter actually is the subcommand: delete it and shift
|
||||
PARAM[1]=()
|
||||
shift
|
||||
### End parsing command-specific options
|
||||
|
||||
### Set global options (useless, but for code retro-compatibility)
|
||||
for opt in ${(k)global_opts}; do
|
||||
if [[ $opt == '-q' ]]; then
|
||||
QUIET=1
|
||||
elif [[ $opt == '-D' ]]; then
|
||||
DEBUG=1
|
||||
fi
|
||||
done
|
||||
|
||||
CMD=$subcommand
|
||||
CMD2=$PARAM[1]
|
||||
CMD3=$PARAM[2]
|
||||
|
||||
func "Tomb command: $CMD $CMD2 $CMD3"
|
||||
|
||||
case "$CMD" in
|
||||
case "$subcommand" in
|
||||
create) check_priv ; create_tomb ;;
|
||||
mount) check_priv ; mount_tomb ;;
|
||||
open) check_priv ; mount_tomb ;;
|
||||
|
@ -211,7 +211,7 @@ if [ $1 ]; then # is it a file?
|
||||
exit 1
|
||||
else
|
||||
|
||||
"${TOMBEXEC}" -k ${tombkey} mount ${tombdir}/${tombfile}
|
||||
"${TOMBEXEC}" mount -k ${tombkey} ${tombdir}/${tombfile}
|
||||
success=$?
|
||||
fi
|
||||
|
||||
@ -255,7 +255,7 @@ if [ "$1" != "wizard" ]; then
|
||||
if [ -z $DISPLAY ]; then
|
||||
error "tomb-open is a wrapper for the command 'tomb'"
|
||||
error "[!] type 'tomb-open wizard' if you want to be guided"
|
||||
"${TOMBEXEC}" -h
|
||||
"${TOMBEXEC}" help
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
@ -338,7 +338,7 @@ cat <<EOF
|
||||
EOF
|
||||
|
||||
tombfile=${tombname}.tomb
|
||||
"${TOMBEXEC}" -s $tombsize create ${tombfile}
|
||||
"${TOMBEXEC}" create -s $tombsize ${tombfile}
|
||||
|
||||
if [ $? != 0 ]; then
|
||||
error "An error occurred creating tomb, operation aborted."
|
||||
@ -368,7 +368,7 @@ if [ $? = 0 ]; then
|
||||
notice "${tombname}.key succesfully saved on your USB"
|
||||
act "now we'll proceed opening your brand new tomb"
|
||||
|
||||
"${TOMBEXEC}" -k ${tombfile}.key open ${tombfile}
|
||||
"${TOMBEXEC}" open -k ${tombfile}.key ${tombfile}
|
||||
if [ $? = 0 ]; then
|
||||
launch_status ${tombname}
|
||||
fi
|
||||
@ -392,7 +392,7 @@ cat <<EOF
|
||||
|
||||
EOF
|
||||
|
||||
"${TOMBEXEC}" -k ${tombname}.tomb.key open ${tombfile}
|
||||
"${TOMBEXEC}" open -k ${tombname}.tomb.key ${tombfile}
|
||||
if [ $? = 0 ]; then
|
||||
launch_status ${tombname}
|
||||
fi
|
||||
|
Loading…
Reference in New Issue
Block a user