3 * argv[0-*] nick[,*auth[,*!*@mask[...]]]
5 struct neonserv_cmd_unban_cache {
6 struct ClientSocket *client, *textclient;
10 struct ModeBuffer *modeBuf;
11 int provided_masks, done_masks, pending_whos, unbanned_masks;
14 static USERAUTH_CALLBACK(neonserv_cmd_unban_userauth_lookup);
15 static void neonserv_cmd_unban_nick(struct neonserv_cmd_unban_cache *cache, struct UserNode *user);
16 static void neonserv_cmd_unban_mask(struct neonserv_cmd_unban_cache *cache, char *mask);
17 static void neonserv_cmd_unban_finish(struct neonserv_cmd_unban_cache *cache);
19 static CMD_BIND(neonserv_cmd_unban) {
20 char *mask, *nextmask;
21 struct ModeBuffer *modeBuf;
22 modeBuf = initModeBuffer(client, chan);
23 nextmask = merge_argv_char(argv, 0, argc, ',');
24 struct neonserv_cmd_unban_cache *cache = malloc(sizeof(*cache));
26 perror("malloc() failed");
29 cache->client = client;
30 cache->textclient = getTextBot();
34 cache->modeBuf = modeBuf;
35 cache->done_masks = 0;
36 cache->provided_masks = 0;
37 cache->unbanned_masks = 0;
38 while((mask = nextmask)) {
39 nextmask = strstr(mask, ",");
44 cache->provided_masks++;
45 if(is_valid_nick(mask)) {
46 struct UserNode *cuser = getUserByNick(mask);
48 cuser = createTempUser(mask);
49 cuser->flags |= USERFLAG_ISTMPUSER;
50 get_userauth(cuser, neonserv_cmd_unban_userauth_lookup, cache);
51 cache->pending_whos++;
53 neonserv_cmd_unban_nick(cache, cuser);
56 neonserv_cmd_unban_mask(cache, mask);
59 if(!cache->pending_whos)
60 neonserv_cmd_unban_finish(cache);
63 static USERAUTH_CALLBACK(neonserv_cmd_unban_userauth_lookup) {
64 struct neonserv_cmd_unban_cache *cache = data;
65 cache->pending_whos--;
67 neonserv_cmd_unban_nick(cache, user);
69 neonserv_cmd_unban_mask(cache, user_nick);
70 if(!cache->pending_whos)
71 neonserv_cmd_unban_finish(cache);
74 static void neonserv_cmd_unban_nick(struct neonserv_cmd_unban_cache *cache, struct UserNode *user) {
77 char usermask[NICKLEN+USERLEN+HOSTLEN+3];
78 sprintf(usermask, "%s!%s@%s", user->nick, user->ident, user->host);
79 for(ban = cache->chan->bans; ban; ban = ban->next) {
80 if(!match(ban->mask, usermask)) {
81 modeBufferUnban(cache->modeBuf, ban->mask);
82 cache->unbanned_masks++;
90 static void neonserv_cmd_unban_mask(struct neonserv_cmd_unban_cache *cache, char *mask) {
91 char banmask[NICKLEN+USERLEN+HOSTLEN+3];
94 mask = make_banmask(mask, banmask);
95 for(ban = cache->chan->bans; ban; ban = ban->next) {
96 if(!match(mask, ban->mask)) {
97 modeBufferUnban(cache->modeBuf, ban->mask);
98 cache->unbanned_masks++;
105 for(ban = cache->chan->bans; ban; ban = ban->next) {
106 if(!match(ban->mask, mask)) {
107 reply(cache->textclient, cache->user, "NS_DELBAN_BANNED_BY", mask, ban->mask);
114 static void neonserv_cmd_unban_finish(struct neonserv_cmd_unban_cache *cache) {
115 freeModeBuffer(cache->modeBuf);
116 if(cache->done_masks == cache->provided_masks)
117 reply(cache->textclient, cache->user, "NS_UNBAN_DONE", cache->unbanned_masks, cache->chan->name);
119 reply(cache->textclient, cache->user, "NS_UNBAN_FAIL", cache->client->user->nick);
120 if(cache->done_masks)
121 logEvent(cache->event);