api.php 7.7 KB

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