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 \
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
# 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
CFLAGS=-Wall -ggdb -Iinclude/
BIN=efserv
LEX=@LEX@
+MV=mv
+CPPC=gcc -E -C
BISON=@BISON@
MAINSO=efserv.so
prefix=@prefix@
config.c\
clients.c\
clones.c\
+ dyntfuncs.c\
database.c\
efserv.c\
log.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}
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
* 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>
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)
{
if (ch->exops == NULL)
return;
+ BestOps = NULL;
FORLIST(node, ch->exops, struct ChanopUser *, cou)
{
i = 0;
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...
*/
}
}
+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)
{
break;
}
}
- hack++;
break;
case 'e':
case 'I':
arg++;
- hack++;
}
#ifdef USE_AUTOJUPE
if (hack == 0)
* 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>
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[] =
{
{"JOIN", m_join},
{"WHOIS", m_whois},
{"ERROR", m_error},
+ {"KICK", m_kick},
{0, 0}
};
--- /dev/null
+/* $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*)*/
+
--- /dev/null
+/*
+ * 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));
+}
--- /dev/null
+/*
+ * 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];}
--- /dev/null
+/*
+ * 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);
+};
* 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
#define SERVLEN 80
#define CHANLEN 255
+#define HASHSIZE 0x1000
+
#endif
* 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 */
#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
--- /dev/null
+/*
+ * 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);
* 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;
};
* 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
struct HashEntry *next;
};
+extern struct HashEntry *hash[HASHSIZE];
+
struct List
{
struct List *next, *prev;
* 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)
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)
{
{
void (*do_main_loop)(void);
void (*do_setup)(void);
+ void (*translate_all)(void);
void *dt;
/* Force efence in... */
dt = malloc(1);
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)
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();
}
* 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>
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);
}
* 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>
#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)