commit 5cc53af92d6bfae8b930d3c9154c8ed44e1feb09 from: rsc date: Sun Feb 12 19:40:23 2006 UTC more changes commit - d0d15c12d43d201cf916ebfff157b976c8f3b6a1 commit + 5cc53af92d6bfae8b930d3c9154c8ed44e1feb09 blob - acb155f522481ef45297362b77581924b3dabd51 blob + 2a6925d2b57e6fc1ba724b4387368f8572579102 --- src/cmd/upas/common/common.h +++ src/cmd/upas/common/common.h @@ -18,6 +18,8 @@ enum Elemlen= 28, Errlen= 128, Pathlen= 256, + + RetryCode = 2, }; /* blob - cf56c8693fb4e850f3dda1ffcbf78a5fea1f8fb1 blob + a1c29517632d90c7da52e549da612fd1870f88d4 --- src/cmd/upas/common/libsys.c +++ src/cmd/upas/common/libsys.c @@ -1,3 +1,7 @@ +#include +#include +#include +#include #include "common.h" #include #include @@ -407,6 +411,7 @@ sysdirreadall(int fd, Dir **d) /* * read in the system name */ +static char *unix_hostname_read(void); extern char * sysname_read(void) { @@ -424,20 +429,27 @@ sysname_read(void) extern char * alt_sysname_read(void) { + char *cp; static char name[128]; - int n, fd; - fd = open("/dev/sysname", OREAD); - if(fd < 0) - return 0; - n = read(fd, name, sizeof(name)-1); - close(fd); - if(n <= 0) - return 0; - name[n] = 0; + cp = getenv("sysname"); + if(cp == 0 || *cp == 0) + cp = unix_hostname_read(); + if(cp == 0 || *cp == 0) + return 0; + strecpy(name, name+sizeof name, cp); return name; } +static char * +unix_hostname_read(void) +{ + static char hostname[256]; + if(gethostname(hostname, sizeof hostname) < 0) + return nil; + return hostname; +} + /* * get all names */ @@ -445,57 +457,49 @@ extern char** sysnames_read(void) { static char **namev; - Ndbtuple *t, *nt; - Ndb* db; - Ndbs s; - int n; - char *cp; + struct hostent *h; + char **p, **a; if(namev) return namev; -/* XXX */ - /* free(csgetvalue(0, "sys", alt_sysname_read(), "dom", &t)); jpc */ - db = ndbopen(unsharp("#9/ndb/local")); - free(ndbgetvalue(db, &s, "sys", sysname(),"dom", &t)); - /* t = nil; /* jpc */ - /* fprint(2,"csgetvalue called: fixme"); /* jpc */ + h = gethostbyname(alt_sysname_read()); + for(p=h->h_aliases; *p; p++) + ; + + namev = malloc((2+p-h->h_aliases)*sizeof namev[0]); + if(namev == 0) + return 0; - n = 0; - for(nt = t; nt; nt = nt->entry) - if(strcmp(nt->attr, "dom") == 0) - n++; - - namev = (char**)malloc(sizeof(char *)*(n+3)); - - if(namev){ - n = 0; - namev[n++] = strdup(sysname_read()); - cp = alt_sysname_read(); - if(cp) - namev[n++] = strdup(cp); - for(nt = t; nt; nt = nt->entry) - if(strcmp(nt->attr, "dom") == 0) - namev[n++] = strdup(nt->val); - namev[n] = 0; - } - if(t) - ndbfree(t); + a = namev; + *a++ = strdup(h->h_name); + for(p=h->h_aliases; *p; p++) + *a++ = strdup(*p); + *a = 0; return namev; } /* - * read in the domain name + * read in the domain name. + * chop off beginning pieces until we find one with an mx record. */ extern char * domainname_read(void) { - char **namev; + char **namev, *p; + Ndbtuple *t; - for(namev = sysnames_read(); *namev; namev++) - if(strchr(*namev, '.')) - return *namev; + for(namev = sysnames_read(); *namev; namev++){ + if(strchr(*namev, '.')){ + for(p=*namev-1; p && *++p; p=strchr(p, '.')){ + if((t = dnsquery(nil, p, "mx")) != nil){ + ndbfree(t); + return p; + } + } + } + } return 0; } @@ -608,36 +612,12 @@ sysisdir(char *file) } /* - * kill a process or process group - */ - -static int -stomp(int pid, char *file) -{ - char name[64]; - int fd; - - snprint(name, sizeof(name), "/proc/%d/%s", pid, file); - fd = open(name, 1); - if(fd < 0) - return -1; - if(write(fd, "die: yankee pig dog\n", sizeof("die: yankee pig dog\n") - 1) <= 0){ - close(fd); - return -1; - } - close(fd); - return 0; - -} - -/* * kill a process */ extern int syskill(int pid) { - return stomp(pid, "note"); - + return postnote(PNPROC, pid, "kill"); } /* @@ -646,7 +626,7 @@ syskill(int pid) extern int syskillpg(int pid) { - return stomp(pid, "notepg"); + return postnote(PNGROUP, pid, "kill"); } extern int @@ -723,12 +703,24 @@ sysfiles(void) extern String * mboxpath(char *path, char *user, String *to, int dot) { - upasconfig(); - + char *dir; + String *s; + if (dot || *path=='/' || strncmp(path, "./", 2) == 0 || strncmp(path, "../", 3) == 0) { to = s_append(to, path); } else { + if ((dir = homedir(user)) != nil) { + s = s_copy(dir); + s_append(s, "/mail/"); + if(access(s_to_c(s), AEXIST) >= 0){ + to = s_append(to, s_to_c(s)); + s_free(s); + to = s_append(to, path); + return to; + } + s_free(s); + } to = s_append(to, MAILROOT); to = s_append(to, "/box/"); to = s_append(to, user); @@ -755,13 +747,6 @@ deadletter(String *to) /* pass in sender??? */ return mboxpath("dead.letter", cp, to, 0); } -char * -homedir(char *user) -{ - USED(user); - return getenv("home"); -} - String * readlock(String *file) { @@ -776,56 +761,48 @@ readlock(String *file) String * username(String *from) { - int n; - Biobuf *bp; - char *p, *q; - String *s; + String* s; + struct passwd* pw; - bp = Bopen("/adm/keys.who", OREAD); - if(bp == 0) - bp = Bopen("/adm/netkeys.who", OREAD); - if(bp == 0) - return 0; + setpwent(); + while((pw = getpwent()) != nil){ + if(strcmp(s_to_c(from), pw->pw_name) == 0){ + s = s_new(); + s_append(s, "\""); + s_append(s, pw->pw_gecos); + s_append(s, "\""); + return s; + } + } + return nil; +} - s = 0; - n = strlen(s_to_c(from)); - for(;;) { - p = Brdline(bp, '\n'); - if(p == 0) - break; - p[Blinelen(bp)-1] = 0; - if(strncmp(p, s_to_c(from), n)) - continue; - p += n; - if(*p != ' ' && *p != '\t') /* must be full match */ - continue; - while(*p && (*p == ' ' || *p == '\t')) - p++; - if(*p == 0) - continue; - for(q = p; *q; q++) - if(('0' <= *q && *q <= '9') || *q == '<') - break; - while(q > p && q[-1] != ' ' && q[-1] != '\t') - q--; - while(q > p && (q[-1] == ' ' || q[-1] == '\t')) - q--; - *q = 0; - s = s_new(); - s_append(s, "\""); - s_append(s, p); - s_append(s, "\""); - break; - } - Bterm(bp); - return s; +char * +homedir(char *user) +{ + static char buf[1024]; + struct passwd* pw; + + setpwent(); + while((pw = getpwent()) != nil) + if(strcmp(user, pw->pw_name) == 0){ + strecpy(buf, buf+sizeof buf, pw->pw_dir); + return buf; + } + return nil; } char * remoteaddr(int fd, char *dir) { - /* XXX should call netconninfo */ - return ""; + char *raddr; + NetConnInfo *nci; + + if((nci = getnetconninfo(dir, fd)) == nil) + return nil; + raddr = strdup(nci->raddr); + freenetconninfo(nci); + return raddr; } // create a file and blob - 0ed3a8a62f14de02c78a999b5e164a2ac4ca5757 blob + 2df5a98731fc02620edb8bde4ab0b096e644f65f --- src/cmd/upas/marshal/marshal.c +++ src/cmd/upas/marshal/marshal.c @@ -1104,7 +1104,7 @@ sendmail(Addr *to, Addr *cc, int *pid, char *rcvr) exec(s_to_c(cmd), av); exec("myupassend", av); exec(unsharp("#9/bin/upas/send"), av); - fatal("execing: %r"); + fatal("exec: %r"); break; default: if(rcvr != nil) blob - 7ab055ed84f83bb06937185fdf8419b817ffbbe1 blob + e7f35284b8ef2b7fb19c2e9c2d4cdd896f4fae1f --- src/cmd/upas/q/runq.c +++ src/cmd/upas/q/runq.c @@ -513,7 +513,7 @@ dofile(Dir *dp) if(wm->msg[0]){ if(debug) fprint(2, "[%d] wm->msg == %s\n", getpid(), wm->msg); - if(!Rflag && strstr(wm->msg, "Retry")==0){ + if(!Rflag && atoi(wm->msg) != RetryCode){ /* return the message and remove it */ if(returnmail(av, dp->name, wm->msg) != 0) logit("returnmail failed", dp->name, av); blob - 56fddba3a531d83108fc9c3a1df9246c1f4b0873 blob + afd93e3bee92debb91fbafa1a85da9b4727c1cea --- src/cmd/upas/send/message.c +++ src/cmd/upas/send/message.c @@ -2,7 +2,7 @@ #include "send.h" #include "../smtp/smtp.h" -#include "../smtp/y.tab.h" +#include "../smtp/rfc822.tab.h" /* global to this file */ static Reprog *rfprog; blob - 2feacbf21d6c0aa180fb16c59f26a8b37e6da002 blob + 3f30d4f3aa0d0e0eee788df78e07854e961905aa --- src/cmd/upas/send/rewrite.c +++ src/cmd/upas/send/rewrite.c @@ -301,6 +301,7 @@ substitute(String *source, Resub *subexp, message *mp) sp = getrcvar(sp+1, &s); s_append(stp, s); free(s); + sp--; /* counter sp++ below */ } else s_putc(stp, *sp); sp++; blob - a3a3f4d46f8f82c7ed3e7fbb185204abef6f1431 blob + 1efd145718db661f984f9fd6d5d254416983290a --- src/cmd/upas/smtp/greylist.c +++ src/cmd/upas/smtp/greylist.c @@ -241,7 +241,6 @@ isrcptrecent(char *rcpt) void vfysenderhostok(void) { - char *fqdn; int recent = 0; Link *l; @@ -258,7 +257,7 @@ vfysenderhostok(void) if (fd >= 0) { seek(fd, 0, 2); /* paranoia */ - fprint(fd, "# %s\n%s\n\n", fqdn, nci->rsys); + fprint(fd, "# unknown\n%s\n\n", nci->rsys); close(fd); } } else { blob - ae272c7d0fba50f54b7785184686eb890e06ae8d blob + 31c6e5ba6991f3774eff051373e2ac7ac3401624 --- src/cmd/upas/smtp/mxdial.c +++ src/cmd/upas/smtp/mxdial.c @@ -22,7 +22,6 @@ Ndb *db; extern int debug; static int mxlookup(DS*, char*); -static int mxlookup1(DS*, char*); static int compar(const void*, const void*); static int callmx(DS*, char*, char*); static void expand_meta(DS *ds); @@ -113,83 +112,28 @@ callmx(DS *ds, char *dest, char *domain) } /* - * call the dns process and have it try to resolve the mx request - * - * this routine knows about the firewall and tries inside and outside - * dns's seperately. + * use dns to resolve the mx request */ static int mxlookup(DS *ds, char *domain) { - int n; - - /* just in case we find no domain name */ - strcpy(domain, ds->host); - - if(ds->netdir){ - n = mxlookup1(ds, domain); - } else { - ds->netdir = "/net"; - n = mxlookup1(ds, domain); - if(n == 0) { - ds->netdir = "/net.alt"; - n = mxlookup1(ds, domain); - } - } - - return n; -} - -static int -mxlookup1(DS *ds, char *domain) -{ - char buf[1024]; - char dnsname[Maxstring]; - char *fields[4]; - int i, n, fd, nmx; - - snprint(dnsname, sizeof dnsname, "%s/dns", ds->netdir); - - fd = open(dnsname, ORDWR); - if(fd < 0) - return 0; - + int i, n, nmx; + Ndbtuple *t, *tmx, *tpref, *tip; + + ds->netdir = "/net"; nmx = 0; - snprint(buf, sizeof(buf), "%s mx", ds->host); - if(debug) - fprint(2, "sending %s '%s'\n", dnsname, buf); - n = write(fd, buf, strlen(buf)); - if(n < 0){ - rerrstr(buf, sizeof buf); - if(debug) - fprint(2, "dns: %s\n", buf); - if(strstr(buf, "dns failure")){ - /* if dns fails for the mx lookup, we have to stop */ - close(fd); - return -1; + if((t = dnsquery(nil, ds->host, "mx")) != nil){ + for(tmx=t; (tmx=ndbfindattr(tmx->entry, nil, "mx")) != nil && nmxline; tpref != tmx; tpref=tmx->line){ + if(strcmp(tpref->attr, "pref") == 0){ + strncpy(mx[nmx].host, tmx->val, sizeof(mx[n].host)-1); + mx[nmx].pref = atoi(tpref->val); + nmx++; + break; + } + } } - } else { - /* - * get any mx entries - */ - seek(fd, 0, 0); - while(nmx < Nmx && (n = read(fd, buf, sizeof(buf)-1)) > 0){ - buf[n] = 0; - if(debug) - fprint(2, "dns mx: %s\n", buf); - n = getfields(buf, fields, 4, 1, " \t"); - if(n < 4) - continue; - - if(strchr(domain, '.') == 0) - strcpy(domain, fields[0]); - - strncpy(mx[nmx].host, fields[3], sizeof(mx[n].host)-1); - mx[nmx].pref = atoi(fields[2]); - nmx++; - } - if(debug) - fprint(2, "dns mx; got %d entries\n", nmx); + ndbfree(t); } /* @@ -210,20 +154,16 @@ mxlookup1(DS *ds, char *domain) * look up all ip addresses */ for(i = 0; i < nmx; i++){ - seek(fd, 0, 0); - snprint(buf, sizeof buf, "%s ip", mx[i].host); - mx[i].ip[0] = 0; - if(write(fd, buf, strlen(buf)) < 0) + if((t = dnsquery(nil, mx[i].host, "ip")) == nil) goto no; - seek(fd, 0, 0); - if((n = read(fd, buf, sizeof buf-1)) < 0) + if((tip = ndbfindattr(t, nil, "ip")) == nil){ + ndbfree(t); goto no; - buf[n] = 0; - if(getfields(buf, fields, 4, 1, " \t") < 3) - goto no; - strncpy(mx[i].ip, fields[2], sizeof(mx[i].ip)-1); + } + strncpy(mx[i].ip, tip->val, sizeof(mx[i].ip)-1); + ndbfree(t); continue; - + no: /* remove mx[i] and go around again */ nmx--; @@ -274,74 +214,17 @@ dial_string_parse(char *str, DS *ds) expand_meta(ds); } -#if 0 /* jpc */ static void expand_meta(DS *ds) { - char buf[128], cs[128], *net, *p; - int fd, n; - - net = ds->netdir; - if(!net) - net = "/net"; - - if(debug) - fprint(2, "expanding %s!%s\n", net, ds->host); - snprint(cs, sizeof(cs), "%s/cs", net); - if((fd = open(cs, ORDWR)) == -1){ - if(debug) - fprint(2, "open %s: %r\n", cs); - syslog(0, "smtp", "cannot open %s: %r", cs); - return; - } - - snprint(buf, sizeof(buf), "!ipinfo %s", ds->host+1); // +1 to skip $ - if(write(fd, buf, strlen(buf)) <= 0){ - if(debug) - fprint(2, "write %s: %r\n", cs); - syslog(0, "smtp", "%s to %s - write failed: %r", buf, cs); - close(fd); - return; - } - - seek(fd, 0, 0); - if((n = read(fd, ds->expand, sizeof(ds->expand)-1)) < 0){ - if(debug) - fprint(2, "read %s: %r\n", cs); - syslog(0, "smtp", "%s - read failed: %r", cs); - close(fd); - return; - } - close(fd); - - ds->expand[n] = 0; - if((p = strchr(ds->expand, '=')) == nil){ - if(debug) - fprint(2, "response %s: %s\n", cs, ds->expand); - syslog(0, "smtp", "%q from %s - bad response: %r", ds->expand, cs); - return; - } - ds->host = p+1; - - /* take only first one returned (quasi-bug) */ - if((p = strchr(ds->host, ' ')) != nil) - *p = 0; -} -#endif /* jpc */ - -/* XXX */ -static void -expand_meta(DS *ds) -{ - Ndb *db; + static Ndb *db; Ndbs s; char *sys, *smtpserver; + /* can't ask cs, so query database directly. */ sys = sysname(); - db = ndbopen(unsharp("#9/ndb/local")); - fprint(2,"%s",ds->host); + if(db == nil) + db = ndbopen(0); smtpserver = ndbgetvalue(db, &s, "sys", sys, "smtp", nil); - snprint(ds->host,128,"%s",smtpserver); - fprint(2," exanded to %s\n",ds->host); - + snprint(ds->host, 128, "%s", smtpserver); } blob - cddbbc0fae671d8a9ff7a56ae8d6267461491a8a blob + a31a0e67b20868f78bf3afa07852d35e9a22ae77 --- src/cmd/upas/smtp/rfc822.tab.h +++ src/cmd/upas/smtp/rfc822.tab.h @@ -1,98 +1,25 @@ -/* A Bison parser, made by GNU Bison 2.0. */ - -/* Skeleton parser for Yacc-like parsing with Bison, - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - WORD = 258, - DATE = 259, - RESENT_DATE = 260, - RETURN_PATH = 261, - FROM = 262, - SENDER = 263, - REPLY_TO = 264, - RESENT_FROM = 265, - RESENT_SENDER = 266, - RESENT_REPLY_TO = 267, - SUBJECT = 268, - TO = 269, - CC = 270, - BCC = 271, - RESENT_TO = 272, - RESENT_CC = 273, - RESENT_BCC = 274, - REMOTE = 275, - PRECEDENCE = 276, - MIMEVERSION = 277, - CONTENTTYPE = 278, - MESSAGEID = 279, - RECEIVED = 280, - MAILER = 281, - BADTOKEN = 282 - }; -#endif -#define WORD 258 -#define DATE 259 -#define RESENT_DATE 260 -#define RETURN_PATH 261 -#define FROM 262 -#define SENDER 263 -#define REPLY_TO 264 -#define RESENT_FROM 265 -#define RESENT_SENDER 266 -#define RESENT_REPLY_TO 267 -#define SUBJECT 268 -#define TO 269 -#define CC 270 -#define BCC 271 -#define RESENT_TO 272 -#define RESENT_CC 273 -#define RESENT_BCC 274 -#define REMOTE 275 -#define PRECEDENCE 276 -#define MIMEVERSION 277 -#define CONTENTTYPE 278 -#define MESSAGEID 279 -#define RECEIVED 280 -#define MAILER 281 -#define BADTOKEN 282 - - - - -#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -typedef int YYSTYPE; -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - -extern YYSTYPE yylval; - - - +#define WORD 57346 +#define DATE 57347 +#define RESENT_DATE 57348 +#define RETURN_PATH 57349 +#define FROM 57350 +#define SENDER 57351 +#define REPLY_TO 57352 +#define RESENT_FROM 57353 +#define RESENT_SENDER 57354 +#define RESENT_REPLY_TO 57355 +#define SUBJECT 57356 +#define TO 57357 +#define CC 57358 +#define BCC 57359 +#define RESENT_TO 57360 +#define RESENT_CC 57361 +#define RESENT_BCC 57362 +#define REMOTE 57363 +#define PRECEDENCE 57364 +#define MIMEVERSION 57365 +#define CONTENTTYPE 57366 +#define MESSAGEID 57367 +#define RECEIVED 57368 +#define MAILER 57369 +#define BADTOKEN 57370 blob - fb00cd5f5f99014d5fb2acb596609c4c0eee9077 blob + 0661f4c6544368c9760152ed7590b4fd4c73a0d2 --- src/cmd/upas/smtp/smtp.c +++ src/cmd/upas/smtp/smtp.c @@ -5,6 +5,7 @@ #include #include #include +#include static char* connect(char*); static char* dotls(char*); @@ -59,7 +60,7 @@ void usage(void) { fprint(2, "usage: smtp [-adips] [-uuser] [-hhost] [.domain] net!host[!service] sender rcpt-list\n"); - exits(Giveup); + threadexitsall(Giveup); } int @@ -70,17 +71,16 @@ timeout(void *x, char *msg) if(strstr(msg, "alarm")){ fprint(2, "smtp timeout: connection to %s timed out\n", farend); if(quitting) - exits(quitrv); - exits(Retry); + threadexitsall(quitrv); + threadexitsall(Retry); } if(strstr(msg, "closed pipe")){ - /* call _exits() to prevent Bio from trying to flush closed pipe */ fprint(2, "smtp timeout: connection closed to %s\n", farend); if(quitting){ syslog(0, "smtp.fail", "closed pipe to %s", farend); - _exits(quitrv); + threadexitsall(quitrv); } - _exits(Retry); + threadexitsall(Retry); } return 0; } @@ -96,6 +96,14 @@ removenewline(char *p) p[n] = 0; } +int +exitcode(char *s) +{ + if(strstr(s, "Retry")) /* known to runq */ + return RetryCode; + return 1; +} + void threadmain(int argc, char **argv) { @@ -171,7 +179,7 @@ threadmain(int argc, char **argv) if(*argv == 0) usage(); addr = *argv++; argc--; - // expand $smtp if necessary XXX + // expand $smtp if necessary addr = expand_addr(addr); farend = addr; @@ -199,12 +207,12 @@ threadmain(int argc, char **argv) rv = data(from, &bfile); if(rv != 0) goto error; - exits(0); + threadexitsall(0); } /* mxdial uses its own timeout handler */ if((rv = connect(addr)) != 0) - exits(rv); + threadexitsall(rv); /* 10 minutes to get through the initial handshake */ atnotify(timeout, 1); @@ -238,7 +246,7 @@ threadmain(int argc, char **argv) if(ping){ quit(0); - exits(0); + threadexitsall(0); } rv = data(from, &bfile); @@ -246,7 +254,7 @@ threadmain(int argc, char **argv) goto error; quit(0); if(rcvrs == ok) - exits(0); + threadexitsall(0); /* * here when some but not all rcvrs failed @@ -258,7 +266,7 @@ threadmain(int argc, char **argv) fprint(2, " mail to %s failed: %s", argv[i], errs[i]); } } - exits(Giveup); + threadexitsall(Giveup); /* * here when all rcvrs failed @@ -271,7 +279,7 @@ error: fprint(2, "%s connect to %s:\n%s\n", thedate(), addr, s_to_c(reply)); if(!filter) quit(rv); - exits(rv); + threadexitsall(rv); } /* @@ -319,6 +327,8 @@ dotls(char *me) int fd; uchar hash[SHA1dlen]; + return Giveup; + c = mallocz(sizeof(*c), 1); /* Note: not freed on success */ if (c == nil) return Giveup; @@ -1097,27 +1107,44 @@ dBputc(int x) return Bputc(&bout, x); } -/* XXX */ char* -expand_addr(char* a) +expand_addr(char *addr) { + static char buf[256]; + char *p, *q, *name, *sys; + Ndbtuple *t; Ndb *db; - Ndbs s; - char *sys, *ret, *proto, *host; - - proto = strtok(a,"!"); - if ( strcmp(proto,"net") != 0 ) { - fprint(2,"unknown proto %s\n",proto); + + p = strchr(addr, '!'); + if(p){ + q = strchr(p+1, '!'); + name = p+1; + }else{ + name = addr; + q = nil; } - host = strtok(0,"!"); - if ( strcmp(host,"$smtp") == 0 ) { - sys = sysname(); - db = ndbopen(unsharp("#9/ndb/local")); - host = ndbgetvalue(db, &s, "sys", sys, "smtp", nil); - } - ret = malloc(strlen(proto)+strlen(host)+2); - sprint(ret,"%s!%s",proto,host); - return ret; - + if(name[0] != '$') + return addr; + name++; + if(q) + *q = 0; + + sys = sysname(); + db = ndbopen(0); + t = ndbipinfo(db, "sys", sys, &name, 1); + if(t == nil){ + ndbclose(db); + if(q) + *q = '!'; + return addr; + } + + *(name-1) = 0; + if(q) + *q = '!'; + else + q = ""; + snprint(buf, sizeof buf, "%s%s%s", addr, t->val, q); + return buf; } blob - 7b54b3cfff06ce499ce78254f2813bd3fe7ceede blob + e59dbddd2ae63c26d0e94675e086be081e8e3cbd --- src/cmd/upas/smtp/smtpd.c +++ src/cmd/upas/smtp/smtpd.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "../smtp/rfc822.tab.h" #define DBGMX 1 @@ -84,11 +85,11 @@ s_error(char *f, char *status) else reply("452 out of memory %s\r\n", errbuf); syslog(0, "smtpd", "++Malloc failure %s [%s]", him, nci->rsys); - exits(status); + threadexitsall(status); } void -main(int argc, char **argv) +threadmain(int argc, char **argv) { char *p, buf[1024]; char *netdir; @@ -137,6 +138,8 @@ main(int argc, char **argv) passwordinclear = 1; break; case 'c': + fprint(2, "tls is not available\n"); + threadexitsall("no tls"); tlscert = ARGF(); break; case 't': @@ -145,7 +148,7 @@ main(int argc, char **argv) break; default: fprint(2, "usage: smtpd [-dfhrs] [-n net] [-c cert]\n"); - exits("usage"); + threadexitsall("usage"); }ARGEND; nci = getnetconninfo(netdir, 0); @@ -179,7 +182,7 @@ main(int argc, char **argv) atnotify(catchalarm, 1); alarm(45*60*1000); zzparse(); - exits(0); + threadexitsall(0); } void @@ -276,7 +279,7 @@ hello(String *himp, int extended) syslog(0, "smtpd", "Hung up on %s; claimed to be %s", nci->rsys, him); reply("554 Liar!\r\n"); - exits("client pretended to be us"); + threadexitsall("client pretended to be us"); return; } } @@ -533,7 +536,7 @@ quit(void) { reply("221 Successful termination\r\n"); close(0); - exits(0); + threadexitsall(0); } void @@ -1063,6 +1066,7 @@ sendermxcheck(void) char *who; int pid; Waitmsg *w; + static char *validate; who = s_to_c(senders.first->p); if(strcmp(who, "/dev/null") == 0){ @@ -1074,7 +1078,9 @@ sendermxcheck(void) return 0; } - if(access("/mail/lib/validatesender", AEXEC) < 0) + if(validate == nil) + validate = unsharp("#9/mail/lib/validatesender"); + if(access(validate, AEXEC) < 0) return 0; senddom = strdup(who); @@ -1095,9 +1101,9 @@ sendermxcheck(void) * Could add an option with the remote IP address * to allow validatesender to implement SPF eventually. */ - execl("/mail/lib/validatesender", "validatesender", + execl(validate, "validatesender", "-n", nci->root, senddom, user, nil); - _exits("exec validatesender: %r"); + threadexitsall("exec validatesender: %r"); default: break; } @@ -1265,7 +1271,7 @@ rejectcheck(void) if(rejectcount > MAXREJECTS){ syslog(0, "smtpd", "Rejected (%s/%s)", him, nci->rsys); reply("554 too many errors. transaction failed.\r\n"); - exits("errcount"); + threadexitsall("errcount"); } if(hardreject){ rejectcount++; @@ -1344,7 +1350,7 @@ starttls(void) /* force the client to hang up */ close(Bfildes(&bin)); /* probably fd 0 */ close(1); - exits("tls failed"); + threadexitsall("tls failed"); } Bterm(&bin); Binit(&bin, fd, OREAD);