Ejemplo n.º 1
0
/* writes a single test into almost-flat form starting at codep.
 * returns the next code location or -1 on error. */
static int bc_test_generate(int codep, bytecode_info_t *retval, test_t *t)
{
    if(!retval) return -1;
    switch(t->type) {
    case STRUE: /* BC_TRUE */
        if(!atleast(retval,codep+1)) return -1;
        retval->data[codep++].op = BC_TRUE;
        break;
    case SFALSE:/* BC_FALSE */
        if(!atleast(retval,codep+1)) return -1;
        retval->data[codep++].op = BC_FALSE;
        break;
    case NOT: /* BC_NOT {subtest : test} */
        if(!atleast(retval,codep+1)) return -1;
        retval->data[codep++].op = BC_NOT;
        codep = bc_test_generate(codep, retval, t->u.t);
        if (codep == -1) return -1;
        break;
    case SIZE: /* BC_SIZE (B_OVER | B_UNDER) {size : int} */
        if(!atleast(retval,codep+3)) return -1;
        retval->data[codep++].op = BC_SIZE;
        retval->data[codep++].value = (t->u.sz.t == OVER
                                       ? B_OVER : B_UNDER);
        retval->data[codep++].value = t->u.sz.n;
        break;
    case EXISTS:/* BC_EXISTS { headers : string list } */
        if(!atleast(retval,codep+1)) return -1;
        retval->data[codep++].op = BC_EXISTS;
        codep= bc_stringlist_generate(codep, retval, t->u.sl);
        break;
    case ANYOF:/* BC_ANYOF { tests : test list } */
        if(!atleast(retval,codep+1)) return -1;
        retval->data[codep++].op = BC_ANYOF;
        codep=bc_testlist_generate(codep, retval, t->u.tl);
        if (codep == -1) return -1;
        break;
    case ALLOF: /* BC_ALLOF { tests : test list } */
        if(!atleast(retval,codep+1)) return -1;
        retval->data[codep++].op = BC_ALLOF;
        codep= bc_testlist_generate(codep, retval, t->u.tl);
        if (codep == -1) return -1;
        break;
    case HEADER:
    case HASFLAG:
        /* BC_HEADER { i: index } { c: comparator }
         * { haystacks : string list } { patterns : string list }
         *
         * BC_HASFLAG { c: comparator }
         * { haystacks : string list } { patterns : string list }
         */

        if(!atleast(retval,codep + 1)) return -1;
        retval->data[codep++].op = (t->type == HEADER)
            ? BC_HEADER : BC_HASFLAG;

        if (t->type == HEADER) {
        /* index */
        if(!atleast(retval,codep + 1)) return -1;
        retval->data[codep++].value = t->u.h.index;
        }

        /* comparator */
        codep = bc_comparator_generate(codep, retval,
                                       t->u.h.comptag,
                                       t->u.h.relation,
                                       t->u.h.comparator);
        if (codep == -1) return -1;

        /* haystacks */
        codep = bc_stringlist_generate(codep, retval, t->u.h.sl);
        if (codep == -1) return -1;

        /* pattern */
        codep = bc_stringlist_generate(codep, retval, t->u.h.pl);
        if (codep == -1) return -1;
        break;
    case ADDRESS:
    case ENVELOPE:
        /* BC_ADDRESS {i : index } {c : comparator}
           (B_ALL | B_LOCALPART | ...) { header : string list }
           { pattern : string list }

           BC_ENVELOPE {c : comparator}
           (B_ALL | B_LOCALPART | ...) { header : string list }
           { pattern : string list } */

        if(!atleast(retval,codep+1)) return -1;

        retval->data[codep++].op = (t->type == ADDRESS)
            ? BC_ADDRESS : BC_ENVELOPE;

        /* index */
        if (t->type == ADDRESS) {
                if(!atleast(retval,codep+1)) return -1;
                retval->data[codep++].value = t->u.ae.index;
        }

        codep = bc_comparator_generate(codep, retval,t->u.ae.comptag,
                                       t->u.ae.relation,
                                       t->u.ae.comparator);
        if (codep == -1) return -1;

        if(!atleast(retval,codep+1)) return -1;

        /*address part*/
        switch(t->u.ae.addrpart) {
        case ALL:
            retval->data[codep++].value = B_ALL;
            break;
        case LOCALPART:
            retval->data[codep++].value = B_LOCALPART;
            break;
        case DOMAIN:
            retval->data[codep++].value = B_DOMAIN;
            break;
        case USER:
            retval->data[codep++].value = B_USER;
            break;
        case DETAIL:
            retval->data[codep++].value = B_DETAIL;
            break;
        default:
            return -1;
        }

        /*headers*/
        codep = bc_stringlist_generate(codep, retval, t->u.ae.sl);
        if (codep == -1) return -1;

        /*patterns*/
        codep = bc_stringlist_generate(codep, retval, t->u.ae.pl);
        if (codep == -1) return -1;

        break;
    case BODY:
        /* BC_BODY {c : comparator} (B_RAW | B_TEXT | ...)
           { content-types : stringlist }
           { offset : int }
           { pattern : string list } */

        if(!atleast(retval,codep+1)) return -1;

        retval->data[codep++].op = BC_BODY;

        codep = bc_comparator_generate(codep, retval,t->u.b.comptag,
                                       t->u.b.relation,
                                       t->u.b.comparator);
        if (codep == -1) return -1;

        if(!atleast(retval,codep+2)) return -1;

        /*transform*/
        switch(t->u.b.transform) {
        case RAW:
            retval->data[codep++].value = B_RAW;
            break;
        case TEXT:
            retval->data[codep++].value = B_TEXT;
            break;
        case CONTENT:
            retval->data[codep++].value = B_CONTENT;
            break;
        default:
            return -1;
        }

        /*offset*/
        retval->data[codep++].value = t->u.b.offset;

        /*content-types*/
        codep = bc_stringlist_generate(codep, retval, t->u.b.content_types);
        if (codep == -1) return -1;

        /*patterns*/
        codep = bc_stringlist_generate(codep, retval, t->u.b.pl);
        if (codep == -1) return -1;

        break;
    case DATE:
    case CURRENTDATE:
        /* BC_DATE { i: index } { time-zone: string} { c: comparator }
         *         { header-name : string } { date-part: string }
         *         { key-list : string list }
         *
         * BC_CURRENTDATE { time-zone: string} { c: comparator }
         *         { date-part: string } { key-list : string list }
        */

        if(!atleast(retval,codep + 1)) return -1;
        retval->data[codep++].op = (DATE == t->type) ? BC_DATE : BC_CURRENTDATE;

        /* index */
        if (DATE == t->type) {
                if(!atleast(retval,codep + 1)) return -1;
                retval->data[codep++].value = t->u.dt.index;
        }

        /* zone */
        codep = bc_zone_generate(codep, retval,
                                 t->u.dt.zonetag,
                                 t->u.dt.zone);
        if (codep == -1) return -1;

        /* comparator */
        codep = bc_comparator_generate(codep, retval,
                                       t->u.dt.comptag,
                                       t->u.dt.relation,
                                       t->u.dt.comparator);
        if (codep == -1) return -1;

        /* date-part */
        if(!atleast(retval,codep + 1)) return -1;
        switch (t->u.dt.date_part) {
        case YEAR:
                retval->data[codep++].value = B_YEAR;
                break;
        case MONTH:
                retval->data[codep++].value = B_MONTH;
                break;
        case DAY:
                retval->data[codep++].value = B_DAY;
                break;
        case DATE:
                retval->data[codep++].value = B_DATE;
                break;
        case JULIAN:
                retval->data[codep++].value = B_JULIAN;
                break;
        case HOUR:
                retval->data[codep++].value = B_HOUR;
                break;
        case MINUTE:
                retval->data[codep++].value = B_MINUTE;
                break;
        case SECOND:
                retval->data[codep++].value = B_SECOND;
                break;
        case TIME:
                retval->data[codep++].value = B_TIME;
                break;
        case ISO8601:
                retval->data[codep++].value = B_ISO8601;
                break;
        case STD11:
                retval->data[codep++].value = B_STD11;
                break;
        case ZONE:
                retval->data[codep++].value = B_ZONE;
                break;
        case WEEKDAY:
                retval->data[codep++].value = B_WEEKDAY;
                break;
        }

        if (DATE == t->type) {
                /* header-name */
                if(!atleast(retval,codep + 2)) return -1;
                retval->data[codep++].len = strlen(t->u.dt.header_name);
                retval->data[codep++].str = t->u.dt.header_name;
        }

        /* keywords */
        codep = bc_stringlist_generate(codep, retval, t->u.dt.kl);
        if (codep == -1) return -1;

        break;
    default:
        return -1;

    }
    return codep;
}
Ejemplo n.º 2
0
/* writes a single test into almost-flat form starting at codep.
 * returns the next code location or -1 on error. */
static int bc_test_generate(int codep, bytecode_info_t *retval, test_t *t)
{
    if(!retval) return -1;
    switch(t->type) {
    case STRUE: /* BC_TRUE */
	if(!atleast(retval,codep+1)) return -1;
	retval->data[codep++].op = BC_TRUE;
	break;
    case SFALSE:/* BC_FALSE */
	if(!atleast(retval,codep+1)) return -1;
	retval->data[codep++].op = BC_FALSE;
	break;
    case NOT: /* BC_NOT {subtest : test} */
	if(!atleast(retval,codep+1)) return -1;
	retval->data[codep++].op = BC_NOT;
	codep = bc_test_generate(codep, retval, t->u.t);
	if (codep == -1) return -1;
	break;
    case SIZE: /* BC_SIZE (B_OVER | B_UNDER) {size : int} */
	if(!atleast(retval,codep+3)) return -1;
	retval->data[codep++].op = BC_SIZE;
	retval->data[codep++].value = (t->u.sz.t == OVER
				       ? B_OVER : B_UNDER);
	retval->data[codep++].value = t->u.sz.n;
	break;
    case EXISTS:/* BC_EXISTS { headers : string list } */
	if(!atleast(retval,codep+1)) return -1;
	retval->data[codep++].op = BC_EXISTS;
	codep= bc_stringlist_generate(codep, retval, t->u.sl);
	break;
    case ANYOF:/* BC_ANYOF { tests : test list } */
	if(!atleast(retval,codep+1)) return -1;
	retval->data[codep++].op = BC_ANYOF;
	codep=bc_testlist_generate(codep, retval, t->u.tl);
	if (codep == -1) return -1;
	break;
    case ALLOF: /* BC_ALLOF { tests : test list } */
	if(!atleast(retval,codep+1)) return -1;
	retval->data[codep++].op = BC_ALLOF;
	codep= bc_testlist_generate(codep, retval, t->u.tl);
	if (codep == -1) return -1;
	break;
    case HEADER:
	/* BC_HEADER { c: comparator } { headers : string list }
	   { patterns : string list } 
	*/
      
	if(!atleast(retval,codep + 1)) return -1;
	retval->data[codep++].op = BC_HEADER;
      
	/* comparator */
	codep = bc_comparator_generate(codep, retval,
				       t->u.h.comptag,
				       t->u.h.relation,
				       t->u.h.comparator);
	if (codep == -1) return -1;
      
	/* headers */
	codep = bc_stringlist_generate(codep, retval, t->u.h.sl);
	if (codep == -1) return -1;
      
	/* pattern */
	codep = bc_stringlist_generate(codep, retval, t->u.h.pl);
	if (codep == -1) return -1;
	break;
    case ADDRESS:
    case ENVELOPE:
	/* (BC_ADDRESS | BC_ENVELOPE) {c : comparator} 
	   (B_ALL | B_LOCALPART | ...) { header : string list }
	   { pattern : string list } */
      
	if(!atleast(retval,codep+1)) return -1;
      
	retval->data[codep++].op = (t->type == ADDRESS)
	    ? BC_ADDRESS : BC_ENVELOPE;
            
	codep = bc_comparator_generate(codep, retval,t->u.ae.comptag,
				       t->u.ae.relation, 
				       t->u.ae.comparator);
	if (codep == -1) return -1;

	if(!atleast(retval,codep+1)) return -1;

	/*address part*/
	switch(t->u.ae.addrpart) {
	case ALL:
	    retval->data[codep++].value = B_ALL;
	    break;
	case LOCALPART:
	    retval->data[codep++].value = B_LOCALPART;
	    break;
	case DOMAIN:
	    retval->data[codep++].value = B_DOMAIN;
	    break;
	case USER:
	    retval->data[codep++].value = B_USER;
	    break;
	case DETAIL:
	    retval->data[codep++].value = B_DETAIL;
	    break;
	default:
	    return -1;
	}

	/*headers*/
	codep = bc_stringlist_generate(codep, retval, t->u.ae.sl);
	if (codep == -1) return -1;

	/*patterns*/
	codep = bc_stringlist_generate(codep, retval, t->u.ae.pl);
	if (codep == -1) return -1;
     
	break;
    case BODY:
	/* BC_BODY {c : comparator} (B_RAW | B_TEXT | ...)
	   { content-types : stringlist }
	   { offset : int }
	   { pattern : string list } */
      
	if(!atleast(retval,codep+1)) return -1;
      
	retval->data[codep++].op = BC_BODY;
            
	codep = bc_comparator_generate(codep, retval,t->u.b.comptag,
				       t->u.b.relation, 
				       t->u.b.comparator);
	if (codep == -1) return -1;

	if(!atleast(retval,codep+2)) return -1;

	/*transform*/
	switch(t->u.b.transform) {
	case RAW:
	    retval->data[codep++].value = B_RAW;
	    break;
	case TEXT:
	    retval->data[codep++].value = B_TEXT;
	    break;
	case CONTENT:
	    retval->data[codep++].value = B_CONTENT;
	    break;
	default:
	    return -1;
	}

	/*offset*/
	retval->data[codep++].value = t->u.b.offset;

	/*content-types*/
	codep = bc_stringlist_generate(codep, retval, t->u.b.content_types);
	if (codep == -1) return -1;

	/*patterns*/
	codep = bc_stringlist_generate(codep, retval, t->u.b.pl);
	if (codep == -1) return -1;
     
	break;
    default:
	return -1;
      
    }
    return codep;
}