Ejemplo n.º 1
0
void zmq::reaper_t::process_stop ()
{
    terminating = true;

    //  If there are no sockets being reaped finish immediately.
    if (!sockets) {
        send_done ();
        poller->rm_fd (mailbox_handle);
        poller->stop ();
    }
}
Ejemplo n.º 2
0
void zmq::reaper_t::process_reaped ()
{
    --sockets;

    //  If reaped was already asked to terminate and there are no more sockets,
    //  finish immediately.
    if (!sockets && terminating) {
        send_done ();
        poller->rm_fd (mailbox_handle);
        poller->stop ();
    }
}
Ejemplo n.º 3
0
/* main parallism function */
void worker() {
  int i,j;

  for(;;) {
    /* find work */
    if (!(cj = freejob()) && !(cj = steal()))
      return;
    if (cj->status == JOB_DONE)   // done
      return;
   
    /* do work */
    cj->status = JOB_TAKEN;
    p_head = p_tail = 0;
    slow_crunch();
   
    /* aftermath */
    switch (cj->status) {
      case JOB_BLOCKED:   
        add_jobarray(cj); 
        cj = 0; 
        break;
    
      case JOB_DONE:      
        if (!cj->jid && master)   // done
          return;
        else {
          send_done(cj);
          free(cj);
          }
        break;
   
      case JOB_CANCELLED: 
        free(cj);
      }
    }
  }    
Ejemplo n.º 4
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 );
    }
Ejemplo n.º 5
0
/* message handling routine */
void p_handle(int b) {
  int i,k,len,tid,tag;
  jobinfo *j;
  jobinfo tj; 
  pvm_bufinfo(b,&len,&tag,&tid);

  switch (tag) {
    case TAG_HELLO:
      if (master) {
        wtid = realloc(wtid,sizeof(int) * ++nw);
        wtid[nw-1] = tid;
        for (i=1;i<nw;i++) {
          pvm_initsend(0);
          k = i << BASE_SHIFT;
          pvm_pkint(&k,1,1);
          pvm_pkint(&nw,1,1);
          pvm_pkint(wtid,nw,1);
          pvm_send(wtid[i],TAG_WORKERS);
          }
        }
      break;

    case TAG_WORKERS: 
      pvm_upkint(&nextjid,1,1);      
      nextjid <<= BASE_SHIFT;
      pvm_upkint(&nw,1,1);
      free(wtid);
      wtid = malloc(sizeof(int) * nw);
      pvm_upkint(wtid,nw,1);
      break;

    case TAG_KILL:
      die("Received TAG_KILL.  Too lazy to do anything useful.\n");

    case TAG_REQUEST:
      if (j = freejob()) {
        pvm_initsend(0);
        pkjobinfo_active(j);
        pvm_send(tid,TAG_JOB);
        add_stolen(tid,j->jid);
        free(j);
        }
      else if (!victim(tid)) {
        pvm_initsend(0);
        pvm_send(tid,TAG_NO_JOB);
        }
      break; 

    case TAG_DONE:
      upkjobinfo_done(&tj);
      if (cj && cj->jid == tj.pjid)
        slow_absorb(cj,&tj.s);
      else if (!tj.jid && master) {
        j = malloc(sizeof(jobinfo)); 
        *j = tj;
        add_jobarray(j);
        }
      else if ((i = find_jobarray(tj.pjid)) >= 0) { 
        slow_absorb(ja[i],&tj.s);
        if (ja[i]->status == JOB_DONE && !(!ja[i]->jid && master)) {
          send_done(ja[i]);
          free(ja[i]); 
          del_jobarray(i);
          }
        }
      else if (tj.tid = find_stolen(tj.pjid))  // if 0, job was cancelled
        send_done(&tj);
      break; 
    
    case TAG_CANCEL:
      pvm_upkint(&k,1,1); 
      if (cj && cj->jid == k) {
        cj->status = JOB_CANCELLED;
        if (p_head > 0) 
          cancel_children(cj);
        p_head = 1000;
        add_stolen(0,cj->jid);
        }
      else if ((i = find_jobarray(k)) >= 0) { 
        cancel_children(ja[i]);
        add_stolen(0,ja[i]->jid); 
        free(ja[i]);
        del_jobarray(i);
        }
      else if (tid = find_stolen(k)) 
        send_cancel(tid,k); 
      break;

    case TAG_STAT:
    default:
      die("Warning: ignoring invalid message\n");
    }
  }
Ejemplo n.º 6
0
/**
 * Request NAKs from all clients.
 * Returns the aggregate number of NAKs for the section.
 */
int get_naks(struct finfo_t *finfo, unsigned int pass, unsigned int section,
             int *alldone)
{
    unsigned char *packet, *decrypted;
    struct uftp_h *header;
    struct timeval timeout;
    struct sockaddr_in receiver;
    int resend, attempt, last_pass, gotall, anyerror;
    int blocks_this_sec, section_offset;
    int rcv_status, len, nakidx, numnaks, i, j;
    time_t endtime;

    packet = calloc(mtu, 1);
    decrypted = calloc(mtu, 1);
    if ((packet == NULL) || (decrypted == NULL)) {
        syserror(0, 0, "calloc failed!");
        exit(1);
    }
    header = (struct uftp_h *)packet;

    section_offset = (blocksize * 8) * (section - 1);
    blocks_this_sec = ((section < finfo->sections) ? (blocksize * 8) :
                            (finfo->blocks % (blocksize * 8)));
    if (finfo->sections && !blocks_this_sec) blocks_this_sec = blocksize * 8;
    for (i = 0; i < blocks_this_sec; i++) {
        nakidx = i + section_offset;
        finfo->naklist[nakidx] = 0;
    }

    for (i = 0; i < destcount; i++) {
        if (client_error(i)) {
            continue;
        }
        if (destlist[i].clientcnt != -1) {
            destlist[i].status = DEST_ACTIVE;
        } else if (destlist[i].status == DEST_ACTIVE) {
            destlist[i].status = DEST_STATUS;
        }
        free(destlist[i].last_status);
        destlist[i].last_status = NULL;
        for (j = 0; j < destlist[i].last_prstatus_cnt; j++) {
            free(destlist[i].last_prstatus[j]);
            destlist[i].last_prstatus[j] = NULL;
        }
        destlist[i].last_prstatus_cnt = 0;
    }

    endtime = time(NULL) + status_time;
    timeout.tv_sec = status_int / 1000;
    timeout.tv_usec = (status_int % 1000) * 1000;
    resend = 1;
    attempt = 1;
    gotall = 0;
    last_pass = 0;
    while ((time(NULL) < endtime) && (!gotall)) {
        if (resend) {
            if (!send_doneconf(finfo, attempt)) {
                continue;
            }
            if (!send_done(finfo, attempt, pass, section)) {
                continue;
            }
            resend = 0;
        }
        // See comments in announce_phase regarding timing
        if ((rcv_status = read_packet(sock, &receiver, packet, &len,
                                      mtu, &timeout)) == -1) {
            continue;
        } else if (rcv_status == 0) {
            attempt++;
            resend = 1;
            if (last_pass) break;
            continue;
        }
        if (!validate_packet(packet, len, finfo)) {
            continue;
        }

        if (!handle_transfer_phase(packet, decrypted, &receiver,
                blocks_this_sec, section_offset, pass, section, finfo)) {
            continue;
        }
        for (i = 0, gotall = 1, *alldone = 1;
                (i < destcount) && (gotall || *alldone); i++) {
            gotall = gotall && (destlist[i].status != DEST_STATUS);
            *alldone = *alldone && ((destlist[i].status == DEST_DONE) ||
                            (client_error(i)) || (destlist[i].clientcnt != -1));
        }
        if (*alldone) {
            if (finfo->file_id != 0) break;
            // Change the wait interval to the client's done_int * 1.5
            // to allow for late completions
            timeout.tv_sec = (int)(done_int / 1000 * 1.5);
            timeout.tv_usec = (int)((done_int % 1000) * 1000 * 1.5);
            if (!last_pass) {
                log(0, 0, "Late completions:");
            }
            last_pass = 1;
            gotall = 0;
            send_doneconf(finfo, attempt + 1);
        } 
    }

    anyerror = 0;
    if (*alldone) {
        send_doneconf(finfo, attempt + 1);
    } else if (!gotall) {
        for (i = 0, *alldone = 1; i < destcount; i++) {
            if (destlist[i].status == DEST_STATUS) {
                log1(0, 0, "Couldn't get STATUS from %s", destlist[i].name);
                destlist[i].status = DEST_LOST;
                anyerror = 1;
            }
            *alldone = *alldone && ((destlist[i].status == DEST_DONE) ||
                            (client_error(i)) || (destlist[i].clientcnt != -1));
        }
    }
    if (anyerror && quit_on_error) {
        log0(0, 0, "Aboring all clients");
        send_abort(finfo, "A client dropped out, aborting all",
                &receive_dest, NULL, (keytype != KEY_NONE), 0);
        for (i = 0; i < destcount; i++) {
            if (destlist[i].status == DEST_ACTIVE) {
                destlist[i].status = DEST_ABORT;
            }
        }
        *alldone = 1;
    }

    for (i = 0, numnaks = 0; i < blocks_this_sec; i++) {
        nakidx = i + section_offset;
        if (finfo->naklist[nakidx]) {
            numnaks++;
        }
    }

    free(packet);
    free(decrypted);
    return numnaks;
}
Ejemplo n.º 7
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 );
}