📄 tar.php
字号:
} //----------------------------------------- // add files: // Takes an array of files, and adds them to the tar file // Optionally takes a path to use as root for the tar file - if omitted, it // assumes the current working directory is the tarball root. Be careful with // this, or you may get unexpected results -especially when attempting to read // and add files to the tarball. // EXAMPLE DIR STRUCTURE // /usr/home/somedir/forums/sources // BRIEF: To tar up the sources directory // $files = array( 'sources/somescript.php', 'sources/anothersscript.php' ); // If CWD is 'somedir', you'll need to use $tar->add_files( $files, "/usr/home/somedir/forums" ); // or it'll attempt to open /usr/home/somedir/sources/somescript.php - which would result // in an error. Either that, or use: // chdir("/usr/home/somedir/forums"); // $tar->add_files( $files ); //----------------------------------------- function add_files( $files, $root_path="" ) { // Do we a root path to change into? if ($root_path != "") { chdir($root_path); } $count = 0; foreach ($files as $file) { // is it a Mac OS X work file? if ( preg_match("/\.ds_store/i", $file ) ) { continue; } $typeflag = 0; $data = ""; $linkname = ""; $stat = stat($file); // Did stat fail? if (! is_array($stat) ) { $this->warnings[] = sprintf( $this->ipsclass->lang['error_tar14'], $file ); continue; } $mode = fileperms($file); $uid = $stat[4]; $gid = $stat[5]; $rdev = $stat[6]; $size = filesize($file); $mtime = filemtime($file); if (is_file($file)) { // It's a plain file, so lets suck it up $typeflag = 0; if ( $FH = fopen($file, 'rb') ) { $data = fread( $FH, filesize($file) ); fclose($FH); } else { $this->warnings[] = sprintf( $this->ipsclass->lang['error_tar15'], $file ); continue; } } else if (is_link($file)) { $typeflag = 1; $linkname = @readlink($file); } else if (is_dir($file)) { $typeflag = 5; } else { // Sockets, Pipes and char/block specials are not // supported, so - lets use a silly value to keep the // tar ball legitimate. $typeflag = 9; } // Add this data to our in memory tar file $this->tar_in_mem[] = array ( 'name' => $file, 'mode' => $mode, 'uid' => $uid, 'gid' => $gid, 'size' => strlen($data), 'mtime' => $mtime, 'chksum' => " ", 'typeflag' => $typeflag, 'linkname' => $linkname, 'magic' => "ustar\0", 'version' => '00', 'uname' => 'unknown', 'gname' => 'unknown', 'devmajor' => "", 'devminor' => "", 'prefix' => "", 'data' => $data ); // Clear the stat cache @clearstatcache(); $count++; } @chdir($this->current_dir); //Return the number of files to anyone who's interested return $count; } //----------------------------------------- // write_tar: // Writes the tarball into the directory specified in new_tar with a filename // specified in new_tar //----------------------------------------- function write_tar() { if ($this->tarfile_path_name == "") { $this->error = $this->ipsclass->lang['error_tar16']; return; } if ( count($this->tar_in_mem) < 1 ) { $this->error = $this->ipsclass->lang['error_tar17']; return; } $tardata = ""; foreach ($this->tar_in_mem as $file) { $prefix = ""; $tmp = ""; $last = ""; // make sure the filename isn't longer than 99 characters. if (strlen($file['name']) > 99) { $pos = strrpos( $file['name'], "/" ); if (is_string($pos) && !$pos) { // filename alone is longer than 99 characters! $this->error[] = sprintf( $this->ipsclass->lang['error_tar18'], $file['name'] ); continue; } $prefix = substr( $file['name'], 0 , $pos ); // Move the path to the prefix $file['name'] = substr( $file['name'], ($pos+1)); if (strlen($prefix) > 154) { $this->error[] = $this->ipsclass->lang['error_tar19']; continue; } } // BEGIN FORMATTING (a8a1a100) $mode = sprintf("%6s ", decoct($file['mode'])); $uid = sprintf("%6s ", decoct($file['uid'])); $gid = sprintf("%6s ", decoct($file['gid'])); $size = sprintf("%11s ", decoct($file['size'])); $mtime = sprintf("%11s ", decoct($file['mtime'])); $tmp = pack("a100a8a8a8a12a12",$file['name'],$mode,$uid,$gid,$size,$mtime); $last = pack("a1" , $file['typeflag']); $last .= pack("a100" , $file['linkname']); $last .= pack("a6", "ustar"); // magic $last .= pack("a2", "" ); // version $last .= pack("a32", $file['uname']); $last .= pack("a32", $file['gname']); $last .= pack("a8", ""); // devmajor $last .= pack("a8", ""); // devminor $last .= pack("a155", $prefix); //$last .= pack("a12", ""); $test_len = $tmp . $last . "12345678"; $last .= $this->internal_build_string( "\0" , ($this->tar_header_length - strlen($test_len)) ); // Here comes the science bit, handling // the checksum. $checksum = 0; for ($i = 0 ; $i < 148 ; $i++ ) { $checksum += ord( substr($tmp, $i, 1) ); } for ($i = 148 ; $i < 156 ; $i++) { $checksum += ord(' '); } for ($i = 156, $j = 0 ; $i < 512 ; $i++, $j++) { $checksum += ord( substr($last, $j, 1) ); } $checksum = sprintf( "%6s ", decoct($checksum) ); $tmp .= pack("a8", $checksum); $tmp .= $last; $tmp .= $file['data']; // Tidy up this chunk to the power of 512 if ($file['size'] > 0) { if ($file['size'] % 512 != 0) { $homer = $this->internal_build_string( "\0" , (512 - ($file['size'] % 512)) ); $tmp .= $homer; } } $tardata .= $tmp; } // Add the footer $tardata .= pack( "a512", "" ); // print it to the tar file $FH = fopen( $this->tarfile_path_name, 'wb' ); fputs( $FH, $tardata, strlen($tardata) ); fclose($FH); @chmod( $this->tarfile_path_name, 0777); // Done.. } //----------------------------------------- // Read the tarball - builds an associative array //----------------------------------------- function read_tar() { $filename = $this->tarfile_path_name; if ($filename == "") { $this->error = $this->ipsclass->lang['error_tar21']; return array(); } if (! file_exists($filename) ) { $this->error = $this->ipsclass->lang['error_tar22'] . $filename; return array(); } $tar_info = array(); $this->tar_filename = $filename; // Open up the tar file and start the loop if (! $FH = fopen( $filename , 'rb' ) ) { $this->error = sprintf( $this->ipsclass->lang['error_tar23'], $filename ); return array(); } // Grrr, perl allows spaces, PHP doesn't. Pack strings are hard to read without // them, so to save my sanity, I'll create them with spaces and remove them here $this->tar_unpack_header = preg_replace( "/\s/", "" , $this->tar_unpack_header); while (!feof($FH)) { $buffer = fread( $FH , $this->tar_header_length ); // 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) ); } $fa = unpack( $this->tar_unpack_header, $buffer); $name = trim($fa[filename]); $mode = OctDec(trim($fa[mode])); $uid = OctDec(trim($fa[uid])); $gid = OctDec(trim($fa[gid])); $size = OctDec(trim($fa[size])); $mtime = OctDec(trim($fa[mtime])); $chksum = OctDec(trim($fa[chksum])); $typeflag = trim($fa[typeflag]); $linkname = trim($fa[linkname]); $magic = trim($fa[magic]); $version = trim($fa[version]); $uname = trim($fa[uname]); $gname = trim($fa[gname]); $devmajor = OctDec(trim($fa[devmajor])); $devminor = OctDec(trim($fa[devminor])); $prefix = trim($fa[prefix]); if ( ($checksum == 256) && ($chksum == 0) ) { //EOF! break; } if ($prefix) { $name = $prefix.'/'.$name; } // Some broken tars don't set the type flag // correctly for directories, so we assume that // if it ends in / it's a directory... if ( (preg_match( "#/$#" , $name)) and (! $name) ) { $typeflag = 5; } // If it's the end of the tarball... $test = $this->internal_build_string( '\0' , 512 ); if ($buffer == $test) { break; } // Read the next chunk $data = fread( $FH, $size ); if (strlen($data) != $size) { $this->error = $this->ipsclass->lang['error_tar24']; fclose( $FH ); return array(); } $diff = $size % 512; if ($diff != 0) { // Padding, throw away $crap = fread( $FH, (512-$diff) ); } // Protect against tarfiles with garbage at the end if ($name == "") { break; } $tar_info[] = array ( 'name' => $name, 'mode' => $mode, 'uid' => $uid, 'gid' => $gid, 'size' => $size, 'mtime' => $mtime, 'chksum' => $chksum, 'typeflag' => $typeflag, 'linkname' => $linkname, 'magic' => $magic, 'version' => $version, 'uname' => $uname, 'gname' => $gname, 'devmajor' => $devmajor, 'devminor' => $devminor, 'prefix' => $prefix, 'data' => $data ); } fclose($FH); return $tar_info; } //-----------------------------------------// INTERNAL FUNCTIONS - These should NOT be called outside this module//+------------------------------------------------------------------------------ //----------------------------------------- // build_string: Builds a repititive string //----------------------------------------- function internal_build_string($string="", $times=0) { $return = ""; for ($i=0 ; $i < $times ; ++$i ) { $return .= $string; } return $return; } }?>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -