commit 7bf9015da718033ccdf3bc6697cefe809ba87c53
parent ca9e56240a7e0afae7d5db321491cb9d29729eec
Author: Jan Pobrislo <ccx@webprojekty.cz>
Date: Sat, 28 Sep 2013 22:13:08 +0200
use shell functions instead of generating code
Diffstat:
| A | bin/fileset | | | 3 | +++ |
| M | bin/fileset.awk | | | 127 | +++++++++++++++++++------------------------------------------------------------ |
| A | bin/fileset_inc.sh | | | 102 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | bin/fsapply | | | 4 | ++-- |
| A | test.sh | | | 51 | +++++++++++++++++++++++++++++++++++++++++++++++++++ |
5 files changed, 188 insertions(+), 99 deletions(-)
diff --git a/bin/fileset b/bin/fileset
@@ -0,0 +1,3 @@
+#!/bin/sh
+cat "$(dirname "$0")/fileset_inc.sh" && \
+exec awk -f "$(dirname "$0")/fileset.awk" "$@"
diff --git a/bin/fileset.awk b/bin/fileset.awk
@@ -3,14 +3,6 @@ BEGIN {
fname="\"$fname\"" # constants so I don't have to write it out
dirname="\"$dirname\""
or_die="|| exit $?"
-
- # header
- print "#!/bin/sh"
- print "export fname dirname"
- print_b("die() {")
- print_i("printf '%s\\n' \"$*\"")
- print_i("exit 1")
- print_e("}")
}
function escaped(str) {
@@ -62,27 +54,18 @@ function get_till_tab( result) {
return result
}
-# common code to create file-like stuff
-function cmd_mknod(test_cmd, err_msg_type, create_cmd) {
- print_b("if ! "test_cmd"; then")
- print_b("if test -e "fname"; then")
- if(crest ~ /!/) {
- if(crest ~ /f/) {
- print_d("rm -rf "fname)
- } else {
- print_d("rm -r "fname)
- }
+function get_argument(whole_statement, result) {
+ if(whole_statement) {
+ result = statement
+ statement = ""
} else {
- print_i("die \"already present but not a "err_msg_type":\" "fname)
+ result = get_till_tab()
}
- print_e("fi")
- if(crest ~ /p/) {
- print_d("mkdir -p "dirname)
- }
- if(create_cmd) {
- print_d(create_cmd)
- }
- print_e("fi")
+ return result
+}
+
+function shellfunc(fun, flags) {
+ print_d("flags "quoted(flags)"; "fun)
}
function process_statement() {
@@ -124,88 +107,33 @@ function process_statement() {
# remove
if(cchar == "r") {
- print_b("if test -e "fname"; then")
- if(crest ~ /r/) {
- if(crest ~ /f/) {
- print_d("rm -rf "fname)
- } else {
- print_d("rm -r "fname)
- }
- } else {
- }
- if(crest ~ /f/) {
- print_d("rm -f "fname)
- } else {
- print_d("rm "fname)
- }
- print_e("fi")
+ shellfunc("r", crest)
continue
}
+ # create file
if(cchar == "f") {
- cmd_mknod("test -f "fname, "file", "touch fname")
+ shellfunc("f", crest)
continue
}
- # needs special handling as we may not have readline
- if(cchar == "l") {
- link_dest = quoted(get_till_tab())
- print_b("if ! test -x /bin/readlink || ! test -l "fname" || test x\"$(readlink "fname")\" != x"link_dest"; then")
- if(crest ~ /!/) {
- print_b("if test -e "fname"; then")
- } else {
- print_b("if test -L "fname"; then")
- }
- if(crest ~ /f/) {
- print_d("rm -f "fname)
- } else {
- print_d("rm "fname)
- }
- if(crest !~ /!/) {
- print_m("else")
- print_i("die \"already present but not a symbolic link:\" "fname)
- }
- print_e("fi")
- if(crest ~ /p/) {
- print_d("mkdir -p "dirname)
- }
- print_d("ln -s "link_dest" "fname)
- print_e("fi")
+ # symbolic link
+ if(cchar ~ /[lL]/) {
+ shellfunc("l "quoted(get_argument(cchar == "L")), crest)
continue
}
- # could be folded to mknod at the expense of superfluous mkdir -p
+ # directory
if(cchar == "d") {
- print_b("if ! test -d "fname"; then")
- print_b("if test -e "fname"; then")
- if(crest ~ /!/) {
- if(crest ~ /f/) {
- print_d("rm -f "fname)
- } else {
- print_d("rm "fname)
- }
- } else {
- print_i("die \"already present but not a directory:\" "fname)
- }
- print_e("fi")
- if(crest ~ /p/) {
- print_d("mkdir -p "fname)
- } else {
- print_d("mkdir "fname)
- }
- print_e("fi")
+ shellfunc("d", crest)
continue
}
# cat, copy, content; eats rest of statement and puts it into the file
if(cchar ~ /[cC]/) {
- cmd_mknod("test -f "fname, "file")
- if(cchar == "C") {
- content = statement
- statement = ""
- } else {
- content = get_till_tab()
- }
+ shellfunc("f 1", crest)
+ content = get_argument(cchar == "C")
+
# unless disabled with the N flag, append newline at the end of
# last line, if not already present
printf_fmt = crest ~ /n/ || (crest !~ /N/ && content !~ /\n$/) ? \
@@ -219,23 +147,28 @@ function process_statement() {
# run shell command
if(cchar == "!") {
+ # use as Filter
if(crest ~ /f/) {
if(crest ~ /c/) {
- cmd_mknod("test -f "fname, "file", "touch "fname)
+ shellfunc("f", crest)
} else {
- cmd_mknod("test -f "fname, "file")
+ shellfunc("f 1", crest)
}
print_d("{ "statement"\n} <"fname" >"fname".tmp.$$")
print_d("cat >"fname" "fname".tmp.$$")
print_d("rm "fname".tmp.$$")
+ # use file as Input
} else if(crest ~ /i/) {
print_d("{ "statement"\n} <"fname)
+ # use file as Output
} else if(crest ~ /o/) {
- cmd_mknod("test -f "fname, "file")
+ shellfunc("f 1", crest)
print_d("{ "statement"\n} >"fname)
+ # Append to file
} else if(crest ~ /a/) {
- cmd_mknod("test -f "fname, "file")
+ shellfunc("f 1", crest)
print_d("{ "statement"\n} >>"fname)
+ # do nothing special with file
} else {
print_d("{ "statement"\n}")
}
diff --git a/bin/fileset_inc.sh b/bin/fileset_inc.sh
@@ -0,0 +1,102 @@
+#!/bin/sh
+export fname dirname
+die() {
+ printf '%s\\n' \"$*\"
+ exit 1
+}
+
+flags() {
+ case "$1" in (*'!'*) f_bang=true;; (*) f_bang=false;; esac
+ case "$1" in (*p*) f_p=true;; (*) f_p=false;; esac
+ case "$1" in (*f*) f_f=true;; (*) f_f=false;; esac
+ case "$1" in (*r*) f_r=true;; (*) f_r=false;; esac
+ case "$1" in (*n*) f_n=true;; (*) f_n=false;; esac
+ case "$1" in (*N*) f_N=true;; (*) f_N=false;; esac
+ case "$1" in (*a*) f_a=true;; (*) f_a=false;; esac
+ case "$1" in (*i*) f_i=true;; (*) f_i=false;; esac
+ case "$1" in (*o*) f_o=true;; (*) f_o=false;; esac
+}
+
+# TODO: search $PATH
+if test -x /bin/readlink -o -x /usr/bin/readlink; then
+ has_readlink=true
+else
+ has_readlink=false
+fi
+
+rm_flags() {
+ if $f_f; then
+ rm -f$2 "$fname" || exit $?
+ elif test -n "$2"; then
+ rm -$2 "$fname" || exit $?
+ else
+ rm "$fname" || exit $?
+ fi
+}
+
+mkdir_p() {
+ if $f_p; then
+ mkdir -p "$dirname" || exit $?
+ fi
+}
+
+l() {
+ if test -L "$fname"; then
+ if $has_readlink && test x"$(readlink "$fname")" = x"$1"; then
+ return
+ elif $f_f; then
+ rm_flags
+ fi
+ elif test -e "$fname"; then
+ if $f_bang; then
+ rm_flags r
+ else
+ die "already present but not a symbolic link: $fname"
+ fi
+ fi
+ mkdir_p
+ ln -s "$1" "$fname" || exit $?
+}
+
+r() {
+ if test -e "$fname"; then
+ if $f_r; then
+ rm_flags r
+ else
+ rm_flags
+ fi
+ fi
+}
+
+f() {
+ if test -f "$fname"; then
+ return
+ elif test -e "$fname"; then
+ if $f_bang; then
+ rm_flags r
+ else
+ die "already present but not a file: $fname"
+ fi
+ fi
+ mkdir_p
+ if test -z "$1"; then
+ touch "$fname" || exit $?
+ fi
+}
+
+d() {
+ if test -d "$fname"; then
+ return
+ elif test -e "$fname"; then
+ if $f_bang; then
+ rm_flags
+ else
+ die "already present but not a directory: $fname"
+ fi
+ fi
+ if $f_p; then
+ mkdir -p "$fname" || exit $?
+ else
+ mkdir "$fname" || exit $?
+ fi
+}
diff --git a/bin/fsapply b/bin/fsapply
@@ -12,7 +12,7 @@ fi
cd "$1" || exit $?
shift
if [[ -n "$opt" ]]; then
- fileset.awk | sh $opt
+ fileset "$@" | sh $opt
else
- fileset.awk | sh
+ fileset "$@" | sh
fi
diff --git a/test.sh b/test.sh
@@ -0,0 +1,51 @@
+#!/bin/sh
+export fname dirname
+die() {
+ printf '%s\n' "$*"
+ exit 1
+}
+
+fname=./etc/autofs/auto.smb
+dirname=./etc/autofs
+if ! test -f "$fname"; then
+ if test -e "$fname"; then
+ die "already present but not a file:" "$fname"
+ fi
+fi
+content='#!/bin/bash
+
+# This file must be executable to work! chmod 755!
+
+key="$1"
+opts="-fstype=cifs"
+
+for P in /bin /sbin /usr/bin /usr/sbin
+do
+ if [ -x $P/smbclient ]
+ then
+ SMBCLIENT=$P/smbclient
+ break
+ fi
+done
+
+[ -x $SMBCLIENT ] || exit 1
+
+$SMBCLIENT -gNL $key 2>/dev/null| awk -v key="$key" -v opts="$opts" -F'\''|'\'' -- '\''
+ BEGIN { ORS=""; first=1 }
+ /Disk/ {
+ if (first)
+ print opts; first=0
+ dir = $2
+ loc = $2
+ # Enclose mount dir and location in quotes
+ # Double quote "$" in location as it is special
+ gsub(/\$$/, "\\$", loc);
+ gsub(/\&/,"\\\\&",loc)
+ print " \\\n\t \"/" dir "\"", "\"://" key "/" loc "\""
+ }
+ END { if (!first) print "\n"; else exit 1 }
+ '\''
+'
+printf >"$fname" '%s\n' "$content" || exit $?
+chown 0:0 "$fname" || exit $?
+chmod 755 "$fname" || exit $?