145 |
* side effects - remove ONE mode from a channel |
* side effects - remove ONE mode from a channel |
146 |
*/ |
*/ |
147 |
void |
void |
148 |
channel_demote_members(struct Channel *channel, const struct Client *client, unsigned int mask, const char flag) |
channel_demote_members(struct Channel *channel, const struct Client *client) |
149 |
{ |
{ |
150 |
dlink_node *node; |
dlink_node *node; |
151 |
char modebuf[MODEBUFLEN]; |
char modebuf[MAXMODEPARAMS + 1]; |
152 |
char parabuf[MODEBUFLEN]; |
char parabuf[MAXMODEPARAMS * (NICKLEN + 1) + 1]; |
153 |
char *mbuf = modebuf; |
char *mbuf = modebuf; |
154 |
char *pbuf = parabuf; |
char *pbuf = parabuf; |
155 |
const char *names[MAXMODEPARAMS]; |
unsigned int pargs = 0; |
156 |
static const unsigned int names_size = sizeof(names) / sizeof(names[0]); |
struct member_status |
157 |
unsigned int count = 0; |
{ |
158 |
|
unsigned char prefix; |
159 |
|
unsigned int flag; |
160 |
|
} table[] = |
161 |
|
{ |
162 |
|
{ 'o', CHFL_CHANOP }, |
163 |
|
{ 'h', CHFL_HALFOP }, |
164 |
|
{ 'v', CHFL_VOICE }, |
165 |
|
{ '\0', 0 } |
166 |
|
}; |
167 |
|
|
168 |
DLINK_FOREACH(node, channel->members.head) |
DLINK_FOREACH(node, channel->members.head) |
169 |
{ |
{ |
170 |
struct ChannelMember *member = node->data; |
struct ChannelMember *member = node->data; |
171 |
|
|
172 |
if ((member->flags & mask) == 0) |
for (const struct member_status *status = table; status->flag; ++status) |
|
continue; |
|
|
|
|
|
member->flags &= ~mask; |
|
|
|
|
|
names[count++] = member->client->name; |
|
|
|
|
|
*mbuf++ = flag; |
|
|
|
|
|
if (count >= names_size) |
|
173 |
{ |
{ |
174 |
*mbuf = '\0'; |
if (member->flags & status->flag) |
175 |
|
{ |
176 |
for (unsigned int i = 0; i < names_size; ++i) |
member->flags &= ~status->flag; |
177 |
pbuf += snprintf(pbuf, sizeof(parabuf) - (pbuf - parabuf), " %s", names[i]); |
*mbuf++ = status->prefix; |
178 |
|
pbuf += snprintf(pbuf, sizeof(parabuf) - (pbuf - parabuf), "%s ", member->client->name); |
179 |
sendto_channel_local(NULL, channel, 0, 0, 0, ":%s MODE %s -%s%s", |
|
180 |
client->name, channel->name, modebuf, parabuf); |
if (++pargs >= MAXMODEPARAMS) |
181 |
mbuf = modebuf; |
{ |
182 |
pbuf = parabuf; |
*mbuf = *(pbuf - 1) = '\0'; |
183 |
count = 0; |
sendto_channel_local(NULL, channel, 0, 0, 0, ":%s MODE %s -%s %s", |
184 |
|
client->name, channel->name, modebuf, parabuf); |
185 |
|
|
186 |
|
mbuf = modebuf; |
187 |
|
pbuf = parabuf; |
188 |
|
pargs = 0; |
189 |
|
} |
190 |
|
} |
191 |
} |
} |
192 |
} |
} |
193 |
|
|
194 |
if (count) |
if (pargs) |
195 |
{ |
{ |
196 |
assert(count < names_size); |
*mbuf = *(pbuf - 1) = '\0'; |
197 |
*mbuf = '\0'; |
sendto_channel_local(NULL, channel, 0, 0, 0, ":%s MODE %s -%s %s", |
|
|
|
|
for (unsigned int i = 0; i < count; ++i) |
|
|
pbuf += snprintf(pbuf, sizeof(parabuf) - (pbuf - parabuf), " %s", names[i]); |
|
|
|
|
|
sendto_channel_local(NULL, channel, 0, 0, 0, ":%s MODE %s -%s%s", |
|
198 |
client->name, channel->name, modebuf, parabuf); |
client->name, channel->name, modebuf, parabuf); |
199 |
} |
} |
200 |
} |
} |