酷!學園
技術討論區 => Linux 討論版 => 主題作者是: dark 於 2018-11-08 09:59
-
小弟只想要一個簡單的 webmail 瀏覽
1. 有個下拉式選單列出當前目錄的 mailbox (/var/spool/mail/)
2. 選擇後看每封信內容
3. 能指令列呼叫 php://stdin
偏偏搜尋都是走 imap , 沒有只看 local 端單純解 mailbox 的
不知有沒有哪位大大知道什麼 php 套件如此簡單
或告知使用過最簡單的是哪個 ?
謝謝!!
-
我自己做了一個 webmail , 本來的用途是免費限時收信的 webmail ,後來自己寫著寫著忽然覺得發現了什麼就往正式的 mail 系統開發
https://hoyo.idv.tw/wm/
使用 PHP MySQL ,帳號、信件全部存在資料庫,收信直接使用網頁,不支援 imap 和 pop3 (哈哈哈)
---
正式的資料還沒整理完全
https://blog.hoyo.idv.tw/?p=4774
可以使用 postfix mysql Google 或是先參考下面幾個網址
https://wiki.gentoo.org/wiki/Complete_Virtual_Mail_Server/Postfix_to_Database
https://serverfault.com/questions/722137/how-to-specify-target-directory-in-postfix-with-mysql
---
有興趣的人如果多就找時間說一場,如果還是小眾就等小弟的資料或努力 Google 吧 = =a
-
如果要直接解讀 /var/spool/mail 內檔案可能會有點困難
因為那是一個單大容量文字檔,信件都放在一起,讀入檔案再進行切割解讀信件應該是一件很耗硬體資源的事情
我無聊的時候寫個 php 測試看看
-
藉由網頁透過 php 讀取 /var/spool/mail 是不可行的,除非把檔案權限設定成開放讀取
預設應該是 660 的 mail 權限, apache 並無法讀取檔案
不過如果撇開權限決心硬幹的話 那有進一步的成果再分享
-
https://github.com/pugong/phabricator/tree/master/externals/mimemailparser
使用 php parse mail Google 就可以找到已經寫好的套件了
不過問題一樣,要先自己打開檔案讀取權限
-
<?php
ini_set('display_errors',true);
ini_set('error_reporting',E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED);
const path = '/var/spool/mail';
$users = scandir(path);
foreach( $users as $k=>$user ){
if ( $user !='.' && $user !='..' ){
echo $user;
$mime = mailparse_msg_parse_file(path .'/'. $user);
$structure = mailparse_msg_get_structure($mime);
$parts = array();
foreach($structure as $part_id) {
$part = mailparse_msg_get_part($mime, $part_id);
$parts[$part_id] = mailparse_msg_get_part_data($part);
print_r($parts[$part_id]);
}
}
}
把這個程式碼丟在網站內讀讀看 可以的話就是可以使用了
-
感謝 hoyo 大回覆 ..
小弟抓下來測試 , 但 debug 了四五次後放棄
準備自己寫看看 ...
等等若遇到問題 , 再上來問嚕 ...
小弟之前的做法很簡單
架構是 ..
hotmail 郵件規則轉寄回來給 root -> 最前面那台 gw 只收 ms 公佈的 outlook 主機 IP
-> 內部我常用的 linux 會定時將 gw 上 mail 複製回來並刪除
-> 有 url 抓出來 , 遇到 mime => base64 -d 再抓 url
-> curl 把連結都點完 -> 刪除
其實我不看 mail 的 , 目前是想轉寄一些還不知道規則的持續觀察
才發現 win7 後不支援 outlook 之類的讀郵件程式 ... 真是後知後覺得離譜
小弟內部這台 linux , httpd 編譯成可用 root ... 幾乎所有 deamon 都改成 root
-
才發現 win7 後不支援 outlook 之類的讀郵件程式 ...
1. Mozilla Thunderbird
2. windows live mail 2012 (https://www.mobile01.com/topicdetail.php?f=511&t=5083767)
-
如果要直接解讀 /var/spool/mail 內檔案可能會有點困難
因為那是一個單大容量文字檔,信件都放在一起,讀入檔案再進行切割解讀信件應該是一件很耗硬體資源的事情
我無聊的時候寫個 php 測試看看
換成 maildir 會不會好些?
-
如果要直接解讀 /var/spool/mail 內檔案可能會有點困難
因為那是一個單大容量文字檔,信件都放在一起,讀入檔案再進行切割解讀信件應該是一件很耗硬體資源的事情
我無聊的時候寫個 php 測試看看
換成 maildir 會不會好些?
如果已經是 maildir 架構, dark 兄就不會有這個問題了
郵件已經分成一對一檔案,要讀取相對容易些
-
不過 maildir 對於程式的記憶體處理並沒有帶來優勢,還是需要把所有的檔案讀入才可以進行解析
解析後才可以讀出信件主旨,如此才可正確選到想讀取的信件
-
切開 mail 雖然看了 formail 指令可以用
但還是沒有切
大多使用 bash 指令即可完成抓出指定信件跟刪除信件
目前如附件 ..
將信件複製到 index.php 旁邊的 mailboxs 資料夾就能看
讀信只轉一次 mime , 看來還須看看是否有較完整套件能用
抓信部分算是差不多了 , 剛剛發現一個 bug
mailbox 信件太少時 , 移到最後一封 , 算出不出數量超過還 ajax
先休息一下 , 小睡後再來看了 ... 看來真的老了
不過有個問題 ..
裡面有個 php function maillistformat()
若將陣列傳入 , 陣列中的中文都會變問號
百思不得其解 , 只好搬出來重複貼上執行
-
https://github.com/php-mime-mail-parser/php-mime-mail-parser 也許可用
-
<?php
ini_set('display_errors',true);
ini_set('error_reporting',E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED);
mb_internal_encoding('UTF-8');
const path = '/var/spool/mail';
$userArray = scandir(path);
$users =array();
foreach( $userArray as $k=>$user ){
if ( $user !='.' && $user !='..' ){
$users[] = $user;
}
}
// 選取了使用者信箱
if ( $_GET['a'] =='user' ) {
$mail = array();
$m = '';
$f = path .'/'. $_POST['user'];
$handle = @fopen($f, "r");
$mail = $body = array();
$i = -1;
if ($handle) {
$header = true;
while (($line = fgets($handle, 4096)) != false) {
if ( preg_match('/^From /', $line) ){
$header = true;
++$i;
$mail[$i] .= $line;
}
else{
if ( $header == true ) {
$mail[$i] .= $line;
}
else{
$body[$i] .= $line;
}
}
if ( preg_match('/^\n$/', $line) ) {
$header = false;
}
}
fclose($handle);
}
// 讀取單一信件
$m = array();
foreach( $mail as $k=>$v ){
// 將信件內容丟進 mailparse 進行解析
$mime = mailparse_msg_create();
mailparse_msg_parse($mime, $v);
// 讀取信件結構 -> header & body
$structure = mailparse_msg_get_structure($mime);
$parts = array();
foreach($structure as $part_id) {
$part = mailparse_msg_get_part($mime, $part_id);
$parts[$part_id] = mailparse_msg_get_part_data($part);
// 將信件結構存入陣列
$m[$k] = $parts[$part_id];
}
//print_r($m);
}
$mail = array();
foreach( $m as $k=>$v ){
$mail[$k]['subject'] = mb_decode_mimeheader($v['headers']['subject']);
}
if ( count($m) >=1 ){
$Return = array( 'Result'=>true, 'Data'=>$mail );
}
else {
$Return = array( 'Result'=>false );
}
echo json_encode($Return);
exit;
}
//
if ( $_GET['a'] =='mail' ) {
$mail = array();
$m = '';
$f = path .'/'. $_POST['user'];
$handle = @fopen($f, "r");
$mail = $body = array();
$i = -1;
if ($handle) {
$header = true;
while (($line = fgets($handle, 4096)) != false) {
if ( preg_match('/^From /', $line) ){
$header = true;
++$i;
$mail[$i] .= $line;
}
else{
if ( $header == true ) {
$mail[$i] .= $line;
}
else{
$body[$i] .= $line;
}
}
if ( preg_match('/^\n$/', $line) ) {
$header = false;
}
}
fclose($handle);
}
if ( count($m) >=1 ){
$Return = array( 'Result'=>true, 'Data'=>$body[$_POST['mail']] );
}
else {
$Return = array( 'Result'=>false );
}
echo json_encode($Return);
exit;
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width"/>
<title></title>
<style>
*{
font-size: 16px;
}
pre{
background-color: #eee;
border: 1px solid #aaa;
border-radius: 8px;
padding: 16px;
margin: 16px;
}
.box{
margin: 16px;
padding: 16px;
border-radius: 8px;
border: 1px solid #ddd;
}
</style>
</head>
<body>
<div class="box">
<label>選擇使用者帳號:
<select name="user" onchange="selectUser(this)">
<option value="">- 選擇信箱 -</option>
<?php foreach($users as $k=>$v){ ?>
<option value="<?php echo $v;?>"><?php echo $v;?></option>
<?php } ?>
</select>
</label>
</div>
<?php echo $_POST['user'];?>
<div class="box">
<label>選取信件:
<select name="mail" onchange="readMail(this)"></select>
</label>
</div>
<div>信件內容:</div>
<pre id="MailBody"></pre>
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script>
var user = '';
function selectUser(obj){
var $this = $(obj);
user = $this.val();
$.ajax({
url: '?a=user',
type: 'post',
data: {
user: $this.val()
},
dataType: 'json',
success: function(json){
var h = '<option value="">- 選擇信件 -</option>';
if ( json['Result'] ==true ){
$.each( json['Data'], function(k,v){
h += '<option value="'+ k +'">'+ v['subject'] +'</option>';
} );
}
$('[name="mail"]').html(h);
}
});
}
function readMail(obj){
var $this = $(obj);
$.ajax({
url: '?a=mail',
type: 'post',
data: {
user: user,
mail: $('[name="mail"]').val()
},
dataType: 'json',
success: function(json){
var h = '';
if ( json['Result'] ==true ){
h += json['Data'];
}
$('#MailBody').html(h);
}
});
}
</script>
</body>
</html>
獻上 hoyo 版本, MIME 格式郵件還沒繼續處理,需要的人把 mail 區段 $body 繼續解析即可
-
https://github.com/php-mime-mail-parser/php-mime-mail-parser 也許可用
目前流通的 PHP email parse 都有多多少少的問題,例如附件解析不出來或是該 base64 decode 卻沒有 decode
所以還是要自己拿 Mailparse libary 自己寫遇到問題才比較容易解決
http://php.net/manual/en/book.mailparse.php
只是問題出在最開始說的,Gmail 流行了,自己搞 Mail Server 的人少了,所以相關資訊及文件相對就少了
-
https://github.com/php-mime-mail-parser/php-mime-mail-parser 也許可用
目前流通的 PHP email parse 都有多多少少的問題,例如附件解析不出來或是該 base64 decode 卻沒有 decode
所以還是要自己拿 Mailparse libary 自己寫遇到問題才比較容易解決
http://php.net/manual/en/book.mailparse.php
只是問題出在最開始說的,Gmail 流行了,自己搞 Mail Server 的人少了,所以相關資訊及文件相對就少了
我比較喜歡用別人的輪子,不合再改輪子
-
感謝 hoyo 大的範例指點
兩位大大貼的 github 小弟之前試過都不行
早上用 hoyo 大的 , 仍然不行
由於 hoyo 大寫的簡單明瞭 , 於是照著模仿試寫
跳出了不支援 mailparse_msg_create 後
搞到剛剛才了解什麼是 php 擴充 ...
那兩個連結都有提到 pear 或 pecl
偏偏小弟就缺這麼重要的 php 常識 :'(
hoyo 大的程式已經可以 work 了
接下來細部的需求 , 小弟理當知道該怎麼做了
等寫完再貼上來請各位大大指點
-
現在的工作是專職寫程式,就培養寫出 「大家都看得懂」的程式 (不是優美或是精簡)
因為看不懂維護起來很慘 .....
-
報告 ... 已經算是寫完了
其實 11月底就完成 , 並測試使用一段時間
無奈家裡 switch 壞掉 , 等上線後又整理斷線時缺的資料
等等在分享利用 php 網空心得
------------
01. 只有一個檔案 index.php , 小圖標已 base64 內建
02. 用到 jquery (附件1.7.1 , 若要更高 , 請置換 index.php 內容)
03. 每封 mail 以 iframe 內容方式顯示 , 若附件為 mail 或 mailbox , 將 iframe/iframe/... 遞迴顯示 (故須留意資源)
04. 若 mail 是 text / html 並存 , 會同等級 iframe 顯示 (如圖) ... 一般應用程式會選擇系統環境擇一顯示
05. index.php 前幾行 ~ 抓信箱方法 , 參數可方便更改
06. 其中抓信箱方法只寫了 ssh 方式 , 所以若要 ftp / smbget 可加至 class toremote
07. 要連入的 ssh server 要關閉 sshd DNS 反解 , 不然動做會很久
08. index.php 只適合放 linux , 因為許多動做使用 exec("linux 指令")
09. ssh 抓信使用 sshpass
10. 功能頁中 : 抓信箱 , 本地複製信件信箱 , 本地移動信件信箱(未完成) , 重整信箱(未完成)
11. 只解析圖片檔 , mail 檔 , 其餘皆顯示下載
12. 沒用到的協定皆預留
ps ..
快寫完時 , 小弟才體會到 css 該定義 body
而底下要參照上層使用比例 ...
找免費網空時試了一下 , 應該以後就會養成習慣