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-7.2/src/channel_mode.c (file contents), Revision 356 by adx, Mon Jan 2 22:05:15 2006 UTC vs.
ircd-hybrid-7.3/src/channel_mode.c (file contents), Revision 1150 by michael, Wed Aug 3 01:09:49 2011 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"
31   #include "hash.h"
32 + #include "hostmask.h"
33   #include "irc_string.h"
34   #include "sprintf_irc.h"
35   #include "ircd.h"
35 #include "list.h"
36   #include "numeric.h"
37   #include "s_serv.h"             /* captab */
38   #include "s_user.h"
# Line 43 | Line 43
43   #include "memory.h"
44   #include "balloc.h"
45   #include "s_log.h"
46 + #include "msg.h"
47  
48   /* some small utility functions */
49   static char *check_string(char *);
# Line 81 | Line 82 | static void chm_invex(struct Client *, s
82                        int, int *, char **, int *, int, int, char, void *,
83                        const char *);
84   static void send_cap_mode_changes(struct Client *, struct Client *,
85 <                                  struct Channel *, int, int);
85 >                                  struct Channel *, unsigned int, unsigned int);
86   static void send_mode_changes(struct Client *, struct Client *,
87                                struct Channel *, char *);
88  
# Line 90 | Line 91 | static void send_mode_changes(struct Cli
91   #define NCHCAPS         (sizeof(channel_capabs)/sizeof(int))
92   #define NCHCAP_COMBOS   (1 << NCHCAPS)
93  
94 + static char nuh_mask[MAXPARA][IRCD_BUFSIZE];
95   /* some buffers for rebuilding channel/nick lists with ,'s */
96   static char modebuf[IRCD_BUFSIZE];
97   static char parabuf[MODEBUFLEN];
# Line 123 | Line 125 | check_string(char *s)
125    static char star[] = "*";
126  
127    if (EmptyString(s))
128 <    return (star);
128 >    return star;
129  
130    for (; *s; ++s)
131    {
# Line 134 | Line 136 | check_string(char *s)
136      }
137    }
138  
139 <  return (str);
139 >  return str;
140   }
141  
142   /*
# Line 147 | 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];
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 171 | 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);
# Line 199 | 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      {
207      MyFree(name);
208      MyFree(user);
209      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 = BlockHeapAlloc(ban_heap);
226 >
227 >  DupString(ban_p->name, name);
228 >  DupString(ban_p->username, user);
229 >  DupString(ban_p->host, host);
230 >
231 >  ban_p->when = CurrentTime;
232 >  ban_p->len = len - 2; /* -2 for @ and ! */
233 >  ban_p->type = parse_netmask(host, &ban_p->addr, &ban_p->bits);
234  
235    if (IsClient(client_p))
236    {
237 <    actualBan->who =
238 <      MyMalloc(strlen(client_p->name) +
239 <               strlen(client_p->username) +
240 <               strlen(client_p->host) + 3);
241 <    ircsprintf(actualBan->who, "%s!%s@%s",
228 <               client_p->name, client_p->username, client_p->host);
237 >    ban_p->who = MyMalloc(strlen(client_p->name) +
238 >                          strlen(client_p->username) +
239 >                          strlen(client_p->host) + 3);
240 >    ircsprintf(ban_p->who, "%s!%s@%s", client_p->name,
241 >               client_p->username, client_p->host);
242    }
243    else
244 <    DupString(actualBan->who, client_p->name);
244 >    DupString(ban_p->who, client_p->name);
245  
246 <  dlinkAdd(actualBan, &actualBan->node, list);
246 >  dlinkAdd(ban_p, &ban_p->node, list);
247  
248    return 1;
249   }
# Line 248 | Line 261 | del_id(struct Channel *chptr, char *bani
261    dlink_list *list;
262    dlink_node *ban;
263    struct Ban *banptr;
264 <  char *name = NULL, *user = NULL, *host = NULL;
264 >  char name[NICKLEN];
265 >  char user[USERLEN + 1];
266 >  char host[HOSTLEN + 1];
267 >  struct split_nuh_item nuh;
268  
269    if (banid == NULL)
270      return 0;
271  
272 <  split_nuh(check_string(banid), &name, &user, &host);
272 >  nuh.nuhmask  = check_string(banid);
273 >  nuh.nickptr  = name;
274 >  nuh.userptr  = user;
275 >  nuh.hostptr  = host;
276 >
277 >  nuh.nicksize = sizeof(name);
278 >  nuh.usersize = sizeof(user);
279 >  nuh.hostsize = sizeof(host);
280 >
281 >  split_nuh(&nuh);
282  
283    /*
284 <   * Assemble a n!u@h and print it back to banid for sending
284 >   * Re-assemble a new n!u@h and print it back to banid for sending
285     * the mode to the channel.
286     */
287    ircsprintf(banid, "%s!%s@%s", name, user, host);
# Line 277 | Line 302 | del_id(struct Channel *chptr, char *bani
302      default:
303        sendto_realops_flags(UMODE_ALL, L_ALL,
304                             "del_id() called with unknown ban type %d!", type);
305 <      MyFree(name);
281 <      MyFree(user);
282 <      MyFree(host);
283 <      return(0);
305 >      return 0;
306    }
307  
308    DLINK_FOREACH(ban, list->head)
# Line 288 | Line 310 | del_id(struct Channel *chptr, char *bani
310      banptr = ban->data;
311  
312      if (!irccmp(name, banptr->name) &&
313 <        !irccmp(user, banptr->username) &&
314 <        !irccmp(host, banptr->host))
313 >        !irccmp(user, banptr->username) &&
314 >        !irccmp(host, banptr->host))
315      {
316        remove_ban(banptr, list);
295      MyFree(name);
296      MyFree(user);
297      MyFree(host);
317        return 1;
318      }
319    }
320  
302  MyFree(name);
303  MyFree(user);
304  MyFree(host);
321    return 0;
322   }
323  
# Line 316 | Line 332 | static const struct mode_letter
332    { MODE_PRIVATE,    'p' },
333    { MODE_SECRET,     's' },
334    { MODE_TOPICLIMIT, 't' },
335 +  { MODE_OPERONLY,   'O' },
336 +  { MODE_SSLONLY,    'S' },
337    { 0, '\0' }
338   };
339  
# Line 421 | 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  
444   /* Now lets do some stuff to keep track of what combinations of
445   * servers exist...
# Line 596 | Line 615 | chm_simple(struct Client *client_p, stru
615   }
616  
617   static void
618 + chm_operonly(struct Client *client_p, struct Client *source_p, struct Channel *chptr,
619 +            int parc, int *parn, char **parv, int *errors, int alev, int dir,
620 +            char c, void *d, const char *chname)
621 + {
622 +  long mode_type;
623 +
624 +  mode_type = (long)d;
625 +
626 +  if ((alev < CHACCESS_HALFOP) ||
627 +      ((mode_type == MODE_PRIVATE) && (alev < CHACCESS_CHANOP)))
628 +  {
629 +    if (!(*errors & SM_ERR_NOOPS))
630 +      sendto_one(source_p, form_str(alev == CHACCESS_NOTONCHAN ?
631 +                                    ERR_NOTONCHANNEL : ERR_CHANOPRIVSNEEDED),
632 +                 me.name, source_p->name, chname);
633 +    *errors |= SM_ERR_NOOPS;
634 +    return;
635 +  }
636 +  else if (MyClient(source_p) && !IsOper(source_p))
637 +  {
638 +    if (!(*errors & SM_ERR_NOTOPER))
639 +    {
640 +      if (alev == CHACCESS_NOTONCHAN)
641 +        sendto_one(source_p, form_str(ERR_NOTONCHANNEL),
642 +                   me.name, source_p->name, chname);
643 +      else
644 +        sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
645 +                   me.name, source_p->name);
646 +    }
647 +
648 +    *errors |= SM_ERR_NOTOPER;
649 +    return;
650 +  }
651 +
652 +  /* If have already dealt with this simple mode, ignore it */
653 +  if (simple_modes_mask & mode_type)
654 +    return;
655 +
656 +  simple_modes_mask |= mode_type;
657 +
658 +  if ((dir == MODE_ADD)) /* && !(chptr->mode.mode & mode_type)) */
659 +  {
660 +    chptr->mode.mode |= mode_type;
661 +
662 +    mode_changes[mode_count].letter = c;
663 +    mode_changes[mode_count].dir = MODE_ADD;
664 +    mode_changes[mode_count].caps = 0;
665 +    mode_changes[mode_count].nocaps = 0;
666 +    mode_changes[mode_count].id = NULL;
667 +    mode_changes[mode_count].mems = ALL_MEMBERS;
668 +    mode_changes[mode_count].mems = ALL_MEMBERS;
669 +    mode_changes[mode_count++].arg = NULL;
670 +  }
671 +  else if ((dir == MODE_DEL)) /* && (chptr->mode.mode & mode_type)) */
672 +  {
673 +    /* setting - */
674 +
675 +    chptr->mode.mode &= ~mode_type;
676 +
677 +    mode_changes[mode_count].letter = c;
678 +    mode_changes[mode_count].dir = MODE_DEL;
679 +    mode_changes[mode_count].caps = 0;
680 +    mode_changes[mode_count].nocaps = 0;
681 +    mode_changes[mode_count].mems = ALL_MEMBERS;
682 +    mode_changes[mode_count].id = NULL;
683 +    mode_changes[mode_count++].arg = NULL;
684 +  }
685 + }
686 +
687 + static void
688   chm_ban(struct Client *client_p, struct Client *source_p,
689          struct Channel *chptr, int parc, int *parn,
690          char **parv, int *errors, int alev, int dir, char c, void *d,
# Line 639 | Line 728 | chm_ban(struct Client *client_p, struct
728    if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
729      return;
730  
731 <  mask = parv[(*parn)++];
732 <  
731 >  mask = nuh_mask[*parn];
732 >  memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
733 >  ++*parn;
734 >
735    if (IsServer(client_p))
736      if (strchr(mask, ' '))
737        return;
# Line 652 | Line 743 | chm_ban(struct Client *client_p, struct
743          return;
744        break;
745      case MODE_DEL:
655 /* XXX grrrrrrr */
656 #ifdef NO_BAN_COOKIE
746        if (!del_id(chptr, mask, CHFL_BAN))
747          return;
659 #else
660     /* XXX this hack allows /mode * +o-b nick ban.cookie
661      * I'd like to see this hack go away in the future.
662      */
663      del_id(chptr, mask, CHFL_BAN);
664 #endif
748        break;
749      default:
750        assert(0);
# Line 734 | Line 817 | chm_except(struct Client *client_p, stru
817    if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
818      return;
819  
820 <  mask = parv[(*parn)++];
820 >  mask = nuh_mask[*parn];
821 >  memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
822 >  ++*parn;
823  
824    if (IsServer(client_p))
825      if (strchr(mask, ' '))
# Line 826 | Line 911 | chm_invex(struct Client *client_p, struc
911    if (MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
912      return;
913  
914 <  mask = parv[(*parn)++];
914 >  mask = nuh_mask[*parn];
915 >  memcpy(mask, parv[*parn], sizeof(nuh_mask[*parn]));
916 >  ++*parn;
917  
918    if (IsServer(client_p))
919      if (strchr(mask, ' '))
# Line 870 | Line 957 | clear_ban_cache(struct Channel *chptr)
957   {
958    dlink_node *ptr = NULL;
959  
960 <  DLINK_FOREACH(ptr, chptr->locmembers.head)
960 >  DLINK_FOREACH(ptr, chptr->members.head)
961 >  {
962 >    struct Membership *ms = ptr->data;
963 >
964 >    if (MyConnect(ms->client_p))
965 >      ms->flags &= ~(CHFL_BAN_SILENCED|CHFL_BAN_CHECKED);
966 >  }
967 > }
968 >
969 > void
970 > clear_ban_cache_client(struct Client *client_p)
971 > {
972 >  dlink_node *ptr = NULL;
973 >
974 >  DLINK_FOREACH(ptr, client_p->channel.head)
975    {
976      struct Membership *ms = ptr->data;
977      ms->flags &= ~(CHFL_BAN_SILENCED|CHFL_BAN_CHECKED);
# Line 927 | Line 1028 | chm_op(struct Client *client_p, struct C
1028    {
1029   #ifdef HALFOPS
1030      if (has_member_flags(member, CHFL_HALFOP))
1031 +    {
1032 +      --*parn;
1033        chm_hop(client_p, source_p, chptr, parc, parn, parv, errors, alev,
1034                dir, c, d, chname);
1035 +    }
1036   #endif
1037      return;
1038    }
# Line 1266 | Line 1370 | struct ChannelMode
1370    void *d;
1371   };
1372  
1269 /* *INDENT-OFF* */
1373   static struct ChannelMode ModeTable[255] =
1374   {
1375    {chm_nosuch, NULL},
# Line 1284 | Line 1387 | static struct ChannelMode ModeTable[255]
1387    {chm_nosuch, NULL},                             /* L */
1388    {chm_nosuch, NULL},                             /* M */
1389    {chm_nosuch, NULL},                             /* N */
1390 <  {chm_nosuch, NULL},                             /* O */
1390 >  {chm_operonly, (void *) MODE_OPERONLY},         /* O */
1391    {chm_nosuch, NULL},                             /* P */
1392    {chm_nosuch, NULL},                             /* Q */
1393    {chm_nosuch, NULL},                             /* R */
1394 <  {chm_nosuch, NULL},                             /* S */
1394 >  {chm_simple, (void *) MODE_SSLONLY},            /* S */
1395    {chm_nosuch, NULL},                             /* T */
1396    {chm_nosuch, NULL},                             /* U */
1397    {chm_nosuch, NULL},                             /* V */
# Line 1333 | Line 1436 | static struct ChannelMode ModeTable[255]
1436    {chm_nosuch, NULL},                             /* y */
1437    {chm_nosuch, NULL},                             /* z */
1438   };
1336 /* *INDENT-ON* */
1439  
1440   /* get_channel_access()
1441   *
# Line 1390 | Line 1492 | get_channel_access(struct Client *source
1492  
1493   static void
1494   send_cap_mode_changes(struct Client *client_p, struct Client *source_p,
1495 <                      struct Channel *chptr, int cap, int nocap)
1495 >                      struct Channel *chptr, unsigned int cap, unsigned int nocap)
1496   {
1497    int i, mbl, pbl, arglen, nc, mc;
1498    int len;
# Line 1448 | Line 1550 | send_cap_mode_changes(struct Client *cli
1550          (pbl + arglen + BAN_FUDGE) >= MODEBUFLEN)
1551      {
1552        if (nc != 0)
1553 <        sendto_server(client_p, source_p, chptr, cap, nocap,
1554 <                      LL_ICHAN | LL_ICLIENT, "%s %s",
1553 >        sendto_server(client_p, chptr, cap, nocap,
1554 >                      "%s %s",
1555                        modebuf, parabuf);
1556        nc = 0;
1557        mc = 0;
# Line 1490 | Line 1592 | send_cap_mode_changes(struct Client *cli
1592      parabuf[pbl - 1] = 0;
1593  
1594    if (nc != 0)
1595 <    sendto_server(client_p, source_p, chptr, cap, nocap,
1596 <                  LL_ICLIENT, "%s %s", modebuf, parabuf);
1595 >    sendto_server(client_p, chptr, cap, nocap,
1596 >                  "%s %s", modebuf, parabuf);
1597   }
1598  
1599   /* void send_mode_changes(struct Client *client_p,

Diff Legend

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