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