IM/MS/smtp/smtp.cpp

193 lines
4.6 KiB
C++

#include "smtp.h"
#include <iostream>
namespace Jxiepc {
Smtp::Smtp(int port, std::string domain, std::string user, std::string pwd,
std::string t_mail, std::string title, std::string content, std::string type)
: m_port(port), m_domain(domain), m_user(user), m_password(pwd), m_tmail(t_mail),
m_title(title), m_content(content), m_type(type) {
ret = init();
if(ret < 0) {
perror("init error");
}
}
Smtp::~Smtp() {
close(m_sockfd);
}
int Smtp::init() {
if(make_connect() == -1) {
return -1;
}
std::string str;
Recv();
if(strstr(m_buf, "220") == nullptr) { return -1; }
std::cout << "****: " << m_buf << std::endl;
Send("HELO " + m_user + "\r\n");
Recv();
if(strstr(m_buf, "250") == nullptr) { return -1; }
Send("AUTH LOGIN\r\n");
Recv();
if(strstr(m_buf, "334") == nullptr) { return -1; }
str = m_user.substr(0, m_user.find('@', 0));
str = enBase64(str.c_str());
str += "\r\n";
Send(str);
Recv();
if(strstr(m_buf, "334") == nullptr) { return -1; }
Send(enBase64(m_password.c_str()) + "\r\n");
Recv();
if(strstr(m_buf, "235") == nullptr) { return -1; }
std::cout << "AUTH SUCCESS..." << std::endl;
Send("MAIL FROM: <" + m_user + ">\r\n");
Recv();
if(strstr(m_buf, "250") == nullptr) { return -1; }
Send("RCPT TO: <" + m_tmail+ ">\r\n");
Recv();
if(strstr(m_buf, "250") == nullptr) { return -1; }
Send("DATA\r\n");
Recv();
str = "From: " + m_user + "\r\n";
str += "To: " + m_tmail + "\r\n";
str += "Subject: " + m_title + "\r\n";
str += "Content-Type: multipart/mixed;boundary=qwertyuiop\r\n";
str += "\r\n--qwertyuiop\r\n";
if(m_type == "html"){
str += "content-type:text/html;charset=utf-8\r\n"; //html类型
}else{
str += "Content-Type: text/plain;charset=utf-8\r\n"; //文本类型
}
Send(str);
str = "\r\n" + m_content + "\r\n";
str += "\r\n--qwertyuiop--\r\n.\r\n";
Send(str);
Recv();
if(strstr(m_buf, "250") == nullptr) { return -1; }
std::cout << "send success..." << std::endl;
Send("QUIT\r\n");
return 0;
}
int Smtp::make_connect() {
m_sockfd = Socket(AF_INET, SOCK_STREAM, 0);
hostent *host_info = gethostbyname(m_domain.c_str());
if(host_info == nullptr){
perror("gethostbyname error");
return -1;
}
if(host_info->h_addrtype != AF_INET) {
perror("AF_INET error");
return -1;
}
char buf[128];
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = *((unsigned long*)host_info->h_addr_list[0]);
addr.sin_port = htons(m_port);
Connect(m_sockfd, (struct sockaddr*)&addr, sizeof(addr));
return 0;
}
void Smtp::Connect(int fd, const struct sockaddr *sa, socklen_t salen) {
if(connect(fd, sa, salen) == -1) {
perror("connect error");
exit(-1);
}
}
int Smtp::Socket(int family, int type, int protocol) {
int sockfd;
if((sockfd = socket(family, type, protocol)) == -1) {
perror("socket error");
exit(-1);
}
return sockfd;
}
ssize_t Smtp::Send(const std::string& str) {
ssize_t n;
// std::cout << str;
if((n = send(m_sockfd, str.c_str(), str.length(), 0)) == -1) {
perror("write error");
exit(-1);
}
return n;
}
ssize_t Smtp::Recv() {
ssize_t n;
m_buf[0] = '\0';
if((n == recv(m_sockfd, m_buf, 0xFFF, 0)) == -1) {
perror("recv error");
exit(-1);
}
return n;
}
std::string Smtp::enBase64(const std::string& str)
{
std::string base64_table="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int str_len = str.length();
std::string res="";
for (int strp=0; strp<str_len/3*3; strp+=3)
{
res+=base64_table[str[strp]>>2];
res+=base64_table[(str[strp]&0x3)<<4 | (str[strp+1])>>4];
res+=base64_table[(str[strp+1]&0xf)<<2 | (str[strp+2])>>6];
res+=base64_table[(str[strp+2])&0x3f];
}
if (str_len%3==1)
{
int pos=str_len/3 * 3;
res += base64_table[str[pos]>>2];
res += base64_table[(str[pos]&0x3)<<4];
res += "=";
res += "=";
}
else if (str_len%3==2)
{
int pos=str_len/3 * 3;
res += base64_table[str[pos]>>2];
res += base64_table[(str[pos]&0x3)<<4 | (str[pos+1])>>4];
res += base64_table[(str[pos+1]&0xf)<<2];
res += "=";
}
return res;
}
bool Smtp::getRet() const {
if(ret < 0) {
return false;
} else {
return true;
}
}
}