/
CDC-1.2b/
CDC-1.2b/src/
parent $programmer
object $admin

var $root child_index 11
var $root owners [$admin]
var $root fertile 0
var $has_commands commands [["@copy * to *", 'copy_cmd], ["@task?s", 'tasks_cmd], ["@del-t?ask|@kill *", 'del_task_cmd], ["@backup", 'backup_cmd], ["@shutdown *", 'shutdown_cmd], ["@adjust user|att?itude * to *", 'adjust_user_cmd], ["@log *", 'log_cmd], ["@ustat *", 'user_stat_cmd], ["@grep *", 'grep_cmd]]
var $has_commands shortcuts []
var $has_verbs verbs #[]
var $location contents []
var $located location $nowhere
var $user password "*"
var $user connected_at 0
var $user last_command_at 0
var $user connections []
var $root inited 1
var $root owned [$admin]
var $programmer eval_prefix #[["me", "me = this()"], ["here", "here = this().location()"]]
var $admin shutdown_started 0
var $command_aliases command_aliases []
var $user modes #[]
var $mail_list letters #[]
var $mail_list letters_index #[]
var $mail_list senders 1
var $mail_list readers [$core]
var $mail_list notify [$admin]
var $mail_list last_letter 0
var $mail_ui subscribed #[[$admin, 791485891]]
var $gendered gender $gender_neuter
var $located obvious 1
var $described prose #[]
var $user prompt ""
var $root manager $admin
var $root writable [$admin]
var $root readable ['parameters, 'methods, 'code]
var $user parsers [$command_parser, $verb_parser]
var $user tell_traceback ['verbose, 4]
var $user context #[]
var $root quota 75000
var $root dbref 'admin
var $named name ['uniq, "Generic Admin"]
var $named name_aliases []
var $user_data user_data #[['real_name, [1, "???"]], ['email, [1, "???"]]]
var $old_command_environment verb_cache #[]
var $old_command_environment command_cache []
var $old_command_environment shortcuts_cache []
var $help_ui current_node $help_node_summary
var $help_ui last_visited #[['pos, 1], ['nodes, [$help_node_summary]]]
var $mail_list mail []
var $mail_ui current #[['location, 0], ['list, $admin]]
var $programmer eval_offset #[]

method init_admin
    if (caller() != $root)
        throw(~perm, "Caller is not $root.");
    $sys.new_admin();
.

method uninit_admin
    if (caller() != $root)
        throw(~perm, "Caller is not $root.");
    $sys.admin_going_away();
.

method copy_cmd
    arg sspec, tspec;
    var mode, parsed, sobj, smtd, code, tobj, tmtd, errors;
    
    // @copy dbref.method  to dbref[.method]
    if (!(.is_writable_by(sender())))
        throw(~perm, "Sender is not an owner.");
    
    // 'mode will hold the copy mode, for possible copying of commands and verbs.
    // currently only handles methods.
    mode = 'method;
    parsed = explode(sspec, ".");
    if (listlen(parsed) != 2) {
        .tell(("! \"" + sspec) + "\" is not a reference to the source method.");
        return;
    }
    sobj = $parse.object_match(parsed[1]);
    if (!sobj)
        return;
    smtd = tosym(parsed[2]);
    catch ~methodnf, ~perm {
        code = sobj.list_method(smtd);
    } with handler {
        switch (error()) {
            case ~methodnf:
                .tell(((("! " + (sobj.id())) + " does not define a method ") + toliteral(smtd)) + ".");
            case ~perm:
                .tell(("! " + (sobj.id())) + " is not readable by you.");
        }
        return;
    }
    parsed = explode(tspec, ".");
    if (listlen(parsed) != 2)
        tmtd = smtd;
    else
        tmtd = tosym(parsed[2]);
    tobj = $parse.object_match(parsed[1]);
    if (!tobj)
        return;
    catch ~perm {
        errors = tobj.compile(code, tmtd);
        if (errors) {
            // This should never happen.
            .tell(errors);
        } else {
            .tell((((((toliteral(smtd) + " successfully copied from ") + (sobj.id())) + " to ") + (tobj.id())) + ((smtd != tmtd) ? " as " + toliteral(tmtd) | "")) + ".");
        }
    } with handler {
        .tell(((("! Permission denied to @copy " + tostr('mode)) + " to ") + (tobj.id())) + ".");
    }
.

method del_task_cmd
    arg com, task;
    var syn;
    
    .perms(sender(), 'parser);
    syn = ("`" + com) + " <TID>' (use @tasks to get a TID)";
    task = toint(task);
    if (!task)
        $parse.tell_error("Tasks must be given as an integer", syn);
    catch any {
        $scheduler.del_task(task);
    } with handler {
        $parse.tell_error((traceback()[1])[2], syn);
    }
    .tell(("Task number " + tostr(task)) + " deleted.");
.

method tasks_cmd
    arg com;
    var output, task, task_queue, line, len_c1, time, args;
    
    .perms(sender(), 'parser);
    task_queue = $scheduler.task_queue();
    len_c1 = $list.nth_element_maxlength(1, task_queue);
    len_c1 = (len_c1 > 5) ? len_c1 + 1 | 5;
    output = [];
    time = (($time.ltime('12hr_sec, 'ampm)) + " ") + ($time.ldate('long));
    .tell("=====[ Queued Tasks at: " + time);
    .tell((pad("TID", len_c1) + pad("Exec Time", 20)) + "Task");
    .tell((pad("---", len_c1) + pad("---------", 20)) + "----");
    if (task_queue) {
        for task in (task_queue) {
            // this is broken down like this, because I HATE wrapped lines.
            line = pad(tostr(task[1]), len_c1);
            time = (task[2]) + (task[3]);
            time = (($time.ldate(time, 'dmy, 'dash)) + " ") + ($time.ltime(time, '12hr_sec, 'ampm));
            line = line + pad(time, 20);
            line = (((line + ($data.unparse(task[4]))) + ".") + tostr(task[6])) + "(";
            args = $data.unparse(task[8]);
            line = (line + substr(args, 2, strlen(args) - 2)) + ")";
            .tell($string.chop(line, .linelen()));
        }
    } else {
        .tell("***  NO QUEUED TASKS ****");
    }
.

method backup_cmd
    arg com;
    
    .perms(sender(), 'parser);
    .tell("Starting backup.");
    $sys.do_backup(this());
    .tell("Done.");
.

method shutdown_cmd
    arg com, [why];
    var time;
    
    .perms(sender(), 'parser);
    why = why[1];
    time = toint(why);
    if (time || (why && ((why[1]) == "0")))
        why = $list.to_string(sublist(explode(why), 2));
    else
        time = 5;
    if (why) {
        .tell([(("Shutdown the server in " + tostr(time)) + " minutes because: ") + why, "[yes|no]"]);
        .read_line('_shutdown_ask, why, time);
    } else {
        .tell("Why do you want to shutdown the server?");
        .read_line('_shutdown_why, time);
    }
.

method _shutdown_why
    arg str, time;
    
    if (sender() != this())
        throw(~perm, "Sender is not this.");
    if (!str)
        return .tell("I guess you just don't want to shutdown...");
    .tell([(("Shutdown the server in " + tostr(time)) + " minutes because: ") + (str[1]), "[yes|no]"]);
    .read_line('_shutdown_ask, @str, time);
.

method _shutdown_ask
    arg str, why, time;
    
    str = str[1];
    if (sender() != this())
        throw(~perm, "Sender is not this.");
    if (match_begin("no", str))
        return .tell("I didn't think so...");
    .tell("Ok...");
    if (time)
        shutdown_started = time * 60;
    ._shutdown(why);
.

method _shutdown
    arg why;
    var line1, line2;
    
    if (sender() != this())
        throw(~perm, "Sender is not this");
    
    //
    if (shutdown_started >= 120)
        shutdown_started = shutdown_started - 120;
    else if (shutdown_started >= 60)
        shutdown_started = shutdown_started - 60;
    else
        shutdown_started = 0;
    
    //
    if (shutdown_started > 0) {
        line1 = " *** SERVER WILL BE SHUTDOWN IN ";
        line1 = line1 + uppercase($time.elapsed(shutdown_started, 'long));
        if (why)
            line1 = line1 + " because:";
        line2 = (" *** " + why) + " ***";
        $channels.announce('all, line1 + " ***");
        if (why)
            $channels.announce('all, line2);
        $scheduler.add_task(120, '_shutdown, why);
    } else {
        $sys.shutdown(why);
    }
.

method adjust_user_cmd
    arg com, com, who, com, what;
    var promos, wp, name, pwd;
    
    .perms(sender(), 'parser);
    what = explode(what);
    what = what[listlen(what)];
    promos = #[["user", ['user, $user]], ["builder", ['builder, $builder]], ["programmer", ['programmer, $programmer]], ["admin", ['admin, $admin]]];
    who = .match_env_nice(who);
    wp = who.parents();
    if (!(what in dict_keys(promos)))
        $parse.tell_error(("Promote to any of: " + (dict_keys(promos).to_english())) + ".");
    (| who.chparents([(promos[what])[2]]) |);
    who.tell((((((.namef()) + " has made you ") + ($string.a_or_an(what))) + " ") + what) + ".");
    if ($guest in wp) {
        pwd = $code.random_word();
        who.set_password(pwd);
        (| who.del_filter($wrap_filter) |);
        who.tell(("Your password is currently \"" + pwd) + "\".");
        who.tell("You can change it with the command: `@password`");
        who.set_title("");
    }
    who.rehash_command_environment();
    .tell(((("Ok, " + (who.namef('titled))) + " is now a ") + what) + ".");
.

method grep_cmd
    arg cmd, args;
    var what, from, obj, syn;
    
    (> .perms(sender(), 'this) <);
    syn = ("Syntax: `" + cmd) + " <regexp> [from] <object>`";
    syn = [syn, "!  Note: if the tag 'from' is not defined, it only searches <object>."];
    if (!args)
        return .tell(syn);
    
    // we need a quote parsing method...
    args = args.explode();
    obj = args[listlen(args)];
    if ((args[listlen(args) - 1]) == "from") {
        from = 1;
        what = sublist(args, 1, listlen(args) - 2).to_string();
    } else {
        what = sublist(args, 1, listlen(args) - 1).to_string();
    }
    if (!what)
        return .tell(syn);
    if (cmd == "@grep") {
        if (("^" in what) != 1)
            what = "*" + what;
        if (what && (("$" in what) != strlen(what)))
            what = what + "*";
    }
    obj = .match_env_nice(obj);
    .tell(("Searching for \"" + what) + "\"...");
    .grep(what, from, obj, @(cmd == "@grep") ? [] | ['regexp]);
    .tell("--- Fin ---");
.

method egrep_cmd
    arg what;
    var found, x;
    
    .perms(sender(), 'parser);
    .tell("Searching...");
    found = .grep(what, 'regexp);
    for x in (found)
        .tell((((((x[1]).name_str()) + ".") + tostr(x[2])) + " : ") + tostr((x[3])[1]));
    .tell("--- + Finis + ---");
.

method grep
    arg regexp, from, object, [type];
    var method, found, findings, count, total, x, objects;
    
    findings = [];
    count = 0;
    total = 0;
    objects = [object];
    if (from)
        objects = [@objects, @object.descendants()];
    for object in (objects) {
        found = ._grep_object(regexp, object, @type);
        if (found)
            findings = findings + found;
        count = count + 1;
        total = total + 1;
        if (count == 50) {
            .tell(tostr(total) + " Objects Searched...");
            count = 0;
        }
        pause();
    }
    
    // fix later
    .tell(((tostr(total) + " Object") + ((total == 1) ? "" | "s")) + " Searched.");
    for x in (findings)
        .tell((((((x[1]).dbref()) + ".") + tostr(x[2])) + ": ") + (((x[3])[1]).to_english()));
.

method log_cmd
    arg com, [line];
    
    .perms(sender(), 'parser);
    if (!(line[1])) {
        return $changes_log.read_cmd("", "");
    } else {
        line = line[1];
        line = (($time.ldate('mdy, 'dash)) + "]: ") + line;
        line = ((((.namef()) + " [") + ($time.ltime('24hr))) + "/") + line;
        $changes_log.add_text([line], this(), 'dont_even_think_it);
        .tell("Thank you for your donation.");
    }
.

method user_stat_cmd
    arg cmd, str;
    var u, x, y, cs, line;
    
    (> .perms(sender(), 'this) <);
    u = .find_object_nice(str, 'user, 'environment, 'grasp);
    line = "Random stats on user " + (u.name());
    line = ((line + " <") + (u.user_data('email))) + ">";
    .tell(((line + " [") + tostr($code.user_type(u))) + "]:");
    x = u.quota_byte_usage();
    y = u.quota();
    line = ((((" Quota: " + (y.to_english())) + "  Usage: ") + (x.to_english())) + "  Remaining: ") + ((y - x).to_english());
    .tell(line);
    if (u.connected()) {
        .tell(" Connections:");
        cs = u.connections();
        for x in [1 .. listlen(cs)] {
            line = ("   " + ((cs[x]).dbref())) + ": [";
            line = line + ($time.ldate((cs[x]).started_at(), 'date));
            line = (line + "/") + ($time.ltime((cs[x]).started_at(), '24hr_sec));
            .tell((line + "] ") + ((cs[x]).address()));
        }
    } else {
        .tell(((" Last connected at " + ($time.ltime(abs(u.connected_at())))) + " ") + ($time.ldate(abs(u.connected_at()))));
    }
    .tell(u.display_data());
.

method _grep_object
    arg regexp, obj, [how];
    var method, found, findings, what;
    
    (> .perms(sender(), 'this) <);
    findings = [];
    if (valid(obj)) {
        for method in (obj.methods()) {
            found = ._grep_text(regexp, obj.list_method(method), @how);
            if (found)
                findings = findings + [[obj, method, found]];
            pause();
        }
    }
    return findings;
.

method _grep_text
    arg regexp, text, [how];
    var line, result, lines;
    
    (> .perms(sender(), 'this) <);
    how = [@how, 'match_pattern][1];
    lines = [];
    for line in [1 .. listlen(text)] {
        if (match_pattern(regexp, text[line]))
            lines = [@lines, line];
    }
    return lines;
.