| <?php |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| if (!defined('IN_PHPBB')) |
| { |
| exit; |
| } |
| |
| |
| |
| |
| |
| class compress |
| { |
| var $fp = 0; |
| |
| |
| |
| |
| function add_file($src, $src_rm_prefix = '', $src_add_prefix = '', $skip_files = '') |
| { |
| global $phpbb_root_path; |
| |
| $skip_files = explode(',', $skip_files); |
| |
| |
| $src_path = ($src_rm_prefix) ? preg_replace('#^(' . preg_quote($src_rm_prefix, '#') . ')#', '', $src) : $src; |
| |
| $src_path = ($src_add_prefix) ? ($src_add_prefix . ((substr($src_add_prefix, -1) != '/') ? '/' : '') . $src_path) : $src_path; |
| |
| $src_path = (substr($src_path, 0, 1) == '/') ? substr($src_path, 1) : $src_path; |
| |
| if (is_file($phpbb_root_path . $src)) |
| { |
| $this->data($src_path, file_get_contents("$phpbb_root_path$src"), false, stat("$phpbb_root_path$src")); |
| } |
| else if (is_dir($phpbb_root_path . $src)) |
| { |
| |
| $src_path = ($src_path && substr($src_path, -1) != '/') ? $src_path . '/' : $src_path; |
| |
| $filelist = array(); |
| $filelist = filelist("$phpbb_root_path$src", '', '*'); |
| krsort($filelist); |
| |
| if ($src_path) |
| { |
| $this->data($src_path, '', true, stat("$phpbb_root_path$src")); |
| } |
| |
| foreach ($filelist as $path => $file_ary) |
| { |
| if ($path) |
| { |
| |
| $path = (substr($path, 0, 1) == '/') ? substr($path, 1) : $path; |
| $path = ($path && substr($path, -1) != '/') ? $path . '/' : $path; |
| |
| $this->data("$src_path$path", '', true, stat("$phpbb_root_path$src$path")); |
| } |
| |
| foreach ($file_ary as $file) |
| { |
| if (in_array($path . $file, $skip_files)) |
| { |
| continue; |
| } |
| |
| $this->data("$src_path$path$file", file_get_contents("$phpbb_root_path$src$path$file"), false, stat("$phpbb_root_path$src$path$file")); |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| |
| |
| |
| function add_custom_file($src, $filename) |
| { |
| $this->data($filename, file_get_contents($src), false, stat($src)); |
| return true; |
| } |
| |
| |
| |
| |
| function add_data($src, $name) |
| { |
| $stat = array(); |
| $stat[2] = 436; |
| $stat[4] = $stat[5] = 0; |
| $stat[7] = strlen($src); |
| $stat[9] = time(); |
| $this->data($name, $src, false, $stat); |
| return true; |
| } |
| |
| |
| |
| |
| function methods() |
| { |
| $methods = array('.tar'); |
| $available_methods = array('.tar.gz' => 'zlib', '.tar.bz2' => 'bz2', '.zip' => 'zlib'); |
| |
| foreach ($available_methods as $type => $module) |
| { |
| if (!@extension_loaded($module)) |
| { |
| continue; |
| } |
| $methods[] = $type; |
| } |
| |
| return $methods; |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| class compress_zip extends compress |
| { |
| var $datasec = array(); |
| var $ctrl_dir = array(); |
| var $eof_cdh = "\x50\x4b\x05\x06\x00\x00\x00\x00"; |
| |
| var $old_offset = 0; |
| var $datasec_len = 0; |
| |
| |
| |
| |
| function compress_zip($mode, $file) |
| { |
| return $this->fp = @fopen($file, $mode . 'b'); |
| } |
| |
| |
| |
| |
| function unix_to_dos_time($time) |
| { |
| $timearray = (!$time) ? getdate() : getdate($time); |
| |
| if ($timearray['year'] < 1980) |
| { |
| $timearray['year'] = 1980; |
| $timearray['mon'] = $timearray['mday'] = 1; |
| $timearray['hours'] = $timearray['minutes'] = $timearray['seconds'] = 0; |
| } |
| |
| return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) | ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1); |
| } |
| |
| |
| |
| |
| function extract($dst) |
| { |
| |
| $dd_try = false; |
| rewind($this->fp); |
| |
| while (!feof($this->fp)) |
| { |
| |
| $signature = fread($this->fp, 4); |
| |
| switch ($signature) |
| { |
| |
| case "\x50\x4b\x03\x04": |
| |
| |
| $data = unpack("@4/vc_method/@10/Vcrc/Vc_size/Vuc_size/vname_len/vextra_field", fread($this->fp, 26)); |
| $file_name = fread($this->fp, $data['name_len']); |
| |
| if ($data['extra_field']) |
| { |
| fread($this->fp, $data['extra_field']); |
| } |
| |
| $target_filename = "$dst$file_name"; |
| |
| if (!$data['uc_size'] && !$data['crc'] && substr($file_name, -1, 1) == '/') |
| { |
| if (!is_dir($target_filename)) |
| { |
| $str = ''; |
| $folders = explode('/', $target_filename); |
| |
| |
| foreach ($folders as $folder) |
| { |
| $folder = trim($folder); |
| if (!$folder) |
| { |
| continue; |
| } |
| |
| $str = (!empty($str)) ? $str . '/' . $folder : $folder; |
| if (!is_dir($str)) |
| { |
| if (!@mkdir($str, 0777)) |
| { |
| trigger_error("Could not create directory $folder"); |
| } |
| phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE); |
| } |
| } |
| } |
| |
| continue; |
| } |
| else |
| { |
| |
| $str = ''; |
| $folders = explode('/', pathinfo($target_filename, PATHINFO_DIRNAME)); |
| |
| |
| foreach ($folders as $folder) |
| { |
| $folder = trim($folder); |
| if (!$folder) |
| { |
| continue; |
| } |
| |
| $str = (!empty($str)) ? $str . '/' . $folder : $folder; |
| if (!is_dir($str)) |
| { |
| if (!@mkdir($str, 0777)) |
| { |
| trigger_error("Could not create directory $folder"); |
| } |
| phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE); |
| } |
| } |
| } |
| |
| if (!$data['uc_size']) |
| { |
| $content = ''; |
| } |
| else |
| { |
| $content = fread($this->fp, $data['c_size']); |
| } |
| |
| $fp = fopen($target_filename, "w"); |
| |
| switch ($data['c_method']) |
| { |
| case 0: |
| |
| fwrite($fp, $content); |
| break; |
| |
| case 8: |
| |
| fwrite($fp, gzinflate($content, $data['uc_size'])); |
| break; |
| |
| case 12: |
| |
| fwrite($fp, bzdecompress($content)); |
| break; |
| } |
| |
| fclose($fp); |
| break; |
| |
| |
| |
| case "\x50\x4b\x01\x02": |
| |
| case "\x50\x4b\x05\x06": |
| break 2; |
| |
| |
| case 'PK00': |
| continue 2; |
| |
| |
| default: |
| if (!$dd_try) |
| { |
| |
| $dd_try = true; |
| fseek($this->fp, 8, SEEK_CUR); |
| continue 2; |
| } |
| trigger_error("Unexpected header, ending loop"); |
| break 2; |
| } |
| |
| $dd_try = false; |
| } |
| } |
| |
| |
| |
| |
| function close() |
| { |
| |
| if (sizeof($this->ctrl_dir)) |
| { |
| fwrite($this->fp, $this->file()); |
| } |
| fclose($this->fp); |
| } |
| |
| |
| |
| |
| function data($name, $data, $is_dir = false, $stat) |
| { |
| $name = str_replace('\\', '/', $name); |
| |
| $hexdtime = pack('V', $this->unix_to_dos_time($stat[9])); |
| |
| if ($is_dir) |
| { |
| $unc_len = $c_len = $crc = 0; |
| $zdata = ''; |
| $var_ext = 10; |
| } |
| else |
| { |
| $unc_len = strlen($data); |
| $crc = crc32($data); |
| $zdata = gzdeflate($data); |
| $c_len = strlen($zdata); |
| $var_ext = 20; |
| |
| |
| if ($c_len >= $unc_len) |
| { |
| $zdata = $data; |
| $c_len = $unc_len; |
| $var_ext = 10; |
| } |
| } |
| unset($data); |
| |
| |
| $c_method = ($c_len == $unc_len) ? "\x00\x00" : "\x08\x00"; |
| |
| |
| $attrib = ($is_dir) ? 16 : 32; |
| |
| |
| $fr = "\x50\x4b\x03\x04"; |
| $fr .= pack('v', $var_ext); |
| $fr .= "\x00\x00"; |
| $fr .= $c_method; |
| $fr .= $hexdtime; |
| $fr .= pack('V', $crc); |
| $fr .= pack('V', $c_len); |
| $fr .= pack('V', $unc_len); |
| $fr .= pack('v', strlen($name)); |
| |
| $fr .= pack('v', 0); |
| $fr .= $name; |
| $fr .= $zdata; |
| unset($zdata); |
| |
| $this->datasec_len += strlen($fr); |
| |
| |
| fwrite($this->fp, $fr); |
| unset($fr); |
| |
| |
| $cdrec = "\x50\x4b\x01\x02"; |
| $cdrec .= "\x00\x00"; |
| $cdrec .= pack('v', $var_ext); |
| $cdrec .= "\x00\x00"; |
| $cdrec .= $c_method; |
| $cdrec .= $hexdtime; |
| $cdrec .= pack('V', $crc); |
| $cdrec .= pack('V', $c_len); |
| $cdrec .= pack('V', $unc_len); |
| $cdrec .= pack('v', strlen($name)); |
| $cdrec .= pack('v', 0); |
| $cdrec .= pack('v', 0); |
| $cdrec .= pack('v', 0); |
| $cdrec .= pack('v', 0); |
| $cdrec .= pack('V', $attrib); |
| $cdrec .= pack('V', $this->old_offset); |
| $cdrec .= $name; |
| |
| |
| $this->ctrl_dir[] = $cdrec; |
| |
| $this->old_offset = $this->datasec_len; |
| } |
| |
| |
| |
| |
| function file() |
| { |
| $ctrldir = implode('', $this->ctrl_dir); |
| |
| return $ctrldir . $this->eof_cdh . |
| pack('v', sizeof($this->ctrl_dir)) . |
| pack('v', sizeof($this->ctrl_dir)) . |
| pack('V', strlen($ctrldir)) . |
| pack('V', $this->datasec_len) . |
| "\x00\x00"; |
| } |
| |
| |
| |
| |
| function download($filename, $download_name = false) |
| { |
| global $phpbb_root_path; |
| |
| if ($download_name === false) |
| { |
| $download_name = $filename; |
| } |
| |
| $mimetype = 'application/zip'; |
| |
| header('Pragma: no-cache'); |
| header("Content-Type: $mimetype; name=\"$download_name.zip\""); |
| header("Content-disposition: attachment; filename=$download_name.zip"); |
| |
| $fp = @fopen("{$phpbb_root_path}store/$filename.zip", 'rb'); |
| if ($fp) |
| { |
| while ($buffer = fread($fp, 1024)) |
| { |
| echo $buffer; |
| } |
| fclose($fp); |
| } |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| class compress_tar extends compress |
| { |
| var $isgz = false; |
| var $isbz = false; |
| var $filename = ''; |
| var $mode = ''; |
| var $type = ''; |
| var $wrote = false; |
| |
| |
| |
| |
| function compress_tar($mode, $file, $type = '') |
| { |
| $type = (!$type) ? $file : $type; |
| $this->isgz = (strpos($type, '.tar.gz') !== false || strpos($type, '.tgz') !== false) ? true : false; |
| $this->isbz = (strpos($type, '.tar.bz2') !== false) ? true : false; |
| |
| $this->mode = &$mode; |
| $this->file = &$file; |
| $this->type = &$type; |
| $this->open(); |
| } |
| |
| |
| |
| |
| function extract($dst) |
| { |
| $fzread = ($this->isbz && function_exists('bzread')) ? 'bzread' : (($this->isgz && @extension_loaded('zlib')) ? 'gzread' : 'fread'); |
| |
| |
| while ($buffer = $fzread($this->fp, 512)) |
| { |
| $tmp = unpack('A6magic', substr($buffer, 257, 6)); |
| |
| if (trim($tmp['magic']) == 'ustar') |
| { |
| $tmp = unpack('A100name', $buffer); |
| $filename = trim($tmp['name']); |
| |
| $tmp = unpack('Atype', substr($buffer, 156, 1)); |
| $filetype = (int) trim($tmp['type']); |
| |
| $tmp = unpack('A12size', substr($buffer, 124, 12)); |
| $filesize = octdec((int) trim($tmp['size'])); |
| |
| $target_filename = "$dst$filename"; |
| |
| if ($filetype == 5) |
| { |
| if (!is_dir($target_filename)) |
| { |
| $str = ''; |
| $folders = explode('/', $target_filename); |
| |
| |
| foreach ($folders as $folder) |
| { |
| $folder = trim($folder); |
| if (!$folder) |
| { |
| continue; |
| } |
| |
| $str = (!empty($str)) ? $str . '/' . $folder : $folder; |
| if (!is_dir($str)) |
| { |
| if (!@mkdir($str, 0777)) |
| { |
| trigger_error("Could not create directory $folder"); |
| } |
| phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE); |
| } |
| } |
| } |
| } |
| else if ($filesize >= 0 && ($filetype == 0 || $filetype == "\0")) |
| { |
| |
| $str = ''; |
| $folders = explode('/', pathinfo($target_filename, PATHINFO_DIRNAME)); |
| |
| |
| foreach ($folders as $folder) |
| { |
| $folder = trim($folder); |
| if (!$folder) |
| { |
| continue; |
| } |
| |
| $str = (!empty($str)) ? $str . '/' . $folder : $folder; |
| if (!is_dir($str)) |
| { |
| if (!@mkdir($str, 0777)) |
| { |
| trigger_error("Could not create directory $folder"); |
| } |
| phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE); |
| } |
| } |
| |
| |
| if (!($fp = fopen($target_filename, 'wb'))) |
| { |
| trigger_error("Couldn't create file $filename"); |
| } |
| phpbb_chmod($target_filename, CHMOD_READ); |
| |
| |
| fwrite($fp, ($filesize) ? $fzread($this->fp, ($filesize + 511) &~ 511) : '', $filesize); |
| fclose($fp); |
| } |
| } |
| } |
| } |
| |
| |
| |
| |
| function close() |
| { |
| $fzclose = ($this->isbz && function_exists('bzclose')) ? 'bzclose' : (($this->isgz && @extension_loaded('zlib')) ? 'gzclose' : 'fclose'); |
| |
| if ($this->wrote) |
| { |
| $fzwrite = ($this->isbz && function_exists('bzwrite')) ? 'bzwrite' : (($this->isgz && @extension_loaded('zlib')) ? 'gzwrite' : 'fwrite'); |
| |
| |
| $fzwrite($this->fp, str_repeat("\0", 1024)); |
| } |
| |
| $fzclose($this->fp); |
| } |
| |
| |
| |
| |
| function data($name, $data, $is_dir = false, $stat) |
| { |
| $this->wrote = true; |
| $fzwrite = ($this->isbz && function_exists('bzwrite')) ? 'bzwrite' : (($this->isgz && @extension_loaded('zlib')) ? 'gzwrite' : 'fwrite'); |
| |
| $typeflag = ($is_dir) ? '5' : ''; |
| |
| |
| $header = ''; |
| $header .= pack('a100', $name); |
| $header .= pack('a8', sprintf("%07o", $stat[2])); |
| $header .= pack('a8', sprintf("%07o", $stat[4])); |
| $header .= pack('a8', sprintf("%07o", $stat[5])); |
| $header .= pack('a12', sprintf("%011o", $stat[7])); |
| $header .= pack('a12', sprintf("%011o", $stat[9])); |
| |
| |
| $checksum = 0; |
| for ($i = 0; $i < 148; $i++) |
| { |
| $checksum += ord($header[$i]); |
| } |
| |
| |
| $checksum += 2415 + (($is_dir) ? 53 : 0); |
| |
| $header .= pack('a8', sprintf("%07o", $checksum)); |
| $header .= pack('a1', $typeflag); |
| $header .= pack('a100', ''); |
| $header .= pack('a6', 'ustar'); |
| $header .= pack('a2', '00'); |
| $header .= pack('a32', 'Unknown'); |
| $header .= pack('a32', 'Unknown'); |
| $header .= pack('a8', ''); |
| $header .= pack('a8', ''); |
| $header .= pack('a155', ''); |
| $header .= pack('a12', ''); |
| |
| |
| $fzwrite($this->fp, $header . (($stat[7] !== 0 && !$is_dir) ? $data . str_repeat("\0", (($stat[7] + 511) &~ 511) - $stat[7]) : '')); |
| unset($data); |
| } |
| |
| |
| |
| |
| function open() |
| { |
| $fzopen = ($this->isbz && function_exists('bzopen')) ? 'bzopen' : (($this->isgz && @extension_loaded('zlib')) ? 'gzopen' : 'fopen'); |
| $this->fp = @$fzopen($this->file, $this->mode . (($fzopen == 'bzopen') ? '' : 'b') . (($fzopen == 'gzopen') ? '9' : '')); |
| |
| if (!$this->fp) |
| { |
| trigger_error('Unable to open file ' . $this->file . ' [' . $fzopen . ' - ' . $this->mode . 'b]'); |
| } |
| } |
| |
| |
| |
| |
| function download($filename, $download_name = false) |
| { |
| global $phpbb_root_path; |
| |
| if ($download_name === false) |
| { |
| $download_name = $filename; |
| } |
| |
| switch ($this->type) |
| { |
| case '.tar': |
| $mimetype = 'application/x-tar'; |
| break; |
| |
| case '.tar.gz': |
| $mimetype = 'application/x-gzip'; |
| break; |
| |
| case '.tar.bz2': |
| $mimetype = 'application/x-bzip2'; |
| break; |
| |
| default: |
| $mimetype = 'application/octet-stream'; |
| break; |
| } |
| |
| header('Pragma: no-cache'); |
| header("Content-Type: $mimetype; name=\"$download_name$this->type\""); |
| header("Content-disposition: attachment; filename=$download_name$this->type"); |
| |
| $fp = @fopen("{$phpbb_root_path}store/$filename$this->type", 'rb'); |
| if ($fp) |
| { |
| while ($buffer = fread($fp, 1024)) |
| { |
| echo $buffer; |
| } |
| fclose($fp); |
| } |
| } |
| } |
| |
| ?> |