Cjdns.php 3.4 KB

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