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:
@@ -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
@@ -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
@@ -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 */
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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 */
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user