1#!/bin/sh
2
3set -e
4
5error() {
6  echo >&2 "$0: error: $@"
7}
8
9fatal_error() {
10  error "$@"
11  exit 1
12}
13
14is_set() {
15  ( eval [ "\"\${$1+set}\"" = "set" ] )
16}
17
18show_usage() {
19cat <<EOT
20Usage: $0 [OPTION]... [VAR=VALUE]...
21
22This script creates necessary configuration files to build/install.
23
24To assign environment variables (e.g., CC, CFLAGS...), specify them as
25VAR=VALUE.  See below for descriptions of some of the useful variables.
26
27Defaults for the options are specified in brackets.
28
29Main options:
30  -h, --help             display this help and exit
31  --prefix=[path]        base path [/usr/local]
32  --bindir=DIR           user executables [PREFIX/bin]
33  --sbindir=DIR          system admin executables [PREFIX/sbin]
34  --libdir=DIR           object code libraries [PREFIX/lib]
35  --scriptdir=DIR        script type plugins [LIBDIR/vlock/scripts]
36  --moduledir=DIR        module type plugins [LIBDIR/vlock/modules]
37  --mandir=DIR           man documentation [PREFIX/share/man]
38
39Optional Features:
40  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
41  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
42  --enable-plugins        enable plugin support [enabled]
43  --enable-pam            enable PAM authentication [enabled]
44  --enable-shadow         enable shadow authentication [disabled]
45  --enable-root-password  enable unlogging with root password [enabled]
46  --enable-debug          enable debugging
47
48Additional configuration:
49  --with-scripts=SCRIPTS  enable the named scripts []
50  --with-modules=MODULES  enable the named modules [<architecture depedent>]
51
52Some influential environment variables:
53  CC            C compiler command
54  CFLAGS        C compiler flags
55  EXTRA_CFLAGS  additional C compiler flags (extends default)
56  LDFLAGS       linker flags, e.g. -L<lib dir> if you have libraries in a
57                nonstandard directory <lib dir>
58  EXTRA_LDFLAGS additional linker flags (extends default)
59  VLOCK_GROUP   group for restricted modules (default: vlock)
60  VLOCK_MODE    mode for restricted modules (default: 0750)
61
62Use these variables to override the choices made by \`configure' or to help
63it to find libraries and programs with nonstandard names/locations.
64
65Report bugs to <frank-vlock@benkstein.net>.
66EOT
67}
68
69set_variable() {
70  eval "$1"='"$2"'
71}
72
73enable_feature() {
74  case "$1" in
75    plugins)
76      ENABLE_PLUGINS="$2"
77    ;;
78    root-password)
79      ENABLE_ROOT_PASSWORD="$2"
80    ;;
81    pam|shadow)
82      if [ "$2" = "yes" ] ; then
83        if [ -n "$auth_method" ] && [ "$auth_method" != "$1" ] ; then
84          fatal_error "pam and shadow authentication are mutually exclusive"
85        fi
86        AUTH_METHOD="$1"
87      else
88        fatal_error "cannot disable authentication"
89      fi
90    ;;
91    debug)
92      if [ "$2" = "yes" ] ; then
93        CFLAGS="${DEBUG_CFLAGS}"
94      else
95        CFLAGS="${DEFAULT_CFLAGS}"
96      fi
97    ;;
98    *)
99      fatal_error "invalid feature name: $1"
100    ;;
101  esac
102}
103
104parse_arguments() {
105  local feature opt optarg
106
107  while [ $# -gt 0 ] ; do
108    if ! opt=`expr "x$1" : 'x\([^=]*\)=.*'` ; then
109      opt="$1"
110    fi
111
112    if ! optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` ; then
113      optarg=""
114    fi
115
116    case "$1" in
117      --disable-*)
118        feature=`expr "x$1" : 'x--disable-\(.*\)'`
119        enable_feature "$feature" no
120        shift
121      ;;
122      --enable-*=no)
123        feature=`expr "x$1" : 'x--enable-\(.*\)=no'`
124        enable_feature "$feature" no
125        shift
126      ;;
127      --enable-*=yes)
128        feature=`expr "x$1" : 'x--enable-\(.*\)=yes'`
129        enable_feature "$feature" yes
130        shift
131      ;;
132      --enable-*)
133        feature=`expr "x$1" : 'x--enable-\(.*\)'`
134        enable_feature "$feature" yes
135        shift
136      ;;
137      *=*)
138        shift
139        # unshift
140        set -- "$opt" "$optarg" "$@"
141      ;;
142      --prefix)
143        PREFIX="$2"
144        shift 2 || fatal_error "$1 argument missing"
145      ;;
146      --bindir)
147        BINDIR="$2"
148        shift 2 || fatal_error "$1 argument missing"
149      ;;
150      --sbindir)
151        SBINDIR="$2"
152        shift 2 || fatal_error "$1 argument missing"
153      ;;
154      --libdir)
155        LIBDIR="$2"
156        shift 2 || fatal_error "$1 argument missing"
157      ;;
158      --moduledir)
159        MODULEDIR="$2"
160        shift 2 || fatal_error "$1 argument missing"
161      ;;
162      --scriptdir)
163        SCRIPTDIR="$2"
164        shift 2 || fatal_error "$1 argument missing"
165      ;;
166      --mandir)
167        MANDIR="$2"
168        shift 2 || fatal_error "$1 argument missing"
169      ;;
170      --with-modules)
171        MODULES="$2"
172        shift 2 || fatal_error "$1 argument missing"
173      ;;
174      --with-scripts)
175        SCRIPTS="$2"
176        shift 2 || fatal_error "$1 argument missing"
177      ;;
178      EXTRA_CFLAGS)
179        CFLAGS="${CFLAGS} $2"
180        shift 2 || fatal_error "$1 value missing"
181      ;;
182      EXTRA_LDFLAGS)
183        LDFLAGS="${LDFLAGS} $2"
184        shift 2 || fatal_error "$1 value missing"
185      ;;
186      [A-Z]*)
187        set_variable "$1" "$2"
188        shift 2 || fatal_error "$1 value missing"
189      ;;
190      --quiet)
191        verbose=0
192        shift
193      ;;
194      --help|-h)
195        show_usage
196        exit
197      ;;
198      -*)
199        error "unrecognized option: $1"
200        echo >&2 "Try \`$0 --help' for more information."
201        exit 1
202      ;;
203      *)
204        error "invalid argument: $1"
205        echo >&2 "Try \`$0 --help' for more information."
206        exit 1
207      ;;
208    esac
209  done
210}
211
212set_defaults() {
213  # architecture independent defaults
214  PREFIX="/usr/local"
215  BINDIR="\$(PREFIX)/bin"
216  SBINDIR="\$(PREFIX)/sbin"
217  LIBDIR="\$(PREFIX)/lib"
218  MANDIR="\$(PREFIX)/share/man"
219  SCRIPTDIR="\$(LIBDIR)/vlock/scripts"
220  MODULEDIR="\$(LIBDIR)/vlock/modules"
221
222  #CC=gcc
223  DEFAULT_CFLAGS="-O2 -Wall -W -pedantic -std=gnu99"
224  DEBUG_CFLAGS="-O0 -g -Wall -W -pedantic -std=gnu99"
225  #CFLAGS="${DEFAULT_CFLAGS}"
226  #LD=ld
227  #LDFLAGS=""
228  AUTH_METHOD="pam"
229  ENABLE_ROOT_PASSWORD="yes"
230  ENABLE_PLUGINS="yes"
231  SCRIPTS=""
232
233  VLOCK_GROUP="vlock"
234  VLOCK_MODULE_MODE="0750"
235
236  BOURNE_SHELL="/bin/sh"
237
238  # architecture dependent defaults
239  OS=`uname`
240
241  for make in make gmake ; do
242    if $make -f /dev/null -q -v 2>/dev/null | head -n 1 | grep -q "GNU Make" ; then
243      MAKE="$make"
244      break
245    fi
246  done
247
248  ROOT_GROUP=`getent group | awk -F: '$3 == 0 { print $1 ; exit }'`
249
250  case "$OS" in
251    Linux)
252      PAM_LIBS='-ldl -lpam'
253      DL_LIB='-ldl'
254      CRYPT_LIB='-lcrypt'
255      MODULES="all.so new.so nosysrq.so"
256    ;;
257    GNU/kFreeBSD)
258      PAM_LIBS='-ldl -lpam'
259      DL_LIB='-ldl'
260      CRYPT_LIB='-lcrypt'
261      MODULES="all.so new.so"
262    ;;
263    FreeBSD)
264      PAM_LIBS='-lpam'
265      DL_LIB=''
266      CRYPT_LIB=''
267      MODULES="all.so new.so"
268    ;;
269  esac
270}
271
272parse_config_mk() {
273  local tmpdir
274
275  if [ -z "$MAKE" ] ; then
276    error "GNU make not found"
277    echo >&2 "Set MAKE environment variable to specify alternative."
278    exit 1
279  fi
280
281  tmpdir=`mktemp -d -t vlock-configure.XXXXXX`
282
283  $MAKE -rR -f config.mk -p -q . 2>/dev/null | awk > "$tmpdir/config.mk" '
284    /^# makefile/ { p=1; next }
285    /^#/ { p=0; next }
286    p==1 && $1 != "MAKEFILE_LIST" && /^[A-Za-z_]+ :?= .*/ { print }
287  '
288
289  while read line
290  do
291    variable_name=`expr "x${line}" : 'x\([[[:alpha:]_]\{1,\}\) :\{0,1\}='`
292    if variable_value=`expr "x${line}" : 'x[[:alpha:]_]\{1,\} :\{0,1\}= \(.*\)'` ; then
293      set_variable "$variable_name" "$variable_value"
294    else
295      set_variable "$variable_name" ""
296    fi
297  done < "$tmpdir/config.mk"
298
299  rm -rf "$tmpdir"
300}
301
302show_summary() {
303  cat <<EOF
304vlock configuration
305
306directories:
307  prefix:     $PREFIX
308  bindir:     $BINDIR
309  sbindir:    $SBINDIR
310  libdir:     $LIBDIR
311  mandir:     $MANDIR
312  scriptdir:  $SCRIPTDIR
313  moduledir:  $MODULEDIR
314
315features:
316  enable plugins: $ENABLE_PLUGINS
317  root-password:  $ENABLE_ROOT_PASSWORD
318  auth-method:    $AUTH_METHOD
319  modules:        $MODULES
320  scripts:        $SCRIPTS
321
322build configuration:
323
324  operating system: $OS
325  gnu make:         $MAKE
326  c compiler:       $CC
327  compiler flags:   $CFLAGS
328  linker flags      $LDFLAGS
329  pam libs:         $PAM_LIBS
330  dl libs:          $DL_LIB
331  crypt lib:        $CRYPT_LIB
332
333installation configuration:
334  root group:       $ROOT_GROUP
335  vlock group:      $VLOCK_GROUP
336EOF
337}
338
339create_config_mk() {
340  cat > config.mk <<EOF
341# automatically generated by $0 on $(date)
342
343### configuration options ###
344
345# authentification method (pam or shadow)
346AUTH_METHOD = ${AUTH_METHOD}
347# also prompt for the root password in adition to the user's
348ENABLE_ROOT_PASSWORD = ${ENABLE_ROOT_PASSWORD}
349# enable plugins for vlock-main
350ENABLE_PLUGINS = ${ENABLE_PLUGINS}
351# which plugins should be build
352MODULES = ${MODULES}
353# which scripts should be installed
354SCRIPTS = ${SCRIPTS}
355
356# root's group
357ROOT_GROUP = ${ROOT_GROUP}
358
359# group for privileged plugins
360VLOCK_GROUP = ${VLOCK_GROUP}
361# mode for privileged plugins
362VLOCK_MODULE_MODE = ${VLOCK_MODULE_MODE}
363
364### paths ###
365
366# installation prefix
367PREFIX = ${PREFIX}
368BINDIR = ${BINDIR}
369SBINDIR = ${SBINDIR}
370LIBDIR = ${LIBDIR}
371MANDIR = ${MANDIR}
372# installation root
373DESTDIR =
374# path where modules will be located
375MODULEDIR = ${MODULEDIR}
376# path where scripts will be located
377SCRIPTDIR = ${SCRIPTDIR}
378
379### programs ###
380
381# shell to run vlock.sh with (only bash is known to work)
382BOURNE_SHELL = ${BOURNE_SHELL}
383# C compiler
384CC = ${CC}
385# linker
386LD = ${LD}
387# mkdir
388MKDIR_P = mkdir -p
389# install
390INSTALL = install
391
392### compiler and linker settings ###
393
394# C compiler flags
395CFLAGS = ${CFLAGS}
396# linker flags
397LDFLAGS = ${LDFLAGS}
398# linker flags needed for dlopen and friends
399DL_LIB = ${DL_LIB}
400# linker flags needed for crypt
401CRYPT_LIB = ${CRYPT_LIB}
402# linker flags needed for pam
403PAM_LIBS = ${PAM_LIBS}
404EOF
405}
406
407main() {
408  verbose=1
409
410  set_defaults
411  parse_config_mk
412  parse_arguments "$@"
413
414  if [ "$verbose" -ge 1 ] ; then
415    show_summary
416  fi
417
418  create_config_mk
419}
420
421main "$@"
422