#!/usr/bin/env php _store->exists($pasteId)) { self::_error('given ID does not exist, has expired or was already deleted', 6); } $this->_store->delete($pasteId); if ($this->_store->exists($pasteId)) { self::_error('paste ID exists after deletion, permission problem?', 7); } exit("paste $pasteId successfully deleted" . PHP_EOL); } /** * removes empty directories, if current storage model uses Filesystem * * @access private */ private function _empty_dirs() { if ($this->_conf->getKey('class', 'model') !== 'Filesystem') { self::_error('instance not using Filesystem storage, no directories to empty', 4); } $dir = $this->_conf->getKey('dir', 'model_options'); passthru("find $dir -type d -empty -delete", $code); exit($code); } /** * display a message on STDERR and exits * * @access private * @static * @param string $message * @param int $code optional, defaults to 1 */ private static function _error($message, $code = 1) { self::_error_echo($message); exit($code); } /** * display a message on STDERR * * @access private * @static * @param string $message */ private static function _error_echo($message) { fwrite(STDERR, 'Error: ' . $message . PHP_EOL); } /** * display usage help on STDOUT and exits * * @access private * @static * @param int $code optional, defaults to 0 */ private static function _help($code = 0) { echo <<<'EOT' Usage: administration [--delete | --empty-dirs | --help | --statistics] Options: -d, --delete deletes the requested paste ID -e, --empty-dirs removes empty directories (only if Filesystem storage is configured) -h, --help displays this help message -s, --statistics reads all stored pastes and comments and reports statistics EOT, PHP_EOL; exit($code); } /** * return option for given short or long keyname, if it got set * * @access private * @static * @param string $short * @param string $long * @return string|null */ private function _option($short, $long) { foreach (array($short, $long) as $key) { if (array_key_exists($key, $this->_opts)) { return $this->_opts[$key]; } } return null; } /** * initialize options from given argument array * * @access private * @static * @param array $arguments */ private function _options_initialize($arguments) { if ($arguments > 3) { self::_error_echo('too many arguments given'); echo PHP_EOL; self::_help(1); } if ($arguments < 2) { self::_error_echo('missing arguments'); echo PHP_EOL; self::_help(2); } $this->_opts = getopt('hd:eps', array('help', 'delete:', 'empty-dirs', 'purge', 'statistics')); if (!$this->_opts) { self::_error_echo('unsupported arguments given'); echo PHP_EOL; self::_help(3); } } /** * reads all stored pastes and comments and reports statistics * * @access public */ private function _statistics() { $counters = array( 'burn' => 0, 'discussion' => 0, 'expired' => 0, 'md' => 0, 'percent' => 1, 'plain' => 0, 'progress' => 0, 'syntax' => 0, 'total' => 0, 'unknown' => 0, ); $time = time(); $ids = $this->_store->getAllPastes(); $counters['total'] = count($ids); $dots = $counters['total'] < 100 ? 10 : ( $counters['total'] < 1000 ? 50 : 100 ); $percentages = $counters['total'] < 100 ? 0 : ( $counters['total'] < 1000 ? 4 : 10 ); echo "Total:\t\t\t${counters['total']}", PHP_EOL; foreach ($ids as $pasteid) { $paste = $this->_store->read($pasteid); ++$counters['progress']; if ( array_key_exists('expire_date', $paste['meta']) && $paste['meta']['expire_date'] < $time ) { ++$counters['expired']; } if (array_key_exists('adata', $paste)) { $format = $paste['adata'][1]; $discussion = $paste['adata'][2]; $burn = $paste['adata'][3]; } else { $format = array_key_exists('formatter', $paste['meta']) ? $paste['meta']['formatter'] : 'plaintext'; $discussion = array_key_exists('opendiscussion', $paste['meta']) ? $paste['meta']['opendiscussion'] : false; $burn = array_key_exists('burnafterreading', $paste['meta']) ? $paste['meta']['burnafterreading'] : false; } if ($format === 'plaintext') { ++$counters['plain']; } elseif ($format === 'syntaxhighlighting') { ++$counters['syntax']; } elseif ($format === 'markdown') { ++$counters['md']; } else { ++$counters['unknown']; } $counters['discussion'] += (int) $discussion; $counters['burn'] += (int) $burn; // display progress if ($counters['progress'] % $dots === 0) { echo '.'; if ($percentages) { $progress = $percentages / $counters['total'] * $counters['progress']; if ($progress >= $counters['percent']) { printf(' %d%% ', 100 / $percentages * $progress); ++$counters['percent']; } } } } echo PHP_EOL, << 0) { echo "Unknown format:\t\t${counters['unknown']}", PHP_EOL; } } /** * constructor * * initializes and runs administrative tasks * * @access public */ public function __construct() { $this->_options_initialize($_SERVER['argc']); if ($this->_option('h', 'help') !== null) { self::_help(); } $this->_conf = new Configuration; if ($this->_option('e', 'empty-dirs') !== null) { $this->_empty_dirs(); } $class = 'PrivateBin\\Data\\' . $this->_conf->getKey('class', 'model'); $this->_store = new $class($this->_conf->getSection('model_options')); if (($pasteId = $this->_option('d', 'delete')) !== null) { $this->_delete($pasteId); } if ($this->_option('p', 'purge') !== null) { $this->_store->purge(PHP_INT_MAX); exit('purging of expired pastes concluded' . PHP_EOL); } if ($this->_option('s', 'statistics') !== null) { $this->_statistics(); } } } new Administration();