2 #include "cmd_neonserv.h"
5 * argv[0-*] nick[,*auth[,*!*@mask[...]]]
7 struct neonserv_cmd_unban_cache {
8 struct ClientSocket *client, *textclient;
10 struct ChanNode *chan;
12 struct ModeBuffer *modeBuf;
13 int provided_masks, done_masks, pending_whos, unbanned_masks;
16 static USERAUTH_CALLBACK(neonserv_cmd_unban_userauth_lookup);
17 static void neonserv_cmd_unban_nick(struct neonserv_cmd_unban_cache *cache, struct UserNode *user);
18 static void neonserv_cmd_unban_mask(struct neonserv_cmd_unban_cache *cache, char *mask);
19 static void neonserv_cmd_unban_finish(struct neonserv_cmd_unban_cache *cache);
21 CMD_BIND(neonserv_cmd_unban) {
22 char *mask, *nextmask;
23 struct ModeBuffer *modeBuf;
24 modeBuf = initModeBuffer(client, chan);
25 nextmask = merge_argv_char(argv, 0, argc, ',');
26 struct neonserv_cmd_unban_cache *cache = malloc(sizeof(*cache));
28 perror("malloc() failed");
31 cache->client = client;
32 cache->textclient = getTextBot();
36 cache->modeBuf = modeBuf;
37 cache->done_masks = 0;
38 cache->provided_masks = 0;
39 cache->unbanned_masks = 0;
40 while((mask = nextmask)) {
41 nextmask = strstr(mask, ",");
46 cache->provided_masks++;
47 if(is_valid_nick(mask)) {
48 struct UserNode *cuser = getUserByNick(mask);
50 cuser = createTempUser(mask);
51 cuser->flags |= USERFLAG_ISTMPUSER;
52 get_userauth(cuser, neonserv_cmd_unban_userauth_lookup, cache);
53 cache->pending_whos++;
55 neonserv_cmd_unban_nick(cache, cuser);
58 neonserv_cmd_unban_mask(cache, mask);
61 if(!cache->pending_whos)
62 neonserv_cmd_unban_finish(cache);
65 static USERAUTH_CALLBACK(neonserv_cmd_unban_userauth_lookup) {
66 struct neonserv_cmd_unban_cache *cache = data;
67 cache->pending_whos--;
69 neonserv_cmd_unban_nick(cache, user);
71 neonserv_cmd_unban_mask(cache, user_nick);
72 if(!cache->pending_whos)
73 neonserv_cmd_unban_finish(cache);
76 static void neonserv_cmd_unban_nick(struct neonserv_cmd_unban_cache *cache, struct UserNode *user) {
79 char usermask[NICKLEN+USERLEN+HOSTLEN+3];
80 sprintf(usermask, "%s!%s@%s", user->nick, user->ident, user->host);
81 for(ban = cache->chan->bans; ban; ban = ban->next) {
82 if(!match(ban->mask, usermask)) {
83 modeBufferUnban(cache->modeBuf, ban->mask);
84 cache->unbanned_masks++;
92 static void neonserv_cmd_unban_mask(struct neonserv_cmd_unban_cache *cache, char *mask) {
93 char banmask[NICKLEN+USERLEN+HOSTLEN+3];
96 mask = make_banmask(mask, banmask);
97 for(ban = cache->chan->bans; ban; ban = ban->next) {
98 if(!match(mask, ban->mask)) {
99 modeBufferUnban(cache->modeBuf, ban->mask);
100 cache->unbanned_masks++;
107 for(ban = cache->chan->bans; ban; ban = ban->next) {
108 if(!match(ban->mask, mask)) {
109 reply(cache->textclient, cache->user, "NS_DELBAN_BANNED_BY", mask, ban->mask);
116 static void neonserv_cmd_unban_finish(struct neonserv_cmd_unban_cache *cache) {
117 freeModeBuffer(cache->modeBuf);
118 if(cache->done_masks == cache->provided_masks)
119 reply(cache->textclient, cache->user, "NS_UNBAN_DONE", cache->unbanned_masks, cache->chan->name);
121 reply(cache->textclient, cache->user, "NS_UNBAN_FAIL", cache->client->user->nick);
122 if(cache->done_masks)
123 logEvent(cache->event);