summaryrefslogtreecommitdiffstats
path: root/usr.sbin/sendmail/src/daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/sendmail/src/daemon.c')
-rw-r--r--usr.sbin/sendmail/src/daemon.c538
1 files changed, 358 insertions, 180 deletions
diff --git a/usr.sbin/sendmail/src/daemon.c b/usr.sbin/sendmail/src/daemon.c
index b4b4e8b..c2f5327 100644
--- a/usr.sbin/sendmail/src/daemon.c
+++ b/usr.sbin/sendmail/src/daemon.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1983, 1995 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -37,20 +37,27 @@
#ifndef lint
#ifdef DAEMON
-static char sccsid[] = "@(#)daemon.c 8.48.1.5 (Berkeley) 3/28/95 (with daemon mode)";
+static char sccsid[] = "@(#)daemon.c 8.118 (Berkeley) 10/8/95 (with daemon mode)";
#else
-static char sccsid[] = "@(#)daemon.c 8.48.1.5 (Berkeley) 3/28/95 (without daemon mode)";
+static char sccsid[] = "@(#)daemon.c 8.118 (Berkeley) 10/8/95 (without daemon mode)";
#endif
#endif /* not lint */
#ifdef DAEMON
-# include <netdb.h>
# include <arpa/inet.h>
#if NAMED_BIND
-# include <arpa/nameser.h>
# include <resolv.h>
+# ifndef NO_DATA
+# define NO_DATA NO_ADDRESS
+# endif
+#endif
+
+#if IP_SRCROUTE
+# include <netinet/in_systm.h>
+# include <netinet/ip.h>
+# include <netinet/ip_var.h>
#endif
/*
@@ -106,13 +113,14 @@ int ListenQueueSize = 10; /* size of listen queue */
int TcpRcvBufferSize = 0; /* size of TCP receive buffer */
int TcpSndBufferSize = 0; /* size of TCP send buffer */
+void
getrequests()
{
int t;
bool refusingconnections = TRUE;
FILE *pidf;
int socksize;
-#ifdef XDEBUG
+#if XDEBUG
bool j_has_dot;
#endif
extern void reapchild();
@@ -167,11 +175,11 @@ getrequests()
fclose(pidf);
}
-#ifdef XDEBUG
+#if XDEBUG
{
char jbuf[MAXHOSTNAMELEN];
- expand("\201j", jbuf, &jbuf[sizeof jbuf - 1], CurEnv);
+ expand("\201j", jbuf, sizeof jbuf, CurEnv);
j_has_dot = strchr(jbuf, '.') != NULL;
}
#endif
@@ -184,6 +192,7 @@ getrequests()
register int pid;
auto int lotherend;
extern bool refuseconnections();
+ extern int getla();
/* see if we are rejecting connections */
CurrentLA = getla();
@@ -196,29 +205,24 @@ getrequests()
DaemonSocket = -1;
}
refusingconnections = TRUE;
- setproctitle("rejecting connections: load average: %d",
- CurrentLA);
sleep(15);
continue;
}
+ /* arrange to (re)open the socket if necessary */
if (refusingconnections)
{
- /* start listening again */
(void) opendaemonsocket(FALSE);
- setproctitle("accepting connections");
refusingconnections = FALSE;
}
-#ifdef XDEBUG
+#if XDEBUG
/* check for disaster */
{
- register STAB *s;
char jbuf[MAXHOSTNAMELEN];
- expand("\201j", jbuf, &jbuf[sizeof jbuf - 1], CurEnv);
- if ((s = stab(jbuf, ST_CLASS, ST_FIND)) == NULL ||
- !bitnset('w', s->s_class))
+ expand("\201j", jbuf, sizeof jbuf, CurEnv);
+ if (!wordinclass(jbuf, 'w'))
{
dumpstate("daemon lost $j");
syslog(LOG_ALERT, "daemon process doesn't have $j in $=w; see syslog");
@@ -234,6 +238,7 @@ getrequests()
#endif
/* wait for a connection */
+ setproctitle("accepting connections");
do
{
errno = 0;
@@ -244,6 +249,11 @@ getrequests()
if (t < 0)
{
syserr("getrequests: accept");
+
+ /* arrange to re-open the socket next time around */
+ (void) close(DaemonSocket);
+ DaemonSocket = -1;
+ refusingconnections = TRUE;
sleep(5);
continue;
}
@@ -268,6 +278,8 @@ getrequests()
{
char *p;
extern char *hostnamebyanyaddr();
+ extern void intsig();
+ FILE *inchannel, *outchannel;
/*
** CHILD -- return to caller.
@@ -276,34 +288,31 @@ getrequests()
*/
(void) setsignal(SIGCHLD, SIG_DFL);
- DisConnected = FALSE;
+ (void) setsignal(SIGHUP, intsig);
+ (void) close(DaemonSocket);
setproctitle("startup with %s",
anynet_ntoa(&RealHostAddr));
/* determine host name */
p = hostnamebyanyaddr(&RealHostAddr);
+ if (strlen(p) > MAXNAME)
+ p[MAXNAME] = '\0';
RealHostName = newstr(p);
setproctitle("startup with %s", p);
-#ifdef LOG
- if (LogLevel > 11)
- {
- /* log connection information */
- syslog(LOG_INFO, "connect from %s (%s)",
- RealHostName, anynet_ntoa(&RealHostAddr));
- }
-#endif
-
- (void) close(DaemonSocket);
- if ((InChannel = fdopen(t, "r")) == NULL ||
+ if ((inchannel = fdopen(t, "r")) == NULL ||
(t = dup(t)) < 0 ||
- (OutChannel = fdopen(t, "w")) == NULL)
+ (outchannel = fdopen(t, "w")) == NULL)
{
syserr("cannot open SMTP server channel, fd=%d", t);
exit(0);
}
+ InChannel = inchannel;
+ OutChannel = outchannel;
+ DisConnected = FALSE;
+
/* should we check for illegal connection here? XXX */
#ifdef XLA
if (!xla_host_ok(RealHostName))
@@ -318,6 +327,8 @@ getrequests()
return;
}
+ CurChildren++;
+
/* close the port so that others will hang (for a while) */
(void) close(t);
}
@@ -347,7 +358,7 @@ opendaemonsocket(firsttime)
bool firsttime;
{
int on = 1;
- int socksize;
+ int socksize = 0;
int ntries = 0;
int saveerrno;
@@ -363,7 +374,6 @@ opendaemonsocket(firsttime)
DaemonSocket = socket(DaemonAddr.sa.sa_family, SOCK_STREAM, 0);
if (DaemonSocket < 0)
{
- /* probably another daemon already */
saveerrno = errno;
syserr("opendaemonsocket: can't create server SMTP socket");
severe:
@@ -393,19 +403,19 @@ opendaemonsocket(firsttime)
SO_RCVBUF,
(char *) &TcpRcvBufferSize,
sizeof(TcpRcvBufferSize)) < 0)
- syserr("getrequests: setsockopt(SO_RCVBUF)");
+ syserr("opendaemonsocket: setsockopt(SO_RCVBUF)");
}
#endif
switch (DaemonAddr.sa.sa_family)
{
-# ifdef NETINET
+# if NETINET
case AF_INET:
socksize = sizeof DaemonAddr.sin;
break;
# endif
-# ifdef NETISO
+# if NETISO
case AF_ISO:
socksize = sizeof DaemonAddr.siso;
break;
@@ -418,8 +428,9 @@ opendaemonsocket(firsttime)
if (bind(DaemonSocket, &DaemonAddr.sa, socksize) < 0)
{
+ /* probably another daemon already */
saveerrno = errno;
- syserr("getrequests: cannot bind");
+ syserr("opendaemonsocket: cannot bind");
(void) close(DaemonSocket);
goto severe;
}
@@ -427,12 +438,13 @@ opendaemonsocket(firsttime)
if (!firsttime && listen(DaemonSocket, ListenQueueSize) < 0)
{
saveerrno = errno;
- syserr("getrequests: cannot listen");
+ syserr("opendaemonsocket: cannot listen");
(void) close(DaemonSocket);
goto severe;
}
return socksize;
} while (ntries++ < MAXOPENTRIES && transienterror(saveerrno));
+ syserr("!opendaemonsocket: server SMTP socket wedged: exiting");
finis();
}
/*
@@ -448,6 +460,7 @@ opendaemonsocket(firsttime)
** releases any resources used by the passive daemon.
*/
+void
clrdaemon()
{
if (DaemonSocket >= 0)
@@ -464,6 +477,7 @@ clrdaemon()
** none.
*/
+void
setdaemonoptions(p)
register char *p;
{
@@ -488,25 +502,27 @@ setdaemonoptions(p)
continue;
while (isascii(*++v) && isspace(*v))
continue;
+ if (isascii(*f) && islower(*f))
+ *f = toupper(*f);
switch (*f)
{
case 'F': /* address family */
if (isascii(*v) && isdigit(*v))
DaemonAddr.sa.sa_family = atoi(v);
-#ifdef NETINET
+#if NETINET
else if (strcasecmp(v, "inet") == 0)
DaemonAddr.sa.sa_family = AF_INET;
#endif
-#ifdef NETISO
+#if NETISO
else if (strcasecmp(v, "iso") == 0)
DaemonAddr.sa.sa_family = AF_ISO;
#endif
-#ifdef NETNS
+#if NETNS
else if (strcasecmp(v, "ns") == 0)
DaemonAddr.sa.sa_family = AF_NS;
#endif
-#ifdef NETX25
+#if NETX25
else if (strcasecmp(v, "x.25") == 0)
DaemonAddr.sa.sa_family = AF_CCITT;
#endif
@@ -517,10 +533,10 @@ setdaemonoptions(p)
case 'A': /* address */
switch (DaemonAddr.sa.sa_family)
{
-#ifdef NETINET
+#if NETINET
case AF_INET:
if (isascii(*v) && isdigit(*v))
- DaemonAddr.sin.sin_addr.s_addr = inet_network(v);
+ DaemonAddr.sin.sin_addr.s_addr = htonl(inet_network(v));
else
{
register struct netent *np;
@@ -546,7 +562,7 @@ setdaemonoptions(p)
{
short port;
-#ifdef NETINET
+#if NETINET
case AF_INET:
if (isascii(*v) && isdigit(*v))
DaemonAddr.sin.sin_port = htons(atoi(v));
@@ -563,7 +579,7 @@ setdaemonoptions(p)
break;
#endif
-#ifdef NETISO
+#if NETISO
case AF_ISO:
/* assume two byte transport selector */
if (isascii(*v) && isdigit(*v))
@@ -600,6 +616,9 @@ setdaemonoptions(p)
case 'R': /* receive buffer size */
TcpRcvBufferSize = atoi(v);
break;
+
+ default:
+ syserr("554 DaemonPortOptions parameter \"%s\" unknown", f);
}
}
}
@@ -622,6 +641,15 @@ setdaemonoptions(p)
** none.
*/
+static jmp_buf CtxConnectTimeout;
+
+static void
+connecttimeout()
+{
+ errno = ETIMEDOUT;
+ longjmp(CtxConnectTimeout, 1);
+}
+
SOCKADDR CurHostAddr; /* address of current host */
int
@@ -631,14 +659,14 @@ makeconnection(host, port, mci, usesecureport)
register MCI *mci;
bool usesecureport;
{
- register int i, s;
+ register int i = 0;
+ register int s;
register struct hostent *hp = (struct hostent *)NULL;
SOCKADDR addr;
int sav_errno;
int addrlen;
-#if NAMED_BIND
- extern int h_errno;
-#endif
+ bool firstconnect;
+ EVENT *ev;
/*
** Set up the address for the mailer.
@@ -661,18 +689,26 @@ makeconnection(host, port, mci, usesecureport)
if (p != NULL)
{
*p = '\0';
-#ifdef NETINET
+#if NETINET
hid = inet_addr(&host[1]);
if (hid == -1)
#endif
{
/* try it as a host name (avoid MX lookup) */
- hp = gethostbyname(&host[1]);
+ hp = sm_gethostbyname(&host[1]);
if (hp == NULL && p[-1] == '.')
{
+#if NAMED_BIND
+ int oldopts = _res.options;
+
+ _res.options &= ~(RES_DEFNAMES|RES_DNSRCH);
+#endif
p[-1] = '\0';
- hp = gethostbyname(&host[1]);
+ hp = sm_gethostbyname(&host[1]);
p[-1] = '.';
+#if NAMED_BIND
+ _res.options = oldopts;
+#endif
}
*p = ']';
goto gothostent;
@@ -682,9 +718,10 @@ makeconnection(host, port, mci, usesecureport)
if (p == NULL)
{
usrerr("553 Invalid numeric domain spec \"%s\"", host);
+ mci->mci_status = "5.1.2";
return (EX_NOHOST);
}
-#ifdef NETINET
+#if NETINET
addr.sin.sin_family = AF_INET; /*XXX*/
addr.sin.sin_addr.s_addr = hid;
#endif
@@ -693,34 +730,43 @@ makeconnection(host, port, mci, usesecureport)
{
register char *p = &host[strlen(host) - 1];
- hp = gethostbyname(host);
+ hp = sm_gethostbyname(host);
if (hp == NULL && *p == '.')
{
+#if NAMED_BIND
+ int oldopts = _res.options;
+
+ _res.options &= ~(RES_DEFNAMES|RES_DNSRCH);
+#endif
*p = '\0';
- hp = gethostbyname(host);
+ hp = sm_gethostbyname(host);
*p = '.';
+#if NAMED_BIND
+ _res.options = oldopts;
+#endif
}
gothostent:
if (hp == NULL)
{
#if NAMED_BIND
- if (errno == ETIMEDOUT || h_errno == TRY_AGAIN)
- return (EX_TEMPFAIL);
-
- /* if name server is specified, assume temp fail */
- if (errno == ECONNREFUSED && UseNameServer)
+ /* check for name server timeouts */
+ if (errno == ETIMEDOUT || h_errno == TRY_AGAIN ||
+ (errno == ECONNREFUSED && UseNameServer))
+ {
+ mci->mci_status = "4.4.3";
return (EX_TEMPFAIL);
+ }
#endif
return (EX_NOHOST);
}
addr.sa.sa_family = hp->h_addrtype;
switch (hp->h_addrtype)
{
-#ifdef NETINET
+#if NETINET
case AF_INET:
bcopy(hp->h_addr,
&addr.sin.sin_addr,
- sizeof addr.sin.sin_addr);
+ INADDRSZ);
break;
#endif
@@ -737,15 +783,16 @@ gothostent:
** Determine the port number.
*/
- if (port != 0)
- port = htons(port);
- else
+ if (port == 0)
{
register struct servent *sp = getservbyname("smtp", "tcp");
if (sp == NULL)
{
- syserr("554 makeconnection: service \"smtp\" unknown");
+#ifdef LOG
+ if (LogLevel > 2)
+ syslog(LOG_ERR, "makeconnection: service \"smtp\" unknown");
+#endif
port = htons(25);
}
else
@@ -754,14 +801,14 @@ gothostent:
switch (addr.sa.sa_family)
{
-#ifdef NETINET
+#if NETINET
case AF_INET:
addr.sin.sin_port = port;
addrlen = sizeof (struct sockaddr_in);
break;
#endif
-#ifdef NETISO
+#if NETISO
case AF_ISO:
/* assume two byte transport selector */
bcopy((char *) &port, TSEL((struct sockaddr_iso *) &addr), 2);
@@ -784,6 +831,7 @@ gothostent:
return EX_TEMPFAIL;
#endif
+ firstconnect = TRUE;
for (;;)
{
if (tTd(16, 1))
@@ -806,7 +854,7 @@ gothostent:
if (s < 0)
{
sav_errno = errno;
- syserr("makeconnection: no socket");
+ syserr("makeconnection: cannot create socket");
goto failure;
}
@@ -833,24 +881,54 @@ gothostent:
if (CurEnv->e_xfp != NULL)
(void) fflush(CurEnv->e_xfp); /* for debugging */
errno = 0; /* for debugging */
- if (connect(s, (struct sockaddr *) &addr, addrlen) >= 0)
- break;
- /* couldn't connect.... figure out why */
+ /*
+ ** Linux seems to hang in connect for 90 minutes (!!!).
+ ** Time out the connect to avoid this problem.
+ */
+
+ if (setjmp(CtxConnectTimeout) == 0)
+ {
+ if (TimeOuts.to_connect == 0)
+ ev = NULL;
+ else
+ ev = setevent(TimeOuts.to_connect, connecttimeout, 0);
+ if (connect(s, (struct sockaddr *) &addr, addrlen) >= 0)
+ {
+ if (ev != NULL)
+ clrevent(ev);
+ break;
+ }
+ }
sav_errno = errno;
+ if (ev != NULL)
+ clrevent(ev);
+
+ /* if running demand-dialed connection, try again */
+ if (DialDelay > 0 && firstconnect)
+ {
+ if (tTd(16, 1))
+ printf("Connect failed (%s); trying again...\n",
+ errstring(sav_errno));
+ firstconnect = FALSE;
+ sleep(DialDelay);
+ continue;
+ }
+
+ /* couldn't connect.... figure out why */
(void) close(s);
- if (hp && hp->h_addr_list[i])
+ if (hp != NULL && hp->h_addr_list[i])
{
if (tTd(16, 1))
printf("Connect failed (%s); trying new address....\n",
errstring(sav_errno));
switch (addr.sa.sa_family)
{
-#ifdef NETINET
+#if NETINET
case AF_INET:
bcopy(hp->h_addr_list[i++],
&addr.sin.sin_addr,
- sizeof addr.sin.sin_addr);
+ INADDRSZ);
break;
#endif
@@ -902,61 +980,77 @@ gothostent:
** Adds numeric codes to $=w.
*/
-char **
+struct hostent *
myhostname(hostbuf, size)
char hostbuf[];
int size;
{
register struct hostent *hp;
- extern struct hostent *gethostbyname();
+ extern bool getcanonname();
if (gethostname(hostbuf, size) < 0)
{
(void) strcpy(hostbuf, "localhost");
}
- hp = gethostbyname(hostbuf);
+ hp = sm_gethostbyname(hostbuf);
if (hp == NULL)
+ return NULL;
+ if (strchr(hp->h_name, '.') != NULL || strchr(hostbuf, '.') == NULL)
{
- syserr("!My host name (%s) does not seem to exist!", hostbuf);
+ (void) strncpy(hostbuf, hp->h_name, size - 1);
+ hostbuf[size - 1] = '\0';
}
- (void) strncpy(hostbuf, hp->h_name, size - 1);
- hostbuf[size - 1] = '\0';
-#if NAMED_BIND
- /* if still no dot, try DNS directly (i.e., avoid NIS problems) */
+ /*
+ ** If there is still no dot in the name, try looking for a
+ ** dotted alias.
+ */
+
if (strchr(hostbuf, '.') == NULL)
{
- extern bool getcanonname();
- extern int h_errno;
+ char **ha;
- /* try twice in case name server not yet started up */
- if (!getcanonname(hostbuf, size, TRUE) &&
- UseNameServer &&
- (h_errno != TRY_AGAIN ||
- (sleep(30), !getcanonname(hostbuf, size, TRUE))))
+ for (ha = hp->h_aliases; *ha != NULL; ha++)
{
- errno = h_errno + E_DNSBASE;
- syserr("!My host name (%s) not known to DNS",
- hostbuf);
+ if (strchr(*ha, '.') != NULL)
+ {
+ (void) strncpy(hostbuf, *ha, size - 1);
+ hostbuf[size - 1] = '\0';
+ break;
+ }
}
}
-#endif
- if (hp->h_addrtype == AF_INET && hp->h_length == 4)
- {
- register int i;
+ /*
+ ** If _still_ no dot, wait for a while and try again -- it is
+ ** possible that some service is starting up. This can result
+ ** in excessive delays if the system is badly configured, but
+ ** there really isn't a way around that, particularly given that
+ ** the config file hasn't been read at this point.
+ ** All in all, a bit of a mess.
+ */
- for (i = 0; hp->h_addr_list[i] != NULL; i++)
+ if (strchr(hostbuf, '.') == NULL &&
+ !getcanonname(hostbuf, size, TRUE))
+ {
+#ifdef LOG
+ syslog(LOG_CRIT, "My unqualifed host name (%s) unknown; sleeping for retry",
+ hostbuf);
+#endif
+ message("My unqualifed host name (%s) unknown; sleeping for retry",
+ hostbuf);
+ sleep(60);
+ if (!getcanonname(hostbuf, size, TRUE))
{
- char ipbuf[100];
-
- sprintf(ipbuf, "[%s]",
- inet_ntoa(*((struct in_addr *) hp->h_addr_list[i])));
- setclass('w', ipbuf);
+#ifdef LOG
+ syslog(LOG_ALERT, "unable to qualify my own domain name (%s) -- using short name",
+ hostbuf);
+#endif
+ message("WARNING: unable to qualify my own domain name (%s) -- using short name",
+ hostbuf);
}
}
-
- return (hp->h_aliases);
+ return (hp);
}
/*
** GETAUTHINFO -- get the real host name asociated with a file descriptor
@@ -970,41 +1064,34 @@ myhostname(hostbuf, size)
** The user@host information associated with this descriptor.
*/
-#if IDENTPROTO
-
static jmp_buf CtxAuthTimeout;
-static
+static void
authtimeout()
{
longjmp(CtxAuthTimeout, 1);
}
-#endif
-
char *
getauthinfo(fd)
int fd;
{
int falen;
register char *p;
-#if IDENTPROTO
SOCKADDR la;
int lalen;
register struct servent *sp;
- int s;
+ volatile int s;
int i;
EVENT *ev;
int nleft;
char ibuf[MAXNAME + 1];
-#endif
static char hbuf[MAXNAME * 2 + 2];
extern char *hostnamebyanyaddr();
- extern char RealUserName[]; /* main.c */
falen = sizeof RealHostAddr;
- if (getpeername(fd, &RealHostAddr.sa, &falen) < 0 || falen <= 0 ||
- RealHostAddr.sa.sa_family == 0)
+ if (isatty(fd) || getpeername(fd, &RealHostAddr.sa, &falen) < 0 ||
+ falen <= 0 || RealHostAddr.sa.sa_family == 0)
{
(void) sprintf(hbuf, "%s@localhost", RealUserName);
if (tTd(9, 1))
@@ -1018,7 +1105,6 @@ getauthinfo(fd)
RealHostName = newstr(hostnamebyanyaddr(&RealHostAddr));
}
-#if IDENTPROTO
if (TimeOuts.to_ident == 0)
goto noident;
@@ -1120,6 +1206,14 @@ getauthinfo(fd)
}
/* p now points to the OSTYPE field */
+ while (isascii(*p) && isspace(*p))
+ p++;
+ if (strncasecmp(p, "other", 5) == 0 &&
+ (p[5] == ':' || p[5] == ' ' || p[5] == ',' || p[5] == '\0'))
+ {
+ /* not useful information */
+ goto noident;
+ }
p = strchr(p, ':');
if (p == NULL)
{
@@ -1136,14 +1230,12 @@ getauthinfo(fd)
i = strlen(hbuf);
hbuf[i++] = '@';
strcpy(&hbuf[i], RealHostName == NULL ? "localhost" : RealHostName);
- goto finish;
+ goto postident;
closeident:
(void) close(s);
clrevent(ev);
-#endif /* IDENTPROTO */
-
noident:
if (RealHostName == NULL)
{
@@ -1153,12 +1245,92 @@ noident:
}
(void) strcpy(hbuf, RealHostName);
-finish:
+postident:
+#if IP_SRCROUTE
+ /*
+ ** Extract IP source routing information.
+ **
+ ** Format of output for a connection from site a through b
+ ** through c to d:
+ ** loose: @site-c@site-b:site-a
+ ** strict: !@site-c@site-b:site-a
+ **
+ ** o - pointer within ipopt_list structure.
+ ** q - pointer within ls/ss rr route data
+ ** p - pointer to hbuf
+ */
+
+ if (RealHostAddr.sa.sa_family == AF_INET)
+ {
+ int ipoptlen, j;
+ u_char *q;
+ u_char *o;
+ struct in_addr addr;
+ struct ipoption ipopt;
+
+ ipoptlen = sizeof ipopt;
+ if (getsockopt(fd, IPPROTO_IP, IP_OPTIONS,
+ (char *) &ipopt, &ipoptlen) < 0)
+ goto noipsr;
+ if (ipoptlen == 0)
+ goto noipsr;
+ o = (u_char *) ipopt.ipopt_list;
+ while (o != NULL && o < (u_char *) &ipopt + ipoptlen)
+ {
+ switch (*o)
+ {
+ case IPOPT_EOL:
+ o = NULL;
+ break;
+
+ case IPOPT_NOP:
+ o++;
+ break;
+
+ case IPOPT_SSRR:
+ case IPOPT_LSRR:
+ p = &hbuf[strlen(hbuf)];
+ sprintf(p, " [%s@%.120s",
+ *o == IPOPT_SSRR ? "!" : "",
+ inet_ntoa(ipopt.ipopt_dst));
+ p += strlen(p);
+
+ /* o[1] is option length */
+ j = *++o / sizeof(struct in_addr) - 1;
+
+ /* q skips length and router pointer to data */
+ q = o + 2;
+ for ( ; j >= 0; j--)
+ {
+ memcpy(&addr, q, sizeof(addr));
+ sprintf(p, "%c%.120s",
+ j ? '@' : ':',
+ inet_ntoa(addr));
+ p += strlen(p);
+ q += sizeof(struct in_addr);
+ }
+ o += *o;
+ break;
+
+ default:
+ /* Skip over option */
+ o += o[1];
+ break;
+ }
+ }
+ strcat(hbuf,"]");
+ goto postipsr;
+ }
+#endif
+
+noipsr:
if (RealHostName != NULL && RealHostName[0] != '[')
{
p = &hbuf[strlen(hbuf)];
- (void) sprintf(p, " [%s]", anynet_ntoa(&RealHostAddr));
+ (void) sprintf(p, " [%.100s]", anynet_ntoa(&RealHostAddr));
}
+
+postipsr:
if (tTd(9, 1))
printf("getauthinfo: %s\n", hbuf);
return hbuf;
@@ -1192,15 +1364,10 @@ host_map_lookup(map, name, av, statp)
int *statp;
{
register struct hostent *hp;
- u_long in_addr;
+ struct in_addr in_addr;
char *cp;
- int i;
register STAB *s;
- char hbuf[MAXNAME];
- extern struct hostent *gethostbyaddr();
-#if NAMED_BIND
- extern int h_errno;
-#endif
+ char hbuf[MAXNAME + 1];
/*
** See if we have already looked up this name. If so, just
@@ -1212,22 +1379,39 @@ host_map_lookup(map, name, av, statp)
{
if (tTd(9, 1))
printf("host_map_lookup(%s) => CACHE %s\n",
- name, s->s_namecanon.nc_cname);
+ name,
+ s->s_namecanon.nc_cname == NULL
+ ? "NULL"
+ : s->s_namecanon.nc_cname);
errno = s->s_namecanon.nc_errno;
#if NAMED_BIND
h_errno = s->s_namecanon.nc_herrno;
#endif
*statp = s->s_namecanon.nc_stat;
- if (CurEnv->e_message == NULL && *statp == EX_TEMPFAIL)
+ if (*statp == EX_TEMPFAIL)
{
- sprintf(hbuf, "%s: Name server timeout",
+ CurEnv->e_status = "4.4.3";
+ message("851 %s: Name server timeout",
shortenstring(name, 33));
- CurEnv->e_message = newstr(hbuf);
}
return s->s_namecanon.nc_cname;
}
/*
+ ** If we are running without a regular network connection (usually
+ ** dial-on-demand) and we are just queueing, we want to avoid DNS
+ ** lookups because those could try to connect to a server.
+ */
+
+ if (CurEnv->e_sendmode == SM_DEFER)
+ {
+ if (tTd(9, 1))
+ printf("host_map_lookup(%s) => DEFERRED\n", name);
+ *statp = EX_TEMPFAIL;
+ return NULL;
+ }
+
+ /*
** If first character is a bracket, then it is an address
** lookup. Address is copied into a temporary buffer to
** strip the brackets and to preserve name if address is
@@ -1241,8 +1425,14 @@ host_map_lookup(map, name, av, statp)
if (tTd(9, 1))
printf("host_map_lookup(%s) => ", name);
s->s_namecanon.nc_flags |= NCF_VALID; /* will be soon */
- (void) strcpy(hbuf, name);
- if (getcanonname(hbuf, sizeof hbuf - 1, TRUE))
+ if (strlen(name) < sizeof hbuf)
+ (void) strcpy(hbuf, name);
+ else
+ {
+ bcopy(name, hbuf, sizeof hbuf - 1);
+ hbuf[sizeof hbuf - 1] = '\0';
+ }
+ if (getcanonname(hbuf, sizeof hbuf - 1, !HasWildcardMX))
{
if (tTd(9, 1))
printf("%s\n", hbuf);
@@ -1264,16 +1454,15 @@ host_map_lookup(map, name, av, statp)
case TRY_AGAIN:
if (UseNameServer)
{
- sprintf(hbuf, "%s: Name server timeout",
+ CurEnv->e_status = "4.4.3";
+ message("851 %s: Name server timeout",
shortenstring(name, 33));
- message("%s", hbuf);
- if (CurEnv->e_message == NULL)
- CurEnv->e_message = newstr(hbuf);
}
*statp = EX_TEMPFAIL;
break;
case HOST_NOT_FOUND:
+ case NO_DATA:
*statp = EX_NOHOST;
break;
@@ -1291,34 +1480,16 @@ host_map_lookup(map, name, av, statp)
*statp = EX_NOHOST;
#endif
s->s_namecanon.nc_stat = *statp;
- if (*statp != EX_TEMPFAIL || UseNameServer)
- return NULL;
-
- /*
- ** Try to look it up in /etc/hosts
- */
-
- hp = gethostbyname(name);
- if (hp == NULL)
- {
- /* no dice there either */
- s->s_namecanon.nc_stat = *statp = EX_NOHOST;
- return NULL;
- }
-
- s->s_namecanon.nc_stat = *statp = EX_OK;
- cp = map_rewrite(map, hp->h_name, strlen(hp->h_name), av);
- s->s_namecanon.nc_cname = newstr(cp);
- return cp;
+ return NULL;
}
}
if ((cp = strchr(name, ']')) == NULL)
return (NULL);
*cp = '\0';
- in_addr = inet_addr(&name[1]);
+ in_addr.s_addr = inet_addr(&name[1]);
/* nope -- ask the name server */
- hp = gethostbyaddr((char *)&in_addr, sizeof(struct in_addr), AF_INET);
+ hp = sm_gethostbyaddr((char *)&in_addr, INADDRSZ, AF_INET);
s->s_namecanon.nc_errno = errno;
#if NAMED_BIND
s->s_namecanon.nc_herrno = h_errno;
@@ -1331,7 +1502,7 @@ host_map_lookup(map, name, av, statp)
}
/* found a match -- copy out */
- cp = map_rewrite(map, hp->h_name, strlen(hp->h_name), av);
+ cp = map_rewrite(map, (char *) hp->h_name, strlen(hp->h_name), av);
s->s_namecanon.nc_stat = *statp = EX_OK;
s->s_namecanon.nc_cname = newstr(cp);
return cp;
@@ -1346,6 +1517,10 @@ host_map_lookup(map, name, av, statp)
** A printable version of that sockaddr.
*/
+#if NETLINK
+# include <net/if_dl.h>
+#endif
+
char *
anynet_ntoa(sap)
register SOCKADDR *sap;
@@ -1363,8 +1538,7 @@ anynet_ntoa(sap)
switch (sap->sa.sa_family)
{
-#ifdef MAYBENEXTRELEASE /*** UNTESTED *** UNTESTED *** UNTESTED ***/
-#ifdef NETUNIX
+#if NETUNIX
case AF_UNIX:
if (sap->sunix.sun_path[0] != '\0')
sprintf(buf, "[UNIX: %.64s]", sap->sunix.sun_path);
@@ -1372,16 +1546,22 @@ anynet_ntoa(sap)
sprintf(buf, "[UNIX: localhost]");
return buf;
#endif
-#endif
-#ifdef NETINET
+#if NETINET
case AF_INET:
- return inet_ntoa(((struct sockaddr_in *) sap)->sin_addr);
+ return inet_ntoa(sap->sin.sin_addr);
#endif
+#if NETLINK
+ case AF_LINK:
+ sprintf(buf, "[LINK: %s]",
+ link_ntoa((struct sockaddr_dl *) &sap->sa));
+ return buf;
+#endif
default:
- /* this case is only to ensure syntactic correctness */
- break;
+ /* this case is needed when nothing is #defined */
+ /* in order to keep the switch syntactically correct */
+ break;
}
/* unknown family -- just dump bytes */
@@ -1424,30 +1604,28 @@ hostnamebyanyaddr(sap)
switch (sap->sa.sa_family)
{
-#ifdef NETINET
+#if NETINET
case AF_INET:
- hp = gethostbyaddr((char *) &sap->sin.sin_addr,
- sizeof sap->sin.sin_addr,
+ hp = sm_gethostbyaddr((char *) &sap->sin.sin_addr,
+ INADDRSZ,
AF_INET);
break;
#endif
-#ifdef NETISO
+#if NETISO
case AF_ISO:
- hp = gethostbyaddr((char *) &sap->siso.siso_addr,
+ hp = sm_gethostbyaddr((char *) &sap->siso.siso_addr,
sizeof sap->siso.siso_addr,
AF_ISO);
break;
#endif
-#ifdef MAYBENEXTRELEASE /*** UNTESTED *** UNTESTED *** UNTESTED ***/
case AF_UNIX:
hp = NULL;
break;
-#endif
default:
- hp = gethostbyaddr(sap->sa.sa_data,
+ hp = sm_gethostbyaddr(sap->sa.sa_data,
sizeof sap->sa.sa_data,
sap->sa.sa_family);
break;
@@ -1458,13 +1636,13 @@ hostnamebyanyaddr(sap)
#endif /* NAMED_BIND */
if (hp != NULL)
- return hp->h_name;
+ return (char *) hp->h_name;
else
{
/* produce a dotted quad */
- static char buf[512];
+ static char buf[203];
- (void) sprintf(buf, "[%s]", anynet_ntoa(sap));
+ (void) sprintf(buf, "[%.200s]", anynet_ntoa(sap));
return buf;
}
}
@@ -1548,7 +1726,7 @@ host_map_lookup(map, name, avp, statp)
{
register struct hostent *hp;
- hp = gethostbyname(name);
+ hp = sm_gethostbyname(name);
if (hp != NULL)
return hp->h_name;
*statp = EX_NOHOST;
OpenPOWER on IntegriCloud