more changes
This commit is contained in:
parent
d0d15c12d4
commit
5cc53af92d
11 changed files with 234 additions and 412 deletions
|
|
@ -18,6 +18,8 @@ enum
|
||||||
Elemlen= 28,
|
Elemlen= 28,
|
||||||
Errlen= 128,
|
Errlen= 128,
|
||||||
Pathlen= 256,
|
Pathlen= 256,
|
||||||
|
|
||||||
|
RetryCode = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <netdb.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include <auth.h>
|
#include <auth.h>
|
||||||
#include <ndb.h>
|
#include <ndb.h>
|
||||||
|
|
@ -407,6 +411,7 @@ sysdirreadall(int fd, Dir **d)
|
||||||
/*
|
/*
|
||||||
* read in the system name
|
* read in the system name
|
||||||
*/
|
*/
|
||||||
|
static char *unix_hostname_read(void);
|
||||||
extern char *
|
extern char *
|
||||||
sysname_read(void)
|
sysname_read(void)
|
||||||
{
|
{
|
||||||
|
|
@ -424,19 +429,26 @@ sysname_read(void)
|
||||||
extern char *
|
extern char *
|
||||||
alt_sysname_read(void)
|
alt_sysname_read(void)
|
||||||
{
|
{
|
||||||
|
char *cp;
|
||||||
static char name[128];
|
static char name[128];
|
||||||
int n, fd;
|
|
||||||
|
|
||||||
fd = open("/dev/sysname", OREAD);
|
cp = getenv("sysname");
|
||||||
if(fd < 0)
|
if(cp == 0 || *cp == 0)
|
||||||
|
cp = unix_hostname_read();
|
||||||
|
if(cp == 0 || *cp == 0)
|
||||||
return 0;
|
return 0;
|
||||||
n = read(fd, name, sizeof(name)-1);
|
strecpy(name, name+sizeof name, cp);
|
||||||
close(fd);
|
|
||||||
if(n <= 0)
|
|
||||||
return 0;
|
|
||||||
name[n] = 0;
|
|
||||||
return name;
|
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
|
* get all names
|
||||||
|
|
@ -445,57 +457,49 @@ extern char**
|
||||||
sysnames_read(void)
|
sysnames_read(void)
|
||||||
{
|
{
|
||||||
static char **namev;
|
static char **namev;
|
||||||
Ndbtuple *t, *nt;
|
struct hostent *h;
|
||||||
Ndb* db;
|
char **p, **a;
|
||||||
Ndbs s;
|
|
||||||
int n;
|
|
||||||
char *cp;
|
|
||||||
|
|
||||||
if(namev)
|
if(namev)
|
||||||
return namev;
|
return namev;
|
||||||
|
|
||||||
/* XXX */
|
h = gethostbyname(alt_sysname_read());
|
||||||
/* free(csgetvalue(0, "sys", alt_sysname_read(), "dom", &t)); jpc */
|
for(p=h->h_aliases; *p; p++)
|
||||||
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;
|
namev = malloc((2+p-h->h_aliases)*sizeof namev[0]);
|
||||||
for(nt = t; nt; nt = nt->entry)
|
if(namev == 0)
|
||||||
if(strcmp(nt->attr, "dom") == 0)
|
return 0;
|
||||||
n++;
|
|
||||||
|
|
||||||
namev = (char**)malloc(sizeof(char *)*(n+3));
|
a = namev;
|
||||||
|
*a++ = strdup(h->h_name);
|
||||||
if(namev){
|
for(p=h->h_aliases; *p; p++)
|
||||||
n = 0;
|
*a++ = strdup(*p);
|
||||||
namev[n++] = strdup(sysname_read());
|
*a = 0;
|
||||||
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);
|
|
||||||
|
|
||||||
return namev;
|
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 *
|
extern char *
|
||||||
domainname_read(void)
|
domainname_read(void)
|
||||||
{
|
{
|
||||||
char **namev;
|
char **namev, *p;
|
||||||
|
Ndbtuple *t;
|
||||||
|
|
||||||
for(namev = sysnames_read(); *namev; namev++)
|
for(namev = sysnames_read(); *namev; namev++){
|
||||||
if(strchr(*namev, '.'))
|
if(strchr(*namev, '.')){
|
||||||
return *namev;
|
for(p=*namev-1; p && *++p; p=strchr(p, '.')){
|
||||||
|
if((t = dnsquery(nil, p, "mx")) != nil){
|
||||||
|
ndbfree(t);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -607,37 +611,13 @@ sysisdir(char *file)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* 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
|
* kill a process
|
||||||
*/
|
*/
|
||||||
extern int
|
extern int
|
||||||
syskill(int pid)
|
syskill(int pid)
|
||||||
{
|
{
|
||||||
return stomp(pid, "note");
|
return postnote(PNPROC, pid, "kill");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -646,7 +626,7 @@ syskill(int pid)
|
||||||
extern int
|
extern int
|
||||||
syskillpg(int pid)
|
syskillpg(int pid)
|
||||||
{
|
{
|
||||||
return stomp(pid, "notepg");
|
return postnote(PNGROUP, pid, "kill");
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
|
|
@ -723,12 +703,24 @@ sysfiles(void)
|
||||||
extern String *
|
extern String *
|
||||||
mboxpath(char *path, char *user, String *to, int dot)
|
mboxpath(char *path, char *user, String *to, int dot)
|
||||||
{
|
{
|
||||||
upasconfig();
|
char *dir;
|
||||||
|
String *s;
|
||||||
|
|
||||||
if (dot || *path=='/' || strncmp(path, "./", 2) == 0
|
if (dot || *path=='/' || strncmp(path, "./", 2) == 0
|
||||||
|| strncmp(path, "../", 3) == 0) {
|
|| strncmp(path, "../", 3) == 0) {
|
||||||
to = s_append(to, path);
|
to = s_append(to, path);
|
||||||
} else {
|
} 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, MAILROOT);
|
||||||
to = s_append(to, "/box/");
|
to = s_append(to, "/box/");
|
||||||
to = s_append(to, user);
|
to = s_append(to, user);
|
||||||
|
|
@ -755,13 +747,6 @@ deadletter(String *to) /* pass in sender??? */
|
||||||
return mboxpath("dead.letter", cp, to, 0);
|
return mboxpath("dead.letter", cp, to, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
|
||||||
homedir(char *user)
|
|
||||||
{
|
|
||||||
USED(user);
|
|
||||||
return getenv("home");
|
|
||||||
}
|
|
||||||
|
|
||||||
String *
|
String *
|
||||||
readlock(String *file)
|
readlock(String *file)
|
||||||
{
|
{
|
||||||
|
|
@ -776,56 +761,48 @@ readlock(String *file)
|
||||||
String *
|
String *
|
||||||
username(String *from)
|
username(String *from)
|
||||||
{
|
{
|
||||||
int n;
|
String* s;
|
||||||
Biobuf *bp;
|
struct passwd* pw;
|
||||||
char *p, *q;
|
|
||||||
String *s;
|
|
||||||
|
|
||||||
bp = Bopen("/adm/keys.who", OREAD);
|
setpwent();
|
||||||
if(bp == 0)
|
while((pw = getpwent()) != nil){
|
||||||
bp = Bopen("/adm/netkeys.who", OREAD);
|
if(strcmp(s_to_c(from), pw->pw_name) == 0){
|
||||||
if(bp == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
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 = s_new();
|
||||||
s_append(s, "\"");
|
s_append(s, "\"");
|
||||||
s_append(s, p);
|
s_append(s, pw->pw_gecos);
|
||||||
s_append(s, "\"");
|
s_append(s, "\"");
|
||||||
break;
|
|
||||||
}
|
|
||||||
Bterm(bp);
|
|
||||||
return s;
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 *
|
char *
|
||||||
remoteaddr(int fd, char *dir)
|
remoteaddr(int fd, char *dir)
|
||||||
{
|
{
|
||||||
/* XXX should call netconninfo */
|
char *raddr;
|
||||||
return "";
|
NetConnInfo *nci;
|
||||||
|
|
||||||
|
if((nci = getnetconninfo(dir, fd)) == nil)
|
||||||
|
return nil;
|
||||||
|
raddr = strdup(nci->raddr);
|
||||||
|
freenetconninfo(nci);
|
||||||
|
return raddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a file and
|
// create a file and
|
||||||
|
|
|
||||||
|
|
@ -1104,7 +1104,7 @@ sendmail(Addr *to, Addr *cc, int *pid, char *rcvr)
|
||||||
exec(s_to_c(cmd), av);
|
exec(s_to_c(cmd), av);
|
||||||
exec("myupassend", av);
|
exec("myupassend", av);
|
||||||
exec(unsharp("#9/bin/upas/send"), av);
|
exec(unsharp("#9/bin/upas/send"), av);
|
||||||
fatal("execing: %r");
|
fatal("exec: %r");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if(rcvr != nil)
|
if(rcvr != nil)
|
||||||
|
|
|
||||||
|
|
@ -513,7 +513,7 @@ dofile(Dir *dp)
|
||||||
if(wm->msg[0]){
|
if(wm->msg[0]){
|
||||||
if(debug)
|
if(debug)
|
||||||
fprint(2, "[%d] wm->msg == %s\n", getpid(), wm->msg);
|
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 */
|
/* return the message and remove it */
|
||||||
if(returnmail(av, dp->name, wm->msg) != 0)
|
if(returnmail(av, dp->name, wm->msg) != 0)
|
||||||
logit("returnmail failed", dp->name, av);
|
logit("returnmail failed", dp->name, av);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
#include "send.h"
|
#include "send.h"
|
||||||
|
|
||||||
#include "../smtp/smtp.h"
|
#include "../smtp/smtp.h"
|
||||||
#include "../smtp/y.tab.h"
|
#include "../smtp/rfc822.tab.h"
|
||||||
|
|
||||||
/* global to this file */
|
/* global to this file */
|
||||||
static Reprog *rfprog;
|
static Reprog *rfprog;
|
||||||
|
|
|
||||||
|
|
@ -301,6 +301,7 @@ substitute(String *source, Resub *subexp, message *mp)
|
||||||
sp = getrcvar(sp+1, &s);
|
sp = getrcvar(sp+1, &s);
|
||||||
s_append(stp, s);
|
s_append(stp, s);
|
||||||
free(s);
|
free(s);
|
||||||
|
sp--; /* counter sp++ below */
|
||||||
} else
|
} else
|
||||||
s_putc(stp, *sp);
|
s_putc(stp, *sp);
|
||||||
sp++;
|
sp++;
|
||||||
|
|
|
||||||
|
|
@ -241,7 +241,6 @@ isrcptrecent(char *rcpt)
|
||||||
void
|
void
|
||||||
vfysenderhostok(void)
|
vfysenderhostok(void)
|
||||||
{
|
{
|
||||||
char *fqdn;
|
|
||||||
int recent = 0;
|
int recent = 0;
|
||||||
Link *l;
|
Link *l;
|
||||||
|
|
||||||
|
|
@ -258,7 +257,7 @@ vfysenderhostok(void)
|
||||||
|
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
seek(fd, 0, 2); /* paranoia */
|
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);
|
close(fd);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ Ndb *db;
|
||||||
extern int debug;
|
extern int debug;
|
||||||
|
|
||||||
static int mxlookup(DS*, char*);
|
static int mxlookup(DS*, char*);
|
||||||
static int mxlookup1(DS*, char*);
|
|
||||||
static int compar(const void*, const void*);
|
static int compar(const void*, const void*);
|
||||||
static int callmx(DS*, char*, char*);
|
static int callmx(DS*, char*, char*);
|
||||||
static void expand_meta(DS *ds);
|
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
|
* use dns to resolve the mx request
|
||||||
*
|
|
||||||
* this routine knows about the firewall and tries inside and outside
|
|
||||||
* dns's seperately.
|
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
mxlookup(DS *ds, char *domain)
|
mxlookup(DS *ds, char *domain)
|
||||||
{
|
{
|
||||||
int n;
|
int i, n, nmx;
|
||||||
|
Ndbtuple *t, *tmx, *tpref, *tip;
|
||||||
|
|
||||||
/* just in case we find no domain name */
|
|
||||||
strcpy(domain, ds->host);
|
|
||||||
|
|
||||||
if(ds->netdir){
|
|
||||||
n = mxlookup1(ds, domain);
|
|
||||||
} else {
|
|
||||||
ds->netdir = "/net";
|
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;
|
|
||||||
|
|
||||||
nmx = 0;
|
nmx = 0;
|
||||||
snprint(buf, sizeof(buf), "%s mx", ds->host);
|
if((t = dnsquery(nil, ds->host, "mx")) != nil){
|
||||||
if(debug)
|
for(tmx=t; (tmx=ndbfindattr(tmx->entry, nil, "mx")) != nil && nmx<Nmx; ){
|
||||||
fprint(2, "sending %s '%s'\n", dnsname, buf);
|
for(tpref=tmx->line; tpref != tmx; tpref=tmx->line){
|
||||||
n = write(fd, buf, strlen(buf));
|
if(strcmp(tpref->attr, "pref") == 0){
|
||||||
if(n < 0){
|
strncpy(mx[nmx].host, tmx->val, sizeof(mx[n].host)-1);
|
||||||
rerrstr(buf, sizeof buf);
|
mx[nmx].pref = atoi(tpref->val);
|
||||||
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;
|
|
||||||
}
|
|
||||||
} 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++;
|
nmx++;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if(debug)
|
}
|
||||||
fprint(2, "dns mx; got %d entries\n", nmx);
|
}
|
||||||
|
ndbfree(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -210,18 +154,14 @@ mxlookup1(DS *ds, char *domain)
|
||||||
* look up all ip addresses
|
* look up all ip addresses
|
||||||
*/
|
*/
|
||||||
for(i = 0; i < nmx; i++){
|
for(i = 0; i < nmx; i++){
|
||||||
seek(fd, 0, 0);
|
if((t = dnsquery(nil, mx[i].host, "ip")) == nil)
|
||||||
snprint(buf, sizeof buf, "%s ip", mx[i].host);
|
|
||||||
mx[i].ip[0] = 0;
|
|
||||||
if(write(fd, buf, strlen(buf)) < 0)
|
|
||||||
goto no;
|
goto no;
|
||||||
seek(fd, 0, 0);
|
if((tip = ndbfindattr(t, nil, "ip")) == nil){
|
||||||
if((n = read(fd, buf, sizeof buf-1)) < 0)
|
ndbfree(t);
|
||||||
goto no;
|
goto no;
|
||||||
buf[n] = 0;
|
}
|
||||||
if(getfields(buf, fields, 4, 1, " \t") < 3)
|
strncpy(mx[i].ip, tip->val, sizeof(mx[i].ip)-1);
|
||||||
goto no;
|
ndbfree(t);
|
||||||
strncpy(mx[i].ip, fields[2], sizeof(mx[i].ip)-1);
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
no:
|
no:
|
||||||
|
|
@ -274,74 +214,17 @@ dial_string_parse(char *str, DS *ds)
|
||||||
expand_meta(ds);
|
expand_meta(ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /* jpc */
|
|
||||||
static void
|
static void
|
||||||
expand_meta(DS *ds)
|
expand_meta(DS *ds)
|
||||||
{
|
{
|
||||||
char buf[128], cs[128], *net, *p;
|
static Ndb *db;
|
||||||
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;
|
|
||||||
Ndbs s;
|
Ndbs s;
|
||||||
char *sys, *smtpserver;
|
char *sys, *smtpserver;
|
||||||
|
|
||||||
|
/* can't ask cs, so query database directly. */
|
||||||
sys = sysname();
|
sys = sysname();
|
||||||
db = ndbopen(unsharp("#9/ndb/local"));
|
if(db == nil)
|
||||||
fprint(2,"%s",ds->host);
|
db = ndbopen(0);
|
||||||
smtpserver = ndbgetvalue(db, &s, "sys", sys, "smtp", nil);
|
smtpserver = ndbgetvalue(db, &s, "sys", sys, "smtp", nil);
|
||||||
snprint(ds->host,128,"%s",smtpserver);
|
snprint(ds->host, 128, "%s", smtpserver);
|
||||||
fprint(2," exanded to %s\n",ds->host);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,98 +1,25 @@
|
||||||
/* A Bison parser, made by GNU Bison 2.0. */
|
#define WORD 57346
|
||||||
|
#define DATE 57347
|
||||||
/* Skeleton parser for Yacc-like parsing with Bison,
|
#define RESENT_DATE 57348
|
||||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
#define RETURN_PATH 57349
|
||||||
|
#define FROM 57350
|
||||||
This program is free software; you can redistribute it and/or modify
|
#define SENDER 57351
|
||||||
it under the terms of the GNU General Public License as published by
|
#define REPLY_TO 57352
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
#define RESENT_FROM 57353
|
||||||
any later version.
|
#define RESENT_SENDER 57354
|
||||||
|
#define RESENT_REPLY_TO 57355
|
||||||
This program is distributed in the hope that it will be useful,
|
#define SUBJECT 57356
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
#define TO 57357
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
#define CC 57358
|
||||||
GNU General Public License for more details.
|
#define BCC 57359
|
||||||
|
#define RESENT_TO 57360
|
||||||
You should have received a copy of the GNU General Public License
|
#define RESENT_CC 57361
|
||||||
along with this program; if not, write to the Free Software
|
#define RESENT_BCC 57362
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
#define REMOTE 57363
|
||||||
Boston, MA 02111-1307, USA. */
|
#define PRECEDENCE 57364
|
||||||
|
#define MIMEVERSION 57365
|
||||||
/* As a special exception, when this file is copied by Bison into a
|
#define CONTENTTYPE 57366
|
||||||
Bison output file, you may use that output file without restriction.
|
#define MESSAGEID 57367
|
||||||
This special exception was added by the Free Software Foundation
|
#define RECEIVED 57368
|
||||||
in version 1.24 of Bison. */
|
#define MAILER 57369
|
||||||
|
#define BADTOKEN 57370
|
||||||
/* 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;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <libsec.h>
|
#include <libsec.h>
|
||||||
#include <auth.h>
|
#include <auth.h>
|
||||||
#include <ndb.h>
|
#include <ndb.h>
|
||||||
|
#include <thread.h>
|
||||||
|
|
||||||
static char* connect(char*);
|
static char* connect(char*);
|
||||||
static char* dotls(char*);
|
static char* dotls(char*);
|
||||||
|
|
@ -59,7 +60,7 @@ void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
fprint(2, "usage: smtp [-adips] [-uuser] [-hhost] [.domain] net!host[!service] sender rcpt-list\n");
|
fprint(2, "usage: smtp [-adips] [-uuser] [-hhost] [.domain] net!host[!service] sender rcpt-list\n");
|
||||||
exits(Giveup);
|
threadexitsall(Giveup);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
@ -70,17 +71,16 @@ timeout(void *x, char *msg)
|
||||||
if(strstr(msg, "alarm")){
|
if(strstr(msg, "alarm")){
|
||||||
fprint(2, "smtp timeout: connection to %s timed out\n", farend);
|
fprint(2, "smtp timeout: connection to %s timed out\n", farend);
|
||||||
if(quitting)
|
if(quitting)
|
||||||
exits(quitrv);
|
threadexitsall(quitrv);
|
||||||
exits(Retry);
|
threadexitsall(Retry);
|
||||||
}
|
}
|
||||||
if(strstr(msg, "closed pipe")){
|
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);
|
fprint(2, "smtp timeout: connection closed to %s\n", farend);
|
||||||
if(quitting){
|
if(quitting){
|
||||||
syslog(0, "smtp.fail", "closed pipe to %s", farend);
|
syslog(0, "smtp.fail", "closed pipe to %s", farend);
|
||||||
_exits(quitrv);
|
threadexitsall(quitrv);
|
||||||
}
|
}
|
||||||
_exits(Retry);
|
threadexitsall(Retry);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -96,6 +96,14 @@ removenewline(char *p)
|
||||||
p[n] = 0;
|
p[n] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
exitcode(char *s)
|
||||||
|
{
|
||||||
|
if(strstr(s, "Retry")) /* known to runq */
|
||||||
|
return RetryCode;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
threadmain(int argc, char **argv)
|
threadmain(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
|
@ -171,7 +179,7 @@ threadmain(int argc, char **argv)
|
||||||
if(*argv == 0)
|
if(*argv == 0)
|
||||||
usage();
|
usage();
|
||||||
addr = *argv++; argc--;
|
addr = *argv++; argc--;
|
||||||
// expand $smtp if necessary XXX
|
// expand $smtp if necessary
|
||||||
addr = expand_addr(addr);
|
addr = expand_addr(addr);
|
||||||
farend = addr;
|
farend = addr;
|
||||||
|
|
||||||
|
|
@ -199,12 +207,12 @@ threadmain(int argc, char **argv)
|
||||||
rv = data(from, &bfile);
|
rv = data(from, &bfile);
|
||||||
if(rv != 0)
|
if(rv != 0)
|
||||||
goto error;
|
goto error;
|
||||||
exits(0);
|
threadexitsall(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mxdial uses its own timeout handler */
|
/* mxdial uses its own timeout handler */
|
||||||
if((rv = connect(addr)) != 0)
|
if((rv = connect(addr)) != 0)
|
||||||
exits(rv);
|
threadexitsall(rv);
|
||||||
|
|
||||||
/* 10 minutes to get through the initial handshake */
|
/* 10 minutes to get through the initial handshake */
|
||||||
atnotify(timeout, 1);
|
atnotify(timeout, 1);
|
||||||
|
|
@ -238,7 +246,7 @@ threadmain(int argc, char **argv)
|
||||||
|
|
||||||
if(ping){
|
if(ping){
|
||||||
quit(0);
|
quit(0);
|
||||||
exits(0);
|
threadexitsall(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = data(from, &bfile);
|
rv = data(from, &bfile);
|
||||||
|
|
@ -246,7 +254,7 @@ threadmain(int argc, char **argv)
|
||||||
goto error;
|
goto error;
|
||||||
quit(0);
|
quit(0);
|
||||||
if(rcvrs == ok)
|
if(rcvrs == ok)
|
||||||
exits(0);
|
threadexitsall(0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* here when some but not all rcvrs failed
|
* 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]);
|
fprint(2, " mail to %s failed: %s", argv[i], errs[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exits(Giveup);
|
threadexitsall(Giveup);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* here when all rcvrs failed
|
* 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));
|
fprint(2, "%s connect to %s:\n%s\n", thedate(), addr, s_to_c(reply));
|
||||||
if(!filter)
|
if(!filter)
|
||||||
quit(rv);
|
quit(rv);
|
||||||
exits(rv);
|
threadexitsall(rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -319,6 +327,8 @@ dotls(char *me)
|
||||||
int fd;
|
int fd;
|
||||||
uchar hash[SHA1dlen];
|
uchar hash[SHA1dlen];
|
||||||
|
|
||||||
|
return Giveup;
|
||||||
|
|
||||||
c = mallocz(sizeof(*c), 1); /* Note: not freed on success */
|
c = mallocz(sizeof(*c), 1); /* Note: not freed on success */
|
||||||
if (c == nil)
|
if (c == nil)
|
||||||
return Giveup;
|
return Giveup;
|
||||||
|
|
@ -1097,27 +1107,44 @@ dBputc(int x)
|
||||||
return Bputc(&bout, x);
|
return Bputc(&bout, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX */
|
|
||||||
char*
|
char*
|
||||||
expand_addr(char* a)
|
expand_addr(char *addr)
|
||||||
{
|
{
|
||||||
|
static char buf[256];
|
||||||
|
char *p, *q, *name, *sys;
|
||||||
|
Ndbtuple *t;
|
||||||
Ndb *db;
|
Ndb *db;
|
||||||
Ndbs s;
|
|
||||||
char *sys, *ret, *proto, *host;
|
|
||||||
|
|
||||||
proto = strtok(a,"!");
|
p = strchr(addr, '!');
|
||||||
if ( strcmp(proto,"net") != 0 ) {
|
if(p){
|
||||||
fprint(2,"unknown proto %s\n",proto);
|
q = strchr(p+1, '!');
|
||||||
|
name = p+1;
|
||||||
|
}else{
|
||||||
|
name = addr;
|
||||||
|
q = nil;
|
||||||
}
|
}
|
||||||
host = strtok(0,"!");
|
|
||||||
if ( strcmp(host,"$smtp") == 0 ) {
|
if(name[0] != '$')
|
||||||
|
return addr;
|
||||||
|
name++;
|
||||||
|
if(q)
|
||||||
|
*q = 0;
|
||||||
|
|
||||||
sys = sysname();
|
sys = sysname();
|
||||||
db = ndbopen(unsharp("#9/ndb/local"));
|
db = ndbopen(0);
|
||||||
host = ndbgetvalue(db, &s, "sys", sys, "smtp", nil);
|
t = ndbipinfo(db, "sys", sys, &name, 1);
|
||||||
|
if(t == nil){
|
||||||
|
ndbclose(db);
|
||||||
|
if(q)
|
||||||
|
*q = '!';
|
||||||
|
return addr;
|
||||||
}
|
}
|
||||||
ret = malloc(strlen(proto)+strlen(host)+2);
|
|
||||||
sprint(ret,"%s!%s",proto,host);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
|
*(name-1) = 0;
|
||||||
|
if(q)
|
||||||
|
*q = '!';
|
||||||
|
else
|
||||||
|
q = "";
|
||||||
|
snprint(buf, sizeof buf, "%s%s%s", addr, t->val, q);
|
||||||
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include <mp.h>
|
#include <mp.h>
|
||||||
#include <libsec.h>
|
#include <libsec.h>
|
||||||
#include <auth.h>
|
#include <auth.h>
|
||||||
|
#include <thread.h>
|
||||||
#include "../smtp/rfc822.tab.h"
|
#include "../smtp/rfc822.tab.h"
|
||||||
|
|
||||||
#define DBGMX 1
|
#define DBGMX 1
|
||||||
|
|
@ -84,11 +85,11 @@ s_error(char *f, char *status)
|
||||||
else
|
else
|
||||||
reply("452 out of memory %s\r\n", errbuf);
|
reply("452 out of memory %s\r\n", errbuf);
|
||||||
syslog(0, "smtpd", "++Malloc failure %s [%s]", him, nci->rsys);
|
syslog(0, "smtpd", "++Malloc failure %s [%s]", him, nci->rsys);
|
||||||
exits(status);
|
threadexitsall(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
main(int argc, char **argv)
|
threadmain(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char *p, buf[1024];
|
char *p, buf[1024];
|
||||||
char *netdir;
|
char *netdir;
|
||||||
|
|
@ -137,6 +138,8 @@ main(int argc, char **argv)
|
||||||
passwordinclear = 1;
|
passwordinclear = 1;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
|
fprint(2, "tls is not available\n");
|
||||||
|
threadexitsall("no tls");
|
||||||
tlscert = ARGF();
|
tlscert = ARGF();
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
|
|
@ -145,7 +148,7 @@ main(int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprint(2, "usage: smtpd [-dfhrs] [-n net] [-c cert]\n");
|
fprint(2, "usage: smtpd [-dfhrs] [-n net] [-c cert]\n");
|
||||||
exits("usage");
|
threadexitsall("usage");
|
||||||
}ARGEND;
|
}ARGEND;
|
||||||
|
|
||||||
nci = getnetconninfo(netdir, 0);
|
nci = getnetconninfo(netdir, 0);
|
||||||
|
|
@ -179,7 +182,7 @@ main(int argc, char **argv)
|
||||||
atnotify(catchalarm, 1);
|
atnotify(catchalarm, 1);
|
||||||
alarm(45*60*1000);
|
alarm(45*60*1000);
|
||||||
zzparse();
|
zzparse();
|
||||||
exits(0);
|
threadexitsall(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -276,7 +279,7 @@ hello(String *himp, int extended)
|
||||||
syslog(0, "smtpd", "Hung up on %s; claimed to be %s",
|
syslog(0, "smtpd", "Hung up on %s; claimed to be %s",
|
||||||
nci->rsys, him);
|
nci->rsys, him);
|
||||||
reply("554 Liar!\r\n");
|
reply("554 Liar!\r\n");
|
||||||
exits("client pretended to be us");
|
threadexitsall("client pretended to be us");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -533,7 +536,7 @@ quit(void)
|
||||||
{
|
{
|
||||||
reply("221 Successful termination\r\n");
|
reply("221 Successful termination\r\n");
|
||||||
close(0);
|
close(0);
|
||||||
exits(0);
|
threadexitsall(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1063,6 +1066,7 @@ sendermxcheck(void)
|
||||||
char *who;
|
char *who;
|
||||||
int pid;
|
int pid;
|
||||||
Waitmsg *w;
|
Waitmsg *w;
|
||||||
|
static char *validate;
|
||||||
|
|
||||||
who = s_to_c(senders.first->p);
|
who = s_to_c(senders.first->p);
|
||||||
if(strcmp(who, "/dev/null") == 0){
|
if(strcmp(who, "/dev/null") == 0){
|
||||||
|
|
@ -1074,7 +1078,9 @@ sendermxcheck(void)
|
||||||
return 0;
|
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;
|
return 0;
|
||||||
|
|
||||||
senddom = strdup(who);
|
senddom = strdup(who);
|
||||||
|
|
@ -1095,9 +1101,9 @@ sendermxcheck(void)
|
||||||
* Could add an option with the remote IP address
|
* Could add an option with the remote IP address
|
||||||
* to allow validatesender to implement SPF eventually.
|
* to allow validatesender to implement SPF eventually.
|
||||||
*/
|
*/
|
||||||
execl("/mail/lib/validatesender", "validatesender",
|
execl(validate, "validatesender",
|
||||||
"-n", nci->root, senddom, user, nil);
|
"-n", nci->root, senddom, user, nil);
|
||||||
_exits("exec validatesender: %r");
|
threadexitsall("exec validatesender: %r");
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1265,7 +1271,7 @@ rejectcheck(void)
|
||||||
if(rejectcount > MAXREJECTS){
|
if(rejectcount > MAXREJECTS){
|
||||||
syslog(0, "smtpd", "Rejected (%s/%s)", him, nci->rsys);
|
syslog(0, "smtpd", "Rejected (%s/%s)", him, nci->rsys);
|
||||||
reply("554 too many errors. transaction failed.\r\n");
|
reply("554 too many errors. transaction failed.\r\n");
|
||||||
exits("errcount");
|
threadexitsall("errcount");
|
||||||
}
|
}
|
||||||
if(hardreject){
|
if(hardreject){
|
||||||
rejectcount++;
|
rejectcount++;
|
||||||
|
|
@ -1344,7 +1350,7 @@ starttls(void)
|
||||||
/* force the client to hang up */
|
/* force the client to hang up */
|
||||||
close(Bfildes(&bin)); /* probably fd 0 */
|
close(Bfildes(&bin)); /* probably fd 0 */
|
||||||
close(1);
|
close(1);
|
||||||
exits("tls failed");
|
threadexitsall("tls failed");
|
||||||
}
|
}
|
||||||
Bterm(&bin);
|
Bterm(&bin);
|
||||||
Binit(&bin, fd, OREAD);
|
Binit(&bin, fd, OREAD);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue