HyrbidTeam RC6, RC7 and RC8 Patches. Wonder whats broken now :(

This commit is contained in:
fishwaldo 2003-01-29 09:28:50 +00:00
parent 69acba7822
commit 9eab176837
46 changed files with 1018 additions and 777 deletions

View file

@ -11,6 +11,7 @@ Symbols are:
(F) - Added Z umode to identify SSL clients, and added whois reply for SSL clients (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) - Can invite non-Z clients into +S channels
(F) - SSL conf file support and restart of neoircd coding :) (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 * 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 (S) - Fixed up event.c for a possible serious bug reported by Dianora from hybrid team

3
TODO
View file

@ -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 /stats g should report when a G line will expire
SSL client support modes and channel related stuff SSL client support modes and channel related stuff

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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 #ifndef INCLUDED_channel_h
@ -65,7 +65,7 @@ struct Channel
dlink_list voiced; dlink_list voiced;
dlink_list peons; /* non ops, just members */ dlink_list peons; /* non ops, just members */
dlink_list deopped; /* users deopped on sjoin */ dlink_list deopped; /* users deopped on sjoin */
dlink_list locchanadmins; /* local versions of the above */ dlink_list locchanadmins; /* local versions of the above */
dlink_list locchanops; /* local versions of the above */ dlink_list locchanops; /* local versions of the above */
dlink_list lochalfops; dlink_list lochalfops;

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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 #ifndef INCLUDED_client_h
@ -40,9 +40,6 @@
#include "linebuf.h" #include "linebuf.h"
#include "channel.h" #include "channel.h"
#include "res.h" #include "res.h"
#ifdef IPV6 #ifdef IPV6
#define HOSTIPLEN 53 /* sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255.ipv6") */ #define HOSTIPLEN 53 /* sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255.ipv6") */
#else #else
@ -189,7 +186,7 @@ struct Client
* client->vhost is the vitual host that users get by default with umode +x * 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 * if you want to change the presentation of the users host, do it here, and leave
* client->host alone * client->host alone
*/ */
char vhost[HOSTLEN +1]; char vhost[HOSTLEN +1];
/* /*
* client->swhois stores a swhois structure * client->swhois stores a swhois structure
@ -288,7 +285,6 @@ struct LocalUser
char out_key[CIPHERKEYLEN]; char out_key[CIPHERKEYLEN];
#endif #endif
int fd; /* >= 0, for local clients */ int fd; /* >= 0, for local clients */
#ifndef HAVE_SOCKETPAIR #ifndef HAVE_SOCKETPAIR
int fd_r; /* fd for reading */ int fd_r; /* fd for reading */
@ -363,7 +359,7 @@ struct LocalUser
#define SetServer(x) {(x)->status = STAT_SERVER; \ #define SetServer(x) {(x)->status = STAT_SERVER; \
(x)->handler = SERVER_HANDLER; } (x)->handler = SERVER_HANDLER; }
#define SetClient(x) {(x)->status = STAT_CLIENT; \ #define SetClient(x) {(x)->status = STAT_CLIENT; \
(x)->handler = IsOper((x)) ? \ (x)->handler = IsOper((x)) ? \
OPER_HANDLER : CLIENT_HANDLER; } OPER_HANDLER : CLIENT_HANDLER; }
@ -492,6 +488,9 @@ struct LocalUser
#define SetAccess(x) ((x)->flags |= FLAGS_CHKACCESS) #define SetAccess(x) ((x)->flags |= FLAGS_CHKACCESS)
#define IsClosing(x) ((x)->flags & FLAGS_CLOSING) #define IsClosing(x) ((x)->flags & FLAGS_CLOSING)
#define SetClosing(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 ClearAccess(x) ((x)->flags &= ~FLAGS_CHKACCESS)
#define IsCryptIn(x) ((x)->flags & FLAGS_CRYPTIN) #define IsCryptIn(x) ((x)->flags & FLAGS_CRYPTIN)
#define SetCryptIn(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 IsSSL(x) ((x)->flags & FLAGS_SSL)
#define SetSSLOK(x) ((x)->flags2 |= FLAGS2_SSLOK) #define SetSSLOK(x) ((x)->flags2 |= FLAGS2_SSLOK)
#define IsSSLOK(x) ((x)->flags2 & FLAGS2_SSLOK) #define IsSSLOK(x) ((x)->flags2 & FLAGS2_SSLOK)
#define IsDefunct(x) ((x)->flags & (FLAGS_DEADSOCKET|FLAGS_CLOSING))
/* oper flags */ /* oper flags */
#define MyOper(x) (MyConnect(x) && IsOper(x)) #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); char *nick);
extern int change_local_nick(struct Client *client_p, struct Client *source_p, extern int change_local_nick(struct Client *client_p, struct Client *source_p,
char *nick); char *nick);
extern void dead_link(struct Client *client_p); extern void dead_link_on_write(struct Client *client_p, int ierrno);
extern void exit_aborted_clients(void); extern void dead_link_on_read(struct Client *client_p, int error);
extern void make_virthost(char *curr, char *host, char *new); extern void make_virthost(char *curr, char *host, char *new);
#endif /* INCLUDED_client_h */ #endif /* INCLUDED_client_h */

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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 #ifndef INCLUDED_ircd_h
@ -78,9 +78,11 @@ extern char* infotext[];
extern char* serno; extern char* serno;
extern char* ircd_version; extern char* ircd_version;
extern const char* logFileName; extern const char* logFileName;
extern const char* pidFileName;
extern const char serveropts[]; extern const char serveropts[];
extern int cold_start; extern int cold_start;
extern int dorehash; extern int dorehash;
extern int doremotd;
extern struct Client me; extern struct Client me;
extern struct Client* GlobalClientList; extern struct Client* GlobalClientList;
extern struct Client* local[]; extern struct Client* local[];

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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 #ifndef INCLUDED_modules_h
@ -70,7 +70,7 @@ extern void _modinit(void);
extern void _moddeinit(void); extern void _moddeinit(void);
extern int unload_one_module (char *, int); 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 load_a_module (char *, int, int);
extern int findmodule_byname (char *); extern int findmodule_byname (char *);
extern char* irc_basename(char *); extern char* irc_basename(char *);

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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 #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_non_blocking(int);
extern int set_sock_buffers(int, int); extern int set_sock_buffers(int, int);
extern void error_exit_client(struct Client*, int);
extern int get_sockerr(int); extern int get_sockerr(int);
extern int ignoreErrno(int ierrno); extern int ignoreErrno(int ierrno);

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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 #ifndef INCLUDED_s_conf_h
@ -88,7 +88,6 @@ struct ConfItem
#define CONF_SERVER 0x0004 #define CONF_SERVER 0x0004
#define CONF_OPERATOR 0x0010 #define CONF_OPERATOR 0x0010
#define CONF_KILL 0x0040 #define CONF_KILL 0x0040
#define CONF_USERVER 0x0080
#define CONF_CLASS 0x0400 #define CONF_CLASS 0x0400
#define CONF_LEAF 0x0800 #define CONF_LEAF 0x0800
@ -250,7 +249,7 @@ struct config_channel_entry
int no_create_on_split; int no_create_on_split;
int no_join_on_split; int no_join_on_split;
int persist_time; int persist_time;
int oper_pass_resv; int oper_pass_resv;
int quiet_on_ban; int quiet_on_ban;
int default_split_server_count; int default_split_server_count;
int default_split_user_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_x_conf(struct ConfItem *);
extern void conf_add_fields(struct ConfItem*, char*, char *, char*, char *,char *); extern void conf_add_fields(struct ConfItem*, char*, char *, char*, char *,char *);
extern void conf_add_conf(struct ConfItem *); extern void conf_add_conf(struct ConfItem *);
extern void flush_expired_ips(void *);
/* XXX consider moving these into kdparse.h */ /* XXX consider moving these into kdparse.h */
extern void parse_k_file(FBFILE *fb); extern void parse_k_file(FBFILE *fb);

View file

@ -110,6 +110,9 @@
/* Define if you have the EVP_rc5_32_12_16_cfb function. */ /* Define if you have the EVP_rc5_32_12_16_cfb function. */
#undef HAVE_EVP_RC5_32_12_16_CFB #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. */ /* Define if you have the dlopen function. */
#undef HAVE_DLOPEN #undef HAVE_DLOPEN

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -57,7 +57,7 @@ _moddeinit(void)
mod_del_cmd(&die_msgtab); mod_del_cmd(&die_msgtab);
} }
const char *_version = "$Revision: 1.2 $"; const char *_version = "$Revision: 1.3 $";
#endif #endif
/* /*
* mo_die - DIE command handler * 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 * this is a normal exit, tell the os it's ok
*/ */
unlink(pidFileName);
exit(0); exit(0);
/* NOT REACHED */ /* NOT REACHED */
} }

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #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, struct Client *source_p, struct Client *target_p,
char *text); char *text);
static void handle_opers(int p_or_n, char *command, static void handle_special(int p_or_n, char *command,
struct Client *client_p, struct Client *client_p,
struct Client *source_p, char *nick, char *text); struct Client *source_p, char *nick, char *text);
struct Message privmsg_msgtab = { struct Message privmsg_msgtab = {
"PRIVMSG", 0, 0, 1, 0, MFLG_SLOW | MFLG_UNREG, 0L, "PRIVMSG", 0, 0, 1, 0, MFLG_SLOW | MFLG_UNREG, 0L,
@ -122,7 +122,7 @@ _moddeinit(void)
mod_del_cmd(&notice_msgtab); mod_del_cmd(&notice_msgtab);
} }
const char *_version = "$Revision: 1.13 $"; const char *_version = "$Revision: 1.14 $";
#endif #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, '@'))) 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 else
{ {
@ -782,30 +782,123 @@ flood_attack_channel(int p_or_n, struct Client *source_p,
/* /*
* handle_opers * handle_special
* *
* inputs - server pointer * inputs - server pointer
* - client pointer * - client pointer
* - nick stuff to grok for opers * - nick stuff to grok for opers
* - text to send if grok * - text to send if grok
* output - none * 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." * i.e. "/msg #some.host."
* However, syntax has been changed. * However, syntax has been changed.
* previous syntax "/msg #some.host.mask" * previous syntax "/msg #some.host.mask"
* now becomes "/msg $#some.host.mask" * now becomes "/msg $#some.host.mask"
* previous syntax of: "/msg $some.server.mask" remains * previous syntax of: "/msg $some.server.mask" remains
* This disambiguates the syntax. * 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 static void
handle_opers(int p_or_n, char *command, struct Client *client_p, handle_special(int p_or_n, char *command, struct Client *client_p,
struct Client *source_p, char *nick, char *text) struct Client *source_p, char *nick, char *text)
{ {
struct Client *target_p; struct Client *target_p;
char *host; char *host;
char *server; char *server;
char *s;
int count; 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 * the following two cases allow masks in NOTICEs
* (for OPERs only) * (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); me.name, source_p->name, command, nick, nick);
return; return;
} }
/* we can send to * now. */
/* we allow it to send messages to anybody */ #if 0
#if 0
if ((s = strrchr(nick, '.')) == NULL) if ((s = strrchr(nick, '.')) == NULL)
{ {
sendto_one(source_p, form_str(ERR_NOTOPLEVEL), 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; 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);
} }
/* /*

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -61,7 +61,7 @@ _moddeinit(void)
{ {
mod_del_cmd(&part_msgtab); mod_del_cmd(&part_msgtab);
} }
const char *_version = "$Revision: 1.4 $"; const char *_version = "$Revision: 1.5 $";
#endif #endif
static void part_one_client(struct Client *client_p, 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, ":%s PART %s :%s", ID(source_p), chptr->chname,
reason); reason);
sendto_server(client_p, NULL, chptr, NOCAPS, CAP_UID, NOFLAGS, 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); reason);
sendto_channel_local(ALL_MEMBERS, sendto_channel_local(ALL_MEMBERS,
chptr, ":%s!%s@%s PART %s :%s", chptr, ":%s!%s@%s PART %s :%s",

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -67,7 +67,7 @@ _moddeinit(void)
{ {
mod_del_cmd(&server_msgtab); mod_del_cmd(&server_msgtab);
} }
const char *_version = "$Revision: 1.11 $"; const char *_version = "$Revision: 1.12 $";
#endif #endif
int bogus_host(char *host); 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.", "Non-Hub link %s introduced %s.",
get_client_name(client_p, MASK_IP), name); 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; return;
} }

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -55,10 +55,11 @@ _moddeinit(void)
return; return;
} }
const char *_version = "$Revision: 1.6 $"; const char *_version = "$Revision: 1.7 $";
#endif #endif
#else #else
static void failed_challenge_notice(struct Client *, char *, char *);
static void m_challenge(struct Client*, struct Client*, int, char**); static void m_challenge(struct Client*, struct Client*, int, char**);
void binary_to_hex( unsigned char * bin, char * hex, int length ); void binary_to_hex( unsigned char * bin, char * hex, int length );
@ -80,7 +81,7 @@ _moddeinit(void)
mod_del_cmd(&challenge_msgtab); mod_del_cmd(&challenge_msgtab);
} }
const char *_version = "$Revision: 1.6 $"; const char *_version = "$Revision: 1.7 $";
#endif #endif
/* /*
* m_challenge - generate RSA challenge for wouldbe oper * 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, sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name,
source_p->name); source_p->name);
failed_challenge_notice(source_p, source_p->user->auth_oper, "challenge failed");
return; return;
} }
@ -196,4 +198,23 @@ static void m_challenge( struct Client *client_p, struct Client *source_p,
return; 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 */ #endif /* HAVE_LIBCRYPTO */

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -67,7 +67,7 @@ _moddeinit(void)
mod_del_cmd(&uhelp_msgtab); mod_del_cmd(&uhelp_msgtab);
} }
const char *_version = "$Revision: 1.4 $"; const char *_version = "$Revision: 1.5 $";
#endif #endif
/* /*
* m_help - HELP message handler * 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); 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); sendto_one(source_p, form_str(RPL_ENDOFHELP), me.name, nick, topic);
return; return;
} }

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -40,12 +40,14 @@
#include "msg.h" #include "msg.h"
#include "parse.h" #include "parse.h"
#include "modules.h" #include "modules.h"
#include "packet.h"
static void m_invite(struct Client *, struct Client *, int, char **); static void m_invite(struct Client *, struct Client *, int, char **);
static void ms_invite(struct Client *, struct Client *, int, char **);
struct Message invite_msgtab = { struct Message invite_msgtab = {
"INVITE", 0, 0, 3, 0, MFLG_SLOW, 0, "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 #ifndef STATIC_MODULES
@ -61,7 +63,7 @@ _moddeinit(void)
mod_del_cmd(&invite_msgtab); mod_del_cmd(&invite_msgtab);
} }
const char *_version = "$Revision: 1.7 $"; const char *_version = "$Revision: 1.8 $";
#endif #endif
/* /*
@ -85,10 +87,12 @@ m_invite(struct Client *client_p,
return; return;
} }
/* A little sanity test here */ if(!IsClient(source_p))
if (source_p->user == NULL)
return; return;
if(MyClient(source_p) && !IsFloodDone(source_p))
flood_endgrace(source_p);
if ((target_p = find_person(parv[1])) == NULL) if ((target_p = find_person(parv[1])) == NULL)
{ {
sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, parv[0], parv[1]); 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); burst_channel(target_p->from, vchan);
} }
if (MyConnect(target_p)) if (MyConnect(target_p) && chop)
{ add_invite(vchan, 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 the channel is +pi, broadcast everywhere thats CAP_PARA, send to sendto_anywhere(target_p, source_p, "INVITE %s :%s",
* target if target isnt CAP_PARA capable, else just send to target 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, sendto_server(source_p->from, source_p, NULL, NOCAPS, NOCAPS, NOFLAGS,
ONLY_CHANOPS_HALFOPS, CAP_PARA, NOCAPS, ":%s INVITE %s %s :%s",
chptr, ":%s INVITE %s :%s", parv[0], me.name, source_p->name, target_p->name, vchan->chname);
target_p->name, vchan->chname);
/* XXX This possibly should be a numeric -db */
if(!MyConnect(target_p) && (target_p->from != client_p) && sendto_channel_local(ONLY_CHANOPS_HALFOPS, vchan,
!IsCapable(target_p->from, CAP_PARA)) ":%s NOTICE %s :%s is inviting %s to %s.",
sendto_one(target_p->from, ":%s INVITE %s :%s", parv[0], me.name, chptr->chname, source_p->name,
target_p->name, vchan->chname); 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);
}
}
}

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -46,6 +46,7 @@
static struct ConfItem *find_password_aconf(char *name, struct Client *source_p); static struct ConfItem *find_password_aconf(char *name, struct Client *source_p);
static int match_oper_password(char *password, struct ConfItem *aconf); 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 ); int oper_up( struct Client *source_p, struct ConfItem *aconf );
#ifdef CRYPT_OPER_PASSWORD #ifdef CRYPT_OPER_PASSWORD
extern char *crypt(); extern char *crypt();
@ -74,7 +75,7 @@ _moddeinit(void)
mod_del_cmd(&oper_msgtab); mod_del_cmd(&oper_msgtab);
} }
const char *_version = "$Revision: 1.6 $"; const char *_version = "$Revision: 1.7 $";
#endif #endif
/* /*
@ -110,13 +111,8 @@ m_oper(struct Client *client_p, struct Client *source_p,
if((aconf = find_password_aconf(name,source_p)) == NULL) if((aconf = find_password_aconf(name,source_p)) == NULL)
{ {
sendto_one(source_p, form_str(ERR_NOOPERHOST), me.name, source_p->name); sendto_one(source_p, form_str(ERR_NOOPERHOST), me.name, source_p->name);
if (ConfigFileEntry.failed_oper_notice) failed_oper_notice(source_p, name, find_conf_by_name(name, CONF_OPERATOR) ?
{ "host mismatch" : "no oper {} block");
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);
}
log_failed_oper(source_p, name); log_failed_oper(source_p, name);
return; return;
} }
@ -137,11 +133,8 @@ m_oper(struct Client *client_p, struct Client *source_p,
if(attach_conf(source_p, aconf) != 0) if(attach_conf(source_p, aconf) != 0)
{ {
sendto_one(source_p,":%s NOTICE %s :Can't attach conf!", sendto_one(source_p,":%s NOTICE %s :Can't attach conf!",
me.name,source_p->name); me.name, source_p->name);
sendto_realops_flags(FLAGS_ALL, L_ALL, failed_oper_notice(source_p, name, "can't attach conf!");
"Failed OPER attempt by %s (%s@%s) can't attach conf!",
source_p->name, source_p->username,
source_p->host);
/* /*
* 20001216: * 20001216:
* Reattach old iline * Reattach old iline
@ -161,15 +154,9 @@ m_oper(struct Client *client_p, struct Client *source_p,
else else
{ {
sendto_one(source_p,form_str(ERR_PASSWDMISMATCH),me.name, parv[0]); sendto_one(source_p,form_str(ERR_PASSWDMISMATCH),me.name, parv[0]);
if (ConfigFileEntry.failed_oper_notice) failed_oper_notice(source_p, name, "password mismatch");
{
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);
} }
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 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) SetOper(source_p);
source_p->handler = OPER_HANDLER;
source_p->umodes |= FLAGS_OPER;
Count.oper++; Count.oper++;
sendto_server(client_p, source_p, NULL, NOCAPS, NOCAPS, NOFLAGS, sendto_server(client_p, source_p, NULL, NOCAPS, NOCAPS, NOFLAGS,
":%s MODE %s :+o", parv[0], parv[0]); ":%s MODE %s :+o", parv[0], parv[0]);
@ -276,3 +260,23 @@ match_oper_password(char *password, struct ConfItem *aconf)
else else
return (NO); 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);
}

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -57,15 +57,18 @@ void
_modinit(void) _modinit(void)
{ {
mod_add_cmd(&post_msgtab); mod_add_cmd(&post_msgtab);
} mod_add_cmd(&get_msgtab);
mod_add_cmd(&put_msgtab);}
void void
_moddeinit(void) _moddeinit(void)
{ {
mod_del_cmd(&post_msgtab); 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 #endif
/* /*
** mr_dumb_proxy ** mr_dumb_proxy

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -61,7 +61,7 @@ _moddeinit(void)
{ {
mod_del_cmd(&whowas_msgtab); mod_del_cmd(&whowas_msgtab);
} }
const char *_version = "$Revision: 1.4 $"; const char *_version = "$Revision: 1.5 $";
#endif #endif
static int whowas_do(struct Client *client_p, struct Client *source_p, static int whowas_do(struct Client *client_p, struct Client *source_p,
int parc, char *parv[]); int parc, char *parv[]);
@ -79,7 +79,7 @@ static void m_whowas(struct Client *client_p,
{ {
static time_t last_used=0L; static time_t last_used=0L;
if (parc < 2) if (parc < 2 || parv[1][0] == '\0')
{ {
sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN), sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN),
me.name, parv[0]); me.name, parv[0]);
@ -104,7 +104,7 @@ static void mo_whowas(struct Client *client_p,
int parc, int parc,
char *parv[]) char *parv[])
{ {
if (parc < 2) if (parc < 2 || parv[1][0] == '\0')
{ {
sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN), sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN),
me.name, parv[0]); me.name, parv[0]);
@ -132,7 +132,7 @@ static int whowas_do(struct Client *client_p, struct Client *source_p,
max = atoi(parv[2]); max = atoi(parv[2]);
if (parc > 3) if (parc > 3)
if (hunt_server(client_p,source_p,":%s WHOWAS %s %s :%s", 3,parc,parv)) if (hunt_server(client_p,source_p,":%s WHOWAS %s %s :%s", 3,parc,parv))
return 0; return(0);
nick = parv[1]; nick = parv[1];
while (*nick == ',') while (*nick == ',')
@ -140,7 +140,7 @@ static int whowas_do(struct Client *client_p, struct Client *source_p,
if((p = strchr(nick,',')) != NULL) if((p = strchr(nick,',')) != NULL)
*p = '\0'; *p = '\0';
if (!*nick) if (!*nick)
return 0; return(0);
temp = WHOWASHASH[hash_whowas_name(nick)]; temp = WHOWASHASH[hash_whowas_name(nick)];
found = 0; found = 0;

View file

@ -25,7 +25,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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); assert(0 == 1);
outofmemory(); outofmemory();
return NULL; return(NULL);
} }
@ -551,10 +551,7 @@ BlockHeapDestroy(BlockHeap * bh)
free(walker); free(walker);
} }
if(walker != NULL) free(bh);
{
free(bh);
}
return(0); return(0);
} }
#endif #endif

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -84,6 +84,7 @@ void init_channels(void)
channel_heap = BlockHeapCreate(sizeof(struct Channel), CHANNEL_HEAP_SIZE); channel_heap = BlockHeapCreate(sizeof(struct Channel), CHANNEL_HEAP_SIZE);
ban_heap = BlockHeapCreate(sizeof(struct Ban), BAN_HEAP_SIZE); ban_heap = BlockHeapCreate(sizeof(struct Ban), BAN_HEAP_SIZE);
topic_heap = BlockHeapCreate(TOPICLEN+1 + USERHOST_REPLYLEN, TOPIC_HEAP_SIZE); topic_heap = BlockHeapCreate(TOPICLEN+1 + USERHOST_REPLYLEN, TOPIC_HEAP_SIZE);
eventAddIsh("channelheap_garbage_collect", channelheap_garbage_collect, eventAddIsh("channelheap_garbage_collect", channelheap_garbage_collect,
NULL, 45); NULL, 45);
} }
@ -224,20 +225,22 @@ remove_user_from_channel(struct Channel *chptr, struct Client *who)
free_dlink_node(ptr); free_dlink_node(ptr);
} }
chptr->users_last = CurrentTime; 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); if (ptr->data == chptr)
free_dlink_node(ptr); {
break; dlinkDelete(ptr, &who->user->channel);
free_dlink_node(ptr);
who->user->joined--;
break;
}
} }
} }
who->user->joined--;
if (MyClient(who)) 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->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->chanadmins, "!");
send_members(client_p, modebuf, parabuf, chptr, &chptr->voiced, "+"); send_members(client_p, modebuf, parabuf, chptr, &chptr->voiced, "+");
send_members(client_p, modebuf, parabuf, chptr, &chptr->peons, ""); 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->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 * sub1_from_channel
** block, if channel became empty). *
*/ * 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 static int
sub1_from_channel(struct Channel *chptr) sub1_from_channel(struct Channel *chptr)
{ {
if (--chptr->users <= 0) 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 chptr->users = 0; /* if chptr->users < 0, make sure it sticks at 0
* It should never happen but... * It should never happen but...
*/ */
@ -538,9 +548,8 @@ destroy_channel(struct Channel *chptr)
* any reference it has to this channel. * any reference it has to this channel.
* Finally, free now unused dlink's * Finally, free now unused dlink's
* *
* This test allows us to use this code both for LazyLinks and * For LazyLinks, note that the channel need not be empty, it only
* persistent channels. In the case of a LL the channel need not * has to be empty of local users.
* be empty, it only has to be empty of local users.
*/ */
delete_members(chptr, &chptr->chanadmins); delete_members(chptr, &chptr->chanadmins);
delete_members(chptr, &chptr->chanops); delete_members(chptr, &chptr->chanops);
@ -615,20 +624,21 @@ delete_members(struct Channel *chptr, dlink_list * list)
next_ptr = ptr->next; next_ptr = ptr->next;
who = (struct Client *)ptr->data; who = (struct Client *)ptr->data;
/* remove reference to chptr from who */ if (who->user != NULL)
for (ptr_ch = who->user->channel.head; ptr_ch; ptr_ch = next_ptr_ch)
{ {
next_ptr_ch = ptr_ch->next; /* remove reference to chptr from who */
DLINK_FOREACH_SAFE (ptr_ch, next_ptr_ch, who->user->channel.head)
if (ptr_ch->data == chptr)
{ {
dlinkDelete(ptr_ch, &who->user->channel); if (ptr_ch->data == chptr)
free_dlink_node(ptr_ch); {
break; dlinkDelete(ptr_ch, &who->user->channel);
free_dlink_node(ptr_ch);
who->user->joined--;
break;
}
} }
} }
who->user->joined--;
/* remove reference to who from chptr */ /* 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; actualBan = NULL;
} }
if (actualBan != NULL) if ((actualBan != NULL))
{ {
DLINK_FOREACH(except, chptr->exceptlist.head) DLINK_FOREACH(except, chptr->exceptlist.head)
{ {
actualExcept = except->data; 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; 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_host[NICKLEN + USERLEN + HOSTLEN + 6];
char src_iphost[NICKLEN + USERLEN + HOSTLEN + 6]; char src_iphost[NICKLEN + USERLEN + HOSTLEN + 6];
char src_vhost[NICKLEN + USERLEN + HOSTLEN +6]; char src_vhost[NICKLEN + USERLEN + HOSTLEN +6];
assert(source_p->localClient != NULL); assert(source_p->localClient != NULL);
ircsprintf(src_host, ircsprintf(src_host,
@ -980,7 +993,7 @@ can_join(struct Client *source_p, struct Channel *chptr, char *key)
} }
if (ptr == NULL) if (ptr == NULL)
return (ERR_INVITEONLYCHAN); return (ERR_INVITEONLYCHAN);
} }
} }
if ((chptr->mode.mode & MODE_SSLONLY) && !IsSSL(source_p)) { if ((chptr->mode.mode & MODE_SSLONLY) && !IsSSL(source_p)) {
for (lp = source_p->user->invited.head; lp; lp = lp->next) { 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 * 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 * - pointer to client struct being checked
* output - yes if anyop no if not * output - yes if anyop no if not
* side effects - * side effects -

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -127,10 +127,14 @@ static void update_channel_info(struct Channel *);
* some buffers for rebuilding channel/nick lists with ,'s * 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 char mask_buf[BUFSIZE];
static int mask_pos; 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 struct ChModeChange mode_changes[BUFSIZE];
static int mode_count; static int mode_count;
@ -218,7 +222,7 @@ add_id(struct Client *client_p, struct Channel *chptr, char *banid, int type)
{ {
actualBan = ban->data; actualBan = ban->data;
if (match(actualBan->banstr, banid)) if (match(actualBan->banstr, banid))
return 0; return(0);
} }
ban = make_dlink_node(); 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); dlinkAdd(actualBan, ban, list);
chptr->num_mask++; chptr->num_mask++;
return 1; return(1);
} }
/* /*
@ -431,7 +435,7 @@ change_channel_membership(struct Channel *chptr,
free_dlink_node(ptr); free_dlink_node(ptr);
} }
return ok; return (ok);
} }
/* /*
@ -752,6 +756,10 @@ chm_hideops(struct Client *client_p, struct Client *source_p,
return; return;
} }
if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
return;
if (dir == MODE_ADD && !(chptr->mode.mode & MODE_HIDEOPS)) if (dir == MODE_ADD && !(chptr->mode.mode & MODE_HIDEOPS))
{ {
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 else
mask = pretty_mask(raw_mask); 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 we're adding a NEW id */
if (dir == MODE_ADD) if (dir == MODE_ADD)
{ {
@ -849,6 +853,9 @@ chm_ban(struct Client *client_p, struct Client *source_p,
} }
else if (dir == MODE_DEL) else if (dir == MODE_DEL)
{ {
/* XXX grrrrrrr */
#ifdef NO_BAN_COOKIE
if (del_id(chptr, mask, CHFL_BAN) == 0) if (del_id(chptr, mask, CHFL_BAN) == 0)
{ {
/* mask isn't a valid ban, check raw_mask */ /* 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; 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].letter = c;
mode_changes[mode_count].dir = MODE_DEL; mode_changes[mode_count].dir = MODE_DEL;
mode_changes[mode_count].mems = ALL_MEMBERS; mode_changes[mode_count].mems = ALL_MEMBERS;
@ -914,10 +929,6 @@ chm_except(struct Client *client_p, struct Client *source_p,
else else
mask = pretty_mask(raw_mask); 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 we're adding a NEW id */
if (dir == MODE_ADD) 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].letter = c;
mode_changes[mode_count].dir = MODE_ADD; 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].id = NULL;
mode_changes[mode_count++].arg = mask; mode_changes[mode_count++].arg = mask;
} }
@ -997,10 +1008,6 @@ chm_invex(struct Client *client_p, struct Client *source_p,
else else
mask = pretty_mask(raw_mask); 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(dir == MODE_ADD)
{ {
if((add_id(source_p, chptr, mask, CHFL_INVEX) == 0) && MyClient(source_p)) 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].letter = c;
mode_changes[mode_count].dir = MODE_ADD; 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].id = NULL;
mode_changes[mode_count++].arg = mask; 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].letter = c;
mode_changes[mode_count].dir = MODE_DEL; 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].id = NULL;
mode_changes[mode_count++].arg = mask; 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); mode_get_status(chptr, targ_p, &t_op, &t_hop, &t_voice, &t_admin, 1);
if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS)) if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
return; return;
@ -1618,7 +1625,7 @@ chm_key(struct Client *client_p, struct Client *source_p,
fix_key_old(key); fix_key_old(key);
assert(key[0] != ' '); 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 */ /* if somebody does MODE #channel +kk a b, accept latter --fl */
for (i = 0; i < mode_count; i++) for (i = 0; i < mode_count; i++)
@ -1728,7 +1735,7 @@ static struct ChannelMode ModeTable[255] =
* MODE_PEON for peon level access. * MODE_PEON for peon level access.
* Side-effects: None. * Side-effects: None.
*/ */
static int static int
get_channel_access(struct Client *source_p, struct Channel *chptr) get_channel_access(struct Client *source_p, struct Channel *chptr)
{ {
/* Let hacked servers in for now... */ /* 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)) if (is_chan_admin(chptr, source_p))
return CHACCESS_ADMIN; return CHACCESS_ADMIN;
if (is_chan_op(chptr, source_p)) if (is_chan_op(chptr, source_p))
return CHACCESS_CHANOP; return CHACCESS_CHANOP;
@ -1771,32 +1778,35 @@ static void
send_cap_mode_changes(struct Client *client_p, struct Client *source_p, send_cap_mode_changes(struct Client *client_p, struct Client *source_p,
struct Channel *chptr) struct Channel *chptr)
{ {
int i, mbl, pbl, nc, mc; int i, mbl, pbl, arglen, nc, mc;
int len;
char *arg; char *arg;
char *parptr;
int dir; int dir;
int cap, nocap; int cap, nocap;
cap = 0; cap = 0;
nocap = 0; nocap = 0;
mc = 0; mc = 0;
nc = 0; nc = 0;
pbl = 0; pbl = 0;
parabuf[0] = 0;
dir = MODE_QUERY; dir = MODE_QUERY;
parabuf[0] = '\0';
parptr = parabuf;
if ((cap & CAP_UID) && source_p->user && if ((cap & CAP_UID) && source_p->user &&
(source_p->user->id[0] == '.')) (source_p->user->id[0] == '.'))
mbl = ircsprintf(modebuf, ":%s MODE %s ", source_p->user->id, mbl = ircsprintf(modebuf, ":%s MODE %s ", source_p->user->id,
chptr->chname); chptr->chname);
else else
mbl = ircsprintf(modebuf, ":%s MODE %s ", source_p->name, mbl = ircsprintf(modebuf, ":%s MODE %s ", source_p->name,
chptr->chname); chptr->chname);
/* loop the list of - modes we have */
for (i = 0; i < mode_count; i++) for (i = 0; i < mode_count; i++)
{ {
/* if they dont support the cap we need, or they do support a cap they /* 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 * cant have, then dont add it to the modebuf.. that way they wont see
* the mode * the mode
@ -1808,7 +1818,7 @@ send_cap_mode_changes(struct Client *client_p, struct Client *source_p,
arg = ""; arg = "";
if ((cap & CAP_UID) && mode_changes[i].id) if ((cap & CAP_UID) && mode_changes[i].id)
arg = mode_changes[i].id; arg = mode_changes[i].id;
if (!*arg) if (*arg == '\0')
arg = mode_changes[i].arg; arg = mode_changes[i].arg;
/* if we're creeping past the buf size, we need to send it and make /* 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, * 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. * 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) || if((mc == MAXMODEPARAMS) ||
((strlen(arg) + mbl + pbl + 2) > BUFSIZE))) ((arglen + mbl + pbl + 2) > BUFSIZE) ||
(pbl + arglen + BAN_FUDGE) >= MODEBUFLEN)
{ {
if (nc != 0) if (nc != 0)
sendto_server(client_p, source_p, chptr, cap, nocap, 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; nc = 0;
mc = 0; mc = 0;
@ -1837,7 +1853,9 @@ send_cap_mode_changes(struct Client *client_p, struct Client *source_p,
chptr->chname); chptr->chname);
pbl = 0; pbl = 0;
parabuf[0] = 0; parabuf[0] = '\0';
parptr = parabuf;
dir = MODE_QUERY;
} }
if(dir != mode_changes[i].dir) 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++] = mode_changes[i].letter;
modebuf[mbl] = 0; modebuf[mbl] = '\0';
nc++; nc++;
if (arg != NULL) if (arg != NULL)
{ {
pbl = strlcat(parabuf, arg, MODEBUFLEN); len = ircsprintf(parptr, "%s ", arg);
parabuf[pbl++] = ' '; pbl += len;
parabuf[pbl] = '\0'; parptr += len;
mc++; mc++;
} }
} }
@ -1865,8 +1883,6 @@ send_cap_mode_changes(struct Client *client_p, struct Client *source_p,
if (nc != 0) if (nc != 0)
sendto_server(client_p, source_p, chptr, cap, nocap, sendto_server(client_p, source_p, chptr, cap, nocap,
LL_ICLIENT, "%s %s", modebuf, parabuf); LL_ICLIENT, "%s %s", modebuf, parabuf);
} }
/* void send_mode_changes(struct Client *client_p, /* 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 * Side-effects: Sends the appropriate mode changes to other clients
* and propagates to servers. * and propagates to servers.
*/ */
/* ensure parabuf < MODEBUFLEN -db */
static void static void
send_mode_changes(struct Client *client_p, struct Client *source_p, send_mode_changes(struct Client *client_p, struct Client *source_p,
struct Channel *chptr, char *chname) struct Channel *chptr, char *chname)
{ {
int pbl, mbl, nc, mc; int i, mbl, pbl, arglen, nc, mc;
int i, st; int len;
char *arg;
char *parptr;
int st;
int dir = MODE_QUERY; int dir = MODE_QUERY;
/* bail out if we have nothing to do... */ /* bail out if we have nothing to do... */
if (mode_count <= 0) if (mode_count <= 0)
return; return;
/* Send all mode changes to the chanops/halfops, and even peons if /* Send all mode changes to the chanops/halfops, and even peons if
* we are not +A... * 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, mbl = ircsprintf(modebuf, ":%s!%s@%s MODE %s ", source_p->name,
source_p->username, source_p->vhost, chname); source_p->username, source_p->vhost, chname);
pbl = 0;
parabuf[0] = '\0';
nc = 0;
mc = 0; mc = 0;
nc = 0;
pbl = 0;
parabuf[0] = '\0';
parptr = parabuf;
for (i = 0; i < mode_count; i++) 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) mode_changes[i].mems == ONLY_SERVERS)
continue; continue;
arg = mode_changes[i].arg;
if (arg != NULL)
arglen = strlen(arg);
else
arglen = 0;
if (mode_changes[i].arg != NULL && if ((mc == MAXMODEPARAMS) ||
((mc == MAXMODEPARAMS) || ((arglen + mbl + pbl + 2) > BUFSIZE) ||
((strlen(mode_changes[i].arg) + mbl + pbl + 2) > BUFSIZE))) ((arglen + pbl + BAN_FUDGE) >= MODEBUFLEN))
{ {
if (mbl && modebuf[mbl - 1] == '-') if (mbl && modebuf[mbl - 1] == '-')
modebuf[mbl - 1] = '\0'; modebuf[mbl - 1] = '\0';
@ -1937,6 +1963,8 @@ send_mode_changes(struct Client *client_p, struct Client *source_p,
pbl = 0; pbl = 0;
parabuf[0] = '\0'; parabuf[0] = '\0';
parptr = parabuf;
dir = MODE_QUERY;
} }
if(dir != mode_changes[i].dir) if(dir != mode_changes[i].dir)
@ -1949,12 +1977,12 @@ send_mode_changes(struct Client *client_p, struct Client *source_p,
modebuf[mbl] = '\0'; modebuf[mbl] = '\0';
nc++; nc++;
if (mode_changes[i].arg != NULL) if (arg != NULL)
{ {
len = ircsprintf(parptr, "%s ", arg);
pbl += len;
parptr += len;
mc++; 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; continue;
} }
if (mode_changes[i].arg != NULL && ((mc == MAXMODEPARAMS) || arg = mode_changes[i].arg;
((strlen(mode_changes[i].arg) + mbl + pbl + 2) > BUFSIZE))) 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] == '-') if (mbl && modebuf[mbl - 1] == '-')
modebuf[mbl - 1] = '\0'; 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); mbl = ircsprintf(modebuf, ":%s MODE %s ", me.name, chname);
pbl = 0; pbl = 0;
parabuf[0] = '\0'; parabuf[0] = '\0';
parptr = parabuf;
} }
if(dir != mode_changes[i].dir) if(dir != mode_changes[i].dir)
@ -2019,12 +2055,12 @@ send_mode_changes(struct Client *client_p, struct Client *source_p,
modebuf[mbl] = '\0'; modebuf[mbl] = '\0';
nc++; nc++;
if (mode_changes[i].arg != NULL) if (arg != NULL)
{ {
mc++; len = ircsprintf(parptr, "%s ", arg);
pbl = strlen(strcat(parabuf, mode_changes[i].arg)); pbl += len;
parabuf[pbl++] = ' '; parptr += len;
parabuf[pbl] = '\0'; 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); sendto_channel_local(st, chptr, "%s %s", modebuf, parabuf);
} }
if (nc != 0)
sendto_one(client_p, "%s %s", modebuf, parabuf);
/* Now send to servers... */ /* Now send to servers... */
send_cap_mode_changes(client_p, source_p, chptr); 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; char *ml = parv[0], c;
int table_position; int table_position;
mask_pos = 0; mask_pos = 0;
mode_count = 0; mode_count = 0;
hideops_changed = (chptr->mode.mode & MODE_HIDEOPS); 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); update_channel_info(chptr);
send_mode_changes(client_p, source_p, chptr, chname); 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 opbuf[MODEBUFLEN];
char *t; char *t;
*mcbuf = *opbuf = '\0'; *mcbuf = *opbuf = '\0';
t = opbuf; t = opbuf;
@ -2217,7 +2253,6 @@ sync_channel_oplists(struct Channel *chptr, int dir)
{ {
dlink_node *ptr; dlink_node *ptr;
for (ptr=chptr->locpeons.head; ptr!=NULL && ptr->data!=NULL; ptr=ptr->next) for (ptr=chptr->locpeons.head; ptr!=NULL && ptr->data!=NULL; ptr=ptr->next)
sync_oplists(chptr, ptr->data, MODE_ADD, chptr->chname); sync_oplists(chptr, ptr->data, MODE_ADD, chptr->chname);
for (ptr=chptr->locvoiced.head; ptr!=NULL && ptr->data!=NULL; ptr = ptr->next) 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; int i;
if (need_check) if (need_check)
{ {
*t_op = is_chan_op(chptr, target_p); *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; *t_hop = (mode_changes[i].dir == MODE_ADD) ? 1 : 0;
return; 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; *t_voice = (mode_changes[i].dir == MODE_ADD) ? 1 : 0;
return; return;
@ -2281,7 +2315,6 @@ update_channel_info(struct Channel *chptr)
dlink_node *ptr; dlink_node *ptr;
dlink_node *ptr_next; dlink_node *ptr_next;
/* hideops_changed is set to chptr->mode.mode & MODE_HIDEOPS at /* hideops_changed is set to chptr->mode.mode & MODE_HIDEOPS at
* the beginning.. * the beginning..
*/ */
@ -2423,18 +2456,18 @@ update_channel_info(struct Channel *chptr)
} }
} }
else if (mode_changes[i].letter == 'a') 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, change_channel_membership(chptr, &chptr->peons, &chptr->locpeons,
mode_changes[i].client); mode_changes[i].client);
} }
else else
{ {
change_channel_membership(chptr, &chptr->chanadmins, &chptr->locchanadmins, change_channel_membership(chptr, &chptr->chanadmins, &chptr->locchanadmins,
mode_changes[i].client); mode_changes[i].client);
}
} }
}
else if (mode_changes[i].letter == 'v') else if (mode_changes[i].letter == 'v')
{ {
{ {

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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 "stdinc.h"
#include "config.h" #include "config.h"
@ -58,6 +58,7 @@
static void check_pings_list(dlink_list *list); static void check_pings_list(dlink_list *list);
static void check_unknowns_list(dlink_list *list); static void check_unknowns_list(dlink_list *list);
static void free_exited_clients(void *unused); static void free_exited_clients(void *unused);
static void free_local_client(struct Client *client_p);
static EVH check_pings; static EVH check_pings;
@ -68,7 +69,6 @@ static BlockHeap *client_heap = NULL;
static BlockHeap *lclient_heap = NULL; static BlockHeap *lclient_heap = NULL;
dlink_list dead_list; dlink_list dead_list;
dlink_list abort_list;
/* /*
* client_heap_gc * client_heap_gc
@ -175,40 +175,50 @@ struct Client* make_client(struct Client* from)
return client_p; 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)) if (MyConnect(client_p))
{ {
assert(IsClosing(client_p) && IsDead(client_p));
/* /*
* clean up extra sockets from P-lines which have been discarded. * clean up extra sockets from P-lines which have been discarded.
*/ */
if (client_p->localClient->listener) if (client_p->localClient->listener)
{ {
assert(0 < client_p->localClient->listener->ref_count); assert(0 < client_p->localClient->listener->ref_count);
if (0 == --client_p->localClient->listener->ref_count && if (0 == --client_p->localClient->listener->ref_count &&
!client_p->localClient->listener->active) !client_p->localClient->listener->active)
free_listener(client_p->localClient->listener); free_listener(client_p->localClient->listener);
client_p->localClient->listener = 0; 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) if (client_p->localClient->fd >= 0)
fd_close(client_p->localClient->fd); fd_close(client_p->localClient->fd);
BlockHeapFree(lclient_heap, client_p->localClient); BlockHeapFree(lclient_heap, client_p->localClient);
--local_client_count; --local_client_count;
assert(local_client_count >= 0); 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 else
{
--remote_client_count; --remote_client_count;
}
BlockHeapFree(client_heap, client_p); BlockHeapFree(client_heap, client_p);
} }
@ -270,7 +280,7 @@ check_pings_list(dlink_list *list)
** Note: No need to notify opers here. It's ** Note: No need to notify opers here. It's
** already done when "FLAGS_DEADSOCKET" is set. ** already done when "FLAGS_DEADSOCKET" is set.
*/ */
if (client_p->flags & FLAGS_DEADSOCKET) if (IsDead(client_p))
{ {
/* Ignore it, its been exited already */ /* Ignore it, its been exited already */
continue; continue;
@ -309,30 +319,30 @@ check_pings_list(dlink_list *list)
else else
ping = get_client_ping(client_p); ping = get_client_ping(client_p);
if (ping < (CurrentTime - client_p->lasttime)) if (ping < (CurrentTime - client_p->lasttime))
{ {
/* /*
* If the client/server hasnt talked to us in 2*ping seconds * If the client/server hasnt talked to us in 2*ping seconds
* and it has a ping time, then close its connection. * and it has a ping time, then close its connection.
*/ */
if (((CurrentTime - client_p->lasttime) >= (2 * ping) && if (((CurrentTime - client_p->lasttime) >= (2 * ping) &&
(client_p->flags & FLAGS_PINGSENT))) (client_p->flags & FLAGS_PINGSENT)))
{ {
if (IsServer(client_p) || IsConnecting(client_p) || if (IsServer(client_p) || IsConnecting(client_p) ||
IsHandshake(client_p)) IsHandshake(client_p))
{ {
sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ADMIN, sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ADMIN,
"No response from %s, closing link", "No response from %s, closing link",
get_client_name(client_p, HIDE_IP)); get_client_name(client_p, HIDE_IP));
sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_OPER, sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_OPER,
"No response from %s, closing link", "No response from %s, closing link",
get_client_name(client_p, MASK_IP)); get_client_name(client_p, MASK_IP));
ilog(L_NOTICE, "No response from %s, closing link", ilog(L_NOTICE, "No response from %s, closing link",
get_client_name(client_p, HIDE_IP)); get_client_name(client_p, HIDE_IP));
} }
(void)ircsprintf(scratch, (void)ircsprintf(scratch,
"Ping timeout: %d seconds", "Ping timeout: %d seconds",
(int)(CurrentTime - client_p->lasttime)); (int)(CurrentTime - client_p->lasttime));
(void)exit_client(client_p, client_p, &me, scratch); (void)exit_client(client_p, client_p, &me, scratch);
continue; continue;
@ -826,15 +836,15 @@ get_client_name(struct Client* client, int showip)
switch (showip) switch (showip)
{ {
case SHOW_IP: case SHOW_IP:
ircsprintf(nbuf, "%s[%s@%s]", client->name, client->username, ircsprintf(nbuf, "%s [%s@%s]", client->name, client->username,
client->localClient->sockhost); client->localClient->sockhost);
break; break;
case MASK_IP: 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); client->username);
break; break;
default: default:
ircsprintf(nbuf, "%s[%s@%s]", client->name, client->username, ircsprintf(nbuf, "%s [%s@%s]", client->name, client->username,
client->host); client->host);
} }
return nbuf; return nbuf;
@ -864,6 +874,8 @@ free_exited_clients(void *unused)
free_dlink_node(ptr); free_dlink_node(ptr);
continue; continue;
} }
release_client_state(target_p); release_client_state(target_p);
free_client(target_p); free_client(target_p);
dlinkDelete(ptr, &dead_list); dlinkDelete(ptr, &dead_list);
@ -875,9 +887,9 @@ free_exited_clients(void *unused)
** Exit one client, local or remote. Assuming all dependents have ** Exit one client, local or remote. Assuming all dependents have
** been already removed, and socket closed for local client. ** been already removed, and socket closed for local client.
*/ */
static void exit_one_client(struct Client *client_p, static void
struct Client *source_p, exit_one_client(struct Client *client_p, struct Client *source_p,
struct Client *from, const char *comment) struct Client *from, const char *comment)
{ {
struct Client* target_p; struct Client* target_p;
dlink_node *lp; dlink_node *lp;
@ -940,7 +952,7 @@ static void exit_one_client(struct Client *client_p,
target_p = source_p->from; target_p = source_p->from;
if (target_p && IsServer(target_p) && target_p != client_p && !IsMe(target_p) && 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); 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... */ 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 ** is no sense in sending the QUIT--KILL's have been
** sent instead. ** sent instead.
*/ */
if ((source_p->flags & FLAGS_KILLED) == 0) if (!IsKilled(source_p))
{ {
sendto_server(client_p, source_p, NULL, NOCAPS, NOCAPS, sendto_server(client_p, source_p, NULL, NOCAPS, NOCAPS,
NOFLAGS, ":%s QUIT :%s", source_p->name, comment); NOFLAGS, ":%s QUIT :%s", source_p->name, comment);
@ -968,9 +980,9 @@ static void exit_one_client(struct Client *client_p,
comment); comment);
DLINK_FOREACH_SAFE(lp, next_lp, source_p->user->channel.head) 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 */ /* Should not be in any channels now */
assert(source_p->user->channel.head == NULL); 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 */ /* Check to see if the client isn't already on the dead list */
assert(dlinkFind(&dead_list, source_p) == NULL); assert(dlinkFind(&dead_list, source_p) == NULL);
/* add to dead client dlist */ /* add to dead_list */
lp = make_dlink_node(); lp = make_dlink_node();
SetDead(source_p);
dlinkAdd(source_p, lp, &dead_list); 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... * 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; 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)) while ((target_p = source_p->serv->users))
{ {
target_p->flags |= FLAGS_KILLED; SetKilled(target_p);
exit_one_client(NULL, target_p, &me, comment); 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 ** a server marked as "KILLED" won't send a SQUIT
** in exit_one_client() -orabidoo ** in exit_one_client() -orabidoo
*/ */
target_p->flags |= FLAGS_KILLED; SetKilled(target_p);
exit_one_client(NULL, target_p, &me, me.name); 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); 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; const char *notice;
if(IsClosing(client_p) || IsDead(client_p))
return;
linebuf_donebuf(&client_p->localClient->buf_recvq); if(IsDefunct(client_p))
linebuf_donebuf(&client_p->localClient->buf_sendq); return;
SetDead(client_p);
if(client_p->flags & FLAGS_SENDQEX) if(client_p->flags & FLAGS_SENDQEX)
notice = "Max SendQ exceeded"; notice = "Max SendQ exceeded";
else else
notice = "Write error: connection closed"; 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, sendto_realops_flags(FLAGS_ALL, L_ADMIN,
"Closing link to %s: %s", "Closing link to %s: %s",
@ -1159,42 +1168,74 @@ void dead_link(struct Client *client_p)
"Closing link to %s: %s", "Closing link to %s: %s",
get_client_name(client_p, MASK_IP), notice); get_client_name(client_p, MASK_IP), notice);
} }
Debug((DEBUG_ERROR, "Closing link to %s: %s", get_client_name(client_p, HIDE_IP), notice)); Debug((DEBUG_ERROR, "Closing link to %s: %s",
assert(dlinkFind(&abort_list, client_p) == NULL); get_client_name(client_p, HIDE_IP), notice));
m = make_dlink_node(); exit_client(client_p, client_p, &me, "Closing link");
dlinkAdd(client_p, m, &abort_list);
SetDead(client_p); /* You are dead my friend */
} }
/*
* dead_link_on_read - report a read error if not already dead,
* mark it as dead then exit it
*
*/
void void
exit_aborted_clients(void) dead_link_on_read(struct Client* client_p, int error)
{ {
dlink_node *ptr, *next; char errmsg[255];
struct Client *target_p; int current_error = get_sockerr(client_p->localClient->fd);
char *notice;
DLINK_FOREACH_SAFE(ptr, next, abort_list.head) if(IsDead(client_p))
{ return;
target_p = ptr->data; SetDead(client_p);
if (ptr->data == NULL)
{ Debug((DEBUG_ERROR, "READ ERROR: fd = %d %d %d",
sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ALL, client_p->localClient->fd, current_error, error));
"Warning: null client on abort_list!");
dlinkDelete(ptr, &abort_list); if (IsServer(client_p) || IsHandshake(client_p))
free_dlink_node(ptr); {
continue; int connected = CurrentTime - client_p->firsttime;
}
dlinkDelete(ptr, &abort_list);
if(target_p->flags & FLAGS_SENDQEX)
notice = "Max SendQ exceeded";
else
notice = "Write error: connection closed";
exit_client(target_p, target_p, &me, notice); if (error == 0)
free_dlink_node(ptr); {
} /* 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 ** 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) ** CLIENT_EXITED if (client_p == source_p)
** 0 if (client_p != source_p) ** 0 if (client_p != source_p)
*/ */
int int
exit_client( exit_client(
struct Client* client_p, /* The local client originating the struct Client* client_p, /* The local client originating the
@ -1232,16 +1274,15 @@ exit_client(
{ {
char comment1[HOSTLEN + HOSTLEN + 2]; char comment1[HOSTLEN + HOSTLEN + 2];
dlink_node *m; dlink_node *m;
if (IsClosing(source_p))
return(0);
SetClosing(source_p);
if (MyConnect(source_p)) if (MyConnect(source_p))
{ {
/* DO NOT REMOVE. exit_client can be called twice after a failed if (IsIpHash(source_p))
* read/write.
*/
if(IsClosing(source_p))
return 0;
SetClosing(source_p);
if (source_p->flags & FLAGS_IPHASH)
remove_one_ip(&source_p->localClient->ip); remove_one_ip(&source_p->localClient->ip);
delete_adns_queries(source_p->localClient->dns_query); delete_adns_queries(source_p->localClient->dns_query);
@ -1317,9 +1358,10 @@ exit_client(
source_p->name, source_p->username, source_p->host, source_p->name, source_p->username, source_p->host,
comment, comment,
source_p->localClient->sockhost); source_p->localClient->sockhost);
log_user_exit(source_p); log_user_exit(source_p);
if (source_p->localClient->fd >= 0) if (!IsDead(source_p))
{ {
if (client_p != NULL && source_p != client_p) if (client_p != NULL && source_p != client_p)
sendto_one(source_p, "ERROR :Closing Link: %s %s (%s)", 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)", sendto_one(source_p, "ERROR :Closing Link: %s (%s)",
source_p->vhost, comment); 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)) if(IsServer(source_p))
@ -1379,12 +1407,18 @@ exit_client(
source_p->localClient->sendK, source_p->localClient->receiveK); 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 */ /* The client *better* be off all of the lists */
assert(dlinkFind(&unknown_list, source_p) == NULL); assert(dlinkFind(&unknown_list, source_p) == NULL);
assert(dlinkFind(&lclient_list, source_p) == NULL); assert(dlinkFind(&lclient_list, source_p) == NULL);
assert(dlinkFind(&serv_list, source_p) == NULL); assert(dlinkFind(&serv_list, source_p) == NULL);
assert(dlinkFind(&oper_list, source_p) == NULL); assert(dlinkFind(&oper_list, source_p) == NULL);
exit_one_client(client_p, source_p, from, comment); exit_one_client(client_p, source_p, from, comment);
return client_p == source_p ? CLIENT_EXITED : 0; return client_p == source_p ? CLIENT_EXITED : 0;

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -50,6 +50,27 @@ static char unknown_ver[] = "<unknown>";
* -TimeMr14C * -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 #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)); shl_unload((shl_t) & (modlist[modindex]->address));
#else #else
/* /*
** XXX - The type system in C does not allow direct conversion between ** We use FreeBSD's dlfunc(3) interface, or fake it as we
** data and function pointers, but as it happens, most C compilers will ** used to here if it isn't there. The interface should
** safely do this, however it is a theoretical overlow to cast as we ** be standardised some day, and so it eventually will be
** must do here. I have library functions to take care of this, but ** providing something guaranteed to do the right thing here.
** 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.
** -jmallett ** -jmallett
*/ */
if ((deinitfunc = (void (*)(void))(uintptr_t)dlsym(modlist[modindex]->address, "_moddeinit")) if ((deinitfunc = (void (*)(void))dlfunc(modlist[modindex]->address, "_moddeinit"))
|| (deinitfunc = (void (*)(void))(uintptr_t)dlsym(modlist[modindex]->address, "__moddeinit"))) { || (deinitfunc = (void (*)(void))dlfunc(modlist[modindex]->address, "__moddeinit"))) {
deinitfunc(); deinitfunc();
} }
dlclose(modlist[modindex]->address); dlclose(modlist[modindex]->address);
@ -291,9 +309,9 @@ load_a_module (char *path, int warn, int core)
ver = *verp; ver = *verp;
#else #else
initfunc = (void (*)(void))(uintptr_t)dlsym (tmpptr, "_modinit"); initfunc = (void (*)(void))dlfunc (tmpptr, "_modinit");
if (initfunc == NULL 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, sendto_realops_flags(FLAGS_ALL, L_ALL,
"Module %s has no _modinit() function", "Module %s has no _modinit() function",

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #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 */ static unsigned long initialVMTop = 0; /* top of virtual memory at init */
const char * logFileName = LPATH; const char * logFileName = LPATH;
static const char * pidFileName = PPATH; const char * pidFileName = PPATH;
char** myargv; char** myargv;
int dorehash = 0; int dorehash = 0;
int debuglevel = 10; /* Server debug level */ int doremotd = 0;
int debuglevel = -1; /* Server debug level */
char* debugmode = ""; /* -"- -"- -"- */ char* debugmode = ""; /* -"- -"- -"- */
time_t nextconnect = 1; /* time for next try_connections call */ time_t nextconnect = 1; /* time for next try_connections call */
@ -338,6 +339,13 @@ io_loop(void)
rehash(1); rehash(1);
dorehash = 0; 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); fbclose(fb);
} }
else else if(errno != ENOENT)
{ {
/* log(L_ERROR, "Error opening pid file %s", filename); */ /* log(L_ERROR, "Error opening pid file %s", filename); */
} }
@ -508,19 +516,6 @@ static void setup_corefile(void)
#endif #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[]) int main(int argc, char *argv[])
{ {
/* Check to see if the user is running us as root, which is a nono */ /* 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 */ /* Setup the timeout check. I'll shift it later :) -- adrian */
eventAddIsh("comm_checktimeouts", comm_checktimeouts, NULL, 1); eventAddIsh("comm_checktimeouts", comm_checktimeouts, NULL, 1);
#if 0
eventAddIsh("cleanup_zombies", cleanup_zombies, NULL, 30); eventAddIsh("cleanup_zombies", cleanup_zombies, NULL, 30);
#endif
#if 0
if (ConfigFileEntry.throttle_time > 0) if (ConfigFileEntry.throttle_time > 0)
eventAddIsh("flush_expired_ips", flush_expired_ips, NULL, ConfigFileEntry.throttle_time); eventAddIsh("flush_expired_ips", flush_expired_ips, NULL, ConfigFileEntry.throttle_time);
else else
eventAddIsh("flush_expired_ips", flush_expired_ips, NULL, 300); eventAddIsh("flush_expired_ips", flush_expired_ips, NULL, 300);
#endif
if(ConfigServerHide.links_delay > 0) if(ConfigServerHide.links_delay > 0)
eventAddIsh("write_links_file", write_links_file, NULL, ConfigServerHide.links_delay); eventAddIsh("write_links_file", write_links_file, NULL, ConfigServerHide.links_delay);

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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; break;
/* XXX - should we unload this module on /rehash, if it isn't listed? */ /* 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); MyFree(m_bn);
#endif #endif

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -613,7 +613,7 @@ GreetUser(struct Client *client)
me.name, me.name,
client->user->server); client->user->server);
client->flags |= FLAGS_KILLED; SetKilled(client);
exit_client(NULL, client, &me, "Ghost"); exit_client(NULL, client, &me, "Ghost");
return; return;

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -81,7 +81,8 @@ parse_k_file(FBFILE *file)
* Side Effects - Parse one new style D line * Side Effects - Parse one new style D line
*/ */
void parse_d_file(FBFILE *file) void
parse_d_file(FBFILE *file)
{ {
struct ConfItem *aconf; struct ConfItem *aconf;
char* reason_field=(char *)NULL; char* reason_field=(char *)NULL;
@ -117,44 +118,55 @@ void parse_d_file(FBFILE *file)
* output - next field * output - next field
* side effects - field breakup for ircd.conf file. * 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; char *end, *field;
if (newline) if (newline != NULL)
line = newline; line = newline;
if (line == (char *)NULL) if (line == NULL)
return((char *)NULL); return(NULL);
field = line; field = line;
/* XXX make this skip to first " if present */ /* XXX make this skip to first " if present */
if(*field == '"') if(*field == '"')
{
field++; field++;
end = field;
}
else 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 = NULL;
line = (char *)NULL; return(NULL);
/* XXX verify properly terminating " */
if(*end == '"')
*end = '\0';
else
return((char *)NULL);
} }
else else if (*end == '\\') /* found escape character ? */
{ {
line = end + 1; end++;
--end;
if(*end == '"')
*end = '\0';
else
return((char *)NULL);
} }
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);
} }

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -304,13 +304,13 @@ int unbase64_block(char **output, char *data, int len)
q_in = 0; 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]] ; 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; 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; 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; q_in |= base64_values[in[i ]] << 18;
out[count++] = (q_in >> 16) & 0xff; out[count++] = (q_in >> 16) & 0xff;

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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[] = { static char * replies[] = {
@ -540,7 +540,7 @@ static char * replies[] = {
/* 510 */ NULL, /* 510 */ NULL,
/* 511 */ NULL, /* 511 */ NULL,
/* 512 */ 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, /* 514 */ NULL,
/* 515 */ NULL, /* 515 */ NULL,
/* 516 */ NULL, /* 516 */ NULL,

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -320,7 +320,7 @@ load_core_modules(int warn)
* side effects - * side effects -
*/ */
int int
load_one_module (char *path) load_one_module (char *path, int coremodule)
{ {
char modpath[MAXPATHLEN]; char modpath[MAXPATHLEN];
dlink_node *pathst; dlink_node *pathst;
@ -340,7 +340,10 @@ load_one_module (char *path)
if(S_ISREG(statbuf.st_mode)) if(S_ISREG(statbuf.st_mode))
{ {
/* Regular files only please */ /* 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", sendto_one (source_p, ":%s NOTICE %s :Module %s is already loaded",
me.name, source_p->name, m_bn); me.name, source_p->name, m_bn);
MyFree(m_bn);
return; return;
} }
load_one_module (parv[1]); load_one_module (parv[1], 0);
MyFree(m_bn); MyFree(m_bn);
} }
@ -414,7 +418,7 @@ mo_modunload (struct Client *client_p, struct Client *source_p, int parc, char *
return; 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", sendto_one (source_p, ":%s NOTICE %s :Module %s is not loaded",
me.name, source_p->name, m_bn); 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; 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", sendto_one (source_p, ":%s NOTICE %s :Module %s is not loaded",
me.name, source_p->name, m_bn); 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; 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, sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ALL,
"Error reloading core module: %s: terminating ircd", "Error reloading core module: %s: terminating ircd",

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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 "stdinc.h"
#include "tools.h" #include "tools.h"
@ -58,27 +58,31 @@ parse_client_queued(struct Client *client_p)
for(;;) for(;;)
{ {
if (IsDead(client_p))
return;
if (client_p->localClient == NULL)
return;
/* rate unknown clients at MAX_FLOOD per loop */ /* rate unknown clients at MAX_FLOOD per loop */
if(i >= MAX_FLOOD) if(i >= MAX_FLOOD)
break; break;
dolen = linebuf_get(&client_p->localClient->buf_recvq, readBuf, dolen = linebuf_get(&client_p->localClient->buf_recvq, readBuf,
READBUF_SIZE, LINEBUF_COMPLETE, LINEBUF_PARSED); READBUF_SIZE, LINEBUF_COMPLETE, LINEBUF_PARSED);
if(dolen <= 0) if(dolen <= 0)
break; break;
if(!IsDead(client_p)) if(!IsDead(client_p))
{ {
client_dopacket(client_p, readBuf, dolen); client_dopacket(client_p, readBuf, dolen);
i++; 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 * to the parsing for their appropriate status. --fl
*/ */
if(!IsUnknown(client_p)) if(!IsUnknown(client_p))
break; break;
} }
else if(MyConnect(client_p)) 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 (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, while ((dolen = linebuf_get(&client_p->localClient->buf_recvq,
readBuf, READBUF_SIZE, LINEBUF_COMPLETE, readBuf, READBUF_SIZE, LINEBUF_COMPLETE,
LINEBUF_PARSED)) > 0) LINEBUF_PARSED)) > 0)
@ -103,22 +112,31 @@ parse_client_queued(struct Client *client_p)
linebuf_donebuf(&client_p->localClient->buf_sendq); linebuf_donebuf(&client_p->localClient->buf_sendq);
return; 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.no_oper_flood && (IsOper(client_p) || IsCanFlood(client_p)))
if (ConfigFileEntry.true_no_oper_flood) {
if (ConfigFileEntry.true_no_oper_flood)
checkflood = -1; checkflood = -1;
else
checkflood = 0;
}
/* /*
* Handle flood protection here - if we exceed our flood limit on * Handle flood protection here - if we exceed our flood limit on
* messages in this loop, we simply drop out of the loop prematurely. * messages in this loop, we simply drop out of the loop prematurely.
* -- adrian * -- adrian
*/ */
for (;;) for(;;)
{ {
if (IsDead(client_p))
break;
/* This flood protection works as follows: /* This flood protection works as follows:
* *
* A client is given allow_read lines to send to the server. Every * 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) else if(lclient_p->sent_parsed >= (4 * lclient_p->allow_read) && checkflood != -1)
break; break;
if(client_p->localClient == NULL)
break;
dolen = linebuf_get(&client_p->localClient->buf_recvq, readBuf, dolen = linebuf_get(&client_p->localClient->buf_recvq, readBuf,
READBUF_SIZE, LINEBUF_COMPLETE, LINEBUF_PARSED); READBUF_SIZE, LINEBUF_COMPLETE, LINEBUF_PARSED);
@ -254,14 +275,12 @@ read_ctrl_packet(int fd, void *data)
{ {
if((length == -1) && ignoreErrno(errno)) if((length == -1) && ignoreErrno(errno))
goto nodata; goto nodata;
error_exit_client(server, length);
return; return;
} }
reply->command = tmp[0]; reply->command = tmp[0];
} }
for (replydef = slinkrpltab; replydef->handler; replydef++) for(replydef = slinkrpltab; replydef->handler; replydef++)
{ {
if (replydef->replyid == reply->command) if (replydef->replyid == reply->command)
break; break;
@ -279,7 +298,7 @@ read_ctrl_packet(int fd, void *data)
{ {
if((length == -1) && ignoreErrno(errno)) if((length == -1) && ignoreErrno(errno))
goto nodata; goto nodata;
error_exit_client(server, length); dead_link_on_read(server, length);
return; return;
} }
@ -310,7 +329,7 @@ read_ctrl_packet(int fd, void *data)
{ {
if((length == -1) && ignoreErrno(errno)) if((length == -1) && ignoreErrno(errno))
goto nodata; goto nodata;
error_exit_client(server, length); dead_link_on_read(server, length);
return; return;
} }
@ -391,7 +410,7 @@ read_packet(int fd, void *data)
} else } else
#endif #endif
length = recv(fd_r, readBuf, READBUF_SIZE, 0); length = recv(fd_r, readBuf, READBUF_SIZE, 0);
/* THIS WAS <= 0, should it stay? */ /* THIS WAS <= 0, should it stay? */
if (length <= 0) if (length <= 0)
@ -402,7 +421,7 @@ read_packet(int fd, void *data)
read_packet, client_p, 0); read_packet, client_p, 0);
return; return;
} }
error_exit_client(client_p, length); dead_link_on_read(client_p, length);
return; return;
} }
@ -430,67 +449,53 @@ read_packet(int fd, void *data)
lbuf_len = linebuf_parse(&client_p->localClient->buf_recvq, lbuf_len = linebuf_parse(&client_p->localClient->buf_recvq,
readBuf, length, binary); 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; lclient_p->actually_read += lbuf_len;
if (client_p->next == NULL)
return;
/* Attempt to parse what we have */ /* Attempt to parse what we have */
parse_client_queued(client_p);
if (!IsDead(client_p))
/* Check to make sure we're not flooding */
if (IsPerson(client_p) &&
(linebuf_alloclen(&client_p->localClient->buf_recvq) >
ConfigFileEntry.client_flood))
{ {
parse_client_queued(client_p);
if (IsDead(client_p))
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))) if (!(ConfigFileEntry.no_oper_flood && IsOper(client_p)))
{ {
exit_client(client_p, client_p, client_p, "Excess Flood"); exit_client(client_p, client_p, client_p, "Excess Flood");
return; return;
} }
} }
/* server fd may have changed */ /* server fd may have changed */
fd_r = client_p->localClient->fd; fd_r = client_p->localClient->fd;
#ifndef HAVE_SOCKETPAIR #ifndef HAVE_SOCKETPAIR
if (HasServlink(client_p)) if (HasServlink(client_p))
{ {
assert(client_p->localClient->fd_r > -1); assert(client_p->localClient->fd_r > -1);
fd_r = client_p->localClient->fd_r; fd_r = client_p->localClient->fd_r;
} }
#endif #endif
if (!IsDead(client_p))
{
/* If we get here, we need to register for another COMM_SELECT_READ */ /* 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, comm_setselect(fd_r, FDLIST_SERVER, COMM_SELECT_READ,
read_packet, client_p, 0); read_packet, client_p, 0);
} else { }
else
{
comm_setselect(fd_r, FDLIST_IDLECLIENT, COMM_SELECT_READ, 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_dopacket - copy packet to client buf and parse it
* client_p - pointer to client structure for which the buffer data * client_p - pointer to client structure for which the buffer data

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -135,7 +135,7 @@ parse(struct Client *client_p, char *pbuffer, char *bufend)
assert(!IsDead(client_p)); assert(!IsDead(client_p));
assert(client_p->localClient->fd >= 0); assert(client_p->localClient->fd >= 0);
if(IsDead(client_p) || client_p->localClient->fd < 0) if(IsDefunct(client_p))
return; return;
assert((bufend-pbuffer) < 512); assert((bufend-pbuffer) < 512);
@ -542,7 +542,7 @@ hash(char *p)
* *
* inputs - pointer to client to report to * inputs - pointer to client to report to
* output - NONE * output - NONE
* side effects - NONE * side effects - client is shown list of commands
*/ */
void void
report_messages(struct Client *source_p) report_messages(struct Client *source_p)
@ -556,11 +556,12 @@ report_messages(struct Client *source_p)
{ {
assert(ptr->msg != NULL); assert(ptr->msg != NULL);
assert(ptr->cmd != NULL); assert(ptr->cmd != NULL);
sendto_one(source_p, form_str(RPL_STATSCOMMANDS), if (!((ptr->msg->flags & MFLG_HIDDEN) && !IsAdmin(source_p)))
me.name, source_p->name, ptr->cmd, sendto_one(source_p, form_str(RPL_STATSCOMMANDS),
ptr->msg->count, ptr->msg->bytes, me.name, source_p->name, ptr->cmd,
ptr->msg->rcount); 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) for(ptr = msg_hash_table[i]; ptr; ptr = ptr->next)
{ {
sendto_one(source_p, ":%s NOTICE %s :%s", if (!((ptr->msg->flags & MFLG_HIDDEN) && !IsAdmin(source_p)))
me.name, source_p->name, ptr->cmd); sendto_one(source_p, ":%s NOTICE %s :%s",
me.name, source_p->name, ptr->cmd);
} }
} }
} }

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -60,7 +60,7 @@ void server_reboot(void)
sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ALL, sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ALL,
"Restarting server..."); "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 * 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 * 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 * bah, for now, the program ain't coming back to here, so forcibly
* close everything the "wrong" way for now, and just LEAVE... * close everything the "wrong" way for now, and just LEAVE...
*/ */
for (i = 0; i < MAXCONNECTIONS; ++i) for (i = 3; i < MAXCONNECTIONS; ++i)
close(i); close(i);
unlink(pidFileName);
execv(SPATH, myargv); execv(SPATH, myargv);
fprintf(stderr, "ircd: execv() failed: %s\n", strerror(errno));
exit(-1); exit(-1);
} }

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -52,6 +52,7 @@
#endif #endif
#include "memory.h" #include "memory.h"
#ifndef IN_LOOPBACKNET #ifndef IN_LOOPBACKNET
#define IN_LOOPBACKNET 0x7f #define IN_LOOPBACKNET 0x7f
#endif #endif
@ -75,7 +76,8 @@ static PF comm_connect_tryconnect;
/* close_all_connections() can be used *before* the system come up! */ /* close_all_connections() can be used *before* the system come up! */
void close_all_connections(void) void
close_all_connections(void)
{ {
int i; int i;
#ifndef NDEBUG #ifndef NDEBUG
@ -120,14 +122,16 @@ void close_all_connections(void)
* This may only work when SO_DEBUG is enabled but its worth the * This may only work when SO_DEBUG is enabled but its worth the
* gamble anyway. * gamble anyway.
*/ */
int get_sockerr(int fd) int
get_sockerr(int fd)
{ {
int errtmp = errno; int errtmp = errno;
#ifdef SO_ERROR #ifdef SO_ERROR
int err = 0; int err = 0;
socklen_t len = sizeof(err); 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) if (err)
errtmp = err; errtmp = err;
} }
@ -155,7 +159,8 @@ int get_sockerr(int fd)
* Actually stderr is still there IFF ircd was run with -s --Rodder * 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 : ""; who = (who) ? who : "";
@ -207,7 +212,8 @@ disable_sock_options(int fd)
* side effects - use POSIX compliant non blocking and * side effects - use POSIX compliant non blocking and
* be done with it. * be done with it.
*/ */
int set_non_blocking(int fd) int
set_non_blocking(int fd)
{ {
#ifndef VMS #ifndef VMS
int nonb = 0; int nonb = 0;
@ -242,7 +248,8 @@ int set_non_blocking(int fd)
* Close the physical connection. This function must make * Close the physical connection. This function must make
* MyConnect(client_p) == FALSE, and set client_p->from == NULL. * 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; struct ConfItem *aconf;
assert(NULL != client_p); assert(NULL != client_p);
@ -309,18 +316,18 @@ void close_connection(struct Client *client_p)
else else
ServerStats->is_ni++; ServerStats->is_ni++;
if (-1 < client_p->localClient->fd) if (!IsDead(client_p))
{ {
/* attempt to flush any pending dbufs. Evil, but .. -- adrian */ /* 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); fd_close(client_p->localClient->fd);
client_p->localClient->fd = -1; client_p->localClient->fd = -1;
SetDead(client_p);
} }
if(HasServlink(client_p)) if(HasServlink(client_p))
{ {
if(client_p->localClient->fd > -1) if(client_p->localClient->ctrlfd > -1)
{ {
fd_close(client_p->localClient->ctrlfd); fd_close(client_p->localClient->ctrlfd);
#ifndef HAVE_SOCKETPAIR #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 * The client is sent to the auth module for verification, and not put in
* any client list yet. * any client list yet.
*/ */
void add_connection(struct Listener* listener, int fd) void
add_connection(struct Listener* listener, int fd)
{ {
struct Client* new_client; 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 * stolen from squid - its a neat (but overused! :) routine which we

View file

@ -20,7 +20,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "config.h"
@ -296,5 +296,9 @@ comm_select(unsigned long delay)
/* XXX Get here, we broke! */ /* XXX Get here, we broke! */
return 0; return 0;
} }
#else
/**
* Don't let an empty compilation unit slip through.
*/
static int dummy;
#endif /* USE_DEVPOLL */ #endif /* USE_DEVPOLL */

View file

@ -20,7 +20,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "config.h"
@ -286,4 +286,9 @@ comm_select(unsigned long delay)
return 0; return 0;
} }
#else /* USE_KQUEUE */
/**
* Don't let an empty compilation unit slip through.
*/
static int dummy;
#endif /* USE_KQUEUE */ #endif /* USE_KQUEUE */

View file

@ -20,7 +20,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "config.h"
@ -257,5 +257,9 @@ comm_select(unsigned long delay)
} }
return 0; return 0;
} }
#else
/**
* Don't let an empty compilation unit slip through.
*/
static int dummy;
#endif #endif

View file

@ -20,7 +20,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "config.h"
@ -219,4 +219,9 @@ comm_select(unsigned long delay)
return 0; return 0;
} }
#else /* USE_SELECT */
/**
* Don't let an empty compilation unit slip through.
*/
static int dummy;
#endif /* USE_SELECT */ #endif /* USE_SELECT */

View file

@ -21,7 +21,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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 #ifndef _GNU_SOURCE
@ -353,5 +353,9 @@ int comm_select(unsigned long delay)
mask_our_signal(sigio_signal); mask_our_signal(sigio_signal);
return 0; return 0;
} }
#else
/**
* Don't let an empty compilation unit slip through.
*/
static int dummy;
#endif #endif

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -211,6 +211,7 @@ free_conf(struct ConfItem* aconf)
MyFree(aconf->name); MyFree(aconf->name);
MyFree(aconf->className); MyFree(aconf->className);
MyFree(aconf->user); MyFree(aconf->user);
MyFree(aconf->fakename);
#ifdef HAVE_LIBCRYPTO #ifdef HAVE_LIBCRYPTO
if (aconf->rsa_public_key) { RSA_free(aconf->rsa_public_key); } if (aconf->rsa_public_key) { RSA_free(aconf->rsa_public_key); }
if (aconf->rsa_public_key_file) { MyFree(aconf->rsa_public_key_file); } 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; char* classname;
int port; int port;
for (tmp = ConfigItemList; tmp; tmp = tmp->next) { for (tmp = ConfigItemList; tmp; tmp = tmp->next)
{
if (tmp->status & mask) if (tmp->status & mask)
{ {
for (p = &report_array[0]; p->conf_type; p++) for (p = &report_array[0]; p->conf_type; p++)
@ -404,15 +406,16 @@ report_specials(struct Client* source_p, int flags, int numeric)
int int
check_client(struct Client *client_p, struct Client *source_p, char *username) check_client(struct Client *client_p, struct Client *source_p, char *username)
{ {
static char sockname[HOSTLEN + 1]; int i;
int i;
ClearAccess(source_p); ClearAccess(source_p);
/* I'm already in big trouble if source_p->localClient is NULL -db */
if ((i = verify_access(source_p, username))) 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 ) switch( i )
{ {
@ -469,7 +472,7 @@ check_client(struct Client *client_p, struct Client *source_p, char *username)
source_p->localClient->listener->port); source_p->localClient->listener->port);
(void)exit_client(client_p, source_p, &me, (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; break;
} }
case BANNED_CLIENT: case BANNED_CLIENT:
@ -582,8 +585,8 @@ int attach_iline(struct Client *client_p, struct ConfItem *aconf)
ip_found->count++; ip_found->count++;
/* only check it if its non zero */ /* only check it if its non zero */
if ( aconf->c_class /* This should never non NULL *grin* */ && if (aconf->c_class /* This should never non NULL *grin* */ &&
ConfConFreq(aconf) && ip_found->count > ConfConFreq(aconf)) ConfConFreq(aconf) && ip_found->count > ConfConFreq(aconf))
{ {
if(!IsConfExemptLimits(aconf)) if(!IsConfExemptLimits(aconf))
return(TOO_MANY); /* Already at maximum allowed ip#'s */ return(TOO_MANY); /* Already at maximum allowed ip#'s */
@ -668,9 +671,9 @@ find_or_add_ip(struct irc_inaddr *ip_in)
return(ptr); 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(); outofmemory();
newptr = ip_hash_table[hash_index] = free_ip_entries; newptr = ip_hash_table[hash_index] = free_ip_entries;
@ -683,14 +686,14 @@ find_or_add_ip(struct irc_inaddr *ip_in)
return(newptr); return(newptr);
} }
if (free_ip_entries == (IP_ENTRY *)NULL) if (free_ip_entries == NULL)
outofmemory(); outofmemory();
ptr = ip_hash_table[hash_index] = free_ip_entries; ptr = ip_hash_table[hash_index] = free_ip_entries;
free_ip_entries = ptr->next; free_ip_entries = ptr->next;
memcpy(&ptr->ip, ip_in, sizeof(struct irc_inaddr)); memcpy(&ptr->ip, ip_in, sizeof(struct irc_inaddr));
ptr->count = 0; ptr->count = 0;
ptr->next = (IP_ENTRY *)NULL; ptr->next = NULL;
return(ptr); return(ptr);
} }
@ -710,28 +713,28 @@ remove_one_ip(struct irc_inaddr *ip_in)
{ {
IP_ENTRY *ptr, **lptr; IP_ENTRY *ptr, **lptr;
int hash_index = hash_ip(ip_in); int hash_index = hash_ip(ip_in);
for (lptr = ip_hash_table+hash_index, ptr = *lptr; for (lptr = ip_hash_table+hash_index, ptr = *lptr; ptr;
ptr;
lptr=&ptr->next, ptr=*lptr) lptr=&ptr->next, ptr=*lptr)
{ {
#ifndef IPV6 #ifndef IPV6
if (ptr->ip != PIN_ADDR(ip_in)) if (ptr->ip != PIN_ADDR(ip_in))
continue; continue;
#else #else
if (memcmp(&IN_ADDR(ptr->ip), &PIN_ADDR(ip_in), if (memcmp(&IN_ADDR(ptr->ip), &PIN_ADDR(ip_in),
sizeof(struct irc_inaddr))) sizeof(struct irc_inaddr)))
continue; continue;
#endif #endif
if (ptr->count != 0) if (ptr->count > 0)
ptr->count--; ptr->count--;
if (ptr->count != 0 || if (ptr->count == 0 &&
(CurrentTime-ptr->last_attempt)<=ConfigFileEntry.throttle_time) (CurrentTime-ptr->last_attempt)>ConfigFileEntry.throttle_time)
continue; {
*lptr = ptr->next; *lptr = ptr->next;
ptr->next = free_ip_entries; ptr->next = free_ip_entries;
free_ip_entries = ptr; free_ip_entries = ptr;
return; return;
} }
}
} }
/* /*
@ -1554,7 +1557,6 @@ conf_connect_allowed(struct irc_inaddr *addr, int aftype)
ConfigFileEntry.throttle_time) ConfigFileEntry.throttle_time)
{ {
ip_found->last_attempt = CurrentTime; ip_found->last_attempt = CurrentTime;
ip_found->count--;
return(TOO_FAST); return(TOO_FAST);
} }
ip_found->last_attempt = CurrentTime; ip_found->last_attempt = CurrentTime;
@ -2146,7 +2148,7 @@ WriteKlineOrDline( KlineType type,
filename = get_conf_name(type); filename = get_conf_name(type);
if(type == DLINE_TYPE) if (type == DLINE_TYPE)
{ {
sendto_realops_flags(FLAGS_ALL, L_ALL, sendto_realops_flags(FLAGS_ALL, L_ALL,
"%s added D-Line for [%s] [%s]", "%s added D-Line for [%s] [%s]",
@ -2164,7 +2166,7 @@ WriteKlineOrDline( KlineType type,
me.name, source_p->name, user, host); 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, sendto_realops_flags(FLAGS_ALL, L_ALL,
"*** Problem opening %s ", filename); "*** Problem opening %s ", filename);
@ -2424,34 +2426,3 @@ conf_yy_fatal_error(char *msg)
{ {
return(0); 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; i<IP_HASH_SIZE; i++)
{
for (iee=ip_hash_table+i, ie=*iee; ie; ie=*iee)
{
if (ie->count == 0 && ie->last_attempt <= expire_before)
{
*iee=ie->next;
ie->next = free_ip_entries;
free_ip_entries = ie;
}
else
iee = &ie->next;
}
*iee = NULL;
}
}

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -29,6 +29,8 @@
#include "rsa.h" #include "rsa.h"
#endif #endif
#include <netinet/tcp.h>
#include "tools.h" #include "tools.h"
#include "s_serv.h" #include "s_serv.h"
#include "channel_mode.h" #include "channel_mode.h"
@ -939,6 +941,7 @@ int server_estab(struct Client *client_p)
dlink_node *m; dlink_node *m;
dlink_node *ptr; dlink_node *ptr;
unsigned int srvopt; unsigned int srvopt;
int opt;
assert(NULL != client_p); assert(NULL != client_p);
if(client_p == NULL) if(client_p == NULL)
@ -1004,11 +1007,17 @@ int server_estab(struct Client *client_p)
srvopt = 0; srvopt = 0;
if (ConfigServerHide.hidden) srvopt = SERVER_HIDDEN; 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", sendto_one(client_p, "SERVER %s 1 %d :%s",
my_name_for_link(me.name, aconf), my_name_for_link(me.name, aconf),
srvopt, srvopt,
(me.info[0]) ? (me.info) : "IRCers United"); (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 } else
fd_note(client_p->localClient->fd, "Server: %s", client_p->name); fd_note(client_p->localClient->fd, "Server: %s", client_p->name);
/* /*
** Send reserved nickname and channel information to the other server ** Send reserved nickname and channel information to the other server
** these can be dynamic (ie, set from other servers) or config based ** these can be dynamic (ie, set from other servers) or config based
** seeing as both types should be applied to the entire network ** 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, sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_OPER,
"Error connecting to %s: %s", "Error connecting to %s: %s",
client_p->name, comm_errstr(status)); 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; return;
} }
@ -2152,13 +2165,14 @@ serv_connect_callback(int fd, int status, void *data)
/* Get the C/N lines */ /* Get the C/N lines */
aconf = find_conf_name(&client_p->localClient->confs, aconf = find_conf_name(&client_p->localClient->confs,
client_p->name, CONF_SERVER); client_p->name, CONF_SERVER);
if (!aconf) if (aconf == NULL)
{ {
sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ADMIN, sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ADMIN,
"Lost connect{} block for %s", get_client_name(client_p, HIDE_IP)); "Lost connect{} block for %s", get_client_name(client_p, HIDE_IP));
sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_OPER, sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_OPER,
"Lost connect{} block for %s", get_client_name(client_p, MASK_IP)); "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; return;
} }
/* Next, send the initial handshake */ /* Next, send the initial handshake */
@ -2213,7 +2227,7 @@ serv_connect_callback(int fd, int status, void *data)
client_p->host); client_p->host);
sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_OPER, sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_OPER,
"%s went dead during handshake", client_p->name); "%s went dead during handshake", client_p->name);
exit_client(client_p, client_p, &me, "Went dead during handshake");
return; return;
} }
@ -2238,8 +2252,8 @@ void cryptlink_init(struct Client *client_p,
int enc_len; int enc_len;
/* get key */ /* get key */
if ( (!ServerInfo.rsa_private_key) || if ((!ServerInfo.rsa_private_key) ||
(!RSA_check_key(ServerInfo.rsa_private_key)) ) (!RSA_check_key(ServerInfo.rsa_private_key)) )
{ {
cryptlink_error(client_p, "SERV", "Invalid RSA private key", cryptlink_error(client_p, "SERV", "Invalid RSA private key",
"Invalid RSA private key"); "Invalid RSA private key");
@ -2304,10 +2318,6 @@ void cryptlink_init(struct Client *client_p,
MyFree(encrypted); MyFree(encrypted);
MyFree(key_to_send); 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)) if (IsDead(client_p))
{ {
cryptlink_error(client_p, "SERV", "Went dead during handshake", 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, void
char *reason, char *client_reason) 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", sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ADMIN, "%s: CRYPTLINK %s error - %s",
get_client_name(client_p, SHOW_IP), type, reason); 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 * If client_reason isn't NULL, then exit the client with the message
* defined in the call. * defined in the call.
*/ */
if (client_reason != NULL) if ((client_reason != NULL) && (!IsDead(client_p)))
{ {
exit_client(client_p, client_p, &me, client_reason); exit_client(client_p, client_p, &me, client_reason);
} }

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -125,10 +125,10 @@ tstats(struct Client *source_p)
sendto_one(source_p, ":%s %d %s :Client Server", sendto_one(source_p, ":%s %d %s :Client Server",
me.name, RPL_STATSDEBUG, source_p->name); 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, me.name, RPL_STATSDEBUG, source_p->name,
dlink_list_length(&lclient_list), (unsigned int)dlink_list_length(&lclient_list),
dlink_list_length(&serv_list)); (unsigned int)dlink_list_length(&serv_list));
sendto_one(source_p, ":%s %d %s :bytes sent %d.%uK %d.%uK", sendto_one(source_p, ":%s %d %s :bytes sent %d.%uK %d.%uK",
me.name, RPL_STATSDEBUG, source_p->name, me.name, RPL_STATSDEBUG, source_p->name,
(int)sp->is_cks, sp->is_cbs, (int)sp->is_sks, sp->is_sbs); (int)sp->is_cks, sp->is_cbs, (int)sp->is_sks, sp->is_sbs);

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #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)", kill_client(client_p, source_p, "%s (Server doesn't exist)",
me.name); me.name);
source_p->flags |= FLAGS_KILLED; SetKilled(source_p);
return exit_client(NULL, source_p, &me, "Ghosted Client"); 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, user->server,
target_p->from->name); target_p->from->name);
source_p->flags |= FLAGS_KILLED; SetKilled(source_p);
return exit_client(source_p, source_p, &me, return exit_client(source_p, source_p, &me,
"USER server wrong direction"); "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", 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, user->server, source_p->name, source_p->username,
source_p->host, source_p->from->name); 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"); 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 /* 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 ** 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)) 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]); sendto_one(source_p, form_str(ERR_USERSDONTMATCH), me.name, parv[0]);
return 0; return 0;
} }
if (parc < 3) if (parc < 3)
{ {
m = buf; 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, /* we may not get these,
* but they shouldnt be in default * but they shouldnt be in default
*/ */
case ' ' : case ' ' :
case '\n' : case '\n' :
case '\r' : 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, sendto_one(source_p, ":%s NOTICE %s :*** Oper privs are %s", me.name,
source_p->name, operprivs); source_p->name, operprivs);
SendMessageFile(source_p, &ConfigFileEntry.opermotd); SendMessageFile(source_p, &ConfigFileEntry.opermotd);
/* autojoin them to a channel if its defined */ /* autojoin them to a channel if its defined */
flags = 0; flags = 0;
if (strlen(ConfigFileEntry.operautojoin) > 0) { if (strlen(ConfigFileEntry.operautojoin) > 0) {

View file

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -61,7 +61,6 @@ unsigned long current_serial=0L;
static void static void
sendto_list_local(dlink_list *list, buf_head_t *linebuf); sendto_list_local(dlink_list *list, buf_head_t *linebuf);
static void static void
sendto_list_local_butone(struct Client *one, dlink_list *list, sendto_list_local_butone(struct Client *one, dlink_list *list,
buf_head_t *linebuf); buf_head_t *linebuf);
@ -175,7 +174,7 @@ _send_linebuf(struct Client *to, buf_head_t *linebuf)
get_sendq(to)); get_sendq(to));
if (IsClient(to)) if (IsClient(to))
to->flags |= FLAGS_SENDQEX; to->flags |= FLAGS_SENDQEX;
dead_link(to); dead_link_on_write(to, 0);
return -1; return -1;
} }
else else
@ -222,23 +221,23 @@ send_linebuf_remote(struct Client *to, struct Client *from,
if (IsServer(from)) if (IsServer(from))
{ {
sendto_realops_flags(FLAGS_ALL, L_ALL, 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); to->name, to->from->name, from->name);
return; return;
} }
sendto_realops_flags(FLAGS_ALL, L_ALL, 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, to->name, to->username, to->host,
from->name, from->username, from->host, from->name, from->username, from->host,
to->from->name); to->from->name);
sendto_server(NULL, to, NULL, NOCAPS, NOCAPS, NOFLAGS, 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, me.name, to->name, me.name, to->name,
to->username, to->vhost, to->from->name); to->username, to->vhost, to->from->name);
to->flags |= FLAGS_KILLED; SetKilled(to);
if (IsPerson(from)) if (IsPerson(from))
sendto_one(from, form_str(ERR_GHOSTEDCLIENT), sendto_one(from, form_str(ERR_GHOSTEDCLIENT),
@ -331,7 +330,7 @@ send_queued_write(int fd, void *data)
} }
else if (retlen <= 0) else if (retlen <= 0)
{ {
dead_link(to); dead_link_on_write(to, errno);
return; return;
} }
} }
@ -380,14 +379,14 @@ send_queued_slink_write(int fd, void *data)
/* If we have a fatal error */ /* If we have a fatal error */
if (!ignoreErrno(errno)) if (!ignoreErrno(errno))
{ {
dead_link(to); dead_link_on_write(to, errno);
return; return;
} }
} }
else if (retlen == 0) else if (retlen == 0)
{ {
/* 0 bytes is an EOF .. */ /* 0 bytes is an EOF .. */
dead_link(to); dead_link_on_write(to, 0);
return; return;
} }
else else
@ -1176,7 +1175,6 @@ sendto_anywhere(struct Client *to, struct Client *from,
linebuf_putmsg(&linebuf, pattern, &args, ":%s ", ID(from)); linebuf_putmsg(&linebuf, pattern, &args, ":%s ", ID(from));
else else
linebuf_putmsg(&linebuf, pattern, &args, ":%s ", from->name); linebuf_putmsg(&linebuf, pattern, &args, ":%s ", from->name);
} }
va_end(args); va_end(args);
@ -1346,7 +1344,8 @@ kill_client(struct Client *client_p,
va_start(args, pattern); 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 :", linebuf_putmsg(&linebuf, pattern, &args, ":%s KILL %s :",
me.name, ID(diedie)); me.name, ID(diedie));
else else
@ -1407,7 +1406,8 @@ kill_client_ll_serv_butone(struct Client *one, struct Client *source_p,
if (one && (client_p == one->from)) if (one && (client_p == one->from))
continue; 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 & if((source_p->lazyLinkClientExists &
client_p->localClient->serverMask) != 0) client_p->localClient->serverMask) != 0)
@ -1420,7 +1420,8 @@ kill_client_ll_serv_butone(struct Client *one, struct Client *source_p,
} }
else 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); send_linebuf(client_p, &linebuf_uid);
else else
send_linebuf(client_p, &linebuf_nick); send_linebuf(client_p, &linebuf_nick);

View file

@ -20,7 +20,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA * 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" #include "stdinc.h"
@ -179,12 +179,14 @@ SSL_smart_shutdown (struct Client *client_p)
int rc; int rc;
rc = 0; rc = 0;
SSL_set_shutdown(client_p->localClient->ssl, SSL_RECEIVED_SHUTDOWN);
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
if ((rc = SSL_shutdown (client_p->localClient->ssl))) if ((rc = SSL_shutdown (client_p->localClient->ssl)))
break; break;
} }
SSL_free(client_p->localClient->ssl);
client_p->localClient->ssl = NULL;
return rc; return rc;
} }