Esempio n. 1
0
/*
 *  report a recipient to remote
 */
char *
rcptto(char *to)
{
	String *s;

	s = unescapespecial(bangtoat(to));
	if(toline == 0)
		toline = s_new();
	else
		s_append(toline, ", ");
	s_append(toline, s_to_c(s));
	if(strchr(s_to_c(s), '@'))
		dBprint("RCPT TO:<%s>\r\n", s_to_c(s));
	else {
		s_append(toline, "@");
		s_append(toline, ddomain);
		dBprint("RCPT TO:<%s@%s>\r\n", s_to_c(s), ddomain);
	}
	alarm(10*alarmscale);
	switch(getreply()){
	case 2:
		break;
	case 5:
		return Giveup;
	default:
		return Retry;
	}
	return 0;
}
Esempio n. 2
0
/* dispose of local addresses */
int
cat_mail(dest *dp, message *mp)
{
	Biobuf *fp;
	char *rcvr, *cp;
	Mlock *l;
	String *tmp, *s;
	int i, n;

	s = unescapespecial(s_clone(dp->repl1));
	if (nflg) {
		if(!xflg)
			print("cat >> %s\n", s_to_c(s));
		else
			print("%s\n", s_to_c(dp->addr));
		s_free(s);
		return 0;
	}
	for(i = 0;; i++){
		l = syslock(s_to_c(s));
		if(l == 0)
			return refuse(dp, mp, "can't lock mail file", 0, 0);

		fp = sysopen(s_to_c(s), "al", MBOXMODE);
		if(fp)
			break;
		tmp = s_append(0, s_to_c(s));
		s_append(tmp, ".tmp");
		fp = sysopen(s_to_c(tmp), "al", MBOXMODE);
		if(fp){
			syslog(0, "mail", "error: used %s", s_to_c(tmp));
			s_free(tmp);
			break;
		}
		s_free(tmp);
		sysunlock(l);
		if(i >= 5)
			return refuse(dp, mp, "mail file cannot be opened", 0, 0);
		sleep(1000);
	}
	s_free(s);
	n = m_print(mp, fp, (char *)0, 1);
	if (Bprint(fp, "\n") < 0 || Bflush(fp) < 0 || n < 0){
		sysclose(fp);
		sysunlock(l);
		return refuse(dp, mp, "error writing mail file", 0, 0);
	}
	sysclose(fp);
	sysunlock(l);
	rcvr = s_to_c(dp->addr);
	if(cp = strrchr(rcvr, '!'))
		rcvr = cp+1;
	logdelivery(dp, rcvr, mp);
	return 0;
}
Esempio n. 3
0
/* output a message */
extern int
m_print(message *mp, Biobuf *fp, char *remote, int mbox)
{
	String *date, *sender;
	char *f[6];
	int n;

	sender = unescapespecial(s_clone(mp->sender));

	if (remote != 0){
		if(print_remote_header(fp,s_to_c(sender),s_to_c(mp->date),remote) < 0){
			s_free(sender);
			return -1;
		}
	} else {
		if(print_header(fp, s_to_c(sender), s_to_c(mp->date)) < 0){
			s_free(sender);
			return -1;
		}
	}
	s_free(sender);
	if(!rmail && !mp->havedate){
		/* add a date: line Date: Sun, 19 Apr 1998 12:27:52 -0400 */
		date = s_copy(s_to_c(mp->date));
		n = getfields(s_to_c(date), f, 6, 1, " \t");
		if(n == 6)
			Bprint(fp, "Date: %s, %s %s %s %s %s\n", f[0], f[2], f[1],
			 f[5], f[3], rewritezone(f[4]));
	}
	if(!rmail && !mp->havemime && isutf8(mp->body))
		printutf8mime(fp);
	if(mp->to){
		/* add the to: line */
		if (Bprint(fp, "%s\n", s_to_c(mp->to)) < 0)
			return -1;
		/* add the from: line */
		if (!mp->havefrom && printfrom(mp, fp) < 0)
			return -1;
		if(!mp->rfc822headers && *s_to_c(mp->body) != '\n')
			if (Bprint(fp, "\n") < 0)
				return -1;
	} else if(!rmail){
		/* add the from: line */
		if (!mp->havefrom && printfrom(mp, fp) < 0)
			return -1;
		if(!mp->rfc822headers && *s_to_c(mp->body) != '\n')
			if (Bprint(fp, "\n") < 0)
				return -1;
	}

	if (!mbox)
		return m_noescape(mp, fp);
	return m_escape(mp, fp);
}
Esempio n. 4
0
int
matcher(char *action, Pattern *p, char *message, Resub *m)
{
    char *cp;
    String *s;

    for(cp = message; matchpat(p, cp, m); cp = m->ep) {
        switch(p->action) {
        case SaveLine:
            if(vflag)
                xprint(2, action, m);
            saveline(linefile, sender, m);
            break;
        case HoldHeader:
        case Hold:
            if(nflag)
                continue;
            if(vflag)
                xprint(2, action, m);
            *qdir = holdqueue;
            if(hflag && qname) {
                cp = strchr(sender, '!');
                if(cp) {
                    *cp = 0;
                    *qname = strdup(sender);
                    *cp = '!';
                } else
                    *qname = strdup(sender);
            }
            return 1;
        case Dump:
            if(vflag)
                xprint(2, action, m);
            *(m->ep) = 0;
            if(!tflag) {
                s = s_new();
                s_append(s, sender);
                s = unescapespecial(s);
                syslog(0, "smtpd", "Dumped %s [%s] to %s", s_to_c(s), m->sp,
                       s_to_c(s_restart(recips)));
                s_free(s);
            }
            tflag = 1;
            if(sflag)
                cout = opendump(sender);
            return 1;
        default:
            break;
        }
    }
    return 0;
}
Esempio n. 5
0
static int
printfrom(message *mp, Biobuf *fp)
{
	String *s;
	int rv;

	if(!returnable(s_to_c(mp->sender)))
		return Bprint(fp, "From: Postmaster\n");

	s = username(mp->sender);
	if(s) {
		s_append(s, " <");
		s_append(s, s_to_c(mp->sender));
		s_append(s, ">");
	} else {
		s = s_copy(s_to_c(mp->sender));
	}
	s = unescapespecial(s);
	rv = Bprint(fp, "From: %s\n", s_to_c(s));
	s_free(s);
	return rv;
}
Esempio n. 6
0
File: runq.c Progetto: 99years/plan9
/*
 *  send back the mail with an error message
 *
 *  return 0 if successful
 */
int
returnmail(char **av, char *name, char *msg)
{
	int pfd[2];
	Waitmsg *wm;
	int fd;
	char buf[256];
	char attachment[256];
	int i;
	long n;
	String *s;
	char *sender;

	if(av[1] == 0 || av[2] == 0){
		logit("runq - dumping bad file", name, av);
		return 0;
	}

	s = unescapespecial(s_copy(av[2]));
	sender = s_to_c(s);

	if(!returnable(sender) || strcmp(sender, "postmaster") == 0) {
		logit("runq - dumping p to p mail", name, av);
		return 0;
	}

	if(pipe(pfd) < 0){
		logit("runq - pipe failed", name, av);
		return -1;
	}

	switch(rfork(RFFDG|RFPROC|RFENVG)){
	case -1:
		logit("runq - fork failed", name, av);
		return -1;
	case 0:
		logit("returning", name, av);
		close(pfd[1]);
		close(0);
		dup(pfd[0], 0);
		close(pfd[0]);
		putenv("upasname", "/dev/null");
		snprint(buf, sizeof(buf), "%s/marshal", UPASBIN);
		snprint(attachment, sizeof(attachment), "%s", file(name, 'D'));
		execl(buf, "send", "-A", attachment, "-s", "permanent failure", sender, nil);
		error("can't exec", 0);
		break;
	default:
		break;
	}

	close(pfd[0]);
	fprint(pfd[1], "\n");	/* get out of headers */
	if(av[1]){
		fprint(pfd[1], "Your request ``%.20s ", av[1]);
		for(n = 3; av[n]; n++)
			fprint(pfd[1], "%s ", av[n]);
	}
	fprint(pfd[1], "'' failed (code %s).\nThe symptom was:\n\n", msg);
	fd = open(file(name, 'E'), OREAD);
	if(fd >= 0){
		for(;;){
			n = read(fd, buf, sizeof(buf));
			if(n <= 0)
				break;
			if(write(pfd[1], buf, n) != n){
				close(fd);
				goto out;
			}
		}
		close(fd);
	}
	close(pfd[1]);
out:
	wm = wait();
	if(wm == nil){
		syslog(0, "runq", "wait: %r");
		logit("wait failed", name, av);
		return -1;
	}
	i = 0;
	if(wm->msg[0]){
		i = -1;
		syslog(0, "runq", "returnmail child: %s", wm->msg);
		logit("returnmail child failed", name, av);
	}
	free(wm);
	return i;
}
Esempio n. 7
0
void
main(int argc, char **argv)
{
	int i, ok, rcvrs;
	char *addr, *rv, *trv, *host, *domain;
	char **errs;
	char hellodomain[256];
	String *from, *fromm, *sender;

	alarmscale = 60*1000;	/* minutes */
	quotefmtinstall();
	fmtinstall('[', encodefmt);
	errs = malloc(argc*sizeof(char*));
	reply = s_new();
	host = 0;
	ARGBEGIN{
	case 'a':
		tryauth = 1;
		if(trysecure == 0)
			trysecure = 1;
		break;
	case 'A':	/* autistic: won't talk to us until we talk (Verizon) */
		autistic = 1;
		break;
	case 'b':
		if (bustedmx >= Maxbustedmx)
			sysfatal("more than %d busted mxs given", Maxbustedmx);
		bustedmxs[bustedmx++] = EARGF(usage());
		break;
	case 'd':
		debug = 1;
		break;
	case 'f':
		filter = 1;
		break;
	case 'g':
		gdomain = EARGF(usage());
		break;
	case 'h':
		host = EARGF(usage());
		break;
	case 'i':
		insecure = 1;
		break;
	case 'p':
		alarmscale = 10*1000;	/* tens of seconds */
		ping = 1;
		break;
	case 's':
		if(trysecure == 0)
			trysecure = 1;
		break;
	case 't':
		trysecure = 2;
		break;
	case 'u':
		user = EARGF(usage());
		break;
	default:
		usage();
		break;
	}ARGEND;

	Binit(&berr, 2, OWRITE);
	Binit(&bfile, 0, OREAD);

	/*
	 *  get domain and add to host name
	 */
	if(*argv && **argv=='.') {
		domain = *argv;
		argv++; argc--;
	} else
		domain = domainname_read();
	if(host == 0)
		host = sysname_read();
	strcpy(hostdomain, domainify(host, domain));
	strcpy(hellodomain, domainify(sysname_read(), domain));

	/*
	 *  get destination address
	 */
	if(*argv == 0)
		usage();
	addr = *argv++; argc--;
	farend = addr;

	/*
	 *  get sender's machine.
	 *  get sender in internet style.  domainify if necessary.
	 */
	if(*argv == 0)
		usage();
	sender = unescapespecial(s_copy(*argv++));
	argc--;
	fromm = s_clone(sender);
	rv = strrchr(s_to_c(fromm), '!');
	if(rv)
		*rv = 0;
	else
		*s_to_c(fromm) = 0;
	from = bangtoat(s_to_c(sender));

	/*
	 *  send the mail
	 */
	if(filter){
		Binit(&bout, 1, OWRITE);
		rv = data(from, &bfile);
		if(rv != 0)
			goto error;
		exits(0);
	}

	/* mxdial uses its own timeout handler */
	if((rv = connect(addr)) != 0)
		exits(rv);

	/* 10 minutes to get through the initial handshake */
	atnotify(timeout, 1);
	alarm(10*alarmscale);
	if((rv = hello(hellodomain, 0)) != 0)
		goto error;
	alarm(10*alarmscale);
	if((rv = mailfrom(s_to_c(from))) != 0)
		goto error;

	ok = 0;
	rcvrs = 0;
	/* if any rcvrs are ok, we try to send the message */
	for(i = 0; i < argc; i++){
		if((trv = rcptto(argv[i])) != 0){
			/* remember worst error */
			if(rv != Giveup)
				rv = trv;
			errs[rcvrs] = strdup(s_to_c(reply));
			removenewline(errs[rcvrs]);
		} else {
			ok++;
			errs[rcvrs] = 0;
		}
		rcvrs++;
	}

	/* if no ok rcvrs or worst error is retry, give up */
	if(ok == 0 || rv == Retry)
		goto error;

	if(ping){
		quit(0);
		exits(0);
	}

	rv = data(from, &bfile);
	if(rv != 0)
		goto error;
	quit(0);
	if(rcvrs == ok)
		exits(0);

	/*
	 *  here when some but not all rcvrs failed
	 */
	fprint(2, "%s connect to %s:\n", thedate(), addr);
	for(i = 0; i < rcvrs; i++){
		if(errs[i]){
			syslog(0, "smtp.fail", "delivery to %s at %s failed: %s", argv[i], addr, errs[i]);
			fprint(2, "  mail to %s failed: %s", argv[i], errs[i]);
		}
	}
	exits(Giveup);

	/*
	 *  here when all rcvrs failed
	 */
error:
	removenewline(s_to_c(reply));
	syslog(0, "smtp.fail", "%s to %s failed: %s",
		ping ? "ping" : "delivery",
		addr, s_to_c(reply));
	fprint(2, "%s connect to %s:\n%s\n", thedate(), addr, s_to_c(reply));
	if(!filter)
		quit(rv);
	exits(rv);
}
Esempio n. 8
0
/* loop through the names to be translated */
void
main(int argc, char *argv[])
{
	String *s;
	String *alias;		/* the alias for the name */
	char **names;		/* names of this system */
	String *files;		/* list of files to search */
	int i, rv;
	char *p;

	ARGBEGIN {
	case 'd':
		debug = 1;
		break;
	case 'f':
		from = 1;
		break;
	case 'n':
		namefiles = ARGF();
		break;
	} ARGEND
	if (chdir(UPASLIB) < 0) {
		perror("translate(chdir):");
		exit(1);
	}

	/* get environmental info */
	names = sysnames_read();
	files = getdbfiles();
	alias = s_new();

	/* loop through the names to be translated (from standard input) */
	for(i=0; i<argc; i++) {
		s = unescapespecial(s_copy(mklower(argv[i])));
		if(strchr(s_to_c(s), '!') == 0)
			rv = translate(s_to_c(s), names, files, alias);
		else
			rv = -1;
		if(from){
			if (rv >= 0 && *s_to_c(alias) != '\0'){
				p = strchr(s_to_c(alias), '\n');
				if(p)
					*p = 0;
				p = strchr(s_to_c(alias), '!');
				if(p) {
					*p = 0;
					print("%s", s_to_c(alias));
				} else {
					p = strchr(s_to_c(alias), '@');
					if(p)
						print("%s", p+1);
					else
						print("%s", s_to_c(alias));
				}
			}
		} else {
			if (rv < 0 || *s_to_c(alias) == '\0')
				print("local!%s\n", s_to_c(s));
			else {
				/* this must be a write, not a print */
				write(1, s_to_c(alias), strlen(s_to_c(alias)));
			}
		}
		s_free(s);
	}
	exits(0);
}