/
CDC-1.2b/
CDC-1.2b/src/
parent $network
object $daemon

var $root dbref 'daemon
var $root child_index 5
var $root fertile 0
var $root manager $daemon
var $root owned [$daemon]
var $root owners [$daemon]
var $root writable []
var $root readable ['parameters, 'methods, 'code]
var $network buffer `[]
var $network ip ""
var $network hostname ""
var $network port 0
var $network socket 0
var $network active 0
var $root inited 1
var $daemon current_receiver 0
var $daemon connections []
var $daemon interface 0
var $daemon timeout 0
var $daemon default_port 0

method new_connection
    var num, tmp;
    
    // we have a new connection.
    if ((sender() != this()) || (caller() != definer()))
        throw(~perm, "Invalid call to private method.");
    catch any {
        // Get a good dbref
        num = listlen(connections);
        tmp = (tostr(.dbref('symbol)) + "_") + tostr(num);
        while ((| get_objnum(tosym("connection_" + tmp)) |)) {
            num = num + 1;
            tmp = (tostr(.dbref('symbol)) + "_") + tostr(num);
        }
    
        // Create a new receiver
        current_receiver = $connection.spawn(tmp);
        current_receiver.add_writer(this());
        current_receiver.set_manager(current_receiver);
        current_receiver.initialize_connection(interface, timeout);
    
        // bind it
        (> .bind_port(.port(), current_receiver) <);
    
        // add it to the list
        connections = setadd(connections, current_receiver);
    } with handler {
        // switch (error()) {
        //    case ~bind:
        (| current_receiver.close() |);
        (| .stop_listening() |);
        rethrow(error());
    
        // }
    }
.

method connection_starting
    // called by $connection.connect()
    (> .perms(caller(), $connection) <);
    (> .new_connection() <);
.

method connection_ending
    // called by $connection.disconnect()
    (> .perms(caller(), $connection) <);
    (> .old_connection(sender()) <);
.

method old_connection
    arg obj;
    
    // called by $daemon.connection_ending
    (> .perms(sender(), 'this) <);
    connections = setremove(connections, obj);
.

method uninit_daemon
    (> .perms(caller(), $root) <);
    (> .reset_daemon() <);
    (| current_receiver.daemon_reset() |);
    interface = 0;
    current_receiver = 0;
    connections = [];
    timeout = -1;
    default_port = 0;
.

method init_daemon
    (> .perms(caller(), $root) <);
    interface = 0;
    current_receiver = 0;
    connections = [];
    timeout = -1;
    default_port = 0;
.

method reset_daemon
    arg [args];
    var c, cons;
    
    (> .perms(sender(), 'this) <);
    args = [@args, 'continue][1];
    cons = connections + (current_receiver ? [current_receiver] | []);
    for c in (cons) {
        (| c.receive("DAEMON RESET", 'daemon_reset) |);
        (| c.close() |);
    }
    current_receiver = 0;
    connections = [];
    if (args == 'continue)
        (> .new_connection() <);
.

method set_interface
    arg obj;
    
    (> .perms(sender(), 'manager) <);
    interface = obj;
.

method start_listening
    arg [port];
    
    (> .perms(sender(), 'manager) <);
    port = [@port, default_port][1];
    .set_port(port);
    .new_connection();
.

method stop_listening
    (> .perms(sender(), 'manager) <);
    (| .set_port(0) |);
    (| current_receiver.close() |);
    (| .reset_daemon('stop) |);
    (| .unbind_port(.port()) |);
.

method set_timeout
    arg seconds;
    
    (> .perms(sender(), 'manager) <);
    timeout = seconds;
.

method default_port
    return default_port;
.

method set_default_port
    arg port;
    
    (> .perms(sender(), 'manager) <);
    if (type(port) != 'integer)
        throw(~type, "Port must be submitted as an integer.");
    default_port = port;
.

method connections
    return connections;
.

method startup
    arg [args];
    var name, opt, port;
    
    catch any {
        (> .perms(caller(), $sys) <);
        name = tostr(.dbref('symbol));
        name = "-p" + substr(name, 1, ("_" in name) - 1);
        opt = name in args;
        port = (| toint(args[opt + 1]) |) || default_port;
        (| .stop_listening() |);
        .start_listening(port);
        $sys.log(((("** Starting " + (.dbref())) + " on port ") + tostr(port)) + " **");
    } with handler {
        $sys.log($parse.traceback(traceback()));
    }
.