From 49eb6e38061d744f4a35b78082dce49fa35f79c8 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Fri, 15 Jan 2010 19:50:13 +0100 Subject: some more coding standard compliance updates --- inc/TarLib.class.php | 1547 ++++++++++++++++++++++++-------------------------- 1 file changed, 745 insertions(+), 802 deletions(-) (limited to 'inc/TarLib.class.php') diff --git a/inc/TarLib.class.php b/inc/TarLib.class.php index ab802163b..3c1827554 100644 --- a/inc/TarLib.class.php +++ b/inc/TarLib.class.php @@ -59,860 +59,803 @@ define('ARCHIVE_DYNAMIC',0); define('ARCHIVE_RENAMECOMP',5); define('COMPRESS_DETECT',-1); -class TarLib -{ - var $_comptype; - var $_compzlevel; - var $_fp; - var $_memdat; - var $_nomf; - var $_result; - var $_initerror; - - /** - * constructor, initialize the class - * - * The constructor initialize the variables and prepare the class for the - * archive, and return the object created. Note that you can use multiple - * instances of the MaxgTar class, if you call this function another time and - * store the object in an other variable. - * - * In fact, MaxgTar accepts the following arguments (all are optional) : - * - * filename can be either a file name (absolute or relative). In this - * case, it can be used both for reading and writing. You can also open - * remote archive if you add a protocole name at the beginning of the file - * (ie https://host.dom/archive.tar.gz), but for reading only and if the - * directive allow_url_fopen is enabled in PHP.INI (this can be checked with - * TarInfo()). If you pass a file that doesn't exist, the script - * will try to create it. If the archive already exists and contains files, - * you can use Add() to append files.But by default this parameter - * is ARCHIVE_DYNAMIC (write only) so the archive is created in memory and - * can be sent to a file [writeArchive()] or to the client - * [sendClient()] - * - * compression_type should be a constant that represents a type of - * compression, or its integer value. The different values are described in - * the constants. - * - * compression_level is an integer between 1 and 9 (by default) an - * represent the GZIP or BZIP compression level. 1 produce fast compression, - * and 9 produce smaller files. See the RFC 1952 for more infos. - */ - function tarlib($p_filen = ARCHIVE_DYNAMIC , $p_comptype = COMPRESS_AUTO, $p_complevel = 9) - { - $this->_initerror = 0; - $this->_nomf = $p_filen; $flag=0; - if($p_comptype && $p_comptype % 5 == 0){$p_comptype /= ARCHIVE_RENAMECOMP; $flag=1;} - - if($p_complevel > 0 && $p_complevel <= 9) $this->_compzlevel = $p_complevel; - else $p_complevel = 9; - - if($p_comptype == COMPRESS_DETECT) - { - if(strtolower(substr($p_filen,-3)) == '.gz') $p_comptype = COMPRESS_GZIP; - elseif(strtolower(substr($p_filen,-4)) == '.bz2') $p_comptype = COMPRESS_BZIP; - else $p_comptype = COMPRESS_NONE; - } +class TarLib { + var $_comptype; + var $_compzlevel; + var $_fp; + var $_memdat; + var $_nomf; + var $_result; + var $_initerror; + + /** + * constructor, initialize the class + * + * The constructor initialize the variables and prepare the class for the + * archive, and return the object created. Note that you can use multiple + * instances of the MaxgTar class, if you call this function another time and + * store the object in an other variable. + * + * In fact, MaxgTar accepts the following arguments (all are optional) : + * + * filename can be either a file name (absolute or relative). In this + * case, it can be used both for reading and writing. You can also open + * remote archive if you add a protocole name at the beginning of the file + * (ie https://host.dom/archive.tar.gz), but for reading only and if the + * directive allow_url_fopen is enabled in PHP.INI (this can be checked with + * TarInfo()). If you pass a file that doesn't exist, the script + * will try to create it. If the archive already exists and contains files, + * you can use Add() to append files.But by default this parameter + * is ARCHIVE_DYNAMIC (write only) so the archive is created in memory and + * can be sent to a file [writeArchive()] or to the client + * [sendClient()] + * + * compression_type should be a constant that represents a type of + * compression, or its integer value. The different values are described in + * the constants. + * + * compression_level is an integer between 1 and 9 (by default) an + * represent the GZIP or BZIP compression level. 1 produce fast compression, + * and 9 produce smaller files. See the RFC 1952 for more infos. + */ + function tarlib($p_filen = ARCHIVE_DYNAMIC , $p_comptype = COMPRESS_AUTO, $p_complevel = 9) { + $this->_initerror = 0; + $this->_nomf = $p_filen; + $flag=0; + if($p_comptype && $p_comptype % 5 == 0){ + $p_comptype /= ARCHIVE_RENAMECOMP; + $flag=1; + } - switch($p_comptype) - { - case COMPRESS_GZIP: - if(!extension_loaded('zlib')) $this->_initerror = -1; - $this->_comptype = COMPRESS_GZIP; - break; - - case COMPRESS_BZIP: - if(!extension_loaded('bz2')) $this->_inierror = -2; - $this->_comptype = COMPRESS_BZIP; - break; - - case COMPRESS_AUTO: - if(extension_loaded('zlib')) - $this->_comptype = COMPRESS_GZIP; - elseif(extension_loaded('bz2')) - $this->_comptype = COMPRESS_BZIP; - else - $this->_comptype = COMPRESS_NONE; - break; + if($p_complevel > 0 && $p_complevel <= 9) $this->_compzlevel = $p_complevel; + else $p_complevel = 9; - default: - $this->_comptype = COMPRESS_NONE; + if($p_comptype == COMPRESS_DETECT) { + if(strtolower(substr($p_filen,-3)) == '.gz') $p_comptype = COMPRESS_GZIP; + elseif(strtolower(substr($p_filen,-4)) == '.bz2') $p_comptype = COMPRESS_BZIP; + else $p_comptype = COMPRESS_NONE; + } + + switch($p_comptype) { + case COMPRESS_GZIP: + if(!extension_loaded('zlib')) $this->_initerror = -1; + $this->_comptype = COMPRESS_GZIP; + break; + + case COMPRESS_BZIP: + if(!extension_loaded('bz2')) $this->_inierror = -2; + $this->_comptype = COMPRESS_BZIP; + break; + + case COMPRESS_AUTO: + if(extension_loaded('zlib')) + $this->_comptype = COMPRESS_GZIP; + elseif(extension_loaded('bz2')) + $this->_comptype = COMPRESS_BZIP; + else + $this->_comptype = COMPRESS_NONE; + break; + + default: + $this->_comptype = COMPRESS_NONE; + } + + if($this->_init_error < 0) $this->_comptype = COMPRESS_NONE; + + if($flag) $this->_nomf.= '.'.$this->getCompression(1); + $this->_result = true; } - if($this->_init_error < 0) $this->_comptype = COMPRESS_NONE; - - if($flag) $this->_nomf.= '.'.$this->getCompression(1); - $this->_result = true; - } - - /** - * Recycle a TAR object. - * - * This function does exactly the same as TarLib (constructor), except it - * returns a status code. - */ - function setArchive($p_name='', $p_comp = COMPRESS_AUTO, $p_level=9) - { - $this->_CompTar(); - $this->TarLib($p_name, $p_comp, $p_level); - return $this->_result; - } - - /** - * Get the compression used to generate the archive - * - * This is a very useful function when you're using dynamical archives. - * Besides, if you let the script chose which compression to use, you'll have - * a problem when you'll want to send it to the client if you don't know - * which compression was used. - * - * There are two ways to call this function : if you call it without argument - * or with FALSE, it will return the compression constants, explained on the - * MaxgTar Constants. If you call it with GetExtension on TRUE it will - * return the extension without starting dot (ie "tar" or "tar.bz2" or - * "tar.gz") - * - * NOTE: This can be done with the flag ARCHIVE_RENAMECOMP, see the - * MaxgTar Constants - */ - function getCompression($ext = false) - { - $exts = Array('tar','tar.gz','tar.bz2'); - if($ext) return $exts[$this->_comptype]; - return $this->_comptype; - } - - /** - * Change the compression mode. - * - * This function will change the compression methode to read or write - * the archive. See the MaxgTar Constants to see which constants you can use. - * It may look strange, but it returns the GZIP compression level. - */ - function setCompression($p_comp = COMPRESS_AUTO) - { - $this->setArchive($this->_nomf, $p_comp, $this->_compzlevel); - return $this->_compzlevel; - } - - /** - * Returns the compressed dynamic archive. - * - * When you're working with dynamic archives, use this function to grab - * the final compressed archive in a string ready to be put in a SQL table or - * in a file. - */ - function getDynamicArchive() - { - return $this->_encode($this->_memdat); - } - - /** - * Write a dynamical archive into a file - * - * This function attempts to write a dynamicaly-genrated archive into - * TargetFile on the webserver. It returns a TarErrorStr() status - * code. - * - * To know the extension to add to the file if you're using AUTO_DETECT - * compression, you can use getCompression(). - */ - function writeArchive($p_archive) { - if(!$this->_memdat) return -7; - $fp = @fopen($p_archive, 'wb'); - if(!$fp) return -6; - - fwrite($fp, $this->_memdat); - fclose($fp); - - return true; - } - - /** - * Send a TAR archive to the client browser. - * - * This function will send an archive to the client, and return a status - * code, but can behave differently depending on the arguments you give. All - * arguments are optional. - * - * ClientName is used to specify the archive name to give to the browser. If - * you don't give one, it will send the constructor filename or return an - * error code in case of dynamical archive. - * - * FileName is optional and used to send a specific archive. Leave it blank - * to send dynamical archives or the current working archive. - * - * If SendHeaders is enabled (by default), the library will send the HTTP - * headers itself before it sends the contents. This headers are : - * Content-Type, Content-Disposition, Content-Length and Accept-Range. - * - * Please note that this function DOES NOT stops the script so don't forget - * to exit() to avoid your script sending other data and corrupt the archive. - * Another note : for AUTO_DETECT dynamical archives you can know the - * extension to add to the name with getCompression() - */ - function sendClient($name = '', $archive = '', $headers = true) - { - if(!$name && !$this->_nomf) return -9; - if(!$archive && !$this->_memdat) return -10; - if(!$name) $name = basename($this->_nomf); - - if($archive){ if(!file_exists($archive)) return -11; } - else $decoded = $this->getDynamicArchive(); - - if($headers) - { - header('Content-Type: application/x-gtar'); - header('Content-Disposition: attachment; filename='.basename($name)); - header('Accept-Ranges: bytes'); - header('Content-Length: '.($archive ? filesize($archive) : strlen($decoded))); + /** + * Recycle a TAR object. + * + * This function does exactly the same as TarLib (constructor), except it + * returns a status code. + */ + function setArchive($p_name='', $p_comp = COMPRESS_AUTO, $p_level=9) { + $this->_CompTar(); + $this->TarLib($p_name, $p_comp, $p_level); + return $this->_result; } - if($archive) - { - $fp = @fopen($archive,'rb'); - if(!$fp) return -4; + /** + * Get the compression used to generate the archive + * + * This is a very useful function when you're using dynamical archives. + * Besides, if you let the script chose which compression to use, you'll have + * a problem when you'll want to send it to the client if you don't know + * which compression was used. + * + * There are two ways to call this function : if you call it without argument + * or with FALSE, it will return the compression constants, explained on the + * MaxgTar Constants. If you call it with GetExtension on TRUE it will + * return the extension without starting dot (ie "tar" or "tar.bz2" or + * "tar.gz") + * + * NOTE: This can be done with the flag ARCHIVE_RENAMECOMP, see the + * MaxgTar Constants + */ + function getCompression($ext = false) { + $exts = Array('tar','tar.gz','tar.bz2'); + if($ext) return $exts[$this->_comptype]; + return $this->_comptype; + } - while(!feof($fp)) echo fread($fp,2048); + /** + * Change the compression mode. + * + * This function will change the compression methode to read or write + * the archive. See the MaxgTar Constants to see which constants you can use. + * It may look strange, but it returns the GZIP compression level. + */ + function setCompression($p_comp = COMPRESS_AUTO) { + $this->setArchive($this->_nomf, $p_comp, $this->_compzlevel); + return $this->_compzlevel; } - else - { - echo $decoded; + + /** + * Returns the compressed dynamic archive. + * + * When you're working with dynamic archives, use this function to grab + * the final compressed archive in a string ready to be put in a SQL table or + * in a file. + */ + function getDynamicArchive() { + return $this->_encode($this->_memdat); } - return true; - } - - /** - * Extract part or totality of the archive. - * - * This function can extract files from an archive, and returns then a - * status codes that can be converted with TarErrorStr() into a - * human readable message. - * - * Only the first argument is required, What and it can be either the - * constant FULL_ARCHIVE or an indexed array containing each file you want to - * extract. - * - * To contains the target folder to extract the archive. It is optional and - * the default value is '.' which means the current folder. If the target - * folder doesn't exist, the script attempts to create it and give it - * permissions 0777 by default. - * - * RemovePath is very usefull when you want to extract files from a subfoler - * in the archive to a root folder. For instance, if you have a file in the - * archive called some/sub/folder/test.txt and you want to extract it to the - * script folder, you can call Extract with To = '.' and RemovePath = - * 'some/sub/folder/' - * - * FileMode is optional and its default value is 0755. It is in fact the UNIX - * permission in octal mode (prefixed with a 0) that will be given on each - * extracted file. - */ - function Extract($p_what = FULL_ARCHIVE, $p_to = '.', $p_remdir='', $p_mode = 0755) - { - if(!$this->_OpenRead()) return -4; -// if(!@is_dir($p_to)) if(!@mkdir($p_to, 0777)) return -8; --CS - if(!@is_dir($p_to)) if(!$this->_dirApp($p_to)) return -8; //--CS (route through correct dir fn) - - $ok = $this->_extractList($p_to, $p_what, $p_remdir, $p_mode); - $this->_CompTar(); - - return $ok; - } - - /** - * Create a new package with the given files - * - * This function will attempt to create a new archive with global headers - * then add the given files into. If the archive is a real file, the - * contents are written directly into the file, if it is a dynamic archive - * contents are only stored in memory. This function should not be used to - * add files to an existing archive, you should use Add() instead. - * - * The FileList actually supports three different modes : - * - * - You can pass a string containing filenames separated by pipes '|'. - * In this case the file are read from the webserver filesystem and the - * root folder is the folder where the script using the MaxgTar is called. - * - * - You can also give a unidimensional indexed array containing the - * filenames. The behaviour for the content reading is the same that a - * '|'ed string. - * - * - The more useful usage is to pass bidimensional arrays, where the - * first element contains the filename and the second contains the file - * contents. You can even add empty folders to the package if the filename - * has a leading '/'. Once again, have a look at the exemples to understand - * better. - * - * Note you can also give arrays with both dynamic contents and static files. - * - * The optional parameter RemovePath can be used to delete a part of the tree - * of the filename you're adding, for instance if you're adding in the root - * of a package a file that is stored somewhere in the server tree. - * - * On the contrary the parameter AddPath can be used to add a prefix folder - * to the file you store. Note also that the RemovePath is applied before the - * AddPath is added, so it HAS a sense to use both parameters together. - */ - function Create($p_filelist,$p_add='',$p_rem='') - { - if(!$fl = $this->_fetchFilelist($p_filelist)) return -5; - if(!$this->_OpenWrite()) return -6; - - $ok = $this->_addFileList($fl,$p_add,$p_rem); - - if($ok) $this->_writeFooter(); - else{ $this->_CompTar(); @unlink($this->_nomf); } - - return $ok; - } - - /** - * Add files to an existing package. - * - * This function does exactly the same than Create() exept it - * will append the given files at the end of the archive. Please not the is - * safe to call Add() on a newly created archive whereas the - * contrary will fail ! - * - * This function returns a status code, you can use TarErrorStr() on - * it to get the human-readable description of the error. - */ - function Add($p_filelist, $p_add = '', $p_rem = '') { if (($this->_nomf -!= ARCHIVE_DYNAMIC && @is_file($this->_nomf)) || ($this->_nomf == -ARCHIVE_DYNAMIC && !$this->_memdat)) return $this->Create($p_filelist, -$p_add, $p_rem); - - if(!$fl = $this->_fetchFilelist($p_filelist)) return -5; - return $this->_append($fl, $p_add, $p_rem); - } - - /** - * Read the contents of a TAR archive - * - * This function attempts to get the list of the files stored in the - * archive, and return either an error code or an indexed array of - * associative array containing for each file the following informations : - * - * checksum Tar Checksum of the file - * filename The full name of the stored file (up to 100 c.) - * mode UNIX permissions in DECIMAL, not octal - * uid The Owner ID - * gid The Group ID - * size Uncompressed filesize - * mtime Timestamp of last modification - * typeflag Empty for files, set for folders - * link For the links, did you guess it ? - * uname Owner name - * gname Group name - */ - function ListContents() - { - if(!$this->_nomf) return -3; - if(!$this->_OpenRead()) return -4; - - $result = Array(); - - while ($dat = $this->_read(512)) - { - $dat = $this->_readHeader($dat); - if(!is_array($dat)) continue; - - $this->_seek(ceil($dat['size']/512)*512,1); - $result[] = $dat; + /** + * Write a dynamical archive into a file + * + * This function attempts to write a dynamicaly-genrated archive into + * TargetFile on the webserver. It returns a TarErrorStr() status + * code. + * + * To know the extension to add to the file if you're using AUTO_DETECT + * compression, you can use getCompression(). + */ + function writeArchive($p_archive) { + if(!$this->_memdat) return -7; + $fp = @fopen($p_archive, 'wb'); + if(!$fp) return -6; + + fwrite($fp, $this->_memdat); + fclose($fp); + + return true; } - return $result; - } - - /** - * Convert a status code into a human readable message - * - * Some MaxgTar functions like Create(), Add() ... return numerical - * status code. You can pass them to this function to grab their english - * equivalent. - */ - function TarErrorStr($i) - { - $ecodes = Array( - 1 => true, - 0 => "Undocumented error", - -1 => "Can't use COMPRESS_GZIP compression : ZLIB extensions are not loaded !", - -2 => "Can't use COMPRESS_BZIP compression : BZ2 extensions are not loaded !", - -3 => "You must set a archive file to read the contents !", - -4 => "Can't open the archive file for read !", - -5 => "Invalide file list !", - -6 => "Can't open the archive in write mode !", - -7 => "There is no ARCHIVE_DYNAMIC to write !", - -8 => "Can't create the directory to extract files !", - -9 => "Please pass a archive name to send if you made created an ARCHIVE_DYNAMIC !", - -10 => "You didn't pass an archive filename and there is no stored ARCHIVE_DYNAMIC !", - -11 => "Given archive doesn't exist !" - ); - - return isset($ecodes[$i]) ? $ecodes[$i] : $ecodes[0]; - } - - /** - * Display informations about the MaxgTar Class. - * - * This function will display vaious informations about the server - * MaxgTar is running on. - * - * The optional parameter DispHeaders is used to generate a full page with - * HTML headers (TRUE by default) or just the table with the informations - * (FALSE). Note that the HTML page generated is verified compatible XHTML - * 1.0, but not HTML 4.0 compatible. - */ - function TarInfo($headers = true) - { - if($headers) - { - ?> - - - - - MaxgComp TAR - - - - - - -_nomf) return -9; + if(!$archive && !$this->_memdat) return -10; + if(!$name) $name = basename($this->_nomf); + + if($archive){ if(!file_exists($archive)) return -11; } + else $decoded = $this->getDynamicArchive(); + + if($headers) { + header('Content-Type: application/x-gtar'); + header('Content-Disposition: attachment; filename='.basename($name)); + header('Accept-Ranges: bytes'); + header('Content-Length: '.($archive ? filesize($archive) : strlen($decoded))); + } + + if($archive) { + $fp = @fopen($archive,'rb'); + if(!$fp) return -4; + + while(!feof($fp)) echo fread($fp,2048); + } else { + echo $decoded; + } + + return true; } -?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MaxgComp TAR
This software was created by the Maxg Network, http://maxg.info -
It is distributed under the GNU Lesser General Public License -
You can find the documentation of this class here
MaxgComp TAR
MaxgComp TAR version
ZLIB extensionsYes' : 'No')?>
BZ2 extensionsYes' : 'No')?>
Allow URL fopenYes' : 'No')?>
Time limit
PHP Version
- Special thanks to « Vincent Blavet » for his PEAR::Archive_Tar class -
-'; - } - - function _seek($p_flen, $tell=0) - { - if($this->_nomf === ARCHIVE_DYNAMIC) - $this->_memdat=substr($this->_memdat,0,($tell ? strlen($this->_memdat) : 0) + $p_flen); - elseif($this->_comptype == COMPRESS_GZIP) - @gzseek($this->_fp, ($tell ? @gztell($this->_fp) : 0)+$p_flen); - elseif($this->_comptype == COMPRESS_BZIP) - @fseek($this->_fp, ($tell ? @ftell($this->_fp) : 0)+$p_flen); - else - @fseek($this->_fp, ($tell ? @ftell($this->_fp) : 0)+$p_flen); - } - - function _OpenRead() - { - if($this->_comptype == COMPRESS_GZIP) - $this->_fp = @gzopen($this->_nomf, 'rb'); - elseif($this->_comptype == COMPRESS_BZIP) - $this->_fp = @bzopen($this->_nomf, 'rb'); - else - $this->_fp = @fopen($this->_nomf, 'rb'); - - return ($this->_fp ? true : false); - } - - function _OpenWrite($add = 'w') - { - if($this->_nomf === ARCHIVE_DYNAMIC) return true; - - if($this->_comptype == COMPRESS_GZIP) - $this->_fp = @gzopen($this->_nomf, $add.'b'.$this->_compzlevel); - elseif($this->_comptype == COMPRESS_BZIP) - $this->_fp = @bzopen($this->_nomf, $add.'b'); - else - $this->_fp = @fopen($this->_nomf, $add.'b'); - - return ($this->_fp ? true : false); - } - - function _CompTar() - { - if($this->_nomf === ARCHIVE_DYNAMIC || !$this->_fp) return; - - if($this->_comptype == COMPRESS_GZIP) @gzclose($this->_fp); - elseif($this->_comptype == COMPRESS_BZIP) @bzclose($this->_fp); - else @fclose($this->_fp); - } - - function _read($p_len) - { - if($this->_comptype == COMPRESS_GZIP) - return @gzread($this->_fp,$p_len); - elseif($this->_comptype == COMPRESS_BZIP) - return @bzread($this->_fp,$p_len); - else - return @fread($this->_fp,$p_len); - } - - function _write($p_data) - { - if($this->_nomf === ARCHIVE_DYNAMIC) $this->_memdat .= $p_data; - elseif($this->_comptype == COMPRESS_GZIP) - return @gzwrite($this->_fp,$p_data); - - elseif($this->_comptype == COMPRESS_BZIP) - return @bzwrite($this->_fp,$p_data); - - else - return @fwrite($this->_fp,$p_data); - } - - function _encode($p_dat) - { - if($this->_comptype == COMPRESS_GZIP) - return gzencode($p_dat, $this->_compzlevel); - elseif($this->_comptype == COMPRESS_BZIP) - return bzcompress($p_dat, $this->_compzlevel); - else return $p_dat; - } - - function _readHeader($p_dat) - { - if (!$p_dat || strlen($p_dat) != 512) return false; - - for ($i=0, $chks=0; $i<148; $i++) - $chks += ord($p_dat[$i]); - - for ($i=156,$chks+=256; $i<512; $i++) - $chks += ord($p_dat[$i]); - - $headers = @unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor", $p_dat); - if(!$headers) return false; - - $return['checksum'] = OctDec(trim($headers['checksum'])); - if ($return['checksum'] != $chks) return false; - - $return['filename'] = trim($headers['filename']); - $return['mode'] = OctDec(trim($headers['mode'])); - $return['uid'] = OctDec(trim($headers['uid'])); - $return['gid'] = OctDec(trim($headers['gid'])); - $return['size'] = OctDec(trim($headers['size'])); - $return['mtime'] = OctDec(trim($headers['mtime'])); - $return['typeflag'] = $headers['typeflag']; - $return['link'] = trim($headers['link']); - $return['uname'] = trim($headers['uname']); - $return['gname'] = trim($headers['gname']); - - return $return; - } - - function _fetchFilelist($p_filelist) - { - if(!$p_filelist || (is_array($p_filelist) && !@count($p_filelist))) return false; - - if(is_string($p_filelist)) - { - $p_filelist = explode('|',$p_filelist); - if(!is_array($p_filelist)) $p_filelist = Array($p_filelist); + + /** + * Extract part or totality of the archive. + * + * This function can extract files from an archive, and returns then a + * status codes that can be converted with TarErrorStr() into a + * human readable message. + * + * Only the first argument is required, What and it can be either the + * constant FULL_ARCHIVE or an indexed array containing each file you want to + * extract. + * + * To contains the target folder to extract the archive. It is optional and + * the default value is '.' which means the current folder. If the target + * folder doesn't exist, the script attempts to create it and give it + * permissions 0777 by default. + * + * RemovePath is very usefull when you want to extract files from a subfoler + * in the archive to a root folder. For instance, if you have a file in the + * archive called some/sub/folder/test.txt and you want to extract it to the + * script folder, you can call Extract with To = '.' and RemovePath = + * 'some/sub/folder/' + * + * FileMode is optional and its default value is 0755. It is in fact the UNIX + * permission in octal mode (prefixed with a 0) that will be given on each + * extracted file. + */ + function Extract($p_what = FULL_ARCHIVE, $p_to = '.', $p_remdir='', $p_mode = 0755) { + if(!$this->_OpenRead()) return -4; + // if(!@is_dir($p_to)) if(!@mkdir($p_to, 0777)) return -8; --CS + if(!@is_dir($p_to)) if(!$this->_dirApp($p_to)) return -8; //--CS (route through correct dir fn) + + $ok = $this->_extractList($p_to, $p_what, $p_remdir, $p_mode); + $this->_CompTar(); + + return $ok; } - return $p_filelist; - } + /** + * Create a new package with the given files + * + * This function will attempt to create a new archive with global headers + * then add the given files into. If the archive is a real file, the + * contents are written directly into the file, if it is a dynamic archive + * contents are only stored in memory. This function should not be used to + * add files to an existing archive, you should use Add() instead. + * + * The FileList actually supports three different modes : + * + * - You can pass a string containing filenames separated by pipes '|'. + * In this case the file are read from the webserver filesystem and the + * root folder is the folder where the script using the MaxgTar is called. + * + * - You can also give a unidimensional indexed array containing the + * filenames. The behaviour for the content reading is the same that a + * '|'ed string. + * + * - The more useful usage is to pass bidimensional arrays, where the + * first element contains the filename and the second contains the file + * contents. You can even add empty folders to the package if the filename + * has a leading '/'. Once again, have a look at the exemples to understand + * better. + * + * Note you can also give arrays with both dynamic contents and static files. + * + * The optional parameter RemovePath can be used to delete a part of the tree + * of the filename you're adding, for instance if you're adding in the root + * of a package a file that is stored somewhere in the server tree. + * + * On the contrary the parameter AddPath can be used to add a prefix folder + * to the file you store. Note also that the RemovePath is applied before the + * AddPath is added, so it HAS a sense to use both parameters together. + */ + function Create($p_filelist,$p_add='',$p_rem='') { + if(!$fl = $this->_fetchFilelist($p_filelist)) return -5; + if(!$this->_OpenWrite()) return -6; + + $ok = $this->_addFileList($fl,$p_add,$p_rem); + + if($ok){ + $this->_writeFooter(); + }else{ + $this->_CompTar(); + @unlink($this->_nomf); + } - function _addFileList($p_fl, $p_addir, $p_remdir) - { - foreach($p_fl as $file) - { - if(($file == $this->_nomf && $this->_nomf != ARCHIVE_DYNAMIC) || !$file || (!file_exists($file) && !is_array($file))) - continue; + return $ok; + } - if (!$this->_addFile($file, $p_addir, $p_remdir)) - continue; + /** + * Add files to an existing package. + * + * This function does exactly the same than Create() exept it + * will append the given files at the end of the archive. Please not the is + * safe to call Add() on a newly created archive whereas the + * contrary will fail ! + * + * This function returns a status code, you can use TarErrorStr() on + * it to get the human-readable description of the error. + */ + function Add($p_filelist, $p_add = '', $p_rem = '') { + if (($this->_nomf != ARCHIVE_DYNAMIC && @is_file($this->_nomf)) || + ($this->_nomf == ARCHIVE_DYNAMIC && !$this->_memdat)){ + return $this->Create($p_filelist, $p_add, $p_rem); + } - if (@is_dir($file)) - { - $d = @opendir($file); + if(!$fl = $this->_fetchFilelist($p_filelist)) return -5; + return $this->_append($fl, $p_add, $p_rem); + } - if(!$d) continue; - readdir($d); readdir($d); + /** + * Read the contents of a TAR archive + * + * This function attempts to get the list of the files stored in the + * archive, and return either an error code or an indexed array of + * associative array containing for each file the following informations : + * + * checksum Tar Checksum of the file + * filename The full name of the stored file (up to 100 c.) + * mode UNIX permissions in DECIMAL, not octal + * uid The Owner ID + * gid The Group ID + * size Uncompressed filesize + * mtime Timestamp of last modification + * typeflag Empty for files, set for folders + * link For the links, did you guess it ? + * uname Owner name + * gname Group name + */ + function ListContents() { + if(!$this->_nomf) return -3; + if(!$this->_OpenRead()) return -4; + + $result = Array(); + + while ($dat = $this->_read(512)) { + $dat = $this->_readHeader($dat); + if(!is_array($dat)) continue; + + $this->_seek(ceil($dat['size']/512)*512,1); + $result[] = $dat; + } + + return $result; + } - while($f = readdir($d)) - { - if($file != ".") $tmplist[0] = "$file/$f"; - else $tmplist[0] = $d; + /** + * Convert a status code into a human readable message + * + * Some MaxgTar functions like Create(), Add() ... return numerical + * status code. You can pass them to this function to grab their english + * equivalent. + */ + function TarErrorStr($i) { + $ecodes = Array( + 1 => true, + 0 => "Undocumented error", + -1 => "Can't use COMPRESS_GZIP compression : ZLIB extensions are not loaded !", + -2 => "Can't use COMPRESS_BZIP compression : BZ2 extensions are not loaded !", + -3 => "You must set a archive file to read the contents !", + -4 => "Can't open the archive file for read !", + -5 => "Invalide file list !", + -6 => "Can't open the archive in write mode !", + -7 => "There is no ARCHIVE_DYNAMIC to write !", + -8 => "Can't create the directory to extract files !", + -9 => "Please pass a archive name to send if you made created an ARCHIVE_DYNAMIC !", + -10 => "You didn't pass an archive filename and there is no stored ARCHIVE_DYNAMIC !", + -11 => "Given archive doesn't exist !" + ); + + return isset($ecodes[$i]) ? $ecodes[$i] : $ecodes[0]; + } - $this->_addFileList($tmplist, $p_addir, $p_remdir); + /** + * Display informations about the MaxgTar Class. + * + * This function will display vaious informations about the server + * MaxgTar is running on. + * + * The optional parameter DispHeaders is used to generate a full page with + * HTML headers (TRUE by default) or just the table with the informations + * (FALSE). Note that the HTML page generated is verified compatible XHTML + * 1.0, but not HTML 4.0 compatible. + */ + function TarInfo($headers = true) { + if($headers) { + ?> + + + + + MaxgComp TAR + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MaxgComp TAR
This software was created by the Maxg Network, http://maxg.info +
It is distributed under the GNU Lesser General Public License +
You can find the documentation of this class here
MaxgComp TAR
MaxgComp TAR version
ZLIB extensionsYes' : 'No')?>
BZ2 extensionsYes' : 'No')?>
Allow URL fopenYes' : 'No')?>
Time limit
PHP Version
+ Special thanks to « Vincent Blavet » for his PEAR::Archive_Tar class +
+ '; + } - closedir($d); unset($tmplist,$f); - } + function _seek($p_flen, $tell=0) { + if($this->_nomf === ARCHIVE_DYNAMIC) + $this->_memdat=substr($this->_memdat,0,($tell ? strlen($this->_memdat) : 0) + $p_flen); + elseif($this->_comptype == COMPRESS_GZIP) + @gzseek($this->_fp, ($tell ? @gztell($this->_fp) : 0)+$p_flen); + elseif($this->_comptype == COMPRESS_BZIP) + @fseek($this->_fp, ($tell ? @ftell($this->_fp) : 0)+$p_flen); + else + @fseek($this->_fp, ($tell ? @ftell($this->_fp) : 0)+$p_flen); } - return true; - } - function _addFile($p_fn, $p_addir = '', $p_remdir = '') - { - if(is_array($p_fn)) list($p_fn, $data) = $p_fn; - $sname = $p_fn; + function _OpenRead() { + if($this->_comptype == COMPRESS_GZIP) + $this->_fp = @gzopen($this->_nomf, 'rb'); + elseif($this->_comptype == COMPRESS_BZIP) + $this->_fp = @bzopen($this->_nomf, 'rb'); + else + $this->_fp = @fopen($this->_nomf, 'rb'); + + return ($this->_fp ? true : false); + } - if($p_remdir) - { - if(substr($p_remdir,-1) != '/') $p_remdir .= "/"; + function _OpenWrite($add = 'w') { + if($this->_nomf === ARCHIVE_DYNAMIC) return true; + + if($this->_comptype == COMPRESS_GZIP) + $this->_fp = @gzopen($this->_nomf, $add.'b'.$this->_compzlevel); + elseif($this->_comptype == COMPRESS_BZIP) + $this->_fp = @bzopen($this->_nomf, $add.'b'); + else + $this->_fp = @fopen($this->_nomf, $add.'b'); - if(substr($sname, 0, strlen($p_remdir)) == $p_remdir) - $sname = substr($sname, strlen($p_remdir)); + return ($this->_fp ? true : false); } - if($p_addir) $sname = $p_addir.(substr($p_addir,-1) == '/' ? '' : "/").$sname; + function _CompTar() { + if($this->_nomf === ARCHIVE_DYNAMIC || !$this->_fp) return; - if(strlen($sname) > 99) return; + if($this->_comptype == COMPRESS_GZIP) @gzclose($this->_fp); + elseif($this->_comptype == COMPRESS_BZIP) @bzclose($this->_fp); + else @fclose($this->_fp); + } + + function _read($p_len) { + if($this->_comptype == COMPRESS_GZIP) + return @gzread($this->_fp,$p_len); + elseif($this->_comptype == COMPRESS_BZIP) + return @bzread($this->_fp,$p_len); + else + return @fread($this->_fp,$p_len); + } + + function _write($p_data) { + if($this->_nomf === ARCHIVE_DYNAMIC) $this->_memdat .= $p_data; + elseif($this->_comptype == COMPRESS_GZIP) + return @gzwrite($this->_fp,$p_data); - if(@is_dir($p_fn)) - { - if(!$this->_writeFileHeader($p_fn, $sname)) return false; + elseif($this->_comptype == COMPRESS_BZIP) + return @bzwrite($this->_fp,$p_data); + + else + return @fwrite($this->_fp,$p_data); } - else - { - if(!$data) - { - $fp = fopen($p_fn, 'rb'); - if(!$fp) return false; - } - - if(!$this->_writeFileHeader($p_fn, $sname, ($data ? strlen($data) : false))) return false; - - if(!$data) - { - while(!feof($fp)) - { - $packed = pack("a512", fread($fp,512)); - $this->_write($packed); - } - fclose($fp); - } - else - { - for($s = 0; $s < strlen($data); $s += 512) - $this->_write(pack("a512",substr($data,$s,512))); - } + + function _encode($p_dat) { + if($this->_comptype == COMPRESS_GZIP) + return gzencode($p_dat, $this->_compzlevel); + elseif($this->_comptype == COMPRESS_BZIP) + return bzcompress($p_dat, $this->_compzlevel); + else return $p_dat; } - return true; - } - - function _writeFileHeader($p_file, $p_sname, $p_data=false) - { - if(!$p_data) - { - if (!$p_sname) $p_sname = $p_file; - $p_sname = $this->_pathTrans($p_sname); - - $h_info = stat($p_file); - $h[0] = sprintf("%6s ", DecOct($h_info[4])); - $h[] = sprintf("%6s ", DecOct($h_info[5])); - $h[] = sprintf("%6s ", DecOct(fileperms($p_file))); - clearstatcache(); - $h[] = sprintf("%11s ", DecOct(filesize($p_file))); - $h[] = sprintf("%11s", DecOct(filemtime($p_file))); - - $dir = @is_dir($p_file) ? '5' : ''; - } - else - { - $dir = ''; - $p_data = sprintf("%11s ", DecOct($p_data)); - $time = sprintf("%11s ", DecOct(time())); - $h = Array(" 0 "," 0 "," 40777 ",$p_data,$time); - } - - $data_first = pack("a100a8a8a8a12A12", $p_sname, $h[2], $h[0], $h[1], $h[3], $h[4]); - $data_last = pack("a1a100a6a2a32a32a8a8a155a12", $dir, '', '', '', '', '', '', '', '', ""); - - for ($i=0,$chks=0; $i<148; $i++) - $chks += ord($data_first[$i]); - - for ($i=156, $chks+=256, $j=0; $i<512; $i++, $j++) - $chks += ord($data_last[$j]); - - $this->_write($data_first); - - $chks = pack("a8",sprintf("%6s ", DecOct($chks))); - $this->_write($chks.$data_last); - - return true; - } - - function _append($p_filelist, $p_addir="", $p_remdir="") - { - if(!$this->_fp) if(!$this->_OpenWrite('a')) return -6; - - if($this->_nomf == ARCHIVE_DYNAMIC) - { - $s = strlen($this->_memdat); - $this->_memdat = substr($this->_memdat,0,-512); + function _readHeader($p_dat) { + if (!$p_dat || strlen($p_dat) != 512) return false; + + for ($i=0, $chks=0; $i<148; $i++) + $chks += ord($p_dat[$i]); + + for ($i=156,$chks+=256; $i<512; $i++) + $chks += ord($p_dat[$i]); + + $headers = @unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor", $p_dat); + if(!$headers) return false; + + $return['checksum'] = OctDec(trim($headers['checksum'])); + if ($return['checksum'] != $chks) return false; + + $return['filename'] = trim($headers['filename']); + $return['mode'] = OctDec(trim($headers['mode'])); + $return['uid'] = OctDec(trim($headers['uid'])); + $return['gid'] = OctDec(trim($headers['gid'])); + $return['size'] = OctDec(trim($headers['size'])); + $return['mtime'] = OctDec(trim($headers['mtime'])); + $return['typeflag'] = $headers['typeflag']; + $return['link'] = trim($headers['link']); + $return['uname'] = trim($headers['uname']); + $return['gname'] = trim($headers['gname']); + + return $return; } - else - { - $s = filesize($this->_nomf); - $this->_seek($s-512); + + function _fetchFilelist($p_filelist) { + if(!$p_filelist || (is_array($p_filelist) && !@count($p_filelist))) return false; + + if(is_string($p_filelist)) { + $p_filelist = explode('|',$p_filelist); + if(!is_array($p_filelist)) $p_filelist = Array($p_filelist); + } + + return $p_filelist; } - $ok = $this->_addFileList($p_filelist, $p_addir, $p_remdir); - $this->_writeFooter(); - - return $ok; - } - - function _pathTrans($p_dir) - { - if ($p_dir) - { - $subf = explode("/", $p_dir); $r=''; - - for ($i=count($subf)-1; $i>=0; $i--) - { - if ($subf[$i] == ".") {} - else if ($subf[$i] == "..") $i--; - else if (!$subf[$i] && $i!=count($subf)-1 && $i) {} - else $r = $subf[$i].($i!=(count($subf)-1) ? "/".$r : ""); - } + function _addFileList($p_fl, $p_addir, $p_remdir) { + foreach($p_fl as $file) { + if(($file == $this->_nomf && $this->_nomf != ARCHIVE_DYNAMIC) || !$file || (!file_exists($file) && !is_array($file))) + continue; + + if (!$this->_addFile($file, $p_addir, $p_remdir)) + continue; + + if (@is_dir($file)) { + $d = @opendir($file); + + if(!$d) continue; + readdir($d); + readdir($d); + + while($f = readdir($d)) { + if($file != ".") $tmplist[0] = "$file/$f"; + else $tmplist[0] = $d; + + $this->_addFileList($tmplist, $p_addir, $p_remdir); + } + + closedir($d); + unset($tmplist,$f); + } + } + return true; } - return $r; - } - - function _writeFooter() - { - $this->_write(pack("a512", "")); - } - - function _extractList($p_to, $p_files, $p_remdir, $p_mode = 0755) - { - if (!$p_to || ($p_to[0]!="/"&&substr($p_to,0,3)!="../"&&substr($p_to,1,3)!=":\\"&&substr($p_to,1,2)!=":/")) /*" // <- PHP Coder bug */ - $p_to = "./$p_to"; - - if ($p_remdir && substr($p_remdir,-1)!='/') $p_remdir .= '/'; - $p_remdirs = strlen($p_remdir); - while($dat = $this->_read(512)) - { - $headers = $this->_readHeader($dat); - if(!$headers['filename']) continue; - - if($p_files == -1 || $p_files[0] == -1) $extract = true; - else - { - $extract = false; - - foreach($p_files as $f) - { - if(substr($f,-1) == "/") { - if((strlen($headers['filename']) > strlen($f)) && (substr($headers['filename'],0,strlen($f))==$f)) { - $extract = true; break; + + function _addFile($p_fn, $p_addir = '', $p_remdir = '') { + if(is_array($p_fn)) list($p_fn, $data) = $p_fn; + $sname = $p_fn; + + if($p_remdir) { + if(substr($p_remdir,-1) != '/') $p_remdir .= "/"; + + if(substr($sname, 0, strlen($p_remdir)) == $p_remdir) + $sname = substr($sname, strlen($p_remdir)); + } + + if($p_addir) $sname = $p_addir.(substr($p_addir,-1) == '/' ? '' : "/").$sname; + + if(strlen($sname) > 99) return; + + if(@is_dir($p_fn)) { + if(!$this->_writeFileHeader($p_fn, $sname)) return false; + } else { + if(!$data) { + $fp = fopen($p_fn, 'rb'); + if(!$fp) return false; + } + + if(!$this->_writeFileHeader($p_fn, $sname, ($data ? strlen($data) : false))) return false; + + if(!$data) { + while(!feof($fp)) { + $packed = pack("a512", fread($fp,512)); + $this->_write($packed); + } + fclose($fp); + } else { + $len = strlen($data); + for($s = 0; $s < $len; $s += 512){ + $this->_write(pack("a512",substr($data,$s,512))); + } } - } - elseif($f == $headers['filename']) { - $extract = true; break; - } } - } - if ($extract) - { - $det[] = $headers; - if ($p_remdir && substr($headers['filename'],0,$p_remdirs)==$p_remdir) - $headers['filename'] = substr($headers['filename'],$p_remdirs); + return true; + } + + function _writeFileHeader($p_file, $p_sname, $p_data=false) { + if(!$p_data) { + if (!$p_sname) $p_sname = $p_file; + $p_sname = $this->_pathTrans($p_sname); + + $h_info = stat($p_file); + $h[0] = sprintf("%6s ", DecOct($h_info[4])); + $h[] = sprintf("%6s ", DecOct($h_info[5])); + $h[] = sprintf("%6s ", DecOct(fileperms($p_file))); + clearstatcache(); + $h[] = sprintf("%11s ", DecOct(filesize($p_file))); + $h[] = sprintf("%11s", DecOct(filemtime($p_file))); + + $dir = @is_dir($p_file) ? '5' : ''; + } else { + $dir = ''; + $p_data = sprintf("%11s ", DecOct($p_data)); + $time = sprintf("%11s ", DecOct(time())); + $h = Array(" 0 "," 0 "," 40777 ",$p_data,$time); + } - if($headers['filename'].'/' == $p_remdir && $headers['typeflag']=='5') continue; + $data_first = pack("a100a8a8a8a12A12", $p_sname, $h[2], $h[0], $h[1], $h[3], $h[4]); + $data_last = pack("a1a100a6a2a32a32a8a8a155a12", $dir, '', '', '', '', '', '', '', '', ""); - if ($p_to != "./" && $p_to != "/") - { - while($p_to{-1}=="/") $p_to = substr($p_to,0,-1); + for ($i=0,$chks=0; $i<148; $i++) + $chks += ord($data_first[$i]); + + for ($i=156, $chks+=256, $j=0; $i<512; $i++, $j++) + $chks += ord($data_last[$j]); + + $this->_write($data_first); + + $chks = pack("a8",sprintf("%6s ", DecOct($chks))); + $this->_write($chks.$data_last); + + return true; + } - if($headers['filename']{0} == "/") - $headers['filename'] = $p_to.$headers['filename']; - else - $headers['filename'] = $p_to."/".$headers['filename']; + function _append($p_filelist, $p_addir="", $p_remdir="") { + if(!$this->_fp) if(!$this->_OpenWrite('a')) return -6; + + if($this->_nomf == ARCHIVE_DYNAMIC) { + $s = strlen($this->_memdat); + $this->_memdat = substr($this->_memdat,0,-512); + } else { + $s = filesize($this->_nomf); + $this->_seek($s-512); } - $ok = $this->_dirApp($headers['typeflag']=="5" ? $headers['filename'] : dirname($headers['filename'])); - if($ok < 0) return $ok; + $ok = $this->_addFileList($p_filelist, $p_addir, $p_remdir); + $this->_writeFooter(); + + return $ok; + } + + function _pathTrans($p_dir) { + if ($p_dir) { + $subf = explode("/", $p_dir); + $r=''; + + for ($i=count($subf)-1; $i>=0; $i--) { + if ($subf[$i] == ".") { + # do nothing + } elseif ($subf[$i] == "..") { + $i--; + } elseif (!$subf[$i] && $i!=count($subf)-1 && $i) { + # do nothing + } else { + $r = $subf[$i].($i!=(count($subf)-1) ? "/".$r : ""); + } + } + } + return $r; + } - if (!$headers['typeflag']) - { - if (!$fp = @fopen($headers['filename'], "wb")) return -6; - $n = floor($headers['size']/512); + function _writeFooter() { + $this->_write(pack("a512", "")); + } - for ($i=0; $i<$n; $i++) fwrite($fp, $this->_read(512),512); - if (($headers['size'] % 512) != 0) fwrite($fp, $this->_read(512), $headers['size'] % 512); + function _extractList($p_to, $p_files, $p_remdir, $p_mode = 0755) { + if (!$p_to || ($p_to[0]!="/"&&substr($p_to,0,3)!="../"&&substr($p_to,1,3)!=":\\"&&substr($p_to,1,2)!=":/")) /*" // <- PHP Coder bug */ + $p_to = "./$p_to"; + + if ($p_remdir && substr($p_remdir,-1)!='/') $p_remdir .= '/'; + $p_remdirs = strlen($p_remdir); + while($dat = $this->_read(512)) { + $headers = $this->_readHeader($dat); + if(!$headers['filename']) continue; + + if($p_files == -1 || $p_files[0] == -1){ + $extract = true; + } else { + $extract = false; + + foreach($p_files as $f) { + if(substr($f,-1) == "/") { + if((strlen($headers['filename']) > strlen($f)) && (substr($headers['filename'],0,strlen($f))==$f)) { + $extract = true; + break; + } + } elseif($f == $headers['filename']) { + $extract = true; + break; + } + } + } - fclose($fp); - touch($headers['filename'], $headers['mtime']); - chmod($headers['filename'], $p_mode); + if ($extract) { + $det[] = $headers; + if ($p_remdir && substr($headers['filename'],0,$p_remdirs)==$p_remdir) + $headers['filename'] = substr($headers['filename'],$p_remdirs); + + if($headers['filename'].'/' == $p_remdir && $headers['typeflag']=='5') continue; + + if ($p_to != "./" && $p_to != "/") { + while($p_to{-1}=="/") $p_to = substr($p_to,0,-1); + + if($headers['filename']{0} == "/") + $headers['filename'] = $p_to.$headers['filename']; + else + $headers['filename'] = $p_to."/".$headers['filename']; + } + + $ok = $this->_dirApp($headers['typeflag']=="5" ? $headers['filename'] : dirname($headers['filename'])); + if($ok < 0) return $ok; + + if (!$headers['typeflag']) { + if (!$fp = @fopen($headers['filename'], "wb")) return -6; + $n = floor($headers['size']/512); + + for ($i=0; $i<$n; $i++){ + fwrite($fp, $this->_read(512),512); + } + if (($headers['size'] % 512) != 0) fwrite($fp, $this->_read(512), $headers['size'] % 512); + + fclose($fp); + touch($headers['filename'], $headers['mtime']); + chmod($headers['filename'], $p_mode); + } else { + $this->_seek(ceil($headers['size']/512)*512,1); + } + }else $this->_seek(ceil($headers['size']/512)*512,1); } - else - { - $this->_seek(ceil($headers['size']/512)*512,1); - } - }else $this->_seek(ceil($headers['size']/512)*512,1); + return $det; } - return $det; - } - -function _dirApp($d) - { -// map to dokuwiki function (its more robust) - return io_mkdir_p($d); -/* - $d = explode('/', $d); - $base = ''; - - foreach($d as $f) - { - if(!is_dir($base.$f)) - { - $ok = @mkdir($base.$f, 0777); - if(!$ok) return false; - } - $base .= "$f/"; + + function _dirApp($d) { + // map to dokuwiki function (its more robust) + return io_mkdir_p($d); } -*/ - } } -- cgit v1.2.3