function getid3_tar(&$fd, &$ThisFileInfo) { $ThisFileInfo['fileformat'] = 'tar'; $ThisFileInfo['tar']['files'] = array(); $unpack_header = 'a100fname/a8mode/a8uid/a8gid/a12size/a12mtime/a8chksum/a1typflag/a100lnkname/a6magic/a2ver/a32uname/a32gname/a8devmaj/a8devmin/a155/prefix'; $null_512k = str_repeat("", 512); // end-of-file marker @fseek($fd, 0); while (!feof($fd)) { $buffer = fread($fd, 512); // check the block $checksum = 0; for ($i = 0; $i < 148; $i++) { $checksum += ord($buffer[$i]); } for ($i = 148; $i < 156; $i++) { $checksum += ord(' '); } for ($i = 156; $i < 512; $i++) { $checksum += ord($buffer[$i]); } $attr = unpack($unpack_header, $buffer); $name = trim(@$attr['fname']); $mode = octdec(trim(@$attr['mode'])); $uid = octdec(trim(@$attr['uid'])); $gid = octdec(trim(@$attr['gid'])); $size = octdec(trim(@$attr['size'])); $mtime = octdec(trim(@$attr['mtime'])); $chksum = octdec(trim(@$attr['chksum'])); $typflag = trim(@$attr['typflag']); $lnkname = trim(@$attr['lnkname']); $magic = trim(@$attr['magic']); $ver = trim(@$attr['ver']); $uname = trim(@$attr['uname']); $gname = trim(@$attr['gname']); $devmaj = octdec(trim(@$attr['devmaj'])); $devmin = octdec(trim(@$attr['devmin'])); $prefix = trim(@$attr['prefix']); if ($checksum == 256 && $chksum == 0) { // EOF Found break; } if ($prefix) { $name = $prefix . '/' . $name; } if (preg_match('#/$#', $name) && !$name) { $typeflag = 5; } if ($buffer == $null_512k) { // it's the end of the tar-file... break; } // Read to the next chunk fseek($fd, $size, SEEK_CUR); $diff = $size % 512; if ($diff != 0) { // Padding, throw away fseek($fd, 512 - $diff, SEEK_CUR); } // Protect against tar-files with garbage at the end if ($name == '') { break; } $ThisFileInfo['tar']['file_details'][$name] = array('name' => $name, 'mode_raw' => $mode, 'mode' => getid3_tar::display_perms($mode), 'uid' => $uid, 'gid' => $gid, 'size' => $size, 'mtime' => $mtime, 'chksum' => $chksum, 'typeflag' => getid3_tar::get_flag_type($typflag), 'linkname' => $lnkname, 'magic' => $magic, 'version' => $ver, 'uname' => $uname, 'gname' => $gname, 'devmajor' => $devmaj, 'devminor' => $devmin); $ThisFileInfo['tar']['files'] = getid3_lib::array_merge_clobber($ThisFileInfo['tar']['files'], getid3_lib::CreateDeepArray($ThisFileInfo['tar']['file_details'][$name]['name'], '/', $size)); } return true; }
function Analyze() { $info =& $this->getid3->info; $info['fileformat'] = 'tar'; $fp = $this->getid3->fp; fseek($fp, 0); $unpack_header = 'a100fname/a8mode/a8uid/a8gid/a12size/a12mtime/a8chksum/a1typflag/a100lnkname/a6magic/a2ver/a32uname/a32gname/a8devmaj/a8devmin/a155/prefix'; $null_512k = str_repeat("", 512); // end-of-file marker $already_warned = false; while (!feof($fp)) { $buffer = fread($fp, 512); // check the block $checksum = 0; for ($i = 0; $i < 148; $i++) { $checksum += ord(substr($buffer, $i, 1)); } for ($i = 148; $i < 156; $i++) { $checksum += ord(' '); } for ($i = 156; $i < 512; $i++) { $checksum += ord(substr($buffer, $i, 1)); } $attr = unpack($unpack_header, $buffer); $name = trim(@$attr['fname']); $mode = octdec(trim(@$attr['mode'])); $uid = octdec(trim(@$attr['uid'])); $gid = octdec(trim(@$attr['gid'])); $size = octdec(trim(@$attr['size'])); $mtime = octdec(trim(@$attr['mtime'])); $chksum = octdec(trim(@$attr['chksum'])); $typflag = trim(@$attr['typflag']); $lnkname = trim(@$attr['lnkname']); $magic = trim(@$attr['magic']); $ver = trim(@$attr['ver']); $uname = trim(@$attr['uname']); $gname = trim(@$attr['gname']); $devmaj = octdec(trim(@$attr['devmaj'])); $devmin = octdec(trim(@$attr['devmin'])); $prefix = trim(@$attr['prefix']); // EOF Found if ($checksum == 256 && $chksum == 0) { break; } // Check if filename if 7bit as spec requires if (!$already_warned) { for ($i = 0; $i < strlen($name); $i++) { if ($name[$i] < chr(32) || $name[$i] > chr(127)) { $this->getid3->warning('Some filenames contains extended characters, which breaks the tar specifation. This is not uncommon, but you will have to handle the character encoding for filenames yourself.'); $already_warned = true; break; } } } if ($prefix) { $name = $prefix . '/' . $name; } if (preg_match('#/$#', $name) && !$name) { $typeflag = 5; } // If it's the end of the tar-file... if ($buffer == $null_512k) { break; } // Protect against tar-files with garbage at the end if ($name == '') { break; } $info['tar']['file_details'][$name] = array('name' => $name, 'mode_raw' => $mode, 'mode' => getid3_tar::display_perms($mode), 'uid' => $uid, 'gid' => $gid, 'size' => $size, 'mtime' => $mtime, 'chksum' => $chksum, 'typeflag' => getid3_tar::get_flag_type($typflag), 'linkname' => $lnkname, 'magic' => $magic, 'version' => $ver, 'uname' => $uname, 'gname' => $gname, 'devmajor' => $devmaj, 'devminor' => $devmin); // Skip the next chunk fseek($fp, $size, SEEK_CUR); // Throw away padding if ($size % 512) { fseek($fp, 512 - $diff, SEEK_CUR); } } return true; }