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  ?>