api.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. <?php
  2. function pingServer($hostname, $port) {
  3. $sock = socket_create(AF_INET, SOCK_STREAM, getprotobyname("tcp"));
  4. if (!$sock)
  5. return false;
  6. if (!@socket_connect($sock, $hostname, $port)) {
  7. error_log("Failed to connect to ${hostname}:${port}");
  8. return false;
  9. }
  10. socket_close($sock);
  11. return true;
  12. }
  13. if (isset($_GET["command"])) {
  14. switch ($_GET["command"]) {
  15. case "version":
  16. $fic = substr(file_get_contents("./.git/HEAD"), 5);
  17. if ($fic === FALSE) {
  18. header("HTTP/1.1 500 Server error");
  19. break;
  20. }
  21. $fic = file_get_contents("./.git/".trim($fic));
  22. if ($fic === FALSE) {
  23. header("HTTP/1.1 500 Server error");
  24. break;
  25. }
  26. echo json_encode(trim($fic));
  27. break;
  28. case "servers":
  29. require_once("./inc/servers.php");
  30. echo json_encode(getServers());
  31. break;
  32. case "channels":
  33. require_once("./inc/channels.php");
  34. echo json_encode(getChannels());
  35. break;
  36. case "ping":
  37. require_once("./.htconfig.php");
  38. require_once("inc/servers.php");
  39. if (!isset($_GET["key"]) || $_GET["key"] !== API_KEY) {
  40. $state = getServersState();
  41. if (!$state) {
  42. header("HTTP/1.0 500 Internal Server Error");
  43. die;
  44. }
  45. echo json_encode($state);
  46. die;
  47. }
  48. // Clean uploaded files
  49. $dirname = getcwd() ."/uploads/";
  50. $dir = opendir($dirname);
  51. $now = time();
  52. if ($dir !== FALSE) {
  53. $dbFile = getcwd()."/uploads/db.json";
  54. $fDbData = array();
  55. try {
  56. $fDbData = json_decode(@file_get_contents($dbFile), true);
  57. } catch(\Exception $e) {
  58. $fDbData = new StdClass();
  59. }
  60. $fDb = fopen($dbFile, "w");
  61. if (!$fDb)
  62. return;
  63. flock($fDb, LOCK_EX);
  64. while ($entry = readdir($dir)) {
  65. if (is_dir($dirname.$entry) || $entry === "db.json" || $entry === ".htaccess")
  66. continue;
  67. $stats = stat($dirname.$entry);
  68. if ($stats === FALSE) {
  69. error_log("Cannot stat uploaded file " .$dirname.$entry);
  70. continue;
  71. }
  72. if (($now -$stats["mtime"]) / 60 > 5)
  73. {
  74. $found = false;
  75. foreach ($fDbData as $i => $remote) {
  76. foreach ($remote as $j => $fileentry) {
  77. if ($fileentry["file"] === $dirname.$entry) {
  78. unset($fDbData[$i][$j]);
  79. if (count($fDbData[$i]) === 0)
  80. unset($fDbData[$i]);
  81. $found = true;
  82. break;
  83. }
  84. }
  85. if ($found) break;
  86. }
  87. unlink($dirname.$entry);
  88. }
  89. }
  90. fwrite($fDb, json_encode($fDbData));
  91. fclose($fDb);
  92. closedir($dir);
  93. } else {
  94. error_log("Cannot open upload dir for cleaning");
  95. }
  96. // Ping servers
  97. $result = [];
  98. foreach (getServers() as $i => $attrs) {
  99. $success = false;
  100. foreach ($attrs["ports"] as $port => $unused) {
  101. if (pingServer($i, $port)) {
  102. $success = true;
  103. break;
  104. }
  105. }
  106. $result[$i] = $success;
  107. }
  108. $result = array(
  109. "result" => $result,
  110. "date" => time()
  111. );
  112. writeServersState($result);
  113. break;
  114. case "gravatar":
  115. require_once(".htconfig.php");
  116. if (!isset($_GET["nick"])) {
  117. header("HTTP/1.0 400 Bad Request");
  118. die("Bad Request");
  119. }
  120. $dblink = getlink();
  121. $userRow = $dblink->prepare("SELECT `core`.`email` FROM `anope_NickCore` `core` INNER JOIN `anope_NickAlias` `alias` on `alias`.`nc`=`core`.`display` WHERE `alias`.`nick`=:nick AND `core`.`USE_GRAVATAR`=true LIMIT 1");
  122. $userRow->execute([
  123. "nick" => $_GET["nick"]
  124. ]);
  125. $res = $userRow->fetch(PDO::FETCH_ASSOC);
  126. header('Location: https://www.gravatar.com/avatar/' .md5($res === false ? $_GET["nick"] : $res["email"]) .'.png?d=retro');
  127. die();
  128. break;
  129. case "file":
  130. require_once(".htconfig.php");
  131. if (!isset($_GET["from"]) || strlen($_GET["from"]) == 0 || !isset($_FILES["file"])) {
  132. header("HTTP/1.0 400 Bad Request");
  133. die("Bad Request");
  134. }
  135. $extensionLocal = strrpos($_FILES["file"]["name"], '.');
  136. $extension = strtolower(substr($_FILES["file"]["name"], $extensionLocal === FALSE ? 0 : $extensionLocal));
  137. if (strpos($_FILES["file"]["type"], "image/") !== 0 || !in_array($extension, array(
  138. ".png", ".jpg", ".jpeg", ".ico"))) {
  139. header("HTTP/1.0 400 Bad Request");
  140. die("Unrecognized file type");
  141. }
  142. if ($_FILES["file"]["size"] > MAX_ALLOWED_UPLOAD_SIZE) {
  143. header("HTTP/1.0 400 Bad Request");
  144. die("File is too large (max " .MAX_ALLOWED_UPLOAD_SIZE ."o, got " .$_FILES["file"]["size"] .')');
  145. }
  146. $filename = md5($_GET["from"].time()) .$extension;
  147. // Flood protection
  148. if (file_exists($filename)) {
  149. header("HTTP/1.0 400 Bad Request");
  150. die("Please wait between uploads");
  151. }
  152. // Append file in files db
  153. $dbFile = getcwd()."/uploads/db.json";
  154. $fDbData = array();
  155. try {
  156. $fDbData = json_decode(@file_get_contents($dbFile), true);
  157. } catch(\Exception $e) {
  158. $fDbData = array();
  159. }
  160. $fDb = fopen($dbFile, "w");
  161. if (!$fDb)
  162. return;
  163. flock($fDb, LOCK_EX);
  164. if ($fDbData === NULL) $fDbData = array();
  165. if (isset($fDbData->{$_SERVER["REMOTE_ADDR"]})) {
  166. $cur = $fDbData->{$_SERVER["REMOTE_ADDR"]};
  167. while (count($fDbData->{$_SERVER["REMOTE_ADDR"]}) > 10) {
  168. $fileToRemove = array_shift($fDbData->{$_SERVER["REMOTE_ADDR"]});
  169. var_dump("unlink".$fileToRemove->{"file"});
  170. @unlink($fileToRemove->{"file"});
  171. }
  172. }
  173. // Actual write file
  174. if (move_uploaded_file($_FILES["file"]["tmp_name"], getcwd()."/uploads/".$filename) === FALSE) {
  175. fwrite($fDb, json_encode($fDbData));
  176. fclose($fDb);
  177. header("HTTP/1.0 500 Internal Server Error");
  178. die("Internal Server Error");
  179. }
  180. // Write to file db
  181. $fDbData[$_SERVER["REMOTE_ADDR"]] = isset($fDbData[$_SERVER["REMOTE_ADDR"]]) ? $fDbData[$_SERVER["REMOTE_ADDR"]] : array();
  182. $fDbData[$_SERVER["REMOTE_ADDR"]][] = array("file" => getcwd()."/uploads/".$filename, "time" => time(), "from" => $_GET["from"], "ip" => $_SERVER["REMOTE_ADDR"]);
  183. fwrite($fDb, json_encode($fDbData));
  184. fclose($fDb);
  185. // Log info
  186. error_log($_GET["from"] ." uploaded file " .$filename ." " .print_r($_FILES["file"], true) ." from " .$_SERVER["REMOTE_ADDR"]);
  187. echo "/uploads/" .$filename;
  188. break;
  189. }
  190. }
  191. ?>