diff options
Diffstat (limited to 'usr.sbin/sendmail/src/daemon.c')
-rw-r--r-- | usr.sbin/sendmail/src/daemon.c | 538 |
1 files changed, 180 insertions, 358 deletions
diff --git a/usr.sbin/sendmail/src/daemon.c b/usr.sbin/sendmail/src/daemon.c index c2f5327..b4b4e8b 100644 --- a/usr.sbin/sendmail/src/daemon.c +++ b/usr.sbin/sendmail/src/daemon.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1983 Eric P. Allman * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * @@ -37,27 +37,20 @@ #ifndef lint #ifdef DAEMON -static char sccsid[] = "@(#)daemon.c 8.118 (Berkeley) 10/8/95 (with daemon mode)"; +static char sccsid[] = "@(#)daemon.c 8.48.1.5 (Berkeley) 3/28/95 (with daemon mode)"; #else -static char sccsid[] = "@(#)daemon.c 8.118 (Berkeley) 10/8/95 (without daemon mode)"; +static char sccsid[] = "@(#)daemon.c 8.48.1.5 (Berkeley) 3/28/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 /* @@ -113,14 +106,13 @@ 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; -#if XDEBUG +#ifdef XDEBUG bool j_has_dot; #endif extern void reapchild(); @@ -175,11 +167,11 @@ getrequests() fclose(pidf); } -#if XDEBUG +#ifdef XDEBUG { char jbuf[MAXHOSTNAMELEN]; - expand("\201j", jbuf, sizeof jbuf, CurEnv); + expand("\201j", jbuf, &jbuf[sizeof jbuf - 1], CurEnv); j_has_dot = strchr(jbuf, '.') != NULL; } #endif @@ -192,7 +184,6 @@ getrequests() register int pid; auto int lotherend; extern bool refuseconnections(); - extern int getla(); /* see if we are rejecting connections */ CurrentLA = getla(); @@ -205,24 +196,29 @@ 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; } -#if XDEBUG +#ifdef XDEBUG /* check for disaster */ { + register STAB *s; char jbuf[MAXHOSTNAMELEN]; - expand("\201j", jbuf, sizeof jbuf, CurEnv); - if (!wordinclass(jbuf, 'w')) + expand("\201j", jbuf, &jbuf[sizeof jbuf - 1], CurEnv); + if ((s = stab(jbuf, ST_CLASS, ST_FIND)) == NULL || + !bitnset('w', s->s_class)) { dumpstate("daemon lost $j"); syslog(LOG_ALERT, "daemon process doesn't have $j in $=w; see syslog"); @@ -238,7 +234,6 @@ getrequests() #endif /* wait for a connection */ - setproctitle("accepting connections"); do { errno = 0; @@ -249,11 +244,6 @@ 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; } @@ -278,8 +268,6 @@ getrequests() { char *p; extern char *hostnamebyanyaddr(); - extern void intsig(); - FILE *inchannel, *outchannel; /* ** CHILD -- return to caller. @@ -288,31 +276,34 @@ getrequests() */ (void) setsignal(SIGCHLD, SIG_DFL); - (void) setsignal(SIGHUP, intsig); - (void) close(DaemonSocket); + DisConnected = FALSE; 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); - if ((inchannel = fdopen(t, "r")) == NULL || +#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 || (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)) @@ -327,8 +318,6 @@ getrequests() return; } - CurChildren++; - /* close the port so that others will hang (for a while) */ (void) close(t); } @@ -358,7 +347,7 @@ opendaemonsocket(firsttime) bool firsttime; { int on = 1; - int socksize = 0; + int socksize; int ntries = 0; int saveerrno; @@ -374,6 +363,7 @@ 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: @@ -403,19 +393,19 @@ opendaemonsocket(firsttime) SO_RCVBUF, (char *) &TcpRcvBufferSize, sizeof(TcpRcvBufferSize)) < 0) - syserr("opendaemonsocket: setsockopt(SO_RCVBUF)"); + syserr("getrequests: setsockopt(SO_RCVBUF)"); } #endif switch (DaemonAddr.sa.sa_family) { -# if NETINET +# ifdef NETINET case AF_INET: socksize = sizeof DaemonAddr.sin; break; # endif -# if NETISO +# ifdef NETISO case AF_ISO: socksize = sizeof DaemonAddr.siso; break; @@ -428,9 +418,8 @@ opendaemonsocket(firsttime) if (bind(DaemonSocket, &DaemonAddr.sa, socksize) < 0) { - /* probably another daemon already */ saveerrno = errno; - syserr("opendaemonsocket: cannot bind"); + syserr("getrequests: cannot bind"); (void) close(DaemonSocket); goto severe; } @@ -438,13 +427,12 @@ opendaemonsocket(firsttime) if (!firsttime && listen(DaemonSocket, ListenQueueSize) < 0) { saveerrno = errno; - syserr("opendaemonsocket: cannot listen"); + syserr("getrequests: cannot listen"); (void) close(DaemonSocket); goto severe; } return socksize; } while (ntries++ < MAXOPENTRIES && transienterror(saveerrno)); - syserr("!opendaemonsocket: server SMTP socket wedged: exiting"); finis(); } /* @@ -460,7 +448,6 @@ opendaemonsocket(firsttime) ** releases any resources used by the passive daemon. */ -void clrdaemon() { if (DaemonSocket >= 0) @@ -477,7 +464,6 @@ clrdaemon() ** none. */ -void setdaemonoptions(p) register char *p; { @@ -502,27 +488,25 @@ 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); -#if NETINET +#ifdef NETINET else if (strcasecmp(v, "inet") == 0) DaemonAddr.sa.sa_family = AF_INET; #endif -#if NETISO +#ifdef NETISO else if (strcasecmp(v, "iso") == 0) DaemonAddr.sa.sa_family = AF_ISO; #endif -#if NETNS +#ifdef NETNS else if (strcasecmp(v, "ns") == 0) DaemonAddr.sa.sa_family = AF_NS; #endif -#if NETX25 +#ifdef NETX25 else if (strcasecmp(v, "x.25") == 0) DaemonAddr.sa.sa_family = AF_CCITT; #endif @@ -533,10 +517,10 @@ setdaemonoptions(p) case 'A': /* address */ switch (DaemonAddr.sa.sa_family) { -#if NETINET +#ifdef NETINET case AF_INET: if (isascii(*v) && isdigit(*v)) - DaemonAddr.sin.sin_addr.s_addr = htonl(inet_network(v)); + DaemonAddr.sin.sin_addr.s_addr = inet_network(v); else { register struct netent *np; @@ -562,7 +546,7 @@ setdaemonoptions(p) { short port; -#if NETINET +#ifdef NETINET case AF_INET: if (isascii(*v) && isdigit(*v)) DaemonAddr.sin.sin_port = htons(atoi(v)); @@ -579,7 +563,7 @@ setdaemonoptions(p) break; #endif -#if NETISO +#ifdef NETISO case AF_ISO: /* assume two byte transport selector */ if (isascii(*v) && isdigit(*v)) @@ -616,9 +600,6 @@ setdaemonoptions(p) case 'R': /* receive buffer size */ TcpRcvBufferSize = atoi(v); break; - - default: - syserr("554 DaemonPortOptions parameter \"%s\" unknown", f); } } } @@ -641,15 +622,6 @@ setdaemonoptions(p) ** none. */ -static jmp_buf CtxConnectTimeout; - -static void -connecttimeout() -{ - errno = ETIMEDOUT; - longjmp(CtxConnectTimeout, 1); -} - SOCKADDR CurHostAddr; /* address of current host */ int @@ -659,14 +631,14 @@ makeconnection(host, port, mci, usesecureport) register MCI *mci; bool usesecureport; { - register int i = 0; - register int s; + register int i, s; register struct hostent *hp = (struct hostent *)NULL; SOCKADDR addr; int sav_errno; int addrlen; - bool firstconnect; - EVENT *ev; +#if NAMED_BIND + extern int h_errno; +#endif /* ** Set up the address for the mailer. @@ -689,26 +661,18 @@ makeconnection(host, port, mci, usesecureport) if (p != NULL) { *p = '\0'; -#if NETINET +#ifdef NETINET hid = inet_addr(&host[1]); if (hid == -1) #endif { /* try it as a host name (avoid MX lookup) */ - hp = sm_gethostbyname(&host[1]); + hp = 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 = sm_gethostbyname(&host[1]); + hp = gethostbyname(&host[1]); p[-1] = '.'; -#if NAMED_BIND - _res.options = oldopts; -#endif } *p = ']'; goto gothostent; @@ -718,10 +682,9 @@ 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); } -#if NETINET +#ifdef NETINET addr.sin.sin_family = AF_INET; /*XXX*/ addr.sin.sin_addr.s_addr = hid; #endif @@ -730,43 +693,34 @@ makeconnection(host, port, mci, usesecureport) { register char *p = &host[strlen(host) - 1]; - hp = sm_gethostbyname(host); + hp = gethostbyname(host); if (hp == NULL && *p == '.') { -#if NAMED_BIND - int oldopts = _res.options; - - _res.options &= ~(RES_DEFNAMES|RES_DNSRCH); -#endif *p = '\0'; - hp = sm_gethostbyname(host); + hp = gethostbyname(host); *p = '.'; -#if NAMED_BIND - _res.options = oldopts; -#endif } gothostent: if (hp == NULL) { #if NAMED_BIND - /* check for name server timeouts */ - if (errno == ETIMEDOUT || h_errno == TRY_AGAIN || - (errno == ECONNREFUSED && UseNameServer)) - { - mci->mci_status = "4.4.3"; + if (errno == ETIMEDOUT || h_errno == TRY_AGAIN) + return (EX_TEMPFAIL); + + /* if name server is specified, assume temp fail */ + if (errno == ECONNREFUSED && UseNameServer) return (EX_TEMPFAIL); - } #endif return (EX_NOHOST); } addr.sa.sa_family = hp->h_addrtype; switch (hp->h_addrtype) { -#if NETINET +#ifdef NETINET case AF_INET: bcopy(hp->h_addr, &addr.sin.sin_addr, - INADDRSZ); + sizeof addr.sin.sin_addr); break; #endif @@ -783,16 +737,15 @@ gothostent: ** Determine the port number. */ - if (port == 0) + if (port != 0) + port = htons(port); + else { register struct servent *sp = getservbyname("smtp", "tcp"); if (sp == NULL) { -#ifdef LOG - if (LogLevel > 2) - syslog(LOG_ERR, "makeconnection: service \"smtp\" unknown"); -#endif + syserr("554 makeconnection: service \"smtp\" unknown"); port = htons(25); } else @@ -801,14 +754,14 @@ gothostent: switch (addr.sa.sa_family) { -#if NETINET +#ifdef NETINET case AF_INET: addr.sin.sin_port = port; addrlen = sizeof (struct sockaddr_in); break; #endif -#if NETISO +#ifdef NETISO case AF_ISO: /* assume two byte transport selector */ bcopy((char *) &port, TSEL((struct sockaddr_iso *) &addr), 2); @@ -831,7 +784,6 @@ gothostent: return EX_TEMPFAIL; #endif - firstconnect = TRUE; for (;;) { if (tTd(16, 1)) @@ -854,7 +806,7 @@ gothostent: if (s < 0) { sav_errno = errno; - syserr("makeconnection: cannot create socket"); + syserr("makeconnection: no socket"); goto failure; } @@ -881,54 +833,24 @@ gothostent: if (CurEnv->e_xfp != NULL) (void) fflush(CurEnv->e_xfp); /* for debugging */ errno = 0; /* for debugging */ - - /* - ** 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; - } + if (connect(s, (struct sockaddr *) &addr, addrlen) >= 0) + break; /* couldn't connect.... figure out why */ + sav_errno = errno; (void) close(s); - if (hp != NULL && hp->h_addr_list[i]) + if (hp && 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) { -#if NETINET +#ifdef NETINET case AF_INET: bcopy(hp->h_addr_list[i++], &addr.sin.sin_addr, - INADDRSZ); + sizeof addr.sin.sin_addr); break; #endif @@ -980,77 +902,61 @@ gothostent: ** Adds numeric codes to $=w. */ -struct hostent * +char ** myhostname(hostbuf, size) char hostbuf[]; int size; { register struct hostent *hp; - extern bool getcanonname(); + extern struct hostent *gethostbyname(); if (gethostname(hostbuf, size) < 0) { (void) strcpy(hostbuf, "localhost"); } - hp = sm_gethostbyname(hostbuf); + hp = gethostbyname(hostbuf); if (hp == NULL) - return NULL; - if (strchr(hp->h_name, '.') != NULL || strchr(hostbuf, '.') == NULL) { - (void) strncpy(hostbuf, hp->h_name, size - 1); - hostbuf[size - 1] = '\0'; + syserr("!My host name (%s) does not seem to exist!", hostbuf); } + (void) strncpy(hostbuf, hp->h_name, size - 1); + hostbuf[size - 1] = '\0'; - /* - ** If there is still no dot in the name, try looking for a - ** dotted alias. - */ - +#if NAMED_BIND + /* if still no dot, try DNS directly (i.e., avoid NIS problems) */ if (strchr(hostbuf, '.') == NULL) { - char **ha; + extern bool getcanonname(); + extern int h_errno; - for (ha = hp->h_aliases; *ha != NULL; 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)))) { - if (strchr(*ha, '.') != NULL) - { - (void) strncpy(hostbuf, *ha, size - 1); - hostbuf[size - 1] = '\0'; - break; - } + errno = h_errno + E_DNSBASE; + syserr("!My host name (%s) not known to DNS", + hostbuf); } } +#endif - /* - ** 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. - */ - - if (strchr(hostbuf, '.') == NULL && - !getcanonname(hostbuf, size, TRUE)) + if (hp->h_addrtype == AF_INET && hp->h_length == 4) { -#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)) + register int i; + + for (i = 0; hp->h_addr_list[i] != NULL; i++) { -#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); + char ipbuf[100]; + + sprintf(ipbuf, "[%s]", + inet_ntoa(*((struct in_addr *) hp->h_addr_list[i]))); + setclass('w', ipbuf); } } - return (hp); + + return (hp->h_aliases); } /* ** GETAUTHINFO -- get the real host name asociated with a file descriptor @@ -1064,34 +970,41 @@ myhostname(hostbuf, size) ** The user@host information associated with this descriptor. */ +#if IDENTPROTO + static jmp_buf CtxAuthTimeout; -static void +static 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; - volatile int s; + 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 (isatty(fd) || getpeername(fd, &RealHostAddr.sa, &falen) < 0 || - falen <= 0 || RealHostAddr.sa.sa_family == 0) + if (getpeername(fd, &RealHostAddr.sa, &falen) < 0 || falen <= 0 || + RealHostAddr.sa.sa_family == 0) { (void) sprintf(hbuf, "%s@localhost", RealUserName); if (tTd(9, 1)) @@ -1105,6 +1018,7 @@ getauthinfo(fd) RealHostName = newstr(hostnamebyanyaddr(&RealHostAddr)); } +#if IDENTPROTO if (TimeOuts.to_ident == 0) goto noident; @@ -1206,14 +1120,6 @@ 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) { @@ -1230,12 +1136,14 @@ getauthinfo(fd) i = strlen(hbuf); hbuf[i++] = '@'; strcpy(&hbuf[i], RealHostName == NULL ? "localhost" : RealHostName); - goto postident; + goto finish; closeident: (void) close(s); clrevent(ev); +#endif /* IDENTPROTO */ + noident: if (RealHostName == NULL) { @@ -1245,92 +1153,12 @@ noident: } (void) strcpy(hbuf, RealHostName); -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: +finish: if (RealHostName != NULL && RealHostName[0] != '[') { p = &hbuf[strlen(hbuf)]; - (void) sprintf(p, " [%.100s]", anynet_ntoa(&RealHostAddr)); + (void) sprintf(p, " [%s]", anynet_ntoa(&RealHostAddr)); } - -postipsr: if (tTd(9, 1)) printf("getauthinfo: %s\n", hbuf); return hbuf; @@ -1364,10 +1192,15 @@ host_map_lookup(map, name, av, statp) int *statp; { register struct hostent *hp; - struct in_addr in_addr; + u_long in_addr; char *cp; + int i; register STAB *s; - char hbuf[MAXNAME + 1]; + char hbuf[MAXNAME]; + extern struct hostent *gethostbyaddr(); +#if NAMED_BIND + extern int h_errno; +#endif /* ** See if we have already looked up this name. If so, just @@ -1379,39 +1212,22 @@ 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 == NULL - ? "NULL" - : s->s_namecanon.nc_cname); + name, 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 (*statp == EX_TEMPFAIL) + if (CurEnv->e_message == NULL && *statp == EX_TEMPFAIL) { - CurEnv->e_status = "4.4.3"; - message("851 %s: Name server timeout", + sprintf(hbuf, "%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 @@ -1425,14 +1241,8 @@ 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 */ - 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)) + (void) strcpy(hbuf, name); + if (getcanonname(hbuf, sizeof hbuf - 1, TRUE)) { if (tTd(9, 1)) printf("%s\n", hbuf); @@ -1454,15 +1264,16 @@ host_map_lookup(map, name, av, statp) case TRY_AGAIN: if (UseNameServer) { - CurEnv->e_status = "4.4.3"; - message("851 %s: Name server timeout", + sprintf(hbuf, "%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; @@ -1480,16 +1291,34 @@ host_map_lookup(map, name, av, statp) *statp = EX_NOHOST; #endif s->s_namecanon.nc_stat = *statp; - return NULL; + 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; } } if ((cp = strchr(name, ']')) == NULL) return (NULL); *cp = '\0'; - in_addr.s_addr = inet_addr(&name[1]); + in_addr = inet_addr(&name[1]); /* nope -- ask the name server */ - hp = sm_gethostbyaddr((char *)&in_addr, INADDRSZ, AF_INET); + hp = gethostbyaddr((char *)&in_addr, sizeof(struct in_addr), AF_INET); s->s_namecanon.nc_errno = errno; #if NAMED_BIND s->s_namecanon.nc_herrno = h_errno; @@ -1502,7 +1331,7 @@ host_map_lookup(map, name, av, statp) } /* found a match -- copy out */ - cp = map_rewrite(map, (char *) hp->h_name, strlen(hp->h_name), av); + cp = map_rewrite(map, 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; @@ -1517,10 +1346,6 @@ 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; @@ -1538,7 +1363,8 @@ anynet_ntoa(sap) switch (sap->sa.sa_family) { -#if NETUNIX +#ifdef MAYBENEXTRELEASE /*** UNTESTED *** UNTESTED *** UNTESTED ***/ +#ifdef NETUNIX case AF_UNIX: if (sap->sunix.sun_path[0] != '\0') sprintf(buf, "[UNIX: %.64s]", sap->sunix.sun_path); @@ -1546,22 +1372,16 @@ anynet_ntoa(sap) sprintf(buf, "[UNIX: localhost]"); return buf; #endif +#endif -#if NETINET +#ifdef NETINET case AF_INET: - return inet_ntoa(sap->sin.sin_addr); + return inet_ntoa(((struct sockaddr_in *) sap)->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 needed when nothing is #defined */ - /* in order to keep the switch syntactically correct */ - break; + /* this case is only to ensure syntactic correctness */ + break; } /* unknown family -- just dump bytes */ @@ -1604,28 +1424,30 @@ hostnamebyanyaddr(sap) switch (sap->sa.sa_family) { -#if NETINET +#ifdef NETINET case AF_INET: - hp = sm_gethostbyaddr((char *) &sap->sin.sin_addr, - INADDRSZ, + hp = gethostbyaddr((char *) &sap->sin.sin_addr, + sizeof sap->sin.sin_addr, AF_INET); break; #endif -#if NETISO +#ifdef NETISO case AF_ISO: - hp = sm_gethostbyaddr((char *) &sap->siso.siso_addr, + hp = 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 = sm_gethostbyaddr(sap->sa.sa_data, + hp = gethostbyaddr(sap->sa.sa_data, sizeof sap->sa.sa_data, sap->sa.sa_family); break; @@ -1636,13 +1458,13 @@ hostnamebyanyaddr(sap) #endif /* NAMED_BIND */ if (hp != NULL) - return (char *) hp->h_name; + return hp->h_name; else { /* produce a dotted quad */ - static char buf[203]; + static char buf[512]; - (void) sprintf(buf, "[%.200s]", anynet_ntoa(sap)); + (void) sprintf(buf, "[%s]", anynet_ntoa(sap)); return buf; } } @@ -1726,7 +1548,7 @@ host_map_lookup(map, name, avp, statp) { register struct hostent *hp; - hp = sm_gethostbyname(name); + hp = gethostbyname(name); if (hp != NULL) return hp->h_name; *statp = EX_NOHOST; |