commit 4fca6babf920e22ce13cfa2309c1b2e6bc854214 Author: Christoph Date: Sat Dec 23 16:43:58 2017 +0100 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dece8a1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.swp +conf/*.conf +log/* +messages/* diff --git a/conf/mail_to_listadmins.conf.sample b/conf/mail_to_listadmins.conf.sample new file mode 100644 index 0000000..f311b7d --- /dev/null +++ b/conf/mail_to_listadmins.conf.sample @@ -0,0 +1,33 @@ +# ---------------------------------------------------- +# --- +# - Default Parameters for script mail_to_listadmins.sh. +# --- +# ---------------------------------------------------- + + +# - MESSAGE_FILE +# - +# - UTF-8 encoded file containing the message that should +# - be sended to the list administrators +# - +# - Default value is empty +# - +#MESSAGE_FILE="" + +# - SENDER_ADDRESS +# - +# - The sender address from which the message to the listadmins +# - will be dended. +# - +# - Defaults value is empty +# - +#SENDER_ADDRESS="" + +# - SUBJECT +# - +# - The subject that will be used with the message that should +# - be sended to the list administrators +# - +# - Default value is empty +# - +#SUBJECT="" diff --git a/mail_to_listadmins.sh b/mail_to_listadmins.sh new file mode 100755 index 0000000..703ee44 --- /dev/null +++ b/mail_to_listadmins.sh @@ -0,0 +1,820 @@ +#!/usr/bin/env bash + +working_dir="$(dirname "$(realpath $0)")" +conf_file="${working_dir}/conf/mail_to_listadmins.conf" + +_date="$(date +%Y-%m-%d-%H%M)" + +log_dir="${working_dir}/log" +log_file="${log_dir}/mail_to_listadmins.${_date}.log" + +schleuder_conf_file="/etc/schleuder/schleuder.yml" + +LOCK_DIR="$(mktemp -d)" +err_msg="${LOCK_DIR}/err_msg.log" + +#----------------------------- +# Some variables definitions +#----------------------------- + +declare -a schleuder_domains_arr +declare -a schleuder_lists_arr + +declare -a lists_done +declare -a lists_failed +declare -a lists_warn + +#----------------------------- +# Base Function(s) +#----------------------------- + +clean_up() { + + # Perform program exit housekeeping + rm -rf $LOCK_DIR + exit $1 +} + +echo_log() { + echo "$*" >> "$log_file" +} + +echo_log_done() { + echo "[ done ] $*" >> "$log_file" +} +echo_log_failed() { + echo "[ Error ] $*" >> "$log_file" +} +echo_log_skipped() { + echo "[ skipped ] $*" >> "$log_file" +} + +echononl(){ + if $terminal && $LOGGING ; 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 ]: $*" + echo "" + echo -e " \033[31m\033[1mScript was interupted\033[m!" + else + echo " [ Fatal ]: $*" + echo "" + echo " Script was terminated...." + fi + echo "" + clean_up 1 +} + +error (){ + echo "" + if $terminal ; then + echo -e " [ \033[31m\033[1mError\033[m ]: $*" + else + echo " [ Error ]: $*" + fi + echo "" +} + +warn (){ + echo "" + if $terminal ; then + echo -e " [ \033[33m\033[1mWarning\033[m ]: $*" + else + echo " [ Warning ]: $*" + fi + echo "" +} + +info (){ + echo "" + if $terminal ; then + echo -e " [ \033[32m\033[1mInfo\033[m ]: $*" + else + echo " [ Info ]: $*" + fi + echo "" +} + +echo_done() { + if $terminal ; then + echo -e "\033[75G[ \033[32mdone\033[m ]" + else + echo " [ done ]" + fi +} + +echo_failed(){ + if $terminal && $LOGGING ; then + echo -e "\033[75G[ \033[1;31mfailed\033[m ]" + else + echo " [ failed ]" + fi +} + +echo_skipped() { + if $terminal && $LOGGING ; then + echo -e "\033[75G[ \033[33m\033[1mskipped\033[m ]" + else + echo " [ skipped ]" + fi +} + +function usage () { + + if [ -n "$1" ];then + echo -e "\nError: $1" + fi + + echo -e " + +Usage: \033[1m$(basename $0) [-h] [<-s email-address>] [-f ]\033[m + +$(basename $0) sends a message, reading from a given file, to all list administrators of +all supported schleuder3 lists. + +The given message file (and within the containing text) must be UTF8 encoded. In the +message, you can use the parameter string '@LIST@' which will be replaced by the +full qualified list address for the appropriate list. + +\033[1mNotice\033[m +The keyring of the user invoking this script (for now only user 'root' is possible) +must contain the private key for the given sender address. The script will ask you +for the concerning passwort. + +The message file may contain string \033[1m@LIST@\033[m which will be replaced +by the list address. + +Parameters not given on the commandline will be interactivly ask for. + + +Optinal Control Options: + + -h + print that help text + + + -b Subject + subject name of the e-mail. + + -p Password + Password for the secret key of the sender address. Its \033[1mhighly not recommend\033[m + to use this parameter, because the password is prompted out and maybe also + saved in the shell's history file. If omitting this option, the script will + ask for the password. The password will not be prompted at the commandline. + + + -s Sender Adrress + name of the sender e-mail address. + + + -f Message File + full qualified path tio the file containing the message + + +Example: + + $(basename $0) -b "Listsoftware has changed" -f /root/msg_listadmin.txt -s support@so36.net + +" +clean_up 2 + +} + +# - See https://gist.github.com/epiloque/8cf512c6d64641bde388 +parse_yaml() { + local prefix=$2 + local s + local w + local fs + s='[[:space:]]*' + w='[a-zA-Z0-9_]*' + #fs="$(echo @|tr @ '\034')" + fs="$(echo @|tr @ '\034'|tr -d '\015')" + sed -ne "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \ + -e "s|^\($s\)\($w\)$s[:-]$s\(.*\)$s\$|\1$fs\2$fs\3|p" "$1" | + awk -F"$fs" '{ + indent = length($1)/2; + vname[indent] = $2; + for (i in vname) {if (i > indent) {delete vname[i]}} + if (length($3) > 0) { + vn=""; for (i=0; i "$err_msg" 2>&1; then + error "$(cat "$err_msg")" + fatal "(Schleuder) User '$schleuder_user' does not exists" +fi + + +#----------------------------- +# Read default values from script configuration file +#----------------------------- + +SENDER_ADDRESS="" +MESSAGE_FILE="" +SUBJECT="" + +echo "" +echononl " Loading default Configuration values from $(basename ${conf_file}).." +if [[ ! -f "$conf_file" ]]; then + echo_skipped +else + source "${conf_file}" > $err_msg 2>&1 + if [[ $? -eq 0 ]]; then + echo_done + else + echo_failed + fatal "$(cat $err_msg)" + fi +fi + +[[ -n "$SENDER_ADDRESS" ]] && default_sender_address="$SENDER_ADDRESS" +[[ -n "$MESSAGE_FILE" ]] && default_orig_msg_file="$MESSAGE_FILE" +[[ -n "$SUBJECT" ]] && default_subject="$SUBJECT" + + +#----------------------------- +# Read Commandline Parameters +#----------------------------- + +subject="" +sender_address="" +gpg_pw="" +orig_msg_file="" +while getopts b:hf:p:s: opt ; do + case $opt in + b) subject="$OPTARG" + ;; + s) sender_address="$OPTARG" + ;; + p) gpg_pw="$OPTARG" + ;; + f) orig_msg_file="$OPTARG" + ;; + h) usage + ;; + *) usage + esac +done + + +if [[ -z "$orig_msg_file" ]] ; then + echo "" + echo -e "\033[32m--\033[m" + echo "" + echo "Enter full qualified file name containing the message" + echo "you want to send to the list admins." + echo "" + orig_msg_file="" + if [[ -n "$default_orig_msg_file" ]]; then + echononl "Message file [$default_orig_msg_file]: " + read orig_msg_file + if [[ -z "$orig_msg_file" ]]; then + orig_msg_file="$default_orig_msg_file" + fi + else + while [[ -z "$orig_msg_file" ]] ; do + echononl "Message file: " + read orig_msg_file + if [[ -z "$orig_msg_file" ]]; then + echo -e "\n \033[33m\033[1mMessage file is required!\033[m\n" + fi + done + fi +fi + +if [[ ! -f "$orig_msg_file" ]]; then + fatal "Message file \033[1m$orig_msg_file\033[m not found!" +fi + +if [[ -z "$subject" ]]; then + echo "" + echo -e "\033[32m--\033[m" + echo "" + echo "Enter the subject for sending the info e-mails." + echo "" + subject="" + if [[ -n "$default_subject" ]]; then + echononl "Subject [$default_subject]: " + read subject + if [[ -z "$subject" ]]; then + subject="$default_subject" + fi + else + while [[ -z "$subject" ]] ; do + echononl "Subject: " + read subject + if [[ -z "" ]]; then + echo -e "\n \033[33m\033[1mSender e-mail address is required!\033[m\n" + fi + done + fi +fi + +# - To encode a header using this technique you must use this format: +# - +# - =?charset?encoding?encoded-text?= +# - +# - The encoding must be either B or Q, these mean base 64 and quoted-printable respectively. +# - You can read the RFC 1342 document for more information about how they work. +# - +subject_encoded="" +if echo "$subject" 2> /dev/null | file -i - | grep -i -q utf-8 ; then + subject_encoded="=?UTF-8?B?$(echo "$subject" | base64)?=" +fi + + +if [[ -z "$sender_address" ]] ; then + echo "" + echo -e "\033[32m--\033[m" + echo "" + echo "Enter the sender e-mail address you want to use for sending the info e-mails." + echo "" + sender_address="" + if [[ -n "$default_sender_address" ]]; then + echononl "Sender e-mail [$default_sender_address]: " + read sender_address + if [[ -z "$sender_address" ]]; then + sender_address="$default_sender_address" + fi + else + while [[ -z "$sender_address" ]] ; do + echononl "Sender e-mail: " + read sender_address + if [[ -z "" ]]; then + echo -e "\n \033[33m\033[1mSender e-mail address is required!\033[m\n" + fi + done + fi +fi + +# - Secret Key for $sender_address must be present +# - +if ! gpg --list-secret-keys "${sender_address}" > /dev/null 2>&1 ; then + fatal "No secret key for id \"${sender_address}\" found" +fi + + +if [[ -z "$gpg_pw" ]]; then + _gpg_pw_1="X" + _gpg_pw_2="Y" + echo "" + echo -e "\033[32m--\033[m" + echo "" + echo "Enter gpg password for ${sender_address}. The password will not" + echo "be shown at the command line" + echo "" + while [[ "$_gpg_pw_1" != "$_gpg_pw_2" ]] ; do + echononl "Password: " + read -s _gpg_pw_1 + echo + if [ "X$_gpg_pw_1" = "X" ]; then + echo -e "\n \033[33m\033[1mPassword is required!\033[m\n" + continue + fi + echononl "Repeat password: " + read -s _gpg_pw_2 + echo + if [ "X$_gpg_pw_2" = "X" ]; then + echo -e "\n \033[33m\033[1mPassword is required!\033[m\n" + continue + fi + if [ "$_gpg_pw_1" != "$_gpg_pw_2" ];then + echo -e "\n\t\033[33m\033[1mThe given passwords differs!\033[m\n" + else + gpg_pw=$_gpg_pw_1 + fi + done +fi + +gpg-connect-agent reloadagent /bye > /dev/null 2>&1 +if ! $(echo "$gpg_pw" | gpg --trust-model=always --pinentry-mode loopback -o /dev/null --local-user $sender_address --passphrase $gpg_pw -as - > /dev/null 2>&1) ; then + fatal "Password does not match user id '${sender_address}'!" +fi + + +clear +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "" +echo -e " \033[1;32mSettings for script \033[1m$(basename "$0")\033[m" +echo "" +echo -e " Sender Address...................: $sender_address" +echo -e " E-Mail Subject...................: $subject" +if [[ -n "$subject_encoded" ]] ; then + echo -e " E-Mail Subject (utf-8 encoded)...: $subject_encoded" +fi +echo -e " File containing the message......: $orig_msg_file" +echo "" +echo -e " Message: \n\n\033[1m$(cat "$orig_msg_file")\033[m\n" +echo "" + + +echo "" +echononl "Type upper case \033[1;37mYES\033[m to continue executing this script: " +read OK +if [[ "$OK" = "YES" ]] ; then + echo "" + echo -e "\033[32m--\033[m" + echo "" + echo -e " \033[32m----------\033[m" + echo -e " \033[1mStarting Script to inform all Listadmins\033[m" + echo -e " \033[32m----------\033[m" + echo_log "# ----------------------------------------------------------------" + echo_log "# - Log output of script '$(basename $0)' at $_date" + echo_log "# ----------------------------------------------------------------" + echo_log "" + echo_log "----------" + echo_log "Settings for script $(basename "$0"):" + echo_log "----------" + echo_log "" + echo_log "Sender Address...................: $sender_address" + echo_log "E-Mail Subject...................: $subject" + if [[ -n "$subject_encoded" ]] ; then + echo_log "E-Mail Subject (utf-8 encoded)...: $subject_encoded" + fi + echo_log "File containing the message......: $orig_msg_file" + echo_log "" + echo_log "Message: " + echo_log "--" + echo_log "$(cat "$orig_msg_file")" + echo_log "--" + +else + fatal "Abort by user request - Answer as not 'YES'" +fio "" +fi +echo "" + + +echononl " Create log directory" +if [[ ! -d "$log_dir" ]]; then + mkdir "$log_dir" > /dev/null 2>&1 + if [[ $? -ne 0 ]]; then + echo_failed + else + echo_done + fi +else + echo_skipped +fi + +echo "" +echo "" +echo -e " \033[32m----------\033[m" +echo -e " \033[1mSummary Lists at $(hostname -f)\033[m" +echo -e " \033[32m----------\033[m" +echo "" +echo_log "" +echo_log "" +echo_log "----------" +echo_log "Summary Lists at $(hostname -f)" +echo_log "----------" +echo_log + +# - Get Schleuder domains +# - +while IFS= read -r -d '' _dir ; do + schleuder_domains_arr+=("$(basename "$_dir")") +done < <(find "$schleuder_lists_dir" -mindepth 1 -maxdepth 1 -type d -print0) + +echo_log "Schleuder Domains:" +echo -e " \033[32m\033[1mSchleuder Domains\033[m:" +for _domain in ${schleuder_domains_arr[@]} ; do + echo_log " $_domain" + echo " $_domain" +done + +# - Get Schleuder lists +# - +for _domain in ${schleuder_domains_arr[@]} ; do + while IFS= read -r -d '' _list ; do + schleuder_lists_arr+=("$_domain:$(basename "$_list")") + done < <(find "${schleuder_lists_dir}/${_domain}" -mindepth 1 -maxdepth 1 -type d -print0 | sort -z ) +done + +echo_log "" +echo_log "Schleuder Lists" +echo -e "\n \033[32m\033[1mSchleuder Lists\033[m:" +for _val in "${schleuder_lists_arr[@]}" ; do + IFS=':' read -a _val_arr <<< "${_val}" + _domain="${_val_arr[0]}" + _list="${_val_arr[1]}" + if [[ -n "$_last_domain" ]] && [[ "$_last_domain" != "$_domain" ]] ; then + echo_log "" + echo "" + fi + echo_log " ${_domain}: ${_list}" + echo " ${_domain}: ${_list}" + _last_domain="$_domain" +done + +echo "" +echo "" +echo -e " \033[32m----------\033[m" +echo -e " \033[1mMain part of script: inform list admins\033[m" +echo -e " \033[32m----------\033[m" +echo_log "" +echo_log "" +echo_log "----------" +echo_log "Main part of script: inform list admins" +echo_log "----------" + +# - Export key of $sender_address into temporary directory ($LOCK_DIR) +# - +#echononl " Export public key '${sender_address}'.." +#gpg -a --export $sender_address > ${LOCK_DIR}/${sender_address}.asc 2> "$err_msg" +#if [[ $? -ne 0 ]]; then +# echo_log_failed "Export public key '${sender_address}'" +# echo_log "$(cat "$err_msg")" +# echo_failed +# error "$(cat "$err_msg")" +#else +# echo_done +# echo_log_done "Export public key '${sender_address}'" +#fi + +for _val in "${schleuder_lists_arr[@]}" ; do + + _missing_key=false + _message_prepared=false + _message_encrypted=false + + IFS=':' read -a _val_arr <<< "${_val}" + _domain="${_val_arr[0]}" + _list="${_val_arr[1]}" + + msg_file="${LOCK_DIR}/msg-${_list}-${_domain}.txt" + msg_file_encrypted="${LOCK_DIR}/msg_encrypted-${_list}-${_domain}.asc" + + echo_log "" + echo_log "${_list}@${_domain}:" + echo -e "\n \033[32m\033[1m${_domain} - ${_list}\033[m:" + + # - Copy original message in tmp folder ($LOCK_DIR) + # - + cp "$orig_msg_file" "$msg_file" > "$err_msg" 2>&1 + if [[ $? -ne 0 ]]; then + echo_log "$(cat "$err_msg")" + error "$(cat "$err_msg")" + lists_failed+=("${_list}@$_domain") + continue + fi + + echononl " Add List Key to keyring of 'root'" + if ! gpg -k "${_list}@$_domain" > /dev/null 2>&1 ; then + gpg --batch --yes --home "$_list_dir" -a --export ${_list}@$_domain | gpg --import + if [[ $? -ne 0 ]]; then + echo_log_failed "Add List Key to keyring of 'root'" + echo_failed + lists_failed+=("${_list}@$_domain") + continue + else + echo_log_done "Add List Key to keyring of 'root'" + echo_done + fi + else + echo_log_skipped "Add List Key to keyring of 'root'" + echo_skipped + fi + + # - Check if gpg key of $sender_address is part of the keyring. Add key if missing + # - + _list_dir="${schleuder_lists_dir}/${_domain}/${_list}" + echononl " Adding key '$sender_address' to keyring.." + if ! gpg --home "$_list_dir" -k "$sender_address" > /dev/null 2>&1 ; then + #gpg --batch --yes --home "$_list_dir" --import /home/ckubu/support.so36.net.asc > "$err_msg" 2>&1 + gpg --batch --yes -a --export "$sender_address" | gpg --home "$_list_dir" --import > "$err_msg" 2>&1 + if [[ $? -ne 0 ]]; then + echo_log_failed "Adding key '$sender_address' to keyring" + echo_log "$(cat "$err_msg")" + echo_failed + error "$(cat "$err_msg")" + lists_failed+=("${_list}@$_domain") + continue + else + echo_log_done "Adding key '$sender_address' to keyring" + echo_done + fi + _missing_key=true + else + echo_log_skipped "Adding key '$sender_address' to keyring" + echo_skipped + fi + + echononl " Adjust message file for list.." + perl -i -n -p -e "s/\@LIST\@/${_list}\@${_domain}/g" "$msg_file" > "$err_msg" 2>&1 + if [[ $? -ne 0 ]]; then + echo_log_failed "Adjust message file for list" + echo_log "$(cat "$err_msg")" + echo_failed + error "$(cat "$err_msg")" + lists_failed+=("${_list}@$_domain") + else + echo_log_done "Adjust message file for list" + echo_done + _message_prepared=true + fi + + echononl " Encrypt and sign message for list.." + if $_message_prepared ; then + gpg --trust-model=always --pinentry-mode loopback --passphrase $gpg_pw -a -se -u "${sender_address}" -r "${_list}@$_domain" -o "${msg_file_encrypted}" "${msg_file}" > "$err_msg" 2>&1 + if [[ $? -ne 0 ]]; then + echo_log_failed "Encrypt and sign message for list" + echo_log "$(cat "$err_msg")" + echo_failed + error "$(cat "$err_msg")" + lists_failed+=("${_list}@$_domain") + else + echo_log_done "Encrypt and sign message for list" + echo_done + _message_encrypted=true + fi + fi + + if $_message_encrypted ; then + boundery_1="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 33 | head -n 1)" + boundery_2="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 33 | head -n 1)" + message_id="$(cat /dev/urandom | tr -dc 'a-f0-9' | fold -w 8 | head -n 1)-$(cat /dev/urandom | tr -dc 'a-f0-9' | fold -w 4 | head -n 1)-$(cat /dev/urandom | tr -dc 'a-f0-9' | fold -w 4 | head -n 1)-$(cat /dev/urandom | tr -dc 'a-f0-9' | fold -w 4 | head -n 1)-$(cat /dev/urandom | tr -dc 'a-f0-9' | fold -w 12 | head -n 1)@so36.net" + + if [[ -n "$subject_encoded" ]] ; then + subject="$subject_encoded" + fi + + cat < "${LOCK_DIR}/e-mail-${_list}-${_domain}.txt" +Content-Type: multipart/mixed; boundary="$boundery_1"; + protected-headers="v1" +From: so36.NET +To: ${_list}-owner@$_domain +Date: $(date +"%a, %d %b %Y %H:%M:%S %z") +Message-ID: <$message_id> +Subject: $subject + +--$boundery_1 +Content-Type: multipart/mixed; boundary="$boundery_2" + +--$boundery_2 +Content-Type: text/plain; charset=utf-8 +Content-Language: de-DE +Content-Transfer-Encoding: quoted-printable + +EOF + + cat "$msg_file_encrypted" >> "${LOCK_DIR}/e-mail-${_list}-${_domain}.txt" + + cat <> "${LOCK_DIR}/e-mail-${_list}-${_domain}.txt" + +--$boundery_2-- + +--$boundery_1-- +EOF + + echononl " Send info e-mail to list owner .." + cat "${LOCK_DIR}/e-mail-${_list}-${_domain}.txt" | su schleuder -c"/usr/local/bin/schleuder work ${_list}-owner@$_domain" -s /bin/bash + if [[ $? -ne 0 ]]; then + echo_log_failed "Send info e-mail to list owner" + echo_failed + lists_failed+=("${_list}@$_domain") + else + echo_log_done "Send info e-mail to list owner" + echo_done + lists_done+=("${_list}@$_domain") + fi + fi + + echononl " Removing key of '$sender_address' from list keyring.." + if $_missing_key ; then + gpg --batch --yes --home "$_list_dir" --delete-key "$sender_address" > "$err_msg" 2>&1 + if [[ $? -ne 0 ]]; then + echo_log_failed "Removing key of '$sender_address' from list keyring" + echo_log "$(cat "$err_msg")" + echo_failed + warn "$(cat "$err_msg")" + lists_warn+=("${_list}@$_domain") + else + echo_log_done "Removing key of '$sender_address' from list keyring" + echo_done + fi + echononl " Set ownerchip of list keyring back to '${schleuder_user}'" + chown ${schleuder_user}:${schleuder_group} $_list_dir/pubring.* > "$err_msg" 2>&1 + if [[ $? -ne 0 ]]; then + echo_log_failed "Set ownerchip of list keyring back to '${schleuder_user}'" + echo_log "$(cat "$err_msg")" + echo_failed + warn "$(cat "$err_msg")" + lists_warn+=("${_list}@$_domain") + else + echo_log_done "Set ownerchip of list keyring back to '${schleuder_user}'" + echo_done + fi + else + echo_log_skipped "Removing key of '$sender_address' from list keyring" + echo_skipped + fi + +done + +# - Clear cached gpg password +# - +echo "" +echo "" +echo_log "" +echo_log "" +echononl " Clear cached gpg password.." +gpg-connect-agent reloadagent /bye > "$err_msg" 2>&1 +if [[ $? -ne 0 ]]; then + echo_log_failed "Clear cached gpg password" + echo_log "$(cat "$err_msg")" + echo_failed + error "$(cat "$err_msg")" +else + echo_log_done "Clear cached gpg password" + echo_done +fi + +echononl " Archive msg file.." +mv "$orig_msg_file" "${orig_msg_file}.${_date}.sent" +if [[ $? -ne 0 ]]; then + echo_log_failed "Archive msg file" + echo_log "$(cat "$err_msg")" + echo_failed + error "$(cat "$err_msg")" +else + echo_log_done "Archive msg file" + echo_done +fi + +echo "" +echo "" +echo -e " \033[32m----------\033[m" +echo -e " \033[1mStatistics \033[m" +echo -e " \033[32m----------\033[m" +echo "" +echo -e " ${#lists_done[@]} lists successfully informed" +echo -e " ${#lists_warn[@]} lists with warnings" +echo -e " ${#lists_failed[@]} lists failed" +echo_log "" +echo_log "" +echo_log "----------" +echo_log "Statistics" +echo_log "----------" +echo_log +echo_log "${#lists_done[@]} lists successfully informed" +echo_log "${#lists_warn[@]} lists with warnings" +echo_log "${#lists_failed[@]} lists failed" +echo_log +if [[ ${#lists_failed[@]} -gt 0 ]]; then + echo_log "Listadmin(s) not informed:" + echo -e "\n \033[1mListadmin(s) not informed:\033[m" + for _list in "${lists_failed[@]}" ; do + echo -e " $_list" + echo_log " $_list" + done + echo_log + info "See also log file: $log_file" +else + info "See also script output at log file: $log_file" +fi + + +echo "" +clean_up 0 +