PageRenderTime 68ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

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

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