/
CDC-1.1/
parent $utilities
object $code

var $root child_index 0
var $root owners [$code]
var $root fertile 0
var $root inited 1
var $root owned [$code]
var $root manager $code
var $root writable [$code]
var $root readable ['parameters, 'methods, 'code]
var $code quotes [["\"Abandon all hope, ye who enter here.\""], ["\"Pull out Wedge, your not doing any more good back there.\"", "     - Luke Skywalker, StarWars"], ["\"God is in the details.\""], ["\"I don't practice what I preach because I'm not the type of person", "I'm preaching to.\"", "     - Bob Dobbs"], ["\"I haven't shaved for six years.  I seem to be cursed with a thin", "beard.\"", "     - Calvin, Age 6 (of Calvin & Hobbes)"], ["\"I may be a Dreamer, but I'm not the only one.\"", "     - John Lennon"], ["\"C code.  C code run.  Run, Code, Run!  Please!?\"", "     - Anonymous C hacker."], ["\"They who dream by day are cognizant of many things which escape", "those who dream only by night.\"", "     - Edgar Allan Poe"], ["\"The good die first, and they whose hearts are dry as a summer dust", "burn to the socket.\"", "     - William Wordsworth"], ["\"Banning guns to prevent murder is like banning word processors to", "prevent libel.\"", "     - Unknown"]]
var $root dbref 'code

method set_obj_param
    arg obj, param, val;
    var set_code;
    
    // set param on obj to val
    if (!((sender() == $root) || ($sys.is_admin(sender()))))
        throw(~perm, "Sender not admin or $root");
    if (!valid(obj))
        throw(~objnf, ("Object " + ($data.unparse(obj))) + " is not a valid object.");
    if (!(param in (obj.parameters())))
        throw(~parmnf, ((("Parameter " + ($data.unparse(param))) + " is not a parmater on ") + ($data.unparse(obj))) + ".");
    if ('__set_any in ($obj.methods()))
        throw(~methexist, "Method '__set_any already defined on target object.");
    
    // Copy _set_any to obj
    set_code = .list_method('_set_var);
    obj.compile(set_code, '__set_var);
    
    // Set and delete method
    catch any {
        obj.__set_var(param, val);
        obj.del_method('__set_var);
    } with handler {
        obj.del_method('__set_var);
        rethrow(error());
    }
.

method _set_var
    arg param, val;
    
    if (sender() != $code)
        throw(~perm, "Sender not $code");
    return set_var(param, val);
.

method quotes
    return quotes;
.

method add_random_quote
    arg quote, [from];
    
    if (!($sys.is_admin(sender())))
        throw(~perm, "Sender is not an owner");
    if (type(quote) != 'string)
        throw(~type, "Quote must be given as a string.");
    quote = ("\"" + quote) + "\"";
    quote = $string.wrap_line(quote, 70);
    quote = from ? [@quote, "     - " + (from[1])] | quote;
    quotes = quotes + [quote];
.

method generate_listing
    arg who, [args];
    var meths, methval, input, output, element, header, title, cols, x, z, len, line, linea;
    
    // called by one of the who_cmds, does all the grunge work.
    title = [@args, "Connected Users"][1];
    meths = [@args, [['namef, 'titled], ['time_poll], ['realm_name]], [['namef, 'titled], ['time_poll], ['realm_name]]][2];
    header = [@args, ["Name", "Times", "Location"], ["Name", "Times", "Location"], ["Name", "Times", "Location"]][3];
    cols = [@args, [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]][4];
    
    // get values using $list.map
    element = $list.map(who, (meths[1])[1], @sublist(meths[1], 2));
    input = [];
    for x in (element) {
        input = [@input, [x]];
        if (strlen(x) > (cols[1]))
            cols = replace(cols, 1, strlen(x));
    }
    for x in [2 .. listlen(meths)] {
        methval = $list.map(who, (meths[x])[1], @sublist(meths[x], 2));
        for z in [1 .. listlen(methval)] {
            if (strlen(methval[z]) > (cols[x]))
                cols = replace(cols, x, strlen(methval[z]));
            input = replace(input, z, [@input[z], methval[z]]);
        }
    }
    
    // the header.
    len = (| sender().linelen() |) || 79;
    line = "";
    linea = "";
    for x in [1 .. listlen(cols)] {
        line = line + pad(header[x], (cols[x]) + 2);
        linea = linea + pad(pad("", strlen(header[x]), "-"), (cols[x]) + 2);
    }
    output = [((("--- " + title) + " (") + tostr(listlen(input))) + ") ---"];
    output = [@output, $string.trim(pad(line, len))];
    output = [@output, $string.trim(pad(linea, len))];
    
    // tell the rest:
    for x in (input) {
        line = "";
        for z in [1 .. listlen(cols)]
            line = line + pad(x[z], (cols[z]) + 2);
        output = [@output, pad(line, len)];
    }
    return [@output];
.

method random_quote
    var which;
    
    which = random(listlen(quotes));
    if (which)
        return quotes[which];
    return [];
.

method valid_email
    arg email;
    var host, user, ip, tmp;
    
    email = explode(email, "@");
    if (listlen(email) != 2)
        return ['invalid, email, ""];
    
    // if we want we can do something overly extensive with this, but we will not
    user = email[1];
    host = email[2];
    if (toint(host[1])) {
        tmp = hostname(host);
        if (tmp == "-1")
            return ['invip, user, host];
    } else {
        tmp = ip(host);
        if (tmp == "-1")
            return ['invhostname, user, host];
    }
    return ['valid, user, host];
.

method unparse_command
    arg command;
    var x, line;
    
    // command should be passed as a list, and can either be a command
    // or shortcut.  This will return a string.
    if (listlen(command) == 2)
        return toliteral(command[1]);
    line = "";
    for x in (command[3]) {
        if (type(x) == 'string)
            line = (line + (line ? " " | "")) + x;
        else
            line = ((line + (line ? " " | "")) + "%") + tostr(x);
    }
    return ((("\"" + (command[1])) + "\" => \"") + line) + "\"";
.

method parse_name
    arg name;
    
    // used to parse $named names and aliases.
    name = explode(name, ",");
    if (!name)
        throw(~name, "Emtpy name.");
    return [name[1], sublist(name, 2)];
.

method generate_family_listing
    arg obj, [type];
    var line, obj, colx, col, family, x, out;
    
    type = [@type, 'children][1];
    family = obj.(type)();
    if (!family) {
        out = ["** None **"];
    } else {
        col = ((| sender().linelen() |) || 79) / 8;
        colx = col * 3;
        line = pad(" Name", colx + 2) + pad(" Perms", col - 2);
        out = [(line + pad("Size ", -col)) + "Manager"];
        for obj in (family) {
            line = " " + (obj.namef('xref));
            line = pad(line, colx + 2);
            line = line + pad(" " + ($object.see_perms(obj)), col - 2);
            line = line + pad(tostr(obj.size()) + " ", -col);
            line = line + pad($object.get_name(obj.manager(), 'namef, ['xref]), colx);
            out = [@out, line];
        }
    }
    return out;
.