📄 send_m~1.cpp
字号:
/* send_message.cpp*/#define _GNU_SOURCE#include <stdio.h>#include <stdlib.h>#include <string.h>#include <syslog.h>#include <errno.h>#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/stat.h>#include <signal.h>#include "parse_form.h"#include "environment.h"#include "config.h"#include "session.h"#include "main.h"#include "random.h"#include "inbox_page.h"#include "err_page.h"#include "mail_process.h"#include "parse_mail_headers.h"#include "view_message.h"#include "preferences.h"#include "headers.h"struct send_info { char* from; addr_t* to; addr_t* cc; addr_t* bcc; char* subject; char* body; FILE* att; char* filename; char* att_cont_type; char* new_boundary; int refw; FILE* refw_file; mail_header* mail_h;};int init_send_info_struct(send_info*);int delete_send_info_struct(send_info*);int fill_send_info_struct(send_info*);int cleanup_send_info_struct(send_info*);int gen_header(char*, char**);int send_attachment(struct send_info*, FILE*);int conv_to_base64(int*, char*);int base64_char_conv(int);int sendmail_fork_child_process(int*);int sendmail_fork_parent_process(int*, pid_t, send_info*);int init_refw_msg(struct send_info*);int send_refw_message(FILE*, struct send_info*);int send_addr(FILE*, addr_t*);int err_addr(send_info*);////////////////////////////////////////////////////////////////////// This function gets send_mail info from stdin, generates a mail// message, and forks a sendmail process to deliver the messageint send_message_action(void){ int err=0; pid_t pid=0; send_info info; int fdes[2]; init_send_info_struct(&info); err=fill_send_info_struct(&info); if(err != 0 && err != 1) { syslog(LOG_MAIL | LOG_ERR,"Error setting up mail to send. " "User abort?"); err_page(); return(-1); } if( (cleanup_send_info_struct(&info)) != 0) { delete_send_info_struct(&info); return(-1); } if(info.refw != -1) //if this is a reply/forward message and we need to attach { // a previous message (non-text) if(init_refw_msg(&info) != 0) { syslog(LOG_MAIL | LOG_ERR,"Could not attach refw message."); err_string_page("Send message failed."); delete_send_info_struct(&info); return(-1); } } fflush(stdout); if(pipe(fdes) != 0) { syslog(LOG_MAIL | LOG_ERR,"pipe failed (%s)",strerror(errno)); err_page(); delete_send_info_struct(&info); return(-1); } pid=fork(); if(pid == 0) { sendmail_fork_child_process(fdes); exit(-1); } else if(pid > 0) err=sendmail_fork_parent_process(fdes,pid,&info); else { syslog(LOG_MAIL | LOG_ERR,"fork failed (%s)",strerror(errno)); err_page(); delete_send_info_struct(&info); return(-1); } delete_send_info_struct(&info); if(err == 0) inbox_action(); else err_string_page("Send message failed."); return(0);}///////////////////////////////////////////////////////////////////int sendmail_fork_parent_process(int* fdes, pid_t child_pid, send_info* info){ FILE* out_pipe=NULL; int status=0; int err=0; close(fdes[0]); out_pipe=fdopen(fdes[1],"w"); if(info->att != NULL && info->new_boundary == NULL) { info->new_boundary=get_rand_string(20); if(info->new_boundary == NULL) { syslog(LOG_MAIL | LOG_ERR,"Out of memory."); kill(child_pid,SIGKILL); return(-1); } } if(info->from != NULL) fprintf(out_pipe,"%s\n",info->from); if(info->to != NULL) { fprintf(out_pipe,"To: "); send_addr(out_pipe,info->to); } if(info->cc != NULL) { fprintf(out_pipe,"cc: "); send_addr(out_pipe,info->cc); } if(info->bcc != NULL) { fprintf(out_pipe,"bcc: "); send_addr(out_pipe,info->bcc); } if(info->subject != NULL) fprintf(out_pipe,"%s\n",info->subject); fprintf(out_pipe,"X-Mailer: Nmail " VERSION "\n"); fprintf(out_pipe,"MIME-Version: 1.0\n"); if(info->new_boundary != NULL) fprintf(out_pipe,"Content-Type: multipart/mixed;\n\tboundary=\"%s\"\n", info->new_boundary); fprintf(out_pipe,"\n"); if(info->body != NULL) { if(info->new_boundary != NULL) { fprintf(out_pipe,"\n--%s\n",info->new_boundary); fprintf(out_pipe,"Content-Type: text/plain\n\n"); } fprintf(out_pipe,"%s\n",info->body); } if(info->att != NULL) { send_attachment(info,out_pipe); } if(info->refw_file != NULL) if(send_refw_message(out_pipe,info) != 0) { kill(child_pid,SIGKILL); syslog(LOG_MAIL | LOG_ERR,"Error sending reply/forward."); return(-1); } if(info->mail_h != NULL) if(info->mail_h->cont_type == ct_multipart_alternative) fprintf(out_pipe,"\n--%s--\n",info->mail_h->cont_boundary); if(info->new_boundary != NULL) fprintf(out_pipe,"\n--%s--\n",info->new_boundary); fclose(out_pipe); err=waitpid(child_pid,&status,WUNTRACED); return(status);}///////////////////////////////////////////////////////////////////int sendmail_fork_child_process(int* fdes){ close(fdes[1]); dup2(fdes[0],0); close(fdes[0]); dup2(2,1); //redirect stdout to stderr // sendmail should not stdout char* from={"-f"};#ifndef SENDMAIL_N_U char* new_argv[]={SENDMAIL,"-bm","-i","-t","-U",NULL,NULL,NULL,NULL}; #define START_ARG 5#else char* new_argv[]={SENDMAIL,"-bm","-i","-t",NULL,NULL,NULL,NULL}; #define START_ARG 4#endif if( strncmp(user_pref.reply_to.email, user_ses.loginname, strlen(user_ses.loginname)) == 0) { new_argv[START_ARG]=from; new_argv[START_ARG+1]=user_pref.reply_to.email; } setreuid(euid,euid); execv(SENDMAIL,new_argv); syslog(LOG_MAIL | LOG_ERR,"sendmail exec failed (%s)",strerror(errno)); exit(-1);}///////////////////////////////////////////////////////////////////int send_addr(FILE* out_pipe, addr_t* addr){ int x=0; if(addr == NULL) return(-1); for(x=0; addr[x].name || addr[x].email; x++) { if(addr[x].email != NULL) { if(x != 0) fprintf(out_pipe,"\t, "); if(addr[x].name != NULL) fprintf(out_pipe,"\"%s\" <%s>\n",addr[x].name,addr[x].email); else fprintf(out_pipe, "%s\n",addr[x].email); } } if(x == 0) { fprintf(out_pipe,"\n"); return(-1); } return(0);}///////////////////////////////////////////////////////////////////// This function will parse all the header lines and make them// fit the 76 char max by folding fields as necessaryint cleanup_send_info_struct(send_info* info){ int flag=0; int x=0; int y=0; if(info == NULL) return(-1); if(info->from != NULL) if(gen_header("From: ",&(info->from)) != 0) return(-1); if(info->subject != NULL) if(gen_header("Subject: ",&(info->subject)) != 0) return(-1); if(info->to == NULL && info->cc == NULL && info->bcc == NULL) { //if no recepients, this is an error err_addr(info); return(-1); } /* if names without email, need to check address book */ if(info->to != NULL) for(x=0; info->to[x].name || info->to[x].email; x++) if(info->to[x].email == NULL) flag=-1; /* if names without email, need to check address book */ if(info->cc != NULL) for(x=0; info->cc[x].name || info->cc[x].email; x++) if(info->cc[x].email == NULL) flag=-1; /* if names without email, need to check address book */ if(info->bcc != NULL) for(x=0; info->bcc[x].name || info->bcc[x].email; x++) if(info->bcc[x].email == NULL) flag=-1; /* if names without email and no address book */ if(flag != 0) { /* we cannot find name in address book, so error */ if(user_pref.addr == NULL) { err_addr(info); return(-1); } } flag=0; if(info->to != NULL) for(x=0; info->to[x].name || info->to[x].email; x++) { //for every name in TO line... /* if no email just name, try to find it in address book */ if(info->to[x].email == NULL) { for(y=0; user_pref.addr[y].name || user_pref.addr[y].email; y++) { if(user_pref.addr[y].name != NULL && user_pref.addr[y].email != NULL) if(strcasecmp(user_pref.addr[y].name,info->to[x].name) == 0) { info->to[x].email=strdup(user_pref.addr[y].email); break; } } if(info->to[x].email == NULL) flag=-1; } } if(info->cc != NULL) for(x=0; info->cc[x].name || info->cc[x].email; x++) { //for every name in CC line... /* if no email just name, try to find it in address book */ if(info->cc[x].email == NULL) { for(y=0; user_pref.addr[y].name || user_pref.addr[y].email; y++) { if(user_pref.addr[y].name != NULL && user_pref.addr[y].email != NULL) if(strcasecmp(user_pref.addr[y].name,info->cc[x].name) == 0) info->cc[x].email=strdup(user_pref.addr[y].email); } if(info->cc[x].email == NULL) flag=-1; } } if(info->bcc != NULL) for(x=0; info->bcc[x].name || info->bcc[x].email; x++) { //for every name in BCC line... /* if no email just name, try to find it in address book */ if(info->bcc[x].email == NULL) { for(y=0; user_pref.addr[y].name || user_pref.addr[y].email; y++) { if(user_pref.addr[y].name != NULL && user_pref.addr[y].email != NULL) if(strcasecmp(user_pref.addr[y].name,info->bcc[x].name) == 0) info->bcc[x].email=strdup(user_pref.addr[y].email); } if(info->bcc[x].email == NULL) flag=-1; } } if(flag != 0) //if there were any names without email and we { // could not find them in address book, error err_addr(info); return(-1); } return(0);}////////////////////////////////////////////////////////////////////// This function will parse the cgi name/values and fill the send_info structint fill_send_info_struct(send_info* info){ char* tmp_ptr=NULL; cgi_t* cgi_data=NULL; while( get_cgi_data(&cgi_data) == 0) { if(strcmp(cgi_data->name,"from") == 0) { if(info->from == NULL) { info->from=cgi_data->value; cgi_data->value=NULL; free(cgi_data->name); cgi_data->name=NULL; } } else if(strcmp(cgi_data->name,"to") == 0) { if(info->to == NULL) { info->to=parse_addr(&(cgi_data->value)); free(cgi_data->name); cgi_data->name=NULL; } } else if(strcmp(cgi_data->name,"cc") == 0) { if(info->cc == NULL) { info->cc=parse_addr(&(cgi_data->value)); free(cgi_data->name); cgi_data->name=NULL; } } else if(strcmp(cgi_data->name,"bcc") == 0) { if(info->bcc == NULL) { info->bcc=parse_addr(&(cgi_data->value)); free(cgi_data->name); cgi_data->name=NULL; } } else if(strcmp(cgi_data->name,"subject") == 0) { if(info->subject == NULL) { info->subject=cgi_data->value; cgi_data->value=NULL; free(cgi_data->name); cgi_data->name=NULL; } } else if(strcmp(cgi_data->name,"body") == 0) { if(info->body == NULL) { info->body=cgi_data->value; cgi_data->value=NULL; free(cgi_data->name); cgi_data->name=NULL; } } else if(strcmp(cgi_data->name,"attachment") == 0) { if(cgi_data->filename != NULL && *(cgi_data->filename) != '\0') { tmp_ptr=strrchr(cgi_data->filename,'\\'); if(tmp_ptr != NULL) tmp_ptr++; else tmp_ptr=cgi_data->filename; info->filename=strdup(tmp_ptr); } info->att=cgi_data->tmp_file; info->att_cont_type=cgi_data->cont_type; cgi_data->cont_type=NULL; free(cgi_data->name); cgi_data->name=NULL; } else if(strcmp(cgi_data->name,"fwmsg") == 0) { if(cgi_data->value != NULL) info->refw=atol(cgi_data->value); } } return(0);}///////////////////////////////////////////////////////////////////////This function will generate a header file. // buff will be reallocated, head prepended to it, and any// necessary '\n\t' folding will be doneint gen_header(char* head, char** buff){ char* new_buff=NULL; char* tmp_ptr=NULL; size_t new_size=0; char char1=0; char char2=0; char char3=0; if(head == NULL || buff == NULL || *buff == NULL) return(-1); new_size=strlen(head)+strlen(*buff)+1; new_buff=(char*)malloc(new_size); if(new_buff == NULL) { syslog(LOG_MAIL | LOG_ERR,"mem allocation failed (%s)", strerror(errno)); return(-1); } strcpy(new_buff,head); strcat(new_buff,*buff); free(*buff); *buff=new_buff;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -