Desconozco por qué agregan el asterisco (*) delante del nix, que otras variantes a UNIX existen? Disculpen mi ignorancia...
Lo quiero hacer con PHP porque estoy desarrollando el programa en mi servidor doméstico pero en realidad la idea es cargarlo en el servidor de la empresa de un conocido que desea porder respaldar y poseer consigo mismo los datos del servidor de datos (almacenan información de todos los equipos de la empresa allí). Está en mis planes incluso realizar este script para poder cargarlo en cualquier servidor que lo requiera, por esto lo quiero hacer general. También olvidé mensionar que lo hago en PHP para correrlo en Apache y que de este modo las personas que realizan el respaldo, lo descarguen mediante el explorador directamente a sus equipos a pesar de que ninguno de ellos sabe manejar *nix, al menos desde la línea de comandos.
Dejo aquí el código que genera el tar (pero como script PHP, no como ejecutable *nix):
Código PHP:
function createzip($struct,$namezip=0)
{ $ZipData = array();
$Dircont = array();
$DirFile = array();
$offseto = 0;
while(list($file,$data)=each($struct))
{ $file= str_replace("\\", "/", $file);
$dir=explode("/",$file);
for($i=0; $i<sizeof($dir); $i++)if($dir[$i]=="")unset($dir[$i]);
$num=count($dir); //Total de niveles
$ele=0; //Nivel actual
$dirname=""; //Nombre archivo o directorio
while(list($idx,$val)=each($dir))
{ $ty=(++$ele)==$num?true:false;
$ty=trim($data)!=""?$ty:false;//Compruebar si el ultimo elemento es directorio o archivo
$dirname.=$val.($ty?"":"/");
if(isset($DirFile[$dirname]))continue; else $DirFile[$dirname]=true;
$gzdata="";
if($ty)
{ $unziplen=strlen($data);
$czip=crc32($data);
$gzdata=gzcompress($data);
$gzdata=substr(substr($gzdata,0,strlen($gzdata)-4),2);
$cziplen=strlen($gzdata);
}
$ZipData[]="\x50\x4b\x03\x04".($ty?"\x14":"\x0a")."\x00\x00\x00".($ty?"\x08":"\x00")."\x00\x00\x00\x00\x00".
pack("V",$ty?$czip:0).pack("V",$ty?$cziplen:0).pack("V",$ty?$unziplen:0).pack("v",strlen($dirname)).
pack("v",0).$dirname.$gzdata.pack("V",$ty?$czip:0).pack("V",$ty?$cziplen:0).pack("V",$ty?$unziplen:0);
$Dircont[]="\x50\x4b\x01\x02\x00\x00".($ty?"\x14":"\x0a")."\x00\x00\x00".($ty?"\x08":"\x00")."\x00\x00\x00\x00\x00".
pack("V",$ty?$czip:0).pack("V",$ty?$cziplen:0).pack("V",$ty?$unziplen:0).pack("v",strlen($dirname)).
pack("v", 0 ).pack("v",0).pack("v",0).pack("v",0).pack("V",$ty?32:16).pack("V",$offseto).$dirname;
$offseto=strlen(implode("",$ZipData));
}//Fin While dir
}//Fin While archivos
$data = implode("",$ZipData);
$cdir = implode("",$Dircont);
$data=$data.$cdir."\x50\x4b\x05\x06\x00\x00\x00\x00".pack("v",sizeof($Dircont)).pack("v",sizeof($Dircont)).pack("V",strlen($cdir)).pack("V",strlen($data))."\x00\x00";
if($namezip)//Construir el archivo
{ if(($fp=fopen($namezip,"wb")))
{ fwrite($fp,$data);
fclose ($fp);
return true;
}else return false;
}else return $data;
}
function fun_dir($dir,&$A,$path=0)
{ $d = dir($dir);
$path=$path?$path:$dir;
while($df=$d->read())
{ if($df=="." || $df=="..")continue;
if(is_file($d->path.$df))
{ $A[str_replace($path,"",$d->path.$df)]=file_get_contents($d->path.$df);
}
else
{ $A[str_replace($path,"",$d->path.$df)."/"]="";
fun_dir($d->path.$df."/",$A,$path);
}
} $d->close();
}
$cont=array();
fun_dir("../../../home/",$cont);
$cont["generado.txt"]="Zip generado".date("Y-m-d H:i:s");
$data = createzip($cont);
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-Description: File Transfer");
header("Content-Type: application/force-download");
header("Content-Length: " . strlen($data));
header("Content-Disposition: attachment; filename=demozip.zip");
echo $data;
Es un código pre-fabricado el cual adapté (o intenté) a mis necesidades.
Saludos !