pax_global_header00006660000000000000000000000064121522140610014504gustar00rootroot0000000000000052 comment=397fb37df35ab798a6364598550f392c8618b6b6 php-net-nntp-1.5.0/000077500000000000000000000000001215221406100140375ustar00rootroot00000000000000php-net-nntp-1.5.0/Net_NNTP-1.5.0/000077500000000000000000000000001215221406100160635ustar00rootroot00000000000000php-net-nntp-1.5.0/Net_NNTP-1.5.0/LICENSE000066400000000000000000000067401215221406100170770ustar00rootroot00000000000000+-----------------------------------------------------------------------+ | | | W3CŪ SOFTWARE NOTICE AND LICENSE | | http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 | | | | This work (and included software, documentation such as READMEs, | | or other related items) is being provided by the copyright holders | | under the following license. By obtaining, using and/or copying | | this work, you (the licensee) agree that you have read, understood, | | and will comply with the following terms and conditions. | | | | Permission to copy, modify, and distribute this software and its | | documentation, with or without modification, for any purpose and | | without fee or royalty is hereby granted, provided that you include | | the following on ALL copies of the software and documentation or | | portions thereof, including modifications: | | | | 1. The full text of this NOTICE in a location viewable to users | | of the redistributed or derivative work. | | | | 2. Any pre-existing intellectual property disclaimers, notices, | | or terms and conditions. If none exist, the W3C Software Short | | Notice should be included (hypertext is preferred, text is | | permitted) within the body of any redistributed or derivative | | code. | | | | 3. Notice of any changes or modifications to the files, including | | the date changes were made. (We recommend you provide URIs to | | the location from which the code is derived.) | | | | THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT | | HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, | | INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR | | FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE | | OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, | | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. | | | | COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, | | SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE | | SOFTWARE OR DOCUMENTATION. | | | | The name and trademarks of copyright holders may NOT be used in | | advertising or publicity pertaining to the software without | | specific, written prior permission. Title to copyright in this | | software and any associated documentation will at all times | | remain with copyright holders. | | | +-----------------------------------------------------------------------+ php-net-nntp-1.5.0/Net_NNTP-1.5.0/NNTP/000077500000000000000000000000001215221406100166425ustar00rootroot00000000000000php-net-nntp-1.5.0/Net_NNTP-1.5.0/NNTP/Client.php000066400000000000000000001277011215221406100206010ustar00rootroot00000000000000 * +-----------------------------------------------------------------------+ * | | * | W3CŪ SOFTWARE NOTICE AND LICENSE | * | http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 | * | | * | This work (and included software, documentation such as READMEs, | * | or other related items) is being provided by the copyright holders | * | under the following license. By obtaining, using and/or copying | * | this work, you (the licensee) agree that you have read, understood, | * | and will comply with the following terms and conditions. | * | | * | Permission to copy, modify, and distribute this software and its | * | documentation, with or without modification, for any purpose and | * | without fee or royalty is hereby granted, provided that you include | * | the following on ALL copies of the software and documentation or | * | portions thereof, including modifications: | * | | * | 1. The full text of this NOTICE in a location viewable to users | * | of the redistributed or derivative work. | * | | * | 2. Any pre-existing intellectual property disclaimers, notices, | * | or terms and conditions. If none exist, the W3C Software Short | * | Notice should be included (hypertext is preferred, text is | * | permitted) within the body of any redistributed or derivative | * | code. | * | | * | 3. Notice of any changes or modifications to the files, including | * | the date changes were made. (We recommend you provide URIs to | * | the location from which the code is derived.) | * | | * | THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT | * | HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, | * | INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR | * | FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE | * | OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, | * | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. | * | | * | COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, | * | SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE | * | SOFTWARE OR DOCUMENTATION. | * | | * | The name and trademarks of copyright holders may NOT be used in | * | advertising or publicity pertaining to the software without | * | specific, written prior permission. Title to copyright in this | * | software and any associated documentation will at all times | * | remain with copyright holders. | * | | * +-----------------------------------------------------------------------+ * * * @category Net * @package Net_NNTP * @author Heino H. Gehlsen * @copyright 2002-2011 Heino H. Gehlsen . All Rights Reserved. * @license http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 W3CŪ SOFTWARE NOTICE AND LICENSE * @version SVN: $Id: Client.php 317347 2011-09-26 20:26:12Z janpascal $ * @link http://pear.php.net/package/Net_NNTP * @see * * @filesource */ /** * */ require_once 'Net/NNTP/Protocol/Client.php'; // {{{ Net_NNTP_Client /** * Implementation of the client side of NNTP (Network News Transfer Protocol) * * The Net_NNTP_Client class is a frontend class to the Net_NNTP_Protocol_Client class. * * @category Net * @package Net_NNTP * @version package: 1.5.0 (stable) * @version api: 0.9.0 (alpha) * @access public * @see Net_NNTP_Protocol_Client */ class Net_NNTP_Client extends Net_NNTP_Protocol_Client { // {{{ properties /** * Information summary about the currently selected group. * * @var array * @access private */ var $_selectedGroupSummary = null; /** * * * @var array * @access private * @since 1.3.0 */ var $_overviewFormatCache = null; // }}} // {{{ constructor /** * Constructor * * Usage example: * {@example docs/examples/phpdoc/constructor.php} * * @access public */ function Net_NNTP_Client() { parent::Net_NNTP_Protocol_Client(); } // }}} // {{{ connect() /** * Connect to a server. * * xxx * * Usage example: * {@example docs/examples/phpdoc/connect.php} * * @param string $host (optional) The hostname og IP-address of the NNTP-server to connect to, defaults to localhost. * @param mixed $encryption (optional) false|'tls'|'ssl', defaults to false. * @param int $port (optional) The port number to connect to, defaults to 119 or 563 dependng on $encryption. * @param int $timeout (optional) * * @return mixed
* - (bool) True when posting allowed, otherwise false * - (object) Pear_Error on failure * @access public * @see Net_NNTP_Client::disconnect() * @see Net_NNTP_Client::authenticate() */ function connect($host = null, $encryption = null, $port = null, $timeout = null) { // v1.0.x API if (is_int($encryption)) { trigger_error('You are using deprecated API v1.0 in Net_NNTP_Client: connect() !', E_USER_NOTICE); $port = $encryption; $encryption = null; } return parent::connect($host, $encryption, $port, $timeout); } // }}} // {{{ disconnect() /** * Disconnect from server. * * @return mixed
* - (bool) * - (object) Pear_Error on failure * @access public * @see Net_NNTP_Client::connect() */ function disconnect() { return parent::disconnect(); } // }}} // {{{ quit() /** * Deprecated alias for disconnect(). * * @access public * @deprecated * @ignore */ function quit() { return $this->disconnect(); } // }}} // {{{ authenticate() /** * Authenticate. * * xxx * * Non-standard!
* This method uses non-standard commands, which is not part * of the original RFC977, but has been formalized in RFC2890. * * Usage example: * {@example docs/examples/phpdoc/authenticate.php} * * @param string $user The username * @param string $pass The password * * @return mixed
* - (bool) True on successful authentification, otherwise false * - (object) Pear_Error on failure * @access public * @see Net_NNTP_Client::connect() */ function authenticate($user, $pass) { // Username is a must... if ($user == null) { return $this->throwError('No username supplied', null); } return $this->cmdAuthinfo($user, $pass); } // }}} // {{{ selectGroup() /** * Selects a group. * * Moves the servers 'currently selected group' pointer to the group * a new group, and returns summary information about it. * * Non-standard!
* When using the second parameter, * This method uses non-standard commands, which is not part * of the original RFC977, but has been formalized in RFC2890. * * Usage example: * {@example docs/examples/phpdoc/selectGroup.php} * * @param string $group Name of the group to select * @param mixed $articles (optional) experimental! When true the article numbers is returned in 'articles' * * @return mixed
* - (array) Summary about the selected group * - (object) Pear_Error on failure * @access public * @see Net_NNTP_Client::getGroups() * @see Net_NNTP_Client::group() * @see Net_NNTP_Client::first() * @see Net_NNTP_Client::last() * @see Net_NNTP_Client::count() */ function selectGroup($group, $articles = false) { // Select group (even if $articles is set, since many servers does not select groups when the listgroup command is run) $summary = $this->cmdGroup($group); if (PEAR::isError($summary)) { return $summary; } // Store group info in the object $this->_selectedGroupSummary = $summary; // if ($articles !== false) { $summary2 = $this->cmdListgroup($group, ($articles === true ? null : $articles)); if (PEAR::isError($summary2)) { return $summary2; } // Make sure the summary array is correct... if ($summary2['group'] == $group) { $summary = $summary2; // ... even if server does not include summary in status reponce. } else { $summary['articles'] = $summary2['articles']; } } return $summary; } // }}} // {{{ selectPreviousArticle() /** * Select the previous article. * * Select the previous article in current group. * * Usage example: * {@example docs/examples/phpdoc/selectPreviousArticle.php} * * @param int $_ret (optional) Experimental * * @return mixed
* - (integer) Article number, if $ret=0 (default) * - (string) Message-id, if $ret=1 * - (array) Both article number and message-id, if $ret=-1 * - (bool) False if no prevoius article exists * - (object) Pear_Error on failure * @access public * @see Net_NNTP_Client::selectArticle() * @see Net_NNTP_Client::selectNextArticle() */ function selectPreviousArticle($_ret = 0) { $response = $this->cmdLast(); if (PEAR::isError($response)) { return false; } switch ($_ret) { case -1: return array('Number' => (int) $response[0], 'Message-ID' => (string) $response[1]); break; case 0: return (int) $response[0]; break; case 1: return (string) $response[1]; break; default: error(); // ... } } // }}} // {{{ selectNextArticle() /** * Select the next article. * * Select the next article in current group. * * Usage example: * {@example docs/examples/phpdoc/selectNextArticle.php} * * @param int $_ret (optional) Experimental * * @return mixed
* - (integer) Article number, if $ret=0 (default) * - (string) Message-id, if $ret=1 * - (array) Both article number and message-id, if $ret=-1 * - (bool) False if no further articles exist * - (object) Pear_Error on unexpected failure * @access public * @see Net_NNTP_Client::selectArticle() * @see Net_NNTP_Client::selectPreviousArticle() */ function selectNextArticle($_ret = 0) { $response = $this->cmdNext(); if (PEAR::isError($response)) { return $response; } switch ($_ret) { case -1: return array('Number' => (int) $response[0], 'Message-ID' => (string) $response[1]); break; case 0: return (int) $response[0]; break; case 1: return (string) $response[1]; break; default: error(); // ... } } // }}} // {{{ selectArticle() /** * Selects an article by article message-number. * * xxx * * Usage example: * {@example docs/examples/phpdoc/selectArticle.php} * * @param mixed $article The message-number (on the server) of * the article to select as current article. * @param int $_ret (optional) Experimental * * @return mixed
* - (integer) Article number * - (bool) False if article doesn't exists * - (object) Pear_Error on failure * @access public * @see Net_NNTP_Client::selectNextArticle() * @see Net_NNTP_Client::selectPreviousArticle() */ function selectArticle($article = null, $_ret = 0) { $response = $this->cmdStat($article); if (PEAR::isError($response)) { return $response; } switch ($_ret) { case -1: return array('Number' => (int) $response[0], 'Message-ID' => (string) $response[1]); break; case 0: return (int) $response[0]; break; case 1: return (string) $response[1]; break; default: error(); // ... } } // }}} // {{{ getArticle() /** * Fetch article into transfer object. * * Select an article based on the arguments, and return the entire * article (raw data). * * Usage example: * {@example docs/examples/phpdoc/getArticle.php} * * @param mixed $article (optional) Either the message-id or the * message-number on the server of the * article to fetch. * @param bool $implode (optional) When true the result array * is imploded to a string, defaults to * false. * * @return mixed
* - (array) Complete article (when $implode is false) * - (string) Complete article (when $implode is true) * - (object) Pear_Error on failure * @access public * @see Net_NNTP_Client::getHeader() * @see Net_NNTP_Client::getBody() */ function getArticle($article = null, $implode = false) { // v1.1.x API if (is_string($implode)) { trigger_error('You are using deprecated API v1.1 in Net_NNTP_Client: getHeader() !', E_USER_NOTICE); $class = $implode; $implode = false; if (!class_exists($class)) { return $this->throwError("Class '$class' does not exist!"); } } $data = $this->cmdArticle($article); if (PEAR::isError($data)) { return $data; } if ($implode == true) { $data = implode("\r\n", $data); } // v1.1.x API if (isset($class)) { return $obj = new $class($data); } // return $data; } // }}} // {{{ getHeader() /** * Fetch article header. * * Select an article based on the arguments, and return the article * header (raw data). * * Usage example: * {@example docs/examples/phpdoc/getHeader.php} * * @param mixed $article (optional) Either message-id or message * number of the article to fetch. * @param bool $implode (optional) When true the result array * is imploded to a string, defaults to * false. * * @return mixed
* - (bool) False if article does not exist * - (array) Header fields (when $implode is false) * - (string) Header fields (when $implode is true) * - (object) Pear_Error on failure * @access public * @see Net_NNTP_Client::getArticle() * @see Net_NNTP_Client::getBody() */ function getHeader($article = null, $implode = false) { // v1.1.x API if (is_string($implode)) { trigger_error('You are using deprecated API v1.1 in Net_NNTP_Client: getHeader() !', E_USER_NOTICE); $class = $implode; $implode = false; if (!class_exists($class)) { return $this->throwError("Class '$class' does not exist!"); } } $data = $this->cmdHead($article); if (PEAR::isError($data)) { return $data; } if ($implode == true) { $data = implode("\r\n", $data); } // v1.1.x API if (isset($class)) { return $obj = new $class($data); } // return $data; } // }}} // {{{ getBody() /** * Fetch article body. * * Select an article based on the arguments, and return the article * body (raw data). * * Usage example: * {@example docs/examples/phpdoc/getBody.php} * * @param mixed $article (optional) Either the message-id or the * message-number on the server of the * article to fetch. * @param bool $implode (optional) When true the result array * is imploded to a string, defaults to * false. * * @return mixed
* - (array) Message body (when $implode is false) * - (string) Message body (when $implode is true) * - (object) Pear_Error on failure * @access public * @see Net_NNTP_Client::getHeader() * @see Net_NNTP_Client::getArticle() */ function getBody($article = null, $implode = false) { // v1.1.x API if (is_string($implode)) { trigger_error('You are using deprecated API v1.1 in Net_NNTP_Client: getHeader() !', E_USER_NOTICE); $class = $implode; $implode = false; if (!class_exists($class)) { return $this->throwError("Class '$class' does not exist!"); } } $data = $this->cmdBody($article); if (PEAR::isError($data)) { return $data; } if ($implode == true) { $data = implode("\r\n", $data); } // v1.1.x API if (isset($class)) { return $obj = new $class($data); } // return $data; } // }}} // {{{ post() /** * Post a raw article to a number of groups. * * Usage example: * {@example docs/examples/phpdoc/post.php} * * @param mixed $article
* - (string) Complete article in a ready to send format (lines terminated by LFCR etc.) * - (array) First key is the article header, second key is article body - any further keys are ignored !!! * - (mixed) Something 'callable' (which must return otherwise acceptable data as replacement) * * @return mixed
* - (string) Server response * - (object) Pear_Error on failure * @access public * @ignore */ function post($article) { // API v1.0 if (func_num_args() >= 4) { // trigger_error('You are using deprecated API v1.0 in Net_NNTP_Client: post() !', E_USER_NOTICE); // $groups = func_get_arg(0); $subject = func_get_arg(1); $body = func_get_arg(2); $from = func_get_arg(3); $additional = func_get_arg(4); return $this->mail($groups, $subject, $body, "From: $from\r\n" . $additional); } // Only accept $article if array or string if (!is_array($article) && !is_string($article)) { return $this->throwError('Ups', null, 0); } // Check if server will receive an article $post = $this->cmdPost(); if (PEAR::isError($post)) { return $post; } // Get article data from callback function if (is_callable($article)) { $article = call_user_func($article); } // Actually send the article return $this->cmdPost2($article); } // }}} // {{{ mail() /** * Post an article to a number of groups - using same parameters as PHP's mail() function. * * Among the aditional headers you might think of adding could be: * "From: ", which should contain the e-mail address * of the author of the article. * Or "Organization: " which contain the name of the organization * the post originates from. * Or "NNTP-Posting-Host: ", which should contain the IP-address * of the author of the post, so the message can be traced back to him. * * Usage example: * {@example docs/examples/phpdoc/mail.php} * * @param string $groups The groups to post to. * @param string $subject The subject of the article. * @param string $body The body of the article. * @param string $additional (optional) Additional header fields to send. * * @return mixed
* - (string) Server response * - (object) Pear_Error on failure * @access public */ function mail($groups, $subject, $body, $additional = null) { // Check if server will receive an article $post = $this->cmdPost(); if (PEAR::isError($post)) { return $post; } // Construct header $header = "Newsgroups: $groups\r\n"; $header .= "Subject: $subject\r\n"; $header .= "X-poster: PEAR::Net_NNTP v1.5.0 (stable)\r\n"; if ($additional !== null) { $header .= $additional; } $header .= "\r\n"; // Actually send the article return $this->cmdPost2(array($header, $body)); } // }}} // {{{ getDate() /** * Get the server's internal date * * Non-standard!
* This method uses non-standard commands, which is not part * of the original RFC977, but has been formalized in RFC2890. * * Usage example: * {@example docs/examples/phpdoc/getDate.php} * * @param int $format (optional) Determines the format of returned date: * - 0: return string * - 1: return integer/timestamp * - 2: return an array('y'=>year, 'm'=>month,'d'=>day) * * @return mixed
* - (mixed) * - (object) Pear_Error on failure * @access public */ function getDate($format = 1) { $date = $this->cmdDate(); if (PEAR::isError($date)) { return $date; } switch ($format) { case 0: return $date; break; case 1: return strtotime(substr($date, 0, 8).' '.substr($date, 8, 2).':'.substr($date, 10, 2).':'.substr($date, 12, 2)); break; case 2: return array('y' => substr($date, 0, 4), 'm' => substr($date, 4, 2), 'd' => substr($date, 6, 2)); break; default: error(); } } // }}} // {{{ getNewGroups() /** * Get new groups since a date. * * Returns a list of groups created on the server since the specified date * and time. * * Usage example: * {@example docs/examples/phpdoc/getNewGroups.php} * * @param mixed $time
* - (integer) A timestamp * - (string) Somthing parseable by strtotime() like '-1 week' * @param string $distributions (optional) * * @return mixed
* - (array) * - (object) Pear_Error on failure * @access public */ function getNewGroups($time, $distributions = null) { switch (true) { case is_integer($time): break; case is_string($time): $time = strtotime($time); if ($time === false || ($time === -1 && version_compare(phpversion(), '5.1.0', '<'))) { return $this->throwError('$time could not be converted into a timestamp!', null, 0); } break; default: trigger_error('$time must be either a string or an integer/timestamp!', E_USER_ERROR); } return $this->cmdNewgroups($time, $distributions); } // }}} // {{{ getNewArticles() /** * Get new articles since a date. * * Returns a list of message-ids of new articles (since the specified date * and time) in the groups whose names match the wildmat * * Usage example: * {@example docs/examples/phpdoc/getNewArticles.php} * * @param mixed $time
* - (integer) A timestamp * - (string) Somthing parseable by strtotime() like '-1 week' * @param string $groups (optional) * @param string $distributions (optional) * * @return mixed
* - (array) * - (object) Pear_Error on failure * @access public * @since 1.3.0 */ function getNewArticles($time, $groups = '*', $distribution = null) { switch (true) { case is_integer($time): break; case is_string($time): $time = strtotime($time); if ($time === false || ($time === -1 && version_compare(php_version(), '5.1.0', '<'))) { return $this->throwError('$time could not be converted into a timestamp!', null, 0); } break; default: trigger_error('$time must be either a string or an integer/timestamp!', E_USER_ERROR); } return $this->cmdNewnews($time, $groups, $distribution); } // }}} // {{{ getGroups() /** * Fetch valid groups. * * Returns a list of valid groups (that the client is permitted to select) * and associated information. * * Usage example: * {@example docs/examples/phpdoc/getGroups.php} * * @return mixed
* - (array) Nested array with information about every valid group * - (object) Pear_Error on failure * @access public * @see Net_NNTP_Client::getDescriptions() * @see Net_NNTP_Client::selectGroup() */ function getGroups($wildmat = null) { $backup = false; // Get groups $groups = $this->cmdListActive($wildmat); if (PEAR::isError($groups)) { switch ($groups->getCode()) { case 500: case 501: $backup = true; break; default: return $groups; } } // if ($backup == true) { // if (!is_null($wildmat)) { return $this->throwError("The server does not support the 'LIST ACTIVE' command, and the 'LIST' command does not support the wildmat parameter!", null, null); } // $groups2 = $this->cmdList(); if (PEAR::isError($groups2)) { // Ignore... } else { $groups = $groups2; } } if (PEAR::isError($groups)) { return $groups; } return $groups; } // }}} // {{{ getDescriptions() /** * Fetch all known group descriptions. * * Fetches a list of known group descriptions - including groups which * the client is not permitted to select. * * Non-standard!
* This method uses non-standard commands, which is not part * of the original RFC977, but has been formalized in RFC2890. * * Usage example: * {@example docs/examples/phpdoc/getDescriptions.php} * * @param mixed $wildmat (optional) * * @return mixed
* - (array) Associated array with descriptions of known groups * - (object) Pear_Error on failure * @access public * @see Net_NNTP_Client::getGroups() */ function getDescriptions($wildmat = null) { if (is_array($wildmat)) { $wildmat = implode(',', $wildmat); } // Get group descriptions $descriptions = $this->cmdListNewsgroups($wildmat); if (PEAR::isError($descriptions)) { return $descriptions; } // TODO: add xgtitle as backup return $descriptions; } // }}} // {{{ getOverview() /** * Fetch an overview of article(s) in the currently selected group. * * Returns the contents of all the fields in the database for a number * of articles specified by either article-numnber range, a message-id, * or nothing (indicating currently selected article). * * The first 8 fields per article is always as follows: * - 'Number' - '0' or the article number of the currently selected group. * - 'Subject' - header content. * - 'From' - header content. * - 'Date' - header content. * - 'Message-ID' - header content. * - 'References' - header content. * - ':bytes' - metadata item. * - ':lines' - metadata item. * * The server may send more fields form it's database... * * Non-standard!
* This method uses non-standard commands, which is not part * of the original RFC977, but has been formalized in RFC2890. * * Usage example: * {@example docs/examples/phpdoc/getOverview.php} * * @param mixed $range (optional) * - '' * - '-' * - '-' * - '' * @param boolean $_names (optional) experimental parameter! Use field names as array kays * @param boolean $_forceNames (optional) experimental parameter! * * @return mixed
* - (array) Nested array of article overview data * - (object) Pear_Error on failure * @access public * @see Net_NNTP_Client::getHeaderField() * @see Net_NNTP_Client::getOverviewFormat() */ function getOverview($range = null, $_names = true, $_forceNames = true) { // API v1.0 switch (true) { // API v1.3 case func_num_args() != 2: case is_bool(func_get_arg(1)): case !is_int(func_get_arg(1)) || (is_string(func_get_arg(1)) && ctype_digit(func_get_arg(1))): case !is_int(func_get_arg(0)) || (is_string(func_get_arg(0)) && ctype_digit(func_get_arg(0))): break; default: // trigger_error('You are using deprecated API v1.0 in Net_NNTP_Client: getOverview() !', E_USER_NOTICE); // Fetch overview via API v1.3 $overview = $this->getOverview(func_get_arg(0) . '-' . func_get_arg(1), true, false); if (PEAR::isError($overview)) { return $overview; } // Create and return API v1.0 compliant array $articles = array(); foreach ($overview as $article) { // Rename 'Number' field into 'number' $article = array_merge(array('number' => array_shift($article)), $article); // Use 'Message-ID' field as key $articles[$article['Message-ID']] = $article; } return $articles; } // Fetch overview from server $overview = $this->cmdXOver($range); if (PEAR::isError($overview)) { return $overview; } // Use field names from overview format as keys? if ($_names) { // Already cached? if (is_null($this->_overviewFormatCache)) { // Fetch overview format $format = $this->getOverviewFormat($_forceNames, true); if (PEAR::isError($format)){ return $format; } // Prepend 'Number' field $format = array_merge(array('Number' => false), $format); // Cache format $this->_overviewFormatCache = $format; // } else { $format = $this->_overviewFormatCache; } // Loop through all articles foreach ($overview as $key => $article) { // Copy $format $f = $format; // Field counter $i = 0; // Loop through forld names in format foreach ($f as $tag => $full) { // $f[$tag] = $article[$i++]; // If prefixed by field name, remove it if ($full === true) { $f[$tag] = ltrim( substr($f[$tag], strpos($f[$tag], ':') + 1), " \t"); } } // Replace article $overview[$key] = $f; } } // switch (true) { // Expect one article case is_null($range); case is_int($range); case is_string($range) && ctype_digit($range): case is_string($range) && substr($range, 0, 1) == '<' && substr($range, -1, 1) == '>': if (count($overview) == 0) { return false; } else { return reset($overview); } break; // Expect multiple articles default: return $overview; } } // }}} // {{{ getOverviewFormat() /** * Fetch names of fields in overview database * * Returns a description of the fields in the database for which it is consistent. * * Non-standard!
* This method uses non-standard commands, which is not part * of the original RFC977, but has been formalized in RFC2890. * * Usage example: * {@example docs/examples/phpdoc/getOveriewFormat.php} * * @return mixed
* - (array) Overview field names * - (object) Pear_Error on failure * @access public * @see Net_NNTP_Client::getOverview() */ function getOverviewFormat($_forceNames = true, $_full = false) { $format = $this->cmdListOverviewFmt(); if (PEAR::isError($format)) { return $format; } // Force name of first seven fields if ($_forceNames) { array_splice($format, 0, 7); $format = array_merge(array('Subject' => false, 'From' => false, 'Date' => false, 'Message-ID' => false, 'References' => false, ':bytes' => false, ':lines' => false), $format); } if ($_full) { return $format; } else { return array_keys($format); } } // }}} // {{{ getHeaderField() /** * Fetch content of a header field from message(s). * * Retreives the content of specific header field from a number of messages. * * Non-standard!
* This method uses non-standard commands, which is not part * of the original RFC977, but has been formalized in RFC2890. * * Usage example: * {@example docs/examples/phpdoc/getHeaderField.php} * * @param string $field The name of the header field to retreive * @param mixed $range (optional) * '' * '-' * '-' * '' * * @return mixed
* - (array) Nested array of * - (object) Pear_Error on failure * @access public * @see Net_NNTP_Client::getOverview() * @see Net_NNTP_Client::getReferences() */ function getHeaderField($field, $range = null) { $fields = $this->cmdXHdr($field, $range); if (PEAR::isError($fields)) { return $fields; } // switch (true) { // Expect one article case is_null($range); case is_int($range); case is_string($range) && ctype_digit($range): case is_string($range) && substr($range, 0, 1) == '<' && substr($range, -1, 1) == '>': if (count($fields) == 0) { return false; } else { return reset($fields); } break; // Expect multiple articles default: return $fields; } } // }}} // {{{ getGroupArticles() /** * * * Non-standard!
* This method uses non-standard commands, which is not part * of the original RFC977, but has been formalized in RFC2890. * * Usage example: * {@example docs/examples/phpdoc/getGroupArticles.php} * * @param mixed $range (optional) Experimental! * * @return mixed
* - (array) * - (object) Pear_Error on failure * @access public * @since 1.3.0 */ function getGroupArticles($range = null) { $summary = $this->cmdListgroup(); if (PEAR::isError($summary)) { return $summary; } // Update summary cache if group was also 'selected' if ($summary['group'] !== null) { $this->_selectedGroupSummary($summary); } // return $summary['articles']; } // }}} // {{{ getReferences() /** * Fetch reference header field of message(s). * * Retrieves the content of the references header field of messages via * either the XHDR ord the XROVER command. * * Identical to getHeaderField('References'). * * Non-standard!
* This method uses non-standard commands, which is not part * of the original RFC977, but has been formalized in RFC2890. * * Usage example: * {@example docs/examples/phpdoc/getReferences.php} * * @param mixed $range (optional) * '' * '-' * '-' * '' * * @return mixed
* - (array) Nested array of references * - (object) Pear_Error on failure * @access public * @see Net_NNTP_Client::getHeaderField() */ function getReferences($range = null) { $backup = false; $references = $this->cmdXHdr('References', $range); if (PEAR::isError($references)) { switch ($references->getCode()) { case 500: case 501: $backup = true; break; default: return $references; } } if (true && (is_array($references) && count($references) == 0)) { $backup = true; } if ($backup == true) { $references2 = $this->cmdXROver($range); if (PEAR::isError($references2)) { // Ignore... } else { $references = $references2; } } if (PEAR::isError($references)) { return $references; } if (is_array($references)) { foreach ($references as $key => $val) { $references[$key] = preg_split("/ +/", trim($val), -1, PREG_SPLIT_NO_EMPTY); } } // switch (true) { // Expect one article case is_null($range); case is_int($range); case is_string($range) && ctype_digit($range): case is_string($range) && substr($range, 0, 1) == '<' && substr($range, -1, 1) == '>': if (count($references) == 0) { return false; } else { return reset($references); } break; // Expect multiple articles default: return $references; } } // }}} // {{{ count() /** * Number of articles in currently selected group * * Usage example: * {@example docs/examples/phpdoc/count.php} * * @return mixed
* - (string) the number of article in group * - (object) Pear_Error on failure * @access public * @see Net_NNTP_Client::group() * @see Net_NNTP_Client::first() * @see Net_NNTP_Client::last() * @see Net_NNTP_Client::selectGroup() * @ignore */ function count() { return $this->_selectedGroupSummary['count']; } // }}} // {{{ last() /** * Maximum article number in currently selected group * * Usage example: * {@example docs/examples/phpdoc/last.php} * * @return mixed
* - (string) the last article's number * - (object) Pear_Error on failure * @access public * @see Net_NNTP_Client::first() * @see Net_NNTP_Client::group() * @see Net_NNTP_Client::count() * @see Net_NNTP_Client::selectGroup() * @ignore */ function last() { return $this->_selectedGroupSummary['last']; } // }}} // {{{ first() /** * Minimum article number in currently selected group * * Usage example: * {@example docs/examples/phpdoc/first.php} * * @return mixed
* - (string) the first article's number * - (object) Pear_Error on failure * @access public * @see Net_NNTP_Client::last() * @see Net_NNTP_Client::group() * @see Net_NNTP_Client::count() * @see Net_NNTP_Client::selectGroup() * @ignore */ function first() { return $this->_selectedGroupSummary['first']; } // }}} // {{{ group() /** * Currently selected group * * Usage example: * {@example docs/examples/phpdoc/group.php} * * @return mixed
* - (string) group name * - (object) Pear_Error on failure * @access public * @see Net_NNTP_Client::first() * @see Net_NNTP_Client::last() * @see Net_NNTP_Client::count() * @see Net_NNTP_Client::selectGroup() * @ignore */ function group() { return $this->_selectedGroupSummary['group']; } // }}} // {{{ isConnected() /** * Test whether a connection is currently open or closed. * * @return bool True if connected, otherwise false * @access public * @see Net_NNTP_Client::connect() * @see Net_NNTP_Client::quit() * @deprecated since v1.3.0 due to use of protected method: Net_NNTP_Protocol_Client::isConnected() * @ignore */ function isConnected() { trigger_error('You are using deprecated API v1.0 in Net_NNTP_Client: isConnected() !', E_USER_NOTICE); return parent::_isConnected(); } // }}} // {{{ getArticleRaw() /** * Deprecated alias for getArticle() * * @deprecated * @ignore */ function getArticleRaw($article, $implode = false) { trigger_error('You are using deprecated API v1.0 in Net_NNTP_Client: getArticleRaw() !', E_USER_NOTICE); return $this->getArticle($article, $implode); } // }}} // {{{ getHeaderRaw() /** * Deprecated alias for getHeader() * * @deprecated * @ignore */ function getHeaderRaw($article = null, $implode = false) { trigger_error('You are using deprecated API v1.0 in Net_NNTP_Client: getHeaderRaw() !', E_USER_NOTICE); return $this->getHeader($article, $implode); } // }}} // {{{ getBodyRaw() /** * Deprecated alias for getBody() * * @deprecated * @ignore */ function getBodyRaw($article = null, $implode = false) { trigger_error('You are using deprecated API v1.0 in Net_NNTP_Client: getBodyRaw() !', E_USER_NOTICE); return $this->getBody($article, $implode); } // }}} // {{{ getNewNews() /** * Deprecated alias for getNewArticles() * * @deprecated * @ignore */ function getNewNews($time, $groups = '*', $distribution = null) { trigger_error('You are using deprecated API v1.1 in Net_NNTP_Client: getNewNews() !', E_USER_NOTICE); return $this->getNewArticles($time, $groups, $distribution); } // }}} // {{{ getReferencesOverview() /** * Deprecated alias for getReferences() * * @deprecated * @ignore */ function getReferencesOverview($first, $last) { trigger_error('You are using deprecated API v1.0 in Net_NNTP_Client: getReferencesOverview() !', E_USER_NOTICE); return $this->getReferences($first . '-' . $last); } // }}} } // }}} /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * c-hanging-comment-ender-p: nil * End: */ ?> php-net-nntp-1.5.0/Net_NNTP-1.5.0/NNTP/Protocol/000077500000000000000000000000001215221406100204435ustar00rootroot00000000000000php-net-nntp-1.5.0/Net_NNTP-1.5.0/NNTP/Protocol/Client.php000066400000000000000000002123671215221406100224050ustar00rootroot00000000000000 * +-----------------------------------------------------------------------+ * | | * | W3CŪ SOFTWARE NOTICE AND LICENSE | * | http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 | * | | * | This work (and included software, documentation such as READMEs, | * | or other related items) is being provided by the copyright holders | * | under the following license. By obtaining, using and/or copying | * | this work, you (the licensee) agree that you have read, understood, | * | and will comply with the following terms and conditions. | * | | * | Permission to copy, modify, and distribute this software and its | * | documentation, with or without modification, for any purpose and | * | without fee or royalty is hereby granted, provided that you include | * | the following on ALL copies of the software and documentation or | * | portions thereof, including modifications: | * | | * | 1. The full text of this NOTICE in a location viewable to users | * | of the redistributed or derivative work. | * | | * | 2. Any pre-existing intellectual property disclaimers, notices, | * | or terms and conditions. If none exist, the W3C Software Short | * | Notice should be included (hypertext is preferred, text is | * | permitted) within the body of any redistributed or derivative | * | code. | * | | * | 3. Notice of any changes or modifications to the files, including | * | the date changes were made. (We recommend you provide URIs to | * | the location from which the code is derived.) | * | | * | THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT | * | HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, | * | INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR | * | FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE | * | OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, | * | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. | * | | * | COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, | * | SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE | * | SOFTWARE OR DOCUMENTATION. | * | | * | The name and trademarks of copyright holders may NOT be used in | * | advertising or publicity pertaining to the software without | * | specific, written prior permission. Title to copyright in this | * | software and any associated documentation will at all times | * | remain with copyright holders. | * | | * +-----------------------------------------------------------------------+ * * * @category Net * @package Net_NNTP * @author Heino H. Gehlsen * @copyright 2002-2011 Heino H. Gehlsen . All Rights Reserved. * @license http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 W3CŪ SOFTWARE NOTICE AND LICENSE * @version SVN: $Id: Client.php 330426 2013-05-31 14:41:46Z janpascal $ * @link http://pear.php.net/package/Net_NNTP * @see */ // Warn about PHP bugs if (version_compare(PHP_VERSION, '5.2.11') === 0) { trigger_error('PHP bug #16657 breaks feof() on socket streams! Connection consistency might be compromised!', E_USER_WARNING); } /** * */ require_once 'PEAR.php'; //require_once 'Net/NNTP/Error.php'; require_once 'Net/NNTP/Protocol/Responsecode.php'; // {{{ constants /** * Default host * * @access public * @ignore */ define('NET_NNTP_PROTOCOL_CLIENT_DEFAULT_HOST', 'localhost'); /** * Default port * * @access public * @ignore */ define('NET_NNTP_PROTOCOL_CLIENT_DEFAULT_PORT', '119'); // }}} // {{{ Net_NNTP_Protocol_Client /** * Low level NNTP Client * * Implements the client part of the NNTP standard acording to: * - RFC 977, * - RFC 2980, * - RFC 850/1036, and * - RFC 822/2822 * * Each NNTP command is represented by a method: cmd*() * * WARNING: The Net_NNTP_Protocol_Client class is considered an internal class * (and should therefore currently not be extended directly outside of * the Net_NNTP package). Therefore its API is NOT required to be fully * stable, for as long as such changes doesn't affect the public API of * the Net_NNTP_Client class, which is considered stable. * * TODO: cmdListActiveTimes() * cmdDistribPats() * * @category Net * @package Net_NNTP * @author Heino H. Gehlsen * @version package: 1.5.0 (stable) * @version api: 0.9.0 (alpha) * @access private * @see Net_NNTP_Client */ class Net_NNTP_Protocol_Client extends PEAR { // {{{ properties /** * The socket resource being used to connect to the NNTP server. * * @var resource * @access private */ var $_socket = null; /** * Contains the last recieved status response code and text * * @var array * @access private */ var $_currentStatusResponse = null; /** * * * @var object * @access private */ var $_logger = null; // }}} // {{{ constructor /** * Constructor * * @access public */ function Net_NNTP_Protocol_Client() { // // parent::PEAR('Net_NNTP_Error'); parent::PEAR(); } // }}} // {{{ getPackageVersion() /** * * * @access public */ function getPackageVersion() { return '1.5.0'; } // }}} // {{{ getApiVersion() /** * * * @access public */ function getApiVersion() { return '0.9.0'; } // }}} // {{{ setLogger() /** * * * @param object $logger * * @access protected */ function setLogger($logger) { $this->_logger = $logger; } // }}} // {{{ setDebug() /** * @deprecated */ function setDebug($debug = true) { trigger_error('You are using deprecated API v1.0 in Net_NNTP_Protocol_Client: setDebug() ! Debugging in now automatically handled when a logger is given.', E_USER_NOTICE); } // }}} // {{{ _sendCommand() /** * Send command * * Send a command to the server. A carriage return / linefeed (CRLF) sequence * will be appended to each command string before it is sent to the IMAP server. * * @param string $cmd The command to launch, ie: "ARTICLE 1004853" * * @return mixed (int) response code on success or (object) pear_error on failure * @access private */ function _sendCommand($cmd) { // NNTP/RFC977 only allows command up to 512 (-2) chars. if (!strlen($cmd) > 510) { return $this->throwError('Failed writing to socket! (Command to long - max 510 chars)'); } /***************************************************************************************/ /* Credit: Thanks to Brendan Coles (http://itsecuritysolutions.org) */ /* for pointing out possibility to inject pipelined NNTP commands into pretty */ /* much any Net_NNTP command-sending function with user input, by appending */ /* a new line character followed by the injection. */ /***************************************************************************************/ // Prevent new line (and possible future) characters in the NNTP commands // Net_NNTP does not support pipelined commands. Inserting a new line charecter // allows sending multiple commands and thereby making the communication between // NET_NNTP and the server out of sync... if (preg_match_all('/\r?\n/', $cmd, $matches, PREG_PATTERN_ORDER)) { foreach ($matches[0] as $key => $match) { $this->_logger->debug("Illegal character in command: ". htmlentities(str_replace(array("\r","\n"), array("'Carriage Return'", "'New Line'"), $match))); } return $this->throwError("Illegal character(s) in NNTP command!"); } // Check if connected if (!$this->_isConnected()) { return $this->throwError('Failed to write to socket! (connection lost!)'); } // Send the command $R = @fwrite($this->_socket, $cmd . "\r\n"); if ($R === false) { return $this->throwError('Failed to write to socket!'); } // if ($this->_logger && $this->_logger->_isMasked(PEAR_LOG_DEBUG)) { $this->_logger->debug('C: ' . $cmd); } // return $this->_getStatusResponse(); } // }}} // {{{ _getStatusResponse() /** * Get servers status response after a command. * * @return mixed (int) statuscode on success or (object) pear_error on failure * @access private */ function _getStatusResponse() { // Retrieve a line (terminated by "\r\n") from the server. // RFC says max is 510, but IETF says "be liberal in what you accept"... $response = @fgets($this->_socket, 4096); if ($response === false) { return $this->throwError('Failed to read from socket...!'); } // if ($this->_logger && $this->_logger->_isMasked(PEAR_LOG_DEBUG)) { $this->_logger->debug('S: ' . rtrim($response, "\r\n")); } // Trim the start of the response in case of misplased whitespace (should not be needen!!!) $response = ltrim($response); $this->_currentStatusResponse = array( (int) substr($response, 0, 3), (string) rtrim(substr($response, 4)) ); // return $this->_currentStatusResponse[0]; } // }}} // {{{ _getTextResponse() /** * Retrieve textural data * * Get data until a line with only a '.' in it is read and return data. * * @return mixed (array) text response on success or (object) pear_error on failure * @access private */ function _getTextResponse() { $data = array(); $line = ''; // $debug = $this->_logger && $this->_logger->_isMasked(PEAR_LOG_DEBUG); // Continue until connection is lost while (!feof($this->_socket)) { // Retrieve and append up to 1024 characters from the server. $recieved = @fgets($this->_socket, 1024); if ($recieved === false) { return $this->throwError('Failed to read line from socket.', null); } $line .= $recieved; // Continue if the line is not terminated by CRLF if (substr($line, -2) != "\r\n" || strlen($line) < 2) { continue; } // Validate recieved line if (false) { // Lines should/may not be longer than 998+2 chars (RFC2822 2.3) if (strlen($line) > 1000) { if ($this->_logger) { $this->_logger->notice('Max line length...'); } return $this->throwError('Invalid line recieved!', null); } } // Remove CRLF from the end of the line $line = substr($line, 0, -2); // Check if the line terminates the textresponse if ($line == '.') { if ($this->_logger) { $this->_logger->debug('T: ' . $line); } // return all previous lines return $data; } // If 1st char is '.' it's doubled (NNTP/RFC977 2.4.1) if (substr($line, 0, 2) == '..') { $line = substr($line, 1); } // if ($debug) { $this->_logger->debug('T: ' . $line); } // Add the line to the array of lines $data[] = $line; // Reset/empty $line $line = ''; } if ($this->_logger) { $this->_logger->warning('Broke out of reception loop! This souldn\'t happen unless connection has been lost?'); } // return $this->throwError('End of stream! Connection lost?', null); } // }}} // {{{ _sendText() /** * * * @access private */ function _sendArticle($article) { /* data should be in the format specified by RFC850 */ switch (true) { case is_string($article): // @fwrite($this->_socket, $article); @fwrite($this->_socket, "\r\n.\r\n"); // if ($this->_logger && $this->_logger->_isMasked(PEAR_LOG_DEBUG)) { foreach (explode("\r\n", $article) as $line) { $this->_logger->debug('D: ' . $line); } $this->_logger->debug('D: .'); } break; case is_array($article): // $header = reset($article); $body = next($article); /* Experimental... // If header is an array, implode it. if (is_array($header)) { $header = implode("\r\n", $header) . "\r\n"; } */ // Send header (including separation line) @fwrite($this->_socket, $header); @fwrite($this->_socket, "\r\n"); // if ($this->_logger && $this->_logger->_isMasked(PEAR_LOG_DEBUG)) { foreach (explode("\r\n", $header) as $line) { $this->_logger->debug('D: ' . $line); } } /* Experimental... // If body is an array, implode it. if (is_array($body)) { $header = implode("\r\n", $body) . "\r\n"; } */ // Send body @fwrite($this->_socket, $body); @fwrite($this->_socket, "\r\n.\r\n"); // if ($this->_logger && $this->_logger->_isMasked(PEAR_LOG_DEBUG)) { foreach (explode("\r\n", $body) as $line) { $this->_logger->debug('D: ' . $line); } $this->_logger->debug('D: .'); } break; default: return $this->throwError('Ups...', null, null); } return true; } // }}} // {{{ _currentStatusResponse() /** * * * @return string status text * @access private */ function _currentStatusResponse() { return $this->_currentStatusResponse[1]; } // }}} // {{{ _handleUnexpectedResponse() /** * * * @param int $code Status code number * @param string $text Status text * * @return mixed * @access private */ function _handleUnexpectedResponse($code = null, $text = null) { if ($code === null) { $code = $this->_currentStatusResponse[0]; } if ($text === null) { $text = $this->_currentStatusResponse(); } switch ($code) { case NET_NNTP_PROTOCOL_RESPONSECODE_NOT_PERMITTED: // 502, 'access restriction or permission denied' / service permanently unavailable return $this->throwError('Command not permitted / Access restriction / Permission denied', $code, $text); break; default: return $this->throwError("Unexpected response: '$text'", $code, $text); } } // }}} /* Session administration commands */ // {{{ Connect() /** * Connect to a NNTP server * * @param string $host (optional) The address of the NNTP-server to connect to, defaults to 'localhost'. * @param mixed $encryption (optional) * @param int $port (optional) The port number to connect to, defaults to 119. * @param int $timeout (optional) * * @return mixed (bool) on success (true when posting allowed, otherwise false) or (object) pear_error on failure * @access protected */ function connect($host = null, $encryption = null, $port = null, $timeout = null) { // if ($this->_isConnected() ) { return $this->throwError('Already connected, disconnect first!', null); } // v1.0.x API if (is_int($encryption)) { trigger_error('You are using deprecated API v1.0 in Net_NNTP_Protocol_Client: connect() !', E_USER_NOTICE); $port = $encryption; $encryption = false; } // if (is_null($host)) { $host = 'localhost'; } // Choose transport based on encryption, and if no port is given, use default for that encryption switch ($encryption) { case null: case false: $transport = 'tcp'; $port = is_null($port) ? 119 : $port; break; case 'ssl': case 'tls': $transport = $encryption; $port = is_null($port) ? 563 : $port; break; default: trigger_error('$encryption parameter must be either tcp, tls or ssl.', E_USER_ERROR); } // if (is_null($timeout)) { $timeout = 15; } // Open Connection $R = stream_socket_client($transport . '://' . $host . ':' . $port, $errno, $errstr, $timeout); if ($R === false) { if ($this->_logger) { $this->_logger->notice("Connection to $transport://$host:$port failed."); } return $R; } $this->_socket = $R; // if ($this->_logger) { $this->_logger->info("Connection to $transport://$host:$port has been established."); } // Retrive the server's initial response. $response = $this->_getStatusResponse(); if (PEAR::isError($response)) { return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_READY_POSTING_ALLOWED: // 200, Posting allowed // TODO: Set some variable before return return true; break; case NET_NNTP_PROTOCOL_RESPONSECODE_READY_POSTING_PROHIBITED: // 201, Posting NOT allowed // if ($this->_logger) { $this->_logger->info('Posting not allowed!'); } // TODO: Set some variable before return return false; break; case 400: return $this->throwError('Server refused connection', $response, $this->_currentStatusResponse()); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NOT_PERMITTED: // 502, 'access restriction or permission denied' / service permanently unavailable return $this->throwError('Server refused connection', $response, $this->_currentStatusResponse()); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ disconnect() /** * alias for cmdQuit() * * @access protected */ function disconnect() { return $this->cmdQuit(); } // }}} // {{{ cmdCapabilities() /** * Returns servers capabilities * * @return mixed (array) list of capabilities on success or (object) pear_error on failure * @access protected */ function cmdCapabilities() { // tell the newsserver we want an article $response = $this->_sendCommand('CAPABILITIES'); if (PEAR::isError($response)) { return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_CAPABILITIES_FOLLOW: // 101, Draft: 'Capability list follows' $data = $this->_getTextResponse(); if (PEAR::isError($data)) { return $data; } return $data; break; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ cmdModeReader() /** * * * @return mixed (bool) true when posting allowed, false when postind disallowed or (object) pear_error on failure * @access protected */ function cmdModeReader() { // tell the newsserver we want an article $response = $this->_sendCommand('MODE READER'); if (PEAR::isError($response)) { return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_READY_POSTING_ALLOWED: // 200, RFC2980: 'Hello, you can post' // TODO: Set some variable before return return true; break; case NET_NNTP_PROTOCOL_RESPONSECODE_READY_POSTING_PROHIBITED: // 201, RFC2980: 'Hello, you can't post' if ($this->_logger) { $this->_logger->info('Posting not allowed!'); } // TODO: Set some variable before return return false; break; case NET_NNTP_PROTOCOL_RESPONSECODE_NOT_PERMITTED: // 502, 'access restriction or permission denied' / service permanently unavailable return $this->throwError('Connection being closed, since service so permanently unavailable', $response, $this->_currentStatusResponse()); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ cmdQuit() /** * Disconnect from the NNTP server * * @return mixed (bool) true on success or (object) pear_error on failure * @access protected */ function cmdQuit() { // Tell the server to close the connection $response = $this->_sendCommand('QUIT'); if (PEAR::isError($response)) { return $response; } switch ($response) { case 205: // RFC977: 'closing connection - goodbye!' // If socket is still open, close it. if ($this->_isConnected()) { fclose($this->_socket); } if ($this->_logger) { $this->_logger->info('Connection closed.'); } return true; break; default: return $this->_handleUnexpectedResponse($response); } } // }}} /* */ // {{{ cmdStartTLS() /** * * * @return mixed (bool) on success or (object) pear_error on failure * @access protected */ function cmdStartTLS() { $response = $this->_sendCommand('STARTTLS'); if (PEAR::isError($response)) { return $response; } switch ($response) { case 382: // RFC4642: 'continue with TLS negotiation' $encrypted = stream_socket_enable_crypto($this->_socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT); switch (true) { case $encrypted === true: if ($this->_logger) { $this->_logger->info('TLS encryption started.'); } return true; break; case $encrypted === true: if ($this->_logger) { $this->_logger->info('TLS encryption failed.'); } return $this->throwError('Could not initiate TLS negotiation', $response, $this->_currentStatusResponse()); break; case is_int($encrypted): return $this->throwError('', $response, $this->_currentStatusResponse()); break; default: return $this->throwError('Internal error - unknown response from stream_socket_enable_crypto()', $response, $this->_currentStatusResponse()); } break; case 580: // RFC4642: 'can not initiate TLS negotiation' return $this->throwError('', $response, $this->_currentStatusResponse()); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} /* Article posting and retrieval */ /* Group and article selection */ // {{{ cmdGroup() /** * Selects a news group (issue a GROUP command to the server) * * @param string $newsgroup The newsgroup name * * @return mixed (array) groupinfo on success or (object) pear_error on failure * @access protected */ function cmdGroup($newsgroup) { $response = $this->_sendCommand('GROUP '.$newsgroup); if (PEAR::isError($response)) { return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_GROUP_SELECTED: // 211, RFC977: 'n f l s group selected' $response_arr = explode(' ', trim($this->_currentStatusResponse())); if ($this->_logger) { $this->_logger->info('Group selected: '.$response_arr[3]); } return array('group' => $response_arr[3], 'first' => $response_arr[1], 'last' => $response_arr[2], 'count' => $response_arr[0]); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_GROUP: // 411, RFC977: 'no such news group' return $this->throwError('No such news group', $response, $this->_currentStatusResponse()); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ cmdListgroup() /** * * * @param optional string $newsgroup * @param optional mixed $range * * @return optional mixed (array) on success or (object) pear_error on failure * @access protected */ function cmdListgroup($newsgroup = null, $range = null) { if (is_null($newsgroup)) { $command = 'LISTGROUP'; } else { if (is_null($range)) { $command = 'LISTGROUP ' . $newsgroup; } else { $command = 'LISTGROUP ' . $newsgroup . ' ' . $range; } } $response = $this->_sendCommand($command); if (PEAR::isError($response)){ return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_GROUP_SELECTED: // 211, RFC2980: 'list of article numbers follow' $articles = $this->_getTextResponse(); if (PEAR::isError($articles)) { return $articles; } $response_arr = explode(' ', trim($this->_currentStatusResponse()), 4); // If server does not return group summary in status response, return null'ed array if (!is_numeric($response_arr[0]) || !is_numeric($response_arr[1]) || !is_numeric($response_arr[2]) || empty($response_arr[3])) { return array('group' => null, 'first' => null, 'last' => null, 'count' => null, 'articles' => $articles); } return array('group' => $response_arr[3], 'first' => $response_arr[1], 'last' => $response_arr[2], 'count' => $response_arr[0], 'articles' => $articles); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED: // 412, RFC2980: 'Not currently in newsgroup' return $this->throwError('Not currently in newsgroup', $response, $this->_currentStatusResponse()); break; case 502: // RFC2980: 'no permission' return $this->throwError('No permission', $response, $this->_currentStatusResponse()); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ cmdLast() /** * * * @return mixed (array) or (string) or (int) or (object) pear_error on failure * @access protected */ function cmdLast() { // $response = $this->_sendCommand('LAST'); if (PEAR::isError($response)) { return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_ARTICLE_SELECTED: // 223, RFC977: 'n a article retrieved - request text separately (n = article number, a = unique article id)' $response_arr = explode(' ', trim($this->_currentStatusResponse())); if ($this->_logger) { $this->_logger->info('Selected previous article: ' . $response_arr[0] .' - '. $response_arr[1]); } return array($response_arr[0], (string) $response_arr[1]); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED: // 412, RFC977: 'no newsgroup selected' return $this->throwError('No newsgroup has been selected', $response, $this->_currentStatusResponse()); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_ARTICLE_SELECTED: // 420, RFC977: 'no current article has been selected' return $this->throwError('No current article has been selected', $response, $this->_currentStatusResponse()); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_PREVIOUS_ARTICLE: // 422, RFC977: 'no previous article in this group' return $this->throwError('No previous article in this group', $response, $this->_currentStatusResponse()); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ cmdNext() /** * * * @return mixed (array) or (string) or (int) or (object) pear_error on failure * @access protected */ function cmdNext() { // $response = $this->_sendCommand('NEXT'); if (PEAR::isError($response)) { return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_ARTICLE_SELECTED: // 223, RFC977: 'n a article retrieved - request text separately (n = article number, a = unique article id)' $response_arr = explode(' ', trim($this->_currentStatusResponse())); if ($this->_logger) { $this->_logger->info('Selected previous article: ' . $response_arr[0] .' - '. $response_arr[1]); } return array($response_arr[0], (string) $response_arr[1]); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED: // 412, RFC977: 'no newsgroup selected' return $this->throwError('No newsgroup has been selected', $response, $this->_currentStatusResponse()); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_ARTICLE_SELECTED: // 420, RFC977: 'no current article has been selected' return $this->throwError('No current article has been selected', $response, $this->_currentStatusResponse()); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_NEXT_ARTICLE: // 421, RFC977: 'no next article in this group' return $this->throwError('No next article in this group', $response, $this->_currentStatusResponse()); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} /* Retrieval of articles and article sections */ // {{{ cmdArticle() /** * Get an article from the currently open connection. * * @param mixed $article Either a message-id or a message-number of the article to fetch. If null or '', then use current article. * * @return mixed (array) article on success or (object) pear_error on failure * @access protected */ function cmdArticle($article = null) { if (is_null($article)) { $command = 'ARTICLE'; } else { $command = 'ARTICLE ' . $article; } // tell the newsserver we want an article $response = $this->_sendCommand($command); if (PEAR::isError($response)) { return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_ARTICLE_FOLLOWS: // 220, RFC977: 'n article retrieved - head and body follow (n = article number, = message-id)' $data = $this->_getTextResponse(); if (PEAR::isError($data)) { return $data; } if ($this->_logger) { $this->_logger->info(($article == null ? 'Fetched current article' : 'Fetched article: '.$article)); } return $data; break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED: // 412, RFC977: 'no newsgroup has been selected' return $this->throwError('No newsgroup has been selected', $response, $this->_currentStatusResponse()); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_ARTICLE_SELECTED: // 420, RFC977: 'no current article has been selected' return $this->throwError('No current article has been selected', $response, $this->_currentStatusResponse()); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_NUMBER: // 423, RFC977: 'no such article number in this group' return $this->throwError('No such article number in this group', $response, $this->_currentStatusResponse()); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_ID: // 430, RFC977: 'no such article found' return $this->throwError('No such article found', $response, $this->_currentStatusResponse()); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ cmdHead() /** * Get the headers of an article from the currently open connection. * * @param mixed $article Either a message-id or a message-number of the article to fetch the headers from. If null or '', then use current article. * * @return mixed (array) headers on success or (object) pear_error on failure * @access protected */ function cmdHead($article = null) { if (is_null($article)) { $command = 'HEAD'; } else { $command = 'HEAD ' . $article; } // tell the newsserver we want the header of an article $response = $this->_sendCommand($command); if (PEAR::isError($response)) { return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_HEAD_FOLLOWS: // 221, RFC977: 'n article retrieved - head follows' $data = $this->_getTextResponse(); if (PEAR::isError($data)) { return $data; } if ($this->_logger) { $this->_logger->info(($article == null ? 'Fetched current article header' : 'Fetched article header for article: '.$article)); } return $data; break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED: // 412, RFC977: 'no newsgroup has been selected' return $this->throwError('No newsgroup has been selected', $response, $this->_currentStatusResponse()); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_ARTICLE_SELECTED: // 420, RFC977: 'no current article has been selected' return $this->throwError('No current article has been selected', $response, $this->_currentStatusResponse()); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_NUMBER: // 423, RFC977: 'no such article number in this group' return $this->throwError('No such article number in this group', $response, $this->_currentStatusResponse()); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_ID: // 430, RFC977: 'no such article found' return $this->throwError('No such article found', $response, $this->_currentStatusResponse()); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ cmdBody() /** * Get the body of an article from the currently open connection. * * @param mixed $article Either a message-id or a message-number of the article to fetch the body from. If null or '', then use current article. * * @return mixed (array) body on success or (object) pear_error on failure * @access protected */ function cmdBody($article = null) { if (is_null($article)) { $command = 'BODY'; } else { $command = 'BODY ' . $article; } // tell the newsserver we want the body of an article $response = $this->_sendCommand($command); if (PEAR::isError($response)) { return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_BODY_FOLLOWS: // 222, RFC977: 'n article retrieved - body follows' $data = $this->_getTextResponse(); if (PEAR::isError($data)) { return $data; } if ($this->_logger) { $this->_logger->info(($article == null ? 'Fetched current article body' : 'Fetched article body for article: '.$article)); } return $data; break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED: // 412, RFC977: 'no newsgroup has been selected' return $this->throwError('No newsgroup has been selected', $response, $this->_currentStatusResponse()); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_ARTICLE_SELECTED: // 420, RFC977: 'no current article has been selected' return $this->throwError('No current article has been selected', $response, $this->_currentStatusResponse()); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_NUMBER: // 423, RFC977: 'no such article number in this group' return $this->throwError('No such article number in this group', $response, $this->_currentStatusResponse()); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_ID: // 430, RFC977: 'no such article found' return $this->throwError('No such article found', $response, $this->_currentStatusResponse()); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ cmdStat /** * * * @param mixed $article * * @return mixed (array) or (string) or (int) or (object) pear_error on failure * @access protected */ function cmdStat($article = null) { if (is_null($article)) { $command = 'STAT'; } else { $command = 'STAT ' . $article; } // tell the newsserver we want an article $response = $this->_sendCommand($command); if (PEAR::isError($response)) { return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_ARTICLE_SELECTED: // 223, RFC977: 'n article retrieved - request text separately' (actually not documented, but copied from the ARTICLE command) $response_arr = explode(' ', trim($this->_currentStatusResponse())); if ($this->_logger) { $this->_logger->info('Selected article: ' . $response_arr[0].' - '.$response_arr[1]); } return array($response_arr[0], (string) $response_arr[1]); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED: // 412, RFC977: 'no newsgroup has been selected' (actually not documented, but copied from the ARTICLE command) return $this->throwError('No newsgroup has been selected', $response, $this->_currentStatusResponse()); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_NUMBER: // 423, RFC977: 'no such article number in this group' (actually not documented, but copied from the ARTICLE command) return $this->throwError('No such article number in this group', $response, $this->_currentStatusResponse()); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_ID: // 430, RFC977: 'no such article found' (actually not documented, but copied from the ARTICLE command) return $this->throwError('No such article found', $response, $this->_currentStatusResponse()); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} /* Article posting */ // {{{ cmdPost() /** * Post an article to a newsgroup. * * @return mixed (bool) true on success or (object) pear_error on failure * @access protected */ function cmdPost() { // tell the newsserver we want to post an article $response = $this->_sendCommand('POST'); if (PEAR::isError($response)) { return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_POSTING_SEND: // 340, RFC977: 'send article to be posted. End with .' return true; break; case NET_NNTP_PROTOCOL_RESPONSECODE_POSTING_PROHIBITED: // 440, RFC977: 'posting not allowed' return $this->throwError('Posting not allowed', $response, $this->_currentStatusResponse()); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ cmdPost2() /** * Post an article to a newsgroup. * * @param mixed $article (string/array) * * @return mixed (bool) true on success or (object) pear_error on failure * @access protected */ function cmdPost2($article) { /* should be presented in the format specified by RFC850 */ // $this->_sendArticle($article); // Retrive server's response. $response = $this->_getStatusResponse(); if (PEAR::isError($response)) { return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_POSTING_SUCCESS: // 240, RFC977: 'article posted ok' return true; break; case NET_NNTP_PROTOCOL_RESPONSECODE_POSTING_FAILURE: // 441, RFC977: 'posting failed' return $this->throwError('Posting failed', $response, $this->_currentStatusResponse()); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ cmdIhave() /** * * * @param string $id * * @return mixed (bool) true on success or (object) pear_error on failure * @access protected */ function cmdIhave($id) { // tell the newsserver we want to post an article $response = $this->_sendCommand('IHAVE ' . $id); if (PEAR::isError($response)) { return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_TRANSFER_SEND: // 335 return true; break; case NET_NNTP_PROTOCOL_RESPONSECODE_TRANSFER_UNWANTED: // 435 return $this->throwError('Article not wanted', $response, $this->_currentStatusResponse()); break; case NET_NNTP_PROTOCOL_RESPONSECODE_TRANSFER_FAILURE: // 436 return $this->throwError('Transfer not possible; try again later', $response, $this->_currentStatusResponse()); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ cmdIhave2() /** * * * @param mixed $article (string/array) * * @return mixed (bool) true on success or (object) pear_error on failure * @access protected */ function cmdIhave2($article) { /* should be presented in the format specified by RFC850 */ // $this->_sendArticle($article); // Retrive server's response. $response = $this->_getStatusResponse(); if (PEAR::isError($response)) { return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_TRANSFER_SUCCESS: // 235 return true; break; case NET_NNTP_PROTOCOL_RESPONSECODE_TRANSFER_FAILURE: // 436 return $this->throwError('Transfer not possible; try again later', $response, $this->_currentStatusResponse()); break; case NET_NNTP_PROTOCOL_RESPONSECODE_TRANSFER_REJECTED: // 437 return $this->throwError('Transfer rejected; do not retry', $response, $this->_currentStatusResponse()); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} /* Information commands */ // {{{ cmdDate() /** * Get the date from the newsserver format of returned date * * @return mixed (string) 'YYYYMMDDhhmmss' / (int) timestamp on success or (object) pear_error on failure * @access protected */ function cmdDate() { $response = $this->_sendCommand('DATE'); if (PEAR::isError($response)){ return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_SERVER_DATE: // 111, RFC2980: 'YYYYMMDDhhmmss' return $this->_currentStatusResponse(); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ cmdHelp() /** * Returns the server's help text * * @return mixed (array) help text on success or (object) pear_error on failure * @access protected */ function cmdHelp() { // tell the newsserver we want an article $response = $this->_sendCommand('HELP'); if (PEAR::isError($response)) { return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_HELP_FOLLOWS: // 100 $data = $this->_getTextResponse(); if (PEAR::isError($data)) { return $data; } return $data; break; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ cmdNewgroups() /** * Fetches a list of all newsgroups created since a specified date. * * @param int $time Last time you checked for groups (timestamp). * @param optional string $distributions (deprecaded in rfc draft) * * @return mixed (array) nested array with informations about existing newsgroups on success or (object) pear_error on failure * @access protected */ function cmdNewgroups($time, $distributions = null) { $date = gmdate('ymd His', $time); if (is_null($distributions)) { $command = 'NEWGROUPS ' . $date . ' GMT'; } else { $command = 'NEWGROUPS ' . $date . ' GMT <' . $distributions . '>'; } $response = $this->_sendCommand($command); if (PEAR::isError($response)){ return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_NEW_GROUPS_FOLLOW: // 231, REF977: 'list of new newsgroups follows' $data = $this->_getTextResponse(); if (PEAR::isError($data)) { return $data; } $groups = array(); foreach($data as $line) { $arr = explode(' ', trim($line)); $group = array('group' => $arr[0], 'last' => $arr[1], 'first' => $arr[2], 'posting' => $arr[3]); $groups[$group['group']] = $group; } return $groups; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ cmdNewnews() /** * * * @param timestamp $time * @param mixed $newsgroups (string or array of strings) * @param mixed $distribution (string or array of strings) * * @return mixed * @access protected */ function cmdNewnews($time, $newsgroups, $distribution = null) { $date = gmdate('ymd His', $time); if (is_array($newsgroups)) { $newsgroups = implode(',', $newsgroups); } if (is_null($distribution)) { $command = 'NEWNEWS ' . $newsgroups . ' ' . $date . ' GMT'; } else { if (is_array($distribution)) { $distribution = implode(',', $distribution); } $command = 'NEWNEWS ' . $newsgroups . ' ' . $date . ' GMT <' . $distribution . '>'; } // TODO: the lenght of the request string may not exceed 510 chars $response = $this->_sendCommand($command); if (PEAR::isError($response)){ return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_NEW_ARTICLES_FOLLOW: // 230, RFC977: 'list of new articles by message-id follows' $messages = array(); foreach($this->_getTextResponse() as $line) { $messages[] = $line; } return $messages; break; default: return $this->_handleUnexpectedResponse($response); } } // }}} /* The LIST commands */ // {{{ cmdList() /** * Fetches a list of all avaible newsgroups * * @return mixed (array) nested array with informations about existing newsgroups on success or (object) pear_error on failure * @access protected */ function cmdList() { $response = $this->_sendCommand('LIST'); if (PEAR::isError($response)){ return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_GROUPS_FOLLOW: // 215, RFC977: 'list of newsgroups follows' $data = $this->_getTextResponse(); if (PEAR::isError($data)) { return $data; } $groups = array(); foreach($data as $line) { $arr = explode(' ', trim($line)); $group = array('group' => $arr[0], 'last' => $arr[1], 'first' => $arr[2], 'posting' => $arr[3]); $groups[$group['group']] = $group; } return $groups; break; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ cmdListActive() /** * Fetches a list of all avaible newsgroups * * @param string $wildmat * * @return mixed (array) nested array with informations about existing newsgroups on success or (object) pear_error on failure * @access protected */ function cmdListActive($wildmat = null) { if (is_null($wildmat)) { $command = 'LIST ACTIVE'; } else { $command = 'LIST ACTIVE ' . $wildmat; } $response = $this->_sendCommand($command); if (PEAR::isError($response)){ return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_GROUPS_FOLLOW: // 215, RFC977: 'list of newsgroups follows' $data = $this->_getTextResponse(); if (PEAR::isError($data)) { return $data; } $groups = array(); foreach($data as $line) { $arr = explode(' ', trim($line)); $group = array('group' => $arr[0], 'last' => $arr[1], 'first' => $arr[2], 'posting' => $arr[3]); $groups[$group['group']] = $group; } if ($this->_logger) { $this->_logger->info('Fetched list of available groups'); } return $groups; break; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ cmdListNewsgroups() /** * Fetches a list of (all) avaible newsgroup descriptions. * * @param string $wildmat Wildmat of the groups, that is to be listed, defaults to null; * * @return mixed (array) nested array with description of existing newsgroups on success or (object) pear_error on failure * @access protected */ function cmdListNewsgroups($wildmat = null) { if (is_null($wildmat)) { $command = 'LIST NEWSGROUPS'; } else { $command = 'LIST NEWSGROUPS ' . $wildmat; } $response = $this->_sendCommand($command); if (PEAR::isError($response)){ return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_GROUPS_FOLLOW: // 215, RFC2980: 'information follows' $data = $this->_getTextResponse(); if (PEAR::isError($data)) { return $data; } $groups = array(); foreach($data as $line) { if (preg_match("/^(\S+)\s+(.*)$/", ltrim($line), $matches)) { $groups[$matches[1]] = (string) $matches[2]; } else { if ($this->_logger) { $this->_logger->warning("Recieved non-standard line: '$line'"); } } } if ($this->_logger) { $this->_logger->info('Fetched group descriptions'); } return $groups; break; case 503: // RFC2980: 'program error, function not performed' return $this->throwError('Internal server error, function not performed', $response, $this->_currentStatusResponse()); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} /* Article field access commands */ // {{{ cmdOver() /** * Fetch message header from message number $first until $last * * The format of the returned array is: * $messages[][header_name] * * @param optional string $range articles to fetch * * @return mixed (array) nested array of message and there headers on success or (object) pear_error on failure * @access protected */ function cmdOver($range = null) { if (is_null($range)) { $command = 'OVER'; } else { $command = 'OVER ' . $range; } $response = $this->_sendCommand($command); if (PEAR::isError($response)){ return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_OVERVIEW_FOLLOWS: // 224, RFC2980: 'Overview information follows' $data = $this->_getTextResponse(); if (PEAR::isError($data)) { return $data; } foreach ($data as $key => $value) { $data[$key] = explode("\t", trim($value)); } if ($this->_logger) { $this->_logger->info('Fetched overview ' . ($range == null ? 'for current article' : 'for range: '.$range)); } return $data; break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED: // 412, RFC2980: 'No news group current selected' return $this->throwError('No news group current selected', $response, $this->_currentStatusResponse()); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_ARTICLE_SELECTED: // 420, RFC2980: 'No article(s) selected' return $this->throwError('No article(s) selected', $response, $this->_currentStatusResponse()); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_NUMBER: // 423:, Draft27: 'No articles in that range' return $this->throwError('No articles in that range', $response, $this->_currentStatusResponse()); break; case 502: // RFC2980: 'no permission' return $this->throwError('No permission', $response, $this->_currentStatusResponse()); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ cmdXOver() /** * Fetch message header from message number $first until $last * * The format of the returned array is: * $messages[message_id][header_name] * * @param optional string $range articles to fetch * * @return mixed (array) nested array of message and there headers on success or (object) pear_error on failure * @access protected */ function cmdXOver($range = null) { // deprecated API (the code _is_ still in alpha state) if (func_num_args() > 1 ) { die('The second parameter in cmdXOver() has been deprecated! Use x-y instead...'); } if (is_null($range)) { $command = 'XOVER'; } else { $command = 'XOVER ' . $range; } $response = $this->_sendCommand($command); if (PEAR::isError($response)){ return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_OVERVIEW_FOLLOWS: // 224, RFC2980: 'Overview information follows' $data = $this->_getTextResponse(); if (PEAR::isError($data)) { return $data; } foreach ($data as $key => $value) { $data[$key] = explode("\t", trim($value)); } if ($this->_logger) { $this->_logger->info('Fetched overview ' . ($range == null ? 'for current article' : 'for range: '.$range)); } return $data; break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED: // 412, RFC2980: 'No news group current selected' return $this->throwError('No news group current selected', $response, $this->_currentStatusResponse()); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_ARTICLE_SELECTED: // 420, RFC2980: 'No article(s) selected' return $this->throwError('No article(s) selected', $response, $this->_currentStatusResponse()); break; case 502: // RFC2980: 'no permission' return $this->throwError('No permission', $response, $this->_currentStatusResponse()); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ cmdListOverviewFmt() /** * Returns a list of avaible headers which are send from newsserver to client for every news message * * @return mixed (array) of header names on success or (object) pear_error on failure * @access protected */ function cmdListOverviewFmt() { $response = $this->_sendCommand('LIST OVERVIEW.FMT'); if (PEAR::isError($response)){ return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_GROUPS_FOLLOW: // 215, RFC2980: 'information follows' $data = $this->_getTextResponse(); if (PEAR::isError($data)) { return $data; } $format = array(); foreach ($data as $line) { // Check if postfixed by ':full' (case-insensitive) if (0 == strcasecmp(substr($line, -5, 5), ':full')) { // ':full' is _not_ included in tag, but value set to true $format[substr($line, 0, -5)] = true; } else { // ':' is _not_ included in tag; value set to false $format[substr($line, 0, -1)] = false; } } if ($this->_logger) { $this->_logger->info('Fetched overview format'); } return $format; break; case 503: // RFC2980: 'program error, function not performed' return $this->throwError('Internal server error, function not performed', $response, $this->_currentStatusResponse()); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ cmdXHdr() /** * * * The format of the returned array is: * $messages[message_id] * * @param optional string $field * @param optional string $range articles to fetch * * @return mixed (array) nested array of message and there headers on success or (object) pear_error on failure * @access protected */ function cmdXHdr($field, $range = null) { if (is_null($range)) { $command = 'XHDR ' . $field; } else { $command = 'XHDR ' . $field . ' ' . $range; } $response = $this->_sendCommand($command); if (PEAR::isError($response)){ return $response; } switch ($response) { case 221: // 221, RFC2980: 'Header follows' $data = $this->_getTextResponse(); if (PEAR::isError($data)) { return $data; } $return = array(); foreach($data as $line) { $line = explode(' ', trim($line), 2); $return[$line[0]] = $line[1]; } return $return; break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED: // 412, RFC2980: 'No news group current selected' return $this->throwError('No news group current selected', $response, $this->_currentStatusResponse()); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_ARTICLE_SELECTED: // 420, RFC2980: 'No current article selected' return $this->throwError('No current article selected', $response, $this->_currentStatusResponse()); break; case 430: // 430, RFC2980: 'No such article' return $this->throwError('No such article', $response, $this->_currentStatusResponse()); break; case 502: // RFC2980: 'no permission' return $this->throwError('No permission', $response, $this->_currentStatusResponse()); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} /** * Fetches a list of (all) avaible newsgroup descriptions. * Depresated as of RFC2980. * * @param string $wildmat Wildmat of the groups, that is to be listed, defaults to '*'; * * @return mixed (array) nested array with description of existing newsgroups on success or (object) pear_error on failure * @access protected */ function cmdXGTitle($wildmat = '*') { $response = $this->_sendCommand('XGTITLE '.$wildmat); if (PEAR::isError($response)){ return $response; } switch ($response) { case 282: // RFC2980: 'list of groups and descriptions follows' $data = $this->_getTextResponse(); if (PEAR::isError($data)) { return $data; } $groups = array(); foreach($data as $line) { preg_match("/^(.*?)\s(.*?$)/", trim($line), $matches); $groups[$matches[1]] = (string) $matches[2]; } return $groups; break; case 481: // RFC2980: 'Groups and descriptions unavailable' return $this->throwError('Groups and descriptions unavailable', $response, $this->_currentStatusResponse()); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ cmdXROver() /** * Fetch message references from message number $first to $last * * @param optional string $range articles to fetch * * @return mixed (array) assoc. array of message references on success or (object) pear_error on failure * @access protected */ function cmdXROver($range = null) { // Warn about deprecated API (the code _is_ still in alpha state) if (func_num_args() > 1 ) { die('The second parameter in cmdXROver() has been deprecated! Use x-y instead...'); } if (is_null($range)) { $command = 'XROVER'; } else { $command = 'XROVER ' . $range; } $response = $this->_sendCommand($command); if (PEAR::isError($response)){ return $response; } switch ($response) { case NET_NNTP_PROTOCOL_RESPONSECODE_OVERVIEW_FOLLOWS: // 224, RFC2980: 'Overview information follows' $data = $this->_getTextResponse(); if (PEAR::isError($data)) { return $data; } $return = array(); foreach($data as $line) { $line = explode(' ', trim($line), 2); $return[$line[0]] = $line[1]; } return $return; break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED: // 412, RFC2980: 'No news group current selected' return $this->throwError('No news group current selected', $response, $this->_currentStatusResponse()); break; case NET_NNTP_PROTOCOL_RESPONSECODE_NO_ARTICLE_SELECTED: // 420, RFC2980: 'No article(s) selected' return $this->throwError('No article(s) selected', $response, $this->_currentStatusResponse()); break; case 502: // RFC2980: 'no permission' return $this->throwError('No permission', $response, $this->_currentStatusResponse()); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ cmdXPat() /** * * * @param string $field * @param string $range * @param mixed $wildmat * * @return mixed (array) nested array of message and there headers on success or (object) pear_error on failure * @access protected */ function cmdXPat($field, $range, $wildmat) { if (is_array($wildmat)) { $wildmat = implode(' ', $wildmat); } $response = $this->_sendCommand('XPAT ' . $field . ' ' . $range . ' ' . $wildmat); if (PEAR::isError($response)){ return $response; } switch ($response) { case 221: // 221, RFC2980: 'Header follows' $data = $this->_getTextResponse(); if (PEAR::isError($data)) { return $data; } $return = array(); foreach($data as $line) { $line = explode(' ', trim($line), 2); $return[$line[0]] = $line[1]; } return $return; break; case 430: // 430, RFC2980: 'No such article' return $this->throwError('No current article selected', $response, $this->_currentStatusResponse()); break; case 502: // RFC2980: 'no permission' return $this->throwError('No permission', $response, $this->_currentStatusResponse()); break; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ cmdAuthinfo() /** * Authenticate using 'original' method * * @param string $user The username to authenticate as. * @param string $pass The password to authenticate with. * * @return mixed (bool) true on success or (object) pear_error on failure * @access protected */ function cmdAuthinfo($user, $pass) { // Send the username $response = $this->_sendCommand('AUTHINFO user '.$user); if (PEAR::isError($response)) { return $response; } // Send the password, if the server asks if (($response == 381) && ($pass !== null)) { // Send the password $response = $this->_sendCommand('AUTHINFO pass '.$pass); if (PEAR::isError($response)) { return $response; } } switch ($response) { case 281: // RFC2980: 'Authentication accepted' if ($this->_logger) { $this->_logger->info("Authenticated (as user '$user')"); } // TODO: Set some variable before return return true; break; case 381: // RFC2980: 'More authentication information required' return $this->throwError('Authentication uncompleted', $response, $this->_currentStatusResponse()); break; case 482: // RFC2980: 'Authentication rejected' return $this->throwError('Authentication rejected', $response, $this->_currentStatusResponse()); break; case 502: // RFC2980: 'No permission' return $this->throwError('Authentication rejected', $response, $this->_currentStatusResponse()); break; // case 500: // case 501: // return $this->throwError('Authentication failed', $response, $this->_currentStatusResponse()); // break; default: return $this->_handleUnexpectedResponse($response); } } // }}} // {{{ cmdAuthinfoSimple() /** * Authenticate using 'simple' method * * @param string $user The username to authenticate as. * @param string $pass The password to authenticate with. * * @return mixed (bool) true on success or (object) pear_error on failure * @access protected */ function cmdAuthinfoSimple($user, $pass) { return $this->throwError("The auth mode: 'simple' is has not been implemented yet", null); } // }}} // {{{ cmdAuthinfoGeneric() /** * Authenticate using 'generic' method * * @param string $user The username to authenticate as. * @param string $pass The password to authenticate with. * * @return mixed (bool) true on success or (object) pear_error on failure * @access protected */ function cmdAuthinfoGeneric($user, $pass) { return $this->throwError("The auth mode: 'generic' is has not been implemented yet", null); } // }}} // {{{ _isConnected() /** * Test whether we are connected or not. * * @return bool true or false * @access protected */ function _isConnected() { return (is_resource($this->_socket) && (!feof($this->_socket))); } // }}} } // }}} /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * c-hanging-comment-ender-p: nil * End: */ ?> php-net-nntp-1.5.0/Net_NNTP-1.5.0/NNTP/Protocol/Responsecode.php000066400000000000000000000300351215221406100236060ustar00rootroot00000000000000 * +-----------------------------------------------------------------------+ * | | * | W3CŪ SOFTWARE NOTICE AND LICENSE | * | http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 | * | | * | This work (and included software, documentation such as READMEs, | * | or other related items) is being provided by the copyright holders | * | under the following license. By obtaining, using and/or copying | * | this work, you (the licensee) agree that you have read, understood, | * | and will comply with the following terms and conditions. | * | | * | Permission to copy, modify, and distribute this software and its | * | documentation, with or without modification, for any purpose and | * | without fee or royalty is hereby granted, provided that you include | * | the following on ALL copies of the software and documentation or | * | portions thereof, including modifications: | * | | * | 1. The full text of this NOTICE in a location viewable to users | * | of the redistributed or derivative work. | * | | * | 2. Any pre-existing intellectual property disclaimers, notices, | * | or terms and conditions. If none exist, the W3C Software Short | * | Notice should be included (hypertext is preferred, text is | * | permitted) within the body of any redistributed or derivative | * | code. | * | | * | 3. Notice of any changes or modifications to the files, including | * | the date changes were made. (We recommend you provide URIs to | * | the location from which the code is derived.) | * | | * | THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT | * | HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, | * | INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR | * | FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE | * | OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, | * | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. | * | | * | COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, | * | SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE | * | SOFTWARE OR DOCUMENTATION. | * | | * | The name and trademarks of copyright holders may NOT be used in | * | advertising or publicity pertaining to the software without | * | specific, written prior permission. Title to copyright in this | * | software and any associated documentation will at all times | * | remain with copyright holders. | * | | * +-----------------------------------------------------------------------+ * * * @category Net * @package Net_NNTP * @author Heino H. Gehlsen * @copyright 2002-2011 Heino H. Gehlsen . All Rights Reserved. * @license http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 W3CŪ SOFTWARE NOTICE AND LICENSE * @version SVN: $Id: Responsecode.php 306619 2010-12-24 12:16:07Z heino $ * @link http://pear.php.net/package/Net_NNTP * @see * @since File available since release 1.3.0 */ // {{{ Constants: Connection /** * 'Server ready - posting allowed' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_READY_POSTING_ALLOWED', 200); /** * 'Server ready - no posting allowed' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_READY_POSTING_PROHIBITED', 201); /** * 'Closing connection - goodbye!' (RFC977) * * @access public * @since ? */ //define('NET_NNTP_PROTOCOL_RESPONSECODE_DISCONNECTING_REQUESTED', 205); ///// goodbye /** * 'Service discontinued' (RFC977) * * @access public * @since ? */ //define('NET_NNTP_PROTOCOL_RESPONSECODE_DISCONNECTING_FORCED', 400); ///// unavailable / discontinued /** * 'Slave status noted' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_SLAVE_RECOGNIZED', 202); // }}} // {{{ Constants: Common errors /** * 'Command not recognized' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_UNKNOWN_COMMAND', 500); /** * 'Command syntax error' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_SYNTAX_ERROR', 501); /** * 'Access restriction or permission denied' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_NOT_PERMITTED', 502); /** * 'Program fault - command not performed' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_NOT_SUPPORTED', 503); // }}} // {{{ Constants: Group selection /** * 'Group selected' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_GROUP_SELECTED', 211); /** * 'No such news group' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_GROUP', 411); // }}} // {{{ Constants: Article retrieval /** * 'Article retrieved - head and body follow' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_ARTICLE_FOLLOWS', 220); /** * 'Article retrieved - head follows' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_HEAD_FOLLOWS', 221); /** * 'Article retrieved - body follows' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_BODY_FOLLOWS', 222); /** * 'Article retrieved - request text separately' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_ARTICLE_SELECTED', 223); /** * 'No newsgroup has been selected' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_NO_GROUP_SELECTED', 412); /** * 'No current article has been selected' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_NO_ARTICLE_SELECTED', 420); /** * 'No next article in this group' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_NO_NEXT_ARTICLE', 421); /** * 'No previous article in this group' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_NO_PREVIOUS_ARTICLE', 422); /** * 'No such article number in this group' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_NUMBER', 423); /** * 'No such article found' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_NO_SUCH_ARTICLE_ID', 430); // }}} // {{{ Constants: Transferring /** * 'Send article to be transferred' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_TRANSFER_SEND', 335); /** * 'Article transferred ok' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_TRANSFER_SUCCESS', 235); /** * 'Article not wanted - do not send it' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_TRANSFER_UNWANTED', 435); /** * 'Transfer failed - try again later' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_TRANSFER_FAILURE', 436); /** * 'Article rejected - do not try again' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_TRANSFER_REJECTED', 437); // }}} // {{{ Constants: Posting /** * 'Send article to be posted' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_POSTING_SEND', 340); /** * 'Article posted ok' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_POSTING_SUCCESS', 240); /** * 'Posting not allowed' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_POSTING_PROHIBITED', 440); /** * 'Posting failed' (RFC977) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_POSTING_FAILURE', 441); // }}} // {{{ Constants: Authorization /** * 'Authorization required for this command' (RFC2980) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_AUTHORIZATION_REQUIRED', 450); /** * 'Continue with authorization sequence' (RFC2980) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_AUTHORIZATION_CONTINUE', 350); /** * 'Authorization accepted' (RFC2980) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_AUTHORIZATION_ACCEPTED', 250); /** * 'Authorization rejected' (RFC2980) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_AUTHORIZATION_REJECTED', 452); // }}} // {{{ Constants: Authentication /** * 'Authentication required' (RFC2980) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_AUTHENTICATION_REQUIRED', 480); /** * 'More authentication information required' (RFC2980) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_AUTHENTICATION_CONTINUE', 381); /** * 'Authentication accepted' (RFC2980) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_AUTHENTICATION_ACCEPTED', 281); /** * 'Authentication rejected' (RFC2980) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_AUTHENTICATION_REJECTED', 482); // }}} // {{{ Constants: Misc /** * 'Help text follows' (Draft) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_HELP_FOLLOWS', 100); /** * 'Capabilities list follows' (Draft) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_CAPABILITIES_FOLLOW', 101); /** * 'Server date and time' (Draft) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_SERVER_DATE', 111); /** * 'Information follows' (Draft) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_GROUPS_FOLLOW', 215); /** * 'Overview information follows' (Draft) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_OVERVIEW_FOLLOWS', 224); /** * 'Headers follow' (Draft) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_HEADERS_FOLLOW', 225); /** * 'List of new articles follows' (Draft) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_NEW_ARTICLES_FOLLOW', 230); /** * 'List of new newsgroups follows' (Draft) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_NEW_GROUPS_FOLLOW', 231); /** * 'The server is in the wrong mode; the indicated capability should be used to change the mode' (Draft) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_WRONG_MODE', 401); /** * 'Internal fault or problem preventing action being taken' (Draft) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_INTERNAL_FAULT', 403); /** * 'Command unavailable until suitable privacy has been arranged' (Draft) * * (the client must negotiate appropriate privacy protection on the connection. * This will involve the use of a privacy extension such as [NNTP-TLS].) * * @access public * @since ? */ //define('NET_NNTP_PROTOCOL_RESPONSECODE_ENCRYPTION_REQUIRED', 483); /** * 'Error in base64-encoding [RFC3548] of an argument' (Draft) * * @access public */ define('NET_NNTP_PROTOCOL_RESPONSECODE_BASE64_ENCODING_ERROR', 504); // }}} /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * c-hanging-comment-ender-p: nil * End: */ ?> php-net-nntp-1.5.0/Net_NNTP-1.5.0/docs/000077500000000000000000000000001215221406100170135ustar00rootroot00000000000000php-net-nntp-1.5.0/Net_NNTP-1.5.0/docs/examples/000077500000000000000000000000001215221406100206315ustar00rootroot00000000000000php-net-nntp-1.5.0/Net_NNTP-1.5.0/docs/examples/demo/000077500000000000000000000000001215221406100215555ustar00rootroot00000000000000php-net-nntp-1.5.0/Net_NNTP-1.5.0/docs/examples/demo/article.php000066400000000000000000000276261215221406100237260ustar00rootroot00000000000000 * +-----------------------------------------------------------------------+ * | | * | W3CŪ SOFTWARE NOTICE AND LICENSE | * | http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 | * | | * | This work (and included software, documentation such as READMEs, | * | or other related items) is being provided by the copyright holders | * | under the following license. By obtaining, using and/or copying | * | this work, you (the licensee) agree that you have read, understood, | * | and will comply with the following terms and conditions. | * | | * | Permission to copy, modify, and distribute this software and its | * | documentation, with or without modification, for any purpose and | * | without fee or royalty is hereby granted, provided that you include | * | the following on ALL copies of the software and documentation or | * | portions thereof, including modifications: | * | | * | 1. The full text of this NOTICE in a location viewable to users | * | of the redistributed or derivative work. | * | | * | 2. Any pre-existing intellectual property disclaimers, notices, | * | or terms and conditions. If none exist, the W3C Software Short | * | Notice should be included (hypertext is preferred, text is | * | permitted) within the body of any redistributed or derivative | * | code. | * | | * | 3. Notice of any changes or modifications to the files, including | * | the date changes were made. (We recommend you provide URIs to | * | the location from which the code is derived.) | * | | * | THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT | * | HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, | * | INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR | * | FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE | * | OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, | * | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. | * | | * | COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, | * | SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE | * | SOFTWARE OR DOCUMENTATION. | * | | * | The name and trademarks of copyright holders may NOT be used in | * | advertising or publicity pertaining to the software without | * | specific, written prior permission. Title to copyright in this | * | software and any associated documentation will at all times | * | remain with copyright holders. | * | | * +-----------------------------------------------------------------------+ * * * @category Net * @package Net_NNTP * @author Heino H. Gehlsen * @copyright 2002-2011 Heino H. Gehlsen . All Rights Reserved. * @license http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 W3CŪ SOFTWARE NOTICE AND LICENSE * @version SVN: $Id: article.php 306619 2010-12-24 12:16:07Z heino $ * @link http://pear.php.net/package/Net_NNTP * @see * @since File available since release 1.3.0 */ /** * */ require_once 'config.inc.php'; /** * */ require_once 'common.inc.php'; /* Validate input */ /* // Must have either $messageNum or $messageID if (is_null($messageNum) and is_null($messageID)) { error('Error: Nither message number nor message-id provided!'); } // Only $messageNum OR $messageID if (!is_null($messageNum) and !is_null($messageId)) { error('Error: Both message-id _AND_ message number provided!'); } // $messageNum requires $group if (is_null($messageNum) and !is_null($group)) { error('Error: Message number requires group!'); } */ // $messageID = $group === null ? $article : null; #$article = $group !== null ? $article : null; /* Prepare breadcrumbs */ $breadcrumbs = array(); $breadcrumbs['Frontpage'] = './index.php?' . query(); $breadcrumbs['groups @ ' . ($host == null ? 'localhost' : $host)] = './groups.php?' . query(); if ($messageID !== null) { $breadcrumbs['Article: '.htmlentities($messageID)] = null; } else { $breadcrumbs['group: '.$group] = './group.php?' . query("group=$group&from=$from&next=$next"); $breadcrumbs['Article: #'.$article] = null; } // Connect $posting = $nntp->connect($host, $encryption, $port); if (PEAR::isError($posting)) { error('Unable to connect to NNTP server: ' . $posting->getMessage()); } // Start TLS encryption if ($starttls) { $R = $nntp->cmdStartTLS(); if (PEAR::isError($R)) { error('Unable to connect to NNTP server: ' . $R->getMessage()); } } // Authenticate if (!is_null($user) && !is_null($pass)) { $authenticated = $nntp->authenticate($user, $pass); if (PEAR::isError($authenticated)) { error('Unable to authenticate: ' . $authenticated->getMessage()); } } // If asked for a article in a group, select group then article if ($messageID === null) { // Select group $summary = $nntp->selectGroup($group); if (PEAR::isError($summary)) { error($summary->getMessage()); } // Select article $article = $nntp->selectArticle($article); if (PEAR::isError($article)) { error($article->getMessage()); } if ($article === false) { error('The article is not avalible on the server!'); } // Fetch overview $overview = $nntp->getOverview(); if (PEAR::isError($overview)) { $logger->warning('Error fetching overview (Server response: ' . $overview->getMessage() . ')'); // $overview = false; } // Fetch 'Newsgroups' header field $groups = $nntp->getHeaderField('Newsgroups'); if (PEAR::isError($groups)) { $logger->warning('Error fetching \'Newsgroups\' header field (Server response: ' . $groups->getMessage() . ')'); // $groups = false; } } // Fetch header $header = $nntp->getHeader($messageID); if (PEAR::isError($header)) { error('Error fetching header (Server response: ', $header->getMessage(), ')'); } if ($header === false) { error('The article is not avalible on the server!'); } // Fetch body $body = $nntp->getBody($messageID); if (PEAR::isError($body)) { error('Error fetching body (Server response: ', $body->getMessage(), ')'); } // Close connection $nntp->disconnect(); /* ... */ /** * */ function x($header, $fieldname, $index = 0) { // $fieldname = strtolower($fieldname); // for ($i = 0, $j = 0 ; $i < count($header) ; $i++) { // $line = $header[$i]; // @list($tag, $value) = explode(": ", $line, 2); if (strtolower($tag) != $fieldname) { continue; } // Skip if $index not reached if ($j++ < $index) { continue; } // Append folded lines... while (($next = $header[++$i]) && ($next[0] == ' ' || $next[0] == "\t")) { $value .= ' ' . ltrim($next, " \t"); } // Set $group return $value; } } // if (!empty($overview)) { $subject = $overview['Subject']; $from = $overview['From']; $date = $overview['Date']; $references = $overview['References']; } else { $subject = x($header, 'Subject'); $from = x($header, 'From'); $date = x($header, 'Date'); $references = x($header, 'References'); if (empty($references)) { $references = x($header, 'In-reply-to'); } } // if (empty($groups)) { $logger->info('Received an empty \'Newsgroups\' header field - parsing header as backup...'); $groups = x($header, 'Newsgroups'); } // $references = empty($references) ? null : preg_split("/[ \t]/", $references); /** * */ function outputHead() { // extract($GLOBALS); echo '' . "\r\n"; // Subject echo ' ' . "\r\n"; echo ' ' . "\r\n"; echo ' ', "\r\n"; echo ' ', "\r\n"; // From echo ' ', "\r\n"; echo ' ' . "\r\n"; echo ' ', "\r\n"; // Date echo ' ' . "\r\n"; echo ' ', "\r\n"; echo ' ', "\r\n"; echo ' ', "\r\n"; // References echo ' ' . "\r\n"; echo ' ', "\r\n"; // Groups echo ' ' . "\r\n"; echo ' ', "\r\n"; echo ' ', "\r\n"; // echo '
Subject:' . htmlspecialchars($subject) . '
From:' . htmlspecialchars($from) . 'Date:' . htmlspecialchars($date) . '
References:'; switch (true) { case is_array($references): foreach ($references as $reference) { echo ' #', ++$i, '', "\r\n"; } break; case is_string($references) && !empty($references): echo ' #', ++$i, '', "\r\n"; break; } echo ' Groups:', "\r\n"; foreach (explode(',', $groups) as $group) { echo '', $group, ' '; } echo '
', "\r\n"; } /** * */ function outputHeader() { // extract($GLOBALS); echo '
', "\r\n"; echo '
', "\r\n";
    echo preg_replace("/\r\n(\t| )+/", ' ', implode("\r\n", $header));
    echo ' 
', "\r\n"; echo '
', "\r\n"; } /** * */ function outputBody() { // extract($GLOBALS); echo '
', "\r\n"; echo '
', "\r\n";
    foreach ($body as $line) {

        /* Code from news.php.net begins here */ 
    
        // this is some amazingly simplistic code to color quotes/signatures
        // differently, and turn links into real links. it actually appears
        // to work fairly well, but could easily be made more sophistimicated.
        $line = htmlentities($line, ENT_NOQUOTES, 'utf-8');
        $line = preg_replace("/((mailto|http|ftp|nntp|news):.+?)(>|\\s|\\)|\\.\\s|$)/", "\\1\\3", $line);
        if (!$insig && $line == "-- \r\n") {
        	echo '';
        	$insig = 1;
        }
        if ($insig && $line == "\r\n") {
        	echo '';
        	$insig = 0;
        }
        if (!$insig && substr($line, 0, 4) == '>') {
        	echo '', $line, '';
        } else {
        	echo $line;
        }
        /* Code from news.php.net ends here */ 

        echo "\r\n";
    }
    echo ' 
', "\r\n"; echo '
', "\r\n"; } /**********/ /* Output */ /**********/ /** * Output header */ include 'header.inc.php'; $logger->dump(); outputHead(); outputBody(); /** * Output footer */ include 'footer.inc.php'; ?> php-net-nntp-1.5.0/Net_NNTP-1.5.0/docs/examples/demo/common.inc.php000066400000000000000000000302361215221406100243320ustar00rootroot00000000000000 * +-----------------------------------------------------------------------+ * | | * | W3CŪ SOFTWARE NOTICE AND LICENSE | * | http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 | * | | * | This work (and included software, documentation such as READMEs, | * | or other related items) is being provided by the copyright holders | * | under the following license. By obtaining, using and/or copying | * | this work, you (the licensee) agree that you have read, understood, | * | and will comply with the following terms and conditions. | * | | * | Permission to copy, modify, and distribute this software and its | * | documentation, with or without modification, for any purpose and | * | without fee or royalty is hereby granted, provided that you include | * | the following on ALL copies of the software and documentation or | * | portions thereof, including modifications: | * | | * | 1. The full text of this NOTICE in a location viewable to users | * | of the redistributed or derivative work. | * | | * | 2. Any pre-existing intellectual property disclaimers, notices, | * | or terms and conditions. If none exist, the W3C Software Short | * | Notice should be included (hypertext is preferred, text is | * | permitted) within the body of any redistributed or derivative | * | code. | * | | * | 3. Notice of any changes or modifications to the files, including | * | the date changes were made. (We recommend you provide URIs to | * | the location from which the code is derived.) | * | | * | THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT | * | HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, | * | INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR | * | FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE | * | OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, | * | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. | * | | * | COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, | * | SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE | * | SOFTWARE OR DOCUMENTATION. | * | | * | The name and trademarks of copyright holders may NOT be used in | * | advertising or publicity pertaining to the software without | * | specific, written prior permission. Title to copyright in this | * | software and any associated documentation will at all times | * | remain with copyright holders. | * | | * +-----------------------------------------------------------------------+ * * * @category Net * @package Net_NNTP * @author Heino H. Gehlsen * @copyright 2002-2011 Heino H. Gehlsen . All Rights Reserved. * @license http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 W3CŪ SOFTWARE NOTICE AND LICENSE * @version SVN: $Id: common.inc.php 306810 2010-12-29 00:23:33Z heino $ * @link http://pear.php.net/package/Net_NNTP * @see * @since File available since release 1.3.0 */ /*****************/ /* Setup logging */ /*****************/ // require_once "Log.php"; /** * */ class Logger extends Log { var $_events = array(); function Logger($name = '', $ident = '', $conf = null, $level = PEAR_LOG_NOTICE) { $this->_id = md5(microtime()); $this->_ident = $ident; $this->_mask = Log::UPTO($level); } function log($message, $priority = null) { /* If a priority hasn't been specified, use the default value. */ if ($priority === null) { $priority = $this->_priority; } /* Abort early if the priority is above the maximum logging level. */ if (!$this->_isMasked($priority)) { return false; } /* Extract the string representation of the message. */ $message = $this->_extractMessage($message); /* */ $this->_events[] = array('priority' => $priority, 'message' => $message); /* Notify observers about this log message. */ $this->_announce(array('priority' => $priority, 'message' => $message)); return true; } function dump() { if (count($this->_events) == 0) { return; } echo '
', "\r\n"; echo '

Log:

'; foreach ($this->_events as $event) { $priority = Log::priorityToString($event['priority']); echo '

'; echo '' . ucfirst($priority) . ': '; echo nl2br(htmlspecialchars($event['message'])); echo '

', "\r\n"; } echo '
', "\r\n"; } function grabPearErrors() { require_once "PEAR.php"; PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array(&$this, 'errorHandler')); } function errorHandler($error) { global $logger; if (!isset($logger)) { return; } foreach ($error->backtrace as $X) { if (substr($X['class'], 0, 4) == 'PEAR') { continue; } $message .= get_class($error) . ': "' . $error->getMessage() . '"'; if ($code = $error->getCode()) { $message .= ' (' . $error->getCode(). ')'; } $message .= ' thrown by '; if (isset($X['class'])) { $message .= $X['class'] . '::'; } $message .= $X['function'] . '('; for ($args = $X['args'], $i = 0; isset($args[$i]); ) { $arg = $args[$i]; switch (true) { case is_null($arg): $message .= 'null'; break; case is_string($arg): $message .= "'" . $arg . "'"; break; case is_int($arg): $message .= (int) $arg; break; case is_bool($arg): $message .= $arg ? 'true' : 'false'; break; default: $message .= $arg; } if (!isset($args[++$i])) { break; } $message .= ', '; } $message .= ')'; break; } $logger->log($message, PEAR_LOG_NOTICE); } } // Register connection input parameters if ($allowOverwrite) { $loglevel = isset($_GET['loglevel']) && !empty($_GET['loglevel']) ? $_GET['loglevel'] : $loglevel; } // $logger = new Logger(null, null, null, $loglevel); $logger->grabPearErrors(); /********************/ /* Init NNTP client */ /********************/ // require_once 'Net/NNTP/Client.php'; // $nntp = new Net_NNTP_Client(); // Use logger object as logger in NNTP client $nntp->setLogger($logger); /***************************************************************************************/ /* Credit: Thanks to Brendan Coles (http://itsecuritysolutions.org) */ /* for pointing out the need of url input validation to prevent cross-site */ /* scripting (XXS). The demo was originally never intended as more than an */ /* offline documentation example, but evolved and now requires security */ /* considerations... */ /***************************************************************************************/ // $bodyID = $noext = preg_replace('/(.+)\..*$/', '$1', basename($_SERVER['PHP_SELF'])); /****************************************/ /* Register connection input parameters */ /****************************************/ if ($allowOverwrite) { if (isset($_GET['host']) && !empty($_GET['host']) && !is_array($_GET['host'])) { // Validate input if ($validateInput && !preg_match($hostValidationRegExp, $_GET['host'], $matches)) { error("Error: Invalid host '".htmlentities($_GET['host'])."' !"); } // Actually set internal variable... $host = $_GET['host']; } if ($allowPortOverwrite) { if (isset($_GET['port']) && !empty($_GET['port']) && !is_array($_GET['port'])) { // TODO: add validation... $port = $_GET['port']; } } if (isset($_GET['encryption']) && !empty($_GET['encryption']) && !is_array($_GET['encryption'])) { // TODO: add validation... $encryption = $_GET['encryption']; } if (isset($_GET['user']) && !empty($_GET['user']) && !is_array($_GET['user'])) { // TODO: add validation... $user = $_GET['user']; } if (isset($_GET['pass']) && !empty($_GET['pass']) && !is_array($_GET['pass'])) { // TODO: add validation... $pass = $_GET['pass']; } // Not really a connection parameter, but it still here ;-) if (isset($_GET['wildmat']) && !empty($_GET['wildmat']) && !is_array($_GET['wildmat'])) { // TODO: add validation... $wildmat = $_GET['wildmat']; } } /***********************************/ /* Register other input parameters */ /***********************************/ $group = null; if (isset($_GET['group']) && !empty($_GET['group']) && !is_array($_GET['group'])) { // Validate input if ($validateInput && !preg_match($groupValidationRegExp, $_GET['group'], $matches)) { error("Error: Invalid group '".htmlentities($_GET['group'])."' !"); } // Actually set internal variable... $group = $_GET['group']; } $action = null; if (isset($_GET['action']) && !empty($_GET['action']) && !is_array($_GET['action'])) { // TODO: add validation... $action = strtolower($_GET['action']); } $article = null; if (isset($_GET['article']) && !empty($_GET['article']) && !is_array($_GET['article'])) { // Validate input if ($validateInput && !preg_match($articleValidationRegExp, $_GET['article'], $matches)) { error("Error: Invalid article '".htmlentities($_GET['article'])."' !"); } // Actually set internal variable... $article = $_GET['article']; } $format = 'html'; if (isset($_GET['format']) && !empty($_GET['format']) && !is_array($_GET['format'])) { // TODO: add validation... $format = $_GET['format']; } /********************/ /* */ /********************/ $starttls = ($encryption == 'starttls'); if ($starttls) { $encryption = null; } /*******************/ /* Misc. functions */ /*******************/ function error($text) { // extract($GLOBALS); include 'header.inc.php'; echo '

', $text, '

'; $logger->dump(); include 'footer.inc.php'; die(); } function query($query = null) { // extract($GLOBALS); if (!$allowOverwrite || !$frontpage) { return $query; } $full = 'host=' . urlencode($host) . '&encryption=' . urlencode($encryption) . ($allowPortOverwrite ? '&port=' . urlencode($port) : '') . '&user=' . urlencode($user) . '&pass=' . urlencode($pass) . '&wildmat=' . urlencode($wildmat) . '&loglevel=' . urlencode($loglevel); if (!empty($query)) { $full .= '&' . $query; } return $full; } ?> php-net-nntp-1.5.0/Net_NNTP-1.5.0/docs/examples/demo/config.inc.php000066400000000000000000000113201215221406100243000ustar00rootroot00000000000000 * +-----------------------------------------------------------------------+ * | | * | W3CŪ SOFTWARE NOTICE AND LICENSE | * | http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 | * | | * | This work (and included software, documentation such as READMEs, | * | or other related items) is being provided by the copyright holders | * | under the following license. By obtaining, using and/or copying | * | this work, you (the licensee) agree that you have read, understood, | * | and will comply with the following terms and conditions. | * | | * | Permission to copy, modify, and distribute this software and its | * | documentation, with or without modification, for any purpose and | * | without fee or royalty is hereby granted, provided that you include | * | the following on ALL copies of the software and documentation or | * | portions thereof, including modifications: | * | | * | 1. The full text of this NOTICE in a location viewable to users | * | of the redistributed or derivative work. | * | | * | 2. Any pre-existing intellectual property disclaimers, notices, | * | or terms and conditions. If none exist, the W3C Software Short | * | Notice should be included (hypertext is preferred, text is | * | permitted) within the body of any redistributed or derivative | * | code. | * | | * | 3. Notice of any changes or modifications to the files, including | * | the date changes were made. (We recommend you provide URIs to | * | the location from which the code is derived.) | * | | * | THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT | * | HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, | * | INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR | * | FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE | * | OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, | * | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. | * | | * | COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, | * | SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE | * | SOFTWARE OR DOCUMENTATION. | * | | * | The name and trademarks of copyright holders may NOT be used in | * | advertising or publicity pertaining to the software without | * | specific, written prior permission. Title to copyright in this | * | software and any associated documentation will at all times | * | remain with copyright holders. | * | | * +-----------------------------------------------------------------------+ * * * @category Net * @package Net_NNTP * @author Heino H. Gehlsen * @copyright 2002-2011 Heino H. Gehlsen . All Rights Reserved. * @license http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 W3CŪ SOFTWARE NOTICE AND LICENSE * @version SVN: $Id: config.inc.php 306630 2010-12-25 02:00:55Z heino $ * @link http://pear.php.net/package/Net_NNTP * @see * @since File available since release 1.3.0 */ $frontpage = true; $loglevel = 5; // PEAR_LOG_NOTICE = 5 ; PEAR_LOG_INFO = 6 ; PEAR_LOG_DEBUG = 7 $allowOverwrite = true; $allowPortOverwrite = false; $host = 'news.php.net'; $port = null; $timeout = null; $encryption = null; $user = null; $pass = null; $wildmat = 'php.pear*'; $useRange = false; $max = 10; $validateInput = true; $hostValidationRegExp = '/^([^<>]+)$/'; $articleValidationRegExp = '/^([0-9]+|<[^<]+>)$/'; $groupValidationRegExp = '/^([^<>]+)$/'; ?> php-net-nntp-1.5.0/Net_NNTP-1.5.0/docs/examples/demo/footer.inc.php000066400000000000000000000005631215221406100243400ustar00rootroot00000000000000 php-net-nntp-1.5.0/Net_NNTP-1.5.0/docs/examples/demo/group.php000066400000000000000000000326021215221406100234250ustar00rootroot00000000000000 * +-----------------------------------------------------------------------+ * | | * | W3CŪ SOFTWARE NOTICE AND LICENSE | * | http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 | * | | * | This work (and included software, documentation such as READMEs, | * | or other related items) is being provided by the copyright holders | * | under the following license. By obtaining, using and/or copying | * | this work, you (the licensee) agree that you have read, understood, | * | and will comply with the following terms and conditions. | * | | * | Permission to copy, modify, and distribute this software and its | * | documentation, with or without modification, for any purpose and | * | without fee or royalty is hereby granted, provided that you include | * | the following on ALL copies of the software and documentation or | * | portions thereof, including modifications: | * | | * | 1. The full text of this NOTICE in a location viewable to users | * | of the redistributed or derivative work. | * | | * | 2. Any pre-existing intellectual property disclaimers, notices, | * | or terms and conditions. If none exist, the W3C Software Short | * | Notice should be included (hypertext is preferred, text is | * | permitted) within the body of any redistributed or derivative | * | code. | * | | * | 3. Notice of any changes or modifications to the files, including | * | the date changes were made. (We recommend you provide URIs to | * | the location from which the code is derived.) | * | | * | THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT | * | HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, | * | INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR | * | FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE | * | OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, | * | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. | * | | * | COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, | * | SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE | * | SOFTWARE OR DOCUMENTATION. | * | | * | The name and trademarks of copyright holders may NOT be used in | * | advertising or publicity pertaining to the software without | * | specific, written prior permission. Title to copyright in this | * | software and any associated documentation will at all times | * | remain with copyright holders. | * | | * +-----------------------------------------------------------------------+ * * * @category Net * @package Net_NNTP * @author Heino H. Gehlsen * @copyright 2002-2011 Heino H. Gehlsen . All Rights Reserved. * @license http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 W3CŪ SOFTWARE NOTICE AND LICENSE * @version SVN: $Id: group.php 306619 2010-12-24 12:16:07Z heino $ * @link http://pear.php.net/package/Net_NNTP * @see * @since File available since release 1.3.0 */ /** * */ require_once 'config.inc.php'; /** * */ require_once 'common.inc.php'; /* Validate input */ // $group must be set if (empty($group)) { error('No newsgroup choosen!'); } /* Prepare breadcrumbs */ $breadcrumbs = array(); $breadcrumbs['Frontpage'] = './index.php?' . query(); $breadcrumbs['groups @ ' . ($host == null ? 'localhost' : $host)] = './groups.php?' . query(); $breadcrumbs['group: ' . $group] = null; // Connect $posting = $nntp->connect($host, $encryption, $port); if (PEAR::isError($posting)) { error('Unable to connect to NNTP server: ' . $posting->getMessage()); } // Start TLS encryption if ($starttls) { $R = $nntp->cmdStartTLS(); if (PEAR::isError($R)) { error('Unable to connect to NNTP server: ' . $R->getMessage()); } } // Authenticate if (!is_null($user) && !is_null($pass)) { $authenticated = $nntp->authenticate($user, $pass); if (PEAR::isError($authenticated)) { error('Unable to authenticate: ' . $authenticated->getMessage()); } } // Select group $summary = $nntp->selectGroup($group); if (PEAR::isError($summary)) { error($summary->getMessage()); } // if (!$useRange) { // Select article switch ($article) { case '': case 'last': $article = $nntp->last(); break; case 'first': $article = $nntp->first(); break; } $dummy = $nntp->selectArticle($article); if (PEAR::isError($dummy)) { error($dummy->getMessage()); } // Select next/previous article switch ($action) { case 'next': $dummy = $nntp->selectNextArticle(); break; case 'previous': $dummy = $nntp->selectPreviousArticle(); break; } if (PEAR::isError($dummy)) { error($dummy->getMessage()); } // $i = 0; $articles = array(); // Loop until break inside while (true) { // Break if no more articles if ($article === false) { break; } // Fetch overview for currently selected article $overview = $nntp->getOverview(); if (PEAR::isError($overview)) { error($overview->getMessage()); } // $articles[] = $overview; // Break if max article reached if (++$i >= $max) { break; } // Select next/previous article if ($action == 'next') { $article = $nntp->selectNextArticle(); } else { $article = $nntp->selectPreviousArticle(); } if (PEAR::isError($article)) { error($article->getMessage()); } } } else { // Fetch overview for currently selected article switch ($action) { case '': case 'last': $range = ($nntp->last() - $max + 1) .'-'. $nntp->last(); break; case 'previous': $range = ($article - $max) .'-'. ($article - 1); break; case 'next': $range = ($article + 1) .'-'. ($article + $max); break; case 'first': $range = $nntp->first() .'-'. ($nntp->first() + $max - 1); break; default: error('bad input!'); } $articles = $nntp->getOverview($range); if (PEAR::isError($articles)) { error($articles->getMessage()); } } // Disconnect $nntp->disconnect(); // if (!$useRange) { if ($action != 'next') { $articles = array_reverse($articles); } } /** * */ function nav() { // extract($GLOBALS); // get the first and the last article number from returned articles $first = reset($articles); $last = end($articles); // Start table echo ''; echo ''; // Previous # link echo ''; // Group info echo ''; // Next # link echo ''; // End table echo ''; echo '
'; if ($first['Number'] > $nntp->first()) { echo '« Previous '; } else { echo ' '; } echo ''; echo $group, ' (', $first['Number'], '-', $last['Number'], ' of ', $summary['last'], ' ; ', $summary['count'], ' on server)'; echo ''; if ($last['Number'] < $nntp->last()) { echo 'Next » '; } else { echo ' '; } echo '
'; } /** * */ function articles() { // extract($GLOBALS); // switch ($format) { case ''; case 'html'; echo '', "\r\n"; echo '', "\r\n"; break; case 'rss'; header('Content-type: text/xml'); echo '', "\r\n"; echo '', "\r\n"; echo ' ', "\r\n"; echo ' ', $host, ': ', $group, '', "\r\n"; echo ' http://', $_SERVER['SERVER_NAME'], dirname($_SERVER['SCRIPT_NAME']), '/' , htmlspecialchars(query('group='.$group)), '', "\r\n"; echo ' ', "\r\n"; break; case 'rdf'; header('Content-type: text/xml'); echo '', "\r\n"; echo '', "\r\n"; echo ' ', "\r\n"; echo ' ', $_SERVER['HTTP_HOST'], ' : ', $group, '', "\r\n"; echo ' http://', $_SERVER['SERVER_NAME'], dirname($_SERVER['SCRIPT_NAME']), '/' , htmlspecialchars(query('group='.$group)), '', "\r\n"; echo ' ', $group, 'Newsgroup at ', $host, '', "\r\n"; echo ' en-US', "\r\n"; echo ' ', "\r\n"; break; } // Loop through articles $i == 0; foreach ($articles as $overview) { // $number = $overview['Number']; $subject = $overview['Subject']; $from = $overview['From']; $date = $overview['Date']; // $link = 'article.php?' . query('group='.urlencode($group) . '&article='.urlencode($number)); // Decode subject and from header fields, if mime-extension is loaded... if (function_exists('imap_mime_header_decode')) { // Decode $subject $decoded = imap_mime_header_decode($subject); $subject = ''; foreach ($decoded as $element) { $subject .= $element->text; } // Decode $from $decoded = imap_mime_header_decode($from); $from = ''; foreach ($decoded as $element) { $from .= $element->text; } } // Format... (removes comments etc.) //$date = strftime('%c', strtotime(preg_replace('/\([^\)]*\)/', '', $date))); // Output switch ($format) { case ''; case 'html'; echo ' ', "\r\n"; echo ' ', "\r\n"; echo ' ', "\r\n"; echo ' ', "\r\n"; echo ' ', "\r\n"; echo ' ', "\r\n"; break; case 'rss'; echo ' ', "\r\n"; echo ' http://', $_SERVER['SERVER_NAME'], dirname($_SERVER['SCRIPT_NAME']), '/' . htmlspecialchars($link), '', "\r\n"; echo ' ', htmlspecialchars($subject), '', "\r\n"; echo ' ', '', "\r\n"; echo ' ', $date, '', "\r\n"; echo ' ', "\r\n"; break; case 'rdf': echo ' ', "\r\n"; echo ' ', htmlspecialchars($subject), '', "\r\n"; echo ' http://', $_SERVER['SERVER_NAME'], dirname($_SERVER['SCRIPT_NAME']), '/' . htmlspecialchars($link), '', "\r\n"; echo ' ', '', "\r\n"; echo ' ', $date822, '', "\r\n"; echo ' ', "\r\n"; break; } } // switch ($format) { case ''; case 'html'; echo '
#SubjectAuthorDate
', $number, '', $subject, '', $from, '', str_replace(' ', ' ', $date), '
', "\r\n"; break; case 'rss'; echo ' ', "\r\n"; echo '', "\r\n"; break; case 'rdf'; echo '', "\r\n"; break; } } /**********/ /* Output */ /**********/ if ($format == 'html') { /** * Output header */ include 'header.inc.php'; // $logger->dump(); // nav(); } // if (count($articles) < 1) { echo 'No articles...'; } else { articles(); } // if ($format == 'html') { // nav(); /** * Output footer */ include 'footer.inc.php'; } ?> php-net-nntp-1.5.0/Net_NNTP-1.5.0/docs/examples/demo/groups.php000066400000000000000000000157101215221406100236110ustar00rootroot00000000000000 * +-----------------------------------------------------------------------+ * | | * | W3CŪ SOFTWARE NOTICE AND LICENSE | * | http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 | * | | * | This work (and included software, documentation such as READMEs, | * | or other related items) is being provided by the copyright holders | * | under the following license. By obtaining, using and/or copying | * | this work, you (the licensee) agree that you have read, understood, | * | and will comply with the following terms and conditions. | * | | * | Permission to copy, modify, and distribute this software and its | * | documentation, with or without modification, for any purpose and | * | without fee or royalty is hereby granted, provided that you include | * | the following on ALL copies of the software and documentation or | * | portions thereof, including modifications: | * | | * | 1. The full text of this NOTICE in a location viewable to users | * | of the redistributed or derivative work. | * | | * | 2. Any pre-existing intellectual property disclaimers, notices, | * | or terms and conditions. If none exist, the W3C Software Short | * | Notice should be included (hypertext is preferred, text is | * | permitted) within the body of any redistributed or derivative | * | code. | * | | * | 3. Notice of any changes or modifications to the files, including | * | the date changes were made. (We recommend you provide URIs to | * | the location from which the code is derived.) | * | | * | THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT | * | HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, | * | INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR | * | FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE | * | OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, | * | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. | * | | * | COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, | * | SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE | * | SOFTWARE OR DOCUMENTATION. | * | | * | The name and trademarks of copyright holders may NOT be used in | * | advertising or publicity pertaining to the software without | * | specific, written prior permission. Title to copyright in this | * | software and any associated documentation will at all times | * | remain with copyright holders. | * | | * +-----------------------------------------------------------------------+ * * * @category Net * @package Net_NNTP * @author Heino H. Gehlsen * @copyright 2002-2011 Heino H. Gehlsen . All Rights Reserved. * @license http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 W3CŪ SOFTWARE NOTICE AND LICENSE * @version SVN: $Id: groups.php 306619 2010-12-24 12:16:07Z heino $ * @link http://pear.php.net/package/Net_NNTP * @see * @since File available since release 1.3.0 */ /** * */ require_once 'config.inc.php'; /** * */ require_once 'common.inc.php'; /* Prepare breadcrumbs */ $breadcrumbs = array(); $breadcrumbs['Frontpage'] = './index.php?' . query(); $breadcrumbs['Groups @ ' . ($host == null ? 'localhost' : $host)] = null; // Connect $posting = $nntp->connect($host, $encryption, $port); if (PEAR::isError($posting)) { error('Unable to connect to NNTP server: ' . $posting->getMessage()); } // Start TLS encryption if ($starttls) { $R = $nntp->cmdStartTLS(); if (PEAR::isError($R)) { error('Unable to connect to NNTP server: ' . $R->getMessage()); } } // Authenticate if (!is_null($user) && !is_null($pass)) { $authenticated = $nntp->authenticate($user, $pass); if (PEAR::isError($authenticated)) { error('Unable to authenticate: ' . $authenticated->getMessage()); } } // Fetch list of groups $groups = $nntp->getGroups($wildmat); if (PEAR::isError($groups)) { error('Fetching list of groups failed: ' . $groups->getMessage()); } // Fetch known (to the server) group descriptions $descriptions = $nntp->getDescriptions($wildmat); if (PEAR::isError($descriptions)) { $logger->notice('Fetching group descriptions failes: ' . $descriptions->getMessage()); // $descriptions = array(); } // Close connection $nntp->disconnect(); /** * */ function groups() { // extract($GLOBALS); // echo '', "\r\n"; echo '', "\r\n"; // Loop through groups $i = 0; foreach ($groups as $group) { $link = 'group.php?' . query('group='.urlencode($group['group'])); $messageCount = $group['last'] - $group['first'] + 1; $description = empty($descriptions[$group['group']]) ? '' : $descriptions[$group['group']]; switch ($group['posting']) { case 'y': $posting = 'yes'; break; case 'n': $posting = 'no'; break; case 'm': $posting = 'moderated'; break; default: $posting = 'unknown'; } echo ' ', "\r\n"; echo ' ', "\r\n"; echo ' ', "\r\n"; echo ' ', "\r\n"; echo ' ', "\r\n"; echo ' ', "\r\n"; } // echo '
GroupArticlesDescriptionPosting
', $group['group'], '', $messageCount, '', $description, '', $posting, '
', "\r\n"; } /**********/ /* Output */ /**********/ /** * Output header */ include 'header.inc.php'; // $logger->dump(); // groups(); /** * Output footer */ include 'footer.inc.php'; ?> php-net-nntp-1.5.0/Net_NNTP-1.5.0/docs/examples/demo/header.inc.php000066400000000000000000000027421215221406100242730ustar00rootroot00000000000000', "\n"; ?> PEAR::Net_NNTP Demo php-net-nntp-1.5.0/Net_NNTP-1.5.0/docs/examples/demo/index.php000066400000000000000000000153311215221406100234000ustar00rootroot00000000000000 * +-----------------------------------------------------------------------+ * | | * | W3CŪ SOFTWARE NOTICE AND LICENSE | * | http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 | * | | * | This work (and included software, documentation such as READMEs, | * | or other related items) is being provided by the copyright holders | * | under the following license. By obtaining, using and/or copying | * | this work, you (the licensee) agree that you have read, understood, | * | and will comply with the following terms and conditions. | * | | * | Permission to copy, modify, and distribute this software and its | * | documentation, with or without modification, for any purpose and | * | without fee or royalty is hereby granted, provided that you include | * | the following on ALL copies of the software and documentation or | * | portions thereof, including modifications: | * | | * | 1. The full text of this NOTICE in a location viewable to users | * | of the redistributed or derivative work. | * | | * | 2. Any pre-existing intellectual property disclaimers, notices, | * | or terms and conditions. If none exist, the W3C Software Short | * | Notice should be included (hypertext is preferred, text is | * | permitted) within the body of any redistributed or derivative | * | code. | * | | * | 3. Notice of any changes or modifications to the files, including | * | the date changes were made. (We recommend you provide URIs to | * | the location from which the code is derived.) | * | | * | THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT | * | HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, | * | INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR | * | FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE | * | OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, | * | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. | * | | * | COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, | * | SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE | * | SOFTWARE OR DOCUMENTATION. | * | | * | The name and trademarks of copyright holders may NOT be used in | * | advertising or publicity pertaining to the software without | * | specific, written prior permission. Title to copyright in this | * | software and any associated documentation will at all times | * | remain with copyright holders. | * | | * +-----------------------------------------------------------------------+ * * * @category Net * @package Net_NNTP * @author Heino H. Gehlsen * @copyright 2002-2011 Heino H. Gehlsen . All Rights Reserved. * @license http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 W3CŪ SOFTWARE NOTICE AND LICENSE * @version SVN: $Id: index.php 306630 2010-12-25 02:00:55Z heino $ * @link http://pear.php.net/package/Net_NNTP * @see * @since File available since release 1.3.0 */ /** * */ require_once 'config.inc.php'; // Forward to groups.php if $frontpage not allowed if (!$frontpage) { include 'groups.php'; die(); } /** * */ require_once 'common.inc.php'; /** * Output header */ include 'header.inc.php'; ?>
Host:(Defaults to 'localhost' when empty)
Port:>(Defaults to '119' on non-encrypted connections, and '563' on encrypted connections when empty)
Windmat:(Group wildmat)
Username:(Only used if both username and password is entered)
Password:(Only used if both username and password is entered)
Encryption:none
startTLS(Starts encryption on an initially unencrypted connection)
TLS(Requires a NNTPS server)
SSL(Requires a NNTPS server)
Loglevel:warning
notice
info
debug
(Application logging level)
php-net-nntp-1.5.0/Net_NNTP-1.5.0/docs/examples/demo/style.css000066400000000000000000000063601215221406100234340ustar00rootroot00000000000000body { margin: 0px; padding: 0px; color: #000000; background: #ffffff; } body, li, th, td { font-family: verdana,arial,helvetica,sans-serif; font-size: 95%; } .debug { border: 0px solid #999999; border-top-width: 3px; border-bottom-width: 3px; margin: 0em; margin-top: 1em; margin-bottom: 1em; padding: 0em; } .debug p { color: #333333; border-color: #999999; border-style: solid; border-width: 0px; border-left-width: 3px; border-right-width: 3px; margin: 0em; margin-left: 1em; margin-right: 1em; padding: 0em; padding-left: 1em; padding-right: 1em; XXXfont-family: system; Xfont-size: %; } .debug p.warning { border-color: #990000; } .debug p.notice { border-color: #000099; } .debug p.info { border-color: #009900; } .debug p.debug { color: #999999; border-color: #999999; } img { border : 0px; } .odd { background: #ffffff; } .even { background: #ddddcc; } td { color: #000000; } .nav { width: 20%; } a:link { color: #000099; } a:hover { color: #ff0000; } #page-header tr.header { background-color: #339900; } #page-header tr.subheader { background-color: #006600; height : 15px; } #page-header tr.header a { color: #66cc66; text-decoration: none; } #page-header tr.header a:hover { color: #66ff66; text-decoration: underline; } #page-header tr.header h1 { color: #66ff66; } #page-header tr.header h1 a { color: #66ff66; text-decoration: none; } #page-breadcrumbs { margin-top: 0.5ex; margin-bottom: 1.5em; } #page-breadcrumbs a { color: #666600; text-decoration: none; font-weight: bolder; } #page-breadcrumbs a:hover { text-decoration: underline; } #page-footer { margin-top: 2em; } #page-footer hr { color: #999999; } #page-footer .copyright { font-size: 75%; color: #999999; text-align: center; } #page-footer .copyright a { color: #999999; } #page-footer .copyright a:hover { color: #000000; } #index #xxx td { border-top: 1px dashed #cccccc; } #groups th { color: #000000; background: #999966; } #groups .group .name { font-weight: bolder; } #groups .group .name a { text-decoration: none; } #groups .group .name a:hover { text-decoration: underline; } #groups .posting-yes .name a { color: #006600; } #groups .posting-yes .posting { color: #006600; } #groups .posting-no .name a { color: #660000; } #groups .posting-no .posting { color: #660000; } #groups .posting-moderated .name a { color: #666600; } #groups .posting-moderated .posting { color: #666600; } #group th { color: #000000; background: #999966; } #article #article-head .label { background: #ddddcc; text-align: right; font-weight: bold; } #article #article-head .value { background: #eeeeee; text-align: left; } #article #article-body { color: #000000; } #article #article-body .quote { color: #006600; } #article #article-body .signature { font-size: smaller; color: gray; } #article #article-body .signature a { color: #9999ff; } #article #article-body .signature a:hover { color: #ff9999; } php-net-nntp-1.5.0/Net_NNTP-1.5.0/docs/examples/phpdoc/000077500000000000000000000000001215221406100221065ustar00rootroot00000000000000php-net-nntp-1.5.0/Net_NNTP-1.5.0/docs/examples/phpdoc/authenticate.php000066400000000000000000000002671215221406100253020ustar00rootroot00000000000000$authenticated = $nntp->authenticate('somebody', 'secret'); if (PEAR::isError($authenticated)) { // handle error } if ($authenticated) { // success } else { // failure } php-net-nntp-1.5.0/Net_NNTP-1.5.0/docs/examples/phpdoc/connect.php000066400000000000000000000001401215221406100242430ustar00rootroot00000000000000$posting = $nntp->connect('news.php.net'); if (PEAR::isError($posting)) { // handle error } php-net-nntp-1.5.0/Net_NNTP-1.5.0/docs/examples/phpdoc/constructor.php000066400000000000000000000000371215221406100252040ustar00rootroot00000000000000$nntp = new Net_NNTP_Client(); php-net-nntp-1.5.0/Net_NNTP-1.5.0/docs/examples/phpdoc/getDescriptions.php000066400000000000000000000003221215221406100257620ustar00rootroot00000000000000$descriptions = $nntp->getDescriptions('*.pear.*'); if (PEAR::isError($descriptions)) { // handle error } foreach ($descriptions as $group => $description) { echo $group, ': ', $description, "\r\n"; } php-net-nntp-1.5.0/Net_NNTP-1.5.0/docs/examples/phpdoc/getGroups.php000066400000000000000000000004011215221406100245710ustar00rootroot00000000000000$groups = $nntp->getGroups('*.pear.*'); if (PEAR::isError($groupsummary)) { // handle error } foreach ($groups as $group) { echo $group['group'], ': '; echo $group['first'], '-', $group['last']; echo ' (', $group['posting'], ')', "\r\n"; } php-net-nntp-1.5.0/Net_NNTP-1.5.0/docs/examples/phpdoc/getOverview.php000066400000000000000000000014421215221406100251260ustar00rootroot00000000000000// Detches single article $overview = $nntp->getOverview(5); $overview = $nntp->getOverview(''); if (PEAR::isError($overview)) { // handle error } echo 'Number: ', $overview['Number'], "\r\n"; echo 'Subject: ', $overview['Subject'], "\r\n"; echo 'From: ', $overview['From'], "\r\n"; echo 'Date: ', $overview['Date'], "\r\n"; // Fetches multiple articles $overview = $nntp->getOverview(); $overview = $nntp->getOverview('5-'); $overview = $nntp->getOverview('5-9'); if (PEAR::isError($overview)) { // handle error } foreach ($overview as $name => $content) { echo 'Number: ', $content['Number'], "\r\n"; echo 'Subject: ', $content['Subject'], "\r\n"; echo 'From: ', $content['From'], "\r\n"; echo 'Date: ', $content['Date'], "\r\n"; } php-net-nntp-1.5.0/Net_NNTP-1.5.0/docs/examples/phpdoc/selectArticle.php000066400000000000000000000004371215221406100254060ustar00rootroot00000000000000$groupsummary = $nntp->selectGroup('php.pear.general'); if (PEAR::isError($groupsummary)) { // handle error } $article = $nntp->selectArticle(5); if (PEAR::isError($article)) { // handle error } if ($article === false) { // article does not exist } else { // success } php-net-nntp-1.5.0/Net_NNTP-1.5.0/docs/examples/phpdoc/selectGroup.php000066400000000000000000000003661215221406100251200ustar00rootroot00000000000000$groupsummary = $nntp->selectGroup('php.pear.general'); if (PEAR::isError($groupsummary)) { // handle error } $group = $groupsummary['group']; $count = $groupsummary['count']; $first = $groupsummary['first']; $last = $groupsummary['last']; php-net-nntp-1.5.0/Net_NNTP-1.5.0/docs/examples/phpdoc/selectNextArticle.php000066400000000000000000000002571215221406100262450ustar00rootroot00000000000000$article = $nntp->selectNextArticle(); if (PEAR::isError($article)) { // handle error } if ($article === false) { // article does not exist } else { // success } php-net-nntp-1.5.0/Net_NNTP-1.5.0/docs/examples/phpdoc/selectPreviousArticle.php000066400000000000000000000002631215221406100271400ustar00rootroot00000000000000$article = $nntp->selectPreviousArticle(); if (PEAR::isError($article)) { // handle error } if ($article === false) { // article does not exist } else { // success } php-net-nntp-1.5.0/package.xml000066400000000000000000000675571215221406100162000ustar00rootroot00000000000000 Net_NNTP pear.php.net NNTP implementation PEAR's package for communication with NNTP/Usenet servers. Net_NNTP handles the connection and protocol level commands (RFC977), including many commonly implemented non-standard commands (RFC2980). Net_NNTP includes an unserfriendly API for intermediate user, who don't want to work directly at the command level. However, Net_NNTP does require some knowlege about the NNTP protocol (RFC 977), and general knowledge about email (RFC(2)822) and MIME (2045-2048), since any handling of both content and headers is left up to the user! The protocol implementation does not parse the actual article data, but at the command level it splits returned data at protocol specified boundaries where appropriate. Heino H. Gehlsen heino heino@gehlsen.dk yes Jan-Pascal van Best janpascal janpascal@vanbest.org yes 2013-05-31 1.5.0 0.9.0 stable alpha W3C Stable release, only bug reported during 1,5 years of RC status just fixed 5.0.0 1.4.5 PEAR pear.php.net 1.4.0 Log pear.php.net 1.8.7 2013-05-31 1.5.0RC3 0.9.0 stable alpha Fix noisy version_compare warning (bug #19753) 2011-10-05 1.5.0RC2 0.9.0 beta alpha + Fix limited buffer for large replies from server (bug# 18875) 2011-08-15 1.5.0RC1 0.9.0 beta alpha + Fix NNTP injection vulnerability (reported by Brendan Coles, itsecuritysolutions.org) + Fix XXS vulnerability in demo (reported by Brendan Coles, itsecuritysolutions.org) + Fix usage of deprecated split() (bug #17417 and #17783) + Fix for large groups on 32 bit systems: Article numbers are no longer cast into integers, but passed on directly from the server as strings (bug #17689). This _could_ possibly have implications and should considered a possible backward compatibility breakage, but is thought to be acceptable, since PHP is expected to cast into integers/floats as needed... 2009-10-04 1.5.0a1 0.8.1 alpha alpha W3C + Added support for STARTTLS encryption + Use PHP's streams instead of Net_NNTP (to allow easy TLS encryption and future on demand data compressed) + Improved logging with notices for most commands + Added warning about feof() defect in PHP 5.2.11 (bug #49706) 2008-06-17 1.4.0 0.8.1 stable alpha W3C Finally released as stable - after two years as release candidate... 1.4.0RC1 0.8.1 beta alpha 2006-06-17 W3C Changes in Net_NNTP_Client: - fix bug #6833: mail() does not work - fix bug #6845: notices in getOverview() + Loading deprecated classes Net_NNTP_Message and Net_NNTP_Header now triggers warnings ! 1.3.3 0.8.1 beta alpha 2006-02-06 W3C + Changes in Net_NNTP_Protocol_Client: - fix bug #6618: notices in cmdListNewsgroups() 1.3.2 0.8.1 alpha alpha 2005-12-23 W3C + Changes in Net_NNTP_Client: - getNewArticles() and getNewGroups() now validates that any strtotime() convertions was successfull. + Changes in Net_NNTP_Protocol_Client: - fix bug #6334: cmdNewNews() and cmdNewGroups() no longer localize the timestamp depending on timezones. 1.3.1 0.8.1 alpha alpha 2005-12-23 W3C + Changes in Net_NNTP_Client: - added: mail() as a replacement for experimental post() using identical parameters as PHP's mail() function, (temporarily) preserving backward compatibility with experimental method in v1.0. - modified and rewritten: post(), reduced to having only one parameter, (temporarily) preserving backward compatibility with experimental method in v1.0. + Changes in Net_NNTP_Protocol_Client: - added: _sendArticle() - modified and rewritten: cmdPost() split into cmdPost() and cmdPost2() + now sends data via _sendArticle() - modified and rewritten: cmdIhave() split into cmdIhave() and cmdIhave2() + now sends data via _sendArticle() 1.3.1 0.8.0 alpha alpha 2005-12-14 W3C + WARNING! - Serious backward compatibility break with v1.2.x (alpha) releases!!! The experimental classes Net_NNTP_Header and Net_NNTP_Message has been droped, since such features does not belong in this package! For now loading either class results in a notice/warning, but later on both classes will be removed! Previously unimplementet NNTP commands now allow access to article headers... - Some backward compatibility break with v1.1.x (beta) releases!!! + Changes in Net_NNTP_Client: - fixed: connect(), now returns false when posting is prohibited (like cmdModeReader()). - fixed: getGroupArticles(), now updates internal group summary cache. - added: getHeaderField(). - added: getGroupArticles(). - modified: connect(), added $encryption parameter to support ssl/tls connections, and $timeout parameter. - modified: selectGroup(), added (experimental) parameter to allow fetching of article numbers at once. - modified: getOverview(), added two (experimental) parameters (rewritten to preserve backward compatible with v1.0). - modified and rewritten: getGroups(), addition of optional $wildmat parameter. - modified and rewritten: getDescriptions(), addition of optional $wildmat parameter. - modified and rewritten: getOverview(), $first and $last parameters changed into $range. - renamed: quit() into disconnect(), (temporarily) preserving backward compatible with v1.0. - renamed: getArticleRaw() into getArticle(), (temporarily) preserving backward compatible with v1.1. - renamed: getHeaderRaw() into getHeader(), (temporarily) preserving backward compatible with v1.1. - renamed: getBodyRaw() into getBody(), (temporarily) preserving backward compatible with v1.1. - renamed and rewritten: getReferencesOverview() into getReferences(). - removed: connectAuthenticated() (as in MAINT_1_0 and MAINT_1_2). - removed: isConnected() removed due to use of private members in Net_Socket! - misc: all internal PEAR::throwError() changed to $this->throwError(). - misc: major phpdoc rewrite. - misc: removal of code related to not yet implemented alternative authentication methods. + Changes in Net_NNTP_Protocol_Client: - added: cmdXHdr(). - added: cmdCapabilities(). - added: cmdHelp(). - added: cmdListActive(). - added: cmdXPat(). - modified connect(), added $encryption parameter to support ssl/tls connections. - modified: cmdNext(), now returns array by default. - modified and rewritten: cmdXOver(), first parameter now optional. - renamed: isConnected() into _isConnected(), due to use of private members in Net_Socket. - misc: support for logging via the Log package (debugging rewritten to use logger). - misc: use of status response code constants in Net_NNTP_Protocol_Responsecode. - misc: extends PEAR (as in v1.0.x). - misc: all internal PEAR::throwError() changed to $this->throwError(). + Examples replaced by fully functional newsgroup reader demo. + License upgraded to newer edition of 'W3C SOFTWARE NOTICE AND LICENSE' 1.2.5 0.7.4 alpha alpha 2005-11-27 W3C + getHeaderField() added + getReferencesOverview() rewritten + cmdOver() added + cmdHelp() added + cmdXHdr() added + cmdCapabilities() added + cmdXOver() rewritten + cmdListOverviewFmt rewritten + cmdNext() modified + cmdPrevious() modified + cmdStat() modified + connectAuthenticated() removed + examples rewritten 1.2.4 0.7.3 alpha alpha 2005-10-20 W3C + Fix: connect() now returns false when posting is prohibited, like cmdModeReader() does + New: Response code constants + Misc. internal rewrites in protocol implementation: - Expected response codes in cmdArticle(), cmdHead() and cmdBody() reduced to correspond actual implementations. - First parameter in cmdXOver(), cmdXROver() and cmdListgroup() is now optional. - New third optional parameter in getNewNews() and cmdNewnews(). - cmdNext(), cmdLast() and cmdStat() now returns array by default. 1.2.3 0.7.2 alpha alpha 2005-05-13 W3C + New method in Net_NNTP_Client: getBody(). + Added parameters to Net_NNTP_Client::getArticle/getHeader() to allow use of external return classes. + Added status response code constants in Net_NNTP_Protocol_Clients. 1.2.2 0.7.1 alpha alpha 2005-03-13 W3C + Bug #3967 fixed: typo in Net_NNTP_Header::decodeString(). 1.2.1 0.7.1 alpha alpha 2005-03-28 W3C + New methods in Net_NNTP_Client: selectArticle(), selectNextArticle() and selectPreviousArticle(). + New methods in Net_NNTP_Protocol_Client: cmdStat(), cmdNext() and cmdLast(). 1.2.0 0.7.0 alpha alpha 2005-01-14 W3C + Corresponds to v0.11.3 (exact feature match). 1.1.2 0.6.2 beta beta 2005-05-13 W3C + Three new Net_NNTP_Client methods: getArticle(), getHeader() and getBody() - stripped down versions from the v1.2 releases (no default return classes). 1.1.1 0.6.1 beta beta 2005-03-28 W3C + Net_NNTP_Client::connectAuthenticated() removed - it should only exist in the MAINT_1_2 branch for now (was not removed by mistake in the v1.1.0 release). 1.1.0 0.6.0 beta beta 2005-01-14 W3C + This release is NOT fully backward compatible with v0.11.3, since experimental features (Net_NNTP_Message and Net_NNTP_Header and related methods Net_NNTP_Client::getArticle() and Net_NNTP_Client::getHeader()) have been removed (users of those features should consider v1.2.x in stead). 1.0.1 0.5.0 stable beta 2005-03-28 W3C + Fixes lack of $fp property in historical Net_NNTP class (only relevant for backward compatibility with v0.2.5). + Fixes typo in examples. 1.0.0 0.5.0 stable beta 2005-01-18 W3C + This release is NOT backward compatible with v0.11.3, since all non-stable features (classes, methods etc.) have been removed!!! + Users of releases between 0.3.x and 0.11.x should consider v1.1.x or v1.2.x in stead. (This release is meant only as a final replacement for v0.2.5 - and of cause as a way to finally get rid of the former protocol implementation). + Backward compatible with v0.2.5 (this is ONLY guarantied in v1.0.x releases, and may be removed in the future). 1.0.0RC1 0.5.0 beta beta 2005-01-14 W3C + This release is NOT backward compatible with v0.11.3, since all non-stable features (classes, methods etc.) have been removed!!! + Users of releases between 0.3.x and 0.11.x should consider v1.1.x or v1.2.x in stead. (This release is meant only as a final replacement for v0.2.5 - and of cause as a way to finally get rid of the former protocol implementation). + Backward compatible with v0.2.5 (this is ONLY guarantied in v1.0.x releases, and may be removed in the future). 0.11.3 0.4.3 beta beta 2004-09-06 W3C + Going beta (features not documented in the manual should still be considered experiemental). + Added the 'distributions' parameter to getNewGroups() and cmdNewGroups(). 0.11.2 0.4.2 alpha alpha 2004-08-22 W3C + Update PhpDoc blocks. + Changed xmdXOver(),cmdXROver(),getOverview() and getReferencesOverview() into using only parameter: $range. + Fixes whitespace in Net_NNTP_Client, Net_NNTP_Protocol_Client and Net_NNTP. 0.11.1 0.4.1 devel alpha 2004-07-30 W3C + Fixes bug in (deprecated) Net_NNTP::command(). + Rename a few constants due to renamed classes (BC preserved). + Update class phpdoc blocks. 0.11.0 0.4.0 devel alpha 2004-07-19 W3C + New directory structure (classes/files renamed/moved) to allow future server class (dummy files preserves backward compatibility). 0.10.3 0.3.1 alpha alpha 2004-07-14 W3C + Fixes undefined property warning. 0.10.2 0.3.1 alpha alpha 2004-07-06 W3C + Fixes bug #1803 (trailing space character sent in cmdListNewsgrups()). + Fixes bug #825 (no more lazy assignement of new values to $this). + Examples moved into docs to comply with the standard PEAR directory structure. 0.10.1 0.3.1 alpha alpha 2003-10-24 W3C + Fixes bug #7 (lines longer than 1000 chars no longer stop download). 0.10.0 0.3.0 alpha alpha 2003-10-12 W3C + Merges v0.3.3 and v0.9.4 into one package (The 'Net_NNTP' class from v0.9.x is now called 'Net_NNTP_Realtime'). 0.9.3 0.2.2 alpha alpha 2003-09-13 W3C + Fixes Incorrect handling of the XROVER extension corrected in cmdXROver() and removed in getOverview(). + Constant names pearified. + Deprecated/historical methods that didn't follow PEAR's coding standard have been removed. 0.9.2 0.2.1 alpha alpha 2003-08-16 W3C + Fixes syntax typo... 0.9.1 0.2.1 alpha alpha 2002-08-15 W3C + Bug fixing and improvements in Net_NNTP_Header and Net_NNTP_Message. 0.9.0 0.2.0 alpha alpha 2002-08-09 W3C + Major rewrite, yet still generaly backward compatible - now uses Net_Socket, lets the user choose if the article data are to be returned as strings or arrays or objects, authentication has been separated from the execution of commands, returns pear_error objects of failure, and handles the server's responses individually. 0.3.3 0.1.1 beta beta 2003-10-12 W3C + Fixes bug #85. + PhpDoc updateds. 0.3.2 0.1.1 beta beta 2003-09-20 W3C + Incorrect handling of the XROVER extension corrected in cmdXROver() and removed in getOverview(). 0.3.1 0.1.1 beta beta 2003-08-31 W3C + Uses the new protocol implementation from 0.9.*, but preserves backward compatibility with 0.2, since the experimental header and message classes are not used. + Deprecated/historical methods that didn't follow PEAR's coding standard have been removed. 0.2.5 0.0.3 stable alpha 2004-07-19 PHP 2.0 + post() rewritten to allow posting using authentication (bug #817). + Examples moved into docs to comply with the standard PEAR directory structure. 0.2.4 0.0.3 stable alpha 2004-03-10 PHP 2.0 (Not released) 0.2.3 0.0.3 stable alpha 2003-09-20 PHP 2.0 + Incorrect handling of the XROVER extension in getOverview() removed. 0.2.2 0.0.3 stable alpha 2003-08-31 PHP 2.0 + Constant names pearified. 0.2.1 0.0.2 stable alpha 2003-08-09 PHP 2.0 + Fix binary safety. 0.2 0.0.2 stable alpha 2003-07-20 PHP 2.0 + Pearified API. 0.1 0.0.1 stable alpha 2002-05-22 PHP 2.0 + This is the initial independent release of the NNTP package.