'$2y$12$6iyKwObB3zokmhwUuBhXxuB3/ZenHS4aosToHJJK0Yl3JgY1S80sy', 
);

// Readonly users
// e.g. array('users', 'guest', ...)
$readonly_users = array(
    'user'
);

// Global readonly, including when auth is not being used
$global_readonly = false;

// user specific directories
// array('Username' => 'Directory path', 'Username2' => 'Directory path', ...)
$directories_users = array();

// Enable highlight.js (https://highlightjs.org/) on view's page
$use_highlightjs = true;

// highlight.js style
// for dark theme use 'ir-black'
$highlightjs_style = 'vs';

// Enable ace.js (https://ace.c9.io/) on view's page
$edit_files = true;

// Default timezone for date() and time()
// Doc - http://php.net/manual/en/timezones.php
$default_timezone = 'Etc/UTC'; // UTC

// Root path for file manager
// use absolute path of directory i.e: '/var/www/folder' or $_SERVER['DOCUMENT_ROOT'].'/folder'
$root_path = $_SERVER['DOCUMENT_ROOT'];

// Root url for links in file manager.Relative to $http_host. Variants: '', 'path/to/subfolder'
// Will not working if $root_path will be outside of server document root
$root_url = '';

// Server hostname. Can set manually if wrong
// $_SERVER['HTTP_HOST'].'/folder'
$http_host = $_SERVER['HTTP_HOST'];

// input encoding for iconv
$iconv_input_encoding = 'UTF-8';

// date() format for file modification date
// Doc - https://www.php.net/manual/en/function.date.php
$datetime_format = 'm/d/Y g:i A';

// Path display mode when viewing file information
// 'full' => show full path
// 'relative' => show path relative to root_path
// 'host' => show path on the host
$path_display_mode = 'full';

// Allowed file extensions for create and rename files
// e.g. 'txt,html,css,js'
$allowed_file_extensions = '';

// Allowed file extensions for upload files
// e.g. 'gif,png,jpg,html,txt'
$allowed_upload_extensions = '';

// Favicon path. This can be either a full url to an .PNG image, or a path based on the document root.
// full path, e.g http://example.com/favicon.png
// local path, e.g images/icons/favicon.png
$favicon_path = '';

// Files and folders to excluded from listing
// e.g. array('myfile.html', 'personal-folder', '*.php', ...)
$exclude_items = array();

// Online office Docs Viewer
// Availabe rules are 'google', 'microsoft' or false
// Google => View documents using Google Docs Viewer
// Microsoft => View documents using Microsoft Web Apps Viewer
// false => disable online doc viewer
$online_viewer = 'google';

// Sticky Nav bar
// true => enable sticky header
// false => disable sticky header
$sticky_navbar = true;

// Maximum file upload size
// Increase the following values in php.ini to work properly
// memory_limit, upload_max_filesize, post_max_size
$max_upload_size_bytes = 5000000000; // size 5,000,000,000 bytes (~5GB)

// chunk size used for upload
// eg. decrease to 1MB if nginx reports problem 413 entity too large
$upload_chunk_size_bytes = 2000000; // chunk size 2,000,000 bytes (~2MB)

// Possible rules are 'OFF', 'AND' or 'OR'
// OFF => Don't check connection IP, defaults to OFF
// AND => Connection must be on the whitelist, and not on the blacklist
// OR => Connection must be on the whitelist, or not on the blacklist
$ip_ruleset = 'OFF';

// Should users be notified of their block?
$ip_silent = true;

// IP-addresses, both ipv4 and ipv6
$ip_whitelist = array(
    '127.0.0.1',    // local ipv4
    '::1'           // local ipv6
);

// IP-addresses, both ipv4 and ipv6
$ip_blacklist = array(
    '0.0.0.0',      // non-routable meta ipv4
    '::'            // non-routable meta ipv6
);

// if User has the external config file, try to use it to override the default config above [config.php]
// sample config - https://tinyfilemanager.github.io/config-sample.txt
$config_file = __DIR__.'/config.php';
if (is_readable($config_file)) {
    @include($config_file);
}

// External CDN resources that can be used in the HTML (replace for GDPR compliance)
$external = array(
    'css-bootstrap' => '',
    'css-dropzone' => '',
    'css-font-awesome' => '',
    'css-highlightjs' => '',
    'js-ace' => '',
    'js-bootstrap' => '',
    'js-dropzone' => '',
    'js-jquery' => '',
    'js-jquery-datatables' => '',
    'js-highlightjs' => '',
    'pre-jsdelivr' => '',
    'pre-cloudflare' => ''
);

// --- EDIT BELOW CAREFULLY OR DO NOT EDIT AT ALL ---

// max upload file size
define('MAX_UPLOAD_SIZE', $max_upload_size_bytes);

// upload chunk size
define('UPLOAD_CHUNK_SIZE', $upload_chunk_size_bytes);

// private key and session name to store to the session
if ( !defined( 'FM_SESSION_ID')) {
    define('FM_SESSION_ID', 'filemanager');
}

// Configuration
$cfg = new FM_Config();

// Default language
$lang = isset($cfg->data['lang']) ? $cfg->data['lang'] : 'en';

// Show or hide files and folders that starts with a dot
$show_hidden_files = isset($cfg->data['show_hidden']) ? $cfg->data['show_hidden'] : true;

// PHP error reporting - false = Turns off Errors, true = Turns on Errors
$report_errors = isset($cfg->data['error_reporting']) ? $cfg->data['error_reporting'] : true;

// Hide Permissions and Owner cols in file-listing
$hide_Cols = isset($cfg->data['hide_Cols']) ? $cfg->data['hide_Cols'] : true;

// Theme
$theme = isset($cfg->data['theme']) ? $cfg->data['theme'] : 'light';

define('FM_THEME', $theme);

//available languages
$lang_list = array(
    'en' => 'English'
);

if ($report_errors == true) {
    @ini_set('error_reporting', E_ALL);
    @ini_set('display_errors', 1);
} else {
    @ini_set('error_reporting', E_ALL);
    @ini_set('display_errors', 0);
}

// if fm included
if (defined('FM_EMBED')) {
    $use_auth = false;
    $sticky_navbar = false;
} else {
    @set_time_limit(600);

    date_default_timezone_set($default_timezone);

    ini_set('default_charset', 'UTF-8');
    if (version_compare(PHP_VERSION, '5.6.0', '<') && function_exists('mb_internal_encoding')) {
        mb_internal_encoding('UTF-8');
    }
    if (function_exists('mb_regex_encoding')) {
        mb_regex_encoding('UTF-8');
    }

    session_cache_limiter('nocache'); // Prevent logout issue after page was cached
    session_name(FM_SESSION_ID );
    function session_error_handling_function($code, $msg, $file, $line) {
        // Permission denied for default session, try to create a new one
        if ($code == 2) {
            session_abort();
            session_id(session_create_id());
            @session_start();
        }
    }
    set_error_handler('session_error_handling_function');
    session_start();
    restore_error_handler();
}

//Generating CSRF Token
if (empty($_SESSION['token'])) {
    if (function_exists('random_bytes')) {
        $_SESSION['token'] = bin2hex(random_bytes(32));
    } else {
        $_SESSION['token'] = bin2hex(openssl_random_pseudo_bytes(32));
    }
}

if (empty($auth_users)) {
    $use_auth = false;
}

$is_https = isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1)
    || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https';

// update $root_url based on user specific directories
if (isset($_SESSION[FM_SESSION_ID]['logged']) && !empty($directories_users[$_SESSION[FM_SESSION_ID]['logged']])) {
    $wd = fm_clean_path(dirname($_SERVER['PHP_SELF']));
    $root_url =  $root_url.$wd.DIRECTORY_SEPARATOR.$directories_users[$_SESSION[FM_SESSION_ID]['logged']];
}
// clean $root_url
$root_url = fm_clean_path($root_url);

// abs path for site
defined('FM_ROOT_URL') || define('FM_ROOT_URL', ($is_https ? 'https' : 'http') . '://' . $http_host . (!empty($root_url) ? '/' . $root_url : ''));
defined('FM_SELF_URL') || define('FM_SELF_URL', ($is_https ? 'https' : 'http') . '://' . $http_host . $_SERVER['PHP_SELF']);

// logout
if (isset($_GET['logout'])) {
    unset($_SESSION[FM_SESSION_ID]['logged']);
    unset( $_SESSION['token']); 
    fm_redirect(FM_SELF_URL);
}

// Validate connection IP
if ($ip_ruleset != 'OFF') {
    function getClientIP() {
        if (array_key_exists('HTTP_CF_CONNECTING_IP', $_SERVER)) {
            return  $_SERVER["HTTP_CF_CONNECTING_IP"];
        }else if (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)) {
            return  $_SERVER["HTTP_X_FORWARDED_FOR"];
        }else if (array_key_exists('REMOTE_ADDR', $_SERVER)) {
            return $_SERVER['REMOTE_ADDR'];
        }else if (array_key_exists('HTTP_CLIENT_IP', $_SERVER)) {
            return $_SERVER['HTTP_CLIENT_IP'];
        }
        return '';
    }

    $clientIp = getClientIP();
    $proceed = false;
    $whitelisted = in_array($clientIp, $ip_whitelist);
    $blacklisted = in_array($clientIp, $ip_blacklist);

    if($ip_ruleset == 'AND'){
        if($whitelisted == true && $blacklisted == false){
            $proceed = true;
        }
    } else
    if($ip_ruleset == 'OR'){
         if($whitelisted == true || $blacklisted == false){
            $proceed = true;
        }
    }

    if($proceed == false){
        trigger_error('User connection denied from: ' . $clientIp, E_USER_WARNING);

        if($ip_silent == false){
            fm_set_msg(lng('Access denied. IP restriction applicable'), 'error');
            fm_show_header_login();
            fm_show_message();
        }
        exit();
    }
}

// Checking if the user is logged in or not. If not, it will show the login form.
if ($use_auth) {
    if (isset($_SESSION[FM_SESSION_ID]['logged'], $auth_users[$_SESSION[FM_SESSION_ID]['logged']])) {
        // Logged
    } elseif (isset($_POST['fm_usr'], $_POST['fm_pwd'], $_POST['token'])) {
        // Logging In
        sleep(1);
        if(function_exists('password_verify')) {
            if (isset($auth_users[$_POST['fm_usr']]) && isset($_POST['fm_pwd']) && password_verify($_POST['fm_pwd'], $auth_users[$_POST['fm_usr']]) && verifyToken($_POST['token'])) {
                $_SESSION[FM_SESSION_ID]['logged'] = $_POST['fm_usr'];
                fm_set_msg(lng('You are logged in'));
                fm_redirect(FM_SELF_URL);
            } else {
                unset($_SESSION[FM_SESSION_ID]['logged']);
                fm_set_msg(lng('Login failed. Invalid username or password'), 'error');
                fm_redirect(FM_SELF_URL);
            }
        } else {
            fm_set_msg(lng('password_hash not supported, Upgrade PHP version'), 'error');;
        }
    } else {
        // Form
        unset($_SESSION[FM_SESSION_ID]['logged']);
        fm_show_header_login();
        ?>
        
".lng('Root path')." \"{$root_path}\" ".lng('not found!')." "; exit; } defined('FM_SHOW_HIDDEN') || define('FM_SHOW_HIDDEN', $show_hidden_files); defined('FM_ROOT_PATH') || define('FM_ROOT_PATH', $root_path); defined('FM_LANG') || define('FM_LANG', $lang); defined('FM_FILE_EXTENSION') || define('FM_FILE_EXTENSION', $allowed_file_extensions); defined('FM_UPLOAD_EXTENSION') || define('FM_UPLOAD_EXTENSION', $allowed_upload_extensions); defined('FM_EXCLUDE_ITEMS') || define('FM_EXCLUDE_ITEMS', (version_compare(PHP_VERSION, '7.0.0', '<') ? serialize($exclude_items) : $exclude_items)); defined('FM_DOC_VIEWER') || define('FM_DOC_VIEWER', $online_viewer); define('FM_READONLY', $global_readonly || ($use_auth && !empty($readonly_users) && isset($_SESSION[FM_SESSION_ID]['logged']) && in_array($_SESSION[FM_SESSION_ID]['logged'], $readonly_users))); define('FM_IS_WIN', DIRECTORY_SEPARATOR == '\\'); // always use ?p= if (!isset($_GET['p']) && empty($_FILES)) { fm_redirect(FM_SELF_URL . '?p='); } // get path $p = isset($_GET['p']) ? $_GET['p'] : (isset($_POST['p']) ? $_POST['p'] : ''); // clean path $p = fm_clean_path($p); // for ajax request - save $input = file_get_contents('php://input'); $_POST = (strpos($input, 'ajax') != FALSE && strpos($input, 'save') != FALSE) ? json_decode($input, true) : $_POST; // instead globals vars define('FM_PATH', $p); define('FM_USE_AUTH', $use_auth); define('FM_EDIT_FILE', $edit_files); defined('FM_ICONV_INPUT_ENC') || define('FM_ICONV_INPUT_ENC', $iconv_input_encoding); defined('FM_USE_HIGHLIGHTJS') || define('FM_USE_HIGHLIGHTJS', $use_highlightjs); defined('FM_HIGHLIGHTJS_STYLE') || define('FM_HIGHLIGHTJS_STYLE', $highlightjs_style); defined('FM_DATETIME_FORMAT') || define('FM_DATETIME_FORMAT', $datetime_format); unset($p, $use_auth, $iconv_input_encoding, $use_highlightjs, $highlightjs_style); /*************************** ACTIONS ***************************/ // Handle all AJAX Request if ((isset($_SESSION[FM_SESSION_ID]['logged'], $auth_users[$_SESSION[FM_SESSION_ID]['logged']]) || !FM_USE_AUTH) && isset($_POST['ajax'], $_POST['token']) && !FM_READONLY) { if(!verifyToken($_POST['token'])) { header('HTTP/1.0 401 Unauthorized'); die("Invalid Token."); } //search : get list of files from the current folder if(isset($_POST['type']) && $_POST['type']=="search") { $dir = $_POST['path'] == "." ? '': $_POST['path']; $response = scan(fm_clean_path($dir), $_POST['content']); echo json_encode($response); exit(); } // save editor file if (isset($_POST['type']) && $_POST['type'] == "save") { // get current path $path = FM_ROOT_PATH; if (FM_PATH != '') { $path .= '/' . FM_PATH; } // check path if (!is_dir($path)) { fm_redirect(FM_SELF_URL . '?p='); } $file = $_GET['edit']; $file = fm_clean_path($file); $file = str_replace('/', '', $file); if ($file == '' || !is_file($path . '/' . $file)) { fm_set_msg(lng('File not found'), 'error'); $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } header('X-XSS-Protection:0'); $file_path = $path . '/' . $file; $writedata = $_POST['content']; $fd = fopen($file_path, "w"); $write_results = @fwrite($fd, $writedata); fclose($fd); if ($write_results === false){ header("HTTP/1.1 500 Internal Server Error"); die("Could Not Write File! - Check Permissions / Ownership"); } die(true); } // backup files if (isset($_POST['type']) && $_POST['type'] == "backup" && !empty($_POST['file'])) { $fileName = fm_clean_path($_POST['file']); $fullPath = FM_ROOT_PATH . '/'; if (!empty($_POST['path'])) { $relativeDirPath = fm_clean_path($_POST['path']); $fullPath .= "{$relativeDirPath}/"; } $date = date("dMy-His"); $newFileName = "{$fileName}-{$date}.bak"; $fullyQualifiedFileName = $fullPath . $fileName; try { if (!file_exists($fullyQualifiedFileName)) { throw new Exception("File {$fileName} not found"); } if (copy($fullyQualifiedFileName, $fullPath . $newFileName)) { echo "Backup {$newFileName} created"; } else { throw new Exception("Could not copy file {$fileName}"); } } catch (Exception $e) { echo $e->getMessage(); } } // Save Config if (isset($_POST['type']) && $_POST['type'] == "settings") { global $cfg, $lang, $report_errors, $show_hidden_files, $lang_list, $hide_Cols, $theme; $newLng = $_POST['js-language']; fm_get_translations([]); if (!array_key_exists($newLng, $lang_list)) { $newLng = 'en'; } $erp = isset($_POST['js-error-report']) && $_POST['js-error-report'] == "true" ? true : false; $shf = isset($_POST['js-show-hidden']) && $_POST['js-show-hidden'] == "true" ? true : false; $hco = isset($_POST['js-hide-cols']) && $_POST['js-hide-cols'] == "true" ? true : false; $te3 = $_POST['js-theme-3']; if ($cfg->data['lang'] != $newLng) { $cfg->data['lang'] = $newLng; $lang = $newLng; } if ($cfg->data['error_reporting'] != $erp) { $cfg->data['error_reporting'] = $erp; $report_errors = $erp; } if ($cfg->data['show_hidden'] != $shf) { $cfg->data['show_hidden'] = $shf; $show_hidden_files = $shf; } if ($cfg->data['show_hidden'] != $shf) { $cfg->data['show_hidden'] = $shf; $show_hidden_files = $shf; } if ($cfg->data['hide_Cols'] != $hco) { $cfg->data['hide_Cols'] = $hco; $hide_Cols = $hco; } if ($cfg->data['theme'] != $te3) { $cfg->data['theme'] = $te3; $theme = $te3; } $cfg->save(); echo true; } // new password hash if (isset($_POST['type']) && $_POST['type'] == "pwdhash") { $res = isset($_POST['inputPassword2']) && !empty($_POST['inputPassword2']) ? password_hash($_POST['inputPassword2'], PASSWORD_DEFAULT) : ''; echo $res; } //upload using url if(isset($_POST['type']) && $_POST['type'] == "upload" && !empty($_REQUEST["uploadurl"])) { $path = FM_ROOT_PATH; if (FM_PATH != '') { $path .= '/' . FM_PATH; } function event_callback ($message) { global $callback; echo json_encode($message); } function get_file_path () { global $path, $fileinfo, $temp_file; return $path."/".basename($fileinfo->name); } $url = !empty($_REQUEST["uploadurl"]) && preg_match("|^http(s)?://.+$|", stripslashes($_REQUEST["uploadurl"])) ? stripslashes($_REQUEST["uploadurl"]) : null; //prevent 127.* domain and known ports $domain = parse_url($url, PHP_URL_HOST); $port = parse_url($url, PHP_URL_PORT); $knownPorts = [22, 23, 25, 3306]; if (preg_match("/^localhost$|^127(?:\.[0-9]+){0,2}\.[0-9]+$|^(?:0*\:)*?:?0*1$/i", $domain) || in_array($port, $knownPorts)) { $err = array("message" => "URL is not allowed"); event_callback(array("fail" => $err)); exit(); } $use_curl = false; $temp_file = tempnam(sys_get_temp_dir(), "upload-"); $fileinfo = new stdClass(); $fileinfo->name = trim(basename($url), ".\x00..\x20"); $allowed = (FM_UPLOAD_EXTENSION) ? explode(',', FM_UPLOAD_EXTENSION) : false; $ext = strtolower(pathinfo($fileinfo->name, PATHINFO_EXTENSION)); $isFileAllowed = ($allowed) ? in_array($ext, $allowed) : true; $err = false; if(!$isFileAllowed) { $err = array("message" => "File extension is not allowed"); event_callback(array("fail" => $err)); exit(); } if (!$url) { $success = false; } else if ($use_curl) { @$fp = fopen($temp_file, "w"); @$ch = curl_init($url); curl_setopt($ch, CURLOPT_NOPROGRESS, false ); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_FILE, $fp); @$success = curl_exec($ch); $curl_info = curl_getinfo($ch); if (!$success) { $err = array("message" => curl_error($ch)); } @curl_close($ch); fclose($fp); $fileinfo->size = $curl_info["size_download"]; $fileinfo->type = $curl_info["content_type"]; } else { $ctx = stream_context_create(); @$success = copy($url, $temp_file, $ctx); if (!$success) { $err = error_get_last(); } } if ($success) { $success = rename($temp_file, strtok(get_file_path(), '?')); } if ($success) { event_callback(array("done" => $fileinfo)); } else { unlink($temp_file); if (!$err) { $err = array("message" => "Invalid url parameter"); } event_callback(array("fail" => $err)); } } exit(); } // Delete file / folder if (isset($_GET['del'], $_POST['token']) && !FM_READONLY) { $del = str_replace( '/', '', fm_clean_path( $_GET['del'] ) ); if ($del != '' && $del != '..' && $del != '.' && verifyToken($_POST['token'])) { $path = FM_ROOT_PATH; if (FM_PATH != '') { $path .= '/' . FM_PATH; } $is_dir = is_dir($path . '/' . $del); if (fm_rdelete($path . '/' . $del)) { $msg = $is_dir ? lng('Folder').' %s '.lng('Deleted') : lng('File').' %s '.lng('Deleted'); fm_set_msg(sprintf($msg, fm_enc($del))); } else { $msg = $is_dir ? lng('Folder').' %s '.lng('not deleted') : lng('File').' %s '.lng('not deleted'); fm_set_msg(sprintf($msg, fm_enc($del)), 'error'); } } else { fm_set_msg(lng('Invalid file or folder name'), 'error'); } $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } // Create a new file/folder if (isset($_POST['newfilename'], $_POST['newfile'], $_POST['token']) && !FM_READONLY) { $type = urldecode($_POST['newfile']); $new = str_replace( '/', '', fm_clean_path( strip_tags( $_POST['newfilename'] ) ) ); if (fm_isvalid_filename($new) && $new != '' && $new != '..' && $new != '.' && verifyToken($_POST['token'])) { $path = FM_ROOT_PATH; if (FM_PATH != '') { $path .= '/' . FM_PATH; } if ($type == "file") { if (!file_exists($path . '/' . $new)) { if(fm_is_valid_ext($new)) { @fopen($path . '/' . $new, 'w') or die('Cannot open file: ' . $new); fm_set_msg(sprintf(lng('File').' %s '.lng('Created'), fm_enc($new))); } else { fm_set_msg(lng('File extension is not allowed'), 'error'); } } else { fm_set_msg(sprintf(lng('File').' %s '.lng('already exists'), fm_enc($new)), 'alert'); } } else { if (fm_mkdir($path . '/' . $new, false) === true) { fm_set_msg(sprintf(lng('Folder').' %s '.lng('Created'), $new)); } elseif (fm_mkdir($path . '/' . $new, false) === $path . '/' . $new) { fm_set_msg(sprintf(lng('Folder').' %s '.lng('already exists'), fm_enc($new)), 'alert'); } else { fm_set_msg(sprintf(lng('Folder').' %s '.lng('not created'), fm_enc($new)), 'error'); } } } else { fm_set_msg(lng('Invalid characters in file or folder name'), 'error'); } $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } // Copy folder / file if (isset($_GET['copy'], $_GET['finish']) && !FM_READONLY) { // from $copy = urldecode($_GET['copy']); $copy = fm_clean_path($copy); // empty path if ($copy == '') { fm_set_msg(lng('Source path not defined'), 'error'); $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } // abs path from $from = FM_ROOT_PATH . '/' . $copy; // abs path to $dest = FM_ROOT_PATH; if (FM_PATH != '') { $dest .= '/' . FM_PATH; } $dest .= '/' . basename($from); // move? $move = isset($_GET['move']); $move = fm_clean_path(urldecode($move)); // copy/move/duplicate if ($from != $dest) { $msg_from = trim(FM_PATH . '/' . basename($from), '/'); if ($move) { // Move and to != from so just perform move $rename = fm_rename($from, $dest); if ($rename) { fm_set_msg(sprintf(lng('Moved from').' %s '.lng('to').' %s', fm_enc($copy), fm_enc($msg_from))); } elseif ($rename === null) { fm_set_msg(lng('File or folder with this path already exists'), 'alert'); } else { fm_set_msg(sprintf(lng('Error while moving from').' %s '.lng('to').' %s', fm_enc($copy), fm_enc($msg_from)), 'error'); } } else { // Not move and to != from so copy with original name if (fm_rcopy($from, $dest)) { fm_set_msg(sprintf(lng('Copied from').' %s '.lng('to').' %s', fm_enc($copy), fm_enc($msg_from))); } else { fm_set_msg(sprintf(lng('Error while copying from').' %s '.lng('to').' %s', fm_enc($copy), fm_enc($msg_from)), 'error'); } } } else { if (!$move){ //Not move and to = from so duplicate $msg_from = trim(FM_PATH . '/' . basename($from), '/'); $fn_parts = pathinfo($from); $extension_suffix = ''; if(!is_dir($from)){ $extension_suffix = '.'.$fn_parts['extension']; } //Create new name for duplicate $fn_duplicate = $fn_parts['dirname'].'/'.$fn_parts['filename'].'-'.date('YmdHis').$extension_suffix; $loop_count = 0; $max_loop = 1000; // Check if a file with the duplicate name already exists, if so, make new name (edge case...) while(file_exists($fn_duplicate) & $loop_count < $max_loop){ $fn_parts = pathinfo($fn_duplicate); $fn_duplicate = $fn_parts['dirname'].'/'.$fn_parts['filename'].'-copy'.$extension_suffix; $loop_count++; } if (fm_rcopy($from, $fn_duplicate, False)) { fm_set_msg(sprintf('Copied from %s to %s', fm_enc($copy), fm_enc($fn_duplicate))); } else { fm_set_msg(sprintf('Error while copying from %s to %s', fm_enc($copy), fm_enc($fn_duplicate)), 'error'); } } else{ fm_set_msg(lng('Paths must be not equal'), 'alert'); } } $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } // Mass copy files/ folders if (isset($_POST['file'], $_POST['copy_to'], $_POST['finish'], $_POST['token']) && !FM_READONLY) { if(!verifyToken($_POST['token'])) { fm_set_msg(lng('Invalid Token.'), 'error'); } // from $path = FM_ROOT_PATH; if (FM_PATH != '') { $path .= '/' . FM_PATH; } // to $copy_to_path = FM_ROOT_PATH; $copy_to = fm_clean_path($_POST['copy_to']); if ($copy_to != '') { $copy_to_path .= '/' . $copy_to; } if ($path == $copy_to_path) { fm_set_msg(lng('Paths must be not equal'), 'alert'); $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } if (!is_dir($copy_to_path)) { if (!fm_mkdir($copy_to_path, true)) { fm_set_msg('Unable to create destination folder', 'error'); $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } } // move? $move = isset($_POST['move']); // copy/move $errors = 0; $files = $_POST['file']; if (is_array($files) && count($files)) { foreach ($files as $f) { if ($f != '') { $f = fm_clean_path($f); // abs path from $from = $path . '/' . $f; // abs path to $dest = $copy_to_path . '/' . $f; // do if ($move) { $rename = fm_rename($from, $dest); if ($rename === false) { $errors++; } } else { if (!fm_rcopy($from, $dest)) { $errors++; } } } } if ($errors == 0) { $msg = $move ? 'Selected files and folders moved' : 'Selected files and folders copied'; fm_set_msg($msg); } else { $msg = $move ? 'Error while moving items' : 'Error while copying items'; fm_set_msg($msg, 'error'); } } else { fm_set_msg(lng('Nothing selected'), 'alert'); } $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } // Rename if (isset($_POST['rename_from'], $_POST['rename_to'], $_POST['token']) && !FM_READONLY) { if(!verifyToken($_POST['token'])) { fm_set_msg("Invalid Token.", 'error'); } // old name $old = urldecode($_POST['rename_from']); $old = fm_clean_path($old); $old = str_replace('/', '', $old); // new name $new = urldecode($_POST['rename_to']); $new = fm_clean_path(strip_tags($new)); $new = str_replace('/', '', $new); // path $path = FM_ROOT_PATH; if (FM_PATH != '') { $path .= '/' . FM_PATH; } // rename if (fm_isvalid_filename($new) && $old != '' && $new != '') { if (fm_rename($path . '/' . $old, $path . '/' . $new)) { fm_set_msg(sprintf(lng('Renamed from').' %s '. lng('to').' %s', fm_enc($old), fm_enc($new))); } else { fm_set_msg(sprintf(lng('Error while renaming from').' %s '. lng('to').' %s', fm_enc($old), fm_enc($new)), 'error'); } } else { fm_set_msg(lng('Invalid characters in file name'), 'error'); } $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } // Download if (isset($_GET['dl'], $_POST['token'])) { if(!verifyToken($_POST['token'])) { fm_set_msg("Invalid Token.", 'error'); } $dl = urldecode($_GET['dl']); $dl = fm_clean_path($dl); $dl = str_replace('/', '', $dl); $path = FM_ROOT_PATH; if (FM_PATH != '') { $path .= '/' . FM_PATH; } if ($dl != '' && is_file($path . '/' . $dl)) { fm_download_file($path . '/' . $dl, $dl, 1024); exit; } else { fm_set_msg(lng('File not found'), 'error'); $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } } // Upload if (!empty($_FILES) && !FM_READONLY) { if(isset($_POST['token'])) { if(!verifyToken($_POST['token'])) { $response = array ('status' => 'error','info' => "Invalid Token."); echo json_encode($response); exit(); } } else { $response = array ('status' => 'error','info' => "Token Missing."); echo json_encode($response); exit(); } $chunkIndex = $_POST['dzchunkindex']; $chunkTotal = $_POST['dztotalchunkcount']; $fullPathInput = fm_clean_path($_REQUEST['fullpath']); $f = $_FILES; $path = FM_ROOT_PATH; $ds = DIRECTORY_SEPARATOR; if (FM_PATH != '') { $path .= '/' . FM_PATH; } $errors = 0; $uploads = 0; $allowed = (FM_UPLOAD_EXTENSION) ? explode(',', FM_UPLOAD_EXTENSION) : false; $response = array ( 'status' => 'error', 'info' => 'Oops! Try again' ); $filename = $f['file']['name']; $tmp_name = $f['file']['tmp_name']; $ext = pathinfo($filename, PATHINFO_FILENAME) != '' ? strtolower(pathinfo($filename, PATHINFO_EXTENSION)) : ''; $isFileAllowed = ($allowed) ? in_array($ext, $allowed) : true; if(!fm_isvalid_filename($filename) && !fm_isvalid_filename($fullPathInput)) { $response = array ( 'status' => 'error', 'info' => "Invalid File name!", ); echo json_encode($response); exit(); } $targetPath = $path . $ds; if ( is_writable($targetPath) ) { $fullPath = $path . '/' . basename($fullPathInput); $folder = substr($fullPath, 0, strrpos($fullPath, "/")); if (!is_dir($folder)) { $old = umask(0); mkdir($folder, 0777, true); umask($old); } if (empty($f['file']['error']) && !empty($tmp_name) && $tmp_name != 'none' && $isFileAllowed) { if ($chunkTotal){ $out = @fopen("{$fullPath}.part", $chunkIndex == 0 ? "wb" : "ab"); if ($out) { $in = @fopen($tmp_name, "rb"); if ($in) { if (PHP_VERSION_ID < 80009) { // workaround https://bugs.php.net/bug.php?id=81145 do { for (;;) { $buff = fread($in, 4096); if ($buff === false || $buff === '') { break; } fwrite($out, $buff); } } while (!feof($in)); } else { stream_copy_to_stream($in, $out); } $response = array ( 'status' => 'success', 'info' => "file upload successful" ); } else { $response = array ( 'status' => 'error', 'info' => "failed to open output stream", 'errorDetails' => error_get_last() ); } @fclose($in); @fclose($out); @unlink($tmp_name); $response = array ( 'status' => 'success', 'info' => "file upload successful" ); } else { $response = array ( 'status' => 'error', 'info' => "failed to open output stream" ); } if ($chunkIndex == $chunkTotal - 1) { if (file_exists ($fullPath)) { $ext_1 = $ext ? '.'.$ext : ''; $fullPathTarget = $path . '/' . basename($fullPathInput, $ext_1) .'_'. date('ymdHis'). $ext_1; } else { $fullPathTarget = $fullPath; } rename("{$fullPath}.part", $fullPathTarget); } } else if (move_uploaded_file($tmp_name, $fullPath)) { // Be sure that the file has been uploaded if ( file_exists($fullPath) ) { $response = array ( 'status' => 'success', 'info' => "file upload successful" ); } else { $response = array ( 'status' => 'error', 'info' => 'Couldn\'t upload the requested file.' ); } } else { $response = array ( 'status' => 'error', 'info' => "Error while uploading files. Uploaded files $uploads", ); } } } else { $response = array ( 'status' => 'error', 'info' => 'The specified folder for upload isn\'t writeable.' ); } // Return the response echo json_encode($response); exit(); } // Mass deleting if (isset($_POST['group'], $_POST['delete'], $_POST['token']) && !FM_READONLY) { if(!verifyToken($_POST['token'])) { fm_set_msg(lng("Invalid Token."), 'error'); } $path = FM_ROOT_PATH; if (FM_PATH != '') { $path .= '/' . FM_PATH; } $errors = 0; $files = $_POST['file']; if (is_array($files) && count($files)) { foreach ($files as $f) { if ($f != '') { $new_path = $path . '/' . $f; if (!fm_rdelete($new_path)) { $errors++; } } } if ($errors == 0) { fm_set_msg(lng('Selected files and folder deleted')); } else { fm_set_msg(lng('Error while deleting items'), 'error'); } } else { fm_set_msg(lng('Nothing selected'), 'alert'); } $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } // Pack files zip, tar if (isset($_POST['group'], $_POST['token']) && (isset($_POST['zip']) || isset($_POST['tar'])) && !FM_READONLY) { if(!verifyToken($_POST['token'])) { fm_set_msg(lng("Invalid Token."), 'error'); } $path = FM_ROOT_PATH; $ext = 'zip'; if (FM_PATH != '') { $path .= '/' . FM_PATH; } //set pack type $ext = isset($_POST['tar']) ? 'tar' : 'zip'; if (($ext == "zip" && !class_exists('ZipArchive')) || ($ext == "tar" && !class_exists('PharData'))) { fm_set_msg(lng('Operations with archives are not available'), 'error'); $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } $files = $_POST['file']; $sanitized_files = array(); // clean path foreach($files as $file){ array_push($sanitized_files, fm_clean_path($file)); } $files = $sanitized_files; if (!empty($files)) { chdir($path); if (count($files) == 1) { $one_file = reset($files); $one_file = basename($one_file); $zipname = $one_file . '_' . date('ymd_His') . '.'.$ext; } else { $zipname = 'archive_' . date('ymd_His') . '.'.$ext; } if($ext == 'zip') { $zipper = new FM_Zipper(); $res = $zipper->create($zipname, $files); } elseif ($ext == 'tar') { $tar = new FM_Zipper_Tar(); $res = $tar->create($zipname, $files); } if ($res) { fm_set_msg(sprintf(lng('Archive').' %s '.lng('Created'), fm_enc($zipname))); } else { fm_set_msg(lng('Archive not created'), 'error'); } } else { fm_set_msg(lng('Nothing selected'), 'alert'); } $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } // Unpack zip, tar if (isset($_POST['unzip'], $_POST['token']) && !FM_READONLY) { if(!verifyToken($_POST['token'])) { fm_set_msg(lng("Invalid Token."), 'error'); } $unzip = urldecode($_POST['unzip']); $unzip = fm_clean_path($unzip); $unzip = str_replace('/', '', $unzip); $isValid = false; $path = FM_ROOT_PATH; if (FM_PATH != '') { $path .= '/' . FM_PATH; } if ($unzip != '' && is_file($path . '/' . $unzip)) { $zip_path = $path . '/' . $unzip; $ext = pathinfo($zip_path, PATHINFO_EXTENSION); $isValid = true; } else { fm_set_msg(lng('File not found'), 'error'); } if (($ext == "zip" && !class_exists('ZipArchive')) || ($ext == "tar" && !class_exists('PharData'))) { fm_set_msg(lng('Operations with archives are not available'), 'error'); $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } if ($isValid) { //to folder $tofolder = ''; if (isset($_POST['tofolder'])) { $tofolder = pathinfo($zip_path, PATHINFO_FILENAME); if (fm_mkdir($path . '/' . $tofolder, true)) { $path .= '/' . $tofolder; } } if($ext == "zip") { $zipper = new FM_Zipper(); $res = $zipper->unzip($zip_path, $path); } elseif ($ext == "tar") { try { $gzipper = new PharData($zip_path); if (@$gzipper->extractTo($path,null, true)) { $res = true; } else { $res = false; } } catch (Exception $e) { //TODO:: need to handle the error $res = true; } } if ($res) { fm_set_msg(lng('Archive unpacked')); } else { fm_set_msg(lng('Archive not unpacked'), 'error'); } } else { fm_set_msg(lng('File not found'), 'error'); } $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } // Change Perms (not for Windows) if (isset($_POST['chmod'], $_POST['token']) && !FM_READONLY && !FM_IS_WIN) { if(!verifyToken($_POST['token'])) { fm_set_msg(lng("Invalid Token."), 'error'); } $path = FM_ROOT_PATH; if (FM_PATH != '') { $path .= '/' . FM_PATH; } $file = $_POST['chmod']; $file = fm_clean_path($file); $file = str_replace('/', '', $file); if ($file == '' || (!is_file($path . '/' . $file) && !is_dir($path . '/' . $file))) { fm_set_msg(lng('File not found'), 'error'); $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } $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($path . '/' . $file, $mode)) { fm_set_msg(lng('Permissions changed')); } else { fm_set_msg(lng('Permissions not changed'), 'error'); } $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } /*************************** ACTIONS ***************************/ // get current path $path = FM_ROOT_PATH; if (FM_PATH != '') { $path .= '/' . FM_PATH; } // check path if (!is_dir($path)) { fm_redirect(FM_SELF_URL . '?p='); } // get parent folder $parent = fm_get_parent_path(FM_PATH); $objects = is_readable($path) ? scandir($path) : array(); $folders = array(); $files = array(); $current_path = array_slice(explode("/",$path), -1)[0]; if (is_array($objects) && fm_is_exclude_items($current_path)) { foreach ($objects as $file) { if ($file == '.' || $file == '..') { continue; } if (!FM_SHOW_HIDDEN && substr($file, 0, 1) === '.') { continue; } $new_path = $path . '/' . $file; if (@is_file($new_path) && fm_is_exclude_items($file)) { $files[] = $file; } elseif (@is_dir($new_path) && $file != '.' && $file != '..' && fm_is_exclude_items($file)) { $folders[] = $file; } } } if (!empty($files)) { natcasesort($files); } if (!empty($folders)) { natcasesort($folders); } // upload form if (isset($_GET['upload']) && !FM_READONLY) { fm_show_header(); // HEADER fm_show_nav_path(FM_PATH); // current path //get the allowed file extensions function getUploadExt() { $extArr = explode(',', FM_UPLOAD_EXTENSION); if(FM_UPLOAD_EXTENSION && $extArr) { array_walk($extArr, function(&$x) {$x = ".$x";}); return implode(',', $extArr); } return ''; } ?>
' . PHP_EOL; } ?>

: , ', $copy_files) ?>

:
/

 

Copying

Source path:
Destination folder:

Copy   Move   Cancel

/>
/>
/>

""

:
File size:
MIME-type:
:
:
:
: %
'.lng('Image size').': ' . (isset($image_size[0]) ? $image_size[0] : '0') . ' x ' . (isset($image_size[1]) ? $image_size[1] : '0') . '
'; } // Text info if ($is_text) { $is_utf8 = fm_is_utf8($content); if (function_exists('iconv')) { if (!$is_utf8) { $content = iconv(FM_ICONV_INPUT_ENC, 'UTF-8//IGNORE', $content); } } echo ''.lng('Charset').': ' . ($is_utf8 ? 'utf-8' : '8 bit') . '
'; } ?>

 
 
     
'; } else if($online_viewer == 'microsoft') { echo ''; } } elseif ($is_zip) { // ZIP content if ($filenames !== false) { echo ''; foreach ($filenames as $fn) { if ($fn['folder']) { echo '' . fm_enc($fn['name']) . '
'; } else { echo $fn['name'] . ' (' . fm_get_filesize($fn['filesize']) . ')
'; } } echo '
'; } else { echo '

'.lng('Error while fetching archive info').'

'; } } elseif ($is_image) { // Image content if (in_array($ext, array('gif', 'jpg', 'jpeg', 'png', 'bmp', 'ico', 'svg', 'webp', 'avif'))) { echo '

'; } } elseif ($is_audio) { // Audio content echo '

'; } elseif ($is_video) { // Video content echo '
'; } elseif ($is_text) { if (FM_USE_HIGHLIGHTJS) { // highlight $hljs_classes = array( 'shtml' => 'xml', 'htaccess' => 'apache', 'phtml' => 'php', 'lock' => 'json', 'svg' => 'xml', ); $hljs_class = isset($hljs_classes[$ext]) ? 'lang-' . $hljs_classes[$ext] : 'lang-' . $ext; if (empty($ext) || in_array(strtolower($file), fm_get_text_names()) || preg_match('#\.min\.(css|js)$#i', $file)) { $hljs_class = 'nohighlight'; } $content = '
' . fm_enc($content) . '
'; } elseif (in_array($ext, array('php', 'php4', 'php5', 'phtml', 'phps'))) { // php highlight $content = highlight_string($content, true); } else { $content = '
' . fm_enc($content) . '
'; } echo $content; } ?>
'. $file. ''; header('X-XSS-Protection:0'); fm_show_header(); // HEADER fm_show_nav_path(FM_PATH); // current path $file_url = FM_ROOT_URL . fm_convert_win((FM_PATH != '' ? '/' . FM_PATH : '') . '/' . $file); $file_path = $path . '/' . $file; // normal editer $isNormalEditor = true; if (isset($_GET['env'])) { if ($_GET['env'] == "ace") { $isNormalEditor = false; } } // Save File if (isset($_POST['savedata'])) { $writedata = $_POST['savedata']; $fd = fopen($file_path, "w"); @fwrite($fd, $writedata); fclose($fd); fm_set_msg(lng('File Saved Successfully')); } $ext = strtolower(pathinfo($file_path, PATHINFO_EXTENSION)); $mime_type = fm_get_mime_type($file_path); $filesize = filesize($file_path); $is_text = false; $content = ''; // for text if (in_array($ext, fm_get_text_exts()) || substr($mime_type, 0, 4) == 'text' || in_array($mime_type, fm_get_text_mimes())) { $is_text = true; $content = file_get_contents($file_path); } ?>
' . htmlspecialchars($content) . ''; echo ''; } elseif ($is_text) { echo '
' . htmlspecialchars($content) . '
'; } else { fm_set_msg(lng('FILE EXTENSION HAS NOT SUPPORTED'), 'error'); } ?>

:

 

'?'); } if ($group === false) { $group = array('name' => '?'); } } else { $owner = array('name' => '?'); $group = array('name' => '?'); } ?> '?'); } if ($group === false) { $group = array('name' => '?'); } } else { $owner = array('name' => '?'); $group = array('name' => '?'); } ?>
..
>
' . readlink($path . '/' . $f) . '' : '') ?>
">
>
' . readlink($path . '/' . $f) . '' : '') ?>
">
'.fm_get_filesize($all_files_size).'' ?> '.$num_files.'' ?> '.$num_folders.'' ?>
"; return; } echo "$external[$key]"; } /** * Verify CSRF TOKEN and remove after cerify * @param string $token * @return bool */ function verifyToken($token) { if (hash_equals($_SESSION['token'], $token)) { return true; } return false; } /** * Delete file or folder (recursively) * @param string $path * @return bool */ function fm_rdelete($path) { if (is_link($path)) { return unlink($path); } elseif (is_dir($path)) { $objects = scandir($path); $ok = true; if (is_array($objects)) { foreach ($objects as $file) { if ($file != '.' && $file != '..') { if (!fm_rdelete($path . '/' . $file)) { $ok = false; } } } } return ($ok) ? rmdir($path) : false; } elseif (is_file($path)) { return unlink($path); } return false; } /** * Recursive chmod * @param string $path * @param int $filemode * @param int $dirmode * @return bool * @todo Will use in mass chmod */ function fm_rchmod($path, $filemode, $dirmode) { if (is_dir($path)) { if (!chmod($path, $dirmode)) { return false; } $objects = scandir($path); if (is_array($objects)) { foreach ($objects as $file) { if ($file != '.' && $file != '..') { if (!fm_rchmod($path . '/' . $file, $filemode, $dirmode)) { return false; } } } } return true; } elseif (is_link($path)) { return true; } elseif (is_file($path)) { return chmod($path, $filemode); } return false; } /** * Check the file extension which is allowed or not * @param string $filename * @return bool */ function fm_is_valid_ext($filename) { $allowed = (FM_FILE_EXTENSION) ? explode(',', FM_FILE_EXTENSION) : false; $ext = pathinfo($filename, PATHINFO_EXTENSION); $isFileAllowed = ($allowed) ? in_array($ext, $allowed) : true; return ($isFileAllowed) ? true : false; } /** * Safely rename * @param string $old * @param string $new * @return bool|null */ function fm_rename($old, $new) { $isFileAllowed = fm_is_valid_ext($new); if(!is_dir($old)) { if (!$isFileAllowed) return false; } return (!file_exists($new) && file_exists($old)) ? rename($old, $new) : null; } /** * Copy file or folder (recursively). * @param string $path * @param string $dest * @param bool $upd Update files * @param bool $force Create folder with same names instead file * @return bool */ function fm_rcopy($path, $dest, $upd = true, $force = true) { if (is_dir($path)) { if (!fm_mkdir($dest, $force)) { return false; } $objects = scandir($path); $ok = true; if (is_array($objects)) { foreach ($objects as $file) { if ($file != '.' && $file != '..') { if (!fm_rcopy($path . '/' . $file, $dest . '/' . $file)) { $ok = false; } } } } return $ok; } elseif (is_file($path)) { return fm_copy($path, $dest, $upd); } return false; } /** * Safely create folder * @param string $dir * @param bool $force * @return bool */ function fm_mkdir($dir, $force) { if (file_exists($dir)) { if (is_dir($dir)) { return $dir; } elseif (!$force) { return false; } unlink($dir); } return mkdir($dir, 0777, true); } /** * Safely copy file * @param string $f1 * @param string $f2 * @param bool $upd Indicates if file should be updated with new content * @return bool */ function fm_copy($f1, $f2, $upd) { $time1 = filemtime($f1); if (file_exists($f2)) { $time2 = filemtime($f2); if ($time2 >= $time1 && $upd) { return false; } } $ok = copy($f1, $f2); if ($ok) { touch($f2, $time1); } return $ok; } /** * Get mime type * @param string $file_path * @return mixed|string */ function fm_get_mime_type($file_path) { if (function_exists('finfo_open')) { $finfo = finfo_open(FILEINFO_MIME_TYPE); $mime = finfo_file($finfo, $file_path); finfo_close($finfo); return $mime; } elseif (function_exists('mime_content_type')) { return mime_content_type($file_path); } elseif (!stristr(ini_get('disable_functions'), 'shell_exec')) { $file = escapeshellarg($file_path); $mime = shell_exec('file -bi ' . $file); return $mime; } else { return '--'; } } /** * HTTP Redirect * @param string $url * @param int $code */ function fm_redirect($url, $code = 302) { header('Location: ' . $url, true, $code); exit; } /** * Path traversal prevention and clean the url * It replaces (consecutive) occurrences of / and \\ with whatever is in DIRECTORY_SEPARATOR, and processes /. and /.. fine. * @param $path * @return string */ function get_absolute_path($path) { $path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path); $parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen'); $absolutes = array(); foreach ($parts as $part) { if ('.' == $part) continue; if ('..' == $part) { array_pop($absolutes); } else { $absolutes[] = $part; } } return implode(DIRECTORY_SEPARATOR, $absolutes); } /** * Clean path * @param string $path * @return string */ function fm_clean_path($path, $trim = true) { $path = $trim ? trim($path) : $path; $path = trim($path, '\\/'); $path = str_replace(array('../', '..\\'), '', $path); $path = get_absolute_path($path); if ($path == '..') { $path = ''; } return str_replace('\\', '/', $path); } /** * Get parent path * @param string $path * @return bool|string */ function fm_get_parent_path($path) { $path = fm_clean_path($path); if ($path != '') { $array = explode('/', $path); if (count($array) > 1) { $array = array_slice($array, 0, -1); return implode('/', $array); } return ''; } return false; } function fm_get_display_path($file_path) { global $path_display_mode, $root_path, $root_url; switch ($path_display_mode) { case 'relative': return array( 'label' => 'Path', 'path' => fm_enc(fm_convert_win(str_replace($root_path, '', $file_path))) ); case 'host': $relative_path = str_replace($root_path, '', $file_path); return array( 'label' => 'Host Path', 'path' => fm_enc(fm_convert_win('/' . $root_url . '/' . ltrim(str_replace('\\', '/', $relative_path), '/'))) ); case 'full': default: return array( 'label' => 'Full Path', 'path' => fm_enc(fm_convert_win($file_path)) ); } } /** * Check file is in exclude list * @param string $file * @return bool */ function fm_is_exclude_items($file) { $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION)); if (isset($exclude_items) and sizeof($exclude_items)) { unset($exclude_items); } $exclude_items = FM_EXCLUDE_ITEMS; if (version_compare(PHP_VERSION, '7.0.0', '<')) { $exclude_items = unserialize($exclude_items); } if (!in_array($file, $exclude_items) && !in_array("*.$ext", $exclude_items)) { return true; } return false; } /** * get language translations from json file * @param int $tr * @return array */ function fm_get_translations($tr) { try { $content = @file_get_contents('translation.json'); if($content !== FALSE) { $lng = json_decode($content, TRUE); global $lang_list; foreach ($lng["language"] as $key => $value) { $code = $value["code"]; $lang_list[$code] = $value["name"]; if ($tr) $tr[$code] = $value["translation"]; } return $tr; } } catch (Exception $e) { echo $e; } } /** * @param string $file * Recover all file sizes larger than > 2GB. * Works on php 32bits and 64bits and supports linux * @return int|string */ function fm_get_size($file) { static $iswin; static $isdarwin; if (!isset($iswin)) { $iswin = (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN'); } if (!isset($isdarwin)) { $isdarwin = (strtoupper(substr(PHP_OS, 0)) == "DARWIN"); } static $exec_works; if (!isset($exec_works)) { $exec_works = (function_exists('exec') && !ini_get('safe_mode') && @exec('echo EXEC') == 'EXEC'); } // try a shell command if ($exec_works) { $arg = escapeshellarg($file); $cmd = ($iswin) ? "for %F in (\"$file\") do @echo %~zF" : ($isdarwin ? "stat -f%z $arg" : "stat -c%s $arg"); @exec($cmd, $output); if (is_array($output) && ctype_digit($size = trim(implode("\n", $output)))) { return $size; } } // try the Windows COM interface if ($iswin && class_exists("COM")) { try { $fsobj = new COM('Scripting.FileSystemObject'); $f = $fsobj->GetFile( realpath($file) ); $size = $f->Size; } catch (Exception $e) { $size = null; } if (ctype_digit($size)) { return $size; } } // if all else fails return filesize($file); } /** * Get nice filesize * @param int $size * @return string */ function fm_get_filesize($size) { $size = (float) $size; $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'); $power = ($size > 0) ? floor(log($size, 1024)) : 0; $power = ($power > (count($units) - 1)) ? (count($units) - 1) : $power; return sprintf('%s %s', round($size / pow(1024, $power), 2), $units[$power]); } /** * Get total size of directory tree. * * @param string $directory Relative or absolute directory name. * @return int Total number of bytes. */ function fm_get_directorysize($directory) { $bytes = 0; $directory = realpath($directory); if ($directory !== false && $directory != '' && file_exists($directory)){ foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory, FilesystemIterator::SKIP_DOTS)) as $file){ $bytes += $file->getSize(); } } return $bytes; } /** * Get info about zip archive * @param string $path * @return array|bool */ function fm_get_zif_info($path, $ext) { if ($ext == 'zip' && function_exists('zip_open')) { $arch = @zip_open($path); if ($arch) { $filenames = array(); while ($zip_entry = @zip_read($arch)) { $zip_name = @zip_entry_name($zip_entry); $zip_folder = substr($zip_name, -1) == '/'; $filenames[] = array( 'name' => $zip_name, 'filesize' => @zip_entry_filesize($zip_entry), 'compressed_size' => @zip_entry_compressedsize($zip_entry), 'folder' => $zip_folder //'compression_method' => zip_entry_compressionmethod($zip_entry), ); } @zip_close($arch); return $filenames; } } elseif($ext == 'tar' && class_exists('PharData')) { $archive = new PharData($path); $filenames = array(); foreach(new RecursiveIteratorIterator($archive) as $file) { $parent_info = $file->getPathInfo(); $zip_name = str_replace("phar://".$path, '', $file->getPathName()); $zip_name = substr($zip_name, ($pos = strpos($zip_name, '/')) !== false ? $pos + 1 : 0); $zip_folder = $parent_info->getFileName(); $zip_info = new SplFileInfo($file); $filenames[] = array( 'name' => $zip_name, 'filesize' => $zip_info->getSize(), 'compressed_size' => $file->getCompressedSize(), 'folder' => $zip_folder ); } return $filenames; } return false; } /** * Encode html entities * @param string $text * @return string */ function fm_enc($text) { return htmlspecialchars($text, ENT_QUOTES, 'UTF-8'); } /** * Prevent XSS attacks * @param string $text * @return string */ function fm_isvalid_filename($text) { return (strpbrk($text, '/?%*:|"<>') === FALSE) ? true : false; } /** * Save message in session * @param string $msg * @param string $status */ function fm_set_msg($msg, $status = 'ok') { $_SESSION[FM_SESSION_ID]['message'] = $msg; $_SESSION[FM_SESSION_ID]['status'] = $status; } /** * Check if string is in UTF-8 * @param string $string * @return int */ function fm_is_utf8($string) { return preg_match('//u', $string); } /** * Convert file name to UTF-8 in Windows * @param string $filename * @return string */ function fm_convert_win($filename) { if (FM_IS_WIN && function_exists('iconv')) { $filename = iconv(FM_ICONV_INPUT_ENC, 'UTF-8//IGNORE', $filename); } return $filename; } /** * @param $obj * @return array */ function fm_object_to_array($obj) { if (!is_object($obj) && !is_array($obj)) { return $obj; } if (is_object($obj)) { $obj = get_object_vars($obj); } return array_map('fm_object_to_array', $obj); } /** * Get CSS classname for file * @param string $path * @return string */ function fm_get_file_icon_class($path) { // get extension $ext = strtolower(pathinfo($path, PATHINFO_EXTENSION)); switch ($ext) { case 'ico': case 'gif': case 'jpg': case 'jpeg': case 'jpc': case 'jp2': case 'jpx': case 'xbm': case 'wbmp': case 'png': case 'bmp': case 'tif': case 'tiff': case 'webp': case 'avif': case 'svg': $img = 'fa fa-picture-o'; break; case 'passwd': case 'ftpquota': case 'sql': case 'js': case 'ts': case 'jsx': case 'tsx': case 'hbs': case 'json': case 'sh': case 'config': case 'twig': case 'tpl': case 'md': case 'gitignore': case 'c': case 'cpp': case 'cs': case 'py': case 'rs': case 'map': case 'lock': case 'dtd': $img = 'fa fa-file-code-o'; break; case 'txt': case 'ini': case 'conf': case 'log': case 'htaccess': case 'yaml': case 'yml': case 'toml': case 'tmp': case 'top': case 'bot': case 'dat': case 'bak': case 'htpasswd': case 'pl': $img = 'fa fa-file-text-o'; break; case 'css': case 'less': case 'sass': case 'scss': $img = 'fa fa-css3'; break; case 'bz2': case 'zip': case 'rar': case 'gz': case 'tar': case '7z': case 'xz': $img = 'fa fa-file-archive-o'; break; case 'php': case 'php4': case 'php5': case 'phps': case 'phtml': $img = 'fa fa-code'; break; case 'htm': case 'html': case 'shtml': case 'xhtml': $img = 'fa fa-html5'; break; case 'xml': case 'xsl': $img = 'fa fa-file-excel-o'; break; case 'wav': case 'mp3': case 'mp2': case 'm4a': case 'aac': case 'ogg': case 'oga': case 'wma': case 'mka': case 'flac': case 'ac3': case 'tds': $img = 'fa fa-music'; break; case 'm3u': case 'm3u8': case 'pls': case 'cue': case 'xspf': $img = 'fa fa-headphones'; break; case 'avi': case 'mpg': case 'mpeg': case 'mp4': case 'm4v': case 'flv': case 'f4v': case 'ogm': case 'ogv': case 'mov': case 'mkv': case '3gp': case 'asf': case 'wmv': case 'webm': $img = 'fa fa-file-video-o'; break; case 'eml': case 'msg': $img = 'fa fa-envelope-o'; break; case 'xls': case 'xlsx': case 'ods': $img = 'fa fa-file-excel-o'; break; case 'csv': $img = 'fa fa-file-text-o'; break; case 'bak': case 'swp': $img = 'fa fa-clipboard'; break; case 'doc': case 'docx': case 'odt': $img = 'fa fa-file-word-o'; break; case 'ppt': case 'pptx': $img = 'fa fa-file-powerpoint-o'; break; case 'ttf': case 'ttc': case 'otf': case 'woff': case 'woff2': case 'eot': case 'fon': $img = 'fa fa-font'; break; case 'pdf': $img = 'fa fa-file-pdf-o'; break; case 'psd': case 'ai': case 'eps': case 'fla': case 'swf': $img = 'fa fa-file-image-o'; break; case 'exe': case 'msi': $img = 'fa fa-file-o'; break; case 'bat': $img = 'fa fa-terminal'; break; default: $img = 'fa fa-info-circle'; } return $img; } /** * Get image files extensions * @return array */ function fm_get_image_exts() { return array('ico', 'gif', 'jpg', 'jpeg', 'jpc', 'jp2', 'jpx', 'xbm', 'wbmp', 'png', 'bmp', 'tif', 'tiff', 'psd', 'svg', 'webp', 'avif'); } /** * Get video files extensions * @return array */ function fm_get_video_exts() { return array('avi', 'webm', 'wmv', 'mp4', 'm4v', 'ogm', 'ogv', 'mov', 'mkv'); } /** * Get audio files extensions * @return array */ function fm_get_audio_exts() { return array('wav', 'mp3', 'ogg', 'm4a'); } /** * Get text file extensions * @return array */ function fm_get_text_exts() { return array( 'txt', 'css', 'ini', 'conf', 'log', 'htaccess', 'passwd', 'ftpquota', 'sql', 'js', 'ts', 'jsx', 'tsx', 'mjs', 'json', 'sh', 'config', 'php', 'php4', 'php5', 'phps', 'phtml', 'htm', 'html', 'shtml', 'xhtml', 'xml', 'xsl', 'm3u', 'm3u8', 'pls', 'cue', 'bash', 'vue', 'eml', 'msg', 'csv', 'bat', 'twig', 'tpl', 'md', 'gitignore', 'less', 'sass', 'scss', 'c', 'cpp', 'cs', 'py', 'go', 'zsh', 'swift', 'map', 'lock', 'dtd', 'svg', 'asp', 'aspx', 'asx', 'asmx', 'ashx', 'jsp', 'jspx', 'cgi', 'dockerfile', 'ruby', 'yml', 'yaml', 'toml', 'vhost', 'scpt', 'applescript', 'csx', 'cshtml', 'c++', 'coffee', 'cfm', 'rb', 'graphql', 'mustache', 'jinja', 'http', 'handlebars', 'java', 'es', 'es6', 'markdown', 'wiki', 'tmp', 'top', 'bot', 'dat', 'bak', 'htpasswd', 'pl' ); } /** * Get mime types of text files * @return array */ function fm_get_text_mimes() { return array( 'application/xml', 'application/javascript', 'application/x-javascript', 'image/svg+xml', 'message/rfc822', 'application/json', ); } /** * Get file names of text files w/o extensions * @return array */ function fm_get_text_names() { return array( 'license', 'readme', 'authors', 'contributors', 'changelog', ); } /** * Get online docs viewer supported files extensions * @return array */ function fm_get_onlineViewer_exts() { return array('doc', 'docx', 'xls', 'xlsx', 'pdf', 'ppt', 'pptx', 'ai', 'psd', 'dxf', 'xps', 'rar', 'odt', 'ods'); } /** * It returns the mime type of a file based on its extension. * @param extension The file extension of the file you want to get the mime type for. * @return string|string[] The mime type of the file. */ function fm_get_file_mimes($extension) { $fileTypes['swf'] = 'application/x-shockwave-flash'; $fileTypes['pdf'] = 'application/pdf'; $fileTypes['exe'] = 'application/octet-stream'; $fileTypes['zip'] = 'application/zip'; $fileTypes['doc'] = 'application/msword'; $fileTypes['xls'] = 'application/vnd.ms-excel'; $fileTypes['ppt'] = 'application/vnd.ms-powerpoint'; $fileTypes['gif'] = 'image/gif'; $fileTypes['png'] = 'image/png'; $fileTypes['jpeg'] = 'image/jpg'; $fileTypes['jpg'] = 'image/jpg'; $fileTypes['webp'] = 'image/webp'; $fileTypes['avif'] = 'image/avif'; $fileTypes['rar'] = 'application/rar'; $fileTypes['ra'] = 'audio/x-pn-realaudio'; $fileTypes['ram'] = 'audio/x-pn-realaudio'; $fileTypes['ogg'] = 'audio/x-pn-realaudio'; $fileTypes['wav'] = 'video/x-msvideo'; $fileTypes['wmv'] = 'video/x-msvideo'; $fileTypes['avi'] = 'video/x-msvideo'; $fileTypes['asf'] = 'video/x-msvideo'; $fileTypes['divx'] = 'video/x-msvideo'; $fileTypes['mp3'] = 'audio/mpeg'; $fileTypes['mp4'] = 'audio/mpeg'; $fileTypes['mpeg'] = 'video/mpeg'; $fileTypes['mpg'] = 'video/mpeg'; $fileTypes['mpe'] = 'video/mpeg'; $fileTypes['mov'] = 'video/quicktime'; $fileTypes['swf'] = 'video/quicktime'; $fileTypes['3gp'] = 'video/quicktime'; $fileTypes['m4a'] = 'video/quicktime'; $fileTypes['aac'] = 'video/quicktime'; $fileTypes['m3u'] = 'video/quicktime'; $fileTypes['php'] = ['application/x-php']; $fileTypes['html'] = ['text/html']; $fileTypes['txt'] = ['text/plain']; //Unknown mime-types should be 'application/octet-stream' if(empty($fileTypes[$extension])) { $fileTypes[$extension] = ['application/octet-stream']; } return $fileTypes[$extension]; } /** * This function scans the files and folder recursively, and return matching files * @param string $dir * @param string $filter * @return array|null */ function scan($dir = '', $filter = '') { $path = FM_ROOT_PATH.'/'.$dir; if($path) { $ite = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)); $rii = new RegexIterator($ite, "/(" . $filter . ")/i"); $files = array(); foreach ($rii as $file) { if (!$file->isDir()) { $fileName = $file->getFilename(); $location = str_replace(FM_ROOT_PATH, '', $file->getPath()); $files[] = array( "name" => $fileName, "type" => "file", "path" => $location, ); } } return $files; } } /** * Parameters: downloadFile(File Location, File Name, * max speed, is streaming * If streaming - videos will show as videos, images as images * instead of download prompt * https://stackoverflow.com/a/13821992/1164642 */ function fm_download_file($fileLocation, $fileName, $chunkSize = 1024) { if (connection_status() != 0) return (false); $extension = pathinfo($fileName, PATHINFO_EXTENSION); $contentType = fm_get_file_mimes($extension); if(is_array($contentType)) { $contentType = implode(' ', $contentType); } $size = filesize($fileLocation); if ($size == 0) { fm_set_msg(lng('Zero byte file! Aborting download'), 'error'); $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); return (false); } @ini_set('magic_quotes_runtime', 0); $fp = fopen("$fileLocation", "rb"); if ($fp === false) { fm_set_msg(lng('Cannot open file! Aborting download'), 'error'); $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); return (false); } // headers header('Content-Description: File Transfer'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); header("Content-Transfer-Encoding: binary"); header("Content-Type: $contentType"); $contentDisposition = 'attachment'; if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE")) { $fileName = preg_replace('/\./', '%2e', $fileName, substr_count($fileName, '.') - 1); header("Content-Disposition: $contentDisposition;filename=\"$fileName\""); } else { header("Content-Disposition: $contentDisposition;filename=\"$fileName\""); } header("Accept-Ranges: bytes"); $range = 0; if (isset($_SERVER['HTTP_RANGE'])) { list($a, $range) = explode("=", $_SERVER['HTTP_RANGE']); str_replace($range, "-", $range); $size2 = $size - 1; $new_length = $size - $range; header("HTTP/1.1 206 Partial Content"); header("Content-Length: $new_length"); header("Content-Range: bytes $range$size2/$size"); } else { $size2 = $size - 1; header("Content-Range: bytes 0-$size2/$size"); header("Content-Length: " . $size); } $fileLocation = realpath($fileLocation); while (ob_get_level()) ob_end_clean(); readfile($fileLocation); fclose($fp); return ((connection_status() == 0) and !connection_aborted()); } /** * If the theme is dark, return the text-white and bg-dark classes. * @return string the value of the variable. */ function fm_get_theme() { $result = ''; if(FM_THEME == "dark") { $result = "text-white bg-dark"; } return $result; } /** * Class to work with zip files (using ZipArchive) */ class FM_Zipper { private $zip; public function __construct() { $this->zip = new ZipArchive(); } /** * Create archive with name $filename and files $files (RELATIVE PATHS!) * @param string $filename * @param array|string $files * @return bool */ public function create($filename, $files) { $res = $this->zip->open($filename, ZipArchive::CREATE); if ($res !== true) { return false; } if (is_array($files)) { foreach ($files as $f) { $f = fm_clean_path($f); if (!$this->addFileOrDir($f)) { $this->zip->close(); return false; } } $this->zip->close(); return true; } else { if ($this->addFileOrDir($files)) { $this->zip->close(); return true; } return false; } } /** * Extract archive $filename to folder $path (RELATIVE OR ABSOLUTE PATHS) * @param string $filename * @param string $path * @return bool */ public function unzip($filename, $path) { $res = $this->zip->open($filename); if ($res !== true) { return false; } if ($this->zip->extractTo($path)) { $this->zip->close(); return true; } return false; } /** * Add file/folder to archive * @param string $filename * @return bool */ private function addFileOrDir($filename) { if (is_file($filename)) { return $this->zip->addFile($filename); } elseif (is_dir($filename)) { return $this->addDir($filename); } return false; } /** * Add folder recursively * @param string $path * @return bool */ private function addDir($path) { if (!$this->zip->addEmptyDir($path)) { return false; } $objects = scandir($path); if (is_array($objects)) { foreach ($objects as $file) { if ($file != '.' && $file != '..') { if (is_dir($path . '/' . $file)) { if (!$this->addDir($path . '/' . $file)) { return false; } } elseif (is_file($path . '/' . $file)) { if (!$this->zip->addFile($path . '/' . $file)) { return false; } } } } return true; } return false; } } /** * Class to work with Tar files (using PharData) */ class FM_Zipper_Tar { private $tar; public function __construct() { $this->tar = null; } /** * Create archive with name $filename and files $files (RELATIVE PATHS!) * @param string $filename * @param array|string $files * @return bool */ public function create($filename, $files) { $this->tar = new PharData($filename); if (is_array($files)) { foreach ($files as $f) { $f = fm_clean_path($f); if (!$this->addFileOrDir($f)) { return false; } } return true; } else { if ($this->addFileOrDir($files)) { return true; } return false; } } /** * Extract archive $filename to folder $path (RELATIVE OR ABSOLUTE PATHS) * @param string $filename * @param string $path * @return bool */ public function unzip($filename, $path) { $res = $this->tar->open($filename); if ($res !== true) { return false; } if ($this->tar->extractTo($path)) { return true; } return false; } /** * Add file/folder to archive * @param string $filename * @return bool */ private function addFileOrDir($filename) { if (is_file($filename)) { try { $this->tar->addFile($filename); return true; } catch (Exception $e) { return false; } } elseif (is_dir($filename)) { return $this->addDir($filename); } return false; } /** * Add folder recursively * @param string $path * @return bool */ private function addDir($path) { $objects = scandir($path); if (is_array($objects)) { foreach ($objects as $file) { if ($file != '.' && $file != '..') { if (is_dir($path . '/' . $file)) { if (!$this->addDir($path . '/' . $file)) { return false; } } elseif (is_file($path . '/' . $file)) { try { $this->tar->addFile($path . '/' . $file); } catch (Exception $e) { return false; } } } } return true; } return false; } } /** * Save Configuration */ class FM_Config { var $data; function __construct() { global $root_path, $root_url, $CONFIG; $fm_url = $root_url.$_SERVER["PHP_SELF"]; $this->data = array( 'lang' => 'en', 'error_reporting' => true, 'show_hidden' => true ); $data = false; if (strlen($CONFIG)) { $data = fm_object_to_array(json_decode($CONFIG)); } else { $msg = 'Tiny File Manager
Error: Cannot load configuration'; if (substr($fm_url, -1) == '/') { $fm_url = rtrim($fm_url, '/'); $msg .= '
'; $msg .= '
Seems like you have a trailing slash on the URL.'; $msg .= '
Try this link: ' . $fm_url . ''; } die($msg); } if (is_array($data) && count($data)) $this->data = $data; else $this->save(); } function save() { $fm_file = __FILE__; $var_name = '$CONFIG'; $var_value = var_export(json_encode($this->data), true); $config_string = " ' . $_SESSION[FM_SESSION_ID]['message'] . '

'; unset($_SESSION[FM_SESSION_ID]['message']); unset($_SESSION[FM_SESSION_ID]['status']); } } /** * Show page header in Login Form */ function fm_show_header_login() { $sprites_ver = '20160315'; header("Content-Type: text/html; charset=utf-8"); header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0"); header("Pragma: no-cache"); global $lang, $root_url, $favicon_path; ?> '; } ?> <?php echo fm_enc(APP_TITLE) ?> ">
'; } ?> <?php echo fm_enc(APP_TITLE) ?> ">

100 percent free Gacha Sex Video clips Community

Naturally, as with every gacha video game, spending needless to say provides you with a plus, even though I might say it’s way too many or even need to. Even if You will find spent some money on my head membership to support the brand new designers, In addition have a vacation F2P account which is next to maximum peak possesses a group that may undertake very degree currently. As previously mentioned, the video game is a change-based credit battler in which you create a small grouping of 5 waifus and you can obvious levels from the assaulting opponent groups. It’s fully PVE, and each stage try a different such. You will do you need electricity (or times because the online game means they) to try out levels; when you are getting past the first work from a huge amount of 100 percent free strength replenishes from rapidly leveling up, the new everyday union level try limited.

verashia full video

Confidentiality factors also are extremely important; play with safe and personal internet connections to safeguard important computer data. Keep in mind enough time spent to play, and you may harmony they together with other life things. Finally, be aware of the games’s blogs and make certain they aligns with your own personal comfort profile. NSFW gacha games commonly monetize as a result of inside the-application purchases plus the entry to gacha auto mechanics. Participants could possibly get spend money discover digital issues or emails, increasing the gaming sense. This type of monetization steps are designed to become interesting, often encouraging regular using.

Within 2-3 weeks out of performing a feature poll, these have arranged an enormous content inform containing all of the features that have been voted in the fresh poll, that has been a breathing of clean air. The brand new builders also are individually contactable to your game’s formal Discord servers. This website contains ages-restricted material and nudity and explicit depictions from sexual intercourse. Because of the typing, your affirm that you’re at the least 18 yrs old or even the chronilogical age of majority in the legislation you are opening the website away from therefore agree to enjoying intimately direct blogs. Back in the day, the fresh Gacha community contains adults and you can family instead of children.

If you are here aren’t guild battles or leaderboards yet, the new builders intend to expand on the program soon. Completely fledged incidents which have improvements music takes place in the after per month, always running for starters-2 weeks, with a lot of advantages. Having downtime between events, it is extremely simple for players to arrange adequately to grind him or her when they indeed become as much as again. I won’t enter into excessive outline here, but i’m the video game looks pretty good. Therefore yeah, there’s in reality probably going to be a Gacha porn game entitled Gacha Heaven. Frequent blog post associated with the will bring you muted or possibly blocked.

Pornhub will give you limitless free porn video clips on the top adult performers. Enjoy the prominent novice porno area on the net as well because the full-length views regarding the better Mature studios. I inform all of our porno videos daily to ensure you always get the highest quality sex videos. First, I believed that designer interaction to your area is actually a little scarce, however, because it turns out, which hushed spell is actually because they was in reality moving aside a great deal from blogs and online game alter asked by the neighborhood.

Ft SSR rates try 2percent with no embarrassment program, with unexpected banner summons which have a shame program encouraging an enthusiastic SSR just after a hundred check my source draws but with a base SSR price of 1-1.5percent. Most other flag summons tend to be skewed prices in favor of freshly put-out systems (overall SSR rate is still 2percent), otherwise enjoy-exclusives (e.g The brand new Year’s, Valentine’s), that can have a 2percent speed. Sure, NSFW gacha video game is courtroom, considering it conform to the fresh regulations of one’s part in which they arrive. This type of game generally have tight ages limits to be sure they commonly reached by the minors.

Totally free 7 day superior availableness

It’s necessary for professionals to be familiar with and you will value these constraints. Nikke could have been an interest out of much talk, mostly because of its uncensored blogs. But not, what often becomes overshadowed is actually their sturdy profile structure and you can interesting game play. Town try split up; particular supplement their boldness and visual appeals, while others indicate the brand new controversies close its specific blogs.

  • This type of monetization procedures are made to be engaging, usually promising regular spending.
  • As the Gacha was a bit some other when they didn’t.
  • Getting mindful of these elements may cause a safer and you may more enjoyable betting experience.
  • Some of the best characters in the meta are actually Roentgen and Letter letters that everybody features, meaning that you will not need to get in the gacha far when the hoarding info is your matter.
  • Lastly, understand online game’s blogs and make certain they aligns with your own comfort profile.
  • The story need to be charming, have a tendency to weaving adult layouts which have state-of-the-art narratives you to definitely remain professionals invested.

Individually, I’d to the game immediately after enjoying VTubers play it, and i also avoid the brand new NSFW content whatsoever, whilst moments are purportedly really well done. The risks were potential dependency, connection with specific blogs, and you can privacy things. So you can decrease such threats, participants would be to lay date restrictions, understand the game’s content just before to try out, and make certain he is having fun with safer and personal networks. Being conscious of this type of factors may cause a better and you may less stressful gambling experience.

“Post me personally anything” Postings

Games auto mechanics will be creative, challenging but really obtainable, making certain players remain engaged. Lastly, neighborhood involvement is vital, because it allows participants to share with you enjoy, steps, and you can form a contact with the overall game beyond the NSFW blogs. When you are here aren’t of several emails in the games yet , (currently 47) and the video game provides an auto function to own farming objectives, a number of the company fights or any other degree require a little an excellent little bit of strategizing to overcome. Essentially, unless of course their people is really overleveled, it ought to be impossible to vehicle as a result of a supervisor competition or difficult stage, requiring you to definitely imagine and you will gamble from the matches in your individual. So far as change-centered video game wade, that is most likely the most user friendly of those available.

What cannot be declined, even when, try the influence on the newest NSFW gacha gambling scene. On the ever before-evolving landscaping away from mobile playing, NSFW (Maybe not Safe for Performs) gacha online game provides carved another niche for themselves. Since the an enthusiastic buff and critic within sphere, I’ve seen its great growth in the newest gaming area. These types of online game, known for its adult articles, haven’t only entertained a critical listeners but i have and challenged the new borders away from traditional gaming narratives. TenkafuMA is an excellent H-gacha game one to has just released international inside the late January, which includes a turn-dependent credit competition system the place you generate several five waifus and you may overcome the world in the footwear of one’s strong Archdemon Caesar. It will be the first video game created by Taiwanese business SG-Arts, but packages shocking quality, not only in terms of artstyle and H-posts, but also gameplay.

Game play

All the profile features an alternative Biggest Feature and various First Symptoms and additional Couch potato Efficiency, which dictate the way they play on your own party. No specific profile is required the of one’s content inside the the game (perhaps the endgame tower form or afterwards sections from the tale), if you build a well-balanced group with a range away from kinds. There is no gizmos within this games, you get a lot more strength from the possibly leveling enhance characters, changing them (raising the celebs of a characteristics), or broadening the potentials (guide stat increments using materials). An excellent NSFW gacha video game transcends simple titillation; it’s an artful combination of facts depth, character invention, and you can entertaining game mechanics, the when you’re fostering an exciting community. The story have to be pleasant, tend to weaving mature themes having advanced narratives you to definitely keep participants invested. Reputation advancement is extremely important, because adds a sheet of relatability and emotional accessory.

There are several game modes currently, like the fundamental facts, farmable quests, and the tower mode known as Demon Spire, that is filled with problem degree. For now, the new endgame may revolve in the leaderboards for it form, which is future in addition to a large modify second Wednesday. This really is towards the top of any feel that’s already powering (or no), and therefore I shall talk about later. Firstly, follow ages limits; these online game commonly suitable for minors.

How do NSFW Gacha Video game Monetize?

I would state the online game may be F2P friendly while the while the long as you create a well-balanced, solid party of 5 waifus, you could potentially take on any blogs. Investing in the game is certainly caused by for shorter progress otherwise raising the sort of emails in your lineup, if you can definitely reach the latest endgame in this a few months from to try out. The very best letters in the meta already are Roentgen and you may N emails that everyone provides, meaning that you simply will not even have to pull regarding the gacha much if hoarding information will be your issue.

Totally free Gacha Porno Video

That it explains as to the reasons Gacha Resorts is a real 13+ video game which is Slightly Raunchy. Anyways, Phantom told you one a great hentai video game company known as Nutaku achieved out to Lunime and you may questioned when they’d come together for the an excellent hentai game. Because the Gacha will be a little additional once they didn’t. XVideos.com – an informed free pornography videos to your sites, at no cost. There’s already a simple guild program at the job along with her together with other players to find perks by doing daily quests the month.