PclZip

The WordPress Core PclZip class.

Defined (1)

The class is defined in the following location(s).

/wp-admin/includes/class-pclzip.php  
  1. class PclZip 
  2. // ----- Filename of the zip file 
  3. var $zipname = ''; 
  4.  
  5. // ----- File descriptor of the zip file 
  6. var $zip_fd = 0; 
  7.  
  8. // ----- Internal error handling 
  9. var $error_code = 1; 
  10. var $error_string = ''; 
  11.  
  12. // ----- Current status of the magic_quotes_runtime 
  13. // This value store the php configuration for magic_quotes 
  14. // The class can then disable the magic_quotes and reset it after 
  15. var $magic_quotes_status; 
  16.  
  17. // -------------------------------------------------------------------------------- 
  18. // Function : PclZip() 
  19. // Description : 
  20. // Creates a PclZip object and set the name of the associated Zip archive 
  21. // filename. 
  22. // Note that no real action is taken, if the archive does not exist it is not 
  23. // created. Use create() for that. 
  24. // -------------------------------------------------------------------------------- 
  25. function __construct($p_zipname) 
  26.  
  27. // ----- Tests the zlib 
  28. if (!function_exists('gzopen')) 
  29. die('Abort '.basename(__FILE__).' : Missing zlib extensions'); 
  30.  
  31. // ----- Set the attributes 
  32. $this->zipname = $p_zipname; 
  33. $this->zip_fd = 0; 
  34. $this->magic_quotes_status = -1; 
  35.  
  36. // ----- Return 
  37. return; 
  38.  
  39. public function PclZip($p_zipname) { 
  40. self::__construct($p_zipname); 
  41. // -------------------------------------------------------------------------------- 
  42.  
  43. // -------------------------------------------------------------------------------- 
  44. // Function : 
  45. // create($p_filelist, $p_add_dir="", $p_remove_dir="") 
  46. // create($p_filelist, $p_option, $p_option_value, ...) 
  47. // Description : 
  48. // This method supports two different synopsis. The first one is historical. 
  49. // This method creates a Zip Archive. The Zip file is created in the 
  50. // filesystem. The files and directories indicated in $p_filelist 
  51. // are added in the archive. See the parameters description for the 
  52. // supported format of $p_filelist. 
  53. // When a directory is in the list, the directory and its content is added 
  54. // in the archive. 
  55. // In this synopsis, the function takes an optional variable list of 
  56. // options. See bellow the supported options. 
  57. // Parameters : 
  58. // $p_filelist : An array containing file or directory names, or 
  59. // a string containing one filename or one directory name, or 
  60. // a string containing a list of filenames and/or directory 
  61. // names separated by spaces. 
  62. // $p_add_dir : A path to add before the real path of the archived file,  
  63. // in order to have it memorized in the archive. 
  64. // $p_remove_dir : A path to remove from the real path of the file to archive,  
  65. // in order to have a shorter path memorized in the archive. 
  66. // When $p_add_dir and $p_remove_dir are set, $p_remove_dir 
  67. // is removed first, before $p_add_dir is added. 
  68. // Options : 
  69. // PCLZIP_OPT_ADD_PATH : 
  70. // PCLZIP_OPT_REMOVE_PATH : 
  71. // PCLZIP_OPT_REMOVE_ALL_PATH : 
  72. // PCLZIP_OPT_COMMENT : 
  73. // PCLZIP_CB_PRE_ADD : 
  74. // PCLZIP_CB_POST_ADD : 
  75. // Return Values : 
  76. // 0 on failure,  
  77. // The list of the added files, with a status of the add action. 
  78. // (see PclZip::listContent() for list entry format) 
  79. // -------------------------------------------------------------------------------- 
  80. function create($p_filelist) 
  81. $v_result=1; 
  82.  
  83. // ----- Reset the error handler 
  84. $this->privErrorReset(); 
  85.  
  86. // ----- Set default values 
  87. $v_options = array(); 
  88. $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; 
  89.  
  90. // ----- Look for variable options arguments 
  91. $v_size = func_num_args(); 
  92.  
  93. // ----- Look for arguments 
  94. if ($v_size > 1) { 
  95. // ----- Get the arguments 
  96. $v_arg_list = func_get_args(); 
  97.  
  98. // ----- Remove from the options list the first argument 
  99. array_shift($v_arg_list); 
  100. $v_size--; 
  101.  
  102. // ----- Look for first arg 
  103. if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { 
  104.  
  105. // ----- Parse the options 
  106. $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,  
  107. array (PCLZIP_OPT_REMOVE_PATH => 'optional',  
  108. PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',  
  109. PCLZIP_OPT_ADD_PATH => 'optional',  
  110. PCLZIP_CB_PRE_ADD => 'optional',  
  111. PCLZIP_CB_POST_ADD => 'optional',  
  112. PCLZIP_OPT_NO_COMPRESSION => 'optional',  
  113. PCLZIP_OPT_COMMENT => 'optional',  
  114. PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',  
  115. PCLZIP_OPT_TEMP_FILE_ON => 'optional',  
  116. PCLZIP_OPT_TEMP_FILE_OFF => 'optional' 
  117. //, PCLZIP_OPT_CRYPT => 'optional' 
  118. )); 
  119. if ($v_result != 1) { 
  120. return 0; 
  121.  
  122. // ----- Look for 2 args 
  123. // Here we need to support the first historic synopsis of the 
  124. // method. 
  125. else { 
  126.  
  127. // ----- Get the first argument 
  128. $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0]; 
  129.  
  130. // ----- Look for the optional second argument 
  131. if ($v_size == 2) { 
  132. $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; 
  133. else if ($v_size > 2) { 
  134. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,  
  135. "Invalid number / type of arguments"); 
  136. return 0; 
  137.  
  138. // ----- Look for default option values 
  139. $this->privOptionDefaultThreshold($v_options); 
  140.  
  141. // ----- Init 
  142. $v_string_list = array(); 
  143. $v_att_list = array(); 
  144. $v_filedescr_list = array(); 
  145. $p_result_list = array(); 
  146.  
  147. // ----- Look if the $p_filelist is really an array 
  148. if (is_array($p_filelist)) { 
  149.  
  150. // ----- Look if the first element is also an array 
  151. // This will mean that this is a file description entry 
  152. if (isset($p_filelist[0]) && is_array($p_filelist[0])) { 
  153. $v_att_list = $p_filelist; 
  154.  
  155. // ----- The list is a list of string names 
  156. else { 
  157. $v_string_list = $p_filelist; 
  158.  
  159. // ----- Look if the $p_filelist is a string 
  160. else if (is_string($p_filelist)) { 
  161. // ----- Create a list from the string 
  162. $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); 
  163.  
  164. // ----- Invalid variable type for $p_filelist 
  165. else { 
  166. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist"); 
  167. return 0; 
  168.  
  169. // ----- Reformat the string list 
  170. if (sizeof($v_string_list) != 0) { 
  171. foreach ($v_string_list as $v_string) { 
  172. if ($v_string != '') { 
  173. $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; 
  174. else { 
  175.  
  176. // ----- For each file in the list check the attributes 
  177. $v_supported_attributes 
  178. = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' 
  179. , PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' 
  180. , PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' 
  181. , PCLZIP_ATT_FILE_MTIME => 'optional' 
  182. , PCLZIP_ATT_FILE_CONTENT => 'optional' 
  183. , PCLZIP_ATT_FILE_COMMENT => 'optional' 
  184. ); 
  185. foreach ($v_att_list as $v_entry) { 
  186. $v_result = $this->privFileDescrParseAtt($v_entry,  
  187. $v_filedescr_list[],  
  188. $v_options,  
  189. $v_supported_attributes); 
  190. if ($v_result != 1) { 
  191. return 0; 
  192.  
  193. // ----- Expand the filelist (expand directories) 
  194. $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); 
  195. if ($v_result != 1) { 
  196. return 0; 
  197.  
  198. // ----- Call the create fct 
  199. $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options); 
  200. if ($v_result != 1) { 
  201. return 0; 
  202.  
  203. // ----- Return 
  204. return $p_result_list; 
  205. // -------------------------------------------------------------------------------- 
  206.  
  207. // -------------------------------------------------------------------------------- 
  208. // Function : 
  209. // add($p_filelist, $p_add_dir="", $p_remove_dir="") 
  210. // add($p_filelist, $p_option, $p_option_value, ...) 
  211. // Description : 
  212. // This method supports two synopsis. The first one is historical. 
  213. // This methods add the list of files in an existing archive. 
  214. // If a file with the same name already exists, it is added at the end of the 
  215. // archive, the first one is still present. 
  216. // If the archive does not exist, it is created. 
  217. // Parameters : 
  218. // $p_filelist : An array containing file or directory names, or 
  219. // a string containing one filename or one directory name, or 
  220. // a string containing a list of filenames and/or directory 
  221. // names separated by spaces. 
  222. // $p_add_dir : A path to add before the real path of the archived file,  
  223. // in order to have it memorized in the archive. 
  224. // $p_remove_dir : A path to remove from the real path of the file to archive,  
  225. // in order to have a shorter path memorized in the archive. 
  226. // When $p_add_dir and $p_remove_dir are set, $p_remove_dir 
  227. // is removed first, before $p_add_dir is added. 
  228. // Options : 
  229. // PCLZIP_OPT_ADD_PATH : 
  230. // PCLZIP_OPT_REMOVE_PATH : 
  231. // PCLZIP_OPT_REMOVE_ALL_PATH : 
  232. // PCLZIP_OPT_COMMENT : 
  233. // PCLZIP_OPT_ADD_COMMENT : 
  234. // PCLZIP_OPT_PREPEND_COMMENT : 
  235. // PCLZIP_CB_PRE_ADD : 
  236. // PCLZIP_CB_POST_ADD : 
  237. // Return Values : 
  238. // 0 on failure,  
  239. // The list of the added files, with a status of the add action. 
  240. // (see PclZip::listContent() for list entry format) 
  241. // -------------------------------------------------------------------------------- 
  242. function add($p_filelist) 
  243. $v_result=1; 
  244.  
  245. // ----- Reset the error handler 
  246. $this->privErrorReset(); 
  247.  
  248. // ----- Set default values 
  249. $v_options = array(); 
  250. $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; 
  251.  
  252. // ----- Look for variable options arguments 
  253. $v_size = func_num_args(); 
  254.  
  255. // ----- Look for arguments 
  256. if ($v_size > 1) { 
  257. // ----- Get the arguments 
  258. $v_arg_list = func_get_args(); 
  259.  
  260. // ----- Remove form the options list the first argument 
  261. array_shift($v_arg_list); 
  262. $v_size--; 
  263.  
  264. // ----- Look for first arg 
  265. if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { 
  266.  
  267. // ----- Parse the options 
  268. $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,  
  269. array (PCLZIP_OPT_REMOVE_PATH => 'optional',  
  270. PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',  
  271. PCLZIP_OPT_ADD_PATH => 'optional',  
  272. PCLZIP_CB_PRE_ADD => 'optional',  
  273. PCLZIP_CB_POST_ADD => 'optional',  
  274. PCLZIP_OPT_NO_COMPRESSION => 'optional',  
  275. PCLZIP_OPT_COMMENT => 'optional',  
  276. PCLZIP_OPT_ADD_COMMENT => 'optional',  
  277. PCLZIP_OPT_PREPEND_COMMENT => 'optional',  
  278. PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',  
  279. PCLZIP_OPT_TEMP_FILE_ON => 'optional',  
  280. PCLZIP_OPT_TEMP_FILE_OFF => 'optional' 
  281. //, PCLZIP_OPT_CRYPT => 'optional' 
  282. )); 
  283. if ($v_result != 1) { 
  284. return 0; 
  285.  
  286. // ----- Look for 2 args 
  287. // Here we need to support the first historic synopsis of the 
  288. // method. 
  289. else { 
  290.  
  291. // ----- Get the first argument 
  292. $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0]; 
  293.  
  294. // ----- Look for the optional second argument 
  295. if ($v_size == 2) { 
  296. $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; 
  297. else if ($v_size > 2) { 
  298. // ----- Error log 
  299. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); 
  300.  
  301. // ----- Return 
  302. return 0; 
  303.  
  304. // ----- Look for default option values 
  305. $this->privOptionDefaultThreshold($v_options); 
  306.  
  307. // ----- Init 
  308. $v_string_list = array(); 
  309. $v_att_list = array(); 
  310. $v_filedescr_list = array(); 
  311. $p_result_list = array(); 
  312.  
  313. // ----- Look if the $p_filelist is really an array 
  314. if (is_array($p_filelist)) { 
  315.  
  316. // ----- Look if the first element is also an array 
  317. // This will mean that this is a file description entry 
  318. if (isset($p_filelist[0]) && is_array($p_filelist[0])) { 
  319. $v_att_list = $p_filelist; 
  320.  
  321. // ----- The list is a list of string names 
  322. else { 
  323. $v_string_list = $p_filelist; 
  324.  
  325. // ----- Look if the $p_filelist is a string 
  326. else if (is_string($p_filelist)) { 
  327. // ----- Create a list from the string 
  328. $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); 
  329.  
  330. // ----- Invalid variable type for $p_filelist 
  331. else { 
  332. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist"); 
  333. return 0; 
  334.  
  335. // ----- Reformat the string list 
  336. if (sizeof($v_string_list) != 0) { 
  337. foreach ($v_string_list as $v_string) { 
  338. $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; 
  339.  
  340. // ----- For each file in the list check the attributes 
  341. $v_supported_attributes 
  342. = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' 
  343. , PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' 
  344. , PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' 
  345. , PCLZIP_ATT_FILE_MTIME => 'optional' 
  346. , PCLZIP_ATT_FILE_CONTENT => 'optional' 
  347. , PCLZIP_ATT_FILE_COMMENT => 'optional' 
  348. ); 
  349. foreach ($v_att_list as $v_entry) { 
  350. $v_result = $this->privFileDescrParseAtt($v_entry,  
  351. $v_filedescr_list[],  
  352. $v_options,  
  353. $v_supported_attributes); 
  354. if ($v_result != 1) { 
  355. return 0; 
  356.  
  357. // ----- Expand the filelist (expand directories) 
  358. $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); 
  359. if ($v_result != 1) { 
  360. return 0; 
  361.  
  362. // ----- Call the create fct 
  363. $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options); 
  364. if ($v_result != 1) { 
  365. return 0; 
  366.  
  367. // ----- Return 
  368. return $p_result_list; 
  369. // -------------------------------------------------------------------------------- 
  370.  
  371. // -------------------------------------------------------------------------------- 
  372. // Function : listContent() 
  373. // Description : 
  374. // This public method, gives the list of the files and directories, with their 
  375. // properties. 
  376. // The properties of each entries in the list are (used also in other functions) : 
  377. // filename : Name of the file. For a create or add action it is the filename 
  378. // given by the user. For an extract function it is the filename 
  379. // of the extracted file. 
  380. // stored_filename : Name of the file / directory stored in the archive. 
  381. // size : Size of the stored file. 
  382. // compressed_size : Size of the file's data compressed in the archive 
  383. // (without the headers overhead) 
  384. // mtime : Last known modification date of the file (UNIX timestamp) 
  385. // comment : Comment associated with the file 
  386. // folder : true | false 
  387. // index : index of the file in the archive 
  388. // status : status of the action (depending of the action) : 
  389. // Values are : 
  390. // ok : OK ! 
  391. // filtered : the file / dir is not extracted (filtered by user) 
  392. // already_a_directory : the file can not be extracted because a 
  393. // directory with the same name already exists 
  394. // write_protected : the file can not be extracted because a file 
  395. // with the same name already exists and is 
  396. // write protected 
  397. // newer_exist : the file was not extracted because a newer file exists 
  398. // path_creation_fail : the file is not extracted because the folder 
  399. // does not exist and can not be created 
  400. // write_error : the file was not extracted because there was a 
  401. // error while writing the file 
  402. // read_error : the file was not extracted because there was a error 
  403. // while reading the file 
  404. // invalid_header : the file was not extracted because of an archive 
  405. // format error (bad file header) 
  406. // Note that each time a method can continue operating when there 
  407. // is an action error on a file, the error is only logged in the file status. 
  408. // Return Values : 
  409. // 0 on an unrecoverable failure,  
  410. // The list of the files in the archive. 
  411. // -------------------------------------------------------------------------------- 
  412. function listContent() 
  413. $v_result=1; 
  414.  
  415. // ----- Reset the error handler 
  416. $this->privErrorReset(); 
  417.  
  418. // ----- Check archive 
  419. if (!$this->privCheckFormat()) { 
  420. return(0); 
  421.  
  422. // ----- Call the extracting fct 
  423. $p_list = array(); 
  424. if (($v_result = $this->privList($p_list)) != 1) 
  425. unset($p_list); 
  426. return(0); 
  427.  
  428. // ----- Return 
  429. return $p_list; 
  430. // -------------------------------------------------------------------------------- 
  431.  
  432. // -------------------------------------------------------------------------------- 
  433. // Function : 
  434. // extract($p_path="./", $p_remove_path="") 
  435. // extract([$p_option, $p_option_value, ...]) 
  436. // Description : 
  437. // This method supports two synopsis. The first one is historical. 
  438. // This method extract all the files / directories from the archive to the 
  439. // folder indicated in $p_path. 
  440. // If you want to ignore the 'root' part of path of the memorized files 
  441. // you can indicate this in the optional $p_remove_path parameter. 
  442. // By default, if a newer file with the same name already exists, the 
  443. // file is not extracted. 
  444. // 
  445. // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions 
  446. // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append 
  447. // at the end of the path value of PCLZIP_OPT_PATH. 
  448. // Parameters : 
  449. // $p_path : Path where the files and directories are to be extracted 
  450. // $p_remove_path : First part ('root' part) of the memorized path 
  451. // (if any similar) to remove while extracting. 
  452. // Options : 
  453. // PCLZIP_OPT_PATH : 
  454. // PCLZIP_OPT_ADD_PATH : 
  455. // PCLZIP_OPT_REMOVE_PATH : 
  456. // PCLZIP_OPT_REMOVE_ALL_PATH : 
  457. // PCLZIP_CB_PRE_EXTRACT : 
  458. // PCLZIP_CB_POST_EXTRACT : 
  459. // Return Values : 
  460. // 0 or a negative value on failure,  
  461. // The list of the extracted files, with a status of the action. 
  462. // (see PclZip::listContent() for list entry format) 
  463. // -------------------------------------------------------------------------------- 
  464. function extract() 
  465. $v_result=1; 
  466.  
  467. // ----- Reset the error handler 
  468. $this->privErrorReset(); 
  469.  
  470. // ----- Check archive 
  471. if (!$this->privCheckFormat()) { 
  472. return(0); 
  473.  
  474. // ----- Set default values 
  475. $v_options = array(); 
  476. // $v_path = "./"; 
  477. $v_path = ''; 
  478. $v_remove_path = ""; 
  479. $v_remove_all_path = false; 
  480.  
  481. // ----- Look for variable options arguments 
  482. $v_size = func_num_args(); 
  483.  
  484. // ----- Default values for option 
  485. $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; 
  486.  
  487. // ----- Look for arguments 
  488. if ($v_size > 0) { 
  489. // ----- Get the arguments 
  490. $v_arg_list = func_get_args(); 
  491.  
  492. // ----- Look for first arg 
  493. if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { 
  494.  
  495. // ----- Parse the options 
  496. $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,  
  497. array (PCLZIP_OPT_PATH => 'optional',  
  498. PCLZIP_OPT_REMOVE_PATH => 'optional',  
  499. PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',  
  500. PCLZIP_OPT_ADD_PATH => 'optional',  
  501. PCLZIP_CB_PRE_EXTRACT => 'optional',  
  502. PCLZIP_CB_POST_EXTRACT => 'optional',  
  503. PCLZIP_OPT_SET_CHMOD => 'optional',  
  504. PCLZIP_OPT_BY_NAME => 'optional',  
  505. PCLZIP_OPT_BY_EREG => 'optional',  
  506. PCLZIP_OPT_BY_PREG => 'optional',  
  507. PCLZIP_OPT_BY_INDEX => 'optional',  
  508. PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',  
  509. PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',  
  510. PCLZIP_OPT_REPLACE_NEWER => 'optional' 
  511. , PCLZIP_OPT_STOP_ON_ERROR => 'optional' 
  512. , PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',  
  513. PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',  
  514. PCLZIP_OPT_TEMP_FILE_ON => 'optional',  
  515. PCLZIP_OPT_TEMP_FILE_OFF => 'optional' 
  516. )); 
  517. if ($v_result != 1) { 
  518. return 0; 
  519.  
  520. // ----- Set the arguments 
  521. if (isset($v_options[PCLZIP_OPT_PATH])) { 
  522. $v_path = $v_options[PCLZIP_OPT_PATH]; 
  523. if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { 
  524. $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; 
  525. if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { 
  526. $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; 
  527. if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { 
  528. // ----- Check for '/' in last path char 
  529. if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { 
  530. $v_path .= '/'; 
  531. $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; 
  532.  
  533. // ----- Look for 2 args 
  534. // Here we need to support the first historic synopsis of the 
  535. // method. 
  536. else { 
  537.  
  538. // ----- Get the first argument 
  539. $v_path = $v_arg_list[0]; 
  540.  
  541. // ----- Look for the optional second argument 
  542. if ($v_size == 2) { 
  543. $v_remove_path = $v_arg_list[1]; 
  544. else if ($v_size > 2) { 
  545. // ----- Error log 
  546. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); 
  547.  
  548. // ----- Return 
  549. return 0; 
  550.  
  551. // ----- Look for default option values 
  552. $this->privOptionDefaultThreshold($v_options); 
  553.  
  554. // ----- Trace 
  555.  
  556. // ----- Call the extracting fct 
  557. $p_list = array(); 
  558. $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,  
  559. $v_remove_all_path, $v_options); 
  560. if ($v_result < 1) { 
  561. unset($p_list); 
  562. return(0); 
  563.  
  564. // ----- Return 
  565. return $p_list; 
  566. // -------------------------------------------------------------------------------- 
  567.  
  568.  
  569. // -------------------------------------------------------------------------------- 
  570. // Function : 
  571. // extractByIndex($p_index, $p_path="./", $p_remove_path="") 
  572. // extractByIndex($p_index, [$p_option, $p_option_value, ...]) 
  573. // Description : 
  574. // This method supports two synopsis. The first one is historical. 
  575. // This method is doing a partial extract of the archive. 
  576. // The extracted files or folders are identified by their index in the 
  577. // archive (from 0 to n). 
  578. // Note that if the index identify a folder, only the folder entry is 
  579. // extracted, not all the files included in the archive. 
  580. // Parameters : 
  581. // $p_index : A single index (integer) or a string of indexes of files to 
  582. // extract. The form of the string is "0, 4-6, 8-12" with only numbers 
  583. // and '-' for range or ', ' to separate ranges. No spaces or ';' 
  584. // are allowed. 
  585. // $p_path : Path where the files and directories are to be extracted 
  586. // $p_remove_path : First part ('root' part) of the memorized path 
  587. // (if any similar) to remove while extracting. 
  588. // Options : 
  589. // PCLZIP_OPT_PATH : 
  590. // PCLZIP_OPT_ADD_PATH : 
  591. // PCLZIP_OPT_REMOVE_PATH : 
  592. // PCLZIP_OPT_REMOVE_ALL_PATH : 
  593. // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and 
  594. // not as files. 
  595. // The resulting content is in a new field 'content' in the file 
  596. // structure. 
  597. // This option must be used alone (any other options are ignored). 
  598. // PCLZIP_CB_PRE_EXTRACT : 
  599. // PCLZIP_CB_POST_EXTRACT : 
  600. // Return Values : 
  601. // 0 on failure,  
  602. // The list of the extracted files, with a status of the action. 
  603. // (see PclZip::listContent() for list entry format) 
  604. // -------------------------------------------------------------------------------- 
  605. //function extractByIndex($p_index, options...) 
  606. function extractByIndex($p_index) 
  607. $v_result=1; 
  608.  
  609. // ----- Reset the error handler 
  610. $this->privErrorReset(); 
  611.  
  612. // ----- Check archive 
  613. if (!$this->privCheckFormat()) { 
  614. return(0); 
  615.  
  616. // ----- Set default values 
  617. $v_options = array(); 
  618. // $v_path = "./"; 
  619. $v_path = ''; 
  620. $v_remove_path = ""; 
  621. $v_remove_all_path = false; 
  622.  
  623. // ----- Look for variable options arguments 
  624. $v_size = func_num_args(); 
  625.  
  626. // ----- Default values for option 
  627. $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; 
  628.  
  629. // ----- Look for arguments 
  630. if ($v_size > 1) { 
  631. // ----- Get the arguments 
  632. $v_arg_list = func_get_args(); 
  633.  
  634. // ----- Remove form the options list the first argument 
  635. array_shift($v_arg_list); 
  636. $v_size--; 
  637.  
  638. // ----- Look for first arg 
  639. if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { 
  640.  
  641. // ----- Parse the options 
  642. $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,  
  643. array (PCLZIP_OPT_PATH => 'optional',  
  644. PCLZIP_OPT_REMOVE_PATH => 'optional',  
  645. PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',  
  646. PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',  
  647. PCLZIP_OPT_ADD_PATH => 'optional',  
  648. PCLZIP_CB_PRE_EXTRACT => 'optional',  
  649. PCLZIP_CB_POST_EXTRACT => 'optional',  
  650. PCLZIP_OPT_SET_CHMOD => 'optional',  
  651. PCLZIP_OPT_REPLACE_NEWER => 'optional' 
  652. , PCLZIP_OPT_STOP_ON_ERROR => 'optional' 
  653. , PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',  
  654. PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',  
  655. PCLZIP_OPT_TEMP_FILE_ON => 'optional',  
  656. PCLZIP_OPT_TEMP_FILE_OFF => 'optional' 
  657. )); 
  658. if ($v_result != 1) { 
  659. return 0; 
  660.  
  661. // ----- Set the arguments 
  662. if (isset($v_options[PCLZIP_OPT_PATH])) { 
  663. $v_path = $v_options[PCLZIP_OPT_PATH]; 
  664. if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { 
  665. $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; 
  666. if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { 
  667. $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; 
  668. if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { 
  669. // ----- Check for '/' in last path char 
  670. if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { 
  671. $v_path .= '/'; 
  672. $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; 
  673. if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) { 
  674. $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; 
  675. else { 
  676.  
  677. // ----- Look for 2 args 
  678. // Here we need to support the first historic synopsis of the 
  679. // method. 
  680. else { 
  681.  
  682. // ----- Get the first argument 
  683. $v_path = $v_arg_list[0]; 
  684.  
  685. // ----- Look for the optional second argument 
  686. if ($v_size == 2) { 
  687. $v_remove_path = $v_arg_list[1]; 
  688. else if ($v_size > 2) { 
  689. // ----- Error log 
  690. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); 
  691.  
  692. // ----- Return 
  693. return 0; 
  694.  
  695. // ----- Trace 
  696.  
  697. // ----- Trick 
  698. // Here I want to reuse extractByRule(), so I need to parse the $p_index 
  699. // with privParseOptions() 
  700. $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index); 
  701. $v_options_trick = array(); 
  702. $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,  
  703. array (PCLZIP_OPT_BY_INDEX => 'optional' )); 
  704. if ($v_result != 1) { 
  705. return 0; 
  706. $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX]; 
  707.  
  708. // ----- Look for default option values 
  709. $this->privOptionDefaultThreshold($v_options); 
  710.  
  711. // ----- Call the extracting fct 
  712. if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) { 
  713. return(0); 
  714.  
  715. // ----- Return 
  716. return $p_list; 
  717. // -------------------------------------------------------------------------------- 
  718.  
  719. // -------------------------------------------------------------------------------- 
  720. // Function : 
  721. // delete([$p_option, $p_option_value, ...]) 
  722. // Description : 
  723. // This method removes files from the archive. 
  724. // If no parameters are given, then all the archive is emptied. 
  725. // Parameters : 
  726. // None or optional arguments. 
  727. // Options : 
  728. // PCLZIP_OPT_BY_INDEX : 
  729. // PCLZIP_OPT_BY_NAME : 
  730. // PCLZIP_OPT_BY_EREG : 
  731. // PCLZIP_OPT_BY_PREG : 
  732. // Return Values : 
  733. // 0 on failure,  
  734. // The list of the files which are still present in the archive. 
  735. // (see PclZip::listContent() for list entry format) 
  736. // -------------------------------------------------------------------------------- 
  737. function delete() 
  738. $v_result=1; 
  739.  
  740. // ----- Reset the error handler 
  741. $this->privErrorReset(); 
  742.  
  743. // ----- Check archive 
  744. if (!$this->privCheckFormat()) { 
  745. return(0); 
  746.  
  747. // ----- Set default values 
  748. $v_options = array(); 
  749.  
  750. // ----- Look for variable options arguments 
  751. $v_size = func_num_args(); 
  752.  
  753. // ----- Look for arguments 
  754. if ($v_size > 0) { 
  755. // ----- Get the arguments 
  756. $v_arg_list = func_get_args(); 
  757.  
  758. // ----- Parse the options 
  759. $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,  
  760. array (PCLZIP_OPT_BY_NAME => 'optional',  
  761. PCLZIP_OPT_BY_EREG => 'optional',  
  762. PCLZIP_OPT_BY_PREG => 'optional',  
  763. PCLZIP_OPT_BY_INDEX => 'optional' )); 
  764. if ($v_result != 1) { 
  765. return 0; 
  766.  
  767. // ----- Magic quotes trick 
  768. $this->privDisableMagicQuotes(); 
  769.  
  770. // ----- Call the delete fct 
  771. $v_list = array(); 
  772. if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) { 
  773. $this->privSwapBackMagicQuotes(); 
  774. unset($v_list); 
  775. return(0); 
  776.  
  777. // ----- Magic quotes trick 
  778. $this->privSwapBackMagicQuotes(); 
  779.  
  780. // ----- Return 
  781. return $v_list; 
  782. // -------------------------------------------------------------------------------- 
  783.  
  784. // -------------------------------------------------------------------------------- 
  785. // Function : deleteByIndex() 
  786. // Description : 
  787. // ***** Deprecated ***** 
  788. // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered. 
  789. // -------------------------------------------------------------------------------- 
  790. function deleteByIndex($p_index) 
  791.  
  792. $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index); 
  793.  
  794. // ----- Return 
  795. return $p_list; 
  796. // -------------------------------------------------------------------------------- 
  797.  
  798. // -------------------------------------------------------------------------------- 
  799. // Function : properties() 
  800. // Description : 
  801. // This method gives the properties of the archive. 
  802. // The properties are : 
  803. // nb : Number of files in the archive 
  804. // comment : Comment associated with the archive file 
  805. // status : not_exist, ok 
  806. // Parameters : 
  807. // None 
  808. // Return Values : 
  809. // 0 on failure,  
  810. // An array with the archive properties. 
  811. // -------------------------------------------------------------------------------- 
  812. function properties() 
  813.  
  814. // ----- Reset the error handler 
  815. $this->privErrorReset(); 
  816.  
  817. // ----- Magic quotes trick 
  818. $this->privDisableMagicQuotes(); 
  819.  
  820. // ----- Check archive 
  821. if (!$this->privCheckFormat()) { 
  822. $this->privSwapBackMagicQuotes(); 
  823. return(0); 
  824.  
  825. // ----- Default properties 
  826. $v_prop = array(); 
  827. $v_prop['comment'] = ''; 
  828. $v_prop['nb'] = 0; 
  829. $v_prop['status'] = 'not_exist'; 
  830.  
  831. // ----- Look if file exists 
  832. if (@is_file($this->zipname)) 
  833. // ----- Open the zip file 
  834. if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) 
  835. $this->privSwapBackMagicQuotes(); 
  836.  
  837. // ----- Error log 
  838. PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); 
  839.  
  840. // ----- Return 
  841. return 0; 
  842.  
  843. // ----- Read the central directory informations 
  844. $v_central_dir = array(); 
  845. if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) 
  846. $this->privSwapBackMagicQuotes(); 
  847. return 0; 
  848.  
  849. // ----- Close the zip file 
  850. $this->privCloseFd(); 
  851.  
  852. // ----- Set the user attributes 
  853. $v_prop['comment'] = $v_central_dir['comment']; 
  854. $v_prop['nb'] = $v_central_dir['entries']; 
  855. $v_prop['status'] = 'ok'; 
  856.  
  857. // ----- Magic quotes trick 
  858. $this->privSwapBackMagicQuotes(); 
  859.  
  860. // ----- Return 
  861. return $v_prop; 
  862. // -------------------------------------------------------------------------------- 
  863.  
  864. // -------------------------------------------------------------------------------- 
  865. // Function : duplicate() 
  866. // Description : 
  867. // This method creates an archive by copying the content of an other one. If 
  868. // the archive already exist, it is replaced by the new one without any warning. 
  869. // Parameters : 
  870. // $p_archive : The filename of a valid archive, or 
  871. // a valid PclZip object. 
  872. // Return Values : 
  873. // 1 on success. 
  874. // 0 or a negative value on error (error code). 
  875. // -------------------------------------------------------------------------------- 
  876. function duplicate($p_archive) 
  877. $v_result = 1; 
  878.  
  879. // ----- Reset the error handler 
  880. $this->privErrorReset(); 
  881.  
  882. // ----- Look if the $p_archive is a PclZip object 
  883. if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) 
  884.  
  885. // ----- Duplicate the archive 
  886. $v_result = $this->privDuplicate($p_archive->zipname); 
  887.  
  888. // ----- Look if the $p_archive is a string (so a filename) 
  889. else if (is_string($p_archive)) 
  890.  
  891. // ----- Check that $p_archive is a valid zip file 
  892. // TBC : Should also check the archive format 
  893. if (!is_file($p_archive)) { 
  894. // ----- Error log 
  895. PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'"); 
  896. $v_result = PCLZIP_ERR_MISSING_FILE; 
  897. else { 
  898. // ----- Duplicate the archive 
  899. $v_result = $this->privDuplicate($p_archive); 
  900.  
  901. // ----- Invalid variable 
  902. else 
  903. // ----- Error log 
  904. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); 
  905. $v_result = PCLZIP_ERR_INVALID_PARAMETER; 
  906.  
  907. // ----- Return 
  908. return $v_result; 
  909. // -------------------------------------------------------------------------------- 
  910.  
  911. // -------------------------------------------------------------------------------- 
  912. // Function : merge() 
  913. // Description : 
  914. // This method merge the $p_archive_to_add archive at the end of the current 
  915. // one ($this). 
  916. // If the archive ($this) does not exist, the merge becomes a duplicate. 
  917. // If the $p_archive_to_add archive does not exist, the merge is a success. 
  918. // Parameters : 
  919. // $p_archive_to_add : It can be directly the filename of a valid zip archive,  
  920. // or a PclZip object archive. 
  921. // Return Values : 
  922. // 1 on success,  
  923. // 0 or negative values on error (see below). 
  924. // -------------------------------------------------------------------------------- 
  925. function merge($p_archive_to_add) 
  926. $v_result = 1; 
  927.  
  928. // ----- Reset the error handler 
  929. $this->privErrorReset(); 
  930.  
  931. // ----- Check archive 
  932. if (!$this->privCheckFormat()) { 
  933. return(0); 
  934.  
  935. // ----- Look if the $p_archive_to_add is a PclZip object 
  936. if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) 
  937.  
  938. // ----- Merge the archive 
  939. $v_result = $this->privMerge($p_archive_to_add); 
  940.  
  941. // ----- Look if the $p_archive_to_add is a string (so a filename) 
  942. else if (is_string($p_archive_to_add)) 
  943.  
  944. // ----- Create a temporary archive 
  945. $v_object_archive = new PclZip($p_archive_to_add); 
  946.  
  947. // ----- Merge the archive 
  948. $v_result = $this->privMerge($v_object_archive); 
  949.  
  950. // ----- Invalid variable 
  951. else 
  952. // ----- Error log 
  953. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); 
  954. $v_result = PCLZIP_ERR_INVALID_PARAMETER; 
  955.  
  956. // ----- Return 
  957. return $v_result; 
  958. // -------------------------------------------------------------------------------- 
  959.  
  960.  
  961.  
  962. // -------------------------------------------------------------------------------- 
  963. // Function : errorCode() 
  964. // Description : 
  965. // Parameters : 
  966. // -------------------------------------------------------------------------------- 
  967. function errorCode() 
  968. if (PCLZIP_ERROR_EXTERNAL == 1) { 
  969. return(PclErrorCode()); 
  970. else { 
  971. return($this->error_code); 
  972. // -------------------------------------------------------------------------------- 
  973.  
  974. // -------------------------------------------------------------------------------- 
  975. // Function : errorName() 
  976. // Description : 
  977. // Parameters : 
  978. // -------------------------------------------------------------------------------- 
  979. function errorName($p_with_code=false) 
  980. $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',  
  981. PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',  
  982. PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',  
  983. PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',  
  984. PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',  
  985. PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',  
  986. PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',  
  987. PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',  
  988. PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',  
  989. PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',  
  990. PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',  
  991. PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',  
  992. PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',  
  993. PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',  
  994. PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',  
  995. PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',  
  996. PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',  
  997. PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',  
  998. PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION' 
  999. , PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE' 
  1000. , PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION' 
  1001. ); 
  1002.  
  1003. if (isset($v_name[$this->error_code])) { 
  1004. $v_value = $v_name[$this->error_code]; 
  1005. else { 
  1006. $v_value = 'NoName'; 
  1007.  
  1008. if ($p_with_code) { 
  1009. return($v_value.' ('.$this->error_code.')'); 
  1010. else { 
  1011. return($v_value); 
  1012. // -------------------------------------------------------------------------------- 
  1013.  
  1014. // -------------------------------------------------------------------------------- 
  1015. // Function : errorInfo() 
  1016. // Description : 
  1017. // Parameters : 
  1018. // -------------------------------------------------------------------------------- 
  1019. function errorInfo($p_full=false) 
  1020. if (PCLZIP_ERROR_EXTERNAL == 1) { 
  1021. return(PclErrorString()); 
  1022. else { 
  1023. if ($p_full) { 
  1024. return($this->errorName(true)." : ".$this->error_string); 
  1025. else { 
  1026. return($this->error_string." [code ".$this->error_code."]"); 
  1027. // -------------------------------------------------------------------------------- 
  1028.  
  1029.  
  1030. // -------------------------------------------------------------------------------- 
  1031. // ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS ***** 
  1032. // ***** ***** 
  1033. // ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY ***** 
  1034. // -------------------------------------------------------------------------------- 
  1035.  
  1036.  
  1037.  
  1038. // -------------------------------------------------------------------------------- 
  1039. // Function : privCheckFormat() 
  1040. // Description : 
  1041. // This method check that the archive exists and is a valid zip archive. 
  1042. // Several level of check exists. (futur) 
  1043. // Parameters : 
  1044. // $p_level : Level of check. Default 0. 
  1045. // 0 : Check the first bytes (magic codes) (default value)) 
  1046. // 1 : 0 + Check the central directory (futur) 
  1047. // 2 : 1 + Check each file header (futur) 
  1048. // Return Values : 
  1049. // true on success,  
  1050. // false on error, the error code is set. 
  1051. // -------------------------------------------------------------------------------- 
  1052. function privCheckFormat($p_level=0) 
  1053. $v_result = true; 
  1054.  
  1055. // ----- Reset the file system cache 
  1056. clearstatcache(); 
  1057.  
  1058. // ----- Reset the error handler 
  1059. $this->privErrorReset(); 
  1060.  
  1061. // ----- Look if the file exits 
  1062. if (!is_file($this->zipname)) { 
  1063. // ----- Error log 
  1064. PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'"); 
  1065. return(false); 
  1066.  
  1067. // ----- Check that the file is readeable 
  1068. if (!is_readable($this->zipname)) { 
  1069. // ----- Error log 
  1070. PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'"); 
  1071. return(false); 
  1072.  
  1073. // ----- Check the magic code 
  1074. // TBC 
  1075.  
  1076. // ----- Check the central header 
  1077. // TBC 
  1078.  
  1079. // ----- Check each file header 
  1080. // TBC 
  1081.  
  1082. // ----- Return 
  1083. return $v_result; 
  1084. // -------------------------------------------------------------------------------- 
  1085.  
  1086. // -------------------------------------------------------------------------------- 
  1087. // Function : privParseOptions() 
  1088. // Description : 
  1089. // This internal methods reads the variable list of arguments ($p_options_list,  
  1090. // $p_size) and generate an array with the options and values ($v_result_list). 
  1091. // $v_requested_options contains the options that can be present and those that 
  1092. // must be present. 
  1093. // $v_requested_options is an array, with the option value as key, and 'optional',  
  1094. // or 'mandatory' as value. 
  1095. // Parameters : 
  1096. // See above. 
  1097. // Return Values : 
  1098. // 1 on success. 
  1099. // 0 on failure. 
  1100. // -------------------------------------------------------------------------------- 
  1101. function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false) 
  1102. $v_result=1; 
  1103.  
  1104. // ----- Read the options 
  1105. $i=0; 
  1106. while ($i<$p_size) { 
  1107.  
  1108. // ----- Check if the option is supported 
  1109. if (!isset($v_requested_options[$p_options_list[$i]])) { 
  1110. // ----- Error log 
  1111. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method"); 
  1112.  
  1113. // ----- Return 
  1114. return PclZip::errorCode(); 
  1115.  
  1116. // ----- Look for next option 
  1117. switch ($p_options_list[$i]) { 
  1118. // ----- Look for options that request a path value 
  1119. case PCLZIP_OPT_PATH : 
  1120. case PCLZIP_OPT_REMOVE_PATH : 
  1121. case PCLZIP_OPT_ADD_PATH : 
  1122. // ----- Check the number of parameters 
  1123. if (($i+1) >= $p_size) { 
  1124. // ----- Error log 
  1125. PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1126.  
  1127. // ----- Return 
  1128. return PclZip::errorCode(); 
  1129.  
  1130. // ----- Get the value 
  1131. $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); 
  1132. $i++; 
  1133. break; 
  1134.  
  1135. case PCLZIP_OPT_TEMP_FILE_THRESHOLD : 
  1136. // ----- Check the number of parameters 
  1137. if (($i+1) >= $p_size) { 
  1138. PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1139. return PclZip::errorCode(); 
  1140.  
  1141. // ----- Check for incompatible options 
  1142. if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { 
  1143. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); 
  1144. return PclZip::errorCode(); 
  1145.  
  1146. // ----- Check the value 
  1147. $v_value = $p_options_list[$i+1]; 
  1148. if ((!is_integer($v_value)) || ($v_value<0)) { 
  1149. PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1150. return PclZip::errorCode(); 
  1151.  
  1152. // ----- Get the value (and convert it in bytes) 
  1153. $v_result_list[$p_options_list[$i]] = $v_value*1048576; 
  1154. $i++; 
  1155. break; 
  1156.  
  1157. case PCLZIP_OPT_TEMP_FILE_ON : 
  1158. // ----- Check for incompatible options 
  1159. if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { 
  1160. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); 
  1161. return PclZip::errorCode(); 
  1162.  
  1163. $v_result_list[$p_options_list[$i]] = true; 
  1164. break; 
  1165.  
  1166. case PCLZIP_OPT_TEMP_FILE_OFF : 
  1167. // ----- Check for incompatible options 
  1168. if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) { 
  1169. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'"); 
  1170. return PclZip::errorCode(); 
  1171. // ----- Check for incompatible options 
  1172. if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { 
  1173. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'"); 
  1174. return PclZip::errorCode(); 
  1175.  
  1176. $v_result_list[$p_options_list[$i]] = true; 
  1177. break; 
  1178.  
  1179. case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : 
  1180. // ----- Check the number of parameters 
  1181. if (($i+1) >= $p_size) { 
  1182. // ----- Error log 
  1183. PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1184.  
  1185. // ----- Return 
  1186. return PclZip::errorCode(); 
  1187.  
  1188. // ----- Get the value 
  1189. if ( is_string($p_options_list[$i+1]) 
  1190. && ($p_options_list[$i+1] != '')) { 
  1191. $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); 
  1192. $i++; 
  1193. else { 
  1194. break; 
  1195.  
  1196. // ----- Look for options that request an array of string for value 
  1197. case PCLZIP_OPT_BY_NAME : 
  1198. // ----- Check the number of parameters 
  1199. if (($i+1) >= $p_size) { 
  1200. // ----- Error log 
  1201. PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1202.  
  1203. // ----- Return 
  1204. return PclZip::errorCode(); 
  1205.  
  1206. // ----- Get the value 
  1207. if (is_string($p_options_list[$i+1])) { 
  1208. $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1]; 
  1209. else if (is_array($p_options_list[$i+1])) { 
  1210. $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; 
  1211. else { 
  1212. // ----- Error log 
  1213. PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1214.  
  1215. // ----- Return 
  1216. return PclZip::errorCode(); 
  1217. $i++; 
  1218. break; 
  1219.  
  1220. // ----- Look for options that request an EREG or PREG expression 
  1221. case PCLZIP_OPT_BY_EREG : 
  1222. // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG 
  1223. // to PCLZIP_OPT_BY_PREG 
  1224. $p_options_list[$i] = PCLZIP_OPT_BY_PREG; 
  1225. case PCLZIP_OPT_BY_PREG : 
  1226. //case PCLZIP_OPT_CRYPT : 
  1227. // ----- Check the number of parameters 
  1228. if (($i+1) >= $p_size) { 
  1229. // ----- Error log 
  1230. PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1231.  
  1232. // ----- Return 
  1233. return PclZip::errorCode(); 
  1234.  
  1235. // ----- Get the value 
  1236. if (is_string($p_options_list[$i+1])) { 
  1237. $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; 
  1238. else { 
  1239. // ----- Error log 
  1240. PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1241.  
  1242. // ----- Return 
  1243. return PclZip::errorCode(); 
  1244. $i++; 
  1245. break; 
  1246.  
  1247. // ----- Look for options that takes a string 
  1248. case PCLZIP_OPT_COMMENT : 
  1249. case PCLZIP_OPT_ADD_COMMENT : 
  1250. case PCLZIP_OPT_PREPEND_COMMENT : 
  1251. // ----- Check the number of parameters 
  1252. if (($i+1) >= $p_size) { 
  1253. // ----- Error log 
  1254. PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,  
  1255. "Missing parameter value for option '" 
  1256. .PclZipUtilOptionText($p_options_list[$i]) 
  1257. ."'"); 
  1258.  
  1259. // ----- Return 
  1260. return PclZip::errorCode(); 
  1261.  
  1262. // ----- Get the value 
  1263. if (is_string($p_options_list[$i+1])) { 
  1264. $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; 
  1265. else { 
  1266. // ----- Error log 
  1267. PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,  
  1268. "Wrong parameter value for option '" 
  1269. .PclZipUtilOptionText($p_options_list[$i]) 
  1270. ."'"); 
  1271.  
  1272. // ----- Return 
  1273. return PclZip::errorCode(); 
  1274. $i++; 
  1275. break; 
  1276.  
  1277. // ----- Look for options that request an array of index 
  1278. case PCLZIP_OPT_BY_INDEX : 
  1279. // ----- Check the number of parameters 
  1280. if (($i+1) >= $p_size) { 
  1281. // ----- Error log 
  1282. PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1283.  
  1284. // ----- Return 
  1285. return PclZip::errorCode(); 
  1286.  
  1287. // ----- Get the value 
  1288. $v_work_list = array(); 
  1289. if (is_string($p_options_list[$i+1])) { 
  1290.  
  1291. // ----- Remove spaces 
  1292. $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', ''); 
  1293.  
  1294. // ----- Parse items 
  1295. $v_work_list = explode(", ", $p_options_list[$i+1]); 
  1296. else if (is_integer($p_options_list[$i+1])) { 
  1297. $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1]; 
  1298. else if (is_array($p_options_list[$i+1])) { 
  1299. $v_work_list = $p_options_list[$i+1]; 
  1300. else { 
  1301. // ----- Error log 
  1302. PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1303.  
  1304. // ----- Return 
  1305. return PclZip::errorCode(); 
  1306.  
  1307. // ----- Reduce the index list 
  1308. // each index item in the list must be a couple with a start and 
  1309. // an end value : [0, 3], [5-5], [8-10], ... 
  1310. // ----- Check the format of each item 
  1311. $v_sort_flag=false; 
  1312. $v_sort_value=0; 
  1313. for ($j=0; $j<sizeof($v_work_list); $j++) { 
  1314. // ----- Explode the item 
  1315. $v_item_list = explode("-", $v_work_list[$j]); 
  1316. $v_size_item_list = sizeof($v_item_list); 
  1317.  
  1318. // ----- TBC : Here we might check that each item is a 
  1319. // real integer ... 
  1320.  
  1321. // ----- Look for single value 
  1322. if ($v_size_item_list == 1) { 
  1323. // ----- Set the option value 
  1324. $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; 
  1325. $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0]; 
  1326. elseif ($v_size_item_list == 2) { 
  1327. // ----- Set the option value 
  1328. $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; 
  1329. $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1]; 
  1330. else { 
  1331. // ----- Error log 
  1332. PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1333.  
  1334. // ----- Return 
  1335. return PclZip::errorCode(); 
  1336.  
  1337.  
  1338. // ----- Look for list sort 
  1339. if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) { 
  1340. $v_sort_flag=true; 
  1341.  
  1342. // ----- TBC : An automatic sort should be writen ... 
  1343. // ----- Error log 
  1344. PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1345.  
  1346. // ----- Return 
  1347. return PclZip::errorCode(); 
  1348. $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start']; 
  1349.  
  1350. // ----- Sort the items 
  1351. if ($v_sort_flag) { 
  1352. // TBC : To Be Completed 
  1353.  
  1354. // ----- Next option 
  1355. $i++; 
  1356. break; 
  1357.  
  1358. // ----- Look for options that request no value 
  1359. case PCLZIP_OPT_REMOVE_ALL_PATH : 
  1360. case PCLZIP_OPT_EXTRACT_AS_STRING : 
  1361. case PCLZIP_OPT_NO_COMPRESSION : 
  1362. case PCLZIP_OPT_EXTRACT_IN_OUTPUT : 
  1363. case PCLZIP_OPT_REPLACE_NEWER : 
  1364. case PCLZIP_OPT_STOP_ON_ERROR : 
  1365. $v_result_list[$p_options_list[$i]] = true; 
  1366. break; 
  1367.  
  1368. // ----- Look for options that request an octal value 
  1369. case PCLZIP_OPT_SET_CHMOD : 
  1370. // ----- Check the number of parameters 
  1371. if (($i+1) >= $p_size) { 
  1372. // ----- Error log 
  1373. PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1374.  
  1375. // ----- Return 
  1376. return PclZip::errorCode(); 
  1377.  
  1378. // ----- Get the value 
  1379. $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; 
  1380. $i++; 
  1381. break; 
  1382.  
  1383. // ----- Look for options that request a call-back 
  1384. case PCLZIP_CB_PRE_EXTRACT : 
  1385. case PCLZIP_CB_POST_EXTRACT : 
  1386. case PCLZIP_CB_PRE_ADD : 
  1387. case PCLZIP_CB_POST_ADD : 
  1388. /** for futur use 
  1389. case PCLZIP_CB_PRE_DELETE : 
  1390. case PCLZIP_CB_POST_DELETE : 
  1391. case PCLZIP_CB_PRE_LIST : 
  1392. case PCLZIP_CB_POST_LIST : 
  1393. */ 
  1394. // ----- Check the number of parameters 
  1395. if (($i+1) >= $p_size) { 
  1396. // ----- Error log 
  1397. PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1398.  
  1399. // ----- Return 
  1400. return PclZip::errorCode(); 
  1401.  
  1402. // ----- Get the value 
  1403. $v_function_name = $p_options_list[$i+1]; 
  1404.  
  1405. // ----- Check that the value is a valid existing function 
  1406. if (!function_exists($v_function_name)) { 
  1407. // ----- Error log 
  1408. PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 
  1409.  
  1410. // ----- Return 
  1411. return PclZip::errorCode(); 
  1412.  
  1413. // ----- Set the attribute 
  1414. $v_result_list[$p_options_list[$i]] = $v_function_name; 
  1415. $i++; 
  1416. break; 
  1417.  
  1418. default : 
  1419. // ----- Error log 
  1420. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,  
  1421. "Unknown parameter '" 
  1422. .$p_options_list[$i]."'"); 
  1423.  
  1424. // ----- Return 
  1425. return PclZip::errorCode(); 
  1426.  
  1427. // ----- Next options 
  1428. $i++; 
  1429.  
  1430. // ----- Look for mandatory options 
  1431. if ($v_requested_options !== false) { 
  1432. for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { 
  1433. // ----- Look for mandatory option 
  1434. if ($v_requested_options[$key] == 'mandatory') { 
  1435. // ----- Look if present 
  1436. if (!isset($v_result_list[$key])) { 
  1437. // ----- Error log 
  1438. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); 
  1439.  
  1440. // ----- Return 
  1441. return PclZip::errorCode(); 
  1442.  
  1443. // ----- Look for default values 
  1444. if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { 
  1445.  
  1446.  
  1447. // ----- Return 
  1448. return $v_result; 
  1449. // -------------------------------------------------------------------------------- 
  1450.  
  1451. // -------------------------------------------------------------------------------- 
  1452. // Function : privOptionDefaultThreshold() 
  1453. // Description : 
  1454. // Parameters : 
  1455. // Return Values : 
  1456. // -------------------------------------------------------------------------------- 
  1457. function privOptionDefaultThreshold(&$p_options) 
  1458. $v_result=1; 
  1459.  
  1460. if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) 
  1461. || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) { 
  1462. return $v_result; 
  1463.  
  1464. // ----- Get 'memory_limit' configuration value 
  1465. $v_memory_limit = ini_get('memory_limit'); 
  1466. $v_memory_limit = trim($v_memory_limit); 
  1467. $v_memory_limit_int = (int) $v_memory_limit; 
  1468. $last = strtolower(substr($v_memory_limit, -1)); 
  1469.  
  1470. if($last == 'g') 
  1471. //$v_memory_limit_int = $v_memory_limit_int*1024*1024*1024; 
  1472. $v_memory_limit_int = $v_memory_limit_int*1073741824; 
  1473. if($last == 'm') 
  1474. //$v_memory_limit_int = $v_memory_limit_int*1024*1024; 
  1475. $v_memory_limit_int = $v_memory_limit_int*1048576; 
  1476. if($last == 'k') 
  1477. $v_memory_limit_int = $v_memory_limit_int*1024; 
  1478.  
  1479. $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit_int*PCLZIP_TEMPORARY_FILE_RATIO); 
  1480.  
  1481.  
  1482. // ----- Sanity check : No threshold if value lower than 1M 
  1483. if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) { 
  1484. unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]); 
  1485.  
  1486. // ----- Return 
  1487. return $v_result; 
  1488. // -------------------------------------------------------------------------------- 
  1489.  
  1490. // -------------------------------------------------------------------------------- 
  1491. // Function : privFileDescrParseAtt() 
  1492. // Description : 
  1493. // Parameters : 
  1494. // Return Values : 
  1495. // 1 on success. 
  1496. // 0 on failure. 
  1497. // -------------------------------------------------------------------------------- 
  1498. function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false) 
  1499. $v_result=1; 
  1500.  
  1501. // ----- For each file in the list check the attributes 
  1502. foreach ($p_file_list as $v_key => $v_value) { 
  1503.  
  1504. // ----- Check if the option is supported 
  1505. if (!isset($v_requested_options[$v_key])) { 
  1506. // ----- Error log 
  1507. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file"); 
  1508.  
  1509. // ----- Return 
  1510. return PclZip::errorCode(); 
  1511.  
  1512. // ----- Look for attribute 
  1513. switch ($v_key) { 
  1514. case PCLZIP_ATT_FILE_NAME : 
  1515. if (!is_string($v_value)) { 
  1516. PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); 
  1517. return PclZip::errorCode(); 
  1518.  
  1519. $p_filedescr['filename'] = PclZipUtilPathReduction($v_value); 
  1520.  
  1521. if ($p_filedescr['filename'] == '') { 
  1522. PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'"); 
  1523. return PclZip::errorCode(); 
  1524.  
  1525. break; 
  1526.  
  1527. case PCLZIP_ATT_FILE_NEW_SHORT_NAME : 
  1528. if (!is_string($v_value)) { 
  1529. PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); 
  1530. return PclZip::errorCode(); 
  1531.  
  1532. $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value); 
  1533.  
  1534. if ($p_filedescr['new_short_name'] == '') { 
  1535. PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'"); 
  1536. return PclZip::errorCode(); 
  1537. break; 
  1538.  
  1539. case PCLZIP_ATT_FILE_NEW_FULL_NAME : 
  1540. if (!is_string($v_value)) { 
  1541. PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); 
  1542. return PclZip::errorCode(); 
  1543.  
  1544. $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value); 
  1545.  
  1546. if ($p_filedescr['new_full_name'] == '') { 
  1547. PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'"); 
  1548. return PclZip::errorCode(); 
  1549. break; 
  1550.  
  1551. // ----- Look for options that takes a string 
  1552. case PCLZIP_ATT_FILE_COMMENT : 
  1553. if (!is_string($v_value)) { 
  1554. PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); 
  1555. return PclZip::errorCode(); 
  1556.  
  1557. $p_filedescr['comment'] = $v_value; 
  1558. break; 
  1559.  
  1560. case PCLZIP_ATT_FILE_MTIME : 
  1561. if (!is_integer($v_value)) { 
  1562. PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'"); 
  1563. return PclZip::errorCode(); 
  1564.  
  1565. $p_filedescr['mtime'] = $v_value; 
  1566. break; 
  1567.  
  1568. case PCLZIP_ATT_FILE_CONTENT : 
  1569. $p_filedescr['content'] = $v_value; 
  1570. break; 
  1571.  
  1572. default : 
  1573. // ----- Error log 
  1574. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,  
  1575. "Unknown parameter '".$v_key."'"); 
  1576.  
  1577. // ----- Return 
  1578. return PclZip::errorCode(); 
  1579.  
  1580. // ----- Look for mandatory options 
  1581. if ($v_requested_options !== false) { 
  1582. for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { 
  1583. // ----- Look for mandatory option 
  1584. if ($v_requested_options[$key] == 'mandatory') { 
  1585. // ----- Look if present 
  1586. if (!isset($p_file_list[$key])) { 
  1587. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); 
  1588. return PclZip::errorCode(); 
  1589.  
  1590. // end foreach 
  1591.  
  1592. // ----- Return 
  1593. return $v_result; 
  1594. // -------------------------------------------------------------------------------- 
  1595.  
  1596. // -------------------------------------------------------------------------------- 
  1597. // Function : privFileDescrExpand() 
  1598. // Description : 
  1599. // This method look for each item of the list to see if its a file, a folder 
  1600. // or a string to be added as file. For any other type of files (link, other) 
  1601. // just ignore the item. 
  1602. // Then prepare the information that will be stored for that file. 
  1603. // When its a folder, expand the folder with all the files that are in that 
  1604. // folder (recursively). 
  1605. // Parameters : 
  1606. // Return Values : 
  1607. // 1 on success. 
  1608. // 0 on failure. 
  1609. // -------------------------------------------------------------------------------- 
  1610. function privFileDescrExpand(&$p_filedescr_list, &$p_options) 
  1611. $v_result=1; 
  1612.  
  1613. // ----- Create a result list 
  1614. $v_result_list = array(); 
  1615.  
  1616. // ----- Look each entry 
  1617. for ($i=0; $i<sizeof($p_filedescr_list); $i++) { 
  1618.  
  1619. // ----- Get filedescr 
  1620. $v_descr = $p_filedescr_list[$i]; 
  1621.  
  1622. // ----- Reduce the filename 
  1623. $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false); 
  1624. $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']); 
  1625.  
  1626. // ----- Look for real file or folder 
  1627. if (file_exists($v_descr['filename'])) { 
  1628. if (@is_file($v_descr['filename'])) { 
  1629. $v_descr['type'] = 'file'; 
  1630. else if (@is_dir($v_descr['filename'])) { 
  1631. $v_descr['type'] = 'folder'; 
  1632. else if (@is_link($v_descr['filename'])) { 
  1633. // skip 
  1634. continue; 
  1635. else { 
  1636. // skip 
  1637. continue; 
  1638.  
  1639. // ----- Look for string added as file 
  1640. else if (isset($v_descr['content'])) { 
  1641. $v_descr['type'] = 'virtual_file'; 
  1642.  
  1643. // ----- Missing file 
  1644. else { 
  1645. // ----- Error log 
  1646. PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist"); 
  1647.  
  1648. // ----- Return 
  1649. return PclZip::errorCode(); 
  1650.  
  1651. // ----- Calculate the stored filename 
  1652. $this->privCalculateStoredFilename($v_descr, $p_options); 
  1653.  
  1654. // ----- Add the descriptor in result list 
  1655. $v_result_list[sizeof($v_result_list)] = $v_descr; 
  1656.  
  1657. // ----- Look for folder 
  1658. if ($v_descr['type'] == 'folder') { 
  1659. // ----- List of items in folder 
  1660. $v_dirlist_descr = array(); 
  1661. $v_dirlist_nb = 0; 
  1662. if ($v_folder_handler = @opendir($v_descr['filename'])) { 
  1663. while (($v_item_handler = @readdir($v_folder_handler)) !== false) { 
  1664.  
  1665. // ----- Skip '.' and '..' 
  1666. if (($v_item_handler == '.') || ($v_item_handler == '..')) { 
  1667. continue; 
  1668.  
  1669. // ----- Compose the full filename 
  1670. $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler; 
  1671.  
  1672. // ----- Look for different stored filename 
  1673. // Because the name of the folder was changed, the name of the 
  1674. // files/sub-folders also change 
  1675. if (($v_descr['stored_filename'] != $v_descr['filename']) 
  1676. && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) { 
  1677. if ($v_descr['stored_filename'] != '') { 
  1678. $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler; 
  1679. else { 
  1680. $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler; 
  1681.  
  1682. $v_dirlist_nb++; 
  1683.  
  1684. @closedir($v_folder_handler); 
  1685. else { 
  1686. // TBC : unable to open folder in read mode 
  1687.  
  1688. // ----- Expand each element of the list 
  1689. if ($v_dirlist_nb != 0) { 
  1690. // ----- Expand 
  1691. if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) { 
  1692. return $v_result; 
  1693.  
  1694. // ----- Concat the resulting list 
  1695. $v_result_list = array_merge($v_result_list, $v_dirlist_descr); 
  1696. else { 
  1697.  
  1698. // ----- Free local array 
  1699. unset($v_dirlist_descr); 
  1700.  
  1701. // ----- Get the result list 
  1702. $p_filedescr_list = $v_result_list; 
  1703.  
  1704. // ----- Return 
  1705. return $v_result; 
  1706. // -------------------------------------------------------------------------------- 
  1707.  
  1708. // -------------------------------------------------------------------------------- 
  1709. // Function : privCreate() 
  1710. // Description : 
  1711. // Parameters : 
  1712. // Return Values : 
  1713. // -------------------------------------------------------------------------------- 
  1714. function privCreate($p_filedescr_list, &$p_result_list, &$p_options) 
  1715. $v_result=1; 
  1716. $v_list_detail = array(); 
  1717.  
  1718. // ----- Magic quotes trick 
  1719. $this->privDisableMagicQuotes(); 
  1720.  
  1721. // ----- Open the file in write mode 
  1722. if (($v_result = $this->privOpenFd('wb')) != 1) 
  1723. // ----- Return 
  1724. return $v_result; 
  1725.  
  1726. // ----- Add the list of files 
  1727. $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options); 
  1728.  
  1729. // ----- Close 
  1730. $this->privCloseFd(); 
  1731.  
  1732. // ----- Magic quotes trick 
  1733. $this->privSwapBackMagicQuotes(); 
  1734.  
  1735. // ----- Return 
  1736. return $v_result; 
  1737. // -------------------------------------------------------------------------------- 
  1738.  
  1739. // -------------------------------------------------------------------------------- 
  1740. // Function : privAdd() 
  1741. // Description : 
  1742. // Parameters : 
  1743. // Return Values : 
  1744. // -------------------------------------------------------------------------------- 
  1745. function privAdd($p_filedescr_list, &$p_result_list, &$p_options) 
  1746. $v_result=1; 
  1747. $v_list_detail = array(); 
  1748.  
  1749. // ----- Look if the archive exists or is empty 
  1750. if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0)) 
  1751.  
  1752. // ----- Do a create 
  1753. $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options); 
  1754.  
  1755. // ----- Return 
  1756. return $v_result; 
  1757. // ----- Magic quotes trick 
  1758. $this->privDisableMagicQuotes(); 
  1759.  
  1760. // ----- Open the zip file 
  1761. if (($v_result=$this->privOpenFd('rb')) != 1) 
  1762. // ----- Magic quotes trick 
  1763. $this->privSwapBackMagicQuotes(); 
  1764.  
  1765. // ----- Return 
  1766. return $v_result; 
  1767.  
  1768. // ----- Read the central directory informations 
  1769. $v_central_dir = array(); 
  1770. if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) 
  1771. $this->privCloseFd(); 
  1772. $this->privSwapBackMagicQuotes(); 
  1773. return $v_result; 
  1774.  
  1775. // ----- Go to beginning of File 
  1776. @rewind($this->zip_fd); 
  1777.  
  1778. // ----- Creates a temporay file 
  1779. $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; 
  1780.  
  1781. // ----- Open the temporary file in write mode 
  1782. if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) 
  1783. $this->privCloseFd(); 
  1784. $this->privSwapBackMagicQuotes(); 
  1785.  
  1786. PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); 
  1787.  
  1788. // ----- Return 
  1789. return PclZip::errorCode(); 
  1790.  
  1791. // ----- Copy the files from the archive to the temporary file 
  1792. // TBC : Here I should better append the file and go back to erase the central dir 
  1793. $v_size = $v_central_dir['offset']; 
  1794. while ($v_size != 0) 
  1795. $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 
  1796. $v_buffer = fread($this->zip_fd, $v_read_size); 
  1797. @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); 
  1798. $v_size -= $v_read_size; 
  1799.  
  1800. // ----- Swap the file descriptor 
  1801. // Here is a trick : I swap the temporary fd with the zip fd, in order to use 
  1802. // the following methods on the temporary fil and not the real archive 
  1803. $v_swap = $this->zip_fd; 
  1804. $this->zip_fd = $v_zip_temp_fd; 
  1805. $v_zip_temp_fd = $v_swap; 
  1806.  
  1807. // ----- Add the files 
  1808. $v_header_list = array(); 
  1809. if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) 
  1810. fclose($v_zip_temp_fd); 
  1811. $this->privCloseFd(); 
  1812. @unlink($v_zip_temp_name); 
  1813. $this->privSwapBackMagicQuotes(); 
  1814.  
  1815. // ----- Return 
  1816. return $v_result; 
  1817.  
  1818. // ----- Store the offset of the central dir 
  1819. $v_offset = @ftell($this->zip_fd); 
  1820.  
  1821. // ----- Copy the block of file headers from the old archive 
  1822. $v_size = $v_central_dir['size']; 
  1823. while ($v_size != 0) 
  1824. $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 
  1825. $v_buffer = @fread($v_zip_temp_fd, $v_read_size); 
  1826. @fwrite($this->zip_fd, $v_buffer, $v_read_size); 
  1827. $v_size -= $v_read_size; 
  1828.  
  1829. // ----- Create the Central Dir files header 
  1830. for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++) 
  1831. // ----- Create the file header 
  1832. if ($v_header_list[$i]['status'] == 'ok') { 
  1833. if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { 
  1834. fclose($v_zip_temp_fd); 
  1835. $this->privCloseFd(); 
  1836. @unlink($v_zip_temp_name); 
  1837. $this->privSwapBackMagicQuotes(); 
  1838.  
  1839. // ----- Return 
  1840. return $v_result; 
  1841. $v_count++; 
  1842.  
  1843. // ----- Transform the header to a 'usable' info 
  1844. $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); 
  1845.  
  1846. // ----- Zip file comment 
  1847. $v_comment = $v_central_dir['comment']; 
  1848. if (isset($p_options[PCLZIP_OPT_COMMENT])) { 
  1849. $v_comment = $p_options[PCLZIP_OPT_COMMENT]; 
  1850. if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) { 
  1851. $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT]; 
  1852. if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) { 
  1853. $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment; 
  1854.  
  1855. // ----- Calculate the size of the central header 
  1856. $v_size = @ftell($this->zip_fd)-$v_offset; 
  1857.  
  1858. // ----- Create the central dir footer 
  1859. if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1) 
  1860. // ----- Reset the file list 
  1861. unset($v_header_list); 
  1862. $this->privSwapBackMagicQuotes(); 
  1863.  
  1864. // ----- Return 
  1865. return $v_result; 
  1866.  
  1867. // ----- Swap back the file descriptor 
  1868. $v_swap = $this->zip_fd; 
  1869. $this->zip_fd = $v_zip_temp_fd; 
  1870. $v_zip_temp_fd = $v_swap; 
  1871.  
  1872. // ----- Close 
  1873. $this->privCloseFd(); 
  1874.  
  1875. // ----- Close the temporary file 
  1876. @fclose($v_zip_temp_fd); 
  1877.  
  1878. // ----- Magic quotes trick 
  1879. $this->privSwapBackMagicQuotes(); 
  1880.  
  1881. // ----- Delete the zip file 
  1882. // TBC : I should test the result ... 
  1883. @unlink($this->zipname); 
  1884.  
  1885. // ----- Rename the temporary file 
  1886. // TBC : I should test the result ... 
  1887. //@rename($v_zip_temp_name, $this->zipname); 
  1888. PclZipUtilRename($v_zip_temp_name, $this->zipname); 
  1889.  
  1890. // ----- Return 
  1891. return $v_result; 
  1892. // -------------------------------------------------------------------------------- 
  1893.  
  1894. // -------------------------------------------------------------------------------- 
  1895. // Function : privOpenFd() 
  1896. // Description : 
  1897. // Parameters : 
  1898. // -------------------------------------------------------------------------------- 
  1899. function privOpenFd($p_mode) 
  1900. $v_result=1; 
  1901.  
  1902. // ----- Look if already open 
  1903. if ($this->zip_fd != 0) 
  1904. // ----- Error log 
  1905. PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open'); 
  1906.  
  1907. // ----- Return 
  1908. return PclZip::errorCode(); 
  1909.  
  1910. // ----- Open the zip file 
  1911. if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0) 
  1912. // ----- Error log 
  1913. PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode'); 
  1914.  
  1915. // ----- Return 
  1916. return PclZip::errorCode(); 
  1917.  
  1918. // ----- Return 
  1919. return $v_result; 
  1920. // -------------------------------------------------------------------------------- 
  1921.  
  1922. // -------------------------------------------------------------------------------- 
  1923. // Function : privCloseFd() 
  1924. // Description : 
  1925. // Parameters : 
  1926. // -------------------------------------------------------------------------------- 
  1927. function privCloseFd() 
  1928. $v_result=1; 
  1929.  
  1930. if ($this->zip_fd != 0) 
  1931. @fclose($this->zip_fd); 
  1932. $this->zip_fd = 0; 
  1933.  
  1934. // ----- Return 
  1935. return $v_result; 
  1936. // -------------------------------------------------------------------------------- 
  1937.  
  1938. // -------------------------------------------------------------------------------- 
  1939. // Function : privAddList() 
  1940. // Description : 
  1941. // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is 
  1942. // different from the real path of the file. This is usefull if you want to have PclTar 
  1943. // running in any directory, and memorize relative path from an other directory. 
  1944. // Parameters : 
  1945. // $p_list : An array containing the file or directory names to add in the tar 
  1946. // $p_result_list : list of added files with their properties (specially the status field) 
  1947. // $p_add_dir : Path to add in the filename path archived 
  1948. // $p_remove_dir : Path to remove in the filename path archived 
  1949. // Return Values : 
  1950. // -------------------------------------------------------------------------------- 
  1951. // function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options) 
  1952. function privAddList($p_filedescr_list, &$p_result_list, &$p_options) 
  1953. $v_result=1; 
  1954.  
  1955. // ----- Add the files 
  1956. $v_header_list = array(); 
  1957. if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) 
  1958. // ----- Return 
  1959. return $v_result; 
  1960.  
  1961. // ----- Store the offset of the central dir 
  1962. $v_offset = @ftell($this->zip_fd); 
  1963.  
  1964. // ----- Create the Central Dir files header 
  1965. for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++) 
  1966. // ----- Create the file header 
  1967. if ($v_header_list[$i]['status'] == 'ok') { 
  1968. if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { 
  1969. // ----- Return 
  1970. return $v_result; 
  1971. $v_count++; 
  1972.  
  1973. // ----- Transform the header to a 'usable' info 
  1974. $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); 
  1975.  
  1976. // ----- Zip file comment 
  1977. $v_comment = ''; 
  1978. if (isset($p_options[PCLZIP_OPT_COMMENT])) { 
  1979. $v_comment = $p_options[PCLZIP_OPT_COMMENT]; 
  1980.  
  1981. // ----- Calculate the size of the central header 
  1982. $v_size = @ftell($this->zip_fd)-$v_offset; 
  1983.  
  1984. // ----- Create the central dir footer 
  1985. if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1) 
  1986. // ----- Reset the file list 
  1987. unset($v_header_list); 
  1988.  
  1989. // ----- Return 
  1990. return $v_result; 
  1991.  
  1992. // ----- Return 
  1993. return $v_result; 
  1994. // -------------------------------------------------------------------------------- 
  1995.  
  1996. // -------------------------------------------------------------------------------- 
  1997. // Function : privAddFileList() 
  1998. // Description : 
  1999. // Parameters : 
  2000. // $p_filedescr_list : An array containing the file description 
  2001. // or directory names to add in the zip 
  2002. // $p_result_list : list of added files with their properties (specially the status field) 
  2003. // Return Values : 
  2004. // -------------------------------------------------------------------------------- 
  2005. function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options) 
  2006. $v_result=1; 
  2007. $v_header = array(); 
  2008.  
  2009. // ----- Recuperate the current number of elt in list 
  2010. $v_nb = sizeof($p_result_list); 
  2011.  
  2012. // ----- Loop on the files 
  2013. for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) { 
  2014. // ----- Format the filename 
  2015. $p_filedescr_list[$j]['filename'] 
  2016. = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false); 
  2017.  
  2018.  
  2019. // ----- Skip empty file names 
  2020. // TBC : Can this be possible ? not checked in DescrParseAtt ? 
  2021. if ($p_filedescr_list[$j]['filename'] == "") { 
  2022. continue; 
  2023.  
  2024. // ----- Check the filename 
  2025. if ( ($p_filedescr_list[$j]['type'] != 'virtual_file') 
  2026. && (!file_exists($p_filedescr_list[$j]['filename']))) { 
  2027. PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist"); 
  2028. return PclZip::errorCode(); 
  2029.  
  2030. // ----- Look if it is a file or a dir with no all path remove option 
  2031. // or a dir with all its path removed 
  2032. // if ( (is_file($p_filedescr_list[$j]['filename'])) 
  2033. // || ( is_dir($p_filedescr_list[$j]['filename']) 
  2034. if ( ($p_filedescr_list[$j]['type'] == 'file') 
  2035. || ($p_filedescr_list[$j]['type'] == 'virtual_file') 
  2036. || ( ($p_filedescr_list[$j]['type'] == 'folder') 
  2037. && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]) 
  2038. || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) 
  2039. ) { 
  2040.  
  2041. // ----- Add the file 
  2042. $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,  
  2043. $p_options); 
  2044. if ($v_result != 1) { 
  2045. return $v_result; 
  2046.  
  2047. // ----- Store the file infos 
  2048. $p_result_list[$v_nb++] = $v_header; 
  2049.  
  2050. // ----- Return 
  2051. return $v_result; 
  2052. // -------------------------------------------------------------------------------- 
  2053.  
  2054. // -------------------------------------------------------------------------------- 
  2055. // Function : privAddFile() 
  2056. // Description : 
  2057. // Parameters : 
  2058. // Return Values : 
  2059. // -------------------------------------------------------------------------------- 
  2060. function privAddFile($p_filedescr, &$p_header, &$p_options) 
  2061. $v_result=1; 
  2062.  
  2063. // ----- Working variable 
  2064. $p_filename = $p_filedescr['filename']; 
  2065.  
  2066. // TBC : Already done in the fileAtt check ... ? 
  2067. if ($p_filename == "") { 
  2068. // ----- Error log 
  2069. PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)"); 
  2070.  
  2071. // ----- Return 
  2072. return PclZip::errorCode(); 
  2073.  
  2074. // ----- Look for a stored different filename 
  2075. /** TBC : Removed 
  2076. if (isset($p_filedescr['stored_filename'])) { 
  2077. $v_stored_filename = $p_filedescr['stored_filename']; 
  2078. else { 
  2079. $v_stored_filename = $p_filedescr['stored_filename']; 
  2080. */ 
  2081.  
  2082. // ----- Set the file properties 
  2083. clearstatcache(); 
  2084. $p_header['version'] = 20; 
  2085. $p_header['version_extracted'] = 10; 
  2086. $p_header['flag'] = 0; 
  2087. $p_header['compression'] = 0; 
  2088. $p_header['crc'] = 0; 
  2089. $p_header['compressed_size'] = 0; 
  2090. $p_header['filename_len'] = strlen($p_filename); 
  2091. $p_header['extra_len'] = 0; 
  2092. $p_header['disk'] = 0; 
  2093. $p_header['internal'] = 0; 
  2094. $p_header['offset'] = 0; 
  2095. $p_header['filename'] = $p_filename; 
  2096. // TBC : Removed $p_header['stored_filename'] = $v_stored_filename; 
  2097. $p_header['stored_filename'] = $p_filedescr['stored_filename']; 
  2098. $p_header['extra'] = ''; 
  2099. $p_header['status'] = 'ok'; 
  2100. $p_header['index'] = -1; 
  2101.  
  2102. // ----- Look for regular file 
  2103. if ($p_filedescr['type']=='file') { 
  2104. $p_header['external'] = 0x00000000; 
  2105. $p_header['size'] = filesize($p_filename); 
  2106.  
  2107. // ----- Look for regular folder 
  2108. else if ($p_filedescr['type']=='folder') { 
  2109. $p_header['external'] = 0x00000010; 
  2110. $p_header['mtime'] = filemtime($p_filename); 
  2111. $p_header['size'] = filesize($p_filename); 
  2112.  
  2113. // ----- Look for virtual file 
  2114. else if ($p_filedescr['type'] == 'virtual_file') { 
  2115. $p_header['external'] = 0x00000000; 
  2116. $p_header['size'] = strlen($p_filedescr['content']); 
  2117.  
  2118.  
  2119. // ----- Look for filetime 
  2120. if (isset($p_filedescr['mtime'])) { 
  2121. $p_header['mtime'] = $p_filedescr['mtime']; 
  2122. else if ($p_filedescr['type'] == 'virtual_file') { 
  2123. $p_header['mtime'] = time(); 
  2124. else { 
  2125. $p_header['mtime'] = filemtime($p_filename); 
  2126.  
  2127. // ------ Look for file comment 
  2128. if (isset($p_filedescr['comment'])) { 
  2129. $p_header['comment_len'] = strlen($p_filedescr['comment']); 
  2130. $p_header['comment'] = $p_filedescr['comment']; 
  2131. else { 
  2132. $p_header['comment_len'] = 0; 
  2133. $p_header['comment'] = ''; 
  2134.  
  2135. // ----- Look for pre-add callback 
  2136. if (isset($p_options[PCLZIP_CB_PRE_ADD])) { 
  2137.  
  2138. // ----- Generate a local information 
  2139. $v_local_header = array(); 
  2140. $this->privConvertHeader2FileInfo($p_header, $v_local_header); 
  2141.  
  2142. // ----- Call the callback 
  2143. // Here I do not use call_user_func() because I need to send a reference to the 
  2144. // header. 
  2145. $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header); 
  2146. if ($v_result == 0) { 
  2147. // ----- Change the file status 
  2148. $p_header['status'] = "skipped"; 
  2149. $v_result = 1; 
  2150.  
  2151. // ----- Update the informations 
  2152. // Only some fields can be modified 
  2153. if ($p_header['stored_filename'] != $v_local_header['stored_filename']) { 
  2154. $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']); 
  2155.  
  2156. // ----- Look for empty stored filename 
  2157. if ($p_header['stored_filename'] == "") { 
  2158. $p_header['status'] = "filtered"; 
  2159.  
  2160. // ----- Check the path length 
  2161. if (strlen($p_header['stored_filename']) > 0xFF) { 
  2162. $p_header['status'] = 'filename_too_long'; 
  2163.  
  2164. // ----- Look if no error, or file not skipped 
  2165. if ($p_header['status'] == 'ok') { 
  2166.  
  2167. // ----- Look for a file 
  2168. if ($p_filedescr['type'] == 'file') { 
  2169. // ----- Look for using temporary file to zip 
  2170. if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) 
  2171. && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) 
  2172. || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) 
  2173. && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) { 
  2174. $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options); 
  2175. if ($v_result < PCLZIP_ERR_NO_ERROR) { 
  2176. return $v_result; 
  2177.  
  2178. // ----- Use "in memory" zip algo 
  2179. else { 
  2180.  
  2181. // ----- Open the source file 
  2182. if (($v_file = @fopen($p_filename, "rb")) == 0) { 
  2183. PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); 
  2184. return PclZip::errorCode(); 
  2185.  
  2186. // ----- Read the file content 
  2187. $v_content = @fread($v_file, $p_header['size']); 
  2188.  
  2189. // ----- Close the file 
  2190. @fclose($v_file); 
  2191.  
  2192. // ----- Calculate the CRC 
  2193. $p_header['crc'] = @crc32($v_content); 
  2194.  
  2195. // ----- Look for no compression 
  2196. if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { 
  2197. // ----- Set header parameters 
  2198. $p_header['compressed_size'] = $p_header['size']; 
  2199. $p_header['compression'] = 0; 
  2200.  
  2201. // ----- Look for normal compression 
  2202. else { 
  2203. // ----- Compress the content 
  2204. $v_content = @gzdeflate($v_content); 
  2205.  
  2206. // ----- Set header parameters 
  2207. $p_header['compressed_size'] = strlen($v_content); 
  2208. $p_header['compression'] = 8; 
  2209.  
  2210. // ----- Call the header generation 
  2211. if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { 
  2212. @fclose($v_file); 
  2213. return $v_result; 
  2214.  
  2215. // ----- Write the compressed (or not) content 
  2216. @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); 
  2217.  
  2218.  
  2219.  
  2220. // ----- Look for a virtual file (a file from string) 
  2221. else if ($p_filedescr['type'] == 'virtual_file') { 
  2222.  
  2223. $v_content = $p_filedescr['content']; 
  2224.  
  2225. // ----- Calculate the CRC 
  2226. $p_header['crc'] = @crc32($v_content); 
  2227.  
  2228. // ----- Look for no compression 
  2229. if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { 
  2230. // ----- Set header parameters 
  2231. $p_header['compressed_size'] = $p_header['size']; 
  2232. $p_header['compression'] = 0; 
  2233.  
  2234. // ----- Look for normal compression 
  2235. else { 
  2236. // ----- Compress the content 
  2237. $v_content = @gzdeflate($v_content); 
  2238.  
  2239. // ----- Set header parameters 
  2240. $p_header['compressed_size'] = strlen($v_content); 
  2241. $p_header['compression'] = 8; 
  2242.  
  2243. // ----- Call the header generation 
  2244. if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { 
  2245. @fclose($v_file); 
  2246. return $v_result; 
  2247.  
  2248. // ----- Write the compressed (or not) content 
  2249. @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); 
  2250.  
  2251. // ----- Look for a directory 
  2252. else if ($p_filedescr['type'] == 'folder') { 
  2253. // ----- Look for directory last '/' 
  2254. if (@substr($p_header['stored_filename'], -1) != '/') { 
  2255. $p_header['stored_filename'] .= '/'; 
  2256.  
  2257. // ----- Set the file properties 
  2258. $p_header['size'] = 0; 
  2259. //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked 
  2260. $p_header['external'] = 0x00000010; // Value for a folder : to be checked 
  2261.  
  2262. // ----- Call the header generation 
  2263. if (($v_result = $this->privWriteFileHeader($p_header)) != 1) 
  2264. return $v_result; 
  2265.  
  2266. // ----- Look for post-add callback 
  2267. if (isset($p_options[PCLZIP_CB_POST_ADD])) { 
  2268.  
  2269. // ----- Generate a local information 
  2270. $v_local_header = array(); 
  2271. $this->privConvertHeader2FileInfo($p_header, $v_local_header); 
  2272.  
  2273. // ----- Call the callback 
  2274. // Here I do not use call_user_func() because I need to send a reference to the 
  2275. // header. 
  2276. $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header); 
  2277. if ($v_result == 0) { 
  2278. // ----- Ignored 
  2279. $v_result = 1; 
  2280.  
  2281. // ----- Update the informations 
  2282. // Nothing can be modified 
  2283.  
  2284. // ----- Return 
  2285. return $v_result; 
  2286. // -------------------------------------------------------------------------------- 
  2287.  
  2288. // -------------------------------------------------------------------------------- 
  2289. // Function : privAddFileUsingTempFile() 
  2290. // Description : 
  2291. // Parameters : 
  2292. // Return Values : 
  2293. // -------------------------------------------------------------------------------- 
  2294. function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options) 
  2295. $v_result=PCLZIP_ERR_NO_ERROR; 
  2296.  
  2297. // ----- Working variable 
  2298. $p_filename = $p_filedescr['filename']; 
  2299.  
  2300.  
  2301. // ----- Open the source file 
  2302. if (($v_file = @fopen($p_filename, "rb")) == 0) { 
  2303. PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); 
  2304. return PclZip::errorCode(); 
  2305.  
  2306. // ----- Creates a compressed temporary file 
  2307. $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; 
  2308. if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) { 
  2309. fclose($v_file); 
  2310. PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); 
  2311. return PclZip::errorCode(); 
  2312.  
  2313. // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks 
  2314. $v_size = filesize($p_filename); 
  2315. while ($v_size != 0) { 
  2316. $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 
  2317. $v_buffer = @fread($v_file, $v_read_size); 
  2318. //$v_binary_data = pack('a'.$v_read_size, $v_buffer); 
  2319. @gzputs($v_file_compressed, $v_buffer, $v_read_size); 
  2320. $v_size -= $v_read_size; 
  2321.  
  2322. // ----- Close the file 
  2323. @fclose($v_file); 
  2324. @gzclose($v_file_compressed); 
  2325.  
  2326. // ----- Check the minimum file size 
  2327. if (filesize($v_gzip_temp_name) < 18) { 
  2328. PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes'); 
  2329. return PclZip::errorCode(); 
  2330.  
  2331. // ----- Extract the compressed attributes 
  2332. if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) { 
  2333. PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); 
  2334. return PclZip::errorCode(); 
  2335.  
  2336. // ----- Read the gzip file header 
  2337. $v_binary_data = @fread($v_file_compressed, 10); 
  2338. $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data); 
  2339.  
  2340. // ----- Check some parameters 
  2341. $v_data_header['os'] = bin2hex($v_data_header['os']); 
  2342.  
  2343. // ----- Read the gzip file footer 
  2344. @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8); 
  2345. $v_binary_data = @fread($v_file_compressed, 8); 
  2346. $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data); 
  2347.  
  2348. // ----- Set the attributes 
  2349. $p_header['compression'] = ord($v_data_header['cm']); 
  2350. //$p_header['mtime'] = $v_data_header['mtime']; 
  2351. $p_header['crc'] = $v_data_footer['crc']; 
  2352. $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18; 
  2353.  
  2354. // ----- Close the file 
  2355. @fclose($v_file_compressed); 
  2356.  
  2357. // ----- Call the header generation 
  2358. if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { 
  2359. return $v_result; 
  2360.  
  2361. // ----- Add the compressed data 
  2362. if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) 
  2363. PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); 
  2364. return PclZip::errorCode(); 
  2365.  
  2366. // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks 
  2367. fseek($v_file_compressed, 10); 
  2368. $v_size = $p_header['compressed_size']; 
  2369. while ($v_size != 0) 
  2370. $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 
  2371. $v_buffer = @fread($v_file_compressed, $v_read_size); 
  2372. //$v_binary_data = pack('a'.$v_read_size, $v_buffer); 
  2373. @fwrite($this->zip_fd, $v_buffer, $v_read_size); 
  2374. $v_size -= $v_read_size; 
  2375.  
  2376. // ----- Close the file 
  2377. @fclose($v_file_compressed); 
  2378.  
  2379. // ----- Unlink the temporary file 
  2380. @unlink($v_gzip_temp_name); 
  2381.  
  2382. // ----- Return 
  2383. return $v_result; 
  2384. // -------------------------------------------------------------------------------- 
  2385.  
  2386. // -------------------------------------------------------------------------------- 
  2387. // Function : privCalculateStoredFilename() 
  2388. // Description : 
  2389. // Based on file descriptor properties and global options, this method 
  2390. // calculate the filename that will be stored in the archive. 
  2391. // Parameters : 
  2392. // Return Values : 
  2393. // -------------------------------------------------------------------------------- 
  2394. function privCalculateStoredFilename(&$p_filedescr, &$p_options) 
  2395. $v_result=1; 
  2396.  
  2397. // ----- Working variables 
  2398. $p_filename = $p_filedescr['filename']; 
  2399. if (isset($p_options[PCLZIP_OPT_ADD_PATH])) { 
  2400. $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH]; 
  2401. else { 
  2402. $p_add_dir = ''; 
  2403. if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) { 
  2404. $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH]; 
  2405. else { 
  2406. $p_remove_dir = ''; 
  2407. if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { 
  2408. $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH]; 
  2409. else { 
  2410. $p_remove_all_dir = 0; 
  2411.  
  2412.  
  2413. // ----- Look for full name change 
  2414. if (isset($p_filedescr['new_full_name'])) { 
  2415. // ----- Remove drive letter if any 
  2416. $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']); 
  2417.  
  2418. // ----- Look for path and/or short name change 
  2419. else { 
  2420.  
  2421. // ----- Look for short name change 
  2422. // Its when we cahnge just the filename but not the path 
  2423. if (isset($p_filedescr['new_short_name'])) { 
  2424. $v_path_info = pathinfo($p_filename); 
  2425. $v_dir = ''; 
  2426. if ($v_path_info['dirname'] != '') { 
  2427. $v_dir = $v_path_info['dirname'].'/'; 
  2428. $v_stored_filename = $v_dir.$p_filedescr['new_short_name']; 
  2429. else { 
  2430. // ----- Calculate the stored filename 
  2431. $v_stored_filename = $p_filename; 
  2432.  
  2433. // ----- Look for all path to remove 
  2434. if ($p_remove_all_dir) { 
  2435. $v_stored_filename = basename($p_filename); 
  2436. // ----- Look for partial path remove 
  2437. else if ($p_remove_dir != "") { 
  2438. if (substr($p_remove_dir, -1) != '/') 
  2439. $p_remove_dir .= "/"; 
  2440.  
  2441. if ( (substr($p_filename, 0, 2) == "./") 
  2442. || (substr($p_remove_dir, 0, 2) == "./")) { 
  2443.  
  2444. if ( (substr($p_filename, 0, 2) == "./") 
  2445. && (substr($p_remove_dir, 0, 2) != "./")) { 
  2446. $p_remove_dir = "./".$p_remove_dir; 
  2447. if ( (substr($p_filename, 0, 2) != "./") 
  2448. && (substr($p_remove_dir, 0, 2) == "./")) { 
  2449. $p_remove_dir = substr($p_remove_dir, 2); 
  2450.  
  2451. $v_compare = PclZipUtilPathInclusion($p_remove_dir,  
  2452. $v_stored_filename); 
  2453. if ($v_compare > 0) { 
  2454. if ($v_compare == 2) { 
  2455. $v_stored_filename = ""; 
  2456. else { 
  2457. $v_stored_filename = substr($v_stored_filename,  
  2458. strlen($p_remove_dir)); 
  2459.  
  2460. // ----- Remove drive letter if any 
  2461. $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename); 
  2462.  
  2463. // ----- Look for path to add 
  2464. if ($p_add_dir != "") { 
  2465. if (substr($p_add_dir, -1) == "/") 
  2466. $v_stored_filename = $p_add_dir.$v_stored_filename; 
  2467. else 
  2468. $v_stored_filename = $p_add_dir."/".$v_stored_filename; 
  2469.  
  2470. // ----- Filename (reduce the path of stored name) 
  2471. $v_stored_filename = PclZipUtilPathReduction($v_stored_filename); 
  2472. $p_filedescr['stored_filename'] = $v_stored_filename; 
  2473.  
  2474. // ----- Return 
  2475. return $v_result; 
  2476. // -------------------------------------------------------------------------------- 
  2477.  
  2478. // -------------------------------------------------------------------------------- 
  2479. // Function : privWriteFileHeader() 
  2480. // Description : 
  2481. // Parameters : 
  2482. // Return Values : 
  2483. // -------------------------------------------------------------------------------- 
  2484. function privWriteFileHeader(&$p_header) 
  2485. $v_result=1; 
  2486.  
  2487. // ----- Store the offset position of the file 
  2488. $p_header['offset'] = ftell($this->zip_fd); 
  2489.  
  2490. // ----- Transform UNIX mtime to DOS format mdate/mtime 
  2491. $v_date = getdate($p_header['mtime']); 
  2492. $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; 
  2493. $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; 
  2494.  
  2495. // ----- Packed data 
  2496. $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,  
  2497. $p_header['version_extracted'], $p_header['flag'],  
  2498. $p_header['compression'], $v_mtime, $v_mdate,  
  2499. $p_header['crc'], $p_header['compressed_size'],  
  2500. $p_header['size'],  
  2501. strlen($p_header['stored_filename']),  
  2502. $p_header['extra_len']); 
  2503.  
  2504. // ----- Write the first 148 bytes of the header in the archive 
  2505. fputs($this->zip_fd, $v_binary_data, 30); 
  2506.  
  2507. // ----- Write the variable fields 
  2508. if (strlen($p_header['stored_filename']) != 0) 
  2509. fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); 
  2510. if ($p_header['extra_len'] != 0) 
  2511. fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); 
  2512.  
  2513. // ----- Return 
  2514. return $v_result; 
  2515. // -------------------------------------------------------------------------------- 
  2516.  
  2517. // -------------------------------------------------------------------------------- 
  2518. // Function : privWriteCentralFileHeader() 
  2519. // Description : 
  2520. // Parameters : 
  2521. // Return Values : 
  2522. // -------------------------------------------------------------------------------- 
  2523. function privWriteCentralFileHeader(&$p_header) 
  2524. $v_result=1; 
  2525.  
  2526. // TBC 
  2527. //for(reset($p_header); $key = key($p_header); next($p_header)) { 
  2528. //} 
  2529.  
  2530. // ----- Transform UNIX mtime to DOS format mdate/mtime 
  2531. $v_date = getdate($p_header['mtime']); 
  2532. $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; 
  2533. $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; 
  2534.  
  2535.  
  2536. // ----- Packed data 
  2537. $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,  
  2538. $p_header['version'], $p_header['version_extracted'],  
  2539. $p_header['flag'], $p_header['compression'],  
  2540. $v_mtime, $v_mdate, $p_header['crc'],  
  2541. $p_header['compressed_size'], $p_header['size'],  
  2542. strlen($p_header['stored_filename']),  
  2543. $p_header['extra_len'], $p_header['comment_len'],  
  2544. $p_header['disk'], $p_header['internal'],  
  2545. $p_header['external'], $p_header['offset']); 
  2546.  
  2547. // ----- Write the 42 bytes of the header in the zip file 
  2548. fputs($this->zip_fd, $v_binary_data, 46); 
  2549.  
  2550. // ----- Write the variable fields 
  2551. if (strlen($p_header['stored_filename']) != 0) 
  2552. fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); 
  2553. if ($p_header['extra_len'] != 0) 
  2554. fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); 
  2555. if ($p_header['comment_len'] != 0) 
  2556. fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']); 
  2557.  
  2558. // ----- Return 
  2559. return $v_result; 
  2560. // -------------------------------------------------------------------------------- 
  2561.  
  2562. // -------------------------------------------------------------------------------- 
  2563. // Function : privWriteCentralHeader() 
  2564. // Description : 
  2565. // Parameters : 
  2566. // Return Values : 
  2567. // -------------------------------------------------------------------------------- 
  2568. function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) 
  2569. $v_result=1; 
  2570.  
  2571. // ----- Packed data 
  2572. $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,  
  2573. $p_nb_entries, $p_size,  
  2574. $p_offset, strlen($p_comment)); 
  2575.  
  2576. // ----- Write the 22 bytes of the header in the zip file 
  2577. fputs($this->zip_fd, $v_binary_data, 22); 
  2578.  
  2579. // ----- Write the variable fields 
  2580. if (strlen($p_comment) != 0) 
  2581. fputs($this->zip_fd, $p_comment, strlen($p_comment)); 
  2582.  
  2583. // ----- Return 
  2584. return $v_result; 
  2585. // -------------------------------------------------------------------------------- 
  2586.  
  2587. // -------------------------------------------------------------------------------- 
  2588. // Function : privList() 
  2589. // Description : 
  2590. // Parameters : 
  2591. // Return Values : 
  2592. // -------------------------------------------------------------------------------- 
  2593. function privList(&$p_list) 
  2594. $v_result=1; 
  2595.  
  2596. // ----- Magic quotes trick 
  2597. $this->privDisableMagicQuotes(); 
  2598.  
  2599. // ----- Open the zip file 
  2600. if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) 
  2601. // ----- Magic quotes trick 
  2602. $this->privSwapBackMagicQuotes(); 
  2603.  
  2604. // ----- Error log 
  2605. PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); 
  2606.  
  2607. // ----- Return 
  2608. return PclZip::errorCode(); 
  2609.  
  2610. // ----- Read the central directory informations 
  2611. $v_central_dir = array(); 
  2612. if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) 
  2613. $this->privSwapBackMagicQuotes(); 
  2614. return $v_result; 
  2615.  
  2616. // ----- Go to beginning of Central Dir 
  2617. @rewind($this->zip_fd); 
  2618. if (@fseek($this->zip_fd, $v_central_dir['offset'])) 
  2619. $this->privSwapBackMagicQuotes(); 
  2620.  
  2621. // ----- Error log 
  2622. PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); 
  2623.  
  2624. // ----- Return 
  2625. return PclZip::errorCode(); 
  2626.  
  2627. // ----- Read each entry 
  2628. for ($i=0; $i<$v_central_dir['entries']; $i++) 
  2629. // ----- Read the file header 
  2630. if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) 
  2631. $this->privSwapBackMagicQuotes(); 
  2632. return $v_result; 
  2633. $v_header['index'] = $i; 
  2634.  
  2635. // ----- Get the only interesting attributes 
  2636. $this->privConvertHeader2FileInfo($v_header, $p_list[$i]); 
  2637. unset($v_header); 
  2638.  
  2639. // ----- Close the zip file 
  2640. $this->privCloseFd(); 
  2641.  
  2642. // ----- Magic quotes trick 
  2643. $this->privSwapBackMagicQuotes(); 
  2644.  
  2645. // ----- Return 
  2646. return $v_result; 
  2647. // -------------------------------------------------------------------------------- 
  2648.  
  2649. // -------------------------------------------------------------------------------- 
  2650. // Function : privConvertHeader2FileInfo() 
  2651. // Description : 
  2652. // This function takes the file informations from the central directory 
  2653. // entries and extract the interesting parameters that will be given back. 
  2654. // The resulting file infos are set in the array $p_info 
  2655. // $p_info['filename'] : Filename with full path. Given by user (add),  
  2656. // extracted in the filesystem (extract). 
  2657. // $p_info['stored_filename'] : Stored filename in the archive. 
  2658. // $p_info['size'] = Size of the file. 
  2659. // $p_info['compressed_size'] = Compressed size of the file. 
  2660. // $p_info['mtime'] = Last modification date of the file. 
  2661. // $p_info['comment'] = Comment associated with the file. 
  2662. // $p_info['folder'] = true/false : indicates if the entry is a folder or not. 
  2663. // $p_info['status'] = status of the action on the file. 
  2664. // $p_info['crc'] = CRC of the file content. 
  2665. // Parameters : 
  2666. // Return Values : 
  2667. // -------------------------------------------------------------------------------- 
  2668. function privConvertHeader2FileInfo($p_header, &$p_info) 
  2669. $v_result=1; 
  2670.  
  2671. // ----- Get the interesting attributes 
  2672. $v_temp_path = PclZipUtilPathReduction($p_header['filename']); 
  2673. $p_info['filename'] = $v_temp_path; 
  2674. $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']); 
  2675. $p_info['stored_filename'] = $v_temp_path; 
  2676. $p_info['size'] = $p_header['size']; 
  2677. $p_info['compressed_size'] = $p_header['compressed_size']; 
  2678. $p_info['mtime'] = $p_header['mtime']; 
  2679. $p_info['comment'] = $p_header['comment']; 
  2680. $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010); 
  2681. $p_info['index'] = $p_header['index']; 
  2682. $p_info['status'] = $p_header['status']; 
  2683. $p_info['crc'] = $p_header['crc']; 
  2684.  
  2685. // ----- Return 
  2686. return $v_result; 
  2687. // -------------------------------------------------------------------------------- 
  2688.  
  2689. // -------------------------------------------------------------------------------- 
  2690. // Function : privExtractByRule() 
  2691. // Description : 
  2692. // Extract a file or directory depending of rules (by index, by name, ...) 
  2693. // Parameters : 
  2694. // $p_file_list : An array where will be placed the properties of each 
  2695. // extracted file 
  2696. // $p_path : Path to add while writing the extracted files 
  2697. // $p_remove_path : Path to remove (from the file memorized path) while writing the 
  2698. // extracted files. If the path does not match the file path,  
  2699. // the file is extracted with its memorized path. 
  2700. // $p_remove_path does not apply to 'list' mode. 
  2701. // $p_path and $p_remove_path are commulative. 
  2702. // Return Values : 
  2703. // 1 on success, 0 or less on error (see error code list) 
  2704. // -------------------------------------------------------------------------------- 
  2705. function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) 
  2706. $v_result=1; 
  2707.  
  2708. // ----- Magic quotes trick 
  2709. $this->privDisableMagicQuotes(); 
  2710.  
  2711. // ----- Check the path 
  2712. if ( ($p_path == "") 
  2713. || ( (substr($p_path, 0, 1) != "/") 
  2714. && (substr($p_path, 0, 3) != "../") 
  2715. && (substr($p_path, 1, 2)!=":/"))) 
  2716. $p_path = "./".$p_path; 
  2717.  
  2718. // ----- Reduce the path last (and duplicated) '/' 
  2719. if (($p_path != "./") && ($p_path != "/")) 
  2720. // ----- Look for the path end '/' 
  2721. while (substr($p_path, -1) == "/") 
  2722. $p_path = substr($p_path, 0, strlen($p_path)-1); 
  2723.  
  2724. // ----- Look for path to remove format (should end by /) 
  2725. if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) 
  2726. $p_remove_path .= '/'; 
  2727. $p_remove_path_size = strlen($p_remove_path); 
  2728.  
  2729. // ----- Open the zip file 
  2730. if (($v_result = $this->privOpenFd('rb')) != 1) 
  2731. $this->privSwapBackMagicQuotes(); 
  2732. return $v_result; 
  2733.  
  2734. // ----- Read the central directory informations 
  2735. $v_central_dir = array(); 
  2736. if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) 
  2737. // ----- Close the zip file 
  2738. $this->privCloseFd(); 
  2739. $this->privSwapBackMagicQuotes(); 
  2740.  
  2741. return $v_result; 
  2742.  
  2743. // ----- Start at beginning of Central Dir 
  2744. $v_pos_entry = $v_central_dir['offset']; 
  2745.  
  2746. // ----- Read each entry 
  2747. $j_start = 0; 
  2748. for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) 
  2749.  
  2750. // ----- Read next Central dir entry 
  2751. @rewind($this->zip_fd); 
  2752. if (@fseek($this->zip_fd, $v_pos_entry)) 
  2753. // ----- Close the zip file 
  2754. $this->privCloseFd(); 
  2755. $this->privSwapBackMagicQuotes(); 
  2756.  
  2757. // ----- Error log 
  2758. PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); 
  2759.  
  2760. // ----- Return 
  2761. return PclZip::errorCode(); 
  2762.  
  2763. // ----- Read the file header 
  2764. $v_header = array(); 
  2765. if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) 
  2766. // ----- Close the zip file 
  2767. $this->privCloseFd(); 
  2768. $this->privSwapBackMagicQuotes(); 
  2769.  
  2770. return $v_result; 
  2771.  
  2772. // ----- Store the index 
  2773. $v_header['index'] = $i; 
  2774.  
  2775. // ----- Store the file position 
  2776. $v_pos_entry = ftell($this->zip_fd); 
  2777.  
  2778. // ----- Look for the specific extract rules 
  2779. $v_extract = false; 
  2780.  
  2781. // ----- Look for extract by name rule 
  2782. if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) 
  2783. && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { 
  2784.  
  2785. // ----- Look if the filename is in the list 
  2786. for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) { 
  2787.  
  2788. // ----- Look for a directory 
  2789. if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { 
  2790.  
  2791. // ----- Look if the directory is in the filename path 
  2792. if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) 
  2793. && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { 
  2794. $v_extract = true; 
  2795. // ----- Look for a filename 
  2796. elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { 
  2797. $v_extract = true; 
  2798.  
  2799. // ----- Look for extract by ereg rule 
  2800. // ereg() is deprecated with PHP 5.3 
  2801. /** 
  2802. else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) 
  2803. && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { 
  2804.   
  2805. if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) { 
  2806. $v_extract = true; 
  2807. */ 
  2808.  
  2809. // ----- Look for extract by preg rule 
  2810. else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) 
  2811. && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { 
  2812.  
  2813. if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) { 
  2814. $v_extract = true; 
  2815.  
  2816. // ----- Look for extract by index rule 
  2817. else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) 
  2818. && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { 
  2819.  
  2820. // ----- Look if the index is in the list 
  2821. for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) { 
  2822.  
  2823. if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { 
  2824. $v_extract = true; 
  2825. if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { 
  2826. $j_start = $j+1; 
  2827.  
  2828. if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { 
  2829. break; 
  2830.  
  2831. // ----- Look for no rule, which means extract all the archive 
  2832. else { 
  2833. $v_extract = true; 
  2834.  
  2835. // ----- Check compression method 
  2836. if ( ($v_extract) 
  2837. && ( ($v_header['compression'] != 8) 
  2838. && ($v_header['compression'] != 0))) { 
  2839. $v_header['status'] = 'unsupported_compression'; 
  2840.  
  2841. // ----- Look for PCLZIP_OPT_STOP_ON_ERROR 
  2842. if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) 
  2843. && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { 
  2844.  
  2845. $this->privSwapBackMagicQuotes(); 
  2846.  
  2847. PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,  
  2848. "Filename '".$v_header['stored_filename']."' is " 
  2849. ."compressed by an unsupported compression " 
  2850. ."method (".$v_header['compression'].") "); 
  2851.  
  2852. return PclZip::errorCode(); 
  2853.  
  2854. // ----- Check encrypted files 
  2855. if (($v_extract) && (($v_header['flag'] & 1) == 1)) { 
  2856. $v_header['status'] = 'unsupported_encryption'; 
  2857.  
  2858. // ----- Look for PCLZIP_OPT_STOP_ON_ERROR 
  2859. if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) 
  2860. && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { 
  2861.  
  2862. $this->privSwapBackMagicQuotes(); 
  2863.  
  2864. PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,  
  2865. "Unsupported encryption for " 
  2866. ." filename '".$v_header['stored_filename'] 
  2867. ."'"); 
  2868.  
  2869. return PclZip::errorCode(); 
  2870.  
  2871. // ----- Look for real extraction 
  2872. if (($v_extract) && ($v_header['status'] != 'ok')) { 
  2873. $v_result = $this->privConvertHeader2FileInfo($v_header,  
  2874. $p_file_list[$v_nb_extracted++]); 
  2875. if ($v_result != 1) { 
  2876. $this->privCloseFd(); 
  2877. $this->privSwapBackMagicQuotes(); 
  2878. return $v_result; 
  2879.  
  2880. $v_extract = false; 
  2881.  
  2882. // ----- Look for real extraction 
  2883. if ($v_extract) 
  2884.  
  2885. // ----- Go to the file position 
  2886. @rewind($this->zip_fd); 
  2887. if (@fseek($this->zip_fd, $v_header['offset'])) 
  2888. // ----- Close the zip file 
  2889. $this->privCloseFd(); 
  2890.  
  2891. $this->privSwapBackMagicQuotes(); 
  2892.  
  2893. // ----- Error log 
  2894. PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); 
  2895.  
  2896. // ----- Return 
  2897. return PclZip::errorCode(); 
  2898.  
  2899. // ----- Look for extraction as string 
  2900. if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) { 
  2901.  
  2902. $v_string = ''; 
  2903.  
  2904. // ----- Extracting the file 
  2905. $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options); 
  2906. if ($v_result1 < 1) { 
  2907. $this->privCloseFd(); 
  2908. $this->privSwapBackMagicQuotes(); 
  2909. return $v_result1; 
  2910.  
  2911. // ----- Get the only interesting attributes 
  2912. if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) 
  2913. // ----- Close the zip file 
  2914. $this->privCloseFd(); 
  2915. $this->privSwapBackMagicQuotes(); 
  2916.  
  2917. return $v_result; 
  2918.  
  2919. // ----- Set the file content 
  2920. $p_file_list[$v_nb_extracted]['content'] = $v_string; 
  2921.  
  2922. // ----- Next extracted file 
  2923. $v_nb_extracted++; 
  2924.  
  2925. // ----- Look for user callback abort 
  2926. if ($v_result1 == 2) { 
  2927. break; 
  2928. // ----- Look for extraction in standard output 
  2929. elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) 
  2930. && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) { 
  2931. // ----- Extracting the file in standard output 
  2932. $v_result1 = $this->privExtractFileInOutput($v_header, $p_options); 
  2933. if ($v_result1 < 1) { 
  2934. $this->privCloseFd(); 
  2935. $this->privSwapBackMagicQuotes(); 
  2936. return $v_result1; 
  2937.  
  2938. // ----- Get the only interesting attributes 
  2939. if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { 
  2940. $this->privCloseFd(); 
  2941. $this->privSwapBackMagicQuotes(); 
  2942. return $v_result; 
  2943.  
  2944. // ----- Look for user callback abort 
  2945. if ($v_result1 == 2) { 
  2946. break; 
  2947. // ----- Look for normal extraction 
  2948. else { 
  2949. // ----- Extracting the file 
  2950. $v_result1 = $this->privExtractFile($v_header,  
  2951. $p_path, $p_remove_path,  
  2952. $p_remove_all_path,  
  2953. $p_options); 
  2954. if ($v_result1 < 1) { 
  2955. $this->privCloseFd(); 
  2956. $this->privSwapBackMagicQuotes(); 
  2957. return $v_result1; 
  2958.  
  2959. // ----- Get the only interesting attributes 
  2960. if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) 
  2961. // ----- Close the zip file 
  2962. $this->privCloseFd(); 
  2963. $this->privSwapBackMagicQuotes(); 
  2964.  
  2965. return $v_result; 
  2966.  
  2967. // ----- Look for user callback abort 
  2968. if ($v_result1 == 2) { 
  2969. break; 
  2970.  
  2971. // ----- Close the zip file 
  2972. $this->privCloseFd(); 
  2973. $this->privSwapBackMagicQuotes(); 
  2974.  
  2975. // ----- Return 
  2976. return $v_result; 
  2977. // -------------------------------------------------------------------------------- 
  2978.  
  2979. // -------------------------------------------------------------------------------- 
  2980. // Function : privExtractFile() 
  2981. // Description : 
  2982. // Parameters : 
  2983. // Return Values : 
  2984. // 
  2985. // 1 : ... ? 
  2986. // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback 
  2987. // -------------------------------------------------------------------------------- 
  2988. function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) 
  2989. $v_result=1; 
  2990.  
  2991. // ----- Read the file header 
  2992. if (($v_result = $this->privReadFileHeader($v_header)) != 1) 
  2993. // ----- Return 
  2994. return $v_result; 
  2995.  
  2996.  
  2997. // ----- Check that the file header is coherent with $p_entry info 
  2998. if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { 
  2999. // TBC 
  3000.  
  3001. // ----- Look for all path to remove 
  3002. if ($p_remove_all_path == true) { 
  3003. // ----- Look for folder entry that not need to be extracted 
  3004. if (($p_entry['external']&0x00000010)==0x00000010) { 
  3005.  
  3006. $p_entry['status'] = "filtered"; 
  3007.  
  3008. return $v_result; 
  3009.  
  3010. // ----- Get the basename of the path 
  3011. $p_entry['filename'] = basename($p_entry['filename']); 
  3012.  
  3013. // ----- Look for path to remove 
  3014. else if ($p_remove_path != "") 
  3015. if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2) 
  3016.  
  3017. // ----- Change the file status 
  3018. $p_entry['status'] = "filtered"; 
  3019.  
  3020. // ----- Return 
  3021. return $v_result; 
  3022.  
  3023. $p_remove_path_size = strlen($p_remove_path); 
  3024. if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) 
  3025.  
  3026. // ----- Remove the path 
  3027. $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size); 
  3028.  
  3029.  
  3030. // ----- Add the path 
  3031. if ($p_path != '') { 
  3032. $p_entry['filename'] = $p_path."/".$p_entry['filename']; 
  3033.  
  3034. // ----- Check a base_dir_restriction 
  3035. if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) { 
  3036. $v_inclusion 
  3037. = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION],  
  3038. $p_entry['filename']); 
  3039. if ($v_inclusion == 0) { 
  3040.  
  3041. PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,  
  3042. "Filename '".$p_entry['filename']."' is " 
  3043. ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"); 
  3044.  
  3045. return PclZip::errorCode(); 
  3046.  
  3047. // ----- Look for pre-extract callback 
  3048. if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { 
  3049.  
  3050. // ----- Generate a local information 
  3051. $v_local_header = array(); 
  3052. $this->privConvertHeader2FileInfo($p_entry, $v_local_header); 
  3053.  
  3054. // ----- Call the callback 
  3055. // Here I do not use call_user_func() because I need to send a reference to the 
  3056. // header. 
  3057. $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); 
  3058. if ($v_result == 0) { 
  3059. // ----- Change the file status 
  3060. $p_entry['status'] = "skipped"; 
  3061. $v_result = 1; 
  3062.  
  3063. // ----- Look for abort result 
  3064. if ($v_result == 2) { 
  3065. // ----- This status is internal and will be changed in 'skipped' 
  3066. $p_entry['status'] = "aborted"; 
  3067. $v_result = PCLZIP_ERR_USER_ABORTED; 
  3068.  
  3069. // ----- Update the informations 
  3070. // Only some fields can be modified 
  3071. $p_entry['filename'] = $v_local_header['filename']; 
  3072.  
  3073.  
  3074. // ----- Look if extraction should be done 
  3075. if ($p_entry['status'] == 'ok') { 
  3076.  
  3077. // ----- Look for specific actions while the file exist 
  3078. if (file_exists($p_entry['filename'])) 
  3079.  
  3080. // ----- Look if file is a directory 
  3081. if (is_dir($p_entry['filename'])) 
  3082.  
  3083. // ----- Change the file status 
  3084. $p_entry['status'] = "already_a_directory"; 
  3085.  
  3086. // ----- Look for PCLZIP_OPT_STOP_ON_ERROR 
  3087. // For historical reason first PclZip implementation does not stop 
  3088. // when this kind of error occurs. 
  3089. if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) 
  3090. && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { 
  3091.  
  3092. PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY,  
  3093. "Filename '".$p_entry['filename']."' is " 
  3094. ."already used by an existing directory"); 
  3095.  
  3096. return PclZip::errorCode(); 
  3097. // ----- Look if file is write protected 
  3098. else if (!is_writeable($p_entry['filename'])) 
  3099.  
  3100. // ----- Change the file status 
  3101. $p_entry['status'] = "write_protected"; 
  3102.  
  3103. // ----- Look for PCLZIP_OPT_STOP_ON_ERROR 
  3104. // For historical reason first PclZip implementation does not stop 
  3105. // when this kind of error occurs. 
  3106. if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) 
  3107. && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { 
  3108.  
  3109. PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,  
  3110. "Filename '".$p_entry['filename']."' exists " 
  3111. ."and is write protected"); 
  3112.  
  3113. return PclZip::errorCode(); 
  3114.  
  3115. // ----- Look if the extracted file is older 
  3116. else if (filemtime($p_entry['filename']) > $p_entry['mtime']) 
  3117. // ----- Change the file status 
  3118. if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER])) 
  3119. && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) { 
  3120. else { 
  3121. $p_entry['status'] = "newer_exist"; 
  3122.  
  3123. // ----- Look for PCLZIP_OPT_STOP_ON_ERROR 
  3124. // For historical reason first PclZip implementation does not stop 
  3125. // when this kind of error occurs. 
  3126. if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) 
  3127. && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { 
  3128.  
  3129. PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,  
  3130. "Newer version of '".$p_entry['filename']."' exists " 
  3131. ."and option PCLZIP_OPT_REPLACE_NEWER is not selected"); 
  3132.  
  3133. return PclZip::errorCode(); 
  3134. else { 
  3135.  
  3136. // ----- Check the directory availability and create it if necessary 
  3137. else { 
  3138. if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/')) 
  3139. $v_dir_to_check = $p_entry['filename']; 
  3140. else if (!strstr($p_entry['filename'], "/")) 
  3141. $v_dir_to_check = ""; 
  3142. else 
  3143. $v_dir_to_check = dirname($p_entry['filename']); 
  3144.  
  3145. if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) { 
  3146.  
  3147. // ----- Change the file status 
  3148. $p_entry['status'] = "path_creation_fail"; 
  3149.  
  3150. // ----- Return 
  3151. //return $v_result; 
  3152. $v_result = 1; 
  3153.  
  3154. // ----- Look if extraction should be done 
  3155. if ($p_entry['status'] == 'ok') { 
  3156.  
  3157. // ----- Do the extraction (if not a folder) 
  3158. if (!(($p_entry['external']&0x00000010)==0x00000010)) 
  3159. // ----- Look for not compressed file 
  3160. if ($p_entry['compression'] == 0) { 
  3161.  
  3162. // ----- Opening destination file 
  3163. if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) 
  3164.  
  3165. // ----- Change the file status 
  3166. $p_entry['status'] = "write_error"; 
  3167.  
  3168. // ----- Return 
  3169. return $v_result; 
  3170.  
  3171.  
  3172. // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks 
  3173. $v_size = $p_entry['compressed_size']; 
  3174. while ($v_size != 0) 
  3175. $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 
  3176. $v_buffer = @fread($this->zip_fd, $v_read_size); 
  3177. /** Try to speed up the code 
  3178. $v_binary_data = pack('a'.$v_read_size, $v_buffer); 
  3179. @fwrite($v_dest_file, $v_binary_data, $v_read_size); 
  3180. */ 
  3181. @fwrite($v_dest_file, $v_buffer, $v_read_size); 
  3182. $v_size -= $v_read_size; 
  3183.  
  3184. // ----- Closing the destination file 
  3185. fclose($v_dest_file); 
  3186.  
  3187. // ----- Change the file mtime 
  3188. touch($p_entry['filename'], $p_entry['mtime']); 
  3189.  
  3190.  
  3191. else { 
  3192. // ----- TBC 
  3193. // Need to be finished 
  3194. if (($p_entry['flag'] & 1) == 1) { 
  3195. PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.'); 
  3196. return PclZip::errorCode(); 
  3197.  
  3198.  
  3199. // ----- Look for using temporary file to unzip 
  3200. if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) 
  3201. && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) 
  3202. || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) 
  3203. && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) { 
  3204. $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options); 
  3205. if ($v_result < PCLZIP_ERR_NO_ERROR) { 
  3206. return $v_result; 
  3207.  
  3208. // ----- Look for extract in memory 
  3209. else { 
  3210.  
  3211.  
  3212. // ----- Read the compressed file in a buffer (one shot) 
  3213. $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); 
  3214.  
  3215. // ----- Decompress the file 
  3216. $v_file_content = @gzinflate($v_buffer); 
  3217. unset($v_buffer); 
  3218. if ($v_file_content === FALSE) { 
  3219.  
  3220. // ----- Change the file status 
  3221. // TBC 
  3222. $p_entry['status'] = "error"; 
  3223.  
  3224. return $v_result; 
  3225.  
  3226. // ----- Opening destination file 
  3227. if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { 
  3228.  
  3229. // ----- Change the file status 
  3230. $p_entry['status'] = "write_error"; 
  3231.  
  3232. return $v_result; 
  3233.  
  3234. // ----- Write the uncompressed data 
  3235. @fwrite($v_dest_file, $v_file_content, $p_entry['size']); 
  3236. unset($v_file_content); 
  3237.  
  3238. // ----- Closing the destination file 
  3239. @fclose($v_dest_file); 
  3240.  
  3241.  
  3242. // ----- Change the file mtime 
  3243. @touch($p_entry['filename'], $p_entry['mtime']); 
  3244.  
  3245. // ----- Look for chmod option 
  3246. if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) { 
  3247.  
  3248. // ----- Change the mode of the file 
  3249. @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]); 
  3250.  
  3251.  
  3252. // ----- Change abort status 
  3253. if ($p_entry['status'] == "aborted") { 
  3254. $p_entry['status'] = "skipped"; 
  3255.  
  3256. // ----- Look for post-extract callback 
  3257. elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { 
  3258.  
  3259. // ----- Generate a local information 
  3260. $v_local_header = array(); 
  3261. $this->privConvertHeader2FileInfo($p_entry, $v_local_header); 
  3262.  
  3263. // ----- Call the callback 
  3264. // Here I do not use call_user_func() because I need to send a reference to the 
  3265. // header. 
  3266. $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); 
  3267.  
  3268. // ----- Look for abort result 
  3269. if ($v_result == 2) { 
  3270. $v_result = PCLZIP_ERR_USER_ABORTED; 
  3271.  
  3272. // ----- Return 
  3273. return $v_result; 
  3274. // -------------------------------------------------------------------------------- 
  3275.  
  3276. // -------------------------------------------------------------------------------- 
  3277. // Function : privExtractFileUsingTempFile() 
  3278. // Description : 
  3279. // Parameters : 
  3280. // Return Values : 
  3281. // -------------------------------------------------------------------------------- 
  3282. function privExtractFileUsingTempFile(&$p_entry, &$p_options) 
  3283. $v_result=1; 
  3284.  
  3285. // ----- Creates a temporary file 
  3286. $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; 
  3287. if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) { 
  3288. fclose($v_file); 
  3289. PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); 
  3290. return PclZip::errorCode(); 
  3291.  
  3292.  
  3293. // ----- Write gz file format header 
  3294. $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3)); 
  3295. @fwrite($v_dest_file, $v_binary_data, 10); 
  3296.  
  3297. // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks 
  3298. $v_size = $p_entry['compressed_size']; 
  3299. while ($v_size != 0) 
  3300. $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 
  3301. $v_buffer = @fread($this->zip_fd, $v_read_size); 
  3302. //$v_binary_data = pack('a'.$v_read_size, $v_buffer); 
  3303. @fwrite($v_dest_file, $v_buffer, $v_read_size); 
  3304. $v_size -= $v_read_size; 
  3305.  
  3306. // ----- Write gz file format footer 
  3307. $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']); 
  3308. @fwrite($v_dest_file, $v_binary_data, 8); 
  3309.  
  3310. // ----- Close the temporary file 
  3311. @fclose($v_dest_file); 
  3312.  
  3313. // ----- Opening destination file 
  3314. if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { 
  3315. $p_entry['status'] = "write_error"; 
  3316. return $v_result; 
  3317.  
  3318. // ----- Open the temporary gz file 
  3319. if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) { 
  3320. @fclose($v_dest_file); 
  3321. $p_entry['status'] = "read_error"; 
  3322. PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); 
  3323. return PclZip::errorCode(); 
  3324.  
  3325.  
  3326. // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks 
  3327. $v_size = $p_entry['size']; 
  3328. while ($v_size != 0) { 
  3329. $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 
  3330. $v_buffer = @gzread($v_src_file, $v_read_size); 
  3331. //$v_binary_data = pack('a'.$v_read_size, $v_buffer); 
  3332. @fwrite($v_dest_file, $v_buffer, $v_read_size); 
  3333. $v_size -= $v_read_size; 
  3334. @fclose($v_dest_file); 
  3335. @gzclose($v_src_file); 
  3336.  
  3337. // ----- Delete the temporary file 
  3338. @unlink($v_gzip_temp_name); 
  3339.  
  3340. // ----- Return 
  3341. return $v_result; 
  3342. // -------------------------------------------------------------------------------- 
  3343.  
  3344. // -------------------------------------------------------------------------------- 
  3345. // Function : privExtractFileInOutput() 
  3346. // Description : 
  3347. // Parameters : 
  3348. // Return Values : 
  3349. // -------------------------------------------------------------------------------- 
  3350. function privExtractFileInOutput(&$p_entry, &$p_options) 
  3351. $v_result=1; 
  3352.  
  3353. // ----- Read the file header 
  3354. if (($v_result = $this->privReadFileHeader($v_header)) != 1) { 
  3355. return $v_result; 
  3356.  
  3357.  
  3358. // ----- Check that the file header is coherent with $p_entry info 
  3359. if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { 
  3360. // TBC 
  3361.  
  3362. // ----- Look for pre-extract callback 
  3363. if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { 
  3364.  
  3365. // ----- Generate a local information 
  3366. $v_local_header = array(); 
  3367. $this->privConvertHeader2FileInfo($p_entry, $v_local_header); 
  3368.  
  3369. // ----- Call the callback 
  3370. // Here I do not use call_user_func() because I need to send a reference to the 
  3371. // header. 
  3372. // eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); 
  3373. $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); 
  3374. if ($v_result == 0) { 
  3375. // ----- Change the file status 
  3376. $p_entry['status'] = "skipped"; 
  3377. $v_result = 1; 
  3378.  
  3379. // ----- Look for abort result 
  3380. if ($v_result == 2) { 
  3381. // ----- This status is internal and will be changed in 'skipped' 
  3382. $p_entry['status'] = "aborted"; 
  3383. $v_result = PCLZIP_ERR_USER_ABORTED; 
  3384.  
  3385. // ----- Update the informations 
  3386. // Only some fields can be modified 
  3387. $p_entry['filename'] = $v_local_header['filename']; 
  3388.  
  3389. // ----- Trace 
  3390.  
  3391. // ----- Look if extraction should be done 
  3392. if ($p_entry['status'] == 'ok') { 
  3393.  
  3394. // ----- Do the extraction (if not a folder) 
  3395. if (!(($p_entry['external']&0x00000010)==0x00000010)) { 
  3396. // ----- Look for not compressed file 
  3397. if ($p_entry['compressed_size'] == $p_entry['size']) { 
  3398.  
  3399. // ----- Read the file in a buffer (one shot) 
  3400. $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); 
  3401.  
  3402. // ----- Send the file to the output 
  3403. echo $v_buffer; 
  3404. unset($v_buffer); 
  3405. else { 
  3406.  
  3407. // ----- Read the compressed file in a buffer (one shot) 
  3408. $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); 
  3409.  
  3410. // ----- Decompress the file 
  3411. $v_file_content = gzinflate($v_buffer); 
  3412. unset($v_buffer); 
  3413.  
  3414. // ----- Send the file to the output 
  3415. echo $v_file_content; 
  3416. unset($v_file_content); 
  3417.  
  3418. // ----- Change abort status 
  3419. if ($p_entry['status'] == "aborted") { 
  3420. $p_entry['status'] = "skipped"; 
  3421.  
  3422. // ----- Look for post-extract callback 
  3423. elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { 
  3424.  
  3425. // ----- Generate a local information 
  3426. $v_local_header = array(); 
  3427. $this->privConvertHeader2FileInfo($p_entry, $v_local_header); 
  3428.  
  3429. // ----- Call the callback 
  3430. // Here I do not use call_user_func() because I need to send a reference to the 
  3431. // header. 
  3432. $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); 
  3433.  
  3434. // ----- Look for abort result 
  3435. if ($v_result == 2) { 
  3436. $v_result = PCLZIP_ERR_USER_ABORTED; 
  3437.  
  3438. return $v_result; 
  3439. // -------------------------------------------------------------------------------- 
  3440.  
  3441. // -------------------------------------------------------------------------------- 
  3442. // Function : privExtractFileAsString() 
  3443. // Description : 
  3444. // Parameters : 
  3445. // Return Values : 
  3446. // -------------------------------------------------------------------------------- 
  3447. function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) 
  3448. $v_result=1; 
  3449.  
  3450. // ----- Read the file header 
  3451. $v_header = array(); 
  3452. if (($v_result = $this->privReadFileHeader($v_header)) != 1) 
  3453. // ----- Return 
  3454. return $v_result; 
  3455.  
  3456.  
  3457. // ----- Check that the file header is coherent with $p_entry info 
  3458. if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { 
  3459. // TBC 
  3460.  
  3461. // ----- Look for pre-extract callback 
  3462. if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { 
  3463.  
  3464. // ----- Generate a local information 
  3465. $v_local_header = array(); 
  3466. $this->privConvertHeader2FileInfo($p_entry, $v_local_header); 
  3467.  
  3468. // ----- Call the callback 
  3469. // Here I do not use call_user_func() because I need to send a reference to the 
  3470. // header. 
  3471. $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); 
  3472. if ($v_result == 0) { 
  3473. // ----- Change the file status 
  3474. $p_entry['status'] = "skipped"; 
  3475. $v_result = 1; 
  3476.  
  3477. // ----- Look for abort result 
  3478. if ($v_result == 2) { 
  3479. // ----- This status is internal and will be changed in 'skipped' 
  3480. $p_entry['status'] = "aborted"; 
  3481. $v_result = PCLZIP_ERR_USER_ABORTED; 
  3482.  
  3483. // ----- Update the informations 
  3484. // Only some fields can be modified 
  3485. $p_entry['filename'] = $v_local_header['filename']; 
  3486.  
  3487.  
  3488. // ----- Look if extraction should be done 
  3489. if ($p_entry['status'] == 'ok') { 
  3490.  
  3491. // ----- Do the extraction (if not a folder) 
  3492. if (!(($p_entry['external']&0x00000010)==0x00000010)) { 
  3493. // ----- Look for not compressed file 
  3494. // if ($p_entry['compressed_size'] == $p_entry['size']) 
  3495. if ($p_entry['compression'] == 0) { 
  3496.  
  3497. // ----- Reading the file 
  3498. $p_string = @fread($this->zip_fd, $p_entry['compressed_size']); 
  3499. else { 
  3500.  
  3501. // ----- Reading the file 
  3502. $v_data = @fread($this->zip_fd, $p_entry['compressed_size']); 
  3503.  
  3504. // ----- Decompress the file 
  3505. if (($p_string = @gzinflate($v_data)) === FALSE) { 
  3506. // TBC 
  3507.  
  3508. // ----- Trace 
  3509. else { 
  3510. // TBC : error : can not extract a folder in a string 
  3511.  
  3512.  
  3513. // ----- Change abort status 
  3514. if ($p_entry['status'] == "aborted") { 
  3515. $p_entry['status'] = "skipped"; 
  3516.  
  3517. // ----- Look for post-extract callback 
  3518. elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { 
  3519.  
  3520. // ----- Generate a local information 
  3521. $v_local_header = array(); 
  3522. $this->privConvertHeader2FileInfo($p_entry, $v_local_header); 
  3523.  
  3524. // ----- Swap the content to header 
  3525. $v_local_header['content'] = $p_string; 
  3526. $p_string = ''; 
  3527.  
  3528. // ----- Call the callback 
  3529. // Here I do not use call_user_func() because I need to send a reference to the 
  3530. // header. 
  3531. $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); 
  3532.  
  3533. // ----- Swap back the content to header 
  3534. $p_string = $v_local_header['content']; 
  3535. unset($v_local_header['content']); 
  3536.  
  3537. // ----- Look for abort result 
  3538. if ($v_result == 2) { 
  3539. $v_result = PCLZIP_ERR_USER_ABORTED; 
  3540.  
  3541. // ----- Return 
  3542. return $v_result; 
  3543. // -------------------------------------------------------------------------------- 
  3544.  
  3545. // -------------------------------------------------------------------------------- 
  3546. // Function : privReadFileHeader() 
  3547. // Description : 
  3548. // Parameters : 
  3549. // Return Values : 
  3550. // -------------------------------------------------------------------------------- 
  3551. function privReadFileHeader(&$p_header) 
  3552. $v_result=1; 
  3553.  
  3554. // ----- Read the 4 bytes signature 
  3555. $v_binary_data = @fread($this->zip_fd, 4); 
  3556. $v_data = unpack('Vid', $v_binary_data); 
  3557.  
  3558. // ----- Check signature 
  3559. if ($v_data['id'] != 0x04034b50) 
  3560.  
  3561. // ----- Error log 
  3562. PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); 
  3563.  
  3564. // ----- Return 
  3565. return PclZip::errorCode(); 
  3566.  
  3567. // ----- Read the first 42 bytes of the header 
  3568. $v_binary_data = fread($this->zip_fd, 26); 
  3569.  
  3570. // ----- Look for invalid block size 
  3571. if (strlen($v_binary_data) != 26) 
  3572. $p_header['filename'] = ""; 
  3573. $p_header['status'] = "invalid_header"; 
  3574.  
  3575. // ----- Error log 
  3576. PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); 
  3577.  
  3578. // ----- Return 
  3579. return PclZip::errorCode(); 
  3580.  
  3581. // ----- Extract the values 
  3582. $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data); 
  3583.  
  3584. // ----- Get filename 
  3585. $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']); 
  3586.  
  3587. // ----- Get extra_fields 
  3588. if ($v_data['extra_len'] != 0) { 
  3589. $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']); 
  3590. else { 
  3591. $p_header['extra'] = ''; 
  3592.  
  3593. // ----- Extract properties 
  3594. $p_header['version_extracted'] = $v_data['version']; 
  3595. $p_header['compression'] = $v_data['compression']; 
  3596. $p_header['size'] = $v_data['size']; 
  3597. $p_header['compressed_size'] = $v_data['compressed_size']; 
  3598. $p_header['crc'] = $v_data['crc']; 
  3599. $p_header['flag'] = $v_data['flag']; 
  3600. $p_header['filename_len'] = $v_data['filename_len']; 
  3601.  
  3602. // ----- Recuperate date in UNIX format 
  3603. $p_header['mdate'] = $v_data['mdate']; 
  3604. $p_header['mtime'] = $v_data['mtime']; 
  3605. if ($p_header['mdate'] && $p_header['mtime']) 
  3606. // ----- Extract time 
  3607. $v_hour = ($p_header['mtime'] & 0xF800) >> 11; 
  3608. $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; 
  3609. $v_seconde = ($p_header['mtime'] & 0x001F)*2; 
  3610.  
  3611. // ----- Extract date 
  3612. $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; 
  3613. $v_month = ($p_header['mdate'] & 0x01E0) >> 5; 
  3614. $v_day = $p_header['mdate'] & 0x001F; 
  3615.  
  3616. // ----- Get UNIX date format 
  3617. $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); 
  3618.  
  3619. else 
  3620. $p_header['mtime'] = time(); 
  3621.  
  3622. // TBC 
  3623. //for(reset($v_data); $key = key($v_data); next($v_data)) { 
  3624. //} 
  3625.  
  3626. // ----- Set the stored filename 
  3627. $p_header['stored_filename'] = $p_header['filename']; 
  3628.  
  3629. // ----- Set the status field 
  3630. $p_header['status'] = "ok"; 
  3631.  
  3632. // ----- Return 
  3633. return $v_result; 
  3634. // -------------------------------------------------------------------------------- 
  3635.  
  3636. // -------------------------------------------------------------------------------- 
  3637. // Function : privReadCentralFileHeader() 
  3638. // Description : 
  3639. // Parameters : 
  3640. // Return Values : 
  3641. // -------------------------------------------------------------------------------- 
  3642. function privReadCentralFileHeader(&$p_header) 
  3643. $v_result=1; 
  3644.  
  3645. // ----- Read the 4 bytes signature 
  3646. $v_binary_data = @fread($this->zip_fd, 4); 
  3647. $v_data = unpack('Vid', $v_binary_data); 
  3648.  
  3649. // ----- Check signature 
  3650. if ($v_data['id'] != 0x02014b50) 
  3651.  
  3652. // ----- Error log 
  3653. PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); 
  3654.  
  3655. // ----- Return 
  3656. return PclZip::errorCode(); 
  3657.  
  3658. // ----- Read the first 42 bytes of the header 
  3659. $v_binary_data = fread($this->zip_fd, 42); 
  3660.  
  3661. // ----- Look for invalid block size 
  3662. if (strlen($v_binary_data) != 42) 
  3663. $p_header['filename'] = ""; 
  3664. $p_header['status'] = "invalid_header"; 
  3665.  
  3666. // ----- Error log 
  3667. PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); 
  3668.  
  3669. // ----- Return 
  3670. return PclZip::errorCode(); 
  3671.  
  3672. // ----- Extract the values 
  3673. $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data); 
  3674.  
  3675. // ----- Get filename 
  3676. if ($p_header['filename_len'] != 0) 
  3677. $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']); 
  3678. else 
  3679. $p_header['filename'] = ''; 
  3680.  
  3681. // ----- Get extra 
  3682. if ($p_header['extra_len'] != 0) 
  3683. $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']); 
  3684. else 
  3685. $p_header['extra'] = ''; 
  3686.  
  3687. // ----- Get comment 
  3688. if ($p_header['comment_len'] != 0) 
  3689. $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']); 
  3690. else 
  3691. $p_header['comment'] = ''; 
  3692.  
  3693. // ----- Extract properties 
  3694.  
  3695. // ----- Recuperate date in UNIX format 
  3696. //if ($p_header['mdate'] && $p_header['mtime']) 
  3697. // TBC : bug : this was ignoring time with 0/0/0 
  3698. if (1) 
  3699. // ----- Extract time 
  3700. $v_hour = ($p_header['mtime'] & 0xF800) >> 11; 
  3701. $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; 
  3702. $v_seconde = ($p_header['mtime'] & 0x001F)*2; 
  3703.  
  3704. // ----- Extract date 
  3705. $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; 
  3706. $v_month = ($p_header['mdate'] & 0x01E0) >> 5; 
  3707. $v_day = $p_header['mdate'] & 0x001F; 
  3708.  
  3709. // ----- Get UNIX date format 
  3710. $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); 
  3711.  
  3712. else 
  3713. $p_header['mtime'] = time(); 
  3714.  
  3715. // ----- Set the stored filename 
  3716. $p_header['stored_filename'] = $p_header['filename']; 
  3717.  
  3718. // ----- Set default status to ok 
  3719. $p_header['status'] = 'ok'; 
  3720.  
  3721. // ----- Look if it is a directory 
  3722. if (substr($p_header['filename'], -1) == '/') { 
  3723. //$p_header['external'] = 0x41FF0010; 
  3724. $p_header['external'] = 0x00000010; 
  3725.  
  3726.  
  3727. // ----- Return 
  3728. return $v_result; 
  3729. // -------------------------------------------------------------------------------- 
  3730.  
  3731. // -------------------------------------------------------------------------------- 
  3732. // Function : privCheckFileHeaders() 
  3733. // Description : 
  3734. // Parameters : 
  3735. // Return Values : 
  3736. // 1 on success,  
  3737. // 0 on error; 
  3738. // -------------------------------------------------------------------------------- 
  3739. function privCheckFileHeaders(&$p_local_header, &$p_central_header) 
  3740. $v_result=1; 
  3741.  
  3742. // ----- Check the static values 
  3743. // TBC 
  3744. if ($p_local_header['filename'] != $p_central_header['filename']) { 
  3745. if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) { 
  3746. if ($p_local_header['flag'] != $p_central_header['flag']) { 
  3747. if ($p_local_header['compression'] != $p_central_header['compression']) { 
  3748. if ($p_local_header['mtime'] != $p_central_header['mtime']) { 
  3749. if ($p_local_header['filename_len'] != $p_central_header['filename_len']) { 
  3750.  
  3751. // ----- Look for flag bit 3 
  3752. if (($p_local_header['flag'] & 8) == 8) { 
  3753. $p_local_header['size'] = $p_central_header['size']; 
  3754. $p_local_header['compressed_size'] = $p_central_header['compressed_size']; 
  3755. $p_local_header['crc'] = $p_central_header['crc']; 
  3756.  
  3757. // ----- Return 
  3758. return $v_result; 
  3759. // -------------------------------------------------------------------------------- 
  3760.  
  3761. // -------------------------------------------------------------------------------- 
  3762. // Function : privReadEndCentralDir() 
  3763. // Description : 
  3764. // Parameters : 
  3765. // Return Values : 
  3766. // -------------------------------------------------------------------------------- 
  3767. function privReadEndCentralDir(&$p_central_dir) 
  3768. $v_result=1; 
  3769.  
  3770. // ----- Go to the end of the zip file 
  3771. $v_size = filesize($this->zipname); 
  3772. @fseek($this->zip_fd, $v_size); 
  3773. if (@ftell($this->zip_fd) != $v_size) 
  3774. // ----- Error log 
  3775. PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\''); 
  3776.  
  3777. // ----- Return 
  3778. return PclZip::errorCode(); 
  3779.  
  3780. // ----- First try : look if this is an archive with no commentaries (most of the time) 
  3781. // in this case the end of central dir is at 22 bytes of the file end 
  3782. $v_found = 0; 
  3783. if ($v_size > 26) { 
  3784. @fseek($this->zip_fd, $v_size-22); 
  3785. if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22)) 
  3786. // ----- Error log 
  3787. PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); 
  3788.  
  3789. // ----- Return 
  3790. return PclZip::errorCode(); 
  3791.  
  3792. // ----- Read for bytes 
  3793. $v_binary_data = @fread($this->zip_fd, 4); 
  3794. $v_data = @unpack('Vid', $v_binary_data); 
  3795.  
  3796. // ----- Check signature 
  3797. if ($v_data['id'] == 0x06054b50) { 
  3798. $v_found = 1; 
  3799.  
  3800. $v_pos = ftell($this->zip_fd); 
  3801.  
  3802. // ----- Go back to the maximum possible size of the Central Dir End Record 
  3803. if (!$v_found) { 
  3804. $v_maximum_size = 65557; // 0xFFFF + 22; 
  3805. if ($v_maximum_size > $v_size) 
  3806. $v_maximum_size = $v_size; 
  3807. @fseek($this->zip_fd, $v_size-$v_maximum_size); 
  3808. if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size)) 
  3809. // ----- Error log 
  3810. PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); 
  3811.  
  3812. // ----- Return 
  3813. return PclZip::errorCode(); 
  3814.  
  3815. // ----- Read byte per byte in order to find the signature 
  3816. $v_pos = ftell($this->zip_fd); 
  3817. $v_bytes = 0x00000000; 
  3818. while ($v_pos < $v_size) 
  3819. // ----- Read a byte 
  3820. $v_byte = @fread($this->zip_fd, 1); 
  3821.  
  3822. // ----- Add the byte 
  3823. //$v_bytes = ($v_bytes << 8) | Ord($v_byte); 
  3824. // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number 
  3825. // Otherwise on systems where we have 64bit integers the check below for the magic number will fail. 
  3826. $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte); 
  3827.  
  3828. // ----- Compare the bytes 
  3829. if ($v_bytes == 0x504b0506) 
  3830. $v_pos++; 
  3831. break; 
  3832.  
  3833. $v_pos++; 
  3834.  
  3835. // ----- Look if not found end of central dir 
  3836. if ($v_pos == $v_size) 
  3837.  
  3838. // ----- Error log 
  3839. PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature"); 
  3840.  
  3841. // ----- Return 
  3842. return PclZip::errorCode(); 
  3843.  
  3844. // ----- Read the first 18 bytes of the header 
  3845. $v_binary_data = fread($this->zip_fd, 18); 
  3846.  
  3847. // ----- Look for invalid block size 
  3848. if (strlen($v_binary_data) != 18) 
  3849.  
  3850. // ----- Error log 
  3851. PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data)); 
  3852.  
  3853. // ----- Return 
  3854. return PclZip::errorCode(); 
  3855.  
  3856. // ----- Extract the values 
  3857. $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data); 
  3858.  
  3859. // ----- Check the global size 
  3860. if (($v_pos + $v_data['comment_size'] + 18) != $v_size) { 
  3861.  
  3862. // ----- Removed in release 2.2 see readme file 
  3863. // The check of the file size is a little too strict. 
  3864. // Some bugs where found when a zip is encrypted/decrypted with 'crypt'. 
  3865. // While decrypted, zip has training 0 bytes 
  3866. if (0) { 
  3867. // ----- Error log 
  3868. PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,  
  3869. 'The central dir is not at the end of the archive.' 
  3870. .' Some trailing bytes exists after the archive.'); 
  3871.  
  3872. // ----- Return 
  3873. return PclZip::errorCode(); 
  3874.  
  3875. // ----- Get comment 
  3876. if ($v_data['comment_size'] != 0) { 
  3877. $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']); 
  3878. else 
  3879. $p_central_dir['comment'] = ''; 
  3880.  
  3881. $p_central_dir['entries'] = $v_data['entries']; 
  3882. $p_central_dir['disk_entries'] = $v_data['disk_entries']; 
  3883. $p_central_dir['offset'] = $v_data['offset']; 
  3884. $p_central_dir['size'] = $v_data['size']; 
  3885. $p_central_dir['disk'] = $v_data['disk']; 
  3886. $p_central_dir['disk_start'] = $v_data['disk_start']; 
  3887.  
  3888. // TBC 
  3889. //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) { 
  3890. //} 
  3891.  
  3892. // ----- Return 
  3893. return $v_result; 
  3894. // -------------------------------------------------------------------------------- 
  3895.  
  3896. // -------------------------------------------------------------------------------- 
  3897. // Function : privDeleteByRule() 
  3898. // Description : 
  3899. // Parameters : 
  3900. // Return Values : 
  3901. // -------------------------------------------------------------------------------- 
  3902. function privDeleteByRule(&$p_result_list, &$p_options) 
  3903. $v_result=1; 
  3904. $v_list_detail = array(); 
  3905.  
  3906. // ----- Open the zip file 
  3907. if (($v_result=$this->privOpenFd('rb')) != 1) 
  3908. // ----- Return 
  3909. return $v_result; 
  3910.  
  3911. // ----- Read the central directory informations 
  3912. $v_central_dir = array(); 
  3913. if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) 
  3914. $this->privCloseFd(); 
  3915. return $v_result; 
  3916.  
  3917. // ----- Go to beginning of File 
  3918. @rewind($this->zip_fd); 
  3919.  
  3920. // ----- Scan all the files 
  3921. // ----- Start at beginning of Central Dir 
  3922. $v_pos_entry = $v_central_dir['offset']; 
  3923. @rewind($this->zip_fd); 
  3924. if (@fseek($this->zip_fd, $v_pos_entry)) 
  3925. // ----- Close the zip file 
  3926. $this->privCloseFd(); 
  3927.  
  3928. // ----- Error log 
  3929. PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); 
  3930.  
  3931. // ----- Return 
  3932. return PclZip::errorCode(); 
  3933.  
  3934. // ----- Read each entry 
  3935. $v_header_list = array(); 
  3936. $j_start = 0; 
  3937. for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) 
  3938.  
  3939. // ----- Read the file header 
  3940. $v_header_list[$v_nb_extracted] = array(); 
  3941. if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1) 
  3942. // ----- Close the zip file 
  3943. $this->privCloseFd(); 
  3944.  
  3945. return $v_result; 
  3946.  
  3947.  
  3948. // ----- Store the index 
  3949. $v_header_list[$v_nb_extracted]['index'] = $i; 
  3950.  
  3951. // ----- Look for the specific extract rules 
  3952. $v_found = false; 
  3953.  
  3954. // ----- Look for extract by name rule 
  3955. if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) 
  3956. && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { 
  3957.  
  3958. // ----- Look if the filename is in the list 
  3959. for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) { 
  3960.  
  3961. // ----- Look for a directory 
  3962. if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { 
  3963.  
  3964. // ----- Look if the directory is in the filename path 
  3965. if ( (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) 
  3966. && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { 
  3967. $v_found = true; 
  3968. elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /** Indicates a folder */ 
  3969. && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) { 
  3970. $v_found = true; 
  3971. // ----- Look for a filename 
  3972. elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { 
  3973. $v_found = true; 
  3974.  
  3975. // ----- Look for extract by ereg rule 
  3976. // ereg() is deprecated with PHP 5.3 
  3977. /** 
  3978. else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) 
  3979. && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { 
  3980.   
  3981. if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { 
  3982. $v_found = true; 
  3983. */ 
  3984.  
  3985. // ----- Look for extract by preg rule 
  3986. else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) 
  3987. && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { 
  3988.  
  3989. if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { 
  3990. $v_found = true; 
  3991.  
  3992. // ----- Look for extract by index rule 
  3993. else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) 
  3994. && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { 
  3995.  
  3996. // ----- Look if the index is in the list 
  3997. for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) { 
  3998.  
  3999. if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { 
  4000. $v_found = true; 
  4001. if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { 
  4002. $j_start = $j+1; 
  4003.  
  4004. if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { 
  4005. break; 
  4006. else { 
  4007. $v_found = true; 
  4008.  
  4009. // ----- Look for deletion 
  4010. if ($v_found) 
  4011. unset($v_header_list[$v_nb_extracted]); 
  4012. else 
  4013. $v_nb_extracted++; 
  4014.  
  4015. // ----- Look if something need to be deleted 
  4016. if ($v_nb_extracted > 0) { 
  4017.  
  4018. // ----- Creates a temporay file 
  4019. $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; 
  4020.  
  4021. // ----- Creates a temporary zip archive 
  4022. $v_temp_zip = new PclZip($v_zip_temp_name); 
  4023.  
  4024. // ----- Open the temporary zip file in write mode 
  4025. if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) { 
  4026. $this->privCloseFd(); 
  4027.  
  4028. // ----- Return 
  4029. return $v_result; 
  4030.  
  4031. // ----- Look which file need to be kept 
  4032. for ($i=0; $i<sizeof($v_header_list); $i++) { 
  4033.  
  4034. // ----- Calculate the position of the header 
  4035. @rewind($this->zip_fd); 
  4036. if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) { 
  4037. // ----- Close the zip file 
  4038. $this->privCloseFd(); 
  4039. $v_temp_zip->privCloseFd(); 
  4040. @unlink($v_zip_temp_name); 
  4041.  
  4042. // ----- Error log 
  4043. PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); 
  4044.  
  4045. // ----- Return 
  4046. return PclZip::errorCode(); 
  4047.  
  4048. // ----- Read the file header 
  4049. $v_local_header = array(); 
  4050. if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) { 
  4051. // ----- Close the zip file 
  4052. $this->privCloseFd(); 
  4053. $v_temp_zip->privCloseFd(); 
  4054. @unlink($v_zip_temp_name); 
  4055.  
  4056. // ----- Return 
  4057. return $v_result; 
  4058.  
  4059. // ----- Check that local file header is same as central file header 
  4060. if ($this->privCheckFileHeaders($v_local_header,  
  4061. $v_header_list[$i]) != 1) { 
  4062. // TBC 
  4063. unset($v_local_header); 
  4064.  
  4065. // ----- Write the file header 
  4066. if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) { 
  4067. // ----- Close the zip file 
  4068. $this->privCloseFd(); 
  4069. $v_temp_zip->privCloseFd(); 
  4070. @unlink($v_zip_temp_name); 
  4071.  
  4072. // ----- Return 
  4073. return $v_result; 
  4074.  
  4075. // ----- Read/write the data block 
  4076. if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) { 
  4077. // ----- Close the zip file 
  4078. $this->privCloseFd(); 
  4079. $v_temp_zip->privCloseFd(); 
  4080. @unlink($v_zip_temp_name); 
  4081.  
  4082. // ----- Return 
  4083. return $v_result; 
  4084.  
  4085. // ----- Store the offset of the central dir 
  4086. $v_offset = @ftell($v_temp_zip->zip_fd); 
  4087.  
  4088. // ----- Re-Create the Central Dir files header 
  4089. for ($i=0; $i<sizeof($v_header_list); $i++) { 
  4090. // ----- Create the file header 
  4091. if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) { 
  4092. $v_temp_zip->privCloseFd(); 
  4093. $this->privCloseFd(); 
  4094. @unlink($v_zip_temp_name); 
  4095.  
  4096. // ----- Return 
  4097. return $v_result; 
  4098.  
  4099. // ----- Transform the header to a 'usable' info 
  4100. $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); 
  4101.  
  4102.  
  4103. // ----- Zip file comment 
  4104. $v_comment = ''; 
  4105. if (isset($p_options[PCLZIP_OPT_COMMENT])) { 
  4106. $v_comment = $p_options[PCLZIP_OPT_COMMENT]; 
  4107.  
  4108. // ----- Calculate the size of the central header 
  4109. $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset; 
  4110.  
  4111. // ----- Create the central dir footer 
  4112. if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) { 
  4113. // ----- Reset the file list 
  4114. unset($v_header_list); 
  4115. $v_temp_zip->privCloseFd(); 
  4116. $this->privCloseFd(); 
  4117. @unlink($v_zip_temp_name); 
  4118.  
  4119. // ----- Return 
  4120. return $v_result; 
  4121.  
  4122. // ----- Close 
  4123. $v_temp_zip->privCloseFd(); 
  4124. $this->privCloseFd(); 
  4125.  
  4126. // ----- Delete the zip file 
  4127. // TBC : I should test the result ... 
  4128. @unlink($this->zipname); 
  4129.  
  4130. // ----- Rename the temporary file 
  4131. // TBC : I should test the result ... 
  4132. //@rename($v_zip_temp_name, $this->zipname); 
  4133. PclZipUtilRename($v_zip_temp_name, $this->zipname); 
  4134.  
  4135. // ----- Destroy the temporary archive 
  4136. unset($v_temp_zip); 
  4137.  
  4138. // ----- Remove every files : reset the file 
  4139. else if ($v_central_dir['entries'] != 0) { 
  4140. $this->privCloseFd(); 
  4141.  
  4142. if (($v_result = $this->privOpenFd('wb')) != 1) { 
  4143. return $v_result; 
  4144.  
  4145. if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) { 
  4146. return $v_result; 
  4147.  
  4148. $this->privCloseFd(); 
  4149.  
  4150. // ----- Return 
  4151. return $v_result; 
  4152. // -------------------------------------------------------------------------------- 
  4153.  
  4154. // -------------------------------------------------------------------------------- 
  4155. // Function : privDirCheck() 
  4156. // Description : 
  4157. // Check if a directory exists, if not it creates it and all the parents directory 
  4158. // which may be useful. 
  4159. // Parameters : 
  4160. // $p_dir : Directory path to check. 
  4161. // Return Values : 
  4162. // 1 : OK 
  4163. // -1 : Unable to create directory 
  4164. // -------------------------------------------------------------------------------- 
  4165. function privDirCheck($p_dir, $p_is_dir=false) 
  4166. $v_result = 1; 
  4167.  
  4168.  
  4169. // ----- Remove the final '/' 
  4170. if (($p_is_dir) && (substr($p_dir, -1)=='/')) 
  4171. $p_dir = substr($p_dir, 0, strlen($p_dir)-1); 
  4172.  
  4173. // ----- Check the directory availability 
  4174. if ((is_dir($p_dir)) || ($p_dir == "")) 
  4175. return 1; 
  4176.  
  4177. // ----- Extract parent directory 
  4178. $p_parent_dir = dirname($p_dir); 
  4179.  
  4180. // ----- Just a check 
  4181. if ($p_parent_dir != $p_dir) 
  4182. // ----- Look for parent directory 
  4183. if ($p_parent_dir != "") 
  4184. if (($v_result = $this->privDirCheck($p_parent_dir)) != 1) 
  4185. return $v_result; 
  4186.  
  4187. // ----- Create the directory 
  4188. if (!@mkdir($p_dir, 0777)) 
  4189. // ----- Error log 
  4190. PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'"); 
  4191.  
  4192. // ----- Return 
  4193. return PclZip::errorCode(); 
  4194.  
  4195. // ----- Return 
  4196. return $v_result; 
  4197. // -------------------------------------------------------------------------------- 
  4198.  
  4199. // -------------------------------------------------------------------------------- 
  4200. // Function : privMerge() 
  4201. // Description : 
  4202. // If $p_archive_to_add does not exist, the function exit with a success result. 
  4203. // Parameters : 
  4204. // Return Values : 
  4205. // -------------------------------------------------------------------------------- 
  4206. function privMerge(&$p_archive_to_add) 
  4207. $v_result=1; 
  4208.  
  4209. // ----- Look if the archive_to_add exists 
  4210. if (!is_file($p_archive_to_add->zipname)) 
  4211.  
  4212. // ----- Nothing to merge, so merge is a success 
  4213. $v_result = 1; 
  4214.  
  4215. // ----- Return 
  4216. return $v_result; 
  4217.  
  4218. // ----- Look if the archive exists 
  4219. if (!is_file($this->zipname)) 
  4220.  
  4221. // ----- Do a duplicate 
  4222. $v_result = $this->privDuplicate($p_archive_to_add->zipname); 
  4223.  
  4224. // ----- Return 
  4225. return $v_result; 
  4226.  
  4227. // ----- Open the zip file 
  4228. if (($v_result=$this->privOpenFd('rb')) != 1) 
  4229. // ----- Return 
  4230. return $v_result; 
  4231.  
  4232. // ----- Read the central directory informations 
  4233. $v_central_dir = array(); 
  4234. if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) 
  4235. $this->privCloseFd(); 
  4236. return $v_result; 
  4237.  
  4238. // ----- Go to beginning of File 
  4239. @rewind($this->zip_fd); 
  4240.  
  4241. // ----- Open the archive_to_add file 
  4242. if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1) 
  4243. $this->privCloseFd(); 
  4244.  
  4245. // ----- Return 
  4246. return $v_result; 
  4247.  
  4248. // ----- Read the central directory informations 
  4249. $v_central_dir_to_add = array(); 
  4250. if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1) 
  4251. $this->privCloseFd(); 
  4252. $p_archive_to_add->privCloseFd(); 
  4253.  
  4254. return $v_result; 
  4255.  
  4256. // ----- Go to beginning of File 
  4257. @rewind($p_archive_to_add->zip_fd); 
  4258.  
  4259. // ----- Creates a temporay file 
  4260. $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; 
  4261.  
  4262. // ----- Open the temporary file in write mode 
  4263. if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) 
  4264. $this->privCloseFd(); 
  4265. $p_archive_to_add->privCloseFd(); 
  4266.  
  4267. PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); 
  4268.  
  4269. // ----- Return 
  4270. return PclZip::errorCode(); 
  4271.  
  4272. // ----- Copy the files from the archive to the temporary file 
  4273. // TBC : Here I should better append the file and go back to erase the central dir 
  4274. $v_size = $v_central_dir['offset']; 
  4275. while ($v_size != 0) 
  4276. $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 
  4277. $v_buffer = fread($this->zip_fd, $v_read_size); 
  4278. @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); 
  4279. $v_size -= $v_read_size; 
  4280.  
  4281. // ----- Copy the files from the archive_to_add into the temporary file 
  4282. $v_size = $v_central_dir_to_add['offset']; 
  4283. while ($v_size != 0) 
  4284. $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 
  4285. $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size); 
  4286. @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); 
  4287. $v_size -= $v_read_size; 
  4288.  
  4289. // ----- Store the offset of the central dir 
  4290. $v_offset = @ftell($v_zip_temp_fd); 
  4291.  
  4292. // ----- Copy the block of file headers from the old archive 
  4293. $v_size = $v_central_dir['size']; 
  4294. while ($v_size != 0) 
  4295. $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 
  4296. $v_buffer = @fread($this->zip_fd, $v_read_size); 
  4297. @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); 
  4298. $v_size -= $v_read_size; 
  4299.  
  4300. // ----- Copy the block of file headers from the archive_to_add 
  4301. $v_size = $v_central_dir_to_add['size']; 
  4302. while ($v_size != 0) 
  4303. $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 
  4304. $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size); 
  4305. @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); 
  4306. $v_size -= $v_read_size; 
  4307.  
  4308. // ----- Merge the file comments 
  4309. $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment']; 
  4310.  
  4311. // ----- Calculate the size of the (new) central header 
  4312. $v_size = @ftell($v_zip_temp_fd)-$v_offset; 
  4313.  
  4314. // ----- Swap the file descriptor 
  4315. // Here is a trick : I swap the temporary fd with the zip fd, in order to use 
  4316. // the following methods on the temporary fil and not the real archive fd 
  4317. $v_swap = $this->zip_fd; 
  4318. $this->zip_fd = $v_zip_temp_fd; 
  4319. $v_zip_temp_fd = $v_swap; 
  4320.  
  4321. // ----- Create the central dir footer 
  4322. if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1) 
  4323. $this->privCloseFd(); 
  4324. $p_archive_to_add->privCloseFd(); 
  4325. @fclose($v_zip_temp_fd); 
  4326. $this->zip_fd = null; 
  4327.  
  4328. // ----- Reset the file list 
  4329. unset($v_header_list); 
  4330.  
  4331. // ----- Return 
  4332. return $v_result; 
  4333.  
  4334. // ----- Swap back the file descriptor 
  4335. $v_swap = $this->zip_fd; 
  4336. $this->zip_fd = $v_zip_temp_fd; 
  4337. $v_zip_temp_fd = $v_swap; 
  4338.  
  4339. // ----- Close 
  4340. $this->privCloseFd(); 
  4341. $p_archive_to_add->privCloseFd(); 
  4342.  
  4343. // ----- Close the temporary file 
  4344. @fclose($v_zip_temp_fd); 
  4345.  
  4346. // ----- Delete the zip file 
  4347. // TBC : I should test the result ... 
  4348. @unlink($this->zipname); 
  4349.  
  4350. // ----- Rename the temporary file 
  4351. // TBC : I should test the result ... 
  4352. //@rename($v_zip_temp_name, $this->zipname); 
  4353. PclZipUtilRename($v_zip_temp_name, $this->zipname); 
  4354.  
  4355. // ----- Return 
  4356. return $v_result; 
  4357. // -------------------------------------------------------------------------------- 
  4358.  
  4359. // -------------------------------------------------------------------------------- 
  4360. // Function : privDuplicate() 
  4361. // Description : 
  4362. // Parameters : 
  4363. // Return Values : 
  4364. // -------------------------------------------------------------------------------- 
  4365. function privDuplicate($p_archive_filename) 
  4366. $v_result=1; 
  4367.  
  4368. // ----- Look if the $p_archive_filename exists 
  4369. if (!is_file($p_archive_filename)) 
  4370.  
  4371. // ----- Nothing to duplicate, so duplicate is a success. 
  4372. $v_result = 1; 
  4373.  
  4374. // ----- Return 
  4375. return $v_result; 
  4376.  
  4377. // ----- Open the zip file 
  4378. if (($v_result=$this->privOpenFd('wb')) != 1) 
  4379. // ----- Return 
  4380. return $v_result; 
  4381.  
  4382. // ----- Open the temporary file in write mode 
  4383. if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) 
  4384. $this->privCloseFd(); 
  4385.  
  4386. PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode'); 
  4387.  
  4388. // ----- Return 
  4389. return PclZip::errorCode(); 
  4390.  
  4391. // ----- Copy the files from the archive to the temporary file 
  4392. // TBC : Here I should better append the file and go back to erase the central dir 
  4393. $v_size = filesize($p_archive_filename); 
  4394. while ($v_size != 0) 
  4395. $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 
  4396. $v_buffer = fread($v_zip_temp_fd, $v_read_size); 
  4397. @fwrite($this->zip_fd, $v_buffer, $v_read_size); 
  4398. $v_size -= $v_read_size; 
  4399.  
  4400. // ----- Close 
  4401. $this->privCloseFd(); 
  4402.  
  4403. // ----- Close the temporary file 
  4404. @fclose($v_zip_temp_fd); 
  4405.  
  4406. // ----- Return 
  4407. return $v_result; 
  4408. // -------------------------------------------------------------------------------- 
  4409.  
  4410. // -------------------------------------------------------------------------------- 
  4411. // Function : privErrorLog() 
  4412. // Description : 
  4413. // Parameters : 
  4414. // -------------------------------------------------------------------------------- 
  4415. function privErrorLog($p_error_code=0, $p_error_string='') 
  4416. if (PCLZIP_ERROR_EXTERNAL == 1) { 
  4417. PclError($p_error_code, $p_error_string); 
  4418. else { 
  4419. $this->error_code = $p_error_code; 
  4420. $this->error_string = $p_error_string; 
  4421. // -------------------------------------------------------------------------------- 
  4422.  
  4423. // -------------------------------------------------------------------------------- 
  4424. // Function : privErrorReset() 
  4425. // Description : 
  4426. // Parameters : 
  4427. // -------------------------------------------------------------------------------- 
  4428. function privErrorReset() 
  4429. if (PCLZIP_ERROR_EXTERNAL == 1) { 
  4430. PclErrorReset(); 
  4431. else { 
  4432. $this->error_code = 0; 
  4433. $this->error_string = ''; 
  4434. // -------------------------------------------------------------------------------- 
  4435.  
  4436. // -------------------------------------------------------------------------------- 
  4437. // Function : privDisableMagicQuotes() 
  4438. // Description : 
  4439. // Parameters : 
  4440. // Return Values : 
  4441. // -------------------------------------------------------------------------------- 
  4442. function privDisableMagicQuotes() 
  4443. $v_result=1; 
  4444.  
  4445. // ----- Look if function exists 
  4446. if ( (!function_exists("get_magic_quotes_runtime")) 
  4447. || (!function_exists("set_magic_quotes_runtime"))) { 
  4448. return $v_result; 
  4449.  
  4450. // ----- Look if already done 
  4451. if ($this->magic_quotes_status != -1) { 
  4452. return $v_result; 
  4453.  
  4454. // ----- Get and memorize the magic_quote value 
  4455. $this->magic_quotes_status = @get_magic_quotes_runtime(); 
  4456.  
  4457. // ----- Disable magic_quotes 
  4458. if ($this->magic_quotes_status == 1) { 
  4459. @set_magic_quotes_runtime(0); 
  4460.  
  4461. // ----- Return 
  4462. return $v_result; 
  4463. // -------------------------------------------------------------------------------- 
  4464.  
  4465. // -------------------------------------------------------------------------------- 
  4466. // Function : privSwapBackMagicQuotes() 
  4467. // Description : 
  4468. // Parameters : 
  4469. // Return Values : 
  4470. // -------------------------------------------------------------------------------- 
  4471. function privSwapBackMagicQuotes() 
  4472. $v_result=1; 
  4473.  
  4474. // ----- Look if function exists 
  4475. if ( (!function_exists("get_magic_quotes_runtime")) 
  4476. || (!function_exists("set_magic_quotes_runtime"))) { 
  4477. return $v_result; 
  4478.  
  4479. // ----- Look if something to do 
  4480. if ($this->magic_quotes_status != -1) { 
  4481. return $v_result; 
  4482.  
  4483. // ----- Swap back magic_quotes 
  4484. if ($this->magic_quotes_status == 1) { 
  4485. @set_magic_quotes_runtime($this->magic_quotes_status); 
  4486.  
  4487. // ----- Return 
  4488. return $v_result; 
  4489. // -------------------------------------------------------------------------------- 
  4490.