/wp-admin/includes/class-pclzip.php

  1. <?php 
  2. // -------------------------------------------------------------------------------- 
  3. // PhpConcept Library - Zip Module 2.8.2 
  4. // -------------------------------------------------------------------------------- 
  5. // License GNU/LGPL - Vincent Blavet - August 2009 
  6. // http://www.phpconcept.net 
  7. // -------------------------------------------------------------------------------- 
  8. // 
  9. // Presentation : 
  10. // PclZip is a PHP library that manage ZIP archives. 
  11. // So far tests show that archives generated by PclZip are readable by 
  12. // WinZip application and other tools. 
  13. // 
  14. // Description : 
  15. // See readme.txt and http://www.phpconcept.net 
  16. // 
  17. // Warning : 
  18. // This library and the associated files are non commercial, non professional 
  19. // work. 
  20. // It should not have unexpected results. However if any damage is caused by 
  21. // this software the author can not be responsible. 
  22. // The use of this software is at the risk of the user. 
  23. // 
  24. // -------------------------------------------------------------------------------- 
  25. // $Id: pclzip.lib.php, v 1.60 2009/09/30 21:01:04 vblavet Exp $ 
  26. // -------------------------------------------------------------------------------- 
  27.  
  28. // ----- Constants 
  29. if (!defined('PCLZIP_READ_BLOCK_SIZE')) { 
  30. define( 'PCLZIP_READ_BLOCK_SIZE', 2048 ); 
  31.  
  32. // ----- File list separator 
  33. // In version 1.x of PclZip, the separator for file list is a space 
  34. // (which is not a very smart choice, specifically for windows paths !). 
  35. // A better separator should be a comma (, ). This constant gives you the 
  36. // abilty to change that. 
  37. // However notice that changing this value, may have impact on existing 
  38. // scripts, using space separated filenames. 
  39. // Recommanded values for compatibility with older versions : 
  40. //define( 'PCLZIP_SEPARATOR', ' ' ); 
  41. // Recommanded values for smart separation of filenames. 
  42. if (!defined('PCLZIP_SEPARATOR')) { 
  43. define( 'PCLZIP_SEPARATOR', ', ' ); 
  44.  
  45. // ----- Error configuration 
  46. // 0 : PclZip Class integrated error handling 
  47. // 1 : PclError external library error handling. By enabling this 
  48. // you must ensure that you have included PclError library. 
  49. // [2, ...] : reserved for futur use 
  50. if (!defined('PCLZIP_ERROR_EXTERNAL')) { 
  51. define( 'PCLZIP_ERROR_EXTERNAL', 0 ); 
  52.  
  53. // ----- Optional static temporary directory 
  54. // By default temporary files are generated in the script current 
  55. // path. 
  56. // If defined : 
  57. // - MUST BE terminated by a '/'. 
  58. // - MUST be a valid, already created directory 
  59. // Samples : 
  60. // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' ); 
  61. // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' ); 
  62. if (!defined('PCLZIP_TEMPORARY_DIR')) { 
  63. define( 'PCLZIP_TEMPORARY_DIR', '' ); 
  64.  
  65. // ----- Optional threshold ratio for use of temporary files 
  66. // Pclzip sense the size of the file to add/extract and decide to 
  67. // use or not temporary file. The algorythm is looking for 
  68. // memory_limit of PHP and apply a ratio. 
  69. // threshold = memory_limit * ratio. 
  70. // Recommended values are under 0.5. Default 0.47. 
  71. // Samples : 
  72. // define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.5 ); 
  73. if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) { 
  74. define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.47 ); 
  75.  
  76. // -------------------------------------------------------------------------------- 
  77. // ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED ***** 
  78. // -------------------------------------------------------------------------------- 
  79.  
  80. // ----- Global variables 
  81. $g_pclzip_version = "2.8.2"; 
  82.  
  83. // ----- Error codes 
  84. // -1 : Unable to open file in binary write mode 
  85. // -2 : Unable to open file in binary read mode 
  86. // -3 : Invalid parameters 
  87. // -4 : File does not exist 
  88. // -5 : Filename is too long (max. 255) 
  89. // -6 : Not a valid zip file 
  90. // -7 : Invalid extracted file size 
  91. // -8 : Unable to create directory 
  92. // -9 : Invalid archive extension 
  93. // -10 : Invalid archive format 
  94. // -11 : Unable to delete file (unlink) 
  95. // -12 : Unable to rename file (rename) 
  96. // -13 : Invalid header checksum 
  97. // -14 : Invalid archive size 
  98. define( 'PCLZIP_ERR_USER_ABORTED', 2 ); 
  99. define( 'PCLZIP_ERR_NO_ERROR', 0 ); 
  100. define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 ); 
  101. define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 ); 
  102. define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 ); 
  103. define( 'PCLZIP_ERR_MISSING_FILE', -4 ); 
  104. define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 ); 
  105. define( 'PCLZIP_ERR_INVALID_ZIP', -6 ); 
  106. define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 ); 
  107. define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 ); 
  108. define( 'PCLZIP_ERR_BAD_EXTENSION', -9 ); 
  109. define( 'PCLZIP_ERR_BAD_FORMAT', -10 ); 
  110. define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 ); 
  111. define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 ); 
  112. define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 ); 
  113. define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 ); 
  114. define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 ); 
  115. define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 ); 
  116. define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 ); 
  117. define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 ); 
  118. define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 ); 
  119. define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 ); 
  120. define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 ); 
  121.  
  122. // ----- Options values 
  123. define( 'PCLZIP_OPT_PATH', 77001 ); 
  124. define( 'PCLZIP_OPT_ADD_PATH', 77002 ); 
  125. define( 'PCLZIP_OPT_REMOVE_PATH', 77003 ); 
  126. define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 ); 
  127. define( 'PCLZIP_OPT_SET_CHMOD', 77005 ); 
  128. define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 ); 
  129. define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 ); 
  130. define( 'PCLZIP_OPT_BY_NAME', 77008 ); 
  131. define( 'PCLZIP_OPT_BY_INDEX', 77009 ); 
  132. define( 'PCLZIP_OPT_BY_EREG', 77010 ); 
  133. define( 'PCLZIP_OPT_BY_PREG', 77011 ); 
  134. define( 'PCLZIP_OPT_COMMENT', 77012 ); 
  135. define( 'PCLZIP_OPT_ADD_COMMENT', 77013 ); 
  136. define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 ); 
  137. define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 ); 
  138. define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 ); 
  139. define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 ); 
  140. // Having big trouble with crypt. Need to multiply 2 long int 
  141. // which is not correctly supported by PHP ... 
  142. //define( 'PCLZIP_OPT_CRYPT', 77018 ); 
  143. define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 ); 
  144. define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 ); 
  145. define( 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020 ); // alias 
  146. define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 ); 
  147. define( 'PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021 ); // alias 
  148. define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 ); 
  149. define( 'PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022 ); // alias 
  150.  
  151. // ----- File description attributes 
  152. define( 'PCLZIP_ATT_FILE_NAME', 79001 ); 
  153. define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 ); 
  154. define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 ); 
  155. define( 'PCLZIP_ATT_FILE_MTIME', 79004 ); 
  156. define( 'PCLZIP_ATT_FILE_CONTENT', 79005 ); 
  157. define( 'PCLZIP_ATT_FILE_COMMENT', 79006 ); 
  158.  
  159. // ----- Call backs values 
  160. define( 'PCLZIP_CB_PRE_EXTRACT', 78001 ); 
  161. define( 'PCLZIP_CB_POST_EXTRACT', 78002 ); 
  162. define( 'PCLZIP_CB_PRE_ADD', 78003 ); 
  163. define( 'PCLZIP_CB_POST_ADD', 78004 ); 
  164. /** For futur use 
  165. define( 'PCLZIP_CB_PRE_LIST', 78005 ); 
  166. define( 'PCLZIP_CB_POST_LIST', 78006 ); 
  167. define( 'PCLZIP_CB_PRE_DELETE', 78007 ); 
  168. define( 'PCLZIP_CB_POST_DELETE', 78008 ); 
  169. */ 
  170.  
  171. // -------------------------------------------------------------------------------- 
  172. // Class : PclZip 
  173. // Description : 
  174. // PclZip is the class that represent a Zip archive. 
  175. // The public methods allow the manipulation of the archive. 
  176. // Attributes : 
  177. // Attributes must not be accessed directly. 
  178. // Methods : 
  179. // PclZip() : Object creator 
  180. // create() : Creates the Zip archive 
  181. // listContent() : List the content of the Zip archive 
  182. // extract() : Extract the content of the archive 
  183. // properties() : List the properties of the archive 
  184. // -------------------------------------------------------------------------------- 
  185. class PclZip 
  186. // ----- Filename of the zip file 
  187. var $zipname = ''; 
  188.  
  189. // ----- File descriptor of the zip file 
  190. var $zip_fd = 0; 
  191.  
  192. // ----- Internal error handling 
  193. var $error_code = 1; 
  194. var $error_string = ''; 
  195.  
  196. // ----- Current status of the magic_quotes_runtime 
  197. // This value store the php configuration for magic_quotes 
  198. // The class can then disable the magic_quotes and reset it after 
  199. var $magic_quotes_status; 
  200.  
  201. // -------------------------------------------------------------------------------- 
  202. // Function : PclZip() 
  203. // Description : 
  204. // Creates a PclZip object and set the name of the associated Zip archive 
  205. // filename. 
  206. // Note that no real action is taken, if the archive does not exist it is not 
  207. // created. Use create() for that. 
  208. // -------------------------------------------------------------------------------- 
  209. function __construct($p_zipname) 
  210.  
  211. // ----- Tests the zlib 
  212. if (!function_exists('gzopen')) 
  213. die('Abort '.basename(__FILE__).' : Missing zlib extensions'); 
  214.  
  215. // ----- Set the attributes 
  216. $this->zipname = $p_zipname; 
  217. $this->zip_fd = 0; 
  218. $this->magic_quotes_status = -1; 
  219.  
  220. // ----- Return 
  221. return; 
  222.  
  223. public function PclZip($p_zipname) { 
  224. self::__construct($p_zipname); 
  225. // -------------------------------------------------------------------------------- 
  226.  
  227. // -------------------------------------------------------------------------------- 
  228. // Function : 
  229. // create($p_filelist, $p_add_dir="", $p_remove_dir="") 
  230. // create($p_filelist, $p_option, $p_option_value, ...) 
  231. // Description : 
  232. // This method supports two different synopsis. The first one is historical. 
  233. // This method creates a Zip Archive. The Zip file is created in the 
  234. // filesystem. The files and directories indicated in $p_filelist 
  235. // are added in the archive. See the parameters description for the 
  236. // supported format of $p_filelist. 
  237. // When a directory is in the list, the directory and its content is added 
  238. // in the archive. 
  239. // In this synopsis, the function takes an optional variable list of 
  240. // options. See bellow the supported options. 
  241. // Parameters : 
  242. // $p_filelist : An array containing file or directory names, or 
  243. // a string containing one filename or one directory name, or 
  244. // a string containing a list of filenames and/or directory 
  245. // names separated by spaces. 
  246. // $p_add_dir : A path to add before the real path of the archived file,  
  247. // in order to have it memorized in the archive. 
  248. // $p_remove_dir : A path to remove from the real path of the file to archive,  
  249. // in order to have a shorter path memorized in the archive. 
  250. // When $p_add_dir and $p_remove_dir are set, $p_remove_dir 
  251. // is removed first, before $p_add_dir is added. 
  252. // Options : 
  253. // PCLZIP_OPT_ADD_PATH : 
  254. // PCLZIP_OPT_REMOVE_PATH : 
  255. // PCLZIP_OPT_REMOVE_ALL_PATH : 
  256. // PCLZIP_OPT_COMMENT : 
  257. // PCLZIP_CB_PRE_ADD : 
  258. // PCLZIP_CB_POST_ADD : 
  259. // Return Values : 
  260. // 0 on failure,  
  261. // The list of the added files, with a status of the add action. 
  262. // (see PclZip::listContent() for list entry format) 
  263. // -------------------------------------------------------------------------------- 
  264. function create($p_filelist) 
  265. $v_result=1; 
  266.  
  267. // ----- Reset the error handler 
  268. $this->privErrorReset(); 
  269.  
  270. // ----- Set default values 
  271. $v_options = array(); 
  272. $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; 
  273.  
  274. // ----- Look for variable options arguments 
  275. $v_size = func_num_args(); 
  276.  
  277. // ----- Look for arguments 
  278. if ($v_size > 1) { 
  279. // ----- Get the arguments 
  280. $v_arg_list = func_get_args(); 
  281.  
  282. // ----- Remove from the options list the first argument 
  283. array_shift($v_arg_list); 
  284. $v_size--; 
  285.  
  286. // ----- Look for first arg 
  287. if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { 
  288.  
  289. // ----- Parse the options 
  290. $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,  
  291. array (PCLZIP_OPT_REMOVE_PATH => 'optional',  
  292. PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',  
  293. PCLZIP_OPT_ADD_PATH => 'optional',  
  294. PCLZIP_CB_PRE_ADD => 'optional',  
  295. PCLZIP_CB_POST_ADD => 'optional',  
  296. PCLZIP_OPT_NO_COMPRESSION => 'optional',  
  297. PCLZIP_OPT_COMMENT => 'optional',  
  298. PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',  
  299. PCLZIP_OPT_TEMP_FILE_ON => 'optional',  
  300. PCLZIP_OPT_TEMP_FILE_OFF => 'optional' 
  301. //, PCLZIP_OPT_CRYPT => 'optional' 
  302. )); 
  303. if ($v_result != 1) { 
  304. return 0; 
  305.  
  306. // ----- Look for 2 args 
  307. // Here we need to support the first historic synopsis of the 
  308. // method. 
  309. else { 
  310.  
  311. // ----- Get the first argument 
  312. $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0]; 
  313.  
  314. // ----- Look for the optional second argument 
  315. if ($v_size == 2) { 
  316. $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; 
  317. else if ($v_size > 2) { 
  318. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,  
  319. "Invalid number / type of arguments"); 
  320. return 0; 
  321.  
  322. // ----- Look for default option values 
  323. $this->privOptionDefaultThreshold($v_options); 
  324.  
  325. // ----- Init 
  326. $v_string_list = array(); 
  327. $v_att_list = array(); 
  328. $v_filedescr_list = array(); 
  329. $p_result_list = array(); 
  330.  
  331. // ----- Look if the $p_filelist is really an array 
  332. if (is_array($p_filelist)) { 
  333.  
  334. // ----- Look if the first element is also an array 
  335. // This will mean that this is a file description entry 
  336. if (isset($p_filelist[0]) && is_array($p_filelist[0])) { 
  337. $v_att_list = $p_filelist; 
  338.  
  339. // ----- The list is a list of string names 
  340. else { 
  341. $v_string_list = $p_filelist; 
  342.  
  343. // ----- Look if the $p_filelist is a string 
  344. else if (is_string($p_filelist)) { 
  345. // ----- Create a list from the string 
  346. $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); 
  347.  
  348. // ----- Invalid variable type for $p_filelist 
  349. else { 
  350. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist"); 
  351. return 0; 
  352.  
  353. // ----- Reformat the string list 
  354. if (sizeof($v_string_list) != 0) { 
  355. foreach ($v_string_list as $v_string) { 
  356. if ($v_string != '') { 
  357. $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; 
  358. else { 
  359.  
  360. // ----- For each file in the list check the attributes 
  361. $v_supported_attributes 
  362. = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' 
  363. , PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' 
  364. , PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' 
  365. , PCLZIP_ATT_FILE_MTIME => 'optional' 
  366. , PCLZIP_ATT_FILE_CONTENT => 'optional' 
  367. , PCLZIP_ATT_FILE_COMMENT => 'optional' 
  368. ); 
  369. foreach ($v_att_list as $v_entry) { 
  370. $v_result = $this->privFileDescrParseAtt($v_entry,  
  371. $v_filedescr_list[],  
  372. $v_options,  
  373. $v_supported_attributes); 
  374. if ($v_result != 1) { 
  375. return 0; 
  376.  
  377. // ----- Expand the filelist (expand directories) 
  378. $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); 
  379. if ($v_result != 1) { 
  380. return 0; 
  381.  
  382. // ----- Call the create fct 
  383. $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options); 
  384. if ($v_result != 1) { 
  385. return 0; 
  386.  
  387. // ----- Return 
  388. return $p_result_list; 
  389. // -------------------------------------------------------------------------------- 
  390.  
  391. // -------------------------------------------------------------------------------- 
  392. // Function : 
  393. // add($p_filelist, $p_add_dir="", $p_remove_dir="") 
  394. // add($p_filelist, $p_option, $p_option_value, ...) 
  395. // Description : 
  396. // This method supports two synopsis. The first one is historical. 
  397. // This methods add the list of files in an existing archive. 
  398. // If a file with the same name already exists, it is added at the end of the 
  399. // archive, the first one is still present. 
  400. // If the archive does not exist, it is created. 
  401. // Parameters : 
  402. // $p_filelist : An array containing file or directory names, or 
  403. // a string containing one filename or one directory name, or 
  404. // a string containing a list of filenames and/or directory 
  405. // names separated by spaces. 
  406. // $p_add_dir : A path to add before the real path of the archived file,  
  407. // in order to have it memorized in the archive. 
  408. // $p_remove_dir : A path to remove from the real path of the file to archive,  
  409. // in order to have a shorter path memorized in the archive. 
  410. // When $p_add_dir and $p_remove_dir are set, $p_remove_dir 
  411. // is removed first, before $p_add_dir is added. 
  412. // Options : 
  413. // PCLZIP_OPT_ADD_PATH : 
  414. // PCLZIP_OPT_REMOVE_PATH : 
  415. // PCLZIP_OPT_REMOVE_ALL_PATH : 
  416. // PCLZIP_OPT_COMMENT : 
  417. // PCLZIP_OPT_ADD_COMMENT : 
  418. // PCLZIP_OPT_PREPEND_COMMENT : 
  419. // PCLZIP_CB_PRE_ADD : 
  420. // PCLZIP_CB_POST_ADD : 
  421. // Return Values : 
  422. // 0 on failure,  
  423. // The list of the added files, with a status of the add action. 
  424. // (see PclZip::listContent() for list entry format) 
  425. // -------------------------------------------------------------------------------- 
  426. function add($p_filelist) 
  427. $v_result=1; 
  428.  
  429. // ----- Reset the error handler 
  430. $this->privErrorReset(); 
  431.  
  432. // ----- Set default values 
  433. $v_options = array(); 
  434. $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; 
  435.  
  436. // ----- Look for variable options arguments 
  437. $v_size = func_num_args(); 
  438.  
  439. // ----- Look for arguments 
  440. if ($v_size > 1) { 
  441. // ----- Get the arguments 
  442. $v_arg_list = func_get_args(); 
  443.  
  444. // ----- Remove form the options list the first argument 
  445. array_shift($v_arg_list); 
  446. $v_size--; 
  447.  
  448. // ----- Look for first arg 
  449. if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { 
  450.  
  451. // ----- Parse the options 
  452. $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,  
  453. array (PCLZIP_OPT_REMOVE_PATH => 'optional',  
  454. PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',  
  455. PCLZIP_OPT_ADD_PATH => 'optional',  
  456. PCLZIP_CB_PRE_ADD => 'optional',  
  457. PCLZIP_CB_POST_ADD => 'optional',  
  458. PCLZIP_OPT_NO_COMPRESSION => 'optional',  
  459. PCLZIP_OPT_COMMENT => 'optional',  
  460. PCLZIP_OPT_ADD_COMMENT => 'optional',  
  461. PCLZIP_OPT_PREPEND_COMMENT => 'optional',  
  462. PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',  
  463. PCLZIP_OPT_TEMP_FILE_ON => 'optional',  
  464. PCLZIP_OPT_TEMP_FILE_OFF => 'optional' 
  465. //, PCLZIP_OPT_CRYPT => 'optional' 
  466. )); 
  467. if ($v_result != 1) { 
  468. return 0; 
  469.  
  470. // ----- Look for 2 args 
  471. // Here we need to support the first historic synopsis of the 
  472. // method. 
  473. else { 
  474.  
  475. // ----- Get the first argument 
  476. $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0]; 
  477.  
  478. // ----- Look for the optional second argument 
  479. if ($v_size == 2) { 
  480. $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; 
  481. else if ($v_size > 2) { 
  482. // ----- Error log 
  483. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); 
  484.  
  485. // ----- Return 
  486. return 0; 
  487.  
  488. // ----- Look for default option values 
  489. $this->privOptionDefaultThreshold($v_options); 
  490.  
  491. // ----- Init 
  492. $v_string_list = array(); 
  493. $v_att_list = array(); 
  494. $v_filedescr_list = array(); 
  495. $p_result_list = array(); 
  496.  
  497. // ----- Look if the $p_filelist is really an array 
  498. if (is_array($p_filelist)) { 
  499.  
  500. // ----- Look if the first element is also an array 
  501. // This will mean that this is a file description entry 
  502. if (isset($p_filelist[0]) && is_array($p_filelist[0])) { 
  503. $v_att_list = $p_filelist; 
  504.  
  505. // ----- The list is a list of string names 
  506. else { 
  507. $v_string_list = $p_filelist; 
  508.  
  509. // ----- Look if the $p_filelist is a string 
  510. else if (is_string($p_filelist)) { 
  511. // ----- Create a list from the string 
  512. $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); 
  513.  
  514. // ----- Invalid variable type for $p_filelist 
  515. else { 
  516. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist"); 
  517. return 0; 
  518.  
  519. // ----- Reformat the string list 
  520. if (sizeof($v_string_list) != 0) { 
  521. foreach ($v_string_list as $v_string) { 
  522. $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; 
  523.  
  524. // ----- For each file in the list check the attributes 
  525. $v_supported_attributes 
  526. = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' 
  527. , PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' 
  528. , PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' 
  529. , PCLZIP_ATT_FILE_MTIME => 'optional' 
  530. , PCLZIP_ATT_FILE_CONTENT => 'optional' 
  531. , PCLZIP_ATT_FILE_COMMENT => 'optional' 
  532. ); 
  533. foreach ($v_att_list as $v_entry) { 
  534. $v_result = $this->privFileDescrParseAtt($v_entry,  
  535. $v_filedescr_list[],  
  536. $v_options,  
  537. $v_supported_attributes); 
  538. if ($v_result != 1) { 
  539. return 0; 
  540.  
  541. // ----- Expand the filelist (expand directories) 
  542. $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); 
  543. if ($v_result != 1) { 
  544. return 0; 
  545.  
  546. // ----- Call the create fct 
  547. $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options); 
  548. if ($v_result != 1) { 
  549. return 0; 
  550.  
  551. // ----- Return 
  552. return $p_result_list; 
  553. // -------------------------------------------------------------------------------- 
  554.  
  555. // -------------------------------------------------------------------------------- 
  556. // Function : listContent() 
  557. // Description : 
  558. // This public method, gives the list of the files and directories, with their 
  559. // properties. 
  560. // The properties of each entries in the list are (used also in other functions) : 
  561. // filename : Name of the file. For a create or add action it is the filename 
  562. // given by the user. For an extract function it is the filename 
  563. // of the extracted file. 
  564. // stored_filename : Name of the file / directory stored in the archive. 
  565. // size : Size of the stored file. 
  566. // compressed_size : Size of the file's data compressed in the archive 
  567. // (without the headers overhead) 
  568. // mtime : Last known modification date of the file (UNIX timestamp) 
  569. // comment : Comment associated with the file 
  570. // folder : true | false 
  571. // index : index of the file in the archive 
  572. // status : status of the action (depending of the action) : 
  573. // Values are : 
  574. // ok : OK ! 
  575. // filtered : the file / dir is not extracted (filtered by user) 
  576. // already_a_directory : the file can not be extracted because a 
  577. // directory with the same name already exists 
  578. // write_protected : the file can not be extracted because a file 
  579. // with the same name already exists and is 
  580. // write protected 
  581. // newer_exist : the file was not extracted because a newer file exists 
  582. // path_creation_fail : the file is not extracted because the folder 
  583. // does not exist and can not be created 
  584. // write_error : the file was not extracted because there was a 
  585. // error while writing the file 
  586. // read_error : the file was not extracted because there was a error 
  587. // while reading the file 
  588. // invalid_header : the file was not extracted because of an archive 
  589. // format error (bad file header) 
  590. // Note that each time a method can continue operating when there 
  591. // is an action error on a file, the error is only logged in the file status. 
  592. // Return Values : 
  593. // 0 on an unrecoverable failure,  
  594. // The list of the files in the archive. 
  595. // -------------------------------------------------------------------------------- 
  596. function listContent() 
  597. $v_result=1; 
  598.  
  599. // ----- Reset the error handler 
  600. $this->privErrorReset(); 
  601.  
  602. // ----- Check archive 
  603. if (!$this->privCheckFormat()) { 
  604. return(0); 
  605.  
  606. // ----- Call the extracting fct 
  607. $p_list = array(); 
  608. if (($v_result = $this->privList($p_list)) != 1) 
  609. unset($p_list); 
  610. return(0); 
  611.  
  612. // ----- Return 
  613. return $p_list; 
  614. // -------------------------------------------------------------------------------- 
  615.  
  616. // -------------------------------------------------------------------------------- 
  617. // Function : 
  618. // extract($p_path="./", $p_remove_path="") 
  619. // extract([$p_option, $p_option_value, ...]) 
  620. // Description : 
  621. // This method supports two synopsis. The first one is historical. 
  622. // This method extract all the files / directories from the archive to the 
  623. // folder indicated in $p_path. 
  624. // If you want to ignore the 'root' part of path of the memorized files 
  625. // you can indicate this in the optional $p_remove_path parameter. 
  626. // By default, if a newer file with the same name already exists, the 
  627. // file is not extracted. 
  628. // 
  629. // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions 
  630. // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append 
  631. // at the end of the path value of PCLZIP_OPT_PATH. 
  632. // Parameters : 
  633. // $p_path : Path where the files and directories are to be extracted 
  634. // $p_remove_path : First part ('root' part) of the memorized path 
  635. // (if any similar) to remove while extracting. 
  636. // Options : 
  637. // PCLZIP_OPT_PATH : 
  638. // PCLZIP_OPT_ADD_PATH : 
  639. // PCLZIP_OPT_REMOVE_PATH : 
  640. // PCLZIP_OPT_REMOVE_ALL_PATH : 
  641. // PCLZIP_CB_PRE_EXTRACT : 
  642. // PCLZIP_CB_POST_EXTRACT : 
  643. // Return Values : 
  644. // 0 or a negative value on failure,  
  645. // The list of the extracted files, with a status of the action. 
  646. // (see PclZip::listContent() for list entry format) 
  647. // -------------------------------------------------------------------------------- 
  648. function extract() 
  649. $v_result=1; 
  650.  
  651. // ----- Reset the error handler 
  652. $this->privErrorReset(); 
  653.  
  654. // ----- Check archive 
  655. if (!$this->privCheckFormat()) { 
  656. return(0); 
  657.  
  658. // ----- Set default values 
  659. $v_options = array(); 
  660. // $v_path = "./"; 
  661. $v_path = ''; 
  662. $v_remove_path = ""; 
  663. $v_remove_all_path = false; 
  664.  
  665. // ----- Look for variable options arguments 
  666. $v_size = func_num_args(); 
  667.  
  668. // ----- Default values for option 
  669. $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; 
  670.  
  671. // ----- Look for arguments 
  672. if ($v_size > 0) { 
  673. // ----- Get the arguments 
  674. $v_arg_list = func_get_args(); 
  675.  
  676. // ----- Look for first arg 
  677. if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { 
  678.  
  679. // ----- Parse the options 
  680. $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,  
  681. array (PCLZIP_OPT_PATH => 'optional',  
  682. PCLZIP_OPT_REMOVE_PATH => 'optional',  
  683. PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',  
  684. PCLZIP_OPT_ADD_PATH => 'optional',  
  685. PCLZIP_CB_PRE_EXTRACT => 'optional',  
  686. PCLZIP_CB_POST_EXTRACT => 'optional',  
  687. PCLZIP_OPT_SET_CHMOD => 'optional',  
  688. PCLZIP_OPT_BY_NAME => 'optional',  
  689. PCLZIP_OPT_BY_EREG => 'optional',  
  690. PCLZIP_OPT_BY_PREG => 'optional',  
  691. PCLZIP_OPT_BY_INDEX => 'optional',  
  692. PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',  
  693. PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',  
  694. PCLZIP_OPT_REPLACE_NEWER => 'optional' 
  695. , PCLZIP_OPT_STOP_ON_ERROR => 'optional' 
  696. , PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',  
  697. PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',  
  698. PCLZIP_OPT_TEMP_FILE_ON => 'optional',  
  699. PCLZIP_OPT_TEMP_FILE_OFF => 'optional' 
  700. )); 
  701. if ($v_result != 1) { 
  702. return 0; 
  703.  
  704. // ----- Set the arguments 
  705. if (isset($v_options[PCLZIP_OPT_PATH])) { 
  706. $v_path = $v_options[PCLZIP_OPT_PATH]; 
  707. if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { 
  708. $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; 
  709. if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { 
  710. $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; 
  711. if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { 
  712. // ----- Check for '/' in last path char 
  713. if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { 
  714. $v_path .= '/'; 
  715. $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; 
  716.  
  717. // ----- Look for 2 args 
  718. // Here we need to support the first historic synopsis of the 
  719. // method. 
  720. else { 
  721.  
  722. // ----- Get the first argument 
  723. $v_path = $v_arg_list[0]; 
  724.  
  725. // ----- Look for the optional second argument 
  726. if ($v_size == 2) { 
  727. $v_remove_path = $v_arg_list[1]; 
  728. else if ($v_size > 2) { 
  729. // ----- Error log 
  730. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); 
  731.  
  732. // ----- Return 
  733. return 0; 
  734.  
  735. // ----- Look for default option values 
  736. $this->privOptionDefaultThreshold($v_options); 
  737.  
  738. // ----- Trace 
  739.  
  740. // ----- Call the extracting fct 
  741. $p_list = array(); 
  742. $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,  
  743. $v_remove_all_path, $v_options); 
  744. if ($v_result < 1) { 
  745. unset($p_list); 
  746. return(0); 
  747.  
  748. // ----- Return 
  749. return $p_list; 
  750. // -------------------------------------------------------------------------------- 
  751.  
  752.  
  753. // -------------------------------------------------------------------------------- 
  754. // Function : 
  755. // extractByIndex($p_index, $p_path="./", $p_remove_path="") 
  756. // extractByIndex($p_index, [$p_option, $p_option_value, ...]) 
  757. // Description : 
  758. // This method supports two synopsis. The first one is historical. 
  759. // This method is doing a partial extract of the archive. 
  760. // The extracted files or folders are identified by their index in the 
  761. // archive (from 0 to n). 
  762. // Note that if the index identify a folder, only the folder entry is 
  763. // extracted, not all the files included in the archive. 
  764. // Parameters : 
  765. // $p_index : A single index (integer) or a string of indexes of files to 
  766. // extract. The form of the string is "0, 4-6, 8-12" with only numbers 
  767. // and '-' for range or ', ' to separate ranges. No spaces or ';' 
  768. // are allowed. 
  769. // $p_path : Path where the files and directories are to be extracted 
  770. // $p_remove_path : First part ('root' part) of the memorized path 
  771. // (if any similar) to remove while extracting. 
  772. // Options : 
  773. // PCLZIP_OPT_PATH : 
  774. // PCLZIP_OPT_ADD_PATH : 
  775. // PCLZIP_OPT_REMOVE_PATH : 
  776. // PCLZIP_OPT_REMOVE_ALL_PATH : 
  777. // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and 
  778. // not as files. 
  779. // The resulting content is in a new field 'content' in the file 
  780. // structure. 
  781. // This option must be used alone (any other options are ignored). 
  782. // PCLZIP_CB_PRE_EXTRACT : 
  783. // PCLZIP_CB_POST_EXTRACT : 
  784. // Return Values : 
  785. // 0 on failure,  
  786. // The list of the extracted files, with a status of the action. 
  787. // (see PclZip::listContent() for list entry format) 
  788. // -------------------------------------------------------------------------------- 
  789. //function extractByIndex($p_index, options...) 
  790. function extractByIndex($p_index) 
  791. $v_result=1; 
  792.  
  793. // ----- Reset the error handler 
  794. $this->privErrorReset(); 
  795.  
  796. // ----- Check archive 
  797. if (!$this->privCheckFormat()) { 
  798. return(0); 
  799.  
  800. // ----- Set default values 
  801. $v_options = array(); 
  802. // $v_path = "./"; 
  803. $v_path = ''; 
  804. $v_remove_path = ""; 
  805. $v_remove_all_path = false; 
  806.  
  807. // ----- Look for variable options arguments 
  808. $v_size = func_num_args(); 
  809.  
  810. // ----- Default values for option 
  811. $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; 
  812.  
  813. // ----- Look for arguments 
  814. if ($v_size > 1) { 
  815. // ----- Get the arguments 
  816. $v_arg_list = func_get_args(); 
  817.  
  818. // ----- Remove form the options list the first argument 
  819. array_shift($v_arg_list); 
  820. $v_size--; 
  821.  
  822. // ----- Look for first arg 
  823. if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { 
  824.  
  825. // ----- Parse the options 
  826. $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,  
  827. array (PCLZIP_OPT_PATH => 'optional',  
  828. PCLZIP_OPT_REMOVE_PATH => 'optional',  
  829. PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',  
  830. PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',  
  831. PCLZIP_OPT_ADD_PATH => 'optional',  
  832. PCLZIP_CB_PRE_EXTRACT => 'optional',  
  833. PCLZIP_CB_POST_EXTRACT => 'optional',  
  834. PCLZIP_OPT_SET_CHMOD => 'optional',  
  835. PCLZIP_OPT_REPLACE_NEWER => 'optional' 
  836. , PCLZIP_OPT_STOP_ON_ERROR => 'optional' 
  837. , PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',  
  838. PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',  
  839. PCLZIP_OPT_TEMP_FILE_ON => 'optional',  
  840. PCLZIP_OPT_TEMP_FILE_OFF => 'optional' 
  841. )); 
  842. if ($v_result != 1) { 
  843. return 0; 
  844.  
  845. // ----- Set the arguments 
  846. if (isset($v_options[PCLZIP_OPT_PATH])) { 
  847. $v_path = $v_options[PCLZIP_OPT_PATH]; 
  848. if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { 
  849. $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; 
  850. if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { 
  851. $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; 
  852. if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { 
  853. // ----- Check for '/' in last path char 
  854. if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { 
  855. $v_path .= '/'; 
  856. $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; 
  857. if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) { 
  858. $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; 
  859. else { 
  860.  
  861. // ----- Look for 2 args 
  862. // Here we need to support the first historic synopsis of the 
  863. // method. 
  864. else { 
  865.  
  866. // ----- Get the first argument 
  867. $v_path = $v_arg_list[0]; 
  868.  
  869. // ----- Look for the optional second argument 
  870. if ($v_size == 2) { 
  871. $v_remove_path = $v_arg_list[1]; 
  872. else if ($v_size > 2) { 
  873. // ----- Error log 
  874. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); 
  875.  
  876. // ----- Return 
  877. return 0; 
  878.  
  879. // ----- Trace 
  880.  
  881. // ----- Trick 
  882. // Here I want to reuse extractByRule(), so I need to parse the $p_index 
  883. // with privParseOptions() 
  884. $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index); 
  885. $v_options_trick = array(); 
  886. $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,  
  887. array (PCLZIP_OPT_BY_INDEX => 'optional' )); 
  888. if ($v_result != 1) { 
  889. return 0; 
  890. $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX]; 
  891.  
  892. // ----- Look for default option values 
  893. $this->privOptionDefaultThreshold($v_options); 
  894.  
  895. // ----- Call the extracting fct 
  896. if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) { 
  897. return(0); 
  898.  
  899. // ----- Return 
  900. return $p_list; 
  901. // -------------------------------------------------------------------------------- 
  902.  
  903. // -------------------------------------------------------------------------------- 
  904. // Function : 
  905. // delete([$p_option, $p_option_value, ...]) 
  906. // Description : 
  907. // This method removes files from the archive. 
  908. // If no parameters are given, then all the archive is emptied. 
  909. // Parameters : 
  910. // None or optional arguments. 
  911. // Options : 
  912. // PCLZIP_OPT_BY_INDEX : 
  913. // PCLZIP_OPT_BY_NAME : 
  914. // PCLZIP_OPT_BY_EREG : 
  915. // PCLZIP_OPT_BY_PREG : 
  916. // Return Values : 
  917. // 0 on failure,  
  918. // The list of the files which are still present in the archive. 
  919. // (see PclZip::listContent() for list entry format) 
  920. // -------------------------------------------------------------------------------- 
  921. function delete() 
  922. $v_result=1; 
  923.  
  924. // ----- Reset the error handler 
  925. $this->privErrorReset(); 
  926.  
  927. // ----- Check archive 
  928. if (!$this->privCheckFormat()) { 
  929. return(0); 
  930.  
  931. // ----- Set default values 
  932. $v_options = array(); 
  933.  
  934. // ----- Look for variable options arguments 
  935. $v_size = func_num_args(); 
  936.  
  937. // ----- Look for arguments 
  938. if ($v_size > 0) { 
  939. // ----- Get the arguments 
  940. $v_arg_list = func_get_args(); 
  941.  
  942. // ----- Parse the options 
  943. $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,  
  944. array (PCLZIP_OPT_BY_NAME => 'optional',  
  945. PCLZIP_OPT_BY_EREG => 'optional',  
  946. PCLZIP_OPT_BY_PREG => 'optional',  
  947. PCLZIP_OPT_BY_INDEX => 'optional' )); 
  948. if ($v_result != 1) { 
  949. return 0; 
  950.  
  951. // ----- Magic quotes trick 
  952. $this->privDisableMagicQuotes(); 
  953.  
  954. // ----- Call the delete fct 
  955. $v_list = array(); 
  956. if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) { 
  957. $this->privSwapBackMagicQuotes(); 
  958. unset($v_list); 
  959. return(0); 
  960.  
  961. // ----- Magic quotes trick 
  962. $this->privSwapBackMagicQuotes(); 
  963.  
  964. // ----- Return 
  965. return $v_list; 
  966. // -------------------------------------------------------------------------------- 
  967.  
  968. // -------------------------------------------------------------------------------- 
  969. // Function : deleteByIndex() 
  970. // Description : 
  971. // ***** Deprecated ***** 
  972. // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered. 
  973. // -------------------------------------------------------------------------------- 
  974. function deleteByIndex($p_index) 
  975.  
  976. $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index); 
  977.  
  978. // ----- Return 
  979. return $p_list; 
  980. // -------------------------------------------------------------------------------- 
  981.  
  982. // -------------------------------------------------------------------------------- 
  983. // Function : properties() 
  984. // Description : 
  985. // This method gives the properties of the archive. 
  986. // The properties are : 
  987. // nb : Number of files in the archive 
  988. // comment : Comment associated with the archive file 
  989. // status : not_exist, ok 
  990. // Parameters : 
  991. // None 
  992. // Return Values : 
  993. // 0 on failure,  
  994. // An array with the archive properties. 
  995. // -------------------------------------------------------------------------------- 
  996. function properties() 
  997.  
  998. // ----- Reset the error handler 
  999. $this->privErrorReset(); 
  1000.  
  1001. // ----- Magic quotes trick 
  1002. $this->privDisableMagicQuotes(); 
  1003.  
  1004. // ----- Check archive 
  1005. if (!$this->privCheckFormat()) { 
  1006. $this->privSwapBackMagicQuotes(); 
  1007. return(0); 
  1008.  
  1009. // ----- Default properties 
  1010. $v_prop = array(); 
  1011. $v_prop['comment'] = ''; 
  1012. $v_prop['nb'] = 0; 
  1013. $v_prop['status'] = 'not_exist'; 
  1014.  
  1015. // ----- Look if file exists 
  1016. if (@is_file($this->zipname)) 
  1017. // ----- Open the zip file 
  1018. if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) 
  1019. $this->privSwapBackMagicQuotes(); 
  1020.  
  1021. // ----- Error log 
  1022. PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); 
  1023.  
  1024. // ----- Return 
  1025. return 0; 
  1026.  
  1027. // ----- Read the central directory informations 
  1028. $v_central_dir = array(); 
  1029. if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) 
  1030. $this->privSwapBackMagicQuotes(); 
  1031. return 0; 
  1032.  
  1033. // ----- Close the zip file 
  1034. $this->privCloseFd(); 
  1035.  
  1036. // ----- Set the user attributes 
  1037. $v_prop['comment'] = $v_central_dir['comment']; 
  1038. $v_prop['nb'] = $v_central_dir['entries']; 
  1039. $v_prop['status'] = 'ok'; 
  1040.  
  1041. // ----- Magic quotes trick 
  1042. $this->privSwapBackMagicQuotes(); 
  1043.  
  1044. // ----- Return 
  1045. return $v_prop; 
  1046. // -------------------------------------------------------------------------------- 
  1047.  
  1048. // -------------------------------------------------------------------------------- 
  1049. // Function : duplicate() 
  1050. // Description : 
  1051. // This method creates an archive by copying the content of an other one. If 
  1052. // the archive already exist, it is replaced by the new one without any warning. 
  1053. // Parameters : 
  1054. // $p_archive : The filename of a valid archive, or 
  1055. // a valid PclZip object. 
  1056. // Return Values : 
  1057. // 1 on success. 
  1058. // 0 or a negative value on error (error code). 
  1059. // -------------------------------------------------------------------------------- 
  1060. function duplicate($p_archive) 
  1061. $v_result = 1; 
  1062.  
  1063. // ----- Reset the error handler 
  1064. $this->privErrorReset(); 
  1065.  
  1066. // ----- Look if the $p_archive is a PclZip object 
  1067. if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) 
  1068.  
  1069. // ----- Duplicate the archive 
  1070. $v_result = $this->privDuplicate($p_archive->zipname); 
  1071.  
  1072. // ----- Look if the $p_archive is a string (so a filename) 
  1073. else if (is_string($p_archive)) 
  1074.  
  1075. // ----- Check that $p_archive is a valid zip file 
  1076. // TBC : Should also check the archive format 
  1077. if (!is_file($p_archive)) { 
  1078. // ----- Error log 
  1079. PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'"); 
  1080. $v_result = PCLZIP_ERR_MISSING_FILE; 
  1081. else { 
  1082. // ----- Duplicate the archive 
  1083. $v_result = $this->privDuplicate($p_archive); 
  1084.  
  1085. // ----- Invalid variable 
  1086. else 
  1087. // ----- Error log 
  1088. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); 
  1089. $v_result = PCLZIP_ERR_INVALID_PARAMETER; 
  1090.  
  1091. // ----- Return 
  1092. return $v_result; 
  1093. // -------------------------------------------------------------------------------- 
  1094.  
  1095. // -------------------------------------------------------------------------------- 
  1096. // Function : merge() 
  1097. // Description : 
  1098. // This method merge the $p_archive_to_add archive at the end of the current 
  1099. // one ($this). 
  1100. // If the archive ($this) does not exist, the merge becomes a duplicate. 
  1101. // If the $p_archive_to_add archive does not exist, the merge is a success. 
  1102. // Parameters : 
  1103. // $p_archive_to_add : It can be directly the filename of a valid zip archive,  
  1104. // or a PclZip object archive. 
  1105. // Return Values : 
  1106. // 1 on success,  
  1107. // 0 or negative values on error (see below). 
  1108. // -------------------------------------------------------------------------------- 
  1109. function merge($p_archive_to_add) 
  1110. $v_result = 1; 
  1111.  
  1112. // ----- Reset the error handler 
  1113. $this->privErrorReset(); 
  1114.  
  1115. // ----- Check archive 
  1116. if (!$this->privCheckFormat()) { 
  1117. return(0); 
  1118.  
  1119. // ----- Look if the $p_archive_to_add is a PclZip object 
  1120. if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) 
  1121.  
  1122. // ----- Merge the archive 
  1123. $v_result = $this->privMerge($p_archive_to_add); 
  1124.  
  1125. // ----- Look if the $p_archive_to_add is a string (so a filename) 
  1126. else if (is_string($p_archive_to_add)) 
  1127.  
  1128. // ----- Create a temporary archive 
  1129. $v_object_archive = new PclZip($p_archive_to_add); 
  1130.  
  1131. // ----- Merge the archive 
  1132. $v_result = $this->privMerge($v_object_archive); 
  1133.  
  1134. // ----- Invalid variable 
  1135. else 
  1136. // ----- Error log 
  1137. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); 
  1138. $v_result = PCLZIP_ERR_INVALID_PARAMETER; 
  1139.  
  1140. // ----- Return 
  1141. return $v_result; 
  1142. // -------------------------------------------------------------------------------- 
  1143.  
  1144.  
  1145.  
  1146. // -------------------------------------------------------------------------------- 
  1147. // Function : errorCode() 
  1148. // Description : 
  1149. // Parameters : 
  1150. // -------------------------------------------------------------------------------- 
  1151. function errorCode() 
  1152. if (PCLZIP_ERROR_EXTERNAL == 1) { 
  1153. return(PclErrorCode()); 
  1154. else { 
  1155. return($this->error_code); 
  1156. // -------------------------------------------------------------------------------- 
  1157.  
  1158. // -------------------------------------------------------------------------------- 
  1159. // Function : errorName() 
  1160. // Description : 
  1161. // Parameters : 
  1162. // -------------------------------------------------------------------------------- 
  1163. function errorName($p_with_code=false) 
  1164. $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',  
  1165. PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',  
  1166. PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',  
  1167. PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',  
  1168. PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',  
  1169. PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',  
  1170. PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',  
  1171. PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',  
  1172. PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',  
  1173. PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',  
  1174. PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',  
  1175. PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',  
  1176. PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',  
  1177. PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',  
  1178. PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',  
  1179. PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',  
  1180. PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',  
  1181. PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',  
  1182. PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION' 
  1183. , PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE' 
  1184. , PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION' 
  1185. ); 
  1186.  
  1187. if (isset($v_name[$this->error_code])) { 
  1188. $v_value = $v_name[$this->error_code]; 
  1189. else { 
  1190. $v_value = 'NoName'; 
  1191.  
  1192. if ($p_with_code) { 
  1193. return($v_value.' ('.$this->error_code.')'); 
  1194. else { 
  1195. return($v_value); 
  1196. // -------------------------------------------------------------------------------- 
  1197.  
  1198. // -------------------------------------------------------------------------------- 
  1199. // Function : errorInfo() 
  1200. // Description : 
  1201. // Parameters : 
  1202. // -------------------------------------------------------------------------------- 
  1203. function errorInfo($p_full=false) 
  1204. if (PCLZIP_ERROR_EXTERNAL == 1) { 
  1205. return(PclErrorString()); 
  1206. else { 
  1207. if ($p_full) { 
  1208. return($this->errorName(true)." : ".$this->error_string); 
  1209. else { 
  1210. return($this->error_string." [code ".$this->error_code."]"); 
  1211. // -------------------------------------------------------------------------------- 
  1212.  
  1213.  
  1214. // -------------------------------------------------------------------------------- 
  1215. // ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS ***** 
  1216. // ***** ***** 
  1217. // ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY ***** 
  1218. // -------------------------------------------------------------------------------- 
  1219.  
  1220.  
  1221.  
  1222. // -------------------------------------------------------------------------------- 
  1223. // Function : privCheckFormat() 
  1224. // Description : 
  1225. // This method check that the archive exists and is a valid zip archive. 
  1226. // Several level of check exists. (futur) 
  1227. // Parameters : 
  1228. // $p_level : Level of check. Default 0. 
  1229. // 0 : Check the first bytes (magic codes) (default value)) 
  1230. // 1 : 0 + Check the central directory (futur) 
  1231. // 2 : 1 + Check each file header (futur) 
  1232. // Return Values : 
  1233. // true on success,  
  1234. // false on error, the error code is set. 
  1235. // -------------------------------------------------------------------------------- 
  1236. function privCheckFormat($p_level=0) 
  1237. $v_result = true; 
  1238.  
  1239. // ----- Reset the file system cache 
  1240. clearstatcache(); 
  1241.  
  1242. // ----- Reset the error handler 
  1243. $this->privErrorReset(); 
  1244.  
  1245. // ----- Look if the file exits 
  1246. if (!is_file($this->zipname)) { 
  1247. // ----- Error log 
  1248. PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'"); 
  1249. return(false); 
  1250.  
  1251. // ----- Check that the file is readeable 
  1252. if (!is_readable($this->zipname)) { 
  1253. // ----- Error log 
  1254. PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'"); 
  1255. return(false); 
  1256.  
  1257. // ----- Check the magic code 
  1258. // TBC 
  1259.  
  1260. // ----- Check the central header 
  1261. // TBC 
  1262.  
  1263. // ----- Check each file header 
  1264. // TBC 
  1265.  
  1266. // ----- Return 
  1267. return $v_result; 
  1268. // -------------------------------------------------------------------------------- 
  1269.  
  1270. // -------------------------------------------------------------------------------- 
  1271. // Function : privParseOptions() 
  1272. // Description : 
  1273. // This internal methods reads the variable list of arguments ($p_options_list,  
  1274. // $p_size) and generate an array with the options and values ($v_result_list). 
  1275. // $v_requested_options contains the options that can be present and those that 
  1276. // must be present. 
  1277. // $v_requested_options is an array, with the option value as key, and 'optional',  
  1278. // or 'mandatory' as value. 
  1279. // Parameters : 
  1280. // See above. 
  1281. // Return Values : 
  1282. // 1 on success. 
  1283. // 0 on failure. 
  1284. // -------------------------------------------------------------------------------- 
  1285. function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false) 
  1286. $v_result=1; 
  1287.  
  1288. // ----- Read the options 
  1289. $i=0; 
  1290. while ($i<$p_size) { 
  1291.  
  1292. // ----- Check if the option is supported 
  1293. if (!isset($v_requested_options[$p_options_list[$i]])) { 
  1294. // ----- Error log 
  1295. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method"); 
  1296.  
  1297. // ----- Return 
  1298. return PclZip::errorCode(); 
  1299.  
  1300. // ----- Look for next option 
  1301. switch ($p_options_list[$i]) { 
  1302. // ----- Look for options that request a path value 
  1303. case PCLZIP_OPT_PATH : 
  1304. case PCLZIP_OPT_REMOVE_PATH : 
  1305. case PCLZIP_OPT_ADD_PATH : 
  1306. // ----- Check the number of parameters 
  1307. if (($i+1) >= $p_size) { 
  1308. // ----- Error log 
  1309. PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1310.  
  1311. // ----- Return 
  1312. return PclZip::errorCode(); 
  1313.  
  1314. // ----- Get the value 
  1315. $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); 
  1316. $i++; 
  1317. break; 
  1318.  
  1319. case PCLZIP_OPT_TEMP_FILE_THRESHOLD : 
  1320. // ----- Check the number of parameters 
  1321. if (($i+1) >= $p_size) { 
  1322. PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1323. return PclZip::errorCode(); 
  1324.  
  1325. // ----- Check for incompatible options 
  1326. if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { 
  1327. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); 
  1328. return PclZip::errorCode(); 
  1329.  
  1330. // ----- Check the value 
  1331. $v_value = $p_options_list[$i+1]; 
  1332. if ((!is_integer($v_value)) || ($v_value<0)) { 
  1333. PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1334. return PclZip::errorCode(); 
  1335.  
  1336. // ----- Get the value (and convert it in bytes) 
  1337. $v_result_list[$p_options_list[$i]] = $v_value*1048576; 
  1338. $i++; 
  1339. break; 
  1340.  
  1341. case PCLZIP_OPT_TEMP_FILE_ON : 
  1342. // ----- Check for incompatible options 
  1343. if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { 
  1344. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); 
  1345. return PclZip::errorCode(); 
  1346.  
  1347. $v_result_list[$p_options_list[$i]] = true; 
  1348. break; 
  1349.  
  1350. case PCLZIP_OPT_TEMP_FILE_OFF : 
  1351. // ----- Check for incompatible options 
  1352. if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) { 
  1353. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'"); 
  1354. return PclZip::errorCode(); 
  1355. // ----- Check for incompatible options 
  1356. if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { 
  1357. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'"); 
  1358. return PclZip::errorCode(); 
  1359.  
  1360. $v_result_list[$p_options_list[$i]] = true; 
  1361. break; 
  1362.  
  1363. case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : 
  1364. // ----- Check the number of parameters 
  1365. if (($i+1) >= $p_size) { 
  1366. // ----- Error log 
  1367. PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1368.  
  1369. // ----- Return 
  1370. return PclZip::errorCode(); 
  1371.  
  1372. // ----- Get the value 
  1373. if ( is_string($p_options_list[$i+1]) 
  1374. && ($p_options_list[$i+1] != '')) { 
  1375. $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); 
  1376. $i++; 
  1377. else { 
  1378. break; 
  1379.  
  1380. // ----- Look for options that request an array of string for value 
  1381. case PCLZIP_OPT_BY_NAME : 
  1382. // ----- Check the number of parameters 
  1383. if (($i+1) >= $p_size) { 
  1384. // ----- Error log 
  1385. PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1386.  
  1387. // ----- Return 
  1388. return PclZip::errorCode(); 
  1389.  
  1390. // ----- Get the value 
  1391. if (is_string($p_options_list[$i+1])) { 
  1392. $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1]; 
  1393. else if (is_array($p_options_list[$i+1])) { 
  1394. $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; 
  1395. else { 
  1396. // ----- Error log 
  1397. PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1398.  
  1399. // ----- Return 
  1400. return PclZip::errorCode(); 
  1401. $i++; 
  1402. break; 
  1403.  
  1404. // ----- Look for options that request an EREG or PREG expression 
  1405. case PCLZIP_OPT_BY_EREG : 
  1406. // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG 
  1407. // to PCLZIP_OPT_BY_PREG 
  1408. $p_options_list[$i] = PCLZIP_OPT_BY_PREG; 
  1409. case PCLZIP_OPT_BY_PREG : 
  1410. //case PCLZIP_OPT_CRYPT : 
  1411. // ----- Check the number of parameters 
  1412. if (($i+1) >= $p_size) { 
  1413. // ----- Error log 
  1414. PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1415.  
  1416. // ----- Return 
  1417. return PclZip::errorCode(); 
  1418.  
  1419. // ----- Get the value 
  1420. if (is_string($p_options_list[$i+1])) { 
  1421. $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; 
  1422. else { 
  1423. // ----- Error log 
  1424. PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1425.  
  1426. // ----- Return 
  1427. return PclZip::errorCode(); 
  1428. $i++; 
  1429. break; 
  1430.  
  1431. // ----- Look for options that takes a string 
  1432. case PCLZIP_OPT_COMMENT : 
  1433. case PCLZIP_OPT_ADD_COMMENT : 
  1434. case PCLZIP_OPT_PREPEND_COMMENT : 
  1435. // ----- Check the number of parameters 
  1436. if (($i+1) >= $p_size) { 
  1437. // ----- Error log 
  1438. PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,  
  1439. "Missing parameter value for option '" 
  1440. .PclZipUtilOptionText($p_options_list[$i]) 
  1441. ."'"); 
  1442.  
  1443. // ----- Return 
  1444. return PclZip::errorCode(); 
  1445.  
  1446. // ----- Get the value 
  1447. if (is_string($p_options_list[$i+1])) { 
  1448. $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; 
  1449. else { 
  1450. // ----- Error log 
  1451. PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,  
  1452. "Wrong parameter value for option '" 
  1453. .PclZipUtilOptionText($p_options_list[$i]) 
  1454. ."'"); 
  1455.  
  1456. // ----- Return 
  1457. return PclZip::errorCode(); 
  1458. $i++; 
  1459. break; 
  1460.  
  1461. // ----- Look for options that request an array of index 
  1462. case PCLZIP_OPT_BY_INDEX : 
  1463. // ----- Check the number of parameters 
  1464. if (($i+1) >= $p_size) { 
  1465. // ----- Error log 
  1466. PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1467.  
  1468. // ----- Return 
  1469. return PclZip::errorCode(); 
  1470.  
  1471. // ----- Get the value 
  1472. $v_work_list = array(); 
  1473. if (is_string($p_options_list[$i+1])) { 
  1474.  
  1475. // ----- Remove spaces 
  1476. $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', ''); 
  1477.  
  1478. // ----- Parse items 
  1479. $v_work_list = explode(", ", $p_options_list[$i+1]); 
  1480. else if (is_integer($p_options_list[$i+1])) { 
  1481. $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1]; 
  1482. else if (is_array($p_options_list[$i+1])) { 
  1483. $v_work_list = $p_options_list[$i+1]; 
  1484. else { 
  1485. // ----- Error log 
  1486. PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1487.  
  1488. // ----- Return 
  1489. return PclZip::errorCode(); 
  1490.  
  1491. // ----- Reduce the index list 
  1492. // each index item in the list must be a couple with a start and 
  1493. // an end value : [0, 3], [5-5], [8-10], ... 
  1494. // ----- Check the format of each item 
  1495. $v_sort_flag=false; 
  1496. $v_sort_value=0; 
  1497. for ($j=0; $j<sizeof($v_work_list); $j++) { 
  1498. // ----- Explode the item 
  1499. $v_item_list = explode("-", $v_work_list[$j]); 
  1500. $v_size_item_list = sizeof($v_item_list); 
  1501.  
  1502. // ----- TBC : Here we might check that each item is a 
  1503. // real integer ... 
  1504.  
  1505. // ----- Look for single value 
  1506. if ($v_size_item_list == 1) { 
  1507. // ----- Set the option value 
  1508. $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; 
  1509. $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0]; 
  1510. elseif ($v_size_item_list == 2) { 
  1511. // ----- Set the option value 
  1512. $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; 
  1513. $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1]; 
  1514. else { 
  1515. // ----- Error log 
  1516. PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1517.  
  1518. // ----- Return 
  1519. return PclZip::errorCode(); 
  1520.  
  1521.  
  1522. // ----- Look for list sort 
  1523. if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) { 
  1524. $v_sort_flag=true; 
  1525.  
  1526. // ----- TBC : An automatic sort should be writen ... 
  1527. // ----- Error log 
  1528. PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1529.  
  1530. // ----- Return 
  1531. return PclZip::errorCode(); 
  1532. $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start']; 
  1533.  
  1534. // ----- Sort the items 
  1535. if ($v_sort_flag) { 
  1536. // TBC : To Be Completed 
  1537.  
  1538. // ----- Next option 
  1539. $i++; 
  1540. break; 
  1541.  
  1542. // ----- Look for options that request no value 
  1543. case PCLZIP_OPT_REMOVE_ALL_PATH : 
  1544. case PCLZIP_OPT_EXTRACT_AS_STRING : 
  1545. case PCLZIP_OPT_NO_COMPRESSION : 
  1546. case PCLZIP_OPT_EXTRACT_IN_OUTPUT : 
  1547. case PCLZIP_OPT_REPLACE_NEWER : 
  1548. case PCLZIP_OPT_STOP_ON_ERROR : 
  1549. $v_result_list[$p_options_list[$i]] = true; 
  1550. break; 
  1551.  
  1552. // ----- Look for options that request an octal value 
  1553. case PCLZIP_OPT_SET_CHMOD : 
  1554. // ----- Check the number of parameters 
  1555. if (($i+1) >= $p_size) { 
  1556. // ----- Error log 
  1557. PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1558.  
  1559. // ----- Return 
  1560. return PclZip::errorCode(); 
  1561.  
  1562. // ----- Get the value 
  1563. $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; 
  1564. $i++; 
  1565. break; 
  1566.  
  1567. // ----- Look for options that request a call-back 
  1568. case PCLZIP_CB_PRE_EXTRACT : 
  1569. case PCLZIP_CB_POST_EXTRACT : 
  1570. case PCLZIP_CB_PRE_ADD : 
  1571. case PCLZIP_CB_POST_ADD : 
  1572. /** for futur use 
  1573. case PCLZIP_CB_PRE_DELETE : 
  1574. case PCLZIP_CB_POST_DELETE : 
  1575. case PCLZIP_CB_PRE_LIST : 
  1576. case PCLZIP_CB_POST_LIST : 
  1577. */ 
  1578. // ----- Check the number of parameters 
  1579. if (($i+1) >= $p_size) { 
  1580. // ----- Error log 
  1581. PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1582.  
  1583. // ----- Return 
  1584. return PclZip::errorCode(); 
  1585.  
  1586. // ----- Get the value 
  1587. $v_function_name = $p_options_list[$i+1]; 
  1588.  
  1589. // ----- Check that the value is a valid existing function 
  1590. if (!function_exists($v_function_name)) { 
  1591. // ----- Error log 
  1592. PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1593.  
  1594. // ----- Return 
  1595. return PclZip::errorCode(); 
  1596.  
  1597. // ----- Set the attribute 
  1598. $v_result_list[$p_options_list[$i]] = $v_function_name; 
  1599. $i++; 
  1600. break; 
  1601.  
  1602. default : 
  1603. // ----- Error log 
  1604. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,  
  1605. "Unknown parameter '" 
  1606. .$p_options_list[$i]."'"); 
  1607.  
  1608. // ----- Return 
  1609. return PclZip::errorCode(); 
  1610.  
  1611. // ----- Next option
  1612. $i++; 
  1613.  
  1614. // ----- Look for mandatory options 
  1615. if ($v_requested_options !== false) { 
  1616. for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { 
  1617. // ----- Look for mandatory option 
  1618. if ($v_requested_options[$key] == 'mandatory') { 
  1619. // ----- Look if present 
  1620. if (!isset($v_result_list[$key])) { 
  1621. // ----- Error log 
  1622. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); 
  1623.  
  1624. // ----- Return 
  1625. return PclZip::errorCode(); 
  1626.  
  1627. // ----- Look for default values 
  1628. if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { 
  1629.  
  1630.  
  1631. // ----- Return 
  1632. return $v_result; 
  1633. // -------------------------------------------------------------------------------- 
  1634.  
  1635. // -------------------------------------------------------------------------------- 
  1636. // Function : privOptionDefaultThreshold() 
  1637. // Description : 
  1638. // Parameters : 
  1639. // Return Values : 
  1640. // -------------------------------------------------------------------------------- 
  1641. function privOptionDefaultThreshold(&$p_options) 
  1642. $v_result=1; 
  1643.  
  1644. if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) 
  1645. || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) { 
  1646. return $v_result; 
  1647.  
  1648. // ----- Get 'memory_limit' configuration value 
  1649. $v_memory_limit = ini_get('memory_limit'); 
  1650. $v_memory_limit = trim($v_memory_limit); 
  1651. $v_memory_limit_int = (int) $v_memory_limit; 
  1652. $last = strtolower(substr($v_memory_limit, -1)); 
  1653.  
  1654. if($last == 'g') 
  1655. //$v_memory_limit_int = $v_memory_limit_int*1024*1024*1024; 
  1656. $v_memory_limit_int = $v_memory_limit_int*1073741824; 
  1657. if($last == 'm') 
  1658. //$v_memory_limit_int = $v_memory_limit_int*1024*1024; 
  1659. $v_memory_limit_int = $v_memory_limit_int*1048576; 
  1660. if($last == 'k') 
  1661. $v_memory_limit_int = $v_memory_limit_int*1024; 
  1662.  
  1663. $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit_int*PCLZIP_TEMPORARY_FILE_RATIO); 
  1664.  
  1665.  
  1666. // ----- Sanity check : No threshold if value lower than 1M 
  1667. if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) { 
  1668. unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]); 
  1669.  
  1670. // ----- Return 
  1671. return $v_result; 
  1672. // -------------------------------------------------------------------------------- 
  1673.  
  1674. // -------------------------------------------------------------------------------- 
  1675. // Function : privFileDescrParseAtt() 
  1676. // Description : 
  1677. // Parameters : 
  1678. // Return Values : 
  1679. // 1 on success. 
  1680. // 0 on failure. 
  1681. // -------------------------------------------------------------------------------- 
  1682. function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false) 
  1683. $v_result=1; 
  1684.  
  1685. // ----- For each file in the list check the attributes 
  1686. foreach ($p_file_list as $v_key => $v_value) { 
  1687.  
  1688. // ----- Check if the option is supported 
  1689. if (!isset($v_requested_options[$v_key])) { 
  1690. // ----- Error log 
  1691. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file"); 
  1692.  
  1693. // ----- Return 
  1694. return PclZip::errorCode(); 
  1695.  
  1696. // ----- Look for attribute 
  1697. switch ($v_key) { 
  1698. case PCLZIP_ATT_FILE_NAME : 
  1699. if (!is_string($v_value)) { 
  1700. PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); 
  1701. return PclZip::errorCode(); 
  1702.  
  1703. $p_filedescr['filename'] = PclZipUtilPathReduction($v_value); 
  1704.  
  1705. if ($p_filedescr['filename'] == '') { 
  1706. PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'"); 
  1707. return PclZip::errorCode(); 
  1708.  
  1709. break; 
  1710.  
  1711. case PCLZIP_ATT_FILE_NEW_SHORT_NAME : 
  1712. if (!is_string($v_value)) { 
  1713. PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); 
  1714. return PclZip::errorCode(); 
  1715.  
  1716. $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value); 
  1717.  
  1718. if ($p_filedescr['new_short_name'] == '') { 
  1719. PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'"); 
  1720. return PclZip::errorCode(); 
  1721. break; 
  1722.  
  1723. case PCLZIP_ATT_FILE_NEW_FULL_NAME : 
  1724. if (!is_string($v_value)) { 
  1725. PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); 
  1726. return PclZip::errorCode(); 
  1727.  
  1728. $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value); 
  1729.  
  1730. if ($p_filedescr['new_full_name'] == '') { 
  1731. PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'"); 
  1732. return PclZip::errorCode(); 
  1733. break; 
  1734.  
  1735. // ----- Look for options that takes a string 
  1736. case PCLZIP_ATT_FILE_COMMENT : 
  1737. if (!is_string($v_value)) { 
  1738. PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); 
  1739. return PclZip::errorCode(); 
  1740.  
  1741. $p_filedescr['comment'] = $v_value; 
  1742. break; 
  1743.  
  1744. case PCLZIP_ATT_FILE_MTIME : 
  1745. if (!is_integer($v_value)) { 
  1746. PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'"); 
  1747. return PclZip::errorCode(); 
  1748.  
  1749. $p_filedescr['mtime'] = $v_value; 
  1750. break; 
  1751.  
  1752. case PCLZIP_ATT_FILE_CONTENT : 
  1753. $p_filedescr['content'] = $v_value; 
  1754. break; 
  1755.  
  1756. default : 
  1757. // ----- Error log 
  1758. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,  
  1759. "Unknown parameter '".$v_key."'"); 
  1760.  
  1761. // ----- Return 
  1762. return PclZip::errorCode(); 
  1763.  
  1764. // ----- Look for mandatory options 
  1765. if ($v_requested_options !== false) { 
  1766. for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { 
  1767. // ----- Look for mandatory option 
  1768. if ($v_requested_options[$key] == 'mandatory') { 
  1769. // ----- Look if present 
  1770. if (!isset($p_file_list[$key])) { 
  1771. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); 
  1772. return PclZip::errorCode(); 
  1773.  
  1774. // end foreach 
  1775.  
  1776. // ----- Return 
  1777. return $v_result; 
  1778. // -------------------------------------------------------------------------------- 
  1779.  
  1780. // -------------------------------------------------------------------------------- 
  1781. // Function : privFileDescrExpand() 
  1782. // Description : 
  1783. // This method look for each item of the list to see if its a file, a folder 
  1784. // or a string to be added as file. For any other type of files (link, other) 
  1785. // just ignore the item. 
  1786. // Then prepare the information that will be stored for that file. 
  1787. // When its a folder, expand the folder with all the files that are in that 
  1788. // folder (recursively). 
  1789. // Parameters : 
  1790. // Return Values : 
  1791. // 1 on success. 
  1792. // 0 on failure. 
  1793. // -------------------------------------------------------------------------------- 
  1794. function privFileDescrExpand(&$p_filedescr_list, &$p_options) 
  1795. $v_result=1; 
  1796.  
  1797. // ----- Create a result list 
  1798. $v_result_list = array(); 
  1799.  
  1800. // ----- Look each entry 
  1801. for ($i=0; $i<sizeof($p_filedescr_list); $i++) { 
  1802.  
  1803. // ----- Get filedescr 
  1804. $v_descr = $p_filedescr_list[$i]; 
  1805.  
  1806. // ----- Reduce the filename 
  1807. $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false); 
  1808. $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']); 
  1809.  
  1810. // ----- Look for real file or folder 
  1811. if (file_exists($v_descr['filename'])) { 
  1812. if (@is_file($v_descr['filename'])) { 
  1813. $v_descr['type'] = 'file'; 
  1814. else if (@is_dir($v_descr['filename'])) { 
  1815. $v_descr['type'] = 'folder'; 
  1816. else if (@is_link($v_descr['filename'])) { 
  1817. // skip 
  1818. continue; 
  1819. else { 
  1820. // skip 
  1821. continue; 
  1822.  
  1823. // ----- Look for string added as file 
  1824. else if (isset($v_descr['content'])) { 
  1825. $v_descr['type'] = 'virtual_file'; 
  1826.  
  1827. // ----- Missing file 
  1828. else { 
  1829. // ----- Error log 
  1830. PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist"); 
  1831.  
  1832. // ----- Return 
  1833. return PclZip::errorCode(); 
  1834.  
  1835. // ----- Calculate the stored filename 
  1836. $this->privCalculateStoredFilename($v_descr, $p_options); 
  1837.  
  1838. // ----- Add the descriptor in result list 
  1839. $v_result_list[sizeof($v_result_list)] = $v_descr; 
  1840.  
  1841. // ----- Look for folder 
  1842. if ($v_descr['type'] == 'folder') { 
  1843. // ----- List of items in folder 
  1844. $v_dirlist_descr = array(); 
  1845. $v_dirlist_nb = 0; 
  1846. if ($v_folder_handler = @opendir($v_descr['filename'])) { 
  1847. while (($v_item_handler = @readdir($v_folder_handler)) !== false) { 
  1848.  
  1849. // ----- Skip '.' and '..' 
  1850. if (($v_item_handler == '.') || ($v_item_handler == '..')) { 
  1851. continue; 
  1852.  
  1853. // ----- Compose the full filename 
  1854. $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler; 
  1855.  
  1856. // ----- Look for different stored filename 
  1857. // Because the name of the folder was changed, the name of the 
  1858. // files/sub-folders also change 
  1859. if (($v_descr['stored_filename'] != $v_descr['filename']) 
  1860. && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) { 
  1861. if ($v_descr['stored_filename'] != '') { 
  1862. $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler; 
  1863. else { 
  1864. $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler; 
  1865.  
  1866. $v_dirlist_nb++; 
  1867.  
  1868. @closedir($v_folder_handler); 
  1869. else { 
  1870. // TBC : unable to open folder in read mode 
  1871.  
  1872. // ----- Expand each element of the list 
  1873. if ($v_dirlist_nb != 0) { 
  1874. // ----- Expand 
  1875. if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) { 
  1876. return $v_result; 
  1877.  
  1878. // ----- Concat the resulting list 
  1879. $v_result_list = array_merge($v_result_list, $v_dirlist_descr); 
  1880. else { 
  1881.  
  1882. // ----- Free local array 
  1883. unset($v_dirlist_descr); 
  1884.  
  1885. // ----- Get the result list 
  1886. $p_filedescr_list = $v_result_list; 
  1887.  
  1888. // ----- Return 
  1889. return $v_result; 
  1890. // -------------------------------------------------------------------------------- 
  1891.  
  1892. // -------------------------------------------------------------------------------- 
  1893. // Function : privCreate() 
  1894. // Description : 
  1895. // Parameters : 
  1896. // Return Values : 
  1897. // -------------------------------------------------------------------------------- 
  1898. function privCreate($p_filedescr_list, &$p_result_list, &$p_options) 
  1899. $v_result=1; 
  1900. $v_list_detail = array(); 
  1901.  
  1902. // ----- Magic quotes trick 
  1903. $this->privDisableMagicQuotes(); 
  1904.  
  1905. // ----- Open the file in write mode 
  1906. if (($v_result = $this->privOpenFd('wb')) != 1) 
  1907. // ----- Return 
  1908. return $v_result; 
  1909.  
  1910. // ----- Add the list of files 
  1911. $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options); 
  1912.  
  1913. // ----- Close 
  1914. $this->privCloseFd(); 
  1915.  
  1916. // ----- Magic quotes trick 
  1917. $this->privSwapBackMagicQuotes(); 
  1918.  
  1919. // ----- Return 
  1920. return $v_result; 
  1921. // -------------------------------------------------------------------------------- 
  1922.  
  1923. // -------------------------------------------------------------------------------- 
  1924. // Function : privAdd() 
  1925. // Description : 
  1926. // Parameters : 
  1927. // Return Values : 
  1928. // -------------------------------------------------------------------------------- 
  1929. function privAdd($p_filedescr_list, &$p_result_list, &$p_options) 
  1930. $v_result=1; 
  1931. $v_list_detail = array(); 
  1932.  
  1933. // ----- Look if the archive exists or is empty 
  1934. if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0)) 
  1935.  
  1936. // ----- Do a create 
  1937. $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options); 
  1938.  
  1939. // ----- Return 
  1940. return $v_result; 
  1941. // ----- Magic quotes trick 
  1942. $this->privDisableMagicQuotes(); 
  1943.  
  1944. // ----- Open the zip file 
  1945. if (($v_result=$this->privOpenFd('rb')) != 1) 
  1946. // ----- Magic quotes trick 
  1947. $this->privSwapBackMagicQuotes(); 
  1948.  
  1949. // ----- Return 
  1950. return $v_result; 
  1951.  
  1952. // ----- Read the central directory informations 
  1953. $v_central_dir = array(); 
  1954. if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) 
  1955. $this->privCloseFd(); 
  1956. $this->privSwapBackMagicQuotes(); 
  1957. return $v_result; 
  1958.  
  1959. // ----- Go to beginning of File 
  1960. @rewind($this->zip_fd); 
  1961.  
  1962. // ----- Creates a temporay file 
  1963. $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; 
  1964.  
  1965. // ----- Open the temporary file in write mode 
  1966. if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) 
  1967. $this->privCloseFd(); 
  1968. $this->privSwapBackMagicQuotes(); 
  1969.  
  1970. PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); 
  1971.  
  1972. // ----- Return 
  1973. return PclZip::errorCode(); 
  1974.  
  1975. // ----- Copy the files from the archive to the temporary file 
  1976. // TBC : Here I should better append the file and go back to erase the central dir 
  1977. $v_size = $v_central_dir['offset']; 
  1978. while ($v_size != 0) 
  1979. $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 
  1980. $v_buffer = fread($this->zip_fd, $v_read_size); 
  1981. @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); 
  1982. $v_size -= $v_read_size; 
  1983.  
  1984. // ----- Swap the file descriptor 
  1985. // Here is a trick : I swap the temporary fd with the zip fd, in order to use 
  1986. // the following methods on the temporary fil and not the real archive 
  1987. $v_swap = $this->zip_fd; 
  1988. $this->zip_fd = $v_zip_temp_fd; 
  1989. $v_zip_temp_fd = $v_swap; 
  1990.  
  1991. // ----- Add the files 
  1992. $v_header_list = array(); 
  1993. if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) 
  1994. fclose($v_zip_temp_fd); 
  1995. $this->privCloseFd(); 
  1996. @unlink($v_zip_temp_name); 
  1997. $this->privSwapBackMagicQuotes(); 
  1998.  
  1999. // ----- Return 
  2000. return $v_result; 
  2001.  
  2002. // ----- Store the offset of the central dir 
  2003. $v_offset = @ftell($this->zip_fd); 
  2004.  
  2005. // ----- Copy the block of file headers from the old archive 
  2006. $v_size = $v_central_dir['size']; 
  2007. while ($v_size != 0) 
  2008. $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 
  2009. $v_buffer = @fread($v_zip_temp_fd, $v_read_size); 
  2010. @fwrite($this->zip_fd, $v_buffer, $v_read_size); 
  2011. $v_size -= $v_read_size; 
  2012.  
  2013. // ----- Create the Central Dir files header 
  2014. for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++) 
  2015. // ----- Create the file header 
  2016. if ($v_header_list[$i]['status'] == 'ok') { 
  2017. if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { 
  2018. fclose($v_zip_temp_fd); 
  2019. $this->privCloseFd(); 
  2020. @unlink($v_zip_temp_name); 
  2021. $this->privSwapBackMagicQuotes(); 
  2022.  
  2023. // ----- Return 
  2024. return $v_result; 
  2025. $v_count++; 
  2026.  
  2027. // ----- Transform the header to a 'usable' info 
  2028. $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); 
  2029.  
  2030. // ----- Zip file comment 
  2031. $v_comment = $v_central_dir['comment']; 
  2032. if (isset($p_options[PCLZIP_OPT_COMMENT])) { 
  2033. $v_comment = $p_options[PCLZIP_OPT_COMMENT]; 
  2034. if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) { 
  2035. $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT]; 
  2036. if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) { 
  2037. $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment; 
  2038.  
  2039. // ----- Calculate the size of the central header 
  2040. $v_size = @ftell($this->zip_fd)-$v_offset; 
  2041.  
  2042. // ----- Create the central dir footer 
  2043. if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1) 
  2044. // ----- Reset the file list 
  2045. unset($v_header_list); 
  2046. $this->privSwapBackMagicQuotes(); 
  2047.  
  2048. // ----- Return 
  2049. return $v_result; 
  2050.  
  2051. // ----- Swap back the file descriptor 
  2052. $v_swap = $this->zip_fd; 
  2053. $this->zip_fd = $v_zip_temp_fd; 
  2054. $v_zip_temp_fd = $v_swap; 
  2055.  
  2056. // ----- Close 
  2057. $this->privCloseFd(); 
  2058.  
  2059. // ----- Close the temporary file 
  2060. @fclose($v_zip_temp_fd); 
  2061.  
  2062. // ----- Magic quotes trick 
  2063. $this->privSwapBackMagicQuotes(); 
  2064.  
  2065. // ----- Delete the zip file 
  2066. // TBC : I should test the result ... 
  2067. @unlink($this->zipname); 
  2068.  
  2069. // ----- Rename the temporary file 
  2070. // TBC : I should test the result ... 
  2071. //@rename($v_zip_temp_name, $this->zipname); 
  2072. PclZipUtilRename($v_zip_temp_name, $this->zipname); 
  2073.  
  2074. // ----- Return 
  2075. return $v_result; 
  2076. // -------------------------------------------------------------------------------- 
  2077.  
  2078. // -------------------------------------------------------------------------------- 
  2079. // Function : privOpenFd() 
  2080. // Description : 
  2081. // Parameters : 
  2082. // -------------------------------------------------------------------------------- 
  2083. function privOpenFd($p_mode) 
  2084. $v_result=1; 
  2085.  
  2086. // ----- Look if already open 
  2087. if ($this->zip_fd != 0) 
  2088. // ----- Error log 
  2089. PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open'); 
  2090.  
  2091. // ----- Return 
  2092. return PclZip::errorCode(); 
  2093.  
  2094. // ----- Open the zip file 
  2095. if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0) 
  2096. // ----- Error log 
  2097. PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode'); 
  2098.  
  2099. // ----- Return 
  2100. return PclZip::errorCode(); 
  2101.  
  2102. // ----- Return 
  2103. return $v_result; 
  2104. // -------------------------------------------------------------------------------- 
  2105.  
  2106. // -------------------------------------------------------------------------------- 
  2107. // Function : privCloseFd() 
  2108. // Description : 
  2109. // Parameters : 
  2110. // -------------------------------------------------------------------------------- 
  2111. function privCloseFd() 
  2112. $v_result=1; 
  2113.  
  2114. if ($this->zip_fd != 0) 
  2115. @fclose($this->zip_fd); 
  2116. $this->zip_fd = 0; 
  2117.  
  2118. // ----- Return 
  2119. return $v_result; 
  2120. // -------------------------------------------------------------------------------- 
  2121.  
  2122. // -------------------------------------------------------------------------------- 
  2123. // Function : privAddList() 
  2124. // Description : 
  2125. // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is 
  2126. // different from the real path of the file. This is usefull if you want to have PclTar 
  2127. // running in any directory, and memorize relative path from an other directory. 
  2128. // Parameters : 
  2129. // $p_list : An array containing the file or directory names to add in the tar 
  2130. // $p_result_list : list of added files with their properties (specially the status field) 
  2131. // $p_add_dir : Path to add in the filename path archived 
  2132. // $p_remove_dir : Path to remove in the filename path archived 
  2133. // Return Values : 
  2134. // -------------------------------------------------------------------------------- 
  2135. // function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options) 
  2136. function privAddList($p_filedescr_list, &$p_result_list, &$p_options) 
  2137. $v_result=1; 
  2138.  
  2139. // ----- Add the files 
  2140. $v_header_list = array(); 
  2141. if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) 
  2142. // ----- Return 
  2143. return $v_result; 
  2144.  
  2145. // ----- Store the offset of the central dir 
  2146. $v_offset = @ftell($this->zip_fd); 
  2147.  
  2148. // ----- Create the Central Dir files header 
  2149. for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++) 
  2150. // ----- Create the file header 
  2151. if ($v_header_list[$i]['status'] == 'ok') { 
  2152. if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { 
  2153. // ----- Return 
  2154. return $v_result; 
  2155. $v_count++; 
  2156.  
  2157. // ----- Transform the header to a 'usable' info 
  2158. $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); 
  2159.  
  2160. // ----- Zip file comment 
  2161. $v_comment = ''; 
  2162. if (isset($p_options[PCLZIP_OPT_COMMENT])) { 
  2163. $v_comment = $p_options[PCLZIP_OPT_COMMENT]; 
  2164.  
  2165. // ----- Calculate the size of the central header 
  2166. $v_size = @ftell($this->zip_fd)-$v_offset; 
  2167.  
  2168. // ----- Create the central dir footer 
  2169. if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1) 
  2170. // ----- Reset the file list 
  2171. unset($v_header_list); 
  2172.  
  2173. // ----- Return 
  2174. return $v_result; 
  2175.  
  2176. // ----- Return 
  2177. return $v_result; 
  2178. // -------------------------------------------------------------------------------- 
  2179.  
  2180. // -------------------------------------------------------------------------------- 
  2181. // Function : privAddFileList() 
  2182. // Description : 
  2183. // Parameters : 
  2184. // $p_filedescr_list : An array containing the file description 
  2185. // or directory names to add in the zip 
  2186. // $p_result_list : list of added files with their properties (specially the status field) 
  2187. // Return Values : 
  2188. // -------------------------------------------------------------------------------- 
  2189. function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options) 
  2190. $v_result=1; 
  2191. $v_header = array(); 
  2192.  
  2193. // ----- Recuperate the current number of elt in list 
  2194. $v_nb = sizeof($p_result_list); 
  2195.  
  2196. // ----- Loop on the files 
  2197. for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) { 
  2198. // ----- Format the filename 
  2199. $p_filedescr_list[$j]['filename'] 
  2200. = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false); 
  2201.  
  2202.  
  2203. // ----- Skip empty file names 
  2204. // TBC : Can this be possible ? not checked in DescrParseAtt ? 
  2205. if ($p_filedescr_list[$j]['filename'] == "") { 
  2206. continue; 
  2207.  
  2208. // ----- Check the filename 
  2209. if ( ($p_filedescr_list[$j]['type'] != 'virtual_file') 
  2210. && (!file_exists($p_filedescr_list[$j]['filename']))) { 
  2211. PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist"); 
  2212. return PclZip::errorCode(); 
  2213.  
  2214. // ----- Look if it is a file or a dir with no all path remove option 
  2215. // or a dir with all its path removed 
  2216. // if ( (is_file($p_filedescr_list[$j]['filename'])) 
  2217. // || ( is_dir($p_filedescr_list[$j]['filename']) 
  2218. if ( ($p_filedescr_list[$j]['type'] == 'file') 
  2219. || ($p_filedescr_list[$j]['type'] == 'virtual_file') 
  2220. || ( ($p_filedescr_list[$j]['type'] == 'folder') 
  2221. && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]) 
  2222. || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) 
  2223. ) { 
  2224.  
  2225. // ----- Add the file 
  2226. $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,  
  2227. $p_options); 
  2228. if ($v_result != 1) { 
  2229. return $v_result; 
  2230.  
  2231. // ----- Store the file infos 
  2232. $p_result_list[$v_nb++] = $v_header; 
  2233.  
  2234. // ----- Return 
  2235. return $v_result; 
  2236. // -------------------------------------------------------------------------------- 
  2237.  
  2238. // -------------------------------------------------------------------------------- 
  2239. // Function : privAddFile() 
  2240. // Description : 
  2241. // Parameters : 
  2242. // Return Values : 
  2243. // -------------------------------------------------------------------------------- 
  2244. function privAddFile($p_filedescr, &$p_header, &$p_options) 
  2245. $v_result=1; 
  2246.  
  2247. // ----- Working variable 
  2248. $p_filename = $p_filedescr['filename']; 
  2249.  
  2250. // TBC : Already done in the fileAtt check ... ? 
  2251. if ($p_filename == "") { 
  2252. // ----- Error log 
  2253. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)"); 
  2254.  
  2255. // ----- Return 
  2256. return PclZip::errorCode(); 
  2257.  
  2258. // ----- Look for a stored different filename 
  2259. /** TBC : Removed 
  2260. if (isset($p_filedescr['stored_filename'])) { 
  2261. $v_stored_filename = $p_filedescr['stored_filename']; 
  2262. } 
  2263. else { 
  2264. $v_stored_filename = $p_filedescr['stored_filename']; 
  2265. } 
  2266. */ 
  2267.  
  2268. // ----- Set the file properties 
  2269. clearstatcache(); 
  2270. $p_header['version'] = 20; 
  2271. $p_header['version_extracted'] = 10; 
  2272. $p_header['flag'] = 0; 
  2273. $p_header['compression'] = 0; 
  2274. $p_header['crc'] = 0; 
  2275. $p_header['compressed_size'] = 0; 
  2276. $p_header['filename_len'] = strlen($p_filename); 
  2277. $p_header['extra_len'] = 0; 
  2278. $p_header['disk'] = 0; 
  2279. $p_header['internal'] = 0; 
  2280. $p_header['offset'] = 0; 
  2281. $p_header['filename'] = $p_filename; 
  2282. // TBC : Removed $p_header['stored_filename'] = $v_stored_filename; 
  2283. $p_header['stored_filename'] = $p_filedescr['stored_filename']; 
  2284. $p_header['extra'] = ''; 
  2285. $p_header['status'] = 'ok'; 
  2286. $p_header['index'] = -1; 
  2287.  
  2288. // ----- Look for regular file 
  2289. if ($p_filedescr['type']=='file') { 
  2290. $p_header['external'] = 0x00000000; 
  2291. $p_header['size'] = filesize($p_filename); 
  2292.  
  2293. // ----- Look for regular folder 
  2294. else if ($p_filedescr['type']=='fold