OSX compatibility master
authorMichael Wallner <mike@php.net>
Wed, 5 Aug 2015 16:22:53 +0000 (18:22 +0200)
committerMichael Wallner <mike@php.net>
Wed, 5 Aug 2015 16:23:06 +0000 (18:23 +0200)
19 files changed:
.gitignore
Makefile.am
README.md
bin/Makefile.am [new file with mode: 0644]
bin/btr
bin/btr-hook
bin/btr-setsid.c [new file with mode: 0644]
bin/btrc
bin/btrd [deleted file]
bin/btrd.in [new file with mode: 0755]
configure.ac
share/btr/btr.sh
share/btr/btrc.args
share/btr/btrc.sh
share/btr/btrd.sh
share/btr/common.sh [deleted file]
share/btr/common.sh.in [new file with mode: 0755]
share/btr/opt.awk [deleted file]
share/btr/opt.awk.in [new file with mode: 0755]

index 5c80847..6acac89 100644 (file)
@@ -11,3 +11,11 @@ config.log
 config.status
 config.cache
 btr-?.?.*
+bin/btr-setsid
+bin/btrd
+compile
+depcomp
+*.o
+.deps
+share/btr/common.sh
+share/btr/opt.awk
index ec71d7b..4ef424a 100644 (file)
@@ -1,5 +1,12 @@
 EXTRA_SCRIPTS =
 btrdir = $(prefix)
+#bin_SCRIPTS = share/btr/opt.awk share/btr/common.sh bin/btrd
 dist_bin_SCRIPTS = $(BTR_BIN)
 nobase_dist_btr_SCRIPTS = $(BTR_SCRIPTS)
 nobase_dist_btr_DATA = $(BTR_SHARE)
+
+#CLEANFILES = share/btr/opt.awk share/btr/common.sh bin/btrd
+
+SUBDIRS = bin
+
+# vim: noet
index 6f15c99..8459995 100644 (file)
--- a/README.md
+++ b/README.md
@@ -62,3 +62,8 @@ Usage: btr [-hyvqcC] [<options>]
   See also curl.example.conf
 
 ```
+
+#### Prerequisites
+
+* GNU getopt
+* nmap's ncat (for btrd/btrc)
diff --git a/bin/Makefile.am b/bin/Makefile.am
new file mode 100644 (file)
index 0000000..f2a3741
--- /dev/null
@@ -0,0 +1,2 @@
+bin_PROGRAMS = btr-setsid
+btr_setsid_SOURCES = btr-setsid.c
\ No newline at end of file
diff --git a/bin/btr b/bin/btr
index a8a29a4..db82d6f 100755 (executable)
--- a/bin/btr
+++ b/bin/btr
@@ -1,21 +1,21 @@
 #!/bin/bash
 
-export BTR_BINDIR=$(realpath $(dirname $0)/)
-export BTR_LIBDIR=$(realpath $(dirname $0)/../share/btr)
+export BTR_BINDIR=$(dirname $0)/
+export BTR_LIBDIR=$(dirname $0)/../share/btr
 BTR_BANNER="Build, test & report. Simple and stupid."
 
 . $BTR_LIBDIR/common.sh
 . $BTR_LIBDIR/btr.sh
 
-btr-parseopts "$@"
-btr-setup
+btr_parseopts "$@"
+btr_setup
 
 if $BTR_VERBOSE
 then
-       btr-conf-show
-       btr-confirm "Everything setup. Do you want to continue?"
+       btr_conf_show
+       btr_confirm "Everything setup. Do you want to continue?"
 fi
 
-btr-run
+btr_run
 
 # vim: noet
index 644d60c..099fea0 100755 (executable)
@@ -1,21 +1,21 @@
 #!/bin/bash
 
-export BTR_BINDIR=$(realpath $(dirname $0)/)
-export BTR_LIBDIR=$(realpath $(dirname $0)/../share/btr)
+export BTR_BINDIR=$(dirname $0)/
+export BTR_LIBDIR=$(dirname $0)/../share/btr
 BTR_BANNER="Install btr hook into your VCS reporitory."
 
 . $BTR_LIBDIR/common.sh
 . $BTR_LIBDIR/btr.sh
 
-btr-parseopts "$@"
-btr-setup false
+btr_parseopts "$@"
+btr_setup false
 
 if $BTR_VERBOSE
 then
-       btr-conf-show
+       btr_conf_show
 fi
 
-btr-confirm "Everything setup. Do you want to install the '$BTR_EXTRA_ARGS' hook for '$BTR_SOURCE_RULES'?"
+btr_confirm "Everything setup. Do you want to install the '$BTR_EXTRA_ARGS' hook for '$BTR_SOURCE_RULES'?"
 
 case "$BTR_SOURCE_RULES" in
 git)
@@ -29,7 +29,7 @@ git)
                        else
                                echo "#!/bin/bash"
                        fi
-                       echo $(btr-conf-dump) 'BTR_BRANCH=$(basename $(git symbolic-ref HEAD))' "'$BTR_BINDIR/btr' -qy &"
+                       echo $(btr_conf_dump) 'BTR_BRANCH=$(basename $(git symbolic-ref HEAD))' "'$BTR_BINDIR/btr' -qy &"
                ) >"$BTR_HOOK_FILE.tmp" && \
                        chmod +x "$BTR_HOOK_FILE.tmp" && \
                        mv "$BTR_HOOK_FILE.tmp" "$BTR_HOOK_FILE" && \
diff --git a/bin/btr-setsid.c b/bin/btr-setsid.c
new file mode 100644 (file)
index 0000000..f293efa
--- /dev/null
@@ -0,0 +1,34 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+       if (argc < 2) {
+               fprintf(stderr, "Usage: %s <program> [args...]\n", argv[0]);
+               return EXIT_FAILURE;
+       }
+
+       if (getpid() == getpgrp()) {
+               pid_t pid = fork();
+
+               switch (pid) {
+               case 0:
+                       break;
+               case -1:
+                       perror("fork");
+                       return EXIT_FAILURE;
+               default:
+                       return EXIT_SUCCESS;
+               }
+       }
+
+       if (setsid() < 0) {
+               perror("setsid");
+               return EXIT_FAILURE;
+       }
+
+       execvp(argv[1], &argv[1]);
+       perror("exec");
+       return EXIT_FAILURE;
+}
index 82b9b7f..658372d 100755 (executable)
--- a/bin/btrc
+++ b/bin/btrc
@@ -1,27 +1,32 @@
 #!/bin/bash
 
-export BTR_BINDIR=$(realpath $(dirname $0)/)
-export BTR_LIBDIR=$(realpath $(dirname $0)/../share/btr)
+export BTR_BINDIR=$(dirname $0)/
+export BTR_LIBDIR=$(dirname $0)/../share/btr
 BTR_BANNER="Control \`btrd\` daemons."
 
 . $BTR_LIBDIR/common.sh
 . $BTR_LIBDIR/btrc.sh
 
-btr-parseopts "$@"
-btrc-setup
+btr_parseopts "$@"
+btrc_setup
 
 case "$BTR_ACTION" in
 status)
-       ncat --recv-only -U "$BTR_COMFILE"
+       # see https://github.com/nmap/nmap/issues/193
+       if test $(uname -s) = Darwin; then
+               ncat --recv-only 127.0.0.1 $(cat "$BTR_COMFILE")
+       else
+               ncat --recv-only -U "$BTR_COMFILE"
+       fi
        ;;
 cancel)
-       btrc-signal INT
+       btrc_signal INT
        ;;
 run)
-       btrc-signal HUP
+       btrc_signal HUP
        ;;
 term)
-       btrc-signal TERM
+       btrc_signal TERM
        ;;
 esac
 
diff --git a/bin/btrd b/bin/btrd
deleted file mode 100755 (executable)
index 055bd7b..0000000
--- a/bin/btrd
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/bash
-
-export BTR_BINDIR=$(realpath $(dirname $0)/)
-export BTR_LIBDIR=$(realpath $(dirname $0)/../share/btr)
-BTR_BANNER="Run btr as background daemon receiving jobs for a repo."
-
-. $BTR_LIBDIR/common.sh
-. $BTR_LIBDIR/btr.sh
-
-btr-parseopts "$@"
-btr-setup
-
-if $BTR_VERBOSE
-then
-       btr-conf-show
-       btr-confirm "Everything setup. Do you want to start the daemon?"
-elif ! $BTR_QUIET
-then
-       echo "Starting the daemon. Control with \`btrc $BTR_BUILD\`"
-else
-       echo "$BUILD"
-fi
-
-setsid $SHELL -c "$BTR_LIBDIR/btrd.sh &"
-
-# vim: noet
diff --git a/bin/btrd.in b/bin/btrd.in
new file mode 100755 (executable)
index 0000000..bcb1038
--- /dev/null
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+export BTR_BINDIR=$(dirname $0)/
+export BTR_LIBDIR=$(dirname $0)/../share/btr
+BTR_BANNER="Run btr as background daemon receiving jobs for a repo."
+
+. $BTR_LIBDIR/common.sh
+. $BTR_LIBDIR/btr.sh
+
+btr_parseopts "$@"
+btr_setup
+
+if $BTR_VERBOSE
+then
+       btr_conf_show
+       btr_confirm "Everything setup. Do you want to start the daemon?"
+elif ! $BTR_QUIET
+then
+       echo "Starting the daemon. Control with \`btrc $BTR_BUILD\`"
+else
+       echo "$BUILD"
+fi
+
+@SETSID@ $SHELL -c "$BTR_LIBDIR/btrd.sh &"
+
+# vim: noet
index 98676b6..a3ab9da 100644 (file)
@@ -1,22 +1,72 @@
-AC_INIT([btr], [0.4.0], [mike@php.net])
+AC_INIT([btr], [0.5.0], [mike@php.net])
 AM_INIT_AUTOMAKE([foreign])
-AM_SILENT_RULES()
+AM_SILENT_RULES
 AC_CONFIG_SRCDIR([./share/btr/btr.sh])
 
+AC_PATH_PROG([GETOPT], [getopt], [getopt])
+AC_ARG_VAR([GETOPT], [location of gnu-getopt, see --with-gnu-getopt; e.g. /usr/local/opt/gnu-getopt/bin/getopt])
+AC_ARG_WITH([gnu-getopt], [AS_HELP_STRING([--with-gnu-getopt=path], [
+       Location of the enhanced GNU getopt program])], [
+], [
+       with_gnu_getopt=$GETOPT
+])
+
+AC_MSG_CHECKING([for GNU getopt])
+$with_gnu_getopt --test >/dev/null
+AS_IF([test $? -ne 4], [
+       AC_MSG_RESULT([no])
+       AC_MSG_ERROR([$with_gnu_getopt looks like the BSD version, please provide the path to the GNU version --with-gnu-getopt])
+], [
+       AC_MSG_RESULT([yes, $with_gnu_getopt])
+       AC_SUBST([GETOPT], [$with_gnu_getopt])
+])
+
+AC_PROG_AWK
+AC_PATH_PROG([AWK_PATH], [$AWK], [/bin/$AWK])
+
+AC_CHECK_PROGS([SETSID], [setsid], [nothing])
+AC_ARG_VAR([SETSID], [location of a setsid program; a simple replacement will be built if none found or provided])
+AS_IF([test "$SETSID" = nothing], [
+       SETSID="\$BTR_BINDIR/btr-setsid"
+       AC_PROG_CC
+       AC_CONFIG_FILES([bin/Makefile])
+], [:]);
+
+AC_CHECK_PROGS([NPROC], [nproc sysctl], [nothing])
+AC_MSG_CHECKING([for number of cores])
+AS_CASE([$NPROC],
+       [nproc], [
+               BTR_CPUS=$(nproc)
+       ],
+       [sysctl], [
+               BTR_CPUS=$(sysctl -n hw.ncpu 2>/dev/null ||¬†echo 1)
+       ],
+       [
+               BTR_CPUS=1
+       ]
+)
+AC_MSG_RESULT([$BTR_CPUS])
+AC_SUBST([BTR_CPUS], [$BTR_CPUS])
+
 AC_MSG_CHECKING([for bin/ scripts]);
-       BTR_BIN=$(find $srcdir/bin -type f -perm -a=x | xargs)
+       BTR_BIN=$(find $srcdir/bin -type f -perm -a=x | sed 's/\.in$//' | xargs)
 AC_MSG_RESULT([$BTR_BIN])
 AC_SUBST([BTR_BIN], [$BTR_BIN])
 
 AC_MSG_CHECKING([for share/ scripts])
-       BTR_SCRIPTS=$(find $srcdir/share/btr -type f -perm -a=x | xargs)
+       BTR_SCRIPTS=$(find $srcdir/share/btr -type f -perm -a=x | sed 's/\.in$//' | xargs)
 AC_MSG_RESULT([$BTR_SCRIPTS])
 AC_SUBST([BTR_SCRIPTS], [$BTR_SCRIPTS])
 
 AC_MSG_CHECKING([for share/ data])
-       BTR_SHARE=$(find $srcdir/share/btr -type f ! -perm -a=x | xargs)
+       BTR_SHARE=$(find $srcdir/share/btr -type f ! -perm -a=x | sed 's/\.in$//' | xargs)
 AC_MSG_RESULT([$BTR_SHARE])
 AC_SUBST([BTR_SHARE], [$BTR_SHARE])
 
+AC_CONFIG_FILES([bin/btrd], [chmod +x bin/btrd])
+AC_CONFIG_FILES([share/btr/opt.awk], [chmod +x share/btr/opt.awk])
+AC_CONFIG_FILES([share/btr/common.sh], [chmod +x share/btr/common.sh])
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
+
+dnl vim: noet
index 04ac847..518afd1 100755 (executable)
@@ -1,14 +1,14 @@
 #!/bin/sh
 
-function btr-setup {
+function btr_setup {
        if test -z "$BTR_SOURCE_RULES" -o -z "$BTR_BUILD_RULES" -o -z "$BTR_REPORT_RULES"
        then
-               btr-banner
-               btr-help
+               btr_banner
+               btr_help
        fi
 
-       btr-setup-verbosity ${1:-true}
-       btr-setup-rundir
+       btr_setup_verbosity ${1:-true}
+       btr_setup_rundir
 
        export BTR_SOURCE_RULES BTR_BUILD_RULES BTR_REPORT_RULES
        test -z "$BTR_SOURCE_ARGS"  || export BTR_SOURCE_ARGS
@@ -17,7 +17,7 @@ function btr-setup {
        test -z "$BTR_BUILD_CLEAN"  || export BTR_BUILD_CLEAN
        test -z "$BTR_TEST_ARGS"    || export BTR_TEST_ARGS
        test -z "$BTR_REPORT_ARGS"  || export BTR_REPORT_ARGS
-       BTR_REPO=$(basename $(sed -re 's~^.*[/:#]~~' <<<"$BTR_SOURCE_ARGS") .git)
+       BTR_REPO=$(basename $(sed 's~^.*[/:#]~~' <<<"$BTR_SOURCE_ARGS") .git)
        BTR_SAFE_BRANCH=$(tr ":/" "_" <<<$(basename "$BTR_BRANCH"))
        export BTR_REPO BTR_BRANCH BTR_SAFE_BRANCH
 
@@ -38,9 +38,9 @@ function btr-setup {
        export BTR_LAST_REPORT=$(basename $(ls -t "$BTR_RUNDIR/$BTR_LOG_DIR/test@"* 2>/dev/null | head -n1) 2>/dev/null)
        export BTR_REPORT="$BTR_LOG_DIR/report@$BTR_DATE.log"
 }
-export -f btr-setup
+export -f btr_setup
 
-function btr-conf-show {
+function btr_conf_show {
        echo
        echo "# Configuration:"
        echo
@@ -72,15 +72,15 @@ function btr-conf-show {
        echo "BTR_LAST_REPORT    = $BTR_LAST_REPORT"
        echo
 }
-export -f btr-conf-show
+export -f btr_conf_show
 
-function btr-run {
+function btr_run {
        set -e
-       make -e $BTR_SILENT_FLAG -C $BTR_RUNDIR -f $BTR_LIBDIR/source/$BTR_SOURCE_RULES.mk
-       make -e $BTR_SILENT_FLAG -C $BTR_RUNDIR -f $BTR_LIBDIR/build/$BTR_BUILD_RULES.mk
-       make -e $BTR_SILENT_FLAG -C $BTR_RUNDIR -f $BTR_LIBDIR/report/$BTR_REPORT_RULES.mk
+       make -e $BTR_SILENT_FLAG -C $BTR_RUNDIR -f $(pwd)/$BTR_LIBDIR/source/$BTR_SOURCE_RULES.mk
+       make -e $BTR_SILENT_FLAG -C $BTR_RUNDIR -f $(pwd)/$BTR_LIBDIR/build/$BTR_BUILD_RULES.mk
+       make -e $BTR_SILENT_FLAG -C $BTR_RUNDIR -f $(pwd)/$BTR_LIBDIR/report/$BTR_REPORT_RULES.mk
        set +e
 }
-export -f btr-run
+export -f btr_run
 
 # vim: noet
index 9526539..ea25776 100644 (file)
@@ -1,5 +1,4 @@
 [action]       s[t[at[us]]]  Show the status of the build\\nr[un]         Make a BTR run\\nc[anc[el]]    Cancel currently running job\\nt[erm[inate]] Terminate the BTR daemon
 
 <build>        The build id of the `btrd` daemon.\\nUsually similar to $repo@$branch[-$suffix].
-
 # vim: noet ts=24 sw=24
index 8a38bb3..a230318 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/bash
 
-function btrc-parseargs {
+function btrc_parseargs {
        eval set -- "$BTR_EXTRA_ARGS"
        while test $# -gt 0
        do
@@ -30,13 +30,13 @@ function btrc-parseargs {
        done
 }
 
-function btrc-setup {
-       btrc-parseargs
+function btrc_setup {
+       btrc_parseargs
        
        if test -z "$BTR_BUILD"
        then
-               btr-banner
-               btr-help
+               btr_banner
+               btr_help
        fi
        
        if test -z "$BTR_ACTION"
@@ -44,8 +44,8 @@ function btrc-setup {
                BTR_ACTION=status
        fi
        
-       btr-setup-rundir
-       btr-setup-verbosity false
+       btr_setup_rundir
+       btr_setup_verbosity false
        
        BTR_PIDFILE="$BTR_RUNDIR/$BTR_BUILD.pid"
        BTR_LOGFILE="$BTR_RUNDIR/$BTR_BUILD.log"
@@ -63,9 +63,9 @@ function btrc-setup {
                error "Could not find btrd pid file of '$BTR_BUILD' in $BTR_RUNDIR."
        fi
 }
-export -f btrc-setup
+export -f btrc_setup
 
-function btrc-signal {
+function btrc_signal {
        local sig=$1
        local pid=$(cat "$BTR_PIDFILE")
        kill -s $sig $pid
@@ -82,7 +82,7 @@ function btrc-signal {
                ;;
        esac
 }
-export -f btrc-signal
+export -f btrc_signal
 
 
 # vim: noet
index 725f0e4..77aa951 100755 (executable)
@@ -1,49 +1,48 @@
 #!/bin/bash
 
-function btrd-start {
-       btrd-cancel
+function btrd_start {
+       btrd_cancel
        BTR_DATE=$(date +%Y%m%d%H%M%S)
-       btr-setup
-       btr-run &
+       btr_setup
+       btr_run &
        BTR_WORKER=$!
 }
-export -f btrd-start
+export -f btrd_start
 
-function btrd-cancel {
-       if btrd-worker-started
+function btrd_cancel {
+       if btrd_worker_started
        then
-               kill $BTR_WORKER
-               wait $BTR_WORKER
+               btrd_worker_kill
+               btrd_worker_reap
        fi
-       BTR_WORKER=0
 }
-export -f btrd-cancel
+export -f btrd_cancel
 
-function btrd-stop {
+function btrd_stop {
        BTR_DAEMON=false
 }
-export -f btrd-stop
+export -f btrd_stop
 
-function btrd-ctime {
+function btrd_ctime {
        stat -c %y "$1"
 }
-export -f btrd-ctime
+export -f btrd_ctime
 
-function btrd-fsize {
+function btrd_fsize {
        local bytes=$(stat -c %s "$1")
 }
-export -f btrd-fsize
+export -f btrd_fsize
 
-function btrd-status {
+function btrd_status {
        echo "BTR_BUILD='$BTR_BUILD'"
        echo "BTR_SERVER='$BTR_SERVER'"
        echo "BTR_PIDFILE='$BTR_PIDFILE'"
        echo "BTR_LOGFILE='$BTR_LOGFILE'"
        echo "BTR_COMFILE='$BTR_COMFILE'"
 }
-export -f btrd-status
+export -f btrd_status
 
-function btrd-logrotate {
+function btrd_logrotate {
        local i=1
        local f="$BTR_LOGFILE"
        
@@ -57,28 +56,28 @@ function btrd-logrotate {
        fi
        
 }
-export -f btrd-logrotate
+export -f btrd_logrotate
 
-function btrd-worker-started {
+function btrd_worker_started {
        test "$BTR_WORKER" -gt 1
 }
-export -f btrd-worker-started
+export -f btrd_worker_started
 
-function btrd-worker-running {
+function btrd_worker_running {
        kill -s 0 $BTR_WORKER
 }
-export -f btrd-worker-running
+export -f btrd_worker_running
 
-function btrd-worker-reap {
+function btrd_worker_reap {
        wait $BTR_WORKER
        BTR_WORKER=0
 }
-export -f btrd-worker-reap
+export -f btrd_worker_reap
 
-function btrd-worker-kill {
+function btrd_worker_kill {
        kill $BTR_WORKER
 }
-export -f btrd-worker-kill
+export -f btrd_worker_kill
  
 BTR_DAEMON=true
 BTR_WORKER=0
@@ -89,29 +88,35 @@ BTR_COMFILE="$BTR_RUNDIR/$BTR_BUILD.socket"
 
 export BTR_DAEMON BTR_WORKER BTR_SERVER BTR_PIDFILE BTR_LOGFILE BTR_COMFILE
 
-btrd-logrotate
+btrd_logrotate
 
 exec >"$BTR_LOGFILE" 2>&1
 echo $$ >"$BTR_PIDFILE"
 
-ncat -lkU -c btrd-status "$BTR_COMFILE" &
+# see https://github.com/nmap/nmap/issues/193
+if test $(uname -s) = Darwin; then
+       echo $(($(cksum <<<"$BTR_BUILD" | cut -d" " -f 1) % 64511 + 1024)) > "$BTR_COMFILE"
+       ncat -nlkc btrd_status 127.0.0.1 $(cat "$BTR_COMFILE") &
+else
+       ncat -nlkc btrd_status -U "$BTR_COMFILE" &
+fi
 BTR_SERVER=$!
 
-trap btrd-start HUP
-trap btrd-cancel INT
-trap btrd-stop TERM
+trap btrd_start HUP
+trap btrd_cancel INT
+trap btrd_stop TERM
 
 while $BTR_DAEMON
 do
-       if btrd-worker-started && btrd-worker-running
+       if btrd_worker_started && btrd_worker_running
        then
-               btrd-worker-reap
+               btrd_worker_reap
        else
                kill -s STOP $$
        fi
 done
 
-btrd-cancel
+btrd_cancel
 
 if test "$BTR_SERVER" -gt 1
 then
diff --git a/share/btr/common.sh b/share/btr/common.sh
deleted file mode 100755 (executable)
index 88f522e..0000000
+++ /dev/null
@@ -1,336 +0,0 @@
-#!/bin/bash
-
-export BTR_DATE=$(date +%Y%m%d%H%M%S)
-export BTR_CPUS=${CPUS:-$(nproc)}
-export BTR_PROG=$(basename "$0")
-export BTR_QUIET=false
-export BTR_VERBOSE=false
-export BTR_FORCEYES=false
-
-function error {
-       echo "$@" >&2
-       exit 1
-}
-export -f error
-
-function btr-banner {
-       echo "$BTR_PROG v0.4.0, (c) Michael Wallner <mike@php.net>"
-       if test "$BTR_BANNER"
-       then
-               echo "$BTR_BANNER"
-       fi
-}
-export -f btr-banner
-
-function btr-confirm {
-       local CONTINUE
-       if ! $BTR_FORCEYES
-       then
-               echo
-               echo -n "$1 (y/N) "
-               read -r CONTINUE
-               case $CONTINUE in
-                       y*|Y*)
-                               echo
-                               ;;
-                       *)
-                               exit -1
-                               ;;
-               esac
-       fi
-}
-export -f btr-confirm
-
-function btr-setup-rundir {
-       local default_rundir="${1:-/tmp/btr}"
-       
-       if test -z "$BTR_RUNDIR"
-       then
-               export BTR_RUNDIR="$default_rundir"
-       else
-               export BTR_RUNDIR=$(realpath "$BTR_RUNDIR")
-       fi
-       
-       mkdir -p "$BTR_RUNDIR" || error "Could not create directory '$BTR_RUNDIR'"
-}
-export -f btr-setup-rundir
-
-function btr-setup-verbosity {
-       local for_make=${1:-false}
-       
-       if ${BTR_VERBOSE:-false}
-       then
-               BTR_QUIET_FLAG=
-               BTR_SILENT_FLAG=
-               BTR_VERBOSE_FLAG="-v"
-               SAY="echo; echo"
-       elif $BTR_QUIET
-       then
-               BTR_QUIET_FLAG="-q"
-               BTR_SILENT_FLAG="-s"
-               BTR_VERBOSE_FLAG=
-               SAY="true"
-       else
-               BTR_QUIET_FLAG=
-               BTR_SILENT_FLAG="-s"
-               BTR_VERBOSE_FLAG=
-               SAY="echo"
-       fi
-       
-       if $for_make
-       then
-               SAY="@$SAY"
-       fi
-       
-       export BTR_QUIET BTR_VERBOSE BTR_FORCEYES BTR_QUIET_FLAG BTR_SILENT_FLAG BTR_VERBOSE_FLAG SAY
-}
-export -f btr-setup-verbosity
-
-function btr-shortoptions {
-       (
-               local f
-               local e
-               
-               for f in common $BTR_PROG
-               do
-                       for e in flags opts
-                       do
-                               test -e "$BTR_LIBDIR/$f.$e" && cut -sf1 <"$BTR_LIBDIR/$f.$e"
-                       done
-               done
-       ) | xargs | tr -d " "
-}
-export -f btr-shortoptions
-
-function btr-longoptions {
-       (
-               local f
-               local e
-               
-               for f in common $BTR_PROG
-               do
-                       for e in flags opts
-                       do
-                               test -e "$BTR_LIBDIR/$f.$e" && cut -sf2 <"$BTR_LIBDIR/$f.$e"
-                       done
-               done
-       )  | sed -r -e 's/(:+).*/\1/' | xargs | tr " " ","
-}
-export -f btr-longoptions
-
-function btr-flags {
-       (
-               local f
-               local e
-               
-               for f in common $BTR_PROG
-               do
-                       test -e "$BTR_LIBDIR/$f.flags" && cut -sf1 <"$BTR_LIBDIR/$f.flags"
-               done
-       ) | xargs | tr -d " "
-}
-export -f btr-flags
-
-function btr-help-options {
-       local f o=$(
-               for f in common $BTR_PROG
-               do
-                       test -e "$BTR_LIBDIR/$f.$1" && "$BTR_LIBDIR/opt.awk" <"$BTR_LIBDIR/$f.$1"
-               done
-       )
-       if test "$o"
-       then
-               echo
-               case "$1" in
-               flags)
-                       echo "  Flags:"
-                       ;;
-               opts)
-                       echo "  Options:"
-                       ;;
-               esac
-               echo "$o"
-       fi
-}
-export -f btr-help-options
-
-function btr-help-args {
-       local a d l
-       
-       if test -e "$BTR_LIBDIR/$BTR_PROG.args"
-       then
-               echo
-               echo "  Arguments:"
-               while read a d
-               do
-                       printf "%b\n" "$d" | fold -sw46 | while read l
-                       do
-                               printf "    %-16s %s\n" "$a" "$l"
-                               a=
-                       done
-                       echo
-               done <"$BTR_LIBDIR/$BTR_PROG.args"
-       fi
-}
-export -f btr-help-args
-
-function btr-args {
-       if test -e "$BTR_LIBDIR/$BTR_PROG.args"
-       then
-               cut -sf1 <"$BTR_LIBDIR/$BTR_PROG.args" | xargs
-       fi
-}
-export -f btr-args
-
-function btr-help {
-       echo
-       echo "Usage: $BTR_PROG [-$(btr-flags)] [<options>]" $(btr-args)
-       btr-help-options flags
-       btr-help-options opts
-       btr-help-args
-       if test $BTR_PROG != "btrc"
-       then
-       echo
-       echo "  Rules format:"
-       echo "    type=arg  e.g: notify-send=\"-u low\""
-       echo "                   mail=\"-c copy@to rcpt@to\""
-       echo "                   irc=\"tcp://btr@chat.freenode.org/#btr\""
-       echo "                   git=\$HOME/src/btr.git"
-       echo
-       echo "    Note though, that some rules do not use any argument."
-       echo
-       echo "  Rulesets:"
-       for ruleset in source build report
-       do
-               printf "    %10s: %s\n" $ruleset \
-                       "$(find "$BTR_LIBDIR/$ruleset" -name '*.mk' -exec basename {} .mk \; | sort | xargs)"
-       done
-       echo
-       fi
-       exit
-}
-export -f btr-help
-
-function btr-parseopts {
-       local shortoptions="$(btr-shortoptions common btr-flags btr-options)"
-       local longoptions="$(btr-longoptions common btr-flags btr-options)"
-       local options
-       
-       options=$(getopt \
-               --name $BTR_PROG \
-               --options "$shortoptions" \
-               --longoptions "$longoptions" \
-               -- "$@" \
-       )
-       if test $? -ne 0
-       then
-               btr-help
-       fi
-       
-       eval set -- "$options"
-       
-       while test $# -gt 0
-       do
-               case "$1" in
-                       -h|--help)
-                               btr-banner
-                               btr-help
-                               ;;
-                       -v|--verbose)
-                               BTR_QUIET=false
-                               BTR_VERBOSE=true
-                               ;;
-                       -q|--quiet)
-                               BTR_QUIET=true
-                               BTR_VERBOSE=false
-                               ;;
-                       -y|--yes)
-                               BTR_FORCEYES=true
-                               ;;
-                       -c|--clean)
-                               BTR_BUILD_CLEAN=true
-                               ;;
-                       -C|--vcsclean)
-                               BTR_SOURCE_CLEAN=true
-                               ;;
-                       ####
-                       -f|--config)
-                               source "$2"
-                               shift
-                               ;;
-                       ####
-                       -B|--branch)
-                               BTR_BRANCH="$2"
-                               shift
-                               ;;
-                       -D|--directory)
-                               BTR_RUNDIR="$2"
-                               shift
-                               ;;
-                       -S|--suffix)
-                               BTR_SUFFIX="$2"
-                               shift
-                               ;;
-                       -T|--test)
-                               BTR_TEST_ARGS="$2"
-                               shift
-                               ;;
-                       ####
-                       -s|--source)
-                               case "$2" in
-                               git*)
-                                       test -z "$BTR_BRANCH" && BTR_BRANCH=master
-                                       ;;
-                               svn*)
-                                       test -z "$BTR_BRANCH" && BTR_BRANCH=trunk
-                                       ;;
-                               cvs*)
-                                       test -z "$BTR_BRANCH" && BTR_BRANCH=HEAD
-                                       ;;
-                               esac
-                               BTR_SOURCE_RULES="$(cut -d= -f1 <<<$2)"
-                               BTR_SOURCE_ARGS="$(cut -s -d= -f2- <<<$2)"
-                               shift
-                               ;;
-                       -b|--build)
-                               BTR_BUILD_RULES="$(cut -d= -f1 <<<$2)"
-                               BTR_BUILD_ARGS="$(cut -s -d= -f2- <<<$2)"
-                               shift
-                               ;;
-                       -r|--report)
-                               BTR_REPORT_RULES="$(cut -d= -f1 <<<$2)"
-                               BTR_REPORT_ARGS="$(cut -s -d= -f2- <<<$2)"
-                               shift
-                               ;;
-                       ####
-                       --)
-                               shift
-                               BTR_EXTRA_ARGS="$@"
-                               break
-                               ;;
-               esac
-               shift
-       done
-}
-export -f btr-parseopts
-
-function btr-conf-dump {
-       echo "BTR_QUIET='$BTR_QUIET'"
-       echo "BTR_VERBOSE='$BTR_VEROSE'"
-       echo "BTR_FORCEYES='$BTR_FORCEYES'"
-       echo "BTR_BRANCH='$BTR_BRANCH'"
-       echo "BTR_SUFFIX='$BTR_SUFFIX'"
-       echo "BTR_RUNDIR='$BTR_RUNDIR'"
-       echo "BTR_SOURCE_RULES='$BTR_SOURCE_RULES'"
-       test ${BTR_SOURCE_ARGS+defined} && echo "BTR_SOURCE_ARGS='$BTR_SOURCE_ARGS'"
-       test ${BTR_SOURC_CLEAN+defined} && echo "BTR_SOURCE_CLEAN='$BTR_SOURCE_CLEAN'"
-       echo "BTR_BUILD_RULES='$BTR_BUILD_RULES'"
-       test ${BTR_BUILD_ARGS+defined}  && echo "BTR_BUILD_ARGS='$BTR_BUILD_ARGS'"
-       test ${BTR_BUILD_CLEAN+defined} && echo "BTR_BUILD_CLEAN='$BTR_BUILD_CLEAN'"
-       test ${BTR_TEST_ARGS+defined}   && echo "BTR_TEST_ARGS='$BTR_TEST_ARGS'"
-       echo "BTR_REPORT_RULES='$BTR_REPORT_RULES'"
-       test ${BTR_REPORT_ARGS+defined} && echo "BTR_REPORT_ARGS='$BTR_REPORT_ARGS'"
-}
-export -f btr-conf-dump
-
-# vim: noet
diff --git a/share/btr/common.sh.in b/share/btr/common.sh.in
new file mode 100755 (executable)
index 0000000..8c8b7e8
--- /dev/null
@@ -0,0 +1,349 @@
+#!/bin/bash
+
+export BTR_DATE=$(date +%Y%m%d%H%M%S)
+export BTR_CPUS=${CPUS:-@BTR_CPUS@}
+export BTR_PROG=$(basename "$0")
+export BTR_QUIET=false
+export BTR_VERBOSE=false
+export BTR_FORCEYES=false
+
+function error {
+       echo "$@" >&2
+       exit 1
+}
+export -f error
+
+function btr_banner {
+       echo "$BTR_PROG v@PACKAGE_VERSION@, (c) Michael Wallner <mike@php.net>"
+       if test "$BTR_BANNER"
+       then
+               echo "$BTR_BANNER"
+       fi
+}
+export -f btr_banner
+
+function btr_confirm {
+       local CONTINUE
+       if ! $BTR_FORCEYES
+       then
+               echo
+               echo -n "$1 (y/N) "
+               read -r CONTINUE
+               case $CONTINUE in
+                       y*|Y*)
+                               echo
+                               ;;
+                       *)
+                               exit -1
+                               ;;
+               esac
+       fi
+}
+export -f btr_confirm
+
+function btr_setup_rundir {
+       local default_rundir="${1:-/tmp/btr}"
+
+       if test -z "$BTR_RUNDIR"
+       then
+               export BTR_RUNDIR="$default_rundir"
+       else
+               export BTR_RUNDIR
+       fi
+
+       mkdir -p "$BTR_RUNDIR" || error "Could not create directory '$BTR_RUNDIR'"
+}
+export -f btr_setup_rundir
+
+btr_verbose_echo_n=false
+function btr_verbose_echo {
+       if test "$1" != "-n"; then
+               $btr_verbose_echo_n ||¬†echo
+               btr_verbose_echo_n=false
+       else
+               btr_verbose_echo_n=true
+       fi
+       echo "$@"
+}
+export -f btr_verbose_echo
+
+function btr_setup_verbosity {
+       local for_make=${1:-false}
+
+       if ${BTR_VERBOSE:-false}
+       then
+               BTR_QUIET_FLAG=
+               BTR_SILENT_FLAG=
+               BTR_VERBOSE_FLAG="-v"
+               SAY="btr_verbose_echo"
+       elif $BTR_QUIET
+       then
+               BTR_QUIET_FLAG="-q"
+               BTR_SILENT_FLAG="-s"
+               BTR_VERBOSE_FLAG=
+               SAY="true"
+       else
+               BTR_QUIET_FLAG=
+               BTR_SILENT_FLAG="-s"
+               BTR_VERBOSE_FLAG=
+               SAY="echo"
+       fi
+
+       if $for_make
+       then
+               SAY="@$SAY"
+       fi
+
+       export BTR_QUIET BTR_VERBOSE BTR_FORCEYES BTR_QUIET_FLAG BTR_SILENT_FLAG BTR_VERBOSE_FLAG SAY
+}
+export -f btr_setup_verbosity
+
+function btr_shortoptions {
+       (
+               local f
+               local e
+
+               for f in common $BTR_PROG
+               do
+                       for e in flags opts
+                       do
+                               test -e "$BTR_LIBDIR/$f.$e" && cut -sf1 <"$BTR_LIBDIR/$f.$e"
+                       done
+               done
+       ) | xargs | tr -d " "
+}
+export -f btr_shortoptions
+
+function btr_longoptions {
+       (
+               local f
+               local e
+
+               for f in common $BTR_PROG
+               do
+                       for e in flags opts
+                       do
+                               test -e "$BTR_LIBDIR/$f.$e" && cut -sf2 <"$BTR_LIBDIR/$f.$e"
+                       done
+               done
+       )  | sed 's/\(:\).*/\1/' | xargs | tr " " ","
+}
+export -f btr_longoptions
+
+function btr_flags {
+       (
+               local f
+               local e
+
+               for f in common $BTR_PROG
+               do
+                       test -e "$BTR_LIBDIR/$f.flags" && cut -sf1 <"$BTR_LIBDIR/$f.flags"
+               done
+       ) | xargs | tr -d " "
+}
+export -f btr_flags
+
+function btr_help_options {
+       local f o=$(
+               for f in common $BTR_PROG
+               do
+                       test -e "$BTR_LIBDIR/$f.$1" && "$BTR_LIBDIR/opt.awk" <"$BTR_LIBDIR/$f.$1"
+               done
+       )
+       if test "$o"
+       then
+               echo
+               case "$1" in
+               flags)
+                       echo "  Flags:"
+                       ;;
+               opts)
+                       echo "  Options:"
+                       ;;
+               esac
+               echo "$o"
+       fi
+}
+export -f btr_help_options
+
+function btr_help_args {
+       local a d l
+
+       if test -e "$BTR_LIBDIR/$BTR_PROG.args"
+       then
+               echo
+               echo "  Arguments:"
+               sed -e 's/#.*//' -e '/^$/d' < "$BTR_LIBDIR/$BTR_PROG.args" | while read a d
+               do
+                       test -z "$a" && continue
+                       printf "%b\n" "$d" | fold -sw46 | while read l
+                       do
+                               printf "    %-16s %s\n" "$a" "$l"
+                               a=
+                       done
+                       echo
+               done
+       fi
+}
+export -f btr_help_args
+
+function btr_args {
+       if test -e "$BTR_LIBDIR/$BTR_PROG.args"
+       then
+               cut -sf1 <"$BTR_LIBDIR/$BTR_PROG.args" | xargs
+       fi
+}
+export -f btr_args
+
+function btr_help {
+       echo
+       echo "Usage: $BTR_PROG [-$(btr_flags)] [<options>]" $(btr_args)
+       btr_help_options flags
+       btr_help_options opts
+       btr_help_args
+       if test $BTR_PROG != "btrc"
+       then
+       echo
+       echo "  Rules format:"
+       echo "    type=arg  e.g: notify-send=\"-u low\""
+       echo "                   mail=\"-c copy@to rcpt@to\""
+       echo "                   irc=\"tcp://btr@chat.freenode.org/#btr\""
+       echo "                   git=\$HOME/src/btr.git"
+       echo
+       echo "    Note though, that some rules do not use any argument."
+       echo
+       echo "  Rulesets:"
+       for ruleset in source build report
+       do
+               printf "    %10s: %s\n" $ruleset \
+                       "$(find "$BTR_LIBDIR/$ruleset" -name '*.mk' -exec basename {} .mk \; | sort | xargs)"
+       done
+       echo
+       fi
+       exit
+}
+export -f btr_help
+
+function btr_parseopts {
+       local shortoptions="$(btr_shortoptions common btr-flags btr-options)"
+       local longoptions="$(btr_longoptions common btr-flags btr-options)"
+       local options
+
+       options=$(@GETOPT@ \
+               --name $BTR_PROG \
+               --options "$shortoptions" \
+               --longoptions "$longoptions" \
+               -- "$@" \
+       )
+       if test $? -ne 0
+       then
+               btr-help
+       fi
+
+       eval set -- "$options"
+
+       while test $# -gt 0
+       do
+               case "$1" in
+                       -h|--help)
+                               btr_banner
+                               btr_help
+                               ;;
+                       -v|--verbose)
+                               BTR_QUIET=false
+                               BTR_VERBOSE=true
+                               ;;
+                       -q|--quiet)
+                               BTR_QUIET=true
+                               BTR_VERBOSE=false
+                               ;;
+                       -y|--yes)
+                               BTR_FORCEYES=true
+                               ;;
+                       -c|--clean)
+                               BTR_BUILD_CLEAN=true
+                               ;;
+                       -C|--vcsclean)
+                               BTR_SOURCE_CLEAN=true
+                               ;;
+                       ####
+                       -f|--config)
+                               source "$2"
+                               shift
+                               ;;
+                       ####
+                       -B|--branch)
+                               BTR_BRANCH="$2"
+                               shift
+                               ;;
+                       -D|--directory)
+                               BTR_RUNDIR="$2"
+                               shift
+                               ;;
+                       -S|--suffix)
+                               BTR_SUFFIX="$2"
+                               shift
+                               ;;
+                       -T|--test)
+                               BTR_TEST_ARGS="$2"
+                               shift
+                               ;;
+                       ####
+                       -s|--source)
+                               case "$2" in
+                               git*)
+                                       test -z "$BTR_BRANCH" && BTR_BRANCH=master
+                                       ;;
+                               svn*)
+                                       test -z "$BTR_BRANCH" && BTR_BRANCH=trunk
+                                       ;;
+                               cvs*)
+                                       test -z "$BTR_BRANCH" && BTR_BRANCH=HEAD
+                                       ;;
+                               esac
+                               BTR_SOURCE_RULES="$(cut -d= -f1 <<<$2)"
+                               BTR_SOURCE_ARGS="$(cut -s -d= -f2- <<<$2)"
+                               shift
+                               ;;
+                       -b|--build)
+                               BTR_BUILD_RULES="$(cut -d= -f1 <<<$2)"
+                               BTR_BUILD_ARGS="$(cut -s -d= -f2- <<<$2)"
+                               shift
+                               ;;
+                       -r|--report)
+                               BTR_REPORT_RULES="$(cut -d= -f1 <<<$2)"
+                               BTR_REPORT_ARGS="$(cut -s -d= -f2- <<<$2)"
+                               shift
+                               ;;
+                       ####
+                       --)
+                               shift
+                               BTR_EXTRA_ARGS="$@"
+                               break
+                               ;;
+               esac
+               shift
+       done
+}
+export -f btr_parseopts
+
+function btr_conf_dump {
+       echo "BTR_QUIET='$BTR_QUIET'"
+       echo "BTR_VERBOSE='$BTR_VEROSE'"
+       echo "BTR_FORCEYES='$BTR_FORCEYES'"
+       echo "BTR_BRANCH='$BTR_BRANCH'"
+       echo "BTR_SUFFIX='$BTR_SUFFIX'"
+       echo "BTR_RUNDIR='$BTR_RUNDIR'"
+       echo "BTR_SOURCE_RULES='$BTR_SOURCE_RULES'"
+       test ${BTR_SOURCE_ARGS+defined} && echo "BTR_SOURCE_ARGS='$BTR_SOURCE_ARGS'"
+       test ${BTR_SOURC_CLEAN+defined} && echo "BTR_SOURCE_CLEAN='$BTR_SOURCE_CLEAN'"
+       echo "BTR_BUILD_RULES='$BTR_BUILD_RULES'"
+       test ${BTR_BUILD_ARGS+defined}  && echo "BTR_BUILD_ARGS='$BTR_BUILD_ARGS'"
+       test ${BTR_BUILD_CLEAN+defined} && echo "BTR_BUILD_CLEAN='$BTR_BUILD_CLEAN'"
+       test ${BTR_TEST_ARGS+defined}   && echo "BTR_TEST_ARGS='$BTR_TEST_ARGS'"
+       echo "BTR_REPORT_RULES='$BTR_REPORT_RULES'"
+       test ${BTR_REPORT_ARGS+defined} && echo "BTR_REPORT_ARGS='$BTR_REPORT_ARGS'"
+}
+export -f btr_conf_dump
+
+# vim: noet
diff --git a/share/btr/opt.awk b/share/btr/opt.awk
deleted file mode 100755 (executable)
index cdc0b76..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/awk -f
-
-BEGIN {
-       FS="\t"
-}
-
-{
-       sub("[[:space:]]*#.*", "");
-       if (NF) {
-               if (sub("::", "[=<", $2)) {
-                       $2 = $2">]"
-               }
-               if (sub(":", "=<", $2)) {
-                       $2 = $2">"
-               }
-               sub(":+", "", $1)
-               printf "    -%s, --%-24s %s\n", $1, $2, $3
-       }
-}
diff --git a/share/btr/opt.awk.in b/share/btr/opt.awk.in
new file mode 100755 (executable)
index 0000000..e9ed958
--- /dev/null
@@ -0,0 +1,21 @@
+#!@AWK_PATH@ -f
+
+BEGIN {
+       FS="\t"
+}
+
+{
+       sub("[[:space:]]*#.*", "");
+       if (NF) {
+               if (sub("::", "[=<", $2)) {
+                       $2 = $2">]"
+               }
+               if (sub(":", "=<", $2)) {
+                       $2 = $2">"
+               }
+               sub(":+", "", $1)
+               printf "    -%s, --%-24s %s\n", $1, $2, $3
+       }
+}
+
+# vim: noet