/************************************************************************
 *   psybnc2.2.2, src/p_hash.c
 *   Copyright (C) 2001 the most psychoid  and
 *                      the cool lam3rz IRC Group, IRCnet
 *			http://www.psychoid.lam3rz.de
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 1, or (at your option)
 *   any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#ifndef lint
static char rcsid[] = "@(#)$Id: p_hash.c, v 2.2.2 2001/03/25 02:02:02 psychoid Exp $";
#endif

#define P_HASH

#include <p_global.h>

/* local types */

struct hasht {
    char *command;
    int(*handler)(int);
    char *comment;
    char *helpfile;
    int proceed; /* 0 = dont proceed, 1 = proceed, 2 = return code of routine (0 or 1) */
    int adminonly; /* 0 = normal users, 1 = admins */
};


struct hasht inboundhash[]={
    {"PRIVMSG",	cmdprivmsg,	NULL,					NULL			,2,0},
    {"PING",	cmdping,	NULL,					NULL			,0,0},
    {"QUIT",	cmdquit,	NULL,					NULL			,0,0},
    {"WHO",	cmdwho,		NULL,					NULL			,1,0},
    {"USER",	cmduser,	NULL,					NULL			,0,0},
#ifdef PARTYCHANNEL
    {"JOIN",	cmdjoin,	NULL,					NULL			,2,0},	
    {"PART",	cmdpart,	NULL,					NULL			,2,0},	
    {"TOPIC",	cmdtopic,	NULL,					NULL			,2,0},
#endif
    {"NICK",	cmdnick,	NULL,					NULL			,1,0},
    {"BWHO",	cmdbwho,	"Lists all Users on the Bouncer",	"help/BWHO.TXT"		,0,0},
    {"PASSWORD",cmdpassword,	"Sets your or another Users Password(Admin)","help/PASSWORD.TXT",0,0},
    {"VHOST",	cmdvhost,	"Sets your vhost to connect thru",	"help/VHOST.TXT"	,0,0},
#ifdef PROXYS
    {"PROXY",	cmdproxy,	"Sets your proxy to connect thru",	"help/PROXY.TXT"	,0,0},
#endif
    {"SETUSERNAME",cmdsetusername,"Sets your User Name",		"help/SETUSERNAME.TXT"	,0,0},
    {"SETAWAY",	cmdsetaway,	"Sets your away-Text when you leave",	"help/SETAWAY.TXT"	,0,0},
    {"SETLEAVEMSG",cmdsetleavemsg,"Sets your Leave-MSG when you leave",	"help/SETLEAVEMSG.TXT"	,0,0},
    {"LEAVEQUIT",cmdleavequit,	"If set to 1, parts all channels on quit","help/LEAVEQUIT"	,0,0},
    {"SETAWAYNICK",cmdsetawaynick,"Sets your nick when you are offline","help/SETAWAYNICK.TXT"	,0,0},
    {"JUMP",	cmdjump,	"Jumps to the next IRC-Server",		"help/JUMP.TXT"		,0,0},
#ifndef DYNAMIC
    {"BQUIT",	cmdbquit,	"Quits your current Server Connection",	"help/BQUIT.TXT"	,0,0},
    {"BCONNECT",cmdbconnect,	"Reconnects a bquitted Connection",	"help/BCONNECT.TXT"	,0,0},
#endif
    {"AIDLE",cmdaidle,		"Enables/Disables Antiidle",		"help/AIDLE.TXT"	,0,0},
    {"AUTOREJOIN",cmdautorejoin,"Enables/Disables Auto-Rejoin",		"help/AUTOREJOIN.TXT"	,0,0},
    {"ADDSERVER",cmdaddserver,	"Adds an IRC-Server to your Serverlist","help/ADDSERVER.TXT"	,0,0},
    {"DELSERVER",cmddelserver,	"Deletes an IRC-Server by number",	"help/DELSERVER.TXT"	,0,0},
    {"LISTSERVERS",cmdlistservers,"Lists all IRC-Servers added",	"help/LISTSERVERS.TXT"	,0,0},
#ifdef NETWORK
    {"ADDNETWORK",cmdaddnetwork,"Adds a seperate Network to your client","help/ADDNETWORK.TXT"	,0,0},
    {"DELNETWORK",cmddelnetwork,"Deletes a Network from your client",	"help/DELNETWORK.TXT"	,0,0},
    {"SWITCHNET",cmdswitchnet,	"Switches to a given Network",		"help/SWITCHNET.TXT"	,0,0},
#endif
    {"ADDOP",	cmdaddop,	"Adds a User who may get Op from you",	"help/ADDOP.TXT"	,0,0},
    {"DELOP",	cmddelop,	"Deletes an added User who got Op",	"help/DELOP.TXT"	,0,0},
    {"LISTOPS",	cmdlistops,	"Lists all added Ops",			"help/LISTOPS.TXT"	,0,0},
    {"ADDAUTOOP",cmdaddautoop,	"Adds a User who gets Auto-Op from you","help/ADDAUTOOP.TXT"	,0,0},
    {"DELAUTOOP",cmddelautoop,	"Deletes an added User who got Op",	"help/DELAUTOOP.TXT"	,0,0},
    {"LISTAUTOOPS",cmdlistautoops,"Lists all added Auto-Ops",		"help/LISTAUTOOPS.TXT"	,0,0},
    {"ADDBAN",	cmdaddban,	"Adds a ban (global or to a channel)",	"help/ADDBAN.TXT"	,0,0},
    {"DELBAN",	cmddelban,	"Deletes a ban by Number",		"help/DELBAN.TXT"	,0,0},
    {"LISTBANS",cmdlistbans,	"Lists all bans",			"help/LISTBANS.TXT"	,0,0},
    {"ADDASK",	cmdaddask,	"Adds a host/bot to ask Op from",	"help/ADDASK.TXT"	,0,0},
    {"DELASK",	cmddelask,	"Deletes a host/bot to ask Op by Number","help/DELASK.TXT"	,0,0},
    {"LISTASK",	cmdlistask,	"Lists the hosts/bots to ask Op from",	"help/LISTASK.TXT"	,0,0},
#ifdef DCCCHAT
    {"ADDDCC",	cmdadddcc,	"Adds a DCC-Connection to a bot",	"help/ADDDCC.TXT"	,0,0},
    {"LISTDCC",	cmdlistdcc,	"Lists all added DCC-Connectionc",	"help/LISTDCC.TXT"	,0,0},
    {"DELDCC",	cmddeldcc,	"Deletes a DCC-Connection by number",	"help/DELDCC.TXT"	,0,0},
    {"DCCCHAT",	cmddccchat,	"Offers a DCC Chat to a given IRC User","help/DCCCHAT.TXT"	,0,0},
    {"DCCANSWER",cmddccanswer,	"Answers to a DCC Chat-Request",	"help/DCCANSWER.TXT"	,0,0},
#define DCCALLOW 1
    {"DCCENABLE",cmddccenable,	"Enables/Disables DCC thru psybnc",	"help/DCCENABLE.TXT"	,0,0},
#endif
#ifdef DCCFILES
    {"DCCSEND",	cmddccsend,	"Sends a file to a given IRC User",	"help/DCCSEND.TXT"	,0,0},
    {"DCCGET",	cmddccget,	"Gets a DCC Send File from an IRC User","help/DCCGET.TXT"	,0,0},
    {"DCCSENDME",cmddccsendme,	"Sends the bouncer User a File",	"help/DCCSENDME.TXT"	,0,0},
    {"AUTOGETDCC",cmdautogetdcc,"always get offered Files",		"help/AUTOGETDCC.TXT"	,0,0},
#ifndef DCCALLOW
    {"DCCENABLE",cmddccenable,	"Enables/Disables DCC thru psybnc",	"help/DCCENABLE.TXT"	,0,0},
#endif
#endif
#ifdef DCCANCEL
    {"DCCCANCEL",cmddcccancel,	"Cancels a dccchat or a transfer",	"help/DCCCANCEL.TXT"	,0,0},
#endif
#ifndef DYNAMIC
    {"PLAYPRIVATELOG",	playprivatelog,	"Plays your Message Log",	"help/PLAYPRIVATELOG.TXT",0,0},
    {"ERASEPRIVATELOG",eraseprivatelog,"Erases your Message Log",	"help/ERASEPRIVATELOG.TXT",0,0},
#endif
#ifdef TRAFFICLOG
#ifndef DYNAMIC
    {"ADDLOG",	cmdaddlog,	"Adds a Log source / filter",		"help/ADDLOG.TXT"	,0,0},
    {"DELLOG",	cmddellog,	"Deletes a Log source by number",	"help/DELLOG.TXT"	,0,0},
    {"LISTLOGS",cmdlistlogs,	"Lists all added Log sources/filters",	"help/LISTLOGS.TXT"	,0,0},
    {"PLAYTRAFFICLOG",playtrafficlog,	"Plays the Traffic Log",	"help/PLAYTRAFFICLOG.TXT",0,0},
    {"ERASETRAFFICLOG",erasetrafficlog,"Erases the Traffic Log",	"help/ERASETRAFFICLOG.TXT",0,0},
#endif
#endif
#ifdef CRYPT
    {"SETUSERKEY",cmdsetuserkey,"Sets the Key for an encrypted User-Connection","help/SETUSERKEY.TXT",0,0},
    {"SETLINKKEY",cmdsetlinkkey,"Sets the Key for an encrypted Link-Connection","help/SETLINKKEY.TXT",0,1},
    {"ENCRYPT",cmdencrypt,	"Encrypts talk to a given channel/user","help/ENCRYPT.TXT"	,0,0},
    {"DELENCRYPT",cmddelencrypt,"Deletes an encryption entry by number","help/DELENCRYPT.TXT"	,0,0},
    {"LISTENCRYPT",cmdlistencrypt,"Shows a List of encrypted talks",	"help/LISTENCRYPT.TXT"	,0,0},
#endif
#ifdef TRANSLATE
    {"TRANSLATE",cmdtranslate,	"Adds a translator to/from channels/users","help/TRANSLATE.TXT"	,0,0},
    {"DELTRANSLATE",cmddeltranslate,"Deletes a translator by number",	"help/DELTRANSLATE.TXT"	,0,0},
    {"LISTTRANSLATE",cmdlisttranslate,"Shows a List of translated talks","help/LISTTRANSLATE.TXT",0,0},
#endif
    {"BREHASH",	cmdrehash,	"Rehashes the proxy and resets all Connections","help/REHASH.TXT",0,1},
#ifdef MULTIUSER
    {"MADMIN",	cmdadmin,	"Gives a User an Admin flag",		"help/MADMIN.TXT"	,0,1},
    {"UNADMIN",	cmdunadmin,	"Removes the Admin flag from a User",	"help/UNADMIN.TXT"	,0,1},
    {"BKILL",	cmdbkill,	"Kills a User from the proxy",		"help/BKILL.TXT"	,0,1},
#endif
    {"SOCKSTAT",cmdsockstat,	"Shows/Logs the current Connections",	"help/SOCKSTAT.TXT"	,0,1},
#ifdef MULTIUSER
    {"ADDUSER",	cmdadduser,	"Adds a new User to the Bouncer",	"help/ADDUSER.TXT"	,0,1},
    {"DELUSER", cmddeluser,	"Deletes a User from the Bouncer",	"help/DELUSER.TXT"	,0,1},
#endif
#ifdef LINKAGE
    {"NAMEBOUNCER",cmdname,	"Names your bouncer (needed for linking)","help/NAMEBOUNCER.TXT",0,1},
    {"LINKTO",	cmdlinkto,	"Adds a bouncer Link to the Host/Port",	"help/LINKTO.TXT"	,0,1},
    {"LINKFROM",cmdlinkfrom,	"Adds a bouncer Link from your Bouncer","help/LINKFROM.TXT"	,0,1},
    {"RELAYLINK",cmdrelaylink,	"Allows or disables a relayable Link",	"help/RELAYLINK.TXT"	,0,1},
    {"DELLINK",	cmddellink,	"Deletes a Link to a bouncer",		"help/DELLINK.TXT"	,0,1},
    {"LISTLINKS",cmdlistlinks,	"Lists all Links to/from the Bouncer",	"help/LISTLINKS.TXT"	,0,0},
    {"RELINK",	cmdrelink,	"Resets a link to a bouncer by number",	"help/RELINK.TXT"	,0,1},
#endif
#ifndef DYNAMIC
    {"PLAYMAINLOG",playmainlog,	"Plays the Connection Log",		"help/PLAYMAINLOG.TXT"	,0,1},
    {"ERASEMAINLOG",erasemainlog,"Erases the Connection Log",		"help/ERASEMAINLOG.TXT"	,0,1},
#endif
    {"ADDALLOW",cmdaddallow,	"Adds a host allow to connect",		"help/ADDALLOW.TXT"	,0,1},
    {"DELALLOW",cmddelallow,	"Deletes a host allow",			"help/DELALLOW.TXT"	,0,1},
    {"LISTALLOW",cmdlistallow,	"Lists the host allows on your proxy",	"help/LISTALLOW.TXT"	,0,1},
#ifdef SCRIPTING
    {"SRELOAD",cmdreloadscript,	"Reloads the Script for the User",	"help/SRELOAD.TXT"	,0,0},
    {"LISTTASKS",cmdlisttasks,	"Lists the current running tasks",	"help/LISTTASKS.TXT"	,0,0},
#endif
    {"BHELP",	printhelp,	"Lists this help or help on a topic",	"help/BHELP.TXT"	,0,0},
    {NULL,	NULL,		NULL,					NULL		,0,0}
};

struct hasht outboundhash[]={
    {"ERROR",	msgERROR,	NULL,NULL,0,0},
    {"001",	msg001,		NULL,NULL,1,0},
    {"002",	msg002to005,	NULL,NULL,1,0},
    {"003",	msg002to005,	NULL,NULL,1,0},
    {"004",	msg002to005,	NULL,NULL,1,0},
    {"005",	msg002to005,	NULL,NULL,1,0},
    {"251",	msg251to255,	NULL,NULL,1,0},
    {"252",	msg251to255,	NULL,NULL,1,0},
    {"253",	msg251to255,	NULL,NULL,1,0},
    {"254",	msg251to255,	NULL,NULL,1,0},
    {"255",	msg251to255,	NULL,NULL,1,0},
    {"372",	msg372to375,	NULL,NULL,2,0},
    {"375",	msg372to375,	NULL,NULL,2,0},
    {"376",	msg376,		NULL,NULL,0,0},
    {"352",	msg352,		NULL,NULL,2,0},
    {"353",	msg353,		NULL,NULL,1,0},
    {"315",	msg315,		NULL,NULL,2,0},
    {"324",	msg324,		NULL,NULL,1,0},
    {"332",	msg332,		NULL,NULL,1,0},
    {"366",	msg366,		NULL,NULL,1,0},
    {"432",	msg432to437,	NULL,NULL,2,0},
    {"433",	msg432to437,	NULL,NULL,2,0},
    {"437",	msg432to437,	NULL,NULL,2,0},
    {"PING",	pong,		NULL,NULL,0,0},
    {"NICK",	gotnick,	NULL,NULL,1,0},
    {"JOIN",	gotjoin,	NULL,NULL,1,0},
    {"PART",	gotpart,	NULL,NULL,1,0},
    {"QUIT",	gotquit,	NULL,NULL,1,0},
    {"KICK",	gotkick,	NULL,NULL,1,0},
    {"MODE",	gotmode,	NULL,NULL,1,0},
    {"TOPIC",	gottopic,	NULL,NULL,1,0},
    {"PRIVMSG", msgprivmsg,	NULL,NULL,2,0},        
    {"NOTICE",  msgprivmsg,	NULL,NULL,2,0},        
    {NULL,	NULL,		NULL,NULL,0,0}
};

#ifdef INTNET

struct inthasht {
    char *command;
    int(*handler)(int,int);
    char *comment;
    char *helpfile;
    int proceed; /* 0 = dont proceed, 1 = proceed, 2 = return code of routine (0 or 1) */
    int adminonly; /* 0 = normal users, 1 = admins */
};
    
struct inthasht inthash[]={
    {"PRIVMSG",	cmdintprivmsg,	NULL,					NULL			,0,0},
    {"NOTICE",	cmdintnotice,	NULL,					NULL			,0,0},
    {"JOIN",	cmdintjoin,	NULL,					NULL			,0,0},	
    {"MODE",	cmdintmode,	NULL,					NULL			,0,0},
    {"PART",	cmdintpart,	NULL,					NULL			,0,0},	
    {"KICK",	cmdintkick,	NULL,					NULL			,0,0},
    {"NICK",	cmdintnick,	NULL,					NULL			,0,0},
    {"NAMES",	cmdintnames,	NULL,					NULL			,0,0},
    {"QUIT",	cmdintquit,	NULL,					NULL			,0,0},
    {"WHO",	cmdintwho,	NULL,					NULL			,0,0},
    {"WHOIS",	cmdintwhois,	NULL,					NULL			,0,0},
    {"USER",	cmdintuser,	NULL,					NULL			,0,0},
    {"TOPIC",	cmdinttopic,	NULL,					NULL			,0,0},
    {"INVITE",	cmdintinvite,	NULL,					NULL			,0,0},
    {NULL,	NULL,		NULL,					NULL			,0,0}
};

/* the internal network inbound hash processing */

int internalinbound(int iusern, int link)
{
    int rc,ca;
    int usern;
    int hashn=0;
    int ret,dummy;
    pcontext;    
    usern=iusern;
    if ((usern>0 && user(usern)->instate > STD_NOCON) || link>0) {
	 parse();
	 if(ifcommand("NICK") && usern>0) return 0x0; /* nick only changed on server event */
	 while(inthash[hashn].command!=NULL)
	 {
	    if (ifcommand(inthash[hashn].command))
	    {
		ret=inthash[hashn].proceed;
		if(inthash[hashn].adminonly==1 && user(usern)->rights!=RI_ADMIN && link==0)
		{
		    ssnprintf(user(iusern)->insock,":%s-psybnc.net 481 %s :Permission denied - You are not a bouncer admin",me,user(usern)->nick);
		    return 0x0;
		}
		pcontext;    
		if(ret==2)
		{
		    if(inthash[hashn].handler!=NULL)
			ret=(*inthash[hashn].handler)(usern,link);
		}
		else
		{
		    if(inthash[hashn].handler!=NULL)
			dummy=(*inthash[hashn].handler)(usern,link);
		}
		pcontext;    
		if (ret==0) return 0x0;
		break;
	    }
	    hashn++;
	  }
	  if(user(usern)->instate==STD_CONN && link==0)
	  {
	      ssnprintf(user(usern)->instate,"%s-psybnc.net 421 %s %s :Unknown Command",me,user(usern)->nick,irccommand);
	  }    
    }
}

#endif

/* displays a hash help text list, or a file to a topic */

int userhelp(int usern, char *cmd)
{
    int hashn=0;
    static char bufx[200];
    char lc=' ';
    FILE *inp;
    pcontext;    
    if(cmd==NULL)
    {
	while(inboundhash[hashn].command!=NULL)
	{
	    if(inboundhash[hashn].adminonly==1)
		lc='*';
	    else
		lc=' ';    
	    if (inboundhash[hashn].comment!=NULL)
	    {
		ssnprintf(user(usern)->insock,":irc.psychoid.net NOTICE %s :BHELP %c %-15s - %s\n",user(usern)->nick,lc,inboundhash[hashn].command,inboundhash[hashn].comment);
	    }
	    hashn++;
	}
	ssnprintf(user(usern)->insock,":irc.psychoid.net NOTICE %s :BHELP Use /QUOTE bhelp <command> for details.\n",user(usern)->nick);
#ifdef SCRIPTING
	aliasbhelp(usern);
#endif
    } else {
	strmncpy(irccommand,cmd,sizeof(irccommand));
	ucase(irccommand);
	ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de PRIVMSG %s :Help for: %s\n",user(usern)->nick,irccommand);
	while(inboundhash[hashn].command!=NULL)
	{
	    if(ifcommand(inboundhash[hashn].command) && inboundhash[hashn].helpfile!=NULL)
	    {
		if ((inp=fopen(inboundhash[hashn].helpfile,"r"))==NULL)
		{
		    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de PRIVMSG %s :Helpfile %s not available.\n",user(usern)->nick,inboundhash[hashn].helpfile);
		    return 0x0;
		}
		while(fgets(bufx,sizeof(bufx),inp))
		{
		    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de PRIVMSG %s :%s\n",user(usern)->nick,bufx);
		}
		fclose(inp);
		break;
	    }
	    hashn++;
	}
        if(inboundhash[hashn].command==NULL)
	{
	    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de PRIVMSG %s :No Help found for: %s\n",user(usern)->nick,irccommand);
	}
    }
    return 0x0;
}

/* the userinbound hash processing */

int userinbound(int iusern)
{
    int rc,ca;
    int usern,ausern;
    int hashn=0;
    int ret,dummy;
    pcontext;    
    ausern=iusern;
    if(user(iusern)->parent!=0) ausern=user(iusern)->parent;
    usern=ausern;
    usern=checknetwork(usern);
    while (checknetwork(ausern)!=ausern); /* filtering other network tokens */
    if(usern<=1000)
    {
	parse();
#ifdef SCRIPTING
	ca=executealias(usern);
	if(ca==0)
	{
#endif
	    while(inboundhash[hashn].command!=NULL)
    	    {
		if (ifcommand(inboundhash[hashn].command))
		{
		    ret=inboundhash[hashn].proceed;
		    if(inboundhash[hashn].adminonly==1 && user(usern)->rights!=RI_ADMIN)
		    {
			ssnprintf(user(ausern)->insock,":-psyBNC!psyBNC@lam3rz.de PRIVMSG %s :Only admins may use that command.\r\n",user(ausern)->nick);
			return 0x0;
		    }
		    pcontext;    
		    if(ret==2)
		    {
			if(inboundhash[hashn].handler!=NULL)
			    ret=(*inboundhash[hashn].handler)(usern);
		    }
		    else
		    {
			if(inboundhash[hashn].handler!=NULL)
			    dummy=(*inboundhash[hashn].handler)(usern);
		    }
		    pcontext;    
		    if (ret==0) return 0x0;
		    break;
		}
		hashn++;
	    }
#ifdef SCRIPTING
	}
#endif
    }
#ifdef INTNET
    if(usern>10000)
    	internalinbound(usern-10000,-1);
    else
#endif
    if (user(usern)->outstate > STD_NOCON) {
#ifdef SCRIPTING
        if(ca==0)
#endif
    	    writesock(user(usern)->outsock,ircbuf);
    }
}

/* the useroutbound hash processing */

int useroutbound(int usern)
{
    int rc,ret;
    char *po;
    int hashn=0;
    int dummy;
    pcontext;    
    if(usern<=10000) 
    {
	if (user(usern)->parent != 0) {
	    user(usern)->insock=user(user(usern)->parent)->insock;
	    user(usern)->instate=user(user(usern)->parent)->instate;
	}
	if (user(usern)->autopongreply ==0) {
	    ssnprintf(user(usern)->outsock,"PONG :%s\r\n",user(usern)->server);
	    user(usern)->autopongreply=200;
	}
	user(usern)->autopongreply--;
	parse();
#ifdef SCRIPTING
	if(!ifcommand("MODE")) /* modes get triggered from parsing */
	    serverevent(usern);
#endif
	while(outboundhash[hashn].command!=NULL)
	{
	    if (ifcommand(outboundhash[hashn].command))
	    {
		ret=outboundhash[hashn].proceed;
		pcontext;    
		if(ret==2)
		{
		    if(outboundhash[hashn].handler!=NULL)
			ret=(*outboundhash[hashn].handler)(usern);
		}
		else
		{
		    if(outboundhash[hashn].handler!=NULL)
			dummy=(*outboundhash[hashn].handler)(usern);
		}
		pcontext;    
		if (ret==0) return 0x0;
		break;
	    }
	    hashn++;
	}
    }
    pcontext;    
    if (user(usern)->instate == STD_CONN && getpsocketbysock(user(usern)->insock)!=NULL) 
    {
        pcontext;    
	if (user(usern)->parent != 0 || usern>10000) {
    	    addtoken(usern); /* adding the network token */
	}	
	if (*ircbuf) writesock(user(usern)->insock,ircbuf);
#ifdef TRAFFICLOG
    } else {
        pcontext;    
        if (*ircbuf) checklogging(usern);
#endif
    }
    return 0x0;
}

