mirror of
https://codeberg.org/TicklishHoneyBee/CLIte.git
synced 2026-03-11 09:04:37 +00:00
494 lines
9.2 KiB
JavaScript
494 lines
9.2 KiB
JavaScript
clite.commands.data = function() {
|
|
// insert commands below this line
|
|
|
|
clite.commands.load('help',function(args,env,io) {
|
|
if (args.length > 1) {
|
|
// TODO: implement command help lookup
|
|
io.write('help with arguments is a work in progress');
|
|
}
|
|
io.write(`
|
|
Welcome to CLIte (pronounced like 'site' with an added L).
|
|
|
|
Various unix-like commands are available for navigating the CLIte shell:
|
|
|
|
ls - list directory contents
|
|
cat - concatenate files and print to std output or local file
|
|
touch - create a new file
|
|
less - simple text file viewer
|
|
file - determines the file type
|
|
|
|
Under Development:
|
|
view - file viewer
|
|
edit - text file editor
|
|
|
|
Running any command with the argument -? will give you help for that program.
|
|
Or you can run help <command> to get the same info.
|
|
|
|
As a basic guide for guests:
|
|
Use ls to see what content is available, eg: ls web
|
|
Use view or less to view the content, eg: view web/about
|
|
|
|
`);
|
|
return 0;
|
|
});
|
|
|
|
clite.commands.load('ls',function(args,env,io) {
|
|
var dirs = [];
|
|
var long = false;
|
|
var stdlib = io.include('stdlib');
|
|
var stdio = io.include('stdio');
|
|
function help() {
|
|
io.write(`
|
|
ls - list directory contents
|
|
Usage: ls [OPTION] [FILE]
|
|
|
|
Options:
|
|
-? Print this help information
|
|
-l Display data in long format
|
|
`);
|
|
}
|
|
|
|
function writeNodeData(st,fd) {
|
|
if (long) {
|
|
if (st.type == stdio.types.FT_LINK) {
|
|
var d = stdio.readAll(fd);
|
|
if (!d)
|
|
d = '?';
|
|
io.write(st.perms+'\t'+st.uid+'\t'+st.gid+'\t'+st.name+' -> '+d);
|
|
}else{
|
|
io.write(st.perms+'\t'+st.uid+'\t'+st.gid+'\t'+st.name);
|
|
}
|
|
}else{
|
|
io.write(st.name);
|
|
}
|
|
}
|
|
|
|
for (var i=1; i<args.length; i++) {
|
|
if (args[i][0] == '-') {
|
|
for (var j=1; j<args[i].length; j++) {
|
|
switch (args[i][j]) {
|
|
case '?':
|
|
help();
|
|
return 0;
|
|
break;
|
|
case 'l':
|
|
long = true;
|
|
break;
|
|
default:
|
|
io.error('unknown argument: -'+args[i][j]);
|
|
}
|
|
}
|
|
}else{
|
|
dirs.push(stdlib.resolvePath(args[i],false));
|
|
}
|
|
}
|
|
|
|
if (dirs.length < 1)
|
|
dirs.push(env.PWD);
|
|
|
|
dirs.forEach(function(dir,index) {
|
|
if (dirs.length > 1)
|
|
io.write(dir+':');
|
|
var fd = stdio.open(dir,false);
|
|
if (!fd) {
|
|
io.error('cannot open directory: '+dir);
|
|
return;
|
|
}
|
|
var st = stdio.fstat(fd);
|
|
if (!st || st.type != stdio.types.FT_DIR) {
|
|
writeNodeData(st,fd);
|
|
stdio.close(fd);
|
|
return;
|
|
}
|
|
var e;
|
|
while ((e = stdio.read(fd)) != null) {
|
|
var efd = stdio.open(dir+'/'+e,false,true);
|
|
if (!efd) {
|
|
io.error('cannot read contents: '+dir);
|
|
break;
|
|
}
|
|
var est = stdio.fstat(efd);
|
|
if (!est) {
|
|
stdio.close(efd);
|
|
io.error('cannot read contents: '+dir);
|
|
break;
|
|
}
|
|
writeNodeData(est,efd);
|
|
stdio.close(efd);
|
|
}
|
|
stdio.close(fd);
|
|
});
|
|
|
|
return 0;
|
|
});
|
|
|
|
clite.commands.load('cat',function(args,env,io) {
|
|
var files = [];
|
|
var download = false;
|
|
var pending = 0;
|
|
var stdlib = io.include('stdlib');
|
|
var stdio = io.include('stdio');
|
|
|
|
function help() {
|
|
io.write(`
|
|
cat - concatenate files and print to std output or local file
|
|
Usage: cat [OPTION] <FILE> [FILE]
|
|
|
|
Options:
|
|
-? Print this help information
|
|
-d Download the file data, instead of printing it
|
|
`);
|
|
}
|
|
|
|
for (var i=1; i<args.length; i++) {
|
|
if (args[i][0] == '-') {
|
|
for (var j=1; j<args[i].length; j++) {
|
|
switch (args[i][j]) {
|
|
case '?':
|
|
help();
|
|
return 0;
|
|
break;
|
|
case 'd':
|
|
download = true;
|
|
break;
|
|
default:
|
|
io.error('unknown argument: -'+args[i][j]);
|
|
}
|
|
}
|
|
}else{
|
|
files.push(stdlib.resolvePath(args[i],false));
|
|
}
|
|
}
|
|
|
|
if (files.length < 1)
|
|
return 1;
|
|
pending = files.length;
|
|
|
|
function fcb(fd) {
|
|
var st = stdio.fstat(fd);
|
|
// check if it's a directory or link
|
|
if (!st || st.type == stdio.types.FT_DIR || st.type == stdio.types.FT_LINK) {
|
|
if (st) {
|
|
io.error('not a normal file: '+st.name);
|
|
}else{
|
|
io.error('not a normal file');
|
|
}
|
|
}else{
|
|
var d = stdio.readAll(fd);
|
|
if (d != null) {
|
|
if (download) {
|
|
var ld = stdio.open('/dev/local',false);
|
|
if (ld) {
|
|
stdio.write(ld,{name:st.name,data:d});
|
|
stdio.close(ld);
|
|
}else{
|
|
io.error('can not write to local device');
|
|
}
|
|
}else{
|
|
io.write(d);
|
|
}
|
|
}
|
|
}
|
|
pending--;
|
|
stdio.close(fd);
|
|
if (pending <1)
|
|
io.exit(0);
|
|
}
|
|
|
|
files.forEach(function(file,index) {
|
|
var st = stdio.stat(file);
|
|
// check if it's a directory or link
|
|
if (!st || st.type == stdio.types.FT_DIR || st.type == stdio.types.FT_LINK) {
|
|
io.error('not a normal file: '+file);
|
|
pending--;
|
|
return;
|
|
}
|
|
var fd = stdio.open(file,fcb);
|
|
if (!fd) {
|
|
io.error('cannot open file: '+file);
|
|
pending--;
|
|
return;
|
|
}
|
|
});
|
|
|
|
if (pending <1)
|
|
return 0;
|
|
|
|
return null;
|
|
});
|
|
|
|
clite.commands.load('touch',function(args,env,io) {
|
|
var file = null;
|
|
var stdlib = io.include('stdlib');
|
|
var stdio = io.include('stdio');
|
|
function help() {
|
|
io.write(`
|
|
touch - create a new empty file
|
|
Usage: touch [OPTION] <FILE>
|
|
|
|
Options:
|
|
-? Print this help information
|
|
`);
|
|
}
|
|
|
|
for (var i=1; i<args.length; i++) {
|
|
if (args[i][0] == '-') {
|
|
for (var j=1; j<args[i].length; j++) {
|
|
switch (args[i][j]) {
|
|
case '?':
|
|
help();
|
|
return 0;
|
|
break;
|
|
default:
|
|
io.error('unknown argument: -'+args[i][j]);
|
|
}
|
|
}
|
|
}else if (file == null) {
|
|
file = stdlib.resolvePath(args[i],false);
|
|
}else{
|
|
io.error('unknown argument: '+args[i]);
|
|
}
|
|
}
|
|
|
|
if (file == null) {
|
|
io.error('no file specified');
|
|
return 1;
|
|
}
|
|
|
|
function loadRemote(fd) {
|
|
if (!fd) {
|
|
io.error('unable to create file: '+file);
|
|
io.exit(1);
|
|
return;
|
|
}
|
|
io.exit(0);
|
|
}
|
|
|
|
if (!stdio.creat(file)) {
|
|
var fd = stdio.open(file,loadRemote);
|
|
return null;
|
|
}
|
|
|
|
return 0;
|
|
});
|
|
|
|
clite.commands.load('less',function(args,env,io) {
|
|
var stdlib = io.include('stdlib');
|
|
var stdio = io.include('stdio');
|
|
var term = io.include('term');
|
|
var file = null;
|
|
|
|
function help() {
|
|
io.write(`
|
|
less - text file viewer
|
|
Usage: less [OPTION] <FILE>
|
|
|
|
Options:
|
|
-? Print this help information
|
|
`);
|
|
}
|
|
|
|
for (var i=1; i<args.length; i++) {
|
|
if (args[i][0] == '-') {
|
|
for (var j=1; j<args[i].length; j++) {
|
|
switch (args[i][j]) {
|
|
case '?':
|
|
help();
|
|
return 0;
|
|
break;
|
|
default:
|
|
io.error('unknown argument: -'+args[i][j]);
|
|
}
|
|
}
|
|
}else if (file == null) {
|
|
file = stdlib.resolvePath(args[i],false);
|
|
}else{
|
|
io.error('unknown argument: '+args[i]);
|
|
}
|
|
}
|
|
|
|
if (file == null) {
|
|
io.error('no file specified');
|
|
return 1;
|
|
}
|
|
|
|
var lines = [];
|
|
var topLine = 0;
|
|
var bottomLine = 0;
|
|
|
|
function showAt(line) {
|
|
var start = line;
|
|
var end = line+tty.lines;
|
|
if (end > lines.length)
|
|
end = lines.length;
|
|
tty.clear();
|
|
for (var i=start; i<end; i++) {
|
|
tty.draw(lines[i]+'\n');
|
|
}
|
|
}
|
|
|
|
function prepFile(fd) {
|
|
if (!fd) {
|
|
io.error('could not open file: '+file);
|
|
io.exit(1);
|
|
return;
|
|
}
|
|
var t = stdlib.getFileType(fd);
|
|
if (t != 1 && t != 7) {
|
|
io.error('can not read files of this type');
|
|
io.exit(1);
|
|
return;
|
|
}
|
|
var txt = stdio.readAll(fd);
|
|
stdio.close(fd);
|
|
|
|
var parts = txt.split('\n');
|
|
parts.forEach(function(line) {
|
|
if (line.length > tty.chars) {
|
|
var sects = line.match(new RegExp('(.{1,'+tty.chars+'})','g'));
|
|
lines.push.apply(lines,sects);
|
|
return;
|
|
}
|
|
lines.push(line);
|
|
});
|
|
|
|
bottomLine = (lines.length-tty.lines);
|
|
|
|
showAt(0);
|
|
}
|
|
|
|
var fd = stdio.open(file,prepFile);
|
|
if (!fd) {
|
|
io.error('could not open file: '+file);
|
|
io.exit(1);
|
|
return;
|
|
}
|
|
|
|
var tty = term.createTTY();
|
|
tty.setRaw(false);
|
|
|
|
tty.handleKeys(function(e) {
|
|
switch (e.key) {
|
|
case 'Escape':
|
|
case 'q':
|
|
term.closeTTY(tty);
|
|
io.exit(0);
|
|
break;
|
|
case 'Up':
|
|
case 'ArrowUp':
|
|
if (topLine > 0) {
|
|
topLine--;
|
|
showAt(topLine);
|
|
}
|
|
break;
|
|
case 'Down':
|
|
case 'ArrowDown':
|
|
if (topLine < bottomLine) {
|
|
topLine++;
|
|
showAt(topLine);
|
|
}
|
|
break;
|
|
}
|
|
});
|
|
tty.draw('Loading...');
|
|
|
|
return null;
|
|
});
|
|
|
|
clite.commands.load('view',function(args,env,io) {
|
|
io.write('view is under development');
|
|
return 0;
|
|
});
|
|
|
|
clite.commands.load('edit',function(args,env,io) {
|
|
io.write('edit is under development');
|
|
return 0;
|
|
});
|
|
|
|
clite.commands.load('file',function(args,env,io) {
|
|
var short = '';
|
|
var file = null;
|
|
var stdlib = io.include('stdlib');
|
|
var stdio = io.include('stdio');
|
|
function help() {
|
|
io.write(`
|
|
file - determine type of FILE
|
|
Usage: touch [OPTION] [FILE]
|
|
|
|
Options:
|
|
-? Print this help information
|
|
`);
|
|
}
|
|
|
|
for (var i=1; i<args.length; i++) {
|
|
if (args[i][0] == '-') {
|
|
for (var j=1; j<args[i].length; j++) {
|
|
switch (args[i][j]) {
|
|
case '?':
|
|
help();
|
|
return 0;
|
|
break;
|
|
default:
|
|
io.error('unknown argument: -'+args[i][j]);
|
|
}
|
|
}
|
|
}else if (file == null) {
|
|
short = args[i];
|
|
file = stdlib.resolvePath(args[i],false);
|
|
}else{
|
|
io.error('unknown argument: '+args[i]);
|
|
}
|
|
}
|
|
|
|
if (file == null) {
|
|
io.error('no file specified');
|
|
return 1;
|
|
}
|
|
|
|
var fd = stdio.open(file,false);
|
|
if (!fd) {
|
|
io.error('cannot open file: '+file);
|
|
return 1;
|
|
}
|
|
|
|
var t = stdlib.getFileType(fd);
|
|
stdio.close(fd);
|
|
|
|
var txt = short+': ';
|
|
switch (t) {
|
|
case 1:
|
|
txt += 'Plain Text';
|
|
break;
|
|
case 2:
|
|
txt += 'CLIte Executable';
|
|
break;
|
|
case 3:
|
|
txt += 'Directory';
|
|
break;
|
|
case 4:
|
|
txt += 'Link';
|
|
break;
|
|
case 5:
|
|
txt += 'Device File';
|
|
break;
|
|
case 6:
|
|
txt += 'Unloaded Remote Data';
|
|
break;
|
|
case 7:
|
|
txt += 'Shell Script';
|
|
break;
|
|
case 8:
|
|
txt += 'Image';
|
|
break;
|
|
default:
|
|
txt += 'Unknown Data';
|
|
break;
|
|
}
|
|
|
|
io.write(txt);
|
|
|
|
return 0;
|
|
});
|
|
|
|
// insert commands above this line
|
|
}
|