예제 #1
0
파일: sleep.c 프로젝트: aahud/harvey
void
main(void)
{
	int64_t a2000, a500, tStart, tEnd;
	if (!atnotify(printFirst, 1) || !atnotify(failOnSecond, 1)){
		fprint(2, "%r\n");
		exits("atnotify fails");
	}

	alarm(2000);
	a2000 = nsec();
	alarm(500);
	a500 = nsec();
	tStart = nsec();
	sleep(1000);
	tEnd = nsec();

	if(verbose)
		fprint(2, "%d: set alarm(2000)@%lld then alarm(500)@%lld; elapsed in sleep() %lld nanosecond\n", getpid(), a2000, a500, tEnd-tStart);

	if(tEnd-tStart > 1200 * 1000 * 1000){
		print("FAIL: should sleep less\n");
		exits("FAIL");
	}

	if(tEnd-tStart < 800 * 1000 * 1000){
		print("FAIL: should sleep more\n");
		exits("FAIL");
	}

	print("PASS\n");
	exits("PASS");
}
예제 #2
0
파일: mxdial.c 프로젝트: 9fans/plan9port
/*
 *  take an address and return all the mx entries for it,
 *  most preferred first
 */
static int
callmx(DS *ds, char *dest, char *domain)
{
	int fd, i, nmx;
	char addr[Maxstring];

	/* get a list of mx entries */
	nmx = mxlookup(ds, domain);
	if(nmx < 0){
		/* dns isn't working, don't just dial */
		return -1;
	}
	if(nmx == 0){
		if(debug)
			fprint(2, "mxlookup returns nothing\n");
		return dial(dest, 0, 0, 0);
	}

	/* refuse to honor loopback addresses given by dns */
	for(i = 0; i < nmx; i++){
		if(strcmp(mx[i].ip, "127.0.0.1") == 0){
			if(debug)
				fprint(2, "mxlookup returns loopback\n");
			werrstr("illegal: domain lists 127.0.0.1 as mail server");
			return -1;
		}
	}

	/* sort by preference */
	if(nmx > 1)
		qsort(mx, nmx, sizeof(Mx), compar);

	if(debug){
		for(i=0; i<nmx; i++)
			print("%s %d\n", mx[i].host, mx[i].pref);
	}
	/* dial each one in turn */
	for(i = 0; i < nmx; i++){
#ifdef PLAN9PORT
		snprint(addr, sizeof(addr), "%s", mx[i].host);
#else
		snprint(addr, sizeof(addr), "%s!%s!%s", ds->proto,
			mx[i].host, ds->service);
#endif
		if(debug)
			fprint(2, "mxdial trying %s (%d)\n", addr, i);
		atnotify(timeout, 1);
		alarm(10*1000);
#ifdef PLAN9PORT
		fd = smtpdial(addr);
#else
		fd = dial(addr, 0, 0, 0);
#endif
		alarm(0);
		atnotify(timeout, 0);
		if(fd >= 0)
			return fd;
	}
	return -1;
}
예제 #3
0
long
timedwrite(int fd, void *buf, long len, long ms)
{
	long n, oalarm;

	atnotify(timeout, 1);
	oalarm = alarm(ms);
	n = write(fd, buf, len);
	alarm(oalarm);
	atnotify(timeout, 0);
	return n;
}
예제 #4
0
파일: tee.c 프로젝트: Earnestly/plan9
void
main(int argc, char **argv)
{
	int i;
	int r, n;

	ARGBEGIN {
	case 'a':
		aflag++;
		break;

	case 'i':
		atnotify(intignore, 1);
		break;

	case 'u':
		uflag++;
		/* uflag is ignored and undocumented; it's a relic from Unix */
		break;

	default:
		fprint(2, "usage: tee [-ai] [file ...]\n");
		exits("usage");
	} ARGEND

	openf = malloc((1+argc)*sizeof(int));
	if(openf == nil)
		sysfatal("out of memory: %r");

	n = 0;
	while(*argv) {
		if(aflag) {
			openf[n] = open(argv[0], OWRITE);
			if(openf[n] < 0)
				openf[n] = create(argv[0], OWRITE, 0666);
			seek(openf[n], 0L, 2);
		} else
			openf[n] = create(argv[0], OWRITE, 0666);
		if(openf[n] < 0) {
			fprint(2, "tee: cannot open %s: %r\n", argv[0]);
		} else
			n++;
		argv++;
	}
	openf[n++] = 1;

	for(;;) {
		r = read(0, in, sizeof in);
		if(r <= 0)
			exits(nil);
		for(i=0; i<n; i++)
			write(openf[i], in, r);
	}
}
예제 #5
0
파일: lockt.c 프로젝트: aahud/harvey
void
main(void)
{
	int64_t start, elapsed, res;
	static Lock l;

	rfork(RFNOTEG|RFREND);
	rStart.l = &rl;
	rCompleted.l = &rl;
	resInWaiter = 0xff;

	spawnWaiter(&l);
	lock(&l);

	alarm(20000);	/* global timeout, FAIL if reached */
	if (!atnotify(failOnTimeout, 1)){
		fprint(2, "%r\n");
		exits("atnotify fails");
	}

	/* verify that lockt returns 0 on timeout */
	start = nsec();
	res = lockt(&l, 1000);
	elapsed = (nsec() - start) / (1000 * 1000);
	if(verbose)
		print("lockt returned %d, elapsed = %d ms\n", res, elapsed);
	if(res != 0 || elapsed < 900 || elapsed > 1300){
		print("FAIL: lockt timeout\n");
		exits("FAIL");
	}

	/* verify that lockt returns 1 if the lock is released and
	 * it can take it
	 */
	resInWaiter = -1;
	qlock(&rl);
	rwakeupall(&rStart);
	qunlock(&rl);
	sleep(1200);
	unlock(&l);

	qlock(&rl);
	while(elapsedInWaiter == 0)
		rsleep(&rCompleted);
	qunlock(&rl);
	if(resInWaiter != 1 || elapsedInWaiter < 1100 || elapsedInWaiter > 1500){
		print("FAIL: lockt delayed acquisition\n");
		exits("FAIL");
	}

	print("PASS\n");
	exits("PASS");
}
예제 #6
0
파일: sleep.c 프로젝트: aahud/harvey
int
printFirst(void *v, char *s)
{
	/* just not exit, please */
	if(strcmp(s, "alarm") == 0){
		if(verbose)
			fprint(2, "%d: noted: %s at %lld\n", getpid(), s, nsec());
		atnotify(printFirst, 0);
		return 1;
	}
	return 0;
}
예제 #7
0
파일: pppoe.c 프로젝트: aahud/harvey
void
main(int argc, char **argv)
{
	int fd;
	char *dev;

	ARGBEGIN{
	case 'A':
		wantac = EARGF(usage());
		break;
	case 'P':
		primary = 1;
		break;
	case 'S':
		srvname = EARGF(usage());
		break;
	case 'd':
		debug++;
		break;
	case 'm':
		mtu = atoi(EARGF(usage()));
		break;
	case 'k':
		keyspec = EARGF(usage());
		break;
	case 'x':
		pppnetmtpt = EARGF(usage());
		break;
	default:
		usage();
	}ARGEND

	switch(argc){
	default:
		usage();
	case 0:
		dev = "ether0";
		break;
	case 1:
		dev = argv[0];
		break;
	}

	fmtinstall('E', eipfmt);

	atnotify(catchalarm, 1);
	fd = pppoe(dev);
	execppp(fd);
}
예제 #8
0
파일: 9pserve.c 프로젝트: 00001/plan9port
void
mainproc(void *v)
{
	int n, nn;
	Fcall f;
	USED(v);

	atnotify(ignorepipe, 1);
	fmtinstall('D', dirfmt);
	fmtinstall('M', dirmodefmt);
	fmtinstall('F', fcallfmt);
	fmtinstall('H', encodefmt);

	outq = qalloc();
	inq = qalloc();

	if(!versioned){
		f.type = Tversion;
		f.version = "9P2000";
		f.msize = msize;
		f.tag = NOTAG;
		n = convS2M(&f, vbuf, sizeof vbuf);
		if(n <= BIT16SZ)
			sysfatal("convS2M conversion error");
		if(verbose > 1) fprint(2, "%T * <- %F\n", &f);
		nn = write(1, vbuf, n);
		if(n != nn)
			sysfatal("error writing Tversion: %r\n");
		n = read9pmsg(0, vbuf, sizeof vbuf);
		if(n < 0)
			sysfatal("read9pmsg failure");
		if(convM2S(vbuf, n, &f) != n)
			sysfatal("convM2S failure");
		if(f.msize < msize)
			msize = f.msize;
		if(verbose > 1) fprint(2, "%T * -> %F\n", &f);
	}

	threadcreate(inputthread, nil, STACK);
	threadcreate(outputthread, nil, STACK);

/*	if(rootfid) */
/*		dorootstat(); */
	
	threadcreate(listenthread, nil, STACK);
	threadexits(0);
}
예제 #9
0
파일: xmr.c 프로젝트: carriercomm/plan9-gpl
void
main(int argc, char **argv)
{
	int fd;
	uchar seqno;
	ulong bytes;

	ARGBEGIN {
	case 'd':
		dfd = 2;
		debug = 1;
		break;
	} ARGEND

	if(argc != 1){
		fprint(2, "usage: xmr filename\n");
		exits("usage");
	}
	fd = open("/dev/consctl", OWRITE);
	if(fd >= 0)
		write(fd, "rawon", 5);
	fd = create(argv[0], ORDWR, 0666);
	if(fd < 0){
		perror("xmr: create");
		exits("create");
	}

	atnotify(notifyf, 1);
	send(Nak);

	/*
	 *  keep receiving till the other side gives up
	 */
	bytes = 0;
	for(seqno = 1; ; seqno++){
		if(receive(fd, seqno) == -1)
			break;
		bytes += 128;
	}
	fprint(2, "xmr: received %ld bytes\n", bytes);
	exits(0);
}
예제 #10
0
파일: event.c 프로젝트: grobe0ba/plan9front
void
einit(ulong keys)
{
	int ctl, fd;
	char buf[256];

	parentpid = getpid();
	if(pipe(epipe) < 0)
		drawerror(display, "events: einit pipe");
	atexit(ekill);
	atnotify(enote, 1);
	snprint(buf, sizeof buf, "%s/mouse", display->devdir);
	mousefd = open(buf, ORDWR|OCEXEC);
	if(mousefd < 0)
		drawerror(display, "einit: can't open mouse\n");
	snprint(buf, sizeof buf, "%s/cursor", display->devdir);
	cursorfd = open(buf, ORDWR|OCEXEC);
	if(cursorfd < 0)
		drawerror(display, "einit: can't open cursor\n");
	if(keys&Ekeyboard){
		snprint(buf, sizeof buf, "%s/cons", display->devdir);
		fd = open(buf, OREAD);
		if(fd < 0)
			drawerror(display, "events: can't open console");
		snprint(buf, sizeof buf, "%s/consctl", display->devdir);
		ctl = open("/dev/consctl", OWRITE|OCEXEC);
		if(ctl < 0)
			drawerror(display, "events: can't open consctl");
		write(ctl, "rawon", 5);
		for(Skeyboard=0; Ekeyboard & ~(1<<Skeyboard); Skeyboard++)
			;
		ekeyslave(fd);
	}
	if(keys&Emouse){
		estart(Emouse, mousefd, 1+4*12);
		for(Smouse=0; Emouse & ~(1<<Smouse); Smouse++)
			;
	}
}
예제 #11
0
파일: smtp.c 프로젝트: grobe0ba/plan9front
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);
}
예제 #12
0
파일: plan9.c 프로젝트: Earnestly/plan9
void
catchnotes()
{
	atnotify(notifyf, 1);
}
예제 #13
0
파일: lpsend.c 프로젝트: 00001/plan9port
void
main(int argc, char *argv[])
{
	char *devdir;
	int i, rv, netfd, bsize;
	int datafd;

#ifndef plan9

	void (*oldhandler)();

#endif

	devdir = nil;
	/* make connection */
	if (argc != 2) {
		fprint(stderr, "usage: %s network!destination!service\n", argv[0]);
		exits("incorrect number of arguments");
	}

	/* read options line from stdin into lnbuf */
	i = readline(0);

	/* read stdin into tempfile to get size */
	datafd = tempfile();
	bsize = prereadfile(datafd);

	/* network connection is opened after data is in to avoid timeout */
	if ((netfd=dial(argv[1], 0, 0, 0)) < 0) {
		fprint(stderr, "dialing %s\n", devdir);
		perror("dial");
		exits("can't dial");
	}

	/* write out the options we read above */
	if (write(netfd, lnbuf, i) != i) {
		error(0, "write error while sending options\n");
		exits("write error while sending options");
	}

	/* send the size of the file to be sent */
	sprint(lnbuf, "%d\n", bsize);
	i = strlen(lnbuf);
	if ((rv=write(netfd, lnbuf, i)) != i) {
		perror("write error while sending size");
		error(0, "write returned %d\n", rv);
		exits("write error while sending size");
	}

	if (seek(datafd, 0L, 0) < 0) {
		error(0, "error seeking temp file\n");
		exits("seek error");
	}
	/* mirror performance in readfile() in lpdaemon */

#ifdef plan9

	atnotify(alarmhandler, 1);

#else

	oldhandler = signal(SIGALRM, alarmhandler);

#endif

	dbgstate = 1;
	if(!recvACK(netfd)) {
		error(0, "failed to receive ACK before sending data\n");
		exits("recv ack1 failed");
	}
	dbgstate = 2;
	if ((i=pass(datafd, netfd, bsize)) != 0) {
		NAK(netfd);
		error(0, "failed to send %d bytes\n", i);
		exits("send data failed");
	}
	ACK(netfd);
	dbgstate = 3;
	if(!recvACK(netfd)) {
		error(0, "failed to receive ACK after sending data\n");
		exits("recv ack2 failed");
	}

	/* get response, as from lp -q */
	dbgstate = 4;
	while((rv=read(netfd, jobbuf, RDSIZE)) > 0) {
		if((write(1, jobbuf, rv)) != rv) {
			error(0, "write error while sending to stdout\n");
			exits("write error while sending to stdout");
		}
	}
	dbgstate = 5;

#ifdef plan9

	atnotify(alarmhandler, 0);
	/* close down network connections and go away */
	exits("");

#else

	signal(SIGALRM, oldhandler);
	exit(0);

#endif

}
예제 #14
0
파일: smtpd.c 프로젝트: 99years/plan9
void
data(void)
{
	int status, nbytes;
	char *cp, *ep;
	char errx[ERRMAX];
	Link *l;
	String *cmd, *err;

	if(rejectcheck())
		return;
	if(senders.last == 0){
		reply("503 2.5.2 Data without MAIL FROM:\r\n");
		rejectcount++;
		return;
	}
	if(rcvers.last == 0){
		reply("503 2.5.2 Data without RCPT TO:\r\n");
		rejectcount++;
		return;
	}
	if(!trusted && sendermxcheck()){
		rerrstr(errx, sizeof errx);
		if(strncmp(errx, "rejected:", 9) == 0)
			reply("554 5.7.1 %s\r\n", errx);
		else
			reply("450 4.7.0 %s\r\n", errx);
		for(l=rcvers.first; l; l=l->next)
			syslog(0, "smtpd", "[%s/%s] %s -> %s sendercheck: %s",
				him, nci->rsys, s_to_c(senders.first->p),
				s_to_c(l->p), errx);
		rejectcount++;
		return;
	}

	cmd = startcmd();
	if(cmd == 0)
		return;

	reply("354 Input message; end with <CRLF>.<CRLF>\r\n");
	if(debug){
		seek(2, 0, 2);
		stamp();
		fprint(2, "# sent 354; accepting DATA %s\n", thedate());
	}


	/*
	 *  allow 145 more minutes to move the data
	 */
	alarm(145*60*1000);

	status = pipemsg(&nbytes);

	/*
	 *  read any error messages
	 */
	err = s_new();
	if (debug) {
		stamp();
		fprint(2, "waiting for upas/send to close stderr\n");
	}
	while(s_read_line(pp->std[2]->fp, err))
		;

	alarm(0);
	atnotify(catchalarm, 0);

	if (debug) {
		stamp();
		fprint(2, "waiting for upas/send to exit\n");
	}
	status |= proc_wait(pp);
	if(debug){
		seek(2, 0, 2);
		stamp();
		fprint(2, "# %d upas/send status %#ux at %s\n",
			getpid(), status, thedate());
		if(*s_to_c(err))
			fprint(2, "# %d error %s\n", getpid(), s_to_c(err));
	}

	/*
	 *  if process terminated abnormally, send back error message
	 */
	if(status){
		int code;
		char *ecode;

		if(strstr(s_to_c(err), "mail refused")){
			syslog(0, "smtpd", "++[%s/%s] %s %s refused: %s",
				him, nci->rsys, s_to_c(senders.first->p),
				s_to_c(cmd), firstline(s_to_c(err)));
			code = 554;
			ecode = "5.0.0";
		} else {
			syslog(0, "smtpd", "++[%s/%s] %s %s %s%s%sreturned %#q %s",
				him, nci->rsys,
				s_to_c(senders.first->p), s_to_c(cmd),
				piperror? "error during pipemsg: ": "",
				piperror? piperror: "",
				piperror? "; ": "",
				pp->waitmsg->msg, firstline(s_to_c(err)));
			code = 450;
			ecode = "4.0.0";
		}
		for(cp = s_to_c(err); ep = strchr(cp, '\n'); cp = ep){
			*ep++ = 0;
			reply("%d-%s %s\r\n", code, ecode, cp);
		}
		reply("%d %s mail process terminated abnormally\r\n",
			code, ecode);
	} else {
		/*
		 * if a message appeared on stderr, despite good status,
		 * log it.  this can happen if rewrite.in contains a bad
		 * r.e., for example.
		 */
		if(*s_to_c(err))
			syslog(0, "smtpd",
				"%s returned good status, but said: %s",
				s_to_c(mailer), s_to_c(err));

		if(filterstate == BLOCKED)
			reply("554 5.7.1 we believe this is spam.  "
				"we don't accept it.\r\n");
		else if(filterstate == DELAY)
			reply("450 4.3.0 There will be a delay in delivery "
				"of this message.\r\n");
		else {
			reply("250 2.5.0 sent\r\n");
			logcall(nbytes);
			if(debug){
				seek(2, 0, 2);
				stamp();
				fprint(2, "# %d sent 250 reply %s\n",
					getpid(), thedate());
			}
		}
	}
	proc_free(pp);
	pp = 0;
	s_free(cmd);
	s_free(err);

	listfree(&senders);
	listfree(&rcvers);
}
예제 #15
0
파일: smtpd.c 프로젝트: 99years/plan9
void
main(int argc, char **argv)
{
	char *netdir;
	char buf[1024];

	netdir = nil;
	quotefmtinstall();
	fmtinstall('I', eipfmt);
	starttime = time(0);
	ARGBEGIN{
	case 'a':
		authenticate = 1;
		break;
	case 'c':
		tlscert = EARGF(usage());
		break;
	case 'D':
		Dflag++;
		break;
	case 'd':
		debug++;
		break;
	case 'f':				/* disallow relaying */
		fflag = 1;
		break;
	case 'g':
		gflag = 1;
		break;
	case 'h':				/* default domain name */
		dom = EARGF(usage());
		break;
	case 'k':				/* prohibited ip address */
		addbadguy(EARGF(usage()));
		break;
	case 'm':				/* set mail command */
		mailer = mailerpath(EARGF(usage()));
		break;
	case 'n':				/* log peer ip address */
		netdir = EARGF(usage());
		break;
	case 'p':
		passwordinclear = 1;
		break;
	case 'r':
		rflag = 1;			/* verify sender's domain */
		break;
	case 's':				/* save blocked messages */
		sflag = 1;
		break;
	case 't':
		fprint(2, "%s: the -t option is no longer supported, see -c\n",
			argv0);
		tlscert = "/sys/lib/ssl/smtpd-cert.pem";
		break;
	default:
		usage();
	}ARGEND;

	nci = getnetconninfo(netdir, 0);
	if(nci == nil)
		sysfatal("can't get remote system's address: %r");
	parseip(rsysip, nci->rsys);

	if(mailer == nil)
		mailer = mailerpath("send");

	if(debug){
		snprint(buf, sizeof buf, "%s/smtpdb/%ld", UPASLOG, time(0));
		close(2);
		if (create(buf, OWRITE | OEXCL, 0662) >= 0) {
			seek(2, 0, 2);
			fprint(2, "%d smtpd %s\n", getpid(), thedate());
		} else
			debug = 0;
	}
	getconf();
	if (isbadguy())
		exits("banned");
	Binit(&bin, 0, OREAD);

	if (chdir(UPASLOG) < 0)
		syslog(0, "smtpd", "no %s: %r", UPASLOG);
	me = sysname_read();
	if(dom == 0 || dom[0] == 0)
		dom = domainname_read();
	if(dom == 0 || dom[0] == 0)
		dom = me;
	parseinit();
	sayhi();

	/* allow 45 minutes to parse the header */
	atnotify(catchalarm, 1);
	alarm(45*60*1000);
	zzparse();
	exits(0);
}
예제 #16
0
Packet *
rpc(char *dest, Secret *shared, Packet *req)
{
	uchar buf[4096], buf2[4096], *b, *e;
	Packet *resp;
	Attribute *a;
	int m, n, fd, try;

	/* marshal request */
	e = buf + sizeof buf;
	buf[0] = req->code;
	buf[1] = req->ID;
	memmove(buf+4, req->authenticator, 16);
	b = buf+20;
	for(a = &req->first; a; a = a->next){
		if(b + 2 + a->len > e)
			return nil;
		*b++ = a->type;
		*b++ = 2 + a->len;
		memmove(b, a->val, a->len);
		b += a->len;
	}
	n = b-buf;
	buf[2] = n>>8;
	buf[3] = n;

	/* send request, wait for reply */
	fd = dial(dest, 0, 0, 0);
	if(fd < 0){
		syslog(0, AUTHLOG, "%s: rpc can't get udp channel", dest);
		return nil;
	}
	atnotify(ding, 1);
	m = -1;
	for(try = 0; try < 2; try++){
		alarm(4000);
		m = write(fd, buf, n);
		if(m != n){
			syslog(0, AUTHLOG, "%s: rpc write err %d %d: %r", dest, m, n);
			m = -1;
			break;
		}
		m = read(fd, buf2, sizeof buf2);
		alarm(0);
		if(m < 0){
			syslog(0, AUTHLOG, "%s rpc read err %d: %r", dest, m);
			break; /* failure */
		}
		if(m == 0 || buf2[1] != buf[1]){  /* need matching ID */
			syslog(0, AUTHLOG, "%s unmatched reply %d", dest, m);
			continue;
		}
		if(authcmp(shared, buf2, m, buf+4) == 0)
			break;
		syslog(0, AUTHLOG, "%s bad rpc chksum", dest);
	}
	close(fd);
	if(m <= 0)
		return nil;

	/* unmarshal reply */
	b = buf2;
	e = buf2+m;
	resp = (Packet*)malloc(sizeof(*resp));
	if(resp == nil)
		return nil;
	resp->code = *b++;
	resp->ID = *b++;
	n = *b++;
	n = (n<<8) | *b++;
	if(m != n){
		syslog(0, AUTHLOG, "rpc got %d bytes, length said %d", m, n);
		if(m > n)
			e = buf2+n;
	}
	memmove(resp->authenticator, b, 16);
	b += 16;
	a = &resp->first;
	a->type = 0;
	while(1){
		if(b >= e){
			a->next = nil;
			break;			/* exit loop */
		}
		a->type = *b++;
		a->len = (*b++) - 2;
		if(b + a->len > e){ /* corrupt packet */
			a->next = nil;
			freePacket(resp);
			return nil;
		}
		memmove(a->val, b, a->len);
		b += a->len;
		if(b < e){  /* any more attributes? */
			a->next = (Attribute*)malloc(sizeof(*a));
			if(a->next == nil){
				free(req);
				return nil;
			}
			a = a->next;
		}
	}
	return resp;
}

int
setAttribute(Packet *p, uchar type, uchar *s, int n)
{
	Attribute *a;

	a = &p->first;
	if(a->type != 0){
		a = (Attribute*)malloc(sizeof(*a));
		if(a == nil)
			return -1;
		a->next = p->first.next;
		p->first.next = a;
	}
	a->type = type;
	a->len = n;
	if(a->len > 253 )  /* RFC2138, section 5 */
		a->len = 253;
	memmove(a->val, s, a->len);
	return 0;
}
예제 #17
0
파일: mxdial.c 프로젝트: Earnestly/plan9
/*
 *  take an address and return all the mx entries for it,
 *  most preferred first
 */
static int
callmx(DS *ds, char *dest, char *domain)
{
	int fd, i, nmx;
	char *ip;
	char addr[Maxstring];

	/* get a list of mx entries */
	nmx = mxlookup(ds, domain);
	if(nmx < 0){
		/* dns isn't working, don't just dial */
		return -1;
	}
	if(nmx == 0){
		if(debug)
			fprint(2, "mxlookup returns nothing\n");
		return dial(dest, 0, 0, 0);
	}

	/* refuse to honor loopback addresses given by dns.  catch \n too. */
	for(i = 0; i < nmx; i++) {
		ip = mx[i].ip;
		if(strchr(ip, '\n') != nil){
			if(debug)
				fprint(2, "mxlookup ip contains newline\n");
			werrstr("illegal: newline in mail server ip");
			return -1;
		}else if(isloopback(ip)){
			if(debug)
				fprint(2, "mxlookup returns loopback\n");
			werrstr("illegal: domain lists %s as mail server", ip);
			return -1;
		}
	}

	/* sort by preference */
	if(nmx > 1)
		qsort(mx, nmx, sizeof(Mx), compar);

	/* dial each one in turn by name, not ip */
	for(i = 0; i < nmx; i++){
		if (busted(mx[i].host)) {
			if (debug)
				fprint(2, "mxdial skipping busted mx %s\n",
					mx[i].host);
			continue;
		}
		snprint(addr, sizeof(addr), "%s/%s!%s!%s", ds->netdir, ds->proto,
			mx[i].host, ds->service);
		if(debug)
			fprint(2, "mxdial trying %s\n", addr);
		atnotify(timeout, 1);
		/* this was 10 seconds, but oclsc.org at least needs more. */
		alarm(60*1000);
		fd = dial(addr, 0, 0, 0);
		if (debug && fd < 0)
			fprint(2, "dial: %r\n");
		alarm(0);
		atnotify(timeout, 0);
		if(fd >= 0)
			return fd;
	}
	return -1;
}