diff -u -r zmailer-2.99.48p3/Makefile.in zmailer-2.99.48p4/Makefile.in --- zmailer-2.99.48p3/Makefile.in Fri Jun 13 23:46:44 1997 +++ zmailer-2.99.48p4/Makefile.in Fri Jun 13 23:53:34 1997 @@ -2,7 +2,7 @@ MAJORVERSION = 2 MINORVERSION = 99 -PATCHLEVEL = 48p3 +PATCHLEVEL = 48p4 srcdir = @srcdir@ VPATH = @srcdir@ Only in zmailer-2.99.48p3/bin: mkdep Only in zmailer-2.99.48p3/bin: mklibdep Only in zmailer-2.99.48p4: config.status diff -u -r zmailer-2.99.48p3/doc/design/Makefile zmailer-2.99.48p4/doc/design/Makefile --- zmailer-2.99.48p3/doc/design/Makefile Thu Apr 17 18:51:40 1997 +++ zmailer-2.99.48p4/doc/design/Makefile Wed Jun 11 18:16:47 1997 @@ -1,3 +1,4 @@ +# Generated automatically from Makefile.in by configure. ZMOG= zmog ROFFMACROS= ms TEXI2ROFFDIR= ../../support/texi2roff Only in zmailer-2.99.48p4/doc/design: zmog.ps diff -u -r zmailer-2.99.48p3/doc/design/zmog.tex zmailer-2.99.48p4/doc/design/zmog.tex --- zmailer-2.99.48p3/doc/design/zmog.tex Tue Nov 14 09:15:18 1995 +++ zmailer-2.99.48p4/doc/design/zmog.tex Mon Jun 9 13:47:05 1997 @@ -10,7 +10,7 @@ @center Version 2.99.21 @sp 2 @center Matti Aarnio -@center mea@nic.funet.fi +@center mea@@nic.funet.fi @sp 1 @center Finnish University and Research Network @center FUNET @@ -209,8 +209,8 @@ @subsection Heritage: Smail 3.0 The final, and most recently developed, mailer worth mentioning -here is Smail3.0.@footnote{Around 1988, since then -Smail3.1 has been released with many differences@dots} +here is Smail3.0.@footnote{Around 1988, since then Smail3.1 has +been released with many differences@dots{}}. It is intended as a program capable of replacing Sendmail in many situations. Only in zmailer-2.99.48p3/doc/drafts: draft-ietf-drums-msg-fmt-00.txt Only in zmailer-2.99.48p4/doc/drafts: draft-ietf-drums-msg-fmt-01.txt diff -u -r zmailer-2.99.48p3/include/netdb6.h zmailer-2.99.48p4/include/netdb6.h --- zmailer-2.99.48p3/include/netdb6.h Wed Mar 12 04:00:55 1997 +++ zmailer-2.99.48p4/include/netdb6.h Sat Jun 14 00:41:09 1997 @@ -1,7 +1,11 @@ /* - + IPv6 API additions for the ZMailer at those machines + without proper libraries and includes. + By Matti Aarnio 1997 */ +#ifndef AI_PASSIVE + struct addrinfo { int ai_flags; /* AI_PASSIVE | AI_CANONNAME */ int ai_family; /* PF_xxx */ @@ -15,18 +19,19 @@ #define AI_PASSIVE 0x01 #define AI_CANONNAME 0x02 +#define AI_NONAME 0x04 /* (extension) Don't even try nameservice */ -#define EAI_ADDRFAMILY 1 -#define EAI_AGAIN 2 -#define EAI_BADFLAGS 3 -#define EAI_FAIL 4 -#define EAI_FAMILY 5 -#define EAI_MEMORY 6 -#define EAI_NODATA 7 -#define EAI_NONAME 8 -#define EAI_SERVICE 9 -#define EAI_SOCKTYPE 10 -#define EAI_SYSTEM 11 +#define EAI_ADDRFAMILY -1 +#define EAI_AGAIN -2 +#define EAI_BADFLAGS -3 +#define EAI_FAIL -4 +#define EAI_FAMILY -5 +#define EAI_MEMORY -6 +#define EAI_NODATA -7 +#define EAI_NONAME -8 +#define EAI_SERVICE -9 +#define EAI_SOCKTYPE -10 +#define EAI_SYSTEM -11 #define NI_MAXHOST 1025 #define NI_MAXSERV 32 @@ -36,3 +41,5 @@ #define NI_NAMEREQD 0x04 #define NI_NOFQDN 0x08 #define NI_DGRAM 0x10 + +#endif diff -u -r zmailer-2.99.48p3/lib/selfaddrs.c zmailer-2.99.48p4/lib/selfaddrs.c --- zmailer-2.99.48p3/lib/selfaddrs.c Wed Apr 9 01:49:05 1997 +++ zmailer-2.99.48p4/lib/selfaddrs.c Wed Jun 11 19:09:49 1997 @@ -173,7 +173,7 @@ /* Known address families ? */ if (ifr->ifr_addr.sa_family != AF_INET -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) && ifr->ifr_addr.sa_family != AF_INET6 #endif @@ -220,7 +220,7 @@ memcpy(si4, &ifr->ifr_addr, sizeof(struct sockaddr_in)); sap[ifcount] = (struct sockaddr*)si4; } -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) if (sa->sa_family == AF_INET6) { struct sockaddr_in6 *si6 = (void*)malloc(sizeof(*si6)); if (si6 == NULL) @@ -238,7 +238,7 @@ sap[ifcount] = NULL; close(s); -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) if (af != AF_INET6) { af = AF_INET6; goto other_socktype; @@ -267,7 +267,7 @@ struct hostent *hp, hent; union { struct in_addr ia4; -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) struct in6_addr ia6; #endif } au; @@ -291,7 +291,7 @@ #define IN6ADDRSZ 16 #endif -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) if (strncasecmp(host,"[ipv6.",6)==0) { af = AF_INET6; addrsiz = IN6ADDRSZ; @@ -325,7 +325,7 @@ ++naddrs; if (hp->h_addrtype == AF_INET) addrsiz = sizeof(struct sockaddr_in); -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) else if (hp->h_addrtype == AF_INET6) addrsiz = sizeof(struct sockaddr_in6); #endif @@ -353,7 +353,7 @@ si->sin_family = AF_INET; memcpy(&si->sin_addr.s_addr, *hp_getaddr(), hp->h_length); } -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) if (hp->h_addrtype == AF_INET6) { struct sockaddr_in6 *si6; si6 = malloc(sizeof(*si6)); @@ -456,7 +456,7 @@ memcmp(sa, myaddrs[i], sizeof(struct sockaddr_in)) == 0) return 1; -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) if (sa->sa_family == AF_INET6 && memcmp(sa, myaddrs[i], sizeof(struct sockaddr_in6)) == 0) @@ -474,7 +474,7 @@ char **alist; int i; struct sockaddr_in si; -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) struct sockaddr_in6 si6; #endif #ifndef h_addr /* no h_addr macro -- presumably 4.2BSD or earlier.. */ @@ -488,7 +488,7 @@ #endif memset(&si,0,sizeof(si)); si.sin_family = AF_INET; -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) memset(&si6,0,sizeof(si6)); si6.sin6_family = AF_INET; #endif @@ -499,7 +499,7 @@ if ((i = matchmyaddress((struct sockaddr*)&si))) return i; } -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) if (hp->h_addrtype == AF_INET) { memcpy(&si6.sin6_addr.s6_addr, *alist, hp->h_length); if ((i = matchmyaddress((struct sockaddr*)&si6))) @@ -534,7 +534,7 @@ inet_ntop(AF_INET, &((struct sockaddr_in **) sa)[i]->sin_addr, buf, sizeof(buf)); printf("IPv4: [%s]\n", buf); break; -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) case AF_INET6: inet_ntop(AF_INET6, &((struct sockaddr_in6 **) sa)[i]->sin6_addr, buf, sizeof(buf)); printf("IPv6: [ipv6.%s]\n"); diff -u -r zmailer-2.99.48p3/libc/getaddrinfo.c zmailer-2.99.48p4/libc/getaddrinfo.c --- zmailer-2.99.48p3/libc/getaddrinfo.c Sat Mar 29 18:40:29 1997 +++ zmailer-2.99.48p4/libc/getaddrinfo.c Tue Jun 10 20:35:25 1997 @@ -1,20 +1,33 @@ /* -%%% copyright-cmetz -This software is Copyright 1996 by Craig Metz, All Rights Reserved. + * Generalized adaptation to ZMailer libc fill-in use by + * Matti Aarnio 1997 + * + * The original version was a bit too much Linux specific... + */ + +/* +%%% copyright-cmetz-96 +This software is Copyright 1996-1997 by Craig Metz, All Rights Reserved. The Inner Net License Version 2 applies to this software. You should have received a copy of the license with this software. If you didn't get a copy, you may request one from . */ -/* getaddrinfo() v1.13 */ +/* getaddrinfo() v1.22 */ -/* To do what POSIX says, even when it's broken: */ +/* To do what POSIX says, even when it's broken, define: */ /* #define BROKEN_LIKE_POSIX 1 */ +/* Note: real apps will break if you define this, while nothing other than a + conformance test suite should have a problem with it undefined */ #include "hostenv.h" #include -#include -#include +#ifdef HAVE_STDLIB_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif #include #include @@ -38,8 +51,8 @@ #include "netdb6.h" #endif -extern void freeaddrinfo (); /* ((struct addrinfo *)); */ -extern char *inet_ntop (); +#include +#include #ifndef AF_LOCAL #define AF_LOCAL AF_UNIX @@ -51,21 +64,16 @@ #define UNIX_PATH_MAX 108 #endif /* UNIX_PATH_MAX */ -#define GAIH_OKIFUNSPEC 0x0100 -#define GAIH_EAI ~(GAIH_OKIFUNSPEC) - -struct hostent *gethostbyname2(const char *, int); +#undef AF_LOCAL /* We DO NOT do AF_LOCAL/AF_UNIX stuff... */ -struct hostent *_hostname2addr_hosts(const char *name, int); -struct hostent *_addr2hostname_hosts(const char *name, int, int); - -#ifdef AF_INET6 -const struct in6_addr in6addr_any = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; -const struct in6_addr in6addr_loopback = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }; -#endif +#include +#include "libc.h" +#define GAIH_OKIFUNSPEC 0x0100 +#define GAIH_EAI ~(GAIH_OKIFUNSPEC) -static struct addrinfo nullreq = { 0, PF_UNSPEC, 0, 0, 0, NULL, NULL, NULL }; +static struct addrinfo nullreq = +{ 0, PF_UNSPEC, 0, 0, 0, NULL, NULL, NULL }; struct gaih_service { char *name; @@ -87,6 +95,7 @@ struct gaih_addrtuple *next; int family; char addr[16]; + char *cname; }; struct gaih_typeproto { @@ -95,56 +104,355 @@ char *name; }; -static int gaih_local(const char *name, const struct gaih_service *service, - const struct addrinfo *req, struct addrinfo **pai) +static int hosttable_lookup_addr __((const char *name, + const struct addrinfo *req, + struct gaih_addrtuple **pat)); + +static int +hosttable_lookup_addr(name, req, pat) +const char *name; +const struct addrinfo *req; +struct gaih_addrtuple **pat; +{ + FILE *f; + char buffer[1024]; + char *c, *c2; + int rval = 1; + char *prevcname = NULL; + + f = fopen("/etc/hosts", "r"); + if (f == NULL) + return -(EAI_SYSTEM); + + while (fgets(buffer, sizeof(buffer), f)) { + c = strchr(buffer, '#'); + if (c != NULL) + *c = 0; + + c = buffer; + while (*c && !isspace(*c)) c++; + if (!*c) + continue; + + *(c++) = 0; + + while (*c && isspace(*c)) c++; + if (!*c) + continue; + + c2 = strstr(c, name); + if (c2 == NULL) + continue; + + if (*(c2 - 1) && !isspace(*(c2 - 1))) + continue; + + c2 += strlen(name); + if (*c2 && !isspace(*c2)) + continue; + + c2 = c; + while (*c2 && !isspace(*c2)) c2++; + if (!*c2) + continue; + *c2 = 0; + + if (*pat == NULL) { + *pat = malloc(sizeof(struct gaih_addrtuple)); + if (*pat == NULL) + return -(EAI_MEMORY); + } + + memset(*pat, 0, sizeof(struct gaih_addrtuple)); + + if (!req->ai_family || (req->ai_family == AF_INET)) + if (inet_pton(AF_INET, buffer, (void*)((*pat)->addr)) > 0) { + (*pat)->family = AF_INET; + goto build; + } + +#if defined(INET6) && defined(AF_INET6) + if (!req->ai_family || (req->ai_family == AF_INET6)) + if (inet_pton(AF_INET6, buffer, (void*)((*pat)->addr)) > 0) { + (*pat)->family = AF_INET6; + goto build; + } +#endif /* INET6 */ + + continue; + +build: + if (req->ai_flags & AI_CANONNAME) + if (prevcname && !strcmp(prevcname, c)) + (*pat)->cname = prevcname; + else + prevcname = (*pat)->cname = strdup(c); + + pat = &((*pat)->next); + + rval = 0; + } + + fclose(f); + return (rval); +} + +#ifndef HFIXEDSZ +#define HFIXEDSZ 12 +#endif + +static int resolver_lookup_addr __((const char *name, int type, + const struct addrinfo *req, + struct gaih_addrtuple **pat, + FILE *vlog)); + +static int +resolver_lookup_addr(name, type, req, pat, vlog) +const char *name; +int type; +const struct addrinfo *req; +struct gaih_addrtuple **pat; +FILE *vlog; +{ + char answer[PACKETSZ]; + int answerlen; + char dn[/* MAXDNAME */ 128]; + char *prevcname = NULL; + char *p, *ep; + int answers, qdcount, i, j; + int rtype, rclass; + + answerlen = res_search(name, C_IN, type, (void*)answer, sizeof(answer)); + if (answerlen < 0) { + switch(h_errno) { +#ifdef NETDB_INTERNAL + case NETDB_INTERNAL: + if (vlog) + fprintf(vlog,"res_search() yields NETDB_INTERNAL error for lookup of name='%s', type=%d\n",name,type); + return -(EAI_SYSTEM); +#endif + case HOST_NOT_FOUND: + return 1; + case TRY_AGAIN: + return -(EAI_AGAIN); /* XXX */ + case NO_RECOVERY: + if (vlog) fprintf(vlog, "res_search('%s',C_IN,type=%d) -> NO_RECOVERY error\n", name, type); + return -(EAI_FAIL); + case NO_DATA: + return 1; + default: + if (vlog) fprintf(vlog, "res_search() yields unknown h_errno value: %d\n", h_errno); + return -(EAI_FAIL); + } + } + + p = answer; + ep = answer + answerlen; + + if (answerlen < HFIXEDSZ) { + if (vlog) + fprintf(vlog,"res_search() yielded answer with too small reply: %d ( < 10 )\n", answerlen); + return -(EAI_FAIL); + } else { + HEADER *h = (HEADER *)p; + qdcount = ntohs(h->qdcount); + answers = ntohs(h->ancount); + if (!h->qr || (h->opcode != QUERY) || (qdcount != 1) || !answers) { + if (vlog) fprintf(vlog, "eaifail%d\n",__LINE__); + return -(EAI_FAIL); + } + } + p += HFIXEDSZ; + + dn[0] = 0; + for (; qdcount > 0; --qdcount) { + int qt, qc; + i = dn_expand((void*)answer, (void*)ep, (void*)p, dn, sizeof(dn)); +#if 0 +#if defined(BIND_VER) && (BIND_VER >= 473) +#else /* !defined(BIND_VER) || (BIND_VER < 473) */ + i = dn_skip((const unsigned char*)p); +#endif /* defined(BIND_VER) && (BIND_VER >= 473) */ +#endif + p += i; + if (i < 0) { + if (vlog) fprintf(vlog, "eaifail%d\n",__LINE__); + return -(EAI_FAIL); + } + qt = _getshort(p); p += 2; + qc = _getshort(p); p += 2; +#if 0 + if (qt != type || qc != C_IN) { + if (vlog) fprintf(vlog, "eaifail%d\n",__LINE__); + return -(EAI_FAIL); + } +#endif + } + + if (vlog) + fprintf(vlog,"resolver(): question skipped, dn='%s', first answer at p=%d answers=%d\n", dn, (p-answer), answers); + + for ( ; answers > 0; --answers) { + i = dn_expand((void*)answer, (void*)ep, (void*)p, dn, sizeof(dn)); + if (i < 0) { + if (vlog) + fprintf(vlog, "resolver() dn_expand() fail; eof-p=%d, p-start=%d\n", + (ep-p), (p-answer)); + return -(EAI_FAIL); + } + p += i; + + if (p + 10 > ep) { /* Too little data! */ + if (vlog) fprintf(vlog, "resolver(): Out of data in reply [1]\n"); + return -(EAI_FAIL); + } else { + j = _getshort(p); p += 2; /* type */ + rclass = _getshort(p); p += 2; /* class */ + if (rclass != C_IN) { + if (vlog) fprintf(vlog, "resolver() reply block class info != C_IN: %d\n", rclass ); + return -(EAI_FAIL); + } + p += 4; /* TTL */ + i = _getshort(p); p += 2; /* size */ + } + + if (p + i > ep) { + if (vlog) fprintf(vlog, "resolver(): Out of data in reply [2]\n"); + return -(EAI_FAIL); + } + + if (j == type) { + while (*pat) + pat = &((*pat)->next); + + switch (type) { + case T_A: + if (i != 4) { + if (vlog) fprintf(vlog, "eaifail@%s:%d; A size = %d != 4\n",__FILE__, __LINE__, i); + return -(EAI_FAIL); + } + + *pat = malloc(sizeof(struct gaih_addrtuple)); + if (*pat == NULL) + return -(EAI_MEMORY); + memset(*pat, 0, sizeof(struct gaih_addrtuple)); + + (*pat)->family = AF_INET; + break; +#if defined(INET6) && defined(AF_INET6) +#ifndef T_AAAA +# define T_AAAA 28 /* IPv6 address record */ +#endif + case T_AAAA: + if (i != 16) { + if (vlog) fprintf(vlog, "eaifail@%s:%d; AAAA size = %d != 16\n",__FILE__,__LINE__, i); + return -(EAI_FAIL); + } + + *pat = malloc(sizeof(struct gaih_addrtuple)); + if (*pat == NULL) + return -(EAI_MEMORY); + memset(*pat, 0, sizeof(struct gaih_addrtuple)); + + (*pat)->family = AF_INET6; + break; +#endif /* INET6 */ + default: + p += i; + continue; /* Skip non T_A / T_AAAA entries */ + break; + } + memcpy((*pat)->addr, p, i); + + if (req->ai_flags & AI_CANONNAME) + if (prevcname && !strcmp(prevcname, dn)) + (*pat)->cname = prevcname; + else + prevcname = (*pat)->cname = strdup(dn); + } + p += i; + } + + return 0; +} + +#ifdef AF_LOCAL +static int gaih_local __((const char *name, const struct gaih_service *service, + const struct addrinfo *req, struct addrinfo **pai, + FILE *vlog)); + +static int +gaih_local(name, service, req, pai, vlog) +const char *name; +const struct gaih_service *service; +const struct addrinfo *req; +struct addrinfo **pai; +FILE *vlog; { struct utsname utsname; + int newsize; + struct sockaddr_un *saun; if (name || (req->ai_flags & AI_CANONNAME)) - if (uname(&utsname)) - return -EAI_SYSTEM; - if (name) { - if (strcmp(name, "localhost") && strcmp(name, "local") && strcmp(name, "unix") && strcmp(name, utsname.nodename)) - return (GAIH_OKIFUNSPEC | -EAI_NONAME); - }; - - if (!(*pai = malloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_un) + ((req->ai_flags & AI_CANONNAME) ? (strlen(utsname.nodename) + 1): 0)))) - return -EAI_MEMORY; - - (*pai)->ai_next = NULL; - (*pai)->ai_flags = req->ai_flags; - (*pai)->ai_family = AF_LOCAL; + if (uname(&utsname) != 0) { + return -(EAI_SYSTEM); + } + + if (name != NULL) { + if (strcmp(name, "localhost") != 0 && + strcmp(name, "local") != 0 && + strcmp(name, "unix") != 0 && + strcmp(name, utsname.nodename) != 0) + return (GAIH_OKIFUNSPEC | -(EAI_NONAME)); + } + + /* I am conservative, and suspect (seriously) compiler qualities + in handling complex convoluted "t:a?b" expressions... [mea] */ + newsize = sizeof(struct addrinfo) + sizeof(struct sockaddr_un); + newsize += ((req->ai_flags & AI_CANONNAME) ? + (strlen(utsname.nodename) + 1): 0); + *pai = malloc(newsize); + if (*pai == NULL) + return -(EAI_MEMORY); + + (*pai)->ai_next = NULL; + (*pai)->ai_flags = req->ai_flags; + (*pai)->ai_family = AF_LOCAL; (*pai)->ai_socktype = req->ai_socktype ? req->ai_socktype : SOCK_STREAM; (*pai)->ai_protocol = req->ai_protocol; - (*pai)->ai_addrlen = sizeof(struct sockaddr_un); - (*pai)->ai_addr = (void*)((char *)(*pai) + sizeof(struct addrinfo)); -#if SALEN - ((struct sockaddr_un *)(*pai)->ai_addr)->sun_len = sizeof(struct sockaddr_un); + (*pai)->ai_addrlen = sizeof(struct sockaddr_un); + (*pai)->ai_addr = (void *)((char *)(*pai) + sizeof(struct addrinfo)); + saun = (struct sockaddr_un *) (*pai)->ai_addr; +#if HAVE_SA_LEN + saun->sun_len = sizeof(struct sockaddr_un); #endif /* SALEN */ - ((struct sockaddr_un *)(*pai)->ai_addr)->sun_family = AF_LOCAL; - memset(((struct sockaddr_un *)(*pai)->ai_addr)->sun_path, 0, UNIX_PATH_MAX); - if (service) { - char *c; - if (c = strchr(service->name, '/')) { - if (strlen(service->name) >= sizeof(((struct sockaddr_un *)(*pai)->ai_addr)->sun_path)) - return (GAIH_OKIFUNSPEC | -EAI_SERVICE); - strcpy(((struct sockaddr_un *)(*pai)->ai_addr)->sun_path, service->name); + saun->sun_family = AF_LOCAL; + memset(saun->sun_path, 0, UNIX_PATH_MAX); + if (service != NULL) { + char *c = strchr(service->name, '/'); + if (c != NULL) { + if (strlen(service->name) >= sizeof(saun->sun_path)) + return (GAIH_OKIFUNSPEC | -(EAI_SERVICE)); + strcpy(saun->sun_path, service->name); } else { - if (strlen(P_tmpdir "/") + 1 + strlen(service->name) >= sizeof(((struct sockaddr_un *)(*pai)->ai_addr)->sun_path)) - return (GAIH_OKIFUNSPEC | -EAI_SERVICE); - strcpy(((struct sockaddr_un *)(*pai)->ai_addr)->sun_path, P_tmpdir "/"); - strcat(((struct sockaddr_un *)(*pai)->ai_addr)->sun_path, service->name); - }; + if (strlen(P_tmpdir "/") + 1 + strlen(service->name) >= sizeof(saun->sun_path)) + return (GAIH_OKIFUNSPEC | -(EAI_SERVICE)); + strcpy(saun->sun_path, P_tmpdir "/"); + strcat(saun->sun_path, service->name); + } } else { - if (!tmpnam(((struct sockaddr_un *)(*pai)->ai_addr)->sun_path)) - return -EAI_SYSTEM; - }; - if (req->ai_flags & AI_CANONNAME) - strcpy((*pai)->ai_canonname = (char *)(*pai) + sizeof(struct addrinfo) + sizeof(struct sockaddr_un), utsname.nodename); - else + if (!tmpnam(saun->sun_path)) + return -(EAI_SYSTEM); + } + if (req->ai_flags & AI_CANONNAME) { + (*pai)->ai_canonname = ((char *)(*pai) + sizeof(struct addrinfo) + + sizeof(struct sockaddr_un)); + strcpy((*pai)->ai_canonname, utsname.nodename); + } else (*pai)->ai_canonname = NULL; return 0; } +#endif static struct gaih_typeproto gaih_inet_typeproto[] = { { 0, 0, NULL }, @@ -153,28 +461,45 @@ { 0, 0, NULL } }; -static int gaih_inet_serv(char *servicename, struct gaih_typeproto *tp, struct gaih_servtuple **st) +static int gaih_inet_serv __((char *servicename, struct gaih_typeproto *tp, + struct gaih_servtuple **st)); + +static int +gaih_inet_serv(servicename, tp, st) +char *servicename; +struct gaih_typeproto *tp; +struct gaih_servtuple **st; { struct servent *s; - if (!(s = getservbyname(servicename, tp->name))) - return (GAIH_OKIFUNSPEC | -EAI_SERVICE); - - if (!(*st = malloc(sizeof(struct gaih_servtuple)))) - return -EAI_MEMORY; + s = getservbyname(servicename, tp->name); + if (s == NULL) + return (GAIH_OKIFUNSPEC | -(EAI_SERVICE)); + + *st = malloc(sizeof(struct gaih_servtuple)); + if (*st == NULL) + return -(EAI_MEMORY); - (*st)->next = NULL; + (*st)->next = NULL; (*st)->socktype = tp->socktype; (*st)->protocol = tp->protocol; - (*st)->port = s->s_port; + (*st)->port = s->s_port; return 0; } -static int gaih_inet(const char *name, const struct gaih_service *service, - const struct addrinfo *req, struct addrinfo **pai) +static int gaih_inet __((const char *name, const struct gaih_service *service, + const struct addrinfo *req, struct addrinfo **pai, + FILE *vlog)); + +static int +gaih_inet(name, service, req, pai, vlog) +const char *name; +const struct gaih_service *service; +const struct addrinfo *req; +struct addrinfo **pai; +FILE *vlog; { - struct hostent *h = NULL; struct gaih_typeproto *tp = gaih_inet_typeproto; struct gaih_servtuple *st = &nullserv; struct gaih_addrtuple *at = NULL; @@ -182,24 +507,26 @@ if (req->ai_protocol || req->ai_socktype) { for (tp++; tp->name && - ((req->ai_socktype != tp->socktype) || !req->ai_socktype) && - ((req->ai_protocol != tp->protocol) || !req->ai_protocol); tp++); + ((req->ai_socktype != tp->socktype) || !req->ai_socktype) && + ((req->ai_protocol != tp->protocol) || !req->ai_protocol); tp++); if (!tp->name) if (req->ai_socktype) - return (GAIH_OKIFUNSPEC | -EAI_SOCKTYPE); + return (GAIH_OKIFUNSPEC | -(EAI_SOCKTYPE)); else - return (GAIH_OKIFUNSPEC | -EAI_SERVICE); + return (GAIH_OKIFUNSPEC | -(EAI_SERVICE)); } if (service) { if (service->num < 0) { if (tp->name) { - if (i = gaih_inet_serv(service->name, tp, &st)) + i = gaih_inet_serv(service->name, tp, &st); + if (i != 0) return i; } else { struct gaih_servtuple **pst = &st; for (tp++; tp->name; tp++) { - if (i = gaih_inet_serv(service->name, tp, pst)) { + i = gaih_inet_serv(service->name, tp, pst); + if (i != 0) { if (i & GAIH_OKIFUNSPEC) continue; goto ret; @@ -207,236 +534,190 @@ pst = &((*pst)->next); } if (st == &nullserv) { - i = (GAIH_OKIFUNSPEC | -EAI_SERVICE); + i = (GAIH_OKIFUNSPEC | -(EAI_SERVICE)); goto ret; } } } else { - if (!(st = malloc(sizeof(struct gaih_servtuple)))) - return -EAI_MEMORY; + st = malloc(sizeof(struct gaih_servtuple)); + if (st == NULL) + return -(EAI_MEMORY); - st->next = NULL; + st->next = NULL; st->socktype = tp->socktype; st->protocol = tp->protocol; - st->port = htons(service->num); + st->port = htons(service->num); } } - if (name) { - if (!(at = malloc(sizeof(struct gaih_addrtuple)))) { - i = -EAI_MEMORY; + if (!name) { + at = malloc(sizeof(struct gaih_addrtuple)); + if (at == NULL) { + i = -(EAI_MEMORY); goto ret; } - at->family = 0; - at->next = NULL; - - if (!at->family || !req->ai_family || (req->ai_family == AF_INET)) - if (inet_pton(AF_INET, name, at->addr) > 0) - at->family = AF_INET; - -#ifdef AF_INET6 - if (!at->family && (!req->ai_family || (req->ai_family == AF_INET6))) - if (inet_pton(AF_INET6, name, at->addr) > 0) - at->family = AF_INET6; -#endif /* AF_INET6 */ - -#if HOSTTABLE - if (!at->family) { - struct hostent *h; - struct gaih_addrtuple **pat = &at; - -#ifdef AF_INET6 - if (!req->ai_family || (req->ai_family == AF_INET6)) - if (h = _hostname2addr_hosts(name, AF_INET6)) { - for (i = 0; h->h_addr_list[i]; i++) { - if (!*pat) { - if (!(*pat = malloc(sizeof(struct gaih_addrtuple)))) { - i = -EAI_MEMORY; - goto ret; - } - } - (*pat)->next = NULL; - (*pat)->family = AF_INET6; - memcpy((*pat)->addr, h->h_addr_list[i], sizeof(struct in6_addr)); - pat = &((*pat)->next); - } - } -#endif /* AF_INET6 */ + memset(at, 0, sizeof(struct gaih_addrtuple)); - if (!req->ai_family || (req->ai_family == AF_INET)) - if (h = _hostname2addr_hosts(name, AF_INET)) { - for (i = 0; h->h_addr_list[i]; i++) { - if (!*pat) { - if (!(*pat = malloc(sizeof(struct gaih_addrtuple)))) { - i = -EAI_MEMORY; - goto ret; - } - } - (*pat)->next = NULL; - (*pat)->family = AF_INET; - memcpy((*pat)->addr, h->h_addr_list[i], sizeof(struct in_addr)); - pat = &((*pat)->next); - } - } +#if defined(INET6) && defined(AF_INET6) + at->next = malloc(sizeof(struct gaih_addrtuple)); + if (at->next == NULL) { + i = -(EAI_MEMORY); + goto ret; } -#endif /* HOSTTABLE */ -#if RESOLVER - if (!at->family) { - struct hostent *h; - struct gaih_addrtuple **pat = &at; - -#if AF_INET6 - if (!req->ai_family || (req->ai_family == AF_INET6)) - if (h = gethostbyname2(name, AF_INET6)) { - for (i = 0; h->h_addr_list[i]; i++) { - if (!*pat) { - if (!(*pat = malloc(sizeof(struct gaih_addrtuple)))) { - i = -EAI_MEMORY; - goto ret; - } - } - (*pat)->next = NULL; - (*pat)->family = AF_INET6; - memcpy((*pat)->addr, h->h_addr_list[i], sizeof(struct in6_addr)); - pat = &((*pat)->next); - } - } -#endif /* AF_INET6 */ + memset(at->next, 0, sizeof(struct gaih_addrtuple)); + at->next->family = AF_INET; - if (!req->ai_family || (req->ai_family == AF_INET)) - if (h = gethostbyname2(name, AF_INET)) { - for (i = 0; h->h_addr_list[i]; i++) { - if (!*pat) { - if (!(*pat = malloc(sizeof(struct gaih_addrtuple)))) { - i = -EAI_MEMORY; - goto ret; - } - } - (*pat)->next = NULL; - (*pat)->family = AF_INET; - memcpy((*pat)->addr, h->h_addr_list[i], sizeof(struct in_addr)); - pat = &((*pat)->next); - } - } + at->family = AF_INET6; +#else + at->family = AF_INET; +#endif /* INET6 */ + + goto build; + } + + if (!req->ai_family || (req->ai_family == AF_INET)) { + struct in_addr in_addr; + if (inet_pton(AF_INET, name, (void*)&in_addr) > 0) { + at = malloc(sizeof(struct gaih_addrtuple)); + if (at == NULL) + return -(EAI_MEMORY); + + memset(at, 0, sizeof(struct gaih_addrtuple)); + + at->family = AF_INET; + memcpy(at->addr, &in_addr, sizeof(struct in_addr)); + goto build; } -#endif /* RESOLVER */ + } - if (!at->family) - return (GAIH_OKIFUNSPEC | -EAI_NONAME); - } else { - if (!(at = malloc(sizeof(struct gaih_addrtuple)))) { - i = -EAI_MEMORY; - goto ret; - }; +#if defined(INET6) && defined(AF_INET6) + if (!req->ai_family || (req->ai_family == AF_INET6)) { + struct in6_addr in6_addr; + if (inet_pton(AF_INET6, name, (void*)&in6_addr) > 0) { + if (!(at = malloc(sizeof(struct gaih_addrtuple)))) + return -(EAI_MEMORY); + + memset(at, 0, sizeof(struct gaih_addrtuple)); + + at->family = AF_INET6; + memcpy(at->addr, &in6_addr, sizeof(struct in6_addr)); + goto build; + } + } +#endif /* INET6 */ - memset(at, 0, sizeof(struct gaih_addrtuple)); + if ((req->ai_flags & AI_NONAME) == 0) { + i = hosttable_lookup_addr(name, req, &at); +if (vlog) + fprintf(vlog,"hosttable_lookup_addr(name='%s') returns %d\n", name, i); -#ifdef AF_INET6 - if (!(at->next = malloc(sizeof(struct gaih_addrtuple)))) { - i = -EAI_MEMORY; + if (i < 0) goto ret; - }; + if (i == 0) + goto build; - at->family = AF_INET6; +#if defined(INET6) && defined(AF_INET6) + if (!req->ai_family || (req->ai_family == AF_INET6)) { + i = resolver_lookup_addr(name, T_AAAA, req, &at, vlog); +if (vlog) + fprintf(vlog,"resolver_lookup_addr(name='%s', T_AAAA) returns %d\n",name, i); + if (i < 0) + goto ret; + } +#endif /* INET6 */ + if (!req->ai_family || (req->ai_family == AF_INET)) { + i = resolver_lookup_addr(name, T_A, req, &at, vlog); +if (vlog) + fprintf(vlog,"resolver_lookup_addr(name='%s', T_A) returns %d\n",name, i); + if (i < 0) + goto ret; + } - memset(at->next, 0, sizeof(struct gaih_addrtuple)); - at->next->family = AF_INET; -#else /* AF_INET6 */ - at->family = AF_INET; -#endif /* !AF_INET6 */ - }; + if (i == 0) + goto build; + } - if (!pai) { - i = 0; - goto ret; - }; + if (at == NULL) + return (GAIH_OKIFUNSPEC | -(EAI_NONAME)); +build: { - const char *c = NULL; + char *prevcname = NULL; struct gaih_servtuple *st2; struct gaih_addrtuple *at2 = at; int j; -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 128 -#endif /* MAXHOSTNAMELEN */ - char buffer[MAXHOSTNAMELEN]; - while(at2) { + while (at2 != NULL) { if (req->ai_flags & AI_CANONNAME) { - struct hostent *h = NULL; - - h = gethostbyaddr(at2->addr, -#ifdef AF_INET6 - (at2->family == AF_INET6) ? sizeof(struct in6_addr) : -#endif /* AF_INET6 */ - sizeof(struct in_addr), at2->family); -#if HOSTTABLE - if (!h) - h = _addr2hostname_hosts(at2->addr, -#ifdef AF_INET6 - (at2->family == AF_INET6) ? sizeof(struct in6_addr) : -#endif /* AF_INET6 */ - sizeof(struct in_addr), at2->family); -#endif /* HOSTTABLE */ - - if (!h) - c = inet_ntop(at2->family, at2->addr, buffer, sizeof(buffer)); + if (at2->cname != NULL) + j = strlen(at2->cname) + 1; else - c = h->h_name; - - if (!c) { - i = (GAIH_OKIFUNSPEC | -EAI_NONAME); - goto ret; - } - - j = strlen(c) + 1; + j = strlen(name) + 1; } else j = 0; -#ifdef AF_INET6 +#if defined(INET6) && defined(AF_INET6) if (at2->family == AF_INET6) i = sizeof(struct sockaddr_in6); else -#endif /* AF_INET6 */ +#endif /* INET6 */ i = sizeof(struct sockaddr_in); st2 = st; - while(st2) { - if (!(*pai = malloc(sizeof(struct addrinfo) + i + j))) { - i = -EAI_MEMORY; + while (st2) { + + *pai = malloc(sizeof(struct addrinfo) + i + j); + if (*pai == NULL) { + i = -(EAI_MEMORY); goto ret; } - (*pai)->ai_flags = req->ai_flags; - (*pai)->ai_family = at2->family; - (*pai)->ai_socktype = st2->socktype; - (*pai)->ai_protocol = st2->protocol; - (*pai)->ai_addrlen = i; - (*pai)->ai_addr = (void*)((char *)(*pai) + sizeof(struct addrinfo)); -#if SALEN - ((struct sockaddr_in *)(*pai)->ai_addr)->sin_len = i; -#endif /* SALEN */ - ((struct sockaddr_in *)(*pai)->ai_addr)->sin_family = at2->family; - ((struct sockaddr_in *)(*pai)->ai_addr)->sin_port = st2->port; + memset(*pai, 0, sizeof(struct addrinfo) + i + j); -#ifdef AF_INET6 + (*pai)->ai_flags = req->ai_flags; + (*pai)->ai_family = at2->family; + (*pai)->ai_socktype = st2->socktype; + (*pai)->ai_protocol = st2->protocol; + (*pai)->ai_addrlen = i; + (*pai)->ai_addr = (void*)((char*)(*pai)+sizeof(struct addrinfo)); + +#if defined(INET6) && defined(AF_INET6) if (at2->family == AF_INET6) { - ((struct sockaddr_in6 *)(*pai)->ai_addr)->sin6_flowinfo = 0; - memcpy(&((struct sockaddr_in6 *)(*pai)->ai_addr)->sin6_addr, at2->addr, sizeof(struct in6_addr)); + struct sockaddr_in6 *si6; + si6 = (struct sockaddr_in6 *) (*pai)->ai_addr; +#if HAVE_SA_LEN + si6->sin6_len = i; +#endif /* SALEN */ + si6->sin6_family = at2->family; + si6->sin6_flowinfo = 0; + si6->sin6_port = st2->port; + memcpy(&si6->sin6_addr, at2->addr, sizeof(struct in6_addr)); } else -#endif /* AF_INET6 */ - { - memcpy(&((struct sockaddr_in *)(*pai)->ai_addr)->sin_addr, at2->addr, sizeof(struct in_addr)); - memset(((struct sockaddr_in *)(*pai)->ai_addr)->sin_zero, 0, sizeof(((struct sockaddr_in *)(*pai)->ai_addr)->sin_zero)); - } - - if (c) { +#endif /* INET6 */ + { + struct sockaddr_in *si4; + si4 = (struct sockaddr_in *) (*pai)->ai_addr; +#if HAVE_SA_LEN + si4->sin_len = i; +#endif /* SALEN */ + si4->sin_family = at2->family; + si4->sin_port = st2->port; + memcpy(&si4->sin_addr, at2->addr, sizeof(struct in_addr)); + } + + if (j != 0) { (*pai)->ai_canonname = (char *)(*pai) + sizeof(struct addrinfo) + i; - strcpy((*pai)->ai_canonname, c); - } else - (*pai)->ai_canonname = NULL; - (*pai)->ai_next = NULL; + if (at2->cname != NULL) { + strcpy((*pai)->ai_canonname, at2->cname); + if (prevcname != at2->cname) { + if (prevcname != NULL) + free(prevcname); + prevcname = at2->cname; + } + } else + strcpy((*pai)->ai_canonname, name); + } pai = &((*pai)->ai_next); @@ -451,7 +732,7 @@ ret: if (st != &nullserv) { struct gaih_servtuple *st2 = st; - while(st) { + while (st != NULL) { st2 = st->next; free(st); st = st2; @@ -459,7 +740,7 @@ } if (at) { struct gaih_addrtuple *at2 = at; - while(at) { + while (at != NULL) { at2 = at->next; free(at); at = at2; @@ -470,23 +751,32 @@ struct gaih { int family; - int (*gaih)(const char *name, const struct gaih_service *service, - const struct addrinfo *req, struct addrinfo **pai); + int (*gaih) __((const char *name, const struct gaih_service *service, + const struct addrinfo *req, struct addrinfo **pai, + FILE *vlog)); }; static struct gaih gaih[] = { -#ifdef AF_INET6 - { PF_INET6, gaih_inet }, -#endif /* AF_INET6 */ - { PF_INET, gaih_inet }, - { PF_LOCAL, gaih_local }, + { PF_INET, gaih_inet }, +#if defined(INET6) && defined(AF_INET6) + { PF_INET6, gaih_inet }, +#endif /* INET6 */ +#ifdef AF_LOCAL + { PF_LOCAL, gaih_local }, +#endif { PF_UNSPEC, NULL } }; -int getaddrinfo(const char *name, const char *service, - const struct addrinfo *req, struct addrinfo **pai) +int +_getaddrinfo_(name, service, req, pai, vlog) +const char *name; +const char *service; +const struct addrinfo *req; +struct addrinfo **pai; +FILE *vlog; { - int i, j = 0; + int i = 0, j = 0; + int anyok; struct addrinfo *p = NULL, **end; struct gaih *g = gaih, *pg = NULL; struct gaih_service gaih_service, *pservice; @@ -512,15 +802,12 @@ return EAI_BADFLAGS; if (service && *service) { - char *c; - gaih_service.num = strtoul(gaih_service.name = (void *)service, &c, 10); - if (*c) { - gaih_service.num = -1; - } + gaih_service.name = (void *)service; + gaih_service.num = atol(gaih_service.name); #if BROKEN_LIKE_POSIX - else - if (!req->ai_socktype) - return EAI_SERVICE; + if (gaih_service.num != -1) + if (!req->ai_socktype) + return EAI_SERVICE; #endif /* BROKEN_LIKE_POSIX */ pservice = &gaih_service; } else @@ -531,21 +818,28 @@ else end = NULL; - while(g->gaih) { + anyok = 0; + for ( ; g->gaih; ++g) { if ((req->ai_family == g->family) || !req->ai_family) { j++; if (!((pg && (pg->gaih == g->gaih)))) { pg = g; - if (i = g->gaih(name, pservice, req, end)) { + i = g->gaih(name, pservice, req, end, vlog); + if (i == 0) + anyok = 1; + +if (vlog) + fprintf(vlog,"getaddrinfo(): g->family=%d g->gaih(name='%s', service='%s') returns: %d\n", g->family, name, service ? service : "", i); + + if (i != 0 && !anyok) { if (!req->ai_family && (i & GAIH_OKIFUNSPEC)) continue; goto gaih_err; } if (end) - while(*end) end = &((*end)->ai_next); + while (*end) end = &((*end)->ai_next); } } - g++; } if (!j) @@ -569,351 +863,25 @@ return EAI_NONAME; } -void freeaddrinfo(struct addrinfo *ai) +int +getaddrinfo(name, service, req, pai) +const char *name; +const char *service; +const struct addrinfo *req; +struct addrinfo **pai; +{ + return _getaddrinfo_(name, service, req, pai, NULL); +} + +void +freeaddrinfo(ai) +struct addrinfo *ai; { struct addrinfo *p; - while(ai) { + while (ai != NULL) { p = ai; ai = ai->ai_next; free((void *)p); - } -} - -#if 0 -/* - * hostname2addr.c -- Name to address translation. For now, only consults - * /etc/hosts, but DNS stuff will go here eventually. - * - * Copyright 1995 by Randall Atkinson, Bao Phan, and Dan McDonald - * All Rights Reserved. - * All Rights under this copyright have been assigned to NRL. - */ - -/*---------------------------------------------------------------------- -# @(#)COPYRIGHT 1.1a (NRL) 17 August 1995 - -COPYRIGHT NOTICE - -All of the documentation and software included in this software -distribution from the US Naval Research Laboratory (NRL) are -copyrighted by their respective developers. - -This software and documentation were developed at NRL by various -people. Those developers have each copyrighted the portions that they -developed at NRL and have assigned All Rights for those portions to -NRL. Outside the USA, NRL also has copyright on the software -developed at NRL. The affected files all contain specific copyright -notices and those notices must be retained in any derived work. - -NRL LICENSE - -NRL grants permission for redistribution and use in source and binary -forms, with or without modification, of the software and documentation -created at NRL provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. All advertising materials mentioning features or use of this software - must display the following acknowledgement: - - This product includes software developed at the Information - Technology Division, US Naval Research Laboratory. - -4. Neither the name of the NRL nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS -IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NRL OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -The views and conclusions contained in the software and documentation -are those of the authors and should not be interpreted as representing -official policies, either expressed or implied, of the US Naval -Research Laboratory (NRL). - -----------------------------------------------------------------------*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#endif - -extern struct hostent _hostent_buffer; -extern int _hostent_parse(char *line, int af, int addrsize); -extern int _hostent_linelen; -extern char *_hostent_linebuf; -extern char *_hostent_file; -extern FILE *_hostent_fh; - -/* Using the /etc/hosts file, find the (first) hostent entry matching the - hostname given (may be either primary or an alias) */ -struct hostent *_hostname2addr_hosts(name, af) -const char *name; -int af; -{ - int addrsize, foo; - - /* Only open the /etc/hosts file once and keep it open. Is this a - Good Thing? (performance vs. memory/resources) */ - if (_hostent_fh) - rewind(_hostent_fh); - else { - if ((_hostent_fh = fopen(_hostent_file, "r")) == NULL) - return (struct hostent *)NULL; - if ((_hostent_linebuf = malloc(_hostent_linelen)) == NULL) - return (struct hostent *)(_hostent_fh = NULL); - } - - switch (af) { - case AF_INET: - addrsize = sizeof(struct in_addr); - break; -#if AF_INET6 - case AF_INET6: - addrsize = sizeof(struct in6_addr); - break; -#endif /* AF_INET6 */ - default: - return (struct hostent *)NULL; - } - - /* Read the file, line by line, and feed the lines to the parser. - If the hostname or an alias matches what we were given to look - for, it's a winner. */ - do - if (fgets(_hostent_linebuf, _hostent_linelen, _hostent_fh) - == _hostent_linebuf) - if (_hostent_parse(_hostent_linebuf, af, addrsize)) - if (!strcmp(_hostent_buffer.h_name, name)) - return &_hostent_buffer; - else - for (foo = 0; _hostent_buffer.h_aliases[foo]; foo++) - if (!strcmp(_hostent_buffer.h_aliases[foo], name)) - return &_hostent_buffer; - while (!feof(_hostent_fh)); - - return NULL; -} - -#if 0 -/* Standard API entry point. We only really handle the Internet protocols, - though I really don't see why it wouldn't work for the rest, since the - parser uses ascii2addr to do the job. */ -/* Eventually, we'll probably want to look at /etc/hosts first, then, - if we don't find anything, try DNS... ? (or maybe a config file?) */ -/* The addresses in the returned hostent structure need to point into - a buffer such that we can transform an in_addr into an in6_addr. - The current functions do this; look at them before implementing - other resolvers. */ -struct hostent *hostname2addr(name, af) -const char *name; -int af; -{ - struct hostent *rval = (struct hostent *)NULL; - - switch (af) { -#if AF_INET6 - case AF_INET6: - rval = _hostname2addr_hosts(name, AF_INET6); - if (rval) - break; - /* do DNS here */ - - /* If there's an IPv4 address available, return it as a IPv4-as-IPv6 - mapped address */ - rval = hostname2addr(name, AF_INET); - if (rval) { - int i; - struct in6_addr in6_v4map_prefix; - IN6_ADDR_ASSIGN(in6_v4map_prefix, 0, 0, htonl(0xffff), 0); - for (i = 0; rval->h_addr_list[i]; i++) { - rval->h_addr_list[i] -= (sizeof(struct in6_addr) - - sizeof(struct in_addr)); - memcpy(rval->h_addr_list[i], &in6_v4map_prefix, - (sizeof(struct in6_addr) - sizeof(struct in_addr))); - } - rval->h_addrtype = AF_INET6; - rval->h_length = sizeof(struct in6_addr); - } - break; -#endif /* AF_INET6 */ - case AF_INET: - rval = _hostname2addr_hosts(name, AF_INET); - if (rval) - break; - /* do DNS here */ - } - - return rval; -} -#endif /* 0 */ - -#if 0 -/* - * _hostent_com.c -- Common routines between the /etc/hosts lookup functions - * - * - * Copyright 1995 by Randall Atkinson, Bao Phan, and Dan McDonald - * All Rights Reserved. - * All Rights under this copyright have been assigned to NRL. - */ - -/*---------------------------------------------------------------------- -# @(#)COPYRIGHT 1.1a (NRL) 17 August 1995 - -COPYRIGHT NOTICE - -All of the documentation and software included in this software -distribution from the US Naval Research Laboratory (NRL) are -copyrighted by their respective developers. - -This software and documentation were developed at NRL by various -people. Those developers have each copyrighted the portions that they -developed at NRL and have assigned All Rights for those portions to -NRL. Outside the USA, NRL also has copyright on the software -developed at NRL. The affected files all contain specific copyright -notices and those notices must be retained in any derived work. - -NRL LICENSE - -NRL grants permission for redistribution and use in source and binary -forms, with or without modification, of the software and documentation -created at NRL provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. All advertising materials mentioning features or use of this software - must display the following acknowledgement: - - This product includes software developed at the Information - Technology Division, US Naval Research Laboratory. - -4. Neither the name of the NRL nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS -IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NRL OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -The views and conclusions contained in the software and documentation -are those of the authors and should not be interpreted as representing -official policies, either expressed or implied, of the US Naval -Research Laboratory (NRL). - -----------------------------------------------------------------------*/ - -#include -#include -#include -#include -#include -#include -#include - -#include "support.h" -#endif - -/* Arbitrary limits */ -#define MAX_ALIAS 4 -#define MAX_ADDR 8 - -/* If this isn't big enough to store any address you're going to parse using -this function, you're gonna lose. */ -#if AF_INET6 -#define MAX_ADDR_SZ sizeof(struct in6_addr) -#else /* AF_INET6 */ -#define MAX_ADDR_SZ sizeof(struct in_addr) -#endif /* AF_INET6 */ - -/* These are the buffers that become the returned static buffer */ -static char h_addr_buf[MAX_ADDR_SZ * MAX_ADDR]; -static char *h_addr_list[MAX_ADDR]; -static char *h_aliases[MAX_ALIAS]; -struct hostent _hostent_buffer; - -int _hostent_linelen = 128; -char *_hostent_linebuf; -FILE *_hostent_fh; -char *_hostent_file = "/etc/hosts"; - -/* Take a line from /etc/hosts, parse it, and put the results in the hostent - buffer. Assumes that anything not a valid address is a name. Handles - comments. */ -int _hostent_parse(char *line, int af, int addrsize) -{ - char *head, *tail; - int c, naddr, nname; - - head = tail = line; - c = naddr = nname = 0; - - _hostent_buffer.h_aliases = h_aliases; - _hostent_buffer.h_addr_list = h_addr_list; - _hostent_buffer.h_length = addrsize; - _hostent_buffer.h_addrtype = af; - - while (1) { - switch (*tail) { - case '#': - case '\0': - case '\n': - c++; - case ' ': - case '\t': - *tail = 0; - if (tail != head) { - void *addr = (char *)h_addr_buf + (MAX_ADDR_SZ * naddr) + - (MAX_ADDR_SZ - addrsize); - memset(&(h_addr_buf[MAX_ADDR_SZ * naddr]), 0, MAX_ADDR_SZ); - if (inet_pton(af, head, addr) == addrsize) { - h_addr_list[naddr++] = addr; - } else { - if (nname) - h_aliases[nname - 1] = head; - else - _hostent_buffer.h_name = head; - nname++; - } - } - if (c) { - memset(&(h_addr_buf[MAX_ADDR_SZ * naddr]), 0, MAX_ADDR_SZ); - h_addr_list[naddr] = NULL; - h_aliases[nname - 1] = NULL; - return (naddr && nname); - } - head = tail + 1;; - } - tail++; } } diff -u -r zmailer-2.99.48p3/libc/getnameinfo.c zmailer-2.99.48p4/libc/getnameinfo.c --- zmailer-2.99.48p3/libc/getnameinfo.c Sat Mar 29 18:49:57 1997 +++ zmailer-2.99.48p4/libc/getnameinfo.c Tue Jun 10 20:39:18 1997 @@ -1,19 +1,30 @@ /* -%%% copyright-cmetz -This software is Copyright 1996 by Craig Metz, All Rights Reserved. + * Generalized adaptation to ZMailer libc fill-in use by + * Matti Aarnio 1997 + * + * The original version was a bit too much Linux specific... + */ + +/* +%%% copyright-cmetz-96 +This software is Copyright 1996-1997 by Craig Metz, All Rights Reserved. The Inner Net License Version 2 applies to this software. You should have received a copy of the license with this software. If you didn't get a copy, you may request one from . -v0.02 */ +/* getnameinfo() v1.20 */ + #include "hostenv.h" -#include -#include -#ifdef __linux__ /* 2.0 series of Linux kernels has this, but wrong.. */ -# define in_addr6 in6_addr +#include +#ifdef HAVE_STDLIB_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include #endif +#include #include #ifdef HAVE_NETINET_IN6_H @@ -31,171 +42,442 @@ #include #ifndef EAI_AGAIN -# include "netdb6.h" +#include "netdb6.h" #endif + #include #include - -/* #include "support.h" */ +#include +#include #ifndef AF_LOCAL #define AF_LOCAL AF_UNIX #endif /* AF_LOCAL */ -#ifndef MAXHOSTNAMELEN -# define MAXHOSTNAMELEN 256 -#endif - -#if HOSTTABLE -struct hostent *_addr2hostname_hosts(const char *, int, int); -#endif /* HOSTTABLE */ +#include +#include "libc.h" #ifndef min #define min(x,y) (((x) > (y)) ? (y) : (x)) #endif /* min */ -extern char *inet_ntop (); +static int hosttable_lookup_name __((int, void*, char *, int, int)); + +static int +hosttable_lookup_name(family, addr, name, namelen, flags) +int family; +void *addr; +char *name; +int namelen; +int flags; +{ + FILE *f; + char buffer[1024]; + char addrbuf[16]; + char *c, *c2; + int i; + + f = fopen("/etc/hosts", "r"); + if (f == NULL) + return -(EAI_SYSTEM); + + while (fgets(buffer, sizeof(buffer), f)) { + c = strchr(buffer, '#'); + if (c != NULL) + *c = 0; + + c = buffer; + while (*c && !isspace(*c)) c++; + if (!*c) + continue; + + *(c++) = 0; + + if (family == AF_INET) + if (inet_pton(AF_INET, buffer, (void*)addrbuf) > 0) + if (memcmp(addrbuf, addr, sizeof(struct in_addr)) != 0) + goto build; + +#if defined(INET6) && defined(AF_INET6) + if (family == AF_INET6) + if (inet_pton(AF_INET6, buffer, (void*)addrbuf) > 0) + if (memcmp(addrbuf, addr, sizeof(struct in6_addr)) != 0) + goto build; +#endif /* INET6 */ + + continue; + + build: + while (*c && isspace(*c)) c++; + if (!*c) + continue; + + c2 = c; + while (*c2 && !isspace(*c2)) c2++; + if (!*c2) + continue; + *c2 = 0; + + if ((flags & NI_NOFQDN) && (_res.options & RES_INIT) && _res.defdname[0] && + ((c2 = strstr(c + 1, _res.defdname)) != NULL) && (*(--c2) == '.')) { + *c2 = 0; + i = min(c2 - c, namelen); + strncpy(name, c, i); + } else + strncpy(name, c, namelen); + + fclose(f); + return 0; + } + + fclose(f); + return 1; +} + +#if defined(INET6) && defined(AF_INET6) +static char hextab[] = { '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; +#endif /* INET6 */ + +struct rrheader { + short type; + short class; +#if SIZEOF_INT == 4 +#define UINT4 unsigned int + UINT4 ttl; +#else +#if SIZEOF_LONG == 4 +#define UINT4 unsigned long + UINT4 ttl; +#else + ERROR:ERROR: "Can't determine proper type for 4 byte words.." +#endif +#endif + short size; +}; + +#define RRHEADER_SZ 10 +#ifndef HFIXEDSZ +#define HFIXEDSZ 12 +#endif -static char *domain = NULL; -static char domainbuffer[MAXHOSTNAMELEN] = ""; +static int resolver_lookup_name __((const char *, char *, int, int)); -char *nrl_domainname(void) +static int +resolver_lookup_name(ptrname, name, namelen, flags) +const char *ptrname; +char *name; +int namelen; +int flags; { - static int first = 1; + char answer[PACKETSZ]; + int answerlen; + char dn[MAXDNAME]; + char *p, *ep; + int answers, qdcount, i; + + answerlen = res_search(ptrname, C_IN, T_PTR, (void*)answer, sizeof(answer)); + + if (answerlen < 0) { + switch(h_errno) { +#ifdef NETDB_INTERNAL + case NETDB_INTERNAL: + return -(EAI_SYSTEM); +#endif + case HOST_NOT_FOUND: + return 1; + case TRY_AGAIN: + return -(EAI_AGAIN); /* XXX */ + case NO_RECOVERY: + return -(EAI_FAIL); + case NO_DATA: + return 1; + default: + return -(EAI_FAIL); + } + } + + p = answer; + ep = answer + answerlen; + + if (answerlen < HFIXEDSZ) { + return -(EAI_FAIL); + } else { + HEADER *h = (HEADER *)p; + qdcount = ntohs(h->qdcount); + answers = ntohs(h->ancount); + if (!h->qr || (h->opcode != QUERY) || (qdcount != 1) || !answers) { + return -(EAI_FAIL); + } + } + p += HFIXEDSZ; - if (first) { - char *c, buf[MAXHOSTNAMELEN]; - struct hostent *h; + /* question(s) to skip.. */ + for (; qdcount > 0; --qdcount) { + int qt, qc; + i = dn_expand((void*)answer, (void*)ep, (void*)p, dn, sizeof(dn)); +#if 0 +#if defined(BIND_VER) && (BIND_VER >= 473) +#else /* !defined(BIND_VER) || (BIND_VER < 473) */ + i = dn_skip((const unsigned char*)p); +#endif /* defined(BIND_VER) && (BIND_VER >= 473) */ +#endif + p += i; + if (i < 0) { + return -(EAI_FAIL); + } + qt = _getshort(p); p += 2; + qc = _getshort(p); p += 2; +#if 0 + if (qt != T_PTR || qc != C_IN) { + return -(EAI_FAIL); + } +#endif + } + + while (answers-- > 0) { - first = 0; + int atype, aclass; - if ((h = gethostbyname("localhost")) && (c = strchr(h->h_name, '.'))) - return strcpy(domain = domainbuffer, ++c); + i = dn_expand((void*)answer, (void*)ep, (void*)p, dn, sizeof(dn)); + if (i < 0) + return -(EAI_FAIL); + p += i; - if (!gethostname(domainbuffer, sizeof(domainbuffer))) { - if (c = strchr(domainbuffer, '.')) - return (domain = ++c); + if (p + 10 > ep) { /* Too little data! */ + + return -(EAI_FAIL); + + } else { + + atype = _getshort(p); p += 2; /* type */ + aclass = _getshort(p); p += 2; /* class */ + if (aclass != C_IN) { + return -(EAI_FAIL); + } + p += 4; /* TTL */ + i = _getshort(p); p += 2; /* size */ - if ((h = gethostbyname(domainbuffer)) && (c = strchr(h->h_name, '.'))) - return strcpy(domain = domainbuffer, ++c); } - { - struct in_addr in_addr; + if (p + i > ep) /* Too little data! */ + return -(EAI_FAIL); - in_addr.s_addr = htonl(0x7f000001); + if (dn_expand((void*)answer, (void*)ep, (void*)p, dn, sizeof(dn)) != i) + return -(EAI_FAIL); - if ((h = gethostbyaddr((const char *)&in_addr, sizeof(struct in_addr), AF_INET)) && (c = strchr(h->h_name, '.'))) - return strcpy(domain = domainbuffer, ++c); + else { + /* XXX: see if the object is T_CNAME ! + (and what others you may encounter here..) */ + char *c2; + + if ((flags & NI_NOFQDN) && (_res.options & RES_INIT) && _res.defdname[0] && + ((c2 = strstr(dn + 1, _res.defdname)) != NULL) && (*(--c2) == '.')) { + *c2 = 0; + i = min(c2 - dn, namelen); + strncpy(name, dn, i); + } else + strncpy(name, dn, namelen); } - return NULL; - } + p += i; - return domain; -} + } /* All answers */ + return 0; +} -int getnameinfo(const struct sockaddr *sa, size_t addrlen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) +int getnameinfo(sa, addrlen, host, hostlen, serv, servlen, flags) +const struct sockaddr *sa; +size_t addrlen; +char *host; +size_t hostlen; +char *serv; +size_t servlen; +int flags; { int serrno = errno; + int rval = 0; + int my_alen; + + if (!sa || addrlen < 1) + return -(EAI_FAIL); + + /* my_alen = NRL_SA_LEN(sa); */ +#ifdef HAVE_SA_LEN + my_alen = sa->sa_len; +#else + my_alen = -1; /* Totally invalid value */ + if (sa->sa_family == AF_INET) + my_alen = sizeof(struct sockaddr_in); +#if defined(INET6) && defined(AF_INET6) + if (sa->sa_family == AF_INET6) + my_alen = sizeof(struct sockaddr_in6); +#endif +#endif - if (!sa || (addrlen != NRL_SA_LEN(sa))) - return -1; + if (addrlen != my_alen) + return -(EAI_FAIL); if (host && (hostlen > 0)) - switch(sa->sa_family) { - case AF_INET: -#ifdef AF_INET6 - case AF_INET6: -#endif /* AF_INET6 */ - if (!(flags & NI_NUMERICHOST)) { - struct hostent *h = NULL; -#if HOSTTABLE -#ifdef AF_INET6 - if (sa->sa_family == AF_INET6) - h = _addr2hostname_hosts((void *)&(((struct sockaddr_in6 *)sa)->sin6_addr), sizeof(struct in6_addr), AF_INET6); - else -#endif /* AF_INET6 */ - h = _addr2hostname_hosts((void *)&(((struct sockaddr_in *)sa)->sin_addr), sizeof(struct in_addr), AF_INET); -#endif /* HOSTTABLE */ - - if (!h) { -#ifdef AF_INET6 - if (sa->sa_family == AF_INET6) - h = gethostbyaddr((void *)&(((struct sockaddr_in6 *)sa)->sin6_addr), sizeof(struct in6_addr), AF_INET6); - else -#endif /* INET6 */ - h = gethostbyaddr((void *)&(((struct sockaddr_in *)sa)->sin_addr), sizeof(struct in_addr), AF_INET); - endhostent(); - }; - - if (h) { - if (flags & NI_NOFQDN) { - char *c, *c2; - if ((c = nrl_domainname()) && (c = strstr(h->h_name, c)) && (c != h->h_name) && (*(--c) == '.')) { - strncpy(host, h->h_name, min(hostlen, (c - h->h_name))); - break; - }; - }; - strncpy(host, h->h_name, hostlen); - break; + switch (sa->sa_family) { +#if defined(INET6) && defined(AF_INET6) + case AF_INET6: + { + struct in6_addr *sa6; + sa6 = &((struct sockaddr_in6 *)sa)->sin6_addr; + + if (flags & NI_NUMERICHOST) + goto inet6_noname; + +#ifndef IN6_IS_ADDR_V4MAPPED +# define IN6_IS_ADDR_V4MAPPED(a) /* Alignment guaranteed.. */ \ + ((((UINT4 *)(a))[0] == 0) && (((UINT4 *)(a))[1] == 0) && \ + (((UINT4 *)(a))[2] == htonl(0xffff))) +#endif + + if (IN6_IS_ADDR_V4MAPPED(sa6)) { + struct sockaddr_in si4; + memset(&si4, 0, sizeof(struct sockaddr_in)); +#if HAVE_SA_LEN + si4.sin_len = sizeof(struct sockaddr_in); +#endif /* SALEN */ + si4.sin_family = AF_INET; + si4.sin_port = ((struct sockaddr_in6 *)sa)->sin6_port; + si4.sin_addr.s_addr = ((UINT4 *)sa6)[3]; + rval = getnameinfo((struct sockaddr *)&si4, + sizeof(struct sockaddr_in), + host, hostlen, + serv, servlen, + flags | NI_NAMEREQD); + if (rval == 0) + return 0; + if (rval != -(EAI_NONAME)) + return rval; + goto inet6_noname; + } + + rval = hosttable_lookup_name(AF_INET6,(void*)sa6,host,hostlen,flags); + if (rval < 0) + goto fail; + + if (!rval) + break; + else { + char ptrname[73]; + int i; + char *c = ptrname; + unsigned char *p = (unsigned char *)sa6 + sizeof(struct in6_addr) - 1; + + i = sizeof(struct in6_addr) / sizeof(unsigned char); + for (; i > 0; --i, --p) { + *(c++) = hextab[*p & 0x0f]; + *(c++) = '.'; + *(c++) = hextab[(*p & 0xf0) >> 4]; + *(c++) = '.'; } + strcpy(c, "ip6.int."); + + rval = resolver_lookup_name(ptrname, host, hostlen, flags); + if (rval < 0) + goto fail; + + if (rval == 0) + break; } - + + inet6_noname: if (flags & NI_NAMEREQD) goto fail; - - { - const char *c; -#ifdef AF_INET6 - if (sa->sa_family == AF_INET6) - c = inet_ntop(AF_INET6, (void *)&(((struct sockaddr_in6 *)sa)->sin6_addr), host, hostlen); - else + + if (!inet_ntop(AF_INET6, (void*)sa6, host, hostlen)) + goto fail; + } + break; #endif /* INET6 */ - c = inet_ntop(AF_INET, (void *)&(((struct sockaddr_in *)sa)->sin_addr), host, hostlen); + case AF_INET: + { + const struct in_addr *sa4; + sa4 = &((const struct sockaddr_in *)sa)->sin_addr; + + if (flags & NI_NUMERICHOST) + goto inet_noname; + + rval = hosttable_lookup_name(AF_INET,(void*)sa4, host, hostlen, flags); + if (rval < 0) + goto fail; - if (!c) + if (rval == 0) + break; + else { + char ptrname[30]; + unsigned char *p = (unsigned char *)sa4; + sprintf(ptrname, "%d.%d.%d.%d.in-addr.arpa.", + p[3], p[2], p[1], p[0]); + + rval = resolver_lookup_name(ptrname, host, hostlen, flags); + if (rval < 0) goto fail; + + if (rval == 0) + break; + } + + inet_noname: + if (flags & NI_NAMEREQD) { + rval = -(EAI_NONAME); + goto fail; } - break; - case AF_LOCAL: - if (!(flags & NI_NUMERICHOST)) { - struct utsname utsname; + + if (!inet_ntop(AF_INET, (void*)sa4, host, hostlen)) + goto fail; + } + break; + + case AF_LOCAL: + if (!(flags & NI_NUMERICHOST)) { + struct utsname utsname; - if (!uname(&utsname)) { - strncpy(host, utsname.nodename, hostlen); - break; - }; - }; + if (!uname(&utsname)) { + strncpy(host, utsname.nodename, hostlen); + break; + } + } - if (flags & NI_NAMEREQD) - goto fail; + if (flags & NI_NAMEREQD) + goto fail; - strncpy(host, "localhost", hostlen); - break; - default: - return -1; + strncpy(host, "localhost", hostlen); + break; + + default: + return -(EAI_FAMILY); } if (serv && (servlen > 0)) switch(sa->sa_family) { - case AF_INET: -#ifdef AF_INET6 - case AF_INET6: + case AF_INET: +#if defined(INET6) && defined(AF_INET6) + case AF_INET6: #endif /* INET6 */ - if (!(flags & NI_NUMERICSERV)) { - struct servent *s; - if (s = getservbyport(((struct sockaddr_in *)sa)->sin_port, (flags & NI_DGRAM) ? "udp" : "tcp")) { - strncpy(serv, s->s_name, servlen); - break; - }; - }; - snprintf(serv, servlen, "%d", ntohs(((struct sockaddr_in *)sa)->sin_port)); - break; - case AF_LOCAL: - strncpy(serv, ((struct sockaddr_un *)sa)->sun_path, servlen); - break; + if (!(flags & NI_NUMERICSERV)) { + struct servent *s; + s = getservbyport(((const struct sockaddr_in *)sa)->sin_port, + (flags & NI_DGRAM) ? "udp" : "tcp"); + if (s != NULL) { + strncpy(serv, s->s_name, servlen); + break; + } + } + if (servlen >= 6) + sprintf(serv, "%u", ntohs(((const struct sockaddr_in *)sa)->sin_port)); + else + strncpy(serv, "*99999", servlen); + break; + + case AF_LOCAL: + strncpy(serv, ((const struct sockaddr_un *)sa)->sun_path, servlen); + break; } if (host && (hostlen > 0)) @@ -207,5 +489,8 @@ fail: errno = serrno; - return -1; + if (rval == 1) + return EAI_FAIL; + else + return -rval; } diff -u -r zmailer-2.99.48p3/libc/inet_ntop.c zmailer-2.99.48p4/libc/inet_ntop.c --- zmailer-2.99.48p3/libc/inet_ntop.c Fri Mar 21 03:57:45 1997 +++ zmailer-2.99.48p4/libc/inet_ntop.c Sun May 11 03:13:59 1997 @@ -45,7 +45,7 @@ */ static const char *inet_ntop4 __((const u_char *src, char *dst, size_t size)); -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) static const char *inet_ntop6 __((const u_char *src, char *dst, size_t size)); #endif @@ -57,6 +57,9 @@ * author: * Paul Vixie, 1996. */ + +const char * inet_ntop __((int, const void *, char *, size_t)); + const char * inet_ntop(af, src, dst, size) int af; @@ -67,7 +70,7 @@ switch (af) { case AF_INET: return (inet_ntop4(src, dst, size)); -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) case AF_INET6: return (inet_ntop6(src, dst, size)); #endif @@ -106,7 +109,7 @@ return (dst); } -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) #ifndef IN6ADDRSZ #define IN6ADDRSZ 16 diff -u -r zmailer-2.99.48p3/libc/inet_pton.c zmailer-2.99.48p4/libc/inet_pton.c --- zmailer-2.99.48p3/libc/inet_pton.c Fri Mar 21 03:57:40 1997 +++ zmailer-2.99.48p4/libc/inet_pton.c Sun May 11 03:13:44 1997 @@ -48,7 +48,7 @@ */ static int inet_pton4 __((const char *src, u_char *dst)); -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) static int inet_pton6 __((const char *src, u_char *dst)); #endif @@ -63,6 +63,9 @@ * author: * Paul Vixie, 1996. */ + +int inet_pton __((int, const char *, void *)); + int inet_pton(af, src, dst) int af; @@ -72,7 +75,7 @@ switch (af) { case AF_INET: return (inet_pton4(src, dst)); -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) case AF_INET6: return (inet_pton6(src, dst)); #endif @@ -133,7 +136,8 @@ return (1); } -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) + /* int * inet_pton6(src, dst) * convert presentation level address to network order binary form. diff -u -r zmailer-2.99.48p3/libident/identuser.c zmailer-2.99.48p4/libident/identuser.c --- zmailer-2.99.48p3/libident/identuser.c Tue Apr 1 04:34:56 1997 +++ zmailer-2.99.48p4/libident/identuser.c Sun May 11 15:53:45 1997 @@ -52,7 +52,7 @@ #define FNDELAY O_NDELAY #endif -unsigned short ident_tcpport = 113; +unsigned int ident_tcpport = 113; #define SIZ 500 /* various buffers */ @@ -62,19 +62,20 @@ static jmp_buf jmpalarm; +static int ident_tcpsock5 __((const int, const int, const void *, const void *, int *)); + static int ident_tcpsock5(af, len, inlocal, inremote, sockp) -int af, len; -register int *inlocal; -register int *inremote; -int *sockp; + const int af, len; + const void *inlocal; + const void *inremote; + int *sockp; { union { struct sockaddr_in v4; -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) struct sockaddr_in6 v6; #endif } sa; - int addrlen; register int s; register int fl; register int saveerrno; @@ -93,7 +94,7 @@ if (bind(s,(struct sockaddr*)&sa,sizeof(sa.v4)) < 0) CLORETS(-1); } -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) else if (af == AF_INET6) { sa.v6.sin6_family = AF_INET6; sa.v6.sin6_flowinfo = 0; @@ -128,7 +129,7 @@ if (errno != EINPROGRESS) CLORETS(-1); } -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) else if (af == AF_INET6) { sa.v6.sin6_family = AF_INET6; sa.v6.sin6_flowinfo = 0; @@ -145,26 +146,27 @@ return s; } +static volatile const char *ident_sockuser2 __((const int, const int, const int, char *, const int)); -static char *ident_sockuser2(s,local,remote,realbuf,realbuflen) -int s; -unsigned short local; -unsigned short remote; -char *realbuf; -int realbuflen; +static volatile const char *ident_sockuser2(s,local,remote,realbuf,realbuflen) + const int s; + const int local; + const int remote; + char *realbuf; + const int realbuflen; { register int buflen; register int w; register int saveerrno; char ch; - unsigned short rlocal; - unsigned short rremote; + int rlocal; + int rremote; register int fl; fd_set wfds; void (*old_sig)__((int)); char *buf; - old_sig = signal(SIGPIPE, SIG_IGN); + SIGNAL_HANDLESAVE(SIGPIPE, SIG_IGN, old_sig); FD_ZERO(&wfds); FD_SET(s,&wfds); @@ -172,11 +174,11 @@ /* now s is writable */ #if USENONBLOCK if ((fl = fcntl(s,F_GETFL,0)) == -1) { - signal(SIGPIPE, old_sig); + SIGNAL_HANDLE(SIGPIPE, old_sig); CLORETS("SOCKFCNTL1"); } if (fcntl(s,F_SETFL,~FNDELAY & fl) == -1) { - signal(SIGPIPE, old_sig); + SIGNAL_HANDLE(SIGPIPE, old_sig); CLORETS("SOCKFCNTL2"); } #endif @@ -186,7 +188,7 @@ buflen = strlen(buf); while ((w = write(s,buf,buflen)) < buflen) if (w == -1) /* should we worry about 0 as well? */ { - signal(SIGPIPE, old_sig); + SIGNAL_HANDLE(SIGPIPE, old_sig); saveerrno = errno; close(s); if (errno == ECONNREFUSED || errno == EPIPE) @@ -207,12 +209,12 @@ if (((buf - realbuf) > (realbuflen -1) ) || (ch == '\n')) break; } - signal(SIGPIPE, old_sig); + SIGNAL_HANDLE(SIGPIPE, old_sig); if (w == -1) CLORETS("SOCKREAD"); *buf = 0; - if (sscanf(realbuf,"%hd,%hd: USERID :%*[^:]:%s", + if (sscanf(realbuf,"%d,%d: USERID :%*[^:]:%s", &rremote,&rlocal,realbuf) < 3) { close(s); errno = EIO; @@ -232,21 +234,24 @@ } +static void sig_alrm __((int)); static void sig_alrm (sig) int sig; { + SIGNAL_HANDLE(SIGALRM, sig_alrm); + SIGNAL_RELEASE(SIGALRM); longjmp(jmpalarm,1); } -char *ident_tcpuser9(af,len,inlocal,inremote,local,remote,timeout,buf,buflen) - int af, len; /* Address family, and address size */ - int *inlocal; /* Addresses */ - int *inremote; - unsigned short local; /* Ports */ - unsigned short remote; - int timeout; +volatile const char *ident_tcpuser9(af,len,inlocal,inremote,local,remote,timeout,buf,buflen) + const int af, len; /* Address family, and address size */ + const void *inlocal; /* Addresses */ + const void *inremote; + const int local; /* Ports */ + const int remote; + const int timeout; char *buf; - int buflen; + const int buflen; { int s, r; struct timeval tv; @@ -254,12 +259,12 @@ int saveerrno; void (*old_sig)__((int)); void (*old_alrm)__((int)); - int oldival; - char *retval; + unsigned int oldival; + volatile const char *retval; - old_sig = signal(SIGPIPE, SIG_IGN); + SIGNAL_HANDLESAVE(SIGPIPE, SIG_IGN, old_sig); oldival = alarm(10); /* 10 seconds until... */ - old_alrm = signal(SIGALRM, sig_alrm); + SIGNAL_HANDLESAVE(SIGALRM, sig_alrm, old_alrm); s = -1; if (setjmp(jmpalarm) == 0) { @@ -269,10 +274,10 @@ if (s >= 0) close(s); r = -1; } - signal(SIGALRM, old_alrm); + SIGNAL_HANDLE(SIGALRM, old_alrm); alarm(oldival); if (r < 0) { - signal(SIGPIPE, old_sig); + SIGNAL_HANDLE(SIGPIPE, old_sig); return "SOCKFAULT1"; } tv.tv_sec = timeout; @@ -282,17 +287,17 @@ r = select(s + 1, NULL, &wfds, NULL,&tv); /* XXX: how to handle EINTR? */ if (r == -1) { - signal(SIGPIPE, old_sig); + SIGNAL_HANDLE(SIGPIPE, old_sig); CLORETS("SOCKSELERR"); } if (!FD_ISSET(s,&wfds)) { close(s); errno = ETIMEDOUT; - signal(SIGPIPE, old_sig); + SIGNAL_HANDLE(SIGPIPE, old_sig); return "TIMEDOUT"; } retval = ident_sockuser2(s,local,remote,buf,buflen); - signal(SIGPIPE, old_sig); + SIGNAL_HANDLE(SIGPIPE, old_sig); return retval; } @@ -425,11 +430,11 @@ char *retval; - old_sig = signal(SIGPIPE, SIG_IGN); + SIGNAL_HANDLESAVE(SIGPIPE, SIG_IGN, old_sig); s = ident_tcpsock(inlocal,inremote); if (s == -1) { - signal(SIGPIPE, old_sig); + SIGNAL_HANDLE(SIGPIPE, old_sig); return "SOCKFAULT1"; } tv.tv_sec = timeout; @@ -439,17 +444,17 @@ r = select(s + 1,(fd_set *) 0,&wfds,(fd_set *) 0,&tv); /* XXX: how to handle EINTR? */ if (r == -1) { - signal(SIGPIPE, old_sig); + SIGNAL_HANDLE(SIGPIPE, old_sig); CLORETS("SOCKSELERR"); } if (!FD_ISSET(s,&wfds)) { close(s); errno = ETIMEDOUT; - signal(SIGPIPE, old_sig); + SIGNAL_HANDLE(SIGPIPE, old_sig); return "TIMEDOUT"; } retval = ident_sockuser(s,local,remote); - signal(SIGPIPE, old_sig); + SIGNAL_HANDLE(SIGPIPE, old_sig); return retval; } @@ -470,7 +475,7 @@ fd_set wfds; void (*old_sig)__((int)); - old_sig = signal(SIGPIPE, SIG_IGN); + SIGNAL_HANDLESAVE(SIGPIPE, SIG_IGN, old_sig); FD_ZERO(&wfds); FD_SET(s,&wfds); @@ -478,11 +483,11 @@ /* now s is writable */ #if USENONBLOCK if ((fl = fcntl(s,F_GETFL,0)) == -1) { - signal(SIGPIPE, old_sig); + SIGNAL_HANDLE(SIGPIPE, old_sig); CLORETS("SOCKFCNTL1"); } if (fcntl(s,F_SETFL,~FNDELAY & fl) == -1) { - signal(SIGPIPE, old_sig); + SIGNAL_HANDLE(SIGPIPE, old_sig); CLORETS("SOCKFCNTL2"); } #endif @@ -492,7 +497,7 @@ buflen = strlen(buf); while ((w = write(s,buf,buflen)) < buflen) if (w == -1) /* should we worry about 0 as well? */ { - signal(SIGPIPE, old_sig); + SIGNAL_HANDLE(SIGPIPE, old_sig); saveerrno = errno; close(s); if (errno = ECONNREFUSED) @@ -511,7 +516,7 @@ if ((buf - realbuf == sizeof(realbuf) - 1) || (ch == '\n')) break; } - signal(SIGPIPE, old_sig); + SIGNAL_HANDLE(SIGPIPE, old_sig); if (w == -1) CLORETS("SOCKREAD"); *buf = 0; Only in zmailer-2.99.48p3/man: Makefile Only in zmailer-2.99.48p3/man: vacation.1 Only in zmailer-2.99.48p3/proto/db: Makefile Only in zmailer-2.99.48p3/proto: smtpserver.conf diff -u -r zmailer-2.99.48p3/router/libdb/bind.c zmailer-2.99.48p4/router/libdb/bind.c --- zmailer-2.99.48p3/router/libdb/bind.c Mon Mar 24 17:27:28 1997 +++ zmailer-2.99.48p4/router/libdb/bind.c Wed Jun 11 19:17:50 1997 @@ -692,7 +692,7 @@ if (rrtype == T_ANY) { return newstring((u_char*)strsave(host)); } -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) { char tb[80]; const char *ss; diff -u -r zmailer-2.99.48p3/router/libdb/selfmatch.c zmailer-2.99.48p4/router/libdb/selfmatch.c --- zmailer-2.99.48p3/router/libdb/selfmatch.c Wed Apr 23 20:54:21 1997 +++ zmailer-2.99.48p4/router/libdb/selfmatch.c Wed Jun 11 19:18:18 1997 @@ -47,7 +47,7 @@ stashmyaddresses(NULL); if (cistrncmp(sip->key,"ipv6.",5)==0) { -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) struct sockaddr_in6 si6; memset(&si6, 0, sizeof(si6)); @@ -108,7 +108,7 @@ inet_ntop(AF_INET, (void*)&((struct sockaddr_in*)sa[i])->sin_addr, buf, sizeof(buf)); fprintf(outfp,"[%s]\n",buf); } -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) else if (sa[i]->sa_family == AF_INET) { inet_ntop(AF_INET6, (void*)&((struct sockaddr_in6*)sa[i])->sin6_addr, buf, sizeof(buf)); fprintf(outfp,"[ipv6.%s]\n",buf); diff -u -r zmailer-2.99.48p3/smtpserver/smtpserver.c zmailer-2.99.48p4/smtpserver/smtpserver.c --- zmailer-2.99.48p3/smtpserver/smtpserver.c Fri Jun 13 23:46:44 1997 +++ zmailer-2.99.48p4/smtpserver/smtpserver.c Wed Jun 11 19:17:39 1997 @@ -420,7 +420,7 @@ progname, strerror(errno)); exit(1); } -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) if (SS.raddr.v6.sin6_family == AF_INET6) SS.rport = SS.raddr.v6.sin6_port; else @@ -483,7 +483,7 @@ fflush(stdout); fflush(stderr); } -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) /* Perhaps the system can grok the IPv6 - at least the headers seem to indicate so, but like we know of Linux, the protocol might not be loaded in, or some such... @@ -554,7 +554,7 @@ port = service->s_port; } -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) if (use_ipv6) { extern const struct in6_addr in6addr_any; @@ -732,7 +732,7 @@ SIGNAL_HANDLE(SIGTERM, SIG_IGN); -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) if (SS.raddr.v6.sin6_family == AF_INET6) SS.rport = SS.raddr.v6.sin6_port; else @@ -859,7 +859,7 @@ if (SS->raddr.v4.sin_family == AF_INET) inet_ntop(AF_INET, &SS->raddr.v4.sin_addr, /* IPv4 */ SS->ihostaddr+1, sizeof(SS->ihostaddr)-2); -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) else if (SS->raddr.v6.sin6_family == AF_INET6) { strcpy(SS->ihostaddr+1,"ipv6."); inet_ntop(AF_INET6, &SS->raddr.v6.sin6_addr, /* IPv6 */ @@ -875,7 +875,7 @@ if (skeptical) { if (SS->raddr.v4.sin_family == AF_INET) hp = gethostbyaddr((char*)&SS->raddr.v4.sin_addr, 4, AF_INET); -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) else if (SS->raddr.v6.sin6_family == AF_INET6) { struct in6_addr *ip6; /* Ok, early Linuxes do not have this IPNGWG-BSD-API @@ -1078,7 +1078,7 @@ if (*(cp + strlen(cp) - 1) == '\n') *(cp + strlen(cp) - 1) = '\0'; -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) if (SS->localsock.v6.sin6_family == AF_INET6) { struct in6_addr *ip6 = &SS->localsock.v6.sin6_addr; if (IN6_IS_ADDR_V4MAPPED(ip6)) @@ -1651,7 +1651,7 @@ int rc; char identbuf[1024]; -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) if (SS->raddr.v6.sin6_family == AF_INET6) { cp = ident_tcpuser9(SS->raddr.v6.sin6_family, 16, &SS->localsock.v6.sin6_addr, Only in zmailer-2.99.48p3/support/vacation: vacation.sh diff -u -r zmailer-2.99.48p3/transports/libta/diagnostic.c zmailer-2.99.48p4/transports/libta/diagnostic.c --- zmailer-2.99.48p3/transports/libta/diagnostic.c Wed Apr 23 20:22:20 1997 +++ zmailer-2.99.48p4/transports/libta/diagnostic.c Wed Jun 11 22:22:39 1997 @@ -295,22 +295,26 @@ #endif /* Log the diagnostic string to the file */ -#ifndef SPRINTF_CHAR - len = -#endif - sprintf(sbuf, "%c%c%ld:%ld:%ld::%ld\t%s\t%s\n", - _CF_DIAGNOSTIC, _CFTAG_NORMAL, - rp->id, rp->headeroffset, rp->drptoffset, - time(NULL), notarybuf, message); -#ifdef SPRINTF_CHAR + len = -1; +/* #ifndef SPRINTF_CHAR + len = + #endif */ + sprintf(sbuf, "%c%c%ld:%ld:%ld::%ld\t%s\t%s\n", + _CF_DIAGNOSTIC, _CFTAG_NORMAL, + rp->id, rp->headeroffset, rp->drptoffset, + time(NULL), notarybuf, message); +/* #ifdef SPRINTF_CHAR */ +/* If the autoconfig fails, we are in DEEP trouble, + and the 'len' variable in uninitialized.. */ len = strlen(sbuf); -#endif +/* #endif */ oldalarm = alarm(0); /* We do NOT want to be alarmed while writing to the log! */ rc = write(rp->desc->ctlfd, sbuf, len); if (rc != len) { /* UAARGH! -- write failed, must have disk full! */ + printf("#HELP! diagnostic writeout with bad results!: len=%d, rc=%d\n", len, rc); exit(EX_DATAERR); } fsync(rp->desc->ctlfd); diff -u -r zmailer-2.99.48p3/transports/smtp/smtp.c zmailer-2.99.48p4/transports/smtp/smtp.c --- zmailer-2.99.48p3/transports/smtp/smtp.c Fri Jun 13 23:46:44 1997 +++ zmailer-2.99.48p4/transports/smtp/smtp.c Wed Jun 11 20:12:18 1997 @@ -702,11 +702,16 @@ break; } } + if (errflg || optind > argc) { fprintf(stderr, "Usage: %s [-8|-8H|-7][-e][-r][-x][-E][-P][-W][-T timeout][-h myhostname][-l logfile][-p portnum][-c channel][-F forcedest][-L localidentity] [host]\n", argv[0]); exit(EX_USAGE); } + + if (SS.servport < 0) + SS.servport = IPPORT_SMTP; + if (optind < argc) { host = strdup(argv[optind]); } else @@ -2017,11 +2022,13 @@ stashmyaddresses(myhostname); - if (debug) { + if (debug && logfp) fprintf(logfp, "%s#\tsmtpconn: host = %.200s\n", logtag(), host); - } + if (SS->verboselog) - fprintf(SS->verboselog,"SMTP: Connecting to host: %.200s\n",host); + fprintf(SS->verboselog,"SMTP: pid=%d Connecting to host: %.200s\n", + getpid(), host); + if (*host == '[') { /* hostname is IP address domain literal */ char *cp, *hcp, buf[BUFSIZ]; int rc; @@ -2033,7 +2040,7 @@ *cp = '\0'; af = AF_INET; -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) if (strncasecmp(buf,"ipv6.",5)==0) { af = AF_INET6; rc = inet_pton(af, buf+5, ipaddr); @@ -2277,7 +2284,7 @@ struct hostent *hp; union { struct sockaddr_in v4; -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) struct sockaddr_in6 v6; #endif } laddr; @@ -2294,7 +2301,7 @@ if (laddr.v4.sin_family == AF_INET) hp = gethostbyaddr((char*)&laddr.v4.sin_addr, 4, AF_INET); -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) else if (laddr.v6.sin6_family == AF_INET6) hp = gethostbyaddr((char*)&laddr.v6.sin6_addr, 16, AF_INET6); #endif @@ -2356,7 +2363,7 @@ for (hp_init(hp); hp_getaddr() && *hp_getaddr(); hp_nextaddr()) { int i; struct sockaddr_in si; -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) struct sockaddr_in6 si6; #endif @@ -2367,7 +2374,7 @@ i = matchmyaddress((struct sockaddr*)&si); inet_ntop(AF_INET, &si.sin_addr.s_addr, SS->ipaddress, sizeof(SS->ipaddress)); } -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) if (hp->h_addrtype == AF_INET6) { memset(&si6,0,sizeof(si6)); si6.sin6_family = AF_INET6; @@ -2382,7 +2389,7 @@ /* XXX: Locally matched address is on some MX target, if ismx >= 0. In such a case, the error should be ???? What ? */ - if (i != 0) { + if (i != 0 && SS->servport == IPPORT_SMTP) { time(&endtime); notary_setxdelay((int)(endtime-starttime)); if (i == 2) { @@ -2404,7 +2411,7 @@ if (hp->h_addrtype == AF_INET) i = vcsetup(SS, (struct sockaddr*)&si, &mfd, hostbuf); -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) if (hp->h_addrtype == AF_INET6) i = vcsetup(SS, (struct sockaddr*)&si6, &mfd, hostbuf); #endif @@ -2454,7 +2461,7 @@ register int s; struct sockaddr_in *sai = (struct sockaddr_in *)sa; struct sockaddr_in sad; -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) struct sockaddr_in6 *sai6 = (struct sockaddr_in6 *)sa; struct sockaddr_in6 sad6; #endif @@ -2465,7 +2472,7 @@ time(&now); af = sa->sa_family; -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) if (sa->sa_family == AF_INET6) { addrsiz = sizeof(*sai6); memset(&sad6, 0, sizeof(sad6)); @@ -2508,7 +2515,7 @@ /* Uh... Somebody wants us to do special hoops... ... to bind some of our alternate IP addresses, for example.. */ -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) if (cistrncmp(localidentity,"[ipv6.",6) == 0) { char *s = strchr(localidentity,']'); if (s) *s = 0; @@ -2545,7 +2552,7 @@ if (bind(s, (struct sockaddr *)&sad, sizeof sad) >= 0) break; } -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) else if (af == AF_INET6) { sad6.sin6_family = AF_INET6; sad6.sin6_port = htons(p); @@ -2587,26 +2594,18 @@ binding on the specific IP will be accepted. */ if (af == AF_INET) bind(s, (struct sockaddr *)&sad, sizeof sad); -#ifdef AF_INET6 +#if defined(AF_INET6) && defined(INET6) if (af == AF_INET6) bind(s, (struct sockaddr *)&sad6, sizeof sad6); #endif /* If it fails, what could we do ? */ } - if (af == AF_INET) { - if (SS->servport < 0) - sai->sin_port = htons((u_short)IPPORT_SMTP); - else - sai->sin_port = htons(SS->servport); - } -#ifdef AF_INET6 - if (af == AF_INET6) { - if (SS->servport < 0) - sai6->sin6_port = htons((u_short)IPPORT_SMTP); - else - sai6->sin6_port = htons(SS->servport); - } + if (af == AF_INET) + sai->sin_port = htons(SS->servport); +#if defined(AF_INET6) && defined(INET6) + if (af == AF_INET6) + sai6->sin6_port = htons(SS->servport); #endif /* setreuid(0,first_uid); if(SS->verboselog) fprintf(SS->verboselog,"setreuid: first_uid=%d, ruid=%d, euid=%d\n",first_uid,getuid(),geteuid()); */