#include "common.h" #include "send.h" Biobuf bin; int rmail, tflg; char *subjectarg; char *findbody(char*); void main(int argc, char *argv[]) { message *mp; dest *dp; Reprog *p; Resub match[10]; char file[MAXPATHLEN + 1]; Biobuf *fp; char *rcvr, *cp; Mlock *l; String *tmp; int i; int header, body; header = body = 0; ARGBEGIN { case 'h': header = 1; break; case 'b': header = 1; body = 1; break; } ARGEND Binit(&bin, 0, OREAD); if(argc < 2){ fprint(2, "usage: filter rcvr mailfile [regexp mailfile ...]\n"); exits("usage"); } mp = m_read(&bin, 1, 0); /* get rid of local system name */ cp = strchr(s_to_c(mp->sender), '!'); if(cp){ cp++; mp->sender = s_copy(cp); } dp = d_new(s_copy(argv[0])); strecpy(file, file + sizeof(file), argv[1]); cp = findbody(s_to_c(mp->body)); for(i = 2; i < argc; i += 2){ p = regcomp(argv[i]); if(p == 0) continue; if(regexec(p, s_to_c(mp->sender), match, 10)){ regsub(argv[i+1], file, sizeof(file), match, 10); break; } if(header == 0 && body == 0) continue; if(regexec(p, s_to_c(mp->body), match, 10)){ if(body == 0 && match[0].sp >= cp) continue; regsub(argv[i+1], file, sizeof(file), match, 10); break; } } /* * always lock the normal mail file to avoid too many lock files * lying about. This isn't right but it's what the majority prefers. */ l = syslock(argv[1]); if(l == 0){ fprint(2, "can't lock mail file %s\n", argv[1]); exit(1); } /* * open the destination mail file */ fp = sysopen(file, "ca", MBOXMODE); if (fp == 0){ tmp = s_append(0, file); s_append(tmp, ".tmp"); fp = sysopen(s_to_c(tmp), "cal", MBOXMODE); if(fp == 0){ sysunlock(l); fprint(2, "can't open mail file %s\n", file); exit(1); } syslog(0, "mail", "error: used %s", s_to_c(tmp)); s_free(tmp); } Bseek(fp, 0, 2); if(m_print(mp, fp, (char *)0, 1) < 0 || Bprint(fp, "\n") < 0 || Bflush(fp) < 0){ sysclose(fp); sysunlock(l); fprint(2, "can't write mail file %s\n", file); exit(1); } sysclose(fp); sysunlock(l); rcvr = argv[0]; if(cp = strrchr(rcvr, '!')) rcvr = cp+1; logdelivery(dp, rcvr, mp); exit(0); } char* findbody(char *p) { if(*p == '\n') return p; while(*p){ if(*p == '\n' && *(p+1) == '\n') return p+1; p++; } return p; }