/*
* whowas.c a linked list buffer of people who have left your channel
* mainly used for ban prot and stats stuff.
* Should even speed stuff up a bit too.
*
* Written by Scott H Kilau
*
* Copyright(c) 1995
*
* See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT
*
* Modified by Flier
*
* $Id: whowas.c,v 1.9 2002/01/23 18:48:10 f Exp $
*/
#include "irc.h"
#include "vars.h"
#include "ircaux.h"
#include "window.h"
#include "whois.h"
#include "hook.h"
#include "input.h"
#include "names.h"
#include "alias.h"
#include "output.h"
#include "numbers.h"
#include "status.h"
#include "screen.h"
#include "edit.h"
#include "config.h"
#include "list.h"
#include "whowas.h"
#include "myvars.h"
#define whowas_userlist_max 150
#define whowas_reg_max 300
#define whowas_chan_max 20
extern int CheckChannel _((char *, char *));
WhowasList *whowas_userlist_list=(WhowasList *) 0;
WhowasList *whowas_reg_list=(WhowasList *) 0;
WhowasChanList *whowas_chan_list=(WhowasChanList *) 0;
static int whowas_userlist_count=0;
static int whowas_reg_count=0;
static int whowas_chan_count=0;
extern WhowasList *check_whowas_buffer(nick,userhost,channel,unlink)
char *nick;
char *userhost;
char *channel;
int unlink;
{
WhowasList *tmp;
WhowasList *last=(WhowasList *) 0;
for (tmp=whowas_userlist_list;tmp;tmp=tmp->next) {
if (!my_stricmp(tmp->nicklist->userhost,userhost) &&
!my_stricmp(tmp->channel,channel)) {
if (unlink) {
if (last) last->next=tmp->next;
else whowas_userlist_list=tmp->next;
whowas_userlist_count--;
}
return(tmp);
}
last=tmp;
}
last=(WhowasList *) 0;
for (tmp=whowas_reg_list;tmp;tmp=tmp->next) {
if (!my_stricmp(tmp->nicklist->userhost,userhost) &&
!my_stricmp(tmp->channel,channel)) {
if (unlink) {
if (last) last->next=tmp->next;
else whowas_reg_list=tmp->next;
whowas_reg_count--;
}
return(tmp);
}
last=tmp;
}
return((WhowasList *) 0);
}
void add_to_whowas_buffer(nicklist,channel)
NickList *nicklist;
char *channel;
{
WhowasList *new;
WhowasList **slot;
if (!nicklist || !(nicklist->userhost)) return;
if (nicklist->frlist) {
if (whowas_userlist_count>=whowas_userlist_max) {
whowas_userlist_count-=
remove_oldest_whowas(&whowas_userlist_list,0,
(whowas_userlist_max+1)-whowas_userlist_count);
}
new=(WhowasList *) new_malloc(sizeof(WhowasList));
new->channel=(char *) 0;
new->nicklist=nicklist;
new->nicklist->next=(NickList *) 0;
malloc_strcpy(&(new->channel),channel);
new->time=time(NULL);
/* we've created it, now put it in order */
for (slot=&whowas_userlist_list;*slot;slot=&(*slot)->next)
if ((*slot)->time>new->time) break;
new->next=*slot;
*slot=new;
whowas_userlist_count++;
}
else {
if (whowas_reg_count>=whowas_reg_max) {
whowas_reg_count-=
remove_oldest_whowas(&whowas_reg_list,0,
(whowas_reg_max+1)-whowas_reg_count);
}
new=(WhowasList *) new_malloc(sizeof(WhowasList));
new->channel=(char *) 0;
new->nicklist=nicklist;
new->nicklist->next=(NickList *) 0;
malloc_strcpy(&(new->channel),channel);
new->time=time(NULL);
/* we've created it, now put it in order */
for (slot=&whowas_reg_list;*slot;slot=&(*slot)->next)
if ((*slot)->time>new->time) break;
new->next=*slot;
*slot=new;
whowas_reg_count++;
}
}
int remove_oldest_whowas(list,timet,count)
WhowasList **list;
time_t timet;
int count;
{
WhowasList *tmp=(WhowasList *) 0;
time_t t;
int total=0;
/* if no ..count.. then remove ..time.. links */
if (!count) {
t=time(NULL);
while (*list && ((*list)->time+timet)<=t) {
tmp=*list;
new_free(&(tmp->nicklist->nick));
new_free(&(tmp->nicklist->userhost));
new_free(&(tmp->nicklist));
new_free(&(tmp->channel));
*list=tmp->next;
new_free(&tmp);
total++;
}
}
else {
while (*list && count) {
tmp=*list;
new_free(&(tmp->nicklist->nick));
new_free(&(tmp->nicklist->userhost));
new_free(&(tmp->nicklist));
new_free(&(tmp->channel));
*list=tmp->next;
new_free(&tmp);
total++;
count--;
}
}
return(total);
}
void clean_whowas_list() {
whowas_userlist_count-=remove_oldest_whowas(&whowas_userlist_list,25*60,0);
whowas_reg_count-=remove_oldest_whowas(&whowas_reg_list,15*60,0);
}
/* Used to rehash whowas listings for new users */
void synch_whowas_adduser(added)
struct friends *added;
{
WhowasList *tmp;
char user[mybufsize/2];
for (tmp=whowas_userlist_list;tmp;tmp=tmp->next) {
if (!tmp->nicklist) continue;
if (CheckChannel(tmp->channel,added->channels)) {
snprintf(user,sizeof(user),"%s!%s",tmp->nicklist->nick,tmp->nicklist->userhost);
if (wild_match(added->userhost,user)) tmp->nicklist->frlist=added;
}
}
for (tmp=whowas_reg_list;tmp;tmp=tmp->next) {
if (!tmp->nicklist) continue;
if (CheckChannel(tmp->channel,added->channels)) {
snprintf(user,sizeof(user),"%s!%s",tmp->nicklist->nick,tmp->nicklist->userhost);
if (wild_match(added->userhost,user)) tmp->nicklist->frlist=added;
}
}
}
/* Used to rehash whowas listings for removed userlist entries */
void synch_whowas_unuser(entry)
struct friends *entry;
{
WhowasList *tmp;
for (tmp=whowas_userlist_list;tmp;tmp=tmp->next) {
if (!tmp->nicklist || !(tmp->nicklist->frlist)) continue;
if (!my_stricmp(tmp->nicklist->frlist->userhost,entry->userhost) &&
!my_stricmp(tmp->nicklist->frlist->channels,entry->channels))
tmp->nicklist->frlist=(struct friends *) 0;
}
for (tmp=whowas_reg_list;tmp;tmp=tmp->next) {
if (!tmp->nicklist || !(tmp->nicklist->frlist)) continue;
if (!my_stricmp(tmp->nicklist->frlist->userhost,entry->userhost) &&
!my_stricmp(tmp->nicklist->frlist->channels,entry->channels))
tmp->nicklist->frlist=(struct friends *) 0;
}
}
/* Used to rehash whowas listings for new shitlist entries */
void synch_whowas_addshit(added)
struct autobankicks *added;
{
WhowasList *tmp;
char user[BIG_BUFFER_SIZE+1];
for (tmp=whowas_userlist_list;tmp;tmp=tmp->next) {
if (!tmp->nicklist) continue;
if (CheckChannel(tmp->channel,added->channels)) {
snprintf(user,sizeof(user),"%s!%s",tmp->nicklist->nick,tmp->nicklist->userhost);
if (wild_match(added->userhost,user)) tmp->nicklist->shitlist=added;
}
}
for (tmp=whowas_reg_list;tmp;tmp=tmp->next) {
if (!tmp->nicklist) continue;
if (CheckChannel(tmp->channel,added->channels)) {
snprintf(user,sizeof(user),"%s!%s",tmp->nicklist->nick,tmp->nicklist->userhost);
if (wild_match(added->userhost,user)) tmp->nicklist->shitlist=added;
}
}
}
/* Used to rehash whowas listings for removed shitlist entries */
void synch_whowas_unshit(entry)
struct autobankicks *entry;
{
WhowasList *tmp;
for (tmp=whowas_userlist_list;tmp;tmp=tmp->next) {
if (!tmp->nicklist || !(tmp->nicklist->shitlist)) continue;
if (!my_stricmp(tmp->nicklist->shitlist->userhost,entry->userhost) &&
!my_stricmp(tmp->nicklist->shitlist->channels,entry->channels))
tmp->nicklist->shitlist=(struct autobankicks *) 0;
}
for (tmp=whowas_reg_list;tmp;tmp=tmp->next) {
if (!tmp->nicklist || !(tmp->nicklist->shitlist)) continue;
if (!my_stricmp(tmp->nicklist->shitlist->userhost,entry->userhost) &&
!my_stricmp(tmp->nicklist->shitlist->channels,entry->channels))
tmp->nicklist->shitlist=(struct autobankicks *) 0;
}
}
/* BELOW THIS MARK IS THE CHANNEL WHOWAS STUFF */
extern WhowasChanList *check_whowas_chan_buffer(channel,unlink)
char *channel;
int unlink;
{
WhowasChanList *tmp;
WhowasChanList *last=(WhowasChanList *) 0;
for (tmp=whowas_chan_list;tmp;tmp=tmp->next) {
if (!my_stricmp(tmp->channellist->channel,channel)) {
if (unlink) {
if (last) last->next=tmp->next;
else whowas_chan_list=tmp->next;
whowas_chan_count--;
}
return(tmp);
}
last=tmp;
}
return((WhowasChanList *) 0);
}
int add_to_whowas_chan_buffer(channel)
ChannelList *channel;
{
WhowasChanList *new;
WhowasChanList **slot;
if (check_whowas_chan_buffer(channel->channel,0)) return(0);
if (whowas_chan_count>=whowas_chan_max) {
whowas_chan_count-=
remove_oldest_chan_whowas(&whowas_chan_list,0,
(whowas_chan_max+1)-whowas_chan_count);
}
new=(WhowasChanList *) new_malloc(sizeof(WhowasChanList));
new->channellist=channel;
new->time=time(NULL);
/* we've created it, now put it in order */
for (slot=&whowas_chan_list;*slot;slot=&(*slot)->next)
if ((*slot)->time>new->time) break;
new->next=*slot;
*slot=new;
whowas_chan_count++;
return(1);
}
int remove_oldest_chan_whowas(list,timet,count)
WhowasChanList **list;
time_t timet;
int count;
{
WhowasChanList *tmp=(WhowasChanList *) 0;
time_t t;
int total=0;
/* if no ..count.. then remove ..time.. links */
if (!count) {
t = time(NULL);
while (*list && ((*list)->time+timet)<=t) {
tmp=*list;
new_free(&(tmp->channellist->channel));
new_free(&(tmp->channellist->s_mode));
new_free(&(tmp->channellist->key));
#ifdef EXTRAS
new_free(&(tmp->channellist->modelock));
new_free(&(tmp->channellist->topiclock));
#endif
new_free(&(tmp->channellist->topicstr));
new_free(&(tmp->channellist->topicwho));
tmp->channellist->nicks=(NickList *) 0;
tmp->channellist->banlist=(struct bans *) 0;
new_free(&(tmp->channellist));
*list=tmp->next;
new_free(&tmp);
total++;
}
}
else {
while (*list && count) {
tmp=*list;
new_free(&(tmp->channellist->channel));
new_free(&(tmp->channellist->s_mode));
new_free(&(tmp->channellist->key));
#ifdef EXTRAS
new_free(&(tmp->channellist->modelock));
new_free(&(tmp->channellist->topiclock));
#endif
new_free(&(tmp->channellist->topicstr));
new_free(&(tmp->channellist->topicwho));
tmp->channellist->nicks=(NickList *) 0;
tmp->channellist->banlist=(struct bans *) 0;
new_free(&(tmp->channellist));
*list=tmp->next;
new_free(&tmp);
total++;
count--;
}
}
return(total);
}
void clean_whowas_chan_list() {
whowas_chan_count-=remove_oldest_chan_whowas(&whowas_chan_list,24*60*60,0);
}
/* Clean up memory used by whowas lists */
void CleanUpWhowas() {
remove_oldest_whowas(&whowas_userlist_list,0,whowas_userlist_max);
remove_oldest_whowas(&whowas_reg_list,0,whowas_reg_max);
remove_oldest_chan_whowas(&whowas_chan_list,0,whowas_chan_max);
}
/*
void show_whowas() {
int count=1;
WhowasList *tmp;
say("Scanning whowas userlist, flag thinks there is %d entries",whowas_userlist_count);
for (tmp=whowas_userlist_list;tmp;tmp=tmp->next) {
if (!tmp->nicklist) say("%d: NO NICKLIST!!! BUG!",count);
else say("%d: %s %s",count,tmp->nicklist->nick,tmp->nicklist->userhost);
if (!tmp->channel) say("%d: NO CHANNEL!!! BUG!",count);
else say("%d: %s",count,tmp->channel);
count++;
}
count=1;
say("Scanning whowas reg, flag thinks there is %d entries",whowas_reg_count);
for (tmp=whowas_reg_list;tmp;tmp=tmp->next) {
if (!tmp->nicklist) say("%d: NO NICKLIST!!! BUG!",count);
else say("%d: %s %s",count,tmp->nicklist->nick,tmp->nicklist->userhost);
if (!tmp->channel) say("%d: NO CHANNEL!!! BUG!",count);
else say("%d: %s",count,tmp->channel);
count++;
}
}*/
syntax highlighted by Code2HTML, v. 0.9.1