X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=blobdiff_plain;f=tools%2Ffix_date.sh;h=2c2344d64e1bdadb259bfb812559d140f7550003;hp=12718415159030243bb29ef0066b30726fa5dbeb;hb=723acc9063cd53cbf22810724135da2be370c703;hpb=f51555adba9e34fd927997e4a922a89ffd72b33a diff --git a/tools/fix_date.sh b/tools/fix_date.sh old mode 100644 new mode 100755 index 127184151..2c2344d64 --- a/tools/fix_date.sh +++ b/tools/fix_date.sh @@ -1,70 +1,246 @@ #!/bin/sh +# * Copyright 2004 Tristan Chabredier +# * +# * This file is free software; you can redistribute it and/or modify it +# * under the terms of the GNU General Public License as published by +# * the Free Software Foundation; either version 3 of the License, or +# * (at your option) any later version. +# * +# * This program is distributed in the hope that it will be useful, but +# * WITHOUT ANY WARRANTY; without even the implied warranty of +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# * General Public License for more details. +# * +# * You should have received a copy of the GNU General Public License +# * along with this program; if not, write to the Free Software +# * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# fix_date.sh helper script to fix non-standard date or add missing +# date header to emails + # usage: fix_date.sh [..] # It will replace the Date: value w/ the one picked up from more recent -# Received: field if this field resides in one line. Otherwise, it will -# take the file modification time (using a RFC 2822-compliant form). -# If no X-Original-Date already exist, the former Date value will be set -# in such field. +# Fetchinfo time header, Received: field.. Otherwise, it will take the file +# modification time (using a RFC 2822-compliant form). +# Any already existing X-Original-Date is kept, if missing we're adding it +# if the Date: was set (even if set w/ non conform value) + +# TODO: fallback to X-OriginalArrivalTime: ? + +VERSION="0.1.2" + + +version() +{ + echo "$VERSION" + exit 0 +} + +usage() +{ + echo "usage:" + echo " ${0##*/} [] [ ..]" + echo "switches:" + echo " --help display this help then exit" + echo " --version display version information then exit" + echo " --force always force (re-)writing of Date: header" + echo " --rfc force re-writing of Date: header when it's not RFC-compliant" + echo " --debug turn on debug information (be more verbose)" + echo " --strict use RFC-strict matching patterns for dates" + echo " -- end of switches (in case a filename starts with a -)" + exit $1 +} + +date_valid() +{ + test $STRICT -eq 1 && \ + REGEXP="$DATE_REGEXP_STRICT" || \ + REGEXP="$DATE_REGEXP" + + echo "$1" | grep -qEim 1 "$REGEXP" + DATE_VALID=$? +} + +dump_date_fields() +{ + test -z "$X_ORIGINAL_DATE" -a -n "$DATE" && \ + echo "X-Original-Date:$DATE" >> "$TMP" + echo "Date:$REPLACEMENT_DATE" >> "$TMP" +} -if [ $# -lt 1 ] +# use --force to always (re-)write the Date header +# otherwise, the Date header will be written if only it doesn't exist +FORCE=0 +# use --rfc to (re-)write the Date header when it's not RFC-compliant +# otherwise, the Date header will be written if only it doesn't exist +RFC=0 +# use --debug to display more information about what's performed +DEBUG=0 +# use --strict to use strict matching patterns for date validation +STRICT=0 +# 0 = valid, always valid until --strict is used, then date_valid overrides this value +DATE_VALID=0 + +while [ -n "$1" ] +do + case "$1" in + --help) usage 0;; + --version) version;; + --force) FORCE=1;; + --debug) DEBUG=1;; + --rfc) RFC=1;; + --strict) STRICT=1;; + --) shift + break;; + -*) echo "error: unrecognized switch '$1'" + usage 1;; + *) break;; + esac + shift +done + +if [ $FORCE -eq 1 -a $RFC -eq 1 ] then - echo "usage: ${0##*/} [ ..]" - exit 1 + echo "error: use either --force or --rfc, but not both at the same time" + usage 1 fi +test $# -lt 1 && \ + usage 1 + TMP="/tmp/${0##*/}.tmp" +HEADERS="/tmp/${0##*/}.headers.tmp" +BODY="/tmp/${0##*/}.body.tmp" + +DATE_REGEXP='( (Mon|Tue|Wed|Thu|Fri|Sat|Sun),)? [0-9]+ (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) [0-9]+ [0-9]+:[0-9]+:[0-9]+ [-+]?[0-9]+' +DATE_REGEXP_STRICT='(Mon|Tue|Wed|Thu|Fri|Sat|Sun), [0-9]+ (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) [0-9]+ [0-9]+:[0-9]+:[0-9]+ [-+]?[0-9]+' + while [ -n "$1" ] do - test ! -s "$1" && \ + # skip if file is empty or doesn't exist + if [ ! -s "$1" ] + then + shift continue + fi + SKIP=0 + + # split headers and body + # get the empty line (separation between headers and body) + SEP=`grep -nEm1 "^$" "$1" 2>/dev/null | cut -d ':' -f 1` + if [ -z "$SEP" -o "$SEP" = "0" ] + then + cp -f "$1" "$HEADERS" + :> "$BODY" + else + sed -n '1,'`expr $SEP - 1`'p' "$1" > "$HEADERS" + sed '1,'`expr $SEP - 1`'d' "$1" > "$BODY" + fi - X_ORIGINAL_DATE=$(grep -Eim 1 '^X-Original-Date: ' "$1" | cut -d ':' -f 2) - DATE=$(grep -Eim 1 '^Date: ' "$1" | cut -d ':' -f 2) - RECEIVED_DATE=$(grep -Eim 1 ';( (Mon|Tue|Wed|Thu|Fri|Sat|Sun),)? [0-9]+ (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dev) [0-9]+ [0-9]+:[0-9]+:[0-9}+ [-+][0-9]+' "$1" | cut -d ';' -f 2) -# strict, day of week needed -# RECEIVED_DATE=$(grep -Eim 1 '; (Mon|Tue|Wed|Thu|Fri|Sat|Sun), [0-9]+ (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dev) [0-9]+ [0-9]+:[0-9]+:[0-9}+ [-+][0-9]+' "$1" | cut -d ';' -f 2) - FILE_DATE=$(ls -l --time-style="+%a, %d %b %Y %X %z" "$1" | tr -s ' ' ' ' | cut -d ' ' -f 6-11) + # work on headers only + + # get the Date and X-Original-Date + X_ORIGINAL_DATE=`sed -n '/^X-Original-Date:/,/^[^\t]/p' "$HEADERS" | head -n -1 | cut -d ':' -f 2-` + DATE=`sed -n '/^Date:/,/^[^\t]/p' "$HEADERS" | head -n -1 | cut -d ':' -f 2-` + + # work on headers, minus Date and X-Original-Date + test -n "$X_ORIGINAL_DATE" && \ + sed -i '/^X-Original-Date:/,/^[^\t]/d' "$HEADERS" + test -n "$DATE" && \ + sed -i '/^Date:/,/^[^\t]/d' "$HEADERS" + + # found a replacement date in Fetchinfo headers + FETCH_DATE=`grep -im1 'X-FETCH-TIME: ' "$HEADERS" | cut -d ' ' -f 2-` + + # or in Received: headers .. + test $STRICT -eq 1 && \ + REGEXP="$DATE_REGEXP" || \ + REGEXP="$DATE_REGEXP_STRICT" + RECEIVED_DATE=`sed -n '/^Received:/,/^[^\t]/p' "$HEADERS" | head -n -1 | grep -Eoim 1 "$REGEXP"` + + # .. or from FS + FILE_DATE=`LC_ALL=POSIX LANG=POSIX ls -l --time-style="+%a, %d %b %Y %X %z" "$1" | tr -s ' ' | cut -d ' ' -f 6-11` # we could also use the system date as a possible replacement - #SYSTEM_DATE="$(date -R)" + SYSTEM_DATE="`date -R`" # determine which replacement date to use - if [ -z "$RECEIVED_DATE" ] + if [ -z "$FETCH_DATE" ] then - # don't forget to add the leading whitespace - REPLACEMENT_DATE=" $FILE_DATE" + if [ -z "$RECEIVED_DATE" ] + then + # don't forget the leading whitespace here + REPLACEMENT_DATE=" $FILE_DATE" + REPLACEMENT="file date" +# REPLACEMENT_DATE=" $SYSTEM_DATE" +# REPLACEMENT="system date" + else + REPLACEMENT_DATE="$RECEIVED_DATE" + REPLACEMENT="received date" + fi else - REPLACEMENT_DATE="$RECEIVED_DATE" + # don't forget the leading whitespace here + REPLACEMENT_DATE=" $FETCH_DATE" + REPLACEMENT="Fetchinfo time header" fi - # ensure that a X-Original-Date is set - if [ -z "$X_ORIGINAL_DATE" ] + # ensure that the original X-Original-Date is kept + :> "$TMP" + if [ -n "$X_ORIGINAL_DATE" ] then - test -z "$DATE" && \ - echo "X-Original-Date:$REPLACEMENT_DATE" > "$TMP" || \ - echo "X-Original-Date:$DATE" > "$TMP" - else - :> "$TMP" + echo "X-Original-Date:$X_ORIGINAL_DATE" >> "$TMP" fi # replace/set the date and write all lines + test $RFC -eq 1 && \ + date_valid "$DATE" if [ -z "$DATE" ] then - echo "Date:$REPLACEMENT_DATE" >> "$TMP" - cat "$1" >> "$TMP" + test $DEBUG -eq 1 && \ + echo "$1: date not found, using $REPLACEMENT now" + dump_date_fields else - sed "s/^Date: .*/Date:$REPLACEMENT_DATE/" "$1" >> "$TMP" + if [ $FORCE -eq 1 ] + then + test $DEBUG -eq 1 && \ + echo "$1: date already found, replacing with $REPLACEMENT" + dump_date_fields + else + if [ $RFC -eq 1 ] + then + if [ $DATE_VALID -ne 0 ] + then + test $DEBUG -eq 1 && \ + echo "$1: date already found but not RFC-compliant, replacing with $REPLACEMENT" + dump_date_fields + else + test $DEBUG -eq 1 && \ + echo "$1: date already found and RFC-compliant, skipping" + SKIP=1 + fi + else + test $DEBUG -eq 1 && \ + echo "$1: date already found, skipping" + SKIP=1 + fi + fi fi - # uncomment the following line to backup the original file - #mv -f "$1" "$1.bak" - - mv -f "$TMP" "$1" - if [ $? -ne 0 ] + if [ $SKIP -eq 0 ] then - echo "error while moving $TMP to $1" - exit 1 + # uncomment the following line to backup the original file + #mv -f "$1" "$1.bak" + + cat "$HEADERS" >> "$TMP" + cat "$BODY" >> "$TMP" + mv -f "$TMP" "$1" + if [ $? -ne 0 ] + then + echo "error while moving '$TMP' to '$1'" + exit 1 + fi fi + rm -f "$HEADERS" "$BODY" "$TMP" >/dev/null 2>&1 shift done