1
0

privatebin-admin 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #!/usr/bin/env php
  2. <?php
  3. define('PATH', dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR);
  4. require PATH . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
  5. use PrivateBin\Configuration;
  6. use PrivateBin\Model\Paste;
  7. $options = array();
  8. function error($message, $code = 1) {
  9. error_echo($message);
  10. exit($code);
  11. }
  12. function error_echo($message) {
  13. fwrite(STDERR, 'Error: ' . $message . PHP_EOL);
  14. }
  15. function help($code = 0) {
  16. echo <<<'EOT'
  17. Usage:
  18. privatebin-admin [--delete <paste id> | --empty-dirs | --help | --statistics]
  19. Options:
  20. -d, --delete deletes the requested paste ID
  21. -e, --empty-dirs removes empty directories (only if Filesystem storage is
  22. configured)
  23. -h, --help displays this help message
  24. -s, --statistics reads all stored pastes and comments and reports statistics
  25. EOT, PHP_EOL;
  26. exit($code);
  27. }
  28. function option($short, $long) {
  29. global $options;
  30. $option = null;
  31. foreach (array($short, $long) as $key) {
  32. if (array_key_exists($key, $options)) {
  33. $option = $options[$key];
  34. }
  35. }
  36. return $option;
  37. }
  38. function main() {
  39. if ($_SERVER['argc'] > 3) {
  40. error_echo('too many arguments given');
  41. fwrite(STDERR, PHP_EOL);
  42. help(1);
  43. }
  44. if ($_SERVER['argc'] < 2) {
  45. error_echo('missing arguments');
  46. fwrite(STDERR, PHP_EOL);
  47. help(2);
  48. }
  49. global $options;
  50. $options = getopt('hd:eps', array('help', 'delete:', 'empty-dirs', 'purge', 'statistics'));
  51. if (!$options) {
  52. error_echo('unsupported arguments given');
  53. fwrite(STDERR, PHP_EOL);
  54. help(3);
  55. }
  56. if (option('h', 'help') !== null) {
  57. help();
  58. }
  59. $conf = new Configuration;
  60. if (option('e', 'empty-dirs') !== null) {
  61. if ($conf->getKey('class', 'model') !== 'Filesystem') {
  62. error('instance not using Filesystem storage, no directories to empty', 4);
  63. }
  64. $dir = $conf->getKey('dir', 'model_options');
  65. passthru("find $dir -type d -empty -delete", $code);
  66. exit($code);
  67. }
  68. $class = 'PrivateBin\\Data\\' . $conf->getKey('class', 'model');
  69. $store = new $class($conf->getSection('model_options'));
  70. if (($pasteid = option('d', 'delete')) !== null) {
  71. if (!Paste::isValidId($pasteid)) {
  72. error('given ID is not a valid paste ID (16 hexadecimal digits)', 5);
  73. }
  74. if (!$store->exists($pasteid)) {
  75. error('given ID does not exist, has expired or was already deleted', 6);
  76. }
  77. $store->delete($pasteid);
  78. if ($store->exists($pasteid)) {
  79. error('paste ID exists after deletion, permission problem?', 7);
  80. }
  81. exit("paste $pasteid successfully deleted" . PHP_EOL);
  82. }
  83. if (option('p', 'purge') !== null) {
  84. $store->purge(PHP_INT_MAX);
  85. exit('purging of expired pastes concluded' . PHP_EOL);
  86. }
  87. if (option('s', 'statistics') !== null) {
  88. $counters = array(
  89. 'burn' => 0,
  90. 'discussion' => 0,
  91. 'expired' => 0,
  92. 'md' => 0,
  93. 'percent' => 1,
  94. 'plain' => 0,
  95. 'progress' => 0,
  96. 'syntax' => 0,
  97. 'total' => 0,
  98. 'unknown' => 0,
  99. );
  100. $time = time();
  101. $ids = $store->getAllPastes();
  102. $counters['total'] = count($ids);
  103. $dots = $counters['total'] < 100 ? 10 : (
  104. $counters['total'] < 1000 ? 50 : 100
  105. );
  106. $percentages = $counters['total'] < 100 ? 0 : (
  107. $counters['total'] < 1000 ? 4 : 10
  108. );
  109. echo "Total:\t\t\t${counters['total']}", PHP_EOL;
  110. foreach ($ids as $pasteid) {
  111. $paste = $store->read($pasteid);
  112. ++$counters['progress'];
  113. if (
  114. array_key_exists('expire_date', $paste['meta']) &&
  115. $paste['meta']['expire_date'] < $time
  116. ) {
  117. ++$counters['expired'];
  118. }
  119. if (array_key_exists('adata', $paste)) {
  120. $format = $paste['adata'][1];
  121. $discussion = $paste['adata'][2];
  122. $burn = $paste['adata'][3];
  123. } else {
  124. $format = array_key_exists('formatter', $paste['meta']) ? $paste['meta']['formatter'] : 'plaintext';
  125. $discussion = array_key_exists('opendiscussion', $paste['meta']) ? $paste['meta']['opendiscussion'] : false;
  126. $burn = array_key_exists('burnafterreading', $paste['meta']) ? $paste['meta']['burnafterreading'] : false;
  127. }
  128. if ($format === 'plaintext') {
  129. ++$counters['plain'];
  130. } elseif ($format === 'syntaxhighlighting') {
  131. ++$counters['syntax'];
  132. } elseif ($format === 'markdown') {
  133. ++$counters['md'];
  134. } else {
  135. ++$counters['unknown'];
  136. }
  137. $counters['discussion'] += (int) $discussion;
  138. $counters['burn'] += (int) $burn;
  139. // display progress
  140. if ($counters['progress'] % $dots === 0) {
  141. echo '.';
  142. if ($percentages) {
  143. $progress = $percentages / $counters['total'] * $counters['progress'];
  144. if ($progress >= $counters['percent']) {
  145. printf(' %d%% ', 100 / $percentages * $progress);
  146. ++$counters['percent'];
  147. }
  148. }
  149. }
  150. }
  151. echo PHP_EOL, <<<EOT
  152. Expired:\t\t${counters['expired']}
  153. Burn after reading:\t${counters['burn']}
  154. Discussions:\t\t${counters['discussion']}
  155. Plain Text:\t\t${counters['plain']}
  156. Source Code:\t\t${counters['syntax']}
  157. Markdown:\t\t${counters['md']}
  158. EOT, PHP_EOL;
  159. if ($counters['unknown'] > 0) {
  160. echo "Unknown format:\t\t${counters['unknown']}", PHP_EOL;
  161. }
  162. }
  163. }
  164. main();