?? smtpr.c
字號:
/****************************************************/
/* AUTHOR : LAW CHIU YUEN */
*/
/* FILENAME : smtpr.c */
/****************************************************/
#ifdef WIN32
#include <windows.h>
#include <winsock.h>
#else
#define closesocket close
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>
#include <ctype.h>
//#define MYPORT 40711 // the port users will be connecting to
#define PORT 25
#define MAXBUFLEN 1024 // max buffer size
#define RELAY_NAME 255 // max length of file name
#define BACKLOG 10 // how many pending connections queue will hold
#define MAXDATASIZE 512 // max number of bytes we can get at once
#define SQMAXDATASIZE 1048576 //1024 * 1024
#define RECVTIME 100 // max number of time to wait for client's message
#define MAXEMAILADDRESS 320 // 64 + 1 + 255
#define MAXRCPT 50 //max number of mail receipients
/* State1 */
#define ACCEPT 0
#define HELO 1
#define MAILFROM 2
#define RCPTTO 3
#define DATA 4
#define MESSAGE 5
#define QUIT 6
#define RELAY 7
/* State2 */
#define FIRSTHELO 0
#define SECONDHELO 1
#define MAXHELO 1024
/* tokenize mailto string, each time return the first email address */
/* eg. a@a.com,b@b.com,c@c.com --> a@a.com */
char* tokenize(char *mailto){
const char delimiters[] = ",";
char *token, *cp;
printf("b4 strtok: mailto:%s\n",mailto);
/* Make writable copy. */
token = strtok (mailto, delimiters); /* token => "words" */
printf("tokenize() speaking : mailto: %s\n",mailto);
printf("tokenize() speaking : token: %s\n",token);
return token;
}
/* tokenize mailto string, each time return the email address other then the first one*/
/* first call: a@a.com,b@b.com,c@c.com --> b@b.com */
/* second call: a@a.com,b@b.com,c@c.com --> c@c.com */
char* tokenize_null(){
const char delimiters[] = ",";
char *token, *cp;
token = strtok (NULL, delimiters); /* token => "words" */
printf("tokenize_null() speaking : token: %s\n",token);
return token;
}
/* take in an email_address, and header; */
/* convert to : header: email_address */
char* compose_mailheader(char *header,char *mail){
char *a = malloc(strlen(mail)+30);
char *b = NULL;
char *c = NULL;
strcpy(a, header);
b = strcat(a, mail);
c = strcat(b, "\r\n");
printf("compose_mailheader: b=%s\n", b);
return b;
}
/* 1. receive message from smtp server */
void receive(int fd, char* command, char *buf){
int numbytes;
if ((numbytes=recv(fd, buf, MAXDATASIZE, 0)) == -1) {
fprintf(stderr,"error in receiving\n");
exit(1);
}
buf[numbytes] = '\0';
printf(" receive() Received buf : %s",buf);
if ( strstr(buf, command) != NULL ){
printf(" receive() Received command : %s\n",command);
}else{
}
}
/* helo */
/* 1. called by relaymail() */
/* 2. interact with a smtp server */
void helo(int sockfd){
int numbytes;
char buf2[MAXDATASIZE];
char buf[MAXDATASIZE];
printf("\n");
printf("helo is called\n");
/*receive 220*/
receive(sockfd, "220 ", buf);
/* send helo */
if (send(sockfd, "HELO server\r\n", 13, 0) == -1)
perror("HELO SERVER");
// printf("sent HELO SERVER\n");
/* receive 250*/
receive(sockfd, "250 ", buf);
/* testing */
// if (send(sockfd, "HELO server\r\n", 13, 0) == -1)
// perror("HELO SERVER");
// receive(sockfd, "250 ", buf);
}
/* mailfrom */
/* 1. called by relaymail() */
/* 2. interact with a smtp server */
void mailfrom(int sockfd,char *mail_from){
char buf[MAXDATASIZE] = "MAIL FROM:";
char *out;
int numbytes;
int i;
printf("\n");
printf("mailfrom is called\n");
/* compose the "MAIL FROM:email@address.com" message */
strcat(buf, mail_from);
strcat(buf, "\r\n");
printf("mailfrom() speaking: buf=%s\n", buf);
printf("mailfrom() speaking: strlen(buf)=%i\n", strlen(buf));
/* send out */
if( send(sockfd, buf, strlen(buf), 0) == -1 )
perror("mailfrom()");
/* receive 250*/
receive(sockfd, "250 ", buf);
} //mailfrom
/* 1. called by rcptto() */
/* 2. interact with a smtp server */
void rcptto2(int sockfd,char *mailtos){
char buf[MAXDATASIZE]="";
char *a;
char *out;
int numbytes;
int i,len;
printf("\n");
printf("rcptto2 is called\n");
/* compose the "RCPT TO:email@address.com" message */
strcat(buf, "RCPT TO:");
strcat(buf, tokenize_null());
strcat(buf, "\r\n");
printf("rcptto2() speaking: buf=%s\n", buf);
printf("rcptto2() speaking: strlen(buf)=%i\n", strlen(buf));
/* send out */
if( send(sockfd, buf, strlen(buf), 0) == -1 )
perror("rcptto()");
/* receive 250*/
receive(sockfd, "250 ", buf);
/* clear the buffer */
for(i=0; i<strlen(buf);i++){
buf[i]='\0';
}//for()
}
/* rcptto */
/* 1. called by relaymail() */
/* 2. interact with a smtp server */
void rcptto(int sockfd,char *mailtos, int mailto_num){
char buf[MAXDATASIZE] = "RCPT TO:";
char *a;
char *out;
int numbytes;
int i,len;
printf("\n");
printf("rcptto is called\n");
/* sending the first address... */
/* compose the "RCPT TO:email@address.com" message */
strcat(buf, tokenize(mailtos));
strcat(buf, "\r\n");
printf("rcptto() speaking: buf=%s\n", buf);
printf("rcptto() speaking: strlen(buf)=%i\n", strlen(buf));
/* send out */
if( send(sockfd, buf, strlen(buf), 0) == -1 )
perror("rcptto()");
/* receive 250*/
receive(sockfd, "250 ", buf);
/* clear the buffer */
/* handle multiple recipients case*/
for(i=0;i<mailto_num-1;i++)
rcptto2(sockfd, mailtos);
/* sending remaining addresses... */
} //rcptto
/* 1. called by relaymail() */
/* 2. interact with a smtp server */
void data(int sockfd){
char buf[MAXDATASIZE] = "";
printf("\n");
printf("data() is called\n");
/* send "DATA" */
if( send(sockfd, "DATA\r\n", 6, 0) == -1 )
perror("data()");
/* receive 354 */
receive(sockfd, "354 ", buf);
}
/* 1. called by relaymail() */
/* 2. interact with a smtp server */
void message(int sockfd, char *msg){
int times,i,j;
int remainder;
printf("\n");
char out[1025];
printf("message() is called\n");
times = strlen(msg) / MAXDATASIZE;
remainder = strlen(msg) - (times * MAXDATASIZE);
printf("remainder: %i\n", remainder);
printf("times: %i\n", times);
for (i=0;i< times;i++){
for (j=0;j< 1024;j++)
out[j]= msg[1024*i + j];
out[1024 +1] = '\0';
printf("sending msg: %i\n", i);
if( send(sockfd, out, 1025, 0) == -1 );
}
printf("end while: %i\n", i);
printf("out: %s\n", out);
for (j=0;j< remainder;j++)
out[j]= msg[1024*times + j];
out[remainder +1] = '\0';
if( send(sockfd, out, remainder+1, 0) == -1 )
perror("message");
printf("out: %s\n", out);
}
/* 1. called by relaymail() */
/* 2. interact with a smtp server */
void quit(int sockfd){
char buf[MAXDATASIZE] = "";
printf("\n");
printf("quit() is called\n");
/* send "QUIT" */
if( send(sockfd, "QUIT\r\n", 6, 0) == -1 )
perror("quit()");
/* receive 354 */
receive(sockfd, "250 ", buf);
}
/*relay mail to a email server*/
void relaymail(char *relay,char *mail_from, char *mailto, int mailto_num, char *msg){
int sockfd, numbytes;
char buf[MAXDATASIZE];
struct hostent *he;
struct sockaddr_in their_addr; // connector's address information
int state = 1;
int logswitch = 0;
int logwhile = 0;
if ((he=gethostbyname(relay)) == NULL) { // get the host info
fprintf(stderr,"gethostbyname fail\n");
exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
fprintf(stderr,"fail to create socket\n");
exit(1);
}
their_addr.sin_family = AF_INET; // host byte order
their_addr.sin_port = htons(PORT); // short, network byte order
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the struct
if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) {
fprintf(stderr,"connect fail\n");
exit(1);
}
while (state <7 && logwhile <10){ /* make sure the program won't run indefinitely */
logwhile++;
/* log */
// printf("\n");
// printf("logwhile = %i\n", logwhile);
// printf("state = %i\n", state);
// printf("\n");
switch (state){
case HELO :
helo(sockfd);
state++;
printf ("end of case HELO\n");
break;
case MAILFROM :
mailfrom(sockfd, mail_from);
state++;
printf ("relaymail(): end of case MAILFROM\n");
break;
case RCPTTO :
rcptto(sockfd, mailto, mailto_num);
state++;
printf ("relaymail(): end of case RCPTTO\n");
break;
case DATA :
data(sockfd);
state++;
printf ("relaymail(): end of case DATA\n");
break;
case MESSAGE :
message(sockfd, msg);
printf ("relaymail(): end of case MESSAGE\n");
state++;
printf ("relaymail(): end of case MESSAGE\n");
case QUIT :
quit(sockfd);
state++;
printf ("end of case QUIT\n");
closesocket(sockfd);
break;
default :
break;
}
} // while()
closesocket(sockfd);
}
/* remove < > */
char* remove_brackets(char* input)
{
int length;
int i, j;
char* output;
length = strlen(input);
output = (char*) malloc(length + 1);
j = 0;
/* copy character of input which in not equal to < or > to output */
for (i=0; i<length; i++)
if ((input[i]!='<') && (input[i]!='>'))
{
output[j] = input[i];
j++;
}
output[j] = '\0';
return output;
}
/* trim the space(s) before and after the string */
char* trim_space(char* input)
{
int i, j, length, is_ch, is_end, end_pos;
char *output;
/* trim the space(s) before the string */
length = strlen(input);
output = (char*) malloc (length+1);
is_ch = 0;
is_end = 0;
j = 0;
for(i=0; i<length; i++)
{
/* copy input characters to output */
if (is_ch==1 || !isspace(input[i]))
{
output[j] = input[i];
j++;
is_ch = 1;
}
}
output[j] = '\0';
/* trim the space(s) after the string */
length = strlen(output);
end_pos = length-1;
is_end = 0;
for (i=0; i<length; i++)
if (is_end==0 && isspace(output[i]))
{
is_end = 1;
end_pos = i;
}
else if (!isspace(output[i]))
is_end = 0;
output[end_pos] = '\0';
return output;
}
/* convert : MAIL FROM: a@a.com ---> a@a.com */
char *extractemail(const char *buf, const int i){
char * email = NULL;
char * tmp_email = NULL;
char * tmp_email2 = NULL;
char * tmp_email3 = NULL;
/* extract email address */
/* 1. remove MAIL FROM: */
email = malloc(strlen(buf));
strcpy(email,buf);
email += i;
printf("\n");
printf("email =%s\n", email);
printf("email length =%i\n", strlen(email));
printf("\n");
/* 2. trim head and trailing whitespace */
tmp_email = trim_space(email);
printf("trimmed email= %s\n", tmp_email);
/* 3. remove <> */
tmp_email2 = remove_brackets(tmp_email);
printf("remove<> email= %s\n", tmp_email2);
/* 4. trim again */
// tmp_email3 = trim_space("ellen@cs.com.hk");
// printf("\n");
// printf("extracted email= ~~~~~~%s~~~~~~\n", tmp_email3);
// printf("\n");
// printf("extracted email= ~~~~~~%s~~~~~~\n", tmp_email3);
return tmp_email2;
}
/* check if email address is a valid one */
int check_email_validity(const char *address) {
// check if email address is valid
// return 1 if valid
// return 0 if invalid
int number = 0;
const char *a, *host;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -