-/* ChanUser.c - NeonServ v5.0
- * Copyright (C) 2011 Philipp Kreil (pk910)
+/* ChanUser.c - NeonServ v5.5
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
*
* 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
#include "ChanUser.h"
#include "ChanNode.h"
+#include "ModeNode.h"
#include "UserNode.h"
struct ChanUser* addChanUser(struct ChanNode *chan, struct UserNode *user) {
- struct ChanUser *chanuser = malloc(sizeof(*chan));
+ struct ChanUser *chanuser = malloc(sizeof(*chanuser));
if (!chanuser)
{
perror("malloc() failed");
chanuser->flags = 0;
chanuser->user = user;
chanuser->chan = chan;
+ chanuser->visCount = 0;
chanuser->changeTime = 0;
+ chanuser->spamnode = NULL;
+
+ SYNCHRONIZE(cache_sync);
chanuser->next_user = chan->user;
chan->user = chanuser;
chanuser->next_chan = user->channel;
user->channel = chanuser;
+ DESYNCHRONIZE(cache_sync);
+
return chanuser;
}
struct ChanUser* addInvisibleChanUser(struct ChanNode *chan, struct UserNode *user) {
- struct ChanUser *chanuser = malloc(sizeof(*chan));
+ struct ChanUser *chanuser = malloc(sizeof(*chanuser));
if (!chanuser)
{
perror("malloc() failed");
chanuser->flags = CHANUSERFLAG_INVISIBLE;
chanuser->user = user;
chanuser->chan = chan;
+ chanuser->visCount = 0;
chanuser->changeTime = 0;
+ chanuser->spamnode = NULL;
+ SYNCHRONIZE(cache_sync);
chanuser->next_user = chan->user;
chan->user = chanuser;
+ DESYNCHRONIZE(cache_sync);
chan->usercount++;
return chanuser;
int isUserOnChan(struct UserNode *user, struct ChanNode *chan) {
struct ChanUser *chanuser;
- for(chanuser = user->channel; chanuser; chanuser = chanuser->next_chan) {
- if(chanuser->chan == chan)
- return 1;
+ if(isModeSet(chan->modes, 'd') || isModeSet(chan->modes, 'D')) {
+ for(chanuser = chan->user; chanuser; chanuser = chanuser->next_user) {
+ if(chanuser->user == user)
+ return 1;
+ }
+ } else {
+ for(chanuser = user->channel; chanuser; chanuser = chanuser->next_chan) {
+ if(chanuser->chan == chan)
+ return 1;
+ }
}
return 0;
}
struct ChanUser* getChanUser(struct UserNode *user, struct ChanNode *chan) {
struct ChanUser *chanuser;
- for(chanuser = user->channel; chanuser; chanuser = chanuser->next_chan) {
- if(chanuser->chan == chan)
- return chanuser;
+ if(isModeSet(chan->modes, 'd') || isModeSet(chan->modes, 'D')) {
+ for(chanuser = chan->user; chanuser; chanuser = chanuser->next_user) {
+ if(chanuser->user == user)
+ return chanuser;
+ }
+ } else {
+ for(chanuser = user->channel; chanuser; chanuser = chanuser->next_chan) {
+ if(chanuser->chan == chan)
+ return chanuser;
+ }
}
return NULL;
}
return last->next_chan;
}
-void delChanUser(struct ChanUser *chanuser, int freeChanUser) {
+void delChanUser(struct ChanUser *chanuser, int do_freeChanUser) {
+ SYNCHRONIZE(cache_sync);
struct ChanUser *cchanuser, *last;
//remove it from the user's channel-list
- if(!(chanuser->flags & CHANUSERFLAG_INVISIBLE)) {
- last = NULL;
- for(cchanuser = chanuser->user->channel; cchanuser; cchanuser = cchanuser->next_chan) {
- if(cchanuser == chanuser) {
- if(last)
- last->next_chan = chanuser->next_chan;
- else
- chanuser->user->channel = chanuser->next_chan;
- break;
- } else
- last = cchanuser;
- }
+ last = NULL;
+ for(cchanuser = chanuser->user->channel; cchanuser; cchanuser = cchanuser->next_chan) {
+ if(cchanuser == chanuser) {
+ if(last)
+ last->next_chan = chanuser->next_chan;
+ else
+ chanuser->user->channel = chanuser->next_chan;
+ break;
+ } else
+ last = cchanuser;
}
//remove it from the channel's user-list
last = cchanuser;
}
- if(freeChanUser)
- free(chanuser);
- else {
+ if(do_freeChanUser) {
+ freeChanUser(chanuser);
+ } else {
chanuser->next_chan = NULL;
chanuser->next_user = NULL;
}
+ DESYNCHRONIZE(cache_sync);
}
-void removeChanUserFromLists(struct ChanUser *chanuser, int remove_from_userlist, int remove_from_channellist, int freeChanUser) {
+void removeChanUserFromLists(struct ChanUser *chanuser, int remove_from_userlist, int remove_from_channellist, int do_freeChanUser) {
+ SYNCHRONIZE(cache_sync);
struct ChanUser *cchanuser, *last;
if(remove_from_userlist) {
//remove it from the channel's user-list
chanuser->next_chan = NULL;
}
- if(freeChanUser)
- free(chanuser);
+ if(do_freeChanUser) {
+ freeChanUser(chanuser);
+ }
+ DESYNCHRONIZE(cache_sync);
+}
+
+void freeChanUser(struct ChanUser *chanuser) {
+ if(chanuser->spamnode)
+ free(chanuser->spamnode);
+ free(chanuser);
}