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 5752 by michael, Thu Apr 2 17:27:33 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 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 113 | Line 114 | add_id(struct Client *client_p, struct C
114   {
115    dlink_list *list = NULL;
116    dlink_node *node = NULL;
117 <  struct Ban *banptr = NULL;
117 >  struct Ban *ban = NULL;
118    size_t len = 0;
119    char name[NICKLEN + 1] = "";
120    char user[USERLEN + 1] = "";
# Line 151 | 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 173 | Line 174 | add_id(struct Client *client_p, struct C
174  
175    DLINK_FOREACH(node, list->head)
176    {
177 <    banptr = node->data;
177 >    ban = node->data;
178  
179 <    if (!irccmp(banptr->name, name) &&
180 <        !irccmp(banptr->user, user) &&
181 <        !irccmp(banptr->host, host))
179 >    if (!irccmp(ban->name, name) &&
180 >        !irccmp(ban->user, user) &&
181 >        !irccmp(ban->host, host))
182        return 0;
183    }
184  
185 <  banptr = mp_pool_get(ban_pool);
186 <  banptr->name = xstrdup(name);
187 <  banptr->user = xstrdup(user);
188 <  banptr->host = xstrdup(host);
189 <  banptr->when = CurrentTime;
190 <  banptr->len = len - 2;  /* -2 for ! + @ */
191 <  banptr->type = parse_netmask(host, &banptr->addr, &banptr->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 <    banptr->who = MyCalloc(strlen(client_p->name) +
196 <                           strlen(client_p->username) +
197 <                           strlen(client_p->host) + 3);
198 <    sprintf(banptr->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 <    banptr->who = xstrdup(me.name);
202 >    ban->who = xstrdup(me.name);
203    else
204 <    banptr->who = xstrdup(client_p->name);
204 >    ban->who = xstrdup(client_p->name);
205  
206 <  dlinkAdd(banptr, &banptr->node, list);
206 >  dlinkAdd(ban, &ban->node, list);
207  
208    return 1;
209   }
# Line 241 | 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 263 | Line 264 | del_id(struct Channel *chptr, char *bani
264  
265    DLINK_FOREACH(node, list->head)
266    {
267 <    struct Ban *banptr = node->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 347 | Line 348 | fix_key(char *arg)
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 *node = NULL;
354  
355    DLINK_FOREACH(node, chptr->locmembers.head)
356    {
357 <    struct Membership *ms = node->data;
358 <    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  
# Line 365 | Line 366 | clear_ban_cache_client(struct Client *cl
366  
367    DLINK_FOREACH(node, client_p->channel.head)
368    {
369 <    struct Membership *ms = node->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  
# Line 408 | Line 409 | chm_simple(struct Client *source_p, stru
409        sendto_one_numeric(source_p, &me,
410                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
411                           ERR_CHANOPRIVSNEEDED, chptr->name);
412 +
413      *errors |= SM_ERR_NOOPS;
414      return;
415    }
# Line 458 | Line 460 | chm_registered(struct Client *source_p,
460        sendto_one_numeric(source_p, &me,
461                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
462                           ERR_ONLYSERVERSCANCHANGE, chptr->name);
463 +
464      *errors |= SM_ERR_ONLYSERVER;
465      return;
466    }
# Line 502 | Line 505 | static void
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_CHANOP)
508 >  if (alev < CHACCESS_HALFOP)
509    {
510      if (!(*errors & SM_ERR_NOOPS))
511        sendto_one_numeric(source_p, &me,
# Line 567 | Line 570 | chm_ban(struct Client *source_p, struct
570  
571      DLINK_FOREACH(node, chptr->banlist.head)
572      {
573 <      const struct Ban *banptr = node->data;
573 >      const struct Ban *ban = node->data;
574        sendto_one_numeric(source_p, &me, RPL_BANLIST, chptr->name,
575 <                         banptr->name, banptr->user, banptr->host,
576 <                         banptr->who, banptr->when);
575 >                         ban->name, ban->user, ban->host,
576 >                         ban->who, ban->when);
577      }
578  
579      sendto_one_numeric(source_p, &me, RPL_ENDOFBANLIST, chptr->name);
# Line 583 | Line 586 | chm_ban(struct Client *source_p, struct
586        sendto_one_numeric(source_p, &me,
587                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
588                           ERR_CHANOPRIVSNEEDED, chptr->name);
589 +
590      *errors |= SM_ERR_NOOPS;
591      return;
592    }
# Line 591 | Line 595 | chm_ban(struct Client *source_p, struct
595      return;
596  
597    mask = nuh_mask[*parn];
598 <  memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
598 >  strlcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
599    ++(*parn);
600  
601 <  if (!MyConnect(source_p))
602 <    if (strchr(mask, ' '))
599 <      return;
601 >  if (*mask == ':' || (!MyConnect(source_p) && strchr(mask, ' ')))
602 >    return;
603  
604    switch (dir)
605    {
# Line 635 | Line 638 | chm_except(struct Client *source_p, stru
638  
639      DLINK_FOREACH(node, chptr->exceptlist.head)
640      {
641 <      const struct Ban *banptr = node->data;
641 >      const struct Ban *ban = node->data;
642  
643        sendto_one_numeric(source_p, &me, RPL_EXCEPTLIST, chptr->name,
644 <                         banptr->name, banptr->user, banptr->host,
645 <                         banptr->who, banptr->when);
644 >                         ban->name, ban->user, ban->host,
645 >                         ban->who, ban->when);
646      }
647  
648      sendto_one_numeric(source_p, &me, RPL_ENDOFEXCEPTLIST, chptr->name);
# Line 652 | Line 655 | chm_except(struct Client *source_p, stru
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    }
# Line 660 | Line 664 | chm_except(struct Client *source_p, stru
664      return;
665  
666    mask = nuh_mask[*parn];
667 <  memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
667 >  strlcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
668    ++(*parn);
669  
670 <  if (!MyConnect(source_p))
671 <    if (strchr(mask, ' '))
668 <      return;
670 >  if (*mask == ':' || (!MyConnect(source_p) && strchr(mask, ' ')))
671 >    return;
672  
673    switch (dir)
674    {
# Line 704 | Line 707 | chm_invex(struct Client *source_p, struc
707  
708      DLINK_FOREACH(node, chptr->invexlist.head)
709      {
710 <      const struct Ban *banptr = node->data;
710 >      const struct Ban *ban = node->data;
711  
712        sendto_one_numeric(source_p, &me, RPL_INVEXLIST, chptr->name,
713 <                         banptr->name, banptr->user, banptr->host,
714 <                         banptr->who, banptr->when);
713 >                         ban->name, ban->user, ban->host,
714 >                         ban->who, ban->when);
715      }
716  
717      sendto_one_numeric(source_p, &me, RPL_ENDOFINVEXLIST, chptr->name);
# Line 721 | Line 724 | chm_invex(struct Client *source_p, struc
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    }
# Line 729 | Line 733 | chm_invex(struct Client *source_p, struc
733      return;
734  
735    mask = nuh_mask[*parn];
736 <  memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
736 >  strlcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
737    ++(*parn);
738  
739 <  if (!MyConnect(source_p))
740 <    if (strchr(mask, ' '))
737 <      return;
739 >  if (*mask == ':' || (!MyConnect(source_p) && strchr(mask, ' ')))
740 >    return;
741  
742    switch (dir)
743    {
# Line 769 | Line 772 | chm_voice(struct Client *source_p, struc
772        sendto_one_numeric(source_p, &me,
773                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
774                           ERR_CHANOPRIVSNEEDED, chptr->name);
775 +
776      *errors |= SM_ERR_NOOPS;
777      return;
778    }
# Line 783 | Line 787 | chm_voice(struct Client *source_p, struc
787    {
788      if (!(*errors & SM_ERR_NOTONCHANNEL))
789        sendto_one_numeric(source_p, &me, ERR_USERNOTINCHANNEL, target_p->name, chptr->name);
790 +
791      *errors |= SM_ERR_NOTONCHANNEL;
792      return;
793    }
# Line 793 | Line 798 | chm_voice(struct Client *source_p, struc
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  
# Line 820 | Line 826 | chm_hop(struct Client *source_p, struct
826        sendto_one_numeric(source_p, &me,
827                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
828                           ERR_CHANOPRIVSNEEDED, chptr->name);
829 +
830      *errors |= SM_ERR_NOOPS;
831      return;
832    }
# Line 834 | Line 841 | chm_hop(struct Client *source_p, struct
841    {
842      if (!(*errors & SM_ERR_NOTONCHANNEL))
843        sendto_one_numeric(source_p, &me, ERR_USERNOTINCHANNEL, target_p->name, chptr->name);
844 +
845      *errors |= SM_ERR_NOTONCHANNEL;
846      return;
847    }
# Line 844 | Line 852 | chm_hop(struct Client *source_p, struct
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  
# Line 871 | Line 880 | chm_op(struct Client *source_p, struct C
880        sendto_one_numeric(source_p, &me,
881                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
882                           ERR_CHANOPRIVSNEEDED, chptr->name);
883 +
884      *errors |= SM_ERR_NOOPS;
885      return;
886    }
# Line 885 | Line 895 | chm_op(struct Client *source_p, struct C
895    {
896      if (!(*errors & SM_ERR_NOTONCHANNEL))
897        sendto_one_numeric(source_p, &me, ERR_USERNOTINCHANNEL, target_p->name, chptr->name);
898 +
899      *errors |= SM_ERR_NOTONCHANNEL;
900      return;
901    }
# Line 895 | Line 906 | chm_op(struct Client *source_p, struct C
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  
# Line 930 | Line 942 | chm_limit(struct Client *source_p, struc
942  
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 982 | Line 994 | chm_key(struct Client *source_p, struct
994  
995    if (dir == MODE_ADD && parc > *parn)
996    {
997 <    char *key = fix_key(parv[(*parn)++]);
997 >    char *const key = fix_key(parv[(*parn)++]);
998  
999      if (EmptyString(key))
1000        return;
# Line 1086 | Line 1098 | const 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 1328 | Line 1340 | send_mode_changes_server(struct Client *
1340    parptr = parabuf;
1341  
1342    mbl = snprintf(modebuf, sizeof(modebuf), ":%s TMODE %lu %s ", source_p->id,
1343 <                 (unsigned long)chptr->channelts, chptr->name);
1343 >                 (unsigned long)chptr->creationtime, chptr->name);
1344  
1345    /* Loop the list of modes we have */
1346 <  for (unsigned i = 0; i < mode_count; ++i)
1346 >  for (unsigned int i = 0; i < mode_count; ++i)
1347    {
1348      if (mode_changes[i].letter == 0)
1349        continue;
# Line 1355 | Line 1367 | send_mode_changes_server(struct Client *
1367          (pbl + arglen + BAN_FUDGE) >= MODEBUFLEN)
1368      {
1369        if (nc)
1370 <        sendto_server(source_p, NOCAPS, NOCAPS, "%s %s", modebuf, parabuf);
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->name);
1376 >                     (unsigned long)chptr->creationtime, chptr->name);
1377  
1378        pbl = 0;
1379        parabuf[0] = '\0';
# Line 1392 | Line 1404 | send_mode_changes_server(struct Client *
1404      parabuf[pbl - 1] = '\0';
1405  
1406    if (nc)
1407 <    sendto_server(source_p, NOCAPS, NOCAPS, "%s %s", modebuf, parabuf);
1407 >    sendto_server(source_p, 0, 0, "%s %s", modebuf, parabuf);
1408   }
1409  
1410   /* void send_mode_changes(struct Client *client_p,
# Line 1407 | 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   {
1424    int mbl = 0, pbl = 0, arglen = 0, nc = 0, mc = 0;
1425    int len = 0;
# Line 1415 | Line 1427 | send_mode_changes(struct Client *source_
1427    const char *arg = NULL;
1428    char *parptr = NULL;
1429  
1418 –  /* Bail out if we have nothing to do... */
1419 –  if (!mode_count)
1420 –    return;
1421 –
1430    if (IsServer(source_p))
1431      mbl = snprintf(modebuf, sizeof(modebuf), ":%s MODE %s ", (IsHidden(source_p) ||
1432                     ConfigServerHide.hide_servers) ?
# Line 1492 | Line 1500 | send_mode_changes(struct Client *source_
1500  
1501    if (nc)
1502      sendto_channel_local(0, chptr, "%s %s", modebuf, parabuf);
1495 –
1496 –  send_mode_changes_server(source_p, chptr);
1503   }
1504  
1505   /*
# Line 1543 | Line 1549 | set_channel_mode(struct Client *source_p
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)