1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-07-05 02:53:13 +02:00

can_send() now returns 0 (false) or 1 (true), rather than magic values.

Also, the HOOKTYPE_CAN_SEND prototype changed so you can communicate
the error message in a flexible way, similar to what I just did
with extbans.
This commit is contained in:
Bram Matthys
2019-06-22 15:57:32 +02:00
parent f08557f2fd
commit bf4d96e991
6 changed files with 73 additions and 74 deletions
-7
View File
@@ -26,13 +26,6 @@
#define MODEBUFLEN 200
#define CANNOT_SEND_MODERATED 1
#define CANNOT_SEND_NOPRIVMSGS 2
#define CANNOT_SEND_BAN 4
#define CANNOT_SEND_MODREG 6
#define CANNOT_SEND_SWEAR 7 /* This isn't actually used here */
#define CANNOT_SEND_NONOTICE 8
#define NullChn ((aChannel *)0)
#define ChannelExists(n) (find_channel(n, NullChn) != NullChn)
+1 -1
View File
@@ -975,7 +975,7 @@ int hooktype_handshake(aClient *sptr);
int hooktype_away(aClient *sptr, char *reason);
int hooktype_invite(aClient *from, aClient *to, aChannel *chptr);
int hooktype_can_join(aClient *sptr, aChannel *chptr, char *key, char *parv[]);
int hooktype_can_send(aClient *sptr, aChannel *chptr, char *text, Membership *member, int notice);
int hooktype_can_send(aClient *sptr, aChannel *chptr, Membership *member, char **text, char **errmsg, int notice);
int hooktype_can_kick(aClient *sptr, aClient *victim, aChannel *chptr, char *comment, long sptr_flags, long victim_flags, char **error);
int hooktype_free_client(aClient *acptr);
int hooktype_free_user(anUser *user, aClient *acptr);
+59 -35
View File
@@ -149,12 +149,14 @@ static int list_length(Link *lp)
Member *find_member_link(Member *lp, aClient *ptr)
{
if (ptr)
{
while (lp)
{
if (lp->cptr == ptr)
return (lp);
lp = lp->next;
}
}
}
return NULL;
}
@@ -179,7 +181,7 @@ Member *make_member(void)
if (freemember == NULL)
{
for (i = 1; i <= (4072/sizeof(Member)); ++i)
for (i = 1; i <= (4072/sizeof(Member)); ++i)
{
lp = MyMallocEx(sizeof(Member));
lp->cptr = NULL;
@@ -239,7 +241,7 @@ Membership *make_membership(int local)
{
if (freemembershipL == NULL)
{
for (i = 1; i <= (4072/sizeof(MembershipL)); i++)
for (i = 1; i <= (4072/sizeof(MembershipL)); i++)
{
lp2 = MyMallocEx(sizeof(MembershipL));
lp2->next = (Membership *) freemembershipL;
@@ -343,7 +345,7 @@ int add_listmode_ex(Ban **list, aClient *cptr, aChannel *chptr, char *banid, cha
if (MyClient(cptr))
(void)collapse(banid);
len = strlen(banid);
if (!*list && ((len > MAXBANLENGTH) || (MAXBANS < 1)))
{
@@ -693,9 +695,10 @@ int is_chanowner(aClient *cptr, aChannel *chptr)
return 0;
}
int is_chanownprotop(aClient *cptr, aChannel *chptr) {
int is_chanownprotop(aClient *cptr, aChannel *chptr)
{
Membership *lp;
if (IsServer(cptr))
return 1;
if (chptr)
@@ -705,9 +708,10 @@ int is_chanownprotop(aClient *cptr, aChannel *chptr) {
return 0;
}
int is_skochanop(aClient *cptr, aChannel *chptr) {
int is_skochanop(aClient *cptr, aChannel *chptr)
{
Membership *lp;
if (IsServer(cptr))
return 1;
if (chptr)
@@ -732,26 +736,34 @@ int is_chanprot(aClient *cptr, aChannel *chptr)
return 0;
}
// FIXME: move to m_message and efunc !!
/** Can user send a message to this channel?
* @param cptr The client
* @param chptr The channel
* @param msgtext The message to send (MAY be changed, even if user is allowed to send)
* @param errmsg The error message (will be filled in)
* @param notice If it's a NOTICE then this is set to 1. Set to 0 for PRIVMSG.
* @returns Returns 1 if the user is allowed to send, otherwise 0.
* (note that this behavior was reversed in UnrealIRCd versions <5.x.
*/
int can_send(aClient *cptr, aChannel *chptr, char **msgtext, char **errmsg, int notice)
{
Membership *lp;
int member, i = 0;
Hook *h;
/*
* #0000053 by |savage|, speedup
*/
if (!MyClient(cptr))
{
return 0;
}
return 1;
*errmsg = NULL;
member = IsMember(cptr, chptr);
if (chptr->mode.mode & MODE_NOPRIVMSGS && !member)
{
/* Channel mode +n. Reject, unless HOOKTYPE_CAN_BYPASS_NO_EXTERNAL_MSGS
* tells otherwise.
/* Channel does not accept external messages (+n).
* Reject, unless HOOKTYPE_CAN_BYPASS_NO_EXTERNAL_MSGS tells otherwise.
*/
for (h = Hooks[HOOKTYPE_CAN_BYPASS_CHANNEL_MESSAGE_RESTRICTION]; h; h = h->next)
{
@@ -760,17 +772,20 @@ int can_send(aClient *cptr, aChannel *chptr, char **msgtext, char **errmsg, int
break;
}
if (i != HOOK_ALLOW)
return CANNOT_SEND_NOPRIVMSGS;
{
*errmsg = "No external channel messages";
return 0;
}
}
lp = find_membership_link(cptr->user->channel, chptr);
if (chptr->mode.mode & MODE_MODERATED && !op_can_override("channel:override:message:moderated",cptr,chptr,NULL) &&
(!lp
|| !(lp->flags & (CHFL_CHANOP | CHFL_VOICE | CHFL_CHANOWNER |
CHFL_HALFOP | CHFL_CHANPROT))))
{
/* Channel mode +m. Reject, unless HOOKTYPE_CAN_BYPASS_MODERATED
* tells otherwise.
if (chptr->mode.mode & MODE_MODERATED &&
!op_can_override("channel:override:message:moderated",cptr,chptr,NULL) &&
(!lp /* FIXME: UGLY */
|| !(lp->flags & (CHFL_CHANOP | CHFL_VOICE | CHFL_CHANOWNER | CHFL_HALFOP | CHFL_CHANPROT))))
{
/* Channel is moderated (+m).
* Reject, unless HOOKTYPE_CAN_BYPASS_MODERATED tells otherwise.
*/
for (h = Hooks[HOOKTYPE_CAN_BYPASS_CHANNEL_MESSAGE_RESTRICTION]; h; h = h->next)
{
@@ -779,21 +794,25 @@ int can_send(aClient *cptr, aChannel *chptr, char **msgtext, char **errmsg, int
break;
}
if (i != HOOK_ALLOW)
return CANNOT_SEND_MODERATED;
}
{
*errmsg = "You need voice (+v)";
return 0;
}
}
/* Modules can plug in as well */
for (h = Hooks[HOOKTYPE_CAN_SEND]; h; h = h->next)
{
i = (*(h->func.intfunc))(cptr,chptr,msgtext,lp,notice);
i = (*(h->func.intfunc))(cptr, chptr, lp, &msgtext, &errmsg, notice);
if (i != HOOK_CONTINUE)
break;
}
if (i != HOOK_CONTINUE)
return i;
return 0;
/* Makes opers able to talk thru bans -Stskeeps suggested by The_Cat */
/* Now we are going to check bans */
/* ..but first: exempt ircops */
if (op_can_override("channel:override:message:ban",cptr,chptr,NULL))
return 0;
@@ -801,9 +820,14 @@ int can_send(aClient *cptr, aChannel *chptr, char **msgtext, char **errmsg, int
|| !(lp->flags & (CHFL_CHANOP | CHFL_VOICE | CHFL_CHANOWNER |
CHFL_HALFOP | CHFL_CHANPROT))) && MyClient(cptr)
&& is_banned(cptr, chptr, BANCHK_MSG, msgtext, errmsg))
return (CANNOT_SEND_BAN);
{
/* Modules can set 'errmsg', otherwise we default to this: */
if (!*errmsg)
*errmsg = "You are banned";
return 0;
}
return 0;
return 1;
}
/** Returns 1 if channel has this channel mode set and 0 if not */
@@ -834,7 +858,7 @@ int has_channel_mode(aChannel *chptr, char mode)
/* Special handling for +k (needed??) */
if (chptr->mode.key[0] && (mode == 'k'))
return 1;
return 0; /* Not found */
}
+4 -3
View File
@@ -32,7 +32,7 @@ Cmode_t EXTCMODE_NONOTICE;
#define IsNoNotice(chptr) (chptr->mode.extmode & EXTCMODE_NONOTICE)
int nonotice_check_can_send(aClient *cptr, aChannel *chptr, char *msgtext, Membership *lp, int notice);
int nonotice_check_can_send(aClient *cptr, aChannel *chptr, Membership *lp, char **msg, char **errmsg, int notice);
MOD_TEST(nonotice)
{
@@ -65,7 +65,7 @@ MOD_UNLOAD(nonotice)
return MOD_SUCCESS;
}
int nonotice_check_can_send(aClient *cptr, aChannel *chptr, char *msgtext, Membership *lp, int notice)
int nonotice_check_can_send(aClient *cptr, aChannel *chptr, Membership *lp, char **msg, char **errmsg, int notice)
{
Hook *h;
int i;
@@ -81,7 +81,8 @@ int nonotice_check_can_send(aClient *cptr, aChannel *chptr, char *msgtext, Membe
}
if (i == HOOK_ALLOW)
return HOOK_CONTINUE; /* bypass restriction */
return CANNOT_SEND_NONOTICE; /* block notice */
*errmsg = "NOTICEs are not permitted in this channel";
return HOOK_DENY; /* block notice */
}
return HOOK_CONTINUE;
+5 -4
View File
@@ -34,8 +34,8 @@ static char errMsg[2048];
#define IsRegOnlySpeak(chptr) (chptr->mode.extmode & EXTCMODE_REGONLYSPEAK)
int regonlyspeak_can_send (aClient* cptr, aChannel *chptr, char* message, Membership* lp, int notice);
char * regonlyspeak_part_message (aClient* sptr, aChannel *chptr, char* comment);
int regonlyspeak_can_send(aClient *cptr, aChannel *chptr, Membership *lp, char **msg, char **errmsg, int notice);
char *regonlyspeak_part_message (aClient* sptr, aChannel *chptr, char* comment);
MOD_TEST(regonlyspeak)
{
@@ -81,7 +81,7 @@ char *regonlyspeak_part_message (aClient *sptr, aChannel *chptr, char *comment)
return comment;
}
int regonlyspeak_can_send (aClient *cptr, aChannel *chptr, char *message, Membership *lp, int notice)
int regonlyspeak_can_send(aClient *cptr, aChannel *chptr, Membership *lp, char **msg, char **errmsg, int notice)
{
Hook *h;
int i;
@@ -100,7 +100,8 @@ int regonlyspeak_can_send (aClient *cptr, aChannel *chptr, char *message, Member
if (i == HOOK_ALLOW)
return HOOK_CONTINUE; /* bypass +M restriction */
return CANNOT_SEND_MODREG; /* BLOCK message */
*errmsg = "You must have a registered nick (+r) to talk on this channel";
return HOOK_DENY; /* BLOCK message */
}
return HOOK_CONTINUE;
+4 -24
View File
@@ -178,25 +178,6 @@ int m_message(aClient *cptr, aClient *sptr, MessageTag *recv_mtags, int parc, ch
MessageTag *mtags;
int sendflags;
/*
* Reasons why someone can't send to a channel
* Note: a few have been moved to modules now, but don't just blindly delete them!! as we use the array index ;p
*/
static char *err_cantsend[] = {
"You need voice (+v)",
"No external channel messages",
"Color is not permitted in this channel <<NOLONGERUSED>>",
"You are banned",
"CTCPs are not permitted in this channel <<NOLONGERUSED>>",
"You must have a registered nick (+r) to talk on this channel",
"Swearing is not permitted in this channel",
"NOTICEs are not permitted in this channel",
NULL
};
if (IsHandshake(sptr))
return 0;
if (parc < 2 || *parv[1] == '\0')
{
sendnumeric(sptr, ERR_NORECIPIENT, cmd);
@@ -344,14 +325,13 @@ int m_message(aClient *cptr, aClient *sptr, MessageTag *recv_mtags, int parc, ch
errmsg = NULL;
if (MyClient(sptr) && !IsULine(sptr))
{
int cansend = can_send(sptr, chptr, &text, &errmsg, notice);
if (cansend != 0)
if (!can_send(sptr, chptr, &text, &errmsg, notice))
{
if (!notice || (cansend == 8))
if (!notice)
{
/* Send error message */
// TODO: move all the cansend shit to *errmsg ? if possible?
sendnumeric(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname, errmsg ? errmsg : err_cantsend[cansend - 1], p2);
// TODO: move all the cansend shit to *errmsg ? if possible?
sendnumeric(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname, errmsg, p2);
}
continue; /* skip */
}