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 |
|
|
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, |
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; |
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; |
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; |
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; |
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; |
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; |
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; |
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; |
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; |
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; |
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); |
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; |
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); |
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; |
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; |
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; |
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 = "*"; |
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; |
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; |
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 |
|
|
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, |
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 || |
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, |