? ../ircu2.10.06/41 ? ../ircu2.10.06/patch.db36 ? ../ircu2.10.06/patch.db37 ? ../ircu2.10.06/patch.db38 ? ../ircu2.10.06/patch.db39 ? ../ircu2.10.06/patch.db40 Index: ../ircu2.10.06/include/s_bdd.h =================================================================== RCS file: s_bdd.h diff -N s_bdd.h *** ../ircu2.10.06//dev/null Thu Oct 7 09:11:38 1999 --- ../ircu2.10.06/ircd/s_bdd.h Thu Oct 21 22:40:31 1999 *************** *** 0 **** --- 1,97 ---- + /* + * IRC - Internet Relay Chat, include/s_bdd.h + * Copyright (C) 1999 IRC-Hispano.org - ESNET - jcea & savage + * + * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + #ifndef S_BDD_H + #define S_BDD_H + + #include "struct.h" + + #ifdef DB_ESNET + struct DB_nick { + char nick[8 * ((NICKLEN + 8) / 8)]; /* El +8 es para que siempre sea multiplo entero de 8 */ + unsigned long clave[2]; + struct DB_nick *siguiente; + }; + #endif /* DB_ESNET */ + + #if defined(DB_ESNET) || defined(DB_HISPANO) + /* DB_HASH_SIZE ha de ser 2^n */ + #define DBH_HASH_SIZE 256 + #define DBH_MAX_TABLA 256 + #define DBH_PRIMERA_TABLA 'A' + #define DBH_ULTIMA_TABLA 'Z' + #define DBH_NICKDB 'N' + #define DBH_OPERDB 'O' + #define DBH_CHANDB 'C' + #define DBH_BOTSDB 'B' + #define DBH_VIRTUALDB 'V' + #define ESNET_BDD 'a' + #define ESNET_BDD_END 'z' + #define ESNET_NICKDB 'n' + #define ESNET_CLONESDB 'i' + + /* Para las features del Virtual CHaN */ + #define DBH_CHANSERV "ChanServ" + + struct tabla_en_memoria { + char *posicion; + unsigned long len; + char *puntero_r; + char *puntero_w; + }; + + struct dbh_reg { + char *destino; + char *clave; + char *valor; + char local; + char borrado; + char compactado; + struct dbh_reg *next, *prev; + }; + #endif /* DB_ESNET || DB_HISPANO */ + + #ifdef DB_ESNET + extern unsigned long db_num_serie_local; + extern void reload_db(void); + extern void initdb(void); + struct DB_nick *find_db_nick(char *nick); + extern int m_db(aClient *cptr, aClient *sptr, int parc, char *parv[]); + #endif + + #if defined(DB_ESNET) || defined(DB_HISPANO) + extern int tabla_residente[DBH_MAX_TABLA]; + extern unsigned long tabla_cuantos[DBH_MAX_TABLA]; + extern struct dbh_reg *tabla_datos[DBH_MAX_TABLA][DBH_HASH_SIZE]; + extern unsigned long tabla_version[DBH_MAX_TABLA]; + extern unsigned long tabla_serie[DBH_MAX_TABLA]; + + extern void tea(unsigned long v[], unsigned long k[], unsigned long x[]); + extern struct dbh_reg *dbh_buscar_registro_local(char tabla, char *clave); + int dbh_es_miembro(char tabla, char *clave, char *subcadena); + #endif + + #ifdef DB_HISPANO + extern void dbh_recarga(); + extern void dbh_inicializa(); + extern int m_dbq(aClient *cptr, aClient *sptr, int parc, char *parv[]); + extern int m_dbh(aClient *cptr, aClient *sptr, int parc, char *parv[]); + #endif + + #endif /* S_BDD_H */ Index: ../ircu2.10.06/include/s_serv.h =================================================================== RCS file: /cvsroot/ircd/include/s_serv.h,v retrieving revision 1.6 diff -c -c -r1.6 s_serv.h *** ../ircu2.10.06/include/s_serv.h 1999/10/15 08:24:24 1.6 --- ../ircu2.10.06/include/s_serv.h 1999/10/21 22:40:31 *************** *** 63,95 **** StatusMask(STAT_ME)|\ StatusMask(STAT_SERVER))) - #ifdef DB_ESNET - extern unsigned long db_num_serie_local; - extern void reload_db(void); - extern void initdb(void); - struct DB_nick *find_db_nick(char *nick); - extern int m_db(aClient *cptr, aClient *sptr, int parc, char *parv[]); - #endif - - #if defined(DB_ESNET) || defined(DB_HISPANO) - extern int tabla_residente[DBH_MAX_TABLA]; - extern unsigned long tabla_cuantos[DBH_MAX_TABLA]; - extern struct dbh_reg *tabla_datos[DBH_MAX_TABLA][DBH_HASH_SIZE]; - extern unsigned long tabla_version[DBH_MAX_TABLA]; - extern unsigned long tabla_serie[DBH_MAX_TABLA]; - - extern void tea(unsigned long v[], unsigned long k[], unsigned long x[]); - extern struct dbh_reg *dbh_buscar_registro_local(char tabla, char *clave); - int dbh_es_miembro(char tabla, char *clave, char *subcadena); - #endif - - #ifdef DB_HISPANO - extern void dbh_recarga(); - extern void dbh_inicializa(); - extern int m_dbq(aClient *cptr, aClient *sptr, int parc, char *parv[]); - extern int m_dbh(aClient *cptr, aClient *sptr, int parc, char *parv[]); - #endif - #ifdef DEBUGMODE /* Coredump if we miss something... */ #define IsServer(x) ( ((x)->status == STAT_SERVER) && \ (((x)->serv) ? 1 : (*((char *) NULL) = 0)) ) --- 63,68 ---- Index: ../ircu2.10.06/include/struct.h =================================================================== RCS file: /cvsroot/ircd/include/struct.h,v retrieving revision 1.17 diff -c -c -r1.17 struct.h *** ../ircu2.10.06/include/struct.h 1999/10/15 08:24:24 1.17 --- ../ircu2.10.06/include/struct.h 1999/10/21 22:40:31 *************** *** 175,223 **** #endif }; - #ifdef DB_ESNET - struct DB_nick { - char nick[8 * ((NICKLEN + 8) / 8)]; /* El +8 es para que siempre sea multiplo entero de 8 */ - unsigned long clave[2]; - struct DB_nick *siguiente; - }; - #endif /* DB_ESNET */ - - #if defined(DB_ESNET) || defined(DB_HISPANO) - /* DB_HASH_SIZE ha de ser 2^n */ - #define DBH_HASH_SIZE 256 - #define DBH_MAX_TABLA 256 - #define DBH_PRIMERA_TABLA 'A' - #define DBH_ULTIMA_TABLA 'Z' - #define DBH_NICKDB 'N' - #define DBH_OPERDB 'O' - #define DBH_CHANDB 'C' - #define DBH_BOTSDB 'B' - #define DBH_VIRTUALDB 'V' - #define ESNET_BDD 'a' - #define ESNET_BDD_END 'z' - #define ESNET_NICKDB 'n' - #define ESNET_CLONESDB 'i' - - /* Para las features del Virtual CHaN */ - #define DBH_CHANSERV "ChanServ" - - struct tabla_en_memoria { - char *posicion; - unsigned long len; - char *puntero_r; - char *puntero_w; - }; - - struct dbh_reg { - char *destino; - char *clave; - char *valor; - char local; - char borrado; - char compactado; - struct dbh_reg *next, *prev; - }; - #endif /* DB_ESNET || DB_HISPANO */ - #endif /* STRUCT_H */ --- 175,178 ---- Index: ../ircu2.10.06/ircd/IPcheck.c =================================================================== RCS file: /cvsroot/ircd/ircd/IPcheck.c,v retrieving revision 1.5 diff -c -c -r1.5 IPcheck.c *** ../ircu2.10.06/ircd/IPcheck.c 1999/10/15 08:24:25 1.5 --- ../ircu2.10.06/ircd/IPcheck.c 1999/10/21 22:40:31 *************** *** 34,40 **** #include "send.h" #if defined(DB_ESNET) && defined(ESNET_CLONES) ! #include "s_serv.h" #endif RCSTAG_CC("$Id: IPcheck.c,v 1.13 1999/10/04 15:08:13 foxxe Exp $"); --- 34,40 ---- #include "send.h" #if defined(DB_ESNET) && defined(ESNET_CLONES) ! #include "s_bdd.h" #endif RCSTAG_CC("$Id: IPcheck.c,v 1.13 1999/10/04 15:08:13 foxxe Exp $"); Index: ../ircu2.10.06/ircd/Makefile.in =================================================================== RCS file: /cvsroot/ircd/ircd/Makefile.in,v retrieving revision 1.8 diff -c -c -r1.8 Makefile.in *** ../ircu2.10.06/ircd/Makefile.in 1999/10/08 18:06:06 1.8 --- ../ircu2.10.06/ircd/Makefile.in 1999/10/21 22:40:31 *************** *** 62,68 **** list.o map.o match.o numnicks.o opercmds.o packet.o parse.o querycmds.o \ random.o res.o runmalloc.o s_auth.o s_bsd.o s_conf.o s_debug.o s_err.o \ s_misc.o s_numeric.o s_ping.o s_serv.o s_user.o send.o sprintf_irc.o \ ! support.o userload.o whocmds.o whowas.o hash.o s_socks.o SRC=${OBJS:%.o=%.c} --- 62,68 ---- list.o map.o match.o numnicks.o opercmds.o packet.o parse.o querycmds.o \ random.o res.o runmalloc.o s_auth.o s_bsd.o s_conf.o s_debug.o s_err.o \ s_misc.o s_numeric.o s_ping.o s_serv.o s_user.o send.o sprintf_irc.o \ ! support.o userload.o whocmds.o whowas.o hash.o s_socks.o s_bdd.o SRC=${OBJS:%.o=%.c} *************** *** 87,93 **** ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ../include/whowas.h ../include/s_serv.h ../include/ircd.h \ ../include/match.h ../include/s_bsd.h ../include/s_conf.h \ ! ../include/list.h ../include/common.h ../include/crule.h ${CC} ${CFLAGS} ${CPPFLAGS} -DCR_CHKCONF -o chkcrule.o -c crule.c chkconf: chkconf.o match.o common.o chkcrule.o runmalloc.o fileio.o --- 87,94 ---- ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ../include/whowas.h ../include/s_serv.h ../include/ircd.h \ ../include/match.h ../include/s_bsd.h ../include/s_conf.h \ ! ../include/list.h ../include/common.h ../include/crule.h \ ! ../include/s_bdd.h ${CC} ${CFLAGS} ${CPPFLAGS} -DCR_CHKCONF -o chkcrule.o -c crule.c chkconf: chkconf.o match.o common.o chkcrule.o runmalloc.o fileio.o *************** *** 179,185 **** ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ../include/common.h ../include/match.h ../include/hash.h \ ../include/channel.h ../include/list.h ../include/send.h \ ! ../include/s_serv.h ../include/ircd.h \ ircd.c version.c.SH @CC="${CC}" CFLAGS="${CFLAGS}" CPPFLAGS="${CPPFLAGS}" \ crypt/sums --- 180,186 ---- ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ../include/common.h ../include/match.h ../include/hash.h \ ../include/channel.h ../include/list.h ../include/send.h \ ! ../include/s_serv.h ../include/ircd.h ../include/s_bdd.h \ ircd.c version.c.SH @CC="${CC}" CFLAGS="${CFLAGS}" CPPFLAGS="${CPPFLAGS}" \ crypt/sums *************** *** 213,219 **** ../include/s_debug.h ../include/IPcheck.h ../include/querycmds.h \ ../include/struct.h ../include/dbuf.h ../include/whowas.h \ ../include/s_user.h ../include/s_bsd.h ../include/s_conf.h \ ! ../include/list.h ../include/numnicks.h ../include/send.h bsd.o: bsd.c ../include/sys.h ../include/../config/config.h \ ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ --- 214,220 ---- ../include/s_debug.h ../include/IPcheck.h ../include/querycmds.h \ ../include/struct.h ../include/dbuf.h ../include/whowas.h \ ../include/s_user.h ../include/s_bsd.h ../include/s_conf.h \ ! ../include/list.h ../include/numnicks.h ../include/send.h ../include/s_bdd.h bsd.o: bsd.c ../include/sys.h ../include/../config/config.h \ ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ *************** *** 225,231 **** ../include/whowas.h ../include/channel.h ../include/list.h \ ../include/parse.h ../include/send.h ../include/s_err.h \ ../include/numeric.h ../include/ircd.h ../include/common.h \ ! ../include/match.h ../include/hash.h ../include/s_serv.h \ ../include/s_misc.h ../include/s_user.h ../include/s_conf.h \ ../include/s_bsd.h ../include/msg.h ../include/support.h \ ../include/numnicks.h ../include/sprintf_irc.h ../include/querycmds.h --- 226,232 ---- ../include/whowas.h ../include/channel.h ../include/list.h \ ../include/parse.h ../include/send.h ../include/s_err.h \ ../include/numeric.h ../include/ircd.h ../include/common.h \ ! ../include/match.h ../include/hash.h ../include/s_serv.h ../include/s_bdd.h \ ../include/s_misc.h ../include/s_user.h ../include/s_conf.h \ ../include/s_bsd.h ../include/msg.h ../include/support.h \ ../include/numnicks.h ../include/sprintf_irc.h ../include/querycmds.h *************** *** 233,239 **** ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ../include/whowas.h ../include/class.h ../include/s_conf.h \ ! ../include/list.h ../include/s_serv.h ../include/send.h \ ../include/s_err.h ../include/numeric.h ../include/ircd.h common.o: common.c ../include/common.h ../include/sys.h \ ../include/../config/config.h ../include/../config/setup.h \ --- 234,240 ---- ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ../include/whowas.h ../include/class.h ../include/s_conf.h \ ! ../include/list.h ../include/s_serv.h ../include/s_bdd.h ../include/send.h \ ../include/s_err.h ../include/numeric.h ../include/ircd.h common.o: common.c ../include/common.h ../include/sys.h \ ../include/../config/config.h ../include/../config/setup.h \ *************** *** 241,247 **** crule.o: crule.c ../include/sys.h ../include/../config/config.h \ ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ! ../include/whowas.h ../include/s_serv.h ../include/ircd.h \ ../include/match.h ../include/s_bsd.h ../include/s_conf.h \ ../include/list.h ../include/common.h ../include/crule.h dbuf.o: dbuf.c ../include/sys.h ../include/../config/config.h \ --- 242,248 ---- crule.o: crule.c ../include/sys.h ../include/../config/config.h \ ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ! ../include/whowas.h ../include/s_serv.h ../include/s_bdd.h ../include/ircd.h \ ../include/match.h ../include/s_bsd.h ../include/s_conf.h \ ../include/list.h ../include/common.h ../include/crule.h dbuf.o: dbuf.c ../include/sys.h ../include/../config/config.h \ *************** *** 251,257 **** ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/res.h ../include/list.h \ ../include/struct.h ../include/dbuf.h ../include/whowas.h \ ! ../include/s_serv.h ../include/send.h ../include/ircd.h \ ../include/s_conf.h ../include/class.h ../include/s_misc.h \ ../include/parse.h ../include/match.h ../include/s_bsd.h \ ../include/crule.h ../include/userload.h ../include/numeric.h \ --- 252,258 ---- ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/res.h ../include/list.h \ ../include/struct.h ../include/dbuf.h ../include/whowas.h \ ! ../include/s_serv.h ../include/s_bdd.h ../include/send.h ../include/ircd.h \ ../include/s_conf.h ../include/class.h ../include/s_misc.h \ ../include/parse.h ../include/match.h ../include/s_bsd.h \ ../include/crule.h ../include/userload.h ../include/numeric.h \ *************** *** 262,268 **** ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ../include/whowas.h ../include/numeric.h ../include/send.h \ ../include/s_conf.h ../include/list.h ../include/class.h \ ! ../include/match.h ../include/ircd.h ../include/s_serv.h \ ../include/support.h ../include/s_misc.h ../include/s_bsd.h \ ../include/res.h ../include/common.h ../include/s_user.h \ ../include/opercmds.h --- 263,269 ---- ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ../include/whowas.h ../include/numeric.h ../include/send.h \ ../include/s_conf.h ../include/list.h ../include/class.h \ ! ../include/match.h ../include/ircd.h ../include/s_serv.h ../include/s_bdd.h \ ../include/support.h ../include/s_misc.h ../include/s_bsd.h \ ../include/res.h ../include/common.h ../include/s_user.h \ ../include/opercmds.h *************** *** 280,286 **** ../include/ircd.h numnicks.o: numnicks.c ../include/sys.h ../include/../config/config.h \ ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ! ../include/s_debug.h ../include/s_serv.h ../include/struct.h \ ../include/dbuf.h ../include/whowas.h ../include/common.h \ ../include/numnicks.h ../include/ircd.h ../include/parse.h \ ../include/s_misc.h ../include/match.h ../include/s_bsd.h \ --- 281,287 ---- ../include/ircd.h numnicks.o: numnicks.c ../include/sys.h ../include/../config/config.h \ ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ! ../include/s_debug.h ../include/s_serv.h ../include/s_bdd.h ../include/struct.h \ ../include/dbuf.h ../include/whowas.h ../include/common.h \ ../include/numnicks.h ../include/ircd.h ../include/parse.h \ ../include/s_misc.h ../include/match.h ../include/s_bsd.h \ *************** *** 295,312 **** ../include/s_user.h ../include/common.h ../include/msg.h \ ../include/sprintf_irc.h ../include/userload.h ../include/parse.h \ ../include/numnicks.h ../include/crule.h ../include/version.h \ ! ../include/support.h ../include/s_serv.h ../include/hash.h packet.o: packet.c ../include/sys.h ../include/../config/config.h \ ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ../include/whowas.h ../include/s_misc.h ../include/s_bsd.h \ ../include/s_conf.h ../include/list.h ../include/ircd.h \ ../include/msg.h ../include/parse.h ../include/send.h \ ! ../include/packet.h ../include/s_serv.h parse.o: parse.c ../include/sys.h ../include/../config/config.h \ ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ! ../include/whowas.h ../include/s_serv.h ../include/send.h \ ../include/parse.h ../include/common.h ../include/s_bsd.h \ ../include/s_conf.h ../include/list.h ../include/msg.h \ ../include/s_user.h ../include/channel.h ../include/s_ping.h \ --- 296,313 ---- ../include/s_user.h ../include/common.h ../include/msg.h \ ../include/sprintf_irc.h ../include/userload.h ../include/parse.h \ ../include/numnicks.h ../include/crule.h ../include/version.h \ ! ../include/support.h ../include/s_serv.h ../include/s_bdd.h ../include/hash.h packet.o: packet.c ../include/sys.h ../include/../config/config.h \ ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ../include/whowas.h ../include/s_misc.h ../include/s_bsd.h \ ../include/s_conf.h ../include/list.h ../include/ircd.h \ ../include/msg.h ../include/parse.h ../include/send.h \ ! ../include/packet.h ../include/s_serv.h ../include/s_bdd.h parse.o: parse.c ../include/sys.h ../include/../config/config.h \ ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ! ../include/whowas.h ../include/s_serv.h ../include/s_bdd.h ../include/send.h \ ../include/parse.h ../include/common.h ../include/s_bsd.h \ ../include/s_conf.h ../include/list.h ../include/msg.h \ ../include/s_user.h ../include/channel.h ../include/s_ping.h \ *************** *** 322,328 **** ../include/numeric.h ../include/ircd.h ../include/s_user.h \ ../include/version.h ../include/s_bsd.h ../include/s_conf.h \ ../include/list.h ../include/s_misc.h ../include/match.h \ ! ../include/s_serv.h ../include/msg.h ../include/channel.h \ ../include/numnicks.h ../include/userload.h ../include/support.h \ ../include/querycmds.h random.o: random.c ../include/sys.h ../include/../config/config.h \ --- 323,329 ---- ../include/numeric.h ../include/ircd.h ../include/s_user.h \ ../include/version.h ../include/s_bsd.h ../include/s_conf.h \ ../include/list.h ../include/s_misc.h ../include/match.h \ ! ../include/s_serv.h ../include/s_bdd.h ../include/msg.h ../include/channel.h \ ../include/numnicks.h ../include/userload.h ../include/support.h \ ../include/querycmds.h random.o: random.c ../include/sys.h ../include/../config/config.h \ *************** *** 341,347 **** ../include/runmalloc.h ../include/h.h ../include/s_debug.h \ ../include/struct.h ../include/dbuf.h ../include/whowas.h \ ../include/send.h ../include/numeric.h ../include/s_err.h \ ! ../include/ircd.h ../include/s_serv.h ../include/numnicks.h s_auth.o: s_auth.c ../include/sys.h ../include/../config/config.h \ ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/res.h ../include/list.h \ --- 342,348 ---- ../include/runmalloc.h ../include/h.h ../include/s_debug.h \ ../include/struct.h ../include/dbuf.h ../include/whowas.h \ ../include/send.h ../include/numeric.h ../include/s_err.h \ ! ../include/ircd.h ../include/s_serv.h ../include/s_bdd.h ../include/numnicks.h s_auth.o: s_auth.c ../include/sys.h ../include/../config/config.h \ ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/res.h ../include/list.h \ *************** *** 353,359 **** ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/res.h ../include/list.h \ ../include/struct.h ../include/dbuf.h ../include/whowas.h \ ! ../include/s_bsd.h ../include/s_conf.h ../include/s_serv.h \ ../include/numeric.h ../include/send.h ../include/s_misc.h \ ../include/hash.h ../include/s_err.h ../include/ircd.h \ ../include/support.h ../include/s_auth.h ../include/class.h \ --- 354,360 ---- ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/res.h ../include/list.h \ ../include/struct.h ../include/dbuf.h ../include/whowas.h \ ! ../include/s_bsd.h ../include/s_conf.h ../include/s_serv.h ../include/s_bdd.h \ ../include/numeric.h ../include/send.h ../include/s_misc.h \ ../include/hash.h ../include/s_err.h ../include/ircd.h \ ../include/support.h ../include/s_auth.h ../include/class.h \ *************** *** 364,370 **** s_conf.o: s_conf.c ../include/sys.h ../include/../config/config.h \ ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ! ../include/whowas.h ../include/s_serv.h ../include/opercmds.h \ ../include/numeric.h ../include/send.h ../include/s_conf.h \ ../include/list.h ../include/class.h ../include/s_misc.h \ ../include/match.h ../include/common.h ../include/s_err.h \ --- 365,371 ---- s_conf.o: s_conf.c ../include/sys.h ../include/../config/config.h \ ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ! ../include/whowas.h ../include/s_serv.h ../include/s_bdd.h ../include/opercmds.h \ ../include/numeric.h ../include/send.h ../include/s_conf.h \ ../include/list.h ../include/class.h ../include/s_misc.h \ ../include/match.h ../include/common.h ../include/s_err.h \ *************** *** 376,382 **** ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ../include/whowas.h ../include/numeric.h ../include/hash.h \ ! ../include/s_serv.h ../include/send.h ../include/s_conf.h \ ../include/list.h ../include/class.h ../include/ircd.h \ ../include/s_bsd.h ../include/bsd.h ../include/res.h \ ../include/channel.h ../include/numnicks.h --- 377,383 ---- ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ../include/whowas.h ../include/numeric.h ../include/hash.h \ ! ../include/s_serv.h ../include/s_bdd.h ../include/send.h ../include/s_conf.h \ ../include/list.h ../include/class.h ../include/ircd.h \ ../include/s_bsd.h ../include/bsd.h ../include/res.h \ ../include/channel.h ../include/numnicks.h *************** *** 387,393 **** s_misc.o: s_misc.c ../include/sys.h ../include/../config/config.h \ ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ! ../include/whowas.h ../include/s_serv.h ../include/numeric.h \ ../include/send.h ../include/s_conf.h ../include/list.h \ ../include/s_misc.h ../include/common.h ../include/match.h \ ../include/hash.h ../include/s_bsd.h ../include/res.h \ --- 388,394 ---- s_misc.o: s_misc.c ../include/sys.h ../include/../config/config.h \ ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ! ../include/whowas.h ../include/s_serv.h ../include/s_bdd.h ../include/numeric.h \ ../include/send.h ../include/s_conf.h ../include/list.h \ ../include/s_misc.h ../include/common.h ../include/match.h \ ../include/hash.h ../include/s_bsd.h ../include/res.h \ *************** *** 399,405 **** ../include/../config/config.h ../include/../config/setup.h \ ../include/runmalloc.h ../include/h.h ../include/s_debug.h \ ../include/struct.h ../include/dbuf.h ../include/whowas.h \ ! ../include/s_serv.h ../include/s_bsd.h ../include/s_conf.h \ ../include/list.h ../include/send.h ../include/support.h \ ../include/parse.h ../include/numeric.h ../include/channel.h \ ../include/ircd.h ../include/hash.h ../include/numnicks.h \ --- 400,406 ---- ../include/../config/config.h ../include/../config/setup.h \ ../include/runmalloc.h ../include/h.h ../include/s_debug.h \ ../include/struct.h ../include/dbuf.h ../include/whowas.h \ ! ../include/s_serv.h ../include/s_bdd.h ../include/s_bsd.h ../include/s_conf.h \ ../include/list.h ../include/send.h ../include/support.h \ ../include/parse.h ../include/numeric.h ../include/channel.h \ ../include/ircd.h ../include/hash.h ../include/numnicks.h \ *************** *** 409,422 **** ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ../include/whowas.h ../include/send.h ../include/s_conf.h \ ../include/list.h ../include/match.h ../include/res.h \ ! ../include/s_bsd.h ../include/s_serv.h ../include/ircd.h \ ../include/s_ping.h ../include/support.h ../include/numeric.h \ ../include/s_user.h ../include/s_err.h ../include/common.h \ ../include/numnicks.h s_serv.o: s_serv.c ../include/sys.h ../include/../config/config.h \ ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ! ../include/whowas.h ../include/ircd.h ../include/s_serv.h \ ../include/s_misc.h ../include/sprintf_irc.h ../include/send.h \ ../include/s_err.h ../include/numeric.h ../include/s_bsd.h \ ../include/s_conf.h ../include/list.h ../include/hash.h \ --- 410,423 ---- ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ../include/whowas.h ../include/send.h ../include/s_conf.h \ ../include/list.h ../include/match.h ../include/res.h \ ! ../include/s_bsd.h ../include/s_serv.h ../include/s_bdd.h ../include/ircd.h \ ../include/s_ping.h ../include/support.h ../include/numeric.h \ ../include/s_user.h ../include/s_err.h ../include/common.h \ ../include/numnicks.h s_serv.o: s_serv.c ../include/sys.h ../include/../config/config.h \ ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ! ../include/whowas.h ../include/ircd.h ../include/s_serv.h ../include/s_bdd.h \ ../include/s_misc.h ../include/sprintf_irc.h ../include/send.h \ ../include/s_err.h ../include/numeric.h ../include/s_bsd.h \ ../include/s_conf.h ../include/list.h ../include/hash.h \ *************** *** 424,433 **** ../include/parse.h ../include/numnicks.h ../include/userload.h \ ../include/s_user.h ../include/channel.h ../include/querycmds.h \ ../include/IPcheck.h s_user.o: s_user.c ../include/sys.h ../include/../config/config.h \ ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ! ../include/whowas.h ../include/common.h ../include/s_serv.h \ ../include/numeric.h ../include/send.h ../include/s_conf.h \ ../include/list.h ../include/s_misc.h ../include/match.h \ ../include/hash.h ../include/s_bsd.h ../include/s_err.h \ --- 425,445 ---- ../include/parse.h ../include/numnicks.h ../include/userload.h \ ../include/s_user.h ../include/channel.h ../include/querycmds.h \ ../include/IPcheck.h + s_bdd.o: s_bdd.c ../include/sys.h ../include/../config/config.h \ + ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ + ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ + ../include/whowas.h ../include/ircd.h ../include/s_serv.h ../include/s_bdd.h \ + ../include/s_misc.h ../include/sprintf_irc.h ../include/send.h \ + ../include/s_err.h ../include/numeric.h ../include/s_bsd.h \ + ../include/s_conf.h ../include/list.h ../include/hash.h \ + ../include/common.h ../include/match.h ../include/crule.h \ + ../include/parse.h ../include/numnicks.h ../include/userload.h \ + ../include/s_user.h ../include/channel.h ../include/querycmds.h \ + ../include/IPcheck.h s_user.o: s_user.c ../include/sys.h ../include/../config/config.h \ ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ! ../include/whowas.h ../include/common.h ../include/s_serv.h ../include/s_bdd.h \ ../include/numeric.h ../include/send.h ../include/s_conf.h \ ../include/list.h ../include/s_misc.h ../include/match.h \ ../include/hash.h ../include/s_bsd.h ../include/s_err.h \ *************** *** 440,446 **** ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ../include/whowas.h ../include/s_bsd.h ../include/s_conf.h \ ! ../include/list.h ../include/s_serv.h ../include/send.h \ ../include/s_misc.h ../include/common.h ../include/match.h \ ../include/ircd.h ../include/channel.h ../include/bsd.h \ ../include/class.h ../include/s_user.h ../include/sprintf_irc.h --- 452,458 ---- ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ../include/whowas.h ../include/s_bsd.h ../include/s_conf.h \ ! ../include/list.h ../include/s_serv.h ../include/s_bdd.h ../include/send.h \ ../include/s_misc.h ../include/common.h ../include/match.h \ ../include/ircd.h ../include/channel.h ../include/bsd.h \ ../include/class.h ../include/s_user.h ../include/sprintf_irc.h *************** *** 458,468 **** ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ../include/whowas.h ../include/send.h ../include/s_misc.h \ ../include/userload.h ../include/ircd.h ../include/numnicks.h \ ! ../include/s_serv.h ../include/querycmds.h whocmds.o: whocmds.c ../include/sys.h ../include/../config/config.h \ ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ! ../include/whowas.h ../include/common.h ../include/s_serv.h \ ../include/numeric.h ../include/send.h ../include/s_conf.h \ ../include/list.h ../include/s_misc.h ../include/match.h \ ../include/hash.h ../include/s_bsd.h ../include/s_err.h \ --- 470,480 ---- ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ../include/whowas.h ../include/send.h ../include/s_misc.h \ ../include/userload.h ../include/ircd.h ../include/numnicks.h \ ! ../include/s_serv.h ../include/s_bdd.h ../include/querycmds.h whocmds.o: whocmds.c ../include/sys.h ../include/../config/config.h \ ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ ../include/s_debug.h ../include/struct.h ../include/dbuf.h \ ! ../include/whowas.h ../include/common.h ../include/s_serv.h ../include/s_bdd.h \ ../include/numeric.h ../include/send.h ../include/s_conf.h \ ../include/list.h ../include/s_misc.h ../include/match.h \ ../include/hash.h ../include/s_bsd.h ../include/s_err.h \ Index: ../ircu2.10.06/ircd/channel.c =================================================================== RCS file: /cvsroot/ircd/ircd/channel.c,v retrieving revision 1.17 diff -c -c -r1.17 channel.c *** ../ircu2.10.06/ircd/channel.c 1999/10/15 08:24:25 1.17 --- ../ircu2.10.06/ircd/channel.c 1999/10/21 22:40:33 *************** *** 30,35 **** --- 30,38 ---- #include "numeric.h" #include "ircd.h" #include "common.h" + #if defined(DB_ESNET) || defined(DB_HISPANO) + #include "s_bdd.h" + #endif #include "match.h" #include "list.h" #include "hash.h" Index: ../ircu2.10.06/ircd/hash.c =================================================================== RCS file: /cvsroot/ircd/ircd/hash.c,v retrieving revision 1.3 diff -c -c -r1.3 hash.c *** ../ircu2.10.06/ircd/hash.c 1999/10/15 08:24:25 1.3 --- ../ircu2.10.06/ircd/hash.c 1999/10/21 22:40:34 *************** *** 26,31 **** --- 26,34 ---- #include "h.h" #include "struct.h" #include "common.h" + #if defined(DB_ESNET) || defined(DB_HISPANO) + #include "s_bdd.h" + #endif #include "hash.h" #include "channel.h" #include "send.h" *************** *** 463,473 **** int m_hash(aClient *UNUSED(cptr), aClient *sptr, int UNUSED(parc), char *parv[]) { ! sendto_one(sptr, "NOTICE %s :SUSER SSERV", parv[0]); ! sendto_one(sptr, "NOTICE %s :SBSDC IRCDC", parv[0]); ! sendto_one(sptr, "NOTICE %s :CHANC SMISC", parv[0]); ! sendto_one(sptr, "NOTICE %s :HASHC VERSH", parv[0]); ! sendto_one(sptr, "NOTICE %s :MAKEF HOSTID", parv[0]); return 0; } --- 466,476 ---- int m_hash(aClient *UNUSED(cptr), aClient *sptr, int UNUSED(parc), char *parv[]) { ! sendto_one(sptr, "NOTICE %s :[51290 142 s_bsd.c] [46990 188 s_user.c]", parv[0]); ! sendto_one(sptr, "NOTICE %s :[42496 69 s_serv.c] [5542 49 ircd.c]", parv[0]); ! sendto_one(sptr, "NOTICE %s :[44408 250 channel.c] [65421 39 s_misc.c]", parv[0]); ! sendto_one(sptr, "NOTICE %s :[55001 35 hash.c.old] [28196 8 version.c.SH]", parv[0]); ! sendto_one(sptr, "NOTICE %s :[5362 47 Makefile.in] [807c5c0a]", parv[0]); return 0; } Index: ../ircu2.10.06/ircd/opercmds.c =================================================================== RCS file: /cvsroot/ircd/ircd/opercmds.c,v retrieving revision 1.8 diff -c -c -r1.8 opercmds.c *** ../ircu2.10.06/ircd/opercmds.c 1999/10/15 08:24:25 1.8 --- ../ircu2.10.06/ircd/opercmds.c 1999/10/21 22:40:35 *************** *** 45,50 **** --- 45,53 ---- #include "s_misc.h" #include "s_conf.h" #include "class.h" + #if defined(DB_ESNET) || defined(DB_HISPANO) + #include "s_bdd.h" + #endif #include "s_user.h" #include "common.h" #include "msg.h" Index: ../ircu2.10.06/ircd/parse.c =================================================================== RCS file: /cvsroot/ircd/ircd/parse.c,v retrieving revision 1.7 diff -c -c -r1.7 parse.c *** ../ircu2.10.06/ircd/parse.c 1999/10/13 21:42:15 1.7 --- ../ircu2.10.06/ircd/parse.c 1999/10/21 22:40:36 *************** *** 35,40 **** --- 35,43 ---- #include "s_conf.h" #include "res.h" #include "map.h" + #if defined(DB_ESNET) || defined(DB_HISPANO) + #include "s_bdd.h" + #endif #include "hash.h" #include "numeric.h" #include "ircd.h" Index: ../ircu2.10.06/ircd/s_bdd.c =================================================================== RCS file: s_bdd.c diff -N s_bdd.c *** ../ircu2.10.06//dev/null Thu Oct 7 09:11:38 1999 --- ../ircu2.10.06/ircd/s_bdd.c Thu Oct 21 22:40:36 1999 *************** *** 0 **** --- 1,2200 ---- + /* + * IRC - Internet Relay Chat, ircd/s_serv.c (formerly ircd/s_msg.c) + * Copyright (C) 1999 IRC-Hispano.org - ESNET - jcea & savage + * + * 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + #include "sys.h" + #include + + #if defined(DB_ESNET) || defined(DB_HISPANO) + #include + #include + #include + #include + #include + #include "h.h" + #include "struct.h" + #include "ircd.h" + #include "s_serv.h" + #include "s_misc.h" + #include "sprintf_irc.h" + #include "send.h" + #include "s_err.h" + #include "numeric.h" + #include "s_bsd.h" + #include "s_conf.h" + #include "hash.h" + #include "common.h" + #include "match.h" + #include "crule.h" + #include "parse.h" + #include "numnicks.h" + #include "userload.h" + #include "s_user.h" + #include "channel.h" + #include "querycmds.h" + #include "IPcheck.h" + + #include "s_bdd.h" + + #if defined(DB_ESNET) || defined(DB_HISPANO) + #include "msg.h" + #include "support.h" + /* + * Las tablas con los registros, serie, version ... + */ + int tabla_residente[DBH_MAX_TABLA]; + unsigned long tabla_cuantos[DBH_MAX_TABLA]; + struct dbh_reg *tabla_datos[DBH_MAX_TABLA][DBH_HASH_SIZE]; + unsigned long tabla_version[DBH_MAX_TABLA]; + unsigned long tabla_serie[DBH_MAX_TABLA]; + unsigned long tabla_hash_hi[DBH_MAX_TABLA]; + unsigned long tabla_hash_lo[DBH_MAX_TABLA]; + #endif /* DB_ESNET || DB_HISPANO */ + + + #if defined(DB_ESNET) || defined(DB_HISPANO) + /* + * TEA (cifrado) + * + * Cifra 64 bits de datos, usando clave de 64 bits (los 64 bits superiores son cero) + * Se cifra v[0]^x[0], v[1]^x[1], para poder hacer CBC facilmente. + * + */ + void tea(unsigned long v[], unsigned long k[], unsigned long x[]) + { + unsigned long y = v[0] ^ x[0], z = v[1] ^ x[1], sum = 0, delta = 0x9E3779B9; + unsigned long a = k[0], b = k[1], n = 32; + unsigned long c = 0, d = 0; + + while (n-- > 0) + { + sum += delta; + y += (z << 4) + a ^ z + sum ^ (z >> 5) + b; + z += (y << 4) + c ^ y + sum ^ (y >> 5) + d; + } + + x[0] = y; + x[1] = z; + } + + void actualiza_hash(char *registro, char que_bdd) + { + unsigned long buffer[129 * sizeof(unsigned long)]; + unsigned long *p = buffer; + unsigned long x[2], v[2], k[2]; + char *p2; + + /* + ** Calculamos el HASH + */ + memset(buffer, 0, sizeof(buffer)); + strncpy((char *)buffer, registro, sizeof(buffer) - 1); + while ((p2 = strchr((char *)buffer, '\n'))) + *p2 = '\0'; + while ((p2 = strchr((char *)buffer, '\r'))) + *p2 = '\0'; + k[0] = k[1] = 0; + x[0] = tabla_hash_hi[que_bdd]; + x[1] = tabla_hash_lo[que_bdd]; + while (*p) + { + v[0] = ntohl(*p++); + v[1] = ntohl(*p++); + tea(v, k, x); + } + tabla_hash_hi[que_bdd] = x[0]; + tabla_hash_lo[que_bdd] = x[1]; + } + + /* + * dbh_eliminar_borrados (tabla) + * + * libera (free) todos los registros con marca 'borrados' de memoria. + * 1999/06/21 savage@apostols.org + */ + void dbh_eliminar_borrados(char tabla) + { + FILE *f; + struct dbh_reg *reg; + int i; + + tabla_cuantos[tabla] = 0; + + for (i = 0; i < DBH_HASH_SIZE; i++) + for (reg = tabla_datos[tabla][i]; reg != NULL; reg = reg->next) + if (reg->borrado) + { + if (reg->prev) + reg->prev->next = reg->next; + else + tabla_datos[tabla][i] = reg->next; /* era el primero */ + if (reg->next) + reg->next->prev = reg->prev; + if (reg->clave) + RunFree(reg->clave); + if (reg->valor) + RunFree(reg->valor); + RunFree(reg); + } + else + tabla_cuantos[tabla]++; + + return; + } + + /* + * dbh_eliminar_registro (tabla, clave) + * + * libera (free) un registro de memoria. + * 1999/06/23 savage@apostols.org + */ + void dbh_eliminar_registro(char tabla, char *clave) + { + struct dbh_reg *reg; + int hashi, i = 0; + char *c; + + c = RunMalloc(strlen(clave) + 1); + if (c == NULL) + return; + strcpy(c, clave); + /* paso a minusculas */ + while (c[i] != 0) + { + c[i] = toLower(c[i]); + i++; + } + + hashi = dbh_hash_registro(c); + + for (reg = tabla_datos[tabla][hashi]; reg != NULL; reg = reg->next) + if (!strcmp(reg->clave, c)) + { + /* + sendto_ops("Elimino T='%c' C='%s' H=%u",tabla, reg->clave, hashi ); + */ + if (reg->prev) + reg->prev->next = reg->next; + else + tabla_datos[tabla][hashi] = reg->next; /* era el primero */ + + if (reg->next) + reg->next->prev = reg->prev; + + if (reg->clave) + RunFree(reg->clave); + if (reg->valor) + RunFree(reg->valor); + RunFree(reg); + tabla_cuantos[tabla]--; + break; + } + + RunFree(c); + + return; + } + + /* + * dbh_insertar_registro (tabla, destino, clave, valor) + * + * mete un registro en memoria ... + * 1999/06/23 savage@apostols.org + */ + void dbh_insertar_registro(char tabla, char *destino, char *clave, char *valor) + { + struct dbh_reg *reg, *rh; + int hashi; + char *c, *v, *d; + aClient *acptr; + int i = 0; + + /* lo borro primero, por si es un cambio */ + dbh_eliminar_registro(tabla, clave); + + c = RunMalloc(strlen(clave) + 1); + if (!c) + return; + v = RunMalloc(strlen(valor) + 1); + if (!v) + { + RunFree(c); + return; + } + d = RunMalloc(strlen(destino) + 1); + if (!d) + { + RunFree(c); + RunFree(v); + return; + } + + reg = RunMalloc(sizeof(struct dbh_reg)); + if (!reg) + { + RunFree(c); + RunFree(v); + RunFree(d); + return; + } + + strcpy(c, clave); + strcpy(v, valor); + strcpy(d, destino); + + /* paso a minusculas */ + while (c[i] != 0) + { + c[i] = toLower(c[i]); + i++; + } + + /* creo el registro */ + reg->clave = c; + reg->valor = v; + reg->destino = d; + reg->next = reg->prev = NULL; + reg->borrado = 0; + reg->compactado = 0; + + /* marco como local si es para mi o broadcast */ + if (*d == '*' || ((acptr = find_match_server(d)) && (IsMe(acptr)))) + reg->local = 1; + else + reg->local = 0; + + /* busco hash */ + hashi = dbh_hash_registro(reg->clave); + + /* + sendto_ops("Inserto T='%c' C='%s' H=%u",tabla, reg->clave, hashi ); + */ + + rh = tabla_datos[tabla][hashi]; + tabla_datos[tabla][hashi] = reg; + reg->next = rh; + if (rh) + rh->prev = reg; + + tabla_cuantos[tabla]++; + + return; + } + + /* + * dbh_buscar_registro (tabla, clave) + * + * busca un registro en memoria ... + * 1999/06/23 savage@apostols.org + */ + struct dbh_reg *dbh_buscar_registro(char tabla, char *clave) + { + struct dbh_reg *reg; + int hashi, i = 0; + char *c; + + c = RunMalloc(strlen(clave) + 1); + if (c == NULL) + return; + strcpy(c, clave); + /* paso a minusculas */ + while (c[i] != 0) + { + c[i] = toLower(c[i]); + i++; + } + + /* busco hash */ + hashi = dbh_hash_registro(c); + + /* + sendto_ops("Busco T='%c' C='%s' H=%u",tabla, c, hashi ); + */ + + for (reg = tabla_datos[tabla][hashi]; reg != NULL; reg = reg->next) + if (!strcmp(reg->clave, c)) + { + RunFree(c); + return reg; + } + RunFree(c); + return NULL; + } + + /* + * dbh_buscar_registro_local (tabla, clave) + * + * busca un registro local en memoria ... + * 1999/06/23 savage@apostols.org + */ + struct dbh_reg *dbh_buscar_registro_local(char tabla, char *clave) + { + struct dbh_reg *reg; + + reg = dbh_buscar_registro(tabla, clave); + if (!reg) + return NULL; + + if (reg->local) + return reg; + else + return NULL; + } + + /* + * dbh_es_miembro (tabla, clave, subcadena) + * + * varor registro es una lista separada por comas, y si subcadena es + # una de ellas, retorna la posicion, sino 0 + * 1999/07/03 savage@apostols.org + */ + int dbh_es_miembro(char tabla, char *clave, char *subcadena) + { + int j, i = 0; + char *buff, *f, *s = NULL; + struct dbh_reg *reg; + + if ((reg = dbh_buscar_registro_local(tabla, clave)) == NULL) + return 0; + + buff = RunMalloc(strlen(reg->valor) + 1); + if (!buff) + return 0; + + strcpy(buff, reg->valor); + for (f = strtoken(&s, buff, ","); f != NULL; f = strtoken(&s, NULL, ",")) + { + j++; + if (!strCasediff(f, subcadena)) + { + i++; + break; + } + } + + RunFree(buff); + return i; + } + + #endif /* defined(DB_ESNET) || defined(DB_HISPANO) */ + + /* + ** Esta rutina mata el servidor. + ** Es casi una copia de m_die(). + */ + extern char **myargv; /* ircd.c */ + void db_die(char *msg, char que_bdd) + { + aClient *acptr; + int i; + char buf[1024]; + + sprintf_irc(buf, "DB '%c' - %s. El daemon muere...", que_bdd, msg); + for (i = 0; i <= highest_fd; i++) + { + if (!(acptr = loc_clients[i])) + continue; + if (IsUser(acptr)) + sendto_one(acptr, ":%s NOTICE %s :%s", me.name, acptr->name, buf); + else if (IsServer(acptr)) + sendto_one(acptr, ":%s ERROR :%s", me.name, buf); + } + + #ifndef USE_SYSLOG + openlog(myargv[0], LOG_PID | LOG_NDELAY, LOG_DAEMON); + #endif + + syslog(LOG_ERR, buf); + + #ifndef USE_SYSLOG + closelog(); + #endif + + Debug((DEBUG_ERROR, buf)); + + #ifdef __cplusplus + s_die(0); + #else + s_die(); + #endif + } + + #ifdef DB_ESNET + /* + * leer_db + * + * Lee un registro de la base de datos. + * + */ + int leer_db(struct tabla_en_memoria *mapeo, char *buf) + { + int cont = 0; + int estado; + char *p = mapeo->posicion + mapeo->len; + + while (mapeo->puntero_r < p) + { + *buf = *(mapeo->puntero_r++); + if (*buf == '\r') + continue; + if ((*buf++ == '\n')) + { + *--buf = '\0'; + return cont; + } + if (cont++ > 500) + break; + } + *buf = '\0'; + return -1; + } + + /* + ** Seek por bidivision + */ + int seek_db(struct tabla_en_memoria *mapeo, char *buf, unsigned long registro) + { + char *p, *p2, *plo, *phi; + unsigned long v; + + /* + ** Este caso especial es lo bastante + ** comun como para que se tenga en cuenta. + */ + if (!registro) + { + mapeo->puntero_r = mapeo->posicion; + return leer_db(mapeo, buf); + } + + plo = mapeo->posicion; + phi = plo + mapeo->len; + while (plo != phi) + { + /* + ** p apunta al principio del registro + ** p2 apunta al registro siguiente + */ + p2 = p = plo + (phi - plo) / 2; + while ((p >= plo) && (*p != '\n')) + p--; + if (p < plo) + p = plo; + if (*p == '\n') + p++; + while ((p2 < phi) && (*p2++ != '\n')); + /* + ** Estamos al principio de un registro + */ + v = atol(p); + if (v > registro) + phi = p; + else if (v < registro) + plo = p2; + else + { + plo = phi = p; /* Encontrado */ + break; + } + } + mapeo->puntero_r = plo; + return leer_db(mapeo, buf); + } + + /* + * abrir_db + * + * Se mueve hasta un registro de la base de datos + * + */ + int abrir_db(unsigned long registro, char *buf, char que_bdd, + struct tabla_en_memoria *mapeo) + { + int handle; + int cont; + char path[1024]; + struct stat estado; + + *buf = '\0'; + sprintf_irc(path, "%s/tabla.%c", DBPATH, que_bdd); + alarm(3); + handle = open(path, O_RDONLY, S_IRUSR | S_IWUSR); + fstat(handle, &estado); + mapeo->len = estado.st_size; + mapeo->posicion = mmap(NULL, mapeo->len, + PROT_READ, MAP_SHARED | MAP_NORESERVE, handle, 0); + close(handle); + alarm(0); + mapeo->puntero_r = mapeo->puntero_w = mapeo->posicion; + + if (handle == -1) + db_die("Error al intentar leer (open)", que_bdd); + if ((mapeo->len != 0) && (mapeo->posicion == MAP_FAILED)) + db_die("Error al intentar leer (mmap)", que_bdd); + + if ((handle == -1) || (mapeo->posicion == MAP_FAILED)) + return -1; + + cont = seek_db(mapeo, buf, registro); + if (cont == -1) + { + *buf = '\0'; + return -1; + } + return handle; + } + + void cerrar_db(struct tabla_en_memoria *mapeo) + { + munmap(mapeo->posicion, mapeo->len); + } + + /* + ** almacena_hash + ** + ** El fichero de HASHES contiene una linea + ** por BDD. Cada linea tiene el formato + ** "BDD HASH\n" + ** En total, cada linea mide 15 bytes. + */ + void almacena_hash(char que_bdd) + { + char path[1024]; + char hash[20]; + int db_file; + + sprintf_irc(path, "%s/hashes", DBPATH); + inttobase64(hash, tabla_hash_hi[que_bdd], 6); + inttobase64(hash + 6, tabla_hash_lo[que_bdd], 6); + alarm(3); + db_file = open(path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); + if (db_file == -1) + db_die("Error al intentar guardar hashes (open)", que_bdd); + sprintf_irc(path, "%c %s\n", que_bdd, hash); + if (lseek(db_file, 15 * (que_bdd - ESNET_BDD), SEEK_SET) == -1) + db_die("Error al intentar guardar hashes (lseek)", que_bdd); + if (write(db_file, path, strlen(path)) == -1) + db_die("Error al intentar guardas hashes (write)", que_bdd); + close(db_file); + alarm(0); + } + + /* + ** lee_hash + */ + void lee_hash(char que_bdd, unsigned long *hi, unsigned long *lo) + { + char path[1024]; + char c; + int db_file; + + sprintf_irc(path, "%s/hashes", DBPATH); + alarm(3); + db_file = open(path, O_RDONLY); + /* + ** No metemos verificacion, porque ya verifica + ** al contrastar el hash. + */ + lseek(db_file, 15 * (que_bdd - ESNET_BDD) + 2, SEEK_SET); + read(db_file, path, 12); + close(db_file); + alarm(0); + path[12] = '\0'; + c = path[6]; + path[6] = '\0'; + *hi = base64toint(path); + path[6] = c; + *lo = base64toint(path + 6); + } + + /* + * db_alta + * + * Da de alta una entrada en la base de datos en memoria + * Formato "serie destino id clave contenido" + * + * modificado para usar las hash con funciones dbh_* + * 1999/06/30 savage@apostols.org + */ + void db_alta(char *registro, char que_bdd, int guarda_hash) + { + char *p0, *p1, *p2, *p3, *p4; + + actualiza_hash(registro, que_bdd); + + if (guarda_hash) + almacena_hash(que_bdd); + + p0 = strtok(registro, " "); /* serie */ + p1 = strtok(NULL, " "); /* destino */ + p2 = strtok(NULL, " "); /* tabla */ + p3 = strtok(NULL, " \r\n"); /* clave */ + p4 = strtok(NULL, "\r\n"); /* valor (opcional) */ + + if (p3 == NULL) + return; /* registro incompleto */ + + tabla_serie[que_bdd] = atol(p0); + + if (tabla_residente[que_bdd]) + { + if (p4 == NULL) /* Borrado */ + dbh_eliminar_registro(que_bdd, p3); + else + dbh_insertar_registro(que_bdd, p1, p3, p4); + } + } + + /* + ** db_pack + ** + ** Elimina los registro superfluos + ** de una Base de Datos Local. + ** + ** Se invoca cuando re recibe un CheckPoint, y el + ** formato es "serie destino id * texto" + */ + void db_pack(char *registro, char que_bdd) + { + int db_file; + char path[1024]; + char *map; + char *lectura, *escritura, *p; + char *clave, *valor; + char c; + unsigned long len, len2; + struct stat estado; + struct dbh_reg *reg; + + /* + ** El primer valor es el numero de serie actual + */ + tabla_serie[que_bdd] = atol(registro); + + sprintf_irc(path, "%s/tabla.%c", DBPATH, que_bdd); + alarm(3); + db_file = open(path, O_RDWR | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR); + fstat(db_file, &estado); + len = estado.st_size; + map = mmap(NULL, len, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_NORESERVE, db_file, 0); + alarm(0); + if (db_file == -1) + db_die("Error al intentar compactar (open)", que_bdd); + if ((len != 0) && (map == MAP_FAILED)) + db_die("Error al intentar compactar (mmap)", que_bdd); + + if (!tabla_residente[que_bdd]) + { /* No residente -> No pack */ + escritura = map + len; + goto fin; + } + + tabla_hash_hi[que_bdd] = 0; + tabla_hash_lo[que_bdd] = 0; + + p = lectura = escritura = map; + while (lectura < map + len) + { + p = strchr(p, ' ') + 1; /* Destino */ + p = strchr(p, ' ') + 1; /* BDD */ + valor = clave = p = strchr(p, ' ') + 1; /* Clave */ + while ((p < map + len) && (*p != '\n') && (*p != '\r')) + p++; + while ((*valor != ' ') && (valor < p)) + valor++; + valor++; /* Nos saltamos el espacio */ + + /* + ** Los registros "*" son borrados automaticamente + ** al compactar, porque no aparecen en la + ** base de datos en memoria. + ** + ** Solo se mantiene el nuevo, porque es + ** el que se graba tras la compactacion + */ + if (valor < p) + { /* Nuevo registro, no un borrado */ + *(valor - 1) = '\0'; + reg = dbh_buscar_registro_local(que_bdd, clave); + *(valor - 1) = ' '; + if (reg != NULL) + { /* El registro sigue existiendo */ + + len2 = strlen(reg->valor); + if ((valor + len2 == p) && (!strncmp(valor, reg->valor, len2))) + { /* !!El mismo!! */ + + /* + ** Actualizamos HASH + */ + if ((*p == '\n') || (*p == '\r')) + { + c = *p; + *p = '\0'; + actualiza_hash(lectura, que_bdd); + *p = c; + } + else + { /* Estamos al final y no hay retorno de carro */ + memcpy(path, lectura, p - lectura); + path[p - lectura] = '\0'; + actualiza_hash(path, que_bdd); + } + + while ((p < map + len) && ((*p == '\n') || (*p == '\r'))) + p++; + memcpy(escritura, lectura, p - lectura); + escritura += p - lectura; + lectura = p; + continue; /* MUY IMPORTANTE */ + } /* Hay otro mas moderno que este */ + } /* El registro fue borrado */ + } /* Es un borrado */ + while ((p < map + len) && ((*p == '\n') || (*p == '\r'))) + p++; + lectura = p; + } + + fin: + + munmap(map, len); + + alarm(3); + ftruncate(db_file, escritura - map); + lseek(db_file, 0, SEEK_END); + write(db_file, registro, strlen(registro)); /* CheckPoint */ + close(db_file); + alarm(0); + actualiza_hash(registro, que_bdd); + almacena_hash(que_bdd); + } + + /* + * borrar_db + * + * Borra la base de datos en memoria (modificado para uso de hash) + * + * 1999/06/30 savage@apostols.org + */ + void borrar_db(char que_bdd) + { + int i; + struct dbh_reg *reg; + + for (i = 0; i < DBH_HASH_SIZE; i++) + for (reg = tabla_datos[que_bdd][i]; reg != NULL; reg = reg->next) + reg->borrado = 1; + /* + ** Evita Memory Leak + */ + dbh_eliminar_borrados(que_bdd); + + /* Error introducido en DBH + ** BUGFIX! + */ + tabla_serie[que_bdd] = 0; + tabla_cuantos[que_bdd] = 0; + tabla_hash_hi[que_bdd] = 0; + tabla_hash_lo[que_bdd] = 0; + } + + + static void corta_si_multiples_hubs(aClient *cptr, char que_bdd, char *mensaje) + { + char buf[1024]; + Dlink *lp; + int num_hubs = 0; + aClient *acptr; + + for (lp = me.serv->down; lp; lp = lp->next) + { + if (find_conf_host(lp->value.cptr->confs, + lp->value.cptr->name, CONF_HUB) != NULL) num_hubs++; + } + + if (num_hubs >= 2) + { + + /* + ** No podemos simplemente hace el bucle, porque + ** el "exit_client()" modifica la estructura + */ + corta: + if (num_hubs-- > 1) + { /* Deja un HUB conectado */ + for (lp = me.serv->down; lp; lp = lp->next) + { + acptr = lp->value.cptr; + /* + ** Si se especifica que se desea mantener un HUB + ** en concreto, respeta esa peticion + */ + if ((acptr != cptr) && + find_conf_host(acptr->confs, acptr->name, CONF_HUB) != NULL) + { + sprintf_irc(buf, "BDD '%c' %s. Resincronizando...", que_bdd, mensaje); + exit_client(acptr, acptr, &me, buf); + goto corta; + } + } + } + } + } + + /* + * initdb + * + * Lee la base de datos de disco + * + */ + void initdb2(char que_bdd) + { + unsigned long hi, lo; + char buf[1024]; + char path[1024]; + int db_file; + Dlink *lp; + struct tabla_en_memoria mapeo; + + borrar_db(que_bdd); + + db_file = abrir_db(0, buf, que_bdd, &mapeo); + if (db_file != -1) + do + { + /* db_alta modifica la cadena */ + if (tabla_residente[que_bdd] && !((*buf == '*') && (*(buf + 1) == '\0'))) + { + db_alta(buf, que_bdd, 0); + } + else + { + actualiza_hash(buf, que_bdd); + } + } + while (leer_db(&mapeo, buf) != -1); + cerrar_db(&mapeo); + + /* + ** Ahora comprueba que el HASH de la BDD + ** cargada se corresponda con el HASH almacenado + */ + lee_hash(que_bdd, &hi, &lo); + if ((tabla_hash_hi[que_bdd] != hi) || (tabla_hash_lo[que_bdd] != lo)) + { + sendto_ops("ATENCION - Base de Datos " + "'%c' aparentemente corrupta. Borrando...", que_bdd); + borrar_db(que_bdd); + sprintf_irc(path, "%s/tabla.%c", DBPATH, que_bdd); + alarm(3); + db_file = open(path, O_TRUNC, S_IRUSR | S_IWUSR); + close(db_file); + if (db_file == -1) + db_die("Error al intentar truncar (open)", que_bdd); + alarm(0); + + /* + ** Solucion temporal + ** Corta conexiones con los HUBs + */ + for (lp = me.serv->down; lp; lp = lp->next) + { + if (find_conf_host(lp->value.cptr->confs, + lp->value.cptr->name, CONF_HUB) != NULL) + { + sprintf_irc(buf, "BDD '%c' inconsistente. Resincronizando...", que_bdd); + exit_client(lp->value.cptr, lp->value.cptr, &me, buf); + } + } + /* + ** Fin solucion temporal + */ + + corta_si_multiples_hubs(NULL, que_bdd, "inconsistente"); + + sendto_ops("Solicitando actualizacion BDD '%c' " + "a los nodos vecinos.", que_bdd); + + /* + ** Solo pide a los HUBs, porque no se + ** aceptan datos de leafs. + */ + for (lp = me.serv->down; lp; lp = lp->next) + { + if (find_conf_host(lp->value.cptr->confs, + lp->value.cptr->name, CONF_HUB) != NULL) + { + sendto_one(lp->value.cptr, "%s DB %s 0 J %lu %c", + NumServ(&me), lp->value.cptr->name, tabla_serie[que_bdd], que_bdd); + } + } + } + almacena_hash(que_bdd); + } + + void initdb(void) + { + char c; + + tabla_residente[ESNET_NICKDB] = 1; + #if defined(DB_ESNET) && defined(ESNET_CLONES) + tabla_residente[ESNET_CLONESDB] = 1; + #endif + + for (c = ESNET_BDD; c <= ESNET_BDD_END; c++) + initdb2(c); + } + + /* + * reload_db + * + * Recarga la base de datos de disco, liberando la memoria + * + */ + void reload_db(void) + { + char buf[16]; + char c; + + sendto_ops("Releyendo Bases de Datos..."); + initdb(); + for (c = ESNET_BDD; c <= ESNET_BDD_END; c++) + { + if (tabla_serie[c]) + { + inttobase64(buf, tabla_hash_hi[c], 6); + inttobase64(buf + 6, tabla_hash_lo[c], 6); + sendto_ops("DB: '%c'. Ultimo registro: %lu. HASH: %s", + c, tabla_serie[c], buf); + } + } + } + + + /* + * m_db + * + * Gestion de la base de datos - ESNET + * 29/May/98 jcea@argo.es + * + */ + int m_db(aClient *cptr, aClient *sptr, int parc, char *parv[]) + { + unsigned long db; + aClient *acptr; + Dlink *lp; + char db_buf[1024], db_buf2[1024]; + char path[1024]; + int db_file; + int es_hub = 0; + char *p, *p2, *p3, *p4; + char que_bdd = ESNET_NICKDB; + unsigned long mascara_bdd; + int cont; + struct tabla_en_memoria mapeo; + + + if (!IsServer(sptr) || parc < 5) + return 0; + db = atol(parv[2]); + if (find_conf_host(cptr->confs, cptr->name, CONF_HUB) != NULL) + es_hub = !0; + if (!db) + { + db = atol(parv[4]); + + if (parc == 6) + { + que_bdd = *parv[5]; + if ((que_bdd < 'a') || (que_bdd > 'z')) + if ((que_bdd < '2') || (que_bdd > '9') || (*parv[3] != 'J')) + return 0; + else + que_bdd = ESNET_NICKDB; + } + mascara_bdd = ((unsigned long)1) << (que_bdd - ESNET_BDD); + + switch (*parv[3]) + { + case 'B': + if (es_hub) + sendto_one(sptr, "%s DB %s 0 J %lu %c", + NumServ(&me), parv[0], tabla_serie[que_bdd], que_bdd); + return 0; + break; + + case 'J': + if ((parc == 6) && (*parv[5] >= '2') && (*parv[5] <= '9')) + { + /* + ** Informamos del estado de nuestras BDD + */ + for (cont = ESNET_BDD; cont <= ESNET_BDD_END; cont++) + { + if (cont != ESNET_NICKDB) /* No mandamos nicks de nuevo */ + sendto_one(sptr, "%s DB %s 0 J %lu %c", + NumServ(&me), parv[0], tabla_serie[cont], cont); + } + } + + /* + ** No hay problemas de CPU en el + ** extremo receptor. Esto es para + ** limitar el LAG y el caudal + ** consumido. + */ + cont = 100; + + if (db >= tabla_serie[que_bdd]) + { /* Se le pueden mandar registros individuales */ + sptr->serv->esnet_db |= mascara_bdd; + return 0; + break; + } + else if ((sptr->serv->esnet_db) & mascara_bdd) + { + /* + ** Teniamos el grifo abierto, y ahora + ** nos esta pidiendo registros antiguos. + ** Eso SOLO ocurre si ha detectado que su + ** copia local de la BDD esta corrupta. + */ + sptr->serv->esnet_db &= ~mascara_bdd; + /* + ** Borramos su BDD porque es posible + ** que le hayamos enviado mas registros. + ** Es preferible empezar desde cero. + */ + sendto_one(sptr, "%s DB %s 0 D BDD_CORRUPTA %c", + NumServ(&me), sptr->name, que_bdd); + db = 0; /* Nos curamos en salud; se la enviamos entera */ + } + + db_file = abrir_db(db + 1, db_buf, que_bdd, &mapeo); + if (db_file == -1) + return 0; /* Problemas con la DB */ + do + { + p = strchr(db_buf, ' '); + if (p == NULL) + continue; + *p++ = '\0'; + p2 = strchr(p, ' '); + if (p2 == NULL) + continue; + *p2++ = '\0'; + p3 = strchr(p2, ' '); + if (p3 == NULL) + continue; + *p3++ = '\0'; + p4 = strchr(p3, ' '); + if (p4 == NULL) + { + sendto_one(sptr, "%s DB %s %s %s %s", NumServ(&me), p, db_buf, p2, + p3); + } + else + { + *p4++ = '\0'; + sendto_one(sptr, "%s DB %s %s %s %s :%s", NumServ(&me), p, db_buf, + p2, p3, p4); + } + if (!(--cont)) + break; + } + while (leer_db(&mapeo, db_buf) != -1); + cerrar_db(&mapeo); + if (cont) + sptr->serv->esnet_db |= mascara_bdd; + else + sendto_one(sptr, "%s DB %s 0 B %lu %c", + NumServ(&me), parv[0], tabla_serie[que_bdd], que_bdd); + return 0; + break; + + case 'D': + if (!es_hub) + return 0; + /* + ** Por bug en lastNNServer no se puede usar 'find_match_server()' + */ + collapse(parv[1]); + if (!match(parv[1], me.name)) + { + sprintf_irc(path, "%s/tabla.%c", DBPATH, que_bdd); + alarm(3); + db_file = open(path, O_TRUNC, S_IRUSR | S_IWUSR); + close(db_file); + if (db_file == -1) + db_die("Error al intentar truncar (open)", que_bdd); + alarm(0); + borrar_db(que_bdd); + sprintf_irc(db_buf, "borrada (%s)", sptr->name); + corta_si_multiples_hubs(cptr, que_bdd, db_buf); + /* + ** Podemos enviar a 'sptr' tranquilos, porque el + ** corte afectaria a todos los HUBs menos a + ** traves del que llega la peticion. + */ + sendto_one(sptr, "%s DB %s 0 E %s %c\n", + NumServ(&me), sptr->name, parv[4], que_bdd); + } + + /* + ** Como no sabemos si el otro extremo nos ha + ** cerrado el grifo o no, nos curamos en salud + */ + sendto_one(cptr, "%s DB %s 0 J %lu %c", + NumServ(&me), cptr->name, tabla_serie[que_bdd], que_bdd); + + sprintf(db_buf, "%s DB %s 0 D %s %c", + NumServ(sptr), parv[1], parv[4], que_bdd); + + for (lp = me.serv->down; lp; lp = lp->next) + { + if (lp->value.cptr == cptr) + continue; + /* + ** No sabemos si la otra punta + ** va a cumplir la mascara, asi que + ** nos curamos en salud. + */ + lp->value.cptr->serv->esnet_db &= ~mascara_bdd; + + sendto_one(lp->value.cptr, db_buf); + } + + return 0; + break; + + case 'E': /* Podemos ser destinatarios si el otro estaba corrupto */ + case 'R': + if ((acptr = find_match_server(parv[1])) && (!IsMe(acptr))) + sendto_one(acptr, "%s DB %s 0 %c %s %c", NumServ(sptr), + acptr->name, *parv[3], parv[4], que_bdd); + return 0; + break; + + case 'Q': + if (!es_hub) + return 0; + /* + ** Por bug en lastNNServer no se puede usar 'find_match_server()' + */ + collapse(parv[1]); + if (!match(parv[1], me.name)) + { + inttobase64(db_buf, tabla_hash_hi[que_bdd], 6); + inttobase64(db_buf + 6, tabla_hash_lo[que_bdd], 6); + sendto_one(sptr, "%s DB %s 0 R %lu-%s-%s %c", + NumServ(&me), sptr->name, tabla_serie[que_bdd], + db_buf, parv[4], que_bdd); + } + + sprintf(db_buf, "%s DB %s 0 Q %s %c", + NumServ(sptr), parv[1], parv[4], que_bdd); + + for (lp = me.serv->down; lp; lp = lp->next) + { + if (lp->value.cptr == cptr) + continue; + sendto_one(lp->value.cptr, db_buf); + } + + return 0; + break; + } + return 0; + } + + /* Nuevo registro */ + + que_bdd = *parv[3]; + if ((que_bdd < 'a') || (que_bdd > 'z')) + { + if (que_bdd == 'N') + que_bdd = ESNET_NICKDB; + else + return 0; + } + + mascara_bdd = ((unsigned long)1) << (que_bdd - ESNET_BDD); + + if (db <= tabla_serie[que_bdd]) + return 0; + if (!es_hub) + return 0; + + /* + ** Ojo, hay que usar 'db' y no 'parv[2]' + ** porque en la cadena de formateo se + ** dice que se le pasa un numero, no + ** una cadena. + ** Se le pasa un numero para que se formatee + ** correctamente, ya que luego sera + ** utilizado en un HASH y todos los + ** nodos deberian dar el mismo valor. + */ + if (parc == 5) + sprintf_irc(db_buf, "%s DB %s %lu %s %s", + NumServ(sptr), parv[1], db, parv[3], parv[4]); + else + sprintf_irc(db_buf, "%s DB %s %lu %s %s :%s", + NumServ(sptr), parv[1], db, parv[3], parv[4], parv[5]); + + for (lp = me.serv->down; lp; lp = lp->next) + { + if (!((lp->value.cptr->serv->esnet_db) & mascara_bdd) || + (lp->value.cptr == cptr)) continue; + sendto_one(lp->value.cptr, db_buf); + } + + sprintf_irc(path, "%s/tabla.%c", DBPATH, que_bdd); + alarm(3); + db_file = open(path, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR); + if (db_file == -1) + db_die("Error al intentar an~adir nuevo registro (open)", que_bdd); + alarm(0); + + if (parc == 5) + sprintf_irc(db_buf, "%lu %s %s %s\n", db, parv[1], parv[3], parv[4]); + else + sprintf_irc(db_buf, "%lu %s %s %s %s\n", db, parv[1], parv[3], parv[4], + parv[5]); + + strcpy(db_buf2, db_buf); /* db_alta modifica la cadena */ + if (strcmp(parv[4], "*")) + db_alta(db_buf2, que_bdd, !0); /* CheckPoint */ + + alarm(3); + if (strcmp(parv[4], "*")) + { /* CheckPoint */ + if (write(db_file, db_buf, strlen(db_buf)) == -1) + db_die("Error al intentar an~adir nuevo registro (write)", que_bdd); + } + close(db_file); + alarm(0); + + if (!strcmp(parv[4], "*")) + db_pack(db_buf, que_bdd); + + return 0; + } + + #endif /* DB_ESNET */ + + #ifdef DB_HISPANO + /* + * dbh_violacion (argc, argv, texto) + * + * Muestra error protocolo DBH a los opers. + * 1999/06/28 savage@apostols.org + */ + void dbh_violacion(int parc, char *parv[], char *causa) + { + int i; + char line[2048]; + + sprintf_irc(line, "%s %s ", parv[0], MSG_DBH); + for (i = 1; i < parc; i++) + { + strcat(line, parv[i]); + strcat(line, " "); + } + + sendto_ops("Error DBH: %s", causa); + sendto_ops("Debug DBH: %s", line); + } + + /* + * dbh_hash_tabla (tabla) + * + * calcula la HASH de una tabla. + * 1999/06/21 savage@apostols.org + */ + unsigned long dbh_hash_tabla(char tabla) + { + return 0; + } + + /* + * dbh_guardar_version (tabla, version) + * + * actualiza la version en memoria y disco. + * 1999/06/21 savage@apostols.org + */ + void dbh_guardar_version(char tabla, unsigned long version) + { + FILE *f; + char fichero[1024]; + + /* guardo en memoria */ + tabla_version[tabla] = version; + + /* guardo en disco */ + sprintf_irc(fichero, "%s/version.%c", DBPATH, tabla); + alarm(3); + f = fopen(fichero, "w"); + if (f) + { + fprintf(f, "%lu\n", version); + fclose(f); + } + alarm(0); + + return; + } + + /* + * dbh_leer_version (tabla) + * + * actualiza la version en memoria a partir de la de disco. + * 1999/06/21 savage@apostols.org + */ + unsigned long dbh_leer_version(char tabla) + { + FILE *f; + char fichero[1024]; + char buff[512]; + + buff[0] = 0; + + /* guardo en disco */ + sprintf_irc(fichero, "%s/version.%c", DBPATH, tabla); + alarm(3); + f = fopen(fichero, "r"); + if (f) + { + fgets(buff, sizeof(buff) - 1, f); + fclose(f); + } + alarm(0); + + /* ke pone? */ + tabla_version[tabla] = atol(buff); + + return tabla_version[tabla]; + } + + /* + * dbh_abrir_tabla (fichero) + * + * abre una tabla con un modo concreto "a", "r", "w" ... + * 1999/06/21 savage@apostols.org + */ + FILE *dbh_abrir_tabla(char tabla, char *modo) + { + FILE *f; + char fichero[1024]; + + alarm(3); + sprintf_irc(fichero, "%s/tabla.%c", DBPATH, tabla); + f = fopen(fichero, modo); + alarm(0); + + return f; + } + + /* + * dbh_cerrar_tabla (fichero) + * + * cierra una tabla abierta con dbh_abrir_tabla ... + * 1999/06/21 savage@apostols.org + */ + int dbh_cerrar_tabla(FILE * f) + { + if (f) + { + alarm(3); + fclose(f); + alarm(0); + } + + return 0; + } + + /* + * dbh_leer_registro (fichero, numero_registro) + * + * lee el registro n de una tabla abierta con dbh_abrir_tabla + * 1999/06/21 savage@apostols.org + */ + char *dbh_leer_registro(FILE * f, unsigned long regnum) + { + char buf[1024]; + static char b2[1024]; + char *p; + unsigned long num = 0; + + while (num != regnum && !feof(f)) + { + alarm(3); + fgets(buf, sizeof(buf) - 1, f); + alarm(0); + memcpy(b2, buf, sizeof(b2)); /* mas rapido ke strcpy */ + p = strtok(buf, " "); + p = strtok(NULL, " "); + if (p) + num = atol(p); + } + + if (num != regnum) + return NULL; + + return b2; + } + + /* + * dbh_cargar_tabla (tabla) + * + * lee una tabla y la mete en memoria + * 1999/06/21 savage@apostols.org + */ + void dbh_cargar_tabla(char tabla) + { + char *p1, *p2, *p3, *p4, *p5, *txt; + unsigned long num = 0; + FILE *f; + + f = dbh_abrir_tabla(tabla, "r"); + if (!f) + return; + while ((txt = dbh_leer_registro(f, num + 1)) != NULL) + { + num++; + if (tabla_residente[tabla]) + { + p1 = strtok(txt, " "); /* destino */ + p2 = strtok(NULL, " "); /* serie */ + p3 = strtok(NULL, " "); /* tabla */ + p4 = strtok(NULL, " \n\r"); /* clave */ + p5 = strtok(NULL, "\n\r"); /* :valor */ + + if (p5 != NULL) + dbh_insertar_registro(*p3, p1, p4, ++p5); /* salto : */ + else + dbh_eliminar_registro(*p3, p4); + } + } + + dbh_cerrar_tabla(f); + + dbh_leer_version(tabla); + tabla_serie[tabla] = num; + } + + /* + * dbh_borrar_tabla (tabla, version) + * + * borra la tabla de disco, guarda version en disco, marca + * todos los registros como borrados en memoria. + * 1999/06/21 savage@apostols.org + */ + void dbh_borrar_tabla(char tabla, unsigned long version) + { + FILE *f; + struct dbh_reg *reg; + int i; + + f = dbh_abrir_tabla(tabla, "w"); /* esto truncara la tabla */ + dbh_cerrar_tabla(f); + + dbh_guardar_version(tabla, version); + + if (!tabla_residente[tabla]) + return; /* no esta en memoria, no hace falta */ + + for (i = 0; i < DBH_HASH_SIZE; i++) + for (reg = tabla_datos[tabla][i]; reg != NULL; reg = reg->next) + reg->borrado = 1; + + return; + } + + /* + * dbh_compactar_tabla (tabla, version, serie, hash) + * + * compacta la tabla de disco, guarda version en disco, + * si la hash no coincide borra la tabla. + * 1999/06/21 savage@apostols.org + */ + void dbh_compactar_tabla(char tabla, unsigned long version, unsigned long serie, + unsigned long hash) + { + FILE *n, *o; + struct dbh_reg *reg; + unsigned long i, j = 0; + char resi; + char *rtxt; + char *p; + char tmp1[1024], tmp2[1024]; + + resi = tabla_residente[tabla]; + + /* creamos una tabla nueva */ + n = dbh_abrir_tabla('-', "w"); + o = dbh_abrir_tabla(tabla, "r"); + + if (!resi) + dbh_cargar_tabla(tabla); /* Hacemos residente la tabla un momento */ + + /* pongo los flags de compactacion a 0 */ + for (i = 0; i < DBH_HASH_SIZE; i++) + for (reg = tabla_datos[tabla][i]; reg != NULL; reg = reg->next) + reg->compactado = 0; + + /* + * recorremos la tabla y si el registro esta en memoria, + * lo metemos de nuevo en la tabla + */ + for (i = 1; i < tabla_serie[tabla]; i++) + { + if ((rtxt = dbh_leer_registro(o, i)) != NULL) + { + p = strtok(rtxt, " "); /* destino */ + p = strtok(NULL, " "); /* serie */ + p = strtok(NULL, " "); /* tabla */ + p = strtok(NULL, " \n\r"); /* clave */ + if (p && ((reg = dbh_buscar_registro(tabla, p)) != NULL) + && reg->compactado == 0) + { + reg->compactado = 1; + fprintf(n, "%s %lu %c %s :%s\n", reg->destino, ++j, tabla, p, + reg->valor); + } + } + } + + dbh_cerrar_tabla(o); + dbh_cerrar_tabla(n); + + /* en cualquier caso actualizo version */ + dbh_guardar_version(tabla, version); + + /* calculo si ha sido correcto */ + sprintf(tmp1, "%s/tabla.%c", DBPATH, tabla); + sprintf(tmp2, "%s/tabla.%c", DBPATH, '-'); /* tabla temporal */ + if (hash == dbh_hash_tabla('-') && j == serie) + { + unlink(tmp1); + rename(tmp2, tmp1); + } + else + { + unlink(tmp2); + dbh_borrar_tabla(tabla, version); /* pone a 0 la serie */ + dbh_eliminar_borrados(tabla); /* limpia de verdad con RunFree() */ + return; + } + + if (!resi) + { + /* no era residente, la elimino de memoria aunque haya funcionado */ + for (i = 0; i < DBH_HASH_SIZE; i++) + for (reg = tabla_datos[tabla][i]; reg != NULL; reg = reg->next) + reg->borrado = 1; + dbh_eliminar_borrados(tabla); + } + + return; + } + + /* + * m_dbq + * + * parv[0] = prefijo del enviador + * parv[1..] = argumentos de DBQ [] + * + * Maneja los mensajes DBQ recibidos de users y servers. + * 1999/10/13 savage@apostols.org + */ + int m_dbq(aClient *cptr, aClient *sptr, int parc, char *parv[]) + { + char tabla, *clave, *servidor; + aClient *acptr; + struct dbh_reg *reg; + + if (!IsServer(sptr) && !IsOper(sptr) && !IsHelpOp(sptr)) + return 0; /* No autorizado */ + + /* DBQ [] */ + if (parc != 3 && parc != 4) + { + + if (!IsServer(sptr)) + sendto_one(cptr, + ":%s NOTICE %s :Parametros incorrectos: Formato: DBQ [] ", + me.name, parv[0]); + return 0; + } + + if (parc == 3) + { + servidor = NULL; /* no nos indican server */ + tabla = *parv[1]; + clave = parv[2]; + } + else + { + servidor = parv[1]; + tabla = *parv[2]; + clave = parv[3]; + + if (*servidor == '*') + { + /* WOOW, BROADCAST */ + sendto_serv_butone(cptr, ":%s DBQ * %c %s", parv[0], tabla, clave); + } + else + { + /* NOT BROADCAST */ + if (!(acptr = find_match_server(servidor))) + { + /* joer, el server de destino no existe */ + sendto_one(cptr, err_str(ERR_NOSUCHSERVER), me.name, parv[0], servidor); + return 0; + } + + if (!IsMe(acptr)) /* no es para mi, a rutar */ + { + sendto_one(acptr, ":%s DBQ %s %c %s", parv[0], servidor, tabla, clave); + return 0; /* ok, rutado, fin del trabajo */ + } + } + } + + if (!tabla_residente[tabla]) + { + if (MyUser(sptr) || Protocol(cptr) < 10) + sendto_one(cptr, ":%s NOTICE %s :DBQ ERROR TABLA_NO_RESIDENTE", + me.name, parv[0]); + else + sendto_one(cptr, "%s NOTICE %s%s :DBQ ERROR TABLA_NO_RESIDENTE", + NumServ(&me), NumNick(sptr)); + return 0; + } + + reg = dbh_buscar_registro(tabla, clave); + if (!reg) + { + if (MyUser(sptr) || Protocol(cptr) < 10) + sendto_one(cptr, ":%s NOTICE %s :DBQ ERROR REGISTRO_NO_ENCONTRADO", + me.name, parv[0]); + else + sendto_one(cptr, "%s NOTICE %s%s :DBQ ERROR REGISTRO_NO_ENCONTRADO", + NumServ(&me), NumNick(sptr)); + return 0; + } + + if (MyUser(sptr) || Protocol(cptr) < 10) + sendto_one(cptr, + ":%s NOTICE %s :DBQ OK Tabla='%c' Destino='%s' Clave='%s' Valor='%s'", + me.name, parv[0], tabla, reg->destino, reg->clave, reg->valor); + else + sendto_one(cptr, + "%s NOTICE %s%s :DBQ OK Tabla='%c' Destino='%s' Clave='%s' Valor='%s'", + NumServ(&me), NumNick(sptr), tabla, reg->destino, reg->clave, + reg->valor); + + return 0; + } + + /* + * m_dbh + * + * parv[0] = prefijo del enviador + * parv[1..] = argumentos de DBH + * + * Maneja los mensajes DBH recibidos por los servers. + * 1999/06/20 savage@apostols.org + */ + int m_dbh(aClient *cptr, aClient *sptr, int parc, char *parv[]) + { + unsigned long numserie, numversion, i, hash; + unsigned int j; + char tabla; + aClient *acptr; + Dlink *lp; + char db_buf[1024], *reg; + FILE *db_file; + int es_hub = 0; + + if (!IsServer(sptr)) + { + if (!IsOper(sptr) && !IsHelpOp(sptr)) + return 0; + + sendto_one(cptr, + ":%s NOTICE %s :Comando obsoleto, utiliza DBQ [] ", + me.name, parv[0]); + return 0; + } + + if (find_conf_host(cptr->confs, cptr->name, CONF_HUB) != NULL) + es_hub = 1; /* El remoto es un Hub */ + + numserie = atol(parv[2]); /* solo != 0 en registros */ + + if (!numserie) + { + switch (*parv[3]) + { + case 'B': + /* DBH 0 B */ + /* No rutable, solo hub-nodo: sera para nosotros */ + if (!es_hub || parc != 7) + { + /* + * Un nodo idiota nos envia un "continua burst", + * avisamos a los ircops + */ + dbh_violacion(parc, parv, "Origen no Hub o Parametros incorrectos"); + break; + } + + tabla = *parv[4]; + numversion = atol(parv[5]); + numserie = atol(parv[6]); + + if (numversion == tabla_version[tabla] + && numserie == tabla_serie[tabla]) + { + /* + * parece que llegamos al final, ya podemos eliminar de memoria + * los registros marcados para borrar ... + */ + dbh_eliminar_borrados(tabla); + break; + } + + /* le contestamos con 0 J para que continue */ + sendto_one(sptr, "%s %s - 0 J %c %lu %lu", + NumServ(&me), MSG_DBH, + tabla, tabla_version[tabla], tabla_serie[tabla]); + break; + + case 'J': + /* DBH 0 J */ + /* No rutable, solo nodo-nodo: sera para nosotros */ + if (parc != 7) + { + /* parametros incorrectos, avisamos */ + dbh_violacion(parc, parv, "Parametros incorrectos"); + break; + } + + tabla = *parv[4]; + numversion = atol(parv[5]); + numserie = atol(parv[6]); + + /* Parece ke no estamos en la version correcta */ + if (numversion > tabla_version[tabla] && es_hub) + { + /* me perdi un COMMIT .... */ + dbh_violacion(parc, parv, + "Hub con version Superior. Borrando DB local ..."); + dbh_borrar_tabla(tabla, numversion); + /* le contestamos con 0 J para que continue o pare */ + /* y al resto de nodos para que se enteren de la nueva version */ + for (lp = me.serv->down; lp; lp = lp->next) + sendto_one(sptr, "%s %s - 0 J %c %lu %lu", + NumServ(&me), MSG_DBH, tabla, tabla_version[tabla], 0); + break; + } + #ifdef HUB + if (numversion > tabla_version[tabla] && !es_hub) + { + /* el nodo es un mamon, con version superior, ordeno borrado */ + /* tambien podria ser ke yo me perdiera algo, pero ... shit hapens */ + dbh_violacion(parc, parv, + "Nodo con version Superior. Borrando DB remota ..."); + sendto_one(sptr, "%s %s %s 0 D %c %lu", NumServ(&me), MSG_DBH, + parv[0], tabla, tabla_version[tabla]); + break; + } + + if (numversion < tabla_version[tabla]) + { + /* El remoto se perdio un compromiso */ + dbh_violacion(parc, parv, + "Remoto con version Inferior. Actualizando DB remota ..."); + /* + * El remoto se dara cuenta, y borrara su version vieja. + * Esto provocara un nuevo msg 0 J con version adecuada y serie 0 + * pero hasta que esto suceda, yo paso de enviarle nada .... + */ + break; + } + + /* + * Fantastico, hablamos sobre al misma version, + * a ver si tengo que actualizarle ... + */ + + if (numserie >= tabla_serie[tabla]) + break; /* El remoto es mas nuevo que nosotros o ya esta ok */ + + /* abrimos la tabla */ + db_file = dbh_abrir_tabla(tabla, "r"); + + for (j = 0, i = numserie + 1; + db_file && i <= tabla_serie[tabla] && j < 25; i++, j++) + { + char *reg; + + reg = dbh_leer_registro(db_file, i); + if (reg) + { + sendto_one(sptr, "%s %s %s", NumServ(&me), MSG_DBH, reg); + } + } + + dbh_cerrar_tabla(db_file); + + /* Enviamos el '0 B' para que el otro se entere si hemos terminado */ + sendto_one(sptr, "%s %s - 0 B %c %lu %lu", + NumServ(&me), MSG_DBH, + tabla, tabla_version[tabla], tabla_serie[tabla]); + #endif /* HUB */ + + break; + + case 'q': + /* DBH 0 q */ + /* Rutable, debemos buscar destino */ + #ifdef HUB + if (parc != 8) + { + /* parametros incorrectos, avisamos */ + dbh_violacion(parc, parv, "Parametros incorrectos"); + break; + } + + /* lo dejo pasar hacia destino, no puede ser para mi */ + if (!(acptr = find_match_server(parv[1]))) + { + /* joer, el server de destino no existe */ + sendto_one(sptr, err_str(ERR_NOSUCHSERVER), me.name, parv[0], + parv[1]); + break; + } + + if (IsMe(acptr)) + { + /* + * Un nodo/hub idiota nos contesta sobre una tabla, + * no hace falta avisar ... + */ + break; + } + else + sendto_one(acptr, "%s %s %s 0 q %s %s %s %s", + NumServ(sptr), MSG_DBH, acptr->name, + parv[4], parv[5], parv[6], parv[7]); + #endif /* HUB */ + break; + + case 'Q': + /* DBH /<*> 0 Q */ + /* Rutable y Broadcast: tendre ke mirar destino */ + if (!es_hub || parc != 5) + { + /* + * Un nodo idiota nos interroga sobre una tabla, + * avisamos a los ircops + */ + dbh_violacion(parc, parv, "Origen no Hub o Parametros incorrectos"); + break; + } + #ifdef HUB + /* + * Si es un wildcard lo propago a todos + */ + if (*parv[1] == '*') + { + for (lp = me.serv->down; lp; lp = lp->next) + { + if (lp->value.cptr == cptr) + continue; /* al que nos lo envia, no se lo reenvio */ + sendto_one(lp->value.cptr, "%s %s %s 0 Q %s", + parv[0], MSG_DBH, parv[1], parv[4]); + } + } + else + { + /* + * Pues no, no es un wilcard, busco destino ... + */ + if (!(acptr = find_match_server(parv[1]))) + { + /* joer, el server de destino no existe */ + sendto_one(sptr, err_str(ERR_NOSUCHSERVER), me.name, parv[0], + parv[1]); + break; + } + + if (!IsMe(acptr)) + { + sendto_one(acptr, "%s %s %s 0 Q %s\n", + NumServ(sptr), MSG_DBH, acptr->name, parv[4]); + break; + } + } + #endif /* HUB */ + + /* bueno, este 0 Q es para mí (o wilcard), a contestar ... */ + tabla = *parv[4]; + sendto_one(sptr, "%s %s %s 0 q %c %lu %lu %lu\n", + NumServ(&me), MSG_DBH, parv[0], + tabla, tabla_version[tabla], tabla_serie[tabla], + dbh_hash_tabla(tabla)); + break; + + case 'D': + /* DBH 0 D */ + /* Rutable: tendre que buscar destino */ + if (!es_hub || parc != 6) + { + /* + * Un nodo idiota intenta borrarnos una tabla, + * avisamos a los ircops + */ + dbh_violacion(parc, parv, "Origen no Hub o Parametros incorrectos"); + break; + } + #ifdef HUB + if (!(acptr = find_match_server(parv[1]))) + { + /* joer, el server de destino no existe */ + sendto_one(sptr, err_str(ERR_NOSUCHSERVER), me.name, parv[0], + parv[1]); + break; + } + + if (!IsMe(acptr)) + { + sendto_one(acptr, "%s %s %s 0 D %s %s\n", + NumServ(sptr), MSG_DBH, acptr->name, parv[4], parv[5]); + break; + } + #endif /* HUB */ + + /* pues alguien me ordena borrar una tabla */ + tabla = *parv[4]; + numversion = atol(parv[5]); + dbh_borrar_tabla(tabla, numversion); + + /* envio un 0 J para solicitar registros nuevos */ + sendto_one(sptr, "%s %s - 0 J %c %lu %lu", + NumServ(&me), MSG_DBH, + tabla, tabla_version[tabla], tabla_serie[tabla]); + break; + + case 'C': + /* DBH <*> 0 C */ + /* Broadcast: tengo que propagarlo a todos */ + if (!es_hub || parc != 8 || *parv[1] != '*') + { + /* + * Un nodo idiota intenta compactarnos una tabla, + * avisamos a los ircops + */ + dbh_violacion(parc, parv, "Origen no Hub o Parametros incorrectos"); + break; + } + + #ifdef HUB + /* + * Propago compactacion a todos mis nodos + */ + for (lp = me.serv->down; lp; lp = lp->next) + { + if (lp->value.cptr == cptr) + continue; /* al que nos lo envia, no se lo reenvio */ + sendto_one(lp->value.cptr, "%s %s %s 0 C %s %s %s %s", + parv[0], MSG_DBH, parv[1], parv[4], parv[5], parv[6], parv[7]); + } + #endif + tabla = *parv[4]; + numversion = atol(parv[5]); + numserie = atol(parv[6]); + hash = atol(parv[7]); + dbh_compactar_tabla(tabla, numversion, numserie, hash); + /* Enviamos el '0 J' para informar / pedir mas */ + sendto_one(sptr, "%s %s - 0 J %c %lu %lu", + NumServ(&me), MSG_DBH, + tabla, tabla_version[tabla], tabla_serie[tabla]); + break; + + default: + return 0; /* Orden incorrecta, ni puto caso */ + } + + /* orden procesada */ + return 0; + } + + /* Si llegamos aqui, se trata de un registro */ + /* parv[0] parv[1] parv[2] parv[3] parv[4] parv[5] */ + /* DBH /<*> [:] */ + /* Broadcast: tengo que propagarlo a todos */ + + if (!es_hub || parc < 5) + { + /* + * Un nodo idiota nos envia un registro, + * avisaremos a los operadores o a los services + */ + dbh_violacion(parc, parv, "Origen no Hub o Parametros incorrectos"); + return 0; + } + + /* Procesamos un registro */ + tabla = *parv[3]; + if (numserie != (tabla_serie[tabla] + 1)) + { + /* + * carambas, un registro atrasado o adelantado ... lo ignoro ... + * no me interesa ni a mi ni a nadie que cuelgue de mi. + */ + return 0; + } + + #ifdef HUB + /* + * Propago el registro ... + */ + if (parc == 6) + sprintf_irc(db_buf, "%s %s %s %s %s %s :%s", + NumServ(sptr), MSG_DBH, parv[1], parv[2], parv[3], parv[4], parv[5]); + else + sprintf_irc(db_buf, "%s %s %s %s %s %s", + NumServ(sptr), MSG_DBH, parv[1], parv[2], parv[3], parv[4]); + + for (lp = me.serv->down; lp; lp = lp->next) + { + if (lp->value.cptr == cptr) + continue; /* al que nos lo envia, no se lo reenvio */ + sendto_one(lp->value.cptr, db_buf); + } + #endif /* HUB */ + + /* + * meto el registro en la tabla de disco + * lo meto en un formato aprovechable en los burst + */ + db_file = dbh_abrir_tabla(tabla, "a"); + if (!db_file) + return 0; /* que paso ? deberia informar error %m */ + alarm(3); + if (parc == 6) + fprintf(db_file, "%s %lu %c %s :%s\n", + parv[1], numserie, tabla, parv[4], parv[5]); + else + fprintf(db_file, "%s %lu %c %s\n", parv[1], numserie, tabla, parv[4]); + dbh_cerrar_tabla(db_file); + alarm(0); + + /* + * Actualizo la serie en memoria + */ + tabla_serie[tabla]++; + + /* + * Meto el registro en memoria si es una tabla residente + */ + if (tabla_residente[tabla]) + { + if (parc == 6) + dbh_insertar_registro(tabla, parv[1], parv[4], parv[5]); + else + dbh_eliminar_registro(tabla, parv[4]); + } + + /* orden procesada */ + return 0; + } + + /* + * dbh_recarga () + * + * Recarga la base de datos (carga todas las tablas) + * 1999/06/28 savage@apostols.org + */ + void dbh_recarga() + { + unsigned char i; + unsigned int j; + struct dbh_reg *reg; + + sendto_ops("Recargando tablas DBH"); + for (i = DBH_PRIMERA_TABLA; i <= DBH_ULTIMA_TABLA; i++) + { + /* marco todo como borrado */ + for (j = 0; j < DBH_HASH_SIZE; j++) + for (reg = tabla_datos[i][j]; reg != NULL; reg = reg->next) + reg->borrado = 1; + /* cargo de nuevo de disco */ + dbh_cargar_tabla(i); + /* elimino lo marcado */ + dbh_eliminar_borrados(i); + if (tabla_serie[i]) + sendto_ops("Tabla '%c' V:%lu S:%lu", i, tabla_version[i], tabla_serie[i]); + } + + return; + } + + /* + * dbh_inicializa () + * + * Inicailiza la base de datos (carga todas las tablas) + * 1999/06/28 savage@apostols.org + */ + void dbh_inicializa() + { + unsigned char i; + + /* --------------------------------------------------- */ + memset(tabla_residente, 0, sizeof(tabla_residente)); + memset(tabla_cuantos, 0, sizeof(tabla_cuantos)); + memset(tabla_datos, 0, sizeof(tabla_datos)); + memset(tabla_version, 0, sizeof(tabla_version)); + memset(tabla_serie, 0, sizeof(tabla_serie)); + /* --------------------------------------------------- */ + + /* + * Hago residentes las tablas necesarias para los parches + */ + tabla_residente[DBH_NICKDB] = 1; + tabla_residente[DBH_OPERDB] = 1; + tabla_residente[DBH_CHANDB] = 1; + tabla_residente[DBH_BOTSDB] = 1; + tabla_residente[DBH_VIRTUALDB] = 1; + + /* --------------------------------------------------- */ + for (i = DBH_PRIMERA_TABLA; i <= DBH_ULTIMA_TABLA; i++) + dbh_cargar_tabla(i); + + return; + } + + #endif /* DB_HISPANO */ + + #endif /* S_BDD.C */ Index: ../ircu2.10.06/ircd/s_bsd.c =================================================================== RCS file: /cvsroot/ircd/ircd/s_bsd.c,v retrieving revision 1.14 diff -c -c -r1.14 s_bsd.c *** ../ircu2.10.06/ircd/s_bsd.c 1999/10/15 08:24:25 1.14 --- ../ircu2.10.06/ircd/s_bsd.c 1999/10/21 22:40:37 *************** *** 70,75 **** --- 70,78 ---- #include "numeric.h" #include "send.h" #include "s_conf.h" + #if defined(DB_ESNET) || defined(DB_HISPANO) + #include "s_bdd.h" + #endif #include "s_misc.h" #include "s_bsd.h" #include "hash.h" Index: ../ircu2.10.06/ircd/s_debug.c =================================================================== RCS file: /cvsroot/ircd/ircd/s_debug.c,v retrieving revision 1.62 diff -c -c -r1.62 s_debug.c *** ../ircu2.10.06/ircd/s_debug.c 1999/10/19 18:02:34 1.62 --- ../ircu2.10.06/ircd/s_debug.c 1999/10/21 22:40:37 *************** *** 191,197 **** '-', #endif #endif ! 'D','B','3','9', #ifdef DB_ESNET '+', #else --- 191,197 ---- '-', #endif #endif ! 'D','B','4','0', #ifdef DB_ESNET '+', #else Index: ../ircu2.10.06/ircd/s_serv.c =================================================================== RCS file: /cvsroot/ircd/ircd/s_serv.c,v retrieving revision 1.44 diff -c -c -r1.44 s_serv.c *** ../ircu2.10.06/ircd/s_serv.c 1999/10/19 18:02:34 1.44 --- ../ircu2.10.06/ircd/s_serv.c 1999/10/21 22:40:37 *************** *** 23,37 **** #include "sys.h" #include - - #if defined(DB_ESNET) || defined(DB_HISPANO) - #include - #include - #include - #include - #include - #endif - #include "h.h" #include "struct.h" #include "ircd.h" --- 23,28 ---- *************** *** 45,50 **** --- 36,45 ---- #include "s_conf.h" #include "hash.h" #include "common.h" + #if defined(DB_ESNET) || defined(DB_HISPANO) + #include "s_bdd.h" + #include "msg.h" + #endif #include "match.h" #include "crule.h" #include "parse.h" *************** *** 57,77 **** RCSTAG_CC("$Id: s_serv.c,v 1.81 1999/10/04 15:08:16 foxxe Exp $"); - #if defined(DB_ESNET) || defined(DB_HISPANO) - #include "msg.h" - #include "support.h" - /* - * Las tablas con los registros, serie, version ... - */ - int tabla_residente[DBH_MAX_TABLA]; - unsigned long tabla_cuantos[DBH_MAX_TABLA]; - struct dbh_reg *tabla_datos[DBH_MAX_TABLA][DBH_HASH_SIZE]; - unsigned long tabla_version[DBH_MAX_TABLA]; - unsigned long tabla_serie[DBH_MAX_TABLA]; - unsigned long tabla_hash_hi[DBH_MAX_TABLA]; - unsigned long tabla_hash_lo[DBH_MAX_TABLA]; - #endif /* DB_ESNET || DB_HISPANO */ - static int exit_new_server(aClient *cptr, aClient *sptr, char *host, time_t timestamp, char *fmt, ...) --- 52,57 ---- *************** *** 1180,3312 **** } return 0; } - - #if defined(DB_ESNET) || defined(DB_HISPANO) - /* - * TEA (cifrado) - * - * Cifra 64 bits de datos, usando clave de 64 bits (los 64 bits superiores son cero) - * Se cifra v[0]^x[0], v[1]^x[1], para poder hacer CBC facilmente. - * - */ - void tea(unsigned long v[], unsigned long k[], unsigned long x[]) - { - unsigned long y = v[0] ^ x[0], z = v[1] ^ x[1], sum = 0, delta = 0x9E3779B9; - unsigned long a = k[0], b = k[1], n = 32; - unsigned long c = 0, d = 0; - - while (n-- > 0) - { - sum += delta; - y += (z << 4) + a ^ z + sum ^ (z >> 5) + b; - z += (y << 4) + c ^ y + sum ^ (y >> 5) + d; - } - - x[0] = y; - x[1] = z; - } - - void actualiza_hash(char *registro, char que_bdd) - { - unsigned long buffer[129 * sizeof(unsigned long)]; - unsigned long *p = buffer; - unsigned long x[2], v[2], k[2]; - char *p2; - - /* - ** Calculamos el HASH - */ - memset(buffer, 0, sizeof(buffer)); - strncpy((char *)buffer, registro, sizeof(buffer) - 1); - while ((p2 = strchr((char *)buffer, '\n'))) - *p2 = '\0'; - while ((p2 = strchr((char *)buffer, '\r'))) - *p2 = '\0'; - k[0] = k[1] = 0; - x[0] = tabla_hash_hi[que_bdd]; - x[1] = tabla_hash_lo[que_bdd]; - while (*p) - { - v[0] = ntohl(*p++); - v[1] = ntohl(*p++); - tea(v, k, x); - } - tabla_hash_hi[que_bdd] = x[0]; - tabla_hash_lo[que_bdd] = x[1]; - } - - /* - * dbh_eliminar_borrados (tabla) - * - * libera (free) todos los registros con marca 'borrados' de memoria. - * 1999/06/21 savage@apostols.org - */ - void dbh_eliminar_borrados(char tabla) - { - FILE *f; - struct dbh_reg *reg; - int i; - - tabla_cuantos[tabla] = 0; - - for (i = 0; i < DBH_HASH_SIZE; i++) - for (reg = tabla_datos[tabla][i]; reg != NULL; reg = reg->next) - if (reg->borrado) - { - if (reg->prev) - reg->prev->next = reg->next; - else - tabla_datos[tabla][i] = reg->next; /* era el primero */ - if (reg->next) - reg->next->prev = reg->prev; - if (reg->clave) - RunFree(reg->clave); - if (reg->valor) - RunFree(reg->valor); - RunFree(reg); - } - else - tabla_cuantos[tabla]++; - - return; - } - - /* - * dbh_eliminar_registro (tabla, clave) - * - * libera (free) un registro de memoria. - * 1999/06/23 savage@apostols.org - */ - void dbh_eliminar_registro(char tabla, char *clave) - { - struct dbh_reg *reg; - int hashi, i = 0; - char *c; - - c = RunMalloc(strlen(clave) + 1); - if (c == NULL) - return; - strcpy(c, clave); - /* paso a minusculas */ - while (c[i] != 0) - { - c[i] = toLower(c[i]); - i++; - } - - hashi = dbh_hash_registro(c); - - for (reg = tabla_datos[tabla][hashi]; reg != NULL; reg = reg->next) - if (!strcmp(reg->clave, c)) - { - /* - sendto_ops("Elimino T='%c' C='%s' H=%u",tabla, reg->clave, hashi ); - */ - if (reg->prev) - reg->prev->next = reg->next; - else - tabla_datos[tabla][hashi] = reg->next; /* era el primero */ - - if (reg->next) - reg->next->prev = reg->prev; - - if (reg->clave) - RunFree(reg->clave); - if (reg->valor) - RunFree(reg->valor); - RunFree(reg); - tabla_cuantos[tabla]--; - break; - } - - RunFree(c); - - return; - } - - /* - * dbh_insertar_registro (tabla, destino, clave, valor) - * - * mete un registro en memoria ... - * 1999/06/23 savage@apostols.org - */ - void dbh_insertar_registro(char tabla, char *destino, char *clave, char *valor) - { - struct dbh_reg *reg, *rh; - int hashi; - char *c, *v, *d; - aClient *acptr; - int i = 0; - - /* lo borro primero, por si es un cambio */ - dbh_eliminar_registro(tabla, clave); - - c = RunMalloc(strlen(clave) + 1); - if (!c) - return; - v = RunMalloc(strlen(valor) + 1); - if (!v) - { - RunFree(c); - return; - } - d = RunMalloc(strlen(destino) + 1); - if (!d) - { - RunFree(c); - RunFree(v); - return; - } - - reg = RunMalloc(sizeof(struct dbh_reg)); - if (!reg) - { - RunFree(c); - RunFree(v); - RunFree(d); - return; - } - - strcpy(c, clave); - strcpy(v, valor); - strcpy(d, destino); - - /* paso a minusculas */ - while (c[i] != 0) - { - c[i] = toLower(c[i]); - i++; - } - - /* creo el registro */ - reg->clave = c; - reg->valor = v; - reg->destino = d; - reg->next = reg->prev = NULL; - reg->borrado = 0; - reg->compactado = 0; - - /* marco como local si es para mi o broadcast */ - if (*d == '*' || ((acptr = find_match_server(d)) && (IsMe(acptr)))) - reg->local = 1; - else - reg->local = 0; - - /* busco hash */ - hashi = dbh_hash_registro(reg->clave); - - /* - sendto_ops("Inserto T='%c' C='%s' H=%u",tabla, reg->clave, hashi ); - */ - - rh = tabla_datos[tabla][hashi]; - tabla_datos[tabla][hashi] = reg; - reg->next = rh; - if (rh) - rh->prev = reg; - - tabla_cuantos[tabla]++; - - return; - } - - /* - * dbh_buscar_registro (tabla, clave) - * - * busca un registro en memoria ... - * 1999/06/23 savage@apostols.org - */ - struct dbh_reg *dbh_buscar_registro(char tabla, char *clave) - { - struct dbh_reg *reg; - int hashi, i = 0; - char *c; - - c = RunMalloc(strlen(clave) + 1); - if (c == NULL) - return; - strcpy(c, clave); - /* paso a minusculas */ - while (c[i] != 0) - { - c[i] = toLower(c[i]); - i++; - } - - /* busco hash */ - hashi = dbh_hash_registro(c); - - /* - sendto_ops("Busco T='%c' C='%s' H=%u",tabla, c, hashi ); - */ - - for (reg = tabla_datos[tabla][hashi]; reg != NULL; reg = reg->next) - if (!strcmp(reg->clave, c)) - { - RunFree(c); - return reg; - } - RunFree(c); - return NULL; - } - - /* - * dbh_buscar_registro_local (tabla, clave) - * - * busca un registro local en memoria ... - * 1999/06/23 savage@apostols.org - */ - struct dbh_reg *dbh_buscar_registro_local(char tabla, char *clave) - { - struct dbh_reg *reg; - - reg = dbh_buscar_registro(tabla, clave); - if (!reg) - return NULL; - - if (reg->local) - return reg; - else - return NULL; - } - - /* - * dbh_es_miembro (tabla, clave, subcadena) - * - * varor registro es una lista separada por comas, y si subcadena es - # una de ellas, retorna la posicion, sino 0 - * 1999/07/03 savage@apostols.org - */ - int dbh_es_miembro(char tabla, char *clave, char *subcadena) - { - int j, i = 0; - char *buff, *f, *s = NULL; - struct dbh_reg *reg; - - if ((reg = dbh_buscar_registro_local(tabla, clave)) == NULL) - return 0; - - buff = RunMalloc(strlen(reg->valor) + 1); - if (!buff) - return 0; - - strcpy(buff, reg->valor); - for (f = strtoken(&s, buff, ","); f != NULL; f = strtoken(&s, NULL, ",")) - { - j++; - if (!strCasediff(f, subcadena)) - { - i++; - break; - } - } - - RunFree(buff); - return i; - } - - #endif /* defined(DB_ESNET) || defined(DB_HISPANO) */ - - /* - ** Esta rutina mata el servidor. - ** Es casi una copia de m_die(). - */ - extern char **myargv; /* ircd.c */ - void db_die(char *msg, char que_bdd) - { - aClient *acptr; - int i; - char buf[1024]; - - sprintf_irc(buf, "DB '%c' - %s. El daemon muere...", que_bdd, msg); - for (i = 0; i <= highest_fd; i++) - { - if (!(acptr = loc_clients[i])) - continue; - if (IsUser(acptr)) - sendto_one(acptr, ":%s NOTICE %s :%s", me.name, acptr->name, buf); - else if (IsServer(acptr)) - sendto_one(acptr, ":%s ERROR :%s", me.name, buf); - } - - #ifndef USE_SYSLOG - openlog(myargv[0], LOG_PID | LOG_NDELAY, LOG_DAEMON); - #endif - - syslog(LOG_ERR, buf); - - #ifndef USE_SYSLOG - closelog(); - #endif - - Debug((DEBUG_ERROR, buf)); - - #ifdef __cplusplus - s_die(0); - #else - s_die(); - #endif - } - - #ifdef DB_ESNET - /* - * leer_db - * - * Lee un registro de la base de datos. - * - */ - int leer_db(struct tabla_en_memoria *mapeo, char *buf) - { - int cont = 0; - int estado; - char *p = mapeo->posicion + mapeo->len; - - while (mapeo->puntero_r < p) - { - *buf = *(mapeo->puntero_r++); - if (*buf == '\r') - continue; - if ((*buf++ == '\n')) - { - *--buf = '\0'; - return cont; - } - if (cont++ > 500) - break; - } - *buf = '\0'; - return -1; - } - - /* - ** Seek por bidivision - */ - int seek_db(struct tabla_en_memoria *mapeo, char *buf, unsigned long registro) - { - char *p, *p2, *plo, *phi; - unsigned long v; - - /* - ** Este caso especial es lo bastante - ** comun como para que se tenga en cuenta. - */ - if (!registro) - { - mapeo->puntero_r = mapeo->posicion; - return leer_db(mapeo, buf); - } - - plo = mapeo->posicion; - phi = plo + mapeo->len; - while (plo != phi) - { - /* - ** p apunta al principio del registro - ** p2 apunta al registro siguiente - */ - p2 = p = plo + (phi - plo) / 2; - while ((p >= plo) && (*p != '\n')) - p--; - if (p < plo) - p = plo; - if (*p == '\n') - p++; - while ((p2 < phi) && (*p2++ != '\n')); - /* - ** Estamos al principio de un registro - */ - v = atol(p); - if (v > registro) - phi = p; - else if (v < registro) - plo = p2; - else - { - plo = phi = p; /* Encontrado */ - break; - } - } - mapeo->puntero_r = plo; - return leer_db(mapeo, buf); - } - - /* - * abrir_db - * - * Se mueve hasta un registro de la base de datos - * - */ - int abrir_db(unsigned long registro, char *buf, char que_bdd, - struct tabla_en_memoria *mapeo) - { - int handle; - int cont; - char path[1024]; - struct stat estado; - - *buf = '\0'; - sprintf_irc(path, "%s/tabla.%c", DBPATH, que_bdd); - alarm(3); - handle = open(path, O_RDONLY, S_IRUSR | S_IWUSR); - fstat(handle, &estado); - mapeo->len = estado.st_size; - mapeo->posicion = mmap(NULL, mapeo->len, - PROT_READ, MAP_SHARED | MAP_NORESERVE, handle, 0); - close(handle); - alarm(0); - mapeo->puntero_r = mapeo->puntero_w = mapeo->posicion; - - if (handle == -1) - db_die("Error al intentar leer (open)", que_bdd); - if ((mapeo->len != 0) && (mapeo->posicion == MAP_FAILED)) - db_die("Error al intentar leer (mmap)", que_bdd); - - if ((handle == -1) || (mapeo->posicion == MAP_FAILED)) - return -1; - - cont = seek_db(mapeo, buf, registro); - if (cont == -1) - { - *buf = '\0'; - return -1; - } - return handle; - } - - void cerrar_db(struct tabla_en_memoria *mapeo) - { - munmap(mapeo->posicion, mapeo->len); - } - - /* - ** almacena_hash - ** - ** El fichero de HASHES contiene una linea - ** por BDD. Cada linea tiene el formato - ** "BDD HASH\n" - ** En total, cada linea mide 15 bytes. - */ - void almacena_hash(char que_bdd) - { - char path[1024]; - char hash[20]; - int db_file; - - sprintf_irc(path, "%s/hashes", DBPATH); - inttobase64(hash, tabla_hash_hi[que_bdd], 6); - inttobase64(hash + 6, tabla_hash_lo[que_bdd], 6); - alarm(3); - db_file = open(path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); - if (db_file == -1) - db_die("Error al intentar guardar hashes (open)", que_bdd); - sprintf_irc(path, "%c %s\n", que_bdd, hash); - if (lseek(db_file, 15 * (que_bdd - ESNET_BDD), SEEK_SET) == -1) - db_die("Error al intentar guardar hashes (lseek)", que_bdd); - if (write(db_file, path, strlen(path)) == -1) - db_die("Error al intentar guardas hashes (write)", que_bdd); - close(db_file); - alarm(0); - } - - /* - ** lee_hash - */ - void lee_hash(char que_bdd, unsigned long *hi, unsigned long *lo) - { - char path[1024]; - char c; - int db_file; - - sprintf_irc(path, "%s/hashes", DBPATH); - alarm(3); - db_file = open(path, O_RDONLY); - /* - ** No metemos verificacion, porque ya verifica - ** al contrastar el hash. - */ - lseek(db_file, 15 * (que_bdd - ESNET_BDD) + 2, SEEK_SET); - read(db_file, path, 12); - close(db_file); - alarm(0); - path[12] = '\0'; - c = path[6]; - path[6] = '\0'; - *hi = base64toint(path); - path[6] = c; - *lo = base64toint(path + 6); - } - - /* - * db_alta - * - * Da de alta una entrada en la base de datos en memoria - * Formato "serie destino id clave contenido" - * - * modificado para usar las hash con funciones dbh_* - * 1999/06/30 savage@apostols.org - */ - void db_alta(char *registro, char que_bdd, int guarda_hash) - { - char *p0, *p1, *p2, *p3, *p4; - - actualiza_hash(registro, que_bdd); - - if (guarda_hash) - almacena_hash(que_bdd); - - p0 = strtok(registro, " "); /* serie */ - p1 = strtok(NULL, " "); /* destino */ - p2 = strtok(NULL, " "); /* tabla */ - p3 = strtok(NULL, " \r\n"); /* clave */ - p4 = strtok(NULL, "\r\n"); /* valor (opcional) */ - - if (p3 == NULL) - return; /* registro incompleto */ - - tabla_serie[que_bdd] = atol(p0); - - if (tabla_residente[que_bdd]) - { - if (p4 == NULL) /* Borrado */ - dbh_eliminar_registro(que_bdd, p3); - else - dbh_insertar_registro(que_bdd, p1, p3, p4); - } - } - - /* - ** db_pack - ** - ** Elimina los registro superfluos - ** de una Base de Datos Local. - ** - ** Se invoca cuando re recibe un CheckPoint, y el - ** formato es "serie destino id * texto" - */ - void db_pack(char *registro, char que_bdd) - { - int db_file; - char path[1024]; - char *map; - char *lectura, *escritura, *p; - char *clave, *valor; - char c; - unsigned long len, len2; - struct stat estado; - struct dbh_reg *reg; - - /* - ** El primer valor es el numero de serie actual - */ - tabla_serie[que_bdd] = atol(registro); - - sprintf_irc(path, "%s/tabla.%c", DBPATH, que_bdd); - alarm(3); - db_file = open(path, O_RDWR | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR); - fstat(db_file, &estado); - len = estado.st_size; - map = mmap(NULL, len, PROT_READ | PROT_WRITE, - MAP_SHARED | MAP_NORESERVE, db_file, 0); - alarm(0); - if (db_file == -1) - db_die("Error al intentar compactar (open)", que_bdd); - if ((len != 0) && (map == MAP_FAILED)) - db_die("Error al intentar compactar (mmap)", que_bdd); - - if (!tabla_residente[que_bdd]) - { /* No residente -> No pack */ - escritura = map + len; - goto fin; - } - - tabla_hash_hi[que_bdd] = 0; - tabla_hash_lo[que_bdd] = 0; - - p = lectura = escritura = map; - while (lectura < map + len) - { - p = strchr(p, ' ') + 1; /* Destino */ - p = strchr(p, ' ') + 1; /* BDD */ - valor = clave = p = strchr(p, ' ') + 1; /* Clave */ - while ((p < map + len) && (*p != '\n') && (*p != '\r')) - p++; - while ((*valor != ' ') && (valor < p)) - valor++; - valor++; /* Nos saltamos el espacio */ - - /* - ** Los registros "*" son borrados automaticamente - ** al compactar, porque no aparecen en la - ** base de datos en memoria. - ** - ** Solo se mantiene el nuevo, porque es - ** el que se graba tras la compactacion - */ - if (valor < p) - { /* Nuevo registro, no un borrado */ - *(valor - 1) = '\0'; - reg = dbh_buscar_registro_local(que_bdd, clave); - *(valor - 1) = ' '; - if (reg != NULL) - { /* El registro sigue existiendo */ - - len2 = strlen(reg->valor); - if ((valor + len2 == p) && (!strncmp(valor, reg->valor, len2))) - { /* !!El mismo!! */ - - /* - ** Actualizamos HASH - */ - if ((*p == '\n') || (*p == '\r')) - { - c = *p; - *p = '\0'; - actualiza_hash(lectura, que_bdd); - *p = c; - } - else - { /* Estamos al final y no hay retorno de carro */ - memcpy(path, lectura, p - lectura); - path[p - lectura] = '\0'; - actualiza_hash(path, que_bdd); - } - - while ((p < map + len) && ((*p == '\n') || (*p == '\r'))) - p++; - memcpy(escritura, lectura, p - lectura); - escritura += p - lectura; - lectura = p; - continue; /* MUY IMPORTANTE */ - } /* Hay otro mas moderno que este */ - } /* El registro fue borrado */ - } /* Es un borrado */ - while ((p < map + len) && ((*p == '\n') || (*p == '\r'))) - p++; - lectura = p; - } - - fin: - - munmap(map, len); - - alarm(3); - ftruncate(db_file, escritura - map); - lseek(db_file, 0, SEEK_END); - write(db_file, registro, strlen(registro)); /* CheckPoint */ - close(db_file); - alarm(0); - actualiza_hash(registro, que_bdd); - almacena_hash(que_bdd); - } - - /* - * borrar_db - * - * Borra la base de datos en memoria (modificado para uso de hash) - * - * 1999/06/30 savage@apostols.org - */ - void borrar_db(char que_bdd) - { - int i; - struct dbh_reg *reg; - - for (i = 0; i < DBH_HASH_SIZE; i++) - for (reg = tabla_datos[que_bdd][i]; reg != NULL; reg = reg->next) - reg->borrado = 1; - /* - ** Evita Memory Leak - */ - dbh_eliminar_borrados(que_bdd); - - /* Error introducido en DBH - ** BUGFIX! - */ - tabla_serie[que_bdd] = 0; - tabla_cuantos[que_bdd] = 0; - tabla_hash_hi[que_bdd] = 0; - tabla_hash_lo[que_bdd] = 0; - } - - - static void corta_si_multiples_hubs(aClient *cptr, char que_bdd, char *mensaje) - { - char buf[1024]; - Dlink *lp; - int num_hubs = 0; - aClient *acptr; - - for (lp = me.serv->down; lp; lp = lp->next) - { - if (find_conf_host(lp->value.cptr->confs, - lp->value.cptr->name, CONF_HUB) != NULL) num_hubs++; - } - - if (num_hubs >= 2) - { - - /* - ** No podemos simplemente hace el bucle, porque - ** el "exit_client()" modifica la estructura - */ - corta: - if (num_hubs-- > 1) - { /* Deja un HUB conectado */ - for (lp = me.serv->down; lp; lp = lp->next) - { - acptr = lp->value.cptr; - /* - ** Si se especifica que se desea mantener un HUB - ** en concreto, respeta esa peticion - */ - if ((acptr != cptr) && - find_conf_host(acptr->confs, acptr->name, CONF_HUB) != NULL) - { - sprintf_irc(buf, "BDD '%c' %s. Resincronizando...", que_bdd, mensaje); - exit_client(acptr, acptr, &me, buf); - goto corta; - } - } - } - } - } - - /* - * initdb - * - * Lee la base de datos de disco - * - */ - void initdb2(char que_bdd) - { - unsigned long hi, lo; - char buf[1024]; - char path[1024]; - int db_file; - Dlink *lp; - struct tabla_en_memoria mapeo; - - borrar_db(que_bdd); - - db_file = abrir_db(0, buf, que_bdd, &mapeo); - if (db_file != -1) - do - { - /* db_alta modifica la cadena */ - if (tabla_residente[que_bdd] && !((*buf == '*') && (*(buf + 1) == '\0'))) - { - db_alta(buf, que_bdd, 0); - } - else - { - actualiza_hash(buf, que_bdd); - } - } - while (leer_db(&mapeo, buf) != -1); - cerrar_db(&mapeo); - - /* - ** Ahora comprueba que el HASH de la BDD - ** cargada se corresponda con el HASH almacenado - */ - lee_hash(que_bdd, &hi, &lo); - if ((tabla_hash_hi[que_bdd] != hi) || (tabla_hash_lo[que_bdd] != lo)) - { - sendto_ops("ATENCION - Base de Datos " - "'%c' aparentemente corrupta. Borrando...", que_bdd); - borrar_db(que_bdd); - sprintf_irc(path, "%s/tabla.%c", DBPATH, que_bdd); - alarm(3); - db_file = open(path, O_TRUNC, S_IRUSR | S_IWUSR); - close(db_file); - if (db_file == -1) - db_die("Error al intentar truncar (open)", que_bdd); - alarm(0); - - /* - ** Solucion temporal - ** Corta conexiones con los HUBs - */ - for (lp = me.serv->down; lp; lp = lp->next) - { - if (find_conf_host(lp->value.cptr->confs, - lp->value.cptr->name, CONF_HUB) != NULL) - { - sprintf_irc(buf, "BDD '%c' inconsistente. Resincronizando...", que_bdd); - exit_client(lp->value.cptr, lp->value.cptr, &me, buf); - } - } - /* - ** Fin solucion temporal - */ - - corta_si_multiples_hubs(NULL, que_bdd, "inconsistente"); - - sendto_ops("Solicitando actualizacion BDD '%c' " - "a los nodos vecinos.", que_bdd); - - /* - ** Solo pide a los HUBs, porque no se - ** aceptan datos de leafs. - */ - for (lp = me.serv->down; lp; lp = lp->next) - { - if (find_conf_host(lp->value.cptr->confs, - lp->value.cptr->name, CONF_HUB) != NULL) - { - sendto_one(lp->value.cptr, "%s DB %s 0 J %lu %c", - NumServ(&me), lp->value.cptr->name, tabla_serie[que_bdd], que_bdd); - } - } - } - almacena_hash(que_bdd); - } - - void initdb(void) - { - char c; - - tabla_residente[ESNET_NICKDB] = 1; - #if defined(DB_ESNET) && defined(ESNET_CLONES) - tabla_residente[ESNET_CLONESDB] = 1; - #endif - - for (c = ESNET_BDD; c <= ESNET_BDD_END; c++) - initdb2(c); - } - - /* - * reload_db - * - * Recarga la base de datos de disco, liberando la memoria - * - */ - void reload_db(void) - { - char buf[16]; - char c; - - sendto_ops("Releyendo Bases de Datos..."); - initdb(); - for (c = ESNET_BDD; c <= ESNET_BDD_END; c++) - { - if (tabla_serie[c]) - { - inttobase64(buf, tabla_hash_hi[c], 6); - inttobase64(buf + 6, tabla_hash_lo[c], 6); - sendto_ops("DB: '%c'. Ultimo registro: %lu. HASH: %s", - c, tabla_serie[c], buf); - } - } - } - - - /* - * m_db - * - * Gestion de la base de datos - ESNET - * 29/May/98 jcea@argo.es - * - */ - int m_db(aClient *cptr, aClient *sptr, int parc, char *parv[]) - { - unsigned long db; - aClient *acptr; - Dlink *lp; - char db_buf[1024], db_buf2[1024]; - char path[1024]; - int db_file; - int es_hub = 0; - char *p, *p2, *p3, *p4; - char que_bdd = ESNET_NICKDB; - unsigned long mascara_bdd; - int cont; - struct tabla_en_memoria mapeo; - - - if (!IsServer(sptr) || parc < 5) - return 0; - db = atol(parv[2]); - if (find_conf_host(cptr->confs, cptr->name, CONF_HUB) != NULL) - es_hub = !0; - if (!db) - { - db = atol(parv[4]); - - if (parc == 6) - { - que_bdd = *parv[5]; - if ((que_bdd < 'a') || (que_bdd > 'z')) - if ((que_bdd < '2') || (que_bdd > '9') || (*parv[3] != 'J')) - return 0; - else - que_bdd = ESNET_NICKDB; - } - mascara_bdd = ((unsigned long)1) << (que_bdd - ESNET_BDD); - - switch (*parv[3]) - { - case 'B': - if (es_hub) - sendto_one(sptr, "%s DB %s 0 J %lu %c", - NumServ(&me), parv[0], tabla_serie[que_bdd], que_bdd); - return 0; - break; - - case 'J': - if ((parc == 6) && (*parv[5] >= '2') && (*parv[5] <= '9')) - { - /* - ** Informamos del estado de nuestras BDD - */ - for (cont = ESNET_BDD; cont <= ESNET_BDD_END; cont++) - { - if (cont != ESNET_NICKDB) /* No mandamos nicks de nuevo */ - sendto_one(sptr, "%s DB %s 0 J %lu %c", - NumServ(&me), parv[0], tabla_serie[cont], cont); - } - } - - /* - ** No hay problemas de CPU en el - ** extremo receptor. Esto es para - ** limitar el LAG y el caudal - ** consumido. - */ - cont = 100; - - if (db >= tabla_serie[que_bdd]) - { /* Se le pueden mandar registros individuales */ - sptr->serv->esnet_db |= mascara_bdd; - return 0; - break; - } - else if ((sptr->serv->esnet_db) & mascara_bdd) - { - /* - ** Teniamos el grifo abierto, y ahora - ** nos esta pidiendo registros antiguos. - ** Eso SOLO ocurre si ha detectado que su - ** copia local de la BDD esta corrupta. - */ - sptr->serv->esnet_db &= ~mascara_bdd; - /* - ** Borramos su BDD porque es posible - ** que le hayamos enviado mas registros. - ** Es preferible empezar desde cero. - */ - sendto_one(sptr, "%s DB %s 0 D BDD_CORRUPTA %c", - NumServ(&me), sptr->name, que_bdd); - db = 0; /* Nos curamos en salud; se la enviamos entera */ - } - - db_file = abrir_db(db + 1, db_buf, que_bdd, &mapeo); - if (db_file == -1) - return 0; /* Problemas con la DB */ - do - { - p = strchr(db_buf, ' '); - if (p == NULL) - continue; - *p++ = '\0'; - p2 = strchr(p, ' '); - if (p2 == NULL) - continue; - *p2++ = '\0'; - p3 = strchr(p2, ' '); - if (p3 == NULL) - continue; - *p3++ = '\0'; - p4 = strchr(p3, ' '); - if (p4 == NULL) - { - sendto_one(sptr, "%s DB %s %s %s %s", NumServ(&me), p, db_buf, p2, - p3); - } - else - { - *p4++ = '\0'; - sendto_one(sptr, "%s DB %s %s %s %s :%s", NumServ(&me), p, db_buf, - p2, p3, p4); - } - if (!(--cont)) - break; - } - while (leer_db(&mapeo, db_buf) != -1); - cerrar_db(&mapeo); - if (cont) - sptr->serv->esnet_db |= mascara_bdd; - else - sendto_one(sptr, "%s DB %s 0 B %lu %c", - NumServ(&me), parv[0], tabla_serie[que_bdd], que_bdd); - return 0; - break; - - case 'D': - if (!es_hub) - return 0; - /* - ** Por bug en lastNNServer no se puede usar 'find_match_server()' - */ - collapse(parv[1]); - if (!match(parv[1], me.name)) - { - sprintf_irc(path, "%s/tabla.%c", DBPATH, que_bdd); - alarm(3); - db_file = open(path, O_TRUNC, S_IRUSR | S_IWUSR); - close(db_file); - if (db_file == -1) - db_die("Error al intentar truncar (open)", que_bdd); - alarm(0); - borrar_db(que_bdd); - sprintf_irc(db_buf, "borrada (%s)", sptr->name); - corta_si_multiples_hubs(cptr, que_bdd, db_buf); - /* - ** Podemos enviar a 'sptr' tranquilos, porque el - ** corte afectaria a todos los HUBs menos a - ** traves del que llega la peticion. - */ - sendto_one(sptr, "%s DB %s 0 E %s %c\n", - NumServ(&me), sptr->name, parv[4], que_bdd); - } - - /* - ** Como no sabemos si el otro extremo nos ha - ** cerrado el grifo o no, nos curamos en salud - */ - sendto_one(cptr, "%s DB %s 0 J %lu %c", - NumServ(&me), cptr->name, tabla_serie[que_bdd], que_bdd); - - sprintf(db_buf, "%s DB %s 0 D %s %c", - NumServ(sptr), parv[1], parv[4], que_bdd); - - for (lp = me.serv->down; lp; lp = lp->next) - { - if (lp->value.cptr == cptr) - continue; - /* - ** No sabemos si la otra punta - ** va a cumplir la mascara, asi que - ** nos curamos en salud. - */ - lp->value.cptr->serv->esnet_db &= ~mascara_bdd; - - sendto_one(lp->value.cptr, db_buf); - } - - return 0; - break; - - case 'E': /* Podemos ser destinatarios si el otro estaba corrupto */ - case 'R': - if ((acptr = find_match_server(parv[1])) && (!IsMe(acptr))) - sendto_one(acptr, "%s DB %s 0 %c %s %c", NumServ(sptr), - acptr->name, *parv[3], parv[4], que_bdd); - return 0; - break; - - case 'Q': - if (!es_hub) - return 0; - /* - ** Por bug en lastNNServer no se puede usar 'find_match_server()' - */ - collapse(parv[1]); - if (!match(parv[1], me.name)) - { - inttobase64(db_buf, tabla_hash_hi[que_bdd], 6); - inttobase64(db_buf + 6, tabla_hash_lo[que_bdd], 6); - sendto_one(sptr, "%s DB %s 0 R %lu-%s-%s %c", - NumServ(&me), sptr->name, tabla_serie[que_bdd], - db_buf, parv[4], que_bdd); - } - - sprintf(db_buf, "%s DB %s 0 Q %s %c", - NumServ(sptr), parv[1], parv[4], que_bdd); - - for (lp = me.serv->down; lp; lp = lp->next) - { - if (lp->value.cptr == cptr) - continue; - sendto_one(lp->value.cptr, db_buf); - } - - return 0; - break; - } - return 0; - } - - /* Nuevo registro */ - - que_bdd = *parv[3]; - if ((que_bdd < 'a') || (que_bdd > 'z')) - { - if (que_bdd == 'N') - que_bdd = ESNET_NICKDB; - else - return 0; - } - - mascara_bdd = ((unsigned long)1) << (que_bdd - ESNET_BDD); - - if (db <= tabla_serie[que_bdd]) - return 0; - if (!es_hub) - return 0; - - /* - ** Ojo, hay que usar 'db' y no 'parv[2]' - ** porque en la cadena de formateo se - ** dice que se le pasa un numero, no - ** una cadena. - ** Se le pasa un numero para que se formatee - ** correctamente, ya que luego sera - ** utilizado en un HASH y todos los - ** nodos deberian dar el mismo valor. - */ - if (parc == 5) - sprintf_irc(db_buf, "%s DB %s %lu %s %s", - NumServ(sptr), parv[1], db, parv[3], parv[4]); - else - sprintf_irc(db_buf, "%s DB %s %lu %s %s :%s", - NumServ(sptr), parv[1], db, parv[3], parv[4], parv[5]); - - for (lp = me.serv->down; lp; lp = lp->next) - { - if (!((lp->value.cptr->serv->esnet_db) & mascara_bdd) || - (lp->value.cptr == cptr)) continue; - sendto_one(lp->value.cptr, db_buf); - } - - sprintf_irc(path, "%s/tabla.%c", DBPATH, que_bdd); - alarm(3); - db_file = open(path, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR); - if (db_file == -1) - db_die("Error al intentar an~adir nuevo registro (open)", que_bdd); - alarm(0); - - if (parc == 5) - sprintf_irc(db_buf, "%lu %s %s %s\n", db, parv[1], parv[3], parv[4]); - else - sprintf_irc(db_buf, "%lu %s %s %s %s\n", db, parv[1], parv[3], parv[4], - parv[5]); - - strcpy(db_buf2, db_buf); /* db_alta modifica la cadena */ - if (strcmp(parv[4], "*")) - db_alta(db_buf2, que_bdd, !0); /* CheckPoint */ - - alarm(3); - if (strcmp(parv[4], "*")) - { /* CheckPoint */ - if (write(db_file, db_buf, strlen(db_buf)) == -1) - db_die("Error al intentar an~adir nuevo registro (write)", que_bdd); - } - close(db_file); - alarm(0); - - if (!strcmp(parv[4], "*")) - db_pack(db_buf, que_bdd); - - return 0; - } - - #endif /* DB_ESNET */ - - #ifdef DB_HISPANO - /* - * dbh_violacion (argc, argv, texto) - * - * Muestra error protocolo DBH a los opers. - * 1999/06/28 savage@apostols.org - */ - void dbh_violacion(int parc, char *parv[], char *causa) - { - int i; - char line[2048]; - - sprintf_irc(line, "%s %s ", parv[0], MSG_DBH); - for (i = 1; i < parc; i++) - { - strcat(line, parv[i]); - strcat(line, " "); - } - - sendto_ops("Error DBH: %s", causa); - sendto_ops("Debug DBH: %s", line); - } - - /* - * dbh_hash_tabla (tabla) - * - * calcula la HASH de una tabla. - * 1999/06/21 savage@apostols.org - */ - unsigned long dbh_hash_tabla(char tabla) - { - return 0; - } - - /* - * dbh_guardar_version (tabla, version) - * - * actualiza la version en memoria y disco. - * 1999/06/21 savage@apostols.org - */ - void dbh_guardar_version(char tabla, unsigned long version) - { - FILE *f; - char fichero[1024]; - - /* guardo en memoria */ - tabla_version[tabla] = version; - - /* guardo en disco */ - sprintf_irc(fichero, "%s/version.%c", DBPATH, tabla); - alarm(3); - f = fopen(fichero, "w"); - if (f) - { - fprintf(f, "%lu\n", version); - fclose(f); - } - alarm(0); - - return; - } - - /* - * dbh_leer_version (tabla) - * - * actualiza la version en memoria a partir de la de disco. - * 1999/06/21 savage@apostols.org - */ - unsigned long dbh_leer_version(char tabla) - { - FILE *f; - char fichero[1024]; - char buff[512]; - - buff[0] = 0; - - /* guardo en disco */ - sprintf_irc(fichero, "%s/version.%c", DBPATH, tabla); - alarm(3); - f = fopen(fichero, "r"); - if (f) - { - fgets(buff, sizeof(buff) - 1, f); - fclose(f); - } - alarm(0); - - /* ke pone? */ - tabla_version[tabla] = atol(buff); - - return tabla_version[tabla]; - } - - /* - * dbh_abrir_tabla (fichero) - * - * abre una tabla con un modo concreto "a", "r", "w" ... - * 1999/06/21 savage@apostols.org - */ - FILE *dbh_abrir_tabla(char tabla, char *modo) - { - FILE *f; - char fichero[1024]; - - alarm(3); - sprintf_irc(fichero, "%s/tabla.%c", DBPATH, tabla); - f = fopen(fichero, modo); - alarm(0); - - return f; - } - - /* - * dbh_cerrar_tabla (fichero) - * - * cierra una tabla abierta con dbh_abrir_tabla ... - * 1999/06/21 savage@apostols.org - */ - int dbh_cerrar_tabla(FILE * f) - { - if (f) - { - alarm(3); - fclose(f); - alarm(0); - } - - return 0; - } - - /* - * dbh_leer_registro (fichero, numero_registro) - * - * lee el registro n de una tabla abierta con dbh_abrir_tabla - * 1999/06/21 savage@apostols.org - */ - char *dbh_leer_registro(FILE * f, unsigned long regnum) - { - char buf[1024]; - static char b2[1024]; - char *p; - unsigned long num = 0; - - while (num != regnum && !feof(f)) - { - alarm(3); - fgets(buf, sizeof(buf) - 1, f); - alarm(0); - memcpy(b2, buf, sizeof(b2)); /* mas rapido ke strcpy */ - p = strtok(buf, " "); - p = strtok(NULL, " "); - if (p) - num = atol(p); - } - - if (num != regnum) - return NULL; - - return b2; - } - - /* - * dbh_cargar_tabla (tabla) - * - * lee una tabla y la mete en memoria - * 1999/06/21 savage@apostols.org - */ - void dbh_cargar_tabla(char tabla) - { - char *p1, *p2, *p3, *p4, *p5, *txt; - unsigned long num = 0; - FILE *f; - - f = dbh_abrir_tabla(tabla, "r"); - if (!f) - return; - while ((txt = dbh_leer_registro(f, num + 1)) != NULL) - { - num++; - if (tabla_residente[tabla]) - { - p1 = strtok(txt, " "); /* destino */ - p2 = strtok(NULL, " "); /* serie */ - p3 = strtok(NULL, " "); /* tabla */ - p4 = strtok(NULL, " \n\r"); /* clave */ - p5 = strtok(NULL, "\n\r"); /* :valor */ - - if (p5 != NULL) - dbh_insertar_registro(*p3, p1, p4, ++p5); /* salto : */ - else - dbh_eliminar_registro(*p3, p4); - } - } - - dbh_cerrar_tabla(f); - - dbh_leer_version(tabla); - tabla_serie[tabla] = num; - } - - /* - * dbh_borrar_tabla (tabla, version) - * - * borra la tabla de disco, guarda version en disco, marca - * todos los registros como borrados en memoria. - * 1999/06/21 savage@apostols.org - */ - void dbh_borrar_tabla(char tabla, unsigned long version) - { - FILE *f; - struct dbh_reg *reg; - int i; - - f = dbh_abrir_tabla(tabla, "w"); /* esto truncara la tabla */ - dbh_cerrar_tabla(f); - - dbh_guardar_version(tabla, version); - - if (!tabla_residente[tabla]) - return; /* no esta en memoria, no hace falta */ - - for (i = 0; i < DBH_HASH_SIZE; i++) - for (reg = tabla_datos[tabla][i]; reg != NULL; reg = reg->next) - reg->borrado = 1; - - return; - } - - /* - * dbh_compactar_tabla (tabla, version, serie, hash) - * - * compacta la tabla de disco, guarda version en disco, - * si la hash no coincide borra la tabla. - * 1999/06/21 savage@apostols.org - */ - void dbh_compactar_tabla(char tabla, unsigned long version, unsigned long serie, - unsigned long hash) - { - FILE *n, *o; - struct dbh_reg *reg; - unsigned long i, j = 0; - char resi; - char *rtxt; - char *p; - char tmp1[1024], tmp2[1024]; - - resi = tabla_residente[tabla]; - - /* creamos una tabla nueva */ - n = dbh_abrir_tabla('-', "w"); - o = dbh_abrir_tabla(tabla, "r"); - - if (!resi) - dbh_cargar_tabla(tabla); /* Hacemos residente la tabla un momento */ - - /* pongo los flags de compactacion a 0 */ - for (i = 0; i < DBH_HASH_SIZE; i++) - for (reg = tabla_datos[tabla][i]; reg != NULL; reg = reg->next) - reg->compactado = 0; - - /* - * recorremos la tabla y si el registro esta en memoria, - * lo metemos de nuevo en la tabla - */ - for (i = 1; i < tabla_serie[tabla]; i++) - { - if ((rtxt = dbh_leer_registro(o, i)) != NULL) - { - p = strtok(rtxt, " "); /* destino */ - p = strtok(NULL, " "); /* serie */ - p = strtok(NULL, " "); /* tabla */ - p = strtok(NULL, " \n\r"); /* clave */ - if (p && ((reg = dbh_buscar_registro(tabla, p)) != NULL) - && reg->compactado == 0) - { - reg->compactado = 1; - fprintf(n, "%s %lu %c %s :%s\n", reg->destino, ++j, tabla, p, - reg->valor); - } - } - } - - dbh_cerrar_tabla(o); - dbh_cerrar_tabla(n); - - /* en cualquier caso actualizo version */ - dbh_guardar_version(tabla, version); - - /* calculo si ha sido correcto */ - sprintf(tmp1, "%s/tabla.%c", DBPATH, tabla); - sprintf(tmp2, "%s/tabla.%c", DBPATH, '-'); /* tabla temporal */ - if (hash == dbh_hash_tabla('-') && j == serie) - { - unlink(tmp1); - rename(tmp2, tmp1); - } - else - { - unlink(tmp2); - dbh_borrar_tabla(tabla, version); /* pone a 0 la serie */ - dbh_eliminar_borrados(tabla); /* limpia de verdad con RunFree() */ - return; - } - - if (!resi) - { - /* no era residente, la elimino de memoria aunque haya funcionado */ - for (i = 0; i < DBH_HASH_SIZE; i++) - for (reg = tabla_datos[tabla][i]; reg != NULL; reg = reg->next) - reg->borrado = 1; - dbh_eliminar_borrados(tabla); - } - - return; - } - - /* - * m_dbq - * - * parv[0] = prefijo del enviador - * parv[1..] = argumentos de DBQ [] - * - * Maneja los mensajes DBQ recibidos de users y servers. - * 1999/10/13 savage@apostols.org - */ - int m_dbq(aClient *cptr, aClient *sptr, int parc, char *parv[]) - { - char tabla, *clave, *servidor; - aClient *acptr; - struct dbh_reg *reg; - - if (!IsServer(sptr) && !IsOper(sptr) && !IsHelpOp(sptr)) - return 0; /* No autorizado */ - - /* DBQ [] */ - if (parc != 3 && parc != 4) - { - - if (!IsServer(sptr)) - sendto_one(cptr, - ":%s NOTICE %s :Parametros incorrectos: Formato: DBQ [] ", - me.name, parv[0]); - return 0; - } - - if (parc == 3) - { - servidor = NULL; /* no nos indican server */ - tabla = *parv[1]; - clave = parv[2]; - } - else - { - servidor = parv[1]; - tabla = *parv[2]; - clave = parv[3]; - - if (*servidor == '*') - { - /* WOOW, BROADCAST */ - sendto_serv_butone(cptr, ":%s DBQ * %c %s", parv[0], tabla, clave); - } - else - { - /* NOT BROADCAST */ - if (!(acptr = find_match_server(servidor))) - { - /* joer, el server de destino no existe */ - sendto_one(cptr, err_str(ERR_NOSUCHSERVER), me.name, parv[0], servidor); - return 0; - } - - if (!IsMe(acptr)) /* no es para mi, a rutar */ - { - sendto_one(acptr, ":%s DBQ %s %c %s", parv[0], servidor, tabla, clave); - return 0; /* ok, rutado, fin del trabajo */ - } - } - } - - if (!tabla_residente[tabla]) - { - if (MyUser(sptr) || Protocol(cptr) < 10) - sendto_one(cptr, ":%s NOTICE %s :DBQ ERROR TABLA_NO_RESIDENTE", - me.name, parv[0]); - else - sendto_one(cptr, "%s NOTICE %s%s :DBQ ERROR TABLA_NO_RESIDENTE", - NumServ(&me), NumNick(sptr)); - return 0; - } - - reg = dbh_buscar_registro(tabla, clave); - if (!reg) - { - if (MyUser(sptr) || Protocol(cptr) < 10) - sendto_one(cptr, ":%s NOTICE %s :DBQ ERROR REGISTRO_NO_ENCONTRADO", - me.name, parv[0]); - else - sendto_one(cptr, "%s NOTICE %s%s :DBQ ERROR REGISTRO_NO_ENCONTRADO", - NumServ(&me), NumNick(sptr)); - return 0; - } - - if (MyUser(sptr) || Protocol(cptr) < 10) - sendto_one(cptr, - ":%s NOTICE %s :DBQ OK Tabla='%c' Destino='%s' Clave='%s' Valor='%s'", - me.name, parv[0], tabla, reg->destino, reg->clave, reg->valor); - else - sendto_one(cptr, - "%s NOTICE %s%s :DBQ OK Tabla='%c' Destino='%s' Clave='%s' Valor='%s'", - NumServ(&me), NumNick(sptr), tabla, reg->destino, reg->clave, - reg->valor); - - return 0; - } - - /* - * m_dbh - * - * parv[0] = prefijo del enviador - * parv[1..] = argumentos de DBH - * - * Maneja los mensajes DBH recibidos por los servers. - * 1999/06/20 savage@apostols.org - */ - int m_dbh(aClient *cptr, aClient *sptr, int parc, char *parv[]) - { - unsigned long numserie, numversion, i, hash; - unsigned int j; - char tabla; - aClient *acptr; - Dlink *lp; - char db_buf[1024], *reg; - FILE *db_file; - int es_hub = 0; - - if (!IsServer(sptr)) - { - if (!IsOper(sptr) && !IsHelpOp(sptr)) - return 0; - - sendto_one(cptr, - ":%s NOTICE %s :Comando obsoleto, utiliza DBQ [] ", - me.name, parv[0]); - return 0; - } - - if (find_conf_host(cptr->confs, cptr->name, CONF_HUB) != NULL) - es_hub = 1; /* El remoto es un Hub */ - - numserie = atol(parv[2]); /* solo != 0 en registros */ - - if (!numserie) - { - switch (*parv[3]) - { - case 'B': - /* DBH 0 B */ - /* No rutable, solo hub-nodo: sera para nosotros */ - if (!es_hub || parc != 7) - { - /* - * Un nodo idiota nos envia un "continua burst", - * avisamos a los ircops - */ - dbh_violacion(parc, parv, "Origen no Hub o Parametros incorrectos"); - break; - } - - tabla = *parv[4]; - numversion = atol(parv[5]); - numserie = atol(parv[6]); - - if (numversion == tabla_version[tabla] - && numserie == tabla_serie[tabla]) - { - /* - * parece que llegamos al final, ya podemos eliminar de memoria - * los registros marcados para borrar ... - */ - dbh_eliminar_borrados(tabla); - break; - } - - /* le contestamos con 0 J para que continue */ - sendto_one(sptr, "%s %s - 0 J %c %lu %lu", - NumServ(&me), MSG_DBH, - tabla, tabla_version[tabla], tabla_serie[tabla]); - break; - - case 'J': - /* DBH 0 J */ - /* No rutable, solo nodo-nodo: sera para nosotros */ - if (parc != 7) - { - /* parametros incorrectos, avisamos */ - dbh_violacion(parc, parv, "Parametros incorrectos"); - break; - } - - tabla = *parv[4]; - numversion = atol(parv[5]); - numserie = atol(parv[6]); - - /* Parece ke no estamos en la version correcta */ - if (numversion > tabla_version[tabla] && es_hub) - { - /* me perdi un COMMIT .... */ - dbh_violacion(parc, parv, - "Hub con version Superior. Borrando DB local ..."); - dbh_borrar_tabla(tabla, numversion); - /* le contestamos con 0 J para que continue o pare */ - /* y al resto de nodos para que se enteren de la nueva version */ - for (lp = me.serv->down; lp; lp = lp->next) - sendto_one(sptr, "%s %s - 0 J %c %lu %lu", - NumServ(&me), MSG_DBH, tabla, tabla_version[tabla], 0); - break; - } - #ifdef HUB - if (numversion > tabla_version[tabla] && !es_hub) - { - /* el nodo es un mamon, con version superior, ordeno borrado */ - /* tambien podria ser ke yo me perdiera algo, pero ... shit hapens */ - dbh_violacion(parc, parv, - "Nodo con version Superior. Borrando DB remota ..."); - sendto_one(sptr, "%s %s %s 0 D %c %lu", NumServ(&me), MSG_DBH, - parv[0], tabla, tabla_version[tabla]); - break; - } - - if (numversion < tabla_version[tabla]) - { - /* El remoto se perdio un compromiso */ - dbh_violacion(parc, parv, - "Remoto con version Inferior. Actualizando DB remota ..."); - /* - * El remoto se dara cuenta, y borrara su version vieja. - * Esto provocara un nuevo msg 0 J con version adecuada y serie 0 - * pero hasta que esto suceda, yo paso de enviarle nada .... - */ - break; - } - - /* - * Fantastico, hablamos sobre al misma version, - * a ver si tengo que actualizarle ... - */ - - if (numserie >= tabla_serie[tabla]) - break; /* El remoto es mas nuevo que nosotros o ya esta ok */ - - /* abrimos la tabla */ - db_file = dbh_abrir_tabla(tabla, "r"); - - for (j = 0, i = numserie + 1; - db_file && i <= tabla_serie[tabla] && j < 25; i++, j++) - { - char *reg; - - reg = dbh_leer_registro(db_file, i); - if (reg) - { - sendto_one(sptr, "%s %s %s", NumServ(&me), MSG_DBH, reg); - } - } - - dbh_cerrar_tabla(db_file); - - /* Enviamos el '0 B' para que el otro se entere si hemos terminado */ - sendto_one(sptr, "%s %s - 0 B %c %lu %lu", - NumServ(&me), MSG_DBH, - tabla, tabla_version[tabla], tabla_serie[tabla]); - #endif /* HUB */ - - break; - - case 'q': - /* DBH 0 q */ - /* Rutable, debemos buscar destino */ - #ifdef HUB - if (parc != 8) - { - /* parametros incorrectos, avisamos */ - dbh_violacion(parc, parv, "Parametros incorrectos"); - break; - } - - /* lo dejo pasar hacia destino, no puede ser para mi */ - if (!(acptr = find_match_server(parv[1]))) - { - /* joer, el server de destino no existe */ - sendto_one(sptr, err_str(ERR_NOSUCHSERVER), me.name, parv[0], - parv[1]); - break; - } - - if (IsMe(acptr)) - { - /* - * Un nodo/hub idiota nos contesta sobre una tabla, - * no hace falta avisar ... - */ - break; - } - else - sendto_one(acptr, "%s %s %s 0 q %s %s %s %s", - NumServ(sptr), MSG_DBH, acptr->name, - parv[4], parv[5], parv[6], parv[7]); - #endif /* HUB */ - break; - - case 'Q': - /* DBH /<*> 0 Q */ - /* Rutable y Broadcast: tendre ke mirar destino */ - if (!es_hub || parc != 5) - { - /* - * Un nodo idiota nos interroga sobre una tabla, - * avisamos a los ircops - */ - dbh_violacion(parc, parv, "Origen no Hub o Parametros incorrectos"); - break; - } - #ifdef HUB - /* - * Si es un wildcard lo propago a todos - */ - if (*parv[1] == '*') - { - for (lp = me.serv->down; lp; lp = lp->next) - { - if (lp->value.cptr == cptr) - continue; /* al que nos lo envia, no se lo reenvio */ - sendto_one(lp->value.cptr, "%s %s %s 0 Q %s", - parv[0], MSG_DBH, parv[1], parv[4]); - } - } - else - { - /* - * Pues no, no es un wilcard, busco destino ... - */ - if (!(acptr = find_match_server(parv[1]))) - { - /* joer, el server de destino no existe */ - sendto_one(sptr, err_str(ERR_NOSUCHSERVER), me.name, parv[0], - parv[1]); - break; - } - - if (!IsMe(acptr)) - { - sendto_one(acptr, "%s %s %s 0 Q %s\n", - NumServ(sptr), MSG_DBH, acptr->name, parv[4]); - break; - } - } - #endif /* HUB */ - - /* bueno, este 0 Q es para mí (o wilcard), a contestar ... */ - tabla = *parv[4]; - sendto_one(sptr, "%s %s %s 0 q %c %lu %lu %lu\n", - NumServ(&me), MSG_DBH, parv[0], - tabla, tabla_version[tabla], tabla_serie[tabla], - dbh_hash_tabla(tabla)); - break; - - case 'D': - /* DBH 0 D */ - /* Rutable: tendre que buscar destino */ - if (!es_hub || parc != 6) - { - /* - * Un nodo idiota intenta borrarnos una tabla, - * avisamos a los ircops - */ - dbh_violacion(parc, parv, "Origen no Hub o Parametros incorrectos"); - break; - } - #ifdef HUB - if (!(acptr = find_match_server(parv[1]))) - { - /* joer, el server de destino no existe */ - sendto_one(sptr, err_str(ERR_NOSUCHSERVER), me.name, parv[0], - parv[1]); - break; - } - - if (!IsMe(acptr)) - { - sendto_one(acptr, "%s %s %s 0 D %s %s\n", - NumServ(sptr), MSG_DBH, acptr->name, parv[4], parv[5]); - break; - } - #endif /* HUB */ - - /* pues alguien me ordena borrar una tabla */ - tabla = *parv[4]; - numversion = atol(parv[5]); - dbh_borrar_tabla(tabla, numversion); - - /* envio un 0 J para solicitar registros nuevos */ - sendto_one(sptr, "%s %s - 0 J %c %lu %lu", - NumServ(&me), MSG_DBH, - tabla, tabla_version[tabla], tabla_serie[tabla]); - break; - - case 'C': - /* DBH <*> 0 C */ - /* Broadcast: tengo que propagarlo a todos */ - if (!es_hub || parc != 8 || *parv[1] != '*') - { - /* - * Un nodo idiota intenta compactarnos una tabla, - * avisamos a los ircops - */ - dbh_violacion(parc, parv, "Origen no Hub o Parametros incorrectos"); - break; - } - - #ifdef HUB - /* - * Propago compactacion a todos mis nodos - */ - for (lp = me.serv->down; lp; lp = lp->next) - { - if (lp->value.cptr == cptr) - continue; /* al que nos lo envia, no se lo reenvio */ - sendto_one(lp->value.cptr, "%s %s %s 0 C %s %s %s %s", - parv[0], MSG_DBH, parv[1], parv[4], parv[5], parv[6], parv[7]); - } - #endif - tabla = *parv[4]; - numversion = atol(parv[5]); - numserie = atol(parv[6]); - hash = atol(parv[7]); - dbh_compactar_tabla(tabla, numversion, numserie, hash); - /* Enviamos el '0 J' para informar / pedir mas */ - sendto_one(sptr, "%s %s - 0 J %c %lu %lu", - NumServ(&me), MSG_DBH, - tabla, tabla_version[tabla], tabla_serie[tabla]); - break; - - default: - return 0; /* Orden incorrecta, ni puto caso */ - } - - /* orden procesada */ - return 0; - } - - /* Si llegamos aqui, se trata de un registro */ - /* parv[0] parv[1] parv[2] parv[3] parv[4] parv[5] */ - /* DBH /<*> [:] */ - /* Broadcast: tengo que propagarlo a todos */ - - if (!es_hub || parc < 5) - { - /* - * Un nodo idiota nos envia un registro, - * avisaremos a los operadores o a los services - */ - dbh_violacion(parc, parv, "Origen no Hub o Parametros incorrectos"); - return 0; - } - - /* Procesamos un registro */ - tabla = *parv[3]; - if (numserie != (tabla_serie[tabla] + 1)) - { - /* - * carambas, un registro atrasado o adelantado ... lo ignoro ... - * no me interesa ni a mi ni a nadie que cuelgue de mi. - */ - return 0; - } - - #ifdef HUB - /* - * Propago el registro ... - */ - if (parc == 6) - sprintf_irc(db_buf, "%s %s %s %s %s %s :%s", - NumServ(sptr), MSG_DBH, parv[1], parv[2], parv[3], parv[4], parv[5]); - else - sprintf_irc(db_buf, "%s %s %s %s %s %s", - NumServ(sptr), MSG_DBH, parv[1], parv[2], parv[3], parv[4]); - - for (lp = me.serv->down; lp; lp = lp->next) - { - if (lp->value.cptr == cptr) - continue; /* al que nos lo envia, no se lo reenvio */ - sendto_one(lp->value.cptr, db_buf); - } - #endif /* HUB */ - - /* - * meto el registro en la tabla de disco - * lo meto en un formato aprovechable en los burst - */ - db_file = dbh_abrir_tabla(tabla, "a"); - if (!db_file) - return 0; /* que paso ? deberia informar error %m */ - alarm(3); - if (parc == 6) - fprintf(db_file, "%s %lu %c %s :%s\n", - parv[1], numserie, tabla, parv[4], parv[5]); - else - fprintf(db_file, "%s %lu %c %s\n", parv[1], numserie, tabla, parv[4]); - dbh_cerrar_tabla(db_file); - alarm(0); - - /* - * Actualizo la serie en memoria - */ - tabla_serie[tabla]++; - - /* - * Meto el registro en memoria si es una tabla residente - */ - if (tabla_residente[tabla]) - { - if (parc == 6) - dbh_insertar_registro(tabla, parv[1], parv[4], parv[5]); - else - dbh_eliminar_registro(tabla, parv[4]); - } - - /* orden procesada */ - return 0; - } - - /* - * dbh_recarga () - * - * Recarga la base de datos (carga todas las tablas) - * 1999/06/28 savage@apostols.org - */ - void dbh_recarga() - { - unsigned char i; - unsigned int j; - struct dbh_reg *reg; - - sendto_ops("Recargando tablas DBH"); - for (i = DBH_PRIMERA_TABLA; i <= DBH_ULTIMA_TABLA; i++) - { - /* marco todo como borrado */ - for (j = 0; j < DBH_HASH_SIZE; j++) - for (reg = tabla_datos[i][j]; reg != NULL; reg = reg->next) - reg->borrado = 1; - /* cargo de nuevo de disco */ - dbh_cargar_tabla(i); - /* elimino lo marcado */ - dbh_eliminar_borrados(i); - if (tabla_serie[i]) - sendto_ops("Tabla '%c' V:%lu S:%lu", i, tabla_version[i], tabla_serie[i]); - } - - return; - } - - /* - * dbh_inicializa () - * - * Inicailiza la base de datos (carga todas las tablas) - * 1999/06/28 savage@apostols.org - */ - void dbh_inicializa() - { - unsigned char i; - - /* --------------------------------------------------- */ - memset(tabla_residente, 0, sizeof(tabla_residente)); - memset(tabla_cuantos, 0, sizeof(tabla_cuantos)); - memset(tabla_datos, 0, sizeof(tabla_datos)); - memset(tabla_version, 0, sizeof(tabla_version)); - memset(tabla_serie, 0, sizeof(tabla_serie)); - /* --------------------------------------------------- */ - - /* - * Hago residentes las tablas necesarias para los parches - */ - tabla_residente[DBH_NICKDB] = 1; - tabla_residente[DBH_OPERDB] = 1; - tabla_residente[DBH_CHANDB] = 1; - tabla_residente[DBH_BOTSDB] = 1; - tabla_residente[DBH_VIRTUALDB] = 1; - - /* --------------------------------------------------- */ - for (i = DBH_PRIMERA_TABLA; i <= DBH_ULTIMA_TABLA; i++) - dbh_cargar_tabla(i); - - return; - } - - #endif /* DB_HISPANO */ --- 1160,1162 ---- Index: ../ircu2.10.06/ircd/s_user.c =================================================================== RCS file: /cvsroot/ircd/ircd/s_user.c,v retrieving revision 1.24 diff -c -c -r1.24 s_user.c *** ../ircu2.10.06/ircd/s_user.c 1999/10/15 08:24:25 1.24 --- ../ircu2.10.06/ircd/s_user.c 1999/10/21 22:40:38 *************** *** 49,54 **** --- 49,57 ---- #include "list.h" #include "s_err.h" #include "parse.h" + #if defined(DB_ESNET) || defined(DB_HISPANO) + #include "s_bdd.h" + #endif #include "ircd.h" #include "s_user.h" #include "support.h"