PageRenderTime 56ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/kickstart/kickstart.php

#
PHP | 1651 lines | 903 code | 137 blank | 611 comment | 210 complexity | 98a2cbe025bdcec54a7bb0999e5698ed MD5 | raw file
  1. <?php
  2. /**
  3. *
  4. * Due to PHP issues, usage of this script is NOT possible with Safe Mode enabled.
  5. *
  6. */
  7. define('CHUNKSIZE', '1024768'); // Default pass-through chunk size (used when extracting uncompressed data): 1Mb
  8. define('MAXBATCHSIZE', 1024768); // Maximum archive chunk's size to be processed at once: 2Mb
  9. define('MAXBATCHFILES', 40); // Maximum files to process at once: 40
  10. define('DRYRUN', 0); // Set to 1 for Test mode (no extraction, no deletion)
  11. // ==========================================================================================
  12. // KS: Simple Unzip Class
  13. // ==========================================================================================
  14. class CSimpleUnzip
  15. {
  16. /**
  17. * Absolute file name and path of the ZIP file
  18. *
  19. * @var string
  20. */
  21. var $_filename = '';
  22. /**
  23. * Read only file pointer to the ZIP file
  24. *
  25. * @var unknown_type
  26. */
  27. var $_filepointer = false;
  28. /**
  29. * Did we encounter an error?
  30. *
  31. * @var boolean
  32. */
  33. var $_isError = false;
  34. /**
  35. * Error description
  36. *
  37. * @var string
  38. */
  39. var $_error = '';
  40. /**
  41. * Creates the CSimpleUnzip object and tries to open the file specified in $filename
  42. *
  43. * @param string $filename Absolute path and file name of the ZIP file to open
  44. * @return CSimpleUnzip
  45. */
  46. function CSimpleUnzip( $filename )
  47. {
  48. // Set the stored filename to the defined parameter
  49. $this->_filename = $filename;
  50. // Try opening the file
  51. $this->_filepointer = $this->_getFP();
  52. }
  53. /**
  54. * Returns a file pointer to the ZIP file, or tries to open the file.
  55. *
  56. * @return integer|boolean File pointer or FALSE when there's an error
  57. * @access private
  58. */
  59. function _getFP()
  60. {
  61. // If the file is open, return the existing file pointer
  62. if ( $this->_filepointer !== FALSE ) return $this->_filepointer;
  63. if( file_exists($this->_filename) )
  64. {
  65. $fp = @fopen( $this->_filename, 'r');
  66. if( $fp === false )
  67. {
  68. $this->_error = "Could not open " . $this->_filename . " for reading. Check permissions?";
  69. $this->_isError = true;
  70. return false;
  71. } else {
  72. $this->_filepointer = $fp;
  73. return $this->_filepointer;
  74. }
  75. } else {
  76. $this->_error = "File " . $this->_filename . " does not exist.";
  77. $this->_isError = true;
  78. return false;
  79. }
  80. }
  81. /**
  82. * Returns the error message for the current error state, or FALSE if no error has occured
  83. *
  84. * @return string|boolean Error message or FALSE for no errors
  85. */
  86. function getError()
  87. {
  88. if( !$this->_isError ) {
  89. return false;
  90. } else {
  91. return $this->_error;
  92. }
  93. }
  94. /**
  95. * Extracts a file from the ZIP archive
  96. *
  97. * @param integer $offset The offset to start extracting from. If ommited, or set to null,
  98. * it continues from the ZIP file's current location.
  99. * @return array|boolean A return array or FALSE if an error occured
  100. */
  101. function ExtractFile( $offset = null )
  102. {
  103. // Generate a return array
  104. $retArray = array(
  105. "file" => '', // File name extracted
  106. "compressed" => 0, // Compressed size
  107. "uncompressed" => 0, // Uncompressed size
  108. "type" => "file", // File type (file | dir)
  109. "zipoffset" => 0, // Offset in ZIP file
  110. "done" => false // Are we done with extracting files?
  111. );
  112. // Get file pointer to the ZIP file
  113. $fp = $this->_getFP();
  114. // If we can't open the file, return an error condition
  115. if( $fp === false ) return false;
  116. // Go to the offset specified, if specified. Otherwise, it will continue reading from current position
  117. if( !is_null($offset) ) fseek( $fp, $offset );
  118. // Get and decode Local File Header
  119. $headerBinary = fread($fp, 30);
  120. $headerData = unpack('Vsig/C2ver/vbitflag/vcompmethod/vlastmodtime/vlastmoddate/Vcrc/Vcompsize/Vuncomp/vfnamelen/veflen', $headerBinary);
  121. // Check signature
  122. if( $headerData['sig'] == 0x04034b50 )
  123. {
  124. // This is a file header. Get basic parameters.
  125. $retArray['compressed'] = $headerData['compsize'];
  126. $retArray['uncompressed'] = $headerData['uncomp'];
  127. $nameFieldLength = $headerData['fnamelen'];
  128. $extraFieldLength = $headerData['eflen'];
  129. // Read filename field
  130. $retArray['file'] = fread( $fp, $nameFieldLength );
  131. // Read extra field if present
  132. if($extraFieldLength > 0) $extrafield = fread( $fp, $extraFieldLength );
  133. if( strrpos($retArray['file'], '/') == strlen($retArray['file']) - 1 ) $retArray['type'] = 'dir';
  134. // Do we need to create the directory?
  135. if(strpos($retArray['file'], '/') > 0) {
  136. $lastSlash = strrpos($retArray['file'], '/');
  137. $dirName = substr( $retArray['file'], 0, $lastSlash);
  138. if( $this->_createDirRecursive($dirName) == false ) {
  139. $this->_isError = true;
  140. $this->_error = "Could not create $dirName folder";
  141. return false;
  142. }
  143. }
  144. if( $headerData['compmethod'] == 8 )
  145. {
  146. // DEFLATE compression
  147. $zipData = fread( $fp, $retArray['compressed'] );
  148. $unzipData = gzinflate( $zipData );
  149. unset($zipData);
  150. if( DRYRUN != 1 )
  151. {
  152. // Try writing to the output file
  153. $outfp = @fopen( $retArray['file'], 'w' );
  154. if( $outfp === false ) {
  155. // An error occured
  156. $this->_isError = true;
  157. $this->_error = "Could not open " . $retArray['file'] . " for writing.";
  158. return false;
  159. } else {
  160. // No error occured. Write to the file.
  161. fwrite( $outfp, $unzipData, $retArray['uncompressed'] );
  162. fclose( $outfp );
  163. }
  164. }
  165. unset($unzipData);
  166. } else {
  167. if( $retArray['type'] == "file" )
  168. {
  169. // No compression
  170. if( $retArray['uncompressed'] > 0 )
  171. {
  172. if( DRYRUN != 1 ) {
  173. $outfp = @fopen( $retArray['file'], 'w' );
  174. if( $outfp === false ) {
  175. // An error occured
  176. $this->_isError = true;
  177. $this->_error = "Could not open " . $retArray['file'] . " for writing.";
  178. return false;
  179. } else {
  180. $readBytes = 0;
  181. $toReadBytes = 0;
  182. $leftBytes = $retArray['compressed'];
  183. while( $leftBytes > 0)
  184. {
  185. $toReadBytes = ($leftBytes > CHUNKSIZE) ? CHUNKSIZE : $leftBytes;
  186. $leftBytes -= $toReadBytes;
  187. $data = fread( $fp, $toReadBytes );
  188. fwrite( $outfp, $data );
  189. }
  190. fclose($outfp);
  191. }
  192. }
  193. } else {
  194. // 0 byte file, just touch it
  195. if( DRYRUN != 1 )
  196. {
  197. $outfp = @fopen( $retArray['file'], 'w' );
  198. if( $outfp === false ) {
  199. // An error occured
  200. $this->_isError = true;
  201. $this->_error = "Could not open " . $retArray['file'] . " for writing.";
  202. return false;
  203. } else {
  204. fclose($outfp);
  205. }
  206. }
  207. }
  208. } else {
  209. if( DRYRUN != 1 ) {
  210. $result = $this->_createDirRecursive( $retArray['file'] );
  211. if( !$result ) {
  212. return false;
  213. }
  214. }
  215. }
  216. }
  217. $retArray['zipoffset'] = ftell( $fp );
  218. return $retArray;
  219. } else {
  220. // This is not a file header. This means we are done.
  221. $retArray['done'] = true;
  222. return $retArray;
  223. }
  224. }
  225. /**
  226. * Tries to recursively create the directory $dirName
  227. *
  228. * @param string $dirName The directory to create
  229. * @return boolean TRUE on success, FALSE on failure
  230. * @access private
  231. */
  232. function _createDirRecursive( $dirName )
  233. {
  234. $dirArray = explode('/', $dirName);
  235. $path = '';
  236. foreach( $dirArray as $dir )
  237. {
  238. $path .= $dir . '/';
  239. $ret = is_dir($path) ? true : @mkdir($path);
  240. if( !ret ) {
  241. $this->_isError = true;
  242. $this->_error = "Could not create $path folder.";
  243. return false;
  244. }
  245. }
  246. return true;
  247. }
  248. }
  249. // ==========================================================================================
  250. // KS: UnJPA: JoomlaPack Archive Extraction Class
  251. // ==========================================================================================
  252. /**
  253. * JoomlaPack Archive extraction class
  254. * Implements the JoomlaPack Archive format version 1.0
  255. */
  256. class CUnJPA
  257. {
  258. /**
  259. * File pointer of the archive opened
  260. * @var integer
  261. */
  262. var $_fp = FALSE;
  263. /**
  264. * Absolute pathname to archive being operated upon
  265. * @var string
  266. */
  267. var $_filename;
  268. /**
  269. * Did we encounter an error?
  270. *
  271. * @var boolean
  272. */
  273. var $_isError = false;
  274. /**
  275. * Error description
  276. *
  277. * @var string
  278. */
  279. var $_error = '';
  280. /**
  281. * Data read from archive's header
  282. * @var array
  283. */
  284. var $headerData = array();
  285. /**
  286. * The last offset in the archive file we read data from
  287. *
  288. * @var unknown_type
  289. */
  290. var $lastOffset = 0;
  291. /**
  292. * Opens a JPA archive for reading
  293. * @param string $filename The absolute pathname to the file being operated upon
  294. * @return CUnJPA
  295. */
  296. function CUnJPA( $filename )
  297. {
  298. // Store the filename
  299. $this->_filename = $filename;
  300. // Try opening the file
  301. $this->_fp = $this->_getFP();
  302. // Read the header
  303. $this->_ReadHeader();
  304. }
  305. function Close()
  306. {
  307. @fclose( $this->_fp );
  308. }
  309. /**
  310. * Returns the error message for the current error state, or FALSE if no error has occured
  311. *
  312. * @return string|boolean Error message or FALSE for no errors
  313. */
  314. function getError()
  315. {
  316. if( !$this->_isError ) {
  317. return false;
  318. } else {
  319. return $this->_error;
  320. }
  321. }
  322. /**
  323. * Extracts a file from the ZIP archive
  324. *
  325. * @param integer $offset The offset to start extracting from. If ommited, or set to null,
  326. * it continues from the ZIP file's current location.
  327. * @return array|boolean A return array or FALSE if an error occured
  328. */
  329. function ExtractFile( $offset = null )
  330. {
  331. // Generate a return array
  332. $retArray = array(
  333. "file" => '', // File name extracted
  334. "compressed" => 0, // Compressed size
  335. "uncompressed" => 0, // Uncompressed size
  336. "type" => "file", // File type (file | dir)
  337. "compression" => "none", // Compression type (none | gzip | bzip2)
  338. "archiveoffset" => 0, // Offset in ZIP file
  339. "permissions" => 0, // UNIX permissions stored in the archive
  340. "done" => false // Are we done with extracting files?
  341. );
  342. $offset = $offset == 0 ? null : $offset;
  343. // Get file pointer to the ZIP file
  344. $fp = $this->_getFP();
  345. // If we can't open the file, return an error condition
  346. if( $fp === false ) return false;
  347. // Go to the offset specified, if specified. Otherwise, it will continue reading from current position
  348. if( is_null($offset) ) $offset = $this->lastOffset;
  349. if( !is_null($offset) ) fseek( $fp, $offset );
  350. // Get and decode Entity Description Block
  351. $signature = fread($fp, 3);
  352. // Check signature
  353. if( $signature == 'JPF' )
  354. {
  355. // This a JPA Entity Block. Process the header.
  356. // Read length of EDB and of the Entity Path Data
  357. $length_array = unpack('vblocksize/vpathsize', fread($fp, 4));
  358. // Read the path data
  359. $file = fread( $fp, $length_array['pathsize'] );
  360. // Read and parse the known data portion
  361. $bin_data = fread( $fp, 14 );
  362. $header_data = unpack('Ctype/Ccompression/Vcompsize/Vuncompsize/Vperms', $bin_data);
  363. // Read any unknwon data
  364. $restBytes = $length_array['blocksize'] - (21 + $length_array['pathsize']);
  365. if( $restBytes > 0 ) $junk = fread($fp, $restBytes);
  366. $compressionType = $header_data['compression'];
  367. // Populate the return array
  368. $retArray['file'] = $file;
  369. $retArray['compressed'] = $header_data['compsize'];
  370. $retArray['uncompressed'] = $header_data['uncompsize'];
  371. $retArray['type'] = ($header_data['type'] == 0 ? "dir" : "file");
  372. switch( $compressionType )
  373. {
  374. case 0:
  375. $retArray['compression'] = 'none';
  376. break;
  377. case 1:
  378. $retArray['compression'] = 'gzip';
  379. break;
  380. case 2:
  381. $retArray['compression'] = 'bzip2';
  382. break;
  383. }
  384. $retArray['permissions'] = $header_data['perms'];
  385. // Do we need to create the directory?
  386. if(strpos($retArray['file'], '/') > 0) {
  387. $lastSlash = strrpos($retArray['file'], '/');
  388. $dirName = substr( $retArray['file'], 0, $lastSlash);
  389. if( DRYRUN != 1 )
  390. {
  391. if( $this->_createDirRecursive($dirName) == false ) {
  392. $this->_isError = true;
  393. $this->_error = "Could not create $dirName folder";
  394. return false;
  395. }
  396. }
  397. }
  398. switch( $retArray['type'] )
  399. {
  400. case "dir":
  401. if( DRYRUN != 1 ) {
  402. $result = $this->_createDirRecursive( $retArray['file'] );
  403. if( !$result ) {
  404. return false;
  405. }
  406. }
  407. break;
  408. case "file":
  409. switch( $compressionType )
  410. {
  411. case 0: // No compression
  412. if( $retArray['uncompressed'] > 0 )
  413. {
  414. if( DRYRUN != 1 )
  415. {
  416. $outfp = @fopen( $retArray['file'], 'w' );
  417. if( $outfp === false ) {
  418. // An error occured
  419. $this->_isError = true;
  420. $this->_error = "Could not open " . $retArray['file'] . " for writing.";
  421. return false;
  422. }
  423. }
  424. $readBytes = 0;
  425. $toReadBytes = 0;
  426. $leftBytes = $retArray['compressed'];
  427. while( $leftBytes > 0)
  428. {
  429. $toReadBytes = ($leftBytes > CHUNKSIZE) ? CHUNKSIZE : $leftBytes;
  430. $leftBytes -= $toReadBytes;
  431. $data = fread( $fp, $toReadBytes );
  432. if( DRYRUN != 1 ) fwrite( $outfp, $data );
  433. }
  434. if( DRYRUN != 1 ) fclose($outfp);
  435. } else {
  436. // 0 byte file, just touch it
  437. if( DRYRUN != 1 )
  438. {
  439. $outfp = @fopen( $retArray['file'], 'w' );
  440. if( $outfp === false ) {
  441. // An error occured
  442. $this->_isError = true;
  443. $this->_error = "Could not open " . $retArray['file'] . " for writing.";
  444. return false;
  445. } else {
  446. fclose($outfp);
  447. }
  448. }
  449. }
  450. break;
  451. case 1: // GZip compression
  452. $zipData = fread( $fp, $retArray['compressed'] );
  453. $unzipData = gzinflate( $zipData );
  454. unset($zipData);
  455. if( DRYRUN != 1 )
  456. {
  457. // Try writing to the output file
  458. $outfp = @fopen( $retArray['file'], 'w' );
  459. if( $outfp === false ) {
  460. // An error occured
  461. $this->_isError = true;
  462. $this->_error = "Could not open " . $retArray['file'] . " for writing.";
  463. return false;
  464. } else {
  465. // No error occured. Write to the file.
  466. fwrite( $outfp, $unzipData, $retArray['uncompressed'] );
  467. fclose( $outfp );
  468. }
  469. }
  470. unset($unzipData);
  471. break;
  472. case 2: // BZip2 compression
  473. $zipData = fread( $fp, $retArray['compressed'] );
  474. $unzipData = bzdecompress( $zipData );
  475. unset($zipData);
  476. if( DRYRUN != 1 )
  477. {
  478. // Try writing to the output file
  479. $outfp = @fopen( $retArray['file'], 'w' );
  480. if( $outfp === false ) {
  481. // An error occured
  482. $this->_isError = true;
  483. $this->_error = "Could not open " . $retArray['file'] . " for writing.";
  484. return false;
  485. } else {
  486. // No error occured. Write to the file.
  487. fwrite( $outfp, $unzipData, $retArray['uncompressed'] );
  488. fclose( $outfp );
  489. }
  490. }
  491. unset($unzipData);
  492. break;
  493. }
  494. break;
  495. }
  496. $retArray['archiveoffset'] = ftell( $fp );
  497. $this->lastOffset = $retArray['archiveoffset'];
  498. return $retArray;
  499. } else {
  500. // This is not a file header. This means we are done.
  501. $retArray['done'] = true;
  502. return $retArray;
  503. }
  504. }
  505. /**
  506. * Returns a file pointer to the ZIP file, or tries to open the file.
  507. *
  508. * @return integer|boolean File pointer or FALSE when there's an error
  509. * @access private
  510. */
  511. function _getFP()
  512. {
  513. // If the file is open, return the existing file pointer
  514. if ( $this->_fp !== FALSE ) return $this->_fp;
  515. if( file_exists($this->_filename) )
  516. {
  517. $fp = @fopen( $this->_filename, 'r');
  518. if( $fp === false )
  519. {
  520. $this->_error = "Could not open " . $this->_filename . " for reading. Check permissions?";
  521. $this->_isError = true;
  522. return false;
  523. } else {
  524. $this->_fp = $fp;
  525. return $this->_fp;
  526. }
  527. } else {
  528. $this->_error = "File " . $this->_filename . " does not exist.";
  529. $this->_isError = true;
  530. return false;
  531. }
  532. }
  533. /**
  534. * Tries to recursively create the directory $dirName
  535. *
  536. * @param string $dirName The directory to create
  537. * @return boolean TRUE on success, FALSE on failure
  538. * @access private
  539. */
  540. function _createDirRecursive( $dirName )
  541. {
  542. $dirArray = explode('/', $dirName);
  543. $path = '';
  544. foreach( $dirArray as $dir )
  545. {
  546. $path .= $dir . '/';
  547. $ret = is_dir($path) ? true : @mkdir($path);
  548. if( !ret ) {
  549. $this->_isError = true;
  550. $this->_error = "Could not create $path folder.";
  551. return false;
  552. }
  553. }
  554. return true;
  555. }
  556. /**
  557. * Reads the files header
  558. * @access private
  559. * @return boolean TRUE on success
  560. */
  561. function _ReadHeader()
  562. {
  563. // Initialize header data array
  564. $this->headerData = array();
  565. // Get filepointer
  566. $fp = $this->_getFP();
  567. // Fail for unreadable files
  568. if( $fp === false ) return false;
  569. // Go to the beggining of the file
  570. rewind( $fp );
  571. // Read the signature
  572. $sig = fread( $fp, 3 );
  573. if ($sig != 'JPA') return false; // Not a JoomlaPack Archive?
  574. // Read and parse header length
  575. $header_length_array = unpack( 'v', fread( $fp, 2 ) );
  576. $header_length = $header_length_array[1];
  577. // Read and parse the known portion of header data (14 bytes)
  578. $bin_data = fread($fp, 14);
  579. $header_data = unpack('Cmajor/Cminor/Vcount/Vuncsize/Vcsize', $bin_data);
  580. // Load any remaining header data (forward compatibility)
  581. $rest_length = $header_length - 19;
  582. if( $rest_length > 0 ) $junk = fread($fp, $rest_length);
  583. $this->headerData = array(
  584. 'signature' => $sig,
  585. 'length' => $header_length,
  586. 'major' => $header_data['major'],
  587. 'minor' => $header_data['minor'],
  588. 'filecount' => $header_data['count'],
  589. 'uncompressedsize' => $header_data['uncsize'],
  590. 'compressedsize' => $header_data['csize'],
  591. 'unknowndata' => $junk
  592. );
  593. $this->lastOffset = ftell( $fp );
  594. return true;
  595. }
  596. }
  597. // ==========================================================================================
  598. // KS: (S)AJAX Library
  599. // ==========================================================================================
  600. if (!isset($SAJAX_INCLUDED)) {
  601. /*
  602. * GLOBALS AND DEFAULTS
  603. *
  604. */
  605. $GLOBALS['sajax_version'] = '0.12';
  606. $GLOBALS['sajax_debug_mode'] = 0;
  607. $GLOBALS['sajax_export_list'] = array();
  608. $GLOBALS['sajax_request_type'] = 'POST';
  609. $GLOBALS['sajax_remote_uri'] = '';
  610. $GLOBALS['sajax_failure_redirect'] = '';
  611. /*
  612. * CODE
  613. *
  614. */
  615. //
  616. // Initialize the Sajax library.
  617. //
  618. function sajax_init() {
  619. }
  620. // Since str_split used in sajax_get_my_uri is only available on PHP 5, we have
  621. // to provide an alternative for those using PHP 4.x
  622. if(!function_exists('str_split')){
  623. function str_split($string,$split_length=1){
  624. $count = strlen($string);
  625. if($split_length < 1){
  626. return false;
  627. } elseif($split_length > $count){
  628. return array($string);
  629. } else {
  630. $num = (int)ceil($count/$split_length);
  631. $ret = array();
  632. for($i=0;$i<$num;$i++){
  633. $ret[] = substr($string,$i*$split_length,$split_length);
  634. }
  635. return $ret;
  636. }
  637. }
  638. }
  639. //
  640. // Helper function to return the script's own URI.
  641. //
  642. function sajax_get_my_uri() {
  643. return $_SERVER["REQUEST_URI"];
  644. }
  645. $sajax_remote_uri = sajax_get_my_uri();
  646. //
  647. // Helper function to return an eval()-usable representation
  648. // of an object in JavaScript.
  649. //
  650. function sajax_get_js_repr($value) {
  651. $type = gettype($value);
  652. if ($type == "boolean") {
  653. return ($value) ? "Boolean(true)" : "Boolean(false)";
  654. }
  655. elseif ($type == "integer") {
  656. return "parseInt($value)";
  657. }
  658. elseif ($type == "double") {
  659. return "parseFloat($value)";
  660. }
  661. elseif ($type == "array" || $type == "object" ) {
  662. //
  663. // XXX Arrays with non-numeric indices are not
  664. // permitted according to ECMAScript, yet everyone
  665. // uses them.. We'll use an object.
  666. //
  667. $s = "{ ";
  668. if ($type == "object") {
  669. $value = get_object_vars($value);
  670. }
  671. foreach ($value as $k=>$v) {
  672. $esc_key = sajax_esc($k);
  673. if (is_numeric($k))
  674. $s .= "$k: " . sajax_get_js_repr($v) . ", ";
  675. else
  676. $s .= "\"$esc_key\": " . sajax_get_js_repr($v) . ", ";
  677. }
  678. if (count($value))
  679. $s = substr($s, 0, -2);
  680. return $s . " }";
  681. }
  682. else {
  683. $esc_val = sajax_esc($value);
  684. $s = "'$esc_val'";
  685. return $s;
  686. }
  687. }
  688. function sajax_handle_client_request() {
  689. global $sajax_export_list;
  690. $mode = "";
  691. if (! empty($_GET["rs"]))
  692. $mode = "get";
  693. if (!empty($_POST["rs"]))
  694. $mode = "post";
  695. if (empty($mode))
  696. return;
  697. $target = "";
  698. ob_clean();
  699. if ($mode == "get") {
  700. // Bust cache in the head
  701. header ("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
  702. header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
  703. // always modified
  704. header ("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
  705. header ("Pragma: no-cache"); // HTTP/1.0
  706. $func_name = $_GET["rs"];
  707. if (! empty($_GET["rsargs"]))
  708. $args = $_GET["rsargs"];
  709. else
  710. $args = array();
  711. }
  712. else {
  713. $func_name = $_POST["rs"];
  714. if (! empty($_POST["rsargs"]))
  715. $args = $_POST["rsargs"];
  716. else
  717. $args = array();
  718. }
  719. if (! in_array($func_name, $sajax_export_list))
  720. echo "-:$func_name not callable";
  721. else {
  722. echo "+:";
  723. ob_flush();
  724. $result = call_user_func_array($func_name, $args);
  725. echo "var res = " . trim(sajax_get_js_repr($result)) . "; res;";
  726. ob_flush();
  727. flush();
  728. }
  729. exit;
  730. }
  731. function sajax_get_common_js() {
  732. global $option;
  733. global $sajax_debug_mode;
  734. global $sajax_request_type;
  735. global $sajax_remote_uri;
  736. global $sajax_failure_redirect;
  737. $t = strtoupper($sajax_request_type);
  738. if ($t != "" && $t != "GET" && $t != "POST")
  739. return "// Invalid type: $t.. \n\n";
  740. ob_start();
  741. ?>
  742. // remote scripting library
  743. // (c) copyright 2005 modernmethod, inc
  744. var sajax_debug_mode = <?php echo $sajax_debug_mode ? "true" : "false"; ?>;
  745. var sajax_request_type = "<?php echo $t; ?>";
  746. var sajax_target_id = "";
  747. var sajax_failure_redirect = "<?php echo $sajax_failure_redirect; ?>";
  748. var sajax_failed_eval = "";
  749. var sajax_fail_handle = "";
  750. function sajax_debug(text) {
  751. if (sajax_debug_mode)
  752. alert(text);
  753. }
  754. function sajax_init_object() {
  755. sajax_debug("sajax_init_object() called..")
  756. var A;
  757. var msxmlhttp = new Array(
  758. 'Msxml2.XMLHTTP.5.0',
  759. 'Msxml2.XMLHTTP.4.0',
  760. 'Msxml2.XMLHTTP.3.0',
  761. 'Msxml2.XMLHTTP',
  762. 'Microsoft.XMLHTTP');
  763. for (var i = 0; i < msxmlhttp.length; i++) {
  764. try {
  765. A = new ActiveXObject(msxmlhttp[i]);
  766. } catch (e) {
  767. A = null;
  768. }
  769. }
  770. if(!A && typeof XMLHttpRequest != "undefined")
  771. A = new XMLHttpRequest();
  772. if (!A)
  773. sajax_debug("Could not create connection object.");
  774. return A;
  775. }
  776. var sajax_requests = new Array();
  777. function sajax_cancel() {
  778. for (var i = 0; i < sajax_requests.length; i++)
  779. sajax_requests[i].abort();
  780. }
  781. function sajax_do_call(func_name, args) {
  782. var i, x, n;
  783. var uri;
  784. var post_data;
  785. var target_id;
  786. sajax_debug("in sajax_do_call().." + sajax_request_type + "/" + sajax_target_id);
  787. target_id = sajax_target_id;
  788. if (typeof(sajax_request_type) == "undefined" || sajax_request_type == "")
  789. sajax_request_type = "GET";
  790. uri = "<?php echo sajax_get_my_uri() . "?option=$option&no_html=1&act=ajax"; ?>";
  791. if (sajax_request_type == "GET") {
  792. if (uri.indexOf("?") == -1)
  793. uri += "?rs=" + escape(func_name);
  794. else
  795. uri += "&rs=" + escape(func_name);
  796. uri += "&rst=" + escape(sajax_target_id);
  797. uri += "&rsrnd=" + new Date().getTime();
  798. for (i = 0; i < args.length-1; i++)
  799. uri += "&rsargs[]=" + escape(args[i]);
  800. post_data = null;
  801. }
  802. else if (sajax_request_type == "POST") {
  803. post_data = "option=<?php echo $option; ?>&no_html=1&act=ajax"
  804. post_data += "&rs=" + escape(func_name);
  805. post_data += "&rst=" + escape(sajax_target_id);
  806. post_data += "&rsrnd=" + new Date().getTime();
  807. for (i = 0; i < args.length-1; i++)
  808. post_data = post_data + "&rsargs[]=" + escape(args[i]);
  809. }
  810. else {
  811. alert("Illegal request type: " + sajax_request_type);
  812. }
  813. x = sajax_init_object();
  814. if (x == null) {
  815. if (sajax_failure_redirect != "") {
  816. location.href = sajax_failure_redirect;
  817. return false;
  818. } else {
  819. sajax_debug("NULL sajax object for user agent:\n" + navigator.userAgent);
  820. return false;
  821. }
  822. } else {
  823. x.open(sajax_request_type, uri, true);
  824. // window.open(uri);
  825. sajax_requests[sajax_requests.length] = x;
  826. if (sajax_request_type == "POST") {
  827. x.setRequestHeader("Method", "POST " + uri + " HTTP/1.1");
  828. x.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  829. }
  830. x.onreadystatechange = function() {
  831. if (x.readyState != 4)
  832. return;
  833. sajax_debug("received " + x.responseText);
  834. var status;
  835. var data;
  836. var txt = x.responseText.replace(/^\s*|\s*$/g,"");
  837. status = txt.charAt(0);
  838. data = txt.substring(2);
  839. if (status == "") {
  840. // let's just assume this is a pre-response bailout and let it slide for now
  841. } else if (status == "-")
  842. alert("Error: " + data);
  843. else {
  844. if (target_id != "")
  845. document.getElementById(target_id).innerHTML = eval(data);
  846. else {
  847. try {
  848. var callback;
  849. var extra_data = false;
  850. if (typeof args[args.length-1] == "object") {
  851. callback = args[args.length-1].callback;
  852. extra_data = args[args.length-1].extra_data;
  853. } else {
  854. callback = args[args.length-1];
  855. }
  856. callback(eval(data), extra_data);
  857. } catch (e) {
  858. sajax_debug("Caught error " + e + ": Could not eval " + data );
  859. sajax_failed_eval = data;
  860. sajax_fail_handle(data);
  861. }
  862. }
  863. }
  864. }
  865. }
  866. sajax_debug(func_name + " uri = " + uri + "/post = " + post_data);
  867. x.send(post_data);
  868. sajax_debug(func_name + " waiting..");
  869. delete x;
  870. return true;
  871. }
  872. <?php
  873. $html = ob_get_contents();
  874. ob_end_clean();
  875. return $html;
  876. }
  877. function sajax_show_common_js() {
  878. echo sajax_get_common_js();
  879. }
  880. // javascript escape a value
  881. function sajax_esc($val)
  882. {
  883. $val = str_replace("\\", "\\\\", $val);
  884. $val = str_replace("\r", "\\r", $val);
  885. $val = str_replace("\n", "\\n", $val);
  886. $val = str_replace("'", "\\'", $val);
  887. return str_replace('"', '\\"', $val);
  888. }
  889. function sajax_get_one_stub($func_name) {
  890. ob_start();
  891. ?>
  892. // wrapper for <?php echo $func_name; ?>
  893. function x_<?php echo $func_name; ?>() {
  894. sajax_do_call("<?php echo $func_name; ?>",
  895. x_<?php echo $func_name; ?>.arguments);
  896. }
  897. <?php
  898. $html = ob_get_contents();
  899. ob_end_clean();
  900. return $html;
  901. }
  902. function sajax_show_one_stub($func_name) {
  903. echo sajax_get_one_stub($func_name);
  904. }
  905. function sajax_export() {
  906. global $sajax_export_list;
  907. $n = func_num_args();
  908. for ($i = 0; $i < $n; $i++) {
  909. $sajax_export_list[] = func_get_arg($i);
  910. }
  911. }
  912. $sajax_js_has_been_shown = 0;
  913. function sajax_get_javascript()
  914. {
  915. global $sajax_js_has_been_shown;
  916. global $sajax_export_list;
  917. $html = "";
  918. if (! $sajax_js_has_been_shown) {
  919. $html .= sajax_get_common_js();
  920. $sajax_js_has_been_shown = 1;
  921. }
  922. foreach ($sajax_export_list as $func) {
  923. $html .= sajax_get_one_stub($func);
  924. }
  925. return $html;
  926. }
  927. function sajax_show_javascript()
  928. {
  929. echo sajax_get_javascript();
  930. }
  931. $SAJAX_INCLUDED = 1;
  932. }
  933. // ==========================================================================================
  934. // KS: Filesystem abstraction layer
  935. // ==========================================================================================
  936. /**
  937. * Filesystem Abstraction Module
  938. *
  939. * Provides filesystem handling functions in a compatible manner, depending on server's capabilities
  940. */
  941. class CFSAbstraction {
  942. /**
  943. * Should we use glob() ?
  944. * @var boolean
  945. */
  946. var $_globEnable;
  947. /**
  948. * Public constructor for CFSAbstraction class. Does some heuristics to figure out the
  949. * server capabilities and setup internal variables
  950. */
  951. function CFSAbstraction()
  952. {
  953. // Don't use glob if it's disabled or if opendir is available
  954. $this->_globEnable = function_exists('glob');
  955. if( function_exists('opendir') && function_exists('readdir') && function_exists('closedir') )
  956. $this->_globEnable = false;
  957. }
  958. /**
  959. * Searches the given directory $dirName for files and folders and returns a multidimensional array.
  960. * If the directory is not accessible, returns FALSE
  961. *
  962. * @param string $dirName
  963. * @param string $shellFilter
  964. * @return array See function description for details
  965. */
  966. function getDirContents( $dirName, $shellFilter = null )
  967. {
  968. if ($this->_globEnable) {
  969. return $this->_getDirContents_glob( $dirName, $shellFilter );
  970. } else {
  971. return $this->_getDirContents_opendir( $dirName, $shellFilter );
  972. }
  973. }
  974. // ============================================================================
  975. // PRIVATE SECTION
  976. // ============================================================================
  977. /**
  978. * Searches the given directory $dirName for files and folders and returns a multidimensional array.
  979. * If the directory is not accessible, returns FALSE. This function uses the PHP glob() function.
  980. * @return array See function description for details
  981. */
  982. function _getDirContents_glob( $dirName, $shellFilter = null )
  983. {
  984. if (is_null($shellFilter)) {
  985. // Get folder contents
  986. $allFilesAndDirs1 = @glob($dirName . "/*"); // regular files
  987. $allFilesAndDirs2 = @glob($dirName . "/.*"); // *nix hidden files
  988. // Try to merge the arrays
  989. if ($allFilesAndDirs1 === false) {
  990. if ($allFilesAndDirs2 === false) {
  991. $allFilesAndDirs = false;
  992. } else {
  993. $allFilesAndDirs = $allFilesAndDirs2;
  994. }
  995. } elseif ($allFilesAndDirs2 === false) {
  996. $allFilesAndDirs = $allFilesAndDirs1;
  997. } else {
  998. $allFilesAndDirs = @array_merge($allFilesAndDirs1, $allFilesAndDirs2);
  999. }
  1000. // Free unused arrays
  1001. unset($allFilesAndDirs1);
  1002. unset($allFilesAndDirs2);
  1003. } else {
  1004. $allFilesAndDirs = @glob($dirName . "/$shellFilter"); // filtered files
  1005. }
  1006. // Check for unreadable directories
  1007. if ( $allFilesAndDirs === FALSE ) {
  1008. return FALSE;
  1009. }
  1010. // Populate return array
  1011. $retArray = array();
  1012. foreach($allFilesAndDirs as $filename) {
  1013. $filename = CFSAbstraction::TranslateWinPath( $filename );
  1014. $newEntry['name'] = $filename;
  1015. $newEntry['type'] = filetype( $filename );
  1016. if ($newEntry['type'] == "file") {
  1017. $newEntry['size'] = filesize( $filename );
  1018. } else {
  1019. $newEntry['size'] = 0;
  1020. }
  1021. $retArray[] = $newEntry;
  1022. }
  1023. return $retArray;
  1024. }
  1025. function TranslateWinPath( $p_path )
  1026. {
  1027. if (stristr(php_uname(), 'windows')){
  1028. // Change potential windows directory separator
  1029. if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0, 1) == '\\')){
  1030. $p_path = strtr($p_path, '\\', '/');
  1031. }
  1032. }
  1033. return $p_path;
  1034. }
  1035. function _getDirContents_opendir( $dirName, $shellFilter = null )
  1036. {
  1037. $handle = @opendir( $dirName );
  1038. // If directory is not accessible, just return FALSE
  1039. if ($handle === FALSE) {
  1040. return FALSE;
  1041. }
  1042. // Initialize return array
  1043. $retArray = array();
  1044. while( !( ( $filename = readdir($handle) ) === false) ) {
  1045. $match = is_null( $shellFilter );
  1046. $match = (!$match) ? fnmatch($shellFilter, $filename) : true;
  1047. if ($match) {
  1048. $filename = CFSAbstraction::TranslateWinPath( $dirName . "/" . $filename );
  1049. $newEntry['name'] = $filename;
  1050. $newEntry['type'] = @filetype( $filename );
  1051. if ($newEntry['type'] !== FALSE) {
  1052. // FIX 1.1.0 Stable - When open_basedir restrictions are in effect, an attempt to read <root>/.. could result into failure of the backup. This fix is a simplistic workaround.
  1053. if ($newEntry['type'] == 'file') {
  1054. $newEntry['size'] = @filesize( $filename );
  1055. } else {
  1056. $newEntry['size'] = 0;
  1057. }
  1058. $retArray[] = $newEntry;
  1059. }
  1060. }
  1061. }
  1062. closedir($handle);
  1063. return $retArray;
  1064. }
  1065. }
  1066. // fnmatch not available on non-POSIX systems
  1067. // Thanks to soywiz@php.net for this usefull alternative function [http://gr2.php.net/fnmatch]
  1068. if (!function_exists('fnmatch')) {
  1069. function fnmatch($pattern, $string) {
  1070. return @preg_match(
  1071. '/^' . strtr(addcslashes($pattern, '/\\.+^$(){}=!<>|'),
  1072. array('*' => '.*', '?' => '.?')) . '$/i', $string
  1073. );
  1074. }
  1075. }
  1076. // ==========================================================================================
  1077. // KS: Interface
  1078. // ==========================================================================================
  1079. function showMain()
  1080. {
  1081. ?>
  1082. <html>
  1083. <head>
  1084. <title>Hotelier Kickstart</title>
  1085. <style type="text/css">
  1086. body {
  1087. font-family: Arial, Helvetica, sans-serif;
  1088. font-size: 10pt;
  1089. color: #000000;
  1090. background-color: #666666;
  1091. }
  1092. h1 {
  1093. font-family: Arial, Helvetica, sans-serif;
  1094. font-size: 18pt;
  1095. display: block;
  1096. height: 22pt;
  1097. padding: 2pt 5pt;
  1098. background-color: #000000;
  1099. color: #ffffff;
  1100. margin: 0px;
  1101. }
  1102. #maincontainer {
  1103. display: block;
  1104. background-color: #ffffff;
  1105. border-left: 3pt solid black;
  1106. border-right: 3pt solid black;
  1107. }
  1108. #maincontainer p {
  1109. margin: 0px;
  1110. }
  1111. #errorbox {
  1112. background-color: #ffffaa;
  1113. border: 3pt solid #ff0000;
  1114. margin: 0pt 5pt;
  1115. padding: 5pt;
  1116. color: #990000;
  1117. display: none;
  1118. }
  1119. #process {
  1120. background-color: #eeeeee;
  1121. border: 3px solid #333333;
  1122. margin: 0pt 5pt;
  1123. padding: 5pt;
  1124. color: #000000;
  1125. display: none;
  1126. }
  1127. #select {
  1128. padding: 5px;
  1129. }
  1130. #footer {
  1131. background-color: #000000;
  1132. color: #aaaaaa;
  1133. font-size: 8pt;
  1134. }
  1135. #footer p {
  1136. padding: 2pt;
  1137. margin: 0px;
  1138. text-align: center;
  1139. }
  1140. #footer a {
  1141. color: #aaaabb;
  1142. }
  1143. </style>
  1144. <script type="text/javascript">
  1145. <?php echo sajax_get_javascript(); ?>
  1146. var BytesIn = 0;
  1147. var BytesOut = 0;
  1148. var Files = 0;
  1149. var FileName = '';
  1150. var Offset = '';
  1151. function do_testCompatibility()
  1152. {
  1153. x_testCompatibility( cb_testCompatibility );
  1154. }
  1155. function cb_testCompatibility( myRet )
  1156. {
  1157. if( !myRet )
  1158. {
  1159. document.getElementById('errorbox').style.display = 'block';
  1160. document.getElementById('errorbox').innerHTML = '<p>This script is not compatible with your server setup.<br />Make sure PHP Safe Mode is turned off and that the current directory has 0777 permissions.</p>';
  1161. } else {
  1162. do_getZIPList();
  1163. }
  1164. }
  1165. function do_getZIPList()
  1166. {
  1167. x_getZIPList( cb_getZIPList );
  1168. }
  1169. function cb_getZIPList( myRet )
  1170. {
  1171. document.getElementById('interface').innerHTML = myRet;
  1172. }
  1173. function do_startExtract()
  1174. {
  1175. BytesIn = 0;
  1176. BytesOut = 0;
  1177. Files = 0;
  1178. Offset = 0;
  1179. FileName = document.getElementById('zipselect').value;
  1180. do_Extract();
  1181. }
  1182. function do_Extract()
  1183. {
  1184. document.getElementById('interface').style.display = 'none';
  1185. x_myExtract( FileName, Offset, cb_Extract );
  1186. }
  1187. function cb_Extract( myRet )
  1188. {
  1189. // offset, bytesin, bytesout, files, iserror, error, done
  1190. var myHTML = '';
  1191. document.getElementById('process').style.display = 'block';
  1192. if( myRet['error'] ) {
  1193. document.getElementById('process').style.display = 'none';
  1194. document.getElementById('errorbox').style.display = 'block';
  1195. document.getElementById('errorbox').innerHTML = myRet['error'];
  1196. } else {
  1197. if( myRet['done'] ) {
  1198. // Done extracting
  1199. document.getElementById('process').style.display = 'none';
  1200. document.getElementById('interface').style.display = 'block';
  1201. document.getElementById('interface').innerHTML = '';
  1202. x_renameHtaccess(true, cb_firstRename);
  1203. } else {
  1204. // Continue extracting
  1205. BytesIn += myRet['bytesin'];
  1206. BytesOut += myRet['bytesout'];
  1207. Files += myRet['files'];
  1208. Offset = myRet['offset'];
  1209. myHTML = "<p>Read: ";
  1210. myHTML += BytesIn;
  1211. myHTML += " bytes<br />Written: ";
  1212. myHTML += BytesOut
  1213. myHTML += " bytes<br />Processed: "
  1214. myHTML += Files;
  1215. myHTML += " files<br /></p>";
  1216. document.getElementById('process').innerHTML = myHTML;
  1217. do_Extract();
  1218. }
  1219. }
  1220. }
  1221. function cb_firstRename( myRet )
  1222. {
  1223. document.getElementById('interface').innerHTML = '<p>Please click' +
  1224. '<a href="installation/index.php" target="_blank"> here</a> to open the Hotelier Installation script ' +
  1225. 'in a new window.<br /><b>DO NOT CLOSE THIS WINDOW!!</b>'+
  1226. '<br />When you have finished the installation please click '+
  1227. '<a href="javascript:postInstall();">here</a> to activate your .htaccess '+
  1228. '(if you had one in the first place) and delete the ZIP and this script.</p>';
  1229. }
  1230. function postInstall()
  1231. {
  1232. x_renameHtaccess(false, cb_postRename);
  1233. }
  1234. function cb_postRename( myRet )
  1235. {
  1236. x_deleteLeftovers( FileName, cb_deleteLeftovers );
  1237. }
  1238. function cb_deleteLeftovers( myRet )
  1239. {
  1240. document.getElementById('interface').innerHTML = '<h2>Congratulations!</h2>' +
  1241. '<p>You have successfully completed the hotelier KickStart wizard</p>';
  1242. }
  1243. </script>
  1244. </head>
  1245. <body>
  1246. <h1>Hotelier Kickstart</h1>
  1247. <div id="maincontainer">
  1248. <p>&nbsp;</p>
  1249. <div id="errorbox">
  1250. </div>
  1251. <div id="process">
  1252. </div>
  1253. <div id="interface">
  1254. </div>
  1255. <p>&nbsp;</p>
  1256. <script type="text/javascript">
  1257. do_testCompatibility();
  1258. </script>
  1259. </div>
  1260. <div id="footer">
  1261. <p></p>
  1262. </div>
  1263. </body>
  1264. </html>
  1265. <?php
  1266. }
  1267. // ==========================================================================================
  1268. // KS: AJAX Functions
  1269. // ==========================================================================================
  1270. /**
  1271. * Tests compatibility of this script with the server it's running on
  1272. *
  1273. * @return boolean
  1274. */
  1275. function testCompatibility()
  1276. {
  1277. // 1. Try creating a directory - catches permissions and safe_mode errors
  1278. $myres = @mkdir('jpkickstart');
  1279. if( $myres === false ) return false;
  1280. if( !is_dir('jpkickstart') ) return false;
  1281. @rmdir('jpkickstart');
  1282. // 2. Try creating a file
  1283. $fp = @fopen('dummy.txt', 'w');
  1284. if( $fp === false ) return false;
  1285. fclose($fp);
  1286. if( !file_exists('dummy.txt') ) return false;
  1287. @unlink('dummy.txt');
  1288. return true;
  1289. }
  1290. /**
  1291. * Gets the ZIP files present in the current directory and returns a hefty selection box
  1292. *
  1293. * @return unknown
  1294. */
  1295. function getZIPList()
  1296. {
  1297. $html = "";
  1298. $fs = new CFSAbstraction();
  1299. $partialListZIP = $fs->getDirContents( '.', '*.zip' );
  1300. $partialListJPA = $fs->getDirContents( '.', '*.jpa' );
  1301. $allZIPs = array_merge( $partialListJPA, $partialListZIP );
  1302. if( count($allZIPs) == 0 ) {
  1303. $html = "<p>There are no ZIP/JPA files in the current directory?!</p>";
  1304. } else {
  1305. $html = '<p id="select">Please select a ZIP/JPA file below and press the &quot;Start&quot; button.<br /><select id="zipselect">';
  1306. foreach( $allZIPs as $thisFile )
  1307. {
  1308. $html .= '<option value="' . $thisFile['name'] . '">' . $thisFile['name'] . '</option>';
  1309. }
  1310. $html .= '</select>&nbsp;';
  1311. $html .= '<input type="button" value="Start" onClick="do_startExtract();" />';
  1312. $html .= '</p>';
  1313. }
  1314. return $html;
  1315. }
  1316. /**
  1317. * Extracts a bacth of files from the ZIP file
  1318. *
  1319. * @param string $filename The ZIP file to extract from
  1320. * @param integer $offset Offset to start unzipping from
  1321. * @return array A return array
  1322. */
  1323. function myExtract( $filename, $offset = 0 )
  1324. {
  1325. $extension = array_pop(explode('.', $filename));
  1326. switch( $extension )
  1327. {
  1328. case 'zip':
  1329. $zip = new CSimpleUnzip( $filename );
  1330. $isJPA = false;
  1331. break;
  1332. case 'jpa':
  1333. $zip = new CUnJPA( $filename );
  1334. $isJPA = true;
  1335. break;
  1336. default:
  1337. die("Unexpected file type $extension encountered; this should never happen!");
  1338. break;
  1339. }
  1340. $filesRead = 0;
  1341. $bytesRead = 0;
  1342. $bytesOut = 0;
  1343. // Process up to MAXBATCHFILES files in a row, or a maximum of MAXBATCHSIZE bytes
  1344. while( ($filesRead <= MAXBATCHFILES) && ($bytesRead <= MAXBATCHSIZE) )
  1345. {
  1346. $result = $zip->ExtractFile( $offset );
  1347. if( $result === false )
  1348. {
  1349. $retArray = array(
  1350. 'offset' => $offset,
  1351. 'bytesin' => 0,
  1352. 'bytesout' => 0,
  1353. 'files' => 0,
  1354. 'iserror' => true,
  1355. 'error' => $zip->getError(),
  1356. 'done' => false
  1357. );
  1358. return $retArray;
  1359. } else {
  1360. if( $result['done'] == false )
  1361. {
  1362. // Increase read counter by ammount of bytes read and increase file read count
  1363. $bytesRead += $result['compressed'];
  1364. $bytesOut += $result['uncompressed'];
  1365. $filesRead += 1;
  1366. // Update next offset
  1367. $offset = $isJPA ? $result['archiveoffset'] : $result['zipoffset'];
  1368. } else {
  1369. // We are just done extracting!
  1370. $retArray = array(
  1371. 'offset' => $offset,
  1372. 'bytesin' => $bytesRead,
  1373. 'bytesout' => $bytesOut,
  1374. 'files' => $filesRead,
  1375. 'iserror' => false,
  1376. 'error' => '',
  1377. 'done' => true
  1378. );
  1379. return $retArray;
  1380. }
  1381. }
  1382. }
  1383. $retArray = array(
  1384. 'offset' => $offset,
  1385. 'bytesin' => $bytesRead,
  1386. 'bytesout' => $bytesOut,
  1387. 'files' => $filesRead,
  1388. 'iserror' => false,
  1389. 'error' => '',
  1390. 'done' => false
  1391. );
  1392. return $retArray;
  1393. }
  1394. /**
  1395. * Renames the .htaccess file (if it exists) to htaccess.txt or vice versa
  1396. *
  1397. * @param boolean $isPreInstall If TRUE, renames .htaccess to htaccess.bak. If FALSE performs the inverse.
  1398. * @return unknown
  1399. */
  1400. function renameHtaccess( $isPreInstall = true )
  1401. {
  1402. if( $isPreInstall ) {
  1403. if( file_exists('htaccess.bak') ) @unlink('htaccess.bak');
  1404. if( file_exists('.htaccess') ) return @rename('.htaccess', 'htaccess.bak');
  1405. } else {
  1406. if( file_exists('htaccess.bak') ) return @rename('htaccess.bak', '.htaccess');
  1407. }
  1408. }
  1409. /**
  1410. * Deletes the ZIP file and this script (suicide code!)
  1411. *
  1412. * @param string $zipFile The absolute path and name of the ZIP files
  1413. */
  1414. function deleteLeftovers( $zipFile )
  1415. {
  1416. @unlink( $zipFile );
  1417. @unlink( __FILE__ );
  1418. @_unlinkRecursive('installation');
  1419. }
  1420. function _unlinkRecursive( $dirName ) {
  1421. $FS = new CFSAbstraction();
  1422. if (is_file( $dirName )) {
  1423. echo "Unlinking file $dirName<br/>";
  1424. die();
  1425. @unlink( $dirName );
  1426. } elseif (is_dir( $dirName )) {
  1427. echo "Recursing directory $dirName<br/>";
  1428. $fileList = $FS->getDirContents( $dirName );
  1429. if ($fileList === false) {
  1430. } else {
  1431. foreach($fileList as $fileDescriptor) {
  1432. switch($fileDescriptor['type']) {
  1433. case "dir":
  1434. if( !((substr($fileDescriptor['name'], -1, 1) == '.') || (substr($fileDescriptor['name'], -1, 2) == '..') ) )
  1435. {
  1436. _unlinkRecursive( $fileDescriptor['name'] );
  1437. }
  1438. break;
  1439. case "file":
  1440. @unlink( $fileDescriptor['name'] );
  1441. break;
  1442. // All other types (links, character devices etc) are ignored.
  1443. }
  1444. }
  1445. @rmdir($dirName);
  1446. }
  1447. }
  1448. }
  1449. // ==========================================================================================
  1450. // KS: Main loop
  1451. // ==========================================================================================
  1452. sajax_export('testCompatibility', 'getZIPList', 'myExtract', 'renameHtaccess', 'deleteLeftovers');
  1453. sajax_handle_client_request();
  1454. if( empty($_POST["rs"]) ) {
  1455. showMain();
  1456. }
  1457. ?>