#!/bin/sh
# $Id: sm.setup.sh.in,v 1.58 2005/09/06 05:40:58 ca Exp $
#
# Copyright (c) 2004, 2005 Sendmail, Inc. and its suppliers.
#	All rights reserved.
#
# By using this file, you agree to the terms and conditions set
# forth in the LICENSE file which can be found at the top level of
# the sendmail distribution.
#

# -------------------------------------------------------
# Simple script to setup a runtime system for sendmail X
# This is used by make install, it is converted to sm.setup.sh
# during configuration to replace path names etc.
# -------------------------------------------------------

# queue directory
SMXQD=${DESTDIR}${SMXQDIR:-/var/spool/smx}
# configuration directory
SMXETC=${DESTDIR}${SMXCONFDIR:-/usr/local/etc/smx}
# log directory (unless syslog(3) is used)
LOGDIR=${SMXLOGDIR:-.}
if test ${LOGDIR} != "." -a "${DESTDIR}"X != "X"
then
  LOGDIR=${DESTDIR}${LOGDIR}
fi

# users and groups
# SMTP Server
SMXS=${SMXS:-smxs}
# SMTP Client
SMXC=${SMXC:-smxc}
# QMGR
SMXQ=${SMXQ:-smxq}
# address resolver (misc)
SMXM=${SMXM:-smxm}
# generic (configuration etc)
SMX=${SMX:-smx}
# possible groups for logfiles (rw)
LGS=${SMXLG:-"operator sysadmin root cannotfindgroupforlogfile"}
# path to build directory
SMXOBJ=`pwd`
S=${SMX_OBJ:-${SMXOBJ}}
# base name of configuration file
SMXCNFB=${SMXCONF:-smx.conf}

RUNASPRG=${SMXRUNAS:-/usr/local/bin/runas}
if ${RUNASPRG} ${SMXM} /usr/local/sbin/t-hostname
then
   RUNAS="${RUNASPRG} ${SMXM}"
else
   RUNAS=""
fi

# hostname
HOSTNAME=`${RUNAS} /usr/local/sbin/t-hostname -l -V 2>/dev/null`
if test "X${HOSTNAME}" = "X"
then
  HOSTNAME="unconfigured.host.name"
  echo "Warning: cannot determine host name"
fi
SMXCGID=`${RUNAS} /usr/local/sbin/t-getgroup ${SMXC} 2>/dev/null`
if test "X${SMXCGID}" = "X"
then
  echo "Error: cannot find gid for ${SMXC}"
  exit 1
fi

# get a group for root to use for logfiles
for LG in ${LGS}
do
  if ${RUNAS} /usr/local/sbin/t-getgroup ${LG} 2>/dev/null
  then
    break
  fi
done
if test "${LG}" = "cannotfindgroupforlogfile"
then
  echo "Cannot find group for logfile"
  exit 1
fi

#
SCRIPT=sm.awk
if test -f ${SCRIPT}
then
  echo "${SCRIPT} exists; please remove"
  exit 1
fi

# these values will be replaced by configure
srcdir=.
top_srcdir=..
prefix=/usr/local
exec_prefix=${prefix}
bindir=${exec_prefix}/bin
sbindir=${exec_prefix}/sbin
libexecdir=${exec_prefix}/libexec
datadir=${prefix}/share
sysconfdir=${prefix}/etc
sharedstatedir=${prefix}/com
localstatedir=${prefix}/var
libdir=${exec_prefix}/lib
infodir=${prefix}/info
mandir=${prefix}/man
includedir=${prefix}/include
oldincludedir=/usr/include
pkgdatadir=${datadir}/smX
pkglibdir=${libdir}/smX
pkgincludedir=${includedir}/smX
top_builddir=.
# ----

# some utilities
CHOWN=${SMXCHOWN:-chown}
CHMOD=${SMXCHMOD:-chmod}
MKDIR=${SMXMKDIR:-mkdir}
TOUCH=${SMXTOUCH:-touch}
AWK=${SMXAWK:-awk}
SED=${SMXSED:-sed}
CAT=${SMXCAT:-cat}

# -- try to find name server
NS=""
RSLVC=/etc/resolv.conf
if test -s ${RSLVC}
then
NS=`grep '^nameserver' ${RSLVC} | head -1 | ${SED} -e 's/nameserver[	 ]*\([0-9][0-9\.]*\).*$/\1/'`
fi
if test -z "${NS}"
then
  echo "$0: no nameserver found"
  NS=127.0.0.1
fi

# create base directory and change to it
test -d ${SMXQD} || ${MKDIR} -p ${SMXQD}
if cd ${SMXQD}; then
  :
else
  echo "cannot chdir to ${SMXQD}"
  exit 1
fi
if ${CHMOD} 0755 .; then
  :
else
  echo "cannot chmod ${SMXQD}"
  exit 1
fi

# create queue directories (for CDB)
for i in 0 1 2 3 4 5 6 7 8 9 A B C D E F
do
  test -d ${i} || ${MKDIR} ${i}
  ${CHOWN} ${SMXS}:${SMXQ} ${i} || exit 3
  ${CHMOD} 0771 ${i}
done

# deferred envelope queue
DEFEDB=defedb
test -d ${DEFEDB} || ${MKDIR} ${DEFEDB} || exit 4
${CHOWN} ${SMXQ}:${SMXQ} ${DEFEDB} || exit 5
${CHMOD} 0700 ${DEFEDB} || exit 6

# create directories for sockets etc
for i in qmsmtps qmsmtpc qmsmar smtps ibdb ibdb/ibdb
do
  test -d ${i} || ${MKDIR} ${i}
  ${CHMOD} 02770 ${i} || exit 1
done
${CHMOD} 0700 ibdb ibdb/ibdb || exit 1
${CHMOD} 0750 smtps || exit 1

${CHOWN} ${SMXQ}:${SMXM} qmsmar || exit 1
${CHOWN} ${SMXQ}:${SMXC} qmsmtpc || exit 1
${CHOWN} ${SMXQ}:${SMXS} qmsmtps || exit 1
${CHOWN} ${SMXS}:${SMXS} smtps || exit 1
${CHOWN} ${SMXQ}:${SMXQ} ibdb || exit 1
${CHOWN} ${SMXQ}:${SMXQ} ibdb/ibdb || exit 1

# --
# create configuration directory
test -d ${SMXETC} || ${MKDIR} -p ${SMXETC}
if test ! -d ${SMXETC}; then
  echo "failed to mkdir ${SMXETC}"
  exit 1
fi

# create "mailertable"
MT=${SMXETC}/mt
if test ! -f ${MT}
then
   ${CAT} > ${MT} <<EOF
local.host	lmtp:
${HOSTNAME}	lmtp:
EOF

${CHOWN} ${SMXM}:${SMXM} ${MT} || exit 1
fi

SMXCNF=${SMXETC}/${SMXCNFB}
if test -s ${SMXCNF}
then
  SMXCONFPRG=/usr/local/bin/smconf
  if test -x ${SMXCONFPRG}
  then
    ${SMXCONFPRG} ${SMXCNF} >/dev/null 2>&1
    R=$?
  else
    R=0
  fi
  echo "${SMXCNF} exists and will not be overwritten."
  if test ${R} != 0
  then
     echo "It is not syntactically correct for this version of sendmail X."
  fi
  echo "Please move it out of the way or upgrade it yourself."
else
${CAT} > ${SMXCNF} <<EOF
# -------------------------------------------------------
# Sample configuration file for sendmail X
# can be used by mcp, qmgr, smar, smtps, and smtpc
# module -f ${SMXCNF}
# -------------------------------------------------------
# Entries are started in reverse order by mcp
# -------------------------------------------------------

# default values
# SMTPS_socket = "qmsmtps/qmsmtps";
# SMTPC_socket = "qmsmtpc/qmsmtpc";
# SMAR_socket = "qmsmar/qmsmar";
# CDB_base_directory = "";

# activate this for local delivery using procmail and LMTP
# lmtp {
# 	listen_socket { type=unix;
#		path = lmtpsock; umask = 007;
# 		user = root; group = ${SMXC}; }
# 	start_action = nostartaccept;
# 	min_processes = 1;
# 	max_processes = 8;
# 	user = root;
# 	path = /usr/local/bin/procmail;
# 	arguments = "procmail -z+";
# }

smtps {
  log_level = 11;
  log { facility=mail; ident="smtps"; }
  CDB_gid = ${SMXCGID};
  wait_for_server = 4;
  listen_socket { type=inet; port = 25; }
  start_action = pass;
  pass_fd_socket = smtps/smtpsfd;
  user = ${SMXS};
  path = "${libexecdir}/smtps";
  arguments = "smtps -f ${SMXCNF}";
}

## To run two servers different names and different sockets must be used.
## Moreover, restart_dependencies for qmgr and smar must be changed too.
## Note: this does not use a configuration file and should be changed
#smtps MSA {
#	log_level = 11;
#	log { facility=mail; ident="MSA"; }
#	CDB_gid = ${SMXCGID};
#	listen_socket { type=inet; port = 587; }
#	start_action = pass;
#	pass_fd_socket = smtps/msafd;
#	user = ${SMXS};
#	path = "${libexecdir}/smtps";
#	arguments = "smtps -I 1 -N MSA -f ${SMXCNF}";
#}
#
#smtps MTA {
#	log_level = 11;
#	log { facility=mail; ident="MTA"; }
#	CDB_gid = ${SMXCGID};
#	listen_socket { type=inet; port = 25; }
#	start_action = pass;
#	pass_fd_socket = smtps/mtafd;
#	user = ${SMXS};
#	path = "${libexecdir}/smtps";
#	arguments = "smtps -I 0 -N MTA -f ${SMXCNF}";
#}

##
smtpc {
  log_level = 12;
  log { facility=mail; ident="smtpc"; }
  wait_for_server = 4;
  start_action = wait;
  user = ${SMXC};
  path = "${libexecdir}/smtpc";
  arguments = "smtpc -f ${SMXCNF}";
}

# must be previous to last in the list: started after smar
qmgr {
  log_level = 12;
  log { facility=mail; ident="qmgr"; }
  wait_for_server = 4;
  wait_for_client = 3;
  start_action = wait;
  user = ${SMXQ};
  restart_dependencies = { smtps, smtpc, smar };
  path = "${libexecdir}/qmgr";
  arguments = "qmgr -f ${SMXCNF}";
}

# must be last in the list: started first
smar {
  log_level = 12;
  log { facility=mail; ident="smar"; }
  nameserver = ${NS};
  start_action = wait;
  user = ${SMXM};
  restart_dependencies = { smtps, qmgr };
  path = "${libexecdir}/smar";
  arguments = "smar -f ${SMXCNF}";
}
EOF
fi

${CHOWN} ${SMX}:${SMX} ${SMXCNF} || exit 1

# create simple startup script
MCPSH=/usr/local/etc/rc.d/smx-mcp.sh
if test ! -s ${MCPSH}
then
${CAT} > ${MCPSH} <<EOF
#!/bin/sh
# start sendmail X via MCP

MCPPID=mcp.pid
MCPOUT=mcp.out

start_mcp()
{
	${sbindir}/mcp -l -p \${MCPPID} ${SMXCNF} > \${MCPOUT} 2>&1 &
}

stop_mcp()
{
	if test -s \${MCPPID}; then
		kill \`head -1 \${MCPPID}\`
	else
		echo "\$0: pid file \${MCPPID} does not exist or is empty"
	fi
}

if cd "${SMXQD}"; then
	:
else
	echo "\$0: cd ${SMXQD} failed"
	exit 1
fi

case "\$1" in
'start')
	start_mcp
	;;
'stop')
	stop_mcp
	;;
'restart')
	stop_mcp
	start_mcp
	;;
*)
	echo "Usage: \$0 { start | stop | restart }"
	exit 1
	;;
esac
exit 0
EOF
${CHMOD} 0700 ${MCPSH}
fi

LOGN=lognull.sh
if test ! -s ${LOGN}
then
${CAT} > ${LOGN} <<EOF
#!/bin/sh
for i in *.log
do
  cp /dev/null \${i}
done
EOF
${CHMOD} +x ${LOGN}
fi

${CAT} > ${SCRIPT} <<EOF
/^section=/ {NAME=\$2; next;}
/^title=/ {NAME=\$2; next;}
/^user=/ {printf("%s:%s\n",NAME,\$2); }
/ user=/ {printf("%s:%s\n",NAME,\$2); }
EOF

# try to use a scanner for configuration file
SCAN=/usr/local/sbin/tree
if test -x ${SCAN}
then
for i in `${SCAN} -e < ${SMXCNF} | ${SED} -e 's/[	 ][	 ]*=[	 ][	 ]*/=/g' -e 's/;//'  -e 's/"//g' | ${AWK} -F= -f ${SCRIPT}`
do
  # i contains program:owner
  FILE=`echo ${i} | ${SED} 's;:.*;;'`
  LOGF=${LOGDIR}/${FILE}.log
  OWNER=`echo ${i} | ${SED} 's;.*:;;'`
  ${TOUCH} ${LOGF} || exit 1
  ${CHOWN} ${OWNER}:${LG} ${LOGF} || exit 1
done
else
  # hack
  echo "cannot find ${SCAN}"
  exit 1
fi

#
MF=${SMXETC}/Makefile
if test -f ${MF}
then
  echo "$0: ${MF} already exists; not changed"
else
${CAT} > ${MF} <<EOF
# Simple Makefile to create smX maps
MM=${bindir}/createmap
# all maps?
all: aliases.db access.db qmgr_conf.db
# or just aliases?
#all: aliases.db
aliases.db:aliases
	-test -f aliases.db && mv aliases.db aliases.db-
	\${MM} <aliases 
	chown ${SMXM} aliases.db
	chmod 664 aliases.db
	echo "kill -USR1 smar"
access.db:access
	-test -f access.db && mv access.db access.db-
	\${MM} -w -F access.db < access
	chown ${SMXM} access.db
	chmod 664 access.db
	echo "kill -USR1 smar"
qmgr_conf.db:qmgr_conf
	-test -f qmgr_conf.db && mv qmgr_conf.db qmgr_conf.db-
	\${MM} -w -F qmgr_conf.db < qmgr_conf
	chown ${SMXQ} qmgr_conf.db
	chmod 664 qmgr_conf.db
	echo "kill -USR1 qmgr"
EOF
fi

#
ALIASES=${SMXETC}/aliases
if test -f ${ALIASES}
then
  echo "$0: ${ALIASES} already exists; not changed"
else
${CAT} > ${ALIASES} <<EOF
# Replace user with a valid user who is responsible for this MTS
postmaster:	user
root:	user
user: local:
EOF
echo "please edit ${ALIASES} and run make afterwards"
fi

#
QMGRCONF=${SMXETC}/qmgr_conf
if test -f ${QMGRCONF}
then
  echo "$0: ${QMGRCONF} already exists; not changed"
else
${CAT} > ${QMGRCONF} <<EOF
# outgoing: local; this should match the number of lmtp processes
oci:127.0.0.255	1
ocm:127.0.0.255	8
# occ timeout (> smtpc timeout)
#octo:	600
# incoming: local limits
#icm:127.0.0.1	100
#icr:127.0.0.1	200
EOF
echo "please review ${QMGRCONF} and run make afterwards"
fi

# check first whether smtps/smtpc support STARTTLS?
echo "setup certs if STARTTLS should be used"

exit 0
