Pragana's Tcl Guide


Old notes


A simple pop3 fetcher

Tired of trying to get fetchmail and other pop clients to work as I wanted, I decided to build my own pop3 fetcher. In the old days, I used to check my incoming mailbox with popclient, but it got old and unsupported. Anyway, why to install a dino like sendmail in our local machine just to have a way to deliver messages? So, tcl to the rescue again! A pop client in just half page of code. To cut yet more my coding needs, there exists a bunch of pop3 functions already packaged in tcllib, a handy tcl-only library.

There are just five functions we need to call from the pop3 library:

pop3::open host user pass Open a connection to the server with user and password given and return the connection socket.
pop3::status chan
To query the server for the status of the mail spool. It returns a list with two elements: the number of messages, and the size (in bytes) of all messages.
pop3::retrieve chan startIndex
Retrieve the message number startIndex, returning a list with just one element, the message body. (Though it may retrieve all messages at once!)
pop3::delete chan startIndex endIndex Remove the messages in range: startIndex ... endIndex.
pop3::closechan Close the connection to the server.

The full program has only a proc, to get the contents of a (possibly remote) pop3 server account and to insert it in your local mailbox. The code is so easy I will show you without further comments:

proc pop3chk {mbox host user pass} {
set sk [pop3::open $host $user $pass]
set f [open $mbox a+]
	set st [pop3::status $sk]
	set n [lindex $st 0] 
	puts "status: $st"
	for {set i 1} {$i <= $n} {incr i} {
    		puts "retrieving msg $i"
    		set body [lindex [pop3::retrieve $sk $i] 0]
    		set timestamp [clock format [clock seconds] -gmt 1]
    		puts $f "From pop3-tclmail $timestamp\n$body"
	}   
	pop3::delete $sk 1 end
	pop3::close $sk
	close $f
	puts "--------------"
}

The only thing worth explaining is the header insertion command   puts $f "From pop3-tclmail $timestamp\n$body" , which insert a proper heading with the fetch time stamp at the beggining of each message. This makes your mailbox readable by pine, mull, elm, or whatever e-mail client (MUA) you prefer to read your messages.
To make your script usable,  insert the package require command for pop3  before the proc, and any number of  pop3chk calls as remote pop3 servers you want to fetch. The arguments are: the local incoming mailbox (usually /var/spool/mail/username), the pop3 server, username, and password.

#!/bin/sh
# \
exec tclsh "$0" "$@"

package require pop3

...<insert the proc above here>...

pop3chk /var/spool/mail/rildo pop3.host.domain rildo rildo_pass
pop3chk  /var/spool/mail/rildo pop3.other_host.com rpragana rpragana_pass
...

What to do next?  If you want to insert mail filters to get rid of spam, you may add the filters with some regexps just inside the horse mouth. I find this a easier and far less time consuming solution than to spend a couple of hours fighting against procmail configuration files to get the job done. Remember the first computing principle KISS (keep it simple stupid!).
If after seeing that, you still want a feature rich (??)  pop3 client, you may start now reading the fetchmail FAQ. I prefer to get simple things done by simple programs. You decide!

That's all fellows. Happy hacking!


Back Home