summaryrefslogtreecommitdiff
path: root/mail.class
diff options
context:
space:
mode:
authorUrban Müller2007-07-26 13:02:24 +0000
committerUrban Müller2007-07-26 13:02:24 +0000
commit806a5297e7e99d455b97a4f0acaba2f40f470584 (patch)
treeb9fc43ef227da87d873cf3676c08c49fa0dc1240 /mail.class
parentc3cba034c8009b65c25dd4ef5f54b18d9c8ee7d4 (diff)
downloaditools-806a5297e7e99d455b97a4f0acaba2f40f470584.tar.gz
itools-806a5297e7e99d455b97a4f0acaba2f40f470584.tar.bz2
itools-806a5297e7e99d455b97a4f0acaba2f40f470584.zip
renamed files for autoloader
Diffstat (limited to 'mail.class')
-rw-r--r--mail.class483
1 files changed, 0 insertions, 483 deletions
diff --git a/mail.class b/mail.class
deleted file mode 100644
index f10e84d..0000000
--- a/mail.class
+++ /dev/null
@@ -1,483 +0,0 @@
-<?php
-/*
-** $Id$
-**
-** mail.class - Create a mail object, add header and content and send it
-**
-** ITools - the Internet Tools Library
-**
-** Copyright (C) 1995-2003 by the ITools Authors.
-** This program is free software; you can redistribute it and/or
-** modify it under the terms of either the GNU General Public License
-** or the GNU Lesser General Public License, as published by the Free
-** Software Foundation. See http://www.gnu.org/licenses/ for details.
-*/
-
-define('IT_MAIL_PLAIN', 0);
-define('IT_MAIL_HTML', 1);
-
-/* Return codes of it_mail::check_email() */
-define('IT_MAIL_CHECKEMAIL_INVALID', 0);
-define('IT_MAIL_CHECKEMAIL_MAILBOXFULL', 5);
-define('IT_MAIL_CHECKEMAIL_OK', 10);
-
-/**
- * Construct an email message with headers, body (plaintext and/or HTML) and
- * send it. Also provides utility function to check email address validity.<br>
- * <em>Example:</em><br>
- * <code><nobr>
- * if (!it_mail::check_email($to))<br>
- * &nbsp;&nbsp;&nbsp;&nbsp;die("Invalid email address '$to'\n");<br>
- * <br>
- * $mail = new it_mail(array('To' => $to&#44; 'From' => 'itools@gna.ch', 'Subject' => 'Example'));<br>
- * $mail->add_body('Plain text message body');<br>
- * $mail->add_body('HTML message with &lt;a href="http://gna.ch/"&gt;link&lt;/a&gt;', IT_MAIL_HTML);<br>
- * $mail->send();<br>
- * </nobr></code>
- */
-class it_mail
-{
- var $header_names = array();
- var $header_values = array();
- var $body = array();
- var $attachments = array();
-
- var $to = array();
- var $subject = "";
- var $cc = array();
- var $bcc = array();
- var $flags = "";
- var $charset = 'iso-8859-1';
-
-/**
- * Construct a new email message. Headers and body can be added later.
- * Note: Headers To, Cc, Bcc can be arrays
- * @param $headers Array of headers for this email, e.g. From, To and Subject
- */
-function it_mail($headers = "")
-{
- if (is_array($headers))
- {
- foreach ($headers as $header => $value)
- $this->add_header($header, $value);
- }
-}
-
-
-/**
- * Add header line to the this email message. Can be called repeatedly.
- * Note: Headers To, Cc, Bcc can be arrays
- * @param $header Header to be added, e.g. Cc, Bcc or X-My-Header
- * @param $value Value of header, e.g. itools@gna.ch for Bcc header
- */
-function add_header($header, $value)
-{
- $value = $this->header_escape($value);
-
- switch ($header)
- {
- case 'To':
- if (is_array($value))
- {
- foreach ($value as $val)
- $this->to[] = $val;
- }
- else
- $this->to[] = $value;
- break;
-
- case 'Subject':
- $this->subject .= $value;
- break;
-
- case 'Cc':
- if (is_array($value))
- {
- foreach ($value as $val)
- $this->cc[] = $val;
- }
- else
- $this->cc[] = $value;
- break;
-
- case 'Bcc':
- if (is_array($value))
- {
- foreach ($value as $val)
- $this->bcc[] = $val;
- }
- else
- $this->bcc[] = $value;
- break;
-
- case 'charset':
- $this->charset = $value;
- break;
-
- case 'Errors-To':
- $this->flags = "-f " . escapeshellarg(preg_replace('/.*<([^>]+)>.*/', '$1', $value));
- /* FALLTHROUGH */
- default:
- $this->header_names[] = $header;
- $this->header_values[] = $value;
- break;
- }
-}
-
-
-/**
- * Add body part to this email message. Can be called repeatedly.
- * @param $text Text to be added to email message
- * @param $type Type of text, one of IT_MAIL_PLAIN (default) or IT_MAIL_HTML
- */
-function add_body($text, $type = IT_MAIL_PLAIN)
-{
- switch ($type)
- {
- case IT_MAIL_PLAIN:
- case IT_MAIL_HTML:
- $this->body[$type] .= $text;
- break;
-
- default:
- it::fatal("it_mail::add_body invalid type $type");
- break;
- }
-}
-
-
-/**
- * Add attachment to this email message. Can be called repeatedly.
- * @param $data Data to be attached
- * @param $name Name of attached file
- * @param $mimetype MIME-Type of attached file
- * @return 'cid:'.Content-ID of this attachment
- */
-function add_attachment($data, $mimetype = "application/octet-stream", $name = '')
-{
- if ($name == '')
- $name = 'Attachment' . (count($this->attachments) + 1);
-
- $cid = md5(uniqid(rand()));
- $this->attachments[] = array ('mimetype' => $mimetype, 'data' => $data, 'encode' => $encode, 'name' => $name, 'cid' => $cid);
-
- return 'cid:'.$cid;
-}
-
-
-/**
- * Add file attachment to this email message. Can be called repeatedly.
- * @param $filename File to be attached
- * @param $name Name of attached file as stored in mail
- * @param $mimetype MIME-Type of attached file
- */
-function add_file($filename, $mimetype = "application/octet-stream", $name = '')
-{
- if ($name == '')
- $name = basename($filename);
-
- if ($file = @fopen($filename, "r"))
- {
- if ($data = fread($file, @filesize($filename)))
- $result = $this->add_attachment($data, $mimetype, $name);
-
- fclose($file);
- }
-
- return $result;
-}
-
-
-/**
- * Send this email message
- * @return True if mail was sent
- */
-function send()
-{
- $to = join(",", $this->to);
- $headers = array();
-
- if (count($this->cc) > 0)
- $headers[] = "Cc: " . join(",", $this->cc);
-
- if (count($this->bcc) > 0)
- $headers[] = "Bcc: " . join(",", $this->bcc);
-
- for ($i = 0; $i < count($this->header_names); $i++)
- $headers[] = $this->header_names[$i] . ': ' . $this->header_values[$i];
-
-
- /* Automatically add doctype if none given */
- if ($this->body[IT_MAIL_HTML] && !eregi('^<!doctype', $this->body[IT_MAIL_HTML]))
- {
- $this->body[IT_MAIL_HTML] = '<!doctype html public "-//w3c//dtd html 4.01 transitional//en">' . "\n" . $this->body[IT_MAIL_HTML];
- }
-
-
- $headers[] = "MIME-Version: 1.0";
-
- if ($this->attachments)
- {
- /* Attachments need multipart MIME mail */
- $boundary1 = md5(uniqid(rand()));
- $mixedtype = "Content-Type: multipart/mixed; boundary=\"$boundary1\"";
-
- $headers[] = $mixedtype;
- $text .= "This is a multi-part message in MIME format.";
- $text .= "\n--$boundary1\n";
- }
-
- /* Headers for plain and HTML content */
- $plaintype = "Content-Type: text/plain; charset=".$this->charset."\nContent-Transfer-Encoding: 8bit";
- $htmltype = "Content-Type: text/html; charset=".$this->charset."\nContent-Transfer-Encoding: 8bit";
-
- if ($this->body[IT_MAIL_PLAIN])
- {
- if ($this->body[IT_MAIL_HTML])
- {
- $boundary2 = md5(uniqid(rand()));
- $alternativetype = "Content-Type: multipart/alternative; boundary=\"$boundary2\"";
-
- /* Plain and HTML */
- if ($this->attachments)
- $text .= "$alternativetype\n\n";
- else
- $headers[] = $alternativetype;
-
- $text .= "--$boundary2\n$plaintype\n\n";
- $text .= $this->body[IT_MAIL_PLAIN];
- $text .= "\n--$boundary2\n$htmltype\n\n";
- $text .= $this->body[IT_MAIL_HTML];
- $text .= "\n--$boundary2--\n";
- }
- else
- {
- /* Just plain */
- if ($this->attachments)
- $text .= "$plaintype\n\n";
- else
- $headers[] = $plaintype;
-
- $text .= $this->body[IT_MAIL_PLAIN];
- }
- }
- else if ($this->body[IT_MAIL_HTML])
- {
- /* Just HTML */
- if ($this->attachments)
- {
- if (strstr($this->body[IT_MAIL_HTML], "cid:"))
- {
- $boundary3 = md5(uniqid(rand()));
- $text .= "Content-Type: multipart/related; boundary=\"$boundary3\"\n\n--$boundary3\n";
- }
-
- $text .= "$htmltype\n\n";
- }
- else
- $headers[] = $htmltype;
-
- $text .= $this->body[IT_MAIL_HTML];
- }
-
- if ($this->attachments)
- {
- $text .= "\n";
- $boundary = $boundary3 ? $boundary3 : $boundary1;
-
- foreach ($this->attachments as $attachment)
- {
- $text .= "\n--$boundary\nContent-Type: {$attachment['mimetype']}; name=\"{$attachment['name']}\"\nContent-Transfer-Encoding: base64\nContent-ID: <{$attachment['cid']}>\nContent-Disposition: inline; filename=\"{$attachment['name']}\"\n\n";
- $text .= chunk_split(base64_encode($attachment['data']));
- }
-
- if ($boundary3)
- $text .= "\n--$boundary3--\n\n";
-
- $text .= "--$boundary1--\n";
- }
-
- return mail($to, $this->subject, $text, join("\n", $headers), $this->flags);
-}
-
-
-/**
- * INTERNAL: Escape header line with ?=iso-8859-1? if necessary, e.g. in Subject line
- * @param $string String to be escaped
- * @return String escape suitable for sending in header line
- */
-function header_escape($string)
-{
- return preg_replace('/[\x80-\xff]/e', "sprintf('=?iso-8859-1?Q?=%02X?=', ord('\\0'))", $string);
-}
-
-/**
- * Make string safe to be used in "$fullname <$email>": Remove illegal
- * characters and enclose in double quotes.
- * @param $string Fulle name to be escaped
- * @return String to be safely used in "$fullname <$email>" for To: etc.
- */
-function fullname_escape($string)
-{
- return '"' . preg_replace('/["\x00-\x1f]/', '', $string) . '"';
-}
-
-/**
- * INTERNAL: Send SMTP command and return true if result is 2XX
- * @param $fp Connection to SMTP server opened using fsockopen
- * @param $command Command to send, e.g. HELO gna.ch
- * @param $anwer String containing full answer from SMTP server
- * @param timeoutok Whether a timeout is considered ok
- * @param $failcode Lowest SMTP result code which is considered a failure (default 300)
- * @return True if SMTP result code is lower than $failcode
- *
- */
-function send_smtp_cmd($fp, $cmd, &$answer, $timeoutok = false, $failcode = 300)
-{
- $result = false;
- $answer = '';
-
- if (!$cmd || (!feof($fp) && fwrite($fp, "$cmd\r\n")))
- {
- while (!feof($fp) && ereg('^(...)(.?)(.*)$', fgets($fp, 1024), $regs))
- {
- $answer .= $regs[0];
- $resultcode = intval($regs[1]);
-
- if ($regs[2] != '-') /* Multi line response? */
- {
- if (($resultcode >= 100) && ($resultcode < $failcode))
- $result = true;
-
- break;
- }
- }
- }
-
- /* A timeout can be considered ok for SLOW mail servers */
- if ($answer == '')
- $result = $timeoutok;
-
- //echo ">>it_mail::send_smtp_cmd " . time() . " '$cmd' => $result: $answer";
-
- return $result;
-}
-
-
-/**
- * Check if given email address is valid (syntax, MX record). If you set
- * checkmailbox to true it also connects to MX and asks if mailbox is valid.
- * Note: Connecting to the MX can be slow.
- * @param $email email to be check
- * @param $checkmailbox True if you want to connect to MX and check account
- * @return One of IT_MAIL_CHECKEMAIL_INVALID (0), IT_MAIL_CHECKEMAIL_MAILBOXFULL
- * or IT_MAIL_CHECKEMAIL_OK (both != 0).
- */
-function check_email($email, $checkmailbox = true)
-{
- $result = IT_MAIL_CHECKEMAIL_INVALID;
-
- /* Check if username starts with www. or not well-formed => reject */
- if (!ereg('^www\.', $email) && eregi('^[a-z0-9&_+.-]+@([a-z0-9.-]+\.[a-z]+)$', $email, $regs))
- {
- $domain = $regs[1];
-
- if (!getmxrr($domain, $mxhosts, $weights))
- {
- /* If we find no MX we check if domain exists */
- if (gethostbynamel($domain))
- {
- $mxhosts = array($domain);
- $weights = array(1);
- }
- }
-
- if ($mxhosts) /* We need at least one valid MX */
- {
- if ($checkmailbox)
- {
- $mx = array();
-
- for ($i = 0; $i < count($mxhosts); $i++)
- $mx[$mxhosts[$i]] = $weights[$i];
-
- asort($mx, SORT_NUMERIC);
- $port = getservbyname('smtp', 'tcp');
- $from = 'itools@gna.ch';
-
- /* Determine domain and email for test, skip if called as it_mail::check_email() */
- if (is_object($this))
- {
- for ($i = 0; $i < count($this->header_names); $i++)
- {
- if ($this->header_names[$i] == 'From')
- {
- $from = $this->header_values[$i];
- break;
- }
- }
- }
-
- if (eregi('@([a-z0-9.-]+\.[a-z]+)$', $from, $regs))
- $fromdomain = $regs[1];
- else
- $fromdomain = 'gna.ch';
-
- $finished = false;
- $connected = 0;
-
- if (function_exists('stream_set_timeout'))
- $timeout = 'stream_set_timeout';
- else
- $timeout = 'socket_set_timeout';
-
- foreach ($mx as $mxhost => $weight)
- {
- //echo ">>it_mail::check_email: " . time() . " checking $mxhost\n";
- if ($fp = @fsockopen($mxhost, $port, $errno, $errstr, 5))
- {
- $connected++;
- $timeout($fp, 45);
- $answer = '';
-
- if (it_mail::send_smtp_cmd($fp, '', $answer) && it_mail::send_smtp_cmd($fp, "HELO $fromdomain", $answer) && it_mail::send_smtp_cmd($fp, "MAIL FROM: <$from>", $answer))
- {
- $timeout($fp, 2);
- $timeoutok = ($domain != 'bluewin.ch');
-
- if (it_mail::send_smtp_cmd($fp, "RCPT TO: <$email>", $answer, $timeoutok, 500)) # 450 is often used for Greylisting
- $result = IT_MAIL_CHECKEMAIL_OK;
- else if (eregi('quota|full|exceeded storage', $answer))
- $result = IT_MAIL_CHECKEMAIL_MAILBOXFULL;
-
- /* Do not try other MX if we got this far */
- $finished = true;
- }
-
- $timeout($fp, 0, 1);
-
- it_mail::send_smtp_cmd($fp, 'RSET', $answer);
-
- it_mail::send_smtp_cmd($fp, 'QUIT', $answer);
- fclose($fp);
- }
-
- if ($finished)
- break;
- }
-
- /* If we cannot connect to _any_ MX it could be because of temporary overload / virus attack */
- if (!$connected)
- $result = IT_MAIL_CHECKEMAIL_OK;
- }
- else
- $result = IT_MAIL_CHECKEMAIL_OK;
- }
- }
-
- return $result;
-}
-
-}
-
-?>