1. Using Common way to send mail
=====================================================================
PHP调用qmail的控制程序
在Linux环境中,每一个程序都有相应的用户和组的概念。PHP程序在服务器中执行时,默认的用户是nobody,没有权利执行qmail的控制程序。在Linux里面有个sudo命令,允许其它用户以root身份执行一些命令。修改/etc/sudoers文件,增加以下部分:
--------------------------------------------------------------------------------
nobody ALL=/var/vpopmail/bin/vadduser (增加用户)
nobody ALL=/var/vpopmail/bin/vdeluser (删除用户)
nobody ALL=/var/vpopmail/bin/vpasswd (修改口令)
nobody ALL=/var/vpopmail/bin/vchkpw (检查用户口令是否正确)
nobody ALL=/var/vpopmail/bin/vsetuserquota (修改邮箱最大容量)
nobody ALL=/var/vpopmail/bin/vmoduser (修改用户信息)
root ALL=(ALL) ALL
--------------------------------------------------------------------------------
在调用qmail控制程序时,需要用户手工输入一部分信息。如果要实现自动化,还需要使用Linux中的重定向技术,将用户预先输入的信息存放到文件中,使用重定向技术传递为Shell脚本。
PHP提供执行外部命令的函数为system()、exec()。system()函数执行给定的命令、输出和返回结果。exec()函数与system()类似,但不输出结果。使用程序控制必须选用exec()函数,并根据执行后的状态来确定控制程序是否正确执行,如果出现错误需要向邮件管理员通告。下面代码以“增加用户”功能为例进行说明:
--------------------------------------------------------------------------------
require("/home/httpd/phplib/qmail.inc");
$qmail_date = "v1";
$qmail_email = new register_email ;
$sql = "select pw_name from ".$qmail_date;
$qmail_email->query($sql);
while ($qmail_email->next_record())
{
$qmail_user = $qmail_email->f("pw_name");
$passwd = "12345";
$str_command = "sudo /var/vpopmail/bin/vadduser " .$qmail_user.;
$str_command = $str_command."@mail.com".$passwd." -q 10000000 /home/n";
@exec($str_command,$str,&$result);
if ($result != 0 )
{
echo "command string is :".$str_command." , command is failed!!!<br>";
$error_info = "在执行vadduser命令时失败";
$address = "From: computer@mail.com/nReply-To: computer@mail.com/n" ;
mail("webmaster@mail.com", $error_info , $message,$address );
}
}
$qmail_email->free();
--------------------------------------------------------------------------------
其它功能如修改口令、修改邮箱容量、删除邮箱等,在程序实现上非常类似,不做过多阐述。
E-mail中附件的上传及下载
PHP本身提供上载功能,但根据实际情况,可以相应做一些配置和错误处理。用户可以通过修改php.ini文件来扩大上载文件的最大容量。同时,可以通过在网页的Form中增加的方法,将单个附件的大小限制在5MB以内。如果网络速度比较慢,则需要设置网页的timeout变量,否则上载时会因为时间太长而超时。在服务器端的处理程序部分代码如下:
--------------------------------------------------------------------------------
if (!file_exists($mail_att)) //判断文件是否上载成功
{ //错误处理及显示
break ;
}
copy ($mail_att, $mail_att.".att") ; //将附件重新改名并拷贝到指定位置。
for ($i = 1; $i <= $num_attach; $i++)
{
$file_name = "send_att".$i; //得到上传文件的原始名称
$file_tmp = "send_att_tmp".$i; //得到上传文件在服务器中的临时文件名称
$file_size = "send_att_size".$i; //得到上传文件的大小
$file_mime = "send_att_mime".$i; //得到上传文件的类型
}
--------------------------------------------------------------------------------
在提供附件下载时,这里没有采用常用做法,即给用户提供文件的URL。因为这种做法理论上并不安全,用户有可能通过链接直接下载到该文件。相反,从浏览器无法访问到的目录下读出文件提供给用户下载,就不会遇到类似安全问题。程序核心代码如下:
--------------------------------------------------------------------------------
if (file_exists($attach_filepos)) //判断文件是否存在
{
$size = filesize($attach_filepos); //得到文件的大小
//将用户原始文件名提供给用户下载。
header("Content-Disposition: attachment; filename=".$attach_filename);
header("Content-length: ".$size);
header("Content-type: application/x-zip-compressed");
readfile($attach_filepos); //将下载文件读出,提供给用户下载。
}
--------------------------------------------------------------------------------
2. Using qMail-mySQL Handling-Class
<?
/*
* Include the HandlingClass
*/
require './includes/classes/qmail-mysql.class.php';
/*
* Initializing qMail-mySQL Class
*/
$qmail = new qmail_handler;
/*
* Username & Password for User
*/
$qmail->username = $user;
$qmail->password = $pass;
/*
* Default users homedir
*/
$qmail->homedir = "/var/qmail/users"; // can be different..
$qmail->mboxhost = "your-mail-domain.com"; // your mx-domain
$qmail->uid = 501; // uid of apache
$qmail->gid = 501; // gid of apache
$qmail->pid = ""; // not used
$qmail->quota_size = 10240; // standard quota-size ("" means unlimited).
/*
* initialize qmail-mysql-database
*/
$qmail->db_initialize();
/*
* checking user $qmail->username
* with password $qmail->password
*/
$qmailauthed = $qmail->db_checkuser();
if ($qmailauthed) {
/*
* fetching maildir-content
*/
// mails in users mailbox..
$mailboxcount = $qmail->mailbox_count();
// size of users mailbox (bytes)
$mailboxsize = $qmail->mailbox_size();
// email-headers
$mails_in = $qmail->mailbox_scan();
/*
* sample output in format:
*
* new | from | date | subject | size
* ----+--------------+----------------------+--------------------+------------
* y/n | foo bar | dd.mm.yyyy, hh:mm:ss | mailsubject | 8,50 kb
*
*/
echo "<table border=\"0\" cellpadding=\"3\" cellspacing=\"1\">";
echo "<tr bgcolor=\"#eeeeee\">";
echo "<td>New:</td>";
echo "<td>From:</td>";
echo "<td>Date:</td>";
echo "<td>Subject:</td>";
echo "<td>Size:</td>";
echo "</tr>";
// walking through header-array $mails_in
for ($i=0;$i<sizeof($mails_in);$i++) {
if($i%2==0)
echo "<tr bgcolor=\"#ffffff\">";
else
echo "<tr bgcolor=\"#eeeeee\">";
if ($mails_in[$i]["Status"] == "") { $new = 1; }
else { $new = 0; }
// state
echo "<td>".$new."</td>";
// from
echo "<td>".$mails_in[$i]["From"]."</td>";
// date ( $mails_inc[$i]["Date"] == unix-timestamp )
$maildate = $mails_in[$i]["Date"];
echo "<td>".strftime("%d.%m.%Y, %H:%M:%S",$maildate)."</td>";
// subject
echo "<td>".$mails_in[$i]["Subject"]."</td>";
// mailsize
$mailsize["byte"] = number_format($mails_in[$i]["Size"],2,",",".");
$mailsize["kilobyte"] = number_format($mailsize["byte"]/1024,2,",",".");
echo "<td>".$mailsize["kilobyte"]." kb</td>";
echo "</tr>";
}
echo "</table>";
?>
class qmail_handler
{
var $homedir;
var $maildir = "Maildir/"; // works only with "./Maildir/", not with "./Mailbox"
var $mailbox;
var $username;
var $password;
var $quota_size;
var $mboxhost;
var $uid;
var $gid;
var $pid;
var $crypt_seed = "ItsMyFooSeed";
// database
var $dbhostname = "127.0.0.1";
var $dbusername = "happystrip";
var $dbpassword = "";
var $dbname = "qmail";
/* db_initialize */
function db_initialize() {
// connecting to mysql-db
mysql_connect($this->dbhostname,$this->dbusername,$this->dbpassword);
mysql_select_db($this->dbname);
}
/* db_checkuser */
function db_checkuser() {
$qu = "SELECT id,passwd,home,quota_size,active FROM qmailpasswd WHERE id = '$this->username'
AND passwd = '$this->password' AND mbox_host = '$this->mboxhost'";
$rs = mysql_query($qu) or die("database-error");
$rc = mysql_num_rows($rs);
if (!$rc) {
return 0;
} else {
list($id,$passwd,$home,$quota_size,$active) = mysql_fetch_row($rs);
if ($active == "Y") {
$this->mailbox = $home."/".$this->maildir."new/";
$this->quota_size = $quota_size;
return 1;
} else {
return 0;
}
}
}
/* maildirmake */
function maildirmake() {
$home = $this->homedir."/".$this->username;
// adding maildir
if(!file_exists($home)) {
exec("/bin/mkdir $home",$results,$errorcode0);
// maildir mit maildirmake anlegen
exec("/var/qmail/bin/maildirmake $home/Maildir",$results,$errorcode1);
// forwarder datei ".qmail" anlegen
exec("echo \"./Maildir/\" > $home/.qmail",$results,$errorcode2);
// permissions
exec("chmod -R 0700 $home/Maildir",$results,$errorcode3);
exec("chmod 0755 $home/.",$results,$errorcode4);
exec("chmod 0644 $home/.qmail",$results,$errorcode5);
if ($errorcode0 == 1 ||
$errorcode1 == 1 ||
$errorcode2 == 1 ||
$errorcode3 == 1 ||
$errorcode4 == 1 ||
$errorcode5 == 1 ){
return false;
} else {
return true;
}
}
}
/* GetMailInfo */
function GetMailInfo($filename) {
// add filesize to array
$content["Size"] = filesize($filename);
// checking for errors in access-mode
if (!is_readable($filename)) { return ERR_ACCESS; }
// open file-pointer
$fp = fopen($filename,"r");
$i = 0;
while (!feof ($fp)) {
$buffer = fgets($fp, 4096);
if (!isset($nextisbody)) {
$pos_one = strpos($buffer, ":");
$content_left = trim(substr($buffer,0,$pos_one));
$content_right = trim(substr($buffer,$pos_one+1,strlen($buffer)-$pos_one));
if (is_string($content_left) && is_string($content_right) && trim($buffer) != "") {
if ($content_left == "Date") {
$content["$content_left"] = strtotime("$content_right");
} else {
$content["$content_left"] = htmlspecialchars($content_right);
}
} elseif(trim($buffer) == "") {
// the next line is the mail-body
$nextisbody = 1;
}
} else {
// it's the body ;-)
$content["Body"] .= htmlspecialchars($buffer);
}
}
fclose($fp);
return $content;
}
/* MAILBOX_ADD */
function mailbox_add(){
$mboxhost = $this->mboxhost;
$pass_crypted = crypt($this->password,$this->crypt_seed);
$pass_ncrypted = $this->password;
$home = $this->homedir."/".$this->username;
$qu = "
INSERT INTO qmailpasswd
(
id,
mbox_host,
crypt,
passwd,
uid,
gid,
shell,
home,
start_date,
expire_date,
active,
quota_size
)
VALUES (
'$this->username',
'$this->mboxhost',
'$pass_crypted',
'$pass_ncrypted',
'$this->uid',
'$this->gid',
'/bin/false',
'$home',
'2000-01-01',
'2090-01-01',
'Y',
'$this->quota_size',
'$this->pid'
)
";
$rs = mysql_query($qu) or die("Database-Error - \"function mailbox_add()\"");
if (!$rs) {
return false;
} else {
return true;
}
}
/* MAILBOX_SCAN */
function mailbox_scan() {
// "new"-box in users maildir.
$mailbox = $this->mailbox;
// list directory
exec("ls $mailbox",$results,$errcode);
// checking for errors.
if ($errorcode) return 0;
// looping folder-content and fetch informations with GetMailInfo()
$i=0;
while(list(,$filename) = each($results)){
$returnvalue[$i] = $this->GetMailInfo($mailbox.$filename);
$i++;
}
$i=0;
return $returnvalue;
}
/* MAILBOX_COUNT */
function mailbox_count() {
$mailbox = $this->mailbox;
exec("ls $mailbox",$results,$errcode);
return sizeof($results);
}
/* MAILBOX_SIZE */
function mailbox_size() {
$mailbox = $this->mailbox;
exec("du -ks $mailbox",$result,$error);
list(,$tmp) = each($result);
$return = explode("/",trim($tmp));
$return = $return[0];
return $return;
}
/*
* NOT YET IMPLEMENTED
*/
/* MAIL_INJECT */
function mail_inject($subject,$message,$header){}
/* MAIL_DELETE */
function mail_delete($index = 0){}
/* MAIL_CHSTATE */
function mail_chstate() {}
}
?>