#!/bin/bash
#
# rcptcreate
#
# Crea una lista con todos los destinatarios
# de correo validos en el sistema
#
# Copyright 2011-2017 asic-linux, S.A. de C.V.
# Todos los derechos reservados
#




FECHA="20180122"
VERSION="0.3.1"

DEBUG=0
USA_MONDIR=1

######################################################
#                  Funciones utiles                  #
######################################################


MONDIR="/var/log/mon"
MONFILE=${MONDIR}/`basename $0`

termina_error() {
   # Registramos el suceso en MONDIR
   if [ $USA_MONDIR -gt 0 ]; then
      [ -d "$MONDIR" ] || mkdir -p "$MONDIR"
      if [ $? -gt 0 ]; then
         echo "*** Error al crear $MONDIR" >&2
      else
         echo ----- `date` ----- >> $MONFILE
         echo "*** error: $1" >> "$MONFILE"
         if [ -r $ERRFILE ]; then
            cat $ERRFILE >> "$MONFILE"
         fi
      fi
   fi


   # Informamos via stderr
   echo "*** error: $1" >&2
   if [ -r $ERRFILE ]; then
      cat $ERRFILE >&2
   fi

   rm -f $ERRFILE
   if [ "$2" ]; then
      exit $2
   else
      exit 1
   fi
}


despliega_uso() {
cat << EOF
Uso: $(basename $0) [opciones]

Opciones:

   -V             Muestra el numero de version
   -v             Verbose on
   -c <config>    Ruta al archivo de configuracion (Default: /etc/$(basename $0).conf) 

EOF
}


crea_temp() {
   # Archivo temporal
   local retfile=`mktemp ${TMPBASE}/$(basename $0).XXXXXX`
   if [ $? -gt 0 ]; then
      termina_error "Error al crear archivo temporal en $TMPBASE"
      exit 1
   fi

   echo $retfile
}

crea_temp_dir() {
   # Directorio temporal
   local retdir=`mktemp -d ${TMPBASE}/$(basename $0).XXXXXX`
   if [ $? -gt 0 ]; then
      termina_error "Error al crear directorio temporal en $TMPBASE"
      exit 1
   fi

   echo $retdir
}

comment-clean () {
  sed '/^#/d; s/#.*//g' 
}

verbose () {
   if [[ $VERBOSE -gt 0 ]]; then
      return 0
   else
      return 1
   fi
}


#######################################################
#                      Defaults                       #
#######################################################

# Direccion del administrador del sistema
[ "$ADMIN" ] || ADMIN="monitor@asic-linux.com.mx"

# Archivo de configuracion
[ "$CONFIGFILE" ] || CONFIGFILE="/etc/$(basename $0).conf"

# Verbose?
[ "$VERBOSE" ] || VERBOSE=0

# Ruta para archivos temporales
[ "$TMPBASE" ] || TMPBASE="/tmp"



#######################################################
#              Procesamos las opciones                #
#######################################################

while getopts ":Vvc:" opt; do
  case $opt in
    V)
      echo "$(basename $0) $VERSION, $FECHA"
      exit 0
      ;;
    c)
      CONFIGFILE="$OPTARG"
      ;;
    v)
      VERBOSE=1
      ;;
    \?)
      echo "$(basename $0): Opcion invalida: -$OPTARG" >&2
      despliega_uso
      exit 1
      ;;
    :)
      echo "$(basename $0): Opcion -$OPTARG requiere un argumento" >&2
      exit 1
      ;;
  esac
done

shift $(($OPTIND-1))

# Log de errores
ERRFILE=$( crea_temp ) || termina_error "Error al crear el archivo ERRFILE"

# Leemos el archivo de configuracion
if [ -f "$CONFIGFILE" ]; then
   source "$CONFIGFILE" 2>>$ERRFILE || termina_error "Leyendo el archivo de configuracion $CONFIGFILE"
fi

#####################################################
#            Verificaciones de sanidad              #
#####################################################

#[ -d "$SPOOLDIR" ]  || termina_error "El directorio de spool $SPOOLDIR no existe"



#####################################################
#                Variables globales                 #
#####################################################

locals=$(sort -u /var/qmail/control/locals)


# atlocals()
#
# Imprime una lista de direcciones locales
# usando a su argumento como buzon
#
# @param string nombre del buzon
#

atlocals () {
     for l in $locals; do
        echo ${1}@${l}
     done
     return 0
}


# cuentas-locales
#
# Imprime una lista de direcciones con destino
# en los dominios locales del sistema
#

cuentas-locales () {

   ##### Cuentas locales #####

   local i u d a
   local linea

   # Estas salen de /etc/passwd
   i=0
   while read linea; do
      # Usuario y home
      u=$(echo $linea | cut -f1 -d:)
      d=$(echo $linea | cut -f6 -d:)
      # Solo nos interesa si tiene Maildir y por tanto
      # puede recibir correo
      if [[ -d ${d}/Maildir/new ]]; then
        # Estos nombres son validos para todo lo que
        # hay en /var/qmail/locals
        atlocals "$u"
        # Ahora los alias
        for a in $(find "$d" -maxdepth 1 -type f -name ".qmail-*" ); do
           a=$(basename "$a" | cut -f2- -d- | tr ':' '.' | egrep -v "^default$")
           # Buzon debe ser *algo*
           [[ -z "$a" ]] || atlocals "${u}-${a}"
        done
      fi
   done < /etc/passwd

   # Alias del sistema
   for a in $(find /var/qmail/alias -name ".qmail-*" | cut -f2- -d- | tr ':' '.'); do
      atlocals "$a"
   done

}


# cuentas-virtuales
#
# Imprime una lista de direcciones con destino
# en los dominios virtuales del sistema
#

cuentas-virtuales () {

   ##### Dominios virtuales #####

   local i u d a
   local linea buzon

   OLDHOME="$HOME"
   # Por cada linea de de /var/qmail/contro/virtualdomains
   if [ -r /var/qmail/control/virtualdomains ]; then
      comment-clean < /var/qmail/control/virtualdomains | sort -u | while read linea; do

         ### Primero los buzones de listvdomain ###

         # Usuario y home
         u=$(echo $linea | cut -f2 -d:)
         verbose && echo "u: $u" >&2

         d=$(egrep ^${u}: /etc/passwd | cut -f6 -d:)
         verbose && echo "d: $d" >&2

         v=$(echo $linea | cut -f1 -d:)
         verbose && echo "v: $v" >&2

         if [[ -d "$d" ]]; then
            # Nombre de dominio
            export HOME="$d"
            if [[ -r ${HOME}/passwd.cdb ]]; then
               listvdomain | cut -f1 -d" " | egrep -v "^User$" | while read buzon; do
                  # En vmailmgr un buzon con +@dominio es un catchall
                  # y eso para validrcptto lo representamos con @dominio
                  # (buzon es una cadena vacia)
                  if [[ "${buzon}" == "+" ]]; then
                     buzon=""
                  fi
                  echo "${buzon}@${v}"
               done
            else
               echo "+++ Advertencia: No puedo leer '${HOME}/passwd.cdb' ($linea)" >&2
            fi

            ### Ahora los alias del usuario del dominio virtual ###

            # Eliminamos solo lo que diga unicamente "default" porque eso ya lo maneja vdeliver
            find "$d" -maxdepth 1 \( -type f -o -type l \) -name ".qmail-*" | while read puntoqmail; do
               a=$(echo $(basename "$puntoqmail") | cut -f2- -d- | tr ':' '.' | egrep -v "^default$")

               # Buzon debe ser *algo*
               [[ -z "$a" ]] || echo "${a}@${v}"

            done

         else
            echo "*** '$d' no es un directorio ($linea)" >&2
         fi

      done
   fi
   export HOME="$OLDHOME"
   return 0
}

# cuentas-extra
#
# Agrega las cuentas contenidas en los archivos
# localizados en $QMAILDIR/morercptto
#

cuentas-extra () {

   local i
   for i in /var/qmail/control/morercptto/*; do
      [[ -f "$i" ]] && comment-clean < "$i"
   done
   return 0

}

#####################################################
#                 Bucle principal                   #
#####################################################

main () {

   cuentas-locales
   cuentas-virtuales
   cuentas-extra

}

main
rm -f $ERRFILE
exit $?

