inlib
1.2.0
|
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved. 00002 // See the file inlib.license for terms. 00003 00004 #ifndef inlib_mail 00005 #define inlib_mail 00006 00007 //inheritance : 00008 #include "inet_socket" 00009 00010 #include "../cstr" 00011 00012 namespace inlib { 00013 namespace net { 00014 00015 class mail : public inet_socket { 00016 public: 00017 mail(std::ostream& a_out,bool a_verbose) 00018 : inet_socket(a_out,a_verbose) 00019 {} 00020 virtual ~mail(){} 00021 protected: 00022 mail(const mail& a_from): inet_socket(a_from){} 00023 mail& operator=(const mail&){return *this;} 00024 public: 00025 static int mail_port() {return 25;} 00026 static int secure_port() {return 587;} 00027 00028 bool send(const std::string& a_host, 00029 const std::string& a_from, 00030 const std::string& a_to, 00031 const std::string& a_subject, 00032 const std::string& a_msg, 00033 int a_port = mail_port()) { 00034 if(!connect(a_host,a_port,10,1)) return false; 00035 00036 {std::string answer; 00037 if(!get_answer(answer)) return false; 00038 if(answer.substr(0,3)!="220") { 00039 m_out << "inlib::net::mail::send : not 220." 00040 << " Answer was " << sout(answer) << "." 00041 << std::endl; 00042 return false; 00043 }} 00044 00045 {std::string cmd = "HELO xxx"; 00046 std::string answer; 00047 if(!send_command(cmd,answer)) return false; 00048 if(answer.substr(0,3)!="250") { 00049 m_out << "inlib::net::mail::send : not 250." 00050 << " Answer was " << sout(answer) << "." 00051 << std::endl; 00052 return false; 00053 }} 00054 00055 {std::string cmd = "MAIL FROM: "+a_from; 00056 std::string answer; 00057 if(!send_command(cmd,answer)) return false;} 00058 00059 {std::string cmd = "RCPT TO: "+a_to; 00060 std::string answer; 00061 if(!send_command(cmd,answer)) return false;} 00062 00063 {std::string cmd = "data"; 00064 std::string answer; 00065 if(!send_command(cmd,answer)) return false; 00066 if(answer.substr(0,3)!="354") { 00067 m_out << "inlib::net::mail::send : not 354." 00068 << " Answer was " << sout(answer) << "." 00069 << std::endl; 00070 return false; 00071 }} 00072 00073 {std::string cmd = "Subject: "+a_subject; 00074 if(!send_command_no_answer(cmd)) return false;} 00075 00076 {std::string cmd = a_msg; 00077 if(!send_command_no_answer(cmd)) return false;} 00078 00079 {std::string cmd = "."; 00080 if(!send_command_no_answer(cmd)) return false;} 00081 00082 {std::string cmd = "quit"; 00083 std::string answer; 00084 if(!send_command(cmd,answer)) return false;} 00085 00086 return true; 00087 } 00088 00089 protected: 00090 static char LF() {return 10;} 00091 static char CR() {return 13;} 00092 00093 bool get_answer(std::string& a_answer) { 00094 char* buffer; 00095 inlib::uint64 length; 00096 if(!fetch_upto_char(CR(),buffer,length)) { 00097 m_out << "inlib::net::mail::fetch_upto_char failed." << std::endl; 00098 a_answer.clear(); 00099 return false; 00100 } 00101 //m_out << "length : " << length << std::endl; 00102 *(buffer+length-1) = 0; 00103 a_answer = buffer; 00104 delete [] buffer; 00105 if(m_verbose) { 00106 m_out << "get_answer : " << sout(a_answer) << std::endl; 00107 } 00108 return true; 00109 } 00110 00111 bool send_command_no_answer(const std::string& a_cmd) { 00112 if(a_cmd.empty()) { 00113 return false; 00114 } 00115 if(m_verbose) { 00116 m_out << "send_command : " << sout(a_cmd) << std::endl; 00117 } 00118 //NOTE : use C str. std::string don't like CR,LF. 00119 char* cmd = inlib::str_new(); 00120 inlib::str_cat(cmd,a_cmd.c_str()); 00121 inlib::str_cat(cmd,CR()); 00122 inlib::str_cat(cmd,LF()); 00123 if(!send_buffer(cmd,::strlen(cmd))) { 00124 m_out << "send_buffer failed." << std::endl; 00125 inlib::str_del(cmd); 00126 return false; 00127 } 00128 inlib::str_del(cmd); 00129 return true; 00130 } 00131 00132 bool send_command(const std::string& a_cmd,std::string& a_answer) { 00133 if(!send_command_no_answer(a_cmd)) { 00134 a_answer.clear(); 00135 return false; 00136 } 00137 return get_answer(a_answer); 00138 } 00139 }; 00140 00141 }} 00142 00143 #endif