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-8/src/channel_mode.c (file contents), Revision 1495 by michael, Sun Aug 5 09:35:42 2012 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 "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 680 | Line 830 | chm_except(struct Client *client_p, stru
830   {
831    char *mask = NULL;
832  
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 –
833    if (alev < CHACCESS_HALFOP)
834    {
835      if (!(*errors & SM_ERR_NOOPS))
# Line 730 | Line 866 | chm_except(struct Client *client_p, stru
866    if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
867      return;
868  
869 <  mask = parv[(*parn)++];
869 >  mask = nuh_mask[*parn];
870 >  memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
871 >  ++*parn;
872  
873    if (IsServer(client_p))
874      if (strchr(mask, ' '))
# Line 754 | Line 892 | chm_except(struct Client *client_p, stru
892    mode_changes[mode_count].dir = dir;
893    mode_changes[mode_count].caps = CAP_EX;
894    mode_changes[mode_count].nocaps = 0;
895 <
758 <  if (ConfigChannel.use_except)
759 <    mode_changes[mode_count].mems = ONLY_CHANOPS;
760 <  else
761 <    mode_changes[mode_count].mems = ONLY_SERVERS;
762 <
895 >  mode_changes[mode_count].mems = ONLY_CHANOPS;
896    mode_changes[mode_count].id = NULL;
897    mode_changes[mode_count++].arg = mask;
898   }
# Line 772 | Line 905 | chm_invex(struct Client *client_p, struc
905   {
906    char *mask = NULL;
907  
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 –
908    if (alev < CHACCESS_HALFOP)
909    {
910      if (!(*errors & SM_ERR_NOOPS))
# Line 822 | Line 941 | chm_invex(struct Client *client_p, struc
941    if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
942      return;
943  
944 <  mask = parv[(*parn)++];
944 >  mask = nuh_mask[*parn];
945 >  memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
946 >  ++*parn;
947  
948    if (IsServer(client_p))
949      if (strchr(mask, ' '))
# Line 846 | Line 967 | chm_invex(struct Client *client_p, struc
967    mode_changes[mode_count].dir = dir;
968    mode_changes[mode_count].caps = CAP_IE;
969    mode_changes[mode_count].nocaps = 0;
970 <
850 <  if (ConfigChannel.use_invex)
851 <    mode_changes[mode_count].mems = ONLY_CHANOPS;
852 <  else
853 <    mode_changes[mode_count].mems = ONLY_SERVERS;
854 <
970 >  mode_changes[mode_count].mems = ONLY_CHANOPS;
971    mode_changes[mode_count].id = NULL;
972    mode_changes[mode_count++].arg = mask;
973   }
# Line 866 | Line 982 | clear_ban_cache(struct Channel *chptr)
982   {
983    dlink_node *ptr = NULL;
984  
985 <  DLINK_FOREACH(ptr, chptr->locmembers.head)
985 >  DLINK_FOREACH(ptr, chptr->members.head)
986 >  {
987 >    struct Membership *ms = ptr->data;
988 >
989 >    if (MyConnect(ms->client_p))
990 >      ms->flags &= ~(CHFL_BAN_SILENCED|CHFL_BAN_CHECKED);
991 >  }
992 > }
993 >
994 > void
995 > clear_ban_cache_client(struct Client *client_p)
996 > {
997 >  dlink_node *ptr = NULL;
998 >
999 >  DLINK_FOREACH(ptr, client_p->channel.head)
1000    {
1001      struct Membership *ms = ptr->data;
1002      ms->flags &= ~(CHFL_BAN_SILENCED|CHFL_BAN_CHECKED);
# Line 882 | Line 1012 | chm_op(struct Client *client_p, struct C
1012    char *opnick;
1013    struct Client *targ_p;
1014    struct Membership *member;
1015 +  int caps = 0;
1016  
1017    if (alev < CHACCESS_CHANOP)
1018    {
# Line 919 | Line 1050 | chm_op(struct Client *client_p, struct C
1050    if (dir == MODE_ADD &&  has_member_flags(member, CHFL_CHANOP))
1051      return;
1052    if (dir == MODE_DEL && !has_member_flags(member, CHFL_CHANOP))
1053 +  {
1054 + #ifdef HALFOPS
1055 +    if (has_member_flags(member, CHFL_HALFOP))
1056 +    {
1057 +      --*parn;
1058 +      chm_hop(client_p, source_p, chptr, parc, parn, parv, errors, alev,
1059 +              dir, c, d, chname);
1060 +    }
1061 + #endif
1062      return;
1063 +  }
1064 +
1065 + #ifdef HALFOPS
1066 +  if (dir == MODE_ADD && has_member_flags(member, CHFL_HALFOP))
1067 +  {
1068 +    /* promoting from % to @ is visible only to CAP_HOPS servers */
1069 +    mode_changes[mode_count].letter = 'h';
1070 +    mode_changes[mode_count].dir = MODE_DEL;
1071 +    mode_changes[mode_count].caps = caps = CAP_HOPS;
1072 +    mode_changes[mode_count].nocaps = 0;
1073 +    mode_changes[mode_count].mems = ALL_MEMBERS;
1074 +    mode_changes[mode_count].id = NULL;
1075 +    mode_changes[mode_count].arg = targ_p->name;
1076 +    mode_changes[mode_count++].client = targ_p;
1077 +  }
1078 + #endif
1079  
1080    mode_changes[mode_count].letter = 'o';
1081    mode_changes[mode_count].dir = dir;
1082 <  mode_changes[mode_count].caps = 0;
1082 >  mode_changes[mode_count].caps = caps;
1083    mode_changes[mode_count].nocaps = 0;
1084    mode_changes[mode_count].mems = ALL_MEMBERS;
1085    mode_changes[mode_count].id = targ_p->id;
# Line 933 | Line 1089 | chm_op(struct Client *client_p, struct C
1089    if (dir == MODE_ADD)
1090    {
1091      AddMemberFlag(member, CHFL_CHANOP);
1092 <    DelMemberFlag(member, CHFL_DEOPPED);
1092 >    DelMemberFlag(member, CHFL_DEOPPED | CHFL_HALFOP);
1093    }
1094    else
1095      DelMemberFlag(member, CHFL_CHANOP);
# Line 997 | Line 1153 | chm_hop(struct Client *client_p, struct
1153      return;
1154  
1155    /* no redundant mode changes */
1156 <  if (dir == MODE_ADD &&  has_member_flags(member, CHFL_HALFOP))
1156 >  if (dir == MODE_ADD &&  has_member_flags(member, CHFL_HALFOP | CHFL_CHANOP))
1157      return;
1158    if (dir == MODE_DEL && !has_member_flags(member, CHFL_HALFOP))
1159      return;
1160  
1161    mode_changes[mode_count].letter = 'h';
1162    mode_changes[mode_count].dir = dir;
1163 <  mode_changes[mode_count].caps = 0;
1163 >  mode_changes[mode_count].caps = CAP_HOPS;
1164    mode_changes[mode_count].nocaps = 0;
1165    mode_changes[mode_count].mems = ALL_MEMBERS;
1166    mode_changes[mode_count].id = targ_p->id;
1167    mode_changes[mode_count].arg = targ_p->name;
1168    mode_changes[mode_count++].client = targ_p;
1169  
1170 +  mode_changes[mode_count].letter = 'o';
1171 +  mode_changes[mode_count].dir = dir;
1172 +  mode_changes[mode_count].caps = 0;
1173 +  mode_changes[mode_count].nocaps = CAP_HOPS;
1174 +  mode_changes[mode_count].mems = ONLY_SERVERS;
1175 +  mode_changes[mode_count].id = targ_p->id;
1176 +  mode_changes[mode_count].arg = targ_p->name;
1177 +  mode_changes[mode_count++].client = targ_p;
1178 +
1179    if (dir == MODE_ADD)
1180    {
1181      AddMemberFlag(member, CHFL_HALFOP);
# Line 1230 | Line 1395 | struct ChannelMode
1395    void *d;
1396   };
1397  
1233 – /* *INDENT-OFF* */
1398   static struct ChannelMode ModeTable[255] =
1399   {
1400    {chm_nosuch, NULL},
# Line 1248 | Line 1412 | static struct ChannelMode ModeTable[255]
1412    {chm_nosuch, NULL},                             /* L */
1413    {chm_nosuch, NULL},                             /* M */
1414    {chm_nosuch, NULL},                             /* N */
1415 <  {chm_nosuch, NULL},                             /* O */
1415 >  {chm_operonly, (void *) MODE_OPERONLY},         /* O */
1416    {chm_nosuch, NULL},                             /* P */
1417    {chm_nosuch, NULL},                             /* Q */
1418 <  {chm_nosuch, NULL},                             /* R */
1419 <  {chm_nosuch, NULL},                             /* S */
1418 >  {chm_simple, (void *) MODE_REGONLY},            /* R */
1419 >  {chm_simple, (void *) MODE_SSLONLY},            /* S */
1420    {chm_nosuch, NULL},                             /* T */
1421    {chm_nosuch, NULL},                             /* U */
1422    {chm_nosuch, NULL},                             /* V */
# Line 1287 | Line 1451 | static struct ChannelMode ModeTable[255]
1451    {chm_op, NULL},                                 /* o */
1452    {chm_simple, (void *) MODE_PRIVATE},            /* p */
1453    {chm_nosuch, NULL},                             /* q */
1454 <  {chm_nosuch, NULL},                             /* r */
1454 >  {chm_registered, (void *) MODE_REGISTERED},     /* r */
1455    {chm_simple, (void *) MODE_SECRET},             /* s */
1456    {chm_simple, (void *) MODE_TOPICLIMIT},         /* t */
1457    {chm_nosuch, NULL},                             /* u */
# Line 1297 | Line 1461 | static struct ChannelMode ModeTable[255]
1461    {chm_nosuch, NULL},                             /* y */
1462    {chm_nosuch, NULL},                             /* z */
1463   };
1300 – /* *INDENT-ON* */
1464  
1465   /* get_channel_access()
1466   *
# Line 1354 | Line 1517 | get_channel_access(struct Client *source
1517  
1518   static void
1519   send_cap_mode_changes(struct Client *client_p, struct Client *source_p,
1520 <                      struct Channel *chptr, int cap, int nocap)
1520 >                      struct Channel *chptr, unsigned int cap, unsigned int nocap)
1521   {
1522    int i, mbl, pbl, arglen, nc, mc;
1523    int len;
# Line 1412 | Line 1575 | send_cap_mode_changes(struct Client *cli
1575          (pbl + arglen + BAN_FUDGE) >= MODEBUFLEN)
1576      {
1577        if (nc != 0)
1578 <        sendto_server(client_p, source_p, chptr, cap, nocap,
1579 <                      LL_ICHAN | LL_ICLIENT, "%s %s",
1578 >        sendto_server(client_p, cap, nocap,
1579 >                      "%s %s",
1580                        modebuf, parabuf);
1581        nc = 0;
1582        mc = 0;
# Line 1454 | Line 1617 | send_cap_mode_changes(struct Client *cli
1617      parabuf[pbl - 1] = 0;
1618  
1619    if (nc != 0)
1620 <    sendto_server(client_p, source_p, chptr, cap, nocap,
1621 <                  LL_ICLIENT, "%s %s", modebuf, parabuf);
1620 >    sendto_server(client_p, cap, nocap,
1621 >                  "%s %s", modebuf, parabuf);
1622   }
1623  
1624   /* void send_mode_changes(struct Client *client_p,
# Line 1519 | Line 1682 | send_mode_changes(struct Client *client_
1682          modebuf[mbl - 1] = '\0';
1683  
1684        if (nc != 0)
1685 <        sendto_channel_local(ALL_MEMBERS, NO, chptr, "%s %s", modebuf, parabuf);
1685 >        sendto_channel_local(ALL_MEMBERS, 0, chptr, "%s %s", modebuf, parabuf);
1686  
1687        nc = 0;
1688        mc = 0;
# Line 1559 | Line 1722 | send_mode_changes(struct Client *client_
1722      parabuf[pbl - 1] = 0;
1723  
1724    if (nc != 0)
1725 <    sendto_channel_local(ALL_MEMBERS, NO, chptr, "%s %s", modebuf, parabuf);
1725 >    sendto_channel_local(ALL_MEMBERS, 0, chptr, "%s %s", modebuf, parabuf);
1726  
1727    nc = 0;
1728    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-8/src/channel_mode.c (property svn:keywords), Revision 1495 by michael, Sun Aug 5 09:35:42 2012 UTC

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

Diff Legend

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