// 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;
}