作者 主題: 請問最簡單的webmail  (閱讀 650 次)

0 會員 與 3 訪客 正在閱讀本文。

dark

  • 俺是博士!
  • *****
  • 文章數: 1566
    • 檢視個人資料
請問最簡單的webmail
« 於: 2018-11-08 09:59 »
小弟只想要一個簡單的 webmail 瀏覽
1. 有個下拉式選單列出當前目錄的 mailbox (/var/spool/mail/)
2. 選擇後看每封信內容
3. 能指令列呼叫 php://stdin

偏偏搜尋都是走 imap , 沒有只看 local 端單純解 mailbox 的

不知有沒有哪位大大知道什麼 php 套件如此簡單
或告知使用過最簡單的是哪個 ?


謝謝!!

hoyo

  • 榮譽博士
  • 俺是博士!
  • *****
  • 文章數: 4043
  • 性別: 男
  • 有需要的時候,學習就不會分階段。
    • 檢視個人資料
    • 樂咖黑電腦學習網
Re: 請問最簡單的webmail
« 回覆 #1 於: 2018-11-08 13:24 »
我自己做了一個 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
受人與魚,不如授人與漁
上海自來水來自海上;倫敦好奇人奇好敦倫

hoyo

  • 榮譽博士
  • 俺是博士!
  • *****
  • 文章數: 4043
  • 性別: 男
  • 有需要的時候,學習就不會分階段。
    • 檢視個人資料
    • 樂咖黑電腦學習網
Re: 請問最簡單的webmail
« 回覆 #2 於: 2018-11-08 13:45 »
如果要直接解讀 /var/spool/mail 內檔案可能會有點困難

因為那是一個單大容量文字檔,信件都放在一起,讀入檔案再進行切割解讀信件應該是一件很耗硬體資源的事情

我無聊的時候寫個 php 測試看看
受人與魚,不如授人與漁
上海自來水來自海上;倫敦好奇人奇好敦倫

hoyo

  • 榮譽博士
  • 俺是博士!
  • *****
  • 文章數: 4043
  • 性別: 男
  • 有需要的時候,學習就不會分階段。
    • 檢視個人資料
    • 樂咖黑電腦學習網
Re: 請問最簡單的webmail
« 回覆 #3 於: 2018-11-08 13:58 »
藉由網頁透過 php 讀取 /var/spool/mail 是不可行的,除非把檔案權限設定成開放讀取

預設應該是 660 的 mail 權限, apache 並無法讀取檔案

不過如果撇開權限決心硬幹的話  那有進一步的成果再分享
受人與魚,不如授人與漁
上海自來水來自海上;倫敦好奇人奇好敦倫

hoyo

  • 榮譽博士
  • 俺是博士!
  • *****
  • 文章數: 4043
  • 性別: 男
  • 有需要的時候,學習就不會分階段。
    • 檢視個人資料
    • 樂咖黑電腦學習網
Re: 請問最簡單的webmail
« 回覆 #4 於: 2018-11-08 14:17 »
https://github.com/pugong/phabricator/tree/master/externals/mimemailparser

使用 php parse mail Google 就可以找到已經寫好的套件了

不過問題一樣,要先自己打開檔案讀取權限
受人與魚,不如授人與漁
上海自來水來自海上;倫敦好奇人奇好敦倫

hoyo

  • 榮譽博士
  • 俺是博士!
  • *****
  • 文章數: 4043
  • 性別: 男
  • 有需要的時候,學習就不會分階段。
    • 檢視個人資料
    • 樂咖黑電腦學習網
Re: 請問最簡單的webmail
« 回覆 #5 於: 2018-11-08 14:26 »
代碼: [選擇]
<?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]);
        }
    }
}

把這個程式碼丟在網站內讀讀看  可以的話就是可以使用了
受人與魚,不如授人與漁
上海自來水來自海上;倫敦好奇人奇好敦倫

dark

  • 俺是博士!
  • *****
  • 文章數: 1566
    • 檢視個人資料
Re: 請問最簡單的webmail
« 回覆 #6 於: 2018-11-09 13:08 »
感謝 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

hoyo

  • 榮譽博士
  • 俺是博士!
  • *****
  • 文章數: 4043
  • 性別: 男
  • 有需要的時候,學習就不會分階段。
    • 檢視個人資料
    • 樂咖黑電腦學習網
Re: 請問最簡單的webmail
« 回覆 #7 於: 2018-11-09 14:13 »
才發現 win7 後不支援 outlook 之類的讀郵件程式 ...

1. Mozilla Thunderbird
2. windows live mail 2012 (https://www.mobile01.com/topicdetail.php?f=511&t=5083767)
受人與魚,不如授人與漁
上海自來水來自海上;倫敦好奇人奇好敦倫

netman

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 17393
    • 檢視個人資料
    • http://www.study-area.org
Re: 請問最簡單的webmail
« 回覆 #8 於: 2018-11-09 17:04 »
如果要直接解讀 /var/spool/mail 內檔案可能會有點困難

因為那是一個單大容量文字檔,信件都放在一起,讀入檔案再進行切割解讀信件應該是一件很耗硬體資源的事情

我無聊的時候寫個 php 測試看看

換成 maildir 會不會好些?

hoyo

  • 榮譽博士
  • 俺是博士!
  • *****
  • 文章數: 4043
  • 性別: 男
  • 有需要的時候,學習就不會分階段。
    • 檢視個人資料
    • 樂咖黑電腦學習網
Re: 請問最簡單的webmail
« 回覆 #9 於: 2018-11-09 17:27 »
如果要直接解讀 /var/spool/mail 內檔案可能會有點困難

因為那是一個單大容量文字檔,信件都放在一起,讀入檔案再進行切割解讀信件應該是一件很耗硬體資源的事情

我無聊的時候寫個 php 測試看看

換成 maildir 會不會好些?

如果已經是 maildir 架構, dark 兄就不會有這個問題了

郵件已經分成一對一檔案,要讀取相對容易些
受人與魚,不如授人與漁
上海自來水來自海上;倫敦好奇人奇好敦倫

hoyo

  • 榮譽博士
  • 俺是博士!
  • *****
  • 文章數: 4043
  • 性別: 男
  • 有需要的時候,學習就不會分階段。
    • 檢視個人資料
    • 樂咖黑電腦學習網
Re: 請問最簡單的webmail
« 回覆 #10 於: 2018-11-09 18:00 »
不過 maildir 對於程式的記憶體處理並沒有帶來優勢,還是需要把所有的檔案讀入才可以進行解析

解析後才可以讀出信件主旨,如此才可正確選到想讀取的信件
受人與魚,不如授人與漁
上海自來水來自海上;倫敦好奇人奇好敦倫

dark

  • 俺是博士!
  • *****
  • 文章數: 1566
    • 檢視個人資料
Re: 請問最簡單的webmail
« 回覆 #11 於: 2018-11-10 13:55 »
切開 mail 雖然看了 formail 指令可以用
但還是沒有切
大多使用 bash 指令即可完成抓出指定信件跟刪除信件

目前如附件 ..
將信件複製到 index.php 旁邊的 mailboxs 資料夾就能看

讀信只轉一次 mime , 看來還須看看是否有較完整套件能用

抓信部分算是差不多了 , 剛剛發現一個 bug
mailbox 信件太少時 , 移到最後一封 , 算出不出數量超過還 ajax

先休息一下 , 小睡後再來看了 ... 看來真的老了


不過有個問題 ..
裡面有個 php function maillistformat()
若將陣列傳入 , 陣列中的中文都會變問號
百思不得其解 , 只好搬出來重複貼上執行

asako

  • 活潑的大學生
  • ***
  • 文章數: 235
    • 檢視個人資料

hoyo

  • 榮譽博士
  • 俺是博士!
  • *****
  • 文章數: 4043
  • 性別: 男
  • 有需要的時候,學習就不會分階段。
    • 檢視個人資料
    • 樂咖黑電腦學習網
Re: 請問最簡單的webmail
« 回覆 #13 於: 2018-11-13 09:48 »
代碼: [選擇]
<?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($handle4096)) != 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) >=){
        
$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($handle4096)) != 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) >=){
        
$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 繼續解析即可
受人與魚,不如授人與漁
上海自來水來自海上;倫敦好奇人奇好敦倫

hoyo

  • 榮譽博士
  • 俺是博士!
  • *****
  • 文章數: 4043
  • 性別: 男
  • 有需要的時候,學習就不會分階段。
    • 檢視個人資料
    • 樂咖黑電腦學習網
Re: 請問最簡單的webmail
« 回覆 #14 於: 2018-11-13 09:52 »
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 的人少了,所以相關資訊及文件相對就少了
受人與魚,不如授人與漁
上海自來水來自海上;倫敦好奇人奇好敦倫

asako

  • 活潑的大學生
  • ***
  • 文章數: 235
    • 檢視個人資料
Re: 請問最簡單的webmail
« 回覆 #15 於: 2018-11-13 16:36 »
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 的人少了,所以相關資訊及文件相對就少了

我比較喜歡用別人的輪子,不合再改輪子