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 3648 by michael, Mon May 26 14:11:18 2014 UTC vs.
Revision 4833 by michael, Sun Nov 2 11:45:04 2014 UTC

# 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 83 | Line 83 | const struct mode_letter chan_modes[] =
83   static char *
84   check_string(char *s)
85   {
86 <  char *str = s;
86 >  char *const str = s;
87    static char star[] = "*";
88  
89    if (EmptyString(str))
# Line 112 | Line 112 | int
112   add_id(struct Client *client_p, struct Channel *chptr, char *banid, unsigned int type)
113   {
114    dlink_list *list = NULL;
115 <  dlink_node *ban = NULL;
116 <  struct Ban *ban_p = NULL;
117 <  unsigned int num_mask;
115 >  dlink_node *node = NULL;
116 >  struct Ban *ban = NULL;
117    size_t len = 0;
118    char name[NICKLEN + 1] = "";
119    char user[USERLEN + 1] = "";
# Line 124 | Line 123 | add_id(struct Client *client_p, struct C
123    /* Don't let local clients overflow the b/e/I lists */
124    if (MyClient(client_p))
125    {
126 <    num_mask = dlink_list_length(&chptr->banlist) +
127 <               dlink_list_length(&chptr->exceptlist) +
128 <               dlink_list_length(&chptr->invexlist);
126 >    unsigned int num_mask = dlink_list_length(&chptr->banlist) +
127 >                            dlink_list_length(&chptr->exceptlist) +
128 >                            dlink_list_length(&chptr->invexlist);
129  
130      if (num_mask >= ConfigChannel.max_bans)
131      {
132 <      sendto_one_numeric(client_p, &me, ERR_BANLISTFULL, chptr->chname, banid);
132 >      sendto_one_numeric(client_p, &me, ERR_BANLISTFULL, chptr->name, banid);
133        return 0;
134      }
135  
# Line 152 | Line 151 | add_id(struct Client *client_p, struct C
151     * Re-assemble a new n!u@h and print it back to banid for sending
152     * the mode to the channel.
153     */
154 <  len = sprintf(banid, "%s!%s@%s", name, user, host);
154 >  len = snprintf(banid, IRCD_BUFSIZE, "%s!%s@%s", name, user, host);
155  
156    switch (type)
157    {
# Line 172 | Line 171 | add_id(struct Client *client_p, struct C
171        return 0;
172    }
173  
174 <  DLINK_FOREACH(ban, list->head)
174 >  DLINK_FOREACH(node, list->head)
175    {
176 <    ban_p = ban->data;
176 >    ban = node->data;
177  
178 <    if (!irccmp(ban_p->name, name) &&
179 <        !irccmp(ban_p->user, user) &&
180 <        !irccmp(ban_p->host, host))
178 >    if (!irccmp(ban->name, name) &&
179 >        !irccmp(ban->user, user) &&
180 >        !irccmp(ban->host, host))
181        return 0;
182    }
183  
184 <  ban_p = mp_pool_get(ban_pool);
185 <  memset(ban_p, 0, sizeof(*ban_p));
186 <  ban_p->name = xstrdup(name);
187 <  ban_p->user = xstrdup(user);
188 <  ban_p->host = xstrdup(host);
189 <  ban_p->when = CurrentTime;
190 <  ban_p->len = len - 2;  /* -2 for @ and ! */
192 <  ban_p->type = parse_netmask(host, &ban_p->addr, &ban_p->bits);
184 >  ban = mp_pool_get(ban_pool);
185 >  ban->name = xstrdup(name);
186 >  ban->user = xstrdup(user);
187 >  ban->host = xstrdup(host);
188 >  ban->when = CurrentTime;
189 >  ban->len = len - 2;  /* -2 for ! + @ */
190 >  ban->type = parse_netmask(host, &ban->addr, &ban->bits);
191  
192    if (IsClient(client_p))
193    {
194 <    ban_p->who = MyCalloc(strlen(client_p->name) +
195 <                          strlen(client_p->username) +
196 <                          strlen(client_p->host) + 3);
197 <    sprintf(ban_p->who, "%s!%s@%s", client_p->name,
194 >    ban->who = MyCalloc(strlen(client_p->name) +
195 >                        strlen(client_p->username) +
196 >                        strlen(client_p->host) + 3);
197 >    sprintf(ban->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 <    ban_p->who = xstrdup(me.name);
201 >    ban->who = xstrdup(me.name);
202    else
203 <    ban_p->who = xstrdup(client_p->name);
203 >    ban->who = xstrdup(client_p->name);
204  
205 <  dlinkAdd(ban_p, &ban_p->node, list);
205 >  dlinkAdd(ban, &ban->node, list);
206  
207    return 1;
208   }
# Line 220 | Line 218 | static int
218   del_id(struct Channel *chptr, char *banid, unsigned int type)
219   {
220    dlink_list *list = NULL;
221 <  dlink_node *ban = NULL;
221 >  dlink_node *node = NULL;
222    char name[NICKLEN + 1] = "";
223    char user[USERLEN + 1] = "";
224    char host[HOSTLEN + 1] = "";
# Line 243 | Line 241 | del_id(struct Channel *chptr, char *bani
241     * Re-assemble a new n!u@h and print it back to banid for sending
242     * the mode to the channel.
243     */
244 <  sprintf(banid, "%s!%s@%s", name, user, host);
244 >  snprintf(banid, IRCD_BUFSIZE, "%s!%s@%s", name, user, host);
245  
246    switch (type)
247    {
# Line 263 | Line 261 | del_id(struct Channel *chptr, char *bani
261        return 0;
262    }
263  
264 <  DLINK_FOREACH(ban, list->head)
264 >  DLINK_FOREACH(node, list->head)
265    {
266 <    struct Ban *banptr = ban->data;
266 >    struct Ban *ban = node->data;
267  
268 <    if (!irccmp(name, banptr->name) &&
269 <        !irccmp(user, banptr->user) &&
270 <        !irccmp(host, banptr->host))
268 >    if (!irccmp(name, ban->name) &&
269 >        !irccmp(user, ban->user) &&
270 >        !irccmp(host, ban->host))
271      {
272 <      remove_ban(banptr, list);
272 >      remove_ban(ban, list);
273        return 1;
274      }
275    }
# Line 290 | Line 288 | del_id(struct Channel *chptr, char *bani
288   * chptr onto buffer mbuf with the parameters in pbuf.
289   */
290   void
291 < channel_modes(struct Channel *chptr, struct Client *client_p,
294 <              char *mbuf, char *pbuf)
291 > channel_modes(struct Channel *chptr, struct Client *client_p, char *mbuf, char *pbuf)
292   {
296  const struct mode_letter *tab = chan_modes;
297
293    *mbuf++ = '+';
294    *pbuf = '\0';
295  
296 <  for (; tab->mode; ++tab)
296 >  for (const struct mode_letter *tab = chan_modes; tab->mode; ++tab)
297      if (chptr->mode.mode & tab->mode)
298        *mbuf++ = tab->letter;
299  
# Line 346 | Line 341 | fix_key(char *arg)
341    return arg;
342   }
343  
349 /* fix_key_old()
350 *
351 * inputs       - pointer to key to clean up
352 * output       - pointer to cleaned up key
353 * side effects - input string is modifed
354 *
355 * Here we attempt to be compatible with older non-hybrid servers.
356 * We can't back down from the ':' issue however.  --Rodder
357 */
358 static char *
359 fix_key_old(char *arg)
360 {
361  unsigned char *s, *t, c;
362
363  for (s = t = (unsigned char *)arg; (c = *s); ++s)
364  {
365    c &= 0x7f;
366
367    if ((c != 0x0a) && (c != ':') &&
368        (c != 0x0d) && (c != ','))
369      *t++ = c;
370  }
371
372  *t = '\0';
373  return arg;
374 }
375
344   /*
345   * inputs       - pointer to channel
346   * output       - none
# Line 381 | Line 349 | fix_key_old(char *arg)
349   void
350   clear_ban_cache(struct Channel *chptr)
351   {
352 <  dlink_node *ptr = NULL;
352 >  dlink_node *node = NULL;
353  
354 <  DLINK_FOREACH(ptr, chptr->members.head)
354 >  DLINK_FOREACH(node, chptr->locmembers.head)
355    {
356 <    struct Membership *ms = ptr->data;
357 <
390 <    if (MyConnect(ms->client_p))
391 <      ms->flags &= ~(CHFL_BAN_SILENCED|CHFL_BAN_CHECKED);
356 >    struct Membership *member = node->data;
357 >    member->flags &= ~(CHFL_BAN_SILENCED|CHFL_BAN_CHECKED);
358    }
359   }
360  
361   void
362   clear_ban_cache_client(struct Client *client_p)
363   {
364 <  dlink_node *ptr = NULL;
364 >  dlink_node *node = NULL;
365  
366 <  DLINK_FOREACH(ptr, client_p->channel.head)
366 >  DLINK_FOREACH(node, client_p->channel.head)
367    {
368 <    struct Membership *ms = ptr->data;
369 <    ms->flags &= ~(CHFL_BAN_SILENCED|CHFL_BAN_CHECKED);
368 >    struct Membership *member = node->data;
369 >    member->flags &= ~(CHFL_BAN_SILENCED|CHFL_BAN_CHECKED);
370    }
371   }
372  
# Line 436 | Line 402 | static void
402   chm_simple(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
403             char **parv, int *errors, int alev, int dir, char c, unsigned int d)
404   {
405 <  if ((alev < CHACCESS_HALFOP) ||
440 <      ((d == MODE_PRIVATE) && (alev < CHACCESS_CHANOP)))
405 >  if (alev < CHACCESS_HALFOP)
406    {
407      if (!(*errors & SM_ERR_NOOPS))
408        sendto_one_numeric(source_p, &me,
409                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
410 <                         ERR_CHANOPRIVSNEEDED, chptr->chname);
410 >                         ERR_CHANOPRIVSNEEDED, chptr->name);
411      *errors |= SM_ERR_NOOPS;
412      return;
413    }
# Line 466 | Line 431 | chm_simple(struct Client *source_p, stru
431      chptr->mode.mode |= d;
432  
433      mode_changes[mode_count].letter = c;
434 <    mode_changes[mode_count].dir = MODE_ADD;
434 >    mode_changes[mode_count].arg = NULL;
435      mode_changes[mode_count].id = NULL;
436 <    mode_changes[mode_count].mems = ALL_MEMBERS;
472 <    mode_changes[mode_count++].arg = NULL;
436 >    mode_changes[mode_count++].dir = dir;
437    }
438    else if (dir == MODE_DEL) /* && (chptr->mode.mode & d)) */
439    {
# Line 478 | Line 442 | chm_simple(struct Client *source_p, stru
442      chptr->mode.mode &= ~d;
443  
444      mode_changes[mode_count].letter = c;
445 <    mode_changes[mode_count].dir = MODE_DEL;
482 <    mode_changes[mode_count].mems = ALL_MEMBERS;
445 >    mode_changes[mode_count].arg = NULL;
446      mode_changes[mode_count].id = NULL;
447 <    mode_changes[mode_count++].arg = NULL;
447 >    mode_changes[mode_count++].dir = dir;
448    }
449   }
450  
# Line 494 | Line 457 | chm_registered(struct Client *source_p,
457      if (!(*errors & SM_ERR_ONLYSERVER))
458        sendto_one_numeric(source_p, &me,
459                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
460 <                         ERR_ONLYSERVERSCANCHANGE, chptr->chname);
460 >                         ERR_ONLYSERVERSCANCHANGE, chptr->name);
461      *errors |= SM_ERR_ONLYSERVER;
462      return;
463    }
# Line 518 | Line 481 | chm_registered(struct Client *source_p,
481      chptr->mode.mode |= d;
482  
483      mode_changes[mode_count].letter = c;
484 <    mode_changes[mode_count].dir = MODE_ADD;
484 >    mode_changes[mode_count].arg = NULL;
485      mode_changes[mode_count].id = NULL;
486 <    mode_changes[mode_count].mems = ALL_MEMBERS;
524 <    mode_changes[mode_count++].arg = NULL;
486 >    mode_changes[mode_count++].dir = dir;
487    }
488    else if (dir == MODE_DEL) /* && (chptr->mode.mode & d)) */
489    {
# Line 530 | Line 492 | chm_registered(struct Client *source_p,
492      chptr->mode.mode &= ~d;
493  
494      mode_changes[mode_count].letter = c;
495 <    mode_changes[mode_count].dir = MODE_DEL;
534 <    mode_changes[mode_count].mems = ALL_MEMBERS;
495 >    mode_changes[mode_count].arg = NULL;
496      mode_changes[mode_count].id = NULL;
497 <    mode_changes[mode_count++].arg = NULL;
497 >    mode_changes[mode_count++].dir = dir;
498    }
499   }
500  
501   static void
502 < chm_operonly(struct Client *source_p, struct Channel *chptr,
503 <             int parc, int *parn, char **parv, int *errors, int alev, int dir,
543 <             char c, unsigned int d)
502 > chm_operonly(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
503 >             char **parv, int *errors, int alev, int dir, char c, unsigned int d)
504   {
505 <  if ((alev < CHACCESS_HALFOP) || ((d == MODE_PRIVATE) && (alev < CHACCESS_CHANOP)))
505 >  if (alev < CHACCESS_CHANOP)
506    {
507      if (!(*errors & SM_ERR_NOOPS))
508        sendto_one_numeric(source_p, &me,
509                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
510 <                         ERR_CHANOPRIVSNEEDED, chptr->chname);
510 >                         ERR_CHANOPRIVSNEEDED, chptr->name);
511  
512      *errors |= SM_ERR_NOOPS;
513      return;
# Line 573 | Line 533 | chm_operonly(struct Client *source_p, st
533      chptr->mode.mode |= d;
534  
535      mode_changes[mode_count].letter = c;
536 <    mode_changes[mode_count].dir = MODE_ADD;
536 >    mode_changes[mode_count].arg = NULL;
537      mode_changes[mode_count].id = NULL;
538 <    mode_changes[mode_count].mems = ALL_MEMBERS;
579 <    mode_changes[mode_count++].arg = NULL;
538 >    mode_changes[mode_count++].dir = dir;
539    }
540    else if (dir == MODE_DEL) /* && (chptr->mode.mode & d)) */
541    {
# Line 585 | Line 544 | chm_operonly(struct Client *source_p, st
544      chptr->mode.mode &= ~d;
545  
546      mode_changes[mode_count].letter = c;
547 <    mode_changes[mode_count].dir = MODE_DEL;
589 <    mode_changes[mode_count].mems = ALL_MEMBERS;
547 >    mode_changes[mode_count].arg = NULL;
548      mode_changes[mode_count].id = NULL;
549 <    mode_changes[mode_count++].arg = NULL;
549 >    mode_changes[mode_count++].dir = dir;
550    }
551   }
552  
# Line 600 | Line 558 | chm_ban(struct Client *source_p, struct
558  
559    if (dir == MODE_QUERY || parc <= *parn)
560    {
561 <    dlink_node *ptr = NULL;
561 >    dlink_node *node = NULL;
562  
563      if (*errors & SM_ERR_RPL_B)
564        return;
565  
566      *errors |= SM_ERR_RPL_B;
567  
568 <    DLINK_FOREACH(ptr, chptr->banlist.head)
568 >    DLINK_FOREACH(node, chptr->banlist.head)
569      {
570 <      const struct Ban *banptr = ptr->data;
571 <      sendto_one_numeric(source_p, &me, RPL_BANLIST, chptr->chname,
572 <                         banptr->name, banptr->user, banptr->host,
573 <                         banptr->who, banptr->when);
570 >      const struct Ban *ban = node->data;
571 >      sendto_one_numeric(source_p, &me, RPL_BANLIST, chptr->name,
572 >                         ban->name, ban->user, ban->host,
573 >                         ban->who, ban->when);
574      }
575  
576 <    sendto_one_numeric(source_p, &me, RPL_ENDOFBANLIST, chptr->chname);
576 >    sendto_one_numeric(source_p, &me, RPL_ENDOFBANLIST, chptr->name);
577      return;
578    }
579  
# Line 624 | Line 582 | chm_ban(struct Client *source_p, struct
582      if (!(*errors & SM_ERR_NOOPS))
583        sendto_one_numeric(source_p, &me,
584                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
585 <                         ERR_CHANOPRIVSNEEDED, chptr->chname);
585 >                         ERR_CHANOPRIVSNEEDED, chptr->name);
586      *errors |= SM_ERR_NOOPS;
587      return;
588    }
# Line 634 | Line 592 | chm_ban(struct Client *source_p, struct
592  
593    mask = nuh_mask[*parn];
594    memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
595 <  ++*parn;
595 >  ++(*parn);
596  
597    if (!MyConnect(source_p))
598      if (strchr(mask, ' '))
# Line 655 | Line 613 | chm_ban(struct Client *source_p, struct
613    }
614  
615    mode_changes[mode_count].letter = c;
616 <  mode_changes[mode_count].dir = dir;
659 <  mode_changes[mode_count].mems = ALL_MEMBERS;
616 >  mode_changes[mode_count].arg = mask;
617    mode_changes[mode_count].id = NULL;
618 <  mode_changes[mode_count++].arg = mask;
618 >  mode_changes[mode_count++].dir = dir;
619   }
620  
621   static void
# Line 667 | Line 624 | chm_except(struct Client *source_p, stru
624   {
625    char *mask = NULL;
626  
670  if (alev < CHACCESS_HALFOP)
671  {
672    if (!(*errors & SM_ERR_NOOPS))
673      sendto_one_numeric(source_p, &me,
674                         alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
675                         ERR_CHANOPRIVSNEEDED, chptr->chname);
676    *errors |= SM_ERR_NOOPS;
677    return;
678  }
679
627    if (dir == MODE_QUERY || parc <= *parn)
628    {
629 <    dlink_node *ptr = NULL;
629 >    dlink_node *node = NULL;
630  
631      if (*errors & SM_ERR_RPL_E)
632        return;
633  
634      *errors |= SM_ERR_RPL_E;
635  
636 <    DLINK_FOREACH(ptr, chptr->exceptlist.head)
636 >    DLINK_FOREACH(node, chptr->exceptlist.head)
637      {
638 <      const struct Ban *banptr = ptr->data;
638 >      const struct Ban *ban = node->data;
639  
640 <      sendto_one_numeric(source_p, &me, RPL_EXCEPTLIST, chptr->chname,
641 <                         banptr->name, banptr->user, banptr->host,
642 <                         banptr->who, banptr->when);
640 >      sendto_one_numeric(source_p, &me, RPL_EXCEPTLIST, chptr->name,
641 >                         ban->name, ban->user, ban->host,
642 >                         ban->who, ban->when);
643      }
644  
645 <    sendto_one_numeric(source_p, &me, RPL_ENDOFEXCEPTLIST, chptr->chname);
645 >    sendto_one_numeric(source_p, &me, RPL_ENDOFEXCEPTLIST, chptr->name);
646 >    return;
647 >  }
648 >
649 >  if (alev < CHACCESS_HALFOP)
650 >  {
651 >    if (!(*errors & SM_ERR_NOOPS))
652 >      sendto_one_numeric(source_p, &me,
653 >                         alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
654 >                         ERR_CHANOPRIVSNEEDED, chptr->name);
655 >    *errors |= SM_ERR_NOOPS;
656      return;
657    }
658  
# Line 704 | Line 661 | chm_except(struct Client *source_p, stru
661  
662    mask = nuh_mask[*parn];
663    memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
664 <  ++*parn;
664 >  ++(*parn);
665  
666    if (!MyConnect(source_p))
667      if (strchr(mask, ' '))
# Line 725 | Line 682 | chm_except(struct Client *source_p, stru
682    }
683  
684    mode_changes[mode_count].letter = c;
685 <  mode_changes[mode_count].dir = dir;
729 <  mode_changes[mode_count].mems = ONLY_CHANOPS;
685 >  mode_changes[mode_count].arg = mask;
686    mode_changes[mode_count].id = NULL;
687 <  mode_changes[mode_count++].arg = mask;
687 >  mode_changes[mode_count++].dir = dir;
688   }
689  
690   static void
# Line 737 | Line 693 | chm_invex(struct Client *source_p, struc
693   {
694    char *mask = NULL;
695  
740  if (alev < CHACCESS_HALFOP)
741  {
742    if (!(*errors & SM_ERR_NOOPS))
743      sendto_one_numeric(source_p, &me,
744                         alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
745                         ERR_CHANOPRIVSNEEDED, chptr->chname);
746    *errors |= SM_ERR_NOOPS;
747    return;
748  }
749
696    if (dir == MODE_QUERY || parc <= *parn)
697    {
698 <    dlink_node *ptr = NULL;
698 >    dlink_node *node = NULL;
699  
700      if (*errors & SM_ERR_RPL_I)
701        return;
702  
703      *errors |= SM_ERR_RPL_I;
704  
705 <    DLINK_FOREACH(ptr, chptr->invexlist.head)
705 >    DLINK_FOREACH(node, chptr->invexlist.head)
706      {
707 <      const struct Ban *banptr = ptr->data;
707 >      const struct Ban *ban = node->data;
708  
709 <      sendto_one_numeric(source_p, &me, RPL_INVITELIST, chptr->chname,
710 <                         banptr->name, banptr->user, banptr->host,
711 <                         banptr->who, banptr->when);
709 >      sendto_one_numeric(source_p, &me, RPL_INVEXLIST, chptr->name,
710 >                         ban->name, ban->user, ban->host,
711 >                         ban->who, ban->when);
712      }
713  
714 <    sendto_one_numeric(source_p, &me, RPL_ENDOFINVITELIST, chptr->chname);
714 >    sendto_one_numeric(source_p, &me, RPL_ENDOFINVEXLIST, chptr->name);
715 >    return;
716 >  }
717 >
718 >  if (alev < CHACCESS_HALFOP)
719 >  {
720 >    if (!(*errors & SM_ERR_NOOPS))
721 >      sendto_one_numeric(source_p, &me,
722 >                         alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
723 >                         ERR_CHANOPRIVSNEEDED, chptr->name);
724 >    *errors |= SM_ERR_NOOPS;
725      return;
726    }
727  
# Line 774 | Line 730 | chm_invex(struct Client *source_p, struc
730  
731    mask = nuh_mask[*parn];
732    memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
733 <  ++*parn;
733 >  ++(*parn);
734  
735    if (!MyConnect(source_p))
736      if (strchr(mask, ' '))
# Line 795 | Line 751 | chm_invex(struct Client *source_p, struc
751    }
752  
753    mode_changes[mode_count].letter = c;
754 <  mode_changes[mode_count].dir = dir;
799 <  mode_changes[mode_count].mems = ONLY_CHANOPS;
754 >  mode_changes[mode_count].arg = mask;
755    mode_changes[mode_count].id = NULL;
756 <  mode_changes[mode_count++].arg = mask;
756 >  mode_changes[mode_count++].dir = dir;
757   }
758  
759   static void
760   chm_voice(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
761            char **parv, int *errors, int alev, int dir, char c, unsigned int d)
762   {
808  const char *opnick = NULL;
763    struct Client *target_p;
764    struct Membership *member;
765  
# Line 814 | Line 768 | chm_voice(struct Client *source_p, struc
768      if (!(*errors & SM_ERR_NOOPS))
769        sendto_one_numeric(source_p, &me,
770                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
771 <                         ERR_CHANOPRIVSNEEDED, chptr->chname);
771 >                         ERR_CHANOPRIVSNEEDED, chptr->name);
772      *errors |= SM_ERR_NOOPS;
773      return;
774    }
775  
776 <  if ((dir == MODE_QUERY) || parc <= *parn)
776 >  if (dir == MODE_QUERY || parc <= *parn)
777      return;
778  
779 <  opnick = parv[(*parn)++];
780 <
827 <  if ((target_p = find_chasing(source_p, opnick)) == NULL)
828 <    return;
779 >  if ((target_p = find_chasing(source_p, parv[(*parn)++])) == NULL)
780 >    return;  /* find_chasing sends ERR_NOSUCHNICK */
781  
782    if ((member = find_channel_link(target_p, chptr)) == NULL)
783    {
784      if (!(*errors & SM_ERR_NOTONCHANNEL))
785 <      sendto_one_numeric(source_p, &me, ERR_USERNOTINCHANNEL, opnick, chptr->chname);
785 >      sendto_one_numeric(source_p, &me, ERR_USERNOTINCHANNEL, target_p->name, chptr->name);
786      *errors |= SM_ERR_NOTONCHANNEL;
787      return;
788    }
# Line 844 | Line 796 | chm_voice(struct Client *source_p, struc
796    if (dir == MODE_DEL && !has_member_flags(member, CHFL_VOICE))
797      return;
798  
799 <  mode_changes[mode_count].letter = 'v';
848 <  mode_changes[mode_count].dir = dir;
849 <  mode_changes[mode_count].mems = ALL_MEMBERS;
850 <  mode_changes[mode_count].id = target_p->id;
799 >  mode_changes[mode_count].letter = c;
800    mode_changes[mode_count].arg = target_p->name;
801 <  mode_changes[mode_count++].client = target_p;
801 >  mode_changes[mode_count].id = target_p->id;
802 >  mode_changes[mode_count++].dir = dir;
803  
804    if (dir == MODE_ADD)
805      AddMemberFlag(member, CHFL_VOICE);
# Line 857 | Line 807 | chm_voice(struct Client *source_p, struc
807      DelMemberFlag(member, CHFL_VOICE);
808   }
809  
860 #ifdef HALFOPS
810   static void
811   chm_hop(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
812          char **parv, int *errors, int alev, int dir, char c, unsigned int d)
813   {
865  const char *opnick = NULL;
814    struct Client *target_p;
815    struct Membership *member;
816  
817 <  /* *sigh* - dont allow halfops to set +/-h, they could fully control a
870 <   * channel if there were no ops - it doesnt solve anything.. MODE_PRIVATE
871 <   * when used with MODE_SECRET is paranoid - cant use +p
872 <   *
873 <   * it needs to be optional per channel - but not via +p, that or remove
874 <   * paranoid.. -- fl_
875 <   *
876 <   * +p means paranoid, it is useless for anything else on modern IRC, as
877 <   * list isn't really usable. If you want to have a private channel these
878 <   * days, you set it +s. Halfops can no longer remove simple modes when
879 <   * +p is set (although they can set +p) so it is safe to use this to
880 <   * control whether they can (de)halfop...
881 <   */
882 <  if (alev <
883 <      ((chptr->mode.mode & MODE_PRIVATE) ? CHACCESS_CHANOP : CHACCESS_HALFOP))
817 >  if (alev < CHACCESS_CHANOP)
818    {
819      if (!(*errors & SM_ERR_NOOPS))
820        sendto_one_numeric(source_p, &me,
821                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
822 <                         ERR_CHANOPRIVSNEEDED, chptr->chname);
822 >                         ERR_CHANOPRIVSNEEDED, chptr->name);
823      *errors |= SM_ERR_NOOPS;
824      return;
825    }
826  
827 <  if ((dir == MODE_QUERY) || (parc <= *parn))
827 >  if (dir == MODE_QUERY || parc <= *parn)
828      return;
829  
830 <  opnick = parv[(*parn)++];
831 <
898 <  if ((target_p = find_chasing(source_p, opnick)) == NULL)
899 <    return;
830 >  if ((target_p = find_chasing(source_p, parv[(*parn)++])) == NULL)
831 >    return;  /* find_chasing sends ERR_NOSUCHNICK */
832  
833    if ((member = find_channel_link(target_p, chptr)) == NULL)
834    {
835      if (!(*errors & SM_ERR_NOTONCHANNEL))
836 <      sendto_one_numeric(source_p, &me, ERR_USERNOTINCHANNEL, opnick, chptr->chname);
836 >      sendto_one_numeric(source_p, &me, ERR_USERNOTINCHANNEL, target_p->name, chptr->name);
837      *errors |= SM_ERR_NOTONCHANNEL;
838      return;
839    }
# Line 915 | Line 847 | chm_hop(struct Client *source_p, struct
847    if (dir == MODE_DEL && !has_member_flags(member, CHFL_HALFOP))
848      return;
849  
850 <  mode_changes[mode_count].letter = 'h';
919 <  mode_changes[mode_count].dir = dir;
920 <  mode_changes[mode_count].mems = ALL_MEMBERS;
921 <  mode_changes[mode_count].id = target_p->id;
850 >  mode_changes[mode_count].letter = c;
851    mode_changes[mode_count].arg = target_p->name;
852 <  mode_changes[mode_count++].client = target_p;
852 >  mode_changes[mode_count].id = target_p->id;
853 >  mode_changes[mode_count++].dir = dir;
854  
855    if (dir == MODE_ADD)
926  {
856      AddMemberFlag(member, CHFL_HALFOP);
928    DelMemberFlag(member, CHFL_DEOPPED);
929  }
857    else
858      DelMemberFlag(member, CHFL_HALFOP);
859   }
933 #endif
860  
861   static void
862   chm_op(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
863         char **parv, int *errors, int alev, int dir, char c, unsigned int d)
864   {
939  const char *opnick = NULL;
865    struct Client *target_p;
866    struct Membership *member;
867  
# Line 945 | Line 870 | chm_op(struct Client *source_p, struct C
870      if (!(*errors & SM_ERR_NOOPS))
871        sendto_one_numeric(source_p, &me,
872                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
873 <                         ERR_CHANOPRIVSNEEDED, chptr->chname);
873 >                         ERR_CHANOPRIVSNEEDED, chptr->name);
874      *errors |= SM_ERR_NOOPS;
875      return;
876    }
877  
878 <  if ((dir == MODE_QUERY) || (parc <= *parn))
878 >  if (dir == MODE_QUERY || parc <= *parn)
879      return;
880  
881 <  opnick = parv[(*parn)++];
882 <
958 <  if ((target_p = find_chasing(source_p, opnick)) == NULL)
959 <    return;
881 >  if ((target_p = find_chasing(source_p, parv[(*parn)++])) == NULL)
882 >    return;  /* find_chasing sends ERR_NOSUCHNICK */
883  
884    if ((member = find_channel_link(target_p, chptr)) == NULL)
885    {
886      if (!(*errors & SM_ERR_NOTONCHANNEL))
887 <      sendto_one_numeric(source_p, &me, ERR_USERNOTINCHANNEL, opnick, chptr->chname);
887 >      sendto_one_numeric(source_p, &me, ERR_USERNOTINCHANNEL, target_p->name, chptr->name);
888      *errors |= SM_ERR_NOTONCHANNEL;
889      return;
890    }
# Line 975 | Line 898 | chm_op(struct Client *source_p, struct C
898    if (dir == MODE_DEL && !has_member_flags(member, CHFL_CHANOP))
899      return;
900  
901 <  mode_changes[mode_count].letter = 'o';
979 <  mode_changes[mode_count].dir = dir;
980 <  mode_changes[mode_count].mems = ALL_MEMBERS;
981 <  mode_changes[mode_count].id = target_p->id;
901 >  mode_changes[mode_count].letter = c;
902    mode_changes[mode_count].arg = target_p->name;
903 <  mode_changes[mode_count++].client = target_p;
903 >  mode_changes[mode_count].id = target_p->id;
904 >  mode_changes[mode_count++].dir = dir;
905  
906    if (dir == MODE_ADD)
986  {
907      AddMemberFlag(member, CHFL_CHANOP);
988    DelMemberFlag(member, CHFL_DEOPPED);
989  }
908    else
909      DelMemberFlag(member, CHFL_CHANOP);
910   }
# Line 995 | Line 913 | static void
913   chm_limit(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
914            char **parv, int *errors, int alev, int dir, char c, unsigned int d)
915   {
998  unsigned int i = 0;
916    int limit = 0;
917  
918    if (alev < CHACCESS_HALFOP)
# Line 1003 | Line 920 | chm_limit(struct Client *source_p, struc
920      if (!(*errors & SM_ERR_NOOPS))
921        sendto_one_numeric(source_p, &me,
922                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
923 <                         ERR_CHANOPRIVSNEEDED, chptr->chname);
923 >                         ERR_CHANOPRIVSNEEDED, chptr->name);
924      *errors |= SM_ERR_NOOPS;
925      return;
926    }
# Line 1011 | Line 928 | chm_limit(struct Client *source_p, struc
928    if (dir == MODE_QUERY)
929      return;
930  
931 <  if ((dir == MODE_ADD) && parc > *parn)
931 >  if (dir == MODE_ADD && parc > *parn)
932    {
933 <    char *lstr = parv[(*parn)++];
933 >    char *const lstr = parv[(*parn)++];
934  
935      if (EmptyString(lstr) || (limit = atoi(lstr)) <= 0)
936        return;
# Line 1021 | Line 938 | chm_limit(struct Client *source_p, struc
938      sprintf(lstr, "%d", limit);
939  
940      /* If somebody sets MODE #channel +ll 1 2, accept latter --fl */
941 <    for (i = 0; i < mode_count; ++i)
941 >    for (unsigned int i = 0; i < mode_count; ++i)
942        if (mode_changes[i].letter == c && mode_changes[i].dir == MODE_ADD)
943          mode_changes[i].letter = 0;
944  
945      mode_changes[mode_count].letter = c;
946 <    mode_changes[mode_count].dir = MODE_ADD;
1030 <    mode_changes[mode_count].mems = ALL_MEMBERS;
946 >    mode_changes[mode_count].arg = lstr;
947      mode_changes[mode_count].id = NULL;
948 <    mode_changes[mode_count++].arg = lstr;
948 >    mode_changes[mode_count++].dir = dir;
949  
950      chptr->mode.limit = limit;
951    }
# Line 1041 | Line 957 | chm_limit(struct Client *source_p, struc
957      chptr->mode.limit = 0;
958  
959      mode_changes[mode_count].letter = c;
960 <    mode_changes[mode_count].dir = MODE_DEL;
1045 <    mode_changes[mode_count].mems = ALL_MEMBERS;
960 >    mode_changes[mode_count].arg = NULL;
961      mode_changes[mode_count].id = NULL;
962 <    mode_changes[mode_count++].arg = NULL;
962 >    mode_changes[mode_count++].dir = dir;
963    }
964   }
965  
# Line 1052 | Line 967 | static void
967   chm_key(struct Client *source_p, struct Channel *chptr, int parc, int *parn,
968          char **parv, int *errors, int alev, int dir, char c, unsigned int d)
969   {
1055  unsigned int i = 0;
1056
970    if (alev < CHACCESS_HALFOP)
971    {
972      if (!(*errors & SM_ERR_NOOPS))
973        sendto_one_numeric(source_p, &me,
974                           alev == CHACCESS_NOTONCHAN ? ERR_NOTONCHANNEL :
975 <                         ERR_CHANOPRIVSNEEDED, chptr->chname);
975 >                         ERR_CHANOPRIVSNEEDED, chptr->name);
976      *errors |= SM_ERR_NOOPS;
977      return;
978    }
# Line 1067 | Line 980 | chm_key(struct Client *source_p, struct
980    if (dir == MODE_QUERY)
981      return;
982  
983 <  if ((dir == MODE_ADD) && parc > *parn)
983 >  if (dir == MODE_ADD && parc > *parn)
984    {
985 <    char *key = parv[(*parn)++];
1073 <
1074 <    if (MyClient(source_p))
1075 <      fix_key(key);
1076 <    else
1077 <      fix_key_old(key);
985 >    char *const key = fix_key(parv[(*parn)++]);
986  
987      if (EmptyString(key))
988        return;
# Line 1083 | Line 991 | chm_key(struct Client *source_p, struct
991      strlcpy(chptr->mode.key, key, sizeof(chptr->mode.key));
992  
993      /* If somebody does MODE #channel +kk a b, accept latter --fl */
994 <    for (i = 0; i < mode_count; ++i)
994 >    for (unsigned int i = 0; i < mode_count; ++i)
995        if (mode_changes[i].letter == c && mode_changes[i].dir == MODE_ADD)
996          mode_changes[i].letter = 0;
997  
998      mode_changes[mode_count].letter = c;
999 <    mode_changes[mode_count].dir = MODE_ADD;
1092 <    mode_changes[mode_count].mems = ALL_MEMBERS;
999 >    mode_changes[mode_count].arg = chptr->mode.key;
1000      mode_changes[mode_count].id = NULL;
1001 <    mode_changes[mode_count++].arg = chptr->mode.key;
1001 >    mode_changes[mode_count++].dir = dir;
1002    }
1003    else if (dir == MODE_DEL)
1004    {
1005      if (parc > *parn)
1006 <      (*parn)++;
1006 >      ++(*parn);
1007  
1008      if (chptr->mode.key[0] == '\0')
1009        return;
# Line 1104 | Line 1011 | chm_key(struct Client *source_p, struct
1011      chptr->mode.key[0] = '\0';
1012  
1013      mode_changes[mode_count].letter = c;
1014 <    mode_changes[mode_count].dir = MODE_DEL;
1108 <    mode_changes[mode_count].mems = ALL_MEMBERS;
1014 >    mode_changes[mode_count].arg = "*";
1015      mode_changes[mode_count].id = NULL;
1016 <    mode_changes[mode_count++].arg = "*";
1016 >    mode_changes[mode_count++].dir = dir;
1017    }
1018   }
1019  
1020 < struct ChannelMode
1115 < {
1116 <  void (*func)(struct Client *,
1117 <               struct Channel *, int, int *, char **,
1118 <               int *, int, int, char, unsigned int);
1119 <  unsigned int d;
1120 < };
1121 <
1122 < static struct ChannelMode ModeTable[256] =
1020 > const struct ChannelMode ModeTable[256] =
1021   {
1022    { chm_nosuch,  0 },                   /* 0x00 */
1023    { chm_nosuch,  0 },                   /* 0x01 */
# Line 1225 | Line 1123 | static struct ChannelMode ModeTable[256]
1123    { chm_except,  0 },                   /* e */
1124    { chm_nosuch,  0 },                   /* f */
1125    { chm_nosuch,  0 },                   /* g */
1228 #ifdef HALFOPS
1126    { chm_hop,     0 },                   /* h */
1230 #else
1231  { chm_nosuch,  0 },                   /* h */
1232 #endif
1127    { chm_simple,     MODE_INVITEONLY },  /* i */
1128    { chm_nosuch,     0               },  /* j */
1129    { chm_key,        0               },  /* k */
# Line 1397 | Line 1291 | get_channel_access(const struct Client *
1291   {
1292    /* Let hacked servers in for now... */
1293    if (!MyClient(source_p))
1294 <    return CHACCESS_CHANOP;
1294 >    return CHACCESS_REMOTE;
1295  
1296    if (!member)
1297      return CHACCESS_NOTONCHAN;
# Line 1408 | Line 1302 | get_channel_access(const struct Client *
1302    if (has_member_flags(member, CHFL_CHANOP))
1303      return CHACCESS_CHANOP;
1304  
1411 #ifdef HALFOPS
1305    if (has_member_flags(member, CHFL_HALFOP))
1306      return CHACCESS_HALFOP;
1414 #endif
1307  
1308    return CHACCESS_PEON;
1309   }
# Line 1426 | Line 1318 | get_channel_access(const struct Client *
1318   static void
1319   send_mode_changes_server(struct Client *source_p, struct Channel *chptr)
1320   {
1429  unsigned int i;
1321    int mbl = 0, pbl = 0, arglen = 0, nc = 0, mc = 0;
1322    int len = 0;
1432  const char *arg = NULL;
1433  char *parptr;
1323    int dir = MODE_QUERY;
1324 +  const char *arg = NULL;
1325 +  char *parptr = NULL;
1326  
1327    parabuf[0] = '\0';
1328    parptr = parabuf;
1329  
1330    mbl = snprintf(modebuf, sizeof(modebuf), ":%s TMODE %lu %s ", source_p->id,
1331 <                 (unsigned long)chptr->channelts, chptr->chname);
1331 >                 (unsigned long)chptr->creationtime, chptr->name);
1332  
1333    /* Loop the list of modes we have */
1334 <  for (i = 0; i < mode_count; ++i)
1334 >  for (unsigned i = 0; i < mode_count; ++i)
1335    {
1336 <    if (mode_changes[i].letter == 0) /* XXX: can it ever happen? */
1336 >    if (mode_changes[i].letter == 0)
1337        continue;
1338  
1339      if (mode_changes[i].id)
# Line 1470 | Line 1361 | send_mode_changes_server(struct Client *
1361        mc = 0;
1362  
1363        mbl = snprintf(modebuf, sizeof(modebuf), ":%s TMODE %lu %s ", source_p->id,
1364 <                     (unsigned long)chptr->channelts, chptr->chname);
1364 >                     (unsigned long)chptr->creationtime, chptr->name);
1365  
1366        pbl = 0;
1367        parabuf[0] = '\0';
# Line 1486 | Line 1377 | send_mode_changes_server(struct Client *
1377  
1378      modebuf[mbl++] = mode_changes[i].letter;
1379      modebuf[mbl] = '\0';
1380 <    nc++;
1380 >    ++nc;
1381  
1382      if (arg)
1383      {
1384        len = sprintf(parptr, "%s ", arg);
1385        pbl += len;
1386        parptr += len;
1387 <      mc++;
1387 >      ++mc;
1388      }
1389    }
1390  
# Line 1518 | Line 1409 | send_mode_changes_server(struct Client *
1409   static void
1410   send_mode_changes(struct Client *source_p, struct Channel *chptr)
1411   {
1521  unsigned int i;
1412    int mbl = 0, pbl = 0, arglen = 0, nc = 0, mc = 0;
1413    int len = 0;
1524  const char *arg = NULL;
1525  char *parptr;
1414    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)
# Line 1532 | Line 1422 | send_mode_changes(struct Client *source_
1422    if (IsServer(source_p))
1423      mbl = snprintf(modebuf, sizeof(modebuf), ":%s MODE %s ", (IsHidden(source_p) ||
1424                     ConfigServerHide.hide_servers) ?
1425 <                   me.name : source_p->name, chptr->chname);
1425 >                   me.name : source_p->name, chptr->name);
1426    else
1427      mbl = snprintf(modebuf, sizeof(modebuf), ":%s!%s@%s MODE %s ", source_p->name,
1428 <                   source_p->username, source_p->host, chptr->chname);
1428 >                   source_p->username, source_p->host, chptr->name);
1429  
1430    parabuf[0] = '\0';
1431    parptr = parabuf;
1432  
1433 <  for (i = 0; i < mode_count; ++i)
1433 >  for (unsigned int i = 0; i < mode_count; ++i)
1434    {
1435 <    if (mode_changes[i].letter == 0 ||
1546 <        mode_changes[i].mems == NON_CHANOPS ||
1547 <        mode_changes[i].mems == ONLY_SERVERS)
1435 >    if (mode_changes[i].letter == 0)
1436        continue;
1437  
1438      arg = mode_changes[i].arg;
# Line 1553 | Line 1441 | send_mode_changes(struct Client *source_
1441      else
1442        arglen = 0;
1443  
1444 <    if ((mc == MAXMODEPARAMS)  ||
1444 >    if ((mc == MAXMODEPARAMS) ||
1445          ((arglen + mbl + pbl + 2) > IRCD_BUFSIZE) ||
1446          ((arglen + pbl + BAN_FUDGE) >= MODEBUFLEN))
1447      {
# Line 1561 | Line 1449 | send_mode_changes(struct Client *source_
1449          modebuf[mbl - 1] = '\0';
1450  
1451        if (nc)
1452 <        sendto_channel_local(ALL_MEMBERS, 0, chptr, "%s %s", modebuf, parabuf);
1452 >        sendto_channel_local(0, chptr, "%s %s", modebuf, parabuf);
1453  
1454        nc = 0;
1455        mc = 0;
# Line 1569 | Line 1457 | send_mode_changes(struct Client *source_
1457        if (IsServer(source_p))
1458          mbl = snprintf(modebuf, sizeof(modebuf), ":%s MODE %s ", (IsHidden(source_p) ||
1459                         ConfigServerHide.hide_servers) ?
1460 <                       me.name : source_p->name, chptr->chname);
1460 >                       me.name : source_p->name, chptr->name);
1461        else
1462          mbl = snprintf(modebuf, sizeof(modebuf), ":%s!%s@%s MODE %s ", source_p->name,
1463 <                       source_p->username, source_p->host, chptr->chname);
1463 >                       source_p->username, source_p->host, chptr->name);
1464  
1465        pbl = 0;
1466        parabuf[0] = '\0';
# Line 1588 | Line 1476 | send_mode_changes(struct Client *source_
1476  
1477      modebuf[mbl++] = mode_changes[i].letter;
1478      modebuf[mbl] = '\0';
1479 <    nc++;
1479 >    ++nc;
1480  
1481      if (arg)
1482      {
1483        len = sprintf(parptr, "%s ", arg);
1484        pbl += len;
1485        parptr += len;
1486 <      mc++;
1486 >      ++mc;
1487      }
1488    }
1489  
# Line 1603 | Line 1491 | send_mode_changes(struct Client *source_
1491      parabuf[pbl - 1] = '\0';
1492  
1493    if (nc)
1494 <    sendto_channel_local(ALL_MEMBERS, 0, chptr, "%s %s", modebuf, parabuf);
1494 >    sendto_channel_local(0, chptr, "%s %s", modebuf, parabuf);
1495  
1496    send_mode_changes_server(source_p, chptr);
1497   }
1498  
1499 < /*
1499 > /*
1500   * Input: The the client this originated
1501   *        from, the channel, the parameter count starting at the modes,
1502   *        the parameters, the channel name.
# Line 1623 | Line 1511 | set_channel_mode(struct Client *source_p
1511   {
1512    int dir = MODE_ADD;
1513    int parn = 1;
1514 <  int alevel, errors = 0;
1514 >  int alevel = 0, errors = 0;
1515  
1516    mode_count = 0;
1517    mode_limit = 0;
# Line 1646 | Line 1534 | set_channel_mode(struct Client *source_p
1534          break;
1535        default:
1536        {
1537 <        struct ChannelMode *tptr = &ModeTable[(unsigned char)*ml];
1537 >        const struct ChannelMode *tptr = &ModeTable[(unsigned char)*ml];
1538  
1539          tptr->func(source_p, chptr, parc, &parn, parv,
1540                     &errors, alevel, dir, *ml, tptr->d);

Diff Legend

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