ちょっとMSNメッセンジャー周辺で話題にでたので…
PHPでというか、uw-imapdでimapの添付メール(attachment)取得を行った場合に、生JISで添付ファイル名がつけられているものを正しく取り扱えない場合があります。というか、取り扱えません。uw-imapd自身が添付ファイル名部分のパースに失敗するためです。
[PHP-jp 12088]
#ほかの imapdの実装それぞれでどうだかは不明
で、解決策としてはimap_fetchbodyで全体分捕ってきて自前で解析するしかないということになります。最近のPEARライブラリには入ってるかもしれませんが…
function mail_Q_decode($str) {
$i = 0;
$l = strlen($str);
while ($i < $l) {
while ($str[$i] != '=' && $i < $l) {
$r .= $str[$i++];
}
if ($i == $l) break;
while ($str[$i] == '=' && $i < $l) {
$r .= chr($str[$i+1]*16+$str[$i+2]);
$i += 3;
}
if ($i >= $l) break;
}
return $r;
}
function mail_decode_BQ($s, $tocharset) {
while ($s) {
if (!is_string($idx = strpos($s, "=?")) || $idx) {
$sf = substr($s, 0, $idx);
$sr = substr($s, $idx +2);
if (!is_string($idy = strpos($sr, "?=")) || $idy) {
$sri = substr($sr, 0, $idy);
$srj = substr($sr, $idy +2);
// echo "sri=".$sri."\n";
// echo "srj=".$srj."\n";
$funcname = "stripslashes";
if (eregi('^Shift_jis(.*)\?([BQ])\?(.*)$', $sri, $bs)) {
$fromcode = "SJIS";
}else if (eregi('^iso-2022-jp(.*)\?([BQ])\?(.*)$', $sri, $bs)) {
$fromcode = "JIS";
}else if (eregi('^iso-8859-(.*)\?([BQ])\?(.*)$', $sri, $bs)) {
$fromcode = "pass";
}
if ($bs[2] == 'B') $funcname = "base64_decode";
if ($bs[2] == 'Q') $funcname = "mail_Q_decode";
$ts = i18n_convert($funcname($bs[3]), $tocharset, $fromcode);
}else{
// krudge;
$ts = $sri;
}
$r .= ($sf.$ts);
$s = $srj;
}else{
$r .= $s;
break;
}
}
return $r;
}
function mail_contenttype(&$p, &$types) {
while ((list($k, $v) = each($p)) && isset($v[0]) && $v[0]) {
// echo "d[".$k."]".$v."\n";
if ($v[0] == 'c' || $v[0] == 'C') {
if (eregi("^CONTENT-TYPE:(.*)", $v, $r)) {
$rf = ltrim($r[1]);
while((list($k, $v) = each($p)) && isset($v[0]) && (ereg("[ \011]", $v[0
]))){
// echo "C[".$k."]".$v."\n";
$rf .= ("\015\012".$v);
}
if (ereg("(^[-a-z/A-Z0-9]+)", $rf, $tp)) {
$types = $tp[1];
}
$rf = substr($rf, strpos($rf, ';', strlen($types)) + 1);
if (!isset($v[0]) || !$v[0]) {
// echo "f[".$k."]".$v."\n";
return $rf;
}
}
}
}
// echo "e[".$k."]".$v."\n";
return $rf;
}
function mail_parse_attr($rf) {
$ATTR = array();
if (!$rf) {
return;
}
$i = 0;
while( $i < strlen($rf)) {
while (ereg("[ \011\015\012]", $rf[$i])) $i++;
if ($i >= strlen($rf)) break;
$pa = "";
while (ereg("[-a-zA-Z0-9+]", $rf[$i])) {
$pa .= $rf[$i++];
if ($i >= strlen($rf)) break 2;
}
$pa = strtoupper($pa);
$ATTR[$pa] = "";
while (ereg("[ \011\015\012]", $rf[$i])) $i++;
if ($i >= strlen($rf)) break;
if ($rf[$i] == '=') $i++;
else if ($rf[$i] == ';') { $i++; continue;}
else {
break;
}
$va = "";
while (ereg("[ \011\015\012]", $rf[$i])) $i++;
if ($rf[$i] == chr(042)) {
$i++;
while ($rf[$i] != chr(042)) {
while ($rf[$i] == chr(033) && $rf[$i+1] == '$') {
$va .= "\033$";
$i += 2;
if ($i >= strlen($rf)) break 2;
while (("" != $rf[$i]) && $rf[$i] != chr(033)) {
$va .= $rf[$i];
$i++;
}
if ($i >= strlen($rf)) break 2;
if ($rf[$i] == chr(033) && $rf[$i+1] == chr(050)) {
$va .= "\033\050";
$i += 2;
}
if ($i >= strlen($rf)) break 2;
}
if ($rf[$i] == '\\') {
$i++;
$va .= $rf[$i];
$i++;
}
if ($i >= strlen($rf)) break;
if ($rf[$i] == chr(015)) {
while (ereg("[ \011\015\012]", $rf[$i])) $i++;
}
if ($i >= strlen($rf)) break;
if ($rf[$i] != chr(042)) {
$va .= $rf[$i];
$i++;
}
if ($i >= strlen($rf)) break;
}
$ATTR[$pa] = $va;
// echo "[".$va."]\n";
$i++;
}
}
return $ATTR;
}
function mail_parse_mime(&$p, $boundary, &$at, $lv) {
$lc = 0;
while (list($k, $v) = each($p)) {
// echo "[".$k."]".$v."\n";
if ("--".$boundary == $v) {
$lc++;
// echo "FIND=[".$k."]".$v."\n";
$rf = mail_contenttype($p, $type);
// echo "NEWRF=".$rf."\n";
$boundary2 = "";
if ($rf[0]) {
$attrs = mail_parse_attr($rf);
reset($attrs);
$at[substr($lv.".".$lc,1)] = $attrs;
if (isset($attrs['BOUNDARY'])) {
$boundary2 = $attrs['BOUNDARY'];
}
}
// echo "TYPE2=".$type."\n";
if ($boundary2) {
// echo "BOUNDARY2=".$boundary2."\n";
mail_parse_mime($p, $boundary2, $at, $lv.".".$lc );
}else{
if (!strcasecmp("message/rfc822", $type)) {
// echo "---\n";
$rf = mail_contenttype($p, $type);
$boundary3 = "";
if ($rf[0]) {
$attrs = mail_parse_attr($rf);
reset($attrs);
$at[substr($lv.".".$lc.".1",1)] = $attrs;
if (isset($attrs['BOUNDARY'])) {
$boundary3 = $attrs['BOUNDARY'];
}
}
if ($boundary3) {
// echo "RFC822BD=".$boundary3."\n";
mail_parse_mime($p, $boundary3, $at, $lv.".".$lc);
}
// }else{
// $at[substr($lv.".".$lc."1",1)] = array();
}
}
}
if ("--".$boundary."--" == $v) {
// echo "EXIT=[".$k."]\n";
return;
}
}
}
function mail_fullstructurefetch($mbox, $num, $flags = FT_UID) {
$attr = array();
$p = explode("\015\012", imap_fetchbody($mbox, $num, 0, $flags));
$rf = mail_contenttype($p, $type);
$attrs = mail_parse_attr($rf);
$boundary = $attrs['BOUNDARY'];
$p = explode("\015\012", imap_body($mbox, $num, $flags));
mail_parse_mime($p, $boundary, $attr, "");
$attr[0] = "";
return $attr;
}
Posted by minemaz at 2003年08月28日 23:57