ソースを参照

Many unknown changes. This was the last state of my working directory.

It includes a file called "subUPDATES" where I seem to have logged some changes. I do not know if these have been fully implemented, though:

- users with wildcards in their hosts aren't auto-added anymore
- added option to turn off greeting of new users
- added [suserlist]
Florian Sander 13 年 前
コミット
d4fdf1b277

+ 0 - 1544
DATAHANDLING.~C

@@ -1,1544 +0,0 @@
-/*
- * Copyright (C) 2000,2001  Florian Sander
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-static void incrstats(char *user, char *chan, int type, int value, int set)
-{
-  globstats *gs, *gs2;
-  locstats *ls, *ls2;
-  int i, ii;
-
-  if (type >= TOTAL_TYPES)
-    return;
-  if (!user) {
-    debug0("Stats.mod: incrstats(..) Ups, user is NULL!");
-    return;
-  }
-  if (!chan) {
-    debug0("Stats.mod: incrstats(..) Ups, chan is NULL!");
-    return;
-  }
-  for (gs = sdata; gs; gs = gs->next) {
-    if (!strcasecmp(chan, gs->chan))
-      break;
-  }
-  if (!gs) {
-    gs2 = sdata;
-    while (gs2 && gs2->next)
-      gs2 = gs2->next;
-    gs = nmalloc(sizeof(globstats));
-    globstats_init(gs);
-    gs->started = now;
-    gs->chan = nmalloc(strlen(chan) + 1);
-    strcpy(gs->chan, chan);
-    if (gs2)
-      gs2->next = gs;
-    else
-      sdata = gs;
-  }
-  for (ls = gs->local; ls; ls = ls->next) {
-    if (!strcasecmp(ls->user, user))
-      break;
-  }
-  if (type == T_GSTARTED) {
-    gs->started = value;
-    return;
-  }
-  if (type == T_PEAK) {
-    gs->peak[set] = value;
-    return;
-  }
-  if (!ls) {
-    ls2 = gs->local;
-    while (ls2 && ls2->next)
-      ls2 = ls2->next;
-    ls = nmalloc(sizeof(locstats));
-    locstats_init(ls);
-    ls->started = now;
-    ls->user = nmalloc(strlen(user) + 1);
-    strcpy(ls->user, user);
-    if (ls2)
-      ls2->next = ls;
-    else
-      gs->local = ls;
-    for (i = 0; i < (TOTAL_TYPES + TOTAL_SPECIAL_TYPES); i++)
-      ls->snext[S_TOTAL][i] = ls->snext[S_DAILY][i] = ls->snext[S_WEEKLY][i] = ls->snext[S_MONTHLY][i] = NULL;
-    for (i = 0; i < 4; i++) {
-      for (ii = 0; ii < (TOTAL_TYPES + TOTAL_SPECIAL_TYPES); ii++) {
-        ls2 = gs->slocal[i][ii];
-        while (ls2 && ls2->snext[i][ii])
-          ls2 = ls2->snext[i][ii];
-        if (ls2)
-          ls2->snext[i][ii] = ls;
-        else
-          gs->slocal[i][ii] = ls;
-      }
-    }
-  }
-  if (type == T_LSTARTED)
-    ls->started = value;
-  else {
-    if (set > 0)
-      ls->values[set - 1][type] = value;
-    else if (set < 0)
-      ls->values[(set * (-1)) - 1][type] += value;
-    else {
-      ls->values[S_TOTAL][type] += value;
-      ls->values[S_TODAY][type] += value;
-      ls->values[S_WEEKLY][type] += value;
-      ls->values[S_MONTHLY][type] += value;
-    }
-  }
-}
-
-static void nincrstats(locstats *ls, int type, int value)
-{
-  ls->values[S_TOTAL][type] += value;
-  ls->values[S_TODAY][type] += value;
-  ls->values[S_WEEKLY][type] += value;
-  ls->values[S_MONTHLY][type] += value;
-}
-
-static locstats *initstats(char *chan, char *user)
-{
-  globstats *gs, *gs2;
-  locstats *ls, *ls2;
-  int i, ii;
-
-  gs = sdata;
-  while (gs) {
-    if (!rfc_casecmp(gs->chan, chan))
-      break;
-    gs = gs->next;
-  }
-  if (!gs) {
-    gs2 = sdata;
-    while (gs2 && gs2->next)
-      gs2 = gs2->next;
-    gs = nmalloc(sizeof(globstats));
-    globstats_init(gs);
-    gs->started = now;
-    gs->chan = nmalloc(strlen(chan) + 1);
-    strcpy(gs->chan, chan);
-    if (gs2)
-      gs2->next = gs;
-    else
-      sdata = gs;
-  }
-  for (ls = gs->local; ls; ls = ls->next) {
-    if (!rfc_casecmp(ls->user, user))
-      return ls;
-  }
-  if (!ls) {
-    ls2 = gs->local;
-    while (ls2 && ls2->next)
-      ls2 = ls2->next;
-    ls = nmalloc(sizeof(locstats));
-    locstats_init(ls);
-    ls->started = now;
-    ls->user = nmalloc(strlen(user) + 1);
-    strcpy(ls->user, user);
-    if (ls2)
-      ls2->next = ls;
-    else
-      gs->local = ls;
-    for (i = 0; i < (TOTAL_TYPES + TOTAL_SPECIAL_TYPES); i++)
-      ls->snext[S_TOTAL][i] = ls->snext[S_DAILY][i] = ls->snext[S_WEEKLY][i] = ls->snext[S_MONTHLY][i] = NULL;
-    for (i = 0; i < 4; i++) {
-      for (ii = 0; ii < (TOTAL_TYPES + TOTAL_SPECIAL_TYPES); ii++) {
-        ls2 = gs->slocal[i][ii];
-        while (ls2 && ls2->snext[i][ii])
-          ls2 = ls2->snext[i][ii];
-        if (ls2)
-          ls2->snext[i][ii] = ls;
-        else
-          gs->slocal[i][ii] = ls;
-      }
-    }
-  }
-  return ls;
-}
-
-static void locstats_init(locstats *ls)
-{
-  int i;
-  
-  Assert(ls);
-  ls->started = now;
-  ls->next = NULL;
-  ls->words = NULL;
-  ls->tree = NULL;
-  ls->quotes = NULL;
-  ls->quotefr = 0;
-  ls->flag = 0;
-  for (i = 0; i < TOTAL_TYPES; i++) {
-    ls->values[S_TOTAL][i] = 0;
-    ls->values[S_TODAY][i] = 0;
-    ls->values[S_WEEKLY][i] = 0;
-    ls->values[S_MONTHLY][i] = 0;
-  }
-  ls->user = NULL;
-  ls->u = NULL;
-  ls->lastspoke = 0;
-  for (i = 0; i < (TOTAL_TYPES + TOTAL_SPECIAL_TYPES); i++)
-    ls->snext[S_TOTAL][i] = ls->snext[S_DAILY][i] = ls->snext[S_WEEKLY][i] = ls->snext[S_MONTHLY][i] = NULL;
-}
-
-static void globstats_init(globstats *gs)
-{
-  int i;
-  
-  Assert(gs);
-  gs->next = NULL;
-  gs->chan = NULL;
-  gs->started = now;
-  gs->peak[S_TOTAL] = gs->peak[S_DAILY] = gs->peak[S_WEEKLY] = gs->peak[S_MONTHLY] = 0;
-  for (i = 0; i < 24; i++) {
-    gs->users[S_USERSUM][i] = 0;
-    gs->users[S_USERCOUNTS][i] = -1;
-  }
-  for (i = 0; i < 24; i++)
-    gs->activity[i] = 0;
-  gs->local = NULL;
-  for (i = 0; i < (TOTAL_TYPES + TOTAL_SPECIAL_TYPES); i++)
-    gs->slocal[S_TOTAL][i] = gs->slocal[S_DAILY][i] = gs->slocal[S_WEEKLY][i] = gs->slocal[S_MONTHLY][i] = NULL;
-  gs->words = NULL;
-  gs->topics = NULL;
-  gs->hosts = NULL;
-  gs->urls = NULL;
-  gs->log = gs->lastlog = NULL;
-  gs->log_length = 0;
-  gs->kicks = NULL;
-}
-
-static int getstats(char *user, char *chan, char *type, int today)
-{
-  struct stats_global *gs = sdata;
-  struct stats_local *ls;
-  int itype;
-
-  while (gs) {
-    ls = gs->local;
-    if (!strcasecmp(gs->chan, chan)) {
-      while (ls) {
-        if (!strcasecmp(ls->user, user)) {
-          itype = typetoi(type);
-          if (itype >= 0)
-            return ls->values[today][itype];
-        }
-        ls = ls->next;
-      }
-    }
-    gs = gs->next;
-  }
-  return 0;
-}
-
-static void sortstats(struct stats_global *gs, int itype, int today)
-{
-  int again = 1;
-  struct stats_local *last, *p, *c, *n;
-  int a, b, pitype;
-
-  Context;
-  Assert(gs);
-  again = 1;
-  last = NULL;
-  if (itype < 0) {
-    // switch to the special sorting function
-    switch (itype) {
-      case T_WPL:
-        sortstats_wpl(gs, today);
-        break;
-      case T_VOCABLES:
-        sortstats_vocables(gs, today);
-        break;
-      case T_WORD:
-        sortstats_word(gs, today);
-        break;
-      case T_IDLE:
-        sortstats_idle(gs, today);
-        break;
-      default:
-        debug1("Missing sorting algorithm for \"%d\"!!!", itype);
-    }
-    return;
-  }
-
-  // if (itype < 0) pitype = (TOTAL_TYPES - 1) + (itype * -1);
-  // not needed here
-  pitype = itype;
-  while ((gs->slocal[today][pitype] != last) && (again)) {
-    p = NULL;
-    c = gs->slocal[today][pitype];
-    n = c->snext[today][pitype];
-    again = 0;
-    while (n != last) {
-      if (!c || !n)
-        a = b = 0;
-      else {
-        a = c->values[today][itype];
-        b = n->values[today][itype];
-      }
-      if (a < b) {
-        again = 1;
-        c->snext[today][pitype] = n->snext[today][pitype];
-        n->snext[today][pitype] = c;
-        if (p == NULL)
-          gs->slocal[today][pitype] = n;
-        else
-          p->snext[today][pitype] = n;
-      }
-      p = c;
-      c = n;
-      n = n->snext[today][pitype];
-    }
-    last = c;
-  }
-  Context;
-  return;
-}
-
-static void sortstats_wpl(struct stats_global *gs, int today)
-{
-  int again = 1;
-  struct stats_local *last, *p, *c, *n;
-  int a, b, pitype;
-
-  Context;
-  again = 1;
-  last = NULL;
-  pitype = (T_WPL * (-1)) + TOTAL_TYPES - 1;
-  while ((gs->slocal[today][pitype] != last) && (again)) {
-    p = NULL;
-    c = gs->slocal[today][pitype];
-    n = c->snext[today][pitype];
-    again = 0;
-    while (n != last) {
-      if (!c || !n)
-        a = b = 0;
-      else {
-        if (c->values[today][T_LINES] >= min_lines)
-          a = (int) (((float) c->values[today][T_WORDS] / (float) c->values[today][T_LINES]) * 100.0);
-        else
-          a = 0;
-        if (n->values[today][T_LINES] >= min_lines)
-          b = (int) (((float) n->values[today][T_WORDS] / (float) n->values[today][T_LINES]) * 100.0);
-        else
-          b = 0;
-      }
-      if (a < b) {
-        again = 1;
-        c->snext[today][pitype] = n->snext[today][pitype];
-        n->snext[today][pitype] = c;
-        if (p == NULL)
-          gs->slocal[today][pitype] = n;
-        else
-          p->snext[today][pitype] = n;
-      }
-      p = c;
-      c = n;
-      n = n->snext[today][pitype];
-    }
-    last = c;
-  }
-  Context;
-  return;
-}
-
-static void sortstats_vocables(struct stats_global *gs, int today)
-{
-  int again = 1;
-  struct stats_local *last, *p, *c, *n;
-  int a, b, pitype;
-
-  Context;
-  again = 1;
-  last = NULL;
-  countvocables(gs);
-  pitype = (T_VOCABLES * (-1)) + TOTAL_TYPES - 1;
-  while ((gs->slocal[today][pitype] != last) && (again)) {
-    p = NULL;
-    c = gs->slocal[today][pitype];
-    n = c->snext[today][pitype];
-    again = 0;
-    while (n != last) {
-      if (!c || !n)
-        a = b = 0;
-      else {
-        a = c->vocables;
-        b = n->vocables;
-      }
-      if (a < b) {
-        again = 1;
-        c->snext[today][pitype] = n->snext[today][pitype];
-        n->snext[today][pitype] = c;
-        if (p == NULL)
-          gs->slocal[today][pitype] = n;
-        else
-          p->snext[today][pitype] = n;
-      }
-      p = c;
-      c = n;
-      n = n->snext[today][pitype];
-    }
-    last = c;
-  }
-  Context;
-  return;
-}
-
-static void sortstats_word(struct stats_global *gs, int today)
-{
-  int again = 1;
-  struct stats_local *last, *p, *c, *n;
-  int a, b, pitype;
-
-  Context;
-  debug1("sortstats_word: today == %d", today);
-  again = 1;
-  last = NULL;
-  pitype = (T_WORD * (-1)) + TOTAL_TYPES - 1;
-  debug1("pitype: %d", pitype);
-  while ((gs->slocal[today][pitype] != last) && (again)) {
-    p = NULL;
-    c = gs->slocal[today][pitype];
-    n = c->snext[today][pitype];
-    again = 0;
-    while (n != last) {
-      if (!c || !n)
-        a = b = 0;
-      else {
-        if (c->word)
-          a = c->word->nr;
-        else
-          a = 0;
-        if (n->word)
-          b = n->word->nr;
-        else
-          b = 0;
-      }
-      if (a < b) {
-        again = 1;
-        c->snext[today][pitype] = n->snext[today][pitype];
-        n->snext[today][pitype] = c;
-        if (p == NULL)
-          gs->slocal[today][pitype] = n;
-        else
-          p->snext[today][pitype] = n;
-      }
-      p = c;
-      c = n;
-      n = n->snext[today][pitype];
-    }
-    last = c;
-  }
-  Context;
-  return;
-}
-
-// sort stats by idle-factor (minutes/lines)
-static void sortstats_idle(struct stats_global *gs, int today)
-{
-  int again = 1;
-  struct stats_local *last, *p, *c, *n;
-  int a, b, pitype;
-
-  Context;
-  again = 1;
-  last = NULL;
-  pitype = (T_IDLE * (-1)) + TOTAL_TYPES - 1;
-  while ((gs->slocal[today][pitype] != last) && (again)) {
-    p = NULL;
-    c = gs->slocal[today][pitype];
-    n = c->snext[today][pitype];
-    again = 0;
-    while (n != last) {
-      if (!c || !n)
-        a = b = 0;
-      else {
-        if (c->values[today][T_LINES] >= min_lines)
-          a = (int) (((float) c->values[today][T_MINUTES] / (float) c->values[today][T_LINES]) * 100.0);
-        else
-          a = 0;
-        if (n->values[today][T_LINES] >= min_lines)
-          b = (int) (((float) n->values[today][T_MINUTES] / (float) n->values[today][T_LINES]) * 100.0);
-        else
-          b = 0;
-      }
-      if (a < b) {
-        again = 1;
-        c->snext[today][pitype] = n->snext[today][pitype];
-        n->snext[today][pitype] = c;
-        if (p == NULL)
-          gs->slocal[today][pitype] = n;
-        else
-          p->snext[today][pitype] = n;
-      }
-      p = c;
-      c = n;
-      n = n->snext[today][pitype];
-    }
-    last = c;
-  }
-  Context;
-  return;
-}
-
-static void countvocables(globstats *gs)
-{
-  locstats *ls;
-  wordstats *ws;
-
-  for (ls = gs->local; ls; ls = ls->next) {
-    ls->vocables = 0;
-    for (ws = ls->words; ws; ws = ws->next)
-      ls->vocables++;
-  }
-}
-
-static void sortwordstats(locstats *ls, globstats *gs)
-{
-  int again = 1;
-  wordstats *last, *p, *c, *n, *tmp;
-  int a, b;
-
-  Context;
-  again = 1;
-  last = NULL;
-  if (ls)
-    tmp = ls->words;
-  else
-    tmp = gs->words;
-  while ((tmp != last) && (again)) {
-    p = NULL;
-    if (ls)
-      c = ls->words;
-    else
-      c = gs->words;
-    n = c->next;
-    again = 0;
-    while (n != last) {
-      if (!c || !n)
-        a = b = 0;
-      else {
-        a = c->nr;
-        b = n->nr;
-      }
-      if (a < b) {
-  again = 1;
-  c->next = n->next;
-  n->next = c;
-  if (p == NULL) {
-    if (ls)
-      ls->words = n;
-    else
-      gs->words = n;
-    tmp = n;
-  } else
-    p->next = n;
-      }
-      p = c;
-      c = n;
-      n = n->next;
-    }
-    last = c;
-  }
-  Context;
-  return;
-}
-
-static void sorthosts(struct stats_global *gs)
-{
-  int again = 1;
-  hoststr *last, *p, *c, *n;
-  int a, b;
-
-  Context;
-  again = 1;
-  last = NULL;
-  while ((gs->hosts != last) && (again)) {
-    p = NULL;
-    c = gs->hosts;
-    n = c->next;
-    again = 0;
-    while (n != last) {
-      if (!c || !n)
-        a = b = 0;
-      else {
-        a = c->nr;
-        b = n->nr;
-      }
-      if (a < b) {
-        again = 1;
-        c->next = n->next;
-        n->next = c;
-        if (p == NULL)
-          gs->hosts = n;
-        else
-          p->next = n;
-      }
-      p = c;
-      c = n;
-      n = n->next;
-    }
-    last = c;
-  }
-  Context;
-  return;
-}
-
-// typetoi(): returns the index of a stat-type
-static int typetoi(char *type)
-{
-  if (!strcasecmp(type, "lstarted"))
-    return T_LSTARTED;
-  else if (!strcasecmp(type, "gstarted"))
-    return T_GSTARTED;
-  else if (!strcasecmp(type, "words"))
-    return T_WORDS;
-  else if (!strcasecmp(type, "letters"))
-    return T_LETTERS;
-  else if (!strcasecmp(type, "minutes"))
-    return T_MINUTES;
-  else if (!strcasecmp(type, "topics"))
-    return T_TOPICS;
-  else if (!strcasecmp(type, "lines"))
-    return T_LINES;
-  else if (!strcasecmp(type, "actions"))
-    return T_ACTIONS;
-  else if (!strcasecmp(type, "kicks"))
-    return T_KICKS;
-  else if (!strcasecmp(type, "modes"))
-    return T_MODES;
-  else if (!strcasecmp(type, "bans"))
-    return T_BANS;
-  else if (!strcasecmp(type, "nicks"))
-    return T_NICKS;
-  else if (!strcasecmp(type, "joins"))
-    return T_JOINS;
-  else if (!strcasecmp(type, "smileys"))
-    return T_SMILEYS;
-  else if (!strcasecmp(type, "questions"))
-    return T_QUESTIONS;
-  else if (!strcasecmp(type, "wpl"))
-    return T_WPL;
-  else if (!strcasecmp(type, "w/l"))
-    return T_WPL;
-  else if (!strcasecmp(type, "word"))
-    return T_WORD;
-  else if (!strcasecmp(type, "vocables"))
-    return T_VOCABLES;
-  else if (!strcasecmp(type, "started"))
-    return T_LSTARTED;
-  else if (!strcasecmp(type, "quote"))
-    return T_QUOTE;
-  else if (!strcasecmp(type, "idle"))
-    return T_IDLE;
-  else {
-    debug1("Stats.mod: Unknown stat type: %s", type);
-    return T_ERROR;
-  }
-}
-
-/* itotype():
- * similar to typetoi(), but returns the string that describes
- * the given type
- */
-static char *itotype(int type)
-{
-  switch (type) {
-    case T_WORDS: return "words";
-    case T_LETTERS: return "letters";
-    case T_MINUTES: return "minutes";
-    case T_TOPICS: return "topics";
-    case T_LINES: return "lines";
-    case T_ACTIONS: return "actions";
-    case T_MODES: return "modes";
-    case T_BANS: return "bans";
-    case T_KICKS: return "kicks";
-    case T_NICKS: return "nicks";
-    case T_JOINS: return "joins";
-    case T_SMILEYS: return "smileys";
-    case T_QUESTIONS: return "questions";
-    case T_WPL: return "w/l";
-    case T_IDLE: return "idle";
-    case T_VOCABLES: return "vocables";
-  }
-  return "!!!ERROR!!!";
-}
-
-static locstats *findlocstats(char *chan, char *user)
-{
-  globstats *gl;
-  locstats *ll;
-
-  for (gl = sdata; gl; gl = gl->next) {
-    if (!rfc_casecmp(gl->chan, chan))
-      break;
-  }
-  if (!gl)
-    return NULL;
-  for (ll = gl->local; ll; ll = ll->next) {
-    if (!rfc_casecmp(ll->user, user))
-      return ll;
-  }
-  return NULL;
-}
-
-static globstats *findglobstats(char *chan)
-{
-  globstats *gl;
-
-  for (gl = sdata; gl; gl = gl->next) {
-    if (!rfc_casecmp(gl->chan, chan))
-      break;
-  }
-  return gl;
-}
-
-static void write_stats()
-{
-  char s[125];
-  FILE *f;
-  struct stats_global *gs;
-  struct stats_local *ls;
-  struct stats_userlist *u;
-  struct stats_hostlist *h;
-  int i;
-
-  Context;
-  if (!statsfile[0])
-    return;
-  sprintf(s, "%s~new", statsfile);
-  f = fopen(s, "w");
-  chmod(s, statsfilemode);
-  if (f == NULL) {
-    putlog(LOG_MISC, "*", "ERROR writing stats file.");
-    return;
-  }
-  fprintf(f, "@ # Statistics from %s.\n", botnetnick);
-  fprintf(f, "@ filever 3\n");
-  fprintf(f, "@ month %d\n", getmonth());
-  for (gs = sdata; gs; gs = gs->next) {
-    fprintf(f, "%s ! %d\n", gs->chan, (int) gs->started);
-    fprintf(f, "%s @ %d\n", gs->chan, gs->peak[S_TOTAL]);
-    fprintf(f, "@ peaks %s %d %d %d %d\n", gs->chan, gs->peak[S_TOTAL],
-            gs->peak[S_DAILY], gs->peak[S_WEEKLY], gs->peak[S_MONTHLY]);
-    for (ls = gs->local; ls; ls = ls->next) {
-      fprintf(f, "%s %s %d", gs->chan, ls->user, (int) ls->started);
-      for (i = 0; i < TOTAL_TYPES; i++)
-        fprintf(f, " %ld", ls->values[S_TOTAL][i]);
-      fprintf(f, "\n");
-      fprintf(f, "@ lastspoke %d\n", (int) ls->lastspoke);
-      fprintf(f, "@ daily %s %s", gs->chan, ls->user);
-      for (i = 0; i < TOTAL_TYPES; i++)
-        fprintf(f, " %ld", ls->values[S_DAILY][i]);
-      fprintf(f, "\n");
-      fprintf(f, "@ weekly %s %s", gs->chan, ls->user);
-      for (i = 0; i < TOTAL_TYPES; i++)
-        fprintf(f, " %ld", ls->values[S_WEEKLY][i]);
-      fprintf(f, "\n");
-      fprintf(f, "@ monthly %s %s", gs->chan, ls->user);
-      for (i = 0; i < TOTAL_TYPES; i++)
-        fprintf(f, " %ld", ls->values[S_MONTHLY][i]);
-      fprintf(f, "\n");
-      i = 0;
-    }
-  }
-  for (u = suserlist; u; u = u->next) {
-    fprintf(f, "@ user %s %d %lu %lu", u->user, u->flags, u->created, u->laston);
-    for (h = u->hosts; h; h = h->next) {
-      fprintf(f, " %s %lu %lu", h->mask, h->lastused, h->created);
-    }
-    fprintf(f, "\n");
-    if (u->password || u->email || u->homepage || u->icqnr) {
-      fprintf(f, "@ uxtra %s", u->user);
-      if (u->email)
-        fprintf(f, " e %s", u->email);
-      if (u->homepage)
-        fprintf(f, " h %s", u->homepage);
-      if (u->icqnr)
-        fprintf(f, " i %d", u->icqnr);
-      if (u->password)
-        fprintf(f, " p %s", u->password);
-      fprintf(f, "\n");
-    }
-  }
-  fclose(f);
-  unlink(statsfile);
-  movefile(s, statsfile);
-  Context;
-  return;
-}
-
-static void read_stats()
-{
-  FILE *f;
-  char buf[SAVESTATSLENGTH + 1];
-  char *s, *chan, *user, *cmd, *host, *tmp;
-  int i, version, range, month, list, addhosts, flags;
-  struct stats_userlist *u;
-  time_t lastused;
-  locstats *ls;
-  globstats *gs;
-  time_t created, laston;
-
-  Context;
-  ls = NULL;
-  gs = NULL;
-  version = 0;
-  month = 0;
-  f = fopen(statsfile, "r");
-  if (f == NULL) {
-    putlog(LOG_MISC, "*", "ERROR reading stats file");
-    return;
-  }
-  free_stats();
-  while (!feof(f)) {
-    buf[0] = 0;
-    s = buf;
-    fgets(s, SAVESTATSLENGTH - 1, f);
-    s[SAVESTATSLENGTH - 1] = 0;
-    if (buf[0] == 0)
-      continue;
-    if (s[strlen(s) - 1] == '\n')
-      s[strlen(s) - 1] = 0;
-    chan = newsplit(&s);
-    if (!strcmp(chan, "@")) {
-      cmd = newsplit(&s);
-      if (!strcmp(cmd, "filever"))
-	version = atoi(newsplit(&s));
-      else if (!strcmp(cmd, "month"))
-        month = atoi(newsplit(&s));
-      else if (!strcmp(cmd, "peaks")) {
-        chan = newsplit(&s);
-        incrstats("*", chan, T_PEAK, atoi(newsplit(&s)), S_TOTAL);
-        incrstats("*", chan, T_PEAK, atoi(newsplit(&s)), S_DAILY);
-        incrstats("*", chan, T_PEAK, atoi(newsplit(&s)), S_WEEKLY);
-        incrstats("*", chan, T_PEAK, atoi(newsplit(&s)), S_MONTHLY);
-      } else if (!strcmp(cmd, "daily") || !strcmp(cmd, "weekly")
-                 || !strcmp(cmd, "monthly")) {
-        if (!strcmp(cmd, "daily"))
-	  range = S_DAILY;
-        else if (!strcmp(cmd, "weekly"))
-	  range = S_WEEKLY;
-        else if (!strcmp(cmd, "monthly"))
-          range = S_MONTHLY;
-        else {
-          debug2("Error while reading statsfile: range uninitialized! (%s %s)", cmd, s);
-          continue;
-        }
-        if ((range == S_MONTHLY) && (month != lastmonth))
-          continue;
-        chan = newsplit(&s);
-        user = newsplit(&s);
-        // Check if pointers still point to the correct data and
-        // update them, if not.
-        if ((gs && strcmp(gs->chan, chan)) || !gs) {
-          gs = findglobstats(chan);
-          ls = findlocstats(chan, user);
-        } else {
-          if ((ls && strcmp(ls->user, user)) || !ls)
-            ls = findlocstats(chan, user);
-        }
-        if (!ls)
-          ls = initstats(chan, user);
-        for (i = 0; i < TOTAL_TYPES; i++)
-          ls->values[range][i] = atoi(newsplit(&s));
-      } else if (!strcmp(cmd, "lastspoke")) {
-	if (ls) {
-	  ls->lastspoke = atoi(newsplit(&s));
-	} else {
-	  putlog(LOG_MISC, "*", "ERROR: Can't load lastspoke info. No locstats.");
-	}
-      } else if (!strcmp(cmd, "user")) {
-	user = newsplit(&s);
-	flags = 0;
-	if (version < 2) {
-	  list = atoi(newsplit(&s));
-	  addhosts = atoi(newsplit(&s));
-	  if (list)
-	    flags |= S_LIST;
-	  if (addhosts)
-	    flags |= S_ADDHOSTS;
-	} else
-	  flags = atoi(newsplit(&s));
-	if (version >= 3) {
-	  created = atoi(newsplit(&s));
-	  laston = atoi(newsplit(&s));
-	} else {
-	  created = get_creation_time_from_locstats(user);
-	  laston = get_laston_time_from_hosts(user);
-	}
-	u = addsuser(user, created, laston);
-	u->flags = flags;
-	while (s[0]) {
-	  host = newsplit(&s);
-	  lastused = (time_t) atoi(newsplit(&s));
-	  if (version >= 3)
-	    created = (time_t) atoi(newsplit(&s));
-	  else
-	    created = lastused;
-	  saddhost(u, host, lastused, created);
-	}
-      } else if (!strcmp(cmd, "uxtra")) {
-        user = newsplit(&s);
-        u = findsuser_by_name(user);
-        while (u && s[0]) {
-          tmp = newsplit(&s);
-          if (!strcmp(tmp, "e"))
-            setemail(u, newsplit(&s));
-          else if (!strcmp(tmp, "h"))
-            sethomepage(u, newsplit(&s));
-          else if (!strcmp(tmp, "i"))
-            u->icqnr = atoi(newsplit(&s));
-          else if (!strcmp(tmp, "p"))
-            setpassword(u, newsplit(&s));
-        }
-      }
-    } else {
-      // old style data
-      // left-over from v1.0. I should change it, but I don't want
-      // to break compatibility
-      user = newsplit(&s);
-      if (!strcmp(user, "!"))
-        incrstats(user, chan, T_GSTARTED, atoi(newsplit(&s)), 1);
-      else if (!strcmp(user, "@"))
-        incrstats(user, chan, T_PEAK, atoi(newsplit(&s)), S_TOTAL);
-      else {
-        incrstats(user, chan, T_LSTARTED, atoi(newsplit(&s)), 1);
-        // initstats also returns the current 'ls' if it also exists,
-        // so better don't even use findlocstats() before to save
-        // some CPU-time
-        ls = initstats(chan, user);
-        for (i = 0; i < TOTAL_TYPES; i++)
-          ls->values[S_TOTAL][i] = atoi(newsplit(&s));
-      }
-    }
-  }
-  fclose(f);
-  Context;
-  return;
-}
-
-static void reset_tstats()
-{
-  globstats *gs;
-  locstats *ls;
-  int i;
-
-  Context;
-  putlog(LOG_MISC, "*", "Stats.mod: Resetting today's statistics...");
-  for (gs = sdata; gs; gs = gs->next) {
-    gs->peak[S_TODAY] = 0;
-    free_wordstats(gs->words);
-    gs->words = NULL;
-    free_topics(gs->topics);
-    gs->topics = NULL;
-    free_urls(gs->urls);
-    gs->urls = NULL;
-    free_hosts(gs->hosts);
-    gs->hosts = NULL;
-    free_kicks(gs->kicks);
-    gs->kicks = NULL;
-    for (ls = gs->local; ls; ls = ls->next) {
-      free_wordstats(ls->words);
-      ls->words = NULL;
-      ls->tree = NULL;
-      free_quotes(ls->quotes);
-      ls->quotes = NULL;
-      for (i = 0; i < TOTAL_TYPES; i++)
-        ls->values[S_TODAY][i] = 0;
-    }
-  }
-  Context;
-}
-
-static void reset_mwstats(int range)
-{
-  globstats *gs;
-  locstats *ls;
-  int i;
-
-  Context;
-  putlog(LOG_MISC, "*", "Stats.mod: Resetting %s statistics...", (range == S_WEEKLY) ? "weekly" : "monthly");
-  for (gs = sdata; gs; gs = gs->next) {
-    gs->peak[range] = 0;
-    for (ls = gs->local; ls; ls = ls->next) {
-      for (i = 0; i < TOTAL_TYPES; i++)
-        ls->values[range][i] = 0;
-    }
-  }
-  Context;
-}
-
-static void sort_stats_alphabetically(globstats *gs)
-{
-  locstats *as, *bs, *l, *last;
-  int a, b, again = 1;
-  char *astr, *bstr, n[2];
-
-  Context;
-  n[0] = n[1] = 0;
-  last = NULL;
-  while ((gs->local != last) && again) {
-    again = 0;
-    l = NULL;
-    as = gs->local;
-    bs = gs->local->next;
-    while(bs) {
-      if (!as)
-        astr = n;
-      else
-        astr = as->user;
-      if (!bs)
-        bstr = n;
-      else
-        bstr = bs->user;
-      a = (int) tolower(astr[0]);
-      b = (int) tolower(bstr[0]);
-      while ((a == b) && a && b) {
-	astr++;
-	bstr++;
-        a = (int) tolower(astr[0]);
-        b = (int) tolower(bstr[0]);
-      }
-      if (a > b) {
-        if (!l)
-          gs->local = bs;
-        else
-          l->next = bs;
-        as->next = bs->next;
-        bs->next = as;
-        again = 1;
-        if (l == NULL)
-          gs->local = bs;
-        else
-          l = bs;
-      }
-      l = as;
-      as = bs;
-      bs = bs->next;
-    }
-    last = as;
-  }
-  Context;
-}
-
-static void resetlocstats(locstats *ls)
-{
-  int i;
-
-  if (!ls) {
-    debug0("ERROR! resetlocstats called with NULL pointer!");
-    return;
-  }
-  for (i = 0; i < TOTAL_TYPES; i++) {
-    ls->values[S_TOTAL][i] = 0;
-    ls->values[S_TODAY][i] = 0;
-    ls->values[S_WEEKLY][i] = 0;
-    ls->values[S_MONTHLY][i] = 0;
-  }
-  return;
-}
-
-static void calcwordstats(char *hand, globstats *gs, char *rest, locstats *stats)
-{
-  locstats *ls;
-  char *word;
-  int i;
-
-  Context;
-  if (!log_wordstats)
-    return;
-  if (!gs) {
-    debug1("Can't calculate wordstats for %s, no globstats.", hand);
-    return;
-  }
-  if (stats)
-    ls = stats;
-  else {
-    for (ls = gs->local; ls; ls = ls->next)
-      if (!rfc_casecmp(hand, ls->user))
-        break;
-  }
-  if (!ls) {
-    debug2("Can't calculate wordstats for %s in %s, no locstats.", hand, gs->chan);
-    return;
-  }
-  for (i = 0; i < strlen(rest); i++)
-    if (strchr("!?.,\"<>&\\", rest[i]))
-      rest[i] = ' ';
-  while (rest[0]) {
-    word = newsplit(&rest);
-    strlower(word);
-    incrwordstats(ls, word, 1, 0);
-  }
-}
-
-// add another entry to the tree
-static void incrwordstats(locstats *ls, char *word, int value, int set)
-{
-  wordstats *ne, *te, *le;
-  wordstats *ll;
-  int cmp;
-
-  Context;
-  if ((word[0] == ' ') || !word[0])
-    return;
-  if (min_word_length && (strlen(word) < min_word_length))
-    return;     /* only log words that are longer than min_word_length chars */
-  if (!ls) {
-    return;
-  }
-  // at first, check if it already exists and only needs to be updated
-  te = ls->tree;
-  le = NULL;
-  while (te) {
-    if (!(cmp = strcasecmp(te->word, word)))
-      break;
-    le = te;
-    if (cmp < 0)
-      te = te->left;
-    else
-      te = te->right;
-  }
-  if (!te) { // nothing to update, so let's append a new node
-    ne = nmalloc(sizeof(struct stats_words));
-    ne->word = nmalloc(strlen(word) + 1);
-    strcpy(ne->word, word);
-    ne->nr = 0;
-    ne->left = ne->right = ne->next = NULL;
-    if (!le)  // no last entry -> new entry is going to be the crown
-      ls->tree = ne;
-    else {
-      if (strcasecmp(le->word, word) < 0)  // -1 -> left child
-        le->left = ne;
-      else                                  // 1 -> right child
-        le->right = ne;
-    }
-    // now let's add it also to the linked list (needed for sorting)
-    ll = ls->words;
-    while (ll && ll->next)
-      ll = ll->next;
-    if (ll)
-      ll->next = ne;
-    else
-      ls->words = ne;
-    te = ne;
-  }
-  // now let's set the value
-  if (set)
-    te->nr = value;
-  else
-    te->nr += value;
-}
-
-static void nincrwordstats(globstats *gs, char *word, int value)
-{
-  wordstats *l, *ll;
-
-  for (l = gs->words; l; l = l->next)
-    if (!strcmp(word, l->word))
-      break;
-  if (!l) {
-    l = gs->words;
-    while (l && l->next)
-      l = l->next;
-    ll = nmalloc(sizeof(wordstats));
-    ll->word = nmalloc(strlen(word) + 1);
-    strcpy(ll->word, word);
-    ll->nr = 0;
-    ll->next = NULL;
-    if (l)
-      l->next = ll;
-    else
-      gs->words = ll;
-    l = ll;
-  }
-  l->nr += value;
-}
-
-static time_t glob_lastglobwordstats;
-static void do_globwordstats(globstats *gs)
-{
-  wordstats *l;
-  locstats *ls;
-
-  if (glob_lastglobwordstats == now)
-    return; /* don't recalculate everything if we already did it in this second */
-  debug0("calculating global wordstats");
-  glob_lastglobwordstats = now;
-  for (l = gs->words; l; l = l->next)
-    l->nr = 0;
-  for (ls = gs->local; ls; ls = ls->next)
-    for (l = ls->words; l; l = l->next)
-      nincrwordstats(gs, l->word, l->nr);
-  sortwordstats(NULL, gs);
-}
-
-static void addquote(char *user, globstats *gs, char *quote, locstats *stats)
-{
-  quotestr *l, *nl;
-  locstats *ls;
-
-  if (!quote_freq)
-    return;
-  if (!gs) {
-    debug1("Can't add quote to %s, no globstats.", user);
-    return;
-  }
-  if (stats)
-    ls = stats;
-  else {
-    for (ls = gs->local; ls; ls = ls->next)
-      if (!rfc_casecmp(user, ls->user))
-        break;
-  }
-  if (!ls) {
-    debug2("Can't add quote to %s in %s, no locstats.", user, gs->chan);
-    return;
-  }
-  ls->quotefr--;
-  if (ls->quotefr > 0)
-    return;
-  ls->quotefr = quote_freq;
-  l = ls->quotes;
-  while (l && l->next)
-    l = l->next;
-  nl = nmalloc(sizeof(quotestr));
-  nl->next = NULL;
-  nl->quote = nmalloc(strlen(quote) + 1);
-  strcpy(nl->quote, quote);
-  if (l)
-    l->next = nl;
-  else
-    ls->quotes = nl;
-}
-
-static void addtopic(char *channel, char *topic, char *by)
-{
-  topicstr *e, *ne;
-  globstats *gs;
-
-  Context;
-  gs = findglobstats(channel);
-  if (!gs)
-    return;
-  for (e = gs->topics; e; e = e->next)
-    if (!strcasecmp(topic, e->topic))
-      return;
-  e = gs->topics;
-  while (e && e->next)
-    e = e->next;
-  ne = nmalloc(sizeof(topicstr));
-  ne->topic = nmalloc(strlen(topic) + 1);
-  strcpy(ne->topic, topic);
-  ne->by = nmalloc(strlen(by) + 1);
-  strcpy(ne->by, by);
-  ne->when = now;
-  ne->next = NULL;
-  if (e)
-    e->next = ne;
-  else
-    gs->topics = ne;
-}
-
-static void addhost(char *host, globstats *gs)
-{
-  hoststr *e, *ne;
-  char *s;
-
-  if (!gs || !host)
-    return;
-  s = strchr(host, '@');
-  if (s)
-    host = s + 1;
-  if (strcmp(host, "[IP]"))
-    strlower(host);
-  for (e = gs->hosts; e; e = e->next) {
-    if (!strcmp(host, e->host)) {
-      e->nr++;
-      return;
-    }
-  }
-  e = gs->hosts;
-  while (e && e->next)
-    e = e->next;
-  ne = nmalloc(sizeof(hoststr));
-  ne->host = nmalloc(strlen(host) + 1);
-  strcpy(ne->host, host);
-  ne->nr = 1;
-  ne->next = NULL;
-  if (e)
-    e->next = ne;
-  else
-    gs->hosts = ne;
-  return;
-}
-
-static void setword(globstats *gs, char *word)
-{
-  locstats *l;
-  wordstats *w;
-
-  for (l = gs->local; l; l = l->next) {
-    l->word = NULL;
-    for (w = l->words; w; w = w->next) {
-      if (!strcmp(w->word, word)) {
-        l->word = w;
-        break;
-      }
-    }
-  }
-}
-
-static int track_stat_user(char *oldnick, char *newnick)
-{
-  globstats *gs;
-  locstats *ls;
-  struct stats_userlist *u;
-  int found = 0;
-
-  Context;
-  for (gs = sdata; gs; gs = gs->next) {
-    for (ls = gs->local; ls; ls = ls->next) {
-      if (!rfc_casecmp(oldnick, ls->user) && strcmp(newnick, ls->user)) {
-        nfree(ls->user);
-        ls->user = nmalloc(strlen(newnick) + 1);
-        strcpy(ls->user, newnick);
-        // ls->u should still be valid...
-        found = 1;
-        debug3("Transferred stats from %s to %s in %s", oldnick, newnick, gs->chan);
-      }
-    }
-  }
-  for (u = suserlist; u; u = u->next) {
-    if (!rfc_casecmp(oldnick, u->user) && strcmp(newnick, u->user)) {
-      nfree(u->user);
-      u->user = nmalloc(strlen(newnick) + 1);
-      strcpy(u->user, newnick);
-      found = 1;
-      debug2("Changed user name from %s to %s in my local database.", oldnick, newnick);
-    }
-  }
-  if (found)
-    return 1;
-  return 0;
-}
-
-static void check_for_url(char *user, char *chan, char *text)
-{
-  char *p, *url;
-  char *tmp, *tmp2, *t;
-  struct stats_url *e, *ne;
-  globstats *gs;
-  int weiter;
-
-  if (log_urls < 1)
-    return;
-  gs = findglobstats(chan);
-  if (!gs)
-    return;
-  url = p = tmp = tmp2 = t = NULL;
-  if ((p = strstr(text, "http://")))
-    url = newsplit(&p);
-  else if ((p = strstr(text, "ftp://")))
-    url = newsplit(&p);
-  else if (strstr(text, "www.") || strstr(text, ".com") || strstr(text, "ftp.")) {
-    tmp = nmalloc(strlen(text) + 1);
-    strcpy(tmp, text);
-    t = tmp;
-    while (t[0]) {
-      p = newsplit(&t);
-      if (strstr(p, "www.") || strstr(p, ".com") || strstr(text, "ftp.")) {
-        url = p;
-        break;
-      }
-    }
-  }
-  if (!url)
-    return;
-  if (strchr(url, '@')) { /* probably an email address or something similar */
-    if (tmp)
-      nfree(tmp);
-    return;
-  }
-  if (strncasecmp(url, "http://", 7) && strncasecmp(url, "ftp://", 6)) {
-    if (!strncasecmp(url, "ftp.", 4)) {
-      tmp2 = nmalloc(strlen(url) + 6 + 1);
-      strcpy(tmp2, "ftp://");
-      strcpy(tmp2 + 6, url);
-    } else {
-      tmp2 = nmalloc(strlen(url) + 7 + 1);
-      strcpy(tmp2, "http://");
-      strcpy(tmp2 + 7, url);
-    }
-    url = tmp2;
-  }
-  for (e = gs->urls; e; e = e->next) {
-    if (!strcmp(e->url, url)) {
-      nfree(e->by);
-      e->by = nmalloc(strlen(user) + 1);
-      strcpy(e->by, user);
-      e->when = now;
-      if (tmp)
-        nfree(tmp);
-      if (tmp2)
-        nfree(tmp2);
-      return;
-    }
-  }
-  weiter = 1;
-  for (p = url; (p != url) && weiter; p--) {
-    if (strchr(".!?,#", p[0]))
-      p[0] = 0;
-    else
-      weiter = 0;
-  }
-  for (e = gs->urls; e && e->next; e = e->next);
-  ne = nmalloc(sizeof(struct stats_url));
-  ne->url = nmalloc(strlen(url) + 1);
-  strcpy(ne->url, url);
-  ne->by = nmalloc(strlen(user) + 1);
-  strcpy(ne->by, user);
-  ne->when = now;
-  ne->next = NULL;
-  if (e)
-    e->next = ne;
-  else
-    gs->urls = ne;
-  if (tmp)
-    nfree(tmp);
-  if (tmp2)
-    nfree(tmp2);
-  debug2("Logged URL: \"%s\" mentioned by %s.", ne->url, ne->by);
-}
-
-static void add_chanlog(globstats *gs, char *nick, char *text, int type)
-{
-  char ts[20];
-  time_t tt, ttbuf;
-  quotestr *newlog, *l;
-
-  if (!gs || (kick_context < 1))
-    return;
-  ttbuf = tt = now;
-  strftime(ts, 19, "[%H:%M:%S]", localtime(&tt));
-  newlog = nmalloc(sizeof(quotestr));
-  newlog->next = NULL;
-  if (type == SL_PRIVMSG) {
-    newlog->quote = nmalloc(strlen(nick) + strlen(ts) + strlen(text) + 5);
-    sprintf(newlog->quote, "%s <%s> %s", ts, nick, text);
-  } else if (type == SL_KICK) {
-    newlog->quote = nmalloc(strlen(text) + strlen(ts) + 2);
-    sprintf(newlog->quote, "%s %s", ts, text);
-  } else if (type == SL_MODE) {
-    newlog->quote = nmalloc(strlen(ts) + strlen(text) + 2);
-    sprintf(newlog->quote, "%s %s", ts, text);
-  } else if (type == SL_NICK) {
-    newlog->quote = nmalloc(strlen(ts) + strlen(nick) + strlen(text) + 19);
-    sprintf(newlog->quote, "%s %s changed nick to %s", ts, nick, text);
-  } else if (type == SL_PART) {
-    newlog->quote = nmalloc(strlen(ts) + strlen(nick) + strlen(gs->chan) + 12);
-    sprintf(newlog->quote, "%s %s has left %s", ts, nick, gs->chan);
-  } else if (type == SL_JOIN) {
-    newlog->quote = nmalloc(strlen(ts) + strlen(nick) + strlen(gs->chan) + 14);
-    sprintf(newlog->quote, "%s %s has joined %s", ts, nick, gs->chan);
-  } else if (type == SL_QUIT) {
-    newlog->quote = nmalloc(strlen(ts) + strlen(nick) + strlen(text) + 18);
-    sprintf(newlog->quote, "%s %s has quit IRC (%s)", ts, nick, text);
-  } else {
-    debug1("Unknown log-type: %d !!!", type);
-    newlog->quote = nmalloc(1);
-    newlog->quote[0] = 0;
-  }
-  if (gs->lastlog)
-    gs->lastlog->next = newlog;
-  else
-    gs->log = newlog;
-  gs->lastlog = newlog;
-  gs->log_length++;
-  while ((gs->log_length > kick_context) && (gs->log_length > 0)) {
-    l = gs->log->next;
-    Assert(gs->log->quote);
-    nfree(gs->log->quote);
-    if (gs->lastlog == gs->log)
-      gs->lastlog = NULL;
-    nfree(gs->log);
-    gs->log = l;
-    gs->log_length--;
-  }
-  ctime(&ttbuf); /* workaround for a bug in older eggdrops */
-}
-
-static void save_kick(globstats *gs, char *kick)
-{
-  struct stats_kick *k, *nk;
-  quotestr *log, *l, *nl;
-
-  Context;
-  if (!gs)
-    return;
-  for (k = gs->kicks; k && k->next; k = k->next);
-  nk = nmalloc(sizeof(struct stats_kick));
-  nk->next = NULL;
-  nk->log = NULL;
-  if (!gs->log || (kick_context < 1)) {
-    nl = nmalloc(sizeof(quotestr));
-    nl->quote = nmalloc(strlen(kick) + 1);
-    strcpy(nl->quote, kick);
-    nl->next = NULL;
-    nk->log = nl;
-  } else {
-    for (log = gs->log; log; log = log->next) {
-      nl = nmalloc(sizeof(quotestr));
-      nl->quote = nmalloc(strlen(log->quote) + 1);
-      strcpy(nl->quote, log->quote);
-      nl->next = NULL;
-      for (l = nk->log; l && l->next; l = l->next);
-      if (l)
-        l->next = nl;
-      else
-        nk->log = nl;
-    }
-  }
-  if (k)
-    k->next = nk;
-  else
-    gs->kicks = nk;
-  debug1("Logged kick in %s.", gs->chan);
-}
-
-static int getplace(globstats *gs, int today, int itype, char *user)
-{
-  locstats *ls;
-  int place = 0;
-
-  // if itype is < 0, get the modified itype that we need for accessing the data
-  if (itype < 0)
-    itype = (TOTAL_TYPES - 1) + (itype * -1);
-  for (ls = gs->slocal[today][itype]; ls; ls = ls->snext[today][itype]) {
-    if (!listsuser(ls, gs->chan))
-      continue;
-    place++;
-    if (!rfc_casecmp(ls->user, user))
-      return place;
-  }
-  return 0;
-}

+ 67 - 57
README

@@ -1,21 +1,22 @@
 Description:
 ------------
 
-Stats.mod generates statistics about the users in a channel. It counts
-the words that the users have spoken, the lines, actions, smileys,
-joins, quits, mode changes, topic changes, nick changes, kicks and how
-long the user has been on the channel. Depending on the configuration,
-it even logs the user's favourite words and the most used words on
-the channel.
+Stats.mod generates statistics about the users in a channel. It some data about
+the users like spoken words, lines, time spent in the channel, etc...
+
+It makes those stats accessible either via commands in the channel (!top, ...),
+or through an included webserver which generates statistic-webpages in
+rea-time ("livestats").
+
+A demonstration of this functionality can be found on the homepage of
+this module: http://www.visions-of-fantasy.de/stats.mod/
 
-The statistics are accessable via public commands (!top10, !stat...)
-and via http.
 
 
 Installation:
 -------------
 
-Stats.mod will work with eggdrop1.6.x and eggdrop1.4.x.
+Stats.mod will work with eggdrop1.6.x and probably eggdrop1.4.x.
 
 The following instructions assume, ~/eggdrop1.6/ is the directory
 where you installed your eggdrop from. (of course, other source dirs
@@ -24,14 +25,16 @@ Unfortunately, you need to compile stats.mod within your eggdrop source,
 so if you removed your original compile directory, you'll have to
 compile the whole bot again... sorry.
 
-Put stats.mod.1.3.2.tar.gz in ~/eggdrop1.6/src/mod/,
-and unpack it (tar xfz stats.mod.1.3.2.tar.gz). Change directory
+Put stats.mod.1.4.0.tar.gz in ~/eggdrop1.6/src/mod/,
+and unpack it (tar xfz stats.mod.1.4.0.tar.gz). Change directory
 back to ~/eggdrop1.6/. Type 'make config' (on eggdrop 1.4, you can skip
 that part) Type 'make', wait until compiling
 is done and use 'make install' to install the bot and stats.mod.
 
-Don't forget to copy the language files from ~/eggdrop1.6/src/mod/stats.mod/ to
-~/eggdrop/language/ !
+Don't forget to copy the language files from 
+~/eggdrop1.6/src/mod/stats.mod/language/ to ~/eggdrop/language/
+and the templates from
+~/eggdrop1.6/src/mod/stats.mod/templates to ~/eggdrop/templates/!
 
 All settings can be found in ~/eggdrop1.6/src/mod/stats.mod/stats.conf
 I suggest to copy it to your eggdrop directory (probably ~/eggdrop/),
@@ -44,42 +47,54 @@ restart or rehash.
 Public commands:
 ----------------
 
-!top10 [ordering]
-  lists the top10 users in the channel
-!top20 [ordering]
-  same as !top10, but lists the top20 (surprise!)
+!top [num] [today|weekly|monthly|total] [ordering]
+  lists the top[num] users in the channel
+  
 !stat [user]
   shows the statistics for the user
+
 !place [user/ordering]
   shows on which place the user is
-!ttop10/!ttop20/!tstat/!tplace
-  same as above, but only uses the statistics of today
+
+!lastspoke <user>
+  shows when the user has last spoken a word on the channel
+  (this isn't the same as the idle-time which other script provide with this
+   command, since the idle time also changes with join/part/etc. This command
+   return when a user really has sent some text to the channel)
+
 
 Only available if log-wordstats is turned on:
 !wordstats [user]
   lists the most used words of the user
 !topwords
   lists the most used words in the channel
-!top10 word <word>
+!top word <word>
   lists the top10 people who used <word>
 
+
+
+
 Msg commands:
 -------------
 
 All public commands are also accessible via /msg.
-("/msg <bot> top10 #chan", for example)
+("/msg <bot> top #chan", for example)
 
 
 Additionally, there are two new commands:
 
-/msg <bot> setemail <email-address>
-  sets your email address
-/msg <bot> sethomepage <homepage-address>
-  sets the URL of your homepage
+/msg <bot> statspass <password>
+  with this command, a user can set a password for his statistics-account,
+  so he can log on at the webpage and edit his settings
+
+
 
-DCC commands:
+
+DCC commands (for administration):
 -------------
 
+.savestats
+  saves the database now
 .+suser <user> [host]
   adds a new user to the database
 .-suser <user>
@@ -105,10 +120,9 @@ DCC commands:
 .resetuser <user> <channel>
   sets all statistics of user in channel to 0
   (m|-)
+.swhois
+  displays a stats-account
 
-.writewebstats
-  writes the old, static webfiles
-  (m|-)
 
 TCL commands:
 -------------
@@ -132,15 +146,29 @@ resetslang
   removes every language from the memory, so you can cleanly load a new
   set of languages.
 
-loadslang [lang] <langfile>
+loadstatslang [lang] <langfile>
   loads a language
 
+loadstatsskin <skin-file>
+  loads a skin for livestats
+
 setchanslang <channel> <language>
   sets the language in <channel> to <language>
 
 nick2suser <nick> <channel>
   returns the username of <nick> in <chan>
 
+activeusers [chan]
+  returns all users that have a word-count over 0
+
+suserlist
+  returns a list of all users in stats.mod database
+
+schattr user [+/-list] [+/-addhosts] ...
+  changes attributes of a user
+
+
+
 
 Livestats:
 ----------
@@ -151,8 +179,9 @@ http connections. (accessable via http://your.shell.com:8033/, for example
 The webfiles will then be generated on the fly. There will also be a little
 channel and user list which makes it easier for your users to browse through
 the several channel statistics of your bot.
-  This method also uses less cpu power than the frequently written webfiles,
-because only the file that is really needed is generated. 
+  Users can also enter a private configuration-area on this website where they
+can enter some information (eMail-address, homepage, icq-number, etc) and
+change some options.
   Use .console +1 to see access, or use the setting stats-loglevel to
 change the loglevel.
   Stats.mod is now also able to log the access to a CLF logfile, so you can
@@ -161,16 +190,8 @@ use your favourite loganalyzer to generate stats of the stats access. :)
 Hint: If you don't want a channel to be listed on the index,
 ----  just set it +secret.
 
-Static Webfiles:
----------------
 
-If there's really no way to use livestats, stats.mod can also generate static
-web files.
-In this case, it simply mirrors the whole livestats server into a directory
-on your shell. Of course, this takes some time. You bot won't be able to
-do anything while it's generating the files, so only use it if there's no
-other way. (expect an occasional ping timeout on large channels)
-Be sure that you chose an empty output directory.
+
 
 User management:
 ----------------
@@ -186,12 +207,16 @@ completely.
 new hosts to a user manually. The affected user should cycle the chan to make
 sure that he's recognized correctly by stats.mod.
 
-There are two flags for users: +/-list and +/-addhosts:
+There are three flags for users: +/-list, +/-addhosts and +/-nostats:
 - If a user has the flag -list, he/she/it won't be listed in the top10. (you
   probably want to set all your bot -list)
 - If a user is -addhosts, no new hostmasks will be added to him/her. You'll
   have to add all hosts manually with .+shost. (useful if someone if trying
   to fake you)
+- Hat ein Benutzer +nostats gesetzt, dann werden seine Statistiken nirgendwo
+  angezeigt.(manche Leute legen diesbezüglich vielleicht Wert auf Privatsphäre)
+
+
 
 Channel settings:
 -----------------
@@ -214,21 +239,6 @@ There is absolutely NO WARRANTY on this module. I do my best to make it
 work properly, but if anything gets screwed up, I'm not responsible. Use
 this module at your own risk.
 
-Known problems:
----------------
-
-There can be a problem if you use wordstats on a bot with enabled memory
-debugging. The reset of the daily stats might take a long time on slow shells.
-If your bot is on big channels, your memory table might be too small.
-Edit src/mem.c and change the #define that sets the size of the memtable
-(#define MEMTBLSIZE 25000      /* yikes! */) to a higher value.
-
-Feedback:
----------
-
-Feel free to send feedback and bugreports(I hope there won't be any<g>) to
-stats.mod@visions-of-fantasy.de
-
 Homepage:
 ---------
 

+ 2 - 0
UPDATES

@@ -14,6 +14,8 @@ Changes in Stats.mod: (since v1.0.1)
 - added filter for stupid color-codes
 - new way of expireing users
 - new command: !lastspoke
+- new users get greeted
+- added tcl command [suserlist]
 
 
 1.3.2

+ 244 - 0
backup/README

@@ -0,0 +1,244 @@
+Description:
+------------
+
+Stats.mod generates statistics about the users in a channel. It counts
+the words that the users have spoken, the lines, actions, smileys,
+joins, quits, mode changes, topic changes, nick changes, kicks and how
+long the user has been on the channel. Depending on the configuration,
+it even logs the user's favourite words and the most used words on
+the channel.
+
+The statistics are accessable via public commands (!top10, !stat...)
+and via http.
+
+
+Installation:
+-------------
+
+Stats.mod will work with eggdrop1.6.x and eggdrop1.4.x.
+
+The following instructions assume, ~/eggdrop1.6/ is the directory
+where you installed your eggdrop from. (of course, other source dirs
+will work as well)
+Unfortunately, you need to compile stats.mod within your eggdrop source,
+so if you removed your original compile directory, you'll have to
+compile the whole bot again... sorry.
+
+Put stats.mod.1.3.2.tar.gz in ~/eggdrop1.6/src/mod/,
+and unpack it (tar xfz stats.mod.1.3.2.tar.gz). Change directory
+back to ~/eggdrop1.6/. Type 'make config' (on eggdrop 1.4, you can skip
+that part) Type 'make', wait until compiling
+is done and use 'make install' to install the bot and stats.mod.
+
+Don't forget to copy the language files from ~/eggdrop1.6/src/mod/stats.mod/ to
+~/eggdrop/language/ !
+
+All settings can be found in ~/eggdrop1.6/src/mod/stats.mod/stats.conf
+I suggest to copy it to your eggdrop directory (probably ~/eggdrop/),
+edit it to fit your needs and put a 'source stats.conf' at the end of
+your eggdrop config file. This will execute the config file with every
+restart or rehash.
+
+
+
+Public commands:
+----------------
+
+!top10 [ordering]
+  lists the top10 users in the channel
+!top20 [ordering]
+  same as !top10, but lists the top20 (surprise!)
+!stat [user]
+  shows the statistics for the user
+!place [user/ordering]
+  shows on which place the user is
+!ttop10/!ttop20/!tstat/!tplace
+  same as above, but only uses the statistics of today
+
+Only available if log-wordstats is turned on:
+!wordstats [user]
+  lists the most used words of the user
+!topwords
+  lists the most used words in the channel
+!top10 word <word>
+  lists the top10 people who used <word>
+
+Msg commands:
+-------------
+
+All public commands are also accessible via /msg.
+("/msg <bot> top10 #chan", for example)
+
+
+Additionally, there are two new commands:
+
+/msg <bot> setemail <email-address>
+  sets your email address
+/msg <bot> sethomepage <homepage-address>
+  sets the URL of your homepage
+
+DCC commands:
+-------------
+
+.+suser <user> [host]
+  adds a new user to the database
+.-suser <user>
+  removes a user from the database
+.+shost <user> <hostmask>
+  adds a new hostmask to <user>
+.-shost <user> <hostmask>
+  removes a hostmask from <user>
+.smatch [mask] [+/-list] [+/-addhosts]
+  lists all matching users
+.schannel #chan
+  displays the stats-users in a channel
+.schattr <user> <flags>
+  changes the flags for a stats user
+.chsusername <oldname> <newname>
+  changes the name of a user in the stats database
+.purgestats
+  deletes stats for non-existant users, empty stats and deletes expired users.
+  (m|-)
+.sumuser <user1> <user2>
+  adds all statistics of user2 to user1 and deletes user2
+  (n|-)
+.resetuser <user> <channel>
+  sets all statistics of user in channel to 0
+  (m|-)
+
+.writewebstats
+  writes the old, static webfiles
+  (m|-)
+
+TCL commands:
+-------------
+
+incrstats <user> <chan> <type> <value> [set]
+  increases the statistics of type <type> in <chan> for <user> by <value>.
+  If <set> is 1, the stats are not increased but set to the value.
+
+getstats <user> <chan> <type> [today]
+  returns the stats of <user> in <chan> of type <type>. If <today> is 1,
+  the statistics of today are returned.
+
+livestats <port>
+  starts listening for livestats connections on port <port>.
+  If <port> is "off" or "0", the bot will stop listening.
+
+resetuser <user> <channel>
+  sets all statistics of user in channel to 0
+
+resetslang
+  removes every language from the memory, so you can cleanly load a new
+  set of languages.
+
+loadslang [lang] <langfile>
+  loads a language
+
+setchanslang <channel> <language>
+  sets the language in <channel> to <language>
+
+nick2suser <nick> <channel>
+  returns the username of <nick> in <chan>
+
+
+Livestats:
+----------
+
+If you activate livestats, your bot will listen on a specified port for
+http connections. (accessable via http://your.shell.com:8033/, for example
+(depending on your configuration, you might have to use your vhost instead))
+The webfiles will then be generated on the fly. There will also be a little
+channel and user list which makes it easier for your users to browse through
+the several channel statistics of your bot.
+  This method also uses less cpu power than the frequently written webfiles,
+because only the file that is really needed is generated. 
+  Use .console +1 to see access, or use the setting stats-loglevel to
+change the loglevel.
+  Stats.mod is now also able to log the access to a CLF logfile, so you can
+use your favourite loganalyzer to generate stats of the stats access. :)
+
+Hint: If you don't want a channel to be listed on the index,
+----  just set it +secret.
+
+Static Webfiles:
+---------------
+
+If there's really no way to use livestats, stats.mod can also generate static
+web files.
+In this case, it simply mirrors the whole livestats server into a directory
+on your shell. Of course, this takes some time. You bot won't be able to
+do anything while it's generating the files, so only use it if there's no
+other way. (expect an occasional ping timeout on large channels)
+Be sure that you chose an empty output directory.
+
+User management:
+----------------
+
+Since v1.3.0, stats.mod has an internal userdatabase. It can automatically
+add users and hostmasks to it. Users which are in the eggdrop userfile have a
+higher priority, so if someone is known as "bla" by the bot and as "blub"
+by stats.mod, his stats will be logged to "bla".
+  Hostmasks will be removed from a user if they haven't been used for a
+specified time. If all hosts got removed from a user, the user will be erased
+completely.
+  Note that stats.mod can't know when someone used IDENT or if someone added
+new hosts to a user manually. The affected user should cycle the chan to make
+sure that he's recognized correctly by stats.mod.
+
+There are two flags for users: +/-list and +/-addhosts:
+- If a user has the flag -list, he/she/it won't be listed in the top10. (you
+  probably want to set all your bot -list)
+- If a user is -addhosts, no new hostmasks will be added to him/her. You'll
+  have to add all hosts manually with .+shost. (useful if someone if trying
+  to fake you)
+
+Channel settings:
+-----------------
+
+If you're using eggdrop 1.5 or later, you have some additional config options
+available via .chanset:
+
++nopubstats
+	Disables all channel commands (!top10 etc...)
++quietstats
+	Bot will reply with a notice directly to the user instead of
+	sending the reply to the channel
++nostats
+	Don't log any stats in this chan at all.
+
+Other:
+------
+
+There is absolutely NO WARRANTY on this module. I do my best to make it
+work properly, but if anything gets screwed up, I'm not responsible. Use
+this module at your own risk.
+
+Known problems:
+---------------
+
+There can be a problem if you use wordstats on a bot with enabled memory
+debugging. The reset of the daily stats might take a long time on slow shells.
+If your bot is on big channels, your memory table might be too small.
+Edit src/mem.c and change the #define that sets the size of the memtable
+(#define MEMTBLSIZE 25000      /* yikes! */) to a higher value.
+
+Feedback:
+---------
+
+Feel free to send feedback and bugreports(I hope there won't be any<g>) to
+stats.mod@visions-of-fantasy.de
+
+Homepage:
+---------
+
+The latest version of stats.mod(and a few addons) can always be found at
+http://www.visions-of-fantasy.de/stats.mod/
+
+Thanks to:
+----------
+
+- Fabian for teaching me plenty of things
+- Johoho, Fox_Muld and many others for various bug reports and suggestions
+- dw for the idea of livestats and for many bug reports
+- the eggdev team for developing eggdrop

+ 0 - 16
compat/CVS/Entries

@@ -1,16 +0,0 @@
-/Makefile.in/1.5/Tue Sep 12 15:26:51 2000//
-/gnu_strftime.c/1.1/Mon Sep 18 10:06:14 2000//
-/strftime.h/1.1/Tue Sep 12 15:34:01 2000//
-/compat.h/1.3/Thu Apr 12 23:00:04 2001//
-/inet_aton.c/1.5/Thu Apr 12 23:00:04 2001//
-/inet_aton.h/1.3/Thu Apr 12 23:00:04 2001//
-/memcpy.c/1.2/Thu Apr 12 23:00:04 2001//
-/memcpy.h/1.3/Thu Apr 12 23:00:04 2001//
-/memset.c/1.3/Thu Apr 12 23:00:04 2001//
-/memset.h/1.3/Thu Apr 12 23:00:04 2001//
-/snprintf.c/1.4/Thu Apr 12 23:00:04 2001//
-/snprintf.h/1.7/Thu Apr 12 23:00:04 2001//
-/strcasecmp.c/1.2/Thu Apr 12 23:00:04 2001//
-/strcasecmp.h/1.3/Thu Apr 12 23:00:04 2001//
-/strftime.c/1.2/Thu Apr 12 23:00:04 2001//
-D

+ 0 - 1
compat/CVS/Repository

@@ -1 +0,0 @@
-eggdrop1.6/src/compat

+ 0 - 1
compat/CVS/Root

@@ -1 +0,0 @@
-:pserver:anonymous@cvs.eggheads.org:/usr/local/cvsroot

+ 1 - 1
compat/Makefile

@@ -1,6 +1,6 @@
 # Generated automatically from Makefile.in by configure.
 # Makefile for src/compat/
-# $Id: Makefile.in,v 1.5 2000/09/12 15:26:51 fabian Exp $
+# $Id: Makefile,v 1.1 2005/04/08 13:48:26 Administrator Exp $
 
 SHELL = /bin/sh
 top_srcdir = ../..

+ 92 - 92
compat/Makefile.in

@@ -1,92 +1,92 @@
-# Makefile for src/compat/
-# $Id: Makefile.in,v 1.5 2000/09/12 15:26:51 fabian Exp $
-
-SHELL = @SHELL@
-top_srcdir = @top_srcdir@
-srcdir = @srcdir@
-VPATH = @srcdir@
-
-@SET_MAKE@
-INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-
-CC = @CC@
-LD = @CC@
-STRIP = @STRIP@
-CFLAGS = @CFLAGS@ -I../.. -I$(top_srcdir) -I$(top_srcdir)/src @DEFS@ $(CFLGS)
-CPPFLAGS = @CPPFLAGS@
-
-OBJS = inet_aton.o snprintf.o memset.o memcpy.o strcasecmp.o strftime.o
-
-doofus:
-	@echo ""
-	@echo "Let's try this from the right directory..."
-	@echo ""
-	@cd ../.. && $(MAKE)
-
-depend:
-	$(CC) $(CFLAGS) $(CPPFLAGS) -MM $(srcdir)/*.c > .depend
-
-clean:
-	@rm -f .depend *.o *~
-
-compat: $(OBJS)
-
-.SUFFIXES:
-.SUFFIXES: .c .o .h
-
-.c.o:
-	$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
-
-#safety hash
-gnu_strftime.o: ./gnu_strftime.c
-inet_aton.o: ./inet_aton.c ../../src/main.h ../../config.h \
- ../../src/lang.h ../../src/eggdrop.h ../../src/flags.h \
- ../../src/proto.h ../../lush.h ../../src/misc_file.h ../../src/cmdt.h \
- ../../src/tclegg.h ../../src/tclhash.h ../../src/chan.h \
- ../../src/users.h ../../src/compat/compat.h \
- ../../src/compat/inet_aton.h ../../src/compat/snprintf.h \
- ../../src/compat/memset.h ../../src/compat/memcpy.h \
- ../../src/compat/strcasecmp.h ../../src/compat/strftime.h inet_aton.h
-memcpy.o: ./memcpy.c ../../src/main.h ../../config.h ../../src/lang.h \
- ../../src/eggdrop.h ../../src/flags.h ../../src/proto.h ../../lush.h \
- ../../src/misc_file.h ../../src/cmdt.h ../../src/tclegg.h \
- ../../src/tclhash.h ../../src/chan.h ../../src/users.h \
- ../../src/compat/compat.h ../../src/compat/inet_aton.h \
- ../../src/compat/snprintf.h ../../src/compat/memset.h \
- ../../src/compat/memcpy.h ../../src/compat/strcasecmp.h \
- ../../src/compat/strftime.h memcpy.h
-memset.o: ./memset.c ../../src/main.h ../../config.h ../../src/lang.h \
- ../../src/eggdrop.h ../../src/flags.h ../../src/proto.h ../../lush.h \
- ../../src/misc_file.h ../../src/cmdt.h ../../src/tclegg.h \
- ../../src/tclhash.h ../../src/chan.h ../../src/users.h \
- ../../src/compat/compat.h ../../src/compat/inet_aton.h \
- ../../src/compat/snprintf.h ../../src/compat/memset.h \
- ../../src/compat/memcpy.h ../../src/compat/strcasecmp.h \
- ../../src/compat/strftime.h memset.h
-snprintf.o: ./snprintf.c ../../src/main.h ../../config.h \
- ../../src/lang.h ../../src/eggdrop.h ../../src/flags.h \
- ../../src/proto.h ../../lush.h ../../src/misc_file.h ../../src/cmdt.h \
- ../../src/tclegg.h ../../src/tclhash.h ../../src/chan.h \
- ../../src/users.h ../../src/compat/compat.h \
- ../../src/compat/inet_aton.h ../../src/compat/snprintf.h \
- ../../src/compat/memset.h ../../src/compat/memcpy.h \
- ../../src/compat/strcasecmp.h ../../src/compat/strftime.h snprintf.h
-strcasecmp.o: ./strcasecmp.c ../../src/main.h ../../config.h \
- ../../src/lang.h ../../src/eggdrop.h ../../src/flags.h \
- ../../src/proto.h ../../lush.h ../../src/misc_file.h ../../src/cmdt.h \
- ../../src/tclegg.h ../../src/tclhash.h ../../src/chan.h \
- ../../src/users.h ../../src/compat/compat.h \
- ../../src/compat/inet_aton.h ../../src/compat/snprintf.h \
- ../../src/compat/memset.h ../../src/compat/memcpy.h \
- ../../src/compat/strcasecmp.h ../../src/compat/strftime.h memcpy.h
-strftime.o: ./strftime.c ../../src/main.h ../../config.h \
- ../../src/lang.h ../../src/eggdrop.h ../../src/flags.h \
- ../../src/proto.h ../../lush.h ../../src/misc_file.h ../../src/cmdt.h \
- ../../src/tclegg.h ../../src/tclhash.h ../../src/chan.h \
- ../../src/users.h ../../src/compat/compat.h \
- ../../src/compat/inet_aton.h ../../src/compat/snprintf.h \
- ../../src/compat/memset.h ../../src/compat/memcpy.h \
- ../../src/compat/strcasecmp.h ../../src/compat/strftime.h strftime.h
+# Makefile for src/compat/
+# $Id: Makefile.in,v 1.1 2005/04/08 13:48:26 Administrator Exp $
+
+SHELL = @SHELL@
+top_srcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+@SET_MAKE@
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+
+CC = @CC@
+LD = @CC@
+STRIP = @STRIP@
+CFLAGS = @CFLAGS@ -I../.. -I$(top_srcdir) -I$(top_srcdir)/src @DEFS@ $(CFLGS)
+CPPFLAGS = @CPPFLAGS@
+
+OBJS = inet_aton.o snprintf.o memset.o memcpy.o strcasecmp.o strftime.o
+
+doofus:
+	@echo ""
+	@echo "Let's try this from the right directory..."
+	@echo ""
+	@cd ../.. && $(MAKE)
+
+depend:
+	$(CC) $(CFLAGS) $(CPPFLAGS) -MM $(srcdir)/*.c > .depend
+
+clean:
+	@rm -f .depend *.o *~
+
+compat: $(OBJS)
+
+.SUFFIXES:
+.SUFFIXES: .c .o .h
+
+.c.o:
+	$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
+
+#safety hash
+gnu_strftime.o: ./gnu_strftime.c
+inet_aton.o: ./inet_aton.c ../../src/main.h ../../config.h \
+ ../../src/lang.h ../../src/eggdrop.h ../../src/flags.h \
+ ../../src/proto.h ../../lush.h ../../src/misc_file.h ../../src/cmdt.h \
+ ../../src/tclegg.h ../../src/tclhash.h ../../src/chan.h \
+ ../../src/users.h ../../src/compat/compat.h \
+ ../../src/compat/inet_aton.h ../../src/compat/snprintf.h \
+ ../../src/compat/memset.h ../../src/compat/memcpy.h \
+ ../../src/compat/strcasecmp.h ../../src/compat/strftime.h inet_aton.h
+memcpy.o: ./memcpy.c ../../src/main.h ../../config.h ../../src/lang.h \
+ ../../src/eggdrop.h ../../src/flags.h ../../src/proto.h ../../lush.h \
+ ../../src/misc_file.h ../../src/cmdt.h ../../src/tclegg.h \
+ ../../src/tclhash.h ../../src/chan.h ../../src/users.h \
+ ../../src/compat/compat.h ../../src/compat/inet_aton.h \
+ ../../src/compat/snprintf.h ../../src/compat/memset.h \
+ ../../src/compat/memcpy.h ../../src/compat/strcasecmp.h \
+ ../../src/compat/strftime.h memcpy.h
+memset.o: ./memset.c ../../src/main.h ../../config.h ../../src/lang.h \
+ ../../src/eggdrop.h ../../src/flags.h ../../src/proto.h ../../lush.h \
+ ../../src/misc_file.h ../../src/cmdt.h ../../src/tclegg.h \
+ ../../src/tclhash.h ../../src/chan.h ../../src/users.h \
+ ../../src/compat/compat.h ../../src/compat/inet_aton.h \
+ ../../src/compat/snprintf.h ../../src/compat/memset.h \
+ ../../src/compat/memcpy.h ../../src/compat/strcasecmp.h \
+ ../../src/compat/strftime.h memset.h
+snprintf.o: ./snprintf.c ../../src/main.h ../../config.h \
+ ../../src/lang.h ../../src/eggdrop.h ../../src/flags.h \
+ ../../src/proto.h ../../lush.h ../../src/misc_file.h ../../src/cmdt.h \
+ ../../src/tclegg.h ../../src/tclhash.h ../../src/chan.h \
+ ../../src/users.h ../../src/compat/compat.h \
+ ../../src/compat/inet_aton.h ../../src/compat/snprintf.h \
+ ../../src/compat/memset.h ../../src/compat/memcpy.h \
+ ../../src/compat/strcasecmp.h ../../src/compat/strftime.h snprintf.h
+strcasecmp.o: ./strcasecmp.c ../../src/main.h ../../config.h \
+ ../../src/lang.h ../../src/eggdrop.h ../../src/flags.h \
+ ../../src/proto.h ../../lush.h ../../src/misc_file.h ../../src/cmdt.h \
+ ../../src/tclegg.h ../../src/tclhash.h ../../src/chan.h \
+ ../../src/users.h ../../src/compat/compat.h \
+ ../../src/compat/inet_aton.h ../../src/compat/snprintf.h \
+ ../../src/compat/memset.h ../../src/compat/memcpy.h \
+ ../../src/compat/strcasecmp.h ../../src/compat/strftime.h memcpy.h
+strftime.o: ./strftime.c ../../src/main.h ../../config.h \
+ ../../src/lang.h ../../src/eggdrop.h ../../src/flags.h \
+ ../../src/proto.h ../../lush.h ../../src/misc_file.h ../../src/cmdt.h \
+ ../../src/tclegg.h ../../src/tclhash.h ../../src/chan.h \
+ ../../src/users.h ../../src/compat/compat.h \
+ ../../src/compat/inet_aton.h ../../src/compat/snprintf.h \
+ ../../src/compat/memset.h ../../src/compat/memcpy.h \
+ ../../src/compat/strcasecmp.h ../../src/compat/strftime.h strftime.h

+ 35 - 35
compat/compat.h

@@ -1,35 +1,35 @@
-/*
- * compat.h
- *   wrap-around header for all compability functions.
- *
- * $Id: compat.h,v 1.3 2001/04/12 02:39:44 guppy Exp $
- */
-/*
- * Copyright (C) 2000, 2001 Eggheads Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#ifndef _EGG_COMPAT_COMPAT_H
-#define _EGG_COMPAT_COMPAT_H
-
-#include "inet_aton.h"
-#include "snprintf.h"
-#include "memset.h"
-#include "memcpy.h"
-#include "strcasecmp.h"
-#include "strftime.h"
-
-#endif	/* !__EGG_COMPAT_COMPAT_H */
+/*
+ * compat.h
+ *   wrap-around header for all compability functions.
+ *
+ * $Id: compat.h,v 1.1 2005/04/08 13:48:26 Administrator Exp $
+ */
+/*
+ * Copyright (C) 2000, 2001 Eggheads Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef _EGG_COMPAT_COMPAT_H
+#define _EGG_COMPAT_COMPAT_H
+
+#include "inet_aton.h"
+#include "snprintf.h"
+#include "memset.h"
+#include "memcpy.h"
+#include "strcasecmp.h"
+#include "strftime.h"
+
+#endif	/* !__EGG_COMPAT_COMPAT_H */

+ 186 - 186
compat/inet_aton.c

@@ -1,186 +1,186 @@
-/*
- * inet_aton.c -- provides inet_aton() if necessary.
- *
- * $Id: inet_aton.c,v 1.5 2001/04/12 02:39:44 guppy Exp $
- */
-/*
- * Poritions Copyright (C) 2000, 2001 Eggheads Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#include "main.h"
-#include "inet_aton.h"
-
-#ifndef HAVE_ISASCII
-/* Let all checks succeed if we don't have isascii(). */
-#  define isascii(x)	1
-#endif
-
-#ifndef HAVE_INET_ATON
-/*
- * ++Copyright++ 1983, 1990, 1993
- * -
- * Copyright (c) 1983, 1990, 1993
- *    The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- * 	This product includes software developed by the University of
- * 	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * -
- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies, and that
- * the name of Digital Equipment Corporation not be used in advertising or
- * publicity pertaining to distribution of the document or software without
- * specific, written prior permission.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- * --Copyright--
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)inet_addr.c	8.1 (Berkeley) 6/17/93";
-static char rcsid[] = "$-Id: inet_addr.c,v 1.11 1999/04/29 18:19:53 drepper Exp $";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <ctype.h>
-
-/*
- * Check whether "cp" is a valid ascii representation
- * of an Internet address and convert to a binary address.
- * Returns 1 if the address is valid, 0 if not.
- * This replaces inet_addr, the return value from which
- * cannot distinguish between failure and a local broadcast address.
- */
-int
-egg_inet_aton(cp, addr)
-	const char *cp;
-	struct in_addr *addr;
-{
-	static const u_32bit_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };
-	register u_32bit_t val;	/* changed from u_long --david */
-	register int base;
-	register int n;
-	register char c;
-	u_32bit_t parts[4];
-	register u_32bit_t *pp = parts;
-
-	egg_bzero(parts, sizeof (parts));
-
-	c = *cp;
-	for (;;) {
-		/*
-		 * Collect number up to ``.''.
-		 * Values are specified as for C:
-		 * 0x=hex, 0=octal, isdigit=decimal.
-		 */
-		if (!isdigit(c))
-			goto ret_0;
-		base = 10;
-		if (c == '0') {
-			c = *++cp;
-			if (c == 'x' || c == 'X')
-				base = 16, c = *++cp;
-			else
-				base = 8;
-		}
-		val = 0;
-		for (;;) {
-			if (isascii(c) && isdigit(c)) {
-				val = (val * base) + (c - '0');
-				c = *++cp;
-			} else if (base == 16 && isascii(c) && isxdigit(c)) {
-				val = (val << 4) |
-					(c + 10 - (islower(c) ? 'a' : 'A'));
-				c = *++cp;
-			} else
-				break;
-		}
-		if (c == '.') {
-			/*
-			 * Internet format:
-			 *	a.b.c.d
-			 *	a.b.c	(with c treated as 16 bits)
-			 *	a.b	(with b treated as 24 bits)
-			 */
-			if (pp >= parts + 3)
-				goto ret_0;
-			*pp++ = val;
-			c = *++cp;
-		} else
-			break;
-	}
-	/*
-	 * Check for trailing characters.
-	 */
-	if (c != '\0' && (!isascii(c) || !isspace(c)))
-		goto ret_0;
-	/*
-	 * Concoct the address according to
-	 * the number of parts specified.
-	 */
-	n = pp - parts + 1;
-
-	if (n == 0	/* initial nondigit */
-	    || parts[0] > 0xff || parts[1] > 0xff || parts[2] > 0xff
-	    || val > max[n - 1])
-	  goto ret_0;
-
-	val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
-
-	if (addr)
-		addr->s_addr = htonl(val);
-	return (1);
-
-ret_0:
-	return (0);
-}
-#endif /* HAVE_INET_ATON */
+/*
+ * inet_aton.c -- provides inet_aton() if necessary.
+ *
+ * $Id: inet_aton.c,v 1.1 2005/04/08 13:48:26 Administrator Exp $
+ */
+/*
+ * Poritions Copyright (C) 2000, 2001 Eggheads Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include "main.h"
+#include "inet_aton.h"
+
+#ifndef HAVE_ISASCII
+/* Let all checks succeed if we don't have isascii(). */
+#  define isascii(x)	1
+#endif
+
+#ifndef HAVE_INET_ATON
+/*
+ * ++Copyright++ 1983, 1990, 1993
+ * -
+ * Copyright (c) 1983, 1990, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)inet_addr.c	8.1 (Berkeley) 6/17/93";
+static char rcsid[] = "$-Id: inet_addr.c,v 1.11 1999/04/29 18:19:53 drepper Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <ctype.h>
+
+/*
+ * Check whether "cp" is a valid ascii representation
+ * of an Internet address and convert to a binary address.
+ * Returns 1 if the address is valid, 0 if not.
+ * This replaces inet_addr, the return value from which
+ * cannot distinguish between failure and a local broadcast address.
+ */
+int
+egg_inet_aton(cp, addr)
+	const char *cp;
+	struct in_addr *addr;
+{
+	static const u_32bit_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };
+	register u_32bit_t val;	/* changed from u_long --david */
+	register int base;
+	register int n;
+	register char c;
+	u_32bit_t parts[4];
+	register u_32bit_t *pp = parts;
+
+	egg_bzero(parts, sizeof (parts));
+
+	c = *cp;
+	for (;;) {
+		/*
+		 * Collect number up to ``.''.
+		 * Values are specified as for C:
+		 * 0x=hex, 0=octal, isdigit=decimal.
+		 */
+		if (!isdigit(c))
+			goto ret_0;
+		base = 10;
+		if (c == '0') {
+			c = *++cp;
+			if (c == 'x' || c == 'X')
+				base = 16, c = *++cp;
+			else
+				base = 8;
+		}
+		val = 0;
+		for (;;) {
+			if (isascii(c) && isdigit(c)) {
+				val = (val * base) + (c - '0');
+				c = *++cp;
+			} else if (base == 16 && isascii(c) && isxdigit(c)) {
+				val = (val << 4) |
+					(c + 10 - (islower(c) ? 'a' : 'A'));
+				c = *++cp;
+			} else
+				break;
+		}
+		if (c == '.') {
+			/*
+			 * Internet format:
+			 *	a.b.c.d
+			 *	a.b.c	(with c treated as 16 bits)
+			 *	a.b	(with b treated as 24 bits)
+			 */
+			if (pp >= parts + 3)
+				goto ret_0;
+			*pp++ = val;
+			c = *++cp;
+		} else
+			break;
+	}
+	/*
+	 * Check for trailing characters.
+	 */
+	if (c != '\0' && (!isascii(c) || !isspace(c)))
+		goto ret_0;
+	/*
+	 * Concoct the address according to
+	 * the number of parts specified.
+	 */
+	n = pp - parts + 1;
+
+	if (n == 0	/* initial nondigit */
+	    || parts[0] > 0xff || parts[1] > 0xff || parts[2] > 0xff
+	    || val > max[n - 1])
+	  goto ret_0;
+
+	val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+
+	if (addr)
+		addr->s_addr = htonl(val);
+	return (1);
+
+ret_0:
+	return (0);
+}
+#endif /* HAVE_INET_ATON */

+ 40 - 40
compat/inet_aton.h

@@ -1,40 +1,40 @@
-/*
- * inet_aton.h
- *   prototypes for inet_aton.c
- *
- * $Id: inet_aton.h,v 1.3 2001/04/12 02:39:44 guppy Exp $
- */
-/*
- * Copyright (C) 2000, 2001 Eggheads Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#ifndef _EGG_COMPAT_INET_ATON_H
-#define _EGG_COMPAT_INET_ATON_H
-
-#include "src/main.h"
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#ifndef HAVE_INET_ATON
-/* Use our own implementation. */
-int egg_inet_aton(const char *cp, struct in_addr *addr);
-#else
-#  define egg_inet_aton	inet_aton
-#endif
-
-#endif	/* !__EGG_COMPAT_INET_ATON_H */
+/*
+ * inet_aton.h
+ *   prototypes for inet_aton.c
+ *
+ * $Id: inet_aton.h,v 1.1 2005/04/08 13:48:26 Administrator Exp $
+ */
+/*
+ * Copyright (C) 2000, 2001 Eggheads Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef _EGG_COMPAT_INET_ATON_H
+#define _EGG_COMPAT_INET_ATON_H
+
+#include "src/main.h"
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#ifndef HAVE_INET_ATON
+/* Use our own implementation. */
+int egg_inet_aton(const char *cp, struct in_addr *addr);
+#else
+#  define egg_inet_aton	inet_aton
+#endif
+
+#endif	/* !__EGG_COMPAT_INET_ATON_H */

BIN
compat/inet_aton.o


+ 35 - 35
compat/memcpy.c

@@ -1,35 +1,35 @@
-/*
- * memcpy.c -- provides memcpy() if necessary.
- *
- * $Id: memcpy.c,v 1.2 2001/04/12 02:39:44 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001 Eggheads Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#include "main.h"
-#include "memcpy.h"
-
-#ifndef HAVE_MEMCPY
-void *egg_memcpy(void *dest, const void *src, size_t n)
-{
-  while (n--)
-    *((char *) dest)++ = *((char *) src)++;
-  return dest;
-}
-#endif /* !HAVE_MEMCPY */
+/*
+ * memcpy.c -- provides memcpy() if necessary.
+ *
+ * $Id: memcpy.c,v 1.1 2005/04/08 13:48:26 Administrator Exp $
+ */
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001 Eggheads Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include "main.h"
+#include "memcpy.h"
+
+#ifndef HAVE_MEMCPY
+void *egg_memcpy(void *dest, const void *src, size_t n)
+{
+  while (n--)
+    *((char *) dest)++ = *((char *) src)++;
+  return dest;
+}
+#endif /* !HAVE_MEMCPY */

+ 38 - 38
compat/memcpy.h

@@ -1,38 +1,38 @@
-/*
- * memcpy.h
- *   prototypes for memcpy.c
- *
- * $Id: memcpy.h,v 1.3 2001/04/12 02:39:44 guppy Exp $
- */
-/*
- * Copyright (C) 2000, 2001 Eggheads Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#ifndef _EGG_COMPAT_MEMCPY_H
-#define _EGG_COMPAT_MEMCPY_H
-
-#include "src/main.h"
-#include <string.h>
-
-#ifndef HAVE_MEMCPY
-/* Use our own implementation. */
-void *egg_memcpy(void *dest, const void *src, size_t n);
-#else
-#  define egg_memcpy	memcpy
-#endif
-
-#endif	/* !__EGG_COMPAT_MEMCPY_H */
+/*
+ * memcpy.h
+ *   prototypes for memcpy.c
+ *
+ * $Id: memcpy.h,v 1.1 2005/04/08 13:48:26 Administrator Exp $
+ */
+/*
+ * Copyright (C) 2000, 2001 Eggheads Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef _EGG_COMPAT_MEMCPY_H
+#define _EGG_COMPAT_MEMCPY_H
+
+#include "src/main.h"
+#include <string.h>
+
+#ifndef HAVE_MEMCPY
+/* Use our own implementation. */
+void *egg_memcpy(void *dest, const void *src, size_t n);
+#else
+#  define egg_memcpy	memcpy
+#endif
+
+#endif	/* !__EGG_COMPAT_MEMCPY_H */

BIN
compat/memcpy.o


+ 35 - 35
compat/memset.c

@@ -1,35 +1,35 @@
-/*
- * memset.c -- provides memset() if necessary.
- *
- * $Id: memset.c,v 1.3 2001/04/12 02:39:44 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001 Eggheads Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#include "main.h"
-#include "memset.h"
-
-#ifndef HAVE_MEMSET
-void *egg_memset(void *dest, int c, size_t n)
-{
-  while (n--)
-    *((u_8bit_t *) dest)++ = c;
-  return dest;
-}
-#endif /* !HAVE_MEMSET */
+/*
+ * memset.c -- provides memset() if necessary.
+ *
+ * $Id: memset.c,v 1.1 2005/04/08 13:48:26 Administrator Exp $
+ */
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001 Eggheads Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include "main.h"
+#include "memset.h"
+
+#ifndef HAVE_MEMSET
+void *egg_memset(void *dest, int c, size_t n)
+{
+  while (n--)
+    *((u_8bit_t *) dest)++ = c;
+  return dest;
+}
+#endif /* !HAVE_MEMSET */

+ 42 - 42
compat/memset.h

@@ -1,42 +1,42 @@
-/*
- * memset.h
- *   prototypes for memset.c
- *
- * $Id: memset.h,v 1.3 2001/04/12 02:39:44 guppy Exp $
- */
-/*
- * Copyright (C) 2000, 2001 Eggheads Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#ifndef _EGG_COMPAT_MEMSET_H
-#define _EGG_COMPAT_MEMSET_H
-
-#include "src/main.h"
-#include <string.h>
-
-#ifndef HAVE_MEMSET
-/* Use our own implementation. */
-void *egg_memset(void *dest, int c, size_t n);
-#else
-#  define egg_memset	memset
-#endif
-
-/* Use memset instead of bzero.
- */
-#define egg_bzero(dest, n)	egg_memset(dest, 0, n)
-
-#endif	/* !__EGG_COMPAT_MEMSET_H */
+/*
+ * memset.h
+ *   prototypes for memset.c
+ *
+ * $Id: memset.h,v 1.1 2005/04/08 13:48:27 Administrator Exp $
+ */
+/*
+ * Copyright (C) 2000, 2001 Eggheads Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef _EGG_COMPAT_MEMSET_H
+#define _EGG_COMPAT_MEMSET_H
+
+#include "src/main.h"
+#include <string.h>
+
+#ifndef HAVE_MEMSET
+/* Use our own implementation. */
+void *egg_memset(void *dest, int c, size_t n);
+#else
+#  define egg_memset	memset
+#endif
+
+/* Use memset instead of bzero.
+ */
+#define egg_bzero(dest, n)	egg_memset(dest, 0, n)
+
+#endif	/* !__EGG_COMPAT_MEMSET_H */

BIN
compat/memset.o


+ 720 - 720
compat/snprintf.c

@@ -1,720 +1,720 @@
-/*
- * snprintf.c - a portable implementation of snprintf and vsnprintf
- *
- * $Id: snprintf.c,v 1.4 2001/04/12 02:39:44 guppy Exp $
- */
-/*
- * Portions Copyright (C) 2000, 2001 Eggheads Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-
-/*
- * Copyright Patrick Powell 1995
- * This code is based on code written by Patrick Powell (papowell@astart.com)
- * It may be used for any purpose as long as this notice remains intact
- * on all source code distributions
- */
-
-/**************************************************************
- * Original:
- * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
- * A bombproof version of doprnt (dopr) included.
- * Sigh.  This sort of thing is always nasty do deal with.  Note that
- * the version here does not include floating point...
- *
- * snprintf() is used instead of sprintf() as it does limit checks
- * for string length.  This covers a nasty loophole.
- *
- * The other functions are there to prevent NULL pointers from
- * causing nast effects.
- *
- * More Recently:
- *  Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
- *  This was ugly.  It is still ugly.  I opted out of floating point
- *  numbers, but the formatter understands just about everything
- *  from the normal C string format, at least as far as I can tell from
- *  the Solaris 2.5 printf(3S) man page.
- *
- *  Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1
- *    Ok, added some minimal floating point support, which means this
- *    probably requires libm on most operating systems.  Don't yet
- *    support the exponent (e,E) and sigfig (g,G).  Also, fmtint()
- *    was pretty badly broken, it just wasn't being exercised in ways
- *    which showed it, so that's been fixed.  Also, formated the code
- *    to mutt conventions, and removed dead code left over from the
- *    original.  Also, there is now a builtin-test, just compile with:
- *           gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
- *    and run snprintf for results.
- *
- *  Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
- *    The PGP code was using unsigned hexadecimal formats.
- *    Unfortunately, unsigned formats simply didn't work.
- *
- *  Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
- *    The original code assumed that both snprintf() and vsnprintf() were
- *    missing.  Some systems only have snprintf() but not vsnprintf(), so
- *    the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
- *
- *  Andrew Tridgell (tridge@samba.org) Oct 1998
- *    fixed handling of %.0f
- *    added test for HAVE_LONG_DOUBLE
- *
- *  Fabian Knittel <fknittel@gmx.de> Apr 2000 for eggdrop 1.5.3
- *    Indented code to match eggdrop style. Adjusted to fit into eggdrops
- *    build environment. Added `egg_' prefixes to snprintf and vsnprintf.
- *
- **************************************************************/
-
-#include <string.h>
-#include <ctype.h>
-#include <sys/types.h>
-
-#ifndef HAVE_VSNPRINTF
-
-/* varargs declarations: */
-
-#if defined(__STDC__)
-#  ifdef HAVE_STDARG_H
-#    include <stdarg.h>
-#  else
-#    ifdef HAVE_STD_ARGS_H
-#      include <std_args.h>
-#    endif
-#  endif
-#  include <stdarg.h>
-#  define HAVE_STDARGS		/* let's hope that works everywhere (mj) */
-#  define VA_LOCAL_DECL	va_list ap
-#  define VA_START(f)	va_start(ap, f)
-#  define VA_SHIFT(v,t)	;	/* no-op for ANSI */
-#  define VA_END	va_end(ap)
-#else
-#  include <varargs.h>
-#  undef HAVE_STDARGS
-#  define VA_LOCAL_DECL	va_list ap
-#  define VA_START(f)	va_start(ap)	/* f is ignored! */
-#  define VA_SHIFT(v,t)	v = va_arg(ap,t)
-#  define VA_END	va_end(ap)
-#endif
-
-#ifdef HAVE_LONG_DOUBLE
-#define LDOUBLE	long double
-#else
-#define LDOUBLE	double
-#endif
-
-static void dopr(char *buffer, size_t maxlen, const char *format,
-		 va_list args);
-static void fmtstr(char *buffer, size_t * currlen, size_t maxlen,
-		   char *value, int flags, int min, int max);
-static void fmtint(char *buffer, size_t * currlen, size_t maxlen,
-		   long value, int base, int min, int max, int flags);
-static void fmtfp(char *buffer, size_t * currlen, size_t maxlen,
-		  LDOUBLE fvalue, int min, int max, int flags);
-static void dopr_outch(char *buffer, size_t * currlen, size_t maxlen,
-		       char c);
-
-/*
- * dopr(): poor man's version of doprintf
- */
-
-/* format read states */
-#define DP_S_DEFAULT 0
-#define DP_S_FLAGS   1
-#define DP_S_MIN     2
-#define DP_S_DOT     3
-#define DP_S_MAX     4
-#define DP_S_MOD     5
-#define DP_S_CONV    6
-#define DP_S_DONE    7
-
-/* format flags - Bits */
-#define DP_F_MINUS 	(1 << 0)
-#define DP_F_PLUS  	(1 << 1)
-#define DP_F_SPACE 	(1 << 2)
-#define DP_F_NUM   	(1 << 3)
-#define DP_F_ZERO  	(1 << 4)
-#define DP_F_UP    	(1 << 5)
-#define DP_F_UNSIGNED 	(1 << 6)
-
-/* Conversion Flags */
-#define DP_C_SHORT   1
-#define DP_C_LONG    2
-#define DP_C_LDOUBLE 3
-
-#define char_to_int(p) (p - '0')
-#define MAX(p,q) ((p >= q) ? p : q)
-
-static void dopr(char *buffer, size_t maxlen, const char *format,
-		 va_list args)
-{
-  char ch;
-  long value;
-  LDOUBLE fvalue;
-  char *strvalue;
-  int min;
-  int max;
-  int state;
-  int flags;
-  int cflags;
-  size_t currlen;
-
-  state = DP_S_DEFAULT;
-  currlen = flags = cflags = min = 0;
-  max = -1;
-  ch = *format++;
-
-  while (state != DP_S_DONE) {
-    if ((ch == '\0') || (currlen >= maxlen))
-      state = DP_S_DONE;
-
-    switch (state) {
-    case DP_S_DEFAULT:
-      if (ch == '%')
-	state = DP_S_FLAGS;
-      else
-	dopr_outch(buffer, &currlen, maxlen, ch);
-      ch = *format++;
-      break;
-    case DP_S_FLAGS:
-      switch (ch) {
-      case '-':
-	flags |= DP_F_MINUS;
-	ch = *format++;
-	break;
-      case '+':
-	flags |= DP_F_PLUS;
-	ch = *format++;
-	break;
-      case ' ':
-	flags |= DP_F_SPACE;
-	ch = *format++;
-	break;
-      case '#':
-	flags |= DP_F_NUM;
-	ch = *format++;
-	break;
-      case '0':
-	flags |= DP_F_ZERO;
-	ch = *format++;
-	break;
-      default:
-	state = DP_S_MIN;
-	break;
-      }
-      break;
-    case DP_S_MIN:
-      if (isdigit(ch)) {
-	min = 10 * min + char_to_int(ch);
-	ch = *format++;
-      } else if (ch == '*') {
-	min = va_arg(args, int);
-	ch = *format++;
-	state = DP_S_DOT;
-      } else
-	state = DP_S_DOT;
-      break;
-    case DP_S_DOT:
-      if (ch == '.') {
-	state = DP_S_MAX;
-	ch = *format++;
-      } else
-	state = DP_S_MOD;
-      break;
-    case DP_S_MAX:
-      if (isdigit(ch)) {
-	if (max < 0)
-	  max = 0;
-	max = 10 * max + char_to_int(ch);
-	ch = *format++;
-      } else if (ch == '*') {
-	max = va_arg(args, int);
-	ch = *format++;
-	state = DP_S_MOD;
-      } else
-	state = DP_S_MOD;
-      break;
-    case DP_S_MOD:
-      /* Currently, we don't support Long Long, bummer */
-      switch (ch) {
-      case 'h':
-	cflags = DP_C_SHORT;
-	ch = *format++;
-	break;
-      case 'l':
-	cflags = DP_C_LONG;
-	ch = *format++;
-	break;
-      case 'L':
-	cflags = DP_C_LDOUBLE;
-	ch = *format++;
-	break;
-      default:
-	break;
-      }
-      state = DP_S_CONV;
-      break;
-    case DP_S_CONV:
-      switch (ch) {
-      case 'd':
-      case 'i':
-	if (cflags == DP_C_SHORT)
-	  value = va_arg(args, short int);
-	else if (cflags == DP_C_LONG)
-	  value = va_arg(args, long int);
-	else
-	  value = va_arg(args, int);
-	fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags);
-	break;
-      case 'o':
-	flags |= DP_F_UNSIGNED;
-	if (cflags == DP_C_SHORT)
-	  value = va_arg(args, unsigned short int);
-	else if (cflags == DP_C_LONG)
-	  value = va_arg(args, unsigned long int);
-	else
-	  value = va_arg(args, unsigned int);
-	fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags);
-	break;
-      case 'u':
-	flags |= DP_F_UNSIGNED;
-	if (cflags == DP_C_SHORT)
-	  value = va_arg(args, unsigned short int);
-	else if (cflags == DP_C_LONG)
-	  value = va_arg(args, unsigned long int);
-	else
-	  value = va_arg(args, unsigned int);
-	fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags);
-	break;
-      case 'X':
-	flags |= DP_F_UP;
-      case 'x':
-	flags |= DP_F_UNSIGNED;
-	if (cflags == DP_C_SHORT)
-	  value = va_arg(args, unsigned short int);
-	else if (cflags == DP_C_LONG)
-	  value = va_arg(args, unsigned long int);
-	else
-	  value = va_arg(args, unsigned int);
-	fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags);
-	break;
-      case 'f':
-	if (cflags == DP_C_LDOUBLE)
-	  fvalue = va_arg(args, LDOUBLE);
-	else
-	  fvalue = va_arg(args, double);
-	/* um, floating point? */
-	fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags);
-	break;
-      case 'E':
-	flags |= DP_F_UP;
-      case 'e':
-	if (cflags == DP_C_LDOUBLE)
-	  fvalue = va_arg(args, LDOUBLE);
-	else
-	  fvalue = va_arg(args, double);
-	break;
-      case 'G':
-	flags |= DP_F_UP;
-      case 'g':
-	if (cflags == DP_C_LDOUBLE)
-	  fvalue = va_arg(args, LDOUBLE);
-	else
-	  fvalue = va_arg(args, double);
-	break;
-      case 'c':
-	dopr_outch(buffer, &currlen, maxlen, va_arg(args, int));
-	break;
-      case 's':
-	strvalue = va_arg(args, char *);
-	if (max < 0)
-	  max = maxlen;		/* ie, no max */
-	fmtstr(buffer, &currlen, maxlen, strvalue, flags, min, max);
-	break;
-      case 'p':
-	strvalue = va_arg(args, void *);
-	fmtint(buffer, &currlen, maxlen, (long) strvalue, 16, min, max,
-	       flags);
-	break;
-      case 'n':
-	if (cflags == DP_C_SHORT) {
-	  short int *num;
-	  num = va_arg(args, short int *);
-	  *num = currlen;
-	} else if (cflags == DP_C_LONG) {
-	  long int *num;
-	  num = va_arg(args, long int *);
-	  *num = currlen;
-	} else {
-	  int *num;
-	  num = va_arg(args, int *);
-	  *num = currlen;
-	}
-	break;
-      case '%':
-	dopr_outch(buffer, &currlen, maxlen, ch);
-	break;
-      case 'w':
-	/* not supported yet, treat as next char */
-	ch = *format++;
-	break;
-      default:
-	/* Unknown, skip */
-	break;
-      }
-      ch = *format++;
-      state = DP_S_DEFAULT;
-      flags = cflags = min = 0;
-      max = -1;
-      break;
-    case DP_S_DONE:
-      break;
-    default:
-      /* hmm? */
-      break;			/* some picky compilers need this */
-    }
-  }
-  if (currlen < maxlen - 1)
-    buffer[currlen] = '\0';
-  else
-    buffer[maxlen - 1] = '\0';
-}
-
-static void fmtstr(char *buffer, size_t * currlen, size_t maxlen,
-		   char *value, int flags, int min, int max)
-{
-  int padlen,
-      strln;			/* amount to pad */
-  int cnt = 0;
-
-  if (value == 0) {
-    value = "<NULL>";
-  }
-
-  for (strln = 0; value[strln]; ++strln);	/* strlen */
-  padlen = min - strln;
-  if (padlen < 0)
-    padlen = 0;
-  if (flags & DP_F_MINUS)
-    padlen = -padlen;		/* Left Justify */
-
-  while ((padlen > 0) && (cnt < max)) {
-    dopr_outch(buffer, currlen, maxlen, ' ');
-    --padlen;
-    ++cnt;
-  }
-  while (*value && (cnt < max)) {
-    dopr_outch(buffer, currlen, maxlen, *value++);
-    ++cnt;
-  }
-  while ((padlen < 0) && (cnt < max)) {
-    dopr_outch(buffer, currlen, maxlen, ' ');
-    ++padlen;
-    ++cnt;
-  }
-}
-
-/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
-
-static void fmtint(char *buffer, size_t * currlen, size_t maxlen,
-		   long value, int base, int min, int max, int flags)
-{
-  int signvalue = 0;
-  unsigned long uvalue;
-  char convert[20];
-  int place = 0;
-  int spadlen = 0;		/* amount to space pad */
-  int zpadlen = 0;		/* amount to zero pad */
-  int caps = 0;
-
-  if (max < 0)
-    max = 0;
-
-  uvalue = value;
-
-  if (!(flags & DP_F_UNSIGNED)) {
-    if (value < 0) {
-      signvalue = '-';
-      uvalue = -value;
-    } else if (flags & DP_F_PLUS)	/* Do a sign (+/i) */
-      signvalue = '+';
-    else if (flags & DP_F_SPACE)
-      signvalue = ' ';
-  }
-
-  if (flags & DP_F_UP)
-    caps = 1;			/* Should characters be upper case? */
-
-  do {
-    convert[place++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef")
-	[uvalue % (unsigned) base];
-    uvalue = (uvalue / (unsigned) base);
-  }
-  while (uvalue && (place < 20));
-  if (place == 20)
-    place--;
-  convert[place] = 0;
-
-  zpadlen = max - place;
-  spadlen = min - MAX(max, place) - (signvalue ? 1 : 0);
-  if (zpadlen < 0)
-    zpadlen = 0;
-  if (spadlen < 0)
-    spadlen = 0;
-  if (flags & DP_F_ZERO) {
-    zpadlen = MAX(zpadlen, spadlen);
-    spadlen = 0;
-  }
-  if (flags & DP_F_MINUS)
-    spadlen = -spadlen;		/* Left Justifty */
-
-#ifdef DEBUG_SNPRINTF
-  dprint(1,
-	 (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
-	  zpadlen, spadlen, min, max, place));
-#endif
-
-  /* Spaces */
-  while (spadlen > 0) {
-    dopr_outch(buffer, currlen, maxlen, ' ');
-    --spadlen;
-  }
-
-  /* Sign */
-  if (signvalue)
-    dopr_outch(buffer, currlen, maxlen, signvalue);
-
-  /* Zeros */
-  if (zpadlen > 0) {
-    while (zpadlen > 0) {
-      dopr_outch(buffer, currlen, maxlen, '0');
-      --zpadlen;
-    }
-  }
-
-  /* Digits */
-  while (place > 0)
-    dopr_outch(buffer, currlen, maxlen, convert[--place]);
-
-  /* Left Justified spaces */
-  while (spadlen < 0) {
-    dopr_outch(buffer, currlen, maxlen, ' ');
-    ++spadlen;
-  }
-}
-
-static LDOUBLE abs_val(LDOUBLE value)
-{
-  LDOUBLE result = value;
-
-  if (value < 0)
-    result = -value;
-
-  return result;
-}
-
-static LDOUBLE pow10(int exp)
-{
-  LDOUBLE result = 1;
-
-  while (exp) {
-    result *= 10;
-    exp--;
-  }
-
-  return result;
-}
-
-static long round(LDOUBLE value)
-{
-  long intpart;
-
-  intpart = value;
-  value = value - intpart;
-  if (value >= 0.5)
-    intpart++;
-
-  return intpart;
-}
-
-static void fmtfp(char *buffer, size_t * currlen, size_t maxlen,
-		  LDOUBLE fvalue, int min, int max, int flags)
-{
-  int signvalue = 0;
-  LDOUBLE ufvalue;
-  char iconvert[20];
-  char fconvert[20];
-  int iplace = 0;
-  int fplace = 0;
-  int padlen = 0;		/* amount to pad */
-  int zpadlen = 0;
-  int caps = 0;
-  long intpart;
-  long fracpart;
-
-  /*
-   * AIX manpage says the default is 0, but Solaris says the default
-   * is 6, and sprintf on AIX defaults to 6
-   */
-  if (max < 0)
-    max = 6;
-
-  ufvalue = abs_val(fvalue);
-
-  if (fvalue < 0)
-    signvalue = '-';
-  else if (flags & DP_F_PLUS)	/* Do a sign (+/i) */
-    signvalue = '+';
-  else if (flags & DP_F_SPACE)
-    signvalue = ' ';
-
-#if 0
-  if (flags & DP_F_UP)
-    caps = 1;			/* Should characters be upper case? */
-#endif
-
-  intpart = ufvalue;
-
-  /*
-   * Sorry, we only support 9 digits past the decimal because of our
-   * conversion method
-   */
-  if (max > 9)
-    max = 9;
-
-  /* We "cheat" by converting the fractional part to integer by
-   * multiplying by a factor of 10
-   */
-  fracpart = round((pow10(max)) * (ufvalue - intpart));
-
-  if (fracpart >= pow10(max)) {
-    intpart++;
-    fracpart -= pow10(max);
-  }
-
-  /* Convert integer part */
-  do {
-    iconvert[iplace++] =
-	(caps ? "0123456789ABCDEF" : "0123456789abcdef")[intpart % 10];
-    intpart = (intpart / 10);
-  }
-  while (intpart && (iplace < 20));
-  if (iplace == 20)
-    iplace--;
-  iconvert[iplace] = 0;
-
-  /* Convert fractional part */
-  do {
-    fconvert[fplace++] =
-	(caps ? "0123456789ABCDEF" : "0123456789abcdef")[fracpart % 10];
-    fracpart = (fracpart / 10);
-  }
-  while (fracpart && (fplace < 20));
-  if (fplace == 20)
-    fplace--;
-  fconvert[fplace] = 0;
-
-  /* -1 for decimal point, another -1 if we are printing a sign */
-  padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
-  zpadlen = max - fplace;
-  if (zpadlen < 0)
-    zpadlen = 0;
-  if (padlen < 0)
-    padlen = 0;
-  if (flags & DP_F_MINUS)
-    padlen = -padlen;		/* Left Justifty */
-
-  if ((flags & DP_F_ZERO) && (padlen > 0)) {
-    if (signvalue) {
-      dopr_outch(buffer, currlen, maxlen, signvalue);
-      --padlen;
-      signvalue = 0;
-    }
-    while (padlen > 0) {
-      dopr_outch(buffer, currlen, maxlen, '0');
-      --padlen;
-    }
-  }
-  while (padlen > 0) {
-    dopr_outch(buffer, currlen, maxlen, ' ');
-    --padlen;
-  }
-  if (signvalue)
-    dopr_outch(buffer, currlen, maxlen, signvalue);
-
-  while (iplace > 0)
-    dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]);
-
-  /*
-   * Decimal point.  This should probably use locale to find the correct
-   * char to print out.
-   */
-  if (max > 0) {
-    dopr_outch(buffer, currlen, maxlen, '.');
-
-    while (fplace > 0)
-      dopr_outch(buffer, currlen, maxlen, fconvert[--fplace]);
-  }
-
-  while (zpadlen > 0) {
-    dopr_outch(buffer, currlen, maxlen, '0');
-    --zpadlen;
-  }
-
-  while (padlen < 0) {
-    dopr_outch(buffer, currlen, maxlen, ' ');
-    ++padlen;
-  }
-}
-
-static void dopr_outch(char *buffer, size_t * currlen, size_t maxlen,
-		       char c)
-{
-  if (*currlen < maxlen)
-    buffer[(*currlen)++] = c;
-}
-
-int egg_vsnprintf(char *str, size_t count, const char *fmt, va_list args)
-{
-  str[0] = 0;
-  dopr(str, count, fmt, args);
-  return (strlen(str));
-}
-#endif				/* !HAVE_VSNPRINTF */
-
-#ifndef HAVE_SNPRINTF
-#  ifdef HAVE_STDARGS
-int egg_snprintf(char *str, size_t count, const char *fmt, ...)
-#  else
-int egg_snprintf(va_alist) va_dcl
-#  endif
-{
-#  ifndef HAVE_STDARGS
-  char *str;
-  size_t count;
-  char *fmt;
-#  endif
-  VA_LOCAL_DECL;
-
-  VA_START(fmt);
-  VA_SHIFT(str, char *);
-  VA_SHIFT(count, size_t);
-  VA_SHIFT(fmt, char *);
-  (void) egg_vsnprintf(str, count, fmt, ap);
-  VA_END;
-  return (strlen(str));
-}
-#endif				/* !HAVE_SNPRINTF */
+/*
+ * snprintf.c - a portable implementation of snprintf and vsnprintf
+ *
+ * $Id: snprintf.c,v 1.1 2005/04/08 13:48:27 Administrator Exp $
+ */
+/*
+ * Portions Copyright (C) 2000, 2001 Eggheads Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+
+/*
+ * Copyright Patrick Powell 1995
+ * This code is based on code written by Patrick Powell (papowell@astart.com)
+ * It may be used for any purpose as long as this notice remains intact
+ * on all source code distributions
+ */
+
+/**************************************************************
+ * Original:
+ * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
+ * A bombproof version of doprnt (dopr) included.
+ * Sigh.  This sort of thing is always nasty do deal with.  Note that
+ * the version here does not include floating point...
+ *
+ * snprintf() is used instead of sprintf() as it does limit checks
+ * for string length.  This covers a nasty loophole.
+ *
+ * The other functions are there to prevent NULL pointers from
+ * causing nast effects.
+ *
+ * More Recently:
+ *  Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
+ *  This was ugly.  It is still ugly.  I opted out of floating point
+ *  numbers, but the formatter understands just about everything
+ *  from the normal C string format, at least as far as I can tell from
+ *  the Solaris 2.5 printf(3S) man page.
+ *
+ *  Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1
+ *    Ok, added some minimal floating point support, which means this
+ *    probably requires libm on most operating systems.  Don't yet
+ *    support the exponent (e,E) and sigfig (g,G).  Also, fmtint()
+ *    was pretty badly broken, it just wasn't being exercised in ways
+ *    which showed it, so that's been fixed.  Also, formated the code
+ *    to mutt conventions, and removed dead code left over from the
+ *    original.  Also, there is now a builtin-test, just compile with:
+ *           gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
+ *    and run snprintf for results.
+ *
+ *  Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
+ *    The PGP code was using unsigned hexadecimal formats.
+ *    Unfortunately, unsigned formats simply didn't work.
+ *
+ *  Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
+ *    The original code assumed that both snprintf() and vsnprintf() were
+ *    missing.  Some systems only have snprintf() but not vsnprintf(), so
+ *    the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
+ *
+ *  Andrew Tridgell (tridge@samba.org) Oct 1998
+ *    fixed handling of %.0f
+ *    added test for HAVE_LONG_DOUBLE
+ *
+ *  Fabian Knittel <fknittel@gmx.de> Apr 2000 for eggdrop 1.5.3
+ *    Indented code to match eggdrop style. Adjusted to fit into eggdrops
+ *    build environment. Added `egg_' prefixes to snprintf and vsnprintf.
+ *
+ **************************************************************/
+
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+
+#ifndef HAVE_VSNPRINTF
+
+/* varargs declarations: */
+
+#if defined(__STDC__)
+#  ifdef HAVE_STDARG_H
+#    include <stdarg.h>
+#  else
+#    ifdef HAVE_STD_ARGS_H
+#      include <std_args.h>
+#    endif
+#  endif
+#  include <stdarg.h>
+#  define HAVE_STDARGS		/* let's hope that works everywhere (mj) */
+#  define VA_LOCAL_DECL	va_list ap
+#  define VA_START(f)	va_start(ap, f)
+#  define VA_SHIFT(v,t)	;	/* no-op for ANSI */
+#  define VA_END	va_end(ap)
+#else
+#  include <varargs.h>
+#  undef HAVE_STDARGS
+#  define VA_LOCAL_DECL	va_list ap
+#  define VA_START(f)	va_start(ap)	/* f is ignored! */
+#  define VA_SHIFT(v,t)	v = va_arg(ap,t)
+#  define VA_END	va_end(ap)
+#endif
+
+#ifdef HAVE_LONG_DOUBLE
+#define LDOUBLE	long double
+#else
+#define LDOUBLE	double
+#endif
+
+static void dopr(char *buffer, size_t maxlen, const char *format,
+		 va_list args);
+static void fmtstr(char *buffer, size_t * currlen, size_t maxlen,
+		   char *value, int flags, int min, int max);
+static void fmtint(char *buffer, size_t * currlen, size_t maxlen,
+		   long value, int base, int min, int max, int flags);
+static void fmtfp(char *buffer, size_t * currlen, size_t maxlen,
+		  LDOUBLE fvalue, int min, int max, int flags);
+static void dopr_outch(char *buffer, size_t * currlen, size_t maxlen,
+		       char c);
+
+/*
+ * dopr(): poor man's version of doprintf
+ */
+
+/* format read states */
+#define DP_S_DEFAULT 0
+#define DP_S_FLAGS   1
+#define DP_S_MIN     2
+#define DP_S_DOT     3
+#define DP_S_MAX     4
+#define DP_S_MOD     5
+#define DP_S_CONV    6
+#define DP_S_DONE    7
+
+/* format flags - Bits */
+#define DP_F_MINUS 	(1 << 0)
+#define DP_F_PLUS  	(1 << 1)
+#define DP_F_SPACE 	(1 << 2)
+#define DP_F_NUM   	(1 << 3)
+#define DP_F_ZERO  	(1 << 4)
+#define DP_F_UP    	(1 << 5)
+#define DP_F_UNSIGNED 	(1 << 6)
+
+/* Conversion Flags */
+#define DP_C_SHORT   1
+#define DP_C_LONG    2
+#define DP_C_LDOUBLE 3
+
+#define char_to_int(p) (p - '0')
+#define MAX(p,q) ((p >= q) ? p : q)
+
+static void dopr(char *buffer, size_t maxlen, const char *format,
+		 va_list args)
+{
+  char ch;
+  long value;
+  LDOUBLE fvalue;
+  char *strvalue;
+  int min;
+  int max;
+  int state;
+  int flags;
+  int cflags;
+  size_t currlen;
+
+  state = DP_S_DEFAULT;
+  currlen = flags = cflags = min = 0;
+  max = -1;
+  ch = *format++;
+
+  while (state != DP_S_DONE) {
+    if ((ch == '\0') || (currlen >= maxlen))
+      state = DP_S_DONE;
+
+    switch (state) {
+    case DP_S_DEFAULT:
+      if (ch == '%')
+	state = DP_S_FLAGS;
+      else
+	dopr_outch(buffer, &currlen, maxlen, ch);
+      ch = *format++;
+      break;
+    case DP_S_FLAGS:
+      switch (ch) {
+      case '-':
+	flags |= DP_F_MINUS;
+	ch = *format++;
+	break;
+      case '+':
+	flags |= DP_F_PLUS;
+	ch = *format++;
+	break;
+      case ' ':
+	flags |= DP_F_SPACE;
+	ch = *format++;
+	break;
+      case '#':
+	flags |= DP_F_NUM;
+	ch = *format++;
+	break;
+      case '0':
+	flags |= DP_F_ZERO;
+	ch = *format++;
+	break;
+      default:
+	state = DP_S_MIN;
+	break;
+      }
+      break;
+    case DP_S_MIN:
+      if (isdigit(ch)) {
+	min = 10 * min + char_to_int(ch);
+	ch = *format++;
+      } else if (ch == '*') {
+	min = va_arg(args, int);
+	ch = *format++;
+	state = DP_S_DOT;
+      } else
+	state = DP_S_DOT;
+      break;
+    case DP_S_DOT:
+      if (ch == '.') {
+	state = DP_S_MAX;
+	ch = *format++;
+      } else
+	state = DP_S_MOD;
+      break;
+    case DP_S_MAX:
+      if (isdigit(ch)) {
+	if (max < 0)
+	  max = 0;
+	max = 10 * max + char_to_int(ch);
+	ch = *format++;
+      } else if (ch == '*') {
+	max = va_arg(args, int);
+	ch = *format++;
+	state = DP_S_MOD;
+      } else
+	state = DP_S_MOD;
+      break;
+    case DP_S_MOD:
+      /* Currently, we don't support Long Long, bummer */
+      switch (ch) {
+      case 'h':
+	cflags = DP_C_SHORT;
+	ch = *format++;
+	break;
+      case 'l':
+	cflags = DP_C_LONG;
+	ch = *format++;
+	break;
+      case 'L':
+	cflags = DP_C_LDOUBLE;
+	ch = *format++;
+	break;
+      default:
+	break;
+      }
+      state = DP_S_CONV;
+      break;
+    case DP_S_CONV:
+      switch (ch) {
+      case 'd':
+      case 'i':
+	if (cflags == DP_C_SHORT)
+	  value = va_arg(args, short int);
+	else if (cflags == DP_C_LONG)
+	  value = va_arg(args, long int);
+	else
+	  value = va_arg(args, int);
+	fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags);
+	break;
+      case 'o':
+	flags |= DP_F_UNSIGNED;
+	if (cflags == DP_C_SHORT)
+	  value = va_arg(args, unsigned short int);
+	else if (cflags == DP_C_LONG)
+	  value = va_arg(args, unsigned long int);
+	else
+	  value = va_arg(args, unsigned int);
+	fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags);
+	break;
+      case 'u':
+	flags |= DP_F_UNSIGNED;
+	if (cflags == DP_C_SHORT)
+	  value = va_arg(args, unsigned short int);
+	else if (cflags == DP_C_LONG)
+	  value = va_arg(args, unsigned long int);
+	else
+	  value = va_arg(args, unsigned int);
+	fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags);
+	break;
+      case 'X':
+	flags |= DP_F_UP;
+      case 'x':
+	flags |= DP_F_UNSIGNED;
+	if (cflags == DP_C_SHORT)
+	  value = va_arg(args, unsigned short int);
+	else if (cflags == DP_C_LONG)
+	  value = va_arg(args, unsigned long int);
+	else
+	  value = va_arg(args, unsigned int);
+	fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags);
+	break;
+      case 'f':
+	if (cflags == DP_C_LDOUBLE)
+	  fvalue = va_arg(args, LDOUBLE);
+	else
+	  fvalue = va_arg(args, double);
+	/* um, floating point? */
+	fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags);
+	break;
+      case 'E':
+	flags |= DP_F_UP;
+      case 'e':
+	if (cflags == DP_C_LDOUBLE)
+	  fvalue = va_arg(args, LDOUBLE);
+	else
+	  fvalue = va_arg(args, double);
+	break;
+      case 'G':
+	flags |= DP_F_UP;
+      case 'g':
+	if (cflags == DP_C_LDOUBLE)
+	  fvalue = va_arg(args, LDOUBLE);
+	else
+	  fvalue = va_arg(args, double);
+	break;
+      case 'c':
+	dopr_outch(buffer, &currlen, maxlen, va_arg(args, int));
+	break;
+      case 's':
+	strvalue = va_arg(args, char *);
+	if (max < 0)
+	  max = maxlen;		/* ie, no max */
+	fmtstr(buffer, &currlen, maxlen, strvalue, flags, min, max);
+	break;
+      case 'p':
+	strvalue = va_arg(args, void *);
+	fmtint(buffer, &currlen, maxlen, (long) strvalue, 16, min, max,
+	       flags);
+	break;
+      case 'n':
+	if (cflags == DP_C_SHORT) {
+	  short int *num;
+	  num = va_arg(args, short int *);
+	  *num = currlen;
+	} else if (cflags == DP_C_LONG) {
+	  long int *num;
+	  num = va_arg(args, long int *);
+	  *num = currlen;
+	} else {
+	  int *num;
+	  num = va_arg(args, int *);
+	  *num = currlen;
+	}
+	break;
+      case '%':
+	dopr_outch(buffer, &currlen, maxlen, ch);
+	break;
+      case 'w':
+	/* not supported yet, treat as next char */
+	ch = *format++;
+	break;
+      default:
+	/* Unknown, skip */
+	break;
+      }
+      ch = *format++;
+      state = DP_S_DEFAULT;
+      flags = cflags = min = 0;
+      max = -1;
+      break;
+    case DP_S_DONE:
+      break;
+    default:
+      /* hmm? */
+      break;			/* some picky compilers need this */
+    }
+  }
+  if (currlen < maxlen - 1)
+    buffer[currlen] = '\0';
+  else
+    buffer[maxlen - 1] = '\0';
+}
+
+static void fmtstr(char *buffer, size_t * currlen, size_t maxlen,
+		   char *value, int flags, int min, int max)
+{
+  int padlen,
+      strln;			/* amount to pad */
+  int cnt = 0;
+
+  if (value == 0) {
+    value = "<NULL>";
+  }
+
+  for (strln = 0; value[strln]; ++strln);	/* strlen */
+  padlen = min - strln;
+  if (padlen < 0)
+    padlen = 0;
+  if (flags & DP_F_MINUS)
+    padlen = -padlen;		/* Left Justify */
+
+  while ((padlen > 0) && (cnt < max)) {
+    dopr_outch(buffer, currlen, maxlen, ' ');
+    --padlen;
+    ++cnt;
+  }
+  while (*value && (cnt < max)) {
+    dopr_outch(buffer, currlen, maxlen, *value++);
+    ++cnt;
+  }
+  while ((padlen < 0) && (cnt < max)) {
+    dopr_outch(buffer, currlen, maxlen, ' ');
+    ++padlen;
+    ++cnt;
+  }
+}
+
+/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
+
+static void fmtint(char *buffer, size_t * currlen, size_t maxlen,
+		   long value, int base, int min, int max, int flags)
+{
+  int signvalue = 0;
+  unsigned long uvalue;
+  char convert[20];
+  int place = 0;
+  int spadlen = 0;		/* amount to space pad */
+  int zpadlen = 0;		/* amount to zero pad */
+  int caps = 0;
+
+  if (max < 0)
+    max = 0;
+
+  uvalue = value;
+
+  if (!(flags & DP_F_UNSIGNED)) {
+    if (value < 0) {
+      signvalue = '-';
+      uvalue = -value;
+    } else if (flags & DP_F_PLUS)	/* Do a sign (+/i) */
+      signvalue = '+';
+    else if (flags & DP_F_SPACE)
+      signvalue = ' ';
+  }
+
+  if (flags & DP_F_UP)
+    caps = 1;			/* Should characters be upper case? */
+
+  do {
+    convert[place++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef")
+	[uvalue % (unsigned) base];
+    uvalue = (uvalue / (unsigned) base);
+  }
+  while (uvalue && (place < 20));
+  if (place == 20)
+    place--;
+  convert[place] = 0;
+
+  zpadlen = max - place;
+  spadlen = min - MAX(max, place) - (signvalue ? 1 : 0);
+  if (zpadlen < 0)
+    zpadlen = 0;
+  if (spadlen < 0)
+    spadlen = 0;
+  if (flags & DP_F_ZERO) {
+    zpadlen = MAX(zpadlen, spadlen);
+    spadlen = 0;
+  }
+  if (flags & DP_F_MINUS)
+    spadlen = -spadlen;		/* Left Justifty */
+
+#ifdef DEBUG_SNPRINTF
+  dprint(1,
+	 (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
+	  zpadlen, spadlen, min, max, place));
+#endif
+
+  /* Spaces */
+  while (spadlen > 0) {
+    dopr_outch(buffer, currlen, maxlen, ' ');
+    --spadlen;
+  }
+
+  /* Sign */
+  if (signvalue)
+    dopr_outch(buffer, currlen, maxlen, signvalue);
+
+  /* Zeros */
+  if (zpadlen > 0) {
+    while (zpadlen > 0) {
+      dopr_outch(buffer, currlen, maxlen, '0');
+      --zpadlen;
+    }
+  }
+
+  /* Digits */
+  while (place > 0)
+    dopr_outch(buffer, currlen, maxlen, convert[--place]);
+
+  /* Left Justified spaces */
+  while (spadlen < 0) {
+    dopr_outch(buffer, currlen, maxlen, ' ');
+    ++spadlen;
+  }
+}
+
+static LDOUBLE abs_val(LDOUBLE value)
+{
+  LDOUBLE result = value;
+
+  if (value < 0)
+    result = -value;
+
+  return result;
+}
+
+static LDOUBLE pow10(int exp)
+{
+  LDOUBLE result = 1;
+
+  while (exp) {
+    result *= 10;
+    exp--;
+  }
+
+  return result;
+}
+
+static long round(LDOUBLE value)
+{
+  long intpart;
+
+  intpart = value;
+  value = value - intpart;
+  if (value >= 0.5)
+    intpart++;
+
+  return intpart;
+}
+
+static void fmtfp(char *buffer, size_t * currlen, size_t maxlen,
+		  LDOUBLE fvalue, int min, int max, int flags)
+{
+  int signvalue = 0;
+  LDOUBLE ufvalue;
+  char iconvert[20];
+  char fconvert[20];
+  int iplace = 0;
+  int fplace = 0;
+  int padlen = 0;		/* amount to pad */
+  int zpadlen = 0;
+  int caps = 0;
+  long intpart;
+  long fracpart;
+
+  /*
+   * AIX manpage says the default is 0, but Solaris says the default
+   * is 6, and sprintf on AIX defaults to 6
+   */
+  if (max < 0)
+    max = 6;
+
+  ufvalue = abs_val(fvalue);
+
+  if (fvalue < 0)
+    signvalue = '-';
+  else if (flags & DP_F_PLUS)	/* Do a sign (+/i) */
+    signvalue = '+';
+  else if (flags & DP_F_SPACE)
+    signvalue = ' ';
+
+#if 0
+  if (flags & DP_F_UP)
+    caps = 1;			/* Should characters be upper case? */
+#endif
+
+  intpart = ufvalue;
+
+  /*
+   * Sorry, we only support 9 digits past the decimal because of our
+   * conversion method
+   */
+  if (max > 9)
+    max = 9;
+
+  /* We "cheat" by converting the fractional part to integer by
+   * multiplying by a factor of 10
+   */
+  fracpart = round((pow10(max)) * (ufvalue - intpart));
+
+  if (fracpart >= pow10(max)) {
+    intpart++;
+    fracpart -= pow10(max);
+  }
+
+  /* Convert integer part */
+  do {
+    iconvert[iplace++] =
+	(caps ? "0123456789ABCDEF" : "0123456789abcdef")[intpart % 10];
+    intpart = (intpart / 10);
+  }
+  while (intpart && (iplace < 20));
+  if (iplace == 20)
+    iplace--;
+  iconvert[iplace] = 0;
+
+  /* Convert fractional part */
+  do {
+    fconvert[fplace++] =
+	(caps ? "0123456789ABCDEF" : "0123456789abcdef")[fracpart % 10];
+    fracpart = (fracpart / 10);
+  }
+  while (fracpart && (fplace < 20));
+  if (fplace == 20)
+    fplace--;
+  fconvert[fplace] = 0;
+
+  /* -1 for decimal point, another -1 if we are printing a sign */
+  padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
+  zpadlen = max - fplace;
+  if (zpadlen < 0)
+    zpadlen = 0;
+  if (padlen < 0)
+    padlen = 0;
+  if (flags & DP_F_MINUS)
+    padlen = -padlen;		/* Left Justifty */
+
+  if ((flags & DP_F_ZERO) && (padlen > 0)) {
+    if (signvalue) {
+      dopr_outch(buffer, currlen, maxlen, signvalue);
+      --padlen;
+      signvalue = 0;
+    }
+    while (padlen > 0) {
+      dopr_outch(buffer, currlen, maxlen, '0');
+      --padlen;
+    }
+  }
+  while (padlen > 0) {
+    dopr_outch(buffer, currlen, maxlen, ' ');
+    --padlen;
+  }
+  if (signvalue)
+    dopr_outch(buffer, currlen, maxlen, signvalue);
+
+  while (iplace > 0)
+    dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]);
+
+  /*
+   * Decimal point.  This should probably use locale to find the correct
+   * char to print out.
+   */
+  if (max > 0) {
+    dopr_outch(buffer, currlen, maxlen, '.');
+
+    while (fplace > 0)
+      dopr_outch(buffer, currlen, maxlen, fconvert[--fplace]);
+  }
+
+  while (zpadlen > 0) {
+    dopr_outch(buffer, currlen, maxlen, '0');
+    --zpadlen;
+  }
+
+  while (padlen < 0) {
+    dopr_outch(buffer, currlen, maxlen, ' ');
+    ++padlen;
+  }
+}
+
+static void dopr_outch(char *buffer, size_t * currlen, size_t maxlen,
+		       char c)
+{
+  if (*currlen < maxlen)
+    buffer[(*currlen)++] = c;
+}
+
+int egg_vsnprintf(char *str, size_t count, const char *fmt, va_list args)
+{
+  str[0] = 0;
+  dopr(str, count, fmt, args);
+  return (strlen(str));
+}
+#endif				/* !HAVE_VSNPRINTF */
+
+#ifndef HAVE_SNPRINTF
+#  ifdef HAVE_STDARGS
+int egg_snprintf(char *str, size_t count, const char *fmt, ...)
+#  else
+int egg_snprintf(va_alist) va_dcl
+#  endif
+{
+#  ifndef HAVE_STDARGS
+  char *str;
+  size_t count;
+  char *fmt;
+#  endif
+  VA_LOCAL_DECL;
+
+  VA_START(fmt);
+  VA_SHIFT(str, char *);
+  VA_SHIFT(count, size_t);
+  VA_SHIFT(fmt, char *);
+  (void) egg_vsnprintf(str, count, fmt, ap);
+  VA_END;
+  return (strlen(str));
+}
+#endif				/* !HAVE_SNPRINTF */

+ 49 - 49
compat/snprintf.h

@@ -1,49 +1,49 @@
-/*
- * snprintf.h
- *   header file for snprintf.c
- *
- * $Id: snprintf.h,v 1.7 2001/04/12 02:39:44 guppy Exp $
- */
-/*
- * Copyright (C) 2000, 2001 Eggheads Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#ifndef _EGG_COMPAT_SNPRINTF_H_
-#define _EGG_COMPAT_SNPRINTF_H_
-
-/* Use the system libraries version of vsnprintf() if available. Otherwise
- * use our own.
- */
-#ifndef HAVE_VSNPRINTF
-int egg_vsnprintf(char *str, size_t count, const char *fmt, va_list ap);
-#else
-#  define egg_vsnprintf	vsnprintf
-#endif
-
-/* Use the system libraries version of snprintf() if available. Otherwise
- * use our own.
- */
-#ifndef HAVE_SNPRINTF
-#  ifdef __STDC__
-int egg_snprintf(char *str, size_t count, const char *fmt, ...);
-#  else
-int egg_snprintf();
-#  endif
-#define snprintf egg_snprintf
-#endif
-
-#endif	/* !_EGG_COMPAT_SNPRINTF_H_ */
+/*
+ * snprintf.h
+ *   header file for snprintf.c
+ *
+ * $Id: snprintf.h,v 1.1 2005/04/08 13:48:28 Administrator Exp $
+ */
+/*
+ * Copyright (C) 2000, 2001 Eggheads Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef _EGG_COMPAT_SNPRINTF_H_
+#define _EGG_COMPAT_SNPRINTF_H_
+
+/* Use the system libraries version of vsnprintf() if available. Otherwise
+ * use our own.
+ */
+#ifndef HAVE_VSNPRINTF
+int egg_vsnprintf(char *str, size_t count, const char *fmt, va_list ap);
+#else
+#  define egg_vsnprintf	vsnprintf
+#endif
+
+/* Use the system libraries version of snprintf() if available. Otherwise
+ * use our own.
+ */
+#ifndef HAVE_SNPRINTF
+#  ifdef __STDC__
+int egg_snprintf(char *str, size_t count, const char *fmt, ...);
+#  else
+int egg_snprintf();
+#  endif
+#define snprintf egg_snprintf
+#endif
+
+#endif	/* !_EGG_COMPAT_SNPRINTF_H_ */

BIN
compat/snprintf.o


+ 50 - 50
compat/strcasecmp.c

@@ -1,50 +1,50 @@
-/*
- * strcasecmp.c -- provides strcasecmp() and strncasecmp if necessary.
- *
- * $Id: strcasecmp.c,v 1.2 2001/04/12 02:39:44 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001 Eggheads Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#include "main.h"
-#include "memcpy.h"
-
-#ifndef HAVE_STRCASECMP
-int egg_strcasecmp(const char *s1, const char *s2)
-{
-  while ((*s1) && (*s2) && (toupper(*s1) == toupper(*s2))) {
-    s1++;
-    s2++;
-  }
-  return toupper(*s1) - toupper(*s2);
-}
-#endif /* !HAVE_STRCASECMP */
-
-#ifndef HAVE_STRNCASECMP
-int egg_strncasecmp(const char *s1, const char *s2, size_t n)
-{
-  if (!n)
-    return 0;
-  while (--n && (*s1) && (*s2) && (toupper(*s1) == toupper(*s2))) {
-    s1++;
-    s2++;
-  }
-  return toupper(*s1) - toupper(*s2);
-}
-#endif /* !HAVE_STRNCASECMP */
+/*
+ * strcasecmp.c -- provides strcasecmp() and strncasecmp if necessary.
+ *
+ * $Id: strcasecmp.c,v 1.1 2005/04/08 13:48:28 Administrator Exp $
+ */
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001 Eggheads Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include "main.h"
+#include "memcpy.h"
+
+#ifndef HAVE_STRCASECMP
+int egg_strcasecmp(const char *s1, const char *s2)
+{
+  while ((*s1) && (*s2) && (toupper(*s1) == toupper(*s2))) {
+    s1++;
+    s2++;
+  }
+  return toupper(*s1) - toupper(*s2);
+}
+#endif /* !HAVE_STRCASECMP */
+
+#ifndef HAVE_STRNCASECMP
+int egg_strncasecmp(const char *s1, const char *s2, size_t n)
+{
+  if (!n)
+    return 0;
+  while (--n && (*s1) && (*s2) && (toupper(*s1) == toupper(*s2))) {
+    s1++;
+    s2++;
+  }
+  return toupper(*s1) - toupper(*s2);
+}
+#endif /* !HAVE_STRNCASECMP */

+ 46 - 46
compat/strcasecmp.h

@@ -1,46 +1,46 @@
-/*
- * strcasecmp.h
- *   prototypes for strcasecmp.c
- *
- * $Id: strcasecmp.h,v 1.3 2001/04/12 02:39:44 guppy Exp $
- */
-/*
- * Copyright (C) 2000, 2001 Eggheads Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#ifndef _EGG_COMPAT_STRCASECMP_H
-#define _EGG_COMPAT_STRCASECMP_H
-
-#include "src/main.h"
-#include <ctype.h>
-
-
-#ifndef HAVE_STRCASECMP
-/* Use our own implementation. */
-int egg_strcasecmp(const char *, const char *);
-#else
-#  define egg_strcasecmp	strcasecmp
-#endif
-
-#ifndef HAVE_STRNCASECMP
-/* Use our own implementation. */
-int egg_strncasecmp(const char *, const char *, size_t);
-#else
-#  define egg_strncasecmp	strncasecmp
-#endif
-
-#endif	/* !__EGG_COMPAT_STRCASECMP_H */
+/*
+ * strcasecmp.h
+ *   prototypes for strcasecmp.c
+ *
+ * $Id: strcasecmp.h,v 1.1 2005/04/08 13:48:28 Administrator Exp $
+ */
+/*
+ * Copyright (C) 2000, 2001 Eggheads Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef _EGG_COMPAT_STRCASECMP_H
+#define _EGG_COMPAT_STRCASECMP_H
+
+#include "src/main.h"
+#include <ctype.h>
+
+
+#ifndef HAVE_STRCASECMP
+/* Use our own implementation. */
+int egg_strcasecmp(const char *, const char *);
+#else
+#  define egg_strcasecmp	strcasecmp
+#endif
+
+#ifndef HAVE_STRNCASECMP
+/* Use our own implementation. */
+int egg_strncasecmp(const char *, const char *, size_t);
+#else
+#  define egg_strncasecmp	strncasecmp
+#endif
+
+#endif	/* !__EGG_COMPAT_STRCASECMP_H */

BIN
compat/strcasecmp.o


+ 35 - 35
compat/strftime.c

@@ -1,35 +1,35 @@
-/*
- * strftime.c
- *   Portable strftime implementation. Uses GNU's strftime().
- *
- * $Id: strftime.c,v 1.2 2001/04/12 02:39:44 guppy Exp $
- */
-/*
- * Copyright (C) 2000, 2001 Eggheads Development Team
- * Written by Fabian Knittel
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#include "src/main.h"
-#include "strftime.h"
-
-#ifndef HAVE_STRFTIME
-#  undef emacs
-#  undef _LIBC
-#  define strftime	egg_strftime
-
-#  include "gnu_strftime.c"
-#endif	/* !HAVE_STRFTIME */
+/*
+ * strftime.c
+ *   Portable strftime implementation. Uses GNU's strftime().
+ *
+ * $Id: strftime.c,v 1.1 2005/04/08 13:48:29 Administrator Exp $
+ */
+/*
+ * Copyright (C) 2000, 2001 Eggheads Development Team
+ * Written by Fabian Knittel
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include "src/main.h"
+#include "strftime.h"
+
+#ifndef HAVE_STRFTIME
+#  undef emacs
+#  undef _LIBC
+#  define strftime	egg_strftime
+
+#  include "gnu_strftime.c"
+#endif	/* !HAVE_STRFTIME */

+ 42 - 42
compat/strftime.h

@@ -1,42 +1,42 @@
-/*
- * strftime.h
- *   header file for strftime.c
- *
- * $Id: strftime.h,v 1.1 2000/09/12 15:34:01 fabian Exp $
- */
-/* 
- * Copyright (C) 2000  Eggheads
- * Written by Fabian Knittel
- * 
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#ifndef _EGG_COMPAT_STRFTIME_H_
-#define _EGG_COMPAT_STRFTIME_H_
-
-#include "src/main.h"
-#include <time.h>
-
-/* Use the system libraries version of strftime() if available. Otherwise
- * use our own.
- */
-#ifndef HAVE_STRFTIME
-size_t egg_strftime(char *s, size_t maxsize, const char *format,
-		    const struct tm *tp);
-#else
-#  define egg_strftime	strftime
-#endif
-
-#endif	/* !_EGG_COMPAT_STRFTIME_H_ */
+/*
+ * strftime.h
+ *   header file for strftime.c
+ *
+ * $Id: strftime.h,v 1.1 2005/04/08 13:48:29 Administrator Exp $
+ */
+/* 
+ * Copyright (C) 2000  Eggheads
+ * Written by Fabian Knittel
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef _EGG_COMPAT_STRFTIME_H_
+#define _EGG_COMPAT_STRFTIME_H_
+
+#include "src/main.h"
+#include <time.h>
+
+/* Use the system libraries version of strftime() if available. Otherwise
+ * use our own.
+ */
+#ifndef HAVE_STRFTIME
+size_t egg_strftime(char *s, size_t maxsize, const char *format,
+		    const struct tm *tp);
+#else
+#  define egg_strftime	strftime
+#endif
+
+#endif	/* !_EGG_COMPAT_STRFTIME_H_ */

BIN
compat/strftime.o


+ 5 - 2
core/mini_httpd.c

@@ -304,7 +304,7 @@ static void http_activity(int idx, char *buf, int len)
 #endif
   int lev, content_length;
   struct timeval t;
-  double pre_time;
+  double pre_time, post_time;
 
   debug2("%s: %s", dcc[idx].host, buf);
 
@@ -388,9 +388,12 @@ static void http_activity(int idx, char *buf, int len)
       debug0("now sending...");
       gettimeofday(&t, NULL);
       pre_time = (float) t.tv_sec + (((float) t.tv_usec) / 1000000);
+      debug1("pre-time: %.3f", pre_time);
       process_get_request(idx);
       gettimeofday(&t, NULL);
-      debug1("Processing time: %.3f", ((float) t.tv_sec + (((float) t.tv_usec) / 1000000)) - pre_time);
+      post_time = ((float) t.tv_sec + (((float) t.tv_usec) / (float) 1000000));
+      debug1("post-time: %.3f", post_time);
+      debug1("Processing time: %.3f",  post_time - pre_time);
       dcc[idx].status = 1;
 #ifndef OLDBOT
       /* If there's no data in our socket, we immediately get rid of it.

+ 309 - 309
core/misc.c

@@ -1,309 +1,309 @@
-/*
- * Copyright (C) 2000,2001  Florian Sander
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-static char *inverted_csplit(char **rest, char divider)
-{
-  char *p;
-
-  if (!rest)
-    return *rest = "";
-  p = *rest + strlen(*rest) - 1;
-  while ((p[0] != divider) && (p != *rest))
-    p--;
-  p[0] = 0;
-  return p + 1;
-}
-
-/* stolen from tcl_duration in tclmisc.c */
-static char duration_temp[256];
-static char *stats_duration(int seconds, int details)
-{
-  char s[256];
-  time_t sec;
-  int details_shown = 0;
-
-  sec = seconds;
-  s[0] = 0;
-  if (sec < 1) {
-    snprintf(duration_temp, sizeof(duration_temp), "%s", SLSOMETIME);
-    return duration_temp;
-  }
-  if (sec >= 31536000) {
-    sprintf(s, "%d %s ", (int) (sec / 31536000),
-            ((int) (sec / 31536000) > 1) ? SLYEARS : SLYEAR);
-    sec -= (((int) (sec / 31536000)) * 31536000);
-    details_shown++;
-  }
-  if ((sec >= 604800) && (details_shown < details)) {
-    sprintf(&s[strlen(s)], "%d %s ", (int) (sec / 604800),
-            ((int) (sec / 604800) > 1) ? SLWEEKS : SLWEEK);
-    sec -= (((int) (sec / 604800)) * 604800);
-    details_shown++;
-  }
-  if ((sec >= 86400) && (details_shown < details)) {
-    sprintf(&s[strlen(s)], "%d %s ", (int) (sec / 86400),
-            ((int) (sec / 86400) > 1) ? SLDAYS : SLDAY);
-    sec -= (((int) (sec / 86400)) * 86400);
-    details_shown++;
-  }
-  if ((sec >= 3600) && (details_shown < details)) {
-    sprintf(&s[strlen(s)], "%d %s ", (int) (sec / 3600),
-            ((int) (sec / 3600) > 1) ? SLHOURS : SLHOUR);
-    sec -= (((int) (sec / 3600)) * 3600);
-    details_shown++;
-  }
-  if ((sec >= 60) && (details_shown < details)) {
-    sprintf(&s[strlen(s)], "%d %s ", (int) (sec / 60),
-            ((int) (sec / 60) > 1) ? SLMINUTES : SLMINUTE);
-    sec -= (((int) (sec / 60)) * 60);
-    details_shown++;
-  }
-  if ((sec > 0) && (details_shown < details)) {
-    sprintf(&s[strlen(s)], "%d %s", (int) (sec / 1),
-            ((int) (sec / 1) > 1) ? SLSECONDS : SLSECOND);
-  }
-  if (s[strlen(s) - 1] == ' ')
-  	s[strlen(s) - 1]='\0';
-  snprintf(duration_temp, sizeof(duration_temp), "%s", s);
-  return duration_temp;
-}
-
-static int countsmileys(char *text)
-{
-  char buf[512], *pbuf, *smiley, *p;
-  int ismileys = 0;
-
-  sprintf(buf, "%s", smileys);
-  pbuf = buf;
-  while (strlen(pbuf) > 0) {
-    smiley = newsplit(&pbuf);
-    p = strstr(text, smiley);
-    while (p) {
-      ismileys++;
-      p += strlen(smiley);
-      p = strstr(p, smiley);
-    }
-  }
-  return ismileys;
-}
-
-static int countwords(char *buf)
-{
-  int i, words = 1;
-
-  for (i = 0; i < strlen(buf); i++) {
-    if ((buf[i] == ' ') && (buf[i+1] != ' '))
-      words++;
-  }
-  return words;
-}
-
-static int countquestions(char *buf)
-{
-  int i, questions = 0;
-
-  for (i = 0; i < strlen(buf); i++) {
-    if ((buf[i] == '?') && (buf[i+1] != '?'))
-      questions++;
-  }
-  return questions;
-}
-
-// void lower(char*p){for(;*p=tolower(*p);p++);}
-
-static void strlower(char *text)
-{
-  int i;
-
-  for (i = 0; i < strlen(text); i++)
-    text[i] = tolower(text[i]);
-}
-
-static int gethour()
-{
-  char ts[10];
-  time_t tt;
-
-  tt = now;
-  strftime(ts, 9, "%H", localtime(&tt));
-  ts[9] = 0;
-  return atoi(ts);
-}
-
-static int getmonth()
-{
-  char ts[10];
-  time_t tt;
-
-  tt = now;
-  strftime(ts, 9, "%m", localtime(&tt));
-  ts[9] = 0;
-  return atoi(ts);
-}
-
-static int ismonday()
-{
-  char ts[10];
-  time_t tt;
-
-  tt = now;
-  strftime(ts, 9, "%a", localtime(&tt));
-  ts[9] = 0;
-  return (!strcasecmp(ts, "mon"));
-}
-
-/* maskstricthost():
- * basically the same as maskhost() from src/misc.c, but _never_ stripts
- * "~+-^=" off the host
- * maskhost() version: * $Id: misc.c,v 1.30 2000/10/27 19:27:32 fabian Exp $
- */
-static void maskstricthost(const char *s, char *nw)
-{
-  register const char *p, *q, *e, *f;
-  int i;
-
-  *nw++ = '*';
-  *nw++ = '!';
-  p = (q = strchr(s, '!')) ? q + 1 : s;
-  /* Strip of any nick, if a username is found, use last 8 chars */
-  if ((q = strchr(p, '@'))) {
-    int fl = 0;
-
-    if ((q - p) > 9) {
-      nw[0] = '*';
-      p = q - 7;
-      i = 1;
-    } else
-      i = 0;
-    while (*p != '@') {
-      if (!fl && strchr("~+-^=", *p)) {
-//        if (strict_host)
-      nw[i] = '?';
-//    else
-//      i--;
-      } else
-    nw[i] = *p;
-      fl++;
-      p++;
-      i++;
-    }
-    nw[i++] = '@';
-    q++;
-  } else {
-    nw[0] = '*';
-    nw[1] = '@';
-    i = 2;
-    q = s;
-  }
-  nw += i;
-  e = NULL;
-  /* Now q points to the hostname, i point to where to put the mask */
-  if ((!(p = strchr(q, '.')) || !(e = strchr(p + 1, '.'))) && !strchr(q, ':'))
-    /* TLD or 2 part host */
-    strcpy(nw, q);
-  else {
-    if (e == NULL) {        /* IPv6 address?        */
-      const char *mask_str;
-
-      f = strrchr(q, ':');
-      if (strchr(f, '.')) { /* IPv4 wrapped in an IPv6? */
-    f = strrchr(f, '.');
-    mask_str = ".*";
-      } else            /* ... no, true IPv6.       */
-    mask_str = ":*";
-      strncpy(nw, q, f - q);
-      /* No need to nw[f-q] = 0 here, as the strcpy below will
-       * terminate the string for us.
-       */
-      nw += (f - q);
-      strcpy(nw, mask_str);
-    } else {
-      for (f = e; *f; f++);
-      f--;
-      if (*f >= '0' && *f <= '9') { /* Numeric IP address */
-    while (*f != '.')
-      f--;
-    strncpy(nw, q, f - q);
-    /* No need to nw[f-q] = 0 here, as the strcpy below will
-     * terminate the string for us.
-     */
-    nw += (f - q);
-    strcpy(nw, ".*");
-      } else {              /* Normal host >= 3 parts */
-    /*    a.b.c  -> *.b.c
-     *    a.b.c.d ->  *.b.c.d if tld is a country (2 chars)
-     *             OR   *.c.d if tld is com/edu/etc (3 chars)
-     *    a.b.c.d.e -> *.c.d.e   etc
-     */
-    const char *x = strchr(e + 1, '.');
-
-    if (!x)
-      x = p;
-    else if (strchr(x + 1, '.'))
-      x = e;
-    else if (strlen(x) == 3)
-      x = p;
-    else
-      x = e;
-    sprintf(nw, "*%s", x);
-      }
-    }
-  }
-}
-
-/* get_timerange():
- *
- */
-static int get_timerange(char *text)
-{
-  if (!strcasecmp(text, "today"))
-    return S_TODAY;
-  else if (!strcasecmp(text, "daily"))
-    return S_TODAY;
-  else if (!strcasecmp(text, "weekly"))
-    return S_WEEKLY;
-  else if (!strcasecmp(text, "monthly"))
-    return S_MONTHLY;
-  else if (!strcasecmp(text, "total"))
-    return S_TOTAL;
-  else
-    return T_ERROR;
-  // FIXME: Check for slanged timeranges!
-}
-
-#define SENDMAIL_ERROR 1
-
-static int email_send(char *to, char *subject, char *body)
-{
-	FILE *f;
-
-	f = popen("/usr/sbin/sendmail -t", "w");
-	if (!f)
-		return SENDMAIL_ERROR;
-	fprintf(f, "To: %s\n", to);
-	fprintf(f, "From: %s\n", botnetnick);
-	fprintf(f, "Subject: %s\n", subject);
-	fprintf(f, "\n");
-	fprintf(f, "%s", body);
-	fprintf(f, "\n.\n");
-	debug0("rückmeldung von pclose testen");
-	if (pclose(f) == -1)
-		return SENDMAIL_ERROR;
-	else
-		return 0;
-}
+/*
+ * Copyright (C) 2000,2001  Florian Sander
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+static char *inverted_csplit(char **rest, char divider)
+{
+  char *p;
+
+  if (!rest)
+    return *rest = "";
+  p = *rest + strlen(*rest) - 1;
+  while ((p[0] != divider) && (p != *rest))
+    p--;
+  p[0] = 0;
+  return p + 1;
+}
+
+/* stolen from tcl_duration in tclmisc.c */
+static char duration_temp[256];
+static char *stats_duration(int seconds, int details)
+{
+  char s[256];
+  time_t sec;
+  int details_shown = 0;
+
+  sec = seconds;
+  s[0] = 0;
+  if (sec < 1) {
+    snprintf(duration_temp, sizeof(duration_temp), "%s", SLSOMETIME);
+    return duration_temp;
+  }
+  if (sec >= 31536000) {
+    sprintf(s, "%d %s ", (int) (sec / 31536000),
+            ((int) (sec / 31536000) > 1) ? SLYEARS : SLYEAR);
+    sec -= (((int) (sec / 31536000)) * 31536000);
+    details_shown++;
+  }
+  if ((sec >= 604800) && (details_shown < details)) {
+    sprintf(&s[strlen(s)], "%d %s ", (int) (sec / 604800),
+            ((int) (sec / 604800) > 1) ? SLWEEKS : SLWEEK);
+    sec -= (((int) (sec / 604800)) * 604800);
+    details_shown++;
+  }
+  if ((sec >= 86400) && (details_shown < details)) {
+    sprintf(&s[strlen(s)], "%d %s ", (int) (sec / 86400),
+            ((int) (sec / 86400) > 1) ? SLDAYS : SLDAY);
+    sec -= (((int) (sec / 86400)) * 86400);
+    details_shown++;
+  }
+  if ((sec >= 3600) && (details_shown < details)) {
+    sprintf(&s[strlen(s)], "%d %s ", (int) (sec / 3600),
+            ((int) (sec / 3600) > 1) ? SLHOURS : SLHOUR);
+    sec -= (((int) (sec / 3600)) * 3600);
+    details_shown++;
+  }
+  if ((sec >= 60) && (details_shown < details)) {
+    sprintf(&s[strlen(s)], "%d %s ", (int) (sec / 60),
+            ((int) (sec / 60) > 1) ? SLMINUTES : SLMINUTE);
+    sec -= (((int) (sec / 60)) * 60);
+    details_shown++;
+  }
+  if ((sec > 0) && (details_shown < details)) {
+    sprintf(&s[strlen(s)], "%d %s", (int) (sec / 1),
+            ((int) (sec / 1) > 1) ? SLSECONDS : SLSECOND);
+  }
+  if (s[strlen(s) - 1] == ' ')
+  	s[strlen(s) - 1]='\0';
+  snprintf(duration_temp, sizeof(duration_temp), "%s", s);
+  return duration_temp;
+}
+
+static int countsmileys(char *text)
+{
+  char buf[512], *pbuf, *smiley, *p;
+  int ismileys = 0;
+
+  sprintf(buf, "%s", smileys);
+  pbuf = buf;
+  while (strlen(pbuf) > 0) {
+    smiley = newsplit(&pbuf);
+    p = strstr(text, smiley);
+    while (p) {
+      ismileys++;
+      p += strlen(smiley);
+      p = strstr(p, smiley);
+    }
+  }
+  return ismileys;
+}
+
+static int countwords(char *buf)
+{
+  int i, words = 1;
+
+  for (i = 0; i < strlen(buf); i++) {
+    if ((buf[i] == ' ') && (buf[i+1] != ' '))
+      words++;
+  }
+  return words;
+}
+
+static int countquestions(char *buf)
+{
+  int i, questions = 0;
+
+  for (i = 0; i < strlen(buf); i++) {
+    if ((buf[i] == '?') && (buf[i+1] != '?'))
+      questions++;
+  }
+  return questions;
+}
+
+// void lower(char*p){for(;*p=tolower(*p);p++);}
+
+static void strlower(char *text)
+{
+  int i;
+
+  for (i = 0; i < strlen(text); i++)
+    text[i] = tolower(text[i]);
+}
+
+static int gethour()
+{
+  char ts[10];
+  time_t tt;
+
+  tt = now;
+  strftime(ts, 9, "%H", localtime(&tt));
+  ts[9] = 0;
+  return atoi(ts);
+}
+
+static int getmonth()
+{
+  char ts[10];
+  time_t tt;
+
+  tt = now;
+  strftime(ts, 9, "%m", localtime(&tt));
+  ts[9] = 0;
+  return atoi(ts);
+}
+
+static int ismonday()
+{
+  char ts[10];
+  time_t tt;
+
+  tt = now;
+  strftime(ts, 9, "%a", localtime(&tt));
+  ts[9] = 0;
+  return (!strcasecmp(ts, "mon"));
+}
+
+/* maskstricthost():
+ * basically the same as maskhost() from src/misc.c, but _never_ stripts
+ * "~+-^=" off the host
+ * maskhost() version: * $Id: misc.c,v 1.1 2005/04/08 13:48:30 Administrator Exp $
+ */
+static void maskstricthost(const char *s, char *nw)
+{
+  register const char *p, *q, *e, *f;
+  int i;
+
+  *nw++ = '*';
+  *nw++ = '!';
+  p = (q = strchr(s, '!')) ? q + 1 : s;
+  /* Strip of any nick, if a username is found, use last 8 chars */
+  if ((q = strchr(p, '@'))) {
+    int fl = 0;
+
+    if ((q - p) > 9) {
+      nw[0] = '*';
+      p = q - 7;
+      i = 1;
+    } else
+      i = 0;
+    while (*p != '@') {
+      if (!fl && strchr("~+-^=", *p)) {
+//        if (strict_host)
+      nw[i] = '?';
+//    else
+//      i--;
+      } else
+    nw[i] = *p;
+      fl++;
+      p++;
+      i++;
+    }
+    nw[i++] = '@';
+    q++;
+  } else {
+    nw[0] = '*';
+    nw[1] = '@';
+    i = 2;
+    q = s;
+  }
+  nw += i;
+  e = NULL;
+  /* Now q points to the hostname, i point to where to put the mask */
+  if ((!(p = strchr(q, '.')) || !(e = strchr(p + 1, '.'))) && !strchr(q, ':'))
+    /* TLD or 2 part host */
+    strcpy(nw, q);
+  else {
+    if (e == NULL) {        /* IPv6 address?        */
+      const char *mask_str;
+
+      f = strrchr(q, ':');
+      if (strchr(f, '.')) { /* IPv4 wrapped in an IPv6? */
+    f = strrchr(f, '.');
+    mask_str = ".*";
+      } else            /* ... no, true IPv6.       */
+    mask_str = ":*";
+      strncpy(nw, q, f - q);
+      /* No need to nw[f-q] = 0 here, as the strcpy below will
+       * terminate the string for us.
+       */
+      nw += (f - q);
+      strcpy(nw, mask_str);
+    } else {
+      for (f = e; *f; f++);
+      f--;
+      if (*f >= '0' && *f <= '9') { /* Numeric IP address */
+    while (*f != '.')
+      f--;
+    strncpy(nw, q, f - q);
+    /* No need to nw[f-q] = 0 here, as the strcpy below will
+     * terminate the string for us.
+     */
+    nw += (f - q);
+    strcpy(nw, ".*");
+      } else {              /* Normal host >= 3 parts */
+    /*    a.b.c  -> *.b.c
+     *    a.b.c.d ->  *.b.c.d if tld is a country (2 chars)
+     *             OR   *.c.d if tld is com/edu/etc (3 chars)
+     *    a.b.c.d.e -> *.c.d.e   etc
+     */
+    const char *x = strchr(e + 1, '.');
+
+    if (!x)
+      x = p;
+    else if (strchr(x + 1, '.'))
+      x = e;
+    else if (strlen(x) == 3)
+      x = p;
+    else
+      x = e;
+    sprintf(nw, "*%s", x);
+      }
+    }
+  }
+}
+
+/* get_timerange():
+ *
+ */
+static int get_timerange(char *text)
+{
+  if (!strcasecmp(text, "today"))
+    return S_TODAY;
+  else if (!strcasecmp(text, "daily"))
+    return S_TODAY;
+  else if (!strcasecmp(text, "weekly"))
+    return S_WEEKLY;
+  else if (!strcasecmp(text, "monthly"))
+    return S_MONTHLY;
+  else if (!strcasecmp(text, "total"))
+    return S_TOTAL;
+  else
+    return T_ERROR;
+  // FIXME: Check for slanged timeranges!
+}
+
+#define SENDMAIL_ERROR 1
+
+static int email_send(char *to, char *subject, char *body)
+{
+	FILE *f;
+
+	f = popen("/usr/sbin/sendmail -t", "w");
+	if (!f)
+		return SENDMAIL_ERROR;
+	fprintf(f, "To: %s\n", to);
+	fprintf(f, "From: %s\n", botnetnick);
+	fprintf(f, "Subject: %s\n", subject);
+	fprintf(f, "\n");
+	fprintf(f, "%s", body);
+	fprintf(f, "\n.\n");
+	debug0("rückmeldung von pclose testen");
+	if (pclose(f) == -1)
+		return SENDMAIL_ERROR;
+	else
+		return 0;
+}

+ 6 - 0
core/userrec.c

@@ -226,6 +226,10 @@ static void stats_autosadd(struct stats_member *m, struct stats_chan *chan)
            m->nick, chan->chan, m->user->user);
     return;
   }
+  if (!m->uhost)
+  	return;
+  if (strchr(m->uhost, '*') ||  strchr(m->uhost, '?'))
+  	return;
   u = findsuser_by_name(m->nick);
   host = nmalloc(strlen(m->uhost) + strlen(m->nick) + 2);
   sprintf(host, "%s!%s", m->nick, m->uhost);
@@ -279,6 +283,8 @@ static void welcome_suser(char *nick, struct stats_userlist *u, char *chan)
   char *text;
 
   reset_global_vars();
+  if (!greet_new_users)
+  	return;
   glob_user = u;
   glob_nick = nick;
   glob_slang = slang_find(coreslangs, slang_chanlang_get(chanlangs, chan));

+ 1 - 0
core/vars.c

@@ -69,3 +69,4 @@ static int expire_base = 7;	/* Minimum time before user gets deleted */
 static int expire_factor = 25;	/* percent value which defines how much of
 				   a user's "age" he can stay away without
 				   being expired */
+static int greet_new_users = 1; /* send a welcome message to new users? */

+ 2 - 171
stats.c

@@ -31,7 +31,7 @@
 
 #define MAKING_STATS
 #define MODULE_NAME "stats"
-#define MODULE_VERSION "1.4.0 dev20"
+#define MODULE_VERSION "1.4.0 dev21"
 #ifndef NO_EGG
 #include "../module.h"
 #include "../irc.mod/irc.h"
@@ -112,176 +112,6 @@ static int stats_expmem()
 	return 0;
 }
 
-/*
-static int stats_expmem()
-{
-  int size = 0;
-
-  Context;
-#ifdef DYNAMIC_MEM_DEBUG
-  return 0;
-#endif
-  size += stats_globstats_expmem(sdata);
-  Context;
-  size += suserlist_expmem(suserlist);
-  size += llist_expmem(&schanset);
-  size += expmem_templates();
-  size += expmem_httpd();
-  size += expmem_global_vars();
-  size += slang_glob_expmem();
-  size += slang_expmem(coreslangs);
-  size += slang_chanlang_expmem(chanlangs);
-  if (stats_pubcmd_reply)
-    size += strlen(stats_pubcmd_reply) + 1;
-  return size;
-}
-
-static int stats_globstats_expmem(struct stats_global *gs)
-{
-  int size = 0;
-
-  while (gs) {
-    size += sizeof(struct stats_global);
-    size += strlen(gs->chan) + 1;
-    size += localstats_expmem(gs->local);
-    size += wordstats_expmem(gs->words);
-    size += topics_expmem(gs->topics);
-    size += urls_expmem(gs->urls);
-    size += hosts_expmem(gs->hosts);
-    size += quotes_expmem(gs->log);
-    size += kicks_expmem(gs->kicks);
-    gs = gs->next;
-  }
-  return size;
-}
-
-static int suserlist_expmem(struct stats_userlist *e)
-{
-  int size = 0;
-
-  Context;
-  while (e) {
-    size += stats_userlist_expmem_entry(e);
-    e = e->next;
-  }
-  return size;
-}
-
-static int hostlist_expmem(struct stats_hostlist *e)
-{
-  int size = 0;
-
-  Context;
-  while (e) {
-    size += sizeof(struct stats_hostlist);
-    size += strlen(e->mask) + 1;
-    e = e->next;
-  }
-  return size;
-}
-
-static int localstats_expmem(struct stats_local *sl)
-{
-  int size = 0;
-
-  Context;
-  while (sl) {
-    size += sizeof(struct stats_local);
-    size += strlen(sl->user) + 1;
-    size += wordstats_expmem(sl->words);
-    size += quotes_expmem(sl->quotes);
-    sl = sl->next;
-  }
-  Context;
-  return size;
-}
-
-static int wordstats_expmem(wordstats *l)
-{
-  int size = 0;
-
-  Context;
-  while (l) {
-    size += strlen(l->word) + 1;
-    size += sizeof(wordstats);
-    l = l->next;
-  }
-  return size;
-}
-
-static int quotes_expmem(quotestr *l)
-{
-  int size = 0;
-
-  Context;
-  while (l) {
-    size += strlen(l->quote) + 1;
-    size += sizeof(quotestr);
-    l = l->next;
-  }
-  return size;
-}
-
-static int topics_expmem(topicstr *e)
-{
-  int size = 0;
-
-  Context;
-  while (e) {
-    size += strlen(e->topic) + 1;
-    size += strlen(e->by) + 1;
-    size += sizeof(topicstr);
-    e = e->next;
-  }
-  return size;
-}
-
-static int urls_expmem(struct stats_url *e)
-{
-  int size = 0;
-
-  Context;
-  while (e) {
-    size += strlen(e->url) + 1;
-    size += strlen(e->by) + 1;
-    size += sizeof(struct stats_url);
-    e = e->next;
-  }
-  return size;
-}
-
-static int kicks_expmem(struct stats_kick *e)
-{
-  int size = 0;
-
-  Context;
-  while (e) {
-    size += sizeof(struct stats_kick);
-    size += quotes_expmem(e->log);
-    e = e->next;
-  }
-  return size;
-}
-
-static int hosts_expmem(hoststr *e)
-{
-  int size = 0;
-
-  Context;
-  while (e) {
-    size += strlen(e->host) + 1;
-    size += sizeof(hoststr);
-    e = e->next;
-  }
-  return size;
-}
-*/
-
-
-
-
-
-
 /* a report on the module status */
 static void stats_report(int idx, int details)
 {
@@ -365,6 +195,7 @@ static tcl_ints my_tcl_ints[] =
   {"min-lines", &min_lines, 0},
   {"expire-base", &expire_base, 0},
   {"expire-factor", &expire_factor, 0},
+  {"greet-new-users", &greet_new_users, 0},
   {0, 0, 0}
 };
 

+ 12 - 6
stats.conf

@@ -23,20 +23,26 @@ set save-stats 15
 #     him/herself, he/she must cycle the chan to be recognized. (lowest CPU usage)
 set autoadd 5
 
+# send a welcome-message to auto-added users?
+set greet-new-users 1
+
 # minimum number of lines that a user must have spoken before he/she gets
 # autoadded (you don't want "dead" users in your database, do you?)
 set autoadd-min-lines 5
 
+## User expireing
+
+# expire-base defines how long a users can stay away from the channel
+# before they get deleted
 set expire-base 7
 
+# the expire-factor get's added to the expire-base. This factor is the percentage
+# of the user's "age" (time since his first appearance in the channel)
 set expire-factor 25
 
-# delete users that have been added by the module if they haven't been seen
-# for more than x days
-#set expire-users 30
-
-# if the user has a password set, delay the expiration for another x days
-#set expire-delay 30
+# a short example:
+# 'dummy' has been in the channel since 100 days. So with the default settings like
+# above, he can stay away for 7 + (100 * 25%) = 7 + 25 = 32 days.
 
 # log wordstats (most used words) (this stats are resetted daily)
 # NOTE: This is very cpu- and memory consuming, so don't

+ 8 - 0
subUPDATES

@@ -0,0 +1,8 @@
+Changes in this devel-version:
+------------------------------
+
+dev21:
+
+- users with wildcards in their hosts aren't auto-added anymore
+- added option to turn off greeting of new users
+- added [suserlist]

+ 30 - 0
tclstats.c

@@ -232,6 +232,34 @@ static int tcl_activeusers STDVAR
 	return TCL_OK;
 }
 
+static int tcl_suserlist STDVAR
+{
+	struct stats_userlist *user;
+
+	BADARGS(1, 1);
+	for (user = suserlist; user; user = user->next)
+		Tcl_AppendElement(irp, user->user);
+	return TCL_OK;
+}
+
+static int tcl_delsuser STDVAR
+{
+  struct stats_userlist *u;
+
+  Context;
+  BADARGS(2, 2, " statsusername");
+
+  u = findsuser_by_name(argv[1]);
+  if (!u) {
+    Tcl_AppendResult(irp, "User not found.", NULL);
+    return TCL_ERROR;
+  }
+  delsuser(argv[1]);
+  return TCL_OK;
+}
+
+
+
 static tcl_cmds mytcls[] =
 {
   {"incrstats", tcl_incrstats},
@@ -247,5 +275,7 @@ static tcl_cmds mytcls[] =
   {"loadstatslang", tcl_loadstatslang},
   {"schattr", tcl_schattr},
   {"activeusers", tcl_activeusers},
+  {"suserlist", tcl_suserlist},
+  {"delsuser", tcl_delsuser},
   {0, 0}
 };

+ 19 - 24
templates/stats/classic/classic.en.lang

@@ -151,30 +151,25 @@ F vocables 2 <a href="../users/<?user/?>/"><?user/?></a> used almost as much voc
 1000 User Login
 1010 Username
 1020 Password
-1030 If you don't have a password set yet, you can do it now on IRC:
-1040 WARNING: This password will be transferred and stored in plaintext, so better don't use your mail password or any other important password.
-1050 Login
-1060 I forgot my password
-
-1100 Settings for <?user/?>
-1110 Age
-1115 Allowed inactivity
-1116 before account gets deleted
-1120 ICQ#
-1130 eMail
-1140 Homepage
-1150 List me in the top<?topnr/?>?
-1151 Automatically add new hosts to my account?
-1152 Publish my stats at all?
-1153 (for those concerned about privacy...)
-1160 yes
-1165 no
-1170 If you want to change your password, enter the new one below:
-1171 New Password
-1172 Confirm New Password
-1180 If you want to merge your account with another one
-1181
-1182
+1030 Age
+1035 allowed inactivity
+1036 account will be deleted after this deadline
+1040 new password
+1045 new password (confirmation)
+1050 ICQ#
+1060 eMail
+1070 Homepage
+1080 List me in the top<?topnr/?>?
+1081 add new hosts to my account automatically?
+1082 make my stats available at all?
+1083 (in case you are worried about privacy...)
+1085 yay
+1086 nope
+
+1100 User Login
+1110 If you don't have a password set yet, you can do it now on IRC:
+1120 WARNING: This password will be transferred and stored in plaintext, so better don't use your mail password or any other important password.
+1130 I forgot my password
 
 1200 Login Error!
 1210 Your attempt to login resulted in the following error:

+ 1 - 1
templates/stats/classic/usersettings.tpl

@@ -62,7 +62,7 @@
   </td>
 </tr>
 <tr><td>&nbsp;</td><td>&nbsp;</td></tr>
-<tr><td><?slang id="</td><td>&nbsp;</td></tr>
+<tr><td>&nbsp;</td><td>&nbsp;</td></tr>
 <tr>
   <td><?-- "New Password" --/?><?slang id="1040"/?>: </td>
   <td><INPUT TYPE="password" SIZE="12" MAXLENGTH="1000" NAME="newpassword" value=""></td>

+ 40 - 48
todo.txt

@@ -1,48 +1,40 @@
-/msg <bot> SIDENT
-
-> 2. min_lines_value: I mentioned this last time. This tcl value sets 
-> how many lines minimum to check for before calculating the WPL and 
-> IDLE stats.
-
-> 5.  Because of #4, I changed the place command so that if someone 
-> has 0 as the stat value (or less than min_lines_value), it outputs 
-> a different lang line:
-> 1019 [nick] is last.
-> This makes more sense when say, 100 users have 0 as their stat 
-> value. They are all last and shouldnt be counted!
-
-gettotal() optimieren
-
-check_desynch(): countmembers() optimieren (besser zähler in chan-struct)
-
-gethour() optimieren
-
-Mit Argo war heute nicht zu scherzen... 1 Opfer erfuhren dies auf die harte Art.
-Auch [smiley]'s Toleranz war in 0 Fällen erschöpft.
-
-TCL-Befehl um die stats von allen zu resetten.
-
-monats-reset verbessern.
-
-getstats idle
-
-17.1.2002 	schan_members_find() optimieren?
-
-23.4.2002
-> Something else I just noticed, Age  31 weeks 1 day 11 hours. But when I 
-> log into Edit my settings it shows Age: 1 day 10 hours 43 minutes.  I 
-> only set a statspass a day ago ?
-
-21.3.2002
-mal schauen, ob man den typ "minutes" nicht zu "time" umbenennen kann
-
-7.4.2002 - [20:10:56] QQ [iRC]: actions dont get logged
-
-11.5.2002
-
-hi, i thinks  there  is a little  bug in stat module,  it have some  problem with nick that contain [ ] it recognize   } {
-and  another problem with autoadd mask: *!?***@*.29-151.libero.it this mask is general most user have this mask couse  username is undefinited.
-
-das grüßen-zeugs als option in die config datei pflatschen
-
-tcl-funktion um user aufzulisten
+/msg <bot> SIDENT
+
+> 2. min_lines_value: I mentioned this last time. This tcl value sets 
+> how many lines minimum to check for before calculating the WPL and 
+> IDLE stats.
+
+> 5.  Because of #4, I changed the place command so that if someone 
+> has 0 as the stat value (or less than min_lines_value), it outputs 
+> a different lang line:
+> 1019 [nick] is last.
+> This makes more sense when say, 100 users have 0 as their stat 
+> value. They are all last and shouldnt be counted!
+
+gettotal() optimieren
+
+check_desynch(): countmembers() optimieren (besser zähler in chan-struct)
+
+gethour() optimieren
+
+Mit Argo war heute nicht zu scherzen... 1 Opfer erfuhren dies auf die harte Art.
+Auch [smiley]'s Toleranz war in 0 Fällen erschöpft.
+
+TCL-Befehl um die stats von allen zu resetten.
+
+monats-reset verbessern.
+
+getstats idle
+
+17.1.2002 	schan_members_find() optimieren?
+
+23.4.2002
+> Something else I just noticed, Age  31 weeks 1 day 11 hours. But when I 
+> log into Edit my settings it shows Age: 1 day 10 hours 43 minutes.  I 
+> only set a statspass a day ago ?
+
+21.3.2002
+mal schauen, ob man den typ "minutes" nicht zu "time" umbenennen kann
+
+7.4.2002 - [20:10:56] QQ [iRC]: actions dont get logged
+

+ 16 - 16
wishlist.txt

@@ -1,16 +1,16 @@
-Now that you have Age on the webpage (I know its always been in the 
-userfile) you should add that quick little stat percentage ;)
-Age / Total Minutes gives the average of how often the user can be found 
-in the channel, Ive been doing it by script for awhile, but since you've 
-put Age in the livestats I figured I'd suggest it again :)
-
-Wenn Du ins stats.mod noch wie bei MircStats die verschiedenen Nicks der User anzeigen lassen könntest dann währe dein Stats.mod schon besser als MircStats.
-
-eggdrop userdatenbank komplett ignorierbar per option machen
-
-Suchmaschienen-Spider optional blockierbar machen.
-
-flag um user vorm löschen zu bewahren
-
-you should REALLY REALLY put a trigger to get channel peak... maybe you can 
-write a few lines to add to the tcl'z to add the trigger? plz!!! :)
+Now that you have Age on the webpage (I know its always been in the 
+userfile) you should add that quick little stat percentage ;)
+Age / Total Minutes gives the average of how often the user can be found 
+in the channel, Ive been doing it by script for awhile, but since you've 
+put Age in the livestats I figured I'd suggest it again :)
+
+Wenn Du ins stats.mod noch wie bei MircStats die verschiedenen Nicks der User anzeigen lassen könntest dann währe dein Stats.mod schon besser als MircStats.
+
+eggdrop userdatenbank komplett ignorierbar per option machen
+
+Suchmaschienen-Spider optional blockierbar machen. (robots.txt)
+
+flag um user vorm löschen zu bewahren
+
+you should REALLY REALLY put a trigger to get channel peak... maybe you can 
+write a few lines to add to the tcl'z to add the trigger? plz!!! :)