Verzeichnisstruktur phpBB-3.1.0


Veröffentlicht
27.10.2014

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:51 - Dateigröße: 19.55 KiB


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