static int dump2_test(bytecode_input_t *d, int i, int version) { test_t test; int len; /* there is no short circuiting involved here */ i = bc_test_parse(d, i, version, &test); switch (test.type) { case BC_NOT: printf("NOT "); i = dump2_test(d, i, version); break; case BC_ANYOF: case BC_ALLOF: len = test.u.aa.ntests; printf("%s({%d}\n\t", (test.type == BC_ANYOF) ? "ANYOF" : "ALLOF", len); while (len--) { i = dump2_test(d, i, version); printf("\t"); } printf(")\n"); break; default: print_test(&test); break; } return i; }
static void dump2(bytecode_input_t *d, int bc_len) { int i; int version; const char *data; int len; if (!d) return; if (memcmp(d, BYTECODE_MAGIC, BYTECODE_MAGIC_LEN)) { printf("not a bytecode file [magic number test failed]\n"); return; } i = BYTECODE_MAGIC_LEN / sizeof(bytecode_input_t); version = ntohl(d[i].op); printf("Sievecode version %d\n", version); for(i++; i<bc_len;) { int copy = 0; printf("%d: ",i); switch(ntohl(d[i++].op)) { case B_STOP:/*0*/ printf("STOP\n"); break; case B_KEEP:/*1*/ printf("KEEP\n"); break; case B_DISCARD:/*2*/ printf("DISCARD\n"); break; case B_REJECT:/*3*/ i = unwrap_string(d, i, &data, &len); printf("REJECT {%d}%s\n", len, data); break; case B_FILEINTO: /*19*/ copy = ntohl(d[i++].value); /* fall through */ case B_FILEINTO_ORIG: /*4*/ i = unwrap_string(d, i, &data, &len); printf("FILEINTO COPY(%d) FOLDER({%d}%s)\n",copy,len,data); break; case B_REDIRECT: /*20*/ copy = ntohl(d[i++].value); /* fall through */ case B_REDIRECT_ORIG: /*5*/ i = unwrap_string(d, i, &data, &len); printf("REDIRECT COPY(%d) ADDRESS({%d}%s)\n",copy,len,data); break; case B_IF:/*6*/ printf("IF (ends at %d)", ntohl(d[i].value)); /* there is no short circuiting involved here*/ i = dump2_test(d,i+1); printf("\n"); break; case B_MARK:/*7*/ printf("MARK\n"); break; case B_UNMARK:/*8*/ printf("UNMARK\n"); break; case B_ADDFLAG: /*9*/ printf("ADDFLAG {%d}\n",ntohl(d[i].len)); i=write_list(ntohl(d[i].len),i+1,d); break; case B_SETFLAG: /*10*/ printf("SETFLAG {%d}\n",ntohl(d[i].len)); i=write_list(ntohl(d[i].len),i+1,d); break; case B_REMOVEFLAG: /*11*/ printf("REMOVEFLAG {%d}\n",ntohl(d[i].len)); i=write_list(ntohl(d[i].len),i+1,d); break; case B_DENOTIFY:/*12*/ printf("DENOTIFY\n"); printf(" PRIORITY(%d) Comparison type %d (relat %d)\n", ntohl(d[i].value), ntohl(d[i+1].value), ntohl(d[i+2].value)); i+=3; i = unwrap_string(d, i+1, &data, &len); printf(" ({%d}%s)\n", len, (!data ? "[nil]" : data)); break; case B_NOTIFY: /*13*/ i = unwrap_string(d, i, &data, &len); printf("NOTIFY METHOD({%d}%s)\n",len,data); i = unwrap_string(d, i, &data, &len); printf(" ID({%d}%s) OPTIONS ", len, (!data ? "[nil]" : data)); i=write_list(ntohl(d[i].len),i+1,d); printf(" PRIORITY(%d)\n", ntohl(d[i].value)); i++; i = unwrap_string(d, i, &data, &len); printf(" MESSAGE({%d}%s)\n", len, data); break; case B_VACATION:/*14*/ printf("VACATION\n"); /*add address list here!*/ i=write_list(ntohl(d[i].len),i+1,d); i = unwrap_string(d, i, &data, &len); printf("%d SUBJ({%d}%s) \n",i, len, (!data ? "[nil]" : data)); i = unwrap_string(d, i, &data, &len); printf("%d MESG({%d}%s) \n", i, len, (!data ? "[nil]" : data)); printf("DAYS(%d) MIME(%d)\n", ntohl(d[i].value), ntohl(d[i+1].value)); i+=2; if (version >= 0x05) { i = unwrap_string(d, i, &data, &len); printf("%d FROM({%d}%s) \n",i, len, (!data ? "[nil]" : data)); i = unwrap_string(d, i, &data, &len); printf("%d HANDLE({%d}%s) \n",i, len, (!data ? "[nil]" : data)); } break; case B_NULL:/*15*/ printf("NULL\n"); break; case B_JUMP:/*16*/ printf("JUMP %d\n", ntohl(d[i].jump)); i+=1; break; case B_INCLUDE:/*17*/ printf("INCLUDE "); switch (ntohl(d[i].value)) { case B_PERSONAL: printf("Personal"); break; case B_GLOBAL: printf("Global"); break; } i = unwrap_string(d, i+1, &data, &len); printf(" {%d}%s\n", len, data); break; case B_RETURN:/*18*/ printf("RETURN\n"); break; default: printf("%d (NOT AN OP)\n",ntohl(d[i-1].op)); exit(1); } } printf("full len is: %d\n", bc_len); }
static int dump2_test(bytecode_input_t * d, int i) { int l,x; switch(ntohl(d[i].value)) { case BC_FALSE: printf("false"); i++; break; case BC_TRUE: printf("true"); i++; break; case BC_NOT:/*2*/ /* XXX there is a value being skipped in the second pass... no idea what it does, but it isn't carried to here... see bytecodee.c */ printf(" not("); i=dump2_test(d, i+1); printf(")\n"); break; case BC_EXISTS: printf("exists"); i=write_list(ntohl(d[i+1].len), i+2, d); break; case BC_SIZE: printf("size"); if (ntohl(d[i+1].value)==B_OVER) { /* over */ printf("over %d", ntohl(d[i+2].value)); } else { /* under */ printf("under %d", ntohl(d[i+2].value)); } i+=3; break; case BC_ANYOF:/*5*/ printf("any of \n("); l=ntohl(d[i+1].len); i+=3; for (x=0; x<l; x++) { i=dump2_test(d,i); if((x+1)<l) printf(" OR "); } printf(")\n"); break; case BC_ALLOF:/*6*/ printf("all of \n("); l=ntohl(d[i+1].len); i+=3; for (x=0; x<l; x++) { i=dump2_test(d,i); if((x+1)<l) printf(" AND "); } printf(")\n"); break; case BC_ADDRESS:/*7*/ printf("Address ["); i=printComparison(d, i+1); printf(" type: "); switch(ntohl(d[i++].value)) { case B_ALL: printf("all"); break; case B_LOCALPART:printf("localpart"); break; case B_DOMAIN:printf("domain"); break; case B_USER:printf("user"); break; case B_DETAIL:printf("detail"); break; } printf(" Headers:"); i=write_list(ntohl(d[i].len), i+1, d); printf(" Data:"); i=write_list(ntohl(d[i].len), i+1, d); printf(" ]\n"); break; case BC_ENVELOPE:/*8*/ printf("Envelope ["); i=printComparison(d, i+1); printf(" type: "); switch(ntohl(d[i++].value)) { case B_ALL: printf("all"); break; case B_LOCALPART:printf("localpart"); break; case B_DOMAIN:printf("domain"); break; case B_USER:printf("user"); break; case B_DETAIL:printf("detail"); break; } printf(" Headers:"); i=write_list(ntohl(d[i].len), i+1, d); printf(" Data:"); i=write_list(ntohl(d[i].len), i+1, d); printf(" ]\n"); break; case BC_HEADER:/*9*/ printf("Header ["); i= printComparison(d, i+1); printf(" Headers: "); i=write_list(ntohl(d[i].len), i+1, d); printf(" Data: "); i=write_list(ntohl(d[i].len), i+1, d); printf(" ]\n"); break; case BC_BODY:/*10*/ printf("Body ["); i=printComparison(d, i+1); printf(" Transform: "); switch(ntohl(d[i++].value)) { case B_RAW: printf("raw"); break; case B_TEXT:printf("text"); break; case B_CONTENT:printf("content"); break; } printf("\tOffset: %d\n", ntohl(d[i++].value)); printf(" Content-Types:"); i=write_list(ntohl(d[i].len), i+1, d); printf(" Data:"); i=write_list(ntohl(d[i].len), i+1, d); printf(" ]\n"); break; default: printf("WERT %d ", ntohl(d[i].value)); } return i; }
static void dump2(bytecode_input_t *d, int bc_len) { int i; int version, requires; if (!d) return; i = bc_header_parse(d, &version, &requires); if (i < 0) { printf("not a bytecode file [magic number test failed]\n"); return; } printf("Bytecode version: %d\n", version); if (version >= 0x11) { printf("Require:"); if (requires & BFE_VARIABLES) printf(" Variables"); printf("\n"); } printf("\n"); while (i < bc_len) { commandlist_t cmd; printf("%04d: ", i); i = bc_action_parse(d, i, version, &cmd); switch (cmd.type) { case B_STOP: printf("STOP"); break; case B_KEEP_ORIG: case B_KEEP_COPY: case B_KEEP: printf("KEEP"); if (cmd.type >= B_KEEP_COPY) { print_stringlist(" FLAGS", cmd.u.k.flags); } break; case B_DISCARD: printf("DISCARD"); break; case B_EREJECT: printf("E"); GCC_FALLTHROUGH case B_REJECT: print_string("REJECT ", cmd.u.str); break; case B_ERROR: print_string("ERROR ", cmd.u.str); break; case B_FILEINTO_ORIG: case B_FILEINTO_COPY: case B_FILEINTO_FLAGS: case B_FILEINTO_CREATE: case B_FILEINTO_SPECIALUSE: case B_FILEINTO: printf("FILEINTO"); if (cmd.type >= B_FILEINTO_COPY) { printf(" COPY(%d)", cmd.u.f.copy); if (cmd.type >= B_FILEINTO_FLAGS) { print_stringlist(" FLAGS", cmd.u.f.flags); if (cmd.type >= B_FILEINTO_CREATE) { printf("\n\tCREATE(%d)", cmd.u.f.create); if (cmd.type >= B_FILEINTO_SPECIALUSE) { print_string(" SPECIALUSE", cmd.u.f.specialuse); if (cmd.type >= B_FILEINTO) { print_string(" MAILBOXID", cmd.u.f.mailboxid); } } } } } print_string(" FOLDER", cmd.u.f.folder); break; case B_REDIRECT_ORIG: case B_REDIRECT_COPY: case B_REDIRECT_LIST: case B_REDIRECT: printf("REDIRECT"); if (cmd.type >= B_REDIRECT_COPY) { printf(" COPY(%d)", cmd.u.r.copy); if (cmd.type >= B_REDIRECT_LIST) { printf( "LIST(%d)", cmd.u.r.list); if (cmd.type >= B_REDIRECT) { print_string(" BYTIME", cmd.u.r.bytime); print_string(" BYMODE", cmd.u.r.bymode); printf(" BYTRACE(%d)", cmd.u.r.bytrace); print_string("\n\tDSN-NOTIFY", cmd.u.r.dsn_notify); print_string(" DSN-RET", cmd.u.r.dsn_ret); } } } print_string(" ADDRESS", cmd.u.r.address); break; case B_IF: printf("IF (ends at %d) ", cmd.u.i.testend); i = dump2_test(d, i, version); break; case B_MARK: printf("MARK"); break; case B_UNMARK: printf("UNMARK"); break; case B_ADDFLAG_ORIG: case B_ADDFLAG: printf("ADDFLAG"); if (cmd.type >= B_ADDFLAG) print_string(" VARIABLE", cmd.u.fl.variable); print_stringlist(" FLAGS", cmd.u.fl.flags); break; case B_SETFLAG_ORIG: case B_SETFLAG: printf("SETFLAG"); if (cmd.type >= B_SETFLAG) print_string(" VARIABLE", cmd.u.fl.variable); print_stringlist(" FLAGS", cmd.u.fl.flags); break; case B_REMOVEFLAG_ORIG: case B_REMOVEFLAG: printf("REMOVEFLAG"); if (cmd.type >= B_REMOVEFLAG) print_string(" VARIABLE", cmd.u.fl.variable); print_stringlist(" FLAGS", cmd.u.fl.flags); break; case B_DENOTIFY: printf("DENOTIFY PRIORITY(%d)", cmd.u.d.priority); if (cmd.u.d.pattern) { print_comparator(&cmd.u.d.comp); print_string("\n\tPATTERN", cmd.u.d.pattern); } break; case B_ENOTIFY: printf("E"); GCC_FALLTHROUGH case B_NOTIFY: printf("NOTIFY "); print_string(" METHOD", cmd.u.n.method); if (cmd.type == B_ENOTIFY) { printf(" IMPORTANCE(%d)", cmd.u.n.priority); print_string(" FROM", cmd.u.n.from); } else { printf(" PRIORITY(%d)", cmd.u.n.priority); print_string(" ID", cmd.u.n.id); } print_stringlist(" OPTIONS", cmd.u.n.options); print_string("\n\tMESSAGE", cmd.u.n.message); break; case B_VACATION_ORIG: case B_VACATION_SEC: case B_VACATION_FCC: case B_VACATION: printf("VACATION"); print_stringlist(" ADDR", cmd.u.v.addresses); print_string("\n\tSUBJ", cmd.u.v.subject); print_string("\n\tMESG", cmd.u.v.message); printf("\n\tSECONDS(%d) MIME(%d)", cmd.u.v.seconds * (cmd.type == B_VACATION_ORIG ? DAY2SEC : 1), cmd.u.v.mime); if (version >= 0x05) { print_string(" FROM", cmd.u.v.from); print_string(" HANDLE", cmd.u.v.handle); if (cmd.type >= B_VACATION_FCC) { print_string("\n\tFCC", cmd.u.v.fcc.folder); if (cmd.u.v.fcc.folder) { printf(" CREATE(%d)", cmd.u.v.fcc.create); print_stringlist(" FLAGS", cmd.u.v.fcc.flags); if (cmd.type >= B_VACATION) { print_string("\n\tSPECIALUSE", cmd.u.v.fcc.specialuse); } } } } break; case B_NULL: printf("NULL"); break; case B_JUMP: printf("JUMP %d", cmd.u.jump); break; case B_INCLUDE: printf("INCLUDE LOCATION(%s) ONCE(%d) OPTIONAL(%d)", (cmd.u.inc.location = B_PERSONAL) ? "Personal" : "Global", cmd.u.inc.once, cmd.u.inc.optional); print_string("\n\tSCRIPT", cmd.u.inc.script); break; case B_SET: printf("SET LOWER(%d) UPPER(%d)", cmd.u.s.mod40 & BFV_LOWER, cmd.u.s.mod40 & BFV_UPPER); printf(" LOWERFIRST(%d) UPPERFIRST(%d)", cmd.u.s.mod30 & BFV_LOWERFIRST, cmd.u.s.mod30 & BFV_UPPERFIRST); printf("\n\tQUOTEWILDCARD(%d) QUOTEREGEX(%d)", cmd.u.s.mod20 & BFV_QUOTEWILDCARD, cmd.u.s.mod20 & BFV_QUOTEREGEX); printf(" ENCODEURL(%d) LENGTH(%d)", cmd.u.s.mod15 & BFV_ENCODEURL, cmd.u.s.mod10 & BFV_LENGTH); print_string("\n\tVARIABLE", cmd.u.s.variable); print_string(" VALUE", cmd.u.s.value); break; case B_ADDHEADER: printf("ADDHEADER INDEX(%d)", cmd.u.ah.index); print_string(" NAME", cmd.u.ah.name); print_string(" VALUE", cmd.u.ah.value); break; case B_DELETEHEADER: printf("DELETEHEADER INDEX(%d)", cmd.u.dh.comp.index); print_comparator(&cmd.u.dh.comp); print_string("\n\tNAME", cmd.u.dh.name); print_stringlist(" VALUES", cmd.u.dh.values); break; case B_RETURN: printf("RETURN"); break; default: printf("%d (NOT AN OP)\n", cmd.type); exit(1); } printf("\n"); } printf("full len is: %d\n", bc_len); }