diff options
Diffstat (limited to 'src/cmd/upas/send/filter.c')
-rw-r--r-- | src/cmd/upas/send/filter.c | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/src/cmd/upas/send/filter.c b/src/cmd/upas/send/filter.c new file mode 100644 index 00000000..cfee5253 --- /dev/null +++ b/src/cmd/upas/send/filter.c @@ -0,0 +1,128 @@ +#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]; + 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].s.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; +} |