PageRenderTime 63ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 1ms

/4.9/administrator/includes/pcl/pcltar.lib.php

http://miacms.googlecode.com/
PHP | 3575 lines | 1996 code | 511 blank | 1068 comment | 619 complexity | 7642ed2fb1c2f2ec1eb28c483f1b24c7 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0, LGPL-2.0
  1. <?php
  2. /**
  3. * @package MiaCMS
  4. */
  5. /** ensure this file is being included by a parent file */
  6. defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );
  7. // --------------------------------------------------------------------------------
  8. // PhpConcept Library - Tar Module 1.3
  9. // --------------------------------------------------------------------------------
  10. // License GNU/GPL - Vincent Blavet - August 2001
  11. // http://www.phpconcept.net
  12. // --------------------------------------------------------------------------------
  13. //
  14. // Presentation :
  15. // PclTar is a library that allow you to create a GNU TAR + GNU ZIP archive,
  16. // to add files or directories, to extract all the archive or a part of it.
  17. // So far tests show that the files generated by PclTar are readable by
  18. // gzip tools and WinZip application.
  19. //
  20. // Description :
  21. // See readme.txt (English & Français) and http://www.phpconcept.net
  22. //
  23. // Warning :
  24. // This library and the associated files are non commercial, non professional
  25. // work.
  26. // It should not have unexpected results. However if any damage is caused by
  27. // this software the author can not be responsible.
  28. // The use of this software is at the risk of the user.
  29. //
  30. // --------------------------------------------------------------------------------
  31. // ----- Look for double include
  32. if (!defined("PCL_TAR"))
  33. {
  34. define( "PCL_TAR", 1 );
  35. // ----- Configuration variable
  36. // Theses values may be changed by the user of PclTar library
  37. if (!isset($g_pcltar_lib_dir))
  38. $g_pcltar_lib_dir = "lib";
  39. // ----- Error codes
  40. // -1 : Unable to open file in binary write mode
  41. // -2 : Unable to open file in binary read mode
  42. // -3 : Invalid parameters
  43. // -4 : File does not exist
  44. // -5 : Filename is too long (max. 99)
  45. // -6 : Not a valid tar file
  46. // -7 : Invalid extracted file size
  47. // -8 : Unable to create directory
  48. // -9 : Invalid archive extension
  49. // -10 : Invalid archive format
  50. // -11 : Unable to delete file (unlink)
  51. // -12 : Unable to rename file (rename)
  52. // -13 : Invalid header checksum
  53. // --------------------------------------------------------------------------------
  54. // ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED *****
  55. // --------------------------------------------------------------------------------
  56. // ----- Global variables
  57. $g_pcltar_version = "1.3";
  58. // ----- Extract extension type (.php3/.php/...)
  59. // $g_pcltar_extension = substr(strrchr(basename($PATH_TRANSLATED), '.'), 1);
  60. $g_pcltar_extension = substr(strrchr(basename(@$_SERVER["PATH_TRANSLATED"]), '.'), 1);
  61. // ----- Include other libraries
  62. // This library should be called by each script before the include of PhpZip
  63. // Library in order to limit the potential 'lib' directory path problem.
  64. if (!defined("PCLERROR_LIB"))
  65. {
  66. include($g_pcltar_lib_dir."/pclerror.lib.".$g_pcltar_extension);
  67. }
  68. if (!defined("PCLTRACE_LIB"))
  69. {
  70. include($g_pcltar_lib_dir."/pcltrace.lib.".$g_pcltar_extension);
  71. }
  72. // --------------------------------------------------------------------------------
  73. // Function : PclTarCreate()
  74. // Description :
  75. // Creates a new archive with name $p_tarname containing the files and/or
  76. // directories indicated in $p_list. If the tar filename extension is
  77. // ".tar", the file will not be compressed. If it is ".tar.gz" or ".tgz"
  78. // it will be a gzip compressed tar archive.
  79. // If you want to use an other extension, you must indicate the mode in
  80. // $p_mode ("tar" or "tgz").
  81. // $p_add_dir and $p_remove_dir give you the ability to store a path
  82. // which is not the real path of the files.
  83. // Parameters :
  84. // $p_tarname : Name of an existing tar file
  85. // $p_filelist : An array containing file or directory names, or
  86. // a string containing one filename or directory name, or
  87. // a string containing a list of filenames and/or directory
  88. // names separated by spaces.
  89. // $p_mode : "tar" for normal tar archive, "tgz" for gzipped tar archive,
  90. // if $p_mode is not specified, it will be determined by the extension.
  91. // $p_add_dir : Path to add in the filename path archived
  92. // $p_remove_dir : Path to remove in the filename path archived
  93. // Return Values :
  94. // 1 on success, or an error code (see table at the beginning).
  95. // --------------------------------------------------------------------------------
  96. function PclTarCreate($p_tarname, $p_filelist="", $p_mode="", $p_add_dir="", $p_remove_dir="")
  97. {
  98. TrFctStart(__FILE__, __LINE__, "PclTarCreate", "tar=$p_tarname, file='$p_filelist', mode=$p_mode, add_dir='$p_add_dir', remove_dir='$p_remove_dir'");
  99. $v_result=1;
  100. // ----- Look for default mode
  101. if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz")))
  102. {
  103. // ----- Extract the tar format from the extension
  104. if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
  105. {
  106. // ----- Return
  107. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  108. return PclErrorCode();
  109. }
  110. // ----- Trace
  111. TrFctMessage(__FILE__, __LINE__, 1, "Auto mode selected : found $p_mode");
  112. }
  113. // ----- Look if the $p_filelist is really an array
  114. if (is_array($p_filelist))
  115. {
  116. // ----- Call the create fct
  117. $v_result = PclTarHandleCreate($p_tarname, $p_filelist, $p_mode, $p_add_dir, $p_remove_dir);
  118. }
  119. // ----- Look if the $p_filelist is a string
  120. else if (is_string($p_filelist))
  121. {
  122. // ----- Create a list with the elements from the string
  123. $v_list = explode(" ", $p_filelist);
  124. // ----- Call the create fct
  125. $v_result = PclTarHandleCreate($p_tarname, $v_list, $p_mode, $p_add_dir, $p_remove_dir);
  126. }
  127. // ----- Invalid variable
  128. else
  129. {
  130. // ----- Error log
  131. PclErrorLog(-3, "Invalid variable type p_filelist");
  132. $v_result = -3;
  133. }
  134. // ----- Return
  135. TrFctEnd(__FILE__, __LINE__, $v_result);
  136. return $v_result;
  137. }
  138. // --------------------------------------------------------------------------------
  139. // --------------------------------------------------------------------------------
  140. // Function : PclTarAdd()
  141. // Description :
  142. // PLEASE DO NOT USE ANY MORE THIS FUNCTION. Use PclTarAddList().
  143. //
  144. // This function is maintained only for compatibility reason
  145. //
  146. // Parameters :
  147. // $p_tarname : Name of an existing tar file
  148. // $p_filelist : An array containing file or directory names, or
  149. // a string containing one filename or directory name, or
  150. // a string containing a list of filenames and/or directory
  151. // names separated by spaces.
  152. // Return Values :
  153. // 1 on success,
  154. // Or an error code (see list on top).
  155. // --------------------------------------------------------------------------------
  156. function PclTarAdd($p_tarname, $p_filelist)
  157. {
  158. TrFctStart(__FILE__, __LINE__, "PclTarAdd", "tar=$p_tarname, file=$p_filelist");
  159. $v_result=1;
  160. $v_list_detail = array();
  161. // ----- Extract the tar format from the extension
  162. if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
  163. {
  164. // ----- Return
  165. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  166. return PclErrorCode();
  167. }
  168. // ----- Look if the $p_filelist is really an array
  169. if (is_array($p_filelist))
  170. {
  171. // ----- Call the add fct
  172. $v_result = PclTarHandleAppend($p_tarname, $p_filelist, $p_mode, $v_list_detail, "", "");
  173. }
  174. // ----- Look if the $p_filelist is a string
  175. else if (is_string($p_filelist))
  176. {
  177. // ----- Create a list with the elements from the string
  178. $v_list = explode(" ", $p_filelist);
  179. // ----- Call the add fct
  180. $v_result = PclTarHandleAppend($p_tarname, $v_list, $p_mode, $v_list_detail, "", "");
  181. }
  182. // ----- Invalid variable
  183. else
  184. {
  185. // ----- Error log
  186. PclErrorLog(-3, "Invalid variable type p_filelist");
  187. $v_result = -3;
  188. }
  189. // ----- Cleaning
  190. unset($v_list_detail);
  191. // ----- Return
  192. TrFctEnd(__FILE__, __LINE__, $v_result);
  193. return $v_result;
  194. }
  195. // --------------------------------------------------------------------------------
  196. // --------------------------------------------------------------------------------
  197. // Function : PclTarAddList()
  198. // Description :
  199. // Add a list of files or directories ($p_filelist) in the tar archive $p_tarname.
  200. // The list can be an array of file/directory names or a string with names
  201. // separated by one space.
  202. // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
  203. // different from the real path of the file. This is usefull if you want to have PclTar
  204. // running in any directory, and memorize relative path from an other directory.
  205. // If $p_mode is not set it will be automatically computed from the $p_tarname
  206. // extension (.tar, .tar.gz or .tgz).
  207. // Parameters :
  208. // $p_tarname : Name of an existing tar file
  209. // $p_filelist : An array containing file or directory names, or
  210. // a string containing one filename or directory name, or
  211. // a string containing a list of filenames and/or directory
  212. // names separated by spaces.
  213. // $p_add_dir : Path to add in the filename path archived
  214. // $p_remove_dir : Path to remove in the filename path archived
  215. // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
  216. // Return Values :
  217. // 1 on success,
  218. // Or an error code (see list on top).
  219. // --------------------------------------------------------------------------------
  220. function PclTarAddList($p_tarname, $p_filelist, $p_add_dir="", $p_remove_dir="", $p_mode="")
  221. {
  222. TrFctStart(__FILE__, __LINE__, "PclTarAddList", "tar=$p_tarname, file=$p_filelist, p_add_dir='$p_add_dir', p_remove_dir='$p_remove_dir', mode=$p_mode");
  223. $v_result=1;
  224. $p_list_detail = array();
  225. // ----- Extract the tar format from the extension
  226. if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz")))
  227. {
  228. if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
  229. {
  230. // ----- Return
  231. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  232. return PclErrorCode();
  233. }
  234. }
  235. // ----- Look if the $p_filelist is really an array
  236. if (is_array($p_filelist))
  237. {
  238. // ----- Call the add fct
  239. $v_result = PclTarHandleAppend($p_tarname, $p_filelist, $p_mode, $p_list_detail, $p_add_dir, $p_remove_dir);
  240. }
  241. // ----- Look if the $p_filelist is a string
  242. else if (is_string($p_filelist))
  243. {
  244. // ----- Create a list with the elements from the string
  245. $v_list = explode(" ", $p_filelist);
  246. // ----- Call the add fct
  247. $v_result = PclTarHandleAppend($p_tarname, $v_list, $p_mode, $p_list_detail, $p_add_dir, $p_remove_dir);
  248. }
  249. // ----- Invalid variable
  250. else
  251. {
  252. // ----- Error log
  253. PclErrorLog(-3, "Invalid variable type p_filelist");
  254. $v_result = -3;
  255. }
  256. // ----- Return
  257. if ($v_result != 1)
  258. {
  259. TrFctEnd(__FILE__, __LINE__, 0);
  260. return 0;
  261. }
  262. TrFctEnd(__FILE__, __LINE__, $p_list_detail);
  263. return $p_list_detail;
  264. }
  265. // --------------------------------------------------------------------------------
  266. // --------------------------------------------------------------------------------
  267. // Function : PclTarList()
  268. // Description :
  269. // Gives the list of all the files present in the tar archive $p_tarname.
  270. // The list is the function result, it will be 0 on error.
  271. // Depending on the $p_tarname extension (.tar, .tar.gz or .tgz) the
  272. // function will determine the type of the archive.
  273. // Parameters :
  274. // $p_tarname : Name of an existing tar file
  275. // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
  276. // Return Values :
  277. // 0 on error (Use PclErrorCode() and PclErrorString() for more info)
  278. // or
  279. // An array containing file properties. Each file properties is an array of
  280. // properties.
  281. // The properties (array field names) are :
  282. // filename, size, mode, uid, gid, mtime, typeflag, status
  283. // Exemple : $v_list = PclTarList("my.tar");
  284. // for ($i=0; $i<sizeof($v_list); $i++)
  285. // echo "Filename :'".$v_list[$i][filename]."'<br>";
  286. // --------------------------------------------------------------------------------
  287. function PclTarList($p_tarname, $p_mode="")
  288. {
  289. TrFctStart(__FILE__, __LINE__, "PclTarList", "tar=$p_tarname, mode='$p_mode'");
  290. $v_result=1;
  291. // ----- Extract the tar format from the extension
  292. if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz")))
  293. {
  294. if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
  295. {
  296. // ----- Return
  297. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  298. return 0;
  299. }
  300. }
  301. // ----- Call the extracting fct
  302. $p_list = array();
  303. if (($v_result = PclTarHandleExtract($p_tarname, 0, $p_list, "list", "", $p_mode, "")) != 1)
  304. {
  305. unset($p_list);
  306. TrFctEnd(__FILE__, __LINE__, 0, PclErrorString());
  307. return(0);
  308. }
  309. // ----- Return
  310. TrFctEnd(__FILE__, __LINE__, $p_list);
  311. return $p_list;
  312. }
  313. // --------------------------------------------------------------------------------
  314. // --------------------------------------------------------------------------------
  315. // Function : PclTarExtract()
  316. // Description :
  317. // Extract all the files present in the archive $p_tarname, in the directory
  318. // $p_path. The relative path of the archived files are keep and become
  319. // relative to $p_path.
  320. // If a file with the same name already exists it will be replaced.
  321. // If the path to the file does not exist, it will be created.
  322. // Depending on the $p_tarname extension (.tar, .tar.gz or .tgz) the
  323. // function will determine the type of the archive.
  324. // Parameters :
  325. // $p_tarname : Name of an existing tar file.
  326. // $p_path : Path where the files will be extracted. The files will use
  327. // their memorized path from $p_path.
  328. // If $p_path is "", files will be extracted in "./".
  329. // $p_remove_path : Path to remove (from the file memorized path) while writing the
  330. // extracted files. If the path does not match the file path,
  331. // the file is extracted with its memorized path.
  332. // $p_path and $p_remove_path are commulative.
  333. // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
  334. // Return Values :
  335. // Same as PclTarList()
  336. // --------------------------------------------------------------------------------
  337. function PclTarExtract($p_tarname, $p_path="./", $p_remove_path="", $p_mode="")
  338. {
  339. TrFctStart(__FILE__, __LINE__, "PclTarExtract", "tar='$p_tarname', path='$p_path', remove_path='$p_remove_path', mode='$p_mode'");
  340. $v_result=1;
  341. // ----- Extract the tar format from the extension
  342. if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz")))
  343. {
  344. if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
  345. {
  346. // ----- Return
  347. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  348. return 0;
  349. }
  350. }
  351. // ----- Call the extracting fct
  352. if (($v_result = PclTarHandleExtract($p_tarname, 0, $p_list, "complete", $p_path, $p_mode, $p_remove_path)) != 1)
  353. {
  354. TrFctEnd(__FILE__, __LINE__, 0, PclErrorString());
  355. return(0);
  356. }
  357. // ----- Return
  358. TrFctEnd(__FILE__, __LINE__, $p_list);
  359. return $p_list;
  360. }
  361. // --------------------------------------------------------------------------------
  362. // --------------------------------------------------------------------------------
  363. // Function : PclTarExtractList()
  364. // Description :
  365. // Extract the files present in the archive $p_tarname and specified in
  366. // $p_filelist, in the directory
  367. // $p_path. The relative path of the archived files are keep and become
  368. // relative to $p_path.
  369. // If a directory is spécified in the list, all the files from this directory
  370. // will be extracted.
  371. // If a file with the same name already exists it will be replaced.
  372. // If the path to the file does not exist, it will be created.
  373. // Depending on the $p_tarname extension (.tar, .tar.gz or .tgz) the
  374. // function will determine the type of the archive.
  375. // Parameters :
  376. // $p_tarname : Name of an existing tar file
  377. // $p_filelist : An array containing file or directory names, or
  378. // a string containing one filename or directory name, or
  379. // a string containing a list of filenames and/or directory
  380. // names separated by spaces.
  381. // $p_path : Path where the files will be extracted. The files will use
  382. // their memorized path from $p_path.
  383. // If $p_path is "", files will be extracted in "./".
  384. // $p_remove_path : Path to remove (from the file memorized path) while writing the
  385. // extracted files. If the path does not match the file path,
  386. // the file is extracted with its memorized path.
  387. // $p_path and $p_remove_path are commulative.
  388. // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
  389. // Return Values :
  390. // Same as PclTarList()
  391. // --------------------------------------------------------------------------------
  392. function PclTarExtractList($p_tarname, $p_filelist, $p_path="./", $p_remove_path="", $p_mode="")
  393. {
  394. TrFctStart(__FILE__, __LINE__, "PclTarExtractList", "tar=$p_tarname, list, path=$p_path, remove_path='$p_remove_path', mode='$p_mode'");
  395. $v_result=1;
  396. // ----- Extract the tar format from the extension
  397. if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz")))
  398. {
  399. if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
  400. {
  401. // ----- Return
  402. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  403. return 0;
  404. }
  405. }
  406. // ----- Look if the $p_filelist is really an array
  407. if (is_array($p_filelist))
  408. {
  409. // ----- Call the extracting fct
  410. if (($v_result = PclTarHandleExtract($p_tarname, $p_filelist, $p_list, "partial", $p_path, $v_tar_mode, $p_remove_path)) != 1)
  411. {
  412. TrFctEnd(__FILE__, __LINE__, 0, PclErrorString());
  413. return(0);
  414. }
  415. }
  416. // ----- Look if the $p_filelist is a string
  417. else if (is_string($p_filelist))
  418. {
  419. // ----- Create a list with the elements from the string
  420. $v_list = explode(" ", $p_filelist);
  421. // ----- Call the extracting fct
  422. if (($v_result = PclTarHandleExtract($p_tarname, $v_list, $p_list, "partial", $p_path, $v_tar_mode, $p_remove_path)) != 1)
  423. {
  424. TrFctEnd(__FILE__, __LINE__, 0, PclErrorString());
  425. return(0);
  426. }
  427. }
  428. // ----- Invalid variable
  429. else
  430. {
  431. // ----- Error log
  432. PclErrorLog(-3, "Invalid variable type p_filelist");
  433. // ----- Return
  434. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  435. return 0;
  436. }
  437. // ----- Return
  438. TrFctEnd(__FILE__, __LINE__, $p_list);
  439. return $p_list;
  440. }
  441. // --------------------------------------------------------------------------------
  442. // --------------------------------------------------------------------------------
  443. // Function : PclTarExtractIndex()
  444. // Description :
  445. // Extract the files present in the archive $p_tarname and specified at
  446. // the indexes in $p_index, in the directory
  447. // $p_path. The relative path of the archived files are keep and become
  448. // relative to $p_path.
  449. // If a directory is specified in the list, the directory only is created. All
  450. // the file stored in this archive for this directory
  451. // are not extracted.
  452. // If a file with the same name already exists it will be replaced.
  453. // If the path to the file does not exist, it will be created.
  454. // Depending on the $p_tarname extension (.tar, .tar.gz or .tgz) the
  455. // function will determine the type of the archive.
  456. // Parameters :
  457. // $p_tarname : Name of an existing tar file
  458. // $p_index : A single index (integer) or a string of indexes of files to
  459. // extract. The form of the string is "0,4-6,8-12" with only numbers
  460. // and '-' for range or ',' to separate ranges. No spaces or ';'
  461. // are allowed.
  462. // $p_path : Path where the files will be extracted. The files will use
  463. // their memorized path from $p_path.
  464. // If $p_path is "", files will be extracted in "./".
  465. // $p_remove_path : Path to remove (from the file memorized path) while writing the
  466. // extracted files. If the path does not match the file path,
  467. // the file is extracted with its memorized path.
  468. // $p_path and $p_remove_path are commulative.
  469. // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
  470. // Return Values :
  471. // Same as PclTarList()
  472. // --------------------------------------------------------------------------------
  473. function PclTarExtractIndex($p_tarname, $p_index, $p_path="./", $p_remove_path="", $p_mode="")
  474. {
  475. TrFctStart(__FILE__, __LINE__, "PclTarExtractIndex", "tar=$p_tarname, index='$p_index', path=$p_path, remove_path='$p_remove_path', mode='$p_mode'");
  476. $v_result=1;
  477. // ----- Extract the tar format from the extension
  478. if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz")))
  479. {
  480. if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
  481. {
  482. // ----- Return
  483. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  484. return 0;
  485. }
  486. }
  487. // ----- Look if the $p_index is really an integer
  488. if (is_integer($p_index))
  489. {
  490. // ----- Call the extracting fct
  491. if (($v_result = PclTarHandleExtractByIndexList($p_tarname, "$p_index", $p_list, $p_path, $p_remove_path, $v_tar_mode)) != 1)
  492. {
  493. TrFctEnd(__FILE__, __LINE__, 0, PclErrorString());
  494. return(0);
  495. }
  496. }
  497. // ----- Look if the $p_filelist is a string
  498. else if (is_string($p_index))
  499. {
  500. // ----- Call the extracting fct
  501. if (($v_result = PclTarHandleExtractByIndexList($p_tarname, $p_index, $p_list, $p_path, $p_remove_path, $v_tar_mode)) != 1)
  502. {
  503. TrFctEnd(__FILE__, __LINE__, 0, PclErrorString());
  504. return(0);
  505. }
  506. }
  507. // ----- Invalid variable
  508. else
  509. {
  510. // ----- Error log
  511. PclErrorLog(-3, "Invalid variable type $p_index");
  512. // ----- Return
  513. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  514. return 0;
  515. }
  516. // ----- Return
  517. TrFctEnd(__FILE__, __LINE__, $p_list);
  518. return $p_list;
  519. }
  520. // --------------------------------------------------------------------------------
  521. // --------------------------------------------------------------------------------
  522. // Function : PclTarDelete()
  523. // Description :
  524. // This function deletes from the archive $p_tarname the files which are listed
  525. // in $p_filelist. $p_filelist can be a string with file names separated by
  526. // spaces, or an array containing the file names.
  527. // Parameters :
  528. // $p_tarname : Name of an existing tar file
  529. // $p_filelist : An array or a string containing file names to remove from the
  530. // archive.
  531. // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
  532. // Return Values :
  533. // List of the files which are kept in the archive (same format as PclTarList())
  534. // --------------------------------------------------------------------------------
  535. function PclTarDelete($p_tarname, $p_filelist, $p_mode="")
  536. {
  537. TrFctStart(__FILE__, __LINE__, "PclTarDelete", "tar='$p_tarname', list='$p_filelist', mode='$p_mode'");
  538. $v_result=1;
  539. // ----- Extract the tar format from the extension
  540. if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz")))
  541. {
  542. if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
  543. {
  544. // ----- Return
  545. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  546. return 0;
  547. }
  548. }
  549. // ----- Look if the $p_filelist is really an array
  550. if (is_array($p_filelist))
  551. {
  552. // ----- Call the extracting fct
  553. if (($v_result = PclTarHandleDelete($p_tarname, $p_filelist, $p_list, $p_mode)) != 1)
  554. {
  555. TrFctEnd(__FILE__, __LINE__, 0, PclErrorString());
  556. return(0);
  557. }
  558. }
  559. // ----- Look if the $p_filelist is a string
  560. else if (is_string($p_filelist))
  561. {
  562. // ----- Create a list with the elements from the string
  563. $v_list = explode(" ", $p_filelist);
  564. // ----- Call the extracting fct
  565. if (($v_result = PclTarHandleDelete($p_tarname, $v_list, $p_list, $p_mode)) != 1)
  566. {
  567. TrFctEnd(__FILE__, __LINE__, 0, PclErrorString());
  568. return(0);
  569. }
  570. }
  571. // ----- Invalid variable
  572. else
  573. {
  574. // ----- Error log
  575. PclErrorLog(-3, "Invalid variable type p_filelist");
  576. // ----- Return
  577. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  578. return 0;
  579. }
  580. // ----- Return
  581. TrFctEnd(__FILE__, __LINE__, $p_list);
  582. return $p_list;
  583. }
  584. // --------------------------------------------------------------------------------
  585. // --------------------------------------------------------------------------------
  586. // Function : PclTarUpdate()
  587. // Description :
  588. // This function updates the files in $p_filelist which are already in the
  589. // $p_tarname archive with an older last modified date. If the file does not
  590. // exist, it is added at the end of the archive.
  591. // Parameters :
  592. // $p_tarname : Name of an existing tar file
  593. // $p_filelist : An array or a string containing file names to update from the
  594. // archive.
  595. // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
  596. // Return Values :
  597. // List of the files contained in the archive. The field status contains
  598. // "updated", "not_updated", "added" or "ok" for the files not concerned.
  599. // --------------------------------------------------------------------------------
  600. function PclTarUpdate($p_tarname, $p_filelist, $p_mode="", $p_add_dir="", $p_remove_dir="")
  601. {
  602. TrFctStart(__FILE__, __LINE__, "PclTarUpdate", "tar='$p_tarname', list='$p_filelist', mode='$p_mode'");
  603. $v_result=1;
  604. // ----- Extract the tar format from the extension
  605. if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz")))
  606. {
  607. if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
  608. {
  609. // ----- Return
  610. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  611. return 0;
  612. }
  613. }
  614. // ----- Look if the $p_filelist is really an array
  615. if (is_array($p_filelist))
  616. {
  617. // ----- Call the extracting fct
  618. if (($v_result = PclTarHandleUpdate($p_tarname, $p_filelist, $p_list, $p_mode, $p_add_dir, $p_remove_dir)) != 1)
  619. {
  620. TrFctEnd(__FILE__, __LINE__, 0, PclErrorString());
  621. return(0);
  622. }
  623. }
  624. // ----- Look if the $p_filelist is a string
  625. else if (is_string($p_filelist))
  626. {
  627. // ----- Create a list with the elements from the string
  628. $v_list = explode(" ", $p_filelist);
  629. // ----- Call the extracting fct
  630. if (($v_result = PclTarHandleUpdate($p_tarname, $v_list, $p_list, $p_mode, $p_add_dir, $p_remove_dir)) != 1)
  631. {
  632. TrFctEnd(__FILE__, __LINE__, 0, PclErrorString());
  633. return(0);
  634. }
  635. }
  636. // ----- Invalid variable
  637. else
  638. {
  639. // ----- Error log
  640. PclErrorLog(-3, "Invalid variable type p_filelist");
  641. // ----- Return
  642. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  643. return 0;
  644. }
  645. // ----- Return
  646. TrFctEnd(__FILE__, __LINE__, $p_list);
  647. return $p_list;
  648. }
  649. // --------------------------------------------------------------------------------
  650. // --------------------------------------------------------------------------------
  651. // Function : PclTarMerge()
  652. // Description :
  653. // This function add the content of $p_tarname_add at the end of $p_tarname.
  654. // Parameters :
  655. // $p_tarname : Name of an existing tar file
  656. // $p_tarname_add : Name of an existing tar file taht will be added at the end
  657. // of $p_tarname.
  658. // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
  659. // $p_mode_add : 'tar' or 'tgz', if not set, will be determined by $p_tarname_add
  660. // extension
  661. // Return Values :
  662. // List of the files contained in the archive. The field status contains
  663. // "updated", "not_updated", "added" or "ok" for the files not concerned.
  664. // --------------------------------------------------------------------------------
  665. function PclTarMerge($p_tarname, $p_tarname_add, $p_mode="", $p_mode_add="")
  666. {
  667. TrFctStart(__FILE__, __LINE__, "PclTarMerge", "tar='$p_tarname', tar_add='$p_tarname_add', mode='$p_mode', mode_add='$p_mode_add'");
  668. $v_result=1;
  669. // ----- Check the parameters
  670. if (($p_tarname == "") || ($p_tarname_add == ""))
  671. {
  672. // ----- Error log
  673. PclErrorLog(-3, "Invalid empty archive name");
  674. // ----- Return
  675. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  676. return PclErrorCode();
  677. }
  678. // ----- Extract the tar format from the extension
  679. if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz")))
  680. {
  681. if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
  682. {
  683. // ----- Return
  684. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  685. return 0;
  686. }
  687. }
  688. if (($p_mode_add == "") || (($p_mode_add!="tar") && ($p_mode_add!="tgz")))
  689. {
  690. if (($p_mode_add = PclTarHandleExtension($p_tarname_add)) == "")
  691. {
  692. // ----- Return
  693. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  694. return 0;
  695. }
  696. }
  697. // ----- Clear filecache
  698. clearstatcache();
  699. // ----- Check the file size
  700. if ((!is_file($p_tarname)) ||
  701. (((($v_size = filesize($p_tarname)) % 512) != 0) && ($p_mode=="tar")))
  702. {
  703. // ----- Error log
  704. if (!is_file($p_tarname))
  705. PclErrorLog(-4, "Archive '$p_tarname' does not exist");
  706. else
  707. PclErrorLog(-6, "Archive '$p_tarname' has invalid size ".filesize($p_tarname)."(not a 512 block multiple)");
  708. // ----- Return
  709. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  710. return PclErrorCode();
  711. }
  712. if ((!is_file($p_tarname_add)) ||
  713. (((($v_size_add = filesize($p_tarname_add)) % 512) != 0) && ($p_mode_add=="tar")))
  714. {
  715. // ----- Error log
  716. if (!is_file($p_tarname_add))
  717. PclErrorLog(-4, "Archive '$p_tarname_add' does not exist");
  718. else
  719. PclErrorLog(-6, "Archive '$p_tarname_add' has invalid size ".filesize($p_tarname_add)."(not a 512 block multiple)");
  720. // ----- Return
  721. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  722. return PclErrorCode();
  723. }
  724. // ----- Look for compressed archive
  725. if ($p_mode == "tgz")
  726. {
  727. // ----- Open the file in read mode
  728. if (($p_tar = @gzopen($p_tarname, "rb")) == 0)
  729. {
  730. // ----- Error log
  731. PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode");
  732. // ----- Return
  733. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  734. return PclErrorCode();
  735. }
  736. // ----- Open a temporary file in write mode
  737. $v_temp_tarname = uniqid("pcltar-").".tmp";
  738. TrFctMessage(__FILE__, __LINE__, 2, "Creating temporary archive file $v_temp_tarname");
  739. if (($v_temp_tar = @gzopen($v_temp_tarname, "wb")) == 0)
  740. {
  741. // ----- Close tar file
  742. gzclose($p_tar);
  743. // ----- Error log
  744. PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode");
  745. // ----- Return
  746. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  747. return PclErrorCode();
  748. }
  749. // ----- Read the first 512 bytes block
  750. $v_buffer = gzread($p_tar, 512);
  751. // ----- Read the following blocks but not the last one
  752. if (!gzeof($p_tar))
  753. {
  754. TrFctMessage(__FILE__, __LINE__, 3, "More than one 512 block file");
  755. $i=1;
  756. // ----- Read new 512 block and write the already read
  757. do{
  758. // ----- Write the already read block
  759. $v_binary_data = pack("a512", "$v_buffer");
  760. gzputs($v_temp_tar, $v_binary_data);
  761. $i++;
  762. TrFctMessage(__FILE__, __LINE__, 3, "Reading block $i");
  763. // ----- Read next block
  764. $v_buffer = gzread($p_tar, 512);
  765. } while (!gzeof($p_tar));
  766. TrFctMessage(__FILE__, __LINE__, 3, "$i 512 bytes blocks");
  767. }
  768. }
  769. // ----- Look for uncompressed tar file
  770. else if ($p_mode=="tar")
  771. {
  772. // ----- Open the tar file
  773. if (($p_tar = fopen($p_tarname, "r+b")) == 0)
  774. {
  775. // ----- Error log
  776. PclErrorLog(-1, "Unable to open file '$p_tarname' in binary write mode");
  777. // ----- Return
  778. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  779. return PclErrorCode();
  780. }
  781. // ----- Go to the beginning of last block
  782. TrFctMessage(__FILE__, __LINE__, 4, "Position before :".($p_mode=="tar"?ftell($p_tar):gztell($p_tar)));
  783. fseek($p_tar, $v_size-512);
  784. TrFctMessage(__FILE__, __LINE__, 4, "Position after :".($p_mode=="tar"?ftell($p_tar):gztell($p_tar)));
  785. }
  786. // ----- Look for unknown type
  787. else
  788. {
  789. // ----- Error log
  790. PclErrorLog(-3, "Invalid tar mode $p_mode");
  791. // ----- Return
  792. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  793. return PclErrorCode();
  794. }
  795. // ----- Look for type of archive to add
  796. if ($p_mode_add == "tgz")
  797. {
  798. TrFctMessage(__FILE__, __LINE__, 4, "Opening file $p_tarname_add");
  799. // ----- Open the file in read mode
  800. if (($p_tar_add = @gzopen($p_tarname_add, "rb")) == 0)
  801. {
  802. // ----- Error log
  803. PclErrorLog(-2, "Unable to open file '$p_tarname_add' in binary read mode");
  804. // ----- Return
  805. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  806. return PclErrorCode();
  807. }
  808. // ----- Read the first 512 bytes block
  809. $v_buffer = gzread($p_tar_add, 512);
  810. // ----- Read the following blocks but not the last one
  811. if (!gzeof($p_tar_add))
  812. {
  813. TrFctMessage(__FILE__, __LINE__, 3, "More than one 512 block file");
  814. $i=1;
  815. // ----- Read new 512 block and write the already read
  816. do{
  817. // ----- Write the already read block
  818. $v_binary_data = pack("a512", "$v_buffer");
  819. if ($p_mode=="tar")
  820. fputs($p_tar, $v_binary_data);
  821. else
  822. gzputs($v_temp_tar, $v_binary_data);
  823. $i++;
  824. TrFctMessage(__FILE__, __LINE__, 3, "Reading block $i");
  825. // ----- Read next block
  826. $v_buffer = gzread($p_tar_add, 512);
  827. } while (!gzeof($p_tar_add));
  828. TrFctMessage(__FILE__, __LINE__, 3, "$i 512 bytes blocks");
  829. }
  830. // ----- Close the files
  831. gzclose($p_tar_add);
  832. }
  833. // ----- Look for uncompressed tar file
  834. else if ($p_mode=="tar")
  835. {
  836. // ----- Open the file in read mode
  837. if (($p_tar_add = @fopen($p_tarname_add, "rb")) == 0)
  838. {
  839. // ----- Error log
  840. PclErrorLog(-2, "Unable to open file '$p_tarname_add' in binary read mode");
  841. // ----- Return
  842. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  843. return PclErrorCode();
  844. }
  845. // ----- Read the first 512 bytes block
  846. $v_buffer = fread($p_tar_add, 512);
  847. // ----- Read the following blocks but not the last one
  848. if (!feof($p_tar_add))
  849. {
  850. TrFctMessage(__FILE__, __LINE__, 3, "More than one 512 block file");
  851. $i=1;
  852. // ----- Read new 512 block and write the already read
  853. do{
  854. // ----- Write the already read block
  855. $v_binary_data = pack("a512", "$v_buffer");
  856. if ($p_mode=="tar")
  857. fputs($p_tar, $v_binary_data);
  858. else
  859. gzputs($v_temp_tar, $v_binary_data);
  860. $i++;
  861. TrFctMessage(__FILE__, __LINE__, 3, "Reading block $i");
  862. // ----- Read next block
  863. $v_buffer = fread($p_tar_add, 512);
  864. } while (!feof($p_tar_add));
  865. TrFctMessage(__FILE__, __LINE__, 3, "$i 512 bytes blocks");
  866. }
  867. // ----- Close the files
  868. fclose($p_tar_add);
  869. }
  870. // ----- Call the footer of the tar archive
  871. $v_result = PclTarHandleFooter($p_tar, $p_mode);
  872. // ----- Look for closing compressed archive
  873. if ($p_mode == "tgz")
  874. {
  875. // ----- Close the files
  876. gzclose($p_tar);
  877. gzclose($v_temp_tar);
  878. // ----- Unlink tar file
  879. if (!@unlink($p_tarname))
  880. {
  881. // ----- Error log
  882. PclErrorLog(-11, "Error while deleting archive name $p_tarname");
  883. }
  884. // ----- Rename tar file
  885. if (!@rename($v_temp_tarname, $p_tarname))
  886. {
  887. // ----- Error log
  888. PclErrorLog(-12, "Error while renaming temporary file $v_temp_tarname to archive name $p_tarname");
  889. // ----- Return
  890. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  891. return PclErrorCode();
  892. }
  893. // ----- Return
  894. TrFctEnd(__FILE__, __LINE__, $v_result);
  895. return $v_result;
  896. }
  897. // ----- Look for closing uncompressed tar file
  898. else if ($p_mode=="tar")
  899. {
  900. // ----- Close the tarfile
  901. fclose($p_tar);
  902. }
  903. // ----- Return
  904. TrFctEnd(__FILE__, __LINE__, $v_result);
  905. return $v_result;
  906. }
  907. // --------------------------------------------------------------------------------
  908. // --------------------------------------------------------------------------------
  909. // ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
  910. // ***** *****
  911. // ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY *****
  912. // --------------------------------------------------------------------------------
  913. // --------------------------------------------------------------------------------
  914. // Function : PclTarHandleCreate()
  915. // Description :
  916. // Parameters :
  917. // $p_tarname : Name of the tar file
  918. // $p_list : An array containing the file or directory names to add in the tar
  919. // $p_mode : "tar" for normal tar archive, "tgz" for gzipped tar archive
  920. // Return Values :
  921. // --------------------------------------------------------------------------------
  922. function PclTarHandleCreate($p_tarname, $p_list, $p_mode, $p_add_dir="", $p_remove_dir="")
  923. {
  924. TrFctStart(__FILE__, __LINE__, "PclTarHandleCreate", "tar=$p_tarname, list, mode=$p_mode, add_dir='$p_add_dir', remove_dir='$p_remove_dir'");
  925. $v_result=1;
  926. $v_list_detail = array();
  927. // ----- Check the parameters
  928. if (($p_tarname == "") || (($p_mode != "tar") && ($p_mode != "tgz")))
  929. {
  930. // ----- Error log
  931. if ($p_tarname == "")
  932. PclErrorLog(-3, "Invalid empty archive name");
  933. else
  934. PclErrorLog(-3, "Unknown mode '$p_mode'");
  935. // ----- Return
  936. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  937. return PclErrorCode();
  938. }
  939. // ----- Look for tar file
  940. if ($p_mode == "tar")
  941. {
  942. // ----- Open the tar file
  943. if (($p_tar = fopen($p_tarname, "wb")) == 0)
  944. {
  945. // ----- Error log
  946. PclErrorLog(-1, "Unable to open file [$p_tarname] in binary write mode");
  947. // ----- Return
  948. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  949. return PclErrorCode();
  950. }
  951. // ----- Call the adding fct inside the tar
  952. if (($v_result = PclTarHandleAddList($p_tar, $p_list, $p_mode, $v_list_detail, $p_add_dir, $p_remove_dir)) == 1)
  953. {
  954. // ----- Call the footer of the tar archive
  955. $v_result = PclTarHandleFooter($p_tar, $p_mode);
  956. }
  957. // ----- Close the tarfile
  958. fclose($p_tar);
  959. }
  960. // ----- Look for tgz file
  961. else
  962. {
  963. // ----- Open the tar file
  964. if (($p_tar = @gzopen($p_tarname, "wb")) == 0)
  965. {
  966. // ----- Error log
  967. PclErrorLog(-1, "Unable to open file [$p_tarname] in binary write mode");
  968. // ----- Return
  969. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  970. return PclErrorCode();
  971. }
  972. // ----- Call the adding fct inside the tar
  973. if (($v_result = PclTarHandleAddList($p_tar, $p_list, $p_mode, $v_list_detail, $p_add_dir, $p_remove_dir)) == 1)
  974. {
  975. // ----- Call the footer of the tar archive
  976. $v_result = PclTarHandleFooter($p_tar, $p_mode);
  977. }
  978. // ----- Close the tarfile
  979. gzclose($p_tar);
  980. }
  981. // ----- Return
  982. TrFctEnd(__FILE__, __LINE__, $v_result);
  983. return $v_result;
  984. }
  985. // --------------------------------------------------------------------------------
  986. // --------------------------------------------------------------------------------
  987. // Function : PclTarHandleAppend()
  988. // Description :
  989. // Parameters :
  990. // $p_tarname : Name of the tar file
  991. // $p_list : An array containing the file or directory names to add in the tar
  992. // $p_mode : "tar" for normal tar archive, "tgz" for gzipped tar archive
  993. // Return Values :
  994. // --------------------------------------------------------------------------------
  995. function PclTarHandleAppend($p_tarname, $p_list, $p_mode, &$p_list_detail, $p_add_dir, $p_remove_dir)
  996. {
  997. TrFctStart(__FILE__, __LINE__, "PclTarHandleAppend", "tar=$p_tarname, list, mode=$p_mode");
  998. $v_result=1;
  999. // ----- Check the parameters
  1000. if ($p_tarname == "")
  1001. {
  1002. // ----- Error log
  1003. PclErrorLog(-3, "Invalid empty archive name");
  1004. // ----- Return
  1005. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  1006. return PclErrorCode();
  1007. }
  1008. clearstatcache();
  1009. // ----- Check the file size
  1010. if ((!is_file($p_tarname)) ||
  1011. (((($v_size = filesize($p_tarname)) % 512) != 0) && ($p_mode=="tar")))
  1012. {
  1013. // ----- Error log
  1014. if (!is_file($p_tarname))
  1015. PclErrorLog(-4, "Archive '$p_tarname' does not exist");
  1016. else
  1017. PclErrorLog(-6, "Archive '$p_tarname' has invalid size ".filesize($p_tarname)."(not a 512 block multiple)");
  1018. // ----- Return
  1019. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  1020. return PclErrorCode();
  1021. }
  1022. // ----- Look for compressed archive
  1023. if ($p_mode == "tgz")
  1024. {
  1025. // ----- Open the file in read mode
  1026. if (($p_tar = @gzopen($p_tarname, "rb")) == 0)
  1027. {
  1028. // ----- Error log
  1029. PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode");
  1030. // ----- Return
  1031. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  1032. return PclErrorCode();
  1033. }
  1034. // ----- Open a temporary file in write mode
  1035. $v_temp_tarname = uniqid("pcltar-").".tmp";
  1036. TrFctMessage(__FILE__, __LINE__, 2, "Creating temporary archive file $v_temp_tarname");
  1037. if (($v_temp_tar = @gzopen($v_temp_tarname, "wb")) == 0)
  1038. {
  1039. // ----- Close tar file
  1040. gzclose($p_tar);
  1041. // ----- Error log
  1042. PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode");
  1043. // ----- Return
  1044. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  1045. return PclErrorCode();
  1046. }
  1047. // ----- Read the first 512 bytes block
  1048. $v_buffer = gzread($p_tar, 512);
  1049. // ----- Read the following blocks but not the last one
  1050. if (!gzeof($p_tar))
  1051. {
  1052. TrFctMessage(__FILE__, __LINE__, 3, "More than one 512 block file");
  1053. $i=1;
  1054. // ----- Read new 512 block and write the already read
  1055. do{
  1056. // ----- Write the already read block
  1057. $v_binary_data = pack("a512", "$v_buffer");
  1058. gzputs($v_temp_tar, $v_binary_data);
  1059. $i++;
  1060. TrFctMessage(__FILE__, __LINE__, 3, "Reading block $i");
  1061. // ----- Read next block
  1062. $v_buffer = gzread($p_tar, 512);
  1063. } while (!gzeof($p_tar));
  1064. TrFctMessage(__FILE__, __LINE__, 3, "$i 512 bytes blocks");
  1065. }
  1066. // ----- Call the adding fct inside the tar
  1067. if (($v_result = PclTarHandleAddList($v_temp_tar, $p_list, $p_mode, $p_list_detail, $p_add_dir, $p_remove_dir)) == 1)
  1068. {
  1069. // ----- Call the footer of the tar archive
  1070. $v_result = PclTarHandleFooter($v_temp_tar, $p_mode);
  1071. }
  1072. // ----- Close the files
  1073. gzclose($p_tar);
  1074. gzclose($v_temp_tar);
  1075. // ----- Unlink tar file
  1076. if (!@unlink($p_tarname))
  1077. {
  1078. // ----- Error log
  1079. PclErrorLog(-11, "Error while deleting archive name $p_tarname");
  1080. }
  1081. // ----- Rename tar file
  1082. if (!@rename($v_temp_tarname, $p_tarname))
  1083. {
  1084. // ----- Error log
  1085. PclErrorLog(-12, "Error while renaming temporary file $v_temp_tarname to archive name $p_tarname");
  1086. // ----- Return
  1087. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  1088. return PclErrorCode();
  1089. }
  1090. // ----- Return
  1091. TrFctEnd(__FILE__, __LINE__, $v_result);
  1092. return $v_result;
  1093. }
  1094. // ----- Look for uncompressed tar file
  1095. else if ($p_mode=="tar")
  1096. {
  1097. // ----- Open the tar file
  1098. if (($p_tar = fopen($p_tarname, "r+b")) == 0)
  1099. {
  1100. // ----- Error log
  1101. PclErrorLog(-1, "Unable to open file '$p_tarname' in binary write mode");
  1102. // ----- Return
  1103. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  1104. return PclErrorCode();
  1105. }
  1106. // ----- Go to the beginning of last block
  1107. TrFctMessage(__FILE__, __LINE__, 4, "Position before :".($p_mode=="tar"?ftell($p_tar):gztell($p_tar)));
  1108. fseek($p_tar, $v_size-512);
  1109. TrFctMessage(__FILE__, __LINE__, 4, "Position after :".($p_mode=="tar"?ftell($p_tar):gztell($p_tar)));
  1110. // ----- Call the adding fct inside the tar
  1111. if (($v_result = PclTarHandleAddList($p_tar, $p_list, $p_mode, $p_list_detail, $p_add_dir, $p_remove_dir)) == 1)
  1112. {
  1113. // ----- Call the footer of the tar archive
  1114. $v_result = PclTarHandleFooter($p_tar, $p_mode);
  1115. }
  1116. // ----- Close the tarfile
  1117. fclose($p_tar);
  1118. }
  1119. // ----- Look for unknown type
  1120. else
  1121. {
  1122. // ----- Error log
  1123. PclErrorLog(-3, "Invalid tar mode $p_mode");
  1124. // ----- Return
  1125. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  1126. return PclErrorCode();
  1127. }
  1128. // ----- Return
  1129. TrFctEnd(__FILE__, __LINE__, $v_result);
  1130. return $v_result;
  1131. }
  1132. // --------------------------------------------------------------------------------
  1133. // --------------------------------------------------------------------------------
  1134. // Function : PclTarHandleAddList()
  1135. // Description :
  1136. // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
  1137. // different from the real path of the file. This is usefull if you want to have PclTar
  1138. // running in any directory, and memorize relative path from an other directory.
  1139. // Parameters :
  1140. // $p_tar : File descriptor of the tar archive
  1141. // $p_list : An array containing the file or directory names to add in the tar
  1142. // $p_mode : "tar" for normal tar archive, "tgz" for gzipped tar archive
  1143. // $p_list_detail : list of added files with their properties (specially the status field)
  1144. // $p_add_dir : Path to add in the filename path archived
  1145. // $p_remove_dir : Path to remove in the filename path archived
  1146. // Return Values :
  1147. // --------------------------------------------------------------------------------
  1148. function PclTarHandleAddList($p_tar, $p_list, $p_mode, &$p_list_detail, $p_add_dir, $p_remove_dir)
  1149. {
  1150. TrFctStart(__FILE__, __LINE__, "PclTarHandleAddList", "tar='$p_tar', list, mode='$p_mode', add_dir='$p_add_dir', remove_dir='$p_remove_dir'");
  1151. $v_result=1;
  1152. $v_header = array();
  1153. // ----- Recuperate the current number of elt in list
  1154. $v_nb = sizeof($p_list_detail);
  1155. // ----- Check the parameters
  1156. if ($p_tar == 0)
  1157. {
  1158. // ----- Error log
  1159. PclErrorLog(-3, "Invalid file descriptor in file ".__FILE__.", line ".__LINE__);
  1160. // ----- Return
  1161. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  1162. return PclErrorCode();
  1163. }
  1164. // ----- Check the arguments
  1165. if (sizeof($p_list) == 0)
  1166. {
  1167. // ----- Error log
  1168. PclErrorLog(-3, "Invalid file list parameter (invalid or empty list)");
  1169. // ----- Return
  1170. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  1171. return PclErrorCode();
  1172. }
  1173. // ----- Loop on the files
  1174. for ($j=0; ($j<count($p_list)) && ($v_result==1); $j++)
  1175. {
  1176. // ----- Recuperate the filename
  1177. $p_filename = $p_list[$j];
  1178. TrFctMessage(__FILE__, __LINE__, 2, "Looking for file [$p_filename]");
  1179. // ----- Skip empty file names
  1180. if ($p_filename == "")
  1181. {
  1182. TrFctMessage(__FILE__, __LINE__, 2, "Skip empty filename");
  1183. continue;
  1184. }
  1185. // ----- Check the filename
  1186. if (!file_exists($p_filename))
  1187. {
  1188. // ----- Error log
  1189. TrFctMessage(__FILE__, __LINE__, 2, "File '$p_filename' does not exists");
  1190. PclErrorLog(-4, "File '$p_filename' does not exists");
  1191. // ----- Return
  1192. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  1193. return PclErrorCode();
  1194. }
  1195. // ----- Check the path length
  1196. if (strlen($p_filename) > 99)
  1197. {
  1198. // ----- Error log
  1199. PclErrorLog(-5, "File name is too long (max. 99) : '$p_filename'");
  1200. // ----- Return
  1201. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  1202. return PclErrorCode();
  1203. }
  1204. TrFctMessage(__FILE__, __LINE__, 4, "File position before header =".($p_mode=="tar"?ftell($p_tar):gztell($p_tar)));
  1205. // ----- Add the file
  1206. if (($v_result = PclTarHandleAddFile($p_tar, $p_filename, $p_mode, $v_header, $p_add_dir, $p_remove_dir)) != 1)
  1207. {
  1208. // ----- Return status
  1209. TrFctEnd(__FILE__, __LINE__, $v_result);
  1210. return $v_result;
  1211. }
  1212. // ----- Store the file infos
  1213. $p_list_detail[$v_nb++] = $v_header;
  1214. // ----- Look for directory
  1215. if (is_dir($p_filename))
  1216. {
  1217. TrFctMessage(__FILE__, __LINE__, 2, "$p_filename is a directory");
  1218. // ----- Look for path
  1219. if ($p_filename != ".")
  1220. $v_path = $p_filename."/";
  1221. else
  1222. $v_path = "";
  1223. // ----- Read the directory for files and sub-directories
  1224. $p_hdir = opendir($p_filename);
  1225. $p_hitem = readdir($p_hdir); // '.' directory
  1226. $p_hitem = readdir($p_hdir); // '..' directory
  1227. while ($p_hitem = readdir($p_hdir))
  1228. {
  1229. // ----- Look for a file
  1230. if (is_file($v_path.$p_hitem))
  1231. {
  1232. TrFctMessage(__FILE__, __LINE__, 4, "Add the file '".$v_path.$p_hitem."'");
  1233. // ----- Add the file
  1234. if (($v_result = PclTarHandleAddFile($p_tar, $v_path.$p_hitem, $p_mode, $v_header, $p_add_dir, $p_remove_dir)) != 1)
  1235. {
  1236. // ----- Return status
  1237. TrFctEnd(__FILE__, __LINE__, $v_result);
  1238. return $v_result;
  1239. }
  1240. // ----- Store the file infos
  1241. $p_list_detail[$v_nb++] = $v_header;
  1242. }
  1243. // ----- Recursive call to PclTarHandleAddFile()
  1244. else
  1245. {
  1246. TrFctMessage(__FILE__, __LINE__, 4, "'".$v_path.$p_hitem."' is a directory");
  1247. // ----- Need an array as parameter
  1248. $p_temp_list[0] = $v_path.$p_hitem;
  1249. $v_result = PclTarHandleAddList($p_tar, $p_temp_list, $p_mode, $p_list_detail, $p_add_dir, $p_remove_dir);
  1250. }
  1251. }
  1252. // ----- Free memory for the recursive loop
  1253. unset($p_temp_list);
  1254. unset($p_hdir);
  1255. unset($p_hitem);
  1256. }
  1257. else
  1258. {
  1259. TrFctMessage(__FILE__, __LINE__, 4, "File position after blocks =".($p_mode=="tar"?ftell($p_tar):gztell($p_tar)));
  1260. }
  1261. }
  1262. // ----- Return
  1263. TrFctEnd(__FILE__, __LINE__, $v_result);
  1264. return $v_result;
  1265. }
  1266. // --------------------------------------------------------------------------------
  1267. // --------------------------------------------------------------------------------
  1268. // Function : PclTarHandleAddFile()
  1269. // Description :
  1270. // Parameters :
  1271. // Return Values :
  1272. // --------------------------------------------------------------------------------
  1273. function PclTarHandleAddFile($p_tar, $p_filename, $p_mode, &$p_header, $p_add_dir, $p_remove_dir)
  1274. {
  1275. TrFctStart(__FILE__, __LINE__, "PclTarHandleAddFile", "tar='$p_tar', filename='$p_filename', p_mode='$p_mode', add_dir='$p_add_dir', remove_dir='$p_remove_dir'");
  1276. $v_result=1;
  1277. // ----- Check the parameters
  1278. if ($p_tar == 0)
  1279. {
  1280. // ----- Error log
  1281. PclErrorLog(-3, "Invalid file descriptor in file ".__FILE__.", line ".__LINE__);
  1282. // ----- Return
  1283. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  1284. return PclErrorCode();
  1285. }
  1286. // ----- Skip empty file names
  1287. if ($p_filename == "")
  1288. {
  1289. // ----- Error log
  1290. PclErrorLog(-3, "Invalid file list parameter (invalid or empty list)");
  1291. // ----- Return
  1292. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  1293. return PclErrorCode();
  1294. }
  1295. // ----- Calculate the stored filename
  1296. $v_stored_filename = $p_filename;
  1297. if ($p_remove_dir != "")
  1298. {
  1299. if (substr($p_remove_dir, -1) != '/')
  1300. $p_remove_dir .= "/";
  1301. if ((substr($p_filename, 0, 2) == "./") || (substr($p_remove_dir, 0, 2) == "./"))
  1302. {
  1303. if ((substr($p_filename, 0, 2) == "./") && (substr($p_remove_dir, 0, 2) != "./"))
  1304. $p_remove_dir = "./".$p_remove_dir;
  1305. if ((substr($p_filename, 0, 2) != "./") && (substr($p_remove_dir, 0, 2) == "./"))
  1306. $p_remove_dir = substr($p_remove_dir, 2);
  1307. }
  1308. if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir)
  1309. {
  1310. $v_stored_filename = substr($p_filename, strlen($p_remove_dir));
  1311. TrFctMessage(__FILE__, __LINE__, 3, "Remove path '$p_remove_dir' in file '$p_filename' = '$v_stored_filename'");
  1312. }
  1313. }
  1314. if ($p_add_dir != "")
  1315. {
  1316. if (substr($p_add_dir, -1) == "/")
  1317. $v_stored_filename = $p_add_dir.$v_stored_filename;
  1318. else
  1319. $v_stored_filename = $p_add_dir."/".$v_stored_filename;
  1320. TrFctMessage(__FILE__, __LINE__, 3, "Add path '$p_add_dir' in file '$p_filename' = '$v_stored_filename'");
  1321. }
  1322. // ----- Check the path length
  1323. if (strlen($v_stored_filename) > 99)
  1324. {
  1325. // ----- Error log
  1326. PclErrorLog(-5, "Stored file name is too long (max. 99) : '$v_stored_filename'");
  1327. // ----- Return
  1328. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  1329. return PclErrorCode();
  1330. }
  1331. // ----- Look for a file
  1332. if (is_file($p_filename))
  1333. {
  1334. // ----- Open the source file
  1335. if (($v_file = fopen($p_filename, "rb")) == 0)
  1336. {
  1337. // ----- Error log
  1338. PclErrorLog(-2, "Unable to open file '$p_filename' in binary read mode");
  1339. // ----- Return
  1340. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  1341. return PclErrorCode();
  1342. }
  1343. // ----- Call the header generation
  1344. if (($v_result = PclTarHandleHeader($p_tar, $p_filename, $p_mode, $p_header, $v_stored_filename)) != 1)
  1345. {
  1346. // ----- Return status
  1347. TrFctEnd(__FILE__, __LINE__, $v_result);
  1348. return $v_result;
  1349. }
  1350. TrFctMessage(__FILE__, __LINE__, 4, "File position after header =".($p_mode=="tar"?ftell($p_tar):gztell($p_tar)));
  1351. // ----- Read the file by 512 octets blocks
  1352. $i=0;
  1353. while (($v_buffer = fread($v_file, 512)) != "")
  1354. {
  1355. $v_binary_data = pack("a512", "$v_buffer");
  1356. if ($p_mode == "tar")
  1357. fputs($p_tar, $v_binary_data);
  1358. else
  1359. gzputs($p_tar, $v_binary_data);
  1360. $i++;
  1361. }
  1362. TrFctMessage(__FILE__, __LINE__, 2, "$i 512 bytes blocks");
  1363. // ----- Close the file
  1364. fclose($v_file);
  1365. TrFctMessage(__FILE__, __LINE__, 4, "File position after blocks =".($p_mode=="tar"?ftell($p_tar):gztell($p_tar)));
  1366. }
  1367. // ----- Look for a directory
  1368. else
  1369. {
  1370. // ----- Call the header generation
  1371. if (($v_result = PclTarHandleHeader($p_tar, $p_filename, $p_mode, $p_header, $v_stored_filename)) != 1)
  1372. {
  1373. // ----- Return status
  1374. TrFctEnd(__FILE__, __LINE__, $v_result);
  1375. return $v_result;
  1376. }
  1377. TrFctMessage(__FILE__, __LINE__, 4, "File position after header =".($p_mode=="tar"?ftell($p_tar):gztell($p_tar)));
  1378. }
  1379. // ----- Return
  1380. TrFctEnd(__FILE__, __LINE__, $v_result);
  1381. return $v_result;
  1382. }
  1383. // --------------------------------------------------------------------------------
  1384. // --------------------------------------------------------------------------------
  1385. // Function : PclTarHandleHeader()
  1386. // Description :
  1387. // This function creates in the TAR $p_tar, the TAR header for the file
  1388. // $p_filename.
  1389. //
  1390. // 1. The informations needed to compose the header are recuperated and formatted
  1391. // 2. Two binary strings are composed for the first part of the header, before
  1392. // and after checksum field.
  1393. // 3. The checksum is calculated from the two binary strings
  1394. // 4. The header is write in the tar file (first binary string, binary string
  1395. // for checksum and last binary string).
  1396. // Parameters :
  1397. // $p_tar : a valid file descriptor, opened in write mode,
  1398. // $p_filename : The name of the file the header is for,
  1399. // $p_mode : The mode of the archive ("tar" or "tgz").
  1400. // $p_header : A pointer to a array where will be set the file properties
  1401. // Return Values :
  1402. // --------------------------------------------------------------------------------
  1403. function PclTarHandleHeader($p_tar, $p_filename, $p_mode, &$p_header, $p_stored_filename)
  1404. {
  1405. TrFctStart(__FILE__, __LINE__, "PclTarHandleHeader", "tar=$p_tar, file='$p_filename', mode='$p_mode', stored_filename='$p_stored_filename'");
  1406. $v_result=1;
  1407. // ----- Check the parameters
  1408. if (($p_tar == 0) || ($p_filename == ""))
  1409. {
  1410. // ----- Error log
  1411. PclErrorLog(-3, "Invalid file descriptor in file ".__FILE__.", line ".__LINE__);
  1412. // ----- Return
  1413. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  1414. return PclErrorCode();
  1415. }
  1416. // ----- Filename (reduce the path of stored name)
  1417. if ($p_stored_filename == "")
  1418. $p_stored_filename = $p_filename;
  1419. $v_reduce_filename = PclTarHandlePathReduction($p_stored_filename);
  1420. TrFctMessage(__FILE__, __LINE__, 2, "Filename (reduced) '$v_reduce_filename', strlen ".strlen($v_reduce_filename));
  1421. // ----- Get file info
  1422. $v_info = stat($p_filename);
  1423. $v_uid = sprintf("%6s ", DecOct($v_info[4]));
  1424. $v_gid = sprintf("%6s ", DecOct($v_info[5]));
  1425. TrFctMessage(__FILE__, __LINE__, 3, "uid=$v_uid, gid=$v_gid");
  1426. $v_perms = sprintf("%6s ", DecOct(fileperms($p_filename)));
  1427. TrFctMessage(__FILE__, __LINE__, 3, "file permissions $v_perms");
  1428. // ----- File mtime
  1429. $v_mtime_data = filemtime($p_filename);
  1430. TrFctMessage(__FILE__, __LINE__, 2, "File mtime : $v_mtime_data");
  1431. $v_mtime = sprintf("%11s", DecOct($v_mtime_data));
  1432. // ----- File typeflag
  1433. // '0' or '\0' is the code for regular file
  1434. // '5' is directory
  1435. if (is_dir($p_filename))
  1436. {
  1437. $v_typeflag = "5";
  1438. $v_size = 0;
  1439. }
  1440. else
  1441. {
  1442. $v_typeflag = "";
  1443. // ----- Get the file size
  1444. clearstatcache();
  1445. $v_size = filesize($p_filename);
  1446. }
  1447. TrFctMessage(__FILE__, __LINE__, 2, "File size : $v_size");
  1448. $v_size = sprintf("%11s ", DecOct($v_size));
  1449. TrFctMessage(__FILE__, __LINE__, 2, "File typeflag : $v_typeflag");
  1450. // ----- Linkname
  1451. $v_linkname = "";
  1452. // ----- Magic
  1453. $v_magic = "";
  1454. // ----- Version
  1455. $v_version = "";
  1456. // ----- uname
  1457. $v_uname = "";
  1458. // ----- gname
  1459. $v_gname = "";
  1460. // ----- devmajor
  1461. $v_devmajor = "";
  1462. // ----- devminor
  1463. $v_devminor = "";
  1464. // ----- prefix
  1465. $v_prefix = "";
  1466. // ----- Compose the binary string of the header in two parts arround the checksum position
  1467. $v_binary_data_first = pack("a100a8a8a8a12A12", $v_reduce_filename, $v_perms, $v_uid, $v_gid, $v_size, $v_mtime);
  1468. $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12", $v_typeflag, $v_linkname, $v_magic, $v_version, $v_uname, $v_gname, $v_devmajor, $v_devminor, $v_prefix, "");
  1469. // ----- Calculate the checksum
  1470. $v_checksum = 0;
  1471. // ..... First part of the header
  1472. for ($i=0; $i<148; $i++)
  1473. {
  1474. $v_checksum += ord(substr($v_binary_data_first,$i,1));
  1475. }
  1476. // ..... Ignore the checksum value and replace it by ' ' (space)
  1477. for ($i=148; $i<156; $i++)
  1478. {
  1479. $v_checksum += ord(' ');
  1480. }
  1481. // ..... Last part of the header
  1482. for ($i=156, $j=0; $i<512; $i++, $j++)
  1483. {
  1484. $v_checksum += ord(substr($v_binary_data_last,$j,1));
  1485. }
  1486. TrFctMessage(__FILE__, __LINE__, 3, "Calculated checksum : $v_checksum");
  1487. // ----- Write the first 148 bytes of the header in the archive
  1488. if ($p_mode == "tar")
  1489. fputs($p_tar, $v_binary_data_first, 148);
  1490. else
  1491. gzputs($p_tar, $v_binary_data_first, 148);
  1492. // ----- Write the calculated checksum
  1493. $v_checksum = sprintf("%6s ", DecOct($v_checksum));
  1494. $v_binary_data = pack("a8", $v_checksum);
  1495. if ($p_mode == "tar")
  1496. fputs($p_tar, $v_binary_data, 8);
  1497. else
  1498. gzputs($p_tar, $v_binary_data, 8);
  1499. // ----- Write the last 356 bytes of the header in the archive
  1500. if ($p_mode == "tar")
  1501. fputs($p_tar, $v_binary_data_last, 356);
  1502. else
  1503. gzputs($p_tar, $v_binary_data_last, 356);
  1504. // ----- Set the properties in the header "structure"
  1505. $p_header[filename] = $v_reduce_filename;
  1506. $p_header[mode] = $v_perms;
  1507. $p_header[uid] = $v_uid;
  1508. $p_header[gid] = $v_gid;
  1509. $p_header[size] = $v_size;
  1510. $p_header[mtime] = $v_mtime;
  1511. $p_header[typeflag] = $v_typeflag;
  1512. $p_header[status] = "added";
  1513. // ----- Return
  1514. TrFctEnd(__FILE__, __LINE__, $v_result);
  1515. return $v_result;
  1516. }
  1517. // --------------------------------------------------------------------------------
  1518. // --------------------------------------------------------------------------------
  1519. // Function : PclTarHandleFooter()
  1520. // Description :
  1521. // Parameters :
  1522. // Return Values :
  1523. // --------------------------------------------------------------------------------
  1524. function PclTarHandleFooter($p_tar, $p_mode)
  1525. {
  1526. TrFctStart(__FILE__, __LINE__, "PclTarHandleFooter", "tar='$p_tar', p_mode=$p_mode");
  1527. $v_result=1;
  1528. // ----- Write the last 0 filled block for end of archive
  1529. $v_binary_data = pack("a512", "");
  1530. if ($p_mode == "tar")
  1531. fputs($p_tar, $v_binary_data);
  1532. else
  1533. gzputs($p_tar, $v_binary_data);
  1534. // ----- Return
  1535. TrFctEnd(__FILE__, __LINE__, $v_result);
  1536. return $v_result;
  1537. }
  1538. // --------------------------------------------------------------------------------
  1539. // --------------------------------------------------------------------------------
  1540. // Function : PclTarHandleExtract()
  1541. // Description :
  1542. // Parameters :
  1543. // $p_tarname : Filename of the tar (or tgz) archive
  1544. // $p_file_list : An array which contains the list of files to extract, this
  1545. // array may be empty when $p_mode is 'complete'
  1546. // $p_list_detail : An array where will be placed the properties of each extracted/listed file
  1547. // $p_mode : 'complete' will extract all files from the archive,
  1548. // 'partial' will look for files in $p_file_list
  1549. // 'list' will only list the files from the archive without any extract
  1550. // $p_path : Path to add while writing the extracted files
  1551. // $p_tar_mode : 'tar' for GNU TAR archive, 'tgz' for compressed archive
  1552. // $p_remove_path : Path to remove (from the file memorized path) while writing the
  1553. // extracted files. If the path does not match the file path,
  1554. // the file is extracted with its memorized path.
  1555. // $p_remove_path does not apply to 'list' mode.
  1556. // $p_path and $p_remove_path are commulative.
  1557. // Return Values :
  1558. // --------------------------------------------------------------------------------
  1559. function PclTarHandleExtract($p_tarname, $p_file_list, &$p_list_detail, $p_mode, $p_path, $p_tar_mode, $p_remove_path)
  1560. {
  1561. TrFctStart(__FILE__, __LINE__, "PclTarHandleExtract", "archive='$p_tarname', list, mode=$p_mode, path=$p_path, tar_mode=$p_tar_mode, remove_path='$p_remove_path'");
  1562. $v_result=1;
  1563. $v_nb = 0;
  1564. $v_extract_all = TRUE;
  1565. $v_listing = FALSE;
  1566. // ----- Check the path
  1567. /*
  1568. if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../")))
  1569. $p_path = "./".$p_path;
  1570. */
  1571. $isWin = (substr(PHP_OS, 0, 3) == 'WIN');
  1572. if(!$isWin)
  1573. {
  1574. if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../")))
  1575. $p_path = "./".$p_path;
  1576. }
  1577. // ----- Look for path to remove format (should end by /)
  1578. if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
  1579. {
  1580. $p_remove_path .= '/';
  1581. }
  1582. $p_remove_path_size = strlen($p_remove_path);
  1583. // ----- Study the mode
  1584. switch ($p_mode) {
  1585. case "complete" :
  1586. // ----- Flag extract of all files
  1587. $v_extract_all = TRUE;
  1588. $v_listing = FALSE;
  1589. break;
  1590. case "partial" :
  1591. // ----- Flag extract of specific files
  1592. $v_extract_all = FALSE;
  1593. $v_listing = FALSE;
  1594. break;
  1595. case "list" :
  1596. // ----- Flag list of all files
  1597. $v_extract_all = FALSE;
  1598. $v_listing = TRUE;
  1599. break;
  1600. default :
  1601. // ----- Error log
  1602. PclErrorLog(-3, "Invalid extract mode ($p_mode)");
  1603. // ----- Return
  1604. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  1605. return PclErrorCode();
  1606. }
  1607. // ----- Open the tar file
  1608. if ($p_tar_mode == "tar")
  1609. {
  1610. TrFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  1611. $v_tar = fopen($p_tarname, "rb");
  1612. }
  1613. else
  1614. {
  1615. TrFctMessage(__FILE__, __LINE__, 3, "Open file in gzip binary read mode");
  1616. $v_tar = @gzopen($p_tarname, "rb");
  1617. }
  1618. // ----- Check that the archive is open
  1619. if ($v_tar == 0)
  1620. {
  1621. // ----- Error log
  1622. PclErrorLog(-2, "Unable to open archive '$p_tarname' in binary read mode");
  1623. // ----- Return
  1624. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  1625. return PclErrorCode();
  1626. }
  1627. // ----- Read the blocks
  1628. While (!($v_end_of_file = ($p_tar_mode == "tar"?feof($v_tar):gzeof($v_tar))))
  1629. {
  1630. TrFctMessage(__FILE__, __LINE__, 3, "Looking for next header ...");
  1631. // ----- Clear cache of file infos
  1632. clearstatcache();
  1633. // ----- Reset extract tag
  1634. $v_extract_file = FALSE;
  1635. $v_extraction_stopped = 0;
  1636. // ----- Read the 512 bytes header
  1637. if ($p_tar_mode == "tar")
  1638. $v_binary_data = fread($v_tar, 512);
  1639. else
  1640. $v_binary_data = gzread($v_tar, 512);
  1641. // ----- Read the header properties
  1642. if (($v_result = PclTarHandleReadHeader($v_binary_data, $v_header)) != 1)
  1643. {
  1644. // ----- Close the archive file
  1645. if ($p_tar_mode == "tar")
  1646. fclose($v_tar);
  1647. else
  1648. gzclose($v_tar);
  1649. // ----- Return
  1650. TrFctEnd(__FILE__, __LINE__, $v_result);
  1651. return $v_result;
  1652. }
  1653. // ----- Look for empty blocks to skip
  1654. if ($v_header["filename"] == "")
  1655. {
  1656. TrFctMessage(__FILE__, __LINE__, 2, "Empty block found. End of archive ?");
  1657. continue;
  1658. }
  1659. TrFctMessage(__FILE__, __LINE__, 2, "Found file '" . $v_header["filename"] . "', size '$v_header[size]'");
  1660. // ----- Look for partial extract
  1661. if ((!$v_extract_all) && (is_array($p_file_list)))
  1662. {
  1663. TrFctMessage(__FILE__, __LINE__, 2, "Look if the file '$v_header[filename]' need to be extracted");
  1664. // ----- By default no unzip if the file is not found
  1665. $v_extract_file = FALSE;
  1666. // ----- Look into the file list
  1667. for ($i=0; $i<sizeof($p_file_list); $i++)
  1668. {
  1669. TrFctMessage(__FILE__, __LINE__, 2, "Compare archived file '$v_header[filename]' from asked list file '".$p_file_list[$i]."'");
  1670. // ----- Look if it is a directory
  1671. if (substr($p_file_list[$i], -1) == "/")
  1672. {
  1673. TrFctMessage(__FILE__, __LINE__, 3, "Compare file '$v_header[filename]' with directory '$p_file_list[$i]'");
  1674. // ----- Look if the directory is in the filename path
  1675. if ((strlen($v_header["filename"]) > strlen($p_file_list[$i])) && (substr($v_header["filename"], 0, strlen($p_file_list[$i])) == $p_file_list[$i]))
  1676. {
  1677. // ----- The file is in the directory, so extract it
  1678. TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' is in directory '$p_file_list[$i]' : extract it");
  1679. $v_extract_file = TRUE;
  1680. // ----- End of loop
  1681. break;
  1682. }
  1683. }
  1684. // ----- It is a file, so compare the file names
  1685. else if ($p_file_list[$i] == $v_header["filename"])
  1686. {
  1687. // ----- File found
  1688. TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' should be extracted");
  1689. $v_extract_file = TRUE;
  1690. // ----- End of loop
  1691. break;
  1692. }
  1693. }
  1694. // ----- Trace
  1695. if (!$v_extract_file)
  1696. {
  1697. TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' should not be extracted");
  1698. }
  1699. }
  1700. else
  1701. {
  1702. // ----- All files need to be extracted
  1703. $v_extract_file = TRUE;
  1704. }
  1705. // ----- Look if this file need to be extracted
  1706. if (($v_extract_file) && (!$v_listing))
  1707. {
  1708. // ----- Look for path to remove
  1709. if (($p_remove_path != "")
  1710. && (substr($v_header["filename"], 0, $p_remove_path_size) == $p_remove_path))
  1711. {
  1712. TrFctMessage(__FILE__, __LINE__, 3, "Found path '$p_remove_path' to remove in file '$v_header[filename]'");
  1713. // ----- Remove the path
  1714. $v_header["filename"] = substr($v_header["filename"], $p_remove_path_size);
  1715. TrFctMessage(__FILE__, __LINE__, 3, "Reslting file is '$v_header[filename]'");
  1716. }
  1717. // ----- Add the path to the file
  1718. if (($p_path != "./") && ($p_path != "/"))
  1719. {
  1720. // ----- Look for the path end '/'
  1721. while (substr($p_path, -1) == "/")
  1722. {
  1723. TrFctMessage(__FILE__, __LINE__, 3, "Destination path [$p_path] ends by '/'");
  1724. $p_path = substr($p_path, 0, strlen($p_path)-1);
  1725. TrFctMessage(__FILE__, __LINE__, 3, "Modified to [$p_path]");
  1726. }
  1727. // ----- Add the path
  1728. if (substr($v_header["filename"], 0, 1) == "/")
  1729. $v_header["filename"] = $p_path.$v_header["filename"];
  1730. else
  1731. $v_header["filename"] = $p_path."/".$v_header["filename"];
  1732. }
  1733. // ----- Trace
  1734. TrFctMessage(__FILE__, __LINE__, 2, "Extracting file (with path) '$v_header[filename]', size '$v_header[size]'");
  1735. // ----- Check that the file does not exists
  1736. if (file_exists($v_header["filename"]))
  1737. {
  1738. TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' already exists");
  1739. // ----- Look if file is a directory
  1740. if (is_dir($v_header["filename"]))
  1741. {
  1742. TrFctMessage(__FILE__, __LINE__, 2, "Existing file '$v_header[filename]' is a directory");
  1743. // ----- Change the file status
  1744. $v_header["status"] = "already_a_directory";
  1745. // ----- Skip the extract
  1746. $v_extraction_stopped = 1;
  1747. $v_extract_file = 0;
  1748. }
  1749. // ----- Look if file is write protected
  1750. else if (!is_writeable($v_header["filename"]))
  1751. {
  1752. TrFctMessage(__FILE__, __LINE__, 2, "Existing file '$v_header[filename]' is write protected");
  1753. // ----- Change the file status
  1754. $v_header["status"] = "write_protected";
  1755. // ----- Skip the extract
  1756. $v_extraction_stopped = 1;
  1757. $v_extract_file = 0;
  1758. }
  1759. // ----- Look if the extracted file is older
  1760. else if (filemtime($v_header["filename"]) > $v_header["mtime"])
  1761. {
  1762. TrFctMessage(__FILE__, __LINE__, 2, "Existing file '$v_header[filename]' is newer (".date("l dS of F Y h:i:s A", filemtime($v_header[filename])).") than the extracted file (".date("l dS of F Y h:i:s A", $v_header[mtime]).")");
  1763. // ----- Change the file status
  1764. $v_header["status"] = "newer_exist";
  1765. // ----- Skip the extract
  1766. $v_extraction_stopped = 1;
  1767. $v_extract_file = 0;
  1768. }
  1769. }
  1770. // ----- Check the directory availability and create it if necessary
  1771. else
  1772. {
  1773. if ($v_header["typeflag"]=="5")
  1774. $v_dir_to_check = $v_header["filename"];
  1775. else if (!strstr($v_header["filename"], "/"))
  1776. $v_dir_to_check = "";
  1777. else
  1778. $v_dir_to_check = dirname($v_header["filename"]);
  1779. if (($v_result = PclTarHandlerDirCheck($v_dir_to_check)) != 1)
  1780. {
  1781. TrFctMessage(__FILE__, __LINE__, 2, "Unable to create path for '$v_header[filename]'");
  1782. // ----- Change the file status
  1783. $v_header["status"] = "path_creation_fail";
  1784. // ----- Skip the extract
  1785. $v_extraction_stopped = 1;
  1786. $v_extract_file = 0;
  1787. }
  1788. }
  1789. // ----- Do the extraction
  1790. if (($v_extract_file) && ($v_header["typeflag"]!="5"))
  1791. {
  1792. // ----- Open the destination file in write mode
  1793. if (($v_dest_file = @fopen($v_header["filename"], "wb")) == 0)
  1794. {
  1795. TrFctMessage(__FILE__, __LINE__, 2, "Error while opening '$v_header[filename]' in write binary mode");
  1796. // ----- Change the file status
  1797. $v_header["status"] = "write_error";
  1798. // ----- Jump to next file
  1799. TrFctMessage(__FILE__, __LINE__, 2, "Jump to next file");
  1800. if ($p_tar_mode == "tar")
  1801. fseek($v_tar, ftell($v_tar)+(ceil(($v_header[size]/512))*512));
  1802. else
  1803. gzseek($v_tar, gztell($v_tar)+(ceil(($v_header[size]/512))*512));
  1804. }
  1805. else
  1806. {
  1807. TrFctMessage(__FILE__, __LINE__, 2, "Start extraction of '$v_header[filename]'");
  1808. // ----- Read data
  1809. $n = floor($v_header["size"]/512);
  1810. for ($i=0; $i<$n; $i++)
  1811. {
  1812. TrFctMessage(__FILE__, __LINE__, 3, "Read complete 512 bytes block number ".($i+1));
  1813. if ($p_tar_mode == "tar")
  1814. $v_content = fread($v_tar, 512);
  1815. else
  1816. $v_content = gzread($v_tar, 512);
  1817. fwrite($v_dest_file, $v_content, 512);
  1818. }
  1819. if (($v_header["size"] % 512) != 0)
  1820. {
  1821. TrFctMessage(__FILE__, __LINE__, 3, "Read last ".($v_header["size"] % 512)." bytes in a 512 block");
  1822. if ($p_tar_mode == "tar")
  1823. $v_content = fread($v_tar, 512);
  1824. else
  1825. $v_content = gzread($v_tar, 512);
  1826. fwrite($v_dest_file, $v_content, ($v_header["size"] % 512));
  1827. }
  1828. // ----- Close the destination file
  1829. fclose($v_dest_file);
  1830. // ----- Change the file mode, mtime
  1831. touch($v_header["filename"], $v_header["mtime"]);
  1832. //chmod($v_header[filename], DecOct($v_header[mode]));
  1833. }
  1834. // ----- Check the file size
  1835. clearstatcache();
  1836. if (filesize($v_header["filename"]) != $v_header["size"])
  1837. {
  1838. // ----- Close the archive file
  1839. if ($p_tar_mode == "tar")
  1840. fclose($v_tar);
  1841. else
  1842. gzclose($v_tar);
  1843. // ----- Error log
  1844. PclErrorLog(-7, "Extracted file '$v_header[filename]' does not have the correct file size '".filesize($v_filename)."' ('$v_header[size]' expected). Archive may be corrupted.");
  1845. // ----- Return
  1846. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  1847. return PclErrorCode();
  1848. }
  1849. // ----- Trace
  1850. TrFctMessage(__FILE__, __LINE__, 2, "Extraction done");
  1851. }
  1852. else
  1853. {
  1854. TrFctMessage(__FILE__, __LINE__, 2, "Extraction of file '$v_header[filename]' skipped.");
  1855. // ----- Jump to next file
  1856. TrFctMessage(__FILE__, __LINE__, 2, "Jump to next file");
  1857. if ($p_tar_mode == "tar")
  1858. fseek($v_tar, ftell($v_tar)+(ceil(($v_header["size"]/512))*512));
  1859. else
  1860. gzseek($v_tar, gztell($v_tar)+(ceil(($v_header["size"]/512))*512));
  1861. }
  1862. }
  1863. // ----- Look for file that is not to be unzipped
  1864. else
  1865. {
  1866. // ----- Trace
  1867. TrFctMessage(__FILE__, __LINE__, 2, "Jump file '$v_header[filename]'");
  1868. TrFctMessage(__FILE__, __LINE__, 4, "Position avant jump [".($p_tar_mode=="tar"?ftell($v_tar):gztell($v_tar))."]");
  1869. // ----- Jump to next file
  1870. if ($p_tar_mode == "tar")
  1871. fseek($v_tar, ($p_tar_mode=="tar"?ftell($v_tar):gztell($v_tar))+(ceil(($v_header[size]/512))*512));
  1872. else
  1873. gzseek($v_tar, gztell($v_tar)+(ceil(($v_header[size]/512))*512));
  1874. TrFctMessage(__FILE__, __LINE__, 4, "Position apr?s jump [".($p_tar_mode=="tar"?ftell($v_tar):gztell($v_tar))."]");
  1875. }
  1876. if ($p_tar_mode == "tar")
  1877. $v_end_of_file = feof($v_tar);
  1878. else
  1879. $v_end_of_file = gzeof($v_tar);
  1880. // ----- File name and properties are logged if listing mode or file is extracted
  1881. if ($v_listing || $v_extract_file || $v_extraction_stopped)
  1882. {
  1883. TrFctMessage(__FILE__, __LINE__, 2, "Memorize info about file '$v_header[filename]'");
  1884. // ----- Log extracted files
  1885. if (($v_file_dir = dirname($v_header["filename"])) == $v_header["filename"])
  1886. $v_file_dir = "";
  1887. if ((substr($v_header["filename"], 0, 1) == "/") && ($v_file_dir == ""))
  1888. $v_file_dir = "/";
  1889. // ----- Add the array describing the file into the list
  1890. $p_list_detail[$v_nb] = $v_header;
  1891. // ----- Increment
  1892. $v_nb++;
  1893. }
  1894. }
  1895. // ----- Close the tarfile
  1896. if ($p_tar_mode == "tar")
  1897. fclose($v_tar);
  1898. else
  1899. gzclose($v_tar);
  1900. // ----- Return
  1901. TrFctEnd(__FILE__, __LINE__, $v_result);
  1902. return $v_result;
  1903. }
  1904. // --------------------------------------------------------------------------------
  1905. // --------------------------------------------------------------------------------
  1906. // Function : PclTarHandleExtractByIndexList()
  1907. // Description :
  1908. // Extract the files which are at the indexes specified. If the 'file' at the
  1909. // index is a directory, the directory only is created, not all the files stored
  1910. // for that directory.
  1911. // Parameters :
  1912. // $p_index_string : String of indexes of files to extract. The form of the
  1913. // string is "0,4-6,8-12" with only numbers and '-' for
  1914. // for range, and ',' to separate ranges. No spaces or ';'
  1915. // are allowed.
  1916. // Return Values :
  1917. // --------------------------------------------------------------------------------
  1918. function PclTarHandleExtractByIndexList($p_tarname, $p_index_string, &$p_list_detail, $p_path, $p_remove_path, $p_tar_mode)
  1919. {
  1920. TrFctStart(__FILE__, __LINE__, "PclTarHandleExtractByIndexList", "archive='$p_tarname', index_string='$p_index_string', list, path=$p_path, remove_path='$p_remove_path', tar_mode=$p_tar_mode");
  1921. $v_result=1;
  1922. $v_nb = 0;
  1923. // ----- TBC : I should check the string by a regexp
  1924. // ----- Check the path
  1925. if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../") && (substr($p_path, 0, 2) != "./")))
  1926. $p_path = "./".$p_path;
  1927. // ----- Look for path to remove format (should end by /)
  1928. if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
  1929. {
  1930. $p_remove_path .= '/';
  1931. }
  1932. $p_remove_path_size = strlen($p_remove_path);
  1933. // ----- Open the tar file
  1934. if ($p_tar_mode == "tar")
  1935. {
  1936. TrFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  1937. $v_tar = @fopen($p_tarname, "rb");
  1938. }
  1939. else
  1940. {
  1941. TrFctMessage(__FILE__, __LINE__, 3, "Open file in gzip binary read mode");
  1942. $v_tar = @gzopen($p_tarname, "rb");
  1943. }
  1944. // ----- Check that the archive is open
  1945. if ($v_tar == 0)
  1946. {
  1947. // ----- Error log
  1948. PclErrorLog(-2, "Unable to open archive '$p_tarname' in binary read mode");
  1949. // ----- Return
  1950. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  1951. return PclErrorCode();
  1952. }
  1953. // ----- Manipulate the index list
  1954. $v_list = explode(",", $p_index_string);
  1955. sort($v_list);
  1956. // ----- Loop on the index list
  1957. $v_index=0;
  1958. for ($i=0; ($i<sizeof($v_list)) && ($v_result); $i++)
  1959. {
  1960. TrFctMessage(__FILE__, __LINE__, 3, "Looking for index part '$v_list[$i]'");
  1961. // ----- Extract range
  1962. $v_index_list = explode("-", $v_list[$i]);
  1963. $v_size_index_list = sizeof($v_index_list);
  1964. if ($v_size_index_list == 1)
  1965. {
  1966. TrFctMessage(__FILE__, __LINE__, 3, "Only one index '$v_index_list[0]'");
  1967. // ----- Do the extraction
  1968. $v_result = PclTarHandleExtractByIndex($v_tar, $v_index, $v_index_list[0], $v_index_list[0], $p_list_detail, $p_path, $p_remove_path, $p_tar_mode);
  1969. }
  1970. else if ($v_size_index_list == 2)
  1971. {
  1972. TrFctMessage(__FILE__, __LINE__, 3, "Two indexes '$v_index_list[0]' and '$v_index_list[1]'");
  1973. // ----- Do the extraction
  1974. $v_result = PclTarHandleExtractByIndex($v_tar, $v_index, $v_index_list[0], $v_index_list[1], $p_list_detail, $p_path, $p_remove_path, $p_tar_mode);
  1975. }
  1976. }
  1977. // ----- Close the tarfile
  1978. if ($p_tar_mode == "tar")
  1979. fclose($v_tar);
  1980. else
  1981. gzclose($v_tar);
  1982. // ----- Return
  1983. TrFctEnd(__FILE__, __LINE__, $v_result);
  1984. return $v_result;
  1985. }
  1986. // --------------------------------------------------------------------------------
  1987. // --------------------------------------------------------------------------------
  1988. // Function : PclTarHandleExtractByIndex()
  1989. // Description :
  1990. // Parameters :
  1991. // Return Values :
  1992. // --------------------------------------------------------------------------------
  1993. function PclTarHandleExtractByIndex($p_tar, &$p_index_current, $p_index_start, $p_index_stop, &$p_list_detail, $p_path, $p_remove_path, $p_tar_mode)
  1994. {
  1995. TrFctStart(__FILE__, __LINE__, "PclTarHandleExtractByIndex", "archive_descr='$p_tar', index_current=$p_index_current, index_start='$p_index_start', index_stop='$p_index_stop', list, path=$p_path, remove_path='$p_remove_path', tar_mode=$p_tar_mode");
  1996. $v_result=1;
  1997. $v_nb = 0;
  1998. // TBC : I should replace all $v_tar by $p_tar in this function ....
  1999. $v_tar = $p_tar;
  2000. // ----- Look the number of elements already in $p_list_detail
  2001. $v_nb = sizeof($p_list_detail);
  2002. // ----- Read the blocks
  2003. While (!($v_end_of_file = ($p_tar_mode == "tar"?feof($v_tar):gzeof($v_tar))))
  2004. {
  2005. TrFctMessage(__FILE__, __LINE__, 3, "Looking for next file ...");
  2006. TrFctMessage(__FILE__, __LINE__, 3, "Index current=$p_index_current, range=[$p_index_start, $p_index_stop])");
  2007. if ($p_index_current > $p_index_stop)
  2008. {
  2009. TrFctMessage(__FILE__, __LINE__, 2, "Stop extraction, past stop index");
  2010. break;
  2011. }
  2012. // ----- Clear cache of file infos
  2013. clearstatcache();
  2014. // ----- Reset extract tag
  2015. $v_extract_file = FALSE;
  2016. $v_extraction_stopped = 0;
  2017. // ----- Read the 512 bytes header
  2018. if ($p_tar_mode == "tar")
  2019. $v_binary_data = fread($v_tar, 512);
  2020. else
  2021. $v_binary_data = gzread($v_tar, 512);
  2022. // ----- Read the header properties
  2023. if (($v_result = PclTarHandleReadHeader($v_binary_data, $v_header)) != 1)
  2024. {
  2025. // ----- Return
  2026. TrFctEnd(__FILE__, __LINE__, $v_result);
  2027. return $v_result;
  2028. }
  2029. // ----- Look for empty blocks to skip
  2030. if ($v_header[filename] == "")
  2031. {
  2032. TrFctMessage(__FILE__, __LINE__, 2, "Empty block found. End of archive ?");
  2033. continue;
  2034. }
  2035. TrFctMessage(__FILE__, __LINE__, 2, "Found file '$v_header[filename]', size '$v_header[size]'");
  2036. // ----- Look if file is in the range to be extracted
  2037. if (($p_index_current >= $p_index_start) && ($p_index_current <= $p_index_stop))
  2038. {
  2039. TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' is in the range to be extracted");
  2040. $v_extract_file = TRUE;
  2041. }
  2042. else
  2043. {
  2044. TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' is out of the range");
  2045. $v_extract_file = FALSE;
  2046. }
  2047. // ----- Look if this file need to be extracted
  2048. if ($v_extract_file)
  2049. {
  2050. if (($v_result = PclTarHandleExtractFile($v_tar, $v_header, $p_path, $p_remove_path, $p_tar_mode)) != 1)
  2051. {
  2052. // ----- Return
  2053. TrFctEnd(__FILE__, __LINE__, $v_result);
  2054. return $v_result;
  2055. }
  2056. }
  2057. // ----- Look for file that is not to be extracted
  2058. else
  2059. {
  2060. // ----- Trace
  2061. TrFctMessage(__FILE__, __LINE__, 2, "Jump file '$v_header[filename]'");
  2062. TrFctMessage(__FILE__, __LINE__, 4, "Position avant jump [".($p_tar_mode=="tar"?ftell($v_tar):gztell($v_tar))."]");
  2063. // ----- Jump to next file
  2064. if ($p_tar_mode == "tar")
  2065. fseek($v_tar, ($p_tar_mode=="tar"?ftell($v_tar):gztell($v_tar))+(ceil(($v_header[size]/512))*512));
  2066. else
  2067. gzseek($v_tar, gztell($v_tar)+(ceil(($v_header[size]/512))*512));
  2068. TrFctMessage(__FILE__, __LINE__, 4, "Position apr?s jump [".($p_tar_mode=="tar"?ftell($v_tar):gztell($v_tar))."]");
  2069. }
  2070. if ($p_tar_mode == "tar")
  2071. $v_end_of_file = feof($v_tar);
  2072. else
  2073. $v_end_of_file = gzeof($v_tar);
  2074. // ----- File name and properties are logged if listing mode or file is extracted
  2075. if ($v_extract_file)
  2076. {
  2077. TrFctMessage(__FILE__, __LINE__, 2, "Memorize info about file '$v_header[filename]'");
  2078. // ----- Log extracted files
  2079. if (($v_file_dir = dirname($v_header[filename])) == $v_header[filename])
  2080. $v_file_dir = "";
  2081. if ((substr($v_header[filename], 0, 1) == "/") && ($v_file_dir == ""))
  2082. $v_file_dir = "/";
  2083. // ----- Add the array describing the file into the list
  2084. $p_list_detail[$v_nb] = $v_header;
  2085. // ----- Increment
  2086. $v_nb++;
  2087. }
  2088. // ----- Increment the current file index
  2089. $p_index_current++;
  2090. }
  2091. // ----- Return
  2092. TrFctEnd(__FILE__, __LINE__, $v_result);
  2093. return $v_result;
  2094. }
  2095. // --------------------------------------------------------------------------------
  2096. // --------------------------------------------------------------------------------
  2097. // Function : PclTarHandleExtractFile()
  2098. // Description :
  2099. // Parameters :
  2100. // Return Values :
  2101. // --------------------------------------------------------------------------------
  2102. function PclTarHandleExtractFile($p_tar, &$v_header, $p_path, $p_remove_path, $p_tar_mode)
  2103. {
  2104. TrFctStart(__FILE__, __LINE__, "PclTarHandleExtractFile", "archive_descr='$p_tar', path=$p_path, remove_path='$p_remove_path', tar_mode=$p_tar_mode");
  2105. $v_result=1;
  2106. // TBC : I should replace all $v_tar by $p_tar in this function ....
  2107. $v_tar = $p_tar;
  2108. $v_extract_file = 1;
  2109. $p_remove_path_size = strlen($p_remove_path);
  2110. // ----- Look for path to remove
  2111. if (($p_remove_path != "")
  2112. && (substr($v_header[filename], 0, $p_remove_path_size) == $p_remove_path))
  2113. {
  2114. TrFctMessage(__FILE__, __LINE__, 3, "Found path '$p_remove_path' to remove in file '$v_header[filename]'");
  2115. // ----- Remove the path
  2116. $v_header[filename] = substr($v_header[filename], $p_remove_path_size);
  2117. TrFctMessage(__FILE__, __LINE__, 3, "Resulting file is '$v_header[filename]'");
  2118. }
  2119. // ----- Add the path to the file
  2120. if (($p_path != "./") && ($p_path != "/"))
  2121. {
  2122. // ----- Look for the path end '/'
  2123. while (substr($p_path, -1) == "/")
  2124. {
  2125. TrFctMessage(__FILE__, __LINE__, 3, "Destination path [$p_path] ends by '/'");
  2126. $p_path = substr($p_path, 0, strlen($p_path)-1);
  2127. TrFctMessage(__FILE__, __LINE__, 3, "Modified to [$p_path]");
  2128. }
  2129. // ----- Add the path
  2130. if (substr($v_header[filename], 0, 1) == "/")
  2131. $v_header[filename] = $p_path.$v_header[filename];
  2132. else
  2133. $v_header[filename] = $p_path."/".$v_header[filename];
  2134. }
  2135. // ----- Trace
  2136. TrFctMessage(__FILE__, __LINE__, 2, "Extracting file (with path) '$v_header[filename]', size '$v_header[size]'");
  2137. // ----- Check that the file does not exists
  2138. if (file_exists($v_header[filename]))
  2139. {
  2140. TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' already exists");
  2141. // ----- Look if file is a directory
  2142. if (is_dir($v_header[filename]))
  2143. {
  2144. TrFctMessage(__FILE__, __LINE__, 2, "Existing file '$v_header[filename]' is a directory");
  2145. // ----- Change the file status
  2146. $v_header[status] = "already_a_directory";
  2147. // ----- Skip the extract
  2148. $v_extraction_stopped = 1;
  2149. $v_extract_file = 0;
  2150. }
  2151. // ----- Look if file is write protected
  2152. else if (!is_writeable($v_header[filename]))
  2153. {
  2154. TrFctMessage(__FILE__, __LINE__, 2, "Existing file '$v_header[filename]' is write protected");
  2155. // ----- Change the file status
  2156. $v_header[status] = "write_protected";
  2157. // ----- Skip the extract
  2158. $v_extraction_stopped = 1;
  2159. $v_extract_file = 0;
  2160. }
  2161. // ----- Look if the extracted file is older
  2162. else if (filemtime($v_header[filename]) > $v_header[mtime])
  2163. {
  2164. TrFctMessage(__FILE__, __LINE__, 2, "Existing file '$v_header[filename]' is newer (".date("l dS of F Y h:i:s A", filemtime($v_header[filename])).") than the extracted file (".date("l dS of F Y h:i:s A", $v_header[mtime]).")");
  2165. // ----- Change the file status
  2166. $v_header[status] = "newer_exist";
  2167. // ----- Skip the extract
  2168. $v_extraction_stopped = 1;
  2169. $v_extract_file = 0;
  2170. }
  2171. }
  2172. // ----- Check the directory availability and create it if necessary
  2173. else
  2174. {
  2175. if ($v_header[typeflag]=="5")
  2176. $v_dir_to_check = $v_header[filename];
  2177. else if (!strstr($v_header[filename], "/"))
  2178. $v_dir_to_check = "";
  2179. else
  2180. $v_dir_to_check = dirname($v_header[filename]);
  2181. if (($v_result = PclTarHandlerDirCheck($v_dir_to_check)) != 1)
  2182. {
  2183. TrFctMessage(__FILE__, __LINE__, 2, "Unable to create path for '$v_header[filename]'");
  2184. // ----- Change the file status
  2185. $v_header[status] = "path_creation_fail";
  2186. // ----- Skip the extract
  2187. $v_extraction_stopped = 1;
  2188. $v_extract_file = 0;
  2189. }
  2190. }
  2191. // ----- Do the real bytes extraction (if not a directory)
  2192. if (($v_extract_file) && ($v_header[typeflag]!="5"))
  2193. {
  2194. // ----- Open the destination file in write mode
  2195. if (($v_dest_file = @fopen($v_header[filename], "wb")) == 0)
  2196. {
  2197. TrFctMessage(__FILE__, __LINE__, 2, "Error while opening '$v_header[filename]' in write binary mode");
  2198. // ----- Change the file status
  2199. $v_header[status] = "write_error";
  2200. // ----- Jump to next file
  2201. TrFctMessage(__FILE__, __LINE__, 2, "Jump to next file");
  2202. if ($p_tar_mode == "tar")
  2203. fseek($v_tar, ftell($v_tar)+(ceil(($v_header[size]/512))*512));
  2204. else
  2205. gzseek($v_tar, gztell($v_tar)+(ceil(($v_header[size]/512))*512));
  2206. }
  2207. else
  2208. {
  2209. TrFctMessage(__FILE__, __LINE__, 2, "Start extraction of '$v_header[filename]'");
  2210. // ----- Read data
  2211. $n = floor($v_header[size]/512);
  2212. for ($i=0; $i<$n; $i++)
  2213. {
  2214. TrFctMessage(__FILE__, __LINE__, 3, "Read complete 512 bytes block number ".($i+1));
  2215. if ($p_tar_mode == "tar")
  2216. $v_content = fread($v_tar, 512);
  2217. else
  2218. $v_content = gzread($v_tar, 512);
  2219. fwrite($v_dest_file, $v_content, 512);
  2220. }
  2221. if (($v_header[size] % 512) != 0)
  2222. {
  2223. TrFctMessage(__FILE__, __LINE__, 3, "Read last ".($v_header[size] % 512)." bytes in a 512 block");
  2224. if ($p_tar_mode == "tar")
  2225. $v_content = fread($v_tar, 512);
  2226. else
  2227. $v_content = gzread($v_tar, 512);
  2228. fwrite($v_dest_file, $v_content, ($v_header[size] % 512));
  2229. }
  2230. // ----- Close the destination file
  2231. fclose($v_dest_file);
  2232. // ----- Change the file mode, mtime
  2233. touch($v_header[filename], $v_header[mtime]);
  2234. //chmod($v_header[filename], DecOct($v_header[mode]));
  2235. }
  2236. // ----- Check the file size
  2237. clearstatcache();
  2238. if (filesize($v_header[filename]) != $v_header[size])
  2239. {
  2240. // ----- Error log
  2241. PclErrorLog(-7, "Extracted file '$v_header[filename]' does not have the correct file size '".filesize($v_filename)."' ('$v_header[size]' expected). Archive may be corrupted.");
  2242. // ----- Return
  2243. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  2244. return PclErrorCode();
  2245. }
  2246. // ----- Trace
  2247. TrFctMessage(__FILE__, __LINE__, 2, "Extraction done");
  2248. }
  2249. else
  2250. {
  2251. TrFctMessage(__FILE__, __LINE__, 2, "Extraction of file '$v_header[filename]' skipped.");
  2252. // ----- Jump to next file
  2253. TrFctMessage(__FILE__, __LINE__, 2, "Jump to next file");
  2254. if ($p_tar_mode == "tar")
  2255. fseek($v_tar, ftell($v_tar)+(ceil(($v_header[size]/512))*512));
  2256. else
  2257. gzseek($v_tar, gztell($v_tar)+(ceil(($v_header[size]/512))*512));
  2258. }
  2259. // ----- Return
  2260. TrFctEnd(__FILE__, __LINE__, $v_result);
  2261. return $v_result;
  2262. }
  2263. // --------------------------------------------------------------------------------
  2264. // --------------------------------------------------------------------------------
  2265. // Function : PclTarHandleDelete()
  2266. // Description :
  2267. // Parameters :
  2268. // Return Values :
  2269. // --------------------------------------------------------------------------------
  2270. function PclTarHandleDelete($p_tarname, $p_file_list, &$p_list_detail, $p_tar_mode)
  2271. {
  2272. TrFctStart(__FILE__, __LINE__, "PclTarHandleDelete", "archive='$p_tarname', list, tar_mode=$p_tar_mode");
  2273. $v_result=1;
  2274. $v_nb=0;
  2275. // ----- Look for regular tar file
  2276. if ($p_tar_mode == "tar")
  2277. {
  2278. // ----- Open file
  2279. TrFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  2280. if (($v_tar = @fopen($p_tarname, "rb")) == 0)
  2281. {
  2282. // ----- Error log
  2283. PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode");
  2284. // ----- Return
  2285. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  2286. return PclErrorCode();
  2287. }
  2288. // ----- Open a temporary file in write mode
  2289. $v_temp_tarname = uniqid("pcltar-").".tmp";
  2290. TrFctMessage(__FILE__, __LINE__, 2, "Creating temporary archive file $v_temp_tarname");
  2291. if (($v_temp_tar = @fopen($v_temp_tarname, "wb")) == 0)
  2292. {
  2293. // ----- Close tar file
  2294. fclose($v_tar);
  2295. // ----- Error log
  2296. PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode");
  2297. // ----- Return
  2298. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  2299. return PclErrorCode();
  2300. }
  2301. }
  2302. // ----- Look for compressed tar file
  2303. else
  2304. {
  2305. // ----- Open the file in read mode
  2306. TrFctMessage(__FILE__, __LINE__, 3, "Open file in gzip binary read mode");
  2307. if (($v_tar = @gzopen($p_tarname, "rb")) == 0)
  2308. {
  2309. // ----- Error log
  2310. PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode");
  2311. // ----- Return
  2312. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  2313. return PclErrorCode();
  2314. }
  2315. // ----- Open a temporary file in write mode
  2316. $v_temp_tarname = uniqid("pcltar-").".tmp";
  2317. TrFctMessage(__FILE__, __LINE__, 2, "Creating temporary archive file $v_temp_tarname");
  2318. if (($v_temp_tar = @gzopen($v_temp_tarname, "wb")) == 0)
  2319. {
  2320. // ----- Close tar file
  2321. gzclose($v_tar);
  2322. // ----- Error log
  2323. PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode");
  2324. // ----- Return
  2325. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  2326. return PclErrorCode();
  2327. }
  2328. }
  2329. // ----- Read the blocks
  2330. While (!($v_end_of_file = ($p_tar_mode == "tar"?feof($v_tar):gzeof($v_tar))))
  2331. {
  2332. TrFctMessage(__FILE__, __LINE__, 3, "Looking for next header ...");
  2333. // ----- Clear cache of file infos
  2334. clearstatcache();
  2335. // ----- Reset delete tag
  2336. $v_delete_file = FALSE;
  2337. // ----- Read the first 512 block header
  2338. if ($p_tar_mode == "tar")
  2339. $v_binary_data = fread($v_tar, 512);
  2340. else
  2341. $v_binary_data = gzread($v_tar, 512);
  2342. // ----- Read the header properties
  2343. if (($v_result = PclTarHandleReadHeader($v_binary_data, $v_header)) != 1)
  2344. {
  2345. // ----- Close the archive file
  2346. if ($p_tar_mode == "tar")
  2347. {
  2348. fclose($v_tar);
  2349. fclose($v_temp_tar);
  2350. }
  2351. else
  2352. {
  2353. gzclose($v_tar);
  2354. gzclose($v_temp_tar);
  2355. }
  2356. @unlink($v_temp_tarname);
  2357. // ----- Return
  2358. TrFctEnd(__FILE__, __LINE__, $v_result);
  2359. return $v_result;
  2360. }
  2361. // ----- Look for empty blocks to skip
  2362. if ($v_header[filename] == "")
  2363. {
  2364. TrFctMessage(__FILE__, __LINE__, 2, "Empty block found. End of archive ?");
  2365. continue;
  2366. }
  2367. TrFctMessage(__FILE__, __LINE__, 2, "Found file '$v_header[filename]', size '$v_header[size]'");
  2368. // ----- Look for filenames to delete
  2369. for ($i=0, $v_delete_file=FALSE; ($i<sizeof($p_file_list)) && (!$v_delete_file); $i++)
  2370. {
  2371. // ----- Compare the file names
  2372. // if ($p_file_list[$i] == $v_header[filename])
  2373. if (($v_len = strcmp($p_file_list[$i], $v_header[filename])) <= 0)
  2374. {
  2375. if ($v_len==0)
  2376. {
  2377. TrFctMessage(__FILE__, __LINE__, 3, "Found that '$v_header[filename]' need to be deleted");
  2378. $v_delete_file = TRUE;
  2379. }
  2380. else
  2381. {
  2382. TrFctMessage(__FILE__, __LINE__, 3, "Look if '$v_header[filename]' is a file in $p_file_list[$i]");
  2383. if (substr($v_header[filename], strlen($p_file_list[$i]), 1) == "/")
  2384. {
  2385. TrFctMessage(__FILE__, __LINE__, 3, "'$v_header[filename]' is a file in $p_file_list[$i]");
  2386. $v_delete_file = TRUE;
  2387. }
  2388. }
  2389. }
  2390. }
  2391. // ----- Copy files that do not need to be deleted
  2392. if (!$v_delete_file)
  2393. {
  2394. TrFctMessage(__FILE__, __LINE__, 2, "Keep file '$v_header[filename]'");
  2395. // ----- Write the file header
  2396. if ($p_tar_mode == "tar")
  2397. {
  2398. fputs($v_temp_tar, $v_binary_data, 512);
  2399. }
  2400. else
  2401. {
  2402. gzputs($v_temp_tar, $v_binary_data, 512);
  2403. }
  2404. // ----- Write the file data
  2405. $n = ceil($v_header[size]/512);
  2406. for ($i=0; $i<$n; $i++)
  2407. {
  2408. TrFctMessage(__FILE__, __LINE__, 3, "Read complete 512 bytes block number ".($i+1));
  2409. if ($p_tar_mode == "tar")
  2410. {
  2411. $v_content = fread($v_tar, 512);
  2412. fwrite($v_temp_tar, $v_content, 512);
  2413. }
  2414. else
  2415. {
  2416. $v_content = gzread($v_tar, 512);
  2417. gzwrite($v_temp_tar, $v_content, 512);
  2418. }
  2419. }
  2420. // ----- File name and properties are logged if listing mode or file is extracted
  2421. TrFctMessage(__FILE__, __LINE__, 2, "Memorize info about file '$v_header[filename]'");
  2422. // ----- Add the array describing the file into the list
  2423. $p_list_detail[$v_nb] = $v_header;
  2424. $p_list_detail[$v_nb][status] = "ok";
  2425. // ----- Increment
  2426. $v_nb++;
  2427. }
  2428. // ----- Look for file that is to be deleted
  2429. else
  2430. {
  2431. // ----- Trace
  2432. TrFctMessage(__FILE__, __LINE__, 2, "Start deletion of '$v_header[filename]'");
  2433. TrFctMessage(__FILE__, __LINE__, 4, "Position avant jump [".($p_tar_mode=="tar"?ftell($v_tar):gztell($v_tar))."]");
  2434. // ----- Jump to next file
  2435. if ($p_tar_mode == "tar")
  2436. fseek($v_tar, ftell($v_tar)+(ceil(($v_header[size]/512))*512));
  2437. else
  2438. gzseek($v_tar, gztell($v_tar)+(ceil(($v_header[size]/512))*512));
  2439. TrFctMessage(__FILE__, __LINE__, 4, "Position apr?s jump [".($p_tar_mode=="tar"?ftell($v_tar):gztell($v_tar))."]");
  2440. }
  2441. // ----- Look for end of file
  2442. if ($p_tar_mode == "tar")
  2443. $v_end_of_file = feof($v_tar);
  2444. else
  2445. $v_end_of_file = gzeof($v_tar);
  2446. }
  2447. // ----- Write the last empty buffer
  2448. PclTarHandleFooter($v_temp_tar, $p_tar_mode);
  2449. // ----- Close the tarfile
  2450. if ($p_tar_mode == "tar")
  2451. {
  2452. fclose($v_tar);
  2453. fclose($v_temp_tar);
  2454. }
  2455. else
  2456. {
  2457. gzclose($v_tar);
  2458. gzclose($v_temp_tar);
  2459. }
  2460. // ----- Unlink tar file
  2461. if (!@unlink($p_tarname))
  2462. {
  2463. // ----- Error log
  2464. PclErrorLog(-11, "Error while deleting archive name $p_tarname");
  2465. }
  2466. // ----- Rename tar file
  2467. if (!@rename($v_temp_tarname, $p_tarname))
  2468. {
  2469. // ----- Error log
  2470. PclErrorLog(-12, "Error while renaming temporary file $v_temp_tarname to archive name $p_tarname");
  2471. // ----- Return
  2472. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  2473. return PclErrorCode();
  2474. }
  2475. // ----- Return
  2476. TrFctEnd(__FILE__, __LINE__, $v_result);
  2477. return $v_result;
  2478. }
  2479. // --------------------------------------------------------------------------------
  2480. // --------------------------------------------------------------------------------
  2481. // Function : PclTarHandleUpdate()
  2482. // Description :
  2483. // Parameters :
  2484. // Return Values :
  2485. // --------------------------------------------------------------------------------
  2486. function PclTarHandleUpdate($p_tarname, $p_file_list, &$p_list_detail, $p_tar_mode, $p_add_dir, $p_remove_dir)
  2487. {
  2488. TrFctStart(__FILE__, __LINE__, "PclTarHandleUpdate", "archive='$p_tarname', list, tar_mode=$p_tar_mode");
  2489. $v_result=1;
  2490. $v_nb=0;
  2491. $v_found_list = array();
  2492. // ----- Look for regular tar file
  2493. if ($p_tar_mode == "tar")
  2494. {
  2495. // ----- Open file
  2496. TrFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  2497. if (($v_tar = @fopen($p_tarname, "rb")) == 0)
  2498. {
  2499. // ----- Error log
  2500. PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode");
  2501. // ----- Return
  2502. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  2503. return PclErrorCode();
  2504. }
  2505. // ----- Open a temporary file in write mode
  2506. $v_temp_tarname = uniqid("pcltar-").".tmp";
  2507. TrFctMessage(__FILE__, __LINE__, 2, "Creating temporary archive file $v_temp_tarname");
  2508. if (($v_temp_tar = @fopen($v_temp_tarname, "wb")) == 0)
  2509. {
  2510. // ----- Close tar file
  2511. fclose($v_tar);
  2512. // ----- Error log
  2513. PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode");
  2514. // ----- Return
  2515. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  2516. return PclErrorCode();
  2517. }
  2518. }
  2519. // ----- Look for compressed tar file
  2520. else
  2521. {
  2522. // ----- Open the file in read mode
  2523. TrFctMessage(__FILE__, __LINE__, 3, "Open file in gzip binary read mode");
  2524. if (($v_tar = @gzopen($p_tarname, "rb")) == 0)
  2525. {
  2526. // ----- Error log
  2527. PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode");
  2528. // ----- Return
  2529. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  2530. return PclErrorCode();
  2531. }
  2532. // ----- Open a temporary file in write mode
  2533. $v_temp_tarname = uniqid("pcltar-").".tmp";
  2534. TrFctMessage(__FILE__, __LINE__, 2, "Creating temporary archive file $v_temp_tarname");
  2535. if (($v_temp_tar = @gzopen($v_temp_tarname, "wb")) == 0)
  2536. {
  2537. // ----- Close tar file
  2538. gzclose($v_tar);
  2539. // ----- Error log
  2540. PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode");
  2541. // ----- Return
  2542. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  2543. return PclErrorCode();
  2544. }
  2545. }
  2546. // ----- Prepare the list of files
  2547. for ($i=0; $i<sizeof($p_file_list); $i++)
  2548. {
  2549. // ----- Reset the found list
  2550. $v_found_list[$i] = 0;
  2551. // ----- Calculate the stored filename
  2552. $v_stored_list[$i] = $p_file_list[$i];
  2553. if ($p_remove_dir != "")
  2554. {
  2555. if (substr($p_file_list[$i], -1) != '/')
  2556. $p_remove_dir .= "/";
  2557. if (substr($p_file_list[$i], 0, strlen($p_remove_dir)) == $p_remove_dir)
  2558. {
  2559. $v_stored_list[$i] = substr($p_file_list[$i], strlen($p_remove_dir));
  2560. TrFctMessage(__FILE__, __LINE__, 3, "Remove path '$p_remove_dir' in file '$p_file_list[$i]' = '$v_stored_list[$i]'");
  2561. }
  2562. }
  2563. if ($p_add_dir != "")
  2564. {
  2565. if (substr($p_add_dir, -1) == "/")
  2566. $v_stored_list[$i] = $p_add_dir.$v_stored_list[$i];
  2567. else
  2568. $v_stored_list[$i] = $p_add_dir."/".$v_stored_list[$i];
  2569. TrFctMessage(__FILE__, __LINE__, 3, "Add path '$p_add_dir' in file '$p_file_list[$i]' = '$v_stored_list[$i]'");
  2570. }
  2571. $v_stored_list[$i] = PclTarHandlePathReduction($v_stored_list[$i]);
  2572. TrFctMessage(__FILE__, __LINE__, 3, "After reduction '$v_stored_list[$i]'");
  2573. }
  2574. // ----- Update file cache
  2575. clearstatcache();
  2576. // ----- Read the blocks
  2577. While (!($v_end_of_file = ($p_tar_mode == "tar"?feof($v_tar):gzeof($v_tar))))
  2578. {
  2579. TrFctMessage(__FILE__, __LINE__, 3, "Looking for next header ...");
  2580. // ----- Clear cache of file infos
  2581. clearstatcache();
  2582. // ----- Reset current found filename
  2583. $v_current_filename = "";
  2584. // ----- Reset delete tag
  2585. $v_delete_file = FALSE;
  2586. // ----- Read the first 512 block header
  2587. if ($p_tar_mode == "tar")
  2588. $v_binary_data = fread($v_tar, 512);
  2589. else
  2590. $v_binary_data = gzread($v_tar, 512);
  2591. // ----- Read the header properties
  2592. if (($v_result = PclTarHandleReadHeader($v_binary_data, $v_header)) != 1)
  2593. {
  2594. // ----- Close the archive file
  2595. if ($p_tar_mode == "tar")
  2596. {
  2597. fclose($v_tar);
  2598. fclose($v_temp_tar);
  2599. }
  2600. else
  2601. {
  2602. gzclose($v_tar);
  2603. gzclose($v_temp_tar);
  2604. }
  2605. @unlink($v_temp_tarname);
  2606. // ----- Return
  2607. TrFctEnd(__FILE__, __LINE__, $v_result);
  2608. return $v_result;
  2609. }
  2610. // ----- Look for empty blocks to skip
  2611. if ($v_header[filename] == "")
  2612. {
  2613. TrFctMessage(__FILE__, __LINE__, 2, "Empty block found. End of archive ?");
  2614. continue;
  2615. }
  2616. TrFctMessage(__FILE__, __LINE__, 2, "Found file '$v_header[filename]', size '$v_header[size]'");
  2617. // ----- Look for filenames to update
  2618. for ($i=0, $v_update_file=FALSE, $v_found_file=FALSE; ($i<sizeof($v_stored_list)) && (!$v_update_file); $i++)
  2619. {
  2620. TrFctMessage(__FILE__, __LINE__, 4, "Compare with file '$v_stored_list[$i]'");
  2621. // ----- Compare the file names
  2622. if ($v_stored_list[$i] == $v_header[filename])
  2623. {
  2624. TrFctMessage(__FILE__, __LINE__, 3, "File '$v_stored_list[$i]' is present in archive");
  2625. TrFctMessage(__FILE__, __LINE__, 3, "File '$v_stored_list[$i]' mtime=".filemtime($p_file_list[$i])." ".date("l dS of F Y h:i:s A", filemtime($p_file_list[$i])));
  2626. TrFctMessage(__FILE__, __LINE__, 3, "Archived mtime=".$v_header[mtime]." ".date("l dS of F Y h:i:s A", $v_header[mtime]));
  2627. // ----- Store found informations
  2628. $v_found_file = TRUE;
  2629. $v_current_filename = $p_file_list[$i];
  2630. // ----- Look if the file need to be updated
  2631. if (filemtime($p_file_list[$i]) > $v_header[mtime])
  2632. {
  2633. TrFctMessage(__FILE__, __LINE__, 3, "File '$p_file_list[$i]' need to be updated");
  2634. $v_update_file = TRUE;
  2635. }
  2636. else
  2637. {
  2638. TrFctMessage(__FILE__, __LINE__, 3, "File '$p_file_list[$i]' does not need to be updated");
  2639. $v_update_file = FALSE;
  2640. }
  2641. // ----- Flag the name in order not to add the file at the end
  2642. $v_found_list[$i] = 1;
  2643. }
  2644. else
  2645. {
  2646. TrFctMessage(__FILE__, __LINE__, 4, "File '$p_file_list[$i]' is not '$v_header[filename]'");
  2647. }
  2648. }
  2649. // ----- Copy files that do not need to be updated
  2650. if (!$v_update_file)
  2651. {
  2652. TrFctMessage(__FILE__, __LINE__, 2, "Keep file '$v_header[filename]'");
  2653. // ----- Write the file header
  2654. if ($p_tar_mode == "tar")
  2655. {
  2656. fputs($v_temp_tar, $v_binary_data, 512);
  2657. }
  2658. else
  2659. {
  2660. gzputs($v_temp_tar, $v_binary_data, 512);
  2661. }
  2662. // ----- Write the file data
  2663. $n = ceil($v_header[size]/512);
  2664. for ($j=0; $j<$n; $j++)
  2665. {
  2666. TrFctMessage(__FILE__, __LINE__, 3, "Read complete 512 bytes block number ".($j+1));
  2667. if ($p_tar_mode == "tar")
  2668. {
  2669. $v_content = fread($v_tar, 512);
  2670. fwrite($v_temp_tar, $v_content, 512);
  2671. }
  2672. else
  2673. {
  2674. $v_content = gzread($v_tar, 512);
  2675. gzwrite($v_temp_tar, $v_content, 512);
  2676. }
  2677. }
  2678. // ----- File name and properties are logged if listing mode or file is extracted
  2679. TrFctMessage(__FILE__, __LINE__, 2, "Memorize info about file '$v_header[filename]'");
  2680. // ----- Add the array describing the file into the list
  2681. $p_list_detail[$v_nb] = $v_header;
  2682. $p_list_detail[$v_nb][status] = ($v_found_file?"not_updated":"ok");
  2683. // ----- Increment
  2684. $v_nb++;
  2685. }
  2686. // ----- Look for file that need to be updated
  2687. else
  2688. {
  2689. // ----- Trace
  2690. TrFctMessage(__FILE__, __LINE__, 2, "Start update of file '$v_current_filename'");
  2691. // ----- Store the old file size
  2692. $v_old_size = $v_header[size];
  2693. // ----- Add the file
  2694. if (($v_result = PclTarHandleAddFile($v_temp_tar, $v_current_filename, $p_tar_mode, $v_header, $p_add_dir, $p_remove_dir)) != 1)
  2695. {
  2696. // ----- Close the tarfile
  2697. if ($p_tar_mode == "tar")
  2698. {
  2699. fclose($v_tar);
  2700. fclose($v_temp_tar);
  2701. }
  2702. else
  2703. {
  2704. gzclose($v_tar);
  2705. gzclose($v_temp_tar);
  2706. }
  2707. @unlink($p_temp_tarname);
  2708. // ----- Return status
  2709. TrFctEnd(__FILE__, __LINE__, $v_result);
  2710. return $v_result;
  2711. }
  2712. // ----- Trace
  2713. TrFctMessage(__FILE__, __LINE__, 2, "Skip old file '$v_header[filename]'");
  2714. // ----- Jump to next file
  2715. if ($p_tar_mode == "tar")
  2716. fseek($v_tar, ftell($v_tar)+(ceil(($v_old_size/512))*512));
  2717. else
  2718. gzseek($v_tar, gztell($v_tar)+(ceil(($v_old_size/512))*512));
  2719. // ----- Add the array describing the file into the list
  2720. $p_list_detail[$v_nb] = $v_header;
  2721. $p_list_detail[$v_nb][status] = "updated";
  2722. // ----- Increment
  2723. $v_nb++;
  2724. }
  2725. // ----- Look for end of file
  2726. if ($p_tar_mode == "tar")
  2727. $v_end_of_file = feof($v_tar);
  2728. else
  2729. $v_end_of_file = gzeof($v_tar);
  2730. }
  2731. // ----- Look for files that does not exists in the archive and need to be added
  2732. for ($i=0; $i<sizeof($p_file_list); $i++)
  2733. {
  2734. // ----- Look if file not found in the archive
  2735. if (!$v_found_list[$i])
  2736. {
  2737. TrFctMessage(__FILE__, __LINE__, 3, "File '$p_file_list[$i]' need to be added");
  2738. // ----- Add the file
  2739. if (($v_result = PclTarHandleAddFile($v_temp_tar, $p_file_list[$i], $p_tar_mode, $v_header, $p_add_dir, $p_remove_dir)) != 1)
  2740. {
  2741. // ----- Close the tarfile
  2742. if ($p_tar_mode == "tar")
  2743. {
  2744. fclose($v_tar);
  2745. fclose($v_temp_tar);
  2746. }
  2747. else
  2748. {
  2749. gzclose($v_tar);
  2750. gzclose($v_temp_tar);
  2751. }
  2752. @unlink($p_temp_tarname);
  2753. // ----- Return status
  2754. TrFctEnd(__FILE__, __LINE__, $v_result);
  2755. return $v_result;
  2756. }
  2757. // ----- Add the array describing the file into the list
  2758. $p_list_detail[$v_nb] = $v_header;
  2759. $p_list_detail[$v_nb][status] = "added";
  2760. // ----- Increment
  2761. $v_nb++;
  2762. }
  2763. else
  2764. {
  2765. TrFctMessage(__FILE__, __LINE__, 3, "File '$p_file_list[$i]' was already updated if needed");
  2766. }
  2767. }
  2768. // ----- Write the last empty buffer
  2769. PclTarHandleFooter($v_temp_tar, $p_tar_mode);
  2770. // ----- Close the tarfile
  2771. if ($p_tar_mode == "tar")
  2772. {
  2773. fclose($v_tar);
  2774. fclose($v_temp_tar);
  2775. }
  2776. else
  2777. {
  2778. gzclose($v_tar);
  2779. gzclose($v_temp_tar);
  2780. }
  2781. // ----- Unlink tar file
  2782. if (!@unlink($p_tarname))
  2783. {
  2784. // ----- Error log
  2785. PclErrorLog(-11, "Error while deleting archive name $p_tarname");
  2786. }
  2787. // ----- Rename tar file
  2788. if (!@rename($v_temp_tarname, $p_tarname))
  2789. {
  2790. // ----- Error log
  2791. PclErrorLog(-12, "Error while renaming temporary file $v_temp_tarname to archive name $p_tarname");
  2792. // ----- Return
  2793. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  2794. return PclErrorCode();
  2795. }
  2796. // ----- Return
  2797. TrFctEnd(__FILE__, __LINE__, $v_result);
  2798. return $v_result;
  2799. }
  2800. // --------------------------------------------------------------------------------
  2801. // --------------------------------------------------------------------------------
  2802. // Function : PclTarHandleReadHeader()
  2803. // Description :
  2804. // Parameters :
  2805. // Return Values :
  2806. // --------------------------------------------------------------------------------
  2807. function PclTarHandleReadHeader($v_binary_data, &$v_header)
  2808. {
  2809. TrFctStart(__FILE__, __LINE__, "PclTarHandleReadHeader", "");
  2810. $v_result=1;
  2811. // ----- Read the 512 bytes header
  2812. /*
  2813. if ($p_tar_mode == "tar")
  2814. $v_binary_data = fread($p_tar, 512);
  2815. else
  2816. $v_binary_data = gzread($p_tar, 512);
  2817. */
  2818. // ----- Look for no more block
  2819. if (strlen($v_binary_data)==0)
  2820. {
  2821. $v_header[filename] = "";
  2822. $v_header[status] = "empty";
  2823. // ----- Return
  2824. TrFctEnd(__FILE__, __LINE__, $v_result, "End of archive found");
  2825. return $v_result;
  2826. }
  2827. // ----- Look for invalid block size
  2828. if (strlen($v_binary_data) != 512)
  2829. {
  2830. $v_header[filename] = "";
  2831. $v_header[status] = "invalid_header";
  2832. TrFctMessage(__FILE__, __LINE__, 2, "Invalid block size : ".strlen($v_binary_data));
  2833. // ----- Error log
  2834. PclErrorLog(-10, "Invalid block size : ".strlen($v_binary_data));
  2835. // ----- Return
  2836. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  2837. return PclErrorCode();
  2838. }
  2839. // ----- Calculate the checksum
  2840. $v_checksum = 0;
  2841. // ..... First part of the header
  2842. for ($i=0; $i<148; $i++)
  2843. {
  2844. $v_checksum+=ord(substr($v_binary_data,$i,1));
  2845. }
  2846. // ..... Ignore the checksum value and replace it by ' ' (space)
  2847. for ($i=148; $i<156; $i++)
  2848. {
  2849. $v_checksum += ord(' ');
  2850. }
  2851. // ..... Last part of the header
  2852. for ($i=156; $i<512; $i++)
  2853. {
  2854. $v_checksum+=ord(substr($v_binary_data,$i,1));
  2855. }
  2856. TrFctMessage(__FILE__, __LINE__, 3, "Calculated checksum : $v_checksum");
  2857. // ----- Extract the values
  2858. TrFctMessage(__FILE__, __LINE__, 2, "Header : '$v_binary_data'");
  2859. $v_data = unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor", $v_binary_data);
  2860. // ----- Extract the checksum for check
  2861. $v_header["checksum"] = OctDec(trim($v_data["checksum"]));
  2862. TrFctMessage(__FILE__, __LINE__, 3, "File checksum : $v_header[checksum]");
  2863. if ($v_header["checksum"] != $v_checksum)
  2864. {
  2865. TrFctMessage(__FILE__, __LINE__, 2, "File checksum is invalid : $v_checksum calculated, $v_header[checksum] expected");
  2866. $v_header["filename"] = "";
  2867. $v_header["status"] = "invalid_header";
  2868. // ----- Look for last block (empty block)
  2869. if (($v_checksum == 256) && ($v_header["checksum"] == 0))
  2870. {
  2871. $v_header["status"] = "empty";
  2872. // ----- Return
  2873. TrFctEnd(__FILE__, __LINE__, $v_result, "End of archive found");
  2874. return $v_result;
  2875. }
  2876. // ----- Error log
  2877. PclErrorLog(-13, "Invalid checksum : $v_checksum calculated, " . $v_header["checksum"] . " expected");
  2878. // ----- Return
  2879. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  2880. return PclErrorCode();
  2881. }
  2882. TrFctMessage(__FILE__, __LINE__, 2, "File checksum is valid ($v_checksum)");
  2883. // ----- Extract the properties
  2884. $v_header["filename"] = trim($v_data["filename"]);
  2885. TrFctMessage(__FILE__, __LINE__, 2, "Name : '$v_header[filename]'");
  2886. $v_header["mode"] = OctDec(trim($v_data["mode"]));
  2887. TrFctMessage(__FILE__, __LINE__, 2, "Mode : '".DecOct($v_header["mode"])."'");
  2888. $v_header["uid"] = OctDec(trim($v_data["uid"]));
  2889. TrFctMessage(__FILE__, __LINE__, 2, "Uid : '$v_header[uid]'");
  2890. $v_header["gid"] = OctDec(trim($v_data["gid"]));
  2891. TrFctMessage(__FILE__, __LINE__, 2, "Gid : '$v_header[gid]'");
  2892. $v_header["size"] = OctDec(trim($v_data["size"]));
  2893. TrFctMessage(__FILE__, __LINE__, 2, "Size : '$v_header[size]'");
  2894. $v_header["mtime"] = OctDec(trim($v_data["mtime"]));
  2895. TrFctMessage(__FILE__, __LINE__, 2, "Date : ".date("l dS of F Y h:i:s A", $v_header["mtime"]));
  2896. if (($v_header["typeflag"] = $v_data["typeflag"]) == "5")
  2897. {
  2898. $v_header["size"] = 0;
  2899. TrFctMessage(__FILE__, __LINE__, 2, "Size (folder) : '$v_header[size]'");
  2900. }
  2901. TrFctMessage(__FILE__, __LINE__, 2, "File typeflag : $v_header[typeflag]");
  2902. /* ----- All these fields are removed form the header because they do not carry interesting info
  2903. $v_header[link] = trim($v_data[link]);
  2904. TrFctMessage(__FILE__, __LINE__, 2, "Linkname : $v_header[linkname]");
  2905. $v_header[magic] = trim($v_data[magic]);
  2906. TrFctMessage(__FILE__, __LINE__, 2, "Magic : $v_header[magic]");
  2907. $v_header[version] = trim($v_data[version]);
  2908. TrFctMessage(__FILE__, __LINE__, 2, "Version : $v_header[version]");
  2909. $v_header[uname] = trim($v_data[uname]);
  2910. TrFctMessage(__FILE__, __LINE__, 2, "Uname : $v_header[uname]");
  2911. $v_header[gname] = trim($v_data[gname]);
  2912. TrFctMessage(__FILE__, __LINE__, 2, "Gname : $v_header[gname]");
  2913. $v_header[devmajor] = trim($v_data[devmajor]);
  2914. TrFctMessage(__FILE__, __LINE__, 2, "Devmajor : $v_header[devmajor]");
  2915. $v_header[devminor] = trim($v_data[devminor]);
  2916. TrFctMessage(__FILE__, __LINE__, 2, "Devminor : $v_header[devminor]");
  2917. */
  2918. // ----- Set the status field
  2919. $v_header["status"] = "ok";
  2920. // ----- Return
  2921. TrFctEnd(__FILE__, __LINE__, $v_result);
  2922. return $v_result;
  2923. }
  2924. // --------------------------------------------------------------------------------
  2925. // --------------------------------------------------------------------------------
  2926. // Function : PclTarHandlerDirCheck()
  2927. // Description :
  2928. // Check if a directory exists, if not it creates it and all the parents directory
  2929. // which may be useful.
  2930. // Parameters :
  2931. // $p_dir : Directory path to check (without / at the end).
  2932. // Return Values :
  2933. // 1 : OK
  2934. // -1 : Unable to create directory
  2935. // --------------------------------------------------------------------------------
  2936. function PclTarHandlerDirCheck($p_dir)
  2937. {
  2938. $v_result = 1;
  2939. TrFctStart(__FILE__, __LINE__, "PclTarHandlerDirCheck", "$p_dir");
  2940. // ----- Check the directory availability
  2941. if ((is_dir($p_dir)) || ($p_dir == ""))
  2942. {
  2943. TrFctEnd(__FILE__, __LINE__, "'$p_dir' is a directory");
  2944. return 1;
  2945. }
  2946. // ----- Look for file alone
  2947. /*
  2948. if (!strstr("$p_dir", "/"))
  2949. {
  2950. TrFctEnd(__FILE__, __LINE__, "'$p_dir' is a file with no directory");
  2951. return 1;
  2952. }
  2953. */
  2954. // ----- Extract parent directory
  2955. $p_parent_dir = dirname($p_dir);
  2956. TrFctMessage(__FILE__, __LINE__, 3, "Parent directory is '$p_parent_dir'");
  2957. // ----- Just a check
  2958. if ($p_parent_dir != $p_dir)
  2959. {
  2960. // ----- Look for parent directory
  2961. if ($p_parent_dir != "")
  2962. {
  2963. if (($v_result = PclTarHandlerDirCheck($p_parent_dir)) != 1)
  2964. {
  2965. TrFctEnd(__FILE__, __LINE__, $v_result);
  2966. return $v_result;
  2967. }
  2968. }
  2969. }
  2970. // ----- Create the directory
  2971. TrFctMessage(__FILE__, __LINE__, 3, "Create directory '$p_dir'");
  2972. if (!@mkdir($p_dir, 0777))
  2973. {
  2974. // ----- Error log
  2975. PclErrorLog(-8, "Unable to create directory '$p_dir'");
  2976. // ----- Return
  2977. TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  2978. return PclErrorCode();
  2979. }
  2980. // ----- Return
  2981. TrFctEnd(__FILE__, __LINE__, $v_result, "Directory '$p_dir' created");
  2982. return $v_result;
  2983. }
  2984. // --------------------------------------------------------------------------------
  2985. // --------------------------------------------------------------------------------
  2986. // Function : PclTarHandleExtension()
  2987. // Description :
  2988. // Parameters :
  2989. // Return Values :
  2990. // --------------------------------------------------------------------------------
  2991. function PclTarHandleExtension($p_tarname)
  2992. {
  2993. TrFctStart(__FILE__, __LINE__, "PclTarHandleExtension", "tar=$p_tarname");
  2994. // ----- Look for file extension
  2995. if ((substr($p_tarname, -7) == ".tar.gz") || (substr($p_tarname, -4) == ".tgz"))
  2996. {
  2997. TrFctMessage(__FILE__, __LINE__, 2, "Archive is a gzip tar");
  2998. $v_tar_mode = "tgz";
  2999. }
  3000. else if (substr($p_tarname, -4) == ".tar")
  3001. {
  3002. TrFctMessage(__FILE__, __LINE__, 2, "Archive is a tar");
  3003. $v_tar_mode = "tar";
  3004. }
  3005. else
  3006. {
  3007. // ----- Error log
  3008. PclErrorLog(-9, "Invalid archive extension");
  3009. TrFctMessage(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
  3010. $v_tar_mode = "";
  3011. }
  3012. // ----- Return
  3013. TrFctEnd(__FILE__, __LINE__, $v_tar_mode);
  3014. return $v_tar_mode;
  3015. }
  3016. // --------------------------------------------------------------------------------
  3017. // --------------------------------------------------------------------------------
  3018. // Function : PclTarHandlePathReduction()
  3019. // Description :
  3020. // Parameters :
  3021. // Return Values :
  3022. // --------------------------------------------------------------------------------
  3023. function PclTarHandlePathReduction($p_dir)
  3024. {
  3025. TrFctStart(__FILE__, __LINE__, "PclTarHandlePathReduction", "dir='$p_dir'");
  3026. $v_result = "";
  3027. // ----- Look for not empty path
  3028. if ($p_dir != "")
  3029. {
  3030. // ----- Explode path by directory names
  3031. $v_list = explode("/", $p_dir);
  3032. // ----- Study directories from last to first
  3033. for ($i=sizeof($v_list)-1; $i>=0; $i--)
  3034. {
  3035. // ----- Look for current path
  3036. if ($v_list[$i] == ".")
  3037. {
  3038. // ----- Ignore this directory
  3039. // Should be the first $i=0, but no check is done
  3040. }
  3041. else if ($v_list[$i] == "..")
  3042. {
  3043. // ----- Ignore it and ignore the $i-1
  3044. $i--;
  3045. }
  3046. else if (($v_list[$i] == "") && ($i!=(sizeof($v_list)-1)) && ($i!=0))
  3047. {
  3048. // ----- Ignore only the double '//' in path,
  3049. // but not the first and last '/'
  3050. }
  3051. else
  3052. {
  3053. $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:"");
  3054. }
  3055. }
  3056. }
  3057. // ----- Return
  3058. TrFctEnd(__FILE__, __LINE__, $v_result);
  3059. return $v_result;
  3060. }
  3061. // --------------------------------------------------------------------------------
  3062. // ----- End of double include look
  3063. }
  3064. ?>