2 // --------------------------------------------------------------------------------
3 // PhpConcept Library - Tar Module 1.3.1
4 // --------------------------------------------------------------------------------
5 // License GNU/GPL - Vincent Blavet - January 2003
6 // http://www.phpconcept.net
7 // --------------------------------------------------------------------------------
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.
16 // See readme.txt (English & Fran�ais) and http://www.phpconcept.net
19 // This library and the associated files are non commercial, non professional
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.
25 // --------------------------------------------------------------------------------
27 // ----- Look for double include
28 if (!defined("PCL_TAR"))
30 define( "PCL_TAR", 1 );
32 // ----- Configuration variable
33 // Theses values may be changed by the user of PclTar library
34 if (!isset($g_pcltar_lib_dir))
35 $g_pcltar_lib_dir = find_in_path("lib/pcltar");
38 // -1 : Unable to open file in binary write mode
39 // -2 : Unable to open file in binary read mode
40 // -3 : Invalid parameters
41 // -4 : File does not exist
42 // -5 : Filename is too long (max. 99)
43 // -6 : Not a valid tar file
44 // -7 : Invalid extracted file size
45 // -8 : Unable to create directory
46 // -9 : Invalid archive extension
47 // -10 : Invalid archive format
48 // -11 : Unable to delete file (unlink)
49 // -12 : Unable to rename file (rename)
50 // -13 : Invalid header checksum
53 // --------------------------------------------------------------------------------
54 // ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED *****
55 // --------------------------------------------------------------------------------
57 // ----- Global variables
58 $g_pcltar_version = "1.3.1";
60 // ----- Extract extension type (.php3/.php/...)
61 $g_pcltar_extension = "php";
63 // ----- Include other libraries
64 // This library should be called by each script before the include of PhpZip
65 // Library in order to limit the potential 'lib' directory path problem.
66 if (!defined("PCLERROR_LIB"))
68 include($g_pcltar_lib_dir."/pclerror.lib.".$g_pcltar_extension);
70 if (!defined("PCLTRACE_LIB"))
72 include($g_pcltar_lib_dir."/pcltrace.lib.".$g_pcltar_extension);
75 // --------------------------------------------------------------------------------
76 // Function : PclTarCreate()
78 // Creates a new archive with name $p_tarname containing the files and/or
79 // directories indicated in $p_list. If the tar filename extension is
80 // ".tar", the file will not be compressed. If it is ".tar.gz" or ".tgz"
81 // it will be a gzip compressed tar archive.
82 // If you want to use an other extension, you must indicate the mode in
83 // $p_mode ("tar" or "tgz").
84 // $p_add_dir and $p_remove_dir give you the ability to store a path
85 // which is not the real path of the files.
87 // $p_tarname : Name of an existing tar file
88 // $p_filelist : An array containing file or directory names, or
89 // a string containing one filename or directory name, or
90 // a string containing a list of filenames and/or directory
91 // names separated by spaces.
92 // $p_mode : "tar" for normal tar archive, "tgz" for gzipped tar archive,
93 // if $p_mode is not specified, it will be determined by the extension.
94 // $p_add_dir : Path to add in the filename path archived
95 // $p_remove_dir : Path to remove in the filename path archived
97 // 1 on success, or an error code (see table at the beginning).
98 // --------------------------------------------------------------------------------
99 function PclTarCreate($p_tarname, $p_filelist="", $p_mode="", $p_add_dir="", $p_remove_dir="")
101 TrFctStart(__FILE__
, __LINE__
, "PclTarCreate", "tar=$p_tarname, file='$p_filelist', mode=$p_mode, add_dir='$p_add_dir', remove_dir='$p_remove_dir'");
104 // ----- Look for default mode
105 if (($p_mode == "") ||
(($p_mode!="tar") && ($p_mode!="tgz")))
107 // ----- Extract the tar format from the extension
108 if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
111 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
112 return PclErrorCode();
116 TrFctMessage(__FILE__
, __LINE__
, 1, "Auto mode selected : found $p_mode");
119 // ----- Look if the $p_filelist is really an array
120 if (is_array($p_filelist))
122 // ----- Call the create fct
123 $v_result = PclTarHandleCreate($p_tarname, $p_filelist, $p_mode, $p_add_dir, $p_remove_dir);
126 // ----- Look if the $p_filelist is a string
127 else if (is_string($p_filelist))
129 // ----- Create a list with the elements from the string
130 $v_list = explode(" ", $p_filelist);
132 // ----- Call the create fct
133 $v_result = PclTarHandleCreate($p_tarname, $v_list, $p_mode, $p_add_dir, $p_remove_dir);
136 // ----- Invalid variable
140 PclErrorLog(-3, "Invalid variable type p_filelist");
145 TrFctEnd(__FILE__
, __LINE__
, $v_result);
148 // --------------------------------------------------------------------------------
150 // --------------------------------------------------------------------------------
151 // Function : PclTarAdd()
153 // PLEASE DO NOT USE ANY MORE THIS FUNCTION. Use PclTarAddList().
155 // This function is maintained only for compatibility reason
158 // $p_tarname : Name of an existing tar file
159 // $p_filelist : An array containing file or directory names, or
160 // a string containing one filename or directory name, or
161 // a string containing a list of filenames and/or directory
162 // names separated by spaces.
165 // Or an error code (see list on top).
166 // --------------------------------------------------------------------------------
167 function PclTarAdd($p_tarname, $p_filelist)
169 TrFctStart(__FILE__
, __LINE__
, "PclTarAdd", "tar=$p_tarname, file=$p_filelist");
171 $v_list_detail = array();
173 // ----- Extract the tar format from the extension
174 if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
177 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
178 return PclErrorCode();
181 // ----- Look if the $p_filelist is really an array
182 if (is_array($p_filelist))
184 // ----- Call the add fct
185 $v_result = PclTarHandleAppend($p_tarname, $p_filelist, $p_mode, $v_list_detail, "", "");
188 // ----- Look if the $p_filelist is a string
189 else if (is_string($p_filelist))
191 // ----- Create a list with the elements from the string
192 $v_list = explode(" ", $p_filelist);
194 // ----- Call the add fct
195 $v_result = PclTarHandleAppend($p_tarname, $v_list, $p_mode, $v_list_detail, "", "");
198 // ----- Invalid variable
202 PclErrorLog(-3, "Invalid variable type p_filelist");
207 unset($v_list_detail);
210 TrFctEnd(__FILE__
, __LINE__
, $v_result);
213 // --------------------------------------------------------------------------------
215 // --------------------------------------------------------------------------------
216 // Function : PclTarAddList()
218 // Add a list of files or directories ($p_filelist) in the tar archive $p_tarname.
219 // The list can be an array of file/directory names or a string with names
220 // separated by one space.
221 // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
222 // different from the real path of the file. This is usefull if you want to have PclTar
223 // running in any directory, and memorize relative path from an other directory.
224 // If $p_mode is not set it will be automatically computed from the $p_tarname
225 // extension (.tar, .tar.gz or .tgz).
227 // $p_tarname : Name of an existing tar file
228 // $p_filelist : An array containing file or directory names, or
229 // a string containing one filename or directory name, or
230 // a string containing a list of filenames and/or directory
231 // names separated by spaces.
232 // $p_add_dir : Path to add in the filename path archived
233 // $p_remove_dir : Path to remove in the filename path archived
234 // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
237 // Or an error code (see list on top).
238 // --------------------------------------------------------------------------------
239 function PclTarAddList($p_tarname, $p_filelist, $p_add_dir="", $p_remove_dir="", $p_mode="")
241 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");
243 $p_list_detail = array();
245 // ----- Extract the tar format from the extension
246 if (($p_mode == "") ||
(($p_mode!="tar") && ($p_mode!="tgz")))
248 if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
251 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
252 return PclErrorCode();
256 // ----- Look if the $p_filelist is really an array
257 if (is_array($p_filelist))
259 // ----- Call the add fct
260 $v_result = PclTarHandleAppend($p_tarname, $p_filelist, $p_mode, $p_list_detail, $p_add_dir, $p_remove_dir);
263 // ----- Look if the $p_filelist is a string
264 else if (is_string($p_filelist))
266 // ----- Create a list with the elements from the string
267 $v_list = explode(" ", $p_filelist);
269 // ----- Call the add fct
270 $v_result = PclTarHandleAppend($p_tarname, $v_list, $p_mode, $p_list_detail, $p_add_dir, $p_remove_dir);
273 // ----- Invalid variable
277 PclErrorLog(-3, "Invalid variable type p_filelist");
284 TrFctEnd(__FILE__
, __LINE__
, 0);
287 TrFctEnd(__FILE__
, __LINE__
, $p_list_detail);
288 return $p_list_detail;
290 // --------------------------------------------------------------------------------
292 // --------------------------------------------------------------------------------
293 // Function : PclTarList()
295 // Gives the list of all the files present in the tar archive $p_tarname.
296 // The list is the function result, it will be 0 on error.
297 // Depending on the $p_tarname extension (.tar, .tar.gz or .tgz) the
298 // function will determine the type of the archive.
300 // $p_tarname : Name of an existing tar file
301 // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
303 // 0 on error (Use PclErrorCode() and PclErrorString() for more info)
305 // An array containing file properties. Each file properties is an array of
307 // The properties (array field names) are :
308 // filename, size, mode, uid, gid, mtime, typeflag, status
309 // Exemple : $v_list = PclTarList("my.tar");
310 // for ($i=0; $i<sizeof($v_list); $i++)
311 // echo "Filename :'".$v_list[$i][filename]."'<br>";
312 // --------------------------------------------------------------------------------
313 function PclTarList($p_tarname, $p_mode="")
315 TrFctStart(__FILE__
, __LINE__
, "PclTarList", "tar=$p_tarname, mode='$p_mode'");
318 // ----- Extract the tar format from the extension
319 if (($p_mode == "") ||
(($p_mode!="tar") && ($p_mode!="tgz")))
321 if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
324 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
329 // ----- Call the extracting fct
331 if (($v_result = PclTarHandleExtract($p_tarname, 0, $p_list, "list", "", $p_mode, "")) != 1)
334 TrFctEnd(__FILE__
, __LINE__
, 0, PclErrorString());
339 TrFctEnd(__FILE__
, __LINE__
, $p_list);
342 // --------------------------------------------------------------------------------
344 // --------------------------------------------------------------------------------
345 // Function : PclTarExtract()
347 // Extract all the files present in the archive $p_tarname, in the directory
348 // $p_path. The relative path of the archived files are keep and become
349 // relative to $p_path.
350 // If a file with the same name already exists it will be replaced.
351 // If the path to the file does not exist, it will be created.
352 // Depending on the $p_tarname extension (.tar, .tar.gz or .tgz) the
353 // function will determine the type of the archive.
355 // $p_tarname : Name of an existing tar file.
356 // $p_path : Path where the files will be extracted. The files will use
357 // their memorized path from $p_path.
358 // If $p_path is "", files will be extracted in "./".
359 // $p_remove_path : Path to remove (from the file memorized path) while writing the
360 // extracted files. If the path does not match the file path,
361 // the file is extracted with its memorized path.
362 // $p_path and $p_remove_path are commulative.
363 // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
365 // Same as PclTarList()
366 // --------------------------------------------------------------------------------
367 function PclTarExtract($p_tarname, $p_path="./", $p_remove_path="", $p_mode="")
369 TrFctStart(__FILE__
, __LINE__
, "PclTarExtract", "tar='$p_tarname', path='$p_path', remove_path='$p_remove_path', mode='$p_mode'");
372 // ----- Extract the tar format from the extension
373 if (($p_mode == "") ||
(($p_mode!="tar") && ($p_mode!="tgz")))
375 if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
378 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
383 // ----- Call the extracting fct
384 if (($v_result = PclTarHandleExtract($p_tarname, 0, $p_list, "complete", $p_path, $v_tar_mode, $p_remove_path)) != 1)
386 TrFctEnd(__FILE__
, __LINE__
, 0, PclErrorString());
391 TrFctEnd(__FILE__
, __LINE__
, $p_list);
394 // --------------------------------------------------------------------------------
396 // --------------------------------------------------------------------------------
397 // Function : PclTarExtractList()
399 // Extract the files present in the archive $p_tarname and specified in
400 // $p_filelist, in the directory
401 // $p_path. The relative path of the archived files are keep and become
402 // relative to $p_path.
403 // If a directory is sp�cified in the list, all the files from this directory
404 // will be extracted.
405 // If a file with the same name already exists it will be replaced.
406 // If the path to the file does not exist, it will be created.
407 // Depending on the $p_tarname extension (.tar, .tar.gz or .tgz) the
408 // function will determine the type of the archive.
410 // $p_tarname : Name of an existing tar file
411 // $p_filelist : An array containing file or directory names, or
412 // a string containing one filename or directory name, or
413 // a string containing a list of filenames and/or directory
414 // names separated by spaces.
415 // $p_path : Path where the files will be extracted. The files will use
416 // their memorized path from $p_path.
417 // If $p_path is "", files will be extracted in "./".
418 // $p_remove_path : Path to remove (from the file memorized path) while writing the
419 // extracted files. If the path does not match the file path,
420 // the file is extracted with its memorized path.
421 // $p_path and $p_remove_path are commulative.
422 // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
424 // Same as PclTarList()
425 // --------------------------------------------------------------------------------
426 function PclTarExtractList($p_tarname, $p_filelist, $p_path="./", $p_remove_path="", $p_mode="")
428 TrFctStart(__FILE__
, __LINE__
, "PclTarExtractList", "tar=$p_tarname, list, path=$p_path, remove_path='$p_remove_path', mode='$p_mode'");
431 // ----- Extract the tar format from the extension
432 if (($p_mode == "") ||
(($p_mode!="tar") && ($p_mode!="tgz")))
434 if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
437 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
442 // ----- Look if the $p_filelist is really an array
443 if (is_array($p_filelist))
445 // ----- Call the extracting fct
446 if (($v_result = PclTarHandleExtract($p_tarname, $p_filelist, $p_list, "partial", $p_path, $v_tar_mode, $p_remove_path)) != 1)
448 TrFctEnd(__FILE__
, __LINE__
, 0, PclErrorString());
453 // ----- Look if the $p_filelist is a string
454 else if (is_string($p_filelist))
456 // ----- Create a list with the elements from the string
457 $v_list = explode(" ", $p_filelist);
459 // ----- Call the extracting fct
460 if (($v_result = PclTarHandleExtract($p_tarname, $v_list, $p_list, "partial", $p_path, $v_tar_mode, $p_remove_path)) != 1)
462 TrFctEnd(__FILE__
, __LINE__
, 0, PclErrorString());
467 // ----- Invalid variable
471 PclErrorLog(-3, "Invalid variable type p_filelist");
474 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
479 TrFctEnd(__FILE__
, __LINE__
, $p_list);
482 // --------------------------------------------------------------------------------
484 // --------------------------------------------------------------------------------
485 // Function : PclTarExtractIndex()
487 // Extract the files present in the archive $p_tarname and specified at
488 // the indexes in $p_index, in the directory
489 // $p_path. The relative path of the archived files are keep and become
490 // relative to $p_path.
491 // If a directory is specified in the list, the directory only is created. All
492 // the file stored in this archive for this directory
493 // are not extracted.
494 // If a file with the same name already exists it will be replaced.
495 // If the path to the file does not exist, it will be created.
496 // Depending on the $p_tarname extension (.tar, .tar.gz or .tgz) the
497 // function will determine the type of the archive.
499 // $p_tarname : Name of an existing tar file
500 // $p_index : A single index (integer) or a string of indexes of files to
501 // extract. The form of the string is "0,4-6,8-12" with only numbers
502 // and '-' for range or ',' to separate ranges. No spaces or ';'
504 // $p_path : Path where the files will be extracted. The files will use
505 // their memorized path from $p_path.
506 // If $p_path is "", files will be extracted in "./".
507 // $p_remove_path : Path to remove (from the file memorized path) while writing the
508 // extracted files. If the path does not match the file path,
509 // the file is extracted with its memorized path.
510 // $p_path and $p_remove_path are commulative.
511 // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
513 // Same as PclTarList()
514 // --------------------------------------------------------------------------------
515 function PclTarExtractIndex($p_tarname, $p_index, $p_path="./", $p_remove_path="", $p_mode="")
517 TrFctStart(__FILE__
, __LINE__
, "PclTarExtractIndex", "tar=$p_tarname, index='$p_index', path=$p_path, remove_path='$p_remove_path', mode='$p_mode'");
520 // ----- Extract the tar format from the extension
521 if (($p_mode == "") ||
(($p_mode!="tar") && ($p_mode!="tgz")))
523 if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
526 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
531 // ----- Look if the $p_index is really an integer
532 if (is_integer($p_index))
534 // ----- Call the extracting fct
535 if (($v_result = PclTarHandleExtractByIndexList($p_tarname, "$p_index", $p_list, $p_path, $p_remove_path, $v_tar_mode)) != 1)
537 TrFctEnd(__FILE__
, __LINE__
, 0, PclErrorString());
542 // ----- Look if the $p_filelist is a string
543 else if (is_string($p_index))
545 // ----- Call the extracting fct
546 if (($v_result = PclTarHandleExtractByIndexList($p_tarname, $p_index, $p_list, $p_path, $p_remove_path, $v_tar_mode)) != 1)
548 TrFctEnd(__FILE__
, __LINE__
, 0, PclErrorString());
553 // ----- Invalid variable
557 PclErrorLog(-3, "Invalid variable type $p_index");
560 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
565 TrFctEnd(__FILE__
, __LINE__
, $p_list);
568 // --------------------------------------------------------------------------------
570 // --------------------------------------------------------------------------------
571 // Function : PclTarDelete()
573 // This function deletes from the archive $p_tarname the files which are listed
574 // in $p_filelist. $p_filelist can be a string with file names separated by
575 // spaces, or an array containing the file names.
577 // $p_tarname : Name of an existing tar file
578 // $p_filelist : An array or a string containing file names to remove from the
580 // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
582 // List of the files which are kept in the archive (same format as PclTarList())
583 // --------------------------------------------------------------------------------
584 function PclTarDelete($p_tarname, $p_filelist, $p_mode="")
586 TrFctStart(__FILE__
, __LINE__
, "PclTarDelete", "tar='$p_tarname', list='$p_filelist', mode='$p_mode'");
589 // ----- Extract the tar format from the extension
590 if (($p_mode == "") ||
(($p_mode!="tar") && ($p_mode!="tgz")))
592 if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
595 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
600 // ----- Look if the $p_filelist is really an array
601 if (is_array($p_filelist))
603 // ----- Call the extracting fct
604 if (($v_result = PclTarHandleDelete($p_tarname, $p_filelist, $p_list, $p_mode)) != 1)
606 TrFctEnd(__FILE__
, __LINE__
, 0, PclErrorString());
611 // ----- Look if the $p_filelist is a string
612 else if (is_string($p_filelist))
614 // ----- Create a list with the elements from the string
615 $v_list = explode(" ", $p_filelist);
617 // ----- Call the extracting fct
618 if (($v_result = PclTarHandleDelete($p_tarname, $v_list, $p_list, $p_mode)) != 1)
620 TrFctEnd(__FILE__
, __LINE__
, 0, PclErrorString());
625 // ----- Invalid variable
629 PclErrorLog(-3, "Invalid variable type p_filelist");
632 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
637 TrFctEnd(__FILE__
, __LINE__
, $p_list);
640 // --------------------------------------------------------------------------------
642 // --------------------------------------------------------------------------------
643 // Function : PclTarUpdate()
645 // This function updates the files in $p_filelist which are already in the
646 // $p_tarname archive with an older last modified date. If the file does not
647 // exist, it is added at the end of the archive.
649 // $p_tarname : Name of an existing tar file
650 // $p_filelist : An array or a string containing file names to update from the
652 // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
654 // List of the files contained in the archive. The field status contains
655 // "updated", "not_updated", "added" or "ok" for the files not concerned.
656 // --------------------------------------------------------------------------------
657 function PclTarUpdate($p_tarname, $p_filelist, $p_mode="", $p_add_dir="", $p_remove_dir="")
659 TrFctStart(__FILE__
, __LINE__
, "PclTarUpdate", "tar='$p_tarname', list='$p_filelist', mode='$p_mode'");
662 // ----- Extract the tar format from the extension
663 if (($p_mode == "") ||
(($p_mode!="tar") && ($p_mode!="tgz")))
665 if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
668 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
673 // ----- Look if the $p_filelist is really an array
674 if (is_array($p_filelist))
676 // ----- Call the extracting fct
677 if (($v_result = PclTarHandleUpdate($p_tarname, $p_filelist, $p_list, $p_mode, $p_add_dir, $p_remove_dir)) != 1)
679 TrFctEnd(__FILE__
, __LINE__
, 0, PclErrorString());
684 // ----- Look if the $p_filelist is a string
685 else if (is_string($p_filelist))
687 // ----- Create a list with the elements from the string
688 $v_list = explode(" ", $p_filelist);
690 // ----- Call the extracting fct
691 if (($v_result = PclTarHandleUpdate($p_tarname, $v_list, $p_list, $p_mode, $p_add_dir, $p_remove_dir)) != 1)
693 TrFctEnd(__FILE__
, __LINE__
, 0, PclErrorString());
698 // ----- Invalid variable
702 PclErrorLog(-3, "Invalid variable type p_filelist");
705 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
710 TrFctEnd(__FILE__
, __LINE__
, $p_list);
713 // --------------------------------------------------------------------------------
716 // --------------------------------------------------------------------------------
717 // Function : PclTarMerge()
719 // This function add the content of $p_tarname_add at the end of $p_tarname.
721 // $p_tarname : Name of an existing tar file
722 // $p_tarname_add : Name of an existing tar file taht will be added at the end
724 // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
725 // $p_mode_add : 'tar' or 'tgz', if not set, will be determined by $p_tarname_add
728 // List of the files contained in the archive. The field status contains
729 // "updated", "not_updated", "added" or "ok" for the files not concerned.
730 // --------------------------------------------------------------------------------
731 function PclTarMerge($p_tarname, $p_tarname_add, $p_mode="", $p_mode_add="")
733 TrFctStart(__FILE__
, __LINE__
, "PclTarMerge", "tar='$p_tarname', tar_add='$p_tarname_add', mode='$p_mode', mode_add='$p_mode_add'");
736 // ----- Check the parameters
737 if (($p_tarname == "") ||
($p_tarname_add == ""))
740 PclErrorLog(-3, "Invalid empty archive name");
743 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
744 return PclErrorCode();
747 // ----- Extract the tar format from the extension
748 if (($p_mode == "") ||
(($p_mode!="tar") && ($p_mode!="tgz")))
750 if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
753 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
757 if (($p_mode_add == "") ||
(($p_mode_add!="tar") && ($p_mode_add!="tgz")))
759 if (($p_mode_add = PclTarHandleExtension($p_tarname_add)) == "")
762 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
767 // ----- Clear filecache
770 // ----- Check the file size
771 if ((!is_file($p_tarname)) ||
772 (((($v_size = filesize($p_tarname)) %
512) != 0) && ($p_mode=="tar")))
775 if (!is_file($p_tarname))
776 PclErrorLog(-4, "Archive '$p_tarname' does not exist");
778 PclErrorLog(-6, "Archive '$p_tarname' has invalid size ".filesize($p_tarname)."(not a 512 block multiple)");
781 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
782 return PclErrorCode();
784 if ((!is_file($p_tarname_add)) ||
785 (((($v_size_add = filesize($p_tarname_add)) %
512) != 0) && ($p_mode_add=="tar")))
788 if (!is_file($p_tarname_add))
789 PclErrorLog(-4, "Archive '$p_tarname_add' does not exist");
791 PclErrorLog(-6, "Archive '$p_tarname_add' has invalid size ".filesize($p_tarname_add)."(not a 512 block multiple)");
794 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
795 return PclErrorCode();
798 // ----- Look for compressed archive
799 if ($p_mode == "tgz")
801 // ----- Open the file in read mode
802 if (($p_tar = @gzopen
($p_tarname, "rb")) == 0)
805 PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode");
808 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
809 return PclErrorCode();
812 // ----- Open a temporary file in write mode
813 $v_temp_tarname = uniqid("pcltar-").".tmp";
814 TrFctMessage(__FILE__
, __LINE__
, 2, "Creating temporary archive file $v_temp_tarname");
815 if (($v_temp_tar = @gzopen
($v_temp_tarname, "wb")) == 0)
817 // ----- Close tar file
821 PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode");
824 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
825 return PclErrorCode();
828 // ----- Read the first 512 bytes block
829 $v_buffer = gzread($p_tar, 512);
831 // ----- Read the following blocks but not the last one
834 TrFctMessage(__FILE__
, __LINE__
, 3, "More than one 512 block file");
837 // ----- Read new 512 block and write the already read
839 // ----- Write the already read block
840 $v_binary_data = pack("a512", "$v_buffer");
841 gzputs($v_temp_tar, $v_binary_data);
844 TrFctMessage(__FILE__
, __LINE__
, 3, "Reading block $i");
846 // ----- Read next block
847 $v_buffer = gzread($p_tar, 512);
849 } while (!gzeof($p_tar));
851 TrFctMessage(__FILE__
, __LINE__
, 3, "$i 512 bytes blocks");
855 // ----- Look for uncompressed tar file
856 else if ($p_mode=="tar")
858 // ----- Open the tar file
859 if (($p_tar = fopen($p_tarname, "r+b")) == 0)
862 PclErrorLog(-1, "Unable to open file '$p_tarname' in binary write mode");
865 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
866 return PclErrorCode();
869 // ----- Go to the beginning of last block
870 TrFctMessage(__FILE__
, __LINE__
, 4, "Position before :".($p_mode=="tar"?
ftell($p_tar):gztell($p_tar)));
871 fseek($p_tar, $v_size-512);
872 TrFctMessage(__FILE__
, __LINE__
, 4, "Position after :".($p_mode=="tar"?
ftell($p_tar):gztell($p_tar)));
875 // ----- Look for unknown type
879 PclErrorLog(-3, "Invalid tar mode $p_mode");
882 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
883 return PclErrorCode();
886 // ----- Look for type of archive to add
887 if ($p_mode_add == "tgz")
889 TrFctMessage(__FILE__
, __LINE__
, 4, "Opening file $p_tarname_add");
891 // ----- Open the file in read mode
892 if (($p_tar_add = @gzopen
($p_tarname_add, "rb")) == 0)
895 PclErrorLog(-2, "Unable to open file '$p_tarname_add' in binary read mode");
898 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
899 return PclErrorCode();
902 // ----- Read the first 512 bytes block
903 $v_buffer = gzread($p_tar_add, 512);
905 // ----- Read the following blocks but not the last one
906 if (!gzeof($p_tar_add))
908 TrFctMessage(__FILE__
, __LINE__
, 3, "More than one 512 block file");
911 // ----- Read new 512 block and write the already read
913 // ----- Write the already read block
914 $v_binary_data = pack("a512", "$v_buffer");
916 fputs($p_tar, $v_binary_data);
918 gzputs($v_temp_tar, $v_binary_data);
921 TrFctMessage(__FILE__
, __LINE__
, 3, "Reading block $i");
923 // ----- Read next block
924 $v_buffer = gzread($p_tar_add, 512);
926 } while (!gzeof($p_tar_add));
928 TrFctMessage(__FILE__
, __LINE__
, 3, "$i 512 bytes blocks");
931 // ----- Close the files
935 // ----- Look for uncompressed tar file
936 else if ($p_mode=="tar")
938 // ----- Open the file in read mode
939 if (($p_tar_add = @fopen
($p_tarname_add, "rb")) == 0)
942 PclErrorLog(-2, "Unable to open file '$p_tarname_add' in binary read mode");
945 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
946 return PclErrorCode();
949 // ----- Read the first 512 bytes block
950 $v_buffer = fread($p_tar_add, 512);
952 // ----- Read the following blocks but not the last one
953 if (!feof($p_tar_add))
955 TrFctMessage(__FILE__
, __LINE__
, 3, "More than one 512 block file");
958 // ----- Read new 512 block and write the already read
960 // ----- Write the already read block
961 $v_binary_data = pack("a512", "$v_buffer");
963 fputs($p_tar, $v_binary_data);
965 gzputs($v_temp_tar, $v_binary_data);
968 TrFctMessage(__FILE__
, __LINE__
, 3, "Reading block $i");
970 // ----- Read next block
971 $v_buffer = fread($p_tar_add, 512);
973 } while (!feof($p_tar_add));
975 TrFctMessage(__FILE__
, __LINE__
, 3, "$i 512 bytes blocks");
978 // ----- Close the files
982 // ----- Call the footer of the tar archive
983 $v_result = PclTarHandleFooter($p_tar, $p_mode);
985 // ----- Look for closing compressed archive
986 if ($p_mode == "tgz")
988 // ----- Close the files
990 gzclose($v_temp_tar);
992 // ----- Unlink tar file
993 if (!@unlink
($p_tarname))
996 PclErrorLog(-11, "Error while deleting archive name $p_tarname");
999 // ----- Rename tar file
1000 if (!@rename
($v_temp_tarname, $p_tarname))
1003 PclErrorLog(-12, "Error while renaming temporary file $v_temp_tarname to archive name $p_tarname");
1006 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
1007 return PclErrorCode();
1011 TrFctEnd(__FILE__
, __LINE__
, $v_result);
1015 // ----- Look for closing uncompressed tar file
1016 else if ($p_mode=="tar")
1018 // ----- Close the tarfile
1023 TrFctEnd(__FILE__
, __LINE__
, $v_result);
1026 // --------------------------------------------------------------------------------
1029 // --------------------------------------------------------------------------------
1030 // ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
1032 // ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY *****
1033 // --------------------------------------------------------------------------------
1037 // --------------------------------------------------------------------------------
1038 // Function : PclTarHandleCreate()
1041 // $p_tarname : Name of the tar file
1042 // $p_list : An array containing the file or directory names to add in the tar
1043 // $p_mode : "tar" for normal tar archive, "tgz" for gzipped tar archive
1045 // --------------------------------------------------------------------------------
1046 function PclTarHandleCreate($p_tarname, $p_list, $p_mode, $p_add_dir="", $p_remove_dir="")
1048 TrFctStart(__FILE__
, __LINE__
, "PclTarHandleCreate", "tar=$p_tarname, list, mode=$p_mode, add_dir='$p_add_dir', remove_dir='$p_remove_dir'");
1050 $v_list_detail = array();
1052 // ----- Check the parameters
1053 if (($p_tarname == "") ||
(($p_mode != "tar") && ($p_mode != "tgz")))
1056 if ($p_tarname == "")
1057 PclErrorLog(-3, "Invalid empty archive name");
1059 PclErrorLog(-3, "Unknown mode '$p_mode'");
1062 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
1063 return PclErrorCode();
1066 // ----- Look for tar file
1067 if ($p_mode == "tar")
1069 // ----- Open the tar file
1070 if (($p_tar = fopen($p_tarname, "wb")) == 0)
1073 PclErrorLog(-1, "Unable to open file [$p_tarname] in binary write mode");
1076 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
1077 return PclErrorCode();
1080 // ----- Call the adding fct inside the tar
1081 if (($v_result = PclTarHandleAddList($p_tar, $p_list, $p_mode, $v_list_detail, $p_add_dir, $p_remove_dir)) == 1)
1083 // ----- Call the footer of the tar archive
1084 $v_result = PclTarHandleFooter($p_tar, $p_mode);
1087 // ----- Close the tarfile
1090 // ----- Look for tgz file
1093 // ----- Open the tar file
1094 if (($p_tar = @gzopen
($p_tarname, "wb")) == 0)
1097 PclErrorLog(-1, "Unable to open file [$p_tarname] in binary write mode");
1100 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
1101 return PclErrorCode();
1104 // ----- Call the adding fct inside the tar
1105 if (($v_result = PclTarHandleAddList($p_tar, $p_list, $p_mode, $v_list_detail, $p_add_dir, $p_remove_dir)) == 1)
1107 // ----- Call the footer of the tar archive
1108 $v_result = PclTarHandleFooter($p_tar, $p_mode);
1111 // ----- Close the tarfile
1116 TrFctEnd(__FILE__
, __LINE__
, $v_result);
1119 // --------------------------------------------------------------------------------
1121 // --------------------------------------------------------------------------------
1122 // Function : PclTarHandleAppend()
1125 // $p_tarname : Name of the tar file
1126 // $p_list : An array containing the file or directory names to add in the tar
1127 // $p_mode : "tar" for normal tar archive, "tgz" for gzipped tar archive
1129 // --------------------------------------------------------------------------------
1130 function PclTarHandleAppend($p_tarname, $p_list, $p_mode, &$p_list_detail, $p_add_dir, $p_remove_dir)
1132 TrFctStart(__FILE__
, __LINE__
, "PclTarHandleAppend", "tar=$p_tarname, list, mode=$p_mode");
1135 // ----- Check the parameters
1136 if ($p_tarname == "")
1139 PclErrorLog(-3, "Invalid empty archive name");
1142 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
1143 return PclErrorCode();
1148 // ----- Check the file size
1149 if ((!is_file($p_tarname)) ||
1150 (((($v_size = filesize($p_tarname)) %
512) != 0) && ($p_mode=="tar")))
1153 if (!is_file($p_tarname))
1154 PclErrorLog(-4, "Archive '$p_tarname' does not exist");
1156 PclErrorLog(-6, "Archive '$p_tarname' has invalid size ".filesize($p_tarname)."(not a 512 block multiple)");
1159 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
1160 return PclErrorCode();
1163 // ----- Look for compressed archive
1164 if ($p_mode == "tgz")
1166 // ----- Open the file in read mode
1167 if (($p_tar = @gzopen
($p_tarname, "rb")) == 0)
1170 PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode");
1173 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
1174 return PclErrorCode();
1177 // ----- Open a temporary file in write mode
1178 $v_temp_tarname = uniqid("pcltar-").".tmp";
1179 TrFctMessage(__FILE__
, __LINE__
, 2, "Creating temporary archive file $v_temp_tarname");
1180 if (($v_temp_tar = @gzopen
($v_temp_tarname, "wb")) == 0)
1182 // ----- Close tar file
1186 PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode");
1189 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
1190 return PclErrorCode();
1193 // ----- Read the first 512 bytes block
1194 $v_buffer = gzread($p_tar, 512);
1196 // ----- Read the following blocks but not the last one
1199 TrFctMessage(__FILE__
, __LINE__
, 3, "More than one 512 block file");
1202 // ----- Read new 512 block and write the already read
1204 // ----- Write the already read block
1205 $v_binary_data = pack("a512", "$v_buffer");
1206 gzputs($v_temp_tar, $v_binary_data);
1209 TrFctMessage(__FILE__
, __LINE__
, 3, "Reading block $i");
1211 // ----- Read next block
1212 $v_buffer = gzread($p_tar, 512);
1214 } while (!gzeof($p_tar));
1216 TrFctMessage(__FILE__
, __LINE__
, 3, "$i 512 bytes blocks");
1219 // ----- Call the adding fct inside the tar
1220 if (($v_result = PclTarHandleAddList($v_temp_tar, $p_list, $p_mode, $p_list_detail, $p_add_dir, $p_remove_dir)) == 1)
1222 // ----- Call the footer of the tar archive
1223 $v_result = PclTarHandleFooter($v_temp_tar, $p_mode);
1226 // ----- Close the files
1228 gzclose($v_temp_tar);
1230 // ----- Unlink tar file
1231 if (!@unlink
($p_tarname))
1234 PclErrorLog(-11, "Error while deleting archive name $p_tarname");
1237 // ----- Rename tar file
1238 if (!@rename
($v_temp_tarname, $p_tarname))
1241 PclErrorLog(-12, "Error while renaming temporary file $v_temp_tarname to archive name $p_tarname");
1244 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
1245 return PclErrorCode();
1249 TrFctEnd(__FILE__
, __LINE__
, $v_result);
1253 // ----- Look for uncompressed tar file
1254 else if ($p_mode=="tar")
1256 // ----- Open the tar file
1257 if (($p_tar = fopen($p_tarname, "r+b")) == 0)
1260 PclErrorLog(-1, "Unable to open file '$p_tarname' in binary write mode");
1263 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
1264 return PclErrorCode();
1267 // ----- Go to the beginning of last block
1268 TrFctMessage(__FILE__
, __LINE__
, 4, "Position before :".($p_mode=="tar"?
ftell($p_tar):gztell($p_tar)));
1269 fseek($p_tar, $v_size-512);
1270 TrFctMessage(__FILE__
, __LINE__
, 4, "Position after :".($p_mode=="tar"?
ftell($p_tar):gztell($p_tar)));
1272 // ----- Call the adding fct inside the tar
1273 if (($v_result = PclTarHandleAddList($p_tar, $p_list, $p_mode, $p_list_detail, $p_add_dir, $p_remove_dir)) == 1)
1275 // ----- Call the footer of the tar archive
1276 $v_result = PclTarHandleFooter($p_tar, $p_mode);
1279 // ----- Close the tarfile
1283 // ----- Look for unknown type
1287 PclErrorLog(-3, "Invalid tar mode $p_mode");
1290 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
1291 return PclErrorCode();
1295 TrFctEnd(__FILE__
, __LINE__
, $v_result);
1298 // --------------------------------------------------------------------------------
1300 // --------------------------------------------------------------------------------
1301 // Function : PclTarHandleAddList()
1303 // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
1304 // different from the real path of the file. This is usefull if you want to have PclTar
1305 // running in any directory, and memorize relative path from an other directory.
1307 // $p_tar : File descriptor of the tar archive
1308 // $p_list : An array containing the file or directory names to add in the tar
1309 // $p_mode : "tar" for normal tar archive, "tgz" for gzipped tar archive
1310 // $p_list_detail : list of added files with their properties (specially the status field)
1311 // $p_add_dir : Path to add in the filename path archived
1312 // $p_remove_dir : Path to remove in the filename path archived
1314 // --------------------------------------------------------------------------------
1315 function PclTarHandleAddList($p_tar, $p_list, $p_mode, &$p_list_detail, $p_add_dir, $p_remove_dir)
1317 TrFctStart(__FILE__
, __LINE__
, "PclTarHandleAddList", "tar='$p_tar', list, mode='$p_mode', add_dir='$p_add_dir', remove_dir='$p_remove_dir'");
1319 $v_header = array();
1321 // ----- Recuperate the current number of elt in list
1322 $v_nb = sizeof($p_list_detail);
1324 // ----- Check the parameters
1328 PclErrorLog(-3, "Invalid file descriptor in file ".__FILE__
.", line ".__LINE__
);
1331 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
1332 return PclErrorCode();
1335 // ----- Check the arguments
1336 if (sizeof($p_list) == 0)
1339 PclErrorLog(-3, "Invalid file list parameter (invalid or empty list)");
1342 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
1343 return PclErrorCode();
1346 // ----- Loop on the files
1347 for ($j=0; ($j<count($p_list)) && ($v_result==1); $j++
)
1349 // ----- Recuperate the filename
1350 $p_filename = $p_list[$j];
1352 TrFctMessage(__FILE__
, __LINE__
, 2, "Looking for file [$p_filename]");
1354 // ----- Skip empty file names
1355 if ($p_filename == "")
1357 TrFctMessage(__FILE__
, __LINE__
, 2, "Skip empty filename");
1361 // ----- Check the filename
1362 if (!file_exists($p_filename))
1365 TrFctMessage(__FILE__
, __LINE__
, 2, "File '$p_filename' does not exists");
1366 PclErrorLog(-4, "File '$p_filename' does not exists");
1369 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
1370 return PclErrorCode();
1373 // ----- Check the path length
1374 if (strlen($p_filename) > 99)
1377 PclErrorLog(-5, "File name is too long (max. 99) : '$p_filename'");
1380 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
1381 return PclErrorCode();
1384 TrFctMessage(__FILE__
, __LINE__
, 4, "File position before header =".($p_mode=="tar"?
ftell($p_tar):gztell($p_tar)));
1386 // ----- Add the file
1387 if (($v_result = PclTarHandleAddFile($p_tar, $p_filename, $p_mode, $v_header, $p_add_dir, $p_remove_dir)) != 1)
1389 // ----- Return status
1390 TrFctEnd(__FILE__
, __LINE__
, $v_result);
1394 // ----- Store the file infos
1395 $p_list_detail[$v_nb++
] = $v_header;
1397 // ----- Look for directory
1398 if (is_dir($p_filename))
1400 TrFctMessage(__FILE__
, __LINE__
, 2, "$p_filename is a directory");
1402 // ----- Look for path
1403 if ($p_filename != ".")
1404 $v_path = $p_filename."/";
1408 // ----- Read the directory for files and sub-directories
1409 $p_hdir = opendir($p_filename);
1410 $p_hitem = readdir($p_hdir); // '.' directory
1411 $p_hitem = readdir($p_hdir); // '..' directory
1412 while ($p_hitem = readdir($p_hdir))
1414 // ----- Look for a file
1415 if (is_file($v_path.$p_hitem))
1417 TrFctMessage(__FILE__
, __LINE__
, 4, "Add the file '".$v_path.$p_hitem."'");
1419 // ----- Add the file
1420 if (($v_result = PclTarHandleAddFile($p_tar, $v_path.$p_hitem, $p_mode, $v_header, $p_add_dir, $p_remove_dir)) != 1)
1422 // ----- Return status
1423 TrFctEnd(__FILE__
, __LINE__
, $v_result);
1427 // ----- Store the file infos
1428 $p_list_detail[$v_nb++
] = $v_header;
1431 // ----- Recursive call to PclTarHandleAddFile()
1434 TrFctMessage(__FILE__
, __LINE__
, 4, "'".$v_path.$p_hitem."' is a directory");
1436 // ----- Need an array as parameter
1437 $p_temp_list[0] = $v_path.$p_hitem;
1438 $v_result = PclTarHandleAddList($p_tar, $p_temp_list, $p_mode, $p_list_detail, $p_add_dir, $p_remove_dir);
1442 // ----- Free memory for the recursive loop
1443 unset($p_temp_list);
1449 TrFctMessage(__FILE__
, __LINE__
, 4, "File position after blocks =".($p_mode=="tar"?
ftell($p_tar):gztell($p_tar)));
1454 TrFctEnd(__FILE__
, __LINE__
, $v_result);
1457 // --------------------------------------------------------------------------------
1459 // --------------------------------------------------------------------------------
1460 // Function : PclTarHandleAddFile()
1464 // --------------------------------------------------------------------------------
1465 function PclTarHandleAddFile($p_tar, $p_filename, $p_mode, &$p_header, $p_add_dir, $p_remove_dir)
1467 TrFctStart(__FILE__
, __LINE__
, "PclTarHandleAddFile", "tar='$p_tar', filename='$p_filename', p_mode='$p_mode', add_dir='$p_add_dir', remove_dir='$p_remove_dir'");
1470 // ----- Check the parameters
1474 PclErrorLog(-3, "Invalid file descriptor in file ".__FILE__
.", line ".__LINE__
);
1477 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
1478 return PclErrorCode();
1481 // ----- Skip empty file names
1482 if ($p_filename == "")
1485 PclErrorLog(-3, "Invalid file list parameter (invalid or empty list)");
1488 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
1489 return PclErrorCode();
1492 // ----- Calculate the stored filename
1493 $v_stored_filename = $p_filename;
1494 if ($p_remove_dir != "")
1496 if (substr($p_remove_dir, -1) != '/')
1497 $p_remove_dir .= "/";
1499 if ((substr($p_filename, 0, 2) == "./") ||
(substr($p_remove_dir, 0, 2) == "./"))
1501 if ((substr($p_filename, 0, 2) == "./") && (substr($p_remove_dir, 0, 2) != "./"))
1502 $p_remove_dir = "./".$p_remove_dir;
1503 if ((substr($p_filename, 0, 2) != "./") && (substr($p_remove_dir, 0, 2) == "./"))
1504 $p_remove_dir = substr($p_remove_dir, 2);
1507 if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir)
1509 $v_stored_filename = substr($p_filename, strlen($p_remove_dir));
1510 TrFctMessage(__FILE__
, __LINE__
, 3, "Remove path '$p_remove_dir' in file '$p_filename' = '$v_stored_filename'");
1513 if ($p_add_dir != "")
1515 if (substr($p_add_dir, -1) == "/")
1516 $v_stored_filename = $p_add_dir.$v_stored_filename;
1518 $v_stored_filename = $p_add_dir."/".$v_stored_filename;
1519 TrFctMessage(__FILE__
, __LINE__
, 3, "Add path '$p_add_dir' in file '$p_filename' = '$v_stored_filename'");
1522 // ----- Check the path length
1523 if (strlen($v_stored_filename) > 99)
1526 PclErrorLog(-5, "Stored file name is too long (max. 99) : '$v_stored_filename'");
1529 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
1530 return PclErrorCode();
1533 // ----- Look for a file
1534 if (is_file($p_filename))
1536 // ----- Open the source file
1537 if (($v_file = fopen($p_filename, "rb")) == 0)
1540 PclErrorLog(-2, "Unable to open file '$p_filename' in binary read mode");
1543 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
1544 return PclErrorCode();
1547 // ----- Call the header generation
1548 if (($v_result = PclTarHandleHeader($p_tar, $p_filename, $p_mode, $p_header, $v_stored_filename)) != 1)
1550 // ----- Return status
1551 TrFctEnd(__FILE__
, __LINE__
, $v_result);
1555 TrFctMessage(__FILE__
, __LINE__
, 4, "File position after header =".($p_mode=="tar"?
ftell($p_tar):gztell($p_tar)));
1557 // ----- Read the file by 512 octets blocks
1559 while (($v_buffer = fread($v_file, 512)) != "")
1561 $v_binary_data = pack("a512", "$v_buffer");
1562 if ($p_mode == "tar")
1563 fputs($p_tar, $v_binary_data);
1565 gzputs($p_tar, $v_binary_data);
1568 TrFctMessage(__FILE__
, __LINE__
, 2, "$i 512 bytes blocks");
1570 // ----- Close the file
1573 TrFctMessage(__FILE__
, __LINE__
, 4, "File position after blocks =".($p_mode=="tar"?
ftell($p_tar):gztell($p_tar)));
1576 // ----- Look for a directory
1579 // ----- Call the header generation
1580 if (($v_result = PclTarHandleHeader($p_tar, $p_filename, $p_mode, $p_header, $v_stored_filename)) != 1)
1582 // ----- Return status
1583 TrFctEnd(__FILE__
, __LINE__
, $v_result);
1587 TrFctMessage(__FILE__
, __LINE__
, 4, "File position after header =".($p_mode=="tar"?
ftell($p_tar):gztell($p_tar)));
1591 TrFctEnd(__FILE__
, __LINE__
, $v_result);
1594 // --------------------------------------------------------------------------------
1596 // --------------------------------------------------------------------------------
1597 // Function : PclTarHandleHeader()
1599 // This function creates in the TAR $p_tar, the TAR header for the file
1602 // 1. The informations needed to compose the header are recuperated and formatted
1603 // 2. Two binary strings are composed for the first part of the header, before
1604 // and after checksum field.
1605 // 3. The checksum is calculated from the two binary strings
1606 // 4. The header is write in the tar file (first binary string, binary string
1607 // for checksum and last binary string).
1609 // $p_tar : a valid file descriptor, opened in write mode,
1610 // $p_filename : The name of the file the header is for,
1611 // $p_mode : The mode of the archive ("tar" or "tgz").
1612 // $p_header : A pointer to a array where will be set the file properties
1614 // --------------------------------------------------------------------------------
1615 function PclTarHandleHeader($p_tar, $p_filename, $p_mode, &$p_header, $p_stored_filename)
1617 TrFctStart(__FILE__
, __LINE__
, "PclTarHandleHeader", "tar=$p_tar, file='$p_filename', mode='$p_mode', stored_filename='$p_stored_filename'");
1620 // ----- Check the parameters
1621 if (($p_tar == 0) ||
($p_filename == ""))
1624 PclErrorLog(-3, "Invalid file descriptor in file ".__FILE__
.", line ".__LINE__
);
1627 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
1628 return PclErrorCode();
1631 // ----- Filename (reduce the path of stored name)
1632 if ($p_stored_filename == "")
1633 $p_stored_filename = $p_filename;
1634 $v_reduce_filename = PclTarHandlePathReduction($p_stored_filename);
1635 TrFctMessage(__FILE__
, __LINE__
, 2, "Filename (reduced) '$v_reduce_filename', strlen ".strlen($v_reduce_filename));
1637 // ----- Get file info
1638 $v_info = stat($p_filename);
1639 $v_uid = sprintf("%6s ", DecOct($v_info[4]));
1640 $v_gid = sprintf("%6s ", DecOct($v_info[5]));
1641 TrFctMessage(__FILE__
, __LINE__
, 3, "uid=$v_uid, gid=$v_gid");
1642 $v_perms = sprintf("%6s ", DecOct(fileperms($p_filename)));
1643 TrFctMessage(__FILE__
, __LINE__
, 3, "file permissions $v_perms");
1646 $v_mtime_data = filemtime($p_filename);
1647 TrFctMessage(__FILE__
, __LINE__
, 2, "File mtime : $v_mtime_data");
1648 $v_mtime = sprintf("%11s", DecOct($v_mtime_data));
1650 // ----- File typeflag
1651 // '0' or '\0' is the code for regular file
1653 if (is_dir($p_filename))
1662 // ----- Get the file size
1664 $v_size = filesize($p_filename);
1667 TrFctMessage(__FILE__
, __LINE__
, 2, "File size : $v_size");
1668 $v_size = sprintf("%11s ", DecOct($v_size));
1670 TrFctMessage(__FILE__
, __LINE__
, 2, "File typeflag : $v_typeflag");
1696 // ----- Compose the binary string of the header in two parts arround the checksum position
1697 $v_binary_data_first = pack("a100a8a8a8a12A12", $v_reduce_filename, $v_perms, $v_uid, $v_gid, $v_size, $v_mtime);
1698 $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12", $v_typeflag, $v_linkname, $v_magic, $v_version, $v_uname, $v_gname, $v_devmajor, $v_devminor, $v_prefix, "");
1700 // ----- Calculate the checksum
1702 // ..... First part of the header
1703 for ($i=0; $i<148; $i++
)
1705 $v_checksum +
= ord(substr($v_binary_data_first,$i,1));
1707 // ..... Ignore the checksum value and replace it by ' ' (space)
1708 for ($i=148; $i<156; $i++
)
1710 $v_checksum +
= ord(' ');
1712 // ..... Last part of the header
1713 for ($i=156, $j=0; $i<512; $i++
, $j++
)
1715 $v_checksum +
= ord(substr($v_binary_data_last,$j,1));
1717 TrFctMessage(__FILE__
, __LINE__
, 3, "Calculated checksum : $v_checksum");
1719 // ----- Write the first 148 bytes of the header in the archive
1720 if ($p_mode == "tar")
1721 fputs($p_tar, $v_binary_data_first, 148);
1723 gzputs($p_tar, $v_binary_data_first, 148);
1725 // ----- Write the calculated checksum
1726 $v_checksum = sprintf("%6s ", DecOct($v_checksum));
1727 $v_binary_data = pack("a8", $v_checksum);
1728 if ($p_mode == "tar")
1729 fputs($p_tar, $v_binary_data, 8);
1731 gzputs($p_tar, $v_binary_data, 8);
1733 // ----- Write the last 356 bytes of the header in the archive
1734 if ($p_mode == "tar")
1735 fputs($p_tar, $v_binary_data_last, 356);
1737 gzputs($p_tar, $v_binary_data_last, 356);
1739 // ----- Set the properties in the header "structure"
1740 $p_header[filename
] = $v_reduce_filename;
1741 $p_header[mode
] = $v_perms;
1742 $p_header[uid
] = $v_uid;
1743 $p_header[gid
] = $v_gid;
1744 $p_header[size
] = $v_size;
1745 $p_header[mtime
] = $v_mtime;
1746 $p_header[typeflag
] = $v_typeflag;
1747 $p_header[status
] = "added";
1750 TrFctEnd(__FILE__
, __LINE__
, $v_result);
1753 // --------------------------------------------------------------------------------
1755 // --------------------------------------------------------------------------------
1756 // Function : PclTarHandleFooter()
1760 // --------------------------------------------------------------------------------
1761 function PclTarHandleFooter($p_tar, $p_mode)
1763 TrFctStart(__FILE__
, __LINE__
, "PclTarHandleFooter", "tar='$p_tar', p_mode=$p_mode");
1766 // ----- Write the last 0 filled block for end of archive
1767 $v_binary_data = pack("a512", "");
1768 if ($p_mode == "tar")
1769 fputs($p_tar, $v_binary_data);
1771 gzputs($p_tar, $v_binary_data);
1774 TrFctEnd(__FILE__
, __LINE__
, $v_result);
1777 // --------------------------------------------------------------------------------
1779 // --------------------------------------------------------------------------------
1780 // Function : PclTarHandleExtract()
1783 // $p_tarname : Filename of the tar (or tgz) archive
1784 // $p_file_list : An array which contains the list of files to extract, this
1785 // array may be empty when $p_mode is 'complete'
1786 // $p_list_detail : An array where will be placed the properties of each extracted/listed file
1787 // $p_mode : 'complete' will extract all files from the archive,
1788 // 'partial' will look for files in $p_file_list
1789 // 'list' will only list the files from the archive without any extract
1790 // $p_path : Path to add while writing the extracted files
1791 // $p_tar_mode : 'tar' for GNU TAR archive, 'tgz' for compressed archive
1792 // $p_remove_path : Path to remove (from the file memorized path) while writing the
1793 // extracted files. If the path does not match the file path,
1794 // the file is extracted with its memorized path.
1795 // $p_remove_path does not apply to 'list' mode.
1796 // $p_path and $p_remove_path are commulative.
1798 // --------------------------------------------------------------------------------
1799 function PclTarHandleExtract($p_tarname, $p_file_list, &$p_list_detail, $p_mode, $p_path, $p_tar_mode, $p_remove_path)
1801 TrFctStart(__FILE__
, __LINE__
, "PclTarHandleExtract", "archive='$p_tarname', list, mode=$p_mode, path=$p_path, tar_mode=$p_tar_mode, remove_path='$p_remove_path'");
1804 $v_extract_all = TRUE;
1807 // ----- Check the path
1808 if (($p_path == "") ||
((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../")))
1809 $p_path = "./".$p_path;
1811 // ----- Look for path to remove format (should end by /)
1812 if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
1814 $p_remove_path .= '/';
1816 $p_remove_path_size = strlen($p_remove_path);
1818 // ----- Study the mode
1821 // ----- Flag extract of all files
1822 $v_extract_all = TRUE;
1826 // ----- Flag extract of specific files
1827 $v_extract_all = FALSE;
1831 // ----- Flag list of all files
1832 $v_extract_all = FALSE;
1837 PclErrorLog(-3, "Invalid extract mode ($p_mode)");
1840 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
1841 return PclErrorCode();
1844 // ----- Open the tar file
1845 if ($p_tar_mode == "tar")
1847 TrFctMessage(__FILE__
, __LINE__
, 3, "Open file in binary read mode");
1848 $v_tar = fopen($p_tarname, "rb");
1852 TrFctMessage(__FILE__
, __LINE__
, 3, "Open file in gzip binary read mode");
1853 $v_tar = @gzopen
($p_tarname, "rb");
1856 // ----- Check that the archive is open
1860 PclErrorLog(-2, "Unable to open archive '$p_tarname' in binary read mode");
1863 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
1864 return PclErrorCode();
1867 // ----- Read the blocks
1868 While (!($v_end_of_file = ($p_tar_mode == "tar"?
feof($v_tar):gzeof($v_tar))))
1870 TrFctMessage(__FILE__
, __LINE__
, 3, "Looking for next header ...");
1872 // ----- Clear cache of file infos
1875 // ----- Reset extract tag
1876 $v_extract_file = FALSE;
1877 $v_extraction_stopped = 0;
1879 // ----- Read the 512 bytes header
1880 if ($p_tar_mode == "tar")
1881 $v_binary_data = fread($v_tar, 512);
1883 $v_binary_data = gzread($v_tar, 512);
1885 // ----- Read the header properties
1886 if (($v_result = PclTarHandleReadHeader($v_binary_data, $v_header)) != 1)
1888 // ----- Close the archive file
1889 if ($p_tar_mode == "tar")
1895 TrFctEnd(__FILE__
, __LINE__
, $v_result);
1899 // ----- Look for empty blocks to skip
1900 if ($v_header[filename
] == "")
1902 TrFctMessage(__FILE__
, __LINE__
, 2, "Empty block found. End of archive ?");
1906 TrFctMessage(__FILE__
, __LINE__
, 2, "Found file '$v_header[filename]', size '$v_header[size]'");
1908 // ----- Look for partial extract
1909 if ((!$v_extract_all) && (is_array($p_file_list)))
1911 TrFctMessage(__FILE__
, __LINE__
, 2, "Look if the file '$v_header[filename]' need to be extracted");
1913 // ----- By default no unzip if the file is not found
1914 $v_extract_file = FALSE;
1916 // ----- Look into the file list
1917 for ($i=0; $i<sizeof($p_file_list); $i++
)
1919 TrFctMessage(__FILE__
, __LINE__
, 2, "Compare archived file '$v_header[filename]' from asked list file '".$p_file_list[$i]."'");
1921 // ----- Look if it is a directory
1922 if (substr($p_file_list[$i], -1) == "/")
1924 TrFctMessage(__FILE__
, __LINE__
, 3, "Compare file '$v_header[filename]' with directory '$p_file_list[$i]'");
1926 // ----- Look if the directory is in the filename path
1927 if ((strlen($v_header[filename
]) > strlen($p_file_list[$i])) && (substr($v_header[filename
], 0, strlen($p_file_list[$i])) == $p_file_list[$i]))
1929 // ----- The file is in the directory, so extract it
1930 TrFctMessage(__FILE__
, __LINE__
, 2, "File '$v_header[filename]' is in directory '$p_file_list[$i]' : extract it");
1931 $v_extract_file = TRUE;
1933 // ----- End of loop
1938 // ----- It is a file, so compare the file names
1939 else if ($p_file_list[$i] == $v_header[filename
])
1942 TrFctMessage(__FILE__
, __LINE__
, 2, "File '$v_header[filename]' should be extracted");
1943 $v_extract_file = TRUE;
1945 // ----- End of loop
1951 if (!$v_extract_file)
1953 TrFctMessage(__FILE__
, __LINE__
, 2, "File '$v_header[filename]' should not be extracted");
1958 // ----- All files need to be extracted
1959 $v_extract_file = TRUE;
1962 // ----- Look if this file need to be extracted
1963 if (($v_extract_file) && (!$v_listing))
1965 // ----- Look for path to remove
1966 if (($p_remove_path != "")
1967 && (substr($v_header[filename
], 0, $p_remove_path_size) == $p_remove_path))
1969 TrFctMessage(__FILE__
, __LINE__
, 3, "Found path '$p_remove_path' to remove in file '$v_header[filename]'");
1970 // ----- Remove the path
1971 $v_header[filename
] = substr($v_header[filename
], $p_remove_path_size);
1972 TrFctMessage(__FILE__
, __LINE__
, 3, "Reslting file is '$v_header[filename]'");
1975 // ----- Add the path to the file
1976 if (($p_path != "./") && ($p_path != "/"))
1978 // ----- Look for the path end '/'
1979 while (substr($p_path, -1) == "/")
1981 TrFctMessage(__FILE__
, __LINE__
, 3, "Destination path [$p_path] ends by '/'");
1982 $p_path = substr($p_path, 0, strlen($p_path)-1);
1983 TrFctMessage(__FILE__
, __LINE__
, 3, "Modified to [$p_path]");
1986 // ----- Add the path
1987 if (substr($v_header[filename
], 0, 1) == "/")
1988 $v_header[filename
] = $p_path.$v_header[filename
];
1990 $v_header[filename
] = $p_path."/".$v_header[filename
];
1994 TrFctMessage(__FILE__
, __LINE__
, 2, "Extracting file (with path) '$v_header[filename]', size '$v_header[size]'");
1996 // ----- Check that the file does not exists
1997 if (file_exists($v_header[filename
]))
1999 TrFctMessage(__FILE__
, __LINE__
, 2, "File '$v_header[filename]' already exists");
2001 // ----- Look if file is a directory
2002 if (is_dir($v_header[filename
]))
2004 TrFctMessage(__FILE__
, __LINE__
, 2, "Existing file '$v_header[filename]' is a directory");
2006 // ----- Change the file status
2007 $v_header[status
] = "already_a_directory";
2009 // ----- Skip the extract
2010 $v_extraction_stopped = 1;
2011 $v_extract_file = 0;
2013 // ----- Look if file is write protected
2014 else if (!is_writeable($v_header[filename
]))
2016 TrFctMessage(__FILE__
, __LINE__
, 2, "Existing file '$v_header[filename]' is write protected");
2018 // ----- Change the file status
2019 $v_header[status
] = "write_protected";
2021 // ----- Skip the extract
2022 $v_extraction_stopped = 1;
2023 $v_extract_file = 0;
2025 // ----- Look if the extracted file is older
2026 else if (filemtime($v_header[filename
]) > $v_header[mtime
])
2028 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
]).")");
2030 // ----- Change the file status
2031 $v_header[status
] = "newer_exist";
2033 // ----- Skip the extract
2034 $v_extraction_stopped = 1;
2035 $v_extract_file = 0;
2039 // ----- Check the directory availability and create it if necessary
2042 if ($v_header[typeflag
]=="5")
2043 $v_dir_to_check = $v_header[filename
];
2044 else if (!strstr($v_header[filename
], "/"))
2045 $v_dir_to_check = "";
2047 $v_dir_to_check = dirname($v_header[filename
]);
2049 if (($v_result = PclTarHandlerDirCheck($v_dir_to_check)) != 1)
2051 TrFctMessage(__FILE__
, __LINE__
, 2, "Unable to create path for '$v_header[filename]'");
2053 // ----- Change the file status
2054 $v_header[status
] = "path_creation_fail";
2056 // ----- Skip the extract
2057 $v_extraction_stopped = 1;
2058 $v_extract_file = 0;
2062 // ----- Do the extraction
2063 if (($v_extract_file) && ($v_header[typeflag
]!="5"))
2065 // ----- Open the destination file in write mode
2066 if (($v_dest_file = @fopen
($v_header[filename
], "wb")) == 0)
2068 TrFctMessage(__FILE__
, __LINE__
, 2, "Error while opening '$v_header[filename]' in write binary mode");
2070 // ----- Change the file status
2071 $v_header[status
] = "write_error";
2073 // ----- Jump to next file
2074 TrFctMessage(__FILE__
, __LINE__
, 2, "Jump to next file");
2075 if ($p_tar_mode == "tar")
2076 fseek($v_tar, ftell($v_tar)+
(ceil(($v_header[size
]/512))*512));
2078 gzseek($v_tar, gztell($v_tar)+
(ceil(($v_header[size
]/512))*512));
2082 TrFctMessage(__FILE__
, __LINE__
, 2, "Start extraction of '$v_header[filename]'");
2085 $n = floor($v_header[size
]/512);
2086 for ($i=0; $i<$n; $i++
)
2088 TrFctMessage(__FILE__
, __LINE__
, 3, "Read complete 512 bytes block number ".($i+
1));
2089 if ($p_tar_mode == "tar")
2090 $v_content = fread($v_tar, 512);
2092 $v_content = gzread($v_tar, 512);
2093 fwrite($v_dest_file, $v_content, 512);
2095 if (($v_header[size
] %
512) != 0)
2097 TrFctMessage(__FILE__
, __LINE__
, 3, "Read last ".($v_header[size
] %
512)." bytes in a 512 block");
2098 if ($p_tar_mode == "tar")
2099 $v_content = fread($v_tar, 512);
2101 $v_content = gzread($v_tar, 512);
2102 fwrite($v_dest_file, $v_content, ($v_header[size
] %
512));
2105 // ----- Close the destination file
2106 fclose($v_dest_file);
2108 // ----- Change the file mode, mtime
2109 touch($v_header[filename
], $v_header[mtime
]);
2110 //chmod($v_header[filename], DecOct($v_header[mode]));
2113 // ----- Check the file size
2115 if (filesize($v_header[filename
]) != $v_header[size
])
2117 // ----- Close the archive file
2118 if ($p_tar_mode == "tar")
2124 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.");
2127 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
2128 return PclErrorCode();
2132 TrFctMessage(__FILE__
, __LINE__
, 2, "Extraction done");
2137 TrFctMessage(__FILE__
, __LINE__
, 2, "Extraction of file '$v_header[filename]' skipped.");
2139 // ----- Jump to next file
2140 TrFctMessage(__FILE__
, __LINE__
, 2, "Jump to next file");
2141 if ($p_tar_mode == "tar")
2142 fseek($v_tar, ftell($v_tar)+
(ceil(($v_header[size
]/512))*512));
2144 gzseek($v_tar, gztell($v_tar)+
(ceil(($v_header[size
]/512))*512));
2148 // ----- Look for file that is not to be unzipped
2152 TrFctMessage(__FILE__
, __LINE__
, 2, "Jump file '$v_header[filename]'");
2153 TrFctMessage(__FILE__
, __LINE__
, 4, "Position avant jump [".($p_tar_mode=="tar"?
ftell($v_tar):gztell($v_tar))."]");
2155 // ----- Jump to next file
2156 if ($p_tar_mode == "tar")
2157 fseek($v_tar, ($p_tar_mode=="tar"?
ftell($v_tar):gztell($v_tar))+
(ceil(($v_header[size
]/512))*512));
2159 gzseek($v_tar, gztell($v_tar)+
(ceil(($v_header[size
]/512))*512));
2161 TrFctMessage(__FILE__
, __LINE__
, 4, "Position apr�s jump [".($p_tar_mode=="tar"?
ftell($v_tar):gztell($v_tar))."]");
2164 if ($p_tar_mode == "tar")
2165 $v_end_of_file = feof($v_tar);
2167 $v_end_of_file = gzeof($v_tar);
2169 // ----- File name and properties are logged if listing mode or file is extracted
2170 if ($v_listing ||
$v_extract_file ||
$v_extraction_stopped)
2172 TrFctMessage(__FILE__
, __LINE__
, 2, "Memorize info about file '$v_header[filename]'");
2174 // ----- Log extracted files
2175 if (($v_file_dir = dirname($v_header[filename
])) == $v_header[filename
])
2177 if ((substr($v_header[filename
], 0, 1) == "/") && ($v_file_dir == ""))
2180 // ----- Add the array describing the file into the list
2181 $p_list_detail[$v_nb] = $v_header;
2188 // ----- Close the tarfile
2189 if ($p_tar_mode == "tar")
2195 TrFctEnd(__FILE__
, __LINE__
, $v_result);
2198 // --------------------------------------------------------------------------------
2200 // --------------------------------------------------------------------------------
2201 // Function : PclTarHandleExtractByIndexList()
2203 // Extract the files which are at the indexes specified. If the 'file' at the
2204 // index is a directory, the directory only is created, not all the files stored
2205 // for that directory.
2207 // $p_index_string : String of indexes of files to extract. The form of the
2208 // string is "0,4-6,8-12" with only numbers and '-' for
2209 // for range, and ',' to separate ranges. No spaces or ';'
2212 // --------------------------------------------------------------------------------
2213 function PclTarHandleExtractByIndexList($p_tarname, $p_index_string, &$p_list_detail, $p_path, $p_remove_path, $p_tar_mode)
2215 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");
2219 // ----- TBC : I should check the string by a regexp
2221 // ----- Check the path
2222 if (($p_path == "") ||
((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../") && (substr($p_path, 0, 2) != "./")))
2223 $p_path = "./".$p_path;
2225 // ----- Look for path to remove format (should end by /)
2226 if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
2228 $p_remove_path .= '/';
2230 $p_remove_path_size = strlen($p_remove_path);
2232 // ----- Open the tar file
2233 if ($p_tar_mode == "tar")
2235 TrFctMessage(__FILE__
, __LINE__
, 3, "Open file in binary read mode");
2236 $v_tar = @fopen
($p_tarname, "rb");
2240 TrFctMessage(__FILE__
, __LINE__
, 3, "Open file in gzip binary read mode");
2241 $v_tar = @gzopen
($p_tarname, "rb");
2244 // ----- Check that the archive is open
2248 PclErrorLog(-2, "Unable to open archive '$p_tarname' in binary read mode");
2251 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
2252 return PclErrorCode();
2255 // ----- Manipulate the index list
2256 $v_list = explode(",", $p_index_string);
2259 // ----- Loop on the index list
2261 for ($i=0; ($i<sizeof($v_list)) && ($v_result); $i++
)
2263 TrFctMessage(__FILE__
, __LINE__
, 3, "Looking for index part '$v_list[$i]'");
2265 // ----- Extract range
2266 $v_index_list = explode("-", $v_list[$i]);
2267 $v_size_index_list = sizeof($v_index_list);
2268 if ($v_size_index_list == 1)
2270 TrFctMessage(__FILE__
, __LINE__
, 3, "Only one index '$v_index_list[0]'");
2272 // ----- Do the extraction
2273 $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);
2275 else if ($v_size_index_list == 2)
2277 TrFctMessage(__FILE__
, __LINE__
, 3, "Two indexes '$v_index_list[0]' and '$v_index_list[1]'");
2279 // ----- Do the extraction
2280 $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);
2284 // ----- Close the tarfile
2285 if ($p_tar_mode == "tar")
2291 TrFctEnd(__FILE__
, __LINE__
, $v_result);
2294 // --------------------------------------------------------------------------------
2296 // --------------------------------------------------------------------------------
2297 // Function : PclTarHandleExtractByIndex()
2301 // --------------------------------------------------------------------------------
2302 function PclTarHandleExtractByIndex($p_tar, &$p_index_current, $p_index_start, $p_index_stop, &$p_list_detail, $p_path, $p_remove_path, $p_tar_mode)
2304 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");
2308 // TBC : I should replace all $v_tar by $p_tar in this function ....
2311 // ----- Look the number of elements already in $p_list_detail
2312 $v_nb = sizeof($p_list_detail);
2314 // ----- Read the blocks
2315 While (!($v_end_of_file = ($p_tar_mode == "tar"?
feof($v_tar):gzeof($v_tar))))
2317 TrFctMessage(__FILE__
, __LINE__
, 3, "Looking for next file ...");
2318 TrFctMessage(__FILE__
, __LINE__
, 3, "Index current=$p_index_current, range=[$p_index_start, $p_index_stop])");
2320 if ($p_index_current > $p_index_stop)
2322 TrFctMessage(__FILE__
, __LINE__
, 2, "Stop extraction, past stop index");
2326 // ----- Clear cache of file infos
2329 // ----- Reset extract tag
2330 $v_extract_file = FALSE;
2331 $v_extraction_stopped = 0;
2333 // ----- Read the 512 bytes header
2334 if ($p_tar_mode == "tar")
2335 $v_binary_data = fread($v_tar, 512);
2337 $v_binary_data = gzread($v_tar, 512);
2339 // ----- Read the header properties
2340 if (($v_result = PclTarHandleReadHeader($v_binary_data, $v_header)) != 1)
2343 TrFctEnd(__FILE__
, __LINE__
, $v_result);
2347 // ----- Look for empty blocks to skip
2348 if ($v_header[filename
] == "")
2350 TrFctMessage(__FILE__
, __LINE__
, 2, "Empty block found. End of archive ?");
2354 TrFctMessage(__FILE__
, __LINE__
, 2, "Found file '$v_header[filename]', size '$v_header[size]'");
2356 // ----- Look if file is in the range to be extracted
2357 if (($p_index_current >= $p_index_start) && ($p_index_current <= $p_index_stop))
2359 TrFctMessage(__FILE__
, __LINE__
, 2, "File '$v_header[filename]' is in the range to be extracted");
2360 $v_extract_file = TRUE;
2364 TrFctMessage(__FILE__
, __LINE__
, 2, "File '$v_header[filename]' is out of the range");
2365 $v_extract_file = FALSE;
2368 // ----- Look if this file need to be extracted
2369 if ($v_extract_file)
2371 if (($v_result = PclTarHandleExtractFile($v_tar, $v_header, $p_path, $p_remove_path, $p_tar_mode)) != 1)
2374 TrFctEnd(__FILE__
, __LINE__
, $v_result);
2379 // ----- Look for file that is not to be extracted
2383 TrFctMessage(__FILE__
, __LINE__
, 2, "Jump file '$v_header[filename]'");
2384 TrFctMessage(__FILE__
, __LINE__
, 4, "Position avant jump [".($p_tar_mode=="tar"?
ftell($v_tar):gztell($v_tar))."]");
2386 // ----- Jump to next file
2387 if ($p_tar_mode == "tar")
2388 fseek($v_tar, ($p_tar_mode=="tar"?
ftell($v_tar):gztell($v_tar))+
(ceil(($v_header[size
]/512))*512));
2390 gzseek($v_tar, gztell($v_tar)+
(ceil(($v_header[size
]/512))*512));
2392 TrFctMessage(__FILE__
, __LINE__
, 4, "Position apr�s jump [".($p_tar_mode=="tar"?
ftell($v_tar):gztell($v_tar))."]");
2395 if ($p_tar_mode == "tar")
2396 $v_end_of_file = feof($v_tar);
2398 $v_end_of_file = gzeof($v_tar);
2400 // ----- File name and properties are logged if listing mode or file is extracted
2401 if ($v_extract_file)
2403 TrFctMessage(__FILE__
, __LINE__
, 2, "Memorize info about file '$v_header[filename]'");
2405 // ----- Log extracted files
2406 if (($v_file_dir = dirname($v_header[filename
])) == $v_header[filename
])
2408 if ((substr($v_header[filename
], 0, 1) == "/") && ($v_file_dir == ""))
2411 // ----- Add the array describing the file into the list
2412 $p_list_detail[$v_nb] = $v_header;
2418 // ----- Increment the current file index
2423 TrFctEnd(__FILE__
, __LINE__
, $v_result);
2426 // --------------------------------------------------------------------------------
2428 // --------------------------------------------------------------------------------
2429 // Function : PclTarHandleExtractFile()
2433 // --------------------------------------------------------------------------------
2434 function PclTarHandleExtractFile($p_tar, &$v_header, $p_path, $p_remove_path, $p_tar_mode)
2436 TrFctStart(__FILE__
, __LINE__
, "PclTarHandleExtractFile", "archive_descr='$p_tar', path=$p_path, remove_path='$p_remove_path', tar_mode=$p_tar_mode");
2439 // TBC : I should replace all $v_tar by $p_tar in this function ....
2441 $v_extract_file = 1;
2443 $p_remove_path_size = strlen($p_remove_path);
2445 // ----- Look for path to remove
2446 if (($p_remove_path != "")
2447 && (substr($v_header[filename
], 0, $p_remove_path_size) == $p_remove_path))
2449 TrFctMessage(__FILE__
, __LINE__
, 3, "Found path '$p_remove_path' to remove in file '$v_header[filename]'");
2450 // ----- Remove the path
2451 $v_header[filename
] = substr($v_header[filename
], $p_remove_path_size);
2452 TrFctMessage(__FILE__
, __LINE__
, 3, "Resulting file is '$v_header[filename]'");
2455 // ----- Add the path to the file
2456 if (($p_path != "./") && ($p_path != "/"))
2458 // ----- Look for the path end '/'
2459 while (substr($p_path, -1) == "/")
2461 TrFctMessage(__FILE__
, __LINE__
, 3, "Destination path [$p_path] ends by '/'");
2462 $p_path = substr($p_path, 0, strlen($p_path)-1);
2463 TrFctMessage(__FILE__
, __LINE__
, 3, "Modified to [$p_path]");
2466 // ----- Add the path
2467 if (substr($v_header[filename
], 0, 1) == "/")
2468 $v_header[filename
] = $p_path.$v_header[filename
];
2470 $v_header[filename
] = $p_path."/".$v_header[filename
];
2474 TrFctMessage(__FILE__
, __LINE__
, 2, "Extracting file (with path) '$v_header[filename]', size '$v_header[size]'");
2476 // ----- Check that the file does not exists
2477 if (file_exists($v_header[filename
]))
2479 TrFctMessage(__FILE__
, __LINE__
, 2, "File '$v_header[filename]' already exists");
2481 // ----- Look if file is a directory
2482 if (is_dir($v_header[filename
]))
2484 TrFctMessage(__FILE__
, __LINE__
, 2, "Existing file '$v_header[filename]' is a directory");
2486 // ----- Change the file status
2487 $v_header[status
] = "already_a_directory";
2489 // ----- Skip the extract
2490 $v_extraction_stopped = 1;
2491 $v_extract_file = 0;
2493 // ----- Look if file is write protected
2494 else if (!is_writeable($v_header[filename
]))
2496 TrFctMessage(__FILE__
, __LINE__
, 2, "Existing file '$v_header[filename]' is write protected");
2498 // ----- Change the file status
2499 $v_header[status
] = "write_protected";
2501 // ----- Skip the extract
2502 $v_extraction_stopped = 1;
2503 $v_extract_file = 0;
2505 // ----- Look if the extracted file is older
2506 else if (filemtime($v_header[filename
]) > $v_header[mtime
])
2508 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
]).")");
2510 // ----- Change the file status
2511 $v_header[status
] = "newer_exist";
2513 // ----- Skip the extract
2514 $v_extraction_stopped = 1;
2515 $v_extract_file = 0;
2519 // ----- Check the directory availability and create it if necessary
2522 if ($v_header[typeflag
]=="5")
2523 $v_dir_to_check = $v_header[filename
];
2524 else if (!strstr($v_header[filename
], "/"))
2525 $v_dir_to_check = "";
2527 $v_dir_to_check = dirname($v_header[filename
]);
2529 if (($v_result = PclTarHandlerDirCheck($v_dir_to_check)) != 1)
2531 TrFctMessage(__FILE__
, __LINE__
, 2, "Unable to create path for '$v_header[filename]'");
2533 // ----- Change the file status
2534 $v_header[status
] = "path_creation_fail";
2536 // ----- Skip the extract
2537 $v_extraction_stopped = 1;
2538 $v_extract_file = 0;
2542 // ----- Do the real bytes extraction (if not a directory)
2543 if (($v_extract_file) && ($v_header[typeflag
]!="5"))
2545 // ----- Open the destination file in write mode
2546 if (($v_dest_file = @fopen
($v_header[filename
], "wb")) == 0)
2548 TrFctMessage(__FILE__
, __LINE__
, 2, "Error while opening '$v_header[filename]' in write binary mode");
2550 // ----- Change the file status
2551 $v_header[status
] = "write_error";
2553 // ----- Jump to next file
2554 TrFctMessage(__FILE__
, __LINE__
, 2, "Jump to next file");
2555 if ($p_tar_mode == "tar")
2556 fseek($v_tar, ftell($v_tar)+
(ceil(($v_header[size
]/512))*512));
2558 gzseek($v_tar, gztell($v_tar)+
(ceil(($v_header[size
]/512))*512));
2562 TrFctMessage(__FILE__
, __LINE__
, 2, "Start extraction of '$v_header[filename]'");
2565 $n = floor($v_header[size
]/512);
2566 for ($i=0; $i<$n; $i++
)
2568 TrFctMessage(__FILE__
, __LINE__
, 3, "Read complete 512 bytes block number ".($i+
1));
2569 if ($p_tar_mode == "tar")
2570 $v_content = fread($v_tar, 512);
2572 $v_content = gzread($v_tar, 512);
2573 fwrite($v_dest_file, $v_content, 512);
2575 if (($v_header[size
] %
512) != 0)
2577 TrFctMessage(__FILE__
, __LINE__
, 3, "Read last ".($v_header[size
] %
512)." bytes in a 512 block");
2578 if ($p_tar_mode == "tar")
2579 $v_content = fread($v_tar, 512);
2581 $v_content = gzread($v_tar, 512);
2582 fwrite($v_dest_file, $v_content, ($v_header[size
] %
512));
2585 // ----- Close the destination file
2586 fclose($v_dest_file);
2588 // ----- Change the file mode, mtime
2589 touch($v_header[filename
], $v_header[mtime
]);
2590 //chmod($v_header[filename], DecOct($v_header[mode]));
2593 // ----- Check the file size
2595 if (filesize($v_header[filename
]) != $v_header[size
])
2598 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.");
2601 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
2602 return PclErrorCode();
2606 TrFctMessage(__FILE__
, __LINE__
, 2, "Extraction done");
2610 TrFctMessage(__FILE__
, __LINE__
, 2, "Extraction of file '$v_header[filename]' skipped.");
2612 // ----- Jump to next file
2613 TrFctMessage(__FILE__
, __LINE__
, 2, "Jump to next file");
2614 if ($p_tar_mode == "tar")
2615 fseek($v_tar, ftell($v_tar)+
(ceil(($v_header[size
]/512))*512));
2617 gzseek($v_tar, gztell($v_tar)+
(ceil(($v_header[size
]/512))*512));
2621 TrFctEnd(__FILE__
, __LINE__
, $v_result);
2624 // --------------------------------------------------------------------------------
2626 // --------------------------------------------------------------------------------
2627 // Function : PclTarHandleDelete()
2631 // --------------------------------------------------------------------------------
2632 function PclTarHandleDelete($p_tarname, $p_file_list, &$p_list_detail, $p_tar_mode)
2634 TrFctStart(__FILE__
, __LINE__
, "PclTarHandleDelete", "archive='$p_tarname', list, tar_mode=$p_tar_mode");
2638 // ----- Look for regular tar file
2639 if ($p_tar_mode == "tar")
2642 TrFctMessage(__FILE__
, __LINE__
, 3, "Open file in binary read mode");
2643 if (($v_tar = @fopen
($p_tarname, "rb")) == 0)
2646 PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode");
2649 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
2650 return PclErrorCode();
2653 // ----- Open a temporary file in write mode
2654 $v_temp_tarname = uniqid("pcltar-").".tmp";
2655 TrFctMessage(__FILE__
, __LINE__
, 2, "Creating temporary archive file $v_temp_tarname");
2656 if (($v_temp_tar = @fopen
($v_temp_tarname, "wb")) == 0)
2658 // ----- Close tar file
2662 PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode");
2665 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
2666 return PclErrorCode();
2670 // ----- Look for compressed tar file
2673 // ----- Open the file in read mode
2674 TrFctMessage(__FILE__
, __LINE__
, 3, "Open file in gzip binary read mode");
2675 if (($v_tar = @gzopen
($p_tarname, "rb")) == 0)
2678 PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode");
2681 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
2682 return PclErrorCode();
2685 // ----- Open a temporary file in write mode
2686 $v_temp_tarname = uniqid("pcltar-").".tmp";
2687 TrFctMessage(__FILE__
, __LINE__
, 2, "Creating temporary archive file $v_temp_tarname");
2688 if (($v_temp_tar = @gzopen
($v_temp_tarname, "wb")) == 0)
2690 // ----- Close tar file
2694 PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode");
2697 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
2698 return PclErrorCode();
2702 // ----- Read the blocks
2703 While (!($v_end_of_file = ($p_tar_mode == "tar"?
feof($v_tar):gzeof($v_tar))))
2705 TrFctMessage(__FILE__
, __LINE__
, 3, "Looking for next header ...");
2707 // ----- Clear cache of file infos
2710 // ----- Reset delete tag
2711 $v_delete_file = FALSE;
2713 // ----- Read the first 512 block header
2714 if ($p_tar_mode == "tar")
2715 $v_binary_data = fread($v_tar, 512);
2717 $v_binary_data = gzread($v_tar, 512);
2719 // ----- Read the header properties
2720 if (($v_result = PclTarHandleReadHeader($v_binary_data, $v_header)) != 1)
2722 // ----- Close the archive file
2723 if ($p_tar_mode == "tar")
2726 fclose($v_temp_tar);
2731 gzclose($v_temp_tar);
2733 @unlink
($v_temp_tarname);
2736 TrFctEnd(__FILE__
, __LINE__
, $v_result);
2740 // ----- Look for empty blocks to skip
2741 if ($v_header[filename
] == "")
2743 TrFctMessage(__FILE__
, __LINE__
, 2, "Empty block found. End of archive ?");
2747 TrFctMessage(__FILE__
, __LINE__
, 2, "Found file '$v_header[filename]', size '$v_header[size]'");
2749 // ----- Look for filenames to delete
2750 for ($i=0, $v_delete_file=FALSE; ($i<sizeof($p_file_list)) && (!$v_delete_file); $i++
)
2752 // ----- Compare the file names
2753 // if ($p_file_list[$i] == $v_header[filename])
2754 if (($v_len = strcmp($p_file_list[$i], $v_header[filename
])) <= 0)
2758 TrFctMessage(__FILE__
, __LINE__
, 3, "Found that '$v_header[filename]' need to be deleted");
2759 $v_delete_file = TRUE;
2763 TrFctMessage(__FILE__
, __LINE__
, 3, "Look if '$v_header[filename]' is a file in $p_file_list[$i]");
2764 if (substr($v_header[filename
], strlen($p_file_list[$i]), 1) == "/")
2766 TrFctMessage(__FILE__
, __LINE__
, 3, "'$v_header[filename]' is a file in $p_file_list[$i]");
2767 $v_delete_file = TRUE;
2773 // ----- Copy files that do not need to be deleted
2774 if (!$v_delete_file)
2776 TrFctMessage(__FILE__
, __LINE__
, 2, "Keep file '$v_header[filename]'");
2778 // ----- Write the file header
2779 if ($p_tar_mode == "tar")
2781 fputs($v_temp_tar, $v_binary_data, 512);
2785 gzputs($v_temp_tar, $v_binary_data, 512);
2788 // ----- Write the file data
2789 $n = ceil($v_header[size
]/512);
2790 for ($i=0; $i<$n; $i++
)
2792 TrFctMessage(__FILE__
, __LINE__
, 3, "Read complete 512 bytes block number ".($i+
1));
2793 if ($p_tar_mode == "tar")
2795 $v_content = fread($v_tar, 512);
2796 fwrite($v_temp_tar, $v_content, 512);
2800 $v_content = gzread($v_tar, 512);
2801 gzwrite($v_temp_tar, $v_content, 512);
2805 // ----- File name and properties are logged if listing mode or file is extracted
2806 TrFctMessage(__FILE__
, __LINE__
, 2, "Memorize info about file '$v_header[filename]'");
2808 // ----- Add the array describing the file into the list
2809 $p_list_detail[$v_nb] = $v_header;
2810 $p_list_detail[$v_nb][status
] = "ok";
2816 // ----- Look for file that is to be deleted
2820 TrFctMessage(__FILE__
, __LINE__
, 2, "Start deletion of '$v_header[filename]'");
2821 TrFctMessage(__FILE__
, __LINE__
, 4, "Position avant jump [".($p_tar_mode=="tar"?
ftell($v_tar):gztell($v_tar))."]");
2823 // ----- Jump to next file
2824 if ($p_tar_mode == "tar")
2825 fseek($v_tar, ftell($v_tar)+
(ceil(($v_header[size
]/512))*512));
2827 gzseek($v_tar, gztell($v_tar)+
(ceil(($v_header[size
]/512))*512));
2829 TrFctMessage(__FILE__
, __LINE__
, 4, "Position apr�s jump [".($p_tar_mode=="tar"?
ftell($v_tar):gztell($v_tar))."]");
2832 // ----- Look for end of file
2833 if ($p_tar_mode == "tar")
2834 $v_end_of_file = feof($v_tar);
2836 $v_end_of_file = gzeof($v_tar);
2839 // ----- Write the last empty buffer
2840 PclTarHandleFooter($v_temp_tar, $p_tar_mode);
2842 // ----- Close the tarfile
2843 if ($p_tar_mode == "tar")
2846 fclose($v_temp_tar);
2851 gzclose($v_temp_tar);
2854 // ----- Unlink tar file
2855 if (!@unlink
($p_tarname))
2858 PclErrorLog(-11, "Error while deleting archive name $p_tarname");
2862 // ----- Rename tar file
2863 if (!@rename
($v_temp_tarname, $p_tarname))
2866 PclErrorLog(-12, "Error while renaming temporary file $v_temp_tarname to archive name $p_tarname");
2869 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
2870 return PclErrorCode();
2874 TrFctEnd(__FILE__
, __LINE__
, $v_result);
2877 // --------------------------------------------------------------------------------
2879 // --------------------------------------------------------------------------------
2880 // Function : PclTarHandleUpdate()
2884 // --------------------------------------------------------------------------------
2885 function PclTarHandleUpdate($p_tarname, $p_file_list, &$p_list_detail, $p_tar_mode, $p_add_dir, $p_remove_dir)
2887 TrFctStart(__FILE__
, __LINE__
, "PclTarHandleUpdate", "archive='$p_tarname', list, tar_mode=$p_tar_mode");
2890 $v_found_list = array();
2892 // ----- Look for regular tar file
2893 if ($p_tar_mode == "tar")
2896 TrFctMessage(__FILE__
, __LINE__
, 3, "Open file in binary read mode");
2897 if (($v_tar = @fopen
($p_tarname, "rb")) == 0)
2900 PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode");
2903 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
2904 return PclErrorCode();
2907 // ----- Open a temporary file in write mode
2908 $v_temp_tarname = uniqid("pcltar-").".tmp";
2909 TrFctMessage(__FILE__
, __LINE__
, 2, "Creating temporary archive file $v_temp_tarname");
2910 if (($v_temp_tar = @fopen
($v_temp_tarname, "wb")) == 0)
2912 // ----- Close tar file
2916 PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode");
2919 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
2920 return PclErrorCode();
2924 // ----- Look for compressed tar file
2927 // ----- Open the file in read mode
2928 TrFctMessage(__FILE__
, __LINE__
, 3, "Open file in gzip binary read mode");
2929 if (($v_tar = @gzopen
($p_tarname, "rb")) == 0)
2932 PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode");
2935 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
2936 return PclErrorCode();
2939 // ----- Open a temporary file in write mode
2940 $v_temp_tarname = uniqid("pcltar-").".tmp";
2941 TrFctMessage(__FILE__
, __LINE__
, 2, "Creating temporary archive file $v_temp_tarname");
2942 if (($v_temp_tar = @gzopen
($v_temp_tarname, "wb")) == 0)
2944 // ----- Close tar file
2948 PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode");
2951 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
2952 return PclErrorCode();
2956 // ----- Prepare the list of files
2957 for ($i=0; $i<sizeof($p_file_list); $i++
)
2959 // ----- Reset the found list
2960 $v_found_list[$i] = 0;
2962 // ----- Calculate the stored filename
2963 $v_stored_list[$i] = $p_file_list[$i];
2964 if ($p_remove_dir != "")
2966 if (substr($p_file_list[$i], -1) != '/')
2967 $p_remove_dir .= "/";
2969 if (substr($p_file_list[$i], 0, strlen($p_remove_dir)) == $p_remove_dir)
2971 $v_stored_list[$i] = substr($p_file_list[$i], strlen($p_remove_dir));
2972 TrFctMessage(__FILE__
, __LINE__
, 3, "Remove path '$p_remove_dir' in file '$p_file_list[$i]' = '$v_stored_list[$i]'");
2975 if ($p_add_dir != "")
2977 if (substr($p_add_dir, -1) == "/")
2978 $v_stored_list[$i] = $p_add_dir.$v_stored_list[$i];
2980 $v_stored_list[$i] = $p_add_dir."/".$v_stored_list[$i];
2981 TrFctMessage(__FILE__
, __LINE__
, 3, "Add path '$p_add_dir' in file '$p_file_list[$i]' = '$v_stored_list[$i]'");
2983 $v_stored_list[$i] = PclTarHandlePathReduction($v_stored_list[$i]);
2984 TrFctMessage(__FILE__
, __LINE__
, 3, "After reduction '$v_stored_list[$i]'");
2988 // ----- Update file cache
2991 // ----- Read the blocks
2992 While (!($v_end_of_file = ($p_tar_mode == "tar"?
feof($v_tar):gzeof($v_tar))))
2994 TrFctMessage(__FILE__
, __LINE__
, 3, "Looking for next header ...");
2996 // ----- Clear cache of file infos
2999 // ----- Reset current found filename
3000 $v_current_filename = "";
3002 // ----- Reset delete tag
3003 $v_delete_file = FALSE;
3005 // ----- Read the first 512 block header
3006 if ($p_tar_mode == "tar")
3007 $v_binary_data = fread($v_tar, 512);
3009 $v_binary_data = gzread($v_tar, 512);
3011 // ----- Read the header properties
3012 if (($v_result = PclTarHandleReadHeader($v_binary_data, $v_header)) != 1)
3014 // ----- Close the archive file
3015 if ($p_tar_mode == "tar")
3018 fclose($v_temp_tar);
3023 gzclose($v_temp_tar);
3025 @unlink
($v_temp_tarname);
3028 TrFctEnd(__FILE__
, __LINE__
, $v_result);
3032 // ----- Look for empty blocks to skip
3033 if ($v_header[filename
] == "")
3035 TrFctMessage(__FILE__
, __LINE__
, 2, "Empty block found. End of archive ?");
3039 TrFctMessage(__FILE__
, __LINE__
, 2, "Found file '$v_header[filename]', size '$v_header[size]'");
3041 // ----- Look for filenames to update
3042 for ($i=0, $v_update_file=FALSE, $v_found_file=FALSE; ($i<sizeof($v_stored_list)) && (!$v_update_file); $i++
)
3044 TrFctMessage(__FILE__
, __LINE__
, 4, "Compare with file '$v_stored_list[$i]'");
3046 // ----- Compare the file names
3047 if ($v_stored_list[$i] == $v_header[filename
])
3049 TrFctMessage(__FILE__
, __LINE__
, 3, "File '$v_stored_list[$i]' is present in archive");
3050 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])));
3051 TrFctMessage(__FILE__
, __LINE__
, 3, "Archived mtime=".$v_header[mtime
]." ".date("l dS of F Y h:i:s A", $v_header[mtime
]));
3053 // ----- Store found informations
3054 $v_found_file = TRUE;
3055 $v_current_filename = $p_file_list[$i];
3057 // ----- Look if the file need to be updated
3058 if (filemtime($p_file_list[$i]) > $v_header[mtime
])
3060 TrFctMessage(__FILE__
, __LINE__
, 3, "File '$p_file_list[$i]' need to be updated");
3061 $v_update_file = TRUE;
3065 TrFctMessage(__FILE__
, __LINE__
, 3, "File '$p_file_list[$i]' does not need to be updated");
3066 $v_update_file = FALSE;
3069 // ----- Flag the name in order not to add the file at the end
3070 $v_found_list[$i] = 1;
3074 TrFctMessage(__FILE__
, __LINE__
, 4, "File '$p_file_list[$i]' is not '$v_header[filename]'");
3078 // ----- Copy files that do not need to be updated
3079 if (!$v_update_file)
3081 TrFctMessage(__FILE__
, __LINE__
, 2, "Keep file '$v_header[filename]'");
3083 // ----- Write the file header
3084 if ($p_tar_mode == "tar")
3086 fputs($v_temp_tar, $v_binary_data, 512);
3090 gzputs($v_temp_tar, $v_binary_data, 512);
3093 // ----- Write the file data
3094 $n = ceil($v_header[size
]/512);
3095 for ($j=0; $j<$n; $j++
)
3097 TrFctMessage(__FILE__
, __LINE__
, 3, "Read complete 512 bytes block number ".($j+
1));
3098 if ($p_tar_mode == "tar")
3100 $v_content = fread($v_tar, 512);
3101 fwrite($v_temp_tar, $v_content, 512);
3105 $v_content = gzread($v_tar, 512);
3106 gzwrite($v_temp_tar, $v_content, 512);
3110 // ----- File name and properties are logged if listing mode or file is extracted
3111 TrFctMessage(__FILE__
, __LINE__
, 2, "Memorize info about file '$v_header[filename]'");
3113 // ----- Add the array describing the file into the list
3114 $p_list_detail[$v_nb] = $v_header;
3115 $p_list_detail[$v_nb][status
] = ($v_found_file?
"not_updated":"ok");
3121 // ----- Look for file that need to be updated
3125 TrFctMessage(__FILE__
, __LINE__
, 2, "Start update of file '$v_current_filename'");
3127 // ----- Store the old file size
3128 $v_old_size = $v_header[size
];
3130 // ----- Add the file
3131 if (($v_result = PclTarHandleAddFile($v_temp_tar, $v_current_filename, $p_tar_mode, $v_header, $p_add_dir, $p_remove_dir)) != 1)
3133 // ----- Close the tarfile
3134 if ($p_tar_mode == "tar")
3137 fclose($v_temp_tar);
3142 gzclose($v_temp_tar);
3144 @unlink
($p_temp_tarname);
3146 // ----- Return status
3147 TrFctEnd(__FILE__
, __LINE__
, $v_result);
3152 TrFctMessage(__FILE__
, __LINE__
, 2, "Skip old file '$v_header[filename]'");
3154 // ----- Jump to next file
3155 if ($p_tar_mode == "tar")
3156 fseek($v_tar, ftell($v_tar)+
(ceil(($v_old_size/512))*512));
3158 gzseek($v_tar, gztell($v_tar)+
(ceil(($v_old_size/512))*512));
3160 // ----- Add the array describing the file into the list
3161 $p_list_detail[$v_nb] = $v_header;
3162 $p_list_detail[$v_nb][status
] = "updated";
3168 // ----- Look for end of file
3169 if ($p_tar_mode == "tar")
3170 $v_end_of_file = feof($v_tar);
3172 $v_end_of_file = gzeof($v_tar);
3175 // ----- Look for files that does not exists in the archive and need to be added
3176 for ($i=0; $i<sizeof($p_file_list); $i++
)
3178 // ----- Look if file not found in the archive
3179 if (!$v_found_list[$i])
3181 TrFctMessage(__FILE__
, __LINE__
, 3, "File '$p_file_list[$i]' need to be added");
3183 // ----- Add the file
3184 if (($v_result = PclTarHandleAddFile($v_temp_tar, $p_file_list[$i], $p_tar_mode, $v_header, $p_add_dir, $p_remove_dir)) != 1)
3186 // ----- Close the tarfile
3187 if ($p_tar_mode == "tar")
3190 fclose($v_temp_tar);
3195 gzclose($v_temp_tar);
3197 @unlink
($p_temp_tarname);
3199 // ----- Return status
3200 TrFctEnd(__FILE__
, __LINE__
, $v_result);
3204 // ----- Add the array describing the file into the list
3205 $p_list_detail[$v_nb] = $v_header;
3206 $p_list_detail[$v_nb][status
] = "added";
3213 TrFctMessage(__FILE__
, __LINE__
, 3, "File '$p_file_list[$i]' was already updated if needed");
3217 // ----- Write the last empty buffer
3218 PclTarHandleFooter($v_temp_tar, $p_tar_mode);
3220 // ----- Close the tarfile
3221 if ($p_tar_mode == "tar")
3224 fclose($v_temp_tar);
3229 gzclose($v_temp_tar);
3232 // ----- Unlink tar file
3233 if (!@unlink
($p_tarname))
3236 PclErrorLog(-11, "Error while deleting archive name $p_tarname");
3240 // ----- Rename tar file
3241 if (!@rename
($v_temp_tarname, $p_tarname))
3244 PclErrorLog(-12, "Error while renaming temporary file $v_temp_tarname to archive name $p_tarname");
3247 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
3248 return PclErrorCode();
3252 TrFctEnd(__FILE__
, __LINE__
, $v_result);
3255 // --------------------------------------------------------------------------------
3257 // --------------------------------------------------------------------------------
3258 // Function : PclTarHandleReadHeader()
3262 // --------------------------------------------------------------------------------
3263 function PclTarHandleReadHeader($v_binary_data, &$v_header)
3265 TrFctStart(__FILE__
, __LINE__
, "PclTarHandleReadHeader", "");
3268 // ----- Read the 512 bytes header
3270 if ($p_tar_mode == "tar")
3271 $v_binary_data = fread($p_tar, 512);
3273 $v_binary_data = gzread($p_tar, 512);
3276 // ----- Look for no more block
3277 if (strlen($v_binary_data)==0)
3279 $v_header[filename
] = "";
3280 $v_header[status
] = "empty";
3283 TrFctEnd(__FILE__
, __LINE__
, $v_result, "End of archive found");
3287 // ----- Look for invalid block size
3288 if (strlen($v_binary_data) != 512)
3290 $v_header[filename
] = "";
3291 $v_header[status
] = "invalid_header";
3292 TrFctMessage(__FILE__
, __LINE__
, 2, "Invalid block size : ".strlen($v_binary_data));
3295 PclErrorLog(-10, "Invalid block size : ".strlen($v_binary_data));
3298 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
3299 return PclErrorCode();
3302 // ----- Calculate the checksum
3304 // ..... First part of the header
3305 for ($i=0; $i<148; $i++
)
3307 $v_checksum+
=ord(substr($v_binary_data,$i,1));
3309 // ..... Ignore the checksum value and replace it by ' ' (space)
3310 for ($i=148; $i<156; $i++
)
3312 $v_checksum +
= ord(' ');
3314 // ..... Last part of the header
3315 for ($i=156; $i<512; $i++
)
3317 $v_checksum+
=ord(substr($v_binary_data,$i,1));
3319 TrFctMessage(__FILE__
, __LINE__
, 3, "Calculated checksum : $v_checksum");
3321 // ----- Extract the values
3322 TrFctMessage(__FILE__
, __LINE__
, 2, "Header : '$v_binary_data'");
3323 $v_data = unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor", $v_binary_data);
3325 // ----- Extract the checksum for check
3326 $v_header[checksum
] = OctDec(trim($v_data[checksum
]));
3327 TrFctMessage(__FILE__
, __LINE__
, 3, "File checksum : $v_header[checksum]");
3328 if ($v_header[checksum
] != $v_checksum)
3330 TrFctMessage(__FILE__
, __LINE__
, 2, "File checksum is invalid : $v_checksum calculated, $v_header[checksum] expected");
3332 $v_header[filename
] = "";
3333 $v_header[status
] = "invalid_header";
3335 // ----- Look for last block (empty block)
3336 if (($v_checksum == 256) && ($v_header[checksum
] == 0))
3338 $v_header[status
] = "empty";
3340 TrFctEnd(__FILE__
, __LINE__
, $v_result, "End of archive found");
3345 PclErrorLog(-13, "Invalid checksum : $v_checksum calculated, $v_header[checksum] expected");
3348 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
3349 return PclErrorCode();
3351 TrFctMessage(__FILE__
, __LINE__
, 2, "File checksum is valid ($v_checksum)");
3353 // ----- Extract the properties
3354 $v_header[filename
] = trim($v_data[filename
]);
3355 TrFctMessage(__FILE__
, __LINE__
, 2, "Name : '$v_header[filename]'");
3356 $v_header[mode
] = OctDec(trim($v_data[mode
]));
3357 TrFctMessage(__FILE__
, __LINE__
, 2, "Mode : '".DecOct($v_header[mode
])."'");
3358 $v_header[uid
] = OctDec(trim($v_data[uid
]));
3359 TrFctMessage(__FILE__
, __LINE__
, 2, "Uid : '$v_header[uid]'");
3360 $v_header[gid
] = OctDec(trim($v_data[gid
]));
3361 TrFctMessage(__FILE__
, __LINE__
, 2, "Gid : '$v_header[gid]'");
3362 $v_header[size
] = OctDec(trim($v_data[size
]));
3363 TrFctMessage(__FILE__
, __LINE__
, 2, "Size : '$v_header[size]'");
3364 $v_header[mtime
] = OctDec(trim($v_data[mtime
]));
3365 TrFctMessage(__FILE__
, __LINE__
, 2, "Date : ".date("l dS of F Y h:i:s A", $v_header[mtime
]));
3366 if (($v_header[typeflag
] = $v_data[typeflag
]) == "5")
3368 $v_header[size
] = 0;
3369 TrFctMessage(__FILE__
, __LINE__
, 2, "Size (folder) : '$v_header[size]'");
3371 TrFctMessage(__FILE__
, __LINE__
, 2, "File typeflag : $v_header[typeflag]");
3372 /* ----- All these fields are removed form the header because they do not carry interesting info
3373 $v_header[link] = trim($v_data[link]);
3374 TrFctMessage(__FILE__, __LINE__, 2, "Linkname : $v_header[linkname]");
3375 $v_header[magic] = trim($v_data[magic]);
3376 TrFctMessage(__FILE__, __LINE__, 2, "Magic : $v_header[magic]");
3377 $v_header[version] = trim($v_data[version]);
3378 TrFctMessage(__FILE__, __LINE__, 2, "Version : $v_header[version]");
3379 $v_header[uname] = trim($v_data[uname]);
3380 TrFctMessage(__FILE__, __LINE__, 2, "Uname : $v_header[uname]");
3381 $v_header[gname] = trim($v_data[gname]);
3382 TrFctMessage(__FILE__, __LINE__, 2, "Gname : $v_header[gname]");
3383 $v_header[devmajor] = trim($v_data[devmajor]);
3384 TrFctMessage(__FILE__, __LINE__, 2, "Devmajor : $v_header[devmajor]");
3385 $v_header[devminor] = trim($v_data[devminor]);
3386 TrFctMessage(__FILE__, __LINE__, 2, "Devminor : $v_header[devminor]");
3389 // ----- Set the status field
3390 $v_header[status
] = "ok";
3393 TrFctEnd(__FILE__
, __LINE__
, $v_result);
3396 // --------------------------------------------------------------------------------
3398 // --------------------------------------------------------------------------------
3399 // Function : PclTarHandlerDirCheck()
3401 // Check if a directory exists, if not it creates it and all the parents directory
3402 // which may be useful.
3404 // $p_dir : Directory path to check (without / at the end).
3407 // -1 : Unable to create directory
3408 // --------------------------------------------------------------------------------
3409 function PclTarHandlerDirCheck($p_dir)
3413 TrFctStart(__FILE__
, __LINE__
, "PclTarHandlerDirCheck", "$p_dir");
3415 // ----- Check the directory availability
3416 if ((is_dir($p_dir)) ||
($p_dir == ""))
3418 TrFctEnd(__FILE__
, __LINE__
, "'$p_dir' is a directory");
3422 // ----- Look for file alone
3424 if (!strstr("$p_dir", "/"))
3426 TrFctEnd(__FILE__, __LINE__, "'$p_dir' is a file with no directory");
3431 // ----- Extract parent directory
3432 $p_parent_dir = dirname($p_dir);
3433 TrFctMessage(__FILE__
, __LINE__
, 3, "Parent directory is '$p_parent_dir'");
3435 // ----- Just a check
3436 if ($p_parent_dir != $p_dir)
3438 // ----- Look for parent directory
3439 if ($p_parent_dir != "")
3441 if (($v_result = PclTarHandlerDirCheck($p_parent_dir)) != 1)
3443 TrFctEnd(__FILE__
, __LINE__
, $v_result);
3449 // ----- Create the directory
3450 TrFctMessage(__FILE__
, __LINE__
, 3, "Create directory '$p_dir'");
3451 if (!@mkdir
($p_dir, 0777))
3454 PclErrorLog(-8, "Unable to create directory '$p_dir'");
3457 TrFctEnd(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
3458 return PclErrorCode();
3462 TrFctEnd(__FILE__
, __LINE__
, $v_result, "Directory '$p_dir' created");
3465 // --------------------------------------------------------------------------------
3467 // --------------------------------------------------------------------------------
3468 // Function : PclTarHandleExtension()
3472 // --------------------------------------------------------------------------------
3473 function PclTarHandleExtension($p_tarname)
3475 TrFctStart(__FILE__
, __LINE__
, "PclTarHandleExtension", "tar=$p_tarname");
3477 // ----- Look for file extension
3478 if ((substr($p_tarname, -7) == ".tar.gz") ||
(substr($p_tarname, -4) == ".tgz"))
3480 TrFctMessage(__FILE__
, __LINE__
, 2, "Archive is a gzip tar");
3481 $v_tar_mode = "tgz";
3483 else if (substr($p_tarname, -4) == ".tar")
3485 TrFctMessage(__FILE__
, __LINE__
, 2, "Archive is a tar");
3486 $v_tar_mode = "tar";
3491 PclErrorLog(-9, "Invalid archive extension");
3493 TrFctMessage(__FILE__
, __LINE__
, PclErrorCode(), PclErrorString());
3499 TrFctEnd(__FILE__
, __LINE__
, $v_tar_mode);
3502 // --------------------------------------------------------------------------------
3505 // --------------------------------------------------------------------------------
3506 // Function : PclTarHandlePathReduction()
3510 // --------------------------------------------------------------------------------
3511 function PclTarHandlePathReduction($p_dir)
3513 TrFctStart(__FILE__
, __LINE__
, "PclTarHandlePathReduction", "dir='$p_dir'");
3516 // ----- Look for not empty path
3519 // ----- Explode path by directory names
3520 $v_list = explode("/", $p_dir);
3522 // ----- Study directories from last to first
3523 for ($i=sizeof($v_list)-1; $i>=0; $i--)
3525 // ----- Look for current path
3526 if ($v_list[$i] == ".")
3528 // ----- Ignore this directory
3529 // Should be the first $i=0, but no check is done
3531 else if ($v_list[$i] == "..")
3533 // ----- Ignore it and ignore the $i-1
3536 else if (($v_list[$i] == "") && ($i!=(sizeof($v_list)-1)) && ($i!=0))
3538 // ----- Ignore only the double '//' in path,
3539 // but not the first and last '/'
3543 $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?
"/".$v_result:"");
3549 TrFctEnd(__FILE__
, __LINE__
, $v_result);
3552 // --------------------------------------------------------------------------------
3555 // ----- End of double include look