⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 email.cpp

📁 经典的string 函数库学习资料
💻 CPP
字号:
/** * @file email.cpp * @brief 发送电子邮件包装,函数的实现 * @author 泥偶 * @since  2003-09-12 * @date   2003-09-23 */extern "C"{    #include <errno.h>    #include <sys/time.h>    #include <sys/uio.h>    #include <sys/wait.h>    #include <unistd.h>}#include <cstddef>#include <fstream>#include "email.hpp"namespace x{    bool Email::setTo(const xstring& inAddress)    {        if (!inAddress.isEmail())        {            return false;        }        if (!this->mailTo.empty())        {            this->mailTo += ',';        }        this->mailTo += inAddress;        return true;    }    bool Email::setCc(const xstring& inAddress)    {        if (!inAddress.isEmail())        {            return false;        }        if (!this->mailCc.empty())        {            this->mailCc += ',';        }        this->mailCc += inAddress;        return true;    }    bool Email::setBcc(const xstring& inAddress)    {        if (!inAddress.isEmail())        {            return false;        }        if (!this->mailBcc.empty())        {            this->mailBcc += ',';        }        this->mailBcc += inAddress;        return true;    }    bool Email::setFrom(const xstring& inAddress)    {        if (!inAddress.isEmail())        {            return false;        }        this->mailFrom = inAddress;        return true;    }    bool Email::setSubject(const xstring& inSubject)    {        if (inSubject.trim().empty())        {            return false;        }        this->mailSubject = inSubject;        return true;    }    bool Email::setText(const xstring& inText)    {        if (inText.trim().empty())        {            return false;        }        this->mailText = inText;        return true;    }    bool Email::setHTML(const xstring& inHTML)    {        if (inHTML.trim().empty())        {            return false;        }        this->mailHTML = inHTML;        return true;    }    bool Email::addAttachment(        const xstring& inMessage,        const xstring& inName,        const xstring& inContentType    )    {        if (inMessage.trim().empty())        {            return false;        }        Attachment attachment;        attachment.ctype    = inContentType;        attachment.message  = inMessage;        attachment.encode   = "";        attachment.name     = inName;        this->mailAttachments.push_back(attachment);        return true;    }    bool Email::addAttachmentFile(const xstring& inFileName)    {        xstring message;        char c;        std::ifstream file(inFileName.c_str());        if (!file)        {            return false;        }        while (file.get(c))        {            message += c;        }        return this->addAttachment(message, inFileName.basename(),            this->getContentType(inFileName));    }   // 自动关闭文件    bool Email::send(void)    {        // 设置邮件头为空        xstring mailHeader;        // 添加抄送人        if (!this->mailCc.empty())        {            mailHeader += "Cc: " + this->mailCc + "\n";        }        // 添加秘密抄送人        if (!this->mailBcc.empty())        {            mailHeader += "Bcc: " + this->mailBcc + "\n";        }        // 添加发件人        if (!this->mailFrom.empty())        {            mailHeader += "From: " + this->mailFrom + "\n";        }        // 邮件正文        if (!this->mailText.empty()) {            this->addAttachment(this->mailText, "", "text/plain");        }        // HTML格式邮件正文        if (!this->mailHTML.empty()) {            this->addAttachment(this->mailHTML, "", "text/html");        }        mailHeader += "MIME-Version: 1.0\n" + this->buildMultipart();        return this->mail(this->mailTo, this->mailSubject, "", mailHeader);    }   // Email::send()//============================================================================    xstring Email::getContentType(const xstring& inFilename)    {        xstring extension;        xstring basename = inFilename.basename();        xstring::size_type idx = basename.rfind('.');        if (xstring::npos != idx)        {            extension = basename.substr(idx + 1);        }        if ("gif" == extension)        {            return "image/gif";        }        if ("gz" == extension)        {            return "application/x-gzip";        }        if ("htm" == extension || "html" == extension)        {            return "text/html";        }        if ("jpe" == extension || "jpeg" == extension || "jpg" == extension)        {            return "image/jpeg";        }        if ("png" == extension)        {            return "image/png";        }        if ("tar" == extension)        {            return "application/x-tar";        }        if ("txt" == extension)        {            return "text/plain";        }        if ("zip" == extension)        {            return "application/x-zip-compressed";        }        return "application/octet-stream";    }   // Email::getContentType()    // Build message parts of an multipart mail     xstring Email::buildMessage(const Attachment& inAttachment)    {        return "Content-Type: " + inAttachment.ctype +            (inAttachment.name.empty() ?            "" : "; name=\"" + inAttachment.name + "\"") +            "\nContent-Transfer-Encoding: base64\n\n" +            inAttachment.message.base64_encode().chunk_split() + "\n";    }    // Build a multipart mail     xstring Email::buildMultipart(void)    {        struct timeval now;        gettimeofday(&now, NULL);        int microtime = now.tv_sec * 1000000 + now.tv_usec;        xstring boundary = 'b' + xstring(microtime).md5();        xstring multipart = "Content-Type: multipart/mixed; boundary = " +            boundary + "\n\nThis is a MIME encoded message.\n\n--" + boundary;        for (int i = this->mailAttachments.size() - 1; i >= 0; --i)        {            multipart += "\n" + this->buildMessage(this->mailAttachments[i]) +                "--" + boundary;        }        multipart += "--\n";        return multipart;    }    // 调用sendmail发送邮件    bool Email::mail(        const xstring& to,        const xstring& subject,        const xstring& message,        const xstring& additional_headers    )    {        const xstring sendmail_path = "/usr/sbin/sendmail";        // 环境        char* env_init[] = {            "USER=unknown",            "PATH=/tmp",            NULL        };        int fd[2];        pid_t pid;        if (pipe(fd) < 0)                   // 创建半双工管道        {            return false;   // 坏掉了        }        switch (pid = fork())               // 创建子进程        {        case -1 :       // 坏掉了            close(fd[0]);                   // 关闭半双工管道读的一端            close(fd[1]);                   // 关闭半双工管道写的一端            return false;        case 0 :        // 子进程            close(fd[1]);                   // 关闭半双工管道写的一端            if (fd[0] != STDIN_FILENO)            {                // 把半双工管道读的一端和标准输入捆在一起                if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO)                {                    exit(1);    // 坏掉了                }                close(fd[0]);               // dup2以后这个东东就用不着了            }            // 运行sendmail            if (execle(sendmail_path.c_str(), "sendmail", "-t", "-i",                (char*)0, env_init) < 0)            {                exit(1);        // 坏掉了            }            exit(1);    // 执行不到这里        default :       // 父进程            close(fd[0]);                   // 关闭半双工管道读的一端            writen(fd[1], "To: " + to + "\n");            writen(fd[1], "Subject: " + subject + "\n");            writen(fd[1], additional_headers + "\n");            writen(fd[1], message + "\n");            close(fd[1]);                   // 关闭半双工管道,毁尸灭迹            if (waitpid(pid, NULL, 0) < 0)  // 等子进程死掉            {                return false;               // 坏掉了            }            return true;        }    }   // Email::mail()    /// 向文件描述符写,保证写出指定的字节数    ssize_t Email::writen(int d, const xstring& str)    {        return writen(d, str.data(), str.size());    }    /// 向文件描述符写n字节写,保证写出指定的字节数    ssize_t Email::writen(int d, const void* buf, size_t nbytes)    {        size_t      nleft;        size_t      nwritten;        const char* ptr;        ptr = static_cast<const char*>(buf);    // 不能对void指针进行算术运算        nleft = nbytes;        while (nleft > 0)        {            nwritten = write(d, ptr, nleft);            if (nwritten <= 0)            {                if (EINTR == errno)                {                    nwritten = 0;                }                else                {                    return nwritten;                }            }            nleft -= nwritten;            ptr   += nwritten;        }        return nbytes;    }}   // namespace x

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -