X-Git-Url: http://git.polytechnique.org/?a=blobdiff_plain;f=banana%2Fpost.inc.php;h=b85f23d0174e92594698a2797e166c5a8c636fb5;hb=261210bc9c416cca0d9b79ab215526d4c93b098a;hp=c9949081f41cfed01fdd1d63a4cbb182c84c0919;hpb=e27ae1a3403375ffa4f6cf2b7b70f0fad17d7dbd;p=banana.git diff --git a/banana/post.inc.php b/banana/post.inc.php index c994908..b85f23d 100644 --- a/banana/post.inc.php +++ b/banana/post.inc.php @@ -23,6 +23,8 @@ class BananaPost var $pj; /** poster name */ var $name; + /** test validity */ + var $valid = true; /** constructor * @param $_id STRING MSGNUM or MSGID (a group should be selected in this case) @@ -33,12 +35,17 @@ class BananaPost $this->id = $_id; $this->pj = array(); $this->messages = array(); - $this->_header(); + if (!$this->_header()) { + $this->valid = false; + return null; + } + if ($body = $banana->nntp->body($_id)) { $this->body = join("\n", $body); } else { - return ($this = null); + $this->valid = false; + return null; } if (isset($this->headers['content-transfer-encoding'])) { @@ -49,10 +56,11 @@ class BananaPost } } - if (preg_match("@multipart/([^;]+);@", $this->headers['content-type'], $mpart_type)) { - preg_match("/boundary=\"?([^ \"]+)\"?/", $this->headers['content-type'], $mpart_boundary); - $this->_split_multipart($mpart_type[1], $mpart_boundary[1]); + if ($this->_split_multipart($this->headers, $this->body)) { + $this->set_body_to_part(0); } else { + $this->_split_multipart($mpart_type[1], $mpart_boundary[1]); + $this->_find_uuencode(); if (preg_match('!charset=([^;]*)\s*(;|$)!', $this->headers['content-type'], $matches)) { $this->body = iconv($matches[1], 'utf-8', $this->body); } else { @@ -61,24 +69,68 @@ class BananaPost } } + /** find and add uuencoded attachments + */ + function _find_uuencode() + { + if (preg_match_all('@\n(begin \d+ ([^\r\n]+)\r?(?:\n(?!end)[^\n]*)*\nend)@', $this->body, $matches, PREG_SET_ORDER)) { + foreach ($matches as $match) { + $mime = trim(exec('echo '.escapeshellarg($match[1]).' | uudecode -o /dev/stdout | file -bi -')); + if ($mime != 'application/x-empty') { + $this->body = trim(str_replace($match[0], '', $this->body)); + $body = $match[1]; + $header['content-type'] = $mime.'; name="'.$match[2].'"'; + $header['content-transfer-encoding'] = 'x-uuencode'; + $header['content-disposition'] = 'attachment; filename="'.$match[2].'"'; + $this->_add_attachment(Array('headers' => $header, 'body' => $body)); + } + } + } + } + /** split multipart messages * @param $type STRING multipart type description * @param $boundary STRING multipart boundary identification string */ - function _split_multipart($type, $boundary) + function _split_multipart($headers, $body) { - $parts = preg_split("/\n--$boundary(--|\n)/", $this->body); + if (!preg_match("@multipart/([^;]+);@", $headers['content-type'], $type)) { + return false; + } + + preg_match("/boundary=\"?([^ \"]+)\"?/", $headers['content-type'], $boundary); + $boundary = $boundary[1]; + $type = $type[1]; + $parts = preg_split("@\n--$boundary(--|\n)@", $body); foreach ($parts as $part) { - $part = $this->_get_part($part); + $part = $this->_get_part($part); $local_header = $part['headers']; - $local_body = $part['body']; - if (isset($local_header['content-disposition']) && preg_match("/attachment/", $local_header['content-disposition'])) { - $this->_add_attachment($part); - } else if (isset($local_header['content-type']) && preg_match("@text/([^;]+);@", $local_header['content-type'], $format)) { - array_push($this->messages, $part); + $local_body = $part['body']; + if (!$this->_split_multipart($local_header, $local_body)) { + $is_text = isset($local_header['content-type']) && preg_match("@text/([^;]+);@", $local_header['content-type']) + && (!isset($local_header['content-disposition']) || !preg_match('@attachment@', $local_header['content-disposition'])); + + // alternative ==> multiple formats for messages + if ($type == 'alternative' && $is_text) { + array_push($this->messages, $part); + + // !alternative ==> une body, others are attachments + } else if ($is_text) { + if (count($this->messages) == 0) { + $this->body = $local_body; + foreach (array_keys($local_header) as $key) { + $this->header[$key] = $local_header[$key]; + } + array_push($this->messages, $part); + } else { + $this->_add_attachment($part); + } + } else { + $this->_add_attachment($part); + } } } - $this->set_body_to_part(0); + return true; } /** extract new headers from the part @@ -92,16 +144,24 @@ class BananaPost while (count($lines)) { $line = array_shift($lines); if ($line != "") { - list($hdr, $val) = split(":[ \t\r]*", $line, 2); - $hdr = strtolower($hdr); - if (in_array($hdr, $banana->parse_hdr)) { - $local_headers[$hdr] = $val; + if (preg_match('@^[\t\r ]+@', $line) && isset($hdr)) { + $local_headers[$hdr] .= ' '.trim($line); + } else { + list($hdr, $val) = split(":[ \t\r]*", $line, 2); + $hdr = strtolower($hdr); + if (in_array($hdr, $banana->parse_hdr)) { + $local_headers[$hdr] = $val; + } } } else { break; } } - return Array('headers' => $local_headers, 'body' => join("\n", $lines)); + $local_body = join("\n", $lines); + if (preg_match("/quoted-printable/", $local_headers['content-transfer-encoding'])) { + $local_body = quoted_printable_decode($local_body); + } + return Array('headers' => $local_headers, 'body' => $local_body); } /** add an attachment @@ -111,16 +171,10 @@ class BananaPost $local_header = $part['headers']; $local_body = $part['body']; - if (!isset($local_header['content-transfer-encoding'])) { - return false; - } - - if (isset($local_header['content-disposition'])) { - if (preg_match("/attachment/", $local_header['content-disposition'])) { - preg_match("/filename=\"?([^\"]+)\"?/", $local_header['content-disposition'], $filename); - $filename = $filename[1]; - } - } + if ((isset($local_header['content-disposition']) && preg_match("/filename=\"?([^\"]+)\"?/", $local_header['content-disposition'], $filename)) + || (isset($local_header['content-type']) && preg_match("/name=\"?([^\"]+)\"?/", $local_header['content-type'], $filename))) { + $filename = $filename[1]; + } if (!isset($filename)) { $filename = "attachment".count($pj); } @@ -174,6 +228,8 @@ class BananaPost } if ($file['encoding'] == 'base64') { echo base64_decode($file['data']); + } else if ($file['encoding'] == 'x-uuencode') { + passthru('echo '.escapeshellarg($file['data']).' | uudecode -o /dev/stdout'); } else { header('Content-Transfer-Encoding: '.$file['encoding']); echo $file['data']; @@ -205,7 +261,7 @@ class BananaPost $this->body = iconv($matches[1], 'utf-8', $this->body); } else { $this->body = utf8_encode($this->body); - } + } return true; } @@ -214,7 +270,6 @@ class BananaPost global $banana; $hdrs = $banana->nntp->head($this->id); if (!$hdrs) { - $this = null; return false; } @@ -243,6 +298,7 @@ class BananaPost $this->name = $this->headers['from']; $this->name = preg_replace('/<[^ ]*>/', '', $this->name); $this->name = trim($this->name); + return true; } function checkcancel() @@ -287,15 +343,24 @@ class BananaPost $res = ''; $res .= ''; + $res .= ''; $res .= '
'._b_('En-têtes').'
'; foreach ($banana->show_hdr as $hdr) { if (isset($this->headers[$hdr])) { $res2 = formatdisplayheader($hdr, $this->headers[$hdr]); - if ($res2) { + if ($res2 && ($hdr != 'x-face' || !$banana->formatxface)) { $res .= '\n"; + } else if ($res2) { + $xface = $res2; } } } + $res .= '
'.header_translate($hdr)."$res2
'; + + if ($xface) { + $res .= $xface; + } + $res .= '
'._b_('Corps'); if (count($this->messages) > 1) { @@ -308,7 +373,10 @@ class BananaPost preg_match("@text/([^;]+);@", $this->messages[$i]['headers']['content-type'], $format); $format = textFormat_translate($format[1]); if ($i != $partid) { - $res .= ''.$format.''; + $res .= makeHREF(Array('group' => $banana->state['group'], + 'artid' => $this->id, + 'part' => $i), + $format); } else { $res .= $format; } @@ -335,8 +403,16 @@ class BananaPost $i = 0; foreach ($this->pj as $file) { $res .= $file['filename'].' ('.$file['MIME'].') : '; - $res .= 'télécharger'; - $res .= ' . aperçu'; + $res .= makeHREF(Array('group' => $banana->state['group'], + 'artid' => $this->id, + 'pj' => $i), + _b_('télécharger')); + $res .= ' . '; + $res .= makeHREF(Array('group' => $banana->state['group'], + 'artid' => $this->id, + 'pj' => $i, + 'action'=> 'view'), + _b_('aperçu')); $res .= '
'; $i++; } @@ -351,4 +427,5 @@ class BananaPost } } +// vim:set et sw=4 sts=4 ts=4 ?>