///*0
// * tcp-server.c
// *
// * Created on: 2012-3-12
// * Author: root
// */
#include<stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>//man in.h
#include <arpa/inet.h rel='nofollow' onclick='return false;'>//man inet_addr
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include<time.h>
#include<string.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "base64.h"
#include <wait.h>
#include "SMTP.h"
#define Msg_Wel "220 welcome to zhongchan's smtp server\r\n"
#define Msg_Rig "250 operation success\r\n"
#define Msg_Put "354 end with .\r\n"
#define Msg_Wrn "500 No command is implement\r\n"
#define Msg_Quit "221 Quit success\r\n"
#define mail_box "/opt/mailbox"
//char des[48]={'\0'};
char mailfrom[48]={'\0'};
char tranMsg[10*1024*1024]={'\0'};
pthread_t localtid;
//typedef struct para{
// int newfd;
// char tranIP[48];
//}Para;
MAILTO* head = NULL;
int getIPByDomin(char* domin,char* ip){
printf("the domin=%s\n",domin);
printf("access to getIpByDomin\n");
FILE* fp_src = fopen("domin.conf","r");
while(1){
char buf[128] = {'\0'};
char *p = fgets(buf,sizeof(buf),fp_src);
printf("getIPByDomin buf=%s\n",buf);
char str[128]={'\0'};
strcpy(str,buf);
char *q=strstr(str,"=");
*q='\0';
++q;
printf("getIPByDomin domin=%s\n",q);
if(p == NULL) break;
if(strncmp(q,domin,strlen(domin))== 0 ) {
strcpy(ip,str);
printf("ip=%s\n",ip);
fclose(fp_src);
return 0;}
}
fclose(fp_src);
return -1;
}
void insert_back(char* name,char*domin)
{
printf("access to insert_back\r\n");
MAILTO* p = malloc(sizeof(MAILTO));
strcpy(p->Domin,domin);
strcpy(p->name,name);
strcpy(p->Mailfrom,mailfrom);
char ip[128]={'\0'};
getIPByDomin(domin,ip);
strcpy(p->IP,ip);
p->next = NULL;
MAILTO* q=head;
if(head==NULL){head=p;return;}
while(q->next!=NULL)
{
q=q->next;
}
q->next=p;
}
void clear() {
MAILTO *q1 = head->next;
MAILTO* p=head;
head=NULL;
while (p) {
free(p);
p= q1;
q1 = p->next;
}
}
void travel(MAILTO* h) {
printf("%s\n",mailfrom);
printf("access to travel\n");
MAILTO*p = h;
while (p != NULL) {
printf("%s %s %s %s\n", p->Mailfrom,p->name,p->Domin,p->IP);
p = p->next;
}
printf("\n");
}
void takepartStringBySpace(char* buf,char* key,char* val){
char str[128]={'\0'};
strcpy(str,buf);
printf("takepartStringBySpace buf=%s\n",buf);
printf("takepartStringBySpace str=%s\n",str);
char*p=strstr(str,"\r\n");
*p='\0';
char*q =strstr(str," ");
if(q!=NULL) {
*q='\0';
++q;
strcpy(val,q);
}
else strcpy(val,"");
strcpy(key,str);
}
//char* takepartStringByOther(char* msg){
// char *p=strstr(msg,":");
// if(p){*p='\0';p++;}
// return p;
//}
int readLine(int fd, char* buf, int size) {
int i;
for (i = 0; i < size - 2; ++i) {
int n = recv(fd, buf + i, 1, 0);
if (1 == n) {
if (buf[i] == '\n')
break;
} else {
perror("readLine");
return -1;
}
}
buf[++i] = '\0';
return i;
}
//
void doWel(int newfd){
send(newfd, Msg_Wel, strlen(Msg_Wel), 0);
}
void doHelo(int newfd,char* val){
send(newfd, Msg_Rig, strlen(Msg_Rig), 0);
}
void doEhlo(int newfd,char* val){
char buf[1024]={'\0'};
strcat(buf,"250-hz-b-126smtp2.126.com\r\n");
strcat(buf,"250-mail\r\n");
strcat(buf,"250-PIPELINING\r\n");
strcat(buf,"250-8BITMIME\r\n");
strcat(buf,"250-AUTH LOGIN PLAIN\r\n");
strcat(buf,"250-AUTH=LOGIN PLAIN\r\n");
strcat(buf,"250 STARTTLS 56c2a3da-fb90-48de-ae69-ab45c66f01fb\r\n");
send(newfd, buf, strlen(buf), 0);
}
void doAuth(int newfd){
char* buf="334 VXNlcm5hbWU6(Username)\r\n";
send(newfd, buf, strlen(buf), 0);
char strcode[100]={'\0'};
readLine(newfd,strcode,sizeof(strcode));
int len=1;
char *cname=base64_decode(strcode,&len);
buf="334 UGFzc3dvcmQ6(Password)\r\n";
send(newfd,buf,strlen(buf),0);
bzero(strcode,100);
readLine(newfd,strcode,sizeof(strcode));
char *cpass=base64_decode(strcode,&len);
int fd=open("user.conf",O_RDONLY);
if(fd<0)perror("open");
printf("accee to while\n");
FILE* fp_src = fopen("user.conf","r");
while(1){
char buf1[128]={'\0'};
char *p = fgets(buf1,sizeof(buf1),fp_src);
if (p == NULL)
break;
char str[128] = { '\0' };
strcpy(str, buf1);
char *q = strstr(str, "=");
*q = '\0';
++q;
if(strncmp(str,cname,strlen(cname))==0 && strncmp(q,cpass,strlen(cpass))==0) {
strcpy( buf,"235 auth successfully\r\n");
send(newfd,buf,strlen(buf),0);
return;
}
}
strcpy( buf,"500-AUTH=LOGIN PLAIN Login failure\r\n");
send(newfd,buf,strlen(buf),0);
}
void doMail(int newfd,char* val){
char val2[48]={'\0'};
strcpy(val2,val);
char* p=strstr(val2,"<");
char* q=strstr(val2,">");
*q='\0';
strcpy(mailfrom,++p);
printf("mailfrom=%s\n",mailfrom);
send(newfd, Msg_Rig, strlen(Msg_Rig), 0);
}
void doRcpt(int newfd,char* val){
send(newfd, Msg_Rig, strlen(Msg_Rig), 0);
travel(head);
char str[128]={'\0'};
strcpy(str,val);
char* m=strstr(str,"<");
++m;
char* s=strstr(str,">");
*s='\0';
char *p=strstr(str,"@");
*p='\0';
++p;
printf("doRcpt name=%s domin=%s\n",m,p);
insert_back(m,p);
travel(head);
}
void doRset(int newfd,char* val){
send(newfd, Msg_Rig, strlen(Msg_Rig), 0);
}
void* thread_func3(void* p) {
MAILTO *ppa = p;
//int newfd =ppa->newfd;
char tranip[48]={'\0'};
printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>ass to thread_func3\n");
strcpy(tranip,ppa->IP);
printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ip%s\n",tranip);
int transockfd = socket(PF_INET, SOCK_STREAM, 0);
if (transockfd == -1) {
perror("socket");
pthread_exit(NULL);
}
int opt =1;
setsockopt(transockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
struct sockaddr_in ser_addr;
ser_addr.sin_family = PF_INET;
ser_addr.sin_addr.s_addr = inet_addr(tranip);
ser_addr.sin_port = htons(25);//network byte order
if(connect(transockfd,(struct sockaddr *)(&ser_addr),sizeof(struct sockaddr))==-1)
{
perror("Connect");
//fprintf(stderr,"Connect Error:%s\a\n",strerror(errno));
pthread_exit(NULL);
}
printf("smtp client is ready!\n");
char buf[128]={'\0'};
char reply[128]={'\0'};
readLine(transockfd,reply,sizeof(reply));
printf("%s\n",reply);
if(strncmp(reply,"220",3)==0){
strcpy(buf,"helo zc.com\r\n");
write(transockfd,buf,strlen(buf));
bzero(reply,128);
readLine(transockfd,reply,sizeof(reply));
printf("%s\n",reply);
bzero(buf,128);
sprintf(buf,"MAIL FROM: <%s>\r\n",mailfrom);
printf("%s\n",buf);
write(transockfd,buf,strlen(buf));
bzero(reply,128);
readLine(transockfd,reply,sizeof(reply));
printf("%s\n",reply);
bzero(buf,128);
sprintf(buf,"RCPT TO: <%s@%s>\r\n",ppa->name,ppa->Domin);
printf("%s\n",buf);
write(transockfd,buf,strlen(buf));
bzero(reply,128);
readLine(transockfd,reply,sizeof(reply));
printf("%s\n",reply);
bzero(buf,128);
strcpy(buf,"DATA\r\n");
printf("%s\n",buf);
write(transockfd,buf,strlen(buf));
bzero(reply,sizeof(reply));
readLine(transockfd,reply,sizeof(reply));
if(strncmp(reply,"354",3)==0){
write(transockfd,tranMsg,strlen(tranMsg));
write(transockfd,".\r\n",3);
}else close(transockfd);
bzero(buf,128);
strcpy(buf,"QUIT\r\n");
write(transockfd,buf,strlen(buf));
bzero(reply,sizeof(reply));
readLine(transockfd,reply,sizeof(reply));
printf("%s\n",reply);
if(strncmp(reply,"221",3)==0){
close(transockfd);
}
}else close(transockfd);
return N