tmi2_fluffos_v2/
tmi2_fluffos_v2/bin/
tmi2_fluffos_v2/etc/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/ChangeLog.old/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/Win32/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/compat/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/compat/simuls/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/include/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/clone/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/command/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/data/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/etc/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/include/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/inherit/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/inherit/master/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/log/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/compiler/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/efuns/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/operators/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/u/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/tmp/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/windows/
tmi2_fluffos_v2/lib/
tmi2_fluffos_v2/lib/adm/
tmi2_fluffos_v2/lib/adm/daemons/languages/
tmi2_fluffos_v2/lib/adm/daemons/network/I3/
tmi2_fluffos_v2/lib/adm/daemons/virtual/
tmi2_fluffos_v2/lib/adm/daemons/virtual/template/
tmi2_fluffos_v2/lib/adm/news/
tmi2_fluffos_v2/lib/adm/obj/
tmi2_fluffos_v2/lib/adm/obj/master/
tmi2_fluffos_v2/lib/adm/priv/
tmi2_fluffos_v2/lib/adm/shell/
tmi2_fluffos_v2/lib/adm/tmp/
tmi2_fluffos_v2/lib/cmds/
tmi2_fluffos_v2/lib/d/
tmi2_fluffos_v2/lib/d/Conf/
tmi2_fluffos_v2/lib/d/Conf/adm/
tmi2_fluffos_v2/lib/d/Conf/boards/
tmi2_fluffos_v2/lib/d/Conf/cmds/
tmi2_fluffos_v2/lib/d/Conf/data/
tmi2_fluffos_v2/lib/d/Conf/logs/
tmi2_fluffos_v2/lib/d/Conf/obj/
tmi2_fluffos_v2/lib/d/Conf/text/help/
tmi2_fluffos_v2/lib/d/Fooland/adm/
tmi2_fluffos_v2/lib/d/Fooland/data/
tmi2_fluffos_v2/lib/d/Fooland/data/attic/
tmi2_fluffos_v2/lib/d/Fooland/items/
tmi2_fluffos_v2/lib/d/TMI/
tmi2_fluffos_v2/lib/d/TMI/adm/
tmi2_fluffos_v2/lib/d/TMI/boards/
tmi2_fluffos_v2/lib/d/TMI/data/
tmi2_fluffos_v2/lib/d/TMI/rooms/
tmi2_fluffos_v2/lib/d/grid/
tmi2_fluffos_v2/lib/d/grid/adm/
tmi2_fluffos_v2/lib/d/grid/data/
tmi2_fluffos_v2/lib/d/std/
tmi2_fluffos_v2/lib/d/std/adm/
tmi2_fluffos_v2/lib/data/adm/
tmi2_fluffos_v2/lib/data/adm/daemons/
tmi2_fluffos_v2/lib/data/adm/daemons/doc_d/
tmi2_fluffos_v2/lib/data/adm/daemons/emoted/
tmi2_fluffos_v2/lib/data/adm/daemons/network/http/
tmi2_fluffos_v2/lib/data/adm/daemons/network/services/mail_q/
tmi2_fluffos_v2/lib/data/adm/daemons/network/smtp/
tmi2_fluffos_v2/lib/data/adm/daemons/news/archives/
tmi2_fluffos_v2/lib/data/attic/connection/
tmi2_fluffos_v2/lib/data/attic/user/
tmi2_fluffos_v2/lib/data/std/connection/b/
tmi2_fluffos_v2/lib/data/std/connection/l/
tmi2_fluffos_v2/lib/data/std/user/a/
tmi2_fluffos_v2/lib/data/std/user/b/
tmi2_fluffos_v2/lib/data/std/user/d/
tmi2_fluffos_v2/lib/data/std/user/f/
tmi2_fluffos_v2/lib/data/std/user/l/
tmi2_fluffos_v2/lib/data/std/user/x/
tmi2_fluffos_v2/lib/data/u/d/dm/working/doc_d/
tmi2_fluffos_v2/lib/data/u/l/leto/doc_d/
tmi2_fluffos_v2/lib/data/u/l/leto/smtp/
tmi2_fluffos_v2/lib/doc/
tmi2_fluffos_v2/lib/doc/driverdoc/applies/
tmi2_fluffos_v2/lib/doc/driverdoc/applies/interactive/
tmi2_fluffos_v2/lib/doc/driverdoc/concepts/
tmi2_fluffos_v2/lib/doc/driverdoc/driver/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/arrays/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/buffers/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/compile/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/ed/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/filesystem/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/floats/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/functions/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/general/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/mappings/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/numbers/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/parsing/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/constructs/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/preprocessor/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/types/
tmi2_fluffos_v2/lib/doc/driverdoc/platforms/
tmi2_fluffos_v2/lib/doc/mudlib/
tmi2_fluffos_v2/lib/ftp/
tmi2_fluffos_v2/lib/include/driver/
tmi2_fluffos_v2/lib/log/
tmi2_fluffos_v2/lib/log/driver/
tmi2_fluffos_v2/lib/obj/net/
tmi2_fluffos_v2/lib/obj/shells/
tmi2_fluffos_v2/lib/obj/tools/
tmi2_fluffos_v2/lib/std/adt/
tmi2_fluffos_v2/lib/std/board/
tmi2_fluffos_v2/lib/std/body/
tmi2_fluffos_v2/lib/std/fun/
tmi2_fluffos_v2/lib/std/living/
tmi2_fluffos_v2/lib/std/object/
tmi2_fluffos_v2/lib/std/shop/
tmi2_fluffos_v2/lib/std/socket/
tmi2_fluffos_v2/lib/std/user/
tmi2_fluffos_v2/lib/std/virtual/
tmi2_fluffos_v2/lib/student/
tmi2_fluffos_v2/lib/student/kalypso/
tmi2_fluffos_v2/lib/student/kalypso/armor/
tmi2_fluffos_v2/lib/student/kalypso/rooms/
tmi2_fluffos_v2/lib/student/kalypso/weapons/
tmi2_fluffos_v2/lib/u/l/leto/
tmi2_fluffos_v2/lib/u/l/leto/cmds/
tmi2_fluffos_v2/lib/www/errors/
tmi2_fluffos_v2/lib/www/gateways/
tmi2_fluffos_v2/lib/www/images/
tmi2_fluffos_v2/old/
tmi2_fluffos_v2/win32/
// A daemon to read the documentation directories into a mapping,
// and store for future reference (saves many disk accesses
// during runtime).  Interfaces with the new 'help' command, or
// will do when it's finished.
// Blue@TMI-2, 941018.

// To do: integrate command help with CMD_D
//        re-add facility for 'help <topic>' somehow.

#include <config.h>
#include <man.h>
#include <uid.h>
#include <daemons.h>
#include <help.h>

#define SEPARATOR '.'
#define DESC_FILE_NAME ".description"

// #define DEBUG(x) tell_object(find_player("blue"), x+"\n");
#define DEBUG(x)

inherit SAVE_D ;

void create();
void rehash_all();
void rehash_dirs(string *dirs_to_do);
string *note_files(mixed *dir_contents,
    string base_dir, string description);
void add_file(string name, string base_dir, string description);
int ignoredoc(string name);
string nameof(string name);
string *get_docs_on(string name, string *paths);
mapping get_all_the_docs();
string *command_docs(string name, string *paths);
string get_desc(string path);

mapping all_the_docs;
int last_rehash;

void
create() {
    if (!restore_data())
        rehash_all();
}

void
rehash_all() {
    DEBUG("rehash_all started.")
    all_the_docs = ([ ]);
    seteuid(getuid());
    rehash_dirs( ({ DOC_DIR }) );
}

void
rehash_dirs(string *dirs_to_do) {
    mixed *dir_contents;
    string description;

    DEBUG("Dirs_to_do: "+identify(dirs_to_do)+write("DEBUG EXECUTED\n"))
    description = get_desc(dirs_to_do[0]);
    dir_contents = get_dir(dirs_to_do[0], -1);
    DEBUG("dir_contents: "+identify(dir_contents))
    dir_contents = note_files(dir_contents, dirs_to_do[0], description);
    DEBUG("dir_contents: "+identify(dir_contents))
    dir_contents += dirs_to_do[1..sizeof(dirs_to_do)-1];
    DEBUG("dir_contents: "+identify(dir_contents))
    if (sizeof(dir_contents)) {
        call_out("rehash_dirs", 1, dir_contents);
    }
    else {
        last_rehash = time();
        save_data();
    }
}

string *
note_files(mixed *dir_contents, string base_dir, string description) {
    int i, sz;
    string *new_contents;

    sz = sizeof(dir_contents);
    new_contents = ({ });
    for (i=0;i<sz;i++) {
        if (dir_contents[i][1]==-2) {
            new_contents+=({ base_dir + dir_contents[i][0]+"/" });
        }
        else {
            add_file(dir_contents[i][0], base_dir, description);
        }
    }
    return new_contents;
}


void
add_file(string name, string base_dir, string description) {
    string shortname;

    shortname = nameof(name);
    if (ignoredoc(name)) return;
    if (!all_the_docs[shortname]) {
        all_the_docs[shortname] = ({ description, base_dir+name });
    }
//  else if (stringp(all_the_docs[name])) {
//      all_the_docs[name] = ({ all_the_docs[name], description });
//  }
    else if (pointerp(all_the_docs[shortname])) {
//      all_the_docs[name] += ({ description });
        all_the_docs[shortname] += ({ description, base_dir+name });
    }
// if none of these, something's wrong.
    else {
        log_file("doc_d_errors", name+": "+identify(all_the_docs["name"])+"\n");
    }
}

int
ignoredoc(string name) {
    if (name==DESC_FILE_NAME) return 1;
//  if (name=="README") return 1;
    return 0;
}

string
nameof(string name) {
    int sepoint;
    sepoint = strsrch(name, SEPARATOR, -1);
    if (sepoint==-1) return name;
    return name[0..sepoint-1];
}

string *
get_docs_on(string name, string *paths) {
    string *a;
    string *b;
    a = copy(all_the_docs[name]);
    b = command_docs(name, paths);
    if (!a) return b;
    if (!b) return a;
    return a + b;
}

mapping
get_all_the_docs() {
    return copy(all_the_docs);
}

string *
command_docs(string name, string *paths) {
    string *names;
    int i, j;
    names = ({ });
    j = sizeof(paths);
    for (i=0;i<j;i++) {
        if (file_size(sprintf("%s/_%s.c", paths[i], name)) > 0) {
            names += ({ get_desc(paths[i]), sprintf("%s/_%s", paths[i], name) });
        }
    }
    return names;
}

string get_desc(string path) {
    string description;

    if (!(description = read_file(sprintf("%s/%s", path, DESC_FILE_NAME))))
        description = sprintf("%s\n", path);
    return description;
}