forsyth20121205-174063a80cc13 years agoHistory
252 lines · 4.9 KB · Brainfuck
RawDownload
implement Sendmail; include "sys.m";   	sys: Sys;include "draw.m";include "bufio.m";include "daytime.m";include "smtp.m";include "env.m"; sprint, fprint : import sys; DEBUG : con 0;STRMAX : con 512; Sendmail : module{	PATH : con "/dis/sendmail.dis"; 	# argv is list of persons to send mail to (or nil if To: lines present in message)	# mail is read from standard input	# scans mail for headers (From: , To: , Cc: , Subject: , Re: ) where case is not sensitive	init: fn(ctxt : ref Draw->Context, argv : list of string);}; init(nil : ref Draw->Context, args : list of string) {	from : string;	tos, cc : list of string = nil;   	sys = load Sys Sys->PATH;	smtp := load Smtp Smtp->PATH;  	if (smtp == nil)    		error(sprint("cannot load %s", Smtp->PATH), 1);	daytime := load Daytime Daytime->PATH;	if (daytime == nil)		error(sprint("cannot load %s", Daytime->PATH), 1);	msgl := readin();	for (ml := msgl; ml != nil; ml = tl ml) {		msg := hd ml;		lenm := len msg;		sol := 1;		for (i := 0; i < lenm; i++) {			if (sol) {				for (j := i; j < lenm; j++)					if (msg[j] == '\n')						break;				s := msg[i:j];				if (from == nil) {					from = match(s, "from");					if (from != nil)						from = extract(from);				}				if (tos == nil)					tos = lmatch(s, "to");				if (cc == nil)					cc = lmatch(s, "cc");				sol = 0;			}			if (msg[i] == '\n')				sol = 1;		}	}	if (tos != nil && tl args != nil)		error("recipients specified on To: line and as args - aborted", 1);	if (from == nil)		from = readfile("/dev/user");	from = adddom(from);	if (tos == nil)		tos = tl args;	(ok, err) := smtp->open(nil);  	if (ok < 0) {		smtp->close();    		error(sprint("smtp open failed: %s", err), 1);	}	dump(from, tos, cc, msgl);	msgl = "From " + from + "\t" + daytime->time() + "\n" :: msgl;	# msgl = "From: " + from + "\n" + "Date: " + daytime->time() + "\n" :: msgl;	(ok, err) = smtp->sendmail(from, tos, cc, msgl);	if (ok < 0) {		smtp->close();		error(sprint("send failed : %s", err), 0);	}	smtp->close();} readin() : list of string{	m : string;	ls : list of string;	nc : int; 	bufio := load Bufio Bufio->PATH;	Iobuf : import bufio;	b := bufio->fopen(sys->fildes(0), Bufio->OREAD);	ls = nil;	m = nil;	nc = 0;	while ((s := b.gets('\n')) != nil) {		if (nc > STRMAX) {			ls = m :: ls;			m = nil;			nc = 0;		}		m += s;		nc += len s;	}	b.close();	if (m != nil)		ls = m :: ls;	return rev(ls);} match(s: string, pat : string) : string{	ls := len s;	lp := len pat;	if (ls < lp)		return nil;	for (i := 0; i < lp; i++) {		c := s[i];		if (c >= 'A' && c <= 'Z')			c += 'a'-'A';		if (c != pat[i])			return nil;	}	if (i < len s && s[i] == ':')		i++;	else if (i < len s - 1 && s[i] == ' ' && s[i+1] == ':')		i += 2;	else		return nil;	while (i < len s && (s[i] == ' ' || s[i] == '\t'))		i++;	j := ls-1;	while (j >= 0 && (s[j] == ' ' || s[j] == '\t' || s[j] == '\n'))		j--;	return s[i:j+1];}	lmatch(s : string, pat : string) : list of string{	r := match(s, pat);	if (r != nil) {		(ok, lr) := sys->tokenize(r, " ,\t");		return lr;	}	return nil;}	extract(s : string) : string{	ls := len s;	for(i := 0; i < ls; i++) {		if(s[i] == '<') {			for(j := i+1; j < ls; j++)				if(s[j] == '>')					break;			return s[i+1:j];		}	}	return s;} adddom(s : string) : string{	if (s == nil)		return nil;	for (i := 0; i < len s; i++)		if (s[i] == '@')			return s;	# better to get it from environment if possible	env := load Env Env->PATH;	if (env != nil && (dom := env->getenv("DOMAIN")) != nil) {		ldom := len dom;		if (dom[ldom - 1] == '\n')			dom = dom[0:ldom - 1];		return s + "@" + dom;	}	d := readfile("/usr/" + s + "/mail/domain");	if (d != nil) {		ld := len d;		if (d[ld - 1] == '\n')			d = d[0:ld - 1];		return s + "@" + d;	}	return s;}	readfile(f : string) : string{  	fd := sys->open(f, sys->OREAD);  	if(fd == nil)    		return nil;  	buf := array[128] of byte;  	n := sys->read(fd, buf, len buf);  	if(n < 0)    		return nil;  	return string buf[0:n];	} rev(l1 : list of string) : list of string{	l2 : list of string = nil; 	for ( ; l1 != nil; l1 = tl l1)		l2 = hd l1 :: l2;	return l2;} lprint(fd : ref Sys->FD, ls : list of string){	for ( ; ls != nil; ls = tl ls)		fprint(fd, "%s ", hd ls);	fprint(fd, "\n");} cfd : ref Sys->FD; opencons(){	if (cfd == nil)		cfd = sys->open("/dev/cons", Sys->OWRITE);} dump(from : string, tos : list of string, cc : list of string, msgl : list of string){	if (DEBUG) {		opencons();		fprint(cfd, "from\n");		fprint(cfd, "%s\n", from);		fprint(cfd, "to\n");		lprint(cfd, tos);		fprint(cfd, "cc\n");		lprint(cfd, cc);		fprint(cfd, "message\n");		for ( ; msgl != nil; msgl = tl msgl) {			fprint(cfd, "%s", hd msgl);			fprint(cfd, "xxxx\n");		}	}} error(s : string, ex : int){	if (DEBUG) {		opencons();		fprint(cfd, "sendmail: %s\n", s);	}	fprint(sys->fildes(2), "sendmail: %s\n", s);	if (ex)		exit;}