547 |
|
get_member_status(const struct Membership *ms, int combine) |
548 |
|
{ |
549 |
|
static char buffer[4]; |
550 |
< |
char *p = NULL; |
551 |
< |
|
552 |
< |
if (ms == NULL) |
553 |
< |
return ""; |
554 |
< |
p = buffer; |
550 |
> |
char *p = buffer; |
551 |
|
|
552 |
|
if (ms->flags & CHFL_CHANOP) |
553 |
|
{ |
693 |
|
return NULL; |
694 |
|
} |
695 |
|
|
696 |
+ |
/* |
697 |
+ |
* Basically the same functionality as in bahamut |
698 |
+ |
*/ |
699 |
+ |
static int |
700 |
+ |
msg_has_ctrls(const char *message) |
701 |
+ |
{ |
702 |
+ |
const unsigned char *p = (const unsigned char *)message; |
703 |
+ |
|
704 |
+ |
for (; *p; ++p) |
705 |
+ |
{ |
706 |
+ |
if (*p > 31 || *p == 1) |
707 |
+ |
continue; |
708 |
+ |
|
709 |
+ |
if (*p == 27) |
710 |
+ |
{ |
711 |
+ |
if (*(p + 1) == '$' || |
712 |
+ |
*(p + 1) == '(') |
713 |
+ |
{ |
714 |
+ |
++p; |
715 |
+ |
continue; |
716 |
+ |
} |
717 |
+ |
} |
718 |
+ |
|
719 |
+ |
return 1; |
720 |
+ |
} |
721 |
+ |
|
722 |
+ |
return 0; |
723 |
+ |
} |
724 |
+ |
|
725 |
|
/*! |
726 |
|
* \param chptr pointer to Channel struct |
727 |
|
* \param source_p pointer to Client struct |
731 |
|
* ERR_CANNOTSENDTOCHAN or ERR_NEEDREGGEDNICK if they cannot send to channel\n |
732 |
|
*/ |
733 |
|
int |
734 |
< |
can_send(struct Channel *chptr, struct Client *source_p, struct Membership *ms) |
734 |
> |
can_send(struct Channel *chptr, struct Client *source_p, |
735 |
> |
struct Membership *ms, const char *message) |
736 |
|
{ |
737 |
|
struct MaskItem *conf = NULL; |
738 |
|
|
744 |
|
if ((conf = match_find_resv(chptr->chname)) && !resv_find_exempt(source_p, conf)) |
745 |
|
return ERR_CANNOTSENDTOCHAN; |
746 |
|
|
747 |
< |
if (ms != NULL || (ms = find_channel_link(source_p, chptr))) |
748 |
< |
{ |
747 |
> |
if ((chptr->mode.mode & MODE_NOCTRL) && msg_has_ctrls(message)) |
748 |
> |
return ERR_NOCTRLSONCHAN; |
749 |
> |
if (ms || (ms = find_channel_link(source_p, chptr))) |
750 |
|
if (ms->flags & (CHFL_CHANOP|CHFL_HALFOP|CHFL_VOICE)) |
751 |
|
return CAN_SEND_OPV; |
752 |
+ |
if (chptr->mode.mode & MODE_MODERATED) |
753 |
+ |
return ERR_CANNOTSENDTOCHAN; |
754 |
+ |
if ((chptr->mode.mode & MODE_MODREG) && !HasUMode(source_p, UMODE_REGISTERED)) |
755 |
+ |
return ERR_NEEDREGGEDNICK; |
756 |
|
|
757 |
< |
/* cache can send if quiet_on_ban and banned */ |
758 |
< |
if (ConfigChannel.quiet_on_ban && MyClient(source_p)) |
757 |
> |
/* cache can send if banned */ |
758 |
> |
if (MyClient(source_p)) |
759 |
> |
{ |
760 |
> |
if (ms) |
761 |
|
{ |
762 |
|
if (ms->flags & CHFL_BAN_SILENCED) |
763 |
|
return ERR_CANNOTSENDTOCHAN; |
773 |
|
ms->flags |= CHFL_BAN_CHECKED; |
774 |
|
} |
775 |
|
} |
776 |
+ |
else if (is_banned(chptr, source_p)) |
777 |
+ |
return ERR_CANNOTSENDTOCHAN; |
778 |
|
} |
744 |
– |
else if (chptr->mode.mode & MODE_NOPRIVMSGS) |
745 |
– |
return ERR_CANNOTSENDTOCHAN; |
746 |
– |
|
747 |
– |
if (chptr->mode.mode & MODE_MODERATED) |
748 |
– |
return ERR_CANNOTSENDTOCHAN; |
779 |
|
|
780 |
|
return CAN_SEND_NONOP; |
781 |
|
} |