/************************************************************************
 *   psybnc2.2.2, src/p_client.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_client.c, v 2.2.2 2001/03/25 02:02:02 psychoid Exp $";
#endif

#define P_CLIENT

#include <p_global.h>

/* the partychannel commands */

#ifdef PARTYCHANNEL

int ipartychan()
{	
    char *pt,*pt2;
    char sbuf[200];
    char ebuf[4096];
    strmncpy(sbuf,PARTYCHAN,sizeof(sbuf));
    ucase(sbuf);
    pt=strstr(irccontent,PARTYCHAN);
    if(pt==NULL) pt=strstr(irccontent,sbuf);
    if(pt==NULL) return 0;
    pt2=pt+strlen(sbuf);
    *pt=0;
    if(*pt2==',')
    {
	pt2++;
	ap_snprintf(ebuf,sizeof(ebuf),"%s%s",irccontent,pt2);
	strmncpy(irccontent,ebuf,sizeof(irccontent));
	return 2;
    }
    if(pt!=irccontent) return 2;
    return 1;
}

int cmdjoin(int usern)
{
    int rc;
    char siccont[1024];
    rc=ipartychan();
    strmncpy(siccont,irccontent,sizeof(siccont));
    if(rc>0)
    {
	if(user(usern)->sysmsg==0)
	{
	    user(usern)->sysmsg=1;
	    joinparty(usern);
	}
	ap_snprintf(ircbuf,sizeof(ircbuf),"JOIN :%s\r\n",siccont);
	if(rc==1) return 0;
    }
    return 1;
}


/* the partychannel commands */

int cmdtopic(int usern)
{
    struct usernodes *th;
    int rc;
    if(strmcmp(ircto,PARTYCHAN))
	{
	    th=usernode;
	    while(th!=NULL)
	    {
		rc=th->uid;
		if(user(rc)->instate>STD_NOCON && user(rc)->sysmsg==1)
		{
		    ssnprintf(user(rc)->insock,":$%s*%s!%s@%s TOPIC " PARTYCHAN " :%s\r\n",
			    user(usern)->login,me,user(usern)->login,me,irccontent);
		}
		th=th->next;
	    }
	    ap_snprintf(ircbuf,sizeof(ircbuf),":%s!*@%s TOPIC " PARTYCHAN " :%s\r\n",
		        user(usern)->login,me,irccontent);
	    strmncpy(partytopic,irccontent,sizeof(partytopic));
	    broadcast(0);
	    return 0;
	}
    return 1;
}

int cmdpart(int usern)
{
    char siccont[1024];
    int rc;
    rc=ipartychan();
    strmncpy(siccont,irccontent,sizeof(siccont));
    if(rc>0)    
    {
	if(user(usern)->sysmsg==1)
	{
	    user(usern)->sysmsg=0;
	    ssnprintf(user(usern)->insock,":%s!%s@%s PART " PARTYCHAN " :%s\r\n",user(usern)->nick,user(usern)->login,user(usern)->host,user(usern)->nick);
	    sysparty("User %s logged off.",user(usern)->login);
	}
	ap_snprintf(ircbuf,sizeof(ircbuf),"PART :%s\r\n",siccont);
	if(rc==1) return 0;
    }
    return 1;
}

#endif

/* printing server banner */

int repeatserverinit(int usern)
{
    FILE *userb;
    struct linknodes *dcc;
    char buf[1024];
    char fname[40];
    char *zer;
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    ap_snprintf(fname,sizeof(fname),"motd/USER%d.MOTD",usern);
    if ((userb=fopen(fname,"r")) == NULL) {
	return -1;
    }
    while (fgets(buf,sizeof(buf),userb))
    {
	strmncpy(ircbuf,buf,sizeof(ircbuf));
	/* replacing the initial IP for DCC sessions */
	zer=strstr(ircbuf," 001 ");
	if (zer!=NULL)
	{
	    zer=strchr(zer,'@');
	    if (zer!=NULL)
	    {
		zer++;
		*zer=0;
		if(strlen(ircbuf)+strlen(user(userp)->host)<sizeof(ircbuf))
		    strcat(ircbuf,user(userp)->host);
	    }
	}
	/* done */
	parentnick(usern);
	writesock(user(usern)->insock,ircbuf);
    }
    fclose(userb);
    if (checkforlog(usern))
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :You have Messages. Type /QUOTE PLAYPRIVATELOG to read your messages.",user(userp)->firstnick);
    if (strlen(user(usern)->away)>0) {
	writesock(user(usern)->outsock,"AWAY\r\n");
	strcpy(buf,".AWAY\r\n");
	dcc=user(usern)->dcc;
	while(dcc!=NULL)
	{
	    if (dcc->link!=NULL)
	    {
		if (dcc->link->outstate==STD_CONN)
		    writesock(dcc->link->outsock,buf);
	    }
	    dcc=dcc->next;
	}
    }
    user(usern)->gotop=0;
}
/* who is on the bounce ? */

int cmdbwho(usern)
{
    struct usernodes *th;
    int userl;
    char buf[400];
    char i;
    int userp;
    int last;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    th=usernode;
    while (th!=NULL)
    {
	 userl=th->uid;
	 last=0;
         if (strlen(user(userl)->login)) {
	    if (user(userl)->parent != 0) i='^'; else i='*';
	    if (*user(userl)->host==0) { i=' ';last=1; }
	    if (user(userl)->parent != 0) last=0;
	    if (user(usern)->rights == RI_USER) {
	       if(last==1)
  	           ap_snprintf(buf,sizeof(buf),":-psyBNC!psyBNC@lam3rz.de NOTICE %s :%c %s(%s) [%s:%s] :%s [last:%-20s]\r\n",user(userp)->nick,i,user(userl)->login,user(userl)->nick,user(userl)->network,user(userl)->server,user(userl)->user,user(userl)->last);
	       else
  	           ap_snprintf(buf,sizeof(buf),":-psyBNC!psyBNC@lam3rz.de NOTICE %s :%c %s(%s) [%s:%s] :%s\r\n",user(userp)->nick,i,user(userl)->login,user(userl)->nick,user(userl)->network,user(userl)->server,user(userl)->user);
	    } else {
	       if(last==1)
  	           ap_snprintf(buf,sizeof(buf),":-psyBNC!psyBNC@lam3rz.de NOTICE %s :%c %s(%s)@%s [%s:%s] :%s [last:%-20s]\r\n",user(userp)->nick,i,user(userl)->login,user(userl)->nick,user(userl)->host,user(userl)->network,user(userl)->server,user(userl)->user,user(userl)->last);
	       else
  	           ap_snprintf(buf,sizeof(buf),":-psyBNC!psyBNC@lam3rz.de NOTICE %s :%c %s(%s)@%s [%s:%s] :%s\r\n",user(userp)->nick,i,user(userl)->login,user(userl)->nick,user(userl)->host,user(userl)->network,user(userl)->server,user(userl)->user);
	    }   
	    writesock(user(usern)->insock,buf);
	 }
	 th=th->next;
    }
    ap_snprintf(ircbuf,sizeof(ircbuf),":%s!*@%s BWHO :\r\n",user(usern)->login,me);
    broadcast(0);
}

/* socket stats */

int cmdsockstat(int usern)
{
    log(LOG_INFO,usern,"Logging Current Socketstats");
    usr1_error(31337);
    log(LOG_INFO,usern,"End of stats.");
}

/* printing out the welcome text */

int firstwelcome(void)
{
    char buf[1];
    pcontext;
    ssnprintf(user(0)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Welcome %s !\r\n",user(0)->nick,user(0)->nick);
#ifdef ANONYMOUS
    ssnprintf(user(0)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :This is an anonymous psyBNC-IRC-Proxy.\r\n",user(0)->nick);
#else
    ssnprintf(user(0)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :You are the first to connect to this new proxy server.\r\n",user(0)->nick);
    ssnprintf(user(0)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :You are the proxy-admin. Use ADDSERVER to add a server so the bouncer may connect.\r\n",user(0)->nick);
#endif
    *buf=*ircto;
    *ircto=0;
    printhelp(0);
    *ircto=*buf;
}

/* first user connects */

int firstuser(npeer) {
    int linkto;
    pcontext;
    user(0)->rights = RI_ADMIN;
    strmncpy(irccontent,newpeer(npeer)->user,sizeof(irccontent));
    strmncpy(ircto,newpeer(npeer)->login,sizeof(ircto));
    strmncpy(user(0)->nick,newpeer(npeer)->nick,sizeof(user(0)->nick));
    strmncpy(user(0)->login,newpeer(npeer)->login,sizeof(user(0)->login));
    strmncpy(user(0)->pass,newpeer(npeer)->pass,sizeof(user(0)->pass));
    user(0)->insock = newpeer(npeer)->insock;
    user(0)->instate = STD_CONN;    
    firstwelcome();
    linkto=cmdadduser(0);
    if(linkto==-1)
    {
	return -1;
    }
    if(linkto==1) user(linkto)->rights=RI_ADMIN;
    writeuser(linkto);
    return linkto;
}

/* adding a user by an admin or the firstuser handling */

int cmdadduser(int usern)
{
    int uind;
    int userp;
    char *pt;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (strlen(ircto) == 0) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Ident given. Syntax is ADDUSER ident :username\r\n",user(userp)->nick);
       return -1;
    }
    if (strlen(irccontent) == 0) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Username given. Syntax is ADDUSER ident :username\r\n",user(userp)->nick);
       return -1;
    }
    if (checkuser(ircto) >0) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :User %s already existing.\r\n",user(userp)->nick,ircto);
       return -1;
    }    
    uind = 1;
    U_CREATE=1;
    while (uind<=MAX_USER)
    {
	if (*user(uind)->login == 0) {
	    pt=strchr(ircto,' ');
	    if(pt!=NULL)
	    {
		*pt++=0;
		strmncpy(user(uind)->crkey,user(uind)->crkey,sizeof(user(uind)->crkey));
	    } else {
		*user(uind)->crkey=0;
	    }
	    strmncpy(user(uind)->wantnick,ircto,sizeof(user(uind)->wantnick));
	    strmncpy(user(uind)->nick,ircto,sizeof(user(uind)->nick));
	    strmncpy(user(uind)->login,ircto,sizeof(user(uind)->login));
	    strmncpy(user(uind)->user,irccontent,sizeof(user(uind)->user));	    
	    if (usern==0)
	       strmncpy(user(uind)->pass,user(0)->pass,sizeof(user(uind)->pass));
	    else
	       strmncpy(user(uind)->pass,randstring(8),sizeof(user(uind)->pass));
	    user(uind)->outstate = STD_NOCON;
	    user(uind)->instate = STD_NOCON;
	    user(uind)->rights = 0;
	    user(uind)->dccenabled=1;
	    user(uind)->autorejoin=1;
	    user(uind)->sysmsg = 1;
	    log(LOG_INFO,usern,"New User:%s (%s) added by %s",user(uind)->login,user(uind)->user,user(usern)->login);
	    if(usern!=0)
		ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :New User '%s' added. Password set to '%s'",user(usern)->nick,user(uind)->login,user(uind)->pass);
	    writeuser(uind);
	    clearuser(uind);
	    loaduser(uind);
	    return uind;    	
	}
	uind++;
    }
    log(LOG_ERROR,usern,"Maximum Users exceeded.");
    return -1;
}


/* delete a user */

int cmddeluser(int usern)
{
    int uind;
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (strlen(irccontent) == 0) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Nick given. Syntax is DELUSER nick\r\n",user(userp)->nick);
       return -1;
    }
    if ((uind = checkuser(irccontent)) == 0) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :User %s not found.\r\n",user(userp)->nick,irccontent);
       return -1;
    }    
    if (uind==1)
    {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :User %s is the Owner. He cant be deleted.\r\n",user(userp)->nick,irccontent);
       return -1;
    }
    deluser(uind);
    log(LOG_INFO,usern,"User %s deleted by %s.",user(uind)->nick,user(userp)->login);
    loaduser(uind);
    return 0x0;
}

#ifdef NETWORK

/* adding a network-user by an user */

int cmdaddnetwork(int usern)
{
    int uind;
    pcontext;
    if (user(usern)->parent!=0)
    {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :You cant add a network to a network\r\n",user(user(usern)->parent)->nick);
       return -1;
    }
    if (strlen(irccontent) == 0) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Network given. Syntax is ADDNETWORK network\r\n",user(usern)->nick);
       return -1;
    }
    if (strlen(irccontent) > 10) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Network may be at max. 10 characters.\r\n",user(usern)->nick);
       return -1;
    }
    if (checkusernetwork(usern) >0) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Network %s already existing.\r\n",user(usern)->nick,irccontent);
       return -1;
    }    
    uind = 1;
    U_CREATE=1;
    while (uind<MAX_USER)
    {
	if (strlen(user(uind)->login) == 0) {
	    strmncpy(user(uind)->wantnick,user(usern)->nick,sizeof(user(uind)->wantnick));
	    strmncpy(user(uind)->nick,user(usern)->nick,sizeof(user(uind)->nick));
	    strmncpy(user(uind)->login,user(usern)->login,sizeof(user(uind)->login));
	    strmncpy(user(uind)->user,user(usern)->user,sizeof(user(uind)->user));
	    strmncpy(user(uind)->pass,user(usern)->pass,sizeof(user(uind)->pass));
	    user(uind)->outstate = STD_NOCON;
	    user(uind)->instate = user(usern)->instate;
	    user(uind)->insock = user(usern)->insock;
	    user(uind)->rights = user(usern)->rights;
	    user(uind)->parent = usern;
	    strmncpy(user(uind)->network,irccontent,sizeof(user(uind)->network));
	    writeuser(uind);
	    clearuser(uind);
	    loaduser(uind);
	    log(LOG_INFO,usern,"New Network %s added by %s",user(uind)->network,user(usern)->login);
	    return uind;    	
	}
	uind++;
    }
    log(LOG_ERROR,usern,"Maximum Users exceeded.");
    return -1;
}

/* delete a network */

int cmddelnetwork(int usern)
{
    int uind;
    pcontext;
    if (strlen(irccontent) == 0) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Network given. Syntax is DELNETWORK network\r\n",user(usern)->nick);
       return -1;
    }
    if ((uind = checkusernetwork(usern)) == 0) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Network %s not found.\r\n",user(usern)->nick,irccontent);
       return -1;
    }    
    deluser(uind);
    log(LOG_INFO,usern,"Network %s deleted by %s.",user(uind)->network,user(uind)->login);
    loaduser(uind);
}

/* switch to another network */

int cmdswitchnet(int usern)
{
    int uind;
    char ocont[400];
    struct uchannelt *chan;
    struct usernodes *und;
    struct usert *un,*un1;
    if(user(usern)->parent!=0) return 0x0;
    pcontext;
    if (strlen(irccontent) == 0) 
    {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No existent Network given. Use SWITCHNET newnet :existent\r\n",user(usern)->nick);
       return -1;
    }
    if (strlen(ircto) == 0) 
    {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Source-Network given. Use SWITCHNET newnet :existent\r\n",user(usern)->nick);
       return -1;
    }
    if ((uind = checkusernetwork(usern)) == 0) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Network %s not found.\r\n",user(usern)->nick,irccontent);
       return -1;
    }    
    strmncpy(ocont,irccontent,sizeof(ocont));
    strmncpy(irccontent,ircto,sizeof(irccontent));
    if(checkusernetwork(usern)!=0)
    {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Network %s already existent.\r\n",user(usern)->nick,irccontent);
       return -1;
    }    
    strmncpy(irccontent,ocont,sizeof(irccontent));
    /* part channels of main and network
       main */
    chan=user(usern)->channels;
    while(chan!=NULL)
    {
	if(chan->ison!=0)
	{
	    ssnprintf(user(usern)->insock,":irc.psychoid.net KICK %s %s :Switching Network",chan->name,user(usern)->nick);
	}
	chan=chan->next;
    }    
    chan=user(uind)->channels;
    while(chan!=NULL)
    {
	if(chan->ison!=0)
	{
	    ssnprintf(user(usern)->insock,"irc.psychoid.net KICK #%s~%s %s :Switching Network",user(uind)->network,chan->name,user(usern)->nick);
	}
	chan=chan->next;
    }    
    /* parted all channels, setting new network and parent */
    un=user(usern);
    un1=user(uind);
    und=usernode;
    while(und!=NULL)
    {
	if(und->user!=NULL)
	{
	    if(und->user==un1)
	    {
		und->user=un;
		und->uid=usern;
	    }
	    else if(und->user==un)
	    {
		und->user=un1;
		und->uid=uind;
	    }
	}
	und=und->next;
    }
    user(uind)->network[0]=0;
    user(uind)->parent=0;
    strmncpy(user(usern)->network,ircto,sizeof(user(usern)->network));
    user(usern)->parent=uind;
    writeuser(uind);
    writeuser(usern);
    flushconfig();
    ssnprintf(user(usern)->insock,":%s!%s@%s NICK :%s",user(usern)->nick,user(usern)->login,user(usern)->host,user(uind)->nick);
    rejoinclient(uind);
    rejoinclient(usern);
}

#endif

/* change password */

int cmdpassword(int usern)
{
    char iset[8];
    char fname[20];
    char buf[400];
    int uind;
    pcontext;
    uind=usern;    
    if (strlen(irccontent) == 0) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Password given. Syntax is PASSWORD [user] :newpass\r\n",user(usern)->nick);
       return -1;
    }
    if (strlen(ircto)) {
       uind = checkuser(ircto);
       if (uind==0) {
           ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :User %s not found\r\n",user(usern)->nick,ircto);
           return -1;
       }
    } else
       strmncpy(ircto,user(usern)->login,sizeof(ircto));
    if(uind!=usern && user(usern)->rights!=RI_ADMIN)
    {
           ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :You cant change other peoples passwords.\r\n",user(usern)->nick);
           return -1;
    }
    strmncpy(user(uind)->pass,irccontent,sizeof(user(uind)->pass));
    ap_snprintf(fname,sizeof(fname),"USER%d",uind);
    ap_snprintf(buf,sizeof(buf),"%s%s",slt1,slt2);
    ap_snprintf(user(uind)->pass,sizeof(user(uind)->pass),"=%s",BLOW_stringencrypt(buf,irccontent));
    writeini("USER","PASS",fname,user(uind)->pass);
    flushconfig();
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Password for %s changed to '%s'\r\n",user(usern)->nick,ircto,irccontent);
    return 0x0;
}

int cmdnick(int usern)
{
    pcontext;
    strmncpy(user(usern)->wantnick,irccontent,sizeof(user(usern)->wantnick));
    return 0x0;
}

/* jumping servers */

int cmdjump(int usern)
{
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (user(usern)->outstate == STD_CONN) {
	if(*irccontent!=0)
	{
	    if(atoi(irccontent)>0 && atoi(irccontent)<21)
	    {
		user(usern)->currentserver=atoi(irccontent)-1;
	    }
	}
	ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Hop requested, changing servers.\r\n",user(userp)->nick);
	log(LOG_INFO,usern,"Hop requested by %s. Quitting.",user(usern)->login);
	user(usern)->afterquit=1;
	writesock(user(usern)->outsock,"QUIT :changing servers\r\n");
    } else {
	ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :You are not connected.\r\n",user(userp)->nick);
    }
    return 0x0;
}

/* setting vhost */

int cmdvhost(int usern)
{
    char fname[20];
    char buf[100];
    int vl;
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    vl=atoi(ircto);
    if (vl!=0)
    {
	if (datalink(vl)->type!=1 && datalink(vl)->type!=2)
	{
	    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Link '%d' not found.\r\n",user(usern)->nick,vl);
	    return 0x0;
	}
    }
    user(usern)->vlink=vl;
    strmncpy(user(usern)->vhost,irccontent,sizeof(user(usern)->vhost));
    ap_snprintf(fname,sizeof(fname),"USER%d",usern);
    writeini("USER","VHOST",fname,user(usern)->vhost);
    ap_snprintf(buf,sizeof(buf),"%d",vl);
    writeini("USER","VLINK",fname,buf);
    flushconfig();
    if (vl!=0)
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :VHOST changed to '%s' on Link %d. Use JUMP to activate changed hostname.\r\n",user(userp)->nick,user(usern)->vhost,vl);
    else
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :VHOST changed to '%s'. Use JUMP to activate changed hostname.\r\n",user(userp)->nick,user(usern)->vhost);
    return 0x0;
}

#ifdef PROXYS

/* setting proxy */

int cmdproxy(int usern)
{
    char fname[20];
    char buf[100];
    char grnf[400];
    char *pt,*ept,*dpt;
    int vl;
    int userp;
    pcontext;
    ap_snprintf(grnf,sizeof(grnf),"%s:%s",ircto,irccontent);
    pt=grnf;
    ept=pt;
    while(*ept==' ') ept++;
    pt=ept;
    dpt=ept;
    while(ept!=NULL)
    {
	 ept=strchr(ept+1,':');
         if(ept!=NULL) dpt=ept;
    }
    if(dpt==ept) return 0x0;
    if(dpt==NULL || pt==NULL) return 0x0;
    *dpt=0;
    dpt++;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    strmncpy(user(usern)->proxy,pt,sizeof(user(usern)->proxy));
    user(usern)->pport=atoi(dpt);
    ap_snprintf(fname,sizeof(fname),"USER%d",usern);
    writeini("USER","PROXY",fname,user(usern)->proxy);
    ap_snprintf(buf,sizeof(buf),"%d",user(usern)->pport);
    writeini("USER","PPORT",fname,buf);
    flushconfig();
    if(user(usern)->pport==0)
	ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :PROXY removed. Use JUMP to activate changed proxyusage.\r\n",user(userp)->nick);
    else
	ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :PROXY set to '%s:%d'. Use JUMP to activate changed proxyusage. Use PROXY : to reset to non-proxy usage.\r\n",user(userp)->nick,user(usern)->proxy,user(usern)->pport);
    return 0x0;
}

#endif


/* setting antiidle */

int cmdaidle(int usern)
{
    char fname[20];
    char buf[10];
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (atoi(irccontent) != 0 && atoi(irccontent) != 1) {
	ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Use AIDLE 0 or AIDLE 1.\r\n",user(userp)->nick);
	return 0x0;
    }
    user(usern)->antiidle=atoi(irccontent);
    ap_snprintf(buf,sizeof(buf),"%d",user(usern)->antiidle);
    ap_snprintf(fname,sizeof(fname),"USER%d",usern);
    writeini("USER","AIDLE",fname,buf);
    flushconfig();
    if (user(usern)->antiidle==1) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :AIDLE enabled.\r\n",user(userp)->nick);
    } else {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :AIDLE disabled.\r\n",user(userp)->nick);
    }
    return 0x0;
}

/* setting autojoin */

int cmdautorejoin(int usern)
{
    char fname[20];
    char buf[10];
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (atoi(irccontent) != 0 && atoi(irccontent) != 1) {
	ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Use AUTOREJOIN 0 or AUTOREJOIN 1.\r\n",user(userp)->nick);
	return 0x0;
    }
    user(usern)->autorejoin=atoi(irccontent);
    ap_snprintf(buf,sizeof(buf),"%d",user(usern)->autorejoin);
    ap_snprintf(fname,sizeof(fname),"USER%d",usern);
    writeini("USER","AUTOREJOIN",fname,buf);
    flushconfig();
    if (user(usern)->autorejoin==1) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :AUTOREJOIN enabled.\r\n",user(userp)->nick);
    } else {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :AUTOREJOIN disabled.\r\n",user(userp)->nick);
    }
    return 0x0;
}

/* setting leavequit */

int cmdleavequit(int usern)
{
    char fname[20];
    char buf[10];
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (atoi(irccontent) != 0 && atoi(irccontent) != 1) {
	ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Use LEAVEQUIT 0 or LEAVEQUIT 1.\r\n",user(userp)->nick);
	return 0x0;
    }
    user(usern)->leavequit=atoi(irccontent);
    ap_snprintf(buf,sizeof(buf),"%d",user(usern)->leavequit);
    ap_snprintf(fname,sizeof(fname),"USER%d",usern);
    writeini("USER","LEAVEQUIT",fname,buf);
    flushconfig();
    if (user(usern)->leavequit==1) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :LEAVEQUIT enabled.\r\n",user(userp)->nick);
    } else {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :LEAVEQUIT disabled.\r\n",user(userp)->nick);
    }
    return 0x0;
}

/* cmddccenable - setting if dccs are allowed to the bouncer */

int cmddccenable(int usern)
{
    char fname[20];
    char buf[10];
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (atoi(irccontent) != 0 && atoi(irccontent) != 1) {
	ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Use DCCENABLE 0 or DCCENABLE 1.\r\n",user(userp)->nick);
	return 0x0;
    }
    user(usern)->dccenabled=atoi(irccontent);
    ap_snprintf(buf,sizeof(buf),"%d",user(usern)->dccenabled);
    ap_snprintf(fname,sizeof(fname),"USER%d",usern);
    writeini("USER","DCCENABLED",fname,buf);
    flushconfig();
    if (user(usern)->dccenabled==1) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Pending DCCs enabled.\r\n",user(userp)->nick);
    } else {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Pending DCCs disabled.\r\n",user(userp)->nick);
    }
    return 0x0;
}

/* setting away parameter */

int cmdsetaway(int usern)
{
    char fname[20];
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    strmncpy(user(usern)->away,irccontent,sizeof(user(usern)->away));
    ap_snprintf(fname,sizeof(fname),"USER%d",usern);
    writeini("USER","AWAY",fname,user(usern)->away);
    flushconfig();
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :AWAY changed to '%s'.\r\n",user(userp)->nick,user(usern)->away);
    return 0x0;
}

/* setting leavemsg parameter */

int cmdsetleavemsg(int usern)
{
    char fname[20];
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    strmncpy(user(usern)->leavemsg,irccontent,sizeof(user(usern)->leavemsg));
    ap_snprintf(fname,sizeof(fname),"USER%d",usern);
    writeini("USER","LEAVEMSG",fname,user(usern)->leavemsg);
    flushconfig();
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :LEAVE Messages changed to '%s'. Message will be posted to channels when leaving.\r\n",user(userp)->nick,user(usern)->leavemsg);
    return 0x0;
}

/* setting away nick */

int cmdsetawaynick(int usern)
{
    char fname[20];
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    strmncpy(user(usern)->awaynick,irccontent,sizeof(user(usern)->awaynick));
    ap_snprintf(fname,sizeof(fname),"USER%d",usern);
    writeini("USER","AWAYNICK",fname,user(usern)->awaynick);
    flushconfig();
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :AWAY-Nick changed to '%s'.\r\n",user(userp)->nick,user(usern)->awaynick);
    return 0x0;
}


/* setting username */

int cmdsetusername(int usern)
{
    char fname[20];
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    strmncpy(user(usern)->user,irccontent,sizeof(user(usern)->user));
    ap_snprintf(fname,sizeof(fname),"USER%d",usern);
    writeini("USER","USER",fname,user(usern)->user);
    flushconfig();
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Username changed to '%s'. You need to use JUMP to activate it.\r\n",user(userp)->nick,user(usern)->user);
    return 0x0;
}

int cmdaddserver(int usern)
{
    char fname[20];
    char buf[400];
    char gsrv[400];
    char *pt,*dpt,*ept;
    char *pw;
    char dpw[]="None";
    int prt;
    int nmsrv;
    int rc;
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (strlen(ircto) == 0) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No server given. Syntax is ADDSERVER hostname :port\r\n",user(userp)->nick);
       return -1;
    }
    ap_snprintf(fname,sizeof(fname),"USER%d",usern);
    nmsrv=1;
    while (nmsrv < 10)
    {
	  ap_snprintf(gsrv,sizeof(gsrv),"%s:%s",ircto,irccontent);
	  pt=gsrv;
	  ept=pt;
          while(*ept==' ') ept++;
	  pt=ept;
          dpt=ept;
	  while(ept!=NULL)
	  {
 	     ept=strchr(ept+1,':');
	     if(ept!=NULL) dpt=ept;
          }
          if(dpt==ept) return 0x0;
          if(dpt==NULL || pt==NULL) return 0x0;
          *dpt=0;
          dpt++;
	  
          rc=getserver(nmsrv,usern);
	  if (rc<0) {
              pw=strchr(dpt,' ');
	      if(pw!=NULL)
	      {
	          *pw=0;
		  pw++;
		  ap_snprintf(buf,sizeof(buf),"SPASS%d",nmsrv);
		  writeini("SERVERS",buf,fname,pw);
	      } else {
	          pw=dpw;
	      }
	      if (strlen(dpt)==0) {
	         ap_snprintf(irccontent,sizeof(irccontent),"6667");
	      } else {
	         strmncpy(irccontent,dpt,sizeof(irccontent));
	      }
	      ap_snprintf(buf,sizeof(buf),"PORT%d",nmsrv);
	      writeini("SERVERS",buf,fname,irccontent);
	      ap_snprintf(buf,sizeof(buf),"SERVER%d",nmsrv);
	      writeini("SERVERS",buf,fname,pt);
	      flushconfig();
              ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Server %s port %s (password: %s) added.\r\n",user(userp)->nick,pt,irccontent,pw);
	      user(usern)->delayed=0;	
	      return 0x0;
	  }
	  nmsrv++;
    }
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No server entry free.\r\n",user(userp)->nick);
    return -1;
}

int cmddelserver(int usern)
{
    char fname[20];
    char buf[400];
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (strlen(irccontent) == 0) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No server given. Syntax is DELSERVER number\r\n",user(userp)->nick);
       return -1;
    }
    ap_snprintf(fname,sizeof(fname),"USER%d",usern);
    ap_snprintf(buf,sizeof(buf),"SPASS%s",irccontent);
    writeini("SERVERS",buf,fname,NULL);
    ap_snprintf(buf,sizeof(buf),"PORT%s",irccontent);
    writeini("SERVERS",buf,fname,NULL);
    ap_snprintf(buf,sizeof(buf),"SERVER%s",irccontent);
    writeini("SERVERS",buf,fname,NULL);
    flushconfig();
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Server %s deleted.\r\n",user(userp)->nick,irccontent);
    return -1;
}

int cmdlistservers(int usern)
{
    char fname[20];
    char gsrv[400];
    char sicsrv[400];
    int sicport;
    int prt;
    int nmsrv;
    int rc;
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    sicport=user(usern)->port;
    strmncpy(sicsrv,user(usern)->server,sizeof(sicsrv));
    ap_snprintf(fname,sizeof(fname),"USER%d",usern);
    nmsrv=1;
    while (nmsrv < 10)
    {
          rc=getserver(nmsrv,usern);
	  if (rc==0) {
              ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Server #%d: %s port %d\r\n",user(userp)->nick,nmsrv,user(usern)->server,user(usern)->port);
	  }
	  nmsrv++;
    }
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :End of Servers.\r\n",user(userp)->nick);
    strmncpy(user(usern)->server,sicsrv,sizeof(user(usern)->server));
    user(usern)->port = sicport;
    return -1;
}

#ifdef LINKAGE

int cmdlinkfrom(int usern)
{
    cmdaddlink(usern,LI_ALLOW);
}

int cmdlinkto(int usern)
{
    cmdaddlink(usern,LI_LINK);
}

int cmdaddlink(int usern,int type)
{
    char iset[8];
    char fname[20];
    int newlink;
    char *pt,*ept,*dpt;
    char fr[]="from";
    char tr[]="to";
    char *tp;
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (*me==0) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :You did not define the Name of this bouncer. Do NAMEBOUNCER name first.\r\n",user(userp)->nick);
       return -1;
    }
    if (strlen(irccontent) == 0) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Host given. Use %s name :host:port.\r\n",user(userp)->nick,irccommand);
       return -1;
    }
    if (strlen(ircto) == 0 && type!=LI_LINK) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No name given. Use %s name :host:port.\r\n",user(userp)->nick,irccommand);
       return -1;
    }
    if (strchr(irccontent,':')==NULL) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Port given. Use %s name :host:port.\r\n",user(userp)->nick,irccommand);
       return -1;
    }
    pt=strchr(irccontent,':');
    ept=pt;
    dpt=pt;
    while(ept!=NULL)
    {
	ept=strchr(ept+1,':');
	if(ept!=NULL) dpt=ept;
    }
    pt=dpt;
    *pt=0;pt++;
    if (atoi(pt)==0) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Invalid Port. Use %s name :host:port.\r\n",user(userp)->nick,irccommand);
       return -1;
    }
    if (type==LI_LINK)
    {
	strmncpy(ircto,me,sizeof(ircto));
	strmncpy(datalink(newlink)->pass,randstring(15),sizeof(datalink(newlink)->pass));
	tp=tr;
    } else
	tp=fr;
    newlink=getlinkbyname(ircto);
    if (newlink!=0 && type!=LI_LINK) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Link %s already existent.\r\n",user(userp)->nick,ircto);
       return -1;
    }
    newlink=getnewlink();
    if (newlink==0) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No more free Link-Connections.\r\n",user(userp)->nick);
       return -1;
    }
    clearlink(newlink);
    strmncpy(datalink(newlink)->host,irccontent,sizeof(datalink(newlink)->host));
    datalink(newlink)->port=atoi(pt);
    datalink(newlink)->allowrelay=0;
    strmncpy(datalink(newlink)->name,ircto,sizeof(datalink(newlink)->name));
    datalink(newlink)->type=type;
    if (type==LI_ALLOW)
	 strmncpy(datalink(newlink)->iam,ircto,sizeof(datalink(newlink)->iam));
    writelink(newlink);
    log(LOG_INFO,usern,"New Link '%s' %s %s:%d added by %s.",datalink(newlink)->name,tp,datalink(newlink)->host,datalink(newlink)->port,user(usern)->login);
    return 0x0;
}

/* set / unset the relay flag */
int cmdrelaylink(int usern)
{
    char iset[8];
    char fname[20];
    char yo[]="enable";
    char nes[]="disable";
    int lnk;
    char *pt;
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (strlen(irccontent) == 0 || (atoi(irccontent)!=0 && atoi(irccontent)!=1)) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No valid value given. Use RELAYLINK linknumber :0|1.\r\n",user(userp)->nick);
       return -1;
    }
    if (strlen(ircto)==0) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No linknumber given. Use RELAYLINK linknumber :0|1.\r\n",user(userp)->nick);
       return -1;
    }
    lnk=atoi(ircto);
    if (datalink(lnk)->type==0) lnk=0;
    if (lnk==0)
    {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Link %s unknown.\r\n",user(userp)->nick,ircto);
       return -1;
    }    
    datalink(lnk)->allowrelay=atoi(irccontent);
    writelink(lnk);
    if (datalink(lnk)->allowrelay==0)
	pt=nes;
    else
	pt=yo;
    log(LOG_INFO,usern,"Relay linking for link '%s' %sd by %s",ircto,pt,user(usern)->login);
    return 0x0;
}

int cmddellink(int usern)
{
    char iset[8];
    char fname[20];
    int lnk=0;
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (strlen(irccontent) == 0) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Link-Number defined.\r\n",user(userp)->nick);
       return -1;
    }
    if (datalink(atoi(irccontent))->type!=0)
	lnk=atoi(irccontent);
    if (lnk==0)
    {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Link %s unknown.\r\n",user(userp)->nick,irccontent);
       return -1;
    }
    log(LOG_INFO,usern,"Link %d removed by %s",lnk,user(usern)->login);
    if (datalink(lnk)->outstate==STD_CONN)
    {
	sysparty("Link to %s removed by %s",datalink(lnk)->iam,user(usern)->login);
	killsocket(datalink(lnk)->outsock);
	removetopology(me,datalink(lnk)->iam,lostlink);
    }    
    if (datalink(lnk)->instate==STD_CONN)
    {
	sysparty("Link from %s removed by %s",datalink(lnk)->iam,user(usern)->login);
	killsocket(datalink(lnk)->insock);
	removetopology(me,datalink(lnk)->iam,lostlink);
    }    
    clearlink(lnk);
    eraselinkini(lnk);
}

int iiusern;

/* listevent; */

int listsinglelink(char *dispbuf)
{
    ssnprintf(user(iiusern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :%s",user(iiusern)->nick,dispbuf);
    return 0x0;
}

/* list the links */

int cmdlistlinks(int usern)
{
    struct linknodes *th;
    int linkn=1;
    char o[]="->";
    char i[]="<-";
    char r[]="R ";
    char l;
    char *pt;
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Listing locally defined Links.\r\n",user(usern)->nick); 
    th=linknode;
    while (th!=NULL)
    {
	linkn=th->uid;
	l=' ';
	if (datalink(linkn)->type!=0)
	{
	    if (datalink(linkn)->type==LI_LINK) 
	    {
		pt=o;
		if (datalink(linkn)->outstate==STD_CONN) l='*';
	    }
	    if (datalink(linkn)->type==LI_ALLOW) 
	    {
		if (datalink(linkn)->instate==STD_CONN) l='*';
		pt=i;
	    }
	    if (datalink(linkn)->type==LI_RELAY) { pt=r; l='*';}
	    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :%c%d %s %s %s(%d)\r\n",user(userp)->nick,l,linkn,pt,datalink(linkn)->iam,datalink(linkn)->host,datalink(linkn)->port); 
	}
	th=th->next;
    }
    iiusern=usern;
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :The Link-Tree\r\n",user(usern)->nick); 
    displaytopology(listsinglelink);
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :End of Tree.\r\n",user(usern)->nick); 
    return 0x0;
}

#endif

#ifdef DCCCHAT

int cmdadddcc(int usern)
{
    char *npt;
    char *upt;
    char *ppt;
    char *hpt;
    char *spt;
    char *tpt;
    int port;
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    npt=strchr(ircbuf,' ');
    if (npt!=NULL)
    {
	*npt=0;
	npt++;
	upt=strchr(npt,' ');
	if (upt!=NULL)
	{
	    *upt=0;
	    upt++;
	    ppt=strchr(upt,' ');
	    if (ppt!=NULL)
	    {
		*ppt=0;
		ppt++;
		hpt=strchr(ppt,':');
		if (hpt!=NULL)
		{
		    *hpt=0;
		    hpt++;
		    spt=strchr(hpt,':');
		    tpt=spt;
		    while(tpt!=NULL)
		    {
			spt=tpt;
			tpt++;
			tpt=strchr(tpt,':'); /* stripping ipv6 addresses */
		    }
		    if (spt!=NULL)
		    {
			*spt=0;
			spt++;
			port=atoi(spt);
			if (port!=0)
			{
			    adddcc(usern,hpt,port,upt,ppt,npt,0);
			    return 0x0;
			}
		    }
		}
	    }
	}
    }
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Wrong Parameters. Use ADDDCC botname user pass :host:port\r\n",user(userp)->nick); 
    return 0x0;
}

int cmddeldcc(int usern)
{
    erasedcc(usern,atoi(irccontent));
}

int cmdlistdcc(int usern)
{
    listdccs(usern);
}

int cmddccchat(int usern)
{
    addpendingdcc(usern, PDC_CHATTORQ, NULL, 0, irccontent, NULL, NULL, 0L, AF_INET);
}

int cmddccanswer(int usern)
{
    addpendingdcc(usern, PDC_CHATFROM, NULL, 0, irccontent, NULL, NULL, 0L, AF_INET);
}

#endif

#ifdef DCCFILES

int cmddccsend(int usern)
{
    addpendingdcc(usern, PDC_SENDTORQ, NULL, 0, ircto, irccontent, NULL, 0L, AF_INET);
}

int cmddccget(int usern)
{
    char *pt;
    pt=strchr(irccontent,' ');
    if(pt!=NULL)
    {
	*pt=0;
	pt++;
	addpendingdcc(usern, PDC_RECVFROM, NULL,0, ircto, irccontent, pt, 0L, AF_INET);
    } else {
	addpendingdcc(usern, PDC_RECVFROM, NULL,0, ircto, irccontent, NULL, 0L, AF_INET);
    }
}

int cmddccsendme(int usern)
{
    addpendingdcc(usern, PDC_SENDTORQ, NULL, 0, user(usern)->nick,irccontent, NULL, 0L, AF_INET);
}

/* setting autogetdcc */

int cmdautogetdcc(int usern)
{
    char fname[20];
    char buf[10];
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (atoi(irccontent) != 0 && atoi(irccontent) != 1) {
	ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Use AUTOGETDCC 0 or AUTOGETDCC 1.\r\n",user(userp)->nick);
	return 0x0;
    }
    user(usern)->autogetdcc=atoi(irccontent);
    ap_snprintf(buf,sizeof(buf),"%d",user(usern)->autogetdcc);
    ap_snprintf(fname,sizeof(fname),"USER%d",usern);
    writeini("USER","AUTOGETDCC",fname,buf);
    flushconfig();
    if (user(usern)->autogetdcc==1) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :AUTOGETDCC enabled.\r\n",user(userp)->nick);
    } else {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :AUTOGETDCC disabled.\r\n",user(userp)->nick);
    }
    return 0x0;
}

#endif

int cmddcccancel(int usern)
{
    if(ircto[0]==0)
	canceldcc(usern,irccontent,NULL);
    else
	canceldcc(usern,ircto,irccontent);
    return 0x0;
}

/* display a help to a topic or an overview */

int printhelp(int ausern)
{
    int usern;
    pcontext;
    if (user(usern)->parent!=0) usern=user(usern)->parent; else usern=ausern;
    
    if(*irccontent==0 || ausern==0)
    {
	ssnprintf(user(usern)->insock,":irc.psychoid.net NOTICE %s :" APPNAME " " APPVER " Help (* = BounceAdmin only)\n",user(usern)->nick);
	ssnprintf(user(usern)->insock,":irc.psychoid.net NOTICE %s :--------------------------------------\n",user(usern)->nick);
	userhelp(usern,NULL);
	ssnprintf(user(usern)->insock,":irc.psychoid.net NOTICE %s :BHELP - End of help\n",user(usern)->nick);
    } else {
	userhelp(usern,irccontent);
	ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de PRIVMSG %s :BHELP - End of help\n",user(usern)->nick);
    }
    return 0x0;
}

/* add an op */

int cmdaddop(int usern) {
    char cfile[40];
    char *pt;
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (strlen(irccontent) == 0) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Host given. Use ADDOP [#chan] password :host",user(userp)->nick);
	return 0x0;
    }
    if (strlen(ircto) == 0) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Password given. Use ADDOP [#chan] password :host",user(userp)->nick);
	return 0x0;
    }
    if (strchr(irccontent,';')) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :You may not use ; in hostnames",user(userp)->nick);
	return 0x0;
    }
    ap_snprintf(cfile,sizeof(cfile),"USER%d.OP",usern);
    user(usern)->ops=writelist(irccontent,cryptit(ircto),cfile,user(usern)->ops);
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Added op for hostmask %s (%s)",user(userp)->nick,irccontent,ircto);
    return 0x0;
}

/* add an autoop */

int cmdaddautoop(int usern) {
    char cfile[40];
    char *pt;
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (strlen(irccontent) == 0) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Host given. Use ADDAUTOOP #chan :host",user(userp)->nick);
	return 0x0;
    }
    if (strlen(ircto) == 0) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Channel given. Use ADDAUTOOP #chan :host",user(userp)->nick);
	return 0x0;
    }
    if (strchr(irccontent,';')) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :You may not use ; in hostnames",user(userp)->nick);
	return 0x0;
    }
    ap_snprintf(cfile,sizeof(cfile),"USER%d.AOP",usern);
    user(usern)->aops=writelist(irccontent,cryptit(ircto),cfile,user(usern)->aops);
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Added auto-op for hostmask %s (%s)",user(userp)->nick,irccontent,ircto);
    return 0x0;
}

/* add an askop */

int cmdaddask(int usern) {
    char cfile[40];
    char *pt;
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (strlen(irccontent) == 0) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Host given. Use ADDASK [#chan] password :host",user(userp)->nick);
	return 0x0;
    }
    if (strlen(ircto) == 0) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Password given. Use ADDASK [#chan] password :host",user(userp)->nick);
	return 0x0;
    }
    if (strchr(irccontent,';')) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :You may not use ; in hostnames",user(userp)->nick);
	return 0x0;
    }
    ap_snprintf(cfile,sizeof(cfile),"USER%d.ASK",usern);
    user(usern)->askops=writelist(irccontent,cryptit(ircto),cfile,user(usern)->askops);    
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Added op from hostmask %s (%s)",user(userp)->nick,irccontent,ircto);
    return 0x0;
}

/* add a hostallow */

int cmdaddallow(int usern) {
    char cfile[40];
    char *pt;
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (strlen(irccontent) == 0) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Host given. Use ADDALLOW :hostmask",user(userp)->nick);
	return 0x0;
    }
    if (strchr(irccontent,';')) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :You may not use ; in hostnames",user(userp)->nick);
	return 0x0;
    }
    ap_snprintf(cfile,sizeof(cfile),"PSYBNC.HOSTALLOWS",usern);
    hostallows=writelist(irccontent,"*",cfile,hostallows);    
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Added Host allow from hostmask %s",user(userp)->nick,irccontent);
    return 0x0;
}

/* add a ban */

int cmdaddban(int usern) {
    char cfile[40];
    char *pt;
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (strlen(irccontent) == 0) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Host given. Use ADDBAN [#chan] reason :host",user(userp)->nick);
	return 0x0;
    }
    if (strlen(ircto) == 0) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Reason given. Use ADDBAN [#chan] reason :host",user(userp)->nick);
	return 0x0;
    }
    if (strchr(irccontent,';')) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :You may not use : in hostnames",user(userp)->nick);
	return 0x0;
    }
    ap_snprintf(cfile,sizeof(cfile),"USER%d.BAN",usern);
    user(usern)->bans=writelist(irccontent,ircto,cfile,user(usern)->bans);
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Added ban for host %s (%s)",user(userp)->nick,irccontent,ircto);
    return 0x0;
}

#ifndef DYNAMIC

/* add a logmask */

int cmdaddlog(int usern) {
    char cfile[40];
    char *pt;
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (strlen(irccontent) == 0) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Log Filter given (Use * for all). Use ADDLOG [#chan/logdest.] :filter(included text to get logged)",user(userp)->nick);
	return 0x0;
    }
    if (strlen(ircto) == 0) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Destination given. Use ADDLOG [#chan/logdest.] :filter",user(userp)->nick);
	return 0x0;
    }
    if (strchr(irccontent,';')) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :You may not use ; in filters",user(userp)->nick);
	return 0x0;
    }
    ap_snprintf(cfile,sizeof(cfile),"USER%d.LGI",usern);
    user(usern)->logs=writelist(irccontent,ircto,cfile,user(usern)->logs);
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Added log for destination %s (filtering %s)",user(userp)->nick,ircto,irccontent);
    return 0x0;
}

#endif

#ifdef LINKAGE

int cmdrelink(int usern)
{
    int vl;
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    vl=atoi(irccontent);
    if (vl!=0)
    {
	if (datalink(vl)->type!=1 && datalink(vl)->type!=2)
	{
	    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Link '%d' not found.\r\n",user(usern)->nick,vl);
	    return 0x0;
	}
    }
    if(datalink(vl)->type==LI_LINK && datalink(vl)->outstate==STD_CONN)
	killsocket(datalink(vl)->outsock);
    if(datalink(vl)->type==LI_ALLOW && datalink(vl)->instate==STD_CONN)
	killsocket(datalink(vl)->insock);
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Link '%d' resetted and disconnected.\r\n",user(usern)->nick,vl);
    return 0x0;
}

#endif

#ifdef CRYPT


int cmdsetlinkkey(int usern)
{
    int vl=0,ln;
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    vl=atoi(ircto);
    if(vl==0)
    {
	ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Wrong Syntax. Use SETLINKKEY (linknumber) :key.\r\n",user(usern)->nick);
	return 0x0;
    }
    if (vl!=0)
    {
	if (datalink(vl)->type!=1 && datalink(vl)->type!=2)
	{
	    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Link '%d' not found.\r\n",user(usern)->nick,vl);
	    return 0x0;
	}
    }
#ifdef BLOWFISH
    ln=15;
#else
    ln=54;
#endif
    if(strlen(irccontent)>ln)
    {
	ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Key Phrase may not be longer than %d chars.\r\n",user(usern)->nick,ln);
	return 0x0;
    }
    strmncpy(datalink(vl)->crkey,irccontent,sizeof(datalink(vl)->crkey));
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Initial Key Phrase for link %d set to '%s'. The counterpart also needs to set this linkkey to your link. Trigger RELINK %d after counterpart set the password.\r\n",user(usern)->nick,vl,irccontent,vl);
    writelink(vl);
    return 0x0;
}

int cmdsetuserkey(int usern)
{
    int vl,ln;
    int userp,rc;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    rc=usern;
    if(strlen(ircto))
    {
	if(user(usern)->rights!=RI_ADMIN)
	{
	    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Only Admins may change other Users encryptionkeys.\r\n",user(usern)->nick);
	    return 0x0;
	}
	rc = checkuser(ircto);
	if(rc==0)
	{
	    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No such user.\r\n",user(usern)->nick);
	    return 0x0;
	}
    }
#ifdef BLOWFISH
    ln=15;
#else
    ln=54;
#endif
    if(strlen(irccontent)>ln)
    {
	ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Key Phrase may not be longer than %d chars.\r\n",user(usern)->nick,ln);
	return 0x0;
    }
    strmncpy(user(rc)->crkey,irccontent,sizeof(user(rc)->crkey));
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Initial Key Phrase for User %s set to '%s'. The new setting occurs next time you connect.\r\n",user(usern)->nick,user(rc)->login,irccontent);
    writeuser(rc);
    return 0x0;
}

/* add an encryption */

int cmdencrypt(int usern) {
    char cfile[40];
    char *pt;
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (strlen(irccontent) == 0) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No channel or nick given. Use ENCRYPT password :#channel or nick",user(userp)->nick);
	return 0x0;
    }
    if (strlen(ircto) == 0) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Password given. Use ENCRYPT password :#channel or nick",user(userp)->nick);
	return 0x0;
    }
    if (strchr(irccontent,';')) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :You may not use ; in chan or nick",user(userp)->nick);
	return 0x0;
    }
    ap_snprintf(cfile,sizeof(cfile),"USER%d.ENC",usern);
    ucase(irccontent);
    user(usern)->encrypt=writelist(irccontent,cryptit(ircto),cfile,user(usern)->encrypt);
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Added encryption for %s (%s)",user(userp)->nick,irccontent,ircto);
    return 0x0;
}

#endif

#ifdef TRANSLATE

/* add a translator */

int cmdtranslate(int usern) {
    char cfile[40];
    char *pt;
    int userp;
    char *langs[8];
    char buf[100];
    int ec;
    int isa=0,isb=0;
    langs[0]="en_de";
    langs[1]="en_fr";
    langs[2]="en_it";
    langs[3]="en_pt";
    langs[4]="de_en";
    langs[5]="fr_en";
    langs[6]="it_en";
    langs[7]="pt_en";
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (strlen(irccontent) == 0) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No languages given. Use TRANSLATE #channel or nick :language-from language-to",user(userp)->nick);
	return 0x0;
    }
    if (strlen(ircto) == 0 || *ircto=='+') {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No Channel or User given given. Use TRANSLATE #channel or nick :language-from language-to",user(userp)->nick);
	return 0x0;
    }
    if (strchr(irccontent,';')) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :You may not use ; in language specifications",user(userp)->nick);
	return 0x0;
    }
    strmncpy(buf,irccontent,sizeof(buf));
    pt=strchr(buf,' ');
    if(pt==NULL)
    {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Not enough parameters in language. Use two language specifications.",user(userp)->nick);
	return 0x0;
    }
    *pt++=0;
    if(strlen(pt)!=5 || strlen(buf)!=5)
    {
	ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Wrong languages given. Use en_de,en_fr,en_it,en_pt,de_en,fr_en,it_en or pt_en",user(userp)->nick);
	return 0x0;
    }
    ec=0;
    while(ec<8)
    {
	if(strstr(langs[ec],pt)!=NULL) isa=1;
	if(strstr(langs[ec],buf)!=NULL) isb=1;
	ec++;
    }
    if(isa==1 && isb==1) 
    {
	ap_snprintf(cfile,sizeof(cfile),"USER%d.TRA",usern);
	ucase(ircto);
	user(usern)->translates=writelist(irccontent,ircto,cfile,user(usern)->translates);
	ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Added translator for %s (%s)",user(userp)->nick,ircto,irccontent);
    } else 
	ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Wrong languages given. Use en_de,en_fr,en_it,en_pt,de_en,fr_en,it_en or pt_en",user(userp)->nick);
    return 0x0;
}

#endif

/* remove op entry */

int cmddelop(int usern) {
    char cfile[40];
    int userp;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (strlen(irccontent) == 0) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No number given. Use DELOP number",user(userp)->nick);
	return 0x0;
    }
    ap_snprintf(cfile,sizeof(cfile),"USER%d.OP",usern);
    user(usern)->ops=eraselist(atoi(irccontent),cfile,user(usern)->ops);
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Op Number %s removed",user(userp)->nick,irccontent);
    return 0x0;
}

/* remove autoop entry */

int cmddelautoop(int usern) {
    char cfile[40];
    int userp;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (strlen(irccontent) == 0) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No number given. Use DELOP number",user(userp)->nick);
	return 0x0;
    }
    ap_snprintf(cfile,sizeof(cfile),"USER%d.AOP",usern);
    user(usern)->aops=eraselist(atoi(irccontent),cfile,user(usern)->aops);
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Auto-Op Number %s removed",user(userp)->nick,irccontent);
    return 0x0;
}

/* delete askop */

int cmddelask(int usern) {
    char cfile[40];
    pcontext;
    if (strlen(irccontent) == 0) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No number given. Use DELASK number",user(usern)->nick);
	return 0x0;
    }
    ap_snprintf(cfile,sizeof(cfile),"USER%d.ASK",usern);
    user(usern)->askops=eraselist(atoi(irccontent),cfile,user(usern)->askops);
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :AskOp Number %s removed",user(usern)->nick,irccontent);
    return 0x0;
}

/* delete askop */

int cmddelallow(int usern) {
    char cfile[40];
    pcontext;
    if (strlen(irccontent) == 0) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No number given. Use DELALLOW number",user(usern)->nick);
	return 0x0;
    }
    ap_snprintf(cfile,sizeof(cfile),"PSYBNC.HOSTALLOWS",usern);
    hostallows=eraselist(atoi(irccontent),cfile,hostallows);
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Host Allow Number %s removed",user(usern)->nick,irccontent);
    return 0x0;
}

/* delete a ban */

int cmddelban(int usern) {
    char cfile[40];
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (strlen(irccontent) == 0) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No number given. Use DELBAN number",user(userp)->nick);
	return 0x0;
    }
    ap_snprintf(cfile,sizeof(cfile),"USER%d.BAN",usern);
    pcontext;
    user(usern)->bans=eraselist(atoi(irccontent),cfile,user(usern)->bans);
    pcontext;
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Ban Number %s removed",user(userp)->nick,irccontent);
    pcontext;
    return 0x0;
}

/* delete a log entry */

int cmddellog(int usern) {
    char cfile[40];
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (strlen(irccontent) == 0) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No number given. Use DELLOG number",user(userp)->nick);
	return 0x0;
    }
    ap_snprintf(cfile,sizeof(cfile),"USER%d.LGI",usern);
    user(usern)->logs=eraselist(atoi(irccontent),cfile,user(usern)->logs);
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Log Entry Number %s removed",user(userp)->nick,irccontent);
    return 0x0;
}

#ifdef CRYPT

/* delete encryption */

int cmddelencrypt(int usern) {
    char cfile[40];
    pcontext;
    if (strlen(irccontent) == 0) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No number given. Use DELENCRYPT number",user(usern)->nick);
	return 0x0;
    }
    ap_snprintf(cfile,sizeof(cfile),"USER%d.ENC",usern);
    user(usern)->encrypt=eraselist(atoi(irccontent),cfile,user(usern)->encrypt);
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Encryption Number %s removed",user(usern)->nick,irccontent);
    return 0x0;
}

#endif

#ifdef TRANSLATE

/* delete encryption */

int cmddeltranslate(int usern) {
    char cfile[40];
    pcontext;
    if (strlen(irccontent) == 0) {
        ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No number given. Use DELTRANSLATE number",user(usern)->nick);
	return 0x0;
    }
    ap_snprintf(cfile,sizeof(cfile),"USER%d.TRA",usern);
    user(usern)->translates=eraselist(atoi(irccontent),cfile,user(usern)->translates);
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Translator Number %s removed",user(usern)->nick,irccontent);
    return 0x0;
}

#endif

/* list the ops */

int cmdlistops(int usern) {
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Listing OPs:",user(userp)->nick);
    liststrings(user(usern)->ops,usern);
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :End of List.",user(userp)->nick);
    return 0x0;
}

/* list the autoops */

int cmdlistautoops(int usern) {
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Listing Auto-OPs:",user(userp)->nick);
    liststrings(user(usern)->aops,usern);
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :End of List.",user(userp)->nick);
    return 0x0;
}

/* list the askops */

int cmdlistask(int usern) {
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Listing AskOPs:",user(userp)->nick);
    liststrings(user(usern)->askops,usern);
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :End of List.",user(userp)->nick);
    return 0x0;
}

/* list the hostallows */

int cmdlistallow(int usern) {
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Listing Host Allows:",user(userp)->nick);
    liststrings(hostallows,usern);
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :End of List.",user(userp)->nick);
    return 0x0;
}

/* list all bans */

int cmdlistbans(int usern) {
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Listing Bans:",user(userp)->nick);
    liststrings(user(usern)->bans,usern);
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :End of List.",user(userp)->nick);
    return 0x0;
}

#ifdef CRYPT

/* list all encryptions */

int cmdlistencrypt(int usern) {
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Listing Encryptions:",user(userp)->nick);
    liststrings(user(usern)->encrypt,usern);
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :End of List.",user(userp)->nick);
    return 0x0;
}

#endif

#ifdef TRANSLATE

/* list all translators */

int cmdlisttranslate(int usern) {
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Listing Translators:",user(userp)->nick);
    liststrings(user(usern)->translates,usern);
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :End of List.",user(userp)->nick);
    return 0x0;
}


#endif

#ifndef DYNAMIC

/* list all log-entrys */

int cmdlistlogs(int usern) {
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Listing Log-Entrys:",user(userp)->nick);
    liststrings(user(usern)->logs,usern);
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :End of List.",user(userp)->nick);
    return 0x0;
}

#endif

/* rehash the proxy */

int cmdrehash(int usern) {
    struct socketnodes *sck,*psck;
    char buf[200];
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :REHASHING !! All connections will be dropped:",user(userp)->nick);
    log(LOG_WARNING,usern,"REHASHED by %s",user(usern)->login);
    sck=socketnode;
    /* bug found by syzop - thanks :) */
    while(sck!=NULL)
    {
	psck=sck->next;
	if(sck->sock!=NULL) 
	    if(sck->sock->type!=ST_LISTEN || strmcmp(sck->sock->dest,"DCC")==1)
		killsocket(sck->sock->syssock);
	sck=psck;
    }
/* reloading all users */
    loadusers();
    loadlinks();
}

#ifdef MULTIUSER

/* crown an admin */

int cmdadmin(int usern) {
    int rc;
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (strlen(irccontent)==0) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No user given. Syntax is MADMIN user.",user(userp)->nick);
    }    
    rc=checkuser(irccontent);
    if (rc) {
       user(rc)->rights=RI_ADMIN;
       writeuser(rc);	
       log(LOG_INFO,usern,"User %s declared User %s to admin",user(userp)->nick,irccontent);
    } else {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :User %s not found.",user(userp)->nick,irccontent);
    }
    return 0x0;
}

/* remove the crown */

int cmdunadmin(int usern) {
    char buf[200];
    int rc;
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (strlen(irccontent)==0) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No user given. Syntax is UNADMIN user.",user(userp)->nick);
    }    
    rc=checkuser(irccontent);
    if (rc) {
       log(LOG_INFO,usern,"User %s took admin rights from User %s",user(userp)->nick,irccontent);
       user(rc)->rights=RI_ADMIN;
       writeuser(rc);	
    
    } else {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :User %s not found.",user(userp)->nick,irccontent);
    }
    return 0x0;
}

/* kill a user on the bounce */

int cmdbkill(int usern) {
    char buf[200];
    int rc;
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (strlen(irccontent)==0) {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :No user given. Syntax is BKILL user.",user(userp)->nick);
    }    
    rc=checkuser(irccontent);
    if (rc) {
       if (user(rc)->instate != STD_CONN) {
           ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :He isnt online. Why killing a dead?.",user(userp)->nick);
           return -1;
       }	
       log(LOG_INFO,usern,"User %s killed User %s",user(userp)->nick,irccontent);
       ssnprintf(user(rc)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :You have been killed by %s.",user(rc)->nick,user(usern)->login);
       killsocket(user(rc)->insock);
       memset(user(usern)->host,0x0,sizeof(user(usern)->host));
       user(rc)->instate=STD_NOCON;
       user(rc)->insock=0;	
    } else {
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :User %s not found.",user(userp)->nick,irccontent);
    }
    return 0x0;
}

#endif

#ifdef SCRIPTING

/* reload a script */

int cmdreloadscript(int usern)
{
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    stopdialogues(usern);
    clearuserscript(usern);
    loadscript(usern);
    startdialogues(usern);
    ssnprintf(user(userp)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :Script reloaded\r\n",user(userp)->nick);
    return 0x0;
}

/* list the running tasks (if admin, all, if user, only his) */

int cmdlisttasks(int usern)
{
    int userp;
    struct subtask *stsk;
    stsk=subtasks;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    log(LOG_INFO,usern,"Logging Tasks");
    while(stsk!=NULL)
    {
	if(stsk->uid==usern || user(usern)->rights==RI_ADMIN)
	{
	    log(LOG_INFO,usern,"PID: %d  STDIN: %d STDOUT: %d STDERR: %d PROGRAM: %s",stsk->pid,stsk->fdin,stsk->fdout,stsk->fderr,stsk->desc);
	}
	stsk=stsk->next;
    }
    log(LOG_INFO,usern,"End of Tasks");
    return 0x0;
}

#endif

/* quit a connection */

int cmdbquit(int usern) {
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (user(usern)->quitted ==1) {
	ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :You are already quitted.\n",user(userp)->nick);
	return 0x0;
    }
    user(usern)->quitted = 1;
    ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :You have been marked as quitted.\n",user(userp)->nick);
    writeuser(usern);
    if (user(usern)->outstate == STD_CONN) {
       writesock(user(usern)->outsock,"QUIT :\n");
       killsocket(user(usern)->outsock);
       user(usern)->outstate = STD_NOCON;
       ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :You have been disconnected.\n",user(userp)->nick);
       user(usern)->instate=STD_CONN;
/* bug found by syzop - thanks :) - now it could be zeroed */
       user(usern)->outsock=0;
       user(usern)->server[0]=0;
    }
    return 0x0;
}

int cmdbconnect(int usern) {
    int userp;
    pcontext;
    if (user(usern)->parent!=0) userp=user(usern)->parent; else userp=usern;
    if (user(usern)->quitted==0) {
	ssnprintf(user(usern)->insock,":-psyBNC!psyBNC@lam3rz.de NOTICE %s :You are not marked as quit.\n",user(userp)->nick);
	return 0x0;
    }
    user(usern)->quitted = 0;
    user(usern)->delayed = 0;
    writeuser(usern);
    return 0x0;
}

#ifdef LINKAGE

int cmdname(int usern)
{
    char *pt;
    pcontext;
    if (strlen(me)==0) {
	pt=strchr(irccontent,' '); /* filtering space */
	if (pt!=NULL) *pt=0;
	strmncpy(me,irccontent,sizeof(me));
	writeini("SYSTEM","ME",INIFILE,me);
	flushconfig();
	log(LOG_INFO,usern,"Name of the bouncer set to '%s'.",me);
	return -1;
    }
}

#endif

int cmdquit(int usern)
{
    pcontext;
    if (user(usern)->parent !=0) usern=user(usern)->parent;
    log(LOG_INFO,usern,"User %s quitted (from %s)",user(usern)->login,user(usern)->host);
    ssnprintf(user(usern)->insock,":%s!%s@%s QUIT :good bye\r\n",user(usern)->nick,user(usern)->login,user(usern)->host);
    quitclient(usern);
    return -1;
}

#ifdef CRYPT

int checkcrypt(int usern)
{
    struct stringarray *lkm;
    int match=0;
    int decr=0,valid=0;
    char buf[800],buf1[200];
    char *tomatch;
    char *prefx;
    char *pt,*pt1,*pt2,*er;
    char *b[3];
    char act[]="\x01" "ACTION";
    char nt[]="\x00";
#ifdef BLOWFISH
    char bx[]="[B]";
#endif
#ifdef IDEA
    char bx[]="[I]";
#endif
    b[0]="[B]";
    b[1]="[I]";
    b[2]="[N]";
    prefx=nt;
    lkm=user(usern)->encrypt;
    if(strstr(irccontent,b[2])==irccontent) return 0x0;
    if(*ircbuf==':')
    {
        decr=1;
        if(*ircto=='#' || *ircto=='&' || *ircto=='+' || *ircto=='!')
        {
    	    tomatch=ircto;
	} else {
	    tomatch=ircnick;
	}
    } else {
	decr=0;
	tomatch=ircto;
    }
    strmncpy(buf,tomatch,sizeof(buf));
    ucase(buf);
    while(lkm!=NULL)
    {
	strmncpy(buf1,lkm->entry,sizeof(buf1));
	pt=buf1;
	pt2=strchr(buf1,';');
	if(pt2==NULL) return 0x0;
	*pt2++=0;
	ucase(pt);
	if(strlen(pt)==strlen(buf))
	{
	    if(strstr(pt,buf)==pt)
	    {
		pt1=decryptit(pt2);
		if(decr==1)
		{
		    pt2=NULL;
		    if(*irccontent==1) /* actions, dccs, ctcps */
		    {
			if(strstr(irccontent,act)==irccontent)
			{
			    pt+=strlen(act);
			    prefx=act;
			    valid=1;
			} else {
			    /* we got another control msg, which will be ignored */
			}	
		    } else {
		        pt=irccontent;
			valid=1;
		    }
		    if(valid)
		    {
			pt2=NULL;
			if(strstr(pt,b[0])==pt)
			    pt2=BLOW_stringdecrypt(pt+3,pt1);
			else if(strstr(pt,b[1])==pt)
			    pt2=IDEA_stringdecrypt(pt+3,pt1);
			if(pt2==NULL) return 0x0;
			pt=strstr(ircbuf,irccontent);
			if(pt==NULL) return 0x0;
			pt+=3;
			*pt=0;
			strmncpy(buf,ircbuf,sizeof(buf));
			ap_snprintf(ircbuf,sizeof(ircbuf),"%s%s%s\r\n",buf,prefx,pt2);
			free(pt2);
			parse();
		    }
		    return 0x0;
		} else {
		    if(*irccontent==1)
		    {
			if(strstr(irccontent,act)==irccontent)
			{
			    valid=1;
			} else {
			    return 0x0; /* ignoring others */
			}
		    }
		    pt=strstr(ircbuf,irccontent);
		    if(pt==NULL) return 0x0;
		    if(valid==1) pt+=strlen(act);
		    *pt=0;
		    strmncpy(buf,ircbuf,sizeof(buf));
#ifdef BLOWFISH
		    pt=BLOW_stringencrypt(irccontent,pt1);		    
#endif
#ifdef IDEA
		    pt=IDEA_stringencrypt(irccontent,pt1);
#endif	    		    
		    if(pt==NULL) return 0x0;
		    ap_snprintf(ircbuf,sizeof(ircbuf),"%s%s%s\r\n",buf,bx,pt);
		    parse();
		    return 0x0;		    
		}
	    }
	}
	lkm=lkm->next;
    }
}

#endif

#ifdef TRANSLATE

int checktranslate(int usern)
{
    struct stringarray *lkm;
    int rc=0;
    int dest=0;
    char buf[200],buf1[200];
    char *tomatch;
    char *pt,*pt1,*pt2,*er;
    lkm=user(usern)->translates;

    if(*ircbuf==':')
    {
        dest=TR_FROM;
        if(*ircto=='#' || *ircto=='&' || *ircto=='+' || *ircto=='!')
        {
    	    tomatch=ircto;
	} else {
	    tomatch=ircnick;
	}
    } else {
	dest=TR_TO;
	tomatch=ircto;
    }
    strmncpy(buf,tomatch,sizeof(buf));
    ucase(buf);
    while(lkm!=NULL)
    {
	strmncpy(buf1,lkm->entry,sizeof(buf1));
	pt=buf1;
	pt2=strchr(buf1,';');
	if(pt2==NULL) return 0x1;
	*pt2++=0;
	ucase(pt2);
	if(strlen(pt2)==strlen(buf))
	{
	    if(strstr(pt2,buf)==pt2)
	    {
		pt1=strchr(pt,' ');
		if(pt1==NULL) return 0x1;
		*pt1++=0;
		if(dest==TR_TO)
		{
		    pt1=pt;
		}
		rc=addtranslate(usern,irccontent,ircfrom,ircto,dest,pt1,irccommand);
		return 0x0;
	    }
	}
	lkm=lkm->next;
    }
    return 0x1;
}

#endif

int cmdping(int usern)
{
    /* needs to send back a server pong (for some evil irc-scripts) */
    if(user(usern)->server[0]==0)
	ssnprintf(user(usern)->insock,":irc.psychoid.net PONG irc.psychoid.net :%s",user(usern)->nick);
    else
	ssnprintf(user(usern)->insock,":%s PONG %s :%s",user(usern)->server,user(usern)->server,user(usern)->nick);
    return 0x0;
}

int cmdprivmsg(int usern)
{
    char bc=')';
    int rc;
    pcontext;
#ifdef SCRIPTING
    if(senddialoguequery(usern)==1) return 0x0;
#else
#ifdef DCCCHAT
    if(ircto[0]=='(')
    {
	if(querydccchat(usern,ircto+1)==1) return 0x0;
    }
#endif
#endif
#ifdef PARTYCHANNEL
    if (strmcmp(ircto,PARTYCHAN))
    {
	strcpy(ircto,"$$"); /* ... old clients, compatibility */
    }
#endif
    if (*ircto == '$') {
         querybounce(usern);
	 return 0;
    }
    if (*ircto == bc) {
         querybot(usern);
	 return 0;
    }
    rc=1;
#ifdef TRANSLATE
    rc=checktranslate(usern);
#endif
#ifdef CRYPT
    checkcrypt(usern);
#endif
    return rc;
}

int cmdwho(int usern)
{
    pcontext;
    user(usern)->triggered++;
    return -1;
}

int cmduser(int usern)
{
    return -1;
}

int quitclient(int usern)
{
    struct linknodes *dcc;
    struct usernodes *th;
    struct socketnodes *thn;
    time_t tm;
    pcontext;
    time( &tm );
    strmncpy(user(usern)->last,ctime( &tm ),sizeof(user(usern)->last));
    th=usernode;
    while (th!=NULL)
    {
	if (th->user!=NULL)
	{
	    if (th->uid==usern || th->user->parent==usern)
	    {
	        user(th->uid)->instate = STD_NOCON;
	        if (user(th->uid)->parent!=0) user(th->uid)->insock = 0;
#ifdef INTNET
		cmdintquit(usern,0);
#endif
#ifdef SCRIPTING
		stopdialogues(usern);
#endif
#ifdef DYNAMIC
		cmdbquit(th->uid);
	    	dcc=user(th->uid)->dcc;
	    	while(dcc!=NULL)
	    	{
	    	    if (dcc->link!=NULL)
	    	    {
	    	        if (dcc->link->outstate==STD_CONN)
	    		    killsocket(dcc->link->outsock);
	    	    }
	    	    dcc=dcc->next;
	    	}
#else
		if (user(th->uid)->leavequit!=0)
		{
		    partleavemsg(th->uid);
		} else
	    	if (*user(th->uid)->leavemsg!=0) 
		{
		    sendleavemsg(th->uid);
		}
	        if (strlen(user(th->uid)->away) >0) {
	            ssnprintf(user(usern)->outsock,"AWAY :%s\r\n",user(th->uid)->away);
	    	    dcc=user(th->uid)->dcc;
	    	    while(dcc!=NULL)
	    	    {
	    		if (dcc->link!=NULL)
	    		{
	    		    if (dcc->link->outstate==STD_CONN)
	        		ssnprintf(dcc->link->outsock,".AWAY %s\r\n",user(th->uid)->away);
	    		}
	    		dcc=dcc->next;
	    	    }
	        }    
#endif
		user(th->uid)->triggered=0;
		user(th->uid)->afterquit=1;
	        memset(user(th->uid)->host,0x0,sizeof(user(th->uid)->host));
		if(*user(th->uid)->awaynick!=0)
	    	    ssnprintf(user(th->uid)->outsock,"NICK %s\r\n",user(th->uid)->awaynick);
		else 
	    	    ssnprintf(user(th->uid)->outsock,"NICK %s\r\n",user(th->uid)->wantnick);
	    }
	}
	th=th->next;
    }
    thn=getpsocketbysock(user(usern)->insock);
    if (thn!=NULL)
	thn->sock->destructor=NULL;
    killsocket(user(usern)->insock);
    user(usern)->insock=0;
    flushconfig(); 
#ifdef PARTYCHANNEL
    if(user(usern)->sysmsg==1)
    {
	strcpy(irccontent,PARTYCHAN);
	cmdpart(usern);
	user(usern)->sysmsg=1;
    }
#else
    sysparty("User %s logged off.",user(usern)->login);
#endif
    return 0x0;
}

int userinerror(int usern,int errn)
{
    pcontext;
    log(LOG_ERROR,usern,"User %s: cant get connected User (%s)",user(usern)->login,user(usern)->host);
    if (user(usern)->rights!=RI_ADMIN) systemnotice(usern,"User %s: cant get connected User (%s)",user(usern)->login,user(usern)->host);    
    strcpy(irccontent,"Error");
    quitclient(usern);    
    return -1;
}

int userinkill(int usern)
{
    char buf[400];
    pcontext;
    log(LOG_WARNING,usern,"User %s disconnected (from %s)",user(usern)->login,user(usern)->host);
    if (user(usern)->rights!=RI_ADMIN) systemnotice(usern,"User %s disconnected (from %s)",user(usern)->login,user(usern)->host);    
    strcpy(irccontent,"Connection lost");
    quitclient(usern);    
    return -1;
}

