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 6782 by michael, Sun Nov 15 18:49:32 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->when = CurrentTime;
187 >  ban->len = len - 2;  /* -2 for ! + @ */
188 >  ban->type = parse_netmask(host, &ban->addr, &ban->bits);
189 >  strlcpy(ban->name, name, sizeof(ban->name));
190 >  strlcpy(ban->user, user, sizeof(ban->user));
191 >  strlcpy(ban->host, host, sizeof(ban->host));
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);
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);
194 >    snprintf(ban->who, sizeof(ban->who), "%s!%s@%s", client_p->name,
195 >             client_p->username, client_p->host);
196 >  else if (IsHidden(client_p) || ConfigServerHide.hide_servers)
197 >    strlcpy(ban->who, me.name, sizeof(ban->who));
198    else
199 <    banptr->who = xstrdup(client_p->name);
199 >    strlcpy(ban->who, client_p->name, sizeof(ban->who));
200  
201 <  dlinkAdd(banptr, &banptr->node, list);
201 >  dlinkAdd(ban, &ban->node, list);
202  
203    return 1;
204   }
# Line 241 | Line 237 | del_id(struct Channel *chptr, char *bani
237     * Re-assemble a new n!u@h and print it back to banid for sending
238     * the mode to the channel.
239     */
240 <  sprintf(banid, "%s!%s@%s", name, user, host);
240 >  snprintf(banid, IRCD_BUFSIZE, "%s!%s@%s", name, user, host);
241  
242    switch (type)
243    {
244      case CHFL_BAN:
245        list = &chptr->banlist;
246 <      clear_ban_cache(chptr);
246 >      clear_ban_cache_channel(chptr);
247        break;
248      case CHFL_EXCEPTION:
249        list = &chptr->exceptlist;
250 <      clear_ban_cache(chptr);
250 >      clear_ban_cache_channel(chptr);
251        break;
252      case CHFL_INVEX:
253        list = &chptr->invexlist;
# Line 263 | Line 259 | del_id(struct Channel *chptr, char *bani
259  
260    DLINK_FOREACH(node, list->head)
261    {
262 <    struct Ban *banptr = node->data;
262 >    struct Ban *ban = node->data;
263  
264 <    if (!irccmp(name, banptr->name) &&
265 <        !irccmp(user, banptr->user) &&
266 <        !irccmp(host, banptr->host))
264 >    if (!irccmp(name, ban->name) &&
265 >        !irccmp(user, ban->user) &&
266 >        !irccmp(host, ban->host))
267      {
268 <      remove_ban(banptr, list);
268 >      remove_ban(ban, list);
269        return 1;
270      }
271    }
# Line 301 | Line 297 | channel_modes(struct Channel *chptr, str
297    {
298      *mbuf++ = 'l';
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        pbuf += sprintf(pbuf, "%d ", chptr->mode.limit);
302    }
303  
# Line 309 | Line 305 | channel_modes(struct Channel *chptr, str
305    {
306      *mbuf++ = 'k';
307  
308 <    if (IsServer(client_p) || HasFlag(client_p, FLAGS_SERVICE) || IsMember(client_p, chptr))
308 >    if (IsServer(client_p) || IsMember(client_p, chptr))
309        sprintf(pbuf, "%s ", chptr->mode.key);
310    }
311  
# Line 347 | Line 343 | fix_key(char *arg)
343   * side effects - clear ban cache
344   */
345   void
346 < clear_ban_cache(struct Channel *chptr)
346 > clear_ban_cache_channel(struct Channel *chptr)
347   {
348    dlink_node *node = NULL;
349  
350    DLINK_FOREACH(node, chptr->locmembers.head)
351    {
352 <    struct Membership *ms = node->data;
353 <    ms->flags &= ~(CHFL_BAN_SILENCED|CHFL_BAN_CHECKED);
352 >    struct Membership *member = node->data;
353 >    member->flags &= ~(CHFL_BAN_SILENCED | CHFL_BAN_CHECKED);
354    }
355   }
356  
# Line 365 | Line 361 | clear_ban_cache_client(struct Client *cl
361  
362    DLINK_FOREACH(node, client_p->channel.head)
363    {
364 <    struct Membership *ms = node->data;
365 <    ms->flags &= ~(CHFL_BAN_SILENCED|CHFL_BAN_CHECKED);
364 >    struct Membership *member = node->data;
365 >    member->flags &= ~(CHFL_BAN_SILENCED | CHFL_BAN_CHECKED);
366    }
367   }
368  
# Line 408 | Line 404 | chm_simple(struct Client *source_p, stru
404        sendto_one_numeric(source_p, &me,
405                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
406                           ERR_CHANOPRIVSNEEDED, chptr->name);
407 +
408      *errors |= SM_ERR_NOOPS;
409      return;
410    }
# Line 458 | Line 455 | chm_registered(struct Client *source_p,
455        sendto_one_numeric(source_p, &me,
456                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
457                           ERR_ONLYSERVERSCANCHANGE, chptr->name);
458 +
459      *errors |= SM_ERR_ONLYSERVER;
460      return;
461    }
# Line 502 | Line 500 | static void
500   chm_operonly(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
501               char **parv, int *errors, int alev, int dir, char c, unsigned int d)
502   {
503 <  if (alev < CHACCESS_CHANOP)
503 >  if (alev < CHACCESS_HALFOP)
504    {
505      if (!(*errors & SM_ERR_NOOPS))
506        sendto_one_numeric(source_p, &me,
# Line 567 | Line 565 | chm_ban(struct Client *source_p, struct
565  
566      DLINK_FOREACH(node, chptr->banlist.head)
567      {
568 <      const struct Ban *banptr = node->data;
568 >      const struct Ban *ban = node->data;
569        sendto_one_numeric(source_p, &me, RPL_BANLIST, chptr->name,
570 <                         banptr->name, banptr->user, banptr->host,
571 <                         banptr->who, banptr->when);
570 >                         ban->name, ban->user, ban->host,
571 >                         ban->who, ban->when);
572      }
573  
574      sendto_one_numeric(source_p, &me, RPL_ENDOFBANLIST, chptr->name);
# Line 583 | Line 581 | chm_ban(struct Client *source_p, struct
581        sendto_one_numeric(source_p, &me,
582                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
583                           ERR_CHANOPRIVSNEEDED, chptr->name);
584 +
585      *errors |= SM_ERR_NOOPS;
586      return;
587    }
# Line 591 | Line 590 | chm_ban(struct Client *source_p, struct
590      return;
591  
592    mask = nuh_mask[*parn];
593 <  memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
593 >  strlcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
594    ++(*parn);
595  
596 <  if (!MyConnect(source_p))
597 <    if (strchr(mask, ' '))
599 <      return;
596 >  if (*mask == ':' || (!MyConnect(source_p) && strchr(mask, ' ')))
597 >    return;
598  
599    switch (dir)
600    {
# Line 635 | Line 633 | chm_except(struct Client *source_p, stru
633  
634      DLINK_FOREACH(node, chptr->exceptlist.head)
635      {
636 <      const struct Ban *banptr = node->data;
636 >      const struct Ban *ban = node->data;
637  
638        sendto_one_numeric(source_p, &me, RPL_EXCEPTLIST, chptr->name,
639 <                         banptr->name, banptr->user, banptr->host,
640 <                         banptr->who, banptr->when);
639 >                         ban->name, ban->user, ban->host,
640 >                         ban->who, ban->when);
641      }
642  
643      sendto_one_numeric(source_p, &me, RPL_ENDOFEXCEPTLIST, chptr->name);
# Line 652 | Line 650 | chm_except(struct Client *source_p, stru
650        sendto_one_numeric(source_p, &me,
651                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
652                           ERR_CHANOPRIVSNEEDED, chptr->name);
653 +
654      *errors |= SM_ERR_NOOPS;
655      return;
656    }
# Line 660 | Line 659 | chm_except(struct Client *source_p, stru
659      return;
660  
661    mask = nuh_mask[*parn];
662 <  memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
662 >  strlcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
663    ++(*parn);
664  
665 <  if (!MyConnect(source_p))
666 <    if (strchr(mask, ' '))
668 <      return;
665 >  if (*mask == ':' || (!MyConnect(source_p) && strchr(mask, ' ')))
666 >    return;
667  
668    switch (dir)
669    {
# Line 704 | Line 702 | chm_invex(struct Client *source_p, struc
702  
703      DLINK_FOREACH(node, chptr->invexlist.head)
704      {
705 <      const struct Ban *banptr = node->data;
705 >      const struct Ban *ban = node->data;
706  
707        sendto_one_numeric(source_p, &me, RPL_INVEXLIST, chptr->name,
708 <                         banptr->name, banptr->user, banptr->host,
709 <                         banptr->who, banptr->when);
708 >                         ban->name, ban->user, ban->host,
709 >                         ban->who, ban->when);
710      }
711  
712      sendto_one_numeric(source_p, &me, RPL_ENDOFINVEXLIST, chptr->name);
# Line 721 | Line 719 | chm_invex(struct Client *source_p, struc
719        sendto_one_numeric(source_p, &me,
720                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
721                           ERR_CHANOPRIVSNEEDED, chptr->name);
722 +
723      *errors |= SM_ERR_NOOPS;
724      return;
725    }
# Line 729 | Line 728 | chm_invex(struct Client *source_p, struc
728      return;
729  
730    mask = nuh_mask[*parn];
731 <  memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
731 >  strlcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
732    ++(*parn);
733  
734 <  if (!MyConnect(source_p))
735 <    if (strchr(mask, ' '))
737 <      return;
734 >  if (*mask == ':' || (!MyConnect(source_p) && strchr(mask, ' ')))
735 >    return;
736  
737    switch (dir)
738    {
# Line 769 | Line 767 | chm_voice(struct Client *source_p, struc
767        sendto_one_numeric(source_p, &me,
768                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
769                           ERR_CHANOPRIVSNEEDED, chptr->name);
770 +
771      *errors |= SM_ERR_NOOPS;
772      return;
773    }
# Line 783 | Line 782 | chm_voice(struct Client *source_p, struc
782    {
783      if (!(*errors & SM_ERR_NOTONCHANNEL))
784        sendto_one_numeric(source_p, &me, ERR_USERNOTINCHANNEL, target_p->name, chptr->name);
785 +
786      *errors |= SM_ERR_NOTONCHANNEL;
787      return;
788    }
# Line 793 | Line 793 | chm_voice(struct Client *source_p, struc
793    /* no redundant mode changes */
794    if (dir == MODE_ADD &&  has_member_flags(member, CHFL_VOICE))
795      return;
796 +
797    if (dir == MODE_DEL && !has_member_flags(member, CHFL_VOICE))
798      return;
799  
# Line 820 | Line 821 | chm_hop(struct Client *source_p, struct
821        sendto_one_numeric(source_p, &me,
822                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
823                           ERR_CHANOPRIVSNEEDED, chptr->name);
824 +
825      *errors |= SM_ERR_NOOPS;
826      return;
827    }
# Line 834 | Line 836 | chm_hop(struct Client *source_p, struct
836    {
837      if (!(*errors & SM_ERR_NOTONCHANNEL))
838        sendto_one_numeric(source_p, &me, ERR_USERNOTINCHANNEL, target_p->name, chptr->name);
839 +
840      *errors |= SM_ERR_NOTONCHANNEL;
841      return;
842    }
# Line 844 | Line 847 | chm_hop(struct Client *source_p, struct
847    /* no redundant mode changes */
848    if (dir == MODE_ADD &&  has_member_flags(member, CHFL_HALFOP))
849      return;
850 +
851    if (dir == MODE_DEL && !has_member_flags(member, CHFL_HALFOP))
852      return;
853  
# Line 871 | Line 875 | chm_op(struct Client *source_p, struct C
875        sendto_one_numeric(source_p, &me,
876                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
877                           ERR_CHANOPRIVSNEEDED, chptr->name);
878 +
879      *errors |= SM_ERR_NOOPS;
880      return;
881    }
# Line 885 | Line 890 | chm_op(struct Client *source_p, struct C
890    {
891      if (!(*errors & SM_ERR_NOTONCHANNEL))
892        sendto_one_numeric(source_p, &me, ERR_USERNOTINCHANNEL, target_p->name, chptr->name);
893 +
894      *errors |= SM_ERR_NOTONCHANNEL;
895      return;
896    }
# Line 895 | Line 901 | chm_op(struct Client *source_p, struct C
901    /* no redundant mode changes */
902    if (dir == MODE_ADD &&  has_member_flags(member, CHFL_CHANOP))
903      return;
904 +
905    if (dir == MODE_DEL && !has_member_flags(member, CHFL_CHANOP))
906      return;
907  
# Line 930 | Line 937 | chm_limit(struct Client *source_p, struc
937  
938    if (dir == MODE_ADD && parc > *parn)
939    {
940 <    char *lstr = parv[(*parn)++];
940 >    char *const lstr = parv[(*parn)++];
941  
942      if (EmptyString(lstr) || (limit = atoi(lstr)) <= 0)
943        return;
# Line 982 | Line 989 | chm_key(struct Client *source_p, struct
989  
990    if (dir == MODE_ADD && parc > *parn)
991    {
992 <    char *key = fix_key(parv[(*parn)++]);
992 >    char *const key = fix_key(parv[(*parn)++]);
993  
994      if (EmptyString(key))
995        return;
# Line 1086 | Line 1093 | const struct ChannelMode ModeTable[256]
1093    { chm_nosuch,  0 },                   /* @ */
1094    { chm_nosuch,  0 },                   /* A */
1095    { chm_nosuch,  0 },                   /* B */
1096 <  { chm_nosuch,  0 },                   /* C */
1096 >  { chm_simple,  MODE_NOCTCP },         /* C */
1097    { chm_nosuch,  0 },                   /* D */
1098    { chm_nosuch,  0 },                   /* E */
1099    { chm_nosuch,  0 },                   /* F */
# Line 1327 | Line 1334 | send_mode_changes_server(struct Client *
1334    parabuf[0] = '\0';
1335    parptr = parabuf;
1336  
1337 <  mbl = snprintf(modebuf, sizeof(modebuf), ":%s TMODE %lu %s ", source_p->id,
1338 <                 (unsigned long)chptr->channelts, chptr->name);
1337 >  mbl = snprintf(modebuf, sizeof(modebuf), ":%s TMODE %ju %s ", source_p->id,
1338 >                 chptr->creationtime, chptr->name);
1339  
1340    /* Loop the list of modes we have */
1341 <  for (unsigned i = 0; i < mode_count; ++i)
1341 >  for (unsigned int i = 0; i < mode_count; ++i)
1342    {
1343      if (mode_changes[i].letter == 0)
1344        continue;
# Line 1355 | Line 1362 | send_mode_changes_server(struct Client *
1362          (pbl + arglen + BAN_FUDGE) >= MODEBUFLEN)
1363      {
1364        if (nc)
1365 <        sendto_server(source_p, NOCAPS, NOCAPS, "%s %s", modebuf, parabuf);
1365 >        sendto_server(source_p, 0, 0, "%s %s", modebuf, parabuf);
1366  
1367        nc = 0;
1368        mc = 0;
1369  
1370 <      mbl = snprintf(modebuf, sizeof(modebuf), ":%s TMODE %lu %s ", source_p->id,
1371 <                     (unsigned long)chptr->channelts, chptr->name);
1370 >      mbl = snprintf(modebuf, sizeof(modebuf), ":%s TMODE %ju %s ", source_p->id,
1371 >                     chptr->creationtime, chptr->name);
1372  
1373        pbl = 0;
1374        parabuf[0] = '\0';
# Line 1392 | Line 1399 | send_mode_changes_server(struct Client *
1399      parabuf[pbl - 1] = '\0';
1400  
1401    if (nc)
1402 <    sendto_server(source_p, NOCAPS, NOCAPS, "%s %s", modebuf, parabuf);
1402 >    sendto_server(source_p, 0, 0, "%s %s", modebuf, parabuf);
1403   }
1404  
1405   /* void send_mode_changes(struct Client *client_p,
# Line 1407 | Line 1414 | send_mode_changes_server(struct Client *
1414   */
1415   /* ensure parabuf < MODEBUFLEN -db */
1416   static void
1417 < send_mode_changes(struct Client *source_p, struct Channel *chptr)
1417 > send_mode_changes_client(struct Client *source_p, struct Channel *chptr)
1418   {
1419    int mbl = 0, pbl = 0, arglen = 0, nc = 0, mc = 0;
1420    int len = 0;
# Line 1415 | Line 1422 | send_mode_changes(struct Client *source_
1422    const char *arg = NULL;
1423    char *parptr = NULL;
1424  
1418 –  /* Bail out if we have nothing to do... */
1419 –  if (!mode_count)
1420 –    return;
1421 –
1425    if (IsServer(source_p))
1426      mbl = snprintf(modebuf, sizeof(modebuf), ":%s MODE %s ", (IsHidden(source_p) ||
1427                     ConfigServerHide.hide_servers) ?
# Line 1449 | Line 1452 | send_mode_changes(struct Client *source_
1452          modebuf[mbl - 1] = '\0';
1453  
1454        if (nc)
1455 <        sendto_channel_local(0, chptr, "%s %s", modebuf, parabuf);
1455 >        sendto_channel_local(NULL, chptr, 0, 0, 0, "%s %s", modebuf, parabuf);
1456  
1457        nc = 0;
1458        mc = 0;
# Line 1491 | Line 1494 | send_mode_changes(struct Client *source_
1494      parabuf[pbl - 1] = '\0';
1495  
1496    if (nc)
1497 <    sendto_channel_local(0, chptr, "%s %s", modebuf, parabuf);
1495 <
1496 <  send_mode_changes_server(source_p, chptr);
1497 >    sendto_channel_local(NULL, chptr, 0, 0, 0, "%s %s", modebuf, parabuf);
1498   }
1499  
1500   /*
# Line 1543 | Line 1544 | set_channel_mode(struct Client *source_p
1544      }
1545    }
1546  
1547 <  send_mode_changes(source_p, chptr);
1547 >  /* Bail out if we have nothing to do... */
1548 >  if (!mode_count)
1549 >    return;
1550 >
1551 >  send_mode_changes_client(source_p, chptr);
1552 >  send_mode_changes_server(source_p, chptr);
1553   }

Diff Legend

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