atholon Posted January 28, 2008 Share Posted January 28, 2008 Hi, There is an error with invision's tar.php file for PHP5 for some reason something isn`t compatible with PHP5 so it gives this error: Warning: unpack() [function.unpack]: Invalid format type p in /home/sitename/public_html/forum/sources/lib/tar.php on line 739 Warning: fread() [function.fread]: Length parameter must be greater than 0 in /home/sitename/public_html/forum/sources/lib/tar.php on line 783 The code is kind of long but if someone could help out I am sure that a lot of people would appreciate it. <?php /* +-------------------------------------------------------------------------- | Invision Power Board v1.3.1 Final | ======================================== | by Matthew Mecham | (c) 2001 - 2003 Invision Power Services | http://www.invisionpower.com | ======================================== | Web: http://www.invisionboard.com | Time: Fri, 27 Aug 2004 05:36:27 GMT | Release: 253d4945e04aa2763d518b21140c73e5 | Email: [email protected] | Licence Info: http://www.invisionboard.com/?license +--------------------------------------------------------------------------- | | > GNU Tar creation and extraction module | > Module written by Matt Mecham | > Usage style based on the C and Perl GNU modules | > Will only work with PHP 4+ | | > Date started: 15th Feb 2002 | | > Module Version Number: 1.0.0 | > Module Author: Matthew Mecham +-------------------------------------------------------------------------- | | QUOTE OF THE MODULE: | If you can't find a program the does what you want it to do, write your | own. | +-------------------------------------------------------------------------- | | LICENCE OF USE (THIS MODULE ONLY) | | This module has been created and released under the GNU licence and may be | freely used and distributed. If you find some space to credit us in your source | code, it'll be appreciated. | | Report all bugs / improvements to [email protected] | | NOTE: This does not affect the current licence for the rest of the Invision | board code. I just wanted to share this module as there is a lack of other | decent tar proggies for PHP. | +-------------------------------------------------------------------------- */ /************************************************************* | | EXTRACTION USAGE: | | $tar = new tar(); | $tar->new_tar("/foo/bar", "myTar.tar"); | $files = $tar->list_files(); | $tar->extract_files( "/extract/to/here/dir" ); | | CREATION USAGE: | | $tar = new tar(); | $tar->new_tar("/foo/bar" , "myNewTar.tar"); | $tar->current_dir("/foo" ); //Optional - tells the script which dir we are in | to syncronise file creation from the tarball | $tar->add_files( $file_names_with_path_array ); | (or $tar->add_directory( "/foo/bar/myDir" ); to archive a complete dir) | $tar->write_tar(); | *************************************************************/ class tar { var $tar_header_length = '512'; var $tar_unpack_header = 'a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8chksum/a1typeflag/a100linkname/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor/a155/prefix'; var $tar_pack_header = 'A100 A8 A8 A8 A12 A12 A8 A1 A100 A6 A2 A32 A32 A8 A8 A155'; var $current_dir = ""; var $unpack_dir = ""; var $pack_dir = ""; var $error = ""; var $work_dir = array(); var $tar_in_mem = array(); var $tar_filename = ""; var $filehandle = ""; var $warnings = array(); var $attributes = array(); var $tarfile_name = ""; var $tarfile_path = ""; var $tarfile_path_name = ""; var $workfiles = array(); //+-------------------------------------------------------------------------- // CONSTRUCTOR: Attempt to guess the current working dir. //+-------------------------------------------------------------------------- function tar() { global $HTTP_SERVER_VARS; if ($this_dir = getcwd()) { $this->current_dir = $this_dir; } else if (isset($HTTP_SERVER_VARS['DOCUMENT_ROOT'])) { $this->current_dir = $HTTP_SERVER_VARS['DOCUMENT_ROOT']; } else { $this->current_dir = './'; } // Set some attributes, these can be overriden later $this->attributes = array( 'over_write_existing' => 0, 'over_write_newer' => 0, 'remove_tar_file' => 0, 'remove_original_files' => 0, ); } //+-------------------------------------------------------------------------- // Set the tarname. If we are extracting a tarball, then it must be the // path to the tarball, and it's name (eg: $tar->new_tar("/foo/bar" ,'myTar.tar') // or if we are creating a tar, then it must be the path and name of the tar file // to create. //+-------------------------------------------------------------------------- function new_tar($tarpath, $tarname) { $this->tarfile_name = $tarname; $this->tarfile_path = $tarpath; // Make sure there isn't a trailing slash on the path $this->tarfile_path = preg_replace( "#[/\\\]$#" , "" , $this->tarfile_path ); $this->tarfile_path_name = $this->tarfile_path .'/'. $this->tarfile_name; } //+-------------------------------------------------------------------------- // Easy way to overwrite defaults //+-------------------------------------------------------------------------- function over_write_existing() { $this->attributes['over_write_existing'] = 1; } function over_write_newer() { $this->attributes['over_write_newer'] = 1; } function remove_tar_file() { $this->attributes['remove_tar_file'] = 1; } function remove_original_files() { $this->attributes['remove_original_files'] = 1; } //+-------------------------------------------------------------------------- // User assigns the root directory for the tar ball creation/extraction //+-------------------------------------------------------------------------- function current_dir($dir = "") { $this->current_dir = $dir; } //+-------------------------------------------------------------------------- // list files: returns an array with all the filenames in the tar file //+-------------------------------------------------------------------------- function list_files($advanced="") { // $advanced == "" - return name only // $advanced == 1 - return name, size, mtime, mode $data = $this->read_tar(); $final = array(); foreach($data as $d) { if ($advanced == 1) { $final[] = array ( 'name' => $d['name'], 'size' => $d['size'], 'mtime' => $d['mtime'], 'mode' => substr(decoct( $d['mode'] ), -4), ); } else { $final[] = $d['name']; } } return $final; } //+-------------------------------------------------------------------------- // Add a directory to the tar files. // $tar->add_directory( str(TO DIRECTORY) ) // Can be used in the following methods. // $tar->add_directory( "/foo/bar" ); // $tar->write_tar( "/foo/bar" ); //+-------------------------------------------------------------------------- function add_directory( $dir ) { $this->error = ""; // Make sure the $to_dir is pointing to a valid dir, or we error // and return if (! is_dir($dir) ) { $this->error = "Extract files error: Destination directory ($to_dir) does not exist"; return FALSE; } $cur_dir = getcwd(); chdir($dir); $this->get_dir_contents("./"); $this->add_files($this->workfiles, $dir); chdir($cur_dir); } //------------------------------------- function get_dir_contents( $dir ) { $dir = preg_replace( "#/$#", "", $dir ); if ( file_exists($dir) ) { if ( is_dir($dir) ) { $handle = opendir($dir); while (($filename = readdir($handle)) !== false) { if (($filename != ".") && ($filename != "..")) { if (is_dir($dir."/".$filename)) { $this->get_dir_contents($dir."/".$filename); } else { $this->workfiles[] = $dir."/".$filename; } } } closedir($handle); } else { $this->error = "$dir is not a directory"; return FALSE; } } else { $this->error = "Could not locate $dir"; return; } } //+-------------------------------------------------------------------------- // Extract the tarball // $tar->extract_files( str(TO DIRECTORY), [ array( FILENAMES ) ] ) // Can be used in the following methods. // $tar->extract( "/foo/bar" , $files ); // This will seek out the files in the user array and extract them // $tar->extract( "/foo/bar" ); // Will extract the complete tar file into the user specified directory //+-------------------------------------------------------------------------- function extract_files( $to_dir, $files="" ) { $this->error = ""; // Make sure the $to_dir is pointing to a valid dir, or we error // and return if (! is_dir($to_dir) ) { $this->error = "Extract files error: Destination directory ($to_dir) does not exist"; return; } //--------------------------------------------- // change into the directory chosen by the user. //--------------------------------------------- chdir($to_dir); $cur_dir = getcwd(); $to_dir_slash = $to_dir . "/"; //+------------------------------ // Get the file info from the tar //+------------------------------ $in_files = $this->read_tar(); if ($this->error != "") { return; } foreach ($in_files as $k => $file) { //--------------------------------------------- // Are we choosing which files to extract? //--------------------------------------------- if (is_array($files)) { if (! in_array($file['name'], $files) ) { continue; } } chdir($cur_dir); //--------------------------------------------- // GNU TAR format dictates that all paths *must* be in the *nix // format - if this is not the case, blame the tar vendor, not me! //--------------------------------------------- if ( preg_match("#/#", $file['name']) ) { $path_info = explode( "/" , $file['name'] ); $file_name = array_pop($path_info); } else { $path_info = array(); $file_name = $file['name']; } //--------------------------------------------- // If we have a path, then we must build the directory tree //--------------------------------------------- if (count($path_info) > 0) { foreach($path_info as $dir_component) { if ($dir_component == "") { continue; } if ( (file_exists($dir_component)) && (! is_dir($dir_component)) ) { $this->warnings[] = "WARNING: $dir_component exists, but is not a directory"; continue; } if (! is_dir($dir_component)) { mkdir( $dir_component, 0777); chmod( $dir_component, 0777); } if (! @chdir($dir_component)) { $this->warnings[] = "ERROR: CHDIR to $dir_component FAILED!"; } } } //--------------------------------------------- // check the typeflags, and work accordingly //--------------------------------------------- if (($file['typeflag'] == 0) or (!$file['typeflag']) or ($file['typeflag'] == "")) { if ( $FH = fopen($file_name, "wb") ) { fputs( $FH, $file['data'], strlen($file['data']) ); fclose($FH); } else { $this->warnings[] = "Could not write data to $file_name"; } } else if ($file['typeflag'] == 5) { if ( (file_exists($file_name)) && (! is_dir($file_name)) ) { $this->warnings[] = "$file_name exists, but is not a directory"; continue; } if (! is_dir($file_name)) { @mkdir( $file_name, 0777); } } else if ($file['typeflag'] == 6) { $this->warnings[] = "Cannot handle named pipes"; continue; } else if ($file['typeflag'] == 1) { $this->warnings[] = "Cannot handle system links"; } else if ($file['typeflag'] == 4) { $this->warnings[] = "Cannot handle device files"; } else if ($file['typeflag'] == 3) { $this->warnings[] = "Cannot handle device files"; } else { $this->warnings[] = "Unknown typeflag found"; } if (! @chmod( $file_name, $file['mode'] ) ) { $this->warnings[] = "ERROR: CHMOD $mode on $file_name FAILED!"; } @touch( $file_name, $file['mtime'] ); } // Return to the "real" directory the scripts are in @chdir($this->current_dir); } //+-------------------------------------------------------------------------- // 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[] = "Error: Stat failed on $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[] = "ERROR: Failed to open $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 = 'No filename or path was specified to create a new tar file'; return; } if ( count($this->tar_in_mem) < 1 ) { $this->error = 'No data to write to the new tar file'; 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[] = "Filename {$file['name']} exceeds the length allowed by GNU Tape ARchives"; 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[] = "File path exceeds the length allowed by GNU Tape ARchives"; 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 = 'No filename specified when attempting to read a tar file'; return array(); } if (! file_exists($filename) ) { $this->error = 'Cannot locate the file '.$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 = "Cannot open $filename for reading"; 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 = "Read error on tar file"; 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; } } ?> Link to comment https://forums.phpfreaks.com/topic/88137-solved-tarphp-in-invisionboard-13/ Share on other sites More sharing options...
atholon Posted January 28, 2008 Author Share Posted January 28, 2008 So I was looking on the internet to find out what possibly could have been wrong with the tar.php file. It was something so simple Tinkerbell from www.ipbdownloads.com had the answer: Open sources/lib/tar.php and find: CODEvar $tar_unpack_header = 'a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8chksum/a1typeflag/ a100linkname/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor/a155/prefix'; Replace it with: CODEvar $tar_unpack_header = 'a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8chksum/a1typeflag/ a100linkname/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor/a155'; Whala! If you have any other issues with PHP 5 check out my PHP 5/SQL post. Link to comment https://forums.phpfreaks.com/topic/88137-solved-tarphp-in-invisionboard-13/#findComment-451018 Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.