diff --git a/js/dos/web/bash.js b/js/dos/web/bash.js new file mode 100644 index 0000000..04d47c2 --- /dev/null +++ b/js/dos/web/bash.js @@ -0,0 +1,411 @@ +/** + * Created by sbosse on 6/16/15. + * + * JS Amoeba Shell Interface and Interpreter + */ + +"use strict"; +var log = 0; +var monitor=1; +var version = '1.0'; + +var Io = require('../io'); +//Io.trace_open('/tmp/shell.trace'); +if (typeof Shell != 'object') Io.fail('No Shell object found. Abort.'); + +Io.set_args(Shell.args); +Io.set_stdout(Shell.stdout); +var argv = Io.getargs(); + +var Net = require('../network'); +var Buf = require('../buf'); +var Sch = require('../scheduler'); +var Conn = require('../connection'); +var Rpc = require('../rpc'); +var Std = require('../std'); +var Router = require('../router'); +var util = require('util'); +var Comp = require('../compat'); +var assert = Comp.assert; +var String = Comp.string; +var Array = Comp.array; +var Perv = Comp.pervasives; +var Args = Comp.args; +var Printf = Comp.printf; +var Filename = Comp.filename; +var Status = Net.Status; +var Command = Net.Command; +var Fs = require('fs'); +var Dns = require('../dns'); +var Cs = require('../capset'); +var Getenv = require('getenv'); +var Ash = require('../ash'); +var Host = require('../host'); + +var trace = Io.tracing; +var bport = 3001; +var bip = 'localhost'; +var privhostport = Net.port_name(Net.uniqport()); +var pubhostport = Net.prv2pub(privhostport); +var hport=privhostport; + +var env = Ash.Env(privhostport); +Shell.prompt=function () {return env.prompt();}; + +function fail(msg) { + Io.stderr('[BASH]: Fatal error: '+msg+'\n'); + Io.exit(0); +} +function out(msg) { + Io.stdout('[BASH]: '+msg+'\n'); +} +function warn(msg) { + Io.stderr('[BASH]: Warning: '+msg+'\n'); +} +Args.parse(argv, [ + ['-bport',1,function(val){bport=Perv.int_of_string(val)}], + ['-bip',1,function(val){bip=val}] + ]); + +var scheduler = Sch.TaskScheduler(); +scheduler.Init(); + +var conn = Conn.HttpConnection(Net.uniqport(),bip,bport); +Io.out('[BASH] Connecting to broker '+bip+':'+bport+' ..'); +conn.init(); + +var router = Router.RpcRouter(env.pubhostport); +router.connection_broker(conn); +router.monitor=0; +router.verbose=1; +var rpc = Rpc.RpcInt(router); +router.init(); +router.start(100); + +var StdInt = Std.StdInt(rpc); +var DnsInt = Dns.DnsInt(rpc); +var CsInt = Cs.CsInt(rpc); +var ash = Ash.Ash(rpc,scheduler,env); +var todo = []; +var stat,action; +var lastdnscap=undefined; + +var hostsrv = Host.HostServer(scheduler,rpc,pubhostport,privhostport); + +Args.parse(argv, [ + [['-root','-r'],1,function(val) { + var cap = Net.Parse.capability(val, 0); + if (cap != undefined) { + env.rootdir = CsInt.cs_singleton(cap.cap); + if (env.workdir == undefined) env.workdir = env.rootdir; + } + }], + [['-host','-h'],1,function(val) { + var stat,hostport; + var port = Net.Parse.port(val, 0); + if (port != undefined) { + hostport = port.port; + todo.push([ + function () { + Shell.set('hostport',Net.Print.port(hostport)); + DnsInt.dns_getrootcap(hostport, function (_stat, _cap) { + stat = _stat; + if (stat==Status.STD_OK) { + env.rootdir = CsInt.cs_singleton(_cap); + } + }) + }, + function () { + if (stat != Status.STD_OK) { + Shell.status('hoststatus',false); + Shell.status('rootstatus',false); + out('DNS_ROOT: DNS_GETROOT failed for host ' + + Net.Print.port(hostport) + ': ' + + Status.print(stat)); + } else { + Shell.status('hoststatus',true); + Shell.status('rootstatus',true); + out('DNS ROOT: '+Net.Print.capability(CsInt.cs_to_cap(env.rootdir))); + Shell.set('rootcap',Net.Print.capability(CsInt.cs_to_cap(env.rootdir))); + if (env.workdir == undefined) env.workdir = env.rootdir; + } + } + ]); + } + + }] + ]); +todo.push([ + function () { + /* + ** Was the root DNS root already set? + */ + if (env.rootdir==undefined) { + action=true; + /* + ** Get the DNS root from our embedded host server... + */ + out('Using local host server DNS...'); + Shell.set('hostport',Net.Print.port(pubhostport)); + env.rootdir = Cs.Copy.capset(hostsrv.dns.rootcs); + stat=Status.STD_OK; + } else action=false; + }, + function () { + if (action) { + action=false; + if (stat != Status.STD_OK) { + Shell.status('hoststatus',false); + Shell.status('rootstatus',false); + out('DNS_ROOT: failed for host ' + + Net.Print.port(pubhostport) + ': ' + + Status.print(stat)); + } else { + Shell.status('hoststatus',true); + Shell.status('rootstatus',true); + out('DNS ROOT: ' + Net.Print.capability(CsInt.cs_to_cap(env.rootdir))); + Shell.set('rootcap',Net.Print.capability(CsInt.cs_to_cap(env.rootdir))); + if (env.workdir == undefined) env.workdir = env.rootdir; + } + } + }, + function () { + if (env.rootdir != undefined) { + DnsInt.dns_getdefafs(env.rootdir,function(_stat,_cap) { + out('Default AFS: '+Status.print(_stat)+' is '+ Net.Print.capability(_cap)); + }) + } + }, + function () { + ash.dns.dns_rootdir=env.rootdir; + ash.dns.dns_workdir=env.workdir; + } +]); + +Shell.update=function(xname,xvalue){ + String.match(xname,[ + ['hostport',function(){ + var hostport; + hostport=Net.Parse.port(xvalue).port; + Sch.ScheduleBlock([ + function () { + //Shell.set('hostport',Net.Print.port(hostport)); + DnsInt.dns_getrootcap(hostport, function (_stat, _cap) { + stat = _stat; + if (stat==Status.STD_OK) { + env.rootdir = CsInt.cs_singleton(_cap); + ash.dns.dns_rootdir=env.rootdir; + } + }) + }, + function () { + if (stat != Status.STD_OK) { + Shell.status('hoststatus',false); + Shell.status('rootstatus',false); + out('DNS_ROOT: DNS_GETROOT failed for host ' + + Net.Print.port(hostport) + ': ' + + Status.print(stat)); + } else { + Shell.status('hoststatus',true); + Shell.status('rootstatus',true); + out('DNS ROOT: '+Net.Print.capability(CsInt.cs_to_cap(env.rootdir))); + Shell.set('rootcap',Net.Print.capability(CsInt.cs_to_cap(env.rootdir))); + env.workdir = env.rootdir; + ash.dns.dns_rootdir=env.rootdir; + ash.dns.dns_workdir=env.rootdir; + env.workpath='/'; + env.hostname=Net.Print.port(hostport); + } + } + ],function(e){ + Io.out(e); + }); + Sch.ScheduleNext(); + }], + ['rootcap',function() { + var cap = Net.Parse.capability(xvalue, 0); + if (cap != undefined) { + env.rootdir = CsInt.cs_singleton(cap.cap); + out('DNS ROOT: '+Net.Print.capability(CsInt.cs_to_cap(env.rootdir))); + env.workdir = env.rootdir; + env.workpath='/'; + ash.dns.dns_rootdir=env.rootdir; + ash.dns.dns_workdir=env.rootdir; + //env.hostname=Net.Print.port(cap.cap.cap_port); + } else { + out('DNS_ROOT: invalid capability ' + xvalue); + } + Sch.ScheduleBlock([ + function () { + if (env.rootdir != undefined) { + DnsInt.dns_getdefafs(env.rootdir,function(_stat,_cap) { + out('Default AFS: '+Status.print(_stat)+' is '+ Net.Print.capability(_cap)); + if (_stat==Status.STD_OK) { + env.defafs=_cap; + Shell.set('afscap',Net.Print.capability(_cap)); + } + }) + } + } + ],function(e){ + Io.out(e); + }); + }], + ['rootcap+',function() { + var dnscap = Net.Parse.capability(xvalue, 0); + var stat; + var dnscs; + if (dnscap != undefined) { + lastdnscap=dnscap.cap; + var name=Net.Print.port(dnscap.cap.cap_port); + dnscs = CsInt.cs_singleton(dnscap.cap); + out('Append DNS ROOT: '+Net.Print.capability(dnscap.cap)); + stat=hostsrv.append('dns',name,dnscs); + if (stat!=Status.STD_OK) out('Cannot append '+name+': '+Status.print(stat)); + stat=hostsrv.append('dns','default',dnscs); + } else { + out('DNS_ROOT: invalid capability ' + xvalue); + } + Sch.ScheduleBlock([ + function () { + if (dnscs != undefined && env.defafs==undefined) { + DnsInt.dns_getdefafs(dnscs,function(_stat,_cap) { + out('Default AFS: '+Status.print(_stat)+' is '+ Net.Print.capability(_cap)); + if (_stat==Status.STD_OK) { + env.defafs=_cap; + var name=Net.Print.port(_cap.cap_port); + var afscs = CsInt.cs_singleton(_cap); + out('Append AFS: ' + Net.Print.capability(_cap)); + stat=hostsrv.append('afs',name,afscs); + if (stat!=Status.STD_OK) out('Cannot append '+name+': '+Status.print(stat)); + Shell.set('afscap',Net.Print.capability(_cap)); + } + }) + } + } + ],function(e){ + Io.out(e); + }); + + }], + ['afscap+',function() { + var afscap = Net.Parse.capability(xvalue, 0); + var stat; + var afscs; + if (afscap != undefined) { + var name=Net.Print.port(dnscap.cap.cap_port); + afscs = CsInt.cs_singleton(afscap.cap); + out('Append AFS: '+Net.Print.capability(afscap.cap)); + stat=hostsrv.append('afs',name,afscs); + if (stat!=Status.STD_OK) out('Cannot append '+name+': '+Status.print(stat)); + } else { + out('AFS: invalid capability ' + xvalue); + } + }] + + + + ]) +}; + +if (monitor) Sch.AddTimer(300,'BASH Status Monitor',function () { + var stat; + if (conn.status==Status.STD_OK) + Shell.status('brokerstatus',true); + else + Shell.status('brokerstatus',false); + Sch.ScheduleBlock([ + function () { + stat=Status.STD_UNKNOWN; + if (env.defafs!=undefined) ash.std.std_info(env.defafs,function (_stat,_info){ + if (_stat==Status.STD_OK) { + Shell.status('afsstatus',true); + } else { + Shell.status('afsstatus',false); + } + }) + }, + function () { + stat=Status.STD_UNKNOWN; + if (lastdnscap != undefined) + ash.std.std_info(lastdnscap,function (_stat,_info){ + if (_stat==Status.STD_OK) { + Shell.status('rootstatus',true); + } else { + Shell.status('rootstatus',false); + }}); + + else if (env.rootdir!=undefined) + ash.std.std_info(CsInt.cs_to_cap(env.rootdir),function (_stat,_info){ + if (_stat==Status.STD_OK) { + Shell.status('rootstatus',true); + } else { + Shell.status('rootstatus',false); + } + }) + + } + ],function(e){ + Io.out(e); + }); + //Sch.ScheduleNext(); +}); +Shell.env=env; + +env.rootdir=DnsInt.get_rootdir(); +if(env.workdir==undefined) env.workdir=env.rootdir; + +Shell.interpreter=function (cmd,args,callback) { + var cmdline = cmd; + Array.iter(args,function(arg){ + cmdline=cmdline+' '+arg; + }); + callback(''); + ash.exec(cmdline,function(){Io.out('OK.')}); +}; + + +ash.register_action('import',function (args) { + Shell.upload(function (file,size,data) { + var buf=Buf.Buffer(); + out('Importing file '+file+' ['+size+'] ... '); + Buf.buf_put_bytes(buf,data); + ash.writefile(file,buf,function (stat,cap) { + Io.out(Status.print(stat)); + }); + }); +}); +ash.register_action('export',function (args) { + var file; + var stat; + var data,size,buf; + args=Array.tail(args); + var len=args.length; + Sch.ScheduleLoop(function(index) { + file=args[index]; + return index