int 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]; /* 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; timeout = DEFAULT_TIMEOUT; argn = 1; if (access("/tmp/_articasend.err", F_OK)==0){ if (unlink("/tmp/_articasend.err")<0){ printf("cannot delete file %s\n", "/tmp/_articasend.err"); } } while ( argn < argc && argv[argn][0] == '-' ) { if ( strncmp( argv[argn], "-f", 2 ) == 0 && argv[argn][2] != '\0' ) fake_from = &(argv[argn][2]); 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' ) 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], "-i" ) == 0 ) ; /* ignore */ else if ( strcmp( argv[argn], "-oi" ) == 0 ) ; /* ignore */ else if ( strcmp( argv[argn], "--" ) == 0 ) ; /* ignore */ else usage(); ++argn; } username = getlogin(); if ( username == (char*) 0 ) { #ifdef DO_GETPWUID struct passwd* pw = getpwuid( getuid() ); if ( pw == (struct passwd*) 0 ) { (void) fprintf( stderr, "%s: can't determine username\n", argv0 ); exit( 1 ); } username = pw->pw_name; #else /* DO_GETPWUID */ (void) fprintf( stderr, "%s: can't determine username\n", argv0 ); exit( 1 ); #endif /* DO_GETPWUID */ } if ( gethostname( hostname, sizeof(hostname) - 1 ) < 0 ) show_error( "gethostname" ); if ( fake_from == (char*) 0 ) (void) snprintf( from, sizeof(from), "%s@%s", username, hostname ); else if ( strchr( fake_from, '@' ) == (char*) 0 ) (void) snprintf( from, sizeof(from), "%s@%s", fake_from, hostname ); else (void) snprintf( from, sizeof(from), "%s", fake_from ); /* Strip off any angle brackets in the from address. */ while ( from[0] == '<' ) (void) strcpy( from, &from[1] ); while ( from[strlen(from)-1] == '>' ) from[strlen(from)-1] = '\0'; message = slurp_message(); #ifdef DO_RECEIVED received = make_received( from, username, hostname ); #endif /* DO_RECEIVED */ (void) signal( SIGALRM, sigcatch ); (void) alarm( timeout ); sockfd1 = open_client_socket(); sockfd2 = dup( sockfd1 ); sockrfp = fdopen( sockfd1, "r" ); sockwfp = fdopen( sockfd2, "w" ); /* The full SMTP protocol is spelled out in RFC821, available at ** http://www.faqs.org/rfcs/rfc821.html ** The only non-obvious wrinkles: ** - The commands are terminated with CRLF, not newline. ** - Newlines in the data file get turned into CRLFs. ** - Any data lines beginning with a period get an extra period prepended. */ status = read_response(); if ( status != 220 ) { (void) fprintf( stderr, "%s: unexpected initial greeting %d\n", argv0, status ); myError( "ERROR", "unexpected initial greeting" ); exit( 1 ); } (void) snprintf( buf, sizeof(buf), "HELO %s", hostname ); send_command( buf ); status = read_response(); if ( status != 250 ) { (void) fprintf( stderr, "%s: unexpected response %d to HELO command\n",argv0, status ); myError( "ERROR", "unexpected response %d to HELO command" ); exit( 1 ); } (void) snprintf( buf, sizeof(buf), "MAIL FROM:<%s>", from ); send_command( buf ); status = read_response(); if ( status != 250 ) { (void) fprintf( stderr, "%s: unexpected response %d to MAIL FROM command\n",argv0, status ); myError( "ERROR", "unexpected response to MAIL FROM command" ); exit( 1 ); } got_a_recipient = 0; for ( ; argn < argc; ++argn ) add_recipient( argv[argn], strlen( argv[argn] ) ); if ( parse_message ) parse_for_recipients( message ); if ( ! got_a_recipient ) { (void) fprintf( stderr, "%s: no recipients found\n", argv0 ); myError( "ERROR", "no recipients found" ); exit( 1 ); } send_command( "DATA" ); status = read_response(); if ( status != 354 ) { (void) fprintf(stderr, "%s: unexpected response %d to DATA command\n",argv0, status ); myError( "ERROR", "unexpected response to DATA" ); exit( 1 ); } #ifdef DO_RECEIVED send_data( received ); #endif /* DO_RECEIVED */ send_data( message ); send_done(); status = read_response(); if ( status != 250 ) { (void) fprintf(stderr, "%s: unexpected response %d to DATA\n", argv0, status ); myError( "ERROR", "unexpected response to DATA" ); exit( 1 ); } send_command( "QUIT" ); status = read_response(); if ( status != 221 ) (void) fprintf( stderr, "%s: unexpected response %d to QUIT command - ignored\n",argv0, status ); myError( "INFO", "unexpected response to QUIT command - ignored" ); (void) close( sockfd1 ); (void) close( sockfd2 ); exit( 0 ); }
int main( int argc, char** argv , char** envp) { #ifdef RECEPIENT_DEBUG int argn = 1; #endif int status; int i, h, j, from_count = 0, idx = 0; char* message; #ifdef DO_RECEIVED char* received; #endif /* DO_RECEIVED */ char* username; char **ep; char xuser[50] = ""; char xopt[5000] = ""; char hostname[500] = ""; char from[1000] = ""; // #ifdef RECEPIENT_DEBUG char to[1000] = ""; // #endif char to_buf[1000] = ""; char *to_ptr = to_buf; char buf[2000] = ""; int has_from_header = 0; int has_date_header = 0; char date_header[50]; char from_header[1010]; /* Parse args. */ argv0 = argv[0]; // char *fake_from = from; #ifdef RECEPIENT_DEBUG fake_to = (char*) 0; #endif parse_message = 0; #ifdef DO_MINUS_SP server = "127.0.0.1"; port = SMTP_PORT; #endif /* DO_MINUS_SP */ verbose = 0; debug = 0; timeout = DEFAULT_TIMEOUT; skip_quoted_text = 0; char *safe_env_lst[] = { "USER", "SCRIPT_FILENAME", "REQUEST_URI", "PWD", "REMOTE_ADDR", "MESSAGE_ID" }; /* -fname DONE -f name DONE -f name user@domain -f <name> user@domain -f '' user@domain -f "" user@domain */ for (i=0; i < argc; i++) { if ( strncmp( argv[i], "-d", 2 ) == 0 ) debug = 1; else if ( strncmp( argv[i], "-c", 2 ) == 0 ) skip_quoted_text = 1; else if ( strncmp( argv[i], "-V", 2 ) == 0 ) { printf("Version: %s\n", VERSION); return(0); } else if ( strncmp( argv[i], "-i", 2 ) == 0 || strncmp( argv[i], "-oi", 3 ) == 0 || strncmp( argv[i], "-n", 2 ) == 0 || strcmp( argv[i], "--") == 0 ) { if ( debug ) printf("ARGV[%d](%s): Ignored!\n", i, argv[i]); /* ignore */ } else if ( strncmp( argv[i], "--help", 6 ) == 0 ) { #ifdef DO_MINUS_SP #ifdef DO_DNS char* spflag = "[-s<server>] [-p<port>] "; #else /* DO_DNS */ char* spflag = "[-s<server_ip>] [-p<port>] "; #endif /* DO_DNS */ #else /* DO_MINUS_SP */ char* spflag = ""; #endif /* DO_MINUS_SP */ printf("Usage: %s [-f name] [-v] [-d] [-t] [-T] %s\n", argv[0], spflag); printf(" -i, -oi, -n and -- are ignored\n"); printf(" -d debug\n"); printf(" -v verbose\n"); printf(" -V version\n"); printf(" -s server\n"); printf(" -p port\n"); printf(" -c skip quoted text\n"); printf(" -T timeout (default: 60)\n"); printf(" -t parse the whole message searching for To: Cc: Bcc:\n"); printf(" -f can be used in any format if the last part of that is the email address\n"); printf("Version: %s\n", VERSION); return(0); } else if ( strncmp( argv[i], "-t", 2 ) == 0 ) parse_message = 1; else if ( strncmp( argv[i], "-T", 2 ) == 0 && argv[i][2] != '\0' ) timeout = atoi( &(argv[i][2]) ); else if ( strncmp( argv[i], "-v", 2 ) == 0 ) verbose = 1; else if ( strncmp( argv[i], "-f", 2 ) == 0) { if ( argv[i][2] != '\0' ) { if ( strlen(argv[i]) < 998 ) { for ( h=2; h <= strlen(argv[i]); h++) from[h-2] = argv[i][h]; if ( debug ) printf("FROM0: %s\n", from); } } else if ( strncmp( argv[i+1], "-", 1) != 0 ) { for (h=i+1; h < argc; h++) { if ( argv[h] != NULL ) { // Ako imam oshte edin argument sled tozi i toi ne zapochva s - // to tozi ne e recipient if ( argv[h+1] == NULL ) { // Tui kato nqmam argumenti sled tekushtqt argument // priemame che tova e recipient :) // ako tozi argument naistina sushtestvuva if ( ( strlen(to) + strlen(argv[h]) ) < 1000 ) { for ( j=0; j <= strlen(argv[h]); j++) to[j] = argv[h][j]; if ( debug ) printf("TO0: %s (%s)\n", to, argv[h]); } else { (void) fprintf( stderr, "%s: TO argument too long\n", argv0 ); return(1); } } else { if (strlen(from) + strlen(argv[h]) < 1000) { for ( j=0; j <= strlen(argv[h]); j++) from[j] = argv[h][j]; if ( debug ) printf("FROM1: %s\t(%s), from_count: %d\n", from, argv[h], from_count); } else { (void) fprintf( stderr, "%s: FROM argument too long\n", argv0 ); return(1); } // Ako sledvashtiqt agument ne zapochva s - // i ne e posleden, to neka go dobavim kum from-a if ( strncmp( argv[h+1], "-", 1) != 0 && argv[h+2] != NULL ) { // Ako cqlostnata duljina na tekushtiqt string + cmd // argument-a sa po-malki ot 1000 to dobavi tekushtiqt // cmd argument kum from if (strlen(from) + strlen(argv[h+1]) < 1000) { for ( j=0; j <= strlen(argv[h+1]); j++) from[j] = argv[h+1][j]; if ( debug ) printf("FROM2: %s\t(%s), from_count: %d\n", from, argv[h+1], from_count); } else { (void) fprintf( stderr, "%s: FROM argument too long\n", argv0 ); return(1); } } } } } } } #ifdef DO_MINUS_SP else if ( strncmp( argv[i], "-s", 2 ) == 0 && argv[i][2] != '\0' ) server = &(argv[i][2]); else if ( strncmp( argv[i], "-p", 2 ) == 0 && argv[i][2] != '\0' ) port = atoi( &(argv[i][2]) ); #endif /* DO_MINUS_SP */ if ( ! got_a_recipient && i == argc-1 && parse_message != 1 ) { got_a_recipient++; strcat(to_buf, argv[i]); if ( debug ) printf("This has to be the TO %s\n", argv[i]); } if ( debug ) printf("ARGV[%d]: |%s| %lu\n", i, argv[i], (unsigned long)strlen(argv[i])); } if ( timeout == 0 ) timeout = DEFAULT_TIMEOUT; if ( debug ) #ifdef DO_MINUS_SP printf("parse_message: %d\nserver: %s port: %d\ntimeout: %d verbose: %d\n", parse_message, server, port, timeout, verbose); #else printf("parse_message: %d\ntimeout: %d verbose: %d\n", parse_message, timeout, verbose); #endif #ifdef DO_GETLOGIN username = getlogin(); if ( username == (char*) 0 ) { #endif #ifdef DO_GETPWUID struct passwd* pw = getpwuid( getuid() ); if ( pw == (struct passwd*) 0 ) { (void) fprintf( stderr, "%s: can't determine username\n", argv0 ); exit( 1 ); } username = pw->pw_name; #endif /* DO_GETPWUID */ #ifdef DO_GETLOGIN (void) fprintf( stderr, "%s: can't determine username\n", argv0 ); exit( 1 ); } #endif if ( gethostname( hostname, sizeof(hostname) - 1 ) < 0 ) show_error( "gethostname" ); if ( strlen(from) < 2 ) { if ( debug ) printf("Ko tursish sq tuka?\n"); (void) snprintf( from, sizeof(from), "%s@%s", username, hostname ); } else { // Ako nqmame @ znachi trqbva da fake-nem from-a if ( strchr( from, '@' ) == (char*) 0 ) { if ( debug ) printf("Sho go zamestvash toq email sega??\n"); h = strlen(from); from[h] = '@'; h++; for (i=0; i<=strlen(hostname); i++) from[i+h] = hostname[i]; } } /* Strip off any angle brackets in the from address. */ while ( from[0] == '<' ) (void) strcpy( from, &from[1] ); while ( from[strlen(from)-1] == '>' ) from[strlen(from)-1] = '\0'; message = slurp_message(); #ifdef DO_RECEIVED received = make_received( from, username, hostname ); #endif /* DO_RECEIVED */ has_from_header = has_from(message); has_date_header = has_date(message); if (! has_from_header) { snprintf(from_header, sizeof(from_header), "From: %s\n", from); } if (! has_date_header) { time_t t; struct tm *tmp; t = time(NULL); tmp = localtime(&t); strftime(date_header, sizeof(date_header), "Date: %a, %d %b %Y %T %z\n", tmp); } (void) signal( SIGALRM, sigcatch ); (void) alarm( timeout ); sockfd1 = open_client_socket(); sockfd2 = dup( sockfd1 ); sockrfp = fdopen( sockfd1, "r" ); sockwfp = fdopen( sockfd2, "w" ); /* The full SMTP protocol is spelled out in RFC821, available at ** http://www.faqs.org/rfcs/rfc821.html ** The only non-obvious wrinkles: ** - The commands are terminated with CRLF, not newline. ** - Newlines in the data file get turned into CRLFs. ** - Any data lines beginning with a period get an extra period prepended. */ status = read_response(); if ( status != 220 ) { (void) fprintf( stderr, "%s: unexpected initial greeting %d\n", argv0, status ); exit( 1 ); } (void) snprintf( buf, sizeof(buf), "HELO %s", hostname ); send_command( buf ); status = read_response(); if ( status != 250 ) { (void) fprintf( stderr, "%s: unexpected response %d to HELO command\n", argv0, status ); exit( 1 ); } (void) snprintf( buf, sizeof(buf), "MAIL FROM: %s", from ); send_command( buf ); status = read_response(); if ( status != 250 ) { (void) fprintf( stderr, "%s: unexpected response %d to MAIL FROM command\n", argv0, status ); exit( 1 ); } if ( got_a_recipient ) { if ( debug ) printf("Sending first found recipient: %s\n", to_buf); add_recipient( to_ptr, 0, envp ); } // TO // Check the recipient for @ and only if we have it add the recipient if ( strchr( to, '@' ) ) { j = strlen( to ); if ( debug ) printf("TO: %s(%d)\n", to, j); h=0; for (i=0; i <= j; i++) { if ( to[i] == ' ' && to[i+1] != '\0' ) h=i-1; } from_count=0; for (i=0; i <= j; i++) { if ( to[i+h] != '"' && to[i+h] != '<' && to[i+h] != '>' && to[i+h] != ' ' ) { to_buf[from_count] = to[i+h]; from_count++; } } if ( debug ) printf("TO2: %s\n", to_buf); add_recipient( to_buf, strlen( to_buf ), envp ); } #ifdef RECEPIENT_DEBUG for ( ; argn < argc; ++argn ) { if ( fake_to == (char*) 0 ) (void) snprintf( to, sizeof(to), "%s@%s", argv[argn], hostname ); else if ( strchr( fake_to, '@' ) == (char*) 0 ) (void) snprintf( to, sizeof(to), "%s@%s", fake_to, hostname ); else (void) snprintf( to, sizeof(to), "%s", fake_to ); fprintf( stderr, "RCP: %s\n", fake_to ); add_recipient( argc, argv, envp ); } #endif /* RECEPIENT_DEBUG */ if ( parse_message ) { parse_for_recipients( message, envp ); if ( debug ) (void) fprintf( stderr, "%s\n", message ); } if ( ! got_a_recipient ) { (void) fprintf( stderr, "%s: no recipients found\n", argv0 ); exit( 1 ); } send_command( "DATA" ); status = read_response(); if ( status != 354 ) { (void) fprintf( stderr, "%s: unexpected response %d to DATA command\n", argv0, status ); exit( 1 ); } #ifdef DO_RECEIVED send_data( received ); #endif /* DO_RECEIVED */ if (strlen(username) <= 20) sprintf( xuser, "X-SG-User: %s\n", username); sprintf( xopt, "%s", "X-SG-Opt: "); for (ep = envp; *ep; ep++) for (idx = 0; idx<=5; idx++) if (safe_env_lst[idx] && !strncmp(*ep, safe_env_lst[idx], strlen(safe_env_lst[idx]))) sprintf( xopt, "%s %s ", xopt, *ep); if (! has_from_header) send_data( from_header ); if (! has_date_header) send_data( date_header ); send_data( xuser ); send_data( xopt ); send_data( message ); send_done(); status = read_response(); if ( status != 250 ) { (void) fprintf( stderr, "%s: unexpected response %d to DATA\n", argv0, status ); exit( 1 ); } send_command( "QUIT" ); status = read_response(); if ( status != 221 ) (void) fprintf( stderr, "%s: unexpected response %d to QUIT command - ignored\n", argv0, status ); (void) close( sockfd1 ); (void) close( sockfd2 ); exit( 0 ); }