plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

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 }