Cjdns.php 3.6 KB

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