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

Revision 5509, 33.3 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                $lines_out[] = substr($line,0,$pos);
346                $line = substr($line,$pos + 1);
347                # if we are processing headers we need to
348                # add a LWSP-char to the front of the new line
349                # rfc 822 on long msg headers
350                if($in_headers) {
351                    $line = "\t" . $line;
352                }
353            }
354            $lines_out[] = $line;
355
356            # now send the lines to the server
357            while(list(,$line_out) = @each($lines_out)) {
358                if(strlen($line_out) > 0)
359                {
360                    if(substr($line_out, 0, 1) == ".") {
361                        $line_out = "." . $line_out;
362                    }
363                }
364                fputs($this->smtp_conn,$line_out . $this->CRLF);
365            }
366        }
367
368        # ok all the message data has been sent so lets get this
369        # over with aleady
370        fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF);
371
372        $rply = $this->get_lines();
373        $code = substr($rply,0,3);
374
375        if($this->do_debug >= 2) {
376            echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
377        }
378
379        if($code != 250) {
380            $this->error =
381                array("error" => "DATA not accepted from server",
382                      "smtp_code" => $code,
383                      "smtp_msg" => substr($rply,4));
384            if($this->do_debug >= 1) {
385                echo "SMTP -> ERROR: " . $this->error["error"] .
386                         ": " . $rply . $this->CRLF;
387            }
388            return false;
389        }
390        return true;
391    }
392
393    /**
394     * Expand takes the name and asks the server to list all the
395     * people who are members of the _list_. Expand will return
396     * back and array of the result or false if an error occurs.
397     * Each value in the array returned has the format of:
398     *     [ <full-name> <sp> ] <path>
399     * The definition of <path> is defined in rfc 821
400     *
401     * Implements rfc 821: EXPN <SP> <string> <CRLF>
402     *
403     * SMTP CODE SUCCESS: 250
404     * SMTP CODE FAILURE: 550
405     * SMTP CODE ERROR  : 500,501,502,504,421
406     * @access public
407     * @return string array
408     */
409    function Expand($name) {
410        $this->error = null; # so no confusion is caused
411
412        if(!$this->connected()) {
413            $this->error = array(
414                    "error" => "Called Expand() without being connected");
415            return false;
416        }
417
418        fputs($this->smtp_conn,"EXPN " . $name . $this->CRLF);
419
420        $rply = $this->get_lines();
421        $code = substr($rply,0,3);
422
423        if($this->do_debug >= 2) {
424            echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
425        }
426
427        if($code != 250) {
428            $this->error =
429                array("error" => "EXPN not accepted from server",
430                      "smtp_code" => $code,
431                      "smtp_msg" => substr($rply,4));
432            if($this->do_debug >= 1) {
433                echo "SMTP -> ERROR: " . $this->error["error"] .
434                         ": " . $rply . $this->CRLF;
435            }
436            return false;
437        }
438
439        # parse the reply and place in our array to return to user
440        $entries = explode($this->CRLF,$rply);
441        while(list(,$l) = @each($entries)) {
442            $list[] = substr($l,4);
443        }
444
445        return $list;
446    }
447
448    /**
449     * Sends the HELO command to the smtp server.
450     * This makes sure that we and the server are in
451     * the same known state.
452     *
453     * Implements from rfc 821: HELO <SP> <domain> <CRLF>
454     *
455     * SMTP CODE SUCCESS: 250
456     * SMTP CODE ERROR  : 500, 501, 504, 421
457     * @access public
458     * @return bool
459     */
460    function Hello($host="") {
461        $this->error = null; # so no confusion is caused
462
463        if(!$this->connected()) {
464            $this->error = array(
465                    "error" => "Called Hello() without being connected");
466            return false;
467        }
468
469        # if a hostname for the HELO wasn't specified determine
470        # a suitable one to send
471        if(empty($host)) {
472            # we need to determine some sort of appopiate default
473            # to send to the server
474            $host = "localhost";
475        }
476
477        // Send extended hello first (RFC 2821)
478        if(!$this->SendHello("EHLO", $host))
479        {
480            if(!$this->SendHello("HELO", $host))
481                return false;
482        }
483
484        return true;
485    }
486
487    /**
488     * Sends a HELO/EHLO command.
489     * @access private
490     * @return bool
491     */
492    function SendHello($hello, $host) {
493        fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF);
494
495        $rply = $this->get_lines();
496        $code = substr($rply,0,3);
497
498        if($this->do_debug >= 2) {
499            echo "SMTP -> FROM SERVER: " . $this->CRLF . $rply;
500        }
501
502        if($code != 250) {
503            $this->error =
504                array("error" => $hello . " not accepted from server",
505                      "smtp_code" => $code,
506                      "smtp_msg" => substr($rply,4));
507            if($this->do_debug >= 1) {
508                echo "SMTP -> ERROR: " . $this->error["error"] .
509                         ": " . $rply . $this->CRLF;
510            }
511            return false;
512        }
513
514        $this->helo_rply = $rply;
515       
516        return true;
517    }
518
519    /**
520     * Gets help information on the keyword specified. If the keyword
521     * is not specified then returns generic help, ussually contianing
522     * A list of keywords that help is available on. This function
523     * returns the results back to the user. It is up to the user to
524     * handle the returned data. If an error occurs then false is
525     * returned with $this->error set appropiately.
526     *
527     * Implements rfc 821: HELP [ <SP> <string> ] <CRLF>
528     *
529     * SMTP CODE SUCCESS: 211,214
530     * SMTP CODE ERROR  : 500,501,502,504,421
531     * @access public
532     * @return string
533     */
534    function Help($keyword="") {
535        $this->error = null; # to avoid confusion
536
537        if(!$this->connected()) {
538            $this->error = array(
539                    "error" => "Called Help() without being connected");
540            return false;
541        }
542
543        $extra = "";
544        if(!empty($keyword)) {
545            $extra = " " . $keyword;
546        }
547
548        fputs($this->smtp_conn,"HELP" . $extra . $this->CRLF);
549
550        $rply = $this->get_lines();
551        $code = substr($rply,0,3);
552
553        if($this->do_debug >= 2) {
554            echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
555        }
556
557        if($code != 211 && $code != 214) {
558            $this->error =
559                array("error" => "HELP not accepted from server",
560                      "smtp_code" => $code,
561                      "smtp_msg" => substr($rply,4));
562            if($this->do_debug >= 1) {
563                echo "SMTP -> ERROR: " . $this->error["error"] .
564                         ": " . $rply . $this->CRLF;
565            }
566            return false;
567        }
568
569        return $rply;
570    }
571
572    /**
573     * Starts a mail transaction from the email address specified in
574     * $from. Returns true if successful or false otherwise. If True
575     * the mail transaction is started and then one or more Recipient
576     * commands may be called followed by a Data command.
577     *
578     * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>
579     *
580     * SMTP CODE SUCCESS: 250
581     * SMTP CODE SUCCESS: 552,451,452
582     * SMTP CODE SUCCESS: 500,501,421
583     * @access public
584     * @return bool
585     */
586    function Mail($from) {
587        $this->error = null; # so no confusion is caused
588
589        if(!$this->connected()) {
590            $this->error = array(
591                    "error" => "Called Mail() without being connected");
592            return false;
593        }
594
595        fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $this->CRLF);
596
597        $rply = $this->get_lines();
598        $code = substr($rply,0,3);
599
600        if($this->do_debug >= 2) {
601            echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
602        }
603
604        if($code != 250) {
605            $this->error =
606                array("error" => "MAIL not accepted from server",
607                      "smtp_code" => $code,
608                      "smtp_msg" => substr($rply,4));
609            if($this->do_debug >= 1) {
610                echo "SMTP -> ERROR: " . $this->error["error"] .
611                         ": " . $rply . $this->CRLF;
612            }
613            return false;
614        }
615        return true;
616    }
617
618    /**
619     * Sends the command NOOP to the SMTP server.
620     *
621     * Implements from rfc 821: NOOP <CRLF>
622     *
623     * SMTP CODE SUCCESS: 250
624     * SMTP CODE ERROR  : 500, 421
625     * @access public
626     * @return bool
627     */
628    function Noop() {
629        $this->error = null; # so no confusion is caused
630
631        if(!$this->connected()) {
632            $this->error = array(
633                    "error" => "Called Noop() without being connected");
634            return false;
635        }
636
637        fputs($this->smtp_conn,"NOOP" . $this->CRLF);
638
639        $rply = $this->get_lines();
640        $code = substr($rply,0,3);
641
642        if($this->do_debug >= 2) {
643            echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
644        }
645
646        if($code != 250) {
647            $this->error =
648                array("error" => "NOOP not accepted from server",
649                      "smtp_code" => $code,
650                      "smtp_msg" => substr($rply,4));
651            if($this->do_debug >= 1) {
652                echo "SMTP -> ERROR: " . $this->error["error"] .
653                         ": " . $rply . $this->CRLF;
654            }
655            return false;
656        }
657        return true;
658    }
659
660    /**
661     * Sends the quit command to the server and then closes the socket
662     * if there is no error or the $close_on_error argument is true.
663     *
664     * Implements from rfc 821: QUIT <CRLF>
665     *
666     * SMTP CODE SUCCESS: 221
667     * SMTP CODE ERROR  : 500
668     * @access public
669     * @return bool
670     */
671    function Quit($close_on_error=true) {
672        $this->error = null; # so there is no confusion
673
674        if(!$this->connected()) {
675            $this->error = array(
676                    "error" => "Called Quit() without being connected");
677            return false;
678        }
679
680        # send the quit command to the server
681        fputs($this->smtp_conn,"quit" . $this->CRLF);
682
683        # get any good-bye messages
684        $byemsg = $this->get_lines();
685
686        if($this->do_debug >= 2) {
687            echo "SMTP -> FROM SERVER:" . $this->CRLF . $byemsg;
688        }
689
690        $rval = true;
691        $e = null;
692
693        $code = substr($byemsg,0,3);
694        if($code != 221) {
695            # use e as a tmp var cause Close will overwrite $this->error
696            $e = array("error" => "SMTP server rejected quit command",
697                       "smtp_code" => $code,
698                       "smtp_rply" => substr($byemsg,4));
699            $rval = false;
700            if($this->do_debug >= 1) {
701                echo "SMTP -> ERROR: " . $e["error"] . ": " .
702                         $byemsg . $this->CRLF;
703            }
704        }
705
706        if(empty($e) || $close_on_error) {
707            $this->Close();
708        }
709
710        return $rval;
711    }
712
713    /**
714     * Sends the command RCPT to the SMTP server with the TO: argument of $to.
715     * Returns true if the recipient was accepted false if it was rejected.
716     *
717     * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
718     *
719     * SMTP CODE SUCCESS: 250,251
720     * SMTP CODE FAILURE: 550,551,552,553,450,451,452
721     * SMTP CODE ERROR  : 500,501,503,421
722     * @access public
723     * @return bool
724     */
725    function Recipient($to) {
726        $this->error = null; # so no confusion is caused
727
728        if(!$this->connected()) {
729            $this->error = array(
730                    "error" => "Called Recipient() without being connected");
731            return false;
732        }
733
734        fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF);
735
736        $rply = $this->get_lines();
737        $code = substr($rply,0,3);
738
739        if($this->do_debug >= 2) {
740            echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
741        }
742
743        if($code != 250 && $code != 251) {
744            $this->error =
745                array("error" => "RCPT not accepted from server",
746                      "smtp_code" => $code,
747                      "smtp_msg" => substr($rply,4));
748            if($this->do_debug >= 1) {
749                echo "SMTP -> ERROR: " . $this->error["error"] .
750                         ": " . $rply . $this->CRLF;
751            }
752            return false;
753        }
754        return true;
755    }
756
757    /**
758     * Sends the RSET command to abort and transaction that is
759     * currently in progress. Returns true if successful false
760     * otherwise.
761     *
762     * Implements rfc 821: RSET <CRLF>
763     *
764     * SMTP CODE SUCCESS: 250
765     * SMTP CODE ERROR  : 500,501,504,421
766     * @access public
767     * @return bool
768     */
769    function Reset() {
770        $this->error = null; # so no confusion is caused
771
772        if(!$this->connected()) {
773            $this->error = array(
774                    "error" => "Called Reset() without being connected");
775            return false;
776        }
777
778        fputs($this->smtp_conn,"RSET" . $this->CRLF);
779
780        $rply = $this->get_lines();
781        $code = substr($rply,0,3);
782
783        if($this->do_debug >= 2) {
784            echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
785        }
786
787        if($code != 250) {
788            $this->error =
789                array("error" => "RSET failed",
790                      "smtp_code" => $code,
791                      "smtp_msg" => substr($rply,4));
792            if($this->do_debug >= 1) {
793                echo "SMTP -> ERROR: " . $this->error["error"] .
794                         ": " . $rply . $this->CRLF;
795            }
796            return false;
797        }
798
799        return true;
800    }
801
802    /**
803     * Starts a mail transaction from the email address specified in
804     * $from. Returns true if successful or false otherwise. If True
805     * the mail transaction is started and then one or more Recipient
806     * commands may be called followed by a Data command. This command
807     * will send the message to the users terminal if they are logged
808     * in.
809     *
810     * Implements rfc 821: SEND <SP> FROM:<reverse-path> <CRLF>
811     *
812     * SMTP CODE SUCCESS: 250
813     * SMTP CODE SUCCESS: 552,451,452
814     * SMTP CODE SUCCESS: 500,501,502,421
815     * @access public
816     * @return bool
817     */
818    function Send($from) {
819        $this->error = null; # so no confusion is caused
820
821        if(!$this->connected()) {
822            $this->error = array(
823                    "error" => "Called Send() without being connected");
824            return false;
825        }
826
827        fputs($this->smtp_conn,"SEND FROM:" . $from . $this->CRLF);
828
829        $rply = $this->get_lines();
830        $code = substr($rply,0,3);
831
832        if($this->do_debug >= 2) {
833            echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
834        }
835
836        if($code != 250) {
837            $this->error =
838                array("error" => "SEND not accepted from server",
839                      "smtp_code" => $code,
840                      "smtp_msg" => substr($rply,4));
841            if($this->do_debug >= 1) {
842                echo "SMTP -> ERROR: " . $this->error["error"] .
843                         ": " . $rply . $this->CRLF;
844            }
845            return false;
846        }
847        return true;
848    }
849
850    /**
851     * Starts a mail transaction from the email address specified in
852     * $from. Returns true if successful or false otherwise. If True
853     * the mail transaction is started and then one or more Recipient
854     * commands may be called followed by a Data command. This command
855     * will send the message to the users terminal if they are logged
856     * in and send them an email.
857     *
858     * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>
859     *
860     * SMTP CODE SUCCESS: 250
861     * SMTP CODE SUCCESS: 552,451,452
862     * SMTP CODE SUCCESS: 500,501,502,421
863     * @access public
864     * @return bool
865     */
866    function SendAndMail($from) {
867        $this->error = null; # so no confusion is caused
868
869        if(!$this->connected()) {
870            $this->error = array(
871                "error" => "Called SendAndMail() without being connected");
872            return false;
873        }
874
875        fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF);
876
877        $rply = $this->get_lines();
878        $code = substr($rply,0,3);
879
880        if($this->do_debug >= 2) {
881            echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
882        }
883
884        if($code != 250) {
885            $this->error =
886                array("error" => "SAML not accepted from server",
887                      "smtp_code" => $code,
888                      "smtp_msg" => substr($rply,4));
889            if($this->do_debug >= 1) {
890                echo "SMTP -> ERROR: " . $this->error["error"] .
891                         ": " . $rply . $this->CRLF;
892            }
893            return false;
894        }
895        return true;
896    }
897
898    /**
899     * Starts a mail transaction from the email address specified in
900     * $from. Returns true if successful or false otherwise. If True
901     * the mail transaction is started and then one or more Recipient
902     * commands may be called followed by a Data command. This command
903     * will send the message to the users terminal if they are logged
904     * in or mail it to them if they are not.
905     *
906     * Implements rfc 821: SOML <SP> FROM:<reverse-path> <CRLF>
907     *
908     * SMTP CODE SUCCESS: 250
909     * SMTP CODE SUCCESS: 552,451,452
910     * SMTP CODE SUCCESS: 500,501,502,421
911     * @access public
912     * @return bool
913     */
914    function SendOrMail($from) {
915        $this->error = null; # so no confusion is caused
916
917        if(!$this->connected()) {
918            $this->error = array(
919                "error" => "Called SendOrMail() without being connected");
920            return false;
921        }
922
923        fputs($this->smtp_conn,"SOML FROM:" . $from . $this->CRLF);
924
925        $rply = $this->get_lines();
926        $code = substr($rply,0,3);
927
928        if($this->do_debug >= 2) {
929            echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
930        }
931
932        if($code != 250) {
933            $this->error =
934                array("error" => "SOML not accepted from server",
935                      "smtp_code" => $code,
936                      "smtp_msg" => substr($rply,4));
937            if($this->do_debug >= 1) {
938                echo "SMTP -> ERROR: " . $this->error["error"] .
939                         ": " . $rply . $this->CRLF;
940            }
941            return false;
942        }
943        return true;
944    }
945
946    /**
947     * This is an optional command for SMTP that this class does not
948     * support. This method is here to make the RFC821 Definition
949     * complete for this class and __may__ be implimented in the future
950     *
951     * Implements from rfc 821: TURN <CRLF>
952     *
953     * SMTP CODE SUCCESS: 250
954     * SMTP CODE FAILURE: 502
955     * SMTP CODE ERROR  : 500, 503
956     * @access public
957     * @return bool
958     */
959    function Turn() {
960        $this->error = array("error" => "This method, TURN, of the SMTP ".
961                                        "is not implemented");
962        if($this->do_debug >= 1) {
963            echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF;
964        }
965        return false;
966    }
967
968    /**
969     * Verifies that the name is recognized by the server.
970     * Returns false if the name could not be verified otherwise
971     * the response from the server is returned.
972     *
973     * Implements rfc 821: VRFY <SP> <string> <CRLF>
974     *
975     * SMTP CODE SUCCESS: 250,251
976     * SMTP CODE FAILURE: 550,551,553
977     * SMTP CODE ERROR  : 500,501,502,421
978     * @access public
979     * @return int
980     */
981    function Verify($name) {
982        $this->error = null; # so no confusion is caused
983
984        if(!$this->connected()) {
985            $this->error = array(
986                    "error" => "Called Verify() without being connected");
987            return false;
988        }
989
990        fputs($this->smtp_conn,"VRFY " . $name . $this->CRLF);
991
992        $rply = $this->get_lines();
993        $code = substr($rply,0,3);
994
995        if($this->do_debug >= 2) {
996            echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
997        }
998
999        if($code != 250 && $code != 251) {
1000            $this->error =
1001                array("error" => "VRFY failed on name '$name'",
1002                      "smtp_code" => $code,
1003                      "smtp_msg" => substr($rply,4));
1004            if($this->do_debug >= 1) {
1005                echo "SMTP -> ERROR: " . $this->error["error"] .
1006                         ": " . $rply . $this->CRLF;
1007            }
1008            return false;
1009        }
1010        return $rply;
1011    }
1012
1013    /*******************************************************************
1014     *                       INTERNAL FUNCTIONS                       *
1015     ******************************************************************/
1016
1017    /**
1018     * Read in as many lines as possible
1019     * either before eof or socket timeout occurs on the operation.
1020     * With SMTP we can tell if we have more lines to read if the
1021     * 4th character is '-' symbol. If it is a space then we don't
1022     * need to read anything else.
1023     * @access private
1024     * @return string
1025     */
1026    function get_lines() {
1027        $data = "";
1028        while($str = fgets($this->smtp_conn,515)) {
1029            if($this->do_debug >= 4) {
1030                echo "SMTP -> get_lines(): \$data was \"$data\"" .
1031                         $this->CRLF;
1032                echo "SMTP -> get_lines(): \$str is \"$str\"" .
1033                         $this->CRLF;
1034            }
1035            $data .= $str;
1036            if($this->do_debug >= 4) {
1037                echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF;
1038            }
1039            # if the 4th character is a space then we are done reading
1040            # so just break the loop
1041            if(substr($str,3,1) == " ") { break; }
1042        }
1043        return $data;
1044    }
1045
1046}
1047
1048
1049 ?>
Note: See TracBrowser for help on using the repository browser.