X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=ChanNode.c;h=73adbf6b3881ee6d17c505cb6eb48101a49c3519;hb=795115bf680185ae01043bd1222b78bfed8c1d87;hp=5eafa324404b1a3dcf13ecbf14572287ff905d9d;hpb=c6dca9fe53f48a28c287d8c354e0dbc90a5e9e2f;p=NeonServV5.git diff --git a/ChanNode.c b/ChanNode.c index 5eafa32..73adbf6 100644 --- a/ChanNode.c +++ b/ChanNode.c @@ -1,4 +1,9 @@ #include "ChanNode.h" +#include "ChanUser.h" +#include "UserNode.h" +#include "BanNode.h" +#include "modcmd.h" +#include "ModeNode.h" static struct ChanNode **chanList; @@ -12,7 +17,26 @@ void init_ChanNode() { --------------------------- = 47 */ - userList = calloc(47, sizeof(*userList)); + #define CHANNEL_LIST_SIZE 47 + chanList = calloc(CHANNEL_LIST_SIZE, sizeof(*chanList)); +} + +void free_ChanNode() { + //kamikaze free all channels and chanusers + int i; + struct ChanNode *chan, *next; + struct ChanUser *chanuser, *next_chanuser; + for(i = 0; i < CHANNEL_LIST_SIZE; i++) { + for(chan = chanList[i]; chan; chan = next) { + next = chan->next; + for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = next_chanuser) { + next_chanuser = getChannelUsers(chan, chanuser); + free(chanuser); + } + freeChanNode(chan); + } + } + free(chanList); } int is_valid_chan(const char *name) { @@ -31,7 +55,6 @@ int is_valid_chan(const char *name) { } static int get_chanlist_entry(int name) { - int i; if((name > 0 && name <= 32) || name == ',' || name == '\xa0') return -1; //invalid name if(tolower(name) >= 97 && tolower(name) <= 122) { return (tolower(name) - 97); @@ -54,7 +77,7 @@ static int get_chanlist_entry(int name) { } struct ChanNode* getChanByName(const char *name) { //case insensitive - int chanListIndex = get_chanlist_entry(*name); + int chanListIndex = get_chanlist_entry(name[1]); if(chanListIndex == -1 || chanList[chanListIndex] == NULL) return NULL; struct ChanNode *chan; @@ -65,10 +88,129 @@ struct ChanNode* getChanByName(const char *name) { //case insensitive return NULL; } -struct ChanNode* addChannel(const char *chan) { - return NULL; //to be continued +struct ChanNode* addChannel(const char *name) { + int chanListIndex = get_chanlist_entry(name[1]); + if(chanListIndex == -1 || !is_valid_chan(name)) + return NULL; + struct ChanNode *chan = malloc(sizeof(*chan)); + if (!chan) + { + perror("malloc() failed"); + return NULL; + } + strcpy(chan->name, name); + chan->user = NULL; + chan->bans = NULL; + chan->usercount = 0; + chan->chanbot = NULL; + chan->topic[0] = 0; + chan->flags = 0; + /* mode lists */ + chan->modes = createModeNode(chan); + chan->trigger = NULL; + + chan->next = chanList[chanListIndex]; + chanList[chanListIndex] = chan; + return chan; +} + +int getChannelCount() { + int i, count = 0; + struct ChanNode *chan; + for(i = 0; i < CHANNEL_LIST_SIZE; i++) { + for(chan = chanList[i]; chan; chan = chan->next) { + count++; + } + } + return count; +} + +int getChanUserCount() { + int i, count = 0; + struct ChanNode *chan; + for(i = 0; i < CHANNEL_LIST_SIZE; i++) { + for(chan = chanList[i]; chan; chan = chan->next) { + count += chan->usercount; + } + } + return count; +} + +int getChanBanCount() { + int i, count = 0; + struct ChanNode *chan; + struct BanNode *ban; + for(i = 0; i < CHANNEL_LIST_SIZE; i++) { + for(chan = chanList[i]; chan; chan = chan->next) { + for(ban = chan->bans; ban; ban = ban->next) + count ++; + } + } + return count; } void delChannel(struct ChanNode* chan, int freeChan) { - //to be continued + int chanListIndex = get_chanlist_entry(chan->name[1]); + if(chanListIndex == -1) return; + struct ChanNode *cchan, *last_chan = NULL; + for(cchan = chanList[chanListIndex]; cchan; cchan = cchan->next) { + if(cchan == chan) { + if(last_chan) + last_chan->next = chan->next; + else + chanList[chanListIndex] = chan->next; + break; + } else + last_chan = cchan; + } + if(chan->user) { + //free all chanusers + struct ChanUser *chanuser, *next; + for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = next) { + next = getChannelUsers(chan, chanuser); + removeChanUserFromLists(chanuser, 0, 1, 1); + } + } + if(freeChan) + freeChanNode(chan); + else + chan->next = NULL; +} + +void freeChanNode(struct ChanNode* chan) { + if(chan->trigger) { + struct trigger_cache *trigger, *next_trigger; + for(trigger = chan->trigger; trigger; trigger = next_trigger) { + next_trigger = trigger->next; + free(trigger->trigger); + free(trigger); + } + } + freeModeNode(chan->modes); + if(chan->bans) + removeChannelBans(chan); + free(chan); +} + +void checkChannelVisibility(struct ChanNode* chan) { + struct ChanUser *chanuser, *next; + for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) { + if(chanuser->user->flags & USERFLAG_ISBOT) { + chan->chanbot = chanuser->user; + return; + } + } + //free the channel... + for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = next) { + next = getChannelUsers(chan, chanuser); + //remove the channel from the user's channel-list + removeChanUserFromLists(chanuser, 0, 1, 0); + if(!chanuser->user->channel) { + //free the user (no more channels) + delUser(chanuser->user, 1); + } + free(chanuser); + } + chan->user = NULL; + delChannel(chan, 1); }