Logo You've better use project's tracker

archive size (b)
biffles-0.8.74.tar.gz 103522
biffles-0.8.74.tar.bz2 81697
biffles-0.7.tar.gz 51850
biffles-0.7.tar.bz2 44602

Subversion repository Last time stable revision was 160
Bug tracker is here

MailBox bundle
AppConfig bundle
XML::Writer module


It's README of biffles, in state of v.0.8.

What it is

The biffles means no-biffed. You don't care about new mail notification, because you got mail regularly (as assigned in your crontab)---once login morningly you know there's some mail fetched from your ISP or free mailbox provider. Irregular are robot's reports, but that's not a problem.

The biffles is a mailing-list client. In the parallel world of FidoNet it should be called a tosser. (You don't know what FidoNet is? So you are an Internet Moron.) The purpose is to sort amassed in a local mailbox mail into couple of mailboxes, where that mail will be easily threaded by your respectful mailer. (In the PWoFN, the mailer here is called the echoprocessor; The mailer there does what MTA, ftp client do here; Yet it does the thing called there a chat; A difference is that that chat is point-to-point and nothing more; Jeez, I messed all the things up, didn't I? Forgive me, poor childhood, 4-bit toys...) It gives a means to filter out of the road spam, make personal blacklist and whitelist, reports totals, clears outdated mails,.. Read TODO for more.

Why it is

I have mail and run into another task---filtering and sorting. If your mail is only personal (and isn't massive) that doesn't make a problem. But receiving some mailing-lists, mailbased newsfeeds, and mailed reports makes headache, RSI, eyeache, heartache, IOW, it's deadalous.

A common way to solve it is using procmail or something alike. And that's (I think) the right way when you have biff of any kind. But when mail is going to be delivered anyway, why to bother yourself with configuring additional quasi-daemon? Much more exciting would be creating something new and playing with it later.

How it is

Once started biffles reads command-line and configuration files; some command-line options override specified in the configuration files. Both override defaults. By the way command-line is parsed (via Getopt::Long), options are stored into biffles configuration. Then configuration files (by default those are system-wide (/etc/biffles.cfg) and user-specific (~/.biffles)) are parsed and stored too. Then is performed a short integrity check.

(since v.0.7) biffles allows forcing of mailbox type; that type will be used in case an outbox should be created (as a target of mail); default type is defined by underlying mailbox engine; at present state, biffles fails to provide means to manipulate with that default.

Then in-boxes are scanned. Every defined in-box is opened for reading, then every mail in that in-box is checked to match in-box rule (by default anything match). Any message is tested for X-Biffles: header. If that header would be found (that means, that there is a loop), then a message will stay intact in the in-box. Then every mail found is tested against outbox rules (by default anything will match too, so don't left them undefined). All found triplets (message - in-box - outbox) are stored in configuration.

(since v.0.4) Please note, biffles will use all triplets found, not the first one (what was subject to the way Perl returns hash keys; OTOH, that feature will be extended with flavors of rules). Sometimes you can receive mail with same Message-Id: headers (manually crafted spam, you know). Those faked mails will break internal structures. To avoid this, all the mails with same Message-Id: header value won't be processed. You should handle them manually (delete?). However, there is a case when correct mail would trigger that feature---if you process with biffles a mailbox where your mailer stores your outgoing mail, you post in mailing-list, then receive it back,.. IOW, Message-Id: headers are collected and checked for all in-boxes, not for the one where this mail happened to be found. You are warned.

The figured out triplets are scheduled and that schedule is stored in the internal configuration.

In last turn, all defined in-boxes are cycled, and messages with at least one matching outbox are moved into scheduled outbox. Any moved message is marked with X-Biffles: header. Some informative fields are stored in that header; but no one will be considered as substitution for rules, if message with such header will be found in the in-box in another run (considering drop that check at all). (since v.0.5) There are 3 boxsets of outboxes (hmm, should reconsider that sentence). Those are:


The mail-boxes of that kind are tested first, if a mail matches any (up to all of that boxset), then neither outbox nor lastbox boxsets are considered at all.


(As you can guess, that one is historically first.) The same behaviour is provided for outbox and left yet lastbox boxsets.


Finally, if none mail-box of lastbox boxset matches, then this mail is almost forgotten but processed.

That ridiculous construct gives an illusion of no spam (all that and blacklisted persons go into mailboxes of firstbox boxset; personal mail would go into mailboxes of lastbox; any regular mailing-list feed goes in outboxes. (Too many boxes.)

(since v.0.6) There is one more move; namely---thread-cleaning. That move is performed if two conditions happen (please, note "and"):


Thread-cleaning is enabled for a mail-box (by default it's disabled, setting range to 0 disables);


And there was any mail transferred in mail-box.

The thread-cleaning never happens for in-boxes (give me a reason why it should). As awaited it works like this: if thread contains no mails within range, then it's cleared. What mails are considered to be in thread depends on this or that actual threader, and... sender's MUA.

Finally, some information collected while doing moves is reconsidered and in a pretty printed fashion is mailed to UID. (since v.0.8 That "pretty printed fashion" isn't pretty any more; it's one chunk of XML. So that makes a problem, reading raw XML is no big fun, right? A quite primitive XSLT is distributed in contrib/ (as of me, that pretty simple HTML, it provides, looks much better and readable, then that fscking ascii-art). Anyway, that's the one step toward daily reports (look in TODO)!


The most problem of biffles is robustness. I'm not about time, I'm about size. I don't collect statistics, but I've seen at least 45Mb of core on 180 mails. Because biffles is (supposed to be) a cron-job, it should be aware of the fact that cron would limit resources for its jobs (should rewrite that sentence). Those limits effectively kill biffles. The problem roots in mailbox processing engine---Mail::Box bundle. To solve that problem biffles needs to give a chance every possible engine. Just to find the best.

Every mailbox engine is folded in a specific module (Biffles::MBox for Mail-Box bundle and Biffles::Email for Perl Email Project). They are, in turn, is based on Biffles::Generic. Whatever helper functions (at the moment, storing and checking configuration) are in their specific module (Biffles::Utils). Report processing routines are in specific Biffles::XML too. Every module gives its own documentation internally. If you really (really?) want to know how it works.

That makes biffles itself just a mere stem (that is explained in "How it is" section).

If something goes wrong or inappropriate

(since v.0.8) A report-mode dumps any data (useful or not) about mail left in inbox (ambiguous Message-Id headers, X-Biffles headers, missing target), transferred mail, and threads cleared in touched mailboxes. All the stuff is wrapped in XML; DTD and sample XSLT are in contrib/. You can read all that stuff directly from STDOUT (--report -), but digging your mailbox.

There is a verbose-mode. It tracks through turns of processing and reports configuration and scheduling events.

A debug-mode is almost useless; it gives diagnostic of module and classes biffles depend, not itself. What's worst (just noted himself) engines are unaware of debug-mode. Pity.

--dry-run option with --verbose would provide a plenty of reading. Output of --dump option isn't funniest thing to read, but consider it too.

A test-suite blindly believes that --noreport option works. As biffles became much more modularized, the test-suite improved a lot. However, there is a big deal of keeping on that modularization.


As ever



Eric Pozharski <>


That html is awful :(

So what? it's lynx-friendly! :D

|                          +   |
|                       +      |
|                              |
|    --               +        |
|     ``     *                 |
|     !!                       |
|     ,,            +          |
|    --                        |
|          ++++       +        |
|         /^  ^\  +            |
|        /^    ^\   +          |
|       /^,----.^\             |
|      /^ *BIFF* ^\            |
|     /^  `----'  ^\           |
|      WHWH====HWHW            |
|      HWHW+  +WHWH            |
|      WHWV    VWHW            |
|      HWH+    +HWH            |
|     %WHW      WHW            |
|     %HWH      HWH            |
|    % WoW      WHW    -.      |
|   %  HWH+....+HWH    #~=8    |
|   % ^^^^^^^^^^^^^^  =====    |
|    %%^              `...'    |
|     ( )                      |
|                              |
|         Biff has gone...     |
|                              |
|                              |
|                              |
+---------------whynot, 2007---+

Produced with HTML::Template