Php/XtremUnsplit

From Php-Classes

Jump to: navigation, search

Contents

[edit] XtremUnsplit

[edit] description

Voici une classe php et le code associé pour décoder les fichiers splités avec XtremSplit

  • ce script ne vérifie pas l'intégrité des fichiers avec les md5sum, veuillez utiliser par2 pour cela,
  • ce script essaie de determiner au mieux si le fichier est bien au format XtremSplit, auquel cas il le reconstitue.

[edit] Utilisation

php -q xtremUnplit.php data.001.xtm

remplacer data par le nom de votre fichier. Sur plateforme ubunutu, vous devez installer php avec cette commande :

sudo apt-get install php5-cli

[edit] Restriction

ne fonctionne qu'avec les fichiers sources dans le répertoire courant ; ceci ne fonctionnera pas :

 php -q xtremUnplit.php temp_dir/data.001.xtm

[edit] source code

 <?php
 
 error_reporting(E_ALL);
 
 /**
  * author : Marc Quinton / march 2007.
  * 
  * this script is used to unsplit file from xtremsplit software.
  * more information about this file format at :
  *
  *  http://xtremsplit.free.fr/?page=windows&page2=faq (header)
  */
 
 
 define('HEADER_SIZE', 104);
 
 class XtremSplit{
 
 	protected $fd;
 	protected $file;
 	protected $header;
 
 	public function __construct(){
 		$this->header = null;
 	}
 
 	public function info($file){
 		if(!file_exists($file))
 			return false;
 
 		$this->fd = fopen($file, 'r');
 		$this->header = $this->get_header();
 		fclose($this->fd);
 
 		if(!$this->is_xtrem_file()){
 			echo "$file is not an extrem-split file\n";
 			exit(1);
 		}
 
 		echo "num files = " . $this->num_files() . "\n";
 		echo "filename = " . $this->filename() . "\n";
 		echo "prog = " .  $this->program_name() . "\n";
 		echo "version = " .  $this->version() . "\n";
 		echo "file size = " . $this->file_size() . "\n";
 
 		if($this->hash_enabled())
 			echo "hash enabled\n";
 		else
 			echo "hash not enabled\n";
 
 		printf("prog : %s\n", $this->header_read_string_by_len(0));
 	}
 
 	# ---------------------------------- XtremSplit header reading functions -------------------------------------------
 	/**
 	 * the most basic header reading function : reads $bytes at $pos
 	 */
 	protected function header_read_bytes($pos, $bytes){
 		$data = ;
 		for($i=0 ; $i<$bytes ; $i++)
 			$data .= $this->header[$pos++];
 		return $data;
 	}
 
 	/**
 	 * read 1 char at $pos and return as unsigned char (int value)
 	 */
 	protected function header_read_unsigned_char($pos){
 		$data = unpack('C', $this->header_read_bytes($pos, 1));
 		return $data[1];
 	}
 
 	/**
 	 * unused ; read a string at $pos and return when read "\n" char
 	 */
 	protected function header_read_string($pos, $terminator="\n"){
 		$data = ;
 		while($this->header[$pos] != $terminator)
 			$data .= $this->header[$pos++];
 		return $data;
 	}
 
 	/**
 	 * read a string in header ; $pos is strlen ; value is after strlen ($pos+1)
 	 * return a string
 	 */
 	protected function header_read_string_by_len($pos){
 		$len = $this->header_read_unsigned_char($pos++);
 		return $this->header_read_bytes($pos, $len);
 	}
 
 	# ------------------------------------- XtremSplit header info -------------------------------------------------
 
 	/**
 	 * try to determine if this is an XtremSplit file ; use this before doing complexe reading operations.
 	 */
 	protected function is_xtrem_file(){
 		$name = trim($this->program_name());
 		$len  = $this->header_read_unsigned_char(0);
 
 		if(strcasecmp($this->program_name(), 'Xtmsplit') != 0)
 			return false;
 
 		if($len != strlen($name))
 			return false;
 
 		return true;
 	}
 
 	/**
 	 * number of files used to split original file
 	 */
 	public function num_files(){
 		$value =  unpack('L', $this->header_read_bytes(92, 4));
 		return $value[1];
 	}
 
 	/**
 	 * size of original file (can't read 8 bytes integers with php/unpack, so return only 4 bytes)
 	 */
 	public function file_size(){
 		$v1 =  unpack('N', $this->header_read_bytes(96, 4)); # don't know how to unpack 8 bytes number
 		# $v2 =  unpack('N', $this->header_read_bytes(100, 4)); # don't know how to unpack 8 bytes number
 		return $v1[1];  # not correct
 	}
 
 	/**
 	 * does XtremSplit contains md5sum hash at the end of last file.
 	 */
 	public function hash_enabled(){
 		$enabled = $this->header_read_unsigned_char(91);
 		return $enabled == '1';
 	}
 
 	/**
 	 * version of xtremsplit that generated this header file
 	 */
 	public function version(){
 		return trim($this->header_read_bytes(22, 4));
 	}
 
 	/**
 	 * program that generated this header file.
 	 */
 	public function program_name(){
 		return $this->header_read_string_by_len(0);
 	}
 
 	/**
 	 * original filename before spliting
 	 */
 	public function filename(){
 		return $this->header_read_string_by_len(40);
 	}
 
 	/**
 	 * main method for unspliting files.
 	 */
 	public function unsplit($file){
 
 		$this->fd = fopen($file, 'r');
 		$this->header = $this->get_header();
 		fclose($this->fd);
 
 		echo "unspliting to source file $file\n";
 
 		$orig_file = $this->filename();
 		$count = $this->num_files();
 
 		$files = array();
 
 		for($i=0 ; $i< $count ; $i++){
 			$files[] = sprintf('%s.%03d.xtm', $orig_file, $i+1);
 		}
 
 		if(file_exists($this->filename()))
 			unlink($this->filename());
 
 		$out = fopen($this->filename(), 'w+');
 
 		foreach($files as $key=>$f){
 			echo "unspliting file $f ...\n";
 
 			if(!file_exists($f))
 				throw new Exception("file not found : $f");
 
 			$fd = fopen($f, 'r');
 
 			if($key == 0)
 				$header = fread($fd, HEADER_SIZE);  # skip header;
 
 			while(!feof($fd)){
 				$data = fread($fd, 1024*10);
 				fwrite($out, $data);
 			}
 			fclose($fd);
 		}
 
 		# remove hashes from end of file if hash is enabled.
 		if($this->hash_enabled()){
 			$size = filesize($this->filename()) - $count*32;
 			ftruncate($out, $size);
 		}
 		fclose($out);
 	}
 
 	/**
 	 * read header from $this->fd ; need to call this method before trying to get header information.
 	 */
 	protected function get_header($size = HEADER_SIZE){
 		$data = fread($this->fd, $size);
 		return $data;
 	}
 }
 
 $args = $_SERVER['argv'];
 
 if(count($args) == 2){
 	$file = $args[1];
 	$xtrem = new XtremSplit();
 	# $xtrem->info($file);
 	$xtrem->unsplit($file);
 }
 
 
 ?>

[edit] links

Personal tools
Languages