📄 parse_~2.cpp
字号:
/* parse_mail_headers.cpp*/#define _GNU_SOURCE#include <string.h>#include <sys/types.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <time.h>#include <syslog.h>#include <errno.h>#include "inbox_page.h"#include "session.h"#include "parse_mail_headers.h"#include "main.h"#include "mail_process.h"#include "view_message.h"#include "encoding_conv.h"#include "custom_string.h"char* get_head_data(FILE*, char**, size_t*);time_t compute_time(char*);char* get_ct_string(char*);char* get_parameter_value(char*,char*);int parse_rfc2047(char**);char parse_rfc2047_token(char*, char**, char**);int unencode_rfc2047_quoted_printable(char*, char*, char*);int unencode_rfc2047_base64(char*, char*, char*);int quoted_unencode(char*);int conv_from_ascii_hex(char);void free_mh_data(struct mail_header*);int inbox_size;////////////////////////////////////////////////////////////////////////This will pull all mail headers from a users mailfile. Used during inbox// displaystruct mail_header* get_mail_headers(void){ FILE* user_mail_file=NULL; int m_num=1; int err=0; struct mail_header* first_mh_data; struct mail_header* next_header_ptr; const char* stupid_imap_message="DON'T DELETE THIS MESSAGE"; inbox_size=0; setgid(egid); user_mail_file=open_user_mailfile("r"); setgid(rgid); if(user_mail_file == NULL) { if(errno != 0) errno=-1; else errno=0; return( (struct mail_header*) NULL); } m_num=1; //Create initial mail header structure first_mh_data=fill_mail_h_struct(user_mail_file,m_num++); if(first_mh_data != NULL) err=point_to_next_message(user_mail_file, &(first_mh_data->size_of_message)); if(first_mh_data != NULL && first_mh_data->subject != NULL) if(strncmp(first_mh_data->subject,stupid_imap_message, strlen(stupid_imap_message)) == 0) { syslog(LOG_MAIL | LOG_INFO,"IMAP message found for %s", user_ses.loginname); free_mh_data(first_mh_data); first_mh_data=NULL; first_mh_data=fill_mail_h_struct(user_mail_file,m_num++); if(first_mh_data != NULL) err=point_to_next_message(user_mail_file, &(first_mh_data->size_of_message)); } if(first_mh_data == NULL) { fclose(user_mail_file); errno=0; return((struct mail_header*) NULL); } next_header_ptr=first_mh_data; //Parse mail file headers while(next_header_ptr != NULL && err == 0) { next_header_ptr->next_header= fill_mail_h_struct(user_mail_file,m_num++); next_header_ptr=next_header_ptr->next_header; if(next_header_ptr != NULL) err=point_to_next_message(user_mail_file, &(next_header_ptr->size_of_message)); } fclose(user_mail_file); return(first_mh_data);}////////////////////////////////////////////////////////////////////////This will initialize a mail_header structurevoid init_mail_header(struct mail_header* mh_data){ mh_data->m_num=0; mh_data->next_header=NULL; mh_data->size_of_message=0; mh_data->mail_status=m_new; mh_data->date_received=0; mh_data->from=NULL; mh_data->to=NULL; mh_data->cc=NULL; mh_data->reply_to=NULL; mh_data->subject=NULL; mh_data->cont_type=ct_none; mh_data->cont_type_string=NULL; mh_data->cont_boundary=NULL; mh_data->cont_type_enc=cte_none; mh_data->cont_disposition=ctd_none; mh_data->filename=NULL;}//////////////////////////////////////////////////////////////////////// This function will read the mail header the current file pointer points// to, allocate a mail_header structure, and fill itstruct mail_header* fill_mail_h_struct(FILE* user_mail_file,int m_num){ char* file_buff=NULL; size_t file_buff_size=0; ssize_t b_read=0; char* char_buff=NULL; struct mail_header* mh_data=NULL; enum h_done { hd_pending, hd_done, hd_error } header_done=hd_pending; if(user_mail_file == NULL) { syslog(LOG_MAIL | LOG_ERR,"fill_mail_h_struct was passed NULL file"); return( (struct mail_header*) NULL ); //sanity check } if( feof(user_mail_file) != 0 ) { syslog(LOG_MAIL | LOG_INFO,"End of file found during mail_h_fill."); return( (struct mail_header*) NULL ); //sanity check } mh_data=(struct mail_header*) malloc(sizeof(struct mail_header)); if(mh_data == NULL) { syslog(LOG_MAIL | LOG_ERR,"Out of memory (%s)",strerror(errno)); return( mh_data ); } init_mail_header(mh_data); mh_data->m_num=m_num; do { b_read=getline(&file_buff,&file_buff_size,user_mail_file); mh_data->size_of_message+=b_read; if(b_read <= 0 || file_buff == NULL) header_done=hd_error; else if(*file_buff == '\n') header_done=hd_done; else if(strncasecmp(file_buff,"From:",sizeof("From:") -1 ) == 0 && mh_data->from == NULL) { char_buff= get_head_data(user_mail_file, &file_buff, &file_buff_size); mh_data->from=parse_addr(&char_buff); } else if(strncasecmp(file_buff,"To:",sizeof("To:") - 1 ) == 0 && mh_data->to == NULL) { char_buff= get_head_data(user_mail_file, &file_buff, &file_buff_size); mh_data->to=parse_addr(&char_buff); } else if(strncasecmp(file_buff,"Cc:", sizeof("cc:")-1) == 0 && mh_data->cc == NULL) { char_buff= get_head_data(user_mail_file, &file_buff, &file_buff_size); mh_data->cc=parse_addr(&char_buff); } else if(strncasecmp(file_buff,"Reply-To:", sizeof("Reply-To:")-1 ) == 0 && mh_data->reply_to == NULL) { char_buff= get_head_data(user_mail_file, &file_buff, &file_buff_size); mh_data->reply_to=parse_addr(&char_buff); } else if(strncasecmp(file_buff,"Subject:",sizeof("Subject:")-1 ) == 0 && mh_data->subject == NULL) mh_data->subject= get_head_data(user_mail_file, &file_buff, &file_buff_size); else if(strncasecmp(file_buff,"Status:", sizeof("Status:")-1 ) == 0 && strlen(file_buff) >=8 && strchr(file_buff+8,'R') != NULL) mh_data->mail_status=m_read; else if(strncasecmp(file_buff,"Date:", sizeof("Date:")-1) == 0 ) { char_buff= get_head_data(user_mail_file, &file_buff, &file_buff_size); mh_data->date_received=compute_time(char_buff); if(char_buff != NULL) { free(char_buff); char_buff=NULL; } } else if( strncasecmp(file_buff, "Content-Type:", sizeof("Content-Type:")-1 ) == 0 && char_buff == NULL) { char_buff= get_head_data(user_mail_file, &file_buff, &file_buff_size); if(mh_data->cont_type_string == NULL) mh_data->cont_type_string = get_ct_string(char_buff); mh_data->cont_type= determine_content_type(mh_data->cont_type_string); if(mh_data->cont_type == ct_multipart_mixed || mh_data->cont_type == ct_multipart_alternative || mh_data->cont_type == ct_multipart_parallel || mh_data->cont_type == ct_multipart_digest || mh_data->cont_type == ct_multipart_other ) if(mh_data->cont_boundary == NULL) mh_data->cont_boundary= get_parameter_value(char_buff,"boundary"); if(mh_data->filename == NULL) mh_data->filename=get_parameter_value(char_buff,"name"); free(char_buff); char_buff=NULL; } else if( strncasecmp(file_buff, "Content-Transfer-Encoding:", sizeof("Content-Transfer-Encoding:")-1) == 0 && char_buff == NULL) { char_buff= get_head_data(user_mail_file, &file_buff, &file_buff_size); mh_data->cont_type_enc=determine_content_type_enc(char_buff); free(char_buff); char_buff=NULL; } else if (strncasecmp(file_buff, "Content-Disposition:", sizeof("Content-Disposition:") -1 ) == 0) { char_buff= get_head_data(user_mail_file, &file_buff, &file_buff_size); if(char_buff != NULL) { if(strncasecmp(char_buff,"inline",sizeof("inline")-1) == 0) mh_data->cont_disposition=ctd_inline; else if(strncasecmp(char_buff,"attachment",sizeof("attachment")-1) == 0) mh_data->cont_disposition=ctd_attachment; } if(char_buff != NULL) { if(mh_data->filename != NULL) free(mh_data->filename); mh_data->filename=get_parameter_value(char_buff,"filename"); } free(char_buff); char_buff=NULL; } } while(header_done == hd_pending); if(file_buff != NULL) free(file_buff); if(header_done == hd_error) { free_mail_headers(mh_data); return(NULL); } return(mh_data);}////////////////////////////////////////////////////////////////////////This will return a newly allocated string that follows a ':' in the // passed string that contains a read mail header line. It will then// check the next line to see if it is a continuation (long header line)// returns a string that starts with the first non - LWSP char following// the first ':' in the string. Will concatinate any line continuations// and eliminate any LWSP at the start of the next line.char* get_head_data(FILE* user_mail_file, char** file_buff, size_t* file_buff_size){ size_t new_size=0; size_t b_read=0; size_t skip_set=0; char* start=NULL; char* new_buff=NULL; char* temp_buff=NULL; int next_char='\0'; enum status_type { st_pending, st_done, st_error }; status_type status=st_pending; if(user_mail_file == NULL || *file_buff == NULL || file_buff_size == NULL) return(NULL);//Find ':' start=strchr(*file_buff,':'); if(start == NULL) return(NULL); start++;//Get rid of initial LWSP start+=strspn(start," \t"); if(*start == '\n' || *start == '\0') return(NULL); new_buff=strdup(start); if(new_buff == NULL) return(NULL);//get rid of nl character start=strchr(new_buff,'\n'); if(start != NULL) *start=' ';// check if next line(s) have LWSP characters at start. // If so, read them in also. do { next_char=fgetc(user_mail_file); if(! (next_char == '\t' || next_char == ' ') ) { ungetc(next_char,user_mail_file); status=st_done; } else { b_read=getline(file_buff,file_buff_size,user_mail_file); if(b_read <= 0 || file_buff == NULL) status=st_error; else {//Get rid of remaining LWSP before copy skip_set=strspn(*file_buff," \t"); start=*file_buff+skip_set; new_size=strlen(new_buff) + strlen(start) + 1;//resize buffer temp_buff=(char*)realloc(new_buff,new_size); if(temp_buff == NULL) { if(new_buff != NULL) { free(new_buff); new_buff=NULL; } status=st_error;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -