diff --git a/ChangeLog b/ChangeLog index ef8ee07..3418290 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,7 @@ Symbols are: (F) - Added Z umode to identify SSL clients, and added whois reply for SSL clients (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. * 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 7d5ec2a..adfa1d7 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,6 @@ -$Id: TODO,v 1.14 2002/11/21 13:23:37 fishwaldo Exp $ +$Id: TODO,v 1.15 2003/01/29 09:28:48 fishwaldo Exp $ +put back "expire_channels" stuff /stats g should report when a G line will expire SSL client support modes and channel related stuff diff --git a/include/channel.h b/include/channel.h index 34c8971..0196d13 100644 --- a/include/channel.h +++ b/include/channel.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: channel.h,v 1.10 2002/09/19 05:41:10 fishwaldo Exp $ + * $Id: channel.h,v 1.11 2003/01/29 09:28:48 fishwaldo Exp $ */ #ifndef INCLUDED_channel_h @@ -65,7 +65,7 @@ struct Channel dlink_list voiced; dlink_list peons; /* non ops, just members */ dlink_list deopped; /* users deopped on sjoin */ - + dlink_list locchanadmins; /* local versions of the above */ dlink_list locchanops; /* local versions of the above */ dlink_list lochalfops; diff --git a/include/client.h b/include/client.h index 82d31d4..1831c64 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.12 2002/11/20 14:13:56 fishwaldo Exp $ + * $Id: client.h,v 1.13 2003/01/29 09:28:48 fishwaldo Exp $ */ #ifndef INCLUDED_client_h @@ -40,9 +40,6 @@ #include "linebuf.h" #include "channel.h" #include "res.h" - - - #ifdef IPV6 #define HOSTIPLEN 53 /* sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255.ipv6") */ #else @@ -189,7 +186,7 @@ struct Client * client->vhost is the vitual host that users get by default with umode +x * if you want to change the presentation of the users host, do it here, and leave * client->host alone - */ + */ char vhost[HOSTLEN +1]; /* * client->swhois stores a swhois structure @@ -288,7 +285,6 @@ struct LocalUser char out_key[CIPHERKEYLEN]; #endif - int fd; /* >= 0, for local clients */ #ifndef HAVE_SOCKETPAIR int fd_r; /* fd for reading */ @@ -363,7 +359,7 @@ struct LocalUser #define SetServer(x) {(x)->status = STAT_SERVER; \ (x)->handler = SERVER_HANDLER; } - + #define SetClient(x) {(x)->status = STAT_CLIENT; \ (x)->handler = IsOper((x)) ? \ OPER_HANDLER : CLIENT_HANDLER; } @@ -492,6 +488,9 @@ struct LocalUser #define SetAccess(x) ((x)->flags |= FLAGS_CHKACCESS) #define IsClosing(x) ((x)->flags & FLAGS_CLOSING) #define SetClosing(x) ((x)->flags |= FLAGS_CLOSING) +#define ClearClosing(x) ((x)->flags &= ~FLAGS_CLOSING) +#define IsKilled(x) ((x)->flags & FLAGS_KILLED) +#define SetKilled(x) ((x)->flags |= FLAGS_KILLED) #define ClearAccess(x) ((x)->flags &= ~FLAGS_CHKACCESS) #define IsCryptIn(x) ((x)->flags & FLAGS_CRYPTIN) #define SetCryptIn(x) ((x)->flags |= FLAGS_CRYPTIN) @@ -519,7 +518,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)) /* oper flags */ #define MyOper(x) (MyConnect(x) && IsOper(x)) @@ -645,8 +644,8 @@ extern int set_initial_nick(struct Client *client_p, struct Client *source_p, char *nick); extern int change_local_nick(struct Client *client_p, struct Client *source_p, char *nick); -extern void dead_link(struct Client *client_p); -extern void exit_aborted_clients(void); +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); #endif /* INCLUDED_client_h */ diff --git a/include/ircd.h b/include/ircd.h index f581a73..fb54587 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.3 2002/09/13 06:50:06 fishwaldo Exp $ + * $Id: ircd.h,v 1.4 2003/01/29 09:28:48 fishwaldo Exp $ */ #ifndef INCLUDED_ircd_h @@ -78,9 +78,11 @@ extern char* infotext[]; extern char* serno; extern char* ircd_version; extern const char* logFileName; +extern const char* pidFileName; extern const char serveropts[]; extern int cold_start; extern int dorehash; +extern int doremotd; extern struct Client me; extern struct Client* GlobalClientList; extern struct Client* local[]; diff --git a/include/modules.h b/include/modules.h index 5c7c994..6aaeb67 100644 --- a/include/modules.h +++ b/include/modules.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: modules.h,v 1.3 2002/09/13 06:50:06 fishwaldo Exp $ + * $Id: modules.h,v 1.4 2003/01/29 09:28:48 fishwaldo Exp $ */ #ifndef INCLUDED_modules_h @@ -70,7 +70,7 @@ extern void _modinit(void); extern void _moddeinit(void); extern int unload_one_module (char *, int); -extern int load_one_module (char *); +extern int load_one_module (char *, int); extern int load_a_module (char *, int, int); extern int findmodule_byname (char *); extern char* irc_basename(char *); diff --git a/include/s_bsd.h b/include/s_bsd.h index 9d45d94..f699663 100644 --- a/include/s_bsd.h +++ b/include/s_bsd.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: s_bsd.h,v 1.3 2002/09/13 06:50:06 fishwaldo Exp $ + * $Id: s_bsd.h,v 1.4 2003/01/29 09:28:48 fishwaldo Exp $ */ #ifndef INCLUDED_s_bsd_h @@ -59,7 +59,6 @@ extern void report_error(int, const char*, const char*, int); extern int set_non_blocking(int); extern int set_sock_buffers(int, int); -extern void error_exit_client(struct Client*, int); extern int get_sockerr(int); extern int ignoreErrno(int ierrno); diff --git a/include/s_conf.h b/include/s_conf.h index 3c07622..95ad336 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.8 2003/01/27 04:20:36 fishwaldo Exp $ + * $Id: s_conf.h,v 1.9 2003/01/29 09:28:48 fishwaldo Exp $ */ #ifndef INCLUDED_s_conf_h @@ -88,7 +88,6 @@ struct ConfItem #define CONF_SERVER 0x0004 #define CONF_OPERATOR 0x0010 #define CONF_KILL 0x0040 -#define CONF_USERVER 0x0080 #define CONF_CLASS 0x0400 #define CONF_LEAF 0x0800 @@ -250,7 +249,7 @@ struct config_channel_entry int no_create_on_split; int no_join_on_split; int persist_time; - int oper_pass_resv; + int oper_pass_resv; int quiet_on_ban; int default_split_server_count; int default_split_user_count; @@ -393,7 +392,6 @@ extern void conf_add_d_conf(struct ConfItem *); extern void conf_add_x_conf(struct ConfItem *); extern void conf_add_fields(struct ConfItem*, char*, char *, char*, char *,char *); extern void conf_add_conf(struct ConfItem *); -extern void flush_expired_ips(void *); /* XXX consider moving these into kdparse.h */ extern void parse_k_file(FBFILE *fb); diff --git a/include/setup.h.in b/include/setup.h.in index a1bcad9..53a69a2 100644 --- a/include/setup.h.in +++ b/include/setup.h.in @@ -110,6 +110,9 @@ /* Define if you have the EVP_rc5_32_12_16_cfb function. */ #undef HAVE_EVP_RC5_32_12_16_CFB +/* Define if you have the dlfunc function. */ +#undef HAVE_DLFUNC + /* Define if you have the dlopen function. */ #undef HAVE_DLOPEN diff --git a/modules/core/m_die.c b/modules/core/m_die.c index 9a2c55a..ec9abd5 100644 --- a/modules/core/m_die.c +++ b/modules/core/m_die.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: m_die.c,v 1.2 2002/09/13 06:50:07 fishwaldo Exp $ + * $Id: m_die.c,v 1.3 2003/01/29 09:28:49 fishwaldo Exp $ */ #include "stdinc.h" @@ -57,7 +57,7 @@ _moddeinit(void) mod_del_cmd(&die_msgtab); } -const char *_version = "$Revision: 1.2 $"; +const char *_version = "$Revision: 1.3 $"; #endif /* * mo_die - DIE command handler @@ -117,6 +117,7 @@ static void mo_die(struct Client *client_p, struct Client *source_p, /* * this is a normal exit, tell the os it's ok */ + unlink(pidFileName); exit(0); /* NOT REACHED */ } diff --git a/modules/core/m_message.c b/modules/core/m_message.c index 742340b..20ffc27 100644 --- a/modules/core/m_message.c +++ b/modules/core/m_message.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: m_message.c,v 1.13 2002/10/31 13:01:57 fishwaldo Exp $ + * $Id: m_message.c,v 1.14 2003/01/29 09:28:49 fishwaldo Exp $ */ #include "stdinc.h" @@ -92,9 +92,9 @@ static void msg_client(int p_or_n, char *command, struct Client *source_p, struct Client *target_p, char *text); -static void handle_opers(int p_or_n, char *command, - struct Client *client_p, - struct Client *source_p, char *nick, char *text); +static void handle_special(int p_or_n, char *command, + struct Client *client_p, + struct Client *source_p, char *nick, char *text); struct Message privmsg_msgtab = { "PRIVMSG", 0, 0, 1, 0, MFLG_SLOW | MFLG_UNREG, 0L, @@ -122,7 +122,7 @@ _moddeinit(void) mod_del_cmd(¬ice_msgtab); } -const char *_version = "$Revision: 1.13 $"; +const char *_version = "$Revision: 1.14 $"; #endif /* @@ -401,7 +401,7 @@ build_target_list(int p_or_n, char *command, struct Client *client_p, if((IsOper(source_p) || IsServices(source_p)) && ((*nick == '$') || strchr(nick, '@'))) { - handle_opers(p_or_n, command, client_p, source_p, nick, text); + handle_special(p_or_n, command, client_p, source_p, nick, text); } else { @@ -782,30 +782,123 @@ flood_attack_channel(int p_or_n, struct Client *source_p, /* - * handle_opers + * handle_special * * inputs - server pointer * - client pointer * - nick stuff to grok for opers * - text to send if grok * output - none - * side effects - all the traditional oper type messages are parsed here. + * side effects - old style username@server is handled here for non opers + * opers are allowed username%hostname@server + * all the traditional oper type messages are also parsed here. * i.e. "/msg #some.host." * However, syntax has been changed. * previous syntax "/msg #some.host.mask" * now becomes "/msg $#some.host.mask" * previous syntax of: "/msg $some.server.mask" remains * This disambiguates the syntax. + * + * XXX N.B. dalnet changed it to nick@server as have other servers. + * we will stick with tradition for now. + * - Dianora */ static void -handle_opers(int p_or_n, char *command, struct Client *client_p, - struct Client *source_p, char *nick, char *text) +handle_special(int p_or_n, char *command, struct Client *client_p, + struct Client *source_p, char *nick, char *text) { struct Client *target_p; char *host; char *server; + char *s; int count; + /* + * user[%host]@server addressed? + */ + if ((server = strchr(nick, '@')) != NULL) + { + count = 0; + + if ((host = strchr(nick, '%')) && !(IsOper(source_p) || IsServices(source_p))) + { + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + me.name, source_p->name); + return; + } + if ((target_p = find_server(server + 1)) != NULL) + { + if (!IsMe(target_p)) + { + /* + * Not destined for a user on me :-( + */ + + sendto_one(target_p, ":%s %s %s :%s", source_p->name, + command, nick, text); + if ((p_or_n != NOTICE) && source_p->user) + source_p->user->last = CurrentTime; + return; + } + + *server = '\0'; + + if (host != NULL) + *host++ = '\0'; + + /* Check if someones msg'ing opers@our.server */ + if (strcmp(nick, "opers") == 0) + { + if (!IsOper(source_p)) + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + me.name, source_p->name); + else + sendto_realops_flags(FLAGS_ALL, L_ALL, "To opers: From: %s: %s", + source_p->name, text); + return; + } + + /* + * Look for users which match the destination host + * (no host == wildcard) and if one and one only is + * found connected to me, deliver message! + */ + target_p = find_userhost(nick, host, &count); + + if (target_p != NULL) + { + if (server != NULL) + *server = '@'; + if (host != NULL) + *--host = '%'; + + if (count == 1) + { + sendto_one(target_p, ":%s %s %s :%s", + source_p->name, command, nick, text); + if ((p_or_n != NOTICE) && source_p->user) + source_p->user->last = CurrentTime; + } + else + sendto_one(source_p, form_str(ERR_TOOMANYTARGETS), + me.name, source_p->name, nick); + } + } + else if (server && *(server+1) && (target_p == NULL)) + sendto_one(source_p, form_str(ERR_NOSUCHSERVER), me.name, + source_p->name, server+1); + else if (server && (target_p == NULL)) + sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, + source_p->name, nick); + return; + } + + if (!IsOper(source_p)) + { + sendto_one(source_p, form_str(ERR_NOPRIVILEGES), + me.name, source_p->name); + return; + } /* * the following two cases allow masks in NOTICEs * (for OPERs only) @@ -823,10 +916,8 @@ handle_opers(int p_or_n, char *command, struct Client *client_p, me.name, source_p->name, command, nick, nick); return; } - - /* we allow it to send messages to anybody */ - -#if 0 + /* we can send to * now. */ +#if 0 if ((s = strrchr(nick, '.')) == NULL) { sendto_one(source_p, form_str(ERR_NOTOPLEVEL), @@ -854,70 +945,6 @@ handle_opers(int p_or_n, char *command, struct Client *client_p, return; } - /* - * user[%host]@server addressed? - */ - if ((server = strchr(nick, '@')) && (target_p = find_server(server + 1))) - { - count = 0; - - /* - * Not destined for a user on me :-( - */ - - if (!IsMe(target_p)) - { - sendto_one(target_p, ":%s %s %s :%s", source_p->name, - command, nick, text); - if ((p_or_n != NOTICE) && source_p->user) - source_p->user->last = CurrentTime; - return; - } - - *server = '\0'; - - if ((host = strchr(nick, '%')) != NULL) - *host++ = '\0'; - - /* Check if someones msg'ing opers@our.server */ - if (strcmp(nick, "opers") == 0) - { - sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ALL, "To opers: From: %s: %s", - source_p->name, text); - return; - } - - /* - * Look for users which match the destination host - * (no host == wildcard) and if one and one only is - * found connected to me, deliver message! - */ - target_p = find_userhost(nick, host, &count); - - if (target_p != NULL) - { - if (server != NULL) - *server = '@'; - if (host != NULL) - *--host = '%'; - - if (count == 1) { - sendto_anywhere(target_p, source_p, "%s %s :%s", command, - nick, text); - if ((p_or_n != NOTICE) && source_p->user) - source_p->user->last = CurrentTime; - } - else - sendto_one(source_p, form_str(ERR_TOOMANYTARGETS), - me.name, source_p->name, nick); - } - } - else if (server && *(server+1) && (target_p == NULL)) - sendto_one(source_p, form_str(ERR_NOSUCHSERVER), me.name, - source_p->name, server+1); - else if (server && (target_p == NULL)) - sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, - source_p->name, nick); } /* diff --git a/modules/core/m_part.c b/modules/core/m_part.c index 8d12b48..76ff06e 100644 --- a/modules/core/m_part.c +++ b/modules/core/m_part.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: m_part.c,v 1.4 2002/09/13 06:50:07 fishwaldo Exp $ + * $Id: m_part.c,v 1.5 2003/01/29 09:28:49 fishwaldo Exp $ */ #include "stdinc.h" @@ -61,7 +61,7 @@ _moddeinit(void) { mod_del_cmd(&part_msgtab); } -const char *_version = "$Revision: 1.4 $"; +const char *_version = "$Revision: 1.5 $"; #endif static void part_one_client(struct Client *client_p, @@ -157,7 +157,7 @@ static void part_one_client(struct Client *client_p, ":%s PART %s :%s", ID(source_p), chptr->chname, reason); sendto_server(client_p, NULL, chptr, NOCAPS, CAP_UID, NOFLAGS, - ":%s PART %s :%s", source_p->name, chptr->chname, + ":%s PART %s :%s", source_p->name, chptr->chname, reason); sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s :%s", diff --git a/modules/core/m_server.c b/modules/core/m_server.c index 6ce9c01..673631a 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.11 2002/10/31 13:01:57 fishwaldo Exp $ + * $Id: m_server.c,v 1.12 2003/01/29 09:28:49 fishwaldo Exp $ */ #include "stdinc.h" @@ -67,7 +67,7 @@ _moddeinit(void) { mod_del_cmd(&server_msgtab); } -const char *_version = "$Revision: 1.11 $"; +const char *_version = "$Revision: 1.12 $"; #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, source_p, &me, "No matching hub_mask."); + exit_client(NULL, client_p, &me, "No matching hub_mask."); return; } diff --git a/modules/m_challenge.c b/modules/m_challenge.c index 43e03f3..25f562e 100644 --- a/modules/m_challenge.c +++ b/modules/m_challenge.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: m_challenge.c,v 1.6 2002/10/31 13:01:54 fishwaldo Exp $ + * $Id: m_challenge.c,v 1.7 2003/01/29 09:28:48 fishwaldo Exp $ */ #include "stdinc.h" @@ -55,10 +55,11 @@ _moddeinit(void) return; } -const char *_version = "$Revision: 1.6 $"; +const char *_version = "$Revision: 1.7 $"; #endif #else +static void failed_challenge_notice(struct Client *, char *, char *); static void m_challenge(struct Client*, struct Client*, int, char**); void binary_to_hex( unsigned char * bin, char * hex, int length ); @@ -80,7 +81,7 @@ _moddeinit(void) mod_del_cmd(&challenge_msgtab); } -const char *_version = "$Revision: 1.6 $"; +const char *_version = "$Revision: 1.7 $"; #endif /* * m_challenge - generate RSA challenge for wouldbe oper @@ -115,6 +116,7 @@ static void m_challenge( struct Client *client_p, struct Client *source_p, { sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name, source_p->name); + failed_challenge_notice(source_p, source_p->user->auth_oper, "challenge failed"); return; } @@ -196,4 +198,23 @@ static void m_challenge( struct Client *client_p, struct Client *source_p, return; } +/* + * failed_challenge_notice + * + * inputs - pointer to client doing /oper ... + * - pointer to nick they tried to oper as + * - pointer to reason they have failed + * output - nothing + * side effects - notices all opers of the failed oper attempt if enabled + */ + +static void +failed_challenge_notice(struct Client *source_p, char *name, char *reason) +{ + if (ConfigFileEntry.failed_oper_notice) + sendto_realops_flags(FLAGS_ALL | FLAGS_REMOTE, L_ALL, "Failed CHALLENGE attempt as %s " + "by %s (%s@%s) - %s", name, source_p->name, + source_p->username, source_p->host, reason); +} + #endif /* HAVE_LIBCRYPTO */ diff --git a/modules/m_help.c b/modules/m_help.c index 17fc2eb..44a3790 100644 --- a/modules/m_help.c +++ b/modules/m_help.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: m_help.c,v 1.4 2002/09/13 06:50:06 fishwaldo Exp $ + * $Id: m_help.c,v 1.5 2003/01/29 09:28:48 fishwaldo Exp $ */ #include "stdinc.h" @@ -67,7 +67,7 @@ _moddeinit(void) mod_del_cmd(&uhelp_msgtab); } -const char *_version = "$Revision: 1.4 $"; +const char *_version = "$Revision: 1.5 $"; #endif /* * m_help - HELP message handler @@ -211,6 +211,7 @@ sendhelpfile(struct Client *source_p, char *path, sendto_one(source_p, form_str(RPL_HELPTXT), me.name, nick, topic, line); } + fbclose(file); sendto_one(source_p, form_str(RPL_ENDOFHELP), me.name, nick, topic); return; } diff --git a/modules/m_invite.c b/modules/m_invite.c index 6ff7fd2..ba6e91c 100644 --- a/modules/m_invite.c +++ b/modules/m_invite.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: m_invite.c,v 1.7 2002/11/21 13:23:37 fishwaldo Exp $ + * $Id: m_invite.c,v 1.8 2003/01/29 09:28:48 fishwaldo Exp $ */ #include "stdinc.h" @@ -40,12 +40,14 @@ #include "msg.h" #include "parse.h" #include "modules.h" +#include "packet.h" static void m_invite(struct Client *, struct Client *, int, char **); +static void ms_invite(struct Client *, struct Client *, int, char **); struct Message invite_msgtab = { "INVITE", 0, 0, 3, 0, MFLG_SLOW, 0, - {m_unregistered, m_invite, m_invite, m_invite} + {m_unregistered, m_invite, ms_invite, m_invite} }; #ifndef STATIC_MODULES @@ -61,7 +63,7 @@ _moddeinit(void) mod_del_cmd(&invite_msgtab); } -const char *_version = "$Revision: 1.7 $"; +const char *_version = "$Revision: 1.8 $"; #endif /* @@ -85,10 +87,12 @@ m_invite(struct Client *client_p, return; } - /* A little sanity test here */ - if (source_p->user == NULL) + if(!IsClient(source_p)) return; + if(MyClient(source_p) && !IsFloodDone(source_p)) + flood_endgrace(source_p); + if ((target_p = find_person(parv[1])) == NULL) { sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, parv[0], parv[1]); @@ -188,39 +192,151 @@ m_invite(struct Client *client_p, burst_channel(target_p->from, vchan); } - if (MyConnect(target_p)) - { - add_invite(vchan, target_p); - sendto_one(target_p, ":%s!%s@%s INVITE %s :%s", source_p->name, - source_p->username, source_p->vhost, target_p->name, - chptr->chname); - } - - /* we send a notice to all channel ops/halfops/admins */ - sendto_channel_local(ONLY_CHANOPS_HALFOPS, vchan, - ":%s NOTICE %s :%s is inviting %s to %s.", - me.name, chptr->chname, source_p->name, - target_p->name, chptr->chname); + if (MyConnect(target_p) && chop) + add_invite(vchan, target_p); - /* if the channel is +pi, broadcast everywhere thats CAP_PARA, send to - * target if target isnt CAP_PARA capable, else just send to target + sendto_anywhere(target_p, source_p, "INVITE %s :%s", + target_p->name, chptr->chname); + + /* if the channel is +pi, each server that is capable of CAP_PARA + * will send a local message to channel. If there are servers + * connected to us that do not understand CAP_PARA, send a NOTICE + * to chanops on the channel as per hybrid-6 */ - if(ParanoidChannel(vchan)) + if (ParanoidChannel(vchan)) { - sendto_channel_remote(source_p, client_p, - ONLY_CHANOPS_HALFOPS, CAP_PARA, NOCAPS, - chptr, ":%s INVITE %s :%s", parv[0], - target_p->name, vchan->chname); - - if(!MyConnect(target_p) && (target_p->from != client_p) && - !IsCapable(target_p->from, CAP_PARA)) - sendto_one(target_p->from, ":%s INVITE %s :%s", parv[0], - target_p->name, vchan->chname); + sendto_server(source_p->from, source_p, NULL, NOCAPS, NOCAPS, NOFLAGS, + ":%s INVITE %s %s :%s", + me.name, source_p->name, target_p->name, vchan->chname); + + /* XXX This possibly should be a numeric -db */ + sendto_channel_local(ONLY_CHANOPS_HALFOPS, vchan, + ":%s NOTICE %s :%s is inviting %s to %s.", + me.name, chptr->chname, source_p->name, + target_p->name, chptr->chname); - } - else if(!MyConnect(target_p) && (target_p->from != client_p)) - { - sendto_one(target_p->from, ":%s INVITE %s :%s", parv[0], - target_p->name, vchan->chname); } } + +/* +** ms_invite +** parv[0] - sender prefix +** parv[1] - user to invite +** parv[2] - channel number +*/ +/* + * + */ +static void +ms_invite(struct Client *client_p, + struct Client *source_p, int parc, char *parv[]) +{ + struct Client *source_client_p; + struct Client *target_p; + struct Channel *chptr, *vchan; + int notify_type = 0; + + /* + * If parc is 3, then its an old fashioned :nick INVITE nick2 :#channel + * message, which must be relayed through if its not ours. + * + * If parc > 3, then its a notify the channel message only, which + * would only have been sent if the channel was in ParanoidMode to + * begin with, so the check here is redundant. + */ + + if (parc < 4) + { + source_client_p = source_p; + + if (*parv[2] == '\0') + return; + + if ((target_p = find_person(parv[1])) == NULL) + return; + + if(check_channel_name(parv[2]) == 0) + return; + + if (!IsChannelName(parv[2])) + return; + + if ((chptr = hash_find_channel(parv[2])) == NULL) + return; + } + else + { + notify_type = 1; + + if (*parv[1] == '\0') + return; + + if ((source_client_p = find_person(parv[1])) == NULL) + return; + + if (*parv[2] == '\0') + return; + + if ((target_p = find_person(parv[2])) == NULL) + return; + + if(check_channel_name(parv[3]) == 0) + return; + + if (!IsChannelName(parv[3])) + return; + + if ((chptr = hash_find_channel(parv[3])) == NULL) + return; + } + + /* By this point, chptr is non NULL */ + + vchan = chptr; + + if (IsMember(target_p, vchan)) + return; + + if (!notify_type) + { + if (MyConnect(target_p)) + { + if (vchan->mode.mode & MODE_INVITEONLY) + add_invite(vchan, target_p); + } + + sendto_anywhere(target_p, source_client_p, "INVITE %s :%s", + target_p->name, chptr->chname); + } + else + { + + /* There are two different kinds of behaviour that both make sense here. + * 1) One approach is simply to chop at the first non CAP_PARA hub + * 2) if there is a non CAP_PARA hub in between a cluster of CAP_PARA + * servers and another cluster... then one could attempt to "convert" + * them back to CAP_PARA form. + */ + + /* if the channel is +pi, each server that is capable of CAP_PARA + * will send a local message to channel. If the invite came from + * a non CAP_PARA server, attempt to "convert" it back to CAP_PARA form + * even if this means a duplicate channel message to ops. + */ + if (ParanoidChannel(vchan)) + { + sendto_server(source_p->from, source_p, NULL, NOCAPS, NOCAPS, NOFLAGS, + ":%s INVITE %s %s :%s", + source_p->name, source_client_p->name, + target_p->name, vchan->chname); + + /* XXX This possibly should be a numeric -db */ + sendto_channel_local(ONLY_CHANOPS_HALFOPS, vchan, + ":%s NOTICE %s :%s is inviting %s to %s.", + me.name, chptr->chname, source_client_p->name, + target_p->name, chptr->chname); + + } + } +} + diff --git a/modules/m_oper.c b/modules/m_oper.c index 2d6603a..6a91deb 100644 --- a/modules/m_oper.c +++ b/modules/m_oper.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: m_oper.c,v 1.6 2002/09/19 05:41:10 fishwaldo Exp $ + * $Id: m_oper.c,v 1.7 2003/01/29 09:28:48 fishwaldo Exp $ */ #include "stdinc.h" @@ -46,6 +46,7 @@ static struct ConfItem *find_password_aconf(char *name, struct Client *source_p); static int match_oper_password(char *password, struct ConfItem *aconf); +static void failed_oper_notice(struct Client *source_p, char *name, char *reason); int oper_up( struct Client *source_p, struct ConfItem *aconf ); #ifdef CRYPT_OPER_PASSWORD extern char *crypt(); @@ -74,7 +75,7 @@ _moddeinit(void) mod_del_cmd(&oper_msgtab); } -const char *_version = "$Revision: 1.6 $"; +const char *_version = "$Revision: 1.7 $"; #endif /* @@ -110,13 +111,8 @@ m_oper(struct Client *client_p, struct Client *source_p, if((aconf = find_password_aconf(name,source_p)) == NULL) { sendto_one(source_p, form_str(ERR_NOOPERHOST), me.name, source_p->name); - if (ConfigFileEntry.failed_oper_notice) - { - sendto_realops_flags(FLAGS_ALL, L_ALL, - "Failed OPER attempt - host mismatch by %s (%s@%s)", - source_p->name, source_p->username, - source_p->host); - } + failed_oper_notice(source_p, name, find_conf_by_name(name, CONF_OPERATOR) ? + "host mismatch" : "no oper {} block"); log_failed_oper(source_p, name); return; } @@ -137,11 +133,8 @@ m_oper(struct Client *client_p, struct Client *source_p, if(attach_conf(source_p, aconf) != 0) { sendto_one(source_p,":%s NOTICE %s :Can't attach conf!", - me.name,source_p->name); - sendto_realops_flags(FLAGS_ALL, L_ALL, - "Failed OPER attempt by %s (%s@%s) can't attach conf!", - source_p->name, source_p->username, - source_p->host); + me.name, source_p->name); + failed_oper_notice(source_p, name, "can't attach conf!"); /* * 20001216: * Reattach old iline @@ -161,15 +154,9 @@ m_oper(struct Client *client_p, struct Client *source_p, else { sendto_one(source_p,form_str(ERR_PASSWDMISMATCH),me.name, parv[0]); - if (ConfigFileEntry.failed_oper_notice) - { - sendto_realops_flags(FLAGS_ALL, L_ALL, - "Failed OPER attempt by %s (%s@%s)", - source_p->name, source_p->username, - source_p->host); - } - log_failed_oper(source_p, name); + failed_oper_notice(source_p, name, "password mismatch"); } + log_failed_oper(source_p, name); } /* @@ -199,12 +186,9 @@ ms_oper(struct Client *client_p, struct Client *source_p, { /* if message arrived from server, trust it, and set to oper */ - if (!IsOper(source_p)) + if (!IsOper(source_p) && IsClient(source_p)) { - if (source_p->status == STAT_CLIENT) - source_p->handler = OPER_HANDLER; - - source_p->umodes |= FLAGS_OPER; + SetOper(source_p); Count.oper++; sendto_server(client_p, source_p, NULL, NOCAPS, NOCAPS, NOFLAGS, ":%s MODE %s :+o", parv[0], parv[0]); @@ -276,3 +260,23 @@ match_oper_password(char *password, struct ConfItem *aconf) else return (NO); } + + +/* + * failed_oper_notice + * + * inputs - pointer to client doing /oper ... + * - pointer to nick they tried to oper as + * - pointer to reason they have failed + * output - nothing + * side effects - notices all opers of the failed oper attempt if enabled + */ + +static void +failed_oper_notice(struct Client *source_p, char *name, char *reason) +{ + if (ConfigFileEntry.failed_oper_notice) + sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ALL, "Failed OPER attempt as %s " + "by %s (%s@%s) - %s", name, source_p->name, + source_p->username, source_p->host, reason); +} diff --git a/modules/m_post.c b/modules/m_post.c index d2d6727..14bc512 100644 --- a/modules/m_post.c +++ b/modules/m_post.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: m_post.c,v 1.3 2002/09/13 06:50:07 fishwaldo Exp $ + * $Id: m_post.c,v 1.4 2003/01/29 09:28:49 fishwaldo Exp $ */ #include "stdinc.h" @@ -57,15 +57,18 @@ void _modinit(void) { mod_add_cmd(&post_msgtab); -} + mod_add_cmd(&get_msgtab); + mod_add_cmd(&put_msgtab);} void _moddeinit(void) { mod_del_cmd(&post_msgtab); + mod_del_cmd(&get_msgtab); + mod_del_cmd(&put_msgtab); } -const char *_version = "$Revision: 1.3 $"; +const char *_version = "$Revision: 1.4 $"; #endif /* ** mr_dumb_proxy diff --git a/modules/m_whowas.c b/modules/m_whowas.c index 53c19e1..c8303b8 100644 --- a/modules/m_whowas.c +++ b/modules/m_whowas.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: m_whowas.c,v 1.4 2002/09/13 06:50:07 fishwaldo Exp $ + * $Id: m_whowas.c,v 1.5 2003/01/29 09:28:49 fishwaldo Exp $ */ #include "stdinc.h" @@ -61,7 +61,7 @@ _moddeinit(void) { mod_del_cmd(&whowas_msgtab); } -const char *_version = "$Revision: 1.4 $"; +const char *_version = "$Revision: 1.5 $"; #endif static int whowas_do(struct Client *client_p, struct Client *source_p, int parc, char *parv[]); @@ -79,7 +79,7 @@ static void m_whowas(struct Client *client_p, { static time_t last_used=0L; - if (parc < 2) + if (parc < 2 || parv[1][0] == '\0') { sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN), me.name, parv[0]); @@ -104,7 +104,7 @@ static void mo_whowas(struct Client *client_p, int parc, char *parv[]) { - if (parc < 2) + if (parc < 2 || parv[1][0] == '\0') { sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN), me.name, parv[0]); @@ -132,7 +132,7 @@ static int whowas_do(struct Client *client_p, struct Client *source_p, max = atoi(parv[2]); if (parc > 3) if (hunt_server(client_p,source_p,":%s WHOWAS %s %s :%s", 3,parc,parv)) - return 0; + return(0); nick = parv[1]; while (*nick == ',') @@ -140,7 +140,7 @@ static int whowas_do(struct Client *client_p, struct Client *source_p, if((p = strchr(nick,',')) != NULL) *p = '\0'; if (!*nick) - return 0; + return(0); temp = WHOWASHASH[hash_whowas_name(nick)]; found = 0; diff --git a/src/balloc.c b/src/balloc.c index 8b07654..18d68ac 100644 --- a/src/balloc.c +++ b/src/balloc.c @@ -25,7 +25,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: balloc.c,v 1.5 2002/10/31 13:01:57 fishwaldo Exp $ + * $Id: balloc.c,v 1.6 2003/01/29 09:28:49 fishwaldo Exp $ */ /* @@ -406,7 +406,7 @@ BlockHeapAlloc(BlockHeap * bh) } assert(0 == 1); outofmemory(); - return NULL; + return(NULL); } @@ -551,10 +551,7 @@ BlockHeapDestroy(BlockHeap * bh) free(walker); } - if(walker != NULL) - { - free(bh); - } + free(bh); return(0); } #endif diff --git a/src/channel.c b/src/channel.c index 8084171..b5a6b51 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.15 2002/11/20 14:13:57 fishwaldo Exp $ + * $Id: channel.c,v 1.16 2003/01/29 09:28:49 fishwaldo Exp $ */ #include "stdinc.h" @@ -84,6 +84,7 @@ void init_channels(void) channel_heap = BlockHeapCreate(sizeof(struct Channel), CHANNEL_HEAP_SIZE); ban_heap = BlockHeapCreate(sizeof(struct Ban), BAN_HEAP_SIZE); topic_heap = BlockHeapCreate(TOPICLEN+1 + USERHOST_REPLYLEN, TOPIC_HEAP_SIZE); + eventAddIsh("channelheap_garbage_collect", channelheap_garbage_collect, NULL, 45); } @@ -224,20 +225,22 @@ remove_user_from_channel(struct Channel *chptr, struct Client *who) free_dlink_node(ptr); } - chptr->users_last = CurrentTime; - DLINK_FOREACH_SAFE(ptr, next_ptr, who->user->channel.head) + if (who->user != NULL) { - if (ptr->data == chptr) + DLINK_FOREACH_SAFE(ptr, next_ptr, who->user->channel.head) { - dlinkDelete(ptr, &who->user->channel); - free_dlink_node(ptr); - break; + if (ptr->data == chptr) + { + dlinkDelete(ptr, &who->user->channel); + free_dlink_node(ptr); + who->user->joined--; + break; + } } } - who->user->joined--; if (MyClient(who)) { @@ -316,16 +319,16 @@ send_channel_modes(struct Client *client_p, struct Channel *chptr) send_members(client_p, modebuf, parabuf, chptr, &chptr->chanops, "@"); - send_members(client_p, modebuf, parabuf, chptr, &chptr->halfops, "%"); + send_members(client_p, modebuf, parabuf, chptr, &chptr->halfops, "%"); send_members(client_p, modebuf, parabuf, chptr, &chptr->chanadmins, "!"); send_members(client_p, modebuf, parabuf, chptr, &chptr->voiced, "+"); send_members(client_p, modebuf, parabuf, chptr, &chptr->peons, ""); send_mode_list(client_p, chptr->chname, &chptr->banlist, 'b', 0); - send_mode_list(client_p, chptr->chname, &chptr->exceptlist, 'e', 0); + send_mode_list(client_p, chptr->chname, &chptr->exceptlist, 'e', 0); - send_mode_list(client_p, chptr->chname, &chptr->invexlist, 'I', 0); + send_mode_list(client_p, chptr->chname, &chptr->invexlist, 'I', 0); } /* @@ -416,15 +419,22 @@ check_channel_name(const char *name) } /* -** Subtract one user from channel (and free channel -** block, if channel became empty). -*/ + * sub1_from_channel + * + * inputs - pointer to channel to remove client from + * output - did the channel get destroyed + * side effects - remove one user from chptr. if the + * channel is now empty, and it is not already + * scheduled for destruction, schedule it + */ static int sub1_from_channel(struct Channel *chptr) { if (--chptr->users <= 0) { - assert(chptr->users >= 0); +#ifdef INVARIANTS + assert(chptr->users == 0); +#endif chptr->users = 0; /* if chptr->users < 0, make sure it sticks at 0 * It should never happen but... */ @@ -538,9 +548,8 @@ destroy_channel(struct Channel *chptr) * any reference it has to this channel. * Finally, free now unused dlink's * - * This test allows us to use this code both for LazyLinks and - * persistent channels. In the case of a LL the channel need not - * be empty, it only has to be empty of local users. + * For LazyLinks, note that the channel need not be empty, it only + * has to be empty of local users. */ delete_members(chptr, &chptr->chanadmins); delete_members(chptr, &chptr->chanops); @@ -615,20 +624,21 @@ delete_members(struct Channel *chptr, dlink_list * list) next_ptr = ptr->next; who = (struct Client *)ptr->data; - /* remove reference to chptr from who */ - for (ptr_ch = who->user->channel.head; ptr_ch; ptr_ch = next_ptr_ch) + if (who->user != NULL) { - next_ptr_ch = ptr_ch->next; - - if (ptr_ch->data == chptr) + /* remove reference to chptr from who */ + DLINK_FOREACH_SAFE (ptr_ch, next_ptr_ch, who->user->channel.head) { - dlinkDelete(ptr_ch, &who->user->channel); - free_dlink_node(ptr_ch); - break; + if (ptr_ch->data == chptr) + { + dlinkDelete(ptr_ch, &who->user->channel); + free_dlink_node(ptr_ch); + who->user->joined--; + break; + } } } - who->user->joined--; /* remove reference to who from chptr */ @@ -917,13 +927,16 @@ check_banned(struct Channel *chptr, struct Client *who, char *s, char *s2, char actualBan = NULL; } - if (actualBan != NULL) + if ((actualBan != NULL)) { DLINK_FOREACH(except, chptr->exceptlist.head) { actualExcept = except->data; - if (match(actualExcept->banstr, s) || match(actualExcept->banstr, s2) || match(actualExcept->banstr, s3)) + if (match(actualExcept->banstr, s) || + match(actualExcept->banstr, s2) || + match_cidr(actualExcept->banstr, s2) || + match(actualExcept->banstr, s3)) { return CHFL_EXCEPTION; } @@ -951,7 +964,7 @@ can_join(struct Client *source_p, struct Channel *chptr, char *key) char src_host[NICKLEN + USERLEN + HOSTLEN + 6]; char src_iphost[NICKLEN + USERLEN + HOSTLEN + 6]; char src_vhost[NICKLEN + USERLEN + HOSTLEN +6]; - + assert(source_p->localClient != NULL); ircsprintf(src_host, @@ -980,7 +993,7 @@ can_join(struct Client *source_p, struct Channel *chptr, char *key) } if (ptr == NULL) return (ERR_INVITEONLYCHAN); - } + } } if ((chptr->mode.mode & MODE_SSLONLY) && !IsSSL(source_p)) { for (lp = source_p->user->invited.head; lp; lp = lp->next) { @@ -1078,7 +1091,7 @@ is_chan_admin(struct Channel *chptr, struct Client *who) /* * is_any_op * - * inputs - pointer to channel to check for chanop or halfops or chanadmin on + * inputs - pointer to channel to check for chanop or halfops on * - pointer to client struct being checked * output - yes if anyop no if not * side effects - diff --git a/src/channel_mode.c b/src/channel_mode.c index c381c4d..70bf627 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.20 2002/11/20 14:13:57 fishwaldo Exp $ + * $Id: channel_mode.c,v 1.21 2003/01/29 09:28:49 fishwaldo Exp $ */ #include "stdinc.h" @@ -127,10 +127,14 @@ static void update_channel_info(struct Channel *); * some buffers for rebuilding channel/nick lists with ,'s */ -static char modebuf[MODEBUFLEN], parabuf[MODEBUFLEN]; +static char modebuf[BUFSIZE]; +static char parabuf[MODEBUFLEN]; static char mask_buf[BUFSIZE]; static int mask_pos; +/* 10 is a magic number in hybrid 6 NFI where it comes from -db */ +#define BAN_FUDGE 10 + static struct ChModeChange mode_changes[BUFSIZE]; static int mode_count; @@ -218,7 +222,7 @@ add_id(struct Client *client_p, struct Channel *chptr, char *banid, int type) { actualBan = ban->data; if (match(actualBan->banstr, banid)) - return 0; + return(0); } ban = make_dlink_node(); @@ -245,7 +249,7 @@ add_id(struct Client *client_p, struct Channel *chptr, char *banid, int type) dlinkAdd(actualBan, ban, list); chptr->num_mask++; - return 1; + return(1); } /* @@ -431,7 +435,7 @@ change_channel_membership(struct Channel *chptr, free_dlink_node(ptr); } - return ok; + return (ok); } /* @@ -752,6 +756,10 @@ chm_hideops(struct Client *client_p, struct Client *source_p, return; } + if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS)) + return; + + if (dir == MODE_ADD && !(chptr->mode.mode & MODE_HIDEOPS)) { chptr->mode.mode |= MODE_HIDEOPS; @@ -831,10 +839,6 @@ chm_ban(struct Client *client_p, struct Client *source_p, else mask = pretty_mask(raw_mask); - /* We'd have problems parsing this, hyb6 does it too */ - if (strlen(mask) > (MODEBUFLEN - 2)) - return; - /* if we're adding a NEW id */ if (dir == MODE_ADD) { @@ -849,6 +853,9 @@ chm_ban(struct Client *client_p, struct Client *source_p, } else if (dir == MODE_DEL) { +/* XXX grrrrrrr */ +#ifdef NO_BAN_COOKIE + if (del_id(chptr, mask, CHFL_BAN) == 0) { /* mask isn't a valid ban, check raw_mask */ @@ -860,6 +867,14 @@ chm_ban(struct Client *client_p, struct Client *source_p, mask = raw_mask; } +#else +/* XXX this hack allows /mode * +o-b nick ban.cookie + * I'd like to see this hack go away in the future. + */ + if(del_id(chptr, raw_mask, CHFL_BAN)) + mask = raw_mask; +#endif + mode_changes[mode_count].letter = c; mode_changes[mode_count].dir = MODE_DEL; mode_changes[mode_count].mems = ALL_MEMBERS; @@ -914,10 +929,6 @@ chm_except(struct Client *client_p, struct Client *source_p, else mask = pretty_mask(raw_mask); - /* We'd have problems parsing this, hyb6 does it too */ - if (strlen(mask) > (MODEBUFLEN - 2)) - return; - /* If we're adding a NEW id */ if (dir == MODE_ADD) { @@ -926,7 +937,7 @@ chm_except(struct Client *client_p, struct Client *source_p, mode_changes[mode_count].letter = c; mode_changes[mode_count].dir = MODE_ADD; - mode_changes[mode_count].mems = ONLY_CHANOPS_HALFOPS; + mode_changes[mode_count].mems = ONLY_CHANOPS_HALFOPS; mode_changes[mode_count].id = NULL; mode_changes[mode_count++].arg = mask; } @@ -997,10 +1008,6 @@ chm_invex(struct Client *client_p, struct Client *source_p, else mask = pretty_mask(raw_mask); - /* We'd have problems parsing this, hyb6 does it too */ - if (strlen(mask) > (MODEBUFLEN - 2)) - return; - if(dir == MODE_ADD) { if((add_id(source_p, chptr, mask, CHFL_INVEX) == 0) && MyClient(source_p)) @@ -1008,7 +1015,7 @@ chm_invex(struct Client *client_p, struct Client *source_p, mode_changes[mode_count].letter = c; mode_changes[mode_count].dir = MODE_ADD; - mode_changes[mode_count].mems = ONLY_CHANOPS_HALFOPS; + mode_changes[mode_count].mems = ONLY_CHANOPS_HALFOPS; mode_changes[mode_count].id = NULL; mode_changes[mode_count++].arg = mask; } @@ -1027,7 +1034,7 @@ chm_invex(struct Client *client_p, struct Client *source_p, mode_changes[mode_count].letter = c; mode_changes[mode_count].dir = MODE_DEL; - mode_changes[mode_count].mems = ONLY_CHANOPS_HALFOPS; + mode_changes[mode_count].mems = ONLY_CHANOPS_HALFOPS; mode_changes[mode_count].id = NULL; mode_changes[mode_count++].arg = mask; } @@ -1486,7 +1493,7 @@ chm_voice(struct Client *client_p, struct Client *source_p, } mode_get_status(chptr, targ_p, &t_op, &t_hop, &t_voice, &t_admin, 1); - + if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS)) return; @@ -1618,7 +1625,7 @@ chm_key(struct Client *client_p, struct Client *source_p, fix_key_old(key); assert(key[0] != ' '); - strlcpy(chptr->mode.key, key, KEYLEN); + strlcpy(chptr->mode.key, key, sizeof(chptr->mode.key)); /* if somebody does MODE #channel +kk a b, accept latter --fl */ for (i = 0; i < mode_count; i++) @@ -1728,7 +1735,7 @@ static struct ChannelMode ModeTable[255] = * MODE_PEON for peon level access. * Side-effects: None. */ - static int +static int get_channel_access(struct Client *source_p, struct Channel *chptr) { /* Let hacked servers in for now... */ @@ -1738,7 +1745,7 @@ get_channel_access(struct Client *source_p, struct Channel *chptr) if (is_chan_admin(chptr, source_p)) return CHACCESS_ADMIN; - + if (is_chan_op(chptr, source_p)) return CHACCESS_CHANOP; @@ -1771,32 +1778,35 @@ static void send_cap_mode_changes(struct Client *client_p, struct Client *source_p, struct Channel *chptr) { - int i, mbl, pbl, nc, mc; + int i, mbl, pbl, arglen, nc, mc; + int len; char *arg; + char *parptr; int dir; int cap, nocap; - + cap = 0; nocap = 0; mc = 0; nc = 0; pbl = 0; - parabuf[0] = 0; dir = MODE_QUERY; - + parabuf[0] = '\0'; + parptr = parabuf; if ((cap & CAP_UID) && source_p->user && - (source_p->user->id[0] == '.')) - mbl = ircsprintf(modebuf, ":%s MODE %s ", source_p->user->id, - chptr->chname); - else - mbl = ircsprintf(modebuf, ":%s MODE %s ", source_p->name, - chptr->chname); + (source_p->user->id[0] == '.')) + mbl = ircsprintf(modebuf, ":%s MODE %s ", source_p->user->id, + chptr->chname); + else + mbl = ircsprintf(modebuf, ":%s MODE %s ", source_p->name, + chptr->chname); + + /* loop the list of - modes we have */ for (i = 0; i < mode_count; i++) { - /* if they dont support the cap we need, or they do support a cap they * cant have, then dont add it to the modebuf.. that way they wont see * the mode @@ -1808,7 +1818,7 @@ send_cap_mode_changes(struct Client *client_p, struct Client *source_p, arg = ""; if ((cap & CAP_UID) && mode_changes[i].id) arg = mode_changes[i].id; - if (!*arg) + if (*arg == '\0') arg = mode_changes[i].arg; /* if we're creeping past the buf size, we need to send it and make @@ -1818,13 +1828,19 @@ send_cap_mode_changes(struct Client *client_p, struct Client *source_p, * them as if they were the longest of the nick or uid at all times, * which even then won't work as we don't always know the uid -A1kmm. */ + if (arg != NULL) + arglen = strlen(arg); + else + arglen = 0; - if ((arg != NULL) && ((mc == MAXMODEPARAMS) || - ((strlen(arg) + mbl + pbl + 2) > BUFSIZE))) + if((mc == MAXMODEPARAMS) || + ((arglen + mbl + pbl + 2) > BUFSIZE) || + (pbl + arglen + BAN_FUDGE) >= MODEBUFLEN) { if (nc != 0) sendto_server(client_p, source_p, chptr, cap, nocap, - LL_ICHAN | LL_ICLIENT, "%s %s", modebuf, parabuf); + LL_ICHAN | LL_ICLIENT, "%s %s", + modebuf, parabuf); nc = 0; mc = 0; @@ -1837,7 +1853,9 @@ send_cap_mode_changes(struct Client *client_p, struct Client *source_p, chptr->chname); pbl = 0; - parabuf[0] = 0; + parabuf[0] = '\0'; + parptr = parabuf; + dir = MODE_QUERY; } if(dir != mode_changes[i].dir) @@ -1847,14 +1865,14 @@ send_cap_mode_changes(struct Client *client_p, struct Client *source_p, } modebuf[mbl++] = mode_changes[i].letter; - modebuf[mbl] = 0; + modebuf[mbl] = '\0'; nc++; if (arg != NULL) { - pbl = strlcat(parabuf, arg, MODEBUFLEN); - parabuf[pbl++] = ' '; - parabuf[pbl] = '\0'; + len = ircsprintf(parptr, "%s ", arg); + pbl += len; + parptr += len; mc++; } } @@ -1865,8 +1883,6 @@ send_cap_mode_changes(struct Client *client_p, struct Client *source_p, if (nc != 0) sendto_server(client_p, source_p, chptr, cap, nocap, LL_ICLIENT, "%s %s", modebuf, parabuf); - - } /* void send_mode_changes(struct Client *client_p, @@ -1879,19 +1895,22 @@ send_cap_mode_changes(struct Client *client_p, struct Client *source_p, * Side-effects: Sends the appropriate mode changes to other clients * and propagates to servers. */ +/* ensure parabuf < MODEBUFLEN -db */ static void send_mode_changes(struct Client *client_p, struct Client *source_p, struct Channel *chptr, char *chname) { - int pbl, mbl, nc, mc; - int i, st; + int i, mbl, pbl, arglen, nc, mc; + int len; + char *arg; + char *parptr; + int st; int dir = MODE_QUERY; - - /* bail out if we have nothing to do... */ if (mode_count <= 0) return; + /* Send all mode changes to the chanops/halfops, and even peons if * we are not +A... */ @@ -1903,10 +1922,12 @@ send_mode_changes(struct Client *client_p, struct Client *source_p, mbl = ircsprintf(modebuf, ":%s!%s@%s MODE %s ", source_p->name, source_p->username, source_p->vhost, chname); - pbl = 0; - parabuf[0] = '\0'; - nc = 0; mc = 0; + nc = 0; + pbl = 0; + + parabuf[0] = '\0'; + parptr = parabuf; for (i = 0; i < mode_count; i++) { @@ -1915,10 +1936,15 @@ send_mode_changes(struct Client *client_p, struct Client *source_p, mode_changes[i].mems == ONLY_SERVERS) continue; + arg = mode_changes[i].arg; + if (arg != NULL) + arglen = strlen(arg); + else + arglen = 0; - if (mode_changes[i].arg != NULL && - ((mc == MAXMODEPARAMS) || - ((strlen(mode_changes[i].arg) + mbl + pbl + 2) > BUFSIZE))) + if ((mc == MAXMODEPARAMS) || + ((arglen + mbl + pbl + 2) > BUFSIZE) || + ((arglen + pbl + BAN_FUDGE) >= MODEBUFLEN)) { if (mbl && modebuf[mbl - 1] == '-') modebuf[mbl - 1] = '\0'; @@ -1937,6 +1963,8 @@ send_mode_changes(struct Client *client_p, struct Client *source_p, pbl = 0; parabuf[0] = '\0'; + parptr = parabuf; + dir = MODE_QUERY; } if(dir != mode_changes[i].dir) @@ -1949,12 +1977,12 @@ send_mode_changes(struct Client *client_p, struct Client *source_p, modebuf[mbl] = '\0'; nc++; - if (mode_changes[i].arg != NULL) + if (arg != NULL) { + len = ircsprintf(parptr, "%s ", arg); + pbl += len; + parptr += len; mc++; - pbl = strlen(strcat(parabuf, mode_changes[i].arg)); - parabuf[pbl++] = ' '; - parabuf[pbl] = '\0'; } } @@ -1992,8 +2020,15 @@ send_mode_changes(struct Client *client_p, struct Client *source_p, continue; } - if (mode_changes[i].arg != NULL && ((mc == MAXMODEPARAMS) || - ((strlen(mode_changes[i].arg) + mbl + pbl + 2) > BUFSIZE))) + arg = mode_changes[i].arg; + if(arg != NULL) + arglen = strlen(arg); + else + arglen = 0; + + if ((mc == MAXMODEPARAMS) || + ((arglen + mbl + pbl + 2) > BUFSIZE) || + ((arglen + pbl + BAN_FUDGE) >= MODEBUFLEN)) { if (mbl && modebuf[mbl - 1] == '-') modebuf[mbl - 1] = '\0'; @@ -2007,6 +2042,7 @@ send_mode_changes(struct Client *client_p, struct Client *source_p, mbl = ircsprintf(modebuf, ":%s MODE %s ", me.name, chname); pbl = 0; parabuf[0] = '\0'; + parptr = parabuf; } if(dir != mode_changes[i].dir) @@ -2019,12 +2055,12 @@ send_mode_changes(struct Client *client_p, struct Client *source_p, modebuf[mbl] = '\0'; nc++; - if (mode_changes[i].arg != NULL) + if (arg != NULL) { - mc++; - pbl = strlen(strcat(parabuf, mode_changes[i].arg)); - parabuf[pbl++] = ' '; - parabuf[pbl] = '\0'; + len = ircsprintf(parptr, "%s ", arg); + pbl += len; + parptr += len; + mc++; } } @@ -2037,6 +2073,10 @@ send_mode_changes(struct Client *client_p, struct Client *source_p, sendto_channel_local(st, chptr, "%s %s", modebuf, parabuf); } + + if (nc != 0) + sendto_one(client_p, "%s %s", modebuf, parabuf); + /* Now send to servers... */ send_cap_mode_changes(client_p, source_p, chptr); } @@ -2062,8 +2102,6 @@ set_channel_mode(struct Client *client_p, struct Client *source_p, char *ml = parv[0], c; int table_position; - - mask_pos = 0; mode_count = 0; hideops_changed = (chptr->mode.mode & MODE_HIDEOPS); @@ -2096,7 +2134,7 @@ set_channel_mode(struct Client *client_p, struct Client *source_p, } update_channel_info(chptr); - + send_mode_changes(client_p, source_p, chptr, chname); } @@ -2169,8 +2207,6 @@ send_oplist(const char *chname, struct Client *client_p, dlink_list * list, char opbuf[MODEBUFLEN]; char *t; - - *mcbuf = *opbuf = '\0'; t = opbuf; @@ -2217,7 +2253,6 @@ sync_channel_oplists(struct Channel *chptr, int dir) { dlink_node *ptr; - for (ptr=chptr->locpeons.head; ptr!=NULL && ptr->data!=NULL; ptr=ptr->next) sync_oplists(chptr, ptr->data, MODE_ADD, chptr->chname); for (ptr=chptr->locvoiced.head; ptr!=NULL && ptr->data!=NULL; ptr = ptr->next) @@ -2233,7 +2268,6 @@ static void mode_get_status(struct Channel *chptr, struct Client *target_p, { int i; - if (need_check) { *t_op = is_chan_op(chptr, target_p); @@ -2259,7 +2293,7 @@ static void mode_get_status(struct Channel *chptr, struct Client *target_p, *t_hop = (mode_changes[i].dir == MODE_ADD) ? 1 : 0; return; } - else if (mode_changes[i].letter == 'v') + else if (mode_changes[i].letter == 'v') { *t_voice = (mode_changes[i].dir == MODE_ADD) ? 1 : 0; return; @@ -2281,7 +2315,6 @@ update_channel_info(struct Channel *chptr) dlink_node *ptr; dlink_node *ptr_next; - /* hideops_changed is set to chptr->mode.mode & MODE_HIDEOPS at * the beginning.. */ @@ -2423,18 +2456,18 @@ update_channel_info(struct Channel *chptr) } } else if (mode_changes[i].letter == 'a') - { - if(mode_changes[i].dir == MODE_DEL) { + if(mode_changes[i].dir == MODE_DEL) + { change_channel_membership(chptr, &chptr->peons, &chptr->locpeons, - mode_changes[i].client); - } - else - { + mode_changes[i].client); + } + else + { change_channel_membership(chptr, &chptr->chanadmins, &chptr->locchanadmins, - mode_changes[i].client); + mode_changes[i].client); + } } - } else if (mode_changes[i].letter == 'v') { { diff --git a/src/client.c b/src/client.c index 8883f46..afb0c23 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.11 2002/10/31 13:01:58 fishwaldo Exp $ + * $Id: client.c,v 1.12 2003/01/29 09:28:49 fishwaldo Exp $ */ #include "stdinc.h" #include "config.h" @@ -58,6 +58,7 @@ 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; @@ -68,7 +69,6 @@ static BlockHeap *client_heap = NULL; static BlockHeap *lclient_heap = NULL; dlink_list dead_list; -dlink_list abort_list; /* * client_heap_gc @@ -175,40 +175,50 @@ struct Client* make_client(struct Client* from) return client_p; } -void free_client(struct Client* client_p) +static void +free_local_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. */ - if (client_p->localClient->listener) - { - assert(0 < client_p->localClient->listener->ref_count); - if (0 == --client_p->localClient->listener->ref_count && - !client_p->localClient->listener->active) - free_listener(client_p->localClient->listener); - client_p->localClient->listener = 0; - } - + if (client_p->localClient->listener) + { + assert(0 < client_p->localClient->listener->ref_count); + if (0 == --client_p->localClient->listener->ref_count && + !client_p->localClient->listener->active) + free_listener(client_p->localClient->listener); + client_p->localClient->listener = 0; + } +#ifdef USE_SSL + if (client_p->localClient->ssl) + { + SSL_smart_shutdown(client_p); + } +#endif if (client_p->localClient->fd >= 0) fd_close(client_p->localClient->fd); 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; - } BlockHeapFree(client_heap, client_p); } @@ -270,7 +280,7 @@ check_pings_list(dlink_list *list) ** Note: No need to notify opers here. It's ** already done when "FLAGS_DEADSOCKET" is set. */ - if (client_p->flags & FLAGS_DEADSOCKET) + if (IsDead(client_p)) { /* Ignore it, its been exited already */ continue; @@ -309,30 +319,30 @@ check_pings_list(dlink_list *list) else ping = get_client_ping(client_p); - if (ping < (CurrentTime - client_p->lasttime)) - { - /* - * If the client/server hasnt talked to us in 2*ping seconds - * and it has a ping time, then close its connection. - */ - if (((CurrentTime - client_p->lasttime) >= (2 * ping) && - (client_p->flags & FLAGS_PINGSENT))) - { - if (IsServer(client_p) || IsConnecting(client_p) || - IsHandshake(client_p)) - { + if (ping < (CurrentTime - client_p->lasttime)) + { + /* + * If the client/server hasnt talked to us in 2*ping seconds + * and it has a ping time, then close its connection. + */ + if (((CurrentTime - client_p->lasttime) >= (2 * ping) && + (client_p->flags & FLAGS_PINGSENT))) + { + if (IsServer(client_p) || IsConnecting(client_p) || + IsHandshake(client_p)) + { sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ADMIN, - "No response from %s, closing link", - get_client_name(client_p, HIDE_IP)); + "No response from %s, closing link", + get_client_name(client_p, HIDE_IP)); sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_OPER, - "No response from %s, closing link", - get_client_name(client_p, MASK_IP)); - ilog(L_NOTICE, "No response from %s, closing link", - get_client_name(client_p, HIDE_IP)); - } - (void)ircsprintf(scratch, - "Ping timeout: %d seconds", - (int)(CurrentTime - client_p->lasttime)); + "No response from %s, closing link", + get_client_name(client_p, MASK_IP)); + ilog(L_NOTICE, "No response from %s, closing link", + get_client_name(client_p, HIDE_IP)); + } + (void)ircsprintf(scratch, + "Ping timeout: %d seconds", + (int)(CurrentTime - client_p->lasttime)); (void)exit_client(client_p, client_p, &me, scratch); continue; @@ -826,15 +836,15 @@ get_client_name(struct Client* client, int showip) switch (showip) { case SHOW_IP: - ircsprintf(nbuf, "%s[%s@%s]", client->name, client->username, + ircsprintf(nbuf, "%s [%s@%s]", client->name, client->username, client->localClient->sockhost); break; case MASK_IP: - ircsprintf(nbuf, "%s[%s@255.255.255.255]", client->name, + ircsprintf(nbuf, "%s [%s@255.255.255.255]", client->name, client->username); break; default: - ircsprintf(nbuf, "%s[%s@%s]", client->name, client->username, + ircsprintf(nbuf, "%s [%s@%s]", client->name, client->username, client->host); } return nbuf; @@ -864,6 +874,8 @@ free_exited_clients(void *unused) free_dlink_node(ptr); continue; } + + release_client_state(target_p); free_client(target_p); dlinkDelete(ptr, &dead_list); @@ -875,9 +887,9 @@ free_exited_clients(void *unused) ** Exit one client, local or remote. Assuming all dependents have ** been already removed, and socket closed for local client. */ -static void exit_one_client(struct Client *client_p, - struct Client *source_p, - struct Client *from, const char *comment) +static void +exit_one_client(struct Client *client_p, struct Client *source_p, + struct Client *from, const char *comment) { struct Client* target_p; dlink_node *lp; @@ -940,7 +952,7 @@ static void exit_one_client(struct Client *client_p, target_p = source_p->from; if (target_p && IsServer(target_p) && target_p != client_p && !IsMe(target_p) && - (source_p->flags & FLAGS_KILLED) == 0) + (!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... */ @@ -950,7 +962,7 @@ static void exit_one_client(struct Client *client_p, ** is no sense in sending the QUIT--KILL's have been ** sent instead. */ - if ((source_p->flags & FLAGS_KILLED) == 0) + if (!IsKilled(source_p)) { sendto_server(client_p, source_p, NULL, NOCAPS, NOCAPS, NOFLAGS, ":%s QUIT :%s", source_p->name, comment); @@ -968,9 +980,9 @@ static void exit_one_client(struct Client *client_p, comment); DLINK_FOREACH_SAFE(lp, next_lp, source_p->user->channel.head) - { - remove_user_from_channel(lp->data, source_p); - } + { + remove_user_from_channel(lp->data, source_p); + } /* Should not be in any channels now */ assert(source_p->user->channel.head == NULL); @@ -1003,9 +1015,8 @@ static void exit_one_client(struct Client *client_p, /* Check to see if the client isn't already on the dead list */ assert(dlinkFind(&dead_list, source_p) == NULL); - /* add to dead client dlist */ + /* add to dead_list */ lp = make_dlink_node(); - SetDead(source_p); dlinkAdd(source_p, lp, &dead_list); } @@ -1059,7 +1070,8 @@ static void recurse_send_quits(struct Client *client_p, struct Client *source_p, /* * added sanity test code.... source_p->serv might be NULL... */ -static void recurse_remove_clients(struct Client* source_p, const char* comment) +static void +recurse_remove_clients(struct Client* source_p, const char* comment) { struct Client *target_p; @@ -1071,7 +1083,7 @@ static void recurse_remove_clients(struct Client* source_p, const char* comment) while ((target_p = source_p->serv->users)) { - target_p->flags |= FLAGS_KILLED; + SetKilled(target_p); exit_one_client(NULL, target_p, &me, comment); } @@ -1082,7 +1094,7 @@ static void recurse_remove_clients(struct Client* source_p, const char* comment) ** a server marked as "KILLED" won't send a SQUIT ** in exit_one_client() -orabidoo */ - target_p->flags |= FLAGS_KILLED; + SetKilled(target_p); exit_one_client(NULL, target_p, &me, me.name); } } @@ -1128,29 +1140,26 @@ remove_dependents(struct Client* client_p, recurse_remove_clients(source_p, comment1); } - - - /* - * dead_link - Adds client to a list of clients that need an exit_client() + * dead_link_on_write - report a write error if not already dead, + * mark it as dead then exit it * */ -void dead_link(struct Client *client_p) +void +dead_link_on_write(struct Client *client_p, int ierrno) { - dlink_node *m; const char *notice; - if(IsClosing(client_p) || IsDead(client_p)) - return; - linebuf_donebuf(&client_p->localClient->buf_recvq); - linebuf_donebuf(&client_p->localClient->buf_sendq); + if(IsDefunct(client_p)) + return; + SetDead(client_p); + if(client_p->flags & FLAGS_SENDQEX) notice = "Max SendQ exceeded"; else notice = "Write error: connection closed"; - - if (!IsPerson(client_p) && !IsUnknown(client_p) && !IsClosing(client_p)) + if (!IsPerson(client_p) && !IsUnknown(client_p)) { sendto_realops_flags(FLAGS_ALL, L_ADMIN, "Closing link to %s: %s", @@ -1159,42 +1168,74 @@ void dead_link(struct Client *client_p) "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)); - 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 */ + 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"); } +/* + * dead_link_on_read - report a read error if not already dead, + * mark it as dead then exit it + * + */ void -exit_aborted_clients(void) +dead_link_on_read(struct Client* client_p, int error) { - dlink_node *ptr, *next; - struct Client *target_p; - char *notice; + char errmsg[255]; + int current_error = get_sockerr(client_p->localClient->fd); - 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(target_p->flags & FLAGS_SENDQEX) - notice = "Max SendQ exceeded"; - else - notice = "Write error: connection closed"; + if(IsDead(client_p)) + return; + SetDead(client_p); + + Debug((DEBUG_ERROR, "READ ERROR: fd = %d %d %d", + client_p->localClient->fd, current_error, error)); + + if (IsServer(client_p) || IsHandshake(client_p)) + { + int connected = CurrentTime - client_p->firsttime; - exit_client(target_p, target_p, &me, notice); - free_dlink_node(ptr); - } -} + if (error == 0) + { + /* Admins get the real IP */ + sendto_realops_flags(FLAGS_ALL, 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, + "Server %s closed the connection", + get_client_name(client_p, MASK_IP)); + + ilog(L_NOTICE, "Server %s closed the connection", + get_client_name(client_p, SHOW_IP)); + } + else + { + report_error(L_ADMIN, "Lost connection to %s: %d", + get_client_name(client_p, SHOW_IP), current_error); + report_error(L_OPER, "Lost connection to %s: %d", + get_client_name(client_p, MASK_IP), current_error); + } + + sendto_realops_flags(FLAGS_ALL, L_ALL, + "%s had been connected for %d day%s, %2d:%02d:%02d", + client_p->name, connected/86400, + (connected/86400 == 1) ? "" : "s", + (connected % 86400) / 3600, (connected % 3600) / 60, + connected % 60); + } + + if (error == 0) + { + strcpy(errmsg, "Remote host closed the connection"); + } + else + { + ircsprintf(errmsg, "Read error: %s", strerror(current_error)); + } + exit_client(client_p, client_p, &me, errmsg); +} /* ** exit_client - This is old "m_bye". Name changed, because this is not a @@ -1216,6 +1257,7 @@ exit_aborted_clients(void) ** CLIENT_EXITED if (client_p == source_p) ** 0 if (client_p != source_p) */ + int exit_client( struct Client* client_p, /* The local client originating the @@ -1232,16 +1274,15 @@ exit_client( { char comment1[HOSTLEN + HOSTLEN + 2]; dlink_node *m; + + if (IsClosing(source_p)) + return(0); + + SetClosing(source_p); + if (MyConnect(source_p)) { - /* DO NOT REMOVE. exit_client can be called twice after a failed - * read/write. - */ - if(IsClosing(source_p)) - return 0; - - SetClosing(source_p); - if (source_p->flags & FLAGS_IPHASH) + if (IsIpHash(source_p)) remove_one_ip(&source_p->localClient->ip); delete_adns_queries(source_p->localClient->dns_query); @@ -1317,9 +1358,10 @@ exit_client( source_p->name, source_p->username, source_p->host, comment, source_p->localClient->sockhost); + log_user_exit(source_p); - if (source_p->localClient->fd >= 0) + if (!IsDead(source_p)) { if (client_p != NULL && source_p != client_p) sendto_one(source_p, "ERROR :Closing Link: %s %s (%s)", @@ -1328,20 +1370,6 @@ exit_client( sendto_one(source_p, "ERROR :Closing Link: %s (%s)", source_p->vhost, 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)) @@ -1379,12 +1407,18 @@ exit_client( source_p->localClient->sendK, source_p->localClient->receiveK); } } + + if(MyConnect(source_p)) + { + close_connection(source_p); + SetDead(source_p); /* You are dead my friend */ + } + /* 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; diff --git a/src/dynlink.c b/src/dynlink.c index 7721acc..2171574 100644 --- a/src/dynlink.c +++ b/src/dynlink.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: dynlink.c,v 1.3 2002/09/13 06:50:08 fishwaldo Exp $ + * $Id: dynlink.c,v 1.4 2003/01/29 09:28:49 fishwaldo Exp $ * */ #include "stdinc.h" @@ -50,6 +50,27 @@ static char unknown_ver[] = ""; * -TimeMr14C */ +#if !defined(HAVE_SHL_LOAD) && !defined(HAVE_DLFUNC) +/* + * Fake dlfunc(3) if we don't have it, cause it's happy. + */ +typedef void (*__function_p)(void); + +__function_p +dlfunc(void *myHandle, const char *functionName) +{ + /* XXX This is not guaranteed to work, but with + * traditional dl*(3), it is the best we can do. + * -jmallett + */ + void *symbolp; + + symbolp = dlsym(myHandle, functionName); + + return (__function_p)(uintptr_t)symbolp; +} +#endif + #ifdef HAVE_MACH_O_DYLD_H /* @@ -192,17 +213,14 @@ int unload_one_module (char *name, int warn) shl_unload((shl_t) & (modlist[modindex]->address)); #else /* - ** XXX - The type system in C does not allow direct conversion between - ** data and function pointers, but as it happens, most C compilers will - ** safely do this, however it is a theoretical overlow to cast as we - ** must do here. I have library functions to take care of this, but - ** despite being more "correct" for the C language, this is more - ** practical. Removing the abuse of the ability to cast ANY pointer - ** to and from an integer value here will break some compilers. + ** We use FreeBSD's dlfunc(3) interface, or fake it as we + ** used to here if it isn't there. The interface should + ** be standardised some day, and so it eventually will be + ** providing something guaranteed to do the right thing here. ** -jmallett */ - if ((deinitfunc = (void (*)(void))(uintptr_t)dlsym(modlist[modindex]->address, "_moddeinit")) - || (deinitfunc = (void (*)(void))(uintptr_t)dlsym(modlist[modindex]->address, "__moddeinit"))) { + if ((deinitfunc = (void (*)(void))dlfunc(modlist[modindex]->address, "_moddeinit")) + || (deinitfunc = (void (*)(void))dlfunc(modlist[modindex]->address, "__moddeinit"))) { deinitfunc(); } dlclose(modlist[modindex]->address); @@ -291,9 +309,9 @@ load_a_module (char *path, int warn, int core) ver = *verp; #else - initfunc = (void (*)(void))(uintptr_t)dlsym (tmpptr, "_modinit"); + initfunc = (void (*)(void))dlfunc (tmpptr, "_modinit"); if (initfunc == NULL - && (initfunc = (void (*)(void))(uintptr_t)dlsym(tmpptr, "__modinit")) == NULL) + && (initfunc = (void (*)(void))dlfunc(tmpptr, "__modinit")) == NULL) { sendto_realops_flags(FLAGS_ALL, L_ALL, "Module %s has no _modinit() function", diff --git a/src/ircd.c b/src/ircd.c index b34eaea..50f5e6b 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.9 2003/01/27 04:20:36 fishwaldo Exp $ + * $Id: ircd.c,v 1.10 2003/01/29 09:28:49 fishwaldo Exp $ */ #include "stdinc.h" @@ -110,11 +110,12 @@ int callbacks_called; /* A measure of server load... */ static unsigned long initialVMTop = 0; /* top of virtual memory at init */ const char * logFileName = LPATH; -static const char * pidFileName = PPATH; +const char * pidFileName = PPATH; char** myargv; int dorehash = 0; -int debuglevel = 10; /* Server debug level */ +int doremotd = 0; +int debuglevel = -1; /* Server debug level */ char* debugmode = ""; /* -"- -"- -"- */ time_t nextconnect = 1; /* time for next try_connections call */ @@ -338,6 +339,13 @@ io_loop(void) rehash(1); dorehash = 0; } + if (doremotd) + { + ReadMessageFile( &ConfigFileEntry.motd ); + sendto_realops_flags(FLAGS_ALL, L_ALL, + "Got signal SIGUSR1, reloading ircd motd file"); + doremotd = 0; + } } } @@ -480,7 +488,7 @@ static void check_pidfile(const char *filename) } fbclose(fb); } - else + else if(errno != ENOENT) { /* log(L_ERROR, "Error opening pid file %s", filename); */ } @@ -508,19 +516,6 @@ static void setup_corefile(void) #endif } -/* - * cleanup_zombies - * inputs - nothing - * output - nothing - * side effects - Reaps zombies periodically - * -AndroSyn - */ -static void cleanup_zombies(void *unused) -{ - int status; - waitpid(-1, &status, WNOHANG); -} - int main(int argc, char *argv[]) { /* Check to see if the user is running us as root, which is a nono */ @@ -747,13 +742,16 @@ int main(int argc, char *argv[]) /* Setup the timeout check. I'll shift it later :) -- adrian */ eventAddIsh("comm_checktimeouts", comm_checktimeouts, NULL, 1); - +#if 0 eventAddIsh("cleanup_zombies", cleanup_zombies, NULL, 30); - +#endif + +#if 0 if (ConfigFileEntry.throttle_time > 0) eventAddIsh("flush_expired_ips", flush_expired_ips, NULL, ConfigFileEntry.throttle_time); else eventAddIsh("flush_expired_ips", flush_expired_ips, NULL, 300); +#endif if(ConfigServerHide.links_delay > 0) eventAddIsh("write_links_file", write_links_file, NULL, ConfigServerHide.links_delay); diff --git a/src/ircd_parser.y b/src/ircd_parser.y index 3e64630..b872267 100644 --- a/src/ircd_parser.y +++ b/src/ircd_parser.y @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: ircd_parser.y,v 1.14 2003/01/27 04:20:36 fishwaldo Exp $ + * $Id: ircd_parser.y,v 1.15 2003/01/29 09:28:49 fishwaldo Exp $ */ %{ @@ -377,7 +377,7 @@ modules_module: MODULE '=' QSTRING ';' break; /* XXX - should we unload this module on /rehash, if it isn't listed? */ - load_one_module (yylval.string); + load_one_module (yylval.string, 0); MyFree(m_bn); #endif diff --git a/src/ircdauth.c b/src/ircdauth.c index bd2d633..edff87c 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.5 2002/09/13 16:30:04 fishwaldo Exp $ + * $Id: ircdauth.c,v 1.6 2003/01/29 09:28:49 fishwaldo Exp $ */ #include "stdinc.h" @@ -613,7 +613,7 @@ GreetUser(struct Client *client) me.name, client->user->server); - client->flags |= FLAGS_KILLED; + SetKilled(client); exit_client(NULL, client, &me, "Ghost"); return; diff --git a/src/kdparse.c b/src/kdparse.c index 0130e4b..8837d43 100644 --- a/src/kdparse.c +++ b/src/kdparse.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: kdparse.c,v 1.3 2002/09/13 06:50:08 fishwaldo Exp $ + * $Id: kdparse.c,v 1.4 2003/01/29 09:28:49 fishwaldo Exp $ */ #include "stdinc.h" @@ -81,7 +81,8 @@ parse_k_file(FBFILE *file) * Side Effects - Parse one new style D line */ -void parse_d_file(FBFILE *file) +void +parse_d_file(FBFILE *file) { struct ConfItem *aconf; char* reason_field=(char *)NULL; @@ -117,44 +118,55 @@ void parse_d_file(FBFILE *file) * output - next field * side effects - field breakup for ircd.conf file. */ -char *getfield(char *newline) +char * +getfield(char *newline) { - static char *line = (char *)NULL; + static char *line = NULL; char *end, *field; - if (newline) + if (newline != NULL) line = newline; - if (line == (char *)NULL) - return((char *)NULL); + if (line == NULL) + return(NULL); field = line; /* XXX make this skip to first " if present */ if(*field == '"') + { field++; + end = field; + } else - return((char *)NULL); /* mal-formed field */ + return(NULL); /* mal-formed field */ - if ((end = strchr(line,',')) == NULL) + for (;;) + { + /* At end of string, mark it as end and return */ + if (*end == '\0') { - end = line + strlen(line); - line = (char *)NULL; - /* XXX verify properly terminating " */ - if(*end == '"') - *end = '\0'; - else - return((char *)NULL); + line = NULL; + return(NULL); } - else + else if (*end == '\\') /* found escape character ? */ { - line = end + 1; - --end; - if(*end == '"') - *end = '\0'; - else - return((char *)NULL); + end++; } - return(field); + else if(*end == '"') /* found terminating " */ + { + *end++ = '\0'; + while (IsSpace(*end)) /* skip to start of next " (or '\0') */ + end++; + while (*end == ',') + end++; + while (IsSpace(*end)) + end++; + line = end; + return(field); + } + end++; + } + return (NULL); } diff --git a/src/md5.c b/src/md5.c index 85e2f50..d012a13 100644 --- a/src/md5.c +++ b/src/md5.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: md5.c,v 1.3 2002/09/13 06:50:08 fishwaldo Exp $ + * $Id: md5.c,v 1.4 2003/01/29 09:28:49 fishwaldo Exp $ */ #include "stdinc.h" @@ -304,13 +304,13 @@ int unbase64_block(char **output, char *data, int len) q_in = 0; - if (base64_values[in[i+3]] > -1) + if (base64_values[in[i+3]] != (char)-1) q_in |= base64_values[in[i+3]] ; - if (base64_values[in[i+2]] > -1) + if (base64_values[in[i+2]] != (char)-1) q_in |= base64_values[in[i+2]] << 6; - if (base64_values[in[i+1]] > -1) + if (base64_values[in[i+1]] != (char)-1) q_in |= base64_values[in[i+1]] << 12; - if (base64_values[in[i ]] > -1) + if (base64_values[in[i ]] != (char)-1) q_in |= base64_values[in[i ]] << 18; out[count++] = (q_in >> 16) & 0xff; diff --git a/src/messages.tab b/src/messages.tab index 60e5f17..db6799e 100644 --- a/src/messages.tab +++ b/src/messages.tab @@ -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: messages.tab,v 1.9 2002/11/20 14:13:57 fishwaldo Exp $ + * $Id: messages.tab,v 1.10 2003/01/29 09:28:49 fishwaldo Exp $ */ static char * replies[] = { @@ -540,7 +540,7 @@ static char * replies[] = { /* 510 */ NULL, /* 511 */ NULL, /* 512 */ NULL, -/* 513 ERR_WRONGPONG */ "%s 513 %s :To connect type /QUOTE PONG %lu", +/* 513 ERR_WRONGPONG */ ":%s 513 %s :To connect type /QUOTE PONG %lu", /* 514 */ NULL, /* 515 */ NULL, /* 516 */ NULL, diff --git a/src/modules.c b/src/modules.c index aa55d21..25fb134 100644 --- a/src/modules.c +++ b/src/modules.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: modules.c,v 1.6 2002/09/13 16:30:04 fishwaldo Exp $ + * $Id: modules.c,v 1.7 2003/01/29 09:28:49 fishwaldo Exp $ */ #include "stdinc.h" @@ -320,7 +320,7 @@ load_core_modules(int warn) * side effects - */ int -load_one_module (char *path) +load_one_module (char *path, int coremodule) { char modpath[MAXPATHLEN]; dlink_node *pathst; @@ -340,7 +340,10 @@ load_one_module (char *path) if(S_ISREG(statbuf.st_mode)) { /* Regular files only please */ - return load_a_module(modpath, 1, 0); + if (coremodule) + return load_a_module(modpath, 1, 1); + else + return load_a_module(modpath, 1, 0); } } @@ -372,10 +375,11 @@ mo_modload (struct Client *client_p, struct Client *source_p, int parc, char **p { sendto_one (source_p, ":%s NOTICE %s :Module %s is already loaded", me.name, source_p->name, m_bn); + MyFree(m_bn); return; } - load_one_module (parv[1]); + load_one_module (parv[1], 0); MyFree(m_bn); } @@ -414,7 +418,7 @@ mo_modunload (struct Client *client_p, struct Client *source_p, int parc, char * return; } - if( unload_one_module (m_bn, 1) == -1 ) + if(unload_one_module (m_bn, 1) == -1) { sendto_one (source_p, ":%s NOTICE %s :Module %s is not loaded", me.name, source_p->name, m_bn); @@ -449,7 +453,7 @@ mo_modreload (struct Client *client_p, struct Client *source_p, int parc, char * check_core = modlist[modindex]->core; - if( unload_one_module (m_bn, 1) == -1 ) + if(unload_one_module (m_bn, 1) == -1) { sendto_one (source_p, ":%s NOTICE %s :Module %s is not loaded", me.name, source_p->name, m_bn); @@ -457,7 +461,7 @@ mo_modreload (struct Client *client_p, struct Client *source_p, int parc, char * return; } - if((load_one_module(parv[1]) == -1) && check_core) + if((load_one_module(parv[1], check_core) == -1) && check_core) { sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ALL, "Error reloading core module: %s: terminating ircd", diff --git a/src/packet.c b/src/packet.c index 0f3ab1d..029b96e 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.8 2003/01/27 04:20:36 fishwaldo Exp $ + * $Id: packet.c,v 1.9 2003/01/29 09:28:50 fishwaldo Exp $ */ #include "stdinc.h" #include "tools.h" @@ -58,27 +58,31 @@ parse_client_queued(struct Client *client_p) for(;;) { + if (IsDead(client_p)) + return; + if (client_p->localClient == NULL) + return; + /* rate unknown clients at MAX_FLOOD per loop */ if(i >= MAX_FLOOD) break; - dolen = linebuf_get(&client_p->localClient->buf_recvq, readBuf, - READBUF_SIZE, LINEBUF_COMPLETE, LINEBUF_PARSED); + dolen = linebuf_get(&client_p->localClient->buf_recvq, readBuf, + READBUF_SIZE, LINEBUF_COMPLETE, LINEBUF_PARSED); - if(dolen <= 0) - break; + if(dolen <= 0) + break; if(!IsDead(client_p)) { client_dopacket(client_p, readBuf, dolen); i++; - /* if theyve dropped out of the unknown state, break and move + /* if they've dropped out of the unknown state, break and move * to the parsing for their appropriate status. --fl */ if(!IsUnknown(client_p)) break; - } else if(MyConnect(client_p)) { @@ -91,6 +95,11 @@ parse_client_queued(struct Client *client_p) if (IsServer(client_p) || IsConnecting(client_p) || IsHandshake(client_p)) { + if(IsDead(client_p)) + return; + if(client_p->localClient == NULL) + return; + while ((dolen = linebuf_get(&client_p->localClient->buf_recvq, readBuf, READBUF_SIZE, LINEBUF_COMPLETE, LINEBUF_PARSED)) > 0) @@ -103,22 +112,31 @@ parse_client_queued(struct Client *client_p) linebuf_donebuf(&client_p->localClient->buf_sendq); return; } + if (client_p->localClient == NULL) + return; } } - else if(IsClient(client_p)) + else if(IsClient(client_p)) { - checkflood = 0; + if (ConfigFileEntry.no_oper_flood && (IsOper(client_p) || IsCanFlood(client_p))) - if (ConfigFileEntry.true_no_oper_flood) + { + if (ConfigFileEntry.true_no_oper_flood) checkflood = -1; + else + checkflood = 0; + } /* * Handle flood protection here - if we exceed our flood limit on * messages in this loop, we simply drop out of the loop prematurely. * -- adrian */ - for (;;) + for(;;) { + if (IsDead(client_p)) + break; + /* This flood protection works as follows: * * A client is given allow_read lines to send to the server. Every @@ -144,6 +162,9 @@ parse_client_queued(struct Client *client_p) else if(lclient_p->sent_parsed >= (4 * lclient_p->allow_read) && checkflood != -1) break; + if(client_p->localClient == NULL) + break; + dolen = linebuf_get(&client_p->localClient->buf_recvq, readBuf, READBUF_SIZE, LINEBUF_COMPLETE, LINEBUF_PARSED); @@ -254,14 +275,12 @@ read_ctrl_packet(int fd, void *data) { if((length == -1) && ignoreErrno(errno)) goto nodata; - error_exit_client(server, length); return; } - reply->command = tmp[0]; } - for (replydef = slinkrpltab; replydef->handler; replydef++) + for(replydef = slinkrpltab; replydef->handler; replydef++) { if (replydef->replyid == reply->command) break; @@ -279,7 +298,7 @@ read_ctrl_packet(int fd, void *data) { if((length == -1) && ignoreErrno(errno)) goto nodata; - error_exit_client(server, length); + dead_link_on_read(server, length); return; } @@ -310,7 +329,7 @@ read_ctrl_packet(int fd, void *data) { if((length == -1) && ignoreErrno(errno)) goto nodata; - error_exit_client(server, length); + dead_link_on_read(server, length); return; } @@ -391,7 +410,7 @@ read_packet(int fd, void *data) } else #endif - length = recv(fd_r, readBuf, READBUF_SIZE, 0); + length = recv(fd_r, readBuf, READBUF_SIZE, 0); /* THIS WAS <= 0, should it stay? */ if (length <= 0) @@ -402,7 +421,7 @@ read_packet(int fd, void *data) read_packet, client_p, 0); return; } - error_exit_client(client_p, length); + dead_link_on_read(client_p, length); return; } @@ -430,67 +449,53 @@ read_packet(int fd, void *data) lbuf_len = linebuf_parse(&client_p->localClient->buf_recvq, readBuf, length, binary); - if (lbuf_len < 0) - { - if (IsClient(client_p)) - sendto_one(client_p, ":%s NOTICE %s :*** - You sent a NULL character in " - "your message. Ignored.", - me.name, client_p->name); - else - exit_client(client_p, client_p, client_p, "NULL character found in message"); - return; - } - lclient_p->actually_read += lbuf_len; - if (client_p->next == NULL) - return; - /* Attempt to parse what we have */ - 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)) + + if (!IsDead(client_p)) { + parse_client_queued(client_p); + if (IsDead(client_p)) + 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; + 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 (!IsDead(client_p)) - { /* If we get here, we need to register for another COMM_SELECT_READ */ - if (PARSE_AS_SERVER(client_p)) { + if (PARSE_AS_SERVER(client_p)) + { comm_setselect(fd_r, FDLIST_SERVER, COMM_SELECT_READ, - read_packet, client_p, 0); - } else { + read_packet, client_p, 0); + } + else + { comm_setselect(fd_r, FDLIST_IDLECLIENT, COMM_SELECT_READ, - read_packet, client_p, 0); + read_packet, client_p, 0); } } - /* This is about the only place useful to put it */ - exit_aborted_clients(); - } - - - /* * client_dopacket - copy packet to client buf and parse it * client_p - pointer to client structure for which the buffer data diff --git a/src/parse.c b/src/parse.c index 52e1737..2896be8 100644 --- a/src/parse.c +++ b/src/parse.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: parse.c,v 1.8 2002/10/31 13:01:58 fishwaldo Exp $ + * $Id: parse.c,v 1.9 2003/01/29 09:28:50 fishwaldo Exp $ */ #include "stdinc.h" @@ -135,7 +135,7 @@ parse(struct Client *client_p, char *pbuffer, char *bufend) assert(!IsDead(client_p)); assert(client_p->localClient->fd >= 0); - if(IsDead(client_p) || client_p->localClient->fd < 0) + if(IsDefunct(client_p)) return; assert((bufend-pbuffer) < 512); @@ -542,7 +542,7 @@ hash(char *p) * * inputs - pointer to client to report to * output - NONE - * side effects - NONE + * side effects - client is shown list of commands */ void report_messages(struct Client *source_p) @@ -556,11 +556,12 @@ report_messages(struct Client *source_p) { assert(ptr->msg != NULL); assert(ptr->cmd != NULL); - - sendto_one(source_p, form_str(RPL_STATSCOMMANDS), - me.name, source_p->name, ptr->cmd, - ptr->msg->count, ptr->msg->bytes, - ptr->msg->rcount); + + if (!((ptr->msg->flags & MFLG_HIDDEN) && !IsAdmin(source_p))) + sendto_one(source_p, form_str(RPL_STATSCOMMANDS), + me.name, source_p->name, ptr->cmd, + ptr->msg->count, ptr->msg->bytes, + ptr->msg->rcount); } } } @@ -581,8 +582,9 @@ list_commands(struct Client *source_p) { for(ptr = msg_hash_table[i]; ptr; ptr = ptr->next) { - sendto_one(source_p, ":%s NOTICE %s :%s", - me.name, source_p->name, ptr->cmd); + if (!((ptr->msg->flags & MFLG_HIDDEN) && !IsAdmin(source_p))) + sendto_one(source_p, ":%s NOTICE %s :%s", + me.name, source_p->name, ptr->cmd); } } } diff --git a/src/restart.c b/src/restart.c index bda2286..898a2f1 100644 --- a/src/restart.c +++ b/src/restart.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: restart.c,v 1.4 2002/09/13 16:30:04 fishwaldo Exp $ + * $Id: restart.c,v 1.5 2003/01/29 09:28:50 fishwaldo Exp $ */ #include "stdinc.h" @@ -60,7 +60,7 @@ void server_reboot(void) sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ALL, "Restarting server..."); - ilog(L_NOTICE, "Restarting server..."); + ilog(L_NOTICE, "Restarting server... (%s)",SPATH); /* * XXX we used to call flush_connections() here. But since this routine * doesn't exist anymore, we won't be flushing. This is ok, since @@ -71,11 +71,11 @@ void server_reboot(void) * bah, for now, the program ain't coming back to here, so forcibly * close everything the "wrong" way for now, and just LEAVE... */ - for (i = 0; i < MAXCONNECTIONS; ++i) + for (i = 3; i < MAXCONNECTIONS; ++i) close(i); + unlink(pidFileName); execv(SPATH, myargv); - + fprintf(stderr, "ircd: execv() failed: %s\n", strerror(errno)); exit(-1); } - diff --git a/src/s_bsd.c b/src/s_bsd.c index 603c567..5f31295 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.9 2002/11/04 08:14:00 fishwaldo Exp $ + * $Id: s_bsd.c,v 1.10 2003/01/29 09:28:50 fishwaldo Exp $ */ #include "stdinc.h" @@ -52,6 +52,7 @@ #endif #include "memory.h" + #ifndef IN_LOOPBACKNET #define IN_LOOPBACKNET 0x7f #endif @@ -75,7 +76,8 @@ static PF comm_connect_tryconnect; /* close_all_connections() can be used *before* the system come up! */ -void close_all_connections(void) +void +close_all_connections(void) { int i; #ifndef NDEBUG @@ -120,14 +122,16 @@ void close_all_connections(void) * This may only work when SO_DEBUG is enabled but its worth the * gamble anyway. */ -int get_sockerr(int fd) +int +get_sockerr(int fd) { int errtmp = errno; #ifdef SO_ERROR int err = 0; socklen_t len = sizeof(err); - if (-1 < fd && !getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*) &err, (socklen_t *)&len)) { + if (-1 < fd && !getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*) &err, (socklen_t *)&len)) + { if (err) errtmp = err; } @@ -155,7 +159,8 @@ int get_sockerr(int fd) * Actually stderr is still there IFF ircd was run with -s --Rodder */ -void report_error(int level, const char* text, const char* who, int error) +void +report_error(int level, const char* text, const char* who, int error) { who = (who) ? who : ""; @@ -207,7 +212,8 @@ disable_sock_options(int fd) * side effects - use POSIX compliant non blocking and * be done with it. */ -int set_non_blocking(int fd) +int +set_non_blocking(int fd) { #ifndef VMS int nonb = 0; @@ -242,7 +248,8 @@ int set_non_blocking(int fd) * Close the physical connection. This function must make * MyConnect(client_p) == FALSE, and set client_p->from == NULL. */ -void close_connection(struct Client *client_p) +void +close_connection(struct Client *client_p) { struct ConfItem *aconf; assert(NULL != client_p); @@ -309,18 +316,18 @@ void close_connection(struct Client *client_p) else ServerStats->is_ni++; - if (-1 < client_p->localClient->fd) + if (!IsDead(client_p)) { /* attempt to flush any pending dbufs. Evil, but .. -- adrian */ - if (!IsDead(client_p)) - send_queued_write(client_p->localClient->fd, 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)) { - if(client_p->localClient->fd > -1) + if(client_p->localClient->ctrlfd > -1) { fd_close(client_p->localClient->ctrlfd); #ifndef HAVE_SOCKETPAIR @@ -346,7 +353,8 @@ void close_connection(struct Client *client_p) * The client is sent to the auth module for verification, and not put in * any client list yet. */ -void add_connection(struct Listener* listener, int fd) +void +add_connection(struct Listener* listener, int fd) { struct Client* new_client; @@ -478,73 +486,6 @@ void add_connection(struct Listener* listener, int fd) } -void error_exit_client(struct Client* client_p, int error) -{ - /* - * ...hmm, with non-blocking sockets we might get - * here from quite valid reasons, although.. why - * would select report "data available" when there - * wasn't... so, this must be an error anyway... --msa - * actually, EOF occurs when read() returns 0 and - * in due course, select() returns that fd as ready - * for reading even though it ends up being an EOF. -avalon - */ - char errmsg[255]; - int current_error = get_sockerr(client_p->localClient->fd); - - Debug((DEBUG_ERROR, "READ ERROR: fd = %d %d %d", - client_p->localClient->fd, current_error, error)); - if (IsServer(client_p) || IsHandshake(client_p)) - { - int connected = CurrentTime - client_p->firsttime; - - if (error == 0) - { - /* Admins get the real IP */ - sendto_realops_flags(FLAGS_ALL, 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, - "Server %s closed the connection", - get_client_name(client_p, MASK_IP)); - - ilog(L_NOTICE, "Server %s closed the connection", - get_client_name(client_p, SHOW_IP)); - } - else - { - report_error(L_ADMIN, "Lost connection to %s: %d", - get_client_name(client_p, SHOW_IP), - current_error); - report_error(L_OPER, "Lost connection to %s: %d", - get_client_name(client_p, MASK_IP), - current_error); - - } - - sendto_realops_flags(FLAGS_ALL, L_ALL, - "%s had been connected for %d day%s, %2d:%02d:%02d", - client_p->name, connected/86400, - (connected/86400 == 1) ? "" : "s", - (connected % 86400) / 3600, (connected % 3600) / 60, - connected % 60); - } - if (error == 0) - { - strcpy(errmsg, "Remote host closed the connection"); - } - else - { - ircsprintf(errmsg, "Read error: %s", - strerror(current_error)); - } - fd_close(client_p->localClient->fd); - client_p->localClient->fd = -1; - - exit_client(client_p, client_p, &me, errmsg); -} /* * stolen from squid - its a neat (but overused! :) routine which we diff --git a/src/s_bsd_devpoll.c b/src/s_bsd_devpoll.c index ab7689e..214bd0c 100644 --- a/src/s_bsd_devpoll.c +++ b/src/s_bsd_devpoll.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: s_bsd_devpoll.c,v 1.3 2002/09/13 06:50:08 fishwaldo Exp $ + * $Id: s_bsd_devpoll.c,v 1.4 2003/01/29 09:28:50 fishwaldo Exp $ */ #include "config.h" @@ -296,5 +296,9 @@ comm_select(unsigned long delay) /* XXX Get here, we broke! */ return 0; } - +#else +/** + * Don't let an empty compilation unit slip through. + */ +static int dummy; #endif /* USE_DEVPOLL */ diff --git a/src/s_bsd_kqueue.c b/src/s_bsd_kqueue.c index d2eb966..5bbb12d 100644 --- a/src/s_bsd_kqueue.c +++ b/src/s_bsd_kqueue.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: s_bsd_kqueue.c,v 1.3 2002/09/13 06:50:08 fishwaldo Exp $ + * $Id: s_bsd_kqueue.c,v 1.4 2003/01/29 09:28:50 fishwaldo Exp $ */ #include "config.h" @@ -286,4 +286,9 @@ comm_select(unsigned long delay) return 0; } +#else /* USE_KQUEUE */ +/** + * Don't let an empty compilation unit slip through. + */ +static int dummy; #endif /* USE_KQUEUE */ diff --git a/src/s_bsd_poll.c b/src/s_bsd_poll.c index b245b66..eacb542 100644 --- a/src/s_bsd_poll.c +++ b/src/s_bsd_poll.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: s_bsd_poll.c,v 1.3 2002/09/13 06:50:08 fishwaldo Exp $ + * $Id: s_bsd_poll.c,v 1.4 2003/01/29 09:28:50 fishwaldo Exp $ */ #include "config.h" @@ -257,5 +257,9 @@ comm_select(unsigned long delay) } return 0; } - +#else +/** + * Don't let an empty compilation unit slip through. + */ +static int dummy; #endif diff --git a/src/s_bsd_select.c b/src/s_bsd_select.c index 0c4f377..6e1c5b0 100644 --- a/src/s_bsd_select.c +++ b/src/s_bsd_select.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: s_bsd_select.c,v 1.3 2002/09/13 06:50:08 fishwaldo Exp $ + * $Id: s_bsd_select.c,v 1.4 2003/01/29 09:28:50 fishwaldo Exp $ */ #include "config.h" @@ -219,4 +219,9 @@ comm_select(unsigned long delay) return 0; } +#else /* USE_SELECT */ +/** + * Don't let an empty compilation unit slip through. + */ +static int dummy; #endif /* USE_SELECT */ diff --git a/src/s_bsd_sigio.c b/src/s_bsd_sigio.c index 7aae0c4..af9f380 100644 --- a/src/s_bsd_sigio.c +++ b/src/s_bsd_sigio.c @@ -21,7 +21,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: s_bsd_sigio.c,v 1.3 2002/09/13 06:50:08 fishwaldo Exp $ + * $Id: s_bsd_sigio.c,v 1.4 2003/01/29 09:28:50 fishwaldo Exp $ */ #ifndef _GNU_SOURCE @@ -353,5 +353,9 @@ int comm_select(unsigned long delay) mask_our_signal(sigio_signal); return 0; } - +#else +/** + * Don't let an empty compilation unit slip through. + */ +static int dummy; #endif diff --git a/src/s_conf.c b/src/s_conf.c index b2de517..e075475 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.11 2002/10/31 13:01:58 fishwaldo Exp $ + * $Id: s_conf.c,v 1.12 2003/01/29 09:28:50 fishwaldo Exp $ */ #include "stdinc.h" @@ -211,6 +211,7 @@ free_conf(struct ConfItem* aconf) MyFree(aconf->name); MyFree(aconf->className); MyFree(aconf->user); + MyFree(aconf->fakename); #ifdef HAVE_LIBCRYPTO if (aconf->rsa_public_key) { RSA_free(aconf->rsa_public_key); } if (aconf->rsa_public_key_file) { MyFree(aconf->rsa_public_key_file); } @@ -272,7 +273,8 @@ report_configured_links(struct Client* source_p, int mask) char* classname; int port; - for (tmp = ConfigItemList; tmp; tmp = tmp->next) { + for (tmp = ConfigItemList; tmp; tmp = tmp->next) + { if (tmp->status & mask) { for (p = &report_array[0]; p->conf_type; p++) @@ -404,15 +406,16 @@ report_specials(struct Client* source_p, int flags, int numeric) int check_client(struct Client *client_p, struct Client *source_p, char *username) { - static char sockname[HOSTLEN + 1]; - int i; + int i; ClearAccess(source_p); + /* I'm already in big trouble if source_p->localClient is NULL -db */ if ((i = verify_access(source_p, username))) - { - ilog(L_INFO, "Access denied: %s[%s]", source_p->name, sockname); - } + { + ilog(L_INFO, "Access denied: %s[%s]", + source_p->name, source_p->localClient->sockhost); + } switch( i ) { @@ -469,7 +472,7 @@ check_client(struct Client *client_p, struct Client *source_p, char *username) source_p->localClient->listener->port); (void)exit_client(client_p, source_p, &me, - "You are not authorised to use this server"); + "You are not authorized to use this server"); break; } case BANNED_CLIENT: @@ -582,8 +585,8 @@ int attach_iline(struct Client *client_p, struct ConfItem *aconf) ip_found->count++; /* only check it if its non zero */ - if ( aconf->c_class /* This should never non NULL *grin* */ && - ConfConFreq(aconf) && ip_found->count > ConfConFreq(aconf)) + if (aconf->c_class /* This should never non NULL *grin* */ && + ConfConFreq(aconf) && ip_found->count > ConfConFreq(aconf)) { if(!IsConfExemptLimits(aconf)) return(TOO_MANY); /* Already at maximum allowed ip#'s */ @@ -668,9 +671,9 @@ find_or_add_ip(struct irc_inaddr *ip_in) return(ptr); } } - if ((ptr = ip_hash_table[hash_index]) != (IP_ENTRY *)NULL) + if ((ptr = ip_hash_table[hash_index]) != NULL) { - if( free_ip_entries == (IP_ENTRY *)NULL) + if (free_ip_entries == NULL) outofmemory(); newptr = ip_hash_table[hash_index] = free_ip_entries; @@ -683,14 +686,14 @@ find_or_add_ip(struct irc_inaddr *ip_in) return(newptr); } - if (free_ip_entries == (IP_ENTRY *)NULL) + if (free_ip_entries == NULL) outofmemory(); 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 = (IP_ENTRY *)NULL; + ptr->next = NULL; return(ptr); } @@ -710,28 +713,28 @@ remove_one_ip(struct irc_inaddr *ip_in) { IP_ENTRY *ptr, **lptr; int hash_index = hash_ip(ip_in); - for (lptr = ip_hash_table+hash_index, ptr = *lptr; - ptr; + for (lptr = ip_hash_table+hash_index, ptr = *lptr; ptr; lptr=&ptr->next, ptr=*lptr) { #ifndef IPV6 - if (ptr->ip != PIN_ADDR(ip_in)) - continue; + if (ptr->ip != PIN_ADDR(ip_in)) + continue; #else - if (memcmp(&IN_ADDR(ptr->ip), &PIN_ADDR(ip_in), - sizeof(struct irc_inaddr))) - continue; + if (memcmp(&IN_ADDR(ptr->ip), &PIN_ADDR(ip_in), + sizeof(struct irc_inaddr))) + continue; #endif - if (ptr->count != 0) - ptr->count--; - if (ptr->count != 0 || - (CurrentTime-ptr->last_attempt)<=ConfigFileEntry.throttle_time) - continue; - *lptr = ptr->next; - ptr->next = free_ip_entries; - free_ip_entries = ptr; - return; - } + if (ptr->count > 0) + ptr->count--; + if (ptr->count == 0 && + (CurrentTime-ptr->last_attempt)>ConfigFileEntry.throttle_time) + { + *lptr = ptr->next; + ptr->next = free_ip_entries; + free_ip_entries = ptr; + return; + } + } } /* @@ -1554,7 +1557,6 @@ conf_connect_allowed(struct irc_inaddr *addr, int aftype) ConfigFileEntry.throttle_time) { ip_found->last_attempt = CurrentTime; - ip_found->count--; return(TOO_FAST); } ip_found->last_attempt = CurrentTime; @@ -2146,7 +2148,7 @@ WriteKlineOrDline( KlineType type, filename = get_conf_name(type); - if(type == DLINE_TYPE) + if (type == DLINE_TYPE) { sendto_realops_flags(FLAGS_ALL, L_ALL, "%s added D-Line for [%s] [%s]", @@ -2164,7 +2166,7 @@ WriteKlineOrDline( KlineType type, me.name, source_p->name, user, host); } - if ( (out = fbopen(filename, "a")) == NULL ) + if ((out = fbopen(filename, "a")) == NULL) { sendto_realops_flags(FLAGS_ALL, L_ALL, "*** Problem opening %s ", filename); @@ -2424,34 +2426,3 @@ conf_yy_fatal_error(char *msg) { return(0); } - - -/* void flush_expired_ips(void *unused) - * - * inputs - none. - * output - none. - * side effects - Deletes all IP address entries which should have expired. - */ -void -flush_expired_ips(void *unused) -{ - int i; - time_t expire_before = CurrentTime - ConfigFileEntry.throttle_time; - IP_ENTRY *ie, **iee; - - for (i=0; icount == 0 && ie->last_attempt <= expire_before) - { - *iee=ie->next; - ie->next = free_ip_entries; - free_ip_entries = ie; - } - else - iee = &ie->next; - } - *iee = NULL; - } -} diff --git a/src/s_serv.c b/src/s_serv.c index 07212cd..0b8c124 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.14 2002/10/31 13:01:58 fishwaldo Exp $ + * $Id: s_serv.c,v 1.15 2003/01/29 09:28:50 fishwaldo Exp $ */ #include "stdinc.h" @@ -29,6 +29,8 @@ #include "rsa.h" #endif +#include + #include "tools.h" #include "s_serv.h" #include "channel_mode.h" @@ -939,6 +941,7 @@ int server_estab(struct Client *client_p) dlink_node *m; dlink_node *ptr; unsigned int srvopt; + int opt; assert(NULL != client_p); if(client_p == NULL) @@ -1004,11 +1007,17 @@ int server_estab(struct Client *client_p) srvopt = 0; if (ConfigServerHide.hidden) srvopt = SERVER_HIDDEN; - + opt = 1; + setsockopt(client_p->localClient->fd, IPPROTO_TCP, TCP_NODELAY, + (char *)&opt, sizeof(opt)); + sendto_one(client_p, "SERVER %s 1 %d :%s", my_name_for_link(me.name, aconf), srvopt, (me.info[0]) ? (me.info) : "IRCers United"); + opt--; + setsockopt(client_p->localClient->fd, IPPROTO_TCP, TCP_NODELAY, + (char *)&opt, sizeof(opt)); } /* @@ -1133,7 +1142,7 @@ int server_estab(struct Client *client_p) } else fd_note(client_p->localClient->fd, "Server: %s", client_p->name); - /* + /* ** Send reserved nickname and channel information to the other server ** these can be dynamic (ie, set from other servers) or config based ** seeing as both types should be applied to the entire network @@ -2144,7 +2153,11 @@ serv_connect_callback(int fd, int status, void *data) sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_OPER, "Error connecting to %s: %s", client_p->name, comm_errstr(status)); - exit_client(client_p, client_p, &me, comm_errstr(status)); + + /* If a fd goes bad, call dead_link() the socket is no + * longer valid for reading or writing. + */ + dead_link_on_write(client_p, 0); return; } @@ -2152,13 +2165,14 @@ serv_connect_callback(int fd, int status, void *data) /* Get the C/N lines */ aconf = find_conf_name(&client_p->localClient->confs, client_p->name, CONF_SERVER); - if (!aconf) + if (aconf == NULL) { sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ADMIN, "Lost connect{} block for %s", get_client_name(client_p, HIDE_IP)); sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_OPER, "Lost connect{} block for %s", get_client_name(client_p, MASK_IP)); - exit_client(client_p, client_p, &me, "Lost connect{} block"); + + exit_client(client_p, client_p, &me, "Lost connect{} block"); return; } /* Next, send the initial handshake */ @@ -2213,7 +2227,7 @@ serv_connect_callback(int fd, int status, void *data) client_p->host); sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_OPER, "%s went dead during handshake", client_p->name); - exit_client(client_p, client_p, &me, "Went dead during handshake"); + return; } @@ -2238,8 +2252,8 @@ void cryptlink_init(struct Client *client_p, int enc_len; /* get key */ - if ( (!ServerInfo.rsa_private_key) || - (!RSA_check_key(ServerInfo.rsa_private_key)) ) + if ((!ServerInfo.rsa_private_key) || + (!RSA_check_key(ServerInfo.rsa_private_key)) ) { cryptlink_error(client_p, "SERV", "Invalid RSA private key", "Invalid RSA private key"); @@ -2304,10 +2318,6 @@ void cryptlink_init(struct Client *client_p, MyFree(encrypted); MyFree(key_to_send); - /* - * If we've been marked dead because a send failed, just exit - * here now and save everyone the trouble of us ever existing. - */ if (IsDead(client_p)) { cryptlink_error(client_p, "SERV", "Went dead during handshake", @@ -2323,8 +2333,9 @@ void cryptlink_init(struct Client *client_p, } } -void cryptlink_error(struct Client *client_p, char *type, - char *reason, char *client_reason) +void +cryptlink_error(struct Client *client_p, char *type, + char *reason, char *client_reason) { sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ADMIN, "%s: CRYPTLINK %s error - %s", get_client_name(client_p, SHOW_IP), type, reason); @@ -2336,7 +2347,7 @@ void cryptlink_error(struct Client *client_p, char *type, * If client_reason isn't NULL, then exit the client with the message * defined in the call. */ - if (client_reason != NULL) + if ((client_reason != NULL) && (!IsDead(client_p))) { exit_client(client_p, client_p, &me, client_reason); } diff --git a/src/s_stats.c b/src/s_stats.c index 1d76b42..78051da 100644 --- a/src/s_stats.c +++ b/src/s_stats.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: s_stats.c,v 1.4 2002/09/19 05:41:11 fishwaldo Exp $ + * $Id: s_stats.c,v 1.5 2003/01/29 09:28:50 fishwaldo Exp $ */ #include "stdinc.h" @@ -125,10 +125,10 @@ tstats(struct Client *source_p) sendto_one(source_p, ":%s %d %s :Client Server", me.name, RPL_STATSDEBUG, source_p->name); - sendto_one(source_p, ":%s %d %s :connected %lu %lu", + sendto_one(source_p, ":%s %d %s :connected %u %u", me.name, RPL_STATSDEBUG, source_p->name, - dlink_list_length(&lclient_list), - dlink_list_length(&serv_list)); + (unsigned int)dlink_list_length(&lclient_list), + (unsigned int)dlink_list_length(&serv_list)); sendto_one(source_p, ":%s %d %s :bytes sent %d.%uK %d.%uK", me.name, RPL_STATSDEBUG, source_p->name, (int)sp->is_cks, sp->is_cbs, (int)sp->is_sks, sp->is_sbs); diff --git a/src/s_user.c b/src/s_user.c index 2eb16ca..e6ddc21 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.41 2002/11/20 14:13:57 fishwaldo Exp $ + * $Id: s_user.c,v 1.42 2003/01/29 09:28:50 fishwaldo Exp $ */ #include "stdinc.h" @@ -551,7 +551,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); - source_p->flags |= FLAGS_KILLED; + SetKilled(source_p); return exit_client(NULL, source_p, &me, "Ghosted Client"); } @@ -570,7 +570,7 @@ register_remote_user(struct Client *client_p, struct Client *source_p, user->server, target_p->from->name); - source_p->flags |= FLAGS_KILLED; + SetKilled(source_p); return exit_client(source_p, source_p, &me, "USER server wrong direction"); @@ -587,7 +587,7 @@ register_remote_user(struct Client *client_p, struct Client *source_p, sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ALL, "No server %s for user %s[%s@%s] from %s", user->server, source_p->name, source_p->username, source_p->host, source_p->from->name); - source_p->flags |= FLAGS_KILLED; + SetKilled(source_p); return exit_client(source_p, source_p, &me, "Ghosted Client"); } @@ -964,7 +964,7 @@ user_mode(struct Client *client_p, struct Client *source_p, int parc, char *parv /* if the prefix is from a server, and the server isn't ulined ** and the prefix isn't from the clients server, then its a error - */ + */ if (IsServer(source_p) && (target_p->servptr != source_p) && !IsUlined(source_p)) @@ -980,7 +980,9 @@ user_mode(struct Client *client_p, struct Client *source_p, int parc, char *parv { sendto_one(source_p, form_str(ERR_USERSDONTMATCH), me.name, parv[0]); return 0; - } + } + + if (parc < 3) { m = buf; @@ -1077,7 +1079,6 @@ user_mode(struct Client *client_p, struct Client *source_p, int parc, char *parv /* we may not get these, * but they shouldnt be in default */ - case ' ' : case '\n' : case '\r' : @@ -1414,7 +1415,7 @@ oper_up( struct Client *source_p, struct ConfItem *aconf ) sendto_one(source_p, ":%s NOTICE %s :*** Oper privs are %s", me.name, source_p->name, operprivs); SendMessageFile(source_p, &ConfigFileEntry.opermotd); - + /* autojoin them to a channel if its defined */ flags = 0; if (strlen(ConfigFileEntry.operautojoin) > 0) { diff --git a/src/send.c b/src/send.c index f888505..3c7f09a 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.11 2002/11/04 08:50:46 fishwaldo Exp $ + * $Id: send.c,v 1.12 2003/01/29 09:28:50 fishwaldo Exp $ */ #include "stdinc.h" @@ -61,7 +61,6 @@ 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); @@ -175,7 +174,7 @@ _send_linebuf(struct Client *to, buf_head_t *linebuf) get_sendq(to)); if (IsClient(to)) to->flags |= FLAGS_SENDQEX; - dead_link(to); + dead_link_on_write(to, 0); return -1; } else @@ -222,23 +221,23 @@ send_linebuf_remote(struct Client *to, struct Client *from, if (IsServer(from)) { sendto_realops_flags(FLAGS_ALL, L_ALL, - "Send message to %s[%s] dropped from %s(Fake Dir)", + "Send message to %s [%s] dropped from %s(Fake Dir)", to->name, to->from->name, from->name); return; } sendto_realops_flags(FLAGS_ALL, L_ALL, - "Ghosted: %s[%s@%s] from %s[%s@%s] (%s)", + "Ghosted: %s [%s@%s] from %s [%s@%s] (%s)", to->name, to->username, to->host, from->name, from->username, from->host, to->from->name); sendto_server(NULL, to, NULL, NOCAPS, NOCAPS, NOFLAGS, - ":%s KILL %s :%s (%s[%s@%s] Ghosted %s)", + ":%s KILL %s :%s (%s [%s@%s] Ghosted %s)", me.name, to->name, me.name, to->name, to->username, to->vhost, to->from->name); - to->flags |= FLAGS_KILLED; + SetKilled(to); if (IsPerson(from)) sendto_one(from, form_str(ERR_GHOSTEDCLIENT), @@ -331,7 +330,7 @@ send_queued_write(int fd, void *data) } else if (retlen <= 0) { - dead_link(to); + dead_link_on_write(to, errno); return; } } @@ -380,14 +379,14 @@ send_queued_slink_write(int fd, void *data) /* If we have a fatal error */ if (!ignoreErrno(errno)) { - dead_link(to); + dead_link_on_write(to, errno); return; } } else if (retlen == 0) { /* 0 bytes is an EOF .. */ - dead_link(to); + dead_link_on_write(to, 0); return; } else @@ -1176,7 +1175,6 @@ sendto_anywhere(struct Client *to, struct Client *from, linebuf_putmsg(&linebuf, pattern, &args, ":%s ", ID(from)); else linebuf_putmsg(&linebuf, pattern, &args, ":%s ", from->name); - } va_end(args); @@ -1346,7 +1344,8 @@ kill_client(struct Client *client_p, va_start(args, pattern); - if(HasID(diedie) && IsCapable(client_p, CAP_UID)) + /* XXX perhaps IsCapable should test for localClient itself ? -db */ + if(HasID(diedie) && client_p->localClient && IsCapable(client_p, CAP_UID)) linebuf_putmsg(&linebuf, pattern, &args, ":%s KILL %s :", me.name, ID(diedie)); else @@ -1407,7 +1406,8 @@ kill_client_ll_serv_butone(struct Client *one, struct Client *source_p, if (one && (client_p == one->from)) continue; - if (IsCapable(client_p,CAP_LL) && ServerInfo.hub) + /* XXX perhaps IsCapable should test for localClient itself ? -db */ + if (client_p->localClient && IsCapable(client_p,CAP_LL) && ServerInfo.hub) { if((source_p->lazyLinkClientExists & client_p->localClient->serverMask) != 0) @@ -1420,7 +1420,8 @@ kill_client_ll_serv_butone(struct Client *one, struct Client *source_p, } else { - if (have_uid && IsCapable(client_p, CAP_UID)) + /* XXX perhaps IsCapable should test for localClient itself ? -db */ + if (have_uid && client_p->localClient && IsCapable(client_p, CAP_UID)) send_linebuf(client_p, &linebuf_uid); else send_linebuf(client_p, &linebuf_nick); diff --git a/src/ssl.c b/src/ssl.c index ea467b1..3a36bd4 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: ssl.c,v 1.3 2003/01/27 04:20:36 fishwaldo Exp $ + * $Id: ssl.c,v 1.4 2003/01/29 09:28:50 fishwaldo Exp $ */ #include "stdinc.h" @@ -179,12 +179,14 @@ SSL_smart_shutdown (struct Client *client_p) int rc; rc = 0; + SSL_set_shutdown(client_p->localClient->ssl, SSL_RECEIVED_SHUTDOWN); for (i = 0; i < 4; i++) { if ((rc = SSL_shutdown (client_p->localClient->ssl))) break; } - + SSL_free(client_p->localClient->ssl); + client_p->localClient->ssl = NULL; return rc; }