source: trunk/expressoMail1_2/inc/class.smtp.php @ 5509

Revision 5509, 33.7 KB checked in by gustavo, 12 years ago (diff)

Ticket #2488 - Adicionar cabecalho de licenca em arquivos que nao o possuem

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