X-Git-Url: http://git.polytechnique.org/?a=blobdiff_plain;f=banana%2Fbanana.inc.php.in;h=386e4c1104aab32fe735134852677bbc9ecc5d58;hb=a3c90095a1920b1d39cb1e8ffd892ba407351ca6;hp=fa0f94f0a77345c5ae5e352eec34dbaa51adcc42;hpb=7c111d8d564aa37efe0b364081fabc03c9f42357;p=banana.git diff --git a/banana/banana.inc.php.in b/banana/banana.inc.php.in index fa0f94f..386e4c1 100644 --- a/banana/banana.inc.php.in +++ b/banana/banana.inc.php.in @@ -1,46 +1,67 @@ '', + 'headers' => array('From' => 'Anonymous '), + 'display' => 0, + 'lastnews' => 0, + 'locale' => 'fr_FR.UTF-8', + 'subscribe' => array(), + 'autoup' => 1); + static public $boxpattern; + static public $withtabs = true; + static public $baseurl = null; + static public $mimeparts = array(); + +### Spool ### + static public $spool_root = '/var/spool/banana'; + static public $spool_max = 3000; + static public $spool_tbefore = 5; + static public $spool_tafter = 5; + static public $spool_tmax = 50; + static public $spool_boxlist = true; + +### Message processing ### + static public $msgparse_headers = array('content-disposition', 'content-transfer-encoding', + 'content-type', 'content-id', 'date', 'followup-to', + 'from', 'message-id', 'newsgroups', 'organization', + 'references', 'subject', 'x-face', 'in-reply-to', + 'to', 'cc', 'reply-to'); + +### Message display ### + static public $msgshow_headers = array('from', 'newsgroups', 'followup-to', 'to', 'cc', 'reply-to', + 'organization', 'date', 'references', 'in-reply-to'); + static public $msgshow_mimeparts = array('multipart/report', 'multipart/mixed', + 'text/html', 'text/plain', 'text/enriched', 'text', 'message'); + static public $msgshow_xface = true; + static public $msgshow_wrap = 80; + static public $msgshow_externalimages = false; + static public $msgshow_hasextimages = false; + static public $msgshow_withthread = true; + static public $msgshow_javascript = true; + + static public $msgshow_pgpcheck = true; + static public $msgshow_pgppath = 'gpg'; + static public $msgshow_pgpoptions = ''; - /** Regexp for selecting newsgroups to show (if empty, match all newsgroups) - * ex : '^xorg\..*' for xorg.* - */ - var $grp_pattern; - - var $tbefore = 5; - var $tafter = 5; - var $tmax = 50; - - var $wrap = 74; /** Match an url - * Should be included in a regexp delimited using ! (eg: "!$url_regexp!i") + * Should be included in a regexp delimited using /, !, , or @ (eg: "/$url_regexp/ui") * If it matches, return 3 main parts : * \\1 and \\3 are delimiters * \\2 is the url @@ -50,461 +71,679 @@ class Banana * $matches[2] = "http://www.polytechnique.org" * $matches[3] = "]" */ - var $url_regexp = '(["\[])?((?:https?|ftp|news)://(?:&|,?[a-z@0-9.~%$£µ&i#\-+=_/\?])*)(["\]])?'; + static public $msgshow_url = '(["\[\<])?((?:[a-z]+:\/\/|www\.)(?:[\.\,\;\!\:]*[a-z\@0-9~%$£µ&i#\-+=_\/\?]+)+)(["\]\>])?'; - - /** Boundary for multipart messages - */ - var $boundary = 'bananaBoundary42'; +### Message edition ### + static public $msgedit_canattach = true; + static public $msgedit_maxfilesize = 100000; /** Global headers to use for messages */ - var $custom = "Mime-Version: 1.0\nUser-Agent: Banana @VERSION@\n"; - /** Global headers to use from multipart messages + static public $msgedit_headers = array('Mime-Version' => '1.0', 'User-Agent' => 'Banana @VERSION@'); + /** Mime type order for quoting */ - var $custom_mp = "Content-Type: multipart/mixed; boundary=\"bananaBoundary42\"\nContent-Transfer-Encoding: 7bit\n"; - /** Body type when using plain text - */ - var $custom_plain= "Content-Type: text/plain; charset=utf-8\nContent-Transfert-Encoding: 8bit\n"; - + static public $msgedit_mimeparts = array('multipart/report', 'multipart/mixed', 'text/plain', 'text/enriched', 'text/html', 'text', 'message'); + +### Feed configuration ### + static public $feed_active = true; + static public $feed_format = 'rss2'; + static public $feed_updateOnDemand = false; // Update the feed each time sbd check it + static public $feed_copyright = null; // Global copyright informations + static public $feed_generator = 'Banana @VERSION@'; // Feed generator + static public $feed_email = null; // Admin e-mail + static public $feed_namePrefix = 'Banana :: '; + static public $feed_size = 15; // Number of messages in the feed + +### Protocole ### /** News serveur to use */ - var $host = 'news://localhost:119/'; + static public $nntp_host = 'news://localhost:119/'; + + static public $mbox_path = '/var/mail'; + static public $mbox_helper = './mbox-helper'; + +### Debug ### + static public $debug_nntp = false; + static public $debug_mbox = false; + static public $debug_smarty = false; + + +####### +# Constants +####### + + // Actions + const ACTION_BOX_NEEDED = 1; // mask + const ACTION_BOX_LIST = 2; + const ACTION_BOX_SUBS = 4; + const ACTION_BOX_FEED = 8; + const ACTION_MSG_LIST = 3; + const ACTION_MSG_READ = 5; + const ACTION_MSG_NEW = 9; + const ACTION_MSG_CANCEL = 17; + const ACTION_MSG_IMAGES = 33; + + // Box list view + const BOXES_ALL = 0; + const BOXES_SUB = 1; + const BOXES_NEW = 2; + + // Spool view mode + const SPOOL_ALL = 0; + const SPOOL_UNREAD = 1; + + +####### +# Runtime variables +####### + + static public $protocole = null; + static public $spool = null; + static public $message = null; + static public $page = null; + + static public $group = null; + static public $artid = null; + static public $action = null; + static public $part = null; + static public $first = null; + + /** Class parameters storage + */ + public $params; + + +####### +# Banana Implementation +####### - /** User profile + /** Build the instance of Banana + * This constructor only call \ref loadParams, connect to the server, and build the Smarty page + * @param protocole Protocole to use */ - var $profile = Array( 'name' => 'Anonymous ', 'sig' => '', 'org' => '', - 'customhdr' =>'', 'display' => 0, 'lastnews' => 0, 'locale' => 'fr_FR', 'subscribe' => array()); - - var $state = Array('group' => null, 'artid' => null); - var $nntp; - var $groups; - var $newgroups; - var $post; - var $spool; - - function Banana() + public function __construct($params = null, $protocole = 'NNTP', $pageclass = 'BananaPage') { - $this->_require('NetNNTP'); - setlocale(LC_ALL, $this->profile['locale']); - $this->nntp = new nntp($this->host); - if (!$this->nntp || !$this->nntp->valid) { - $this->nntp = null; + if (is_null($params)) { + $this->params = $_GET; + } else { + $this->params = $params; + } + $this->loadParams(); + + // connect to protocole handler + $classname = 'Banana' . $protocole; + if (!class_exists($classname)) { + Banana::load($protocole); + } + Banana::$protocole = new $classname(Banana::$group); + + // build the page + if ($pageclass == 'BananaPage') { + Banana::load('page'); } + Banana::$page = new $pageclass; + $types = array('multipart/report' => _b_('Rapport d\'erreur'), + 'multipart/mixed' => _b_('Composition'), + 'text/html' => _b_('Texte formaté'), + 'text/plain' => _b_('Texte brut'), + 'text/enriched' => _b_('Texte enrichi'), + 'text' => _b_('Texte'), + 'message/rfc822' => _b_('Mail'), + 'message' => _b_('Message'), + 'source' => _b_('Source')); + Banana::$mimeparts = array_merge($types, Banana::$mimeparts); } - function run($class = 'Banana') + /** Fill state vars (Banana::$group, Banana::$artid, Banana::$action, Banana;:$part, Banana::$first) + */ + protected function loadParams() { - global $banana; - - Banana::_require('misc'); - $banana = new $class(); - - if (!$banana->nntp) { - return '

'._b_('Impossible de contacter le serveur').'

'; + foreach ($this->params as &$value) { + if ($value === "") { + $value = null; + } } - - $group = empty($_GET['group']) ? null : strtolower($_GET['group']); - $artid = empty($_GET['artid']) ? null : strtolower($_GET['artid']); - $partid = !isset($_GET['part']) ? -1 : $_GET['part']; - $banana->state = Array ('group' => $group, 'artid' => $artid); - - if (is_null($group)) { - if (isset($_GET['subscribe'])) { - return $banana->action_listSubs(); - } elseif (isset($_POST['subscribe'])) { - $banana->action_saveSubs(); + Banana::$group = isset($this->params['group']) ? $this->params['group'] : null; + Banana::$artid = isset($this->params['artid']) ? $this->params['artid'] : null; + Banana::$first = isset($this->params['first']) ? $this->params['first'] : null; + Banana::$part = isset($this->params['part']) ? $this->params['part'] : 'text'; + + $action = @$this->params['action']; + if ($action == 'rss' || $action == 'rss2' || $action == 'atom') { + if ($action == 'rss') { + $action = 'rss2'; } - return $banana->action_listGroups(); - - } elseif (is_null($artid)) { - if (isset($_POST['action']) && $_POST['action'] == 'new') { - return $banana->action_doFup($group, isset($_POST['artid']) ? intval($_POST['artid']) : -1); - } elseif (isset($_GET['action']) && $_GET['action'] == 'new') { - return $banana->action_newFup($group); + Banana::$feed_format = $action; + Banana::$action = Banana::ACTION_BOX_FEED; + return; + } + + // Look for the action to execute + if (is_null(Banana::$group)) { + if ($action == 'subscribe') { + Banana::$action = Banana::ACTION_BOX_SUBS; } else { - return $banana->action_showThread($group, isset($_GET['first']) ? intval($_GET['first']) : 1); + Banana::$action = Banana::ACTION_BOX_LIST; } - - } else { - if (isset($_POST['action']) && $_POST['action']=='cancel') { - $res = $banana->action_cancelArticle($group, $artid); + return; + } + + if (is_null(Banana::$artid)) { + if ($action == 'new') { + Banana::$action = Banana::ACTION_MSG_NEW; } else { - $res = ''; - } - - if (isset($_GET['action'])) { - switch ($_GET['action']) { - case 'cancel': - $res .= $banana->action_showArticle($group, $artid, $partid); - if ($banana->post->checkcancel()) { - $form = '

'._b_('Voulez-vous vraiment annuler ce message ?').'

' - . "

" - . '' - . '' - . '

'; - return $form.$res; - } - return $res; - - case 'new': - return $banana->action_newFup($group, $artid); - } + Banana::$action = Banana::ACTION_MSG_LIST; } + return; + } + switch ($action) { + case 'new': + Banana::$action = Banana::ACTION_MSG_NEW; + return; + case 'cancel': + Banana::$action = Banana::ACTION_MSG_CANCEL; + return; + case 'showext': + Banana::$action = Banana::ACTION_MSG_IMAGES; + return; + default: + Banana::$action = Banana::ACTION_MSG_READ; + } + } - if (isset($_GET['pj'])) { - $action = false; - if (isset($_GET['action']) && $_GET['action'] == 'view') { - $action = true; - } - $att = $banana->action_getAttachment($group, $artid, $_GET['pj'], $action); - if ($att != "") { - return $res.$att; - } - return ""; + /** Run Banana + * This function need user profile to be initialised + */ + public function run() + { + // Configure locales + setlocale(LC_ALL, Banana::$profile['locale']); + + // Check if the state is valid + if (Banana::$protocole->lastErrNo()) { + return Banana::$page->kill(_b_('Une erreur a été rencontrée lors de la connexion au serveur') . '
' + . Banana::$protocole->lastError()); + } + if (!Banana::$protocole->isValid()) { + return Banana::$page->kill(_b_('Connexion non-valide')); + } + if (Banana::$action & Banana::ACTION_BOX_NEEDED) { + if(Banana::$boxpattern && !preg_match('/' . Banana::$boxpattern . '/i', Banana::$group)) { + Banana::$page->setPage('group'); + return Banana::$page->kill(_b_("Ce newsgroup n'existe pas ou vous n'avez pas l'autorisation d'y accéder")); } - - return $res . $banana->action_showArticle($group, $artid, $partid); } - } - /**************************************************************************/ - /* actions */ - /**************************************************************************/ + // Dispatch to the action handlers + switch (Banana::$action) { + case Banana::ACTION_BOX_SUBS: + $error = $this->action_subscribe(); + break; + case Banana::ACTION_BOX_LIST: + $error = $this->action_listBoxes(); + break; + case Banana::ACTION_BOX_FEED: + $this->action_feed(); // generate its own xml + break; + case Banana::ACTION_MSG_LIST: + $error = $this->action_showThread(Banana::$group, Banana::$first); + break; + case Banana::ACTION_MSG_IMAGES: + Banana::$msgshow_externalimages = true; + case Banana::ACTION_MSG_READ: + $error = $this->action_showMessage(Banana::$group, Banana::$artid, Banana::$part); + break; + case Banana::ACTION_MSG_NEW: + $error = $this->action_newMessage(Banana::$group, Banana::$artid); + break; + case Banana::ACTION_MSG_CANCEL: + $error = $this->action_cancelMessage(Banana::$group, Banana::$artid); + break; + default: + $error = _b_("L'action demandée n'est pas supportée par Banana"); + } - function action_saveSubs() - { - return; + // Generate the page + if (is_string($error)) { + return Banana::$page->kill($error); + } + return Banana::$page->run(); } - function action_listGroups() + /** Build and post a new message + * @return postid (or -1 if the message has not been found) + */ + public function post($dest, $reply, $subject, $body) { - $this->_newGroup(); - - $cuts = displayshortcuts(); - $res = '

'._b_('Les forums de Banana').'

'.$cuts.$this->groups->to_html(); - if (count($this->newgroups->overview)) { - $res .= '

'._b_('Les forums suivants ont été créés depuis ton dernier passage :').'

'; - $res .= $this->newgroups->to_html(); + $hdrs = Banana::$protocole->requestedHeaders(); + $headers = Banana::$profile['headers']; + $headers[$hdrs['dest']] = $dest; + if ($reply) { + $headers[$hdrs['reply']] = $reply; + } + $headers['Subject'] = $subject; + $msg = BananaMessage::newMessage($headers, $body); + if (Banana::$protocole->send($msg)) { + Banana::$group = ($reply ? $reply : $dest); + $this->loadSpool(Banana::$group); + return Banana::$spool->getPostId($subject); } - - $this->nntp->quit(); - return $res.$cuts; + return -1; } - function action_listSubs() + /** Return the CSS code to include in the headers + */ + public function css() { - $this->_require('groups'); - $this->groups = new BananaGroups(BANANA_GROUP_ALL); - - $cuts = displayshortcuts(); - $res = '

'._b_('Abonnements').'

'.$cuts.$this->groups->to_html(true).$cuts; - - $this->nntp->quit(); - return $res; + return Banana::$page->css; } - function action_showThread($group, $first) + /** Return the Link to the feed of the page + */ + public function feed() { - if (!$this->_newSpool($group, $this->profile['display'], $this->profile['lastnews'])) { - return '

'._b_('Impossible charger la liste des messages').'

'; + if (!Banana::$feed_active) { + return null; } + return Banana::$page->makeURL(array('group' => Banana::$group, 'action' => Banana::$feed_format)); + } - if ($first > count($this->spool->overview)) { - $first = count($this->spool->overview); + /** Return the execution backtrace of the current BananaProtocole + */ + public function backtrace() + { + if (Banana::$protocole) { + return Banana::$protocole->backtrace(); } + return null; + } - $first = $first - ($first % $this->tmax) + 1; - - $cuts = displayshortcuts($first); - - $res = '

'.$group.'

'.$cuts; - $res .= $this->spool->to_html($first, $first+$this->tmax); - - $this->nntp->quit(); - - return $res.$cuts; + /**************************************************************************/ + /* actions */ + /**************************************************************************/ + protected function action_saveSubs($groups) + { + Banana::$profile['subscribe'] = $groups; + return true; } - function action_showArticle($group, $id, $part) + protected function action_subscribe() { - if (!$this->_newSpool($group, $this->profile['display'], $this->profile['lastnews'])) { - return '

'._b_('Impossible charger la liste des messages').'

'; + Banana::$page->setPage('subscribe'); + if (isset($_POST['validsubs'])) { + $this->action_saveSubs(array_keys($_POST['subscribe'])); + Banana::$page->redirect(); } + $groups = Banana::$protocole->getBoxList(Banana::BOXES_ALL); + Banana::$page->assign('groups', $groups); + return true; + } - if (!$this->_newPost($id)) { - if ($this->nntp->lasterrorcode == "423") { - $this->spool->delid($id); - } - $this->nntp->quit(); - return displayshortcuts().'

'._b_('Impossible d\'accéder au message. Le message a peut-être été annulé').'

'; + protected function action_listBoxes() + { + Banana::$page->setPage('forums'); + $groups = Banana::$protocole->getBoxList(Banana::BOXES_SUB, Banana::$profile['lastnews'], true); + Banana::$page->assign('groups', $groups); + if (empty(Banana::$profile['subscribe']) || Banana::$profile['lastnews']) { + $newgroups = Banana::$protocole->getBoxList(Banana::BOXES_NEW, Banana::$profile['lastnews'], true); + Banana::$page->assign('newgroups', $newgroups); } - - $cuts = displayshortcuts(); - $res = '

'._b_('Message').'

'.$cuts; - $res .= $this->post->to_html($part); - - $this->nntp->quit(); - - return $res.$cuts; + return true; } - function action_getAttachment($group, $id, $pjid, $action) + protected function action_feed() { - if (!$this->_newSpool($group, $this->profile['display'], $this->profile['lastnews'])) { - return '

'._b_('Impossible charger la liste des messages').'

'; + Banana::load('feed'); + if (Banana::$group) { + if (Banana::$feed_updateOnDemand) { + $this->loadSpool(Banana::$group); + } + $feed =& BananaFeed::getFeed(); + $feed->toXML(); } - - if (!$this->_newPost($id)) { - if ($this->nntp->lasterrorcode == "423") { - $this->spool->delid($id); + if (Banana::$profile['subscribe']) { + $subfeed = null; + foreach (Banana::$profile['subscribe'] as $group) { + Banana::$group = $group; + if (Banana::$feed_updateOnDemand) { + $this->loadSpool($group); + } + $feed =& BananaFeed::getFeed(); + $subfeed =& BananaFeed::merge($subfeed, $feed, _b_('Abonnements'), _b_('Mes abonnements Banana')); } - $this->nntp->quit(); - return displayshortcuts().'

'._b_('Impossible d\'accéder au message. Le message a peut-être été annulé').'

'; - } - - $this->nntp->quit(); - if ($this->post->get_attachment($pjid, $action)) { - return ""; - } else { - return displayshortcuts().'

'._b_('Impossible d\'accéder à la pièce jointe.').'

'; + $subfeed->toXML(); } + Banana::$page->feed(); } - function action_cancelArticle($group, $id) + protected function action_showThread($group, $first) { - if (!$this->_newSpool($group, $this->profile['display'], $this->profile['lastnews'])) { - return '

'._b_('Impossible charger la liste des messages').'

'; + Banana::$page->setPage('thread'); + if (!$this->loadSpool($group)) { + return _b_('Impossible charger la liste des messages de ') . $group; } - - if (!$this->_newPost($id)) { - return '

'._b_('Impossible de trouver le message à annuler').'

'; + if (Banana::$spool_boxlist) { + $groups = Banana::$protocole->getBoxList(Banana::BOXES_SUB, Banana::$profile['lastnews'], true); + Banana::$page->assign('groups', $groups); } - $mid = array_search($id, $this->spool->ids); + Banana::$page->assign('msgbypage', Banana::$spool_tmax); + return true; + } - if (!$this->post->checkcancel()) { - return '

'._b_('Vous n\'avez pas les permissions pour annuler ce message').'

'; + protected function action_showMessage($group, $artid, $partid = 'text') + { + Banana::$page->setPage('message'); + $istext = $partid == 'text' || $partid == 'source' + || preg_match('!^[-a-z0-9_]+/[-a-z0-9_]+$!', $partid); + if ($istext) { + $this->loadSpool($group); + } + $msg =& $this->loadMessage($group, $artid); + if (is_null($msg)) { + $this->loadSpool($group); + $this->removeMessage($group, $artid); + return _b_('Le message demandé n\'existe pas. Il est possible qu\'il ait été annulé'); } - $msg = 'From: '.$this->profile['name']."\n" - . "Newsgroups: $group\n" - . "Subject: cmsg $mid\n" - . $this->custom - . "Control: cancel $mid\n" - . "\n" - . "Message canceled with Banana"; - if ($this->nntp->post($msg)) { - $this->spool->delid($id); - $this->nntp->quit(); - header("Location: ?group=$group&first=$id"); + if ($partid == 'xface') { + $msg->getXFace(); + exit; + } elseif (!$istext) { + $part = $msg->getPartById($partid); + if (!is_null($part)) { + $part->send(true); + } + $part = $msg->getFile($partid); + if (!is_null($part)) { + $part->send(); + } + exit; + } elseif ($partid == 'text') { + $partid = null; + Banana::$page->assign('body', $msg->getFormattedBody($partid)); + } elseif ($partid == 'source') { + $text = Banana::$protocole->getMessageSource($artid); + if (!is_utf8($text)) { + $text = utf8_encode($text); + } + Banana::$page->assign('body', '
' . banana_htmlentities($text) . '
'); } else { - return '

'._b_('Impossible d\'annuler le message').'

'; + Banana::$page->assign('body', $msg->getFormattedBody($partid)); } + + if (Banana::$profile['autoup']) { + Banana::$spool->markAsRead($artid); + } + if (Banana::$spool_boxlist) { + $groups = Banana::$protocole->getBoxList(Banana::BOXES_SUB, Banana::$profile['lastnews'], true); + Banana::$page->assign('groups', $groups); + } + Banana::$page->assign_by_ref('message', $msg); + Banana::$page->assign('extimages', Banana::$msgshow_hasextimages); + Banana::$page->assign('headers', Banana::$msgshow_headers); + Banana::$page->assign('type', $partid); + return true; } - function action_newFup($group, $id = -1) + protected function action_newMessage($group, $artid) { - $subject = $body = ''; - $target = $group; - - if ($id > 0) { - $this->nntp->group($group); - if ($this->_newPost($id)) { - $subject = preg_replace("/^re\s*:\s*/i", '', 'Re: '.$this->post->headers['subject']); - $body = utf8_encode($this->post->name." "._b_("a écrit"))." :\n".wrap($this->post->get_body(), "> "); - $target = isset($this->post->headers['followup-to']) ? $this->post->headers['followup-to'] : $this->post->headers['newsgroups']; + Banana::$page->setPage('new'); + if (!Banana::$protocole->canSend()) { + return _b_('Vous n\'avez pas le droit de poster'); + } + $hdrs = Banana::$protocole->requestedHeaders(); + $headers = array(); + foreach ($hdrs as $header) { + $headers[$header] = array('name' => BananaMessage::translateHeaderName($header)); + if (isset(Banana::$profile['headers'][$header])) { + $headers[$header]['fixed'] = Banana::$profile['headers'][$header]; } } + if (isset($_POST['sendmessage'])) { + $hdr_values = array(); + foreach ($hdrs as $header) { + $hdr_values[$header] = isset($headers[$header]['fixed']) ? $headers[$header]['fixed'] : @$_POST[$header]; + if (!is_utf8($hdr_values[$header])) { + $hdr_values[$header] = utf8_encode($hdr_values[$header]); + } + if ($headers != 'Subject') { + $hdr_values[$header] = str_replace(', ', ',', $hdr_values[$header]); + } + } + if (!is_null($artid)) { + $old =& $this->loadMessage($group, $artid); + $hdr_values['References'] = $old->getHeaderValue('references') . ' ' . $old->getHeaderValue('message-id'); + } + $msg = null; + if (isset($_POST['body']) && !is_utf8($_POST['body'])) { + $_POST['body'] = utf8_encode($_POST['body']); + } + if (empty($hdr_values['Subject'])) { + Banana::$page->trig(_b_('Le message doit avoir un sujet')); + } elseif (Banana::$msgedit_canattach && isset($_FILES['attachment']) && $_FILES['attachment']['name']) { + $uploaded =& $_FILES['attachment']; + if (!is_uploaded_file($uploaded['tmp_name'])) { + Banana::$page->trig(_b_('Une erreur est survenue lors du téléchargement du fichier')); + } else { + $msg = BananaMessage::newMessage($hdr_values, $_POST['body'], $uploaded); + } + } else { + $msg = BananaMessage::newMessage($hdr_values, $_POST['body']); + } + if (!is_null($msg)) { + if (Banana::$protocole->send($msg)) { + $this->loadSpool($group); + $newid = Banana::$spool->updateUnread(Banana::$profile['lastnews']); + Banana::$page->redirect(array('group' => $group, 'artid' => $newid ? $newid : $artid)); + } else { + Banana::$page->trig(_b_('Une erreur est survenue lors de l\'envoi du message :') . '
' + . Banana::$protocole->lastError()); + } + } + } else { + if (!is_null($artid)) { + $msg =& $this->loadMessage($group, $artid); + $body = $msg->getSender() . _b_(' a écrit :') . "\n" . $msg->quote(); + $subject = $msg->getHeaderValue('subject'); + $headers['Subject']['user'] = 'Re: ' . preg_replace("/^re\s*:\s*/i", '', $subject); + $target = $msg->getHeaderValue($hdrs['reply']); + if (empty($target)) { + $target = $group; + } + $headers[$hdrs['dest']]['user'] =& $target; + } else { + $body = ''; + $headers[$hdrs['dest']]['user'] = $group; + } + if (Banana::$profile['signature']) { + $body .= "\n\n-- \n" . Banana::$profile['signature']; + } + Banana::$page->assign('body', $body); + } - $this->nntp->quit(); - - $cuts = displayshortcuts(); - $html = '

'._b_('Nouveau message').'

'.$cuts; - $html .= '
'; - $html .= ''; - $html .= ''; - $html .= ''; - $html .= ''; - $html .= ''; - $html .= ''; - $html .= ''; - $html .= ''; - $html .= ''; - if ($this->can_attach) { - $html .= ''; - $html .= ''; - } - $html .= ''; - $html .= '
'._b_('En-têtes').'
'._b_('Nom').''.htmlentities($this->profile['name']).'
'._b_('Sujet').'
'._b_('Forums').'
'._b_('Suivi à').'
'._b_('Organisation').''.$this->profile['org'].'
'._b_('Corps').'
'._b_('Pièce jointe').'
'; - $html .= '
'; - if ($id > 0) { - $html .= ''; - } - $html .= ''; - $html .= '
'; - - return $html.$cuts; + Banana::$page->assign('maxfilesize', Banana::$msgedit_maxfilesize); + Banana::$page->assign('can_attach', Banana::$msgedit_canattach); + Banana::$page->assign('headers', $headers); + return true; } - function action_doFup($group, $artid = -1) + protected function action_cancelMessage($group, $artid) { - if ( ! ( is_utf8($_POST['subject']) && is_utf8($_POST['name']) - && is_utf8($_POST['org']) && is_utf8($_POST['body']) ) - ) { - foreach(array('subject', 'name', 'org', 'body') as $key) { - $_POST[$key] = utf8_encode($_POST[$key]); - } + Banana::$page->setPage('cancel'); + $msg =& $this->loadMessage($group, $artid); + if (!$msg->canCancel()) { + return _b_('Vous n\'avez pas les droits suffisants pour supprimer ce message'); } - - $to = preg_replace('/\s*(,|;)\s*/', ',', $_POST['newsgroups']); - if (!$this->_newSpool($group, $this->profile['display'], $this->profile['lastnews'])) { - return '

'._b_('Impossible charger la liste des messages').'

'; - } - - $body = preg_replace("/\n\.[ \t\r]*\n/m", "\n..\n", $_POST['body']); - $msg = 'From: '.$this->profile['name']."\n" - . "Newsgroups: ". $to . "\n" - . "Subject: ".headerEncode($_POST['subject'], 128)."\n" - . (empty($this->profile['org']) ? '' : "Organization: {$this->profile['org']}\n") - . (empty($_POST['followup']) ? '' : 'Followup-To: '.$_POST['followup']."\n"); - - if ($artid != -1) { - $this->_require('post'); - $post = new BananaPost($artid); - if (!$post || !$post->valid) { - return '

'._b_('Impossible charger le message d\'origine').'

'; + if (isset($_POST['cancel'])) { + $this->loadSpool($group); + $ndx = Banana::$spool->getNdX($id) - 1; + if (!Banana::$protocole->cancel($msg)) { + return _b_('Une erreur s\'est produite lors de l\'annulation du message :') . '
' + . Banana::$protocole->lastError(); } - $refs = ( isset($post->headers['references']) ? $post->headers['references']." " : "" ); - $msg .= "References: $refs{$post->headers['message-id']}\n"; + if ($ndx < 50) { + $ndx = 0; + } + $this->removeMessage($group, $artid); + Banana::$page->redirect(Array('group' => $group, 'first' => $ndx)); } - $body_headers = $this->custom_plain; - $body = wrap($body, ""); - - // include attachment in the body - $uploaded = $this->_upload('newpj'); - switch ($uploaded['error']) { - case UPLOAD_ERR_OK: - $this->custom = $this->custom_mp.$this->custom; - $body = $this->_make_part($body_headers, $body); - $file_head = 'Content-Type: '.$uploaded['type'].'; name="'.$uploaded['name']."\"\n" - . 'Content-Transfer-Encoding: '.$uploaded['encoding']."\n" - . 'Content-Disposition: attachment; filename="'.$uploaded['name']."\"\n"; - $body .= $this->_make_part($file_head, $uploaded['data']); - $body .= "\n--".$this->boundary.'--'; - break; + Banana::$page->assign_by_ref('message', $msg); + Banana::$page->assign('body', $msg->getFormattedBody()); + Banana::$page->assign('headers', Banana::$msgshow_headers); + return true; + } - case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_FORM_SIZE: - return '

'._b_('Fichier trop gros pour être envoyé : ') - .$uploaded['name'].'

'.$this->action_showThread($group, $artid); + /**************************************************************************/ + /* Spoolgen functions */ + /**************************************************************************/ - case UPLOAD_ERR_PARTIAL: - return '

'._b_('Erreur lors de l\'upload de ') - .$uploaded['name'].'

'.$this->action_showThread($group, $artid); + private function checkErrors() + { + if (Banana::$protocole->lastErrno()) { + echo "\nL'erreur suivante s'est produite : " + . Banana::$protocole->lastErrno() . " " + . Banana::$protocole->lastError() . "\n"; + return false; + } + return true; + } - case UPLOAD_ERR_NO_FILE: - return '

'._b_('Le fichier spécifié n\'existe pas : ') - .$uploaded['name'].'

'.$this->action_showThread($group, $artid); + static public function createAllSpool(array $protos) + { + foreach ($protos as $proto) { + $banana = new Banana(array(), $proto); - case UPLOAD_ERR_NO_TMP_DIR: - return '

'._b_('Une erreur est survenue sur le serveur lors de l\'upload de ') - .$uploaded['name'].'

'.$this->action_showThread($group, $artid); + if (!$banana->checkErrors()) { + continue; + } + $groups = Banana::$protocole->getBoxList(); + if (!$banana->checkErrors()) { + continue; + } - default: - $this->custom = $body_headers.$this->custom; + print "** $proto **\n"; + foreach (array_keys($groups) as $g) { + print "Generating spool for $g: "; + Banana::$group = $g; + $spool = $banana->loadSpool($g); + if (!$banana->checkErrors()) { + break; + } + print "done.\n"; + unset($spool); + Banana::$spool = null; + } + print "\n"; } + } - // finalise and post the message - $msg .= $this->custom.$this->profile['customhdr']."\n".$body; + static public function refreshAllFeeds(array $protos) + { + Banana::load('feed'); + Banana::$feed_updateOnDemand = true; // In order to force update + foreach ($protos as $proto) { + $banana = new Banana(array(), $proto); - if ($this->nntp->post($msg)) { - header("Location: ?group=$group".($artid==-1 ? '' : "&first=$artid")); - } else { - return "

"._b_('Impossible de poster le message')."

".$this->action_showThread($group, $artid); + if (!$banana->checkErrors()) { + continue; + } + $groups = Banana::$protocole->getBoxList(); + if (!$banana->checkErrors()) { + continue; + } + + print "** $proto **\n"; + foreach (array_keys($groups) as $g) { + print "Generating feed cache for $g: "; + Banana::$group = $g; + $spool = $banana->loadSpool($g); + if (!$banana->checkErrors()) { + break; + } + $feed =& BananaFeed::getFeed(); + print "done.\n"; + unset($feed); + unset($spool); + Banana::$spool = null; + } + print "\n"; } } - + /**************************************************************************/ /* Private functions */ /**************************************************************************/ - function _newSpool($group, $disp=0, $since='') { - $this->_require('spool'); - if (!$this->spool || $this->spool->group != $group) { - $this->spool = new BananaSpool($group, $disp, $since); - if (!$this->spool || !$this->spool->valid) { - $this->spool = null; - return false; - } - } - return true; - } - - function _newPost($id) + protected function loadSpool($group) { - $this->_require('post'); - $this->post = new BananaPost($id); - if (!$this->post || !$this->post->valid) { - $this->post = null; - return false; + Banana::load('spool'); + if (!Banana::$spool || Banana::$spool->group != $group) { + $clean = false; + if (php_sapi_name() != 'cli') { + if ($group == @$_SESSION['banana_group'] && isset($_SESSION['banana_spool'])) { + Banana::$spool = unserialize($_SESSION['banana_spool']); + $clean = @(Banana::$profile['lastnews'] != $_SESSION['banana_lastnews']); + } else { + unset($_SESSION['banana_message']); + unset($_SESSION['banana_artid']); + unset($_SESSION['banana_showhdr']); + } + } + BananaSpool::getSpool($group, Banana::$profile['lastnews'], Banana::$profile['autoup'] || $clean); + if (php_sapi_name() != 'cli') { + $_SESSION['banana_group'] = $group; + if (!Banana::$profile['display']) { + $_SESSION['banana_spool'] = serialize(Banana::$spool); + $_SESSION['banana_lastnews'] = Banana::$profile['lastnews']; + } + } + Banana::$spool->setMode(Banana::$profile['display'] ? Banana::SPOOL_UNREAD : Banana::SPOOL_ALL); } return true; } - function _newGroup() + protected function &loadMessage($group, $artid) { - $this->_require('groups'); - $this->groups = new BananaGroups(BANANA_GROUP_SUB); - if ($this->groups->type == BANANA_GROUP_SUB) { - $this->newgroups = new BananaGroups(BANANA_GROUP_NEW); + Banana::load('message'); + if ($group == @$_SESSION['banana_group'] && $artid == @$_SESSION['banana_artid'] + && isset($_SESSION['banana_message'])) { + $message = unserialize($_SESSION['banana_message']); + Banana::$msgshow_headers = $_SESSION['banana_showhdr']; + } else { + $message = Banana::$protocole->getMessage($artid); + $_SESSION['banana_group'] = $group; + $_SESSION['banana_artid'] = $artid; + $_SESSION['banana_message'] = serialize($message); + $_SESSION['banana_showhdr'] = Banana::$msgshow_headers; } + Banana::$message =& $message; + return $message; } - function _require($file) - { - require_once (dirname(__FILE__).'/'.$file.'.inc.php'); - } - - function _upload($file) + protected function removeMessage($group, $artid) { - if ($_FILES[$file]['name'] == "") { - return Array( 'error' => -1 ); - } - - // upload - $_FILES[$file]['tmp_name']; - - // test if upload is ok - $file = $_FILES[$file]; - if ($file['size'] == 0 || $file['error'] != 0) { - if ($file['error'] == 0) { - $file['error'] = -1; + Banana::$spool->delId($artid); + if ($group == $_SESSION['banana_group']) { + if (!Banana::$profile['display']) { + $_SESSION['banana_spool'] = serialize(Banana::$spool); + } + if ($artid == $_SESSION['banana_artid']) { + unset($_SESSION['banana_message']); + unset($_SESSION['banana_showhdr']); + unset($_SESSION['banana_artid']); } - return $file; - } - - // adding custum data - $mime = rtrim(shell_exec('file -bi '.$file['tmp_name'])); //Because mime_content_type don't work :( - $encod = 'base64'; - if (preg_match("@([^ ]+/[^ ]+); (.*)@", $mime, $format)) { - $mime = $format[1]; - $encod = $format[2]; - } - $data = fread(fopen($file['tmp_name'], 'r'), $file['size']); - if ($encod == 'base64') { - $data = chunk_split(base64_encode($data)); } - $file['name'] = basename($file['name']); - $file['type'] = $mime; - $file['encoding'] = $encod; - $file['data'] = $data; - - return $file; + $this->loadSpool($group); + return true; } - function _make_part($headers, $body) + static private function load($file) { - return "\n--".$this->boundary."\n".$headers."\n".$body; + $file = strtolower($file) . '.inc.php'; + if (!@include_once dirname(__FILE__) . "/$file") { + require_once $file; + } } } +// vim:set et sw=4 sts=4 ts=4 enc=utf-8: ?>