Verzeichnisstruktur phpBB-3.0.0


Veröffentlicht
12.12.2007

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

functions_compress.php

Zuletzt modifiziert: 09.10.2024, 12:50 - Dateigröße: 17.26 KiB


 001  <?php
 002  /**
 003  *
 004  * @package phpBB3
 005  * @version $Id$
 006  * @copyright (c) 2005 phpBB Group
 007  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 008  *
 009  */
 010   
 011  /**
 012  * @ignore
 013  */
 014  if (!defined('IN_PHPBB'))
 015  {
 016      exit;
 017  }
 018   
 019  /**
 020  * Class for handling archives (compression/decompression)
 021  * @package phpBB3
 022  */
 023  class compress
 024  {
 025      var $fp = 0;
 026   
 027      /**
 028      * Add file to archive
 029      */
 030      function add_file($src, $src_rm_prefix = '', $src_add_prefix = '', $skip_files = '')
 031      {
 032          global $phpbb_root_path;
 033   
 034          $skip_files = explode(',', $skip_files);
 035   
 036          // Remove rm prefix from src path
 037          $src_path = ($src_rm_prefix) ? preg_replace('#^(' . preg_quote($src_rm_prefix, '#') . ')#', '', $src) : $src;
 038          // Add src prefix
 039          $src_path = ($src_add_prefix) ? ($src_add_prefix . ((substr($src_add_prefix, -1) != '/') ? '/' : '') . $src_path) : $src_path;
 040          // Remove initial "/" if present
 041          $src_path = (substr($src_path, 0, 1) == '/') ? substr($src_path, 1) : $src_path;
 042   
 043          if (is_file($phpbb_root_path . $src))
 044          {
 045              $this->data($src_path, file_get_contents("$phpbb_root_path$src"), false, stat("$phpbb_root_path$src"));
 046          }
 047          else if (is_dir($phpbb_root_path . $src))
 048          {
 049              // Clean up path, add closing / if not present
 050              $src_path = ($src_path && substr($src_path, -1) != '/') ? $src_path . '/' : $src_path;
 051   
 052              $filelist = array();
 053              $filelist = filelist("$phpbb_root_path$src", '', '*');
 054              krsort($filelist);
 055   
 056              if ($src_path)
 057              {
 058                  $this->data($src_path, '', true, stat("$phpbb_root_path$src"));
 059              }
 060   
 061              foreach ($filelist as $path => $file_ary)
 062              {
 063                  if ($path)
 064                  {
 065                      // Same as for src_path
 066                      $path = (substr($path, 0, 1) == '/') ? substr($path, 1) : $path;
 067                      $path = ($path && substr($path, -1) != '/') ? $path . '/' : $path;
 068   
 069                      $this->data("$src_path$path", '', true, stat("$phpbb_root_path$src$path"));
 070                  }
 071   
 072                  foreach ($file_ary as $file)
 073                  {
 074                      if (in_array($path . $file, $skip_files))
 075                      {
 076                          continue;
 077                      }
 078   
 079                      $this->data("$src_path$path$file", file_get_contents("$phpbb_root_path$src$path$file"), false, stat("$phpbb_root_path$src$path$file"));
 080                  }
 081              }
 082          }
 083   
 084          return true;
 085      }
 086   
 087      /**
 088      * Add custom file (the filepath will not be adjusted)
 089      */
 090      function add_custom_file($src, $filename)
 091      {
 092          $this->data($filename, file_get_contents($src), false, stat($src));
 093          return true;
 094      }
 095   
 096      /**
 097      * Add file data
 098      */
 099      function add_data($src, $name)
 100      {
 101          $stat = array();
 102          $stat[2] = 436; //384
 103          $stat[4] = $stat[5] = 0;
 104          $stat[7] = strlen($src);
 105          $stat[9] = time();
 106          $this->data($name, $src, false, $stat);
 107          return true;
 108      }
 109   
 110      /**
 111      * Return available methods
 112      */
 113      function methods()
 114      {
 115          $methods = array('.tar');
 116          $available_methods = array('.tar.gz' => 'zlib', '.tar.bz2' => 'bz2', '.zip' => 'zlib');
 117   
 118          foreach ($available_methods as $type => $module)
 119          {
 120              if (!@extension_loaded($module))
 121              {
 122                  continue;
 123              }
 124              $methods[] = $type;
 125          }
 126   
 127          return $methods;
 128      }
 129  }
 130   
 131  /**
 132  * Zip creation class from phpMyAdmin 2.3.0 (c) Tobias Ratschiller, Olivier M�ller, Lo�c Chapeaux,
 133  * Marc Delisle, http://www.phpmyadmin.net/
 134  *
 135  * Zip extraction function by Alexandre Tedeschi, alexandrebr at gmail dot com
 136  *
 137  * Modified extensively by psoTFX and DavidMJ, (c) phpBB Group, 2003
 138  *
 139  * Based on work by Eric Mueller and Denis125
 140  * Official ZIP file format: http://www.pkware.com/appnote.txt
 141  *
 142  * @package phpBB3
 143  */
 144  class compress_zip extends compress
 145  {
 146      var $datasec = array();
 147      var $ctrl_dir = array();
 148      var $eof_cdh = "\x50\x4b\x05\x06\x00\x00\x00\x00";
 149   
 150      var $old_offset = 0;
 151      var $datasec_len = 0;
 152   
 153      /**
 154      * Constructor
 155      */
 156      function compress_zip($mode, $file)
 157      {
 158          return $this->fp = @fopen($file, $mode . 'b');
 159      }
 160   
 161      /**
 162      * Convert unix to dos time
 163      */
 164      function unix_to_dos_time($time)
 165      {
 166          $timearray = (!$time) ? getdate() : getdate($time);
 167   
 168          if ($timearray['year'] < 1980)
 169          {
 170              $timearray['year'] = 1980;
 171              $timearray['mon'] = $timearray['mday'] = 1;
 172              $timearray['hours'] = $timearray['minutes'] = $timearray['seconds'] = 0;
 173          }
 174   
 175          return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) | ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1);
 176      }
 177   
 178      /**
 179      * Extract archive
 180      */
 181      function extract($dst)
 182      {        
 183          // Loop the file, looking for files and folders
 184          $dd_try = false;
 185          rewind($this->fp);
 186   
 187          while (!feof($this->fp))
 188          {
 189              // Check if the signature is valid...
 190              $signature = fread($this->fp, 4);
 191   
 192              switch ($signature)
 193              {
 194                  // 'Local File Header'
 195                  case "\x50\x4b\x03\x04":
 196                      // Lets get everything we need.
 197                      // We don't store the version needed to extract, the general purpose bit flag or the date and time fields
 198                      $data = unpack("@4/vc_method/@10/Vcrc/Vc_size/Vuc_size/vname_len/vextra_field", fread($this->fp, 26));
 199                      $file_name = fread($this->fp, $data['name_len']); // filename
 200   
 201                      if ($data['extra_field'])
 202                      {
 203                          fread($this->fp, $data['extra_field']); // extra field
 204                      }
 205   
 206                      $target_filename = "$dst$file_name";
 207   
 208                      if (!$data['uc_size'] && !$data['crc'] && substr($file_name, -1, 1) == '/')
 209                      {
 210                          if (!is_dir($target_filename))
 211                          {
 212                              $str = '';
 213                              $folders = explode('/', $target_filename);
 214   
 215                              // Create and folders and subfolders if they do not exist
 216                              foreach ($folders as $folder)
 217                              {
 218                                  $str = (!empty($str)) ? $str . '/' . $folder : $folder;
 219                                  if (!is_dir($str))
 220                                  {
 221                                      if (!@mkdir($str, 0777))
 222                                      {
 223                                          trigger_error("Could not create directory $folder");
 224                                      }
 225                                      @chmod($str, 0777);
 226                                  }
 227                              }
 228                          }
 229                          // This is a directory, we are not writting files
 230                          continue;
 231                      }
 232                      else
 233                      {
 234                          // Some archivers are punks, they don't don't include folders in their archives!
 235                          $str = '';
 236                          $folders = explode('/', pathinfo($target_filename, PATHINFO_DIRNAME));
 237   
 238                          // Create and folders and subfolders if they do not exist
 239                          foreach ($folders as $folder)
 240                          {
 241                              $str = (!empty($str)) ? $str . '/' . $folder : $folder;
 242                              if (!is_dir($str))
 243                              {
 244                                  if (!@mkdir($str, 0777))
 245                                  {
 246                                      trigger_error("Could not create directory $folder");
 247                                  }
 248                                  @chmod($str, 0777);
 249                              }
 250                          }
 251                      }
 252   
 253                      if (!$data['uc_size'])
 254                      {
 255                          $content = '';
 256                      }
 257                      else
 258                      {
 259                          $content = fread($this->fp, $data['c_size']);
 260                      }
 261   
 262                      $fp = fopen($target_filename, "w");
 263   
 264                      switch ($data['c_method'])
 265                      {
 266                          case 0:
 267                              // Not compressed
 268                              fwrite($fp, $content);
 269                          break;
 270                      
 271                          case 8:
 272                              // Deflate
 273                              fwrite($fp, gzinflate($content, $data['uc_size']));
 274                          break;
 275   
 276                          case 12:
 277                              // Bzip2
 278                              fwrite($fp, bzdecompress($content));
 279                          break;
 280                      }
 281                      
 282                      fclose($fp);
 283                  break;
 284   
 285                  // We hit the 'Central Directory Header', we can stop because nothing else in here requires our attention
 286                  // or we hit the end of the central directory record, we can safely end the loop as we are totally finished with looking for files and folders
 287                  case "\x50\x4b\x01\x02":
 288                  // This case should simply never happen.. but it does exist..
 289                  case "\x50\x4b\x05\x06":
 290                  break 2;
 291                  
 292                  // 'Packed to Removable Disk', ignore it and look for the next signature...
 293                  case 'PK00':
 294                  continue 2;
 295                  
 296                  // We have encountered a header that is weird. Lets look for better data...
 297                  default:
 298                      if (!$dd_try)
 299                      {
 300                          // Unexpected header. Trying to detect wrong placed 'Data Descriptor';
 301                          $dd_try = true;
 302                          fseek($this->fp, 8, SEEK_CUR); // Jump over 'crc-32'(4) 'compressed-size'(4), 'uncompressed-size'(4)
 303                          continue 2;
 304                      }
 305                      trigger_error("Unexpected header, ending loop");
 306                  break 2;
 307              }
 308   
 309              $dd_try = false;
 310          }
 311      }
 312   
 313      /**
 314      * Close archive
 315      */
 316      function close()
 317      {
 318          // Write out central file directory and footer ... if it exists
 319          if (sizeof($this->ctrl_dir))
 320          {
 321              fwrite($this->fp, $this->file());
 322          }
 323          fclose($this->fp);
 324      }
 325   
 326      /**
 327      * Create the structures ... note we assume version made by is MSDOS
 328      */
 329      function data($name, $data, $is_dir = false, $stat)
 330      {
 331          $name = str_replace('\\', '/', $name);
 332   
 333          $hexdtime = pack('V', $this->unix_to_dos_time($stat[9]));
 334   
 335          if ($is_dir)
 336          {
 337              $unc_len = $c_len = $crc = 0;
 338              $zdata = '';
 339              $var_ext = 10;
 340          }
 341          else
 342          {
 343              $unc_len = strlen($data);
 344              $crc = crc32($data);
 345              $zdata = gzdeflate($data);
 346              $c_len = strlen($zdata);
 347              $var_ext = 20;
 348   
 349              // Did we compress? No, then use data as is
 350              if ($c_len >= $unc_len)
 351              {
 352                  $zdata = $data;
 353                  $c_len = $unc_len;
 354                  $var_ext = 10;
 355              }
 356          }
 357          unset($data);
 358   
 359          // If we didn't compress set method to store, else deflate
 360          $c_method = ($c_len == $unc_len) ? "\x00\x00" : "\x08\x00";
 361   
 362          // Are we a file or a directory? Set archive for file
 363          $attrib = ($is_dir) ? 16 : 32;
 364   
 365          // File Record Header
 366          $fr = "\x50\x4b\x03\x04";        // Local file header 4bytes
 367          $fr .= pack('v', $var_ext);        // ver needed to extract 2bytes
 368          $fr .= "\x00\x00";                // gen purpose bit flag 2bytes
 369          $fr .= $c_method;                // compression method 2bytes
 370          $fr .= $hexdtime;                // last mod time and date 2+2bytes
 371          $fr .= pack('V', $crc);            // crc32 4bytes
 372          $fr .= pack('V', $c_len);        // compressed filesize 4bytes
 373          $fr .= pack('V', $unc_len);        // uncompressed filesize 4bytes
 374          $fr .= pack('v', strlen($name));// length of filename 2bytes
 375   
 376          $fr .= pack('v', 0);            // extra field length 2bytes
 377          $fr .= $name;
 378          $fr .= $zdata;
 379          unset($zdata);
 380   
 381          $this->datasec_len += strlen($fr);
 382   
 383          // Add data to file ... by writing data out incrementally we save some memory
 384          fwrite($this->fp, $fr);
 385          unset($fr);
 386   
 387          // Central Directory Header
 388          $cdrec = "\x50\x4b\x01\x02";        // header 4bytes
 389          $cdrec .= "\x00\x00";                // version made by
 390          $cdrec .= pack('v', $var_ext);        // version needed to extract
 391          $cdrec .= "\x00\x00";                // gen purpose bit flag
 392          $cdrec .= $c_method;                // compression method
 393          $cdrec .= $hexdtime;                // last mod time & date
 394          $cdrec .= pack('V', $crc);            // crc32
 395          $cdrec .= pack('V', $c_len);        // compressed filesize
 396          $cdrec .= pack('V', $unc_len);        // uncompressed filesize
 397          $cdrec .= pack('v', strlen($name));    // length of filename
 398          $cdrec .= pack('v', 0);                // extra field length
 399          $cdrec .= pack('v', 0);                // file comment length
 400          $cdrec .= pack('v', 0);                // disk number start
 401          $cdrec .= pack('v', 0);                // internal file attributes
 402          $cdrec .= pack('V', $attrib);        // external file attributes
 403          $cdrec .= pack('V', $this->old_offset);    // relative offset of local header
 404          $cdrec .= $name;
 405   
 406          // Save to central directory
 407          $this->ctrl_dir[] = $cdrec;
 408   
 409          $this->old_offset = $this->datasec_len;
 410      }
 411   
 412      /**
 413      * file
 414      */
 415      function file()
 416      {
 417          $ctrldir = implode('', $this->ctrl_dir);
 418   
 419          return $ctrldir . $this->eof_cdh .
 420              pack('v', sizeof($this->ctrl_dir)) .    // total # of entries "on this disk"
 421              pack('v', sizeof($this->ctrl_dir)) .    // total # of entries overall
 422              pack('V', strlen($ctrldir)) .            // size of central dir
 423              pack('V', $this->datasec_len) .            // offset to start of central dir
 424              "\x00\x00";                                // .zip file comment length
 425      }
 426   
 427      /**
 428      * Download archive
 429      */
 430      function download($filename, $download_name = false)
 431      {
 432          global $phpbb_root_path;
 433   
 434          if ($download_name === false)
 435          {
 436              $download_name = $filename;
 437          }
 438   
 439          $mimetype = 'application/zip';
 440   
 441          header('Pragma: no-cache');
 442          header("Content-Type: $mimetype; name=\"$download_name.zip\"");
 443          header("Content-disposition: attachment; filename=$download_name.zip");
 444   
 445          $fp = @fopen("{$phpbb_root_path}store/$filename.zip", 'rb');
 446          if ($fp)
 447          {
 448              while ($buffer = fread($fp, 1024))
 449              {
 450                  echo $buffer;
 451              }
 452              fclose($fp);
 453          }
 454      }
 455  }
 456   
 457  /**
 458  * Tar/tar.gz compression routine
 459  * Header/checksum creation derived from tarfile.pl, (c) Tom Horsley, 1994
 460  *
 461  * @package phpBB3
 462  */
 463  class compress_tar extends compress
 464  {
 465      var $isgz = false;
 466      var $isbz = false;
 467      var $filename = '';
 468      var $mode = '';
 469      var $type = '';
 470      var $wrote = false;
 471   
 472      /**
 473      * Constructor
 474      */
 475      function compress_tar($mode, $file, $type = '')
 476      {
 477          $type = (!$type) ? $file : $type;
 478          $this->isgz = (strpos($type, '.tar.gz') !== false || strpos($type, '.tgz') !== false) ? true : false;
 479          $this->isbz = (strpos($type, '.tar.bz2') !== false) ? true : false;
 480   
 481          $this->mode = &$mode;
 482          $this->file = &$file;
 483          $this->type = &$type;
 484          $this->open();
 485      }
 486   
 487      /**
 488      * Extract archive
 489      */
 490      function extract($dst)
 491      {
 492          $fzread = ($this->isbz && function_exists('bzread')) ? 'bzread' : (($this->isgz && @extension_loaded('zlib')) ? 'gzread' : 'fread');
 493   
 494          // Run through the file and grab directory entries
 495          while ($buffer = $fzread($this->fp, 512))
 496          {
 497              $tmp = unpack('A6magic', substr($buffer, 257, 6));
 498   
 499              if (trim($tmp['magic']) == 'ustar')
 500              {
 501                  $tmp = unpack('A100name', $buffer);
 502                  $filename = trim($tmp['name']);
 503   
 504                  $tmp = unpack('Atype', substr($buffer, 156, 1));
 505                  $filetype = (int) trim($tmp['type']);
 506   
 507                  $tmp = unpack('A12size', substr($buffer, 124, 12));
 508                  $filesize = octdec((int) trim($tmp['size']));
 509   
 510                  if ($filetype == 5)
 511                  {
 512                      if (!is_dir("$dst$filename"))
 513                      {
 514                          $str = '';
 515                          $folders = explode('/', "$dst$filename");
 516   
 517                          // Create and folders and subfolders if they do not exist
 518                          foreach ($folders as $folder)
 519                          {
 520                              $str = (!empty($str)) ? $str . '/' . $folder : $folder;
 521                              if (!is_dir($str))
 522                              {
 523                                  if (!@mkdir($str, 0777))
 524                                  {
 525                                      trigger_error("Could not create directory $folder");
 526                                  }
 527                                  @chmod($str, 0777);
 528                              }
 529                          }
 530                      }
 531                  }
 532                  else if ($filesize != 0 && ($filetype == 0 || $filetype == "\0"))
 533                  {
 534                      // Write out the files
 535                      if (!($fp = fopen("$dst$filename", 'wb')))
 536                      {
 537                          trigger_error("Couldn't create file $filename");
 538                      }
 539                      @chmod("$dst$filename", 0777);
 540   
 541                      // Grab the file contents
 542                      fwrite($fp, $fzread($this->fp, ($filesize + 511) &~ 511), $filesize);
 543                      fclose($fp);
 544                  }
 545              }
 546          }
 547      }
 548   
 549      /**
 550      * Close archive
 551      */
 552      function close()
 553      {
 554          $fzclose = ($this->isbz && function_exists('bzclose')) ? 'bzclose' : (($this->isgz && @extension_loaded('zlib')) ? 'gzclose' : 'fclose');
 555   
 556          if ($this->wrote)
 557          {
 558              $fzwrite = ($this->isbz && function_exists('bzwrite')) ? 'bzwrite' : (($this->isgz && @extension_loaded('zlib')) ? 'gzwrite' : 'fwrite');
 559   
 560              // The end of a tar archive ends in two records of all NULLs (1024 bytes of \0)
 561              $fzwrite($this->fp, str_repeat("\0", 1024));
 562          }
 563   
 564          $fzclose($this->fp);
 565      }
 566   
 567      /**
 568      * Create the structures
 569      */
 570      function data($name, $data, $is_dir = false, $stat)
 571      {
 572          $this->wrote = true;
 573          $fzwrite =     ($this->isbz && function_exists('bzwrite')) ? 'bzwrite' : (($this->isgz && @extension_loaded('zlib')) ? 'gzwrite' : 'fwrite');
 574   
 575          $typeflag = ($is_dir) ? '5' : '';
 576   
 577          // This is the header data, it contains all the info we know about the file or folder that we are about to archive
 578          $header = '';
 579          $header .= pack('a100', $name);                        // file name
 580          $header .= pack('a8', sprintf("%07o", $stat[2]));    // file mode
 581          $header .= pack('a8', sprintf("%07o", $stat[4]));    // owner id
 582          $header .= pack('a8', sprintf("%07o", $stat[5]));    // group id
 583          $header .= pack('a12', sprintf("%011o", $stat[7]));    // file size
 584          $header .= pack('a12', sprintf("%011o", $stat[9]));    // last mod time
 585   
 586          // Checksum
 587          $checksum = 0;
 588          for ($i = 0; $i < 148; $i++)
 589          {
 590              $checksum += ord($header[$i]);
 591          }
 592   
 593          // We precompute the rest of the hash, this saves us time in the loop and allows us to insert our hash without resorting to string functions
 594          $checksum += 2415 + (($is_dir) ? 53 : 0);
 595   
 596          $header .= pack('a8', sprintf("%07o", $checksum));    // checksum
 597          $header .= pack('a1', $typeflag);                    // link indicator
 598          $header .= pack('a100', '');                        // name of linked file
 599          $header .= pack('a6', 'ustar');                        // ustar indicator
 600          $header .= pack('a2', '00');                        // ustar version
 601          $header .= pack('a32', 'Unknown');                    // owner name
 602          $header .= pack('a32', 'Unknown');                    // group name
 603          $header .= pack('a8', '');                            // device major number
 604          $header .= pack('a8', '');                            // device minor number
 605          $header .= pack('a155', '');                        // filename prefix
 606          $header .= pack('a12', '');                            // end
 607   
 608          // This writes the entire file in one shot. Header, followed by data and then null padded to a multiple of 512
 609          $fzwrite($this->fp, $header . (($stat[7] !== 0 && !$is_dir) ? $data . str_repeat("\0", (($stat[7] + 511) &~ 511) - $stat[7]) : ''));
 610          unset($data);
 611      }
 612   
 613      /**
 614      * Open archive
 615      */
 616      function open()
 617      {
 618          $fzopen = ($this->isbz && function_exists('bzopen')) ? 'bzopen' : (($this->isgz && @extension_loaded('zlib')) ? 'gzopen' : 'fopen');
 619          $this->fp = @$fzopen($this->file, $this->mode . (($fzopen == 'bzopen') ? '' : 'b') . (($fzopen == 'gzopen') ? '9' : ''));
 620   
 621          if (!$this->fp)
 622          {
 623              trigger_error('Unable to open file ' . $this->file . ' [' . $fzopen . ' - ' . $this->mode . 'b]');
 624          }
 625      }
 626   
 627      /**
 628      * Download archive
 629      */
 630      function download($filename, $download_name = false)
 631      {
 632          global $phpbb_root_path;
 633   
 634          if ($download_name === false)
 635          {
 636              $download_name = $filename;
 637          }
 638   
 639          switch ($this->type)
 640          {
 641              case '.tar':
 642                  $mimetype = 'application/x-tar';
 643              break;
 644   
 645              case '.tar.gz':
 646                  $mimetype = 'application/x-gzip';
 647              break;
 648   
 649              case '.tar.bz2':
 650                  $mimetype = 'application/x-bzip2';
 651              break;
 652   
 653              default:
 654                  $mimetype = 'application/octet-stream';
 655              break;
 656          }
 657   
 658          header('Pragma: no-cache');
 659          header("Content-Type: $mimetype; name=\"$download_name$this->type\"");
 660          header("Content-disposition: attachment; filename=$download_name$this->type");
 661   
 662          $fp = @fopen("{$phpbb_root_path}store/$filename$this->type", 'rb');
 663          if ($fp)
 664          {
 665              while ($buffer = fread($fp, 1024))
 666              {
 667                  echo $buffer;
 668              }
 669              fclose($fp);
 670          }
 671      }
 672  }
 673   
 674  ?>