adea56d4bd
enough to allow NetBSD's cron to send mail.
214 lines
5.8 KiB
Text
214 lines
5.8 KiB
Text
$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<sizeof(buf); i++)
|
|
+ {
|
|
+ if (buf[i] == '\n')
|
|
+ buf[i] = ' ';
|
|
+ }
|
|
send_command( buf );
|
|
status = read_response();
|
|
if ( status != 250 && status != 251 )
|
|
@@ -569,7 +631,7 @@
|
|
#endif
|
|
|
|
static int
|
|
-open_client_socket( void )
|
|
+open_client_socket(const char *server, short port)
|
|
{
|
|
#ifdef USE_IPV6
|
|
struct sockaddr_in6 sa;
|
|
@@ -744,10 +806,10 @@
|
|
|
|
sockfd = socket( sock_family, sock_type, sock_protocol );
|
|
if ( sockfd < 0 )
|
|
- show_error( "socket" );
|
|
+ return -1;
|
|
|
|
if ( connect( sockfd, (struct sockaddr*) &sa, sa_len ) < 0 )
|
|
- show_error( "connect" );
|
|
+ return -1;
|
|
|
|
return sockfd;
|
|
}
|