#!/usr/bin/env bash script_name="$(basename $(realpath $0))" working_dir="$(dirname $(realpath $0))" conf_file="${working_dir}/conf/${script_name%%.*}.conf" LOCK_DIR="/tmp/$(basename $0).$$.LOCK" log_file="${LOCK_DIR}/${script_name%%.*}.log" backup_date="$(date +%Y-%m-%d-%H%M)" declare -a files_backuped_arr=() declare -a dirs_backuped_arr=() # ---------- # Base Function(s) # ---------- usage() { [[ -n "$1" ]] && error "$1" [[ $terminal ]] && echo -e " \033[1mUsage:\033[m $(basename $0) \033[1mDescription\033[m Script configures schleuder support for postfix mailsystem. Program parameters will be read from configuration file '$conf_file' and from command line if not running in batch mode. All needed files will be created. The postfix configuration (files 'main.cf' and 'master.cf') will be changed if necessary. You can run this script all the time, even if postfix is already configured. Changed files will be backuped with date suffix. \033[1mRequirements\033[m Both, Postfix and Schleuder must be installed \033[1mOptions\033[m -b Batch mode: Script runs in batch mode. No user action will be taken. Default is off. -d A blank separated and quoted list of domains, which should be handled by the schleuder list manager. If only one domain is given, quotes can be omitted. -e E-mails to adresses postmaster@ and abuse@ will be redirected to this address. Defaults to 'root@localhost' -h Prints this help. -u User under which schleuder program is running. Defaults to 'schleuder' \033[1mFiles\033[m $conf_file: Configuration file \033[1mExample:\033[m The only usage is without any parameters (this will not be checked) $(basename $0) " clean_up 1 } clean_up() { # Perform program exit housekeeping rm -rf "$LOCK_DIR" blank_line exit $1 } echononl(){ if $terminal ; then echo X\\c > /tmp/shprompt$$ if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then echo -e -n " $*\\c" 1>&2 else echo -e -n " $*" 1>&2 fi rm /tmp/shprompt$$ fi } fatal(){ echo "" if $terminal ; then echo -e " [ \033[31m\033[1mFatal\033[m ] $*" else echo -e " [ Fatal ] $*" fi echo "" if $terminal ; then echo -e " \033[1mScript terminated\033[m.." else echo -e " Script terminated.." fi echo "" rm -rf $LOCK_DIR exit 1 } error (){ echo "" if $terminal ; then echo -e " [ \033[31m\033[1mError\033[m ] $*" else echo " [ Error ] $*" fi echo "" } warn (){ if $LOGGING || $terminal ; then echo "" if $terminal ; then echo -e " [ \033[33m\033[1mWarn\033[m ] $*" else echo " [ Warn ] $*" fi echo "" fi } info (){ if $LOGGING || $terminal ; then echo "" if $terminal ; then echo -e " [ \033[32m\033[1mInfo\033[m ] $*" else echo " [ Info ] $*" fi echo "" fi } ok (){ if $LOGGING || $terminal ; then echo "" if $terminal ; then echo -e " [ \033[32m\033[1mOk\033[m ] $*" else echo " [ Ok ] $*" fi echo "" fi } echo_done() { if $terminal ; then echo -e "\033[75G[ \033[32mdone\033[m ]" fi } echo_ok() { if $terminal ; then echo -e "\033[75G[ \033[32mok\033[m ]" fi } echo_failed(){ if $terminal ; then echo -e "\033[75G[ \033[1;31mfailed\033[m ]" fi } echo_skipped() { if $terminal ; then echo -e "\033[75G[ \033[33m\033[1mskipped\033[m ]" fi } trim() { local var="$*" var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters echo -n "$var" } blank_line() { if $terminal ; then echo "" fi } # - Backup file or directory # - backup() { is_directory=false if [[ -z "$1" ]] ; then error "No file/directory for backup given!" return elif [[ -h "$1" ]] ; then _source="$(realpath $1)" warn "'$1' is a symlink to $_source." elif [[ ! -d "$1" ]] && [[ ! -f "$1" ]] ; then warn "'$1' not found. Backup skipped." return else _source="$(realpath $1)" fi if [[ -d "$_source" ]]; then is_directory=true echononl "Backup directory '$_source' .." else echononl "Backup file '$_source' .." fi cp -a "$_source" "${_source}.$backup_date" > $log_file 2>&1 if [[ $? -eq 0 ]] ; then echo_ok if $is_directory ; then dirs_backuped_arr+=("$_source") else files_backuped_arr+=("$_source") fi else echo_failed error "$(cat "$log_file")" fi } # - Remove script generated backups, if source wasn't changed # - rm_unchanged_backup() { if [[ ${#files_backuped_arr[@]} -gt 0 ]] ; then for _file in "${files_backuped_arr[@]}" ; do if $(diff "$_file" "${_file}.$backup_date" > /dev/null 2>&1) ; then echononl "File '$(basename "${_file}")' wasn't changed.\n Delete the previous generated backup. .." rm "${_file}.$backup_date" > "$log_file" 2>&1 if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi blank_line fi done fi if [[ ${#dirs_backuped_arr[@]} -gt 0 ]] ; then for _dir in "${dirs_backuped_arr[@]}" ; do if $(diff -Nur "$_dir" "${_dir}.$backup_date" > /dev/null 2>&1) ; then echononl "Directory '$(basename "${_dir}")' wasn't changed.\n Delete the previous generated backup. .." rm -rf "${_dir}.$backup_date" > "$log_file" 2>&1 if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi blank_line fi done fi } # ---------- # - Jobhandling # ---------- # - Run 'clean_up' for signals SIGHUP SIGINT SIGTERM # - trap clean_up SIGHUP SIGINT SIGTERM # - Create lock directory '$LOCK_DIR" # mkdir "$LOCK_DIR" # ---------- # - Some checks .. # ---------- # - Running in a terminal? # - if [[ -t 1 ]] ; then terminal=true else terminal=false fi # -Is systemd supported on this system? # - systemd_supported=false systemd=$(which systemd) systemctl=$(which systemctl) if [[ -n "$systemd" ]] && [[ -n "$systemctl" ]] ; then systemd_supported=true fi # - Print help? # - if [[ "$(trim $*)" = "--help" ]] ; then usage fi if [[ -z "$(which basename)" ]]; then fatal 'It seems "basename" is not installed, but needed!' fi if [[ -z "$(which realpath)" ]]; then fatal 'It seems "realpath" is not installed, but needed!' fi # ========== # - Begin Main Script # ========== # ---------- # - Headline # ---------- if $terminal ; then echo "" echo -e "\033[1m----------\033[m" echo -e "\033[32m\033[1mRunning script \033[m\033[1m$script_name\033[32m .. \033[m" echo -e "\033[1m----------\033[m" fi # ---------- # Read Configurations from $conf_file # ---------- # - Give your default values here # - LOGGING=false BATCH_MODE=false SCHLEUDER_USER="schleuder" SCHLEUDER_PROG="$(which schleuder)" SCHLEUDER_DOMAINS="" ADMIN_EMAIL="root@localhost" if [[ -f "$conf_file" ]]; then source "$conf_file" else warn "No configuration file '$conf_file' present.\n Loading default values.." fi # ---------- # - Read commandline parameter # ---------- while getopts bd:e:hu: opt ; do case $opt in b) BATCH_MODE=true ;; d) SCHLEUDER_DOMAINS="$OPTARG" ;; e) ADMIN_EMAIL="$OPTARG" ;; h) usage ;; u) SCHLEUDER_USER="$OPTARG" ;; \?) usage ;; esac done # ---------- # - Read in parameters given by user # ---------- if $terminal && ! $BATCH_MODE ; then echo "" echo "" echo -e " \033[1mRead in parameters given by user ..\033[m" echo "" echo "" echo -e "\033[32m--\033[m" echo "" echo " Full qualified path to schleuder program." echo "" echo -e " Type \033[33m\033[m to accept the default." echo "" echo "" _SCHLEUDER_PROG=$SCHLEUDER_PROG SCHLEUDER_PROG="" echononl "Schleuder program [\033[1m$_SCHLEUDER_PROG\033[m]: " read SCHLEUDER_PROG if [[ -z "$SCHLEUDER_PROG" ]] ; then SCHLEUDER_PROG=$_SCHLEUDER_PROG fi echo "" echo -e "\033[32m--\033[m" echo "" echo " The user, under which schleuder is running." echo "" echo -e " Type \033[33m\033[m to accept the default." echo "" echo "" _SCHLEUDER_USER=$SCHLEUDER_USER SCHLEUDER_USER="" echononl "Schleuder user [\033[1m$_SCHLEUDER_USER\033[m]: " read SCHLEUDER_USER if [[ -z "$SCHLEUDER_USER" ]] ; then SCHLEUDER_USER=$_SCHLEUDER_USER fi echo "" echo -e "\033[32m--\033[m" echo "" echo " Blank separated list of schleuder domains" echo "" if [[ -n "$SCHLEUDER_DOMAINS" ]]; then echo -e " Type \033[33m\033[m to accept the default." echo "" echo "" _SCHLEUDER_DOMAINS=$SCHLEUDER_DOMAINS SCHLEUDER_DOMAINS="" echononl "Schleuder domains [\033[1m$_SCHLEUDER_DOMAINS\033[m]: " read SCHLEUDER_DOMAINS if [[ -z "$SCHLEUDER_DOMAINS" ]] ; then SCHLEUDER_DOMAINS=$_SCHLEUDER_DOMAINS fi else echo "" echononl "\033[1mSchleuder domains:\033[m " read SCHLEUDER_DOMAINS while [[ -z "$(trim "$SCHLEUDER_DOMAINS")" ]]; do echo "Entry for schleuder domains is required! Try again.." echononl "\033[1mSchleuder domains: \033[m" read SCHLEUDER_DOMAINS done fi echo "" echo -e "\033[32m--\033[m" echo "" echo " The user, under which schleuder is running." echo "" echo " Admin e-mail addrees, to wich e-mails with recipient" echo "" echo " postmaster@" echo " abuse@" echo "" echo " will be redirected." echo "" echo -e " Type \033[33m\033[m to accept the default." echo "" echo "" _ADMIN_EMAIL=$ADMIN_EMAIL ADMIN_EMAIL="" echononl "Admin e-mail [\033[1m$_ADMIN_EMAIL\033[m]: " read ADMIN_EMAIL if [[ -z "$ADMIN_EMAIL" ]] ; then ADMIN_EMAIL=$_ADMIN_EMAIL fi echo "" echo "" echo -e " \033[32m\033[1mParameter Summary:\033[m" echo "" echo " Schleuder user.............: $SCHLEUDER_USER" echo " Schleuder program..........: $SCHLEUDER_PROG" echo " Schleuder domains..........: $SCHLEUDER_DOMAINS" echo " Admin e-mail address.......: $ADMIN_EMAIL" echo "" echononl "Continue with this parameters? [\033[1myes/no\033[m]: " read OK while [[ "${OK,,}" != "yes" ]] && [[ "${OK,,}" != "no" ]] ; do echononl "\033[33mWrong entry!\033[m [\033[1myes/no\033[m]: " read OK done [[ "${OK,,}" = "yes" ]] || fatal "Canceled by user input." fi # ---------- # - Some pre-script tasks .. # ---------- if $terminal ; then echo "" echo "" echo -e " \033[1mDoing some pre-script tasks ..\033[m" echo "" fi if [[ -z "$SCHLEUDER_PROG" ]]; then fatal "Schleuder list manager (schleuder) not found!" elif [[ ! -x "$SCHLEUDER_PROG" ]] ; then fatal "Found schleuder list manager (${SCHLEUDER_PROG}), but file is not executable" fi if ! $(grep -q -E "^${SCHLEUDER_USER}" /etc/passwd 2> /dev/null) ; then fatal "User '$SCHLEUDER_USER' not present!" fi if [[ -z "$SCHLEUDER_DOMAINS" ]]; then fatal "No domains using as schleuder list domains given!" fi schleuder_home="$(cat /etc/passwd | grep -E "^${SCHLEUDER_USER}" | cut -d ':' -f6)" if [[ ! -d "$schleuder_home" ]]; then fatal "Home Directory '$schleuder_home' for user '$SCHLEUDER_USER' not found!" fi postfix_main_config="/etc/postfix/main.cf" if [[ ! -f "$postfix_main_config" ]] ; then fatal "Postfig configuration '$postfix_main_config' not found!" fi postfix_master_config="/etc/postfix/master.cf" if [[ ! -f "$postfix_master_config" ]] ; then fatal "Postfig configuration '$postfix_master_config' not found!" fi virtual_schleuder_domains_file="/etc/postfix/schleuder_domains_sqlite.cf" virtual_schleuder_lists_file="/etc/postfix/schleuder_lists_sqlite.cf" transport_schleuder_file="/etc/postfix/transport_schleuder" virtual_schleuder_aliases_file="/etc/postfix/virtual_schleuder_aliases" # - How to start/stop postfix daemon # - postfix_sysv_init_script="" postfix_systemd_service="" if $systemd_supported ; then # - Is Service exclusive controlled by systemd # - if systemctl -t service list-unit-files \ | grep -e "^postfix" \ | grep -q -E "(enabled|disabled)" 2> /devnull ; then postfix_systemd_service=$(systemctl -t service list-unit-files \ | grep -e "^postfix" \ | awk '{print$1}'\ | head -1) fi fi if [[ -z "$postfix_systemd_service" ]] ; then if [[ -x /etc/init.d/postfix ]] ; then postfix_sysv_init_script="/etc/init.d/postfix" fi fi if [[ -z "$postfix_systemd_service" ]] && [[ -z "$postfix_sysv_init_script" ]] ; then fatal "Neither an init-script nor a service file for 'postfix' found!" fi # - Backup some files/directories # - backup "$postfix_master_config" backup "$postfix_main_config" backup "$virtual_schleuder_domains_file" backup "$virtual_schleuder_lists_file" backup "$transport_schleuder_file" backup "$virtual_schleuder_aliases_file" # ---------- # - Main part of script # ---------- if $terminal ; then echo "" echo "" echo -e " \033[1mMain part of script ..\033[m" echo "" fi # - # - file /etc/postfix/schleuder_domains_sqlite.cf # - _file="$virtual_schleuder_domains_file" _access_method="sqlite" _parameter="virtual_mailbox_domains" echononl "Create new file '$_file' .." cat << EOF > "$_file" 2> "$log_file" dbpath = /var/lib/schleuder/db.sqlite query = select distinct substr(email, instr(email, '@') + 1) from lists where email like '%%%s' EOF if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi echononl "Add '${_access_method}:${_file}' to parameter ${_parameter}" if ! $(grep -q "${_access_method}:${_file}" "$postfix_main_config") ; then if $(grep -q -E "^\s*${_parameter}\s*=" "$postfix_main_config") ; then perl -i -n -p \ -e "s#^(${_parameter}\s+=.*)#\1\n \#\# - Schleuder\n ${_access_method}:${_file}#" \ "$postfix_main_config" > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi else cat << EOF >> "$postfix_main_config" 2> "$log_file" ${_parameter} = ## - Schleuder ${_access_method}:${_file} EOF if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi fi else echo_skipped fi # - # - virtual_schleuder_lists_file # - _file="$virtual_schleuder_lists_file" _access_method="sqlite" _parameter="virtual_mailbox_maps" # - Create new file '$virtual_schleuder_lists_file' # - echononl "Create new file '$_file' .." cat << EOF > "$_file" 2> "$log_file" # Use this as a table for postfix to select addresses that schleuder # thinks belong to it. This is useful when # smtpd_reject_unlisted_recipient = yes (which is the default for # modern Postfix) # For example, you might dedicate Postfix's "virtual" domains to # schleuder with the following set of configs in main.cf: # # virtual_domains = lists.example.org # virtual_transport = schleuder # virtual_alias_maps = hash:/etc/postfix/virtual_aliases # virtual_mailbox_maps = sqlite:/etc/postfix/schleuder_sqlite.cf # schleuder_destination_recipient_limit = 1 # it is not recommended to use this table for more powerful # configuration options (e.g. transport_maps) because it could give # the schleuder user (which can write the given sqlite database) the # power to change settings for for other mail handled by this Postfix # instance. dbpath = /var/lib/schleuder/db.sqlite query = select 'present' from lists where email = '%s' or email = replace('%s', '-bounce@', '@') or email = replace('%s', '-owner@', '@') or email = replace('%s', '-request@', '@') or email = replace('%s', '-sendkey@', '@') EOF if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi echononl "Add '${_access_method}:${_file}' to parameter ${_parameter}" if ! $(grep -q "${_access_method}:${_file}" "$postfix_main_config") ; then if $(grep -q -E "^\s*${_parameter}\s*=" "$postfix_main_config") ; then perl -i -n -p \ -e "s#^(${_parameter}\s+=.*)#\1\n \#\# - Schleuder\n ${_access_method}:${_file}#" \ "$postfix_main_config" > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi else cat << EOF >> "$postfix_main_config" 2> "$log_file" ${_parameter} = ## - Schleuder lists ${_access_method}:${_file} EOF if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi fi else echo_skipped fi # - # - transport_schleuder_file # - _file="$transport_schleuder_file" _access_method="btree" _parameter="transport_maps" _success=true echononl "Create file '$_file' .." > "$_file" for _domain in $SCHLEUDER_DOMAINS ; do cat << EOF >> $transport_schleuder_file 2>> $"$log_file" $_domain schleuder: EOF if [[ $? -ne 0 ]]; then _success=false fi done if $_success ; then echo_ok else echo_failed error "$(cat "$log_file")" fi echononl "Create db-file '${_file}.db'" postmap ${_access_method}:${_file} > "$log_file" 2>&1 if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi echononl "Add '${_access_method}:${_file}' to parameter ${_parameter}" if ! $(grep -q "${_access_method}:${_file}" "$postfix_main_config") ; then if $(grep -q -E "^\s*${_parameter}\s*=" "$postfix_main_config") ; then perl -i -n -p \ -e "s#^(${_parameter}\s+=.*)#\1\n \#\# - Schleuder\n ${_access_method}:${_file}#" \ "$postfix_main_config" > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi else cat << EOF >> "$postfix_main_config" 2> "$log_file" ${_parameter} = ## - Schleuder ${_access_method}:${_file} EOF if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi fi else echo_skipped fi # - # - file: /etc/postfix/virtual_schleuder_aliases # - _file="$virtual_schleuder_aliases_file" _access_method="btree" _parameter="virtual_alias_maps" _success=true echononl "Create new file '$_file' .." cat << EOF > "$_file" 2> "$log_file" ## - For schleuder domain(s), prevent e-mail addresse ## - postmaster@, ## - abuse@, ## - MAILER-DAEMON@, ## - root@ ## - from sending to schleuder list manager ## - EOF if [[ $? -ne 0 ]]; then _success=false fi for _domain in $SCHLEUDER_DOMAINS ; do cat << EOF >> "$_file" 2> "$log_file" postmaster@$_domain $ADMIN_EMAIL abuse@$_domain $ADMIN_EMAIL MAILER-DAEMON@$_domain root@localhost root@$_domain root@localhost EOF if [[ $? -ne 0 ]]; then _success=false fi done if $_success ; then echo_ok else echo_failed error "$(cat "$log_file")" fi echononl "Create db-file '${_file}.db'" postmap ${_access_method}:${_file} > "$log_file" 2>&1 if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi echononl "Add '${_access_method}:${_file}' to parameter ${_parameter}" if ! $(grep -q "${_access_method}:${_file}" "$postfix_main_config") ; then if $(grep -q -E "^\s*${_parameter}\s*=" "$postfix_main_config") ; then perl -i -n -p \ -e "s#^(${_parameter}\s+=.*)#\1\n \#\# - Schleuder\n ${_access_method}:${_file}#" \ "$postfix_main_config" > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi else cat << EOF >> "$postfix_main_config" 2> "$log_file" ${_parameter} = ## - Schleuder ${_access_method}:${_file} EOF if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi fi else echo_skipped fi # - # - file /etc/postfix/master # - echononl "Add transport options to file '$postfix_master_config' .." if ! grep -q -E "^\s*schleuder" "$postfix_master_config" 2>/dev/null ; then cat <> $postfix_master_config 2> $log_file schleuder unix - n n - - pipe flags=DRhu user=schleuder argv=${SCHLEUDER_PROG} work \${recipient} EOF if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi else echo_skipped fi # - # - main.cf: new Parameter 'schleuder_destination_recipient_limit' # - echononl "Add parameter 'schleuder_destination_recipient_limit = 1' to 'main.cf' .." if ! $(grep -q -E "^\s*schleuder_destination_recipient_limit" "/etc/postfix/main.cf") ; then if $(grep -q -E "^\s*virtual_transport\s*=" "$postfix_main_config") ; then perl -i -n -p \ -e "s#^\s*(virtual_mailbox_maps\s*=.*$)#schleuder_destination_recipient_limit = 1\n\n\1#" \ /etc/postfix/main.cf > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi else cat << EOF >> "$postfix_main_config" 2> $log_file schleuder_destination_recipient_limit = 1 EOF if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi fi fi # ---------- # - Some post-script tasks .. # ---------- if $terminal ; then echo "" echo "" echo -e " \033[1mDoing some post-script tasks ..\033[m" echo "" fi # - Remove generated backup file if source wasn't changed. # - rm_unchanged_backup echononl "Restart postfix mail service .." _success=true if [[ -n "$postfix_systemd_service" ]]; then echo "systemctl daemon-reload" > "$log_file" 2>&1 systemctl daemon-reload >> "$log_file" 2>&1 if [[ $? -ne 0 ]]; then _success=false fi echo "systemctl stop $postfix_systemd_service" >> "$log_file" 2>&1 systemctl stop "$postfix_systemd_service" >> "$log_file" 2>&1 if [[ $? -ne 0 ]]; then _success=false fi # - Cleanup postfix cache.. # - for _file in smtpd_scache.db smtp_scache.db verify_cache.db ; do if [[ -f "/var/lib/postfix/$_file" ]] ; then echo "rm /var/lib/postfix/$_file" >> "$log_file" rm /var/lib/postfix/$_file >> "$log_file" 2>&1 if [[ $? -ne 0 ]]; then _success=false fi fi done echo "systemctl start \"$postfix_systemd_service\"" >> "$log_file" 2>&1 systemctl start "$postfix_systemd_service" >> "$log_file" 2>&1 if [[ $? -ne 0 ]]; then _success=false fi else echo "$postfix_sysv_init_script stop" >> "$log_file" 2>&1 $postfix_sysv_init_script stop >> "$log_file" 2>&1 if [[ $? -ne 0 ]]; then _success=false fi # - Cleanup postfix cache.. # - for _file in smtpd_scache.db smtp_scache.db verify_cache.db ; do if [[ -f "/var/lib/postfix/$_file" ]] ; then echo "rm /var/lib/postfix/$_file" >> "$log_file" rm /var/lib/postfix/$_file >> "$log_file" 2>&1 if [[ $? -ne 0 ]]; then _success=false fi fi done echo "$postfix_sysv_init_script start" >> "$log_file" 2>&1 $postfix_sysv_init_script start >> "$log_file" 2>&1 if [[ $? -ne 0 ]]; then _success=false fi fi if $_success ; then echo_ok else echo_failed error "$(cat "$log_file")" fi clean_up 0 # --- # - Add Postfix support # ---