#!/bin/sh
#########
## act like debianutils tempfile program
## Usage: tempfile [OPTION]
## 
## Create a temporary file in a safe manner.
## 
## -d, --directory=DIR  place temporary file in DIR
## -p, --prefix=STRING  set temporary file's prefix to STRING
## -s, --suffix=STRING  set temporary file's suffix to STRING
## -m, --mode=MODE      open with MODE instead of 0600
## -n, --name=FILE      use FILE instead of tempnam(3)
##     --help           display this help and exit
##     --version        output version information and exit
######
### tempfile.sh 0.1  (supposed to be like debianutils tempfile 2.6)
### Copyright (c) 2003 by Adam Katz <scripts@khopis.com>, GPL
######
#### Differences between this and debianutils tempfile 2.6:
#### - error messages: rather than mimic debian, use touch/chmod errors.
#### - argument leniency: we accept -p=x & -prefix=x & --prefixx on all flags
####   and any flag starting with an 'h' gives help.  also use -V for version.
#### - this creates a file and then removes it if permissions can't be set.
######
#### Surprises in design of debianutils tempfile 2.6, noted by "(!)" in code:
#### - environment variable $TMPDIR overrides --directory
#### - specified directory (and $TMPDIR) ignored if it does not exist
#### - arguments that do not start with a dash are completely ignored
######
#### Caveats:
#### - sh is rather limited: can't abstract shift or exit (or logic for them)
#########

prefix="file"
dir="/tmp"
try_help="Try \`tempfile --help' for more information."

needs_help() {
  printf "tempfile: option \`$1' requires an argument\n$try_help\n" >&2
}

get_arg() { 
  echo "$1" |sed -re "s/^-*[a-z]($2)?=?//i";
}

while [ -n "$1" ]; do
  case $1 in

    -h* | --h* )  # help
      grep '^## ' `which $0 | echo $0` |sed 's/^...//'
      exit 0
      ;;
    -V | --v* )   # version
      grep '^### ' `which $0 | echo $0` |sed 's/^....//'
      exit 0
      ;;
    -d* | --d* )  # directory
      newdir=`get_arg $1 irectory`
      [ -z "$newdir" ] && newdir="$2" && \
        if [ -n "$newdir" ]; then shift; else needs_help $1; exit 1; fi
      [ -d "$dir" ] && dir="$newdir"  # ignore bad and non-existant dirs (!)
      ;;
    -p* | --p* )  # prefix
      prefix=`get_arg $1 refix`
      [ -z "$prefix" ] && prefix="$2" && \
        if [ -n "$prefix" ]; then shift; else needs_help $1; exit 1; fi
      ;;
    -s* | --s* )  # suffix
      suffix=`get_arg $1 uffix`
      [ -z "$suffix" ] && suffix="$2" && \
        if [ -n "$suffix" ]; then shift; else needs_help $1; exit 1; fi
      ;;
    -m* | --m* )  # mode (permissions)
      mode=`get_arg $1 ode`
      [ -z "$mode" ] && mode="$2" && \
        if [ -n "$mode" ]; then shift; else needs_help $1; exit 1; fi
      ;;
    -n* | --n* )  # explicit name
      name=`get_arg $1 ame`
      [ -z "$name" ] && name="$2" && \
        if [ -n "$name" ]; then shift; else needs_help $1; exit 1; fi
      [ -f "$name" ] && echo "tempfile: File exists" >&2 && exit 1
      ;;
    -* )          # bad argument
      printf "tempfile: unrecognized option \`$1'\n$try_help\n" >&2
      exit 1
      ;;
    * )           # ignore arguments that aren't flags (!)
      ;;

  esac
  shift
done

[ -d "$TMPDIR" ] && dir="$TMPDIR"  # override directory flag (!)

[ -r "/dev/urandom" ] && rand=/dev/urandom || rand=/dev/random

while [ -z "$name" ]; do

  temp=`head $rand |strings`
  temp=`echo $temp |sed 's/[^A-Za-z0-9]//g' |head -c6`  # 56.8 billion combos
  temp="$dir/$prefix$temp$suffix"
  if [ -f "$temp" ] || [ -d "$temp" ] # takes a long time w/ LOTS of tempfiles
    then continue
  fi
  name="$temp"

done

touch "$name" || exit $?
if [ -n "$mode" ]
  then
    chmod $mode "$temp"
    RETURN="$?"
    [ "$RETURN" != "0" ] && rm -f "$name" && exit $RETURN
  else  # don't care if the default mode fails
    chmod 0600 "$name" >/dev/null 2>&1
fi
echo "$name"
exit 0
