Hybrid RC9 Patches

This commit is contained in:
fishwaldo 2003-03-06 14:01:51 +00:00
parent dbfa476f4f
commit 526d533ec2
37 changed files with 897 additions and 815 deletions

View file

@ -12,6 +12,8 @@ Symbols are:
(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. (HP) - Hybrid Team Patches. (RC6, RC7, RC8) Woo0oo.. Wonder what they broke this time.
(F) - Fix a Umode Problem
(HP) - Hybrid Team Patches (RC9)
* NeoIRCd Version 0.9.5 - 12th Oct, 2002 - Fish * 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

5
TODO
View file

@ -1,4 +1,4 @@
$Id: TODO,v 1.17 2003/03/04 13:05:30 fishwaldo Exp $ $Id: TODO,v 1.18 2003/03/06 14:01:45 fishwaldo Exp $
put back "expire_channels" stuff put back "expire_channels" stuff
@ -18,4 +18,5 @@ POST 1.0
*channel modes in /list *channel modes in /list
*/silence */silence
*/watch */watch
*/knock on +klO chans, but not when banned */knock on +klO chans, but not when banned
*/kill templates (/kill <nick> <code> = /kill <nick> Abusive user

View file

@ -1,4 +1,4 @@
dnl $Id: configure.in,v 1.7 2002/11/04 08:14:00 fishwaldo Exp $ dnl $Id: configure.in,v 1.8 2003/03/06 14:01:46 fishwaldo Exp $
dnl Process this file with autoconf to produce a configure script. dnl Process this file with autoconf to produce a configure script.
dnl AC_INIT(include/class.h) <- what is this ? -TimeMr14C dnl AC_INIT(include/class.h) <- what is this ? -TimeMr14C
@ -19,6 +19,17 @@ AC_PROG_CC
dnl Make sure autoconf doesnt interfere with cflags -jmallett dnl Make sure autoconf doesnt interfere with cflags -jmallett
CFLAGS="$OLD_CFLAGS" CFLAGS="$OLD_CFLAGS"
dnl check for /dev/null so we can use it to hold evil fd's
AC_MSG_CHECKING(for /dev/null)
if test -c /dev/null ; then
AC_DEFINE(PATH_DEVNULL,"/dev/null")
AC_MSG_RESULT(yes)
else
AC_DEFINE(PATH_DEVNULL,"devnull.log")
AC_MSG_RESULT(no - using devnull.log)
fi
dnl Check for various compilers. -jmallett dnl Check for various compilers. -jmallett
SGS=no SGS=no
AC_MSG_CHECKING(if we are using TenDRA or MIPSpro) AC_MSG_CHECKING(if we are using TenDRA or MIPSpro)

19
configure vendored
View file

@ -2012,6 +2012,25 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
CFLAGS="$OLD_CFLAGS" CFLAGS="$OLD_CFLAGS"
echo "$as_me:$LINENO: checking for /dev/null" >&5
echo $ECHO_N "checking for /dev/null... $ECHO_C" >&6
if test -c /dev/null ; then
cat >>confdefs.h <<\_ACEOF
#define PATH_DEVNULL "/dev/null"
_ACEOF
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
else
cat >>confdefs.h <<\_ACEOF
#define PATH_DEVNULL "devnull.log"
_ACEOF
echo "$as_me:$LINENO: result: no - using devnull.log" >&5
echo "${ECHO_T}no - using devnull.log" >&6
fi
SGS=no SGS=no
echo "$as_me:$LINENO: checking if we are using TenDRA or MIPSpro" >&5 echo "$as_me:$LINENO: checking if we are using TenDRA or MIPSpro" >&5
echo $ECHO_N "checking if we are using TenDRA or MIPSpro... $ECHO_C" >&6 echo $ECHO_N "checking if we are using TenDRA or MIPSpro... $ECHO_C" >&6

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.13 2003/01/29 09:28:48 fishwaldo Exp $ * $Id: client.h,v 1.14 2003/03/06 14:01:46 fishwaldo Exp $
*/ */
#ifndef INCLUDED_client_h #ifndef INCLUDED_client_h
@ -231,6 +231,8 @@ struct LocalUser
struct X509 *ssl_cert; /* clients SSL cert info, if ssl client */ struct X509 *ssl_cert; /* clients SSL cert info, if ssl client */
#endif #endif
dlink_node lclient_node;
/* Send and receive linebuf queues .. */ /* Send and receive linebuf queues .. */
buf_head_t buf_sendq; buf_head_t buf_sendq;
buf_head_t buf_recvq; buf_head_t buf_recvq;
@ -518,7 +520,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)) #define IsDefunct(x) ((x)->flags & (FLAGS_DEADSOCKET|FLAGS_CLOSING|FLAGS_KILLED))
/* oper flags */ /* oper flags */
#define MyOper(x) (MyConnect(x) && IsOper(x)) #define MyOper(x) (MyConnect(x) && IsOper(x))
@ -558,11 +560,17 @@ struct LocalUser
#define SetWallops(x) ((x)->umodes |= FLAGS_WALLOP) #define SetWallops(x) ((x)->umodes |= FLAGS_WALLOP)
#define SetCallerId(x) ((x)->umodes |= FLAGS_CALLERID) #define SetCallerId(x) ((x)->umodes |= FLAGS_CALLERID)
#define IsSetCallerId(x) ((x)->umodes & FLAGS_CALLERID) #define IsSetCallerId(x) ((x)->umodes & FLAGS_CALLERID)
#define SetSendQExceeded(x) ((x)->flags |= FLAGS_SENDQEX)
#define IsSendQExceeded(x) ((x)->flags & FLAGS_SENDQEX)
#define SetIpHash(x) ((x)->flags |= FLAGS_IPHASH) #define SetIpHash(x) ((x)->flags |= FLAGS_IPHASH)
#define ClearIpHash(x) ((x)->flags &= ~FLAGS_IPHASH) #define ClearIpHash(x) ((x)->flags &= ~FLAGS_IPHASH)
#define IsIpHash(x) ((x)->flags & FLAGS_IPHASH) #define IsIpHash(x) ((x)->flags & FLAGS_IPHASH)
#define SetPingSent(x) ((x)->flags |= FLAGS_PINGSENT)
#define IsPingSent(x) ((x)->flags & FLAGS_PINGSENT)
#define ClearPingSent(x) ((x)->flags &= ~FLAGS_PINGSENT)
#define SetNeedId(x) ((x)->flags |= FLAGS_NEEDID) #define SetNeedId(x) ((x)->flags |= FLAGS_NEEDID)
#define IsNeedId(x) (((x)->flags & FLAGS_NEEDID) != 0) #define IsNeedId(x) (((x)->flags & FLAGS_NEEDID) != 0)
@ -647,5 +655,7 @@ extern int change_local_nick(struct Client *client_p, struct Client *source_p,
extern void dead_link_on_write(struct Client *client_p, int ierrno); extern void dead_link_on_write(struct Client *client_p, int ierrno);
extern void dead_link_on_read(struct Client *client_p, int error); 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);
extern void exit_aborted_clients(void);
extern void free_exited_clients(void);
#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.4 2003/01/29 09:28:48 fishwaldo Exp $ * $Id: ircd.h,v 1.5 2003/03/06 14:01:46 fishwaldo Exp $
*/ */
#ifndef INCLUDED_ircd_h #ifndef INCLUDED_ircd_h
@ -105,8 +105,7 @@ extern dlink_list lclient_list;
extern dlink_list serv_list; extern dlink_list serv_list;
extern dlink_list global_serv_list; extern dlink_list global_serv_list;
extern dlink_list oper_list; extern dlink_list oper_list;
extern dlink_list dead_list; extern dlink_list closing_list;
extern dlink_list abort_list;
extern dlink_list lazylink_channels; extern dlink_list lazylink_channels;
extern int callbacks_called; extern int callbacks_called;

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_defs.h,v 1.3 2002/09/13 06:50:06 fishwaldo Exp $ * $Id: ircd_defs.h,v 1.4 2003/03/06 14:01:46 fishwaldo Exp $
*/ */
/* /*
@ -60,6 +60,8 @@
#define HELPLEN 400 #define HELPLEN 400
#define LOWEST_SAFE_FD 4 /* skip stdin, stdout, stderr, and profiler */
/* /*
* message return values * message return values
*/ */

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.9 2003/01/29 09:28:48 fishwaldo Exp $ * $Id: s_conf.h,v 1.10 2003/03/06 14:01:46 fishwaldo Exp $
*/ */
#ifndef INCLUDED_s_conf_h #ifndef INCLUDED_s_conf_h
@ -320,7 +320,7 @@ extern struct admin_info AdminInfo; /* defined in ircd.c */
dlink_list temporary_klines; dlink_list temporary_klines;
dlink_list temporary_ip_klines; dlink_list temporary_ip_klines;
extern void clear_ip_hash_table(void); extern void init_ip_hash_table(void);
extern void iphash_stats(struct Client *,struct Client *,int,char **,FBFILE*); extern void iphash_stats(struct Client *,struct Client *,int,char **,FBFILE*);
extern void count_ip_hash(int *, u_long *); extern void count_ip_hash(int *, u_long *);

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.h,v 1.5 2002/10/31 13:01:54 fishwaldo Exp $ * $Id: send.h,v 1.6 2003/03/06 14:01:46 fishwaldo Exp $
*/ */
#ifndef INCLUDED_send_h #ifndef INCLUDED_send_h
@ -48,7 +48,7 @@ unsigned long current_serial;
/* send.c prototypes */ /* send.c prototypes */
extern void send_queued_write(int fd, void *data); extern void send_queued_write(int fd, struct Client *to);
extern void send_queued_slink_write(int fd, void *data); extern void send_queued_slink_write(int fd, void *data);
@ -62,8 +62,10 @@ extern void sendto_channel_butone(struct Client *one,
extern void sendto_one_prefix(struct Client *, struct Client *, extern void sendto_one_prefix(struct Client *, struct Client *,
const char *, ...) AFP(3, 4); const char *, ...) AFP(3, 4);
extern void sendto_common_channels_local(struct Client *, const char *, extern void sendto_common_channels_local(struct Client *,
...) AFP(2, 3); int,
const char *,
...) AFP(3, 4);
extern void sendto_channel_local(int type, struct Channel *, extern void sendto_channel_local(int type, struct Channel *,
const char *, ...) AFP(3, 4); const char *, ...) AFP(3, 4);

View file

@ -92,6 +92,12 @@
/* topiclen */ /* topiclen */
#undef TOPICLEN #undef TOPICLEN
/* EFNET */
#undef EFNET
/* PATH_DEVNULL */
#undef PATH_DEVNULL
/* Define if you have the EVP_bf_cfb function. */ /* Define if you have the EVP_bf_cfb function. */
#undef HAVE_EVP_BF_CFB #undef HAVE_EVP_BF_CFB

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: tools.h,v 1.5 2002/10/31 13:01:54 fishwaldo Exp $ * $Id: tools.h,v 1.6 2003/03/06 14:01:46 fishwaldo Exp $
*/ */
#ifndef __TOOLS_H__ #ifndef __TOOLS_H__
@ -186,7 +186,8 @@ dlinkDelete(dlink_node *m, dlink_list *list)
* output - pointer to link or NULL if not found * output - pointer to link or NULL if not found
* side effects - Look for ptr in the linked listed pointed to by link. * side effects - Look for ptr in the linked listed pointed to by link.
*/ */
extern inline dlink_node *dlinkFind(dlink_list *list, void * data ) extern inline dlink_node *
dlinkFind(dlink_list *list, void * data )
{ {
dlink_node *ptr; dlink_node *ptr;
@ -237,21 +238,10 @@ dlinkFindDelete(dlink_list *list, void *data)
{ {
dlink_node *m; dlink_node *m;
DLINK_FOREACH(m, list->head) m = dlinkFind(list, data);
{ if (m)
if(m->data != data) dlinkDelete(m, list);
continue; return(m);
if (m->next != NULL)
m->next->prev = m->prev;
else
list->tail = m->prev;
m->next = m->prev = NULL;
list->length--;
return m;
}
return(NULL);
} }
#endif /* __GNUC__ */ #endif /* __GNUC__ */

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_kick.c,v 1.7 2002/09/13 06:50:07 fishwaldo Exp $ * $Id: m_kick.c,v 1.8 2003/03/06 14:01:47 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
@ -59,7 +59,7 @@ _moddeinit(void)
mod_del_cmd(&kick_msgtab); mod_del_cmd(&kick_msgtab);
} }
const char *_version = "$Revision: 1.7 $"; const char *_version = "$Revision: 1.8 $";
#endif #endif
/* /*
** m_kick ** m_kick
@ -68,10 +68,9 @@ const char *_version = "$Revision: 1.7 $";
** parv[2] = client to kick ** parv[2] = client to kick
** parv[3] = kick comment ** parv[3] = kick comment
*/ */
static void m_kick(struct Client *client_p, static void
struct Client *source_p, m_kick(struct Client *client_p, struct Client *source_p,
int parc, int parc, char *parv[])
char *parv[])
{ {
struct Client *who; struct Client *who;
struct Channel *chptr; struct Channel *chptr;
@ -234,17 +233,17 @@ static void m_kick(struct Client *client_p,
":%s KICK %s %s :%s", ":%s KICK %s %s :%s",
parv[0], chptr->chname, parv[0], chptr->chname,
who->name, comment); who->name, comment);
remove_user_from_channel(chptr, who); if (!IsDefunct(who))
remove_user_from_channel(chptr, who);
} }
else else
sendto_one(source_p, form_str(ERR_USERNOTINCHANNEL), sendto_one(source_p, form_str(ERR_USERNOTINCHANNEL),
me.name, parv[0], user, name); me.name, parv[0], user, name);
} }
static void ms_kick(struct Client *client_p, static void
struct Client *source_p, ms_kick(struct Client *client_p, struct Client *source_p,
int parc, int parc, char *parv[])
char *parv[])
{ {
if (*parv[2] == '\0') if (*parv[2] == '\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: m_kill.c,v 1.5 2002/09/13 16:30:04 fishwaldo Exp $ * $Id: m_kill.c,v 1.6 2003/03/06 14:01:47 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
@ -64,7 +64,7 @@ _moddeinit(void)
mod_del_cmd(&kill_msgtab); mod_del_cmd(&kill_msgtab);
} }
const char *_version = "$Revision: 1.5 $"; const char *_version = "$Revision: 1.6 $";
#endif #endif
/* /*
** mo_kill ** mo_kill
@ -72,8 +72,9 @@ const char *_version = "$Revision: 1.5 $";
** parv[1] = kill victim ** parv[1] = kill victim
** parv[2] = kill path ** parv[2] = kill path
*/ */
static void mo_kill(struct Client *client_p, struct Client *source_p, static void
int parc, char *parv[]) mo_kill(struct Client *client_p, struct Client *source_p,
int parc, char *parv[])
{ {
struct Client* target_p; struct Client* target_p;
const char* inpath = client_p->name; const char* inpath = client_p->name;
@ -170,8 +171,9 @@ static void mo_kill(struct Client *client_p, struct Client *source_p,
* parv[1] = kill victim * parv[1] = kill victim
* parv[2] = kill path and reason * parv[2] = kill path and reason
*/ */
static void ms_kill(struct Client *client_p, struct Client *source_p, static void
int parc, char *parv[]) ms_kill(struct Client *client_p, struct Client *source_p,
int parc, char *parv[])
{ {
struct Client *target_p; struct Client *target_p;
char *user; char *user;
@ -281,7 +283,7 @@ static void ms_kill(struct Client *client_p, struct Client *source_p,
relay_kill(client_p, source_p, target_p, path, reason); relay_kill(client_p, source_p, target_p, path, reason);
/* FLAGS_KILLED prevents a quit being sent out */ /* FLAGS_KILLED prevents a quit being sent out */
target_p->flags |= FLAGS_KILLED; SetKilled(target_p);
/* reason comes supplied with its own ()'s */ /* reason comes supplied with its own ()'s */
if(ConfigServerHide.hide_servers && IsServer(source_p)) if(ConfigServerHide.hide_servers && IsServer(source_p))
@ -292,10 +294,9 @@ static void ms_kill(struct Client *client_p, struct Client *source_p,
exit_client(client_p, target_p, source_p, buf); exit_client(client_p, target_p, source_p, buf);
} }
static void relay_kill(struct Client *one, struct Client *source_p, static void
struct Client *target_p, relay_kill(struct Client *one, struct Client *source_p,
const char *inpath, struct Client *target_p, const char *inpath, const char *reason)
const char *reason)
{ {
dlink_node *ptr; dlink_node *ptr;
struct Client *client_p; struct Client *client_p;

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_nick.c,v 1.20 2002/10/31 13:01:57 fishwaldo Exp $ * $Id: m_nick.c,v 1.21 2003/03/06 14:01:48 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
@ -97,7 +97,7 @@ _moddeinit(void)
mod_del_cmd(&client_msgtab); mod_del_cmd(&client_msgtab);
} }
const char *_version = "$Revision: 1.20 $"; const char *_version = "$Revision: 1.21 $";
#endif #endif
/* /*
@ -199,8 +199,9 @@ mr_nick(struct Client *client_p, struct Client *source_p,
* parv[0] = sender prefix * parv[0] = sender prefix
* parv[1] = nickname * parv[1] = nickname
*/ */
static void m_nick(struct Client *client_p, struct Client *source_p, static void
int parc, char *parv[]) m_nick(struct Client *client_p, struct Client *source_p,
int parc, char *parv[])
{ {
char nick[NICKLEN]; char nick[NICKLEN];
struct Client *target_p; struct Client *target_p;
@ -476,7 +477,7 @@ ms_client(struct Client *client_p, struct Client *source_p,
ServerStats->is_kill++; ServerStats->is_kill++;
target_p->flags |= FLAGS_KILLED; SetKilled(target_p);
exit_client(client_p, target_p, &me, "ID Collision"); exit_client(client_p, target_p, &me, "ID Collision");
return; return;
} }
@ -511,8 +512,9 @@ ms_client(struct Client *client_p, struct Client *source_p,
* side effects - if nickname is erroneous, or a different length to * side effects - if nickname is erroneous, or a different length to
* truncated nickname, return 1 * truncated nickname, return 1
*/ */
static int check_clean_nick(struct Client *client_p, struct Client *source_p, static int
char *nick, char *newnick, char *server) check_clean_nick(struct Client *client_p, struct Client *source_p,
char *nick, char *newnick, char *server)
{ {
/* the old code did some wacky stuff here, if the nick is invalid, kill it /* the old code did some wacky stuff here, if the nick is invalid, kill it
* and dont bother messing at all * and dont bother messing at all
@ -534,14 +536,14 @@ static int check_clean_nick(struct Client *client_p, struct Client *source_p,
kill_client_ll_serv_butone(client_p, source_p, kill_client_ll_serv_butone(client_p, source_p,
"%s (Bad Nickname)", "%s (Bad Nickname)",
me.name); me.name);
source_p->flags |= FLAGS_KILLED; SetKilled(source_p);
exit_client(client_p, source_p, &me, "Bad Nickname"); exit_client(client_p, source_p, &me, "Bad Nickname");
} }
return 1; return (1);
} }
return 0; return (0);
} }
/* check_clean_user() /* check_clean_user()
@ -567,7 +569,7 @@ check_clean_user(struct Client *client_p, char *nick,
sendto_one(client_p, ":%s KILL %s :%s (Bad Username)", sendto_one(client_p, ":%s KILL %s :%s (Bad Username)",
me.name, nick, me.name); me.name, nick, me.name);
return 1; return (1);
} }
if(!clean_user_name(user)) if(!clean_user_name(user))
@ -575,7 +577,7 @@ check_clean_user(struct Client *client_p, char *nick,
"Bad Username: %s Nickname: %s From: %s(via %s)", "Bad Username: %s Nickname: %s From: %s(via %s)",
user, nick, server, client_p->name); user, nick, server, client_p->name);
return 0; return (0);
} }
/* check_clean_host() /* check_clean_host()
@ -601,7 +603,7 @@ check_clean_host(struct Client *client_p, char *nick,
sendto_one(client_p, ":%s KILL %s :%s (Bad Hostname)", sendto_one(client_p, ":%s KILL %s :%s (Bad Hostname)",
me.name, nick, me.name); me.name, nick, me.name);
return 1; return (1);
} }
if(!clean_host_name(host)) if(!clean_host_name(host))
@ -609,7 +611,7 @@ check_clean_host(struct Client *client_p, char *nick,
"Bad Hostname: %s Nickname: %s From: %s(via %s)", "Bad Hostname: %s Nickname: %s From: %s(via %s)",
host, nick, server, client_p->name); host, nick, server, client_p->name);
return 0; return (0);
} }
/* clean_nick_name() /* clean_nick_name()
@ -623,21 +625,21 @@ clean_nick_name(char *nick)
{ {
assert(nick); assert(nick);
if(nick == NULL) if(nick == NULL)
return 0; return (0);
/* nicks cant start with a digit or - or be 0 length */ /* nicks cant start with a digit or - or be 0 length */
/* This closer duplicates behaviour of hybrid-6 */ /* This closer duplicates behaviour of hybrid-6 */
if (*nick == '-' || IsDigit(*nick) || *nick == '\0') if (*nick == '-' || IsDigit(*nick) || *nick == '\0')
return 0; return (0);
for(; *nick; nick++) for(; *nick; nick++)
{ {
if(!IsNickChar(*nick)) if(!IsNickChar(*nick))
return 0; return (0);
} }
return 1; return (1);
} }
/* clean_user_name() /* clean_user_name()
@ -762,7 +764,7 @@ nick_from_server(struct Client *client_p, struct Client *source_p, int parc,
if(irccmp(parv[0], nick)) if(irccmp(parv[0], nick))
source_p->tsinfo = newts ? newts : CurrentTime; source_p->tsinfo = newts ? newts : CurrentTime;
sendto_common_channels_local(source_p, ":%s!%s@%s NICK :%s", sendto_common_channels_local(source_p, 1, ":%s!%s@%s NICK :%s",
source_p->name,source_p->username,source_p->vhost, source_p->name,source_p->username,source_p->vhost,
nick); nick);
@ -886,7 +888,7 @@ perform_nick_collides(struct Client *source_p, struct Client *client_p,
sendto_one(target_p, form_str(ERR_NICKCOLLISION), sendto_one(target_p, form_str(ERR_NICKCOLLISION),
me.name, target_p->name, target_p->name); me.name, target_p->name, target_p->name);
target_p->flags |= FLAGS_KILLED; SetKilled(target_p);
exit_client(client_p, target_p, &me, "Nick collision (new)"); exit_client(client_p, target_p, &me, "Nick collision (new)");
return 0; return 0;
} }
@ -930,8 +932,8 @@ perform_nick_collides(struct Client *source_p, struct Client *client_p,
"%s (Nick collision (new))", "%s (Nick collision (new))",
me.name); me.name);
target_p->flags |= FLAGS_KILLED; SetKilled(target_p);
(void)exit_client(client_p, target_p, &me, "Nick collision"); exit_client(client_p, target_p, &me, "Nick collision");
if(parc == 11) if(parc == 11)
nick_from_server(client_p,source_p,parc,parv,newts,nick); nick_from_server(client_p,source_p,parc,parv,newts,nick);
@ -970,9 +972,9 @@ perform_nick_collides(struct Client *source_p, struct Client *client_p,
"%s (Nick change collision)", "%s (Nick change collision)",
me.name); me.name);
target_p->flags |= FLAGS_KILLED; SetKilled(target_p);
exit_client(NULL, target_p, &me, "Nick collision(new)"); exit_client(NULL, target_p, &me, "Nick collision(new)");
source_p->flags |= FLAGS_KILLED; SetKilled(source_p);
exit_client(client_p, source_p, &me, "Nick collision(old)"); exit_client(client_p, source_p, &me, "Nick collision(old)");
return 0; return 0;
} }
@ -1002,7 +1004,7 @@ perform_nick_collides(struct Client *source_p, struct Client *client_p,
"%s (Nick change collision)", "%s (Nick change collision)",
me.name); me.name);
source_p->flags |= FLAGS_KILLED; SetKilled(source_p);
if(sameuser) if(sameuser)
exit_client(client_p, source_p, &me, "Nick collision(old)"); exit_client(client_p, source_p, &me, "Nick collision(old)");
@ -1031,8 +1033,8 @@ perform_nick_collides(struct Client *source_p, struct Client *client_p,
sendto_one(target_p, form_str(ERR_NICKCOLLISION), sendto_one(target_p, form_str(ERR_NICKCOLLISION),
me.name, target_p->name, target_p->name); me.name, target_p->name, target_p->name);
target_p->flags |= FLAGS_KILLED; SetKilled(target_p);
(void)exit_client(client_p, target_p, &me, "Nick collision"); exit_client(client_p, target_p, &me, "Nick collision");
} }
} }

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.12 2003/01/29 09:28:49 fishwaldo Exp $ * $Id: m_server.c,v 1.13 2003/03/06 14:01:48 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
@ -67,7 +67,7 @@ _moddeinit(void)
{ {
mod_del_cmd(&server_msgtab); mod_del_cmd(&server_msgtab);
} }
const char *_version = "$Revision: 1.12 $"; const char *_version = "$Revision: 1.13 $";
#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, client_p, &me, "No matching hub_mask."); exit_client(NULL, source_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_squit.c,v 1.2 2002/09/13 06:50:07 fishwaldo Exp $ * $Id: m_squit.c,v 1.3 2003/03/06 14:01:49 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
@ -58,7 +58,7 @@ _moddeinit(void)
{ {
mod_del_cmd(&squit_msgtab); mod_del_cmd(&squit_msgtab);
} }
const char *_version = "$Revision: 1.2 $"; const char *_version = "$Revision: 1.3 $";
#endif #endif
struct squit_parms struct squit_parms
{ {
@ -131,35 +131,35 @@ static void ms_squit(struct Client *client_p, struct Client *source_p,
char *comment = (parc > 2 && parv[2]) ? parv[2] : client_p->name; char *comment = (parc > 2 && parv[2]) ? parv[2] : client_p->name;
if(parc < 2) if(parc < 2)
{
exit_client(client_p, client_p, source_p, comment);
return;
}
if((found_squit = find_squit(client_p, source_p, parv[1])))
{
/*
** Notify all opers, if my local link is remotely squitted
*/
if (MyConnect(found_squit->target_p))
{ {
exit_client(client_p, client_p, source_p, comment); sendto_wallops_flags(FLAGS_WALLOP, &me,
return; "Remote SQUIT %s from %s (%s)",
} found_squit->server_name,
source_p->name, comment);
if( (found_squit = find_squit(client_p, source_p, parv[1])) )
{ sendto_server(NULL, NULL, NULL, NOCAPS, NOCAPS, NOFLAGS,
/* ":%s WALLOPS :Remote SQUIT %s from %s (%s)",
** Notify all opers, if my local link is remotely squitted me.name, found_squit->server_name,
*/ source_p->name, comment);
if (MyConnect(found_squit->target_p))
{ ilog(L_TRACE, "SQUIT From %s : %s (%s)", parv[0],
sendto_wallops_flags(FLAGS_WALLOP, &me, found_squit->server_name, comment);
"Remote SQUIT %s from %s (%s)",
found_squit->server_name,
source_p->name, comment);
sendto_server(NULL, NULL, NULL, NOCAPS, NOCAPS, NOFLAGS,
":%s WALLOPS :Remote SQUIT %s from %s (%s)",
me.name, found_squit->server_name,
source_p->name, comment);
ilog(L_TRACE, "SQUIT From %s : %s (%s)", parv[0],
found_squit->server_name, comment);
}
exit_client(client_p, found_squit->target_p, source_p, comment);
return;
} }
exit_client(client_p, found_squit->target_p, source_p, comment);
return;
}
} }
@ -171,9 +171,8 @@ static void ms_squit(struct Client *client_p, struct Client *source_p,
* output - pointer to struct containing found squit or none if not found * output - pointer to struct containing found squit or none if not found
* side effects - * side effects -
*/ */
static struct squit_parms *find_squit(struct Client *client_p, static struct squit_parms *
struct Client *source_p, find_squit(struct Client *client_p, struct Client *source_p, char *server)
char *server)
{ {
static struct squit_parms found_squit; static struct squit_parms found_squit;
static struct Client *target_p; static struct Client *target_p;
@ -232,5 +231,5 @@ static struct squit_parms *find_squit(struct Client *client_p,
if(found_squit.target_p != NULL) if(found_squit.target_p != NULL)
return &found_squit; return &found_squit;
else else
return( NULL ); 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: m_close.c,v 1.4 2002/09/19 05:41:10 fishwaldo Exp $ * $Id: m_close.c,v 1.5 2003/03/06 14:01:46 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
@ -54,7 +54,7 @@ _moddeinit(void)
mod_del_cmd(&close_msgtab); mod_del_cmd(&close_msgtab);
} }
const char *_version = "$Revision: 1.4 $"; const char *_version = "$Revision: 1.5 $";
#endif #endif
/* /*
* mo_close - CLOSE message handler * mo_close - CLOSE message handler
@ -83,7 +83,11 @@ mo_close(struct Client *client_p, struct Client *source_p,
#endif #endif
sendto_one(source_p, form_str(RPL_CLOSING), me.name, parv[0], sendto_one(source_p, form_str(RPL_CLOSING), me.name, parv[0],
get_client_name(target_p, SHOW_IP), target_p->status); get_client_name(target_p, SHOW_IP), target_p->status);
(void)exit_client(target_p, target_p, target_p, "Oper Closing"); /*
* exit here is safe, because it is guaranteed not to be source_p
* because it is unregistered and source_p is an oper.
*/
exit_client(target_p, target_p, target_p, "Oper Closing");
closed++; closed++;
} }
sendto_one(source_p, form_str(RPL_CLOSEEND), me.name, parv[0], closed); sendto_one(source_p, form_str(RPL_CLOSEEND), me.name, parv[0], closed);

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_join.c,v 1.12 2002/10/31 13:01:55 fishwaldo Exp $ * $Id: m_join.c,v 1.13 2003/03/06 14:01:46 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
@ -64,7 +64,7 @@ _moddeinit(void)
{ {
mod_del_cmd(&join_msgtab); mod_del_cmd(&join_msgtab);
} }
const char *_version = "$Revision: 1.12 $"; const char *_version = "$Revision: 1.13 $";
#endif #endif
static void do_join_0(struct Client *client_p, struct Client *source_p); static void do_join_0(struct Client *client_p, struct Client *source_p);
@ -438,6 +438,7 @@ do_join_0(struct Client *client_p, struct Client *source_p)
sendto_channel_local(ALL_MEMBERS,chptr, ":%s!%s@%s PART %s", sendto_channel_local(ALL_MEMBERS,chptr, ":%s!%s@%s PART %s",
source_p->name, source_p->username, source_p->name, source_p->username,
source_p->vhost, chptr->chname); source_p->vhost, chptr->chname);
remove_user_from_channel(chptr, source_p); if (!IsDefunct(source_p))
remove_user_from_channel(chptr, source_p);
} }
} }

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: m_svscmds.c,v 1.9 2002/10/31 13:01:56 fishwaldo Exp $ * $Id: m_svscmds.c,v 1.10 2003/03/06 14:01:46 fishwaldo Exp $
*/ */
/* List of ircd includes from ../include/ */ /* List of ircd includes from ../include/ */
@ -134,7 +134,7 @@ _moddeinit(void)
/* When we last modified the file (shown in /modlist), this is usually: /* When we last modified the file (shown in /modlist), this is usually:
*/ */
const char *_version = "$Revision: 1.9 $"; const char *_version = "$Revision: 1.10 $";
#endif #endif
/* /*
@ -206,7 +206,7 @@ static void ms_svsnick(struct Client *client_p, struct Client *source_p,
return; return;
} }
target_p->tsinfo = parv[4] ? atol(parv[3]) : CurrentTime; target_p->tsinfo = parv[4] ? atol(parv[3]) : CurrentTime;
sendto_common_channels_local(target_p, ":%s!%s@%s NICK :%s", target_p->name, target_p->username, target_p->vhost, parv[2]); sendto_common_channels_local(target_p, 1, ":%s!%s@%s NICK :%s", target_p->name, target_p->username, target_p->vhost, parv[2]);
/* send it to the other servers */ /* send it to the other servers */
if (target_p->user) { if (target_p->user) {
add_history(target_p, 1); add_history(target_p, 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: m_whois.c,v 1.11 2002/11/20 14:13:57 fishwaldo Exp $ * $Id: m_whois.c,v 1.12 2003/03/06 14:01:47 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
@ -76,7 +76,7 @@ _moddeinit(void)
mod_del_cmd(&whois_msgtab); mod_del_cmd(&whois_msgtab);
} }
const char *_version = "$Revision: 1.11 $"; const char *_version = "$Revision: 1.12 $";
#endif #endif
/* /*
** m_whois ** m_whois
@ -238,9 +238,7 @@ do_whois(struct Client *client_p, struct Client *source_p,
found = global_whois(source_p,nick,wilds,glob); found = global_whois(source_p,nick,wilds,glob);
} }
if(found) if (!found)
sendto_one(source_p, form_str(RPL_ENDOFWHOIS), me.name, parv[0], parv[1]);
else
sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, parv[0], nick); sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, parv[0], nick);
return (0); return (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: channel.c,v 1.16 2003/01/29 09:28:49 fishwaldo Exp $ * $Id: channel.c,v 1.17 2003/03/06 14:01:49 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
@ -1165,7 +1165,9 @@ is_voiced(struct Channel *chptr, struct Client *who)
int int
can_send(struct Channel *chptr, struct Client *source_p) can_send(struct Channel *chptr, struct Client *source_p)
{ {
if(MyClient(source_p) && find_channel_resv(chptr->chname) && !(IsOper(source_p)) && ConfigChannel.oper_pass_resv) if(MyClient(source_p) &&
(find_channel_resv(chptr->chname) &&
!(IsOper(source_p)) && ConfigChannel.oper_pass_resv))
return (CAN_SEND_NO); return (CAN_SEND_NO);
if (is_any_op(chptr, source_p)) if (is_any_op(chptr, source_p))

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.21 2003/01/29 09:28:49 fishwaldo Exp $ * $Id: channel_mode.c,v 1.22 2003/03/06 14:01:49 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
@ -872,7 +872,9 @@ chm_ban(struct Client *client_p, struct Client *source_p,
* I'd like to see this hack go away in the future. * I'd like to see this hack go away in the future.
*/ */
if(del_id(chptr, raw_mask, CHFL_BAN)) if(del_id(chptr, raw_mask, CHFL_BAN))
mask = raw_mask; mask = raw_mask;
else
del_id(chptr, mask, CHFL_BAN);
#endif #endif
mode_changes[mode_count].letter = c; mode_changes[mode_count].letter = c;
@ -1645,6 +1647,9 @@ chm_key(struct Client *client_p, struct Client *source_p,
if (!(*chptr->mode.key)) if (!(*chptr->mode.key))
return; return;
if (parc > *parn)
(*parn)++;
*chptr->mode.key = 0; *chptr->mode.key = 0;
mode_changes[mode_count].letter = c; mode_changes[mode_count].letter = c;

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.12 2003/01/29 09:28:49 fishwaldo Exp $ * $Id: client.c,v 1.13 2003/03/06 14:01:50 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
#include "config.h" #include "config.h"
@ -57,8 +57,6 @@
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_local_client(struct Client *client_p);
static EVH check_pings; static EVH check_pings;
@ -69,6 +67,7 @@ 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
@ -84,7 +83,6 @@ static void client_heap_gc(void *unused)
BlockHeapGarbageCollect(lclient_heap); BlockHeapGarbageCollect(lclient_heap);
} }
/* /*
* init_client * init_client
* *
@ -92,7 +90,8 @@ static void client_heap_gc(void *unused)
* output - NONE * output - NONE
* side effects - initialize client free memory * side effects - initialize client free memory
*/ */
void init_client(void) void
init_client(void)
{ {
remote_client_count = 0; remote_client_count = 0;
local_client_count = 0; local_client_count = 0;
@ -101,9 +100,8 @@ void init_client(void)
* Every 30 seconds is plenty -- db * Every 30 seconds is plenty -- db
*/ */
client_heap = BlockHeapCreate(sizeof(struct Client), CLIENT_HEAP_SIZE); client_heap = BlockHeapCreate(sizeof(struct Client), CLIENT_HEAP_SIZE);
lclient_heap = BlockHeapCreate(sizeof(struct LocalUser), LCLIENT_HEAP_SIZE); lclient_heap = BlockHeapCreate(sizeof(struct LocalUser), LCLIENT_HEAP_SIZE);
eventAddIsh("check_pings", check_pings, NULL, 30); eventAddIsh("check_pings", check_pings, NULL, 30);
eventAddIsh("free_exited_clients", &free_exited_clients, NULL, 4);
eventAddIsh("client_heap_gc", client_heap_gc, NULL, 30); eventAddIsh("client_heap_gc", client_heap_gc, NULL, 30);
} }
@ -117,7 +115,8 @@ void init_client(void)
* associated with the client defined by * associated with the client defined by
* 'from'). ('from' is a local client!!). * 'from'). ('from' is a local client!!).
*/ */
struct Client* make_client(struct Client* from) struct Client*
make_client(struct Client* from)
{ {
struct Client* client_p = NULL; struct Client* client_p = NULL;
struct LocalUser *localClient; struct LocalUser *localClient;
@ -175,11 +174,18 @@ struct Client* make_client(struct Client* from)
return client_p; return client_p;
} }
static void void
free_local_client(struct Client *client_p) 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)) 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.
*/ */
@ -200,25 +206,17 @@ free_local_client(struct Client *client_p)
if (client_p->localClient->fd >= 0) if (client_p->localClient->fd >= 0)
fd_close(client_p->localClient->fd); fd_close(client_p->localClient->fd);
linebuf_donebuf(&client_p->localClient->buf_recvq);
linebuf_donebuf(&client_p->localClient->buf_sendq);
BlockHeapFree(lclient_heap, client_p->localClient); 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);
} }
@ -267,8 +265,8 @@ check_pings(void *notused)
static void static void
check_pings_list(dlink_list *list) check_pings_list(dlink_list *list)
{ {
char scratch[32]; /* way too generous but... */ char scratch[32]; /* way too generous but... */
struct Client *client_p; /* current local client_p being examined */ struct Client *client_p; /* current local client_p being examined */
int ping = 0; /* ping time value from client */ int ping = 0; /* ping time value from client */
dlink_node *ptr, *next_ptr; dlink_node *ptr, *next_ptr;
@ -285,6 +283,7 @@ check_pings_list(dlink_list *list)
/* Ignore it, its been exited already */ /* Ignore it, its been exited already */
continue; continue;
} }
if (IsPerson(client_p)) if (IsPerson(client_p))
{ {
if(!IsExemptKline(client_p) && if(!IsExemptKline(client_p) &&
@ -326,7 +325,7 @@ check_pings_list(dlink_list *list)
* and it has a ping time, then close its connection. * 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))) IsPingSent(client_p)))
{ {
if (IsServer(client_p) || IsConnecting(client_p) || if (IsServer(client_p) || IsConnecting(client_p) ||
IsHandshake(client_p)) IsHandshake(client_p))
@ -347,15 +346,14 @@ check_pings_list(dlink_list *list)
(void)exit_client(client_p, client_p, &me, scratch); (void)exit_client(client_p, client_p, &me, scratch);
continue; continue;
} }
else if ((client_p->flags & FLAGS_PINGSENT) == 0) else if (!IsPingSent(client_p))
{ {
/* /*
* if we havent PINGed the connection and we havent * if we havent PINGed the connection and we havent
* heard from it in a while, PING it to make sure * heard from it in a while, PING it to make sure
* it is still alive. * it is still alive.
*/ */
client_p->flags |= FLAGS_PINGSENT; SetPingSent(client_p);
/* not nice but does the job */
client_p->lasttime = CurrentTime - ping; client_p->lasttime = CurrentTime - ping;
sendto_one(client_p, "PING :%s", me.name); sendto_one(client_p, "PING :%s", me.name);
} }
@ -415,6 +413,11 @@ check_klines(void)
if (IsMe(client_p)) if (IsMe(client_p))
continue; continue;
/* If a client is already being exited
*/
if (IsDead(client_p))
continue;
/* if there is a returned struct ConfItem then kill it */ /* if there is a returned struct ConfItem then kill it */
if ((aconf = find_dline_conf(&client_p->localClient->ip, if ((aconf = find_dline_conf(&client_p->localClient->ip,
@ -575,12 +578,13 @@ check_klines(void)
* output - NONE * output - NONE
* side effects - * side effects -
*/ */
static void update_client_exit_stats(struct Client* client_p) static void
update_client_exit_stats(struct Client* client_p)
{ {
if (IsServer(client_p)) if (IsServer(client_p))
{ {
--Count.server; --Count.server;
sendto_realops_flags(FLAGS_EXTERNAL, L_ALL, sendto_realops_flags(FLAGS_EXTERNAL|FLAGS_REMOTE, L_ALL,
"Server %s split from %s", "Server %s split from %s",
client_p->name, client_p->servptr->name); client_p->name, client_p->servptr->name);
} }
@ -611,6 +615,7 @@ release_client_state(struct Client* client_p)
{ {
free_user(client_p->user, client_p); /* try this here */ free_user(client_p->user, client_p); /* try this here */
} }
if (client_p->serv != NULL) if (client_p->serv != NULL)
{ {
if (client_p->serv->user != NULL) if (client_p->serv->user != NULL)
@ -633,6 +638,9 @@ remove_client_from_list(struct Client* client_p)
if(client_p == NULL) if(client_p == NULL)
return; return;
/* XXX try without this as well */
#if 1
/* A client made with make_client() /* A client made with make_client()
* is on the unknown_list until removed. * is on the unknown_list until removed.
* If it =does= happen to exit before its removed from that list * If it =does= happen to exit before its removed from that list
@ -643,6 +651,7 @@ remove_client_from_list(struct Client* client_p)
{ {
return; return;
} }
#endif
if (client_p->prev) if (client_p->prev)
client_p->prev->next = client_p->next; client_p->prev->next = client_p->next;
@ -856,8 +865,8 @@ get_client_name(struct Client* client, int showip)
return client->name; return client->name;
} }
static void void
free_exited_clients(void *unused) free_exited_clients(void)
{ {
dlink_node *ptr, *next; dlink_node *ptr, *next;
struct Client *target_p; struct Client *target_p;
@ -874,8 +883,6 @@ 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);
@ -894,6 +901,7 @@ exit_one_client(struct Client *client_p, struct Client *source_p,
struct Client* target_p; struct Client* target_p;
dlink_node *lp; dlink_node *lp;
dlink_node *next_lp; dlink_node *next_lp;
dlink_node *m;
if (IsServer(source_p)) if (IsServer(source_p))
{ {
@ -904,7 +912,10 @@ exit_one_client(struct Client *client_p, struct Client *source_p,
ts_warn("server %s without servptr!", source_p->name); ts_warn("server %s without servptr!", source_p->name);
if(!IsMe(source_p)) if(!IsMe(source_p))
remove_server_from_list(source_p); {
if ((m = dlinkFindDelete(&global_serv_list, source_p)) != NULL)
free_dlink_node(m);
}
} }
else if (source_p->servptr && source_p->servptr->serv) else if (source_p->servptr && source_p->servptr->serv)
{ {
@ -951,9 +962,10 @@ exit_one_client(struct Client *client_p, struct Client *source_p,
} }
target_p = source_p->from; 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 &&
(!IsKilled(source_p))) !IsMe(target_p) && !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... */
{ {
@ -973,11 +985,10 @@ exit_one_client(struct Client *client_p, struct Client *source_p,
** that the client can show the "**signoff" message). ** that the client can show the "**signoff" message).
** (Note: The notice is to the local clients *only*) ** (Note: The notice is to the local clients *only*)
*/ */
sendto_common_channels_local(source_p, ":%s!%s@%s QUIT :%s", sendto_common_channels_local(source_p, 0,
source_p->name, ":%s!%s@%s QUIT :%s",
source_p->username, source_p->name, source_p->username,
source_p->vhost, source_p->vhost, comment);
comment);
DLINK_FOREACH_SAFE(lp, next_lp, source_p->user->channel.head) DLINK_FOREACH_SAFE(lp, next_lp, source_p->user->channel.head)
{ {
@ -989,9 +1000,9 @@ exit_one_client(struct Client *client_p, struct Client *source_p,
/* Clean up invitefield */ /* Clean up invitefield */
DLINK_FOREACH_SAFE(lp, next_lp, source_p->user->invited.head) DLINK_FOREACH_SAFE(lp, next_lp, source_p->user->invited.head)
{ {
del_invite(lp->data, source_p); del_invite(lp->data, source_p);
} }
/* Clean up allow lists */ /* Clean up allow lists */
del_all_accepts(source_p); del_all_accepts(source_p);
@ -1015,8 +1026,9 @@ exit_one_client(struct Client *client_p, struct Client *source_p,
/* Check to see if the client isn't already on the dead list */ /* 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_list */ /* add to dead client dlist */
lp = make_dlink_node(); lp = make_dlink_node();
SetDead(source_p);
dlinkAdd(source_p, lp, &dead_list); dlinkAdd(source_p, lp, &dead_list);
} }
@ -1148,29 +1160,34 @@ remove_dependents(struct Client* client_p,
void void
dead_link_on_write(struct Client *client_p, int ierrno) dead_link_on_write(struct Client *client_p, int ierrno)
{ {
dlink_node *m;
const char *notice; const char *notice;
if(IsDefunct(client_p)) if(IsDefunct(client_p))
return; return;
SetDead(client_p);
if(client_p->flags & FLAGS_SENDQEX) linebuf_donebuf(&client_p->localClient->buf_recvq);
linebuf_donebuf(&client_p->localClient->buf_sendq);
if (IsSendQExceeded(client_p))
notice = "Max SendQ exceeded"; notice = "Max SendQ exceeded";
else else
notice = "Write error: connection closed"; notice = "Write error: connection closed";
if (!IsPerson(client_p) && !IsUnknown(client_p)) if (!IsPerson(client_p) && !IsUnknown(client_p) && !IsClosing(client_p))
{ {
sendto_realops_flags(FLAGS_ALL, L_ADMIN, sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ADMIN,
"Closing link to %s: %s", "Closing link to %s: %s",
get_client_name(client_p, HIDE_IP), notice); get_client_name(client_p, HIDE_IP), notice);
sendto_realops_flags(FLAGS_ALL, L_OPER, sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_OPER,
"Closing link to %s: %s", "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", Debug((DEBUG_ERROR, "Closing link to %s: %s", get_client_name(client_p, HIDE_IP), notice));
get_client_name(client_p, HIDE_IP), notice)); assert(dlinkFind(&abort_list, client_p) == NULL);
exit_client(client_p, client_p, &me, "Closing link"); m = make_dlink_node();
dlinkAdd(client_p, m, &abort_list);
SetDead(client_p); /* You are dead my friend */
} }
/* /*
@ -1184,9 +1201,11 @@ dead_link_on_read(struct Client* client_p, int error)
char errmsg[255]; char errmsg[255];
int current_error = get_sockerr(client_p->localClient->fd); int current_error = get_sockerr(client_p->localClient->fd);
if(IsDead(client_p)) if(IsDefunct(client_p))
return; return;
SetDead(client_p);
linebuf_donebuf(&client_p->localClient->buf_recvq);
linebuf_donebuf(&client_p->localClient->buf_sendq);
Debug((DEBUG_ERROR, "READ ERROR: fd = %d %d %d", Debug((DEBUG_ERROR, "READ ERROR: fd = %d %d %d",
client_p->localClient->fd, current_error, error)); client_p->localClient->fd, current_error, error));
@ -1198,12 +1217,12 @@ dead_link_on_read(struct Client* client_p, int error)
if (error == 0) if (error == 0)
{ {
/* Admins get the real IP */ /* Admins get the real IP */
sendto_realops_flags(FLAGS_ALL, L_ADMIN, sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ADMIN,
"Server %s closed the connection", "Server %s closed the connection",
get_client_name(client_p, SHOW_IP)); get_client_name(client_p, SHOW_IP));
/* Opers get a masked IP */ /* Opers get a masked IP */
sendto_realops_flags(FLAGS_ALL, L_OPER, sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_OPER,
"Server %s closed the connection", "Server %s closed the connection",
get_client_name(client_p, MASK_IP)); get_client_name(client_p, MASK_IP));
@ -1218,7 +1237,7 @@ dead_link_on_read(struct Client* client_p, int error)
get_client_name(client_p, MASK_IP), current_error); get_client_name(client_p, MASK_IP), current_error);
} }
sendto_realops_flags(FLAGS_ALL, L_ALL, sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ALL,
"%s had been connected for %d day%s, %2d:%02d:%02d", "%s had been connected for %d day%s, %2d:%02d:%02d",
client_p->name, connected/86400, client_p->name, connected/86400,
(connected/86400 == 1) ? "" : "s", (connected/86400 == 1) ? "" : "s",
@ -1237,6 +1256,35 @@ dead_link_on_read(struct Client* client_p, int error)
exit_client(client_p, client_p, &me, errmsg); exit_client(client_p, client_p, &me, errmsg);
} }
void
exit_aborted_clients(void)
{
dlink_node *ptr, *next;
struct Client *target_p;
char *notice;
DLINK_FOREACH_SAFE(ptr, next, abort_list.head)
{
target_p = ptr->data;
if (ptr->data == NULL)
{
sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ALL,
"Warning: null client on abort_list!");
dlinkDelete(ptr, &abort_list);
free_dlink_node(ptr);
continue;
}
dlinkDelete(ptr, &abort_list);
if(IsSendQExceeded(target_p))
notice = "Max SendQ exceeded";
else
notice = "Write error: connection closed";
exit_client(target_p, target_p, &me, notice);
free_dlink_node(ptr);
}
}
/* /*
** exit_client - This is old "m_bye". Name changed, because this is not a ** exit_client - This is old "m_bye". Name changed, because this is not a
** protocol function, but a general server utility function. ** protocol function, but a general server utility function.
@ -1275,151 +1323,148 @@ 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))
{
if (IsIpHash(source_p))
remove_one_ip(&source_p->localClient->ip);
delete_adns_queries(source_p->localClient->dns_query);
delete_identd_queries(source_p);
client_flush_input(source_p);
/* This source_p could have status of one of STAT_UNKNOWN, STAT_CONNECTING
* STAT_HANDSHAKE or STAT_UNKNOWN
* all of which are lumped together into unknown_list
*
* In all above cases IsRegistered() will not be true.
*/
if (!IsRegistered(source_p))
{
m = dlinkFind(&unknown_list,source_p);
if(m != NULL)
{
dlinkDelete(m, &unknown_list);
free_dlink_node(m);
}
}
if (IsOper(source_p))
{
m = dlinkFind(&oper_list,source_p);
if(m != NULL)
{
dlinkDelete(m, &oper_list);
free_dlink_node(m);
}
}
if (IsClient(source_p))
{
Count.local--;
if(IsPerson(source_p)) /* a little extra paranoia */
{
m = dlinkFind(&lclient_list,source_p);
if(m != NULL)
{
dlinkDelete(m,&lclient_list);
free_dlink_node(m);
}
}
}
/* As soon as a client is known to be a server of some sort
* it has to be put on the serv_list, or SJOIN's to this new server
* from the connect burst will not be seen.
*/
if (IsServer(source_p) || IsConnecting(source_p) ||
IsHandshake(source_p))
{
m = dlinkFind(&serv_list,source_p);
if(m != NULL)
{
dlinkDelete(m,&serv_list);
free_dlink_node(m);
}
}
if (IsServer(source_p))
{
Count.myserver--;
if(ServerInfo.hub)
remove_lazylink_flags(source_p->localClient->serverMask);
else
uplink = NULL;
}
if (IsPerson(source_p))
sendto_realops_flags(FLAGS_CCONN, L_ALL,
"Client exiting: %s (%s@%s) [%s] [%s]",
source_p->name, source_p->username, source_p->host,
comment,
source_p->localClient->sockhost);
log_user_exit(source_p);
if (!IsDead(source_p))
{
if (client_p != NULL && source_p != client_p)
sendto_one(source_p, "ERROR :Closing Link: %s %s (%s)",
source_p->vhost, source_p->name, comment);
else
sendto_one(source_p, "ERROR :Closing Link: %s (%s)",
source_p->vhost, comment);
}
}
if(IsServer(source_p))
{
if(ConfigServerHide.hide_servers)
{
/* set netsplit message to "me.name *.split" to still show
* that its a split, but hide the servers splitting
*/
ircsprintf(comment1,"%s *.split", me.name);
}
else
{
if((source_p->serv) && (source_p->serv->up))
strcpy(comment1, source_p->serv->up);
else
strcpy(comment1, "<Unknown>");
strcat(comment1," ");
strcat(comment1, source_p->name);
}
if(source_p->serv != NULL) /* XXX Why does this happen */
remove_dependents(client_p, source_p, from, comment, comment1);
if (source_p->servptr == &me)
{
sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ALL,
"%s was connected for %d seconds. %d/%d sendK/recvK.",
source_p->name, (int)(CurrentTime - source_p->firsttime),
source_p->localClient->sendK,
source_p->localClient->receiveK);
ilog(L_NOTICE, "%s was connected for %d seconds. %d/%d sendK/recvK.",
source_p->name, CurrentTime - source_p->firsttime,
source_p->localClient->sendK, source_p->localClient->receiveK);
}
}
if(MyConnect(source_p))
{ {
close_connection(source_p); /* DO NOT REMOVE. exit_client can be called twice after a failed
SetDead(source_p); /* You are dead my friend */ * read/write.
*/
if(IsClosing(source_p))
return 0;
SetClosing(source_p);
if (IsIpHash(source_p))
remove_one_ip(&source_p->localClient->ip);
delete_adns_queries(source_p->localClient->dns_query);
delete_identd_queries(source_p);
client_flush_input(source_p);
/* This source_p could have status of one of STAT_UNKNOWN, STAT_CONNECTING
* STAT_HANDSHAKE or STAT_UNKNOWN
* all of which are lumped together into unknown_list
*
* In all above cases IsRegistered() will not be true.
*/
if (!IsRegistered(source_p))
{
if ((m = dlinkFindDelete(&unknown_list, source_p)) != NULL)
free_dlink_node(m);
}
else if (IsOper(source_p))
{
if ((m = dlinkFindDelete(&oper_list, source_p)) != NULL)
free_dlink_node(m);
}
if (IsClient(source_p))
{
Count.local--;
/* a little extra paranoia */
if (IsPerson(source_p))
dlinkDelete(&source_p->localClient->lclient_node, &lclient_list);
}
/* As soon as a client is known to be a server of some sort
* it has to be put on the serv_list, or SJOIN's to this new server
* from the connect burst will not be seen.
*/
if (IsServer(source_p) || IsConnecting(source_p) ||
IsHandshake(source_p))
{
if ((m = dlinkFindDelete(&serv_list, source_p)) != NULL)
{
free_dlink_node(m);
}
}
if (IsServer(source_p))
{
Count.myserver--;
if(ServerInfo.hub)
remove_lazylink_flags(source_p->localClient->serverMask);
else
uplink = NULL;
}
if (IsPerson(source_p))
sendto_realops_flags(FLAGS_CCONN, L_ALL,
"Client exiting: %s (%s@%s) [%s] [%s]",
source_p->name, source_p->username, source_p->host,
comment,
source_p->localClient->sockhost);
log_user_exit(source_p);
if (!IsDead(source_p))
{
if (client_p != NULL && source_p != client_p)
sendto_one(source_p, "ERROR :Closing Link: %s %s (%s)",
source_p->host, source_p->name, comment);
else
sendto_one(source_p, "ERROR :Closing Link: %s (%s)",
source_p->host, comment);
}
/*
** Currently only server connections can have
** depending remote clients here, but it does no
** harm to check for all local clients. In
** future some other clients than servers might
** have remotes too...
**
** Close the Client connection first and mark it
** so that no messages are attempted to send to it.
** (The following *must* make MyConnect(source_p) == FALSE!).
** It also makes source_p->from == NULL, thus it's unnecessary
** to test whether "source_p != target_p" in the following loops.
*/
close_connection(source_p);
} }
if (IsServer(source_p))
{
if(ConfigServerHide.hide_servers)
{
/* set netsplit message to "me.name *.split" to still show
* that its a split, but hide the servers splitting
*/
ircsprintf(comment1,"%s *.split", me.name);
}
else
{
if((source_p->serv) && (source_p->serv->up))
strcpy(comment1, source_p->serv->up);
else
strcpy(comment1, "<Unknown>");
strcat(comment1," ");
strcat(comment1, source_p->name);
}
/* XXX Why does this happen */
if (source_p->serv != NULL)
remove_dependents(client_p, source_p, from, comment, comment1);
if (source_p->servptr == &me)
{
sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ALL,
"%s was connected for %d seconds. %d/%d sendK/recvK.",
source_p->name, (int)(CurrentTime - source_p->firsttime),
source_p->localClient->sendK,
source_p->localClient->receiveK);
ilog(L_NOTICE, "%s was connected for %d seconds. %d/%d sendK/recvK.",
source_p->name, CurrentTime - source_p->firsttime,
source_p->localClient->sendK, source_p->localClient->receiveK);
}
}
/* The client *better* be off all of the lists */ /* 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;
} }
@ -1561,7 +1606,6 @@ del_all_accepts(struct Client *client_p)
} }
} }
/* /*
* set_initial_nick * set_initial_nick
* inputs * inputs
@ -1645,14 +1689,18 @@ change_local_nick(struct Client *client_p, struct Client *source_p, char *nick)
!ConfigFileEntry.anti_nick_flood || !ConfigFileEntry.anti_nick_flood ||
(IsOper(source_p) && ConfigFileEntry.no_oper_flood)) (IsOper(source_p) && ConfigFileEntry.no_oper_flood))
{ {
/* XXX - the format of this notice should eventually be changed
* to either %s[%s@%s], or even better would be get_client_name() -bill
*/
sendto_realops_flags(FLAGS_NCHANGE, L_ALL, sendto_realops_flags(FLAGS_NCHANGE, L_ALL,
"Nick change: From %s to %s [%s@%s]", "Nick change: From %s to %s [%s@%s]",
source_p->name, nick, source_p->username, source_p->name, nick, source_p->username,
source_p->host); source_p->host);
sendto_common_channels_local(source_p, ":%s!%s@%s NICK :%s", sendto_common_channels_local(source_p, 1,
source_p->name, source_p->username, source_p->vhost, ":%s!%s@%s NICK :%s",
nick); source_p->name, source_p->username,
source_p->vhost, nick);
if (source_p->user) if (source_p->user)
{ {
add_history(source_p, 1); add_history(source_p, 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: fileio.c,v 1.3 2002/09/13 06:50:08 fishwaldo Exp $ * $Id: fileio.c,v 1.4 2003/03/06 14:01:50 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
#include "config.h" #include "config.h"
@ -45,7 +45,7 @@ file_open(const char *filename, int mode, int fmode)
int fd; int fd;
fd = open(filename, mode, fmode); fd = open(filename, mode, fmode);
if (fd == MASTER_MAX) { if (fd == MASTER_MAX) {
fd_close(fd); /* Too many FDs! */ close(fd); /* Too many FDs! */
errno = ENFILE; errno = ENFILE;
fd = -1; fd = -1;
} else if (fd >= 0) } else if (fd >= 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: ircd.c,v 1.10 2003/01/29 09:28:49 fishwaldo Exp $ * $Id: ircd.c,v 1.11 2003/03/06 14:01:50 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
@ -90,13 +90,12 @@ struct Counter Count;
struct ServerState_t server_state; struct ServerState_t server_state;
struct timeval SystemTime; struct timeval SystemTime;
int ServerRunning; /* GLOBAL - server execution state */ int ServerRunning; /* GLOBAL - server execution state */
struct Client me; /* That's me */ struct Client me; /* That's me */
struct LocalUser meLocalUser; /* That's also part of me */ struct LocalUser meLocalUser; /* That's also part of me */
struct Client* GlobalClientList = 0; /* Pointer to beginning of Client list */ struct Client* GlobalClientList = 0; /* Pointer to beginning of Client list */
struct JupedChannel *JupedChannelList = 0;
/* unknown/client pointer lists */ /* unknown/client pointer lists */
dlink_list unknown_list; /* unknown clients ON this server only */ dlink_list unknown_list; /* unknown clients ON this server only */
@ -170,7 +169,8 @@ static unsigned long get_vm_top(void)
/* /*
* get_maxrss - get the operating systems notion of the resident set size * get_maxrss - get the operating systems notion of the resident set size
*/ */
unsigned long get_maxrss(void) unsigned long
get_maxrss(void)
{ {
return get_vm_top() - initialVMTop; return get_vm_top() - initialVMTop;
} }
@ -330,7 +330,9 @@ io_loop(void)
irc_sleep(st); irc_sleep(st);
comm_select(0); comm_select(0);
exit_aborted_clients();
free_exited_clients();
/* /*
* Check to see whether we have to rehash the configuration .. * Check to see whether we have to rehash the configuration ..
*/ */
@ -612,6 +614,11 @@ int main(int argc, char *argv[])
setup_signals(); setup_signals();
/* We need this to initialise the fd array before anything else */ /* We need this to initialise the fd array before anything else */
fdlist_init(); fdlist_init();
if (!server_state.foreground)
{
close_all_connections(); /* this needs to be before init_netio()! */
}
init_log(logFileName);
init_netio(); /* This needs to be setup early ! -- adrian */ init_netio(); /* This needs to be setup early ! -- adrian */
/* Check if there is pidfile and daemon already running */ /* Check if there is pidfile and daemon already running */
check_pidfile(pidFileName); check_pidfile(pidFileName);
@ -619,11 +626,6 @@ int main(int argc, char *argv[])
eventInit(); eventInit();
init_sys(); init_sys();
if (!server_state.foreground)
{
close_all_connections();
}
init_log(logFileName);
initBlockHeap(); initBlockHeap();
init_dlink_nodes(); init_dlink_nodes();
initialize_message_files(); initialize_message_files();
@ -631,7 +633,7 @@ int main(int argc, char *argv[])
init_hash(); init_hash();
id_init(); id_init();
clear_scache_hash_table(); /* server cache name table */ clear_scache_hash_table(); /* server cache name table */
clear_ip_hash_table(); /* client host ip hash table */ init_ip_hash_table(); /* client host ip hash table */
init_host_hash(); /* Host-hashtable. */ init_host_hash(); /* Host-hashtable. */
clear_hash_parse(); clear_hash_parse();
init_client(); init_client();

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.6 2003/01/29 09:28:49 fishwaldo Exp $ * $Id: ircdauth.c,v 1.7 2003/03/06 14:01:50 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
@ -693,16 +693,10 @@ GreetUser(struct Client *client)
ubuf[1] = '\0'; ubuf[1] = '\0';
} }
#if 0 if ((m = dlinkFindDelete(&unknown_list, client)) != NULL)
m = make_dlink_node(); free_dlink_node(m);
dlinkAdd(client, m, &lclient_list);
#endif
m = dlinkFind(&unknown_list, client); dlinkAdd(client, &client->localClient->lclient_node, &lclient_list);
assert(m != NULL);
dlinkDelete(m, &unknown_list);
dlinkAdd(client, m, &lclient_list);
#if 0 #if 0
sendto_serv_butone(client, sendto_serv_butone(client,

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: list.c,v 1.5 2002/10/31 13:01:58 fishwaldo Exp $ * $Id: list.c,v 1.6 2003/03/06 14:01:50 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
@ -54,7 +54,8 @@ int user_count=0;
* *
*/ */
static BlockHeap *user_heap; static BlockHeap *user_heap;
void initUser(void) void
initUser(void)
{ {
user_heap = BlockHeapCreate(sizeof(struct User), USER_HEAP_SIZE); user_heap = BlockHeapCreate(sizeof(struct User), USER_HEAP_SIZE);
if(!user_heap) if(!user_heap)
@ -68,7 +69,8 @@ void initUser(void)
* side effects - add's an User information block to a client * side effects - add's an User information block to a client
* if it was not previously allocated. * if it was not previously allocated.
*/ */
struct User* make_user(struct Client *client_p) struct User*
make_user(struct Client *client_p)
{ {
struct User *user; struct User *user;
@ -94,7 +96,8 @@ struct User* make_user(struct Client *client_p)
* side effects - add's an Server information block to a client * side effects - add's an Server information block to a client
* if it was not previously allocated. * if it was not previously allocated.
*/ */
struct Server *make_server(struct Client *client_p) struct Server *
make_server(struct Client *client_p)
{ {
struct Server* serv = client_p->serv; struct Server* serv = client_p->serv;
@ -127,35 +130,36 @@ struct Server *make_server(struct Client *client_p)
* side effects - Decrease user reference count by one and release block, * side effects - Decrease user reference count by one and release block,
* if count reaches 0 * if count reaches 0
*/ */
void free_user(struct User* user, struct Client* client_p) void
free_user(struct User* user, struct Client* client_p)
{ {
if (--user->refcnt <= 0) if (--user->refcnt <= 0)
{
if (user->away)
MyFree((char *)user->away);
/*
* sanity check
*/
if (user->joined || user->refcnt < 0 ||
user->invited.head || user->channel.head)
{ {
if (user->away) sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ALL,
MyFree((char *)user->away); "* %#lx user (%s!%s@%s) %#lx %#lx %#lx %d %d *",
/* (unsigned long)client_p, client_p ? client_p->name : "<noname>",
* sanity check client_p->username, client_p->host, (unsigned long)user,
*/ (unsigned long)user->invited.head,
if (user->joined || user->refcnt < 0 || (unsigned long)user->channel.head, user->joined,
user->invited.head || user->channel.head) user->refcnt);
{ assert(!user->joined);
sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ALL, assert(!user->refcnt);
"* %#lx user (%s!%s@%s) %#lx %#lx %#lx %d %d *", assert(!user->invited.head);
(unsigned long)client_p, client_p ? client_p->name : "<noname>", assert(!user->channel.head);
client_p->username, client_p->host, (unsigned long)user,
(unsigned long)user->invited.head,
(unsigned long)user->channel.head, user->joined,
user->refcnt);
assert(!user->joined);
assert(!user->refcnt);
assert(!user->invited.head);
assert(!user->channel.head);
}
BlockHeapFree(user_heap, user);
--user_count;
assert(user_count >= 0);
} }
BlockHeapFree(user_heap, user);
--user_count;
assert(user_count >= 0);
}
} }
@ -198,7 +202,8 @@ make_dlink_node(void)
* output - NONE * output - NONE
* side effects - free given dlink_node * side effects - free given dlink_node
*/ */
void free_dlink_node(dlink_node *ptr) void
free_dlink_node(dlink_node *ptr)
{ {
BlockHeapFree(dnode_heap, ptr); BlockHeapFree(dnode_heap, ptr);
--links_count; --links_count;
@ -214,7 +219,8 @@ void free_dlink_node(dlink_node *ptr)
* output - NONE * output - NONE
* side effects - NONE * side effects - NONE
*/ */
void count_user_memory(int *count,int *user_memory_used) void
count_user_memory(int *count,int *user_memory_used)
{ {
*count = user_count; *count = user_count;
*user_memory_used = user_count * sizeof(struct User); *user_memory_used = user_count * sizeof(struct User);
@ -228,7 +234,8 @@ void count_user_memory(int *count,int *user_memory_used)
* output - NONE * output - NONE
* side effects - NONE * side effects - NONE
*/ */
void count_links_memory(int *count,int *links_memory_used) void
count_links_memory(int *count,int *links_memory_used)
{ {
*count = links_count; *count = links_count;
*links_memory_used = links_count * sizeof(dlink_node); *links_memory_used = links_count * sizeof(dlink_node);

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: listener.c,v 1.5 2002/11/04 08:14:00 fishwaldo Exp $ * $Id: listener.c,v 1.6 2003/03/06 14:01:50 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
@ -393,6 +393,14 @@ accept_connection(int pfd, void *data)
fd = comm_accept(listener->fd, &sai); fd = comm_accept(listener->fd, &sai);
if (fd < 0)
{
/* Re-register a new IO request for the next accept .. */
comm_setselect(listener->fd, FDLIST_SERVICE, COMM_SELECT_READ,
accept_connection, listener, 0);
return;
}
copy_s_addr(IN_ADDR(addr), S_ADDR(sai)); copy_s_addr(IN_ADDR(addr), S_ADDR(sai));
#ifdef IPV6 #ifdef IPV6
@ -406,13 +414,6 @@ accept_connection(int pfd, void *data)
} }
#endif #endif
if (fd < 0)
{
/* Re-register a new IO request for the next accept .. */
comm_setselect(listener->fd, FDLIST_SERVICE, COMM_SELECT_READ,
accept_connection, listener, 0);
return;
}
/* /*
* check for connection limit * check for connection limit
*/ */

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_error.c,v 1.5 2002/10/31 13:01:58 fishwaldo Exp $ * $Id: m_error.c,v 1.6 2003/03/06 14:01:50 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
@ -48,15 +48,43 @@ struct Message error_msgtab = {
* parv[0] = sender prefix * parv[0] = sender prefix
* parv[*] = parameters * parv[*] = parameters
*/ */
void m_error(struct Client *client_p, struct Client *source_p, void
int parc, char *parv[]) m_error(struct Client *client_p, struct Client *source_p,
int parc, char *parv[])
{ {
if (MyClient(source_p)) char* para;
para = (parc > 1 && *parv[1] != '\0') ? parv[1] : "<>";
ilog(L_ERROR, "Received ERROR message from %s: %s",
source_p->name, para);
if (client_p == source_p)
{
sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ADMIN,
"ERROR :from %s -- %s",
get_client_name(client_p, HIDE_IP), para);
sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_OPER,
"ERROR :from %s -- %s",
get_client_name(client_p, MASK_IP), para);
}
else
{
sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_OPER,
"ERROR :from %s via %s -- %s",
source_p->name, get_client_name(client_p, MASK_IP), para);
sendto_realops_flags(FLAGS_ALL, L_ADMIN,"ERROR :from %s via %s -- %s",
source_p->name,
get_client_name(client_p, HIDE_IP), para);
}
if(MyClient(source_p))
exit_client(client_p, source_p, source_p, "ERROR"); exit_client(client_p, source_p, source_p, "ERROR");
} }
void ms_error(struct Client *client_p, struct Client *source_p, void
int parc, char *parv[]) ms_error(struct Client *client_p, struct Client *source_p,
int parc, char *parv[])
{ {
char* para; char* para;

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.9 2003/01/29 09:28:50 fishwaldo Exp $ * $Id: packet.c,v 1.10 2003/03/06 14:01:50 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
#include "tools.h" #include "tools.h"
@ -58,7 +58,7 @@ parse_client_queued(struct Client *client_p)
for(;;) for(;;)
{ {
if (IsDead(client_p)) if (IsClosing(client_p))
return; return;
if (client_p->localClient == NULL) if (client_p->localClient == NULL)
return; return;
@ -73,7 +73,7 @@ parse_client_queued(struct Client *client_p)
if(dolen <= 0) if(dolen <= 0)
break; break;
if(!IsDead(client_p)) if(!IsDefunct(client_p))
{ {
client_dopacket(client_p, readBuf, dolen); client_dopacket(client_p, readBuf, dolen);
i++; i++;
@ -95,7 +95,7 @@ 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)) if(IsDefunct(client_p))
return; return;
if(client_p->localClient == NULL) if(client_p->localClient == NULL)
return; return;
@ -104,7 +104,7 @@ parse_client_queued(struct Client *client_p)
readBuf, READBUF_SIZE, LINEBUF_COMPLETE, readBuf, READBUF_SIZE, LINEBUF_COMPLETE,
LINEBUF_PARSED)) > 0) LINEBUF_PARSED)) > 0)
{ {
if (!IsDead(client_p)) if (!IsDefunct(client_p))
client_dopacket(client_p, readBuf, dolen); client_dopacket(client_p, readBuf, dolen);
else if(MyConnect(client_p)) else if(MyConnect(client_p))
{ {
@ -134,7 +134,7 @@ parse_client_queued(struct Client *client_p)
*/ */
for(;;) for(;;)
{ {
if (IsDead(client_p)) if (IsDefunct(client_p))
break; break;
/* This flood protection works as follows: /* This flood protection works as follows:
@ -258,7 +258,7 @@ read_ctrl_packet(int fd, void *data)
reply = &lserver->slinkrpl; reply = &lserver->slinkrpl;
if(IsDead(server)) if(IsDefunct(server))
{ {
return; return;
} }
@ -275,6 +275,7 @@ read_ctrl_packet(int fd, void *data)
{ {
if((length == -1) && ignoreErrno(errno)) if((length == -1) && ignoreErrno(errno))
goto nodata; goto nodata;
dead_link_on_read(server, length);
return; return;
} }
reply->command = tmp[0]; reply->command = tmp[0];
@ -377,7 +378,7 @@ read_packet(int fd, void *data)
#ifndef NDEBUG #ifndef NDEBUG
struct hook_io_data hdata; struct hook_io_data hdata;
#endif #endif
if(IsDead(client_p)) if(IsDefunct(client_p))
return; return;
assert(lclient_p != NULL); assert(lclient_p != NULL);
@ -436,7 +437,7 @@ read_packet(int fd, void *data)
client_p->lasttime = CurrentTime; client_p->lasttime = CurrentTime;
if (client_p->lasttime > client_p->since) if (client_p->lasttime > client_p->since)
client_p->since = CurrentTime; client_p->since = CurrentTime;
client_p->flags &= ~FLAGS_PINGSENT; ClearPingSent(client_p);
/* /*
* Before we even think of parsing what we just read, stick * Before we even think of parsing what we just read, stick
@ -453,35 +454,33 @@ read_packet(int fd, void *data)
/* Attempt to parse what we have */ /* Attempt to parse what we have */
if (!IsDead(client_p)) parse_client_queued(client_p);
/* Check to make sure we're not flooding */
if (IsPerson(client_p) &&
(linebuf_alloclen(&client_p->localClient->buf_recvq) >
ConfigFileEntry.client_flood))
{ {
parse_client_queued(client_p); if (!(ConfigFileEntry.no_oper_flood && IsOper(client_p)))
if (IsDead(client_p)) {
exit_client(client_p, client_p, client_p, "Excess Flood");
return; return;
/* Check to make sure we're not flooding */
if (IsPerson(client_p) &&
(linebuf_alloclen(&client_p->localClient->buf_recvq) >
ConfigFileEntry.client_flood))
{
if (!(ConfigFileEntry.no_oper_flood && IsOper(client_p)))
{
exit_client(client_p, client_p, client_p, "Excess Flood");
return;
}
} }
}
/* server fd may have changed */ /* 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 (!IsDefunct(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))
{ {

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.10 2003/01/29 09:28:50 fishwaldo Exp $ * $Id: s_bsd.c,v 1.11 2003/03/06 14:01:50 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
@ -80,21 +80,9 @@ void
close_all_connections(void) close_all_connections(void)
{ {
int i; int i;
#ifndef NDEBUG
int fd; int fd;
#endif
/* XXX someone tell me why we care about 4 fd's ? */
/* XXX btw, fd 3 is used for profiler ! */
#if 0
#ifndef VMS
for (i = 0; i < MAXCONNECTIONS; ++i) for (i = 0; i < MAXCONNECTIONS; ++i)
#else
for (i = 3; i < MAXCONNECTIONS; ++i)
#endif
#endif
for (i = 4; i < MAXCONNECTIONS; ++i)
{ {
if (fd_table[i].flags.open) if (fd_table[i].flags.open)
fd_close(i); fd_close(i);
@ -102,17 +90,14 @@ close_all_connections(void)
close(i); close(i);
} }
/* XXX should his hack be done in all cases? */ /* Make sure stdio descriptors (0-2) and profiler descriptor (3)
#ifndef NDEBUG always go somewhere harmless. Use -foreground for profiling
/* fugly hack to reserve fd == 2 */ or executing from gdb */
(void)close(2); for (i = 0; i < LOWEST_SAFE_FD; i++)
fd = open("stderr.log",O_WRONLY|O_CREAT|O_APPEND,0644);
if( fd >= 0 )
{ {
dup2(fd, 2); if ((fd = open(PATH_DEVNULL, O_RDWR)) < 0)
close(fd); exit(-1); /* we're hosed if we can't even open /dev/null */
} }
#endif
} }
/* /*
@ -322,7 +307,6 @@ close_connection(struct Client *client_p)
send_queued_write(client_p->localClient->fd, client_p); 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))

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.12 2003/01/29 09:28:50 fishwaldo Exp $ * $Id: s_conf.c,v 1.13 2003/03/06 14:01:51 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
@ -94,7 +94,7 @@ static void clear_special_conf(struct ConfItem **);
#define IP_HASH_SIZE 0x1000 #define IP_HASH_SIZE 0x1000
typedef struct ip_entry struct ip_entry
{ {
#ifndef IPV6 #ifndef IPV6
u_int32_t ip; u_int32_t ip;
@ -104,13 +104,14 @@ typedef struct ip_entry
int count; int count;
time_t last_attempt; time_t last_attempt;
struct ip_entry *next; struct ip_entry *next;
} IP_ENTRY; };
static IP_ENTRY *ip_hash_table[IP_HASH_SIZE];
static struct ip_entry *ip_hash_table[IP_HASH_SIZE];
static BlockHeap *ip_entry_heap = NULL;
static int ip_entries_count = 0;
static int hash_ip(struct irc_inaddr *); static int hash_ip(struct irc_inaddr *);
static void garbage_collect_ip_entries(void);
static IP_ENTRY *find_or_add_ip(struct irc_inaddr*); static struct ip_entry *find_or_add_ip(struct irc_inaddr*);
/* general conf items link list root */ /* general conf items link list root */
struct ConfItem* ConfigItemList = NULL; struct ConfItem* ConfigItemList = NULL;
@ -420,7 +421,7 @@ check_client(struct Client *client_p, struct Client *source_p, char *username)
switch( i ) switch( i )
{ {
case SOCKET_ERROR: case SOCKET_ERROR:
(void)exit_client(client_p, source_p, &me, "Socket Error"); exit_client(client_p, source_p, &me, "Socket Error");
break; break;
case TOO_MANY: case TOO_MANY:
@ -466,17 +467,17 @@ check_client(struct Client *client_p, struct Client *source_p, char *username)
source_p->localClient->listener->port); source_p->localClient->listener->port);
ilog(L_INFO, ilog(L_INFO,
"Unauthorised client connection from %s on [%s/%u].", "Unauthorized client connection from %s on [%s/%u].",
get_client_name(source_p, SHOW_IP), get_client_name(source_p, SHOW_IP),
source_p->localClient->listener->name, source_p->localClient->listener->name,
source_p->localClient->listener->port); source_p->localClient->listener->port);
(void)exit_client(client_p, source_p, &me, exit_client(client_p, source_p, &me,
"You are not authorized to use this server"); "You are not authorised to use this server");
break; break;
} }
case BANNED_CLIENT: case BANNED_CLIENT:
(void)exit_client(client_p,client_p, &me, "*** Banned "); exit_client(client_p,client_p, &me, "*** Banned ");
ServerStats->is_ref++; ServerStats->is_ref++;
break; break;
@ -575,10 +576,10 @@ verify_access(struct Client* client_p, const char* username)
* output - * output -
* side effects - do actual attach * side effects - do actual attach
*/ */
static static int
int attach_iline(struct Client *client_p, struct ConfItem *aconf) attach_iline(struct Client *client_p, struct ConfItem *aconf)
{ {
IP_ENTRY *ip_found; struct ip_entry *ip_found;
ip_found = find_or_add_ip(&client_p->localClient->ip); ip_found = find_or_add_ip(&client_p->localClient->ip);
SetIpHash(client_p); SetIpHash(client_p);
@ -601,45 +602,19 @@ int attach_iline(struct Client *client_p, struct ConfItem *aconf)
return(attach_conf(client_p, aconf)); return(attach_conf(client_p, aconf));
} }
/* link list of free IP_ENTRY's */
static IP_ENTRY *free_ip_entries;
/* /*
* clear_ip_hash_table() * init_ip_hash_table()
* *
* input - NONE * input - NONE
* output - NONE * output - NONE
* side effects - clear the ip hash table * side effects - allocate memory for ip_entry(s)
* * - clear the ip hash table
*/ */
void void
clear_ip_hash_table() init_ip_hash_table()
{ {
void *block_IP_ENTRIES; /* block of IP_ENTRY's */ ip_entry_heap = BlockHeapCreate(sizeof(struct ip_entry), 2*MAXCONNECTIONS);
IP_ENTRY *new_IP_ENTRY; /* new IP_ENTRY being made */
IP_ENTRY *last_IP_ENTRY; /* last IP_ENTRY in chain */
int size;
int n_left_to_allocate = MAXCONNECTIONS;
size = sizeof(IP_ENTRY) + (sizeof(IP_ENTRY) & (sizeof(void*) - 1) );
block_IP_ENTRIES = (void *)MyMalloc((size * n_left_to_allocate));
free_ip_entries = (IP_ENTRY *)block_IP_ENTRIES;
last_IP_ENTRY = free_ip_entries;
/* *shudder* pointer arithmetic */
while(--n_left_to_allocate)
{
block_IP_ENTRIES = (void *)((unsigned long)block_IP_ENTRIES +
(unsigned long) size);
new_IP_ENTRY = (IP_ENTRY *)block_IP_ENTRIES;
last_IP_ENTRY->next = new_IP_ENTRY;
new_IP_ENTRY->next = (IP_ENTRY *)NULL;
last_IP_ENTRY = new_IP_ENTRY;
}
memset((void *)ip_hash_table, 0, sizeof(ip_hash_table)); memset((void *)ip_hash_table, 0, sizeof(ip_hash_table));
} }
@ -649,52 +624,44 @@ clear_ip_hash_table()
* inputs - client_p * inputs - client_p
* - name * - name
* *
* output - pointer to an IP_ENTRY element * output - pointer to a struct ip_entry
* side effects - * side effects -
* *
* If the ip # was not found, a new IP_ENTRY is created, and the ip * If the ip # was not found, a new struct ip_entry is created, and the ip
* count set to 0. * count set to 0.
* XXX: Broken for IPv6
*/ */
static IP_ENTRY * static struct ip_entry *
find_or_add_ip(struct irc_inaddr *ip_in) find_or_add_ip(struct irc_inaddr *ip_in)
{ {
int hash_index; struct ip_entry *ptr, *newptr;
IP_ENTRY *ptr, *newptr; int hash_index=hash_ip(ip_in);
for(ptr = ip_hash_table[hash_index = hash_ip(ip_in)]; ptr; for(ptr = ip_hash_table[hash_index]; ptr; ptr = ptr->next)
ptr = ptr->next)
{ {
if(!memcmp(&ptr->ip, ip_in, sizeof(struct irc_inaddr))) if(memcmp(&ptr->ip, ip_in, sizeof(struct irc_inaddr)) == 0)
{
return(ptr);
}
}
if ((ptr = ip_hash_table[hash_index]) != NULL)
{ {
if (free_ip_entries == NULL) /* Found entry already in hash, return it. */
outofmemory(); return(ptr);
newptr = ip_hash_table[hash_index] = free_ip_entries;
free_ip_entries = newptr->next;
memcpy(&newptr->ip, ip_in, sizeof(struct irc_inaddr));
newptr->count = 0;
newptr->last_attempt = 0;
newptr->next = ptr;
return(newptr);
} }
}
if (free_ip_entries == NULL) if (ip_entries_count >= (2*MAXCONNECTIONS))
outofmemory(); garbage_collect_ip_entries();
ptr = ip_hash_table[hash_index] = free_ip_entries; newptr = BlockHeapAlloc(ip_entry_heap);
free_ip_entries = ptr->next; ip_entries_count++;
memcpy(&ptr->ip, ip_in, sizeof(struct irc_inaddr)); memcpy(&newptr->ip, ip_in, sizeof(struct irc_inaddr));
ptr->count = 0; newptr->count = 0;
ptr->next = NULL; newptr->last_attempt = 0;
return(ptr);
if ((ptr = ip_hash_table[hash_index]) != NULL)
newptr->next = ptr;
else
newptr->next = NULL;
ip_hash_table[hash_index] = newptr;
return(newptr);
} }
/* /*
@ -702,19 +669,20 @@ find_or_add_ip(struct irc_inaddr *ip_in)
* *
* inputs - unsigned long IP address value * inputs - unsigned long IP address value
* output - NONE * output - NONE
* side effects - ip address listed, is looked up in ip hash table * side effects - The ip address given, is looked up in ip hash table
* and number of ip#'s for that ip decremented. * and number of ip#'s for that ip decremented.
* if ip # count reaches 0, the IP_ENTRY is returned * If ip # count reaches 0 and has expired,
* to the free_ip_enties link list. * the struct ip_entry is returned to the ip_entry_heap
*/ */
void void
remove_one_ip(struct irc_inaddr *ip_in) remove_one_ip(struct irc_inaddr *ip_in)
{ {
IP_ENTRY *ptr, **lptr; struct ip_entry *ptr;
struct ip_entry *last_ptr = NULL;
int hash_index = hash_ip(ip_in); int hash_index = hash_ip(ip_in);
for (lptr = ip_hash_table+hash_index, ptr = *lptr; ptr;
lptr=&ptr->next, ptr=*lptr) for(ptr = ip_hash_table[hash_index]; ptr; ptr = ptr->next)
{ {
#ifndef IPV6 #ifndef IPV6
if (ptr->ip != PIN_ADDR(ip_in)) if (ptr->ip != PIN_ADDR(ip_in))
@ -727,13 +695,18 @@ remove_one_ip(struct irc_inaddr *ip_in)
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)
{ {
*lptr = ptr->next; if (last_ptr != NULL)
ptr->next = free_ip_entries; last_ptr->next = ptr->next;
free_ip_entries = ptr; else
ip_hash_table[hash_index] = ptr->next;
BlockHeapFree(ip_entry_heap, ptr);
ip_entries_count--;
return; return;
} }
last_ptr = ptr;
} }
} }
@ -793,24 +766,57 @@ hash_ip(struct irc_inaddr *addr)
void void
count_ip_hash(int *number_ips_stored,u_long *mem_ips_stored) count_ip_hash(int *number_ips_stored,u_long *mem_ips_stored)
{ {
IP_ENTRY *ip_hash_ptr; struct ip_entry *ptr;
int i; int i;
*number_ips_stored = 0; *number_ips_stored = 0;
*mem_ips_stored = 0; *mem_ips_stored = 0;
for (i = 0; i < IP_HASH_SIZE ;i++) for (i = 0; i < IP_HASH_SIZE ;i++)
{
for (ptr = ip_hash_table[i]; ptr; ptr = ptr->next)
{ {
ip_hash_ptr = ip_hash_table[i]; *number_ips_stored += 1;
while(ip_hash_ptr) *mem_ips_stored += sizeof(struct ip_entry);
{
*number_ips_stored = *number_ips_stored + 1;
*mem_ips_stored = *mem_ips_stored +
sizeof(IP_ENTRY);
ip_hash_ptr = ip_hash_ptr->next;
}
} }
}
}
/*
* garbage_collect_ip_entries()
*
* input - NONE
* output - NONE
* side effects - free up all ip entries with no connections
*/
static void
garbage_collect_ip_entries(void)
{
struct ip_entry *ptr;
struct ip_entry *last_ptr;
struct ip_entry *next_ptr;
int i;
for(i = 0; i < IP_HASH_SIZE; i++)
{
last_ptr = NULL;
for(ptr = ip_hash_table[i]; ptr; ptr = next_ptr)
{
next_ptr = ptr->next;
if (ptr->count == 0)
{
if (last_ptr != NULL)
last_ptr->next = ptr->next;
else
ip_hash_table[i] = ptr->next;
BlockHeapFree(ip_entry_heap, ptr);
ip_entries_count--;
}
else
last_ptr = ptr;
}
}
} }
/* /*
@ -822,9 +828,9 @@ count_ip_hash(int *number_ips_stored,u_long *mem_ips_stored)
*/ */
void void
iphash_stats(struct Client *client_p, struct Client *source_p, iphash_stats(struct Client *client_p, struct Client *source_p,
int parc, char *parv[],FBFILE* out) int parc, char *parv[],FBFILE* out)
{ {
IP_ENTRY *ip_hash_ptr; struct ip_entry *ptr;
int i; int i;
int collision_count; int collision_count;
char result_buf[256]; char result_buf[256];
@ -833,36 +839,32 @@ iphash_stats(struct Client *client_p, struct Client *source_p,
sendto_one(source_p,":%s NOTICE %s :*** hash stats for iphash", sendto_one(source_p,":%s NOTICE %s :*** hash stats for iphash",
me.name,client_p->name); me.name,client_p->name);
else else
{ {
(void)sprintf(result_buf,"*** hash stats for iphash\n"); (void)sprintf(result_buf,"*** hash stats for iphash\n");
(void)fbputs(result_buf,out); (void)fbputs(result_buf,out);
} }
for(i = 0; i < IP_HASH_SIZE ;i++) for(i = 0; i < IP_HASH_SIZE ;i++)
{ {
ip_hash_ptr = ip_hash_table[i]; collision_count = 0;
for (ptr = ip_hash_table[i]; ptr; ptr = ptr->next)
collision_count++;
collision_count = 0; if(collision_count != 0)
while(ip_hash_ptr) {
{ if(out == NULL)
collision_count++; {
ip_hash_ptr = ip_hash_ptr->next; sendto_one(source_p,":%s NOTICE %s :Entry %d (0x%X) Collisions %d",
} me.name,client_p->name,i,i,collision_count);
if(collision_count) }
{ else
if(out == NULL) {
{ (void)sprintf(result_buf,"Entry %d (0x%X) Collisions %d\n",
sendto_one(source_p,":%s NOTICE %s :Entry %d (0x%X) Collisions %d", i,i,collision_count);
me.name,client_p->name,i,i,collision_count); (void)fbputs(result_buf,out);
} }
else
{
(void)sprintf(result_buf,"Entry %d (0x%X) Collisions %d\n",
i,i,collision_count);
(void)fbputs(result_buf,out);
}
}
} }
}
} }
/* /*
@ -900,9 +902,7 @@ detach_conf(struct Client* client_p,struct ConfItem* aconf)
} }
} }
if (aconf && !--aconf->clients && IsIllegal(aconf)) if (aconf && !--aconf->clients && IsIllegal(aconf))
{
free_conf(aconf); free_conf(aconf);
}
dlinkDelete(ptr, &client_p->localClient->confs); dlinkDelete(ptr, &client_p->localClient->confs);
free_dlink_node(ptr); free_dlink_node(ptr);
return(0); return(0);
@ -1542,7 +1542,7 @@ lookup_confhost(struct ConfItem* aconf)
int int
conf_connect_allowed(struct irc_inaddr *addr, int aftype) conf_connect_allowed(struct irc_inaddr *addr, int aftype)
{ {
IP_ENTRY *ip_found; struct ip_entry *ip_found;
struct ConfItem *aconf = find_dline_conf(addr,aftype); struct ConfItem *aconf = find_dline_conf(addr,aftype);
/* DLINE exempt also gets you out of static limits/pacing... */ /* DLINE exempt also gets you out of static limits/pacing... */
@ -1555,10 +1555,10 @@ conf_connect_allowed(struct irc_inaddr *addr, int aftype)
ip_found = find_or_add_ip(addr); ip_found = find_or_add_ip(addr);
if ((CurrentTime - ip_found->last_attempt) < if ((CurrentTime - ip_found->last_attempt) <
ConfigFileEntry.throttle_time) ConfigFileEntry.throttle_time)
{ {
ip_found->last_attempt = CurrentTime; ip_found->last_attempt = CurrentTime;
return(TOO_FAST); return(TOO_FAST);
} }
ip_found->last_attempt = CurrentTime; ip_found->last_attempt = CurrentTime;
return(0); return(0);
} }
@ -2091,8 +2091,8 @@ void clear_out_old_conf(void)
* side effects - This function removes I/P conf items * side effects - This function removes I/P conf items
*/ */
static static void
void flush_deleted_I_P(void) flush_deleted_I_P(void)
{ {
struct ConfItem **tmp = &ConfigItemList; struct ConfItem **tmp = &ConfigItemList;
struct ConfItem *tmp2; struct ConfItem *tmp2;

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_log.c,v 1.5 2002/11/01 01:32:37 fishwaldo Exp $ * $Id: s_log.c,v 1.6 2003/03/06 14:01:51 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
@ -86,6 +86,12 @@ static const char *logLevelToString[] =
static int static int
open_log(const char* filename) open_log(const char* filename)
{ {
#ifndef DEBUG
if (!server_state.foreground)
{
close(2); /* let the logfile grab fd 2 to catch stderr */
}
#endif
logFile = fbopen(filename, "a"); logFile = fbopen(filename, "a");
if (logFile == NULL) if (logFile == 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.15 2003/01/29 09:28:50 fishwaldo Exp $ * $Id: s_serv.c,v 1.16 2003/03/06 14:01:51 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
@ -148,8 +148,9 @@ static void cjoin_all(struct Client *client_p);
static CNCB serv_connect_callback; static CNCB serv_connect_callback;
void slink_error(unsigned int rpl, unsigned int len, unsigned char *data, void
struct Client *server_p) slink_error(unsigned int rpl, unsigned int len, unsigned char *data,
struct Client *server_p)
{ {
assert(rpl == SLINKRPL_ERROR); assert(rpl == SLINKRPL_ERROR);
@ -158,11 +159,13 @@ void slink_error(unsigned int rpl, unsigned int len, unsigned char *data,
sendto_realops_flags(FLAGS_ALL, L_ALL, "SlinkError for %s: %s", sendto_realops_flags(FLAGS_ALL, L_ALL, "SlinkError for %s: %s",
server_p->name, data); server_p->name, data);
/* XXX should this be exit_client? */
exit_client(server_p, server_p, &me, "servlink error -- terminating link"); exit_client(server_p, server_p, &me, "servlink error -- terminating link");
} }
void slink_zipstats(unsigned int rpl, unsigned int len, unsigned char *data, void
struct Client *server_p) slink_zipstats(unsigned int rpl, unsigned int len, unsigned char *data,
struct Client *server_p)
{ {
struct ZipStats zipstats; struct ZipStats zipstats;
unsigned long in = 0, in_wire = 0, out = 0, out_wire = 0; unsigned long in = 0, in_wire = 0, out = 0, out_wire = 0;
@ -281,12 +284,13 @@ struct EncCapability *check_cipher(struct Client *client_p,
* according to given config entry --Jto * according to given config entry --Jto
* XXX - this is only called with me.name as name * XXX - this is only called with me.name as name
*/ */
const char* my_name_for_link(const char* name, struct ConfItem* aconf) const char*
my_name_for_link(const char* name, struct ConfItem* aconf)
{ {
if(aconf->fakename) if(aconf->fakename)
return(aconf->fakename); return(aconf->fakename);
else else
return(name); return(name);
} }
/* /*
@ -295,7 +299,8 @@ const char* my_name_for_link(const char* name, struct ConfItem* aconf)
* output - none * output - none
* side effects - server is added to global_serv_list * side effects - server is added to global_serv_list
*/ */
void add_server_to_list(struct Client *client_p) void
add_server_to_list(struct Client *client_p)
{ {
dlink_node *ptr; dlink_node *ptr;
@ -305,36 +310,11 @@ void add_server_to_list(struct Client *client_p)
return; return;
} }
/*
* remove_server_from_list()
*
* input - pointer to client
* output - none
* side effects - server is removed from GlocalServerList
*/
void remove_server_from_list(struct Client *client_p)
{
dlink_node *ptr;
struct Client *target_p;
for (ptr = global_serv_list.head; ptr; ptr = ptr->next)
{
target_p = ptr->data;
if (client_p == target_p)
{
dlinkDelete(ptr,&global_serv_list);
free_dlink_node(ptr);
break;
}
}
return;
}
/* /*
* write_links_file * write_links_file
*/ */
void write_links_file(void* notused) void
write_links_file(void* notused)
{ {
MessageFileLine *next_mptr = 0; MessageFileLine *next_mptr = 0;
MessageFileLine *mptr = 0; MessageFileLine *mptr = 0;
@ -354,7 +334,7 @@ void write_links_file(void* notused)
if ((file = fbopen(MessageFileptr->fileName, "w")) == 0) if ((file = fbopen(MessageFileptr->fileName, "w")) == 0)
return; return;
for( mptr = MessageFileptr->contentsOfFile; mptr; mptr = next_mptr) for (mptr = MessageFileptr->contentsOfFile; mptr; mptr = next_mptr)
{ {
next_mptr = mptr->next; next_mptr = mptr->next;
MyFree(mptr); MyFree(mptr);
@ -430,8 +410,9 @@ void write_links_file(void* notused)
* *
* returns: (see #defines) * returns: (see #defines)
*/ */
int hunt_server(struct Client *client_p, struct Client *source_p, char *command, int
int server, int parc, char *parv[]) hunt_server(struct Client *client_p, struct Client *source_p, char *command,
int server, int parc, char *parv[])
{ {
struct Client *target_p; struct Client *target_p;
int wilds; int wilds;
@ -633,7 +614,8 @@ try_connections(void *unused)
Debug((DEBUG_NOTICE,"Next connection check : %s", myctime(next))); Debug((DEBUG_NOTICE,"Next connection check : %s", myctime(next)));
} }
int check_server(const char *name, struct Client* client_p, int cryptlink) int
check_server(const char *name, struct Client* client_p, int cryptlink)
{ {
struct ConfItem *aconf=NULL; struct ConfItem *aconf=NULL;
struct ConfItem *server_aconf=NULL; struct ConfItem *server_aconf=NULL;
@ -750,8 +732,9 @@ int check_server(const char *name, struct Client* client_p, int cryptlink)
* side effects - send the CAPAB line to a server -orabidoo * side effects - send the CAPAB line to a server -orabidoo
* *
*/ */
void send_capabilities(struct Client *client_p, struct ConfItem *aconf, void
int cap_can_send, int enc_can_send ) send_capabilities(struct Client *client_p, struct ConfItem *aconf,
int cap_can_send, int enc_can_send )
{ {
struct Capability *cap; struct Capability *cap;
char msgbuf[BUFSIZE]; char msgbuf[BUFSIZE];
@ -815,7 +798,8 @@ void send_capabilities(struct Client *client_p, struct ConfItem *aconf,
* output - NONE * output - NONE
* side effects - NICK message is sent towards given client_p * side effects - NICK message is sent towards given client_p
*/ */
void sendnick_TS(struct Client *client_p, struct Client *target_p) void
sendnick_TS(struct Client *client_p, struct Client *target_p)
{ {
static char ubuf[12]; static char ubuf[12];
@ -859,7 +843,8 @@ void sendnick_TS(struct Client *client_p, struct Client *target_p)
* output - NONE * output - NONE
* side effects - If this client is not known by this lazyleaf, send it * side effects - If this client is not known by this lazyleaf, send it
*/ */
void client_burst_if_needed(struct Client *client_p, struct Client *target_p) void
client_burst_if_needed(struct Client *client_p, struct Client *target_p)
{ {
if (!ServerInfo.hub) return; if (!ServerInfo.hub) return;
if (!MyConnect(client_p)) return; if (!MyConnect(client_p)) return;
@ -880,7 +865,8 @@ void client_burst_if_needed(struct Client *client_p, struct Client *target_p)
* side effects - build up string representing capabilities of server listed * side effects - build up string representing capabilities of server listed
*/ */
const char* show_capabilities(struct Client* target_p) const char*
show_capabilities(struct Client* target_p)
{ {
static char msgbuf[BUFSIZE]; static char msgbuf[BUFSIZE];
struct Capability* cap; struct Capability* cap;
@ -931,7 +917,8 @@ const char* show_capabilities(struct Client* target_p)
* side effects - * side effects -
*/ */
int server_estab(struct Client *client_p) int
server_estab(struct Client *client_p)
{ {
struct Client* target_p; struct Client* target_p;
struct ConfItem* aconf; struct ConfItem* aconf;
@ -1067,7 +1054,7 @@ int server_estab(struct Client *client_p)
*/ */
client_p->servptr = &me; client_p->servptr = &me;
if (IsDead(client_p)) if (IsClosing(client_p))
return CLIENT_EXITED; return CLIENT_EXITED;
SetServer(client_p); SetServer(client_p);
@ -1082,9 +1069,14 @@ int server_estab(struct Client *client_p)
{ {
dlinkDelete(m, &unknown_list); dlinkDelete(m, &unknown_list);
dlinkAdd(client_p, m, &serv_list); dlinkAdd(client_p, m, &serv_list);
} else { }
sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ADMIN, "Tried to register (%s) server but it was already registered!?!", host); else
exit_client(client_p, client_p, client_p, "Tried to register server but it was already registered?!?"); {
sendto_realops_flags(FLAGS_ALL, L_ADMIN,
"Tried to register (%s) server but it was already registered!?!",
host);
exit_client(client_p, client_p, client_p,
"Tried to register server but it was already registered?!?");
} }
Count.server++; Count.server++;
@ -1232,7 +1224,8 @@ int server_estab(struct Client *client_p)
return 0; return 0;
} }
static void start_io(struct Client *server) static void
start_io(struct Client *server)
{ {
unsigned char *buf; unsigned char *buf;
int c = 0; int c = 0;
@ -1281,7 +1274,7 @@ static void start_io(struct Client *server)
} }
#endif #endif
while(1) for(;;)
{ {
linecount++; linecount++;
@ -1347,7 +1340,8 @@ static void start_io(struct Client *server)
* output - success: 0 / failure: -1 * output - success: 0 / failure: -1
* side effect - fork, and exec SERVLINK to handle this connection * side effect - fork, and exec SERVLINK to handle this connection
*/ */
static int fork_server(struct Client *server) static int
fork_server(struct Client *server)
{ {
int ret; int ret;
int i; int i;
@ -1413,7 +1407,7 @@ static int fork_server(struct Client *server)
else if (ret == 0) else if (ret == 0)
{ {
/* set our fds as non blocking and close everything else */ /* set our fds as non blocking and close everything else */
for(i = 0; i < HARD_FDLIMIT; i++) for(i = LOWEST_SAFE_FD; i < HARD_FDLIMIT; i++)
{ {
if ((i == slink_fds[0][0][0]) || (i == slink_fds[0][0][1]) || if ((i == slink_fds[0][0][0]) || (i == slink_fds[0][0][1]) ||
@ -1431,10 +1425,7 @@ static int fork_server(struct Client *server)
} }
else else
{ {
#if defined(VMS) || defined(__CYGWIN__) close(i);
if (i > 2) /* don't close std* */
#endif
close(i);
} }
} }
@ -1460,7 +1451,7 @@ static int fork_server(struct Client *server)
} }
else else
{ {
fd_close( server->localClient->fd ); fd_close(server->localClient->fd);
/* close the childs end of the pipes */ /* close the childs end of the pipes */
close(slink_fds[0][0][0]); close(slink_fds[0][0][0]);
@ -1546,7 +1537,8 @@ fork_error:
* side effects - send a server burst * side effects - send a server burst
* bugs - still too long * bugs - still too long
*/ */
static void server_burst(struct Client *client_p) static
void server_burst(struct Client *client_p)
{ {
/* /*
@ -1805,7 +1797,8 @@ remove_lazylink_flags(unsigned long mask)
* output - NONE * output - NONE
* side effects - * side effects -
*/ */
static void burst_members(struct Client *client_p, dlink_list *list) static void
burst_members(struct Client *client_p, dlink_list *list)
{ {
struct Client *target_p; struct Client *target_p;
dlink_node *ptr; dlink_node *ptr;
@ -1830,7 +1823,8 @@ static void burst_members(struct Client *client_p, dlink_list *list)
* output - NONE * output - NONE
* side effects - This version also has to check the bitmap for lazylink * side effects - This version also has to check the bitmap for lazylink
*/ */
static void burst_ll_members(struct Client *client_p, dlink_list *list) static void
burst_ll_members(struct Client *client_p, dlink_list *list)
{ {
struct Client *target_p; struct Client *target_p;
dlink_node *ptr; dlink_node *ptr;
@ -1857,7 +1851,8 @@ static void burst_ll_members(struct Client *client_p, dlink_list *list)
* output - none * output - none
* side effects - * side effects -
*/ */
void set_autoconn(struct Client *source_p,char *parv0,char *name,int newval) void
set_autoconn(struct Client *source_p,char *parv0,char *name,int newval)
{ {
struct ConfItem *aconf; struct ConfItem *aconf;
@ -1890,7 +1885,8 @@ void set_autoconn(struct Client *source_p,char *parv0,char *name,int newval)
} }
void initServerMask(void) void
initServerMask(void)
{ {
freeMask = 0xFFFFFFFFUL; freeMask = 0xFFFFFFFFUL;
} }
@ -1902,7 +1898,8 @@ void initServerMask(void)
* output - unsigned long next unused mask for use in LL * output - unsigned long next unused mask for use in LL
* side effects - * side effects -
*/ */
unsigned long nextFreeMask() unsigned long
nextFreeMask()
{ {
int i; int i;
unsigned long mask; unsigned long mask;
@ -2242,9 +2239,8 @@ serv_connect_callback(int fd, int status, void *data)
/* /*
* sends a CRYPTLINK SERV command. * sends a CRYPTLINK SERV command.
*/ */
void cryptlink_init(struct Client *client_p, void
struct ConfItem *aconf, cryptlink_init(struct Client *client_p, struct ConfItem *aconf, int fd)
int fd)
{ {
char *encrypted; char *encrypted;
char *key_to_send; char *key_to_send;

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.43 2003/03/06 11:33:33 fishwaldo Exp $ * $Id: s_user.c,v 1.44 2003/03/06 14:01:51 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
@ -304,20 +304,22 @@ register_local_user(struct Client *client_p, struct Client *source_p,
if(ConfigFileEntry.ping_cookie) if(ConfigFileEntry.ping_cookie)
{ {
if(!(source_p->flags & FLAGS_PINGSENT) && source_p->localClient->random_ping == 0) if(!IsPingSent(source_p) &&
{ source_p->localClient->random_ping == 0)
source_p->localClient->random_ping = (unsigned long)rand(); {
sendto_one(source_p, "PING :%lu", (unsigned long)source_p->localClient->random_ping); source_p->localClient->random_ping = (unsigned long)rand();
source_p->flags |= FLAGS_PINGSENT; sendto_one(source_p,
return -1; "PING :%lu",
} (unsigned long)source_p->localClient->random_ping);
if(!(source_p->flags2 & FLAGS2_PING_COOKIE)) SetPingSent(source_p);
{ return -1;
return -1; }
} if(!(source_p->flags2 & FLAGS2_PING_COOKIE))
{
return -1;
}
} }
user->last = CurrentTime; user->last = CurrentTime;
/* Straight up the maximum rate of flooding... */ /* Straight up the maximum rate of flooding... */
source_p->localClient->allow_read = MAX_FLOOD_BURST; source_p->localClient->allow_read = MAX_FLOOD_BURST;
@ -337,10 +339,10 @@ register_local_user(struct Client *client_p, struct Client *source_p,
aconf = ptr->data; aconf = ptr->data;
if (aconf == NULL) if (aconf == NULL)
{ {
(void)exit_client(client_p, source_p, &me, "*** Not Authorized"); exit_client(client_p, source_p, &me, "*** Not Authorized");
return(CLIENT_EXITED); return(CLIENT_EXITED);
} }
if (!IsGotId(source_p)) if (!IsGotId(source_p))
{ {
@ -348,14 +350,14 @@ register_local_user(struct Client *client_p, struct Client *source_p,
int i = 0; int i = 0;
if (IsNeedIdentd(aconf)) if (IsNeedIdentd(aconf))
{ {
ServerStats->is_ref++; ServerStats->is_ref++;
sendto_one(source_p, sendto_one(source_p,
":%s NOTICE %s :*** Notice -- You need to install identd to use this server", ":%s NOTICE %s :*** Notice -- You need to install identd to use this server",
me.name, client_p->name); me.name, client_p->name);
(void)exit_client(client_p, source_p, &me, "Install identd"); exit_client(client_p, source_p, &me, "Install identd");
return(CLIENT_EXITED); return(CLIENT_EXITED);
} }
p = username; p = username;
@ -375,13 +377,13 @@ register_local_user(struct Client *client_p, struct Client *source_p,
/* password check */ /* password check */
if (!BadPtr(aconf->passwd) && if (!BadPtr(aconf->passwd) &&
strcmp(source_p->localClient->passwd, aconf->passwd)) strcmp(source_p->localClient->passwd, aconf->passwd))
{ {
ServerStats->is_ref++; ServerStats->is_ref++;
sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), sendto_one(source_p, form_str(ERR_PASSWDMISMATCH),
me.name, source_p->name); me.name, source_p->name);
(void)exit_client(client_p, source_p, &me, "Bad Password"); exit_client(client_p, source_p, &me, "Bad Password");
return(CLIENT_EXITED); return(CLIENT_EXITED);
} }
memset(source_p->localClient->passwd,0, sizeof(source_p->localClient->passwd)); memset(source_p->localClient->passwd,0, sizeof(source_p->localClient->passwd));
/* report if user has &^>= etc. and set flags as needed in source_p */ /* report if user has &^>= etc. and set flags as needed in source_p */
@ -407,8 +409,8 @@ register_local_user(struct Client *client_p, struct Client *source_p,
nick, source_p->host); nick, source_p->host);
ServerStats->is_ref++; ServerStats->is_ref++;
(void)exit_client(client_p, source_p, &me, exit_client(client_p, source_p, &me,
"Sorry, server is full - try later"); "Sorry, server is full - try later");
return(CLIENT_EXITED); return(CLIENT_EXITED);
} }
@ -421,7 +423,7 @@ register_local_user(struct Client *client_p, struct Client *source_p,
nick, source_p->username, source_p->host); nick, source_p->username, source_p->host);
ServerStats->is_ref++; ServerStats->is_ref++;
ircsprintf(tmpstr2, "Invalid username [%s]", source_p->username); ircsprintf(tmpstr2, "Invalid username [%s]", source_p->username);
(void)exit_client(client_p, source_p, &me, tmpstr2); exit_client(client_p, source_p, &me, tmpstr2);
return(CLIENT_EXITED); return(CLIENT_EXITED);
} }
@ -492,18 +494,17 @@ register_local_user(struct Client *client_p, struct Client *source_p,
Count.totalrestartcount++; Count.totalrestartcount++;
m = dlinkFind(&unknown_list, source_p); if ((m = dlinkFindDelete(&unknown_list, source_p)) != NULL)
assert(m != NULL);
if(m != NULL)
{ {
dlinkDelete(m, &unknown_list); free_dlink_node(m);
dlinkAdd(source_p, m, &lclient_list); dlinkAdd(source_p, &source_p->localClient->lclient_node, &lclient_list);
} else { }
sendto_realops_flags(FLAGS_ALL|FLAGS_REMOTE, L_ADMIN, "Tried to register %s (%s@%s) but I couldn't find it?!?", else
nick, source_p->username, source_p->host); {
exit_client(client_p, source_p, &me, "Client exited"); sendto_realops_flags(FLAGS_ALL, L_ADMIN, "Tried to register %s (%s@%s) but I couldn't find it?!?",
return CLIENT_EXITED; nick, source_p->username, source_p->host);
exit_client(client_p, source_p, &me, "Client exited");
return CLIENT_EXITED;
} }
user_welcome(source_p); user_welcome(source_p);
@ -551,6 +552,7 @@ register_remote_user(struct Client *client_p, struct Client *source_p,
kill_client(client_p, source_p, "%s (Server doesn't exist)", kill_client(client_p, source_p, "%s (Server doesn't exist)",
me.name); me.name);
/* XXX */
SetKilled(source_p); SetKilled(source_p);
return exit_client(NULL, source_p, &me, "Ghosted Client"); return exit_client(NULL, source_p, &me, "Ghosted Client");
} }
@ -936,7 +938,7 @@ do_remote_user(char* nick, struct Client* client_p, struct Client* source_p,
int int
user_mode(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) user_mode(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
{ {
int flag = 0; int flag;
int i; int i;
char **p, *m; char **p, *m;
struct Client *target_p; struct Client *target_p;
@ -1151,7 +1153,7 @@ user_mode(struct Client *client_p, struct Client *source_p, int parc, char *parv
*/ */
send_umode_out(source_p, client_p, target_p, setflags); send_umode_out(source_p, client_p, target_p, setflags);
return 0; return(0);
} }
/* /*
@ -1243,13 +1245,20 @@ user_welcome(struct Client *source_p)
sendto_one(source_p, form_str(RPL_YOURHOST), me.name, source_p->name, sendto_one(source_p, form_str(RPL_YOURHOST), me.name, source_p->name,
get_listener_name(source_p->localClient->listener), ircd_version); get_listener_name(source_p->localClient->listener), ircd_version);
#if 0
/* /*
** Don't mess with this one - IRCII needs it! -Avalon ** Don't mess with this one - IRCII needs it! -Avalon
*/ */
/* No one has needed this in years, but I remember when IRCII did!
* It sure confused me why my IRCII client hung at start up
* when I was writing my first ircd from scratch. ;-)
* - Dianora
*/
sendto_one(source_p, sendto_one(source_p,
"NOTICE %s :*** Your host is %s, running version %s", "NOTICE %s :*** Your host is %s, running version %s",
source_p->name, get_listener_name(source_p->localClient->listener), source_p->name, get_listener_name(source_p->localClient->listener),
ircd_version); ircd_version);
#endif
sendto_one(source_p, form_str(RPL_CREATED),me.name,source_p->name,creation); sendto_one(source_p, form_str(RPL_CREATED),me.name,source_p->name,creation);
sendto_one(source_p, form_str(RPL_MYINFO), me.name, source_p->name, sendto_one(source_p, form_str(RPL_MYINFO), me.name, source_p->name,
@ -1324,7 +1333,7 @@ check_X_line(struct Client *client_p, struct Client *source_p)
get_client_name(client_p, HIDE_IP)); get_client_name(client_p, HIDE_IP));
} }
ServerStats->is_ref++; ServerStats->is_ref++;
(void)exit_client(client_p, source_p, &me, "Bad user info"); exit_client(client_p, source_p, &me, "Bad user info");
return (CLIENT_EXITED); return (CLIENT_EXITED);
} }
else else

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.12 2003/01/29 09:28:50 fishwaldo Exp $ * $Id: send.c,v 1.13 2003/03/06 14:01:51 fishwaldo Exp $
*/ */
#include "stdinc.h" #include "stdinc.h"
@ -60,10 +60,8 @@ send_linebuf_remote(struct Client *, struct Client *, buf_head_t *);
unsigned long current_serial=0L; unsigned long current_serial=0L;
static void static void
sendto_list_local(dlink_list *list, buf_head_t *linebuf); sendto_list_local(struct Client *one, dlink_list *list,
static void buf_head_t *linebuf);
sendto_list_local_butone(struct Client *one, dlink_list *list,
buf_head_t *linebuf);
static void static void
sendto_list_remote(struct Client *one, sendto_list_remote(struct Client *one,
@ -173,7 +171,7 @@ _send_linebuf(struct Client *to, buf_head_t *linebuf)
linebuf_len(&to->localClient->buf_sendq), linebuf_len(&to->localClient->buf_sendq),
get_sendq(to)); get_sendq(to));
if (IsClient(to)) if (IsClient(to))
to->flags |= FLAGS_SENDQEX; SetSendQExceeded(to);
dead_link_on_write(to, 0); dead_link_on_write(to, 0);
return -1; return -1;
} }
@ -191,7 +189,7 @@ _send_linebuf(struct Client *to, buf_head_t *linebuf)
to->localClient->sendM += 1; to->localClient->sendM += 1;
me.localClient->sendM += 1; me.localClient->sendM += 1;
send_queued_write(to->localClient->fd, to); send_queued_write(to->localClient->fd, to);
return 0; return 0;
} /* send_linebuf() */ } /* send_linebuf() */
@ -260,9 +258,8 @@ send_linebuf_remote(struct Client *to, struct Client *from,
** possible, and then if any data is left, a write is rescheduled. ** possible, and then if any data is left, a write is rescheduled.
*/ */
void void
send_queued_write(int fd, void *data) send_queued_write(int fd, struct Client *to)
{ {
struct Client *to = data;
int retlen; int retlen;
#ifndef NDEBUG #ifndef NDEBUG
struct hook_io_data hdata; struct hook_io_data hdata;
@ -338,7 +335,7 @@ send_queued_write(int fd, void *data)
/* Finally, if we have any more data, reschedule a write */ /* Finally, if we have any more data, reschedule a write */
if (linebuf_len(&to->localClient->buf_sendq)) if (linebuf_len(&to->localClient->buf_sendq))
comm_setselect(fd, FDLIST_IDLECLIENT, COMM_SELECT_WRITE, comm_setselect(fd, FDLIST_IDLECLIENT, COMM_SELECT_WRITE,
send_queued_write, to, 0); send_queued_slink_write, to, 0);
} /* send_queued_write() */ } /* send_queued_write() */
/* /*
@ -580,10 +577,13 @@ sendto_list_anywhere(struct Client *one, struct Client *from,
{ {
target_p = ptr->data; target_p = ptr->data;
if (IsDefunct(target_p))
continue;
if (target_p->from == one) if (target_p->from == one)
continue; continue;
if (MyConnect(target_p) && IsRegisteredUser(target_p) && !IsDead(target_p)) if (MyConnect(target_p) && IsRegisteredUser(target_p))
{ {
if(target_p->serial != current_serial) if(target_p->serial != current_serial)
{ {
@ -662,6 +662,9 @@ sendto_server(struct Client *one, struct Client *source_p,
{ {
client_p = ptr->data; client_p = ptr->data;
/* If dead already skip */
if (IsDead(client_p))
continue;
/* check against 'one' */ /* check against 'one' */
if (one && (client_p == one->from)) if (one && (client_p == one->from))
continue; continue;
@ -717,7 +720,8 @@ sendto_server(struct Client *one, struct Client *source_p,
* used by m_nick.c and exit_one_client. * used by m_nick.c and exit_one_client.
*/ */
void void
sendto_common_channels_local(struct Client *user, const char *pattern, ...) sendto_common_channels_local(struct Client *user, int touser,
const char *pattern, ...)
{ {
va_list args; va_list args;
dlink_node *ptr; dlink_node *ptr;
@ -732,22 +736,20 @@ sendto_common_channels_local(struct Client *user, const char *pattern, ...)
++current_serial; ++current_serial;
if (user->user != NULL) DLINK_FOREACH_SAFE(ptr, ptr_next, user->user->channel.head)
{ {
DLINK_FOREACH_SAFE(ptr, ptr_next, user->user->channel.head) chptr = ptr->data;
{
chptr = ptr->data;
sendto_list_local(&chptr->locchanops, &linebuf); sendto_list_local(user, &chptr->locchanops, &linebuf);
sendto_list_local(&chptr->lochalfops, &linebuf); sendto_list_local(user, &chptr->lochalfops, &linebuf);
sendto_list_local(&chptr->locvoiced, &linebuf); sendto_list_local(user, &chptr->locvoiced, &linebuf);
sendto_list_local(&chptr->locpeons, &linebuf); sendto_list_local(user, &chptr->locpeons, &linebuf);
sendto_list_local(&chptr->locchanadmins, &linebuf); sendto_list_local(user, &chptr->locchanadmins, &linebuf);
} }
if (MyConnect(user) && (user->serial != current_serial)) if (touser && MyConnect(user) &&
send_linebuf(user, &linebuf); (user->serial != current_serial))
} send_linebuf(user, &linebuf);
linebuf_donebuf(&linebuf); linebuf_donebuf(&linebuf);
} /* sendto_common_channels() */ } /* sendto_common_channels() */
@ -764,9 +766,7 @@ sendto_common_channels_local(struct Client *user, const char *pattern, ...)
* locally connected to this server. * locally connected to this server.
*/ */
void void
sendto_channel_local(int type, sendto_channel_local(int type, struct Channel *chptr, const char *pattern, ...)
struct Channel *chptr,
const char *pattern, ...)
{ {
va_list args; va_list args;
buf_head_t linebuf; buf_head_t linebuf;
@ -782,21 +782,21 @@ sendto_channel_local(int type,
switch(type) switch(type)
{ {
case NON_CHANOPS: case NON_CHANOPS:
sendto_list_local(&chptr->locvoiced, &linebuf); sendto_list_local(NULL, &chptr->locvoiced, &linebuf);
sendto_list_local(&chptr->locpeons, &linebuf); sendto_list_local(NULL, &chptr->locpeons, &linebuf);
break; break;
default: default:
case ALL_MEMBERS: case ALL_MEMBERS:
sendto_list_local(&chptr->locpeons, &linebuf); sendto_list_local(NULL, &chptr->locpeons, &linebuf);
case ONLY_CHANOPS_HALFOPS_VOICED: case ONLY_CHANOPS_HALFOPS_VOICED:
sendto_list_local(&chptr->locvoiced, &linebuf); sendto_list_local(NULL, &chptr->locvoiced, &linebuf);
case ONLY_CHANOPS_HALFOPS: case ONLY_CHANOPS_HALFOPS:
sendto_list_local(&chptr->lochalfops, &linebuf); sendto_list_local(NULL, &chptr->lochalfops, &linebuf);
case ONLY_CHANOPS: case ONLY_CHANOPS:
sendto_list_local(&chptr->locchanops, &linebuf); sendto_list_local(NULL, &chptr->locchanops, &linebuf);
case ONLY_CHANADMIN: case ONLY_CHANADMIN:
sendto_list_local(&chptr->locchanadmins, &linebuf); sendto_list_local(NULL, &chptr->locchanadmins, &linebuf);
} }
linebuf_donebuf(&linebuf); linebuf_donebuf(&linebuf);
} /* sendto_channel_local() */ } /* sendto_channel_local() */
@ -815,8 +815,7 @@ sendto_channel_local(int type,
*/ */
void void
sendto_channel_local_butone(struct Client *one, int type, sendto_channel_local_butone(struct Client *one, int type,
struct Channel *chptr, struct Channel *chptr, const char *pattern, ...)
const char *pattern, ...)
{ {
va_list args; va_list args;
buf_head_t linebuf; buf_head_t linebuf;
@ -832,21 +831,21 @@ sendto_channel_local_butone(struct Client *one, int type,
switch(type) switch(type)
{ {
case NON_CHANOPS: case NON_CHANOPS:
sendto_list_local_butone(one, &chptr->locvoiced, &linebuf); sendto_list_local(one, &chptr->locvoiced, &linebuf);
sendto_list_local_butone(one, &chptr->locpeons, &linebuf); sendto_list_local(one, &chptr->locpeons, &linebuf);
break; break;
default: default:
case ALL_MEMBERS: case ALL_MEMBERS:
sendto_list_local_butone(one, &chptr->locpeons, &linebuf); sendto_list_local(one, &chptr->locpeons, &linebuf);
case ONLY_CHANOPS_HALFOPS_VOICED: case ONLY_CHANOPS_HALFOPS_VOICED:
sendto_list_local_butone(one, &chptr->locvoiced, &linebuf); sendto_list_local(one, &chptr->locvoiced, &linebuf);
case ONLY_CHANOPS_HALFOPS: case ONLY_CHANOPS_HALFOPS:
sendto_list_local_butone(one, &chptr->lochalfops, &linebuf); sendto_list_local(one, &chptr->lochalfops, &linebuf);
case ONLY_CHANOPS: case ONLY_CHANOPS:
sendto_list_local_butone(one, &chptr->locchanops, &linebuf); sendto_list_local(one, &chptr->locchanops, &linebuf);
case ONLY_CHANADMIN: case ONLY_CHANADMIN:
sendto_list_local_butone(one, &chptr->locchanadmins, &linebuf); sendto_list_local(one, &chptr->locchanadmins, &linebuf);
} }
linebuf_donebuf(&linebuf); linebuf_donebuf(&linebuf);
} /* sendto_channel_local_butone() */ } /* sendto_channel_local_butone() */
@ -907,42 +906,6 @@ sendto_channel_remote(struct Client *one,
/* /*
* sendto_list_local * sendto_list_local
* *
* inputs - pointer to all members of this list
* - buffer to send
* - length of buffer
* output - NONE
* side effects - all members who are locally on this server on given list
* are sent given message. Right now, its always a channel list
* but there is no reason we could not use another dlink
* list to send a message to a group of people.
*/
static void
sendto_list_local(dlink_list *list, buf_head_t *linebuf_ptr)
{
dlink_node *ptr;
dlink_node *ptr_next;
struct Client *target_p;
DLINK_FOREACH_SAFE(ptr, ptr_next, list->head)
{
if ((target_p = ptr->data) == NULL)
continue;
if (!MyConnect(target_p) || IsDead(target_p))
continue;
if (target_p->serial == current_serial)
continue;
target_p->serial = current_serial;
send_linebuf(target_p, linebuf_ptr);
}
} /* sendto_list_local() */
/*
* sendto_list_local_butone
*
* inputs - pointer to client not to send to * inputs - pointer to client not to send to
* - pointer to all members of this list * - pointer to all members of this list
* - buffer to send * - buffer to send
@ -954,8 +917,8 @@ sendto_list_local(dlink_list *list, buf_head_t *linebuf_ptr)
* another dlink list to send a message to a group of people. * another dlink list to send a message to a group of people.
*/ */
static void static void
sendto_list_local_butone(struct Client *one, dlink_list *list, sendto_list_local(struct Client *one, dlink_list *list,
buf_head_t *linebuf_ptr) buf_head_t *linebuf_ptr)
{ {
dlink_node *ptr; dlink_node *ptr;
dlink_node *ptr_next; dlink_node *ptr_next;
@ -969,7 +932,7 @@ sendto_list_local_butone(struct Client *one, dlink_list *list,
if (target_p == one) if (target_p == one)
continue; continue;
if (!MyConnect(target_p) || IsDead(target_p)) if (!MyConnect(target_p) || IsDefunct(target_p))
continue; continue;
if (target_p->serial == current_serial) if (target_p->serial == current_serial)
@ -979,7 +942,7 @@ sendto_list_local_butone(struct Client *one, dlink_list *list,
send_linebuf(target_p, linebuf_ptr); send_linebuf(target_p, linebuf_ptr);
} }
} /* sendto_list_local_butone() */ } /* sendto_list_local() */
/* /*
* sendto_list_remote(struct Client *one, * sendto_list_remote(struct Client *one,
@ -1093,6 +1056,9 @@ sendto_match_butone(struct Client *one, struct Client *from,
if (client_p == one) /* must skip the origin !! */ if (client_p == one) /* must skip the origin !! */
continue; continue;
if (IsDefunct(client_p))
continue;
if (match_it(client_p, mask, what)) if (match_it(client_p, mask, what))
send_linebuf(client_p, &local_linebuf); send_linebuf(client_p, &local_linebuf);
} }
@ -1155,12 +1121,12 @@ sendto_anywhere(struct Client *to, struct Client *from,
va_list args; va_list args;
buf_head_t linebuf; buf_head_t linebuf;
linebuf_newbuf(&linebuf);
va_start(args, pattern);
if (IsDead(to)) if (IsDead(to))
return; return;
linebuf_newbuf(&linebuf);
va_start(args, pattern);
if(MyClient(to)) if(MyClient(to))
{ {
if(IsServer(from)) if(IsServer(from))

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: tools.c,v 1.4 2002/09/19 05:41:11 fishwaldo Exp $ * $Id: tools.c,v 1.5 2003/03/06 14:01:51 fishwaldo Exp $
* *
* When you update these functions make sure you update the ones in tools.h * When you update these functions make sure you update the ones in tools.h
* as well!!! * as well!!!
@ -62,7 +62,7 @@ dlinkAdd(void *data, dlink_node * m, dlink_list * list)
/* Assumption: If list->tail != NULL, list->head != NULL */ /* Assumption: If list->tail != NULL, list->head != NULL */
if (list->head != NULL) if (list->head != NULL)
list->head->prev = m; list->head->prev = m;
else if (list->tail == NULL) else /* if (list->tail == NULL) */
list->tail = m; list->tail = m;
list->head = m; list->head = m;
@ -97,7 +97,7 @@ dlinkAddTail(void *data, dlink_node *m, dlink_list *list)
/* Assumption: If list->tail != NULL, list->head != NULL */ /* Assumption: If list->tail != NULL, list->head != NULL */
if (list->tail != NULL) if (list->tail != NULL)
list->tail->next = m; list->tail->next = m;
else if (list->head == NULL) else /* if (list->head == NULL) */
list->head = m; list->head = m;
list->tail = m; list->tail = m;
@ -186,19 +186,8 @@ dlinkFindDelete(dlink_list *list, void *data)
{ {
dlink_node *m; dlink_node *m;
DLINK_FOREACH(m, list->head) m = dlinkFind(list, data);
{ if (m)
if(m->data != data) dlinkDelete(m, list);
continue; return(m);
if (m->next != NULL)
m->next->prev = m->prev;
else
list->tail = m->prev;
m->next = m->prev = NULL;
list->length--;
return m;
}
return(NULL);
} }