$NetBSD: patch-aa,v 1.10 2007/10/27 11:30:37 martin Exp $ --- mini_sendmail.c.orig 2005-06-29 19:37:15.000000000 +0200 +++ mini_sendmail.c 2007-10-27 13:25:55.000000000 +0200 @@ -66,8 +66,13 @@ static char* fake_from; static int parse_message, verbose; #ifdef DO_MINUS_SP -static char* server; static short port; +struct server_entry { + const char *server; + short port; + struct server_entry *next; +}; +struct server_entry *servers; #endif /* DO_MINUS_SP */ static int timeout; static int sockfd1, sockfd2; @@ -84,7 +89,7 @@ #endif /* DO_RECEIVED */ static void parse_for_recipients( char* message ); static void add_recipient( char* recipient, int len ); -static int open_client_socket( void ); +static int open_client_socket( const char *server, short port ); static int read_response( void ); static void send_command( char* command ); static void send_data( char* data ); @@ -106,13 +111,15 @@ char from[1000]; int status; char buf[2000]; +#ifdef DO_MINUS_SP + struct server_entry *cur_server; +#endif /* Parse args. */ argv0 = argv[0]; fake_from = (char*) 0; parse_message = 0; #ifdef DO_MINUS_SP - server = "127.0.0.1"; port = SMTP_PORT; #endif /* DO_MINUS_SP */ verbose = 0; @@ -122,22 +129,36 @@ { if ( strncmp( argv[argn], "-f", 2 ) == 0 && argv[argn][2] != '\0' ) fake_from = &(argv[argn][2]); + else if ( strncmp( argv[argn], "-F", 2 ) == 0 && argv[argn][2] != '\0' ) + ; /* ignore for sendmail compatibility, should set From: header */ + else if ( strncmp( argv[argn], "-or", 3 ) == 0 && argv[argn][3] != '\0' ) + ; /* ignore for sendmail compatibility (sets some timeout) */ else if ( strcmp( argv[argn], "-t" ) == 0 ) parse_message = 1; #ifdef DO_MINUS_SP - else if ( strncmp( argv[argn], "-s", 2 ) == 0 && argv[argn][2] != '\0' ) - server = &(argv[argn][2]); - else if ( strncmp( argv[argn], "-p", 2 ) == 0 && argv[argn][2] != '\0' ) + else if ( strncmp( argv[argn], "-s", 2 ) == 0 && argv[argn][2] != '\0' ) { + cur_server = malloc(sizeof(struct server_entry)); + cur_server->server = &(argv[argn][2]); + cur_server->port = port; + cur_server->next = servers; + servers = cur_server; + } else if ( strncmp( argv[argn], "-p", 2 ) == 0 && argv[argn][2] != '\0' ) port = atoi( &(argv[argn][2]) ); #endif /* DO_MINUS_SP */ else if ( strncmp( argv[argn], "-T", 2 ) == 0 && argv[argn][2] != '\0' ) timeout = atoi( &(argv[argn][2]) ); else if ( strcmp( argv[argn], "-v" ) == 0 ) verbose = 1; + else if ( strcmp( argv[argn], "-oeq" ) == 0 ) + verbose = 0; else if ( strcmp( argv[argn], "-i" ) == 0 ) ; /* ignore */ else if ( strcmp( argv[argn], "-oi" ) == 0 ) ; /* ignore */ + else if ( strcmp( argv[argn], "-odi" ) == 0 ) + ; /* ignore */ + else if ( strcmp( argv[argn], "-oem" ) == 0 ) + ; /* ignore */ else if ( strcmp( argv[argn], "--" ) == 0 ) ; /* ignore */ else @@ -186,8 +207,21 @@ (void) signal( SIGALRM, sigcatch ); + if (!servers) { + static const char default_server[] = "127.0.0.1"; + servers = malloc(sizeof(struct server_entry)); + servers->server = default_server; + servers->port = port; + servers->next = NULL; + } + (void) alarm( timeout ); - sockfd1 = open_client_socket(); + for (cur_server = servers; cur_server; cur_server = cur_server->next) { + sockfd1 = open_client_socket(cur_server->server, cur_server->port); + if (sockfd1 >= 0) break; + } + if (sockfd1 == -1) + show_error("could not open SMTP socket"); sockfd2 = dup( sockfd1 ); sockrfp = fdopen( sockfd1, "r" ); @@ -507,14 +541,24 @@ switch ( *cp ) { case '\n': - add_recipient( recip, ( cp - recip ) ); - state = ST_BOL; - if ( bcc != (char*) 0 ) + /* peek ahead for continuation line */ + switch (cp[1]) { - /* Elide the Bcc: line, and reset cp. */ - (void) strcpy( bcc, cp + 1 ); - cp = bcc - 1; - bcc = (char*) 0; + case ' ': + case '\t': + break; + + default: + add_recipient( recip, ( cp - recip ) ); + state = ST_BOL; + if ( bcc != (char*) 0 ) + { + /* Elide the Bcc: line, and reset cp. */ + (void) strcpy( bcc, cp + 1 ); + cp = bcc - 1; + bcc = (char*) 0; + } + break; } break; case ',': @@ -532,25 +576,43 @@ add_recipient( char* recipient, int len ) { char buf[1000]; + char *first; int status; + int i; + /* Skip leading whitespace. */ - while ( len > 0 && ( *recipient == ' ' || *recipient == '\t' ) ) + while ( len > 0 && ( *recipient == ' ' || *recipient == '\t' || + *recipient == '\n') ) { ++recipient; --len; } - /* Strip off any angle brackets. */ - while ( len > 0 && *recipient == '<' ) + first = recipient; + /* search for angle bracket */ + + while (first < recipient+len && *first != '<') { - ++recipient; - --len; + ++first; } - while ( len > 0 && recipient[len-1] == '>' ) - --len; + + if (*first == '<') + { + len -= first + 1 - recipient; + recipient = first + 1; + + while (len > 2 && recipient[--len] != '>') + ; /* nothing */ + + } (void) snprintf( buf, sizeof(buf), "RCPT TO:<%.*s>", len, recipient ); + for (i=0; i