smtp.cpp
上传用户:adsacym
上传日期:2007-01-07
资源大小:67k
文件大小:7k
源码类别:

Internet/IE编程

开发平台:

Visual C++

  1. /* smtp.c *  by lgd/Paladin.InetSoft   GuangZhou *   */ #include <windows.h> #include <stdio.h> #include <string.h> #include <time.h> #include "tcp.h" #include "smtp.h" char m_base64tab[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz0123456789+/"; #define BASE64_MAXLINE  76 #define EOL  "rn" int Base64BufferSize(int); int EncodeBase64(const char* pszIn, int nInLen, char* pszOut, int nOutSize, int* nOutLen); int get_filename(char *path, char *filename); int smtp_connect(char *host, int port, int timeout) { int sd, ret =0;
  2. if(port <=0) port =110; if((sd =tcp_connect(host, port, timeout, 0)) <0) return -1; if(smtp_getreply(sd) !=220) { tcp_close(sd); return -10; } if(smtp_cmd(sd, "HELO Worldrn", 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"};
  3. int smtp_sendfile(int sd, char *AddrFrom, char *AddrTo, char *filename)
  4. {
  5. FILE *fp;
  6. char buf[1024];
  7. int len;
  8. int ret =0;
  9. if((fp =fopen(filename, "r")) ==NULL) return -1;
  10. while(!feof(fp) && (len =fread(buf, 1, sizeof(buf)-1, fp)) >0)
  11. {
  12. buf[len] =0;
  13. if(smtp_sendmessage(sd, AddrFrom, &AddrTo, 1, NULL, "pass", buf,
  14. NULL, 0, 60) <0)
  15. {
  16. ret =-1;
  17. break;
  18. }
  19. }
  20. fclose(fp);
  21. return ret;
  22. }
  23. 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>rn", AddrFrom); if((ret =smtp_cmd(sd, buf, 250)) <0) return -ret; for(i =0; i<AddrToCount; i++) { sprintf(buf, "RCPT TO:<%s>rn", AddrTo[i]); if((ret =smtp_cmd(sd, buf, 250)) <0) return -ret; } if((ret =smtp_cmd(sd, "DATArn", 354)) <0) return -ret; /* fill header */ szTo[0] =0; for(i =0; i<AddrToCount; i++) { if(i) strcat(szTo, ","); strcat(szTo, AddrTo[i]); } time(&t); ptm =localtime(&t); sprintf(szDate, "%s, %02d %s %d %02d:%02d:%02d %d", Weeks[ptm->tm_wday], ptm->tm_mday, Months[ptm->tm_mon], ptm->tm_year+1900, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, _timezone); sprintf(buf, "From: %srnTo: %srnSubject:%srnDate: %srnX-Mailer: Paladin.InetSoftrn", AddrFrom, szTo, subject, szDate); if(AddrReply) { strcat(buf, "Reply-To: "); strcat(buf, AddrReply); strcat(buf, "rn"); } if(AttachCount) { strcat(buf, "MIME-Version: 1.0rnContent-type: multipart/mixed; boundary="#BOUNDARY#"rn"); } strcat(buf, "rn"); /* end of header */ if(tcp_send(sd, buf, strlen(buf), 20) <0) return -2; if(AttachCount) { strcpy(buf, "rn--#BOUNDARY#rnContent-Type: text/plain; charset=us-asciirn" "Content-Transfer-Encoding: quoted-printablernrn"); 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<AttachCount; i++) { get_filename(AttachFiles[i], filename); sprintf(buf, "rnrn--#BOUNDARY#rn" "Content-Type: application/octet-stream; name=%srn" "Content-Transfer-Encoding: base64rn" "Content-Disposition: attachment; filename=%srnrn", filename, filename); if (tcp_send(sd, buf, strlen(buf), 10) !=(int)strlen(buf)) return -2; if((fp =fopen(AttachFiles[i], "rb")) ==NULL) return -20; flen =fseek(fp, 0, SEEK_END); if(flen ==0) { fclose(fp); return -21; } if((fbuf =(char *)malloc(flen+1)) ==NULL) { fclose(fp); return -30; } fseek(fp, 0, SEEK_SET); if(fread(fbuf, flen+1, 1, fp) !=1) { fclose(fp); free(pbuf); return -22; } outsize =Base64BufferSize(flen); EncodeBase64(fbuf, flen, pbuf, outsize, &bufsize); fclose(fp); if(tcp_send(sd, pbuf, bufsize, 200) !=bufsize) return -2; strcpy(buf, "rn--#BOUNDARY#--"); if(tcp_send(sd, buf, strlen(buf), 10) !=(int)strlen(buf)) return -2; }/* end of sending attachment */ /* send end of msg */ if((ret =smtp_cmd(sd, "rn.rn", 250)) <0) return ret; return 0; } int smtp_disconnect(int sd) { int ret; if((ret =smtp_cmd(sd, "QUITrn", 221)) <0) { tcp_close(sd); return -ret; } return 0; } int smtp_cmd(int sd, char *cmd, int success_code) { if(tcp_send(sd, cmd, strlen(cmd), 10) !=(int)strlen(cmd)) return -2; if(smtp_getreply(sd) !=success_code) return -10; return 0; } #define MAX_WAIT_TIMES 30 extern char g_reply[1000]; int smtp_getreply(int sd) {
  24.   int i, code =0;
  25. again:
  26.   i =0;
  27.   //memset(g_reply, 0, sizeof(g_reply));
  28.   while(1)
  29.   {
  30.     if(tcp_recv(sd, &g_reply[i], 1, MAX_WAIT_TIMES) <=0)
  31.       break;
  32.     if(g_reply[i] =='r') g_reply[i] =' ';
  33.     if(g_reply[i] =='n')
  34.     {
  35.       g_reply[i] =' ';
  36.       if(sscanf(g_reply, "%d", &code) !=1)
  37.       {
  38.         return -1;
  39.       }
  40.       else break;
  41.     }
  42.     i++;
  43.   }
  44.   if(g_reply[3] =='-')
  45.   {
  46.   i =0;
  47.   goto again;
  48.   }
  49.   g_reply[i] =0;
  50.   //g_code =code;
  51.   return code;
  52. } 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<nInLen/3; ++i)  { //Get the next 2 characters int c1 = pszIn[nInPos++] & 0xFF; int c2 = pszIn[nInPos++] & 0xFF; int c3 = pszIn[nInPos++] & 0xFF; //Encode into the 4 6 bit characters pszOut[nOutPos++] = m_base64tab[(c1 & 0xFC) >> 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 <len) { if(path[len -i-1] =='\') break; i++; } strcpy(&path[i], filename); return 0; }