mirror of
https://codeberg.org/TicklishHoneyBee/CLIte.git
synced 2026-03-11 09:04:37 +00:00
shell macros, start of commands (ls,cat)
This commit is contained in:
parent
148b1dc133
commit
c38dd412e7
4 changed files with 423 additions and 50 deletions
|
|
@ -1,9 +1,135 @@
|
|||
clite.commands.data = function() {
|
||||
// insert commands below this line
|
||||
|
||||
clite.commands.load('ls',function(args) {
|
||||
clite.log.write('hello world (l)');
|
||||
clite.shell.writeLine('hello world (s)');
|
||||
clite.commands.load('help',function(args,env,io) {
|
||||
io.write('yeah, I should probably implement this');
|
||||
return 0;
|
||||
});
|
||||
|
||||
clite.commands.load('ls',function(args,env,io) {
|
||||
var dirs = [];
|
||||
var long = false;
|
||||
function help() {
|
||||
io.write(`
|
||||
Usage: ls [OPTION] [FILE]
|
||||
|
||||
Options:
|
||||
-? Print this help information
|
||||
-l Display data in long format
|
||||
`);
|
||||
}
|
||||
|
||||
function writeNodeData(node) {
|
||||
if (long) {
|
||||
io.write(node.perms+'\t'+node.uid+'\t'+node.gid+'\t'+node.name);
|
||||
}else{
|
||||
io.write(node.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]);
|
||||
}
|
||||
}
|
||||
}else if (args[i][0] == '/') {
|
||||
dirs.push(args[i]);
|
||||
}else{
|
||||
dirs.push(clite.lib.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 = clite.io.open(dir);
|
||||
if (!fd) {
|
||||
io.error('cannot open directory: '+dir);
|
||||
return;
|
||||
}
|
||||
if (!fd.node.data.isdir) {
|
||||
writeNodeData(fd.node);
|
||||
clite.io.close(fd);
|
||||
return;
|
||||
}
|
||||
var e;
|
||||
while ((e = clite.io.read(fd)) != null) {
|
||||
writeNodeData(e);
|
||||
}
|
||||
clite.io.close(fd);
|
||||
});
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
clite.commands.load('cat',function(args,env,io) {
|
||||
var files = [];
|
||||
var pending = 0;
|
||||
|
||||
for (var i=1; i<args.length; i++) {
|
||||
if (args[i][0] == '-') {
|
||||
io.error('unknown argument: '+args[i]);
|
||||
}else if (args[i][0] == '/') {
|
||||
files.push(args[i]);
|
||||
}else{
|
||||
files.push(clite.lib.resolvePath(args[i],false));
|
||||
}
|
||||
}
|
||||
|
||||
if (files.length < 1)
|
||||
return 1;
|
||||
pending = files.length;
|
||||
|
||||
function fcb(fd) {
|
||||
if (fd.node.data.isdir || fd.node.data.islink || fd.node.data.isdev) {
|
||||
io.error('not a normal file: '+file);
|
||||
}else{
|
||||
var d = clite.io.readAll(fd);
|
||||
if (d != null) {
|
||||
io.write(d);
|
||||
}
|
||||
}
|
||||
pending--;
|
||||
clite.io.close(fd);
|
||||
if (pending <1)
|
||||
io.exit(0);
|
||||
}
|
||||
|
||||
files.forEach(function(file,index) {
|
||||
var fd = clite.io.open(file,fcb);
|
||||
if (!fd) {
|
||||
io.error('cannot open file: '+file);
|
||||
pending--;
|
||||
return;
|
||||
}
|
||||
if (fd.node.data.isdir || fd.node.data.islink || fd.node.data.isdev) {
|
||||
io.error('not a normal file: '+file);
|
||||
pending--;
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
if (pending <1)
|
||||
return 0;
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
clite.commands.load('download',function(args,env,io) {
|
||||
return 0;
|
||||
});
|
||||
|
||||
// insert commands above this line
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
html,body {margin:0; padding:0; overflow:auto; width:100%; height:100%; background-color:#000000; color:#FFFFFF; font-family:monospace; font-size:14px;}
|
||||
body {}
|
||||
body {display:flex; flex-direction: column;}
|
||||
|
||||
div, header, section, article, p, form, h1 {display:block; margin:0; padding:0;}
|
||||
header {padding:10px;}
|
||||
header h1 {line-height:40px; font-size:30px;}
|
||||
section {}
|
||||
section.content {}
|
||||
section.content div#terminal {border: 1px solid #FFFFFF; width:100%; min-width: 500px; max-width:1000px; margin:10px auto; overflow:hidden; min-height:100px; padding:10px;}
|
||||
section.content {flex-grow:1;}
|
||||
section.content div#terminal {width:100%; min-width: 500px; max-width:1000px; margin:0 auto; overflow:hidden; height:100%; min-height:100px;}
|
||||
section.content article {unicode-bidi: embed; white-space: pre;}
|
||||
section.content form {}
|
||||
section.content form label, section.content form input, section.content form input:focus {display:block; float:left; border:none; margin:0; padding:0; font-family:monospace; font-size:14px; line-height:20px; background-color:#000000; color:#FFFFFF; outline:none;}
|
||||
|
|
|
|||
331
clite/core.js
331
clite/core.js
|
|
@ -150,7 +150,6 @@ var clite = {
|
|||
return;
|
||||
f.perms = '-r-xr-xr-x';
|
||||
f.data.content = fn;
|
||||
clite.log.write('loaded ('+name+')');
|
||||
}
|
||||
}
|
||||
clite.core.load.script('clite/commands.js',function() {
|
||||
|
|
@ -158,14 +157,24 @@ var clite = {
|
|||
clite.commands = null;
|
||||
// check cookies for login
|
||||
clite.log.write('Checking for user session');
|
||||
if (clite.user.init()) {// if logged in:
|
||||
if (clite.user.init(vfsapi)) {// if logged in:
|
||||
clite.log.write('found user session?');
|
||||
// create user session
|
||||
}else{// if new user:
|
||||
clite.log.write('Generating guest session');
|
||||
// read in /usr/share/introduction and write to shell
|
||||
var fd = clite.io.open('/usr/share/introduction',function(fd) {
|
||||
clite.user.genGuest();
|
||||
if (!fd)
|
||||
return;
|
||||
var d = clite.io.readAll(fd);
|
||||
if (d != null)
|
||||
clite.shell.writeLine(d);
|
||||
clite.io.close(fd);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
clite.log.write('Creating Shell');
|
||||
clite.events.refocus();
|
||||
}); // end command load callback
|
||||
}); // end filesys load callback
|
||||
|
||||
|
|
@ -174,7 +183,51 @@ var clite = {
|
|||
};
|
||||
|
||||
clite.user = {
|
||||
init:function() { // returns true if there's a user login or false for guest
|
||||
init:function(vfs) { // returns true if there's a user login or false for guest
|
||||
var udata = {
|
||||
name:'root',
|
||||
uid:0,
|
||||
group:0,
|
||||
groups:[]
|
||||
};
|
||||
clite.user.getUID = function() {
|
||||
return udata.uid;
|
||||
}
|
||||
clite.user.getGID = function() {
|
||||
return udata.gid;
|
||||
}
|
||||
clite.user.checkGID = function(gid) {
|
||||
if (gid == udata.gid)
|
||||
return true;
|
||||
if (udata.groups.indexOf(gid) > -1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
function setLogin(user,uid,gid,groups) {
|
||||
udata.name = user;
|
||||
udata.uid = uid;
|
||||
udata.group = gid;
|
||||
udata.groups = groups;
|
||||
clite.shell.env.HOME = '/usr/home/'+user;
|
||||
clite.shell.env.PWD = '/usr/home/'+user;
|
||||
clite.shell.env.USER = user;
|
||||
clite.shell.prompt.generate();
|
||||
clite.user.hasLogin = function() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
clite.user.genGuest = function() {
|
||||
clite.term.clear();
|
||||
vfs.mkDir('/usr/home/guest');
|
||||
var n = vfs.getNode('/usr/home/guest');
|
||||
if (n) {
|
||||
n.perms = '-rwx------';
|
||||
n.uid = 1;
|
||||
n.gid = 1;
|
||||
}
|
||||
setLogin('guest',1,1,[]);
|
||||
clite.events.refocus();
|
||||
}
|
||||
return false;
|
||||
},
|
||||
getUID:function() { // get the user's user id
|
||||
|
|
@ -185,7 +238,11 @@ clite.user = {
|
|||
},
|
||||
checkGID:function(gid) { // check if the user is in a group
|
||||
return true;
|
||||
}
|
||||
},
|
||||
hasLogin:function() { // check if we're in a user session
|
||||
return false;
|
||||
},
|
||||
genGuest:null
|
||||
};
|
||||
|
||||
clite.io = {
|
||||
|
|
@ -223,7 +280,7 @@ clite.io = {
|
|||
}
|
||||
};
|
||||
|
||||
function getFileDes(path,link) {
|
||||
function getFileDes(path,link,cb) {
|
||||
var n = vfsapi.getNode(path);
|
||||
if (!n)
|
||||
return null;
|
||||
|
|
@ -238,19 +295,24 @@ clite.io = {
|
|||
canexec:false,
|
||||
remote:{
|
||||
ispending:p,
|
||||
callback:null
|
||||
callback:cb
|
||||
}
|
||||
});
|
||||
if (p)
|
||||
if (p) {
|
||||
clite.core.load.file(n.data.remote,function(d) {
|
||||
n.data.content = d;
|
||||
fd.remote.ispending = false;
|
||||
try{
|
||||
fd.remote.callback(fd);
|
||||
} catch(err) {}
|
||||
});
|
||||
}
|
||||
fd.canread = perms.checkReadable(fd.node.perms,fd.node.uid,fd.node.gid);
|
||||
fd.canwrite = perms.checkWritable(fd.node.perms,fd.node.uid,fd.node.gid);
|
||||
fd.canexec = perms.checkExecutable(fd.node.perms,fd.node.uid,fd.node.gid);
|
||||
if (!p && cb != null) {
|
||||
clite.core.execSafeAsync(function() {cb(fd);});
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
clite.io.creat = function(path,type) {
|
||||
|
|
@ -265,8 +327,8 @@ clite.io = {
|
|||
return vfsapi.mkFile(path);
|
||||
}
|
||||
}
|
||||
clite.io.open = function(path) {
|
||||
return getFileDes(path,false);
|
||||
clite.io.open = function(path,cb) {
|
||||
return getFileDes(path,false,cb);
|
||||
}
|
||||
clite.io.close = function(fd) {
|
||||
try{
|
||||
|
|
@ -299,6 +361,9 @@ clite.io = {
|
|||
fd.pos += l.length;
|
||||
return l;
|
||||
}
|
||||
clite.io.readAll = function(fd) {
|
||||
return fd.node.data.content;
|
||||
}
|
||||
clite.io.write = function(fd,data) {
|
||||
if (!fd.canwrite)
|
||||
return false;
|
||||
|
|
@ -327,7 +392,7 @@ clite.io = {
|
|||
return true;
|
||||
}
|
||||
clite.io.truncate = function(path,len) {
|
||||
var fd = getFileDes(path,false);
|
||||
var fd = getFileDes(path,false,null);
|
||||
if (!fd)
|
||||
return false;
|
||||
var r = clite.io.ftruncate(fd,len);
|
||||
|
|
@ -347,15 +412,15 @@ clite.io = {
|
|||
return fd.pos;
|
||||
}
|
||||
clite.io.remove = function(path) {
|
||||
var fd = getFileDes(path,true);
|
||||
var fd = getFileDes(path,true,null);
|
||||
if (!fd || !fd.canwrite)
|
||||
return false;
|
||||
return vfsapi.remove(path);
|
||||
}
|
||||
clite.io.link = function(path,target) {
|
||||
if (!getFileDes(target,false))
|
||||
if (!getFileDes(target,false,null))
|
||||
return false;
|
||||
var fd = getFileDes(path,true);
|
||||
var fd = getFileDes(path,true,null);
|
||||
if (fd) {
|
||||
if (!fd.canwrite)
|
||||
return false;
|
||||
|
|
@ -370,6 +435,7 @@ clite.io = {
|
|||
close:null,
|
||||
read:null,
|
||||
readLine:null,
|
||||
readAll:null,
|
||||
write:null,
|
||||
ftruncate:null,
|
||||
truncate:null,
|
||||
|
|
@ -394,14 +460,20 @@ clite.vfs = {
|
|||
}
|
||||
}
|
||||
function checkCanOpen(node) {
|
||||
return true;
|
||||
if (node.perms[7] == 'r')
|
||||
return true;
|
||||
if (clite.user.checkGID(node.gid) && node.perms[4] == 'r')
|
||||
return true;
|
||||
if (node.uid == clite.user.getUID() && node.perms[1] == 'r')
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
function mkNode() {
|
||||
var fsnode = {
|
||||
name: '',
|
||||
uid: 0,
|
||||
gid: 0,
|
||||
perms:'-rw-r-----',
|
||||
perms:'-rw-r--r--',
|
||||
data:{
|
||||
remote:null,
|
||||
isdir:false,
|
||||
|
|
@ -421,8 +493,9 @@ clite.vfs = {
|
|||
vfsdata.fs.perms[0] = 'd';
|
||||
|
||||
clite.vfs.getApi = function() {
|
||||
// TODO: only allow for the root user
|
||||
return vfsdata.api;
|
||||
if (clite.user.getUID() == 0)
|
||||
return vfsdata.api;
|
||||
return null;
|
||||
}
|
||||
|
||||
vfsdata.api.getNode = function(path) {
|
||||
|
|
@ -467,8 +540,9 @@ clite.vfs = {
|
|||
n.data.parent = parent;
|
||||
n.data.content = [];
|
||||
n.data.isdir = true;
|
||||
n.perms[0] = 'd';
|
||||
// TODO: set uid/gid/permissions
|
||||
n.perms = 'drwxr-xr-x';
|
||||
n.uid = clite.user.getUID();
|
||||
n.gid = clite.user.getGID();
|
||||
parent.data.content.push(n);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -487,7 +561,9 @@ clite.vfs = {
|
|||
n.name = name;
|
||||
n.data.parent = parent;
|
||||
n.data.content = '';
|
||||
// TODO: set uid/gid/permissions
|
||||
n.perms = '-rw-r--r--';
|
||||
n.uid = clite.user.getUID();
|
||||
n.gid = clite.user.getGID();
|
||||
parent.data.content.push(n);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -506,9 +582,10 @@ clite.vfs = {
|
|||
n.name = name;
|
||||
n.data.parent = parent;
|
||||
n.data.islink = true;
|
||||
n.perms[0] = 'l';
|
||||
n.data.content = target;
|
||||
// TODO: set uid/gid/permissions
|
||||
n.perms = 'lrwxr-xr-x';
|
||||
n.uid = clite.user.getUID();
|
||||
n.gid = clite.user.getGID();
|
||||
parent.data.content.push(n);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -539,14 +616,11 @@ clite.vfs = {
|
|||
clite.log = {
|
||||
init:function(vfs) {
|
||||
clite.log.write = function(txt) {
|
||||
// TODO: after login don't write to term or shell
|
||||
try {
|
||||
if (clite.term.hasInput()) {
|
||||
clite.shell.writeLine(txt);
|
||||
}else{
|
||||
if (!clite.user.hasLogin()) {
|
||||
try {
|
||||
clite.term.writeLine(txt);
|
||||
}
|
||||
} catch(e) {}
|
||||
} catch(e) {}
|
||||
}
|
||||
var n = vfs.getNode('/var/logs');
|
||||
if (n)
|
||||
n.data.content += txt+'\n';
|
||||
|
|
@ -648,24 +722,39 @@ clite.term = {
|
|||
};
|
||||
|
||||
clite.shell = {
|
||||
exit:function(v) {
|
||||
clite.shell.prompt.pop();
|
||||
clite.events.refocus();
|
||||
},
|
||||
readLine:function(cb) {
|
||||
},
|
||||
writeLine:function(txt) {
|
||||
clite.term.writeLine(txt);
|
||||
clite.events.refocus();
|
||||
},
|
||||
exec:function(txt) {
|
||||
// TODO: split this better
|
||||
var args = txt.split(' ');
|
||||
// TODO: resolve using PATH
|
||||
var path = '/bin/'+args[0];
|
||||
resolvePath:function(txt) {
|
||||
// TODO: resolve using PATH (check each colon separated path)
|
||||
return clite.lib.resolvePath(txt,clite.shell.env.PATH)
|
||||
},
|
||||
exec:function(args,io) {
|
||||
var path = clite.shell.resolvePath(args[0]);
|
||||
var fd = clite.io.open(path);
|
||||
// TODO: should errors here write to stderr? (io.error)
|
||||
if (!fd) {
|
||||
clite.shell.writeLine('Shell: unknown command: '+args[0]);
|
||||
clite.term.writeLine('Shell: unknown command: '+args[0]);
|
||||
io.exit(-1);
|
||||
return;
|
||||
}
|
||||
if (!clite.core.execSafe(function() {fd.node.data.content(args)}))
|
||||
clite.shell.writeLine('Shell: error in command:'+args[0]);
|
||||
|
||||
var r = clite.core.execSafe(function() {
|
||||
var rr = fd.node.data.content(args,Object.create(clite.shell.env),io);
|
||||
if (typeof rr == 'number')
|
||||
io.exit(rr);
|
||||
});
|
||||
if (!r) {
|
||||
clite.term.writeLine('Shell: error in command:'+args[0]);
|
||||
io.exit(-1);
|
||||
}
|
||||
clite.io.close(fd);
|
||||
},
|
||||
parse:function(txt) {
|
||||
|
|
@ -676,13 +765,108 @@ clite.shell = {
|
|||
clite.shell.history.add(txt);
|
||||
clite.shell.history.resetCurrent();
|
||||
clite.shell.writeLine(clite.shell.prompt.getHTML()+txt);
|
||||
clite.shell.prompt.push('');
|
||||
clite.term.preventInput();
|
||||
// ready stdio (stdout,stdin)
|
||||
var stdio = {
|
||||
error:clite.term.writeLine,
|
||||
write:clite.term.writeLine,
|
||||
read:clite.shell.readLine,
|
||||
exit:clite.shell.exit,
|
||||
istty:true
|
||||
};
|
||||
// check for a macro
|
||||
var args = clite.lib.strToArgs(txt);
|
||||
// then either run the macro or expand the program to be executed via PATH
|
||||
clite.shell.exec(txt);
|
||||
if (typeof clite.shell.macro[args[0]] != 'undefined') {
|
||||
var r = clite.shell.macro[args[0]](args,stdio);
|
||||
clite.shell.exit(r);
|
||||
}else{
|
||||
clite.shell.exec(args,stdio);
|
||||
}
|
||||
},
|
||||
env:{
|
||||
USER:'root',
|
||||
PWD:'/',
|
||||
HOME:'/',
|
||||
PATH:'/bin'
|
||||
},
|
||||
macro:{
|
||||
clear:function(args,io) {
|
||||
clite.term.clear();
|
||||
},
|
||||
cd:function(args,io) {
|
||||
var dir = clite.shell.env.HOME;
|
||||
if (args.length > 1) {
|
||||
dir = clite.lib.resolvePath(args[1]);
|
||||
}
|
||||
var fd = clite.io.open(dir);
|
||||
if (!fd) {
|
||||
io.error('invalid directory: '+dir);
|
||||
return;
|
||||
}
|
||||
clite.io.close(fd);
|
||||
clite.shell.env.PWD = dir;
|
||||
clite.shell.prompt.generate();
|
||||
},
|
||||
pwd:function(args,io) {
|
||||
io.write(clite.shell.env.PWD);
|
||||
},
|
||||
echo:function(args,io) {
|
||||
args.shift();
|
||||
var txt = args.join(' ');
|
||||
io.write(txt);
|
||||
},
|
||||
which:function(args,io) {
|
||||
if (args.length <2)
|
||||
return;
|
||||
if (typeof clite.shell.macro[args[1]] != 'undefined') {
|
||||
return;
|
||||
}else{
|
||||
var path = clite.shell.resolvePath(args[1]);
|
||||
var fd = clite.io.open(path);
|
||||
if (!fd)
|
||||
return;
|
||||
clite.io.close(fd);
|
||||
io.write(args[1]+' is '+path);
|
||||
}
|
||||
},
|
||||
type:function(args,io) {
|
||||
if (args.length <2)
|
||||
return;
|
||||
if (typeof clite.shell.macro[args[1]] != 'undefined') {
|
||||
io.write(args[1]+' is a shell builtin');
|
||||
}else{
|
||||
var path = clite.shell.resolvePath(args[1]);
|
||||
var fd = clite.io.open(path);
|
||||
if (!fd)
|
||||
return;
|
||||
clite.io.close(fd);
|
||||
io.write(args[1]+' is '+path);
|
||||
}
|
||||
},
|
||||
whoami:function(args,io) {
|
||||
io.write(clite.shell.env.USER);
|
||||
},
|
||||
alias:function(args,io) {
|
||||
io.write('unimplemented');
|
||||
},
|
||||
export:function(args,io) {
|
||||
if (args.length == 1) {
|
||||
Object.keys(clite.shell.env,function(key) {
|
||||
io.write(key+'='+clite.shell.env[key]);
|
||||
});
|
||||
return;
|
||||
}
|
||||
var parts = args[1].split('=');
|
||||
if (parts.length != 2)
|
||||
return;
|
||||
clite.shell.env[parts[0]] = parts[1];
|
||||
}
|
||||
},
|
||||
prompt:{
|
||||
list:[],
|
||||
data:'$ ',
|
||||
data:'# ',
|
||||
set:function(txt) {
|
||||
clite.shell.prompt.list = [];
|
||||
clite.shell.prompt.data = txt;
|
||||
|
|
@ -694,6 +878,15 @@ clite.shell = {
|
|||
pop:function() {
|
||||
clite.shell.prompt.data = clite.shell.prompt.list.pop();
|
||||
},
|
||||
generate:function() {
|
||||
var p = clite.shell.env.USER+':'+clite.shell.env.PWD;
|
||||
if (clite.user.getUID() == 0) {
|
||||
p += '# ';
|
||||
}else{
|
||||
p += '$ ';
|
||||
}
|
||||
clite.shell.prompt.set(p);
|
||||
},
|
||||
get:function() {
|
||||
return clite.shell.prompt.data;
|
||||
},
|
||||
|
|
@ -759,5 +952,61 @@ clite.lib = {
|
|||
var parts = txt.split('/');
|
||||
parts.pop();
|
||||
return parts.join('/');
|
||||
},
|
||||
// returns an absolute path: ('foo','/etc') -> '/etc/foo': ('foo','bar') -> $PWD/bar/foo
|
||||
resolvePath:function(txt,base) {
|
||||
if (txt[0] == '/')
|
||||
return txt;
|
||||
if (txt[0] == '~')
|
||||
return clite.shell.env.HOME+txt.substring(1);
|
||||
if (typeof base != 'string')
|
||||
base = clite.shell.env.PWD;
|
||||
if (base[0] != '/')
|
||||
base = clite.shell.env.PWD+'/'+base;
|
||||
return base+'/'+txt;
|
||||
},
|
||||
// convert a string into an argument array: 'ls /etc' -> ['ls',/etc]
|
||||
strToArgs:function(txt) {
|
||||
// TODO: split this properly (escape strings and insert env variables)
|
||||
var parts = [];
|
||||
var s = '';
|
||||
var e = false;
|
||||
var q = false;
|
||||
for (var i=0; i<txt.length; i++) {
|
||||
switch (txt[i]) {
|
||||
case '//':
|
||||
if (e) {
|
||||
s+='//';
|
||||
}else{
|
||||
e = true;
|
||||
}
|
||||
break;
|
||||
case '"':
|
||||
if (!e) {
|
||||
if (!q) {
|
||||
q = true;
|
||||
break;
|
||||
}else{
|
||||
q = false;
|
||||
}
|
||||
}else{
|
||||
s+='"';
|
||||
}
|
||||
case ' ':
|
||||
if (!q) {
|
||||
parts.push(s);
|
||||
s = '';
|
||||
e = false;
|
||||
q = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
s+=txt[i];
|
||||
e = false;
|
||||
}
|
||||
}
|
||||
if (s.length > 0)
|
||||
parts.push(s);
|
||||
return parts;//txt.split(' ');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
BEGINDATAWelcome, this site runs on Clite, the command line site management system.
|
||||
Welcome, this site runs on Clite, the command line site management system.
|
||||
Clite works like a Unix terminal, a guest login will be automatically generated for you.
|
||||
Clite has many Unix-like commands for navigating the website, simply type in a command and press enter to run it.
|
||||
Not sure how this works? Use the `help' command at any time.
|
||||
|
||||
Press Enter to begin.
|
||||
|
|
|
|||
Loading…
Reference in a new issue