aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/upas
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2006-02-12 19:40:23 +0000
committerrsc <devnull@localhost>2006-02-12 19:40:23 +0000
commit5cc53af92d6bfae8b930d3c9154c8ed44e1feb09 (patch)
tree54d4829d507dba44e90e2f0ec2cf26cde280dd11 /src/cmd/upas
parentd0d15c12d43d201cf916ebfff157b976c8f3b6a1 (diff)
downloadplan9port-5cc53af92d6bfae8b930d3c9154c8ed44e1feb09.tar.gz
plan9port-5cc53af92d6bfae8b930d3c9154c8ed44e1feb09.tar.bz2
plan9port-5cc53af92d6bfae8b930d3c9154c8ed44e1feb09.zip
more changes
Diffstat (limited to 'src/cmd/upas')
-rw-r--r--src/cmd/upas/common/common.h2
-rw-r--r--src/cmd/upas/common/libsys.c221
-rw-r--r--src/cmd/upas/marshal/marshal.c2
-rw-r--r--src/cmd/upas/q/runq.c2
-rw-r--r--src/cmd/upas/send/message.c2
-rw-r--r--src/cmd/upas/send/rewrite.c1
-rw-r--r--src/cmd/upas/smtp/greylist.c3
-rw-r--r--src/cmd/upas/smtp/mxdial.c173
-rw-r--r--src/cmd/upas/smtp/rfc822.tab.h123
-rw-r--r--src/cmd/upas/smtp/smtp.c89
-rw-r--r--src/cmd/upas/smtp/smtpd.c28
11 files changed, 234 insertions, 412 deletions
diff --git a/src/cmd/upas/common/common.h b/src/cmd/upas/common/common.h
index acb155f5..2a6925d2 100644
--- a/src/cmd/upas/common/common.h
+++ b/src/cmd/upas/common/common.h
@@ -18,6 +18,8 @@ enum
Elemlen= 28,
Errlen= 128,
Pathlen= 256,
+
+ RetryCode = 2,
};
/*
diff --git a/src/cmd/upas/common/libsys.c b/src/cmd/upas/common/libsys.c
index cf56c869..a1c29517 100644
--- a/src/cmd/upas/common/libsys.c
+++ b/src/cmd/upas/common/libsys.c
@@ -1,3 +1,7 @@
+#include <u.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <netdb.h>
#include "common.h"
#include <auth.h>
#include <ndb.h>
@@ -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,19 +429,26 @@ 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)
+ cp = getenv("sysname");
+ if(cp == 0 || *cp == 0)
+ cp = unix_hostname_read();
+ if(cp == 0 || *cp == 0)
return 0;
- name[n] = 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 */
-
- n = 0;
- for(nt = t; nt; nt = nt->entry)
- if(strcmp(nt->attr, "dom") == 0)
- n++;
-
- namev = (char**)malloc(sizeof(char *)*(n+3));
+ 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;
- 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;
+
+ 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;
+}
- bp = Bopen("/adm/keys.who", OREAD);
- if(bp == 0)
- bp = Bopen("/adm/netkeys.who", OREAD);
- if(bp == 0)
- return 0;
+char *
+homedir(char *user)
+{
+ static char buf[1024];
+ struct passwd* pw;
- 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;
+ 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
diff --git a/src/cmd/upas/marshal/marshal.c b/src/cmd/upas/marshal/marshal.c
index 0ed3a8a6..2df5a987 100644
--- a/src/cmd/upas/marshal/marshal.c
+++ b/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)
diff --git a/src/cmd/upas/q/runq.c b/src/cmd/upas/q/runq.c
index 7ab055ed..e7f35284 100644
--- a/src/cmd/upas/q/runq.c
+++ b/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);
diff --git a/src/cmd/upas/send/message.c b/src/cmd/upas/send/message.c
index 56fddba3..afd93e3b 100644
--- a/src/cmd/upas/send/message.c
+++ b/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;
diff --git a/src/cmd/upas/send/rewrite.c b/src/cmd/upas/send/rewrite.c
index 2feacbf2..3f30d4f3 100644
--- a/src/cmd/upas/send/rewrite.c
+++ b/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++;
diff --git a/src/cmd/upas/smtp/greylist.c b/src/cmd/upas/smtp/greylist.c
index a3a3f4d4..1efd1457 100644
--- a/src/cmd/upas/smtp/greylist.c
+++ b/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 {
diff --git a/src/cmd/upas/smtp/mxdial.c b/src/cmd/upas/smtp/mxdial.c
index ae272c7d..31c6e5ba 100644
--- a/src/cmd/upas/smtp/mxdial.c
+++ b/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 && nmx<Nmx; ){
+ for(tpref=tmx->line; 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);
}
diff --git a/src/cmd/upas/smtp/rfc822.tab.h b/src/cmd/upas/smtp/rfc822.tab.h
index cddbbc0f..a31a0e67 100644
--- a/src/cmd/upas/smtp/rfc822.tab.h
+++ b/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
diff --git a/src/cmd/upas/smtp/smtp.c b/src/cmd/upas/smtp/smtp.c
index fb00cd5f..0661f4c6 100644
--- a/src/cmd/upas/smtp/smtp.c
+++ b/src/cmd/upas/smtp/smtp.c
@@ -5,6 +5,7 @@
#include <libsec.h>
#include <auth.h>
#include <ndb.h>
+#include <thread.h>
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;
}
diff --git a/src/cmd/upas/smtp/smtpd.c b/src/cmd/upas/smtp/smtpd.c
index 7b54b3cf..e59dbddd 100644
--- a/src/cmd/upas/smtp/smtpd.c
+++ b/src/cmd/upas/smtp/smtpd.c
@@ -7,6 +7,7 @@
#include <mp.h>
#include <libsec.h>
#include <auth.h>
+#include <thread.h>
#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);