mailer_class.cpp.svn-base
来自「这是一个很好的参考代码」· SVN-BASE 代码 · 共 1,379 行 · 第 1/3 页
SVN-BASE
1,379 行
} buff[len1] = '\0'; returnstring = buff; if(returnstring.substr(0,3) != OK) { /* we must issue a quit even on an error. in keeping with the rfc's */ if(Send(len1, s, "QUIT\r\n", 6, 0)) { char dummy[buffsize]; Recv(len1, s, dummy, buffsize, 0); } Closesocket(s); /* don't know what went wrong here if we are connected!! * we continue because maybe we have more than 1 server to connect to. */ continue; } } if(auth) { if(!authenticate(greeting, s)) { continue; // try the next server, you never know!! } } /* send the from */ commandline = "MAIL FROM:<" + fromAddress.address + ">\r\n"; if(!Send(len1, s, commandline.c_str(), commandline.length(), 0)) { returnstring = "554 MAIL FROM sending error"; continue; } if(!Recv(len1, s, buff, buffsize, 0)) { returnstring = "554 MAIL FROM receive error"; continue; } /* check for an error */ buff[len1] = '\0'; returnstring = buff; if(returnstring.substr(0,3) != OK) { // we must issue a quit even on an error. in keeping with the rfc's if(Send(len1, s, "QUIT\r\n", 6, 0)) { char dummy[buffsize]; Recv(len1, s, dummy, buffsize, 0); } Closesocket(s); /* don't know what went wrong here if we are connected!! * we continue because maybe we have more than 1 serevr to connect to. */ continue; } for(recipient_const_iter recip = recipients.begin(); recip < recipients.end(); ++recip) { /* send recipient */ commandline = "RCPT TO: <" + (*recip).first.address + ">\r\n"; if(!Send(len1, s, commandline.c_str(), commandline.length(), 0)) { returnstring = "554 Transaction failed"; continue; } if(!Recv(len1, s, buff, buffsize, 0)) { returnstring = buff; continue; } buff[len1] = '\0'; returnstring = buff; if(returnstring.substr(0,3) != OK) { continue; } } /* send message body */ if(!Send(len1, s, "DATA\r\n", 6, 0)) { returnstring = "554 DATA send error"; continue; } if(!Recv(len1, s, buff, buffsize, 0)) { returnstring = "554 DATA, server response error"; continue; } buff[len1] = '\0'; returnstring = buff; if(returnstring.substr(0,3) != "354") { /* we must issue a quit even on an error. in keeping with the rfc's */ if(Send(len1, s, "QUIT\r\n", 6, 0)) { char dummy[buffsize]; Recv(len1, s, dummy, buffsize, 0); } Closesocket(s); continue; } /* Sending the email */ if(!Send(len1, s, &smtpheader[0], smtpheader.size(), 0)) { returnstring = "554 DATA, server response error (actual send)"; continue; } if(!Recv(len1, s, buff, buffsize, 0)) { returnstring = "554 DATA, server response error (actual send)"; continue; } /* The server should give us a 250 reply if the mail was delivered okay */ buff[len1] = '\0'; returnstring = buff; if(returnstring.substr(0,3) != OK) { /* we must issue a quit even on an error. in keeping with the rfc's */ if(Send(len1, s, "QUIT\r\n", 6, 0)) { char dummy[buffsize]; Recv(len1, s, dummy, buffsize, 0); } Closesocket(s); continue; } // hang up the connection if(Send(len1, s, "QUIT\r\n", 6, 0)) { char dummy[buffsize]; Recv(len1, s, dummy, buffsize, 0); } if(returnstring.substr(0,3) != "221") { // maybe will use this later } Closesocket(s); // disconnect break; }}/* build the SMTP message */std::vector<char> Mailer::makesmtpmessage() const{ std::string sender(fromAddress.address); if(sender.length()) { /* extract the servername from the address */ std::string::size_type pos(sender.find("@")); if(pos != std::string::npos) { // found the servername beginning sender = sender.substr(0, pos); } } /* construct the header */ std::vector<char> ret; std::string headerline; if(fromAddress.name.length()) { headerline = "From: " + fromAddress.address + " (" + fromAddress.name + ")\r\n" "Reply-To: " + fromAddress.address + "\r\n"; ret.insert(ret.end(), headerline.begin(), headerline.end()); } else { headerline = "From: " + fromAddress.address + " \r\n" "Reply-To: " + fromAddress.address + "\r\n"; ret.insert(ret.end(), headerline.begin(), headerline.end()); } headerline.clear(); // don't need that any longer /* add the recipients to the header */ std::vector<std::string> to, cc, bcc; for(recipient_const_iter recip = recipients.begin(); recip < recipients.end(); ++recip) { if(recip->second == TO) { to.push_back(recip->first.address); } else if(recip->second == Cc) { cc.push_back(recip->first.address); } else if(recip->second == Bcc) { bcc.push_back(recip->first.address); } } vec_str_const_iter it; // instead of making three on the stack, just one (stops VC whining too) int count = to.size(); if(count) { headerline += "To: "; } for(it = to.begin(); it < to.end(); ++it) { headerline += *it; if(count > 1 && ((it + 1) < to.end()) ) { headerline += ",\r\n "; // must add a space after the comma } else { headerline += "\r\n"; } } /* set CC */ count = cc.size(); if(count) { headerline += "Cc: "; } for(it = cc.begin(); it < cc.end(); ++it) { headerline += *it; if(count > 1 && ((it + 1) < cc.end()) ) { headerline += ",\r\n "; // must add a space after the comma } else { headerline += "\r\n"; } } /* set BCC */ count = bcc.size(); if(count) { headerline += "Bcc: "; } for(it = bcc.begin(); it < bcc.end(); ++it) { headerline += *it; if(count > 1 && ((it + 1) < bcc.end()) ) { headerline += ",\r\n "; // must add a space after the comma } else { headerline += "\r\n"; } } ret.insert(ret.end(), headerline.begin(), headerline.end()); /* set MIME */ const std::string boundary("bounds=_NextP_0056wi_0_8_ty789432_tp"); bool MIME(false); if(attachments.size() || messageHTML.size()) { MIME = true; } if(MIME) { // we have attachments /* use MIME 1.0 */ headerline = "MIME-Version: 1.0\r\n" "Content-Type: multipart/mixed;\r\n" "\tboundary=\"" + boundary + "\"\r\n"; ret.insert(ret.end(), headerline.begin(), headerline.end()); headerline.clear(); } /* add the timestamp */ time_t t; time(&t); tm* ptm = localtime(&t); if(ptm) { headerline = "Date: "; std::ostringstream str; if(ptm->tm_mday < 10) { // add a trailing zero if single digit str << "0"; } str << ptm->tm_mday << " "; switch(ptm->tm_mon) { case 0: str << "Jan "; break; case 1: str << "Feb "; break; case 2: str << "Mar "; break; case 3: str << "Apr "; break; case 4: str << "May "; break; case 5: str << "Jun "; break; case 6: str << "Jul "; break; case 7: str << "Aug "; break; case 8: str << "Sep "; break; case 9: str << "Oct "; break; case 10: str << "Nov "; break; case 11: str << "Dec "; break; default: str << "Jan "; // be safe, pretend the beginning of the year } std::ostringstream year; year << ptm->tm_year; str << year.str().substr(year.str().length() -2, 2) << " "; if(ptm->tm_hour < 10) { str << "0"; } str << ptm->tm_hour << ":"; if(ptm->tm_min < 10) { str << "0"; } str << ptm->tm_min << ":"; if(ptm->tm_sec < 10) { str << "0"; } str << ptm->tm_sec; /* set the timezone offset */ tzset(); const int offset( ptm->tm_gmtoff / 60 / 60); // is in seconds, make hours if(abs(offset) < 10) { if(offset < 0) { str << " -0" << abs(offset) << "00" << "\r\n"; } else { str << " 0" << abs(offset) << "00" << "\r\n"; } } else { if(offset < 0) { str << " -" << abs(offset) << "00" << "\r\n"; } else { str << " " << abs(offset) << "00" << "\r\n"; } } headerline += str.str(); // add the date to the headers ret.insert(ret.end(), headerline.begin(), headerline.end()); } /* add the subject */ headerline = "Subject: " + subject + "\r\n\r\n"; ret.insert(ret.end(), headerline.begin(), headerline.end()); if(MIME) { headerline = "This is a MIME encapsulated message\r\n\r\n"; headerline = headerline + "--" + boundary + "\r\n"; if(!messageHTML.size()) { // plain text message first. headerline += "Content-type: text/plain; charset=iso-8859-1\r\nContent-transfer-encoding: 7BIT\r\n\r\n"; ret.insert(ret.end(), headerline.begin(), headerline.end()); ret.insert(ret.end(), message.begin(), message.end()); headerline = "\r\n\r\n--" + boundary + "\r\n"; } else { // make it multipart/alternative as we have html const std::string innerboundary("inner_jfd_0078hj_0_8_part_tp"); headerline += "Content-Type: multipart/alternative;\r\n" "\tboundary=\"" + innerboundary + "\"\r\n"; /* need the inner boundary starter */ headerline += "\r\n\r\n--" + innerboundary + "\r\n"; /* plain text message first. */ headerline += "Content-type: text/plain; charset=iso-8859-1\r\n" "Content-transfer-encoding: 7BIT\r\n\r\n"; ret.insert(ret.end(), headerline.begin(), headerline.end()); ret.insert(ret.end(), message.begin(), message.end()); headerline = "\r\n\r\n--" + innerboundary + "\r\n"; /* Add html message here! */ headerline += "Content-type: text/html; charset=iso-8859-1\r\n" "Content-Transfer-Encoding: base64\r\n\r\n"; ret.insert(ret.end(), headerline.begin(), headerline.end()); ret.insert(ret.end(), messageHTML.begin(), messageHTML.end()); headerline = "\r\n\r\n--" + innerboundary + "--\r\n"; /* end the boundaries if there are no attachments */ if(!attachments.size()) { headerline += "\r\n--" + boundary + "--\r\n"; } else { headerline += "\r\n--" + boundary + "\r\n"; } } ret.insert(ret.end(), headerline.begin(), headerline.end()); headerline.clear(); /* add attachments */ for(vec_pair_char_str_const_iter it1 = attachments.begin(); it1 != attachments.end(); ++ it1) { if(it1->second.length() > 3) { // long enough for an extension std::string type(it1->second.substr(it1->second.length()-4, 4)); if(type == ".gif") { // gif format presumably headerline += "Content-Type: image/gif;\r\n"; } else if(type == ".jpg" || type == "jpeg") { //j-peg format headerline += "Content-Type: image/jpg;\r\n"; } else if(type == ".txt") { // text format headerline += "Content-Type: plain/txt;\r\n"; } else if(type == ".bmp") { // windows bitmap format headerline += "Content-Type: image/bmp;\r\n"; } else if(type == ".htm" || type == "html") { // hypertext format headerline += "Content-Type: plain/htm;\r\n"; } else if(type == ".png") { // portable network graphic format headerline += "Content-Type: image/png;\r\n"; } else if(type == ".exe") { // application headerline += "Content-Type: application/X-exectype-1;\r\n"; } else { // add other types, everything else headerline += "Content-Type: application/X-other-1;\r\n"; } } else { headerline += "Content-Type: application/X-other-1;\r\n"; } headerline += "\tname=\"" + it1->second + "\"\r\n"; headerline += "Content-Transfer-Encoding: base64\r\n"; headerline += "Content-Disposition: attachment; filename=\"" + it1->second + "\"\r\n\r\n"; ret.insert(ret.end(), headerline.begin(), headerline.end()); headerline.clear(); ret.insert(ret.end(), it1->first.begin(), it1->first.end()); /* terminate the message with the boundary + "--" */ if((it1 + 1) == attachments.end()) { headerline += "\r\n\r\n--" + boundary + "--\r\n"; } else { headerline += "\r\n\r\n--" + boundary + "\r\n"; } ret.insert(ret.end(), headerline.begin(), headerline.end()); headerline.clear(); } } else { // just a plain text message ret.insert(ret.end(), message.begin(), message.end()); } /* end the data in the message */ headerline = "\r\n.\r\n"; ret.insert(ret.end(), headerline.begin(), headerline.end()); return ret;}/* add an attachment */bool Mailer::attach(const std::string &filename){ if(!filename.length()) { return false; } /* read attached file */ std::ifstream file(filename.c_str(), std::ios::binary | std::ios::in); if(!file) { return false; } std::vector<char> filedata; char c = file.get(); for( ; file.good(); c=file.get()) { if(file.bad()) { break; } filedata.push_back(c); } filedata = base64encode(filedata); std::string fn(filename); std::string::size_type p = fn.find_last_of('/'); if(p == std::string::npos) { p = fn.find_last_of('\\'); } if(p != std::string::npos) { p += 1; fn = fn.substr(p, fn.length() - p); } attachments.push_back(std::make_pair(filedata, fn)); return true;}/* remove an attachment from the list */bool Mailer::removeattachment(const std::string &filename){ if(!filename.length()) { // don't have an attachment return false; } if(!attachments.size()) { return false; } std::string fn(filename); std::string::size_type p = fn.find_last_of('/'); if(p == std::string::npos) { p = fn.find_last_of('\\'); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?