<?php
/*
 * mwebadmin.php - a simple Web-based file manager
 * Copyright (C) 2011  schplurtz le deboulonne <schplurtz@laposte.net>
 * This is based on Daniel Wacker <daniel.wacker@web.de> webadmin.php script and
 * includes MaxgTar class by Bouchon <tarlib@bouchon.org> (Maxg)
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * -------------------------------------------------------------------------
 * While using this script, do NOT navigate with your browser's back and
 * forward buttons! Always open files in a new browser tab!
 * -------------------------------------------------------------------------
 *
 * This is Version 1.02.
 * =========================================================================
 * Changes of Version 1.02 revision
 * schplurtz@laposte.net
 *	fixed bug that prevented to create tar file when files to tar are
 *	bigger than 512 bytes.
 * Changes of Version 1.01 revision
 * <schplurtz@laposte.net>
 *    special things for free.fr
 *    added MaxgTar and ZipLib classes by bouchon
 *    added actions: complex_extract, rec_list, rec_list_details, send_tar, gunzip
 *    uses editarea if edit_area dir in same dir as mwebadmin.
 *    reordered columns
 *    time_zone
 *    other changes I don't remember
 * Changes of version 0.90
 *    import from latest version by daniel wacker.
/* ------------------------------------------------------------------------- */
/*
 * Your settings
 */

$runningatfree=false;
if( isset( $_SERVER['SERVER_NAME'] ) && substr( $_SERVER['SERVER_NAME'], -8 ) === '.free.fr' ) {
$runningatfree=true;
/*
 * Only used when hosted at .free.fr  | SEULEMENT UTILISE CHEZ .free.fr
 * The name of the directory that acts| Le nom du dossier qui servira de
 * as trash for empty dirs, since PHP | poubelle a dossier, puisque chez free.fr
 * can't remove dirs at .free.fr .    | PHP ne peut **pas** detruire de dossier.
 * The directory                      | Le dossier sera
 * will be created on demand.         | cree a la demande.
 */
$freefrdirtrash=$_SERVER['DOCUMENT_ROOT'].'/poubelle';
}

/*
 * Your Time zone. Only used if PHP cannot guess it.
 * see http://php.net/manual/en/timezones.php for possible values.
 */
$TimeZone='Europe/Paris';

/* Your language:
 * 'en' - English
 * 'de' - German
 * 'fr' - French
 * 'it' - Italian
 * 'nl' - Dutch
 * 'se' - Swedish
 * 'sp' - Spanish
 * 'dk' - Danish
 * 'tr' - Turkish
 * 'cs' - Czech
 * 'ru' - Russian
 * 'auto' - autoselect
 */
$lang = 'auto';

/* Charset of output:
 * possible values are described in the charset table at
 * http://www.php.net/manual/en/function.htmlentities.php
 * 'auto' - use the same charset as the words of my language are encoded
 */
$site_charset = 'auto';

/* Homedir:
 * For example: './' - the script's directory
 */
$homedir = './';

/* Size of the edit textarea
 */
$editcols = 100;
$editrows = 25;

/* -------------------------------------------
 * Optional configuration (remove # to enable)
 */

/*
 * default action for files and directory
 */
$file_default_action='edit';
$dir_default_action='send_tar';
/* Permission of created directories:
 * For example: 0705 would be 'drwx---r-x'.
 */
$dirpermission = 0755;

/* Permission of created files:
 * For example: 0604 would be '-rw----r--'.
 */
$filepermission = 0644;

/* Filenames related to the apache web server:
 */
$htaccess = '.htaccess';
$htpasswd = '.htpasswd';

/* ------------------------------------------------------------------------- */
if( '' == ini_get('date.timezone') && function_exists('date_default_timezone_set'))
	date_default_timezone_set( $TimeZone );
if (!function_exists('lstat')) {
	function lstat ($filename) {
		return stat($filename);
	}
}


/* vim: se ts=4 sw=4 noet*/
/**
 * TAR format class - Creates TAR archives
 *
 * This class is part or the MaxgComp suite and originally named
 * MaxgTar class.
 *
 * @license GPL
 * @link    http://docs.maxg.info
 * @author  Bouchon <tarlib@bouchon.org> (Maxg)
 * @author  Christopher Smith <chris@jalakai.co.uk>
 */


define('COMPRESS_GZIP',1);
define('COMPRESS_BZIP',2);
define('COMPRESS_AUTO',4);
define('COMPRESS_NONE',0);
define('COMPRESS_RENAMECOMP',32);
# COMPRESS_RENAMECOMP|COMPRESS_AUTO (php doesn't like X*Y in default param val)
define('COMPRESS_AUTORENAME', 36);

define('TARLIB_VERSION','1.2-cm');
define('ARCHLIB_EXTRACT_P',1);
define('ARCHLIB_DONE_SUCCESS',2);
define('ARCHLIB_DONE_FAIL',4);
define('ARCHLIB_DONE_IGNORE',8);
define('ARCHLIB_OK_NOEXTRACT',16);
define('ARCHLIB_END',32);
define('FULL_ARCHIVE',-1);

define('ARCHIVE_DYNAMIC',0);
define('COMPRESS_DETECT',64);



# typical usages
# 1)
#new tar( tarfile, compress_method )
#loop 0-n
#	loop 0-n
#		tar addfile
#	tar write ( one of : tar Create, tar Append,tar SendToClient)
# 2)
#new tar( ARCHIVE_DYNAMIC, compress_method )
#loop 0-n
#	loop 0-n
#		tar addfile
#	tar SendToClient
# 3)
#new tar( tarfile, compress_method )
#	tar getfilelist
#	tar extract
#$tar = new tar;
##$tar->setarchive( 'titi.tar.gz', COMPRESS_GZIP );
##$tar->add( '.' );
##foreach( $tar->_filelist as $n )
##	echo "\tliste >{$n->name}<\n";
##$tar->Create();
#$tar->setarchive( 'phpe.tar', COMPRESS_NONE );
#$tar->add( 'tutu' );
#$tar->Create();
##$tar->append();
#
#echo "nomf {$tar->_nomf}\n";
class tar {

	var $_nomf;
	var $_comptype;
	var $_compzlevel;
	var $_result;
	var $_filelist;
	var $_cache_realnomf;
	var $_cache_basenomf;
	var $_fp;
	var $_data;


	// Constructor
	function tar( $p_filen = ARCHIVE_DYNAMIC , $p_comptype = COMPRESS_AUTORENAME, $p_complevel = 9)
	{
		$this->_filelist=array();
		$this->_fp=NULL;
		$this->_result=NULL;
		$this->_data=NULL;
		$this->_setoptions($p_filen, $p_comptype, $p_complevel);
	}
	function _setoptions( $p_filen, $p_comptype, $p_complevel)
	{
		$this->_result = 0;
		$this->_data=NULL;
		$this->_closearch();
		$flag=0;

		if(!($p_complevel > 0 && $p_complevel <= 9))
			$p_complevel = 9;
		$this->_compzlevel = $p_complevel;

		if(($p_comptype & 7) && ($p_comptype & COMPRESS_RENAMECOMP)) {
			$p_comptype -= COMPRESS_RENAMECOMP;
			$flag=1;
		}

		if( ($p_filen === ARCHIVE_DYNAMIC) ) {
			$flag=0;
		}
		elseif(COMPRESS_AUTO == $p_comptype && 
		     @file_exists($p_filen))
		{
			$flag=0;
			$p_comptype=COMPRESS_DETECT;
		}
		if( $p_comptype == COMPRESS_DETECT ) {
			if(strtolower(substr($p_filen,-3)) == '.gz' ||
			   strtolower(substr($p_filen,-4)) == '.tgz')
				$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->_result = -1;
			$this->_comptype = COMPRESS_GZIP;
		break;

		case COMPRESS_BZIP:
			if(!extension_loaded('bz2'))
				$this->_result = -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->_result < 0)
			$this->_comptype = COMPRESS_NONE;

		if($flag) {
			if(strtolower(substr($p_filen, -4)) == '.tar')
				$p_filen=substr( $p_filen, 0, -4 );
			elseif(strtolower(substr($p_filen, -4)) == '.tgz')
				$p_filen=substr( $p_filen, 0, -4 );
			elseif(strtolower(substr($p_filen, -7)) == '.tar.gz')
				$p_filen=substr( $p_filen, 0, -7 );
			elseif(strtolower(substr($p_filen, -8)) == '.tar.bz2')
				$p_filen=substr( $p_filen, 0, -8 );
			$p_filen .= '.'.$this->getCompression(1);
		}
		$this->_nomf=$p_filen;
		if($p_filen !== ARCHIVE_DYNAMIC) {
			$this->_cache_realnomf = realpath( $p_filen );
			$this->_cache_basenomf = basename( $p_filen );
		}
		else {
			$this->_cache_realnomf = NULL;
			$this->_cache_basenomf = NULL;
		}
		return $this->_result;
	}

	function result() {
		return $this->_result;
	}
	function setArchive($p_name='', $p_comp = COMPRESS_AUTORENAME, $p_level=9)
	{
		$this->_closearch();
		$this->_setoptions($p_name, $p_comp, $p_level);
		return $this->_result;
	}
	function getArchive()
	{
		return $this->_nomf;
	}

	function getCompression($ext = false)
	{
		$exts = Array('tar','tar.gz','tar.bz2');
		if($ext) return $exts[$this->_comptype];
		return $this->_comptype;
	}

	function setCompression($p_comp = COMPRESS_AUTO)
	{
		$this->setArchive($this->_nomf, $p_comp, $this->_compzlevel);
		return $this->_compzlevel;
	}

	function Create()
	{
		if(!$this->_filelist) {
			$this->_result = -7;
			return -7;
		}
		if( $this->_nomf !== ARCHIVE_DYNAMIC ) {
			$this->_openWrite();
			if(!$this->_fp) {
				$this->_result = -6;
				return -6;
			}

			foreach( $this->_filelist as $f ) {
				if( !$this->_rwrite( $f->name, $f->rem, $f->add, $f->data )) {
					$this->_result = -14;
					return -14;
				}
			}
			$this->_writeFooter();
			$this->_closearch();

			return true;
		}
		else
			return -15;
	}

	function SendToClient($name = '', $headers = true)
	{
		if(!$name && ($this->_nomf === ARCHIVE_DYNAMIC))
			$name='archive.' . $this->getcompression(1);
		if(!$name && !$this->_nomf) return -9;
		if(!$name) $name = basename($this->_nomf);

		if($headers)
		{
			header('Content-Type: application/x-gtar');
			header('Content-Disposition: attachment; filename='.basename($name));
			header('Accept-Ranges: bytes');
			if( $this->_nomf )
				header('Content-Length: ' . filesize($this->_nomf));
		}
		if( $this->_nomf ) {
			if( ($fp = @fopen( $this->_nomf, "rb" )) === FALSE )
				return -6;
			while(($buf = fread($fp,8192)) != '') {
				echo $buf;
			}
			if($buf === FALSE)
				return -15;
			fclose($fp);
			return true;
		}
		foreach( $this->_filelist as $f ) {
			$this->_rwrite( $f->name, $f->rem, $f->add, $f->data );
		}
		$this->_writeFooter();
		$this->_closearch();

		return true;
	}

	function Extract($p_what = FULL_ARCHIVE, $p_to = '.', $p_subst=null, $p_mode=0755, $callback=null)
	{
		if(!$this->_OpenRead()) { return -4; }
		if(!@is_dir($p_to)) if(!$this->_mkdir($p_to, $p_mode)) return $this->_result=-8;
		$ok = $this->_extractList($p_what, $p_to, $p_subst, $p_mode, $callback);
		$this->_closearch();

		return $ok;
	}

	/**
	 * List archive contents. put results in $this->data
	 * 
	 * @param $limit maximum number of files to list. default is 0x7fffffff
	 * @return always true.
	 */
	function ListContents($limit=0x7fffffff)
	{
		if(!$this->_nomf) return $this->_result=-3;
		if(!$this->_OpenRead()) return $this->_result=-4;

		$this->_data = array();

		$n=0;
		while ($dat = $this->_readnextheader() )
		{
			if(!$limit--) break;
			$this->_seek(ceil($dat['size']/512)*512,1);
			$this->_data[] = $dat;
		}

		$this->_closearch();
		return  true;
	}

	function ErrorStr($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 an ARCHIVE_DYNAMIC !",
		-10 => "You didn't pass an archive filename and there is no stored ARCHIVE_DYNAMIC !",
		-11 => "Given archive doesn't exist !",
		-12 => "Cannot append to anonymous archive",
		-13 => "Can't append to compressed archive",
		-14 => "IO error while operating on file",
		-15 => "Cannot create dynamic archive (use SendToClient())"
		);

		return isset($ecodes[$i]) ? $ecodes[$i] : $ecodes[0];
	}

	function Add($p_filelist, $p_rem = '', $p_add = '')
	{
		if( !is_string( $p_filelist ))
			return $this->_addFileList($p_filelist,$p_rem,$p_add);
		return $this->_addFileList(array($p_filelist),$p_rem,$p_add);
	}

	function Append() {
		if( $this ->_nomf === ARCHIVE_DYNAMIC )
			return -12;
		if( $this->comptype != COMPRESS_NONE )
			return -13;
		if( !$this->_openWrite() )
			return -6;
		$s = filesize($this->_nomf);
		/* FIXME : some (many) tar files are block padded. with block
		  * beeing 10240 bytes or similar
		  * 2 0-filled-512-bytes-header are the mark of the end of archive
		  * but file may contain much more binary zeroes.
		  * Can't just rewind 512 bytes from the end.
		  */  
		$this->_seek($s-512);
		foreach( $this->_filelist as $f ) {
			$this->_rwrite( $f->name, $f->rem, $f->add, $f->data );
		}
		return $ok;
	}

	function _closearch()
	{
		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);
		$this->_fp = NULL;
		// FIXME : should handle errors from the *close function
		$this->_result = 0;
	}

	// FIXME : incorrect return code. at least when recursing subdirs.
	function _rwrite( $name, $rem, $add, $data=NULL )
	{
		$isrealdir=false;
		if( @is_dir( $name ) && !@is_link( $name )) {
			$isrealdir=true;
			if( $name[strlen($name)-1] != '/' )
				$name .= '/';
		}
		if($rem && substr($name, 0, strlen($rem)) == $rem)
			$archname = substr($name, strlen($rem));
		else
			$archname = $name;
		if($add)
			$archname = $add . $archname;
		if( $isrealdir ) {
			$d = @opendir($name);
			if(!$d) return FALSE;
			$this->_writeFileHeader( $name, $archname );

			# AWAIMS '.' and '..' are not necessarily the first 2
			# entries. skipping first 2 entries is not correct.
			# must test all entries.
			while( $f=readdir($d) ) {
				if($f == '.' || $f == '..')
					continue;
				// FIXME : handle return code. Don't pretend there is no
				// error ever by throwing away the return code
				$this->_rwrite($name.$f, $rem, $add );
			}

			closedir($d);
			return true;
		}
		// Plain file or symlink
		$target=NULL;
		if(!$data)
		{
			# do not try to archive ourself
			if( $this->_cache_basenomf == basename($name) &&
			    $this->_cache_realnomf == realpath($name))
				return true;
			if( !@is_link( $name )) {
				$fp = fopen($name, 'rb');
				if(!$fp) return FALSE;
			}
			else {
				$target=@readlink($name);
				if( NULL === $target || '' === $target )
					return FALSE;
			}
		}

		if(!$this->_writeFileHeader($name, $archname, $target, ($data ? strlen($data) : FALSE))) {
			if($fp) fclose($fp);
			return false;
		}
		if( $target !== NULL ) //symlink. done. All is in the header
			return true;

		if(!$data) //real file
		{
			if(($sz=filesize($name))>0) {
				while($sz>511) {
					$tr=$tw=($sz>65535)?65536:(($sz>8191)?8192:$sz-$sz%512);
					/* FIXME . gzwrite returns always 1. Why ?. */
					/*
					$buf=fread($fp,$tw);
					while($tw-=($ec=$this->_write($buf))) {
						$buf=substr($buf,$ec);
					}
					*/
					$this->_write(fread($fp,$tw));
					$sz-=$tr;
				}
				if($sz) {
					$buf=fread($fp,$sz);
					$packed = pack("a512", $buf);
					$this->_write($packed);
				}
			}
			fclose($fp);
		}
		else // file whose data are passed as parameter. Should be short files...
		{
			for($s = 0; $s < strlen($data); $s += 512)
				$this->_write(pack("a512",substr($data,$s,512)));
		}
		return true;
	}

	# only relative and forward (SEEK_CUR) ie tell=1/true, seek supported on bzip znd gzip.
	# No check here. caller MUST check.
	function _seek($p_flen, $tell=0)
	{
		if($this->_comptype == COMPRESS_GZIP)
			@gzseek($this->_fp, ($tell ? @gztell($this->_fp) : 0)+$p_flen);
		elseif($this->_comptype == COMPRESS_BZIP) {
			$n = floor($p_flen/8192);
			for ($i=0; $i<$n; $i++)
				$this->_read(8192);
			if (($p_flen % 8192) != 0)
				$this->_read($p_flen % 8192);
		}
		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, 'r');
		else
			$this->_fp = @fopen($this->_nomf, 'rb');

		return ($this->_fp ? true : false);
	}

	function _OpenWrite($add = 'w')
	{
		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 _read($p_len)
	{
		if($this->_comptype == COMPRESS_GZIP)
			return gzeof($this->_fp) ? false : @gzread($this->_fp,$p_len);
		elseif($this->_comptype == COMPRESS_BZIP)
			return feof($this->_fp) ? false : @bzread($this->_fp,$p_len);
		else
			return feof($this->_fp) ? false : @fread($this->_fp,$p_len);
	}

	function _write($p_data)
	{
		if($this->_nomf === ARCHIVE_DYNAMIC) {
			if( $this->_comptype == COMPRESS_NONE )
				return printf( '%s', $p_data );
			elseif($this->_comptype == COMPRESS_GZIP)
				echo gzencode( $p_data, $this->_compzlevel );
			elseif($this->_comptype == COMPRESS_BZIP)
				echo bzcompress( $p_data );
			return true;
		}
		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);
	}

	/*
	 * return false on any error : nothing to read, or inconsistent
	 * header, or terminating blank header.
	 * return an header array if all is correct. See _parseHeader for array fields
	 *
	 * May readmore than one header block, when it finds a GNU ././@LongLink
	 */
	function _readnextheader() {
		if( !($dat = $this->_read(512)) )
			return false;
		if( !($h = $this->_parseHeader( $dat )) )
			return false;
		if( ($h['typeflag'] == 'K' || $h['typeflag'] == 'L' ) && '././@LongLink' == $h['filename'] ) {
			if( !($d=$this->_read(ceil($h['size']/512)*512)))
				return false;
			$dar= @unpack('a'.$h['size'].'name', $d );
			if( !($dat = $this->_read(512)) )
				return false;
			if( !($h = $this->_parseHeader( $dat )) )
				return false;
			$h['filename']=$dar['name'];
		}
		return $h;
	}

	/*
	 * return false on any error : inconsistent header, or terminating blank header.
	 * return an header array if all is correct.
	 * ['filename']
	 * ['mode']
	 * ['uid']
	 * ['gid']
	 * ['size']
	 * ['mtime']
	 * ['checksum'] TODO : remove this useless field.
	 * ['typeflag']
	 * ['link']
	 * ['uname']
	 * ['gname']
	 *
	 * When typeflag is 3 or 4, those fields are present
	 * ['devmajor']
	 * ['devminor']
	 */
	function _parseHeader($p_dat)
	{
		if (!$p_dat || strlen($p_dat) != 512) return false;

		$headers = @unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor/a155prefix", $p_dat);
		if(!$headers)
			return false;

		/* we return false on bad checksum. This includes the case of tail blank headers */
		if( $headers['typeflag'] != 'K' && $headers['typeflag'] != 'L' ) {
			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]);

			$return['checksum'] = OctDec(trim($headers['checksum']));
			if ($return['checksum'] != $chks) return false;
		} else {
			$return['checksum']=0;
		}
		$return['filename'] = trim($headers['prefix']);
		if( '' !== $return['filename'] )
			$return['filename'] .= '/';
		$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']);
		if( $return['typeflag'] == 3 || $return['typeflag'] == 4 ) {
			$return['devmajor'] = trim($headers['devmajor']);
			$return['devminor'] = trim($headers['devminor']);
		}
		return $return;
	}

	# analyse ONE ''filename''
	# return array of anon objects with members: name, data
	function _normfilelist($p_filelist)
	{
		if(!$p_filelist || (is_array($p_filelist) && !@count($p_filelist)))
			return;

		$x=(object)array();
		if(is_string($p_filelist))
		{
			$p_filelist = explode('|',$p_filelist);
			# I think some old php cant 'return array( ..... )'
			if(!is_array($p_filelist)) {
				$x->name=$p_filelist;
				$x->data=null;
				$x->rem=null;
				$x->add=null;
				$ret=array( $x );
				return $ret;
			}
			$ret=array();
			foreach( $p_filelist as $n ) {
				$x->name=$n;
				$x->data=null;
				$x->rem=null;
				$x->add=null;
				$ret[]=$x;
			}
			return $ret;
		}

		# we get an array of name and data.
		$x->name=$p_filelist[0];
		$x->data=$p_filelist[1];
		$x->rem=null;
		$x->add=null;
		# I think some old php cant 'return array( ..... )'
		$ret=array( $x );
		return $ret;
	}

	function _addFileList($p_fl, $p_remdir, $p_addir)
	{
		if( !empty($p_remdir) && $p_remdir[strlen($p_remdir)-1] != '/' )
			$p_remdir .= '/';
		if( !empty($p_addir) && $p_addir[strlen($p_addir)-1] == '/')
			$p_addir .= '/';
		foreach($p_fl as $file)
		{
			foreach( $this->_normfilelist( $file ) as $f ) {
				if(($f == $this->_nomf && $this->_nomf != ARCHIVE_DYNAMIC) || !$f || !file_exists($file))
					continue;
				$this->_addFile($f, $p_remdir, $p_addir);
			}
		}
		return true;
	}

	function _addFile($p_fn, $p_remdir = '', $p_addir = '')
	{
		if($p_remdir)
		{
			$p_fn->rem=$p_remdir;
		}

		if($p_addir)
			$p_fn->add=$p_addir;

		if(@is_dir($p_fn->name) && !@is_link( $p_fn->name) && $p_fn->name[strlen($p_fn->name)-1] != '/' )
			$p_fn->name .= '/';

		$this->_filelist[]=$p_fn;

	}

	function _writeFileHeader($p_file, $p_name, $lnktgt=NULL, $p_datalength=FALSE)
	{
		$this->_write($this->_fileHeader( $p_file, $p_name, $lnktgt, $p_datalength));

		return true;
	}
	function _fileHeader($p_file, $p_name, $lnktgt=NULL, $p_datalength=FALSE)
	{
		$dir = '';
		if(!$p_datalength)
		{
			$size=0;
			if( $lnktgt !== NULL ) {
				$dir='2';
				$h_info = lstat($p_file);
			}
			else {
				$h_info = stat($p_file);
				if(is_dir($p_file)) {
					$dir='5';
				}
				else {
					$size=$h_info[7];
				}
			}
			$h[0] = sprintf("%6s ", DecOct($h_info[4]));
			$h[] = sprintf("%6s ", DecOct($h_info[5]));
			$h[] = sprintf("%6s ", DecOct($h_info[2]&07777));
			$h[] = sprintf("%11s ", DecOct($size));
			$h[] = sprintf("%11s", DecOct($h_info[9]));
		}
		else
		{
			$p_data = sprintf("%11s ", DecOct($p_data));
			$time = sprintf("%11s ", DecOct(time()));
			$h = Array("     0 ","     0 "," 40777 ",$p_datalength,$time);
		}

		$data_first = pack("a100a8a8a8a12A12", $p_name, $h[2], $h[0], $h[1], $h[3], $h[4]);
		$data_last = pack("a1a100a6a2a32a32a8a8a155a12", $dir, $lnktgt, '', '', '', '', '', '', '', "");

		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]);

		return $data_first . 
			pack("a8",sprintf("%6s ", DecOct($chks))) .
			$data_last;
	}

	function _append($p_filelist, $p_remdir="", $p_addir="")
	{
		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->_addFileList($p_filelist, $p_addir, $p_remdir);
		$this->_writeFooter();

		return $ok;
	}


	function _writeFooter()
	{
		# tar archive end with 2 512-byte headers filled with 0
		$this->_write(pack("a1024", ""));
	}

	# Retroune dans $this->_result le nombre de fichier extraits, le nombre de fichiers avec erreur,
	# et leur noms.
	# _data=array( 'success' => $nsuc, 'fail' => $nfail, 'failed' => array( 'file1', 'file..'))
	function _extractList($p_files, $p_to, $p_subst, $p_mode, $callback)
	{
		$nsuc=$nfail=0;
		$this->_data=array('failed'=>array());
		# Rem 1
		# ../ c'est pas grave, car ./../ est OK . On peut donc simplifier le test au prix
		# d'un peu plus de travail du FS.
		# Rem 2 Meme sous winchose les gens ont le droit d'utilser X:/ au lieu de X:\
		# Rem 3 :
		# Ne perdez pas de vue que $p_to sera utilisé comme ceci : $p_to . '/' . $something
		if (empty($p_to) || ($p_to[0] != "/" && substr($p_to,0,3) != "../") || (DIRECTORY_SEPARATOR == '\\' && rtrim(substr($p_to,1,2), '/\\') != ':')) /*" // <- PHP Coder bug */
			$p_to = "./$p_to";
		if( '/' == $p_to )
			$p_to='';
		else
			$p_to=rtrim($p_to, '/\\');

		while($header = $this->_readnextheader())
		{
			if(!$header['filename']) {
				continue;
			}
			// malicious filename
			if ((strpos($header['filename'], '/../') !== false) ||
			    (strpos($header['filename'], '../') === 0)) {
				$nfail++;
				$this->_data['failed'][]=$header['filename'];
				$this->_forward($header);
				if($callback){
					$callback( ARCHLIB_EXTRACT_P, $header );
					$callback( ARCHLIB_DONE_IGNORE, $header );
				}
				continue;
			}

			if( $callback )
				$extract=$callback( ARCHLIB_EXTRACT_P, $header );
			elseif($p_files == FULL_ARCHIVE || $p_files[0] == FULL_ARCHIVE)
				$extract = true;
			else
			{
				$extract = false;
				foreach($p_files as $f)
				{
					if(substr($f,-1) == '/') {
						if((strlen($header['filename']) > strlen($f)) && (substr($header['filename'],0,strlen($f))==$f)) {
							$extract = true;
							break;
						}
					}
					elseif($f == $header['filename']) {
						$extract = true;
						break;
					}
				}
			}

			if ($extract!==false)
			{
				# compute the actual filename
				# Remove drive letter on win
				# apply substitution on filename
				# remove leading /
				# prepend extract to path.
				$aname=$header['filename'];
				if( DIRECTORY_SEPARATOR == '\\' && $aname{1} == ':' )
					$aname=substr($aname,2);
				if($p_subst)
					$aname=preg_replace($p_subst['from'],$p_subst['to'],$aname);
				$aname=trim($aname,'/');
				$aname=$p_to . '/' . $aname;

				$ok = $this->_dirApp($header['typeflag'] == '5' ? $aname : dirname($aname),$p_mode);
				if(!$ok) {
					$this->_forward($header);
					$nfail++;
					$this->data['failed'][]=$header['filename'];
					$callback && $callback( ARCHLIB_DONE_FAIL, $header );
					continue;
				}

				// '\0' ou '0' are 'old fashion for file' and 'file'. '7'  is
				// 'contiguous file' Whatever this thing may be, I treat it as plain file.
				// Hope I'am not doing things wrong.
				if (!$header['typeflag'] || 7 == $header['typeflag']) /* regular file */
				{
					if (!($fp = @fopen($aname, 'wb'))) {
						$this->_forward($header);
						$nfail++;
						$this->_data['failed'][]=$header['filename'];
						$callback && $callback( ARCHLIB_DONE_FAIL, $header );
						continue;
					}
					$s=$header['size'];
					while($s>511) {
						$tw=($s>65535)?65536:(($s>8191)?8192:$s-$s%512);
						fwrite($fp,$this->_read($tw),$tw);
						$s-=$tw;
					}
					if ($s)
						fwrite($fp, $this->_read(512), $s);

					fclose($fp);
					# @touch($header['filename'], $header['mtime']);
					# @chmod($header['filename'], $p_mode);
					$nsuc++;
					$callback && $callback( ARCHLIB_DONE_SUCCESS, $header );
				}
				else /* not a file */
				{
					/* 5 is directory */
					if ($callback)
						$callback( ($header['typeflag']==5) ? ARCHLIB_DONE_SUCCESS : ARCHLIB_DONE_IGNORE, $header );
					$this->_forward($header);
				}
			}
			else {
				$this->_forward($header);
				$callback && $callback( ARCHLIB_OK_NOEXTRACT, $header );
			}
		}
		$this->_data['fail']=$nfail;
		$this->_data['success']=$nsuc;
		if ($callback)
			$callback( ARCHLIB_END, null );
	}

	function _forward(&$header){
			$this->_seek(ceil($header['size']/512)*512,1);
	}

	function _dirApp($d,$mode)
	{
		if( is_dir( $d ))
			return true;
		return $this->_mkdir($d,$mode);
	}
	function _mkdir( $dir, $mode )
	{
		if (version_compare(PHP_VERSION, '5.0.0', '<')) {
			return $this->_mkdir44( $dir, $mode );
		}
		else
			return @mkdir( $dir, $mode, true );
	}
	# this function is only run under PHP4
	function _mkdir44( $dir, $mode )
	{
	# we may run under open_base_dir=something directive
	# using is_dir in this circumstances is not trivial.
	# So let's use barbarian mode : create all the path
	# components one after the other, and in he end, check
	# if we were successful...
		if(is_dir($dir)||@mkdir($dir,$mode))
			return true;
		$comp=explode('/',str_replace('\\', '/', $dir));
		$path='';
		for( ; ($d=array_shift($comp)) !== null; $path.='/' ) {
			if('' === $path)
				continue;
			$path .= $d;
			@mkdir($path,$mode);
		}
		return is_dir($dir);
	}
};

/* ------------------------------------------------------------------------- */
/**
 * @author     bouchon
 * @link       http://dev.maxg.info
 * @link       http://forum.maxg.info
 *
 * Modified for Dokuwiki
 * @author    Christopher Smith <chris@jalakai.co.uk>
 * Modified and minimized for webadmin. removed all creation function.
 * @author    Schplurtz le Déboulonné <Schplurtz@laposte.net>
 */
class ZipLib {

	var $archname = null;
	var $mode = 0755;
	var $_data = null;
	var $_result = 0;


	function ZipLib( $filename ) {
		$this->archname=$filename;
	}

	function result() {
		return $this->_result;
	}

	function ErrorStr($c) {
		$ec= array(
			0 => "No error",
			-4 => "Can't open the archive file for read !", 
			-5 => "Malformed zip file", 
		);
		return array_key_exists( $c, $ec ) ? $ec[c] : "Unknown error";
	}

	function ListContents($limit=0x7fffffff) {
		$zip = @fopen($this->archname, 'rb');
		$data = array();
		if(!$zip) {
			$this->_result = -4;
			return false;
		}
		$centd = $this->_readCentralDir($zip);

		@rewind($zip);
		@fseek($zip, $centd['offset']);

		for ($i=0; $i<$centd['entries'] && $i < $limit; $i++) {
			$header = $this->_readCentralFileHeader($zip);
			$header['index'] = $i;

			$info['filename']        = $header['filename'];
			$info['stored_filename'] = $header['stored_filename'];
			$info['size']            = $header['size'];
			$info['compressed_size'] = $header['compressed_size'];
			$info['crc']             = strtoupper(dechex( $header['crc'] ));
			$info['mtime']           = $header['mtime'];
			$info['comment']         = $header['comment'];
			$info['folder']          = ($header['external']==0x41FF0010||$header['external']==16)?1:0;
			$info['index']           = $header['index'];
			$info['status']          = $header['status'];
			$this->_data[]=$info;

			unset($header);
		}
		$this->_result = 0;
		return true;
	}


	/**
	 * Extract a zip file to the $to directory
	 */
	function Extract ( $index=Array(-1), $to='.', $subst=null, $mode=0755, $callback=null ) {
		$this->$mode=$mode;
		$ok = 0;
		$nsuc=$nfail=0;
		$this->_data=array('fail'=>0,'success'=>0,'failed'=>array());

		$zip = @fopen($this->archname,'rb');
		if(!$zip) {
			$this->_result = -4;
			return -1;
		}
		$cdir = $this->_readCentralDir($zip);
		$pos_entry = $cdir['offset'];

		if(!is_array($index)){
			$index = array($index);
		}
		for($i=0; isset($index[$i]);$i++){
			if(intval($index[$i])!=$index[$i]||$index[$i]>$cdir['entries']) {
				$this->_result = -5;
				return -1;
			}
		}

		if(''==$to) $to='./';
		elseif(substr($to,-1)!='/') $to.='/';
		for ($i=0; $i<$cdir['entries']; $i++) {
			@fseek($zip, $pos_entry);
			$header = $this->_readCentralFileHeader($zip);
			$header['index'] = $i;
			$pos_entry = ftell($zip);
			@rewind($zip);
			fseek($zip, $header['offset']);
			if($callback)
				$extract=$callback(ARCHLIB_EXTRACT_P,$header);
			else
				$extract= in_array(-1,$index)||in_array($i,$index);
			if($extract) {
				if( -1 === $this->_extractFile($zip, $header, $to, $subst, $callback) ) {
					$this->_data['failed'][]=$header['filename'];
					$nfail++;
				}
				else {
					$nsuc++;
				}
			}
            elseif($callback)
                $callback(ARCHLIB_OK_NOEXTRACT, $header);
		}
		fclose($zip);
		$this->_data['fail']=$nfail;
		$this->_data['success']=$nsuc;
		if ($callback)
			$callback( ARCHLIB_END, null );
	}

	function _mkdir($dir) {
		return is_dir($dir) ? true : $this->_makedir($dir,$this->mode);
	}
	function _makedir( $dir, $mode )
	{
		if (version_compare(PHP_VERSION, '5.0.0', '<')) {
			return $this->_mkdir44( $dir, $mode );
		}
		else
			return @mkdir( $dir, $mode, true );
	}
	# this function is only run under PHP4
	function _mkdir44( $dir, $mode )
	{
	# we may run under open_base_dir=something directive
	# using is_dir in this circumstances is not trivial.
	# So let's use barbarian mode : create all the path
	# components one after the other, and in he end, check
	# if we were successful...
		if(is_dir($dir)||@mkdir($dir,$mode))
			return true;
		$comp=explode('/',str_replace('\\', '/', $dir));
		$path='';
		for( ; ($d=array_shift($comp)) !== null; $path.='/' ) {
			if('' === $path)
				continue;
			$path .= $d;
			@mkdir($path,$mode);
		}
		return is_dir($dir);
	}

	function _readFileHeader($zip, $header) {
		$binary_data = fread($zip, 30);
		$data = unpack('vchk/vid/vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $binary_data);

		$header['filename'] = fread($zip, $data['filename_len']);
		if ($data['extra_len'] != 0) {
			$header['extra'] = fread($zip, $data['extra_len']);
		} else {
			$header['extra'] = '';
		}

		$header['compression'] = $data['compression'];
		foreach (array('size','compressed_size','crc') as $hd) { // On ODT files, these headers are 0. Keep the previous value.
			if ($data[$hd] != 0) $header[$hd] = $data[$hd];
		}
		$header['flag']  = $data['flag'];
		$header['mdate'] = $data['mdate'];
		$header['mtime'] = $data['mtime'];

		if ($header['mdate'] && $header['mtime']){
			$hour    = ($header['mtime']&0xF800)>>11;
			$minute  = ($header['mtime']&0x07E0)>>5;
			$seconde = ($header['mtime']&0x001F)*2;
			$year    = (($header['mdate']&0xFE00)>>9)+1980;
			$month   = ($header['mdate']&0x01E0)>>5;
			$day     = $header['mdate']&0x001F;
			$header['mtime'] = mktime($hour, $minute, $seconde, $month, $day, $year);
		} else {
			$header['mtime'] = time();
		}

		$header['stored_filename'] = $header['filename'];
		$header['status'] = "ok";
		return $header;
	}

	function _readCentralFileHeader($zip){
		$binary_data = fread($zip, 46);
		$header = unpack('vchkid/vid/vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $binary_data);

		if ($header['filename_len'] != 0){
			$header['filename'] = fread($zip,$header['filename_len']);
		}else{
			$header['filename'] = '';
		}

		if ($header['extra_len'] != 0){
			$header['extra'] = fread($zip, $header['extra_len']);
		}else{
			$header['extra'] = '';
		}

		if ($header['comment_len'] != 0){
			$header['comment'] = fread($zip, $header['comment_len']);
		}else{
			$header['comment'] = '';
		}

		if ($header['mdate'] && $header['mtime']) {
			$hour    = ($header['mtime'] & 0xF800) >> 11;
			$minute  = ($header['mtime'] & 0x07E0) >> 5;
			$seconde = ($header['mtime'] & 0x001F)*2;
			$year    = (($header['mdate'] & 0xFE00) >> 9) + 1980;
			$month   = ($header['mdate'] & 0x01E0) >> 5;
			$day     = $header['mdate'] & 0x001F;
			$header['mtime'] = mktime($hour, $minute, $seconde, $month, $day, $year);
		} else {
			$header['mtime'] = time();
		}

		$header['stored_filename'] = $header['filename'];
		$header['status'] = 'ok';
		if (substr($header['filename'], -1) == '/') $header['external'] = 0x41FF0010;

		return $header;
	}

	function _readCentralDir($zip) {
		$size = filesize($this->archname);
		if ($size < 277){
			$maximum_size = $size;
		} else {
			$maximum_size=277;
		}

		@fseek($zip, $size-$maximum_size);
		$pos   = ftell($zip);
		$bytes = 0x00000000;

		while ($pos < $size) {
			$byte = @fread($zip, 1);
			$bytes=(($bytes << 8) & 0xFFFFFFFF) | Ord($byte);
			if ($bytes == 0x504b0506){
				$pos++;
				break;
			}
			$pos++;
		}

		$data=unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size',
				fread($zip, 18));

		if ($data['comment_size'] != 0){
			$centd['comment'] = fread($zip, $data['comment_size']);
		} else {
			$centd['comment'] = '';
		}
		$centd['entries']      = $data['entries'];
		$centd['disk_entries'] = $data['disk_entries'];
		$centd['offset']       = $data['offset'];
		$centd['disk_start']   = $data['disk_start'];
		$centd['size']         = $data['size'];
		$centd['disk']         = $data['disk'];
		return $centd;
	}

	function _extractFile($zip,$header,$to,$subst,$callback) {
 
		$header = $this->_readFileHeader($zip, $header);

		$fname=$header['filename'];
		if($subst)
			$fname=preg_replace($subst['from'],$subst['to'],$fname);
		$fname=trim($fname,'/');

		if(substr($header['filename'],-1)=='/') {
			$res=$this->_mkdir($to.$fname);
			$callback && $callback( $res ? ARCHLIB_DONE_SUCCESS : ARCHLIB_DONE_FAIL, $header );
			return $res?0:-1;
		}

		if (!$this->_mkdir($to.dirname($fname))) {
			$callback && $callback( ARCHLIB_DONE_FAIL, $header );
			return -1;
		}

		if (!array_key_exists("external", $header) || (!($header['external']==0x41FF0010)&&!($header['external']==16))) {

			if ($header['compression']==0) {
				$fp = @fopen($to.$fname, 'wb');
				if(!$fp) {
					$callback && $callback( ARCHLIB_DONE_FAIL, $header );
					return -1;
				}
				$size = $header['compressed_size'];

				while ($size) {
					$read_size=($size>65535)?65536:(($size>8191)?8192:$size);
					$buffer = fread($zip, $read_size);
					$binary_data = pack('a'.$read_size, $buffer);
					@fwrite($fp, $binary_data, $read_size);
					$size -= $read_size;
				}
				fclose($fp);
				touch($to.$fname, $header['mtime']);
			}else{
				$fp = fopen($to.$fname.'.gz','wb');
				if(!$fp) {
					$callback && $callback( ARCHLIB_DONE_FAIL, $header );
					return -1;
				}
				$binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($header['compression']),
						Chr(0x00), time(), Chr(0x00), Chr(3));

				fwrite($fp, $binary_data, 10);
				$size = $header['compressed_size'];

				while ($size) {
					$read_size=($size>65535)?65536:(($size>8191)?8192:$size);
					$buffer = fread($zip, $read_size);
					$binary_data = pack('a'.$read_size, $buffer);
					@fwrite($fp, $binary_data, $read_size);
					$size -= $read_size;
				}

				$binary_data = pack('VV', $header['crc'], $header['size']);
				fwrite($fp, $binary_data,8);
				fclose($fp);

				$gzp = @gzopen($to.$fname.'.gz','rb');
				if(!$gzp){
					$callback && $callback( ARCHLIB_DONE_FAIL, $header );
					@unlink($to.$fname);
					die("Archive is compressed whereas ZLIB is not enabled.");
				}
				$fp = @fopen($to.$fname,'wb');
				if(!$fp) {
					$callback && $callback( ARCHLIB_DONE_FAIL, $header );
					return -1;
				}
				$size = $header['size'];

				while ($size) {
					#$read_size   = ($size < 2048 ? $size : 2048);
					$read_size=($size>65535)?65536:(($size>8191)?8192:$size);
					$buffer      = gzread($gzp, $read_size);
					$binary_data = pack('a'.$read_size, $buffer);
					@fwrite($fp, $binary_data, $read_size);
					$size -= $read_size;
				}
				fclose($fp);
				gzclose($gzp);

				touch($to.$fname, $header['mtime']);
				@unlink($to.$fname.'.gz');
			}
			$callback && $callback( ARCHLIB_DONE_SUCCESS, $header );
		}
		return 0;
	}
}

/* vim: ts=4:sw=4:noexpandtab */
/*end of ZipLib by bouchon*/


/* ------------------------------------------------------------------------- */
if (get_magic_quotes_gpc()) {
	array_walk($_GET, 'strip');
	array_walk($_POST, 'strip');
	array_walk($_REQUEST, 'strip');
}

if (array_key_exists('image', $_GET)) {
	header('Content-Type: image/png');
	die(getimage($_GET['image']));
}

$delim = DIRECTORY_SEPARATOR;

if (function_exists('php_uname')) {
	$win = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? true : false;
} else {
	$win = ($delim == '\\') ? true : false;
}

if (!empty($_SERVER['PATH_TRANSLATED'])) {
	$scriptdir = dirname($_SERVER['PATH_TRANSLATED']);
} elseif (!empty($_SERVER['SCRIPT_FILENAME'])) {
	$scriptdir = dirname($_SERVER['SCRIPT_FILENAME']);
} elseif (function_exists('getcwd')) {
	$scriptdir = getcwd();
} else {
	$scriptdir = '.';
}
$homedir = relative2absolute($homedir, $scriptdir);

$dir = (array_key_exists('dir', $_REQUEST)) ? $_REQUEST['dir'] : $homedir;

if (array_key_exists('olddir', $_POST) && !path_is_relative($_POST['olddir'])) {
	$dir = relative2absolute($dir, $_POST['olddir']);
}

$directory = simplify_path(addslash($dir));
$haszlib=extension_loaded('zlib');
$hasbzip2=extension_loaded('bz2');
$tarext=array( 'tar' => 1 );
if( $haszlib ) {
	$tarext['tgz']=1;
	$tarext['tar.gz']=1;
}
if( $hasbzip2 ) $tarext['tar.bz2']=1;

$files = array();
$action = '';
if (!empty($_POST['submit_all'])) {
	$action = $_POST['action_all'];
	for ($i = 0; $i < $_POST['num']; $i++) {
		if (array_key_exists("checked$i", $_POST) && $_POST["checked$i"] == 'true') {
			$files[] = $_POST["file$i"];
		}
	}
} elseif (!empty($_REQUEST['action'])) {
	$action = $_REQUEST['action'];
	$files[] = relative2absolute($_REQUEST['file'], $directory);
} elseif (!empty($_POST['submit_upload']) && !empty($_FILES['upload']['name'])) {
	$files[] = $_FILES['upload'];
	$action = 'upload';
} elseif (!empty($_POST['cont_extract'])) {
	$files[] = $_POST['file'];
	$action='extract';
//echo '<big><big><big><big>OUI</big></big></big></big><br />';
} elseif (array_key_exists('num', $_POST)) {
	for ($i = 0; $i < $_POST['num']; $i++) {
		if (array_key_exists("submit$i", $_POST)) break;
	}
	if ($i < $_POST['num']) {
		$action = $_POST["action$i"];
		$files[] = $_POST["file$i"];
	}
}
if (empty($action) && (!empty($_POST['submit_create']) || (array_key_exists('focus', $_POST) && $_POST['focus'] == 'create')) && !empty($_POST['create_name'])) {
	$files[] = relative2absolute($_POST['create_name'], $directory);
	switch ($_POST['create_type']) {
	case 'directory':
		$action = 'create_directory';
	break;
	case 'file':
		$action = 'create_file';
	}
}
if (sizeof($files) == 0) $action = ''; else $file = reset($files);

if ($lang == 'auto') {
	if (array_key_exists('HTTP_ACCEPT_LANGUAGE', $_SERVER) && strlen($_SERVER['HTTP_ACCEPT_LANGUAGE']) >= 2) {
		$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
	} else {
		$lang = 'en';
	}
}

$words = getwords($lang);

if ($site_charset == 'auto') {
	$site_charset = $word_charset;
}

if (!empty($_SERVER['SCRIPT_NAME'])) {
	$self = html(basename($_SERVER['SCRIPT_NAME']));
} elseif (!empty($_SERVER['PHP_SELF'])) {
	$self = html(basename($_SERVER['PHP_SELF']));
} else {
	$self = '';
}

if (array_key_exists('info', $_GET)) {
	info();
	die(0);
}
if (array_key_exists('phpinfo', $_REQUEST)) {
	phpinfo();
	die(0);
}

$cols = ($win) ? 4 : 7;

if (!isset($dirpermission)) {
	$dirpermission = (@function_exists('umask')) ? (0777 & ~umask()) : 0755;
}
if (!isset($filepermission)) {
	$filepermission = (@function_exists('umask')) ? (0666 & ~umask()) : 0644;
}

if (!empty($_SERVER['SERVER_SOFTWARE'])) {
	if (strtolower(substr($_SERVER['SERVER_SOFTWARE'], 0, 6)) == 'apache') {
		$apache = true;
	} else {
		$apache = false;
	}
} else {
	$apache = true;
}

switch ($action) {

case 'view':

	if (is_script($file)) {

		/* highlight_file is a mess! */
		ob_start();
		highlight_file($file);
		$src = ereg_replace('<font color="([^"]*)">', '<span style="color: \1">', ob_get_contents());
		$src = str_replace(array('</font>', "\r", "\n"), array('</span>', '', ''), $src);
		ob_end_clean();

		html_header();
		echo '<h2 style="text-align: left; margin-bottom: 0">', html($file), '</h2>

<hr />

<table>
<tr>
<td style="text-align: right; vertical-align: top; color: gray; padding-right: 3pt; border-right: 1px solid gray">
<pre style="margin-top: 0"><code>';

		for ($i = 1; $i <= sizeof(file($file)); $i++) echo "$i\n";

		echo '</code></pre>
</td>
<td style="text-align: left; vertical-align: top; padding-left: 3pt">
<pre style="margin-top: 0">', $src, '</pre>
</td>
</tr>
</table>

';

		html_footer();

	} else {

		header('Content-Type: ' . getmimetype($file));
		header('Content-Disposition: filename=' . basename($file));

		readfile($file);

	}

break;

case 'download':

	header('Pragma: public');
	header('Expires: 0');
	header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
	header('Content-Type: ' . getmimetype($file));
	header('Content-Disposition: attachment; filename=' . basename($file) . ';');
	header('Content-Length: ' . filesize($file));

	readfile($file);

break;

case 'upload':

	$dest = relative2absolute($file['name'], $directory);

	if (@file_exists($dest)) {
		listing_page(error('already_exists', $dest));
	} elseif (@move_uploaded_file($file['tmp_name'], $dest)) {
		@chmod($dest, $filepermission);
		listing_page(notice('uploaded', $file['name']));
	} else {
		listing_page(error('not_uploaded', $file['name']));
	}

break;

case 'create_directory':

	if (@file_exists($file)) {
		listing_page(error('already_exists', $file));
	} else {
		$old = @umask(0777 & ~$dirpermission);
		if (makedir($file, $dirpermission)) {
			listing_page(notice('created', $file));
		} else {
			listing_page(error('not_created', $file));
		}
		@umask($old);
	}

break;

case 'create_file':

	if (@file_exists($file)) {
		listing_page(error('already_exists', $file));
	} else {
		$old = @umask(0777 & ~$filepermission);
		if (@touch($file)) {
			edit($file);
		} else {
			listing_page(error('not_created', $file));
		}
		@umask($old);
	}

break;

case 'execute':

	chdir(dirname($file));

	$output = array();
	$retval = 0;
	exec('echo "./' . basename($file) . '" | /bin/sh', $output, $retval);

	$error = ($retval == 0) ? false : true;

	if (sizeof($output) == 0) $output = array('<' . $words['no_output'] . '>');

	if ($error) {
		listing_page(error('not_executed', $file, implode("\n", $output)));
	} else {
		listing_page(notice('executed', $file, implode("\n", $output)));
	}

break;

case 'delete':

	if (!empty($_POST['no'])) {
		listing_page();
	} elseif (!empty($_POST['yes'])) {

		$failure = array();
		$success = array();

		foreach ($files as $file) {
			if (del($file)) {
				$success[] = $file;
			} else {
				$failure[] = $file;
			}
		}

		$message = '';
		if (sizeof($failure) > 0) {
			$message = error('not_deleted', implode("\n", $failure));
		}
		if (sizeof($success) > 0) {
			$message .= notice('deleted', implode("\n", $success));
		}

		listing_page($message);

	} else {

		html_header();

		echo '<form action="', $self, '" method="post">
<table class="dialog">
<tr>
<td class="dialog">
';

		request_dump();

		echo "\t<b>", word('really_delete'), '</b>
	<p>
';

		foreach ($files as $file) {
			echo "\t", html($file), "<br />\n";
		}

		echo '	</p>
	<hr />
	<input type="submit" name="no" value="', word('no'), '" id="red_button" />
	<input type="submit" name="yes" value="', word('yes'), '" id="green_button" style="margin-left: 50px" />
</td>
</tr>
</table>
</form>

';

		html_footer();

	}

break;

case 'rename':

	if (!empty($_POST['destination'])) {

		$dest = relative2absolute($_POST['destination'], $directory);

		if (!@file_exists($dest) && @rename($file, $dest)) {
			listing_page(notice('renamed', basename($file), basename($dest)));
		} else {
			listing_page(error('not_renamed', basename($file), basename($dest)));
		}

	} else {

		$name = basename($file);

		html_header();

		echo '<form action="', $self, '" method="post">

<table class="dialog">
<tr>
<td class="dialog">
	<input type="hidden" name="action" value="rename" />
	<input type="hidden" name="file" value="', html($file), '" />
	<input type="hidden" name="dir" value="', html($directory), '" />
	<b>', word('rename_file'), '</b>
	<p>', html($file), '</p>
	<b>', html(substr($file, 0, strlen($file) - strlen($name))), '</b>
	<input type="text" name="destination" size="', textfieldsize($name), '" value="', html($name), '" />
	<hr />
	<input type="submit" value="', word('rename'), '" />
</td>
</tr>
</table>

<p><a href="', $self, '?dir=', urlencode($directory), '">[ ', word('back'), ' ]</a></p>

</form>

';

		html_footer();

	}

break;

case 'move':

	if (!empty($_POST['destination'])) {

		$dest = relative2absolute($_POST['destination'], $directory);

		$failure = array();
		$success = array();

		foreach ($files as $file) {
			$filename = substr($file, strlen($directory));
			$d = $dest . $filename;
			if (!@file_exists($d) && @rename($file, $d)) {
				$success[] = $file;
			} else {
				$failure[] = $file;
			}
		}

		$message = '';
		if (sizeof($failure) > 0) {
			$message = error('not_moved', implode("\n", $failure), $dest);
		}
		if (sizeof($success) > 0) {
			$message .= notice('moved', implode("\n", $success), $dest);
		}

		listing_page($message);

	} else {

		html_header();

		echo '<form action="', $self, '" method="post">

<table class="dialog">
<tr>
<td class="dialog">
';

		request_dump();

		echo "\t<b>", word('move_files'), '</b>
	<p>
';

		foreach ($files as $file) {
			echo "\t", html($file), "<br />\n";
		}

		echo '	</p>
	<hr />
	', word('destination'), ':
	<input type="text" name="destination" size="', textfieldsize($directory), '" value="', html($directory), '" />
	<input type="submit" value="', word('move'), '" />
</td>
</tr>
</table>

<p><a href="', $self, '?dir=', urlencode($directory), '">[ ', word('back'), ' ]</a></p>

</form>

';

		html_footer();

	}

break;

case 'copy':

	if (!empty($_POST['destination'])) {

		$dest = relative2absolute($_POST['destination'], $directory);

		if (@is_dir($dest)) {

			$failure = array();
			$success = array();

			foreach ($files as $file) {
				$filename = substr($file, strlen($directory));
				$d = addslash($dest) . $filename;
				if (!@is_dir($file) && !@file_exists($d) && @copy($file, $d)) {
					$success[] = $file;
				} else {
					$failure[] = $file;
				}
			}

			$message = '';
			if (sizeof($failure) > 0) {
				$message = error('not_copied', implode("\n", $failure), $dest);
			}
			if (sizeof($success) > 0) {
				$message .= notice('copied', implode("\n", $success), $dest);
			}

			listing_page($message);

		} else {

			if (!@file_exists($dest) && @copy($file, $dest)) {
				listing_page(notice('copied', $file, $dest));
			} else {
				listing_page(error('not_copied', $file, $dest));
			}

		}

	} else {

		html_header();

		echo '<form action="', $self, '" method="post">

<table class="dialog">
<tr>
<td class="dialog">
';

		request_dump();

		echo "\n<b>", word('copy_files'), '</b>
	<p>
';

		foreach ($files as $file) {
			echo "\t", html($file), "<br />\n";
		}

		echo '	</p>
	<hr />
	', word('destination'), ':
	<input type="text" name="destination" size="', textfieldsize($directory), '" value="', html($directory), '" />
	<input type="submit" value="', word('copy'), '" />
</td>
</tr>
</table>

<p><a href="', $self, '?dir=', urlencode($directory), '">[ ', word('back'), ' ]</a></p>

</form>

';

		html_footer();

	}

break;

case 'create_symlink':

	if (!empty($_POST['destination'])) {

		$dest = relative2absolute($_POST['destination'], $directory);

		if (substr($dest, -1, 1) == $delim) $dest .= basename($file);

		if (!empty($_POST['relative'])) $file = absolute2relative(addslash(dirname($dest)), $file);

		if (!@file_exists($dest) && @symlink($file, $dest)) {
			listing_page(notice('symlinked', $file, $dest));
		} else {
			listing_page(error('not_symlinked', $file, $dest));
		}

	} else {

		html_header();

		echo '<form action="', $self, '" method="post">

<table class="dialog" id="symlink">
<tr>
	<td style="vertical-align: top">', word('destination'), ': </td>
	<td>
		<b>', html($file), '</b><br />
		<input type="checkbox" name="relative" value="yes" id="checkbox_relative" checked="checked" style="margin-top: 1ex" />
		<label for="checkbox_relative">', word('relative'), '</label>
		<input type="hidden" name="action" value="create_symlink" />
		<input type="hidden" name="file" value="', html($file), '" />
		<input type="hidden" name="dir" value="', html($directory), '" />
	</td>
</tr>
<tr>
	<td>', word('symlink'), ': </td>
	<td>
		<input type="text" name="destination" size="', textfieldsize($directory), '" value="', html($directory), '" />
		<input type="submit" value="', word('create_symlink'), '" />
	</td>
</tr>
</table>

<p><a href="', $self, '?dir=', urlencode($directory), '">[ ', word('back'), ' ]</a></p>

</form>

';

		html_footer();

	}

break;

case 'edit':

	$msg=null;
	if (!empty($_POST['save']) || !empty($_POST['saveandquit'])) {

		$content = str_replace("\r\n", "\n", $_POST['content']);
		if (($f = @fopen($file, 'w')) && @fwrite($f, $content) !== false && @fclose($f)) {
			$msg=notice('saved', $file);
		} else {
			$msg=error('not_saved', $file);
		}
	}
	if (!empty($_POST['saveandquit'])) {
		listing_page($msg);
	}
	else {
		if (@is_readable($file) && @is_writable($file)) {
			edit($file,$msg);
		} else {
			listing_page(error('not_edited', $file));
		}

	}

break;

case 'permission':

	if (!empty($_POST['set'])) {

		$mode = 0;
		if (!empty($_POST['ur'])) $mode |= 0400; if (!empty($_POST['uw'])) $mode |= 0200; if (!empty($_POST['ux'])) $mode |= 0100;
		if (!empty($_POST['gr'])) $mode |= 0040; if (!empty($_POST['gw'])) $mode |= 0020; if (!empty($_POST['gx'])) $mode |= 0010;
		if (!empty($_POST['or'])) $mode |= 0004; if (!empty($_POST['ow'])) $mode |= 0002; if (!empty($_POST['ox'])) $mode |= 0001;

		if (@chmod($file, $mode)) {
			listing_page(notice('permission_set', $file, decoct($mode)));
		} else {
			listing_page(error('permission_not_set', $file, decoct($mode)));
		}

	} else {

		html_header();

		$mode = fileperms($file);

		echo '<form action="', $self, '" method="post">

<table class="dialog">
<tr>
<td class="dialog">

	<p style="margin: 0">', phrase('permission_for', $file), '</p>

	<hr />

	<table id="permission">
	<tr>
		<td></td>
		<td style="border-right: 1px solid black">', word('owner'), '</td>
		<td style="border-right: 1px solid black">', word('group'), '</td>
		<td>', word('other'), '</td>
	</tr>
	<tr>
		<td style="text-align: right">', word('read'), ':</td>
		<td><input type="checkbox" name="ur" value="1"'; if ($mode & 00400) echo ' checked="checked"'; echo ' /></td>
		<td><input type="checkbox" name="gr" value="1"'; if ($mode & 00040) echo ' checked="checked"'; echo ' /></td>
		<td><input type="checkbox" name="or" value="1"'; if ($mode & 00004) echo ' checked="checked"'; echo ' /></td>
	</tr>
	<tr>
		<td style="text-align: right">', word('write'), ':</td>
		<td><input type="checkbox" name="uw" value="1"'; if ($mode & 00200) echo ' checked="checked"'; echo ' /></td>
		<td><input type="checkbox" name="gw" value="1"'; if ($mode & 00020) echo ' checked="checked"'; echo ' /></td>
		<td><input type="checkbox" name="ow" value="1"'; if ($mode & 00002) echo ' checked="checked"'; echo ' /></td>
	</tr>
	<tr>
		<td style="text-align: right">', word('execute'), ':</td>
		<td><input type="checkbox" name="ux" value="1"'; if ($mode & 00100) echo ' checked="checked"'; echo ' /></td>
		<td><input type="checkbox" name="gx" value="1"'; if ($mode & 00010) echo ' checked="checked"'; echo ' /></td>
		<td><input type="checkbox" name="ox" value="1"'; if ($mode & 00001) echo ' checked="checked"'; echo ' /></td>
	</tr>
	</table>

	<hr />

	<input type="submit" name="set" value="', word('set'), '" />

	<input type="hidden" name="action" value="permission" />
	<input type="hidden" name="file" value="', html($file), '" />
	<input type="hidden" name="dir" value="', html($directory), '" />

</td>
</tr>
</table>

<p><a href="', $self, '?dir=', urlencode($directory), '">[ ', word('back'), ' ]</a></p>

</form>

';

		html_footer();

	}


break;

case 'add_basic_auth':
	if (!empty($_POST['password'])) {
		// fpc( $directory.'/.htaccess'
		$pw= (array_key_exists('chkcrypt', $_POST) && $_POST['chkcrypt'] == 'yes') ?
			crypt( $_POST['password'] ) : $_POST['password'];
		fpc( $directory . '/' . $htpasswd, $_POST['user'].':'.$pw );
		fpc( $directory . '/' . $htaccess, basic_auth() );
		listing_page();
	} else {

		html_header();

		echo '
<form action="', $self, '" method="post">

<table class="dialog">
<tr>
<td class="dialog">
	<input type="hidden" name="action" value="add_basic_auth" />
	<input type="hidden" name="file" value="" />
	<input type="hidden" name="dir" value="', html($directory), '" />';
	if(function_exists('crypt')) echo
	word('usecrypt'),	'<input name="chkcrypt" type="checkbox" value="yes" />';
	echo
	word('user'),		'<input name="user"     type="text" />',
	word('password'),	'<input name="password" type="password" />',
	'<hr /><input type="submit" value="',word('add'), '" />
</td>
</tr>
</table>

<p><a href="', $self, '?dir=', urlencode($directory), '">[ ', word('back'), ' ]</a></p>

</form>

';
		html_footer();
	}
break;
case 'create_tar':

	$name=basename( $files[0] );
	if ( '.' == $name ) {
		$name=basename( $directory );
	}
	$name=dirname( $files[0] ).$delim.$name.'.tar';
	$arch = new tar($name);

	$arch->Add( $files, $directory );
	$arch->Create();
	listing_page();
break;

case 'send_tar':

	$arch = new tar;
	//$arch->setCompression(COMPRESS_NONE);
	$arch->add( $files, $directory );
	$name=basename( $files[0] );
	if ( '.' == $name ) {
		$name=basename( $directory );
	}
	$arch->SendToClient( "$name.".$arch->getCompression(1) );
	exit( 0 );
break;

case 'extract':
	complex_extract($files[0]);
	html_footer();
	exit();
break;
case 'rec_list_details':
	header('Content-Type: text/plain; charset=UTF-8');
	$listing='';
	foreach( $files as $file )
		$listing.=rec_list( $file, true );
	die($listing);
	break;
case 'rec_list':
	header('Content-Type: text/plain; charset=UTF-8');
	$listing='';
	foreach( $files as $file )
		$listing.=rec_list( $file, false );
	die($listing);
	break;

case 'gunzip':
	foreach( $files as $file )
		gunzip( $file );
	listing_page();
	break;

default:

	listing_page();

}

/* ------------------------------------------------------------------------- */

function myrmdir( $d ) {
	global $freefrdirtrash, $runningatfree;
	if(!$runningatfree){
		return @rmdir($d);
	}
	if(!is_dir($d))
		return false;
	$h=opendir($d);
	while(false!==($s=readdir($h))) {
		if( $s != '.' && $s != '..' ) {
			closedir($h);
			return false;
		}
	}
	closedir($h);
	return rename($d, $freefrdirtrash);
}
/* ------------------------------------------------------------------------- */

function getlist ($directory) {
	global $delim, $win;

	if ($d = @opendir($directory)) {

		while (($filename = @readdir($d)) !== false) {

			$path = $directory . $filename;

			if ($stat = @lstat($path)) {

				$file = array(
					'filename'    => $filename,
					'path'        => $path,
					'is_file'     => @is_file($path),
					'is_dir'      => @is_dir($path),
					'is_link'     => @is_link($path),
					'is_readable' => @is_readable($path),
					'is_writable' => @is_writable($path),
					'size'        => $stat['size'],
					'permission'  => $stat['mode'],
					'owner'       => $stat['uid'],
					'group'       => $stat['gid'],
					'mtime'       => @filemtime($path),
					'atime'       => @fileatime($path),
					'ctime'       => @filectime($path)
				);

				if ($file['is_dir']) {
					$file['is_executable'] = @file_exists($path . $delim . '.');
				} else {
					if (!$win) {
						$file['is_executable'] = @is_executable($path);
					} else {
						$file['is_executable'] = true;
					}
				}

				if ($file['is_link']) $file['target'] = @readlink($path);

				if (function_exists('posix_getpwuid')) $file['owner_name'] = @reset(posix_getpwuid($file['owner']));
				if (function_exists('posix_getgrgid')) $file['group_name'] = @reset(posix_getgrgid($file['group']));

				$files[] = $file;

			}

		}

		return $files;

	} else {
		return false;
	}

}

function sortlist ($list, $key, $reverse) {

	$dirs = array();
	$files = array();
	
	for ($i = 0; $i < sizeof($list); $i++) {
		if ($list[$i]['is_dir']) $dirs[] = $list[$i];
		else $files[] = $list[$i];
	}

	quicksort($dirs, 0, sizeof($dirs) - 1, $key);
	if ($reverse) $dirs = array_reverse($dirs);

	quicksort($files, 0, sizeof($files) - 1, $key);
	if ($reverse) $files = array_reverse($files);

	return array_merge($dirs, $files);

}

function quicksort (&$array, $first, $last, $key) {

	if ($first < $last) {

		$cmp = $array[floor(($first + $last) / 2)][$key];

		$l = $first;
		$r = $last;

		while ($l <= $r) {

			while ($array[$l][$key] < $cmp) $l++;
			while ($array[$r][$key] > $cmp) $r--;

			if ($l <= $r) {

				$tmp = $array[$l];
				$array[$l] = $array[$r];
				$array[$r] = $tmp;

				$l++;
				$r--;

			}

		}

		quicksort($array, $first, $r, $key);
		quicksort($array, $l, $last, $key);

	}

}

function permission_octal2string( $mode ) {
	// from http://php.net/manual/fr/function.stat.php
	// thank you webmaster at askapache dot com
	$ts=array(
	  0140000=>'s',
	  0120000=>'l',
	  0100000=>'-',
	  0060000=>'b',
	  0040000=>'d',
	  0020000=>'c',
	  0010000=>'p'
	);

	$p=$mode;
	$t=decoct($p & 0170000); // File Encoding Bit

	$str =(array_key_exists(octdec($t),$ts))?$ts[octdec($t)]:'u';
	$str.=(($p&0x0100)?'r':'-').(($p&0x0080)?'w':'-');
	$str.=(($p&0x0040)?(($p&0x0800)?'s':'x'):(($p&0x0800)?'S':'-'));
	$str.=(($p&0x0020)?'r':'-').(($p&0x0010)?'w':'-');
	$str.=(($p&0x0008)?(($p&0x0400)?'s':'x'):(($p&0x0400)?'S':'-'));
	$str.=(($p&0x0004)?'r':'-').(($p&0x0002)?'w':'-');
	$str.=(($p&0x0001)?(($p&0x0200)?'t':'x'):(($p&0x0200)?'T':'-'));

	return $str;
}

function is_script ($filename) {
	return ereg('\.php$|\.php3$|\.php4$|\.php5$', $filename);
}

function getmimetype ($filename) {
	static $mimes = array(
		'\.jpg$|\.jpeg$'  => 'image/jpeg',
		'\.gif$'          => 'image/gif',
		'\.png$'          => 'image/png',
		'\.html$|\.html$' => 'text/html',
		'\.txt$|\.asc$'   => 'text/plain',
		'\.xml$|\.xsl$'   => 'application/xml',
		'\.pdf$'          => 'application/pdf'
	);

	foreach ($mimes as $regex => $mime) {
		if (eregi($regex, $filename)) return $mime;
	}

	// return 'application/octet-stream';
	return 'text/plain';

}

function del ($file) {
	global $delim;
	if (!file_exists($file)) return false;

	if (@is_dir($file) && !@is_link($file)) {

		$success = false;

		if (@myrmdir($file)) {

			$success = true;

		} elseif ($dir = @opendir($file)) {

			$success = true;

			while (($f = readdir($dir)) !== false) {
				if ($f != '.' && $f != '..' && !del($file . $delim . $f)) {
					$success = false;
				}
			}
			closedir($dir);

			if ($success) $success = @myrmdir($file);

		}

		return $success;

	}

	return @unlink($file);

}

function infoline( $file, $show_details ) {
	if( $show_details ) {
		if ($stat = @lstat($file)) {
			$r=sprintf( "%s %10d %3d %9d %9d %s %9d %s\n",
				permission_octal2string( $stat['mode'] ),
				$stat['ino'],
				$stat['nlink'],
				$stat['uid'],
				$stat['gid'],
				strftime( '%Y-%m-%d %H:%M:%S', $stat['mtime'] ),
				$stat['size'],
				$file
			);
			return $r;
		}
	}
	// stat fallback, or no details asked
	return $file."\n";
}
function rec_list ($file, $show_details) {
	global $delim;

	if (!file_exists($file)) return '';

	if (@is_dir($file) && !@is_link($file)) {
		$success = infoline($file, $show_details);
		if ($dir = @opendir($file)) {
			while (($f = readdir($dir)) !== false) {
				if ($f != '.' && $f != '..')
					$success.=rec_list($file.$delim.$f, $show_details);
			}
			closedir($dir);
		}
		return $success;

	}
	return infoline($file,$show_details);
}

function addslash ($directory) {
	global $delim;

	if (substr($directory, -1, 1) != $delim) {
		return $directory . $delim;
	} else {
		return $directory;
	}

}

function relative2absolute ($string, $directory) {

	if (path_is_relative($string)) {
		return simplify_path(addslash($directory) . $string);
	} else {
		return simplify_path($string);
	}

}

function path_is_relative ($path) {
	global $win;

	if ($win) {
		return (substr($path, 1, 1) != ':');
	} else {
		return (substr($path, 0, 1) != '/');
	}

}

function absolute2relative ($directory, $target) {
	global $delim;

	$path = '';
	while ($directory != $target) {
		if ($directory == substr($target, 0, strlen($directory))) {
			$path .= substr($target, strlen($directory));
			break;
		} else {
			$path .= '..' . $delim;
			$directory = substr($directory, 0, strrpos(substr($directory, 0, -1), $delim) + 1);
		}
	}
	if ($path == '') $path = '.';

	return $path;

}

function simplify_path ($path) {
	global $delim;

	if (@file_exists($path) && function_exists('realpath') && @realpath($path) != '') {
		$path = realpath($path);
		if (@is_dir($path)) {
			return addslash($path);
		} else {
			return $path;
		}
	}

	$pattern  = $delim . '.' . $delim;

	if (@is_dir($path)) {
		$path = addslash($path);
	}

	while (strpos($path, $pattern) !== false) {
		$path = str_replace($pattern, $delim, $path);
	}

	$e = addslashes($delim);
	$regex = $e . '((\.[^\.' . $e . '][^' . $e . ']*)|(\.\.[^' . $e . ']+)|([^\.][^' . $e . ']*))' . $e . '\.\.' . $e;

	while (ereg($regex, $path)) {
		$path = ereg_replace($regex, $delim, $path);
	}
	
	return $path;

}

function human_filesize ($filesize) {

	$suffices = 'kMGTPE';

	$n = 0;
	while ($filesize >= 1000) {
		$filesize /= 1024;
		$n++;
	}

	$filesize = round($filesize, 3 - strpos($filesize, '.'));

	if (strpos($filesize, '.') !== false) {
		while (in_array(substr($filesize, -1, 1), array('0', '.'))) {
			$filesize = substr($filesize, 0, strlen($filesize) - 1);
		}
	}

	$suffix = (($n == 0) ? '' : substr($suffices, $n - 1, 1));

	return $filesize . " {$suffix}B";

}

function strip (&$str) {
	$str = stripslashes($str);
}

/* ------------------------------------------------------------------------- */

function top_table ($message = null) {
	global $self, $directory, $sort, $reverse, $writedir, $canexec, $win, $top_done;

	if($top_done) return;
	$top_done=true;
	html_header();
	echo '<h1 style="margin-bottom: 0"><a href="', $self, '?dir=', urlencode($directory), '&info=1">mwebadmin.php</a></h1>
					

<form enctype="multipart/form-data" id="mainform" action="', $self, '" method="post">

<table id="main">
';

	directory_choice();
}
function listing_page ($message = null) {
	global $self, $directory, $sort, $reverse, $writedir, $canexec, $win;

	$canexec=(!$win && function_exists('exec') && @file_exists('/bin/sh'));
	$list = getlist($directory);
	if (array_key_exists('sort', $_GET)) $sort = $_GET['sort']; else $sort = 'filename';
	if (array_key_exists('reverse', $_GET) && $_GET['reverse'] == 'true') $reverse = true; else $reverse = false;

	top_table();
	if (!empty($message)) {
		spacer();
		echo $message;
	}

	$writedir=0;
	if (@is_writable($directory)) {
		upload_box();
		create_box();
		$writedir=1;
	} else {
		spacer();
	}

	if ($list) {
		$list = sortlist($list, $sort, $reverse);
		listing($list);
	} else {
		echo error('not_readable', $directory);
	}

	echo '</table>
</form>
';

	html_footer();

}

function listing ($list) {
	global $directory, $homedir, $sort, $reverse, $win, $cols, $date_format, $self,
	       $file_default_action, $dir_default_action, $writedir, $tarext,
	       $canexec, $apache, $htaccess, $htpasswd;

	echo '<tr class="listing">';
	echo '	<th class="functions">', word('functions'), '</th>
	<th style="text-align: center; vertical-align: middle"><div style="min-width: 17px; background: url(\'?image=sprite\') no-repeat scroll -10px -9px transparent;">&nbsp;</div></th>
';

	column_title('filename', $sort, $reverse);
	column_title('size', $sort, $reverse);

	if (!$win) {
		column_title('permission', $sort, $reverse);
		column_title('owner', $sort, $reverse);
		column_title('group', $sort, $reverse);
	}

	echo '
</tr>
';

	for ($i = 0; $i < sizeof($list); $i++) {
		$file = $list[$i];

		$timestamps  = 'mtime: ' . date($date_format, $file['mtime']) . ', ';
		$timestamps .= 'atime: ' . date($date_format, $file['atime']) . ', ';
		$timestamps .= 'ctime: ' . date($date_format, $file['ctime']);

		echo '<tr class="listing">';
		/* ************** functions **************** */
		echo '	<td class="functions">
		<input type="hidden" name="file', $i, '" value="', html($file['path']), '" />
';

		/*
		 * I suspect array_key_exist to be faster than array_search even for
		 * small arrays. So we also create an has_action array, indexed by action
		 */
		$actions = array();
		$has_action = array();
		if (function_exists('symlink')) {
			$actions[] = 'create_symlink';
			$has_action['create_symlink'] = 1;
		}
//		if (@is_writable(dirname($file['path'])))
		if ($writedir && !('..' == $file['filename'] || '.' == $file['filename'])) {
			$actions[] = 'delete';
			$actions[] = 'rename';
			$actions[] = 'move';
			//if( is_file( $file['path'] ) && basename($file['path'], ".gz").'.gz' == basename($file['path']))
			if( is_file( $file['path'] ) && ((strtolower(substr($file['path'], -3)) == '.gz')||(strtolower(substr($file['path'], -4)) == '.tgz')) ){
				$actions[] = 'gunzip';
				$has_action['gunzip'] = 1;
			}
			$has_action['delete'] = 1;
			$has_action['rename'] = 1;
			$has_action['move'] = 1;
		}
		if ($file['is_dir'] && '..' != $file['filename'] && $file['is_readable']) {
			$actions[] = 'rec_list';
			$has_action['rec_list']=1;
			$actions[] = 'rec_list_details';
			$has_action['rec_list_details']=1;
			$actions[] = 'create_tar';
			$has_action['create_tar']=1;
			if ('.' == $file['filename'] && $apache && $writedir && !file_exists($directory.'/'.$htaccess) && !file_exists($directory.'/'.$htpasswd))  {
				$actions[] = 'add_basic_auth';
				$has_action['add_basic_auth']=1;
			}
		}
		if ($file['is_readable'] && '..' != $file['filename']) {
			$actions[] = 'send_tar';
			$has_action['send_tar'] = 1;
		}
		if ($file['is_file'] && $file['is_readable']) {
			$actions[] = 'copy';
			$actions[] = 'download';
			$has_action['copy'] = 1;
			$has_action['download'] = 1;
			if ($file['is_writable']) {
				$actions[] = 'edit';
				$has_action['edit'] = 1;
			}
			if( $writedir ) {
				$exts=explode( '.',basename($file['path']));
				if(($n=count($exts))>1) {
					$n--;
					$ext2='';
					$ext1=strtolower($exts[$n--]);
					if($n)
						$ext2=strtolower($exts[$n]).".$ext1";
					if( array_key_exists( $ext1, $tarext ) || array_key_exists( $ext2, $tarext ) ) {
						$actions[] = 'extract';
						$has_action['extract']=1;
					}
					if( 'zip' === $ext1 ) {
						$actions[] = 'extract';
						$has_action['extract']=1;
					}
				}
			}
		}
		if ($file['is_file'] && $file['is_executable'] && $canexec) {
			$actions[] = 'execute';
			$has_action['execute'] = 1;
		}

		if (sizeof($actions) > 0) {
			$putnop=0;
			echo '		<select class="small" name="action', $i, '" size="1">
';
			if ($file['is_file'] && array_key_exists( 'extract', $has_action )) {
				echo "\t\t<option value=\"extract\">", word('extract'), "</option>\n";
			}
			elseif ($file['is_file'] && array_key_exists( 'gunzip', $has_action )) {
				echo "\t\t<option value=\"gunzip\">", word('gunzip'), "</option>\n";
			}
			elseif ('' != $file_default_action && $file['is_file'] && array_search( $file_default_action, $actions ) != FALSE ) {
				echo "\t\t<option value=\"$file_default_action\">", word($file_default_action), "</option>\n";
			}
			elseif ( '' != $dir_default_action && $file['is_dir'] &&  array_key_exists( $dir_default_action, $has_action ) != FALSE ) {
				echo "\t\t<option value=\"$dir_default_action\">", word($dir_default_action), "</option>\n";
			}
			else {
				echo '		<option value="">', str_repeat('&nbsp;', 55), '</option>
';
				$putnop=1;
			}
			foreach ($actions as $action) {
				echo "\t\t<option value=\"$action\">", word($action), "</option>\n";
			}
			if ( !$putnop )
				echo '		<option value="">', str_repeat('&nbsp;', 55), '</option>
'; 
			echo '		</select>
		<input class="small" type="submit" name="submit', $i, '" value=" &gt; " onfocus="activate(\'other\')" />
';

		}
		/* ************** functions **************** */
	echo '
	<td class="checkbox"><input type="checkbox" name="checked', $i, '" value="true" onfocus="activate(\'other\')" /></td>
	<td class="filename" title="', html($timestamps), '">';

		if ($file['is_link']) {

			echo '<span class="link">';
			echo html($file['filename']), ' &rarr; ';

			$real_file = relative2absolute($file['target'], $directory);

			if (@is_readable($real_file)) {
				if (@is_dir($real_file)) {
					echo '[ <a href="', $self, '?dir=', urlencode($real_file), '">', html($file['target']), '</a> ]';
				} else {
					echo '<a href="', $self, '?action=view&amp;file=', urlencode($real_file), '">', html($file['target']), '</a>';
				}
			} else {
				echo html($file['target']);
			}

		} elseif ($file['is_dir']) {

			echo '<span class="folder">';
			echo '[ ';
			if ($win || $file['is_executable']) {
				echo '<a href="', $self, '?dir=', urlencode($file['path']), '">', html($file['filename']), '</a>';
			} else {
				echo html($file['filename']);
			}
			echo ' ]';

		} else {

			$hidcls='';
			if (substr($file['filename'], 0, 1) == '.') {
				$hidcls='hidden_';
			}

			echo '<span class="',$hidcls,'file">';
			if ($file['is_file'] && $file['is_readable']) {
			   echo '<a href="', $self, '?action=view&amp;file=', urlencode($file['path']), '">', html($file['filename']), '</a>';
			} else {
				echo html($file['filename']);
			}
		}
		echo '</span>';

		if ($file['size'] >= 1000) {
			$human = ' title="' . human_filesize($file['size']) . '"';
		} else {
			$human = '';
		}

		echo "</td>\n";

		echo "\t<td class=\"size\"$human>{$file['size']} B</td>\n";

		if (!$win) {

			echo "\t<td class=\"permission\" title=\"", decoct($file['permission']), '">';

			$l = !$file['is_link'] && (!function_exists('posix_getuid') || $file['owner'] == posix_getuid());
			if ($l) echo '<a href="', $self, '?action=permission&amp;file=', urlencode($file['path']), '&amp;dir=', urlencode($directory), '">';
			echo html(permission_octal2string($file['permission']));
			if ($l) echo '</a>';

			echo "</td>\n";

			if (array_key_exists('owner_name', $file)) {
				echo "\t<td class=\"owner\" title=\"uid: {$file['owner']}\">{$file['owner_name']}</td>\n";
			} else {
				echo "\t<td class=\"owner\">{$file['owner']}</td>\n";
			}

			if (array_key_exists('group_name', $file)) {
				echo "\t<td class=\"group\" title=\"gid: {$file['group']}\">{$file['group_name']}</td>\n";
			} else {
				echo "\t<td class=\"group\">{$file['group']}</td>\n";
			}

		}


		echo '	</td>
</tr>
';

	}

	echo '<tr class="listing_footer">
	<td>&nbsp;</td>
	<td style="text-align: right; vertical-align: top"><div style="min-width: 17px; background: url(\'?image=sprite\') no-repeat scroll -10px -42px transparent;">&nbsp;</div></td>
	<td colspan="', ($cols - 2), '">
		<input type="hidden" name="num" value="', sizeof($list), '" />
		<input type="hidden" name="focus" value="" />
		<input type="hidden" name="olddir" value="', html($directory), '" />
';

	$actions = array();
	if (@is_writable(dirname($file['path']))) {
		$actions[] = 'delete';
		$actions[] = 'move';
	}
	$actions[] = 'copy';
	$actions[] = 'send_tar';

	echo '		<select class="small" name="action_all" size="1">
		<option value="">', str_repeat('&nbsp;', 40), '</option>
';

	foreach ($actions as $action) {
		echo "\t\t<option value=\"$action\">", word($action), "</option>\n";
	}

	echo '		</select>
		<input class="small" type="submit" name="submit_all" value=" &gt; " onfocus="activate(\'other\')" />
	</td>
</tr>
';

}

function column_title ($column, $sort, $reverse) {
	global $self, $directory;

	$d = 'dir=' . urlencode($directory) . '&amp;';

	$arr='';
	if ($sort == $column) {
		if (!$reverse) {
			$r = '&amp;reverse=true';
			$arr = ' &and;';
		} else {
			$arr = ' &or;';
		}
	} else {
		$r = '';
	}
	echo "\t<th class=\"$column\"><a href=\"$self?{$d}sort=$column$r\">", word($column), "</a>$arr</th>\n";

}

function directory_choice () {
	global $directory, $homedir, $cols, $self;

	echo '<tr>
	<td colspan="', $cols, '" id="directory">
		<a href="', $self, '?dir=', urlencode($homedir), '">', word('directory'), '</a>:
		<input type="text" name="dir" size="', textfieldsize($directory), '" value="', html($directory), '" onfocus="activate(\'directory\')" />
		<input type="submit" name="changedir" value="', word('change'), '" onfocus="activate(\'directory\')" />
	</td>
</tr>
';

}

function upload_box () {
	global $cols;

	$max=ini_get('upload_max_filesize'); /*.ini_get('post_max_size')." />*/
	$der=substr($max, -1);
	if($der == 'k' || $der == 'K') {
		$max=1024 * (int)substr($max, 0, -1);
	}
	elseif($der == 'm' || $der == 'M') {
		$max=1048576 * (int)substr($max, 0, -1);
	}
	elseif($des == 'g' || $der == 'G') {
		$max=1073741824 * (int)substr($max, 0, -1);
	}
	$toobig=sprintf(word('file_too_big'), $max);

	echo '<tr>
	<td colspan="', $cols, '" id="upload">
		', word('file'), ':
		<input type="file" id="i_file" name="upload" onfocus="activate(\'other\')" />
		<input type="submit" name="submit_upload" value="', word('upload'), '" onfocus="activate(\'other\')" />
		<input type="reset" value="Vider" name="reset">
	</td>
</tr>
';

echo <<<END
<script
  src="https://code.jquery.com/jquery-2.2.4.min.js"
  integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
  crossorigin="anonymous">
</script>
<script><!--
jQuery(function() { //document ready
  jQuery('#mainform').on('submit', function () {
    if (window.File && window.FileReader && window.FileList && window.Blob)
    {
      if( !(jQuery('#i_file').val()) )
        return true; // nothing to do if no file to upload
      //get the file size and file type from file input field
      var fsize = jQuery('#i_file')[0].files[0].size;

      if(fsize>$max) //do something if file size greater than PHP can handle
      {
        alert("$toobig" + fsize);
        return false;
      }
    }
    // No File API support or file size is ok :
    return true;
  });
});
//-->
</script>
END;
}

function create_box () {
	global $cols;

	echo '<tr>
	<td colspan="', $cols, '" id="create">
		<select name="create_type" size="1" onfocus="activate(\'create\')">
		<option value="file">', word('file'), '</option>
		<option value="directory">', word('directory'), '</option>
		</select>
		<input type="text" name="create_name" onfocus="activate(\'create\')" />
		<input type="submit" name="submit_create" value="', word('create'), '" onfocus="activate(\'create\')" />
	</td>
</tr>
';

}

function edit ($file, $message=null) {
	global $self, $directory, $editcols, $editrows, $apache, $htpasswd, $htaccess, $runningatfree;

	$syntax='//'; // a JS comment. 
	$more='';
	$maymore=true;
	$toolbar_hl='"search, go_to_line, fullscreen, |, undo, redo, |, select_font,|, change_smooth_selection, highlight, reset_highlight, word_wrap, |, syntax_selection, |, help"';
	$toolbar_nohl='"search, go_to_line, fullscreen, |, undo, redo, |, select_font,|, change_smooth_selection, word_wrap, |, help"';
	$start_hl='false';
	$toolbar=$toolbar_nohl;

	if( is_dir( dirname($_SERVER['SCRIPT_FILENAME']).'/edit_area' )){
		switch( strtolower(pathinfo( $file, PATHINFO_EXTENSION ))) {
		case 'html':
			$syntax=',syntax: "HTML"';
			$toolbar=$toolbar_hl; $start_hl='true';
		break;
		case 'css':
			$syntax=',syntax: "CSS"';
			$toolbar=$toolbar_hl; $start_hl='true';
		break;
		case 'php':
			$syntax=',syntax: "Php"';
			$toolbar=$toolbar_hl; $start_hl='true';
		break;
		case 'pl':
			$syntax=',syntax: "Perl"';
			$toolbar=$toolbar_hl; $start_hl='true';
		break;
		case 'js':
			$syntax=',syntax: "js"';
			$toolbar=$toolbar_hl; $start_hl='true';
		break;
		case 'sql':
			$syntax=',syntax: "SQL"';
			$toolbar=$toolbar_hl; $start_hl='true';
		break;
		case 'py':
			$syntax=',syntax: "Python"';
			$toolbar=$toolbar_hl; $start_hl='true';
		break;
		}
		if( $maymore) $more='
	<script src="edit_area/edit_area_full.js"></script>
	<script>
	editAreaLoader.init({
		id : "textarea_1"
		'.$syntax.'
		,language: "fr"
		,toolbar: '.$toolbar.'
		,start_highlight: '.$start_hl.'
	});
	</script>

	';
	}
	html_header( $more );

	if(!is_null($message)){
		echo '<table class="dialog">',$message;
		spacer();
		echo '</table>';
	}
	echo '<h2 style="margin-bottom: 3pt">', html($file), '</h2>

<form action="', $self, '" method="post">

<table class="dialog">
<tr>
<td class="dialog">

	<textarea id="textarea_1" name="content" cols="', $editcols, '" rows="', $editrows, '" WRAP="off">';

	if (array_key_exists('content', $_POST)) {
		echo html(str_replace("\r\n", "\n", $_POST['content']));
	} else {
		$f = fopen($file, 'r');
		while (!feof($f)) {
			echo html(fread($f, 8192));
		}
		fclose($f);
	}

	if (!empty($_POST['user'])) {
		$pw= (array_key_exists('chkcrypt', $_POST) && $_POST['chkcrypt'] == 'yes') ?
			crypt( $_POST['password'] ) : $_POST['password'];
		echo "\n", $_POST['user'], ':', html( $pw );
	}
	if (!empty($_POST['basic_auth']))
		echo html(basic_auth());

	echo '</textarea>

	<hr />
';

	if ($apache && basename($file) == $htpasswd) {
		echo '
	', word('user'), ': <input type="text" name="user" />
	', word('password'), ': <input type="password" name="password" />
	<input type="submit" value="', word('add'), '" />';
		if(function_exists('crypt')) echo '
	<br />', word('usecrypt'), '<input name="chkcrypt" type="checkbox" value="yes" />

	<hr />
';

	}

	if ($apache && basename($file) == $htaccess) {
		echo '
	<input type="submit" name="basic_auth" value="', word('add_basic_auth'), '" />

	<hr />
';

	}

	echo '
	<input type="hidden" name="action" value="edit" />
	<input type="hidden" name="file" value="', html($file), '" />
	<input type="hidden" name="dir" value="', html($directory), '" />
	<input type="reset" value="', word('reset'), '" id="red_button" />
	<input type="submit" name="save" value="', word('save'), '" id="green_button" style="margin-left: 50px" />
	<input type="submit" name="saveandquit" value="', word('saveandquit'), '" id="green_button2" style="margin-left: 50px" />

</td>
</tr>
</table>

<p><a href="', $self, '?dir=', urlencode($directory), '">[ ', word('back'), ' ]</a></p>

</form>

';

	html_footer();

}

function basic_auth() {
	global $win, $runningatfree, $directory, $htpasswd;
	if ($win) {
		$authfile = str_replace('\\', '/', $directory) . $htpasswd;
	} else {
		$authfile = $directory . $htpasswd;
	}
	if($runningatfree){
		$authfile=str_replace( $_SERVER['DOCUMENT_ROOT'].'/', "", $authfile );
		$ret='PerlSetVar AuthFile '. $authfile;
	}else{
		$ret='AuthUserFile "' . $authfile . '"';
	}
	$ret .= "\n\nAuthType Basic\nAuthName \"Restricted Directory\"\nRequire valid-user\n";
	return $ret;
}
function spacer () {
	global $cols;

	echo '<tr>
	<td colspan="', $cols, '" style="height: 1em"></td>
</tr>
';

}

function textfieldsize ($content) {

	$size = strlen($content) + 5;
	if ($size < 30) $size = 30;

	return $size;

}

function request_dump () {
	foreach ($_REQUEST as $key => $value) {
		echo "\t<input type=\"hidden\" name=\"", html($key), '" value="', html($value), "\" />\n";
	}
}

/* ------------------------------------------------------------------------- */

function html ($string) {
	global $site_charset;
	return htmlentities($string, ENT_COMPAT, $site_charset);
}

function word ($word) {
	global $words, $word_charset;
	return htmlentities($words[$word], ENT_COMPAT, $word_charset);
}

function phrase ($phrase, $arguments) {
	global $words;
	static $search;

	if (!is_array($search)) for ($i = 1; $i <= 8; $i++) $search[] = "%$i";

	for ($i = 0; $i < sizeof($arguments); $i++) {
		$arguments[$i] = nl2br(html($arguments[$i]));
	}

	$replace = array('{' => '<pre>', '}' =>'</pre>', '[' => '<b>', ']' => '</b>');

	return str_replace($search, $arguments, str_replace(array_keys($replace), $replace, nl2br(html($words[$phrase]))));

}

function getwords ($lang) {
	global $word_charset, $date_format;

	switch ($lang) {
	case 'de':

		$date_format = 'd.m.y H:i:s';
		$word_charset = 'UTF-8';

		return array(
'send_tar' => 'Get tar archive',
'extract' => 'Extract',
'warnfail' => 'If this page aborts anormaly, simply click on this button',
'continue' => 'Continue',
'reprise' => 'Continuing archive extraction at file number %1',
'extract_in' => 'Extract in',
'extract_err' => "Error while extracting archive [%1]\n%2",
'arch_result' => "%1 files where extracted\n%2 files were skipped%3",
'usecheckpoint' => 'Use checkpoints',
'nocheckpoint' => "Unable to use checkpoints. Cannot create checkpoint directory\n%1",
'noneedcheckpoint' => 'Archive was succesfully extracted, no need to retry',
'aperçu' => 'Archive content preview',
'gunzip' => 'gunzip',
'createds' => "Those files or directories were successfuly created:\n[%1]",
'not_createds' => "Errors encountered while creating those files or directories:\n[%1]",
'rec_list' => 'recursively list',
'rec_list_details' => 'detailed rec list',
'create_tar' => 'Create tar archive',
'contact' => 'contact ',
'usecrypt' => 'Use encrypted password',
'file_too_big' => '\\u26A0 Error ! \\u26A0\\nFile too big\\nmax %d \\nfile : ',

'directory' => 'Verzeichnis',
'file' => 'Datei',
'filename' => 'Dateiname',

'size' => 'Größe',
'permission' => 'Rechte',
'owner' => 'Eigner',
'group' => 'Gruppe',
'other' => 'Andere',
'functions' => 'Funktionen',

'read' => 'lesen',
'write' => 'schreiben',
'execute' => 'ausführen',

'create_symlink' => 'Symlink erstellen',
'delete' => 'löschen',
'rename' => 'umbenennen',
'move' => 'verschieben',
'copy' => 'kopieren',
'edit' => 'editieren',
'download' => 'herunterladen',
'upload' => 'hochladen',
'create' => 'erstellen',
'change' => 'wechseln',
'save' => 'speichern',
'saveandquit' => 'speichern. zurück',
'set' => 'setze',
'reset' => 'zurücksetzen',
'relative' => 'Pfad zum Ziel relativ',

'yes' => 'Ja',
'no' => 'Nein',
'back' => 'zurück',
'destination' => 'Ziel',
'symlink' => 'Symbolischer Link',
'no_output' => 'keine Ausgabe',

'user' => 'Benutzername',
'password' => 'Kennwort',
'add' => 'hinzufügen',
'add_basic_auth' => 'HTTP-Basic-Auth hinzufügen',

'uploaded' => '"[%1]" wurde hochgeladen.',
'not_uploaded' => '"[%1]" konnte nicht hochgeladen werden.',
'already_exists' => '"[%1]" existiert bereits.',
'created' => '"[%1]" wurde erstellt.',
'not_created' => '"[%1]" konnte nicht erstellt werden.',
'really_delete' => 'Sollen folgende Dateien wirklich gelöscht werden?',
'deleted' => "Folgende Dateien wurden gelöscht:\n[%1]",
'not_deleted' => "Folgende Dateien konnten nicht gelöscht werden:\n[%1]",
'rename_file' => 'Benenne Datei um:',
'renamed' => '"[%1]" wurde in "[%2]" umbenannt.',
'not_renamed' => '"[%1] konnte nicht in "[%2]" umbenannt werden.',
'move_files' => 'Verschieben folgende Dateien:',
'moved' => "Folgende Dateien wurden nach \"[%2]\" verschoben:\n[%1]",
'not_moved' => "Folgende Dateien konnten nicht nach \"[%2]\" verschoben werden:\n[%1]",
'copy_files' => 'Kopiere folgende Dateien:',
'copied' => "Folgende Dateien wurden nach \"[%2]\" kopiert:\n[%1]",
'not_copied' => "Folgende Dateien konnten nicht nach \"[%2]\" kopiert werden:\n[%1]",
'not_edited' => '"[%1]" kann nicht editiert werden.',
'executed' => "\"[%1]\" wurde erfolgreich ausgeführt:\n{%2}",
'not_executed' => "\"[%1]\" konnte nicht erfolgreich ausgeführt werden:\n{%2}",
'saved' => '"[%1]" wurde gespeichert.',
'not_saved' => '"[%1]" konnte nicht gespeichert werden.',
'symlinked' => 'Symbolischer Link von "[%2]" nach "[%1]" wurde erstellt.',
'not_symlinked' => 'Symbolischer Link von "[%2]" nach "[%1]" konnte nicht erstellt werden.',
'permission_for' => 'Rechte für "[%1]":',
'permission_set' => 'Die Rechte für "[%1]" wurden auf [%2] gesetzt.',
'permission_not_set' => 'Die Rechte für "[%1]" konnten nicht auf [%2] gesetzt werden.',
'not_readable' => '"[%1]" kann nicht gelesen werden.'
		);

	case 'fr':

		$date_format = 'd.m.y H:i:s';
		$word_charset = 'UTF-8';

		return array(
'send_tar' => 'Obtenir une archive tar',
'extract' => 'Extraire',
'warnfail' => 'Si cette page se termine anormalement, cliquez sur ce bouton',
'continue' => 'Continuer',
'reprise' => 'Reprise de l\'extraction de l\'archive au fichier %1',
'extract_in' => 'Extraire dans',
'extract_err' => "Erreur au cours de l'extraction de [%1]\n%2",
'arch_result' => "Extrait %1 fichiers\nPassé %2 fichiers%3",
'usecheckpoint' => 'Utiliser des points de reprise',
'nocheckpoint' => "Impossible d'utiliser des points de reprise. Ne peut créer\nle répertoire %1",
'noneedcheckpoint' => 'L\'extraction de l\'archive a été un succès. Inutile de reprendre',
'aperçu' => 'Aperçu du contenu',
'gunzip' => 'décompresser',
'createds'	=> "Fichiers ou répertoires créés:\n[%1]",
'not_createds'	=> "Erreurs lors de la création de ces fichiers ou répertoires\n[%1]",

'directory' => 'Répertoire',
'file' => 'Fichier',
'filename' => 'Nom fichier',

'size' => 'Taille',
'permission' => 'Droits',
'owner' => 'Propriétaire',
'group' => 'Groupe',
'other' => 'Autres',
'functions' => 'Fonctions',

'read' => 'Lire',
'write' => 'Écrire',
'execute' => 'Exécuter',
'rec_list' => 'lister récursivement',
'rec_list_details' => 'lister réc. (détails)',
'create_tar' => 'Créer une archive tar',

'create_symlink' => 'Créer lien symbolique',
'delete' => 'Effacer',
'rename' => 'Renommer',
'move' => 'Déplacer',
'copy' => 'Copier',
'edit' => 'Modifier',
'download' => 'Télécharger sur PC',
'upload' => 'Téléverser',
'create' => 'Créer',
'change' => 'Changer',
'save' => 'Sauvegarder',
'saveandquit' => 'Sauvegarder et retour',
'set' => 'Exécuter',
'reset' => 'Réinitialiser',
'relative' => 'Relatif',

'yes' => 'Oui',
'no' => 'Non',
'back' => 'Retour',
'destination' => 'Destination',
'symlink' => 'Lien symbollique',
'no_output' => 'Pas de sortie',
'contact' => 'Écrire à ',


'user' => 'Utilisateur',
'password' => 'Mot de passe',
'add' => 'Ajouter',
'add_basic_auth' => 'Ajouter authentification basique',
'usecrypt' => 'Utiliser un mot de passe chiffré',
'file_too_big' => '\\u26A0 Erreur ! \\u26A0\\nFichier trop grand\\nmax %d \\nfichier : ',

'uploaded' => '"[%1]" a bien été téléversé.',
'not_uploaded' => '"[%1]" n\'a pas été téléversé.',
'already_exists' => '"[%1]" existe déjà.',
'created' => '"[%1]" a été créé.',
'not_created' => '"[%1]" n\'a pas pu être créé.',
'really_delete' => 'Effacer le fichier?',
'deleted' => "Ces fichiers ont été détruits:\n[%1]",
'not_deleted' => "Ces fichiers n'ont pu être détruits:\n[%1]",
'rename_file' => 'Renommer ce fichier:',
'renamed' => '"[%1]" a été renommé en "[%2]".',
'not_renamed' => '"[%1]" n\'a pas pu être renommé en "[%2]".',
'move_files' => 'Déplacer ces fichiers:',
'moved' => "Ces fichiers ont été déplacés en \"[%2]\":\n[%1]",
'not_moved' => "Ces fichiers n'ont pas pu être déplacés en \"[%2]\":\n[%1]",
'copy_files' => 'Copier ces fichiers:',
'copied' => "Ces fichiers ont été copiés en \"[%2]\":\n[%1]",
'not_copied' => "Ces fichiers n'ont pas pu être copiés en \"[%2]\":\n[%1]",
'not_edited' => '"[%1]" ne peut être ouvert.',
'executed' => "\"[%1]\" a été brillamment exécuté :\n{%2}",
'not_executed' => "\"[%1]\" n'a pas pu être exécuté:\n{%2}",
'saved' => '"[%1]" a été sauvegardé.',
'not_saved' => '"[%1]" n\'a pas pu être sauvegardé.',
'symlinked' => 'Lien symbolique créé de "[%2]" vers "[%1]".',
'not_symlinked' => 'Impossible de créer un lien symbolique de "[%2]" vers "[%1]".',
'permission_for' => 'Droits de "[%1]":',
'permission_set' => 'Droits de "[%1]" ont été changés en [%2].',
'permission_not_set' => 'Droits de "[%1]" n\'ont pas pu être changés en[%2].',
'not_readable' => '"[%1]" ne peut pas être ouvert.'
		);

	case 'it':

		$date_format = 'd-m-Y H:i:s';
		$word_charset = 'UTF-8';

		return array(
'send_tar' => 'Get tar archive',
'extract' => 'Extract',
'warnfail' => 'If this page aborts anormaly, simply click on this button',
'continue' => 'Continue',
'reprise' => 'Continuing archive extraction at file number %1',
'extract_in' => 'Extract in',
'extract_err' => "Error while extracting archive [%1]\n%2",
'arch_result' => "%1 files where extracted\n%2 files were skipped%3",
'usecheckpoint' => 'Use checkpoints',
'nocheckpoint' => "Unable to use checkpoints. Cannot create checkpoint directory\n%1",
'noneedcheckpoint' => 'Archive was succesfully extracted, no need to retry',
'aperçu' => 'Archive content preview',
'gunzip'	=> 'gunzip',
'createds'	=> "Those files or directories were successfuly created:\n[%1]",
'not_createds'	=> "Errors encountered while creating those files or directories:\n[%1]",
'rec_list' => 'recursively list',
'rec_list_details' => 'detailed rec list',
'create_tar' => 'Create tar archive',
'contact' => 'contact ',
'usecrypt' => 'Use encrypted password',
'file_too_big' => '\\u26A0 Error ! \\u26A0\\nFile too big\\nmax %d \\nfile : ',

'directory' => 'Directory',
'file' => 'File',
'filename' => 'Nome File',

'size' => 'Dimensioni',
'permission' => 'Permessi',
'owner' => 'Proprietario',
'group' => 'Gruppo',
'other' => 'Altro',
'functions' => 'Funzioni',

'read' => 'leggi',
'write' => 'scrivi',
'execute' => 'esegui',

'create_symlink' => 'crea link simbolico',
'delete' => 'cancella',
'rename' => 'rinomina',
'move' => 'sposta',
'copy' => 'copia',
'edit' => 'modifica',
'download' => 'download',
'upload' => 'upload',
'create' => 'crea',
'change' => 'cambia',
'save' => 'salva',
'saveandquit' => 'salva. indietro',
'set' => 'imposta',
'reset' => 'reimposta',
'relative' => 'Percorso relativo per la destinazione',

'yes' => 'Si',
'no' => 'No',
'back' => 'indietro',
'destination' => 'Destinazione',
'symlink' => 'Link simbolico',
'no_output' => 'no output',

'user' => 'User',
'password' => 'Password',
'add' => 'aggiungi',
'add_basic_auth' => 'aggiungi autenticazione base',

'uploaded' => '"[%1]" è stato caricato.',
'not_uploaded' => '"[%1]" non è stato caricato.',
'already_exists' => '"[%1]" esiste già.',
'created' => '"[%1]" è stato creato.',
'not_created' => '"[%1]" non è stato creato.',
'really_delete' => 'Cancello questi file ?',
'deleted' => "Questi file sono stati cancellati:\n[%1]",
'not_deleted' => "Questi file non possono essere cancellati:\n[%1]",
'rename_file' => 'File rinominato:',
'renamed' => '"[%1]" è stato rinominato in "[%2]".',
'not_renamed' => '"[%1] non è stato rinominato in "[%2]".',
'move_files' => 'Sposto questi file:',
'moved' => "Questi file sono stati spostati in \"[%2]\":\n[%1]",
'not_moved' => "Questi file non possono essere spostati in \"[%2]\":\n[%1]",
'copy_files' => 'Copio questi file',
'copied' => "Questi file sono stati copiati in \"[%2]\":\n[%1]",
'not_copied' => "Questi file non possono essere copiati in \"[%2]\":\n[%1]",
'not_edited' => '"[%1]" non può essere modificato.',
'executed' => "\"[%1]\" è stato eseguito con successo:\n{%2}",
'not_executed' => "\"[%1]\" non è stato eseguito con successo\n{%2}",
'saved' => '"[%1]" è stato salvato.',
'not_saved' => '"[%1]" non è stato salvato.',
'symlinked' => 'Il link siambolico da "[%2]" a "[%1]" è stato creato.',
'not_symlinked' => 'Il link siambolico da "[%2]" a "[%1]" non è stato creato.',
'permission_for' => 'Permessi di "[%1]":',
'permission_set' => 'I permessi di "[%1]" sono stati impostati [%2].',
'permission_not_set' => 'I permessi di "[%1]" non sono stati impostati [%2].',
'not_readable' => '"[%1]" non può essere letto.'
		);

	case 'nl':

		$date_format = 'n/j/y H:i:s';
		$word_charset = 'UTF-8';

		return array(
'send_tar' => 'Get tar archive',
'extract' => 'Extract',
'warnfail' => 'If this page aborts anormaly, simply click on this button',
'continue' => 'Continue',
'reprise' => 'Continuing archive extraction at file number %1',
'extract_in' => 'Extract in',
'extract_err' => "Error while extracting archive [%1]\n%2",
'arch_result' => "%1 files where extracted\n%2 files were skipped%3",
'usecheckpoint' => 'Use checkpoints',
'nocheckpoint' => "Unable to use checkpoints. Cannot create checkpoint directory\n%1",
'noneedcheckpoint' => 'Archive was succesfully extracted, no need to retry',
'gunzip'	=> 'gunzip',
'createds'	=> "Those files or directories were successfuly created:\n[%1]",
'not_createds'	=> "Errors encountered while creating those files or directories:\n[%1]",
'rec_list' => 'recursively list',
'rec_list_details' => 'detailed rec list',
'create_tar' => 'Create tar archive',
'contact' => 'contact ',
'usecrypt' => 'Use encrypted password',
'file_too_big' => '\\u26A0 Error ! \\u26A0\\nFile too big\\nmax %d \\nfile : ',

'directory' => 'Directory',
'file' => 'Bestand',
'filename' => 'Bestandsnaam',

'size' => 'Grootte',
'permission' => 'Bevoegdheid',
'owner' => 'Eigenaar',
'group' => 'Groep',
'other' => 'Anderen',
'functions' => 'Functies',

'read' => 'lezen',
'write' => 'schrijven',
'execute' => 'uitvoeren',

'create_symlink' => 'maak symlink',
'delete' => 'verwijderen',
'rename' => 'hernoemen',
'move' => 'verplaatsen',
'copy' => 'kopieren',
'edit' => 'bewerken',
'download' => 'downloaden',
'upload' => 'uploaden',
'create' => 'aanmaken',
'change' => 'veranderen',
'save' => 'opslaan',
'saveandquit' => 'opslaan. telug',
'set' => 'instellen',
'reset' => 'resetten',
'relative' => 'Relatief pat naar doel',

'yes' => 'Ja',
'no' => 'Nee',
'back' => 'terug',
'destination' => 'Bestemming',
'symlink' => 'Symlink',
'no_output' => 'geen output',

'user' => 'Gebruiker',
'password' => 'Wachtwoord',
'add' => 'toevoegen',
'add_basic_auth' => 'add basic-authentification',

'uploaded' => '"[%1]" is verstuurd.',
'not_uploaded' => '"[%1]" kan niet worden verstuurd.',
'already_exists' => '"[%1]" bestaat al.',
'created' => '"[%1]" is aangemaakt.',
'not_created' => '"[%1]" kan niet worden aangemaakt.',
'really_delete' => 'Deze bestanden verwijderen?',
'deleted' => "Deze bestanden zijn verwijderd:\n[%1]",
'not_deleted' => "Deze bestanden konden niet worden verwijderd:\n[%1]",
'rename_file' => 'Bestandsnaam veranderen:',
'renamed' => '"[%1]" heet nu "[%2]".',
'not_renamed' => '"[%1] kon niet worden veranderd in "[%2]".',
'move_files' => 'Verplaats deze bestanden:',
'moved' => "Deze bestanden zijn verplaatst naar \"[%2]\":\n[%1]",
'not_moved' => "Kan deze bestanden niet verplaatsen naar \"[%2]\":\n[%1]",
'copy_files' => 'Kopieer deze bestanden:',
'copied' => "Deze bestanden zijn gekopieerd naar \"[%2]\":\n[%1]",
'not_copied' => "Deze bestanden kunnen niet worden gekopieerd naar \"[%2]\":\n[%1]",
'not_edited' => '"[%1]" kan niet worden bewerkt.',
'executed' => "\"[%1]\" is met succes uitgevoerd:\n{%2}",
'not_executed' => "\"[%1]\" is niet goed uitgevoerd:\n{%2}",
'saved' => '"[%1]" is opgeslagen.',
'not_saved' => '"[%1]" is niet opgeslagen.',
'symlinked' => 'Symlink van "[%2]" naar "[%1]" is aangemaakt.',
'not_symlinked' => 'Symlink van "[%2]" naar "[%1]" is niet aangemaakt.',
'permission_for' => 'Bevoegdheid voor "[%1]":',
'permission_set' => 'Bevoegdheid van "[%1]" is ingesteld op [%2].',
'permission_not_set' => 'Bevoegdheid van "[%1]" is niet ingesteld op [%2].',
'not_readable' => '"[%1]" kan niet worden gelezen.'
		);

	case 'se':

		$date_format = 'n/j/y H:i:s';
		$word_charset = 'UTF-8';
 
		return array(
'send_tar' => 'Get tar archive',
'extract' => 'Extract',
'warnfail' => 'If this page aborts anormaly, simply click on this button',
'continue' => 'Continue',
'reprise' => 'Continuing archive extraction at file number %1',
'extract_in' => 'Extract in',
'extract_err' => "Error while extracting archive [%1]\n%2",
'arch_result' => "%1 files where extracted\n%2 files were skipped%3",
'usecheckpoint' => 'Use checkpoints',
'nocheckpoint' => "Unable to use checkpoints. Cannot create checkpoint directory\n%1",
'noneedcheckpoint' => 'Archive was succesfully extracted, no need to retry',
'aperçu' => 'Archive content preview',
'gunzip'	=> 'gunzip',
'createds'	=> "Those files or directories were successfuly created:\n[%1]",
'not_createds'	=> "Errors encountered while creating those files or directories:\n[%1]",
'rec_list' => 'recursively list',
'rec_list_details' => 'detailed rec list',
'create_tar' => 'Create tar archive',
'contact' => 'contact ',
'usecrypt' => 'Use encrypted password',
'file_too_big' => '\\u26A0 Error ! \\u26A0\\nFile too big\\nmax %d \\nfile : ',

'directory' => 'Mapp',
'file' => 'Fil',
'filename' => 'Filnamn',
 
'size' => 'Storlek',
'permission' => 'Säkerhetsnivå',
'owner' => 'Ägare',
'group' => 'Grupp',
'other' => 'Andra',
'functions' => 'Funktioner',
 
'read' => 'Läs',
'write' => 'Skriv',
'execute' => 'Utför',
 
'create_symlink' => 'Skapa symlink',
'delete' => 'Radera',
'rename' => 'Byt namn',
'move' => 'Flytta',
'copy' => 'Kopiera',
'edit' => 'Ändra',
'download' => 'Ladda ner',
'upload' => 'Ladda upp',
'create' => 'Skapa',
'change' => 'Ändra',
'save' => 'Spara',
'saveandquit' => 'Spara. Tillbaks',
'set' => 'Markera',
'reset' => 'Töm',
'relative' => 'Relative path to target',
 
'yes' => 'Ja',
'no' => 'Nej',
'back' => 'Tillbaks',
'destination' => 'Destination',
'symlink' => 'Symlink',
'no_output' => 'no output',
 
'user' => 'Användare',
'password' => 'Lösenord',
'add' => 'Lägg till',
'add_basic_auth' => 'add basic-authentification',
 
'uploaded' => '"[%1]" har laddats upp.',
'not_uploaded' => '"[%1]" kunde inte laddas upp.',
'already_exists' => '"[%1]" finns redan.',
'created' => '"[%1]" har skapats.',
'not_created' => '"[%1]" kunde inte skapas.',
'really_delete' => 'Radera dessa filer?',
'deleted' => "De här filerna har raderats:\n[%1]",
'not_deleted' => "Dessa filer kunde inte raderas:\n[%1]",
'rename_file' => 'Byt namn på fil:',
'renamed' => '"[%1]" har bytt namn till "[%2]".',
'not_renamed' => '"[%1] kunde inte döpas om till "[%2]".',
'move_files' => 'Flytta dessa filer:',
'moved' => "Dessa filer har flyttats till \"[%2]\":\n[%1]",
'not_moved' => "Dessa filer kunde inte flyttas till \"[%2]\":\n[%1]",
'copy_files' => 'Kopiera dessa filer:',
'copied' => "Dessa filer har kopierats till \"[%2]\":\n[%1]",
'not_copied' => "Dessa filer kunde inte kopieras till \"[%2]\":\n[%1]",
'not_edited' => '"[%1]" kan inte ändras.',
'executed' => "\"[%1]\" har utförts:\n{%2}",
'not_executed' => "\"[%1]\" kunde inte utföras:\n{%2}",
'saved' => '"[%1]" har sparats.',
'not_saved' => '"[%1]" kunde inte sparas.',
'symlinked' => 'Symlink från "[%2]" till "[%1]" har skapats.',
'not_symlinked' => 'Symlink från "[%2]" till "[%1]" kunde inte skapas.',
'permission_for' => 'Rättigheter för "[%1]":',
'permission_set' => 'Rättigheter för "[%1]" ändrades till [%2].',
'permission_not_set' => 'Permission of "[%1]" could not be set to [%2].',
'not_readable' => '"[%1]" kan inte läsas.'
		);

	case 'sp':

		$date_format = 'j/n/y H:i:s';
		$word_charset = 'UTF-8';

		return array(
'send_tar' => 'Get tar archive',
'extract' => 'Extract',
'warnfail' => 'If this page aborts anormaly, simply click on this button',
'continue' => 'Continue',
'reprise' => 'Continuing archive extraction at file number %1',
'extract_in' => 'Extract in',
'extract_err' => "Error while extracting archive [%1]\n%2",
'arch_result' => "%1 files where extracted\n%2 files were skipped%3",
'usecheckpoint' => 'Use checkpoints',
'nocheckpoint' => "Unable to use checkpoints. Cannot create checkpoint directory\n%1",
'noneedcheckpoint' => 'Archive was succesfully extracted, no need to retry',
'aperçu' => 'Archive content preview',
'gunzip'	=> 'gunzip',
'createds'	=> "Those files or directories were successfuly created:\n[%1]",
'not_createds'	=> "Errors encountered while creating those files or directories:\n[%1]",
'rec_list' => 'recursively list',
'rec_list_details' => 'detailed rec list',
'create_tar' => 'Create tar archive',
'contact' => 'contact ',
'usecrypt' => 'Use encrypted password',
'file_too_big' => '\\u26A0 Error ! \\u26A0\\nFile too big\\nmax %d \\nfile : ',

'directory' => 'Directorio',
'file' => 'Archivo',
'filename' => 'Nombre Archivo',

'size' => 'Tamaño',
'permission' => 'Permisos',
'owner' => 'Propietario',
'group' => 'Grupo',
'other' => 'Otros',
'functions' => 'Funciones',

'read' => 'lectura',
'write' => 'escritura',
'execute' => 'ejecución',

'create_symlink' => 'crear enlace',
'delete' => 'borrar',
'rename' => 'renombrar',
'move' => 'mover',
'copy' => 'copiar',
'edit' => 'editar',
'download' => 'bajar',
'upload' => 'subir',
'create' => 'crear',
'change' => 'cambiar',
'save' => 'salvar',
'saveandquit' => 'salvar. atrás',
'set' => 'setear',
'reset' => 'resetear',
'relative' => 'Path relativo',

'yes' => 'Si',
'no' => 'No',
'back' => 'atrás',
'destination' => 'Destino',
'symlink' => 'Enlace',
'no_output' => 'sin salida',

'user' => 'Usuario',
'password' => 'Clave',
'add' => 'agregar',
'add_basic_auth' => 'agregar autentificación básica',

'uploaded' => '"[%1]" ha sido subido.',
'not_uploaded' => '"[%1]" no pudo ser subido.',
'already_exists' => '"[%1]" ya existe.',
'created' => '"[%1]" ha sido creado.',
'not_created' => '"[%1]" no pudo ser creado.',
'really_delete' => '¿Borra estos archivos?',
'deleted' => "Estos archivos han sido borrados:\n[%1]",
'not_deleted' => "Estos archivos no pudieron ser borrados:\n[%1]",
'rename_file' => 'Renombra archivo:',
'renamed' => '"[%1]" ha sido renombrado a "[%2]".',
'not_renamed' => '"[%1] no pudo ser renombrado a "[%2]".',
'move_files' => 'Mover estos archivos:',
'moved' => "Estos archivos han sido movidos a \"[%2]\":\n[%1]",
'not_moved' => "Estos archivos no pudieron ser movidos a \"[%2]\":\n[%1]",
'copy_files' => 'Copiar estos archivos:',
'copied' => "Estos archivos han sido copiados a  \"[%2]\":\n[%1]",
'not_copied' => "Estos archivos no pudieron ser copiados \"[%2]\":\n[%1]",
'not_edited' => '"[%1]" no pudo ser editado.',
'executed' => "\"[%1]\" ha sido ejecutado correctamente:\n{%2}",
'not_executed' => "\"[%1]\" no pudo ser ejecutado correctamente:\n{%2}",
'saved' => '"[%1]" ha sido salvado.',
'not_saved' => '"[%1]" no pudo ser salvado.',
'symlinked' => 'Enlace desde "[%2]" a "[%1]" ha sido creado.',
'not_symlinked' => 'Enlace desde "[%2]" a "[%1]" no pudo ser creado.',
'permission_for' => 'Permisos de "[%1]":',
'permission_set' => 'Permisos de "[%1]" fueron seteados a [%2].',
'permission_not_set' => 'Permisos de "[%1]" no pudo ser seteado a [%2].',
'not_readable' => '"[%1]" no pudo ser leído.'
		);

	case 'dk':

		$date_format = 'n/j/y H:i:s';
		$word_charset = 'UTF-8';

		return array(
'send_tar' => 'Get tar archive',
'extract' => 'Extract',
'warnfail' => 'If this page aborts anormaly, simply click on this button',
'continue' => 'Continue',
'reprise' => 'Continuing archive extraction at file number %1',
'extract_in' => 'Extract in',
'extract_err' => "Error while extracting archive [%1]\n%2",
'arch_result' => "%1 files where extracted\n%2 files were skipped%3",
'usecheckpoint' => 'Use checkpoints',
'nocheckpoint' => "Unable to use checkpoints. Cannot create checkpoint directory\n%1",
'noneedcheckpoint' => 'Archive was succesfully extracted, no need to retry',
'aperçu' => 'Archive content preview',
'gunzip'	=> 'gunzip',
'createds'	=> "Those files or directories were successfuly created:\n[%1]",
'not_createds'	=> "Errors encountered while creating those files or directories:\n[%1]",
'rec_list' => 'recursively list',
'rec_list_details' => 'detailed rec list',
'create_tar' => 'Create tar archive',
'contact' => 'contact ',
'usecrypt' => 'Use encrypted password',
'file_too_big' => '\\u26A0 Error ! \\u26A0\\nFile too big\\nmax %d \\nfile : ',

'directory' => 'Mappe',
'file' => 'Fil',
'filename' => 'Filnavn',

'size' => 'Størrelse',
'permission' => 'Rettighed',
'owner' => 'Ejer',
'group' => 'Gruppe',
'other' => 'Andre',
'functions' => 'Funktioner',

'read' => 'læs',
'write' => 'skriv',
'execute' => 'kør',

'create_symlink' => 'opret symbolsk link',
'delete' => 'slet',
'rename' => 'omdøb',
'move' => 'flyt',
'copy' => 'kopier',
'edit' => 'rediger',
'download' => 'download',
'upload' => 'upload',
'create' => 'opret',
'change' => 'skift',
'save' => 'gem',
'saveandquit' => 'gem. tilbage',
'set' => 'sæt',
'reset' => 'nulstil',
'relative' => 'Relativ sti til valg',

'yes' => 'Ja',
'no' => 'Nej',
'back' => 'tilbage',
'destination' => 'Distination',
'symlink' => 'Symbolsk link',
'no_output' => 'ingen resultat',

'user' => 'Bruger',
'password' => 'Kodeord',
'add' => 'tilføj',
'add_basic_auth' => 'tilføj grundliggende rettigheder',

'uploaded' => '"[%1]" er blevet uploaded.',
'not_uploaded' => '"[%1]" kunnu ikke uploades.',
'already_exists' => '"[%1]" findes allerede.',
'created' => '"[%1]" er blevet oprettet.',
'not_created' => '"[%1]" kunne ikke oprettes.',
'really_delete' => 'Slet disse filer?',
'deleted' => "Disse filer er blevet slettet:\n[%1]",
'not_deleted' => "Disse filer kunne ikke slettes:\n[%1]",
'rename_file' => 'Omdød fil:',
'renamed' => '"[%1]" er blevet omdøbt til "[%2]".',
'not_renamed' => '"[%1] kunne ikke omdøbes til "[%2]".',
'move_files' => 'Flyt disse filer:',
'moved' => "Disse filer er blevet flyttet til \"[%2]\":\n[%1]",
'not_moved' => "Disse filer kunne ikke flyttes til \"[%2]\":\n[%1]",
'copy_files' => 'Kopier disse filer:',
'copied' => "Disse filer er kopieret til \"[%2]\":\n[%1]",
'not_copied' => "Disse filer kunne ikke kopieres til \"[%2]\":\n[%1]",
'not_edited' => '"[%1]" kan ikke redigeres.',
'executed' => "\"[%1]\" er blevet kørt korrekt:\n{%2}",
'not_executed' => "\"[%1]\" kan ikke køres korrekt:\n{%2}",
'saved' => '"[%1]" er blevet gemt.',
'not_saved' => '"[%1]" kunne ikke gemmes.',
'symlinked' => 'Symbolsk link fra "[%2]" til "[%1]" er blevet oprettet.',
'not_symlinked' => 'Symbolsk link fra "[%2]" til "[%1]" kunne ikke oprettes.',
'permission_for' => 'Rettigheder for "[%1]":',
'permission_set' => 'Rettigheder for "[%1]" blev sat til [%2].',
'permission_not_set' => 'Rettigheder for "[%1]" kunne ikke sættes til [%2].',
'not_readable' => '"[%1]" Kan ikke læses.'
		);

	case 'tr':

		$date_format = 'n/j/y H:i:s';
		$word_charset = 'UTF-8';

		return array(
'send_tar' => 'Get tar archive',
'extract' => 'Extract',
'warnfail' => 'If this page aborts anormaly, simply click on this button',
'continue' => 'Continue',
'reprise' => 'Continuing archive extraction at file number %1',
'extract_in' => 'Extract in',
'extract_err' => "Error while extracting archive [%1]\n%2",
'arch_result' => "%1 files where extracted\n%2 files were skipped%3",
'usecheckpoint' => 'Use checkpoints',
'nocheckpoint' => "Unable to use checkpoints. Cannot create checkpoint directory\n%1",
'noneedcheckpoint' => 'Archive was succesfully extracted, no need to retry',
'aperçu' => 'Archive content preview',
'gunzip'	=> 'gunzip',
'createds'	=> "Those files or directories were successfuly created:\n[%1]",
'not_createds'	=> "Errors encountered while creating those files or directories:\n[%1]",
'rec_list' => 'recursively list',
'rec_list_details' => 'detailed rec list',
'create_tar' => 'Create tar archive',
'contact' => 'contact ',
'usecrypt' => 'Use encrypted password',
'file_too_big' => '\\u26A0 Error ! \\u26A0\\nFile too big\\nmax %d \\nfile : ',

'directory' => 'Klasör',
'file' => 'Dosya',
'filename' => 'dosya adi',

'size' => 'boyutu',
'permission' => 'Izin',
'owner' => 'sahib',
'group' => 'Grup',
'other' => 'Digerleri',
'functions' => 'Fonksiyonlar',

'read' => 'oku',
'write' => 'yaz',
'execute' => 'çalistir',

'create_symlink' => 'yarat symlink',
'delete' => 'sil',
'rename' => 'ad degistir',
'move' => 'tasi',
'copy' => 'kopyala',
'edit' => 'düzenle',
'download' => 'indir',
'upload' => 'yükle',
'create' => 'create',
'change' => 'degistir',
'save' => 'kaydet',
'saveandquit' => 'kaydet. Geri',
'set' => 'ayar',
'reset' => 'sifirla',
'relative' => 'Hedef yola göre',

'yes' => 'Evet',
'no' => 'Hayir',
'back' => 'Geri',
'destination' => 'Hedef',
'symlink' => 'Kýsa yol',
'no_output' => 'çikti yok',

'user' => 'Kullanici',
'password' => 'Sifre',
'add' => 'ekle',
'add_basic_auth' => 'ekle basit-authentification',

'uploaded' => '"[%1]" yüklendi.',
'not_uploaded' => '"[%1]" yüklenemedi.',
'already_exists' => '"[%1]" kullanilmakta.',
'created' => '"[%1]" olusturuldu.',
'not_created' => '"[%1]" olusturulamadi.',
'really_delete' => 'Bu dosyalari silmek istediginizden eminmisiniz?',
'deleted' => "Bu dosyalar silindi:\n[%1]",
'not_deleted' => "Bu dosyalar silinemedi:\n[%1]",
'rename_file' => 'Adi degisen dosya:',
'renamed' => '"[%1]" adili dosyanin yeni adi "[%2]".',
'not_renamed' => '"[%1] adi degistirilemedi "[%2]" ile.',
'move_files' => 'Tasinan dosyalar:',
'moved' => "Bu dosyalari tasidiginiz yer \"[%2]\":\n[%1]",
'not_moved' => "Bu dosyalari tasiyamadiginiz yer \"[%2]\":\n[%1]",
'copy_files' => 'Kopyalanan dosyalar:',
'copied' => "Bu dosyalar kopyalandi \"[%2]\":\n[%1]",
'not_copied' => "Bu dosyalar kopyalanamiyor \"[%2]\":\n[%1]",
'not_edited' => '"[%1]" düzenlenemiyor.',
'executed' => "\"[%1]\" basariyla çalistirildi:\n{%2}",
'not_executed' => "\"[%1]\" çalistirilamadi:\n{%2}",
'saved' => '"[%1]" kaydedildi.',
'not_saved' => '"[%1]" kaydedilemedi.',
'symlinked' => '"[%2]" den "[%1]" e kýsayol oluþturuldu.',
'not_symlinked' => '"[%2]"den "[%1]" e kýsayol oluþturulamadý.',
'permission_for' => 'Izinler "[%1]":',
'permission_set' => 'Izinler "[%1]" degistirildi [%2].',
'permission_not_set' => 'Izinler "[%1]" degistirilemedi [%2].',
'not_readable' => '"[%1]" okunamiyor.'
		);

	case 'cs':

		$date_format = 'd.m.y H:i:s';
		$word_charset = 'UTF-8';

		return array(
'send_tar' => 'Get tar archive',
'extract' => 'Extract',
'warnfail' => 'If this page aborts anormaly, simply click on this button',
'continue' => 'Continue',
'reprise' => 'Continuing archive extraction at file number %1',
'extract_in' => 'Extract in',
'extract_err' => "Error while extracting archive [%1]\n%2",
'arch_result' => "%1 files where extracted\n%2 files were skipped%3",
'usecheckpoint' => 'Use checkpoints',
'nocheckpoint' => "Unable to use checkpoints. Cannot create checkpoint directory\n%1",
'noneedcheckpoint' => 'Archive was succesfully extracted, no need to retry',
'aperçu' => 'Archive content preview',
'gunzip'	=> 'gunzip',
'createds'	=> "Those files or directories were successfuly created:\n[%1]",
'not_createds'	=> "Errors encountered while creating those files or directories:\n[%1]",
'rec_list' => 'recursively list',
'rec_list_details' => 'detailed rec list',
'create_tar' => 'Create tar archive',
'contact' => 'contact ',
'usecrypt' => 'Use encrypted password',
'file_too_big' => '\\u26A0 Error ! \\u26A0\\nFile too big\\nmax %d \\nfile : ',

'directory' => 'Adresář',
'file' => 'Soubor',
'filename' => 'Jméno souboru',

'size' => 'Velikost',
'permission' => 'Práva',
'owner' => 'Vlastník',
'group' => 'Skupina',
'other' => 'Ostatní',
'functions' => 'Funkce',

'read' => 'Čtení',
'write' => 'Zápis',
'execute' => 'Spouštění',

'create_symlink' => 'Vytvořit symbolický odkaz',
'delete' => 'Smazat',
'rename' => 'Přejmenovat',
'move' => 'Přesunout',
'copy' => 'Zkopírovat',
'edit' => 'Otevřít',
'download' => 'Stáhnout',
'upload' => 'Nahraj na server',
'create' => 'Vytvořit',
'change' => 'Změnit',
'save' => 'Uložit',
'saveandquit' => 'Uložit. Zpět',
'set' => 'Nastavit',
'reset' => 'zpět',
'relative' => 'Relatif',

'yes' => 'Ano',
'no' => 'Ne',
'back' => 'Zpět',
'destination' => 'Destination',
'symlink' => 'Symbolický odkaz',
'no_output' => 'Prázdný výstup',

'user' => 'Uživatel',
'password' => 'Heslo',
'add' => 'Přidat',
'add_basic_auth' => 'přidej základní autentizaci',

'uploaded' => 'Soubor "[%1]" byl nahrán na server.',
'not_uploaded' => 'Soubor "[%1]" nebyl nahrán na server.',
'already_exists' => 'Soubor "[%1]" už exituje.',
'created' => 'Soubor "[%1]" byl vytvořen.',
'not_created' => 'Soubor "[%1]" nemohl být  vytvořen.',
'really_delete' => 'Vymazat soubor?',
'deleted' => "Byly vymazány tyto soubory:\n[%1]",
'not_deleted' => "Tyto soubory nemohly být vytvořeny:\n[%1]",
'rename_file' => 'Přejmenuj soubory:',
'renamed' => 'Soubor "[%1]" byl přejmenován na "[%2]".',
'not_renamed' => 'Soubor "[%1]" nemohl být přejmenován na "[%2]".',
'move_files' => 'Přemístit tyto soubory:',
'moved' => "Tyto soubory byly přemístěny do \"[%2]\":\n[%1]",
'not_moved' => "Tyto soubory nemohly být přemístěny do \"[%2]\":\n[%1]",
'copy_files' => 'Zkopírovat tyto soubory:',
'copied' => "Tyto soubory byly zkopírovány do \"[%2]\":\n[%1]",
'not_copied' => "Tyto soubory nemohly být zkopírovány do \"[%2]\":\n[%1]",
'not_edited' => 'Soubor "[%1]" nemohl být otevřen.',
'executed' => "SOubor \"[%1]\" byl spuštěn :\n{%2}",
'not_executed' => "Soubor \"[%1]\" nemohl být spuštěn:\n{%2}",
'saved' => 'Soubor "[%1]" byl uložen.',
'not_saved' => 'Soubor "[%1]" nemohl být uložen.',
'symlinked' => 'Byl vyvořen symbolický odkaz "[%2]" na soubor "[%1]".',
'not_symlinked' => 'Symbolický odkaz "[%2]" na soubor "[%1]" nemohl být vytvořen.',
'permission_for' => 'Práva k "[%1]":',
'permission_set' => 'Práva k "[%1]" byla změněna na [%2].',
'permission_not_set' => 'Práva k "[%1]" nemohla být změněna na [%2].',
'not_readable' => 'Soubor "[%1]" není možno přečíst.'
		);

	case 'ru':

		$date_format = 'd.m.y H:i:s';
		$word_charset = 'UTF-8';
		return array(
'send_tar' => 'Get tar archive',
'extract' => 'Extract',
'warnfail' => 'If this page aborts anormaly, simply click on this button',
'continue' => 'Continue',
'reprise' => 'Continuing archive extraction at file number %1',
'extract_in' => 'Extract in',
'extract_err' => "Error while extracting archive [%1]\n%2",
'arch_result' => "%1 files where extracted\n%2 files were skipped%3",
'usecheckpoint' => 'Use checkpoints',
'nocheckpoint' => "Unable to use checkpoints. Cannot create checkpoint directory\n%1",
'noneedcheckpoint' => 'Archive was succesfully extracted, no need to retry',
'aperçu' => 'Archive content preview',
'gunzip'	=> 'gunzip',
'createds'	=> "Those files or directories were successfuly created:\n[%1]",
'not_createds'	=> "Errors encountered while creating those files or directories:\n[%1]",
'rec_list' => 'recursively list',
'rec_list_details' => 'detailed rec list',
'create_tar' => 'Create tar archive',
'contact' => 'contact ',
'usecrypt' => 'Use encrypted password',
'file_too_big' => '\\u26A0 Error ! \\u26A0\\nFile too big\\nmax %d \\nfile : ',

'directory' => 'Каталог',
'file' => 'Файл',
'filename' => 'Имя файла',

'size' => 'Размер',
'permission' => 'Права',
'owner' => 'Хозяин',
'group' => 'Группа',
'other' => 'Другие',
'functions' => 'Функция',

'read' => 'читать',
'write' => 'писать',
'execute' => 'выполнить',

'create_symlink' => 'Сделать симлинк',
'delete' => 'удалить',
'rename' => 'переименовать',
'move' => 'передвинуть',
'copy' => 'копировать',
'edit' => 'редактировать',
'download' => 'скачать',
'upload' => 'закачать',
'create' => 'сделать',
'change' => 'поменять',
'save' => 'сохранить',
'saveandquit' => 'сохранить. назад',
'set' => 'установить',
'reset' => 'сбросить',
'relative' => 'относительный путь к цели',

'yes' => 'да',
'no' => 'нет',
'back' => 'назад',
'destination' => 'цель',
'symlink' => 'символический линк',
'no_output' => 'нет вывода',

'user' => 'Пользователь',
'password' => 'Пароль',
'add' => 'добавить',
'add_basic_auth' => 'Добавить HTTP-Basic-Auth',

'uploaded' => '"[%1]" был закачен.',
'not_uploaded' => '"[%1]" невозможно было закачять.',
'already_exists' => '"[%1]" уже существует.',
'created' => '"[%1]" был сделан.',
'not_created' => '"[%1]" не возможно сделать.',
'really_delete' => 'Действительно этот файл удалить?',
'deleted' => "Следующие файлы были удалены:\n[%1]",
'not_deleted' => "Следующие файлы не возможно было удалить:\n[%1]",
'rename_file' => 'Переименовываю файл:',
'renamed' => '"[%1]" был переименован на "[%2]".',
'not_renamed' => '"[%1] невозможно было переименовать на "[%2]".',
'move_files' => 'Передвигаю следующие файлы:',
'moved' => "Следующие файлы были передвинуты в каталог \"[%2]\":\n[%1]",
'not_moved' => "Следующие файлы невозможно было передвинуть в каталог \"[%2]\":\n[%1]",
'copy_files' => 'Копирую следущие файлы:',
'copied' => "Следущие файлы былы скопированы в каталог \"[%2]\" :\n[%1]",
'not_copied' => "Следующие файлы невозможно было скопировать в каталог \"[%2]\" :\n[%1]",
'not_edited' => '"[%1]" не может быть отредактирован.',
'executed' => "\"[%1]\" был успешно исполнен:\n{%2}",
'not_executed' => "\"[%1]\" невозможно было запустить на исполнение:\n{%2}",
'saved' => '"[%1]" был сохранен.',
'not_saved' => '"[%1]" невозможно было сохранить.',
'symlinked' => 'Симлинк с "[%2]" на "[%1]" был сделан.',
'not_symlinked' => 'Невозможно было сделать симлинк с "[%2]" на "[%1]".',
'permission_for' => 'Права доступа "[%1]":',
'permission_set' => 'Права доступа "[%1]" были изменены на [%2].',
'permission_not_set' => 'Невозможно было изменить права доступа к "[%1]" на [%2] .',
'not_readable' => '"[%1]" невозможно прочитать.'
		);

	case 'en':
	default:

		$date_format = 'n/j/y H:i:s';
		$word_charset = 'UTF-8';

		return array(
'send_tar' => 'Get tar archive',
'extract' => 'Extract',
'warnfail' => 'If this page aborts anormaly, simply click on this button',
'continue' => 'Continue',
'reprise' => 'Continuing archive extraction at file number %1',
'extract_in' => 'Extract in',
'extract_err' => "Error while extracting archive [%1]\n%2",
'arch_result' => "%1 files where extracted\n%2 files were skipped%3",
'usecheckpoint' => 'Use checkpoints',
'nocheckpoint' => "Unable to use checkpoints. Cannot create checkpoint directory\n%1",
'noneedcheckpoint' => 'Archive was succesfully extracted, no need to retry',
'aperçu' => 'Archive content preview',
'gunzip'	=> 'gunzip',
'createds'	=> "Those files or directories were successfuly created:\n[%1]",
'not_createds'	=> "Errors encountered while creating those files or directories:\n[%1]",

'directory' => 'Directory',
'file' => 'File',
'filename' => 'Filename',

'size' => 'Size',
'permission' => 'Permission',
'owner' => 'Owner',
'group' => 'Group',
'other' => 'Others',
'functions' => 'Functions',

'read' => 'read',
'write' => 'write',
'execute' => 'execute',
'rec_list' => 'recursively list',
'rec_list_details' => 'detailed rec list',
'create_tar' => 'Create tar archive',

'create_symlink' => 'create symlink',
'delete' => 'delete',
'rename' => 'rename',
'move' => 'move',
'copy' => 'copy',
'edit' => 'edit',
'download' => 'download',
'upload' => 'upload',
'create' => 'create',
'change' => 'change',
'save' => 'save',
'saveandquit' => 'save. back',
'set' => 'set',
'reset' => 'reset',
'relative' => 'Relative path to target',

'yes' => 'Yes',
'no' => 'No',
'back' => 'back',
'destination' => 'Destination',
'symlink' => 'Symlink',
'no_output' => 'no output',
'contact' => 'contact ',
'usecrypt' => 'Use encrypted password',
'file_too_big' => '\\u26A0 Error ! \\u26A0\\nFile too big\\nmax %d \\nfile : ',

'user' => 'User',
'password' => 'Password',
'add' => 'add',
'add_basic_auth' => 'add basic-authentification',

'uploaded' => '"[%1]" has been uploaded.',
'not_uploaded' => '"[%1]" could not be uploaded.',
'already_exists' => '"[%1]" already exists.',
'created' => '"[%1]" has been created.',
'not_created' => '"[%1]" could not be created.',
'really_delete' => 'Delete these files?',
'deleted' => "These files have been deleted:\n[%1]",
'not_deleted' => "These files could not be deleted:\n[%1]",
'rename_file' => 'Rename file:',
'renamed' => '"[%1]" has been renamed to "[%2]".',
'not_renamed' => '"[%1] could not be renamed to "[%2]".',
'move_files' => 'Move these files:',
'moved' => "These files have been moved to \"[%2]\":\n[%1]",
'not_moved' => "These files could not be moved to \"[%2]\":\n[%1]",
'copy_files' => 'Copy these files:',
'copied' => "These files have been copied to \"[%2]\":\n[%1]",
'not_copied' => "These files could not be copied to \"[%2]\":\n[%1]",
'not_edited' => '"[%1]" can not be edited.',
'executed' => "\"[%1]\" has been executed successfully:\n{%2}",
'not_executed' => "\"[%1]\" could not be executed successfully:\n{%2}",
'saved' => '"[%1]" has been saved.',
'not_saved' => '"[%1]" could not be saved.',
'symlinked' => 'Symlink from "[%2]" to "[%1]" has been created.',
'not_symlinked' => 'Symlink from "[%2]" to "[%1]" could not be created.',
'permission_for' => 'Permission of "[%1]":',
'permission_set' => 'Permission of "[%1]" was set to [%2].',
'permission_not_set' => 'Permission of "[%1]" could not be set to [%2].',
'not_readable' => '"[%1]" can not be read.'
		);

	}

}

function getimage ($image) {
	switch ($image) {
	case 'sprite':
		return base64_decode('iVBORw0KGgoAAAANSUhEUgAAADUAAADGEAYAAAAicBSEAAABuUlEQVR42u3dQU7DMBAF0N7/BtwpdwpKq0rIorLjOPYMvLfAatnN1w8ucprHAwAAAAAi2/e+lWkBHX4GcPa1GU4K6OoqsJCXOpfC6QH93ohRv2d4UGMvfYKa1qjWQAS1aDPRGpTNRJBdX+1vkqCSbdMF5D8TAAAAAAAAAABAYk4ZCQpBCQpBIShBCTRto9w8ECQoN2H/s8AIGih2hwAAAAAAAAAAALT4etr32mpSiwNqJbCgDRq1mvikJvXangQ2LKj3QO9aBSUoQQlKUAhKUIJaGdTdAQkq2QdfkwYAAAAAAAAAoNu2HT+PU0N9qwlODur83RoCWxpU7fhXGVT52kSDN0rDgjWqtWkmG6RRtaaZrEYJSqM0Co3SKI3SKLqDGr2aLAAAAAAAAAAAl/kW5mRBnSWwxUG93v28lkF5YluyRmnY5KDKg5Sl1qaZ7KRG1QLz0MqbXT2q/KlZggoalEYlufRpVPDNhEYF356f/XxlskE+R2nUoqA8iQ0AAAAAAAAAgHAcYkkWlBvZkgX1eteNbH+2URoWrFGtTTPZII1ypFmj0CiNEpRGoVEaJajbgnIjGwAAAEA23+4Cmzi/YN1xAAAAAElFTkSuQmCC');
	case 'favicon.png':
		return base64_decode('iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAl2cEFnAAAAEAAAABAAXMatwwAAAoxJREFUOMu1UUtPE2EUPd/MdKbtzLRDpzP0QaEPBEwagQgLQ+qLpYkLNyYGg8rW/+DGGGJi4taFUff+BKNxKW6MugFSClShlEJpLe3MMPN9LkrURoIr7+7e3HPPPecA/6NmC7NgjGEkNzI8NTmdf/LoKTd/6+6Ju+SkYSY9DDmohMvltWeEEL9pxuZt22pslDf+zX6xcBmMMZwZHp3TFflAC0rVqB69/u7NErlUuHI6+NXzl9AjBibHz+d1Tfuc0WSW1WSmqaEvY2fz4+l09i8M92dTrddR26uS1FDqaiws5wzZD0MOYCCijmQy6dlSqUgeLj7uOSD0GCIIAMBUgbwf05UVlSgTANDhfRXNjH4FAFlWTzfxWj4Hl5GCLnKv44GASQhQ6Vi1A8bfdFuNtw8+fMOFyG9Yj4SFG3dw2NoHI9yYTVlftWNjp23D8miEUkwUV7/jxf2FHkL+5tw9zrUdiRBBXV5fGaw73Axz7NuyyI26lgvHduGAkp2WpTAj7qxslrzkYJbE4wN0anqGEskfWARjKc/zkgRIRvy+/rgiKUYoRJJqCADBVquJ3WYTO22ns2cdVTleqDBG1yllGyQgiaxjO913eB7jgwkkZQH1tgMzrIEjBDv1OrSgiG3Lw6f1LbieCwCQRB+4mB6GwHetoJSCSAGYRj8MTcUPx0bDtqBrCkzTBC/JoIwek3Ho71MhxKMhNA872Gu0wBhDuVrDuVwGCb8Ey7KPmUQ4viDKu2ugtHsgJPuRMDVw+802eJ4DR7rR7NbrWFouwlOi0GMJ6LEEEDbwcbWESq3WzZ4QCByPRqsDEvSLDCDwPAr76OiXF9lUCkPJBACgvL2N4mYZrtvVLgoCfAIPBoaf54L2roF7DUIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDExLTA1LTI4VDE2OjUwOjM3KzAyOjAwWWjaMgAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxMS0wNS0yOFQxNjo1MDozNyswMjowMCg1Yo4AAAAASUVORK5CYII=');
	}
}

function html_header ( $more=null ) {
	global $site_charset;

global $header_done;
if( $header_done )
return;
$header_done=TRUE;
	echo <<<END
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>

<meta http-equiv="Content-Type" content="text/html; charset=$site_charset" />
<link rel="shortcut icon" href="?image=favicon.png" />
<title>mwebadmin.php</title>

<style type="text/css">
body { font: small sans-serif; text-align: center }
img { width: 17px; height: 13px }
a, a:visited { text-decoration: none; color: navy }
hr { border-style: none; height: 1px; background-color: silver; color: silver }
#main { margin-top: 6pt; margin-left: auto; margin-right: auto; border-spacing: 1px }
#main th { background: #eee; padding: 3pt 3pt 0pt 3pt }
.listing th, .listing td { padding: 1px 3pt 0 3pt }
.listing th { border: 1px solid silver }
.listing td { border: 1px solid #ddd; background: white }
.listing .checkbox { text-align: center }
.listing .filename { text-align: left }
.listing .size { text-align: right }
.listing th.permission { text-align: left }
.listing td.permission { font-family: monospace }
.listing .owner { text-align: left }
.listing .group { text-align: left }
.listing .functions { text-align: left }
.listing_footer td { background: #eee; border: 1px solid silver }
#directory, #upload, #create, .listing_footer td, #error td, .notice td { text-align: left; padding: 3pt }
#directory { background: #eee; border: 1px solid silver }
#upload { padding-top: 1em }
#create { padding-bottom: 1em }
.small, .small option { font-size: x-small }
textarea { border: none; background: white }
table.info, table.dialog { margin-left: auto; margin-right: auto }
td.info, td.dialog { background: #eee; padding: 1ex; border: 1px solid silver; text-align: center }
#permission { margin-left: auto; margin-right: auto }
#permission td { padding-left: 3pt; padding-right: 3pt; text-align: center }
td.permission_action { text-align: right }
#symlink { background: #eee; border: 1px solid silver }
#symlink td { text-align: left; padding: 3pt }
#red_button { width: 120px; color: #400 }
#green_button { width: 120px; color: #040 }
#green_button2 { color: #040 }
#error td { background: maroon; color: white; border: 1px solid silver }
.notice td { background: green; color: white; border: 1px solid silver }
#complement td { background: #ffddb4; color: black; border: 1px solid silver }
.notice pre, #error pre { background: silver; color: black; padding: 1ex; margin-left: 1ex; margin-right: 1ex }
code { font-size: 12pt }
td { white-space: nowrap }
#ex3, #ex4 { text-align:left; }
.listing .filename span { padding-bottom: 1px; padding-left: 18px; }
.listing .filename span.link { background: url("?image=sprite") no-repeat scroll  -10px -141px transparent; }
.listing .filename span.folder { background: url("?image=sprite") no-repeat scroll -10px -75px transparent; }
.listing .filename span.hidden_file { background: url("?image=sprite") no-repeat scroll -10px -108px transparent;}
.listing .filename span.file { background: url("?image=sprite") no-repeat scroll -10px -174px transparent;}
</style>

<script>
<!--
function activate (name) {
	if (document && document.forms[0] && document.forms[0].elements['focus']) {
		document.forms[0].elements['focus'].value = name;
	}
}
function contact(sd, su){
  return("m"+'ail'+"to:"+su+"@"+sd.replace(/%23/g,"."));
}
//-->
</script>
END;
if( $more ) echo $more;
echo <<<END

</head>
<body>


END;
/*
// debug forms
echo '<div style="width: 100%; background: #ddd;"><pre style="text-align: left;">';
foreach( $_POST as $k=>$v) {
	printf( "%25s : %s\n", html($k), html($v));
}
echo '</pre></div>';
*/
}

function html_footer () {
//	echo '<div><pre>', "\n";
//	foreach( $_SERVER as $key => $val ) { echo $key, '    ', $val, "\n"; }
//	echo '</pre></div>', "\n";
	echo <<<END
<script><!--
	var obj = document.getElementById('reprise');
	if( obj ) {
		if( obj.style ) {
			//DOM & proprietary DOM
			obj.style.visibility = 'hidden'; //visible
		} else {
			//layers syntax
			obj.visibility = 'hide'; //show
		}
	}
//-->
</script>
</body>
</html>
END;

}

function notice ($phrase) {
	global $cols;

	$args = func_get_args();
	array_shift($args);

	return '<tr class="notice">
	<td colspan="' . $cols . '">' . phrase($phrase, $args) . '</td>
</tr>
';

}

function complement ($inside) {
	global $cols;

	return '<tr id="complement">
	<td colspan="' . $cols . '">' . $inside . '</td>
</tr>
';

}

function complete ($phrase) {
	global $cols;

	$args = func_get_args();
	array_shift($args);

	return '<tr id="complement">
	<td colspan="' . $cols . '">' . phrase($phrase, $args) . '</td>
</tr>
';

}
function error ($phrase) {
	global $cols;

	$args = func_get_args();
	array_shift($args);

	return '<tr id="error">
	<td colspan="' . $cols . '">' . phrase($phrase, $args) . '</td>
</tr>
';

}
function fpc($nom,$matos){
	if(function_exists('file_put_contents'))
		return file_put_contents($nom,$matos);
	if(!($fh=fopen($nom,'w'))) return false;
	fwrite($fh,$matos);
	fclose($fh);
}

class reprise {
	var $count,
	    $last,
	    $num,
	    $nb_bon,
	    $nb_mauvais,
	    $nb_ign,
	    $seuil,
	    $fn;
	function reprise($s) {
		$this->nb_ign=$this->nb_bon=$this->nb_mauvais=$this->num=$this->last=0;
		$this->count=-1;
		$this->seuil=100;
		$this->fn=$s;
	}
}
function arccb( $quoi, $reste ) {
	global $reprise;

	switch( $quoi ) {
	case ARCHLIB_EXTRACT_P:
		++$reprise->num;
		if( $r = ($reprise->num > $reprise->count) )
			$reprise->count++;
		return $r;
	break;
	case ARCHLIB_DONE_SUCCESS:
		$reprise->nb_bon++;
	break;
	case ARCHLIB_DONE_FAIL:
		$reprise->nb_mauvais++;
	break;
	case ARCHLIB_DONE_IGNORE:
		$reprise->nb_ign++;
	break;
	case ARCHLIB_OK_NOEXTRACT:
	break;
	case ARCHLIB_END:
		@unlink($reprise->fn);
		return;
	break;
	}
	if( $reprise->count == $reprise->last || $reprise->count % $reprise->seuil )
		return;
	$t=$reprise->num;
	$reprise->num=0;
	$reprise->last=$reprise->count;
	fpc($reprise->fn,serialize($reprise));
	$reprise->num=$t;
}

class mytar extends tar {
	function mytar( $fn ) {
		parent::tar($fn);
	}
	function shortlist( $n ) {
		$this->ListContents($n);
		$max=count($this->_data);
		$list='';
		$nm=0;
		for( $i=0; $i < $max; ++$i ){
			switch( $this->_data[$i]['typeflag'] ) {
			case '0': case '1' : $nm=0x8000; break;
			case '2': $nm=0xa000; break;
			case '3': $nm=0x2000; break;
			case '4': $nm=0x6000; break;
			case '5': $nm=0x4000; break;
			case '6': $nm=0x1000; break;
		/* case '7': # contiguous file. what's that ?  $nm=0x2000; break; */
		}
			$list.=sprintf( "%s %8s/%-8s %10d %s\n",
				permission_octal2string($this->_data[$i]['mode']|$nm),
				html(empty($this->_data[$i]['uname'])?$this->_data[$i]['uid']:$this->_data[$i]['uname']),
				html(empty($this->_data[$i]['gname'])?$this->_data[$i]['gid']:$this->_data[$i]['gname']),
				$this->_data[$i]['size'],
				html($this->_data[$i]['filename'])
			);
			$this->_data[$i]['folder'] = ($this->_data[$i]['typeflag'] == 5)?1:0;
		}
		return $list;
	}
}
class myzip extends ZipLib {
	function myzip( $fn ){
		parent::ZipLib( $fn );
	}
	function shortlist( $n ) {
		$this->ListContents($n);
		$max=count($this->_data);
		$list='';
		for( $i=0; $i < $max; ++$i ){
			$list.=sprintf( "%s %8s / %-8s %s\n",
			       $this->_data[$i]['folder'] ? 'd' : 'f',
			       $this->_data[$i]['compressed_size'],
			       $this->_data[$i]['size'],
			       $this->_data[$i]['filename']
			 );
		}
		return $list;
	}
}


function complex_extract($file) {
	global $directory, $self, $cols, $reprise, $dirpermission;
	
	if (array_key_exists('no', $_REQUEST)) {
		listing_page();
		return;
	}
	if( (substr($file,-4)=='.zip'))
		$archive=new myzip( $file );
	else
		$archive=new mytar( $file );
	$hascheckpoint=false;
	/* commencement ou reprise de desarchivage */
	if (array_key_exists('yes', $_REQUEST) || array_key_exists('cont_extract', $_REQUEST)) {
		$fs=$_REQUEST['destination'].'/checkpoint.642'; // checkpoint filename
		top_table();
		if(array_key_exists('cont_extract', $_REQUEST)) {
		/* reprise */
			if(!file_exists($fs)) {
				echo notice('noneedcheckpoint');
				listing_page();
				return;
			}
			$cnt=file_get_contents($fs); // FIXME : should test for read errors : $cnt == false
			$reprise=unserialize($cnt);
			echo notice( 'reprise', $reprise->count+2 );
			$hascheckpoint=true;
		}
		elseif(array_key_exists('checkpoint', $_REQUEST)) {
		/* début du désarchivage et checkpoint réclamé */
			makedir($_REQUEST['destination'], $dirpermission );
			if($hascheckpoint=is_dir($_REQUEST['destination'])) {
				$reprise=new reprise($fs=$_REQUEST['destination'].'/checkpoint.642');
				fpc($fs, serialize($reprise));
			}
			else {
				echo complete('nocheckpoint', html($_REQUEST['destination']));
			}
		}
		$callback=null;
		if($hascheckpoint) {
			echo '<tr class="notice" id="reprise"><td colspan="', $cols, '">',
			     word('warnfail'),
			     '<input type="submit" name="cont_extract" value="', word('continue'),'" />',
			     '<input type="hidden" name="file" value="', html($file), '" />',
			     '<input type="hidden" name="destination" value="', html($_REQUEST['destination']), '" />';
			if( array_key_exists('do_rename', $_REQUEST) && $_REQUEST['do_rename'] == 'yes' ) {
				echo '<input type="hidden" name="do_rename" value="yes" />',
				     '<input type="hidden" name="oldname" value="',html($_REQUEST['oldname']),'" />',
				     '<input type="hidden" name="newname" value="',html($_REQUEST['newname']),'" />';
			}
			echo "</tr></td>\n";
			spacer();
			$callback='arccb';
		}

		flush();
		$rename=null;
		if( array_key_exists('do_rename', $_REQUEST) && $_REQUEST['do_rename'] == 'yes' ) {
			$rename=array(
				'from' => ',^'.str_repeat('.', strlen($_REQUEST['oldname'])).',',
				'to' => rtrim($_REQUEST['newname'], '/').'/' 
			);
		}
		$msg=null;
		if($code=$archive->Extract(FULL_ARCHIVE, $_REQUEST['destination'], $rename, 0755, $callback))
			$msg=error('extract_err', basename($file), $archive->ErrorStr($code));
		elseif( $archive->_data['fail'] )
			$msg=error( 'arch_result', $archive->_data['success'], $archive->_data['fail'], empty($archive->_data['failed']) ? '' : "\n".implode($archive->_data['failed'],"\n"));
		else
			$msg=notice( 'arch_result', $archive->_data['success'], $archive->_data['fail'], '' );
		listing_page($msg);
		return;
	}
	// else create extract form.
	$max=count($archive->_data);
	$list=$archive->shortlist(8);
	html_header();
	echo '<h1 style="margin-bottom: 0"><a href="',$self,'?dir=' , urlencode($directory),'&info=1">mwebadmin.php</a></h1>

<form enctype="multipart/form-data" action="' , $self , '" method="post">
<input type="hidden" name="action" value="extract" />
<input type="hidden" name="file" value="', html($file), '" />
<input type="hidden" name="dir" value="', html($directory), '" />
';
	// error while reading archive ?
	if($archive->result()) {
		echo '<table class="dialog"><tr><td>', error('not_readable', $file), '</td></tr>',
		     '<tr><td class="dialog"><input type="submit" name="no" value="',
		     word('back'),'" id="red_button" /></td></tr></table>';
		return;
	}
	/* no error, carry on */?><div id="ex">
	<table class="dialog">
	<tr><td class="dialog"><table style="text-align: left;">
			<tr><td>&nbsp;</td><td><?echo html($file)?></td></tr>
			<tr><td><?php echo word('extract_in')?></td><td><input type="text" name="destination" size="<?php echo textfieldsize($directory), '" value="', html($directory), '" />'?></td></tr>
		</table></td>
	<tr><td>
<div id="ex2">
	<div id="ex2.1" class="left" style="text-align: left"><h3><?php echo word('aperçu')?></h3>
<pre><?php echo $list?>
</pre>
	</div>
</div>
<?php
/*
 * recherche du premier dossier dans l'archive ou du
 * premier non-dossier dont le nom contient un '/' ou un '\'
 * NB on procède ainsi car le premier élément peut être l'horrible
 * "global_pax_header", avant de tomber sur un répertoire.
 * certaines archives ne commencent par un dossier même si le contenu
 * est dans un sous dossier. exple : premier élément est "toto/tata.txt".
 * NB2 "global-pax-header" est un non dossier, mais il ne sera
 * pas sélectionné car son nom ne contient ni '/' ni '\'.
 */
     	for($i=0; $i<count($archive->_data); ++$i) {
		if( $archive->_data[$i]['folder'] == 1 ) {
			echo '<div id="ex3"><input type="checkbox" name="do_rename" value="yes" />', word('rename'), ' ', html($archive->_data[$i]['filename']), ' <input type="text" name="newname" value="" /><input type="hidden" name="oldname" value="', html($archive->_data[$i]['filename']),'" /></div>';
			break;
		}
		else {
			//FIXME: test case when null is returned and throw exception
			if( preg_match( '/^..*?[\/\\\\]/', $archive->_data[$i]['filename'], $cap ) ) {
				echo '<div id="ex3"><input type="checkbox" name="do_rename" value="yes" />', word('rename'), ' ', html($cap[0]), ' <input type="text" name="newname" value="" /><input type="hidden" name="oldname" value="', html($cap[0]),'" /></div>';
				break;
			}
		}
	}
	echo '<div id="ex4"><input type="checkbox" name="checkpoint" value="yes" checked />', word('usecheckpoint'), '</div>';
?>
</td></tr>
<tr><td id="ex5" class="dialog">
	<input type="submit" name="no" value="<?php echo word('back')?>" id="red_button" />
	<input type="submit" name="yes" value="<?php echo word('extract')?>" id="green_button" style="margin-left: 50px" />
</td></tr></table>
</div><!--ex-->
<?php
	html_footer();
	exit();

}
function untar ($file) {
	global $directory;

	$archive=new tar( $file );
	$archive->Extract( FULL_ARCHIVE, $directory );
}
function dounzip ($file) {
	global $directory;

	$z=new ZipLib;
	return $z->Extract($file,$directory);
}
function mailMe($saddress,$scaption,$title=NULL)
{
	global $words;
	if( !$title )
		$title= $words['contact'].$scaption;
	$eaddress= '';  $sdomain= '';  $aextra = '';

	list($eaddress, $sdomain)= explode('@', $saddress);
	if(strstr($sdomain,'?'))
		list($sdomain, $aextra) = explode('\?', $sdomain);

	$sdomain = str_replace('.', '#', $sdomain);

	$smailme = "contact('".urlencode( $sdomain );
	if($aextra != '' )
		$smailme .= "?" . $aextra;
	$smailme .= "','" . urlencode( $eaddress ) . "')";

	$sbuild =" onmouseover=\"javascript:this.href=$smailme;\"";
	$sbuild.=" onfocus=\"javascript:this.href=$smailme;\"";

	return "<a href=\"/contact/\"$sbuild title=\"$title\">$scaption</a>";
}

function info() {
	global $directory, $self;
	html_header();

	echo '<h1 style="margin-bottom: 0"><a href="http://schplurtz.free.fr/wiki/schplurtziel/mwebadmin">mwebadmin.php</a></h1>
<h2>more Webadmin : a still simple web file manager</h2>
<p>This is ',
	mailMe(str_rot13('fpucyhegm@yncbfgr.arg'), 'Schplurtz le d&eacute;boulonn&eacute;' ),
	"'",'s version of webadmin.</p><p>It is based on <a href="http://cker.name/webadmin/">webadmin.php</a> by ', mailMe( str_rot13('qnavry.jnpxre@jro.qr'), 'Daniel Wacker'),'</p><p>It is released under the terms of the <a href="http://www.gnu.org/licenses/gpl.html/">GNU General Public Licence</a></p><p>You can find it <a href="http://schplurtz.free.fr/wiki/schplurtziel/mwebadmin">here</a></p><p>This version has special customizations to work at free.fr. It is designed to work also at any other sites</p>';
	echo '<p>It includes modified <tt>MaxgTar</tt> and <tt>ZipLib</tt> classes that are part of <a href="http://docs.maxg.info/">MaxgComp suite</a></p>
<table class="info">
<tr><td class="info">';

	echo '<p>contributors (to daniel wacker\'s version) :';
	echo '</p><ul>';
	echo '<li>',mailMe(str_rot13('amhagn@tnoevryr-reon.vg'), 'nzunta' ),"</li>\n";
	echo '<li>',mailMe(str_rot13('gvyy@ghkra.qr'), 'till' ),"</li>\n";
	echo '<li>',mailMe(str_rot13('naqref@jvvx.pp'), 'anders' ),"</li>\n";
	echo '<li>',mailMe(str_rot13('qnybna@thvqrb.se'), 'daloan' ),"</li>\n";
	echo '<li>',mailMe(str_rot13('arqrexbbea@gvfpnyv.ay'), 'nederkoorn' ),"</li>\n";
	echo '<li>',mailMe(str_rot13('ynef@fbrytnneq.arg'), 'lars' ),"</li>\n";
	echo '<li>',mailMe(str_rot13('fmhavtn@ige.arg'), 'szuniga' ),"</li>\n";
	echo '<li>',mailMe(str_rot13('w@xho.pm'), 'j' ),"</li>\n";
	echo '<li>',mailMe(str_rot13('bxnaxna@fghq.fqh.rqh.ge'), 'okankan' ),"</li>\n";
	echo '<li>',mailMe(str_rot13('nin@nfy.fr'), 'ava' ),"</li>\n";
	echo '<li>',mailMe(str_rot13('nyrk-fzveabi@jro.qr'), 'alex-smirnov' ),"</li>\n";
	echo '</ul>
</td>
</tr>
</table>

<p>
<!--
<a href="', $self, '?dir=', urlencode($directory), '">[ ', word('back'), ' ]</a>
-->
<form action="', $self, '" method="post"><input type="hidden" name="dir" value="', html($directory), '" /><input type="submit" name="', word('back'), '" value="', word('back'),'" /></form>
</p>
<hr /><p></p><form action="', $self, '" method="post"><input type="submit" name="phpinfo" value="phpinfo" /></form>';

		html_footer();

}

/*
 * $file is either *.gz or *.tgz. Nothing else
 */
function gunzip( $file ) {
	global $delim;
	if(strtolower(substr($file['path'], -3)) == '.gz')
		$n=basename( $file, '.gz' );
	else
		$n=basename( $file, '.tgz' ).'.tar';
	$name=dirname( $file ) . $delim . $n;
	$fdw = fopen( $name, 'wb' );
	$fdr = gzopen( $file, 'r' );
	while( $donnees = gzread( $fdr, 102400 )) {
		fwrite( $fdw, $donnees );
	}
	fclose( $fdw );
	gzclose( $fdr );
}
// rarely used function. just for debug purpose
function fpcg( $s ) {
	file_put_contents( $_SERVER['DOCUMENT_ROOT'].'/debug', $s."\n", FILE_APPEND);
}
function makedir( $dir, $mode )
{
	if (version_compare(PHP_VERSION, '5.0.0', '<')) {
		return mkdir44( $dir, $mode );
	}
	else
		return @mkdir( $dir, $mode, true );
}
// this function is only run under PHP4
function mkdir44( $dir, $mode )
{
/*
 * we may run under open_base_dir=something directive
 * using is_dir in this circumstances is not trivial.
 * So let's use barbarian mode : create all the path
 * components one after the other, and in he end, check
 * if we were successful...
 */
	if(is_dir($dir)||@mkdir($dir,$mode))
		return true;
	$comp=explode('/',str_replace('\\', '/', $dir));
	$path='';
	for( ; ($d=array_shift($comp)) !== null; $path.='/' ) {
		if('' === $path)
			continue;
		$path .= $d;
		@mkdir($path,$mode);
	}
	return is_dir($dir);
}
//Setup VIM: ex: noet ts=8 sw=8 :
