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