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: [email protected]/nReply-To: [email protected]/n" ;
mail("[email protected]", $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() {} } ?>