You are here

function SMTP::Data in SMTP Authentication Support 5

Same name and namespace in other branches
  1. 7.2 smtp.transport.inc \SMTP::Data()
  2. 7 smtp.transport.inc \SMTP::Data()

Issues a data command and sends the msg_data to the server finializing the mail transaction. $msg_data is the message that is to be send with the headers. Each header needs to be on a single line followed by a <CRLF> with the message headers and the message body being seperated by and additional <CRLF>.

Implements rfc 821: DATA <CRLF>

SMTP CODE INTERMEDIATE: 354 [data] <CRLF>.<CRLF> SMTP CODE SUCCESS: 250 SMTP CODE FAILURE: 552,554,451,452 SMTP CODE FAILURE: 451,554 SMTP CODE ERROR : 500,501,503,421 @access public

Return value

bool

File

./smtp.module, line 2239
Enables drupal to send email directly to an SMTP server using authentication. Uses the PHPMailer class by Brent R. Matzelle.

Class

SMTP
SMTP is rfc 821 compliant and implements all the rfc 821 SMTP commands except TURN which will always return a not implemented error. SMTP also provides some utility methods for sending mail to an SMTP server. @package PHPMailer @author Chris Ryan

Code

function Data($msg_data) {
  $this->error = null;

  # so no confusion is caused
  if (!$this
    ->connected()) {
    $this->error = array(
      "error" => "Called Data() without being connected",
    );
    return false;
  }
  fputs($this->smtp_conn, "DATA" . $this->CRLF);
  $rply = $this
    ->get_lines();
  $code = substr($rply, 0, 3);
  if ($this->do_debug >= 2) {
    echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
  }
  if ($code != 354) {
    $this->error = array(
      "error" => "DATA command not accepted from server",
      "smtp_code" => $code,
      "smtp_msg" => substr($rply, 4),
    );
    if ($this->do_debug >= 1) {
      echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF;
    }
    return false;
  }

  # the server is ready to accept data!

  # according to rfc 821 we should not send more than 1000

  # including the CRLF

  # characters on a single line so we will break the data up

  # into lines by \r and/or \n then if needed we will break

  # each of those into smaller lines to fit within the limit.

  # in addition we will be looking for lines that start with

  # a period '.' and append and additional period '.' to that

  # line. NOTE: this does not count towards are limit.

  # normalize the line breaks so we know the explode works
  $msg_data = str_replace("\r\n", "\n", $msg_data);
  $msg_data = str_replace("\r", "\n", $msg_data);
  $lines = explode("\n", $msg_data);

  # we need to find a good way to determine is headers are

  # in the msg_data or if it is a straight msg body

  # currently I'm assuming rfc 822 definitions of msg headers

  # and if the first field of the first line (':' sperated)

  # does not contain a space then it _should_ be a header

  # and we can process all lines before a blank "" line as

  # headers.
  $field = substr($lines[0], 0, strpos($lines[0], ":"));
  $in_headers = false;
  if (!empty($field) && !strstr($field, " ")) {
    $in_headers = true;
  }
  $max_line_length = 998;

  # used below; set here for ease in change
  while (list(, $line) = @each($lines)) {
    $lines_out = null;
    if ($line == "" && $in_headers) {
      $in_headers = false;
    }

    # ok we need to break this line up into several

    # smaller lines
    while (strlen($line) > $max_line_length) {
      $pos = strrpos(substr($line, 0, $max_line_length), " ");

      # Patch to fix DOS attack
      if (!$pos) {
        $pos = $max_line_length - 1;
      }
      $lines_out[] = substr($line, 0, $pos);
      $line = substr($line, $pos + 1);

      # if we are processing headers we need to

      # add a LWSP-char to the front of the new line

      # rfc 822 on long msg headers
      if ($in_headers) {
        $line = "\t" . $line;
      }
    }
    $lines_out[] = $line;

    # now send the lines to the server
    while (list(, $line_out) = @each($lines_out)) {
      if (strlen($line_out) > 0) {
        if (substr($line_out, 0, 1) == ".") {
          $line_out = "." . $line_out;
        }
      }
      fputs($this->smtp_conn, $line_out . $this->CRLF);
    }
  }

  # ok all the message data has been sent so lets get this

  # over with aleady
  fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF);
  $rply = $this
    ->get_lines();
  $code = substr($rply, 0, 3);
  if ($this->do_debug >= 2) {
    echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
  }
  if ($code != 250) {
    $this->error = array(
      "error" => "DATA not accepted from server",
      "smtp_code" => $code,
      "smtp_msg" => substr($rply, 4),
    );
    if ($this->do_debug >= 1) {
      echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF;
    }
    return false;
  }
  return true;
}