www.pudn.com > FindMail.zip > smtp.cpp
/* smtp.c * by lgd/Paladin.InetSoft GuangZhou * */ #include "stdafx.h" #include#include #include #include #include "tcp.h" #include "smtp.h" char m_base64tab[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz0123456789+/"; #define BASE64_MAXLINE 76 #define EOL "\r\n" int Base64BufferSize(int); int EncodeBase64(const char* pszIn, int nInLen, char* pszOut, int nOutSize, int* nOutLen); int get_filename(char *path, char *filename); #define REPLY_SIZE 4096 int smtp_connect(char *host, int port, int timeout) { int sd, ret =0; char reply[REPLY_SIZE+1]; if(port <=0) port =25; if((sd =tcp_connect(host, port, timeout, false)) <0) return -1; if(smtp_getreply(sd, reply) !=220) { tcp_close(sd); return -10; } if((ret =smtp_cmd(sd, "HELO iampaladin\r\n", 250)) <0) { tcp_close(sd); return ret; } return sd; } char *Weeks[] ={"Mon", "002", "003", "004", "005", "006", "Sun"}; char *Months[] ={"m01", "m02", "m03", "m04", "m05", "m06", "m07", "m08", "m09", "m10", "m11", "m12"}; int smtp_sendfile(int sd, char *AddrFrom, char *AddrTo, char *filename) { FILE *fp; char buf[1024]; int len; int ret =0; if((fp =fopen(filename, "r")) ==NULL) return -1; while(!feof(fp) && (len =fread(buf, 1, sizeof(buf)-1, fp)) >0) { buf[len] =0; if(smtp_sendmessage(sd, AddrFrom, &AddrTo, 1, NULL, "pass", buf, NULL, 0, 60) <0) { ret =-1; break; } } fclose(fp); return ret; } int smtp_sendmsg(int sd, char *from, char *to, char *subject, char *msg, int timeout) { return smtp_sendmessage(sd, from, &to, 1, NULL, subject, msg, NULL, 0, timeout); } int smtp_test_to(int sd, char *to) { char cmd[100]; int ret; sprintf(cmd, "RCPT TO:<%s>\r\n", to); if((ret =smtp_cmd(sd, cmd, 250)) <0) return ret; return 0; } int smtp_test_from(int sd, char *from) { char cmd[100]; int ret; sprintf(cmd, "MAIL FROM:<%s>\r\n", from); if((ret =smtp_cmd(sd, cmd, 250)) <0) return ret; return 0; } int smtp_sendmessage(int sd, char *AddrFrom, char **AddrTo, int AddrToCount, char *AddrReply, char *subject, char *msg, char **AttachFiles, int AttachCount, int timeout) { int i, ret =0, outsize, bufsize, flen; char buf[5000]; char szTo[2000]; char szDate[50]; char *fbuf, *pbuf =NULL; FILE *fp; time_t t; struct tm *ptm; char filename[128]; sprintf(buf, "MAIL FROM:<%s>\r\n", AddrFrom); if((ret =smtp_cmd(sd, buf, 250)) <0) return ret; for(i =0; i \r\n", AddrTo[i]); if((ret =smtp_cmd(sd, buf, 250)) <0) return ret; } if((ret =smtp_cmd(sd, "DATA\r\n", 354)) <0) return ret; /* fill header */ szTo[0] =0; for(i =0; i tm_wday], ptm->tm_mday, Months[ptm->tm_mon], ptm->tm_year, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, _tzname[0]); sprintf(buf, "From: %s\r\nTo: %s\r\nSubject:%s\r\nDate: %s\r\nX-Mailer: Paladin.InetSoft\r\n", AddrFrom, szTo, subject, szDate); if(AddrReply) { strcat(buf, "Reply-To: "); strcat(buf, AddrReply); strcat(buf, "\r\n"); } if(AttachCount) { strcat(buf, "MIME-Version: 1.0\r\nContent-type: multipart/mixed; boundary=\"#BOUNDARY#\"\r\n"); } strcat(buf, "\r\n"); /* end of header */ if(tcp_send(sd, buf, strlen(buf), 20) <0) return -2; if(AttachCount) { strcpy(buf, "\r\n--#BOUNDARY#\r\nContent-Type: text/plain; charset=us-ascii\r\n" "Content-Transfer-Encoding: quoted-printable\r\n\r\n"); if(tcp_send(sd, buf, strlen(buf), 10) <0) return -2; } if(tcp_send(sd, msg, strlen(msg), 60) <0) return -2; /* sending attachment */ for (i=0; i MAX_WAIT_TIMES) break; len =tcp_recv(sd, reply, REPLY_SIZE-len_recved, 2); if (len ==SOCKET_ERROR) { reply[len_recved] = 0; return 1; } else { if(len) time(&t1); len_recved += len; } reply[len_recved] =0; if(strstr(reply, "\r\n") != NULL) break; } reply[len_recved] =0; if(sscanf(reply, "%d", &code) !=1) return 1; return code; } int Base64BufferSize(int fsize) { int bufsize = (fsize+2)/3*4; // 3:4 conversion ratio bufsize += strlen(EOL)*bufsize/BASE64_MAXLINE + 3; // Space for newlines and NUL return bufsize; } BOOL EncodeBase64(const char* pszIn, int nInLen, char* pszOut, int nOutSize, int* nOutLen) { int nInPos = 0; int nOutPos = 0; int nLineLen = 0; int i, c1, c2; char *cp; // Get three characters at a time from the input buffer and encode them for (i=0; i > 2]; pszOut[nOutPos++] = m_base64tab[((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4)]; pszOut[nOutPos++] = m_base64tab[((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6)]; pszOut[nOutPos++] = m_base64tab[c3 & 0x3F]; nLineLen += 4; //Handle the case where we have gone over the max line boundary if (nLineLen >= BASE64_MAXLINE-3) { cp = EOL; pszOut[nOutPos++] = *cp++; if (*cp) pszOut[nOutPos++] = *cp; nLineLen = 0; } } // Encode the remaining one or two characters in the input buffer switch (nInLen % 3) { case 0: { cp = EOL; pszOut[nOutPos++] = *cp++; if (*cp) pszOut[nOutPos++] = *cp; break; } case 1: { c1 = pszIn[nInPos] & 0xFF; pszOut[nOutPos++] = m_base64tab[(c1 & 0xFC) >> 2]; pszOut[nOutPos++] = m_base64tab[((c1 & 0x03) << 4)]; pszOut[nOutPos++] = '='; pszOut[nOutPos++] = '='; cp = EOL; pszOut[nOutPos++] = *cp++; if (*cp) pszOut[nOutPos++] = *cp; break; } case 2: { c1 = pszIn[nInPos++] & 0xFF; c2 = pszIn[nInPos] & 0xFF; pszOut[nOutPos++] = m_base64tab[(c1 & 0xFC) >> 2]; pszOut[nOutPos++] = m_base64tab[((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4)]; pszOut[nOutPos++] = m_base64tab[((c2 & 0x0F) << 2)]; pszOut[nOutPos++] = '='; cp = EOL; pszOut[nOutPos++] = *cp++; if (*cp) pszOut[nOutPos++] = *cp; break; } default: break; } pszOut[nOutPos] = 0; *nOutLen = nOutPos; return TRUE; } int get_filename(char *path, char *filename) { int i =0; int len =strlen(path); while(i