Script di archiviazione dei messaggi in una Maildir

From RVM Wiki
Jump to navigation Jump to search
Attenzione questo articolo è ancora incompleto.
Sentiti libero di contribuire cliccando sul tasto edit.

Questo sposta i messaggi arrivati in una gerarchia

YYYY.MM
#!/bin/bash
# Takes the source file with full path as firtst argument.
# The file must be in a cur directory
# The scripts move the file from
#       /srcpath/cur 
# to
#       /dstpath/.YYYY.MM.DD
# It reads the date from the "Date: " header in the message
# It resets flags from original filename, so all files are Unread
# It avoid overwriting
# Tipically this script is launched using:
# find /srcpath/cur/ -type f -exec move_maildir_from_cur {}  \;

DEBUG=false

VERSION=0.9.9

function usage {
        echo "$SCRIPTNAME - $VERSION"
        echo "Usage:"
        echo "$SCRIPTNAME [-i -z -v] -s src_file -d dst_path"
        echo "-i : Initialize pidfile"
        echo "-z : Clean stale pidfile"
        echo "-s src_file : source file to move (must be in a cur/ folder)"
        echo "-d dst_path : existing destination Maildir folder to move the file to"
}

SCRIPTNAME="$(basename $0)"

CONVERTDATE="/usr/local/bin/convertdate"

#$DEBUG && echo "$SCRIPTNAME - $VERSION"

while getopts "ivzs:d:" Option
do
  case "$Option" in

    i ) echo "Prepare environment"
        if [ "$(id -un)" != "root" ]
        then
                echo You must run this script with -i as user root >&2
                echo Aborting. >&2
                rm -f /var/run/mailarchive/mailarchive.pid
                exit 1
        fi
        mkdir /var/run/mailarchive
        chmod 1777 /var/run/mailarchive
        ;;

    z ) echo "Reset environment"
        if [ "$(id -un)" != "root" ]
        then
                echo You must run this script with -z as user root >&2
                echo Aborting. >&2
                rm -f /var/run/mailarchive/mailarchive.pid
                exit 1
        fi
        rm -f /var/run/mailarchive/mailarchive.pid
        exit 0
        ;;

    s ) SRCFILE="$OPTARG"
        if [ -z "$SRCFILE" ]
        then
                echo "You moust supply src_file to -s argument."
                usage
                echo "Aborting."
                exit 1
        fi
        ;;

    d ) DSTPATH="$OPTARG"
        if [ -z "$DSTPATH" ]
        then
                echo "You moust supply dst_path to -d argument."
                usage
                echo "Aborting."
                exit 1
        fi
        ;;

    v ) echo Running verbose.
        DEBUG=true
        ;;

    * ) echo "Unimplemented option chosen."
        ;;   # DEFAULT

  esac
done

if [[ -z "$SRCFILE" || -z "$DSTPATH" ]]
then
        usage
        exit 1
fi


if [ ! -d /var/run/mailarchive ]
then
        echo /var/run/mailarchive does not exist.
        echo Run 
        echo "$SCRIPTNAME -i"
        echo as root.
        echo Aborting.
        exit 1
fi


#DSTPATH="/home/mnt.vvngrl/test/destination/Maildir"

# Check that there is no pidfile
if [ -f /var/run/mailarchive/mailarchive.pid  ]
then
        echo Pidfile present. Another instance may already running. >&2
        echo Aborting. >&2
        exit 1
fi

echo "$$" > /var/run/mailarchive/mailarchive.pid || {
        echo Cannot create pidfile. >&2
        echo Check that /var/run/mailarchive exists and is world writable >&2
        echo Aborting. >&2
        exit 1
}


# Check that source file is contained in 
# srcpath/cur

if ( ! echo "$SRCFILE" | grep -q '/cur' )
then
        echo "$(basename $SRCFILE) is not in a ./cur folder." >&2
        echo Aborting. >&2
        rm -f /var/run/mailarchive/mailarchive.pid 
        exit 1
fi

# Destination path exist ?
if [ ! -d "$DSTPATH" ]
then
        echo Destination path does not exist or is not accessible. >&2
        echo Aborting. >&2
        rm -f /var/run/mailarchive/mailarchive.pid
        exit 1
fi

# convertdate exist ?
if [ ! -x "$CONVERTDATE" ]
then
        echo "$DONVERTDATE not found." >&2
        echo Aborting. >&2
        rm -f /var/run/mailarchive/mailarchive.pid
        exit 1
fi

if [ ! -f "$SRCFILE" ]
# Check if the source file to move exists.

# The source filename is formatted as this:
#
# http://cr.yp.to/proto/maildir.html
#
# Example:
# 1237458264.V900If102c2M108510.crosrv02:2,S
# unixtime  .unique identifier .hostname:2 , FLAGS
#
# 1237458264           = unixtime ( i.e. date +%s )
# V900 If102c2 M108510 = unique identifier
#                       V900    = V hexadecimal UNIX device number of this file
#                       If102c2 = I hexadecimal UNIX inode  number of this file
#                       M108510 = M decimal microsecond counter from the same 
#                                 gettimeofday()
# :2,     = Fixed parameter, always this
#
# ,S = FLAGS
#      "P" (passed)
#      "R" (replied)
#      "S" (seen)
#      "T" (trashed)
#      "D" (draft)
#      "F" (flagged)
#      Flags must be stored in ASCII order: e.g., "2,FRS"
#      If the file comes from Maildir/new, it has not :,FLAGS
#
# Example:
# 1237458264.V900If102c2M108510.crosrv02:2,S

then
        echo "[01] Cannot find or read $SRCFILE." >&2
        rm -f /var/run/mailarchive/mailarchive.pid
        exit 1
fi

# Get Owner of srcfile
USERID="$(stat --format=%U $SRCFILE)"

# Check that user running this script is the same as the owner of the file
if [ "$(id -un)" != "$USERID" ]
then
        echo "You must run this script as user $USERID" >&2
        echo Aborting. >&2
        rm -f /var/run/mailarchive/mailarchive.pid
        exit 1
fi

# strip path form argument
ORIGINALNAME="$(basename "$SRCFILE")"

# Get FILENAME without FLAGS
FILENAME="$(echo $ORIGINALNAME | cut -f 1 --delim=':')"

# Get FLAGS, if they exists
if ( echo "$ORIGINALNAME" | grep -q ':' )
then
        FILEFLAGS="$(echo $ORIGINALNAME | cut -f 2 --delim=':')"
#       # If source file has flags, it does not come from a /new folder
#       if [ -n "$FILEFLAGS" ]
#       then
#               echo $ORIGINALNAME has FLAGS=$FILEFLAGS >&2
#               echo Aborting. >&2
#               rm -f /var/run/mailarchive/mailarchive.pid
#               exit 1
#       fi
fi

# Get Timestamp
FILETIMESTAMP="$(echo "$FILENAME" | cut -f 1 --delim='.')"

# Get UUID
FILEUUID="$(echo "$FILENAME" | cut -f 2 --delim='.')"

# Get Hostname
FILEHOST="$(echo "$FILENAME" | cut -f 3 --delim='.')"

# Get Device Number
FILEUUID1="$(echo "$FILEUUID" | cut -f 2 --delim='V' | cut -f 1 --delim="I")"

# Get Inode Number
FILEUUID2="$(echo "$FILEUUID" | cut -f 2 --delim='I' | cut -f 1 --delim="M" )"

# Get Microseconds
FILEUUID3="$(echo "$FILEUUID" | cut -f 2 --delim='M')"

$DEBUG && {
        echo -e "ORIGINALNAME=\t$ORIGINALNAME"
        echo -e "FILENAME=\t$FILENAME"
        echo -e "FILEFLAGS=\t$FILEFLAGS"
        echo -e "FILETIMESTAMP=\t$FILETIMESTAMP"
        echo -e "FILEUUID=\t$FILEUUID"
        echo -e "FILEHOST=\t$FILEHOST"
        echo -e "REBUILD=\t$FILETIMESTAMP.$FILEUUID.$FILEHOST:$FILEFLAGS"
        echo -e "UUBUILD=\tV${FILEUUID1}I${FILEUUID2}M${FILEUUID3}"
}


LINE="$(/bin/ls -al $SRCFILE)"
# -rwxr-xr-x 1 mailarchive mailarchive   46 2009-03-18 12:59 filename
$DEBUG && echo $LINE

# Get date from Date:
DATE="$(grep -m1 '^Date:' $SRCFILE | cut -f 2- --delim=":")"
$DEBUG && echo $DATE

# Use perl script to reformat date
DATE="$(echo $DATE | $CONVERTDATE )"
if [ -z "$DATE" ]
then
        echo Cannot extract Date. Check you have libdate-manip-perl installed. >&2
        echo Aborting. >&2
        rm -f /var/run/mailarchive/mailarchive.pid
        exit 1
fi
$DEBUG && echo $DATE

# Extract year
YEAR="$(echo $DATE | cut -f 1 --delim='-')"
$DEBUG && echo $YEAR
# Extract month
MONTH="$(echo $DATE | cut -f 2 --delim='-')"
$DEBUG && echo $MONTH
# Extract day of month
#DAY=$(echo $DATE | cut -f 3 --delim='-')
#$DEBUG && echo $DAY

# If not Exist create Maildir Folder for Year
if [ ! -d "$DSTPATH.$YEAR" ] 
then
        $DEBUG && echo "Creating $DSTPATH.$YEAR"
        maildirmake "${DSTPATH}.${YEAR}" || \
                {       echo Cannot create "$DSTPATH.$YEAR" >&2
                        rm -f /var/run/mailarchive/mailarchive.pid
                        exit 127
                }

        #chmod g+rX "${DSTPATH}.${YEAR}" || \
        #{      echo [02] Error chmodding $DSTPATH.$YEAR >&2
        #       rm -f /var/run/mailarchive/mailarchive.pid
        #       exit 127
        #}

fi 

# If not Exist create Maildir Folder for Month
if [ ! -d "$DSTPATH.$YEAR.$MONTH" ] 
then
        $DEBUG && echo "Creating $DSTPATH.$YEAR.$MONTH"
        maildirmake "$DSTPATH.$YEAR.$MONTH" || \
                {       echo cannot create "$DSTPATH.$YEAR.$MONTH" >&2
                        rm -f /var/run/mailarchive/mailarchive.pid
                        exit 127
                }
        #chmod g+rX "$DSTPATH.$YEAR.$MONTH" || \
        #{      echo [02] Error chmodding $DSTPATH.$YEAR.$MONTH >&2
        #       rm -f /var/run/mailarchive/mailarchive.pid
        #       exit 127
        #}

fi 

# If not Exist create Maildir Folder for Day
#if [ ! -d $DSTPATH/.$YEAR.$MONTH.$DAY ] 
#then
#       $DEBUG && echo Creating $DSTPATH/.$YEAR.$MONTH.$DAY
#       maildirmake $DSTPATH/.$YEAR.$MONTH.$DAY || \
#               {       echo cannot create $DSTPATH/.$YEAR.$MONTH.$DAY >&2
#                       rm -f /var/run/mailarchive/mailarchive.pid
#                       exit 127
#               }

#       chmod g+rX "$DSTPATH/.$YEAR.$MONTH.$DAY" || \
#       {       echo [02] Error chmodding $DSTPATH.$YEAR.$MONTH.$DAY >&2
#               rm -f /var/run/mailarchive/mailarchive.pid
#               exit 127
#       }
#fi 

# Avoid Overwriting
if [ -f "$DSTPATH.$YEAR.$MONTH/cur/$FILENAME*" ] 
then
        $DEBUG && echo "Destination filename exists: $FILENAME "
        $DEBUG && {
                read -s -n1 -p"Rename it (y/n) ? " REPLY
                if [ "$REPLY" != "y" ]
                then
                        echo User abort request.
                        rm -f /var/run/mailarchive/mailarchive.pid
                        exit 1
                fi
        }

        while [ -f "$DSTPATH.$YEAR.$MONTH/cur/$FILENAME*" ]
        do
                # change name
                # Incrementa il microsecond di uno
                FILEUUID3="$(($FILEUUID3+1))"
                FILEUUID="V${FILEUUID1}I${FILEUUID2}M${FILEUUID3}"
                FILENAME="$FILETIMESTAMP.$FILEUUID.$FILEHOST"
                $DEBUG && echo "New FILENAME is $FILENAME"
        done
fi 

$DEBUG && echo "Destination filename will be $FILENAME:$FILEFLAGS"
$DEBUG && echo mv "$SRCFILE" "$DSTPATH.$YEAR.$MONTH/cur/$FILENAME:$FILEFLAGS"
$DEBUG && {
        read -s -n1 -p"Move it (y/n) ? " REPLY
        if [ "$REPLY" != "y" ]
        then
                echo User abort request.
                rm -f /var/run/mailarchive/mailarchive.pid
                exit 1
        fi
}


# Move file
echo "$SRCFILE -> .$YEAR.$MONTH"

mv -f  "$SRCFILE" "$DSTPATH.$YEAR.$MONTH/cur/$FILENAME:$FILEFLAGS" || \
        {       echo [02] Error moving file >&2
                echo Filename="$SRCFILE" >&2
                echo Destination=$DSTPATH.$YEAR.$MONTH/cur >&2
                rm -f /var/run/mailarchive/mailarchive.pid
                exit 127
        }

#chmod g+r "$DSTPATH.$YEAR.$MONTH/cur/$FILENAME:2,$FILEFLAGS" || \
#       {       echo [02] Error chmodding file >&2
#               echo Filename="$SRCFILE" >&2
#               echo Destination=$DSTPATH.$YEAR.$MONTH/cur >&2
#               rm -f /var/run/mailarchive/mailarchive.pid
#               exit 127
#       }

rm -f /var/run/mailarchive/mailarchive.pid

Riferimenti