44 if (!class_exists(
'PEAR')) {
45 require_once
'PEAR.php';
48 define(
'ARCHIVE_TAR_ATT_SEPARATOR', 90001);
49 define(
'ARCHIVE_TAR_END_BLOCK', pack(
"a512",
''));
51 if (!function_exists(
'gzopen') && function_exists(
'gzopen64')) {
52 function gzopen($filename, $mode, $use_include_path = 0)
54 return gzopen64($filename, $mode, $use_include_path);
58 if (!function_exists(
'gztell') && function_exists(
'gztell64')) {
65 if (!function_exists(
'gzseek') && function_exists(
'gzseek64')) {
66 function gzseek($zp, $offset, $whence = SEEK_SET)
68 return gzseek64($zp, $offset, $whence);
152 parent::__construct();
154 $this->_compress =
false;
155 $this->_compress_type =
'none';
156 if (($p_compress ===
null) || ($p_compress ==
'')) {
157 if (@file_exists($p_tarname)) {
158 if ($fp = @fopen($p_tarname,
"rb")) {
160 $data = fread($fp, 2);
162 if ($data ==
"\37\213") {
163 $this->_compress =
true;
164 $this->_compress_type =
'gz';
166 } elseif ($data ==
"BZ") {
167 $this->_compress =
true;
168 $this->_compress_type =
'bz2';
169 } elseif (file_get_contents($p_tarname,
false,
null, 1, 4) ==
'7zXZ') {
170 $this->_compress =
true;
171 $this->_compress_type =
'lzma2';
177 if (substr($p_tarname, -2) ==
'gz') {
178 $this->_compress =
true;
179 $this->_compress_type =
'gz';
180 } elseif ((substr($p_tarname, -3) ==
'bz2') ||
181 (substr($p_tarname, -2) ==
'bz')
183 $this->_compress =
true;
184 $this->_compress_type =
'bz2';
186 if (substr($p_tarname, -2) ==
'xz') {
187 $this->_compress =
true;
188 $this->_compress_type =
'lzma2';
193 if (($p_compress ===
true) || ($p_compress ==
'gz')) {
194 $this->_compress =
true;
195 $this->_compress_type =
'gz';
197 if ($p_compress ==
'bz2') {
198 $this->_compress =
true;
199 $this->_compress_type =
'bz2';
201 if ($p_compress ==
'lzma2') {
202 $this->_compress =
true;
203 $this->_compress_type =
'lzma2';
206 "Unsupported compression type '$p_compress'\n" .
207 "Supported types are 'gz', 'bz2' and 'lzma2'.\n"
214 $this->_tarname = $p_tarname;
215 if ($this->_compress) {
216 if ($this->_compress_type ==
'gz') {
219 if ($this->_compress_type ==
'bz2') {
222 if ($this->_compress_type ==
'lzma2') {
228 if (!extension_loaded($extname)) {
231 if (!extension_loaded($extname)) {
233 "The extension '$extname' couldn't be found.\n" .
234 "Please make sure your version of PHP was built " .
235 "with '$extname' support.\n"
242 if (version_compare(PHP_VERSION,
"5.5.0-dev") < 0) {
243 $this->_fmt =
"a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/" .
244 "a8checksum/a1typeflag/a100link/a6magic/a2version/" .
245 "a32uname/a32gname/a8devmajor/a8devminor/a131prefix";
247 $this->_fmt =
"Z100filename/Z8mode/Z8uid/Z8gid/Z12size/Z12mtime/" .
248 "Z8checksum/Z1typeflag/Z100link/Z6magic/Z2version/" .
249 "Z32uname/Z32gname/Z8devmajor/Z8devminor/Z131prefix";
260 if ($this->_temp_tarname !=
'') {
261 @unlink($this->_temp_tarname);
307 public function add($p_filelist)
309 return $this->
addModify($p_filelist,
'',
'');
318 public function extract($p_path =
'', $p_preserve =
false, $p_symlinks =
true)
320 return $this->
extractModify($p_path,
'', $p_preserve, $p_symlinks);
328 $v_list_detail = array();
331 if (!$this->
_extractList(
'', $v_list_detail,
"list",
'',
'')) {
332 unset($v_list_detail);
338 return $v_list_detail;
376 public function createModify($p_filelist, $p_add_dir, $p_remove_dir =
'')
384 if ($p_filelist !=
'') {
385 if (is_array($p_filelist)) {
386 $v_list = $p_filelist;
387 } elseif (is_string($p_filelist)) {
388 $v_list = explode($this->_separator, $p_filelist);
391 $this->
_error(
'Invalid file list');
395 $v_result = $this->
_addList($v_list, $p_add_dir, $p_remove_dir);
448 public function addModify($p_filelist, $p_add_dir, $p_remove_dir =
'')
459 if (is_array($p_filelist)) {
460 $v_list = $p_filelist;
461 } elseif (is_string($p_filelist)) {
462 $v_list = explode($this->_separator, $p_filelist);
464 $this->
_error(
'Invalid file list');
468 $v_result = $this->
_append($v_list, $p_add_dir, $p_remove_dir);
501 public function addString($p_filename, $p_string, $p_datetime =
false, $p_params = array())
503 $p_stamp = @$p_params[
"stamp"] ? $p_params[
"stamp"] : ($p_datetime ? $p_datetime : time());
504 $p_mode = @$p_params[
"mode"] ? $p_params[
"mode"] : 0600;
505 $p_type = @$p_params[
"type"] ? $p_params[
"type"] :
"";
506 $p_uid = @$p_params[
"uid"] ? $p_params[
"uid"] :
"";
507 $p_gid = @$p_params[
"gid"] ? $p_params[
"gid"] :
"";
522 $v_result = $this->
_addString($p_filename, $p_string, $p_datetime, $p_params);
566 public function extractModify($p_path, $p_remove_path, $p_preserve =
false, $p_symlinks =
true)
569 $v_list_detail = array();
598 $v_result = $this->_extractInString($p_filename);
628 public function extractList($p_filelist, $p_path =
'', $p_remove_path =
'', $p_preserve =
false, $p_symlinks =
true)
631 $v_list_detail = array();
633 if (is_array($p_filelist)) {
634 $v_list = $p_filelist;
635 } elseif (is_string($p_filelist)) {
636 $v_list = explode($this->_separator, $p_filelist);
638 $this->
_error(
'Invalid string list');
670 if (($v_size = func_num_args()) == 0) {
675 $v_att_list = func_get_args();
679 while ($i < $v_size) {
682 switch ($v_att_list[$i]) {
684 case ARCHIVE_TAR_ATT_SEPARATOR :
686 if (($i + 1) >= $v_size) {
688 'Invalid number of parameters for '
689 .
'attribute ARCHIVE_TAR_ATT_SEPARATOR'
695 $this->_separator = $v_att_list[$i + 1];
700 $this->
_error(
'Unknown attribute code ' . $v_att_list[$i] .
'');
720 $this->_ignore_regexp = $regexp;
734 $regexp = str_replace(array(
'#',
'.',
'^',
'$'), array(
'\#',
'\.',
'\^',
'\$'), $list);
735 $regexp =
'#/' . join(
'$|/', $list) .
'#';
742 public function _error($p_message)
744 $this->error_object = $this->raiseError($p_message);
750 public function _warning($p_message)
752 $this->error_object = $this->raiseError($p_message);
759 public function _isArchive($p_filename =
null)
761 if ($p_filename ==
null) {
765 return @is_file($p_filename) && !@is_link($p_filename);
773 if ($this->_compress_type ==
'gz' && function_exists(
'gzopen')) {
774 $this->_file = @gzopen($this->_tarname,
"wb9");
776 if ($this->_compress_type ==
'bz2' && function_exists(
'bzopen')) {
777 $this->_file = @bzopen($this->_tarname,
"w");
779 if ($this->_compress_type ==
'lzma2' && function_exists(
'xzopen')) {
780 $this->_file = @xzopen($this->_tarname,
'w');
782 if ($this->_compress_type ==
'none') {
783 $this->_file = @fopen($this->_tarname,
"wb");
786 'Unknown or missing compression type ('
787 . $this->_compress_type .
')'
795 if ($this->_file == 0) {
797 'Unable to open in write mode \''
798 . $this->_tarname .
'\''
811 if (strtolower(substr($this->_tarname, 0, 7)) ==
'http://') {
814 if ($this->_temp_tarname ==
'') {
815 $this->_temp_tarname = uniqid(
'tar') .
'.tmp';
816 if (!$v_file_from = @fopen($this->_tarname,
'rb')) {
818 'Unable to open in read mode \''
819 . $this->_tarname .
'\''
821 $this->_temp_tarname =
'';
824 if (!$v_file_to = @fopen($this->_temp_tarname,
'wb')) {
826 'Unable to open in write mode \''
827 . $this->_temp_tarname .
'\''
829 $this->_temp_tarname =
'';
832 while ($v_data = @fread($v_file_from, 1024)) {
833 @fwrite($v_file_to, $v_data);
835 @fclose($v_file_from);
847 if ($this->_compress_type ==
'gz' && function_exists(
'gzopen')) {
848 $this->_file = @gzopen($v_filename,
"rb");
850 if ($this->_compress_type ==
'bz2' && function_exists(
'bzopen')) {
851 $this->_file = @bzopen($v_filename,
"r");
853 if ($this->_compress_type ==
'lzma2' && function_exists(
'xzopen')) {
854 $this->_file = @xzopen($v_filename,
"r");
856 if ($this->_compress_type ==
'none') {
857 $this->_file = @fopen($v_filename,
"rb");
860 'Unknown or missing compression type ('
861 . $this->_compress_type .
')'
869 if ($this->_file == 0) {
870 $this->
_error(
'Unable to open in read mode \'' . $v_filename .
'\'');
882 if ($this->_compress_type ==
'gz') {
883 $this->_file = @gzopen($this->_tarname,
"r+b");
885 if ($this->_compress_type ==
'bz2') {
887 'Unable to open bz2 in read/write mode \''
888 . $this->_tarname .
'\' (limitation of bz2 extension)
'
892 if ($this->_compress_type == 'lzma2
') {
894 'Unable to open lzma2 in read/write mode \
''
895 . $this->_tarname .
'\' (limitation of lzma2 extension)
'
899 if ($this->_compress_type == 'none
') {
900 $this->_file = @fopen($this->_tarname, "r+b");
903 'Unknown or missing compression type (
'
904 . $this->_compress_type . ')
'
912 if ($this->_file == 0) {
914 'Unable to open in read/write mode \
''
915 . $this->_tarname .
'\''
929 if (is_resource($this->_file)) {
930 if ($this->_compress_type ==
'gz') {
931 @gzclose($this->_file);
933 if ($this->_compress_type ==
'bz2') {
934 @bzclose($this->_file);
936 if ($this->_compress_type ==
'lzma2') {
937 @xzclose($this->_file);
939 if ($this->_compress_type ==
'none') {
940 @fclose($this->_file);
943 'Unknown or missing compression type ('
944 . $this->_compress_type .
')'
956 if ($this->_temp_tarname !=
'') {
957 @unlink($this->_temp_tarname);
958 $this->_temp_tarname =
'';
972 if ($this->_temp_tarname !=
'') {
974 @unlink($this->_temp_tarname);
975 $this->_temp_tarname =
'';
978 @unlink($this->_tarname);
980 $this->_tarname =
'';
990 public function _writeBlock($p_binary_data, $p_len =
null)
992 if (is_resource($this->_file)) {
993 if ($p_len ===
null) {
994 if ($this->_compress_type ==
'gz') {
995 @gzputs($this->_file, $p_binary_data);
997 if ($this->_compress_type ==
'bz2') {
998 @bzwrite($this->_file, $p_binary_data);
1000 if ($this->_compress_type ==
'lzma2') {
1001 @xzwrite($this->_file, $p_binary_data);
1003 if ($this->_compress_type ==
'none') {
1004 @fputs($this->_file, $p_binary_data);
1007 'Unknown or missing compression type ('
1008 . $this->_compress_type .
')'
1015 if ($this->_compress_type ==
'gz') {
1016 @gzputs($this->_file, $p_binary_data, $p_len);
1018 if ($this->_compress_type ==
'bz2') {
1019 @bzwrite($this->_file, $p_binary_data, $p_len);
1021 if ($this->_compress_type ==
'lzma2') {
1022 @xzwrite($this->_file, $p_binary_data, $p_len);
1024 if ($this->_compress_type ==
'none') {
1025 @fputs($this->_file, $p_binary_data, $p_len);
1028 'Unknown or missing compression type ('
1029 . $this->_compress_type .
')'
1046 if (is_resource($this->_file)) {
1047 if ($this->_compress_type ==
'gz') {
1048 $v_block = @gzread($this->_file, 512);
1050 if ($this->_compress_type ==
'bz2') {
1051 $v_block = @bzread($this->_file, 512);
1053 if ($this->_compress_type ==
'lzma2') {
1054 $v_block = @xzread($this->_file, 512);
1056 if ($this->_compress_type ==
'none') {
1057 $v_block = @fread($this->_file, 512);
1060 'Unknown or missing compression type ('
1061 . $this->_compress_type .
')'
1077 if (is_resource($this->_file)) {
1078 if ($p_len ===
null) {
1082 if ($this->_compress_type ==
'gz') {
1083 @gzseek($this->_file, gztell($this->_file) + ($p_len * 512));
1085 if ($this->_compress_type ==
'bz2') {
1087 for ($i = 0; $i < $p_len; $i++) {
1091 if ($this->_compress_type ==
'lzma2') {
1093 for ($i = 0; $i < $p_len; $i++) {
1097 if ($this->_compress_type ==
'none') {
1098 @fseek($this->_file, $p_len * 512, SEEK_CUR);
1101 'Unknown or missing compression type ('
1102 . $this->_compress_type .
')'
1117 if (is_resource($this->_file)) {
1119 $v_binary_data = pack(
'a1024',
'');
1131 public function _addList($p_list, $p_add_dir, $p_remove_dir)
1134 $v_header = array();
1140 if (!$this->_file) {
1141 $this->
_error(
'Invalid file descriptor');
1145 if (
sizeof($p_list) == 0) {
1149 foreach ($p_list as $v_filename) {
1155 if ($v_filename == $this->_tarname) {
1159 if ($v_filename ==
'') {
1164 if ($this->_ignore_regexp && preg_match($this->_ignore_regexp,
'/' . $v_filename)) {
1165 $this->
_warning(
"File '$v_filename' ignored");
1169 if (!file_exists($v_filename) && !is_link($v_filename)) {
1170 $this->
_warning(
"File '$v_filename' does not exist");
1175 if (!$this->
_addFile($v_filename, $v_header, $p_add_dir, $p_remove_dir)) {
1179 if (@is_dir($v_filename) && !@is_link($v_filename)) {
1180 if (!($p_hdir = opendir($v_filename))) {
1181 $this->
_warning(
"Directory '$v_filename' can not be read");
1184 while (
false !== ($p_hitem = readdir($p_hdir))) {
1185 if (($p_hitem !=
'.') && ($p_hitem !=
'..')) {
1186 if ($v_filename !=
".") {
1187 $p_temp_list[0] = $v_filename .
'/' . $p_hitem;
1189 $p_temp_list[0] = $p_hitem;
1200 unset($p_temp_list);
1217 public function _addFile($p_filename, &$p_header, $p_add_dir, $p_remove_dir, $v_stored_filename =
null)
1219 if (!$this->_file) {
1220 $this->
_error(
'Invalid file descriptor');
1224 if ($p_filename ==
'') {
1225 $this->
_error(
'Invalid file name');
1229 if (is_null($v_stored_filename)) {
1232 $v_stored_filename = $p_filename;
1234 if (strcmp($p_filename, $p_remove_dir) == 0) {
1238 if ($p_remove_dir !=
'') {
1239 if (substr($p_remove_dir, -1) !=
'/') {
1240 $p_remove_dir .=
'/';
1243 if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir) {
1244 $v_stored_filename = substr($p_filename, strlen($p_remove_dir));
1249 if ($p_add_dir !=
'') {
1250 if (substr($p_add_dir, -1) ==
'/') {
1251 $v_stored_filename = $p_add_dir . $v_stored_filename;
1253 $v_stored_filename = $p_add_dir .
'/' . $v_stored_filename;
1257 $v_stored_filename = $this->_pathReduction($v_stored_filename);
1261 if (($v_file = @fopen($p_filename,
"rb")) == 0) {
1263 "Unable to open file '" . $p_filename
1264 .
"' in binary read mode"
1269 if (!$this->
_writeHeader($p_filename, $v_stored_filename)) {
1273 while (($v_buffer = fread($v_file, $this->buffer_length)) !=
'') {
1277 $pack_format = sprintf(
'a%d', $pack_size);
1279 $pack_format = sprintf(
'a%d', $this->buffer_length);
1281 $v_binary_data = pack($pack_format,
"$v_buffer");
1288 if (!$this->
_writeHeader($p_filename, $v_stored_filename)) {
1303 public function _addString($p_filename, $p_string, $p_datetime =
false, $p_params = array())
1305 $p_stamp = @$p_params[
"stamp"] ? $p_params[
"stamp"] : ($p_datetime ? $p_datetime : time());
1306 $p_mode = @$p_params[
"mode"] ? $p_params[
"mode"] : 0600;
1307 $p_type = @$p_params[
"type"] ? $p_params[
"type"] :
"";
1308 $p_uid = @$p_params[
"uid"] ? $p_params[
"uid"] : 0;
1309 $p_gid = @$p_params[
"gid"] ? $p_params[
"gid"] : 0;
1310 if (!$this->_file) {
1311 $this->
_error(
'Invalid file descriptor');
1315 if ($p_filename ==
'') {
1316 $this->
_error(
'Invalid file name');
1324 if ($p_datetime ===
false) {
1325 $p_datetime = time();
1342 while (($v_buffer = substr($p_string, (($i++) * 512), 512)) !=
'') {
1343 $v_binary_data = pack(
"a512", $v_buffer);
1355 public function _writeHeader($p_filename, $p_stored_filename)
1357 if ($p_stored_filename ==
'') {
1358 $p_stored_filename = $p_filename;
1361 $v_reduced_filename = $this->_pathReduction($p_stored_filename);
1363 if (strlen($v_reduced_filename) > 99) {
1370 if (@is_link($p_filename)) {
1371 $v_linkname = readlink($p_filename);
1374 if (strlen($v_linkname) > 99) {
1380 $v_info = lstat($p_filename);
1381 $v_uid = sprintf(
"%07s", DecOct($v_info[4]));
1382 $v_gid = sprintf(
"%07s", DecOct($v_info[5]));
1383 $v_perms = sprintf(
"%07s", DecOct($v_info[
'mode'] & 000777));
1384 $v_mtime = sprintf(
"%011s", DecOct($v_info[
'mtime']));
1386 if (@is_link($p_filename)) {
1388 $v_size = sprintf(
"%011s", DecOct(0));
1389 } elseif (@is_dir($p_filename)) {
1391 $v_size = sprintf(
"%011s", DecOct(0));
1395 $v_size = sprintf(
"%011s", DecOct($v_info[
'size']));
1398 $v_magic =
'ustar ';
1401 if (function_exists(
'posix_getpwuid')) {
1402 $userinfo = posix_getpwuid($v_info[4]);
1403 $groupinfo = posix_getgrgid($v_info[5]);
1405 $v_uname = $userinfo[
'name'];
1406 $v_gname = $groupinfo[
'name'];
1416 $v_binary_data_first = pack(
1418 $v_reduced_filename,
1425 $v_binary_data_last = pack(
1426 "a1a100a6a2a32a32a8a8a155a12",
1442 for ($i = 0; $i < 148; $i++) {
1443 $v_checksum += ord(substr($v_binary_data_first, $i, 1));
1446 for ($i = 148; $i < 156; $i++) {
1447 $v_checksum += ord(
' ');
1450 for ($i = 156, $j = 0; $i < 512; $i++, $j++) {
1451 $v_checksum += ord(substr($v_binary_data_last, $j, 1));
1458 $v_checksum = sprintf(
"%06s\0 ", DecOct($v_checksum));
1459 $v_binary_data = pack(
"a8", $v_checksum);
1488 $p_filename = $this->_pathReduction($p_filename);
1490 if (strlen($p_filename) > 99) {
1496 if ($p_type ==
"5") {
1497 $v_size = sprintf(
"%011s", DecOct(0));
1499 $v_size = sprintf(
"%011s", DecOct($p_size));
1502 $v_uid = sprintf(
"%07s", DecOct($p_uid));
1503 $v_gid = sprintf(
"%07s", DecOct($p_gid));
1504 $v_perms = sprintf(
"%07s", DecOct($p_perms & 000777));
1506 $v_mtime = sprintf(
"%11s", DecOct($p_mtime));
1510 $v_magic =
'ustar ';
1514 if (function_exists(
'posix_getpwuid')) {
1515 $userinfo = posix_getpwuid($p_uid);
1516 $groupinfo = posix_getgrgid($p_gid);
1518 $v_uname = $userinfo[
'name'];
1519 $v_gname = $groupinfo[
'name'];
1531 $v_binary_data_first = pack(
1540 $v_binary_data_last = pack(
1541 "a1a100a6a2a32a32a8a8a155a12",
1557 for ($i = 0; $i < 148; $i++) {
1558 $v_checksum += ord(substr($v_binary_data_first, $i, 1));
1561 for ($i = 148; $i < 156; $i++) {
1562 $v_checksum += ord(
' ');
1565 for ($i = 156, $j = 0; $i < 512; $i++, $j++) {
1566 $v_checksum += ord(substr($v_binary_data_last, $j, 1));
1573 $v_checksum = sprintf(
"%06s ", DecOct($v_checksum));
1574 $v_binary_data = pack(
"a8", $v_checksum);
1589 $v_uid = sprintf(
"%07s", 0);
1590 $v_gid = sprintf(
"%07s", 0);
1591 $v_perms = sprintf(
"%07s", 0);
1592 $v_size = sprintf(
"%'011s", DecOct(strlen($p_filename)));
1593 $v_mtime = sprintf(
"%011s", 0);
1594 $v_typeflag = ($is_link ?
'K' :
'L');
1596 $v_magic =
'ustar ';
1604 $v_binary_data_first = pack(
1613 $v_binary_data_last = pack(
1614 "a1a100a6a2a32a32a8a8a155a12",
1630 for ($i = 0; $i < 148; $i++) {
1631 $v_checksum += ord(substr($v_binary_data_first, $i, 1));
1634 for ($i = 148; $i < 156; $i++) {
1635 $v_checksum += ord(
' ');
1638 for ($i = 156, $j = 0; $i < 512; $i++, $j++) {
1639 $v_checksum += ord(substr($v_binary_data_last, $j, 1));
1646 $v_checksum = sprintf(
"%06s\0 ", DecOct($v_checksum));
1647 $v_binary_data = pack(
"a8", $v_checksum);
1655 while (($v_buffer = substr($p_filename, (($i++) * 512), 512)) !=
'') {
1656 $v_binary_data = pack(
"a512",
"$v_buffer");
1668 public function _readHeader($v_binary_data, &$v_header)
1670 if (strlen($v_binary_data) == 0) {
1671 $v_header[
'filename'] =
'';
1675 if (strlen($v_binary_data) != 512) {
1676 $v_header[
'filename'] =
'';
1677 $this->
_error(
'Invalid block size : ' . strlen($v_binary_data));
1681 if (!is_array($v_header)) {
1682 $v_header = array();
1687 $v_binary_split = str_split($v_binary_data);
1688 $v_checksum += array_sum(array_map(
'ord', array_slice($v_binary_split, 0, 148)));
1689 $v_checksum += array_sum(array_map(
'ord', array(
' ',
' ',
' ',
' ',
' ',
' ',
' ',
' ',)));
1690 $v_checksum += array_sum(array_map(
'ord', array_slice($v_binary_split, 156, 512)));
1693 $v_data = unpack($this->_fmt, $v_binary_data);
1695 if (strlen($v_data[
"prefix"]) > 0) {
1696 $v_data[
"filename"] =
"$v_data[prefix]/$v_data[filename]";
1700 $v_data_checksum = trim($v_data[
'checksum']);
1701 if (!preg_match(
'/^[0-7]*$/', $v_data_checksum)) {
1703 'Invalid checksum for file "' . $v_data[
'filename']
1704 .
'" : ' . $v_data_checksum .
' extracted'
1709 $v_header[
'checksum'] = OctDec($v_data_checksum);
1710 if ($v_header[
'checksum'] != $v_checksum) {
1711 $v_header[
'filename'] =
'';
1714 if (($v_checksum == 256) && ($v_header[
'checksum'] == 0)) {
1719 'Invalid checksum for file "' . $v_data[
'filename']
1720 .
'" : ' . $v_checksum .
' calculated, '
1721 . $v_header[
'checksum'] .
' expected'
1727 $v_header[
'filename'] = rtrim($v_data[
'filename'],
"\0");
1728 if ($this->_maliciousFilename($v_header[
'filename'])) {
1730 'Malicious .tar detected, file "' . $v_header[
'filename'] .
1731 '" will not install in desired directory tree'
1735 $v_header[
'mode'] = OctDec(trim($v_data[
'mode']));
1736 $v_header[
'uid'] = OctDec(trim($v_data[
'uid']));
1737 $v_header[
'gid'] = OctDec(trim($v_data[
'gid']));
1738 $v_header[
'size'] = $this->_tarRecToSize($v_data[
'size']);
1739 $v_header[
'mtime'] = OctDec(trim($v_data[
'mtime']));
1740 if (($v_header[
'typeflag'] = $v_data[
'typeflag']) ==
"5") {
1741 $v_header[
'size'] = 0;
1743 $v_header[
'link'] = trim($v_data[
'link']);
1763 private function _tarRecToSize($tar_size)
1772 $ch = ord($tar_size[0]);
1775 $rec_str = $tar_size .
"\x00";
1777 $size = ($ch & 0x40) ? -1 : 0;
1778 $size = ($size << 6) | ($ch & 0x3f);
1780 for ($num_ch = 1; $num_ch < 12; ++$num_ch) {
1781 $size = ($size * 256) + ord($rec_str[$num_ch]);
1787 return OctDec(trim($tar_size));
1798 private function _maliciousFilename($file)
1800 if (strpos($file,
'phar://') === 0) {
1803 if (strpos($file,
'../') !==
false || strpos($file,
'..\\') !==
false) {
1816 $v_filesize = $v_header[
'size'];
1817 $n = floor($v_header[
'size'] / 512);
1818 for ($i = 0; $i < $n; $i++) {
1820 $v_filename .= $v_content;
1822 if (($v_header[
'size'] % 512) != 0) {
1824 $v_filename .= $v_content;
1830 if (!$this->
_readHeader($v_binary_data, $v_header)) {
1834 $v_filename = rtrim(substr($v_filename, 0, $v_filesize),
"\0");
1835 $v_header[
'filename'] = $v_filename;
1836 if ($this->_maliciousFilename($v_filename)) {
1838 'Malicious .tar detected, file "' . $v_filename .
1839 '" will not install in desired directory tree'
1855 private function _extractInString($p_filename)
1859 while (strlen($v_binary_data = $this->
_readBlock()) != 0) {
1860 if (!$this->
_readHeader($v_binary_data, $v_header)) {
1864 if ($v_header[
'filename'] ==
'') {
1868 switch ($v_header[
'typeflag']) {
1879 $v_link_header = $v_header;
1883 $v_header[
'link'] = $v_link_header[
'filename'];
1888 if ($v_header[
'filename'] == $p_filename) {
1889 if ($v_header[
'typeflag'] ==
"5") {
1891 'Unable to extract in string a directory '
1892 .
'entry {' . $v_header[
'filename'] .
'}'
1896 $n = floor($v_header[
'size'] / 512);
1897 for ($i = 0; $i < $n; $i++) {
1900 if (($v_header[
'size'] % 512) != 0) {
1902 $v_result_str .= substr(
1905 ($v_header[
'size'] % 512)
1908 return $v_result_str;
1911 $this->
_jumpBlock(ceil(($v_header[
'size'] / 512)));
1934 $p_preserve =
false,
1940 $v_extract_all =
true;
1944 if ($p_path ==
'' || (substr($p_path, 0, 1) !=
'/'
1945 && substr($p_path, 0, 3) !=
"../" && !strpos($p_path,
':'))
1947 $p_path =
"./" . $p_path;
1952 if (($p_remove_path !=
'') && (substr($p_remove_path, -1) !=
'/')) {
1953 $p_remove_path .=
'/';
1955 $p_remove_path_size = strlen($p_remove_path);
1959 $v_extract_all =
true;
1963 $v_extract_all =
false;
1967 $v_extract_all =
false;
1971 $this->
_error(
'Invalid extract mode (' . $p_mode .
')');
1977 while (strlen($v_binary_data = $this->
_readBlock()) != 0) {
1978 $v_extract_file =
false;
1979 $v_extraction_stopped = 0;
1981 if (!$this->
_readHeader($v_binary_data, $v_header)) {
1985 if ($v_header[
'filename'] ==
'') {
1989 switch ($v_header[
'typeflag']) {
2000 $v_link_header = $v_header;
2004 $v_header[
'link'] = $v_link_header[
'filename'];
2010 if ($v_header[
'typeflag'] ==
'x' || $v_header[
'typeflag'] ==
'g') {
2011 $this->
_jumpBlock(ceil(($v_header[
'size'] / 512)));
2015 if ((!$v_extract_all) && (is_array($p_file_list))) {
2017 $v_extract_file =
false;
2019 for ($i = 0; $i <
sizeof($p_file_list); $i++) {
2021 if (substr($p_file_list[$i], -1) ==
'/') {
2023 if ((strlen($v_header[
'filename']) > strlen($p_file_list[$i]))
2024 && (substr($v_header[
'filename'], 0, strlen($p_file_list[$i]))
2025 == $p_file_list[$i])
2027 $v_extract_file =
true;
2031 elseif ($p_file_list[$i] == $v_header[
'filename']) {
2032 $v_extract_file =
true;
2037 $v_extract_file =
true;
2041 if (($v_extract_file) && (!$v_listing)) {
2042 if (($p_remove_path !=
'')
2043 && (substr($v_header[
'filename'] .
'/', 0, $p_remove_path_size)
2046 $v_header[
'filename'] = substr(
2047 $v_header[
'filename'],
2050 if ($v_header[
'filename'] ==
'') {
2054 if (($p_path !=
'./') && ($p_path !=
'/')) {
2055 while (substr($p_path, -1) ==
'/') {
2056 $p_path = substr($p_path, 0, strlen($p_path) - 1);
2059 if (substr($v_header[
'filename'], 0, 1) ==
'/') {
2060 $v_header[
'filename'] = $p_path . $v_header[
'filename'];
2062 $v_header[
'filename'] = $p_path .
'/' . $v_header[
'filename'];
2065 if (file_exists($v_header[
'filename'])) {
2066 if ((@is_dir($v_header[
'filename']))
2067 && ($v_header[
'typeflag'] ==
'')
2070 'File ' . $v_header[
'filename']
2071 .
' already exists as a directory'
2075 if (($this->
_isArchive($v_header[
'filename']))
2076 && ($v_header[
'typeflag'] ==
"5")
2079 'Directory ' . $v_header[
'filename']
2080 .
' already exists as a file'
2084 if (!is_writeable($v_header[
'filename'])) {
2086 'File ' . $v_header[
'filename']
2087 .
' already exists and is write protected'
2091 if (filemtime($v_header[
'filename']) > $v_header[
'mtime']) {
2097 ($v_header[
'typeflag'] ==
"5"
2098 ? $v_header[
'filename']
2099 : dirname($v_header[
'filename']))
2102 $this->
_error(
'Unable to create path for ' . $v_header[
'filename']);
2106 if ($v_extract_file) {
2107 if ($v_header[
'typeflag'] ==
"5") {
2108 if (!@file_exists($v_header[
'filename'])) {
2109 if (!@mkdir($v_header[
'filename'], 0777)) {
2111 'Unable to create directory {'
2112 . $v_header[
'filename'] .
'}'
2117 } elseif ($v_header[
'typeflag'] ==
"2") {
2119 $this->
_warning(
'Symbolic links are not allowed. '
2120 .
'Unable to extract {'
2121 . $v_header[
'filename'] .
'}'
2125 if (@file_exists($v_header[
'filename'])) {
2126 @unlink($v_header[
'filename']);
2128 if (!@symlink($v_header[
'link'], $v_header[
'filename'])) {
2130 'Unable to extract symbolic link {'
2131 . $v_header[
'filename'] .
'}'
2136 if (($v_dest_file = @fopen($v_header[
'filename'],
"wb")) == 0) {
2138 'Error while opening {' . $v_header[
'filename']
2139 .
'} in write binary mode'
2143 $n = floor($v_header[
'size'] / 512);
2144 for ($i = 0; $i < $n; $i++) {
2146 fwrite($v_dest_file, $v_content, 512);
2148 if (($v_header[
'size'] % 512) != 0) {
2150 fwrite($v_dest_file, $v_content, ($v_header[
'size'] % 512));
2153 @fclose($v_dest_file);
2156 @chown($v_header[
'filename'], $v_header[
'uid']);
2157 @chgrp($v_header[
'filename'], $v_header[
'gid']);
2161 @touch($v_header[
'filename'], $v_header[
'mtime']);
2162 if ($v_header[
'mode'] & 0111) {
2164 $mode = fileperms($v_header[
'filename']) | (~umask() & 0111);
2165 @chmod($v_header[
'filename'], $mode);
2171 if (!is_file($v_header[
'filename'])) {
2173 'Extracted file ' . $v_header[
'filename']
2174 .
'does not exist. Archive may be corrupted.'
2179 $filesize = filesize($v_header[
'filename']);
2180 if ($filesize != $v_header[
'size']) {
2182 'Extracted file ' . $v_header[
'filename']
2183 .
' does not have the correct file size \''
2185 .
'\' (
' . $v_header['size
']
2186 . ' expected). Archive may be corrupted.
'
2192 $this->_jumpBlock(ceil(($v_header['size
'] / 512)));
2195 $this->_jumpBlock(ceil(($v_header['size
'] / 512)));
2198 /* TBC : Seems to be unused ...
2199 if ($this->_compress)
2200 $v_end_of_file = @gzeof($this->_file);
2202 $v_end_of_file = @feof($this->_file);
2205 if ($v_listing || $v_extract_file || $v_extraction_stopped) {
2206 // ----- Log extracted files
2207 if (($v_file_dir = dirname($v_header['filename
']))
2208 == $v_header['filename
']
2212 if ((substr($v_header['filename
'], 0, 1) == '/
') && ($v_file_dir == '')) {
2216 $p_list_detail[$v_nb++] = $v_header;
2217 if (is_array($p_file_list) && (count($p_list_detail) == count($p_file_list))) {
2229 public function _openAppend()
2231 if (filesize($this->_tarname) == 0) {
2232 return $this->_openWrite();
2235 if ($this->_compress) {
2238 if (!@rename($this->_tarname, $this->_tarname . ".tmp")) {
2240 'Error
while renaming \
'' . $this->_tarname
2241 .
'\' to temporary file \
'' . $this->_tarname
2247 if ($this->_compress_type ==
'gz') {
2248 $v_temp_tar = @gzopen($this->_tarname .
".tmp",
"rb");
2249 } elseif ($this->_compress_type ==
'bz2') {
2250 $v_temp_tar = @bzopen($this->_tarname .
".tmp",
"r");
2251 } elseif ($this->_compress_type ==
'lzma2') {
2252 $v_temp_tar = @xzopen($this->_tarname .
".tmp",
"r");
2256 if ($v_temp_tar == 0) {
2258 'Unable to open file \'' . $this->_tarname
2259 .
'.tmp\' in binary read mode'
2261 @rename($this->_tarname .
".tmp", $this->_tarname);
2266 @rename($this->_tarname .
".tmp", $this->_tarname);
2270 if ($this->_compress_type ==
'gz') {
2273 while (!@gzeof($v_temp_tar)) {
2274 $v_buffer = @gzread($v_temp_tar, 512);
2275 if ($v_buffer == ARCHIVE_TAR_END_BLOCK || strlen($v_buffer) == 0) {
2280 } elseif ($end_blocks > 0) {
2281 for ($i = 0; $i < $end_blocks; $i++) {
2286 $v_binary_data = pack(
"a512", $v_buffer);
2290 @gzclose($v_temp_tar);
2291 } elseif ($this->_compress_type ==
'bz2') {
2294 while (strlen($v_buffer = @bzread($v_temp_tar, 512)) > 0) {
2295 if ($v_buffer == ARCHIVE_TAR_END_BLOCK || strlen($v_buffer) == 0) {
2300 } elseif ($end_blocks > 0) {
2301 for ($i = 0; $i < $end_blocks; $i++) {
2306 $v_binary_data = pack(
"a512", $v_buffer);
2310 @bzclose($v_temp_tar);
2311 } elseif ($this->_compress_type ==
'lzma2') {
2314 while (strlen($v_buffer = @xzread($v_temp_tar, 512)) > 0) {
2315 if ($v_buffer == ARCHIVE_TAR_END_BLOCK || strlen($v_buffer) == 0) {
2320 } elseif ($end_blocks > 0) {
2321 for ($i = 0; $i < $end_blocks; $i++) {
2326 $v_binary_data = pack(
"a512", $v_buffer);
2330 @xzclose($v_temp_tar);
2333 if (!@unlink($this->_tarname .
".tmp")) {
2335 'Error while deleting temporary file \''
2336 . $this->_tarname .
'.tmp\''
2347 $v_size = filesize($this->_tarname);
2352 fseek($this->_file, $v_size - 1024);
2353 if (fread($this->_file, 512) == ARCHIVE_TAR_END_BLOCK) {
2354 fseek($this->_file, $v_size - 1024);
2355 } elseif (fread($this->_file, 512) == ARCHIVE_TAR_END_BLOCK) {
2356 fseek($this->_file, $v_size - 512);
2369 public function _append($p_filelist, $p_add_dir =
'', $p_remove_dir =
'')
2375 if ($this->
_addList($p_filelist, $p_add_dir, $p_remove_dir)) {
2395 if ((@is_dir($p_dir)) || ($p_dir ==
'')) {
2399 $p_parent_dir = dirname($p_dir);
2401 if (($p_parent_dir != $p_dir) &&
2402 ($p_parent_dir !=
'') &&
2408 if (!@mkdir($p_dir, 0777)) {
2409 $this->
_error(
"Unable to create directory '$p_dir'");
2424 private function _pathReduction($p_dir)
2431 $v_list = explode(
'/', $p_dir);
2434 for ($i =
sizeof($v_list) - 1; $i >= 0; $i--) {
2436 if ($v_list[$i] ==
".") {
2440 if ($v_list[$i] ==
"..") {
2444 if (($v_list[$i] ==
'')
2445 && ($i != (
sizeof($v_list) - 1))
2451 $v_result = $v_list[$i] . ($i != (
sizeof($v_list) - 1) ?
'/'
2459 if (defined(
'OS_WINDOWS') && OS_WINDOWS) {
2460 $v_result = strtr($v_result,
'\\',
'/');
2473 if (defined(
'OS_WINDOWS') && OS_WINDOWS) {
2475 if (($p_remove_disk_letter)
2476 && (($v_position = strpos($p_path,
':')) !=
false)
2478 $p_path = substr($p_path, $v_position + 1);
2481 if ((strpos($p_path,
'\\') > 0) || (substr($p_path, 0, 1) ==
'\\')) {
2482 $p_path = strtr($p_path,
'\\',
'/');