added new multi log system
[NeonServV5.git] / src / modules / NeonServ.mod / cmd_neonserv_unban.c
1 /* cmd_neonserv_unban.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 "cmd_neonserv.h"
19
20 /*
21 * argv[0-*]    nick[,*auth[,*!*@mask[...]]]
22 */
23 struct neonserv_cmd_unban_cache {
24     struct ClientSocket *client, *textclient;
25     struct UserNode *user;
26     struct ChanNode *chan;
27     struct Event *event;
28     struct ModeBuffer *modeBuf;
29     int provided_masks, done_masks, pending_whos, unbanned_masks;
30 };
31
32 static USERAUTH_CALLBACK(neonserv_cmd_unban_userauth_lookup);
33 static void neonserv_cmd_unban_nick(struct neonserv_cmd_unban_cache *cache, struct UserNode *user);
34 static void neonserv_cmd_unban_mask(struct neonserv_cmd_unban_cache *cache, char *mask);
35 static void neonserv_cmd_unban_finish(struct neonserv_cmd_unban_cache *cache);
36
37 CMD_BIND(neonserv_cmd_unban) {
38     char *mask, *nextmask;
39     struct ModeBuffer *modeBuf;
40     modeBuf = initModeBuffer(client, chan);
41     nextmask = merge_argv_char(argv, 0, argc, ',');
42     struct neonserv_cmd_unban_cache *cache = malloc(sizeof(*cache));
43     if (!cache) {
44         printf_log("neonserv", LOG_ERROR, "%s:%d malloc() failed", __FILE__, __LINE__);
45         return;
46     }
47     cache->client = client;
48     cache->textclient = textclient;
49     cache->user = user;
50     cache->chan = chan;
51     cache->event = event;
52     cache->modeBuf = modeBuf;
53     cache->done_masks = 0;
54     cache->provided_masks = 0;
55     cache->unbanned_masks = 0;
56     while((mask = nextmask)) {
57         nextmask = strstr(mask, ",");
58         if(nextmask) {
59             *nextmask = '\0';
60             nextmask++;
61         }
62         cache->provided_masks++;
63         if(is_valid_nick(mask)) {
64             struct UserNode *cuser = getUserByNick(mask);
65             if(!cuser) {
66                 cuser = createTempUserMask(mask);
67                                 if(!cuser) {
68                                         break; //internal bot error
69                                 }
70                 cuser->flags |= USERFLAG_ISTMPUSER;
71                 get_userauth(cuser, module_id, neonserv_cmd_unban_userauth_lookup, cache);
72                 cache->pending_whos++;
73             } else {
74                 neonserv_cmd_unban_nick(cache, cuser);
75             }
76         } else {
77             neonserv_cmd_unban_mask(cache, mask);
78         }
79     }
80     if(!cache->pending_whos)
81         neonserv_cmd_unban_finish(cache);
82 }
83
84 static USERAUTH_CALLBACK(neonserv_cmd_unban_userauth_lookup) {
85     struct neonserv_cmd_unban_cache *cache = data;
86     cache->pending_whos--;
87     if(user)
88         neonserv_cmd_unban_nick(cache, user);
89     else
90         neonserv_cmd_unban_mask(cache, user_nick);
91     if(!cache->pending_whos)
92         neonserv_cmd_unban_finish(cache);
93 }
94
95 static void neonserv_cmd_unban_nick(struct neonserv_cmd_unban_cache *cache, struct UserNode *user) {
96     int matches = 0;
97     struct BanNode *ban;
98     char usermask[NICKLEN+USERLEN+HOSTLEN+3];
99     sprintf(usermask, "%s!%s@%s", user->nick, user->ident, user->host);
100     for(ban = cache->chan->bans; ban; ban = ban->next) {
101         if(!match(ban->mask, usermask)) {
102             modeBufferUnban(cache->modeBuf, ban->mask);
103             cache->unbanned_masks++;
104             matches++;
105         }
106     }
107     if(matches)
108         cache->done_masks++;
109 }
110
111 static void neonserv_cmd_unban_mask(struct neonserv_cmd_unban_cache *cache, char *mask) {
112     char banmask[NICKLEN+USERLEN+HOSTLEN+3];
113     int matches = 0;
114     struct BanNode *ban;
115     mask = make_banmask(mask, banmask);
116     for(ban = cache->chan->bans; ban; ban = ban->next) {
117         if(!match(mask, ban->mask)) {
118             modeBufferUnban(cache->modeBuf, ban->mask);
119             cache->unbanned_masks++;
120             matches++;
121         }
122     }
123     if(matches)
124         cache->done_masks++;
125     else {
126         for(ban = cache->chan->bans; ban; ban = ban->next) {
127             if(!match(ban->mask, mask)) {
128                 reply(cache->textclient, cache->user, "NS_DELBAN_BANNED_BY", mask, ban->mask);
129                 break;
130             }
131         }
132     }
133 }
134
135 static void neonserv_cmd_unban_finish(struct neonserv_cmd_unban_cache *cache) {
136     freeModeBuffer(cache->modeBuf);
137     if(cache->done_masks == cache->provided_masks)
138         reply(cache->textclient, cache->user, "NS_UNBAN_DONE", cache->unbanned_masks, cache->chan->name);
139     else
140         reply(cache->textclient, cache->user, "NS_UNBAN_FAIL", cache->client->user->nick);
141     if(cache->done_masks)
142         logEvent(cache->event);
143     free(cache);
144 }
145