diff --git a/ChangeLog b/ChangeLog index 3418290..89f8e37 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,8 @@ Symbols are: (F) - Can invite non-Z clients into +S channels (F) - SSL conf file support and restart of neoircd coding :) (HP) - Hybrid Team Patches. (RC6, RC7, RC8) Woo0oo.. Wonder what they broke this time. +(F) - Fix a Umode Problem +(HP) - Hybrid Team Patches (RC9) * NeoIRCd Version 0.9.5 - 12th Oct, 2002 - Fish (S) - Fixed up event.c for a possible serious bug reported by Dianora from hybrid team diff --git a/TODO b/TODO index 087f9c0..63d4edc 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,4 @@ -$Id: TODO,v 1.17 2003/03/04 13:05:30 fishwaldo Exp $ +$Id: TODO,v 1.18 2003/03/06 14:01:45 fishwaldo Exp $ put back "expire_channels" stuff @@ -18,4 +18,5 @@ POST 1.0 *channel modes in /list */silence */watch -*/knock on +klO chans, but not when banned \ No newline at end of file +*/knock on +klO chans, but not when banned +*/kill templates (/kill = /kill Abusive user diff --git a/autoconf/configure.in b/autoconf/configure.in index d6e00ac..20bdf47 100644 --- a/autoconf/configure.in +++ b/autoconf/configure.in @@ -1,4 +1,4 @@ -dnl $Id: configure.in,v 1.7 2002/11/04 08:14:00 fishwaldo Exp $ +dnl $Id: configure.in,v 1.8 2003/03/06 14:01:46 fishwaldo Exp $ dnl Process this file with autoconf to produce a configure script. dnl AC_INIT(include/class.h) <- what is this ? -TimeMr14C @@ -19,6 +19,17 @@ AC_PROG_CC dnl Make sure autoconf doesnt interfere with cflags -jmallett CFLAGS="$OLD_CFLAGS" +dnl check for /dev/null so we can use it to hold evil fd's +AC_MSG_CHECKING(for /dev/null) +if test -c /dev/null ; then + AC_DEFINE(PATH_DEVNULL,"/dev/null") + AC_MSG_RESULT(yes) +else + AC_DEFINE(PATH_DEVNULL,"devnull.log") + AC_MSG_RESULT(no - using devnull.log) +fi + + dnl Check for various compilers. -jmallett SGS=no AC_MSG_CHECKING(if we are using TenDRA or MIPSpro) diff --git a/configure b/configure index 9967d83..17d8df2 100755 --- a/configure +++ b/configure @@ -2012,6 +2012,25 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu CFLAGS="$OLD_CFLAGS" +echo "$as_me:$LINENO: checking for /dev/null" >&5 +echo $ECHO_N "checking for /dev/null... $ECHO_C" >&6 +if test -c /dev/null ; then + cat >>confdefs.h <<\_ACEOF +#define PATH_DEVNULL "/dev/null" +_ACEOF + + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + cat >>confdefs.h <<\_ACEOF +#define PATH_DEVNULL "devnull.log" +_ACEOF + + echo "$as_me:$LINENO: result: no - using devnull.log" >&5 +echo "${ECHO_T}no - using devnull.log" >&6 +fi + + SGS=no echo "$as_me:$LINENO: checking if we are using TenDRA or MIPSpro" >&5 echo $ECHO_N "checking if we are using TenDRA or MIPSpro... $ECHO_C" >&6 diff --git a/include/client.h b/include/client.h index 1831c64..a635786 100644 --- a/include/client.h +++ b/include/client.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: client.h,v 1.13 2003/01/29 09:28:48 fishwaldo Exp $ + * $Id: client.h,v 1.14 2003/03/06 14:01:46 fishwaldo Exp $ */ #ifndef INCLUDED_client_h @@ -231,6 +231,8 @@ struct LocalUser struct X509 *ssl_cert; /* clients SSL cert info, if ssl client */ #endif + dlink_node lclient_node; + /* Send and receive linebuf queues .. */ buf_head_t buf_sendq; buf_head_t buf_recvq; @@ -518,7 +520,7 @@ struct LocalUser #define IsSSL(x) ((x)->flags & FLAGS_SSL) #define SetSSLOK(x) ((x)->flags2 |= FLAGS2_SSLOK) #define IsSSLOK(x) ((x)->flags2 & FLAGS2_SSLOK) -#define IsDefunct(x) ((x)->flags & (FLAGS_DEADSOCKET|FLAGS_CLOSING)) +#define IsDefunct(x) ((x)->flags & (FLAGS_DEADSOCKET|FLAGS_CLOSING|FLAGS_KILLED)) /* oper flags */ #define MyOper(x) (MyConnect(x) && IsOper(x)) @@ -558,11 +560,17 @@ struct LocalUser #define SetWallops(x) ((x)->umodes |= FLAGS_WALLOP) #define SetCallerId(x) ((x)->umodes |= FLAGS_CALLERID) #define IsSetCallerId(x) ((x)->umodes & FLAGS_CALLERID) +#define SetSendQExceeded(x) ((x)->flags |= FLAGS_SENDQEX) +#define IsSendQExceeded(x) ((x)->flags & FLAGS_SENDQEX) #define SetIpHash(x) ((x)->flags |= FLAGS_IPHASH) #define ClearIpHash(x) ((x)->flags &= ~FLAGS_IPHASH) #define IsIpHash(x) ((x)->flags & FLAGS_IPHASH) +#define SetPingSent(x) ((x)->flags |= FLAGS_PINGSENT) +#define IsPingSent(x) ((x)->flags & FLAGS_PINGSENT) +#define ClearPingSent(x) ((x)->flags &= ~FLAGS_PINGSENT) + #define SetNeedId(x) ((x)->flags |= FLAGS_NEEDID) #define IsNeedId(x) (((x)->flags & FLAGS_NEEDID) != 0) @@ -647,5 +655,7 @@ extern int change_local_nick(struct Client *client_p, struct Client *source_p, extern void dead_link_on_write(struct Client *client_p, int ierrno); extern void dead_link_on_read(struct Client *client_p, int error); extern void make_virthost(char *curr, char *host, char *new); +extern void exit_aborted_clients(void); +extern void free_exited_clients(void); #endif /* INCLUDED_client_h */ diff --git a/include/ircd.h b/include/ircd.h index fb54587..d4ed77d 100644 --- a/include/ircd.h +++ b/include/ircd.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: ircd.h,v 1.4 2003/01/29 09:28:48 fishwaldo Exp $ + * $Id: ircd.h,v 1.5 2003/03/06 14:01:46 fishwaldo Exp $ */ #ifndef INCLUDED_ircd_h @@ -105,8 +105,7 @@ extern dlink_list lclient_list; extern dlink_list serv_list; extern dlink_list global_serv_list; extern dlink_list oper_list; -extern dlink_list dead_list; -extern dlink_list abort_list; +extern dlink_list closing_list; extern dlink_list lazylink_channels; extern int callbacks_called; diff --git a/include/ircd_defs.h b/include/ircd_defs.h index 84d3389..1db900b 100644 --- a/include/ircd_defs.h +++ b/include/ircd_defs.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: ircd_defs.h,v 1.3 2002/09/13 06:50:06 fishwaldo Exp $ + * $Id: ircd_defs.h,v 1.4 2003/03/06 14:01:46 fishwaldo Exp $ */ /* @@ -60,6 +60,8 @@ #define HELPLEN 400 +#define LOWEST_SAFE_FD 4 /* skip stdin, stdout, stderr, and profiler */ + /* * message return values */ diff --git a/include/s_conf.h b/include/s_conf.h index 95ad336..f382b7a 100644 --- a/include/s_conf.h +++ b/include/s_conf.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: s_conf.h,v 1.9 2003/01/29 09:28:48 fishwaldo Exp $ + * $Id: s_conf.h,v 1.10 2003/03/06 14:01:46 fishwaldo Exp $ */ #ifndef INCLUDED_s_conf_h @@ -320,7 +320,7 @@ extern struct admin_info AdminInfo; /* defined in ircd.c */ dlink_list temporary_klines; dlink_list temporary_ip_klines; -extern void clear_ip_hash_table(void); +extern void init_ip_hash_table(void); extern void iphash_stats(struct Client *,struct Client *,int,char **,FBFILE*); extern void count_ip_hash(int *, u_long *); diff --git a/include/send.h b/include/send.h index 735fcb9..9614733 100644 --- a/include/send.h +++ b/include/send.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: send.h,v 1.5 2002/10/31 13:01:54 fishwaldo Exp $ + * $Id: send.h,v 1.6 2003/03/06 14:01:46 fishwaldo Exp $ */ #ifndef INCLUDED_send_h @@ -48,7 +48,7 @@ unsigned long current_serial; /* send.c prototypes */ -extern void send_queued_write(int fd, void *data); +extern void send_queued_write(int fd, struct Client *to); extern void send_queued_slink_write(int fd, void *data); @@ -62,8 +62,10 @@ extern void sendto_channel_butone(struct Client *one, extern void sendto_one_prefix(struct Client *, struct Client *, const char *, ...) AFP(3, 4); -extern void sendto_common_channels_local(struct Client *, const char *, - ...) AFP(2, 3); +extern void sendto_common_channels_local(struct Client *, + int, + const char *, + ...) AFP(3, 4); extern void sendto_channel_local(int type, struct Channel *, const char *, ...) AFP(3, 4); diff --git a/include/setup.h.in b/include/setup.h.in index 53a69a2..873fd34 100644 --- a/include/setup.h.in +++ b/include/setup.h.in @@ -92,6 +92,12 @@ /* topiclen */ #undef TOPICLEN +/* EFNET */ +#undef EFNET + +/* PATH_DEVNULL */ +#undef PATH_DEVNULL + /* Define if you have the EVP_bf_cfb function. */ #undef HAVE_EVP_BF_CFB diff --git a/include/tools.h b/include/tools.h index c09f9af..5477a3c 100644 --- a/include/tools.h +++ b/include/tools.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: tools.h,v 1.5 2002/10/31 13:01:54 fishwaldo Exp $ + * $Id: tools.h,v 1.6 2003/03/06 14:01:46 fishwaldo Exp $ */ #ifndef __TOOLS_H__ @@ -186,7 +186,8 @@ dlinkDelete(dlink_node *m, dlink_list *list) * output - pointer to link or NULL if not found * side effects - Look for ptr in the linked listed pointed to by link. */ -extern inline dlink_node *dlinkFind(dlink_list *list, void * data ) +extern inline dlink_node * +dlinkFind(dlink_list *list, void * data ) { dlink_node *ptr; @@ -237,21 +238,10 @@ dlinkFindDelete(dlink_list *list, void *data) { dlink_node *m; - DLINK_FOREACH(m, list->head) - { - if(m->data != data) - continue; - - if (m->next != NULL) - m->next->prev = m->prev; - else - list->tail = m->prev; - - m->next = m->prev = NULL; - list->length--; - return m; - } - return(NULL); + m = dlinkFind(list, data); + if (m) + dlinkDelete(m, list); + return(m); } #endif /* __GNUC__ */ diff --git a/modules/core/m_kick.c b/modules/core/m_kick.c index 4e05d59..5988c75 100644 --- a/modules/core/m_kick.c +++ b/modules/core/m_kick.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: m_kick.c,v 1.7 2002/09/13 06:50:07 fishwaldo Exp $ + * $Id: m_kick.c,v 1.8 2003/03/06 14:01:47 fishwaldo Exp $ */ #include "stdinc.h" @@ -59,7 +59,7 @@ _moddeinit(void) mod_del_cmd(&kick_msgtab); } -const char *_version = "$Revision: 1.7 $"; +const char *_version = "$Revision: 1.8 $"; #endif /* ** m_kick @@ -68,10 +68,9 @@ const char *_version = "$Revision: 1.7 $"; ** parv[2] = client to kick ** parv[3] = kick comment */ -static void m_kick(struct Client *client_p, - struct Client *source_p, - int parc, - char *parv[]) +static void +m_kick(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) { struct Client *who; struct Channel *chptr; @@ -234,17 +233,17 @@ static void m_kick(struct Client *client_p, ":%s KICK %s %s :%s", parv[0], chptr->chname, who->name, comment); - remove_user_from_channel(chptr, who); + if (!IsDefunct(who)) + remove_user_from_channel(chptr, who); } else sendto_one(source_p, form_str(ERR_USERNOTINCHANNEL), me.name, parv[0], user, name); } -static void ms_kick(struct Client *client_p, - struct Client *source_p, - int parc, - char *parv[]) +static void +ms_kick(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) { if (*parv[2] == '\0') { diff --git a/modules/core/m_kill.c b/modules/core/m_kill.c index 3234c27..0f9750b 100644 --- a/modules/core/m_kill.c +++ b/modules/core/m_kill.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: m_kill.c,v 1.5 2002/09/13 16:30:04 fishwaldo Exp $ + * $Id: m_kill.c,v 1.6 2003/03/06 14:01:47 fishwaldo Exp $ */ #include "stdinc.h" @@ -64,7 +64,7 @@ _moddeinit(void) mod_del_cmd(&kill_msgtab); } -const char *_version = "$Revision: 1.5 $"; +const char *_version = "$Revision: 1.6 $"; #endif /* ** mo_kill @@ -72,8 +72,9 @@ const char *_version = "$Revision: 1.5 $"; ** parv[1] = kill victim ** parv[2] = kill path */ -static void mo_kill(struct Client *client_p, struct Client *source_p, - int parc, char *parv[]) +static void +mo_kill(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) { struct Client* target_p; const char* inpath = client_p->name; @@ -170,8 +171,9 @@ static void mo_kill(struct Client *client_p, struct Client *source_p, * parv[1] = kill victim * parv[2] = kill path and reason */ -static void ms_kill(struct Client *client_p, struct Client *source_p, - int parc, char *parv[]) +static void +ms_kill(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) { struct Client *target_p; char *user; @@ -281,7 +283,7 @@ static void ms_kill(struct Client *client_p, struct Client *source_p, relay_kill(client_p, source_p, target_p, path, reason); /* FLAGS_KILLED prevents a quit being sent out */ - target_p->flags |= FLAGS_KILLED; + SetKilled(target_p); /* reason comes supplied with its own ()'s */ if(ConfigServerHide.hide_servers && IsServer(source_p)) @@ -292,10 +294,9 @@ static void ms_kill(struct Client *client_p, struct Client *source_p, exit_client(client_p, target_p, source_p, buf); } -static void relay_kill(struct Client *one, struct Client *source_p, - struct Client *target_p, - const char *inpath, - const char *reason) +static void +relay_kill(struct Client *one, struct Client *source_p, + struct Client *target_p, const char *inpath, const char *reason) { dlink_node *ptr; struct Client *client_p; diff --git a/modules/core/m_nick.c b/modules/core/m_nick.c index dd84e70..9424ff6 100644 --- a/modules/core/m_nick.c +++ b/modules/core/m_nick.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: m_nick.c,v 1.20 2002/10/31 13:01:57 fishwaldo Exp $ + * $Id: m_nick.c,v 1.21 2003/03/06 14:01:48 fishwaldo Exp $ */ #include "stdinc.h" @@ -97,7 +97,7 @@ _moddeinit(void) mod_del_cmd(&client_msgtab); } -const char *_version = "$Revision: 1.20 $"; +const char *_version = "$Revision: 1.21 $"; #endif /* @@ -199,8 +199,9 @@ mr_nick(struct Client *client_p, struct Client *source_p, * parv[0] = sender prefix * parv[1] = nickname */ - static void m_nick(struct Client *client_p, struct Client *source_p, - int parc, char *parv[]) + static void + m_nick(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) { char nick[NICKLEN]; struct Client *target_p; @@ -476,7 +477,7 @@ ms_client(struct Client *client_p, struct Client *source_p, ServerStats->is_kill++; - target_p->flags |= FLAGS_KILLED; + SetKilled(target_p); exit_client(client_p, target_p, &me, "ID Collision"); return; } @@ -511,8 +512,9 @@ ms_client(struct Client *client_p, struct Client *source_p, * side effects - if nickname is erroneous, or a different length to * truncated nickname, return 1 */ -static int check_clean_nick(struct Client *client_p, struct Client *source_p, - char *nick, char *newnick, char *server) +static int +check_clean_nick(struct Client *client_p, struct Client *source_p, + char *nick, char *newnick, char *server) { /* the old code did some wacky stuff here, if the nick is invalid, kill it * and dont bother messing at all @@ -534,14 +536,14 @@ static int check_clean_nick(struct Client *client_p, struct Client *source_p, kill_client_ll_serv_butone(client_p, source_p, "%s (Bad Nickname)", me.name); - source_p->flags |= FLAGS_KILLED; + SetKilled(source_p); exit_client(client_p, source_p, &me, "Bad Nickname"); } - return 1; + return (1); } - return 0; + return (0); } /* check_clean_user() @@ -567,7 +569,7 @@ check_clean_user(struct Client *client_p, char *nick, sendto_one(client_p, ":%s KILL %s :%s (Bad Username)", me.name, nick, me.name); - return 1; + return (1); } if(!clean_user_name(user)) @@ -575,7 +577,7 @@ check_clean_user(struct Client *client_p, char *nick, "Bad Username: %s Nickname: %s From: %s(via %s)", user, nick, server, client_p->name); - return 0; + return (0); } /* check_clean_host() @@ -601,7 +603,7 @@ check_clean_host(struct Client *client_p, char *nick, sendto_one(client_p, ":%s KILL %s :%s (Bad Hostname)", me.name, nick, me.name); - return 1; + return (1); } if(!clean_host_name(host)) @@ -609,7 +611,7 @@ check_clean_host(struct Client *client_p, char *nick, "Bad Hostname: %s Nickname: %s From: %s(via %s)", host, nick, server, client_p->name); - return 0; + return (0); } /* clean_nick_name() @@ -623,21 +625,21 @@ clean_nick_name(char *nick) { assert(nick); if(nick == NULL) - return 0; + return (0); /* nicks cant start with a digit or - or be 0 length */ /* This closer duplicates behaviour of hybrid-6 */ if (*nick == '-' || IsDigit(*nick) || *nick == '\0') - return 0; + return (0); for(; *nick; nick++) { if(!IsNickChar(*nick)) - return 0; + return (0); } - return 1; + return (1); } /* clean_user_name() @@ -762,7 +764,7 @@ nick_from_server(struct Client *client_p, struct Client *source_p, int parc, if(irccmp(parv[0], nick)) source_p->tsinfo = newts ? newts : CurrentTime; - sendto_common_channels_local(source_p, ":%s!%s@%s NICK :%s", + sendto_common_channels_local(source_p, 1, ":%s!%s@%s NICK :%s", source_p->name,source_p->username,source_p->vhost, nick); @@ -886,7 +888,7 @@ perform_nick_collides(struct Client *source_p, struct Client *client_p, sendto_one(target_p, form_str(ERR_NICKCOLLISION), me.name, target_p->name, target_p->name); - target_p->flags |= FLAGS_KILLED; + SetKilled(target_p); exit_client(client_p, target_p, &me, "Nick collision (new)"); return 0; } @@ -930,8 +932,8 @@ perform_nick_collides(struct Client *source_p, struct Client *client_p, "%s (Nick collision (new))", me.name); - target_p->flags |= FLAGS_KILLED; - (void)exit_client(client_p, target_p, &me, "Nick collision"); + SetKilled(target_p); + exit_client(client_p, target_p, &me, "Nick collision"); if(parc == 11) nick_from_server(client_p,source_p,parc,parv,newts,nick); @@ -970,9 +972,9 @@ perform_nick_collides(struct Client *source_p, struct Client *client_p, "%s (Nick change collision)", me.name); - target_p->flags |= FLAGS_KILLED; + SetKilled(target_p); exit_client(NULL, target_p, &me, "Nick collision(new)"); - source_p->flags |= FLAGS_KILLED; + SetKilled(source_p); exit_client(client_p, source_p, &me, "Nick collision(old)"); return 0; } @@ -1002,7 +1004,7 @@ perform_nick_collides(struct Client *source_p, struct Client *client_p, "%s (Nick change collision)", me.name); - source_p->flags |= FLAGS_KILLED; + SetKilled(source_p); if(sameuser) exit_client(client_p, source_p, &me, "Nick collision(old)"); @@ -1031,8 +1033,8 @@ perform_nick_collides(struct Client *source_p, struct Client *client_p, sendto_one(target_p, form_str(ERR_NICKCOLLISION), me.name, target_p->name, target_p->name); - target_p->flags |= FLAGS_KILLED; - (void)exit_client(client_p, target_p, &me, "Nick collision"); + SetKilled(target_p); + exit_client(client_p, target_p, &me, "Nick collision"); } } diff --git a/modules/core/m_server.c b/modules/core/m_server.c index 673631a..c440c4a 100644 --- a/modules/core/m_server.c +++ b/modules/core/m_server.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: m_server.c,v 1.12 2003/01/29 09:28:49 fishwaldo Exp $ + * $Id: m_server.c,v 1.13 2003/03/06 14:01:48 fishwaldo Exp $ */ #include "stdinc.h" @@ -67,7 +67,7 @@ _moddeinit(void) { mod_del_cmd(&server_msgtab); } -const char *_version = "$Revision: 1.12 $"; +const char *_version = "$Revision: 1.13 $"; #endif int bogus_host(char *host); @@ -439,7 +439,7 @@ static void ms_server(struct Client *client_p, struct Client *source_p, "Non-Hub link %s introduced %s.", get_client_name(client_p, MASK_IP), name); - exit_client(NULL, client_p, &me, "No matching hub_mask."); + exit_client(NULL, source_p, &me, "No matching hub_mask."); return; } diff --git a/modules/core/m_squit.c b/modules/core/m_squit.c index 94f414d..05c0441 100644 --- a/modules/core/m_squit.c +++ b/modules/core/m_squit.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: m_squit.c,v 1.2 2002/09/13 06:50:07 fishwaldo Exp $ + * $Id: m_squit.c,v 1.3 2003/03/06 14:01:49 fishwaldo Exp $ */ #include "stdinc.h" @@ -58,7 +58,7 @@ _moddeinit(void) { mod_del_cmd(&squit_msgtab); } -const char *_version = "$Revision: 1.2 $"; +const char *_version = "$Revision: 1.3 $"; #endif struct squit_parms { @@ -131,35 +131,35 @@ static void ms_squit(struct Client *client_p, struct Client *source_p, char *comment = (parc > 2 && parv[2]) ? parv[2] : client_p->name; if(parc < 2) + { + exit_client(client_p, client_p, source_p, comment); + return; + } + + if((found_squit = find_squit(client_p, source_p, parv[1]))) + { + /* + ** Notify all opers, if my local link is remotely squitted + */ + if (MyConnect(found_squit->target_p)) { - exit_client(client_p, client_p, source_p, comment); - return; - } - - if( (found_squit = find_squit(client_p, source_p, parv[1])) ) - { - /* - ** Notify all opers, if my local link is remotely squitted - */ - if (MyConnect(found_squit->target_p)) - { - sendto_wallops_flags(FLAGS_WALLOP, &me, - "Remote SQUIT %s from %s (%s)", - found_squit->server_name, - source_p->name, comment); - - sendto_server(NULL, NULL, NULL, NOCAPS, NOCAPS, NOFLAGS, - ":%s WALLOPS :Remote SQUIT %s from %s (%s)", - me.name, found_squit->server_name, - source_p->name, comment); - - ilog(L_TRACE, "SQUIT From %s : %s (%s)", parv[0], - found_squit->server_name, comment); - - } - exit_client(client_p, found_squit->target_p, source_p, comment); - return; + sendto_wallops_flags(FLAGS_WALLOP, &me, + "Remote SQUIT %s from %s (%s)", + found_squit->server_name, + source_p->name, comment); + + sendto_server(NULL, NULL, NULL, NOCAPS, NOCAPS, NOFLAGS, + ":%s WALLOPS :Remote SQUIT %s from %s (%s)", + me.name, found_squit->server_name, + source_p->name, comment); + + ilog(L_TRACE, "SQUIT From %s : %s (%s)", parv[0], + found_squit->server_name, comment); + } + exit_client(client_p, found_squit->target_p, source_p, comment); + return; + } } @@ -171,9 +171,8 @@ static void ms_squit(struct Client *client_p, struct Client *source_p, * output - pointer to struct containing found squit or none if not found * side effects - */ -static struct squit_parms *find_squit(struct Client *client_p, - struct Client *source_p, - char *server) +static struct squit_parms * +find_squit(struct Client *client_p, struct Client *source_p, char *server) { static struct squit_parms found_squit; static struct Client *target_p; @@ -232,5 +231,5 @@ static struct squit_parms *find_squit(struct Client *client_p, if(found_squit.target_p != NULL) return &found_squit; else - return( NULL ); + return(NULL); } diff --git a/modules/m_close.c b/modules/m_close.c index e0c5700..784fefd 100644 --- a/modules/m_close.c +++ b/modules/m_close.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: m_close.c,v 1.4 2002/09/19 05:41:10 fishwaldo Exp $ + * $Id: m_close.c,v 1.5 2003/03/06 14:01:46 fishwaldo Exp $ */ #include "stdinc.h" @@ -54,7 +54,7 @@ _moddeinit(void) mod_del_cmd(&close_msgtab); } -const char *_version = "$Revision: 1.4 $"; +const char *_version = "$Revision: 1.5 $"; #endif /* * mo_close - CLOSE message handler @@ -83,7 +83,11 @@ mo_close(struct Client *client_p, struct Client *source_p, #endif sendto_one(source_p, form_str(RPL_CLOSING), me.name, parv[0], get_client_name(target_p, SHOW_IP), target_p->status); - (void)exit_client(target_p, target_p, target_p, "Oper Closing"); + /* + * exit here is safe, because it is guaranteed not to be source_p + * because it is unregistered and source_p is an oper. + */ + exit_client(target_p, target_p, target_p, "Oper Closing"); closed++; } sendto_one(source_p, form_str(RPL_CLOSEEND), me.name, parv[0], closed); diff --git a/modules/m_join.c b/modules/m_join.c index a04c751..1b205ea 100644 --- a/modules/m_join.c +++ b/modules/m_join.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: m_join.c,v 1.12 2002/10/31 13:01:55 fishwaldo Exp $ + * $Id: m_join.c,v 1.13 2003/03/06 14:01:46 fishwaldo Exp $ */ #include "stdinc.h" @@ -64,7 +64,7 @@ _moddeinit(void) { mod_del_cmd(&join_msgtab); } -const char *_version = "$Revision: 1.12 $"; +const char *_version = "$Revision: 1.13 $"; #endif static void do_join_0(struct Client *client_p, struct Client *source_p); @@ -438,6 +438,7 @@ do_join_0(struct Client *client_p, struct Client *source_p) sendto_channel_local(ALL_MEMBERS,chptr, ":%s!%s@%s PART %s", source_p->name, source_p->username, source_p->vhost, chptr->chname); - remove_user_from_channel(chptr, source_p); + if (!IsDefunct(source_p)) + remove_user_from_channel(chptr, source_p); } } diff --git a/modules/m_svscmds.c b/modules/m_svscmds.c index d2e89be..338dae6 100644 --- a/modules/m_svscmds.c +++ b/modules/m_svscmds.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: m_svscmds.c,v 1.9 2002/10/31 13:01:56 fishwaldo Exp $ + * $Id: m_svscmds.c,v 1.10 2003/03/06 14:01:46 fishwaldo Exp $ */ /* List of ircd includes from ../include/ */ @@ -134,7 +134,7 @@ _moddeinit(void) /* When we last modified the file (shown in /modlist), this is usually: */ -const char *_version = "$Revision: 1.9 $"; +const char *_version = "$Revision: 1.10 $"; #endif /* @@ -206,7 +206,7 @@ static void ms_svsnick(struct Client *client_p, struct Client *source_p, return; } target_p->tsinfo = parv[4] ? atol(parv[3]) : CurrentTime; - sendto_common_channels_local(target_p, ":%s!%s@%s NICK :%s", target_p->name, target_p->username, target_p->vhost, parv[2]); + sendto_common_channels_local(target_p, 1, ":%s!%s@%s NICK :%s", target_p->name, target_p->username, target_p->vhost, parv[2]); /* send it to the other servers */ if (target_p->user) { add_history(target_p, 1); diff --git a/modules/m_whois.c b/modules/m_whois.c index 0e8096c..e77e12e 100644 --- a/modules/m_whois.c +++ b/modules/m_whois.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: m_whois.c,v 1.11 2002/11/20 14:13:57 fishwaldo Exp $ + * $Id: m_whois.c,v 1.12 2003/03/06 14:01:47 fishwaldo Exp $ */ #include "stdinc.h" @@ -76,7 +76,7 @@ _moddeinit(void) mod_del_cmd(&whois_msgtab); } -const char *_version = "$Revision: 1.11 $"; +const char *_version = "$Revision: 1.12 $"; #endif /* ** m_whois @@ -238,9 +238,7 @@ do_whois(struct Client *client_p, struct Client *source_p, found = global_whois(source_p,nick,wilds,glob); } - if(found) - sendto_one(source_p, form_str(RPL_ENDOFWHOIS), me.name, parv[0], parv[1]); - else + if (!found) sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, parv[0], nick); return (0); diff --git a/src/channel.c b/src/channel.c index b5a6b51..03810f7 100644 --- a/src/channel.c +++ b/src/channel.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: channel.c,v 1.16 2003/01/29 09:28:49 fishwaldo Exp $ + * $Id: channel.c,v 1.17 2003/03/06 14:01:49 fishwaldo Exp $ */ #include "stdinc.h" @@ -1165,7 +1165,9 @@ is_voiced(struct Channel *chptr, struct Client *who) int can_send(struct Channel *chptr, struct Client *source_p) { - if(MyClient(source_p) && find_channel_resv(chptr->chname) && !(IsOper(source_p)) && ConfigChannel.oper_pass_resv) + if(MyClient(source_p) && + (find_channel_resv(chptr->chname) && + !(IsOper(source_p)) && ConfigChannel.oper_pass_resv)) return (CAN_SEND_NO); if (is_any_op(chptr, source_p)) diff --git a/src/channel_mode.c b/src/channel_mode.c index 70bf627..e873382 100644 --- a/src/channel_mode.c +++ b/src/channel_mode.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: channel_mode.c,v 1.21 2003/01/29 09:28:49 fishwaldo Exp $ + * $Id: channel_mode.c,v 1.22 2003/03/06 14:01:49 fishwaldo Exp $ */ #include "stdinc.h" @@ -872,7 +872,9 @@ chm_ban(struct Client *client_p, struct Client *source_p, * I'd like to see this hack go away in the future. */ if(del_id(chptr, raw_mask, CHFL_BAN)) - mask = raw_mask; + mask = raw_mask; + else + del_id(chptr, mask, CHFL_BAN); #endif mode_changes[mode_count].letter = c; @@ -1645,6 +1647,9 @@ chm_key(struct Client *client_p, struct Client *source_p, if (!(*chptr->mode.key)) return; + if (parc > *parn) + (*parn)++; + *chptr->mode.key = 0; mode_changes[mode_count].letter = c; diff --git a/src/client.c b/src/client.c index afb0c23..dbe6f64 100644 --- a/src/client.c +++ b/src/client.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: client.c,v 1.12 2003/01/29 09:28:49 fishwaldo Exp $ + * $Id: client.c,v 1.13 2003/03/06 14:01:50 fishwaldo Exp $ */ #include "stdinc.h" #include "config.h" @@ -57,8 +57,6 @@ static void check_pings_list(dlink_list *list); static void check_unknowns_list(dlink_list *list); -static void free_exited_clients(void *unused); -static void free_local_client(struct Client *client_p); static EVH check_pings; @@ -69,6 +67,7 @@ static BlockHeap *client_heap = NULL; static BlockHeap *lclient_heap = NULL; dlink_list dead_list; +dlink_list abort_list; /* * client_heap_gc @@ -84,7 +83,6 @@ static void client_heap_gc(void *unused) BlockHeapGarbageCollect(lclient_heap); } - /* * init_client * @@ -92,7 +90,8 @@ static void client_heap_gc(void *unused) * output - NONE * side effects - initialize client free memory */ -void init_client(void) +void +init_client(void) { remote_client_count = 0; local_client_count = 0; @@ -101,9 +100,8 @@ void init_client(void) * Every 30 seconds is plenty -- db */ client_heap = BlockHeapCreate(sizeof(struct Client), CLIENT_HEAP_SIZE); - lclient_heap = BlockHeapCreate(sizeof(struct LocalUser), LCLIENT_HEAP_SIZE); + lclient_heap = BlockHeapCreate(sizeof(struct LocalUser), LCLIENT_HEAP_SIZE); eventAddIsh("check_pings", check_pings, NULL, 30); - eventAddIsh("free_exited_clients", &free_exited_clients, NULL, 4); eventAddIsh("client_heap_gc", client_heap_gc, NULL, 30); } @@ -117,7 +115,8 @@ void init_client(void) * associated with the client defined by * 'from'). ('from' is a local client!!). */ -struct Client* make_client(struct Client* from) +struct Client* +make_client(struct Client* from) { struct Client* client_p = NULL; struct LocalUser *localClient; @@ -175,11 +174,18 @@ struct Client* make_client(struct Client* from) return client_p; } -static void -free_local_client(struct Client *client_p) +void +free_client(struct Client* client_p) { + assert(NULL != client_p); + assert(&me != client_p); + assert(NULL == client_p->prev); + assert(NULL == client_p->next); + if (MyConnect(client_p)) { + assert(IsClosing(client_p) && IsDead(client_p)); + /* * clean up extra sockets from P-lines which have been discarded. */ @@ -200,25 +206,17 @@ free_local_client(struct Client *client_p) if (client_p->localClient->fd >= 0) fd_close(client_p->localClient->fd); + linebuf_donebuf(&client_p->localClient->buf_recvq); + linebuf_donebuf(&client_p->localClient->buf_sendq); + BlockHeapFree(lclient_heap, client_p->localClient); --local_client_count; assert(local_client_count >= 0); - client_p->localClient = NULL; } -} - -void -free_client(struct Client* client_p) -{ - assert(NULL != client_p); - assert(&me != client_p); - assert(NULL == client_p->prev); - assert(NULL == client_p->next); - - if(MyConnect(client_p)) - free_local_client(client_p); else - --remote_client_count; + { + --remote_client_count; + } BlockHeapFree(client_heap, client_p); } @@ -267,8 +265,8 @@ check_pings(void *notused) static void check_pings_list(dlink_list *list) { - char scratch[32]; /* way too generous but... */ - struct Client *client_p; /* current local client_p being examined */ + char scratch[32]; /* way too generous but... */ + struct Client *client_p; /* current local client_p being examined */ int ping = 0; /* ping time value from client */ dlink_node *ptr, *next_ptr; @@ -285,6 +283,7 @@ check_pings_list(dlink_list *list) /* Ignore it, its been exited already */ continue; } + if (IsPerson(client_p)) { if(!IsExemptKline(client_p) && @@ -326,7 +325,7 @@ check_pings_list(dlink_list *list) * and it has a ping time, then close its connection. */ if (((CurrentTime - client_p->lasttime) >= (2 * ping) && - (client_p->flags & FLAGS_PINGSENT))) + IsPingSent(client_p))) { if (IsServer(client_p) || IsConnecting(client_p) || IsHandshake(client_p)) @@ -347,15 +346,14 @@ check_pings_list(dlink_list *list) (void)exit_client(client_p, client_p, &me, scratch); continue; } - else if ((client_p->flags & FLAGS_PINGSENT) == 0) + else if (!IsPingSent(client_p)) { /* * if we havent PINGed the connection and we havent * heard from it in a while, PING it to make sure * it is still alive. */ - client_p->flags |= FLAGS_PINGSENT; - /* not nice but does the job */ + SetPingSent(client_p); client_p->lasttime = CurrentTime - ping; sendto_one(client_p, "PING :%s", me.name); } @@ -415,6 +413,11 @@ check_klines(void) if (IsMe(client_p)) continue; + + /* If a client is already being exited + */ + if (IsDead(client_p)) + continue; /* if there is a returned struct ConfItem then kill it */ if ((aconf = find_dline_conf(&client_p->localClient->ip, @@ -575,12 +578,13 @@ check_klines(void) * output - NONE * side effects - */ -static void update_client_exit_stats(struct Client* client_p) +static void +update_client_exit_stats(struct Client* client_p) { if (IsServer(client_p)) { --Count.server; - sendto_realops_flags(FLAGS_EXTERNAL, L_ALL, + sendto_realops_flags(FLAGS_EXTERNAL|FLAGS_REMOTE, L_ALL, "Server %s split from %s", client_p->name, client_p->servptr->name); } @@ -611,6 +615,7 @@ release_client_state(struct Client* client_p) { free_user(client_p->user, client_p); /* try this here */ } + if (client_p->serv != NULL) { if (client_p->serv->user != NULL) @@ -633,6 +638,9 @@ remove_client_from_list(struct Client* client_p) if(client_p == NULL) return; + +/* XXX try without this as well */ +#if 1 /* A client made with make_client() * is on the unknown_list until removed. * If it =does= happen to exit before its removed from that list @@ -643,6 +651,7 @@ remove_client_from_list(struct Client* client_p) { return; } +#endif if (client_p->prev) client_p->prev->next = client_p->next; @@ -856,8 +865,8 @@ get_client_name(struct Client* client, int showip) return client->name; } -static void -free_exited_clients(void *unused) +void +free_exited_clients(void) { dlink_node *ptr, *next; struct Client *target_p; @@ -874,8 +883,6 @@ free_exited_clients(void *unused) free_dlink_node(ptr); continue; } - - release_client_state(target_p); free_client(target_p); dlinkDelete(ptr, &dead_list); @@ -894,6 +901,7 @@ exit_one_client(struct Client *client_p, struct Client *source_p, struct Client* target_p; dlink_node *lp; dlink_node *next_lp; + dlink_node *m; if (IsServer(source_p)) { @@ -904,7 +912,10 @@ exit_one_client(struct Client *client_p, struct Client *source_p, ts_warn("server %s without servptr!", source_p->name); if(!IsMe(source_p)) - remove_server_from_list(source_p); + { + if ((m = dlinkFindDelete(&global_serv_list, source_p)) != NULL) + free_dlink_node(m); + } } else if (source_p->servptr && source_p->servptr->serv) { @@ -951,9 +962,10 @@ exit_one_client(struct Client *client_p, struct Client *source_p, } target_p = source_p->from; - if (target_p && IsServer(target_p) && target_p != client_p && !IsMe(target_p) && - (!IsKilled(source_p))) - sendto_one(target_p, ":%s SQUIT %s :%s", from->name, source_p->name, comment); + if (target_p && IsServer(target_p) && target_p != client_p && + !IsMe(target_p) && !IsKilled(source_p)) + sendto_one(target_p, ":%s SQUIT %s :%s", from->name, source_p->name, + comment); } else if (IsPerson(source_p)) /* ...just clean all others with QUIT... */ { @@ -973,11 +985,10 @@ exit_one_client(struct Client *client_p, struct Client *source_p, ** that the client can show the "**signoff" message). ** (Note: The notice is to the local clients *only*) */ - sendto_common_channels_local(source_p, ":%s!%s@%s QUIT :%s", - source_p->name, - source_p->username, - source_p->vhost, - comment); + sendto_common_channels_local(source_p, 0, + ":%s!%s@%s QUIT :%s", + source_p->name, source_p->username, + source_p->vhost, comment); DLINK_FOREACH_SAFE(lp, next_lp, source_p->user->channel.head) { @@ -989,9 +1000,9 @@ exit_one_client(struct Client *client_p, struct Client *source_p, /* Clean up invitefield */ DLINK_FOREACH_SAFE(lp, next_lp, source_p->user->invited.head) - { + { del_invite(lp->data, source_p); - } + } /* Clean up allow lists */ del_all_accepts(source_p); @@ -1015,8 +1026,9 @@ exit_one_client(struct Client *client_p, struct Client *source_p, /* Check to see if the client isn't already on the dead list */ assert(dlinkFind(&dead_list, source_p) == NULL); - /* add to dead_list */ + /* add to dead client dlist */ lp = make_dlink_node(); + SetDead(source_p); dlinkAdd(source_p, lp, &dead_list); } @@ -1148,29 +1160,34 @@ remove_dependents(struct Client* client_p, void dead_link_on_write(struct Client *client_p, int ierrno) { + dlink_node *m; const char *notice; if(IsDefunct(client_p)) return; - SetDead(client_p); - if(client_p->flags & FLAGS_SENDQEX) + linebuf_donebuf(&client_p->localClient->buf_recvq); + linebuf_donebuf(&client_p->localClient->buf_sendq); + + if (IsSendQExceeded(client_p)) notice = "Max SendQ exceeded"; else notice = "Write error: connection closed"; - if (!IsPerson(client_p) && !IsUnknown(client_p)) + if (!IsPerson(client_p) && !IsUnknown(client_p) && !IsClosing(client_p)) { - sendto_realops_flags(FLAGS_ALL, L_ADMIN, + sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ADMIN, "Closing link to %s: %s", get_client_name(client_p, HIDE_IP), notice); - sendto_realops_flags(FLAGS_ALL, L_OPER, + sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_OPER, "Closing link to %s: %s", get_client_name(client_p, MASK_IP), notice); } - Debug((DEBUG_ERROR, "Closing link to %s: %s", - get_client_name(client_p, HIDE_IP), notice)); - exit_client(client_p, client_p, &me, "Closing link"); + Debug((DEBUG_ERROR, "Closing link to %s: %s", get_client_name(client_p, HIDE_IP), notice)); + assert(dlinkFind(&abort_list, client_p) == NULL); + m = make_dlink_node(); + dlinkAdd(client_p, m, &abort_list); + SetDead(client_p); /* You are dead my friend */ } /* @@ -1184,9 +1201,11 @@ dead_link_on_read(struct Client* client_p, int error) char errmsg[255]; int current_error = get_sockerr(client_p->localClient->fd); - if(IsDead(client_p)) + if(IsDefunct(client_p)) return; - SetDead(client_p); + + linebuf_donebuf(&client_p->localClient->buf_recvq); + linebuf_donebuf(&client_p->localClient->buf_sendq); Debug((DEBUG_ERROR, "READ ERROR: fd = %d %d %d", client_p->localClient->fd, current_error, error)); @@ -1198,12 +1217,12 @@ dead_link_on_read(struct Client* client_p, int error) if (error == 0) { /* Admins get the real IP */ - sendto_realops_flags(FLAGS_ALL, L_ADMIN, + sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ADMIN, "Server %s closed the connection", get_client_name(client_p, SHOW_IP)); /* Opers get a masked IP */ - sendto_realops_flags(FLAGS_ALL, L_OPER, + sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_OPER, "Server %s closed the connection", get_client_name(client_p, MASK_IP)); @@ -1218,7 +1237,7 @@ dead_link_on_read(struct Client* client_p, int error) get_client_name(client_p, MASK_IP), current_error); } - sendto_realops_flags(FLAGS_ALL, L_ALL, + sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ALL, "%s had been connected for %d day%s, %2d:%02d:%02d", client_p->name, connected/86400, (connected/86400 == 1) ? "" : "s", @@ -1237,6 +1256,35 @@ dead_link_on_read(struct Client* client_p, int error) exit_client(client_p, client_p, &me, errmsg); } +void +exit_aborted_clients(void) +{ + dlink_node *ptr, *next; + struct Client *target_p; + char *notice; + + DLINK_FOREACH_SAFE(ptr, next, abort_list.head) + { + target_p = ptr->data; + if (ptr->data == NULL) + { + sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ALL, + "Warning: null client on abort_list!"); + dlinkDelete(ptr, &abort_list); + free_dlink_node(ptr); + continue; + } + dlinkDelete(ptr, &abort_list); + if(IsSendQExceeded(target_p)) + notice = "Max SendQ exceeded"; + else + notice = "Write error: connection closed"; + + exit_client(target_p, target_p, &me, notice); + free_dlink_node(ptr); + } +} + /* ** exit_client - This is old "m_bye". Name changed, because this is not a ** protocol function, but a general server utility function. @@ -1275,151 +1323,148 @@ exit_client( char comment1[HOSTLEN + HOSTLEN + 2]; dlink_node *m; - if (IsClosing(source_p)) - return(0); - - SetClosing(source_p); - if (MyConnect(source_p)) - { - if (IsIpHash(source_p)) - remove_one_ip(&source_p->localClient->ip); - - delete_adns_queries(source_p->localClient->dns_query); - delete_identd_queries(source_p); - client_flush_input(source_p); - - /* This source_p could have status of one of STAT_UNKNOWN, STAT_CONNECTING - * STAT_HANDSHAKE or STAT_UNKNOWN - * all of which are lumped together into unknown_list - * - * In all above cases IsRegistered() will not be true. - */ - if (!IsRegistered(source_p)) - { - m = dlinkFind(&unknown_list,source_p); - if(m != NULL) - { - dlinkDelete(m, &unknown_list); - free_dlink_node(m); - } - } - if (IsOper(source_p)) - { - m = dlinkFind(&oper_list,source_p); - if(m != NULL) - { - dlinkDelete(m, &oper_list); - free_dlink_node(m); - } - } - if (IsClient(source_p)) - { - Count.local--; - - if(IsPerson(source_p)) /* a little extra paranoia */ - { - m = dlinkFind(&lclient_list,source_p); - if(m != NULL) - { - dlinkDelete(m,&lclient_list); - free_dlink_node(m); - } - } - } - - /* As soon as a client is known to be a server of some sort - * it has to be put on the serv_list, or SJOIN's to this new server - * from the connect burst will not be seen. - */ - if (IsServer(source_p) || IsConnecting(source_p) || - IsHandshake(source_p)) - { - m = dlinkFind(&serv_list,source_p); - if(m != NULL) - { - dlinkDelete(m,&serv_list); - free_dlink_node(m); - } - } - - if (IsServer(source_p)) - { - Count.myserver--; - if(ServerInfo.hub) - remove_lazylink_flags(source_p->localClient->serverMask); - else - uplink = NULL; - } - - if (IsPerson(source_p)) - sendto_realops_flags(FLAGS_CCONN, L_ALL, - "Client exiting: %s (%s@%s) [%s] [%s]", - source_p->name, source_p->username, source_p->host, - comment, - source_p->localClient->sockhost); - - log_user_exit(source_p); - - if (!IsDead(source_p)) - { - if (client_p != NULL && source_p != client_p) - sendto_one(source_p, "ERROR :Closing Link: %s %s (%s)", - source_p->vhost, source_p->name, comment); - else - sendto_one(source_p, "ERROR :Closing Link: %s (%s)", - source_p->vhost, comment); - } - } - - if(IsServer(source_p)) - { - if(ConfigServerHide.hide_servers) - { - /* set netsplit message to "me.name *.split" to still show - * that its a split, but hide the servers splitting - */ - ircsprintf(comment1,"%s *.split", me.name); - } - else - { - if((source_p->serv) && (source_p->serv->up)) - strcpy(comment1, source_p->serv->up); - else - strcpy(comment1, ""); - - strcat(comment1," "); - strcat(comment1, source_p->name); - } - - if(source_p->serv != NULL) /* XXX Why does this happen */ - remove_dependents(client_p, source_p, from, comment, comment1); - - if (source_p->servptr == &me) - { - sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ALL, - "%s was connected for %d seconds. %d/%d sendK/recvK.", - source_p->name, (int)(CurrentTime - source_p->firsttime), - source_p->localClient->sendK, - source_p->localClient->receiveK); - ilog(L_NOTICE, "%s was connected for %d seconds. %d/%d sendK/recvK.", - source_p->name, CurrentTime - source_p->firsttime, - source_p->localClient->sendK, source_p->localClient->receiveK); - } - } - - if(MyConnect(source_p)) { - close_connection(source_p); - SetDead(source_p); /* You are dead my friend */ + /* DO NOT REMOVE. exit_client can be called twice after a failed + * read/write. + */ + if(IsClosing(source_p)) + return 0; + + SetClosing(source_p); + + if (IsIpHash(source_p)) + remove_one_ip(&source_p->localClient->ip); + + delete_adns_queries(source_p->localClient->dns_query); + delete_identd_queries(source_p); + client_flush_input(source_p); + + /* This source_p could have status of one of STAT_UNKNOWN, STAT_CONNECTING + * STAT_HANDSHAKE or STAT_UNKNOWN + * all of which are lumped together into unknown_list + * + * In all above cases IsRegistered() will not be true. + */ + if (!IsRegistered(source_p)) + { + if ((m = dlinkFindDelete(&unknown_list, source_p)) != NULL) + free_dlink_node(m); + } + else if (IsOper(source_p)) + { + if ((m = dlinkFindDelete(&oper_list, source_p)) != NULL) + free_dlink_node(m); + } + if (IsClient(source_p)) + { + Count.local--; + + /* a little extra paranoia */ + if (IsPerson(source_p)) + dlinkDelete(&source_p->localClient->lclient_node, &lclient_list); + } + + /* As soon as a client is known to be a server of some sort + * it has to be put on the serv_list, or SJOIN's to this new server + * from the connect burst will not be seen. + */ + if (IsServer(source_p) || IsConnecting(source_p) || + IsHandshake(source_p)) + { + if ((m = dlinkFindDelete(&serv_list, source_p)) != NULL) + { + free_dlink_node(m); + } + } + + if (IsServer(source_p)) + { + Count.myserver--; + if(ServerInfo.hub) + remove_lazylink_flags(source_p->localClient->serverMask); + else + uplink = NULL; + } + + if (IsPerson(source_p)) + sendto_realops_flags(FLAGS_CCONN, L_ALL, + "Client exiting: %s (%s@%s) [%s] [%s]", + source_p->name, source_p->username, source_p->host, + comment, + source_p->localClient->sockhost); + + log_user_exit(source_p); + + if (!IsDead(source_p)) + { + if (client_p != NULL && source_p != client_p) + sendto_one(source_p, "ERROR :Closing Link: %s %s (%s)", + source_p->host, source_p->name, comment); + else + sendto_one(source_p, "ERROR :Closing Link: %s (%s)", + source_p->host, comment); + } + + /* + ** Currently only server connections can have + ** depending remote clients here, but it does no + ** harm to check for all local clients. In + ** future some other clients than servers might + ** have remotes too... + ** + ** Close the Client connection first and mark it + ** so that no messages are attempted to send to it. + ** (The following *must* make MyConnect(source_p) == FALSE!). + ** It also makes source_p->from == NULL, thus it's unnecessary + ** to test whether "source_p != target_p" in the following loops. + */ + close_connection(source_p); } + if (IsServer(source_p)) + { + if(ConfigServerHide.hide_servers) + { + /* set netsplit message to "me.name *.split" to still show + * that its a split, but hide the servers splitting + */ + ircsprintf(comment1,"%s *.split", me.name); + } + else + { + if((source_p->serv) && (source_p->serv->up)) + strcpy(comment1, source_p->serv->up); + else + strcpy(comment1, ""); + + strcat(comment1," "); + strcat(comment1, source_p->name); + } + + /* XXX Why does this happen */ + if (source_p->serv != NULL) + remove_dependents(client_p, source_p, from, comment, comment1); + + if (source_p->servptr == &me) + { + sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ALL, + "%s was connected for %d seconds. %d/%d sendK/recvK.", + source_p->name, (int)(CurrentTime - source_p->firsttime), + source_p->localClient->sendK, + source_p->localClient->receiveK); + ilog(L_NOTICE, "%s was connected for %d seconds. %d/%d sendK/recvK.", + source_p->name, CurrentTime - source_p->firsttime, + source_p->localClient->sendK, source_p->localClient->receiveK); + } + } + /* The client *better* be off all of the lists */ assert(dlinkFind(&unknown_list, source_p) == NULL); assert(dlinkFind(&lclient_list, source_p) == NULL); assert(dlinkFind(&serv_list, source_p) == NULL); assert(dlinkFind(&oper_list, source_p) == NULL); - + exit_one_client(client_p, source_p, from, comment); return client_p == source_p ? CLIENT_EXITED : 0; } @@ -1561,7 +1606,6 @@ del_all_accepts(struct Client *client_p) } } - /* * set_initial_nick * inputs @@ -1645,14 +1689,18 @@ change_local_nick(struct Client *client_p, struct Client *source_p, char *nick) !ConfigFileEntry.anti_nick_flood || (IsOper(source_p) && ConfigFileEntry.no_oper_flood)) { + /* XXX - the format of this notice should eventually be changed + * to either %s[%s@%s], or even better would be get_client_name() -bill + */ sendto_realops_flags(FLAGS_NCHANGE, L_ALL, "Nick change: From %s to %s [%s@%s]", source_p->name, nick, source_p->username, source_p->host); - sendto_common_channels_local(source_p, ":%s!%s@%s NICK :%s", - source_p->name, source_p->username, source_p->vhost, - nick); + sendto_common_channels_local(source_p, 1, + ":%s!%s@%s NICK :%s", + source_p->name, source_p->username, + source_p->vhost, nick); if (source_p->user) { add_history(source_p, 1); diff --git a/src/fileio.c b/src/fileio.c index ae923f1..18c93d8 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: fileio.c,v 1.3 2002/09/13 06:50:08 fishwaldo Exp $ + * $Id: fileio.c,v 1.4 2003/03/06 14:01:50 fishwaldo Exp $ */ #include "stdinc.h" #include "config.h" @@ -45,7 +45,7 @@ file_open(const char *filename, int mode, int fmode) int fd; fd = open(filename, mode, fmode); if (fd == MASTER_MAX) { - fd_close(fd); /* Too many FDs! */ + close(fd); /* Too many FDs! */ errno = ENFILE; fd = -1; } else if (fd >= 0) diff --git a/src/ircd.c b/src/ircd.c index 50f5e6b..97f53db 100644 --- a/src/ircd.c +++ b/src/ircd.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: ircd.c,v 1.10 2003/01/29 09:28:49 fishwaldo Exp $ + * $Id: ircd.c,v 1.11 2003/03/06 14:01:50 fishwaldo Exp $ */ #include "stdinc.h" @@ -90,13 +90,12 @@ struct Counter Count; struct ServerState_t server_state; struct timeval SystemTime; -int ServerRunning; /* GLOBAL - server execution state */ +int ServerRunning; /* GLOBAL - server execution state */ struct Client me; /* That's me */ struct LocalUser meLocalUser; /* That's also part of me */ struct Client* GlobalClientList = 0; /* Pointer to beginning of Client list */ -struct JupedChannel *JupedChannelList = 0; /* unknown/client pointer lists */ dlink_list unknown_list; /* unknown clients ON this server only */ @@ -170,7 +169,8 @@ static unsigned long get_vm_top(void) /* * get_maxrss - get the operating systems notion of the resident set size */ -unsigned long get_maxrss(void) +unsigned long +get_maxrss(void) { return get_vm_top() - initialVMTop; } @@ -330,7 +330,9 @@ io_loop(void) irc_sleep(st); comm_select(0); - + exit_aborted_clients(); + free_exited_clients(); + /* * Check to see whether we have to rehash the configuration .. */ @@ -612,6 +614,11 @@ int main(int argc, char *argv[]) setup_signals(); /* We need this to initialise the fd array before anything else */ fdlist_init(); + if (!server_state.foreground) + { + close_all_connections(); /* this needs to be before init_netio()! */ + } + init_log(logFileName); init_netio(); /* This needs to be setup early ! -- adrian */ /* Check if there is pidfile and daemon already running */ check_pidfile(pidFileName); @@ -619,11 +626,6 @@ int main(int argc, char *argv[]) eventInit(); init_sys(); - if (!server_state.foreground) - { - close_all_connections(); - } - init_log(logFileName); initBlockHeap(); init_dlink_nodes(); initialize_message_files(); @@ -631,7 +633,7 @@ int main(int argc, char *argv[]) init_hash(); id_init(); clear_scache_hash_table(); /* server cache name table */ - clear_ip_hash_table(); /* client host ip hash table */ + init_ip_hash_table(); /* client host ip hash table */ init_host_hash(); /* Host-hashtable. */ clear_hash_parse(); init_client(); diff --git a/src/ircdauth.c b/src/ircdauth.c index edff87c..b0a972c 100644 --- a/src/ircdauth.c +++ b/src/ircdauth.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: ircdauth.c,v 1.6 2003/01/29 09:28:49 fishwaldo Exp $ + * $Id: ircdauth.c,v 1.7 2003/03/06 14:01:50 fishwaldo Exp $ */ #include "stdinc.h" @@ -693,16 +693,10 @@ GreetUser(struct Client *client) ubuf[1] = '\0'; } -#if 0 - m = make_dlink_node(); - dlinkAdd(client, m, &lclient_list); -#endif + if ((m = dlinkFindDelete(&unknown_list, client)) != NULL) + free_dlink_node(m); - m = dlinkFind(&unknown_list, client); - assert(m != NULL); - - dlinkDelete(m, &unknown_list); - dlinkAdd(client, m, &lclient_list); + dlinkAdd(client, &client->localClient->lclient_node, &lclient_list); #if 0 sendto_serv_butone(client, diff --git a/src/list.c b/src/list.c index 061426b..12b0431 100644 --- a/src/list.c +++ b/src/list.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: list.c,v 1.5 2002/10/31 13:01:58 fishwaldo Exp $ + * $Id: list.c,v 1.6 2003/03/06 14:01:50 fishwaldo Exp $ */ #include "stdinc.h" @@ -54,7 +54,8 @@ int user_count=0; * */ static BlockHeap *user_heap; -void initUser(void) +void +initUser(void) { user_heap = BlockHeapCreate(sizeof(struct User), USER_HEAP_SIZE); if(!user_heap) @@ -68,7 +69,8 @@ void initUser(void) * side effects - add's an User information block to a client * if it was not previously allocated. */ -struct User* make_user(struct Client *client_p) +struct User* +make_user(struct Client *client_p) { struct User *user; @@ -94,7 +96,8 @@ struct User* make_user(struct Client *client_p) * side effects - add's an Server information block to a client * if it was not previously allocated. */ -struct Server *make_server(struct Client *client_p) +struct Server * +make_server(struct Client *client_p) { struct Server* serv = client_p->serv; @@ -127,35 +130,36 @@ struct Server *make_server(struct Client *client_p) * side effects - Decrease user reference count by one and release block, * if count reaches 0 */ -void free_user(struct User* user, struct Client* client_p) +void +free_user(struct User* user, struct Client* client_p) { if (--user->refcnt <= 0) + { + if (user->away) + MyFree((char *)user->away); + /* + * sanity check + */ + if (user->joined || user->refcnt < 0 || + user->invited.head || user->channel.head) { - if (user->away) - MyFree((char *)user->away); - /* - * sanity check - */ - if (user->joined || user->refcnt < 0 || - user->invited.head || user->channel.head) - { - sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ALL, - "* %#lx user (%s!%s@%s) %#lx %#lx %#lx %d %d *", - (unsigned long)client_p, client_p ? client_p->name : "", - client_p->username, client_p->host, (unsigned long)user, - (unsigned long)user->invited.head, - (unsigned long)user->channel.head, user->joined, - user->refcnt); - assert(!user->joined); - assert(!user->refcnt); - assert(!user->invited.head); - assert(!user->channel.head); - } - - BlockHeapFree(user_heap, user); - --user_count; - assert(user_count >= 0); + sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ALL, + "* %#lx user (%s!%s@%s) %#lx %#lx %#lx %d %d *", + (unsigned long)client_p, client_p ? client_p->name : "", + client_p->username, client_p->host, (unsigned long)user, + (unsigned long)user->invited.head, + (unsigned long)user->channel.head, user->joined, + user->refcnt); + assert(!user->joined); + assert(!user->refcnt); + assert(!user->invited.head); + assert(!user->channel.head); } + + BlockHeapFree(user_heap, user); + --user_count; + assert(user_count >= 0); + } } @@ -198,7 +202,8 @@ make_dlink_node(void) * output - NONE * side effects - free given dlink_node */ -void free_dlink_node(dlink_node *ptr) +void +free_dlink_node(dlink_node *ptr) { BlockHeapFree(dnode_heap, ptr); --links_count; @@ -214,7 +219,8 @@ void free_dlink_node(dlink_node *ptr) * output - NONE * side effects - NONE */ -void count_user_memory(int *count,int *user_memory_used) +void +count_user_memory(int *count,int *user_memory_used) { *count = user_count; *user_memory_used = user_count * sizeof(struct User); @@ -228,7 +234,8 @@ void count_user_memory(int *count,int *user_memory_used) * output - NONE * side effects - NONE */ -void count_links_memory(int *count,int *links_memory_used) +void +count_links_memory(int *count,int *links_memory_used) { *count = links_count; *links_memory_used = links_count * sizeof(dlink_node); diff --git a/src/listener.c b/src/listener.c index a75420f..105de37 100644 --- a/src/listener.c +++ b/src/listener.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: listener.c,v 1.5 2002/11/04 08:14:00 fishwaldo Exp $ + * $Id: listener.c,v 1.6 2003/03/06 14:01:50 fishwaldo Exp $ */ #include "stdinc.h" @@ -393,6 +393,14 @@ accept_connection(int pfd, void *data) fd = comm_accept(listener->fd, &sai); + if (fd < 0) + { + /* Re-register a new IO request for the next accept .. */ + comm_setselect(listener->fd, FDLIST_SERVICE, COMM_SELECT_READ, + accept_connection, listener, 0); + return; + } + copy_s_addr(IN_ADDR(addr), S_ADDR(sai)); #ifdef IPV6 @@ -406,13 +414,6 @@ accept_connection(int pfd, void *data) } #endif - if (fd < 0) - { - /* Re-register a new IO request for the next accept .. */ - comm_setselect(listener->fd, FDLIST_SERVICE, COMM_SELECT_READ, - accept_connection, listener, 0); - return; - } /* * check for connection limit */ diff --git a/src/m_error.c b/src/m_error.c index 3447090..61f3ef5 100644 --- a/src/m_error.c +++ b/src/m_error.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: m_error.c,v 1.5 2002/10/31 13:01:58 fishwaldo Exp $ + * $Id: m_error.c,v 1.6 2003/03/06 14:01:50 fishwaldo Exp $ */ #include "stdinc.h" @@ -48,15 +48,43 @@ struct Message error_msgtab = { * parv[0] = sender prefix * parv[*] = parameters */ -void m_error(struct Client *client_p, struct Client *source_p, - int parc, char *parv[]) +void +m_error(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) { - if (MyClient(source_p)) + char* para; + + para = (parc > 1 && *parv[1] != '\0') ? parv[1] : "<>"; + + ilog(L_ERROR, "Received ERROR message from %s: %s", + source_p->name, para); + + if (client_p == source_p) + { + sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ADMIN, + "ERROR :from %s -- %s", + get_client_name(client_p, HIDE_IP), para); + sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_OPER, + "ERROR :from %s -- %s", + get_client_name(client_p, MASK_IP), para); + } + else + { + sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_OPER, + "ERROR :from %s via %s -- %s", + source_p->name, get_client_name(client_p, MASK_IP), para); + sendto_realops_flags(FLAGS_ALL, L_ADMIN,"ERROR :from %s via %s -- %s", + source_p->name, + get_client_name(client_p, HIDE_IP), para); + } + + if(MyClient(source_p)) exit_client(client_p, source_p, source_p, "ERROR"); } -void ms_error(struct Client *client_p, struct Client *source_p, - int parc, char *parv[]) +void +ms_error(struct Client *client_p, struct Client *source_p, + int parc, char *parv[]) { char* para; diff --git a/src/packet.c b/src/packet.c index 029b96e..58e0ac2 100644 --- a/src/packet.c +++ b/src/packet.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: packet.c,v 1.9 2003/01/29 09:28:50 fishwaldo Exp $ + * $Id: packet.c,v 1.10 2003/03/06 14:01:50 fishwaldo Exp $ */ #include "stdinc.h" #include "tools.h" @@ -58,7 +58,7 @@ parse_client_queued(struct Client *client_p) for(;;) { - if (IsDead(client_p)) + if (IsClosing(client_p)) return; if (client_p->localClient == NULL) return; @@ -73,7 +73,7 @@ parse_client_queued(struct Client *client_p) if(dolen <= 0) break; - if(!IsDead(client_p)) + if(!IsDefunct(client_p)) { client_dopacket(client_p, readBuf, dolen); i++; @@ -95,7 +95,7 @@ parse_client_queued(struct Client *client_p) if (IsServer(client_p) || IsConnecting(client_p) || IsHandshake(client_p)) { - if(IsDead(client_p)) + if(IsDefunct(client_p)) return; if(client_p->localClient == NULL) return; @@ -104,7 +104,7 @@ parse_client_queued(struct Client *client_p) readBuf, READBUF_SIZE, LINEBUF_COMPLETE, LINEBUF_PARSED)) > 0) { - if (!IsDead(client_p)) + if (!IsDefunct(client_p)) client_dopacket(client_p, readBuf, dolen); else if(MyConnect(client_p)) { @@ -134,7 +134,7 @@ parse_client_queued(struct Client *client_p) */ for(;;) { - if (IsDead(client_p)) + if (IsDefunct(client_p)) break; /* This flood protection works as follows: @@ -258,7 +258,7 @@ read_ctrl_packet(int fd, void *data) reply = &lserver->slinkrpl; - if(IsDead(server)) + if(IsDefunct(server)) { return; } @@ -275,6 +275,7 @@ read_ctrl_packet(int fd, void *data) { if((length == -1) && ignoreErrno(errno)) goto nodata; + dead_link_on_read(server, length); return; } reply->command = tmp[0]; @@ -377,7 +378,7 @@ read_packet(int fd, void *data) #ifndef NDEBUG struct hook_io_data hdata; #endif - if(IsDead(client_p)) + if(IsDefunct(client_p)) return; assert(lclient_p != NULL); @@ -436,7 +437,7 @@ read_packet(int fd, void *data) client_p->lasttime = CurrentTime; if (client_p->lasttime > client_p->since) client_p->since = CurrentTime; - client_p->flags &= ~FLAGS_PINGSENT; + ClearPingSent(client_p); /* * Before we even think of parsing what we just read, stick @@ -453,35 +454,33 @@ read_packet(int fd, void *data) /* Attempt to parse what we have */ - if (!IsDead(client_p)) + parse_client_queued(client_p); + + /* Check to make sure we're not flooding */ + if (IsPerson(client_p) && + (linebuf_alloclen(&client_p->localClient->buf_recvq) > + ConfigFileEntry.client_flood)) { - parse_client_queued(client_p); - if (IsDead(client_p)) + if (!(ConfigFileEntry.no_oper_flood && IsOper(client_p))) + { + exit_client(client_p, client_p, client_p, "Excess Flood"); return; - - /* Check to make sure we're not flooding */ - if (IsPerson(client_p) && - (linebuf_alloclen(&client_p->localClient->buf_recvq) > - ConfigFileEntry.client_flood)) - { - if (!(ConfigFileEntry.no_oper_flood && IsOper(client_p))) - { - exit_client(client_p, client_p, client_p, "Excess Flood"); - return; - } } + } - /* server fd may have changed */ - fd_r = client_p->localClient->fd; + /* server fd may have changed */ + fd_r = client_p->localClient->fd; #ifndef HAVE_SOCKETPAIR - if (HasServlink(client_p)) - { - assert(client_p->localClient->fd_r > -1); - fd_r = client_p->localClient->fd_r; - } + if (HasServlink(client_p)) + { + assert(client_p->localClient->fd_r > -1); + fd_r = client_p->localClient->fd_r; + } #endif + if (!IsDefunct(client_p)) + { /* If we get here, we need to register for another COMM_SELECT_READ */ if (PARSE_AS_SERVER(client_p)) { diff --git a/src/s_bsd.c b/src/s_bsd.c index 5f31295..49a5117 100644 --- a/src/s_bsd.c +++ b/src/s_bsd.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: s_bsd.c,v 1.10 2003/01/29 09:28:50 fishwaldo Exp $ + * $Id: s_bsd.c,v 1.11 2003/03/06 14:01:50 fishwaldo Exp $ */ #include "stdinc.h" @@ -80,21 +80,9 @@ void close_all_connections(void) { int i; -#ifndef NDEBUG int fd; -#endif - /* XXX someone tell me why we care about 4 fd's ? */ - /* XXX btw, fd 3 is used for profiler ! */ -#if 0 -#ifndef VMS for (i = 0; i < MAXCONNECTIONS; ++i) -#else - for (i = 3; i < MAXCONNECTIONS; ++i) -#endif -#endif - - for (i = 4; i < MAXCONNECTIONS; ++i) { if (fd_table[i].flags.open) fd_close(i); @@ -102,17 +90,14 @@ close_all_connections(void) close(i); } - /* XXX should his hack be done in all cases? */ -#ifndef NDEBUG - /* fugly hack to reserve fd == 2 */ - (void)close(2); - fd = open("stderr.log",O_WRONLY|O_CREAT|O_APPEND,0644); - if( fd >= 0 ) + /* Make sure stdio descriptors (0-2) and profiler descriptor (3) + always go somewhere harmless. Use -foreground for profiling + or executing from gdb */ + for (i = 0; i < LOWEST_SAFE_FD; i++) { - dup2(fd, 2); - close(fd); + if ((fd = open(PATH_DEVNULL, O_RDWR)) < 0) + exit(-1); /* we're hosed if we can't even open /dev/null */ } -#endif } /* @@ -322,7 +307,6 @@ close_connection(struct Client *client_p) send_queued_write(client_p->localClient->fd, client_p); fd_close(client_p->localClient->fd); client_p->localClient->fd = -1; - SetDead(client_p); } if(HasServlink(client_p)) diff --git a/src/s_conf.c b/src/s_conf.c index e075475..81f9664 100644 --- a/src/s_conf.c +++ b/src/s_conf.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: s_conf.c,v 1.12 2003/01/29 09:28:50 fishwaldo Exp $ + * $Id: s_conf.c,v 1.13 2003/03/06 14:01:51 fishwaldo Exp $ */ #include "stdinc.h" @@ -94,7 +94,7 @@ static void clear_special_conf(struct ConfItem **); #define IP_HASH_SIZE 0x1000 -typedef struct ip_entry +struct ip_entry { #ifndef IPV6 u_int32_t ip; @@ -104,13 +104,14 @@ typedef struct ip_entry int count; time_t last_attempt; struct ip_entry *next; -} IP_ENTRY; - -static IP_ENTRY *ip_hash_table[IP_HASH_SIZE]; +}; +static struct ip_entry *ip_hash_table[IP_HASH_SIZE]; +static BlockHeap *ip_entry_heap = NULL; +static int ip_entries_count = 0; static int hash_ip(struct irc_inaddr *); - -static IP_ENTRY *find_or_add_ip(struct irc_inaddr*); +static void garbage_collect_ip_entries(void); +static struct ip_entry *find_or_add_ip(struct irc_inaddr*); /* general conf items link list root */ struct ConfItem* ConfigItemList = NULL; @@ -420,7 +421,7 @@ check_client(struct Client *client_p, struct Client *source_p, char *username) switch( i ) { case SOCKET_ERROR: - (void)exit_client(client_p, source_p, &me, "Socket Error"); + exit_client(client_p, source_p, &me, "Socket Error"); break; case TOO_MANY: @@ -466,17 +467,17 @@ check_client(struct Client *client_p, struct Client *source_p, char *username) source_p->localClient->listener->port); ilog(L_INFO, - "Unauthorised client connection from %s on [%s/%u].", + "Unauthorized client connection from %s on [%s/%u].", get_client_name(source_p, SHOW_IP), source_p->localClient->listener->name, source_p->localClient->listener->port); - (void)exit_client(client_p, source_p, &me, - "You are not authorized to use this server"); + exit_client(client_p, source_p, &me, + "You are not authorised to use this server"); break; } case BANNED_CLIENT: - (void)exit_client(client_p,client_p, &me, "*** Banned "); + exit_client(client_p,client_p, &me, "*** Banned "); ServerStats->is_ref++; break; @@ -575,10 +576,10 @@ verify_access(struct Client* client_p, const char* username) * output - * side effects - do actual attach */ -static -int attach_iline(struct Client *client_p, struct ConfItem *aconf) +static int +attach_iline(struct Client *client_p, struct ConfItem *aconf) { - IP_ENTRY *ip_found; + struct ip_entry *ip_found; ip_found = find_or_add_ip(&client_p->localClient->ip); SetIpHash(client_p); @@ -601,45 +602,19 @@ int attach_iline(struct Client *client_p, struct ConfItem *aconf) return(attach_conf(client_p, aconf)); } -/* link list of free IP_ENTRY's */ - -static IP_ENTRY *free_ip_entries; - /* - * clear_ip_hash_table() + * init_ip_hash_table() * * input - NONE * output - NONE - * side effects - clear the ip hash table - * + * side effects - allocate memory for ip_entry(s) + * - clear the ip hash table */ void -clear_ip_hash_table() +init_ip_hash_table() { - void *block_IP_ENTRIES; /* block of IP_ENTRY's */ - IP_ENTRY *new_IP_ENTRY; /* new IP_ENTRY being made */ - IP_ENTRY *last_IP_ENTRY; /* last IP_ENTRY in chain */ - int size; - int n_left_to_allocate = MAXCONNECTIONS; - - size = sizeof(IP_ENTRY) + (sizeof(IP_ENTRY) & (sizeof(void*) - 1) ); - - block_IP_ENTRIES = (void *)MyMalloc((size * n_left_to_allocate)); - - free_ip_entries = (IP_ENTRY *)block_IP_ENTRIES; - last_IP_ENTRY = free_ip_entries; - - /* *shudder* pointer arithmetic */ - while(--n_left_to_allocate) - { - block_IP_ENTRIES = (void *)((unsigned long)block_IP_ENTRIES + - (unsigned long) size); - new_IP_ENTRY = (IP_ENTRY *)block_IP_ENTRIES; - last_IP_ENTRY->next = new_IP_ENTRY; - new_IP_ENTRY->next = (IP_ENTRY *)NULL; - last_IP_ENTRY = new_IP_ENTRY; - } + ip_entry_heap = BlockHeapCreate(sizeof(struct ip_entry), 2*MAXCONNECTIONS); memset((void *)ip_hash_table, 0, sizeof(ip_hash_table)); } @@ -649,52 +624,44 @@ clear_ip_hash_table() * inputs - client_p * - name * - * output - pointer to an IP_ENTRY element + * output - pointer to a struct ip_entry * side effects - * - * If the ip # was not found, a new IP_ENTRY is created, and the ip + * If the ip # was not found, a new struct ip_entry is created, and the ip * count set to 0. - * XXX: Broken for IPv6 */ -static IP_ENTRY * +static struct ip_entry * find_or_add_ip(struct irc_inaddr *ip_in) { - int hash_index; - IP_ENTRY *ptr, *newptr; + struct ip_entry *ptr, *newptr; + int hash_index=hash_ip(ip_in); - for(ptr = ip_hash_table[hash_index = hash_ip(ip_in)]; ptr; - ptr = ptr->next) + for(ptr = ip_hash_table[hash_index]; ptr; ptr = ptr->next) { - if(!memcmp(&ptr->ip, ip_in, sizeof(struct irc_inaddr))) - { - return(ptr); - } - } - if ((ptr = ip_hash_table[hash_index]) != NULL) + if(memcmp(&ptr->ip, ip_in, sizeof(struct irc_inaddr)) == 0) { - if (free_ip_entries == NULL) - outofmemory(); - - newptr = ip_hash_table[hash_index] = free_ip_entries; - free_ip_entries = newptr->next; - - memcpy(&newptr->ip, ip_in, sizeof(struct irc_inaddr)); - newptr->count = 0; - newptr->last_attempt = 0; - newptr->next = ptr; - return(newptr); + /* Found entry already in hash, return it. */ + return(ptr); } + } - if (free_ip_entries == NULL) - outofmemory(); + if (ip_entries_count >= (2*MAXCONNECTIONS)) + garbage_collect_ip_entries(); - ptr = ip_hash_table[hash_index] = free_ip_entries; - free_ip_entries = ptr->next; - memcpy(&ptr->ip, ip_in, sizeof(struct irc_inaddr)); - ptr->count = 0; - ptr->next = NULL; - return(ptr); + newptr = BlockHeapAlloc(ip_entry_heap); + ip_entries_count++; + memcpy(&newptr->ip, ip_in, sizeof(struct irc_inaddr)); + newptr->count = 0; + newptr->last_attempt = 0; + + if ((ptr = ip_hash_table[hash_index]) != NULL) + newptr->next = ptr; + else + newptr->next = NULL; + + ip_hash_table[hash_index] = newptr; + return(newptr); } /* @@ -702,19 +669,20 @@ find_or_add_ip(struct irc_inaddr *ip_in) * * inputs - unsigned long IP address value * output - NONE - * side effects - ip address listed, is looked up in ip hash table + * side effects - The ip address given, is looked up in ip hash table * and number of ip#'s for that ip decremented. - * if ip # count reaches 0, the IP_ENTRY is returned - * to the free_ip_enties link list. + * If ip # count reaches 0 and has expired, + * the struct ip_entry is returned to the ip_entry_heap */ void remove_one_ip(struct irc_inaddr *ip_in) { - IP_ENTRY *ptr, **lptr; + struct ip_entry *ptr; + struct ip_entry *last_ptr = NULL; int hash_index = hash_ip(ip_in); - for (lptr = ip_hash_table+hash_index, ptr = *lptr; ptr; - lptr=&ptr->next, ptr=*lptr) + + for(ptr = ip_hash_table[hash_index]; ptr; ptr = ptr->next) { #ifndef IPV6 if (ptr->ip != PIN_ADDR(ip_in)) @@ -727,13 +695,18 @@ remove_one_ip(struct irc_inaddr *ip_in) if (ptr->count > 0) ptr->count--; if (ptr->count == 0 && - (CurrentTime-ptr->last_attempt)>ConfigFileEntry.throttle_time) + (CurrentTime-ptr->last_attempt) >= ConfigFileEntry.throttle_time) { - *lptr = ptr->next; - ptr->next = free_ip_entries; - free_ip_entries = ptr; + if (last_ptr != NULL) + last_ptr->next = ptr->next; + else + ip_hash_table[hash_index] = ptr->next; + + BlockHeapFree(ip_entry_heap, ptr); + ip_entries_count--; return; } + last_ptr = ptr; } } @@ -793,24 +766,57 @@ hash_ip(struct irc_inaddr *addr) void count_ip_hash(int *number_ips_stored,u_long *mem_ips_stored) { - IP_ENTRY *ip_hash_ptr; + struct ip_entry *ptr; int i; *number_ips_stored = 0; *mem_ips_stored = 0; for (i = 0; i < IP_HASH_SIZE ;i++) + { + for (ptr = ip_hash_table[i]; ptr; ptr = ptr->next) { - ip_hash_ptr = ip_hash_table[i]; - while(ip_hash_ptr) - { - *number_ips_stored = *number_ips_stored + 1; - *mem_ips_stored = *mem_ips_stored + - sizeof(IP_ENTRY); - - ip_hash_ptr = ip_hash_ptr->next; - } + *number_ips_stored += 1; + *mem_ips_stored += sizeof(struct ip_entry); } + } +} + +/* + * garbage_collect_ip_entries() + * + * input - NONE + * output - NONE + * side effects - free up all ip entries with no connections + */ +static void +garbage_collect_ip_entries(void) +{ + struct ip_entry *ptr; + struct ip_entry *last_ptr; + struct ip_entry *next_ptr; + int i; + + for(i = 0; i < IP_HASH_SIZE; i++) + { + last_ptr = NULL; + for(ptr = ip_hash_table[i]; ptr; ptr = next_ptr) + { + next_ptr = ptr->next; + + if (ptr->count == 0) + { + if (last_ptr != NULL) + last_ptr->next = ptr->next; + else + ip_hash_table[i] = ptr->next; + BlockHeapFree(ip_entry_heap, ptr); + ip_entries_count--; + } + else + last_ptr = ptr; + } + } } /* @@ -822,9 +828,9 @@ count_ip_hash(int *number_ips_stored,u_long *mem_ips_stored) */ void iphash_stats(struct Client *client_p, struct Client *source_p, - int parc, char *parv[],FBFILE* out) + int parc, char *parv[],FBFILE* out) { - IP_ENTRY *ip_hash_ptr; + struct ip_entry *ptr; int i; int collision_count; char result_buf[256]; @@ -833,36 +839,32 @@ iphash_stats(struct Client *client_p, struct Client *source_p, sendto_one(source_p,":%s NOTICE %s :*** hash stats for iphash", me.name,client_p->name); else - { - (void)sprintf(result_buf,"*** hash stats for iphash\n"); - (void)fbputs(result_buf,out); - } + { + (void)sprintf(result_buf,"*** hash stats for iphash\n"); + (void)fbputs(result_buf,out); + } for(i = 0; i < IP_HASH_SIZE ;i++) - { - ip_hash_ptr = ip_hash_table[i]; + { + collision_count = 0; + for (ptr = ip_hash_table[i]; ptr; ptr = ptr->next) + collision_count++; - collision_count = 0; - while(ip_hash_ptr) - { - collision_count++; - ip_hash_ptr = ip_hash_ptr->next; - } - if(collision_count) - { - if(out == NULL) - { - sendto_one(source_p,":%s NOTICE %s :Entry %d (0x%X) Collisions %d", - me.name,client_p->name,i,i,collision_count); - } - else - { - (void)sprintf(result_buf,"Entry %d (0x%X) Collisions %d\n", - i,i,collision_count); - (void)fbputs(result_buf,out); - } - } + if(collision_count != 0) + { + if(out == NULL) + { + sendto_one(source_p,":%s NOTICE %s :Entry %d (0x%X) Collisions %d", + me.name,client_p->name,i,i,collision_count); + } + else + { + (void)sprintf(result_buf,"Entry %d (0x%X) Collisions %d\n", + i,i,collision_count); + (void)fbputs(result_buf,out); + } } + } } /* @@ -900,9 +902,7 @@ detach_conf(struct Client* client_p,struct ConfItem* aconf) } } if (aconf && !--aconf->clients && IsIllegal(aconf)) - { free_conf(aconf); - } dlinkDelete(ptr, &client_p->localClient->confs); free_dlink_node(ptr); return(0); @@ -1542,7 +1542,7 @@ lookup_confhost(struct ConfItem* aconf) int conf_connect_allowed(struct irc_inaddr *addr, int aftype) { - IP_ENTRY *ip_found; + struct ip_entry *ip_found; struct ConfItem *aconf = find_dline_conf(addr,aftype); /* DLINE exempt also gets you out of static limits/pacing... */ @@ -1555,10 +1555,10 @@ conf_connect_allowed(struct irc_inaddr *addr, int aftype) ip_found = find_or_add_ip(addr); if ((CurrentTime - ip_found->last_attempt) < ConfigFileEntry.throttle_time) - { - ip_found->last_attempt = CurrentTime; - return(TOO_FAST); - } + { + ip_found->last_attempt = CurrentTime; + return(TOO_FAST); + } ip_found->last_attempt = CurrentTime; return(0); } @@ -2091,8 +2091,8 @@ void clear_out_old_conf(void) * side effects - This function removes I/P conf items */ -static -void flush_deleted_I_P(void) +static void +flush_deleted_I_P(void) { struct ConfItem **tmp = &ConfigItemList; struct ConfItem *tmp2; diff --git a/src/s_log.c b/src/s_log.c index ad5c263..882a6a5 100644 --- a/src/s_log.c +++ b/src/s_log.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: s_log.c,v 1.5 2002/11/01 01:32:37 fishwaldo Exp $ + * $Id: s_log.c,v 1.6 2003/03/06 14:01:51 fishwaldo Exp $ */ #include "stdinc.h" @@ -86,6 +86,12 @@ static const char *logLevelToString[] = static int open_log(const char* filename) { +#ifndef DEBUG + if (!server_state.foreground) + { + close(2); /* let the logfile grab fd 2 to catch stderr */ + } +#endif logFile = fbopen(filename, "a"); if (logFile == NULL) { diff --git a/src/s_serv.c b/src/s_serv.c index 0b8c124..aa8eb78 100644 --- a/src/s_serv.c +++ b/src/s_serv.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: s_serv.c,v 1.15 2003/01/29 09:28:50 fishwaldo Exp $ + * $Id: s_serv.c,v 1.16 2003/03/06 14:01:51 fishwaldo Exp $ */ #include "stdinc.h" @@ -148,8 +148,9 @@ static void cjoin_all(struct Client *client_p); static CNCB serv_connect_callback; -void slink_error(unsigned int rpl, unsigned int len, unsigned char *data, - struct Client *server_p) +void +slink_error(unsigned int rpl, unsigned int len, unsigned char *data, + struct Client *server_p) { assert(rpl == SLINKRPL_ERROR); @@ -158,11 +159,13 @@ void slink_error(unsigned int rpl, unsigned int len, unsigned char *data, sendto_realops_flags(FLAGS_ALL, L_ALL, "SlinkError for %s: %s", server_p->name, data); + /* XXX should this be exit_client? */ exit_client(server_p, server_p, &me, "servlink error -- terminating link"); } -void slink_zipstats(unsigned int rpl, unsigned int len, unsigned char *data, - struct Client *server_p) +void +slink_zipstats(unsigned int rpl, unsigned int len, unsigned char *data, + struct Client *server_p) { struct ZipStats zipstats; unsigned long in = 0, in_wire = 0, out = 0, out_wire = 0; @@ -281,12 +284,13 @@ struct EncCapability *check_cipher(struct Client *client_p, * according to given config entry --Jto * XXX - this is only called with me.name as name */ -const char* my_name_for_link(const char* name, struct ConfItem* aconf) +const char* +my_name_for_link(const char* name, struct ConfItem* aconf) { if(aconf->fakename) return(aconf->fakename); else - return(name); + return(name); } /* @@ -295,7 +299,8 @@ const char* my_name_for_link(const char* name, struct ConfItem* aconf) * output - none * side effects - server is added to global_serv_list */ -void add_server_to_list(struct Client *client_p) +void +add_server_to_list(struct Client *client_p) { dlink_node *ptr; @@ -305,36 +310,11 @@ void add_server_to_list(struct Client *client_p) return; } -/* - * remove_server_from_list() - * - * input - pointer to client - * output - none - * side effects - server is removed from GlocalServerList - */ -void remove_server_from_list(struct Client *client_p) -{ - dlink_node *ptr; - struct Client *target_p; - - for (ptr = global_serv_list.head; ptr; ptr = ptr->next) - { - target_p = ptr->data; - - if (client_p == target_p) - { - dlinkDelete(ptr,&global_serv_list); - free_dlink_node(ptr); - break; - } - } - return; -} - /* * write_links_file */ -void write_links_file(void* notused) +void +write_links_file(void* notused) { MessageFileLine *next_mptr = 0; MessageFileLine *mptr = 0; @@ -354,7 +334,7 @@ void write_links_file(void* notused) if ((file = fbopen(MessageFileptr->fileName, "w")) == 0) return; - for( mptr = MessageFileptr->contentsOfFile; mptr; mptr = next_mptr) + for (mptr = MessageFileptr->contentsOfFile; mptr; mptr = next_mptr) { next_mptr = mptr->next; MyFree(mptr); @@ -430,8 +410,9 @@ void write_links_file(void* notused) * * returns: (see #defines) */ -int hunt_server(struct Client *client_p, struct Client *source_p, char *command, - int server, int parc, char *parv[]) +int +hunt_server(struct Client *client_p, struct Client *source_p, char *command, + int server, int parc, char *parv[]) { struct Client *target_p; int wilds; @@ -633,7 +614,8 @@ try_connections(void *unused) Debug((DEBUG_NOTICE,"Next connection check : %s", myctime(next))); } -int check_server(const char *name, struct Client* client_p, int cryptlink) +int +check_server(const char *name, struct Client* client_p, int cryptlink) { struct ConfItem *aconf=NULL; struct ConfItem *server_aconf=NULL; @@ -750,8 +732,9 @@ int check_server(const char *name, struct Client* client_p, int cryptlink) * side effects - send the CAPAB line to a server -orabidoo * */ -void send_capabilities(struct Client *client_p, struct ConfItem *aconf, - int cap_can_send, int enc_can_send ) +void +send_capabilities(struct Client *client_p, struct ConfItem *aconf, + int cap_can_send, int enc_can_send ) { struct Capability *cap; char msgbuf[BUFSIZE]; @@ -815,7 +798,8 @@ void send_capabilities(struct Client *client_p, struct ConfItem *aconf, * output - NONE * side effects - NICK message is sent towards given client_p */ -void sendnick_TS(struct Client *client_p, struct Client *target_p) +void +sendnick_TS(struct Client *client_p, struct Client *target_p) { static char ubuf[12]; @@ -859,7 +843,8 @@ void sendnick_TS(struct Client *client_p, struct Client *target_p) * output - NONE * side effects - If this client is not known by this lazyleaf, send it */ -void client_burst_if_needed(struct Client *client_p, struct Client *target_p) +void +client_burst_if_needed(struct Client *client_p, struct Client *target_p) { if (!ServerInfo.hub) return; if (!MyConnect(client_p)) return; @@ -880,7 +865,8 @@ void client_burst_if_needed(struct Client *client_p, struct Client *target_p) * side effects - build up string representing capabilities of server listed */ -const char* show_capabilities(struct Client* target_p) +const char* +show_capabilities(struct Client* target_p) { static char msgbuf[BUFSIZE]; struct Capability* cap; @@ -931,7 +917,8 @@ const char* show_capabilities(struct Client* target_p) * side effects - */ -int server_estab(struct Client *client_p) +int +server_estab(struct Client *client_p) { struct Client* target_p; struct ConfItem* aconf; @@ -1067,7 +1054,7 @@ int server_estab(struct Client *client_p) */ client_p->servptr = &me; - if (IsDead(client_p)) + if (IsClosing(client_p)) return CLIENT_EXITED; SetServer(client_p); @@ -1082,9 +1069,14 @@ int server_estab(struct Client *client_p) { dlinkDelete(m, &unknown_list); dlinkAdd(client_p, m, &serv_list); - } else { - sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ADMIN, "Tried to register (%s) server but it was already registered!?!", host); - exit_client(client_p, client_p, client_p, "Tried to register server but it was already registered?!?"); + } + else + { + sendto_realops_flags(FLAGS_ALL, L_ADMIN, + "Tried to register (%s) server but it was already registered!?!", + host); + exit_client(client_p, client_p, client_p, + "Tried to register server but it was already registered?!?"); } Count.server++; @@ -1232,7 +1224,8 @@ int server_estab(struct Client *client_p) return 0; } -static void start_io(struct Client *server) +static void +start_io(struct Client *server) { unsigned char *buf; int c = 0; @@ -1281,7 +1274,7 @@ static void start_io(struct Client *server) } #endif - while(1) + for(;;) { linecount++; @@ -1347,7 +1340,8 @@ static void start_io(struct Client *server) * output - success: 0 / failure: -1 * side effect - fork, and exec SERVLINK to handle this connection */ -static int fork_server(struct Client *server) +static int +fork_server(struct Client *server) { int ret; int i; @@ -1413,7 +1407,7 @@ static int fork_server(struct Client *server) else if (ret == 0) { /* set our fds as non blocking and close everything else */ - for(i = 0; i < HARD_FDLIMIT; i++) + for(i = LOWEST_SAFE_FD; i < HARD_FDLIMIT; i++) { if ((i == slink_fds[0][0][0]) || (i == slink_fds[0][0][1]) || @@ -1431,10 +1425,7 @@ static int fork_server(struct Client *server) } else { -#if defined(VMS) || defined(__CYGWIN__) - if (i > 2) /* don't close std* */ -#endif - close(i); + close(i); } } @@ -1460,7 +1451,7 @@ static int fork_server(struct Client *server) } else { - fd_close( server->localClient->fd ); + fd_close(server->localClient->fd); /* close the childs end of the pipes */ close(slink_fds[0][0][0]); @@ -1546,7 +1537,8 @@ fork_error: * side effects - send a server burst * bugs - still too long */ -static void server_burst(struct Client *client_p) +static +void server_burst(struct Client *client_p) { /* @@ -1805,7 +1797,8 @@ remove_lazylink_flags(unsigned long mask) * output - NONE * side effects - */ -static void burst_members(struct Client *client_p, dlink_list *list) +static void +burst_members(struct Client *client_p, dlink_list *list) { struct Client *target_p; dlink_node *ptr; @@ -1830,7 +1823,8 @@ static void burst_members(struct Client *client_p, dlink_list *list) * output - NONE * side effects - This version also has to check the bitmap for lazylink */ -static void burst_ll_members(struct Client *client_p, dlink_list *list) +static void +burst_ll_members(struct Client *client_p, dlink_list *list) { struct Client *target_p; dlink_node *ptr; @@ -1857,7 +1851,8 @@ static void burst_ll_members(struct Client *client_p, dlink_list *list) * output - none * side effects - */ -void set_autoconn(struct Client *source_p,char *parv0,char *name,int newval) +void +set_autoconn(struct Client *source_p,char *parv0,char *name,int newval) { struct ConfItem *aconf; @@ -1890,7 +1885,8 @@ void set_autoconn(struct Client *source_p,char *parv0,char *name,int newval) } -void initServerMask(void) +void +initServerMask(void) { freeMask = 0xFFFFFFFFUL; } @@ -1902,7 +1898,8 @@ void initServerMask(void) * output - unsigned long next unused mask for use in LL * side effects - */ -unsigned long nextFreeMask() +unsigned long +nextFreeMask() { int i; unsigned long mask; @@ -2242,9 +2239,8 @@ serv_connect_callback(int fd, int status, void *data) /* * sends a CRYPTLINK SERV command. */ -void cryptlink_init(struct Client *client_p, - struct ConfItem *aconf, - int fd) +void +cryptlink_init(struct Client *client_p, struct ConfItem *aconf, int fd) { char *encrypted; char *key_to_send; diff --git a/src/s_user.c b/src/s_user.c index 743dd6d..ad3bcc1 100644 --- a/src/s_user.c +++ b/src/s_user.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: s_user.c,v 1.43 2003/03/06 11:33:33 fishwaldo Exp $ + * $Id: s_user.c,v 1.44 2003/03/06 14:01:51 fishwaldo Exp $ */ #include "stdinc.h" @@ -304,20 +304,22 @@ register_local_user(struct Client *client_p, struct Client *source_p, if(ConfigFileEntry.ping_cookie) { - if(!(source_p->flags & FLAGS_PINGSENT) && source_p->localClient->random_ping == 0) - { - source_p->localClient->random_ping = (unsigned long)rand(); - sendto_one(source_p, "PING :%lu", (unsigned long)source_p->localClient->random_ping); - source_p->flags |= FLAGS_PINGSENT; - return -1; - } - if(!(source_p->flags2 & FLAGS2_PING_COOKIE)) - { - return -1; - } + if(!IsPingSent(source_p) && + source_p->localClient->random_ping == 0) + { + source_p->localClient->random_ping = (unsigned long)rand(); + sendto_one(source_p, + "PING :%lu", + (unsigned long)source_p->localClient->random_ping); + SetPingSent(source_p); + return -1; + } + if(!(source_p->flags2 & FLAGS2_PING_COOKIE)) + { + return -1; + } } - user->last = CurrentTime; /* Straight up the maximum rate of flooding... */ source_p->localClient->allow_read = MAX_FLOOD_BURST; @@ -337,10 +339,10 @@ register_local_user(struct Client *client_p, struct Client *source_p, aconf = ptr->data; if (aconf == NULL) - { - (void)exit_client(client_p, source_p, &me, "*** Not Authorized"); - return(CLIENT_EXITED); - } + { + exit_client(client_p, source_p, &me, "*** Not Authorized"); + return(CLIENT_EXITED); + } if (!IsGotId(source_p)) { @@ -348,14 +350,14 @@ register_local_user(struct Client *client_p, struct Client *source_p, int i = 0; if (IsNeedIdentd(aconf)) - { - ServerStats->is_ref++; - sendto_one(source_p, - ":%s NOTICE %s :*** Notice -- You need to install identd to use this server", - me.name, client_p->name); - (void)exit_client(client_p, source_p, &me, "Install identd"); - return(CLIENT_EXITED); - } + { + ServerStats->is_ref++; + sendto_one(source_p, + ":%s NOTICE %s :*** Notice -- You need to install identd to use this server", + me.name, client_p->name); + exit_client(client_p, source_p, &me, "Install identd"); + return(CLIENT_EXITED); + } p = username; @@ -375,13 +377,13 @@ register_local_user(struct Client *client_p, struct Client *source_p, /* password check */ if (!BadPtr(aconf->passwd) && strcmp(source_p->localClient->passwd, aconf->passwd)) - { - ServerStats->is_ref++; - sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), - me.name, source_p->name); - (void)exit_client(client_p, source_p, &me, "Bad Password"); - return(CLIENT_EXITED); - } + { + ServerStats->is_ref++; + sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), + me.name, source_p->name); + exit_client(client_p, source_p, &me, "Bad Password"); + return(CLIENT_EXITED); + } memset(source_p->localClient->passwd,0, sizeof(source_p->localClient->passwd)); /* report if user has &^>= etc. and set flags as needed in source_p */ @@ -407,8 +409,8 @@ register_local_user(struct Client *client_p, struct Client *source_p, nick, source_p->host); ServerStats->is_ref++; - (void)exit_client(client_p, source_p, &me, - "Sorry, server is full - try later"); + exit_client(client_p, source_p, &me, + "Sorry, server is full - try later"); return(CLIENT_EXITED); } @@ -421,7 +423,7 @@ register_local_user(struct Client *client_p, struct Client *source_p, nick, source_p->username, source_p->host); ServerStats->is_ref++; ircsprintf(tmpstr2, "Invalid username [%s]", source_p->username); - (void)exit_client(client_p, source_p, &me, tmpstr2); + exit_client(client_p, source_p, &me, tmpstr2); return(CLIENT_EXITED); } @@ -492,18 +494,17 @@ register_local_user(struct Client *client_p, struct Client *source_p, Count.totalrestartcount++; - m = dlinkFind(&unknown_list, source_p); - - assert(m != NULL); - if(m != NULL) + if ((m = dlinkFindDelete(&unknown_list, source_p)) != NULL) { - dlinkDelete(m, &unknown_list); - dlinkAdd(source_p, m, &lclient_list); - } else { - sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ADMIN, "Tried to register %s (%s@%s) but I couldn't find it?!?", - nick, source_p->username, source_p->host); - exit_client(client_p, source_p, &me, "Client exited"); - return CLIENT_EXITED; + free_dlink_node(m); + dlinkAdd(source_p, &source_p->localClient->lclient_node, &lclient_list); + } + else + { + sendto_realops_flags(FLAGS_ALL, L_ADMIN, "Tried to register %s (%s@%s) but I couldn't find it?!?", + nick, source_p->username, source_p->host); + exit_client(client_p, source_p, &me, "Client exited"); + return CLIENT_EXITED; } user_welcome(source_p); @@ -551,6 +552,7 @@ register_remote_user(struct Client *client_p, struct Client *source_p, kill_client(client_p, source_p, "%s (Server doesn't exist)", me.name); + /* XXX */ SetKilled(source_p); return exit_client(NULL, source_p, &me, "Ghosted Client"); } @@ -936,7 +938,7 @@ do_remote_user(char* nick, struct Client* client_p, struct Client* source_p, int user_mode(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { - int flag = 0; + int flag; int i; char **p, *m; struct Client *target_p; @@ -1151,7 +1153,7 @@ user_mode(struct Client *client_p, struct Client *source_p, int parc, char *parv */ send_umode_out(source_p, client_p, target_p, setflags); - return 0; + return(0); } /* @@ -1243,13 +1245,20 @@ user_welcome(struct Client *source_p) sendto_one(source_p, form_str(RPL_YOURHOST), me.name, source_p->name, get_listener_name(source_p->localClient->listener), ircd_version); +#if 0 /* ** Don't mess with this one - IRCII needs it! -Avalon */ + /* No one has needed this in years, but I remember when IRCII did! + * It sure confused me why my IRCII client hung at start up + * when I was writing my first ircd from scratch. ;-) + * - Dianora + */ sendto_one(source_p, "NOTICE %s :*** Your host is %s, running version %s", source_p->name, get_listener_name(source_p->localClient->listener), ircd_version); +#endif sendto_one(source_p, form_str(RPL_CREATED),me.name,source_p->name,creation); sendto_one(source_p, form_str(RPL_MYINFO), me.name, source_p->name, @@ -1324,7 +1333,7 @@ check_X_line(struct Client *client_p, struct Client *source_p) get_client_name(client_p, HIDE_IP)); } ServerStats->is_ref++; - (void)exit_client(client_p, source_p, &me, "Bad user info"); + exit_client(client_p, source_p, &me, "Bad user info"); return (CLIENT_EXITED); } else diff --git a/src/send.c b/src/send.c index 3c7f09a..035df97 100644 --- a/src/send.c +++ b/src/send.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: send.c,v 1.12 2003/01/29 09:28:50 fishwaldo Exp $ + * $Id: send.c,v 1.13 2003/03/06 14:01:51 fishwaldo Exp $ */ #include "stdinc.h" @@ -60,10 +60,8 @@ send_linebuf_remote(struct Client *, struct Client *, buf_head_t *); unsigned long current_serial=0L; static void -sendto_list_local(dlink_list *list, buf_head_t *linebuf); -static void -sendto_list_local_butone(struct Client *one, dlink_list *list, - buf_head_t *linebuf); +sendto_list_local(struct Client *one, dlink_list *list, + buf_head_t *linebuf); static void sendto_list_remote(struct Client *one, @@ -173,7 +171,7 @@ _send_linebuf(struct Client *to, buf_head_t *linebuf) linebuf_len(&to->localClient->buf_sendq), get_sendq(to)); if (IsClient(to)) - to->flags |= FLAGS_SENDQEX; + SetSendQExceeded(to); dead_link_on_write(to, 0); return -1; } @@ -191,7 +189,7 @@ _send_linebuf(struct Client *to, buf_head_t *linebuf) to->localClient->sendM += 1; me.localClient->sendM += 1; - send_queued_write(to->localClient->fd, to); + send_queued_write(to->localClient->fd, to); return 0; } /* send_linebuf() */ @@ -260,9 +258,8 @@ send_linebuf_remote(struct Client *to, struct Client *from, ** possible, and then if any data is left, a write is rescheduled. */ void -send_queued_write(int fd, void *data) +send_queued_write(int fd, struct Client *to) { - struct Client *to = data; int retlen; #ifndef NDEBUG struct hook_io_data hdata; @@ -338,7 +335,7 @@ send_queued_write(int fd, void *data) /* Finally, if we have any more data, reschedule a write */ if (linebuf_len(&to->localClient->buf_sendq)) comm_setselect(fd, FDLIST_IDLECLIENT, COMM_SELECT_WRITE, - send_queued_write, to, 0); + send_queued_slink_write, to, 0); } /* send_queued_write() */ /* @@ -580,10 +577,13 @@ sendto_list_anywhere(struct Client *one, struct Client *from, { target_p = ptr->data; + if (IsDefunct(target_p)) + continue; + if (target_p->from == one) continue; - if (MyConnect(target_p) && IsRegisteredUser(target_p) && !IsDead(target_p)) + if (MyConnect(target_p) && IsRegisteredUser(target_p)) { if(target_p->serial != current_serial) { @@ -662,6 +662,9 @@ sendto_server(struct Client *one, struct Client *source_p, { client_p = ptr->data; + /* If dead already skip */ + if (IsDead(client_p)) + continue; /* check against 'one' */ if (one && (client_p == one->from)) continue; @@ -717,7 +720,8 @@ sendto_server(struct Client *one, struct Client *source_p, * used by m_nick.c and exit_one_client. */ void -sendto_common_channels_local(struct Client *user, const char *pattern, ...) +sendto_common_channels_local(struct Client *user, int touser, + const char *pattern, ...) { va_list args; dlink_node *ptr; @@ -732,22 +736,20 @@ sendto_common_channels_local(struct Client *user, const char *pattern, ...) ++current_serial; - if (user->user != NULL) + DLINK_FOREACH_SAFE(ptr, ptr_next, user->user->channel.head) { - DLINK_FOREACH_SAFE(ptr, ptr_next, user->user->channel.head) - { - chptr = ptr->data; + chptr = ptr->data; - sendto_list_local(&chptr->locchanops, &linebuf); - sendto_list_local(&chptr->lochalfops, &linebuf); - sendto_list_local(&chptr->locvoiced, &linebuf); - sendto_list_local(&chptr->locpeons, &linebuf); - sendto_list_local(&chptr->locchanadmins, &linebuf); + sendto_list_local(user, &chptr->locchanops, &linebuf); + sendto_list_local(user, &chptr->lochalfops, &linebuf); + sendto_list_local(user, &chptr->locvoiced, &linebuf); + sendto_list_local(user, &chptr->locpeons, &linebuf); + sendto_list_local(user, &chptr->locchanadmins, &linebuf); } - if (MyConnect(user) && (user->serial != current_serial)) - send_linebuf(user, &linebuf); - } + if (touser && MyConnect(user) && + (user->serial != current_serial)) + send_linebuf(user, &linebuf); linebuf_donebuf(&linebuf); } /* sendto_common_channels() */ @@ -764,9 +766,7 @@ sendto_common_channels_local(struct Client *user, const char *pattern, ...) * locally connected to this server. */ void -sendto_channel_local(int type, - struct Channel *chptr, - const char *pattern, ...) +sendto_channel_local(int type, struct Channel *chptr, const char *pattern, ...) { va_list args; buf_head_t linebuf; @@ -782,21 +782,21 @@ sendto_channel_local(int type, switch(type) { case NON_CHANOPS: - sendto_list_local(&chptr->locvoiced, &linebuf); - sendto_list_local(&chptr->locpeons, &linebuf); + sendto_list_local(NULL, &chptr->locvoiced, &linebuf); + sendto_list_local(NULL, &chptr->locpeons, &linebuf); break; default: case ALL_MEMBERS: - sendto_list_local(&chptr->locpeons, &linebuf); + sendto_list_local(NULL, &chptr->locpeons, &linebuf); case ONLY_CHANOPS_HALFOPS_VOICED: - sendto_list_local(&chptr->locvoiced, &linebuf); + sendto_list_local(NULL, &chptr->locvoiced, &linebuf); case ONLY_CHANOPS_HALFOPS: - sendto_list_local(&chptr->lochalfops, &linebuf); + sendto_list_local(NULL, &chptr->lochalfops, &linebuf); case ONLY_CHANOPS: - sendto_list_local(&chptr->locchanops, &linebuf); + sendto_list_local(NULL, &chptr->locchanops, &linebuf); case ONLY_CHANADMIN: - sendto_list_local(&chptr->locchanadmins, &linebuf); + sendto_list_local(NULL, &chptr->locchanadmins, &linebuf); } linebuf_donebuf(&linebuf); } /* sendto_channel_local() */ @@ -815,8 +815,7 @@ sendto_channel_local(int type, */ void sendto_channel_local_butone(struct Client *one, int type, - struct Channel *chptr, - const char *pattern, ...) + struct Channel *chptr, const char *pattern, ...) { va_list args; buf_head_t linebuf; @@ -832,21 +831,21 @@ sendto_channel_local_butone(struct Client *one, int type, switch(type) { case NON_CHANOPS: - sendto_list_local_butone(one, &chptr->locvoiced, &linebuf); - sendto_list_local_butone(one, &chptr->locpeons, &linebuf); + sendto_list_local(one, &chptr->locvoiced, &linebuf); + sendto_list_local(one, &chptr->locpeons, &linebuf); break; default: case ALL_MEMBERS: - sendto_list_local_butone(one, &chptr->locpeons, &linebuf); + sendto_list_local(one, &chptr->locpeons, &linebuf); case ONLY_CHANOPS_HALFOPS_VOICED: - sendto_list_local_butone(one, &chptr->locvoiced, &linebuf); + sendto_list_local(one, &chptr->locvoiced, &linebuf); case ONLY_CHANOPS_HALFOPS: - sendto_list_local_butone(one, &chptr->lochalfops, &linebuf); + sendto_list_local(one, &chptr->lochalfops, &linebuf); case ONLY_CHANOPS: - sendto_list_local_butone(one, &chptr->locchanops, &linebuf); + sendto_list_local(one, &chptr->locchanops, &linebuf); case ONLY_CHANADMIN: - sendto_list_local_butone(one, &chptr->locchanadmins, &linebuf); + sendto_list_local(one, &chptr->locchanadmins, &linebuf); } linebuf_donebuf(&linebuf); } /* sendto_channel_local_butone() */ @@ -907,42 +906,6 @@ sendto_channel_remote(struct Client *one, /* * sendto_list_local * - * inputs - pointer to all members of this list - * - buffer to send - * - length of buffer - * output - NONE - * side effects - all members who are locally on this server on given list - * are sent given message. Right now, its always a channel list - * but there is no reason we could not use another dlink - * list to send a message to a group of people. - */ -static void -sendto_list_local(dlink_list *list, buf_head_t *linebuf_ptr) -{ - dlink_node *ptr; - dlink_node *ptr_next; - struct Client *target_p; - - DLINK_FOREACH_SAFE(ptr, ptr_next, list->head) - { - if ((target_p = ptr->data) == NULL) - continue; - - if (!MyConnect(target_p) || IsDead(target_p)) - continue; - - if (target_p->serial == current_serial) - continue; - - target_p->serial = current_serial; - - send_linebuf(target_p, linebuf_ptr); - } -} /* sendto_list_local() */ - -/* - * sendto_list_local_butone - * * inputs - pointer to client not to send to * - pointer to all members of this list * - buffer to send @@ -954,8 +917,8 @@ sendto_list_local(dlink_list *list, buf_head_t *linebuf_ptr) * another dlink list to send a message to a group of people. */ static void -sendto_list_local_butone(struct Client *one, dlink_list *list, - buf_head_t *linebuf_ptr) +sendto_list_local(struct Client *one, dlink_list *list, + buf_head_t *linebuf_ptr) { dlink_node *ptr; dlink_node *ptr_next; @@ -969,7 +932,7 @@ sendto_list_local_butone(struct Client *one, dlink_list *list, if (target_p == one) continue; - if (!MyConnect(target_p) || IsDead(target_p)) + if (!MyConnect(target_p) || IsDefunct(target_p)) continue; if (target_p->serial == current_serial) @@ -979,7 +942,7 @@ sendto_list_local_butone(struct Client *one, dlink_list *list, send_linebuf(target_p, linebuf_ptr); } -} /* sendto_list_local_butone() */ +} /* sendto_list_local() */ /* * sendto_list_remote(struct Client *one, @@ -1093,6 +1056,9 @@ sendto_match_butone(struct Client *one, struct Client *from, if (client_p == one) /* must skip the origin !! */ continue; + if (IsDefunct(client_p)) + continue; + if (match_it(client_p, mask, what)) send_linebuf(client_p, &local_linebuf); } @@ -1155,12 +1121,12 @@ sendto_anywhere(struct Client *to, struct Client *from, va_list args; buf_head_t linebuf; - linebuf_newbuf(&linebuf); - va_start(args, pattern); - if (IsDead(to)) return; + linebuf_newbuf(&linebuf); + va_start(args, pattern); + if(MyClient(to)) { if(IsServer(from)) diff --git a/src/tools.c b/src/tools.c index 6bab0be..0f6fdc4 100644 --- a/src/tools.c +++ b/src/tools.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: tools.c,v 1.4 2002/09/19 05:41:11 fishwaldo Exp $ + * $Id: tools.c,v 1.5 2003/03/06 14:01:51 fishwaldo Exp $ * * When you update these functions make sure you update the ones in tools.h * as well!!! @@ -62,7 +62,7 @@ dlinkAdd(void *data, dlink_node * m, dlink_list * list) /* Assumption: If list->tail != NULL, list->head != NULL */ if (list->head != NULL) list->head->prev = m; - else if (list->tail == NULL) + else /* if (list->tail == NULL) */ list->tail = m; list->head = m; @@ -97,7 +97,7 @@ dlinkAddTail(void *data, dlink_node *m, dlink_list *list) /* Assumption: If list->tail != NULL, list->head != NULL */ if (list->tail != NULL) list->tail->next = m; - else if (list->head == NULL) + else /* if (list->head == NULL) */ list->head = m; list->tail = m; @@ -186,19 +186,8 @@ dlinkFindDelete(dlink_list *list, void *data) { dlink_node *m; - DLINK_FOREACH(m, list->head) - { - if(m->data != data) - continue; - - if (m->next != NULL) - m->next->prev = m->prev; - else - list->tail = m->prev; - - m->next = m->prev = NULL; - list->length--; - return m; - } - return(NULL); + m = dlinkFind(list, data); + if (m) + dlinkDelete(m, list); + return(m); }