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"); }
/* * 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; }
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; }
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); } }
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"); }
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; }
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); }
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); }
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); }
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++) ; } }
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); }
void catchnotes() { atnotify(notifyf, 1); }
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 }
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); }
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); }
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; }
/* * 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; }