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 30 by adx, Sun Oct 2 20:03:27 2005 UTC vs.
ircd-hybrid-8/src/channel_mode.c (file contents), Revision 1474 by michael, Sun Jul 22 14:44:07 2012 UTC

# Line 19 | Line 19
19   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
20   *  USA
21   *
22 < *  $Id: channel_mode.c,v 7.165 2005/09/18 12:43:45 michael Exp $
22 > *  $Id$
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 "hostmask.h"
32   #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"
40 < #include "s_conf.h"             /* ConfigFileEntry, ConfigChannel */
40 > #include "conf.h"             /* ConfigFileEntry, ConfigChannel */
41   #include "event.h"
42   #include "memory.h"
43   #include "balloc.h"
44 < #include "s_log.h"
44 > #include "log.h"
45 > #include "parse.h"
46  
47   /* some small utility functions */
48   static char *check_string(char *);
# Line 54 | Line 54 | static void chm_nosuch(struct Client *,
54   static void chm_simple(struct Client *, struct Client *, struct Channel *,
55                         int, int *, char **, int *, int, int, char, void *,
56                         const char *);
57 + static void chm_registered(struct Client *, struct Client *, struct Channel *,
58 +                       int, int *, char **, int *, int, int, char, void *,
59 +                       const char *);
60   static void chm_limit(struct Client *, struct Client *, struct Channel *,
61                        int, int *, char **, int *, int, int, char, void *,
62                        const char *);
# Line 81 | Line 84 | static void chm_invex(struct Client *, s
84                        int, int *, char **, int *, int, int, char, void *,
85                        const char *);
86   static void send_cap_mode_changes(struct Client *, struct Client *,
87 <                                  struct Channel *, int, int);
87 >                                  struct Channel *, unsigned int, unsigned int);
88   static void send_mode_changes(struct Client *, struct Client *,
89                                struct Channel *, char *);
90  
# Line 90 | Line 93 | static void send_mode_changes(struct Cli
93   #define NCHCAPS         (sizeof(channel_capabs)/sizeof(int))
94   #define NCHCAP_COMBOS   (1 << NCHCAPS)
95  
96 + static char nuh_mask[MAXPARA][IRCD_BUFSIZE];
97   /* some buffers for rebuilding channel/nick lists with ,'s */
98   static char modebuf[IRCD_BUFSIZE];
99   static char parabuf[MODEBUFLEN];
# Line 97 | Line 101 | static struct ChModeChange mode_changes[
101   static int mode_count;
102   static int mode_limit;          /* number of modes set other than simple */
103   static int simple_modes_mask;   /* bit mask of simple modes already set */
104 + #ifdef HALFOPS
105 + static int channel_capabs[] = { CAP_EX, CAP_IE, CAP_TS6, CAP_HOPS };
106 + #else
107   static int channel_capabs[] = { CAP_EX, CAP_IE, CAP_TS6 };
108 + #endif
109   static struct ChCapCombo chcap_combos[NCHCAP_COMBOS];
110   extern BlockHeap *ban_heap;
111  
# Line 119 | Line 127 | check_string(char *s)
127    static char star[] = "*";
128  
129    if (EmptyString(s))
130 <    return (star);
130 >    return star;
131  
132    for (; *s; ++s)
133    {
# Line 130 | Line 138 | check_string(char *s)
138      }
139    }
140  
141 <  return (str);
141 >  return str;
142   }
143  
144   /*
# Line 143 | Line 151 | check_string(char *s)
151   int
152   add_id(struct Client *client_p, struct Channel *chptr, char *banid, int type)
153   {
154 <  dlink_list *list;
155 <  dlink_node *ban;
154 >  dlink_list *list = NULL;
155 >  dlink_node *ban = NULL;
156    size_t len = 0;
157 <  struct Ban *actualBan;
157 >  struct Ban *ban_p = NULL;
158    unsigned int num_mask;
159 <  char *name = NULL, *user = NULL, *host = NULL;
159 >  char name[NICKLEN + 1];
160 >  char user[USERLEN + 1];
161 >  char host[HOSTLEN + 1];
162 >  struct split_nuh_item nuh;
163  
164    /* dont let local clients overflow the b/e/I lists */
165    if (MyClient(client_p))
# Line 167 | Line 178 | add_id(struct Client *client_p, struct C
178      collapse(banid);
179    }
180  
181 <  split_nuh(check_string(banid), &name, &user, &host);
181 >  nuh.nuhmask  = check_string(banid);
182 >  nuh.nickptr  = name;
183 >  nuh.userptr  = user;
184 >  nuh.hostptr  = host;
185 >
186 >  nuh.nicksize = sizeof(name);
187 >  nuh.usersize = sizeof(user);
188 >  nuh.hostsize = sizeof(host);
189 >
190 >  split_nuh(&nuh);
191  
192    /*
193 <   * Assemble a n!u@h and print it back to banid for sending
193 >   * Re-assemble a new n!u@h and print it back to banid for sending
194     * the mode to the channel.
195     */
196    len = ircsprintf(banid, "%s!%s@%s", name, user, host);
# Line 195 | Line 215 | add_id(struct Client *client_p, struct C
215  
216    DLINK_FOREACH(ban, list->head)
217    {
218 <    actualBan = ban->data;
219 <    if (!irccmp(actualBan->name, name) &&
220 <        !irccmp(actualBan->username, user) &&
221 <        !irccmp(actualBan->host, host))
218 >    ban_p = ban->data;
219 >    if (!irccmp(ban_p->name, name) &&
220 >        !irccmp(ban_p->username, user) &&
221 >        !irccmp(ban_p->host, host))
222      {
203 –      MyFree(name);
204 –      MyFree(user);
205 –      MyFree(host);
223        return 0;
224      }
225    }
226  
227 <  actualBan = BlockHeapAlloc(ban_heap);
228 <  actualBan->when = CurrentTime;
229 <  actualBan->name = name;
230 <  actualBan->username = user;
231 <  actualBan->host = host;
232 <  actualBan->len = len-2; /* -2 for @ and ! */
227 >  ban_p = BlockHeapAlloc(ban_heap);
228 >
229 >  DupString(ban_p->name, name);
230 >  DupString(ban_p->username, user);
231 >  DupString(ban_p->host, host);
232 >
233 >  ban_p->when = CurrentTime;
234 >  ban_p->len = len - 2; /* -2 for @ and ! */
235 >  ban_p->type = parse_netmask(host, &ban_p->addr, &ban_p->bits);
236  
237    if (IsClient(client_p))
238    {
239 <    actualBan->who =
240 <      MyMalloc(strlen(client_p->name) +
241 <               strlen(client_p->username) +
242 <               strlen(client_p->host) + 3);
243 <    ircsprintf(actualBan->who, "%s!%s@%s",
224 <               client_p->name, client_p->username, client_p->host);
239 >    ban_p->who = MyMalloc(strlen(client_p->name) +
240 >                          strlen(client_p->username) +
241 >                          strlen(client_p->host) + 3);
242 >    ircsprintf(ban_p->who, "%s!%s@%s", client_p->name,
243 >               client_p->username, client_p->host);
244    }
245    else
246 <    DupString(actualBan->who, client_p->name);
246 >    DupString(ban_p->who, client_p->name);
247  
248 <  dlinkAdd(actualBan, &actualBan->node, list);
248 >  dlinkAdd(ban_p, &ban_p->node, list);
249  
250    return 1;
251   }
# Line 244 | Line 263 | del_id(struct Channel *chptr, char *bani
263    dlink_list *list;
264    dlink_node *ban;
265    struct Ban *banptr;
266 <  char *name = NULL, *user = NULL, *host = NULL;
266 >  char name[NICKLEN + 1];
267 >  char user[USERLEN + 1];
268 >  char host[HOSTLEN + 1];
269 >  struct split_nuh_item nuh;
270  
271    if (banid == NULL)
272      return 0;
273  
274 <  split_nuh(check_string(banid), &name, &user, &host);
274 >  nuh.nuhmask  = check_string(banid);
275 >  nuh.nickptr  = name;
276 >  nuh.userptr  = user;
277 >  nuh.hostptr  = host;
278 >
279 >  nuh.nicksize = sizeof(name);
280 >  nuh.usersize = sizeof(user);
281 >  nuh.hostsize = sizeof(host);
282 >
283 >  split_nuh(&nuh);
284  
285    /*
286 <   * Assemble a n!u@h and print it back to banid for sending
286 >   * Re-assemble a new n!u@h and print it back to banid for sending
287     * the mode to the channel.
288     */
289    ircsprintf(banid, "%s!%s@%s", name, user, host);
# Line 273 | Line 304 | del_id(struct Channel *chptr, char *bani
304      default:
305        sendto_realops_flags(UMODE_ALL, L_ALL,
306                             "del_id() called with unknown ban type %d!", type);
307 <      MyFree(name);
277 <      MyFree(user);
278 <      MyFree(host);
279 <      return(0);
307 >      return 0;
308    }
309  
310    DLINK_FOREACH(ban, list->head)
# Line 284 | Line 312 | del_id(struct Channel *chptr, char *bani
312      banptr = ban->data;
313  
314      if (!irccmp(name, banptr->name) &&
315 <        !irccmp(user, banptr->username) &&
316 <        !irccmp(host, banptr->host))
315 >        !irccmp(user, banptr->username) &&
316 >        !irccmp(host, banptr->host))
317      {
318        remove_ban(banptr, list);
291 –      MyFree(name);
292 –      MyFree(user);
293 –      MyFree(host);
319        return 1;
320      }
321    }
322  
298 –  MyFree(name);
299 –  MyFree(user);
300 –  MyFree(host);
323    return 0;
324   }
325  
326 < static const struct mode_letter
305 < {
306 <  const unsigned int mode;
307 <  const unsigned char letter;
308 < } flags[] = {
326 > const struct mode_letter chan_modes[] = {
327    { MODE_INVITEONLY, 'i' },
328    { MODE_MODERATED,  'm' },
329    { MODE_NOPRIVMSGS, 'n' },
330    { MODE_PRIVATE,    'p' },
331 +  { MODE_REGISTERED, 'r' },
332    { MODE_SECRET,     's' },
333    { MODE_TOPICLIMIT, 't' },
334 +  { MODE_OPERONLY,   'O' },
335 +  { MODE_REGONLY,    'R' },
336 +  { MODE_SSLONLY,    'S' },
337    { 0, '\0' }
338   };
339  
# Line 329 | Line 351 | void
351   channel_modes(struct Channel *chptr, struct Client *client_p,
352                char *mbuf, char *pbuf)
353   {
354 <  int i;
354 >  const struct mode_letter *tab = chan_modes;
355  
356    *mbuf++ = '+';
357    *pbuf = '\0';
358  
359 <  for (i = 0; flags[i].mode; ++i)
360 <    if (chptr->mode.mode & flags[i].mode)
361 <      *mbuf++ = flags[i].letter;
359 >  for (; tab->mode; ++tab)
360 >    if (chptr->mode.mode & tab->mode)
361 >      *mbuf++ = tab->letter;
362  
363    if (chptr->mode.limit)
364    {
365      *mbuf++ = 'l';
366  
367 <    if (IsMember(client_p, chptr) || IsServer(client_p))
367 >    if (IsServer(client_p) || HasFlag(client_p, FLAGS_SERVICE) || IsMember(client_p, chptr))
368        pbuf += ircsprintf(pbuf, "%d ", chptr->mode.limit);
369    }
370  
# Line 350 | Line 372 | channel_modes(struct Channel *chptr, str
372    {
373      *mbuf++ = 'k';
374  
375 <    if (*pbuf || IsMember(client_p, chptr) || IsServer(client_p))
375 >    if (IsServer(client_p) || HasFlag(client_p, FLAGS_SERVICE) || IsMember(client_p, chptr))
376        ircsprintf(pbuf, "%s ", chptr->mode.key);
377    }
378  
# Line 417 | Line 439 | fix_key_old(char *arg)
439   #define SM_ERR_RPL_E        0x00000010
440   #define SM_ERR_NOTONCHANNEL 0x00000020 /* Not on channel    */
441   #define SM_ERR_RPL_I        0x00000040
442 + #define SM_ERR_NOTOPER      0x00000080
443 + #define SM_ERR_ONLYSERVER   0x00000100
444  
445   /* Now lets do some stuff to keep track of what combinations of
446   * servers exist...
# Line 592 | Line 616 | chm_simple(struct Client *client_p, stru
616   }
617  
618   static void
619 + chm_registered(struct Client *client_p, struct Client *source_p, struct Channel *chptr,
620 +           int parc, int *parn, char **parv, int *errors, int alev, int dir,
621 +           char c, void *d, const char *chname)
622 + {
623 +  long mode_type;
624 +
625 +  mode_type = (long)d;
626 +
627 +
628 +  if (!IsServer(source_p) && !HasFlag(source_p, FLAGS_SERVICE))
629 +  {
630 +    if (!(*errors & SM_ERR_ONLYSERVER))
631 +      sendto_one(source_p, form_str(alev == CHACCESS_NOTONCHAN ?
632 +                                    ERR_NOTONCHANNEL : ERR_ONLYSERVERSCANCHANGE),
633 +                 me.name, source_p->name, chname);
634 +    *errors |= SM_ERR_ONLYSERVER;
635 +    return;
636 +  }
637 +
638 +  /* If have already dealt with this simple mode, ignore it */
639 +  if (simple_modes_mask & mode_type)
640 +    return;
641 +
642 +  simple_modes_mask |= mode_type;
643 +
644 +  /* setting + */
645 +  /* Apparently, (though no one has ever told the hybrid group directly)
646 +   * admins don't like redundant mode checking. ok. It would have been nice
647 +   * if you had have told us directly. I've left the original code snippets
648 +   * in place.
649 +   *
650 +   * -Dianora
651 +   */
652 +  if ((dir == MODE_ADD)) /* && !(chptr->mode.mode & mode_type)) */
653 +  {
654 +    chptr->mode.mode |= mode_type;
655 +
656 +    mode_changes[mode_count].letter = c;
657 +    mode_changes[mode_count].dir = MODE_ADD;
658 +    mode_changes[mode_count].caps = 0;
659 +    mode_changes[mode_count].nocaps = 0;
660 +    mode_changes[mode_count].id = NULL;
661 +    mode_changes[mode_count].mems = ALL_MEMBERS;
662 +    mode_changes[mode_count++].arg = NULL;
663 +  }
664 +  else if ((dir == MODE_DEL)) /* && (chptr->mode.mode & mode_type)) */
665 +  {
666 +    /* setting - */
667 +
668 +    chptr->mode.mode &= ~mode_type;
669 +
670 +    mode_changes[mode_count].letter = c;
671 +    mode_changes[mode_count].dir = MODE_DEL;
672 +    mode_changes[mode_count].caps = 0;
673 +    mode_changes[mode_count].nocaps = 0;
674 +    mode_changes[mode_count].mems = ALL_MEMBERS;
675 +    mode_changes[mode_count].id = NULL;
676 +    mode_changes[mode_count++].arg = NULL;
677 +  }
678 + }
679 +
680 + static void
681 + chm_operonly(struct Client *client_p, struct Client *source_p, struct Channel *chptr,
682 +            int parc, int *parn, char **parv, int *errors, int alev, int dir,
683 +            char c, void *d, const char *chname)
684 + {
685 +  long mode_type;
686 +
687 +  mode_type = (long)d;
688 +
689 +  if ((alev < CHACCESS_HALFOP) ||
690 +      ((mode_type == MODE_PRIVATE) && (alev < CHACCESS_CHANOP)))
691 +  {
692 +    if (!(*errors & SM_ERR_NOOPS))
693 +      sendto_one(source_p, form_str(alev == CHACCESS_NOTONCHAN ?
694 +                                    ERR_NOTONCHANNEL : ERR_CHANOPRIVSNEEDED),
695 +                 me.name, source_p->name, chname);
696 +    *errors |= SM_ERR_NOOPS;
697 +    return;
698 +  }
699 +  else if (MyClient(source_p) && !HasUMode(source_p, UMODE_OPER))
700 +  {
701 +    if (!(*errors & SM_ERR_NOTOPER))
702 +    {
703 +      if (alev == CHACCESS_NOTONCHAN)
704 +        sendto_one(source_p, form_str(ERR_NOTONCHANNEL),
705 +                   me.name, source_p->name, chname);
706 +      else
707 +        sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
708 +                   me.name, source_p->name);
709 +    }
710 +
711 +    *errors |= SM_ERR_NOTOPER;
712 +    return;
713 +  }
714 +
715 +  /* If have already dealt with this simple mode, ignore it */
716 +  if (simple_modes_mask & mode_type)
717 +    return;
718 +
719 +  simple_modes_mask |= mode_type;
720 +
721 +  if ((dir == MODE_ADD)) /* && !(chptr->mode.mode & mode_type)) */
722 +  {
723 +    chptr->mode.mode |= mode_type;
724 +
725 +    mode_changes[mode_count].letter = c;
726 +    mode_changes[mode_count].dir = MODE_ADD;
727 +    mode_changes[mode_count].caps = 0;
728 +    mode_changes[mode_count].nocaps = 0;
729 +    mode_changes[mode_count].id = NULL;
730 +    mode_changes[mode_count].mems = ALL_MEMBERS;
731 +    mode_changes[mode_count].mems = ALL_MEMBERS;
732 +    mode_changes[mode_count++].arg = NULL;
733 +  }
734 +  else if ((dir == MODE_DEL)) /* && (chptr->mode.mode & mode_type)) */
735 +  {
736 +    /* setting - */
737 +
738 +    chptr->mode.mode &= ~mode_type;
739 +
740 +    mode_changes[mode_count].letter = c;
741 +    mode_changes[mode_count].dir = MODE_DEL;
742 +    mode_changes[mode_count].caps = 0;
743 +    mode_changes[mode_count].nocaps = 0;
744 +    mode_changes[mode_count].mems = ALL_MEMBERS;
745 +    mode_changes[mode_count].id = NULL;
746 +    mode_changes[mode_count++].arg = NULL;
747 +  }
748 + }
749 +
750 + static void
751   chm_ban(struct Client *client_p, struct Client *source_p,
752          struct Channel *chptr, int parc, int *parn,
753          char **parv, int *errors, int alev, int dir, char c, void *d,
# Line 635 | Line 791 | chm_ban(struct Client *client_p, struct
791    if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
792      return;
793  
794 <  mask = parv[(*parn)++];
795 <  
794 >  mask = nuh_mask[*parn];
795 >  memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
796 >  ++*parn;
797 >
798    if (IsServer(client_p))
799      if (strchr(mask, ' '))
800        return;
# Line 648 | Line 806 | chm_ban(struct Client *client_p, struct
806          return;
807        break;
808      case MODE_DEL:
651 – /* XXX grrrrrrr */
652 – #ifdef NO_BAN_COOKIE
809        if (!del_id(chptr, mask, CHFL_BAN))
810          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
811        break;
812      default:
813        assert(0);
# Line 730 | Line 880 | chm_except(struct Client *client_p, stru
880    if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
881      return;
882  
883 <  mask = parv[(*parn)++];
883 >  mask = nuh_mask[*parn];
884 >  memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
885 >  ++*parn;
886  
887    if (IsServer(client_p))
888      if (strchr(mask, ' '))
# Line 822 | Line 974 | chm_invex(struct Client *client_p, struc
974    if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
975      return;
976  
977 <  mask = parv[(*parn)++];
977 >  mask = nuh_mask[*parn];
978 >  memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
979 >  ++*parn;
980  
981    if (IsServer(client_p))
982      if (strchr(mask, ' '))
# Line 866 | Line 1020 | clear_ban_cache(struct Channel *chptr)
1020   {
1021    dlink_node *ptr = NULL;
1022  
1023 <  DLINK_FOREACH(ptr, chptr->locmembers.head)
1023 >  DLINK_FOREACH(ptr, chptr->members.head)
1024 >  {
1025 >    struct Membership *ms = ptr->data;
1026 >
1027 >    if (MyConnect(ms->client_p))
1028 >      ms->flags &= ~(CHFL_BAN_SILENCED|CHFL_BAN_CHECKED);
1029 >  }
1030 > }
1031 >
1032 > void
1033 > clear_ban_cache_client(struct Client *client_p)
1034 > {
1035 >  dlink_node *ptr = NULL;
1036 >
1037 >  DLINK_FOREACH(ptr, client_p->channel.head)
1038    {
1039      struct Membership *ms = ptr->data;
1040      ms->flags &= ~(CHFL_BAN_SILENCED|CHFL_BAN_CHECKED);
# Line 882 | Line 1050 | chm_op(struct Client *client_p, struct C
1050    char *opnick;
1051    struct Client *targ_p;
1052    struct Membership *member;
1053 +  int caps = 0;
1054  
1055    if (alev < CHACCESS_CHANOP)
1056    {
# Line 919 | Line 1088 | chm_op(struct Client *client_p, struct C
1088    if (dir == MODE_ADD &&  has_member_flags(member, CHFL_CHANOP))
1089      return;
1090    if (dir == MODE_DEL && !has_member_flags(member, CHFL_CHANOP))
1091 +  {
1092 + #ifdef HALFOPS
1093 +    if (has_member_flags(member, CHFL_HALFOP))
1094 +    {
1095 +      --*parn;
1096 +      chm_hop(client_p, source_p, chptr, parc, parn, parv, errors, alev,
1097 +              dir, c, d, chname);
1098 +    }
1099 + #endif
1100      return;
1101 +  }
1102 +
1103 + #ifdef HALFOPS
1104 +  if (dir == MODE_ADD && has_member_flags(member, CHFL_HALFOP))
1105 +  {
1106 +    /* promoting from % to @ is visible only to CAP_HOPS servers */
1107 +    mode_changes[mode_count].letter = 'h';
1108 +    mode_changes[mode_count].dir = MODE_DEL;
1109 +    mode_changes[mode_count].caps = caps = CAP_HOPS;
1110 +    mode_changes[mode_count].nocaps = 0;
1111 +    mode_changes[mode_count].mems = ALL_MEMBERS;
1112 +    mode_changes[mode_count].id = NULL;
1113 +    mode_changes[mode_count].arg = targ_p->name;
1114 +    mode_changes[mode_count++].client = targ_p;
1115 +  }
1116 + #endif
1117  
1118    mode_changes[mode_count].letter = 'o';
1119    mode_changes[mode_count].dir = dir;
1120 <  mode_changes[mode_count].caps = 0;
1120 >  mode_changes[mode_count].caps = caps;
1121    mode_changes[mode_count].nocaps = 0;
1122    mode_changes[mode_count].mems = ALL_MEMBERS;
1123    mode_changes[mode_count].id = targ_p->id;
# Line 933 | Line 1127 | chm_op(struct Client *client_p, struct C
1127    if (dir == MODE_ADD)
1128    {
1129      AddMemberFlag(member, CHFL_CHANOP);
1130 <    DelMemberFlag(member, CHFL_DEOPPED);
1130 >    DelMemberFlag(member, CHFL_DEOPPED | CHFL_HALFOP);
1131    }
1132    else
1133      DelMemberFlag(member, CHFL_CHANOP);
# Line 997 | Line 1191 | chm_hop(struct Client *client_p, struct
1191      return;
1192  
1193    /* no redundant mode changes */
1194 <  if (dir == MODE_ADD &&  has_member_flags(member, CHFL_HALFOP))
1194 >  if (dir == MODE_ADD &&  has_member_flags(member, CHFL_HALFOP | CHFL_CHANOP))
1195      return;
1196    if (dir == MODE_DEL && !has_member_flags(member, CHFL_HALFOP))
1197      return;
1198  
1199    mode_changes[mode_count].letter = 'h';
1200    mode_changes[mode_count].dir = dir;
1201 <  mode_changes[mode_count].caps = 0;
1201 >  mode_changes[mode_count].caps = CAP_HOPS;
1202    mode_changes[mode_count].nocaps = 0;
1203    mode_changes[mode_count].mems = ALL_MEMBERS;
1204    mode_changes[mode_count].id = targ_p->id;
1205    mode_changes[mode_count].arg = targ_p->name;
1206    mode_changes[mode_count++].client = targ_p;
1207  
1208 +  mode_changes[mode_count].letter = 'o';
1209 +  mode_changes[mode_count].dir = dir;
1210 +  mode_changes[mode_count].caps = 0;
1211 +  mode_changes[mode_count].nocaps = CAP_HOPS;
1212 +  mode_changes[mode_count].mems = ONLY_SERVERS;
1213 +  mode_changes[mode_count].id = targ_p->id;
1214 +  mode_changes[mode_count].arg = targ_p->name;
1215 +  mode_changes[mode_count++].client = targ_p;
1216 +
1217    if (dir == MODE_ADD)
1218    {
1219      AddMemberFlag(member, CHFL_HALFOP);
# Line 1230 | Line 1433 | struct ChannelMode
1433    void *d;
1434   };
1435  
1233 – /* *INDENT-OFF* */
1436   static struct ChannelMode ModeTable[255] =
1437   {
1438    {chm_nosuch, NULL},
# Line 1248 | Line 1450 | static struct ChannelMode ModeTable[255]
1450    {chm_nosuch, NULL},                             /* L */
1451    {chm_nosuch, NULL},                             /* M */
1452    {chm_nosuch, NULL},                             /* N */
1453 <  {chm_nosuch, NULL},                             /* O */
1453 >  {chm_operonly, (void *) MODE_OPERONLY},         /* O */
1454    {chm_nosuch, NULL},                             /* P */
1455    {chm_nosuch, NULL},                             /* Q */
1456 <  {chm_nosuch, NULL},                             /* R */
1457 <  {chm_nosuch, NULL},                             /* S */
1456 >  {chm_simple, (void *) MODE_REGONLY},            /* R */
1457 >  {chm_simple, (void *) MODE_SSLONLY},            /* S */
1458    {chm_nosuch, NULL},                             /* T */
1459    {chm_nosuch, NULL},                             /* U */
1460    {chm_nosuch, NULL},                             /* V */
# Line 1287 | Line 1489 | static struct ChannelMode ModeTable[255]
1489    {chm_op, NULL},                                 /* o */
1490    {chm_simple, (void *) MODE_PRIVATE},            /* p */
1491    {chm_nosuch, NULL},                             /* q */
1492 <  {chm_nosuch, NULL},                             /* r */
1492 >  {chm_registered, (void *) MODE_REGISTERED},     /* r */
1493    {chm_simple, (void *) MODE_SECRET},             /* s */
1494    {chm_simple, (void *) MODE_TOPICLIMIT},         /* t */
1495    {chm_nosuch, NULL},                             /* u */
# Line 1297 | Line 1499 | static struct ChannelMode ModeTable[255]
1499    {chm_nosuch, NULL},                             /* y */
1500    {chm_nosuch, NULL},                             /* z */
1501   };
1300 – /* *INDENT-ON* */
1502  
1503   /* get_channel_access()
1504   *
# Line 1354 | Line 1555 | get_channel_access(struct Client *source
1555  
1556   static void
1557   send_cap_mode_changes(struct Client *client_p, struct Client *source_p,
1558 <                      struct Channel *chptr, int cap, int nocap)
1558 >                      struct Channel *chptr, unsigned int cap, unsigned int nocap)
1559   {
1560    int i, mbl, pbl, arglen, nc, mc;
1561    int len;
# Line 1412 | Line 1613 | send_cap_mode_changes(struct Client *cli
1613          (pbl + arglen + BAN_FUDGE) >= MODEBUFLEN)
1614      {
1615        if (nc != 0)
1616 <        sendto_server(client_p, source_p, chptr, cap, nocap,
1617 <                      LL_ICHAN | LL_ICLIENT, "%s %s",
1616 >        sendto_server(client_p, cap, nocap,
1617 >                      "%s %s",
1618                        modebuf, parabuf);
1619        nc = 0;
1620        mc = 0;
# Line 1454 | Line 1655 | send_cap_mode_changes(struct Client *cli
1655      parabuf[pbl - 1] = 0;
1656  
1657    if (nc != 0)
1658 <    sendto_server(client_p, source_p, chptr, cap, nocap,
1659 <                  LL_ICLIENT, "%s %s", modebuf, parabuf);
1658 >    sendto_server(client_p, cap, nocap,
1659 >                  "%s %s", modebuf, parabuf);
1660   }
1661  
1662   /* void send_mode_changes(struct Client *client_p,
# Line 1519 | Line 1720 | send_mode_changes(struct Client *client_
1720          modebuf[mbl - 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;
# Line 1559 | Line 1760 | send_mode_changes(struct Client *client_
1760      parabuf[pbl - 1] = 0;
1761  
1762    if (nc != 0)
1763 <    sendto_channel_local(ALL_MEMBERS, NO, chptr, "%s %s", modebuf, parabuf);
1763 >    sendto_channel_local(ALL_MEMBERS, 0, chptr, "%s %s", modebuf, parabuf);
1764  
1765    nc = 0;
1766    mc = 0;

Comparing:
ircd-hybrid/src/channel_mode.c (property svn:keywords), Revision 30 by adx, Sun Oct 2 20:03:27 2005 UTC vs.
ircd-hybrid-8/src/channel_mode.c (property svn:keywords), Revision 1474 by michael, Sun Jul 22 14:44:07 2012 UTC

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

Diff Legend

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