Location: PHPKode > scripts > WebNight Commander > webnight-commander-v2/wnc.php
<?php

/**
 * Webnight Commander 2.0
 *
 * Webnight Commander is web file manager with interface similar to GNU
 * Midnight Commander. The main difference is that Webnight Commander have
 * only one directory panel. The whole program code is organized in one PHP
 * script. It allows to cut, copy, paste, delete, rename/move, copyTo,
 * moveTo, chDir, upload, newFile, newDir, newLink, selecting, view and
 * edit files.
 *
 * Webnight Commander 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.
 *
 * Webnight Commander 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 Webnight Commander; if not, write to
 *
 * Free Software Foundation, Inc.
 * 59 Temple Place, Suite 330
 * Boston, MA 02111-1307 USA
 *
 *   @package wnc
 *   @version 2.0
 *    @author Pavel Tzonkov <hide@address.com>
 * @copyright 2007-2010 Webnight Commander Project
 *   @license http://www.opensource.org/licenses/gpl-license.php GPL
 *      @link http://sourceforge.net/projects/wnc
 *
 */


/* BASE CONFIGURATION. Uncomment # comments only */

$config = array(

    // Browser charset
    'charset' => "ISO-8859-1",

    // Font family CSS propery. Fixed width fonts are recomended
    'font-family' => "Fixedsys, Terminus, Fixed, Lucida Console, Courier, Courier New",

    // Font size CSS property
    'font-size' => "14px",

    // Font weight CSS property (normal or bold)
    'font-weight' => "normal",

    // Rendered font resolution in pixels. Important for visual proportions
    'font_resolution' => "8x16",

    // Inactive user sessin lifetime (in minutes). If not set, default lifetime will be selected
    // To work properly, this setting needs 'session_dir' setting, pointed to clean directory
    # 'session_life' => 30,

    // Directory to store user sessions. If not set, default directory will be selected.
    # 'session_dir' => "/full/path/to/directory",

    // Base session variable
    'session_var' => "wnc"

);


/* USER ACCOUNTS. Uncomment # comments only */

$users = array();

//************* SAMPLE USER ACCOUNT - BEGIN
$users[] = array(

    // Username. REQUIRED!
    # 'username' => "user",

    // Password. REQUIRED! The password should be stored in its MD5 hash sum
    # 'password' => "1a1dc91c907325c69271ddf0c944bc72",

    // Default home directory. If not set, wnc.php directory will be selected
    # 'home' => "/path/to/user's/home/directory",

    // Allow access outside home directory. If not set - false
    # 'root' => true,
);
//************* SAMPLE USER ACCOUNT - END

// Repeat SAMPLE USER ACCOUNT section for more user accounts


class session {

    public $values;

    protected $sess_name;
    protected $stamp_name;

    public function __construct($sess_name="wnc", $lifetime=30, $stamp_name="stamp", $store_dir=null) {
        $this->sess_name = $sess_name;
        $this->stamp_name = $stamp_name;
        $lifetime *= 60;
        ini_set('session.gc_maxlifetime', $lifetime);
        if ($store_dir !== null)
            ini_set('session.save_path', $store_dir);
        $this->start();
    }

    public function start() {
        session_start();
        $stamp = @md5(
            $_SERVER['HTTP_ACCEPT_CHARSET'] .
            $_SERVER['HTTP_ACCEPT_ENCODING'] .
            preg_replace('/\d\.?/', "", $_SERVER['HTTP_USER_AGENT']) .
            $_SERVER['REMOTE_ADDR']
        );

        if (!isset($_SESSION [$this->sess_name] [$this->stamp_name] ))
            $_SESSION [$this->sess_name] [$this->stamp_name] = $stamp;

        elseif ($_SESSION [$this->sess_name] [$this->stamp_name] != $stamp) {
            $this->restart();
            return;
        }

        $this->values = &$_SESSION[$this->sess_name];
    }

    public function destroy() {
        session_destroy();
    }

    public function restart() {
        $this->destroy();
        $this->start();
    }

}


class gpc {
    protected $get;
    protected $post;
    protected $cookie;

    public function __construct() {
        $this->get = self::clear_slashes($_GET);
        $this->post = self::clear_slashes($_POST);
        $this->cookie = self::clear_slashes($_COOKIE);
    }

    public function get() {
        $args = func_get_args();
        return $this->get_source($this->get, $args);
    }

    public function post() {
        $args = func_get_args();
        return $this->get_source($this->post, $args);
    }

    public function cookie() {
        $args = func_get_args();
        return $this->get_source($this->cookie, $args);
    }

    protected function get_source($src, $args) {
        foreach ($args as $arg)
            if (isset($src[$arg]))
                $src = $src[$arg];
            else
                return null;
        return $src;
    }

    static function clear_slashes($sbj) {
        if (ini_get('magic_quotes_gpc')) {
            if (is_array($sbj))
                foreach ($sbj as $key => $val)
                    $sbj[$key] = self::clear_slashes($val);
            elseif (is_scalar($sbj))
                $sbj = stripslashes($sbj);
        }
        return $sbj;
    }

}


class dir {

    protected $full_path;
    protected $is_readable;
    protected $is_writable;
    protected $is_executable;
    protected $size = 0;
    protected $modified;
    protected $content = array();

    public function __get($property) {
        if (property_exists($this, $property)) {
            eval("\$return = \$this->$property;");
            return $return;
        } else
            return;
    }

    public function __construct($path) {

        $this->full_path = $path;
        $this->is_readable = is_readable($path);
        $this->is_writable = is_writable($path);
        $this->is_executable = is_executable($path);
        $this->modified = @filectime($path);
        $this->size = 0;

        if ($this->is_readable && $this->is_executable) {
            $dir = getcwd();
            chdir($path);
            $this->full_path = $path = getcwd();
            chdir($dir);

            $this->is_readable = is_readable($path);
            $this->is_writable = is_writable($path);
            $this->is_executable = is_executable($path);
            $this->modified = filectime($path);

            $files = $dirs = array();

            foreach (glob("$path/*") as $item) {
                $element = $this->get_file_info($item);
                if (($element['type'] == "l") && (trim(`whoami`) == $element['owner']))
                    $element['readable'] = $element['writable'] = 1;
                if (($element['type'] == "d") ||
                    (($element['type'] == "l") && ($element['target_info']['type'] == "d"))
                )
                    $dirs[$element['name']] = $element;
                else {
                    $files[$element['name']] = $element;
                    $this->size += $element['size'];
                }
            }

            ksort($dirs);
            ksort($files);

            $parent = $this->get_file_info(dirname($path));
            $parent['name'] = "..";
            $this->content = array_values(array($parent) + $dirs + $files);
        }
    }

    public function search_hash($hash) {
        foreach ($this->content as $i => $item)
            if ($hash == $item['hash'])
                return $i;
        return false;
    }

    public function refresh() {
        $this->__construct($this->full_path);
    }

    public function rrmdir($path) {
        if (preg_match('/^\d+$/', $path)) {
            if (!$path || !isset($this->content[$path]) || ($this->content[$path]['type'] != "d"))
                return false;

            $path = $this->full_path . "/" . $this->content[$path]['name'];

        } elseif (!is_dir($path))
            return false;

        $files = glob("$path/*");
        if ($files === false)
            return false;

        foreach ($files as $file)
            if (is_dir($file)) {
                if (!$this->rrmdir($file))
                    return false;
            } elseif (!@unlink($file))
                return false;

        return @rmdir($path);
    }

    protected function get_file_info($filename) {
        $info = array(
            'name' => basename($filename),
            'size' => filesize($filename),
            'modified' => filectime($filename),
            'readable' => is_readable($filename),
            'writable' => is_writable($filename),
            'executable' => is_executable($filename),
            'perms' => self::get_perms($filename),
            'owner' => self::get_owner($filename),
            'group' => self::get_group($filename),
            'hash' => md5(basename($filename))
        );
        $info['type'] = substr($info['perms'], 0, 1);

        if (is_link($filename) && ($info['type'] != "l")) { // Wrong Link Stat
            $info['type'] = "l";
            $info['perms'] = "lrwxr-xr-x";
            $shellname = str_replace('"', "\\\"", $filename);
            $stat = trim(`stat "$shellname"`);

            // Linux stat
            $regex = '/access\:[^\d]*\d{4}\/([a-z\-]{10,}).*uid\:\s*\(?\s*\d*\s*\/?\s*([^\)]+).*gid\:\s*\(?\s*\d*\s*\/?\s*([^\)]+)/i';
            if (preg_match($regex, $stat, $patt)) {
                $info['perms'] = $patt[1];
                $info['owner'] = $patt[2];
                $info['group'] = $patt[3];

            // BSD stat
            } else {
                $regex = '/^\d+\s+\d+\s+([a-z\-]{10,})\s+\d+\s+([a-z\-]+)\s+([a-z\-]+).*$/';
                if (preg_match($regex, $stat, $patt)) {
                    $info['perms'] = $patt[1];
                    $info['owner'] = $patt[2];
                    $info['group'] = $patt[3];
                }
            }

            $target = self::resolve_link($filename);
            $info['target'] = $target;
            $info['target_info'] = $this->get_file_info($target);
        }

        if (($info['type'] == "d") || ($info['type'] == "l"))
            $info['size'] = 0;

        return $info;
    }

    static function rcopy($src, $dst) {

        if (is_dir($src)) {
            if (file_exists($dst))
                return "File \"$dst\" already exists!";
            if (!@mkdir($dst))
                return "Cannot create \"$dst\" directory!";
            $items = glob("$src/*");
            if ($items === false)
                return "Cannot access \"$src\" directory";
            $return = "";
            foreach ($items as $item) {
                $res = self::rcopy($item, "$dst/" . basename($item));
                if ($res !== true)
                    $return .= "<br />$res";
            }
        } elseif (file_exists($dst))
            return "File \"$dst\" already exists!";
        elseif (!@copy($src, $dst))
            return "Error copying \"$src\" file";

        return (isset($return) && strlen($return))
            ? substr($return, 6)
            : true;
    }

    static function resolve_link($filename) {
        $target = $filename;

        do {
            $link = readlink($target);

            if ($link == ".")
                $link = dirname($target);
            elseif ($link == "..")
                $link = dirname(dirname($target));
            elseif (substr($link, 0, 2) == "./")
                $link = dirname($target) . substr($link, 1);
            elseif (substr($link, 0, 3) == "../")
                $link = dirname(dirname($target)) . substr($link, 2);
            elseif (substr($link, 0, 1) != "/")
                $link = dirname($target) . ((dirname($target) == "/") ? "" : "/") . $link;

            $target = $link;
        } while (is_link($link));

        return $link;
    }

    static function get_perms($filename) {
        $prm = fileperms($filename);

        if (($prm & 0xC000) == 0xC000)      // Socket
            $perms = 's';
        elseif (($prm & 0xA000) == 0xA000)  // Symbolic Link
            $perms = 'l';
        elseif (($prm & 0x8000) == 0x8000)  // Regular
            $perms = '-';
        elseif (($prm & 0x6000) == 0x6000)  // Block special
            $perms = 'b';
        elseif (($prm & 0x4000) == 0x4000)  // Directory
            $perms = 'd';
        elseif (($prm & 0x2000) == 0x2000)  // Character special
            $perms = 'c';
        elseif (($prm & 0x1000) == 0x1000)  // FIFO pipe
            $perms = 'p';
        else                                // Unknown
            $perms = 'u';

        // Owner
        $perms .= ($prm & 0x0100) ? 'r' : '-';
        $perms .= ($prm & 0x0080) ? 'w' : '-';
        $perms .= ($prm & 0x0040)
            ? (($prm & 0x0800) ? 's' : 'x')
            : (($prm & 0x0800) ? 'S' : '-');

        // Group
        $perms .= ($prm & 0x0020) ? 'r' : '-';
        $perms .= ($prm & 0x0010) ? 'w' : '-';
        $perms .= ($prm & 0x0008)
            ? (($prm & 0x0400) ? 's' : 'x')
            : (($prm & 0x0400) ? 'S' : '-');

        // World
        $perms .= ($prm & 0x0004) ? 'r' : '-';
        $perms .= ($prm & 0x0002) ? 'w' : '-';
        $perms .= ($prm & 0x0001)
            ? (($prm & 0x0200) ? 't' : 'x')
            : (($prm & 0x0200) ? 'T' : '-');

        return $perms;
    }

    static function get_owner($filename) {
        $pwuid = posix_getpwuid(fileowner($filename));
        return $pwuid['name'];
    }

    static function get_group($filename) {
        $grgid = posix_getgrgid(filegroup($filename));
        return $grgid['name'];
    }

    static function human_size($size) {
        if ($size < 1024) {
            $size = "$size";
        } elseif (($size < 1048576)) {
            $size /= 1024;
            $size = intval($size) . "K";
        } elseif ($size < 1073741824) {
            $size /= 1048576;
            $size = intval($size) . "M";
        } elseif ($size < 1099511627776) {
            $size /= 1073741824;
            $size = intval($size) . "G";
        } else {
            $size /= 1099511627776;
            $size = intval($size) . "T";
        }
        return $size;
    }

}


class controller {
    protected $config = array();
    protected $users = array();
    protected $session;
    protected $sess = array();
    protected $get = array();
    protected $post = array();
    protected $cookie;
    protected $me = false;

    public function __construct() {
        $gpc = new gpc();
        $this->get = $gpc->get();
        $this->post = $gpc->post();
        $this->cookie = $gpc->cookie();
        $this->session = &$GLOBALS['session'];
        $this->sess = &$this->session->values;
        $this->config = &$GLOBALS['config'];
        $this->users = &$GLOBALS['users'];
        if (isset($this->sess['me']))
            $this->me = &$this->sess['me'];
    }

    public function action() {
        if (isset($this->post['act'])) {
            if (!$this->me) die($this->act_init());

            $act = $this->post['act'];
            $method = "act_$act";

            if ($act == "upload")
                $this->$method();

            elseif (method_exists($this, $method)) {
                $content = (!isset($this->sess['dir']) && ($act != "init") && ($act != "login"))
                    ? $this->act_init()
                    : $this->$method();
                if (isset($this->sess['error']))
                unset($this->sess['error']);
                die($content);
            }


        } elseif (
            $this->me &&
            isset($this->sess['dir']) &&
            isset($this->get['act']) &&
            ($this->get['act'] == "download")
        )
            $this->act_download();
    }

    protected function act_init() {
        if (!$this->me) return $this->act_login();
        if (!isset($this->sess['dir'])) {
            if (isset($this->me['home']) && strlen($this->me['home'])) {
                if (!is_dir($this->me['home'])) {
                    $this->session->restart();
                    return html::login() . html::error("Invalid home directory!");
                }
                $this->sess['dir'] = $this->me['home'];
            } else
                $this->sess['dir'] = getcwd();
        }

        $this->check_dir_access();

        return html::dir($this->sess['dir']);
    }

    protected function act_login() {
        if ($this->me) return $this->act_init();
        if (!isset($this->post['login']) && !isset($this->post['pass']))
            return html::login();
        if (!isset($this->post['login']) || !isset($this->post['pass']))
            return html::login(true);

        foreach ($this->users as $user)
            if (($this->post['login'] == $user['username']) &&
                (md5($this->post['pass']) == $user['password'])
            ) {
                if (!isset($user['home']))
                    $user['home'] = getcwd();
                $this->sess['me'] = $user;
                $this->me = &$this->sess['me'];
                return $this->act_init();
            }

        return html::login(true);
    }

    protected function act_logout() {
        $this->session->restart();
        $this->me = false;
        return html::login();
    }

    protected function act_chdir() {
        $dir = new dir($this->sess['dir']);
        $dirname = $dir->full_path;
        $content = $dir->content;

        // Listed directory click
        if (isset($this->post['item']) &&
            isset($content[$this->post['item']]) &&
            (false !== ($item = $content[$this->post['item']])) && (
                ($item['type'] == "d") || (
                    ($item['type'] == "l") &&
                    ($item['target_info']['type'] == "d")
                )
            )
        )
            $target = ($item['name'] == "..") ? dirname($dirname) : "$dirname/{$item['name']}";

        // Location click
        if (isset($this->post['loc']) &&
            (false !== ($dirs = explode("/", $dir->full_path))) &&
            isset($dirs[$this->post['loc']])
        ) {
            if ($this->post['loc'] == "0")
                $target = "/";
            else {
                $target = "";
                for ($i = 1; $i <= $this->post['loc']; $i++)
                    $target .= "/" . $dirs[$i];
            }
        }

        // Dialog box
        if (isset($this->post['dir'])) {
            $selected = trim(str_replace("//", "/", $this->post['dir']));
            if (($selected == "..") || ($selected == "../"))
                $target = dirname($dirname);
            elseif (substr($selected, 0, 1) == "/")
                $target = $selected;
            else
                $target = "$dirname/$selected";
        }


        if (isset($target)) {
            $chdir = new dir($target);
            if ($chdir->is_readable && $chdir->is_executable) {
                $this->sess['dir'] = $chdir->full_path;
                if ($this->check_dir_access($dir->full_path))
                    $dir = $chdir;
            } else
                $this->sess['error'] = "Cannot access \"{$chdir->full_path}\"!";
        }

        return html::dir($dir);
    }

    protected function act_touch() {
        if (isset($this->post['file']) && isset($this->post['perms'])) {
            $filename = $this->sess['dir'] . "/" . $this->post['file'];
            if (preg_match('/\//', $this->post['file']))
                $this->sess['error'] = "Inorrect filename!";
            elseif (!preg_match('/^[0-7]{3}$/', $this->post['perms']))
                $this->sess['error'] = "Incorrect permissions!";
            elseif (file_exists($filename))
                $this->sess['error'] = "File {$this->post['file']} already exists!";
            elseif (!touch($filename))
                $this->sess['error'] = "Cannot create file \"{$this->post['file']}\"!";
            elseif (!chmod($filename, octdec($this->post['perms'])))
                $this->sess['error'] = "Cannot set file permissions!";
        }
        return html::dir($this->sess['dir']);
    }

    protected function act_mkdir() {
        if (isset($this->post['dir']) && isset($this->post['perms'])) {
            $filename = $this->sess['dir'] . "/" . $this->post['dir'];
            if (preg_match('/\//', $this->post['dir']))
                $this->sess['error'] = "Inorrect directory name!";
            elseif (!preg_match('/^[0-7]{3}$/', $this->post['perms']))
                $this->sess['error'] = "Incorrect permissions!";
            elseif (file_exists($filename))
                $this->sess['error'] = "File {$this->post['dir']} already exists!";
            elseif (!mkdir($filename, octdec($this->post['perms'])))
                $this->sess['error'] = "Cannot create directory \"{$this->post['dir']}\"!";
            elseif (!chmod($filename, octdec($this->post['perms'])))
                $this->sess['error'] = "Cannot set directory permissions!";
        }
        return html::dir($this->sess['dir']);
    }

    protected function act_mklnk() {
        if (isset($this->post['target']) && isset($this->post['file'])) {
            $filename = $this->sess['dir'] . "/" . $this->post['file'];
            if (preg_match('/\//', $this->post['file']))
                $this->sess['error'] = "Inorrect filename!";
            elseif (file_exists($filename))
                $this->sess['error'] = "File \"{$this->post['file']}\" already exists!";
            elseif (!file_exists($this->post['target']) &&
                !file_exists($this->sess['dir'] . "/" . $this->post['target'])
            )
                $this->sess['error'] = "File \"{$this->post['target']}\" not exists!";
            elseif (!symlink($this->post['target'], $filename))
                $this->sess['error'] = "Canot create the symbolic link!";
        }
        return html::dir($this->sess['dir']);
    }

    protected function act_upload() {
        if (isset($_FILES['file']) && ($_FILES['file']['error'] == UPLOAD_ERR_OK)) {
            $file = $_FILES['file'];
            $filename = $this->sess['dir'] . "/" . $file['name'];
            if (file_exists($filename))
                $this->sess['error'] = "File \"{$file['name']}\" already exists!";
            elseif (!move_uploaded_file($file['tmp_name'], $filename)) {
                @unlink($_FILES['file']['tmp_name']);
                $this->sess['error'] = "Cannot upload file in current directory!";
            }
        } else {
            @unlink($_FILES['file']['tmp_name']);
            $this->sess['error'] = "Error occured uploading file!";
        }
    }

    protected function act_download() {
        $dir = new dir($this->sess['dir']);

        if (!isset($this->get['file']) || !isset($this->get['hash']))
            $this->sess['error'] = "Something is wrong!";

        else {
            $file = $this->get['file'];
            $hash = $this->get['hash'];

            if ((!isset($dir->content[$file]) || ($hash != $dir->content[$file]['hash'])) &&
                (false === ($file = $dir->search_hash($hash)))
            )
                $this->sess['error'] = "File not found!";

            else {
                $item = $dir->content[$file];
                $filename = "{$dir->full_path}/{$item['name']}";
                header("Pragma: public");
                header("Expires: 0");
                header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
                header("Cache-Control: private", false);
                header("Content-Type: application/octet-stream");
                header("Content-Disposition: attachment; filename={$item['name']}");
                header("Content-Transfer-Encoding:­ binary");
                header("Content-Length: " . filesize($filename));
                readfile($filename);
                die;
            }
        }
    }

    protected function act_rm() {
        $dir = new dir($this->sess['dir']);
        $index = $this->get_file($dir);
        if (!isset($dir->content[$index]))
            $this->sess['error'] = $index;
        else {
            $this->rm($dir, $index);
            $dir->refresh();
        }
        return html::dir($dir);
    }

    protected function act_chmod() {
        $dir = new dir($this->sess['dir']);
        if (isset($this->post['perms']) && preg_match('/^[0-7]{3}$/', $this->post['perms'])) {
            $index = $this->get_file($dir);
            if (!isset($dir->content[$index]))
                $this->sess['error'] = $index;
            else {
                $item = $dir->content[$index];
                if (!chmod($dir->full_path . "/" . $item['name'], octdec($this->post['perms'])))
                    $this->sess['error'] = "Cannot change file permissions!";
                else
                    $dir->refresh();
            }
        } else
            $this->sess['error'] = "Cannot change file permissions!";

        return html::dir($dir);
    }

    protected function act_cp() {
        $dir = new dir($this->sess['dir']);
        if (isset($this->post['dest'])) {
            $index = $this->get_file($dir);
            if (!isset($dir->content[$index]))
                $this->sess['error'] = $index;
            else {
                $this->cp($dir, $index, $this->post['dest']);
                $dir->refresh();
            }
        }
        return html::dir($dir);
    }

    protected function act_mv() {
        $dir = new dir($this->sess['dir']);
        if (isset($this->post['dest'])) {
            $index = $this->get_file($dir);
            if (!isset($dir->content[$index]))
                $this->sess['error'] = $index;
            else {
                $this->mv($dir, $index, $this->post['dest']);
                $dir->refresh();
            }
        }
        return html::dir($dir);
    }

    protected function act_cut() {
        $dir = new dir($this->sess['dir']);
        $index = $this->get_file($dir);
        if (!isset($dir->content[$index]))
            $this->sess['error'] = $index;
        else {
            $item = $dir->content[$index];
            $this->sess['clipboard'] = array(
                'action' => "cut",
                'files' => array("{$dir->full_path}/{$item['name']}")
            );
        }
        return html::dir($dir);
    }

    protected function act_copy() {
        $dir = new dir($this->sess['dir']);
        $index = $this->get_file($dir);
        if (!isset($dir->content[$index]))
            $this->sess['error'] = $index;
        else {
            $item = $dir->content[$index];
            $this->sess['clipboard'] = array(
                'action' => "copy",
                'files' => array("{$dir->full_path}/{$item['name']}")
            );
        }
        return html::dir($dir);
    }

    protected function act_paste() {
        $dir = new dir($this->sess['dir']);
        if (isset($this->sess['clipboard'])) {
            $error = "";
            foreach ($this->sess['clipboard']['files'] as $i => $file) {
                $basename = basename($file);
                $dest = "{$dir->full_path}/$basename";
                if (($this->sess['clipboard']['action'] == "cut") && !rename($file, $dest))
                    $error .= "<br />Error moving \"$file\"!";
                elseif ($this->sess['clipboard']['action'] == "copy") {
                    $result = dir::rcopy($file, $dest);
                    if ($result !== true)
                        $error .= "<br />$result";
                }
            }

            if (strlen($error))
                $this->sess['error'] = substr($error, 6);

            unset($this->sess['clipboard']);
            $dir->refresh();
        }
        return html::dir($dir);
    }

    protected function act_edit() {
        $dir = new dir($this->sess['dir']);
        $index = $this->get_file($dir);
        if (!isset($dir->content[$index]))
            $this->sess['error'] = $index;

        elseif (isset($this->post['content'])) {
            $filename = $dir->full_path . "/" . $dir->content[$index]['name'];
            if (!@file_put_contents($filename, $this->post['content']))
                $this->sess['error'] = "Cannot write \"{$dir->content[$index]['name']}\"!";
            if (isset($this->post['quit']) && $this->post['quit'])
                $dir->refresh();
            else
                return html::editor($dir, $index);

        } elseif (!$dir->content[$index]['readable'] || !$dir->content[$index]['writable'])
            $this->sess['error'] = "Cannot access \"{$this->content[$index]['name']}\"!";
        else
            return html::editor($dir, $index);
        return html::dir($dir);
    }

    protected function act_view() {
        $dir = new dir($this->sess['dir']);
        $index = $this->get_file($dir);
        if (!isset($dir->content[$index]))
            $this->sess['error'] = $index;

        elseif (!$dir->content[$index]['readable'])
            $this->sess['error'] = "Cannot access \"{$this->content[$index]['name']}\"!";
        else
            return html::viewer($dir, $index);
        return html::dir($dir);
    }

    protected function act_sel_cut() {
        $dir = new dir($this->sess['dir']);
        list($selected, $notfound) = $this->get_selected($dir);
        if (!count($selected) || $notfound)
            $this->sess['error'] = "File(s) not found!";

        if (count($selected)) {
            $content = $dir->content;
            $path = $dir->full_path;

            $this->sess['clipboard'] = array(
                'action' => "cut",
                'files' => array()
            );

            foreach ($selected as $index)
                $this->sess['clipboard']['files'][] = "$path/{$content[$index]['name']}";
        }

        return html::dir($dir);
    }

    protected function act_sel_copy() {
        $dir = new dir($this->sess['dir']);
        list($selected, $notfound) = $this->get_selected($dir);
        if (!count($selected) || $notfound)
            $this->sess['error'] = "File(s) not found!";

        if (count($selected)) {
            $content = $dir->content;
            $path = $dir->full_path;

            $this->sess['clipboard'] = array(
                'action' => "copy",
                'files' => array()
            );

            foreach ($selected as $index)
                $this->sess['clipboard']['files'][] = "$path/{$content[$index]['name']}";
        }

        return html::dir($dir);
    }

    protected function act_sel_cp() {
        $dir = new dir($this->sess['dir']);

        if (isset($this->post['dest'])) {
            list($selected, $notfound) = $this->get_selected($dir);
            $errors = (!count($selected) || $notfound)
                ? "<br />File(s) not found!" : "";

            if (count($selected)) {
                $content = $dir->content;
                $path = $dir->full_path;
                foreach ($selected as $index) {
                    $this->cp($dir, $index, $this->post['dest']);
                    if (isset($this->sess['error'])) {
                        $errors .= "<br />{$this->sess['error']}";
                        unset($this->sess['error']);
                    }
                }
                $dir->refresh();
            }

            if (strlen($errors))
                $this->sess['error'] = substr($errors, 6);
        }
        return html::dir($dir);
    }

    protected function act_sel_mv() {
        $dir = new dir($this->sess['dir']);

        if (isset($this->post['dest'])) {
            list($selected, $notfound) = $this->get_selected($dir);
            $errors = (!count($selected) || $notfound)
                ? "<br />File(s) not found!" : "";

            if (count($selected)) {
                $content = $dir->content;
                $path = $dir->full_path;
                foreach ($selected as $index) {
                    $this->mv($dir, $index, $this->post['dest']);
                    if (isset($this->sess['error'])) {
                        $errors .= "<br />{$this->sess['error']}";
                        unset($this->sess['error']);
                    }
                }
                $dir->refresh();
            }

            if (strlen($errors))
                $this->sess['error'] = substr($errors, 6);
        }
        return html::dir($dir);
    }

    protected function act_sel_chmod() {
        $dir = new dir($this->sess['dir']);
        list($selected, $notfound) = $this->get_selected($dir);
        if (!count($selected) || $notfound)
            $this->sess['error'] = "File(s) not found!";

        if (count($selected)) {
            $content = $dir->content;
            $path = $dir->full_path;
            $errors = "";

            foreach ($selected as $index)
                if (!@chmod("$path/{$content[$index]['name']}", octdec($this->post['perms'])))
                    $errors .= "Cannot change permissions of \"{$content[$index]['name']}\"!<br />";

            if (strlen($errors)) {
                $errors = substr($errors, 0, -6);

                if (isset($this->sess['error']))
                    $this->sess['error'] .= "<br />$errors";
                else
                    $this->sess['error'] = "$errors";
            }

            $dir->refresh();
        }

        return html::dir($dir);
    }

    protected function act_sel_rm() {
        $dir = new dir($this->sess['dir']);
        list($selected, $notfound) = $this->get_selected($dir);
        $errors = (!count($selected) || $notfound)
            ? "<br />File(s) not found!" : "";

        if (count($selected)) {
            foreach ($selected as $index) {
                $this->rm($dir, $index);
                if (isset($this->sess['error'])) {
                    $errors .= "<br />{$this->sess['error']}";
                    unset($this->sess['error']);
                }
            }
            $dir->refresh();
        }

        if (strlen($errors))
                $this->sess['error'] = substr($errors, 6);

        return html::dir($dir);
    }

    protected function get_selected(dir $dir) {
        $content = $dir->content;

        if (!isset($this->post['hash']) ||
            !isset($this->post['file']) ||
            !is_array($this->post['hash']) ||
            !is_array($this->post['file']) ||
            (count($this->post['hash']) != count($this->post['file']))
        )
            return array(array(), true);

        $files = $this->post['file'];
        $hashs = $this->post['hash'];

        $notfound = false;
        for ($i = 0; $i < count($files); $i++)
            if (!isset($content[$files[$i]]) || ($content[$files[$i]]['hash'] != $hashs[$i]))
                if (false === ($files[$i] = $dir->search_hash($hashs[$i]))) {
                    unset($files[$i]);
                    $notfound = true;
                }

        $files = array_values($files);

        return array($files, $notfound);
    }

    protected function get_file(dir $dir) {
        if (!isset($this->post['hash']))
            return "File not found!";

        if (!isset($this->post['file']))
            $this->post['file'] = $dir->search_hash($this->post['hash']);

        $items = $dir->content;
        if (!$this->post['file'] ||
            !isset($items[$this->post['file']]) ||
            (
                ($items[$this->post['file']]['hash'] != $this->post['hash']) &&
                (false !== ($this->post['file'] = $dir->search_hash($this->post['hash'])))
            )
        )
            return "File not found!";

        return $this->post['file'];
    }

    protected function check_dir_access($dir_path=null) {
        if ($dir_path === null) $dir_path = $this->me['home'];
        if ((!isset($this->me['root']) || !$this->me['root']) &&
            ($this->me['home'] != substr($this->sess['dir'], 0, strlen($this->me['home'])))
        ) {
            $this->sess['dir'] = $dir_path;
            $this->sess['error'] = "You can browse files in your home directory only!";
            return false;
        }
        return true;
    }

    protected function cp(dir &$dir, $index, $dest) {
        $item = $dir->content[$index];
        $cwd = getcwd();
        chdir($dir->full_path);

        if (is_dir($dest))
            $dst = "$dest/{$item['name']}";

        else if (
            (dirname($dest) == ".") ||
            is_dir(dirname($dest))
        )
            $dst = $dest;
        else
            $this->sess['error'] = "Invalid destination!";

        if (isset($dst)) {
            $result = dir::rcopy($item['name'], $dst);
            if ($result !== true)
                $this->sess['error'] = $result;
        }

        chdir($cwd);
    }

    protected function mv(dir &$dir, $index, $dest) {
        $item = $dir->content[$index];
        $cwd = getcwd();
        chdir($dir->full_path);

        if (is_dir($dest))
            $dst = "$dest/{$item['name']}";

        else if (
            (dirname($dest) == ".") ||
            is_dir(dirname($dest))
        )
            $dst = $dest;
        else
            $this->sess['error'] = "Invalid destination!";

        if (isset($dst) && !@rename($item['name'], $dst))
            $this->sess['error'] = "Error occured moving \"{$item['name']}\"!";

        chdir($cwd);
    }

    protected function rm(dir &$dir, $index) {
        $item = $dir->content[$index];
        if (($item['type'] == "d") && !$dir->rrmdir($index))
            $this->sess['error'] = "Error occured deleting directory \"{$item['name']}\"!";
        elseif (($item['type'] != "d") && !unlink($dir->full_path . "/" . $item['name']))
            $this->sess['error'] = "Error occured deleting file \"{$item['name']}\"!";
    }

}


class html {

    static function login($error=false) {
        ob_start();

        self::inject_ajax_js("
document.onkeypress = function(e) {
    var e = window.event || e;

    if (e.keyCode == 27) {
        ajax.close_error();
        $('login').elements[1].focus();
    }
};
document.title='Webnight Commander: Login';
$('login').elements[1].focus();");

        if ($error)
            self::error("Incorrect login!");

?><div id="error"></div>
<center>
<div id="dialog" style="display:inline; margin-top:<?= $GLOBALS['h'] ?>px">
<table align="center"><tr><td>
<fieldset>
<legend>Webnight Commander</legend>
<div>
<form id="login" method="post" action="wnc.php" onsubmit="ajax.submit_form(this, 'container'); return false">
<input type="hidden" name="act" value="login" />
<table class="form">
<tr>
<th valign="top">Login:</th>
<td valign="top"><input type="text" name="login" /></td>
</tr>
<tr>
<td colspan="2">&nbsp;</td>
</tr>
<tr>
<th>Password:</th>
<td><input type="password" name="pass" /></td>
</tr>
<tr>
<td colspan="2">&nbsp;</td>
</tr>
<tr>
<th></th>
<td valign="bottom"><a class="button" onclick="ajax.submit_form('login', 'container')">[ Login ]</a><input type="submit" class="hidden" /></td>
</tr>
</table>
</form>
</div>
</fieldset>
</td></tr></table>
</div>
</center><?php

        return self::compress_html(ob_get_clean());
    }

    static function dir($dir) {
        ob_start();

        if (!($dir instanceof dir)) $dir = new dir($dir);

        self::inject_ajax_js("
document.onkeypress = function(e) {
    var e = window.event || e;

    if ((e.keyCode == 27) || (e.keyCode == '13'))
        ajax.close_error();

    if (e.keyCode == 27)
        ajax.close_dialog();
};
document.title='wnc: " . $dir->full_path . "';");

        $sess = $GLOBALS['session']->values;
        if (isset($sess['error']))
            self::error($sess['error']);

        self::js_dir($dir);

?><div id="dialog"></div>
<div id="error"></div>
<table align="center">
<tr><td>
<div class="topic">
<table>
<tr class="title">
<td><a href="http://sourceforge.net/projects/wnc" target="_blank">WEBNIGHT COMMANDER</a><span id="loading"></span></td>
<th>version 2.0</th>
</tr>
<tr>
<td><a class="button" onclick="ajax.post('wnc.php', 'act=chdir&loc=0', 'container')">/</a><?php

        $dirs = explode("/", $dir->full_path);
        foreach ($dirs as $i => $cdir)
            if ($i) {

?><a class="button" onclick="ajax.post('wnc.php', 'act=chdir&loc=<?= $i ?>', 'container')"><?= $cdir . (($i < count($dirs) - 1) ? "/" : "") ?></a><?php

            }

?></td>
<th><a class="button" onclick="ajax.post('wnc.php', 'act=logout', 'container')">Logout</a></th>
</table>
</div>
<table class="list"><tr><td>
<table>
</tr>
<tr>
<th><div class="checkbox" onclick="directory.select_all(this)">[ ]</div></th>
<th width="232">Name</th>
<th>Owner</th>
<th>Group</th>
<th>Permission</th>
<th>Size</th>
<th id="th_mtime">Modified time</th>
<th>Act</th>
</tr><?php

        $items = $dir->content;
        foreach ($items as $i => $item) {
            $tr_class = "";

            // Regular directory
            if ($item['type'] == "d") {
                $tr_class = "dir";
                $size = '<div style="text-align:center">&lt;dir&gt;</div>';
                $name = '<a onclick="ajax.post(\'wnc.php\', \'act=chdir&item='.$i.'\', \'container\')">/'.$item['name'].'</a>';

            // Linked directory
            } elseif (($item['type'] == "l") && ($item['target_info']['type'] == "d")) {
                $tr_class = "dir";
                $size = '<div style="text-align:center" title="' . html::html_value($item['target']) . '">&lt;link&gt;</div>';
                $name = '<a onclick="ajax.post(\'wnc.php\', \'act=chdir&item='.$i.'\', \'container\')">~'.$item['name'].'</a>';

            // Linked file
            } elseif ($item['type'] == "l") {
                $size = '<div style="text-align:center" title="' . html::html_value($item['target']) . '">&lt;link&gt;</div>';
                $name = "<div onclick=\"directory.select($i)\">@{$item['name']}</div>";

            // Character special
            } elseif ($item['type'] == "c") {
                $tr_class = "char";
                $size = '<div style="text-align:center">&lt;char&gt;</div>';
                $name = "<div onclick=\"directory.select($i)\">-{$item['name']}</div>";

            // Block
            } elseif ($item['type'] == "b") {
                $tr_class = "block";
                $size = '<div style="text-align:center">&lt;block&gt;</div>';
                $name = "<div onclick=\"directory.select($i)\">+{$item['name']}</div>";

            // Pipe
            } elseif ($item['type'] == "p") {
                $tr_class = "pipe";
                $size = '<div style="text-align:center">&lt;pipe&gt;</div>';
                $name = "<div onclick=\"directory.select($i)\">={$item['name']}</div>";

            // Socket
            } elseif ($item['type'] == "s") {
                $tr_class = "socket";
                $size = '<div style="text-align:center">&lt;sock&gt;</div>';
                $name = "<div onclick=\"directory.select($i)\">={$item['name']}</div>";

            // Executible file
            } elseif ($item['executable']) {
                $tr_class = "exec";
                $size = '<div style="text-align:right" title="' . $item['size'] . ' bytes">' . $dir->human_size($item['size']) . '</div>';
                $name = "<div onclick=\"directory.select($i)\">*{$item['name']}</div>";

            // Regular file
            } else {
                $size = '<div style="text-align:right" title="' . $item['size'] . ' bytes">' . $dir->human_size($item['size']) . '</div>';
                $name = "<div onclick=\"directory.select($i)\">&nbsp;{$item['name']}</div>";
            }


            $tr_class = trim($tr_class);

?><tr id="tr<?= $i ?>"<?= $tr_class ? " class=\"$tr_class\"" : "" ?>>
<td><?= $i ? "<div id=\"cb$i\" class=\"checkbox\" onclick=\"directory.select($i)\">[ ]</div>" : "" ?></td>
<td><?= $name ?></td>
<td onclick="directory.select(<?= $i ?>)"><?= $item['owner'] ?></td>
<td onclick="directory.select(<?= $i ?>)"><?= $item['group'] ?></td>
<td onclick="directory.select(<?= $i ?>)"><?= $item['perms'] ?></td>
<td onclick="directory.select(<?= $i ?>)"><?= $size ?></td>
<td><div class="context" id="menu<?= $i ?>"></div><div onclick="directory.select(<?= $i ?>)"><?= date("Y-m-d H:m", $item['modified']) ?></div></td>
<td><?= $i ? "<div id=\"act$i\"><a id=\"btn$i\" class=\"button\" onclick=\"directory.show_menu($i, this)\">[+]</a></div>" : "" ?></td>
</tr><?php

        }

?><tr class="last">
<th><div>&nbsp;</div></th>
<th><div>&nbsp;</div></th>
<th><div>&nbsp;</div></th>
<th><div>&nbsp;</div></th>
<th><div>&nbsp;</div></th>
<th><div>&nbsp;</div></th>
<th><div>&nbsp;</div></th>
<th></th>
</tr>
<tr class="bottom">
<th colspan="8"><div id="clipboard"><?php

        if (isset($sess['clipboard'])) {
            if ($dir->is_writable) {

?><a class="button" onclick="ajax.post('wnc.php', 'act=paste', 'container')">Paste <?= count($sess['clipboard']['files']) . ((count($sess['clipboard']['files']) > 1) ? " files" : " file") ?></a><?php

            } else {

?>Cannot paste here<?php

            }
        } else {

?>&nbsp;<?php

        }

?></div><div id="status">&nbsp;</div></th>
</tr>
</table>
</td></tr>
</table>
<div>
<table width="100%">
<tr class="actions">
<td><div id="actions"></div></td>
<th><?php

        if ($dir->is_writable && $dir->is_executable) {

?><form method="post" action="wnc.php" enctype="multipart/form-data">
<input type="hidden" name="act" value="upload"><?php

        }

?><table align="right"><tr><?php

        if ($dir->is_writable && $dir->is_executable) {

?><td><a class="button" onclick="directory.touch()">NewFile</a> <a class="button" onclick="directory.mkdir()">NewDir</a>  <a class="button" onclick="directory.mklnk()">NewLink</a>&nbsp;</td>
<td><div id="div_upload"><input id="fld_upload" type="file" name="file" class="hidden" onchange="this.form.submit()" /></div><a id="btn_upload" class="button">Upload</a></td><?php

        }

?><td>&nbsp;<a class="button" onclick="directory.chdir()">ChDir</a></td>
</tr></table><?php

        if ($dir->is_writable && $dir->is_executable) {

?></form><?php

        }

?></th>
</tr>
</table>
</div>
</td></tr>
</table><?php

        return self::compress_html(ob_get_clean());
    }

    static function editor($dir, $index) {
        $filename = $dir->full_path . "/" . $dir->content[$index]['name'];
        $content = file_get_contents($filename);
        ob_start();

        self::inject_ajax_js("
document.onkeypress = function(e) {
    var e = window.event || e;

    if ((e.keyCode == 27) || (e.keyCode == '13'))
        ajax.close_error();

    if (e.keyCode == 27)
        ajax.close_dialog();
};
directory.changed = false;
document.title = 'wncedit: $filename';
$('editor').style.height = (document.documentElement.clientHeight - 80) + 'px';");

?><div id="dialog"></div>
<div id="error"></div>
<form id="edit" action="wnc.php" method="post">
<input type="hidden" name="act" value="edit" />
<input type="hidden" name="file" value="<?= $index ?>" />
<input type="hidden" name="hash" value="<?= $dir->content[$index]['hash'] ?>" />
<input type="hidden" name="quit" value="0" />
<div class="topic"><table><tr class="title"><td><a href="http://sourceforge.net/projects/wnc" target="_blank">WEBNIGHT COMMANDER</a> editor<span id="loading"></span></td><th>version 2.0</th></tr><tr><td><?= $filename ?><span id="modified"></span></td><th><a class="button" onclick="ajax.post('wnc.php', 'act=logout', 'container')">Logout</a></th></tr></table></div>
<div class="file_content">
<textarea id="editor" name="content" style="width:100%" onkeypress="directory.changed = true; $('modified').innerHTML = '*'"><?= self::textarea_value($content) ?></textarea>
<a class="button" onclick="directory.save_file(<?= $index ?>)">&nbsp;Save&nbsp;</a> <a class="button" onclick="directory.quit_file(<?= $index ?>, directory.changed)">&nbsp;Quit&nbsp;</a>
</div>
</form><?php

        return self::compress_html(ob_get_clean());
    }

    static function viewer($dir, $index) {
        $filename = $dir->full_path . "/" . $dir->content[$index]['name'];
        $content = file_get_contents($filename);
        ob_start();

         self::inject_ajax_js("
document.title = 'wncview: $filename';
$('viewer').style.height = (document.documentElement.clientHeight - 80) + 'px';");

?><div class="topic"><table><tr class="title"><td><a href="http://sourceforge.net/projects/wnc" target="_blank">WEBNIGHT COMMANDER</a> viewer<span id="loading"></span></td><th>version 2.0</th></tr><tr><td><?= $filename ?></td><th><a class="button" onclick="ajax.post('wnc.php', 'act=logout', 'container')">Logout</a></th></tr></table></div>
<div class="file_content">
<textarea id="viewer" style="width:100%" readonly="readonly"><?= self::textarea_value($content) ?></textarea>
<a class="button" onclick="ajax.post('wnc.php', 'act=init', 'container')">&nbsp;Quit&nbsp;</a>
</div><?php

        return self::compress_html(ob_get_clean());
    }

    static function html_value($value) {
        return str_replace('"', "&quot;", $value);
    }

    static function js_value($value) {

        if (is_array($value)) {
            $i = 0;
            $return = "{";
            foreach ($value as $key => $val) {
                $return .= "$key: " . self::js_value($val);
                if (++$i < count($value)) $return .= ", ";
            }
            $return .= "}";

        } elseif (preg_match('/^\d+$/', $value))
            $return = $value;

        elseif (is_bool($value))
            $return = $value ? "true" : "false";

        else
            $return = '"' . str_replace('"', "\\\"", str_replace("\n", "\\\n", $value)) . '"';

        return $return;
    }

    static function textarea_value($value) {
        return str_replace("<", "&lt;", str_replace(">", "&gt;", $value));
    }

    static function inject_ajax_js($js) {
        $header = "<div id=\"ajax_js\">&nbsp;\n<script type=\"text/javascript\">\n";
        $footer = "\n</script>\n</div>";
        $buffer = ob_get_clean();
        if (strpos($buffer, $header) !== false)
            $buffer = str_replace($header, "$header$js\n", $buffer);
        else
            $buffer .= "$header$js$footer";
        ob_start();
        echo $buffer;
    }

    static function js_dir($dir) {
        $js = "directory.content = [";
        $dirs = $dir->content;
        foreach ($dirs as $i => $cdir) {
            $js .= self::js_value($cdir);
            if (++$i < count($dirs)) $js .=  ", ";
        }
        $js .= "];\ndirectory.opened_menu = false;";
        self::inject_ajax_js($js);
    }

    static function error($error) {
        $html = "$error<br /><br /><center><a class=\"button\" onclick=\"$('error').style.display='none'; if ($('login')) $('login').elements[1].focus()\">[ OK ]</a></center>";
        self::inject_ajax_js("ajax.open_error(\"Error!\", " . self::js_value($html) . ");");
    }

    static function compress_html($html) {
        $regex = '/\<textarea([^\>]*)\>([^\<]*)\<\/textarea\s*\>/is';
        if (preg_match_all($regex, $html, $textareas)) {
            $parts = preg_split($regex, $html);
            $return = "";
            foreach ($parts as $i => $part) {
                $compress = trim(preg_replace('/\s+/s', " ", $part));
                $return .= $compress;
                if ($i < count($textareas[0])) {
                    $args = trim(preg_replace('/\s+/s', " ", $textareas[1][$i]));
                    if (strlen($args)) $args = " $args";
                    $return .= "<textarea$args>{$textareas[2][$i]}</textarea>";
                }
            }
            return $return;
        }
        return trim(preg_replace('/\s+/s', " ", $html));
    }
}


//ini_set("display_errors", 1);
//ini_set("error_reporting", E_ALL);

if (!isset($config['session_lifetime'])) $config['session_lifetime'] = ini_get('session.gc_maxlifetime');
if (!isset($config['session_dir'])) $config['session_dir'] = ini_get('session.save_path');
list($w, $h) = explode("x", $config['font_resolution']);

header("Content-Type: text/html; charset={$config['charset']}");
$session = new session($config['session_var'], $config['session_lifetime'], "stamp", $config['session_dir']);
$controller = new controller();
$controller->action();

?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <style type="text/css">body{background:#000;padding:0;color:#fff;cursor:default;margin:<?= $h ?>px <?= $w ?>px}body,input,textarea{font-family:<?= $config['font-family'] ?>;font-size:<?= $config['font-size'] ?>;font-weight:<?= $config['font-weight'] ?>}form{padding:0;margin:0}input[type="text"],input[type="password"],textarea{border:0;background:#18b2b2;padding:0;margin:0}textarea{background:#1818b2;color:#b2b2b2}table{border-collapse:collapse}td,th{padding:0}td{text-align:left}th{text-align:right;font-weight:<?= $config['font-weight'] ?>}a{outline:none;cursor:pointer;text-decoration:none}a.button{background:#b3b3b3;color:#000}a.button:hover{background:#18b2b2}table.form>tbody>tr>th{padding-right:<?= $w ?>px}form span.checkbox:hover{background:#18b2b2}table.list{background:#1818b2}table.list>tbody>tr>td{padding:<?= intval($h / 2) ?>px <?= intval($w / 2) ?>px}table.list table td,table.list table th{border-left:2px solid #b2b2b2;border-right:2px solid #b2b2b2;padding:0 <?= intval($w / 2) - 1 ?>px;white-space:nowrap}table.list table td a{display:block}table.list table th{border-top:1px solid #b2b2b2;padding-top:<?= intval($h / 2) ?>px;text-align:center;color:#ffff54}table.list table tr>td{color:#b2b2b2}table.list tr.dir>td{color:#fff}table.list tr.char>td,table.list tr.block>td{color:#f5f}table.list tr.socket>td,table.list tr.pipe>td{color:#000}table.list tr.exec>td{color:#5f5}table.list table tr:hover>td,table.list tr.dir:hover>td{background:#18b2b2;color:#000;border-color:#000}table.list tr.selected>td,table.list tr.selected:hover>td{color:#ff5}table.list tr.last>th{border-top:0;border-bottom:0}table.list tr.last>th>div{overflow-y:hidden;height:0px}table.list tr.bottom>th{border-top:1px solid #b2b2b2;border-bottom:1px solid #b2b2b2;padding:<?= intval($h / 2) - 1 ?>px <?= intval($w / 2) - 1 ?>px;background:none;text-align:left}table.list a.button{background:#18b2b2}tr.actions a.button{background:#18b2b2}div#dialog,div#error{position:absolute;text-align:center;display:none;left:0;width:100%;color:#000;z-index:3}div#error{z-index:4;color:#fff}div#error table{background-color:#b00}div#dialog table{background-color:#b2b2b2}div#dialog fieldset,div#error fieldset{border:1px solid #fff;border-left-width:2px;border-right-width:2px;margin:0 <?= intval($w / 2) - 1 ?>px <?= intval($h / 2) ?>px <?= intval($w / 2) - 1 ?>px;padding:0 <?= intval($w / 2) + $w - 1 ?>px <?= intval($h / 2) + $h - 1 ?>px <?= intval($w / 2) + $w - 1 ?>px}div#dialog fieldset{border-color:#000}div#dialog legend,div#error legend{color:#ff5;padding:0 <?= $w ?>px;margin:0}div#dialog legend{color:#1818b2}div#dialog fieldset>div,div#error fieldset>div{padding-top:<?= $h - 1 ?>px}div#dialog a.button,div#error a.button{margin:0 <?= intval($w / 2) ?>px}form#login a.button{margin:0}div#error a.button{background:none;color:#fff}div#error a.button:hover{background:#b2b2b2;color:#000}input[type="submit"].hidden{position:absolute;opacity:0;filter:alpha(opacity:0);width:1px;height:1px}div#div_upload{overflow-x:hidden;overflow-y:hidden;position:absolute;z-index:1;filter:alpha(opacity:0);opacity:0}div#div_upload input[type="file"]{cursor:pointer}div.topic{background:#18b2b2;color:#000}div.topic a{color:#000}div.topic a.button{background:#18b2b2;color:#000}div.topic a.button:hover{background:#000;color:#fff}div.topic table{width:100%}div.topic td{padding-left:<?= $w ?>px}div.topic th{padding-right:<?= $w ?>px}div.topic tr.title td,div.topic tr.title th,div.topic tr.title a{background:#b2b2b2;color:#000}div#status{text-align:left;color:#b2b2b2;position:absolute}div#ajax_js{display:none}.checkbox{cursor:pointer}div.context{position:absolute;display:none;background:#b2b2b2;padding:<?= intval($h / 2) - 1 ?>px <?= intval($w / 2) - 1 ?>px;margin-left:-<?= $w ?>px;z-index:2}div.context>div{border:1px solid #000;border-left-width:2px;border-right-width:2px;padding:<?= intval($h / 2) ?>px <?= intval($w / 2) - 1 ?>px}div.context a.button{background:#b2b2b2;display:block;padding-left:<?= $w ?>px}div.context a.button:hover{background:#18b2b2}div#clipboard{float:right}div.file_content a.button{color:#000;background:#18b2b2}span#loading{padding-left:<?= $w * 2 ?>px;color:#b25800}</style> </head> <body> <script type="text/javascript"> function $(id) { return document.getElementById(id); }var ajax = { request: false, url: false, target: false, handler: false, loading_states: ['\\', '|', '/', '-'], loading_index: 0, loading_res: false, http_request: function() { var request = false; if (window.XMLHttpRequest) { request = new XMLHttpRequest(); if (request.overrideMimeType) request.overrideMimeType('text/html'); } else if (window.ActiveXObject) { try { request = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { request = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) {} } } return request; }, get_element: function(elem) { return (elem && elem.length && elem.split) ? $(elem) : (elem ? elem : false); }, ready_handler: function() { if (ajax.request.readyState == 4) { if (ajax.request.status == 200) { if (ajax.target) ajax.target.innerHTML = ajax.request.responseText; if (ajax.handler) ajax.handler(); if ($('ajax_js')) { var code = $('ajax_js').innerHTML; code = code.replace(/^\&nbsp\;\s*/i, ""); code = code.replace(/^\s*\<script[^\>]+\>/i, ""); code = code.replace(/\<\/script>\s*$/i, ""); eval(code); } if ($('div_upload')) { var div = $('div_upload'); var btn = $('btn_upload'); var fld = $('fld_upload'); div.style.width = btn.offsetWidth + "px"; div.style.height = btn.offsetHeight + "px"; var margin_left = btn.offsetWidth - fld.offsetWidth + 4; fld.style.marginLeft = margin_left + "px"; fld.style.marginTop = "-4px"; } if (ajax.loading_res) { clearInterval(ajax.loading_res); ajax.loading_res = false; } } else alert("Server Error " + ajax.request.status + " !"); } }, get: function(url, target, handler) { this.request = this.http_request(); this.url = url; this.target = target ? this.get_element(target) : false; this.handler = (typeof handler == 'function') ? handler : false; if (!this.request) { alert('Error! Ajax functionality not found!'); return false; } if ($('error')) $('error').style.display = "none"; if ($('dialog')) $('dialog').style.display = "none"; if (!this.loading_res) this.loading_res = setInterval('ajax.loading()', 100); this.request.onreadystatechange = ajax.ready_handler; this.request.open("GET", url, true); this.request.setRequestHeader("Expires", "Mon, 26 Jul 1997 05:00:00 GMT"); this.request.setRequestHeader("Cache-Control", "post-check=0, pre-check=0"); this.request.setRequestHeader("Pragma", "no-cache"); this.request.send(null); }, post: function(url, params, target, handler) { this.request = this.http_request(); this.url = url; this.target = target ? this.get_element(target) : false; this.handler = (typeof handler == 'function') ? handler : false; if (!this.request) { alert('Error! Ajax functionality not found!'); return false; } if ($('error')) $('error').style.display = "none"; if ($('dialog')) $('dialog').style.display = "none"; if (!this.loading_res) this.loading_res = setInterval('ajax.loading()', 100); this.request.onreadystatechange = ajax.ready_handler; this.request.open("POST", url, true); this.request.setRequestHeader("Expires", "Mon, 26 Jul 1997 05:00:00 GMT"); this.request.setRequestHeader("Cache-Control", "post-check=0, pre-check=0"); this.request.setRequestHeader("Pragma", "no-cache"); this.request.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); this.request.setRequestHeader("Content-length", params.length); this.request.setRequestHeader("Connection", "close"); this.request.send(params); }, loading: function() { if ($('loading')) { $('loading').innerHTML = "Loading " + ajax.loading_states[ajax.loading_index].replace(/ /, "&nbsp;"); ajax.loading_index++; if (ajax.loading_index >= ajax.loading_states.length) ajax.loading_index = 0; } }, submit_form: function(form, target, handler, url) { form = this.get_element(form); if (!url) url = form.action; var field; var params = ""; for (var i = 0; i < form.length; i++) { field = form.elements[i]; if (field.name && field.name.length) { if ((field.type == "hidden") || (field.type == "password") || (field.type == "select") || (field.type == "submit") || (field.type == "text") || (field.type == "textarea") ) params += this.urlencode(field.name) + "=" + this.urlencode(field.value) + "&"; if ((field.type == "checkbox") && field.checked) params += this.urlencode(field.name) + "=on&"; if ((field.type == "radio") && field.checked && (field.value && field.value.length)) params += this.urlencode(field.name) + "=" + this.urlencode(field.value) + "&"; } } if (params.length) params = params.substr(0, params.length - 1); return (form.method.toLowerCase() == "post") ? this.post(url, params, target, handler) : this.get(this.add_url_params(url, params), target, handler); }, add_url_params: function(url, params) { return /\?/.test(url) ? url + "&" + params : url + "?" + params; }, urlencode: function(string) { string = string.replace(/\r\n/g,"\n"); var utftext = ""; for (var n = 0; n < string.length; n++) { var c = string.charCodeAt(n); if (c < 128) utftext += String.fromCharCode(c); else if ((c > 127) && (c < 2048)) { utftext += String.fromCharCode((c >> 6) | 192); utftext += String.fromCharCode((c & 63) | 128); } else { utftext += String.fromCharCode((c >> 12) | 224); utftext += String.fromCharCode(((c >> 6) & 63) | 128); utftext += String.fromCharCode((c & 63) | 128); } } return escape(utftext); }, urldecode: function(string) { string = unescape(string); var str = ""; var i = 0; var c = c1 = c2 = 0; while ( i < string.length ) { c = string.charCodeAt(i); if (c < 128) { str += str.fromCharCode(c); i++; } else if ((c > 191) && (c < 224)) { c2 = string.charCodeAt(i+1); str += str.fromCharCode(((c & 31) << 6) | (c2 & 63)); i += 2; } else { c2 = string.charCodeAt(i+1); c3 = string.charCodeAt(i+2); str += str.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); i += 3; } } return str; }, get_scroll_top: function() { return document.body.scrollTop ? document.body.scrollTop : (window.pageYOffset ? window.pageYOffset : (document.body.parentElement ? document.body.parentElement.scrollTop : 0)); }, open_window: function(type, title, content, width, height) { if ($(type)) { var dialog = $(type); var top = ajax.get_scroll_top() + 48; var html = '<table align="center"'; if (width || height) html += ' style="' + (width ? ('width:' + width + 'px;') : "") + (height ? ('height:' + height + 'px;') : "") + '"'; html += '><tr><td><fieldset><legend>' + title + '</legend><div>' + content + '</div></fieldset></td></tr></table>'; dialog.innerHTML = html; dialog.style.top = top + "px"; dialog.style.display = "inline"; } }, close_window: function(type) { if ($(type)) $(type).style.display = "none"; }, open_dialog: function(title, content, width, height) { this.open_window('dialog', title, content, width, height); }, close_dialog: function() { this.close_window('dialog'); }, open_error: function(title, content, width, height) { this.open_window('error', title, content, width, height); }, close_error: function() { this.close_window('error'); } };var directory = { content: [], opened_menu: false, select: function(index, set) { if (index == 0) return; checkbox = $('cb' + index); checkbox.innerHTML = (set == null) ? ((checkbox.innerHTML == "[ ]") ? "[x]" : "[ ]") : (set ? "[x]" : "[ ]"); this.content[index].selected = (checkbox.innerHTML == "[x]"); var tr = $('tr' + index); if (this.content[index].selected) { if (!tr.className) tr.className = "selected"; else if (tr.className.substr(tr.className.length - 8, 8) != "selected") { tr.className += " selected"; } } else if (tr.className.substr(tr.className.length - 8, 8) == "selected") { tr.className = (tr.className != "selected") ? tr.className.substr(0, tr.className.length - 9) : ""; } if (set == null) this.refresh_status(); }, select_all: function(checkbox) { checkbox.innerHTML = (checkbox.innerHTML == "[ ]") ? "[x]" : "[ ]"; for (var i = 1; i < this.content.length; i++) this.select(i, (checkbox.innerHTML == "[x]")); this.refresh_status(); }, refresh_status: function() { var readable, writable, item, size, selected; readable = writable = true; selected = size = 0; for (var i = 1; i < this.content.length; i++) { item = this.content[i]; if (item.selected) { selected++; size += item.size; if ((item.type == "d") && (!item.readable || !item.executable)) readable = false; else if (!item.readable) readable = false; if (!item.writable) writable = false; } } $('status').innerHTML = selected ? this.human_size(size) + " bytes in " + selected + " files" : "&nbsp;"; if (selected && (readable || writable)) { var buttons = "Selected:"; if (writable) buttons += ' <a class="button" onclick="directory.sel_cut()">Cut</a>'; if (readable) { buttons += ' <a class="button" onclick="directory.sel_copy()">Copy</a>'; buttons += ' <a class="button" onclick="directory.sel_cp()">CopyTo</a>'; } if (writable) { buttons += ' <a class="button" onclick="directory.sel_mv()">MoveTo</a>'; buttons += ' <a class="button" onclick="directory.sel_chmod()">Perms</a>'; buttons += ' <a class="button" onclick="directory.sel_rm()">Delete</a>'; } $('actions').innerHTML = buttons; } else $('actions').innerHTML = ""; }, show_menu: function(index, btn) { if (btn == null) btn = $('btn' + index); if (this.content[index]) { var menu = $('menu' + index); if (menu.style.display == "inline") { menu.style.display = "none"; btn.innerHTML = "[+]"; btn.style.background = "#18b2b2"; this.opened_menu = false; } else { var item = this.content[index]; var col = $('th_mtime'); menu.style.width = (col.offsetWidth + 2) + "px"; if (this.opened_menu) { $('menu' + this.opened_menu).style.display = "none"; $('btn' + this.opened_menu).style.background = "#18b2b2"; $('btn' + this.opened_menu).innerHTML = "[+]"; this.opened_menu = false; } var html = ""; if (item.writable) html += '<a class="button" onclick="directory.cut(' + index + ')">Cut</a>'; if (item.readable) html += '<a class="button" onclick="directory.copy(' + index + ')">Copy</a>'; if (item.readable) html += '<a class="button" onclick="directory.cp(' + index + ')">Copy to...</a>'; if (item.writable) html += '<a class="button" onclick="directory.mv(' + index + ')">Rename/Move...</a>'; if (item.writable && (item.type != "l")) html += '<a class="button" onclick="directory.chmod(' + index + ')">Permissions...</a>'; if (item.writable) html += '<a class="button" onclick="directory.rm(' + index + ')">Delete</a>'; if ((item.readable && item.writable && (item.type == "-")) || ( (item.type == "l") && (item.target_info.type == "-") && item.target_info.readable && item.target_info.writable ) ) html += '<a class="button" onclick="directory.edit(' + index + ')">Edit</a><a class="button" href="?act=download&file=' + index + '&hash=' + item.hash + '">Download</a>'; else if ( (item.readable && (item.type == "-")) || ((item.type == "l") && (item.target_info.type == "-") && item.target_info.readable) ) html += '<a class="button" onclick="directory.view(' + index + ')">View</a><a class="button" href="?act=download&file=' + index + '&hash=' + item.hash + '">Download</a>'; if (html.length) { btn.style.background = "#b2b2b2"; btn.innerHTML = "[-]"; menu.innerHTML = '<div onclick="directory.show_menu(' + index + ')">' + html + "</div>" ; menu.style.display = "inline"; this.opened_menu = index } } } }, human_size: function(size) { if (size < 1024) { size = size.toString(); } else if (size < 1048576) { size /= 1024; size = parseInt(size).toString() + "K"; } else if (size < 1073741824) { size /= 1048576; size = parseInt(size).toString() + "M"; } else if (size < 1099511627776) { size /= 1073741824; size = parseInt(size).toString() + "G"; } else { size /= 1099511627776; size = parseInt(size).toString() + "T"; } return size; }, chperm: function(which) { var i, j, perm; var checkbox = $(which); var fld_perms = $('perms'); checkbox.innerHTML = (checkbox.innerHTML == "x") ? "&nbsp;" : "x"; checked = (checkbox.innerHTML == "x"); var value = ""; for (i = 0; i <= 2; i++) { perm = 0; for (j = 2; j >= 0; j--) { if ($('p' + i + j).innerHTML == "x") perm += Math.pow(2, j); } value += perm; } fld_perms.value = value; }, chdir: function() { var html = '<form id="chdir" method="post" action="wnc.php" onsubmit="ajax.submit_form(this, \'container\');return false"><input type="hidden" name="act" value="chdir" />Go to directory:<br /><input type="text" name="dir" style="width:100%" /><br /><input type="submit" class="hidden" /><br /></form><center><a class="button" onclick="ajax.submit_form(\'chdir\', \'container\')">[ OK ]</a> <a class="button" onclick="ajax.close_dialog()">[ Cancel ]</a></center>'; ajax.open_dialog("Change Directory", html); $('chdir').elements[1].focus(); }, touch: function() { var html = '<form id="touch" method="post" action="wnc.php" onsubmit="ajax.submit_form(this, \'container\');return false"><input type="hidden" name="act" value="touch" />Enter filename:<br /><input type="text" name="file" style="width:100%" /><br /><br />' + this.perms_input("644") + '<input type="submit" class="hidden" /><br /></form><center><a class="button" onclick="ajax.submit_form(\'touch\', \'container\')">[ OK ]</a> <a class="button" onclick="ajax.close_dialog()">[ Cancel ]</a></center>'; ajax.open_dialog("Create New File", html); $('touch').elements[1].focus(); }, mkdir: function() { var html = '<form id="mkdir" method="post" action="wnc.php" onsubmit="ajax.submit_form(this, \'container\');return false"><input type="hidden" name="act" value="mkdir" />Enter directory name:<br /><input type="text" name="dir" style="width:100%" /><br /><br />' + this.perms_input("755") + '<input type="submit" class="hidden" /><br /></form><center><a class="button" onclick="ajax.submit_form(\'mkdir\', \'container\')">[ OK ]</a> <a class="button" onclick="ajax.close_dialog()">[ Cancel ]</a></center>'; ajax.open_dialog("Create New Directory", html); $('mkdir').elements[1].focus(); }, mklnk: function() { var html = '<form id="mklnk" method="post" action="wnc.php" onsubmit="ajax.submit_form(this, \'container\');return false"><input type="hidden" name="act" value="mklnk" />Existing filename (filename symlink will point to):<br /><input type="text" name="target" style="width:100%" /><br /><br />Symbolic link filename:<br /><input type="text" name="file" style="width:100%" /><br /><input type="submit" class="hidden" /><br /></form><center><a class="button" onclick="ajax.submit_form(\'mklnk\', \'container\')">[ OK ]</a> <a class="button" onclick="ajax.close_dialog()">[ Cancel ]</a></center>'; ajax.open_dialog("Create New Simbolic Link", html); $('mklnk').elements[1].focus(); }, rm: function(index) { var item = this.content[index]; var html = (item.type == "d") ? 'Delete directory "' + this.content[index].name + '" and its content?' : 'Delete file "' + this.content[index].name + '"?'; html += '<br /><br /><center><a class="button" onclick="ajax.post(\'wnc.php\', \'act=rm&file=' + index + '&hash=' + item.hash + '\', \'container\')">[ Yes ]</a> <a class="button" onclick="$(\'error\').style.display=\'none\'">[ No ]</a></center>'; ajax.open_error("Delete", html); }, chmod: function(index) { var item = this.content[index]; var i, j, p, bit, perm = ""; var perms = item.perms.substr(1, item.perms.length - 1); for (i = 0; i < 3; i++) { var p = 0; for (j = 0; j < 3; j++) { bit = perms.substr((i * 3) + j, 1); bit = (bit == "-") ? 0 : Math.pow(2, 2 - j); p += bit; } perm += p; } var html = '<form id="chmod" method="post" action="wnc.php" onsubmit="ajax.submit_form(this, \'container\');return false"><input type="hidden" name="act" value="chmod" /><input type="hidden" name="file" value="' + index + '" /><input type="hidden" name="hash" value="' + item.hash + '" />' + this.perms_input(perm) + '<input type="submit" class="hidden" /><br /></form><center><a class="button" onclick="ajax.submit_form(\'chmod\', \'container\')">[ OK ]</a> <a class="button" onclick="ajax.close_dialog()">[ Cancel ]</a></center>'; ajax.open_dialog(item.name + " permissons", html); }, cp: function(index) { var item = this.content[index]; var html = '<form id="cp" method="post" action="wnc.php" onsubmit="ajax.submit_form(this, \'container\');return false"><input type="hidden" name="act" value="cp" /><input type="hidden" name="file" value="' + index + '" /><input type="hidden" name="hash" value="' + item.hash + '" />Copy "' + item.name + '" to:<br /><input type="text" name="dest" style="width:100%" /><br /><input type="submit" class="hidden" /><br /></form><center><a class="button" onclick="ajax.submit_form(\'cp\', \'container\')">[ OK ]</a> <a class="button" onclick="ajax.close_dialog()">[ Cancel ]</a></center>'; ajax.open_dialog("Copy", html); $('cp').elements[3].focus(); }, mv: function(index) { var item = this.content[index]; var html = '<form id="mv" method="post" action="wnc.php" onsubmit="ajax.submit_form(this, \'container\');return false"><input type="hidden" name="act" value="mv" /><input type="hidden" name="file" value="' + index + '" /><input type="hidden" name="hash" value="' + item.hash + '" />Move or rename "' + item.name + '" to:<br /><input type="text" name="dest" style="width:100%" /><br /><input type="submit" class="hidden" /><br /></form><center><a class="button" onclick="ajax.submit_form(\'mv\', \'container\')">[ OK ]</a> <a class="button" onclick="ajax.close_dialog()">[ Cancel ]</a></center>'; ajax.open_dialog("Move / Rename", html); $('mv').elements[3].focus(); }, cut: function(index) { var item = this.content[index]; ajax.post("wnc.php", "act=cut&file=" + index + "&hash=" + item.hash, 'container'); }, copy: function(index) { var item = this.content[index]; ajax.post("wnc.php", "act=copy&file=" + index + "&hash=" + item.hash, 'container'); }, edit: function(index) { var item = this.content[index]; ajax.post("wnc.php", "act=edit&file=" + index + "&hash=" + item.hash, 'container'); }, view: function(index) { var item = this.content[index]; ajax.post("wnc.php", "act=view&file=" + index + "&hash=" + item.hash, 'container'); }, save_file: function(index) { var html = 'Confirm save file?<br /><br /><center><a class="button" onclick="ajax.close_dialog();ajax.submit_form(\'edit\', \'container\')">[ Save ]</a> <a class="button" onclick="ajax.close_dialog()">[ Cancel ]</a></center>'; ajax.open_dialog("Save file", html); }, quit_file: function(index, changed) { if (!changed) ajax.post('wnc.php', 'act=init', 'container'); else { var item = this.content[index]; var html = 'File was modified, Save with exit?<br /><br /><center><a class="button" onclick="ajax.close_dialog()">[ Cancel quit ]</a> <a class="button" onclick="$(\'edit\').elements[3].value=\'1\';ajax.submit_form(\'edit\', \'container\')">[ Yes ]</a> <a class="button" onclick="ajax.post(\'wnc.php\', \'act=init\', \'container\');">[ No ]</a></center>'; ajax.open_dialog("Quit", html); } }, sel_cut: function() { var selected = this.get_selected(); ajax.post('wnc.php', 'act=sel_cut&' + selected, 'container'); }, sel_copy: function() { var selected = this.get_selected(); ajax.post('wnc.php', 'act=sel_copy&' + selected, 'container'); }, sel_cp: function() { var html = '<form id="sel_cp" method="post" action="wnc.php" onsubmit="ajax.submit_form(this, \'container\');return false"><input type="hidden" name="act" value="sel_cp" />Copy selected files to:<br /><input type="text" name="dest" style="width:100%" /><br />' + this.get_selected(true) + '<input type="submit" class="hidden" /><br /></form><center><a class="button" onclick="ajax.submit_form(\'sel_cp\', \'container\')">[ OK ]</a> <a class="button" onclick="ajax.close_dialog()">[ Cancel ]</a></center>'; ajax.open_dialog("Copy", html); $('sel_cp').elements[1].focus(); }, sel_mv: function() { var html = '<form id="sel_mv" method="post" action="wnc.php" onsubmit="ajax.submit_form(this, \'container\');return false"><input type="hidden" name="act" value="sel_mv" />Move selected files to:<br /><input type="text" name="dest" style="width:100%" /><br />' + this.get_selected(true) + '<input type="submit" class="hidden" /><br /></form><center><a class="button" onclick="ajax.submit_form(\'sel_mv\', \'container\')">[ OK ]</a> <a class="button" onclick="ajax.close_dialog()">[ Cancel ]</a></center>'; ajax.open_dialog("Move", html); $('sel_mv').elements[1].focus(); }, sel_chmod: function() { var html = '<form id="sel_chmod" method="post" action="wnc.php" onsubmit="ajax.submit_form(this, \'container\');return false"><input type="hidden" name="act" value="sel_chmod" />Change selected files permissions:<br /><br />' + this.perms_input("000") + this.get_selected(true) + '<input type="submit" class="hidden" /><br /></form><center><a class="button" onclick="ajax.submit_form(\'sel_chmod\', \'container\')">[ OK ]</a> <a class="button" onclick="ajax.close_dialog()">[ Cancel ]</a></center>'; ajax.open_dialog("Permissons", html); }, sel_rm: function() { var html = 'Delete selected files?<br /><br /><center><a class="button" onclick="ajax.post(\'wnc.php\', \'act=sel_rm&' + this.get_selected() + '\', \'container\')">[ Yes ]</a> <a class="button" onclick="$(\'error\').style.display=\'none\'">[ No ]</a></center>'; ajax.open_error("Delete", html); }, get_selected: function(fields) { var selected = ""; for (var i = 1; i < this.content.length; i++) if (this.content[i].selected) selected += (fields == null) ? '&file[]=' + i + '&hash[]=' + this.content[i].hash : '\n<input type="hidden" name="file[]" value="' + i + '" />' + '\n<input type="hidden" name="hash[]" value="' + this.content[i].hash + '" />' ; return selected ? selected.substr(1, selected.length - 1) : false; }, perms_input: function(mod) { if (!/^\d{3}$/.test(mod)) mod = "000"; var m0 = mod.substr(0, 1); var m1 = mod.substr(1, 1); var m2 = mod.substr(2, 1); var html = '<input type="hidden" id="perms" name="perms" value="' + mod + '" /><span class="checkbox" onclick="directory.chperm(\'p02\')">[<span id="p02">' + ((m0 & 4) ? 'x' : ' ') + '</span>] read by owner</span><br /><span class="checkbox" onclick="directory.chperm(\'p01\')">[<span id="p01">' + ((m0 & 2) ? 'x' : ' ') + '</span>] write by owner</span><br /><span class="checkbox" onclick="directory.chperm(\'p00\')">[<span id="p00">' + ((m0 & 1) ? 'x' : ' ') + '</span>] execute/search by owner</span><br /><span class="checkbox" onclick="directory.chperm(\'p12\')">[<span id="p12">' + ((m1 & 4) ? 'x' : ' ') + '</span>] read by group</span><br /><span class="checkbox" onclick="directory.chperm(\'p11\')">[<span id="p11">' + ((m1 & 2) ? 'x' : ' ') + '</span>] write by group</span><br /><span class="checkbox" onclick="directory.chperm(\'p10\')">[<span id="p10">' + ((m1 & 1) ? 'x' : ' ') + '</span>] execute/search by group</span><br /><span class="checkbox" onclick="directory.chperm(\'p22\')">[<span id="p22">' + ((m2 & 4) ? 'x' : ' ') + '</span>] read by others</span><br /><span class="checkbox" onclick="directory.chperm(\'p21\')">[<span id="p21">' + ((m2 & 2) ? 'x' : ' ') + '</span>] write by others</span><br /><span class="checkbox" onclick="directory.chperm(\'p20\')">[<span id="p20">' + ((m2 & 1) ? 'x' : ' ') + '</span>] execute/search by others</span><br />'; return html; } };window.onload = function() { ajax.post("wnc.php", "act=init", 'container'); }; </script> <div id="container"></div> </body> </html>
Return current item: WebNight Commander