parent $root
object $sys
var $sys admins []
var $sys exit_starting_room $void
var $root child_index 1
var $root owners [$sys]
var $root fertile 0
var $root inited 1
var $sys agents [$sys, $housekeeper, $scheduler, $root, $daemon, $user, $backdoor]
var $sys startup #[['time, 794116991], ['objects, [$login_daemon, $http_daemon, $finger_daemon, $backdoor]], ['heartbeat_interval, 5]]
var $sys starting #[['quota, 75000], ['exit_source, $void], ['place, $creation], ['new_user_class, $admin], ['anonymous_user_class, $guest]]
var $root owned [$sys]
var $sys server_address ["127.0.0.1", "localhost"]
var $root manager $sys
var $root writable [$sys]
var $root readable ['parameters, 'methods, 'code]
var $root info ["The system object has special server-granted permissions, and performs tasks which require these permisions. It receives the 'heartbeat message, as well as being pivitol in such tasks as generating new connections and creating objects."]
var $root dbref 'sys
var $sys system_email_addresses #[['default, "[email not set]"]]
var $sys core_version "1.2"
var $sys validate_email_addresses 1
var $sys load #[['load, "0.0, 0.0, 0.0"]]
var $sys next_pulse 794119075
var $sys backup #[['interval, 3600], ['last, 794117896], ['next, 794121496]]
method startup
arg args;
var opt, str, obj;
args = sublist(args, 3);
catch any {
if (sender() != 0)
throw(~perm, "Sender is not the server.");
// Set up five-second heartbeat.
set_heartbeat(startup['heartbeat_interval]);
// set the startup time, reset backup time.
startup = startup.add('time, time());
backup = backup.add('next, time() + (backup['interval]));
// tell objects who should know, that we are up.
for obj in (startup['objects]) {
.log(("Calling " + (obj.dbref())) + ".startup()");
(| obj.startup(@args) |);
}
} with handler {
.log(("Startup ERROR at " + ctime()) + ":");
.log($parse.traceback(traceback(), -1, ""));
}
.
method server_info
arg what, [long];
var tmp;
switch (what) {
case 'up_time:
return time() - (startup['time]);
case 'startup_time:
return startup['time];
case 'server_hostname:
return server_address[2];
case 'server_ip:
return server_address[1];
case 'load:
return .load();
case 'last_backup:
return backup['last];
case 'driver_version:
tmp = version();
return (((((long ? "ColdX " | "") + tostr(tmp[1])) + ".") + tostr(tmp[2])) + "-") + tostr(tmp[3]);
case 'core_version:
return (long ? "the Cold Dark Core " | "") + core_version;
default:
throw(~unknown, "Unknown flag.");
}
.
method callers
(> .perms(sender(), 'system) <);
return (> callers() <);
.
method create_user
arg name, password, email, [type];
var user;
if ((!(| .perms(caller(), $login_interface) |)) && (!(| .perms(sender(), 'system) |)))
throw(~perm, "Caller and Sender are not allowed to call this method.");
type = [@type, 'new_user_class][1];
catch any {
user = (starting[type]).spawn(name);
user.set_name(name);
if (type == 'new_user_class)
user.set_password(password);
else
user.set_password(crypt(substr(crypt("", substr(name, 1, 2)), 1, random(13))) + "12");
user.set_manager(user);
user.set_data('email, email, 0);
user.chown([user]);
} with handler {
// Failed to initialize the child; destroy it.
if (!(| user.destroy() |)) {
(| user.uninitialize() |);
(| del_dbref(user.dbref('symbol)) |);
(| del_dbref(tosym(name)) |);
(| destroy(user) |);
}
rethrow(error());
}
return user;
.
method admins
return admins;
.
method is_admin
arg obj;
return (obj == $sys) || (obj in admins);
.
method binary_dump
if (!($sys.is_admin(sender())))
throw(~perm, "Sender is not an admin.");
return binary_dump();
.
method shutdown
arg [why];
var line1, line2;
if ((!($sys.is_admin(sender()))) || (definer() != this()))
throw(~perm, "Sender is not an admin.");
why = [@why, ""][1];
// tell everybody everything
line1 = "*** SHUTDOWN called by " + (sender().namef('ref));
if (why) {
line1 = line1 + " because:";
line2 = ("*** " + why) + " ***";
}
.log(line1 + " ***");
$channels.announce('all, line1 + " ***");
if (why) {
.log(line2);
$channels.announce('all, line2);
}
return shutdown();
.
method change_sender_parents
arg parents;
var p;
if (caller() != $root)
throw(~perm, "Caller is not $root.");
(> chparents(sender(), parents) <);
.
method spawn_sender
arg suffix, manager, [owners];
var namestr;
(> .perms(caller(), $root, $sys) <);
if (!owners)
owners = [manager];
namestr = (tostr(sender().dbref('symbol)) + "_") + suffix;
return .create([sender()], tosym(namestr), manager, owners);
.
method assign_dbref
arg name;
var keepers, x;
(> .perms(caller(), $root, $sys) <);
if (type(name) != 'symbol)
throw(~type, "Name must be given as a symbol.");
// don't run this for now--tosym is fucked.
if (0) {
// yeah, we change it to a string, but they don't have to know that.
name = tostr(name);
// lowercase all names:
name = lowercase(name);
// If it isn't a keeper toss the good old error
keepers = "abcdefghijklmnopqrstuvwxyz1234567890_";
for x in [1 .. strlen(name)] {
if (!((name[x]) in keepers))
throw(~type, "Name has one or more non-alphanumeric characters.");
}
name = tosym(name);
}
// make sure nobody has it yet
if ((| get_objnum(name) |) != ~namenf)
throw(~perm, "Name already assigned to " + (get_objnum(name).namef('ref)));
// woo woo, i'm filled with joy, lets give them the name.
add_dbref(name, sender());
.
method destroy_sender
(> .perms(caller(), $root) <);
(| .deassign_dbref(sender().dbref('symbol)) |);
(> destroy(sender()) <);
.
method is_system
arg obj;
return (obj in admins) || ((obj in agents) || (obj.has_ancestor($backdoor)));
.
method log
arg text;
var l;
if ((!(| .perms(sender(), 'system) |)) && (!(| .perms(caller(), 'system) |)))
throw(~perm, "Only system objects can log.");
if (type(text) == 'list) {
for l in (text)
.log(l);
} else {
log((($time.time_stamp()) + "> ") + text);
}
.
method open_connection
arg [args];
(> .perms(caller(), $network) <);
(> open_connection(@args) <);
.
method heartbeat
if (sender() != 0)
throw(~perm, "Sender is not the server.");
$scheduler.pulse();
// system pulse's happen every half hour
if (time() > next_pulse)
(| .pulse() |);
.
method do_backup
arg who;
var line, name;
(> .perms(sender(), 'system) <);
catch any {
name = who.namef('ref);
.log(("BACKUP (" + name) + ") ");
line = (("It is: " + ($time.ltime())) + " -- BACKUP -- called by ") + name;
$channels.announce('System, line);
}
backup = backup.add('next, time() + (backup['interval]));
backup = backup.add('last, time());
pause();
pause();
.text_dump();
.
method set_startup
arg what, value;
var valid;
(> .perms(sender(), .admins()) <);
valid = startup.keys();
if ((!what) in valid)
throw(~type, "Key must be one of " + toliteral(valid));
startup = startup.add(what, value);
.
method sender_data
var output, i;
if (caller() != $root)
throw(~perm, "Caller is not $root.");
return data(sender());
.
method get_system_email
arg what;
var email;
// email directory for system services, such as arch admins.
email = (| system_email_addresses[what] |);
if (!email)
email = (| system_email_addresses['default] |) || "<no email set>";
return email;
.
method new_admin
if (caller() != $admin)
throw(~perm, "Caller is not $admin.");
admins = setadd(admins, sender());
.
method admin_going_away
if (caller != $admin)
throw(~perm, "Caller is not $admin.");
admins = setremove(admins, sender());
.
method agents
return agents;
.
method text_dump
.perms(sender(), 'this);
pause();
return text_dump();
.
method get_startup
arg what;
return starting[what];
.
method set_starting
arg what, value;
var valid;
(> .perms(sender(), .admins()) <);
valid = starting.keys();
if ((!what) in valid)
throw(~type, "Key must be one of " + toliteral(valid));
starting = starting.add(what, value);
.
method execute
arg script, args, [background];
(> .perms(sender(), @admins) <);
(> execute(script, args, @background) <);
.
method get_starting
arg what;
return starting[what];
.
method create
arg parents, name, manager, [owners];
var new;
.perms(sender(), 'system);
new = create(parents);
catch any {
new.set_dbref(name);
new.initialize();
new.set_manager(manager);
new.chown([@owners, [new]][1]);
} with handler {
// Failed to initialize the child; destroy it.
if (!(| new.destroy() |)) {
(| new.uninitialize() |);
(| del_dbref(new.dbref('symbol)) |);
(| del_dbref(tosym(name)) |);
(| destroy(new) |);
}
rethrow(error());
}
return new;
.
method system
return admins + agents;
.
method bind_port
arg port, obj;
(> .perms(caller(), $network, $backdoor) <);
(> bind_port(port, obj) <);
.
method deassign_dbref
arg name;
(> .perms(caller(), $root, $sys) <);
del_dbref(name);
.
method del_system_email
arg key;
(> .perms(sender(), 'manager) <);
system_email_addresses = dict_del(system_email_addresses, key);
.
method add_system_email
arg key, email;
(> .perms(sender(), 'manager) <);
if (type(key) != 'symbol)
throw(~type, "Key is not a symbol.");
if (type(email) != 'string)
throw(~type, "Email address is not a string.");
system_email_addresses = dict_add(system_email_addresses, key, email);
.
method compile
arg code, name;
var line;
(> .perms(sender()) <);
line = ("SYSTEM: ." + tostr(name)) + "() MODIFIED";
line = (line + " by ") + (sender().namef('ref));
.log(line);
return (> pass(code, name) <);
.
method unbind_port
arg port, obj;
(> .perms(caller(), $network, $backdoor) <);
(> unbind_port(port) <);
.
method tasks
return (> tasks() <);
.
method resume
arg task, [args];
(> resume(task, @args) <);
.
method suspend
return (> suspend() <);
.
method validate_email_addresses
return validate_email_addresses;
.
method reassign_connection
arg obj;
(> .perms(caller(), $network, $backdoor) <);
(> reassign_connection(obj) <);
.
method cancel
arg [args];
return (> cancel(@args) <);
.
method signal
arg sig, sigstr;
var line;
if (sender() || caller())
throw(~perm, "Sender is not the server.");
line = ("** Caught Signal: " + sigstr) + " **";
(| $channels.announce('System, line) |);
if (!(sig in [1, 13, 16, 30, 31])) {
(| $channels.announce('System, "******************************") |);
(| $channels.announce('System, "** IMMINENT SERVER SHUTDOWN **") |);
(| $channels.announce('System, "******************************") |);
}
.
method load
arg [args];
(> .perms(sender(), 'system) <);
if (args)
return (> load() <);
else
return load['load];
.
method do_loadcheck
(> .perms(sender(), 'system) <);
load = load.add('load, load());
(| $channels.announce('System, (($time.ltime()) + " LOADCHECK: ") + (load['load])) |);
.
method pulse
(> .perms([caller(), sender()], this()) <);
next_pulse = time() + 1800;
if (time() > (backup['next]))
.do_backup(this());
// if (time() > load['next_check_time])
.do_loadcheck();
.
method status
return (> status() <);
.
method ip
arg [args];
return (> ip(@args) <);
.
method hostname
arg [args];
return (> hostname(@args) <);
.