#! /usr/bin/gawk -f # Last edited on 2003-10-12 12:35:15 by stolfi BEGIN { abort = -1; # Reads a unix folder from standard input. # Outputs the "Date:" headers from all messages. header = 0; dt = ""; fr = ""; start = 1; } (abort >= 0) { exit abort; } /^From[ \011].*[0-9]*[0-9]$/ { if (header) { warning("message without body", fr); output_date(dt, fr); } header = 1; fr = $0; ad = $2; dt = ""; start = FNR; next; } // { if (fr == "") { warning("headerless line at top of file", $0); next; } } /^[ \011]*$/ { if (header) { header = 0; output_date(dt, fr, start); } next; } /^Date:/ { if (header) { if (dt != "") { warning("message with multiple `Date:'", dt); } dt = $0; } else { # warning("`Date:' in message body", $0); } next; } // { next; } END { if (abort >= 0) { exit abort; } if (header) { warning("message without body", fr); if (fr != "") { output_date(dt, fr, start); } } } function output_date(dt,fr,start) { if (dt != "") { print dt; } else if (fr != "") { if ((ad ~ /^stolfi([@]|$)/) || (ad ~ /^VM$/)) { # warning("faking `Date:' from `From'", fr); dt = make_date_from_from(fr, start); print dt; } else { warning("message without `Date:'", fr); print fr; } } else { error("no `Date:' or `From' to output", ""); printf "start = %d\n", start; } } function make_date_from_from(fr,start, fld,nf,sender,wd,mth,md,hms,tz,yr) { nf = split(fr,fld); if (nf == 7) { sender = x_sender(fld[2]); wd = x_weekday(fld[3]); mth = x_month(fld[4]); md = x_monthday(fld[5]); hms = x_time(fld[6]); tz = "-0300"; yr = x_year(fld[7]); } else if (nf == 8) { sender = x_sender(fld[2]); wd = x_weekday(fld[3]); mth = x_month(fld[4]); md = x_monthday(fld[5]); hms = x_time(fld[6]); tz = x_timezone(fld[7]); yr = x_year(fld[8]); } else { error("bad `From' line format", fr); sender = (nf < 2 ? "??????" : x_sender(fld[2])); wd = (nf < 3 ? "???" : x_weekday(fld[3])); mth = (nf < 4 ? "???" : x_month(fld[4])); md = (nf < 5 ? "??" : x_monthday(fld[5])); hms = (nf < 6 ? "??:??:??" : x_time(fld[6])); tz = (nf < 7 ? "+????" : x_timezone(fld[7])); yr = (nf < 8 ? "????" : x_year(fld[8])); } if (sender == "VM") { sender = "stolfi"; } return sprintf("Date: %s, %s %s %s %s %s", wd, md, mth, yr, hms, tz); } function x_sender(f) { if (f !~ /^[a-zA-Z0-9]/) { error("bad sender", f); } return f; } function x_weekday(f) { if (f !~ /^[A-Z][a-z][a-z]$/) { error("bad weekday", f); } return f; } function x_month(f) { if (f !~ /^[A-Z][a-z][a-z]$/) { error("bad month", f); } return f; } function x_monthday(f) { if (f !~ /^([0-3]|)[0-9]$/) { error("bad monthday", f); } return f; } function x_time(f) { if (f !~ /^([0-2]|)[0-9][:][0-5][0-9][:][0-5][0-9]$/) { error("bad time", f); } return f; } function x_timezone(f) { if ( (f !~ /^([-+]|)[0-2][0-9][0-5][0-9]$/) && \ (f !~ /^[A-Z][A-Z][A-Z]$/) && \ (f !~ /^GMT[-+][0-9]+$/) \ ) { error("bad timezone", f); } return f; } function x_year(f) { if (f !~ /^(19|20|)[890][0-9]$/) { error("bad year", f); } return f; } function error(msg,lin) { printf "! line %d: %s\n", start, msg > "/dev/stderr"; if (lin != "") { printf "%s\n", lin > "/dev/stderr"; } abort = 1; exit abort; } function warning(msg,lin) { printf "» line %d: %s\n", start, msg > "/dev/stderr"; if (lin != "") { printf "%s\n", lin > "/dev/stderr"; } }