#!/bin/sh
# Wireless Leiden proxy config-update script for FreeBSD 8.0 (nanobsd)
# Based on the 'API' of Jasper
# Rick van der Zwet ; Richard van Mansom
# XXX: TODO, some proper error checking for fetch

BASEURL="http://132.229.112.21/config/iris/proxy/FreeBSD/8.0-RELEASE/g_list.pl"

# Default config to fetch
CONFIG=`hostname -s | tr '[A-Z]' '[a-z]'`

# Determine it's statup and running location and some other hints
# Skip named.conf as it not planned in current release
FILES="authorized_keys rc.conf.local resolv.conf"
file_details() {
  case "$1" in 
  'authorized_keys')
     STARTUP_LOC="/cfg/dot_ssh/${FILE}"
     RUNNING_LOC="/etc/dot_ssh/${FILE}"
     FILE_HINT=""
   ;;
  'rc.conf.local')
     STARTUP_LOC="/cfg/${FILE}"
     RUNNING_LOC="/etc/${FILE}"
     FILE_HINT="/etc/rc.d/netif restart"
   ;;
   'resolv.conf')
     STARTUP_LOC="/cfg/${FILE}"
     RUNNING_LOC="/etc/${FILE}"
     FILE_HINT=""
   ;;
  esac
}

usage() {
	(
	echo "Usage: $0 [-bn] [-c <config>] [-m <all|startup|testing|running>]"
	echo "	-b		batch mode, no user input"
	echo "	-c <config>   	default configuration to fetch"
	echo "	-n		do not mount config partition"
	echo "	-m all    	copy config files to running & config partition [default]"
	echo "	-m startup	copy config files to config partition"
	echo "	-m testing    	do not copy config files"
	echo "	-m running   	copy config files to running partition"
	echo "	-m hack   	copy  running files to config partition"
	) 1>&2
	exit 2
}

# Argument parsing using getopts
USE_API=1		# Whether or not to use the webinterface
OPT_MOUNT=1
OPT_RUNNING=1
OPT_STARTUP=1
OPT_HACK=0		# Hack for people without configuration managment and testing
OPT_BATCH=0

parse_options() {
  while getopts "bc:nm:" OPT; do
  	case "$OPT" in
  	b) OPT_BATCH=1;;
  	c) CONFIG="${OPTARG}";;
  	n) OPT_MOUNT=0;;
  	m) case "$OPTARG" in
  	   all) true;;
  	   live) OPT_STARTUP=0;;	
  	   startup) OPT_RUNNING=0;;		
  	   testing) OPT_RUNNING=0; OPT_STARTUP=0; OPT_MOUNT=0;;		
  	   hack) OPT_RUNNING=0; OPT_STARTUP=0; OPT_HACK=1; USE_API=0;;		
  	   *) usage;;
  	   esac;;
  	h) usage;;
  	\?) usage;;
  	esac
  done
  # Allow to override automatic mounting, in case of external mount 'managment'
  if [ "$1" = "-n" ]; then
  	OPT_MOUNT=0
  fi
  
  if [ "${OPT_RUNNING}" -eq 1 ]; then
    echo "INFO: Storing new config files in running configuration"
  fi
  
  if [ "${OPT_STARTUP}" -eq 1 ]; then
    echo "INFO: Storing new config files in startup configuration"
  fi
  
  if [ "${OPT_HACK}" -eq 1 ]; then
    echo "WARN: Copy running configuration to startup configuration"
    echo "WARN: Please do mind to document/mention this changes somewhere"
  fi

  # New line before the real work gets started
  echo "" 
}




# test validity of input
config_validator() {
  INPUT="$1"
  `grep -q "^${INPUT}\$" ${TMPDIR}/node_list.txt`
  if [ $? -eq 0 ]; then
    return 0
  else 
     echo "WARNING: Input '${INPUT}' is not valid, some hints..."
     grep "${INPUT}" ${TMPDIR}/node_list.txt
     return 1
  fi  
}



select_node() {
  # List of all available nodes
  fetch -q -o ${TMPDIR}/node_list.txt ${BASEURL} || exit 1
  
  # Provide Nodelist and feedback
  cat ${TMPDIR}/node_list.txt | column
  echo '       THIS script adds the config from GENESIS to this operating system'
  echo '       make sure you know what you are doing, if not press control-C'
  echo '       ENTER CONFIG NAME  ......(and press enter)'

  if [ ${OPT_BATCH} -eq 1 ]; then
    config_validator "${CONFIG}"
   if [ $? -eq 1 ]; then
     echo "ERROR: Please provide valid config" 1>&2
     exit 1
   fi
  else
    # Have the user to select the right node
    INVALID_CONFIG=1
    while [ ${INVALID_CONFIG} -eq 1 ]; do
      # Ask for node name, play around with prev option
      echo -n "Name [${CONFIG}]: "
      read INPUT
      if [ -z "${INPUT}" ]; then
        INPUT=${CONFIG}
      else
        CONFIG=${INPUT}
      fi
    
      config_validator "${INPUT}"
      if [ $? -eq 0 ]; then
         INVALID_CONFIG=0
      fi  
    done
  fi
}




# Copy file, saving some bits if no change needed
copy_file() {
  SOURCE=$1
  TARGET=$2
  diff -q ${SOURCE} ${TARGET} >/dev/null 2>/dev/null
  if [ $? -ne 0 ]; then
    mkdir -p `dirname ${TARGET}` || exit 1
    cp ${SOURCE} ${TARGET} || exit 1
    return $?
  fi
  return 1
}

# Main function
main() {
  TMPDIR=`mktemp -d -t $(basename $0)`
  # Clear out tempdir when done
  if [ ${OPT_MOUNT} -eq 1 ]; then
  	trap "rm -Rf ${TMPDIR}; umount /cfg; mount -ro noatime /; exit" 0 1 2 3 15
  else
  	trap "rm -Rf ${TMPDIR}; exit" 0 1 2 3 15
  
  fi
  
  # Mount if requested
  if [ ${OPT_MOUNT} -eq 1 ]; then
  	mount -uwo noatime /
  	mount /cfg
  fi

  # Select node from web-interface
  if [ ${USE_API} -eq 1 ]; then
  	select_node
  fi
  
  # Worker, place all files in required directory
  for FILE in ${FILES}; do
    if [ ${USE_API} -eq 1 ]; then
      # Fetch needed file
      FRESH_LOC=${TMPDIR}/${FILE}
      fetch -q -o ${FRESH_LOC} ${BASEURL}/${CONFIG}/${FILE} || exit 1
    fi
  
    # Needed file details, like locations and hints
    file_details ${FILE}
  
    echo "INFO: Working on file: '${FILE}'"
    # Copy file boot location
    if [ ${OPT_STARTUP} -eq 1 ]; then
      copy_file ${FRESH_LOC} ${STARTUP_LOC}
    fi
  
    # Copy file running location
    if [ ${OPT_RUNNING} -eq 1 ]; then
      copy_file ${FRESH_LOC} ${RUNNING_LOC}
      if [ $? -eq 0 ]; then
        echo "INFO: '${FILE}' changed"  
        if [ -n "${FILE_HINT}" ]; then
          echo "INFO: For instant activate: ${FILE_HINT}"
          echo ""
        fi
      fi
    fi
  
    # Direct copy
    if [ ${OPT_HACK} -eq 1 ]; then
      # No checking, just dumb try to copy mode
      cp -v ${RUNNING_LOC} ${STARTUP_LOC}
    fi
  done
  
  exit 0
}

parse_options $*
main