A friend's recently had a strange email occurrence,
caused, I think by someone figuring out how to route mail
through a web blog.  The postmaster's mail box was suddenly
flooded with bounced email messages (682924 of them, in
fact).  Since there were some real messages in there as
well (4713), it wasn't practical to simply toss the mailbox.
And the shear size of the mailbox made it impractical to
use his GUI mail user agent's filtering capability.

So I wrote the attached Unicon program to read through a
mail box and sort messages into two files on the basis of
a set of criteria.  The set of criteria can include substrings
in the 'From:' and 'Subject:' lines, any substring match
is considered sufficient.

I'm showing this to the list in case anyone has a similar
need or wants to play; the program could be written better
(it's a quick knock-off) and also extended to allow for more
sophisticated sorting criteria, but running it with:

splitMail --name=root --from="Mail Deliver" --from=MAILER --from=postmaster

was sufficient for my purpose.

Running with no arguments gives a help message.
-- 
Steve Wampler -- [EMAIL PROTECTED]
The gods that smiled on your birth are now laughing out loud.
# splitMail -- split messages from system mailbox by matching substrings in
#              Subject: and/or From: lines

import Utils

record message(from,subject,date,text)

global dryrun, verbose, append, sList, fList

procedure main(args)
    if "--help" == !args then stop(helpMesg())
    whoami := zapPrefix(!args, "--name=")
    verbose := ("--verbose" == !args)
    append := ("--append" == !args)
    dryrun := ("--dryrun" == !args)
    every sList := put([], zapPrefix(!args, "--subject="))
    every fList := put([], zapPrefix(!args, "--from="))
    if /(whoami) then stop(helpMesg())
    if /sList & /fList then stop(helpMesg())

    oMode := if \append then "wa" else "w"

    if \dryrun then verbose := "yes"

    if \verbose then {
        if \append then write(&errout, "append mode")
        if \sList then showList(&errout, "Subject phrases", sList)
        if \fList then showList(&errout, "From phrases", fList)
        write(&errout)
        }

    if /dryrun then f1 := open(whoami||".with", oMode)
    if /dryrun then f2 := open(whoami||".without", oMode)

    while routeMessage(readMessages(whoami), f1, f2)

    if /dryrun then every close(f1|f2)
end

procedure helpMesg()
    write(&errout, "Usage: splitMail --name=USER ")
    write(&errout, "                 --append  --verbose --dryrun")
    write(&errout, "                 --subject=SUBJECT_SUBSTRING")
    write(&errout, "                 --from=FROM_SUBSTRING")
    write(&errout)
    write(&errout, "splits the USER's system mailbox into two sets of")
    write(&errout, "messages: USER.with holds all messages whose subject")
    write(&errout, "and from lines contains any of the SUBJECT_SUBSTRINGs")
    write(&errout, "or any of the FROM_SUBSTRINGs; USER.without holds all")
    write(&errout, "remaining mail messages.  The original system mailbox")
    write(&errout, "is untouched.  Both --subject and --from arguments may")
    write(&errout, "be repeated 0 or more times.")
    write(&errout)
    write(&errout, "With --append, appends to both files instead of overwriting 
them.")
    write(&errout, "With --verbose, shows simple header for messages that")
    write(&errout, "match the search criteria (prefixed by '+++') and don't")
    write(&errout, "match the search criteria (prefixed by '---').")
    write(&errout)
    write(&errout, "The --dryrun option adds --verbose and disables the actual")
    write(&errout, "splitting of the messages into files.")
    return
end

procedure showList(f, prefix, aList)
    if \aList then {
        writes(f, prefix,":")
        every writes(f, " ",!aList)
        write(f)
        }
end

# Read lines with a pushback buffer of one line
#
class PushBack : Class (f, buffer)

    method readLine()
        b := &null
        if \buffer then {
            b :=: buffer
            return b
            }
        else return read(f)
    end

    method pushBack(line)
        buffer := line
    end
end

procedure readMessages(whoami)
    mailFile := PushBack(open("/var/spool/mail/"||whoami)) | fail
    while line := mailFile.readLine() do {
        if match("From ",line) then {
            suspend getMessage(line, mailFile) 
            }
        }
end

procedure getMessage(line, mailFile)
    static WS := ' \t'
    local date, from, subject
    lines := [line]

    line ?  date := (word(),word(),tab(0))
    while line := mailFile.readLine() do {
        line ? {
            if      ="From: "      then /from := tab(0)
            else if =("Subject: " |
                      "subject: ") then /subject := tab(0)
            else if match("From ") then {
                break mailFile.pushBack(line)
                }
            }
        put(lines, line)
        }

    return message((\from)|"Unknown!",(\subject)|"No subject!",date, lines)
end

procedure word()
    static WS := ' \t'
    suspend 1(tab(many(~WS)),tab(many(WS)))
end

procedure routeMessage(message, file1, file2)
    if find(!\sList, message.subject) |
       find(!\fList, message.from)    then {
        if \verbose then showHeader(&errout, "+++",message)
        if /dryrun then every write(file1, !message.text)
        }
    else {
        if \verbose then showHeader(&errout, "---",message)
        if /dryrun then every write(file2, !message.text)
        }
        
end

procedure showHeader(f, prefix, h)
    write(f, prefix, left(mapFrom(h.from),20),": ",left(h.subject,57),
          " (",*(h.text),")")
end

procedure mapFrom(s)
    local ns := ""
    \s ? {
        ns := if      ="\"" then tab(upto('"'))
              else if ="<"  then tab(upto('>'))
              else               tab(upto('<(')|0)
        }
    return trim(ns," \t")
end
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Unicon-group mailing list
Unicon-group@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/unicon-group

Reply via email to