#include "stdinc.h"
#include "channel.h"
#include "client.h"
-#include "common.h"
#include "hash.h"
#include "match.h"
#include "ircd.h"
static bool check_channel_name_loc(struct Client *source_p, const char *name);
static void send_join_error(struct Client *source_p, int numeric, const char *name);
-static void set_final_mode(struct Mode *mode, struct Mode *oldmode);
+static char *set_final_mode(char *mbuf, char *parabuf, struct Mode *mode, struct Mode *oldmode);
static void remove_our_modes(struct Channel *chptr, struct Client *source_p);
static void remove_ban_list(struct Channel *chptr, struct Client *source_p,
rb_dlink_list * list, char c, int mems);
-static char modebuf[MODEBUFLEN];
-static char parabuf[MODEBUFLEN];
-static const char *para[MAXMODEPARAMS];
-static char *mbuf;
-static int pargs;
-
/* Check what we will forward to, without sending any notices to the user
* -- jilles
*/
{
if (next == NULL)
return NULL;
+
chptr = find_channel(next);
/* Can only forward to existing channels */
if (chptr == NULL)
return NULL;
- /* Already on there, show original error message */
+ /* Already on there... but don't send the original reason for
+ * being unable to join. It isn't their fault they're already
+ * on the channel, and it looks hostile otherwise.
+ * --Elizafox
+ */
if (IsMember(source_p, chptr))
+ {
+ *err = ERR_USERONCHANNEL; /* I'm borrowing this for now. --Elizafox */
return NULL;
+ }
/* Juped. Sending a warning notice would be unfair */
if (hash_find_resv(chptr->chname))
return NULL;
/* Don't forward to +Q channel */
if (chptr->mode.mode & MODE_DISFORWARD)
return NULL;
+
i = can_join(source_p, chptr, key, &next);
if (i == 0)
return chptr;
m_join(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
static char jbuf[BUFSIZE];
+ static char parabuf[MODEBUFLEN];
struct Channel *chptr = NULL, *chptr2 = NULL;
struct ConfItem *aconf;
char *name;
/* join 0 parts all channels */
if(*name == '0' && (name[1] == ',' || name[1] == '\0') && name == chanlist)
{
- (void) strcpy(jbuf, "0");
+ rb_strlcpy(jbuf, "0", sizeof(jbuf));
continue;
}
- /* check it begins with # or &, and local chans are disabled */
- else if(!IsChannelName(name) ||
- ( ConfigChannel.disable_local_channels && name[0] == '&'))
+ /* check it begins with a valid channel prefix per policy. */
+ else if (!IsChannelName(name))
{
sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
form_str(ERR_NOSUCHCHANNEL), name);
}
/* If check_forward returns NULL, they couldn't join and there wasn't a usable forward channel. */
- if(!(chptr2 = check_forward(source_p, chptr, key, &i)))
+ if((chptr2 = check_forward(source_p, chptr, key, &i)) == NULL)
{
/* might be wrong, but is there any other better location for such?
* see extensions/chm_operonly.c for other comments on this
static void
ms_join(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
+ static char modebuf[MODEBUFLEN];
+ static char parabuf[MODEBUFLEN];
struct Channel *chptr;
static struct Mode mode;
time_t oldts;
time_t newts;
- int isnew;
+ bool isnew;
bool keep_our_modes = true;
rb_dlink_node *ptr, *next_ptr;
+ char *mbuf;
/* special case for join 0 */
if((parv[1][0] == '0') && (parv[1][1] == '\0') && parc == 2)
/* Lost the TS, other side wins, so remove modes on this side */
if(!keep_our_modes)
{
- set_final_mode(&mode, &chptr->mode);
+ mbuf = set_final_mode(mbuf, parabuf, &mode, &chptr->mode);
chptr->mode = mode;
remove_our_modes(chptr, source_p);
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->invites.head)
static void
ms_sjoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
+ static char modebuf[MODEBUFLEN];
+ static char parabuf[MODEBUFLEN];
static char buf_uid[BUFSIZE];
static const char empty_modes[] = "0";
struct Channel *chptr;
bool keep_our_modes = true;
bool keep_new_modes = true;
int fl;
- int isnew;
+ bool isnew;
int mlen_uid;
int len_uid;
int len;
int i, joinc = 0, timeslice = 0;
static char empty[] = "";
rb_dlink_node *ptr, *next_ptr;
+ char *mbuf;
+ int pargs;
+ const char *para[MAXMODEPARAMS];
if(parc < 5)
return;
if(oldmode->limit > mode.limit)
mode.limit = oldmode->limit;
if(strcmp(mode.key, oldmode->key) < 0)
- strcpy(mode.key, oldmode->key);
+ rb_strlcpy(mode.key, oldmode->key, sizeof(mode.key));
if(oldmode->join_num > mode.join_num ||
(oldmode->join_num == mode.join_num &&
oldmode->join_time > mode.join_time))
mode.join_time = oldmode->join_time;
}
if(irccmp(mode.forward, oldmode->forward) < 0)
- strcpy(mode.forward, oldmode->forward);
+ rb_strlcpy(mode.forward, oldmode->forward, sizeof(mode.forward));
}
else
{
chptr->join_count = chptr->join_delta = 0;
}
- set_final_mode(&mode, oldmode);
+ mbuf = set_final_mode(mbuf, parabuf, &mode, oldmode);
chptr->mode = mode;
/* Lost the TS, other side wins, so remove modes on this side */
}
}
-static void
-set_final_mode(struct Mode *mode, struct Mode *oldmode)
+static char *
+set_final_mode(char *mbuf, char *parabuf, struct Mode *mode, struct Mode *oldmode)
{
int dir = MODE_QUERY;
char *pbuf = parabuf;
pbuf += len;
}
*mbuf = '\0';
+
+ return mbuf;
}
/*
char *lpara[MAXMODEPARAMS];
int count = 0;
int i;
+ char *mbuf = lmodebuf;
- mbuf = lmodebuf;
*mbuf++ = '-';
for(i = 0; i < MAXMODEPARAMS; i++)
char *pbuf;
int count = 0;
int cur_len, mlen, plen;
+ char *mbuf;
pbuf = lparabuf;