⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 class.tar.php

📁 讲的是网络编程
💻 PHP
📖 第 1 页 / 共 2 页
字号:
<?php
// $Id: class.tar.php 2 2005-11-02 18:23:29Z skalpa $
/*
	package::i.tools

	php-downloader	v1.0	-	www.ipunkt.biz

	(c)	2002 - www.ipunkt.biz (rok)
*/

/*
=======================================================================
Name:
	tar Class

Author:
	Josh Barger <joshb@npt.com>

Description:
	This class reads and writes Tape-Archive (TAR) Files and Gzip
	compressed TAR files, which are mainly used on UNIX systems.
	This class works on both windows AND unix systems, and does
	NOT rely on external applications!! Woohoo!

Usage:
	Copyright (C) 2002  Josh Barger

	This library is free software; you can redistribute it and/or
	modify it under the terms of the GNU Lesser General Public
	License as published by the Free Software Foundation; either
	version 2.1 of the License, or (at your option) any later version.

	This library is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
	Lesser General Public License for more details at:
		http://www.gnu.org/copyleft/lesser.html

	If you use this script in your application/website, please
	send me an e-mail letting me know about it :)

Bugs:
	Please report any bugs you might find to my e-mail address
	at joshb@npt.com.  If you have already created a fix/patch
	for the bug, please do send it to me so I can incorporate it into my release.

Version History:
	1.0	04/10/2002	- InitialRelease

	2.0	04/11/2002	- Merged both tarReader and tarWriter
				  classes into one
				- Added support for gzipped tar files
				  Remember to name for .tar.gz or .tgz
				  if you use gzip compression!
				  :: THIS REQUIRES ZLIB EXTENSION ::
				- Added additional comments to
				  functions to help users
				- Added ability to remove files and
				  directories from archive
	2.1	04/12/2002	- Fixed serious bug in generating tar
				- Created another example file
				- Added check to make sure ZLIB is
				  installed before running GZIP
				  compression on TAR
	2.2	05/07/2002	- Added automatic detection of Gzipped
				  tar files (Thanks go to Jidgen Falch
				  for the idea)
				- Changed "private" functions to have
				  special function names beginning with
				  two underscores
=======================================================================
XOOPS changes onokazu <webmaster@xoops.org>

	12/25/2002 - Added flag to addFile() function for binary files

=======================================================================
*/

/**
 * tar Class
 * 
 * This class reads and writes Tape-Archive (TAR) Files and Gzip
 * compressed TAR files, which are mainly used on UNIX systems.
 * This class works on both windows AND unix systems, and does
 * NOT rely on external applications!! Woohoo!
 * 
 * @author	Josh Barger <joshb@npt.com>
 * @copyright	Copyright (C) 2002  Josh Barger
 * 
 * @package     kernel
 * @subpackage  core
 */
class tar
{
	/**#@+
	 * Unprocessed Archive Information
	 */
	var $filename;
	var $isGzipped;
	var $tar_file;
    /**#@-*/

	/**#@+
	 * Processed Archive Information
	 */
	var $files;
	var $directories;
	var $numFiles;
	var $numDirectories;
    /**#@-*/


	/**
	 * Class Constructor -- Does nothing...
	 */
	function tar()
	{
		return true;
	}

	/**
	 * Computes the unsigned Checksum of a file's header
     * to try to ensure valid file
     * 
     * @param	string  $bytestring
     * 
     * @access	private
	 */
	function __computeUnsignedChecksum($bytestring)
	{
		$unsigned_chksum = '';
		for($i=0; $i<512; $i++)
			$unsigned_chksum += ord($bytestring[$i]);
		for($i=0; $i<8; $i++)
			$unsigned_chksum -= ord($bytestring[148 + $i]);
		$unsigned_chksum += ord(" ") * 8;

		return $unsigned_chksum;
	}


	/**
	 * Converts a NULL padded string to a non-NULL padded string
	 * 
	 * @param   string  $string
     * 
	 * @return  string 
     * 
     * @access	private
	 **/
	function __parseNullPaddedString($string)
	{
		$position = strpos($string,chr(0));
		return substr($string,0,$position);
	}

	/**
	 * This function parses the current TAR file
	 * 
	 * @return  bool    always TRUE
     * 
     * @access	private
	 **/
	function __parseTar()
	{
		// Read Files from archive
		$tar_length = strlen($this->tar_file);
		$main_offset = 0;
		$this->numFiles = 0;
		while ( $main_offset < $tar_length ) {
			// If we read a block of 512 nulls, we are at the end of the archive
			if(substr($this->tar_file,$main_offset,512) == str_repeat(chr(0),512))
				break;

			// Parse file name
			$file_name		= $this->__parseNullPaddedString(substr($this->tar_file,$main_offset,100));

			// Parse the file mode
			$file_mode		= substr($this->tar_file,$main_offset + 100,8);

			// Parse the file user ID
			$file_uid		= octdec(substr($this->tar_file,$main_offset + 108,8));

			// Parse the file group ID
			$file_gid		= octdec(substr($this->tar_file,$main_offset + 116,8));

			// Parse the file size
			$file_size		= octdec(substr($this->tar_file,$main_offset + 124,12));

			// Parse the file update time - unix timestamp format
			$file_time		= octdec(substr($this->tar_file,$main_offset + 136,12));

			// Parse Checksum
			$file_chksum		= octdec(substr($this->tar_file,$main_offset + 148,6));

			// Parse user name
			$file_uname		= $this->__parseNullPaddedString(substr($this->tar_file,$main_offset + 265,32));

			// Parse Group name
			$file_gname		= $this->__parseNullPaddedString(substr($this->tar_file,$main_offset + 297,32));

			// Make sure our file is valid
			if($this->__computeUnsignedChecksum(substr($this->tar_file,$main_offset,512)) != $file_chksum)
				return false;

			// Parse File Contents
			$file_contents		= substr($this->tar_file,$main_offset + 512,$file_size);

			/*	### Unused Header Information ###
				$activeFile["typeflag"]		= substr($this->tar_file,$main_offset + 156,1);
				$activeFile["linkname"]		= substr($this->tar_file,$main_offset + 157,100);
				$activeFile["magic"]		= substr($this->tar_file,$main_offset + 257,6);
				$activeFile["version"]		= substr($this->tar_file,$main_offset + 263,2);
				$activeFile["devmajor"]		= substr($this->tar_file,$main_offset + 329,8);
				$activeFile["devminor"]		= substr($this->tar_file,$main_offset + 337,8);
				$activeFile["prefix"]		= substr($this->tar_file,$main_offset + 345,155);
				$activeFile["endheader"]	= substr($this->tar_file,$main_offset + 500,12);
			*/

			if ( $file_size > 0 ) {
				// Increment number of files
				$this->numFiles++;

				// Create us a new file in our array
				$activeFile = &$this->files[];

				// Asign Values
				$activeFile["name"]		= $file_name;
				$activeFile["mode"]		= $file_mode;
				$activeFile["size"]		= $file_size;
				$activeFile["time"]		= $file_time;
				$activeFile["user_id"]		= $file_uid;
				$activeFile["group_id"]		= $file_gid;
				$activeFile["user_name"]	= $file_uname;
				$activeFile["group_name"]	= $file_gname;
				$activeFile["checksum"]		= $file_chksum;
				$activeFile["file"]		= $file_contents;
			} else {
				// Increment number of directories
				$this->numDirectories++;

				// Create a new directory in our array
				$activeDir = &$this->directories[];

				// Assign values
				$activeDir["name"]		= $file_name;
				$activeDir["mode"]		= $file_mode;
				$activeDir["time"]		= $file_time;
				$activeDir["user_id"]		= $file_uid;
				$activeDir["group_id"]		= $file_gid;
				$activeDir["user_name"]		= $file_uname;
				$activeDir["group_name"]	= $file_gname;
				$activeDir["checksum"]		= $file_chksum;
			}

			// Move our offset the number of blocks we have processed
			$main_offset += 512 + (ceil($file_size / 512) * 512);
		}

		return true;
	}

	/**
	 * Read a non gzipped tar file in for processing.
	 * 
	 * @param   string  $filename   full filename
	 * @return  bool    always TRUE
     * 
     * @access	private
	 **/
	function __readTar($filename='')
	{
		// Set the filename to load
		if(!$filename)
			$filename = $this->filename;

		// Read in the TAR file
		$fp = fopen($filename,"rb");
		$this->tar_file = fread($fp,filesize($filename));
		fclose($fp);

		if($this->tar_file[0] == chr(31) && $this->tar_file[1] == chr(139) && $this->tar_file[2] == chr(8)) {
			if(!function_exists("gzinflate"))
				return false;

			$this->isGzipped = true;

			$this->tar_file = gzinflate(substr($this->tar_file,10,-4));
		}

		// Parse the TAR file
		$this->__parseTar();

		return true;
	}

	/**
	 * Generates a TAR file from the processed data
	 * 
	 * @return  bool    always TRUE
     * 
     * @access	private
	 **/
	function __generateTAR()
	{
		// Clear any data currently in $this->tar_file
		unset($this->tar_file);

		// Generate Records for each directory, if we have directories
		if($this->numDirectories > 0) {
			foreach($this->directories as $key => $information) {
				unset($header);

				// Generate tar header for this directory
				// Filename, Permissions, UID, GID, size, Time, checksum, typeflag, linkname, magic, version, user name, group name, devmajor, devminor, prefix, end
				$header .= str_pad($information["name"],100,chr(0));
				$header .= str_pad(decoct($information["mode"]),7,"0",STR_PAD_LEFT) . chr(0);
				$header .= str_pad(decoct($information["user_id"]),7,"0",STR_PAD_LEFT) . chr(0);
				$header .= str_pad(decoct($information["group_id"]),7,"0",STR_PAD_LEFT) . chr(0);
				$header .= str_pad(decoct(0),11,"0",STR_PAD_LEFT) . chr(0);
				$header .= str_pad(decoct($information["time"]),11,"0",STR_PAD_LEFT) . chr(0);
				$header .= str_repeat(" ",8);
				$header .= "5";
				$header .= str_repeat(chr(0),100);
				$header .= str_pad("ustar",6,chr(32));
				$header .= chr(32) . chr(0);
				$header .= str_pad("",32,chr(0));
				$header .= str_pad("",32,chr(0));
				$header .= str_repeat(chr(0),8);
				$header .= str_repeat(chr(0),8);
				$header .= str_repeat(chr(0),155);
				$header .= str_repeat(chr(0),12);

				// Compute header checksum
				$checksum = str_pad(decoct($this->__computeUnsignedChecksum($header)),6,"0",STR_PAD_LEFT);
				for($i=0; $i<6; $i++) {
					$header[(148 + $i)] = substr($checksum,$i,1);
				}
				$header[154] = chr(0);
				$header[155] = chr(32);

				// Add new tar formatted data to tar file contents
				$this->tar_file .= $header;
			}
		}

		// Generate Records for each file, if we have files (We should...)
		if($this->numFiles > 0) {
			$this->tar_file = '';
			foreach($this->files as $key => $information) {
				unset($header);

				// Generate the TAR header for this file
				// Filename, Permissions, UID, GID, size, Time, checksum, typeflag, linkname, magic, version, user name, group name, devmajor, devminor, prefix, end
				$header = str_pad($information["name"],100,chr(0));
				$header .= str_pad(decoct($information["mode"]),7,"0",STR_PAD_LEFT) . chr(0);
				$header .= str_pad(decoct($information["user_id"]),7,"0",STR_PAD_LEFT) . chr(0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -