fix_date.sh 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. #!/bin/sh
  2. # usage: fix_date.sh <filename> [<filename>..]
  3. # It will replace the Date: value w/ the one picked up from more recent
  4. # Received: field if this field resides in one line. Otherwise, it will
  5. # take the file modification time (using a RFC 2822-compliant form).
  6. # If no X-Original-Date already exist, the former Date value will be set
  7. # in such field.
  8. VERSION="0.0.4"
  9. function version()
  10. {
  11. echo "$VERSION"
  12. exit 0
  13. }
  14. function usage()
  15. {
  16. echo "usage:"
  17. echo " ${0##*/} [<switches>] <filename> [<filename> ..]"
  18. echo "switches:"
  19. echo " --help display this help then exit"
  20. echo " --version display version information then exit"
  21. echo " --force always force (re-)writing of Date: header"
  22. echo " --rfc force re-writing of Date: header when it's not RFC-compliant"
  23. echo " --debug turn on debug information (be more verbose)"
  24. echo " --strict use RFC-strict matching patterns for dates"
  25. echo " -- end of switches (in case a filename starts with a -)"
  26. exit $1
  27. }
  28. function date_valid()
  29. {
  30. test $STRICT -eq 1 && \
  31. REGEXP="$DATE_REGEXP_STRICT" || \
  32. REGEXP="$DATE_REGEXP"
  33. echo "$1" | grep -qEim 1 "$REGEXP"
  34. DATE_VALID=$?
  35. }
  36. # use --force to always (re-)write the Date header
  37. # otherwise, the Date header will be written if only it doesn't exist
  38. FORCE=0
  39. # use --rfc to (re-)write the Date header when it's not RFC-compliant
  40. # otherwise, the Date header will be written if only it doesn't exist
  41. RFC=0
  42. # use --debug to display more information about what's performed
  43. DEBUG=0
  44. # use --strict to use strict matching patterns for date validation
  45. STRICT=0
  46. # 0 = valid, always valid until --strict is used, then date_valid overrides this value
  47. DATE_VALID=0
  48. while [ -n "$1" ]
  49. do
  50. case "$1" in
  51. --help) usage 0;;
  52. --version) version;;
  53. --force) FORCE=1;;
  54. --debug) DEBUG=1;;
  55. --rfc) RFC=1;;
  56. --strict) STRICT=1;;
  57. --) shift
  58. break;;
  59. -*) echo "error: unrecognized switch '$1'"
  60. usage 1;;
  61. *) break;;
  62. esac
  63. shift
  64. done
  65. if [ $FORCE -eq 1 -a $RFC -eq 1 ]
  66. then
  67. echo "error: use either --force or --rfc, but not both at the same time"
  68. usage 1
  69. fi
  70. test $# -lt 1 && \
  71. usage 1
  72. TMP="/tmp/${0##*/}.tmp"
  73. DATE_REGEXP="( (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]+"
  74. DATE_REGEXP_STRICT="(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]+"
  75. while [ -n "$1" ]
  76. do
  77. # skip if file is empty or doesn't exist
  78. if [ ! -s "$1" ]
  79. then
  80. shift
  81. continue
  82. fi
  83. X_ORIGINAL_DATE=$(grep -Eim 1 '^X-Original-Date: ' "$1" | cut -d ':' -f 2-)
  84. DATE=$(grep -Eim 1 '^Date: ' "$1" | cut -d ':' -f 2-)
  85. test $STRICT -eq 1 && \
  86. RECEIVED_DATE=$(grep -Eim 1 ";$DATE_REGEXP" "$1" | cut -d ';' -f 2) || \
  87. RECEIVED_DATE=$(grep -Eim 1 "; $DATE_REGEXP_STRICT" "$1" | cut -d ';' -f 2)
  88. FILE_DATE=$(ls -l --time-style="+%a, %d %b %Y %X %z" "$1" | tr -s ' ' ' ' | cut -d ' ' -f 6-11)
  89. # we could also use the system date as a possible replacement
  90. #SYSTEM_DATE="$(date -R)"
  91. # determine which replacement date to use
  92. if [ -z "$RECEIVED_DATE" ]
  93. then
  94. # don't forget the leading whitespace here
  95. REPLACEMENT_DATE=" $FILE_DATE"
  96. REPLACEMENT="file date"
  97. # REPLACEMENT_DATE=" $SYSTEM_DATE"
  98. # REPLACEMENT="system date"
  99. else
  100. REPLACEMENT_DATE="$RECEIVED_DATE"
  101. REPLACEMENT="received date"
  102. fi
  103. # ensure that a X-Original-Date is set (but don't override it)
  104. if [ -z "$X_ORIGINAL_DATE" ]
  105. then
  106. if [ -z "$DATE" ]
  107. then
  108. echo "X-Original-Date:$REPLACEMENT_DATE" > "$TMP"
  109. else
  110. test $FORCE -eq 1 && \
  111. echo "X-Original-Date:$DATE" > "$TMP"
  112. fi
  113. else
  114. :> "$TMP"
  115. fi
  116. # replace/set the date and write all lines
  117. test $RFC -eq 1 && \
  118. date_valid "$DATE"
  119. if [ -z "$DATE" ]
  120. then
  121. test $DEBUG -eq 1 && \
  122. echo "$1: date not found, using $REPLACEMENT now"
  123. echo "Date:$REPLACEMENT_DATE" >> "$TMP"
  124. cat "$1" >> "$TMP"
  125. else
  126. if [ $FORCE -eq 1 ]
  127. then
  128. test $DEBUG -eq 1 && \
  129. echo "$1: date already found, replacing with $REPLACEMENT"
  130. sed "s/^Date: .*/Date:$REPLACEMENT_DATE/" "$1" >> "$TMP"
  131. else
  132. if [ $RFC -eq 1 ]
  133. then
  134. if [ $DATE_VALID -ne 0 ]
  135. then
  136. test $DEBUG -eq 1 && \
  137. echo "$1: date already found but not RFC-compliant, replacing with $REPLACEMENT"
  138. sed "s/^Date: .*/Date:$REPLACEMENT_DATE/" "$1" >> "$TMP"
  139. else
  140. test $DEBUG -eq 1 && \
  141. echo "$1: date already found and RFC-compliant, skipping"
  142. cat "$1" >> "$TMP"
  143. fi
  144. else
  145. test $DEBUG -eq 1 && \
  146. echo "$1: date already found, skipping"
  147. cat "$1" >> "$TMP"
  148. fi
  149. fi
  150. fi
  151. # uncomment the following line to backup the original file
  152. #mv -f "$1" "$1.bak"
  153. mv -f "$TMP" "$1"
  154. if [ $? -ne 0 ]
  155. then
  156. echo "error while moving '$TMP' to '$1'"
  157. exit 1
  158. fi
  159. shift
  160. done
  161. exit 0