📄 ssmtp.c
字号:
// 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"); 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, char *status_code){ int i; char buf[MAXDATASIZE]; strcpy(buf, "RCPT TO:<"); strcat(buf, smtpinfo->toaddr); 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, char *status_code){ FILE *infile, *fp; int i; char buf[MAXDATASIZE]; unsigned char raw; char *headers=0; char *ctype=0; long maxsize=0; #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, smtpinfo->toaddr); strcat(buf, "\r\n");#endif if( sendall(smtpinfo->sockfd, buf, strlen(buf)) < 0 ) return -1; // open file and send if( (infile = fopen(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, attachment, mail_body, mail_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); fclose(infile); unlink(mimetmpfile); return -1; } i = strlen(status_code); if( !strncmp(status_code, buf, i) ) { // status code match, return 0 fclose(fp); 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); 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; 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;}///////////////////////////////////////////////////////////////////////// Function main///////////////////////////////////////////////////////////////////////int main(int argc, char *argv[]){ SMTP_Client_Info *smtpinfo; // init smtpinfo structure smtpinfo = NULL; smtpinfo = malloc(sizeof(SMTP_Client_Info)); if(!smtpinfo) ssmtp_failed(MEM_ALLOC_FAIL); // init smtpinfo parameters ssmtp_init(smtpinfo, argc, argv); // connect to server ssmtp_connect(smtpinfo); // get server response ssmtp_ready(smtpinfo, SERVICE_READY); // 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 ssmtp_mail(smtpinfo, REPLY_OKAY); // mail to ssmtp_rcpt(smtpinfo, "2"); // data ssmtp_data(smtpinfo, "3"); // send content ssmtp_content(smtpinfo, "2"); // send quit ssmtp_quit(smtpinfo); close(smtpinfo->sockfd); free(smtpinfo); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -