638 lines
25 KiB
JavaScript
638 lines
25 KiB
JavaScript
/**
|
|
** ==================================
|
|
** OOOO OOOO OOOO O O OOOO
|
|
** O O O O O O O O O
|
|
** O O O O O O O O O
|
|
** OOOO OOOO OOOO O OOO OOOO
|
|
** O O O O O O O O O
|
|
** O O O O O O O O O
|
|
** OOOO OOOO OOOO OOOO O O OOOO
|
|
** ==================================
|
|
** BSSLAB, Dr. Stefan Bosse http://www.bsslab.de
|
|
**
|
|
** COPYRIGHT: THIS SOFTWARE, EXECUTABLE AND SOURCE CODE IS OWNED
|
|
** BY THE AUTHOR.
|
|
** 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) 2006-2016 BSSLAB
|
|
** $CREATED: 5/25/15 by sbosse.
|
|
** $VERSION: 1.2.6
|
|
**
|
|
** $INFO:
|
|
**
|
|
** DOS: Host Server
|
|
**
|
|
* The HOST Server listening on the public host port.
|
|
* Provides a simple plain DNS (one root directory) used for publishing local servers.
|
|
*
|
|
* Basic directory structure:
|
|
*
|
|
* /
|
|
* /hosts
|
|
* /domains
|
|
* /dns
|
|
*
|
|
**
|
|
** $ENDOFINFO
|
|
*/
|
|
|
|
var log = 0;
|
|
var util = require('util');
|
|
var Io = Require('com/io');
|
|
var trace = Io.tracing;
|
|
|
|
|
|
var Net = Require('dos/network');
|
|
var Rpc = Require('dos/rpc');
|
|
var Router = Require('dos/router');
|
|
var Compat = Require('com/compat');
|
|
var Perv = Compat.pervasives;
|
|
var String = Compat.string;
|
|
var Array = Compat.array;
|
|
var assert = Compat.assert;
|
|
var Sch = Require('dos/scheduler');
|
|
var Buf = Require('dos/buf');
|
|
var DnsCom = Require('dos/dns_srv_common');
|
|
var DnsEMB = Require('dos/dns_srv_emb');
|
|
var Dns = Require('dos/dns');
|
|
var Cs = Require('dos/capset');
|
|
var Status = Net.Status;
|
|
var Command = Net.Command;
|
|
var Rights = Net.Rights;
|
|
|
|
var isNodeJS = Compat.isNodeJS();
|
|
|
|
|
|
|
|
/** Create a HOST server with embedded DNS
|
|
*
|
|
* @param {rpcint} rpc
|
|
* @param {port} pubport
|
|
* @param {port} privport
|
|
* @param {string} [name]
|
|
* @param {object} [env]
|
|
* @constructor
|
|
* @typedef {{CsInt:csint,random:port,dns:dns_server,hostcap:capability,hostsdir:dns_dir,
|
|
* domains:dns_dir,dnsdir:dns_dir,thread}} hostserver~obj
|
|
* @see hostserver~obj
|
|
*/
|
|
var hostserver = function (rpc,pubport,privport,name,env) {
|
|
var self = this;
|
|
this.env=env||{};
|
|
var router = rpc.router;
|
|
this.CsInt = Cs.CsInt(rpc);
|
|
this.name=name||('HOST Server '+(router.brokerserver == undefined ? ' (Broker) ' : '')+Net.Print.port(pubport));
|
|
/*
|
|
** Simple DNS (only one root directory) table
|
|
*/
|
|
this.random=Net.uniqport();
|
|
this.dns = DnsEMB.Server(rpc);
|
|
this.dns.create_dns(pubport,privport,this.random,false,Dns.DNS_DEFAULT_COLS);
|
|
Io.out('[HOST] My host port is '+Net.Print.port(router.hostport));
|
|
Io.out('[HOST] My host name is '+this.name);
|
|
Io.out('[HOST] DNS Root is '+Net.Print.capability(this.CsInt.cs_to_cap(this.dns.rootcs)));
|
|
this.hostcap = Net.Capability(pubport,Net.Private(0,Rights.PRV_ALL_RIGHTS,this.random));
|
|
|
|
if (env) env.rootdir=this.dns.rootcs;
|
|
|
|
// Server
|
|
var main = this;
|
|
|
|
this.services = [];
|
|
this.dns_rights = [
|
|
Rights.DNS_RGT_OWNER|Rights.DNS_RGT_GROUP|Rights.DNS_RGT_OTHERS|
|
|
Rights.DNS_RGT_READ|Rights.DNS_RGT_MODIFY|Rights.DNS_RGT_DELETE|Rights.DNS_RGT_CREATE,
|
|
Rights.DNS_RGT_GROUP|Rights.DNS_RGT_OTHERS|
|
|
Rights.DNS_RGT_READ,
|
|
Rights.DNS_RGT_OTHERS|
|
|
Rights.DNS_RGT_READ
|
|
];
|
|
this.host_rights = [
|
|
Rights.HOST_INFO|Rights.HOST_READ|Rights.HOST_WRITE|Rights.HOST_EXEC,
|
|
Rights.HOST_INFO|Rights.HOST_READ|Rights.HOST_WRITE|Rights.HOST_EXEC,
|
|
Rights.HOST_INFO
|
|
];
|
|
|
|
this.afs_rights = [
|
|
Rights.AFS_RGT_ADMIN|Rights.AFS_RGT_CREATE|Rights.AFS_RGT_DESTROY|Rights.AFS_RGT_MODIFY|Rights.AFS_RGT_READ,
|
|
Rights.AFS_RGT_READ,
|
|
Rights.AFS_RGT_READ
|
|
];
|
|
|
|
/*
|
|
** Create initial directory structure...
|
|
*/
|
|
main.hostsdir=main.dns.create_dir(Dns.DNS_DEFAULT_COLS);
|
|
main.domainsdir=main.dns.create_dir(Dns.DNS_DEFAULT_COLS);
|
|
main.dnsdir=main.dns.create_dir(Dns.DNS_DEFAULT_COLS);
|
|
main.afsdir=main.dns.create_dir(Dns.DNS_DEFAULT_COLS);
|
|
|
|
main.dns.append_row(main.hostsdir,
|
|
DnsCom.Dns_row(main.name,main.dns.time(),this.host_rights,
|
|
main.CsInt.cs_singleton(main.hostcap)));
|
|
|
|
main.dns.append_row(main.dns.rootdir,DnsCom.Dns_row('hosts',main.dns.time(),this.dns_rights,
|
|
main.dns.capset_of_dir(main.hostsdir)));
|
|
main.dns.append_row(main.dns.rootdir,DnsCom.Dns_row('domains',main.dns.time(),this.dns_rights,
|
|
main.dns.capset_of_dir(main.domainsdir)));
|
|
main.dns.append_row(main.dns.rootdir,DnsCom.Dns_row('dns',main.dns.time(),this.dns_rights,
|
|
main.dns.capset_of_dir(main.dnsdir)));
|
|
main.dns.append_row(main.dns.rootdir,DnsCom.Dns_row('afs',main.dns.time(),this.dns_rights,
|
|
main.dns.capset_of_dir(main.afsdir)));
|
|
main.dns.release_dir(main.hostsdir);
|
|
main.dns.release_dir(main.domainsdir);
|
|
main.dns.release_dir(main.dnsdir);
|
|
main.dns.release_dir(main.afsdir);
|
|
|
|
self.geo={};
|
|
|
|
this.thread = function (arg) {
|
|
var thr = this;
|
|
var dying=false;
|
|
|
|
var rpcio = router.pkt_get();
|
|
|
|
this.init = function () {
|
|
Io.out('[HOST'+arg+'] Starting host server with public port ' + Net.Print.port(pubport));
|
|
router.add_port(privport);
|
|
};
|
|
|
|
this.request = function () {
|
|
Io.log((log < 1) || ('[HOST'+arg+'] waiting for a request'));
|
|
rpcio.init();
|
|
rpcio.operation = Rpc.Operation.GETREQ;
|
|
rpcio.header.h_port = privport;
|
|
rpcio.header.h_status = undefined;
|
|
rpcio.header.h_command = undefined;
|
|
rpcio.header.h_priv = undefined;
|
|
// Io.out(util.inspect(rpcio));
|
|
rpc.getreq(rpcio);
|
|
assert((rpcio.index != -1) || ('RPCIO invalid'));
|
|
};
|
|
|
|
this.service = function () {
|
|
var mem, str, used, i, service, name, path, cs, rights, ncols, cols, colnames,
|
|
found, off, mask, priv, paramn, params, stat, serviced;
|
|
|
|
Io.log((log < 1) || ('[HOST'+arg+'] service request'));
|
|
assert(rpcio.index != -1, 'RPCIO invalid');
|
|
Io.log((log < 1) || (Net.Print.header(rpcio.header)));
|
|
|
|
rpcio.pos = 0;
|
|
rpcio.header.h_status = Status.STD_OK;
|
|
var obj = Net.prv_number(rpcio.header.h_priv);
|
|
|
|
switch (rpcio.header.h_command) {
|
|
/*
|
|
** Standard Calls
|
|
*/
|
|
case Command.STD_INFO:
|
|
Io.log((log < 1) || 'hostsrv.STD_INFO ' + Net.Print.private(rpcio.header.h_priv));
|
|
Buf.buf_init(rpcio);
|
|
if (obj == 0) Buf.buf_put_string(rpcio, self.name);
|
|
else {
|
|
// It is a directory object. TODO
|
|
str = '/';
|
|
main.dns.dns_info(rpcio.header.h_priv, function (_stat, _str) {
|
|
Buf.buf_put_string(rpcio, _str);
|
|
});
|
|
}
|
|
break;
|
|
|
|
case Command.STD_AGE:
|
|
/*
|
|
** Force memory garbage collection!
|
|
*/
|
|
if (isNodeJS && global.gc != undefined) {
|
|
mem = process.memoryUsage();
|
|
var mem0 = mem;
|
|
var progress = 1000;
|
|
var count = 20;
|
|
while (count > 0 && progress >= 1000) {
|
|
global.gc();
|
|
mem = process.memoryUsage();
|
|
progress = mem0.rss - mem.rss;
|
|
if (progress < 0) progress = mem0.heapUsed - mem.heapUsed;
|
|
mem0 = mem;
|
|
count--;
|
|
}
|
|
}
|
|
else rpcio.header.h_status = Status.STD_SYSERR;
|
|
break;
|
|
|
|
case Command.STD_STATUS:
|
|
Buf.buf_init(rpcio);
|
|
str = 'Statistics\n==========\n';
|
|
if (process != undefined) {
|
|
mem = process.memoryUsage();
|
|
str = str + 'MEMORY: RSS=' + Perv.div(mem.rss, 1024) + ' HEAP=' + Perv.div(mem.heapTotal, 1024) +
|
|
' USED=' + Perv.div(mem.heapUsed, 1024) + ' kB\n';
|
|
}
|
|
str = str + router.status()+'\n';
|
|
Buf.buf_put_string(rpcio, str);
|
|
break;
|
|
|
|
case Command.STD_LOCATION:
|
|
break;
|
|
|
|
case Command.STD_RESTRICT:
|
|
/*
|
|
* ----------
|
|
* mask (int16)
|
|
* ----------
|
|
* priv (privat)
|
|
* ----------
|
|
*/
|
|
Io.log((log < 1) || 'hostsrv.STD_RESTRICT ' + Net.Print.private(rpcio.header.h_priv));
|
|
mask=Buf.buf_get_int16(rpcio);
|
|
Buf.buf_init(rpcio);
|
|
priv=Net.restrict(rpcio.header.h_priv,mask,main.random);
|
|
if (priv!=undefined) {
|
|
Buf.buf_put_priv(rpcio,priv);
|
|
rpcio.header.h_status=Status.STD_OK;
|
|
} else rpcio.header.h_status=Status.STD_SYSERR;
|
|
break;
|
|
|
|
case Command.STD_SETPARAMS:
|
|
Io.log((log < 1) || 'hostsrv.STD_SETPARAMS ' + Net.Print.private(rpcio.header.h_priv));
|
|
paramn=Buf.buf_get_int16(rpcio);
|
|
params = [];
|
|
stat=Status.STD_OK;
|
|
if (paramn > 0 && paramn < 256) {
|
|
for (i = 0; i < paramn; i++) {
|
|
var pn = Buf.buf_get_string(rpcio);
|
|
var pv = Buf.buf_get_string(rpcio);
|
|
params.push([pn,pv]);
|
|
}
|
|
} else stat=Status.STD_ARGBAD;
|
|
Array.iter (params,function (param) {
|
|
String.match(param[0], [
|
|
['monitor',function () {
|
|
router.monitor=Perv.int_of_string(param[1]);
|
|
}]
|
|
])
|
|
});
|
|
Buf.buf_init(rpcio);
|
|
rpcio.header.h_status=stat;
|
|
break;
|
|
|
|
/*********************
|
|
** DNS Calls
|
|
**********************/
|
|
case Command.DNS_APPEND:
|
|
/*
|
|
* ------------
|
|
* name:string
|
|
* obj:capset
|
|
* ncols:number
|
|
* ------------
|
|
* ------------
|
|
*/
|
|
Io.log((log < 1) || 'hostsrv.DNS_APPEND ' + Net.Print.private(rpcio.header.h_priv));
|
|
name = Buf.buf_get_string(rpcio);
|
|
cs = Cs.buf_get_capset(rpcio);
|
|
ncols = Buf.buf_get_int16(rpcio);
|
|
cols = [];
|
|
for (i = 0; i < ncols; i++) {
|
|
cols.push(Dns.buf_get_rights(rpcio));
|
|
}
|
|
if (log > 1) {
|
|
Io.inspect(name);
|
|
Io.inspect(cs);
|
|
Io.inspect(cols);
|
|
}
|
|
Sch.ScheduleBlock([
|
|
function () {
|
|
main.dns.dns_append(rpcio.header.h_priv, name, cols, cs, function (_stat) {
|
|
rpcio.header.h_status = _stat;
|
|
Buf.buf_init(rpcio);
|
|
Io.log((log < 1) || ('hostsrv.DNS_APPEND returns: ' + Net.Status.print(_stat)));
|
|
});
|
|
}]);
|
|
Io.log((log < 1) || ('hostsrv.DNS_APPEND passes through'));
|
|
break;
|
|
|
|
|
|
case Command.DNS_LOOKUP:
|
|
Io.log((log < 1) || 'hostsrv.DNS_LOOKUP ' + Net.Print.private(rpcio.header.h_priv));
|
|
path = Buf.buf_get_string(rpcio);
|
|
Sch.ScheduleBlock([
|
|
function () {
|
|
main.dns.dns_lookup(rpcio.header.h_priv, path, function (_stat, _cs, _path) {
|
|
Io.log((log < 1) || ('hostsrv.DNS_LOOKUP returns: ' + Net.Status.print(_stat)));
|
|
Buf.buf_init(rpcio);
|
|
if (_stat == Status.STD_OK) {
|
|
/*
|
|
** Put the path_rest string and the capability set.
|
|
*/
|
|
Buf.buf_put_string(rpcio, _path);
|
|
Cs.buf_put_capset(rpcio, _cs);
|
|
|
|
} else {
|
|
rpcio.header.h_status = _stat;
|
|
}
|
|
});
|
|
}]);
|
|
Io.log((log < 1) || ('hostsrv.DNS_LOOKUP passes through'));
|
|
break;
|
|
|
|
case Command.DNS_RENAME:
|
|
/*
|
|
* ------------
|
|
* oldname:string
|
|
* newname:string
|
|
* ------------
|
|
* ------------
|
|
*/
|
|
Io.log((log < 1) || 'hostsrv.DNS_RENAME ' + Net.Print.private(rpcio.header.h_priv));
|
|
name = Buf.buf_get_string(rpcio);
|
|
var newname = Buf.buf_get_string(rpcio);
|
|
Sch.ScheduleBlock([
|
|
function () {
|
|
main.dns.dns_rename(rpcio.header.h_priv, name, newname, function (_stat) {
|
|
Buf.buf_init(rpcio);
|
|
rpcio.header.h_status = _stat;
|
|
});
|
|
}]);
|
|
break;
|
|
|
|
case Command.DNS_DELETE:
|
|
/*
|
|
* ------------
|
|
* rowname:string
|
|
* ------------
|
|
* ------------
|
|
*/
|
|
Io.log((log < 1) || ('hostsrv.DNS_DELETE ' + Net.Print.private(rpcio.header.h_priv)));
|
|
name = Buf.buf_get_string(rpcio);
|
|
Sch.ScheduleBlock([
|
|
function () {
|
|
main.dns.dns_delete(rpcio.header.h_priv, name, function (_stat) {
|
|
Buf.buf_init(rpcio);
|
|
rpcio.header.h_status = _stat;
|
|
});
|
|
}]);
|
|
break;
|
|
|
|
case Command.DNS_CREATE:
|
|
/*
|
|
* -----
|
|
* ncols(int16)
|
|
* [colname(string)] #ncols
|
|
* -----
|
|
* cs(capset)
|
|
* -----
|
|
*/
|
|
Io.log((log < 1) || 'hostsrv.DNS_CREATE ' + Net.Print.private(rpcio.header.h_priv));
|
|
ncols = Buf.buf_get_int16(rpcio);
|
|
colnames = [];
|
|
for (i = 0; i < ncols; i++) {
|
|
colnames.push(Buf.buf_get_string(rpcio));
|
|
}
|
|
Sch.ScheduleBlock([
|
|
function () {
|
|
main.dns.dns_create(rpcio.header.h_priv, colnames, function (_stat, _cs) {
|
|
Buf.buf_init(rpcio);
|
|
rpcio.header.h_status = _stat;
|
|
if (_stat == Status.STD_OK) {
|
|
Cs.buf_put_capset(rpcio, _cs);
|
|
}
|
|
});
|
|
}]);
|
|
break;
|
|
|
|
case Command.DNS_LIST:
|
|
/*
|
|
* --------------
|
|
* rowoff(int16)
|
|
* ---------------
|
|
* next_row(int16)
|
|
* ncols(int16)
|
|
* nrows(int16)
|
|
* colnames: [name(string)] #ncols
|
|
* rows: [
|
|
* name(string)
|
|
* time(int32)
|
|
* [rights(int16)] #ncols
|
|
* ] #nrows
|
|
* --------------
|
|
*/
|
|
Io.log((log < 1) || 'hostsrv.DNS_LIST ' + Net.Print.private(rpcio.header.h_priv));
|
|
off = Buf.buf_get_int16(rpcio);
|
|
rpcio.pos = 0;
|
|
Sch.ScheduleBlock([
|
|
function () {
|
|
main.dns.dns_list(rpcio.header.h_priv, off, 1000,
|
|
function (_stat, nrows, ncols, colnames, rows) {
|
|
rpcio.header.h_status = _stat;
|
|
Buf.buf_init(rpcio);
|
|
if (_stat == Status.STD_OK) {
|
|
Buf.buf_put_int16(rpcio, Dns.DNS_NOMOREROWS);
|
|
Buf.buf_put_int16(rpcio, ncols);
|
|
Buf.buf_put_int16(rpcio, nrows);
|
|
/*
|
|
** Push the column names
|
|
*/
|
|
Array.iter(colnames, function (col) {
|
|
Buf.buf_put_string(rpcio, col);
|
|
});
|
|
/*
|
|
** Assumption: all rows fit in one transaction
|
|
*/
|
|
Array.iter(rows, function (row, index) {
|
|
Buf.buf_put_string(rpcio, row[0]);
|
|
Buf.buf_put_int32(rpcio, row[1]);
|
|
Array.iter(row[2], function (col, index) {
|
|
Dns.buf_put_rights(rpcio, col);
|
|
});
|
|
});
|
|
}
|
|
});
|
|
}]);
|
|
break;
|
|
|
|
case Command.DNS_SETLOOKUP:
|
|
/*
|
|
* ------------
|
|
* nrows(int16)
|
|
* [
|
|
* dir(capset)
|
|
* name(string)
|
|
* ] #nrows
|
|
* ------------
|
|
* [
|
|
* status(int16)
|
|
* cs(capset)
|
|
* ] #nrows
|
|
* ------------
|
|
*/
|
|
Io.log((log < 1) || 'hostsrv.DNS_SETLOOKUP ' + Net.Print.private(rpcio.header.h_priv));
|
|
var nrows = Buf.buf_get_int16(rpcio);
|
|
var dirs=[];
|
|
for(i=0;i<nrows;i++) {
|
|
cs=Cs.buf_get_capset(rpcio);
|
|
name=Buf.buf_get_string(rpcio);
|
|
dirs.push([cs,name]);
|
|
}
|
|
Sch.ScheduleBlock([
|
|
function () {
|
|
main.dns.dns_setlookup(rpcio.header.h_priv, dirs, function (_stat, _rows) {
|
|
rpcio.header.h_status = _stat;
|
|
Buf.buf_init(rpcio);
|
|
Array.iter(_rows, function (statcs) {
|
|
Buf.buf_put_int16(statcs[0]);
|
|
Cs.buf_put_capset(statcs[1]);
|
|
});
|
|
})
|
|
}
|
|
]);
|
|
break;
|
|
|
|
case Command.DNS_GETROOT:
|
|
/*
|
|
* -------------
|
|
* -------------
|
|
* cap(capability)
|
|
* -------------
|
|
*/
|
|
|
|
Io.log((log < 1) || ('hostsrv.DNS_GETROOT: ' + Cs.Print.capset(main.dns.rootcs)));
|
|
Buf.buf_init(rpcio);
|
|
Sch.ScheduleBlock([
|
|
function () {
|
|
/*
|
|
** Return a read-only restricted capability set.
|
|
*/
|
|
main.dns.restrict(main.dns.rootcs, Rights.DNS_RGT_OTHERS + Rights.DNS_RGT_READ,
|
|
function (_stat, _cs) {
|
|
if (_stat == Status.STD_OK) {
|
|
Buf.buf_put_cap(rpcio, main.CsInt.cs_to_cap(_cs));
|
|
}
|
|
rpcio.header.h_status = _stat;
|
|
});
|
|
}
|
|
]);
|
|
break;
|
|
|
|
default:
|
|
rpcio.header.h_status=Status.STD_COMBAD;
|
|
loop: for(i in self.services) {
|
|
service=self.services[i];
|
|
if (service(rpcio)) break loop;
|
|
}
|
|
}
|
|
};
|
|
|
|
this.reply = function () {
|
|
Io.log((log < 1) || ('[HOST'+arg+'] service reply '+Rpc.Print.rpcio(rpcio)));
|
|
assert((rpcio.index != -1) || ('RPCIO invalid'));
|
|
Io.log((log < 1) || ('[HOST'+arg+'] reply ' + Net.Print.header(rpcio.header)));
|
|
rpc.putrep(rpcio);
|
|
};
|
|
|
|
this.terminate = function () {
|
|
Io.log((log < 1) || ('[HOST] terminating'));
|
|
};
|
|
|
|
|
|
this.transitions = function () {
|
|
var trans;
|
|
trans =
|
|
[
|
|
[undefined, this.init, function (thr) {
|
|
return true
|
|
}],
|
|
[this.init, this.request, function (thr) {
|
|
return true
|
|
}],
|
|
[this.request, this.service, function (thr) {
|
|
return true
|
|
}],
|
|
[this.service, this.reply, function (thr) {
|
|
return true
|
|
}],
|
|
[this.reply, this.request, function (thr) {
|
|
return !dying
|
|
}],
|
|
[this.reply, this.terminate, function (thr) {
|
|
return dying
|
|
}]
|
|
];
|
|
return trans;
|
|
};
|
|
this.context = Sch.TaskContext(main.name+' #'+arg, thr);
|
|
};
|
|
};
|
|
|
|
/**
|
|
*
|
|
* @param {string} dirname
|
|
* @param {string} rowname
|
|
* @param {capset} rowcs
|
|
*/
|
|
hostserver.prototype.append = function (dirname,rowname,rowcs) {
|
|
var main=this;
|
|
var stat = Status.STD_NOTFOUND;
|
|
String.match(dirname,[
|
|
['dns',function () {
|
|
if (main.dns.search_row(main.dnsdir,rowname) != undefined) {
|
|
stat= Status.STD_EXISTS;
|
|
} else {
|
|
main.dns.append_row(main.dnsdir, DnsCom.Dns_row(rowname, main.dns.time(), main.dns_rights, rowcs));
|
|
stat = Status.STD_OK;
|
|
}
|
|
}],
|
|
['afs',function () {
|
|
if (main.dns.search_row(main.afsdir,rowname) != undefined) {
|
|
stat = Status.STD_EXISTS;
|
|
} else {
|
|
main.dns.append_row(main.afsdir, DnsCom.Dns_row(rowname, main.dns.time(), main.afs_rights, rowcs));
|
|
stat = Status.STD_OK;
|
|
}
|
|
}]
|
|
]);
|
|
return stat;
|
|
};
|
|
/** Extend the service function and register a new command service handler.
|
|
*
|
|
* @param {function(rpcio):boolean} fun
|
|
*
|
|
*/
|
|
hostserver.prototype.register = function (fun) {
|
|
this.services.push(fun);
|
|
};
|
|
|
|
hostserver.prototype.get_geo = function (geo) {
|
|
return this.geo;
|
|
}
|
|
|
|
hostserver.prototype.set_geo = function (geo) {
|
|
this.geo=geo;
|
|
}
|
|
|
|
|
|
module.exports = {
|
|
/**
|
|
*
|
|
* @param {taskscheduler} scheduler
|
|
* @param {rpcint} rpc
|
|
* @param {port} pubport
|
|
* @param {port} privport
|
|
* @param {string} [name]
|
|
* @param {{}} env
|
|
* @returns {hostserver}
|
|
*/
|
|
HostServer: function(scheduler,rpc,pubport,privport,name,env) {
|
|
var srv = new hostserver(rpc,pubport,privport,name,env);
|
|
for(var i=0;i<4;i++) {
|
|
var proc = new srv.thread(i);
|
|
scheduler.Add(proc.context);
|
|
}
|
|
return srv;
|
|
}
|
|
};
|
|
|