filter.c (2313B)
1 #include "common.h" 2 #include "send.h" 3 4 Biobuf bin; 5 int rmail, tflg; 6 char *subjectarg; 7 8 char *findbody(char*); 9 10 void 11 main(int argc, char *argv[]) 12 { 13 message *mp; 14 dest *dp; 15 Reprog *p; 16 Resub match[10]; 17 char file[MAXPATHLEN]; 18 Biobuf *fp; 19 char *rcvr, *cp; 20 Mlock *l; 21 String *tmp; 22 int i; 23 int header, body; 24 25 header = body = 0; 26 ARGBEGIN { 27 case 'h': 28 header = 1; 29 break; 30 case 'b': 31 header = 1; 32 body = 1; 33 break; 34 } ARGEND 35 36 Binit(&bin, 0, OREAD); 37 if(argc < 2){ 38 fprint(2, "usage: filter rcvr mailfile [regexp mailfile ...]\n"); 39 exits("usage"); 40 } 41 mp = m_read(&bin, 1, 0); 42 43 /* get rid of local system name */ 44 cp = strchr(s_to_c(mp->sender), '!'); 45 if(cp){ 46 cp++; 47 mp->sender = s_copy(cp); 48 } 49 50 dp = d_new(s_copy(argv[0])); 51 strecpy(file, file+sizeof file, argv[1]); 52 cp = findbody(s_to_c(mp->body)); 53 for(i = 2; i < argc; i += 2){ 54 p = regcomp(argv[i]); 55 if(p == 0) 56 continue; 57 if(regexec(p, s_to_c(mp->sender), match, 10)){ 58 regsub(argv[i+1], file, sizeof(file), match, 10); 59 break; 60 } 61 if(header == 0 && body == 0) 62 continue; 63 if(regexec(p, s_to_c(mp->body), match, 10)){ 64 if(body == 0 && match[0].s.sp >= cp) 65 continue; 66 regsub(argv[i+1], file, sizeof(file), match, 10); 67 break; 68 } 69 } 70 71 /* 72 * always lock the normal mail file to avoid too many lock files 73 * lying about. This isn't right but it's what the majority prefers. 74 */ 75 l = syslock(argv[1]); 76 if(l == 0){ 77 fprint(2, "can't lock mail file %s\n", argv[1]); 78 exit(1); 79 } 80 81 /* 82 * open the destination mail file 83 */ 84 fp = sysopen(file, "ca", MBOXMODE); 85 if (fp == 0){ 86 tmp = s_append(0, file); 87 s_append(tmp, ".tmp"); 88 fp = sysopen(s_to_c(tmp), "cal", MBOXMODE); 89 if(fp == 0){ 90 sysunlock(l); 91 fprint(2, "can't open mail file %s\n", file); 92 exit(1); 93 } 94 syslog(0, "mail", "error: used %s", s_to_c(tmp)); 95 s_free(tmp); 96 } 97 Bseek(fp, 0, 2); 98 if(m_print(mp, fp, (char *)0, 1) < 0 99 || Bprint(fp, "\n") < 0 100 || Bflush(fp) < 0){ 101 sysclose(fp); 102 sysunlock(l); 103 fprint(2, "can't write mail file %s\n", file); 104 exit(1); 105 } 106 sysclose(fp); 107 108 sysunlock(l); 109 rcvr = argv[0]; 110 if(cp = strrchr(rcvr, '!')) 111 rcvr = cp+1; 112 logdelivery(dp, rcvr, mp); 113 exit(0); 114 } 115 116 char* 117 findbody(char *p) 118 { 119 if(*p == '\n') 120 return p; 121 122 while(*p){ 123 if(*p == '\n' && *(p+1) == '\n') 124 return p+1; 125 p++; 126 } 127 return p; 128 }