aboutsummaryrefslogtreecommitdiff
path: root/mail/sendmail812/files/socketmap.patch
diff options
context:
space:
mode:
Diffstat (limited to 'mail/sendmail812/files/socketmap.patch')
-rw-r--r--mail/sendmail812/files/socketmap.patch798
1 files changed, 0 insertions, 798 deletions
diff --git a/mail/sendmail812/files/socketmap.patch b/mail/sendmail812/files/socketmap.patch
deleted file mode 100644
index ea128dbace71..000000000000
--- a/mail/sendmail812/files/socketmap.patch
+++ /dev/null
@@ -1,798 +0,0 @@
-Index: sendmail/sendmail/sendmail/README
-diff -u sendmail/sendmail/sendmail/README:1.1.1.2 sendmail/sendmail/sendmail/README:1.3
---- sendmail/README Thu Jan 23 11:50:26 2003
-+++ sendmail/README Tue Jan 28 16:55:41 2003
-@@ -127,6 +127,8 @@
- PH_MAP PH map support. You will need the libphclient library from
- the nph package (http://www-dev.cso.uiuc.edu/ph/nph/).
- MAP_NSD nsd map support (IRIX 6.5 and later).
-+SOCKETMAP Support for a trivial query protocol over UNIX domain or TCP
-+ sockets.
-
- >>> NOTE WELL for NEWDB support: If you want to get ndbm support, for
- >>> Berkeley DB versions under 2.0, it is CRITICAL that you remove
-@@ -180,6 +182,50 @@
- check_* rule-set, you can block a certain range of addresses that would
- otherwise be considered valid.
-
-+The socket map uses a simple request/reply protocol over TCP or UNIX domain
-+sockets to query an external server. Both requests and replies are text
-+based and encoded as D.J. Bernsteins netstrings. E.g., a string
-+"hello there" becomes:
-+11:hello there,
-+
-+NB. neither requests nor replies end with CRLF.
-+
-+The request consists of the database map name and the lookup key separated
-+by a space character:
-+
-+<mapname> ' ' <key>
-+
-+The server responds with a status indicator and the result (if any):
-+
-+<status> ' ' <result> <LF>
-+
-+The status indicator is one of the following upper case words:
-+OK (the key was found, result contains the looked up value)
-+NOTFOUND (the key was not found, the result is empty)
-+TEMP (a temporary failure occured)
-+TIMEOUT (a timeout occured on the server side)
-+PERM (a permanent failure occured)
-+
-+In case of errors (status TEMP, TIMEOUT or PERM) the result fied may
-+contain an explanatory message.
-+
-+Example replies:
-+30:OK resolved.addess@example.com,
-+
-+in case of a successful lookup, or:
-+7:NOTFOUND,
-+
-+in case the key was not found, or:
-+54:TEMP this text explains that we had a temporary failure,
-+
-+in case of a failure.
-+
-+The socket map uses the same syntax as milters the specify the remote
-+endpoint. E.g.:
-+Ksocket mySocketMap inet:12345@127.0.0.1
-+
-+If multiple socket maps define the same remote endpoint, they will share
-+a single connection to this endpoint.
-
- +---------------+
- | COMPILE FLAGS |
-Index: sendmail/sendmail/sendmail/conf.c
-diff -u sendmail/sendmail/sendmail/conf.c:1.1.1.2 sendmail/sendmail/sendmail/conf.c:1.6
---- sendmail/conf.c Thu Jan 23 11:50:27 2003
-+++ sendmail/conf.c Fri Jan 24 15:31:59 2003
-@@ -622,6 +622,13 @@
- dequote_init, null_map_open, null_map_close,
- arith_map_lookup, null_map_store);
-
-+#if SOCKETMAP
-+ /* arbitrary daemons */
-+ MAPDEF("socket", NULL, MCF_ALIASOK,
-+ map_parseargs, socket_map_open, socket_map_close,
-+ socket_map_lookup, null_map_store);
-+#endif /* SOCKETMAP */
-+
- if (tTd(38, 2))
- {
- /* bogus map -- always return tempfail */
-Index: sendmail/sendmail/sendmail/map.c
-diff -u sendmail/sendmail/sendmail/map.c:1.1.1.2 sendmail/sendmail/sendmail/map.c:1.25
---- sendmail/map.c Thu Jan 23 11:50:27 2003
-+++ sendmail/map.c Tue Feb 25 14:57:14 2003
-@@ -66,6 +66,9 @@
- static bool ni_getcanonname __P((char *, int, int *));
- #endif /* NETINFO */
- static bool text_getcanonname __P((char *, int, int *));
-+#ifdef SOCKETMAP
-+static STAB * socket_map_findconn __P((const char*));
-+#endif /* SOCKETMAP */
-
- /* default error message for trying to open a map in write mode */
- #ifdef ENOSYS
-@@ -7395,3 +7398,646 @@
- *statp = EX_CONFIG;
- return NULL;
- }
-+
-+#ifdef SOCKETMAP
-+
-+# if NETINET || NETINET6
-+# include <arpa/inet.h>
-+# endif /* NETINET || NETINET6 */
-+
-+#define socket_map_next map_stack[0]
-+#define socket_map_previous map_stack[1]
-+
-+/*
-+** SOCKET_MAP_OPEN -- open socket table
-+*/
-+
-+bool
-+socket_map_open(map, mode)
-+ MAP *map;
-+ int mode;
-+{
-+ STAB *s;
-+
-+ int sock = 0;
-+ SOCKADDR_LEN_T addrlen = 0;
-+ int addrno = 0;
-+ int save_errno;
-+ char *p;
-+ char *colon;
-+ char *at;
-+ struct hostent *hp = NULL;
-+ SOCKADDR addr;
-+
-+ if (tTd(38, 2))
-+ sm_dprintf("socket_map_open(%s, %s, %d)\n",
-+ map->map_mname, map->map_file, mode);
-+
-+ mode &= O_ACCMODE;
-+
-+ /* sendmail doesn't have the ability to write to SOCKET (yet) */
-+ if (mode != O_RDONLY)
-+ {
-+ /* issue a pseudo-error message */
-+ errno = SM_EMAPCANTWRITE;
-+ return false;
-+ }
-+
-+ if (*map->map_file == '\0')
-+ {
-+ syserr("socket map \"%s\": empty or missing socket information",
-+ map->map_mname);
-+ return false;
-+ }
-+
-+ s = socket_map_findconn(map->map_file);
-+ if (s->s_socketmap != NULL)
-+ {
-+ /* Copy open connection */
-+ map->map_db1 = s->s_socketmap->map_db1;
-+
-+ /* Add this map as head of linked list */
-+ map->socket_map_next = s->s_socketmap;
-+ s->s_socketmap = map;
-+
-+ if (tTd(38, 2))
-+ sm_dprintf("using cached connection\n");
-+ return true;
-+ }
-+
-+ if (tTd(38, 2))
-+ sm_dprintf("opening new connection\n");
-+
-+
-+
-+ /* following code is ripped from milter.c */
-+
-+ /* protocol:filename or protocol:port@host */
-+ memset(&addr, '\0', sizeof addr);
-+ p = map->map_file;
-+ colon = strchr(p, ':');
-+ if (colon != NULL)
-+ {
-+ *colon = '\0';
-+
-+ if (*p == '\0')
-+ {
-+# if NETUNIX
-+ /* default to AF_UNIX */
-+ addr.sa.sa_family = AF_UNIX;
-+# else /* NETUNIX */
-+# if NETINET
-+ /* default to AF_INET */
-+ addr.sa.sa_family = AF_INET;
-+# else /* NETINET */
-+# if NETINET6
-+ /* default to AF_INET6 */
-+ addr.sa.sa_family = AF_INET6;
-+# else /* NETINET6 */
-+ /* no protocols available */
-+ syserr("socket map \"%s\": no valid socket protocols available",
-+ map->map_mname);
-+ return false;
-+# endif /* NETINET6 */
-+# endif /* NETINET */
-+# endif /* NETUNIX */
-+ }
-+# if NETUNIX
-+ else if (sm_strcasecmp(p, "unix") == 0 ||
-+ sm_strcasecmp(p, "local") == 0)
-+ addr.sa.sa_family = AF_UNIX;
-+# endif /* NETUNIX */
-+# if NETINET
-+ else if (sm_strcasecmp(p, "inet") == 0)
-+ addr.sa.sa_family = AF_INET;
-+# endif /* NETINET */
-+# if NETINET6
-+ else if (sm_strcasecmp(p, "inet6") == 0)
-+ addr.sa.sa_family = AF_INET6;
-+# endif /* NETINET6 */
-+ else
-+ {
-+# ifdef EPROTONOSUPPORT
-+ errno = EPROTONOSUPPORT;
-+# else /* EPROTONOSUPPORT */
-+ errno = EINVAL;
-+# endif /* EPROTONOSUPPORT */
-+ syserr("socket map \"%s\": unknown socket type %s",
-+ map->map_mname, p);
-+ return false;
-+ }
-+ *colon++ = ':';
-+ }
-+ else
-+ {
-+ /* default to AF_UNIX */
-+ addr.sa.sa_family = AF_UNIX;
-+ colon = p;
-+ }
-+
-+# if NETUNIX
-+ if (addr.sa.sa_family == AF_UNIX)
-+ {
-+ long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_EXECOK;
-+
-+ at = colon;
-+ if (strlen(colon) >= sizeof addr.sunix.sun_path)
-+ {
-+ syserr("socket map \"%s\": local socket name %s too long",
-+ map->map_mname, colon);
-+ return false;
-+ }
-+ errno = safefile(colon, RunAsUid, RunAsGid, RunAsUserName, sff,
-+ S_IRUSR|S_IWUSR, NULL);
-+
-+ if (errno != 0)
-+ {
-+ /* if not safe, don't create */
-+ syserr("socket map \"%s\": local socket name %s unsafe",
-+ map->map_mname, colon);
-+ return false;
-+ }
-+
-+ (void) sm_strlcpy(addr.sunix.sun_path, colon,
-+ sizeof addr.sunix.sun_path);
-+ addrlen = sizeof (struct sockaddr_un);
-+ }
-+ else
-+# endif /* NETUNIX */
-+# if NETINET || NETINET6
-+ if (false
-+# if NETINET
-+ || addr.sa.sa_family == AF_INET
-+# endif /* NETINET */
-+# if NETINET6
-+ || addr.sa.sa_family == AF_INET6
-+# endif /* NETINET6 */
-+ )
-+ {
-+ unsigned short port;
-+
-+ /* Parse port@host */
-+ at = strchr(colon, '@');
-+ if (at == NULL)
-+ {
-+ syserr("socket map \"%s\": bad address %s (expected port@host)",
-+ map->map_mname, colon);
-+ return false;
-+ }
-+ *at = '\0';
-+ if (isascii(*colon) && isdigit(*colon))
-+ port = htons((unsigned short) atoi(colon));
-+ else
-+ {
-+# ifdef NO_GETSERVBYNAME
-+ syserr("socket map \"%s\": invalid port number %s",
-+ map->map_mname, colon);
-+ return false;
-+# else /* NO_GETSERVBYNAME */
-+ register struct servent *sp;
-+
-+ sp = getservbyname(colon, "tcp");
-+ if (sp == NULL)
-+ {
-+ syserr("socket map \"%s\": unknown port name %s",
-+ map->map_mname, colon);
-+ return false;
-+ }
-+ port = sp->s_port;
-+# endif /* NO_GETSERVBYNAME */
-+ }
-+ *at++ = '@';
-+ if (*at == '[')
-+ {
-+ char *end;
-+
-+ end = strchr(at, ']');
-+ if (end != NULL)
-+ {
-+ bool found = false;
-+# if NETINET
-+ unsigned long hid = INADDR_NONE;
-+# endif /* NETINET */
-+# if NETINET6
-+ struct sockaddr_in6 hid6;
-+# endif /* NETINET6 */
-+
-+ *end = '\0';
-+# if NETINET
-+ if (addr.sa.sa_family == AF_INET &&
-+ (hid = inet_addr(&at[1])) != INADDR_NONE)
-+ {
-+ addr.sin.sin_addr.s_addr = hid;
-+ addr.sin.sin_port = port;
-+ found = true;
-+ }
-+# endif /* NETINET */
-+# if NETINET6
-+ (void) memset(&hid6, '\0', sizeof hid6);
-+ if (addr.sa.sa_family == AF_INET6 &&
-+ anynet_pton(AF_INET6, &at[1],
-+ &hid6.sin6_addr) == 1)
-+ {
-+ addr.sin6.sin6_addr = hid6.sin6_addr;
-+ addr.sin6.sin6_port = port;
-+ found = true;
-+ }
-+# endif /* NETINET6 */
-+ *end = ']';
-+ if (!found)
-+ {
-+ syserr("socket map \"%s\": Invalid numeric domain spec \"%s\"",
-+ map->map_mname, at);
-+ return false;
-+ }
-+ }
-+ else
-+ {
-+ syserr("socket map \"%s\": Invalid numeric domain spec \"%s\"",
-+ map->map_mname, at);
-+ return false;
-+ }
-+ }
-+ else
-+ {
-+ hp = sm_gethostbyname(at, addr.sa.sa_family);
-+ if (hp == NULL)
-+ {
-+ syserr("socket map \"%s\": Unknown host name %s",
-+ map->map_mname, at);
-+ return false;
-+ }
-+ addr.sa.sa_family = hp->h_addrtype;
-+ switch (hp->h_addrtype)
-+ {
-+# if NETINET
-+ case AF_INET:
-+ memmove(&addr.sin.sin_addr,
-+ hp->h_addr, INADDRSZ);
-+ addr.sin.sin_port = port;
-+ addrlen = sizeof (struct sockaddr_in);
-+ addrno = 1;
-+ break;
-+# endif /* NETINET */
-+
-+# if NETINET6
-+ case AF_INET6:
-+ memmove(&addr.sin6.sin6_addr,
-+ hp->h_addr, IN6ADDRSZ);
-+ addr.sin6.sin6_port = port;
-+ addrlen = sizeof (struct sockaddr_in6);
-+ addrno = 1;
-+ break;
-+# endif /* NETINET6 */
-+
-+ default:
-+ syserr("socket map \"%s\": Unknown protocol for %s (%d)",
-+ map->map_mname, at, hp->h_addrtype);
-+# if NETINET6
-+ freehostent(hp);
-+# endif /* NETINET6 */
-+ return false;
-+ }
-+ }
-+ }
-+ else
-+# endif /* NETINET || NETINET6 */
-+ {
-+ syserr("socket map \"%s\": unknown socket protocol", map->map_mname);
-+ return false;
-+ }
-+
-+ /* nope, actually connecting */
-+ for (;;)
-+ {
-+ sock = socket(addr.sa.sa_family, SOCK_STREAM, 0);
-+ if (sock < 0)
-+ {
-+ save_errno = errno;
-+ if (tTd(38, 5))
-+ sm_dprintf("socket map \"%s\": error creating socket: %s\n",
-+ map->map_mname,
-+ sm_errstring(save_errno));
-+# if NETINET6
-+ if (hp != NULL)
-+ freehostent(hp);
-+# endif /* NETINET6 */
-+ return false;
-+ }
-+
-+ if (connect(sock, (struct sockaddr *) &addr, addrlen) >= 0)
-+ break;
-+
-+ /* couldn't connect.... try next address */
-+ save_errno = errno;
-+ p = CurHostName;
-+ CurHostName = at;
-+ if (tTd(38, 5))
-+ sm_dprintf("socket_open (%s): open %s failed: %s\n",
-+ map->map_mname, at, sm_errstring(save_errno));
-+ CurHostName = p;
-+ (void) close(sock);
-+
-+ /* try next address */
-+ if (hp != NULL && hp->h_addr_list[addrno] != NULL)
-+ {
-+ switch (addr.sa.sa_family)
-+ {
-+# if NETINET
-+ case AF_INET:
-+ memmove(&addr.sin.sin_addr,
-+ hp->h_addr_list[addrno++],
-+ INADDRSZ);
-+ break;
-+# endif /* NETINET */
-+
-+# if NETINET6
-+ case AF_INET6:
-+ memmove(&addr.sin6.sin6_addr,
-+ hp->h_addr_list[addrno++],
-+ IN6ADDRSZ);
-+ break;
-+# endif /* NETINET6 */
-+
-+ default:
-+ if (tTd(38, 5))
-+ sm_dprintf("socket map \"%s\": Unknown protocol for %s (%d)\n",
-+ map->map_mname, at,
-+ hp->h_addrtype);
-+# if NETINET6
-+ freehostent(hp);
-+# endif /* NETINET6 */
-+ return false;
-+ }
-+ continue;
-+ }
-+ p = CurHostName;
-+ CurHostName = at;
-+ if (tTd(38, 5))
-+ sm_dprintf("socket map \"%s\": error connecting to socket map: %s\n",
-+ map->map_mname, sm_errstring(save_errno));
-+ CurHostName = p;
-+# if NETINET6
-+ if (hp != NULL)
-+ freehostent(hp);
-+# endif /* NETINET6 */
-+ return false;
-+ }
-+# if NETINET6
-+ if (hp != NULL)
-+ {
-+ freehostent(hp);
-+ hp = NULL;
-+ }
-+# endif /* NETINET6 */
-+ if ((map->map_db1 = (ARBPTR_T) sm_io_open(SmFtStdiofd,
-+ SM_TIME_DEFAULT,
-+ (void *) &sock,
-+ SM_IO_RDWR,
-+ NULL)) == NULL)
-+ {
-+ close(sock);
-+ if (tTd(38, 2))
-+ sm_dprintf("socket_open (%s): failed to create stream: %s\n",
-+ map->map_mname, sm_errstring(errno));
-+ return false;
-+ }
-+
-+ /* Save connection for reuse */
-+ s->s_socketmap = map;
-+ return true;
-+}
-+
-+/*
-+** SOCKET_MAP_FINDCONN -- find a SOCKET connection to the server
-+**
-+** Cache SOCKET connections based on the connection specifier
-+** and PID so we don't have multiple connections open to
-+** the same server for different maps. Need a separate connection
-+** per PID since a parent process may close the map before the
-+** child is done with it.
-+**
-+** Parameters:
-+** conn -- SOCKET map connection specifier
-+**
-+** Returns:
-+** Symbol table entry for the SOCKET connection.
-+*/
-+
-+static STAB *
-+socket_map_findconn(conn)
-+ const char *conn;
-+{
-+ char *format;
-+ char *nbuf;
-+ STAB *SM_NONVOLATILE s = NULL;
-+
-+ format = "%s%c%d";
-+ nbuf = sm_stringf_x(format,
-+ conn,
-+ CONDELSE,
-+ (int) CurrentPid);
-+ if (tTd(38, 20))
-+ sm_dprintf("socket_find_conn '%s'\n", nbuf);
-+ SM_TRY
-+ s = stab(nbuf, ST_SOCKETMAP, ST_ENTER);
-+ SM_FINALLY
-+ sm_free(nbuf);
-+ SM_END_TRY
-+ return s;
-+}
-+
-+/*
-+** SOCKET_MAP_CLOSE -- close the socket
-+*/
-+
-+void
-+socket_map_close(map)
-+ MAP *map;
-+{
-+ STAB *s;
-+ MAP *smap;
-+
-+ if (tTd(38, 20))
-+ sm_dprintf("socket_map_close(%s), pid=%d\n", map->map_file,(int) CurrentPid);
-+
-+ /* Check if already closed */
-+ if (!map->map_db1)
-+ {
-+ if (tTd(38, 20))
-+ sm_dprintf("socket_map_close(%s) already closed\n", map->map_file);
-+ return;
-+ }
-+
-+ sm_io_close((SM_FILE_T *)map->map_db1, SM_TIME_DEFAULT);
-+
-+ /* Mark all the maps that share the connection as closed */
-+ s = socket_map_findconn(map->map_file);
-+
-+ smap = s->s_socketmap;
-+
-+ while (smap != NULL)
-+ {
-+ MAP *next;
-+
-+ if (tTd(38, 2) && smap != map)
-+ sm_dprintf("socket_map_close(%s): closed %s (shared SOCKET connection)\n",
-+ map->map_mname, smap->map_mname);
-+
-+ smap->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
-+ smap->map_db1 = NULL;
-+ next = smap->socket_map_next;
-+ smap->socket_map_next = NULL;
-+ smap = next;
-+ }
-+
-+ s->s_socketmap = NULL;
-+}
-+
-+/*
-+** SOCKET_MAP_LOOKUP -- look up a datum in a SOCKET table
-+*/
-+
-+char *
-+socket_map_lookup(map, name, av, statp)
-+ MAP *map;
-+ char *name;
-+ char **av;
-+ int *statp;
-+{
-+ size_t nettolen;
-+ char *rval = NULL;
-+ SM_FILE_T *f = (SM_FILE_T *)map->map_db1;
-+
-+ if (tTd(38, 20))
-+ sm_dprintf("socket_map_lookup(%s, %s) %s\n",
-+ map->map_mname, name, map->map_file);
-+
-+ nettolen = strlen(map->map_mname) + 1 + strlen(name);
-+ if ((sm_io_fprintf(f, SM_TIME_DEFAULT, "%u:%s %s,",
-+ nettolen, map->map_mname, name) == SM_IO_EOF) || (sm_io_flush(f, SM_TIME_DEFAULT) != 0) ||
-+ (sm_io_error(f)))
-+ {
-+ syserr("socket_map_lookup(%s): failed to send lookup request",
-+ map->map_mname);
-+ *statp = EX_TEMPFAIL;
-+ socket_map_close(map);
-+ }
-+ else
-+ {
-+ size_t replylen;
-+
-+ if (sm_io_fscanf(f, SM_TIME_DEFAULT, "%9u", &replylen) != 1)
-+ {
-+ syserr("socket_map_lookup(%s): failed to read length parameter of reply",
-+ map->map_mname);
-+ *statp = EX_TEMPFAIL;
-+ socket_map_close(map);
-+ }
-+ else
-+ {
-+ /* XXX arbitrary limit for sanity */
-+ if (replylen > 1000000)
-+ {
-+ syserr("socket_map_lookup(%s): reply too long: %u",
-+ map->map_mname, replylen);
-+ /* *statp = EX_PROTOCOL; */
-+ *statp = EX_TEMPFAIL;
-+ socket_map_close(map);
-+ }
-+ else
-+ {
-+ if (sm_io_getc(f, SM_TIME_DEFAULT) != ':')
-+ {
-+ syserr("socket_map_lookup(%s): missing ':' in reply",
-+ map->map_mname);
-+ /* *statp = EX_PROTOCOL; */
-+ *statp = EX_TEMPFAIL;
-+ }
-+ else
-+ {
-+ size_t recvlen;
-+ char *replybuf = (char *) sm_malloc(replylen + 1);
-+ recvlen = sm_io_read(f, SM_TIME_DEFAULT,
-+ replybuf, replylen);
-+ if (recvlen < replylen)
-+ {
-+ syserr("socket_map_lookup(%s): received only %u of %u reply characters",
-+ map->map_mname, recvlen, replylen);
-+ *statp = EX_TEMPFAIL;
-+ socket_map_close(map);
-+ }
-+ else
-+ {
-+ if (sm_io_getc(f, SM_TIME_DEFAULT) != ',')
-+ {
-+ syserr("socket_map_lookup(%s): missing ',' in reply",
-+ map->map_mname);
-+ /* *statp = EX_PROTOCOL; */
-+ *statp = EX_TEMPFAIL;
-+ socket_map_close(map);
-+ }
-+ else
-+ {
-+ char *value;
-+ char *status = replybuf;
-+
-+ replybuf[recvlen] = '\0';
-+ value = strchr(replybuf, ' ');
-+ if (value != NULL)
-+ {
-+ *value = '\0';
-+ value++;
-+ }
-+
-+ if (strcmp(status, "OK") == 0)
-+ {
-+ *statp = EX_OK;
-+
-+ /* collect the return value */
-+ if (bitset(MF_MATCHONLY, map->map_mflags))
-+ rval = map_rewrite(map, name, strlen(name), NULL);
-+ else
-+ rval = map_rewrite(map, value, strlen(value), av);
-+ }
-+ else if(strcmp(status, "NOTFOUND") == 0)
-+ {
-+ *statp = EX_NOTFOUND;
-+ if (tTd(38, 20))
-+ sm_dprintf("socket_map_lookup(%s): %s not found\n",
-+ map->map_mname, name);
-+ }
-+ else
-+ {
-+ if (tTd(38, 5))
-+ sm_dprintf("socket_map_lookup(%s, %s): server returned error: type=%s, reason=%s\n",
-+ map->map_mname, name, status,
-+ value ? value : "");
-+ if ((strcmp(status, "TEMP") == 0) ||
-+ (strcmp(status, "TIMEOUT") == 0))
-+ {
-+ *statp = EX_TEMPFAIL;
-+ }
-+ else if(strcmp(status, "PERM") == 0)
-+ {
-+ *statp = EX_UNAVAILABLE;
-+ }
-+ else
-+ {
-+ *statp = EX_PROTOCOL;
-+ }
-+ }
-+ }
-+ }
-+
-+ sm_free(replybuf);
-+ }
-+ }
-+ }
-+ }
-+
-+ return rval;
-+}
-+
-+
-+#endif /* SOCKETMAP */
-Index: sendmail/sendmail/sendmail/sendmail.h
-diff -u sendmail/sendmail/sendmail/sendmail.h:1.1.1.2 sendmail/sendmail/sendmail/sendmail.h:1.3
---- sendmail/sendmail.h Thu Jan 23 11:50:27 2003
-+++ sendmail/sendmail.h Thu Jan 23 11:51:38 2003
-@@ -1382,6 +1382,9 @@
- #if LDAPMAP
- MAP *sv_lmap; /* Maps for LDAP connection */
- #endif /* LDAPMAP */
-+#if SOCKETMAP
-+ MAP *sv_socketmap; /* Maps for SOCKET connection */
-+#endif /* SOCKETMAP */
- #if MILTER
- struct milter *sv_milter; /* milter filter name */
- #endif /* MILTER */
-@@ -1413,8 +1416,12 @@
- #endif /* MILTER */
- #define ST_QUEUE 15 /* a queue entry */
-
-+#if SOCKETMAP
-+# define ST_SOCKETMAP 16 /* List head of maps for SOCKET connection */
-+#endif /* SOCKETMAP */
-+
- /* This entry must be last */
--#define ST_MCI 16 /* mailer connection info (offset) */
-+#define ST_MCI 17 /* mailer connection info (offset) */
-
- #define s_class s_value.sv_class
- #define s_address s_value.sv_addr
-@@ -1432,6 +1439,9 @@
- #if LDAPMAP
- # define s_lmap s_value.sv_lmap
- #endif /* LDAPMAP */
-+#if SOCKETMAP
-+# define s_socketmap s_value.sv_socketmap
-+#endif /* SOCKETMAP */
- #if MILTER
- # define s_milter s_value.sv_milter
- #endif /* MILTER */
-Index: sendmail/sendmail/sendmail/stab.c
-diff -u sendmail/sendmail/sendmail/stab.c:1.1.1.1 sendmail/sendmail/sendmail/stab.c:1.2
---- sendmail/stab.c Fri Oct 11 14:44:04 2002
-+++ sendmail/stab.c Wed Jan 22 18:57:22 2003
-@@ -173,6 +173,12 @@
- len = sizeof s->s_quegrp;
- break;
-
-+#if SOCKETMAP
-+ case ST_SOCKETMAP:
-+ len = sizeof s->s_socketmap;
-+ break;
-+#endif /* SOCKETMAP */
-+
- default:
- /*
- ** Each mailer has its own MCI stab entry: