#! /bin/sh
#
# exim-config, Copyright Pierre A. Humblet, Dec 2003.
#
# This file is part of the Cygwin port of exim.

#set -x

#############################
# Useful subroutine
#############################
request()
{
  while true
  do
    echo -n "$1 (yes/no) "
    if read answer
      then
      if [ "${answer}" = "yes" ]
        then
	return 0
      elif [ "${answer}" = "no" ]
        then
        return 1
      fi
    else
      echo -e "Quitting.\n"
      exit 1
    fi
  done
}
#############################
# Useful subroutine
#############################
getperiod()
{
  while true
    do
    echo -n "Enter the period of the queue runner, in minutes: [15] "
    if read period
      then
      if [ -z "${period}" ]
        then 
        period=15
	return 0;
      elif echo "${period}" | grep -q '[^0-9]'
        then
        echo "The period must be all digits."
      elif [ "${period}" -eq 0 ]
        then
        echo "The period must be positive."
      else
        return 0
      fi
    else
      echo -e "Quitting.\n"
      exit 1
    fi
  done
}

#############################
# Start
#############################

name="$(basename $0)"
if [ "${name}" = "exim" ]
  then
  echo "You must run exim-config before running exim."
  echo "Help is available from /usr/share/doc/Cygwin/exim-*.README and \"man exim\"."
  return 123
elif [ "${name}" != "exim-config" ]
  then
  echo "Unexpected script name $name"
  return 1
fi

#############################
# Introduction
#############################

echo "************************************************"
echo "This script sets some key parameters of the exim"
echo "installation and starts the exim daemon."
echo "See the details in /usr/share/doc/Cygwin/exim-X-Y.README."
echo "    Interrupt with ^D."
echo
# Check if /etc/passwd and /etc/group are readable.
PASSWD=/etc/passwd
GROUP=/etc/group
ALIASES=/etc/aliases
if [ ! -r "${PASSWD}" -o ! -r "${GROUP}" ]
  then
  echo "${PASSWD} and ${GROUP} must exist and be readable by all."
  return 1
fi
# Check if running on NT
#nt=$(uname -s | sed -ne 's/^CYGWIN_NT-\([^.]*\).\([^ ]*\)/\1\2/p')
nt=$(uname -s | sed -ne 's/^CYGWIN_NT-\([^ ]*\)/\1/p')
if [ -n "$nt" ]
  then
  pingpath="$(cygpath -m --sysdir)/ping.exe"
  export CYGWIN=ntsec
  chmod -c o+r "${PASSWD}" "${GROUP}"
  if grep -q -i '^exim:' "${PASSWD}"
    then
    echo "WARNING: You have defined an \"exim\" user in ${PASSWD}."
    echo -e "This is an advanced feature, do not use it initially.\n"
  fi
  SYSTEMUID=$(sed -ne '/^[^:]*:[^:]*:[0-9]*:[0-9]*:[^:]*,S-1-5-18:.*:/{s/[^:]*:[^:]*:\([0-9]*\):.*$/\1/p;q}' "${PASSWD}")
  if [ -z "$SYSTEMUID" ]
    then
    echo "WARNING: The Local SYSTEM SID S-1-5-18 was not found in ${PASSWD}."
    echo -e "This script will not set file ownership and exim may malfunction.\n"
  fi
  ADMINSGID=$(sed -ne '/^[^:]*:S-1-5-32-544:.*:/{s/[^:]*:[^:]*:\([0-9]*\):.*$/\1/p;q}' "${GROUP}")
  if [ -z "$ADMINSGID" ]
    then
    echo "WARNING: The Local Administrators SID S-1-5-32-544 was not found in ${GROUP}."
    echo -e "This script will not set file ownership and exim may malfunction.\n"
  elif id -G | grep -qE '(^| )'"$ADMINSGID"'( |$)'
    then true
  else
    echo "WARNING: You are not in the Local Administrators group."
    echo -e "This script may fail to set file ownership and permissions.\n"
  fi
else
  pingpath="$(cygpath -m --windir)/ping.exe"
fi

####################################
# Check if usernames contain spaces
####################################
grep -o -e '^[^:]* [^:]*:[^:]*:[^:]*:[^:]*:' "${PASSWD}"
if [ "$?" -eq 0 ]
  then
  echo -e "\nWARNING: The usernames displayed above contain spaces."
  echo "    They cannot send mail nor appear in ${ALIASES}."
  if [ -n "$nt" ]
    then
    echo "    Edit ${PASSWD} and use identifiers without spaces."
  fi
  else
  echo "OK. No usernames contain spaces."  
fi
echo

#############################
# Get the postmaster name
#############################
if grep -iqs \^postmaster: "${ALIASES}"
  then
  echo "OK. The ${ALIASES} file contains \"postmaster\"."
else
  while true
    do
    echo -n "Who is the local postmaster? [${USER}] "
    if read postmaster
      then
      if [ -z "${postmaster}" ]
        then
        postmaster="$USER"
      fi
      if echo "${postmaster}" | grep -Fq " "
        then
        echo "ERROR. The postmaster name cannot contain spaces."
      elif grep -iq \^"${postmaster}:" "${PASSWD}"
        then
        echo "postmaster: ${postmaster}" >> "${ALIASES}"
        if [ -n "$nt" ]
          then
          chmod 0664 "${ALIASES}"
          echo "OK. The ${ALIASES} file was updated and given mode 0664."
          if [ -n "${SYSTEMUID}" -a -n "${ADMINSGID}" ]
            then
            chown "${SYSTEMUID}:${ADMINSGID}" "${ALIASES}"
            echo "OK. The ${ALIASES} file has owner ${SYSTEMUID} and group $ADMINSGID."
          fi 
        else
          echo "OK. The ${ALIASES} file was updated."
        fi
        break
      else
        echo "ERROR: User ${postmaster} is not in ${PASSWD}."
      fi
    else
      echo -e "Quitting.\n"
      return 1
    fi
  done
fi
echo 

#############################
# Need /etc/resolv.conf?
#############################
RESOLV=/etc/resolv.conf
w95="`expr "$sys" : "CYGWIN_95"`"
if [ $w95 -ne 0 ]
  then
  if grep -qsF 'nameserver ' "${RESOLV}"
    then
    echo "OK. The ${RESOLV} file appears to be valid."
  else
    echo "If you use DHCP you must enter the dns server(s) IP address(es) in ${RESOLV}."
    if request "Do you want to enter them now?"
      then
      count=""
      while true
        do
	if [ -z "${count}" ]
          then
	  echo -n "Enter the first address: "
        else
	  echo -n "Enter the next address, if any: "
        fi
        if read address
          then
	  if [ -z "${address}" ]
            then
            if [ -n "${count}" ]
	      then
	      break
            fi
          elif echo "${address}" | grep -qE '^([0-9]{1,3}\.){3}[0-9]{1,3}$'
            then
            echo "nameserver ${address}" >> "${RESOLV}"
            count="positive"
          else
            echo "ERROR: Invalid address."
          fi
        else
          echo -e "Quitting.\n"
	  return 1
        fi
      done
    else
      echo -e "You can run this script again to set the address(es).\n"
      return 1
    fi
  fi
  echo
fi

#############################
# Create exim.conf
#############################

CONF=/etc/exim.conf
CONF_DEF=/etc/defaults/etc/exim.conf
if [ ! -e "${CONF}" ]
  then
  if cp "${CONF_DEF}" "${CONF}"
    then
    echo "OK. ${CONF} created from ${CONF_DEF}."
    if [ -n "$nt" ]
      then
      chmod 664 "${CONF}"
      if [ -n "${SYSTEMUID}" -a -n "${ADMINSGID}" ]
	then
	chown "${SYSTEMUID}:${ADMINSGID}" "${CONF}"
      fi
    fi
  else
    echo "ERROR: Cannot create ${CONF} from ${CONF_DEF}."
    return 1
  fi
  echo
fi

###########################
# Set the primary host name
###########################

# Check if primary_hostname is already defined
hostname="`sed -ne '/^[ \t]*primary_hostname[ \t]*=/{
  s/[^=]*=[ \t]*\(.*\)/\1/p
  q
}' "${CONF}"`"
if [ -z "${hostname}" ]
  then
  echo "Looking for the fully qualified primary hostname."
  # Check if the fqhn can be found in one step
  host="`uname -n`"
  # Make sure we can find the Windows ping 
  if [ ! -x "$pingpath" ]
    then 
    echo "ERROR: $pingpath is not executable. Trying ping."
    pingpath=ping
  fi
  pingout="`eval "$pingpath" -n 1 "${host}" 2> /dev/null`"
  # Get the fqhn and the ip address
  fqhn1="`echo "${pingout}" | sed -ne '2{
    s/^Pinging \([^ ]*\).*/\1/
    y/ABCDEFGHIKLMNOPQRSTUVWXYZ/abcdefghiklmnopqrstuvwxyz/
    p
  }'`"
  if [ -z "${fqhn1}" ]
    then
    fqhn1="${host}"
  fi 
  if request "Is it \"${fqhn1}\"?"
    then
    echo "OK. Exim will autodiscover that name."
  else 
    address="`echo "${pingout}" |  sed -ne '2s/.*\[\(.*\)\].*/\1/p'`"
    # Get the fqhn from the ip address, excluding numerical forms.
    if [ -n "${address}" ]
      then
      fqhn2="`"$pingpath" -n 1 -a "${address}" | sed -ne '2{
        s/^Pinging \([^ ]*\).*/\1/
        s/^[0-9.]*$//
        y/ABCDEFGHIKLMNOPQRSTUVWXYZ/abcdefghiklmnopqrstuvwxyz/
        p
       }'`"
      if [ "${fqhn1}" != "${fqhn2}" -a -n "${fqhn2}" ]
        then
        if request "Is it \"${fqhn2}\"?"
          then
          hostname="${fqhn2}"
        fi
      fi
    fi
    while [ -z "${hostname}" ]
      do
      echo "Enter your fully qualified hostname."
      if read hostname
        then
        if echo "${hostname}" | grep -q '[^a-zA-Z0-9.-]'
          then
          echo "ERROR: The hostname contains invalid characters."
          hostname=""
        fi
      else 
        echo -e "Quitting.\n"
        return 1
      fi	
    done
    # Look for the commented line '# primary_hostname = '
    if sed -e 's/^ *# *primary_hostname *= *$/primary_hostname = '"${hostname}"'/' "${CONF}" > /tmp/exim_conf && \
       grep -Fqm 1 "primary_hostname = ${hostname}" /tmp/exim_conf && \
       mv -f /tmp/exim_conf "${CONF}"
      then
      echo "OK. The hostname ${hostname} was saved in ${CONF}."
      if [ ${nt} -ne 0 ]
        then
        chmod 664 "${CONF}"
        if [ -n "${SYSTEMUID}" -a -n "${ADMINSGID}" ]
          then
          chown "${SYSTEMUID}:${ADMINSGID}" "${CONF}"
        fi
      fi
    else
      echo "WARNING: The script could not set the primary hostname in ${CONF}."
      echo "Please edit that file to set the primary hostname."
    fi
  fi
else
  echo "OK. The primary hostname ${hostname}"
  echo "    is already defined in ${CONF}."
fi
echo

#####################
# Link exim if needed
#####################
# When exim points to exim-config, it returns 123
exim=123
if [ -x /usr/bin/exim ]
  then
  /usr/bin/exim 1> /dev/null 2>&1
  exim="$?"
fi

if [ "$exim" = "123" ]
  then
  for file in $(echo /usr/bin/exim-*.exe)
   do
   exim="${file}"
  done
  
  if [ -z "${exim}" ]
    then
    echo "ERROR: Cannot find exim executable."
    return
  elif ln -sf "${exim}" /usr/bin/exim
    then
    echo "OK. /usr/bin/exim points to ${exim}."
  else
    echo "ERROR: Cannot point /usr/bin/exim to ${exim}" 
    return
  fi
  echo
fi
    
#############################
# Install a service?
#############################
service="job"
if [ -z "$nt" ]
  then
  eximregpath='\HKLM\Software\Microsoft\Windows\CurrentVersion\RunServices\Exim'
  eximregdata=`regtool -q get $eximregpath`
  servtest=""
elif [ ! -e /usr/bin/cygrunsrv.exe ]
  then 
  echo "INFO: Download cygrunsrv to start the mailer daemon as a service."
  servtest=no
else
  cygrunsrv -Q exim > /dev/null 2>&1
  servtest=$?
fi
  
if [ -z "$nt" -a -n "$eximregdata" ]
  then
  echo "Exim is already installed as a service."
  echo "    Key: $eximregpath"
  echo "    Value: $eximregdata".
  if request "Do you want to remove or reinstall it?"
    then
    if regtool unset "$eximregpath"
      then
      echo "OK. The exim service was removed."
    fi
  else
    servtest=no
  fi
elif [ -n "$nt" -a "${servtest}" = "0" ]
  then
  echo "Exim is already installed as a service."
  if request "Do you want to remove or reinstall it?"
    then
    if cygrunsrv -R exim
      then
      echo "OK. The exim service was removed."
    fi
  else
   service="service"
   servtest=no
  fi
fi

if [ "${servtest}" = "no" ]
  then
  true
elif request "Do you want to install the exim daemon as a service?" 
  then
  getperiod
  if [ -n "$nt" ]
    then
    ntsec="nontsec"
    verb="may wish to"
    if request "Do you want the daemon to run with ntsec?" 
      then
      ntsec="ntsec"
      verb="should"
    fi

    privileged=no

    if [ "$nt" \> 5.1 ]
      then
      echo -e "\nYou ${verb} run the exim daemon under a privileged account."
      echo "This allows to setuid during local deliveries."
      echo "To do so, you must have already created a privileged" 
      echo "Windows user, capable of running as a service." 
      if request "Do you want to run the daemon under a privileged account?" 
        then
        privileged=yes
        prompt=""
	if grep -qi '^root:' "$PASSWD"
          then
          prompt='[root] '
        fi  
        while [ -z "${username}" ]
        do
          echo -n "Enter the user name: ${prompt}"
	  if read username
          then
            if [ -z "${username}" -a -n "${prompt}" ]
              then
              username=root
            elif ! grep -qi "^${username}:" "${PASSWD}"
              then
              echo "ERROR: The username is not in ${PASSWD}."
              username=""
            fi
          else 
            echo -e "Quitting.\n"
            return 1
          fi	
        done

        while [ -z "${password}" ]
        do
          echo -n "Enter the user password: "
	  if read password
          then
            true
          else 
            echo -e "Quitting.\n"
            return 1
          fi	
        done
      fi
    fi

    if [ "$privileged" = "yes" ]
      then
      if cygrunsrv -I exim -p /usr/bin/exim -e CYGWIN="${ntsec}" \
          -a "-bdf -q${period}m" -d "Exim Mail Transfer Agent" \
          -1 /var/log/exim/cygrunsrv_out.log -2 /var/log/exim/cygrunsrv_err.log \
	  -u "$username" -w "$password"
        then
        service="service"
      else
        service="off"
      fi
    else
      if cygrunsrv -I exim -p /usr/bin/exim -e CYGWIN="${ntsec}" \
          -a "-bdf -q${period}m" -d "Exim Mail Transfer Agent" \
          -1 /var/log/exim/cygrunsrv_out.log -2 /var/log/exim/cygrunsrv_err.log
        then
        service="service"
      else
        service="off"
      fi
    fi
  else
    eximregdata="\"`cygpath -wl /bin/sh.exe`\" -c \"/usr/bin/exim -bd -q${period}m\""
    if regtool set "$eximregpath" "$eximregdata" 
      then
      echo "OK. The registry was set:"
      echo "    Key: $eximregpath"
      echo "    Value: $eximregdata".
      echo "    This will only take effect at the next reboot."
    fi
  fi
fi
echo

#############################
# Start the daemon?
#############################
if ps -es | grep -Fqi 'exim-'
  then
  echo "INFO: An exim process is already running."
elif [ "${service}" != "off" ]
  then
  rm -f /var/spool/exim/exim-daemon.pid
  if request "Do you want to start the exim daemon as a ${service} now?"
    then
    if [ "${service}" = "job" ]
      then
      if [ -z "$period" ]
        then
        getperiod
      fi
      /usr/bin/exim -bd -q${period}m
    else
      cygrunsrv -S exim
    fi
    if [ $? -eq 0 ]
      then
      echo "OK. The mail daemon is now accepting mail."
      echo "    You can test it with \"telnet localhost 25\"."
    fi
  elif [ "${service}" = "job" ]
    then
    echo "OK. Type \"/usr/bin/exim -bd -q15m\" to start the exim daemon job."
  elif [ -n "$nt" ]
    then
    echo "OK. Type \"cygrunsrv -S exim\" to start the exim daemon service."
    echo "    It will restart automatically at each reboot."
  fi
fi
echo

#############################
# Cleanup
#############################
if [ -e /usr/local/bin/exim ]
  then
  echo "You have an old installation of exim in /usr/local/bin."
  if request "Do you want to delete the executables? (recommended)"
    then
    cd /usr/local/bin
    rm -f exim.exe exim exim-*.exe exim_dumpdb.exe exim_fixdb.exe exim_tidydb.exe exinext exiwhat
    rm -f exim_dbmbuild.exe exicyclog exigrep eximstats exiqsumm exim_lock.exe exim_checkaccess
    echo "OK. The cleanup not affect files under /usr/local/exim."
  fi
  echo
fi

#############################
# /usr/sbin/sendmail
#############################
sendmail=///none///
isexim=0
if [ ! -d /usr/sbin/sendmail ]
then
  if [ -e /usr/sbin/sendmail ]
  then
    if [ -L /usr/sbin/sendmail ]
    then
      sendmail=$(ls -l /usr/sbin/sendmail | sed -ne 's/^.*-> *\(.*\)/\1/'p)
      isexim=$(expr "$sendmail" : '.*exim' )
    fi
  else 
    sendmail=""
  fi
fi
if [ "$sendmail" != "///none///" ]
  then
  echo "Some programs expect /usr/sbin/sendmail to point to a mailer."
  if [ -n "$sendmail" ]
    then
    echo "It currently points to ${sendmail}."
    if [ "$isexim" -eq 0 ]
      then
      echo "Changing it to exim may affect other programs such as cron."
    fi
  fi
  if [ "$isexim" -eq 0 ]
    then
    if request "Do you want to point /usr/sbin/sendmail to /usr/bin/exim ?" 
      then
      ln -s -f /usr/bin/exim /usr/sbin/sendmail
    fi
  fi
  echo
fi

#############################
# End
#############################
echo "INFO: The exim log files are in /var/log/exim."
echo
echo "When everything else fails,"
echo "    read /usr/share/doc/Cygwin/exim-X-Y.README,"
echo "    or look up the documentation on www.exim.org."
echo "Many happy mailings :)"
echo
