fileset

git mirror of https://ccx.te2000.cz/bzr/fileset
git clone https://ccx.te2000.cz/git/fileset
Log | Files | Refs | README

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:
Abin/fileset | 3+++
Mbin/fileset.awk | 127+++++++++++++++++++------------------------------------------------------------
Abin/fileset_inc.sh | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mbin/fsapply | 4++--
Atest.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 $?