added some debug code & fixed compiler warning
[NeonServV5.git] / src / ChanUser.c
1 /* ChanUser.c - NeonServ v5.6
2  * Copyright (C) 2011-2012  Philipp Kreil (pk910)
3  * 
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License 
15  * along with this program. If not, see <http://www.gnu.org/licenses/>. 
16  */
17
18 #include "ChanUser.h"
19 #include "ChanNode.h"
20 #include "ModeNode.h"
21 #include "UserNode.h"
22
23 struct ChanUser* addChanUser(struct ChanNode *chan, struct UserNode *user) {
24     if(isUserOnChan(user, chan)) {
25         putlog(LOGLEVEL_ERROR, "CACHE FAIL");
26     }
27     struct ChanUser *chanuser = malloc(sizeof(*chanuser));
28     if (!chanuser)
29     {
30         perror("malloc() failed");
31         return NULL;
32     }
33     chanuser->flags = 0;
34     chanuser->user = user;
35     chanuser->chan = chan;
36     chanuser->visCount = 0;
37     
38     chanuser->changeTime = 0;
39     chanuser->spamnode = NULL;
40
41     SYNCHRONIZE(cache_sync);
42
43     chanuser->next_user = chan->user;
44     chan->user = chanuser;
45     chan->usercount++;
46
47     chanuser->next_chan = user->channel;
48     user->channel = chanuser;
49
50     DESYNCHRONIZE(cache_sync);
51
52     return chanuser;
53 }
54
55 struct ChanUser* addInvisibleChanUser(struct ChanNode *chan, struct UserNode *user) {
56     struct ChanUser *chanuser = malloc(sizeof(*chanuser));
57     if (!chanuser)
58     {
59         perror("malloc() failed");
60         return NULL;
61     }
62     chanuser->flags = CHANUSERFLAG_INVISIBLE;
63     chanuser->user = user;
64     chanuser->chan = chan;
65     chanuser->visCount = 0;
66     
67     chanuser->changeTime = 0;
68     chanuser->spamnode = NULL;
69
70     SYNCHRONIZE(cache_sync);
71     chanuser->next_user = chan->user;
72     chan->user = chanuser;
73     DESYNCHRONIZE(cache_sync);
74     chan->usercount++;
75
76     return chanuser;
77 }
78
79 int isUserOnChan(struct UserNode *user, struct ChanNode *chan) {
80     struct ChanUser *chanuser;
81     if(isModeSet(chan->modes, 'd') || isModeSet(chan->modes, 'D')) {
82         for(chanuser = chan->user; chanuser; chanuser = chanuser->next_user) {
83             if(chanuser->user == user)
84                 return 1;
85         }
86     } else {
87         for(chanuser = user->channel; chanuser; chanuser = chanuser->next_chan) {
88             if(chanuser->chan == chan)
89                 return 1;
90         }
91     }
92     return 0;
93 }
94
95 struct ChanUser* getChanUser(struct UserNode *user, struct ChanNode *chan) {
96     struct ChanUser *chanuser;
97     if(isModeSet(chan->modes, 'd') || isModeSet(chan->modes, 'D')) {
98         for(chanuser = chan->user; chanuser; chanuser = chanuser->next_user) {
99             if(chanuser->user == user)
100                 return chanuser;
101         }
102     } else {
103         for(chanuser = user->channel; chanuser; chanuser = chanuser->next_chan) {
104             if(chanuser->chan == chan)
105                 return chanuser;
106         }
107     }
108     return NULL;
109 }
110
111 struct ChanUser* getChannelUsers(struct ChanNode *chan, struct ChanUser *last) {
112     if(last == NULL)
113         return chan->user;
114     else
115         return last->next_user;
116 }
117
118 struct ChanUser* getUserChannels(struct UserNode *user, struct ChanUser *last) {
119     if(last == NULL)
120         return user->channel;
121     else
122         return last->next_chan;
123 }
124
125 void delChanUser(struct ChanUser *chanuser, int do_freeChanUser) {
126     SYNCHRONIZE(cache_sync);
127     struct ChanUser *cchanuser, *last;
128     //remove it from the user's channel-list
129     last = NULL;
130     for(cchanuser = chanuser->user->channel; cchanuser; cchanuser = cchanuser->next_chan) {
131         if(cchanuser == chanuser) {
132             if(last) 
133                 last->next_chan = chanuser->next_chan;
134             else
135                 chanuser->user->channel = chanuser->next_chan;
136             break;
137         } else
138             last = cchanuser;
139     }
140
141     //remove it from the channel's user-list
142     last = NULL;
143     for(cchanuser = chanuser->chan->user; cchanuser; cchanuser = cchanuser->next_user) {
144         if(cchanuser == chanuser) {
145             chanuser->chan->usercount--;
146             if(last) 
147                 last->next_user = chanuser->next_user;
148             else
149                 chanuser->chan->user = chanuser->next_user;
150             break;
151         } else
152             last = cchanuser;
153     }
154     
155     if(do_freeChanUser) {
156         freeChanUser(chanuser);
157     } else {
158         chanuser->next_chan = NULL;
159         chanuser->next_user = NULL;
160     }
161     DESYNCHRONIZE(cache_sync);
162 }
163
164 void removeChanUserFromLists(struct ChanUser *chanuser, int remove_from_userlist, int remove_from_channellist, int do_freeChanUser) {
165     SYNCHRONIZE(cache_sync);
166     struct ChanUser *cchanuser, *last;
167     if(remove_from_userlist) {
168         //remove it from the channel's user-list
169         last = NULL;
170         for(cchanuser = chanuser->chan->user; cchanuser; cchanuser = cchanuser->next_user) {
171             if(cchanuser == chanuser) {
172                 chanuser->chan->usercount--;
173                 if(last) 
174                     last->next_user = chanuser->next_user;
175                 else
176                     chanuser->chan->user = chanuser->next_user;
177                 break;
178             } else
179                 last = cchanuser;
180         }
181         chanuser->next_user = NULL;
182     }
183     if(remove_from_channellist) {
184         //remove it from the user's channel-list
185         last = NULL;
186         for(cchanuser = chanuser->user->channel; cchanuser; cchanuser = cchanuser->next_chan) {
187             if(cchanuser == chanuser) {
188                 if(last) 
189                     last->next_chan = chanuser->next_chan;
190                 else
191                     chanuser->user->channel = chanuser->next_chan;
192                 break;
193             } else
194                 last = cchanuser;
195         }
196         chanuser->next_chan = NULL;
197     }
198     
199     if(do_freeChanUser) {
200         freeChanUser(chanuser);
201     }
202     DESYNCHRONIZE(cache_sync);
203 }
204
205 void freeChanUser(struct ChanUser *chanuser) {
206     if(chanuser->spamnode)
207         free(chanuser->spamnode);
208     free(chanuser);
209 }
210