#!/bin/bash
# Copyright (C) by Stefano Falsetto
# e-mail contact ....: mailto:stefko5@inwind.it
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or   
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of 
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
#
# This script edit configuration files for rot[t]log
#
#

# Don't allow pressing CTRL+C (or sending SIGINT) during TEMPDIR generation
trap '' 2

# Following code is taken from:
# checkinstall v1.4.1 (c) Felipe Eduardo Sanchez Diaz Duran
# (with little changes)

# Find a safe TEMPDIR
BASE_TMP_DIR="/tmp"
TEMPDIR=${BASE_TMP_DIR}/`awk 'BEGIN { srand(); for (i=1;i<21;i++) { a=95; while
(a > 90 && a < 97) { a=65+int(50*rand())}; printf("%c", a) } }'`
[ -e "$TEMPDIR" ] && rm -rf $TMP_DIR
if [ -e "$TEMPDIR" ]; then
   echo
   echo "My temp dir exists already."
   echo "This looks like a symlink attack!"
   echo
   echo "*** Aborting"
   echo
   exit 1
fi

mkdir $TEMPDIR
chmod 1700 $TEMPDIR
RETURN=$?

if [ $RETURN -gt 0 ]; then
   echo
   echo "**** Failed to create temp dir!"
   echo "**** Do you have write permission for ${BASE_TMP_DIR}?"
   echo
   echo '**** Aborting execution.'
   echo
   exit  $RETURN
fi

# Original code from stefko begin here :-)

TMPFIL=$TEMPDIR/rotttempfile.$$
NEWtmpFILE=$TEMPDIR/rottnewtmpfile.$$
trap 'rm -Rf $TEMPDIR ; exit $USCITA' 0 2

MAINRC="/etc/rottlog/rc"
MONTRC="/etc/rottlog/monthly"
WEEKRC="/etc/rottlog/weekly"
DAYRC="/etc/rottlog/daily"

syn_error() {
  echo "Syntax line $nline: $3"
  echo ">>> $2"
  while [ 0 ]; do
    echo "Press ENTER to re-edit config file"
    echo "Press CTRL+C to break process and undo last changes..."
    read Q
    if [ "$Q" = "" ]; then
      return
    fi
  done</dev/stdout
}

to_skip () {
  if [ $(expr "$1" : "[[:space:]]*#.*") -ne 0 ] || \
     [ "$(echo "$1"|tr -d ' ')" = "" ]; then
    return 1
  fi
  return 0
}
      
check_rc () {
  local esci=0
  local KEYS="|packer|compress|packdir|fromuser|touser|notifempty|ifempty|mail|unpacker|uncompress|pager|extension|"
  if [ -e $MAINRC ]; then
    chmod 600 $MAINRC
    cp -f $MAINRC $NEWtmpFILE
    chmod 600 $NEWtmpFILE
  fi
  
  while [ $esci -ne 1 ]; do
    $ED $NEWtmpFILE
    echo "Checking syntax..."
    nline=0
    ERROR=
    while read line; do
      nline=$[ nline + 1 ]
      to_skip "$line"
      if [ $? -eq 1 ]; then
        continue
      fi
      if [ $(expr "$line" : ".*=.*") -eq 0 ]; then
        syn_error $nline "$line" "Invalid syntax"
        ERROR=1
        break
      fi
      KEY="$(echo "$line"|cut -d'=' -f1)"
      VALUE="$(echo "$line"|cut -d'=' -f2)"
      if [ -z "$VALUE" ]; then
        syn_error $nline "$line" "Zero value to $KEY"
        ERROR=1
        break
      fi
      if [ $(expr "$KEYS" : ".*|$KEY|.*") -eq 0 ]; then
        syn_error $nline "$line" "Unknown keyword"
        ERROR=1
        break
      fi
    done<$NEWtmpFILE
    if [ -z "$ERROR" ]; then
      esci=1
    fi
  done
  echo "Done."
  install_rc "$MAINRC"
}

ltrim () {
  left=0
  while [ "${1:$left:1}" = " " ]; do
    left=$[ left + 1 ]
  done
  local tmp=${1//\"/\\\"}
  eval "$2=\"${tmp:$left}\""
}

rtrim () {
  right=${#1}
  while [ "${1:$right-1:1}" = " " ]; do
    right=$[ right - 1 ]
  done
  eval "$2=\"${1:0:$right}\""
}

check_mdy () {

  if [ -e $"$1" ]; then
    chmod 600 "$1"
    cp -f "$1" $NEWtmpFILE
    chmod 600 $NEWtmpFILE
  fi

  local esci=0
  local OPEN_BRACKET=
  local KEY0P="|nocompress|postrotate|prerotate|endscript|delaycompress|ifempty|notifempty|nomail|"
  local KEY1P="|storedir|logpart|touser|rotate|"
  local KEY2P=""
  local KEY3P="|create|"
  
  while [ $esci -ne 1 ]; do
    $ED $NEWtmpFILE
    echo "Checking syntax..."
    nline=0
    ERROR=
    OPEN_BRACKET=
    SCRIPT=
    if [ -s "$NEWtmpFILE" ]; then
      while read line; do
        nline=$[ nline + 1 ]
        to_skip "$line"
        if [ $? -eq 1 ]; then
          continue
        fi
        ltrim "$line" line
        if [ ! -z "$SCRIPT" ] && [ "$line" != "endscript" ]; then 
          continue
        fi
        if [ -z "$OPEN_BRACKET" ] && [ $(expr "$line" : ".*{") -eq 0 ]; then
          syn_error $nline "$line" "Invalid syntax"
          ERROR=1
          break
        elif [ -z "$OPEN_BRACKET" ] && [ $(expr "$line" : ".*{") -ne 0 ]; then
          OPEN_BRACKET=1
          FILES=$(echo "$line"|cut -d'{' -f1)
          OLDIFS="$IFS"
          IFS=","
          for i in "$FILES"; do
            rtrim "$i" i
            if [ ! -r "$i" ]; then
              echo "WARNING: Logfile is not readable or not exists"
              echo "> $i"
            fi
          done
          IFS="$OLDIFS"
          continue
        fi
        if [ "$line" = "}" ]; then 
          OPEN_BRACKET=
          continue
        fi
        KEY=$(echo "$line"|cut -d' ' -f1)
        VALUE=$(echo "$line"|cut -d' ' -f2-)
        [ "$KEY" = "$VALUE" ] && VALUE=
  
        if [ $(expr "$KEY0P|$KEY1P|$KEY2P|$KEY3P" : ".*|$KEY|.*") -eq 0 ]; then
          syn_error $nline "$line" "Unknown keyword"
          ERROR=1
          break
        fi
        if [ -z "$VALUE" ] && [ $(expr "$KEY0P" : ".*|$KEY|.*") -eq 0 ]; then
          syn_error $nline "$line" "Syntax error"
          ERROR=1
          break
        fi
        if [ ! -z "$VALUE" ] && \
           [ $(expr "$KEY1P|$KEY2P|$KEY3P" : ".*|$KEY|.*") -eq 0 ]; then
          syn_error $nline "$line" "Syntax error"
          ERROR=1
          break
        fi
        if [ "$line" = "prerotate" ] || [ "$line" = "postrotate" ]; then
          SCRIPT=1
        fi
        if [ "$line" = "endscript" ]; then 
          SCRIPT=
        fi
        
      done<$NEWtmpFILE
    fi
    if [ -z "$ERROR" ]; then
      esci=1
    fi
  done
  echo "Done."
  install_rc "$1"
}

install_rc () {
  if [ -s "$NEWtmpFILE" ]; then 
    echo "Installing new configuration file..."
    cp -f $NEWtmpFILE "$1"
    chmod 0600 "$1"
    echo "Done."
  else
    rm -f "$1"
  fi 
}

##############################################################################
# MAIN 
##############################################################################

if [ ! -z "$VISUAL" ]; then
  ED=$VISUAL
elif [ ! -z "$EDITOR" ]; then
  ED=$EDITOR
else
  ED=vi
fi


PRGNAME="$(basename $0)"
case "$PRGNAME" in
  virottrc) 
               check_rc 
               ;;
  virottmonth)
               check_mdy "$MONTRC"
               ;;
  virottweek)
               check_mdy "$WEEKRC"
               ;;
  virottday)
               check_mdy "$DAYRC" 
               ;;
  *)
               echo "ERROR!"
               exit 3
               ;;
esac

