diff -bur fetchmail-5.9.11-orig/sink.c fetchmail-5.9.11-sg/sink.c --- fetchmail-5.9.11-orig/sink.c Mon Apr 1 02:46:57 2002 +++ fetchmail-5.9.11-sg/sink.c Mon May 27 03:21:50 2002 @@ -606,6 +606,53 @@ /* this is experimental and will be removed if double bounces are reported */ #define EXPLICIT_BOUNCE_ON_BAD_ADDRESS + +const char *is_quad(const char *q) +/* Check if the string passed in points to what could be one quad of a + * dotted-quad IP address. Requirements are that the string is not a + * NULL pointer, begins with a period (which is skipped) or a digit + * and ends with a period or a NULL. If these requirements are met, a + * pointer to the last character (the period or the NULL character) is + * returned; otherwise NULL. + */ +{ + const char *r; + + if (!q || !*q) + return NULL; + if (*q == '.') + q++; + for(r=q;isdigit(*r);r++) + ; + if ( ((*r) && (*r != '.')) || ((r-q) < 1) || ((r-q)>3) ) + return NULL; + /* Make sure quad is < 255 */ + if ( (r-q) == 3) + if (*q > '2') + return NULL; + else if (*q == '2') + { + if (*(q+1) > '5') + return NULL; + else if (*(q+1) == '5') + { + if (*(q+2) > '5') + return NULL; + } + } + return r; +} + +int is_dottedquad(const char *hostname) +/* Returns a true value if the passed in string looks like an IP + * address in dotted-quad form, and a false value otherwise. + */ + +{ + return ((hostname=is_quad(is_quad(is_quad(is_quad(hostname))))) != NULL) && + (*hostname == '\0'); +} + static int open_smtp_sink(struct query *ctl, struct msgblk *msg, int *good_addresses, int *bad_addresses) /* open an SMTP stream */ @@ -662,24 +709,48 @@ */ if (!msg->return_path[0] || (0 == strcmp(msg->return_path, "@"))) { + if (is_dottedquad(ctl->server.truename)) + { +#ifdef HAVE_SNPRINTF + snprintf(addr, sizeof(addr), +#else + sprintf(addr, +#endif /* HAVE_SNPRINTF */ + "%s(_at_)[%s]", ctl->remotename, ctl->server.truename); + } + else + { #ifdef HAVE_SNPRINTF snprintf(addr, sizeof(addr), #else sprintf(addr, #endif /* HAVE_SNPRINTF */ "%s(_at_)%s", ctl->remotename, ctl->server.truename); + } ap = addr; } else if (strchr(msg->return_path,'@') || strchr(msg->return_path,'!')) ap = msg->return_path; else /* in case Return-Path existed but was local */ { + if (is_dottedquad(ctl->server.truename)) + { +#ifdef HAVE_SNPRINTF + snprintf(addr, sizeof(addr), +#else + sprintf(addr, +#endif /* HAVE_SNPRINTF */ + "%s(_at_)[%s]", msg->return_path, ctl->server.truename); + } + else + { #ifdef HAVE_SNPRINTF snprintf(addr, sizeof(addr), #else sprintf(addr, #endif /* HAVE_SNPRINTF */ "%s(_at_)%s", msg->return_path, ctl->server.truename); + } ap = addr; }