[ Index ]

PHP Cross Reference of Mambo 4.6.5

[ Variables ]     [ Functions ]     [ Classes ]     [ Constants ]     [ Statistics ]

title

Body

[close]

/administrator/includes/pcl/ -> pcltar.lib.php (source)

   1  <?php
   2  /**
   3  * @package Mambo
   4  */
   5  
   6  /** ensure this file is being included by a parent file */
   7  defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );
   8  
   9  // --------------------------------------------------------------------------------
  10  // PhpConcept Library - Tar Module 1.3
  11  // --------------------------------------------------------------------------------
  12  // License GNU/GPL - Vincent Blavet - August 2001
  13  // http://www.phpconcept.net
  14  // --------------------------------------------------------------------------------
  15  //
  16  // Presentation :
  17  //   PclTar is a library that allow you to create a GNU TAR + GNU ZIP archive,
  18  //   to add files or directories, to extract all the archive or a part of it.
  19  //   So far tests show that the files generated by PclTar are readable by
  20  //   gzip tools and WinZip application.
  21  //
  22  // Description :
  23  //   See readme.txt (English & Français) and http://www.phpconcept.net
  24  //
  25  // Warning :
  26  //   This library and the associated files are non commercial, non professional
  27  //   work.
  28  //   It should not have unexpected results. However if any damage is caused by
  29  //   this software the author can not be responsible.
  30  //   The use of this software is at the risk of the user.
  31  //
  32  // --------------------------------------------------------------------------------
  33  
  34  // ----- Look for double include
  35  if (!defined("PCL_TAR"))
  36  {
  37    define( "PCL_TAR", 1 );
  38  
  39    // ----- Configuration variable
  40    // Theses values may be changed by the user of PclTar library
  41    if (!isset($g_pcltar_lib_dir))
  42      $g_pcltar_lib_dir = "lib";
  43  
  44    // ----- Error codes
  45    //   -1 : Unable to open file in binary write mode
  46    //   -2 : Unable to open file in binary read mode
  47    //   -3 : Invalid parameters
  48    //   -4 : File does not exist
  49    //   -5 : Filename is too long (max. 99)
  50    //   -6 : Not a valid tar file
  51    //   -7 : Invalid extracted file size
  52    //   -8 : Unable to create directory
  53    //   -9 : Invalid archive extension
  54    //  -10 : Invalid archive format
  55    //  -11 : Unable to delete file (unlink)
  56    //  -12 : Unable to rename file (rename)
  57    //  -13 : Invalid header checksum
  58  
  59  
  60  // --------------------------------------------------------------------------------
  61  // ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED *****
  62  // --------------------------------------------------------------------------------
  63  
  64    // ----- Global variables
  65    $g_pcltar_version = "1.3";
  66  
  67    // ----- Extract extension type (.php3/.php/...)
  68  //  $g_pcltar_extension = substr(strrchr(basename($PATH_TRANSLATED), '.'), 1);
  69    $g_pcltar_extension = substr(strrchr(basename(@$_SERVER["PATH_TRANSLATED"]), '.'), 1);
  70  
  71    // ----- Include other libraries
  72    // This library should be called by each script before the include of PhpZip
  73    // Library in order to limit the potential 'lib' directory path problem.
  74  
  75    if (!defined("PCLERROR_LIB"))
  76    {
  77      include($g_pcltar_lib_dir."/pclerror.lib.".$g_pcltar_extension);
  78    }
  79    if (!defined("PCLTRACE_LIB"))
  80    {
  81      include($g_pcltar_lib_dir."/pcltrace.lib.".$g_pcltar_extension);
  82    }
  83  
  84    // --------------------------------------------------------------------------------
  85    // Function : PclTarCreate()
  86    // Description :
  87    //   Creates a new archive with name $p_tarname containing the files and/or
  88    //   directories indicated in $p_list. If the tar filename extension is
  89    //   ".tar", the file will not be compressed. If it is ".tar.gz" or ".tgz"
  90    //   it will be a gzip compressed tar archive.
  91    //   If you want to use an other extension, you must indicate the mode in
  92    //   $p_mode ("tar" or "tgz").
  93    //   $p_add_dir and $p_remove_dir give you the ability to store a path
  94    //   which is not the real path of the files.
  95    // Parameters :
  96    //   $p_tarname : Name of an existing tar file
  97    //   $p_filelist : An array containing file or directory names, or
  98    //                 a string containing one filename or directory name, or
  99    //                 a string containing a list of filenames and/or directory
 100    //                 names separated by spaces.
 101    //   $p_mode : "tar" for normal tar archive, "tgz" for gzipped tar archive,
 102    //             if $p_mode is not specified, it will be determined by the extension.
 103    //   $p_add_dir : Path to add in the filename path archived
 104    //   $p_remove_dir : Path to remove in the filename path archived
 105    // Return Values :
 106    //   1 on success, or an error code (see table at the beginning).
 107    // --------------------------------------------------------------------------------
 108    function PclTarCreate($p_tarname, $p_filelist="", $p_mode="", $p_add_dir="", $p_remove_dir="")
 109    {
 110      TrFctStart(__FILE__, __LINE__, "PclTarCreate", "tar=$p_tarname, file='$p_filelist', mode=$p_mode, add_dir='$p_add_dir', remove_dir='$p_remove_dir'");
 111      $v_result=1;
 112  
 113      // ----- Look for default mode
 114      if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz")))
 115      {
 116        // ----- Extract the tar format from the extension
 117        if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
 118        {
 119          // ----- Return
 120          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 121          return PclErrorCode();
 122        }
 123  
 124        // ----- Trace
 125        TrFctMessage(__FILE__, __LINE__, 1, "Auto mode selected : found $p_mode");
 126      }
 127  
 128      // ----- Look if the $p_filelist is really an array
 129      if (is_array($p_filelist))
 130      {
 131        // ----- Call the create fct
 132        $v_result = PclTarHandleCreate($p_tarname, $p_filelist, $p_mode, $p_add_dir, $p_remove_dir);
 133      }
 134  
 135      // ----- Look if the $p_filelist is a string
 136      else if (is_string($p_filelist))
 137      {
 138        // ----- Create a list with the elements from the string
 139        $v_list = explode(" ", $p_filelist);
 140  
 141        // ----- Call the create fct
 142        $v_result = PclTarHandleCreate($p_tarname, $v_list, $p_mode, $p_add_dir, $p_remove_dir);
 143      }
 144  
 145      // ----- Invalid variable
 146      else
 147      {
 148        // ----- Error log
 149        PclErrorLog(-3, "Invalid variable type p_filelist");
 150        $v_result = -3;
 151      }
 152  
 153      // ----- Return
 154      TrFctEnd(__FILE__, __LINE__, $v_result);
 155      return $v_result;
 156    }
 157    // --------------------------------------------------------------------------------
 158  
 159    // --------------------------------------------------------------------------------
 160    // Function : PclTarAdd()
 161    // Description :
 162    //   PLEASE DO NOT USE ANY MORE THIS FUNCTION. Use PclTarAddList().
 163    //
 164    //   This function is maintained only for compatibility reason
 165    //
 166    // Parameters :
 167    //   $p_tarname : Name of an existing tar file
 168    //   $p_filelist : An array containing file or directory names, or
 169    //                 a string containing one filename or directory name, or
 170    //                 a string containing a list of filenames and/or directory
 171    //                 names separated by spaces.
 172    // Return Values :
 173    //   1 on success,
 174    //   Or an error code (see list on top).
 175    // --------------------------------------------------------------------------------
 176    function PclTarAdd($p_tarname, $p_filelist)
 177    {
 178      TrFctStart(__FILE__, __LINE__, "PclTarAdd", "tar=$p_tarname, file=$p_filelist");
 179      $v_result=1;
 180      $v_list_detail = array();
 181  
 182      // ----- Extract the tar format from the extension
 183      if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
 184      {
 185        // ----- Return
 186        TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 187        return PclErrorCode();
 188      }
 189  
 190      // ----- Look if the $p_filelist is really an array
 191      if (is_array($p_filelist))
 192      {
 193        // ----- Call the add fct
 194        $v_result = PclTarHandleAppend($p_tarname, $p_filelist, $p_mode, $v_list_detail, "", "");
 195      }
 196  
 197      // ----- Look if the $p_filelist is a string
 198      else if (is_string($p_filelist))
 199      {
 200        // ----- Create a list with the elements from the string
 201        $v_list = explode(" ", $p_filelist);
 202  
 203        // ----- Call the add fct
 204        $v_result = PclTarHandleAppend($p_tarname, $v_list, $p_mode, $v_list_detail, "", "");
 205      }
 206  
 207      // ----- Invalid variable
 208      else
 209      {
 210        // ----- Error log
 211        PclErrorLog(-3, "Invalid variable type p_filelist");
 212        $v_result = -3;
 213      }
 214  
 215      // ----- Cleaning
 216      unset($v_list_detail);
 217  
 218      // ----- Return
 219      TrFctEnd(__FILE__, __LINE__, $v_result);
 220      return $v_result;
 221    }
 222    // --------------------------------------------------------------------------------
 223  
 224    // --------------------------------------------------------------------------------
 225    // Function : PclTarAddList()
 226    // Description :
 227    //   Add a list of files or directories ($p_filelist) in the tar archive $p_tarname.
 228    //   The list can be an array of file/directory names or a string with names
 229    //   separated by one space.
 230    //   $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
 231    //   different from the real path of the file. This is usefull if you want to have PclTar
 232    //   running in any directory, and memorize relative path from an other directory.
 233    //   If $p_mode is not set it will be automatically computed from the $p_tarname
 234    //   extension (.tar, .tar.gz or .tgz).
 235    // Parameters :
 236    //   $p_tarname : Name of an existing tar file
 237    //   $p_filelist : An array containing file or directory names, or
 238    //                 a string containing one filename or directory name, or
 239    //                 a string containing a list of filenames and/or directory
 240    //                 names separated by spaces.
 241    //   $p_add_dir : Path to add in the filename path archived
 242    //   $p_remove_dir : Path to remove in the filename path archived
 243    //   $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
 244    // Return Values :
 245    //   1 on success,
 246    //   Or an error code (see list on top).
 247    // --------------------------------------------------------------------------------
 248    function PclTarAddList($p_tarname, $p_filelist, $p_add_dir="", $p_remove_dir="", $p_mode="")
 249    {
 250      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");
 251      $v_result=1;
 252      $p_list_detail = array();
 253  
 254      // ----- Extract the tar format from the extension
 255      if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz")))
 256      {
 257        if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
 258        {
 259          // ----- Return
 260          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 261          return PclErrorCode();
 262        }
 263      }
 264  
 265      // ----- Look if the $p_filelist is really an array
 266      if (is_array($p_filelist))
 267      {
 268        // ----- Call the add fct
 269        $v_result = PclTarHandleAppend($p_tarname, $p_filelist, $p_mode, $p_list_detail, $p_add_dir, $p_remove_dir);
 270      }
 271  
 272      // ----- Look if the $p_filelist is a string
 273      else if (is_string($p_filelist))
 274      {
 275        // ----- Create a list with the elements from the string
 276        $v_list = explode(" ", $p_filelist);
 277  
 278        // ----- Call the add fct
 279        $v_result = PclTarHandleAppend($p_tarname, $v_list, $p_mode, $p_list_detail, $p_add_dir, $p_remove_dir);
 280      }
 281  
 282      // ----- Invalid variable
 283      else
 284      {
 285        // ----- Error log
 286        PclErrorLog(-3, "Invalid variable type p_filelist");
 287        $v_result = -3;
 288      }
 289  
 290      // ----- Return
 291      if ($v_result != 1)
 292      {
 293        TrFctEnd(__FILE__, __LINE__, 0);
 294        return 0;
 295      }
 296      TrFctEnd(__FILE__, __LINE__, $p_list_detail);
 297      return $p_list_detail;
 298    }
 299    // --------------------------------------------------------------------------------
 300  
 301    // --------------------------------------------------------------------------------
 302    // Function : PclTarList()
 303    // Description :
 304    //   Gives the list of all the files present in the tar archive $p_tarname.
 305    //   The list is the function result, it will be 0 on error.
 306    //   Depending on the $p_tarname extension (.tar, .tar.gz or .tgz) the
 307    //   function will determine the type of the archive.
 308    // Parameters :
 309    //   $p_tarname : Name of an existing tar file
 310    //   $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
 311    // Return Values :
 312    //  0 on error (Use PclErrorCode() and PclErrorString() for more info)
 313    //  or
 314    //  An array containing file properties. Each file properties is an array of
 315    //  properties.
 316    //  The properties (array field names) are :
 317    //    filename, size, mode, uid, gid, mtime, typeflag, status
 318    //  Exemple : $v_list = PclTarList("my.tar");
 319    //            for ($i=0; $i<sizeof($v_list); $i++)
 320    //              echo "Filename :'".$v_list[$i][filename]."'<br>";
 321    // --------------------------------------------------------------------------------
 322    function PclTarList($p_tarname, $p_mode="")
 323    {
 324      TrFctStart(__FILE__, __LINE__, "PclTarList", "tar=$p_tarname, mode='$p_mode'");
 325      $v_result=1;
 326  
 327      // ----- Extract the tar format from the extension
 328      if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz")))
 329      {
 330        if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
 331        {
 332          // ----- Return
 333          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 334          return 0;
 335        }
 336      }
 337  
 338      // ----- Call the extracting fct
 339      $p_list = array();
 340      if (($v_result = PclTarHandleExtract($p_tarname, 0, $p_list, "list", "", $p_mode, "")) != 1)
 341      {
 342        unset($p_list);
 343        TrFctEnd(__FILE__, __LINE__, 0, PclErrorString());
 344        return(0);
 345      }
 346  
 347      // ----- Return
 348      TrFctEnd(__FILE__, __LINE__, $p_list);
 349      return $p_list;
 350    }
 351    // --------------------------------------------------------------------------------
 352  
 353    // --------------------------------------------------------------------------------
 354    // Function : PclTarExtract()
 355    // Description :
 356    //   Extract all the files present in the archive $p_tarname, in the directory
 357    //   $p_path. The relative path of the archived files are keep and become
 358    //   relative to $p_path.
 359    //   If a file with the same name already exists it will be replaced.
 360    //   If the path to the file does not exist, it will be created.
 361    //   Depending on the $p_tarname extension (.tar, .tar.gz or .tgz) the
 362    //   function will determine the type of the archive.
 363    // Parameters :
 364    //   $p_tarname : Name of an existing tar file.
 365    //   $p_path : Path where the files will be extracted. The files will use
 366    //             their memorized path from $p_path.
 367    //             If $p_path is "", files will be extracted in "./".
 368    //   $p_remove_path : Path to remove (from the file memorized path) while writing the
 369    //                    extracted files. If the path does not match the file path,
 370    //                    the file is extracted with its memorized path.
 371    //                    $p_path and $p_remove_path are commulative.
 372    //   $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
 373    // Return Values :
 374    //   Same as PclTarList()
 375    // --------------------------------------------------------------------------------
 376    function PclTarExtract($p_tarname, $p_path="./", $p_remove_path="", $p_mode="")
 377    {
 378      TrFctStart(__FILE__, __LINE__, "PclTarExtract", "tar='$p_tarname', path='$p_path', remove_path='$p_remove_path', mode='$p_mode'");
 379      $v_result=1;
 380  
 381      // ----- Extract the tar format from the extension
 382      if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz")))
 383      {
 384        if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
 385        {
 386          // ----- Return
 387          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 388          return 0;
 389        }
 390      }
 391  
 392      // ----- Call the extracting fct
 393      if (($v_result = PclTarHandleExtract($p_tarname, 0, $p_list, "complete", $p_path, $p_mode, $p_remove_path)) != 1)
 394      {
 395        TrFctEnd(__FILE__, __LINE__, 0, PclErrorString());
 396        return(0);
 397      }
 398  
 399      // ----- Return
 400      TrFctEnd(__FILE__, __LINE__, $p_list);
 401      return $p_list;
 402    }
 403    // --------------------------------------------------------------------------------
 404  
 405    // --------------------------------------------------------------------------------
 406    // Function : PclTarExtractList()
 407    // Description :
 408    //   Extract the files present in the archive $p_tarname and specified in
 409    //   $p_filelist, in the directory
 410    //   $p_path. The relative path of the archived files are keep and become
 411    //   relative to $p_path.
 412    //   If a directory is spécified in the list, all the files from this directory
 413    //   will be extracted.
 414    //   If a file with the same name already exists it will be replaced.
 415    //   If the path to the file does not exist, it will be created.
 416    //   Depending on the $p_tarname extension (.tar, .tar.gz or .tgz) the
 417    //   function will determine the type of the archive.
 418    // Parameters :
 419    //   $p_tarname : Name of an existing tar file
 420    //   $p_filelist : An array containing file or directory names, or
 421    //                 a string containing one filename or directory name, or
 422    //                 a string containing a list of filenames and/or directory
 423    //                 names separated by spaces.
 424    //   $p_path : Path where the files will be extracted. The files will use
 425    //             their memorized path from $p_path.
 426    //             If $p_path is "", files will be extracted in "./".
 427    //   $p_remove_path : Path to remove (from the file memorized path) while writing the
 428    //                    extracted files. If the path does not match the file path,
 429    //                    the file is extracted with its memorized path.
 430    //                    $p_path and $p_remove_path are commulative.
 431    //   $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
 432    // Return Values :
 433    //   Same as PclTarList()
 434    // --------------------------------------------------------------------------------
 435    function PclTarExtractList($p_tarname, $p_filelist, $p_path="./", $p_remove_path="", $p_mode="")
 436    {
 437      TrFctStart(__FILE__, __LINE__, "PclTarExtractList", "tar=$p_tarname, list, path=$p_path, remove_path='$p_remove_path', mode='$p_mode'");
 438      $v_result=1;
 439  
 440      // ----- Extract the tar format from the extension
 441      if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz")))
 442      {
 443        if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
 444        {
 445          // ----- Return
 446          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 447          return 0;
 448        }
 449      }
 450  
 451      // ----- Look if the $p_filelist is really an array
 452      if (is_array($p_filelist))
 453      {
 454        // ----- Call the extracting fct
 455        if (($v_result = PclTarHandleExtract($p_tarname, $p_filelist, $p_list, "partial", $p_path, $v_tar_mode, $p_remove_path)) != 1)
 456        {
 457          TrFctEnd(__FILE__, __LINE__, 0, PclErrorString());
 458          return(0);
 459        }
 460      }
 461  
 462      // ----- Look if the $p_filelist is a string
 463      else if (is_string($p_filelist))
 464      {
 465        // ----- Create a list with the elements from the string
 466        $v_list = explode(" ", $p_filelist);
 467  
 468        // ----- Call the extracting fct
 469        if (($v_result = PclTarHandleExtract($p_tarname, $v_list, $p_list, "partial", $p_path, $v_tar_mode, $p_remove_path)) != 1)
 470        {
 471          TrFctEnd(__FILE__, __LINE__, 0, PclErrorString());
 472          return(0);
 473        }
 474      }
 475  
 476      // ----- Invalid variable
 477      else
 478      {
 479        // ----- Error log
 480        PclErrorLog(-3, "Invalid variable type p_filelist");
 481  
 482        // ----- Return
 483        TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 484        return 0;
 485      }
 486  
 487      // ----- Return
 488      TrFctEnd(__FILE__, __LINE__, $p_list);
 489      return $p_list;
 490    }
 491    // --------------------------------------------------------------------------------
 492  
 493    // --------------------------------------------------------------------------------
 494    // Function : PclTarExtractIndex()
 495    // Description :
 496    //   Extract the files present in the archive $p_tarname and specified at
 497    //   the indexes in $p_index, in the directory
 498    //   $p_path. The relative path of the archived files are keep and become
 499    //   relative to $p_path.
 500    //   If a directory is specified in the list, the directory only is created. All
 501    //   the file stored in this archive for this directory
 502    //   are not extracted.
 503    //   If a file with the same name already exists it will be replaced.
 504    //   If the path to the file does not exist, it will be created.
 505    //   Depending on the $p_tarname extension (.tar, .tar.gz or .tgz) the
 506    //   function will determine the type of the archive.
 507    // Parameters :
 508    //   $p_tarname : Name of an existing tar file
 509    //   $p_index : A single index (integer) or a string of indexes of files to
 510    //              extract. The form of the string is "0,4-6,8-12" with only numbers
 511    //              and '-' for range or ',' to separate ranges. No spaces or ';'
 512    //              are allowed.
 513    //   $p_path : Path where the files will be extracted. The files will use
 514    //             their memorized path from $p_path.
 515    //             If $p_path is "", files will be extracted in "./".
 516    //   $p_remove_path : Path to remove (from the file memorized path) while writing the
 517    //                    extracted files. If the path does not match the file path,
 518    //                    the file is extracted with its memorized path.
 519    //                    $p_path and $p_remove_path are commulative.
 520    //   $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
 521    // Return Values :
 522    //   Same as PclTarList()
 523    // --------------------------------------------------------------------------------
 524    function PclTarExtractIndex($p_tarname, $p_index, $p_path="./", $p_remove_path="", $p_mode="")
 525    {
 526      TrFctStart(__FILE__, __LINE__, "PclTarExtractIndex", "tar=$p_tarname, index='$p_index', path=$p_path, remove_path='$p_remove_path', mode='$p_mode'");
 527      $v_result=1;
 528  
 529      // ----- Extract the tar format from the extension
 530      if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz")))
 531      {
 532        if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
 533        {
 534          // ----- Return
 535          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 536          return 0;
 537        }
 538      }
 539  
 540      // ----- Look if the $p_index is really an integer
 541      if (is_integer($p_index))
 542      {
 543        // ----- Call the extracting fct
 544        if (($v_result = PclTarHandleExtractByIndexList($p_tarname, "$p_index", $p_list, $p_path, $p_remove_path, $v_tar_mode)) != 1)
 545        {
 546          TrFctEnd(__FILE__, __LINE__, 0, PclErrorString());
 547          return(0);
 548        }
 549      }
 550  
 551      // ----- Look if the $p_filelist is a string
 552      else if (is_string($p_index))
 553      {
 554        // ----- Call the extracting fct
 555        if (($v_result = PclTarHandleExtractByIndexList($p_tarname, $p_index, $p_list, $p_path, $p_remove_path, $v_tar_mode)) != 1)
 556        {
 557          TrFctEnd(__FILE__, __LINE__, 0, PclErrorString());
 558          return(0);
 559        }
 560      }
 561  
 562      // ----- Invalid variable
 563      else
 564      {
 565        // ----- Error log
 566        PclErrorLog(-3, "Invalid variable type $p_index");
 567  
 568        // ----- Return
 569        TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 570        return 0;
 571      }
 572  
 573      // ----- Return
 574      TrFctEnd(__FILE__, __LINE__, $p_list);
 575      return $p_list;
 576    }
 577    // --------------------------------------------------------------------------------
 578  
 579    // --------------------------------------------------------------------------------
 580    // Function : PclTarDelete()
 581    // Description :
 582    //   This function deletes from the archive $p_tarname the files which are listed
 583    //   in $p_filelist. $p_filelist can be a string with file names separated by
 584    //   spaces, or an array containing the file names.
 585    // Parameters :
 586    //   $p_tarname : Name of an existing tar file
 587    //   $p_filelist : An array or a string containing file names to remove from the
 588    //                 archive.
 589    //   $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
 590    // Return Values :
 591    //   List of the files which are kept in the archive (same format as PclTarList())
 592    // --------------------------------------------------------------------------------
 593    function PclTarDelete($p_tarname, $p_filelist, $p_mode="")
 594    {
 595      TrFctStart(__FILE__, __LINE__, "PclTarDelete", "tar='$p_tarname', list='$p_filelist', mode='$p_mode'");
 596      $v_result=1;
 597  
 598      // ----- Extract the tar format from the extension
 599      if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz")))
 600      {
 601        if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
 602        {
 603          // ----- Return
 604          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 605          return 0;
 606        }
 607      }
 608  
 609      // ----- Look if the $p_filelist is really an array
 610      if (is_array($p_filelist))
 611      {
 612        // ----- Call the extracting fct
 613        if (($v_result = PclTarHandleDelete($p_tarname, $p_filelist, $p_list, $p_mode)) != 1)
 614        {
 615          TrFctEnd(__FILE__, __LINE__, 0, PclErrorString());
 616          return(0);
 617        }
 618      }
 619  
 620      // ----- Look if the $p_filelist is a string
 621      else if (is_string($p_filelist))
 622      {
 623        // ----- Create a list with the elements from the string
 624        $v_list = explode(" ", $p_filelist);
 625  
 626        // ----- Call the extracting fct
 627        if (($v_result = PclTarHandleDelete($p_tarname, $v_list, $p_list, $p_mode)) != 1)
 628        {
 629          TrFctEnd(__FILE__, __LINE__, 0, PclErrorString());
 630          return(0);
 631        }
 632      }
 633  
 634      // ----- Invalid variable
 635      else
 636      {
 637        // ----- Error log
 638        PclErrorLog(-3, "Invalid variable type p_filelist");
 639  
 640        // ----- Return
 641        TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 642        return 0;
 643      }
 644  
 645      // ----- Return
 646      TrFctEnd(__FILE__, __LINE__, $p_list);
 647      return $p_list;
 648    }
 649    // --------------------------------------------------------------------------------
 650  
 651    // --------------------------------------------------------------------------------
 652    // Function : PclTarUpdate()
 653    // Description :
 654    //   This function updates the files in $p_filelist which are already in the
 655    //   $p_tarname archive with an older last modified date. If the file does not
 656    //   exist, it is added at the end of the archive.
 657    // Parameters :
 658    //   $p_tarname : Name of an existing tar file
 659    //   $p_filelist : An array or a string containing file names to update from the
 660    //                 archive.
 661    //   $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
 662    // Return Values :
 663    //   List of the files contained in the archive. The field status contains
 664    //   "updated", "not_updated", "added" or "ok" for the files not concerned.
 665    // --------------------------------------------------------------------------------
 666    function PclTarUpdate($p_tarname, $p_filelist, $p_mode="", $p_add_dir="", $p_remove_dir="")
 667    {
 668      TrFctStart(__FILE__, __LINE__, "PclTarUpdate", "tar='$p_tarname', list='$p_filelist', mode='$p_mode'");
 669      $v_result=1;
 670  
 671      // ----- Extract the tar format from the extension
 672      if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz")))
 673      {
 674        if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
 675        {
 676          // ----- Return
 677          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 678          return 0;
 679        }
 680      }
 681  
 682      // ----- Look if the $p_filelist is really an array
 683      if (is_array($p_filelist))
 684      {
 685        // ----- Call the extracting fct
 686        if (($v_result = PclTarHandleUpdate($p_tarname, $p_filelist, $p_list, $p_mode, $p_add_dir, $p_remove_dir)) != 1)
 687        {
 688          TrFctEnd(__FILE__, __LINE__, 0, PclErrorString());
 689          return(0);
 690        }
 691      }
 692  
 693      // ----- Look if the $p_filelist is a string
 694      else if (is_string($p_filelist))
 695      {
 696        // ----- Create a list with the elements from the string
 697        $v_list = explode(" ", $p_filelist);
 698  
 699        // ----- Call the extracting fct
 700        if (($v_result = PclTarHandleUpdate($p_tarname, $v_list, $p_list, $p_mode, $p_add_dir, $p_remove_dir)) != 1)
 701        {
 702          TrFctEnd(__FILE__, __LINE__, 0, PclErrorString());
 703          return(0);
 704        }
 705      }
 706  
 707      // ----- Invalid variable
 708      else
 709      {
 710        // ----- Error log
 711        PclErrorLog(-3, "Invalid variable type p_filelist");
 712  
 713        // ----- Return
 714        TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 715        return 0;
 716      }
 717  
 718      // ----- Return
 719      TrFctEnd(__FILE__, __LINE__, $p_list);
 720      return $p_list;
 721    }
 722    // --------------------------------------------------------------------------------
 723  
 724  
 725    // --------------------------------------------------------------------------------
 726    // Function : PclTarMerge()
 727    // Description :
 728    //   This function add the content of $p_tarname_add at the end of $p_tarname.
 729    // Parameters :
 730    //   $p_tarname : Name of an existing tar file
 731    //   $p_tarname_add : Name of an existing tar file taht will be added at the end
 732    //                    of $p_tarname.
 733    //   $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension
 734    //   $p_mode_add : 'tar' or 'tgz', if not set, will be determined by $p_tarname_add
 735    //                 extension
 736    // Return Values :
 737    //   List of the files contained in the archive. The field status contains
 738    //   "updated", "not_updated", "added" or "ok" for the files not concerned.
 739    // --------------------------------------------------------------------------------
 740    function PclTarMerge($p_tarname, $p_tarname_add, $p_mode="", $p_mode_add="")
 741    {
 742      TrFctStart(__FILE__, __LINE__, "PclTarMerge", "tar='$p_tarname', tar_add='$p_tarname_add', mode='$p_mode', mode_add='$p_mode_add'");
 743      $v_result=1;
 744  
 745      // ----- Check the parameters
 746      if (($p_tarname == "") || ($p_tarname_add == ""))
 747      {
 748        // ----- Error log
 749        PclErrorLog(-3, "Invalid empty archive name");
 750  
 751        // ----- Return
 752        TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 753        return PclErrorCode();
 754      }
 755  
 756      // ----- Extract the tar format from the extension
 757      if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz")))
 758      {
 759        if (($p_mode = PclTarHandleExtension($p_tarname)) == "")
 760        {
 761          // ----- Return
 762          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 763          return 0;
 764        }
 765      }
 766      if (($p_mode_add == "") || (($p_mode_add!="tar") && ($p_mode_add!="tgz")))
 767      {
 768        if (($p_mode_add = PclTarHandleExtension($p_tarname_add)) == "")
 769        {
 770          // ----- Return
 771          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 772          return 0;
 773        }
 774      }
 775  
 776      // ----- Clear filecache
 777      clearstatcache();
 778  
 779      // ----- Check the file size
 780      if ((!is_file($p_tarname)) ||
 781          (((($v_size = filesize($p_tarname)) % 512) != 0) && ($p_mode=="tar")))
 782      {
 783        // ----- Error log
 784        if (!is_file($p_tarname))
 785          PclErrorLog(-4, "Archive '$p_tarname' does not exist");
 786        else
 787          PclErrorLog(-6, "Archive '$p_tarname' has invalid size ".filesize($p_tarname)."(not a 512 block multiple)");
 788  
 789        // ----- Return
 790        TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 791        return PclErrorCode();
 792      }
 793      if ((!is_file($p_tarname_add)) ||
 794          (((($v_size_add = filesize($p_tarname_add)) % 512) != 0) && ($p_mode_add=="tar")))
 795      {
 796        // ----- Error log
 797        if (!is_file($p_tarname_add))
 798          PclErrorLog(-4, "Archive '$p_tarname_add' does not exist");
 799        else
 800          PclErrorLog(-6, "Archive '$p_tarname_add' has invalid size ".filesize($p_tarname_add)."(not a 512 block multiple)");
 801  
 802        // ----- Return
 803        TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 804        return PclErrorCode();
 805      }
 806  
 807      // ----- Look for compressed archive
 808      if ($p_mode == "tgz")
 809      {
 810        // ----- Open the file in read mode
 811        if (($p_tar = @gzopen($p_tarname, "rb")) == 0)
 812        {
 813          // ----- Error log
 814          PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode");
 815  
 816          // ----- Return
 817          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 818          return PclErrorCode();
 819        }
 820  
 821        // ----- Open a temporary file in write mode
 822        $v_temp_tarname = uniqid("pcltar-").".tmp";
 823        TrFctMessage(__FILE__, __LINE__, 2, "Creating temporary archive file $v_temp_tarname");
 824        if (($v_temp_tar = @gzopen($v_temp_tarname, "wb")) == 0)
 825        {
 826          // ----- Close tar file
 827          gzclose($p_tar);
 828  
 829          // ----- Error log
 830          PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode");
 831  
 832          // ----- Return
 833          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 834          return PclErrorCode();
 835        }
 836  
 837        // ----- Read the first 512 bytes block
 838        $v_buffer = gzread($p_tar, 512);
 839  
 840        // ----- Read the following blocks but not the last one
 841        if (!gzeof($p_tar))
 842        {
 843          TrFctMessage(__FILE__, __LINE__, 3, "More than one 512 block file");
 844          $i=1;
 845  
 846          // ----- Read new 512 block and write the already read
 847          do{
 848            // ----- Write the already read block
 849            $v_binary_data = pack("a512", "$v_buffer");
 850            gzputs($v_temp_tar, $v_binary_data);
 851  
 852            $i++;
 853            TrFctMessage(__FILE__, __LINE__, 3, "Reading block $i");
 854  
 855            // ----- Read next block
 856            $v_buffer = gzread($p_tar, 512);
 857  
 858          } while (!gzeof($p_tar));
 859  
 860          TrFctMessage(__FILE__, __LINE__, 3, "$i 512 bytes blocks");
 861        }
 862      }
 863  
 864      // ----- Look for uncompressed tar file
 865      else if ($p_mode=="tar")
 866      {
 867        // ----- Open the tar file
 868        if (($p_tar = fopen($p_tarname, "r+b")) == 0)
 869        {
 870          // ----- Error log
 871          PclErrorLog(-1, "Unable to open file '$p_tarname' in binary write mode");
 872  
 873          // ----- Return
 874          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 875          return PclErrorCode();
 876        }
 877  
 878        // ----- Go to the beginning of last block
 879        TrFctMessage(__FILE__, __LINE__, 4, "Position before :".($p_mode=="tar"?ftell($p_tar):gztell($p_tar)));
 880        fseek($p_tar, $v_size-512);
 881        TrFctMessage(__FILE__, __LINE__, 4, "Position after :".($p_mode=="tar"?ftell($p_tar):gztell($p_tar)));
 882      }
 883  
 884      // ----- Look for unknown type
 885      else
 886      {
 887        // ----- Error log
 888        PclErrorLog(-3, "Invalid tar mode $p_mode");
 889  
 890        // ----- Return
 891        TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 892        return PclErrorCode();
 893      }
 894  
 895      // ----- Look for type of archive to add
 896      if ($p_mode_add == "tgz")
 897      {
 898        TrFctMessage(__FILE__, __LINE__, 4, "Opening file $p_tarname_add");
 899  
 900        // ----- Open the file in read mode
 901        if (($p_tar_add = @gzopen($p_tarname_add, "rb")) == 0)
 902        {
 903          // ----- Error log
 904          PclErrorLog(-2, "Unable to open file '$p_tarname_add' in binary read mode");
 905  
 906          // ----- Return
 907          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 908          return PclErrorCode();
 909        }
 910  
 911        // ----- Read the first 512 bytes block
 912        $v_buffer = gzread($p_tar_add, 512);
 913  
 914        // ----- Read the following blocks but not the last one
 915        if (!gzeof($p_tar_add))
 916        {
 917          TrFctMessage(__FILE__, __LINE__, 3, "More than one 512 block file");
 918          $i=1;
 919  
 920          // ----- Read new 512 block and write the already read
 921          do{
 922            // ----- Write the already read block
 923            $v_binary_data = pack("a512", "$v_buffer");
 924            if ($p_mode=="tar")
 925              fputs($p_tar, $v_binary_data);
 926            else
 927              gzputs($v_temp_tar, $v_binary_data);
 928  
 929            $i++;
 930            TrFctMessage(__FILE__, __LINE__, 3, "Reading block $i");
 931  
 932            // ----- Read next block
 933            $v_buffer = gzread($p_tar_add, 512);
 934  
 935          } while (!gzeof($p_tar_add));
 936  
 937          TrFctMessage(__FILE__, __LINE__, 3, "$i 512 bytes blocks");
 938        }
 939  
 940        // ----- Close the files
 941        gzclose($p_tar_add);
 942      }
 943  
 944      // ----- Look for uncompressed tar file
 945      else if ($p_mode=="tar")
 946      {
 947        // ----- Open the file in read mode
 948        if (($p_tar_add = @fopen($p_tarname_add, "rb")) == 0)
 949        {
 950          // ----- Error log
 951          PclErrorLog(-2, "Unable to open file '$p_tarname_add' in binary read mode");
 952  
 953          // ----- Return
 954          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
 955          return PclErrorCode();
 956        }
 957  
 958        // ----- Read the first 512 bytes block
 959        $v_buffer = fread($p_tar_add, 512);
 960  
 961        // ----- Read the following blocks but not the last one
 962        if (!feof($p_tar_add))
 963        {
 964          TrFctMessage(__FILE__, __LINE__, 3, "More than one 512 block file");
 965          $i=1;
 966  
 967          // ----- Read new 512 block and write the already read
 968          do{
 969            // ----- Write the already read block
 970            $v_binary_data = pack("a512", "$v_buffer");
 971            if ($p_mode=="tar")
 972              fputs($p_tar, $v_binary_data);
 973            else
 974              gzputs($v_temp_tar, $v_binary_data);
 975  
 976            $i++;
 977            TrFctMessage(__FILE__, __LINE__, 3, "Reading block $i");
 978  
 979            // ----- Read next block
 980            $v_buffer = fread($p_tar_add, 512);
 981  
 982          } while (!feof($p_tar_add));
 983  
 984          TrFctMessage(__FILE__, __LINE__, 3, "$i 512 bytes blocks");
 985        }
 986  
 987        // ----- Close the files
 988        fclose($p_tar_add);
 989      }
 990  
 991      // ----- Call the footer of the tar archive
 992      $v_result = PclTarHandleFooter($p_tar, $p_mode);
 993  
 994      // ----- Look for closing compressed archive
 995      if ($p_mode == "tgz")
 996      {
 997        // ----- Close the files
 998        gzclose($p_tar);
 999        gzclose($v_temp_tar);
1000  
1001        // ----- Unlink tar file
1002        if (!@unlink($p_tarname))
1003        {
1004          // ----- Error log
1005          PclErrorLog(-11, "Error while deleting archive name $p_tarname");
1006        }
1007  
1008        // ----- Rename tar file
1009        if (!@rename($v_temp_tarname, $p_tarname))
1010        {
1011          // ----- Error log
1012          PclErrorLog(-12, "Error while renaming temporary file $v_temp_tarname to archive name $p_tarname");
1013  
1014          // ----- Return
1015          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
1016          return PclErrorCode();
1017        }
1018  
1019        // ----- Return
1020        TrFctEnd(__FILE__, __LINE__, $v_result);
1021        return $v_result;
1022      }
1023  
1024      // ----- Look for closing uncompressed tar file
1025      else if ($p_mode=="tar")
1026      {
1027        // ----- Close the tarfile
1028        fclose($p_tar);
1029      }
1030  
1031      // ----- Return
1032      TrFctEnd(__FILE__, __LINE__, $v_result);
1033      return $v_result;
1034    }
1035    // --------------------------------------------------------------------------------
1036  
1037  
1038  // --------------------------------------------------------------------------------
1039  // ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
1040  // *****                                                        *****
1041  // *****       THESES FUNCTIONS MUST NOT BE USED DIRECTLY       *****
1042  // --------------------------------------------------------------------------------
1043  
1044  
1045  
1046    // --------------------------------------------------------------------------------
1047    // Function : PclTarHandleCreate()
1048    // Description :
1049    // Parameters :
1050    //   $p_tarname : Name of the tar file
1051    //   $p_list : An array containing the file or directory names to add in the tar
1052    //   $p_mode : "tar" for normal tar archive, "tgz" for gzipped tar archive
1053    // Return Values :
1054    // --------------------------------------------------------------------------------
1055    function PclTarHandleCreate($p_tarname, $p_list, $p_mode, $p_add_dir="", $p_remove_dir="")
1056    {
1057      TrFctStart(__FILE__, __LINE__, "PclTarHandleCreate", "tar=$p_tarname, list, mode=$p_mode, add_dir='$p_add_dir', remove_dir='$p_remove_dir'");
1058      $v_result=1;
1059      $v_list_detail = array();
1060  
1061      // ----- Check the parameters
1062      if (($p_tarname == "") || (($p_mode != "tar") && ($p_mode != "tgz")))
1063      {
1064        // ----- Error log
1065        if ($p_tarname == "")
1066          PclErrorLog(-3, "Invalid empty archive name");
1067        else
1068          PclErrorLog(-3, "Unknown mode '$p_mode'");
1069  
1070        // ----- Return
1071        TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
1072        return PclErrorCode();
1073      }
1074  
1075      // ----- Look for tar file
1076      if ($p_mode == "tar")
1077      {
1078        // ----- Open the tar file
1079        if (($p_tar = fopen($p_tarname, "wb")) == 0)
1080        {
1081          // ----- Error log
1082          PclErrorLog(-1, "Unable to open file [$p_tarname] in binary write mode");
1083  
1084          // ----- Return
1085          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
1086          return PclErrorCode();
1087        }
1088  
1089        // ----- Call the adding fct inside the tar
1090        if (($v_result = PclTarHandleAddList($p_tar, $p_list, $p_mode, $v_list_detail, $p_add_dir, $p_remove_dir)) == 1)
1091        {
1092          // ----- Call the footer of the tar archive
1093          $v_result = PclTarHandleFooter($p_tar, $p_mode);
1094        }
1095  
1096        // ----- Close the tarfile
1097        fclose($p_tar);
1098      }
1099      // ----- Look for tgz file
1100      else
1101      {
1102        // ----- Open the tar file
1103        if (($p_tar = @gzopen($p_tarname, "wb")) == 0)
1104        {
1105          // ----- Error log
1106          PclErrorLog(-1, "Unable to open file [$p_tarname] in binary write mode");
1107  
1108          // ----- Return
1109          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
1110          return PclErrorCode();
1111        }
1112  
1113        // ----- Call the adding fct inside the tar
1114        if (($v_result = PclTarHandleAddList($p_tar, $p_list, $p_mode, $v_list_detail, $p_add_dir, $p_remove_dir)) == 1)
1115        {
1116          // ----- Call the footer of the tar archive
1117          $v_result = PclTarHandleFooter($p_tar, $p_mode);
1118        }
1119  
1120        // ----- Close the tarfile
1121        gzclose($p_tar);
1122      }
1123  
1124      // ----- Return
1125      TrFctEnd(__FILE__, __LINE__, $v_result);
1126      return $v_result;
1127    }
1128    // --------------------------------------------------------------------------------
1129  
1130    // --------------------------------------------------------------------------------
1131    // Function : PclTarHandleAppend()
1132    // Description :
1133    // Parameters :
1134    //   $p_tarname : Name of the tar file
1135    //   $p_list : An array containing the file or directory names to add in the tar
1136    //   $p_mode : "tar" for normal tar archive, "tgz" for gzipped tar archive
1137    // Return Values :
1138    // --------------------------------------------------------------------------------
1139    function PclTarHandleAppend($p_tarname, $p_list, $p_mode, &$p_list_detail, $p_add_dir, $p_remove_dir)
1140    {
1141      TrFctStart(__FILE__, __LINE__, "PclTarHandleAppend", "tar=$p_tarname, list, mode=$p_mode");
1142      $v_result=1;
1143  
1144      // ----- Check the parameters
1145      if ($p_tarname == "")
1146      {
1147        // ----- Error log
1148        PclErrorLog(-3, "Invalid empty archive name");
1149  
1150        // ----- Return
1151        TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
1152        return PclErrorCode();
1153      }
1154  
1155      clearstatcache();
1156  
1157      // ----- Check the file size
1158      if ((!is_file($p_tarname)) ||
1159          (((($v_size = filesize($p_tarname)) % 512) != 0) && ($p_mode=="tar")))
1160      {
1161        // ----- Error log
1162        if (!is_file($p_tarname))
1163          PclErrorLog(-4, "Archive '$p_tarname' does not exist");
1164        else
1165          PclErrorLog(-6, "Archive '$p_tarname' has invalid size ".filesize($p_tarname)."(not a 512 block multiple)");
1166  
1167        // ----- Return
1168        TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
1169        return PclErrorCode();
1170      }
1171  
1172      // ----- Look for compressed archive
1173      if ($p_mode == "tgz")
1174      {
1175        // ----- Open the file in read mode
1176        if (($p_tar = @gzopen($p_tarname, "rb")) == 0)
1177        {
1178          // ----- Error log
1179          PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode");
1180  
1181          // ----- Return
1182          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
1183          return PclErrorCode();
1184        }
1185  
1186        // ----- Open a temporary file in write mode
1187        $v_temp_tarname = uniqid("pcltar-").".tmp";
1188        TrFctMessage(__FILE__, __LINE__, 2, "Creating temporary archive file $v_temp_tarname");
1189        if (($v_temp_tar = @gzopen($v_temp_tarname, "wb")) == 0)
1190        {
1191          // ----- Close tar file
1192          gzclose($p_tar);
1193  
1194          // ----- Error log
1195          PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode");
1196  
1197          // ----- Return
1198          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
1199          return PclErrorCode();
1200        }
1201  
1202        // ----- Read the first 512 bytes block
1203        $v_buffer = gzread($p_tar, 512);
1204  
1205        // ----- Read the following blocks but not the last one
1206        if (!gzeof($p_tar))
1207        {
1208          TrFctMessage(__FILE__, __LINE__, 3, "More than one 512 block file");
1209          $i=1;
1210  
1211          // ----- Read new 512 block and write the already read
1212          do{
1213            // ----- Write the already read block
1214            $v_binary_data = pack("a512", "$v_buffer");
1215            gzputs($v_temp_tar, $v_binary_data);
1216  
1217            $i++;
1218            TrFctMessage(__FILE__, __LINE__, 3, "Reading block $i");
1219  
1220            // ----- Read next block
1221            $v_buffer = gzread($p_tar, 512);
1222  
1223          } while (!gzeof($p_tar));
1224  
1225          TrFctMessage(__FILE__, __LINE__, 3, "$i 512 bytes blocks");
1226        }
1227  
1228        // ----- Call the adding fct inside the tar
1229        if (($v_result = PclTarHandleAddList($v_temp_tar, $p_list, $p_mode, $p_list_detail, $p_add_dir, $p_remove_dir)) == 1)
1230        {
1231          // ----- Call the footer of the tar archive
1232          $v_result = PclTarHandleFooter($v_temp_tar, $p_mode);
1233        }
1234  
1235        // ----- Close the files
1236        gzclose($p_tar);
1237        gzclose($v_temp_tar);
1238  
1239        // ----- Unlink tar file
1240        if (!@unlink($p_tarname))
1241        {
1242          // ----- Error log
1243          PclErrorLog(-11, "Error while deleting archive name $p_tarname");
1244        }
1245  
1246        // ----- Rename tar file
1247        if (!@rename($v_temp_tarname, $p_tarname))
1248        {
1249          // ----- Error log
1250          PclErrorLog(-12, "Error while renaming temporary file $v_temp_tarname to archive name $p_tarname");
1251  
1252          // ----- Return
1253          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
1254          return PclErrorCode();
1255        }
1256  
1257        // ----- Return
1258        TrFctEnd(__FILE__, __LINE__, $v_result);
1259        return $v_result;
1260      }
1261  
1262      // ----- Look for uncompressed tar file
1263      else if ($p_mode=="tar")
1264      {
1265        // ----- Open the tar file
1266        if (($p_tar = fopen($p_tarname, "r+b")) == 0)
1267        {
1268          // ----- Error log
1269          PclErrorLog(-1, "Unable to open file '$p_tarname' in binary write mode");
1270  
1271          // ----- Return
1272          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
1273          return PclErrorCode();
1274        }
1275  
1276        // ----- Go to the beginning of last block
1277        TrFctMessage(__FILE__, __LINE__, 4, "Position before :".($p_mode=="tar"?ftell($p_tar):gztell($p_tar)));
1278        fseek($p_tar, $v_size-512);
1279        TrFctMessage(__FILE__, __LINE__, 4, "Position after :".($p_mode=="tar"?ftell($p_tar):gztell($p_tar)));
1280  
1281        // ----- Call the adding fct inside the tar
1282        if (($v_result = PclTarHandleAddList($p_tar, $p_list, $p_mode, $p_list_detail, $p_add_dir, $p_remove_dir)) == 1)
1283        {
1284          // ----- Call the footer of the tar archive
1285          $v_result = PclTarHandleFooter($p_tar, $p_mode);
1286        }
1287  
1288        // ----- Close the tarfile
1289        fclose($p_tar);
1290      }
1291  
1292      // ----- Look for unknown type
1293      else
1294      {
1295        // ----- Error log
1296        PclErrorLog(-3, "Invalid tar mode $p_mode");
1297  
1298        // ----- Return
1299        TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
1300        return PclErrorCode();
1301      }
1302  
1303      // ----- Return
1304      TrFctEnd(__FILE__, __LINE__, $v_result);
1305      return $v_result;
1306    }
1307    // --------------------------------------------------------------------------------
1308  
1309    // --------------------------------------------------------------------------------
1310    // Function : PclTarHandleAddList()
1311    // Description :
1312    //   $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
1313    //   different from the real path of the file. This is usefull if you want to have PclTar
1314    //   running in any directory, and memorize relative path from an other directory.
1315    // Parameters :
1316    //   $p_tar : File descriptor of the tar archive
1317    //   $p_list : An array containing the file or directory names to add in the tar
1318    //   $p_mode : "tar" for normal tar archive, "tgz" for gzipped tar archive
1319    //   $p_list_detail : list of added files with their properties (specially the status field)
1320    //   $p_add_dir : Path to add in the filename path archived
1321    //   $p_remove_dir : Path to remove in the filename path archived
1322    // Return Values :
1323    // --------------------------------------------------------------------------------
1324    function PclTarHandleAddList($p_tar, $p_list, $p_mode, &$p_list_detail, $p_add_dir, $p_remove_dir)
1325    {
1326      TrFctStart(__FILE__, __LINE__, "PclTarHandleAddList", "tar='$p_tar', list, mode='$p_mode', add_dir='$p_add_dir', remove_dir='$p_remove_dir'");
1327      $v_result=1;
1328      $v_header = array();
1329  
1330      // ----- Recuperate the current number of elt in list
1331      $v_nb = sizeof($p_list_detail);
1332  
1333      // ----- Check the parameters
1334      if ($p_tar == 0)
1335      {
1336        // ----- Error log
1337        PclErrorLog(-3, "Invalid file descriptor in file ".__FILE__.", line ".__LINE__);
1338  
1339        // ----- Return
1340        TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
1341        return PclErrorCode();
1342      }
1343  
1344      // ----- Check the arguments
1345      if (sizeof($p_list) == 0)
1346      {
1347        // ----- Error log
1348        PclErrorLog(-3, "Invalid file list parameter (invalid or empty list)");
1349  
1350        // ----- Return
1351        TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
1352        return PclErrorCode();
1353      }
1354  
1355      // ----- Loop on the files
1356      for ($j=0; ($j<count($p_list)) && ($v_result==1); $j++)
1357      {
1358        // ----- Recuperate the filename
1359        $p_filename = $p_list[$j];
1360  
1361        TrFctMessage(__FILE__, __LINE__, 2, "Looking for file [$p_filename]");
1362  
1363        // ----- Skip empty file names
1364        if ($p_filename == "")
1365        {
1366          TrFctMessage(__FILE__, __LINE__, 2, "Skip empty filename");
1367          continue;
1368        }
1369  
1370        // ----- Check the filename
1371        if (!file_exists($p_filename))
1372        {
1373          // ----- Error log
1374          TrFctMessage(__FILE__, __LINE__, 2, "File '$p_filename' does not exists");
1375          PclErrorLog(-4, "File '$p_filename' does not exists");
1376  
1377          // ----- Return
1378          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
1379          return PclErrorCode();
1380        }
1381  
1382        // ----- Check the path length
1383        if (strlen($p_filename) > 99)
1384        {
1385          // ----- Error log
1386          PclErrorLog(-5, "File name is too long (max. 99) : '$p_filename'");
1387  
1388          // ----- Return
1389          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
1390          return PclErrorCode();
1391        }
1392  
1393        TrFctMessage(__FILE__, __LINE__, 4, "File position before header =".($p_mode=="tar"?ftell($p_tar):gztell($p_tar)));
1394  
1395        // ----- Add the file
1396        if (($v_result = PclTarHandleAddFile($p_tar, $p_filename, $p_mode, $v_header, $p_add_dir, $p_remove_dir)) != 1)
1397        {
1398          // ----- Return status
1399          TrFctEnd(__FILE__, __LINE__, $v_result);
1400          return $v_result;
1401        }
1402  
1403        // ----- Store the file infos
1404        $p_list_detail[$v_nb++] = $v_header;
1405  
1406        // ----- Look for directory
1407        if (is_dir($p_filename))
1408        {
1409          TrFctMessage(__FILE__, __LINE__, 2, "$p_filename is a directory");
1410  
1411          // ----- Look for path
1412          if ($p_filename != ".")
1413            $v_path = $p_filename."/";
1414          else
1415            $v_path = "";
1416  
1417          // ----- Read the directory for files and sub-directories
1418          $p_hdir = opendir($p_filename);
1419          $p_hitem = readdir($p_hdir); // '.' directory
1420          $p_hitem = readdir($p_hdir); // '..' directory
1421          while ($p_hitem = readdir($p_hdir))
1422          {
1423            // ----- Look for a file
1424            if (is_file($v_path.$p_hitem))
1425            {
1426              TrFctMessage(__FILE__, __LINE__, 4, "Add the file '".$v_path.$p_hitem."'");
1427  
1428              // ----- Add the file
1429              if (($v_result = PclTarHandleAddFile($p_tar, $v_path.$p_hitem, $p_mode, $v_header, $p_add_dir, $p_remove_dir)) != 1)
1430              {
1431                // ----- Return status
1432                TrFctEnd(__FILE__, __LINE__, $v_result);
1433                return $v_result;
1434              }
1435  
1436              // ----- Store the file infos
1437              $p_list_detail[$v_nb++] = $v_header;
1438            }
1439  
1440            // ----- Recursive call to PclTarHandleAddFile()
1441            else
1442            {
1443              TrFctMessage(__FILE__, __LINE__, 4, "'".$v_path.$p_hitem."' is a directory");
1444  
1445              // ----- Need an array as parameter
1446              $p_temp_list[0] = $v_path.$p_hitem;
1447              $v_result = PclTarHandleAddList($p_tar, $p_temp_list, $p_mode, $p_list_detail, $p_add_dir, $p_remove_dir);
1448            }
1449          }
1450  
1451          // ----- Free memory for the recursive loop
1452          unset($p_temp_list);
1453          unset($p_hdir);
1454          unset($p_hitem);
1455        }
1456        else
1457        {
1458          TrFctMessage(__FILE__, __LINE__, 4, "File position after blocks =".($p_mode=="tar"?ftell($p_tar):gztell($p_tar)));
1459        }
1460      }
1461  
1462      // ----- Return
1463      TrFctEnd(__FILE__, __LINE__, $v_result);
1464      return $v_result;
1465    }
1466    // --------------------------------------------------------------------------------
1467  
1468    // --------------------------------------------------------------------------------
1469    // Function : PclTarHandleAddFile()
1470    // Description :
1471    // Parameters :
1472    // Return Values :
1473    // --------------------------------------------------------------------------------
1474    function PclTarHandleAddFile($p_tar, $p_filename, $p_mode, &$p_header, $p_add_dir, $p_remove_dir)
1475    {
1476      TrFctStart(__FILE__, __LINE__, "PclTarHandleAddFile", "tar='$p_tar', filename='$p_filename', p_mode='$p_mode', add_dir='$p_add_dir', remove_dir='$p_remove_dir'");
1477      $v_result=1;
1478  
1479      // ----- Check the parameters
1480      if ($p_tar == 0)
1481      {
1482        // ----- Error log
1483        PclErrorLog(-3, "Invalid file descriptor in file ".__FILE__.", line ".__LINE__);
1484  
1485        // ----- Return
1486        TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
1487        return PclErrorCode();
1488      }
1489  
1490      // ----- Skip empty file names
1491      if ($p_filename == "")
1492      {
1493        // ----- Error log
1494        PclErrorLog(-3, "Invalid file list parameter (invalid or empty list)");
1495  
1496        // ----- Return
1497        TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
1498        return PclErrorCode();
1499      }
1500  
1501      // ----- Calculate the stored filename
1502      $v_stored_filename = $p_filename;
1503      if ($p_remove_dir != "")
1504      {
1505        if (substr($p_remove_dir, -1) != '/')
1506          $p_remove_dir .= "/";
1507  
1508        if ((substr($p_filename, 0, 2) == "./") || (substr($p_remove_dir, 0, 2) == "./"))
1509        {
1510          if ((substr($p_filename, 0, 2) == "./") && (substr($p_remove_dir, 0, 2) != "./"))
1511            $p_remove_dir = "./".$p_remove_dir;
1512          if ((substr($p_filename, 0, 2) != "./") && (substr($p_remove_dir, 0, 2) == "./"))
1513            $p_remove_dir = substr($p_remove_dir, 2);
1514        }
1515  
1516        if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir)
1517        {
1518          $v_stored_filename = substr($p_filename, strlen($p_remove_dir));
1519          TrFctMessage(__FILE__, __LINE__, 3, "Remove path '$p_remove_dir' in file '$p_filename' = '$v_stored_filename'");
1520        }
1521      }
1522      if ($p_add_dir != "")
1523      {
1524        if (substr($p_add_dir, -1) == "/")
1525          $v_stored_filename = $p_add_dir.$v_stored_filename;
1526        else
1527          $v_stored_filename = $p_add_dir."/".$v_stored_filename;
1528        TrFctMessage(__FILE__, __LINE__, 3, "Add path '$p_add_dir' in file '$p_filename' = '$v_stored_filename'");
1529      }
1530  
1531      // ----- Check the path length
1532      if (strlen($v_stored_filename) > 99)
1533      {
1534        // ----- Error log
1535        PclErrorLog(-5, "Stored file name is too long (max. 99) : '$v_stored_filename'");
1536  
1537        // ----- Return
1538        TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
1539        return PclErrorCode();
1540      }
1541  
1542      // ----- Look for a file
1543      if (is_file($p_filename))
1544      {
1545        // ----- Open the source file
1546        if (($v_file = fopen($p_filename, "rb")) == 0)
1547        {
1548          // ----- Error log
1549          PclErrorLog(-2, "Unable to open file '$p_filename' in binary read mode");
1550  
1551          // ----- Return
1552          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
1553          return PclErrorCode();
1554        }
1555  
1556        // ----- Call the header generation
1557        if (($v_result = PclTarHandleHeader($p_tar, $p_filename, $p_mode, $p_header, $v_stored_filename)) != 1)
1558        {
1559          // ----- Return status
1560          TrFctEnd(__FILE__, __LINE__, $v_result);
1561          return $v_result;
1562        }
1563  
1564        TrFctMessage(__FILE__, __LINE__, 4, "File position after header =".($p_mode=="tar"?ftell($p_tar):gztell($p_tar)));
1565  
1566        // ----- Read the file by 512 octets blocks
1567        $i=0;
1568        while (($v_buffer = fread($v_file, 512)) != "")
1569        {
1570          $v_binary_data = pack("a512", "$v_buffer");
1571          if ($p_mode == "tar")
1572            fputs($p_tar, $v_binary_data);
1573          else
1574            gzputs($p_tar, $v_binary_data);
1575          $i++;
1576        }
1577        TrFctMessage(__FILE__, __LINE__, 2, "$i 512 bytes blocks");
1578  
1579        // ----- Close the file
1580        fclose($v_file);
1581  
1582        TrFctMessage(__FILE__, __LINE__, 4, "File position after blocks =".($p_mode=="tar"?ftell($p_tar):gztell($p_tar)));
1583      }
1584  
1585      // ----- Look for a directory
1586      else
1587      {
1588        // ----- Call the header generation
1589        if (($v_result = PclTarHandleHeader($p_tar, $p_filename, $p_mode, $p_header, $v_stored_filename)) != 1)
1590        {
1591          // ----- Return status
1592          TrFctEnd(__FILE__, __LINE__, $v_result);
1593          return $v_result;
1594        }
1595  
1596        TrFctMessage(__FILE__, __LINE__, 4, "File position after header =".($p_mode=="tar"?ftell($p_tar):gztell($p_tar)));
1597      }
1598  
1599      // ----- Return
1600      TrFctEnd(__FILE__, __LINE__, $v_result);
1601      return $v_result;
1602    }
1603    // --------------------------------------------------------------------------------
1604  
1605    // --------------------------------------------------------------------------------
1606    // Function : PclTarHandleHeader()
1607    // Description :
1608    //   This function creates in the TAR $p_tar, the TAR header for the file
1609    //   $p_filename.
1610    //
1611    //   1. The informations needed to compose the header are recuperated and formatted
1612    //   2. Two binary strings are composed for the first part of the header, before
1613    //      and after checksum field.
1614    //   3. The checksum is calculated from the two binary strings
1615    //   4. The header is write in the tar file (first binary string, binary string
1616    //      for checksum and last binary string).
1617    // Parameters :
1618    //   $p_tar : a valid file descriptor, opened in write mode,
1619    //   $p_filename : The name of the file the header is for,
1620    //   $p_mode : The mode of the archive ("tar" or "tgz").
1621    //   $p_header : A pointer to a array where will be set the file properties
1622    // Return Values :
1623    // --------------------------------------------------------------------------------
1624    function PclTarHandleHeader($p_tar, $p_filename, $p_mode, &$p_header, $p_stored_filename)
1625    {
1626      TrFctStart(__FILE__, __LINE__, "PclTarHandleHeader", "tar=$p_tar, file='$p_filename', mode='$p_mode', stored_filename='$p_stored_filename'");
1627      $v_result=1;
1628  
1629      // ----- Check the parameters
1630      if (($p_tar == 0) || ($p_filename == ""))
1631      {
1632        // ----- Error log
1633        PclErrorLog(-3, "Invalid file descriptor in file ".__FILE__.", line ".__LINE__);
1634  
1635        // ----- Return
1636        TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
1637        return PclErrorCode();
1638      }
1639  
1640      // ----- Filename (reduce the path of stored name)
1641      if ($p_stored_filename == "")
1642        $p_stored_filename = $p_filename;
1643      $v_reduce_filename = PclTarHandlePathReduction($p_stored_filename);
1644      TrFctMessage(__FILE__, __LINE__, 2, "Filename (reduced) '$v_reduce_filename', strlen ".strlen($v_reduce_filename));
1645  
1646      // ----- Get file info
1647      $v_info = stat($p_filename);
1648      $v_uid = sprintf("%6s ", DecOct($v_info[4]));
1649      $v_gid = sprintf("%6s ", DecOct($v_info[5]));
1650      TrFctMessage(__FILE__, __LINE__, 3, "uid=$v_uid, gid=$v_gid");
1651      $v_perms = sprintf("%6s ", DecOct(fileperms($p_filename)));
1652      TrFctMessage(__FILE__, __LINE__, 3, "file permissions $v_perms");
1653  
1654      // ----- File mtime
1655      $v_mtime_data = filemtime($p_filename);
1656      TrFctMessage(__FILE__, __LINE__, 2, "File mtime : $v_mtime_data");
1657      $v_mtime = sprintf("%11s", DecOct($v_mtime_data));
1658  
1659      // ----- File typeflag
1660      // '0' or '\0' is the code for regular file
1661      // '5' is directory
1662      if (is_dir($p_filename))
1663      {
1664        $v_typeflag = "5";
1665        $v_size = 0;
1666      }
1667      else
1668      {
1669        $v_typeflag = "";
1670  
1671        // ----- Get the file size
1672        clearstatcache();
1673        $v_size = filesize($p_filename);
1674      }
1675  
1676      TrFctMessage(__FILE__, __LINE__, 2, "File size : $v_size");
1677      $v_size = sprintf("%11s ", DecOct($v_size));
1678  
1679      TrFctMessage(__FILE__, __LINE__, 2, "File typeflag : $v_typeflag");
1680  
1681      // ----- Linkname
1682      $v_linkname = "";
1683  
1684      // ----- Magic
1685      $v_magic = "";
1686  
1687      // ----- Version
1688      $v_version = "";
1689  
1690      // ----- uname
1691      $v_uname = "";
1692  
1693      // ----- gname
1694      $v_gname = "";
1695  
1696      // ----- devmajor
1697      $v_devmajor = "";
1698  
1699      // ----- devminor
1700      $v_devminor = "";
1701  
1702      // ----- prefix
1703      $v_prefix = "";
1704  
1705      // ----- Compose the binary string of the header in two parts arround the checksum position
1706      $v_binary_data_first = pack("a100a8a8a8a12A12", $v_reduce_filename, $v_perms, $v_uid, $v_gid, $v_size, $v_mtime);
1707      $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12", $v_typeflag, $v_linkname, $v_magic, $v_version, $v_uname, $v_gname, $v_devmajor, $v_devminor, $v_prefix, "");
1708  
1709      // ----- Calculate the checksum
1710      $v_checksum = 0;
1711      // ..... First part of the header
1712      for ($i=0; $i<148; $i++)
1713      {
1714        $v_checksum += ord(substr($v_binary_data_first,$i,1));
1715      }
1716      // ..... Ignore the checksum value and replace it by ' ' (space)
1717      for ($i=148; $i<156; $i++)
1718      {
1719        $v_checksum += ord(' ');
1720      }
1721      // ..... Last part of the header
1722      for ($i=156, $j=0; $i<512; $i++, $j++)
1723      {
1724        $v_checksum += ord(substr($v_binary_data_last,$j,1));
1725      }
1726      TrFctMessage(__FILE__, __LINE__, 3, "Calculated checksum : $v_checksum");
1727  
1728      // ----- Write the first 148 bytes of the header in the archive
1729      if ($p_mode == "tar")
1730        fputs($p_tar, $v_binary_data_first, 148);
1731      else
1732        gzputs($p_tar, $v_binary_data_first, 148);
1733  
1734      // ----- Write the calculated checksum
1735      $v_checksum = sprintf("%6s ", DecOct($v_checksum));
1736      $v_binary_data = pack("a8", $v_checksum);
1737      if ($p_mode == "tar")
1738        fputs($p_tar, $v_binary_data, 8);
1739      else
1740        gzputs($p_tar, $v_binary_data, 8);
1741  
1742      // ----- Write the last 356 bytes of the header in the archive
1743      if ($p_mode == "tar")
1744        fputs($p_tar, $v_binary_data_last, 356);
1745      else
1746        gzputs($p_tar, $v_binary_data_last, 356);
1747  
1748      // ----- Set the properties in the header "structure"
1749      $p_header[filename] = $v_reduce_filename;
1750      $p_header[mode] = $v_perms;
1751      $p_header[uid] = $v_uid;
1752      $p_header[gid] = $v_gid;
1753      $p_header[size] = $v_size;
1754      $p_header[mtime] = $v_mtime;
1755      $p_header[typeflag] = $v_typeflag;
1756      $p_header[status] = "added";
1757  
1758      // ----- Return
1759      TrFctEnd(__FILE__, __LINE__, $v_result);
1760      return $v_result;
1761    }
1762    // --------------------------------------------------------------------------------
1763  
1764    // --------------------------------------------------------------------------------
1765    // Function : PclTarHandleFooter()
1766    // Description :
1767    // Parameters :
1768    // Return Values :
1769    // --------------------------------------------------------------------------------
1770    function PclTarHandleFooter($p_tar, $p_mode)
1771    {
1772      TrFctStart(__FILE__, __LINE__, "PclTarHandleFooter", "tar='$p_tar', p_mode=$p_mode");
1773      $v_result=1;
1774  
1775      // ----- Write the last 0 filled block for end of archive
1776      $v_binary_data = pack("a512", "");
1777      if ($p_mode == "tar")
1778        fputs($p_tar, $v_binary_data);
1779      else
1780        gzputs($p_tar, $v_binary_data);
1781  
1782      // ----- Return
1783      TrFctEnd(__FILE__, __LINE__, $v_result);
1784      return $v_result;
1785    }
1786    // --------------------------------------------------------------------------------
1787  
1788    // --------------------------------------------------------------------------------
1789    // Function : PclTarHandleExtract()
1790    // Description :
1791    // Parameters :
1792    //   $p_tarname : Filename of the tar (or tgz) archive
1793    //   $p_file_list : An array which contains the list of files to extract, this
1794    //                  array may be empty when $p_mode is 'complete'
1795    //   $p_list_detail : An array where will be placed the properties of  each extracted/listed file
1796    //   $p_mode : 'complete' will extract all files from the archive,
1797    //             'partial' will look for files in $p_file_list
1798    //             'list' will only list the files from the archive without any extract
1799    //   $p_path : Path to add while writing the extracted files
1800    //   $p_tar_mode : 'tar' for GNU TAR archive, 'tgz' for compressed archive
1801    //   $p_remove_path : Path to remove (from the file memorized path) while writing the
1802    //                    extracted files. If the path does not match the file path,
1803    //                    the file is extracted with its memorized path.
1804    //                    $p_remove_path does not apply to 'list' mode.
1805    //                    $p_path and $p_remove_path are commulative.
1806    // Return Values :
1807    // --------------------------------------------------------------------------------
1808    function PclTarHandleExtract($p_tarname, $p_file_list, &$p_list_detail, $p_mode, $p_path, $p_tar_mode, $p_remove_path)
1809    {
1810      TrFctStart(__FILE__, __LINE__, "PclTarHandleExtract", "archive='$p_tarname', list, mode=$p_mode, path=$p_path, tar_mode=$p_tar_mode, remove_path='$p_remove_path'");
1811      $v_result=1;
1812      $v_nb = 0;
1813      $v_extract_all = TRUE;
1814      $v_listing = FALSE;
1815  
1816      // ----- Check the path
1817      /*
1818      if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../")))
1819        $p_path = "./".$p_path;
1820      */
1821  
1822      $isWin = (substr(PHP_OS, 0, 3) == 'WIN');
1823  
1824      if(!$isWin)
1825      {
1826          if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../")))
1827            $p_path = "./".$p_path;
1828      }
1829      // ----- Look for path to remove format (should end by /)
1830      if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
1831      {
1832        $p_remove_path .= '/';
1833      }
1834      $p_remove_path_size = strlen($p_remove_path);
1835  
1836      // ----- Study the mode
1837      switch ($p_mode) {
1838        case "complete" :
1839          // ----- Flag extract of all files
1840          $v_extract_all = TRUE;
1841          $v_listing = FALSE;
1842        break;
1843        case "partial" :
1844            // ----- Flag extract of specific files
1845            $v_extract_all = FALSE;
1846            $v_listing = FALSE;
1847        break;
1848        case "list" :
1849            // ----- Flag list of all files
1850            $v_extract_all = FALSE;
1851            $v_listing = TRUE;
1852        break;
1853        default :
1854          // ----- Error log
1855          PclErrorLog(-3, "Invalid extract mode ($p_mode)");
1856  
1857          // ----- Return
1858          TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
1859          return PclErrorCode();
1860      }
1861  
1862      // ----- Open the tar file
1863      if ($p_tar_mode == "tar")
1864      {
1865        TrFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
1866        $v_tar = fopen($p_tarname, "rb");
1867      }
1868      else
1869      {
1870        TrFctMessage(__FILE__, __LINE__, 3, "Open file in gzip binary read mode");
1871        $v_tar = @gzopen($p_tarname, "rb");
1872      }
1873  
1874      // ----- Check that the archive is open
1875      if ($v_tar == 0)
1876      {
1877        // ----- Error log
1878        PclErrorLog(-2, "Unable to open archive '$p_tarname' in binary read mode");
1879  
1880        // ----- Return
1881        TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
1882        return PclErrorCode();
1883      }
1884  
1885      // ----- Read the blocks
1886      While (!($v_end_of_file = ($p_tar_mode == "tar"?feof($v_tar):gzeof($v_tar))))
1887      {
1888        TrFctMessage(__FILE__, __LINE__, 3, "Looking for next header ...");
1889  
1890        // ----- Clear cache of file infos
1891        clearstatcache();
1892  
1893        // ----- Reset extract tag
1894        $v_extract_file = FALSE;
1895        $v_extraction_stopped = 0;
1896  
1897        // ----- Read the 512 bytes header
1898        if ($p_tar_mode == "tar")
1899          $v_binary_data = fread($v_tar, 512);
1900        else
1901          $v_binary_data = gzread($v_tar, 512);
1902  
1903        // ----- Read the header properties
1904        if (($v_result = PclTarHandleReadHeader($v_binary_data, $v_header)) != 1)
1905        {
1906          // ----- Close the archive file
1907          if ($p_tar_mode == "tar")
1908            fclose($v_tar);
1909          else
1910            gzclose($v_tar);
1911  
1912          // ----- Return
1913          TrFctEnd(__FILE__, __LINE__, $v_result);
1914          return $v_result;
1915        }
1916  
1917        // ----- Look for empty blocks to skip
1918        if ($v_header["filename"] == "")
1919        {
1920          TrFctMessage(__FILE__, __LINE__, 2, "Empty block found. End of archive ?");
1921          continue;
1922        }
1923  
1924        TrFctMessage(__FILE__, __LINE__, 2, "Found file '" . $v_header["filename"] . "', size '$v_header[size]'");
1925  
1926        // ----- Look for partial extract
1927        if ((!$v_extract_all) && (is_array($p_file_list)))
1928        {
1929          TrFctMessage(__FILE__, __LINE__, 2, "Look if the file '$v_header[filename]' need to be extracted");
1930  
1931          // ----- By default no unzip if the file is not found
1932          $v_extract_file = FALSE;
1933  
1934          // ----- Look into the file list
1935          for ($i=0; $i<sizeof($p_file_list); $i++)
1936          {
1937            TrFctMessage(__FILE__, __LINE__, 2, "Compare archived file '$v_header[filename]' from asked list file '".$p_file_list[$i]."'");
1938  
1939            // ----- Look if it is a directory
1940            if (substr($p_file_list[$i], -1) == "/")
1941            {
1942              TrFctMessage(__FILE__, __LINE__, 3, "Compare file '$v_header[filename]' with directory '$p_file_list[$i]'");
1943  
1944              // ----- Look if the directory is in the filename path
1945              if ((strlen($v_header["filename"]) > strlen($p_file_list[$i])) && (substr($v_header["filename"], 0, strlen($p_file_list[$i])) == $p_file_list[$i]))
1946              {
1947                // ----- The file is in the directory, so extract it
1948                TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' is in directory '$p_file_list[$i]' : extract it");
1949                $v_extract_file = TRUE;
1950  
1951                // ----- End of loop
1952                break;
1953              }
1954            }
1955  
1956            // ----- It is a file, so compare the file names
1957            else if ($p_file_list[$i] == $v_header["filename"])
1958            {
1959              // ----- File found
1960              TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' should be extracted");
1961              $v_extract_file = TRUE;
1962  
1963              // ----- End of loop
1964              break;
1965            }
1966          }
1967  
1968          // ----- Trace
1969          if (!$v_extract_file)
1970          {
1971            TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' should not be extracted");
1972          }
1973        }
1974        else
1975        {
1976          // ----- All files need to be extracted
1977          $v_extract_file = TRUE;
1978        }
1979  
1980        // ----- Look if this file need to be extracted
1981        if (($v_extract_file) && (!$v_listing))
1982        {
1983          // ----- Look for path to remove
1984          if (($p_remove_path != "")
1985              && (substr($v_header["filename"], 0, $p_remove_path_size) == $p_remove_path))
1986          {
1987            TrFctMessage(__FILE__, __LINE__, 3, "Found path '$p_remove_path' to remove in file '$v_header[filename]'");
1988            // ----- Remove the path
1989            $v_header["filename"] = substr($v_header["filename"], $p_remove_path_size);
1990            TrFctMessage(__FILE__, __LINE__, 3, "Reslting file is '$v_header[filename]'");
1991          }
1992  
1993          // ----- Add the path to the file
1994          if (($p_path != "./") && ($p_path != "/"))
1995          {
1996            // ----- Look for the path end '/'
1997            while (substr($p_path, -1) == "/")
1998            {
1999              TrFctMessage(__FILE__, __LINE__, 3, "Destination path [$p_path] ends by '/'");
2000              $p_path = substr($p_path, 0, strlen($p_path)-1);
2001              TrFctMessage(__FILE__, __LINE__, 3, "Modified to [$p_path]");
2002            }
2003  
2004            // ----- Add the path
2005            if (substr($v_header["filename"], 0, 1) == "/")
2006                $v_header["filename"] = $p_path.$v_header["filename"];
2007            else
2008              $v_header["filename"] = $p_path."/".$v_header["filename"];
2009          }
2010  
2011          // ----- Trace
2012          TrFctMessage(__FILE__, __LINE__, 2, "Extracting file (with path) '$v_header[filename]', size '$v_header[size]'");
2013  
2014          // ----- Check that the file does not exists
2015          if (file_exists($v_header["filename"]))
2016          {
2017            TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' already exists");
2018  
2019            // ----- Look if file is a directory
2020            if (is_dir($v_header["filename"]))
2021            {
2022              TrFctMessage(__FILE__, __LINE__, 2, "Existing file '$v_header[filename]' is a directory");
2023  
2024              // ----- Change the file status
2025              $v_header["status"] = "already_a_directory";
2026  
2027              // ----- Skip the extract
2028              $v_extraction_stopped = 1;
2029              $v_extract_file = 0;
2030            }
2031            // ----- Look if file is write protected
2032            else if (!is_writeable($v_header["filename"]))
2033            {
2034              TrFctMessage(__FILE__, __LINE__, 2, "Existing file '$v_header[filename]' is write protected");
2035  
2036              // ----- Change the file status
2037              $v_header["status"] = "write_protected";
2038  
2039              // ----- Skip the extract
2040              $v_extraction_stopped = 1;
2041              $v_extract_file = 0;
2042            }
2043            // ----- Look if the extracted file is older
2044            else if (filemtime($v_header["filename"]) > $v_header["mtime"])
2045            {
2046              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]).")");
2047  
2048              // ----- Change the file status
2049              $v_header["status"] = "newer_exist";
2050  
2051              // ----- Skip the extract
2052              $v_extraction_stopped = 1;
2053              $v_extract_file = 0;
2054            }
2055          }
2056  
2057          // ----- Check the directory availability and create it if necessary
2058          else
2059          {
2060            if ($v_header["typeflag"]=="5")
2061              $v_dir_to_check = $v_header["filename"];
2062            else if (!strstr($v_header["filename"], "/"))
2063              $v_dir_to_check = "";
2064            else
2065              $v_dir_to_check = dirname($v_header["filename"]);
2066  
2067            if (($v_result = PclTarHandlerDirCheck($v_dir_to_check)) != 1)
2068            {
2069              TrFctMessage(__FILE__, __LINE__, 2, "Unable to create path for '$v_header[filename]'");
2070  
2071              // ----- Change the file status
2072              $v_header["status"] = "path_creation_fail";
2073  
2074              // ----- Skip the extract
2075              $v_extraction_stopped = 1;
2076              $v_extract_file = 0;
2077            }
2078          }
2079  
2080          // ----- Do the extraction
2081          if (($v_extract_file) && ($v_header["typeflag"]!="5"))
2082          {
2083            // ----- Open the destination file in write mode
2084            if (($v_dest_file = @fopen($v_header["filename"], "wb")) == 0)
2085            {
2086              TrFctMessage(__FILE__, __LINE__, 2, "Error while opening '$v_header[filename]' in write binary mode");
2087  
2088              // ----- Change the file status
2089              $v_header["status"] = "write_error";
2090  
2091              // ----- Jump to next file
2092              TrFctMessage(__FILE__, __LINE__, 2, "Jump to next file");
2093              if ($p_tar_mode == "tar")
2094                fseek($v_tar, ftell($v_tar)+(ceil(($v_header[size]/512))*512));
2095              else
2096                gzseek($v_tar, gztell($v_tar)+(ceil(($v_header[size]/512))*512));
2097            }
2098            else
2099            {
2100              TrFctMessage(__FILE__, __LINE__, 2, "Start extraction of '$v_header[filename]'");
2101  
2102              // ----- Read data
2103              $n = floor($v_header["size"]/512);
2104              for ($i=0; $i<$n; $i++)
2105              {
2106                TrFctMessage(__FILE__, __LINE__, 3, "Read complete 512 bytes block number ".($i+1));
2107                if ($p_tar_mode == "tar")
2108                  $v_content = fread($v_tar, 512);
2109                else
2110                  $v_content = gzread($v_tar, 512);
2111                fwrite($v_dest_file, $v_content, 512);
2112              }
2113              if (($v_header["size"] % 512) != 0)
2114              {
2115                TrFctMessage(__FILE__, __LINE__, 3, "Read last ".($v_header["size"] % 512)." bytes in a 512 block");
2116                if ($p_tar_mode == "tar")
2117                  $v_content = fread($v_tar, 512);
2118                else
2119                  $v_content = gzread($v_tar, 512);
2120                fwrite($v_dest_file, $v_content, ($v_header["size"] % 512));
2121              }
2122  
2123              // ----- Close the destination file
2124              fclose($v_dest_file);
2125  
2126              // ----- Change the file mode, mtime
2127              touch($v_header["filename"], $v_header["mtime"]);
2128              //chmod($v_header[filename], DecOct($v_header[mode]));
2129            }
2130  
2131            // ----- Check the file size
2132            clearstatcache();
2133            if (filesize($v_header["filename"]) != $v_header["size"])
2134            {
2135              // ----- Close the archive file
2136              if ($p_tar_mode == "tar")
2137                fclose($v_tar);
2138              else
2139                gzclose($v_tar);
2140  
2141              // ----- Error log
2142              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.");
2143  
2144              // ----- Return
2145              TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
2146              return PclErrorCode();
2147            }
2148  
2149            // ----- Trace
2150            TrFctMessage(__FILE__, __LINE__, 2, "Extraction done");
2151          }
2152  
2153          else
2154          {
2155            TrFctMessage(__FILE__, __LINE__, 2, "Extraction of file '$v_header[filename]' skipped.");
2156  
2157            // ----- Jump to next file
2158            TrFctMessage(__FILE__, __LINE__, 2, "Jump to next file");
2159            if ($p_tar_mode == "tar")
2160              fseek($v_tar, ftell($v_tar)+(ceil(($v_header["size"]/512))*512));
2161            else
2162              gzseek($v_tar, gztell($v_tar)+(ceil(($v_header["size"]/512))*512));
2163          }
2164        }
2165  
2166        // ----- Look for file that is not to be unzipped
2167        else
2168        {
2169          // ----- Trace
2170          TrFctMessage(__FILE__, __LINE__, 2, "Jump file '$v_header[filename]'");
2171          TrFctMessage(__FILE__, __LINE__, 4, "Position avant jump [".($p_tar_mode=="tar"?ftell($v_tar):gztell($v_tar))."]");
2172  
2173          // ----- Jump to next file
2174          if ($p_tar_mode == "tar")
2175            fseek($v_tar, ($p_tar_mode=="tar"?ftell($v_tar):gztell($v_tar))+(ceil(($v_header[size]/512))*512));
2176          else
2177            gzseek($v_tar, gztell($v_tar)+(ceil(($v_header[size]/512))*512));
2178  
2179          TrFctMessage(__FILE__, __LINE__, 4, "Position après jump [".($p_tar_mode=="tar"?ftell($v_tar):gztell($v_tar))."]");
2180        }
2181  
2182        if ($p_tar_mode == "tar")
2183          $v_end_of_file = feof($v_tar);
2184        else
2185          $v_end_of_file = gzeof($v_tar);
2186  
2187        // ----- File name and properties are logged if listing mode or file is extracted
2188        if ($v_listing || $v_extract_file || $v_extraction_stopped)
2189        {
2190          TrFctMessage(__FILE__, __LINE__, 2, "Memorize info about file '$v_header[filename]'");
2191  
2192          // ----- Log extracted files
2193          if (($v_file_dir = dirname($v_header["filename"])) == $v_header["filename"])
2194            $v_file_dir = "";
2195          if ((substr($v_header["filename"], 0, 1) == "/") && ($v_file_dir == ""))
2196            $v_file_dir = "/";
2197  
2198          // ----- Add the array describing the file into the list
2199          $p_list_detail[$v_nb] = $v_header;
2200  
2201          // ----- Increment
2202          $v_nb++;
2203        }
2204      }
2205  
2206      // ----- Close the tarfile
2207      if ($p_tar_mode == "tar")
2208        fclose($v_tar);
2209      else
2210        gzclose($v_tar);
2211  
2212      // ----- Return
2213      TrFctEnd(__FILE__, __LINE__, $v_result);
2214      return $v_result;
2215    }
2216    // --------------------------------------------------------------------------------
2217  
2218    // --------------------------------------------------------------------------------
2219    // Function : PclTarHandleExtractByIndexList()
2220    // Description :
2221    //   Extract the files which are at the indexes specified. If the 'file' at the
2222    //   index is a directory, the directory only is created, not all the files stored
2223    //   for that directory.
2224    // Parameters :
2225    //   $p_index_string : String of indexes of files to extract. The form of the
2226    //                     string is "0,4-6,8-12" with only numbers and '-' for
2227    //                     for range, and ',' to separate ranges. No spaces or ';'
2228    //                     are allowed.
2229    // Return Values :
2230    // --------------------------------------------------------------------------------
2231    function PclTarHandleExtractByIndexList($p_tarname, $p_index_string, &$p_list_detail, $p_path, $p_remove_path, $p_tar_mode)
2232    {
2233      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");
2234      $v_result=1;
2235      $v_nb = 0;
2236  
2237      // ----- TBC : I should check the string by a regexp
2238  
2239      // ----- Check the path
2240      if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../") && (substr($p_path, 0, 2) != "./")))
2241        $p_path = "./".$p_path;
2242  
2243      // ----- Look for path to remove format (should end by /)
2244      if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
2245      {
2246        $p_remove_path .= '/';
2247      }
2248      $p_remove_path_size = strlen($p_remove_path);
2249  
2250      // ----- Open the tar file
2251      if ($p_tar_mode == "tar")
2252      {
2253        TrFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
2254        $v_tar = @fopen($p_tarname, "rb");
2255      }
2256      else
2257      {
2258        TrFctMessage(__FILE__, __LINE__, 3, "Open file in gzip binary read mode");
2259        $v_tar = @gzopen($p_tarname, "rb");
2260      }
2261  
2262      // ----- Check that the archive is open
2263      if ($v_tar == 0)
2264      {
2265        // ----- Error log
2266        PclErrorLog(-2, "Unable to open archive '$p_tarname' in binary read mode");
2267  
2268        // ----- Return
2269        TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString());
2270        return PclErrorCode();
2271      }
2272  
2273      // ----- Manipulate the index list
2274      $v_list = explode(",", $p_index_string);
2275      sort($v_list);
2276  
2277      // ----- Loop on the index list
2278      $v_index=0;
2279      for ($i=0; ($i<sizeof($v_list)) && ($v_result); $i++)
2280      {
2281        TrFctMessage(__FILE__, __LINE__, 3, "Looking for index part '$v_list[$i]'");
2282  
2283        // ----- Extract range
2284        $v_index_list = explode("-", $v_list[$i]);
2285        $v_size_index_list = sizeof($v_index_list);
2286        if ($v_size_index_list == 1)
2287        {
2288          TrFctMessage(__FILE__, __LINE__, 3, "Only one index '$v_index_list[0]'");
2289  
2290          // ----- Do the extraction
2291          $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);
2292        }
2293        else if ($v_size_index_list == 2)
2294        {
2295          TrFctMessage(__FILE__, __LINE__, 3, "Two indexes '$v_index_list[0]' and '$v_index_list[1]'");
2296  
2297          // ----- Do the extraction
2298          $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);
2299        }
2300      }
2301  
2302      // ----- Close the tarfile
2303      if ($p_tar_mode == "tar")
2304        fclose($v_tar);
2305      else
2306        gzclose($v_tar);
2307  
2308      // ----- Return
2309      TrFctEnd(__FILE__, __LINE__, $v_result);
2310      return $v_result;
2311    }
2312    // --------------------------------------------------------------------------------
2313  
2314    // --------------------------------------------------------------------------------
2315    // Function : PclTarHandleExtractByIndex()
2316    // Description :
2317    // Parameters :
2318    // Return Values :
2319    // --------------------------------------------------------------------------------
2320    function PclTarHandleExtractByIndex($p_tar, &$p_index_current, $p_index_start, $p_index_stop, &$p_list_detail, $p_path, $p_remove_path, $p_tar_mode)
2321    {
2322      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=