Cjdns.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. <?php
  2. /**
  3. * PHP Cjdns Admin API
  4. */
  5. class Cjdns
  6. {
  7. public $buffersize = 69632;
  8. public $keepalive = 2;
  9. public $functions;
  10. private $socket;
  11. private $password;
  12. private $responses = array();
  13. public static function randStr()
  14. {
  15. $output = "";
  16. $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
  17. for($i = 0; $i < 10; $i++)
  18. $output .= $chars[rand(0, strlen($chars)-1)];
  19. return $output;
  20. }
  21. function receive($txid) {
  22. while (!isset($this->responses[$txid]))
  23. {
  24. $data = fread($this->socket, $this->buffersize);
  25. if($data != "")
  26. {
  27. try {
  28. $decoded = Bencode::decode($data, 'TYPE_ARRAY');
  29. }
  30. catch(Exception $e) {
  31. die("Failed to decode: $data\n");
  32. }
  33. }
  34. $this->responses[$decoded['txid']] = @$decoded;
  35. }
  36. $response = $this->responses[$txid];
  37. unset($this->response[$txid]);
  38. return $response;
  39. }
  40. public function send_raw($message)
  41. {
  42. $txid = $this->randStr();
  43. if (!isset($message['txid']))
  44. $message['txid'] = $txid;
  45. else
  46. $txid = $message['txid'];
  47. fwrite($this->socket, Bencode::encode($message));
  48. return $txid;
  49. }
  50. private function getCookie()
  51. {
  52. $data = $this->receive($this->send_raw(array("q" => "cookie")));
  53. return $data['cookie'];
  54. }
  55. public function call($function, $args)
  56. {
  57. $cookie = $this->getCookie();
  58. $txid = $this->randStr();
  59. if ($this->password != NULL)
  60. {
  61. $request = array("q" => "auth",
  62. "aq" => $function,
  63. "hash" => hash("sha256", $this->password.$cookie),
  64. "cookie" => $cookie,
  65. "args" => $args,
  66. "txid" => $txid
  67. );
  68. }
  69. else
  70. {
  71. $request = array("q" => $function,
  72. "args" => $args,
  73. "txid" => $txid
  74. );
  75. }
  76. $requestBencoded = Bencode::encode($request);
  77. $request['hash'] = hash("sha256", $requestBencoded);
  78. $this->send_raw($request);
  79. return $this->receive($txid);
  80. }
  81. function __construct($password=NULL, $host="127.0.0.1", $port=10010)
  82. {
  83. $this->socket = stream_socket_client("udp://".$host.":".$port, $errorno, $errorstr);
  84. if (!$this->socket)
  85. die("Failed to connect, Error #$errorno: $errorstr\n");
  86. fwrite($this->socket, Bencode::encode(array("q"=>"ping"))); // Try to ping it
  87. $returndata = fread($this->socket, $this->buffersize);
  88. if (empty($returndata)) die("Error: cjdroute does not working\n");
  89. if (!endsWith($returndata, "1:q4:ponge")) die("Can't ping: $returndata\n");
  90. $this->password = $password;
  91. $page = 0;
  92. while (true)
  93. {
  94. $request = array("q" => "Admin_availableFunctions",
  95. "args" => array("page" => $page));
  96. fwrite($this->socket, Bencode::encode($request));
  97. $result = Bencode::decode(fread($this->socket, $this->buffersize));
  98. foreach($result['availableFunctions'] as $function => $description)
  99. $this->functions[$function] = $description;
  100. if (isset($result['more'])) $page++;
  101. else break;
  102. }
  103. }
  104. function __destructor()
  105. {
  106. socket_close($this->socket);
  107. }
  108. }
  109. function endsWith($haystack, $needle)
  110. {
  111. return $needle === "" || strpos($haystack, $needle, strlen($haystack) - strlen($needle)) !== FALSE;
  112. }