static void etherwriteproc(void *a) { Ether *e = a; Buf *bp; Channel *wc; threadsetname("etherwrite"); wc = e->wc; while(e->exiting == 0){ bp = recvp(wc); if(bp == nil || e->exiting != 0){ free(bp); break; } e->nout++; if(e->bwrite(e, bp) < 0) e->noerrs++; if(isloopback(e, bp) && e->exiting == 0) sendp(e->rc, bp); /* send to input queue */ else freebuf(e, bp); } deprint(2, "%s: writeproc exiting\n", argv0); closedev(e->dev); }
/* * 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; }