Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

#include "sys.h"
#include "spam.h"

int     debug;
Biobuf  bin;
char    patfile[128], header[Hdrsize+2];
char    cmd[1024];

char*   canon(Biobuf*, char*, char*, int*);
int     matcher(char *, Pattern*, char*, Resub*);
int     matchaction(Patterns*, char*);

void
usage(void)
{
        fprint(2, "missing or bad arguments to qer\n");
        exits("usage");
}

void *
Malloc(long n)
{
        void *p;

        p = malloc(n);
        if(p == 0){
                fprint(2, "malloc error");
                exits("malloc");
        }
        return p;
}

void*
Realloc(void *p, ulong n)
{
        p = realloc(p, n);
        if(p == 0){
                fprint(2, "realloc error");
                exits("realloc");
        }
        return p;
}

void
dumppats(void)
{
        int i, j;
        Pattern *p;
        Spat *s, *q;

        for(i = 0; patterns[i].action; i++){
                for(p = patterns[i].regexps; p; p = p->next){
                        print("%s <REGEXP>\n", patterns[i].action);
                        if(p->alt)
                                print("Alt:");
                        for(s = p->alt; s; s = s->next)
                                print("\t%s\n", s->string);
                }
                p = patterns[i].strings;
                if(p == 0)
                        continue;

                for(j = 0; j < Nhash; j++){
                        for(s = p->spat[j]; s; s = s->next){
                                print("%s %s\n", patterns[i].action, s->string);
                                if(s->alt)
                                        print("Alt:");
                                for(q = s->alt; q; q = q->next)
                                        print("\t%s\n", q->string);
                        }
                }
        }
}

void
main(int argc, char *argv[])
{
        int i, fd, n, aflag, vflag;
        char body[Bodysize+2], *raw, *ret;
        Biobuf *bp;

        sprint(patfile, "%s/patterns", UPASLIB);
        aflag = -1;
        vflag = 0;
        ARGBEGIN {
        case 'a':
                aflag = 1;
                break;
        case 'v':
                vflag = 1;
                break;
        case 'd':
                debug++;
                break;
        case 'p':
                strcpy(patfile,ARGF());
                break;
        } ARGEND

        bp = Bopen(patfile, OREAD);
        if(bp){
                parsepats(bp);
                Bterm(bp);
        }

        if(argc >= 1){
                fd = open(*argv, OREAD);
                if(fd < 0){
                        fprint(2, "can't open %s\n", *argv);
                        exits("open");
                }
                Binit(&bin, fd, OREAD);
        } else 
                Binit(&bin, 0, OREAD);

        *body = 0;
        *header = 0;
        ret = 0;
        for(;;){
                raw = canon(&bin, header+1, body+1, &n);
                if(raw == 0)
                        break;
                if(aflag == 0)
                        continue;
                if(aflag < 0)
                        aflag = 0;
                if(vflag){
                        if(header[1]) {
                                fprint(2, "\t**** Header ****\n\n");
                                write(2, header+1, strlen(header+1));
                                fprint(2, "\n");
                        }
                        fprint(2, "\t**** Body ****\n\n");
                        if(body[1])
                                write(2, body+1, strlen(body+1));
                        fprint(2, "\n");
                }

                for(i = 0; patterns[i].action; i++){
                        if(matchaction(&patterns[i], header+1))
                                ret = patterns[i].action;
                        if(i == HoldHeader)
                                continue;
                        if(matchaction(&patterns[i], body+1))
                                ret = patterns[i].action;
                }
        }
        exits(ret);
}

char*
canon(Biobuf *bp, char *header, char *body, int *n)
{
        int hsize, base64;

        static char *raw;

        hsize = 0;
        base64 = 0;
        *header = 0;
        *body = 0;
        if(raw == 0){
                raw = readmsg(bp, &hsize, n);
                if(raw)
                        base64 = convert(raw, raw+hsize, header, Hdrsize, 0);
        } else {
                free(raw);
                raw = readmsg(bp, 0, n);
        }
        if(raw){
                if(base64)
                        conv64(raw+hsize, raw+*n, body, Bodysize);
                else
                        convert(raw+hsize, raw+*n, body, Bodysize, 1);
        }
        return raw;
}

int
matchaction(Patterns *pp, char *message)
{
        char *name, *cp;
        int ret;
        Pattern *p;
        Resub m[1];

        if(message == 0 || *message == 0)
                return 0;

        name = pp->action;
        p = pp->strings;
        ret = 0;
        if(p)
                for(cp = message; matcher(name, p, cp, m); cp = m[0].ep)
                                ret++;

        for(p = pp->regexps; p; p = p->next)
                for(cp = message; matcher(name, p, cp, m); cp = m[0].ep)
                                ret++;
        return ret;
}

int
matcher(char *action, Pattern *p, char *message, Resub *m)
{
        if(matchpat(p, message, m)){
                if(p->action != Lineoff)
                        xprint(1, action, m);
                return 1;
        }
        return 0;
}