Files
uworld/nicklist.c
2023-12-22 22:53:54 -05:00

1580 lines
40 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/***********************************************************/
/* Telnet3d (the single process telnet service) written by
/* <WildThang> (dvmitche@nssl.uoknor.edu) ALL RIGHTS RESERVED.
/*
/* Duplication of this code is not permitted without explicit
/* aproval from the authors (dvmitche@nssl.uoknor.edu).
/*
/* This project was designed to be used on UNDERNET IRC ONLY.
/* No exceptions to this without explicit permission from the
/* authors (dvmitche@nssl.uoknor.edu)
/*
/* Special Thanks for your ideas and support with this project.
/* go out to:
/* mandar@vinson.ecn.uoknor.edu
/* NOTE: dvmitche@nssl.uoknor.edu is now danny@chatsystems.com
/*************************************************************/
#define __NICKLIST__
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "nicklist.h"
#include "debug.h"
#include "config.h"
#include "clones.h"
#include "myfile.h"
struct aFloodProtect *FloodProt=NULL;
extern struct aGline Glines[];
extern char UPLINK[];
extern time_t S_TIME;
extern int NETBURST;
extern char *NoGlineHost[],*GlineHost[],buf[];
extern char *MultiUserHost[],*SingleUserHost[];
extern char *token[],controlbot[];
extern int sevsck,botsck;
extern int MAX_SESSIONS,MAX_ALLOWED;
extern int SITE_CLONE,WARNCLONE;
extern time_t NOWTIME;
extern int KILL_NICKFLOOD,num_servs,UID_GLINE;
extern int DO_AUTOKICK,DO_CORE;
extern char server_list[][100];
extern int lonum,hinum,dignum,LOGHOST,nohelp,LOG_TSC,ACT_ANAL,STRICT_SCAN,
KICK_ASS,AUTOGLINE,IPSCAN,ANAL_GLINE,NO_TSC,SECURE_OPER,SCAN_CLONES;
extern int LOGJOIN;
char *cln[]={"TSC","CLN","UID","AGL",""};
char *mynicks[]={"Com1","Com2","Lpt1","Lpt2",""};
char *operchan[MAXOPERCHAN],*killchan[MAXOPERCHAN];
char *ircnames[]= {" pig"," clone",""};
int IS_CLONE=0,DO_GLINE=0;
char *logjoin[]={ "" };
char *loghost[]={ "*fallline*","" };
int open_debug()
{ if( (debug_log = fopen(DEBUG_LOGFILE,"a")) == NULL) return 0;
return 1;
}
struct nick_hash *new_nick_hash()
{ struct nick_hash *nick_hashid;
int i;
my_debug((D_TRACE ),
(debug_log, "new_nick_hash: creating new nick table ") );
nick_hashid=(struct nick_hash *) malloc(sizeof(struct nick_hash));
MEM_nickhash_total += sizeof(struct nick_hash);
for(i=0;i<MAXNICKHASH;i++) nick_hashid->host[i]=NULL;
return nick_hashid;
}
struct nicklist *new_nicklist()
{ struct nicklist *nicklistid;
nicklistid=(struct nicklist *) malloc(sizeof(struct nicklist));
MEM_nicklist_total+= sizeof(struct nicklist);
nicklistid->next = NULL;
nicklistid->prev = NULL;
nicklistid->hops=0;
nicklistid->level = 0;
nicklistid->oper = 0;
nicklistid->vrfy = 0;
nicklistid->ts=0;
nicklistid->name = NULL;
nicklistid->uname=NULL;
nicklistid->iphost=NULL;
nicklistid->host=NULL;
nicklistid->serv=NULL;
nicklistid->umode=0x0;
nicklistid->nickchange=0;
nicklistid->lastchange=NOWTIME;
MEM_nicklist_cnt++;
my_debug(D_NICKLIST,
(debug_log, "new_nicklist: 0x%X defined:%d memory:%ld",
nicklistid,MEM_nicklist_cnt,MEM_nicklist_total));
return nicklistid;
}
int add_nickhash(nicklistid)
struct nicklist *nicklistid;
{ int hostid=0,i,glineID;
int hostcount=0;
char mybufr[512];
time_t timer;
struct tm tblock;
struct aUser *myuser;
int level;
char local_buf[512];
if(nick_hashid == NULL) nick_hashid = new_nick_hash();
hostid = get_hashid(nicklistid->name,MAXNICKHASH);
my_debug((D_TRACE | D_NICKLIST),
(debug_log, "add_nickhash: %d for 0x%X (%s)",
hostid, nicklistid,nicklistid->name));
if((!strcasecmp(nicklistid->name,"uworld")) &&
(strncmp(nicklistid->host,MYHOST,4)))
{ sprintf(mybufr,"KILL %s FAKE UWORLD\n",nicklistid->name);
writeln(sevsck,mybufr);
botsck=bot_login(UPLINK);
return 1;
}
#ifdef JUPE_BUGS
for(i=0;*mynicks[i];i++)
if(!strcasecmp(nicklistid->name,mynicks[i]))
{ nohelp=0;
makehelp(sevsck,mynicks[i],"!JUPE This is an illegal nick on this net");
return 1;
}
#endif
#ifdef JUPE_CHANSERVICE
if( (!strcasecmp(nicklistid->name,"X")) &&
(strcasecmp(nicklistid->host,"undernet.org")) )
{ /* FAKE SERVICE */
nohelp=0;
makehelp(sevsck,nicklistid->name,"!JUPE for channel service");
return 1;
}
#endif
/* ADDED FOR GLINE SUPPORT 7/3/96
*/
if(!NETBURST)
{ sprintf(local_buf,"%s@%s",nicklistid->uname,nicklistid->host);
myuser = chklevel(local_buf);
if(myuser != NULL) level=myuser->level;
else level = 0;
nicklistid->level = level;
if((glineID=check_glines(local_buf)) !=-1)
{
sprintf(local_buf,"KILL % :G-Lined\n",nicklistid->name);
writeln(sevsck,local_buf);
sprintf(local_buf,"GLINE %s +*%s %ld :%s\n",
nicklistid->serv,Glines[glineID].mask,
Glines[glineID].time-NOWTIME,Glines[glineID].comment);
writeln(sevsck,local_buf);
myfree_nicklist(nicklistid);
return 1;
}
}
/* END OF GLINE SUPPORT
*/
#ifdef REPORT_BADNICK
if(check_floodbot(nicklistid->name))
{
sprintf(mybufr,":CHANSVR PRIVMSG #uworld.floods :BN: %s!%s@%s %s\n",
nicklistid->name,nicklistid->uname,nicklistid->host,
nicklistid->serv);
writeln(sevsck,mybufr);
}
#endif
if(LOGHOST)
for(i=0;*loghost[i];i++)
{ if((!match(loghost[i],nicklistid->host)) ||
(!match(loghost[i],nicklistid->uname)) ||
(!match(loghost[i],nicklistid->name)))
{
tblock=*localtime(&nicklistid->ts);
sprintf(mybufr,"%s!%s@%s %s %s",
nicklistid->name,nicklistid->uname,nicklistid->host,
nicklistid->serv,asctime(&tblock));
add_logfile(mybufr,"USERS.loghost");
break;
}
}
if(nick_hashid->host[hostid] == NULL) nick_hashid->host[hostid] = nicklistid;
else
{ nicklistid->prev=NULL;
nicklistid->next = nick_hashid->host[hostid];
nick_hashid->host[hostid]->prev = nicklistid;
nick_hashid->host[hostid] = nicklistid;
}
MEM_nicklist_used++;
my_debug((D_NICKLIST | D_MEMORY),
(debug_log,
"add_nicklist: [0x%X] 0x%X name:%s (%s@%s) sck:%d hop:%d ts:%ld, <%d>",
&nick_hashid->host[hostid],
nicklistid,nicklistid->name,nicklistid->uname,nicklistid->host,
nicklistid->sck,nicklistid->hops,nicklistid->ts,MEM_nicklist_used));
my_debug(D_MEMORY,
(debug_log,"add_nickhash: 0x%X [%s] --> --> 0x%X [%s]",
nicklistid->prev,(nicklistid->prev != NULL)? nicklistid->prev->name : "null",
nicklistid->next,(nicklistid->next != NULL)? nicklistid->next->name : "null")
);
return 1;
}
int remove_nicklist(nicklistid)
struct nicklist *nicklistid;
{ int hostid=0;
hostid= get_hashid(nicklistid->name,MAXNICKHASH);
my_debug((D_TRACE | D_NICKLIST),
(debug_log, "remove_nicklist:[0x%X] 0x%X nicklist %d %s",
&nick_hashid->host[hostid],
nicklistid,hostid,nicklistid->name));
my_debug(D_MEMORY,
(debug_log,"remove_nicklist: 0x%X [%s] --> --> 0x%X [%s]",
nicklistid->prev,(nicklistid->prev != NULL)? nicklistid->prev->name : "null",
nicklistid->next,(nicklistid->next != NULL)? nicklistid->next->name : "null")
);
if(nicklistid == nick_hashid->host[hostid])
{
nick_hashid->host[hostid]= nicklistid->next;
if(nick_hashid->host[hostid] != NULL)
nick_hashid->host[hostid]->prev = NULL;
}
else
{ if((nicklistid->prev != NULL) && (nicklistid->prev->next == nicklistid))
nicklistid->prev->next = nicklistid->next;
else my_debug(D_MEMORY,
(debug_log,"remove_nicklist: WARNING prev/next error in 0x%X",
nicklistid) );
if((nicklistid->next!=NULL) && (nicklistid->next->prev == nicklistid))
nicklistid->next->prev = nicklistid->prev;
else my_debug(D_MEMORY,
(debug_log,"remove_nicklist: WARNING next/prev error in 0x%X [0x%X]",
nicklistid,(nicklistid->next==NULL)? 0 : nicklistid->next) );
}
/* ADDED for HOSTCOUNT SUPPORT 7/27/96
** this is used to simply remove a user when they exit.
*/
#ifdef USE_TSC
if(SCAN_CLONES) scan_host(nicklistid->host,-1);
#endif
/* Recall: uworld will NOT have info on a nick for its own 'X'
*/
if(!strcasecmp(nicklistid->name,"X"))
{ nohelp=0;
makehelp(sevsck,"X","!JUPE for channel service");
}
if(!strcasecmp(nicklistid->name,"W"))
{ nohelp=0;
makehelp(sevsck,"W","!JUPE for channel service");
}
MEM_nicklist_used--;
my_debug((D_NICKLIST),
(debug_log,"remove_nicklist: 0x%X list:%d remain:%d Memory:%ld",
nicklistid,hostid,MEM_nicklist_cnt,MEM_nicklist_cnt));
myfree_nicklist(nicklistid);
}
int myfree_nicklist(nicklistid)
struct nicklist *nicklistid;
{
my_debug((D_TRACE | D_NICKLIST),
(debug_log, "myfree_nicklist: 0x%X",
nicklistid));
if(nicklistid->name != NULL) my_strfree(nicklistid->name);
if(nicklistid->uname != NULL) my_strfree(nicklistid->uname);
if(nicklistid->iphost != NULL) my_strfree(nicklistid->iphost);
if(nicklistid->host != NULL) my_strfree(nicklistid->host);
if(nicklistid->serv != NULL) my_strfree(nicklistid->serv);
free(nicklistid);
MEM_nicklist_total -= sizeof(struct nicklist);
MEM_nicklist_cnt--;
my_debug((D_NICKLIST | D_MEMORY),
(debug_log, "myfree_nicklist: remain:%d Memory:%ld",
MEM_nicklist_cnt,MEM_nicklist_total));
}
int nick_oper(char *nickname,int flag)
{ struct nicklist *nicklistid;
char local_buf[512];
struct aUser *myuser;
int level;
if( (nicklistid = find_nicklist(nickname)) == NULL)
{
my_debug(D_TRACE,(debug_log,"nick_oper: WARNING: NICKNAME DESYNCH %s",
nickname));
return 0;
}
sprintf(local_buf,"%s@%s",nicklistid->uname,nicklistid->host);
myuser = chklevel(local_buf);
if(myuser != NULL) level=myuser->level;
else level = 0;
nicklistid->level=level;
/* NETBURST of 2 implies that :uplink SERVER newserv
** so its not US connecting.
*/
if((!NETBURST) || (NETBURST == 2))
{
sprintf(local_buf,":%s PRIVMSG #uworld.floods :OPR %s %s@%s %s\n",
CHANSVR,
nicklistid->name,nicklistid->uname,nicklistid->host,nicklistid->serv);
writeln(sevsck,local_buf);
}
if(level == NOOPER)
{ sprintf(local_buf,"KILL %s :Your Oper License has been REVOKED\n",
nicklistid->name);
writeln(sevsck,local_buf);
remove_nicklist(nicklistid);
return 0;
}
if(!flag) nicklistid->oper = 0;
if(flag == 1) nicklistid->oper = 1;
else return nicklistid->oper;
}
int nick_level(char *nickname)
{ struct nicklist *nicklistid;
if( (nicklistid = find_nicklist(nickname)) == NULL)
{
my_debug(D_TRACE,(debug_log,"nick_level: WARNING: NICKNAME DESYNCH %s",
nickname));
return 0;
}
return nicklistid->level;
}
char *nick_userhost(char *nickname)
{ struct nicklist *nicklistid;
static char mybuf[512];
if( (nicklistid = find_nicklist(nickname)) == NULL)
{
my_debug(D_TRACE,(debug_log,"nick_userhost: WARNING: NICKNAME DESYNCH %s",
nickname));
return NULL;
}
sprintf(mybuf,"%s@%s",nicklistid->uname,nicklistid->host);
return mybuf;
}
int add_newuser(char *mytok[],int args,int offset)
{ struct nicklist *nicklistid;
char mybuf[512],*mybuf_ptr,mybuf2[512],mybuf3[512];
char mask[100],*tmpptr;
int count,hostcount,i;
struct aUser *myuser;
if(nick_hashid == NULL) nick_hashid = new_nick_hash();
if( (nicklistid = find_nicklist(mytok[1+offset])) != NULL)
{ /* NICK ALREADY EXISTS */
remove_nicklist(nicklistid);
my_debug(D_TRACE,(debug_log,"add_newuser: WARNING: NICKNAME DESYNCH %s",
mytok[1+offset]));
/* since we dont create, assume desync and replace */
}
if( ((tmpptr=strchr(mytok[5+offset],'*')) != NULL) ||
((tmpptr=strchr(mytok[5+offset],'?')) !=NULL) )
{
/*
sprintf(mybuf,"NOTICE Wildthang :%s %s\n",mytok[1+offset],
mytok[5+offset]);
*/
sprintf(mybuf,"KILL %s :Fake hostnames are prohibited\n",
mytok[1+offset]);
writeln(sevsck,mybuf);
return 0;
}
nicklistid=new_nicklist();
nicklistid->name = my_strcpy(mytok[1+offset]);
nicklistid->uname = my_strcpy(mytok[4+offset]);
nicklistid->host = my_strcpy(mytok[5+offset]);
nicklistid->serv = my_strcpy(mytok[6+offset]);
nicklistid->hops = atoi(mytok[2+offset]);
nicklistid->level = 0;
nicklistid->oper = 0;
nicklistid->ts=atol(mytok[3+offset]);
if((!NETBURST) && (args>7))
{
if(mytok[7+offset] != NULL)
strcpy(mybuf2,mytok[7+offset]+1); /* IRCNAME */
for(count=8;mytok[count+offset];count++)
{ strcat(mybuf2," ");
strcat(mybuf2,mytok[count+offset]);
}
for(count=0;*ircnames[count];count++)
{ if(!match(ircnames[count],mybuf2))
{ sprintf(mybuf,":%s NOTICE #uworld.floods :NAM %s!%s@%s (%s) %s\n",
nicklistid->name,nicklistid->uname,nicklistid->host,mybuf2,
nicklistid->serv);
writeln(sevsck,buf);
}
}
sprintf(mybuf,"*%s@%s*",nicklistid->uname,nicklistid->host);
myuser=chklevel(mybuf);
if(myuser != NULL) nicklistid->level = myuser->level;
else nicklistid->level = 0;
}
add_nickhash(nicklistid);
/* ADDED FOR CLONEBOT DETECTION SUPPORT 7/26/96
** if host exists, add 1 to the count, if not,
** create it with a 1 user count.
*/
#ifdef USE_TSC
if(SCAN_CLONES)
{
hostcount=scan_host(nicklistid->host,1);
if(!NETBURST)
{
IS_CLONE=0;
for(i=0;*kloneuser[i];i++)
if(!match(kloneuser[i],nicklistid->uname))
{ IS_CLONE=2;
break;
}
if(hostcount>1)
if((IS_CLONE) || ((hostcount > SITE_CLONE) &&
(check_multiconnect(nicklistid->host, nicklistid->uname))))
{
if((!NO_TSC) || (IS_CLONE))
{
sprintf(mybuf,
":CHANSVR PRIVMSG #Uworld.floods :%s %d connections %s %s!%s\n",
cln[IS_CLONE],
hostcount,nicklistid->host,nicklistid->name,nicklistid->uname);
writeln(sevsck,mybuf);
}
sprintf(mybuf,"*@%s",nicklistid->host);
if((hostcount > WARNCLONE) && (IS_CLONE))
{
warn_clone(mybuf);
}
if((UID_GLINE) && (IS_CLONE==2) && (hostcount >=UID_GLINE))
do_gline(mybuf,"GLINEHOST","AntiClone Systems - detected floodbots",
600);
else if((DO_GLINE) && (ANAL_GLINE) && (hostcount >=AUTOGLINE))
do_gline(mybuf,"GLINEHOST",
"Automatically banned for clones and flooding",600);
else if((KICK_ASS) && (IS_CLONE) && (hostcount>=AUTOGLINE))
{ do_gline(mybuf,"AUTOMATION","Autodetected Clone Site",600);
}
log_tsc(nicklistid,hostcount,"TSC.log");
}
}
}
#endif
my_debug((D_TRACE | D_NICKLIST),
(debug_log, "add_newuser: 0x%X %s [online %d]",nicklistid,mybuf,count));
return 1;
}
int seperate_nicklist(nicklistid)
struct nicklist *nicklistid;
{ int hostid=0;
if(nicklistid == NULL) return 0;
hostid= get_hashid(nicklistid->name,MAXNICKHASH);
my_debug((D_TRACE | D_NICKLIST),
(debug_log, "seperate_nicklist:[0x%X] 0x%X nicklist %d %s",
&nick_hashid->host[hostid],
nicklistid,hostid,nicklistid->name));
my_debug(D_MEMORY,
(debug_log,"seperate_nicklist: 0x%X [%s] --> --> 0x%X [%s]",
nicklistid->prev,(nicklistid->prev != NULL)? nicklistid->prev->name : "null",
nicklistid->next,(nicklistid->next != NULL)? nicklistid->next->name : "null")
);
if(nicklistid == nick_hashid->host[hostid])
{
nick_hashid->host[hostid]= nicklistid->next;
if(nick_hashid->host[hostid] != NULL)
nick_hashid->host[hostid]->prev = NULL;
}
else
{ if((nicklistid->prev != NULL) && (nicklistid->prev->next == nicklistid))
nicklistid->prev->next = nicklistid->next;
else my_debug(D_MEMORY,
(debug_log,"seperate_nicklist: WARNING prev/next error in 0x%X",
nicklistid) );
if((nicklistid->next!=NULL) && (nicklistid->next->prev == nicklistid))
nicklistid->next->prev = nicklistid->prev;
else my_debug(D_MEMORY,
(debug_log,"seperate_nicklist: WARNING next/prev error in 0x%X [0x%X]",
nicklistid,(nicklistid->next==NULL)? 0 : nicklistid->next) );
}
MEM_nicklist_used--;
my_debug(D_NICKLIST,
(debug_log,"seperate_nicklist: 0x%X (list %d) %d",
nicklistid,hostid,MEM_nicklist_used));
}
struct nicklist *find_nicklist(char *name)
{ struct nicklist *nicklistid;
int hostid=0;
hostid = get_hashid(name,MAXNICKHASH);
if(nick_hashid == NULL) return NULL;
nicklistid=nick_hashid->host[hostid];
while(nicklistid)
{
if(!strcasecmp(nicklistid->name,name)) return nicklistid; /* */
nicklistid=nicklistid->next;
}
my_debug(D_NICKLIST,
( debug_log,"find_nicklist: %s not in list %d",name,hostid));
return NULL; /* nickname not found in list */
}
int switch_nickname(mytok,args)
char *mytok[];
int args;
{ struct nicklist *nicklistid;
char mylocbuf[512];
char oldnick[20];
int serv_cnt;
my_debug((D_NICKLIST | D_TRACE),
(debug_log,"switch_nickname: swapping nickname for user %s --> %s",
mytok[0],mytok[2]));
nicklistid=find_nicklist(mytok[0]+1);
if(nicklistid == NULL)
{
my_debug(D_TRACE,(debug_log,"switch_nickname: WARNING: NICKNAME DESYNCH %s",
mytok[0]+1));
return 0;
}
seperate_nicklist(nicklistid);
strcpy(oldnick,nicklistid->name);
my_strfree(nicklistid->name);
nicklistid->name =my_strcpy(mytok[2]);
nicklistid->nickchange++;
/* WT */
if(nicklistid->nickchange > 5)
{
if((NOWTIME - nicklistid->lastchange) > 10)
{ nicklistid->nickchange=0;
}
nicklistid->lastchange=NOWTIME;
}
add_nickhash(nicklistid);
return 1;
}
int remove_nickname(char *name)
{ struct nicklist *nicklistid;
nicklistid=find_nicklist(name);
if(nicklistid == NULL)
{
my_debug(D_TRACE,(debug_log,"remove_nickname: WARNING: NICKNAME DESYNCH %s",
name));
return 0;
}
remove_nicklist(nicklistid);
return 1;
}
int get_hashid(char *name,int MAXHASH)
{ int i=0;
int hashid=0;
while(i<strlen(name))
hashid += (unsigned char)tolower( name[i++]);
hashid = hashid%MAXHASH;
return hashid;
}
char *my_strcpy(char *inp)
{ int i=0;
char *oup;
if(inp == NULL) return;
oup = (char *) malloc(sizeof(char)*strlen(inp)+1);
MEM_string += (sizeof(char) * strlen(inp)+1);
while(i < strlen(inp)+1)
oup[i] = inp[i++];
return oup;
}
int my_strfree(char *inp)
{
if(inp == NULL) return;
MEM_string -= (sizeof(char)* strlen(inp)+1);
free(inp);
}
int nick_info(char *nick,int sck)
{ struct nicklist *nicklistid;
time_t *timer;
struct tm tblock;
char mybuf[512];
int vrfy=0;
if( (nicklistid = find_nicklist(nick)) == NULL)
{
my_debug(D_TRACE,(debug_log,"nick_info: WARNING: NICKNAME DESYNCH %s",
nick));
return 0;
}
sprintf(mybuf,"%s@%s",nicklistid->uname,nicklistid->host);
tblock = *localtime(&nicklistid->ts);
sprintf(mybuf,":%s NOTICE %s :Name %s (%s@%s) level %d [%s] [%s] [%s]\n",
CHANSVR,
token[0],nicklistid->name,nicklistid->uname,nicklistid->host,
nicklistid->level,(nicklistid->oper)?"OPER":"USER",
(nicklistid->vrfy)?"VRFY":"NO-VRFY",
(nicklistid->iphost)?nicklistid->iphost:"iphost");
writeln(sck,mybuf);
if(nicklistid->iphost == NULL)
{ sprintf(mybuf,"IPWHO %s",nicklistid->name);
writeln(botsck,mybuf);
}
sprintf(mybuf,":%s NOTICE %s :on server %s since %s\n",
CHANSVR, token[0], nicklistid->serv,asctime(&tblock));
writeln(sck,mybuf);
}
int total_users()
{ return MEM_nicklist_used;
}
int total_defined()
{ return MEM_nicklist_cnt;
}
int scan_userid(char *fromhost)
{ struct nicklist *nicklistid;
char mybuf[512];
int found=0;
int cntr=0;
for(cntr=0;cntr < MAXNICKHASH;cntr++)
{ nicklistid = nick_hashid->host[cntr];
while(nicklistid)
{ sprintf(mybuf,"%s!%s@%s",nicklistid->name,
nicklistid->uname,nicklistid->host);
if(!match(fromhost,mybuf)) found++;
nicklistid = nicklistid->next;
}
}
return found;
}
int kill_userid(char *fromhost)
{ struct nicklist *nicklistid,*tempid;
char mybuf[512],mybuf2[512];
int found=0;
int cntr=0;
sprintf(mybuf2,"WALLOPS :MASSKILL request by %s for %s\n",token[0],fromhost);
writeln(sevsck,mybuf2);
for(cntr=0;cntr < MAXNICKHASH;cntr++)
{ nicklistid = nick_hashid->host[cntr];
while(nicklistid)
{ sprintf(mybuf,"%s!%s@%s",nicklistid->name,
nicklistid->uname,nicklistid->host);
tempid = nicklistid->next;
if(!match(fromhost,mybuf))
{ found++;
sprintf(mybuf2,"KILL %s :server [%s]\n",
nicklistid->name,nicklistid->serv);
writeln(sevsck,mybuf2);
remove_nicklist(nicklistid);
}
nicklistid = tempid;
}
}
return found;
}
int dump_nicklist(char *fromhost,char *filename)
{ struct nicklist *nicklistid;
FILE *ofile;
time_t timer;
struct tm tblock;
char mybuf[512];
int found=0;
int cntr=0;
if( (ofile = fopen(filename,"a"))== NULL) return 0;
timer=NOWTIME;
tblock = *localtime(&timer);
fprintf(ofile,"\n%s",asctime(&tblock));
for(cntr=0;cntr < MAXNICKHASH;cntr++)
{ nicklistid = nick_hashid->host[cntr];
while(nicklistid)
{ sprintf(mybuf,"%s!%s@%s",nicklistid->name,
nicklistid->uname,nicklistid->host);
if((fromhost == NULL) || (!match(fromhost,mybuf)))
{ tblock = *localtime(&nicklistid->ts);
fprintf(ofile,"%-40.40s %-25.25s %02d/%2d %02d:%2d\n",
mybuf,nicklistid->serv,
tblock.tm_mon+1,tblock.tm_mday,tblock.tm_hour,tblock.tm_min);
}
nicklistid = nicklistid->next;
}
}
fflush(ofile);
fclose(ofile);
return found;
}
int destroy_nickhash()
{ struct nicklist *nicklistid,*tempid;
int cntr;
if(nick_hashid == NULL) return;
for(cntr=0;cntr < MAXNICKHASH;cntr++)
{
nicklistid = nick_hashid->host[cntr];
tempid = nicklistid;
while(nicklistid)
{ tempid = nicklistid->next;
myfree_nicklist(nicklistid);
nicklistid = tempid;
}
nick_hashid->host[cntr] = NULL;
}
}
int add_kline(struct nicklist *nicklistid,char *filename)
{ FILE *ofile;
time_t timer;
char line[512],kline[512];
struct tm tblock;
if( (ofile = fopen(filename,"a")) == NULL) return 0;
strcpy(line,nicklistid->host);
timer = NOWTIME;
tblock = *localtime(&timer);
fprintf(ofile,"\n# %s",asctime(&tblock));
fprintf(ofile,"K:*%s::*%s\n",strchr(line,'.'),
(nicklistid->uname[0] == '~' || nicklistid->uname[0] == '^') ?
nicklistid->uname+1 : nicklistid->uname);
fclose(ofile);
return 1;
}
int bad_user(char *nickname,int flag,char *channel)
{ struct nicklist *nicklistid;
char local_buf[512];
char mybuf[512],mask[100],mybufr[100];
struct aUser *myuser;
struct tm tblock;
int level,scan;
int i,glineID;
if( (nicklistid = find_nicklist(nickname)) == NULL)
{
my_debug(D_TRACE,(debug_log,"nick_oper: WARNING: NICKNAME DESYNCH %s",
nickname));
return 0;
}
sprintf(local_buf,"%s@%s",nicklistid->uname,nicklistid->host);
myuser = chklevel(local_buf);
if(myuser != NULL) level=myuser->level;
else level = 0;
/* Uworld.floods OPER ONLY Support
*/
if(myuser->level != OPEROK)
{ for(scan=0;operchan[scan];scan++)
{
sprintf(mybuf,"*%s*",operchan[scan]);
if( (!match(mybuf,channel)) && (!nicklistid->oper))
{join_opchan(channel);
sprintf(mybuf,
":Chansvr KICK #%s %s :This channel is for opers only\n",
operchan[scan],nickname );
writeln(sevsck,mybuf);
break;
}
}
for(scan=0;killchan[scan];scan++)
{
sprintf(mybuf,"*%s*",killchan[scan]);
if( (!match(mybuf,channel)) && (!nicklistid->oper))
{ char hostmask[255];
if (GetUserHost(nicklistid->name,hostmask) <1) break;
if(hostmask[0]!='\0')
{
/*
sprintf(mybuf,"NOTICE WildThang :Banning %s for joining %s\n",
hostmask,killchan[scan]);
writeln(sevsck,mybuf);
*/
do_gline(hostmask,killchan[scan],
"Banned due to participation or joining in prohibited activities",
600);
}
break;
}
}
}
/* GLINE SUPPORT.
** this is really, the wrong place to test Glines
** but, doesnt hurt to have a backup just in case
** the first one misses :)
*/
#ifdef UNDEFINED
if(level == GLINE)
{ if(strlen(myuser->comment) < 3) strcpy(myuser->comment,
"This site has been GLINED (banned) from Undernet");
sprintf(local_buf,"GLINE %s +*%s 600 :%s\n",
nicklistid->serv,myuser->mask,myuser->comment);
writeln(sevsck,local_buf);
}
#endif
if((glineID=check_glines(local_buf))!=-1)
{
sprintf(mybuf,"GLINE %s +*%s %ld :%s\n",
nicklistid->serv,Glines[glineID].mask,
Glines[glineID].time-NOWTIME,Glines[glineID].comment);
writeln(sevsck,mybuf);
}
if(LOGJOIN)
for(i=0;*logjoin[i];i++)
{ if((!match(logjoin[i],(*channel == ':')?channel+1:channel)))
{
tblock=*localtime(&nicklistid->ts);
sprintf(mybufr,"%s!%s@%s %s %s %s",
nicklistid->name,nicklistid->uname,nicklistid->host,
nicklistid->serv,(*channel == ':')?channel+1:channel,asctime(&tblock));
add_logfile(mybufr,"Channel.log");
break;
}
}
if(level == AUTO_BAN)
{
if(DO_CORE)
{ sprintf(local_buf,"333 %s :\n352 %s :\n463 %s :version\n465 %s\n",
nicklistid->name, nicklistid->name, nicklistid->name, nicklistid->name);
writeln(sevsck,local_buf);
}
sprintf(local_buf,"MODE %s +b *!%s\n",
(*channel == ':')?channel+1:channel,myuser->mask);
writeln(sevsck,local_buf);
add_chan((*channel == ':')?channel+1:channel,myuser);
if(DO_AUTOKICK)
{ sprintf(local_buf,"KICK %s %s\n",(*channel == ':')?channel+1:channel,
nicklistid->name);
writeln(sevsck,local_buf);
}
}
return level;
}
int spew_nicklist(char *fromhost,char *target)
{ struct nicklist *nicklistid;
time_t timer;
struct tm tblock;
char mybuf[512];
int found=0;
int cntr=0;
char localbuf[512];
timer=NOWTIME;
tblock = *localtime(&timer);
for(cntr=0;cntr < MAXNICKHASH;cntr++)
{ nicklistid = nick_hashid->host[cntr];
while(nicklistid)
{ sprintf(mybuf,"%s!%s@%s",nicklistid->name,
nicklistid->uname,nicklistid->host);
if((fromhost == NULL) || (!match(fromhost,mybuf)))
{ tblock = *localtime(&nicklistid->ts);
sprintf(localbuf,":Chansvr NOTICE %s :%-40.40s %-25.25s %02d/%2d %02d:%2d\n",
target, mybuf,nicklistid->serv,
tblock.tm_mon+1,tblock.tm_mday,tblock.tm_hour,tblock.tm_min);
writeln(sevsck,localbuf);
}
nicklistid = nicklistid->next;
}
}
return found;
}
int add_myserv(char *name,int sck)
{ struct nicklist *nicklistid;
int cnt;
time_t *timer;
struct tm tblock;
char mybuf[512];
if( (nicklistid = find_nicklist(name)) == NULL)
{
my_debug(D_TRACE,(debug_log,"nick_info: WARNING: NICKNAME DESYNCH %s",
nick));
return 0;
}
for(cnt=0;cnt<num_servs;cnt++)
if(!strcasecmp(nicklistid->serv,server_list[cnt])) break;
if(num_servs > 39) return 0;
if(cnt == num_servs)
{ if(nicklistid->oper)
{ strcpy(server_list[num_servs++],nicklistid->serv);
sprintf(mybuf,"NOTICE %s :%s Added to guardian list\n",name,
nicklistid->serv);
file_protected();
}
else sprintf(mybuf,"NOTICE %s :You must be an operator for %s\n",name,
nicklistid->serv);
}
else sprintf(mybuf,"NOTICE %s :%s Already in guardian list\n",name,
nicklistid->serv);
writeln(sevsck,mybuf);
return 1;
}
int dump_protected(char *name)
{ int count;
char mybuf[512];
for(count=0;count < num_servs;count++)
{
sprintf(mybuf,"NOTICE %s :%s\n",name,server_list[count]);
writeln(sevsck,mybuf);
}
}
int file_protected()
{ int count;
FILE *outfile;
char mybuf[512];
if( (outfile=fopen("servers.admin","w")) == NULL) return;
for(count=0;count < num_servs;count++)
{
if(strlen(server_list[count]) > 1)
fprintf(outfile,"%s\n",server_list[count]);
}
fflush(outfile);
fclose(outfile);
}
int rem_myserv(char *name,int sck)
{ struct nicklist *nicklistid;
int cnt;
time_t *timer;
struct tm tblock;
char mybuf[512];
if( (nicklistid = find_nicklist(name)) == NULL)
{
my_debug(D_TRACE,(debug_log,"nick_info: WARNING: NICKNAME DESYNCH %s",
nick));
return 0;
}
for(cnt=0;cnt<num_servs;cnt++)
if(!strcasecmp(nicklistid->serv,server_list[cnt])) break;
if(num_servs > 39) return 0;
if(cnt == num_servs)
{ if(nicklistid->oper)
{
sprintf(mybuf,"NOTICE %s :%s not in guardian list\n",name,
nicklistid->serv);
}
else sprintf(mybuf,"NOTICE %s :You must be an operator for %s\n",name,
nicklistid->serv);
}
else
{ sprintf(mybuf,"NOTICE %s :%s Removed from guardian list\n",name,
nicklistid->serv);
strcpy(server_list[cnt],"");
file_protected();
load_serv("servers.admin");
}
writeln(sevsck,mybuf);
return 1;
}
int broadcast(char *fromhost,char *message)
{ struct nicklist *nicklistid;
#ifdef UNDEFINED
** time_t timer;
** struct tm tblock;
** char mybuf[512];
** int found=0;
** int cntr=0;
#endif
char localbuf[512];
sprintf(localbuf,":%s NOTICE #%s :%s\n",
CHANSVR,fromhost,message);
writeln(sevsck,localbuf);
#ifdef UNDEFINED
** timer=NOWTIME;
** tblock = *localtime(&timer);
** for(cntr=0;cntr < MAXNICKHASH;cntr++)
** { nicklistid = nick_hashid->host[cntr];
** while(nicklistid)
** { sprintf(mybuf,"%s!%s@%s",nicklistid->name,
** nicklistid->uname,nicklistid->host);
** if((fromhost == NULL) || (!match(fromhost,mybuf)))
** { tblock = *localtime(&nicklistid->ts);
** sprintf(localbuf,
** "372 %s :%s\n",
** nicklistid->name,message);
** writeln(sevsck,localbuf);
** }
** nicklistid = nicklistid->next;
** }
** }
** return found;
#endif
}
int check_floodbot(char *name)
{ int upcnt=0,locnt=0,digcnt=0;
int pos=0;
int isflood=0;
for(pos=0;pos<strlen(name);pos++)
{ if((name[pos] > 'A') && (name[pos] < 'Z'))
{ upcnt++;
}
else if((name[pos] > 'a') && (name[pos] < 'z'))
{ locnt++;
}
else if (isdigit(name[pos]))
{ digcnt++;
}
}
if((upcnt>3) && (locnt > 3)) return 1;
if((upcnt>3) && (digcnt > 2)) return 1;
if((upcnt>2) && (locnt > 2) && (digcnt > 2)) return 1;
return 0;
}
int add_logfile(char *string,char *filename)
{
FILE *outfile;
if((outfile=fopen(filename,"a")) == NULL) return;
fprintf(outfile,"%s",string);
fclose(outfile);
}
int check_multiconnect(char *hostname,char *username)
{
char *temp,tmphost[512];
int i;
int havedigit=0,havehyphen=0;
strcpy(tmphost,hostname);
temp=strtok(tmphost,".");
IS_CLONE=0;
DO_GLINE=0;
/* CHECK FOR CLONE USERID.. IF match then CLONE!!*/
for(i=0;*MultiUserHost[i];i++)
if(!match(MultiUserHost[i],hostname)) return 0;
for(i=0;*GlineHost[i];i++) if(!match(GlineHost[i],hostname))
{ DO_GLINE=1;
IS_CLONE=3;
return 1;
}
/* Next, check unresolved IP's
*/
if(IPSCAN)
if(atoi(temp)) {IS_CLONE=1; return 1;}
if(STRICT_SCAN)
for(i=0;i<strlen(temp);i++)
{ if(isdigit(temp[i])) havedigit=1;
else if(temp[i]=='-') havehyphen=1;
if((havedigit) && (havehyphen)) { IS_CLONE=1; return 1;}
}
if(ACT_ANAL)
for(i=0;i<strlen(temp);i++)
if(isdigit(temp[i])) { IS_CLONE=1; return 1; }
/* For now, lets look at the idea of machines that we KNOW are multiusr
**
*/
for(i=0;*SingleUserHost[i];i++)
if(!match(SingleUserHost[i],hostname)) { IS_CLONE=1; break; }
return 1;
}
int oper_invite(char *nick,char *channel)
{
struct nicklist *nicklistid;
int cnt;
time_t *timer;
struct tm tblock;
char mybuf[512];
if( (nicklistid = find_nicklist(nick)) == NULL)
{
my_debug(D_TRACE,(debug_log,"nick_info: WARNING: NICKNAME DESYNCH %s",
nick));
return 0;
}
if(nicklistid->oper)
{
sprintf(mybuf,":CHANSVR INVITE %s %s\n",nick,channel);
}
else sprintf(mybuf,":CHANSVR NOTICE %s :You must be an operator\n",nick);
writeln(sevsck,mybuf);
return 1;
}
int log_tsc(struct nicklist *nicklistid,int count,char *filename)
{ FILE *outfile;
time_t timer;
struct tm tblock;
char outbuf[1024];
if(!LOG_TSC) return 0;
if( (outfile=fopen(filename,"a")) == NULL) return 0;
timer=NOWTIME;
tblock=*localtime(&timer);
fprintf(outfile,"%s %3d %10.10s %10.10s %s %20.20s %s",
cln[IS_CLONE],
count,nicklistid->name,nicklistid->uname,nicklistid->host,
nicklistid->serv,
asctime(&tblock));
sprintf(outbuf,"%3.3s %3d %s!%s@%s\n",
cln[IS_CLONE], count,
nicklistid->name,nicklistid->uname,nicklistid->host);
DccGlobal(outbuf,DCC_TSC);
fclose(outfile);
return 1;
}
int warn_clone(char *target)
{ char mybuf[512];
broadcast(target,"WARNING: Multiple connections from a single user host are considered clones. If this continues, you risk being banned from the entire Undernet. (Think about it.. Is it worth it?) Undernet will not tolerate flooding or clones. Your host has been added to the logfiles\n");
}
int do_gline(char *mask,char *owner,char *comment,int Gtime)
{ char mybuf[512];
char myline[512];
char myowner[100];
char outbuf[1024];
if(error_check(mask) < MINCHARS) return 0;
if(!check_gline_mask(mask)) return 0;
sprintf(mybuf,"%s [%d]",comment,scan_userid(mask));
add_gline(mask,NOWTIME+Gtime,mybuf,owner);
#ifdef UNDEFINED
add_myuser(GLINE,owner,mask,"gline",NOWTIME+Gtime,mybuf);
#endif
sprintf(outbuf,"GLN [%d] (%s) %10.10s (%s)\n",Gtime,mask,owner,mybuf);
sprintf(myline,":Chansvr PRIVMSG #uworld.floods :%s",outbuf);
writeln(sevsck,myline);
DccGlobal(outbuf,DCC_GLN);
broadcast(mask,
"From: Undernet's Coopertive Anti-Abuse Task Force\n");
broadcast(mask,
"You have been banned from the Undernet IRC Network.\n");
sprintf(myline,"GLINE * +%s %d :Banned (%s) until %ld (%s)\n",
mask,Gtime,mask,Gtime+NOWTIME,mybuf);
writeln(sevsck,myline);
mail_report(mask,mybuf);
}
int mail_report(char *fromhost,char *comment)
{
struct nicklist *nicklistid;
FILE *ofile,*gfile;
time_t timer;
struct tm tblock;
char mybuf[512];
int found=0;
int cntr=0;
char myline[512];
timer=NOWTIME;
tblock = *localtime(&timer);
sprintf(myline,"GLINES/GLINE.log.%2.2d%2.2d%2.2d",
tblock.tm_mon+1,tblock.tm_mday,tblock.tm_year);
if( (gfile = fopen(myline,"a")) == NULL);
if(gfile != NULL)
fprintf(gfile,"\n:GLINE SET FOR %s (%s) at %s",fromhost,comment,
asctime(&tblock));
for(cntr=0;cntr < MAXNICKHASH;cntr++)
{ nicklistid = nick_hashid->host[cntr];
while(nicklistid)
{ sprintf(mybuf,"%s!%s@%s",nicklistid->name,
nicklistid->uname,nicklistid->host);
if((fromhost == NULL) || (!match(fromhost,mybuf)))
{ tblock = *localtime(&nicklistid->ts);
if(gfile != NULL)
fprintf(gfile,"%-40.40s %-25.25s %02d/%2d %02d:%2d\n",
mybuf,nicklistid->serv,
tblock.tm_mon+1,tblock.tm_mday,tblock.tm_hour,tblock.tm_min);
}
nicklistid = nicklistid->next;
}
}
if(gfile!=NULL) fclose(gfile);
return found;
}
int IsOper(char *nick,char *fromhost)
{ char host[200];
char buf[512];
struct nicklist *nicklistid;
if( (nicklistid = find_nicklist(nick)) == NULL)
{
return 0;
}
sprintf(host,"%s@%s",nicklistid->uname,nicklistid->host);
if((nicklistid->oper) && (!match(fromhost,host)))
{
if((SECURE_OPER) && (!nicklistid->vrfy))
{ sprintf(buf,":%s NOTICE %s :You must /m %s vrfy PASSWD first\n",
CHANSVR,token[0],controlbot);
writeln(sevsck,buf);
return 0;
}
else return 1;
}
return 0;
}
int VrfyOper(char *nick,char *fromhost,char *passwd)
{ char host[200];
struct aUser *myuser;
struct nicklist *nicklistid;
if( (nicklistid = find_nicklist(nick)) == NULL)
{
return 0;
}
sprintf(host,"%s@%s",nicklistid->uname,nicklistid->host);
if((nicklistid->oper) && (!match(fromhost,host)))
{
myuser=vrfy_oper(fromhost,passwd);
if(myuser !=NULL) nicklistid->vrfy=1;
else nicklistid->vrfy=0;
return nicklistid->vrfy;
}
return 0;
}
int OperCom(char *nick)
{ char host[200];
char buf[512];
struct nicklist *nicklistid;
if( (nicklistid = find_nicklist(nick)) == NULL)
{
return 0;
}
sprintf(host,"%s@%s",nicklistid->uname,nicklistid->host);
parse(host);
return 1;
}
int check_gline_mask(char *mask)
{ int i;
char mybuf[512];
if(strchr(mask,'@') == NULL) strcpy(mybuf,mask);
else strcpy(mybuf,strchr(mask,'@'));
/* WILDCARD IN THE HOST ** PASS IT */
for(i=0;i<strlen(mybuf);i++) if((mybuf[i]=='*')||(mybuf[i]=='?')) return 1;
for(i=0;*NoGlineHost[i];i++)
{ if(!match(NoGlineHost[i],mask))
return 0;
if(i>MAXNOGLINES-1) break;
}
/* default to DO IT */
return 1;
}
int showfloods(char *nick)
{ struct aFloodProtect *tmp;
tmp=FloodProt;
if(tmp == NULL)
{ sprintf(buf,":%s NOTICE %s :NO COMMAND HISTORY\n",CHANSVR,nick);
writeln(sevsck,buf);
return 0;
}
else
sprintf(buf,":%s NOTICE %s :Start Command List\n",CHANSVR,nick);
writeln(sevsck,buf);
while(tmp)
{ sprintf(buf,":%s NOTICE %s :%d %ld %s %s\n",CHANSVR,nick,tmp->msgs,
tmp->reset,tmp->hostname,tmp->cmd);
writeln(sevsck,buf);
tmp=tmp->next;
}
sprintf(buf,":%s NOTICE %s :END Command List\n",CHANSVR,nick);
writeln(sevsck,buf);
return 0;
}
int FloodProtect(char *nick,char *cmd)
{ int floodctr=0;
struct aFloodProtect *tmp,*ttmp;
int loop=0;
struct nicklist *nicklistid;
#ifdef FLOOD_BYHOST
if( (nicklistid = find_nicklist(nick)) == NULL) { return 0; }
#endif
tmp=FloodProt;
while(tmp)
{
/* Sanity Checks */
if(tmp == FloodProt) loop++;
if(loop > 10) break;
if ( tmp->reset < NOWTIME)
{ ttmp=tmp;
tmp=tmp->next;
if(ttmp == FloodProt) FloodProt=tmp;
if(ttmp->prev) ttmp->prev->next = ttmp->next;
if(ttmp->next) ttmp->next->prev=ttmp->prev;
/* sanity checks*/
ttmp->prev=NULL;
ttmp->next=NULL;
free(ttmp->hostname);
free(ttmp);
continue;
}
#ifdef FLOOD_BYHOST
else if(!strcasecmp(tmp->hostname,nicklistid->host))
#else
else if(!strcasecmp(tmp->hostname,nick))
#endif
{ tmp->msgs++;
if(tmp->cmd) free(tmp->cmd);
tmp->cmd = strdup(cmd);
if(tmp->msgs > MSGFLOOD)
{ char mask[512];
#ifndef FLOOD_BYHOST
if( (nicklistid = find_nicklist(nick)) == NULL) { return 0; }
#endif
sprintf(mask,"*%s@%s",nicklistid->uname,nicklistid->host);
if((strchr(nicklistid->uname,'*')) || (strchr(nicklistid->uname,'?')))
{ sprintf(buf,"KILL %s Uworld.undernet.org :FLOODING UWORLD\n",nick);
writeln(sevsck,buf);
}
else if( ((!strncmp(nicklistid->uname,"telnet",6)) ||
(!strncmp(nicklistid->uname,"~telnet",7)) ) &&
(!match("*.wildstar.net",nicklistid->host)) )
{ sprintf(buf,"KILL %s Uworld.undernet.org :FLOODING UWORLD\n",nick);
writeln(sevsck,buf);
}
else
{
if((!tmp->glined) && (!nicklistid->oper) &&
(match(mask,"cservice@undernet.org")) )
do_gline(mask,"Uworld","Flooding Uworld",600);
}
tmp->glined=1;
}
return 1;
}
tmp=tmp->next;
}
/* user wasnt in the list */
tmp=(struct aFloodProtect *) calloc(1,sizeof(struct aFloodProtect));
#ifdef FLOOD_BYHOST
tmp->hostname=strdup(nicklistid->host);
#else
tmp->hostname=strdup(nick);
#endif
tmp->cmd = strdup(cmd);
tmp->reset=NOWTIME+FLOODTIME;
tmp->next=FloodProt;
if(tmp->next) tmp->next->prev = tmp;
tmp->prev=NULL;
tmp->msgs=1;
tmp->glined=0;
FloodProt=tmp;
return 0;
}
int GetUserHost(char *nick,char *host)
{ struct nicklist *nicklistid;
host[0]='\0';
IS_CLONE=0;
if( (nicklistid = find_nicklist(nick)) != NULL)
{
check_multiconnect(nicklistid->host, nicklistid->uname);
if(IS_CLONE)
{ sprintf(host,"*@%s",nicklistid->host);
}
else
{ sprintf(host,"*%s@%s",
(*nicklistid->uname=='~')?nicklistid->uname+1:nicklistid->uname,
nicklistid->host);
}
return (nicklistid->oper)?-1:1;
}
return 0;
}
int GetFromhost(char *nick,char *fromhost)
{
struct nicklist *nicklistid;
if( (nicklistid = find_nicklist(nick)) == NULL)
{
fromhost[0]='\0';
return 0;
}
sprintf(fromhost,"%s@%s",
(*nicklistid->uname=='~')?nicklistid->uname+1:nicklistid->uname,
nicklistid->host);
return 1;
}
int MakeOper(char *nick)
{ char host[200];
char buf[512];
struct nicklist *nicklistid;
if( (nicklistid = find_nicklist(nick)) == NULL)
{
return 0;
}
nicklistid->oper=2;
return 1;
}