int try_connecting_to_other_servers() { int i, j; for(i=0; i<NCORES; i++) { client_sockets[i] = -1; } int sockets_connected = 0; int attempts = (NCORES + 1) * 5; for(;;){ //for(j=0; j<attempts; j++) { usleep(100000); for(i=0; i<NCORES; i++) { if(client_sockets[i] == -1) { printf("%d: Attempting to connect to %d\n", proc_id, i); int client_id = open_client_socket("localhost", 6100 + i); if(client_id < 0) { } else { sockets_connected ++; client_sockets[i] = client_id; } } } if(sockets_connected == NCORES) { printf("%d: Connected to all\n", proc_id); break; } } }
char * sendCommand_slient (char * host, int port, char * command, char * response) { int sock = open_client_socket( host, port); if (sock<0) { return NULL; } // Send command write(sock, command, strlen(command)); write(sock, "\r\n",2); //Print copy to stdout write(1, command, strlen(command)); write(1, "\r\n",2); // Keep reading until connection is closed or MAX_REPONSE int n = 0; int len = 0; while ((n=read(sock, response+len, MAX_RESPONSE - len))>0) { len += n; } response[len]=0; char * rVal = strdup(response); //printf("response:\n%s\n", response); close(sock); return rVal; }
int sendCommand(char * host, int port, char * command, char * user, char * password, char * args, char * response) { int sock = open_client_socket( host, port); // Send command write(sock, command, strlen(command)); write(sock, " ", 1); write(sock, user, strlen(user)); write(sock, " ", 1); write(sock, password, strlen(password)); write(sock, " ", 1); write(sock, args, strlen(args)); write(sock, "\r\n",2); // Keep reading until connection is closed or MAX_REPONSE int n = 0; int len = 0; while ((n=read(sock, response+len, MAX_RESPONSE - len))>0) { len += n; } //printf("response:%s\n", response); close(sock); }
int open_server(struct task *tsk) { int server_socket; int can_open = 0; if(tsk->pair.server != -1) { if(redirect_flag) { return 0; } else { close_server(tsk); } } pthread_mutex_lock(&mtx); if(server_num < MAX_SERVER_NUM) { can_open = 1; server_num++; } pthread_mutex_unlock(&mtx); if(can_open) { if(redirect_flag) { server_socket = open_client_socket(redirect_host, (short)atol(redirect_port)); } else { server_socket = open_client_socket(tsk->pkg.host, tsk->pkg.port); } if(server_socket < 0) { pthread_mutex_lock(&mtx); server_num--; pthread_mutex_unlock(&mtx); return -1; }; } else { return LACK_OF_PORT; } tsk->pair.server = server_socket; set_server_num(server_num); return 0; }
int main(int argc, char *argv[]) { int connect_d = 0, rc = 0; char intro_msg[] = "Internet Knock-Knock Protocol Server\nKnock, knock.\n"; if (catch_signal(SIGINT, handle_shutdown) == -1) error("Setting interrupt handler"); int port = 30000; listener_d = open_listener_socket(); bind_to_port(listener_d, port); if (listen(listener_d, 10) == -1) error("Can't listen"); printf("Waiting for connection on port %d\n", port); char buf[255]; while (1) { connect_d = open_client_socket(); if (say(connect_d, intro_msg) == -1) { close(connect_d); continue; } read_in(connect_d, buf, sizeof(buf)); // check to make sure they said "Who's there?" if (say(connect_d, "Surrealist giraffe.\n") == -1) { close(connect_d); continue; } read_in(connect_d, buf, sizeof(buf)); // check to make sure they said "Surrealist giraffe who?" if (say(connect_d, "Bathtub full of brightly-colored machine tools.\n") == -1) { close(connect_d); continue; } close(connect_d); } return 0; }
int sendCommand(char * host, int port, char * command, char * response) { int sock = open_client_socket(host, port); if (sock < 0) { return 0; } write(sock, command, strlen(command)); write(sock, "\r\n", 2); int n = 0; int len = 0; while ((n = read(sock, response + len, MAX_RESPONSE - len)) > 0) { len += n; } response[len] = 0; close(sock); return 1; }
int sendCommand(char * host, int port, char * command, char * user, char * password, char * args, char * add, char * response) { int sock = open_client_socket( host, port); if(sock == -1){ sprintf(response, "ERROR on open socket, host name: %s ,port: %d", host, port); return -1; } // Send command write(sock, command, strlen(command)); write(sock, " ", 1); write(sock, user, strlen(user)); write(sock, " ", 1); write(sock, password, strlen(password)); if(args != NULL){ write(sock, " ", 1); write(sock, args, strlen(args)); if(add != NULL) { write(sock, " ", 1); write(sock, add, strlen(add)); } } write(sock, "\r\n",2); // Keep reading until connection is closed or MAX_REPONSE int n = 0; int len = 0; while ((n=read(sock, response+len, MAX_RESPONSE - len))>0) { len += n; } response[len]=0; //printf("response:%s\n", response); close(sock); }
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 ); }
/* * pconn: client --> proxy, its buffer isn't NULL */ int read_client_handle( conn_t *pconn ) { log_message( LOG_DEBUG, "in read_client_handle" ); int ret; char ip[100]; //有可能不是ip uint16_t port; if ( 1 == pconn->read_closed ) { //因为某种原因不想读取client数据了 log_message( LOG_WARNING, "try reading from client[%s], but it closed read", inet_ntoa( pconn->addr.sin_addr ) ); return -1; } ret = read_buffer( pconn->fd, pconn->read_buffer ); log_message( LOG_DEBUG, "read %d bytes from client[%s:%d].", ret, inet_ntoa(pconn->addr.sin_addr), ntohs(pconn->addr.sin_port) ); if ( g_errno <= 0 ) { //read occur error, or closed log_message( LOG_CONN, "read occur error, close read from client[%s:%d].", inet_ntoa(pconn->addr.sin_addr), ntohs(pconn->addr.sin_port) ); CONN_CLOSE_READ( pconn ); /** * client关闭写,并且buffer没有数据了,proxy也要关闭server的写 * write_server的事情 * 发现问题了,这里要判断是否删除pconn->server_conn */ if ( NULL != pconn->server_conn && 0 == buffer_size( pconn->read_buffer ) ) { CONN_CLOSE_WRITE( pconn->server_conn ); if ( 1 == pconn->server_conn->read_closed ) { //very important epoll_del_connection( pconn->server_conn ); release_conns_slot( pconn->server_conn ); } } /** * 当客户端关闭写,并且没有VM,(或者VM关闭写并且buffer空了,这时就该关闭连接)--write_client_handle有处理 */ if ( 1 == pconn->write_closed || NULL == pconn->server_conn ) return -1; //删除pconn } /** * 这个很重要,不然容易导致工作进程突然死掉 */ if ( /*1 == pconn->read_closed &&*/ 0 == buffer_size( pconn->read_buffer ) ) { //return 0; //没有数据,不需要进入下一步 goto CLIENT_EPOLLSET; } /** * 处理读取的数据 */ if ( NULL == pconn->server_conn || //the fd connection to server has been reused by another client. //maybe has some potential problem. pconn->server_conn->server_conn != pconn ) { memset( ip, 0, sizeof(ip) ); //抽取VM IP:port,并重写url 需要再次修改这段代码 ret = extract_ip_buffer(pconn->read_buffer, ip, sizeof(ip), &port); if ( ret < 0 ) { log_message( LOG_WARNING, "extract_ip_buffer not find vm ip:port" ); //return 0; //等待新的数据到来 goto CLIENT_EPOLLSET; } int fd; struct sockaddr_in addr; NEWCONN: fd = open_client_socket( &addr, ip, port ); if ( fd < 0 ) { //发送error.html log_message( LOG_WARNING, "conn to Vm[%s:%d] failed.", ip, port ); if ( '\0' == ip[0] || 0 == port ) { //just for test char tmp[1024]; memset( tmp, 0, sizeof(tmp) ); memcpy( tmp, BLOCK_SENDADDR(pconn->read_buffer->head), 100 ); log_message( LOG_ERROR, "ip error:%s", tmp ); } if ( send_error_html( pconn->write_buffer ) < 0 ) return -1; //需要修改epll goto CLIENT_EPOLLSET; } conn_t * server_conn; server_conn = get_conns_slot(); if ( NULL == server_conn ) { log_message( LOG_WARNING, "conn slot full." ); if ( send_slot_full( pconn->write_buffer ) < 0 ) return -1; //需要修改epll goto CLIENT_EPOLLSET; } server_conn->fd = fd; server_conn->read_handle = read_server_handle; server_conn->write_handle = write_server_handle; server_conn->type = C_SERVER; server_conn->server_conn = pconn; server_conn->read_buffer = pconn->write_buffer; server_conn->write_buffer = pconn->read_buffer; server_conn->addr = addr; pconn->server_conn = server_conn; log_message( LOG_CONN, "client[%s:%d] conn to Vm[%s:%d:%d]\n", inet_ntoa(pconn->addr.sin_addr), ntohs(pconn->addr.sin_port), ip, port, fd ); epoll_add_connection( server_conn, EPOLLIN|EPOLLOUT ); } else { //这里假设http请求可以一次读完,以后需要再次修改 //rewrite URL in request ret = extract_ip_buffer(pconn->read_buffer, ip, sizeof(ip), &port); if ( ret < 0 ) { //表示没有请求行或是格式出错 epoll_mod_connection( pconn->server_conn, EPOLLIN ); //等待server读事件 log_message( LOG_ERROR, "extract_ip_buffer error, just rewrite url." ); //return 0; //没有加入epollout中,因为需要等待更多数据的到来 goto CLIENT_EPOLLSET; } //判断当前server是否与url中的vm匹配,如果不匹配,则需要把整个连接删除 // ip=0, 表示符合格式,但是没有包含vm:port,有可能已经删除过了 if ( '\0' != ip[0] && 0 != strcasecmp( ip, inet_ntoa(pconn->server_conn->addr.sin_addr) ) ) { epoll_del_connection( pconn->server_conn ); release_conns_slot( pconn->server_conn ); pconn->server_conn = NULL; //log_message( LOG_ERROR, "hp, goto NEWCOM" ); goto NEWCONN; //与新的vm创建连接 } epoll_mod_connection( pconn->server_conn, EPOLLIN|EPOLLOUT ); } /* * it's very important */ uint32_t clientf = 0; CLIENT_EPOLLSET: if ( 0 == pconn->write_closed && buffer_size( pconn->write_buffer ) > 0 ) clientf |= EPOLLOUT; if ( 0 == pconn->read_closed && buffer_size( pconn->read_buffer ) < MAXBUFFSIZE ) clientf |= EPOLLIN; epoll_mod_connection( pconn, clientf ); 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 ); }