#!/bin/bash
#
# comprime-maildir
#
# Comprime los mensajes en un maildir, modificando sus nombres
# para su interpretacion por el plugin Zlib de dovecot.
#
# Referencia:
# https://wiki.dovecot.org/Plugins/Zlib
#
# Copyright 2011-2017 asic-linux, S.A. de C.V.
# Todos los derechos reservados
#




FECHA="20170908"
VERSION="1.0.0"

DEBUG=0
USA_MONDIR=0

######################################################
#                  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] <maildir>

Comprime los mensajes en <maildir> alterando sus nombres para
ser utilizados por dovecot.

Opciones:

   -V             Muestra el numero de version
   -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
}

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

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

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

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



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

while getopts ":Vc:" opt; do
  case $opt in
    V)
      echo "$(basename $0) $VERSION, $FECHA"
      exit 0
      ;;
    c)
      CONFIGFILE="$OPTARG"
      ;;
    \?)
      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

#####################################################
#             Argumentos posicionales               #
#####################################################

mdir="$1"


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

if [[ -z "$mdir" ]]; then
   despliega_uso
   exit 1
fi

[[ -d "$mdir/cur" && -d "$mdir/tmp" && -d "$mdir/new" ]] || termina_error "$mdir no parece ser un maildir."




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

main () {

find "${mdir}/new" "${mdir}/cur" -type f -not -name "*,*Z*" | while read f; do

   suffix=""
   zname=""
   bzbase=""

   fbase=$(basename "$f")
   fdir=$(dirname "$f")
   bzfile="${mdir}/tmp/${fbase}"
   bzbase="$fbase"

      
   # Ya tiene un S=nnnnn?
   if ! [[ $f =~ ,S=[0-9]+ ]]; then
      sflag=",S=$(stat -c %s "$f")"
   else
      sflag=""
   fi

   # Ya tiene flags?
   if [[ $f =~ :[0-9],.*$ ]]; then
      # Agregamos la bandera Z
      bzbase="${bzbase}Z"
   else
      bzbase="${bzbase}:2,Z"
   fi

   # Agregamos el campo S=size si no lo teniamos.
   # ${sflag} estara vacio si el nombre del archivo
   # ya tenia un S=size y esta operacion dejara
   # el nombre como esta en ese caso.
   bzbase=$(echo "${bzbase}" | sed "s/:/${sflag}:/g")


   # Primero lo comprimimos en tmp/
   bzip2 < "$f" > "$bzfile" || termina_error "comprimiendo el archivo ($bzfile)"
   # Queremos la misma hora que tenia el original
   touch  -r "$f" "$bzfile" || termina_error "ajustando el tiempo de modificacion del archivo comprimido"
   if [ -r "$f" ]; then
      # Lo movemos a donde estaba el original, con el sufijo correcto
      mv "$bzfile" "$f" && mv -v "$f" "${fdir}/${bzbase}" || termina_error "moviendo el archivo comprimido a su lugar"
   fi

done
}

main
rm -f $ERRFILE
exit $?

