diff -urN sendmail-8.10.0/sendmail/map.c sendmail-8.10.0.wsg.20000308/sendmail/map.c --- sendmail-8.10.0/sendmail/map.c Fri Feb 25 23:35:01 2000 +++ sendmail-8.10.0.wsg.20000308/sendmail/map.c Wed Mar 8 01:14:37 2000 @@ -4250,8 +4250,6 @@ ** Contributed by Mark D. Roth . Contact him for support. */ -# include -# include /* ** PH_MAP_PARSEARGS -- parse ph map definition args. @@ -4262,9 +4260,8 @@ MAP *map; char *args; { - int i; - register int done; PH_MAP_STRUCT *pmap = NULL; + register int done; register char *p = args; pmap = (PH_MAP_STRUCT *) xalloc(sizeof *pmap); @@ -4272,10 +4269,9 @@ /* defaults */ pmap->ph_servers = NULL; pmap->ph_field_list = NULL; - pmap->ph_to_server = NULL; - pmap->ph_from_server = NULL; - pmap->ph_sockfd = -1; + pmap->ph = NULL; pmap->ph_timeout = 0; + pmap->ph_fastclose = 0; map->map_mflags |= MF_TRY0NULL|MF_TRY1NULL; for (;;) @@ -4327,13 +4323,11 @@ map->map_tapp = ++p; break; -#if _FFR_PHMAP_TIMEOUT case 'l': while (isascii(*++p) && isspace(*p)) continue; pmap->ph_timeout = atoi(p); break; -#endif /* _FFR_PHMAP_TIMEOUT */ case 'S': map->map_spacesub = *++p; @@ -4386,8 +4380,6 @@ if (pmap->ph_field_list != NULL) pmap->ph_field_list = newstr(ph_map_dequote(pmap->ph_field_list)); - else - pmap->ph_field_list = DEFAULT_PH_MAP_FIELDS; if (pmap->ph_servers != NULL) pmap->ph_servers = newstr(ph_map_dequote(pmap->ph_servers)); @@ -4401,50 +4393,24 @@ return TRUE; } -#if _FFR_PHMAP_TIMEOUT /* ** PH_MAP_CLOSE -- close the connection to the ph server */ -static void -ph_map_safeclose(map) +void +ph_map_close(map) MAP *map; { - int save_errno = errno; PH_MAP_STRUCT *pmap; pmap = (PH_MAP_STRUCT *)map->map_db1; - if (pmap->ph_sockfd != -1) - { - (void) close(pmap->ph_sockfd); - pmap->ph_sockfd = -1; - } - if (pmap->ph_from_server != NULL) - { - (void) fclose(pmap->ph_from_server); - pmap->ph_from_server = NULL; - } - if (pmap->ph_to_server != NULL) - { - (void) fclose(pmap->ph_to_server); - pmap->ph_to_server = NULL; - } + if (pmap->ph) + ph_close(pmap->ph, pmap->ph_fastclose); + map->map_mflags &= ~(MF_OPEN|MF_WRITABLE); - errno = save_errno; } -void -ph_map_close(map) - MAP *map; -{ - PH_MAP_STRUCT *pmap; - - pmap = (PH_MAP_STRUCT *)map->map_db1; - (void) fprintf(pmap->ph_to_server, "quit\n"); - (void) fflush(pmap->ph_to_server); - ph_map_safeclose(map); -} static jmp_buf PHTimeout; @@ -4455,25 +4421,35 @@ { longjmp(PHTimeout, 1); } -#else /* _FFR_PHMAP_TIMEOUT */ -/* -** PH_MAP_CLOSE -- close the connection to the ph server -*/ -void -ph_map_close(map) - MAP *map; + + + +static void +ph_map_send_debug(text) + char *text; { - PH_MAP_STRUCT *pmap; + if (LogLevel > 9) + sm_syslog(LOG_NOTICE, CurEnv->e_id, + "ph_map_send_debug: ==> %s", text); + if (tTd(38, 20)) + dprintf("ph_map_send_debug: ==> %s", text); +} - pmap = (PH_MAP_STRUCT *)map->map_db1; - CloseQi(pmap->ph_to_server, pmap->ph_from_server); - pmap->ph_to_server = NULL; - pmap->ph_from_server = NULL; + +static void +ph_map_recv_debug(text) + char *text; +{ + if (LogLevel > 10) + sm_syslog(LOG_NOTICE, CurEnv->e_id, + "ph_map_recv_debug: <== %s", text); + if (tTd(38, 21)) + dprintf("ph_map_recv_debug: <== %s\n", text); } -#endif /* _FFR_PHMAP_TIMEOUT */ - /* + +/* ** PH_MAP_OPEN -- sub for opening PH map */ bool @@ -4481,16 +4457,10 @@ MAP *map; int mode; { -#if !_FFR_PHMAP_TIMEOUT - int save_errno = 0; -#endif /* !_FFR_PHMAP_TIMEOUT */ - int j; - char *hostlist, *tmp; - QIR *server_data = NULL; PH_MAP_STRUCT *pmap; -#if _FFR_PHMAP_TIMEOUT register EVENT *ev = NULL; -#endif /* _FFR_PHMAP_TIMEOUT */ + int ph_port, save_errno = 0; + char *hostlist, *host, *tmp; if (tTd(38, 2)) dprintf("ph_map_open(%s)\n", map->map_mname); @@ -4513,10 +4483,23 @@ pmap = (PH_MAP_STRUCT *)map->map_db1; + /* try each host in the list */ hostlist = newstr(pmap->ph_servers); - tmp = strtok(hostlist, " "); - do { -#if _FFR_PHMAP_TIMEOUT + for (host = strtok(hostlist, " "); + host; + host = strtok(NULL, " ")) + { + /* determine port for this host */ + tmp = strchr(host, ':'); + if (tmp) + { + *tmp++ = '\0'; + ph_port = atoi(tmp); + } + else + ph_port = 0; + + /* set timeout */ if (pmap->ph_timeout != 0) { if (setjmp(PHTimeout) != 0) @@ -4525,7 +4508,7 @@ if (LogLevel > 1) sm_syslog(LOG_NOTICE, CurEnv->e_id, "timeout connecting to PH server %.100s", - tmp); + host); # ifdef ETIMEDOUT errno = ETIMEDOUT; # else /* ETIMEDOUT */ @@ -4535,57 +4518,28 @@ } ev = setevent(pmap->ph_timeout, ph_timeout_func, 0); } - if (!OpenQiSock(tmp, &(pmap->ph_sockfd)) && - !Sock2FILEs(pmap->ph_sockfd, &(pmap->ph_to_server), - &(pmap->ph_from_server)) && - fprintf(pmap->ph_to_server, "id sendmail+phmap\n") >= 0 && - fflush(pmap->ph_to_server) == 0 && - (server_data = ReadQi(pmap->ph_from_server, &j)) != NULL && - server_data->code == 200) + + /* open connection to server */ + if (!ph_open(&(pmap->ph), host, ph_port, PH_ROUNDROBIN) && + !ph_id(pmap->ph, "sendmail+phmap")) { if (ev != NULL) clrevent(ev); - FreeQIR(server_data); -#else /* _FFR_PHMAP_TIMEOUT */ - if (OpenQi(tmp, &(pmap->ph_to_server), - &(pmap->ph_from_server)) >= 0) - { - if (fprintf(pmap->ph_to_server, - "id sendmail+phmap\n") < 0 || - fflush(pmap->ph_to_server) < 0 || - (server_data = ReadQi(pmap->ph_from_server, - &j)) == NULL || - server_data->code != 200) - { - save_errno = errno; - CloseQi(pmap->ph_to_server, - pmap->ph_from_server); - continue; - } - if (server_data != NULL) - FreeQIR(server_data); -#endif /* _FFR_PHMAP_TIMEOUT */ free(hostlist); + ph_set_sendhook(pmap->ph, ph_map_send_debug); + ph_set_recvhook(pmap->ph, ph_map_recv_debug); return TRUE; } -#if _FFR_PHMAP_TIMEOUT + ph_map_open_abort: + save_errno = errno; if (ev != NULL) clrevent(ev); - ph_map_safeclose(map); - if (server_data != NULL) - { - FreeQIR(server_data); - server_data = NULL; - } -#else /* _FFR_PHMAP_TIMEOUT */ - save_errno = errno; -#endif /* _FFR_PHMAP_TIMEOUT */ - } while (tmp = strtok(NULL, " ")); + pmap->ph_fastclose = PH_FASTCLOSE; + ph_map_close(map); + errno = save_errno; + } -#if !_FFR_PHMAP_TIMEOUT - errno = save_errno; -#endif /* !_FFR_PHMAP_TIMEOUT */ if (!bitset(MF_OPTIONAL, map->map_mflags)) { if (errno == 0 && !bitset(MF_NODEFER,map->map_mflags)) @@ -4603,10 +4557,6 @@ ** PH_MAP_LOOKUP -- look up key from ph server */ -#if _FFR_PHMAP_TIMEOUT -# define MAX_PH_FIELDS 20 -#endif /* _FFR_PHMAP_TIMEOUT */ - char * ph_map_lookup(map, key, args, pstat) MAP *map; @@ -4614,25 +4564,15 @@ char **args; int *pstat; { - int j; - size_t sz; - char *tmp, *tmp2; - char *message = NULL, *field = NULL, *fmtkey; - QIR *server_data = NULL; - QIR *qirp; - char keybuf[MAXKEY + 1], fieldbuf[101]; -#if _FFR_PHMAP_TIMEOUT - QIR *hold_data[MAX_PH_FIELDS]; - int hold_data_idx = 0; + int i, save_errno = 0; register EVENT *ev = NULL; -#endif /* _FFR_PHMAP_TIMEOUT */ PH_MAP_STRUCT *pmap; + char *value = NULL; pmap = (PH_MAP_STRUCT *)map->map_db1; - *pstat = EX_OK; -#if _FFR_PHMAP_TIMEOUT + /* set timeout */ if (pmap->ph_timeout != 0) { if (setjmp(PHTimeout) != 0) @@ -4653,248 +4593,40 @@ ev = setevent(pmap->ph_timeout, ph_timeout_func, 0); } -#endif /* _FFR_PHMAP_TIMEOUT */ - /* check all relevant fields */ - tmp = pmap->ph_field_list; - do { -#if _FFR_PHMAP_TIMEOUT - server_data = NULL; -#endif /* _FFR_PHMAP_TIMEOUT */ - while (isascii(*tmp) && isspace(*tmp)) - tmp++; - if (*tmp == '\0') - break; - sz = strcspn(tmp, " ") + 1; - if (sz > sizeof fieldbuf) - sz = sizeof fieldbuf; - (void) strlcpy(fieldbuf, tmp, sz); - field = fieldbuf; - tmp += sz; - - (void) strlcpy(keybuf, key, sizeof keybuf); - fmtkey = keybuf; - if (strcmp(field, "alias") == 0) - { - /* - ** for alias lookups, replace any punctuation - ** characters with '-' - */ - - for (tmp2 = fmtkey; *tmp2 != '\0'; tmp2++) - { - if (isascii(*tmp2) && ispunct(*tmp2)) - *tmp2 = '-'; - } - tmp2 = field; - } - else if (strcmp(field,"spacedname") == 0) - { - /* - ** for "spaced" name lookups, replace any - ** punctuation characters with a space - */ - - for (tmp2 = fmtkey; *tmp2 != '\0'; tmp2++) - { - if (isascii(*tmp2) && ispunct(*tmp2) && - *tmp2 != '*') - *tmp2 = ' '; - } - tmp2 = &(field[6]); - } - else - tmp2 = field; - - if (LogLevel > 9) - sm_syslog(LOG_NOTICE, CurEnv->e_id, - "ph_map_lookup: query %s=\"%s\" return email", - tmp2, fmtkey); - if (tTd(38, 20)) - dprintf("ph_map_lookup: query %s=\"%s\" return email\n", - tmp2, fmtkey); - - j = 0; - - if (fprintf(pmap->ph_to_server, "query %s=%s return email\n", - tmp2, fmtkey) < 0) - message = "qi query command failed"; - else if (fflush(pmap->ph_to_server) < 0) - message = "qi fflush failed"; - else if ((server_data = ReadQi(pmap->ph_from_server, - &j)) == NULL) - message = "ReadQi() returned NULL"; - -#if _FFR_PHMAP_TIMEOUT - if ((hold_data[hold_data_idx] = server_data) != NULL) - { - /* save pointer for later free() */ - hold_data_idx++; - } -#endif /* _FFR_PHMAP_TIMEOUT */ - - if (server_data == NULL || - (server_data->code >= 400 && - server_data->code < 500)) - { - /* temporary failure */ - *pstat = EX_TEMPFAIL; -#if _FFR_PHMAP_TIMEOUT - break; -#else /* _FFR_PHMAP_TIMEOUT */ - if (server_data != NULL) - { - FreeQIR(server_data); - server_data = NULL; - } - return NULL; -#endif /* _FFR_PHMAP_TIMEOUT */ - } - - /* - ** if we found a single match, break out. - ** otherwise, try the next field. - */ - - if (j == 1) - break; - - /* - ** check for a single response which is an error: - ** ReadQi() doesn't set j on error responses, - ** but we should stop here instead of moving on if - ** it happens (e.g., alias found but email field empty) - */ - - for (qirp = server_data; - qirp != NULL && qirp->code < 0; - qirp++) - { - if (tTd(38, 20)) - dprintf("ph_map_lookup: QIR: %d:%d:%d:%s\n", - qirp->code, qirp->subcode, qirp->field, - (qirp->message ? qirp->message - : "[NULL]")); - if (qirp->code <= -500) - { - j = 0; - goto ph_map_lookup_abort; - } - } - -#if _FFR_PHMAP_TIMEOUT - } while (*tmp != '\0' && hold_data_idx < MAX_PH_FIELDS); -#else /* _FFR_PHMAP_TIMEOUT */ - } while (*tmp != '\0'); -#endif /* _FFR_PHMAP_TIMEOUT */ + /* perform lookup */ + i = ph_email_resolve(pmap->ph, key, pmap->ph_field_list, &value); + if (i == -1) + save_errno = errno; + else if (i == 1) + *pstat = EX_UNAVAILABLE; ph_map_lookup_abort: -#if _FFR_PHMAP_TIMEOUT if (ev != NULL) clrevent(ev); /* ** Return EX_TEMPFAIL if the timer popped - ** or we got a temporary PH error */ if (*pstat == EX_TEMPFAIL) - ph_map_safeclose(map); - - /* if we didn't find a single match, bail out */ - if (*pstat == EX_OK && j != 1) - *pstat = EX_UNAVAILABLE; + { + save_errno = errno; + ph_map_close(map); + errno = save_errno; + } if (*pstat == EX_OK) { - /* - ** skip leading whitespace and chop at first address - */ - - for (tmp = server_data->message; - isascii(*tmp) && isspace(*tmp); - tmp++) - continue; - - for (tmp2 = tmp; *tmp2 != '\0'; tmp2++) - { - if (isascii(*tmp2) && isspace(*tmp2)) - { - *tmp2 = '\0'; - break; - } - } - if (tTd(38,20)) - dprintf("ph_map_lookup: %s => %s\n", key, tmp); + dprintf("ph_map_lookup: %s => %s\n", key, value); if (bitset(MF_MATCHONLY, map->map_mflags)) - message = map_rewrite(map, key, strlen(key), NULL); + return map_rewrite(map, key, strlen(key), NULL); else - message = map_rewrite(map, tmp, strlen(tmp), args); - } - - /* - ** Deferred free() of returned server_data values - ** the deferral is to avoid the risk of a free() being - ** interrupted by the event timer. By now the timeout event - ** has been cleared and none of the data is still in use. - */ - - while (--hold_data_idx >= 0) - { - if (hold_data[hold_data_idx] != NULL) - FreeQIR(hold_data[hold_data_idx]); + return map_rewrite(map, value, strlen(value), args); } - if (*pstat == EX_OK) - return message; - return NULL; -#else /* _FFR_PHMAP_TIMEOUT */ - /* if we didn't find a single match, bail out */ - if (j != 1) - { - *pstat = EX_UNAVAILABLE; - if (server_data != NULL) - { - FreeQIR(server_data); - server_data = NULL; - } - return NULL; - } - - /* - ** skip leading whitespace and chop at first address - */ - - for (tmp = server_data->message; - isascii(*tmp) && isspace(*tmp); - tmp++) - continue; - - for (tmp2 = tmp; *tmp2 != '\0'; tmp2++) - { - if (isascii(*tmp2) && isspace(*tmp2)) - { - *tmp2 = '\0'; - break; - } - } - - if (tTd(38,20)) - dprintf("ph_map_lookup: %s => %s\n", key, tmp); - - if (bitset(MF_MATCHONLY, map->map_mflags)) - message = map_rewrite(map, key, strlen(key), NULL); - else - message = map_rewrite(map, tmp, strlen(tmp), args); - if (server_data != NULL) - { - FreeQIR(server_data); - server_data = NULL; - } - return message; -#endif /* _FFR_PHMAP_TIMEOUT */ } #endif /* PH_MAP */ /* diff -urN sendmail-8.10.0/sendmail/sendmail.h sendmail-8.10.0.wsg.20000308/sendmail/sendmail.h --- sendmail-8.10.0/sendmail/sendmail.h Sat Feb 26 01:30:06 2000 +++ sendmail-8.10.0.wsg.20000308/sendmail/sendmail.h Wed Mar 8 00:49:46 2000 @@ -949,18 +949,18 @@ */ #ifdef PH_MAP + +# include + struct ph_map_struct { char *ph_servers; /* list of ph servers */ char *ph_field_list; /* list of fields to search for match */ - FILE *ph_to_server; - FILE *ph_from_server; - int ph_sockfd; - time_t ph_timeout; + PH *ph; /* PH server handle */ + int ph_fastclose; /* send "quit" command on close */ + time_t ph_timeout; /* timeout interval */ }; typedef struct ph_map_struct PH_MAP_STRUCT; - -# define DEFAULT_PH_MAP_FIELDS "alias callsign name spacedname" #endif /* PH_MAP */ /* ** Process List (proclist)