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 4800 by michael, Tue Oct 28 13:59:43 2014 UTC vs.
Revision 8022 by michael, Thu Mar 16 21:03:07 2017 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-2017 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 40 | Line 40
40   #include "mempool.h"
41   #include "parse.h"
42  
43 – /* 10 is a magic number in hybrid 6 NFI where it comes from -db */
44 – #define BAN_FUDGE       10
43  
44   static char nuh_mask[MAXPARA][IRCD_BUFSIZE];
47 – /* some buffers for rebuilding channel/nick lists with ,'s */
48 – static char modebuf[IRCD_BUFSIZE];
49 – static char parabuf[MODEBUFLEN];
45   static struct ChModeChange mode_changes[IRCD_BUFSIZE];
46   static unsigned int mode_count;
47   static unsigned int mode_limit;  /* number of modes set other than simple */
# Line 63 | Line 58 | const struct mode_letter chan_modes[] =
58    { MODE_REGISTERED, 'r' },
59    { MODE_SECRET,     's' },
60    { MODE_TOPICLIMIT, 't' },
61 +  { MODE_NOCTCP,     'C' },
62    { MODE_MODREG,     'M' },
63    { MODE_OPERONLY,   'O' },
64    { MODE_REGONLY,    'R' },
65    { MODE_SSLONLY,    'S' },
66 +  { MODE_NONOTICE,   'T' },
67    { 0, '\0' }
68   };
69  
# Line 83 | Line 80 | const struct mode_letter chan_modes[] =
80   static char *
81   check_string(char *s)
82   {
83 <  char *str = s;
83 >  char *const str = s;
84    static char star[] = "*";
85  
86    if (EmptyString(str))
# Line 102 | Line 99 | check_string(char *s)
99   }
100  
101   /*
102 < * Ban functions to work with mode +b/e/d/I
102 > * Ban functions to work with mode +b/e/I
103   */
104   /* add the specified ID to the channel.
105   *   -is 8/9/00
# Line 111 | Line 108 | check_string(char *s)
108   int
109   add_id(struct Client *client_p, struct Channel *chptr, char *banid, unsigned int type)
110   {
111 <  dlink_list *list = NULL;
112 <  dlink_node *node = NULL;
116 <  struct Ban *banptr = NULL;
117 <  size_t len = 0;
111 >  dlink_list *list;
112 >  dlink_node *node;
113    char name[NICKLEN + 1] = "";
114    char user[USERLEN + 1] = "";
115    char host[HOSTLEN + 1] = "";
# Line 151 | Line 146 | add_id(struct Client *client_p, struct C
146     * Re-assemble a new n!u@h and print it back to banid for sending
147     * the mode to the channel.
148     */
149 <  len = sprintf(banid, "%s!%s@%s", name, user, host);
149 >  size_t len = snprintf(banid, IRCD_BUFSIZE, "%s!%s@%s", name, user, host);
150  
151    switch (type)
152    {
153      case CHFL_BAN:
154        list = &chptr->banlist;
155 <      clear_ban_cache(chptr);
155 >      clear_ban_cache_list(&chptr->locmembers);
156        break;
157      case CHFL_EXCEPTION:
158        list = &chptr->exceptlist;
159 <      clear_ban_cache(chptr);
159 >      clear_ban_cache_list(&chptr->locmembers);
160        break;
161      case CHFL_INVEX:
162        list = &chptr->invexlist;
163        break;
164      default:
165 <      assert(0);
171 <      return 0;
165 >      list = NULL;  /* Let it crash */
166    }
167  
168    DLINK_FOREACH(node, list->head)
169    {
170 <    banptr = node->data;
170 >    const struct Ban *ban = node->data;
171  
172 <    if (!irccmp(banptr->name, name) &&
173 <        !irccmp(banptr->user, user) &&
174 <        !irccmp(banptr->host, host))
172 >    if (!irccmp(ban->name, name) &&
173 >        !irccmp(ban->user, user) &&
174 >        !irccmp(ban->host, host))
175        return 0;
176    }
177  
178 <  banptr = mp_pool_get(ban_pool);
179 <  banptr->name = xstrdup(name);
180 <  banptr->user = xstrdup(user);
181 <  banptr->host = xstrdup(host);
182 <  banptr->when = CurrentTime;
183 <  banptr->len = len - 2;  /* -2 for ! + @ */
184 <  banptr->type = parse_netmask(host, &banptr->addr, &banptr->bits);
178 >  struct Ban *ban = mp_pool_get(ban_pool);
179 >  ban->when = CurrentTime;
180 >  ban->len = len - 2;  /* -2 for ! + @ */
181 >  ban->type = parse_netmask(host, &ban->addr, &ban->bits);
182 >  strlcpy(ban->name, name, sizeof(ban->name));
183 >  strlcpy(ban->user, user, sizeof(ban->user));
184 >  strlcpy(ban->host, host, sizeof(ban->host));
185  
186    if (IsClient(client_p))
187 <  {
188 <    banptr->who = MyCalloc(strlen(client_p->name) +
189 <                           strlen(client_p->username) +
190 <                           strlen(client_p->host) + 3);
197 <    sprintf(banptr->who, "%s!%s@%s", client_p->name,
198 <            client_p->username, client_p->host);
199 <  }
200 <  else if (IsHidden(client_p) || (IsServer(client_p) && ConfigServerHide.hide_servers))
201 <    banptr->who = xstrdup(me.name);
187 >    snprintf(ban->who, sizeof(ban->who), "%s!%s@%s", client_p->name,
188 >             client_p->username, client_p->host);
189 >  else if (IsHidden(client_p) || ConfigServerHide.hide_servers)
190 >    strlcpy(ban->who, me.name, sizeof(ban->who));
191    else
192 <    banptr->who = xstrdup(client_p->name);
192 >    strlcpy(ban->who, client_p->name, sizeof(ban->who));
193  
194 <  dlinkAdd(banptr, &banptr->node, list);
194 >  dlinkAdd(ban, &ban->node, list);
195  
196    return 1;
197   }
# Line 217 | Line 206 | add_id(struct Client *client_p, struct C
206   static int
207   del_id(struct Channel *chptr, char *banid, unsigned int type)
208   {
209 <  dlink_list *list = NULL;
210 <  dlink_node *node = NULL;
209 >  dlink_list *list;
210 >  dlink_node *node;
211    char name[NICKLEN + 1] = "";
212    char user[USERLEN + 1] = "";
213    char host[HOSTLEN + 1] = "";
# Line 241 | Line 230 | del_id(struct Channel *chptr, char *bani
230     * Re-assemble a new n!u@h and print it back to banid for sending
231     * the mode to the channel.
232     */
233 <  sprintf(banid, "%s!%s@%s", name, user, host);
233 >  snprintf(banid, IRCD_BUFSIZE, "%s!%s@%s", name, user, host);
234  
235    switch (type)
236    {
237      case CHFL_BAN:
238        list = &chptr->banlist;
239 <      clear_ban_cache(chptr);
239 >      clear_ban_cache_list(&chptr->locmembers);
240        break;
241      case CHFL_EXCEPTION:
242        list = &chptr->exceptlist;
243 <      clear_ban_cache(chptr);
243 >      clear_ban_cache_list(&chptr->locmembers);
244        break;
245      case CHFL_INVEX:
246        list = &chptr->invexlist;
247        break;
248      default:
249 <      assert(0);
261 <      return 0;
249 >      list = NULL;  /* Let it crash */
250    }
251  
252    DLINK_FOREACH(node, list->head)
253    {
254 <    struct Ban *banptr = node->data;
254 >    struct Ban *ban = node->data;
255  
256 <    if (!irccmp(name, banptr->name) &&
257 <        !irccmp(user, banptr->user) &&
258 <        !irccmp(host, banptr->host))
256 >    if (!irccmp(name, ban->name) &&
257 >        !irccmp(user, ban->user) &&
258 >        !irccmp(host, ban->host))
259      {
260 <      remove_ban(banptr, list);
260 >      remove_ban(ban, list);
261        return 1;
262      }
263    }
# Line 301 | Line 289 | channel_modes(struct Channel *chptr, str
289    {
290      *mbuf++ = 'l';
291  
292 <    if (IsServer(client_p) || HasFlag(client_p, FLAGS_SERVICE) || IsMember(client_p, chptr))
293 <      pbuf += sprintf(pbuf, "%d ", chptr->mode.limit);
292 >    if (IsServer(client_p) || IsMember(client_p, chptr))
293 >      pbuf += sprintf(pbuf, "%u ", chptr->mode.limit);
294    }
295  
296    if (chptr->mode.key[0])
297    {
298      *mbuf++ = 'k';
299  
300 <    if (IsServer(client_p) || HasFlag(client_p, FLAGS_SERVICE) || IsMember(client_p, chptr))
300 >    if (IsServer(client_p) || IsMember(client_p, chptr))
301        sprintf(pbuf, "%s ", chptr->mode.key);
302    }
303  
# Line 329 | Line 317 | fix_key(char *arg)
317   {
318    unsigned char *s, *t, c;
319  
320 <  for (s = t = (unsigned char *)arg; (c = *s); ++s)
320 >  for (s = t = (unsigned char *)arg; (c = *s) && s - (unsigned char *)arg < KEYLEN; ++s)
321    {
322      c &= 0x7f;
323  
# Line 347 | Line 335 | fix_key(char *arg)
335   * side effects - clear ban cache
336   */
337   void
338 < clear_ban_cache(struct Channel *chptr)
351 < {
352 <  dlink_node *node = NULL;
353 <
354 <  DLINK_FOREACH(node, chptr->locmembers.head)
355 <  {
356 <    struct Membership *ms = node->data;
357 <    ms->flags &= ~(CHFL_BAN_SILENCED|CHFL_BAN_CHECKED);
358 <  }
359 < }
360 <
361 < void
362 < clear_ban_cache_client(struct Client *client_p)
338 > clear_ban_cache_list(dlink_list *list)
339   {
340 <  dlink_node *node = NULL;
340 >  dlink_node *node;
341  
342 <  DLINK_FOREACH(node, client_p->channel.head)
342 >  DLINK_FOREACH(node, list->head)
343    {
344 <    struct Membership *ms = node->data;
345 <    ms->flags &= ~(CHFL_BAN_SILENCED|CHFL_BAN_CHECKED);
344 >    struct Membership *member = node->data;
345 >    member->flags &= ~(CHFL_BAN_SILENCED | CHFL_BAN_CHECKED);
346    }
347   }
348  
# Line 408 | Line 384 | chm_simple(struct Client *source_p, stru
384        sendto_one_numeric(source_p, &me,
385                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
386                           ERR_CHANOPRIVSNEEDED, chptr->name);
387 +
388      *errors |= SM_ERR_NOOPS;
389      return;
390    }
# Line 458 | Line 435 | chm_registered(struct Client *source_p,
435        sendto_one_numeric(source_p, &me,
436                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
437                           ERR_ONLYSERVERSCANCHANGE, chptr->name);
438 +
439      *errors |= SM_ERR_ONLYSERVER;
440      return;
441    }
# Line 502 | Line 480 | static void
480   chm_operonly(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
481               char **parv, int *errors, int alev, int dir, char c, unsigned int d)
482   {
483 <  if (alev < CHACCESS_CHANOP)
483 >  if (alev < CHACCESS_HALFOP)
484    {
485      if (!(*errors & SM_ERR_NOOPS))
486        sendto_one_numeric(source_p, &me,
# Line 554 | Line 532 | static void
532   chm_ban(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
533          char **parv, int *errors, int alev, int dir, char c, unsigned int d)
534   {
557 –  char *mask = NULL;
558 –
535    if (dir == MODE_QUERY || parc <= *parn)
536    {
537 <    dlink_node *node = NULL;
537 >    dlink_node *node;
538  
539      if (*errors & SM_ERR_RPL_B)
540        return;
# Line 567 | Line 543 | chm_ban(struct Client *source_p, struct
543  
544      DLINK_FOREACH(node, chptr->banlist.head)
545      {
546 <      const struct Ban *banptr = node->data;
546 >      const struct Ban *ban = node->data;
547        sendto_one_numeric(source_p, &me, RPL_BANLIST, chptr->name,
548 <                         banptr->name, banptr->user, banptr->host,
549 <                         banptr->who, banptr->when);
548 >                         ban->name, ban->user, ban->host,
549 >                         ban->who, ban->when);
550      }
551  
552      sendto_one_numeric(source_p, &me, RPL_ENDOFBANLIST, chptr->name);
# Line 583 | Line 559 | chm_ban(struct Client *source_p, struct
559        sendto_one_numeric(source_p, &me,
560                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
561                           ERR_CHANOPRIVSNEEDED, chptr->name);
562 +
563      *errors |= SM_ERR_NOOPS;
564      return;
565    }
# Line 590 | Line 567 | chm_ban(struct Client *source_p, struct
567    if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
568      return;
569  
570 <  mask = nuh_mask[*parn];
571 <  memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
570 >  char *mask = nuh_mask[*parn];
571 >  strlcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
572    ++(*parn);
573  
574 <  if (!MyConnect(source_p))
575 <    if (strchr(mask, ' '))
599 <      return;
574 >  if (*mask == ':' || (!MyConnect(source_p) && strchr(mask, ' ')))
575 >    return;
576  
577    switch (dir)
578    {
# Line 613 | Line 589 | chm_ban(struct Client *source_p, struct
589    }
590  
591    mode_changes[mode_count].letter = c;
592 <  mode_changes[mode_count].arg = mask;
592 >  mode_changes[mode_count].arg = mask;  /* At this point 'mask' is no longer than NICKLEN + USERLEN + HOSTLEN + 3 */
593    mode_changes[mode_count].id = NULL;
594    mode_changes[mode_count++].dir = dir;
595   }
# Line 622 | Line 598 | static void
598   chm_except(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
599             char **parv, int *errors, int alev, int dir, char c, unsigned int d)
600   {
625 –  char *mask = NULL;
626 –
601    if (dir == MODE_QUERY || parc <= *parn)
602    {
603 <    dlink_node *node = NULL;
603 >    dlink_node *node;
604  
605      if (*errors & SM_ERR_RPL_E)
606        return;
# Line 635 | Line 609 | chm_except(struct Client *source_p, stru
609  
610      DLINK_FOREACH(node, chptr->exceptlist.head)
611      {
612 <      const struct Ban *banptr = node->data;
639 <
612 >      const struct Ban *ban = node->data;
613        sendto_one_numeric(source_p, &me, RPL_EXCEPTLIST, chptr->name,
614 <                         banptr->name, banptr->user, banptr->host,
615 <                         banptr->who, banptr->when);
614 >                         ban->name, ban->user, ban->host,
615 >                         ban->who, ban->when);
616      }
617  
618      sendto_one_numeric(source_p, &me, RPL_ENDOFEXCEPTLIST, chptr->name);
# Line 652 | Line 625 | chm_except(struct Client *source_p, stru
625        sendto_one_numeric(source_p, &me,
626                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
627                           ERR_CHANOPRIVSNEEDED, chptr->name);
628 +
629      *errors |= SM_ERR_NOOPS;
630      return;
631    }
# Line 659 | Line 633 | chm_except(struct Client *source_p, stru
633    if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
634      return;
635  
636 <  mask = nuh_mask[*parn];
637 <  memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
636 >  char *mask = nuh_mask[*parn];
637 >  strlcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
638    ++(*parn);
639  
640 <  if (!MyConnect(source_p))
641 <    if (strchr(mask, ' '))
668 <      return;
640 >  if (*mask == ':' || (!MyConnect(source_p) && strchr(mask, ' ')))
641 >    return;
642  
643    switch (dir)
644    {
# Line 682 | Line 655 | chm_except(struct Client *source_p, stru
655    }
656  
657    mode_changes[mode_count].letter = c;
658 <  mode_changes[mode_count].arg = mask;
658 >  mode_changes[mode_count].arg = mask;  /* At this point 'mask' is no longer than NICKLEN + USERLEN + HOSTLEN + 3 */
659    mode_changes[mode_count].id = NULL;
660    mode_changes[mode_count++].dir = dir;
661   }
# Line 691 | Line 664 | static void
664   chm_invex(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
665            char **parv, int *errors, int alev, int dir, char c, unsigned int d)
666   {
694 –  char *mask = NULL;
695 –
667    if (dir == MODE_QUERY || parc <= *parn)
668    {
669 <    dlink_node *node = NULL;
669 >    dlink_node *node;
670  
671      if (*errors & SM_ERR_RPL_I)
672        return;
# Line 704 | Line 675 | chm_invex(struct Client *source_p, struc
675  
676      DLINK_FOREACH(node, chptr->invexlist.head)
677      {
678 <      const struct Ban *banptr = node->data;
708 <
678 >      const struct Ban *ban = node->data;
679        sendto_one_numeric(source_p, &me, RPL_INVEXLIST, chptr->name,
680 <                         banptr->name, banptr->user, banptr->host,
681 <                         banptr->who, banptr->when);
680 >                         ban->name, ban->user, ban->host,
681 >                         ban->who, ban->when);
682      }
683  
684      sendto_one_numeric(source_p, &me, RPL_ENDOFINVEXLIST, chptr->name);
# Line 721 | Line 691 | chm_invex(struct Client *source_p, struc
691        sendto_one_numeric(source_p, &me,
692                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
693                           ERR_CHANOPRIVSNEEDED, chptr->name);
694 +
695      *errors |= SM_ERR_NOOPS;
696      return;
697    }
# Line 728 | Line 699 | chm_invex(struct Client *source_p, struc
699    if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
700      return;
701  
702 <  mask = nuh_mask[*parn];
703 <  memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
702 >  char *mask = nuh_mask[*parn];
703 >  strlcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
704    ++(*parn);
705  
706 <  if (!MyConnect(source_p))
707 <    if (strchr(mask, ' '))
737 <      return;
706 >  if (*mask == ':' || (!MyConnect(source_p) && strchr(mask, ' ')))
707 >    return;
708  
709    switch (dir)
710    {
# Line 751 | Line 721 | chm_invex(struct Client *source_p, struc
721    }
722  
723    mode_changes[mode_count].letter = c;
724 <  mode_changes[mode_count].arg = mask;
724 >  mode_changes[mode_count].arg = mask;  /* At this point 'mask' is no longer than NICKLEN + USERLEN + HOSTLEN + 3 */
725    mode_changes[mode_count].id = NULL;
726    mode_changes[mode_count++].dir = dir;
727   }
# Line 769 | Line 739 | chm_voice(struct Client *source_p, struc
739        sendto_one_numeric(source_p, &me,
740                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
741                           ERR_CHANOPRIVSNEEDED, chptr->name);
742 +
743      *errors |= SM_ERR_NOOPS;
744      return;
745    }
# Line 783 | Line 754 | chm_voice(struct Client *source_p, struc
754    {
755      if (!(*errors & SM_ERR_NOTONCHANNEL))
756        sendto_one_numeric(source_p, &me, ERR_USERNOTINCHANNEL, target_p->name, chptr->name);
757 +
758      *errors |= SM_ERR_NOTONCHANNEL;
759      return;
760    }
# Line 790 | Line 762 | chm_voice(struct Client *source_p, struc
762    if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
763      return;
764  
765 <  /* no redundant mode changes */
766 <  if (dir == MODE_ADD &&  has_member_flags(member, CHFL_VOICE))
767 <    return;
768 <  if (dir == MODE_DEL && !has_member_flags(member, CHFL_VOICE))
769 <    return;
765 >  switch (dir)
766 >  {
767 >    case MODE_ADD:
768 >      if (has_member_flags(member, CHFL_VOICE))
769 >        return;  /* No redundant mode changes */
770 >
771 >      AddMemberFlag(member, CHFL_VOICE);
772 >      break;
773 >    case MODE_DEL:
774 >      if (!has_member_flags(member, CHFL_VOICE))
775 >        return;  /* No redundant mode changes */
776 >
777 >      DelMemberFlag(member, CHFL_VOICE);
778 >      break;
779 >  }
780  
781    mode_changes[mode_count].letter = c;
782    mode_changes[mode_count].arg = target_p->name;
783    mode_changes[mode_count].id = target_p->id;
784    mode_changes[mode_count++].dir = dir;
803 –
804 –  if (dir == MODE_ADD)
805 –    AddMemberFlag(member, CHFL_VOICE);
806 –  else
807 –    DelMemberFlag(member, CHFL_VOICE);
785   }
786  
787   static void
# Line 820 | Line 797 | chm_hop(struct Client *source_p, struct
797        sendto_one_numeric(source_p, &me,
798                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
799                           ERR_CHANOPRIVSNEEDED, chptr->name);
800 +
801      *errors |= SM_ERR_NOOPS;
802      return;
803    }
# Line 834 | Line 812 | chm_hop(struct Client *source_p, struct
812    {
813      if (!(*errors & SM_ERR_NOTONCHANNEL))
814        sendto_one_numeric(source_p, &me, ERR_USERNOTINCHANNEL, target_p->name, chptr->name);
815 +
816      *errors |= SM_ERR_NOTONCHANNEL;
817      return;
818    }
# Line 841 | Line 820 | chm_hop(struct Client *source_p, struct
820    if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
821      return;
822  
823 <  /* no redundant mode changes */
824 <  if (dir == MODE_ADD &&  has_member_flags(member, CHFL_HALFOP))
825 <    return;
826 <  if (dir == MODE_DEL && !has_member_flags(member, CHFL_HALFOP))
827 <    return;
823 >  switch (dir)
824 >  {
825 >    case MODE_ADD:
826 >      if (has_member_flags(member, CHFL_HALFOP))
827 >        return;  /* No redundant mode changes */
828 >
829 >      AddMemberFlag(member, CHFL_HALFOP);
830 >      break;
831 >    case MODE_DEL:
832 >      if (!has_member_flags(member, CHFL_HALFOP))
833 >        return;  /* No redundant mode changes */
834 >
835 >      DelMemberFlag(member, CHFL_HALFOP);
836 >      break;
837 >  }
838  
839    mode_changes[mode_count].letter = c;
840    mode_changes[mode_count].arg = target_p->name;
841    mode_changes[mode_count].id = target_p->id;
842    mode_changes[mode_count++].dir = dir;
854 –
855 –  if (dir == MODE_ADD)
856 –    AddMemberFlag(member, CHFL_HALFOP);
857 –  else
858 –    DelMemberFlag(member, CHFL_HALFOP);
843   }
844  
845   static void
# Line 871 | Line 855 | chm_op(struct Client *source_p, struct C
855        sendto_one_numeric(source_p, &me,
856                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
857                           ERR_CHANOPRIVSNEEDED, chptr->name);
858 +
859      *errors |= SM_ERR_NOOPS;
860      return;
861    }
# Line 885 | Line 870 | chm_op(struct Client *source_p, struct C
870    {
871      if (!(*errors & SM_ERR_NOTONCHANNEL))
872        sendto_one_numeric(source_p, &me, ERR_USERNOTINCHANNEL, target_p->name, chptr->name);
873 +
874      *errors |= SM_ERR_NOTONCHANNEL;
875      return;
876    }
# Line 892 | Line 878 | chm_op(struct Client *source_p, struct C
878    if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
879      return;
880  
881 <  /* no redundant mode changes */
882 <  if (dir == MODE_ADD &&  has_member_flags(member, CHFL_CHANOP))
883 <    return;
884 <  if (dir == MODE_DEL && !has_member_flags(member, CHFL_CHANOP))
885 <    return;
881 >  switch (dir)
882 >  {
883 >    case MODE_ADD:
884 >      if (has_member_flags(member, CHFL_CHANOP))
885 >        return;  /* No redundant mode changes */
886 >
887 >      AddMemberFlag(member, CHFL_CHANOP);
888 >      break;
889 >    case MODE_DEL:
890 >      if (!has_member_flags(member, CHFL_CHANOP))
891 >        return;  /* No redundant mode changes */
892 >
893 >      DelMemberFlag(member, CHFL_CHANOP);
894 >      break;
895 >  }
896  
897    mode_changes[mode_count].letter = c;
898    mode_changes[mode_count].arg = target_p->name;
899    mode_changes[mode_count].id = target_p->id;
900    mode_changes[mode_count++].dir = dir;
905 –
906 –  if (dir == MODE_ADD)
907 –    AddMemberFlag(member, CHFL_CHANOP);
908 –  else
909 –    DelMemberFlag(member, CHFL_CHANOP);
901   }
902  
903   static void
904   chm_limit(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
905            char **parv, int *errors, int alev, int dir, char c, unsigned int d)
906   {
916 –  int limit = 0;
917 –
907    if (alev < CHACCESS_HALFOP)
908    {
909      if (!(*errors & SM_ERR_NOOPS))
# Line 930 | Line 919 | chm_limit(struct Client *source_p, struc
919  
920    if (dir == MODE_ADD && parc > *parn)
921    {
922 <    char *lstr = parv[(*parn)++];
922 >    char *const lstr = parv[(*parn)++];
923 >    int limit = 0;
924  
925      if (EmptyString(lstr) || (limit = atoi(lstr)) <= 0)
926        return;
# Line 982 | Line 972 | chm_key(struct Client *source_p, struct
972  
973    if (dir == MODE_ADD && parc > *parn)
974    {
975 <    char *key = fix_key(parv[(*parn)++]);
975 >    char *const key = fix_key(parv[(*parn)++]);
976  
977      if (EmptyString(key))
978        return;
# Line 996 | Line 986 | chm_key(struct Client *source_p, struct
986          mode_changes[i].letter = 0;
987  
988      mode_changes[mode_count].letter = c;
989 <    mode_changes[mode_count].arg = chptr->mode.key;
989 >    mode_changes[mode_count].arg = key;
990      mode_changes[mode_count].id = NULL;
991      mode_changes[mode_count++].dir = dir;
992    }
# Line 1086 | Line 1076 | const struct ChannelMode ModeTable[256]
1076    { chm_nosuch,  0 },                   /* @ */
1077    { chm_nosuch,  0 },                   /* A */
1078    { chm_nosuch,  0 },                   /* B */
1079 <  { chm_nosuch,  0 },                   /* C */
1079 >  { chm_simple,  MODE_NOCTCP },         /* C */
1080    { chm_nosuch,  0 },                   /* D */
1081    { chm_nosuch,  0 },                   /* E */
1082    { chm_nosuch,  0 },                   /* F */
# Line 1103 | Line 1093 | const struct ChannelMode ModeTable[256]
1093    { chm_nosuch,  0 },                   /* Q */
1094    { chm_simple, MODE_REGONLY},          /* R */
1095    { chm_simple, MODE_SSLONLY},          /* S */
1096 <  { chm_nosuch,  0 },                   /* T */
1096 >  { chm_simple, MODE_NONOTICE},         /* T */
1097    { chm_nosuch,  0 },                   /* U */
1098    { chm_nosuch,  0 },                   /* V */
1099    { chm_nosuch,  0 },                   /* W */
# Line 1318 | Line 1308 | get_channel_access(const struct Client *
1308   static void
1309   send_mode_changes_server(struct Client *source_p, struct Channel *chptr)
1310   {
1311 <  int mbl = 0, pbl = 0, arglen = 0, nc = 0, mc = 0;
1312 <  int len = 0;
1311 >  char modebuf[IRCD_BUFSIZE] = "";
1312 >  char parabuf[IRCD_BUFSIZE] = "";
1313 >  char *parptr = parabuf;
1314 >  int mbl = 0, pbl = 0, arglen = 0, modecount = 0, paracount = 0;
1315    int dir = MODE_QUERY;
1324 –  const char *arg = NULL;
1325 –  char *parptr = NULL;
1316  
1317 <  parabuf[0] = '\0';
1318 <  parptr = parabuf;
1329 <
1330 <  mbl = snprintf(modebuf, sizeof(modebuf), ":%s TMODE %lu %s ", source_p->id,
1331 <                 (unsigned long)chptr->channelts, chptr->name);
1317 >  mbl = snprintf(modebuf, sizeof(modebuf), ":%s TMODE %ju %s ",
1318 >                 source_p->id, chptr->creationtime, chptr->name);
1319  
1320    /* Loop the list of modes we have */
1321 <  for (unsigned i = 0; i < mode_count; ++i)
1321 >  for (unsigned int i = 0; i < mode_count; ++i)
1322    {
1323      if (mode_changes[i].letter == 0)
1324        continue;
1325  
1326 +    const char *arg;
1327      if (mode_changes[i].id)
1328        arg = mode_changes[i].id;
1329      else
# Line 1350 | Line 1338 | send_mode_changes_server(struct Client *
1338       * If we're creeping past the buf size, we need to send it and make
1339       * another line for the other modes
1340       */
1341 <    if ((mc == MAXMODEPARAMS) ||
1342 <        ((arglen + mbl + pbl + 2) > IRCD_BUFSIZE) ||
1355 <        (pbl + arglen + BAN_FUDGE) >= MODEBUFLEN)
1341 >    if ((paracount == MAXMODEPARAMS) ||
1342 >        ((arglen + mbl + pbl + 2 /* +2 for /r/n */ ) > IRCD_BUFSIZE))
1343      {
1344 <      if (nc)
1345 <        sendto_server(source_p, NOCAPS, NOCAPS, "%s %s", modebuf, parabuf);
1344 >      if (modecount)
1345 >        sendto_server(source_p, 0, 0, "%s %s", modebuf, parabuf);
1346  
1347 <      nc = 0;
1348 <      mc = 0;
1347 >      modecount = 0;
1348 >      paracount = 0;
1349  
1350 <      mbl = snprintf(modebuf, sizeof(modebuf), ":%s TMODE %lu %s ", source_p->id,
1351 <                     (unsigned long)chptr->channelts, chptr->name);
1350 >      mbl = snprintf(modebuf, sizeof(modebuf), ":%s TMODE %ju %s ",
1351 >                     source_p->id, chptr->creationtime, chptr->name);
1352  
1353        pbl = 0;
1354        parabuf[0] = '\0';
# Line 1377 | Line 1364 | send_mode_changes_server(struct Client *
1364  
1365      modebuf[mbl++] = mode_changes[i].letter;
1366      modebuf[mbl] = '\0';
1367 <    ++nc;
1367 >    ++modecount;
1368  
1369      if (arg)
1370      {
1371 <      len = sprintf(parptr, "%s ", arg);
1371 >      int len = sprintf(parptr, (pbl == 0) ? "%s" : " %s", arg);
1372        pbl += len;
1373        parptr += len;
1374 <      ++mc;
1374 >      ++paracount;
1375      }
1376    }
1377  
1378 <  if (pbl && parabuf[pbl - 1] == ' ')
1379 <    parabuf[pbl - 1] = '\0';
1393 <
1394 <  if (nc)
1395 <    sendto_server(source_p, NOCAPS, NOCAPS, "%s %s", modebuf, parabuf);
1378 >  if (modecount)
1379 >    sendto_server(source_p, 0, 0, "%s %s", modebuf, parabuf);
1380   }
1381  
1382   /* void send_mode_changes(struct Client *client_p,
# Line 1405 | Line 1389 | send_mode_changes_server(struct Client *
1389   * Side-effects: Sends the appropriate mode changes to other clients
1390   *               and propagates to servers.
1391   */
1408 – /* ensure parabuf < MODEBUFLEN -db */
1392   static void
1393 < send_mode_changes(struct Client *source_p, struct Channel *chptr)
1393 > send_mode_changes_client(struct Client *source_p, struct Channel *chptr)
1394   {
1395 <  int mbl = 0, pbl = 0, arglen = 0, nc = 0, mc = 0;
1396 <  int len = 0;
1395 >  char modebuf[IRCD_BUFSIZE] = "";
1396 >  char parabuf[IRCD_BUFSIZE] = "";
1397 >  char *parptr = parabuf;
1398 >  int mbl = 0, pbl = 0, arglen = 0, modecount = 0, paracount = 0;
1399    int dir = MODE_QUERY;
1415 –  const char *arg = NULL;
1416 –  char *parptr = NULL;
1417 –
1418 –  /* Bail out if we have nothing to do... */
1419 –  if (!mode_count)
1420 –    return;
1400  
1401    if (IsServer(source_p))
1402      mbl = snprintf(modebuf, sizeof(modebuf), ":%s MODE %s ", (IsHidden(source_p) ||
# Line 1427 | Line 1406 | send_mode_changes(struct Client *source_
1406      mbl = snprintf(modebuf, sizeof(modebuf), ":%s!%s@%s MODE %s ", source_p->name,
1407                     source_p->username, source_p->host, chptr->name);
1408  
1430 –  parabuf[0] = '\0';
1431 –  parptr = parabuf;
1432 –
1409    for (unsigned int i = 0; i < mode_count; ++i)
1410    {
1411      if (mode_changes[i].letter == 0)
1412        continue;
1413  
1414 <    arg = mode_changes[i].arg;
1414 >    const char *arg = mode_changes[i].arg;
1415      if (arg)
1416        arglen = strlen(arg);
1417      else
1418        arglen = 0;
1419  
1420 <    if ((mc == MAXMODEPARAMS) ||
1421 <        ((arglen + mbl + pbl + 2) > IRCD_BUFSIZE) ||
1446 <        ((arglen + pbl + BAN_FUDGE) >= MODEBUFLEN))
1420 >    if ((paracount == MAXMODEPARAMS) ||
1421 >        ((arglen + mbl + pbl + 2 /* +2 for /r/n */ ) > IRCD_BUFSIZE))
1422      {
1423 <      if (mbl && modebuf[mbl - 1] == '-')
1424 <        modebuf[mbl - 1] = '\0';
1450 <
1451 <      if (nc)
1452 <        sendto_channel_local(0, chptr, "%s %s", modebuf, parabuf);
1423 >      if (modecount)
1424 >        sendto_channel_local(NULL, chptr, 0, 0, 0, "%s %s", modebuf, parabuf);
1425  
1426 <      nc = 0;
1427 <      mc = 0;
1426 >      modecount = 0;
1427 >      paracount = 0;
1428  
1429        if (IsServer(source_p))
1430          mbl = snprintf(modebuf, sizeof(modebuf), ":%s MODE %s ", (IsHidden(source_p) ||
# Line 1476 | Line 1448 | send_mode_changes(struct Client *source_
1448  
1449      modebuf[mbl++] = mode_changes[i].letter;
1450      modebuf[mbl] = '\0';
1451 <    ++nc;
1451 >    ++modecount;
1452  
1453      if (arg)
1454      {
1455 <      len = sprintf(parptr, "%s ", arg);
1455 >      int len = sprintf(parptr, (pbl == 0) ? "%s" : " %s", arg);
1456        pbl += len;
1457        parptr += len;
1458 <      ++mc;
1458 >      ++paracount;
1459      }
1460    }
1461  
1462 <  if (pbl && parabuf[pbl - 1] == ' ')
1463 <    parabuf[pbl - 1] = '\0';
1492 <
1493 <  if (nc)
1494 <    sendto_channel_local(0, chptr, "%s %s", modebuf, parabuf);
1495 <
1496 <  send_mode_changes_server(source_p, chptr);
1462 >  if (modecount)
1463 >    sendto_channel_local(NULL, chptr, 0, 0, 0, "%s %s", modebuf, parabuf);
1464   }
1465  
1466   /*
# Line 1543 | Line 1510 | set_channel_mode(struct Client *source_p
1510      }
1511    }
1512  
1513 <  send_mode_changes(source_p, chptr);
1513 >  /* Bail out if we have nothing to do... */
1514 >  if (!mode_count)
1515 >    return;
1516 >
1517 >  send_mode_changes_client(source_p, chptr);
1518 >  send_mode_changes_server(source_p, chptr);
1519   }

Comparing ircd-hybrid/trunk/src/channel_mode.c (property svn:keywords):
Revision 4800 by michael, Tue Oct 28 13:59:43 2014 UTC vs.
Revision 8022 by michael, Thu Mar 16 21:03:07 2017 UTC

# Line 1 | Line 1
1 < Id Revision
1 > Id

Diff Legend

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