diff --git a/bin/privatebin-admin b/bin/privatebin-admin new file mode 100755 index 00000000..85d7574d --- /dev/null +++ b/bin/privatebin-admin @@ -0,0 +1,184 @@ +#!/usr/bin/env php + | --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); +} + +function option($short, $long) { + global $options; + $option = null; + foreach (array($short, $long) as $key) { + if (array_key_exists($key, $options)) { + $option = $options[$key]; + } + } + return $option; +} + +function main() { + if ($_SERVER['argc'] > 3) { + error_echo('too many arguments given'); + fwrite(STDERR, PHP_EOL); + help(1); + } + + if ($_SERVER['argc'] < 2) { + error_echo('missing arguments'); + fwrite(STDERR, PHP_EOL); + help(2); + } + + global $options; + $options = getopt('hd:eps', array('help', 'delete:', 'empty-dirs', 'purge', 'statistics')); + if (!$options) { + error_echo('unsupported arguments given'); + fwrite(STDERR, PHP_EOL); + help(3); + } + + if (option('h', 'help') !== null) { + help(); + } + + $conf = new Configuration; + + if (option('e', 'empty-dirs') !== null) { + if ($conf->getKey('class', 'model') !== 'Filesystem') { + error('instance not using Filesystem storage, no directories to empty', 4); + } + $dir = $conf->getKey('dir', 'model_options'); + passthru("find $dir -type d -empty -delete", $code); + exit($code); + } + + $class = 'PrivateBin\\Data\\' . $conf->getKey('class', 'model'); + $store = new $class($conf->getSection('model_options')); + + if (($pasteid = option('d', 'delete')) !== null) { + if (!Paste::isValidId($pasteid)) { + error('given ID is not a valid paste ID (16 hexadecimal digits)', 5); + } + if (!$store->exists($pasteid)) { + error('given ID does not exist, has expired or was already deleted', 6); + } + $store->delete($pasteid); + if ($store->exists($pasteid)) { + error('paste ID exists after deletion, permission problem?', 7); + } + exit("paste $pasteid successfully deleted" . PHP_EOL); + } + + if (option('p', 'purge') !== null) { + $store->purge(PHP_INT_MAX); + exit('purging of expired pastes concluded' . PHP_EOL); + } + + if (option('s', 'statistics') !== null) { + $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 = $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 = $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; + } + } +} + +main(); \ No newline at end of file