source: trunk/spip/esqueleto-redcta/plugins/zabomailmans/class/phpmailer/class.smtp.php @ 96

Last change on this file since 96 was 76, checked in by sebas, 16 years ago

plugin de abonomailman para enviar boletin electronico
basado sobre los cambios de sebas para arreglar los envios.

  • Property svn:executable set to *
File size: 33.8 KB
RevLine 
[76]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 */
24class 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 ?>
Note: See TracBrowser for help on using the repository browser.