> Fetchmail “mda” option makes emails bypass the spamassassin filter in postfix

September 19th, 2014

I have spent several months with no spam filtering in my postfix+dovecote+spamassassin+fetchmail+procmail setup, and no idea why. I had spamassassin enabled and working when I piped emails into it manually, and I had lines like this in my postfix master.cf:

# Listen on port 2025, not 25, and filter with the spamassassin service
2025      inet  n       -       -       -       -       smtpd
	-o content_filter=spamassassin
# ...

# Definition of the spamassassin service: pipe to spamc, then sendmail
spamassassin unix -     n       n       -       -       pipe
	user=spamd argv=/usr/bin/spamc -x -e    
	/usr/sbin/sendmail -oi -f ${sender} ${recipient}

But no matter what I did, I saw no spamassassin headers in my emails, and no mention of using it in the logs. Frustratingly, it was filtering perfectly on outgoing mail, which I really don’t need…

Today I worked out what the problem was – nothing to do with postfix or spamassassin config, but to do with my .fetchmailrc.

Because I was running on a non-standard port, and also because I had tried not allowing unencrypted connections to postfix even from localhost, I was using telling fetchmail to deliver with /usr/sbin/sendmail, instead of allowing it to connect to postfix on port 25 as it normally does. So my .fetchmailrc contained:

poll example.com with proto POP3
    user 'x' there with password 'y' is 'z' here
    mda "/usr/sbin/sendmail  -i  -f %F -- %T"

It turns out this completely bypasses all the filters, and delivers the mail immediately. So, what I needed was the syntax to connect on a non-standard port, which looks like:

poll example.com with proto POP3
    user 'x' there with password 'y' is 'z' here
    smtphost localhost/2025

(If your postfix listens on port 25, you don’t need the smtphost line at all.)

And now my email is being filtered for spam, and put into a Junk folder by procmail.

> Android programming – a menu using Activities and Intents

September 17th, 2014

Series: Setup, Menu, Drawing, non-Android

I will be talking about how to write Android programs that share code with non-Android programs. The program I will be writing is a simple game.

This time we’re making a simple menu structure:

> Raspberry Pi Minecraft Python summer project screenshots

September 16th, 2014

[Screenshots of Minecraft on the Raspberry Pi can't be made with VNC or screenshot tool like scrot, but they can be made with the excellent raspi2png.]

We did some Python programming in Minecraft on the Raspberry Pi for our summer projects.

Child 2 made some lovely houses and enjoyed destroying things much more efficiently than when you do it by hand:

houses

and Child 0 made a spell book. You can see the “elements” spell has been cast in the background (earth, air, water and fire), the “topsy-turvy” spell on the right, the “frozen” spell on the left, and on the far left you can just see a bit of the “river” spell:

spells

To cast spells you must first utter the magical incantations:

python

and then:

from spells import *

then each spell can be cast by simply saying its name followed by the double brackets of power, for example:

topsyturvy()

> Android programming – setting up Android Studio

September 11th, 2014

Series: Setup, Menu, Drawing, non-Android

I will be talking about how to write Android programs that share code with non-Android programs. The program I will be writing is a simple game.

First, how to set up Android Studio:

> What is a string?

August 23rd, 2014

Most programming languages have some wrinkles around unicode and strings*. In my ficticious language Pepper, there are no wrinkles of any kind, and everything is perfect.

*E.g. JavaScript, Java, Haskell, Ruby, Python.

There are several key concepts. The most important are an interface AnyString and the variable** String which is what you should use when you are writing code with strings.

**String is a variable that refers to a type, so you just use it like a type and don’t worry about it.

interface AnyString
{
    def indexable(CodePoint) code_points( implements(AnyString) string )
}

In Pepper an interface can describe what free functions exist as well as what member function a class must have, and here we just require that a code_points function exists that gives us a collection of CodePoint objects that may be indexed (i.e. is random-access).

When your Pepper program starts, the String variable will refer to something that implements this interface, and probably some other interfaces too. Most Pepper programs will use a String that is implemented as an array of bytes representing a string in UTF-8, but the programmer doesn’t need to be aware of that, and in a situation where something different is needed (e.g. where we know lots of non-Latin characters will be used and UTF-16 will be more efficient) String can be set to something different in the configuration settings used by the compiler.

When you want to do something with a string, there will be functions that only rely on the AnyString interface and deal with CodePoints internally, but there will be other overloads that are potentially more efficient, for example there are two versions of the standard print function:

def void print( implements(AnyString) string )
def void print( NativeUtf8String string )

The NativeUtf8String class is implemented as a std::string in the C++ code emitted by the Pepper compiler, and the most efficient way to represent an array of bytes when compiling onto other platforms, so the version of print that uses it can be quite efficient.

Because all these types are known at compile time, the C++ code generated by the Pepper compiler can use the native types directly (and be efficient), even though the programmer is writing code using just the AnyString and String types, meaning their code can be adapted to other platforms by using a different configuration.

The Pepper environment exposes standard-out and standard-in as UTF-8 streams, and takes care of converting to the platform encoding for you (at runtime).