Browse Source

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 years ago
parent
commit
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:
 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:
 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
 The following instructions assume, ~/eggdrop1.6/ is the directory
 where you installed your eggdrop from. (of course, other source dirs
 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
 so if you removed your original compile directory, you'll have to
 compile the whole bot again... sorry.
 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
 back to ~/eggdrop1.6/. Type 'make config' (on eggdrop 1.4, you can skip
 that part) Type 'make', wait until compiling
 that part) Type 'make', wait until compiling
 is done and use 'make install' to install the bot and stats.mod.
 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
 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/),
 I suggest to copy it to your eggdrop directory (probably ~/eggdrop/),
@@ -44,42 +47,54 @@ restart or rehash.
 Public commands:
 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]
 !stat [user]
   shows the statistics for the user
   shows the statistics for the user
+
 !place [user/ordering]
 !place [user/ordering]
   shows on which place the user is
   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:
 Only available if log-wordstats is turned on:
 !wordstats [user]
 !wordstats [user]
   lists the most used words of the user
   lists the most used words of the user
 !topwords
 !topwords
   lists the most used words in the channel
   lists the most used words in the channel
-!top10 word <word>
+!top word <word>
   lists the top10 people who used <word>
   lists the top10 people who used <word>
 
 
+
+
+
 Msg commands:
 Msg commands:
 -------------
 -------------
 
 
 All public commands are also accessible via /msg.
 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:
 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]
 .+suser <user> [host]
   adds a new user to the database
   adds a new user to the database
 .-suser <user>
 .-suser <user>
@@ -105,10 +120,9 @@ DCC commands:
 .resetuser <user> <channel>
 .resetuser <user> <channel>
   sets all statistics of user in channel to 0
   sets all statistics of user in channel to 0
   (m|-)
   (m|-)
+.swhois
+  displays a stats-account
 
 
-.writewebstats
-  writes the old, static webfiles
-  (m|-)
 
 
 TCL commands:
 TCL commands:
 -------------
 -------------
@@ -132,15 +146,29 @@ resetslang
   removes every language from the memory, so you can cleanly load a new
   removes every language from the memory, so you can cleanly load a new
   set of languages.
   set of languages.
 
 
-loadslang [lang] <langfile>
+loadstatslang [lang] <langfile>
   loads a language
   loads a language
 
 
+loadstatsskin <skin-file>
+  loads a skin for livestats
+
 setchanslang <channel> <language>
 setchanslang <channel> <language>
   sets the language in <channel> to <language>
   sets the language in <channel> to <language>
 
 
 nick2suser <nick> <channel>
 nick2suser <nick> <channel>
   returns the username of <nick> in <chan>
   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:
 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
 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
 channel and user list which makes it easier for your users to browse through
 the several channel statistics of your bot.
 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
   Use .console +1 to see access, or use the setting stats-loglevel to
 change the loglevel.
 change the loglevel.
   Stats.mod is now also able to log the access to a CLF logfile, so you can
   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,
 Hint: If you don't want a channel to be listed on the index,
 ----  just set it +secret.
 ----  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:
 User management:
 ----------------
 ----------------
@@ -186,12 +207,16 @@ completely.
 new hosts to a user manually. The affected user should cycle the chan to make
 new hosts to a user manually. The affected user should cycle the chan to make
 sure that he's recognized correctly by stats.mod.
 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
 - 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)
   probably want to set all your bot -list)
 - If a user is -addhosts, no new hostmasks will be added to him/her. You'll
 - 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
   have to add all hosts manually with .+shost. (useful if someone if trying
   to fake you)
   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:
 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
 work properly, but if anything gets screwed up, I'm not responsible. Use
 this module at your own risk.
 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:
 Homepage:
 ---------
 ---------
 
 

+ 2 - 0
UPDATES

@@ -14,6 +14,8 @@ Changes in Stats.mod: (since v1.0.1)
 - added filter for stupid color-codes
 - added filter for stupid color-codes
 - new way of expireing users
 - new way of expireing users
 - new command: !lastspoke
 - new command: !lastspoke
+- new users get greeted
+- added tcl command [suserlist]
 
 
 
 
 1.3.2
 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.
 # Generated automatically from Makefile.in by configure.
 # Makefile for src/compat/
 # 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
 SHELL = /bin/sh
 top_srcdir = ../..
 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
 #endif
   int lev, content_length;
   int lev, content_length;
   struct timeval t;
   struct timeval t;
-  double pre_time;
+  double pre_time, post_time;
 
 
   debug2("%s: %s", dcc[idx].host, buf);
   debug2("%s: %s", dcc[idx].host, buf);
 
 
@@ -388,9 +388,12 @@ static void http_activity(int idx, char *buf, int len)
       debug0("now sending...");
       debug0("now sending...");
       gettimeofday(&t, NULL);
       gettimeofday(&t, NULL);
       pre_time = (float) t.tv_sec + (((float) t.tv_usec) / 1000000);
       pre_time = (float) t.tv_sec + (((float) t.tv_usec) / 1000000);
+      debug1("pre-time: %.3f", pre_time);
       process_get_request(idx);
       process_get_request(idx);
       gettimeofday(&t, NULL);
       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;
       dcc[idx].status = 1;
 #ifndef OLDBOT
 #ifndef OLDBOT
       /* If there's no data in our socket, we immediately get rid of it.
       /* 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);
            m->nick, chan->chan, m->user->user);
     return;
     return;
   }
   }
+  if (!m->uhost)
+  	return;
+  if (strchr(m->uhost, '*') ||  strchr(m->uhost, '?'))
+  	return;
   u = findsuser_by_name(m->nick);
   u = findsuser_by_name(m->nick);
   host = nmalloc(strlen(m->uhost) + strlen(m->nick) + 2);
   host = nmalloc(strlen(m->uhost) + strlen(m->nick) + 2);
   sprintf(host, "%s!%s", m->nick, m->uhost);
   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;
   char *text;
 
 
   reset_global_vars();
   reset_global_vars();
+  if (!greet_new_users)
+  	return;
   glob_user = u;
   glob_user = u;
   glob_nick = nick;
   glob_nick = nick;
   glob_slang = slang_find(coreslangs, slang_chanlang_get(chanlangs, chan));
   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
 static int expire_factor = 25;	/* percent value which defines how much of
 				   a user's "age" he can stay away without
 				   a user's "age" he can stay away without
 				   being expired */
 				   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 MAKING_STATS
 #define MODULE_NAME "stats"
 #define MODULE_NAME "stats"
-#define MODULE_VERSION "1.4.0 dev20"
+#define MODULE_VERSION "1.4.0 dev21"
 #ifndef NO_EGG
 #ifndef NO_EGG
 #include "../module.h"
 #include "../module.h"
 #include "../irc.mod/irc.h"
 #include "../irc.mod/irc.h"
@@ -112,176 +112,6 @@ static int stats_expmem()
 	return 0;
 	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 */
 /* a report on the module status */
 static void stats_report(int idx, int details)
 static void stats_report(int idx, int details)
 {
 {
@@ -365,6 +195,7 @@ static tcl_ints my_tcl_ints[] =
   {"min-lines", &min_lines, 0},
   {"min-lines", &min_lines, 0},
   {"expire-base", &expire_base, 0},
   {"expire-base", &expire_base, 0},
   {"expire-factor", &expire_factor, 0},
   {"expire-factor", &expire_factor, 0},
+  {"greet-new-users", &greet_new_users, 0},
   {0, 0, 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)
 #     him/herself, he/she must cycle the chan to be recognized. (lowest CPU usage)
 set autoadd 5
 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
 # 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?)
 # autoadded (you don't want "dead" users in your database, do you?)
 set autoadd-min-lines 5
 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
 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
 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)
 # log wordstats (most used words) (this stats are resetted daily)
 # NOTE: This is very cpu- and memory consuming, so don't
 # 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;
 	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[] =
 static tcl_cmds mytcls[] =
 {
 {
   {"incrstats", tcl_incrstats},
   {"incrstats", tcl_incrstats},
@@ -247,5 +275,7 @@ static tcl_cmds mytcls[] =
   {"loadstatslang", tcl_loadstatslang},
   {"loadstatslang", tcl_loadstatslang},
   {"schattr", tcl_schattr},
   {"schattr", tcl_schattr},
   {"activeusers", tcl_activeusers},
   {"activeusers", tcl_activeusers},
+  {"suserlist", tcl_suserlist},
+  {"delsuser", tcl_delsuser},
   {0, 0}
   {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
 1000 User Login
 1010 Username
 1010 Username
 1020 Password
 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!
 1200 Login Error!
 1210 Your attempt to login resulted in the following error:
 1210 Your attempt to login resulted in the following error:

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

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