/************************************************************************
* IRC - Internet Relay Chat, src/hide.c
* Copyright (C) 2003 Lucas Madar
*
* hide.c - code for hiding information
*
*/
/* $Id: hide.c,v 1.4 2005/07/05 21:53:41 sheik Exp $ */
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "h.h"
#include "fds.h"
#include "numeric.h"
#include "memcount.h"
/* This is how we maintain a 'fake' list of servers */
struct fakelinkserver {
char *name;
char *description;
};
/* lserver_list is a linked list of Link structures,
each with the 'cp' member pointing to a struct fakelinkserver */
static Link *lserver_list = NULL;
static struct fakelinkserver *fakelinkserver_find(char *name)
{
Link *lp;
struct fakelinkserver *ls;
for(lp = lserver_list; lp; lp = lp->next)
{
ls = (struct fakelinkserver *) lp->value.cp;
if(mycmp(name, ls->name) == 0)
return ls;
}
return NULL;
}
/*
* Delete the entire list
*/
void fakelinkserver_reset()
{
Link *lp;
struct fakelinkserver *ls;
while((lp = lserver_list))
{
lserver_list = lp->next;
ls = (struct fakelinkserver *) lp->value.cp;
MyFree(ls->name);
MyFree(ls->description);
MyFree(ls);
free_link(lp);
}
}
static void fakelinkserver_delete(char *name)
{
Link *lp, *lpprev, *lpn;
struct fakelinkserver *ls;
for(lp = lserver_list, lpprev = NULL; lp; lpprev = lp, lp = lpn)
{
lpn = lp->next;
ls = (struct fakelinkserver *) lp->value.cp;
if(mycmp(name, ls->name) == 0)
{
if(lpprev)
lpprev->next = lp->next;
else
lserver_list = lp->next;
MyFree(ls->name);
MyFree(ls->description);
MyFree(ls);
free_link(lp);
return;
}
}
}
static void fakelinkserver_add(char *name, char *desc)
{
struct fakelinkserver *ls;
Link *lp;
if(fakelinkserver_find(name))
return;
ls = (struct fakelinkserver *) MyMalloc(sizeof(struct fakelinkserver));
ls->name = (char *) MyMalloc(strlen(name) + 1);
strcpy(ls->name, name);
ls->description = (char *) MyMalloc(strlen(desc) + 1);
strcpy(ls->description, desc);
lp = make_link();
lp->value.cp = (char *) ls;
lp->next = lserver_list;
lserver_list = lp;
}
/*
* update the server's description
*/
void fakelinkserver_update(char *name, char *desc)
{
struct fakelinkserver *ls;
if(!(ls = fakelinkserver_find(name)))
return;
MyFree(ls->description);
ls->description = (char *) MyMalloc(strlen(desc) + 1);
strcpy(ls->description, desc);
}
int m_linkscontrol(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
if (!(parc > 1 && (IsServer(sptr) || IsULine(sptr))))
return 0;
else
{
char pbuf[512];
make_parv_copy(pbuf, parc, parv);
sendto_serv_butone(cptr, ":%s LINKSCONTROL %s", parv[0], pbuf);
}
if(mycmp(parv[1], "RESET") == 0)
{
fakelinkserver_reset();
return 0;
}
else if(parc > 2 && mycmp(parv[1], "+") == 0)
{
char *servername = parv[2];
aClient *acptr = find_server(servername, NULL);
char *desc = (parc > 3) ? parv[3] : HIDDEN_SERVER_DESC;
if(strchr(servername, '.') == NULL)
return 0;
if(strchr(servername, ' ') != NULL)
return 0;
fakelinkserver_add(servername, acptr ? acptr->info : desc);
}
else if(parc > 2 && mycmp(parv[1], "-") == 0)
{
char *servername = parv[2];
fakelinkserver_delete(servername);
}
return 0;
}
/* send the list to a client doing /links */
void fakeserver_list(aClient *sptr)
{
Link *lp;
for (lp = lserver_list; lp; lp = lp->next)
{
struct fakelinkserver *ls = (struct fakelinkserver *) lp->value.cp;
sendto_one(sptr, rpl_str(RPL_LINKS), me.name, sptr->name,
ls->name, ls->name, 0, ls->description);
}
}
/* send the list to a client server (we are a hub server) */
void fakeserver_sendserver(aClient *sptr)
{
Link *lp;
#if 0 /* Don't do this. */
/* tell them to reset their list */
sendto_one(sptr, ":%s LINKSCONTROL RESET", me.name);
#endif
for (lp = lserver_list; lp; lp = lp->next)
{
struct fakelinkserver *ls = (struct fakelinkserver *) lp->value.cp;
sendto_one(sptr, ":%s LINKSCONTROL + %s :%s",
me.name, ls->name, ls->description);
}
}
/* -1 if lusers isn't locked */
static time_t luserslock_expiretime = -1;
int is_luserslocked()
{
if(luserslock_expiretime == -1)
return 0;
if(luserslock_expiretime <= NOW)
{
luserslock_expiretime = -1;
sendto_realops("LUSERS lock has expired");
return 0;
}
return 1;
}
static struct fakelusers_struct {
int m_server;
int m_ulined;
int m_client;
int m_clientmax;
int i_count;
int c_count;
int s_count;
int o_count;
int chan_count;
int m_total;
int m_totalmax;
} fakelusers = {0};
static void dolocklusers()
{
fakelusers.m_server = Count.myserver;
fakelusers.m_ulined = Count.myulined;
fakelusers.m_client = Count.local;
fakelusers.m_clientmax = Count.max_loc;
fakelusers.i_count = Count.invisi;
fakelusers.c_count = Count.total - Count.invisi;
fakelusers.s_count = Count.server;
fakelusers.o_count = Count.oper;
fakelusers.chan_count = Count.chan;
fakelusers.m_total = Count.total;
fakelusers.m_totalmax = Count.max_tot;
}
void send_fake_users(aClient *sptr)
{
sendto_one(sptr, rpl_str(RPL_LOCALUSERS), me.name, sptr->name,
fakelusers.m_client, fakelusers.m_clientmax);
sendto_one(sptr, rpl_str(RPL_GLOBALUSERS), me.name, sptr->name,
fakelusers.m_total, fakelusers.m_totalmax);
}
void send_fake_lusers(aClient *sptr)
{
#ifdef SHOW_INVISIBLE_LUSERS
sendto_one(sptr, rpl_str(RPL_LUSERCLIENT), me.name, sptr->name,
fakelusers.c_count, fakelusers.i_count, fakelusers.s_count);
#else
sendto_one(sptr,
":%s %d %s :There are %d users on %d servers", me.name,
RPL_LUSERCLIENT, sptr->name, fakelusers.c_count,
fakelusers.s_count);
#endif
if (fakelusers.o_count)
sendto_one(sptr, rpl_str(RPL_LUSEROP),
me.name, sptr->name, fakelusers.o_count);
if(fakelusers.chan_count)
sendto_one(sptr, rpl_str(RPL_LUSERCHANNELS),
me.name, sptr->name, fakelusers.chan_count);
sendto_one(sptr, rpl_str(RPL_LUSERME), me.name, sptr->name,
#ifdef HIDEULINEDSERVS
fakelusers.m_server - fakelusers.m_ulined);
#else
fakelusers.m_server);
#endif
sendto_one(sptr, rpl_str(RPL_LOCALUSERS), me.name, sptr->name,
fakelusers.m_client, fakelusers.m_clientmax);
sendto_one(sptr, rpl_str(RPL_GLOBALUSERS), me.name, sptr->name,
fakelusers.m_total, fakelusers.m_totalmax);
}
int m_luserslock(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
char pbuf[512];
if(!(IsULine(sptr) || IsServer(sptr)))
return 0;
/* LUSERSLOCK UNTIL <time> */
if(parc > 2 && mycmp(parv[1], "UNTIL") == 0)
{
time_t until = strtol(parv[2], NULL, 0);
if(until < NOW)
return 0;
if(luserslock_expiretime != -1 && luserslock_expiretime < until)
{
sendto_realops("LUSERS lock extended by %s (%d minute duration from now)",
sptr->name, 1 + (until - NOW) / 60);
luserslock_expiretime = until;
}
else if(luserslock_expiretime == -1)
{
sendto_realops("LUSERS lock activated by %s (%d minute duration)",
sptr->name, 1 + (until - NOW) / 60);
luserslock_expiretime = until;
dolocklusers();
}
}
/* LUSERSLOCK CANCEL */
else if(parc > 1 && mycmp(parv[1], "CANCEL") == 0)
{
if(confopts & FLAGS_HUB)
/* If I'm a hub, toss out anyone but services telling me to cancel. */
if(!IsULine(sptr))
return 0;
if(luserslock_expiretime != -1)
{
luserslock_expiretime = -1;
sendto_realops("LUSERS lock cancelled by %s", sptr->name);
}
}
make_parv_copy(pbuf, parc, parv);
sendto_serv_butone(cptr, ":%s LUSERSLOCK %s", parv[0], pbuf);
return 0;
}
void fakelusers_sendlock(aClient *sptr)
{
if(luserslock_expiretime == -1)
sendto_one(sptr, ":%s LUSERSLOCK CANCEL", me.name);
else
sendto_one(sptr, ":%s LUSERSLOCK UNTIL %d", (int) luserslock_expiretime);
}
u_long
memcount_hide(MChide *mc)
{
Link *lp;
struct fakelinkserver *ls;
mc->file = __FILE__;
for (lp = lserver_list; lp; lp = lp->next)
{
ls = (struct fakelinkserver *)lp->value.cp;
mc->fakelinks.c++;
mc->fakelinks.m += sizeof(struct fakelinkserver);
mc->fakelinks.m += strlen(ls->name) + 1;
mc->fakelinks.m += strlen(ls->description) + 1;
mc->e_links++;
}
mc->total.c += mc->fakelinks.c;
mc->total.m += mc->fakelinks.m;
return mc->fakelinks.m;
}
syntax highlighted by Code2HTML, v. 0.9.1