PageRenderTime 38ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/dist/webpagetest/www/lib/pcltar.lib.php3

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