6. Popclient becomes Fetchmail
The real turning point in the project was when Harry Hochheiser sent
me his scratch code for forwarding mail to the client machine's SMTP
port. I realized almost immediately that a reliable implementation of
this feature would make all the other delivery modes next to obsolete.
For many weeks I had been tweaking fetchmail rather incrementally
while feeling like the interface design was serviceable but grubby --
inelegant and with too many exiguous options hanging out all over.
The options to dump fetched mail to a mailbox file or standard output
particularly bothered me, but I couldn't figure out why.
What I saw when I thought about SMTP forwarding was that popclient had
been trying to do too many things. It had been designed to be both a
mail transport agent (MTA) and a local delivery agent (MDA). With
SMTP forwarding, it could get out of the MDA business and be a pure
MTA, handing off mail to other programs for local delivery just as
sendmail does.
Why mess with all the complexity of configuring a mail delivery agent
or setting up lock-and-append on a mailbox when port 25 is almost
guaranteed to be there on any platform with TCP/IP support in the
first place? Especially when this means retrieved mail is guaranteed
to look like normal sender-initiated SMTP mail, which is really what
we want anyway.
There are several lessons here. First, this SMTP-forwarding idea was
the biggest single payoff I got from consciously trying to emulate
Linus's methods. A user gave me this terrific idea -- all I had to do
was understand the implications.
11. The next best thing to having good ideas is recognizing good
ideas from your users. Sometimes the latter is better.
Interestingly enough, you will quickly find that if you are completely
and self-deprecatingly truthful about how much you owe other people,
the world at large will treat you like you did every bit of the
invention yourself and are just being becomingly modest about your
innate genius. We can all see how well this worked for Linus!
(When I gave this paper at the Perl conference in August 1997, Larry
Wall was in the front row. As I got to the last line above he called
out, religious-revival style, ``Tell it, tell it, brother!''. The
whole audience laughed, because they knew it had worked for the
inventor of Perl too.)
After a very few weeks of running the project in the same spirit,
I began to get similar praise not just from my users but from other
people to whom the word leaked out. I stashed away some of that
email; I'll look at it again sometime if I ever start wondering
whether my life has been worthwhile :-).
But there are two more fundamental, non-political lessons here that
are general to all kinds of design.
12. Often, the most striking and innovative solutions
come from realizing that your concept of the problem was wrong.
I had been trying to solve the wrong problem by continuing to develop
popclient as a combined MTA/MDA with all kinds of funky local delivery
modes. Fetchmail's design needed to be rethought from the ground up
as a pure MTA, a part of the normal SMTP-speaking Internet mail path.
When you hit a wall in development -- when you find yourself hard put
to think past the next patch -- it's often time to ask not whether
you've got the right answer, but whether you're asking the right
question. Perhaps the problem needs to be reframed.
Well, I had reframed my problem. Clearly, the right thing to do was
(1) hack SMTP forwarding support into the generic driver, (2) make it
the default mode, and (3) eventually throw out all the other delivery
modes, especially the deliver-to-file and deliver-to-standard-output
options.
I hesitated over step 3 for some time, fearing to upset long-time
popclient users dependent on the alternate delivery mechanisms. In
theory, they could immediately switch to .forward files or their
non-sendmail equivalents to get the same effects. In practice the
transition might have been messy.
But when I did it, the benefits proved huge. The cruftiest parts of
the driver code vanished. Configuration got radically simpler -- no
more grovelling around for the system MDA and user's mailbox, no more
worries about whether the underlying OS supports file locking.
Also, the only way to lose mail vanished. If you specified delivery
to a file and the disk got full, your mail got lost. This can't
happen with SMTP forwarding because your SMTP listener won't return OK
unless the message can be delivered or at least spooled for later
delivery.
Also, performance improved (though not so you'd notice it in a single
run). Another not insignificant benefit of this change was that the
manual page got a lot simpler.
Later, I had to bring delivery via a user-specified local MDA back in order
to allow handling of some obscure situations involving dynamic SLIP.
But I found a much simpler way to do it.
The moral? Don't hesitate to throw away superannuated features when
you can do it without loss of effectiveness. Antoine de
Saint-Exupery (who was an aviator and aircraft designer when he
wasn't being the author of classic children's books) said:
13. ``Perfection (in design) is achieved not when there is nothing more
to add, but rather when there is nothing more to take away.''
When your code is getting both better and simpler, that is when you
know it's right. And in the process, the fetchmail
design acquired an identity of its own, different from the ancestral
popclient.
It was time for the name change. The new design looked much more like
a dual of sendmail than the old popclient had; both are MTAs, but
where sendmail pushes then delivers, the new popclient pulls then
delivers. So, two months off the blocks, I renamed it fetchmail.