#include <stdlib.h>
#include <string.h>
-#if !defined(XXX_BOGUS_TEMP_HACK)
-#include "handlers.h" /* m_names */
-#endif
-
/*
* Helper function to find last 0 in a comma-separated list of
* channel names.
joinbuf_init(&part, sptr, cptr, JOINBUF_TYPE_PARTALL,
"Left all channels", 0);
- while ((member = sptr->user->channel))
+ while ((member = cli_user(sptr)->channel))
joinbuf_join(&part, member->channel,
IsZombie(member) ? CHFL_ZOMBIE : 0);
struct Channel *chptr;
struct JoinBuf join;
struct JoinBuf create;
-#ifdef BADCHAN
struct Gline *gline;
-#endif
unsigned int flags = 0;
int i;
char *p = 0;
keys = parv[2]; /* remember where keys are */
- parv[2] = 0; /* for call to m_names below */
-
for (name = ircd_strtok(&p, chanlist, ","); name;
name = ircd_strtok(&p, 0, ",")) {
clean_channelname(name);
continue;
}
-#ifdef BADCHAN
/* BADCHANed channel */
if ((gline = gline_find(name, GLINE_BADCHAN | GLINE_EXACT)) &&
GlineIsActive(gline) && !IsAnOper(sptr)) {
send_reply(sptr, ERR_BANNEDFROMCHAN, name);
continue;
}
-#endif
if ((chptr = FindChannel(name))) {
if (find_member_link(chptr, sptr))
} else
flags = IsModelessChannel(name) ? CHFL_DEOPPED : CHFL_CHANOP;
- if (sptr->user->joined >= MAXCHANNELSPERUSER
-#ifdef OPER_NO_CHAN_LIMIT
- /* Opers are allowed to join any number of channels */
- && !IsAnOper(sptr)
-#endif
- ) {
+ if (cli_user(sptr)->joined >= MAXCHANNELSPERUSER &&
+ !HasPriv(sptr, PRIV_CHAN_LIMIT)) {
send_reply(sptr, ERR_TOOMANYCHANNELS, chptr ? chptr->chname : name);
break; /* no point processing the other channels */
}
if (check_target_limit(sptr, chptr, chptr->chname, 0))
continue; /* exceeded target limit */
else if ((i = can_join(sptr, chptr, keys))) {
-#ifdef OPER_WALK_THROUGH_LMODES
if (i > MAGIC_OPER_OVERRIDE) { /* oper overrode mode */
switch (i - MAGIC_OPER_OVERRIDE) {
case ERR_CHANNELISFULL: /* figure out which mode */
send_reply(sptr, i, chptr->chname);
continue;
}
-#else
- send_reply(sptr, i, chptr->chname);
- continue;
-#endif
} /* else if ((i = can_join(sptr, chptr, keys))) { */
joinbuf_join(&join, chptr, flags);
chptr->topic_time);
}
- parv[1] = name;
- m_names(cptr, sptr, 2, parv); /* XXX find a better way */
+ do_names(sptr, chptr, NAMES_ALL|NAMES_EON); /* send /names list */
}
joinbuf_flush(&join); /* must be first, if there's a JOIN 0 */
struct Membership *member;
struct Channel *chptr;
struct JoinBuf join;
- struct JoinBuf create;
unsigned int flags = 0;
+ time_t creation = 0;
char *p = 0;
char *chanlist;
char *name;
if (IsServer(sptr)) {
- Debug((DEBUG_ERROR, "%s tried to JOIN a channel", sptr->name));
- return 0;
+ return protocol_violation(sptr,"%s tried to JOIN a channel, duh!", cli_name(sptr));
}
if (parc < 2 || *parv[1] == '\0')
return need_more_params(sptr, "JOIN");
+ if (parc > 2 && parv[2])
+ creation = atoi(parv[2]);
+
joinbuf_init(&join, sptr, cptr, JOINBUF_TYPE_JOIN, 0, 0);
- joinbuf_init(&create, sptr, cptr, JOINBUF_TYPE_CREATE, 0, TStime());
chanlist = last0(parv[1]); /* find last "JOIN 0" */
if (join0(&join, cptr, sptr, name)) /* did client do a JOIN 0? */
continue;
- if (IsLocalChannel(name) || !IsChannelName(name))
+ if (IsLocalChannel(name) || !IsChannelName(name)) {
+ protocol_violation(sptr,"%s tried to join %s",cli_name(cptr),name);
continue;
+ }
- if ((chptr = FindChannel(name))) {
+ if (!(chptr = FindChannel(name))) {
+ /* No channel exists, so create one */
+ if (!(chptr = get_channel(sptr, name, CGT_CREATE))) {
+ protocol_violation(sptr,"couldn't get channel %s for %s",
+ name,cli_name(sptr));
+ continue;
+ }
+ flags = CHFL_DEOPPED | ((cli_flags(sptr) & FLAGS_TS8) ? CHFL_SERVOPOK : 0);
+
+ /* when the network is 2.10.11+ then remove MAGIC_REMOTE_JOIN_TS */
+ chptr->creationtime = creation ? creation : MAGIC_REMOTE_JOIN_TS;
+ }
+ else { /* We have a valid channel? */
if ((member = find_member_link(chptr, sptr))) {
if (!IsZombie(member)) /* already on channel */
continue;
remove_user_from_channel(sptr, chptr);
chptr = FindChannel(name);
} else
- flags = CHFL_DEOPPED | ((sptr->flags & FLAGS_TS8) ? CHFL_SERVOPOK : 0);
- } else
- flags = IsModelessChannel(name) ? CHFL_DEOPPED : CHFL_CHANOP;
+ flags = CHFL_DEOPPED | ((cli_flags(sptr) & FLAGS_TS8) ? CHFL_SERVOPOK : 0);
+ }
- if (chptr)
- joinbuf_join(&join, chptr, flags);
- /* Strange that a channel should get created by a JOIN, but as long
- * as there are desynchs, we have to assume it's possible. Previous
- * solutions involved sending a TS with the JOIN, but that seems
- * unworkable to me; my solution is to transmute the JOIN into a
- * CREATE, and let the next BURST try to fix the problem. Another
- * solution would be to simply issue an upstream KICK, but that
- * won't currently be accepted. Is this what DESTRUCT is for?
- */
- else if (!(chptr = get_channel(sptr, name, CGT_CREATE)))
- continue; /* couldn't get channel */
- else {
- chptr->creationtime = TStime(); /* have to set the creation TS */
- joinbuf_join(&create, chptr, flags);
- }
+ joinbuf_join(&join, chptr, flags);
}
- joinbuf_flush(&join); /* must be first, if there's a JOIN 0 */
- joinbuf_flush(&create);
+ joinbuf_flush(&join); /* flush joins... */
return 0;
}