diff --git a/commands/rm.json b/commands/rm.json new file mode 100644 index 0000000..dc7a50d --- /dev/null +++ b/commands/rm.json @@ -0,0 +1,89 @@ +{ + "name" : "rm", + + "info" : { + "syntax" : "rm <file name>", + "brief" : "Remove the specified file", + }, + + "action" : function ( arg ) + { + if ( !arg || arg.length == 0 ) + { + return "mkdir: Parameter expected
\n"; + } + + shell.auto_prompt_focus = false; + shell.auto_prompt_refresh = false; + arg = shell.expandPath ( arg ); + + var users_php = window.location.href; + users_php = users_php.replace ( /\/([a-zA-Z\.]+)$/, '/modules/users/users.php' ); + params = 'action=rm&file=' + escape ( arg ); + + var http = new XMLHttpRequest(); + http.open ( "POST", users_php, true ); + http.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); + http.setRequestHeader("Content-length", params.length); + http.setRequestHeader("Connection", "close"); + + http.onreadystatechange = function () + { + if ( http.readyState == 4 && http.status == 200 ) + { + if ( http.responseText.length > 0 ) + { + shell.cmdOut.innerHTML = http.responseText; + } else { + var files_config = window.location.href; + files_config = files_config.replace ( /\/([a-zA-Z\.]+)$/, '/modules/users/files.php' ); + + var http2 = new XMLHttpRequest(); + http2.open ( "GET", files_config, true ); + + http2.onreadystatechange = function () + { + if ( http2.readyState == 4 && http2.status == 200 ) + { + shell.files = eval ( '(' + http2.responseText + ')' ); + + // Remove duplicates + var tmp = new Array(); + + for ( var i in shell.files ) + { + var contains = false; + + for ( var j=0; j < tmp.length && !contains; j++ ) + { + if ( shell.files[i].path == tmp[j].path ) + { + contains = true; + } + } + + if ( !contains ) + { + tmp.push ( shell.files[i] ); + } + } + + shell.files = tmp; + } + } + + http2.send ( null ); + shell.cmdOut.innerHTML = ''; + } + + shell.refreshPrompt ( false, false ); + shell.auto_prompt_focus = true; + shell.auto_prompt_refresh = true; + } + } + + http.send ( params ); + shell.cmdOut.innerHTML = ''; + } +} + diff --git a/commands/touch.json b/commands/touch.json new file mode 100644 index 0000000..1a04152 --- /dev/null +++ b/commands/touch.json @@ -0,0 +1,89 @@ +{ + "name" : "touch", + + "info" : { + "syntax" : "touch <file name>", + "brief" : "Create a new (empty) file with the specified name", + }, + + "action" : function ( arg ) + { + if ( !arg || arg.length == 0 ) + { + return "touch: Parameter expected
\n"; + } + + shell.auto_prompt_focus = false; + shell.auto_prompt_refresh = false; + arg = shell.expandPath ( arg ); + + var users_php = window.location.href; + users_php = users_php.replace ( /\/([a-zA-Z\.]+)$/, '/modules/users/users.php' ); + params = 'action=touch&file=' + escape ( arg ); + + var http = new XMLHttpRequest(); + http.open ( "POST", users_php, true ); + http.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); + http.setRequestHeader("Content-length", params.length); + http.setRequestHeader("Connection", "close"); + + http.onreadystatechange = function () + { + if ( http.readyState == 4 && http.status == 200 ) + { + if ( http.responseText.length > 0 ) + { + shell.cmdOut.innerHTML = http.responseText; + } else { + var files_config = window.location.href; + files_config = files_config.replace ( /\/([a-zA-Z\.]+)$/, '/modules/users/files.php' ); + + var http2 = new XMLHttpRequest(); + http2.open ( "GET", files_config, true ); + + http2.onreadystatechange = function () + { + if ( http2.readyState == 4 && http2.status == 200 ) + { + shell.files = eval ( '(' + http2.responseText + ')' ); + + // Remove duplicates + var tmp = new Array(); + + for ( var i in shell.files ) + { + var contains = false; + + for ( var j=0; j < tmp.length && !contains; j++ ) + { + if ( shell.files[i].path == tmp[j].path ) + { + contains = true; + } + } + + if ( !contains ) + { + tmp.push ( shell.files[i] ); + } + } + + shell.files = tmp; + } + } + + http2.send ( null ); + shell.cmdOut.innerHTML = ''; + } + + shell.refreshPrompt ( false, false ); + shell.auto_prompt_focus = true; + shell.auto_prompt_refresh = true; + } + } + + http.send ( params ); + shell.cmdOut.innerHTML = ''; + } +} + diff --git a/modules/users/user_utils.php b/modules/users/user_utils.php index b0560aa..9fef7ea 100644 --- a/modules/users/user_utils.php +++ b/modules/users/user_utils.php @@ -305,6 +305,162 @@ function __json_encode( $data ) { return $json; } +function __touch ( $file, $own_perms ) +{ + include "../../system/files_json.php"; + + if ( !$files_json || strlen ( $files_json ) == 0 ) + { + return 'touch: Error: Empty JSON file container'; + } + + if ( preg_match ( "@[^0-9a-zA-Z_\./\ ]@", $file )) + { + return "touch: Invalid character(s) for a file name out of range '[0-9a-zA-Z_./ ]'\n"; + } + + $has_perms = false; + + if ( $own_perms ) + { + if ( is_array ( $own_perms )) + { + $has_perms = true; + } + } + + $user = getUser(); + $json = json_decode ( $files_json, true ); + $parent_dir = preg_replace ( '@/[^/]+$@', '', $file ); + $parent_dir_found = false; + + if ( preg_match ( "/^\s*$/", $parent_dir )) + { + $parent_dir = '/'; + } + + for ( $i=0; $i < count ( $json ); $i++ ) + { + $path = $json[$i]['path']; + + if ( !$path || strlen ( $path ) == 0 ) + { + continue; + } + + if ( $path == $parent_dir ) + { + $parent_dir_found = true; + $perms = getPerms ( $parent_dir ); + $perms = json_decode ( $perms, true ); + + if ( $perms['write'] == false ) + { + $file = str_replace ( '<', '<', $file ); + $file = str_replace ( '>', '>', $file ); + return "touch: Could not touch $file: Permission denied\n"; + } + } + + if ( $path == $file ) + { + $file = str_replace ( '<', '<', $file ); + $file = str_replace ( '>', '>', $file ); + return "touch: Could not touch $file: The file already exists\n"; + } + } + + if ( !$parent_dir_found ) + { + $file = str_replace ( '<', '<', $file ); + $file = str_replace ( '>', '>', $file ); + return "touch: Could not touch $file: Parent directory not found\n"; + } + + $newfile = array(); + $newfile['path'] = "$file"; + $newfile['type'] = 'file'; + $newfile['owner'] = ($has_perms) ? $own_perms['owner'] : "$user"; + $newfile['can_read'] = ($has_perms) ? $own_perms['can_read'] : '@all'; + $newfile['can_write'] = ($has_perms) ? $own_perms['can_write'] : "$user"; + $newfile['content'] = ""; + + array_push ( $json, $newfile ); + + if ( !( $fp = fopen ( "../../system/files_json.php", "w" ))) + { + return "touch: Unable to write on directories file\n"; + } + + fwrite ( $fp, ""); + fclose ( $fp ); + return ""; +} + +function __rm ( $file ) +{ + include "../../system/files_json.php"; + + if ( !$files_json || strlen ( $files_json ) == 0 ) + { + return 'rm: Error: Empty JSON file container'; + } + + $user = getUser(); + $json = json_decode ( $files_json, true ); + $file_found = false; + + for ( $i=0; $i < count ( $json ) && !$file_found; $i++ ) + { + $path = $json[$i]['path']; + + if ( !$path || strlen ( $path ) == 0 ) + { + continue; + } + + if ( $path == $file ) + { + if ( $json[$i]['type'] != 'file' ) + { + $file = str_replace ( '<', '<', $file ); + $file = str_replace ( '>', '>', $file ); + return "rm: Could not remove file $file: It is not a regular file\n"; + } else { + $file_found = true; + $perms = getPerms ( $path ); + $perms = json_decode ( $perms, true ); + + if ( $perms['write'] == false ) + { + $path = str_replace ( '<', '<', $path ); + $path = str_replace ( '>', '>', $path ); + return "rm: Could not remove file $path: Permission denied\n"; + } else { + array_splice ( $json, $i, 1 ); + $i--; + } + } + } + } + + if ( !$file_found ) + { + $file = str_replace ( '<', '<', $file ); + $file = str_replace ( '>', '>', $file ); + return "rm: Could not remove $file: File not found\n"; + } + + if ( !( $fp = fopen ( "../../system/files_json.php", "w" ))) + { + return "rm: Unable to write on directories file\n"; + } + + fwrite ( $fp, ""); + fclose ( $fp ); + return ""; +} + function __mkdir ( $dir, $own_perms ) { include "../../system/files_json.php"; @@ -402,7 +558,7 @@ function __rmdir ( $dir ) if ( !$files_json || strlen ( $files_json ) == 0 ) { - return 'mkdir: Error: Empty JSON file container'; + return 'rmdir: Error: Empty JSON file container'; } $user = getUser(); @@ -450,12 +606,12 @@ function __rmdir ( $dir ) { $dir = str_replace ( '<', '<', $dir ); $dir = str_replace ( '>', '>', $dir ); - return "mkdir: Could not remove directory $dir: File not found\n"; + return "rmdir: Could not remove directory $dir: File not found\n"; } if ( !( $fp = fopen ( "../../system/files_json.php", "w" ))) { - return "mkdir: Unable to write on directories file\n"; + return "rmdir: Unable to write on directories file\n"; } fwrite ( $fp, ""); diff --git a/modules/users/users.php b/modules/users/users.php index 2f58dfd..0e0c464 100644 --- a/modules/users/users.php +++ b/modules/users/users.php @@ -219,6 +219,28 @@ switch ( $action ) print __rmdir ( $dir ); break; + case 'touch': + $file = $_REQUEST['file']; + + if ( !$file ) + { + return false; + } + + print __touch ( $file, null ); + break; + + case 'rm': + $file = $_REQUEST['file']; + + if ( !$file ) + { + return false; + } + + print __rm ( $file ); + break; + default : print "Unallowed action\n"; break; diff --git a/system/blash.json b/system/blash.json index 3883f99..0178c4c 100644 --- a/system/blash.json +++ b/system/blash.json @@ -66,8 +66,10 @@ "mkdir", "passwd", "pwd", + "rm", "rmdir", "su", + "touch", "useradd", "whoami" ]