Merge pull request #1 from danog/analysis-zdjEEJ
Applied fixes from StyleCI
This commit is contained in:
commit
42e8d105d9
253
AES.class.php
253
AES.class.php
@ -18,7 +18,8 @@
|
|||||||
* Comments, Questions? Contact the author at cody [at] wshost [dot] net
|
* Comments, Questions? Contact the author at cody [at] wshost [dot] net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class AES {
|
class AES
|
||||||
|
{
|
||||||
// The number of 32-bit words comprising the plaintext and columns comrising the state matrix of an AES cipher.
|
// The number of 32-bit words comprising the plaintext and columns comrising the state matrix of an AES cipher.
|
||||||
private static $Nb = 4;
|
private static $Nb = 4;
|
||||||
// The number of 32-bit words comprising the cipher key in this AES cipher.
|
// The number of 32-bit words comprising the cipher key in this AES cipher.
|
||||||
@ -27,7 +28,7 @@ class AES {
|
|||||||
private $Nr;
|
private $Nr;
|
||||||
|
|
||||||
// The S-Box substitution table.
|
// The S-Box substitution table.
|
||||||
private static $sBox = array(
|
private static $sBox = [
|
||||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
|
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
|
||||||
0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
||||||
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
|
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
|
||||||
@ -59,11 +60,11 @@ class AES {
|
|||||||
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
|
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
|
||||||
0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
|
0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
|
||||||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
|
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
|
||||||
0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
|
0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16,
|
||||||
);
|
];
|
||||||
|
|
||||||
// The inverse S-Box substitution table.
|
// The inverse S-Box substitution table.
|
||||||
private static $invSBox = array(
|
private static $invSBox = [
|
||||||
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
|
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
|
||||||
0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
|
0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
|
||||||
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
|
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
|
||||||
@ -95,11 +96,11 @@ class AES {
|
|||||||
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
|
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
|
||||||
0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
|
0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
|
||||||
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
|
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
|
||||||
0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
|
0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d,
|
||||||
);
|
];
|
||||||
|
|
||||||
// Log table based on 0xe5
|
// Log table based on 0xe5
|
||||||
private static $ltable = array(
|
private static $ltable = [
|
||||||
0x00, 0xff, 0xc8, 0x08, 0x91, 0x10, 0xd0, 0x36,
|
0x00, 0xff, 0xc8, 0x08, 0x91, 0x10, 0xd0, 0x36,
|
||||||
0x5a, 0x3e, 0xd8, 0x43, 0x99, 0x77, 0xfe, 0x18,
|
0x5a, 0x3e, 0xd8, 0x43, 0x99, 0x77, 0xfe, 0x18,
|
||||||
0x23, 0x20, 0x07, 0x70, 0xa1, 0x6c, 0x0c, 0x7f,
|
0x23, 0x20, 0x07, 0x70, 0xa1, 0x6c, 0x0c, 0x7f,
|
||||||
@ -131,11 +132,11 @@ class AES {
|
|||||||
0x22, 0x88, 0x94, 0xce, 0x19, 0x01, 0x71, 0x4c,
|
0x22, 0x88, 0x94, 0xce, 0x19, 0x01, 0x71, 0x4c,
|
||||||
0xa5, 0xe3, 0xc5, 0x31, 0xbb, 0xcc, 0x1f, 0x2d,
|
0xa5, 0xe3, 0xc5, 0x31, 0xbb, 0xcc, 0x1f, 0x2d,
|
||||||
0x3b, 0x52, 0x6f, 0xf6, 0x2e, 0x89, 0xf7, 0xc0,
|
0x3b, 0x52, 0x6f, 0xf6, 0x2e, 0x89, 0xf7, 0xc0,
|
||||||
0x68, 0x1b, 0x64, 0x04, 0x06, 0xbf, 0x83, 0x38
|
0x68, 0x1b, 0x64, 0x04, 0x06, 0xbf, 0x83, 0x38,
|
||||||
);
|
];
|
||||||
|
|
||||||
// Inverse log table
|
// Inverse log table
|
||||||
private static $atable = array(
|
private static $atable = [
|
||||||
0x01, 0xe5, 0x4c, 0xb5, 0xfb, 0x9f, 0xfc, 0x12,
|
0x01, 0xe5, 0x4c, 0xb5, 0xfb, 0x9f, 0xfc, 0x12,
|
||||||
0x03, 0x34, 0xd4, 0xc4, 0x16, 0xba, 0x1f, 0x36,
|
0x03, 0x34, 0xd4, 0xc4, 0x16, 0xba, 0x1f, 0x36,
|
||||||
0x05, 0x5c, 0x67, 0x57, 0x3a, 0xd5, 0x21, 0x5a,
|
0x05, 0x5c, 0x67, 0x57, 0x3a, 0xd5, 0x21, 0x5a,
|
||||||
@ -167,8 +168,8 @@ class AES {
|
|||||||
0x1e, 0xd3, 0x49, 0xe9, 0x9c, 0xc8, 0xc6, 0xc7,
|
0x1e, 0xd3, 0x49, 0xe9, 0x9c, 0xc8, 0xc6, 0xc7,
|
||||||
0x22, 0x6e, 0xdb, 0x20, 0xbf, 0x43, 0x51, 0x52,
|
0x22, 0x6e, 0xdb, 0x20, 0xbf, 0x43, 0x51, 0x52,
|
||||||
0x66, 0xb2, 0x76, 0x60, 0xda, 0xc5, 0xf3, 0xf6,
|
0x66, 0xb2, 0x76, 0x60, 0xda, 0xc5, 0xf3, 0xf6,
|
||||||
0xaa, 0xcd, 0x9a, 0xa0, 0x75, 0x54, 0x0e, 0x01
|
0xaa, 0xcd, 0x9a, 0xa0, 0x75, 0x54, 0x0e, 0x01,
|
||||||
);
|
];
|
||||||
|
|
||||||
// The key schedule in this AES cipher.
|
// The key schedule in this AES cipher.
|
||||||
private $w;
|
private $w;
|
||||||
@ -180,16 +181,18 @@ class AES {
|
|||||||
|
|
||||||
/** constructs an AES cipher using a specific key.
|
/** constructs an AES cipher using a specific key.
|
||||||
*/
|
*/
|
||||||
public function __construct($z) {
|
public function __construct($z)
|
||||||
$this->Nk = strlen($z)/4;
|
{
|
||||||
|
$this->Nk = strlen($z) / 4;
|
||||||
$this->Nr = $this->Nk + self::$Nb + 2;
|
$this->Nr = $this->Nk + self::$Nb + 2;
|
||||||
|
|
||||||
if ($this->Nk != 4 && $this->Nk != 6 && $this->Nk != 8)
|
if ($this->Nk != 4 && $this->Nk != 6 && $this->Nk != 8) {
|
||||||
die("Key is " . ($this->Nk*32) . " bits long. *not* 128, 192, or 256.");
|
die('Key is '.($this->Nk * 32).' bits long. *not* 128, 192, or 256.');
|
||||||
|
}
|
||||||
|
|
||||||
$this->Nr = $this->Nk+self::$Nb+2;
|
$this->Nr = $this->Nk + self::$Nb + 2;
|
||||||
$this->w = array(); // Nb*(Nr+1) 32-bit words
|
$this->w = []; // Nb*(Nr+1) 32-bit words
|
||||||
$this->s = array(array()); // 2-D array of Nb colums and 4 rows
|
$this->s = [[]]; // 2-D array of Nb colums and 4 rows
|
||||||
|
|
||||||
$this->KeyExpansion($z); // places expanded key in w
|
$this->KeyExpansion($z); // places expanded key in w
|
||||||
}
|
}
|
||||||
@ -201,23 +204,25 @@ class AES {
|
|||||||
* encryptBlock() function directly, as the amount of time required
|
* encryptBlock() function directly, as the amount of time required
|
||||||
* to encrypt is linear to the size of the ciphertext.
|
* to encrypt is linear to the size of the ciphertext.
|
||||||
**/
|
**/
|
||||||
public function encrypt($x) {
|
public function encrypt($x)
|
||||||
$t = ""; // 16-byte block
|
{
|
||||||
$y = ""; // returned cipher text;
|
$t = ''; // 16-byte block
|
||||||
|
$y = ''; // returned cipher text;
|
||||||
|
|
||||||
// put a 16-byte block into t
|
// put a 16-byte block into t
|
||||||
$xsize = strlen($x);
|
$xsize = strlen($x);
|
||||||
for ($i=0; $i<$xsize; $i+=16) {
|
for ($i = 0; $i < $xsize; $i += 16) {
|
||||||
for ($j=0; $j<16; $j++) {
|
for ($j = 0; $j < 16; $j++) {
|
||||||
if (($i+$j)<$xsize) {
|
if (($i + $j) < $xsize) {
|
||||||
$t[$j] = $x[$i+$j];
|
$t[$j] = $x[$i + $j];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
$t[$j] = chr(0);
|
$t[$j] = chr(0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$y .= $this->encryptBlock($t);
|
$y .= $this->encryptBlock($t);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $y;
|
return $y;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,21 +233,24 @@ class AES {
|
|||||||
* decryptBlock() function directly, as the amount of time required
|
* decryptBlock() function directly, as the amount of time required
|
||||||
* to decrypt is linear to the size of the ciphertext.
|
* to decrypt is linear to the size of the ciphertext.
|
||||||
**/
|
**/
|
||||||
public function decrypt($y) {
|
public function decrypt($y)
|
||||||
$t = ""; // 16-byte block
|
{
|
||||||
$x = ""; // returned plain text;
|
$t = ''; // 16-byte block
|
||||||
|
$x = ''; // returned plain text;
|
||||||
|
|
||||||
// put a 16-byte block into t
|
// put a 16-byte block into t
|
||||||
$ysize = strlen($y);
|
$ysize = strlen($y);
|
||||||
for ($i=0; $i<$ysize; $i+=16) {
|
for ($i = 0; $i < $ysize; $i += 16) {
|
||||||
for ($j=0; $j<16; $j++) {
|
for ($j = 0; $j < 16; $j++) {
|
||||||
if (($i+$j)<$ysize)
|
if (($i + $j) < $ysize) {
|
||||||
$t[$j] = $y[$i+$j];
|
$t[$j] = $y[$i + $j];
|
||||||
else
|
} else {
|
||||||
$t[$j] = chr(0);
|
$t[$j] = chr(0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
$x .= $this->decryptBlock($t);
|
$x .= $this->decryptBlock($t);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $x;
|
return $x;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,19 +258,20 @@ class AES {
|
|||||||
* @params 16-byte plaintext string
|
* @params 16-byte plaintext string
|
||||||
* @returns 16-byte ciphertext string
|
* @returns 16-byte ciphertext string
|
||||||
**/
|
**/
|
||||||
public function encryptBlock($x) {
|
public function encryptBlock($x)
|
||||||
$y = ""; // 16-byte string
|
{
|
||||||
|
$y = ''; // 16-byte string
|
||||||
|
|
||||||
// place input x into the initial state matrix in column order
|
// place input x into the initial state matrix in column order
|
||||||
for ($i=0; $i<4*self::$Nb; $i++) {
|
for ($i = 0; $i < 4 * self::$Nb; $i++) {
|
||||||
// we want integerger division for the second index
|
// we want integerger division for the second index
|
||||||
$this->s[$i%4][($i-$i%self::$Nb)/self::$Nb] = ord($x[$i]);
|
$this->s[$i % 4][($i - $i % self::$Nb) / self::$Nb] = ord($x[$i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add round key
|
// add round key
|
||||||
$this->addRoundKey(0);
|
$this->addRoundKey(0);
|
||||||
|
|
||||||
for ($i=1; $i<$this->Nr; $i++) {
|
for ($i = 1; $i < $this->Nr; $i++) {
|
||||||
// substitute bytes
|
// substitute bytes
|
||||||
$this->subBytes();
|
$this->subBytes();
|
||||||
|
|
||||||
@ -286,8 +295,10 @@ class AES {
|
|||||||
$this->addRoundKey($i);
|
$this->addRoundKey($i);
|
||||||
|
|
||||||
// place state matrix s into y in column order
|
// place state matrix s into y in column order
|
||||||
for ($i=0; $i<4*self::$Nb; $i++)
|
for ($i = 0; $i < 4 * self::$Nb; $i++) {
|
||||||
$y .= chr($this->s[$i%4][($i-$i%self::$Nb)/self::$Nb]);
|
$y .= chr($this->s[$i % 4][($i - $i % self::$Nb) / self::$Nb]);
|
||||||
|
}
|
||||||
|
|
||||||
return $y;
|
return $y;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,17 +306,19 @@ class AES {
|
|||||||
* @params 16-byte ciphertext string
|
* @params 16-byte ciphertext string
|
||||||
* @returns 16-byte plaintext string
|
* @returns 16-byte plaintext string
|
||||||
**/
|
**/
|
||||||
public function decryptBlock($y) {
|
public function decryptBlock($y)
|
||||||
$x = ""; // 16-byte string
|
{
|
||||||
|
$x = ''; // 16-byte string
|
||||||
|
|
||||||
// place input y into the initial state matrix in column order
|
// place input y into the initial state matrix in column order
|
||||||
for ($i=0; $i<4*self::$Nb; $i++)
|
for ($i = 0; $i < 4 * self::$Nb; $i++) {
|
||||||
$this->s[$i%4][($i-$i%self::$Nb)/self::$Nb] = ord($y[$i]);
|
$this->s[$i % 4][($i - $i % self::$Nb) / self::$Nb] = ord($y[$i]);
|
||||||
|
}
|
||||||
|
|
||||||
// add round key
|
// add round key
|
||||||
$this->addRoundKey($this->Nr);
|
$this->addRoundKey($this->Nr);
|
||||||
|
|
||||||
for ($i=$this->Nr-1; $i>0; $i--) {
|
for ($i = $this->Nr - 1; $i > 0; $i--) {
|
||||||
// inverse shift rows
|
// inverse shift rows
|
||||||
$this->invShiftRows();
|
$this->invShiftRows();
|
||||||
|
|
||||||
@ -329,15 +342,16 @@ class AES {
|
|||||||
$this->addRoundKey($i);
|
$this->addRoundKey($i);
|
||||||
|
|
||||||
// place state matrix s into x in column order
|
// place state matrix s into x in column order
|
||||||
for ($i=0; $i<4*self::$Nb; $i++) {
|
for ($i = 0; $i < 4 * self::$Nb; $i++) {
|
||||||
// Used to remove filled null characters.
|
// Used to remove filled null characters.
|
||||||
$x .= ($this->s[$i%4][($i-$i%self::$Nb)/self::$Nb] == chr(0) ? "" : chr($this->s[$i%4][($i-$i%self::$Nb)/self::$Nb]));
|
$x .= ($this->s[$i % 4][($i - $i % self::$Nb) / self::$Nb] == chr(0) ? '' : chr($this->s[$i % 4][($i - $i % self::$Nb) / self::$Nb]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $x;
|
return $x;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __destruct() {
|
public function __destruct()
|
||||||
|
{
|
||||||
unset($this->w);
|
unset($this->w);
|
||||||
unset($this->s);
|
unset($this->s);
|
||||||
}
|
}
|
||||||
@ -345,9 +359,10 @@ class AES {
|
|||||||
/** makes a big key out of a small one
|
/** makes a big key out of a small one
|
||||||
* @returns void
|
* @returns void
|
||||||
**/
|
**/
|
||||||
private function KeyExpansion($z) {
|
private function KeyExpansion($z)
|
||||||
|
{
|
||||||
// Rcon is the round constant
|
// Rcon is the round constant
|
||||||
static $Rcon = array(
|
static $Rcon = [
|
||||||
0x00000000,
|
0x00000000,
|
||||||
0x01000000,
|
0x01000000,
|
||||||
0x02000000,
|
0x02000000,
|
||||||
@ -364,35 +379,36 @@ class AES {
|
|||||||
0xab000000,
|
0xab000000,
|
||||||
0x4d000000,
|
0x4d000000,
|
||||||
0x9a000000,
|
0x9a000000,
|
||||||
0x2f000000
|
0x2f000000,
|
||||||
);
|
];
|
||||||
|
|
||||||
$temp = 0; // temporary 32-bit word
|
$temp = 0; // temporary 32-bit word
|
||||||
|
|
||||||
// the first Nk words of w are the cipher key z
|
// the first Nk words of w are the cipher key z
|
||||||
for ($i=0; $i<$this->Nk; $i++) {
|
for ($i = 0; $i < $this->Nk; $i++) {
|
||||||
$this->w[$i] = 0;
|
$this->w[$i] = 0;
|
||||||
// fill an entire word of expanded key w
|
// fill an entire word of expanded key w
|
||||||
// by pushing 4 bytes into the w[i] word
|
// by pushing 4 bytes into the w[i] word
|
||||||
$this->w[$i] = ord($z[4*$i]); // add a byte in
|
$this->w[$i] = ord($z[4 * $i]); // add a byte in
|
||||||
$this->w[$i] <<= 8; // make room for the next byte
|
$this->w[$i] <<= 8; // make room for the next byte
|
||||||
$this->w[$i] += ord($z[4*$i+1]);
|
$this->w[$i] += ord($z[4 * $i + 1]);
|
||||||
$this->w[$i] <<= 8;
|
$this->w[$i] <<= 8;
|
||||||
$this->w[$i] += ord($z[4*$i+2]);
|
$this->w[$i] += ord($z[4 * $i + 2]);
|
||||||
$this->w[$i] <<= 8;
|
$this->w[$i] <<= 8;
|
||||||
$this->w[$i] += ord($z[4*$i+3]);
|
$this->w[$i] += ord($z[4 * $i + 3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (; $i<self::$Nb*($this->Nr+1); $i++) {
|
for (; $i < self::$Nb * ($this->Nr + 1); $i++) {
|
||||||
$temp = $this->w[$i-1];
|
$temp = $this->w[$i - 1];
|
||||||
|
|
||||||
if ($i%$this->Nk == 0)
|
if ($i % $this->Nk == 0) {
|
||||||
$temp = $this->subWord($this->rotWord($temp)) ^ $Rcon[$i/$this->Nk];
|
$temp = $this->subWord($this->rotWord($temp)) ^ $Rcon[$i / $this->Nk];
|
||||||
else if ($this->Nk > 6 && $i%$this->Nk == 4)
|
} elseif ($this->Nk > 6 && $i % $this->Nk == 4) {
|
||||||
$temp = $this->subWord($temp);
|
$temp = $this->subWord($temp);
|
||||||
|
}
|
||||||
|
|
||||||
$this->w[$i] = $this->w[$i-$this->Nk] ^ $temp;
|
$this->w[$i] = $this->w[$i - $this->Nk] ^ $temp;
|
||||||
|
|
||||||
self::make32BitWord($this->w[$i]);
|
self::make32BitWord($this->w[$i]);
|
||||||
}
|
}
|
||||||
@ -401,13 +417,14 @@ class AES {
|
|||||||
/** adds the key schedule for a round to a state matrix.
|
/** adds the key schedule for a round to a state matrix.
|
||||||
* @returns void
|
* @returns void
|
||||||
**/
|
**/
|
||||||
private function addRoundKey($round) {
|
private function addRoundKey($round)
|
||||||
$temp = "";
|
{
|
||||||
|
$temp = '';
|
||||||
|
|
||||||
for ($i=0; $i<4; $i++) {
|
for ($i = 0; $i < 4; $i++) {
|
||||||
for ($j=0; $j<self::$Nb; $j++) {
|
for ($j = 0; $j < self::$Nb; $j++) {
|
||||||
// place the i-th byte of the j-th word from expanded key w into temp
|
// place the i-th byte of the j-th word from expanded key w into temp
|
||||||
$temp = $this->w[$round*self::$Nb+$j] >> (3-$i)*8;
|
$temp = $this->w[$round * self::$Nb + $j] >> (3 - $i) * 8;
|
||||||
// Cast temp from a 32-bit word into an 8-bit byte.
|
// Cast temp from a 32-bit word into an 8-bit byte.
|
||||||
$temp %= 256;
|
$temp %= 256;
|
||||||
// Can't do unsigned shifts, so we need to make this temp positive
|
// Can't do unsigned shifts, so we need to make this temp positive
|
||||||
@ -421,52 +438,65 @@ class AES {
|
|||||||
/** unmixes each column of a state matrix.
|
/** unmixes each column of a state matrix.
|
||||||
* @returns void
|
* @returns void
|
||||||
**/
|
**/
|
||||||
private function invMixColumns() {
|
private function invMixColumns()
|
||||||
$s0 = $s1 = $s2 = $s3= '';
|
{
|
||||||
|
$s0 = $s1 = $s2 = $s3 = '';
|
||||||
|
|
||||||
// There are Nb columns
|
// There are Nb columns
|
||||||
for ($i=0; $i<self::$Nb; $i++) {
|
for ($i = 0; $i < self::$Nb; $i++) {
|
||||||
$s0 = $this->s[0][$i]; $s1 = $this->s[1][$i]; $s2 = $this->s[2][$i]; $s3 = $this->s[3][$i];
|
$s0 = $this->s[0][$i];
|
||||||
|
$s1 = $this->s[1][$i];
|
||||||
|
$s2 = $this->s[2][$i];
|
||||||
|
$s3 = $this->s[3][$i];
|
||||||
|
|
||||||
$this->s[0][$i] = $this->mult(0x0e, $s0) ^ $this->mult(0x0b, $s1) ^ $this->mult(0x0d, $s2) ^ $this->mult(0x09, $s3);
|
$this->s[0][$i] = $this->mult(0x0e, $s0) ^ $this->mult(0x0b, $s1) ^ $this->mult(0x0d, $s2) ^ $this->mult(0x09, $s3);
|
||||||
$this->s[1][$i] = $this->mult(0x09, $s0) ^ $this->mult(0x0e, $s1) ^ $this->mult(0x0b, $s2) ^ $this->mult(0x0d, $s3);
|
$this->s[1][$i] = $this->mult(0x09, $s0) ^ $this->mult(0x0e, $s1) ^ $this->mult(0x0b, $s2) ^ $this->mult(0x0d, $s3);
|
||||||
$this->s[2][$i] = $this->mult(0x0d, $s0) ^ $this->mult(0x09, $s1) ^ $this->mult(0x0e, $s2) ^ $this->mult(0x0b, $s3);
|
$this->s[2][$i] = $this->mult(0x0d, $s0) ^ $this->mult(0x09, $s1) ^ $this->mult(0x0e, $s2) ^ $this->mult(0x0b, $s3);
|
||||||
$this->s[3][$i] = $this->mult(0x0b, $s0) ^ $this->mult(0x0d, $s1) ^ $this->mult(0x09, $s2) ^ $this->mult(0x0e, $s3);
|
$this->s[3][$i] = $this->mult(0x0b, $s0) ^ $this->mult(0x0d, $s1) ^ $this->mult(0x09, $s2) ^ $this->mult(0x0e, $s3);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** applies an inverse cyclic shift to the last 3 rows of a state matrix.
|
/** applies an inverse cyclic shift to the last 3 rows of a state matrix.
|
||||||
* @returns void
|
* @returns void
|
||||||
**/
|
**/
|
||||||
private function invShiftRows() {
|
private function invShiftRows()
|
||||||
$temp = "";
|
{
|
||||||
for ($i=1; $i<4; $i++) {
|
$temp = '';
|
||||||
for ($j=0; $j<self::$Nb; $j++)
|
for ($i = 1; $i < 4; $i++) {
|
||||||
$temp[($i+$j)%self::$Nb] = $this->s[$i][$j];
|
for ($j = 0; $j < self::$Nb; $j++) {
|
||||||
for ($j=0; $j<self::$Nb; $j++)
|
$temp[($i + $j) % self::$Nb] = $this->s[$i][$j];
|
||||||
|
}
|
||||||
|
for ($j = 0; $j < self::$Nb; $j++) {
|
||||||
$this->s[$i][$j] = $temp[$j];
|
$this->s[$i][$j] = $temp[$j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** applies inverse S-Box substitution to each byte of a state matrix.
|
/** applies inverse S-Box substitution to each byte of a state matrix.
|
||||||
* @returns void
|
* @returns void
|
||||||
**/
|
**/
|
||||||
private function invSubBytes() {
|
private function invSubBytes()
|
||||||
for ($i=0; $i<4; $i++)
|
{
|
||||||
for ($j=0; $j<self::$Nb; $j++)
|
for ($i = 0; $i < 4; $i++) {
|
||||||
|
for ($j = 0; $j < self::$Nb; $j++) {
|
||||||
$this->s[$i][$j] = self::$invSBox[$this->s[$i][$j]];
|
$this->s[$i][$j] = self::$invSBox[$this->s[$i][$j]];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** mixes each column of a state matrix.
|
/** mixes each column of a state matrix.
|
||||||
* @returns void
|
* @returns void
|
||||||
**/
|
**/
|
||||||
private function mixColumns() {
|
private function mixColumns()
|
||||||
$s0 = $s1 = $s2 = $s3= '';
|
{
|
||||||
|
$s0 = $s1 = $s2 = $s3 = '';
|
||||||
|
|
||||||
// There are Nb columns
|
// There are Nb columns
|
||||||
for ($i=0; $i<self::$Nb; $i++) {
|
for ($i = 0; $i < self::$Nb; $i++) {
|
||||||
$s0 = $this->s[0][$i]; $s1 = $this->s[1][$i]; $s2 = $this->s[2][$i]; $s3 = $this->s[3][$i];
|
$s0 = $this->s[0][$i];
|
||||||
|
$s1 = $this->s[1][$i];
|
||||||
|
$s2 = $this->s[2][$i];
|
||||||
|
$s3 = $this->s[3][$i];
|
||||||
|
|
||||||
$this->s[0][$i] = $this->mult(0x02, $s0) ^ $this->mult(0x03, $s1) ^ $this->mult(0x01, $s2) ^ $this->mult(0x01, $s3);
|
$this->s[0][$i] = $this->mult(0x02, $s0) ^ $this->mult(0x03, $s1) ^ $this->mult(0x01, $s2) ^ $this->mult(0x01, $s3);
|
||||||
$this->s[1][$i] = $this->mult(0x01, $s0) ^ $this->mult(0x02, $s1) ^ $this->mult(0x03, $s2) ^ $this->mult(0x01, $s3);
|
$this->s[1][$i] = $this->mult(0x01, $s0) ^ $this->mult(0x02, $s1) ^ $this->mult(0x03, $s2) ^ $this->mult(0x01, $s3);
|
||||||
@ -478,41 +508,49 @@ class AES {
|
|||||||
/** applies a cyclic shift to the last 3 rows of a state matrix.
|
/** applies a cyclic shift to the last 3 rows of a state matrix.
|
||||||
* @returns void
|
* @returns void
|
||||||
**/
|
**/
|
||||||
private function shiftRows() {
|
private function shiftRows()
|
||||||
$temp = "";
|
{
|
||||||
for ($i=1; $i<4; $i++) {
|
$temp = '';
|
||||||
for ($j=0; $j<self::$Nb; $j++)
|
for ($i = 1; $i < 4; $i++) {
|
||||||
$temp[$j] = $this->s[$i][($j+$i)%self::$Nb];
|
for ($j = 0; $j < self::$Nb; $j++) {
|
||||||
for ($j=0; $j<self::$Nb; $j++)
|
$temp[$j] = $this->s[$i][($j + $i) % self::$Nb];
|
||||||
|
}
|
||||||
|
for ($j = 0; $j < self::$Nb; $j++) {
|
||||||
$this->s[$i][$j] = $temp[$j];
|
$this->s[$i][$j] = $temp[$j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** applies S-Box substitution to each byte of a state matrix.
|
/** applies S-Box substitution to each byte of a state matrix.
|
||||||
* @returns void
|
* @returns void
|
||||||
**/
|
**/
|
||||||
private function subBytes() {
|
private function subBytes()
|
||||||
|
{
|
||||||
for ($i=0; $i<4; $i++) {
|
for ($i = 0; $i < 4; $i++) {
|
||||||
for ($j=0; $j<self::$Nb; $j++)
|
for ($j = 0; $j < self::$Nb; $j++) {
|
||||||
$this->s[$i][$j] = self::$sBox[$this->s[$i][$j]];
|
$this->s[$i][$j] = self::$sBox[$this->s[$i][$j]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** multiplies two polynomials a(x), b(x) in GF(2^8) modulo the irreducible polynomial m(x) = x^8+x^4+x^3+x+1
|
/** multiplies two polynomials a(x), b(x) in GF(2^8) modulo the irreducible polynomial m(x) = x^8+x^4+x^3+x+1
|
||||||
* @returns 8-bit value
|
* @returns 8-bit value
|
||||||
**/
|
**/
|
||||||
private static function mult($a, $b) {
|
private static function mult($a, $b)
|
||||||
|
{
|
||||||
$sum = self::$ltable[$a] + self::$ltable[$b];
|
$sum = self::$ltable[$a] + self::$ltable[$b];
|
||||||
$sum %= 255;
|
$sum %= 255;
|
||||||
// Get the antilog
|
// Get the antilog
|
||||||
$sum = self::$atable[$sum];
|
$sum = self::$atable[$sum];
|
||||||
return ($a == 0 ? 0 : ($b == 0 ? 0 : $sum));
|
|
||||||
|
return $a == 0 ? 0 : ($b == 0 ? 0 : $sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** applies a cyclic permutation to a 4-byte word.
|
/** applies a cyclic permutation to a 4-byte word.
|
||||||
* @returns 32-bit int
|
* @returns 32-bit int
|
||||||
**/
|
**/
|
||||||
private static function rotWord($w) {
|
private static function rotWord($w)
|
||||||
|
{
|
||||||
$temp = $w >> 24; // put the first 8-bits into temp
|
$temp = $w >> 24; // put the first 8-bits into temp
|
||||||
$w <<= 8; // make room for temp to fill the lower end of the word
|
$w <<= 8; // make room for temp to fill the lower end of the word
|
||||||
self::make32BitWord($w);
|
self::make32BitWord($w);
|
||||||
@ -526,10 +564,11 @@ class AES {
|
|||||||
/** applies S-box substitution to each byte of a 4-byte word.
|
/** applies S-box substitution to each byte of a 4-byte word.
|
||||||
* @returns 32-bit int
|
* @returns 32-bit int
|
||||||
**/
|
**/
|
||||||
private static function subWord($w) {
|
private static function subWord($w)
|
||||||
|
{
|
||||||
$temp = 0;
|
$temp = 0;
|
||||||
// loop through 4 bytes of a word
|
// loop through 4 bytes of a word
|
||||||
for ($i=0; $i<4; $i++) {
|
for ($i = 0; $i < 4; $i++) {
|
||||||
$temp = $w >> 24; // put the first 8-bits into temp
|
$temp = $w >> 24; // put the first 8-bits into temp
|
||||||
// Can't do unsigned shifts, so we need to make this temp positive
|
// Can't do unsigned shifts, so we need to make this temp positive
|
||||||
$temp = ($temp < 0 ? (256 + $temp) : $temp);
|
$temp = ($temp < 0 ? (256 + $temp) : $temp);
|
||||||
@ -546,9 +585,9 @@ class AES {
|
|||||||
/** reduces a 64-bit word to a 32-bit word
|
/** reduces a 64-bit word to a 32-bit word
|
||||||
* @returns void
|
* @returns void
|
||||||
**/
|
**/
|
||||||
private static function make32BitWord(&$w) {
|
private static function make32BitWord(&$w)
|
||||||
|
{
|
||||||
// Reduce this 64-bit word to 32-bits on 64-bit machines
|
// Reduce this 64-bit word to 32-bits on 64-bit machines
|
||||||
$w &= 0x00000000FFFFFFFF;
|
$w &= 0x00000000FFFFFFFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
|
108
TL.php
108
TL.php
@ -1,11 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libpy2php');
|
|
||||||
require_once ('libpy2php.php');
|
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
|
||||||
|
require_once 'libpy2php.php';
|
||||||
$__author__ = 'agrigoryev';
|
$__author__ = 'agrigoryev';
|
||||||
require_once ('os.php');
|
require_once 'os.php';
|
||||||
class TlConstructor {
|
class TlConstructor
|
||||||
function __construct($json_dict) {
|
{
|
||||||
$this->id = (int)$json_dict['id'];
|
public function __construct($json_dict)
|
||||||
|
{
|
||||||
|
$this->id = (int) $json_dict['id'];
|
||||||
$this->type = $json_dict['type'];
|
$this->type = $json_dict['type'];
|
||||||
$this->predicate = $json_dict['predicate'];
|
$this->predicate = $json_dict['predicate'];
|
||||||
$this->params = [];
|
$this->params = [];
|
||||||
@ -13,10 +16,10 @@ class TlConstructor {
|
|||||||
if (($param['type'] == 'Vector<long>')) {
|
if (($param['type'] == 'Vector<long>')) {
|
||||||
$param['type'] = 'Vector t';
|
$param['type'] = 'Vector t';
|
||||||
$param['subtype'] = 'long';
|
$param['subtype'] = 'long';
|
||||||
} else if (($param['type'] == 'vector<%Message>')) {
|
} elseif (($param['type'] == 'vector<%Message>')) {
|
||||||
$param['type'] = 'vector';
|
$param['type'] = 'vector';
|
||||||
$param['subtype'] = 'message';
|
$param['subtype'] = 'message';
|
||||||
} else if (($param['type'] == 'vector<future_salt>')) {
|
} elseif (($param['type'] == 'vector<future_salt>')) {
|
||||||
$param['type'] = 'vector';
|
$param['type'] = 'vector';
|
||||||
$param['subtype'] = 'future_salt';
|
$param['subtype'] = 'future_salt';
|
||||||
} else {
|
} else {
|
||||||
@ -26,22 +29,28 @@ class TlConstructor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class TlMethod {
|
class TlMethod
|
||||||
function __construct($json_dict) {
|
{
|
||||||
$this->id = (int)$json_dict['id'];
|
public function __construct($json_dict)
|
||||||
|
{
|
||||||
|
$this->id = (int) $json_dict['id'];
|
||||||
$this->type = $json_dict['type'];
|
$this->type = $json_dict['type'];
|
||||||
$this->method = $json_dict['method'];
|
$this->method = $json_dict['method'];
|
||||||
$this->params = $json_dict['params'];
|
$this->params = $json_dict['params'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class TLObject extends ArrayObject {
|
class TLObject extends ArrayObject
|
||||||
function __construct($tl_elem) {
|
{
|
||||||
|
public function __construct($tl_elem)
|
||||||
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->name = $tl_elem->predicate;
|
$this->name = $tl_elem->predicate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class TL {
|
class TL
|
||||||
function __construct($filename) {
|
{
|
||||||
|
public function __construct($filename)
|
||||||
|
{
|
||||||
$TL_dict = json_decode(file_get_contents($filename), true);
|
$TL_dict = json_decode(file_get_contents($filename), true);
|
||||||
$this->constructors = $TL_dict['constructors'];
|
$this->constructors = $TL_dict['constructors'];
|
||||||
$this->constructor_id = [];
|
$this->constructor_id = [];
|
||||||
@ -61,83 +70,89 @@ class TL {
|
|||||||
}
|
}
|
||||||
$this->struct = new \danog\PHP\Struct();
|
$this->struct = new \danog\PHP\Struct();
|
||||||
}
|
}
|
||||||
function serialize_obj($type_, $kwargs) {
|
|
||||||
$bytes_io = fopen("php://memory", "rw+b");
|
public function serialize_obj($type_, $kwargs)
|
||||||
if(isset($this->constructor_type[$type_])) {
|
|
||||||
$tl_constructor = $this->constructor_type[$type_];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
$bytes_io = fopen('php://memory', 'rw+b');
|
||||||
|
if (isset($this->constructor_type[$type_])) {
|
||||||
|
$tl_constructor = $this->constructor_type[$type_];
|
||||||
|
} else {
|
||||||
throw new Exception(sprintf('Could not extract type: %s', $type_));
|
throw new Exception(sprintf('Could not extract type: %s', $type_));
|
||||||
}
|
}
|
||||||
fwrite($bytes_io, $this->struct->pack('<i', $tl_constructor->id));
|
fwrite($bytes_io, $this->struct->pack('<i', $tl_constructor->id));
|
||||||
foreach ($tl_constructor->params as $arg) {
|
foreach ($tl_constructor->params as $arg) {
|
||||||
$this->serialize_param($bytes_io, $arg['type'], $kwargs[$arg['name']]);
|
$this->serialize_param($bytes_io, $arg['type'], $kwargs[$arg['name']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return fread_all($bytes_io);
|
return fread_all($bytes_io);
|
||||||
}
|
}
|
||||||
function serialize_method($type_, $kwargs) {
|
|
||||||
$bytes_io = fopen("php://memory", "rw+b");
|
public function serialize_method($type_, $kwargs)
|
||||||
if(isset($this->method_name[$type_])) {
|
|
||||||
$tl_method = $this->method_name[$type_];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
$bytes_io = fopen('php://memory', 'rw+b');
|
||||||
|
if (isset($this->method_name[$type_])) {
|
||||||
|
$tl_method = $this->method_name[$type_];
|
||||||
|
} else {
|
||||||
throw new Exception(sprintf('Could not extract type: %s', $type_));
|
throw new Exception(sprintf('Could not extract type: %s', $type_));
|
||||||
}
|
}
|
||||||
fwrite($bytes_io, $this->struct->pack('<i', $tl_method->id));
|
fwrite($bytes_io, $this->struct->pack('<i', $tl_method->id));
|
||||||
foreach ($tl_method->params as $arg) {
|
foreach ($tl_method->params as $arg) {
|
||||||
$this->serialize_param($bytes_io, $arg['type'], $kwargs[$arg['name']]);
|
$this->serialize_param($bytes_io, $arg['type'], $kwargs[$arg['name']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return fread_all($bytes_io);
|
return fread_all($bytes_io);
|
||||||
}
|
}
|
||||||
function serialize_param($bytes_io, $type_, $value) {
|
|
||||||
|
public function serialize_param($bytes_io, $type_, $value)
|
||||||
|
{
|
||||||
if (($type_ == 'int')) {
|
if (($type_ == 'int')) {
|
||||||
assert(is_numeric($value));
|
assert(is_numeric($value));
|
||||||
assert(strlen(decbin($value)) <= 32);
|
assert(strlen(decbin($value)) <= 32);
|
||||||
fwrite($bytes_io, $this->struct->pack('<i', $value));
|
fwrite($bytes_io, $this->struct->pack('<i', $value));
|
||||||
} else if (($type_ == 'long')) {
|
} elseif (($type_ == 'long')) {
|
||||||
assert(is_numeric($value));
|
assert(is_numeric($value));
|
||||||
fwrite($bytes_io, $this->struct->pack('<q', $value));
|
fwrite($bytes_io, $this->struct->pack('<q', $value));
|
||||||
} else if (in_array($type_, ['int128', 'int256'])) {
|
} elseif (in_array($type_, ['int128', 'int256'])) {
|
||||||
assert(is_string($value));
|
assert(is_string($value));
|
||||||
fwrite($bytes_io, $value);
|
fwrite($bytes_io, $value);
|
||||||
} else if ($type_ == 'string' || $type_ == 'bytes') {
|
} elseif ($type_ == 'string' || $type_ == 'bytes') {
|
||||||
$l = len($value);
|
$l = len($value);
|
||||||
if (($l < 254)) {
|
if (($l < 254)) {
|
||||||
fwrite($bytes_io, $this->struct->pack('<b', $l));
|
fwrite($bytes_io, $this->struct->pack('<b', $l));
|
||||||
fwrite($bytes_io, $value);
|
fwrite($bytes_io, $value);
|
||||||
fwrite($bytes_io, pack("@".((-$l - 1) % 4)));
|
fwrite($bytes_io, pack('@'.((-$l - 1) % 4)));
|
||||||
} else {
|
} else {
|
||||||
fwrite($bytes_io, string2bin('\xfe'));
|
fwrite($bytes_io, string2bin('\xfe'));
|
||||||
fwrite($bytes_io, substr($this->struct->pack('<i', $l), null, 3));
|
fwrite($bytes_io, substr($this->struct->pack('<i', $l), null, 3));
|
||||||
fwrite($bytes_io, $value);
|
fwrite($bytes_io, $value);
|
||||||
fwrite($bytes_io, pack("@".(-$l % 4)));
|
fwrite($bytes_io, pack('@'.(-$l % 4)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* :type bytes_io: io.BytesIO object
|
* :type bytes_io: io.BytesIO object.
|
||||||
*/
|
*/
|
||||||
function deserialize(&$bytes_io, $type_ = null, $subtype = null) {
|
public function deserialize(&$bytes_io, $type_ = null, $subtype = null)
|
||||||
|
{
|
||||||
assert(get_resource_type($bytes_io) == 'file' || get_resource_type($bytes_io) == 'stream');
|
assert(get_resource_type($bytes_io) == 'file' || get_resource_type($bytes_io) == 'stream');
|
||||||
if (($type_ == 'int')) {
|
if (($type_ == 'int')) {
|
||||||
$x = $this->struct->unpack('<i', fread($bytes_io, 4)) [0];
|
$x = $this->struct->unpack('<i', fread($bytes_io, 4)) [0];
|
||||||
} else if (($type_ == '#')) {
|
} elseif (($type_ == '#')) {
|
||||||
$x = $this->struct->unpack('<I', fread($bytes_io, 4)) [0];
|
$x = $this->struct->unpack('<I', fread($bytes_io, 4)) [0];
|
||||||
} else if (($type_ == 'long')) {
|
} elseif (($type_ == 'long')) {
|
||||||
$x = $this->struct->unpack('<q', fread($bytes_io, 8)) [0];
|
$x = $this->struct->unpack('<q', fread($bytes_io, 8)) [0];
|
||||||
} else if (($type_ == 'double')) {
|
} elseif (($type_ == 'double')) {
|
||||||
$x = $this->struct->unpack('<d', fread($bytes_io, 8)) [0];
|
$x = $this->struct->unpack('<d', fread($bytes_io, 8)) [0];
|
||||||
} else if (($type_ == 'int128')) {
|
} elseif (($type_ == 'int128')) {
|
||||||
$x = fread($bytes_io, 16);
|
$x = fread($bytes_io, 16);
|
||||||
} else if (($type_ == 'int256')) {
|
} elseif (($type_ == 'int256')) {
|
||||||
$x = fread($bytes_io, 32);
|
$x = fread($bytes_io, 32);
|
||||||
} else if (($type_ == 'string') || ($type_ == 'bytes')) {
|
} elseif (($type_ == 'string') || ($type_ == 'bytes')) {
|
||||||
$l = $this->struct->unpack('<C', fread($bytes_io, 1)) [0];
|
$l = $this->struct->unpack('<C', fread($bytes_io, 1)) [0];
|
||||||
assert($l <= 254);
|
assert($l <= 254);
|
||||||
if (($l == 254)) {
|
if (($l == 254)) {
|
||||||
$long_len = $this->struct->unpack('<I', fread($bytes_io, 3) . string2bin('\x00')) [0];
|
$long_len = $this->struct->unpack('<I', fread($bytes_io, 3).string2bin('\x00')) [0];
|
||||||
$x = fread($bytes_io, $long_len);
|
$x = fread($bytes_io, $long_len);
|
||||||
fread($bytes_io, (-$long_len % 4));
|
fread($bytes_io, (-$long_len % 4));
|
||||||
} else {
|
} else {
|
||||||
@ -145,19 +160,19 @@ class TL {
|
|||||||
fread($bytes_io, (($l + 1) % 4));
|
fread($bytes_io, (($l + 1) % 4));
|
||||||
}
|
}
|
||||||
assert(is_string($x));
|
assert(is_string($x));
|
||||||
} else if (($type_ == 'vector')) {
|
} elseif (($type_ == 'vector')) {
|
||||||
assert($subtype != null);
|
assert($subtype != null);
|
||||||
$count = $this->struct->unpack('<l', substr($bytes_io, 4)) [0];
|
$count = $this->struct->unpack('<l', substr($bytes_io, 4)) [0];
|
||||||
$x = [];
|
$x = [];
|
||||||
foreach( pyjslib_range($count) as $i ) {
|
foreach (pyjslib_range($count) as $i) {
|
||||||
$x[] = deserialize($bytes_io, $subtype);
|
$x[] = deserialize($bytes_io, $subtype);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(isset($this->constructor_type[$type_])) {
|
if (isset($this->constructor_type[$type_])) {
|
||||||
$tl_elem = $this->constructor_type[$type_];
|
$tl_elem = $this->constructor_type[$type_];
|
||||||
} else {
|
} else {
|
||||||
$i = $this->struct->unpack('<i', fread($bytes_io, 4)) [0];
|
$i = $this->struct->unpack('<i', fread($bytes_io, 4)) [0];
|
||||||
if(isset($this->constructor_id[$i])) {
|
if (isset($this->constructor_id[$i])) {
|
||||||
$tl_elem = $this->constructor_id[$i];
|
$tl_elem = $this->constructor_id[$i];
|
||||||
} else {
|
} else {
|
||||||
throw new Exception(sprintf('Could not extract type: %s', $type_));
|
throw new Exception(sprintf('Could not extract type: %s', $type_));
|
||||||
@ -174,6 +189,7 @@ class TL {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $x;
|
return $x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libpy2php');
|
|
||||||
require_once ('libpy2php.php');
|
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
|
||||||
|
require_once 'libpy2php.php';
|
||||||
$__all__ = ['Chat', 'User', 'Message', 'Contact'];
|
$__all__ = ['Chat', 'User', 'Message', 'Contact'];
|
||||||
|
@ -1,11 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libpy2php');
|
|
||||||
require_once ('libpy2php.php');
|
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
|
||||||
class Chat {
|
require_once 'libpy2php.php';
|
||||||
function __construct() {
|
class chat
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
$this->_users = [];
|
$this->_users = [];
|
||||||
}
|
}
|
||||||
function add_user($user) {
|
|
||||||
$this->_users+= $user;
|
public function add_user($user)
|
||||||
|
{
|
||||||
|
$this->_users += $user;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libpy2php');
|
|
||||||
require_once ('libpy2php.php');
|
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
|
||||||
class Contact {
|
require_once 'libpy2php.php';
|
||||||
|
class contact
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
@ -1,43 +1,51 @@
|
|||||||
<?php
|
<?php
|
||||||
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libpy2php');
|
|
||||||
require_once ('libpy2php.php');
|
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
|
||||||
require_once ('os.php');
|
require_once 'libpy2php.php';
|
||||||
class File {
|
require_once 'os.php';
|
||||||
function __construct($path) {
|
class file
|
||||||
|
{
|
||||||
|
public function __construct($path)
|
||||||
|
{
|
||||||
$this->_path = $path;
|
$this->_path = $path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* truncates the file and create new with :param bytes.
|
* truncates the file and create new with :param bytes.
|
||||||
* :return number of bytes written
|
* :return number of bytes written.
|
||||||
*/
|
*/
|
||||||
function write_bytes($bytes) {
|
public function write_bytes($bytes)
|
||||||
|
{
|
||||||
// py2php.fixme "with" unsupported.
|
// py2php.fixme "with" unsupported.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* read the file as bytes. :return b'' on file not exist
|
* read the file as bytes. :return b'' on file not exist.
|
||||||
*/
|
*/
|
||||||
function read_bytes() {
|
public function read_bytes()
|
||||||
|
{
|
||||||
if (!(new exists($this->_path))) {
|
if (!(new exists($this->_path))) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
// py2php.fixme "with" unsupported.
|
// py2php.fixme "with" unsupported.
|
||||||
|
}
|
||||||
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* tries to open with os default viewer
|
* tries to open with os default viewer.
|
||||||
*/
|
*/
|
||||||
function open() {
|
public function open()
|
||||||
new call((os::name == 'nt') ? 'cmd /c start "" "' . $this->_path . '"' : [platform::startswith('darwin') ? 'open' : 'xdg-open', $this->_path]);
|
{
|
||||||
|
new call((os::name == 'nt') ? 'cmd /c start "" "'.$this->_path.'"' : [platform::startswith('darwin') ? 'open' : 'xdg-open', $this->_path]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* try to remove the file
|
* try to remove the file.
|
||||||
*/
|
*/
|
||||||
function remove() {
|
public function remove()
|
||||||
|
{
|
||||||
try {
|
try {
|
||||||
os::remove($this->_path);
|
os::remove($this->_path);
|
||||||
}
|
} catch (FileNotFoundError $e) {
|
||||||
catch(FileNotFoundError $e) {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libpy2php');
|
|
||||||
require_once ('libpy2php.php');
|
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
|
||||||
require_once ('crypt.php');
|
require_once 'libpy2php.php';
|
||||||
class Message {
|
require_once 'crypt.php';
|
||||||
|
class message
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
@ -1,280 +1,373 @@
|
|||||||
<?php
|
<?php
|
||||||
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libpy2php');
|
|
||||||
require_once ('libpy2php.php');
|
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
|
||||||
require_once ('os.php');
|
require_once 'libpy2php.php';
|
||||||
class TelepyShell {
|
require_once 'os.php';
|
||||||
|
class TelepyShell
|
||||||
|
{
|
||||||
public $intro = 'Welcome to telepy interactive shell. Type help or ? for help.
|
public $intro = 'Welcome to telepy interactive shell. Type help or ? for help.
|
||||||
';
|
';
|
||||||
public $prompt = '>';
|
public $prompt = '>';
|
||||||
function preloop() {
|
|
||||||
require_once ('classes/telepy.php');
|
public function preloop()
|
||||||
|
{
|
||||||
|
require_once 'classes/telepy.php';
|
||||||
$this->_telepy = new Telepy();
|
$this->_telepy = new Telepy();
|
||||||
}
|
}
|
||||||
function precmd($line) {
|
|
||||||
|
public function precmd($line)
|
||||||
|
{
|
||||||
$line = $line->lstrip();
|
$line = $line->lstrip();
|
||||||
$blank_pos = $line->find(' ');
|
$blank_pos = $line->find(' ');
|
||||||
if (($blank_pos < 0)) {
|
if (($blank_pos < 0)) {
|
||||||
return $line->lower();
|
return $line->lower();
|
||||||
}
|
}
|
||||||
return array_slice($line, null, $blank_pos)->lower() . ' ' . array_slice($line, ($blank_pos + 1), null);
|
|
||||||
|
return array_slice($line, null, $blank_pos)->lower().' '.array_slice($line, ($blank_pos + 1), null);
|
||||||
}
|
}
|
||||||
function completedefault(...$ignored) {
|
|
||||||
|
public function completedefault(...$ignored)
|
||||||
|
{
|
||||||
pyjslib_printnl($ignored);
|
pyjslib_printnl($ignored);
|
||||||
}
|
}
|
||||||
function complete($text, $state) {
|
|
||||||
|
public function complete($text, $state)
|
||||||
|
{
|
||||||
$this->super()->complete($text, $state);
|
$this->super()->complete($text, $state);
|
||||||
pyjslib_printnl('completing');
|
pyjslib_printnl('completing');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* shell <command-line>
|
* shell <command-line>
|
||||||
* lets you use external shell. !<command-line> for short-hand.
|
* lets you use external shell. !<command-line> for short-hand.
|
||||||
*/
|
*/
|
||||||
function do_shell($line) {
|
public function do_shell($line)
|
||||||
|
{
|
||||||
pyjslib_printnl(os::popen($line)->read());
|
pyjslib_printnl(os::popen($line)->read());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* msg <peer>
|
* msg <peer>
|
||||||
* sends message to this peer
|
* sends message to this peer.
|
||||||
*/
|
*/
|
||||||
function do_msg($arg) {
|
public function do_msg($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fwd <user> <msg-no>
|
* fwd <user> <msg-no>
|
||||||
* forward message to user. You can see message numbers starting client with -N
|
* forward message to user. You can see message numbers starting client with -N.
|
||||||
*/
|
*/
|
||||||
function do_fwd($arg) {
|
public function do_fwd($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* chat_with_peer <peer>
|
* chat_with_peer <peer>
|
||||||
* starts one on one chat session with this peer. /exit or /quit to end this mode.
|
* starts one on one chat session with this peer. /exit or /quit to end this mode.
|
||||||
*/
|
*/
|
||||||
function do_chat_with_peer($arg) {
|
public function do_chat_with_peer($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add_contact <phone-number> <first-name> <last-name>
|
* add_contact <phone-number> <first-name> <last-name>
|
||||||
* tries to add contact to contact-list by phone
|
* tries to add contact to contact-list by phone.
|
||||||
*/
|
*/
|
||||||
function do_add_contact($arg) {
|
public function do_add_contact($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rename_contact <user> <first-name> <last-name>
|
* rename_contact <user> <first-name> <last-name>
|
||||||
* tries to rename contact. If you have another device it will be a fight
|
* tries to rename contact. If you have another device it will be a fight.
|
||||||
*/
|
*/
|
||||||
function do_rename_contact($arg) {
|
public function do_rename_contact($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mark_read <peer>
|
* mark_read <peer>
|
||||||
* mark read all received messages with peer
|
* mark read all received messages with peer.
|
||||||
*/
|
*/
|
||||||
function do_mark_read($arg) {
|
public function do_mark_read($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* delete_msg <msg-no>
|
* delete_msg <msg-no>
|
||||||
* deletes message (not completly, though)
|
* deletes message (not completly, though).
|
||||||
*/
|
*/
|
||||||
function do_delete_msg($arg) {
|
public function do_delete_msg($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* restore_msg <msg-no>
|
* restore_msg <msg-no>
|
||||||
* restores delete message. Impossible for secret chats. Only possible short time (one hour, I think) after deletion
|
* restores delete message. Impossible for secret chats. Only possible short time (one hour, I think) after deletion.
|
||||||
*/
|
*/
|
||||||
function do_restore_msg($arg) {
|
public function do_restore_msg($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* send_photo <peer> <photo-file-name>
|
* send_photo <peer> <photo-file-name>
|
||||||
* sends photo to peer
|
* sends photo to peer.
|
||||||
*/
|
*/
|
||||||
function do_send_photo($arg) {
|
public function do_send_photo($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* send_video <peer> <video-file-name>
|
* send_video <peer> <video-file-name>
|
||||||
* sends video to peer
|
* sends video to peer.
|
||||||
*/
|
*/
|
||||||
function do_send_video($arg) {
|
public function do_send_video($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* send_text <peer> <text-file-name>
|
* send_text <peer> <text-file-name>
|
||||||
* sends text file as plain messages
|
* sends text file as plain messages.
|
||||||
*/
|
*/
|
||||||
function do_send_text($arg) {
|
public function do_send_text($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* load_photo <msg-no>
|
* load_photo <msg-no>
|
||||||
* loads photo to download dir
|
* loads photo to download dir.
|
||||||
*/
|
*/
|
||||||
function do_load_photo($arg) {
|
public function do_load_photo($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* load_video <msg-no>
|
* load_video <msg-no>
|
||||||
* loads video to download dir
|
* loads video to download dir.
|
||||||
*/
|
*/
|
||||||
function do_load_video($arg) {
|
public function do_load_video($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* load_video_thumb <msg-no>
|
* load_video_thumb <msg-no>
|
||||||
* loads video thumbnail to download dir
|
* loads video thumbnail to download dir.
|
||||||
*/
|
*/
|
||||||
function do_load_video_thumb($arg) {
|
public function do_load_video_thumb($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* load_audio <msg-no>
|
* load_audio <msg-no>
|
||||||
* loads audio to download dir
|
* loads audio to download dir.
|
||||||
*/
|
*/
|
||||||
function do_load_audio($arg) {
|
public function do_load_audio($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* load_document <msg-no>
|
* load_document <msg-no>
|
||||||
* loads document to download dir
|
* loads document to download dir.
|
||||||
*/
|
*/
|
||||||
function do_load_document($arg) {
|
public function do_load_document($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* load_document_thumb <msg-no>
|
* load_document_thumb <msg-no>
|
||||||
* loads document thumbnail to download dir
|
* loads document thumbnail to download dir.
|
||||||
*/
|
*/
|
||||||
function do_load_document_thumb($arg) {
|
public function do_load_document_thumb($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* view_photo <msg-no>
|
* view_photo <msg-no>
|
||||||
* loads photo/video to download dir and starts system default viewer
|
* loads photo/video to download dir and starts system default viewer.
|
||||||
*/
|
*/
|
||||||
function do_view_photo($arg) {
|
public function do_view_photo($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* view_video <msg-no>
|
* view_video <msg-no>.
|
||||||
*/
|
*/
|
||||||
function do_view_video($arg) {
|
public function do_view_video($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* view_video_thumb <msg-no>
|
* view_video_thumb <msg-no>.
|
||||||
*/
|
*/
|
||||||
function do_view_video_thumb($arg) {
|
public function do_view_video_thumb($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* view_audio <msg-no>
|
* view_audio <msg-no>.
|
||||||
*/
|
*/
|
||||||
function do_view_audio($arg) {
|
public function do_view_audio($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* view_document <msg-no>
|
* view_document <msg-no>.
|
||||||
*/
|
*/
|
||||||
function do_view_document($arg) {
|
public function do_view_document($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* view_document_thumb <msg-no>
|
* view_document_thumb <msg-no>.
|
||||||
*/
|
*/
|
||||||
function do_view_document_thumb($arg) {
|
public function do_view_document_thumb($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fwd_media <msg-no>
|
* fwd_media <msg-no>
|
||||||
* send media in your message. Use this to prevent sharing info about author of media (though, it is possible to determine user_id from media itself, it is not possible get access_hash of this user)
|
* send media in your message. Use this to prevent sharing info about author of media (though, it is possible to determine user_id from media itself, it is not possible get access_hash of this user).
|
||||||
*/
|
*/
|
||||||
function do_fwd_media($arg) {
|
public function do_fwd_media($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set_profile_photo <photo-file-name>
|
* set_profile_photo <photo-file-name>
|
||||||
* sets userpic. Photo should be square, or server will cut biggest central square part
|
* sets userpic. Photo should be square, or server will cut biggest central square part.
|
||||||
*/
|
*/
|
||||||
function do_set_profile_photo($arg) {
|
public function do_set_profile_photo($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* chat_info <chat>
|
* chat_info <chat>
|
||||||
* prints info about chat
|
* prints info about chat.
|
||||||
*/
|
*/
|
||||||
function do_chat_info($arg) {
|
public function do_chat_info($arg)
|
||||||
|
{
|
||||||
$arg = $arg->split();
|
$arg = $arg->split();
|
||||||
if ((count($arg) == 1)) {
|
if ((count($arg) == 1)) {
|
||||||
pyjslib_printnl(['chat_info called with ', $arg[0]]);
|
pyjslib_printnl(['chat_info called with ', $arg[0]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* chat_add_user <chat> <user>
|
* chat_add_user <chat> <user>
|
||||||
* add user to chat
|
* add user to chat.
|
||||||
*/
|
*/
|
||||||
function do_chat_add_user($arg) {
|
public function do_chat_add_user($arg)
|
||||||
|
{
|
||||||
pyjslib_printnl($arg);
|
pyjslib_printnl($arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* chat_del_user <chat> <user>
|
* chat_del_user <chat> <user>
|
||||||
* remove user from chat
|
* remove user from chat.
|
||||||
*/
|
*/
|
||||||
function do_chat_del_user($arg) {
|
public function do_chat_del_user($arg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* chat_rename <chat> <new-name>
|
* chat_rename <chat> <new-name>
|
||||||
* rename chat room
|
* rename chat room.
|
||||||
*/
|
*/
|
||||||
function do_chat_rename($arg) {
|
public function do_chat_rename($arg)
|
||||||
|
{
|
||||||
$arg = $arg->split();
|
$arg = $arg->split();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create_group_chat <chat topic> <user1> <user2> <user3> ...
|
* create_group_chat <chat topic> <user1> <user2> <user3> ...
|
||||||
* creates a groupchat with users, use chat_add_user to add more users
|
* creates a groupchat with users, use chat_add_user to add more users.
|
||||||
*/
|
*/
|
||||||
function do_create_group_chat($chat_topic, $user1, $user2, $user3) {
|
public function do_create_group_chat($chat_topic, $user1, $user2, $user3)
|
||||||
|
{
|
||||||
pyjslib_printnl($chat_topic);
|
pyjslib_printnl($chat_topic);
|
||||||
pyjslib_printnl([$user1, $user2, $user3]);
|
pyjslib_printnl([$user1, $user2, $user3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* chat_set_photo <chat> <photo-file-name>
|
* chat_set_photo <chat> <photo-file-name>
|
||||||
* sets group chat photo. Same limits as for profile photos.
|
* sets group chat photo. Same limits as for profile photos.
|
||||||
*/
|
*/
|
||||||
function do_chat_set_photo($chat, $photo) {
|
public function do_chat_set_photo($chat, $photo)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* search <peer> <pattern>
|
* search <peer> <pattern>
|
||||||
* searches pattern in messages with peer
|
* searches pattern in messages with peer.
|
||||||
*/
|
*/
|
||||||
function do_search($pattern) {
|
public function do_search($pattern)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* global_search <pattern>
|
* global_search <pattern>
|
||||||
* searches pattern in all messages
|
* searches pattern in all messages.
|
||||||
*/
|
*/
|
||||||
function do_global_search($pattern) {
|
public function do_global_search($pattern)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create_secret_chat <user>
|
* create_secret_chat <user>
|
||||||
* creates secret chat with this user
|
* creates secret chat with this user.
|
||||||
*/
|
*/
|
||||||
function do_create_secret_chat($user) {
|
public function do_create_secret_chat($user)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* visualize_key <secret_chat>
|
* visualize_key <secret_chat>
|
||||||
* prints visualization of encryption key. You should compare it to your partner's one
|
* prints visualization of encryption key. You should compare it to your partner's one.
|
||||||
*/
|
*/
|
||||||
function do_visualize_key($secret_chat) {
|
public function do_visualize_key($secret_chat)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set_ttl <secret_chat> <ttl>
|
* set_ttl <secret_chat> <ttl>
|
||||||
* sets ttl to secret chat. Though client does ignore it, client on other end can make use of it
|
* sets ttl to secret chat. Though client does ignore it, client on other end can make use of it.
|
||||||
*/
|
*/
|
||||||
function do_set_ttl($secret_chat, $ttl) {
|
public function do_set_ttl($secret_chat, $ttl)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* accept_secret_chat <secret_chat>
|
* accept_secret_chat <secret_chat>
|
||||||
* manually accept secret chat (only useful when starting with -E key)
|
* manually accept secret chat (only useful when starting with -E key).
|
||||||
*/
|
*/
|
||||||
function do_accept_secret_chat($secret_chat) {
|
public function do_accept_secret_chat($secret_chat)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* user_info <user>
|
* user_info <user>
|
||||||
* prints info about user
|
* prints info about user.
|
||||||
*/
|
*/
|
||||||
function do_user_info($user) {
|
public function do_user_info($user)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* history <peer> [limit]
|
* history <peer> [limit]
|
||||||
* prints history (and marks it as read). Default limit = 40
|
* prints history (and marks it as read). Default limit = 40.
|
||||||
*/
|
*/
|
||||||
function do_history($peer, $limit = 40) {
|
public function do_history($peer, $limit = 40)
|
||||||
|
{
|
||||||
if (($peer == '')) {
|
if (($peer == '')) {
|
||||||
pyjslib_printnl('no peer have specified');
|
pyjslib_printnl('no peer have specified');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$args = $peer->split();
|
$args = $peer->split();
|
||||||
if (!in_array(count($args), [1, 2])) {
|
if (!in_array(count($args), [1, 2])) {
|
||||||
pyjslib_printnl(['not appropriate number of arguments : ', $peer]);
|
pyjslib_printnl(['not appropriate number of arguments : ', $peer]);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((count($args) == 2)) {
|
if ((count($args) == 2)) {
|
||||||
@ -286,54 +379,70 @@ class TelepyShell {
|
|||||||
pyjslib_printnl($peer);
|
pyjslib_printnl($peer);
|
||||||
pyjslib_printnl($limit);
|
pyjslib_printnl($limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dialog_list
|
* dialog_list
|
||||||
* prints info about your dialogs
|
* prints info about your dialogs.
|
||||||
*/
|
*/
|
||||||
function do_dialog_list($ignored) {
|
public function do_dialog_list($ignored)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* contact_list
|
* contact_list
|
||||||
* prints info about users in your contact list
|
* prints info about users in your contact list.
|
||||||
*/
|
*/
|
||||||
function do_contact_list($ignored) {
|
public function do_contact_list($ignored)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* suggested_contacts
|
* suggested_contacts
|
||||||
* print info about contacts, you have max common friends
|
* print info about contacts, you have max common friends.
|
||||||
*/
|
*/
|
||||||
function do_suggested_contacts($ignored) {
|
public function do_suggested_contacts($ignored)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stats
|
* stats
|
||||||
* just for debugging
|
* just for debugging.
|
||||||
*/
|
*/
|
||||||
function do_stats($ignored) {
|
public function do_stats($ignored)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* export_card
|
* export_card
|
||||||
* print your 'card' that anyone can later use to import your contact
|
* print your 'card' that anyone can later use to import your contact.
|
||||||
*/
|
*/
|
||||||
function do_export_card($card) {
|
public function do_export_card($card)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* import_card <card>
|
* import_card <card>
|
||||||
* gets user by card. You can write messages to him after that.
|
* gets user by card. You can write messages to him after that.
|
||||||
*/
|
*/
|
||||||
function do_import_card($card) {
|
public function do_import_card($card)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* quit_force
|
* quit_force
|
||||||
* quit without waiting for query ends
|
* quit without waiting for query ends.
|
||||||
*/
|
*/
|
||||||
function do_quit_force($ignored) {
|
public function do_quit_force($ignored)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* quit
|
* quit
|
||||||
* wait for all queries to end then quit
|
* wait for all queries to end then quit.
|
||||||
*/
|
*/
|
||||||
function do_quit($ignored) {
|
public function do_quit($ignored)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
<?php
|
<?php
|
||||||
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libpy2php');
|
|
||||||
require_once ('libpy2php.php');
|
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
|
||||||
class Telepy {
|
require_once 'libpy2php.php';
|
||||||
function __construct() {
|
class telepy
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
try {
|
try {
|
||||||
require_once ('configparser.php');
|
require_once 'configparser.php';
|
||||||
|
} catch (ImportError $e) {
|
||||||
|
require_once 'ConfigParser.php';
|
||||||
}
|
}
|
||||||
catch(ImportError $e) {
|
require_once 'mtproto.php';
|
||||||
require_once ('ConfigParser.php');
|
|
||||||
}
|
|
||||||
require_once ('mtproto.php');
|
|
||||||
$this->_config = $configparser->ConfigParser();
|
$this->_config = $configparser->ConfigParser();
|
||||||
if (!($this->_config->read('credentials'))) {
|
if (!($this->_config->read('credentials'))) {
|
||||||
pyjslib_printnl('File \'credentials\' seems to not exist.');
|
pyjslib_printnl('File \'credentials\' seems to not exist.');
|
||||||
@ -19,7 +21,7 @@ class Telepy {
|
|||||||
$port = $this->_config->getint('App data', 'port');
|
$port = $this->_config->getint('App data', 'port');
|
||||||
$this->_session = $mtproto->Session($ip, $port);
|
$this->_session = $mtproto->Session($ip, $port);
|
||||||
$this->_session->create_auth_key();
|
$this->_session->create_auth_key();
|
||||||
$__temp22 = py2php_kwargs_method_call($this->_session, 'method_call', ['get_future_salts'], ["num" => 3]);
|
$__temp22 = py2php_kwargs_method_call($this->_session, 'method_call', ['get_future_salts'], ['num' => 3]);
|
||||||
$this->_salt = $__temp22;
|
$this->_salt = $__temp22;
|
||||||
$future_salts = $__temp22;
|
$future_salts = $__temp22;
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libpy2php');
|
|
||||||
require_once ('libpy2php.php');
|
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
|
||||||
class User {
|
require_once 'libpy2php.php';
|
||||||
|
class user
|
||||||
|
{
|
||||||
public $me = null;
|
public $me = null;
|
||||||
// current connected user
|
// current connected user
|
||||||
public $friends = [];
|
public $friends = [];
|
||||||
|
|
||||||
// current connected user's friends
|
// current connected user's friends
|
||||||
function __construct($uid) {
|
public function __construct($uid)
|
||||||
|
{
|
||||||
$this->uid = $uid;
|
$this->uid = $uid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
32
crypt.php
32
crypt.php
@ -1,14 +1,20 @@
|
|||||||
<?php
|
<?php
|
||||||
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libpy2php');
|
|
||||||
require_once ('libpy2php.php');
|
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
|
||||||
require_once ('AES.class.php');
|
require_once 'libpy2php.php';
|
||||||
class crypt {
|
require_once 'AES.class.php';
|
||||||
function ige_encrypt($message, $key, $iv) {
|
class crypt
|
||||||
|
{
|
||||||
|
public function ige_encrypt($message, $key, $iv)
|
||||||
|
{
|
||||||
return _ige($message, $key, $iv, 'encrypt');
|
return _ige($message, $key, $iv, 'encrypt');
|
||||||
}
|
}
|
||||||
function ige_decrypt($message, $key, $iv) {
|
|
||||||
|
public function ige_decrypt($message, $key, $iv)
|
||||||
|
{
|
||||||
return _ige($message, $key, $iv, 'decrypt');
|
return _ige($message, $key, $iv, 'decrypt');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a key, given an iv, and message
|
* Given a key, given an iv, and message
|
||||||
* do whatever operation asked in the operation field.
|
* do whatever operation asked in the operation field.
|
||||||
@ -17,21 +23,22 @@ class crypt {
|
|||||||
* message must be a multiple by 16 bytes (for division in 16 byte blocks)
|
* message must be a multiple by 16 bytes (for division in 16 byte blocks)
|
||||||
* key must be 32 byte
|
* key must be 32 byte
|
||||||
* iv must be 32 byte (it's not internally used in AES 256 ECB, but it's
|
* iv must be 32 byte (it's not internally used in AES 256 ECB, but it's
|
||||||
* needed for IGE)
|
* needed for IGE).
|
||||||
*/
|
*/
|
||||||
function _ige($message, $key, $iv, $operation = 'decrypt') {
|
public function _ige($message, $key, $iv, $operation = 'decrypt')
|
||||||
|
{
|
||||||
$message = str_split($message);
|
$message = str_split($message);
|
||||||
if ((len($key) != 32)) {
|
if ((len($key) != 32)) {
|
||||||
throw new Exception('key must be 32 bytes long (was ' . len($key) . ' bytes)');
|
throw new Exception('key must be 32 bytes long (was '.len($key).' bytes)');
|
||||||
}
|
}
|
||||||
if ((len($iv) != 32)) {
|
if ((len($iv) != 32)) {
|
||||||
throw new Exception('iv must be 32 bytes long (was ' . len($iv) . ' bytes)');
|
throw new Exception('iv must be 32 bytes long (was '.len($iv).' bytes)');
|
||||||
}
|
}
|
||||||
$cipher = new AES($key);
|
$cipher = new AES($key);
|
||||||
$cipher = $cipher->encrypt($iv);
|
$cipher = $cipher->encrypt($iv);
|
||||||
$blocksize = $cipher->block_size;
|
$blocksize = $cipher->block_size;
|
||||||
if ((len($message) % $blocksize) != 0) {
|
if ((len($message) % $blocksize) != 0) {
|
||||||
throw new Exception('message must be a multiple of 16 bytes (try adding ' . (16 - (count($message) % 16)) . ' bytes of padding)');
|
throw new Exception('message must be a multiple of 16 bytes (try adding '.(16 - (count($message) % 16)).' bytes of padding)');
|
||||||
}
|
}
|
||||||
$ivp = substr($iv, 0, $blocksize - 0);
|
$ivp = substr($iv, 0, $blocksize - 0);
|
||||||
$ivp2 = substr($iv, $blocksize, null);
|
$ivp2 = substr($iv, $blocksize, null);
|
||||||
@ -44,7 +51,7 @@ class crypt {
|
|||||||
$outdata = strxor($decrypt_xored, $ivp);
|
$outdata = strxor($decrypt_xored, $ivp);
|
||||||
$ivp = $indata;
|
$ivp = $indata;
|
||||||
$ivp2 = $outdata;
|
$ivp2 = $outdata;
|
||||||
} else if (($operation == 'encrypt')) {
|
} elseif (($operation == 'encrypt')) {
|
||||||
$xored = strxor($indata, $ivp);
|
$xored = strxor($indata, $ivp);
|
||||||
$encrypt_xored = $cipher->encrypt($xored);
|
$encrypt_xored = $cipher->encrypt($xored);
|
||||||
$outdata = strxor($encrypt_xored, $ivp2);
|
$outdata = strxor($encrypt_xored, $ivp2);
|
||||||
@ -55,6 +62,7 @@ class crypt {
|
|||||||
}
|
}
|
||||||
$ciphered .= $outdata;
|
$ciphered .= $outdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ciphered;
|
return $ciphered;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,21 +1,21 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
# Copyright 2006 James Tauber and contributors
|
// Copyright 2006 James Tauber and contributors
|
||||||
#
|
//
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
# You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
#
|
//
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
//
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This call makes three things happen:
|
* This call makes three things happen:.
|
||||||
*
|
*
|
||||||
* 1) a global error handler for php errors that causes an exception to be
|
* 1) a global error handler for php errors that causes an exception to be
|
||||||
* thrown instead of standard php error handling.
|
* thrown instead of standard php error handling.
|
||||||
@ -26,175 +26,182 @@
|
|||||||
* 3) error_reporting is set to E_STRICT, so that even notices cause an
|
* 3) error_reporting is set to E_STRICT, so that even notices cause an
|
||||||
* exception to be thrown. This way we are forced to deal with even
|
* exception to be thrown. This way we are forced to deal with even
|
||||||
* the minor issues during development, and hopefully fewer issues
|
* the minor issues during development, and hopefully fewer issues
|
||||||
make it out into the world.
|
|
||||||
*/
|
*/
|
||||||
require_once( dirname(__FILE__) . DIRECTORY_SEPARATOR . 'strict_mode.php' );
|
require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'strict_mode.php';
|
||||||
init_strict_mode();
|
init_strict_mode();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# iteration from Bob Ippolito's Iteration in JavaScript
|
// iteration from Bob Ippolito's Iteration in JavaScript
|
||||||
# pyjs_extend from Kevin Lindsey's Inteheritance Tutorial (http://www.kevlindev.com/tutorials/javascript/inheritance/)
|
// pyjs_extend from Kevin Lindsey's Inteheritance Tutorial (http://www.kevlindev.com/tutorials/javascript/inheritance/)
|
||||||
|
|
||||||
# type functions from Douglas Crockford's Remedial Javascript: http://www.crockford.com/javascript/remedial.html
|
|
||||||
function pyjslib_isObject($a) {
|
|
||||||
|
|
||||||
|
// type functions from Douglas Crockford's Remedial Javascript: http://www.crockford.com/javascript/remedial.html
|
||||||
|
function pyjslib_isObject($a)
|
||||||
|
{
|
||||||
return is_object($a);
|
return is_object($a);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function pyjslib_isFunction($a) {
|
function pyjslib_isFunction($a)
|
||||||
|
{
|
||||||
return is_function($a);
|
return is_function($a);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function pyjslib_isString($a) {
|
function pyjslib_isString($a)
|
||||||
|
{
|
||||||
return is_string($a);
|
return is_string($a);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function pyjslib_isNull($a) {
|
function pyjslib_isNull($a)
|
||||||
|
{
|
||||||
return is_null($a);
|
return is_null($a);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function pyjslib_isArray($a) {
|
function pyjslib_isArray($a)
|
||||||
|
{
|
||||||
return is_array($a);
|
return is_array($a);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function pyjslib_isUndefined($a) {
|
function pyjslib_isUndefined($a)
|
||||||
|
{
|
||||||
return !isset($a);
|
return !isset($a);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function pyjslib_isIteratable($a) {
|
function pyjslib_isIteratable($a)
|
||||||
|
{
|
||||||
return $a instanceof Traversable;
|
return $a instanceof Traversable;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function pyjslib_isNumber($a) {
|
function pyjslib_isNumber($a)
|
||||||
|
{
|
||||||
return is_numeric($a);
|
return is_numeric($a);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function pyjslib_int($a) {
|
function pyjslib_int($a)
|
||||||
return (int)$a;
|
{
|
||||||
|
return (int) $a;
|
||||||
}
|
}
|
||||||
|
|
||||||
function pyjslib_str($val) {
|
function pyjslib_str($val)
|
||||||
return (string)$val;
|
{
|
||||||
|
return (string) $val;
|
||||||
}
|
}
|
||||||
|
|
||||||
function pyjslib_del_slice(&$list, $from, $to, $step=1) {
|
function pyjslib_del_slice(&$list, $from, $to, $step = 1)
|
||||||
if( $from <= 0 ) {
|
{
|
||||||
|
if ($from <= 0) {
|
||||||
$from = 0;
|
$from = 0;
|
||||||
}
|
}
|
||||||
if( $to === null ) {
|
if ($to === null) {
|
||||||
$to = count($list);
|
$to = count($list);
|
||||||
}
|
}
|
||||||
if( $step <= 0 ) {
|
if ($step <= 0) {
|
||||||
$step = 1;
|
$step = 1;
|
||||||
}
|
}
|
||||||
for( $i = $from; $i < $to; $i += $step ) {
|
for ($i = $from; $i < $to; $i += $step) {
|
||||||
unset( $list[$i]);
|
unset($list[$i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function pyjslib_array_slice($list, $from, $to, $step=1) {
|
function pyjslib_array_slice($list, $from, $to, $step = 1)
|
||||||
|
{
|
||||||
$newlist = [];
|
$newlist = [];
|
||||||
if( $from <= 0 ) {
|
if ($from <= 0) {
|
||||||
$from = 0;
|
$from = 0;
|
||||||
}
|
}
|
||||||
if( $to === null ) {
|
if ($to === null) {
|
||||||
$to = count($list);
|
$to = count($list);
|
||||||
}
|
}
|
||||||
if( $step <= 0 ) {
|
if ($step <= 0) {
|
||||||
$step = 1;
|
$step = 1;
|
||||||
}
|
}
|
||||||
for( $i = $from; $i < $to; $i += $step ) {
|
for ($i = $from; $i < $to; $i += $step) {
|
||||||
$newlist[] = $list[$i];
|
$newlist[] = $list[$i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $newlist;
|
return $newlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# taken from mochikit: range( [start,] stop[, step] )
|
// taken from mochikit: range( [start,] stop[, step] )
|
||||||
function pyjslib_range($start, $stop = null, $step = 1) {
|
function pyjslib_range($start, $stop = null, $step = 1)
|
||||||
if( $stop === null ) {
|
{
|
||||||
|
if ($stop === null) {
|
||||||
$stop = $start;
|
$stop = $start;
|
||||||
$start = 0;
|
$start = 0;
|
||||||
}
|
}
|
||||||
if( $stop <= $start && $step < 0 ) {
|
if ($stop <= $start && $step < 0) {
|
||||||
$arr = range( $stop, $start, -$step );
|
$arr = range($stop, $start, -$step);
|
||||||
array_pop( $arr );
|
array_pop($arr);
|
||||||
return array_reverse( $arr, false );
|
|
||||||
|
return array_reverse($arr, false);
|
||||||
}
|
}
|
||||||
$arr = range( $start, $stop, $step );
|
$arr = range($start, $stop, $step);
|
||||||
array_pop( $arr );
|
array_pop($arr);
|
||||||
|
|
||||||
return $arr;
|
return $arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
function pyjslib_filter($callback, $iterable) {
|
function pyjslib_filter($callback, $iterable)
|
||||||
|
{
|
||||||
$a = [];
|
$a = [];
|
||||||
foreach( $iterable as $item ) {
|
foreach ($iterable as $item) {
|
||||||
if( call_user_func( $callback, $item ) ) {
|
if (call_user_func($callback, $item)) {
|
||||||
$a[] = $item;
|
$a[] = $item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $a;
|
return $a;
|
||||||
}
|
}
|
||||||
|
|
||||||
function pyjslib_globals() {
|
function pyjslib_globals()
|
||||||
|
{
|
||||||
return $GLOBALS;
|
return $GLOBALS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function pyjslib_map($callable) {
|
function pyjslib_map($callable)
|
||||||
|
{
|
||||||
$done = false;
|
$done = false;
|
||||||
$call_cnt = 0;
|
$call_cnt = 0;
|
||||||
$results = [];
|
$results = [];
|
||||||
|
|
||||||
$params = func_get_args();
|
$params = func_get_args();
|
||||||
array_shift( $params );
|
array_shift($params);
|
||||||
|
|
||||||
while( !$done ) {
|
while (!$done) {
|
||||||
$func_args = [];
|
$func_args = [];
|
||||||
$found = false;
|
$found = false;
|
||||||
for( $i = 0; $i < count($params); $i ++ ) {
|
for ($i = 0; $i < count($params); $i++) {
|
||||||
$func_args[] = @$params[$i][$call_cnt];
|
$func_args[] = @$params[$i][$call_cnt];
|
||||||
if( count($params[$i]) > $call_cnt + 1 ) {
|
if (count($params[$i]) > $call_cnt + 1) {
|
||||||
$found = true;
|
$found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( !$found ) {
|
if (!$found) {
|
||||||
$done = true;
|
$done = true;
|
||||||
}
|
}
|
||||||
$results[] = call_user_func_array($callable, $func_args);
|
$results[] = call_user_func_array($callable, $func_args);
|
||||||
$call_cnt ++;
|
$call_cnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $results;
|
return $results;
|
||||||
}
|
}
|
||||||
|
|
||||||
function pyjslib_zip() {
|
function pyjslib_zip()
|
||||||
|
{
|
||||||
$params = func_get_args();
|
$params = func_get_args();
|
||||||
if (count($params) === 1){ // this case could be probably cleaner
|
if (count($params) === 1) { // this case could be probably cleaner
|
||||||
// single iterable passed
|
// single iterable passed
|
||||||
$result = array();
|
$result = [];
|
||||||
foreach ($params[0] as $item){
|
foreach ($params[0] as $item) {
|
||||||
$result[] = array($item);
|
$result[] = [$item];
|
||||||
};
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
};
|
}
|
||||||
$result = call_user_func_array('array_map',array_merge(array(null),$params));
|
$result = call_user_func_array('array_map', array_merge([null], $params));
|
||||||
$length = min(array_map('count', $params));
|
$length = min(array_map('count', $params));
|
||||||
|
|
||||||
return array_slice($result, 0, $length);
|
return array_slice($result, 0, $length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,82 +210,83 @@ function pyjslib_is_assoc($arr)
|
|||||||
return array_keys($arr) !== range(0, count($arr) - 1);
|
return array_keys($arr) !== range(0, count($arr) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function pyjslib_dict($arg=null) {
|
function pyjslib_dict($arg = null)
|
||||||
if( $arg === null ) {
|
{
|
||||||
|
if ($arg === null) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
if( pyjslib_is_assoc( $arg )) {
|
if (pyjslib_is_assoc($arg)) {
|
||||||
return $arg;
|
return $arg;
|
||||||
}
|
}
|
||||||
$dict = [];
|
$dict = [];
|
||||||
foreach( $arg as $a ) {
|
foreach ($arg as $a) {
|
||||||
if( count($a) == 2 ) {
|
if (count($a) == 2) {
|
||||||
$dict[$a[0]] = $a[1];
|
$dict[$a[0]] = $a[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $dict;
|
return $dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
function pyjslib_printWorker($objs, $nl, $multi_arg, $depth=1) {
|
function pyjslib_printWorker($objs, $nl, $multi_arg, $depth = 1)
|
||||||
|
{
|
||||||
$buf = '';
|
$buf = '';
|
||||||
if( is_array( $objs ) && $multi_arg && $depth == 1) {
|
if (is_array($objs) && $multi_arg && $depth == 1) {
|
||||||
$cnt = 0;
|
$cnt = 0;
|
||||||
foreach( $objs as $obj ) {
|
foreach ($objs as $obj) {
|
||||||
if( $cnt ++ > 0 ) {
|
if ($cnt++ > 0) {
|
||||||
$buf .= " ";
|
$buf .= ' ';
|
||||||
}
|
}
|
||||||
$buf .= pyjslib_printWorker( $obj, $nl, $multi_arg, $depth + 1 );
|
$buf .= pyjslib_printWorker($obj, $nl, $multi_arg, $depth + 1);
|
||||||
}
|
}
|
||||||
}
|
} elseif (is_bool($objs)) {
|
||||||
else if( is_bool( $objs )) {
|
$buf = $objs ? 'True' : 'False';
|
||||||
$buf = $objs ? "True" : "False";
|
} elseif (is_null($objs)) {
|
||||||
}
|
|
||||||
else if( is_null( $objs )) {
|
|
||||||
$buf = 'None';
|
$buf = 'None';
|
||||||
}
|
} elseif (is_float($objs)) {
|
||||||
else if( is_float( $objs )) {
|
$buf = (int) $objs;
|
||||||
$buf = (int)$objs;
|
} elseif (is_string($objs) && ($multi_arg && $depth > 2 || (!$multi_arg && $depth > 1))) {
|
||||||
}
|
|
||||||
else if( is_string( $objs ) && ($multi_arg && $depth > 2 || (!$multi_arg && $depth > 1) ) ) {
|
|
||||||
$buf = "'$objs'";
|
$buf = "'$objs'";
|
||||||
}
|
} elseif (is_array($objs)) {
|
||||||
elseif( is_array( $objs )) {
|
|
||||||
$buf = '[';
|
$buf = '[';
|
||||||
$cnt = 0;
|
$cnt = 0;
|
||||||
foreach( $objs as $obj ) {
|
foreach ($objs as $obj) {
|
||||||
$val = pyjslib_printWorker($obj, $nl, false, $depth + 1);
|
$val = pyjslib_printWorker($obj, $nl, false, $depth + 1);
|
||||||
if( $cnt ++ > 0 ) {
|
if ($cnt++ > 0) {
|
||||||
$buf .= ', ';
|
$buf .= ', ';
|
||||||
}
|
}
|
||||||
$buf .= $val;
|
$buf .= $val;
|
||||||
}
|
}
|
||||||
$buf .= "]";
|
$buf .= ']';
|
||||||
// $buf = '[' . implode( ", ", $objs ) . ']';
|
// $buf = '[' . implode( ", ", $objs ) . ']';
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
$buf = $objs;
|
$buf = $objs;
|
||||||
}
|
}
|
||||||
if( $depth == 1 && (!strlen($buf) || $buf[strlen($buf)-1] != "\n") ) {
|
if ($depth == 1 && (!strlen($buf) || $buf[strlen($buf) - 1] != "\n")) {
|
||||||
$buf .= $nl ? "\n" : " ";
|
$buf .= $nl ? "\n" : ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
return $buf;
|
return $buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
function pyjslib_repr($obj) {
|
function pyjslib_repr($obj)
|
||||||
|
{
|
||||||
return pyjslib_printWorker($obj, false, false);
|
return pyjslib_printWorker($obj, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function pyjslib_print($objs, $multi_arg=false) {
|
function pyjslib_print($objs, $multi_arg = false)
|
||||||
|
{
|
||||||
echo pyjslib_printWorker($objs, false, $multi_arg);
|
echo pyjslib_printWorker($objs, false, $multi_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
function pyjslib_printnl($objs, $multi_arg=false) {
|
function pyjslib_printnl($objs, $multi_arg = false)
|
||||||
|
{
|
||||||
echo pyjslib_printWorker($objs, true, $multi_arg);
|
echo pyjslib_printWorker($objs, true, $multi_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
function py2php_kwargs_function_call($funcname, $ordered, $named) {
|
function py2php_kwargs_function_call($funcname, $ordered, $named)
|
||||||
|
{
|
||||||
if( $funcname == 'array' || $funcname == 'pyjslib_dict' ) {
|
if ($funcname == 'array' || $funcname == 'pyjslib_dict') {
|
||||||
return $named;
|
return $named;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,58 +294,62 @@ function py2php_kwargs_function_call($funcname, $ordered, $named) {
|
|||||||
$count = 1;
|
$count = 1;
|
||||||
|
|
||||||
$refFunc = new ReflectionFunction($funcname);
|
$refFunc = new ReflectionFunction($funcname);
|
||||||
foreach( $refFunc->getParameters() as $param ){
|
foreach ($refFunc->getParameters() as $param) {
|
||||||
if( $param->isVariadic() ) {
|
if ($param->isVariadic()) {
|
||||||
$ordered[$count-1] = $named;
|
$ordered[$count - 1] = $named;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//invokes ReflectionParameter::__toString
|
//invokes ReflectionParameter::__toString
|
||||||
if( $count > $num_ordered ) {
|
if ($count > $num_ordered) {
|
||||||
$name = $param->name;
|
$name = $param->name;
|
||||||
$default = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null;
|
$default = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null;
|
||||||
$ordered[] = @$named[$name] ?: $default;
|
$ordered[] = @$named[$name] ?: $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
$count ++;
|
$count++;
|
||||||
}
|
}
|
||||||
//var_dump($ordered);
|
//var_dump($ordered);
|
||||||
return call_user_func_array($funcname, $ordered);
|
return call_user_func_array($funcname, $ordered);
|
||||||
}
|
}
|
||||||
|
|
||||||
function py2php_kwargs_method_call( $obj, $method, $ordered, $named ) {
|
function py2php_kwargs_method_call($obj, $method, $ordered, $named)
|
||||||
|
{
|
||||||
$num_ordered = count($ordered);
|
$num_ordered = count($ordered);
|
||||||
$count = 1;
|
$count = 1;
|
||||||
|
|
||||||
$refFunc = new ReflectionMethod($obj, $method);
|
$refFunc = new ReflectionMethod($obj, $method);
|
||||||
foreach( $refFunc->getParameters() as $param ){
|
foreach ($refFunc->getParameters() as $param) {
|
||||||
//invokes ReflectionParameter::__toString
|
//invokes ReflectionParameter::__toString
|
||||||
if( $count > $num_ordered ) {
|
if ($count > $num_ordered) {
|
||||||
$name = $param->name;
|
$name = $param->name;
|
||||||
$default = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null;
|
$default = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null;
|
||||||
$ordered[] = @$named[$name] ?: $default;
|
$ordered[] = @$named[$name] ?: $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
$count ++;
|
$count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
$callable = [$obj, $method];
|
$callable = [$obj, $method];
|
||||||
|
|
||||||
return call_user_func_array($callable, $ordered);
|
return call_user_func_array($callable, $ordered);
|
||||||
}
|
}
|
||||||
|
|
||||||
class IOError extends Exception{
|
class IOError extends Exception
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
class ValueError extends Exception{
|
class ValueError extends Exception
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function pyjslib_open( $name, $mode="r", $buffering=null ) {
|
function pyjslib_open($name, $mode = 'r', $buffering = null)
|
||||||
return new pyjslib_file( $name, $mode, $buffering );
|
{
|
||||||
|
return new pyjslib_file($name, $mode, $buffering);
|
||||||
}
|
}
|
||||||
|
|
||||||
class pyjslib_file implements Iterator {
|
class pyjslib_file implements Iterator
|
||||||
|
{
|
||||||
private $fh = false;
|
private $fh = false;
|
||||||
private $current_line = null;
|
private $current_line = null;
|
||||||
|
|
||||||
@ -349,138 +361,160 @@ class pyjslib_file implements Iterator {
|
|||||||
public $newlines = null;
|
public $newlines = null;
|
||||||
public $softspace = false;
|
public $softspace = false;
|
||||||
|
|
||||||
function __construct($name_or_fd, $mode="r", $buffering=null) {
|
public function __construct($name_or_fd, $mode = 'r', $buffering = null)
|
||||||
if( is_resource($name_or_fd) ) {
|
{
|
||||||
|
if (is_resource($name_or_fd)) {
|
||||||
$this->fh = $name_or_fd;
|
$this->fh = $name_or_fd;
|
||||||
$this->closed = false;
|
$this->closed = false;
|
||||||
$meta = stream_get_meta_data( $name_or_df );
|
$meta = stream_get_meta_data($name_or_df);
|
||||||
$this->mode = $meta['mode'];
|
$this->mode = $meta['mode'];
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$name = $name_or_fd;
|
$name = $name_or_fd;
|
||||||
try {
|
try {
|
||||||
$this->fh = fopen($name, $mode);
|
$this->fh = fopen($name, $mode);
|
||||||
if( !$this->fh ) {
|
if (!$this->fh) {
|
||||||
throw new Exception("Could not open $name");
|
throw new Exception("Could not open $name");
|
||||||
}
|
}
|
||||||
$this->closed = false;
|
$this->closed = false;
|
||||||
$this->mode = $mode;
|
$this->mode = $mode;
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch( Exception $e ) {
|
throw new IOError($e->getMessage(), $e->getCode());
|
||||||
throw new IOError( $e->getMessage(), $e->getCode() );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function close()
|
||||||
|
{
|
||||||
function close() {
|
if ($this->fh) {
|
||||||
if( $this->fh ) {
|
fclose($this->fh);
|
||||||
fclose( $this->fh );
|
|
||||||
$this->fh = null;
|
$this->fh = null;
|
||||||
$this->closed = true;
|
$this->closed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function flush() {
|
public function flush()
|
||||||
if( !$this->fh ) {
|
{
|
||||||
throw new ValueError("File is closed.");
|
if (!$this->fh) {
|
||||||
|
throw new ValueError('File is closed.');
|
||||||
}
|
}
|
||||||
fflush( $this->fh );
|
fflush($this->fh);
|
||||||
}
|
}
|
||||||
|
|
||||||
function fileno() {
|
public function fileno()
|
||||||
if( !$this->fh ) {
|
{
|
||||||
throw new ValueError("File is closed.");
|
if (!$this->fh) {
|
||||||
|
throw new ValueError('File is closed.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->fh;
|
return $this->fh;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isatty() {
|
public function isatty()
|
||||||
if( !$this->fh ) {
|
{
|
||||||
throw new ValueError("File is closed.");
|
if (!$this->fh) {
|
||||||
|
throw new ValueError('File is closed.');
|
||||||
}
|
}
|
||||||
return posix_isatty( $this->fh );
|
|
||||||
|
return posix_isatty($this->fh);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---
|
/* ---
|
||||||
* Begin PHP Iterator implementation
|
* Begin PHP Iterator implementation
|
||||||
* ---
|
* ---
|
||||||
*/
|
*/
|
||||||
function rewind() {
|
public function rewind()
|
||||||
fseek( $this->fh, 0 );
|
{
|
||||||
|
fseek($this->fh, 0);
|
||||||
$this->line = 0;
|
$this->line = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function current() {
|
public function current()
|
||||||
if( !$this->current_line ) {
|
{
|
||||||
$this->current_line = fgets( $this->fh );
|
if (!$this->current_line) {
|
||||||
|
$this->current_line = fgets($this->fh);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->current_line;
|
return $this->current_line;
|
||||||
}
|
}
|
||||||
|
|
||||||
function key() {
|
public function key()
|
||||||
|
{
|
||||||
return $this->line;
|
return $this->line;
|
||||||
}
|
}
|
||||||
|
|
||||||
function next() {
|
public function next()
|
||||||
|
{
|
||||||
$this->current(); // ensure current line has been retrieved.
|
$this->current(); // ensure current line has been retrieved.
|
||||||
$this->current_line = fgets( $this->fh );
|
$this->current_line = fgets($this->fh);
|
||||||
$this->line ++;
|
$this->line++;
|
||||||
|
|
||||||
return $this->current_line;
|
return $this->current_line;
|
||||||
}
|
}
|
||||||
|
|
||||||
function valid() {
|
public function valid()
|
||||||
return $this->fh != false && !feof( $this->fh );
|
{
|
||||||
|
return $this->fh != false && !feof($this->fh);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---
|
/* ---
|
||||||
* End PHP Iterator implementation
|
* End PHP Iterator implementation
|
||||||
* ---
|
* ---
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function read($size=null) {
|
public function read($size = null)
|
||||||
if( $size !== null) {
|
{
|
||||||
return fread( $this->fh, $size);
|
if ($size !== null) {
|
||||||
}
|
return fread($this->fh, $size);
|
||||||
return stream_get_contents( $this->fh );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function readline($size=null) {
|
return stream_get_contents($this->fh);
|
||||||
return fgets( $this->fh, $size );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function readlines($sizehint=null) {
|
public function readline($size = null)
|
||||||
|
{
|
||||||
|
return fgets($this->fh, $size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function readlines($sizehint = null)
|
||||||
|
{
|
||||||
$len = 0;
|
$len = 0;
|
||||||
$lines = array();
|
$lines = [];
|
||||||
while( $line = fgets( $this->fh ) ) {
|
while ($line = fgets($this->fh)) {
|
||||||
$len += strlen( $line );
|
$len += strlen($line);
|
||||||
$lines[] = $line;
|
$lines[] = $line;
|
||||||
if( $sizehint && $len >= $sizehint ) {
|
if ($sizehint && $len >= $sizehint) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $lines;
|
return $lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
function seek($offset, $whence=SEEK_SET) {
|
public function seek($offset, $whence = SEEK_SET)
|
||||||
return fseek( $this->fh, $offset, $whence);
|
{
|
||||||
|
return fseek($this->fh, $offset, $whence);
|
||||||
}
|
}
|
||||||
|
|
||||||
function tell() {
|
public function tell()
|
||||||
|
{
|
||||||
return ftell($this->fh);
|
return ftell($this->fh);
|
||||||
}
|
}
|
||||||
|
|
||||||
function truncate( $size ) {
|
public function truncate($size)
|
||||||
$rc = ftruncate( $this->fh, $size );
|
{
|
||||||
|
$rc = ftruncate($this->fh, $size);
|
||||||
}
|
}
|
||||||
|
|
||||||
function write( $str ) {
|
public function write($str)
|
||||||
fwrite( $this->fh, $str );
|
{
|
||||||
|
fwrite($this->fh, $str);
|
||||||
}
|
}
|
||||||
|
|
||||||
function writelines($sequence) {
|
public function writelines($sequence)
|
||||||
foreach($sequence as $line) {
|
{
|
||||||
$this->write( $line );
|
foreach ($sequence as $line) {
|
||||||
|
$this->write($line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
425
libpy2php/os.php
425
libpy2php/os.php
@ -1,11 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
class OSError extends Exception{
|
class OSError extends Exception
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class os {
|
class os
|
||||||
|
{
|
||||||
const F_OK = 0x0001;
|
const F_OK = 0x0001;
|
||||||
const R_OK = 0x0002;
|
const R_OK = 0x0002;
|
||||||
const W_OK = 0x0004;
|
const W_OK = 0x0004;
|
||||||
@ -47,524 +48,636 @@ class os {
|
|||||||
public $environ;
|
public $environ;
|
||||||
public $pathconf_names = [];
|
public $pathconf_names = [];
|
||||||
|
|
||||||
static public function ctermid() {
|
public static function ctermid()
|
||||||
|
{
|
||||||
return posix_ctermid();
|
return posix_ctermid();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function getegid() {
|
public static function getegid()
|
||||||
|
{
|
||||||
return posix_getegid();
|
return posix_getegid();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function geteuid() {
|
public static function geteuid()
|
||||||
|
{
|
||||||
return posix_geteuid();
|
return posix_geteuid();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function getgid() {
|
public static function getgid()
|
||||||
|
{
|
||||||
return posix_getgid();
|
return posix_getgid();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function getgroups() {
|
public static function getgroups()
|
||||||
|
{
|
||||||
return posix_getgroups();
|
return posix_getgroups();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function initgroups($username, $gid) {
|
public static function initgroups($username, $gid)
|
||||||
|
{
|
||||||
return posix_initgroups($username, $gid);
|
return posix_initgroups($username, $gid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function getlogin() {
|
public static function getlogin()
|
||||||
|
{
|
||||||
return posix_getlogin();
|
return posix_getlogin();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function getpgid() {
|
public static function getpgid()
|
||||||
|
{
|
||||||
return posix_getpgid();
|
return posix_getpgid();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function getpgrp() {
|
public static function getpgrp()
|
||||||
|
{
|
||||||
return posix_getpgrp();
|
return posix_getpgrp();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function getpid() {
|
public static function getpid()
|
||||||
|
{
|
||||||
return posix_getpid();
|
return posix_getpid();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function getresuid() {
|
public static function getresuid()
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function getresgid() {
|
public static function getresgid()
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function getuid() {
|
public static function getuid()
|
||||||
|
{
|
||||||
return posix_getuid();
|
return posix_getuid();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function getenv($varname, $value=null) {
|
public static function getenv($varname, $value = null)
|
||||||
|
{
|
||||||
return getenv($varname, $value);
|
return getenv($varname, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function putenv($varname, $value) {
|
public static function putenv($varname, $value)
|
||||||
|
{
|
||||||
putenv("$varname=$value");
|
putenv("$varname=$value");
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function setegid($egid) {
|
public static function setegid($egid)
|
||||||
|
{
|
||||||
posix_setegid($egid);
|
posix_setegid($egid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function seteuid($euid) {
|
public static function seteuid($euid)
|
||||||
|
{
|
||||||
posix_seteuid($euid);
|
posix_seteuid($euid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function setgid($gid) {
|
public static function setgid($gid)
|
||||||
|
{
|
||||||
posix_setgid($gid);
|
posix_setgid($gid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function setgroups($groups) {
|
public static function setgroups($groups)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function setpgrp() {
|
public static function setpgrp()
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function setpgid($pid, $pgrp) {
|
public static function setpgid($pid, $pgrp)
|
||||||
|
{
|
||||||
posix_setpgid($pid, $pgrp);
|
posix_setpgid($pid, $pgrp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function setregid($rgid, $egid) {
|
public static function setregid($rgid, $egid)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function setresgid($rgid, $egid, $sgid) {
|
public static function setresgid($rgid, $egid, $sgid)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function setresuid($ruid, $euid, $suid) {
|
public static function setresuid($ruid, $euid, $suid)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function setreuid($ruid, $euid) {
|
public static function setreuid($ruid, $euid)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function getsid($pid) {
|
public static function getsid($pid)
|
||||||
|
{
|
||||||
return posix_getsid();
|
return posix_getsid();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function setsid() {
|
public static function setsid()
|
||||||
|
{
|
||||||
posix_setsid();
|
posix_setsid();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function setuid($uid) {
|
public static function setuid($uid)
|
||||||
|
{
|
||||||
posix_setuid($uid);
|
posix_setuid($uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function strerror($code) {
|
public static function strerror($code)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function umask($mask) {
|
public static function umask($mask)
|
||||||
|
{
|
||||||
umask($mask);
|
umask($mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function uname() {
|
public static function uname()
|
||||||
|
{
|
||||||
return posix_uname();
|
return posix_uname();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function unsetenv($varname) {
|
public static function unsetenv($varname)
|
||||||
|
{
|
||||||
unset($_ENV[$varname]);
|
unset($_ENV[$varname]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function fdopen($fd, $mode=null, $bufsize=null) {
|
public static function fdopen($fd, $mode = null, $bufsize = null)
|
||||||
|
{
|
||||||
return new pyjslib_file($fd);
|
return new pyjslib_file($fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function popen($command, $mode=null, $bufsize=null) {
|
public static function popen($command, $mode = null, $bufsize = null)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function tmpfile() {
|
public static function tmpfile()
|
||||||
|
{
|
||||||
return tmpfile();
|
return tmpfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function popen2($cmd, $mode=null, $bufsize=null) {
|
public static function popen2($cmd, $mode = null, $bufsize = null)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function popen3($cmd, $mode=null, $bufsize=null) {
|
public static function popen3($cmd, $mode = null, $bufsize = null)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function popen4($cmd, $mode=null, $bufsize=null) {
|
public static function popen4($cmd, $mode = null, $bufsize = null)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function close($fd) {
|
public static function close($fd)
|
||||||
fclose( $fd );
|
{
|
||||||
|
fclose($fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function closerange($fd_low, $fd_high) {
|
public static function closerange($fd_low, $fd_high)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function dup($fd) {
|
public static function dup($fd)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function dup2($fd) {
|
public static function dup2($fd)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function fchmod($fd, $mode) {
|
public static function fchmod($fd, $mode)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function fchown($fd, $uid, $gid) {
|
public static function fchown($fd, $uid, $gid)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function fdatasync($fd) {
|
public static function fdatasync($fd)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function fpathconf($fd, $name) {
|
public static function fpathconf($fd, $name)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function fstat($fd) {
|
public static function fstat($fd)
|
||||||
|
{
|
||||||
$info = fstat($fd);
|
$info = fstat($fd);
|
||||||
$obj = new stdClass;
|
$obj = new stdClass();
|
||||||
foreach($arr as $key => $v) {
|
foreach ($arr as $key => $v) {
|
||||||
$attr = "st_" . $key;
|
$attr = 'st_'.$key;
|
||||||
$obj->$attr = $v;
|
$obj->$attr = $v;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $obj;
|
return $obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function fstatvfs($fd) {
|
public static function fstatvfs($fd)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function fsync($fd) {
|
public static function fsync($fd)
|
||||||
|
{
|
||||||
fsync($fd);
|
fsync($fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function ftruncate($fd, $length) {
|
public static function ftruncate($fd, $length)
|
||||||
|
{
|
||||||
ftruncate($fd, $length);
|
ftruncate($fd, $length);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function isatty($fd) {
|
public static function isatty($fd)
|
||||||
return posix_isatty( $fd );
|
{
|
||||||
|
return posix_isatty($fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function lseek($fd, $pos, $how) {
|
public static function lseek($fd, $pos, $how)
|
||||||
|
{
|
||||||
lseek($fd, $pos, $how);
|
lseek($fd, $pos, $how);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function open($file, $flags, $mode=0777) {
|
public static function open($file, $flags, $mode = 0777)
|
||||||
|
{
|
||||||
// todo: define and map flag constants. See list at:
|
// todo: define and map flag constants. See list at:
|
||||||
// https://docs.python.org/2/library/os.html#open-flag-constants
|
// https://docs.python.org/2/library/os.html#open-flag-constants
|
||||||
|
|
||||||
$fl = '';
|
$fl = '';
|
||||||
if( $flags & self::O_RDONLY ) {
|
if ($flags & self::O_RDONLY) {
|
||||||
$fl .= 'r';
|
$fl .= 'r';
|
||||||
}
|
}
|
||||||
if( $flags & self::O_WRONLY ) {
|
if ($flags & self::O_WRONLY) {
|
||||||
$fl .= 'w';
|
$fl .= 'w';
|
||||||
}
|
}
|
||||||
if( $flags & self::O_RDWR ) {
|
if ($flags & self::O_RDWR) {
|
||||||
$fl .= 'rw';
|
$fl .= 'rw';
|
||||||
}
|
}
|
||||||
if( $flags & self::O_APPEND ) {
|
if ($flags & self::O_APPEND) {
|
||||||
$fl .= 'a';
|
$fl .= 'a';
|
||||||
}
|
}
|
||||||
if( $flags & self::O_CREAT ) {
|
if ($flags & self::O_CREAT) {
|
||||||
$fl .= 'c';
|
$fl .= 'c';
|
||||||
}
|
}
|
||||||
if( $flags & self::O_EXCL ) {
|
if ($flags & self::O_EXCL) {
|
||||||
$fl .= 'x';
|
$fl .= 'x';
|
||||||
}
|
}
|
||||||
if( $flags & self::O_TRUNC ) {
|
if ($flags & self::O_TRUNC) {
|
||||||
$fl .= 'w';
|
$fl .= 'w';
|
||||||
}
|
}
|
||||||
|
|
||||||
return fopen($file, $fl, false );
|
return fopen($file, $fl, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function pipe() {
|
public static function pipe()
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function read($fd, $n) {
|
public static function read($fd, $n)
|
||||||
return fread( $fd, $n );
|
{
|
||||||
|
return fread($fd, $n);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function tcgetpgrp($fd) {
|
public static function tcgetpgrp($fd)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function tcsetpgrp($fd, $pg) {
|
public static function tcsetpgrp($fd, $pg)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function ttyname($fd) {
|
public static function ttyname($fd)
|
||||||
|
{
|
||||||
return posix_ttyname($fd);
|
return posix_ttyname($fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function write($fd, $str) {
|
public static function write($fd, $str)
|
||||||
return fwrite( $fd, $str );
|
{
|
||||||
|
return fwrite($fd, $str);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function access($path, $mode) {
|
public static function access($path, $mode)
|
||||||
|
{
|
||||||
return posix_access($path, $mode);
|
return posix_access($path, $mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function chdir($path) {
|
public static function chdir($path)
|
||||||
chdir( $path );
|
{
|
||||||
|
chdir($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function fchdir($path) {
|
public static function fchdir($path)
|
||||||
fchdir( $path );
|
{
|
||||||
|
fchdir($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function getcwd() {
|
public static function getcwd()
|
||||||
|
{
|
||||||
return getcwd();
|
return getcwd();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function getcwdu() {
|
public static function getcwdu()
|
||||||
|
{
|
||||||
return getcwd();
|
return getcwd();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function chflags($path, $flags) {
|
public static function chflags($path, $flags)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function chroot($path) {
|
public static function chroot($path)
|
||||||
|
{
|
||||||
chroot($path);
|
chroot($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function chmode($path, $mode) {
|
public static function chmode($path, $mode)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function chown($path, $uid, $gid) {
|
public static function chown($path, $uid, $gid)
|
||||||
|
{
|
||||||
chown($path, $uid, $gid);
|
chown($path, $uid, $gid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function lchflags($path, $flags) {
|
public static function lchflags($path, $flags)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function lchmod($path, $mode) {
|
public static function lchmod($path, $mode)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function lchown($path, $uid, $gid) {
|
public static function lchown($path, $uid, $gid)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function link($source, $link_name) {
|
public static function link($source, $link_name)
|
||||||
|
{
|
||||||
link($source, $link_name);
|
link($source, $link_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function listdir($path) {
|
public static function listdir($path)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function lstat($path) {
|
public static function lstat($path)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function mkfifo($path, $mode=0666) {
|
public static function mkfifo($path, $mode = 0666)
|
||||||
|
{
|
||||||
posix_mkfifo($path, $mode);
|
posix_mkfifo($path, $mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function mknod($filename, $mode=0666, $device=0) {
|
public static function mknod($filename, $mode = 0666, $device = 0)
|
||||||
return posix_mknod( $filename, $mode );
|
{
|
||||||
|
return posix_mknod($filename, $mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function major($path, $flags) {
|
public static function major($path, $flags)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function minor($path, $flags) {
|
public static function minor($path, $flags)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function makedev($major, $minor) {
|
public static function makedev($major, $minor)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function mkdir($path, $mode=0777) {
|
public static function mkdir($path, $mode = 0777)
|
||||||
mkdir($path, $mode, $recursive=false);
|
{
|
||||||
|
mkdir($path, $mode, $recursive = false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function makedirs($path, $mode=0777) {
|
public static function makedirs($path, $mode = 0777)
|
||||||
mkdir($path, $mode, $recursive=true);
|
{
|
||||||
|
mkdir($path, $mode, $recursive = true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function pathconf($path, $name) {
|
public static function pathconf($path, $name)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function readlink($path) {
|
public static function readlink($path)
|
||||||
|
{
|
||||||
return readlink($path);
|
return readlink($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function remove($path) {
|
public static function remove($path)
|
||||||
if( !is_file( $path ) ) {
|
{
|
||||||
|
if (!is_file($path)) {
|
||||||
throw new OSError("Path is not a file. $path");
|
throw new OSError("Path is not a file. $path");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
unlink( $path );
|
unlink($path);
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch( Exception $e ) {
|
throw new OSError($e->getMessage(), $e->getCode());
|
||||||
throw new OSError( $e->getMessage(), $e->getCode() );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static function removedirs($path) {
|
public static function removedirs($path)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function rename($src, $dst) {
|
public static function rename($src, $dst)
|
||||||
if( is_dir($dst)) {
|
{
|
||||||
|
if (is_dir($dst)) {
|
||||||
throw new OSError("Destination is a directory. $dst");
|
throw new OSError("Destination is a directory. $dst");
|
||||||
}
|
}
|
||||||
rename($src, $dst);
|
rename($src, $dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function renames($old, $new) {
|
public static function renames($old, $new)
|
||||||
self::makedirs( dirname($new) );
|
{
|
||||||
|
self::makedirs(dirname($new));
|
||||||
self::rename($old, $new);
|
self::rename($old, $new);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function rmdir($path) {
|
public static function rmdir($path)
|
||||||
|
{
|
||||||
rmdir($pat);
|
rmdir($pat);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function stat($path) {
|
public static function stat($path)
|
||||||
|
{
|
||||||
$arr = stat($path);
|
$arr = stat($path);
|
||||||
if(!$arr) {
|
if (!$arr) {
|
||||||
throw new OSError("Path does not exist. $path");
|
throw new OSError("Path does not exist. $path");
|
||||||
}
|
}
|
||||||
$obj = new stdClass;
|
$obj = new stdClass();
|
||||||
foreach($arr as $key => $v) {
|
foreach ($arr as $key => $v) {
|
||||||
$attr = "st_" . $key;
|
$attr = 'st_'.$key;
|
||||||
$obj->$attr = $v;
|
$obj->$attr = $v;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $obj;
|
return $obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
static function stat_float_times($newvalue=null) {
|
public static function stat_float_times($newvalue = null)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function statvfs() {
|
public static function statvfs()
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function symlink($source, $link_name) {
|
public static function symlink($source, $link_name)
|
||||||
|
{
|
||||||
symlink($source, $link_name);
|
symlink($source, $link_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function tempnam($dir=null, $prefix='') {
|
public static function tempnam($dir = null, $prefix = '')
|
||||||
if( !$dir ) {
|
{
|
||||||
$dir = sys_get_temp_dir() ;
|
if (!$dir) {
|
||||||
|
$dir = sys_get_temp_dir();
|
||||||
}
|
}
|
||||||
$name = tempnam($dir, $prefix);
|
$name = tempnam($dir, $prefix);
|
||||||
unlink($name);
|
unlink($name);
|
||||||
|
|
||||||
return $name;
|
return $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static function tmpnam() {
|
public static function tmpnam()
|
||||||
|
{
|
||||||
return self::tempnam();
|
return self::tempnam();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function unlink($path) {
|
public static function unlink($path)
|
||||||
|
{
|
||||||
unlink($path);
|
unlink($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function utime($path, $times) {
|
public static function utime($path, $times)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function walk($top, $topdown=true, $onerror=null, $followlinks=false) {
|
public static function walk($top, $topdown = true, $onerror = null, $followlinks = false)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Begin Process Management
|
* Begin Process Management.
|
||||||
*/
|
*/
|
||||||
|
public static function abort()
|
||||||
static function abort() {
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function execl($path, $arg0, $arg1) {
|
public static function execl($path, $arg0, $arg1)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function execle($path, $arg0, $arg1, $env) {
|
public static function execle($path, $arg0, $arg1, $env)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function execlp($file, $arg0, $arg1) {
|
public static function execlp($file, $arg0, $arg1)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function execlpe($file, $arg0, $arg1, $env) {
|
public static function execlpe($file, $arg0, $arg1, $env)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function execv($path, $args) {
|
public static function execv($path, $args)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function execve($path, $args, $env) {
|
public static function execve($path, $args, $env)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function execvp($file, $args) {
|
public static function execvp($file, $args)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function execvpe($file, $args, $env) {
|
public static function execvpe($file, $args, $env)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function _exit($n) {
|
public static function _exit($n)
|
||||||
|
{
|
||||||
exit($n);
|
exit($n);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function fork() {
|
public static function fork()
|
||||||
|
{
|
||||||
return pcntl_fork();
|
return pcntl_fork();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function forkpty() {
|
public static function forkpty()
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function kill($pid, $sig) {
|
public static function kill($pid, $sig)
|
||||||
|
{
|
||||||
posix_kill($pid, $sig);
|
posix_kill($pid, $sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function killpg($pgid, $sig) {
|
public static function killpg($pgid, $sig)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function nice($increment) {
|
public static function nice($increment)
|
||||||
|
{
|
||||||
proc_nice($increment);
|
proc_nice($increment);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function plock($op) {
|
public static function plock($op)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static function _unimplemented()
|
||||||
|
{
|
||||||
private static function _unimplemented() {
|
throw new Exception('Unimplemented. Please consider submitting a patch to py2php project on github.');
|
||||||
throw new Exception( "Unimplemented. Please consider submitting a patch to py2php project on github.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,214 +1,251 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once(dirname(__FILE__) . '/os.php');
|
require_once dirname(__FILE__).'/os.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class to emulate python's os.path
|
* A class to emulate python's os.path.
|
||||||
*/
|
*/
|
||||||
class os_path {
|
class os_path
|
||||||
|
{
|
||||||
const supports_unicode_filenames = true;
|
const supports_unicode_filenames = true;
|
||||||
|
|
||||||
static function abspath($path) {
|
public static function abspath($path)
|
||||||
|
{
|
||||||
return self::normpath(self::join(getcwd(), $path));
|
return self::normpath(self::join(getcwd(), $path));
|
||||||
}
|
}
|
||||||
|
|
||||||
static function basename($path) {
|
public static function basename($path)
|
||||||
|
{
|
||||||
// is this right?
|
// is this right?
|
||||||
return basename($path);
|
return basename($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function commonprefix($list) {
|
public static function commonprefix($list)
|
||||||
|
{
|
||||||
$pl = 0; // common prefix length
|
$pl = 0; // common prefix length
|
||||||
$n = count($list);
|
$n = count($list);
|
||||||
$l = strlen($list[0]);
|
$l = strlen($list[0]);
|
||||||
while ($pl < $l) {
|
while ($pl < $l) {
|
||||||
$c = $list[0][$pl];
|
$c = $list[0][$pl];
|
||||||
for ($i=1; $i<$n; $i++) {
|
for ($i = 1; $i < $n; $i++) {
|
||||||
if ($list[$i][$pl] !== $c) {
|
if ($list[$i][$pl] !== $c) {
|
||||||
break 2;
|
break 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$pl++;
|
$pl++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return substr($list[0], 0, $pl);
|
return substr($list[0], 0, $pl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function dirname($path) {
|
public static function dirname($path)
|
||||||
|
{
|
||||||
return dirname($path);
|
return dirname($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function exists($path) {
|
public static function exists($path)
|
||||||
|
{
|
||||||
return file_exists($path);
|
return file_exists($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function lexists($path) {
|
public static function lexists($path)
|
||||||
|
{
|
||||||
$rc = file_exists($path);
|
$rc = file_exists($path);
|
||||||
if( !$rc && is_link($path) ) {
|
if (!$rc && is_link($path)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $rc;
|
return $rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static function expanduser($path) {
|
public static function expanduser($path)
|
||||||
if( strpos($path, '~') !== false) {
|
{
|
||||||
|
if (strpos($path, '~') !== false) {
|
||||||
$info = posix_getpwuid(posix_getuid());
|
$info = posix_getpwuid(posix_getuid());
|
||||||
$path = str_replace('~', $info['dir'], $path);
|
$path = str_replace('~', $info['dir'], $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $path;
|
return $path;
|
||||||
}
|
}
|
||||||
|
|
||||||
static function expandvars($path) {
|
public static function expandvars($path)
|
||||||
|
{
|
||||||
$env = count($_ENV) ?: $_SERVER;
|
$env = count($_ENV) ?: $_SERVER;
|
||||||
$map = array();
|
$map = [];
|
||||||
foreach( $env as $k => $v ) {
|
foreach ($env as $k => $v) {
|
||||||
if( !is_scalar( $v )) {
|
if (!is_scalar($v)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$map['$' . $k] = $v;
|
$map['$'.$k] = $v;
|
||||||
$map['${' . $k . '}'] = $v;
|
$map['${'.$k.'}'] = $v;
|
||||||
}
|
}
|
||||||
|
|
||||||
return strtr($path, $map);
|
return strtr($path, $map);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function getatime($path) {
|
public static function getatime($path)
|
||||||
|
{
|
||||||
try {
|
try {
|
||||||
$rc = fileatime($path);
|
$rc = fileatime($path);
|
||||||
|
|
||||||
return $rc;
|
return $rc;
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch( Exception $e ) {
|
|
||||||
throw new OSError($e->getMessage, $e->getCode());
|
throw new OSError($e->getMessage, $e->getCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static function getmtime($path) {
|
public static function getmtime($path)
|
||||||
|
{
|
||||||
try {
|
try {
|
||||||
$rc = filemtime($path);
|
$rc = filemtime($path);
|
||||||
|
|
||||||
return $rc;
|
return $rc;
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch( Exception $e ) {
|
|
||||||
throw new OSError($e->getMessage, $e->getCode());
|
throw new OSError($e->getMessage, $e->getCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static function getctime($path) {
|
public static function getctime($path)
|
||||||
|
{
|
||||||
try {
|
try {
|
||||||
$rc = filectime($path);
|
$rc = filectime($path);
|
||||||
|
|
||||||
return $rc;
|
return $rc;
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch( Exception $e ) {
|
|
||||||
throw new OSError($e->getMessage, $e->getCode());
|
throw new OSError($e->getMessage, $e->getCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static function getsize($path) {
|
public static function getsize($path)
|
||||||
|
{
|
||||||
try {
|
try {
|
||||||
$rc = filesize($path);
|
$rc = filesize($path);
|
||||||
|
|
||||||
return $rc;
|
return $rc;
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch( Exception $e ) {
|
|
||||||
throw new OSError($e->getMessage, $e->getCode());
|
throw new OSError($e->getMessage, $e->getCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static function isabs($path) {
|
public static function isabs($path)
|
||||||
|
{
|
||||||
// fixme: implement check for windows.
|
// fixme: implement check for windows.
|
||||||
return $path[0] == '/';
|
return $path[0] == '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
static function isfile($path) {
|
public static function isfile($path)
|
||||||
|
{
|
||||||
return is_file($path);
|
return is_file($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function isdir($path) {
|
public static function isdir($path)
|
||||||
|
{
|
||||||
return is_dir($path);
|
return is_dir($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function islink($path) {
|
public static function islink($path)
|
||||||
|
{
|
||||||
return is_link($path);
|
return is_link($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function ismount($path) {
|
public static function ismount($path)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function split($path) {
|
public static function split($path)
|
||||||
|
{
|
||||||
$parts = explode(DIRECTORY_SEPARATOR, $path);
|
$parts = explode(DIRECTORY_SEPARATOR, $path);
|
||||||
$first = implode(DIRECTORY_SEPARATOR, array_slice($parts, 0, count($parts)-1 ));
|
$first = implode(DIRECTORY_SEPARATOR, array_slice($parts, 0, count($parts) - 1));
|
||||||
$last = $parts[count($parts)-1];
|
$last = $parts[count($parts) - 1];
|
||||||
return array($first, $last);
|
|
||||||
|
return [$first, $last];
|
||||||
}
|
}
|
||||||
|
|
||||||
static function join($path, ...$paths) {
|
public static function join($path, ...$paths)
|
||||||
|
{
|
||||||
$buf = rtrim($path, '/');
|
$buf = rtrim($path, '/');
|
||||||
foreach( $paths as $p ) {
|
foreach ($paths as $p) {
|
||||||
$i = 0;
|
$i = 0;
|
||||||
$p = trim( $p, '/');
|
$p = trim($p, '/');
|
||||||
$buf .= DIRECTORY_SEPARATOR . $p;
|
$buf .= DIRECTORY_SEPARATOR.$p;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $buf;
|
return $buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static function normcase($path) {
|
public static function normcase($path)
|
||||||
|
{
|
||||||
// fixme: different behavior on windows.
|
// fixme: different behavior on windows.
|
||||||
return $path;
|
return $path;
|
||||||
}
|
}
|
||||||
|
|
||||||
static function normpath($path) {
|
public static function normpath($path)
|
||||||
|
{
|
||||||
return realpath($path);
|
return realpath($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function realpath($path) {
|
public static function realpath($path)
|
||||||
|
{
|
||||||
return realpath($path);
|
return realpath($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function relpath($path, $start) {
|
public static function relpath($path, $start)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function samefile($path1, $path2) {
|
public static function samefile($path1, $path2)
|
||||||
|
{
|
||||||
return fileinode($path1) == fileinode($path2);
|
return fileinode($path1) == fileinode($path2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function sameopenfile($fd1, $fd2) {
|
public static function sameopenfile($fd1, $fd2)
|
||||||
$s1 = fstat( $fd1 );
|
{
|
||||||
$s2 = fstat( $fd2 );
|
$s1 = fstat($fd1);
|
||||||
|
$s2 = fstat($fd2);
|
||||||
|
|
||||||
return $s1['ino'] == $s2['ino'];
|
return $s1['ino'] == $s2['ino'];
|
||||||
}
|
}
|
||||||
|
|
||||||
static function samestat($stat1, $stat2) {
|
public static function samestat($stat1, $stat2)
|
||||||
|
{
|
||||||
return $stat1 == $stat2;
|
return $stat1 == $stat2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static function splitdrive($path) {
|
public static function splitdrive($path)
|
||||||
|
{
|
||||||
//fixme: implement windows case.
|
//fixme: implement windows case.
|
||||||
return array('', $path);
|
return ['', $path];
|
||||||
}
|
}
|
||||||
|
|
||||||
static function splitext($path) {
|
public static function splitext($path)
|
||||||
|
{
|
||||||
$first = $path;
|
$first = $path;
|
||||||
$second = '';
|
$second = '';
|
||||||
|
|
||||||
$pos = strrpos( $path, '.');
|
$pos = strrpos($path, '.');
|
||||||
if( $pos !== false ) {
|
if ($pos !== false) {
|
||||||
$first = substr($path, 0, $pos);
|
$first = substr($path, 0, $pos);
|
||||||
$second = substr($path, $pos);
|
$second = substr($path, $pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
return array($first, $second);
|
return [$first, $second];
|
||||||
}
|
}
|
||||||
|
|
||||||
static function splitunc($path) {
|
public static function splitunc($path)
|
||||||
|
{
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function walk($path, $visit, $arg) {
|
public static function walk($path, $visit, $arg)
|
||||||
|
{
|
||||||
// Note: deprecated in python 3 in favor of os.walk()
|
// Note: deprecated in python 3 in favor of os.walk()
|
||||||
self::_unimplemented();
|
self::_unimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function _unimplemented() {
|
private static function _unimplemented()
|
||||||
throw new Exception( "Unimplemented. Please consider submitting a patch to py2php project on github.");
|
{
|
||||||
|
throw new Exception('Unimplemented. Please consider submitting a patch to py2php project on github.');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -7,18 +7,18 @@
|
|||||||
* It is called in this file; the parent php file(s) should use require_once and do
|
* It is called in this file; the parent php file(s) should use require_once and do
|
||||||
* not need to make any call.
|
* not need to make any call.
|
||||||
*/
|
*/
|
||||||
function init_strict_mode() {
|
function init_strict_mode()
|
||||||
|
{
|
||||||
|
|
||||||
// these are safe to call multiple times per process without dups.
|
// these are safe to call multiple times per process without dups.
|
||||||
error_reporting( E_ALL | E_STRICT );
|
error_reporting(E_ALL | E_STRICT);
|
||||||
restore_strict_error_handler();
|
restore_strict_error_handler();
|
||||||
restore_strict_exception_handler();
|
restore_strict_exception_handler();
|
||||||
|
|
||||||
// register_shutdown_function should only be called once per process to avoid dups.
|
// register_shutdown_function should only be called once per process to avoid dups.
|
||||||
static $called = false;
|
static $called = false;
|
||||||
if( !$called ) {
|
if (!$called) {
|
||||||
|
register_shutdown_function('shutdown_handler');
|
||||||
register_shutdown_function( "shutdown_handler" );
|
|
||||||
$called = true;
|
$called = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -28,19 +28,20 @@ function init_strict_mode() {
|
|||||||
* eg by a 3rd party lib. Any error handlers that were registered after
|
* eg by a 3rd party lib. Any error handlers that were registered after
|
||||||
* ours are removed.
|
* ours are removed.
|
||||||
*/
|
*/
|
||||||
function restore_strict_error_handler() {
|
function restore_strict_error_handler()
|
||||||
|
{
|
||||||
$e_handler_name = function() {
|
$e_handler_name = function () {
|
||||||
$name = set_error_handler('restore_strict_error_handler'); // will never be used.
|
$name = set_error_handler('restore_strict_error_handler'); // will never be used.
|
||||||
restore_error_handler();
|
restore_error_handler();
|
||||||
|
|
||||||
return $name;
|
return $name;
|
||||||
};
|
};
|
||||||
|
|
||||||
while( !in_array( $e_handler_name(), array( '_global_error_handler', null ) ) ) {
|
while (!in_array($e_handler_name(), ['_global_error_handler', null])) {
|
||||||
restore_error_handler();
|
restore_error_handler();
|
||||||
}
|
}
|
||||||
if( !$e_handler_name() ) {
|
if (!$e_handler_name()) {
|
||||||
set_error_handler( '_global_error_handler' );
|
set_error_handler('_global_error_handler');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,19 +50,20 @@ function restore_strict_error_handler() {
|
|||||||
* eg by a 3rd party lib. Any error handlers that were registered after
|
* eg by a 3rd party lib. Any error handlers that were registered after
|
||||||
* ours are removed.
|
* ours are removed.
|
||||||
*/
|
*/
|
||||||
function restore_strict_exception_handler() {
|
function restore_strict_exception_handler()
|
||||||
|
{
|
||||||
$exc_handler_name = function() {
|
$exc_handler_name = function () {
|
||||||
$name = set_exception_handler('restore_strict_exception_handler'); // will never be used.
|
$name = set_exception_handler('restore_strict_exception_handler'); // will never be used.
|
||||||
restore_exception_handler();
|
restore_exception_handler();
|
||||||
|
|
||||||
return $name;
|
return $name;
|
||||||
};
|
};
|
||||||
|
|
||||||
while( !in_array( $exc_handler_name(), array( '_global_exception_handler', null ) ) ) {
|
while (!in_array($exc_handler_name(), ['_global_exception_handler', null])) {
|
||||||
restore_exception_handler();
|
restore_exception_handler();
|
||||||
}
|
}
|
||||||
if( !$exc_handler_name() ) {
|
if (!$exc_handler_name()) {
|
||||||
set_exception_handler( '_global_exception_handler' );
|
set_exception_handler('_global_exception_handler');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +74,8 @@ function restore_strict_exception_handler() {
|
|||||||
*
|
*
|
||||||
* However, we allow the @operator in the code to override.
|
* However, we allow the @operator in the code to override.
|
||||||
*/
|
*/
|
||||||
function _global_error_handler($errno, $errstr, $errfile, $errline ) {
|
function _global_error_handler($errno, $errstr, $errfile, $errline)
|
||||||
|
{
|
||||||
|
|
||||||
/* from php.net
|
/* from php.net
|
||||||
* error_reporting() settings will have no effect and your error handler will
|
* error_reporting() settings will have no effect and your error handler will
|
||||||
@ -80,7 +83,7 @@ function _global_error_handler($errno, $errstr, $errfile, $errline ) {
|
|||||||
* error_reporting and act appropriately. Of particular note is that this value will
|
* error_reporting and act appropriately. Of particular note is that this value will
|
||||||
* be 0 if the statement that caused the error was prepended by the @ error-control operator.
|
* be 0 if the statement that caused the error was prepended by the @ error-control operator.
|
||||||
*/
|
*/
|
||||||
if( !error_reporting() ) {
|
if (!error_reporting()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,44 +94,45 @@ function _global_error_handler($errno, $errstr, $errfile, $errline ) {
|
|||||||
/***
|
/***
|
||||||
* This exception handler callback will be called for any exceptions that the application code does not catch.
|
* This exception handler callback will be called for any exceptions that the application code does not catch.
|
||||||
*/
|
*/
|
||||||
function _global_exception_handler( $e ) {
|
function _global_exception_handler($e)
|
||||||
$msg = sprintf( "\nUncaught Exception. code: %s, message: %s\n%s : %s\n\nStack Trace:\n%s\n", $e->getCode(), $e->getMessage(), $e->getFile(), $e->getLine(), $e->getTraceAsString() );
|
{
|
||||||
while( ( $e = $e->getPrevious() ) ) {
|
$msg = sprintf("\nUncaught Exception. code: %s, message: %s\n%s : %s\n\nStack Trace:\n%s\n", $e->getCode(), $e->getMessage(), $e->getFile(), $e->getLine(), $e->getTraceAsString());
|
||||||
$msg .= sprintf( "\nPrevious Exception. code: %s, message: %s\n%s : %s\n\nStack Trace:\n%s\n", $e->getCode(), $e->getMessage(), $e->getFile(), $e->getLine(), $e->getTraceAsString() );
|
while (($e = $e->getPrevious())) {
|
||||||
|
$msg .= sprintf("\nPrevious Exception. code: %s, message: %s\n%s : %s\n\nStack Trace:\n%s\n", $e->getCode(), $e->getMessage(), $e->getFile(), $e->getLine(), $e->getTraceAsString());
|
||||||
}
|
}
|
||||||
echo $msg;
|
echo $msg;
|
||||||
// error_log( $msg );
|
// error_log( $msg );
|
||||||
strict_mode_mail_admin( 'Uncaught exception!', $msg );
|
strict_mode_mail_admin('Uncaught exception!', $msg);
|
||||||
echo "\n\nNow exiting. Please report this problem to the software author\n\n";
|
echo "\n\nNow exiting. Please report this problem to the software author\n\n";
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This shutdown handler callback prints a message and sends email on any PHP fatal error
|
* This shutdown handler callback prints a message and sends email on any PHP fatal error.
|
||||||
*/
|
*/
|
||||||
function shutdown_handler() {
|
function shutdown_handler()
|
||||||
|
{
|
||||||
$error = error_get_last();
|
$error = error_get_last();
|
||||||
|
|
||||||
$ignore = E_WARNING | E_NOTICE | E_USER_WARNING | E_USER_NOTICE | E_STRICT | E_DEPRECATED | E_USER_DEPRECATED;
|
$ignore = E_WARNING | E_NOTICE | E_USER_WARNING | E_USER_NOTICE | E_STRICT | E_DEPRECATED | E_USER_DEPRECATED;
|
||||||
if ( $error && ($error['type'] & $ignore) == 0) {
|
if ($error && ($error['type'] & $ignore) == 0) {
|
||||||
|
|
||||||
// error keys: type, file, line, message
|
// error keys: type, file, line, message
|
||||||
$msg = "Ouch! Encountered PHP Fatal Error. Shutting down.\n" . print_r( $error, true );
|
$msg = "Ouch! Encountered PHP Fatal Error. Shutting down.\n".print_r($error, true);
|
||||||
echo $msg;
|
echo $msg;
|
||||||
strict_mode_mail_admin( 'PHP Fatal Error!', $msg );
|
strict_mode_mail_admin('PHP Fatal Error!', $msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* email admin if defined
|
* email admin if defined.
|
||||||
*/
|
*/
|
||||||
function strict_mode_mail_admin( $subject, $msg ) {
|
function strict_mode_mail_admin($subject, $msg)
|
||||||
$subject = sprintf( '[%s] [%s] %s [pid: %s]', gethostname(), basename($_SERVER['PHP_SELF']), $subject, getmypid() );
|
{
|
||||||
if( defined('ALERTS_MAIL_TO') ) {
|
$subject = sprintf('[%s] [%s] %s [pid: %s]', gethostname(), basename($_SERVER['PHP_SELF']), $subject, getmypid());
|
||||||
mail( ALERTS_MAIL_TO, $subject, $msg );
|
if (defined('ALERTS_MAIL_TO')) {
|
||||||
}
|
mail(ALERTS_MAIL_TO, $subject, $msg);
|
||||||
else {
|
} else {
|
||||||
echo "\nWARNING: ALERTS_MAIL_TO not defined in environment. alert not sent with subject: $subject\n";
|
echo "\nWARNING: ALERTS_MAIL_TO not defined in environment. alert not sent with subject: $subject\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
181
mtproto.php
181
mtproto.php
@ -1,25 +1,30 @@
|
|||||||
<?php
|
<?php
|
||||||
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libpy2php');
|
|
||||||
require_once ('libpy2php.php');
|
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
|
||||||
require_once ('os_path.php');
|
require_once 'libpy2php.php';
|
||||||
require_once ('crypt.php');
|
require_once 'os_path.php';
|
||||||
require_once ('prime.php');
|
require_once 'crypt.php';
|
||||||
require_once ('TL.php');
|
require_once 'prime.php';
|
||||||
require_once ('Struct.php');
|
require_once 'TL.php';
|
||||||
|
require_once 'Struct.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to get hex crc32
|
* Function to get hex crc32
|
||||||
* :param data: Data to encode
|
* :param data: Data to encode.
|
||||||
*/
|
*/
|
||||||
function newcrc32($data) {
|
function newcrc32($data)
|
||||||
return hexdec(hash("crc32b", $data));
|
{
|
||||||
|
return hexdec(hash('crc32b', $data));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to dump the hex version of a string.
|
* Function to dump the hex version of a string.
|
||||||
* :param what: What to dump
|
* :param what: What to dump.
|
||||||
*/
|
*/
|
||||||
function hex_dump($what) { var_dump(bin2hex($what)); };
|
function hex_dump($what)
|
||||||
|
{
|
||||||
|
var_dump(bin2hex($what));
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* len.
|
* len.
|
||||||
*
|
*
|
||||||
@ -40,22 +45,27 @@ function hex_dump($what) { var_dump(bin2hex($what)); };
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to visualize byte streams. Split into bytes, print to console.
|
* Function to visualize byte streams. Split into bytes, print to console.
|
||||||
* :param bs: BYTE STRING
|
* :param bs: BYTE STRING.
|
||||||
*/
|
*/
|
||||||
function vis($bs) {
|
function vis($bs)
|
||||||
|
{
|
||||||
$bs = str_split($bs);
|
$bs = str_split($bs);
|
||||||
$symbols_in_one_line = 8;
|
$symbols_in_one_line = 8;
|
||||||
$n = floor(len($bs) / $symbols_in_one_line);
|
$n = floor(len($bs) / $symbols_in_one_line);
|
||||||
$i = 0;
|
$i = 0;
|
||||||
foreach (pyjslib_range($n) as $i) {
|
foreach (pyjslib_range($n) as $i) {
|
||||||
echo $i * $symbols_in_one_line . ' | ' . join(' ',
|
echo $i * $symbols_in_one_line.' | '.implode(' ',
|
||||||
array_map(function($el) { return bin2hex($el); }, array_slice($bs,$i*$symbols_in_one_line, ($i+1)*$symbols_in_one_line))
|
array_map(function ($el) {
|
||||||
) . PHP_EOL;
|
return bin2hex($el);
|
||||||
|
}, array_slice($bs, $i * $symbols_in_one_line, ($i + 1) * $symbols_in_one_line))
|
||||||
|
).PHP_EOL;
|
||||||
}
|
}
|
||||||
if (!(len($bs) % $symbols_in_one_line == 0)) {
|
if (!(len($bs) % $symbols_in_one_line == 0)) {
|
||||||
echo ($i + 1) * $symbols_in_one_line . ' | ' . join(' ',
|
echo($i + 1) * $symbols_in_one_line.' | '.implode(' ',
|
||||||
array_map(function($el) { return bin2hex($el); }, array_slice($bs, ($i+1)*$symbols_in_one_line))
|
array_map(function ($el) {
|
||||||
) . PHP_EOL;
|
return bin2hex($el);
|
||||||
|
}, array_slice($bs, ($i + 1) * $symbols_in_one_line))
|
||||||
|
).PHP_EOL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -63,7 +73,8 @@ function vis($bs) {
|
|||||||
* Convert a byte string to a long integer.
|
* Convert a byte string to a long integer.
|
||||||
* This is (essentially) the inverse of long_to_bytes().
|
* This is (essentially) the inverse of long_to_bytes().
|
||||||
*/
|
*/
|
||||||
function bytes_to_long($s) {
|
function bytes_to_long($s)
|
||||||
|
{
|
||||||
$acc = 0;
|
$acc = 0;
|
||||||
$length = strlen($s);
|
$length = strlen($s);
|
||||||
if (($length % 4)) {
|
if (($length % 4)) {
|
||||||
@ -71,23 +82,28 @@ function bytes_to_long($s) {
|
|||||||
$s = (($b('') * $extra) + $s);
|
$s = (($b('') * $extra) + $s);
|
||||||
$length = ($length + $extra);
|
$length = ($length + $extra);
|
||||||
}
|
}
|
||||||
foreach( pyjslib_range(0, $length, 4) as $i ) {
|
foreach (pyjslib_range(0, $length, 4) as $i) {
|
||||||
$acc = ($acc << 32 + $this->struct->unpack('I', array_slice($s, $i, ($i + 4) - $i))[0]);
|
$acc = ($acc << 32 + $this->struct->unpack('I', array_slice($s, $i, ($i + 4) - $i))[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $acc;
|
return $acc;
|
||||||
}
|
}
|
||||||
|
|
||||||
function fread_all($handle) {
|
function fread_all($handle)
|
||||||
|
{
|
||||||
$pos = ftell($handle);
|
$pos = ftell($handle);
|
||||||
fseek($handle, 0);
|
fseek($handle, 0);
|
||||||
$content = fread($handle, fstat($handle)["size"]);
|
$content = fread($handle, fstat($handle)['size']);
|
||||||
fseek($handle, $pos);
|
fseek($handle, $pos);
|
||||||
|
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
function fopen_and_write($filename, $mode, $data) {
|
function fopen_and_write($filename, $mode, $data)
|
||||||
|
{
|
||||||
$handle = fopen($filename, $mode);
|
$handle = fopen($filename, $mode);
|
||||||
fwrite($handle, $data);
|
fwrite($handle, $data);
|
||||||
rewind($handle);
|
rewind($handle);
|
||||||
|
|
||||||
return $handle;
|
return $handle;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -97,14 +113,15 @@ function fopen_and_write($filename, $mode, $data) {
|
|||||||
* byte string with binary zeros so that the length is a multiple of
|
* byte string with binary zeros so that the length is a multiple of
|
||||||
* blocksize.
|
* blocksize.
|
||||||
*/
|
*/
|
||||||
function long_to_bytes($n,$blocksize=0) {
|
function long_to_bytes($n, $blocksize = 0)
|
||||||
|
{
|
||||||
$s = $b('');
|
$s = $b('');
|
||||||
$n = long($n);
|
$n = long($n);
|
||||||
while (($n > 0)) {
|
while (($n > 0)) {
|
||||||
$s = ($this->struct->pack('I', $n & 4294967295) + $s);
|
$s = ($this->struct->pack('I', $n & 4294967295) + $s);
|
||||||
$n = $n >> 32;
|
$n = $n >> 32;
|
||||||
}
|
}
|
||||||
foreach( pyjslib_range(strlen($s)) as $i ) {
|
foreach (pyjslib_range(strlen($s)) as $i) {
|
||||||
if (($s[$i] != $b('')[0])) {
|
if (($s[$i] != $b('')[0])) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -113,24 +130,31 @@ function long_to_bytes($n,$blocksize=0) {
|
|||||||
if (($blocksize > 0) && (strlen($s) % $blocksize)) {
|
if (($blocksize > 0) && (strlen($s) % $blocksize)) {
|
||||||
$s = ((($blocksize - (strlen($s) % $blocksize)) * $b('')) + $s);
|
$s = ((($blocksize - (strlen($s) % $blocksize)) * $b('')) + $s);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $s;
|
return $s;
|
||||||
}
|
}
|
||||||
function string2bin($string) {
|
function string2bin($string)
|
||||||
|
{
|
||||||
$res = null;
|
$res = null;
|
||||||
foreach(explode('\\', $string) as $s) {
|
foreach (explode('\\', $string) as $s) {
|
||||||
if($s != null && $s[0] == "x") {
|
if ($s != null && $s[0] == 'x') {
|
||||||
$res .= hex2bin(substr($s, 1));
|
$res .= hex2bin(substr($s, 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Manages TCP Transport. encryption and message frames
|
* Manages TCP Transport. encryption and message frames.
|
||||||
*/
|
*/
|
||||||
class Session {
|
class Session
|
||||||
function __construct($ip, $port, $auth_key = null, $server_salt = null) {
|
{
|
||||||
$this->sock = fsockopen("tcp://".$ip.":".$port);
|
public function __construct($ip, $port, $auth_key = null, $server_salt = null)
|
||||||
if(!(get_resource_type($this->sock) == 'file' || get_resource_type($this->sock) == 'stream')) throw new Exception("Couldn't connect to socket.");
|
{
|
||||||
|
$this->sock = fsockopen('tcp://'.$ip.':'.$port);
|
||||||
|
if (!(get_resource_type($this->sock) == 'file' || get_resource_type($this->sock) == 'stream')) {
|
||||||
|
throw new Exception("Couldn't connect to socket.");
|
||||||
|
}
|
||||||
$this->number = 0;
|
$this->number = 0;
|
||||||
$this->timedelta = 0;
|
$this->timedelta = 0;
|
||||||
$this->session_id = random_bytes(8);
|
$this->session_id = random_bytes(8);
|
||||||
@ -141,59 +165,65 @@ class Session {
|
|||||||
$this->AUTH_MAX_RETRY = 5;
|
$this->AUTH_MAX_RETRY = 5;
|
||||||
$this->struct = new \danog\PHP\Struct();
|
$this->struct = new \danog\PHP\Struct();
|
||||||
try {
|
try {
|
||||||
$this->tl = new TL("https://core.telegram.org/schema/mtproto-json");
|
$this->tl = new TL('https://core.telegram.org/schema/mtproto-json');
|
||||||
} catch(Exception $e){
|
} catch (Exception $e) {
|
||||||
$this->tl = new TL(__DIR__ . '/TL_schema.JSON');
|
$this->tl = new TL(__DIR__.'/TL_schema.JSON');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function __destruct() {
|
|
||||||
|
public function __destruct()
|
||||||
|
{
|
||||||
fclose($this->sock);
|
fclose($this->sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forming the message frame and sending message to server
|
* Forming the message frame and sending message to server
|
||||||
* :param message: byte string to send
|
* :param message: byte string to send.
|
||||||
*/
|
*/
|
||||||
function send_message($message_data) {
|
public function send_message($message_data)
|
||||||
$message_id = $this->struct->pack('<Q', (int)((time() + $this->timedelta) * pow(2, 30)) * 4);
|
{
|
||||||
|
$message_id = $this->struct->pack('<Q', (int) ((time() + $this->timedelta) * pow(2, 30)) * 4);
|
||||||
|
|
||||||
if (($this->auth_key == null) || ($this->server_salt == null)) {
|
if (($this->auth_key == null) || ($this->server_salt == null)) {
|
||||||
$message = string2bin('\x00\x00\x00\x00\x00\x00\x00\x00') . $message_id . $this->struct->pack('<I', strlen($message_data)) . $message_data;
|
$message = string2bin('\x00\x00\x00\x00\x00\x00\x00\x00').$message_id.$this->struct->pack('<I', strlen($message_data)).$message_data;
|
||||||
} else {
|
} else {
|
||||||
$encrypted_data =
|
$encrypted_data =
|
||||||
$this->server_salt . $this->session_id . $message_id . $this->struct->pack('<II', $this->number, strlen($message_data)) . $message_data;
|
$this->server_salt.$this->session_id.$message_id.$this->struct->pack('<II', $this->number, strlen($message_data)).$message_data;
|
||||||
$message_key = substr(sha1($encrypted_data, true), -16, null);
|
$message_key = substr(sha1($encrypted_data, true), -16, null);
|
||||||
$padding = random_bytes((-strlen($encrypted_data) % 16));
|
$padding = random_bytes((-strlen($encrypted_data) % 16));
|
||||||
echo strlen($encrypted_data . $padding) . PHP_EOL;
|
echo strlen($encrypted_data.$padding).PHP_EOL;
|
||||||
list($aes_key, $aes_iv) = $this->aes_calculate($message_key);
|
list($aes_key, $aes_iv) = $this->aes_calculate($message_key);
|
||||||
$message = $this->auth_key_id . $message_key . crypt::ige_encrypt($encrypted_data . $padding, $aes_key, $aes_iv);
|
$message = $this->auth_key_id.$message_key.crypt::ige_encrypt($encrypted_data.$padding, $aes_key, $aes_iv);
|
||||||
}
|
}
|
||||||
$step1 = $this->struct->pack('<II', (strlen($message) + 12), $this->number) . $message;
|
$step1 = $this->struct->pack('<II', (strlen($message) + 12), $this->number).$message;
|
||||||
$step2 = $step1 . $this->struct->pack('<I', newcrc32($step1));
|
$step2 = $step1.$this->struct->pack('<I', newcrc32($step1));
|
||||||
fwrite($this->sock, $step2);
|
fwrite($this->sock, $step2);
|
||||||
$this->number += 1;
|
$this->number += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reading socket and receiving message from server. Check the CRC32.
|
* Reading socket and receiving message from server. Check the CRC32.
|
||||||
*/
|
*/
|
||||||
function recv_message() {
|
public function recv_message()
|
||||||
|
{
|
||||||
$packet_length_data = fread($this->sock, 4);
|
$packet_length_data = fread($this->sock, 4);
|
||||||
if (len($packet_length_data) < 4) {
|
if (len($packet_length_data) < 4) {
|
||||||
throw new Exception('Nothing in the socket!');
|
throw new Exception('Nothing in the socket!');
|
||||||
}
|
}
|
||||||
$packet_length = $this->struct->unpack('<I', $packet_length_data)[1];
|
$packet_length = $this->struct->unpack('<I', $packet_length_data)[1];
|
||||||
$packet = fread($this->sock, ($packet_length - 4));
|
$packet = fread($this->sock, ($packet_length - 4));
|
||||||
if (!(newcrc32($packet_length_data . substr($packet, 0, -4 - 0)) == $this->struct->unpack('<I', substr($packet, -4, null))[1])) {
|
if (!(newcrc32($packet_length_data.substr($packet, 0, -4 - 0)) == $this->struct->unpack('<I', substr($packet, -4, null))[1])) {
|
||||||
throw new Exception('CRC32 was not correct!');
|
throw new Exception('CRC32 was not correct!');
|
||||||
}
|
}
|
||||||
$x = $this->struct->unpack('<I', substr($packet, null, 4));
|
$x = $this->struct->unpack('<I', substr($packet, null, 4));
|
||||||
$auth_key_id = substr($packet, 4, 12 - 4);
|
$auth_key_id = substr($packet, 4, 12 - 4);
|
||||||
if ($auth_key_id == string2bin('\x00\x00\x00\x00\x00\x00\x00\x00')) {
|
if ($auth_key_id == string2bin('\x00\x00\x00\x00\x00\x00\x00\x00')) {
|
||||||
list($message_id, $message_length) = struct.unpack("<8sI", substr($packet, 12, 24));
|
list($message_id, $message_length) = struct.unpack('<8sI', substr($packet, 12, 24));
|
||||||
$data = substr($packet, 24, (24 + $message_length) - 24);
|
$data = substr($packet, 24, (24 + $message_length) - 24);
|
||||||
} else if ($auth_key_id == $this->auth_key_id) {
|
} elseif ($auth_key_id == $this->auth_key_id) {
|
||||||
$message_key = substr($packet, 12, 28 - 12);
|
$message_key = substr($packet, 12, 28 - 12);
|
||||||
$encrypted_data = substr($packet, 28, -4 - 28);
|
$encrypted_data = substr($packet, 28, -4 - 28);
|
||||||
list($aes_key, $aes_iv) = $this->aes_calculate($message_key,'from server');
|
list($aes_key, $aes_iv) = $this->aes_calculate($message_key, 'from server');
|
||||||
$decrypted_data = crypt::ige_decrypt($encrypted_data, $aes_key, $aes_iv);
|
$decrypted_data = crypt::ige_decrypt($encrypted_data, $aes_key, $aes_iv);
|
||||||
assert((substr($decrypted_data, 0, 8 - 0) == $this->server_salt));
|
assert((substr($decrypted_data, 0, 8 - 0) == $this->server_salt));
|
||||||
assert((substr($decrypted_data, 8, 16 - 8) == $this->session_id));
|
assert((substr($decrypted_data, 8, 16 - 8) == $this->session_id));
|
||||||
@ -204,27 +234,32 @@ class Session {
|
|||||||
} else {
|
} else {
|
||||||
throw new Exception('Got unknown auth_key id');
|
throw new Exception('Got unknown auth_key id');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
function method_call($method, $kwargs) {
|
|
||||||
|
public function method_call($method, $kwargs)
|
||||||
|
{
|
||||||
foreach (range(1, $this->MAX_RETRY) as $i) {
|
foreach (range(1, $this->MAX_RETRY) as $i) {
|
||||||
try {
|
try {
|
||||||
//var_dump(py2php_kwargs_function_call('serialize_method', [$method], $kwargs));
|
//var_dump(py2php_kwargs_function_call('serialize_method', [$method], $kwargs));
|
||||||
$this->send_message($this->tl->serialize_method($method, $kwargs));
|
$this->send_message($this->tl->serialize_method($method, $kwargs));
|
||||||
$server_answer = $this->recv_message();
|
$server_answer = $this->recv_message();
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch(Exception $e) {
|
echo $e->getMessage().PHP_EOL;
|
||||||
echo $e->getMessage() . PHP_EOL;
|
|
||||||
pyjslib_printnl('Retry call method');
|
pyjslib_printnl('Retry call method');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return $this->tl->deserialize(fopen_and_write("php://memory", "rw+b", $server_answer));
|
|
||||||
|
return $this->tl->deserialize(fopen_and_write('php://memory', 'rw+b', $server_answer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function create_auth_key() {
|
|
||||||
|
public function create_auth_key()
|
||||||
|
{
|
||||||
$nonce = random_bytes(16);
|
$nonce = random_bytes(16);
|
||||||
pyjslib_printnl('Requesting pq');
|
pyjslib_printnl('Requesting pq');
|
||||||
$ResPQ = $this->method_call('req_pq', ["nonce" => $nonce]);
|
$ResPQ = $this->method_call('req_pq', ['nonce' => $nonce]);
|
||||||
$server_nonce = $ResPQ['server_nonce'];
|
$server_nonce = $ResPQ['server_nonce'];
|
||||||
$public_key_fingerprint = $ResPQ['server_public_key_fingerprints'][0];
|
$public_key_fingerprint = $ResPQ['server_public_key_fingerprints'][0];
|
||||||
$pq_bytes = $ResPQ['pq'];
|
$pq_bytes = $ResPQ['pq'];
|
||||||
@ -237,16 +272,16 @@ class Session {
|
|||||||
pyjslib_printnl(sprintf('Factorization %d = %d * %d', [$pq, $p, $q]));
|
pyjslib_printnl(sprintf('Factorization %d = %d * %d', [$pq, $p, $q]));
|
||||||
$p_bytes = long_to_bytes($p);
|
$p_bytes = long_to_bytes($p);
|
||||||
$q_bytes = long_to_bytes($q);
|
$q_bytes = long_to_bytes($q);
|
||||||
$f = pyjslib_open(__DIR__ . '/rsa.pub');
|
$f = pyjslib_open(__DIR__.'/rsa.pub');
|
||||||
$key = RSA::importKey($f->read());
|
$key = RSA::importKey($f->read());
|
||||||
$new_nonce = random_bytes(32);
|
$new_nonce = random_bytes(32);
|
||||||
$data = py2php_kwargs_function_call('serialize_obj', ['p_q_inner_data'], ["pq" => $pq_bytes, "p" => $p_bytes, "q" => $q_bytes, "nonce" => $nonce, "server_nonce" => $server_nonce, "new_nonce" => $new_nonce]);
|
$data = py2php_kwargs_function_call('serialize_obj', ['p_q_inner_data'], ['pq' => $pq_bytes, 'p' => $p_bytes, 'q' => $q_bytes, 'nonce' => $nonce, 'server_nonce' => $server_nonce, 'new_nonce' => $new_nonce]);
|
||||||
$sha_digest = sha($data, true);
|
$sha_digest = sha($data, true);
|
||||||
$random_bytes = random_bytes(((255 - strlen($data)) - strlen($sha_digest)));
|
$random_bytes = random_bytes(((255 - strlen($data)) - strlen($sha_digest)));
|
||||||
$to_encrypt = (($sha_digest + $data) + $random_bytes);
|
$to_encrypt = (($sha_digest + $data) + $random_bytes);
|
||||||
$encrypted_data = $key->encrypt($to_encrypt, 0) [0];
|
$encrypted_data = $key->encrypt($to_encrypt, 0) [0];
|
||||||
pyjslib_printnl('Starting Diffie Hellman key exchange');
|
pyjslib_printnl('Starting Diffie Hellman key exchange');
|
||||||
$server_dh_params = $this->method_call('req_DH_params', ["nonce" => $nonce, "server_nonce" => $server_nonce, "p" => $p_bytes, "q" => $q_bytes, "public_key_fingerprint" => $public_key_fingerprint, "encrypted_data" => $encrypted_data]);
|
$server_dh_params = $this->method_call('req_DH_params', ['nonce' => $nonce, 'server_nonce' => $server_nonce, 'p' => $p_bytes, 'q' => $q_bytes, 'public_key_fingerprint' => $public_key_fingerprint, 'encrypted_data' => $encrypted_data]);
|
||||||
assert(($nonce == $server_dh_params['nonce']));
|
assert(($nonce == $server_dh_params['nonce']));
|
||||||
assert(($server_nonce == $server_dh_params['server_nonce']));
|
assert(($server_nonce == $server_dh_params['server_nonce']));
|
||||||
$encrypted_answer = $server_dh_params['encrypted_answer'];
|
$encrypted_answer = $server_dh_params['encrypted_answer'];
|
||||||
@ -272,19 +307,19 @@ class Session {
|
|||||||
$b = new bytes_to_long($b_str);
|
$b = new bytes_to_long($b_str);
|
||||||
$g_b = pow($g, $b, $dh_prime);
|
$g_b = pow($g, $b, $dh_prime);
|
||||||
$g_b_str = new long_to_bytes($g_b);
|
$g_b_str = new long_to_bytes($g_b);
|
||||||
$data = py2php_kwargs_function_call('serialize_obj', ['client_DH_inner_data'], ["nonce" => $nonce, "server_nonce" => $server_nonce, "retry_id" => $retry_id, "g_b" => $g_b_str]);
|
$data = py2php_kwargs_function_call('serialize_obj', ['client_DH_inner_data'], ['nonce' => $nonce, 'server_nonce' => $server_nonce, 'retry_id' => $retry_id, 'g_b' => $g_b_str]);
|
||||||
$data_with_sha = (sha1($data, true) + $data);
|
$data_with_sha = (sha1($data, true) + $data);
|
||||||
$data_with_sha_padded = ($data_with_sha + random_bytes((-strlen($data_with_sha) % 16)));
|
$data_with_sha_padded = ($data_with_sha + random_bytes((-strlen($data_with_sha) % 16)));
|
||||||
$encrypted_data = crypt::ige_encrypt($data_with_sha_padded, $tmp_aes_key, $tmp_aes_iv);
|
$encrypted_data = crypt::ige_encrypt($data_with_sha_padded, $tmp_aes_key, $tmp_aes_iv);
|
||||||
foreach (pyjslib_range(1, $this->AUTH_MAX_RETRY) as $i) {
|
foreach (pyjslib_range(1, $this->AUTH_MAX_RETRY) as $i) {
|
||||||
$Set_client_DH_params_answer = $this->method_call('set_client_DH_params', ["nonce" => $nonce, "server_nonce" => $server_nonce, "encrypted_data" => $encrypted_data]);
|
$Set_client_DH_params_answer = $this->method_call('set_client_DH_params', ['nonce' => $nonce, 'server_nonce' => $server_nonce, 'encrypted_data' => $encrypted_data]);
|
||||||
$auth_key = pow($g_a, $b, $dh_prime);
|
$auth_key = pow($g_a, $b, $dh_prime);
|
||||||
$auth_key_str = new long_to_bytes($auth_key);
|
$auth_key_str = new long_to_bytes($auth_key);
|
||||||
$auth_key_sha = sha1($auth_key_str, true);
|
$auth_key_sha = sha1($auth_key_str, true);
|
||||||
$auth_key_aux_hash = array_slice($auth_key_sha, null, 8);
|
$auth_key_aux_hash = array_slice($auth_key_sha, null, 8);
|
||||||
$new_nonce_hash1 = array_slice(sha1($new_nonce . '' . $auth_key_aux_hash, true), -16, null);
|
$new_nonce_hash1 = array_slice(sha1($new_nonce.''.$auth_key_aux_hash, true), -16, null);
|
||||||
$new_nonce_hash2 = array_slice(sha1($new_nonce . '' . $auth_key_aux_hash, true), -16, null);
|
$new_nonce_hash2 = array_slice(sha1($new_nonce.''.$auth_key_aux_hash, true), -16, null);
|
||||||
$new_nonce_hash3 = array_slice(sha1($new_nonce . '' . $auth_key_aux_hash, true), -16, null);
|
$new_nonce_hash3 = array_slice(sha1($new_nonce.''.$auth_key_aux_hash, true), -16, null);
|
||||||
assert(($Set_client_DH_params_answer['nonce'] == $nonce));
|
assert(($Set_client_DH_params_answer['nonce'] == $nonce));
|
||||||
assert(($Set_client_DH_params_answer['server_nonce'] == $server_nonce));
|
assert(($Set_client_DH_params_answer['server_nonce'] == $server_nonce));
|
||||||
if (($Set_client_DH_params_answer->name == 'dh_gen_ok')) {
|
if (($Set_client_DH_params_answer->name == 'dh_gen_ok')) {
|
||||||
@ -294,11 +329,12 @@ class Session {
|
|||||||
$this->auth_key = $auth_key_str;
|
$this->auth_key = $auth_key_str;
|
||||||
$this->auth_key_id = array_slice($auth_key_sha, -8, null);
|
$this->auth_key_id = array_slice($auth_key_sha, -8, null);
|
||||||
pyjslib_printnl('Auth key generated');
|
pyjslib_printnl('Auth key generated');
|
||||||
|
|
||||||
return 'Auth Ok';
|
return 'Auth Ok';
|
||||||
} else if (($Set_client_DH_params_answer->name == 'dh_gen_retry')) {
|
} elseif (($Set_client_DH_params_answer->name == 'dh_gen_retry')) {
|
||||||
assert(($Set_client_DH_params_answer['new_nonce_hash2'] == $new_nonce_hash2));
|
assert(($Set_client_DH_params_answer['new_nonce_hash2'] == $new_nonce_hash2));
|
||||||
pyjslib_printnl('Retry Auth');
|
pyjslib_printnl('Retry Auth');
|
||||||
} else if (($Set_client_DH_params_answer->name == 'dh_gen_fail')) {
|
} elseif (($Set_client_DH_params_answer->name == 'dh_gen_fail')) {
|
||||||
assert(($Set_client_DH_params_answer['new_nonce_hash3'] == $new_nonce_hash3));
|
assert(($Set_client_DH_params_answer['new_nonce_hash3'] == $new_nonce_hash3));
|
||||||
pyjslib_printnl('Auth Failed');
|
pyjslib_printnl('Auth Failed');
|
||||||
throw new Exception('Auth Failed');
|
throw new Exception('Auth Failed');
|
||||||
@ -307,7 +343,9 @@ class Session {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function aes_calculate($msg_key, $direction = 'to server') {
|
|
||||||
|
public function aes_calculate($msg_key, $direction = 'to server')
|
||||||
|
{
|
||||||
$x = ($direction == 'to server') ? 0 : 8;
|
$x = ($direction == 'to server') ? 0 : 8;
|
||||||
$sha1_a = sha1(($msg_key + array_slice($this->auth_key, $x, ($x + 32) - $x)), true);
|
$sha1_a = sha1(($msg_key + array_slice($this->auth_key, $x, ($x + 32) - $x)), true);
|
||||||
$sha1_b = sha1(((array_slice($this->auth_key, ($x + 32), ($x + 48) - ($x + 32)) + $msg_key) + array_slice($this->auth_key, (48 + $x), (64 + $x) - (48 + $x))), true);
|
$sha1_b = sha1(((array_slice($this->auth_key, ($x + 32), ($x + 48) - ($x + 32)) + $msg_key) + array_slice($this->auth_key, (48 + $x), (64 + $x) - (48 + $x))), true);
|
||||||
@ -315,6 +353,7 @@ class Session {
|
|||||||
$sha1_d = sha1(($msg_key + array_slice($this->auth_key, ($x + 96), ($x + 128) - ($x + 96))))->digest();
|
$sha1_d = sha1(($msg_key + array_slice($this->auth_key, ($x + 96), ($x + 128) - ($x + 96))))->digest();
|
||||||
$aes_key = ((array_slice($sha1_a, 0, 8 - 0) + array_slice($sha1_b, 8, 20 - 8)) + array_slice($sha1_c, 4, 16 - 4));
|
$aes_key = ((array_slice($sha1_a, 0, 8 - 0) + array_slice($sha1_b, 8, 20 - 8)) + array_slice($sha1_c, 4, 16 - 4));
|
||||||
$aes_iv = (((array_slice($sha1_a, 8, 20 - 8) + array_slice($sha1_b, 0, 8 - 0)) + array_slice($sha1_c, 16, 20 - 16)) + array_slice($sha1_d, 0, 8 - 0));
|
$aes_iv = (((array_slice($sha1_a, 8, 20 - 8) + array_slice($sha1_b, 0, 8 - 0)) + array_slice($sha1_c, 16, 20 - 16)) + array_slice($sha1_d, 0, 8 - 0));
|
||||||
|
|
||||||
return [$aes_key, $aes_iv];
|
return [$aes_key, $aes_iv];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
97
prime.php
97
prime.php
@ -1,31 +1,39 @@
|
|||||||
<?php
|
<?php
|
||||||
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libpy2php');
|
|
||||||
require_once ('libpy2php.php');
|
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
|
||||||
function everynth($array, $n) {
|
require_once 'libpy2php.php';
|
||||||
$result = array();
|
function everynth($array, $n)
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
$i = -1;
|
$i = -1;
|
||||||
foreach($array as $key => $value) {
|
foreach ($array as $key => $value) {
|
||||||
if ($i++ == $n) {
|
if ($i++ == $n) {
|
||||||
$i = 0;
|
$i = 0;
|
||||||
}
|
}
|
||||||
if($i == 0) {
|
if ($i == 0) {
|
||||||
$result[$key] = $value;
|
$result[$key] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
function array_merge_ignore_keys($array1, $array2) {
|
function array_merge_ignore_keys($array1, $array2)
|
||||||
if(count($array1) == count($array2)) {
|
{
|
||||||
|
if (count($array1) == count($array2)) {
|
||||||
$i = -1;
|
$i = -1;
|
||||||
foreach ($array1 as $key => $val){
|
foreach ($array1 as $key => $val) {
|
||||||
$array1[$key] = $array2[$i++];
|
$array1[$key] = $array2[$i++];
|
||||||
}
|
}
|
||||||
} else return null;
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
return $array1;
|
return $array1;
|
||||||
}
|
}
|
||||||
function primesbelow($N) {
|
function primesbelow($N)
|
||||||
|
{
|
||||||
$correction = (($N % 6) > 1);
|
$correction = (($N % 6) > 1);
|
||||||
$N = [0 => $N, 1 => ($N - 1), 2 => ($N + 4), 3 => ($N + 3), 4 => ($N + 2), 5 => ($N + 1) ][($N % 6) ];
|
$N = [0 => $N, 1 => ($N - 1), 2 => ($N + 4), 3 => ($N + 3), 4 => ($N + 2), 5 => ($N + 1)][($N % 6)];
|
||||||
$sieve = array_fill(0, floor($N / 3), true);
|
$sieve = array_fill(0, floor($N / 3), true);
|
||||||
$sieve[0] = false;
|
$sieve[0] = false;
|
||||||
foreach (pyjslib_range((floor(pyjslib_int(pow($N, 0.5)) / 3) + 1)) as $i) {
|
foreach (pyjslib_range((floor(pyjslib_int(pow($N, 0.5)) / 3) + 1)) as $i) {
|
||||||
@ -37,10 +45,10 @@ function primesbelow($N) {
|
|||||||
array_splice(
|
array_splice(
|
||||||
$sieve, floor(
|
$sieve, floor(
|
||||||
(
|
(
|
||||||
$k*$k + 4*$k - 2*$k*($i%2)
|
$k * $k + 4 * $k - 2 * $k * ($i % 2)
|
||||||
) / 3
|
) / 3
|
||||||
)
|
)
|
||||||
), 2*$k
|
), 2 * $k
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
array_fill(
|
array_fill(
|
||||||
@ -71,23 +79,29 @@ function primesbelow($N) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ([2, 3] + array_map(function ($i, $sieve) { if($sieve[$i]) return (3 * $i + 1) | 1; }, pyjslib_range(1, (($N / 3) - $correction)), $sieve));
|
|
||||||
|
return [2, 3] + array_map(function ($i, $sieve) {
|
||||||
|
if ($sieve[$i]) {
|
||||||
|
return (3 * $i + 1) | 1;
|
||||||
|
}
|
||||||
|
}, pyjslib_range(1, (($N / 3) - $correction)), $sieve);
|
||||||
}
|
}
|
||||||
$smallprimeset = array_unique(primesbelow(100000));
|
$smallprimeset = array_unique(primesbelow(100000));
|
||||||
$_smallprimeset = 100000;
|
$_smallprimeset = 100000;
|
||||||
function isprime($n, $precision = 7) {
|
function isprime($n, $precision = 7)
|
||||||
|
{
|
||||||
if (($n == 1) || (($n % 2) == 0)) {
|
if (($n == 1) || (($n % 2) == 0)) {
|
||||||
return false;
|
return false;
|
||||||
} else if (($n < 1)) {
|
} elseif (($n < 1)) {
|
||||||
throw new $ValueError('Out of bounds, first argument must be > 0');
|
throw new $ValueError('Out of bounds, first argument must be > 0');
|
||||||
} else if (($n < $_smallprimeset)) {
|
} elseif (($n < $_smallprimeset)) {
|
||||||
return in_array($n, $smallprimeset);
|
return in_array($n, $smallprimeset);
|
||||||
}
|
}
|
||||||
$d = ($n - 1);
|
$d = ($n - 1);
|
||||||
$s = 0;
|
$s = 0;
|
||||||
while ((($d % 2) == 0)) {
|
while ((($d % 2) == 0)) {
|
||||||
$d = floor($d /2);
|
$d = floor($d / 2);
|
||||||
$s+= 1;
|
$s += 1;
|
||||||
}
|
}
|
||||||
foreach (pyjslib_range($precision) as $repeat) {
|
foreach (pyjslib_range($precision) as $repeat) {
|
||||||
$a = random::randrange(2, ($n - 2));
|
$a = random::randrange(2, ($n - 2));
|
||||||
@ -105,16 +119,18 @@ function isprime($n, $precision = 7) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
function pollard_brent($n) {
|
function pollard_brent($n)
|
||||||
|
{
|
||||||
if ((($n % 2) == 0)) {
|
if ((($n % 2) == 0)) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
if ((($n % 3) == 0)) {
|
if ((($n % 3) == 0)) {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
list($y, $c, $m) = [random::randint(1, ($n - 1)), random::randint(1, ($n - 1)), random::randint(1, ($n - 1)) ];
|
list($y, $c, $m) = [random::randint(1, ($n - 1)), random::randint(1, ($n - 1)), random::randint(1, ($n - 1))];
|
||||||
list($g, $r, $q) = [1, 1, 1];
|
list($g, $r, $q) = [1, 1, 1];
|
||||||
while (($g == 1)) {
|
while (($g == 1)) {
|
||||||
$x = $y;
|
$x = $y;
|
||||||
@ -129,9 +145,9 @@ function pollard_brent($n) {
|
|||||||
$q = (($q * abs(($x - $y))) % $n);
|
$q = (($q * abs(($x - $y))) % $n);
|
||||||
}
|
}
|
||||||
$g = gcd($q, $n);
|
$g = gcd($q, $n);
|
||||||
$k+= $m;
|
$k += $m;
|
||||||
}
|
}
|
||||||
$r*= 2;
|
$r *= 2;
|
||||||
}
|
}
|
||||||
if (($g == $n)) {
|
if (($g == $n)) {
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -142,10 +158,12 @@ function pollard_brent($n) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $g;
|
return $g;
|
||||||
}
|
}
|
||||||
$smallprimes = primesbelow(10000);
|
$smallprimes = primesbelow(10000);
|
||||||
function primefactors($n, $sort = false) {
|
function primefactors($n, $sort = false)
|
||||||
|
{
|
||||||
global $smallprimes;
|
global $smallprimes;
|
||||||
$factors = [];
|
$factors = [];
|
||||||
$limit = (pyjslib_int(pow($n, 0.5)) + 1);
|
$limit = (pyjslib_int(pow($n, 0.5)) + 1);
|
||||||
@ -173,51 +191,56 @@ function primefactors($n, $sort = false) {
|
|||||||
$factor = pollard_brent($n);
|
$factor = pollard_brent($n);
|
||||||
$factors->extend(primefactors($factor));
|
$factors->extend(primefactors($factor));
|
||||||
$n = floor($n / $factor);
|
$n = floor($n / $factor);
|
||||||
|
|
||||||
}
|
}
|
||||||
if ($sort) {
|
if ($sort) {
|
||||||
$factors->sort();
|
$factors->sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $factors;
|
return $factors;
|
||||||
}
|
}
|
||||||
function factorization($n) {
|
function factorization($n)
|
||||||
|
{
|
||||||
$factors = [];
|
$factors = [];
|
||||||
foreach (primefactors($n) as $p1) {
|
foreach (primefactors($n) as $p1) {
|
||||||
try {
|
try {
|
||||||
$factors[$p1]+= 1;
|
$factors[$p1] += 1;
|
||||||
}
|
} catch (KeyError $e) {
|
||||||
catch(KeyError $e) {
|
|
||||||
$factors[$p1] = 1;
|
$factors[$p1] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $factors;
|
return $factors;
|
||||||
}
|
}
|
||||||
$totients = [];
|
$totients = [];
|
||||||
function totient($n) {
|
function totient($n)
|
||||||
|
{
|
||||||
if (($n == 0)) {
|
if (($n == 0)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return $totients[$n];
|
return $totients[$n];
|
||||||
}
|
} catch (KeyError $e) {
|
||||||
catch(KeyError $e) {
|
|
||||||
}
|
}
|
||||||
$tot = 1;
|
$tot = 1;
|
||||||
foreach (factorization($n)->items() as list($p, $exp)) {
|
foreach (factorization($n)->items() as list($p, $exp)) {
|
||||||
$tot*= (($p - 1) * pow($p, ($exp - 1)));
|
$tot *= (($p - 1) * pow($p, ($exp - 1)));
|
||||||
}
|
}
|
||||||
$totients[$n] = $tot;
|
$totients[$n] = $tot;
|
||||||
|
|
||||||
return $tot;
|
return $tot;
|
||||||
}
|
}
|
||||||
function gcd($a, $b) {
|
function gcd($a, $b)
|
||||||
|
{
|
||||||
if (($a == $b)) {
|
if (($a == $b)) {
|
||||||
return $a;
|
return $a;
|
||||||
}
|
}
|
||||||
while (($b > 0)) {
|
while (($b > 0)) {
|
||||||
list($a, $b) = [$b, ($a % $b) ];
|
list($a, $b) = [$b, ($a % $b)];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $a;
|
return $a;
|
||||||
}
|
}
|
||||||
function lcm($a, $b) {
|
function lcm($a, $b)
|
||||||
|
{
|
||||||
return floor(abs(($a * $b)) / gcd($a, $b));
|
return floor(abs(($a * $b)) / gcd($a, $b));
|
||||||
}
|
}
|
||||||
|
31
telepy.php
31
telepy.php
@ -1,27 +1,30 @@
|
|||||||
<?php
|
<?php
|
||||||
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libpy2php');
|
|
||||||
require_once ('libpy2php.php');
|
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
|
||||||
require_once ('mtproto.php');
|
require_once 'libpy2php.php';
|
||||||
require_once ('classes/shell.php');
|
require_once 'mtproto.php';
|
||||||
|
require_once 'classes/shell.php';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!debug_backtrace()) {
|
if (!debug_backtrace()) {
|
||||||
$clidata = [];
|
$clidata = [];
|
||||||
$clidata["description"] = 'MadelineProto: PHP implementation of telegram API. Translated from telepy by Daniil Gentili.';
|
$clidata['description'] = 'MadelineProto: PHP implementation of telegram API. Translated from telepy by Daniil Gentili.';
|
||||||
$clidata['args']['commands'] = array_merge(['cmd', 'dialog_list', 'contact_list'], array_map(function($sub) { return "chat_" . $sub; }, ['info', 'add_user', 'add_user_to_chat', 'del_user', 'set_photo', 'rename']));
|
$clidata['args']['commands'] = array_merge(['cmd', 'dialog_list', 'contact_list'], array_map(function ($sub) {
|
||||||
$clidata['args']['flags'] = "h";
|
return 'chat_'.$sub;
|
||||||
$clidata["help"] = $clidata["description"] . PHP_EOL . PHP_EOL . "Flags: ";
|
}, ['info', 'add_user', 'add_user_to_chat', 'del_user', 'set_photo', 'rename']));
|
||||||
|
$clidata['args']['flags'] = 'h';
|
||||||
|
$clidata['help'] = $clidata['description'].PHP_EOL.PHP_EOL.'Flags: ';
|
||||||
foreach (str_split($clidata['args']['flags']) as $flag) {
|
foreach (str_split($clidata['args']['flags']) as $flag) {
|
||||||
$clidata["help"] .= "-" . $flag . ", ";
|
$clidata['help'] .= '-'.$flag.', ';
|
||||||
}
|
}
|
||||||
$clidata["help"] .= PHP_EOL . "Commands: ";
|
$clidata['help'] .= PHP_EOL.'Commands: ';
|
||||||
foreach ($clidata['args']['commands'] as $command) {
|
foreach ($clidata['args']['commands'] as $command) {
|
||||||
$clidata["help"] .= $command . ", ";
|
$clidata['help'] .= $command.', ';
|
||||||
}
|
}
|
||||||
$clidata["help"] .= PHP_EOL;
|
$clidata['help'] .= PHP_EOL;
|
||||||
if(isset(getopt($clidata['args']['flags'])["h"])) {
|
if (isset(getopt($clidata['args']['flags'])['h'])) {
|
||||||
die($clidata["help"]);
|
die($clidata['help']);
|
||||||
}
|
}
|
||||||
if ($argc == 1) {
|
if ($argc == 1) {
|
||||||
$newTelePyShell = new TelepyShell();
|
$newTelePyShell = new TelepyShell();
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libpy2php');
|
|
||||||
require_once ('libpy2php.php');
|
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).DIRECTORY_SEPARATOR.'libpy2php');
|
||||||
require_once ('os.php');
|
require_once 'libpy2php.php';
|
||||||
require_once ('mtproto.php');
|
require_once 'os.php';
|
||||||
|
require_once 'mtproto.php';
|
||||||
$config = parse_ini_file('credentials', true);
|
$config = parse_ini_file('credentials', true);
|
||||||
if (!($config)) {
|
if (!($config)) {
|
||||||
pyjslib_printnl('File \'credentials\' seems to not exist.');
|
pyjslib_printnl('File \'credentials\' seems to not exist.');
|
||||||
|
Loading…
Reference in New Issue
Block a user