Mon 21 Jul 22:43:21 CEST 2025
This commit is contained in:
parent
b3cfbc069e
commit
bd72de8968
469
js/dos/appl/gc.js
Normal file
469
js/dos/appl/gc.js
Normal file
|
@ -0,0 +1,469 @@
|
|||
/**
|
||||
** ==============================
|
||||
** O O O OOOO
|
||||
** O O O O O O
|
||||
** O O O O O O
|
||||
** OOOO OOOO O OOO OOOO
|
||||
** O O O O O O O
|
||||
** O O O O O O O
|
||||
** OOOO OOOO O O OOOO
|
||||
** ==============================
|
||||
** Dr. Stefan Bosse http://www.bsslab.de
|
||||
**
|
||||
** COPYRIGHT: THIS SOFTWARE, EXECUTABLE AND SOURCE CODE IS OWNED
|
||||
** BY THE AUTHOR(S).
|
||||
** THIS SOURCE CODE MAY NOT BE COPIED, EXTRACTED,
|
||||
** MODIFIED, OR OTHERWISE USED IN A CONTEXT
|
||||
** OUTSIDE OF THE SOFTWARE SYSTEM.
|
||||
**
|
||||
** $AUTHORS: Stefan Bosse
|
||||
** $INITIAL: (C) 2015-2017 bLAB
|
||||
** $CREATED: 23.9.2016
|
||||
** $VERSION: 1.1.17
|
||||
**
|
||||
** $INFO:
|
||||
**
|
||||
** Standard Request Command Line Application
|
||||
**
|
||||
** $ENDOFINFO
|
||||
*/
|
||||
var log = 0;
|
||||
|
||||
var Io = Require('com/io');
|
||||
//Io.trace_open('/tmp/std.trace');
|
||||
|
||||
if (typeof Shell == 'object') Io.set_stdout(Shell.stdout);
|
||||
|
||||
var Net = Require('dos/network');
|
||||
var Sch = Require('dos/scheduler');
|
||||
var Conn = Require('dos/connection');
|
||||
var Std = Require('dos/std');
|
||||
var Dns = Require('dos/dns');
|
||||
var Cs = Require('dos/capset');
|
||||
var util = Require('util');
|
||||
var Comp = Require('com/compat');
|
||||
var assert = Comp.assert;
|
||||
var String = Comp.string;
|
||||
var Array = Comp.array;
|
||||
var Perv = Comp.pervasives;
|
||||
var Args = Comp.args;
|
||||
var Status = Net.Status;
|
||||
var Command = Net.Command;
|
||||
|
||||
var trace = Io.tracing;
|
||||
|
||||
var options = {
|
||||
afs : undefined,
|
||||
bip:'localhost',
|
||||
bport:3001,
|
||||
broker: true,
|
||||
caps:[],
|
||||
cmd:[Command.STD_TOUCH,Command.STD_AGE],
|
||||
default:false,
|
||||
delay:0,
|
||||
dip : 'localhost',
|
||||
dns : undefined,
|
||||
dports : [],
|
||||
echo:false,
|
||||
env:{},
|
||||
hostname:Io.hostname(),
|
||||
hostport:undefined,
|
||||
hostsrv:false,
|
||||
http:false,
|
||||
interval:1000,
|
||||
keepalive:true,
|
||||
links:[],
|
||||
maxlive:8,
|
||||
monitor:0,
|
||||
myip:'localhost',
|
||||
print : false,
|
||||
root:'/',
|
||||
run:1,
|
||||
servmode:false,
|
||||
tcpnet:1,
|
||||
verbose:0
|
||||
};
|
||||
|
||||
var help=false;
|
||||
var shift='';
|
||||
|
||||
var env={};
|
||||
options.env=env;
|
||||
var argv = Io.getargs();
|
||||
|
||||
var out = function (s) {Io.out('[GC] '+s)};
|
||||
|
||||
function err(msg) {
|
||||
out('Error: gc '+Comp.array.tail(argv,2)+' => '+msg);
|
||||
Io.exit();
|
||||
}
|
||||
|
||||
|
||||
if (typeof Shell == 'object') Io.set_args(Shell.args);
|
||||
Args.parse(argv, [
|
||||
[['-h','-help'],0,function() {help=true}],
|
||||
[['-v','-verbose'],0,function() {options.verbose++;options.echo=true}],
|
||||
[['-d','-default'],0,function() {options.default=true;}],
|
||||
['-monitor',0,function() {options.monitor++;}],
|
||||
['-print',0,function() {options.print=true;}],
|
||||
['-delay',1,function(val) {options.delay=Perv.int_of_string(val);}],
|
||||
['-interval',1,function(val) {options.interval=Perv.int_of_string(val);}],
|
||||
['-run',1,function(val) {options.run=Perv.int_of_string(val);}],
|
||||
['-dns',1,function(val) {options.dns=val;}],
|
||||
['-afs',1,function(val) {options.afs=val;}],
|
||||
['-broker',1,function(val){
|
||||
var tokens = Comp.string.split(':',val);
|
||||
if (tokens.length==1)
|
||||
options.bip=val;
|
||||
else {
|
||||
options.bip=tokens[0];
|
||||
options.bport=Perv.int_of_string(tokens[1])
|
||||
}
|
||||
}],
|
||||
['-dip',1,function(val){options.dip=val}],
|
||||
['-D',1,function(val){options.dports.push(Perv.int_of_string(val))}],
|
||||
['-L',2,function(val1,val2){options.links.push([Perv.int_of_string(val1),getip(val2),getipport(val2)])}],
|
||||
['-nokeepalive',0,function(val){options.keepalive=false;}],
|
||||
['-T',0,function(val){options.tcpnet=1;options.http=false;}],
|
||||
['-T2',0,function(val){options.tcpnet=2;options.http=false;}],
|
||||
['-H',0,function(val){options.http=true;options.tcpnet=0;}],
|
||||
['-fcap',1,function(val){options.fcap=val}],
|
||||
[function(val){
|
||||
options.dns=val;
|
||||
}]
|
||||
],2);
|
||||
|
||||
|
||||
if (help) {
|
||||
Io.out('usage: '+argv[0]+' [<DNS server>]'+argv[1]);
|
||||
Io.out(' [-H -T -T2] Enable connection service');
|
||||
Io.out(' T: TCPIP, 1-ch H:HTTP T2: TCPIP, 2-ch');
|
||||
Io.out(' H: bport, T: bport+100');
|
||||
Io.out(' (Default: -T)');
|
||||
Io.out(' [-D <port>] UDP Server Port');
|
||||
Io.out(' [-L <src port> <UDP dst [address:]port] UDP P2P Connection');
|
||||
Io.out(' [-nokeepalive] Establish a new conncetion for each message.');
|
||||
Io.out(' [-broker <ip[:ipport]>] Broker URL (Default: '+options.bip+': HTTP '+options.bport+' TCPNET '+(options.bport+100)+')');
|
||||
Io.out(' [-dip <VLC UDP server IP>] (Default: '+options.dip+')');
|
||||
Io.out(' [-help -h -v -verbose -monitor]');
|
||||
Io.out(' [-delay <millisec>] Start-up delay');
|
||||
Io.out(' [-interval <millisec>] Loop interval');
|
||||
Io.out(' [-root <path>] DNS Root path (default '+options.root+')');
|
||||
Io.out(' [-afs <capfile|cap>] AFS server capability');
|
||||
Io.out(' [-dns <capfile|cap>] DNS server capability');
|
||||
Io.out(' [-run <number of service loop runs>] 0:infinite loop');
|
||||
Io.out(' [-default -d] Ask broker server for default DNS');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
options.privhostport = Net.uniqport();
|
||||
options.pubhostport = Net.prv2pub(options.privhostport);
|
||||
|
||||
if (options.echo) out('['+Net.Print.port(options.pubhostport)+'] '+argv[1]+' '+
|
||||
(options.cmd[0]?Command.print(options.cmd[0]):'')+
|
||||
(options.cmd[1]?' '+Command.print(options.cmd[1]):'')+ ' ' + options.caps);
|
||||
|
||||
var scheduler = Sch.TaskScheduler();
|
||||
scheduler.Init();
|
||||
//scheduler.log(2);
|
||||
|
||||
|
||||
|
||||
// Set-up the network environment ..
|
||||
// typeof options : {http,tcpnet,dports,bip,bport,myip,verbose}
|
||||
var network = Conn.setup(options);
|
||||
|
||||
var StdInt = Std.StdInt(network.rpc);
|
||||
var DnsInt = Dns.DnsInt(network.rpc);
|
||||
var CsInt = Cs.CsInt(network.rpc);
|
||||
|
||||
var cap;
|
||||
if (env.rootdir) {
|
||||
DnsInt.set_rootdir(env.rootdir);
|
||||
}
|
||||
|
||||
|
||||
var schedules=[];
|
||||
|
||||
var stat,data;
|
||||
|
||||
function action () {
|
||||
var aged,
|
||||
cap,
|
||||
cs,
|
||||
csnew,
|
||||
capp,
|
||||
dir,
|
||||
error,
|
||||
failed0,
|
||||
path,
|
||||
remain,
|
||||
row,
|
||||
rowi,
|
||||
rows,
|
||||
stat=Status.STD_UNKNOWN,
|
||||
touched=0,
|
||||
trash=[],
|
||||
n;
|
||||
|
||||
function statcb(_stat) {stat=_stat};
|
||||
function resolve (name,cb) {
|
||||
var cap,cp;
|
||||
if (env.rootdir) {
|
||||
/*
|
||||
** Look-up from DNS ...
|
||||
*/
|
||||
DnsInt.dns_lookup(env.rootdir,name,function (_stat,_cs) {
|
||||
if (_stat==Status.STD_OK) cb(_stat,CsInt.cs_to_cap(_cs));
|
||||
else cb(_stat);
|
||||
})
|
||||
} else if (Io.exists(name)) {
|
||||
/*
|
||||
** It is a capability file
|
||||
*/
|
||||
cap = Net.cap_of_file(name);
|
||||
if (cap) {
|
||||
env.rootdir=options.dns=CsInt.cs_singleton(cap);
|
||||
cb(Status.STD_OK,cap);
|
||||
} else {
|
||||
err('Invalid capability file: '+name);
|
||||
}
|
||||
|
||||
} else {
|
||||
/*
|
||||
** Is it a capability string?
|
||||
*/
|
||||
cp=Net.Parse.capability(name,0);
|
||||
if (cp==undefined) {
|
||||
/*
|
||||
** It is a port string?
|
||||
*/
|
||||
cp=Net.Parse.port(name,0);
|
||||
if (cp!=undefined) {
|
||||
cap=Net.Capability(cp.port);
|
||||
}
|
||||
} else {
|
||||
cap=cp.cap;
|
||||
}
|
||||
if (cp==undefined) {
|
||||
err('Invalid capability or port: '+name);
|
||||
}
|
||||
env.rootdir=options.dns=CsInt.cs_singleton(cap);
|
||||
cb(Status.STD_OK,cap);
|
||||
}
|
||||
}
|
||||
path=options.root;
|
||||
|
||||
function scan (rootcs,path) {
|
||||
var stat=Status.STD_UNKNOWN,
|
||||
remain,dir,cs,msg,info,
|
||||
entry;
|
||||
function statcb(_stat,_msg) {stat=_stat;msg=_msg;};
|
||||
function err(msg) {out(msg); failed++; error=Status.STD_NOTNOW;};
|
||||
B([
|
||||
function () {
|
||||
if (options.verbose) out('Scanning '+path+', root='+Cs.Print.capset(rootcs));
|
||||
DnsInt.dns_list(rootcs,function (_stat,_dir) {
|
||||
stat=_stat; dir=_dir;
|
||||
});
|
||||
},
|
||||
function () {
|
||||
rowi=0;
|
||||
if (stat==Status.STD_OK)
|
||||
L(
|
||||
function (index) {rowi=index; return index<dir.di_rows.length},
|
||||
[
|
||||
function () {
|
||||
// console.log(rows[index].name);
|
||||
// console.log(dir.di_rows[rowi])
|
||||
error=false;
|
||||
entry=path+(path=='/'?'':'/')+
|
||||
dir.di_rows[rowi].de_name;
|
||||
DnsInt.dns_lookup(rootcs,dir.di_rows[rowi].de_name,function (_stat,_cs){
|
||||
stat=_stat;
|
||||
cs=_cs;
|
||||
})
|
||||
},
|
||||
function () {
|
||||
if (stat==Status.STD_OK) {
|
||||
// get info
|
||||
cap=CsInt.cs_to_cap(cs);
|
||||
if (cap) StdInt.std_info(cap,statcb);
|
||||
} else if (!error) {
|
||||
err('DNS lookup of '+entry+' failed: '+Status.print(stat));
|
||||
}
|
||||
|
||||
},
|
||||
function () {
|
||||
if (stat==Status.RPC_FAILURE) {
|
||||
if (trash[entry]==undefined) trash[entry]=options.maxlive;
|
||||
else {
|
||||
trash[entry]--;
|
||||
if (trash[entry]==0) {
|
||||
out('Deleting '+entry);
|
||||
DnsInt.dns_delete(rootcs,dir.di_rows[rowi].de_name,function (stat) {
|
||||
if (stat!=Status.STD_OK)
|
||||
err(entry+' not deleted: '+Status.print(stat));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (stat==Status.STD_OK) {
|
||||
// touch it
|
||||
info=msg;
|
||||
if (cap) StdInt.std_touch(cap,statcb);
|
||||
if (trash[entry]!=undefined) trash[entry]=undefined;
|
||||
} else if (!error)
|
||||
err(entry+' not responding: '+Status.print(stat));
|
||||
},
|
||||
function () {
|
||||
if (stat==Status.STD_OK) {
|
||||
touched++;
|
||||
if (options.verbose) out('Touched '+entry);
|
||||
if (info && Comp.string.startsWith(info,'/D'))
|
||||
scan(cs,entry);
|
||||
} else if (!error)
|
||||
err('Touching of '+entry+' failed: '+Status.print(stat));
|
||||
|
||||
}
|
||||
],
|
||||
[
|
||||
function () {}
|
||||
],
|
||||
function (stat) {console.log(stat)}
|
||||
);
|
||||
else
|
||||
out('DNS list of '+path+' failed: '+Status.print(stat));
|
||||
|
||||
}
|
||||
]);
|
||||
}
|
||||
L(
|
||||
function(index) {n=index; return options.run==0?true:index<options.run;},
|
||||
[
|
||||
function () {
|
||||
if (options.verbose) out('Run '+n+' ..');
|
||||
touched=0;
|
||||
failed=0;
|
||||
error=Status.STD_OK;
|
||||
},
|
||||
function () {
|
||||
stat=Status.STD_NOTNOW;
|
||||
cap=CsInt.cs_to_cap(env.rootdir);
|
||||
if (cap) StdInt.std_touch(cap,statcb);
|
||||
},
|
||||
function () {
|
||||
if (stat==Status.STD_OK) scan(env.rootdir,path);
|
||||
else error=stat;
|
||||
},
|
||||
function () {
|
||||
if (error) return;
|
||||
// age it
|
||||
if (options.verbose) out(' [touched='+touched+', failed='+failed+']');
|
||||
if (options.verbose) out('Aging (I) '+Net.Print.capability(options.dns));
|
||||
if (failed==0) {
|
||||
StdInt.std_age(options.dns,statcb);
|
||||
aged++;
|
||||
} else {
|
||||
stat=Status.STD_NOTNOW;
|
||||
error=stat;
|
||||
}
|
||||
},
|
||||
function () {
|
||||
if (error) return;
|
||||
error=stat;
|
||||
if (stat!=Status.STD_OK) {
|
||||
out('Aging (I) failed: '+Status.print(stat));
|
||||
}
|
||||
},
|
||||
function () {
|
||||
if (error) return;
|
||||
if (stat==Status.STD_OK && options.afs) {
|
||||
if (options.verbose) out('Aging (II) '+Net.Print.capability(options.afs));
|
||||
StdInt.std_age(options.afs,statcb);
|
||||
}
|
||||
},
|
||||
function () {
|
||||
if (!error && options.afs && stat!=Status.STD_OK) {
|
||||
out('Aging (II) failed: '+Status.print(stat));
|
||||
error=stat;
|
||||
}
|
||||
// if (stat!=Status.STD_OK || error) throw stat;
|
||||
if (error) out('Run '+n+' failed: '+Status.print(error));
|
||||
Sch.Delay(options.interval)
|
||||
}
|
||||
],
|
||||
[
|
||||
function () {
|
||||
out('Exiting.');
|
||||
process.exit(0)
|
||||
}
|
||||
],
|
||||
function (stat) {
|
||||
out('Failed: '+Status.print(stat));
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
B([
|
||||
function () {
|
||||
if (options.delay) Delay(options.delay);
|
||||
},
|
||||
function () {
|
||||
out('Starting ..');
|
||||
resolve(options.dns||options.root,function (_stat,cap) {
|
||||
if (_stat==Status.STD_OK) {
|
||||
out('Using DNS cap '+Net.Print.capability(cap));
|
||||
options.dns=cap;
|
||||
} else {
|
||||
out('No DNS resolved!: '+Status.print(_stat));
|
||||
}
|
||||
stat=_stat;
|
||||
});
|
||||
},
|
||||
function () {
|
||||
if (stat!=Status.STD_OK) throw stat;
|
||||
if (options.afs) resolve(options.afs,function (stat,cap) {
|
||||
if (stat==Status.STD_OK) {
|
||||
out('Using AFS cap '+Net.Print.capability(cap));
|
||||
options.afs=cap;
|
||||
}
|
||||
});
|
||||
else if (options.dns) DnsInt.dns_getdefafs(env.rootdir,function (stat,cap) {
|
||||
if (stat==Status.STD_OK) {
|
||||
out('Using default AFS cap '+Net.Print.capability(cap));
|
||||
options.afs=cap;
|
||||
}
|
||||
});
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
action ();
|
||||
|
||||
var hostsrv;
|
||||
if (options.hostsrv)
|
||||
hostsrv = HostSrv.HostServer(scheduler,
|
||||
network.rpc,
|
||||
options,
|
||||
'GC.'+options.hostname,
|
||||
options.env);
|
||||
|
||||
|
||||
var interrupt=0;
|
||||
|
||||
process.on('SIGINT', function () {
|
||||
out('Got SIGINT ..');
|
||||
interrupt++;
|
||||
if (interrupt>1) process.exit(2);
|
||||
});
|
||||
|
||||
|
||||
if (options.verbose) out('My host port: '+Net.Print.port(options.pubhostport));
|
||||
|
||||
|
||||
// Start up the network ..
|
||||
network.init(network.start);
|
||||
|
||||
scheduler.Run();
|
Loading…
Reference in New Issue
Block a user