Patch to mini_sendmail: - adds logging to syslog (facility LOG_MAIL) - adds logging of message info (from,to,size) - adds ability to send mail... ;) --- mini_sendmail.c.orig Wed Jun 29 20:37:15 2005 +++ mini_sendmail.c Fri Aug 19 12:46:44 2005 @@ -34,6 +34,8 @@ #define DO_GETPWUID /* whether to try a getpwuid() if getlogin() fails */ #define DO_MINUS_SP /* whether to implement the -s and -p flags */ #define DO_DNS /* whether to do a name lookup on -s, or just IP# */ +#define DO_SYSLOG /* log to syslog */ +#define DO_LOG_INFO /* log (to syslog) message info */ #include @@ -45,6 +47,9 @@ #include #include #include +#ifdef DO_SYSLOG +#include +#endif /* DO_SYSLOG */ #ifdef DO_RECEIVED #include @@ -74,6 +79,8 @@ static FILE* sockrfp; static FILE* sockwfp; static int got_a_recipient; +static char from[1000]; +static char* message; /* Forwards. */ @@ -97,13 +104,11 @@ main( int argc, char** argv ) { int argn; - char* message; #ifdef DO_RECEIVED char* received; #endif /* DO_RECEIVED */ char* username; char hostname[500]; - char from[1000]; int status; char buf[2000]; @@ -152,12 +157,20 @@ struct passwd* pw = getpwuid( getuid() ); if ( pw == (struct passwd*) 0 ) { +#ifdef DO_SYSLOG + syslog( LOG_ERR|LOG_MAIL, "can't determine username" ); +#else /* DO_SYSLOG */ (void) fprintf( stderr, "%s: can't determine username\n", argv0 ); +#endif /* DO_SYSLOG */ exit( 1 ); } username = pw->pw_name; #else /* DO_GETPWUID */ +#ifdef DO_SYSLOG + syslog( LOG_ERR|LOG_MAIL, "can't determine username" ); +#else /* DO_SYSLOG */ (void) fprintf( stderr, "%s: can't determine username\n", argv0 ); +#endif /* DO_SYSLOG */ exit( 1 ); #endif /* DO_GETPWUID */ } @@ -204,8 +217,12 @@ status = read_response(); if ( status != 220 ) { +#ifdef DO_SYSLOG + syslog( LOG_ERR|LOG_MAIL, "unexpected initial greeting %d", status ); +#else /* DO_SYSLOG */ (void) fprintf( stderr, "%s: unexpected initial greeting %d\n", argv0, status ); +#endif /* DO_SYSLOG */ exit( 1 ); } @@ -214,9 +231,14 @@ status = read_response(); if ( status != 250 ) { +#ifdef DO_SYSLOG + syslog( LOG_ERR|LOG_MAIL, "unexpected response %d to HELO command", + status ); +#else /* DO_SYSLOG */ (void) fprintf( stderr, "%s: unexpected response %d to HELO command\n", argv0, status ); +#endif /* DO_SYSLOG */ exit( 1 ); } @@ -225,9 +247,14 @@ status = read_response(); if ( status != 250 ) { +#ifdef DO_SYSLOG + syslog( LOG_ERR|LOG_MAIL, "unexpected response %d to MAIL FROM command", + status ); +#else /* DO_SYSLOG */ (void) fprintf( stderr, "%s: unexpected response %d to MAIL FROM command\n", argv0, status ); +#endif /* DO_SYSLOG */ exit( 1 ); } @@ -238,7 +265,11 @@ parse_for_recipients( message ); if ( ! got_a_recipient ) { +#ifdef DO_SYSLOG + syslog( LOG_ERR|LOG_MAIL, "no recipients found" ); +#else /* DO_SYSLOG */ (void) fprintf( stderr, "%s: no recipients found\n", argv0 ); +#endif /* DO_SYSLOG */ exit( 1 ); } @@ -246,9 +277,14 @@ status = read_response(); if ( status != 354 ) { +#ifdef DO_SYSLOG + syslog( LOG_ERR|LOG_MAIL, "unexpected response %d to DATA command", + status ); +#else /* DO_SYSLOG */ (void) fprintf( stderr, "%s: unexpected response %d to DATA command\n", argv0, status ); +#endif /* DO_SYSLOG */ exit( 1 ); } @@ -260,17 +296,26 @@ status = read_response(); if ( status != 250 ) { +#ifdef DO_SYSLOG + syslog( LOG_ERR|LOG_MAIL, "unexpected response %d to DATA", status ); +#else /* DO_SYSLOG */ (void) fprintf( stderr, "%s: unexpected response %d to DATA\n", argv0, status ); +#endif /* DO_SYSLOG */ exit( 1 ); } send_command( "QUIT" ); status = read_response(); if ( status != 221 ) +#ifdef DO_SYSLOG + syslog( LOG_ERR|LOG_MAIL, + "unexpected response %d to QUIT command - ignored", status ); +#else /* DO_SYSLOG */ (void) fprintf( stderr, "%s: unexpected response %d to QUIT command - ignored\n", argv0, status ); +#endif /* DO_SYSLOG */ (void) close( sockfd1 ); (void) close( sockfd2 ); @@ -307,7 +352,11 @@ message = (char*) malloc( message_size ); if ( message == (char*) 0 ) { +#ifdef DO_SYSLOG + syslog( LOG_ERR|LOG_MAIL, "out of memory" ); +#else /* DO_SYSLOG */ (void) fprintf( stderr, "%s: out of memory\n", argv0 ); +#endif /* DO_SYSLOG */ exit( 1 ); } message_len = 0; @@ -323,7 +372,11 @@ message = (char*) realloc( (void*) message, message_size ); if ( message == (char*) 0 ) { +#ifdef DO_SYSLOG + syslog( LOG_ERR|LOG_MAIL, "out of memory" ); +#else /* DO_SYSLOG */ (void) fprintf( stderr, "%s: out of memory\n", argv0 ); +#endif /* DO_SYSLOG */ exit( 1 ); } } @@ -354,7 +407,11 @@ received = (char*) malloc( received_size ); if ( received == (char*) 0 ) { +#ifdef DO_SYSLOG + syslog( LOG_ERR|LOG_MAIL, "out of memory" ); +#else /* DO_SYSLOG */ (void) fprintf( stderr, "%s: out of memory\n", argv0 ); +#endif /* DO_SYSLOG */ exit( 1 ); } (void) snprintf( @@ -533,6 +590,7 @@ { char buf[1000]; int status; + int stripped = 0; /* Skip leading whitespace. */ while ( len > 0 && ( *recipient == ' ' || *recipient == '\t' ) ) @@ -546,18 +604,38 @@ { ++recipient; --len; + stripped = 1; } - while ( len > 0 && recipient[len-1] == '>' ) + while ( len > 0 && recipient[len-1] == '>' && stripped == 1 ) --len; - (void) snprintf( buf, sizeof(buf), "RCPT TO:<%.*s>", len, recipient ); + if (len == 0) { + (void) snprintf( buf, sizeof(buf), "root" ); + } else { + (void) snprintf( buf, sizeof(buf), "%.*s", len, recipient ); + } + +#ifdef DO_LOG_INFO + syslog(LOG_INFO|LOG_MAIL,"from=<%s>, to=%s, size=%d\n", from, buf, strlen(message) ); +#endif /* DO_LOG_INFO */ + + if (len == 0) { + (void) snprintf( buf, sizeof(buf), "RCPT TO:" ); + } else { + (void) snprintf( buf, sizeof(buf), "RCPT TO:<%.*s>", len, recipient ); + } send_command( buf ); status = read_response(); if ( status != 250 && status != 251 ) { +#ifdef DO_SYSLOG + syslog( LOG_ERR|LOG_MAIL, "unexpected response %d to RCPT TO command", + status ); +#else /* DO_SYSLOG */ (void) fprintf( stderr, "%s: unexpected response %d to RCPT TO command\n", argv0, status ); +#endif /* DO_SYSLOG */ exit( 1 ); } got_a_recipient = 1; @@ -618,9 +696,14 @@ (void) snprintf( portstr, sizeof(portstr), "%d", port ); if ( (gaierr = getaddrinfo( server, portstr, &hints, &ai )) != 0 ) { +#ifdef DO_SYSLOG + syslog( LOG_ERR|LOG_MAIL, + "getaddrinfo %s - %s", server, gai_strerror( gaierr ) ); +#else /* DO_SYSLOG */ (void) fprintf( stderr, "%s: getaddrinfo %s - %s\n", argv0, server, gai_strerror( gaierr ) ); +#endif /* DO_SYSLOG */ exit( 1 ); } @@ -647,8 +730,13 @@ { if ( sizeof(sa) < aiv4->ai_addrlen ) { +#ifdef DO_SYSLOG + syslog( LOG_ERR|LOG_MAIL, + "%s - sockaddr too small (%lu < %lu)", +#else /* DO_SYSLOG */ (void) fprintf( stderr, "%s - sockaddr too small (%lu < %lu)\n", +#endif /* DO_SYSLOG */ server, (unsigned long) sizeof(sa), (unsigned long) aiv4->ai_addrlen ); exit( 1 ); @@ -664,8 +752,13 @@ { if ( sizeof(sa) < aiv6->ai_addrlen ) { +#ifdef DO_SYSLOG + syslog( LOG_ERR|LOG_MAIL, + "%s - sockaddr too small (%lu < %lu)", +#else /* DO_SYSLOG */ (void) fprintf( stderr, "%s - sockaddr too small (%lu < %lu)\n", +#endif /* DO_SYSLOG */ server, (unsigned long) sizeof(sa), (unsigned long) aiv6->ai_addrlen ); exit( 1 ); @@ -678,15 +771,25 @@ goto ok; } +#ifdef DO_SYSLOG + syslog( LOG_ERR|LOG_MAIL, + "no valid address found for host %s", server ); +#else /* DO_SYSLOG */ (void) fprintf( stderr, "%s: no valid address found for host %s\n", argv0, server ); +#endif /* DO_SYSLOG */ exit( 1 ); ok: freeaddrinfo( ai ); #else /* DO_DNS */ +#ifdef DO_SYSLOG + syslog( LOG_ERR|LOG_MAIL, + "bad server IP address %s", server ); +#else /* DO_SYSLOG */ (void) fprintf( stderr, "%s: bad server IP address %s\n", argv0, server ); +#endif /* DO_SYSLOG */ exit( 1 ); #endif /* DO_DNS */ } @@ -719,16 +822,27 @@ he = gethostbyname( server ); if ( he == (struct hostent*) 0 ) { +#ifdef DO_SYSLOG + syslog( LOG_ERR|LOG_MAIL, + "server name lookup of '%s' failed - %s", + server, hstrerror( h_errno ) ); +#else /* DO_SYSLOG */ (void) fprintf( stderr, "%s: server name lookup of '%s' failed - %s\n", argv0, server, hstrerror( h_errno ) ); +#endif /* DO_SYSLOG */ exit( 1 ); } sock_family = he->h_addrtype; (void) memmove( &sa.sin_addr, he->h_addr, he->h_length ); #else /* DO_DNS */ +#ifdef DO_SYSLOG + syslog( LOG_ERR|LOG_MAIL, + "bad server IP address %s", server ); +#else /* DO_SYSLOG */ (void) fprintf( stderr, "%s: bad server IP address %s\n", argv0, server ); +#endif /* DO_SYSLOG */ exit( 1 ); #endif /* DO_DNS */ } @@ -765,19 +879,32 @@ (void) alarm( timeout ); if ( fgets( buf, sizeof(buf), sockrfp ) == (char*) 0 ) { +#ifdef DO_SYSLOG + syslog( LOG_ERR|LOG_MAIL, "unexpected EOF" ); +#else /* DO_SYSLOG */ (void) fprintf( stderr, "%s: unexpected EOF\n", argv0 ); +#endif /* DO_SYSLOG */ exit( 1 ); } if ( verbose ) +#ifdef DO_SYSLOG + syslog( LOG_DEBUG|LOG_MAIL, "<<<< %s", buf ); +#else /* DO_SYSLOG */ (void) fprintf( stderr, "<<<< %s", buf ); +#endif /* DO_SYSLOG */ for ( status = 0, cp = buf; *cp >= '0' && *cp <= '9'; ++cp ) status = 10 * status + ( *cp - '0' ); if ( *cp == ' ' ) break; if ( *cp != '-' ) { +#ifdef DO_SYSLOG + syslog( + LOG_ERR|LOG_MAIL, "bogus reply syntax - '%s'", buf ); +#else /* DO_SYSLOG */ (void) fprintf( stderr, "%s: bogus reply syntax - '%s'\n", argv0, buf ); +#endif /* DO_SYSLOG */ exit( 1 ); } } @@ -790,7 +917,11 @@ { (void) alarm( timeout ); if ( verbose ) +#ifdef DO_SYSLOG + syslog( LOG_DEBUG|LOG_MAIL, ">>>> %s", command ); +#else /* DO_SYSLOG */ (void) fprintf( stderr, ">>>> %s\n", command ); +#endif (void) fprintf( sockwfp, "%s\r\n", command ); (void) fflush( sockwfp ); } @@ -829,7 +960,11 @@ static void sigcatch( int sig ) { +#ifdef DO_SYSLOG + syslog( LOG_ERR|LOG_MAIL, "timed out" ); +#else /* DO_SYSLOG */ (void) fprintf( stderr, "%s: timed out\n", argv0 ); +#endif exit( 1 ); } @@ -840,6 +975,10 @@ char buf[5000]; (void) snprintf( buf, sizeof(buf), "%s: %s", argv0, cause ); +#ifdef DO_SYSLOG + syslog( LOG_ERR|LOG_MAIL, "%s", buf ); +#else /* DO_SYSLOG */ perror( buf ); +#endif /* DO_SYSLOG */ exit( 1 ); }