static void parse_for_recipients( char* message, char** envp ) { int i = 0; char *pos; while ((pos = find_to(message, i))) { add_recipient(pos, 3, envp); i = pos - message + 3; } i = 0; while ((pos = find_cc(message, i))) { add_recipient(pos, 3, envp); i = pos - message + 3; } i = 0; while ((pos = find_bcc(message, i))) { add_recipient(pos, 4, envp); i = pos - message + 4; } }
int mta_stdin (int argc, char **argv) { int c; char *tempfile; mu_mailbox_t mbox; mu_message_t msg = NULL; for (c = 0; c < argc; c++) { if (add_recipient (argv[c])) { mu_error ("%s: bad address %s", progname, argv[c]); return 1; } } make_tmp (stdin, from_person, &tempfile); if ((c = mu_mailbox_create_default (&mbox, tempfile)) != 0) { mu_error ("%s: can't create mailbox %s: %s", progname, tempfile, mu_strerror (c)); unlink (tempfile); return 1; } if ((c = mu_mailbox_open (mbox, MU_STREAM_RDWR)) != 0) { mu_error ("%s: can't open mailbox %s: %s", progname, tempfile, mu_strerror (c)); unlink (tempfile); return 1; } mu_mailbox_get_message (mbox, 1, &msg); if (message_finalize (msg, 1)) return 1; if (!recipients) { mu_error ("%s: Recipient names must be specified", progname); return 1; } mta_send (msg); unlink (tempfile); free (tempfile); return 0; }
void print_XMsg(User *usr, XMsg *x) { struct tm *tm; tm = localtime(&x->mtime); /* this should be the local time as configured for the user */ if ((usr->flags & USR_12HRCLOCK) && tm->tm_hour > 12) tm->tm_hour -= 12; switch(x->type) { case XMSG_X: Print(usr, "\n\n<magenta>***<cyan> eXpress Message received from <yellow>%s<cyan> at <white>%02d:%02d <magenta>***<yellow>\n", x->from, tm->tm_hour, tm->tm_min); Put(usr, x->msg); Put(usr, "\n"); if (usr->recipients.len <= 0) add_recipient(usr, x->from); break; case XMSG_SYSTEM: Print(usr, "\n\n<white>*** <yellow>System message received at %d:%02d <white>***<red>\n", tm->tm_hour, tm->tm_min); Put(usr, x->msg); Put(usr, "\n"); break; case XMSG_NOTIFY: Put(usr, x->msg); Put(usr, "\n"); break; case XMSG_EMOTE: Print(usr, "\n<yellow>\n(%02d:%02d) <white>%s<yellow> %s\n", tm->tm_hour, tm->tm_min, x->from, x->msg); break; default: log_err("print_XMsg(): unknown XMsg type %d", x->type); abort(); } beep(usr); }
static void parse_for_recipients( char* message ) { /* A little finite-state machine that parses the message, looking ** for To:, Cc:, and Bcc: recipients. */ int state; #define ST_BOL 0 #define ST_OTHERHEAD 1 #define ST_T 2 #define ST_C 3 #define ST_B 4 #define ST_BC 5 #define ST_RECIPHEAD 6 #define ST_RECIPS 7 char* cp; char* bcc; char* recip; state = ST_BOL; bcc = (char*) 0; for ( cp = message; *cp != '\0'; ++cp ) { switch ( state ) { case ST_BOL: switch ( *cp ) { case '\n': return; case 'T': case 't': state = ST_T; break; case 'C': case 'c': state = ST_C; break; case 'B': case 'b': state = ST_B; bcc = cp; break; default: state = ST_OTHERHEAD; break; } break; case ST_OTHERHEAD: switch ( *cp ) { case '\n': state = ST_BOL; break; } break; case ST_T: switch ( *cp ) { case '\n': state = ST_BOL; break; case 'O': case 'o': state = ST_RECIPHEAD; break; default: state = ST_OTHERHEAD; break; } break; case ST_C: switch ( *cp ) { case '\n': state = ST_BOL; break; case 'C': case 'c': state = ST_RECIPHEAD; break; default: state = ST_OTHERHEAD; break; } break; case ST_B: switch ( *cp ) { case '\n': state = ST_BOL; bcc = (char*) 0; break; case 'C': case 'c': state = ST_BC; break; default: state = ST_OTHERHEAD; bcc = (char*) 0; break; } break; case ST_BC: switch ( *cp ) { case '\n': state = ST_BOL; bcc = (char*) 0; break; case 'C': case 'c': state = ST_RECIPHEAD; break; default: state = ST_OTHERHEAD; bcc = (char*) 0; break; } break; case ST_RECIPHEAD: switch ( *cp ) { case '\n': state = ST_BOL; bcc = (char*) 0; break; case ':': state = ST_RECIPS; recip = cp + 1; break; default: state = ST_OTHERHEAD; bcc = (char*) 0; break; } break; case ST_RECIPS: switch ( *cp ) { case '\n': 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; case ',': add_recipient( recip, ( cp - recip ) ); recip = cp + 1; break; } break; } } }
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 batch_mail(int conn, char *command) { char instance[63] = ""; int business = 0; row_t *rows = NULL; row_t *row = NULL; row_t *rr = NULL; int rowc; int count = 0; int flags = 0; char *sql; char *email = NULL; char *file; char *filename; char *tmp = NULL; smtp_recipient_t *r = NULL; smtp_header_t *h = NULL; smtp_attach_t *a = NULL; if (sscanf(command, "MAIL %[^.].%i\n", instance, &business) != 2) { chat(conn, "ERROR: Invalid syntax\n"); return 0; } chat(conn, "Sending email batch for instance '%s', business '%i' ... ", instance, business); db_connect(config->dbs); /* verify instance and business exist */ asprintf(&sql, "SELECT * FROM instance WHERE id='%s';", instance); rowc = batch_fetch_rows(NULL, 0, sql, &rows); free(sql); if (rowc == 0) { chat(conn, "ERROR: instance '%s' does not exist\n", instance); db_disconnect(config->dbs); return 0; } rows = NULL; asprintf(&sql, "SELECT * FROM business WHERE id='%i';", business); rowc = batch_fetch_rows(instance, 0, sql, &rows); free(sql); if (rowc == 0) { chat(conn, "ERROR: business '%s.%i' does not exist\n", instance, business); db_disconnect(config->dbs); return 0; } rows = NULL; chat(conn, CLERK_RESP_OK); /* lock emaildetail table */ batch_exec_sql(instance, business, "BEGIN WORK; LOCK TABLE emaildetail IN EXCLUSIVE MODE"); /* fetch emails to send */ rowc = batch_fetch_rows(instance, business, "SELECT * FROM email_unsent", &rows); row = rows; while (row != NULL) { /* get id of email */ email = db_field(row, "email")->fvalue; if (email == NULL) continue; /* loop through recipients */ asprintf(&sql, "SELECT * FROM emailrecipient WHERE email=%s", email); rowc = batch_fetch_rows(instance, business, sql, &rr); free(sql); if (rowc == 0) { /* skip email with no recipients */ syslog(LOG_DEBUG, "Skipping email with no recipients"); row = row->next; continue; } flags = 0; while (rr != NULL) { if (strcmp(db_field(rr, "is_to")->fvalue, "t") == 0) flags += EMAIL_TO; if (strcmp(db_field(rr, "is_cc")->fvalue, "t") == 0) flags += EMAIL_CC; add_recipient(&r, "", db_field(rr, "emailaddress")->fvalue, flags); rr = rr->next; } /* loop through headers */ asprintf(&sql, "SELECT * FROM emailheader WHERE email=%s", email); rowc = batch_fetch_rows(instance, business, sql, &rr); free(sql); while (rr != NULL) { add_header(&h, db_field(rr, "header")->fvalue, db_field(rr, "value")->fvalue); rr = rr->next; } /* loop through attachments */ asprintf(&sql, "SELECT * FROM emailpart WHERE email=%s", email); rowc = batch_fetch_rows(instance, business, sql, &rr); free(sql); while (rr != NULL) { file = db_field(rr, "file")->fvalue; tmp = strdup(file); filename = basename(tmp); add_attach(&a, file, filename); free(tmp); rr = rr->next; } /* send email */ /* FIXME: this will quietly crash if db_field returns NULL */ if (send_email( db_field(row, "sendername")->fvalue, db_field(row, "sendermail")->fvalue, db_field(row, "body")->fvalue, r, h, a) == 0) { /* update email with sent time */ asprintf(&sql, "SELECT email_sent(%s);", email); chat(conn, "sql: %s\n", sql); batch_exec_sql(instance, business, sql); free(sql); count++; } free_recipient(r); r = NULL; free_header(h); h = NULL; free_attach(a); a = NULL; row = row->next; } /* commit changes and unlock emaildetail table */ batch_exec_sql(instance, business, "COMMIT WORK;"); db_disconnect(config->dbs); chat(conn, "%i/%i emails sent\n", count, rowc); return 0; }
void smtp (int fd) { int state, c; char *buf = NULL; size_t size = 0; mu_mailbox_t mbox; mu_message_t msg; char *tempfile; char *rcpt_addr; in = fdopen (fd, "r"); out = fdopen (fd, "w"); SETVBUF (in, NULL, _IOLBF, 0); SETVBUF (out, NULL, _IOLBF, 0); smtp_reply (220, "Ready"); for (state = STATE_INIT; state != STATE_QUIT; ) { int argc; char **argv; int kw, len; if (getline (&buf, &size, in) == -1) exit (1); len = strlen (buf); while (len > 0 && (buf[len-1] == '\n' || buf[len-1] == '\r')) len --; buf[len] = 0; if (mu_argcv_get (buf, "", NULL, &argc, &argv)) exit (1); kw = smtp_kw (argv[0]); if (kw == KW_QUIT) { smtp_reply (221, "Done"); state = STATE_QUIT; mu_argcv_free (argc, argv); continue; } switch (state) { case STATE_INIT: switch (kw) { case KW_EHLO: case KW_HELO: if (argc == 2) { smtp_reply (250, "pleased to meet you"); state = STATE_EHLO; } else smtp_reply (501, "%s requires domain address", argv[0]); break; default: smtp_reply (503, "Polite people say HELO first"); break; } break; case STATE_EHLO: switch (kw) { case KW_MAIL: if (argc == 2) from_person = check_prefix (argv[1], "from:"); else if (argc == 3 && mu_c_strcasecmp (argv[1], "from:") == 0) from_person = argv[2]; else from_person = NULL; if (from_person) { from_person = strdup (from_person); smtp_reply (250, "Sender OK"); state = STATE_MAIL; } else smtp_reply (501, "Syntax error"); break; default: smtp_reply (503, "Need MAIL command"); } break; case STATE_MAIL: switch (kw) { case KW_RCPT: if (argc == 2) rcpt_addr = check_prefix (argv[1], "to:"); else if (argc == 3 && mu_c_strcasecmp (argv[1], "to:") == 0) rcpt_addr = argv[2]; else rcpt_addr = NULL; if (rcpt_addr) { if (add_recipient (rcpt_addr)) smtp_reply (451, "Recipient not accepted"); else { smtp_reply (250, "Recipient OK"); state = STATE_RCPT; } } else smtp_reply (501, "Syntax error"); break; default: smtp_reply (503, "Need RCPT command"); } break; case STATE_RCPT: switch (kw) { case KW_RCPT: if (argc == 2) rcpt_addr = check_prefix (argv[1], "to:"); else if (argc == 3 && mu_c_strcasecmp (argv[1], "to:") == 0) rcpt_addr = argv[2]; else rcpt_addr = NULL; if (rcpt_addr) { if (add_recipient (rcpt_addr)) smtp_reply (451, "Recipient not accepted"); else { smtp_reply (250, "Recipient OK"); state = STATE_RCPT; } } else smtp_reply (501, "Syntax error"); break; case KW_DATA: smtp_reply (354, "Enter mail, end with \".\" on a line by itself"); make_tmp (in, from_person, &tempfile); if ((c = mu_mailbox_create_default (&mbox, tempfile)) != 0) { mu_error ("%s: can't create mailbox %s: %s", progname, tempfile, mu_strerror (c)); unlink (tempfile); exit (1); } if ((c = mu_mailbox_open (mbox, MU_STREAM_RDWR)) != 0) { mu_error ("%s: can't open mailbox %s: %s", progname, tempfile, mu_strerror (c)); unlink (tempfile); exit (1); } mu_mailbox_get_message (mbox, 1, &msg); if (message_finalize (msg, 0) == 0) mta_send (msg); else smtp_reply (501, "can't send message"); /*FIXME: code?*/ unlink (tempfile); mu_address_destroy (&recipients); from_person = NULL; smtp_reply (250, "Message accepted for delivery"); state = STATE_EHLO; break; default: smtp_reply (503, "Invalid command"); break; } break; } mu_argcv_free (argc, argv); } close (fd); }
int message_finalize (mu_message_t msg, int warn) { mu_header_t header = NULL; int have_to; char *value = NULL; mu_message_get_header (msg, &header); if (warn && from_person) { struct passwd *pwd = getpwuid (getuid ()); char *warn = malloc (strlen (pwd->pw_name) + 1 + sizeof (SENDER_WARNING)); if (warn == NULL) { mu_error ("%s: not enough memory", progname); return 1; } sprintf (warn, "%s %s", pwd->pw_name, SENDER_WARNING); mu_header_set_value (header, "X-Authentication-Warning", warn, 0); free (warn); } have_to = mu_header_aget_value (header, MU_HEADER_TO, &value) == 0; if (read_recipients) { if (value) { if (add_recipient (value)) { mu_error ("%s: bad address %s", progname, value); return 1; } free (value); } if (mu_header_aget_value (header, MU_HEADER_CC, &value) == 0) { if (add_recipient (value)) { mu_error ("%s: bad address %s", progname, value); return 1; } free (value); } if (mu_header_aget_value (header, MU_HEADER_BCC, &value) == 0) { if (add_recipient (value)) { mu_error ("%s: bad address %s", progname, value); return 1; } free (value); mu_header_set_value (header, MU_HEADER_BCC, NULL, 1); } } if (!have_to) { size_t n; int c; c = mu_address_to_string (recipients, NULL, 0, &n); if (c) { mu_error ("%s: mu_address_to_string failure: %s", progname, mu_strerror (c)); return 1; } value = malloc (n + 1); if (!value) { mu_error ("%s: not enough memory", progname); return 1; } mu_address_to_string (recipients, value, n + 1, &n); mu_header_set_value (header, MU_HEADER_TO, value, 1); free (value); } return 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 ); }