Skip to main content

Ralsina.Me — Roberto Alsina's website

Posts about qmail (old posts, page 7)

Wanted: C programmer

Check­ing on my semi-dead pro­ject­s, I found that one was al­most fin­ished but I had for­got­ten about it: rater

In or­der to make it re­al­ly use­ful, how­ev­er, I need a C pro­gram­mer that can turn this python pro­gram:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
from socket import *
serverHost = 'localhost'
serverPort = 1999

s = socket(AF_INET, SOCK_STREAM)
s.connect((serverHost, serverPort))
print "Sending: ",' '.join(sys.argv[1:])
s.send(' '.join(sys.argv[1:])+"\n")
data = s.recv(1024)
sys.stderr.write(data)
sys.stderr.flush()
sys.exit(int(data.split(' ')[0]))

In­to a nice func­tion that nev­er fails and nev­er leaks mem­o­ry (of course, it should re­turn in­stead of ex­it, this is just ex­am­ple code ;-).

If that's done, I can re­lease rater as a use­ful tool, which should find a home in many qmail in­stal­la­tions (and maybe oth­er us­es).

Rater progresses (slowly)

I am hack­ing a bit on rater my dae­mon/­client to see if things are hap­pen­ing more of­ten than they should (in oth­er word­s, gener­ic rate lim­it­ing).

I had to take a few days of­f, since my broth­er got mar­ried and we all went back to San­ta Fe for that and a week­end, and then ev­ery­one else has sore throats and I am the on­ly one healthy.

But hey, it works well enough al­ready:

  • The sim­­plis­tic pro­­to­­col is done

  • The serv­er works

    • It can take hours of gib­ber­ish with­­­out prob­lem­s.

    • It can take hours of valid in­­­put with­­­out prob­lem­s.

    • It does what it's sup­­­posed to do.

  • It's stay­ing be­low 300S­LOC, which was my goal.

Miss­ing stuff:

  • Val­­grind it.

  • Client li­brary.

  • Gen­er­ic CLI clien­t.

  • A qmail-spp plug­in that us­es it.

And then, I can for­get all about it.

C is not Python II.

RaSPF, my C port of PySPF, is pret­ty much func­tion­al right now.

Here's what I mean:

  • It pass­es 75 in­­ter­­nal unit tests (ok, 74 , but that one is ar­guable).

  • It pass­es 137 of 145 tests of the SPF of­­fi­­cial test suit­­e.

  • It agrees with PySPF in 181 of the 183 cas­es of the lib­spf2 live DNS suit­­e.

  • It seg­­faults in none of the 326 test cas­es.

So, while there are still some cor­ner cas­es to de­bug, it's look­ing very good.

I even spent some time with val­grind to plug some leaks ( the in­ter­nal test suite runs al­most leak­less, the re­al app is a sieve ;-)

All in al­l, if I can spend a lit­tle while with it dur­ing the week, I should be able to make a re­lease that ac­tu­al­ly work­s.

Then, I can re­write my SPF plug­in for qmail, which was what sent me in this mon­th-log tan­gen­t.

As a lan­guage wars com­par­ison:

  • The sloc­­count of raspf is 2557 (or 2272 if we use the ragel gram­­mar source in­­stead of the gen­er­at­ed file)

  • The sloc­­count of PySPF is 993.

So, a 2.6:1 or 2.28:1 code ra­tio.

How­ev­er, I used 4 non-­s­tan­dard C li­braries: bstr­lib, udns, and helpers for hash­es and ex­cep­tion­s, which add an­oth­er 5794 LOC­s.

So, it could be ar­gued as a 8:1 ra­tio, too, but my C code is prob­a­bly ver­bose in ex­treme, and many C lines are not re­al­ly "log­ic" but dec­la­ra­tions and such.

Al­so, I did not write PySPF, so his code may be more con­cise, but I tried my best to copy the flow as much as pos­si­ble line-per-­line.

In short, you need to write, ac­cord­ing to this case, be­tween 2 and 8 times more code than you do in Python.

That's a bit much!

Playing with literate programming

I am us­ing ra-­plu­g­ins as a toy to do things I nev­er both­ered in oth­er project­s.

I am do­ing unit-test­ing. And now... some lit­er­ate pro­gram­ming!

Ok, not much, and not very well, but at least I am play­ing with Lp4all which is a nice, sim­ple tool to gen­er­ate nice HTML from slight­ly wik­i-­marked sources.

You can see some lit­tle things in my code here. My vere­dict so far? A nice way to keep the code doc­u­ment­ed in a fash­ion that ocasi­nal browsers can fol­low.

The main thing miss­ing is au­to­mat­ic cross-ref­er­enc­ing.

In gen­er­al, I am find­ing that this (and unit test­ing) helps me ex­press ex­plic­it­ly to my­self what the heck I am try­ing to do, and see if the code ac­tu­al­ly does it. Which is a re­al­ly good thing.


Contents © 2000-2023 Roberto Alsina