ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/channel_mode.c
(Generate patch)

Comparing ircd-hybrid/trunk/src/channel_mode.c (file contents):
Revision 3153 by michael, Fri Mar 14 15:39:21 2014 UTC vs.
Revision 5753 by michael, Thu Apr 2 17:29:12 2015 UTC

# Line 1 | Line 1
1   /*
2   *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Copyright (c) 1997-2014 ircd-hybrid development team
4 > *  Copyright (c) 1997-2015 ircd-hybrid development team
5   *
6   *  This program is free software; you can redistribute it and/or modify
7   *  it under the terms of the GNU General Public License as published by
# Line 15 | Line 15
15   *
16   *  You should have received a copy of the GNU General Public License
17   *  along with this program; if not, write to the Free Software
18 < *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
18 > *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19   *  USA
20   */
21  
# Line 34 | Line 34
34   #include "irc_string.h"
35   #include "ircd.h"
36   #include "numeric.h"
37 < #include "s_serv.h"
37 > #include "server.h"
38   #include "send.h"
39   #include "memory.h"
40   #include "mempool.h"
# Line 63 | Line 63 | const struct mode_letter chan_modes[] =
63    { MODE_REGISTERED, 'r' },
64    { MODE_SECRET,     's' },
65    { MODE_TOPICLIMIT, 't' },
66 +  { MODE_NOCTCP,     'C' },
67    { MODE_MODREG,     'M' },
68    { MODE_OPERONLY,   'O' },
69    { MODE_REGONLY,    'R' },
# Line 83 | Line 84 | const struct mode_letter chan_modes[] =
84   static char *
85   check_string(char *s)
86   {
87 <  char *str = s;
87 >  char *const str = s;
88    static char star[] = "*";
89  
90    if (EmptyString(str))
# Line 102 | Line 103 | check_string(char *s)
103   }
104  
105   /*
106 < * Ban functions to work with mode +b/e/d/I
106 > * Ban functions to work with mode +b/e/I
107   */
108   /* add the specified ID to the channel.
109   *   -is 8/9/00
# Line 112 | Line 113 | int
113   add_id(struct Client *client_p, struct Channel *chptr, char *banid, unsigned int type)
114   {
115    dlink_list *list = NULL;
116 <  dlink_node *ban = NULL;
116 >  dlink_node *node = NULL;
117 >  struct Ban *ban = NULL;
118    size_t len = 0;
119 <  struct Ban *ban_p = NULL;
120 <  unsigned int num_mask;
121 <  char name[NICKLEN + 1];
120 <  char user[USERLEN + 1];
121 <  char host[HOSTLEN + 1];
119 >  char name[NICKLEN + 1] = "";
120 >  char user[USERLEN + 1] = "";
121 >  char host[HOSTLEN + 1] = "";
122    struct split_nuh_item nuh;
123  
124 <  /* dont let local clients overflow the b/e/I lists */
124 >  /* Don't let local clients overflow the b/e/I lists */
125    if (MyClient(client_p))
126    {
127 <    num_mask = dlink_list_length(&chptr->banlist) +
128 <               dlink_list_length(&chptr->exceptlist) +
129 <               dlink_list_length(&chptr->invexlist);
127 >    unsigned int num_mask = dlink_list_length(&chptr->banlist) +
128 >                            dlink_list_length(&chptr->exceptlist) +
129 >                            dlink_list_length(&chptr->invexlist);
130  
131      if (num_mask >= ConfigChannel.max_bans)
132      {
133 <      sendto_one_numeric(client_p, &me, ERR_BANLISTFULL, chptr->chname, banid);
133 >      sendto_one_numeric(client_p, &me, ERR_BANLISTFULL, chptr->name, banid);
134        return 0;
135      }
136  
# Line 152 | Line 152 | add_id(struct Client *client_p, struct C
152     * Re-assemble a new n!u@h and print it back to banid for sending
153     * the mode to the channel.
154     */
155 <  len = sprintf(banid, "%s!%s@%s", name, user, host);
155 >  len = snprintf(banid, IRCD_BUFSIZE, "%s!%s@%s", name, user, host);
156  
157    switch (type)
158    {
159      case CHFL_BAN:
160        list = &chptr->banlist;
161 <      clear_ban_cache(chptr);
161 >      clear_ban_cache_channel(chptr);
162        break;
163      case CHFL_EXCEPTION:
164        list = &chptr->exceptlist;
165 <      clear_ban_cache(chptr);
165 >      clear_ban_cache_channel(chptr);
166        break;
167      case CHFL_INVEX:
168        list = &chptr->invexlist;
# Line 172 | Line 172 | add_id(struct Client *client_p, struct C
172        return 0;
173    }
174  
175 <  DLINK_FOREACH(ban, list->head)
175 >  DLINK_FOREACH(node, list->head)
176    {
177 <    ban_p = ban->data;
177 >    ban = node->data;
178  
179 <    if (!irccmp(ban_p->name, name) &&
180 <        !irccmp(ban_p->user, user) &&
181 <        !irccmp(ban_p->host, host))
179 >    if (!irccmp(ban->name, name) &&
180 >        !irccmp(ban->user, user) &&
181 >        !irccmp(ban->host, host))
182        return 0;
183    }
184  
185 <  ban_p = mp_pool_get(ban_pool);
186 <  memset(ban_p, 0, sizeof(*ban_p));
187 <  ban_p->name = xstrdup(name);
188 <  ban_p->user = xstrdup(user);
189 <  ban_p->host = xstrdup(host);
190 <  ban_p->when = CurrentTime;
191 <  ban_p->len = len - 2;  /* -2 for @ and ! */
192 <  ban_p->type = parse_netmask(host, &ban_p->addr, &ban_p->bits);
185 >  ban = mp_pool_get(ban_pool);
186 >  ban->name = xstrdup(name);
187 >  ban->user = xstrdup(user);
188 >  ban->host = xstrdup(host);
189 >  ban->when = CurrentTime;
190 >  ban->len = len - 2;  /* -2 for ! + @ */
191 >  ban->type = parse_netmask(host, &ban->addr, &ban->bits);
192  
193    if (IsClient(client_p))
194    {
195 <    ban_p->who = MyMalloc(strlen(client_p->name) +
196 <                          strlen(client_p->username) +
197 <                          strlen(client_p->host) + 3);
198 <    sprintf(ban_p->who, "%s!%s@%s", client_p->name,
195 >    ban->who = MyCalloc(strlen(client_p->name) +
196 >                        strlen(client_p->username) +
197 >                        strlen(client_p->host) + 3);
198 >    sprintf(ban->who, "%s!%s@%s", client_p->name,
199              client_p->username, client_p->host);
200    }
201 <  else if (IsHidden(client_p) || (IsServer(client_p) && ConfigServerHide.hide_servers))
202 <    ban_p->who = xstrdup(me.name);
201 >  else if (IsHidden(client_p) || ConfigServerHide.hide_servers)
202 >    ban->who = xstrdup(me.name);
203    else
204 <    ban_p->who = xstrdup(client_p->name);
204 >    ban->who = xstrdup(client_p->name);
205  
206 <  dlinkAdd(ban_p, &ban_p->node, list);
206 >  dlinkAdd(ban, &ban->node, list);
207  
208    return 1;
209   }
# Line 219 | Line 218 | add_id(struct Client *client_p, struct C
218   static int
219   del_id(struct Channel *chptr, char *banid, unsigned int type)
220   {
221 <  dlink_list *list;
222 <  dlink_node *ban;
223 <  struct Ban *banptr;
224 <  char name[NICKLEN + 1];
225 <  char user[USERLEN + 1];
227 <  char host[HOSTLEN + 1];
221 >  dlink_list *list = NULL;
222 >  dlink_node *node = NULL;
223 >  char name[NICKLEN + 1] = "";
224 >  char user[USERLEN + 1] = "";
225 >  char host[HOSTLEN + 1] = "";
226    struct split_nuh_item nuh;
227  
228    assert(banid);
# Line 244 | Line 242 | del_id(struct Channel *chptr, char *bani
242     * Re-assemble a new n!u@h and print it back to banid for sending
243     * the mode to the channel.
244     */
245 <  sprintf(banid, "%s!%s@%s", name, user, host);
245 >  snprintf(banid, IRCD_BUFSIZE, "%s!%s@%s", name, user, host);
246  
247    switch (type)
248    {
249      case CHFL_BAN:
250        list = &chptr->banlist;
251 <      clear_ban_cache(chptr);
251 >      clear_ban_cache_channel(chptr);
252        break;
253      case CHFL_EXCEPTION:
254        list = &chptr->exceptlist;
255 <      clear_ban_cache(chptr);
255 >      clear_ban_cache_channel(chptr);
256        break;
257      case CHFL_INVEX:
258        list = &chptr->invexlist;
# Line 264 | Line 262 | del_id(struct Channel *chptr, char *bani
262        return 0;
263    }
264  
265 <  DLINK_FOREACH(ban, list->head)
265 >  DLINK_FOREACH(node, list->head)
266    {
267 <    banptr = ban->data;
267 >    struct Ban *ban = node->data;
268  
269 <    if (!irccmp(name, banptr->name) &&
270 <        !irccmp(user, banptr->user) &&
271 <        !irccmp(host, banptr->host))
269 >    if (!irccmp(name, ban->name) &&
270 >        !irccmp(user, ban->user) &&
271 >        !irccmp(host, ban->host))
272      {
273 <      remove_ban(banptr, list);
273 >      remove_ban(ban, list);
274        return 1;
275      }
276    }
# Line 291 | Line 289 | del_id(struct Channel *chptr, char *bani
289   * chptr onto buffer mbuf with the parameters in pbuf.
290   */
291   void
292 < channel_modes(struct Channel *chptr, struct Client *client_p,
295 <              char *mbuf, char *pbuf)
292 > channel_modes(struct Channel *chptr, struct Client *client_p, char *mbuf, char *pbuf)
293   {
297  const struct mode_letter *tab = chan_modes;
298
294    *mbuf++ = '+';
295    *pbuf = '\0';
296  
297 <  for (; tab->mode; ++tab)
297 >  for (const struct mode_letter *tab = chan_modes; tab->mode; ++tab)
298      if (chptr->mode.mode & tab->mode)
299        *mbuf++ = tab->letter;
300  
# Line 347 | Line 342 | fix_key(char *arg)
342    return arg;
343   }
344  
350 /* fix_key_old()
351 *
352 * inputs       - pointer to key to clean up
353 * output       - pointer to cleaned up key
354 * side effects - input string is modifed
355 *
356 * Here we attempt to be compatible with older non-hybrid servers.
357 * We can't back down from the ':' issue however.  --Rodder
358 */
359 static char *
360 fix_key_old(char *arg)
361 {
362  unsigned char *s, *t, c;
363
364  for (s = t = (unsigned char *)arg; (c = *s); ++s)
365  {
366    c &= 0x7f;
367
368    if ((c != 0x0a) && (c != ':') &&
369        (c != 0x0d) && (c != ','))
370      *t++ = c;
371  }
372
373  *t = '\0';
374  return arg;
375 }
376
345   /*
346   * inputs       - pointer to channel
347   * output       - none
348   * side effects - clear ban cache
349   */
350   void
351 < clear_ban_cache(struct Channel *chptr)
351 > clear_ban_cache_channel(struct Channel *chptr)
352   {
353 <  dlink_node *ptr = NULL;
353 >  dlink_node *node = NULL;
354  
355 <  DLINK_FOREACH(ptr, chptr->members.head)
355 >  DLINK_FOREACH(node, chptr->locmembers.head)
356    {
357 <    struct Membership *ms = ptr->data;
358 <
391 <    if (MyConnect(ms->client_p))
392 <      ms->flags &= ~(CHFL_BAN_SILENCED|CHFL_BAN_CHECKED);
357 >    struct Membership *member = node->data;
358 >    member->flags &= ~(CHFL_BAN_SILENCED | CHFL_BAN_CHECKED);
359    }
360   }
361  
362   void
363   clear_ban_cache_client(struct Client *client_p)
364   {
365 <  dlink_node *ptr = NULL;
365 >  dlink_node *node = NULL;
366  
367 <  DLINK_FOREACH(ptr, client_p->channel.head)
367 >  DLINK_FOREACH(node, client_p->channel.head)
368    {
369 <    struct Membership *ms = ptr->data;
370 <    ms->flags &= ~(CHFL_BAN_SILENCED|CHFL_BAN_CHECKED);
369 >    struct Membership *member = node->data;
370 >    member->flags &= ~(CHFL_BAN_SILENCED | CHFL_BAN_CHECKED);
371    }
372   }
373  
374 < /* bitmasks for various error returns that set_channel_mode should only return
374 > /*
375 > * Bitmasks for various error returns that set_channel_mode should only return
376   * once per call  -orabidoo
377   */
378 <
379 < #define SM_ERR_NOTS         0x00000001 /* No TS on channel  */
380 < #define SM_ERR_NOOPS        0x00000002 /* No chan ops       */
381 < #define SM_ERR_UNKNOWN      0x00000004
382 < #define SM_ERR_RPL_B        0x00000008
383 < #define SM_ERR_RPL_E        0x00000010
384 < #define SM_ERR_NOTONCHANNEL 0x00000020 /* Not on channel    */
385 < #define SM_ERR_RPL_I        0x00000040
386 < #define SM_ERR_NOTOPER      0x00000080
387 < #define SM_ERR_ONLYSERVER   0x00000100
378 > enum
379 > {
380 >  SM_ERR_NOOPS        = 1 << 0,  /* No chan ops */
381 >  SM_ERR_UNKNOWN      = 1 << 1,
382 >  SM_ERR_RPL_B        = 1 << 2,
383 >  SM_ERR_RPL_E        = 1 << 3,
384 >  SM_ERR_RPL_I        = 1 << 4,
385 >  SM_ERR_NOTONCHANNEL = 1 << 5,  /* Client is not on channel */
386 >  SM_ERR_NOTOPER      = 1 << 6,
387 >  SM_ERR_ONLYSERVER   = 1 << 7
388 > };
389  
390   /* Mode functions handle mode changes for a particular mode... */
391   static void
392 < chm_nosuch(struct Client *source_p,
425 <           struct Channel *chptr, int parc, int *parn,
392 > chm_nosuch(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
393             char **parv, int *errors, int alev, int dir, char c, unsigned int d)
394   {
395    if (*errors & SM_ERR_UNKNOWN)
# Line 433 | Line 400 | chm_nosuch(struct Client *source_p,
400   }
401  
402   static void
403 < chm_simple(struct Client *source_p, struct Channel *chptr,
404 <           int parc, int *parn, char **parv, int *errors, int alev, int dir,
438 <           char c, unsigned int d)
403 > chm_simple(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
404 >           char **parv, int *errors, int alev, int dir, char c, unsigned int d)
405   {
406 <  if ((alev < CHACCESS_HALFOP) ||
441 <      ((d == MODE_PRIVATE) && (alev < CHACCESS_CHANOP)))
406 >  if (alev < CHACCESS_HALFOP)
407    {
408      if (!(*errors & SM_ERR_NOOPS))
409        sendto_one_numeric(source_p, &me,
410                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
411 <                         ERR_CHANOPRIVSNEEDED, chptr->chname);
411 >                         ERR_CHANOPRIVSNEEDED, chptr->name);
412 >
413      *errors |= SM_ERR_NOOPS;
414      return;
415    }
# Line 467 | Line 433 | chm_simple(struct Client *source_p, stru
433      chptr->mode.mode |= d;
434  
435      mode_changes[mode_count].letter = c;
436 <    mode_changes[mode_count].dir = MODE_ADD;
436 >    mode_changes[mode_count].arg = NULL;
437      mode_changes[mode_count].id = NULL;
438 <    mode_changes[mode_count].mems = ALL_MEMBERS;
473 <    mode_changes[mode_count++].arg = NULL;
438 >    mode_changes[mode_count++].dir = dir;
439    }
440    else if (dir == MODE_DEL) /* && (chptr->mode.mode & d)) */
441    {
# Line 479 | Line 444 | chm_simple(struct Client *source_p, stru
444      chptr->mode.mode &= ~d;
445  
446      mode_changes[mode_count].letter = c;
447 <    mode_changes[mode_count].dir = MODE_DEL;
483 <    mode_changes[mode_count].mems = ALL_MEMBERS;
447 >    mode_changes[mode_count].arg = NULL;
448      mode_changes[mode_count].id = NULL;
449 <    mode_changes[mode_count++].arg = NULL;
449 >    mode_changes[mode_count++].dir = dir;
450    }
451   }
452  
453   static void
454 < chm_registered(struct Client *source_p, struct Channel *chptr,
455 <               int parc, int *parn, char **parv, int *errors, int alev, int dir,
492 <               char c, unsigned int d)
454 > chm_registered(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
455 >               char **parv, int *errors, int alev, int dir, char c, unsigned int d)
456   {
457    if (!IsServer(source_p) && !HasFlag(source_p, FLAGS_SERVICE))
458    {
459      if (!(*errors & SM_ERR_ONLYSERVER))
460        sendto_one_numeric(source_p, &me,
461                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
462 <                         ERR_ONLYSERVERSCANCHANGE, chptr->chname);
462 >                         ERR_ONLYSERVERSCANCHANGE, chptr->name);
463 >
464      *errors |= SM_ERR_ONLYSERVER;
465      return;
466    }
# Line 520 | Line 484 | chm_registered(struct Client *source_p,
484      chptr->mode.mode |= d;
485  
486      mode_changes[mode_count].letter = c;
487 <    mode_changes[mode_count].dir = MODE_ADD;
487 >    mode_changes[mode_count].arg = NULL;
488      mode_changes[mode_count].id = NULL;
489 <    mode_changes[mode_count].mems = ALL_MEMBERS;
526 <    mode_changes[mode_count++].arg = NULL;
489 >    mode_changes[mode_count++].dir = dir;
490    }
491    else if (dir == MODE_DEL) /* && (chptr->mode.mode & d)) */
492    {
# Line 532 | Line 495 | chm_registered(struct Client *source_p,
495      chptr->mode.mode &= ~d;
496  
497      mode_changes[mode_count].letter = c;
498 <    mode_changes[mode_count].dir = MODE_DEL;
536 <    mode_changes[mode_count].mems = ALL_MEMBERS;
498 >    mode_changes[mode_count].arg = NULL;
499      mode_changes[mode_count].id = NULL;
500 <    mode_changes[mode_count++].arg = NULL;
500 >    mode_changes[mode_count++].dir = dir;
501    }
502   }
503  
504   static void
505 < chm_operonly(struct Client *source_p, struct Channel *chptr,
506 <             int parc, int *parn, char **parv, int *errors, int alev, int dir,
545 <             char c, unsigned int d)
505 > chm_operonly(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
506 >             char **parv, int *errors, int alev, int dir, char c, unsigned int d)
507   {
508 <  if ((alev < CHACCESS_HALFOP) ||
548 <      ((d == MODE_PRIVATE) && (alev < CHACCESS_CHANOP)))
508 >  if (alev < CHACCESS_HALFOP)
509    {
510      if (!(*errors & SM_ERR_NOOPS))
511        sendto_one_numeric(source_p, &me,
512                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
513 <                         ERR_CHANOPRIVSNEEDED, chptr->chname);
513 >                         ERR_CHANOPRIVSNEEDED, chptr->name);
514 >
515      *errors |= SM_ERR_NOOPS;
516      return;
517    }
518 <  else if (MyClient(source_p) && !HasUMode(source_p, UMODE_OPER))
518 >
519 >  if (MyClient(source_p) && !HasUMode(source_p, UMODE_OPER))
520    {
521      if (!(*errors & SM_ERR_NOTOPER))
522 <    {
561 <      if (alev == CHACCESS_NOTONCHAN)
562 <        sendto_one_numeric(source_p, &me, ERR_NOTONCHANNEL, chptr->chname);
563 <      else
564 <        sendto_one_numeric(source_p, &me, ERR_NOPRIVILEGES);
565 <    }
522 >      sendto_one_numeric(source_p, &me, ERR_NOPRIVILEGES);
523  
524      *errors |= SM_ERR_NOTOPER;
525      return;
# Line 579 | Line 536 | chm_operonly(struct Client *source_p, st
536      chptr->mode.mode |= d;
537  
538      mode_changes[mode_count].letter = c;
539 <    mode_changes[mode_count].dir = MODE_ADD;
539 >    mode_changes[mode_count].arg = NULL;
540      mode_changes[mode_count].id = NULL;
541 <    mode_changes[mode_count].mems = ALL_MEMBERS;
585 <    mode_changes[mode_count].mems = ALL_MEMBERS;
586 <    mode_changes[mode_count++].arg = NULL;
541 >    mode_changes[mode_count++].dir = dir;
542    }
543    else if (dir == MODE_DEL) /* && (chptr->mode.mode & d)) */
544    {
# Line 592 | Line 547 | chm_operonly(struct Client *source_p, st
547      chptr->mode.mode &= ~d;
548  
549      mode_changes[mode_count].letter = c;
550 <    mode_changes[mode_count].dir = MODE_DEL;
596 <    mode_changes[mode_count].mems = ALL_MEMBERS;
550 >    mode_changes[mode_count].arg = NULL;
551      mode_changes[mode_count].id = NULL;
552 <    mode_changes[mode_count++].arg = NULL;
552 >    mode_changes[mode_count++].dir = dir;
553    }
554   }
555  
556   static void
557 < chm_ban(struct Client *source_p,
604 <        struct Channel *chptr, int parc, int *parn,
557 > chm_ban(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
558          char **parv, int *errors, int alev, int dir, char c, unsigned int d)
559   {
560    char *mask = NULL;
561  
562    if (dir == MODE_QUERY || parc <= *parn)
563    {
564 <    dlink_node *ptr = NULL;
564 >    dlink_node *node = NULL;
565  
566      if (*errors & SM_ERR_RPL_B)
567        return;
568  
569      *errors |= SM_ERR_RPL_B;
570  
571 <    DLINK_FOREACH(ptr, chptr->banlist.head)
571 >    DLINK_FOREACH(node, chptr->banlist.head)
572      {
573 <      const struct Ban *banptr = ptr->data;
574 <      sendto_one_numeric(source_p, &me, RPL_BANLIST, chptr->chname,
575 <                         banptr->name, banptr->user, banptr->host,
576 <                         banptr->who, banptr->when);
573 >      const struct Ban *ban = node->data;
574 >      sendto_one_numeric(source_p, &me, RPL_BANLIST, chptr->name,
575 >                         ban->name, ban->user, ban->host,
576 >                         ban->who, ban->when);
577      }
578  
579 <    sendto_one_numeric(source_p, &me, RPL_ENDOFBANLIST, chptr->chname);
579 >    sendto_one_numeric(source_p, &me, RPL_ENDOFBANLIST, chptr->name);
580      return;
581    }
582  
# Line 632 | Line 585 | chm_ban(struct Client *source_p,
585      if (!(*errors & SM_ERR_NOOPS))
586        sendto_one_numeric(source_p, &me,
587                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
588 <                         ERR_CHANOPRIVSNEEDED, chptr->chname);
588 >                         ERR_CHANOPRIVSNEEDED, chptr->name);
589 >
590      *errors |= SM_ERR_NOOPS;
591      return;
592    }
# Line 641 | Line 595 | chm_ban(struct Client *source_p,
595      return;
596  
597    mask = nuh_mask[*parn];
598 <  memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
599 <  ++*parn;
598 >  strlcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
599 >  ++(*parn);
600  
601 <  if (!MyConnect(source_p))
602 <    if (strchr(mask, ' '))
649 <      return;
601 >  if (*mask == ':' || (!MyConnect(source_p) && strchr(mask, ' ')))
602 >    return;
603  
604    switch (dir)
605    {
# Line 663 | Line 616 | chm_ban(struct Client *source_p,
616    }
617  
618    mode_changes[mode_count].letter = c;
619 <  mode_changes[mode_count].dir = dir;
667 <  mode_changes[mode_count].mems = ALL_MEMBERS;
619 >  mode_changes[mode_count].arg = mask;
620    mode_changes[mode_count].id = NULL;
621 <  mode_changes[mode_count++].arg = mask;
621 >  mode_changes[mode_count++].dir = dir;
622   }
623  
624   static void
625 < chm_except(struct Client *source_p,
674 <           struct Channel *chptr, int parc, int *parn,
625 > chm_except(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
626             char **parv, int *errors, int alev, int dir, char c, unsigned int d)
627   {
628    char *mask = NULL;
629  
679  if (alev < CHACCESS_HALFOP)
680  {
681    if (!(*errors & SM_ERR_NOOPS))
682      sendto_one_numeric(source_p, &me,
683                         alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
684                         ERR_CHANOPRIVSNEEDED, chptr->chname);
685    *errors |= SM_ERR_NOOPS;
686    return;
687  }
688
630    if (dir == MODE_QUERY || parc <= *parn)
631    {
632 <    dlink_node *ptr = NULL;
632 >    dlink_node *node = NULL;
633  
634      if (*errors & SM_ERR_RPL_E)
635        return;
636  
637      *errors |= SM_ERR_RPL_E;
638  
639 <    DLINK_FOREACH(ptr, chptr->exceptlist.head)
639 >    DLINK_FOREACH(node, chptr->exceptlist.head)
640      {
641 <      const struct Ban *banptr = ptr->data;
641 >      const struct Ban *ban = node->data;
642  
643 <      sendto_one_numeric(source_p, &me, RPL_EXCEPTLIST, chptr->chname,
644 <                         banptr->name, banptr->user, banptr->host,
645 <                         banptr->who, banptr->when);
643 >      sendto_one_numeric(source_p, &me, RPL_EXCEPTLIST, chptr->name,
644 >                         ban->name, ban->user, ban->host,
645 >                         ban->who, ban->when);
646      }
647  
648 <    sendto_one_numeric(source_p, &me, RPL_ENDOFEXCEPTLIST, chptr->chname);
648 >    sendto_one_numeric(source_p, &me, RPL_ENDOFEXCEPTLIST, chptr->name);
649 >    return;
650 >  }
651 >
652 >  if (alev < CHACCESS_HALFOP)
653 >  {
654 >    if (!(*errors & SM_ERR_NOOPS))
655 >      sendto_one_numeric(source_p, &me,
656 >                         alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
657 >                         ERR_CHANOPRIVSNEEDED, chptr->name);
658 >
659 >    *errors |= SM_ERR_NOOPS;
660      return;
661    }
662  
# Line 712 | Line 664 | chm_except(struct Client *source_p,
664      return;
665  
666    mask = nuh_mask[*parn];
667 <  memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
668 <  ++*parn;
667 >  strlcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
668 >  ++(*parn);
669  
670 <  if (!MyConnect(source_p))
671 <    if (strchr(mask, ' '))
720 <      return;
670 >  if (*mask == ':' || (!MyConnect(source_p) && strchr(mask, ' ')))
671 >    return;
672  
673    switch (dir)
674    {
# Line 734 | Line 685 | chm_except(struct Client *source_p,
685    }
686  
687    mode_changes[mode_count].letter = c;
688 <  mode_changes[mode_count].dir = dir;
738 <  mode_changes[mode_count].mems = ONLY_CHANOPS;
688 >  mode_changes[mode_count].arg = mask;
689    mode_changes[mode_count].id = NULL;
690 <  mode_changes[mode_count++].arg = mask;
690 >  mode_changes[mode_count++].dir = dir;
691   }
692  
693   static void
694 < chm_invex(struct Client *source_p,
745 <          struct Channel *chptr, int parc, int *parn,
694 > chm_invex(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
695            char **parv, int *errors, int alev, int dir, char c, unsigned int d)
696   {
697    char *mask = NULL;
698  
750  if (alev < CHACCESS_HALFOP)
751  {
752    if (!(*errors & SM_ERR_NOOPS))
753      sendto_one_numeric(source_p, &me,
754                         alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
755                         ERR_CHANOPRIVSNEEDED, chptr->chname);
756    *errors |= SM_ERR_NOOPS;
757    return;
758  }
759
699    if (dir == MODE_QUERY || parc <= *parn)
700    {
701 <    dlink_node *ptr = NULL;
701 >    dlink_node *node = NULL;
702  
703      if (*errors & SM_ERR_RPL_I)
704        return;
705  
706      *errors |= SM_ERR_RPL_I;
707  
708 <    DLINK_FOREACH(ptr, chptr->invexlist.head)
708 >    DLINK_FOREACH(node, chptr->invexlist.head)
709      {
710 <      const struct Ban *banptr = ptr->data;
710 >      const struct Ban *ban = node->data;
711  
712 <      sendto_one_numeric(source_p, &me, RPL_INVITELIST, chptr->chname,
713 <                         banptr->name, banptr->user, banptr->host,
714 <                         banptr->who, banptr->when);
712 >      sendto_one_numeric(source_p, &me, RPL_INVEXLIST, chptr->name,
713 >                         ban->name, ban->user, ban->host,
714 >                         ban->who, ban->when);
715      }
716  
717 <    sendto_one_numeric(source_p, &me, RPL_ENDOFINVITELIST, chptr->chname);
717 >    sendto_one_numeric(source_p, &me, RPL_ENDOFINVEXLIST, chptr->name);
718 >    return;
719 >  }
720 >
721 >  if (alev < CHACCESS_HALFOP)
722 >  {
723 >    if (!(*errors & SM_ERR_NOOPS))
724 >      sendto_one_numeric(source_p, &me,
725 >                         alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
726 >                         ERR_CHANOPRIVSNEEDED, chptr->name);
727 >
728 >    *errors |= SM_ERR_NOOPS;
729      return;
730    }
731  
# Line 783 | Line 733 | chm_invex(struct Client *source_p,
733      return;
734  
735    mask = nuh_mask[*parn];
736 <  memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
737 <  ++*parn;
736 >  strlcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
737 >  ++(*parn);
738  
739 <  if (!MyConnect(source_p))
740 <    if (strchr(mask, ' '))
791 <      return;
739 >  if (*mask == ':' || (!MyConnect(source_p) && strchr(mask, ' ')))
740 >    return;
741  
742    switch (dir)
743    {
# Line 805 | Line 754 | chm_invex(struct Client *source_p,
754    }
755  
756    mode_changes[mode_count].letter = c;
757 <  mode_changes[mode_count].dir = dir;
809 <  mode_changes[mode_count].mems = ONLY_CHANOPS;
757 >  mode_changes[mode_count].arg = mask;
758    mode_changes[mode_count].id = NULL;
759 <  mode_changes[mode_count++].arg = mask;
759 >  mode_changes[mode_count++].dir = dir;
760   }
761  
762   static void
763 < chm_voice(struct Client *source_p,
816 <          struct Channel *chptr, int parc, int *parn,
763 > chm_voice(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
764            char **parv, int *errors, int alev, int dir, char c, unsigned int d)
765   {
819  const char *opnick = NULL;
766    struct Client *target_p;
767    struct Membership *member;
768  
# Line 825 | Line 771 | chm_voice(struct Client *source_p,
771      if (!(*errors & SM_ERR_NOOPS))
772        sendto_one_numeric(source_p, &me,
773                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
774 <                         ERR_CHANOPRIVSNEEDED, chptr->chname);
774 >                         ERR_CHANOPRIVSNEEDED, chptr->name);
775 >
776      *errors |= SM_ERR_NOOPS;
777      return;
778    }
779  
780 <  if ((dir == MODE_QUERY) || parc <= *parn)
780 >  if (dir == MODE_QUERY || parc <= *parn)
781      return;
782  
783 <  opnick = parv[(*parn)++];
784 <
838 <  if ((target_p = find_chasing(source_p, opnick, NULL)) == NULL)
839 <    return;
840 <  if (!IsClient(target_p))
841 <    return;
783 >  if ((target_p = find_chasing(source_p, parv[(*parn)++])) == NULL)
784 >    return;  /* find_chasing sends ERR_NOSUCHNICK */
785  
786    if ((member = find_channel_link(target_p, chptr)) == NULL)
787    {
788      if (!(*errors & SM_ERR_NOTONCHANNEL))
789 <      sendto_one_numeric(source_p, &me, ERR_USERNOTINCHANNEL, opnick, chptr->chname);
789 >      sendto_one_numeric(source_p, &me, ERR_USERNOTINCHANNEL, target_p->name, chptr->name);
790 >
791      *errors |= SM_ERR_NOTONCHANNEL;
792      return;
793    }
# Line 854 | Line 798 | chm_voice(struct Client *source_p,
798    /* no redundant mode changes */
799    if (dir == MODE_ADD &&  has_member_flags(member, CHFL_VOICE))
800      return;
801 +
802    if (dir == MODE_DEL && !has_member_flags(member, CHFL_VOICE))
803      return;
804  
805 <  mode_changes[mode_count].letter = 'v';
861 <  mode_changes[mode_count].dir = dir;
862 <  mode_changes[mode_count].mems = ALL_MEMBERS;
863 <  mode_changes[mode_count].id = target_p->id;
805 >  mode_changes[mode_count].letter = c;
806    mode_changes[mode_count].arg = target_p->name;
807 <  mode_changes[mode_count++].client = target_p;
807 >  mode_changes[mode_count].id = target_p->id;
808 >  mode_changes[mode_count++].dir = dir;
809  
810    if (dir == MODE_ADD)
811      AddMemberFlag(member, CHFL_VOICE);
# Line 870 | Line 813 | chm_voice(struct Client *source_p,
813      DelMemberFlag(member, CHFL_VOICE);
814   }
815  
873 #ifdef HALFOPS
816   static void
817 < chm_hop(struct Client *source_p,
876 <        struct Channel *chptr, int parc, int *parn,
817 > chm_hop(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
818          char **parv, int *errors, int alev, int dir, char c, unsigned int d)
819   {
879  const char *opnick = NULL;
820    struct Client *target_p;
821    struct Membership *member;
822  
823 <  /* *sigh* - dont allow halfops to set +/-h, they could fully control a
884 <   * channel if there were no ops - it doesnt solve anything.. MODE_PRIVATE
885 <   * when used with MODE_SECRET is paranoid - cant use +p
886 <   *
887 <   * it needs to be optional per channel - but not via +p, that or remove
888 <   * paranoid.. -- fl_
889 <   *
890 <   * +p means paranoid, it is useless for anything else on modern IRC, as
891 <   * list isn't really usable. If you want to have a private channel these
892 <   * days, you set it +s. Halfops can no longer remove simple modes when
893 <   * +p is set (although they can set +p) so it is safe to use this to
894 <   * control whether they can (de)halfop...
895 <   */
896 <  if (alev <
897 <      ((chptr->mode.mode & MODE_PRIVATE) ? CHACCESS_CHANOP : CHACCESS_HALFOP))
823 >  if (alev < CHACCESS_CHANOP)
824    {
825      if (!(*errors & SM_ERR_NOOPS))
826        sendto_one_numeric(source_p, &me,
827                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
828 <                         ERR_CHANOPRIVSNEEDED, chptr->chname);
828 >                         ERR_CHANOPRIVSNEEDED, chptr->name);
829 >
830      *errors |= SM_ERR_NOOPS;
831      return;
832    }
833  
834 <  if ((dir == MODE_QUERY) || (parc <= *parn))
834 >  if (dir == MODE_QUERY || parc <= *parn)
835      return;
836  
837 <  opnick = parv[(*parn)++];
838 <
912 <  if ((target_p = find_chasing(source_p, opnick, NULL)) == NULL)
913 <    return;
914 <  if (!IsClient(target_p))
915 <    return;
837 >  if ((target_p = find_chasing(source_p, parv[(*parn)++])) == NULL)
838 >    return;  /* find_chasing sends ERR_NOSUCHNICK */
839  
840    if ((member = find_channel_link(target_p, chptr)) == NULL)
841    {
842      if (!(*errors & SM_ERR_NOTONCHANNEL))
843 <      sendto_one_numeric(source_p, &me, ERR_USERNOTINCHANNEL, opnick, chptr->chname);
843 >      sendto_one_numeric(source_p, &me, ERR_USERNOTINCHANNEL, target_p->name, chptr->name);
844 >
845      *errors |= SM_ERR_NOTONCHANNEL;
846      return;
847    }
# Line 928 | Line 852 | chm_hop(struct Client *source_p,
852    /* no redundant mode changes */
853    if (dir == MODE_ADD &&  has_member_flags(member, CHFL_HALFOP))
854      return;
855 +
856    if (dir == MODE_DEL && !has_member_flags(member, CHFL_HALFOP))
857      return;
858  
859 <  mode_changes[mode_count].letter = 'h';
935 <  mode_changes[mode_count].dir = dir;
936 <  mode_changes[mode_count].mems = ALL_MEMBERS;
937 <  mode_changes[mode_count].id = target_p->id;
859 >  mode_changes[mode_count].letter = c;
860    mode_changes[mode_count].arg = target_p->name;
861 <  mode_changes[mode_count++].client = target_p;
861 >  mode_changes[mode_count].id = target_p->id;
862 >  mode_changes[mode_count++].dir = dir;
863  
864    if (dir == MODE_ADD)
942  {
865      AddMemberFlag(member, CHFL_HALFOP);
944    DelMemberFlag(member, CHFL_DEOPPED);
945  }
866    else
867      DelMemberFlag(member, CHFL_HALFOP);
868   }
949 #endif
869  
870   static void
871 < chm_op(struct Client *source_p,
953 <       struct Channel *chptr, int parc, int *parn,
871 > chm_op(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
872         char **parv, int *errors, int alev, int dir, char c, unsigned int d)
873   {
956  const char *opnick = NULL;
874    struct Client *target_p;
875    struct Membership *member;
876  
# Line 962 | Line 879 | chm_op(struct Client *source_p,
879      if (!(*errors & SM_ERR_NOOPS))
880        sendto_one_numeric(source_p, &me,
881                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
882 <                         ERR_CHANOPRIVSNEEDED, chptr->chname);
882 >                         ERR_CHANOPRIVSNEEDED, chptr->name);
883 >
884      *errors |= SM_ERR_NOOPS;
885      return;
886    }
887  
888 <  if ((dir == MODE_QUERY) || (parc <= *parn))
888 >  if (dir == MODE_QUERY || parc <= *parn)
889      return;
890  
891 <  opnick = parv[(*parn)++];
892 <
975 <  if ((target_p = find_chasing(source_p, opnick, NULL)) == NULL)
976 <    return;
977 <  if (!IsClient(target_p))
978 <    return;
891 >  if ((target_p = find_chasing(source_p, parv[(*parn)++])) == NULL)
892 >    return;  /* find_chasing sends ERR_NOSUCHNICK */
893  
894    if ((member = find_channel_link(target_p, chptr)) == NULL)
895    {
896      if (!(*errors & SM_ERR_NOTONCHANNEL))
897 <      sendto_one_numeric(source_p, &me, ERR_USERNOTINCHANNEL, opnick, chptr->chname);
897 >      sendto_one_numeric(source_p, &me, ERR_USERNOTINCHANNEL, target_p->name, chptr->name);
898 >
899      *errors |= SM_ERR_NOTONCHANNEL;
900      return;
901    }
# Line 991 | Line 906 | chm_op(struct Client *source_p,
906    /* no redundant mode changes */
907    if (dir == MODE_ADD &&  has_member_flags(member, CHFL_CHANOP))
908      return;
909 +
910    if (dir == MODE_DEL && !has_member_flags(member, CHFL_CHANOP))
911      return;
912  
913 <  mode_changes[mode_count].letter = 'o';
998 <  mode_changes[mode_count].dir = dir;
999 <  mode_changes[mode_count].mems = ALL_MEMBERS;
1000 <  mode_changes[mode_count].id = target_p->id;
913 >  mode_changes[mode_count].letter = c;
914    mode_changes[mode_count].arg = target_p->name;
915 <  mode_changes[mode_count++].client = target_p;
915 >  mode_changes[mode_count].id = target_p->id;
916 >  mode_changes[mode_count++].dir = dir;
917  
918    if (dir == MODE_ADD)
1005  {
919      AddMemberFlag(member, CHFL_CHANOP);
1007    DelMemberFlag(member, CHFL_DEOPPED);
1008  }
920    else
921      DelMemberFlag(member, CHFL_CHANOP);
922   }
923  
924   static void
925 < chm_limit(struct Client *source_p,
1015 <          struct Channel *chptr, int parc, int *parn,
925 > chm_limit(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
926            char **parv, int *errors, int alev, int dir, char c, unsigned int d)
927   {
1018  unsigned int i = 0;
928    int limit = 0;
929  
930    if (alev < CHACCESS_HALFOP)
# Line 1023 | Line 932 | chm_limit(struct Client *source_p,
932      if (!(*errors & SM_ERR_NOOPS))
933        sendto_one_numeric(source_p, &me,
934                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
935 <                         ERR_CHANOPRIVSNEEDED, chptr->chname);
935 >                         ERR_CHANOPRIVSNEEDED, chptr->name);
936      *errors |= SM_ERR_NOOPS;
937      return;
938    }
# Line 1031 | Line 940 | chm_limit(struct Client *source_p,
940    if (dir == MODE_QUERY)
941      return;
942  
943 <  if ((dir == MODE_ADD) && parc > *parn)
943 >  if (dir == MODE_ADD && parc > *parn)
944    {
945 <    char *lstr = parv[(*parn)++];
945 >    char *const lstr = parv[(*parn)++];
946  
947      if (EmptyString(lstr) || (limit = atoi(lstr)) <= 0)
948        return;
# Line 1041 | Line 950 | chm_limit(struct Client *source_p,
950      sprintf(lstr, "%d", limit);
951  
952      /* If somebody sets MODE #channel +ll 1 2, accept latter --fl */
953 <    for (i = 0; i < mode_count; ++i)
953 >    for (unsigned int i = 0; i < mode_count; ++i)
954        if (mode_changes[i].letter == c && mode_changes[i].dir == MODE_ADD)
955          mode_changes[i].letter = 0;
956  
957      mode_changes[mode_count].letter = c;
958 <    mode_changes[mode_count].dir = MODE_ADD;
1050 <    mode_changes[mode_count].mems = ALL_MEMBERS;
958 >    mode_changes[mode_count].arg = lstr;
959      mode_changes[mode_count].id = NULL;
960 <    mode_changes[mode_count++].arg = lstr;
960 >    mode_changes[mode_count++].dir = dir;
961  
962      chptr->mode.limit = limit;
963    }
# Line 1061 | Line 969 | chm_limit(struct Client *source_p,
969      chptr->mode.limit = 0;
970  
971      mode_changes[mode_count].letter = c;
972 <    mode_changes[mode_count].dir = MODE_DEL;
1065 <    mode_changes[mode_count].mems = ALL_MEMBERS;
972 >    mode_changes[mode_count].arg = NULL;
973      mode_changes[mode_count].id = NULL;
974 <    mode_changes[mode_count++].arg = NULL;
974 >    mode_changes[mode_count++].dir = dir;
975    }
976   }
977  
978   static void
979 < chm_key(struct Client *source_p,
1073 <        struct Channel *chptr, int parc, int *parn,
979 > chm_key(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
980          char **parv, int *errors, int alev, int dir, char c, unsigned int d)
981   {
1076  unsigned int i = 0;
1077
982    if (alev < CHACCESS_HALFOP)
983    {
984      if (!(*errors & SM_ERR_NOOPS))
985        sendto_one_numeric(source_p, &me,
986                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
987 <                         ERR_CHANOPRIVSNEEDED, chptr->chname);
987 >                         ERR_CHANOPRIVSNEEDED, chptr->name);
988      *errors |= SM_ERR_NOOPS;
989      return;
990    }
# Line 1088 | Line 992 | chm_key(struct Client *source_p,
992    if (dir == MODE_QUERY)
993      return;
994  
995 <  if ((dir == MODE_ADD) && parc > *parn)
995 >  if (dir == MODE_ADD && parc > *parn)
996    {
997 <    char *key = parv[(*parn)++];
1094 <
1095 <    if (MyClient(source_p))
1096 <      fix_key(key);
1097 <    else
1098 <      fix_key_old(key);
997 >    char *const key = fix_key(parv[(*parn)++]);
998  
999      if (EmptyString(key))
1000        return;
# Line 1104 | Line 1003 | chm_key(struct Client *source_p,
1003      strlcpy(chptr->mode.key, key, sizeof(chptr->mode.key));
1004  
1005      /* If somebody does MODE #channel +kk a b, accept latter --fl */
1006 <    for (i = 0; i < mode_count; ++i)
1006 >    for (unsigned int i = 0; i < mode_count; ++i)
1007        if (mode_changes[i].letter == c && mode_changes[i].dir == MODE_ADD)
1008          mode_changes[i].letter = 0;
1009  
1010      mode_changes[mode_count].letter = c;
1011 <    mode_changes[mode_count].dir = MODE_ADD;
1113 <    mode_changes[mode_count].mems = ALL_MEMBERS;
1011 >    mode_changes[mode_count].arg = chptr->mode.key;
1012      mode_changes[mode_count].id = NULL;
1013 <    mode_changes[mode_count++].arg = chptr->mode.key;
1013 >    mode_changes[mode_count++].dir = dir;
1014    }
1015    else if (dir == MODE_DEL)
1016    {
1017      if (parc > *parn)
1018 <      (*parn)++;
1018 >      ++(*parn);
1019  
1020      if (chptr->mode.key[0] == '\0')
1021        return;
# Line 1125 | Line 1023 | chm_key(struct Client *source_p,
1023      chptr->mode.key[0] = '\0';
1024  
1025      mode_changes[mode_count].letter = c;
1026 <    mode_changes[mode_count].dir = MODE_DEL;
1129 <    mode_changes[mode_count].mems = ALL_MEMBERS;
1026 >    mode_changes[mode_count].arg = "*";
1027      mode_changes[mode_count].id = NULL;
1028 <    mode_changes[mode_count++].arg = "*";
1028 >    mode_changes[mode_count++].dir = dir;
1029    }
1030   }
1031  
1032 < struct ChannelMode
1136 < {
1137 <  void (*func)(struct Client *,
1138 <               struct Channel *, int, int *, char **,
1139 <               int *, int, int, char, unsigned int);
1140 <  unsigned int d;
1141 < };
1142 <
1143 < static struct ChannelMode ModeTable[256] =
1032 > const struct ChannelMode ModeTable[256] =
1033   {
1034    { chm_nosuch,  0 },                   /* 0x00 */
1035    { chm_nosuch,  0 },                   /* 0x01 */
# Line 1209 | Line 1098 | static struct ChannelMode ModeTable[256]
1098    { chm_nosuch,  0 },                   /* @ */
1099    { chm_nosuch,  0 },                   /* A */
1100    { chm_nosuch,  0 },                   /* B */
1101 <  { chm_nosuch,  0 },                   /* C */
1101 >  { chm_simple,  MODE_NOCTCP },         /* C */
1102    { chm_nosuch,  0 },                   /* D */
1103    { chm_nosuch,  0 },                   /* E */
1104    { chm_nosuch,  0 },                   /* F */
# Line 1246 | Line 1135 | static struct ChannelMode ModeTable[256]
1135    { chm_except,  0 },                   /* e */
1136    { chm_nosuch,  0 },                   /* f */
1137    { chm_nosuch,  0 },                   /* g */
1249 #ifdef HALFOPS
1138    { chm_hop,     0 },                   /* h */
1251 #else
1252  { chm_nosuch,  0 },                   /* h */
1253 #endif
1139    { chm_simple,     MODE_INVITEONLY },  /* i */
1140    { chm_nosuch,     0               },  /* j */
1141    { chm_key,        0               },  /* k */
# Line 1418 | Line 1303 | get_channel_access(const struct Client *
1303   {
1304    /* Let hacked servers in for now... */
1305    if (!MyClient(source_p))
1306 <    return CHACCESS_CHANOP;
1306 >    return CHACCESS_REMOTE;
1307  
1308 <  if (member == NULL)
1308 >  if (!member)
1309      return CHACCESS_NOTONCHAN;
1310  
1311 <  /* just to be sure.. */
1311 >  /* Just to be sure.. */
1312    assert(source_p == member->client_p);
1313  
1314    if (has_member_flags(member, CHFL_CHANOP))
1315      return CHACCESS_CHANOP;
1316  
1432 #ifdef HALFOPS
1317    if (has_member_flags(member, CHFL_HALFOP))
1318      return CHACCESS_HALFOP;
1435 #endif
1319  
1320    return CHACCESS_PEON;
1321   }
1322  
1323   /* send_mode_changes_server()
1324 < * Input: The client sending(client_p), the source client(source_p),
1324 > * Input: the source client(source_p),
1325   *        the channel to send mode changes for(chptr)
1326   * Output: None.
1327   * Side-effects: Sends the appropriate mode changes to servers.
# Line 1447 | Line 1330 | get_channel_access(const struct Client *
1330   static void
1331   send_mode_changes_server(struct Client *source_p, struct Channel *chptr)
1332   {
1450  unsigned int i;
1333    int mbl = 0, pbl = 0, arglen = 0, nc = 0, mc = 0;
1334    int len = 0;
1453  const char *arg = NULL;
1454  char *parptr;
1335    int dir = MODE_QUERY;
1336 +  const char *arg = NULL;
1337 +  char *parptr = NULL;
1338  
1339    parabuf[0] = '\0';
1340    parptr = parabuf;
1341  
1342    mbl = snprintf(modebuf, sizeof(modebuf), ":%s TMODE %lu %s ", source_p->id,
1343 <                 (unsigned long)chptr->channelts, chptr->chname);
1343 >                 (unsigned long)chptr->creationtime, chptr->name);
1344  
1345 <  /* loop the list of modes we have */
1346 <  for (i = 0; i < mode_count; ++i)
1345 >  /* Loop the list of modes we have */
1346 >  for (unsigned int i = 0; i < mode_count; ++i)
1347    {
1348 <    if (mode_changes[i].letter == 0) /* XXX: can it ever happen? */
1348 >    if (mode_changes[i].letter == 0)
1349        continue;
1350  
1351      if (mode_changes[i].id)
# Line 1471 | Line 1353 | send_mode_changes_server(struct Client *
1353      else
1354        arg = mode_changes[i].arg;
1355  
1356 <    if (arg != NULL)
1356 >    if (arg)
1357        arglen = strlen(arg);
1358      else
1359        arglen = 0;
# Line 1484 | Line 1366 | send_mode_changes_server(struct Client *
1366          ((arglen + mbl + pbl + 2) > IRCD_BUFSIZE) ||
1367          (pbl + arglen + BAN_FUDGE) >= MODEBUFLEN)
1368      {
1369 <      if (nc != 0)
1370 <        sendto_server(source_p, NOCAPS, NOCAPS, "%s %s", modebuf, parabuf);
1369 >      if (nc)
1370 >        sendto_server(source_p, 0, 0, "%s %s", modebuf, parabuf);
1371 >
1372        nc = 0;
1373        mc = 0;
1374  
1375        mbl = snprintf(modebuf, sizeof(modebuf), ":%s TMODE %lu %s ", source_p->id,
1376 <                     (unsigned long)chptr->channelts, chptr->chname);
1376 >                     (unsigned long)chptr->creationtime, chptr->name);
1377  
1378        pbl = 0;
1379        parabuf[0] = '\0';
# Line 1506 | Line 1389 | send_mode_changes_server(struct Client *
1389  
1390      modebuf[mbl++] = mode_changes[i].letter;
1391      modebuf[mbl] = '\0';
1392 <    nc++;
1392 >    ++nc;
1393  
1394 <    if (arg != NULL)
1394 >    if (arg)
1395      {
1396        len = sprintf(parptr, "%s ", arg);
1397        pbl += len;
1398        parptr += len;
1399 <      mc++;
1399 >      ++mc;
1400      }
1401    }
1402  
1403    if (pbl && parabuf[pbl - 1] == ' ')
1404      parabuf[pbl - 1] = '\0';
1405  
1406 <  if (nc != 0)
1407 <    sendto_server(source_p, NOCAPS, NOCAPS, "%s %s", modebuf, parabuf);
1406 >  if (nc)
1407 >    sendto_server(source_p, 0, 0, "%s %s", modebuf, parabuf);
1408   }
1409  
1410   /* void send_mode_changes(struct Client *client_p,
# Line 1536 | Line 1419 | send_mode_changes_server(struct Client *
1419   */
1420   /* ensure parabuf < MODEBUFLEN -db */
1421   static void
1422 < send_mode_changes(struct Client *source_p, struct Channel *chptr)
1422 > send_mode_changes_client(struct Client *source_p, struct Channel *chptr)
1423   {
1541  unsigned int i;
1424    int mbl = 0, pbl = 0, arglen = 0, nc = 0, mc = 0;
1425    int len = 0;
1544  const char *arg = NULL;
1545  char *parptr;
1426    int dir = MODE_QUERY;
1427 <
1428 <  /* Bail out if we have nothing to do... */
1549 <  if (!mode_count)
1550 <    return;
1427 >  const char *arg = NULL;
1428 >  char *parptr = NULL;
1429  
1430    if (IsServer(source_p))
1431      mbl = snprintf(modebuf, sizeof(modebuf), ":%s MODE %s ", (IsHidden(source_p) ||
1432                     ConfigServerHide.hide_servers) ?
1433 <                   me.name : source_p->name, chptr->chname);
1433 >                   me.name : source_p->name, chptr->name);
1434    else
1435      mbl = snprintf(modebuf, sizeof(modebuf), ":%s!%s@%s MODE %s ", source_p->name,
1436 <                   source_p->username, source_p->host, chptr->chname);
1436 >                   source_p->username, source_p->host, chptr->name);
1437  
1438    parabuf[0] = '\0';
1439    parptr = parabuf;
1440  
1441 <  for (i = 0; i < mode_count; ++i)
1441 >  for (unsigned int i = 0; i < mode_count; ++i)
1442    {
1443 <    if (mode_changes[i].letter == 0 ||
1566 <        mode_changes[i].mems == NON_CHANOPS ||
1567 <        mode_changes[i].mems == ONLY_SERVERS)
1443 >    if (mode_changes[i].letter == 0)
1444        continue;
1445  
1446      arg = mode_changes[i].arg;
1447 <    if (arg != NULL)
1447 >    if (arg)
1448        arglen = strlen(arg);
1449      else
1450        arglen = 0;
1451  
1452 <    if ((mc == MAXMODEPARAMS)  ||
1452 >    if ((mc == MAXMODEPARAMS) ||
1453          ((arglen + mbl + pbl + 2) > IRCD_BUFSIZE) ||
1454          ((arglen + pbl + BAN_FUDGE) >= MODEBUFLEN))
1455      {
1456        if (mbl && modebuf[mbl - 1] == '-')
1457          modebuf[mbl - 1] = '\0';
1458  
1459 <      if (nc != 0)
1460 <        sendto_channel_local(ALL_MEMBERS, 0, chptr, "%s %s", modebuf, parabuf);
1459 >      if (nc)
1460 >        sendto_channel_local(0, chptr, "%s %s", modebuf, parabuf);
1461  
1462        nc = 0;
1463        mc = 0;
# Line 1589 | Line 1465 | send_mode_changes(struct Client *source_
1465        if (IsServer(source_p))
1466          mbl = snprintf(modebuf, sizeof(modebuf), ":%s MODE %s ", (IsHidden(source_p) ||
1467                         ConfigServerHide.hide_servers) ?
1468 <                       me.name : source_p->name, chptr->chname);
1468 >                       me.name : source_p->name, chptr->name);
1469        else
1470          mbl = snprintf(modebuf, sizeof(modebuf), ":%s!%s@%s MODE %s ", source_p->name,
1471 <                       source_p->username, source_p->host, chptr->chname);
1471 >                       source_p->username, source_p->host, chptr->name);
1472  
1473        pbl = 0;
1474        parabuf[0] = '\0';
# Line 1608 | Line 1484 | send_mode_changes(struct Client *source_
1484  
1485      modebuf[mbl++] = mode_changes[i].letter;
1486      modebuf[mbl] = '\0';
1487 <    nc++;
1487 >    ++nc;
1488  
1489 <    if (arg != NULL)
1489 >    if (arg)
1490      {
1491        len = sprintf(parptr, "%s ", arg);
1492        pbl += len;
1493        parptr += len;
1494 <      mc++;
1494 >      ++mc;
1495      }
1496    }
1497  
1498    if (pbl && parabuf[pbl - 1] == ' ')
1499      parabuf[pbl - 1] = '\0';
1500  
1501 <  if (nc != 0)
1502 <    sendto_channel_local(ALL_MEMBERS, 0, chptr, "%s %s", modebuf, parabuf);
1627 <
1628 <  send_mode_changes_server(source_p, chptr);
1501 >  if (nc)
1502 >    sendto_channel_local(0, chptr, "%s %s", modebuf, parabuf);
1503   }
1504  
1505 < /* void set_channel_mode(struct Client *client_p, struct Client *source_p,
1506 < *               struct Channel *chptr, int parc, char **parv,
1633 < *               char *chname)
1634 < * Input: The client we received this from, the client this originated
1505 > /*
1506 > * Input: The the client this originated
1507   *        from, the channel, the parameter count starting at the modes,
1508   *        the parameters, the channel name.
1509   * Output: None.
# Line 1645 | Line 1517 | set_channel_mode(struct Client *source_p
1517   {
1518    int dir = MODE_ADD;
1519    int parn = 1;
1520 <  int alevel, errors = 0;
1649 <  char *ml = parv[0], c;
1520 >  int alevel = 0, errors = 0;
1521  
1522    mode_count = 0;
1523    mode_limit = 0;
# Line 1654 | Line 1525 | set_channel_mode(struct Client *source_p
1525  
1526    alevel = get_channel_access(source_p, member);
1527  
1528 <  for (; (c = *ml); ++ml)
1528 >  for (const char *ml = parv[0]; *ml; ++ml)
1529    {
1530 <    switch (c)
1530 >    switch (*ml)
1531      {
1532        case '+':
1533          dir = MODE_ADD;
# Line 1669 | Line 1540 | set_channel_mode(struct Client *source_p
1540          break;
1541        default:
1542        {
1543 <        struct ChannelMode *tptr = &ModeTable[(unsigned char)c];
1543 >        const struct ChannelMode *tptr = &ModeTable[(unsigned char)*ml];
1544  
1545          tptr->func(source_p, chptr, parc, &parn, parv,
1546 <                   &errors, alevel, dir, c, tptr->d);
1546 >                   &errors, alevel, dir, *ml, tptr->d);
1547          break;
1548        }
1549      }
1550    }
1551  
1552 <  send_mode_changes(source_p, chptr);
1552 >  /* Bail out if we have nothing to do... */
1553 >  if (!mode_count)
1554 >    return;
1555 >
1556 >  send_mode_changes_client(source_p, chptr);
1557 >  send_mode_changes_server(source_p, chptr);
1558   }

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)