#! /usr/bin/awk -f # # fullquotedetector.awk * v2.52 * 2012-10-20 # # Copyright 2003-2010: Andreas Schamanek # License: see end of file # # Use this at your own risk. You have been warned. function usage() { e1 = "usage: fullquotedetector.awk [-- [-v[v]] [-t] [-f] [-d] [-r] [--help]]" e2 = "\n\ -v ... verbose (show a line and a rating)\n\ -vv .. veryverbose (be verbose and show From: and Message-ID)\n\ -t ... technical (print numbers of first and last line of quote)\n\ -f ... skip messages with (fwd) or [Fwd] in Subject: line\n\ -r ... detect Outlook style fullquotes with a simple _grep_\n\ -d ... debug\n\ \n\ Currently set to detect quotes of more than %s lines.\n\ The rating is 0 in case of Outlook style quotes and else it's\n\ (lines of largest quote / lines of allowed quote).\n\n" print e1 > "/dev/stderr" printf e2, maxlines > "/dev/stderr" exit 1 } BEGIN { # how many lines may a quoting have, to be not considered a fullquote maxlines = 16 # variable initialisation maxquote = 0 # number of lines of largest quote found verbose = 0 # verbose mode veryverbose = 0 # veryverbose mode technical = 0 # technical mode forwardskip = 0 # do not skip message that seem to be forwarded forwardedmessage = 0 # message does not look like it was forwarded outlook = 0 # rigid mode (outlook mode) debug = 0 # debugging inquote = 0 # = 1 if current line is part of a quote quoteindex = 0 # numbering the quote sections joinline = 0 # = 1 if previous line ended with = # command line options -v (verbose) for (i = 1; i < ARGC; i++) { if (ARGV[i] == "-v") verbose = 1 else if (ARGV[i] == "-vv") { veryverbose = 1 ; verbose = 1 ; } else if (ARGV[i] == "-t") technical = 1 else if (ARGV[i] == "-f") forwardskip = 1 else if (ARGV[i] == "-r") outlook = 1 else if (ARGV[i] == "-d") debug = 1 else if (ARGV[i] == "--help") usage() else if (ARGV[i] ~ /^-?/) { e = sprintf("fullquotedetector.awk: unrecognized option -- %s", substr(ARGV[i], 2)) print e > "/dev/stderr" print "Try '-- --help'." > "/dev/stderr" } else break delete ARGV[i] } } # end of BEGIN # save lines for veryverbose output /^From:/ { fromfound != 1 && myfrom = $0 fromfound = 1 } /^Message-ID:/ { msgidfound != 1 && mymsgid = $0 msgidfound = 1 } # lines that are quoted with > /^\t?>/ { # count number of lines quotelinecount += 1 # store maximum quotelinecount > maxquote && maxquote = quotelinecount # get number of line where quote started inquote == 0 && quotestart[quoteindex] = NR # let's tell others that we are in midst of a quote inquote = 1 # lines ending with = are likely to be continued at next line joinline = 0 ; $0 ~ /[^=]=$/ && joinline = 1 } #lines that are not quoted with > !/^\t?>/ { if (inquote == 1 && joinline == 1) { # we assume this is a continued line, and we skip it # unless the current line ends with = we stop joining if ( $0 ~ /[^=]$/ ) { joinline = 0 } next } if (inquote == 1) { # get number of line where quote stopped # if we were at the largest found (until now) maxquote == quotelinecount && quoteend[quoteindex] = NR - 1 # increment quoteindex (counting number of quotes) # note: quoteindex is only incremented if the last quote # was the largest found (until now) maxquote == quotelinecount && quoteindex += 1 # set number of lines of former quote to 0 quotelinecount = 0 } # let's tell others that we are outside of a quote inquote = 0 } /^ *------* ?(Original Message|(Urspr.*ngliche N|Original(-N|n))achricht) ?------*/ { # detect outlook style fullquotes for option -r outlookFQfound = 1 } /^(Subject|Betreff): (.*(\(fwd\)|Fwd)|F[Ww]: )/ { # message seems to have forwarded message in it # do not remove outlook style messages forwardedmessage = 1 } END { # if the last line processed was within a quote we have to # finish our records, i.e. get values for quoteend and quoteindex # we test whether we were still within a quote and if this FQ was # the largest found. if not we do not care about it. if ( inquote == 1 && maxquote == quotelinecount ) { quoteend[quoteindex] = NR quoteindex += 1 } returncode = 0 # if message seems to have forwarded message in it # we do not remove outlook style fullquotes if ( forwardedmessage == 1 ) { outlookFQfound = 0 } # if longest quote found (maxquote) is longer than maxlines # return number of lines if ( maxquote > maxlines || outlookFQfound == 1 ) { # if we are not in rigid mode (do not look for outlook quotes) if ( outlook == 0 ) { # and there is a normal FQ maxquote > maxlines && returncode = maxquote # else it returncode is 0 } else { # we want to detect outlook style FQs, too outlookFQfound == 1 ? returncode = 1 : returncode = maxquote } # check upper bound of returncode returncode > 255 && returncode = 255 # rating is 0 if outlook quote found else it's calculated outlookFQfound == 1 ? rating = 0 : rating = maxquote / maxlines if ( veryverbose == 1 ) { print myfrom print mymsgid } if ( verbose == 1 ) { # if message seems to have forwarded message in it if ( forwardedmessage == 1 && forwardskip == 1 ) { printf "message seems to contain forwarded data,\nthe following is informational only because of option -f:\n" } if ( outlook == 0 && outlookFQfound == 1 ) { printf "no fullquote found.\n(we did find an outlook style fullquote, but option -r was not given)\n" } else { printf "fullquote found (%2.1f)\n", rating } } if ( technical == 1 && maxquote > maxlines ) { # do nothing if message seems to be forwarded and forwardskip requested if ( forwardedmessage == 0 || forwardskip == 0 ) { print "-v qstart=" quotestart[quoteindex - 1], \ "-v qend=" quoteend[quoteindex - 1] } } if ( veryverbose == 1 ) print "" } # if message seems to have forwarded message in it and -f was given # returncode is being reset to 0 if ( forwardedmessage == 1 && forwardskip == 1 ) { returncode = 0 } if ( debug == 1 ) { if ( verbose == 1 ) print "verbose report requested" print "# of lines in longest quote found (maxquote) ", maxquote print "# of lines in longest quote allowed (maxlines) ", maxlines print "longest quote started at line ", quotestart[quoteindex - 1] print "longest quote ended at line ", quoteend[quoteindex - 1] if ( outlookFQfound == 1 ) print "an outlook style fullquote was found" if ( forwardedmessage == 1 ) { print "message looks like it has a (fwd)" if ( forwardskip == 1 ) print "you requested to skip it (returncode = 0)" } printf "maxquote / maxlines = %2.1f\n", maxquote / maxlines printf "rating = %2.1f\n", rating print "scripts return code is", returncode } exit returncode } # end of END # # This script 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 2 of the License, or # (at your option) any later version. # # This script 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 script; if not, write to the # Free Software Foundation, Inc., 59 Temple Place, Suite 330, # Boston, MA 02111-1307 USA