📄 ssmtp.c
字号:
buf[n]='\0'; // store response message memset(ssmtp_stored_message, '\0', MAXDATASIZE); for( i=0; i<n; i++ ) ssmtp_stored_message[i] = buf[i]; return n; } else { // timeout, retry ? ssmtp_failed(RECV_TIMEOUT); return -1; }}///////////////////////////////////////////////////////////////////////// Function ssmtp_send//// simplely read response from server/////////////////////////////////////////////////////////////////////////int ssmtp_send(SMTP_Client_Info *smtpinfo, char *buf){ if( sendall(smtpinfo->sockfd, buf, strlen(buf)) < 0 ) { ssmtp_failed(SEND_ERR); printf("ssmtp send FAIL !!!!\n"); return -1; } return 0;}///////////////////////////////////////////////////////////////////////// Function ssmtp_ready//// simply read status code from server// to check whetehr server is ready/////////////////////////////////////////////////////////////////////////int ssmtp_ready(SMTP_Client_Info *smtpinfo, char *status_code){ int i; char buf[MAXDATASIZE]; usleep(READ_DELAY); // wait for response, avoid packet split if( ssmtp_read(smtpinfo, buf) < 0 ) return -1; i = strlen(status_code); if( !strncmp(status_code, buf, i) ) { // status code match, return 0 dbgmsg("%s", ssmtp_stored_message); return 0; } else { // status code not match, ssmtp state failed ssmtp_failed(SMTP_FAILED); return -1; }}///////////////////////////////////////////////////////////////////////// Function ssmtp_ehlo//// sends EHLO SMTP command/////////////////////////////////////////////////////////////////////////int ssmtp_ehlo(SMTP_Client_Info *smtpinfo, char *status_code){ int i; char buf[MAXDATASIZE]; strcpy(buf, "EHLO aaa.bbb"); strcat(buf, smtpinfo->domain); strcat(buf, "\r\n"); if( ssmtp_send(smtpinfo, buf) < 0 ) return -1; usleep(READ_DELAY); memset(buf, 0, MAXDATASIZE); if( ssmtp_read(smtpinfo, buf) < 0 ) return -1; i = strlen(status_code); if( !strncmp(status_code, buf, i) ) { // status code match, return 0 dbgmsg("%s", ssmtp_stored_message); return 0; } else { // status code not match, ssmtp state failed ssmtp_failed(SMTP_FAILED); return -1; }}///////////////////////////////////////////////////////////////////////// Function ssmtp_helo//// sends HELO SMTP command/////////////////////////////////////////////////////////////////////////int ssmtp_helo(SMTP_Client_Info *smtpinfo, char *status_code){ int i; char buf[MAXDATASIZE]; strcpy(buf, "HELO aaa.bbb\r\n"); if( ssmtp_send(smtpinfo, buf) < 0 ) return -1; usleep(READ_DELAY); memset(buf, 0, MAXDATASIZE); if( ssmtp_read(smtpinfo, buf) < 0 ) return -1; i = strlen(status_code); if( !strncmp(status_code, buf, i) ) { // status code match, return 0 dbgmsg("%s", ssmtp_stored_message); return 0; } else { // status code not match, ssmtp state failed ssmtp_failed(SMTP_FAILED); return -1; }}///////////////////////////////////////////////////////////////////////// Function ssmtp_mail//// sends MAIL SMTP command/////////////////////////////////////////////////////////////////////////int ssmtp_mail(SMTP_Client_Info *smtpinfo, char *status_code){ int i; char buf[MAXDATASIZE]; strcpy(buf, "MAIL FROM: <"); strcat(buf, smtpinfo->fromaddr); strcat(buf, ">\r\n"); printf(buf); if( ssmtp_send(smtpinfo, buf) < 0 ) return -1; usleep(READ_DELAY); memset(buf, 0, MAXDATASIZE); if( ssmtp_read(smtpinfo, buf) < 0 ) return -1; i = strlen(status_code); if( !strncmp(status_code, buf, i) ) { // status code match, return 0 dbgmsg("%s", ssmtp_stored_message); return 0; } else { // status code not match, ssmtp state failed ssmtp_failed(SMTP_FAILED); return -1; }}///////////////////////////////////////////////////////////////////////// Function ssmtp_rcpt//// sends RCPT SMTP command/////////////////////////////////////////////////////////////////////////int ssmtp_rcpt(SMTP_Client_Info *smtpinfo,SMTP_Mail_Info *mail , char *status_code){ int i; char buf[MAXDATASIZE]; strcpy(buf, "RCPT TO:<"); strcat(buf, mail->to); strcat(buf, ">\r\n"); if( ssmtp_send(smtpinfo, buf) < 0 ) return -1; usleep(READ_DELAY); memset(buf, 0, MAXDATASIZE); if( ssmtp_read(smtpinfo, buf) < 0 ) return -1; i = strlen(status_code); if( !strncmp(status_code, buf, i) ) { // status code match, return 0 dbgmsg("%s", ssmtp_stored_message); return 0; } else { // status code not match, ssmtp state failed ssmtp_failed(SMTP_FAILED); return -1; }}///////////////////////////////////////////////////////////////////////// Function ssmtp_data//// sends DATA SMTP command/////////////////////////////////////////////////////////////////////////int ssmtp_data(SMTP_Client_Info *smtpinfo, char *status_code){ int i; char buf[MAXDATASIZE]; strcpy(buf, "DATA\r\n"); if( ssmtp_send(smtpinfo, buf) < 0 ) return -1; usleep(READ_DELAY); memset(buf, 0, MAXDATASIZE); if( ssmtp_read(smtpinfo, buf) < 0 ) return -1; i = strlen(status_code); if( !strncmp(status_code, buf, i) ) { // status code match, return 0 dbgmsg("%s", ssmtp_stored_message); return 0; } else { // status code not match, ssmtp state failed ssmtp_failed(SMTP_FAILED); return -1; }}///////////////////////////////////////////////////////////////////////// Function ssmtp_data//// send whole content including attachment/////////////////////////////////////////////////////////////////////////int ssmtp_content(SMTP_Client_Info *smtpinfo, SMTP_Mail_Info * mailinfo,char *status_code){ FILE *infile = NULL, *fp; int i; char buf[MAXDATASIZE]; unsigned char raw; char *headers=0; char *ctype=0; long maxsize=0; char mimetmpfile[80]; strcpy(mimetmpfile ,"ltkjwarnMail"); strcat(mimetmpfile,"mime.tmp");#if 1 strcpy(buf, "dummy");#else strcpy(buf, "Date: "); strncat(buf, mail_date, strlen(mail_date)-1); // must strip \n and then plus \r\n strcat(buf, "\r\n"); strcat(buf, "From: "); strcat(buf, smtpinfo->fromaddr); strcat(buf, "\r\n"); strcat(buf, "To: "); strcat(buf, mailinfo->to); strcat(buf, "\r\n");#endif if( sendall(smtpinfo->sockfd, buf, strlen(buf)) < 0 ) return -1; // open file and send if(mailinfo->attachment){ if( (infile = fopen(mailinfo->attachment, "r")) == NULL ) { perror("ssmtp: open"); ssmtp_failed(PIC_OPEN_ERR); return -1; } fseek(infile, 0, SEEK_SET); // seek to beginning } // MIME encode and output to temporary file TMPFILE encode(infile, (FILE *)0, mailinfo->attachment, mailinfo->body, mailinfo->subject, headers, maxsize, ctype, mimetmpfile); usleep(500); // wait file creation // open MIME file if( (fp = fopen(mimetmpfile, "r")) == NULL ) { perror("ssmtp: open"); ssmtp_failed(TMP_OPEN_ERR); return -1; } rewind(fp); // send out the MIME file while( feof(fp)==0 ) { if( fread(&raw, 1, 1, fp) < 0 ) { ssmtp_failed(FILE_READ_ERR); // delete tmporary file fclose(fp); fclose(infile); unlink(mimetmpfile); return -1; } if( sendall(smtpinfo->sockfd, &raw, 1) < 0) { fclose(fp); fclose(infile); unlink(mimetmpfile); return -1; } } // end of mail strcpy(buf, "\r\n.\r\n"); if( sendall(smtpinfo->sockfd, buf, strlen(buf)) < 0 ) { fclose(fp); fclose(infile); unlink(mimetmpfile); return -1; } usleep(READ_DELAY); memset(buf, 0, MAXDATASIZE); if( ssmtp_read(smtpinfo, buf) < 0 ) { fclose(fp); if(infile) fclose(infile); unlink(mimetmpfile); return -1; } i = strlen(status_code); if( !strncmp(status_code, buf, i) ) { // status code match, return 0 fclose(fp); if(infile) fclose(infile); unlink(mimetmpfile); dbgmsg("%s", ssmtp_stored_message); return 0; } else { // status code not match, ssmtp state failed ssmtp_failed(SMTP_FAILED); fclose(fp); if(infile) fclose(infile); unlink(mimetmpfile); return -1; }}///////////////////////////////////////////////////////////////////////// Function to64frombits//// brief Raw bytes in quasi-big-endian order to// base 64 string (NUL-terminated)//// param[out] out A pointer to a char to hold the converted string// param[in] in String to convert// param[in] inlen Length of the string to be converted///////////////////////////////////////////////////////////////////////void to64frombits(unsigned char *out, const unsigned char *in, int inlen){ for (; inlen >= 3; inlen -= 3) { *out++ = base64digits[in[0] >> 2]; *out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)]; *out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)]; *out++ = base64digits[in[2] & 0x3f]; in += 3; } if (inlen > 0) { unsigned char fragment; *out++ = base64digits[in[0] >> 2]; fragment = (in[0] << 4) & 0x30; if (inlen > 1) fragment |= in[1] >> 4; *out++ = base64digits[fragment]; *out++ = (inlen < 2) ? '=' : base64digits[(in[1] << 2) & 0x3c]; *out++ = '='; } *out = '\0';}///////////////////////////////////////////////////////////////////////// Function ssmtp_auth//// sends AUTH command to server/////////////////////////////////////////////////////////////////////////int ssmtp_auth(SMTP_Client_Info *smtpinfo){ char local_in_buf[128]; char local_tmp_buf[128]; char local_out_buf[MAXDATASIZE]; int len; int i; memset(local_tmp_buf,0,sizeof(local_tmp_buf)); // login authentication if( smtpinfo->auth_mech==SASL_LOGIN ) { to64frombits((unsigned char*)local_tmp_buf, (const unsigned char *)smtpinfo->auth_user, strlen(smtpinfo->auth_user)); //asprintf(&local_out_buf,"AUTH LOGIN %s\r\n",local_tmp_buf); strcpy(local_out_buf, "AUTH LOGIN "); strcat(local_out_buf, local_tmp_buf); strcat(local_out_buf, "\r\n"); if( ssmtp_send(smtpinfo, local_out_buf) < 0 ) return -1; // commened by jzks //free(local_out_buf); usleep(READ_DELAY); if( ssmtp_read(smtpinfo, local_in_buf) < 0 ) return -1; dbgmsg("%s", ssmtp_stored_message); if( strncmp(local_in_buf, "3", 1) != 0 ) { ssmtp_failed(SMTP_FAILED); return -1; } memset(local_tmp_buf,0,sizeof(local_tmp_buf)); to64frombits((unsigned char *)local_tmp_buf, (const unsigned char *)smtpinfo->auth_pass, strlen(smtpinfo->auth_pass)); //asprintf(&local_out_buf,"%s\r\n",local_tmp_buf); strcpy(local_out_buf, local_tmp_buf); strcat(local_out_buf, "\r\n"); if( ssmtp_send(smtpinfo, local_out_buf) < 0 ) return -1; //free(local_out_buf); usleep(READ_DELAY); if ( ssmtp_read(smtpinfo, local_in_buf) < 0 ) return -1; dbgmsg("%s", ssmtp_stored_message); if( strncmp(local_in_buf, "2", 1) != 0 ) { ssmtp_failed(SMTP_FAILED); return -1; } } // plain authentication if( smtpinfo->auth_mech==SASL_PLAIN ) { //asprintf(&local_out_buf,"^%s^%s",smtpinfo->auth_user,smtpinfo->auth_pass); strcpy(local_out_buf, "^"); strcat(local_out_buf, smtpinfo->auth_user); strcat(local_out_buf, "^"); strcat(local_out_buf, smtpinfo->auth_pass); len = strlen(local_out_buf); for ( i = len-1 ; i >= 0 ; i-- ) { if (local_out_buf[i]=='^') { local_out_buf[i]='\0'; } } to64frombits((unsigned char *)local_tmp_buf,(const unsigned char *)local_out_buf,len); //free(local_out_buf); //asprintf(&local_out_buf,"AUTH PLAIN %s\r\n",local_tmp_buf); strcpy(local_out_buf, "AUTH PLAIN "); strcat(local_out_buf, local_tmp_buf); strcat(local_out_buf, "\r\n"); if(ssmtp_send(smtpinfo, local_out_buf) < 0 ) return -1; //free(local_out_buf); usleep(READ_DELAY); if( ssmtp_read(smtpinfo, local_in_buf) < 0 ) return -1; dbgmsg("%s", ssmtp_stored_message); if( strncmp(local_in_buf, "2", 1) != 0 ) { ssmtp_failed(SMTP_FAILED); return -1; } } return 0;}///////////////////////////////////////////////////////////////////////// Function ssmtp_quit//// sends QUIT command to server// never mind what server responses/////////////////////////////////////////////////////////////////////////int ssmtp_quit(SMTP_Client_Info *smtpinfo){ int i; char buf[MAXDATASIZE]; strcpy(buf, "QUIT\r\n"); if( ssmtp_send(smtpinfo, buf) < 0 ) return -1; usleep(READ_DELAY); memset(buf, 0, MAXDATASIZE); if( ssmtp_read(smtpinfo, buf) < 0 ) return -1; dbgmsg("%s", ssmtp_stored_message); return 0;}void initClientInfo(SMTP_Client_Info * client){ memset(client, 0 ,sizeof(struct SMTP_Client_Info)); client->port = SMTPPORT; client->auth_mech = SASL_DEFAULT; client->domain = "";}void initMailInfo( SMTP_Mail_Info * mail){ memset(mail, 0 ,sizeof(struct SMTP_Mail_Info)); mail->subject = ""; mail->body = "";}int sendMail(SMTP_Client_Info * smtpinfo, SMTP_Mail_Info * mail){ //if succeced ,return 0,else return -1 if(smtpinfo ==0 || mail ==0) { dbgmsg("SMTP_Client_Info and SMTP_Mail_Infor can not be NULL !"); return -1; } if(ssmtp_connect(smtpinfo) < 0) return -1; if( ssmtp_ready(smtpinfo ,SERVICE_READY) < 0) return -1; // say helo to server if( ssmtp_ehlo(smtpinfo, REPLY_OKAY) < 0 ) { // EHLO failed, try HELO instead if( ssmtp_helo(smtpinfo, REPLY_OKAY) < 0 ) ssmtp_quit(smtpinfo); } else { // authentication if( strlen(smtpinfo->auth_user) >0 && strlen(smtpinfo->auth_pass)>0 ) { if( ssmtp_auth(smtpinfo) < 0 ) { // auth failed, try HELO instead if( ssmtp_helo(smtpinfo, REPLY_OKAY) < 0 ) ssmtp_quit(smtpinfo); } } } // mail from if ( ssmtp_mail(smtpinfo, REPLY_OKAY) < 0) return -1; // mail to if ( ssmtp_rcpt(smtpinfo,mail , "2") < 0) return -1; // data if (ssmtp_data(smtpinfo, "3") < 0) return -1; // send content if( ssmtp_content(smtpinfo, mail ,"2") < 0) return -1; // send quit ssmtp_quit(smtpinfo); close(smtpinfo->sockfd); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -