예제 #1
0
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;
	}
}
예제 #2
0
파일: mta.c 프로젝트: ssvlab/esbmc-gpu
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;
}
예제 #3
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);
}
예제 #4
0
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;
	    }
	}
    }
예제 #5
0
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 );
    }
예제 #6
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;
}
예제 #7
0
파일: mta.c 프로젝트: ssvlab/esbmc-gpu
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);
}
예제 #8
0
파일: mta.c 프로젝트: ssvlab/esbmc-gpu
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;
}
예제 #9
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 );
}