Seite 2 von 2

Verfasst: 22.02.2005 15:06
von Blutgerinsel
Gumfuzi hat geschrieben: Aber sie haben mir angeboten, den TAR-Befehl zu aktivieren (unter einem anderen Dateinamen) - und mit TAR kann man lt. deren Mail nur Dateien und keine Strukturen packen?
ja :wink:
Tar wird in Verbindung mit gzip bzw. bzip2 verwendet....
Letztere beide komprimieren jede Datei für sich eigenständig und da dies unpraktisch ist verwendet man zusätzlich tar um aus der breiten Masse genau eine File zu bekommen.....

Tar bietet auch entsprechendes Interface zu gzip und bzip2......
Parameter j bzw. z stehen für eines von beiden welches genau weiss ich im Moment auch nicht. Dafür gibts ja auch man tar bzw. tar --help etc.

BTW: @Loewenherz: wget bringt ihm relativ wenig unter einem Windows System. Er hat ja so wie es aussieht keinen Shell Zugang :wink:

Verfasst: 22.02.2005 15:25
von Gumfuzi
brauche ich da vollen root-Zuriff bzw. funzt das auch auf einem Apache-Server?
*edit*
habe es gerade gesehen, da braucht man root-zugriff... :(

@Blutgerinsel: danke für die Erklärung

@all:
gibt es keine Möglichkeit, mit dem "system()"-Befehl oder anderen Befehlen die Dateien zu komprimieren - ev. mit einer Zip-Variante (muss ja nicht gleich gzip sein), die in PHP gecodet ist oder soetwas...

Verfasst: 22.02.2005 15:49
von Blutgerinsel
Versuch mal die Klasse hier arbeitet mit pack(); und soll angeblich wunderbar sein :wink:

Das Snippet hab ich mir mal lokal gespeichert, wo es das online gibt ka.
Jedenfalls leg ich das nicht auf meinen Webspace....

Code: Alles auswählen

<?php
/*--------------------------------------------------
 | TAR/GZIP/ZIP ARCHIVE CLASSES
 | By Devin Doucette
 | Copyright (c) 2003 Devin Doucette
 | Email: darksnoopy@shaw.ca
 +--------------------------------------------------
 | Email bugs/suggestions to darksnoopy@shaw.ca
 +--------------------------------------------------
 | This script has been created and released under
 | the GNU GPL and is free to use and redistribute
 | only if this copyright statement is not removed
 +--------------------------------------------------*/

/*------------------------------------------------------------
 | To create tar files:
 | $example = new tarfile($cwd,$flags); // args optional
 | -current working directory
 | -flags (array):
 |  -overwrite - whether to overwrite existing files or return
 |    an error message
 |  -defaultperms - default file permissions (like chmod(),
 |    must include 0 in front of value [eg. 0777, 0644])
 |  -recursesd[1,0] - whether or not to include subdirs
 |  -storepath[1,0] - whether or not to store relative paths
 |  -replacestats[array] - values to replace those from files
 |   -mode - same as the result of a fileperms() call
 |   -uid/gid - user/group id
 |   -time - timestamp
 |   -type - file type (5=dir,1=link,0=file)
 |   -link - the file that is linked to
 |   -path - only supported in USTAR, not recommended
 +------------------------------------------------------------*/

/*------------------------------------------------------------
 | To create gzip files:
 | $example = new gzfile($cwd,$flags); // args optional
 | -current working directory
 | -flags (array):
 |  -overwrite - whether to overwrite existing files or return
 |    an error message
 |  -defaultperms - default file permissions (like chmod(),
 |    must include 0 in front of value [eg. 0777, 0644])
 +------------------------------------------------------------*/

/*------------------------------------------------------------
 | To create zip files:
 | $example = new zipfile($cwd,$flags); // args optional
 | -current working directory
 | -flags (array):
 |  -overwrite - whether to overwrite existing files or return
 |    an error message
 |  -defaultperms - default file permissions (like chmod(),
 |    must include 0 in front of value [eg. 0777, 0644])
 |  -time - timestamp to use to replace the mtime from files
 |  -recursesd[1,0] - whether or not to include subdirs
 |  -storepath[1,0] - whether or not to store relative paths
 |  -level[0-9] - compression level (0 = none, 9 = max)
 |  -comment - comment to add to the archive
 +------------------------------------------------------------*/

/*------------------------------------------------------------
 | To add files:
 | $example->addfile($data,$filename,$flags);
 | -data - file contents
 | -filename - name of file to be put in archive
 | -flags (all flags are optional)
 | -flags (tar) [array]: -same flags as tarfile()
 | -flags (gzip) [string]: -comment to add to archive
 | -flags (zip) [array] -time - last modification time
 |
 | $example->addfiles($filelist);
 | -filelist - array of file names relative to CWD
 |
 | $example->adddirectories($dirlist);
 | -dirlist - array of directory names relative to CWD
 +------------------------------------------------------------*/

/*------------------------------------------------------------
 | To output files:
 | $example->getdata();
 | -returns file contents
 |
 | $example->filedownload($filename);
 | -filename - the name to give the file that is being sent
 |
 | $example->filewrite($filename,$perms); // perms optional
 | -filename - the name (including path) of the file to write
 | -perms - permissions to give the file after it is written
 +------------------------------------------------------------*/

/*------------------------------------------------------------
 | To extract files (tar and gzip)
 | $example->extract($data);
 | -data - data to extract files from
 | -returns an array containing file attributes and contents
 |
 | $example->extractfile($filename);
 | -filename - the name (including path) of the file to use
 | -returns an array containing file attributes and contents
 |
 | Both functions will return a string containing any errors
 +------------------------------------------------------------*/

class tarfile extends archive {
	var $cwd			= "./";
	var $tardata		= "";
	var $defaultflags	= array(
		'mode'	=> 0,
		'uid'	=> 0,
		'gid'	=> 0,
		'time'	=> 0,
		'type'	=> 0,
		'link'	=> "",
		'path'	=> "",
	);
	var $replacestats	= array();
	var $recursesd		= 1;
	var $storepath		= 1;

	function tarfile($cwd="./",$flags=array()) {
		$this->cwd = $cwd;
		$this->defaultflags['mode'] = decoct(0x8000 | 0x0100 | 0x0080 | 0x0020 | 0x0004);
		$this->defaultflags['time'] = time();
		if(isset($flags['recursesd']))
			$this->recursesd = $flags['recursesd'];
		if(isset($flags['storepath']))
			$this->storepath = $flags['storepath'];
		if(isset($flags['replacestats'])) {
			if(is_array($flags['replacestats'])) {
				if(isset($flags['replacestats']['mode']))
					$this->replacestats['mode'] = $flags['replacestats']['mode'];
				if(isset($flags['replacestats']['time']))
					$this->replacestats['time'] = $flags['replacestats']['time'];
			}
			else if($flags['replacestats'] == 1) {
				$this->replacestats['mode'] = $this->defaultflags['mode'];
				$this->replacestats['time'] = $this->defaultflags['time'];
			}
		}

		$this->archive($flags);
	}

	function addfile($data,$filename,$flags=array()) {
		if(strlen($filename) > 99)
			return;

		$flags['mode'] = isset($this->replacestats['mode'])? $this->replacestats['mode'] : (isset($flags['mode'])? $flags['mode'] : $this->defaultflags['mode']);
		$flags['uid'] = isset($flags['uid'])? $flags['uid'] : $this->defaultflags['uid'];
		$flags['gid'] = isset($flags['gid'])? $flags['gid'] : $this->defaultflags['gid'];
		$flags['time'] = isset($this->replacestats['time'])? $this->replacestats['time'] : (isset($flags['time'])? $flags['time'] : $this->defaultflags['time']);
		$flags['type'] = isset($flags['type'])? $flags['type'] : $this->defaultflags['type'];
		$flags['link'] = isset($flags['link'])? $flags['link'] : $this->defaultflags['link'];
		$flags['path'] = isset($flags['path'])? $flags['path'] : $this->defaultflags['path'];
		$flags['size'] = isset($flags['size'])? $flags['size'] : strlen($data);

		if($this->storepath != 1) {
			$filename = strstr($filename,"/")? substr($filename,strrpos($filename,"/")+1) : $filename;
			$flags['path'] = "";
		}
		else
			$filename = preg_replace("/^(\.{1,2}(\/|\\\))+/","",$filename);

		$blockbeg = pack("a100a8a8a8a12a12",$filename,$flags['mode'],sprintf("%6s ",decoct($flags['uid'])),sprintf("%6s ",decoct($flags['gid'])),sprintf("%11s ",decoct($flags['size'])),sprintf("%11s ",decoct($flags['time'])));
		$blockend = pack("a1a100a6a2a32a32a8a8a155",$flags['type'],$flags['link'],"ustar","00","Unknown","Unknown","","",$flags['path']);

		$checksum = 0;
		for($i = 0; $i < 148; $i++)
			$checksum += ord(substr($blockbeg,$i,1));
		for($i = 148; $i < 156; $i++)
			$checksum += ord(" ");
		for($i = 156; $i < 512; $i++)
			$checksum += ord(substr($blockend,$i-156,1));
		$checksum = pack("a8",sprintf("%6s ",decoct($checksum)));

		if($flags['size'] % 512 > 0)
			$data .= $this->nullpad(512 - $flags['size'] % 512);

		$this->tardata .= $blockbeg . $checksum . $blockend . pack("a12","") . $data;
	}

	function addfiles($filelist) {
		$pwd = getcwd();
		@chdir($this->cwd);

		foreach($filelist as $current) {
			$file = array();

			if($this->storepath != 1)
				$file['name'] = strstr($current,"/")? substr($current,strrpos($current,"/")+1) : $current;
			else
				$file['name'] = preg_replace("/^(\.{1,2}(\/|\\\))+/","",$current);

			$file['mode'] = @fileperms($current);
			if($file['mode'] & 0x4000)
				$file['type'] = 5;	// Directory
			else if($file['mode'] & 0x8000)
				$file['type'] = 0;	// Regular
			else if($file['mode'] & 0xA000)
				$file['type'] = 1;	// Link
			else
				$file['type'] = 9;	// Unknown
			$file['mode'] = decoct($file['mode']);

			if($file['type'] == 0 && !@file_exists($current))
				return;
			else if(strlen($file['name']) > 99) {
				$offset = strrpos($file['name'],"/") + 1;
				$file['path'] = substr($file['name'],0,$offset);
				$file['name'] = substr($file['name'],$offset);
				if(strlen($file['name']) > 99 || strlen($file['path']) > 154)
					return;
			}
			else
				$file['path'] = "";

			$stat = stat($current);

			if(($file['type'] == 0 || $file['type'] == 1) && $fp = @fopen($current,"rb")) {
				$data = fread($fp,$stat[7]);
				fclose($fp);
			}
			else
				$data = "";

			$flags = array(
				'mode'	=> $file['mode'],
				'uid'	=> $stat[4],
				'gid'	=> $stat[5],
				'size'	=> $stat[7],
				'time'	=> $stat[9],
				'type'	=> $file['type'],
				'link'	=> $file['type'] == 1? @readlink($current) : "",
				'path'	=> $file['path'],
			);

			$this->addfile($data,$file['name'],$flags);
		}

		@chdir($pwd);
	}

	function extract($data) {
		$return = array();
		$blocks = strlen($data)/512 - 1;
		$offset = 0;

		while($offset < $blocks) {
			$header = substr($data,512*$offset,512);
			$current = unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1type/a100linkname/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor/a155path",$header);
			foreach($current as $k => $v)
				$current[$k] = trim($v);
			$current['mode'] = octdec($current['mode']);
			$current['uid'] = octdec($current['uid']);
			$current['gid'] = octdec($current['gid']);
			$current['size'] = octdec($current['size']);
			$current['mtime'] = octdec($current['mtime']);
			$current['checksum'] = octdec($current['checksum']);
			$current['type'] = octdec($current['type']);

			if($this->storepaths != 1)
				$current['filename'] = substr($current['filename'],strrpos($current['filename'],"/")+1);
			$current['filename'] = preg_replace("/\W+/","",$current['filename']);

			$checksum = 0;
			for($i = 0; $i < 148; $i++)
				$checksum += ord(substr($header,$i,1));
			for($i = 148; $i < 156; $i++)
				$checksum += ord(" ");
			for($i = 156; $i < 512; $i++)
				$checksum += ord(substr($header,$i,1));
			if($current['checksum'] != $checksum)
				return "CHECKSUM";

			$size = ceil($current['size']/512);
			$current['data'] = substr($data,512*($offset++),$current['size']);
			$offset += $size;
			$return[] = $current;
		}

		return $return;
	}

	function getdata() {
		return $this->tardata . pack("a512","");
	}

	function filedownload($filename) {
		@header("Content-type: application/x-tar");
		@header("Content-disposition: attachment; filename=$filename");

		print($this->getdata());
	}

	function nullpad($bytes) {
		$return = "";
		for($i = 0; $i < $bytes; ++$i)
			$return .= "\0";
		return $return;
	}
}

class gzfile extends archive {
	var $gzdata = "";

	function addfile($data,$filename=null,$comment=null) {
		$flags = bindec("000".(!empty($comment)? "1" : "0").(!empty($filename)? "1" : "0")."000");
		$this->gzdata .= pack("C1C1C1C1VC1C1",0x1f,0x8b,8,$flags,time(),2,0xFF);

		if(!empty($filename))
			$this->gzdata .= "$filename\0";

		if(!empty($comment))
			$this->gzdata .= "$comment\0";

		$this->gzdata .= gzdeflate($data);

		$this->gzdata .= pack("VV",crc32($data),strlen($data));
	}

	function extract($data) {
		$id = unpack("H2id1/H2id2",substr($data,0,2));
		if($id['id1'] != "1f" || $id['id2'] != "8b")
			die("Not valid gzip data.");

		$temp = unpack("Cflags",substr($data,2,1));
		$temp = decbin($temp['flags']);
		if($temp & 0x8)
			$flags['name'] = 1;
		if($temp & 0x4)
			$flags['comment'] = 1;

		$offset = 10;

		$filename = "";
		while(!empty($flags['name'])) {
			$char = substr($data,$offset,1);
			$offset++;
			if($char == "\0")
				break;
			$filename .= $char;
		}
		if($filename == "")
			$filename = "file";

		$comment = "";
		while(!empty($flags['comment'])) {
			$char = substr($data,$offset,1);
			$offset++;
			if($char == "\0")
				break;
			$comment .= $char;
		}

		$temp = unpack("Vcrc32/Visize",substr($data,strlen($data)-8,8));
		$crc32 = $temp['crc32'];
		$isize = $temp['isize'];

		$data = gzinflate(substr($data,$offset,strlen($data)-8-$offset));

		if($crc32 != crc32($data))
			return "CRC";

		return array('filename'=>$filename,'comment'=>$comment,'size'=>$isize,'data'=>$data);
	}

	function getdata() {
		return $this->gzdata;
	}

	function filedownload($filename) {
		@header("Content-type: application/x-gzip");
		@header("Content-disposition: attachment; filename=$filename");

		print($this->getdata());
	}
}

class zipfile extends archive {
	var $cwd		= "./";
	var $comment	= "";
	var $level		= 9;
	var $offset		= 0;
	var $recursesd	= 1;
	var $storepath	= 1;
	var $replacetime	= 0;
	var $central	= array();
	var $zipdata	= array();

	function zipfile($cwd="./",$flags=array()) {
		$this->cwd = $cwd;
		if(isset($flags['time']))
			$this->replacetime = $flags['time'];
		if(isset($flags['recursesd']))
			$this->recursesd = $flags['recursesd'];
		if(isset($flags['storepath']))
			$this->storepath = $flags['storepath'];
		if(isset($flags['level']))
			$this->level = $flags['level'];
		if(isset($flags['comment']))
			$this->comment = $flags['comment'];

		$this->archive($flags);
	}

	function addfile($data,$filename,$flags=array()) {
		if($this->storepath != 1)
			$filename = strstr($filename,"/")? substr($filename,strrpos($filename,"/")+1) : $filename;
		else
			$filename = preg_replace("/^(\.{1,2}(\/|\\\))+/","",$filename);

		$mtime = !empty($this->replacetime)? getdate($this->replacetime) : (isset($flags['time'])? getdate($flags['time']) : getdate());
		$mtime = preg_replace("/(..){1}(..){1}(..){1}(..){1}/","\\x\\4\\x\\3\\x\\2\\x\\1",dechex(($mtime['year']-1980<<25)|($mtime['mon']<<21)|($mtime['mday']<<16)|($mtime['hours']<<11)|($mtime['minutes']<<5)|($mtime['seconds']>>1)));
		eval('$mtime = "'.$mtime.'";');

		$crc32 = crc32($data);
		$normlength = strlen($data);
		$data = gzcompress($data,$this->level);
		$data = substr($data,2,strlen($data)-6);
		$complength = strlen($data);

		$this->zipdata[] = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00".$mtime.pack("VVVvv",$crc32,$complength,$normlength,strlen($filename),0x00).$filename.$data.pack("VVV",$crc32,$complength,$normlength);
		$this->central[] = "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00".$mtime.pack("VVVvvvvvVV",$crc32,$complength,$normlength,strlen($filename),0x00,0x00,0x00,0x00,0x0000,$this->offset).$filename;

		$this->offset = strlen(implode("",$this->zipdata));
	}

	function addfiles($filelist) {
		$pwd = getcwd();
		@chdir($this->cwd);

		foreach($filelist as $current) {
			if(!@file_exists($current))
				continue;

			$stat = stat($current);

			if($fp = @fopen($current,"rb")) {
				$data = fread($fp,$stat[7]);
				fclose($fp);
			}
			else
				$data = "";

			$flags = array('time'=>$stat[9]);

			$this->addfile($data,$current,$flags);
		}

		@chdir($pwd);
	}

	function getdata() {
		$central = implode("",$this->central);
		$zipdata = implode("",$this->zipdata);
		return $zipdata.$central."\x50\x4b\x05\x06\x00\x00\x00\x00".pack("vvVVv",sizeof($this->central),sizeof($this->central),strlen($central),strlen($zipdata),strlen($this->comment)).$this->comment;
	}

	function filedownload($filename) {
		@header("Content-type: application/zip");
		@header("Content-disposition: attachment; filename=$filename");

		print($this->getdata());
	}
}

class archive {
	var $overwrite		= 0;
	var $defaultperms	= 0644;

	function archive($flags=array()) {
		if(isset($flags['overwrite']))
			$this->overwrite = $flags['overwrite'];
		if(isset($flags['defaultperms']))
			$this->defaultperms = $flags['defaultperms'];
	}

	function adddirectories($dirlist) {
		$pwd = getcwd();
		@chdir($this->cwd);

		$filelist = array();

		foreach($dirlist as $current) {
			if(@is_dir($current)) {
				$temp = $this->parsedirectories($current);
				foreach($temp as $filename)
					$filelist[] = $filename;
			}
			else if(@file_exists($current))
				$filelist[] = $current;
		}

		@chdir($pwd);
		$this->addfiles($filelist);
	}

	function parsedirectories($dirname) {
		$filelist = array();
		$dir = @opendir($dirname);

		while($file = @readdir($dir)) {
			if($file == "." || $file == "..")
				continue;
			else if(@is_dir($dirname."/".$file)) {
				if($this->recursesd != 1)
					continue;
				$temp = $this->parsedirectories($dirname."/".$file);
				foreach($temp as $file2)
					$filelist[] = $file2;
			}
			else if(@file_exists($dirname."/".$file))
				$filelist[] = $dirname."/".$file;
		}

		@closedir($dir);

		return $filelist;
	}

	function filewrite($filename,$perms=null) {
		if($this->overwrite != 1 && @file_exists($filename))
			die("File $filename already exists.");

		if(@file_exists($filename))
			@unlink($filename);

		$fp = @fopen($filename,"wb");

		if(!fwrite($fp,$this->getdata()))
			die("Could not write data to $filename.");

		@fclose($fp);

		if(!isset($perms))
			$perms = $this->defaultperms;

		@chmod($filename,$perms);
	}

	function extractfile($filename) {
		if($fp = @fopen($filename,"rb")) {
			return $this->extract(fread($fp,filesize($filename)));
			@fclose($fp);
		}
		else
			die("Could not open $filename.");
	}
} ?>

Verfasst: 22.02.2005 16:21
von Gumfuzi
Hi!

Danke für das Snippet, jedoch stehe ich gerade voll daneben, wie ich das Teil aufrufe:

Du hast ja oben geschrieben, daß TAR in Verbindung von GZIP benutzt wird, aber wenn ich ein archiv.tar.gz haben will, muss ich dann beide Funktionen aufrufen oder ist alles in der gzip-Funktion enthalten?

Code: Alles auswählen

/*------------------------------------------------------------ 
 | To create gzip files: 
 | $example = new gzfile($cwd,$flags); // args optional 
 | -current working directory 
 | -flags (array): 
 |  -overwrite - whether to overwrite existing files or return 
 |    an error message 
 |  -defaultperms - default file permissions (like chmod(), 
 |    must include 0 in front of value [eg. 0777, 0644]) 
 +------------------------------------------------------------*/
Und wie rufe ich die auf?
per eigener PHP-Datei, wo ich zuerst dieses Funktionen include, $cwd bestimme (absolut, oder?) und dann per

Code: Alles auswählen

$example = new gzfile($cwd,$flags); 
die aufrufe?
Das $cwd wird dann inkl. Unterverzeichnisse zu einem .tar.gz?
Wie definiere ich das overwrite-Flag? einfach hinten dran "-overwrite" oder "-overwrite=1"?
Und das Zielverzeichnis muss ich per chmod auf 0777 setzten, oder? Wo wird das fertige File denn überhaupt gespeichert? auch im cwd?

Sorry für die vielen Fragen...