| 1 | <?php
 | 
  
    | 2 | ////////////////////////////////////////////////////
 | 
  
    | 3 | // SMTP - PHP SMTP class
 | 
  
    | 4 | //
 | 
  
    | 5 | // Version 1.02
 | 
  
    | 6 | //
 | 
  
    | 7 | // Define an SMTP class that can be used to connect
 | 
  
    | 8 | // and communicate with any SMTP server. It implements
 | 
  
    | 9 | // all the SMTP functions defined in RFC821 except TURN.
 | 
  
    | 10 | //
 | 
  
    | 11 | // Author: Chris Ryan
 | 
  
    | 12 | //
 | 
  
    | 13 | // License: LGPL, see LICENSE
 | 
  
    | 14 | ////////////////////////////////////////////////////
 | 
  
    | 15 | 
 | 
  
    | 16 | /**
 | 
  
    | 17 |  * SMTP is rfc 821 compliant and implements all the rfc 821 SMTP
 | 
  
    | 18 |  * commands except TURN which will always return a not implemented
 | 
  
    | 19 |  * error. SMTP also provides some utility methods for sending mail
 | 
  
    | 20 |  * to an SMTP server.
 | 
  
    | 21 |  * @package PHPMailer
 | 
  
    | 22 |  * @author Chris Ryan
 | 
  
    | 23 |  */
 | 
  
    | 24 | class SMTP
 | 
  
    | 25 | {
 | 
  
    | 26 |     /**
 | 
  
    | 27 |      *  SMTP server port
 | 
  
    | 28 |      *  @var int
 | 
  
    | 29 |      */
 | 
  
    | 30 |     var $SMTP_PORT = 25;
 | 
  
    | 31 |     
 | 
  
    | 32 |     /**
 | 
  
    | 33 |      *  SMTP reply line ending
 | 
  
    | 34 |      *  @var string
 | 
  
    | 35 |      */
 | 
  
    | 36 |     var $CRLF = "\r\n";
 | 
  
    | 37 |     
 | 
  
    | 38 |     /**
 | 
  
    | 39 |      *  Sets whether debugging is turned on
 | 
  
    | 40 |      *  @var bool
 | 
  
    | 41 |      */
 | 
  
    | 42 |     var $do_debug;       # the level of debug to perform
 | 
  
    | 43 | 
 | 
  
    | 44 |     /**#@+
 | 
  
    | 45 |      * @access private
 | 
  
    | 46 |      */
 | 
  
    | 47 |     var $smtp_conn;      # the socket to the server
 | 
  
    | 48 |     var $error;          # error if any on the last call
 | 
  
    | 49 |     var $helo_rply;      # the reply the server sent to us for HELO
 | 
  
    | 50 |     /**#@-*/
 | 
  
    | 51 | 
 | 
  
    | 52 |     /**
 | 
  
    | 53 |      * Initialize the class so that the data is in a known state.
 | 
  
    | 54 |      * @access public
 | 
  
    | 55 |      * @return void
 | 
  
    | 56 |      */
 | 
  
    | 57 |     function SMTP() {
 | 
  
    | 58 |         $this->smtp_conn = 0;
 | 
  
    | 59 |         $this->error = null;
 | 
  
    | 60 |         $this->helo_rply = null;
 | 
  
    | 61 | 
 | 
  
    | 62 |         $this->do_debug = 0;
 | 
  
    | 63 |     }
 | 
  
    | 64 | 
 | 
  
    | 65 |     /*************************************************************
 | 
  
    | 66 |      *                    CONNECTION FUNCTIONS                  *
 | 
  
    | 67 |      ***********************************************************/
 | 
  
    | 68 | 
 | 
  
    | 69 |     /**
 | 
  
    | 70 |      * Connect to the server specified on the port specified.
 | 
  
    | 71 |      * If the port is not specified use the default SMTP_PORT.
 | 
  
    | 72 |      * If tval is specified then a connection will try and be
 | 
  
    | 73 |      * established with the server for that number of seconds.
 | 
  
    | 74 |      * If tval is not specified the default is 30 seconds to
 | 
  
    | 75 |      * try on the connection.
 | 
  
    | 76 |      *
 | 
  
    | 77 |      * SMTP CODE SUCCESS: 220
 | 
  
    | 78 |      * SMTP CODE FAILURE: 421
 | 
  
    | 79 |      * @access public
 | 
  
    | 80 |      * @return bool
 | 
  
    | 81 |      */
 | 
  
    | 82 |     function Connect($host,$port=0,$tval=30) {
 | 
  
    | 83 |         # set the error val to null so there is no confusion
 | 
  
    | 84 |         $this->error = null;
 | 
  
    | 85 | 
 | 
  
    | 86 |         # make sure we are __not__ connected
 | 
  
    | 87 |         if($this->connected()) {
 | 
  
    | 88 |             # ok we are connected! what should we do?
 | 
  
    | 89 |             # for now we will just give an error saying we
 | 
  
    | 90 |             # are already connected
 | 
  
    | 91 |             $this->error =
 | 
  
    | 92 |                 array("error" => "Already connected to a server");
 | 
  
    | 93 |             return false;
 | 
  
    | 94 |         }
 | 
  
    | 95 | 
 | 
  
    | 96 |         if(empty($port)) {
 | 
  
    | 97 |             $port = $this->SMTP_PORT;
 | 
  
    | 98 |         }
 | 
  
    | 99 | 
 | 
  
    | 100 |         #connect to the smtp server
 | 
  
    | 101 |         $this->smtp_conn = fsockopen($host,    # the host of the server
 | 
  
    | 102 |                                      $port,    # the port to use
 | 
  
    | 103 |                                      $errno,   # error number if any
 | 
  
    | 104 |                                      $errstr,  # error message if any
 | 
  
    | 105 |                                      $tval);   # give up after ? secs
 | 
  
    | 106 |         # verify we connected properly
 | 
  
    | 107 |         if(empty($this->smtp_conn)) {
 | 
  
    | 108 |             $this->error = array("error" => "Failed to connect to server",
 | 
  
    | 109 |                                  "errno" => $errno,
 | 
  
    | 110 |                                  "errstr" => $errstr);
 | 
  
    | 111 |             if($this->do_debug >= 1) {
 | 
  
    | 112 |                 echo "SMTP -> ERROR: " . $this->error["error"] .
 | 
  
    | 113 |                          ": $errstr ($errno)" . $this->CRLF;
 | 
  
    | 114 |             }
 | 
  
    | 115 |             return false;
 | 
  
    | 116 |         }
 | 
  
    | 117 | 
 | 
  
    | 118 |         # sometimes the SMTP server takes a little longer to respond
 | 
  
    | 119 |         # so we will give it a longer timeout for the first read
 | 
  
    | 120 |         // Windows still does not have support for this timeout function
 | 
  
    | 121 |         if(substr(PHP_OS, 0, 3) != "WIN")
 | 
  
    | 122 |            socket_set_timeout($this->smtp_conn, $tval, 0);
 | 
  
    | 123 | 
 | 
  
    | 124 |         # get any announcement stuff
 | 
  
    | 125 |         $announce = $this->get_lines();
 | 
  
    | 126 | 
 | 
  
    | 127 |         # set the timeout  of any socket functions at 1/10 of a second
 | 
  
    | 128 |         //if(function_exists("socket_set_timeout"))
 | 
  
    | 129 |         //   socket_set_timeout($this->smtp_conn, 0, 100000);
 | 
  
    | 130 | 
 | 
  
    | 131 |         if($this->do_debug >= 2) {
 | 
  
    | 132 |             echo "SMTP -> FROM SERVER:" . $this->CRLF . $announce;
 | 
  
    | 133 |         }
 | 
  
    | 134 | 
 | 
  
    | 135 |         return true;
 | 
  
    | 136 |     }
 | 
  
    | 137 | 
 | 
  
    | 138 |     /**
 | 
  
    | 139 |      * Performs SMTP authentication.  Must be run after running the
 | 
  
    | 140 |      * Hello() method.  Returns true if successfully authenticated.
 | 
  
    | 141 |      * @access public
 | 
  
    | 142 |      * @return bool
 | 
  
    | 143 |      */
 | 
  
    | 144 |     function Authenticate($username, $password) {
 | 
  
    | 145 |         // Start authentication
 | 
  
    | 146 |         fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF);
 | 
  
    | 147 | 
 | 
  
    | 148 |         $rply = $this->get_lines();
 | 
  
    | 149 |         $code = substr($rply,0,3);
 | 
  
    | 150 | 
 | 
  
    | 151 |         if($code != 334) {
 | 
  
    | 152 |             $this->error =
 | 
  
    | 153 |                 array("error" => "AUTH not accepted from server",
 | 
  
    | 154 |                       "smtp_code" => $code,
 | 
  
    | 155 |                       "smtp_msg" => substr($rply,4));
 | 
  
    | 156 |             if($this->do_debug >= 1) {
 | 
  
    | 157 |                 echo "SMTP -> ERROR: " . $this->error["error"] .
 | 
  
    | 158 |                          ": " . $rply . $this->CRLF;
 | 
  
    | 159 |             }
 | 
  
    | 160 |             return false;
 | 
  
    | 161 |         }
 | 
  
    | 162 | 
 | 
  
    | 163 |         // Send encoded username
 | 
  
    | 164 |         fputs($this->smtp_conn, base64_encode($username) . $this->CRLF);
 | 
  
    | 165 | 
 | 
  
    | 166 |         $rply = $this->get_lines();
 | 
  
    | 167 |         $code = substr($rply,0,3);
 | 
  
    | 168 | 
 | 
  
    | 169 |         if($code != 334) {
 | 
  
    | 170 |             $this->error =
 | 
  
    | 171 |                 array("error" => "Username not accepted from server",
 | 
  
    | 172 |                       "smtp_code" => $code,
 | 
  
    | 173 |                       "smtp_msg" => substr($rply,4));
 | 
  
    | 174 |             if($this->do_debug >= 1) {
 | 
  
    | 175 |                 echo "SMTP -> ERROR: " . $this->error["error"] .
 | 
  
    | 176 |                          ": " . $rply . $this->CRLF;
 | 
  
    | 177 |             }
 | 
  
    | 178 |             return false;
 | 
  
    | 179 |         }
 | 
  
    | 180 | 
 | 
  
    | 181 |         // Send encoded password
 | 
  
    | 182 |         fputs($this->smtp_conn, base64_encode($password) . $this->CRLF);
 | 
  
    | 183 | 
 | 
  
    | 184 |         $rply = $this->get_lines();
 | 
  
    | 185 |         $code = substr($rply,0,3);
 | 
  
    | 186 | 
 | 
  
    | 187 |         if($code != 235) {
 | 
  
    | 188 |             $this->error =
 | 
  
    | 189 |                 array("error" => "Password not accepted from server",
 | 
  
    | 190 |                       "smtp_code" => $code,
 | 
  
    | 191 |                       "smtp_msg" => substr($rply,4));
 | 
  
    | 192 |             if($this->do_debug >= 1) {
 | 
  
    | 193 |                 echo "SMTP -> ERROR: " . $this->error["error"] .
 | 
  
    | 194 |                          ": " . $rply . $this->CRLF;
 | 
  
    | 195 |             }
 | 
  
    | 196 |             return false;
 | 
  
    | 197 |         }
 | 
  
    | 198 | 
 | 
  
    | 199 |         return true;
 | 
  
    | 200 |     }
 | 
  
    | 201 | 
 | 
  
    | 202 |     /**
 | 
  
    | 203 |      * Returns true if connected to a server otherwise false
 | 
  
    | 204 |      * @access private
 | 
  
    | 205 |      * @return bool
 | 
  
    | 206 |      */
 | 
  
    | 207 |     function Connected() {
 | 
  
    | 208 |         if(!empty($this->smtp_conn)) {
 | 
  
    | 209 |             $sock_status = socket_get_status($this->smtp_conn);
 | 
  
    | 210 |             if($sock_status["eof"]) {
 | 
  
    | 211 |                 # hmm this is an odd situation... the socket is
 | 
  
    | 212 |                 # valid but we aren't connected anymore
 | 
  
    | 213 |                 if($this->do_debug >= 1) {
 | 
  
    | 214 |                     echo "SMTP -> NOTICE:" . $this->CRLF .
 | 
  
    | 215 |                          "EOF caught while checking if connected";
 | 
  
    | 216 |                 }
 | 
  
    | 217 |                 $this->Close();
 | 
  
    | 218 |                 return false;
 | 
  
    | 219 |             }
 | 
  
    | 220 |             return true; # everything looks good
 | 
  
    | 221 |         }
 | 
  
    | 222 |         return false;
 | 
  
    | 223 |     }
 | 
  
    | 224 | 
 | 
  
    | 225 |     /**
 | 
  
    | 226 |      * Closes the socket and cleans up the state of the class.
 | 
  
    | 227 |      * It is not considered good to use this function without
 | 
  
    | 228 |      * first trying to use QUIT.
 | 
  
    | 229 |      * @access public
 | 
  
    | 230 |      * @return void
 | 
  
    | 231 |      */
 | 
  
    | 232 |     function Close() {
 | 
  
    | 233 |         $this->error = null; # so there is no confusion
 | 
  
    | 234 |         $this->helo_rply = null;
 | 
  
    | 235 |         if(!empty($this->smtp_conn)) {
 | 
  
    | 236 |             # close the connection and cleanup
 | 
  
    | 237 |             fclose($this->smtp_conn);
 | 
  
    | 238 |             $this->smtp_conn = 0;
 | 
  
    | 239 |         }
 | 
  
    | 240 |     }
 | 
  
    | 241 | 
 | 
  
    | 242 | 
 | 
  
    | 243 |     /***************************************************************
 | 
  
    | 244 |      *                        SMTP COMMANDS                       *
 | 
  
    | 245 |      *************************************************************/
 | 
  
    | 246 | 
 | 
  
    | 247 |     /**
 | 
  
    | 248 |      * Issues a data command and sends the msg_data to the server
 | 
  
    | 249 |      * finializing the mail transaction. $msg_data is the message
 | 
  
    | 250 |      * that is to be send with the headers. Each header needs to be
 | 
  
    | 251 |      * on a single line followed by a <CRLF> with the message headers
 | 
  
    | 252 |      * and the message body being seperated by and additional <CRLF>.
 | 
  
    | 253 |      *
 | 
  
    | 254 |      * Implements rfc 821: DATA <CRLF>
 | 
  
    | 255 |      *
 | 
  
    | 256 |      * SMTP CODE INTERMEDIATE: 354
 | 
  
    | 257 |      *     [data]
 | 
  
    | 258 |      *     <CRLF>.<CRLF>
 | 
  
    | 259 |      *     SMTP CODE SUCCESS: 250
 | 
  
    | 260 |      *     SMTP CODE FAILURE: 552,554,451,452
 | 
  
    | 261 |      * SMTP CODE FAILURE: 451,554
 | 
  
    | 262 |      * SMTP CODE ERROR  : 500,501,503,421
 | 
  
    | 263 |      * @access public
 | 
  
    | 264 |      * @return bool
 | 
  
    | 265 |      */
 | 
  
    | 266 |     function Data($msg_data) {
 | 
  
    | 267 |         $this->error = null; # so no confusion is caused
 | 
  
    | 268 | 
 | 
  
    | 269 |         if(!$this->connected()) {
 | 
  
    | 270 |             $this->error = array(
 | 
  
    | 271 |                     "error" => "Called Data() without being connected");
 | 
  
    | 272 |             return false;
 | 
  
    | 273 |         }
 | 
  
    | 274 | 
 | 
  
    | 275 |         fputs($this->smtp_conn,"DATA" . $this->CRLF);
 | 
  
    | 276 | 
 | 
  
    | 277 |         $rply = $this->get_lines();
 | 
  
    | 278 |         $code = substr($rply,0,3);
 | 
  
    | 279 | 
 | 
  
    | 280 |         if($this->do_debug >= 2) {
 | 
  
    | 281 |             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
 | 
  
    | 282 |         }
 | 
  
    | 283 | 
 | 
  
    | 284 |         if($code != 354) {
 | 
  
    | 285 |             $this->error =
 | 
  
    | 286 |                 array("error" => "DATA command not accepted from server",
 | 
  
    | 287 |                       "smtp_code" => $code,
 | 
  
    | 288 |                       "smtp_msg" => substr($rply,4));
 | 
  
    | 289 |             if($this->do_debug >= 1) {
 | 
  
    | 290 |                 echo "SMTP -> ERROR: " . $this->error["error"] .
 | 
  
    | 291 |                          ": " . $rply . $this->CRLF;
 | 
  
    | 292 |             }
 | 
  
    | 293 |             return false;
 | 
  
    | 294 |         }
 | 
  
    | 295 | 
 | 
  
    | 296 |         # the server is ready to accept data!
 | 
  
    | 297 |         # according to rfc 821 we should not send more than 1000
 | 
  
    | 298 |         # including the CRLF
 | 
  
    | 299 |         # characters on a single line so we will break the data up
 | 
  
    | 300 |         # into lines by \r and/or \n then if needed we will break
 | 
  
    | 301 |         # each of those into smaller lines to fit within the limit.
 | 
  
    | 302 |         # in addition we will be looking for lines that start with
 | 
  
    | 303 |         # a period '.' and append and additional period '.' to that
 | 
  
    | 304 |         # line. NOTE: this does not count towards are limit.
 | 
  
    | 305 | 
 | 
  
    | 306 |         # normalize the line breaks so we know the explode works
 | 
  
    | 307 |         $msg_data = str_replace("\r\n","\n",$msg_data);
 | 
  
    | 308 |         $msg_data = str_replace("\r","\n",$msg_data);
 | 
  
    | 309 |         $lines = explode("\n",$msg_data);
 | 
  
    | 310 | 
 | 
  
    | 311 |         # we need to find a good way to determine is headers are
 | 
  
    | 312 |         # in the msg_data or if it is a straight msg body
 | 
  
    | 313 |         # currently I'm assuming rfc 822 definitions of msg headers
 | 
  
    | 314 |         # and if the first field of the first line (':' sperated)
 | 
  
    | 315 |         # does not contain a space then it _should_ be a header
 | 
  
    | 316 |         # and we can process all lines before a blank "" line as
 | 
  
    | 317 |         # headers.
 | 
  
    | 318 |         $field = substr($lines[0],0,strpos($lines[0],":"));
 | 
  
    | 319 |         $in_headers = false;
 | 
  
    | 320 |         if(!empty($field) && !strstr($field," ")) {
 | 
  
    | 321 |             $in_headers = true;
 | 
  
    | 322 |         }
 | 
  
    | 323 | 
 | 
  
    | 324 |         $max_line_length = 998; # used below; set here for ease in change
 | 
  
    | 325 | 
 | 
  
    | 326 |         while(list(,$line) = @each($lines)) {
 | 
  
    | 327 |             $lines_out = null;
 | 
  
    | 328 |             if($line == "" && $in_headers) {
 | 
  
    | 329 |                 $in_headers = false;
 | 
  
    | 330 |             }
 | 
  
    | 331 |             # ok we need to break this line up into several
 | 
  
    | 332 |             # smaller lines
 | 
  
    | 333 |             while(strlen($line) > $max_line_length) {
 | 
  
    | 334 |                 $pos = strrpos(substr($line,0,$max_line_length)," ");
 | 
  
    | 335 | 
 | 
  
    | 336 |                 # Patch to fix DOS attack
 | 
  
    | 337 |                 if(!$pos) {
 | 
  
    | 338 |                     $pos = $max_line_length - 1;
 | 
  
    | 339 |                 }
 | 
  
    | 340 | 
 | 
  
    | 341 |                 $lines_out[] = substr($line,0,$pos);
 | 
  
    | 342 |                 $line = substr($line,$pos + 1);
 | 
  
    | 343 |                 # if we are processing headers we need to
 | 
  
    | 344 |                 # add a LWSP-char to the front of the new line
 | 
  
    | 345 |                 # rfc 822 on long msg headers
 | 
  
    | 346 |                 if($in_headers) {
 | 
  
    | 347 |                     $line = "\t" . $line;
 | 
  
    | 348 |                 }
 | 
  
    | 349 |             }
 | 
  
    | 350 |             $lines_out[] = $line;
 | 
  
    | 351 | 
 | 
  
    | 352 |             # now send the lines to the server
 | 
  
    | 353 |             while(list(,$line_out) = @each($lines_out)) {
 | 
  
    | 354 |                 if(strlen($line_out) > 0)
 | 
  
    | 355 |                 {
 | 
  
    | 356 |                     if(substr($line_out, 0, 1) == ".") {
 | 
  
    | 357 |                         $line_out = "." . $line_out;
 | 
  
    | 358 |                     }
 | 
  
    | 359 |                 }
 | 
  
    | 360 |                 fputs($this->smtp_conn,$line_out . $this->CRLF);
 | 
  
    | 361 |             }
 | 
  
    | 362 |         }
 | 
  
    | 363 | 
 | 
  
    | 364 |         # ok all the message data has been sent so lets get this
 | 
  
    | 365 |         # over with aleady
 | 
  
    | 366 |         fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF);
 | 
  
    | 367 | 
 | 
  
    | 368 |         $rply = $this->get_lines();
 | 
  
    | 369 |         $code = substr($rply,0,3);
 | 
  
    | 370 | 
 | 
  
    | 371 |         if($this->do_debug >= 2) {
 | 
  
    | 372 |             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
 | 
  
    | 373 |         }
 | 
  
    | 374 | 
 | 
  
    | 375 |         if($code != 250) {
 | 
  
    | 376 |             $this->error =
 | 
  
    | 377 |                 array("error" => "DATA not accepted from server",
 | 
  
    | 378 |                       "smtp_code" => $code,
 | 
  
    | 379 |                       "smtp_msg" => substr($rply,4));
 | 
  
    | 380 |             if($this->do_debug >= 1) {
 | 
  
    | 381 |                 echo "SMTP -> ERROR: " . $this->error["error"] .
 | 
  
    | 382 |                          ": " . $rply . $this->CRLF;
 | 
  
    | 383 |             }
 | 
  
    | 384 |             return false;
 | 
  
    | 385 |         }
 | 
  
    | 386 |         return true;
 | 
  
    | 387 |     }
 | 
  
    | 388 | 
 | 
  
    | 389 |     /**
 | 
  
    | 390 |      * Expand takes the name and asks the server to list all the
 | 
  
    | 391 |      * people who are members of the _list_. Expand will return
 | 
  
    | 392 |      * back and array of the result or false if an error occurs.
 | 
  
    | 393 |      * Each value in the array returned has the format of:
 | 
  
    | 394 |      *     [ <full-name> <sp> ] <path>
 | 
  
    | 395 |      * The definition of <path> is defined in rfc 821
 | 
  
    | 396 |      *
 | 
  
    | 397 |      * Implements rfc 821: EXPN <SP> <string> <CRLF>
 | 
  
    | 398 |      *
 | 
  
    | 399 |      * SMTP CODE SUCCESS: 250
 | 
  
    | 400 |      * SMTP CODE FAILURE: 550
 | 
  
    | 401 |      * SMTP CODE ERROR  : 500,501,502,504,421
 | 
  
    | 402 |      * @access public
 | 
  
    | 403 |      * @return string array
 | 
  
    | 404 |      */
 | 
  
    | 405 |     function Expand($name) {
 | 
  
    | 406 |         $this->error = null; # so no confusion is caused
 | 
  
    | 407 | 
 | 
  
    | 408 |         if(!$this->connected()) {
 | 
  
    | 409 |             $this->error = array(
 | 
  
    | 410 |                     "error" => "Called Expand() without being connected");
 | 
  
    | 411 |             return false;
 | 
  
    | 412 |         }
 | 
  
    | 413 | 
 | 
  
    | 414 |         fputs($this->smtp_conn,"EXPN " . $name . $this->CRLF);
 | 
  
    | 415 | 
 | 
  
    | 416 |         $rply = $this->get_lines();
 | 
  
    | 417 |         $code = substr($rply,0,3);
 | 
  
    | 418 | 
 | 
  
    | 419 |         if($this->do_debug >= 2) {
 | 
  
    | 420 |             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
 | 
  
    | 421 |         }
 | 
  
    | 422 | 
 | 
  
    | 423 |         if($code != 250) {
 | 
  
    | 424 |             $this->error =
 | 
  
    | 425 |                 array("error" => "EXPN not accepted from server",
 | 
  
    | 426 |                       "smtp_code" => $code,
 | 
  
    | 427 |                       "smtp_msg" => substr($rply,4));
 | 
  
    | 428 |             if($this->do_debug >= 1) {
 | 
  
    | 429 |                 echo "SMTP -> ERROR: " . $this->error["error"] .
 | 
  
    | 430 |                          ": " . $rply . $this->CRLF;
 | 
  
    | 431 |             }
 | 
  
    | 432 |             return false;
 | 
  
    | 433 |         }
 | 
  
    | 434 | 
 | 
  
    | 435 |         # parse the reply and place in our array to return to user
 | 
  
    | 436 |         $entries = explode($this->CRLF,$rply);
 | 
  
    | 437 |         while(list(,$l) = @each($entries)) {
 | 
  
    | 438 |             $list[] = substr($l,4);
 | 
  
    | 439 |         }
 | 
  
    | 440 | 
 | 
  
    | 441 |         return $list;
 | 
  
    | 442 |     }
 | 
  
    | 443 | 
 | 
  
    | 444 |     /**
 | 
  
    | 445 |      * Sends the HELO command to the smtp server.
 | 
  
    | 446 |      * This makes sure that we and the server are in
 | 
  
    | 447 |      * the same known state.
 | 
  
    | 448 |      *
 | 
  
    | 449 |      * Implements from rfc 821: HELO <SP> <domain> <CRLF>
 | 
  
    | 450 |      *
 | 
  
    | 451 |      * SMTP CODE SUCCESS: 250
 | 
  
    | 452 |      * SMTP CODE ERROR  : 500, 501, 504, 421
 | 
  
    | 453 |      * @access public
 | 
  
    | 454 |      * @return bool
 | 
  
    | 455 |      */
 | 
  
    | 456 |     function Hello($host="") {
 | 
  
    | 457 |         $this->error = null; # so no confusion is caused
 | 
  
    | 458 | 
 | 
  
    | 459 |         if(!$this->connected()) {
 | 
  
    | 460 |             $this->error = array(
 | 
  
    | 461 |                     "error" => "Called Hello() without being connected");
 | 
  
    | 462 |             return false;
 | 
  
    | 463 |         }
 | 
  
    | 464 | 
 | 
  
    | 465 |         # if a hostname for the HELO wasn't specified determine
 | 
  
    | 466 |         # a suitable one to send
 | 
  
    | 467 |         if(empty($host)) {
 | 
  
    | 468 |             # we need to determine some sort of appopiate default
 | 
  
    | 469 |             # to send to the server
 | 
  
    | 470 |             $host = "localhost";
 | 
  
    | 471 |         }
 | 
  
    | 472 | 
 | 
  
    | 473 |         // Send extended hello first (RFC 2821)
 | 
  
    | 474 |         if(!$this->SendHello("EHLO", $host))
 | 
  
    | 475 |         {
 | 
  
    | 476 |             if(!$this->SendHello("HELO", $host))
 | 
  
    | 477 |                 return false;
 | 
  
    | 478 |         }
 | 
  
    | 479 | 
 | 
  
    | 480 |         return true;
 | 
  
    | 481 |     }
 | 
  
    | 482 | 
 | 
  
    | 483 |     /**
 | 
  
    | 484 |      * Sends a HELO/EHLO command.
 | 
  
    | 485 |      * @access private
 | 
  
    | 486 |      * @return bool
 | 
  
    | 487 |      */
 | 
  
    | 488 |     function SendHello($hello, $host) {
 | 
  
    | 489 |         fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF);
 | 
  
    | 490 | 
 | 
  
    | 491 |         $rply = $this->get_lines();
 | 
  
    | 492 |         $code = substr($rply,0,3);
 | 
  
    | 493 | 
 | 
  
    | 494 |         if($this->do_debug >= 2) {
 | 
  
    | 495 |             echo "SMTP -> FROM SERVER: " . $this->CRLF . $rply;
 | 
  
    | 496 |         }
 | 
  
    | 497 | 
 | 
  
    | 498 |         if($code != 250) {
 | 
  
    | 499 |             $this->error =
 | 
  
    | 500 |                 array("error" => $hello . " not accepted from server",
 | 
  
    | 501 |                       "smtp_code" => $code,
 | 
  
    | 502 |                       "smtp_msg" => substr($rply,4));
 | 
  
    | 503 |             if($this->do_debug >= 1) {
 | 
  
    | 504 |                 echo "SMTP -> ERROR: " . $this->error["error"] .
 | 
  
    | 505 |                          ": " . $rply . $this->CRLF;
 | 
  
    | 506 |             }
 | 
  
    | 507 |             return false;
 | 
  
    | 508 |         }
 | 
  
    | 509 | 
 | 
  
    | 510 |         $this->helo_rply = $rply;
 | 
  
    | 511 |         
 | 
  
    | 512 |         return true;
 | 
  
    | 513 |     }
 | 
  
    | 514 | 
 | 
  
    | 515 |     /**
 | 
  
    | 516 |      * Gets help information on the keyword specified. If the keyword
 | 
  
    | 517 |      * is not specified then returns generic help, ussually contianing
 | 
  
    | 518 |      * A list of keywords that help is available on. This function
 | 
  
    | 519 |      * returns the results back to the user. It is up to the user to
 | 
  
    | 520 |      * handle the returned data. If an error occurs then false is
 | 
  
    | 521 |      * returned with $this->error set appropiately.
 | 
  
    | 522 |      *
 | 
  
    | 523 |      * Implements rfc 821: HELP [ <SP> <string> ] <CRLF>
 | 
  
    | 524 |      *
 | 
  
    | 525 |      * SMTP CODE SUCCESS: 211,214
 | 
  
    | 526 |      * SMTP CODE ERROR  : 500,501,502,504,421
 | 
  
    | 527 |      * @access public
 | 
  
    | 528 |      * @return string
 | 
  
    | 529 |      */
 | 
  
    | 530 |     function Help($keyword="") {
 | 
  
    | 531 |         $this->error = null; # to avoid confusion
 | 
  
    | 532 | 
 | 
  
    | 533 |         if(!$this->connected()) {
 | 
  
    | 534 |             $this->error = array(
 | 
  
    | 535 |                     "error" => "Called Help() without being connected");
 | 
  
    | 536 |             return false;
 | 
  
    | 537 |         }
 | 
  
    | 538 | 
 | 
  
    | 539 |         $extra = "";
 | 
  
    | 540 |         if(!empty($keyword)) {
 | 
  
    | 541 |             $extra = " " . $keyword;
 | 
  
    | 542 |         }
 | 
  
    | 543 | 
 | 
  
    | 544 |         fputs($this->smtp_conn,"HELP" . $extra . $this->CRLF);
 | 
  
    | 545 | 
 | 
  
    | 546 |         $rply = $this->get_lines();
 | 
  
    | 547 |         $code = substr($rply,0,3);
 | 
  
    | 548 | 
 | 
  
    | 549 |         if($this->do_debug >= 2) {
 | 
  
    | 550 |             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
 | 
  
    | 551 |         }
 | 
  
    | 552 | 
 | 
  
    | 553 |         if($code != 211 && $code != 214) {
 | 
  
    | 554 |             $this->error =
 | 
  
    | 555 |                 array("error" => "HELP not accepted from server",
 | 
  
    | 556 |                       "smtp_code" => $code,
 | 
  
    | 557 |                       "smtp_msg" => substr($rply,4));
 | 
  
    | 558 |             if($this->do_debug >= 1) {
 | 
  
    | 559 |                 echo "SMTP -> ERROR: " . $this->error["error"] .
 | 
  
    | 560 |                          ": " . $rply . $this->CRLF;
 | 
  
    | 561 |             }
 | 
  
    | 562 |             return false;
 | 
  
    | 563 |         }
 | 
  
    | 564 | 
 | 
  
    | 565 |         return $rply;
 | 
  
    | 566 |     }
 | 
  
    | 567 | 
 | 
  
    | 568 |     /**
 | 
  
    | 569 |      * Starts a mail transaction from the email address specified in
 | 
  
    | 570 |      * $from. Returns true if successful or false otherwise. If True
 | 
  
    | 571 |      * the mail transaction is started and then one or more Recipient
 | 
  
    | 572 |      * commands may be called followed by a Data command.
 | 
  
    | 573 |      *
 | 
  
    | 574 |      * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>
 | 
  
    | 575 |      *
 | 
  
    | 576 |      * SMTP CODE SUCCESS: 250
 | 
  
    | 577 |      * SMTP CODE SUCCESS: 552,451,452
 | 
  
    | 578 |      * SMTP CODE SUCCESS: 500,501,421
 | 
  
    | 579 |      * @access public
 | 
  
    | 580 |      * @return bool
 | 
  
    | 581 |      */
 | 
  
    | 582 |     function Mail($from) {
 | 
  
    | 583 |         $this->error = null; # so no confusion is caused
 | 
  
    | 584 | 
 | 
  
    | 585 |         if(!$this->connected()) {
 | 
  
    | 586 |             $this->error = array(
 | 
  
    | 587 |                     "error" => "Called Mail() without being connected");
 | 
  
    | 588 |             return false;
 | 
  
    | 589 |         }
 | 
  
    | 590 | 
 | 
  
    | 591 |         fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $this->CRLF);
 | 
  
    | 592 | 
 | 
  
    | 593 |         $rply = $this->get_lines();
 | 
  
    | 594 |         $code = substr($rply,0,3);
 | 
  
    | 595 | 
 | 
  
    | 596 |         if($this->do_debug >= 2) {
 | 
  
    | 597 |             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
 | 
  
    | 598 |         }
 | 
  
    | 599 | 
 | 
  
    | 600 |         if($code != 250) {
 | 
  
    | 601 |             $this->error =
 | 
  
    | 602 |                 array("error" => "MAIL not accepted from server",
 | 
  
    | 603 |                       "smtp_code" => $code,
 | 
  
    | 604 |                       "smtp_msg" => substr($rply,4));
 | 
  
    | 605 |             if($this->do_debug >= 1) {
 | 
  
    | 606 |                 echo "SMTP -> ERROR: " . $this->error["error"] .
 | 
  
    | 607 |                          ": " . $rply . $this->CRLF;
 | 
  
    | 608 |             }
 | 
  
    | 609 |             return false;
 | 
  
    | 610 |         }
 | 
  
    | 611 |         return true;
 | 
  
    | 612 |     }
 | 
  
    | 613 | 
 | 
  
    | 614 |     /**
 | 
  
    | 615 |      * Sends the command NOOP to the SMTP server.
 | 
  
    | 616 |      *
 | 
  
    | 617 |      * Implements from rfc 821: NOOP <CRLF>
 | 
  
    | 618 |      *
 | 
  
    | 619 |      * SMTP CODE SUCCESS: 250
 | 
  
    | 620 |      * SMTP CODE ERROR  : 500, 421
 | 
  
    | 621 |      * @access public
 | 
  
    | 622 |      * @return bool
 | 
  
    | 623 |      */
 | 
  
    | 624 |     function Noop() {
 | 
  
    | 625 |         $this->error = null; # so no confusion is caused
 | 
  
    | 626 | 
 | 
  
    | 627 |         if(!$this->connected()) {
 | 
  
    | 628 |             $this->error = array(
 | 
  
    | 629 |                     "error" => "Called Noop() without being connected");
 | 
  
    | 630 |             return false;
 | 
  
    | 631 |         }
 | 
  
    | 632 | 
 | 
  
    | 633 |         fputs($this->smtp_conn,"NOOP" . $this->CRLF);
 | 
  
    | 634 | 
 | 
  
    | 635 |         $rply = $this->get_lines();
 | 
  
    | 636 |         $code = substr($rply,0,3);
 | 
  
    | 637 | 
 | 
  
    | 638 |         if($this->do_debug >= 2) {
 | 
  
    | 639 |             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
 | 
  
    | 640 |         }
 | 
  
    | 641 | 
 | 
  
    | 642 |         if($code != 250) {
 | 
  
    | 643 |             $this->error =
 | 
  
    | 644 |                 array("error" => "NOOP not accepted from server",
 | 
  
    | 645 |                       "smtp_code" => $code,
 | 
  
    | 646 |                       "smtp_msg" => substr($rply,4));
 | 
  
    | 647 |             if($this->do_debug >= 1) {
 | 
  
    | 648 |                 echo "SMTP -> ERROR: " . $this->error["error"] .
 | 
  
    | 649 |                          ": " . $rply . $this->CRLF;
 | 
  
    | 650 |             }
 | 
  
    | 651 |             return false;
 | 
  
    | 652 |         }
 | 
  
    | 653 |         return true;
 | 
  
    | 654 |     }
 | 
  
    | 655 | 
 | 
  
    | 656 |     /**
 | 
  
    | 657 |      * Sends the quit command to the server and then closes the socket
 | 
  
    | 658 |      * if there is no error or the $close_on_error argument is true.
 | 
  
    | 659 |      *
 | 
  
    | 660 |      * Implements from rfc 821: QUIT <CRLF>
 | 
  
    | 661 |      *
 | 
  
    | 662 |      * SMTP CODE SUCCESS: 221
 | 
  
    | 663 |      * SMTP CODE ERROR  : 500
 | 
  
    | 664 |      * @access public
 | 
  
    | 665 |      * @return bool
 | 
  
    | 666 |      */
 | 
  
    | 667 |     function Quit($close_on_error=true) {
 | 
  
    | 668 |         $this->error = null; # so there is no confusion
 | 
  
    | 669 | 
 | 
  
    | 670 |         if(!$this->connected()) {
 | 
  
    | 671 |             $this->error = array(
 | 
  
    | 672 |                     "error" => "Called Quit() without being connected");
 | 
  
    | 673 |             return false;
 | 
  
    | 674 |         }
 | 
  
    | 675 | 
 | 
  
    | 676 |         # send the quit command to the server
 | 
  
    | 677 |         fputs($this->smtp_conn,"quit" . $this->CRLF);
 | 
  
    | 678 | 
 | 
  
    | 679 |         # get any good-bye messages
 | 
  
    | 680 |         $byemsg = $this->get_lines();
 | 
  
    | 681 | 
 | 
  
    | 682 |         if($this->do_debug >= 2) {
 | 
  
    | 683 |             echo "SMTP -> FROM SERVER:" . $this->CRLF . $byemsg;
 | 
  
    | 684 |         }
 | 
  
    | 685 | 
 | 
  
    | 686 |         $rval = true;
 | 
  
    | 687 |         $e = null;
 | 
  
    | 688 | 
 | 
  
    | 689 |         $code = substr($byemsg,0,3);
 | 
  
    | 690 |         if($code != 221) {
 | 
  
    | 691 |             # use e as a tmp var cause Close will overwrite $this->error
 | 
  
    | 692 |             $e = array("error" => "SMTP server rejected quit command",
 | 
  
    | 693 |                        "smtp_code" => $code,
 | 
  
    | 694 |                        "smtp_rply" => substr($byemsg,4));
 | 
  
    | 695 |             $rval = false;
 | 
  
    | 696 |             if($this->do_debug >= 1) {
 | 
  
    | 697 |                 echo "SMTP -> ERROR: " . $e["error"] . ": " .
 | 
  
    | 698 |                          $byemsg . $this->CRLF;
 | 
  
    | 699 |             }
 | 
  
    | 700 |         }
 | 
  
    | 701 | 
 | 
  
    | 702 |         if(empty($e) || $close_on_error) {
 | 
  
    | 703 |             $this->Close();
 | 
  
    | 704 |         }
 | 
  
    | 705 | 
 | 
  
    | 706 |         return $rval;
 | 
  
    | 707 |     }
 | 
  
    | 708 | 
 | 
  
    | 709 |     /**
 | 
  
    | 710 |      * Sends the command RCPT to the SMTP server with the TO: argument of $to.
 | 
  
    | 711 |      * Returns true if the recipient was accepted false if it was rejected.
 | 
  
    | 712 |      *
 | 
  
    | 713 |      * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
 | 
  
    | 714 |      *
 | 
  
    | 715 |      * SMTP CODE SUCCESS: 250,251
 | 
  
    | 716 |      * SMTP CODE FAILURE: 550,551,552,553,450,451,452
 | 
  
    | 717 |      * SMTP CODE ERROR  : 500,501,503,421
 | 
  
    | 718 |      * @access public
 | 
  
    | 719 |      * @return bool
 | 
  
    | 720 |      */
 | 
  
    | 721 |     function Recipient($to) {
 | 
  
    | 722 |         $this->error = null; # so no confusion is caused
 | 
  
    | 723 | 
 | 
  
    | 724 |         if(!$this->connected()) {
 | 
  
    | 725 |             $this->error = array(
 | 
  
    | 726 |                     "error" => "Called Recipient() without being connected");
 | 
  
    | 727 |             return false;
 | 
  
    | 728 |         }
 | 
  
    | 729 | 
 | 
  
    | 730 |         fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF);
 | 
  
    | 731 | 
 | 
  
    | 732 |         $rply = $this->get_lines();
 | 
  
    | 733 |         $code = substr($rply,0,3);
 | 
  
    | 734 | 
 | 
  
    | 735 |         if($this->do_debug >= 2) {
 | 
  
    | 736 |             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
 | 
  
    | 737 |         }
 | 
  
    | 738 | 
 | 
  
    | 739 |         if($code != 250 && $code != 251) {
 | 
  
    | 740 |             $this->error =
 | 
  
    | 741 |                 array("error" => "RCPT not accepted from server",
 | 
  
    | 742 |                       "smtp_code" => $code,
 | 
  
    | 743 |                       "smtp_msg" => substr($rply,4));
 | 
  
    | 744 |             if($this->do_debug >= 1) {
 | 
  
    | 745 |                 echo "SMTP -> ERROR: " . $this->error["error"] .
 | 
  
    | 746 |                          ": " . $rply . $this->CRLF;
 | 
  
    | 747 |             }
 | 
  
    | 748 |             return false;
 | 
  
    | 749 |         }
 | 
  
    | 750 |         return true;
 | 
  
    | 751 |     }
 | 
  
    | 752 | 
 | 
  
    | 753 |     /**
 | 
  
    | 754 |      * Sends the RSET command to abort and transaction that is
 | 
  
    | 755 |      * currently in progress. Returns true if successful false
 | 
  
    | 756 |      * otherwise.
 | 
  
    | 757 |      *
 | 
  
    | 758 |      * Implements rfc 821: RSET <CRLF>
 | 
  
    | 759 |      *
 | 
  
    | 760 |      * SMTP CODE SUCCESS: 250
 | 
  
    | 761 |      * SMTP CODE ERROR  : 500,501,504,421
 | 
  
    | 762 |      * @access public
 | 
  
    | 763 |      * @return bool
 | 
  
    | 764 |      */
 | 
  
    | 765 |     function Reset() {
 | 
  
    | 766 |         $this->error = null; # so no confusion is caused
 | 
  
    | 767 | 
 | 
  
    | 768 |         if(!$this->connected()) {
 | 
  
    | 769 |             $this->error = array(
 | 
  
    | 770 |                     "error" => "Called Reset() without being connected");
 | 
  
    | 771 |             return false;
 | 
  
    | 772 |         }
 | 
  
    | 773 | 
 | 
  
    | 774 |         fputs($this->smtp_conn,"RSET" . $this->CRLF);
 | 
  
    | 775 | 
 | 
  
    | 776 |         $rply = $this->get_lines();
 | 
  
    | 777 |         $code = substr($rply,0,3);
 | 
  
    | 778 | 
 | 
  
    | 779 |         if($this->do_debug >= 2) {
 | 
  
    | 780 |             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
 | 
  
    | 781 |         }
 | 
  
    | 782 | 
 | 
  
    | 783 |         if($code != 250) {
 | 
  
    | 784 |             $this->error =
 | 
  
    | 785 |                 array("error" => "RSET failed",
 | 
  
    | 786 |                       "smtp_code" => $code,
 | 
  
    | 787 |                       "smtp_msg" => substr($rply,4));
 | 
  
    | 788 |             if($this->do_debug >= 1) {
 | 
  
    | 789 |                 echo "SMTP -> ERROR: " . $this->error["error"] .
 | 
  
    | 790 |                          ": " . $rply . $this->CRLF;
 | 
  
    | 791 |             }
 | 
  
    | 792 |             return false;
 | 
  
    | 793 |         }
 | 
  
    | 794 | 
 | 
  
    | 795 |         return true;
 | 
  
    | 796 |     }
 | 
  
    | 797 | 
 | 
  
    | 798 |     /**
 | 
  
    | 799 |      * Starts a mail transaction from the email address specified in
 | 
  
    | 800 |      * $from. Returns true if successful or false otherwise. If True
 | 
  
    | 801 |      * the mail transaction is started and then one or more Recipient
 | 
  
    | 802 |      * commands may be called followed by a Data command. This command
 | 
  
    | 803 |      * will send the message to the users terminal if they are logged
 | 
  
    | 804 |      * in.
 | 
  
    | 805 |      *
 | 
  
    | 806 |      * Implements rfc 821: SEND <SP> FROM:<reverse-path> <CRLF>
 | 
  
    | 807 |      *
 | 
  
    | 808 |      * SMTP CODE SUCCESS: 250
 | 
  
    | 809 |      * SMTP CODE SUCCESS: 552,451,452
 | 
  
    | 810 |      * SMTP CODE SUCCESS: 500,501,502,421
 | 
  
    | 811 |      * @access public
 | 
  
    | 812 |      * @return bool
 | 
  
    | 813 |      */
 | 
  
    | 814 |     function Send($from) {
 | 
  
    | 815 |         $this->error = null; # so no confusion is caused
 | 
  
    | 816 | 
 | 
  
    | 817 |         if(!$this->connected()) {
 | 
  
    | 818 |             $this->error = array(
 | 
  
    | 819 |                     "error" => "Called Send() without being connected");
 | 
  
    | 820 |             return false;
 | 
  
    | 821 |         }
 | 
  
    | 822 | 
 | 
  
    | 823 |         fputs($this->smtp_conn,"SEND FROM:" . $from . $this->CRLF);
 | 
  
    | 824 | 
 | 
  
    | 825 |         $rply = $this->get_lines();
 | 
  
    | 826 |         $code = substr($rply,0,3);
 | 
  
    | 827 | 
 | 
  
    | 828 |         if($this->do_debug >= 2) {
 | 
  
    | 829 |             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
 | 
  
    | 830 |         }
 | 
  
    | 831 | 
 | 
  
    | 832 |         if($code != 250) {
 | 
  
    | 833 |             $this->error =
 | 
  
    | 834 |                 array("error" => "SEND not accepted from server",
 | 
  
    | 835 |                       "smtp_code" => $code,
 | 
  
    | 836 |                       "smtp_msg" => substr($rply,4));
 | 
  
    | 837 |             if($this->do_debug >= 1) {
 | 
  
    | 838 |                 echo "SMTP -> ERROR: " . $this->error["error"] .
 | 
  
    | 839 |                          ": " . $rply . $this->CRLF;
 | 
  
    | 840 |             }
 | 
  
    | 841 |             return false;
 | 
  
    | 842 |         }
 | 
  
    | 843 |         return true;
 | 
  
    | 844 |     }
 | 
  
    | 845 | 
 | 
  
    | 846 |     /**
 | 
  
    | 847 |      * Starts a mail transaction from the email address specified in
 | 
  
    | 848 |      * $from. Returns true if successful or false otherwise. If True
 | 
  
    | 849 |      * the mail transaction is started and then one or more Recipient
 | 
  
    | 850 |      * commands may be called followed by a Data command. This command
 | 
  
    | 851 |      * will send the message to the users terminal if they are logged
 | 
  
    | 852 |      * in and send them an email.
 | 
  
    | 853 |      *
 | 
  
    | 854 |      * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>
 | 
  
    | 855 |      *
 | 
  
    | 856 |      * SMTP CODE SUCCESS: 250
 | 
  
    | 857 |      * SMTP CODE SUCCESS: 552,451,452
 | 
  
    | 858 |      * SMTP CODE SUCCESS: 500,501,502,421
 | 
  
    | 859 |      * @access public
 | 
  
    | 860 |      * @return bool
 | 
  
    | 861 |      */
 | 
  
    | 862 |     function SendAndMail($from) {
 | 
  
    | 863 |         $this->error = null; # so no confusion is caused
 | 
  
    | 864 | 
 | 
  
    | 865 |         if(!$this->connected()) {
 | 
  
    | 866 |             $this->error = array(
 | 
  
    | 867 |                 "error" => "Called SendAndMail() without being connected");
 | 
  
    | 868 |             return false;
 | 
  
    | 869 |         }
 | 
  
    | 870 | 
 | 
  
    | 871 |         fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF);
 | 
  
    | 872 | 
 | 
  
    | 873 |         $rply = $this->get_lines();
 | 
  
    | 874 |         $code = substr($rply,0,3);
 | 
  
    | 875 | 
 | 
  
    | 876 |         if($this->do_debug >= 2) {
 | 
  
    | 877 |             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
 | 
  
    | 878 |         }
 | 
  
    | 879 | 
 | 
  
    | 880 |         if($code != 250) {
 | 
  
    | 881 |             $this->error =
 | 
  
    | 882 |                 array("error" => "SAML not accepted from server",
 | 
  
    | 883 |                       "smtp_code" => $code,
 | 
  
    | 884 |                       "smtp_msg" => substr($rply,4));
 | 
  
    | 885 |             if($this->do_debug >= 1) {
 | 
  
    | 886 |                 echo "SMTP -> ERROR: " . $this->error["error"] .
 | 
  
    | 887 |                          ": " . $rply . $this->CRLF;
 | 
  
    | 888 |             }
 | 
  
    | 889 |             return false;
 | 
  
    | 890 |         }
 | 
  
    | 891 |         return true;
 | 
  
    | 892 |     }
 | 
  
    | 893 | 
 | 
  
    | 894 |     /**
 | 
  
    | 895 |      * Starts a mail transaction from the email address specified in
 | 
  
    | 896 |      * $from. Returns true if successful or false otherwise. If True
 | 
  
    | 897 |      * the mail transaction is started and then one or more Recipient
 | 
  
    | 898 |      * commands may be called followed by a Data command. This command
 | 
  
    | 899 |      * will send the message to the users terminal if they are logged
 | 
  
    | 900 |      * in or mail it to them if they are not.
 | 
  
    | 901 |      *
 | 
  
    | 902 |      * Implements rfc 821: SOML <SP> FROM:<reverse-path> <CRLF>
 | 
  
    | 903 |      *
 | 
  
    | 904 |      * SMTP CODE SUCCESS: 250
 | 
  
    | 905 |      * SMTP CODE SUCCESS: 552,451,452
 | 
  
    | 906 |      * SMTP CODE SUCCESS: 500,501,502,421
 | 
  
    | 907 |      * @access public
 | 
  
    | 908 |      * @return bool
 | 
  
    | 909 |      */
 | 
  
    | 910 |     function SendOrMail($from) {
 | 
  
    | 911 |         $this->error = null; # so no confusion is caused
 | 
  
    | 912 | 
 | 
  
    | 913 |         if(!$this->connected()) {
 | 
  
    | 914 |             $this->error = array(
 | 
  
    | 915 |                 "error" => "Called SendOrMail() without being connected");
 | 
  
    | 916 |             return false;
 | 
  
    | 917 |         }
 | 
  
    | 918 | 
 | 
  
    | 919 |         fputs($this->smtp_conn,"SOML FROM:" . $from . $this->CRLF);
 | 
  
    | 920 | 
 | 
  
    | 921 |         $rply = $this->get_lines();
 | 
  
    | 922 |         $code = substr($rply,0,3);
 | 
  
    | 923 | 
 | 
  
    | 924 |         if($this->do_debug >= 2) {
 | 
  
    | 925 |             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
 | 
  
    | 926 |         }
 | 
  
    | 927 | 
 | 
  
    | 928 |         if($code != 250) {
 | 
  
    | 929 |             $this->error =
 | 
  
    | 930 |                 array("error" => "SOML not accepted from server",
 | 
  
    | 931 |                       "smtp_code" => $code,
 | 
  
    | 932 |                       "smtp_msg" => substr($rply,4));
 | 
  
    | 933 |             if($this->do_debug >= 1) {
 | 
  
    | 934 |                 echo "SMTP -> ERROR: " . $this->error["error"] .
 | 
  
    | 935 |                          ": " . $rply . $this->CRLF;
 | 
  
    | 936 |             }
 | 
  
    | 937 |             return false;
 | 
  
    | 938 |         }
 | 
  
    | 939 |         return true;
 | 
  
    | 940 |     }
 | 
  
    | 941 | 
 | 
  
    | 942 |     /**
 | 
  
    | 943 |      * This is an optional command for SMTP that this class does not
 | 
  
    | 944 |      * support. This method is here to make the RFC821 Definition
 | 
  
    | 945 |      * complete for this class and __may__ be implimented in the future
 | 
  
    | 946 |      *
 | 
  
    | 947 |      * Implements from rfc 821: TURN <CRLF>
 | 
  
    | 948 |      *
 | 
  
    | 949 |      * SMTP CODE SUCCESS: 250
 | 
  
    | 950 |      * SMTP CODE FAILURE: 502
 | 
  
    | 951 |      * SMTP CODE ERROR  : 500, 503
 | 
  
    | 952 |      * @access public
 | 
  
    | 953 |      * @return bool
 | 
  
    | 954 |      */
 | 
  
    | 955 |     function Turn() {
 | 
  
    | 956 |         $this->error = array("error" => "This method, TURN, of the SMTP ".
 | 
  
    | 957 |                                         "is not implemented");
 | 
  
    | 958 |         if($this->do_debug >= 1) {
 | 
  
    | 959 |             echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF;
 | 
  
    | 960 |         }
 | 
  
    | 961 |         return false;
 | 
  
    | 962 |     }
 | 
  
    | 963 | 
 | 
  
    | 964 |     /**
 | 
  
    | 965 |      * Verifies that the name is recognized by the server.
 | 
  
    | 966 |      * Returns false if the name could not be verified otherwise
 | 
  
    | 967 |      * the response from the server is returned.
 | 
  
    | 968 |      *
 | 
  
    | 969 |      * Implements rfc 821: VRFY <SP> <string> <CRLF>
 | 
  
    | 970 |      *
 | 
  
    | 971 |      * SMTP CODE SUCCESS: 250,251
 | 
  
    | 972 |      * SMTP CODE FAILURE: 550,551,553
 | 
  
    | 973 |      * SMTP CODE ERROR  : 500,501,502,421
 | 
  
    | 974 |      * @access public
 | 
  
    | 975 |      * @return int
 | 
  
    | 976 |      */
 | 
  
    | 977 |     function Verify($name) {
 | 
  
    | 978 |         $this->error = null; # so no confusion is caused
 | 
  
    | 979 | 
 | 
  
    | 980 |         if(!$this->connected()) {
 | 
  
    | 981 |             $this->error = array(
 | 
  
    | 982 |                     "error" => "Called Verify() without being connected");
 | 
  
    | 983 |             return false;
 | 
  
    | 984 |         }
 | 
  
    | 985 | 
 | 
  
    | 986 |         fputs($this->smtp_conn,"VRFY " . $name . $this->CRLF);
 | 
  
    | 987 | 
 | 
  
    | 988 |         $rply = $this->get_lines();
 | 
  
    | 989 |         $code = substr($rply,0,3);
 | 
  
    | 990 | 
 | 
  
    | 991 |         if($this->do_debug >= 2) {
 | 
  
    | 992 |             echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
 | 
  
    | 993 |         }
 | 
  
    | 994 | 
 | 
  
    | 995 |         if($code != 250 && $code != 251) {
 | 
  
    | 996 |             $this->error =
 | 
  
    | 997 |                 array("error" => "VRFY failed on name '$name'",
 | 
  
    | 998 |                       "smtp_code" => $code,
 | 
  
    | 999 |                       "smtp_msg" => substr($rply,4));
 | 
  
    | 1000 |             if($this->do_debug >= 1) {
 | 
  
    | 1001 |                 echo "SMTP -> ERROR: " . $this->error["error"] .
 | 
  
    | 1002 |                          ": " . $rply . $this->CRLF;
 | 
  
    | 1003 |             }
 | 
  
    | 1004 |             return false;
 | 
  
    | 1005 |         }
 | 
  
    | 1006 |         return $rply;
 | 
  
    | 1007 |     }
 | 
  
    | 1008 | 
 | 
  
    | 1009 |     /*******************************************************************
 | 
  
    | 1010 |      *                       INTERNAL FUNCTIONS                       *
 | 
  
    | 1011 |      ******************************************************************/
 | 
  
    | 1012 | 
 | 
  
    | 1013 |     /**
 | 
  
    | 1014 |      * Read in as many lines as possible
 | 
  
    | 1015 |      * either before eof or socket timeout occurs on the operation.
 | 
  
    | 1016 |      * With SMTP we can tell if we have more lines to read if the
 | 
  
    | 1017 |      * 4th character is '-' symbol. If it is a space then we don't
 | 
  
    | 1018 |      * need to read anything else.
 | 
  
    | 1019 |      * @access private
 | 
  
    | 1020 |      * @return string
 | 
  
    | 1021 |      */
 | 
  
    | 1022 |     function get_lines() {
 | 
  
    | 1023 |         $data = "";
 | 
  
    | 1024 |         while($str = fgets($this->smtp_conn,515)) {
 | 
  
    | 1025 |             if($this->do_debug >= 4) {
 | 
  
    | 1026 |                 echo "SMTP -> get_lines(): \$data was \"$data\"" .
 | 
  
    | 1027 |                          $this->CRLF;
 | 
  
    | 1028 |                 echo "SMTP -> get_lines(): \$str is \"$str\"" .
 | 
  
    | 1029 |                          $this->CRLF;
 | 
  
    | 1030 |             }
 | 
  
    | 1031 |             $data .= $str;
 | 
  
    | 1032 |             if($this->do_debug >= 4) {
 | 
  
    | 1033 |                 echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF;
 | 
  
    | 1034 |             }
 | 
  
    | 1035 |             # if the 4th character is a space then we are done reading
 | 
  
    | 1036 |             # so just break the loop
 | 
  
    | 1037 |             if(substr($str,3,1) == " ") { break; }
 | 
  
    | 1038 |         }
 | 
  
    | 1039 |         return $data;
 | 
  
    | 1040 |     }
 | 
  
    | 1041 | 
 | 
  
    | 1042 | }
 | 
  
    | 1043 | 
 | 
  
    | 1044 | 
 | 
  
    | 1045 |  ?>
 |