The version of vichan running on lainchan.org
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

196 lignes
7.5KB

  1. <?php
  2. /*
  3. * Copyright (c) 2010-2014 Tinyboard Development Group
  4. */
  5. require_once 'inc/functions.php';
  6. if ($config['debug'])
  7. $parse_start_time = microtime(true);
  8. require_once 'inc/bans.php';
  9. require_once 'inc/mod/pages.php';
  10. check_login(true);
  11. $query = isset($_SERVER['QUERY_STRING']) ? rawurldecode($_SERVER['QUERY_STRING']) : '';
  12. $pages = array(
  13. '' => ':?/', // redirect to dashboard
  14. '/' => 'dashboard', // dashboard
  15. '/confirm/(.+)' => 'confirm', // confirm action (if javascript didn't work)
  16. '/logout' => 'secure logout', // logout
  17. '/users' => 'users', // manage users
  18. '/users/(\d+)/(promote|demote)' => 'secure user_promote', // prmote/demote user
  19. '/users/(\d+)' => 'secure_POST user', // edit user
  20. '/users/new' => 'secure_POST user_new', // create a new user
  21. '/new_PM/([^/]+)' => 'secure_POST new_pm', // create a new pm
  22. '/PM/(\d+)(/reply)?' => 'pm', // read a pm
  23. '/inbox' => 'inbox', // pm inbox
  24. '/log' => 'log', // modlog
  25. '/log/(\d+)' => 'log', // modlog
  26. '/log:([^/]+)' => 'user_log', // modlog
  27. '/log:([^/]+)/(\d+)' => 'user_log', // modlog
  28. '/news' => 'secure_POST news', // view news
  29. '/news/(\d+)' => 'secure_POST news', // view news
  30. '/news/delete/(\d+)' => 'secure news_delete', // delete from news
  31. '/noticeboard' => 'secure_POST noticeboard', // view noticeboard
  32. '/noticeboard/(\d+)' => 'secure_POST noticeboard', // view noticeboard
  33. '/noticeboard/delete/(\d+)' => 'secure noticeboard_delete', // delete from noticeboard
  34. '/edit/(\%b)' => 'secure_POST edit_board', // edit board details
  35. '/new-board' => 'secure_POST new_board', // create a new board
  36. '/rebuild' => 'secure_POST rebuild', // rebuild static files
  37. '/reports' => 'reports', // report queue
  38. '/reports/(\d+)/dismiss(all)?' => 'secure report_dismiss', // dismiss a report
  39. '/IP/([\w.:]+)' => 'secure_POST ip', // view ip address
  40. '/IP/([\w.:]+)/remove_note/(\d+)' => 'secure ip_remove_note', // remove note from ip address
  41. '/ban' => 'secure_POST ban', // new ban
  42. '/bans' => 'secure_POST bans', // ban list
  43. '/bans.json' => 'secure bans_json', // ban list JSON
  44. '/ban-appeals' => 'secure_POST ban_appeals', // view ban appeals
  45. '/recent/(\d+)' => 'recent_posts', // view recent posts
  46. '/search' => 'search_redirect', // search
  47. '/search/(posts|IP_notes|bans|log)/(.+)/(\d+)' => 'search', // search
  48. '/search/(posts|IP_notes|bans|log)/(.+)' => 'search', // search
  49. '/(\%b)/ban(&delete)?/(\d+)' => 'secure_POST ban_post', // ban poster
  50. '/(\%b)/move/(\d+)' => 'secure_POST move', // move thread
  51. '/(\%b)/move_reply/(\d+)' => 'secure_POST move_reply', // move reply
  52. '/(\%b)/edit(_raw)?/(\d+)' => 'secure_POST edit_post', // edit post
  53. '/(\%b)/delete/(\d+)' => 'secure delete', // delete post
  54. '/(\%b)/deletefile/(\d+)/(\d+)' => 'secure deletefile', // delete file from post
  55. '/(\%b+)/spoiler/(\d+)/(\d+)' => 'secure spoiler_image', // spoiler file
  56. '/(\%b)/deletebyip/(\d+)(/global)?' => 'secure deletebyip', // delete all posts by IP address
  57. '/(\%b)/(un)?lock/(\d+)' => 'secure lock', // lock thread
  58. '/(\%b)/(un)?sticky/(\d+)' => 'secure sticky', // sticky thread
  59. '/(\%b)/bump(un)?lock/(\d+)' => 'secure bumplock', // "bumplock" thread
  60. '/themes' => 'themes_list', // manage themes
  61. '/themes/(\w+)' => 'secure_POST theme_configure', // configure/reconfigure theme
  62. '/themes/(\w+)/rebuild' => 'secure theme_rebuild', // rebuild theme
  63. '/themes/(\w+)/uninstall' => 'secure theme_uninstall', // uninstall theme
  64. '/config' => 'secure_POST config', // config editor
  65. '/config/(\%b)' => 'secure_POST config', // config editor
  66. // these pages aren't listed in the dashboard without $config['debug']
  67. '/debug/antispam' => 'debug_antispam',
  68. '/debug/recent' => 'debug_recent_posts',
  69. '/debug/apc' => 'debug_apc',
  70. '/debug/sql' => 'secure_POST debug_sql',
  71. // This should always be at the end:
  72. '/(\%b)/' => 'view_board',
  73. '/(\%b)/' . preg_quote($config['file_index'], '!') => 'view_board',
  74. '/(\%b)/' . str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) => 'view_board',
  75. '/(\%b)/' . preg_quote($config['dir']['res'], '!') .
  76. str_replace('%d', '(\d+)', preg_quote($config['file_page50'], '!')) => 'view_thread50',
  77. '/(\%b)/' . preg_quote($config['dir']['res'], '!') .
  78. str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) => 'view_thread',
  79. '/(\%b)/' . preg_quote($config['dir']['res'], '!') .
  80. str_replace(array('%d','%s'), array('(\d+)', '[a-z0-9-]+'), preg_quote($config['file_page50_slug'], '!')) => 'view_thread50',
  81. '/(\%b)/' . preg_quote($config['dir']['res'], '!') .
  82. str_replace(array('%d','%s'), array('(\d+)', '[a-z0-9-]+'), preg_quote($config['file_page_slug'], '!')) => 'view_thread',
  83. );
  84. if (!$mod) {
  85. $pages = array('!^(.+)?$!' => 'login');
  86. } elseif (isset($_GET['status'], $_GET['r'])) {
  87. header('Location: ' . $_GET['r'], true, (int)$_GET['status']);
  88. exit;
  89. }
  90. if (isset($config['mod']['custom_pages'])) {
  91. $pages = array_merge($pages, $config['mod']['custom_pages']);
  92. }
  93. $new_pages = array();
  94. foreach ($pages as $key => $callback) {
  95. if (is_string($callback) && preg_match('/^secure /', $callback))
  96. $key .= '(/(?P<token>[a-f0-9]{8}))?';
  97. $key = str_replace('\%b', '?P<board>' . sprintf(substr($config['board_path'], 0, -1), $config['board_regex']), $key);
  98. $new_pages[@$key[0] == '!' ? $key : '!^' . $key . '(?:&[^&=]+=[^&]*)*$!u'] = $callback;
  99. }
  100. $pages = $new_pages;
  101. foreach ($pages as $uri => $handler) {
  102. if (preg_match($uri, $query, $matches)) {
  103. $matches = array_slice($matches, 1);
  104. if (isset($matches['board'])) {
  105. $board_match = $matches['board'];
  106. unset($matches['board']);
  107. $key = array_search($board_match, $matches);
  108. if (preg_match('/^' . sprintf(substr($config['board_path'], 0, -1), '(' . $config['board_regex'] . ')') . '$/u', $matches[$key], $board_match)) {
  109. $matches[$key] = $board_match[1];
  110. }
  111. }
  112. if (is_string($handler) && preg_match('/^secure(_POST)? /', $handler, $m)) {
  113. $secure_post_only = isset($m[1]);
  114. if (!$secure_post_only || $_SERVER['REQUEST_METHOD'] == 'POST') {
  115. $token = isset($matches['token']) ? $matches['token'] : (isset($_POST['token']) ? $_POST['token'] : false);
  116. if ($token === false) {
  117. if ($secure_post_only)
  118. error($config['error']['csrf']);
  119. else {
  120. mod_confirm(substr($query, 1));
  121. exit;
  122. }
  123. }
  124. // CSRF-protected page; validate security token
  125. $actual_query = preg_replace('!/([a-f0-9]{8})$!', '', $query);
  126. if ($token != make_secure_link_token(substr($actual_query, 1))) {
  127. error($config['error']['csrf']);
  128. }
  129. }
  130. $handler = preg_replace('/^secure(_POST)? /', '', $handler);
  131. }
  132. if ($config['debug']) {
  133. $debug['mod_page'] = array(
  134. 'req' => $query,
  135. 'match' => $uri,
  136. 'handler' => $handler,
  137. );
  138. $debug['time']['parse_mod_req'] = '~' . round((microtime(true) - $parse_start_time) * 1000, 2) . 'ms';
  139. }
  140. if (is_string($handler)) {
  141. if ($handler[0] == ':') {
  142. header('Location: ' . substr($handler, 1), true, $config['redirect_http']);
  143. } elseif (is_callable("mod_page_$handler")) {
  144. call_user_func_array("mod_page_$handler", $matches);
  145. } elseif (is_callable("mod_$handler")) {
  146. call_user_func_array("mod_$handler", $matches);
  147. } else {
  148. error("Mod page '$handler' not found!");
  149. }
  150. } elseif (is_callable($handler)) {
  151. call_user_func_array($handler, $matches);
  152. } else {
  153. error("Mod page '$handler' not a string, and not callable!");
  154. }
  155. exit;
  156. }
  157. }
  158. error($config['error']['404']);