static void PrintPiecesThread(void* pv) { CFrameWndEx* pFrame = (CFrameWndEx*)pv; CView* pView = pFrame->GetActiveView(); CPrintDialog PD(FALSE, PD_ALLPAGES|PD_USEDEVMODECOPIES|PD_NOPAGENUMS|PD_NOSELECTION, pFrame); if (theApp.DoPrintDialog(&PD) != IDOK) return; if (PD.m_pd.hDC == NULL) return; Project* project = lcGetActiveProject(); ObjArray<lcPiecesUsedEntry> PiecesUsed; project->GetPiecesUsed(PiecesUsed); PiecesUsed.Sort(PiecesUsedSortFunc, NULL); // gather file to print to if print-to-file selected CString strOutput; if (PD.m_pd.Flags & PD_PRINTTOFILE) { CString strDef(MAKEINTRESOURCE(AFX_IDS_PRINTDEFAULTEXT)); CString strPrintDef(MAKEINTRESOURCE(AFX_IDS_PRINTDEFAULT)); CString strFilter(MAKEINTRESOURCE(AFX_IDS_PRINTFILTER)); CString strCaption(MAKEINTRESOURCE(AFX_IDS_PRINTCAPTION)); CFileDialog dlg(FALSE, strDef, strPrintDef,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, strFilter); dlg.m_ofn.lpstrTitle = strCaption; if (dlg.DoModal() != IDOK) return; strOutput = dlg.GetPathName(); } CString DocName; char* Ext = strrchr(project->m_strTitle, '.'); DocName.Format("LeoCAD - %.*s BOM", Ext ? Ext - project->m_strTitle : strlen(project->m_strTitle), project->m_strTitle); DOCINFO docInfo; memset(&docInfo, 0, sizeof(DOCINFO)); docInfo.cbSize = sizeof(DOCINFO); docInfo.lpszDocName = DocName; CString strPortName; int nFormatID; if (strOutput.IsEmpty()) { docInfo.lpszOutput = NULL; strPortName = PD.GetPortName(); nFormatID = AFX_IDS_PRINTONPORT; } else { docInfo.lpszOutput = strOutput; AfxGetFileTitle(strOutput, strPortName.GetBuffer(_MAX_PATH), _MAX_PATH); nFormatID = AFX_IDS_PRINTTOFILE; } SetAbortProc(PD.m_pd.hDC, _AfxAbortProc); pFrame->EnableWindow(FALSE); CPrintingDialog dlgPrintStatus(NULL); CString strTemp; dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_DOCNAME, DocName); dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PRINTERNAME, PD.GetDeviceName()); AfxFormatString1(strTemp, nFormatID, strPortName); dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PORTNAME, strTemp); dlgPrintStatus.ShowWindow(SW_SHOW); dlgPrintStatus.UpdateWindow(); if (StartDoc(PD.m_pd.hDC, &docInfo) == SP_ERROR) { pFrame->EnableWindow(TRUE); dlgPrintStatus.DestroyWindow(); AfxMessageBox(AFX_IDP_FAILED_TO_START_PRINT); return; } int ResX = GetDeviceCaps(PD.m_pd.hDC, LOGPIXELSX); int ResY = GetDeviceCaps(PD.m_pd.hDC, LOGPIXELSY); CRect RectDraw(0, 0, GetDeviceCaps(PD.m_pd.hDC, HORZRES), GetDeviceCaps(PD.m_pd.hDC, VERTRES)); DPtoLP(PD.m_pd.hDC, (LPPOINT)(RECT*)&RectDraw, 2); RectDraw.DeflateRect((int)(ResX*(float)theApp.GetProfileInt("Default","Margin Left", 50)/100.0f), (int)(ResY*(float)theApp.GetProfileInt("Default","Margin Top", 50)/100.0f), (int)(ResX*(float)theApp.GetProfileInt("Default","Margin Right", 50)/100.0f), (int)(ResY*(float)theApp.GetProfileInt("Default","Margin Bottom", 50)/100.0f)); CRect HeaderRect = RectDraw; HeaderRect.top -= (int)(ResY*theApp.GetProfileInt("Default", "Margin Top", 50) / 200.0f); HeaderRect.bottom += (int)(ResY*theApp.GetProfileInt("Default", "Margin Bottom", 50) / 200.0f); int RowsPerPage = AfxGetApp()->GetProfileInt("Default", "Catalog Rows", 10); int ColsPerPage = AfxGetApp()->GetProfileInt("Default", "Catalog Columns", 3); int PicHeight = RectDraw.Height() / RowsPerPage; int PicWidth = RectDraw.Width() / ColsPerPage; int TotalRows = (PiecesUsed.GetSize() + ColsPerPage - 1) / ColsPerPage; int TotalPages = (TotalRows + RowsPerPage - 1) / RowsPerPage; int RowHeight = RectDraw.Height() / RowsPerPage; int ColWidth = RectDraw.Width() / ColsPerPage; PD.m_pd.nMinPage = 1; PD.m_pd.nMaxPage = TotalPages + 1; UINT EndPage = PD.m_pd.nToPage; UINT StartPage = PD.m_pd.nFromPage; if (PD.PrintAll()) { EndPage = PD.m_pd.nMaxPage; StartPage = PD.m_pd.nMinPage; } lcClamp(EndPage, PD.m_pd.nMinPage, PD.m_pd.nMaxPage); lcClamp(StartPage, PD.m_pd.nMinPage, PD.m_pd.nMaxPage); int StepPage = (EndPage >= StartPage) ? 1 : -1; VERIFY(strTemp.LoadString(AFX_IDS_PRINTPAGENUM)); // begin page printing loop BOOL bError = FALSE; // Creating Compatible Memory Device Context CDC *pMemDC = new CDC; if (!pMemDC->CreateCompatibleDC(pView->GetDC())) return; BITMAPINFO bi; ZeroMemory(&bi, sizeof(BITMAPINFO)); bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bi.bmiHeader.biWidth = PicWidth; bi.bmiHeader.biHeight = PicHeight; bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = 24; bi.bmiHeader.biCompression = BI_RGB; bi.bmiHeader.biSizeImage = PicWidth * PicHeight * 3; bi.bmiHeader.biXPelsPerMeter = 2925; bi.bmiHeader.biYPelsPerMeter = 2925; bi.bmiHeader.biClrUsed = 0; bi.bmiHeader.biClrImportant = 0; LPBITMAPINFOHEADER lpbi[1]; HBITMAP hBm, hBmOld; hBm = CreateDIBSection(pView->GetDC()->GetSafeHdc(), &bi, DIB_RGB_COLORS, (void **)&lpbi, NULL, (DWORD)0); if (!hBm) return; hBmOld = (HBITMAP)::SelectObject(pMemDC->GetSafeHdc(), hBm); PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_SUPPORT_GDI, PFD_TYPE_RGBA, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 }; int pixelformat = ChoosePixelFormat(pMemDC->m_hDC, &pfd); DescribePixelFormat(pMemDC->m_hDC, pixelformat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); SetPixelFormat(pMemDC->m_hDC, pixelformat, &pfd); HGLRC hmemrc = wglCreateContext(pMemDC->GetSafeHdc()); wglMakeCurrent(pMemDC->GetSafeHdc(), hmemrc); GL_DisableVertexBufferObject(); float Aspect = (float)PicWidth/(float)PicHeight; glViewport(0, 0, PicWidth, PicHeight); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(0.5f, 0.1f); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glClearColor(1, 1, 1, 1); LOGFONT lf; memset(&lf, 0, sizeof(LOGFONT)); lf.lfHeight = -MulDiv(12, ResY, 72); lf.lfWeight = FW_REGULAR; lf.lfCharSet = DEFAULT_CHARSET; lf.lfQuality = PROOF_QUALITY; strcpy (lf.lfFaceName , "Arial"); HFONT HeaderFont = CreateFontIndirect(&lf); HFONT OldFont = (HFONT)SelectObject(PD.m_pd.hDC, HeaderFont); SetBkMode(PD.m_pd.hDC, TRANSPARENT); SetTextColor(PD.m_pd.hDC, 0x000000); SetTextAlign(PD.m_pd.hDC, TA_CENTER|TA_NOUPDATECP); DWORD PrintOptions = AfxGetApp()->GetProfileInt("Settings", "Print", PRINT_NUMBERS | PRINT_BORDER/*|PRINT_NAMES*/); bool DrawNames = 1;//(PrintOptions & PRINT_NAMES) != 0; bool Horizontal = 1;//(PrintOptions & PRINT_HORIZONTAL) != 0; pMemDC->SetTextColor(0x000000); pMemDC->SetBkMode(TRANSPARENT); // lf.lfHeight = -MulDiv(40, GetDeviceCaps(pMemDC->m_hDC, LOGPIXELSY), 72); // lf.lfWeight = FW_BOLD; HFONT CatalogFont = CreateFontIndirect(&lf); lf.lfHeight = -MulDiv(80, GetDeviceCaps(pMemDC->m_hDC, LOGPIXELSY), 72); HFONT CountFont = CreateFontIndirect(&lf); HFONT OldMemFont = (HFONT)SelectObject(pMemDC->m_hDC, CatalogFont); HPEN hpOld = (HPEN)SelectObject(pMemDC->m_hDC, GetStockObject(BLACK_PEN)); for (UINT CurPage = StartPage; CurPage != EndPage; CurPage += StepPage) { TCHAR szBuf[80]; wsprintf(szBuf, strTemp, CurPage); dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PAGENUM, szBuf); if (::StartPage(PD.m_pd.hDC) < 0) { bError = TRUE; break; } // Draw header and footer. SelectObject(PD.m_pd.hDC, HeaderFont); CString Header; UINT Align; FormatHeader(Header, Align, AfxGetApp()->GetProfileString("Default", "Catalog Header", ""), project->m_strTitle, project->m_strAuthor, project->m_strDescription, CurPage, TotalPages); Align |= DT_TOP|DT_SINGLELINE; DrawText(PD.m_pd.hDC, (LPCTSTR)Header, Header.GetLength(), HeaderRect, Align); FormatHeader(Header, Align, AfxGetApp()->GetProfileString("Default", "Catalog Footer", "Page &P"), project->m_strTitle, project->m_strAuthor, project->m_strDescription, CurPage, TotalPages); Align |= DT_BOTTOM|DT_SINGLELINE; DrawText(PD.m_pd.hDC, (LPCTSTR)Header, Header.GetLength(), HeaderRect, Align); int StartPiece = (CurPage - 1) * RowsPerPage * ColsPerPage; int EndPiece = lcMin(StartPiece + RowsPerPage * ColsPerPage, PiecesUsed.GetSize()); for (int CurPiece = StartPiece; CurPiece < EndPiece; CurPiece++) { FillRect(pMemDC->m_hDC, CRect(0, PicHeight, PicWidth, 0), (HBRUSH)GetStockObject(WHITE_BRUSH)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); PieceInfo* pInfo = PiecesUsed[CurPiece].Info; pInfo->ZoomExtents(30.0f, Aspect); pInfo->RenderPiece(PiecesUsed[CurPiece].ColorIndex); glFinish(); // Draw description text at the bottom. CRect TextRect(0, 0, PicWidth, PicHeight); if (DrawNames) { SelectObject(pMemDC->m_hDC, CatalogFont); pMemDC->DrawText(pInfo->m_strDescription, strlen(pInfo->m_strDescription), TextRect, DT_CALCRECT | DT_WORDBREAK); TextRect.OffsetRect(0, PicHeight - TextRect.Height() - 5); pMemDC->DrawText(pInfo->m_strDescription, strlen(pInfo->m_strDescription), TextRect, DT_WORDBREAK); } // Draw count. SelectObject(pMemDC->m_hDC, CountFont); TextRect = CRect(0, 0, PicWidth, TextRect.top); TextRect.DeflateRect(5, 5); char CountStr[16]; sprintf(CountStr, "%dx", PiecesUsed[CurPiece].Count); pMemDC->DrawText(CountStr, strlen(CountStr), TextRect, DT_BOTTOM | DT_LEFT | DT_SINGLELINE); LPBITMAPINFOHEADER lpbi[1]; lpbi[0] = (LPBITMAPINFOHEADER)GlobalLock(MakeDib(hBm, 24)); BITMAPINFO bi; ZeroMemory(&bi, sizeof(BITMAPINFO)); memcpy (&bi.bmiHeader, lpbi[0], sizeof(BITMAPINFOHEADER)); SetStretchBltMode(PD.m_pd.hDC, COLORONCOLOR); int CurRow, CurCol; if (Horizontal) { CurRow = (CurPiece - StartPiece) / ColsPerPage; CurCol = (CurPiece - StartPiece) % ColsPerPage; } else { CurRow = (CurPiece - StartPiece) % RowsPerPage; CurCol = (CurPiece - StartPiece) / RowsPerPage; } int Left = RectDraw.left + ColWidth * CurCol + (ColWidth - PicWidth) / 2; int Top = RectDraw.top + RowHeight * CurRow + (RowHeight - PicHeight) / 2; StretchDIBits(PD.m_pd.hDC, Left, Top, PicWidth, PicHeight, 0, 0, PicWidth, PicHeight, (LPBYTE)lpbi[0] + lpbi[0]->biSize + lpbi[0]->biClrUsed * sizeof(RGBQUAD), &bi, DIB_RGB_COLORS, SRCCOPY); if (lpbi[0]) GlobalFreePtr(lpbi[0]); } if (::EndPage(PD.m_pd.hDC) < 0 || !_AfxAbortProc(PD.m_pd.hDC, 0)) { bError = TRUE; break; } } SelectObject(pMemDC->m_hDC, hpOld); SelectObject(PD.m_pd.hDC, OldFont); DeleteObject(HeaderFont); SelectObject(pMemDC->m_hDC, OldMemFont); DeleteObject(CatalogFont); DeleteObject(CountFont); GL_EnableVertexBufferObject(); wglMakeCurrent(NULL, NULL); wglDeleteContext(hmemrc); SelectObject(pMemDC->GetSafeHdc(), hBmOld); DeleteObject(hBm); delete pMemDC; if (!bError) EndDoc(PD.m_pd.hDC); else AbortDoc(PD.m_pd.hDC); pFrame->EnableWindow(); dlgPrintStatus.DestroyWindow(); if (PD.m_pd.hDC != NULL) { ::DeleteDC(PD.m_pd.hDC); PD.m_pd.hDC = NULL; } }
//////////////////////////////////////////////////////////////////////////////// // NAME: Send // DESCRIPTION: Sending the mail. . // ARGUMENTS: none // USES GLOBAL: m_sSMTPSrvName, m_iSMTPSrvPort, SendBuf, RecvBuf, m_sLogin, // m_sPassword, m_sMailFrom, Recipients, CCRecipients, // BCCRecipients, m_sMsgBody, Attachments, // MODIFIES GL: SendBuf // RETURNS: void // AUTHOR: Jakub Piwowarczyk // AUTHOR/DATE: JP 2010-01-28 // JP 2010-07-08 //////////////////////////////////////////////////////////////////////////////// void CSmtp::Send() { unsigned int i,rcpt_count,res,FileId; char *FileBuf = NULL, *FileName = NULL; FILE* hFile = NULL; unsigned long int FileSize,TotalSize,MsgPart; bool bAccepted; // ***** CONNECTING TO SMTP SERVER ***** // connecting to remote host: if( (hSocket = ConnectRemoteServer(m_sSMTPSrvName.c_str(), m_iSMTPSrvPort)) == INVALID_SOCKET ) throw ECSmtp(ECSmtp::WSA_INVALID_SOCKET, NULL); bAccepted = false; do { ReceiveData(); switch(SmtpXYZdigits()) { case 220: bAccepted = true; break; default: throw ECSmtp(ECSmtp::SERVER_NOT_READY, RecvBuf); } }while(!bAccepted); // EHLO <SP> <domain> <CRLF> sprintf(SendBuf,"EHLO %s\r\n",GetLocalHostName()!=NULL ? m_sLocalHostName.c_str() : "domain"); SendData(); bAccepted = false; do { ReceiveData(); switch(SmtpXYZdigits()) { case 250: bAccepted = true; break; default: throw ECSmtp(ECSmtp::COMMAND_EHLO, RecvBuf); } }while(!bAccepted); if(!m_sLogin.empty()) { // AUTH <SP> LOGIN <CRLF> strcpy(SendBuf,"AUTH LOGIN\r\n"); SendData(); bAccepted = false; do { ReceiveData(); switch(SmtpXYZdigits()) { case 250: break; case 334: bAccepted = true; break; default: throw ECSmtp(ECSmtp::COMMAND_AUTH_LOGIN, RecvBuf); } }while(!bAccepted); // send login: if(!m_sLogin.size()) throw ECSmtp(ECSmtp::UNDEF_LOGIN, RecvBuf); std::string encoded_login = base64_encode(reinterpret_cast<const unsigned char*>(m_sLogin.c_str()),m_sLogin.size()); sprintf(SendBuf,"%s\r\n",encoded_login.c_str()); SendData(); bAccepted = false; do { ReceiveData(); switch(SmtpXYZdigits()) { case 334: bAccepted = true; break; default: throw ECSmtp(ECSmtp::UNDEF_XYZ_RESPONSE, RecvBuf); } }while(!bAccepted); // send password: if(!m_sPassword.size()) throw ECSmtp(ECSmtp::UNDEF_PASSWORD, RecvBuf); std::string encoded_password = base64_encode(reinterpret_cast<const unsigned char*>(m_sPassword.c_str()),m_sPassword.size()); sprintf(SendBuf,"%s\r\n",encoded_password.c_str()); SendData(); bAccepted = false; do { ReceiveData(); switch(SmtpXYZdigits()) { case 235: bAccepted = true; break; case 334: break; case 535: throw ECSmtp(ECSmtp::BAD_LOGIN_PASS, RecvBuf); default: throw ECSmtp(ECSmtp::UNDEF_XYZ_RESPONSE, RecvBuf); } }while(!bAccepted); } // ***** SENDING E-MAIL ***** // MAIL <SP> FROM:<reverse-path> <CRLF> if(!m_sMailFrom.size()) throw ECSmtp(ECSmtp::UNDEF_MAIL_FROM, RecvBuf); sprintf(SendBuf,"MAIL FROM:<%s>\r\n",m_sMailFrom.c_str()); SendData(); bAccepted = false; do { ReceiveData(); switch(SmtpXYZdigits()) { case 250: bAccepted = true; break; default: throw ECSmtp(ECSmtp::COMMAND_MAIL_FROM, RecvBuf); } }while(!bAccepted); // RCPT <SP> TO:<forward-path> <CRLF> if(!(rcpt_count = Recipients.size())) throw ECSmtp(ECSmtp::UNDEF_RECIPIENTS, NULL); for(i=0;i<Recipients.size();i++) { sprintf(SendBuf,"RCPT TO:<%s>\r\n",(Recipients.at(i).Mail).c_str()); SendData(); bAccepted = false; do { ReceiveData(); switch(SmtpXYZdigits()) { case 250: bAccepted = true; break; default: rcpt_count--; } }while(!bAccepted); } if(rcpt_count <= 0) throw ECSmtp(ECSmtp::COMMAND_RCPT_TO, RecvBuf); for(i=0;i<CCRecipients.size();i++) { sprintf(SendBuf,"RCPT TO:<%s>\r\n",(CCRecipients.at(i).Mail).c_str()); SendData(); bAccepted = false; do { ReceiveData(); switch(SmtpXYZdigits()) { case 250: bAccepted = true; break; default: ; // not necessary to throw } }while(!bAccepted); } for(i=0;i<BCCRecipients.size();i++) { sprintf(SendBuf,"RCPT TO:<%s>\r\n",(BCCRecipients.at(i).Mail).c_str()); SendData(); bAccepted = false; do { ReceiveData(); switch(SmtpXYZdigits()) { case 250: bAccepted = true; break; default: ; // not necessary to throw } }while(!bAccepted); } // DATA <CRLF> strcpy(SendBuf,"DATA\r\n"); SendData(); bAccepted = false; do { ReceiveData(); switch(SmtpXYZdigits()) { case 354: bAccepted = true; break; case 250: break; default: throw ECSmtp(ECSmtp::COMMAND_DATA, RecvBuf); } }while(!bAccepted); // send header(s) FormatHeader(SendBuf); SendData(); // send text message if(GetMsgLines()) { for(i=0;i<GetMsgLines();i++) { sprintf(SendBuf,"%s\r\n",GetMsgLineText(i)); SendData(); } } else { sprintf(SendBuf,"%s\r\n"," "); SendData(); } // next goes attachments (if they are) if((FileBuf = new char[55]) == NULL) throw ECSmtp(ECSmtp::LACK_OF_MEMORY, RecvBuf); if((FileName = new char[255]) == NULL) throw ECSmtp(ECSmtp::LACK_OF_MEMORY, RecvBuf); TotalSize = 0; for(FileId=0;FileId<Attachments.size();FileId++) { strcpy(FileName,Attachments[FileId].c_str()); sprintf(SendBuf,"--%s\r\n",BOUNDARY_TEXT); strcat(SendBuf,"Content-Type: application/x-msdownload; name=\""); strcat(SendBuf,&FileName[Attachments[FileId].find_last_of("\\") + 1]); strcat(SendBuf,"\"\r\n"); strcat(SendBuf,"Content-Transfer-Encoding: base64\r\n"); strcat(SendBuf,"Content-Disposition: attachment; filename=\""); strcat(SendBuf,&FileName[Attachments[FileId].find_last_of("\\") + 1]); strcat(SendBuf,"\"\r\n"); strcat(SendBuf,"\r\n"); SendData(); // opening the file: hFile = fopen(FileName,"rb"); if(hFile == NULL) throw ECSmtp(ECSmtp::FILE_NOT_EXIST, RecvBuf); // checking file size: FileSize = 0; while(!feof(hFile)) FileSize += fread(FileBuf,sizeof(char),54,hFile); TotalSize += FileSize; // sending the file: if(TotalSize/1024 > MSG_SIZE_IN_MB*1024) throw ECSmtp(ECSmtp::MSG_TOO_BIG, RecvBuf); else { fseek (hFile,0,SEEK_SET); MsgPart = 0; for(i=0;i<FileSize/54+1;i++) { res = fread(FileBuf,sizeof(char),54,hFile); MsgPart ? strcat(SendBuf,base64_encode(reinterpret_cast<const unsigned char*>(FileBuf),res).c_str()) : strcpy(SendBuf,base64_encode(reinterpret_cast<const unsigned char*>(FileBuf),res).c_str()); strcat(SendBuf,"\r\n"); MsgPart += res + 2; if(MsgPart >= BUFFER_SIZE/2) { // sending part of the message MsgPart = 0; SendData(); // FileBuf, FileName, fclose(hFile); } } if(MsgPart) { SendData(); // FileBuf, FileName, fclose(hFile); } } fclose(hFile); } delete[] FileBuf; delete[] FileName; // sending last message block (if there is one or more attachments) if(Attachments.size()) { sprintf(SendBuf,"\r\n--%s--\r\n",BOUNDARY_TEXT); SendData(); } // <CRLF> . <CRLF> strcpy(SendBuf,"\r\n.\r\n"); SendData(); bAccepted = false; do { ReceiveData(); switch(SmtpXYZdigits()) { case 250: bAccepted = true; break; default: throw ECSmtp(ECSmtp::MSG_BODY_ERROR, RecvBuf); } }while(!bAccepted); // ***** CLOSING CONNECTION ***** // QUIT <CRLF> strcpy(SendBuf,"QUIT\r\n"); SendData(); bAccepted = false; do { ReceiveData(); switch(SmtpXYZdigits()) { case 221: bAccepted = true; break; default: throw ECSmtp(ECSmtp::COMMAND_QUIT, RecvBuf); } }while(!bAccepted); #ifdef LINUX close(hSocket); #else closesocket(hSocket); #endif hSocket = 0; }
bool CSmtp::Send() { unsigned int i,rcpt_count,res,FileId; char *FileBuf = NULL, *FileName = NULL; FILE* hFile = NULL; unsigned long int FileSize,TotalSize,MsgPart; // ***** CONNECTING TO SMTP SERVER ***** assert(m_pcSMTPSrvName); // connecting to remote host: if( (hSocket = ConnectRemoteServer(m_pcSMTPSrvName, m_iSMTPSrvPort)) == INVALID_SOCKET ) { m_oError = CSMTP_WSA_INVALID_SOCKET; return false; } Sleep(DELAY_IN_MS); if(!ReceiveData()) return false; switch(SmtpXYZdigits()) { case 220: break; default: m_oError = CSMTP_SERVER_NOT_READY; return false; } // EHLO <SP> <domain> <CRLF> sprintf(SendBuf,"EHLO %s\r\n",GetLocalHostName()!=NULL ? m_pcLocalHostName : "domain"); if(!SendData()) return false; Sleep(DELAY_IN_MS); if(!ReceiveData()) return false; switch(SmtpXYZdigits()) { case 250: break; default: m_oError = CSMTP_COMMAND_EHLO; return false; } // AUTH <SP> LOGIN <CRLF> strcpy(SendBuf,"AUTH LOGIN\r\n"); if(!SendData()) return false; Sleep(DELAY_IN_MS); if(!ReceiveData()) return false; switch(SmtpXYZdigits()) { case 334: break; default: m_oError = CSMTP_COMMAND_AUTH_LOGIN; return false; } // send login: if(!m_pcLogin) { m_oError = CSMTP_UNDEF_LOGIN; return false; } std::string encoded_login = base64_encode(reinterpret_cast<const unsigned char*>(m_pcLogin),strlen(m_pcLogin)); sprintf(SendBuf,"%s\r\n",encoded_login.c_str()); if(!SendData()) return false; Sleep(DELAY_IN_MS); if(!ReceiveData()) return false; switch(SmtpXYZdigits()) { case 334: break; default: m_oError = CSMTP_UNDEF_XYZ_RESPOMSE; return false; } // send password: if(!m_pcPassword) { m_oError = CSMTP_UNDEF_PASSWORD; return false; } std::string encoded_password = base64_encode(reinterpret_cast<const unsigned char*>(m_pcPassword),strlen(m_pcPassword)); sprintf(SendBuf,"%s\r\n",encoded_password.c_str()); if(!SendData()) return false; Sleep(DELAY_IN_MS); if(!ReceiveData()) return false; switch(SmtpXYZdigits()) { case 235: break; case 535: m_oError = CSMTP_BAD_LOGIN_PASS; return false; default: m_oError = CSMTP_UNDEF_XYZ_RESPOMSE; return false; } // ***** SENDING E-MAIL ***** // MAIL <SP> FROM:<reverse-path> <CRLF> if(m_pcMailFrom == NULL) { m_oError = CSMTP_UNDEF_MAILFROM; return false; } sprintf(SendBuf,"MAIL FROM:<%s>\r\n",m_pcMailFrom); if(!SendData()) return false; Sleep(DELAY_IN_MS); if(!ReceiveData()) return false; switch(SmtpXYZdigits()) { case 250: break; default: m_oError = CSMTP_COMMAND_MAIL_FROM; return false; } // RCPT <SP> TO:<forward-path> <CRLF> rcpt_count = Recipients.size(); for(i=0;i<Recipients.size();i++) { sprintf(SendBuf,"RCPT TO:<%s>\r\n",(Recipients.at(i).Mail).c_str()); if(!SendData()) return false; Sleep(DELAY_IN_MS); if(!ReceiveData()) return false; switch(SmtpXYZdigits()) { case 250: break; default: m_oError = CSMTP_COMMAND_RCPT_TO; rcpt_count--; } } if(!rcpt_count) return false; for(i=0;i<CCRecipients.size();i++) { sprintf(SendBuf,"RCPT TO:<%s>\r\n",(CCRecipients.at(i).Mail).c_str()); if(!SendData()) return false; Sleep(DELAY_IN_MS); if(!ReceiveData()) return false; } for(i=0;i<BCCRecipients.size();i++) { sprintf(SendBuf,"RCPT TO:<%s>\r\n",(BCCRecipients.at(i).Mail).c_str()); if(!SendData()) return false; Sleep(DELAY_IN_MS); if(!ReceiveData()) return false; } // DATA <CRLF> strcpy(SendBuf,"DATA\r\n"); if(!SendData()) return false; Sleep(DELAY_IN_MS); if(!ReceiveData()) return false; switch(SmtpXYZdigits()) { case 354: break; default: m_oError = CSMTP_COMMAND_DATA; return false; } // send header(s) if(!FormatHeader(SendBuf)) { m_oError = CSMTP_UNDEF_MSG_HEADER; return false; } if(!SendData()) return false; // send text message sprintf(SendBuf,"%s\r\n",m_pcMsgBody); // NOTICE: each line ends with <CRLF> if(!SendData()) return false; // next goes attachments (if they are) if((FileBuf = new char[55]) == NULL) { m_oError = CSMTP_LACK_OF_MEMORY; return false; } if((FileName = new char[255]) == NULL) { m_oError = CSMTP_LACK_OF_MEMORY; return false; } TotalSize = 0; for(FileId=0;FileId<Attachments.size();FileId++) { strcpy(FileName,Attachments[FileId].c_str()); sprintf(SendBuf,"--%s\r\n",BOUNDARY_TEXT); strcat(SendBuf,"Content-Type: application/x-msdownload; name=\""); strcat(SendBuf,&FileName[Attachments[FileId].find_last_of("\\") + 1]); strcat(SendBuf,"\"\r\n"); strcat(SendBuf,"Content-Transfer-Encoding: base64\r\n"); strcat(SendBuf,"Content-Disposition: attachment; filename=\""); strcat(SendBuf,&FileName[Attachments[FileId].find_last_of("\\") + 1]); strcat(SendBuf,"\"\r\n"); strcat(SendBuf,"\r\n"); if(!SendData()) return false; // opening the file: hFile = fopen(FileName,"rb"); if(hFile == NULL) { m_oError = CSMTP_FILE_NOT_EXIST; break; } // checking file size: FileSize = 0; while(!feof(hFile)) FileSize += fread(FileBuf,sizeof(char),54,hFile); TotalSize += FileSize; // sending the file: if(TotalSize/1024 > MSG_SIZE_IN_MB*1024) m_oError = CSMTP_MSG_TOO_BIG; else { fseek (hFile,0,SEEK_SET); MsgPart = 0; for(i=0;i<FileSize/54+1;i++) { res = fread(FileBuf,sizeof(char),54,hFile); MsgPart ? strcat(SendBuf,base64_encode(reinterpret_cast<const unsigned char*>(FileBuf),res).c_str()) : strcpy(SendBuf,base64_encode(reinterpret_cast<const unsigned char*>(FileBuf),res).c_str()); strcat(SendBuf,"\r\n"); MsgPart += res + 2; if(MsgPart >= BUFFER_SIZE/2) { // sending part of the message MsgPart = 0; if(!SendData()) { delete[] FileBuf; delete[] FileName; fclose(hFile); return false; } } } if(MsgPart) { if(!SendData()) { delete[] FileBuf; delete[] FileName; fclose(hFile); return false; } } } fclose(hFile); } delete[] FileBuf; delete[] FileName; // sending last message block (if there is one or more attachments) if(Attachments.size()) { sprintf(SendBuf,"\r\n--%s--\r\n",BOUNDARY_TEXT); if(!SendData()) return false; } // <CRLF> . <CRLF> strcpy(SendBuf,"\r\n.\r\n"); if(!SendData()) return false; Sleep(DELAY_IN_MS); if(!ReceiveData()) return false; switch(SmtpXYZdigits()) { case 250: break; default: m_oError = CSMTP_MSG_BODY_ERROR; return false; } // ***** CLOSING CONNECTION ***** // QUIT <CRLF> strcpy(SendBuf,"QUIT\r\n"); if(!SendData()) return false; Sleep(DELAY_IN_MS); if(!ReceiveData()) return false; switch(SmtpXYZdigits()) { case 221: break; default: m_oError = CSMTP_COMMAND_QUIT; hSocket = NULL; return false; } closesocket(hSocket); hSocket = NULL; return true; }