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/src/channel_mode.c (file contents), Revision 32 by knight, Sun Oct 2 20:41:23 2005 UTC vs.
ircd-hybrid/trunk/src/channel_mode.c (file contents), Revision 1937 by michael, Sat May 4 20:54:13 2013 UTC

# Line 23 | Line 23
23   */
24  
25   #include "stdinc.h"
26 < #include "tools.h"
26 > #include "list.h"
27   #include "channel.h"
28   #include "channel_mode.h"
29   #include "client.h"
30 – #include "common.h"
30   #include "hash.h"
31 + #include "conf.h"
32 + #include "hostmask.h"
33   #include "irc_string.h"
33 – #include "sprintf_irc.h"
34   #include "ircd.h"
35 – #include "list.h"
35   #include "numeric.h"
36   #include "s_serv.h"             /* captab */
37   #include "s_user.h"
38   #include "send.h"
39   #include "whowas.h"
41 – #include "s_conf.h"             /* ConfigFileEntry, ConfigChannel */
40   #include "event.h"
41   #include "memory.h"
42 < #include "balloc.h"
43 < #include "s_log.h"
42 > #include "mempool.h"
43 > #include "log.h"
44 > #include "parse.h"
45  
46   /* some small utility functions */
47   static char *check_string(char *);
# Line 54 | Line 53 | static void chm_nosuch(struct Client *,
53   static void chm_simple(struct Client *, struct Client *, struct Channel *,
54                         int, int *, char **, int *, int, int, char, void *,
55                         const char *);
56 + static void chm_registered(struct Client *, struct Client *, struct Channel *,
57 +                       int, int *, char **, int *, int, int, char, void *,
58 +                       const char *);
59   static void chm_limit(struct Client *, struct Client *, struct Channel *,
60                        int, int *, char **, int *, int, int, char, void *,
61                        const char *);
# Line 81 | Line 83 | static void chm_invex(struct Client *, s
83                        int, int *, char **, int *, int, int, char, void *,
84                        const char *);
85   static void send_cap_mode_changes(struct Client *, struct Client *,
86 <                                  struct Channel *, int, int);
86 >                                  struct Channel *, unsigned int, unsigned int);
87   static void send_mode_changes(struct Client *, struct Client *,
88                                struct Channel *, char *);
89  
# Line 90 | Line 92 | static void send_mode_changes(struct Cli
92   #define NCHCAPS         (sizeof(channel_capabs)/sizeof(int))
93   #define NCHCAP_COMBOS   (1 << NCHCAPS)
94  
95 + static char nuh_mask[MAXPARA][IRCD_BUFSIZE];
96   /* some buffers for rebuilding channel/nick lists with ,'s */
97   static char modebuf[IRCD_BUFSIZE];
98   static char parabuf[MODEBUFLEN];
# Line 97 | Line 100 | static struct ChModeChange mode_changes[
100   static int mode_count;
101   static int mode_limit;          /* number of modes set other than simple */
102   static int simple_modes_mask;   /* bit mask of simple modes already set */
103 + #ifdef HALFOPS
104 + static int channel_capabs[] = { CAP_EX, CAP_IE, CAP_TS6, CAP_HOPS };
105 + #else
106   static int channel_capabs[] = { CAP_EX, CAP_IE, CAP_TS6 };
107 + #endif
108   static struct ChCapCombo chcap_combos[NCHCAP_COMBOS];
109 < extern BlockHeap *ban_heap;
109 > extern mp_pool_t *ban_pool;
110  
111  
105 – /* XXX check_string is propably not longer required in add_id and del_id */
112   /* check_string()
113   *
114   * inputs       - string to check
# Line 118 | Line 124 | check_string(char *s)
124    char *str = s;
125    static char star[] = "*";
126  
127 <  if (EmptyString(s))
128 <    return (star);
127 >  if (EmptyString(str))
128 >    return star;
129  
130    for (; *s; ++s)
131    {
# Line 130 | Line 136 | check_string(char *s)
136      }
137    }
138  
139 <  return (str);
139 >  return EmptyString(str) ? star : str;
140   }
141  
142   /*
# Line 143 | Line 149 | check_string(char *s)
149   int
150   add_id(struct Client *client_p, struct Channel *chptr, char *banid, int type)
151   {
152 <  dlink_list *list;
153 <  dlink_node *ban;
152 >  dlink_list *list = NULL;
153 >  dlink_node *ban = NULL;
154    size_t len = 0;
155 <  struct Ban *actualBan;
155 >  struct Ban *ban_p = NULL;
156    unsigned int num_mask;
157 <  char *name = NULL, *user = NULL, *host = NULL;
157 >  char name[NICKLEN + 1];
158 >  char user[USERLEN + 1];
159 >  char host[HOSTLEN + 1];
160 >  struct split_nuh_item nuh;
161  
162    /* dont let local clients overflow the b/e/I lists */
163    if (MyClient(client_p))
# Line 167 | Line 176 | add_id(struct Client *client_p, struct C
176      collapse(banid);
177    }
178  
179 <  split_nuh(check_string(banid), &name, &user, &host);
179 >  nuh.nuhmask  = check_string(banid);
180 >  nuh.nickptr  = name;
181 >  nuh.userptr  = user;
182 >  nuh.hostptr  = host;
183 >
184 >  nuh.nicksize = sizeof(name);
185 >  nuh.usersize = sizeof(user);
186 >  nuh.hostsize = sizeof(host);
187 >
188 >  split_nuh(&nuh);
189  
190    /*
191 <   * Assemble a n!u@h and print it back to banid for sending
191 >   * Re-assemble a new n!u@h and print it back to banid for sending
192     * the mode to the channel.
193     */
194 <  len = ircsprintf(banid, "%s!%s@%s", name, user, host);
194 >  len = sprintf(banid, "%s!%s@%s", name, user, host);
195  
196    switch (type)
197    {
# Line 195 | Line 213 | add_id(struct Client *client_p, struct C
213  
214    DLINK_FOREACH(ban, list->head)
215    {
216 <    actualBan = ban->data;
217 <    if (!irccmp(actualBan->name, name) &&
218 <        !irccmp(actualBan->username, user) &&
219 <        !irccmp(actualBan->host, host))
216 >    ban_p = ban->data;
217 >    if (!irccmp(ban_p->name, name) &&
218 >        !irccmp(ban_p->username, user) &&
219 >        !irccmp(ban_p->host, host))
220      {
203 –      MyFree(name);
204 –      MyFree(user);
205 –      MyFree(host);
221        return 0;
222      }
223    }
224  
225 <  actualBan = BlockHeapAlloc(ban_heap);
226 <  actualBan->when = CurrentTime;
227 <  actualBan->name = name;
228 <  actualBan->username = user;
229 <  actualBan->host = host;
230 <  actualBan->len = len-2; /* -2 for @ and ! */
225 >  ban_p = mp_pool_get(ban_pool);
226 >  memset(ban_p, 0, sizeof(*ban_p));
227 >  ban_p->name = xstrdup(name);
228 >  ban_p->username = xstrdup(user);
229 >  ban_p->host = xstrdup(host);
230 >  ban_p->when = CurrentTime;
231 >  ban_p->len = len - 2; /* -2 for @ and ! */
232 >  ban_p->type = parse_netmask(host, &ban_p->addr, &ban_p->bits);
233  
234    if (IsClient(client_p))
235    {
236 <    actualBan->who =
237 <      MyMalloc(strlen(client_p->name) +
238 <               strlen(client_p->username) +
239 <               strlen(client_p->host) + 3);
240 <    ircsprintf(actualBan->who, "%s!%s@%s",
224 <               client_p->name, client_p->username, client_p->host);
236 >    ban_p->who = MyMalloc(strlen(client_p->name) +
237 >                          strlen(client_p->username) +
238 >                          strlen(client_p->host) + 3);
239 >    sprintf(ban_p->who, "%s!%s@%s", client_p->name,
240 >               client_p->username, client_p->host);
241    }
242    else
243 <    DupString(actualBan->who, client_p->name);
243 >    ban_p->who = xstrdup(client_p->name);
244  
245 <  dlinkAdd(actualBan, &actualBan->node, list);
245 >  dlinkAdd(ban_p, &ban_p->node, list);
246  
247    return 1;
248   }
# Line 244 | Line 260 | del_id(struct Channel *chptr, char *bani
260    dlink_list *list;
261    dlink_node *ban;
262    struct Ban *banptr;
263 <  char *name = NULL, *user = NULL, *host = NULL;
263 >  char name[NICKLEN + 1];
264 >  char user[USERLEN + 1];
265 >  char host[HOSTLEN + 1];
266 >  struct split_nuh_item nuh;
267  
268    if (banid == NULL)
269      return 0;
270  
271 <  split_nuh(check_string(banid), &name, &user, &host);
271 >  nuh.nuhmask  = check_string(banid);
272 >  nuh.nickptr  = name;
273 >  nuh.userptr  = user;
274 >  nuh.hostptr  = host;
275 >
276 >  nuh.nicksize = sizeof(name);
277 >  nuh.usersize = sizeof(user);
278 >  nuh.hostsize = sizeof(host);
279 >
280 >  split_nuh(&nuh);
281  
282    /*
283 <   * Assemble a n!u@h and print it back to banid for sending
283 >   * Re-assemble a new n!u@h and print it back to banid for sending
284     * the mode to the channel.
285     */
286 <  ircsprintf(banid, "%s!%s@%s", name, user, host);
286 >  sprintf(banid, "%s!%s@%s", name, user, host);
287  
288    switch (type)
289    {
# Line 271 | Line 299 | del_id(struct Channel *chptr, char *bani
299        list = &chptr->invexlist;
300        break;
301      default:
302 <      sendto_realops_flags(UMODE_ALL, L_ALL,
302 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
303                             "del_id() called with unknown ban type %d!", type);
304 <      MyFree(name);
277 <      MyFree(user);
278 <      MyFree(host);
279 <      return(0);
304 >      return 0;
305    }
306  
307    DLINK_FOREACH(ban, list->head)
# Line 284 | Line 309 | del_id(struct Channel *chptr, char *bani
309      banptr = ban->data;
310  
311      if (!irccmp(name, banptr->name) &&
312 <        !irccmp(user, banptr->username) &&
313 <        !irccmp(host, banptr->host))
312 >        !irccmp(user, banptr->username) &&
313 >        !irccmp(host, banptr->host))
314      {
315        remove_ban(banptr, list);
291 –      MyFree(name);
292 –      MyFree(user);
293 –      MyFree(host);
316        return 1;
317      }
318    }
319  
298 –  MyFree(name);
299 –  MyFree(user);
300 –  MyFree(host);
320    return 0;
321   }
322  
323 < static const struct mode_letter
324 < {
306 <  const unsigned int mode;
307 <  const unsigned char letter;
308 < } flags[] = {
323 > const struct mode_letter chan_modes[] = {
324 >  { MODE_NOCTRL,     'c' },
325    { MODE_INVITEONLY, 'i' },
326    { MODE_MODERATED,  'm' },
327    { MODE_NOPRIVMSGS, 'n' },
328    { MODE_PRIVATE,    'p' },
329 +  { MODE_REGISTERED, 'r' },
330    { MODE_SECRET,     's' },
331    { MODE_TOPICLIMIT, 't' },
332 +  { MODE_OPERONLY,   'O' },
333 +  { MODE_REGONLY,    'R' },
334 +  { MODE_SSLONLY,    'S' },
335    { 0, '\0' }
336   };
337  
# Line 329 | Line 349 | void
349   channel_modes(struct Channel *chptr, struct Client *client_p,
350                char *mbuf, char *pbuf)
351   {
352 <  int i;
352 >  const struct mode_letter *tab = chan_modes;
353  
354    *mbuf++ = '+';
355    *pbuf = '\0';
356  
357 <  for (i = 0; flags[i].mode; ++i)
358 <    if (chptr->mode.mode & flags[i].mode)
359 <      *mbuf++ = flags[i].letter;
357 >  for (; tab->mode; ++tab)
358 >    if (chptr->mode.mode & tab->mode)
359 >      *mbuf++ = tab->letter;
360  
361    if (chptr->mode.limit)
362    {
363      *mbuf++ = 'l';
364  
365 <    if (IsMember(client_p, chptr) || IsServer(client_p))
366 <      pbuf += ircsprintf(pbuf, "%d ", chptr->mode.limit);
365 >    if (IsServer(client_p) || HasFlag(client_p, FLAGS_SERVICE) || IsMember(client_p, chptr))
366 >      pbuf += sprintf(pbuf, "%d ", chptr->mode.limit);
367    }
368  
369    if (chptr->mode.key[0])
370    {
371      *mbuf++ = 'k';
372  
373 <    if (*pbuf || IsMember(client_p, chptr) || IsServer(client_p))
374 <      ircsprintf(pbuf, "%s ", chptr->mode.key);
373 >    if (IsServer(client_p) || HasFlag(client_p, FLAGS_SERVICE) || IsMember(client_p, chptr))
374 >      sprintf(pbuf, "%s ", chptr->mode.key);
375    }
376  
377    *mbuf = '\0';
# Line 417 | Line 437 | fix_key_old(char *arg)
437   #define SM_ERR_RPL_E        0x00000010
438   #define SM_ERR_NOTONCHANNEL 0x00000020 /* Not on channel    */
439   #define SM_ERR_RPL_I        0x00000040
440 + #define SM_ERR_NOTOPER      0x00000080
441 + #define SM_ERR_ONLYSERVER   0x00000100
442  
443   /* Now lets do some stuff to keep track of what combinations of
444   * servers exist...
# Line 592 | Line 614 | chm_simple(struct Client *client_p, stru
614   }
615  
616   static void
617 + chm_registered(struct Client *client_p, struct Client *source_p, struct Channel *chptr,
618 +           int parc, int *parn, char **parv, int *errors, int alev, int dir,
619 +           char c, void *d, const char *chname)
620 + {
621 +  long mode_type;
622 +
623 +  mode_type = (long)d;
624 +
625 +
626 +  if (!IsServer(source_p) && !HasFlag(source_p, FLAGS_SERVICE))
627 +  {
628 +    if (!(*errors & SM_ERR_ONLYSERVER))
629 +      sendto_one(source_p, form_str(alev == CHACCESS_NOTONCHAN ?
630 +                                    ERR_NOTONCHANNEL : ERR_ONLYSERVERSCANCHANGE),
631 +                 me.name, source_p->name, chname);
632 +    *errors |= SM_ERR_ONLYSERVER;
633 +    return;
634 +  }
635 +
636 +  /* If have already dealt with this simple mode, ignore it */
637 +  if (simple_modes_mask & mode_type)
638 +    return;
639 +
640 +  simple_modes_mask |= mode_type;
641 +
642 +  /* setting + */
643 +  /* Apparently, (though no one has ever told the hybrid group directly)
644 +   * admins don't like redundant mode checking. ok. It would have been nice
645 +   * if you had have told us directly. I've left the original code snippets
646 +   * in place.
647 +   *
648 +   * -Dianora
649 +   */
650 +  if ((dir == MODE_ADD)) /* && !(chptr->mode.mode & mode_type)) */
651 +  {
652 +    chptr->mode.mode |= mode_type;
653 +
654 +    mode_changes[mode_count].letter = c;
655 +    mode_changes[mode_count].dir = MODE_ADD;
656 +    mode_changes[mode_count].caps = 0;
657 +    mode_changes[mode_count].nocaps = 0;
658 +    mode_changes[mode_count].id = NULL;
659 +    mode_changes[mode_count].mems = ALL_MEMBERS;
660 +    mode_changes[mode_count++].arg = NULL;
661 +  }
662 +  else if ((dir == MODE_DEL)) /* && (chptr->mode.mode & mode_type)) */
663 +  {
664 +    /* setting - */
665 +
666 +    chptr->mode.mode &= ~mode_type;
667 +
668 +    mode_changes[mode_count].letter = c;
669 +    mode_changes[mode_count].dir = MODE_DEL;
670 +    mode_changes[mode_count].caps = 0;
671 +    mode_changes[mode_count].nocaps = 0;
672 +    mode_changes[mode_count].mems = ALL_MEMBERS;
673 +    mode_changes[mode_count].id = NULL;
674 +    mode_changes[mode_count++].arg = NULL;
675 +  }
676 + }
677 +
678 + static void
679 + chm_operonly(struct Client *client_p, struct Client *source_p, struct Channel *chptr,
680 +            int parc, int *parn, char **parv, int *errors, int alev, int dir,
681 +            char c, void *d, const char *chname)
682 + {
683 +  long mode_type;
684 +
685 +  mode_type = (long)d;
686 +
687 +  if ((alev < CHACCESS_HALFOP) ||
688 +      ((mode_type == MODE_PRIVATE) && (alev < CHACCESS_CHANOP)))
689 +  {
690 +    if (!(*errors & SM_ERR_NOOPS))
691 +      sendto_one(source_p, form_str(alev == CHACCESS_NOTONCHAN ?
692 +                                    ERR_NOTONCHANNEL : ERR_CHANOPRIVSNEEDED),
693 +                 me.name, source_p->name, chname);
694 +    *errors |= SM_ERR_NOOPS;
695 +    return;
696 +  }
697 +  else if (MyClient(source_p) && !HasUMode(source_p, UMODE_OPER))
698 +  {
699 +    if (!(*errors & SM_ERR_NOTOPER))
700 +    {
701 +      if (alev == CHACCESS_NOTONCHAN)
702 +        sendto_one(source_p, form_str(ERR_NOTONCHANNEL),
703 +                   me.name, source_p->name, chname);
704 +      else
705 +        sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
706 +                   me.name, source_p->name);
707 +    }
708 +
709 +    *errors |= SM_ERR_NOTOPER;
710 +    return;
711 +  }
712 +
713 +  /* If have already dealt with this simple mode, ignore it */
714 +  if (simple_modes_mask & mode_type)
715 +    return;
716 +
717 +  simple_modes_mask |= mode_type;
718 +
719 +  if ((dir == MODE_ADD)) /* && !(chptr->mode.mode & mode_type)) */
720 +  {
721 +    chptr->mode.mode |= mode_type;
722 +
723 +    mode_changes[mode_count].letter = c;
724 +    mode_changes[mode_count].dir = MODE_ADD;
725 +    mode_changes[mode_count].caps = 0;
726 +    mode_changes[mode_count].nocaps = 0;
727 +    mode_changes[mode_count].id = NULL;
728 +    mode_changes[mode_count].mems = ALL_MEMBERS;
729 +    mode_changes[mode_count].mems = ALL_MEMBERS;
730 +    mode_changes[mode_count++].arg = NULL;
731 +  }
732 +  else if ((dir == MODE_DEL)) /* && (chptr->mode.mode & mode_type)) */
733 +  {
734 +    /* setting - */
735 +
736 +    chptr->mode.mode &= ~mode_type;
737 +
738 +    mode_changes[mode_count].letter = c;
739 +    mode_changes[mode_count].dir = MODE_DEL;
740 +    mode_changes[mode_count].caps = 0;
741 +    mode_changes[mode_count].nocaps = 0;
742 +    mode_changes[mode_count].mems = ALL_MEMBERS;
743 +    mode_changes[mode_count].id = NULL;
744 +    mode_changes[mode_count++].arg = NULL;
745 +  }
746 + }
747 +
748 + static void
749   chm_ban(struct Client *client_p, struct Client *source_p,
750          struct Channel *chptr, int parc, int *parn,
751          char **parv, int *errors, int alev, int dir, char c, void *d,
# Line 635 | Line 789 | chm_ban(struct Client *client_p, struct
789    if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
790      return;
791  
792 <  mask = parv[(*parn)++];
793 <  
792 >  mask = nuh_mask[*parn];
793 >  memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
794 >  ++*parn;
795 >
796    if (IsServer(client_p))
797      if (strchr(mask, ' '))
798        return;
# Line 648 | Line 804 | chm_ban(struct Client *client_p, struct
804          return;
805        break;
806      case MODE_DEL:
651 – /* XXX grrrrrrr */
652 – #ifdef NO_BAN_COOKIE
807        if (!del_id(chptr, mask, CHFL_BAN))
808          return;
655 – #else
656 –     /* XXX this hack allows /mode * +o-b nick ban.cookie
657 –      * I'd like to see this hack go away in the future.
658 –      */
659 –      del_id(chptr, mask, CHFL_BAN);
660 – #endif
809        break;
810      default:
811        assert(0);
# Line 680 | Line 828 | chm_except(struct Client *client_p, stru
828   {
829    char *mask = NULL;
830  
683 –  /* if we have +e disabled, allow local clients to do anything but
684 –   * set the mode.  This prevents the abuse of +e when just a few
685 –   * servers support it. --fl
686 –   */
687 –  if (!ConfigChannel.use_except && MyClient(source_p) &&
688 –      ((dir == MODE_ADD) && (parc > *parn)))
689 –  {
690 –    if (*errors & SM_ERR_RPL_E)
691 –      return;
692 –
693 –    *errors |= SM_ERR_RPL_E;
694 –    return;
695 –  }
696 –
831    if (alev < CHACCESS_HALFOP)
832    {
833      if (!(*errors & SM_ERR_NOOPS))
# Line 730 | Line 864 | chm_except(struct Client *client_p, stru
864    if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
865      return;
866  
867 <  mask = parv[(*parn)++];
867 >  mask = nuh_mask[*parn];
868 >  memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
869 >  ++*parn;
870  
871    if (IsServer(client_p))
872      if (strchr(mask, ' '))
# Line 752 | Line 888 | chm_except(struct Client *client_p, stru
888  
889    mode_changes[mode_count].letter = c;
890    mode_changes[mode_count].dir = dir;
891 <  mode_changes[mode_count].caps = CAP_EX;
891 >  mode_changes[mode_count].caps = 0;
892    mode_changes[mode_count].nocaps = 0;
893 <
758 <  if (ConfigChannel.use_except)
759 <    mode_changes[mode_count].mems = ONLY_CHANOPS;
760 <  else
761 <    mode_changes[mode_count].mems = ONLY_SERVERS;
762 <
893 >  mode_changes[mode_count].mems = ONLY_CHANOPS;
894    mode_changes[mode_count].id = NULL;
895    mode_changes[mode_count++].arg = mask;
896   }
# Line 772 | Line 903 | chm_invex(struct Client *client_p, struc
903   {
904    char *mask = NULL;
905  
775 –  /* if we have +I disabled, allow local clients to do anything but
776 –   * set the mode.  This prevents the abuse of +I when just a few
777 –   * servers support it --fl
778 –   */
779 –  if (!ConfigChannel.use_invex && MyClient(source_p) &&
780 –      (dir == MODE_ADD) && (parc > *parn))
781 –  {
782 –    if (*errors & SM_ERR_RPL_I)
783 –      return;
784 –    
785 –    *errors |= SM_ERR_RPL_I;
786 –    return;
787 –  }
788 –
906    if (alev < CHACCESS_HALFOP)
907    {
908      if (!(*errors & SM_ERR_NOOPS))
# Line 822 | Line 939 | chm_invex(struct Client *client_p, struc
939    if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
940      return;
941  
942 <  mask = parv[(*parn)++];
942 >  mask = nuh_mask[*parn];
943 >  memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
944 >  ++*parn;
945  
946    if (IsServer(client_p))
947      if (strchr(mask, ' '))
# Line 844 | Line 963 | chm_invex(struct Client *client_p, struc
963  
964    mode_changes[mode_count].letter = c;
965    mode_changes[mode_count].dir = dir;
966 <  mode_changes[mode_count].caps = CAP_IE;
966 >  mode_changes[mode_count].caps = 0;
967    mode_changes[mode_count].nocaps = 0;
968 <
850 <  if (ConfigChannel.use_invex)
851 <    mode_changes[mode_count].mems = ONLY_CHANOPS;
852 <  else
853 <    mode_changes[mode_count].mems = ONLY_SERVERS;
854 <
968 >  mode_changes[mode_count].mems = ONLY_CHANOPS;
969    mode_changes[mode_count].id = NULL;
970    mode_changes[mode_count++].arg = mask;
971   }
# Line 866 | Line 980 | clear_ban_cache(struct Channel *chptr)
980   {
981    dlink_node *ptr = NULL;
982  
983 <  DLINK_FOREACH(ptr, chptr->locmembers.head)
983 >  DLINK_FOREACH(ptr, chptr->members.head)
984 >  {
985 >    struct Membership *ms = ptr->data;
986 >
987 >    if (MyConnect(ms->client_p))
988 >      ms->flags &= ~(CHFL_BAN_SILENCED|CHFL_BAN_CHECKED);
989 >  }
990 > }
991 >
992 > void
993 > clear_ban_cache_client(struct Client *client_p)
994 > {
995 >  dlink_node *ptr = NULL;
996 >
997 >  DLINK_FOREACH(ptr, client_p->channel.head)
998    {
999      struct Membership *ms = ptr->data;
1000      ms->flags &= ~(CHFL_BAN_SILENCED|CHFL_BAN_CHECKED);
# Line 882 | Line 1010 | chm_op(struct Client *client_p, struct C
1010    char *opnick;
1011    struct Client *targ_p;
1012    struct Membership *member;
1013 +  int caps = 0;
1014  
1015    if (alev < CHACCESS_CHANOP)
1016    {
# Line 919 | Line 1048 | chm_op(struct Client *client_p, struct C
1048    if (dir == MODE_ADD &&  has_member_flags(member, CHFL_CHANOP))
1049      return;
1050    if (dir == MODE_DEL && !has_member_flags(member, CHFL_CHANOP))
1051 +  {
1052 + #ifdef HALFOPS
1053 +    if (has_member_flags(member, CHFL_HALFOP))
1054 +    {
1055 +      --*parn;
1056 +      chm_hop(client_p, source_p, chptr, parc, parn, parv, errors, alev,
1057 +              dir, c, d, chname);
1058 +    }
1059 + #endif
1060      return;
1061 +  }
1062 +
1063 + #ifdef HALFOPS
1064 +  if (dir == MODE_ADD && has_member_flags(member, CHFL_HALFOP))
1065 +  {
1066 +    /* promoting from % to @ is visible only to CAP_HOPS servers */
1067 +    mode_changes[mode_count].letter = 'h';
1068 +    mode_changes[mode_count].dir = MODE_DEL;
1069 +    mode_changes[mode_count].caps = caps = CAP_HOPS;
1070 +    mode_changes[mode_count].nocaps = 0;
1071 +    mode_changes[mode_count].mems = ALL_MEMBERS;
1072 +    mode_changes[mode_count].id = NULL;
1073 +    mode_changes[mode_count].arg = targ_p->name;
1074 +    mode_changes[mode_count++].client = targ_p;
1075 +  }
1076 + #endif
1077  
1078    mode_changes[mode_count].letter = 'o';
1079    mode_changes[mode_count].dir = dir;
1080 <  mode_changes[mode_count].caps = 0;
1080 >  mode_changes[mode_count].caps = caps;
1081    mode_changes[mode_count].nocaps = 0;
1082    mode_changes[mode_count].mems = ALL_MEMBERS;
1083    mode_changes[mode_count].id = targ_p->id;
# Line 933 | Line 1087 | chm_op(struct Client *client_p, struct C
1087    if (dir == MODE_ADD)
1088    {
1089      AddMemberFlag(member, CHFL_CHANOP);
1090 <    DelMemberFlag(member, CHFL_DEOPPED);
1090 >    DelMemberFlag(member, CHFL_DEOPPED | CHFL_HALFOP);
1091    }
1092    else
1093      DelMemberFlag(member, CHFL_CHANOP);
# Line 997 | Line 1151 | chm_hop(struct Client *client_p, struct
1151      return;
1152  
1153    /* no redundant mode changes */
1154 <  if (dir == MODE_ADD &&  has_member_flags(member, CHFL_HALFOP))
1154 >  if (dir == MODE_ADD &&  has_member_flags(member, CHFL_HALFOP | CHFL_CHANOP))
1155      return;
1156    if (dir == MODE_DEL && !has_member_flags(member, CHFL_HALFOP))
1157      return;
1158  
1159    mode_changes[mode_count].letter = 'h';
1160    mode_changes[mode_count].dir = dir;
1161 <  mode_changes[mode_count].caps = 0;
1161 >  mode_changes[mode_count].caps = CAP_HOPS;
1162    mode_changes[mode_count].nocaps = 0;
1163    mode_changes[mode_count].mems = ALL_MEMBERS;
1164    mode_changes[mode_count].id = targ_p->id;
1165    mode_changes[mode_count].arg = targ_p->name;
1166    mode_changes[mode_count++].client = targ_p;
1167  
1168 +  mode_changes[mode_count].letter = 'o';
1169 +  mode_changes[mode_count].dir = dir;
1170 +  mode_changes[mode_count].caps = 0;
1171 +  mode_changes[mode_count].nocaps = CAP_HOPS;
1172 +  mode_changes[mode_count].mems = ONLY_SERVERS;
1173 +  mode_changes[mode_count].id = targ_p->id;
1174 +  mode_changes[mode_count].arg = targ_p->name;
1175 +  mode_changes[mode_count++].client = targ_p;
1176 +
1177    if (dir == MODE_ADD)
1178    {
1179      AddMemberFlag(member, CHFL_HALFOP);
# Line 1113 | Line 1276 | chm_limit(struct Client *client_p, struc
1276      if ((limit = atoi(lstr)) <= 0)
1277        return;
1278  
1279 <    ircsprintf(lstr, "%d", limit);
1279 >    sprintf(lstr, "%d", limit);
1280  
1281      /* if somebody sets MODE #channel +ll 1 2, accept latter --fl */
1282      for (i = 0; i < mode_count; i++)
# Line 1230 | Line 1393 | struct ChannelMode
1393    void *d;
1394   };
1395  
1233 – /* *INDENT-OFF* */
1396   static struct ChannelMode ModeTable[255] =
1397   {
1398    {chm_nosuch, NULL},
# Line 1248 | Line 1410 | static struct ChannelMode ModeTable[255]
1410    {chm_nosuch, NULL},                             /* L */
1411    {chm_nosuch, NULL},                             /* M */
1412    {chm_nosuch, NULL},                             /* N */
1413 <  {chm_nosuch, NULL},                             /* O */
1413 >  {chm_operonly, (void *) MODE_OPERONLY},         /* O */
1414    {chm_nosuch, NULL},                             /* P */
1415    {chm_nosuch, NULL},                             /* Q */
1416 <  {chm_nosuch, NULL},                             /* R */
1417 <  {chm_nosuch, NULL},                             /* S */
1416 >  {chm_simple, (void *) MODE_REGONLY},            /* R */
1417 >  {chm_simple, (void *) MODE_SSLONLY},            /* S */
1418    {chm_nosuch, NULL},                             /* T */
1419    {chm_nosuch, NULL},                             /* U */
1420    {chm_nosuch, NULL},                             /* V */
# Line 1268 | Line 1430 | static struct ChannelMode ModeTable[255]
1430    {chm_nosuch, NULL},
1431    {chm_nosuch, NULL},                             /* a */
1432    {chm_ban, NULL},                                /* b */
1433 <  {chm_nosuch, NULL},                             /* c */
1433 >  {chm_simple, (void *) MODE_NOCTRL},             /* c */
1434    {chm_nosuch, NULL},                             /* d */
1435    {chm_except, NULL},                             /* e */
1436    {chm_nosuch, NULL},                             /* f */
# Line 1287 | Line 1449 | static struct ChannelMode ModeTable[255]
1449    {chm_op, NULL},                                 /* o */
1450    {chm_simple, (void *) MODE_PRIVATE},            /* p */
1451    {chm_nosuch, NULL},                             /* q */
1452 <  {chm_nosuch, NULL},                             /* r */
1452 >  {chm_registered, (void *) MODE_REGISTERED},     /* r */
1453    {chm_simple, (void *) MODE_SECRET},             /* s */
1454    {chm_simple, (void *) MODE_TOPICLIMIT},         /* t */
1455    {chm_nosuch, NULL},                             /* u */
# Line 1297 | Line 1459 | static struct ChannelMode ModeTable[255]
1459    {chm_nosuch, NULL},                             /* y */
1460    {chm_nosuch, NULL},                             /* z */
1461   };
1300 – /* *INDENT-ON* */
1462  
1463   /* get_channel_access()
1464   *
# Line 1354 | Line 1515 | get_channel_access(struct Client *source
1515  
1516   static void
1517   send_cap_mode_changes(struct Client *client_p, struct Client *source_p,
1518 <                      struct Channel *chptr, int cap, int nocap)
1518 >                      struct Channel *chptr, unsigned int cap, unsigned int nocap)
1519   {
1520    int i, mbl, pbl, arglen, nc, mc;
1521    int len;
# Line 1370 | Line 1531 | send_cap_mode_changes(struct Client *cli
1531    parptr = parabuf;
1532  
1533    if ((cap & CAP_TS6) && source_p->id[0] != '\0')
1534 <    mbl = ircsprintf(modebuf, ":%s TMODE %lu %s ", source_p->id,
1534 >    mbl = sprintf(modebuf, ":%s TMODE %lu %s ", source_p->id,
1535                       (unsigned long)chptr->channelts, chptr->chname);
1536    else
1537 <    mbl = ircsprintf(modebuf, ":%s MODE %s ", source_p->name,
1537 >    mbl = sprintf(modebuf, ":%s MODE %s ", source_p->name,
1538                       chptr->chname);
1539  
1540    /* loop the list of - modes we have */
# Line 1412 | Line 1573 | send_cap_mode_changes(struct Client *cli
1573          (pbl + arglen + BAN_FUDGE) >= MODEBUFLEN)
1574      {
1575        if (nc != 0)
1576 <        sendto_server(client_p, source_p, chptr, cap, nocap,
1577 <                      LL_ICHAN | LL_ICLIENT, "%s %s",
1576 >        sendto_server(client_p, cap, nocap,
1577 >                      "%s %s",
1578                        modebuf, parabuf);
1579        nc = 0;
1580        mc = 0;
1581  
1582        if ((cap & CAP_TS6) && source_p->id[0] != '\0')
1583 <        mbl = ircsprintf(modebuf, ":%s MODE %s ", source_p->id,
1584 <                         chptr->chname);
1583 >        mbl = sprintf(modebuf, ":%s MODE %s ", source_p->id,
1584 >                      chptr->chname);
1585        else
1586 <        mbl = ircsprintf(modebuf, ":%s MODE %s ", source_p->name,
1587 <                         chptr->chname);
1586 >        mbl = sprintf(modebuf, ":%s MODE %s ", source_p->name,
1587 >                      chptr->chname);
1588  
1589        pbl = 0;
1590        parabuf[0] = '\0';
# Line 1443 | Line 1604 | send_cap_mode_changes(struct Client *cli
1604  
1605      if (arg != NULL)
1606      {
1607 <      len = ircsprintf(parptr, "%s ", arg);
1607 >      len = sprintf(parptr, "%s ", arg);
1608        pbl += len;
1609        parptr += len;
1610        mc++;
# Line 1454 | Line 1615 | send_cap_mode_changes(struct Client *cli
1615      parabuf[pbl - 1] = 0;
1616  
1617    if (nc != 0)
1618 <    sendto_server(client_p, source_p, chptr, cap, nocap,
1619 <                  LL_ICLIENT, "%s %s", modebuf, parabuf);
1618 >    sendto_server(client_p, cap, nocap,
1619 >                  "%s %s", modebuf, parabuf);
1620   }
1621  
1622   /* void send_mode_changes(struct Client *client_p,
# Line 1484 | Line 1645 | send_mode_changes(struct Client *client_
1645      return;
1646  
1647    if (IsServer(source_p))
1648 <    mbl = ircsprintf(modebuf, ":%s MODE %s ", (IsHidden(source_p) ||
1649 <                     ConfigServerHide.hide_servers) ?
1650 <                     me.name : source_p->name, chname);
1648 >    mbl = sprintf(modebuf, ":%s MODE %s ", (IsHidden(source_p) ||
1649 >                  ConfigServerHide.hide_servers) ?
1650 >                  me.name : source_p->name, chname);
1651    else
1652 <    mbl = ircsprintf(modebuf, ":%s!%s@%s MODE %s ", source_p->name,
1653 <                     source_p->username, source_p->host, chname);
1652 >    mbl = sprintf(modebuf, ":%s!%s@%s MODE %s ", source_p->name,
1653 >                  source_p->username, source_p->host, chname);
1654  
1655    mc = 0;
1656    nc = 0;
# Line 1519 | Line 1680 | send_mode_changes(struct Client *client_
1680          modebuf[mbl - 1] = '\0';
1681  
1682        if (nc != 0)
1683 <        sendto_channel_local(ALL_MEMBERS, NO, chptr, "%s %s", modebuf, parabuf);
1683 >        sendto_channel_local(ALL_MEMBERS, 0, chptr, "%s %s", modebuf, parabuf);
1684  
1685        nc = 0;
1686        mc = 0;
1687  
1688        if (IsServer(source_p))
1689 <        mbl = ircsprintf(modebuf, ":%s MODE %s ", me.name, chname);
1689 >        mbl = sprintf(modebuf, ":%s MODE %s ", me.name, chname);
1690        else
1691 <        mbl = ircsprintf(modebuf, ":%s!%s@%s MODE %s ", source_p->name,
1692 <                         source_p->username, source_p->host, chname);
1691 >        mbl = sprintf(modebuf, ":%s!%s@%s MODE %s ", source_p->name,
1692 >                      source_p->username, source_p->host, chname);
1693  
1694        pbl = 0;
1695        parabuf[0] = '\0';
# Line 1548 | Line 1709 | send_mode_changes(struct Client *client_
1709  
1710      if (arg != NULL)
1711      {
1712 <      len = ircsprintf(parptr, "%s ", arg);
1712 >      len = sprintf(parptr, "%s ", arg);
1713        pbl += len;
1714        parptr += len;
1715        mc++;
# Line 1559 | Line 1720 | send_mode_changes(struct Client *client_
1720      parabuf[pbl - 1] = 0;
1721  
1722    if (nc != 0)
1723 <    sendto_channel_local(ALL_MEMBERS, NO, chptr, "%s %s", modebuf, parabuf);
1723 >    sendto_channel_local(ALL_MEMBERS, 0, chptr, "%s %s", modebuf, parabuf);
1724  
1725    nc = 0;
1726    mc = 0;

Comparing:
ircd-hybrid/src/channel_mode.c (property svn:keywords), Revision 32 by knight, Sun Oct 2 20:41:23 2005 UTC vs.
ircd-hybrid/trunk/src/channel_mode.c (property svn:keywords), Revision 1937 by michael, Sat May 4 20:54:13 2013 UTC

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

Diff Legend

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