ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/channel_mode.c
(Generate patch)

Comparing ircd-hybrid/trunk/src/channel_mode.c (file contents):
Revision 3136 by michael, Tue Mar 11 18:24:03 2014 UTC vs.
Revision 3140 by michael, Wed Mar 12 19:23:20 2014 UTC

# Line 54 | Line 54 | static struct ChModeChange mode_changes[
54   static unsigned int mode_count;
55   static unsigned int mode_limit;  /* number of modes set other than simple */
56   static unsigned int simple_modes_mask;  /* bit mask of simple modes already set */
57 #ifdef HALFOPS
58 static int channel_capabs[] = { CAP_HOPS };
59 #else
60 static int channel_capabs[] = { 0 };
61 #endif
62 static struct ChCapCombo chcap_combos[NCHCAP_COMBOS];
57   extern mp_pool_t *ban_pool;
58  
59  
# Line 397 | Line 391 | fix_key_old(char *arg)
391   #define SM_ERR_NOTOPER      0x00000080
392   #define SM_ERR_ONLYSERVER   0x00000100
393  
400 /* Now lets do some stuff to keep track of what combinations of
401 * servers exist...
402 * Note that the number of combinations doubles each time you add
403 * something to this list. Each one is only quick if no servers use that
404 * combination, but if the numbers get too high here MODE will get too
405 * slow. I suggest if you get more than 7 here, you consider getting rid
406 * of some and merging or something. If it wasn't for irc+cs we would
407 * probably not even need to bother about most of these, but unfortunately
408 * we do. -A1kmm
409 */
410
411 /* void init_chcap_usage_counts(void)
412 *
413 * Inputs       - none
414 * Output       - none
415 * Side-effects - Initialises the usage counts to zero. Fills in the
416 *                chcap_yes and chcap_no combination tables.
417 */
418 void
419 init_chcap_usage_counts(void)
420 {
421  unsigned long m, c, y, n;
422
423  memset(chcap_combos, 0, sizeof(chcap_combos));
424
425  /* For every possible combination */
426  for (m = 0; m < NCHCAP_COMBOS; m++)
427  {
428    /* Check each capab */
429    for (c = y = n = 0; c < NCHCAPS; c++)
430    {
431      if ((m & (1 << c)) == 0)
432        n |= channel_capabs[c];
433      else
434        y |= channel_capabs[c];
435    }
436
437    chcap_combos[m].cap_yes = y;
438    chcap_combos[m].cap_no  = n;
439  }
440 }
441
442 /* void set_chcap_usage_counts(struct Client *serv_p)
443 * Input: serv_p; The client whose capabs to register.
444 * Output: none
445 * Side-effects: Increments the usage counts for the correct capab
446 *               combination.
447 */
448 void
449 set_chcap_usage_counts(struct Client *serv_p)
450 {
451  int n;
452
453  for (n = 0; n < NCHCAP_COMBOS; n++)
454  {
455    if (((serv_p->localClient->caps & chcap_combos[n].cap_yes) ==
456         chcap_combos[n].cap_yes) &&
457        ((serv_p->localClient->caps & chcap_combos[n].cap_no) == 0))
458    {
459      chcap_combos[n].count++;
460      return;
461    }
462  }
463
464  /* This should be impossible -A1kmm. */
465  assert(0);
466 }
467
468 /* void set_chcap_usage_counts(struct Client *serv_p)
469 *
470 * Inputs       - serv_p; The client whose capabs to register.
471 * Output       - none
472 * Side-effects - Decrements the usage counts for the correct capab
473 *                combination.
474 */
475 void
476 unset_chcap_usage_counts(struct Client *serv_p)
477 {
478  int n;
479
480  for (n = 0; n < NCHCAP_COMBOS; n++)
481  {
482    if ((serv_p->localClient->caps & chcap_combos[n].cap_yes) ==
483        chcap_combos[n].cap_yes &&
484        (serv_p->localClient->caps & chcap_combos[n].cap_no) == 0)
485    {
486      /* Hopefully capabs can't change dynamically or anything... */
487      assert(chcap_combos[n].count > 0);
488      chcap_combos[n].count--;
489      return;
490    }
491  }
492
493  /* This should be impossible -A1kmm. */
494  assert(0);
495 }
496
394   /* Mode functions handle mode changes for a particular mode... */
395   static void
396   chm_nosuch(struct Client *client_p, struct Client *source_p,
# Line 543 | Line 440 | chm_simple(struct Client *client_p, stru
440  
441      mode_changes[mode_count].letter = c;
442      mode_changes[mode_count].dir = MODE_ADD;
546    mode_changes[mode_count].caps = 0;
547    mode_changes[mode_count].nocaps = 0;
443      mode_changes[mode_count].id = NULL;
444      mode_changes[mode_count].mems = ALL_MEMBERS;
445      mode_changes[mode_count++].arg = NULL;
# Line 557 | Line 452 | chm_simple(struct Client *client_p, stru
452  
453      mode_changes[mode_count].letter = c;
454      mode_changes[mode_count].dir = MODE_DEL;
560    mode_changes[mode_count].caps = 0;
561    mode_changes[mode_count].nocaps = 0;
455      mode_changes[mode_count].mems = ALL_MEMBERS;
456      mode_changes[mode_count].id = NULL;
457      mode_changes[mode_count++].arg = NULL;
# Line 600 | Line 493 | chm_registered(struct Client *client_p,
493  
494      mode_changes[mode_count].letter = c;
495      mode_changes[mode_count].dir = MODE_ADD;
603    mode_changes[mode_count].caps = 0;
604    mode_changes[mode_count].nocaps = 0;
496      mode_changes[mode_count].id = NULL;
497      mode_changes[mode_count].mems = ALL_MEMBERS;
498      mode_changes[mode_count++].arg = NULL;
# Line 614 | Line 505 | chm_registered(struct Client *client_p,
505  
506      mode_changes[mode_count].letter = c;
507      mode_changes[mode_count].dir = MODE_DEL;
617    mode_changes[mode_count].caps = 0;
618    mode_changes[mode_count].nocaps = 0;
508      mode_changes[mode_count].mems = ALL_MEMBERS;
509      mode_changes[mode_count].id = NULL;
510      mode_changes[mode_count++].arg = NULL;
# Line 663 | Line 552 | chm_operonly(struct Client *client_p, st
552  
553      mode_changes[mode_count].letter = c;
554      mode_changes[mode_count].dir = MODE_ADD;
666    mode_changes[mode_count].caps = 0;
667    mode_changes[mode_count].nocaps = 0;
555      mode_changes[mode_count].id = NULL;
556      mode_changes[mode_count].mems = ALL_MEMBERS;
557      mode_changes[mode_count].mems = ALL_MEMBERS;
# Line 678 | Line 565 | chm_operonly(struct Client *client_p, st
565  
566      mode_changes[mode_count].letter = c;
567      mode_changes[mode_count].dir = MODE_DEL;
681    mode_changes[mode_count].caps = 0;
682    mode_changes[mode_count].nocaps = 0;
568      mode_changes[mode_count].mems = ALL_MEMBERS;
569      mode_changes[mode_count].id = NULL;
570      mode_changes[mode_count++].arg = NULL;
# Line 751 | Line 636 | chm_ban(struct Client *client_p, struct
636  
637    mode_changes[mode_count].letter = c;
638    mode_changes[mode_count].dir = dir;
754  mode_changes[mode_count].caps = 0;
755  mode_changes[mode_count].nocaps = 0;
639    mode_changes[mode_count].mems = ALL_MEMBERS;
640    mode_changes[mode_count].id = NULL;
641    mode_changes[mode_count++].arg = mask;
# Line 824 | Line 707 | chm_except(struct Client *client_p, stru
707  
708    mode_changes[mode_count].letter = c;
709    mode_changes[mode_count].dir = dir;
827  mode_changes[mode_count].caps = 0;
828  mode_changes[mode_count].nocaps = 0;
710    mode_changes[mode_count].mems = ONLY_CHANOPS;
711    mode_changes[mode_count].id = NULL;
712    mode_changes[mode_count++].arg = mask;
# Line 897 | Line 778 | chm_invex(struct Client *client_p, struc
778  
779    mode_changes[mode_count].letter = c;
780    mode_changes[mode_count].dir = dir;
900  mode_changes[mode_count].caps = 0;
901  mode_changes[mode_count].nocaps = 0;
781    mode_changes[mode_count].mems = ONLY_CHANOPS;
782    mode_changes[mode_count].id = NULL;
783    mode_changes[mode_count++].arg = mask;
# Line 983 | Line 862 | chm_voice(struct Client *client_p, struc
862  
863    mode_changes[mode_count].letter = 'v';
864    mode_changes[mode_count].dir = dir;
986  mode_changes[mode_count].caps = 0;
987  mode_changes[mode_count].nocaps = 0;
865    mode_changes[mode_count].mems = ALL_MEMBERS;
866    mode_changes[mode_count].id = targ_p->id;
867    mode_changes[mode_count].arg = targ_p->name;
# Line 1052 | Line 929 | chm_hop(struct Client *client_p, struct
929      return;
930  
931    /* no redundant mode changes */
932 <  if (dir == MODE_ADD &&  has_member_flags(member, CHFL_HALFOP | CHFL_CHANOP))
932 >  if (dir == MODE_ADD &&  has_member_flags(member, CHFL_HALFOP))
933      return;
934    if (dir == MODE_DEL && !has_member_flags(member, CHFL_HALFOP))
935      return;
936  
937    mode_changes[mode_count].letter = 'h';
938    mode_changes[mode_count].dir = dir;
1062  mode_changes[mode_count].caps = CAP_HOPS;
1063  mode_changes[mode_count].nocaps = 0;
939    mode_changes[mode_count].mems = ALL_MEMBERS;
940    mode_changes[mode_count].id = targ_p->id;
941    mode_changes[mode_count].arg = targ_p->name;
942    mode_changes[mode_count++].client = targ_p;
943  
1069  mode_changes[mode_count].letter = 'o';
1070  mode_changes[mode_count].dir = dir;
1071  mode_changes[mode_count].caps = 0;
1072  mode_changes[mode_count].nocaps = CAP_HOPS;
1073  mode_changes[mode_count].mems = ONLY_SERVERS;
1074  mode_changes[mode_count].id = targ_p->id;
1075  mode_changes[mode_count].arg = targ_p->name;
1076  mode_changes[mode_count++].client = targ_p;
1077
944    if (dir == MODE_ADD)
945    {
946      AddMemberFlag(member, CHFL_HALFOP);
# Line 1130 | Line 996 | chm_op(struct Client *client_p, struct C
996    if (dir == MODE_ADD &&  has_member_flags(member, CHFL_CHANOP))
997      return;
998    if (dir == MODE_DEL && !has_member_flags(member, CHFL_CHANOP))
1133  {
1134 #ifdef HALFOPS
1135    if (has_member_flags(member, CHFL_HALFOP))
1136    {
1137      --*parn;
1138      chm_hop(client_p, source_p, chptr, parc, parn, parv, errors, alev,
1139              dir, c, d);
1140    }
1141 #endif
999      return;
1143  }
1144
1145 #ifdef HALFOPS
1146  if (dir == MODE_ADD && has_member_flags(member, CHFL_HALFOP))
1147  {
1148    /* promoting from % to @ is visible only to CAP_HOPS servers */
1149    mode_changes[mode_count].letter = 'h';
1150    mode_changes[mode_count].dir = MODE_DEL;
1151    mode_changes[mode_count].caps = caps = CAP_HOPS;
1152    mode_changes[mode_count].nocaps = 0;
1153    mode_changes[mode_count].mems = ALL_MEMBERS;
1154    mode_changes[mode_count].id = NULL;
1155    mode_changes[mode_count].arg = targ_p->name;
1156    mode_changes[mode_count++].client = targ_p;
1157  }
1158 #endif
1000  
1001    mode_changes[mode_count].letter = 'o';
1002    mode_changes[mode_count].dir = dir;
1162  mode_changes[mode_count].caps = caps;
1163  mode_changes[mode_count].nocaps = 0;
1003    mode_changes[mode_count].mems = ALL_MEMBERS;
1004    mode_changes[mode_count].id = targ_p->id;
1005    mode_changes[mode_count].arg = targ_p->name;
# Line 1169 | Line 1008 | chm_op(struct Client *client_p, struct C
1008    if (dir == MODE_ADD)
1009    {
1010      AddMemberFlag(member, CHFL_CHANOP);
1011 <    DelMemberFlag(member, CHFL_DEOPPED | CHFL_HALFOP);
1011 >    DelMemberFlag(member, CHFL_DEOPPED);
1012    }
1013    else
1014      DelMemberFlag(member, CHFL_CHANOP);
# Line 1213 | Line 1052 | chm_limit(struct Client *client_p, struc
1052  
1053      mode_changes[mode_count].letter = c;
1054      mode_changes[mode_count].dir = MODE_ADD;
1216    mode_changes[mode_count].caps = 0;
1217    mode_changes[mode_count].nocaps = 0;
1055      mode_changes[mode_count].mems = ALL_MEMBERS;
1056      mode_changes[mode_count].id = NULL;
1057      mode_changes[mode_count++].arg = lstr;
# Line 1230 | Line 1067 | chm_limit(struct Client *client_p, struc
1067  
1068      mode_changes[mode_count].letter = c;
1069      mode_changes[mode_count].dir = MODE_DEL;
1233    mode_changes[mode_count].caps = 0;
1234    mode_changes[mode_count].nocaps = 0;
1070      mode_changes[mode_count].mems = ALL_MEMBERS;
1071      mode_changes[mode_count].id = NULL;
1072      mode_changes[mode_count++].arg = NULL;
# Line 1281 | Line 1116 | chm_key(struct Client *client_p, struct
1116  
1117      mode_changes[mode_count].letter = c;
1118      mode_changes[mode_count].dir = MODE_ADD;
1284    mode_changes[mode_count].caps = 0;
1285    mode_changes[mode_count].nocaps = 0;
1119      mode_changes[mode_count].mems = ALL_MEMBERS;
1120      mode_changes[mode_count].id = NULL;
1121      mode_changes[mode_count++].arg = chptr->mode.key;
# Line 1299 | Line 1132 | chm_key(struct Client *client_p, struct
1132  
1133      mode_changes[mode_count].letter = c;
1134      mode_changes[mode_count].dir = MODE_DEL;
1302    mode_changes[mode_count].caps = 0;
1303    mode_changes[mode_count].nocaps = 0;
1135      mode_changes[mode_count].mems = ALL_MEMBERS;
1136      mode_changes[mode_count].id = NULL;
1137      mode_changes[mode_count++].arg = "*";
# Line 1634 | Line 1465 | get_channel_access(const struct Client *
1465   /* rewritten to ensure parabuf < MODEBUFLEN -db */
1466  
1467   static void
1468 < send_cap_mode_changes(struct Client *client_p, struct Client *source_p,
1469 <                      struct Channel *chptr, unsigned int cap, unsigned int nocap)
1468 > send_mode_changes_server(struct Client *client_p, struct Client *source_p,
1469 >                         struct Channel *chptr)
1470   {
1471    unsigned int i;
1472    int mbl, pbl, arglen, nc, mc;
# Line 1655 | Line 1486 | send_cap_mode_changes(struct Client *cli
1486                   (unsigned long)chptr->channelts, chptr->chname);
1487  
1488    /* loop the list of - modes we have */
1489 <  for (i = 0; i < mode_count; i++)
1489 >  for (i = 0; i < mode_count; ++i)
1490    {
1491      /* if they dont support the cap we need, or they do support a cap they
1492       * cant have, then dont add it to the modebuf.. that way they wont see
1493       * the mode
1494       */
1495 <    if ((mode_changes[i].letter == 0) ||
1665 <        ((cap & mode_changes[i].caps) != mode_changes[i].caps) ||
1666 <        ((nocap & mode_changes[i].nocaps) != mode_changes[i].nocaps))
1495 >    if (mode_changes[i].letter == 0) /* XXX: can it ever happen? */
1496        continue;
1497  
1498      arg = mode_changes[i].id;
# Line 1679 | Line 1508 | send_cap_mode_changes(struct Client *cli
1508          (pbl + arglen + BAN_FUDGE) >= MODEBUFLEN)
1509      {
1510        if (nc != 0)
1511 <        sendto_server(client_p, cap, nocap, "%s %s", modebuf, parabuf);
1511 >        sendto_server(client_p, NOCAPS, NOCAPS, "%s %s", modebuf, parabuf);
1512        nc = 0;
1513        mc = 0;
1514  
# Line 1715 | Line 1544 | send_cap_mode_changes(struct Client *cli
1544      parabuf[pbl - 1] = 0;
1545  
1546    if (nc != 0)
1547 <    sendto_server(client_p, cap, nocap, "%s %s", modebuf, parabuf);
1547 >    sendto_server(client_p, NOCAPS, NOCAPS, "%s %s", modebuf, parabuf);
1548   }
1549  
1550   /* void send_mode_changes(struct Client *client_p,
# Line 1759 | Line 1588 | send_mode_changes(struct Client *client_
1588    parabuf[0] = '\0';
1589    parptr = parabuf;
1590  
1591 <  for (i = 0; i < mode_count; i++)
1591 >  for (i = 0; i < mode_count; ++i)
1592    {
1593      if (mode_changes[i].letter == 0 ||
1594          mode_changes[i].mems == NON_CHANOPS ||
# Line 1827 | Line 1656 | send_mode_changes(struct Client *client_
1656    nc = 0;
1657    mc = 0;
1658  
1659 <  /* Now send to servers... */
1831 <  for (i = 0; i < NCHCAP_COMBOS; i++)
1832 <    if (chcap_combos[i].count != 0)
1833 <      send_cap_mode_changes(client_p, source_p, chptr,
1834 <                            chcap_combos[i].cap_yes,
1835 <                            chcap_combos[i].cap_no);
1659 >  send_mode_changes_server(client_p, source_p, chptr);
1660   }
1661  
1662   /* void set_channel_mode(struct Client *client_p, struct Client *source_p,

Diff Legend

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