Ir al contenido principal

Ralsina.Me — El sitio web de Roberto Alsina

My SPF lib improving

It now can do a bunch of things like ex­pand­ing macros and (in some cas­es) val­i­dat­ing mech­a­nism­s.

I am mak­ing very heavy use of unit test­ing, be­cause it's a pret­ty com­plex piece and each func­tion needs to do ex­act­ly the right thing or ev­ery­thing else fails (it's pret­ty hard to fig­ure out where it will fail ;-)

You can check the 947 LOC thing at http://­code.­google.­com/p/raspf (the Code tab).

If you do check it, jeep in mind the fol­low­ing:

  • It us­es a few lib­s, and they are in­­­clud­ed in the source code for sim­­plic­i­­ty.

  • I do some­­times com­mit code that does­n't com­pile

  • I do some­­times com­mit code that fails tests

  • You need cmake

  • I am not giv­ing a damn about mem­o­ry man­age­­ment right now, so don't both­­er wor­ry­ing about leak­s: ev­ery­thing leaks in this code. I want to make it func­­tion­al first, then I can plug it one func­­tion at a time (sim­­ply by run­n­ing the unit test­ing code with a mem­o­ry check­­er).

En­joy (although it's not pre­cise­ly en­joy­able code right now ;-)

C is not Python

I am port­ing pyspf to C (long sto­ry, and I am stupid for try­ing). But of course, C is not python.

So you don't have anything nearly as nice as re.­com­pile("what­ev­er").s­plit("­somestring").

What is that good for, you may ask? Well, to do things like split­ting email ad­dress­es while val­i­dat­ing them, or in this spe­cif­ic case, to val­i­date SPF mech­a­nisms (n­ev­er­mind what those are).

But hey, you can al­ways do this (ex­cuse me while I weep a lit­tle):

struct bstrList *re_split(const char *string, const char *pattern)
{
    int status;
    regex_t re;
    regmatch_t pmatch[20];

    if (regcomp(&re, pattern, REG_ICASE|REG_EXTENDED) != 0)
    {
        return(0);      /* Report error. */
    }

    bstring tmp=bfromcstr("");
    char *ptr=(char *)string;

    for (;;)
    {
        status = regexec(&re, ptr, (size_t)20, pmatch, 0);
        if (status==REG_NOMATCH)
        {
            break;
        }
        bcatblk (tmp,ptr,pmatch[0].rm_so);
        bconchar (tmp,0);
        bcatblk (tmp,ptr+pmatch[0].rm_so,pmatch[0].rm_eo-pmatch[0].rm_so);
        bconchar (tmp,0);
        ptr=ptr+pmatch[0].rm_eo;

    }
    regfree(&re);
    bcatblk (tmp,ptr,strlen(string)-(ptr-string));
    struct bstrList *l= bsplit(tmp,0);
    return l;
}

And that is prob­a­bly wrong for some cas­es (and it does­n't split the ex­act same way as Python, but that's what unit test­ing is for).

I must be miss­ing some­thing that makes reg­comp & friends nicer to use. Right? Right?

Any regex wizard reading this?

If so, what is the C POSIX regex (y­ou know reg­comp & friend­s) equiv­a­lent of this python reg­u­lar ex­pre­sion:

re.compile(r'^([a-z][a-z0-9_\-\.]*)=', re.IGNORECASE)

Be­cause it sure is­n't this:

regcomp(&re,"^([a-z][a-z0-9_\-\.]*)=",REG_ICASE)

I have been play­ing with it for two hours and am bored :-)

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.

Itching.

Ok, the SPF im­ple­men­ta­tion sit­u­a­tion is kin­da pa­thet­ic.

There seems to be ex­act­ly one main­tained C im­ple­men­ta­tion. And it's win­dows-on­ly.

  • lib­spf's we­b­site seems to have dis­­ap­­peared

  • lib­spf2's not RFC-­­com­­pli­ant (ver­i­­fied for 1.2.5) and their is­­sue re­­port­ing sys­tem bounces.

So, I have tak­en the most com­pli­ant one I found whose code I can ac­tu­al­ly fol­low (that would be the python one) and am reim­ple­ment­ing it in C (us­ing bstr­lib and lib­d­jbdns).

It will prob­a­bly not come to a good end, but hey, it may work ;-)


Contents © 2000-2020 Roberto Alsina