]> jfr.im git - irc/ircd-hybrid/efserv-cvs.git/commitdiff
- Dynamic translation(dyntrans) code added. This means that we should be
authora1kmm <a1kmm>
Mon, 10 Dec 2001 07:04:45 +0000 (07:04 +0000)
committera1kmm <a1kmm>
Mon, 10 Dec 2001 07:04:45 +0000 (07:04 +0000)
  able to make major changes including adding or rearranging fields within
  structures without restarting efserv, only reloading.

16 files changed:
.depend
Makefile.in
channels.c
commands.c
dtheader.h [new file with mode: 0644]
dyntfuncs.c [new file with mode: 0644]
dyntrans.l [new file with mode: 0644]
dyntrans.y [new file with mode: 0644]
include/config.h
include/define.h
include/dyntrans.h [new file with mode: 0644]
include/struct.h
include/utils.h
modules.c
msg.c
utils.c

diff --git a/.depend b/.depend
index 944521c0c0bdf96364a82dffcf2909583de3e46c..16d4c82465aaf369f281d5ddb5e0471b7a4ef1d9 100644 (file)
--- a/.depend
+++ b/.depend
@@ -5,9 +5,11 @@ commands.o: commands.c include/config.h include/define.h \
 config.o: config.c include/config.h include/define.h include/struct.h \
  include/utils.h include/funcs.h
 clients.o: clients.c include/config.h include/define.h \
- include/struct.h include/utils.h include/funcs.h
+ include/struct.h include/utils.h include/funcs.h include/serno.h
 clones.o: clones.c include/config.h include/define.h include/struct.h \
  include/utils.h include/funcs.h
+dyntfuncs.o: dyntfuncs.c include/define.h include/config.h \
+ include/struct.h include/dyntrans.h include/utils.h
 database.o: database.c include/config.h include/define.h \
  include/struct.h include/utils.h include/funcs.h
 efserv.o: efserv.c include/config.h include/define.h include/struct.h \
@@ -21,3 +23,7 @@ utils.o: utils.c include/config.h include/define.h include/utils.h
 sconfig.tab.o: sconfig.tab.c include/config.h include/define.h \
  include/struct.h include/utils.h include/funcs.h include/conf.h
 lex.yy.o: lex.yy.c include/conf.h sconfig.tab.h
+dyntrans.setup.o: dyntrans.setup.c include/define.h include/dyntrans.h \
+ include/config.h include/utils.h include/struct.h include/funcs.h
+dyntrans.tab.o: dyntrans.tab.c include/conf.h include/config.h \
+ include/dyntrans.h include/utils.h
index 072d993f2f9e5ea0a9356f33d2f002658f767a11..8a668796695c3481e6a109d0b4ca4837d8eafc7f 100644 (file)
@@ -1,7 +1,7 @@
 # efserv Makefile.in
 # DO NOT EDIT
 #
-# $Id: Makefile.in,v 1.9 2001/12/03 02:25:50 wcampbel Exp $
+# $Id: Makefile.in,v 1.10 2001/12/10 07:04:45 a1kmm Exp $
 #
 
 # Don't edit these unless you know what you are doing
@@ -12,6 +12,8 @@ MKDIR=@MKDIR@
 CFLAGS=-Wall -ggdb -Iinclude/
 BIN=efserv
 LEX=@LEX@
+MV=mv
+CPPC=gcc -E -C
 BISON=@BISON@
 MAINSO=efserv.so
 prefix=@prefix@
@@ -25,6 +27,7 @@ SRCS=channels.c\
      config.c\
      clients.c\
      clones.c\
+     dyntfuncs.c\
      database.c\
      efserv.c\
      log.c\
@@ -33,7 +36,8 @@ SRCS=channels.c\
      msg.c\
      utils.c \
      sconfig.tab.c \
-     lex.yy.c
+     lex.yy.c \
+     dyntrans.setup.c
 
 # BSD _AND_ GNU Compliant OBJS definition
 OBJS=${SRCS:.c=.o}
@@ -55,14 +59,32 @@ sconfig.tab.c sconfig.tab.h: sconfig.y
 lex.yy.c: sconfig.l sconfig.tab.h
        ${LEX} sconfig.l
 
+dyntrans.setup.c: dyntrans dtheader.i
+       dyntrans <dtheader.i >dyntrans.setup.c
+
+dyntrans: dyntrans.ll.o dtransgen.o dyntrans.tab.o
+       ${CC} ${CFLAGS} dyntrans.ll.o dtransgen.o dyntrans.tab.o -lfl -o dyntrans
+
+dyntrans.ll.c: dyntrans.l dyntrans.tab.h
+       ${LEX} dyntrans.l
+       ${MV} lex.yy.c dyntrans.ll.c
+
+dyntrans.tab.c dyntrans.tab.h: dyntrans.y
+       ${BISON} --defines dyntrans.y
+
+dtheader.i: dtheader.h
+       ${CPPC} dtheader.h > dtheader.i
+
+dtheader.h: include/config.h include/define.h include/struct.h
+
 .c.o:
        ${CC} -c ${DPATH} ${CFLAGS} $<
 
 help.txt: help.txt.in makehelp.pl
        perl makehelp.pl
 
-depend: lex.yy.c sconfig.tab.c
-       ${CC} ${CFLAGS} -MM ${SRCS} >.depend
+depend: lex.yy.c sconfig.tab.c dyntrans.tab.c
+       ${CC} ${CFLAGS} -MM ${SRCS} dyntrans.tab.c >.depend
 
 clean:
        ${RM} -f *.o *.so core efserv.core efserv lex.yy.c
index 19fc2eb6cf81ff5220b790485247ab9294853eb8..06bc743b8fe091567c4b05c4ad29fad59c916052 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  *    MA  02111-1307  USA.
- * $Id: channels.c,v 1.13 2001/12/02 06:59:04 a1kmm Exp $
+ * $Id: channels.c,v 1.14 2001/12/10 07:04:45 a1kmm Exp $
  */
 #include <stdlib.h>
 #include <stdio.h>
@@ -77,6 +77,7 @@ check_channel_status(struct Channel *ch)
 
   if (server_count < minimum_servers)
     return;
+  BestOps = NULL;
   if ((timenow - ch->ts) > CHAN_RECOVER_TIME)
     ch->first_ts = ch->ts;
   else if (ch->ops != NULL && ch->ts > ch->first_ts && ch->exops != NULL)
@@ -132,6 +133,7 @@ check_channel_status(struct Channel *ch)
   {
     if (ch->exops == NULL)
       return;
+    BestOps = NULL;
     FORLIST(node, ch->exops, struct ChanopUser *, cou)
     {
       i = 0;
@@ -207,6 +209,52 @@ check_channel_status(struct Channel *ch)
       add_to_list(&ch->exops, cou);
     }
   }
+  if (ch->ops != NULL && ch->exops != NULL)
+  {
+    int unopped_exops=0, opped_exops=0;
+    char *md5;
+    BestOps = NULL;
+    FORLIST(node, ch->exops, struct ChanopUser *, cou)
+    {
+      i = 0;
+      FORLIST(node2, BestOps, struct ChanopUser *, cou2)
+        if (++i > 5 || cou2->slices <= cou->slices)
+          break;
+      if (i > 5 || (node2 == NULL && count >= 5))
+        continue;
+      add_to_list_before(&BestOps, node2, cou);
+      count++;
+    }
+    if (count > 5)
+      count = 5;
+    FORLIST(node, ch->ops, struct User*, usr)
+    {
+      i = 0;
+      if (usr->host)
+        md5 = getmd5(usr);
+      FORLIST(node2, BestOps, struct ChanopUser *, cou)
+        if (i++ < 5 && !memcmp(md5, cou->uhost_md5, 16))
+          opped_exops++;
+    }
+    FORLIST(node, ch->nonops, struct User*, usr)
+    {
+      if (usr->host)
+        md5 = getmd5(usr);
+      i = 0;
+      FORLIST(node2, BestOps, struct ChanopUser *, cou)
+      {
+        if (i++ < 5 && !memcmp(md5, cou->uhost_md5, 16))
+          unopped_exops++;
+      }
+    }
+    FORLISTDEL(node, nnode, BestOps, struct ChanopUser *, cou)
+      free(node);
+    if (unopped_exops > 3)
+    {
+      clearops_channel(ch);
+      check_channel_status(ch);
+    }
+  }
   /* Now we simply have to go through and delete the expired
    * ops... 
    */
@@ -459,6 +507,15 @@ m_part(char *sender, int parc, char **parv)
   }
 }
 
+void
+m_kick(char *sender, int parc, char **parv)
+{
+  /* :sender KICK #channel user :reason */
+  if (parc < 3)
+    return;
+  m_part(parv[2], parc, parv);
+}
+
 void
 m_join(char *sender, int parc, char **parv)
 {
@@ -594,12 +651,10 @@ m_chmode(char *sender, int parc, char **parv)
               break;
             }
         }
-        hack++;
         break;
       case 'e':
       case 'I':
         arg++;
-        hack++;
     }
 #ifdef USE_AUTOJUPE
   if (hack == 0)
index f4c9650d3f34b0932b1037dfcbc571857a673c94..9f36dba0c7034092d9dc19b7e3233aab08f0d9f7 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  *    MA  02111-1307  USA.
- * $Id: commands.c,v 1.10 2001/11/11 22:13:52 wcampbel Exp $
+ * $Id: commands.c,v 1.11 2001/12/10 07:04:45 a1kmm Exp $
  */
 
 #include <stdio.h>
@@ -45,6 +45,7 @@ void m_motd(char*, int, char**);
 void m_version(char*, int, char**);
 void m_whois(char*, int, char**);
 void m_error(char*, int, char**);
+void m_kick(char*, int, char **);
 
 struct Command Commands[] =
 {
@@ -64,6 +65,7 @@ struct Command Commands[] =
  {"JOIN", m_join},
  {"WHOIS", m_whois},
  {"ERROR", m_error},
+ {"KICK", m_kick},
  {0, 0}
 };
 
diff --git a/dtheader.h b/dtheader.h
new file mode 100644 (file)
index 0000000..7124c1d
--- /dev/null
@@ -0,0 +1,30 @@
+/* $Id: dtheader.h,v 1.1 2001/12/10 07:04:45 a1kmm Exp $ */
+/*PGINC("stdlib.h")*/
+/*PGINC("string.h")*/
+/*PINC("define.h")*/
+/*PINC("dyntrans.h")*/
+/*PINC("config.h")*/
+/*PINC("utils.h")*/
+/*PINC("struct.h")*/
+/*PINC("funcs.h")*/
+/*PNOTRANS*/
+#include <stdio.h>
+#include "include/config.h"
+#include "include/define.h"
+/*PYESTRANS*/
+#include "include/utils.h"
+#include "include/struct.h"
+
+/* Use PGLOBAL(name,type) to declare globals */
+/*PGLOBAL(hash,struct HashEntry *[HASHSIZE])*/
+/*PGLOBAL(HKeywords,struct List*)*/
+/*PGLOBAL(Channels,struct List*)*/
+/*PGLOBAL(serv_admins,struct List*)*/
+/*PGLOBAL(VoteServers,struct List*)*/
+/*PGLOBAL(Hubs,struct List*)*/
+/*PGLOBAL(JupeExempts,struct List*)*/
+/*PGLOBAL(Servers,struct List*)*/
+/*PGLOBAL(Users,struct List*)*/
+/*PGLOBAL(Monitors,struct List*)*/
+/*PGLOBAL(Hosts,struct List*)*/
+
diff --git a/dyntfuncs.c b/dyntfuncs.c
new file mode 100644 (file)
index 0000000..c067829
--- /dev/null
@@ -0,0 +1,453 @@
+/*
+ *  dyntfuncs.c: Dynamic translation routines
+ *  This is part of efserv, a services.int implementation.
+ *  efserv is Copyright(C) 2001 by Andrew Miller, and others.
+ *  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.
+ * $Id: dyntfuncs.c,v 1.1 2001/12/10 07:04:45 a1kmm Exp $
+ */
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <signal.h>
+#include "define.h"
+#include "config.h"
+#include "struct.h"
+#include "dyntrans.h"
+#include "utils.h"
+#include <assert.h>
+
+extern struct List *structtypes, *structinsts;
+extern unsigned long reloadno;
+struct List* addrhash[0x3FF];
+struct List *tptrs = NULL, *queueptrs = NULL, *simplemap = NULL;
+
+/* The generated setup function: */
+void setup_dyntrans(void);
+
+struct QueuedTranslation
+{
+#define AHT_QT ((void*)1)
+#define AHO_QTADDR (sizeof(int) + sizeof(struct List*))
+ void *type;
+ struct List *n;
+ void *address;
+ struct StructType *t;
+};
+
+struct TPtr
+{
+#define AHT_TPTR ((void*)2)
+#define AHO_TPOLD (sizeof(int)+sizeof(struct List*))
+ void *type;
+ struct List *n;
+ void *old;
+ void *new;
+};
+
+struct SimpleMap
+{
+ void *old;
+ void **saveto;
+};
+
+void*
+FindByAddress(void *a, void *type, int offset)
+{
+  void *d;
+  struct List *n;
+  FORLIST(n, addrhash[(((unsigned long)a)>>2) & 0x3FF], void*, d)
+    if ((*(void**)d) == type && *(void**)(((char*)d)+offset) == a)
+      return d;
+  return NULL;
+}
+
+void
+AddToAddressHash(void *a, void *type, int offset)
+{
+  struct List **h = addrhash +
+                (((*(unsigned long*)(((char*)a) + offset))>>2) & 0x3FF);
+  *(void**)a = type;
+  *(struct List**)(((char*)a)+sizeof(int)) = add_to_list(h, a);
+}
+
+void
+DeleteFromAddressHash(void *a, int offset)
+{
+  struct List *n, **h;
+  char *ad = (char*)a;
+  n = *(struct List**)(ad + sizeof(int));
+  h = addrhash + (((*(unsigned long*)(ad + offset))>>2) & 0x3FF);
+  remove_from_list(h, n);
+}
+
+void
+RegisterStructType(struct StructType *st)
+{
+  struct StructType *stt;
+  struct Field *f1, *f2;
+  struct List *n, *n2, *n3, *n4;
+  int ofc=0, mfc=0;
+  /* This is needed as the string may become unavailable later. */
+  st->name = strdup(st->name);
+  st->serno = reloadno;
+  FORLIST(n, st->fields, struct Field*, f1)
+  {
+    f1->old_offset = -1;
+    f1->old_nrepeats = -1;
+    ofc++;
+  }
+  FORLIST(n, structtypes, struct StructType*,stt)
+    if (!strcmp(stt->name, st->name))
+    {
+      st->olen = stt->len;
+      /* Time to set up the translation fields. */
+      n->data = st;
+      FORLIST(n2, st->fields, struct Field*, f1)
+        FORLISTDEL(n3, n4, stt->fields, struct Field*, f2)
+          if (!strcmp(f2->name, f1->name))
+          {
+            mfc++;
+            if (f1->new_offset != f2->new_offset)
+              st->flags |= SF_MODIFIED;
+            f1->old_nrepeats = f2->nrepeats;
+            f1->old_offset = f2->new_offset;
+            remove_from_list(&stt->fields, n3);
+            free(f2);
+          }
+      free(stt->name);
+      FORLISTDEL(n2, n3, stt->fields, struct Field*, f1)
+      {
+        free(n2);
+        free(f1->name);
+        free(f1);
+      }
+      free(stt);
+      if (mfc != ofc)
+        st->flags |= SF_MODIFIED;
+      return;
+    }
+  st->flags |= SF_NEW;
+  add_to_list(&structtypes, st);
+}
+
+struct StructType*
+FindStructType(const char *name)
+{
+  struct StructType *st;
+  struct List *n;
+  FORLIST(n, structtypes, struct StructType*, st)
+    if (!strcmp(st->name, name))
+      return st;
+  return NULL;
+}
+
+void
+SaveStructType(const char *name, struct StructType **to)
+{
+  struct StructType *st;
+  struct List *n;
+  struct SimpleMap *sm;
+  FORLIST(n, structtypes, struct StructType*, st)
+    if (!strcmp(st->name, name) && st->serno == reloadno)
+    {
+      *to = st;
+      return;
+    }
+  sm = malloc(sizeof(*sm));
+  sm->old = (void*)name;
+  sm->saveto = (void**)to;
+  add_to_list(&simplemap, sm);
+}
+
+void
+RegisterStructInst(const char *name, const char *type, int isptr,
+                   int nreps, void *data)
+{
+  struct List *n;
+  struct StructInst *si;
+  struct StructType *st;
+  FORLIST(n, structinsts, struct StructInst*, si)
+  {
+    if (strcmp(si->name, name))
+      continue;
+    /* Someone has probably renamed a structure, so we have to
+     * restart :( */
+    if (strcmp(si->typename, type))
+      restart();
+    if (si->isptr != isptr)
+      restart();
+    if (isptr)
+      *((void**)data) = *((void**)si->data);
+    si->data = data;
+    si->serno = reloadno;
+    return;
+  }
+  si = malloc(sizeof(*si));
+  si->name = strdup(name);
+  si->typename = strdup(type);
+  si->isptr = isptr ? 1 : 0;
+  si->data = data;
+  si->serno = reloadno;
+  si->nreps = nreps;
+  if ((st = FindStructType(type)) != NULL)
+    memset(data, 0, (isptr ? sizeof(void*) : st->len) * nreps);
+  add_to_list(&structinsts, si);
+}
+
+void
+QueueTranslate(void *address, struct StructType *t, void **ptrto)
+{
+  struct QueuedTranslation *qt;
+  struct TPtr *tp;
+  char c;
+  if (address == NULL)
+    return;
+  if (t == NULL)
+    restart();
+  /* Check it isn't already translated... */
+  if (ptrto != NULL)
+  {
+    if ((tp = (struct TPtr*)FindByAddress(address, AHT_TPTR, AHO_TPOLD)))
+    {
+      *ptrto = tp->new;
+      return;
+    }
+  }
+  /* If it isn't already queued for translation, queue it. */
+  if (FindByAddress(address, AHT_QT, AHO_QTADDR) == NULL)
+  {
+    char c;
+    qt = malloc(sizeof(*qt));
+    qt->address = address;
+    qt->t = t;
+    /* Do a test to catch bugs... */
+    c = *((char*)qt->address);
+    AddToAddressHash(qt, AHT_QT, AHO_QTADDR);
+    add_to_list(&queueptrs, qt);
+  }
+  else
+  {
+    c = ((char*)address)[0];
+    ((char*)address)[0] = c;
+  }
+  /* It doesn't matter if we schedule the same simple mapping
+   * twice.
+   */
+  if (ptrto != NULL)
+  {
+    struct SimpleMap *sm = malloc(sizeof(*sm));
+    sm->saveto = ptrto;
+    sm->old = address;
+    add_to_list(&simplemap, sm);
+  }
+}
+
+void
+Translate(struct QueuedTranslation *qt, void *addr)
+{
+  struct List *n;
+  struct Field *f;
+  struct TPtr *tp;
+  char *ns, *os = (char*)qt->address;
+  int ch = qt->t->flags & (SF_NEW|SF_MODIFIED);
+  if (ch && addr == NULL)
+    ns = (char *)malloc(qt->t->len);
+  else if (addr == NULL)
+    ns = (char*)qt->address;
+  else
+    ns = (char*)addr;
+  FORLIST(n, qt->t->fields, struct Field*, f)
+  {
+    if (ch && f->old_offset != -1)
+    {
+      memcpy(ns + f->new_offset, os + f->old_offset,
+             f->len * ((f->nrepeats > f->old_nrepeats)?
+               f->old_nrepeats : f->nrepeats));
+      if (f->nrepeats > f->old_nrepeats)
+        memset(ns + f->new_offset + f->old_nrepeats*f->len, 0,
+               f->len * (f->nrepeats - f->old_nrepeats));
+    }
+    else if (ch && f->init_func)
+    {
+      int i;
+      for (i=0; i<f->nrepeats; i++)
+        f->init_func(ns, ns + f->new_offset + f->len * i, f->len);
+    }
+    else if (ch && f->flags & SFF_NEEDRESTART)
+      restart();
+    else if (ch)
+      memset(ns + f->new_offset, 0, f->len);
+    /* Record the field's new address for later translations...
+     * We now always have to do this :( because otherwise we forget
+     * we have already tried to translate it.
+     * Note that when f->old_offset was 0, we could be using the same
+     * address for the start of the structure and the old first
+     * field, so we can't add it.
+     */
+    if (f->old_offset > 0 &&
+        FindByAddress(os + f->old_offset, AHT_TPTR, AHO_TPOLD) == NULL)
+    {
+      tp = malloc(sizeof(*tp));
+      tp->new = ns + f->new_offset;
+      tp->old = os + f->old_offset;
+      AddToAddressHash(tp, AHT_TPTR, AHO_TPOLD);
+      add_to_list(&tptrs, tp);
+    }
+    /* Okay, now having translated the field, see if it points to
+     * anything that needs translating itself... */
+    if (f->flags & SFF_ISPOLYPOINTER)
+      continue;
+    if (f->flags & SFF_ISPOINTER && f->type == FIELD_INTTYPE)
+    {
+      /* We do this just in case it is something like a char * into
+       * a structure.
+       */
+      struct SimpleMap *sm = malloc(sizeof(*sm));
+      sm->old = *(void**)(ns + f->new_offset);
+      sm->saveto = (void**)(ns + f->new_offset);
+      add_to_list(&simplemap, sm);
+      continue;
+    }
+    if (f->type != FIELD_STRUCT)
+      continue;
+    if (f->flags & SFF_ISPOINTER)
+    {
+      QueueTranslate(*(void**)(ns + f->new_offset), f->stype,
+                     (void**)(ns + f->new_offset));
+    }
+    else
+    {
+      struct QueuedTranslation qtn;
+      qtn.address = ns + f->new_offset;
+      qtn.t = f->stype;
+      Translate(&qtn, ns + f->new_offset);
+    }
+  }
+  if (FindByAddress(os, AHT_TPTR, AHO_TPOLD) == NULL)
+  {
+    tp = malloc(sizeof(*tp));
+    tp->new = ns;
+    tp->old = os;
+    AddToAddressHash(tp, AHT_TPTR, AHO_TPOLD);
+    add_to_list(&tptrs, tp);
+  }
+  if (ch && addr == NULL)
+    free(qt->address);
+}
+
+/* A kludge for the void* pointers in linked lists... */
+void
+TranslateList(struct List *l, const char *t)
+{
+  struct List *n;
+  void *p;
+  struct StructType *st = FindStructType(t);
+  if (st == NULL)
+    return;
+  FORLIST(n, l, void*, p)
+    QueueTranslate(p, st, &n->data);
+}
+
+void
+TranslateAll(void)
+{
+  struct List *n;
+  struct StructInst *si;
+  struct StructType *st;
+  struct QueuedTranslation *qt;
+  struct SimpleMap *sm;
+  struct TPtr *tp;
+  tptrs = NULL;
+  queueptrs = NULL;
+  simplemap = NULL;
+  /* Step 1: Setup all the types and globals... */
+  setup_dyntrans();
+  while (simplemap)
+  {
+    n = simplemap;
+    sm = n->data;
+    if ((st = FindStructType((char*)sm->old)))
+      *sm->saveto = st;
+    simplemap = simplemap->next;
+    free(n);
+    free(sm);
+  }
+  TranslateList(Channels, "Channel");
+  TranslateList(serv_admins, "ServAdmin");
+  TranslateList(VoteServers, "VoteServer");
+  TranslateList(Hubs, "Hub");
+  TranslateList(JupeExempts, "JExempt");
+  TranslateList(Servers, "Server");
+  TranslateList(Users, "User");
+  TranslateList(Hosts, "Host");
+  FORLIST(n, structinsts, struct StructInst*, si)
+  {
+    int i;
+    /* XXX - should we bother to free here? */
+    if (si->serno != reloadno)
+      continue;
+    if ((st = FindStructType(si->typename)) == NULL)
+    {
+      restart();
+      exit(0);
+    }
+    if (si->data == NULL ||
+        (si->isptr && si->nreps == 0 && *((void**)si->data) == NULL))
+      continue;
+    for (i=0; i<si->nreps; i++)
+    {
+      if (si->isptr)
+        QueueTranslate(((void**)si->data)[i], st, ((void**)si->data) + i);
+      else
+        QueueTranslate((void*)(((char*)si->data) + i*st->olen), st, NULL);
+    }
+  }
+  /* Okay, we have all those globals on the queue. Go through the
+   * queue, and translate structures, queueing new ones as we come
+   * to them... */
+  while(queueptrs)
+  {
+    n = queueptrs;
+    qt = (struct QueuedTranslation*)queueptrs->data;
+    Translate(qt, NULL);
+    DeleteFromAddressHash(qt, AHO_QTADDR);
+    free(qt);
+    remove_from_list(&queueptrs, n);
+  }
+  while(simplemap)
+  {
+    n = simplemap;
+    sm = (struct SimpleMap*)simplemap->data;
+    /* If no translation found, no translation is probably needed. */
+    if ((tp = (struct TPtr*)FindByAddress(sm->old, AHT_TPTR, AHO_TPOLD))
+         != NULL)
+    {
+      *sm->saveto = tp->new;
+    }
+    free(sm);
+    remove_from_list(&simplemap, n);
+  }
+  while(tptrs)
+  {
+    n = tptrs;
+    tptrs = tptrs->next;
+    free(((struct TPtr*)n->data)->n);
+    free(n->data);
+    free(n);
+  }
+  memset(addrhash, 0, sizeof(addrhash));
+}
diff --git a/dyntrans.l b/dyntrans.l
new file mode 100644 (file)
index 0000000..a701e4f
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ *  dyntrans.l: The header lexer for the dynamic translation system.
+ *  This is part of efserv, a services.int implementation.
+ *  efserv is Copyright(C) 2001 by Andrew Miller, and others.
+ *  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.
+ * $Id: dyntrans.l,v 1.1 2001/12/10 07:04:46 a1kmm Exp $
+ */
+
+%{
+#include "conf.h"
+#include "dyntrans.tab.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <string.h>
+#include <strings.h>
+#include <ctype.h>
+#define YY_NO_UNPUT
+extern char *yyexpr;
+%}
+
+%x COMMENT
+%x NOTRANS
+
+preprocess #.*
+name [a-z|A-Z|0-9_]+
+multiptr "*"+
+whitespace [ \t\r\n]
+%%
+{whitespace} ;
+{preprocess} ;
+unsigned ;
+signed ;
+const ;
+int {return T_INT;}
+char {return T_CHAR;}
+long {return T_LONG;}
+short {return T_SHORT;}
+struct {return T_STRUCT;}
+void {return T_VOID;}
+extern {return T_EXTERN;}
+enum {return T_ENUM;}
+"/*PNOTRANS*/" {BEGIN(NOTRANS);}
+<NOTRANS>"/*PYESTRANS*/" { BEGIN(INITIAL); }
+<NOTRANS>[^/]* ;
+<NOTRANS>"/"[^*] ;
+<NOTRANS>"/*"[^P] ;
+<NOTRANS>. {exit(-1);}
+"/*PNEEDINIT*/" {return T_NEEDINIT;}
+"/*PIFUNC(\""[^\"]*"\")*/" {
+ yylval.string = yytext+10;
+ *(strchr(yylval.string, ')')) = 0;
+ yylval.string = strdup(yylval.string);
+ return T_IFUNC;
+}
+"/*PINC(\""[^\"]*"\")*/" {
+  yylval.string = yytext+8;
+  *(strchr(yylval.string, '\"')) = 0;
+  yylval.string = strdup(yylval.string);
+  return T_INC;
+}
+"/*PGINC(\""[^\"]*"\")*/" {
+  yylval.string = yytext+9;
+  *(strchr(yylval.string, '\"')) = 0;
+  yylval.string = strdup(yylval.string);
+  return T_GINC;
+}
+"/*PGLOBAL(" { return T_GLOBAL; }
+")*/" { return T_UCEND; }
+
+"/*" {BEGIN(COMMENT);}
+<COMMENT>"*/" {BEGIN(INITIAL);}
+<COMMENT>"*"[^/] ;
+<COMMENT>[^*]* ;
+"["[^\]]*"]" {
+  yytext[yyleng-1] = 0;
+  if (yyexpr != NULL)
+    free(yyexpr);
+  yyexpr = strdup(yytext+1);
+  return T_EXPR;
+}
+{name} {
+  yylval.string = strdup(yytext);
+  yylval.string[yyleng] = 0;
+  return T_NAME;
+}
+. {return yytext[0];}
diff --git a/dyntrans.y b/dyntrans.y
new file mode 100644 (file)
index 0000000..931ca6b
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ *  dyntrans.y: The header parser for the dynamic translation system.
+ *  This is part of efserv, a services.int implementation.
+ *  efserv is Copyright(C) 2001 by Andrew Miller, and others.
+ *  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.
+ * $Id: dyntrans.y,v 1.1 2001/12/10 07:04:46 a1kmm Exp $
+ */
+%{
+  #include <stdlib.h>
+  #include <string.h>
+  #include <stdio.h>
+  #include <time.h>
+  #include "conf.h"
+  #include "config.h"
+  #include "dyntrans.h"
+  #include "utils.h"
+  int isptr;
+  char *yyexpr = NULL;
+  char *len = NULL, *type = NULL, *stype = NULL, *nrepeats = NULL,
+       *flags  = NULL, *sname;
+  extern int yyleng;
+  void yyerror(const char *e);
+  void start_function(void);
+  int yylex(void);
+%}
+%token T_NAME
+%token T_INT
+%token T_CHAR
+%token T_SHORT
+%token T_LONG
+%token T_STRUCT
+%token T_NEEDINIT
+%token T_IFUNC
+%token T_VOID
+%token T_EXTERN
+%token T_INC
+%token T_GINC
+%token T_EXPR
+%token T_GLOBAL
+%token T_UCEND
+%token T_ENUM
+%%
+
+ALL: ITEMS
+ITEMS: ITEM | ITEM ITEMS;
+ITEM: STRUCT | VDECLARE | AFPROTOTYPE | T_INC
+{
+ printf("#include \"%s\"\n", yylval.string);
+ free(yylval.string);
+} | T_GINC
+{
+ printf("#include <%s>\n", yylval.string);
+ free(yylval.string);
+} | AGLOBAL | ENUM;
+
+ENUM: T_ENUM '{' NAMELIST COMMAOK '}' ';'
+
+COMMAOK: /* empty */ | ',';
+
+STRUCTNAME: T_STRUCT T_NAME
+
+RTTYPE: STRUCTNAME '*'
+{
+  printf("\"%s\", 1, ", yylval.string);
+  free(yylval.string);
+} | STRUCTNAME
+{
+  printf("\"%s\", 0, ", yylval.string);
+  free(yylval.string);
+};
+
+ARTTYPE: RTTYPE T_EXPR
+{
+  /* ampersand isn't needed for an array. */
+  printf("%s, %s);\n", yyexpr, len);
+  free(yyexpr);
+  free(len);
+  len = NULL;
+} | RTTYPE
+{
+  printf("1, &%s);\n", len);
+  free(len);
+  len = NULL;
+};
+
+AGLOBAL: T_GLOBAL T_NAME
+{
+  if (len == NULL)
+    free(len);
+  len = yylval.string;
+  printf("  RegisterStructInst(\"%s\", ", yylval.string);
+} ',' ARTTYPE T_UCEND;
+
+STRUCTTYPE: T_STRUCT T_NAME {free(yylval.string);};
+SIMPLETYPE: T_INT | T_CHAR | T_SHORT | T_LONG | STRUCTTYPE | T_NAME;
+ANYPTR: '*' | ANYPTR '*';
+ANYORNOPTR: /* empty */ | ANYPTR;
+ANYTYPE: SIMPLETYPE ANYORNOPTR | T_VOID ANYORNOPTR;
+ARG: ANYTYPE T_NAME PARRAY {free(yylval.string);};
+ARGLIST: ARG | ARGLIST ',' ARG;
+PARGLIST: ARGLIST | T_VOID;
+PARRAY: /* empty */ | T_EXPR;
+FPROTOTYPE: ANYTYPE T_NAME PARRAY {free(yylval.string);} '(' PARGLIST ')' ';';
+AFPROTOTYPE: T_EXTERN FPROTOTYPE | FPROTOTYPE;
+NAMELIST: NAMELIST ',' NAME | NAME;
+NAME: ANYORNOPTR T_NAME PARRAY{free(yylval.string);}
+VDECLARE: T_EXTERN SIMPLETYPE NAMELIST';';
+STRUCT: T_STRUCT T_NAME
+{
+ start_function();
+ printf("  /* Begin struct %s */\n", yylval.string);
+ printf("  s = (struct StructType*)malloc(sizeof(struct StructType));\n"
+        "  s->name = strdup(\"%s\");\n"
+        "  s->len = 0;\n"
+        "  s->flags = 0;\n"
+        "  s->fields = NULL;\n", yylval.string);
+ if (stype)
+   free(stype);
+ stype = strdup("f->stype = NULL");
+ if (len)
+   free(len);
+ len = NULL;
+ if (nrepeats != NULL)
+   free(nrepeats);
+ nrepeats = NULL;
+ if (flags != NULL)
+   free(flags);
+ flags = strdup("0");
+ isptr = 0;
+ sname = yylval.string;
+} '{' SARGLIST '}'
+{
+ printf("  RegisterStructType(s);\n");
+ free(sname);
+}';';
+SARGLIST: SARG SARGLIST | SARG;
+SARG: SSARG SFLAGS ';' | SSARG ';';
+SFLAGS: SFLAGS SFLAG | SFLAG;
+SFLAG: T_IFUNC
+{
+ printf("  f->func = &%s\n", yylval.string);
+ free(yylval.string);
+} | T_NEEDINIT
+{
+ printf("  f->flags |= SFF_NEEDRESTART;\n");
+ free(yylval.string);
+};
+SSARRAY: /* empty */ |
+         T_EXPR
+{
+  nrepeats = yyexpr;
+  yyexpr = NULL;
+}
+
+SSARG: SSTYPE SSTNAMES
+{
+  if (stype)
+    free(stype);
+  stype = strdup("f->stype = NULL");
+  if (len != NULL)
+    free(len);
+  len = NULL;
+  if (type)
+    free(type);
+  type = NULL;
+  if (flags)
+    free(flags);
+  flags = strdup("0");
+}
+
+SSTNAMES: SSTANAME | SSTNAMES ',' SSTANAME;
+
+SSTANAME: SSTNAME
+{
+  printf("  f = (struct Field*)malloc(sizeof(struct Field));\n"
+         "  f->type = %s;\n"
+         "  %s;\n"
+         "  f->len = %s;\n"
+         "  f->name = strdup(\"%s\");\n"
+         "  f->flags = %s;\n"
+         "  f->nrepeats = %s;\n"
+         "  {\n"
+         "    struct %s tmpv;\n"
+         "    f->new_offset = ((unsigned long)&tmpv.%s) - (unsigned long)&tmpv;\n"
+         "  }\n"
+         "  if (f->new_offset + f->len > s->len)\n"
+         "    s->len = f->new_offset + f->len;\n"
+         "  add_to_list(&s->fields, f);\n", type, stype, len,
+         yylval.string, flags, nrepeats ? nrepeats : "1",
+         sname, yylval.string);
+  if (nrepeats)
+    free(nrepeats);
+  nrepeats = NULL;
+  isptr = 0;
+  free(yylval.string);
+}
+
+SSTNAME: SSPTR T_NAME SSARRAY | T_NAME SSARRAY |
+SSTYPE '(' SSPTR T_NAME
+{
+#if 1
+  fprintf(stderr, "Encountered a function pointer field! Dying.\n");
+  exit(-1);
+#else
+  printf("  f->name = \"%s\";\n"
+         "  f->type = FIELD_FUNCPTR;\n");
+  free(yylval.string);
+#endif
+} ')''(' PARGLIST ')';
+SSTYPE: SSPTR STYPE | STYPE;
+SSPTR: '*'
+{
+ char *oflags = flags;
+ isptr = 1;
+ flags = malloc(strlen(flags) + sizeof("| SFF_ISPOINTER"));
+ strcpy(flags, oflags);
+ strcat(flags, "| SFF_ISPOINTER");
+ if (len != NULL)
+   free(len);
+ len = strdup("sizeof(void*)");
+} | SSPTR '*'
+{
+ char *oflags = flags;
+ if (isptr < 2)
+ {
+   flags = malloc(strlen(flags) + sizeof("| SFF_ISPOLYPOINTER"));
+   strcpy(flags, oflags);
+   strcat(flags, "| SFF_ISPOLYPOINTER");
+ }
+ isptr++;
+};
+STYPE: T_INT
+{
+ type = strdup("FIELD_INTTYPE");
+ len = strdup("sizeof(int)");
+} | T_CHAR
+{
+ type = strdup("FIELD_INTTYPE");
+ len = strdup("sizeof(char)");
+} | T_LONG
+{
+ type = strdup("FIELD_INTTYPE");
+ len = strdup("sizeof(long)");
+} | T_VOID
+{
+ /* This is an error unless it is a pointer... */
+ type = strdup("FIELD_INTTYPE");
+ len = strdup("sizeof(void*)");
+} | T_STRUCT T_NAME
+{
+ type = strdup("FIELD_STRUCT");
+ if (stype)
+   free(stype);
+ stype = (char*)malloc(strlen(yylval.string) +
+                       sizeof("SaveStructType(\"\", &f->stype)"));
+ sprintf(stype, "SaveStructType(\"%s\", &f->stype)", yylval.string);
+ len = malloc(sizeof("sizeof()") + strlen(yylval.string));
+ sprintf(len, "sizeof(%s)", yylval.string);
+ free(yylval.string);
+} | T_NAME
+{
+ /* We don't use typedefs for structs in efserv, so if we don't
+  * recognise the type, assume it is an integer type of some form.
+  */
+ type = strdup("FIELD_INTTYPE");
+ len = malloc(sizeof("sizeof()") + strlen(yylval.string));
+ sprintf(len, "sizeof(%s)", yylval.string);
+ free(yylval.string);
+};
index e7ebe4fe3f3b51990d6d8da0910a40f5d9a0f119..19e9e3c9c44e33c79730a247e91a43324f4d532b 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  *    MA  02111-1307  USA.
- * $Id: config.h,v 1.3 2001/11/12 04:11:56 wcampbel Exp $
+ * $Id: config.h,v 1.4 2001/12/10 07:04:50 a1kmm Exp $
  */
 
 #ifndef CONFIG_H
@@ -61,4 +61,6 @@
 #define SERVLEN 80
 #define CHANLEN 255
 
+#define HASHSIZE 0x1000
+
 #endif
index d4b6cca0f6345bb6a0f2bb0b02398513b35e609b..5a192c3c2969f37db746d2ace3a98cff79e149d8 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  *    MA  02111-1307  USA.
- * $Id: define.h,v 1.10 2001/12/02 06:59:06 a1kmm Exp $
+ * $Id: define.h,v 1.11 2001/12/10 07:04:50 a1kmm Exp $
  */
 
 /* The maximum number of clients per user@host */
@@ -39,7 +39,7 @@
 
 #define JUPE_EXPIRE_TIME 45 *60
 #define MINIMUM_OPS  0 /* 4 */
-#define EXOP_EXPIRE_TIME 2*60 /* *60 */
+#define EXOP_EXPIRE_TIME 2*60 *60
 #define CHAN_SLICE_LENGTH 5
 #define CYCLE_REJOIN_TIME 30
 #define CHAN_RECOVER_TIME 10*60
diff --git a/include/dyntrans.h b/include/dyntrans.h
new file mode 100644 (file)
index 0000000..a4376cb
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *  dyntrans.h: Dynamic translation includes
+ *  This is part of efserv, a services.int implementation.
+ *  efserv is Copyright(C) 2001 by Andrew Miller, and others.
+ *  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.
+ * $Id: dyntrans.h,v 1.1 2001/12/10 07:04:50 a1kmm Exp $
+ */
+
+struct StructType
+{
+ unsigned long serno;
+ char *name;
+ int len, flags;
+ struct List *node, *fields;
+ /* Old length needed for array translation: */
+ int olen;
+};
+
+struct Field
+{
+ char *name;
+ int type, len, flags;
+ struct StructType *stype;
+ int nrepeats, old_nrepeats;
+ /* Is passed the struct, the field and the length. */
+ void (*init_func)(void*, void*, int);
+ /* Below this is only filled for translations... */
+ int old_offset, new_offset; /* old_offset = -1 if new. */
+};
+
+struct StructInst
+{
+ char *name, *typename;
+ int isptr, nreps;
+ void *data;
+ unsigned long serno;
+};
+
+enum
+{
+ FIELD_INTTYPE,
+ FIELD_STRUCT,
+ FIELD_FUNCPTR /* Not implemented yet */
+};
+
+#define SFF_ISPOINTER 1
+#define SFF_POINTEDTO 2
+#define SFF_ISPOLYPOINTER 4 /* These are harder to handle. */
+#define SFF_NEEDRESTART 8 /* Must restart if this didn't exist before. */
+
+#define SF_MODIFIED 1
+#define SF_NEW 2
+
+void restart(void);
+void RegisterStructType(struct StructType *st);
+struct StructType *FindStructType(const char *name);
+void SaveStructType(const char *name, struct StructType **to);
+void RegisterStructInst(const char *name, const char *type, int isptr,
+                        int nrep, void *data);
index fc8f90d92705714606f31b0560529848c4d7ebaf..2cd47913dfa104b07d14dbca182aa79778ce3095 100644 (file)
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  *    MA  02111-1307  USA.
- * $Id: struct.h,v 1.6 2001/12/02 06:59:06 a1kmm Exp $
+ * $Id: struct.h,v 1.7 2001/12/10 07:04:50 a1kmm Exp $
  */
 #include "define.h"
 
+/*  We don't need to translate this, as we reinstall the commands on reload. */
+/*PNOTRANS*/
 struct Command
 {
  char *name;
  void (*func)(char *sender, int argc, char **parv);
 };
+/*PYESTRANS*/
 
 struct User
 {
  struct Server *server;
  char nick[NICKLEN], user[USERLEN], host[HOSTLEN];
  unsigned long flags, caps;
+ time_t last_op_subtract;
  struct ServAdmin *sa;
  struct List *node, *monnode;
 };
index fd3a2854266ef1c768424f6150c15f1adc75139c..863eebe9ddd7e4134d4374b84d23d1bf5ae5b609 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  *    MA  02111-1307  USA.
- * $Id: utils.h,v 1.1 2001/05/31 08:52:08 a1kmm Exp $
+ * $Id: utils.h,v 1.2 2001/12/10 07:04:50 a1kmm Exp $
  */
 
 enum
@@ -36,6 +36,8 @@ struct HashEntry
  struct HashEntry *next;
 };
 
+extern struct HashEntry *hash[HASHSIZE];
+
 struct List
 {
  struct List *next, *prev;
index dfdf7bdc9540bcf4fe71c3e3c87dc5ce0389ceda..95b6f40c79e058f937fdb7898e80800a811c5aa7 100644 (file)
--- a/modules.c
+++ b/modules.c
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  *    MA  02111-1307  USA.
- * $Id: modules.c,v 1.6 2001/07/30 06:51:04 a1kmm Exp $
+ * $Id: modules.c,v 1.7 2001/12/10 07:04:46 a1kmm Exp $
  */
 
 #define PATH PREFIX
+#include "config.h"
 #include <dlfcn.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <signal.h>
 #include <time.h>
+#include <unistd.h>
 
 int reload_module=0, die=0;
-int connected = 0;
-
-struct List *Servers = NULL, *Users = NULL, *Channels = NULL,
-            *Hosts = NULL, *Monitors = NULL, *VoteServers = NULL,
-            *Hubs = NULL, *HKeywords = NULL, *JupeExempts = NULL;
-FILE *logfile = NULL;
-struct Server *first_server = NULL;
+int connected = 0, server_count = 0, minimum_servers = 0;
+time_t channel_record_time = 0;
 void *mmod;
-int server_fd, server_count=0, minimum_servers=0;
-#define HASHSIZE 0x1000
-struct HashEntry *hash[0x1000];
+int server_fd = -1;
 char *server_name=NULL, *server_pass=NULL, *server_host=NULL;
-/* Interface nick... */
 char *sn = NULL;
 int port;
-struct List *serv_admins=NULL;
-time_t channel_record_time = 0;
+FILE *logfile;
+
+/* After all that, these globals do need to be here. */
+struct List *HKeywords, *Channels, *serv_admins, *VoteServers, *Hubs,
+            *JupeExempts, *Servers, *Users, *Monitors, *Hosts;
+struct Server *first_server;
+struct HashEntry *hash[HASHSIZE];
+
+
+
+/* This is here because it has to be. */
+struct List *structtypes = NULL, *structinsts = NULL;
+unsigned long reloadno = 0;
 
 void
 handle_sighup(int n)
@@ -55,6 +60,19 @@ handle_sighup(int n)
  do_rehash();
 }
 
+/* This is the severe measure of actually quitting IRC(!) and restarting
+ * services. */
+void
+restart(void)
+{
+  fprintf(stderr, "Restarting...\n");
+  if (fork() == 0)
+  {
+    execl(PREFIX "/efserv", "");
+  }
+  exit(0);
+}
+
 void
 handle_sigusr1(int n)
 {
@@ -66,6 +84,7 @@ main(int argc, char **argv)
 {
  void (*do_main_loop)(void);
  void (*do_setup)(void);
+ void (*translate_all)(void);
  void *dt;
  /* Force efence in... */
  dt = malloc(1);
@@ -78,8 +97,7 @@ main(int argc, char **argv)
   exit(-1);
  }
  do_setup = (void (*)(void))dlsym(mmod, "do_setup");
- do_main_loop = (void (*)(void))dlsym(mmod, "do_main_loop");
- do_setup();
+ reload_module = 1;
  while (die == 0)
  {
   if (reload_module)
@@ -91,7 +109,12 @@ main(int argc, char **argv)
     exit(-1);
    }
    do_main_loop = (void (*)(void))dlsym(mmod, "do_main_loop");
+   translate_all = (void(*)(void))dlsym(mmod, "TranslateAll");
    reload_module = 0;
+   reloadno++;
+   translate_all();
+   if (reloadno == 1)
+     do_setup();
   }
   do_main_loop();
  }
diff --git a/msg.c b/msg.c
index b7c2b631bb5fed9e83a73fe423902a88624c3ff1..80e952522e2c84a4f3705e1266ef70669efa1e29 100644 (file)
--- a/msg.c
+++ b/msg.c
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  *    MA  02111-1307  USA.
- * $Id: msg.c,v 1.11 2001/11/12 00:43:12 wcampbel Exp $
+ * $Id: msg.c,v 1.12 2001/12/10 07:04:46 a1kmm Exp $
  */
 #include <stdlib.h>
 #include <stdio.h>
@@ -600,16 +600,16 @@ m_privmsg(char *sender, int parc, char **parv)
  for (i=0; OpCommands[i].name; i++)
   if (!strcasecmp(OpCommands[i].name, cmd))
   {
-   if ((OpCommands[i].alevel == ALEVEL_ADMIN && !IsAdmin(usr)) ||
-       (OpCommands[i].alevel == ALEVEL_OPER && !IsOper(usr)) ||
-       (OpCommands[i].alevel == ALEVEL_SERVADMIN && !IsServAdmin(usr))
-       )
-   {
-    send_msg(":%s NOTICE %s :Permission denied.", sn, usr->nick);
-    return;
-   }
-   OpCommands[i].func(usr, msg);
-   return;
+    if ((OpCommands[i].alevel == ALEVEL_ADMIN && !IsAdmin(usr)) ||
+         (OpCommands[i].alevel == ALEVEL_OPER && !IsOper(usr)) ||
+         (OpCommands[i].alevel == ALEVEL_SERVADMIN && !IsServAdmin(usr))
+        )
+     {
+       send_msg(":%s NOTICE %s :Permission denied.", sn, usr->nick);
+       return;
+     }
+     OpCommands[i].func(usr, msg);
+     return;
   }
- send_msg(":%s NOTICE %s :No such command.", sn, sender);  
 send_msg(":%s NOTICE %s :No such command.", sn, sender);  
 }
diff --git a/utils.c b/utils.c
index 4fc1837fd74b09477a4d884ac359a209e7093708..b37529f5753a383775bf2a56d9afbd4fe9a37d18 100644 (file)
--- a/utils.c
+++ b/utils.c
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  *    MA  02111-1307  USA.
- * $Id: utils.c,v 1.8 2001/11/11 22:13:52 wcampbel Exp $
+ * $Id: utils.c,v 1.9 2001/12/10 07:04:46 a1kmm Exp $
  */
 
 #include <ctype.h>
@@ -27,9 +27,7 @@
 #include "define.h"
 #include "utils.h"
 
-#define HASHSIZE 0x1000
-
-extern struct HashEntry *hash[0x1000];
+extern struct HashEntry *hash[HASHSIZE];
 
 unsigned long
 hash_text(const char *txt)