www.pudn.com > doc2pdf-0_7_1.rar > Doc2pdfEmail.cpp


//=========================================================================== 
// 
// Project: doc2pdf - email robot Microsoft Office(tm) document converter 
// 
// File Doc2pdfEmail.cpp 
// 
// Author: Matthew Peterson  
// 
// Description: The email box and converter (the guts) 
// 
//=========================================================================== 
 
 
#include "stdafx.h" 
#include "Doc2PdfEmail.h" 
#include "base64codec.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
 
CDoc2PdfEmailBox::CDoc2PdfEmailBox() 
{ 
    m_IsInitialized = FALSE; 
} 
 
CWnd* CDoc2PdfEmailBox::GetChildWindow(const CWnd* parent, int index) 
{ 
    // index is the 0 based index 
    CWnd* child; 
 
    child = parent->GetWindow(GW_CHILD); 
 
    while ( index && child ) 
    { 
        index --; 
        child = child->GetWindow(GW_HWNDNEXT);       
    } 
 
    return child; 
} 
 
int CDoc2PdfEmailBox::SendKeys(CWnd* wnd, const CString& string) 
{ 
    int     i; 
    DWORD   key; 
    for ( i=0;iPostMessage(WM_CHAR,key,0x08270001); 
 
            //wnd->PostMessage(WM_KEYDOWN,key,0x000f0001); 
            //wnd->PostMessage(WM_KEYUP,key,0xC00f0001); 
        } 
    } 
 
    return 0; 
} 
 
int CDoc2PdfEmailBox::ConvertDoc2Ps(const CString& infile,  
                                    const CString& outfile) 
{ 
    HINSTANCE wordview; 
    CFile printedFile;   
    CWnd* wordViewWnd; 
    CWnd* wordViewPrintWnd; 
    CWnd* wordViewPrintToFileWnd; 
    CWnd* wordViewPrintToFileWndEdit; 
    CWnd* wordViewPrintToFileWndButton; 
 
    int i; 
 
    wordview = ShellExecute(NULL,"open",infile,NULL,NULL,SW_SHOWNORMAL); 
    if ( (DWORD)wordview < 32 ) 
    { 
        // error  
        return -1; 
    } 
 
    // alt-f p to main windowfor print 
    for ( i=0;  
        i < (DOC2PDF_LOAD_DELAY * 1000)/DOC2PDF_WINDOW_CHECK_DELAY; 
        i++ ) 
    { 
        Sleep(DOC2PDF_WINDOW_CHECK_DELAY); 
        wordViewWnd = CWnd::FindWindow("WrdVwrApp",NULL); 
        if ( wordViewWnd ) 
        { 
            CString text; 
            wordViewWnd->GetWindowText(text); 
            if ( wordViewWnd->GetWindowTextLength() > 24 ) 
            { 
                break; 
            } 
        } 
    } 
    if ( wordViewWnd == NULL ) 
    { 
        goto FAILURE; 
    } 
    wordViewWnd->PostMessage(WM_SYSCHAR,0x00000066,0x20210001); 
    wordViewWnd->PostMessage(WM_SYSCHAR,0x00000070,0x00000000);  
 
 
    // alt-l enter to print window for print to file 
    for ( i=0;  
        i < (DOC2PDF_LOAD_DELAY * 1000)/DOC2PDF_WINDOW_CHECK_DELAY; 
        i++ ) 
    { 
 
        Sleep(DOC2PDF_WINDOW_CHECK_DELAY); 
        wordViewPrintWnd = CWnd::FindWindow("bosa_sdm_Microsoft Word Viewer 8.0",NULL); 
        if ( wordViewPrintWnd ) 
        { 
            break;           
        } 
    } 
    if ( wordViewPrintWnd == NULL ) 
    { 
        goto FAILURE; 
    } 
    wordViewPrintWnd->PostMessage(WM_SYSCHAR,0x0000006c,0x20210001); 
    wordViewPrintWnd->PostMessage(WM_KEYDOWN,0x0000000d,0x000f0001); 
    wordViewPrintWnd->PostMessage(WM_KEYUP,0x00000000d,0xC00f0001); 
 
    // Type the outfile into the print to file dialog 
    for ( i=0;  
        i < (DOC2PDF_LOAD_DELAY * 1000)/DOC2PDF_WINDOW_CHECK_DELAY; 
        i++ ) 
    { 
 
        Sleep(DOC2PDF_WINDOW_CHECK_DELAY); 
        wordViewPrintToFileWnd = CWnd::FindWindow(NULL,"Print to File"); 
        if ( wordViewPrintToFileWnd ) 
        { 
            break;           
        } 
    } 
    if ( wordViewPrintToFileWnd == NULL ) 
    { 
        goto FAILURE; 
    } 
    wordViewPrintToFileWndEdit = GetChildWindow(wordViewPrintToFileWnd,6); 
    if ( wordViewPrintToFileWndEdit == NULL ) 
    { 
        goto FAILURE; 
    } 
 
    // Type in the file name to print to 
    SendKeys(wordViewPrintToFileWndEdit,outfile); 
 
    //  Press enter on the save button 
    wordViewPrintToFileWndButton = GetChildWindow(wordViewPrintToFileWnd,10); 
    if ( wordViewPrintToFileWndButton == NULL ) 
    { 
        goto FAILURE; 
    } 
    wordViewPrintToFileWndButton->PostMessage(WM_KEYDOWN,0x0000000d,0x810c0001); 
 
    // Wait for print file to be unlocked.  
    // Then close the down the word viewer 
    for ( i=0;  
        i < (DOC2PDF_PRINT_DELAY * 1000)/DOC2PDF_WINDOW_CHECK_DELAY; 
        i++ ) 
    { 
        Sleep(DOC2PDF_WINDOW_CHECK_DELAY); 
        if ( printedFile.Open(outfile,CFile::modeWrite) ) 
        { 
            printedFile.Close(); 
            break; 
        } 
    } 
 
    wordViewWnd->PostMessage(WM_CLOSE,0x00000000,0x00000000); 
 
    return 0; 
 
    FAILURE: 
 
    if ( wordViewPrintToFileWnd ) 
    { 
        wordViewPrintToFileWnd->PostMessage(WM_CLOSE,0x00000000,0x00000000); 
    } 
    if ( wordViewPrintWnd ) 
    { 
        wordViewPrintWnd->PostMessage(WM_CLOSE,0x00000000,0x00000000); 
    } 
    if ( wordViewWnd ) 
    { 
        wordViewWnd->PostMessage(WM_CLOSE,0x00000000,0x00000000); 
    } 
 
    return 1; 
} 
 
 
int CDoc2PdfEmailBox::ConvertPs2Pdf(const CString& atfile,  
                                    const CString& infile,  
                                    const CString& outfile) 
{ 
    CFile   at; 
    CString atstr; 
    CString gs_cmdline; 
 
    if ( at.Open(atfile,CFile::modeWrite | CFile::modeCreate) == FALSE ) 
    { 
        return -1; 
    } 
 
    atstr.Format(DOC2PDF_GS_AT, 
                 DOC2PDF_GS_COMPATLEVEL, 
                 (LPCSTR)outfile, 
                 (LPCSTR)infile); 
 
    at.Write((LPCSTR)atstr,atstr.GetLength()); 
 
    at.Close(); 
 
    gs_cmdline.Format("%s\\bin\\gswin32c @%s", 
                      (LPCSTR)m_GhostScriptDir, 
                      (LPCSTR)atfile); 
    if ( system(gs_cmdline) != 0 ) 
    { 
        at.Remove(atfile); 
        return  -1; 
    } 
 
    at.Remove(atfile); 
 
    return 0; 
} 
 
int CDoc2PdfEmailBox::ConvertToBase64(const CString& file) 
{ 
    CString fileBase64 = file + ".base64"; 
 
    if ( MoveFile(file,fileBase64) ) 
    { 
        if ( b64('e',fileBase64,file,B64_DEF_LINE_SIZE) == 0 ) 
        { 
            DeleteFile(fileBase64); 
            return 0; 
        } 
    } 
    return -1; 
} 
 
int CDoc2PdfEmailBox::ConvertFromBase64(const CString& file) 
{ 
    CString fileBase64 = file + ".base64"; 
 
    if ( MoveFile(file,fileBase64) ) 
    { 
        if ( b64('d',fileBase64,file,B64_DEF_LINE_SIZE) == 0 ) 
        { 
            DeleteFile(fileBase64); 
            return 0; 
        } 
    } 
    return -1; 
} 
 
int CDoc2PdfEmailBox::ConvertAddressStringToList(const CString& str, 
                                                 CStringList& list) 
{ 
    int     start; 
    int     end; 
    CString listItem; 
 
    start = 0; 
    end = 0; 
    list.RemoveAll(); 
    if ( str.GetLength() ) 
    { 
        while ( end >= 0 ) 
        { 
            end = str.Find(',',start); 
            if ( end >= 0 ) 
            { 
                listItem = str.Mid(start,end - start); 
            } 
            else 
            { 
                listItem = str.Mid(start,str.GetLength() - start); 
            } 
 
            if ( listItem.ReverseFind(' ') >= 0 ) 
            { 
                listItem = listItem.Right(listItem.GetLength() - listItem.ReverseFind(' ') - 1); 
            } 
            if ( listItem.Find('<') < 0 ) 
            { 
                listItem.Insert(0,'<'); 
                listItem += ">"; 
            } 
 
            list.AddTail(listItem); 
 
            start = end; 
            start ++; 
        } 
    } 
 
    return 0; 
} 
 
int CDoc2PdfEmailBox::ReadEmail(CMySocket& sock,  
                                const char* prefix, 
                                CDoc2PdfEmail* email) 
{ 
    time_t          timeout; 
    CString         linein; 
    EmailParseState state = UNKNOWN; 
    int             bytesread; 
    int             start; 
    int             end; 
    BOOL            firstAttachment; 
    CString         boundary; 
    CString         attachmentName; 
    CFile           attachmentFile; 
 
    /*-----------------*/ 
    /* Read the header */ 
    /*-----------------*/ 
    timeout = DOC2PDF_CONNECT_DELAY; 
    while ( 1 ) 
    { 
        bytesread = sock.ReadLine(linein,&timeout); 
        if ( bytesread <= 2 ) 
        { 
            /* Finished with header */ 
            break; 
        } 
 
        if ( linein.Left(9).CompareNoCase("Subject: ") == 0 ) 
        { 
            email->m_Subject=linein.Right(linein.GetLength() - 9); 
            state = SUBJECT; 
        } 
        else if ( linein.Left(6).CompareNoCase("Date: ") == 0 ) 
        { 
            email->m_Date=linein.Right(linein.GetLength() - 6); 
            state = DATE; 
        } 
        else if ( linein.Left(6).CompareNoCase("From: ") == 0 ) 
        { 
            email->m_From=linein.Right(linein.GetLength() - 6); 
            state = FROM; 
        } 
        else if ( linein.Left(4).CompareNoCase("Cc: ") == 0 ) 
        { 
            email->m_Cc=linein.Right(linein.GetLength() - 4); 
            state = CC; 
        } 
        else if ( linein.Left(4).CompareNoCase("To: ") == 0 ) 
        { 
            email->m_To=linein.Right(linein.GetLength() - 4); 
            state = TO; 
        } 
        else if ( linein.Left(14).CompareNoCase("Content-Type: ") == 0 ) 
        { 
            email->m_ContentType = linein.Right(linein.GetLength() - 14); 
            state = CONTENTTYPE; 
        } 
        else if ( linein.Left(1)[0] == 0x20 || 
                  linein.Left(1)[0] == 0x09 ) 
        { 
            /* part of a previous tag */ 
            linein.TrimLeft(); 
            switch ( state ) 
            { 
                case UNKNOWN: 
                    break; 
                case TO: 
                    email->m_To += linein; 
                    break; 
                case CC: 
                    email->m_Cc += linein; 
                    break; 
                case SUBJECT: 
                    email->m_Subject += linein; 
                    break; 
                case FROM: 
                    email->m_From += linein; 
                    break; 
                case DATE: 
                    email->m_Date += linein; 
                    break; 
                case CONTENTTYPE: 
                    email->m_ContentType += linein; 
                    break; 
                default: 
                    break; 
            } 
        } 
        else 
        { 
            state = UNKNOWN; 
        } 
    } 
 
    /*-------------------------------------*/ 
    /* Determine Content Type and boundary */ 
    /*-------------------------------------*/ 
    if ( email->m_ContentType.Left(16).CompareNoCase("multipart/mixed;") ) 
    { 
        /* This is not a multi-part message.  SO 
         * It does not have any attachments. 
         * We'll ignore it. 
         */ 
        goto END; 
    } 
    start = email->m_ContentType.Find("boundary=\""); 
    if ( start < 0 ) 
    { 
        /* The boundary not specified. We can't parse this */ 
        goto END; 
    } 
    start += 10; 
    end =  email->m_ContentType.Find('"',start); 
    if ( end < 0 ) 
    { 
        /* The boundary not specified. We can't parse this */ 
        goto END; 
    } 
    boundary = email->m_ContentType.Mid(start,end-start);    
 
    /*--------------------------*/ 
    /* Read the multipart body  */ 
    /*--------------------------*/ 
    firstAttachment = -1; 
    timeout = DOC2PDF_POP3_RECV_DELAY; // 15 minutes 
    while ( 1 ) 
    { 
        bytesread = sock.ReadLine(linein,&timeout); 
        if ( bytesread <= 0 ) 
        { 
            /* Some sort of error reading bail. */ 
            break; 
        } 
 
        /* Look for a boundary */ 
        if ( linein.Find(boundary) >= 0 ) 
        { 
            /* Found a boundary */ 
            if ( state == ATTACHMENTBODY ) 
            { 
                /* End of attachment body.  Add to List and Close file */ 
                email->m_Attachments.AddTail(attachmentName); 
                attachmentName.Empty(); 
                attachmentFile.Close();              
            } 
            else if ( state != ATTACHMENTHEADER ) 
            { 
                firstAttachment = TRUE;              
 
                /* read out the rest of the header */ 
                while ( sock.ReadLine(linein,&timeout) > 0 ) 
                { 
                    if ( linein == CRLF ) 
                    { 
                        break; 
                    } 
                } 
            } 
            else 
            { 
                firstAttachment = FALSE; 
            } 
 
 
            state = ATTACHMENTHEADER; 
        } 
        else 
        { 
 
            if ( state == ATTACHMENTBODY ) 
            { 
                /* Write linein to the attachment file */ 
                attachmentFile.Write(linein,linein.GetLength()); 
            } 
            else if ( state == ATTACHMENTHEADER ) 
            { 
                /* Are we at the end of the message */ 
                if ( linein == "." CRLF ) 
                { 
                    /* Yes */ 
                    break; 
                } 
                if ( firstAttachment == TRUE ) 
                { 
                    email->m_Body += linein; 
                } 
                else 
                { 
                    start = linein.Find("filename=\""); 
                    if ( start >= 0 ) 
                    { 
                        /* Extract the attachment name */ 
                        start += 10; 
                        end =  linein.Find('"',start); 
                        if ( end > 0 ) 
                        { 
                            attachmentName = m_SpoolDir; 
                            attachmentName += "\\"; 
                            attachmentName += prefix; 
                            attachmentName += "_"; 
                            attachmentName += linein.Mid(start,end-start); 
                            if ( attachmentFile.Open(attachmentName, 
                                                     CFile::modeCreate |  
                                                     CFile::modeWrite) ) 
                            { 
                                /* read out the rest of the header */ 
                                while ( sock.ReadLine(linein,&timeout) > 0 ) 
                                { 
                                    if ( linein == CRLF ) 
                                    { 
                                        break; 
                                    } 
                                } 
                                state = ATTACHMENTBODY; 
                            } 
                            else 
                            { 
                                /* Could not open attachment file */ 
                                attachmentName.Empty(); 
                                state = UNKNOWN; 
                            } 
                        } 
                    } 
                } 
            } 
        }        
    } 
 
    END: 
 
    return 0; 
} 
 
 
int CDoc2PdfEmailBox::Pop3Download() 
{ 
    CString             linein; 
    CString             lineout; 
    CMySocket           sock; 
    struct hostent*     he; 
    struct sockaddr_in  peeraddr; 
    CDoc2PdfEmail*      email; 
    int                 result; 
    time_t              timeout; 
    char                emailnum[13]; 
 
    /*------------------------*/ 
    /* Connect to pop3 server */ 
    /*------------------------*/ 
    timeout = DOC2PDF_CONNECT_DELAY; //30 seconds 
 
    sock.Create(); 
 
    //m_Log->Log("Pop3 Connect"); 
    sock.ReadLine(linein,&timeout); 
 
    he = gethostbyname((LPCSTR)m_Pop3Host); 
    if ( he == NULL ) 
    { 
        /* could not resolve pop3 hostname name */ 
        m_Log->Log("Could not resolve Pop3 server hostname"); 
        return -1; 
    } 
 
    memset(&peeraddr,0,sizeof(struct sockaddr_in)); 
    peeraddr.sin_family=AF_INET; 
    peeraddr.sin_port=htons(110); 
    peeraddr.sin_addr.s_addr = *((unsigned long*)he->h_addr); 
 
    if ( sock.Connect(&peeraddr,&timeout) != 0 ) 
    { 
        /* connection failed */ 
        m_Log->Log("Could not connect to Pop3 server"); 
        return -1; 
    } 
 
    /*-------*/ 
    /* Login */ 
    /*-------*/ 
    //m_Log->Log("Pop3 Login"); 
    sock.ReadLine(linein,&timeout); 
    if ( linein.Find("+OK ",0) < 0 ) 
    { 
        /* Not a POP3 server */ 
        m_Log->Log("ERROR: Bad Pop3 greeting"); 
        m_Log->Log(linein); 
        return -1; 
    } 
    lineout = "USER "; 
    lineout += m_Pop3User; 
    if ( sock.WriteLine(lineout,&timeout) != lineout.GetLength() ) 
    { 
        /* Write error */ 
        m_Log->Log("ERROR: write error"); 
        m_Log->Log(linein); 
        return -1; 
    } 
    sock.ReadLine(linein, &timeout); 
    if ( linein.Find("+OK",0) < 0 ) 
    { 
        /* Problems with USER */ 
        m_Log->Log("ERROR: USER return"); 
        m_Log->Log(linein); 
        return -1; 
    } 
    lineout = "PASS "; 
    lineout += m_Pop3Passwd; 
    if ( sock.WriteLine(lineout,&timeout) != lineout.GetLength() ) 
    { 
        /* Write error */ 
        m_Log->Log("ERROR: write error"); 
        return -1; 
    } 
    sock.ReadLine(linein,&timeout); 
    if ( linein.Find("+OK",0) < 0 ) 
    { 
        /* Bad password */ 
        m_Log->Log("Pop3 Bad password"); 
        return -1; 
    } 
 
    /*------------*/ 
    /* Fetch mail */ 
    /*------------*/ 
    timeout = DOC2PDF_POP3_RECV_DELAY; 
    result = 0; 
    m_Log->Log("Pop3 Download Started ..."); 
    while ( 1 ) 
    { 
        itoa(result + 1, emailnum,10); 
 
        lineout = "RETR "; 
        lineout += emailnum; 
        if ( sock.WriteLine(lineout,&timeout) != lineout.GetLength() ) 
        { 
            /* Problem with write */ 
            m_Log->Log("ERROR: Write error"); 
            break; 
        } 
        sock.ReadLine(linein,&timeout); 
        if ( linein.Find("+OK",0) < 0 ) 
        { 
            /* Problems with RETR */ 
            //m_Log->Log("Pop3 Download Finished"); 
            break; 
        } 
        email = new CDoc2PdfEmail(); 
        if ( ReadEmail(sock,emailnum,email) == 0 ) 
        { 
            m_Mailbox.AddTail(email); 
            lineout.Format("Read message %i",result + 1); 
        } 
        else 
        { 
            /* do add to mailbox */ 
            delete email;                    
        }        
 
        /* delete message */ 
        lineout = "DELE "; 
        lineout += emailnum; 
        if ( sock.WriteLine(lineout,&timeout) != lineout.GetLength() ) 
        { 
            /* Write error */ 
            m_Log->Log("ERROR: write error");    
            linein.TrimRight(); 
            m_Log->Log(linein); 
            break; 
        } 
        sock.ReadLine(linein,&timeout); 
        if ( linein.Find("+OK",0) < 0 ) 
        {             
            /* Problems with DELE */ 
            m_Log->Log("ERROR: DELE return"); 
            linein.TrimRight(); 
            m_Log->Log(linein); 
        } 
 
        result ++; 
 
        lineout.Format("Pop3 read and deleted message #%i",result); 
        m_Log->Log(lineout); 
    } 
 
    /* quit and close socket */ 
    lineout = "QUIT"; 
    sock.WriteLine(lineout,&timeout); 
    sock.ReadLine(linein,&timeout); 
    sock.Close(timeout); 
    //m_Log->Log("Pop3 Logout"); 
 
    return result; 
} 
 
int CDoc2PdfEmailBox::Convert() 
{ 
    POSITION        mboxpos; 
    POSITION        atchpos; 
    CDoc2PdfEmail*  email; 
    CString         attachmentName; 
    CString         attachmentExt; 
    CString         tmp; 
    BOOL            converted; 
    int             result = 0; 
 
 
    mboxpos = m_Mailbox.GetHeadPosition(); 
    while ( mboxpos ) 
    { 
        email = m_Mailbox.GetAt(mboxpos); 
 
        /* Original message separator */ 
        email->m_Body.Insert(0,DOC2PDF_ORIGMSG); 
 
        /* Convert all attachments */ 
        if ( email->m_Attachments.GetCount() ) 
        { 
            atchpos = email->m_Attachments.GetHeadPosition(); 
            while ( atchpos ) 
            { 
                converted = FALSE; 
 
                if ( ConvertFromBase64(email->m_Attachments.GetAt(atchpos)) != 0 ) 
                { 
                    tmp ="base64 conversion failed for "; 
                    tmp += email->m_Attachments.GetAt(atchpos); 
                    m_Log->Log(tmp); 
                    tmp.TrimRight(); 
                    tmp += CRLF; 
                    tmp += CRLF; 
                    email->m_Body.Insert(0,tmp); 
                    goto END; 
                } 
 
                attachmentName = email->m_Attachments.GetAt(atchpos); 
                attachmentExt = attachmentName.Right(4); 
                attachmentExt.MakeLower(); 
                attachmentName = attachmentName.Left(attachmentName.GetLength() - 4); 
                if ( attachmentExt == ".doc" ) 
                { 
                    if ( ConvertDoc2Ps(attachmentName + ".doc",attachmentName + ".ps") != 0 ) 
                    { 
                        tmp = ".doc conversion Failed for "; 
                        tmp += email->m_Attachments.GetAt(atchpos); 
                        m_Log->Log(tmp); 
                        tmp.TrimRight(); 
                        tmp += CRLF; 
                        tmp += CRLF; 
                        email->m_Body.Insert(0,tmp); 
                        goto END; 
                    } 
 
                    while ( DeleteFile(attachmentName + ".doc") == 0 ) 
                    { 
                        Sleep(DOC2PDF_DELETE_DELAY); 
                    } 
                } 
                else if ( attachmentExt == ".ppt" ) 
                { 
                    tmp = ".ppt conversion not yet supported for "; 
                    tmp += email->m_Attachments.GetAt(atchpos); 
                    m_Log->Log(tmp); 
                    tmp.TrimRight(); 
                    tmp += CRLF; 
                    tmp += CRLF; 
                    email->m_Body.Insert(0,tmp); 
                    goto END; 
                } 
                else if ( attachmentExt == ".xls" ) 
                { 
                    tmp = ".xls conversion not yet supported for "; 
                    tmp += email->m_Attachments.GetAt(atchpos); 
                    m_Log->Log(tmp); 
                    tmp.TrimRight(); 
                    tmp += CRLF; 
                    tmp += CRLF; 
                    email->m_Body.Insert(0,tmp); 
                    goto END; 
                } 
                else 
                { 
                    tmp = "Conversion not supported for "; 
                    tmp += email->m_Attachments.GetAt(atchpos); 
                    m_Log->Log(tmp); 
                    tmp.TrimRight(); 
                    tmp += CRLF; 
                    tmp += CRLF; 
                    email->m_Body.Insert(0,tmp); 
                    goto END; 
                } 
 
                if ( ConvertPs2Pdf(CString("c:\\tmp\\ps2pdf.at"),attachmentName + ".ps", attachmentName + ".pdf") != 0 ) 
                { 
                    tmp = ".ps conversion failed for "; 
                    tmp += email->m_Attachments.GetAt(atchpos); 
                    m_Log->Log(tmp); 
                    tmp.TrimRight(); 
                    tmp += CRLF; 
                    tmp += CRLF; 
                    email->m_Body.Insert(0,tmp); 
                    goto END; 
                } 
 
                while ( DeleteFile(attachmentName + ".ps") == 0 ) 
                { 
                    Sleep(DOC2PDF_DELETE_DELAY); 
                } 
 
                if ( ConvertToBase64(attachmentName + ".pdf") == 0 ) 
                { 
                    converted = TRUE;                    
                } 
                else 
                { 
                    tmp = "base64 conversion failed for "; 
                    tmp += email->m_Attachments.GetAt(atchpos); 
                    m_Log->Log(tmp); 
                    tmp.TrimRight(); 
                    tmp += CRLF; 
                    tmp += CRLF; 
                    email->m_Body.Insert(0,tmp); 
                } 
 
                END: 
 
                if ( converted == TRUE ) 
                { 
                    email->m_Attachments.GetAt(atchpos) = attachmentName + ".pdf"; 
                    attachmentName = email->m_Attachments.GetAt(atchpos); 
                    result ++; 
                } 
                else 
                { 
                    while ( DeleteFile(email->m_Attachments.GetAt(atchpos)) == FALSE ) 
                    { 
                        Sleep(DOC2PDF_DELETE_DELAY); 
                    } 
                    email->m_Attachments.GetAt(atchpos).Empty(); 
                } 
 
                email->m_Attachments.GetNext(atchpos); 
            } 
 
            tmp.Format("Converted attachment %i from %s",  
                       result, 
                       email->m_From); 
            tmp.TrimRight(); 
            m_Log->Log(tmp); 
 
        } 
        else 
        { 
            email->m_Body.Insert(0,DOC2PDF_NOCONVERT); 
            tmp.Format("No attachments in email from: %s.",email->m_From); 
            tmp.TrimRight(); 
            m_Log->Log(tmp); 
        } 
 
 
        /* Modify To to include the sender */ 
        email->m_To += ","; 
        email->m_To += email->m_From; 
        email->m_To.Remove('\r'); 
        email->m_To.Remove('\n'); 
        email->m_Cc.Remove('\r'); 
        email->m_Cc.Remove('\n'); 
 
        /* Modify Subject */ 
        email->m_Subject.Insert(0,"Converted: "); 
        email->m_Subject.Remove('\r'); 
        email->m_Subject.Remove('\n'); 
 
        /* Remove CRLF from Date */ 
        email->m_Date.Remove('\r'); 
        email->m_Date.Remove('\n'); 
 
        /* Modify Body (add greeting) */ 
        email->m_Body.Insert(0,DOC2PDF_GREETING); 
 
        m_Mailbox.GetNext(mboxpos);      
    } 
 
    return result; 
} 
 
int CDoc2PdfEmailBox::SmptUpload() 
{ 
    POSITION            mboxpos; 
    POSITION            addrpos; 
    POSITION            atchpos; 
    CString             linein; 
    CString             lineout; 
    CString             attachment; 
    CString             tmp; 
    CFile               atchFile; 
    CMySocket           sock; 
    struct hostent*     he; 
    struct sockaddr_in  peeraddr; 
    CDoc2PdfEmail*      email; 
    int                 count; 
    time_t              timeout; 
    CStringList         addrlist; 
    char*               buf = NULL; 
 
    /*------------------------*/ 
    /* Connect to Smtp server */ 
    /*------------------------*/ 
    timeout = DOC2PDF_CONNECT_DELAY; 
 
    sock.Create(); 
 
    m_Log->Log("SMPT Connect"); 
 
    he = gethostbyname((LPCSTR)m_SmtpHost); 
    if ( he == NULL ) 
    { 
        /* could not resolve pop3 hostname name */ 
        return -1; 
    } 
 
    memset(&peeraddr,0,sizeof(struct sockaddr_in)); 
    peeraddr.sin_family=AF_INET; 
    peeraddr.sin_port=htons(25); 
    peeraddr.sin_addr.s_addr = *((unsigned long*)he->h_addr); 
 
    if ( sock.Connect(&peeraddr,&timeout) != 0 ) 
    { 
        /* connection failed */ 
        return -1; 
    } 
 
    /*-----------------------------*/ 
    /* Read Greeting and say Hello */ 
    /*-----------------------------*/ 
    sock.ReadLine(linein,&timeout); 
    if ( linein.Find("220 ",0) < 0 ) 
    { 
        /* Not a SMTPP server */ 
        m_Log->Log("ERROR: Smtp bad greeting"); 
        m_Log->Log(linein); 
        return -1; 
    } 
    lineout = "HELO there"; 
    if ( sock.WriteLine(lineout,&timeout) != lineout.GetLength() ) 
    { 
        /* Write Error */ 
        m_Log->Log("ERROR: Write error"); 
        return -1; 
    } 
    sock.ReadLine(linein,&timeout); 
    if ( linein.Find("250 ",0) < 0 ) 
    { 
        /* Not a SMTP server */ 
        m_Log->Log("ERROR: Smtp bad greeting response"); 
        m_Log->Log(linein); 
        return -1; 
    } 
 
    /*-----------------------*/ 
    /* Send Mail in mail box */ 
    /*-----------------------*/ 
    buf = (char*) malloc(DOC2PDF_BUFSIZE); 
    if ( buf == NULL ) 
    { 
        m_Log->Log("ERROR: memory allocation error"); 
        return -1; 
    } 
 
    timeout = DOC2PDF_SMTP_SEND_DELAY; 
 
    while ( (mboxpos = m_Mailbox.GetHeadPosition()) ) 
    { 
        email = m_Mailbox.GetAt(mboxpos); 
 
        /* MAIL FROM: */ 
        lineout = "MAIL FROM: "; 
        lineout += m_MyEmailAddress; 
        if ( sock.WriteLine(lineout,&timeout) != lineout.GetLength() ) 
        { 
            /* Problems doing MailFrom */ 
            m_Log->Log("ERROR: write error"); 
            goto END; 
        } 
        sock.ReadLine(linein,&timeout); 
        if ( linein.Find("250 ",0) < 0 ) 
        { 
            /* Problems doing Mail From */ 
            m_Log->Log("ERROR: Smtp problems with MAIL FROM:"); 
            m_Log->Log(linein); 
            goto END; 
        } 
 
        /* MAIL TO: for To recipients */ 
        ConvertAddressStringToList(email->m_To,addrlist); 
        email->m_To.Empty(); 
        addrpos = addrlist.GetHeadPosition(); 
        while ( addrpos ) 
        { 
            /* Don't let our address be replied do */ 
            if ( addrlist.GetAt(addrpos).Find(m_MyEmailAddress) < 0 ) 
            { 
                lineout = "RCPT TO: "; 
                lineout += addrlist.GetAt(addrpos); 
                if ( sock.WriteLine(lineout,&timeout) == lineout.GetLength() ) 
                { 
                    /* Read the (hopefully 250 response) */ 
                    sock.ReadLine(linein,&timeout);  
                } 
                email->m_To += addrlist.GetAt(addrpos); 
                email->m_To += ","; 
            } 
            addrlist.GetNext(addrpos); 
        } 
        email->m_To.TrimRight(','); 
 
        /* MAIL TO: for Cc recipients */ 
        ConvertAddressStringToList(email->m_Cc,addrlist); 
        email->m_Cc.Empty(); 
        addrpos = addrlist.GetHeadPosition(); 
        while ( addrpos ) 
        { 
            /* Don't let our address be replied do */ 
            if ( addrlist.GetAt(addrpos).Find(m_MyEmailAddress) < 0 ) 
            { 
                lineout = "MAIL TO: "; 
                lineout += addrlist.GetAt(addrpos); 
 
                if ( sock.WriteLine(lineout,&timeout) == lineout.GetLength() ) 
                { 
                    /* Read the (hopefully 250 response) */ 
                    sock.ReadLine(linein,&timeout);  
                } 
                email->m_Cc += addrlist.GetAt(addrpos); 
                email->m_Cc += ","; 
            } 
            addrlist.GetNext(addrpos); 
        } 
        email->m_To.TrimRight(','); 
 
 
        /* DATA */ 
        lineout = "DATA"; 
        if ( sock.WriteLine(lineout,&timeout) != lineout.GetLength() ) 
        { 
            /* Problems passing DATA */ 
            m_Log->Log("ERROR: write error"); 
            goto END; 
        } 
        sock.ReadLine(linein,&timeout); 
        if ( linein.Find("354 ",0) < 0 ) 
        { 
            /* Not a SMTP server */ 
            m_Log->Log("ERROR: Smtp problems with MAIL FROM:"); 
            m_Log->Log(linein); 
            goto END; 
        } 
        lineout = "From: "; 
        lineout += m_MyEmailAddress; 
        lineout += CRLF; 
        lineout += "To: "; 
        lineout += email->m_To; 
        lineout += CRLF; 
        lineout += "Subject: "; 
        lineout += email->m_Subject; 
        lineout += CRLF; 
        lineout += "Date: "; 
        lineout += email->m_Date; 
        lineout += CRLF; 
        lineout += "MIME-Version: 1.0" CRLF; 
        lineout += "Content-Type: Multipart/Mixed; boundary=\""; 
        lineout +=  DOC2PDF_PART_BOUNDARY "\"" CRLF CRLF; 
        lineout += "This is a multipart MIME message" CRLF CRLF; 
        lineout += "--" DOC2PDF_PART_BOUNDARY CRLF; 
        lineout += "Content-Type: text/plain; charset=US-ASCII"; 
        lineout += CRLF CRLF; 
        lineout += email->m_Body; 
        if ( sock.WriteLine(lineout,&timeout) != lineout.GetLength() ) 
        { 
            /* Problems with body */ 
            m_Log->Log("ERROR: write error"); 
            goto END; 
        } 
        atchpos = email->m_Attachments.GetHeadPosition(); 
        while ( atchpos ) 
        { 
            attachment = email->m_Attachments.GetAt(atchpos); 
            if ( attachment.GetLength() ) 
            { 
                if ( atchFile.Open(attachment,CFile::modeRead) ) 
                { 
                    attachment = atchFile.GetFileName(); 
                    attachment = attachment.Right(attachment.GetLength() - attachment.Find('_') - 1); 
                    lineout = CRLF "--"DOC2PDF_PART_BOUNDARY CRLF; 
                    lineout += "Content-Type: application/pdf; name=\""; 
                    lineout += attachment; 
                    lineout += "\"" CRLF; 
                    lineout += "Content-Transfer-Encoding: base64" CRLF; 
                    lineout += "Content-Disposition: attachment; filename=\""; 
                    lineout += attachment; 
                    lineout += "\"" CRLF CRLF; 
                    if ( sock.WriteLine(lineout,&timeout) != lineout.GetLength() ) 
                    { 
                        /* Problems passing sending */ 
                        m_Log->Log("ERROR: write error"); 
                        goto END;                            
                    } 
                    while ( (count = atchFile.Read(buf,DOC2PDF_BUFSIZE)) > 0 ) 
                    { 
                        sock.Write(buf,count,&timeout);                          
                    } 
 
                    atchFile.Close(); 
 
                    DeleteFile(email->m_Attachments.GetAt(atchpos)); 
                } 
 
            } 
 
            email->m_Attachments.GetNext(atchpos); 
        } 
 
        lineout = CRLF "--" DOC2PDF_PART_BOUNDARY "--" CRLF CRLF; 
        lineout += CRLF "."; 
        if ( sock.WriteLine(lineout,&timeout) != lineout.GetLength() ) 
        { 
            /* Problems passing DATA */ 
            m_Log->Log("ERROR: write error"); 
            goto END;                
        } 
        sock.ReadLine(linein,&timeout); 
        if ( linein.Find("250 ",0) < 0 ) 
        { 
            /* Not a terminate data */ 
            m_Log->Log("ERROR: could not terminate DATA"); 
            m_Log->Log(linein); 
            goto END; 
        } 
 
        tmp = "SMTP sent reply to: "; 
        tmp += email->m_To.Left(20); 
        tmp.TrimRight(); 
        tmp += "..."; 
        m_Log->Log(tmp); 
 
        END:  
 
        m_Mailbox.RemoveHead(); 
    } 
 
    sock.Close(timeout); 
 
    if ( buf ) 
    { 
        free(buf); 
    } 
 
    return 0; 
} 
 
void  CDoc2PdfEmailBox::SetLog(CDoc2PdfLog* log) 
{ 
    m_Log = log; 
}