skylib_mudos_v1/
skylib_mudos_v1/bin/
skylib_mudos_v1/bin/db/
skylib_mudos_v1/mudlib/banish/a/
skylib_mudos_v1/mudlib/banish/b/
skylib_mudos_v1/mudlib/banish/c/
skylib_mudos_v1/mudlib/banish/d/
skylib_mudos_v1/mudlib/banish/e/
skylib_mudos_v1/mudlib/banish/f/
skylib_mudos_v1/mudlib/banish/g/
skylib_mudos_v1/mudlib/banish/h/
skylib_mudos_v1/mudlib/banish/j/
skylib_mudos_v1/mudlib/banish/l/
skylib_mudos_v1/mudlib/banish/m/
skylib_mudos_v1/mudlib/banish/n/
skylib_mudos_v1/mudlib/banish/o/
skylib_mudos_v1/mudlib/banish/p/
skylib_mudos_v1/mudlib/banish/r/
skylib_mudos_v1/mudlib/banish/s/
skylib_mudos_v1/mudlib/banish/t/
skylib_mudos_v1/mudlib/banish/u/
skylib_mudos_v1/mudlib/banish/w/
skylib_mudos_v1/mudlib/cmds/
skylib_mudos_v1/mudlib/cmds/admin/
skylib_mudos_v1/mudlib/cmds/guild-race/
skylib_mudos_v1/mudlib/cmds/guild-race/crafts/
skylib_mudos_v1/mudlib/cmds/guild-race/magic/
skylib_mudos_v1/mudlib/cmds/guild-race/other/
skylib_mudos_v1/mudlib/cmds/living/broken/
skylib_mudos_v1/mudlib/cmds/player/group_cmds/
skylib_mudos_v1/mudlib/d/admin/
skylib_mudos_v1/mudlib/d/admin/room/
skylib_mudos_v1/mudlib/d/admin/room/we_care/
skylib_mudos_v1/mudlib/d/admin/save/
skylib_mudos_v1/mudlib/d/admin/text/
skylib_mudos_v1/mudlib/d/learning/TinyTown/buildings/
skylib_mudos_v1/mudlib/d/learning/TinyTown/map/
skylib_mudos_v1/mudlib/d/learning/TinyTown/roads/
skylib_mudos_v1/mudlib/d/learning/chars/
skylib_mudos_v1/mudlib/d/learning/functions/
skylib_mudos_v1/mudlib/d/learning/handlers/
skylib_mudos_v1/mudlib/d/learning/help_topics/
skylib_mudos_v1/mudlib/d/learning/help_topics/npcs/
skylib_mudos_v1/mudlib/d/learning/help_topics/objects/
skylib_mudos_v1/mudlib/d/learning/help_topics/rcs_demo/
skylib_mudos_v1/mudlib/d/learning/help_topics/rcs_demo/RCS/
skylib_mudos_v1/mudlib/d/learning/help_topics/rooms/
skylib_mudos_v1/mudlib/d/learning/help_topics/rooms/crowd/
skylib_mudos_v1/mudlib/d/learning/help_topics/rooms/situations/
skylib_mudos_v1/mudlib/d/learning/save/
skylib_mudos_v1/mudlib/d/learning/school/
skylib_mudos_v1/mudlib/d/learning/school/add_sc/
skylib_mudos_v1/mudlib/d/learning/school/characters/
skylib_mudos_v1/mudlib/d/learning/school/general/
skylib_mudos_v1/mudlib/d/learning/school/getting-started/
skylib_mudos_v1/mudlib/d/learning/school/getting-started/basic_commands/
skylib_mudos_v1/mudlib/d/learning/school/getting-started/edtutor/
skylib_mudos_v1/mudlib/d/learning/school/getting-started/unix_tutor/
skylib_mudos_v1/mudlib/d/learning/school/items/
skylib_mudos_v1/mudlib/d/learning/school/npc_school/
skylib_mudos_v1/mudlib/d/learning/school/room_school/
skylib_mudos_v1/mudlib/d/learning/school/room_school/room_basic/
skylib_mudos_v1/mudlib/d/learning/school/room_school/situations/
skylib_mudos_v1/mudlib/d/learning/school/room_school/terrain_tutor/
skylib_mudos_v1/mudlib/d/learning/text/
skylib_mudos_v1/mudlib/d/liaison/
skylib_mudos_v1/mudlib/d/mudlib/
skylib_mudos_v1/mudlib/d/mudlib/changes/
skylib_mudos_v1/mudlib/d/playtesters/
skylib_mudos_v1/mudlib/d/playtesters/effects/
skylib_mudos_v1/mudlib/d/playtesters/handlers/
skylib_mudos_v1/mudlib/d/playtesters/items/
skylib_mudos_v1/mudlib/d/sage/
skylib_mudos_v1/mudlib/doc/
skylib_mudos_v1/mudlib/doc/creator/
skylib_mudos_v1/mudlib/doc/driver/
skylib_mudos_v1/mudlib/doc/driver/efuns/arrays/
skylib_mudos_v1/mudlib/doc/driver/efuns/buffers/
skylib_mudos_v1/mudlib/doc/driver/efuns/compile/
skylib_mudos_v1/mudlib/doc/driver/efuns/filesystem/
skylib_mudos_v1/mudlib/doc/driver/efuns/floats/
skylib_mudos_v1/mudlib/doc/driver/efuns/functions/
skylib_mudos_v1/mudlib/doc/driver/efuns/general/
skylib_mudos_v1/mudlib/doc/driver/efuns/mappings/
skylib_mudos_v1/mudlib/doc/driver/efuns/mixed/
skylib_mudos_v1/mudlib/doc/driver/efuns/mudlib/
skylib_mudos_v1/mudlib/doc/driver/efuns/numbers/
skylib_mudos_v1/mudlib/doc/driver/efuns/parsing/
skylib_mudos_v1/mudlib/doc/known_command/
skylib_mudos_v1/mudlib/doc/login/
skylib_mudos_v1/mudlib/doc/lpc/basic_manual/
skylib_mudos_v1/mudlib/doc/lpc/intermediate/
skylib_mudos_v1/mudlib/doc/new/add_command/
skylib_mudos_v1/mudlib/doc/new/events/
skylib_mudos_v1/mudlib/doc/new/handlers/
skylib_mudos_v1/mudlib/doc/new/living/race/
skylib_mudos_v1/mudlib/doc/new/living/spells/
skylib_mudos_v1/mudlib/doc/new/object/
skylib_mudos_v1/mudlib/doc/new/player/
skylib_mudos_v1/mudlib/doc/new/room/guild/
skylib_mudos_v1/mudlib/doc/new/room/outside/
skylib_mudos_v1/mudlib/doc/new/room/storeroom/
skylib_mudos_v1/mudlib/doc/object/
skylib_mudos_v1/mudlib/doc/playtesters/
skylib_mudos_v1/mudlib/doc/policy/
skylib_mudos_v1/mudlib/doc/weapons/
skylib_mudos_v1/mudlib/global/
skylib_mudos_v1/mudlib/global/creator/
skylib_mudos_v1/mudlib/global/handlers/
skylib_mudos_v1/mudlib/global/virtual/setup_compiler/
skylib_mudos_v1/mudlib/include/cmds/
skylib_mudos_v1/mudlib/include/effects/
skylib_mudos_v1/mudlib/include/npc/
skylib_mudos_v1/mudlib/include/room/
skylib_mudos_v1/mudlib/include/shops/
skylib_mudos_v1/mudlib/net/daemon/
skylib_mudos_v1/mudlib/net/daemon/chars/
skylib_mudos_v1/mudlib/net/inherit/
skylib_mudos_v1/mudlib/net/obj/
skylib_mudos_v1/mudlib/obj/amulets/
skylib_mudos_v1/mudlib/obj/b_day/
skylib_mudos_v1/mudlib/obj/clothes/
skylib_mudos_v1/mudlib/obj/dwarmours/plate/
skylib_mudos_v1/mudlib/obj/dwclothes/transport/horse/
skylib_mudos_v1/mudlib/obj/dwscabbards/
skylib_mudos_v1/mudlib/obj/dwweapons/axes/
skylib_mudos_v1/mudlib/obj/dwweapons/chains/
skylib_mudos_v1/mudlib/obj/faith/symbols/
skylib_mudos_v1/mudlib/obj/fungi/
skylib_mudos_v1/mudlib/obj/gatherables/
skylib_mudos_v1/mudlib/obj/instruments/
skylib_mudos_v1/mudlib/obj/magic/
skylib_mudos_v1/mudlib/obj/media/
skylib_mudos_v1/mudlib/obj/misc/player_shop/
skylib_mudos_v1/mudlib/obj/monster/godmother/
skylib_mudos_v1/mudlib/obj/monster/transport/
skylib_mudos_v1/mudlib/obj/rings/
skylib_mudos_v1/mudlib/obj/spells/
skylib_mudos_v1/mudlib/obj/stationery/
skylib_mudos_v1/mudlib/obj/stationery/envelopes/
skylib_mudos_v1/mudlib/obj/stationery/papers/
skylib_mudos_v1/mudlib/obj/toys/
skylib_mudos_v1/mudlib/obj/vessels/
skylib_mudos_v1/mudlib/obj/weapons/swords/
skylib_mudos_v1/mudlib/save/autodoc/
skylib_mudos_v1/mudlib/save/leaflets/
skylib_mudos_v1/mudlib/save/mail/
skylib_mudos_v1/mudlib/save/new_soul/data/
skylib_mudos_v1/mudlib/save/parcels/
skylib_mudos_v1/mudlib/save/playerinfo/
skylib_mudos_v1/mudlib/save/players/d/
skylib_mudos_v1/mudlib/save/random_names/
skylib_mudos_v1/mudlib/save/random_names/data/
skylib_mudos_v1/mudlib/save/terrains/
skylib_mudos_v1/mudlib/save/terrains/tutorial_desert/
skylib_mudos_v1/mudlib/save/terrains/tutorial_grassy_field/
skylib_mudos_v1/mudlib/save/terrains/tutorial_mountain/
skylib_mudos_v1/mudlib/save/todo_lists/
skylib_mudos_v1/mudlib/secure/
skylib_mudos_v1/mudlib/secure/cmds/admin/
skylib_mudos_v1/mudlib/secure/cmds/lord/
skylib_mudos_v1/mudlib/secure/config/
skylib_mudos_v1/mudlib/secure/handlers/autodoc/
skylib_mudos_v1/mudlib/secure/handlers/intermud/
skylib_mudos_v1/mudlib/secure/include/global/
skylib_mudos_v1/mudlib/secure/save/
skylib_mudos_v1/mudlib/secure/save/handlers/
skylib_mudos_v1/mudlib/secure/std/classes/
skylib_mudos_v1/mudlib/secure/std/modules/
skylib_mudos_v1/mudlib/std/commands/
skylib_mudos_v1/mudlib/std/commands/shadows/
skylib_mudos_v1/mudlib/std/creator/
skylib_mudos_v1/mudlib/std/dom/
skylib_mudos_v1/mudlib/std/effects/
skylib_mudos_v1/mudlib/std/effects/external/
skylib_mudos_v1/mudlib/std/effects/fighting/
skylib_mudos_v1/mudlib/std/effects/priest/
skylib_mudos_v1/mudlib/std/effects/room/
skylib_mudos_v1/mudlib/std/environ/
skylib_mudos_v1/mudlib/std/guilds/
skylib_mudos_v1/mudlib/std/guilds/old/
skylib_mudos_v1/mudlib/std/languages/
skylib_mudos_v1/mudlib/std/languages/BACKUPS/
skylib_mudos_v1/mudlib/std/liquids/
skylib_mudos_v1/mudlib/std/npc/
skylib_mudos_v1/mudlib/std/npc/goals/
skylib_mudos_v1/mudlib/std/npc/goals/basic/
skylib_mudos_v1/mudlib/std/npc/goals/misc/
skylib_mudos_v1/mudlib/std/npc/plans/
skylib_mudos_v1/mudlib/std/npc/plans/basic/
skylib_mudos_v1/mudlib/std/npc/types/
skylib_mudos_v1/mudlib/std/npc/types/helper/
skylib_mudos_v1/mudlib/std/npcs/
skylib_mudos_v1/mudlib/std/outsides/
skylib_mudos_v1/mudlib/std/races/shadows/
skylib_mudos_v1/mudlib/std/room/basic/topography/
skylib_mudos_v1/mudlib/std/room/controller/
skylib_mudos_v1/mudlib/std/room/inherit/topography/
skylib_mudos_v1/mudlib/std/room/topography/area/
skylib_mudos_v1/mudlib/std/room/topography/iroom/
skylib_mudos_v1/mudlib/std/room/topography/milestone/
skylib_mudos_v1/mudlib/std/shadows/curses/
skylib_mudos_v1/mudlib/std/shadows/disease/
skylib_mudos_v1/mudlib/std/shadows/fighting/
skylib_mudos_v1/mudlib/std/shadows/healing/
skylib_mudos_v1/mudlib/std/shadows/magic/
skylib_mudos_v1/mudlib/std/shadows/poison/
skylib_mudos_v1/mudlib/std/shadows/rituals/
skylib_mudos_v1/mudlib/std/shadows/room/
skylib_mudos_v1/mudlib/std/shops/controllers/
skylib_mudos_v1/mudlib/std/shops/objs/
skylib_mudos_v1/mudlib/std/shops/player_shop/
skylib_mudos_v1/mudlib/std/socket/
skylib_mudos_v1/mudlib/std/soul/
skylib_mudos_v1/mudlib/std/soul/d/
skylib_mudos_v1/mudlib/std/soul/e/
skylib_mudos_v1/mudlib/std/soul/i/
skylib_mudos_v1/mudlib/std/soul/j/
skylib_mudos_v1/mudlib/std/soul/k/
skylib_mudos_v1/mudlib/std/soul/l/
skylib_mudos_v1/mudlib/std/soul/n/
skylib_mudos_v1/mudlib/std/soul/o/
skylib_mudos_v1/mudlib/std/soul/q/
skylib_mudos_v1/mudlib/std/soul/u/
skylib_mudos_v1/mudlib/std/soul/v/
skylib_mudos_v1/mudlib/std/soul/y/
skylib_mudos_v1/mudlib/std/soul/z/
skylib_mudos_v1/mudlib/std/stationery/
skylib_mudos_v1/mudlib/w/
skylib_mudos_v1/mudlib/w/default/
skylib_mudos_v1/mudlib/w/default/armour/
skylib_mudos_v1/mudlib/w/default/clothes/
skylib_mudos_v1/mudlib/w/default/item/
skylib_mudos_v1/mudlib/w/default/npc/
skylib_mudos_v1/mudlib/w/default/room/
skylib_mudos_v1/mudlib/w/default/weapon/
skylib_mudos_v1/mudlib/www/
skylib_mudos_v1/mudlib/www/download/
skylib_mudos_v1/mudlib/www/java/
skylib_mudos_v1/mudlib/www/secure/
skylib_mudos_v1/mudlib/www/secure/lpc/advanced/
skylib_mudos_v1/mudlib/www/secure/lpc/intermediate/
skylib_mudos_v1/v22.2b14-DSv10/
skylib_mudos_v1/v22.2b14-DSv10/ChangeLog.old/
skylib_mudos_v1/v22.2b14-DSv10/Win32/
skylib_mudos_v1/v22.2b14-DSv10/compat/
skylib_mudos_v1/v22.2b14-DSv10/compat/simuls/
skylib_mudos_v1/v22.2b14-DSv10/include/
skylib_mudos_v1/v22.2b14-DSv10/mudlib/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/clone/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/command/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/data/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/etc/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/include/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/inherit/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/inherit/master/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/log/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/single/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/single/tests/compiler/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/single/tests/efuns/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/single/tests/operators/
skylib_mudos_v1/v22.2b14-DSv10/testsuite/u/
skylib_mudos_v1/v22.2b14-DSv10/tmp/
skylib_mudos_v1/v22.2b14-DSv10/windows/
/* Hey Emacs, this is -*- LPC -*- ! */
/*
 * $Id: error_tracker_master.c,v 1.7 2000/02/24 15:39:37 turrican Exp $
 *
 * By Sin
 */
#include <board.h>

inherit "/global/player/path";
inherit ERRORS_BASE;

string domain = "unset";
string tracker_name = "generic error tracker";
string error_file = "/ERROR_REPORTS";
string *other_dirs = ({ });
int period = 604800;
int nexttime;

nosave string *queue;
nosave string *messages;
nosave object tester;
nosave string save_file;
nosave int error_total;
nosave int typo_total;
nosave int idea_total;
nosave int key;

#define ERROR_INDEX 0
#define TYPO_INDEX 1
#define IDEA_INDEX 2

/* Define this to use the old ERROR_REPORTS file system */
#undef OLD_SYTEM

void do_the_work();

protected void save_me()
{
  if (domain != "unset")
    unguarded( (: save_object, save_file, 0 :) );
}

void create()
{
  int retval;

  queue = ({ });
  messages = ({ });
  tester = 0;

  seteuid(master()->creator_file(file_name()));
  save_file = file_name();
  if (catch(retval = unguarded((: restore_object, save_file, 1 :))) ||
      !retval) {
    string temp;

    temp = "/save/" + replace(file_name()[1..], "/", "_");
    if (catch(retval = unguarded((: restore_object, temp, 1 :))) ||
        !retval) {
      /* The save file doesn't exist.  Try to make it here, then
       * /save */
      if (catch(save_me()))
        save_file = temp;
    } else
      save_file = temp;
  }
  if (!retval) {
    nexttime = 0;
  }
  if (nexttime < time())
    do_the_work();
  else
    call_out("do_the_work", nexttime - time());
}

void dest_me()
{
  save_me();
  if (key) {
    finish_errors(key);
  }
  destruct(this_object());
}

nomask mixed dwep()
{
  if (key) {
    finish_errors(key);
  }
  destruct(this_object());
  return "Destructed With Extreme Prejudice";
}

protected int post(string message)
{
  if (tester) {
    tester->more_string(message);
    tester = 0;
    return 0;
  }
  return BOARD_HAND->add_message(domain,
    capitalize(tracker_name),
    "Error summaries for " +
      capitalize(domain),
    message);
}

protected int *errors(string directory)
{
  int *retval = ({ 0, 0, 0 });
#ifdef OLD_SYSTEM
  string *lines;
  string test;
  int i, j, k;
#else
  string query;
  mixed ret;
#endif

#ifdef OLD_SYSTEM
  if (file_size(directory) != -2) return retval;
  if (file_size(directory + error_file) <= 0) return retval;
  lines = explode(read_file(directory + error_file), "\n");
  for (i = 0, j = sizeof(lines); i < j; i++) {
    if (sscanf(lines[i], ".START %d", k) == 1) {
      i++;
      if (i < j) {
        if (strsrch(lines[i], "BUG") != -1)
          retval[ERROR_INDEX]++;
        else if (strsrch(lines[i], "IDEA") != -1)
          retval[IDEA_INDEX]++;
        else if (strsrch(lines[i], "TYPO") != -1)
          retval[TYPO_INDEX]++;
      }
      test = sprintf(".END %d", k);
      while (i < j && lines[i] != test) i++;
    }
  }
#else
  query = sprintf("SELECT COUNT(*) FROM errors WHERE Directory = '%s' AND "
                  "Status = 'OPEN' AND Type = 'BUG'\n", directory);
  ret = sql_query(key, query);
  if (stringp(ret)) {
    log_file("ERROR_TRACKER", "%s Error counting bugs for directory %s : %s\n",
             ctime(time()), directory, ret);
  } else if (ret) {
    ret = get_row(key, 1);
    if (stringp(ret)) {
      log_file("ERROR_TRACKER", "%s Error counting bugs for directory %s : "
               "%s\n", ctime(time()), directory, ret);
    } else {
      retval[ERROR_INDEX] = values(ret)[0];
    }
  }
  query = sprintf("SELECT COUNT(*) FROM errors WHERE Directory = '%s' AND "
                  "Status = 'OPEN' AND Type = 'IDEA';", directory);
  ret = sql_query(key, query);
  if (stringp(ret)) {
    log_file("ERROR_TRACKER", "%s Error counting ideas for directory %s : "
             "%s\n", ctime(time()), directory, ret);
  } else if (ret) {
    ret = get_row(key, 1);
    if (stringp(ret)) {
      log_file("ERROR_TRACKER", "%s Error counting ideas for directory %s : "
               "%s\n", ctime(time()), directory, ret);
    } else {
      retval[IDEA_INDEX] = values(ret)[0];
    }
  }
  query = sprintf("SELECT COUNT(*) FROM errors WHERE Directory = '%s' AND "
                  "Status = 'OPEN' AND Type = 'TYPO';", directory);
  ret = sql_query(key, query);
  if (stringp(ret)) {
    log_file("ERROR_TRACKER", "%s Error counting typos for directory %s : "
             "%s\n", ctime(time()), directory, ret);
  } else if (ret) {
    ret = get_row(key, 1);
    if (stringp(ret)) {
      log_file("ERROR_TRACKER", "%s Error counting typos for directory %s : "
               "%s\n", ctime(time()), directory, ret);
    } else {
      retval[TYPO_INDEX] = values(ret)[0];
    }
  }
#endif
  return retval;
}

protected string dodir(string directory)
{
  string mesg;
  string file;
  string *files;
  string *dirs;
  int *counts;

  counts = errors(directory);
  if (counts[0] || counts[1] || counts[2]) {
    mesg = sprintf("%4d %4d %4d %s", counts[ERROR_INDEX],
      counts[TYPO_INDEX], counts[IDEA_INDEX], directory);
    error_total += counts[ERROR_INDEX];
    typo_total += counts[TYPO_INDEX];
    idea_total += counts[IDEA_INDEX];
  } else
    mesg = 0;

  files = get_files(directory + "/*");
  dirs = ({ });
  foreach (file in files) {
    if (file[<2..] == "/." || file[<3..] == "/..")
      continue;
    if (file_size(file) == -2)
      dirs += ({ file });
  }
  queue = dirs + queue;

  return mesg;
}

protected void iterate()
{
  if (sizeof(queue)) {
    string dir = queue[0];

    if (sizeof(queue) > 1)
      queue = queue[1..];
    else
      queue = ({ });

    messages += ({ dodir(dir) });
    call_out((: iterate() :), 1);
  } else {
    string message;

    message = implode(messages - ({ 0 }), "\n");
    if (sizeof(message) == 0) {
      message = "Congratulations!  There are no errors in all of " +
        capitalize(domain) + "!\n";
    } else {
      message = "There are reports in the following directories in " +
        capitalize(domain) + "\n" + 
        " BUG TYPO IDEA\n" +
        message +
        sprintf("\n%4d %4d %4d TOTAL\n",
          error_total, typo_total, idea_total);
    }
    post(message);
    messages = ({ });
#ifndef OLD_SYSTEM
    finish_errors(key);
    key = 0;
#endif
  }
}

void do_the_work()
{
  string ret;

  if (domain == "unset") return;

  nexttime = time() + period;
  call_out("do_the_work", period);
  save_me();

  queue = ({ "/d/" + domain }) + other_dirs;
  messages = ({ });
  error_total = 0;
  idea_total = 0;
  typo_total = 0;
#ifndef OLD_SYSTEM
  key = time();
  ret = init_errors(key, "atuin");
  if (ret) {
    log_file("ERROR_TRACKER", "%s Error initializing errors database for "
             "domain %s : %s\n", ctime(key), domain, ret);
    return;
  }
#endif
  iterate();
}

varargs void test(string dir)
{
  mixed ret;

  tester = this_player();
  if (dir && stringp(dir) && dir != "")
    queue = ({ dir });
  else
    queue = ({ "/d/klatch/djel" });
  messages = ({ });
#ifndef OLD_SYSTEM
  key = time();
  ret = init_errors(key, "atuin");
  if (ret) {
    printf("Error initializing errors database for directory %s : %s\n", dir, ret);
    return;
  }
#endif
  iterate();
}

void set_name(string name)
{
  tracker_name = name;
  save_me();
}

void set_domain(string name)
{
  domain = name;
  save_me();
}

void set_period(int length)
{
  remove_call_out("do_the_work");
  nexttime -= period;
  period = length;
  nexttime += period;
  save_me();
  if (nexttime < time())
    do_the_work();
  else
    call_out("do_the_work", nexttime - time());
}

void set_error_file(string name)
{
  error_file = name;
  save_me();
}

void set_other_dirs(string *others)
{
  if (arrayp(others))
    other_dirs = others;
  else
    other_dirs = ({ });
  save_me();
}

mixed stats()
{
  return ({
    ({ "domain", domain }),
    ({ "name", tracker_name }),
    ({ "error file", error_file }),
    ({ "period", period }),
    ({ "next time", ctime(nexttime) }),
    ({ "testing by", tester }),
    ({ "queue length", sizeof(queue) }),
    ({ "message length", sizeof(messages - ({ 0 })) }),
    ({ "other dirs", sizeof(other_dirs) ? implode(other_dirs, ", ") : 0 }),
    ({ "save file", save_file }),
  });
}