* note: it is guaranteed that parv[0]..parv[parc-1] are all
* non-NULL pointers.
*/
-#if 0
-/*
- * No need to include handlers.h here the signatures must match
- * and we don't need to force a rebuild of all the handlers everytime
- * we add a new one to the list. --Bleep
- */
-#include "handlers.h"
-#endif /* 0 */
+#include "config.h"
+
#include "channel.h"
#include "client.h"
#include "gline.h"
#include <stdlib.h>
#include <string.h>
+/*
+ * Helper function to see if there are any control characters
+ * in a given string
+ */
+static char *
+HasControlChars(char *mstring)
+{
+ char *j;
+ for(j = mstring; *j ; j++) {
+ if(*j <= 32) { return j; }
+ }
+
+ return 0;
+}
+
/*
* Helper function to find last 0 in a comma-separated list of
* channel names.
struct Channel *chptr;
struct JoinBuf join;
struct JoinBuf create;
+ struct ModeBuf mbuf;
struct Gline *gline;
unsigned int flags = 0;
int i;
if (join0(&join, cptr, sptr, name)) /* did client do a JOIN 0? */
continue;
- if (!IsChannelName(name)) { /* bad channel name */
+ if (!IsChannelName(name) || HasControlChars(name)) { /* bad channel name */
send_reply(sptr, ERR_NOSUCHCHANNEL, name);
continue;
}
}
if (chptr) {
+ int is_level0_op = 0;
+ if (!BadPtr(keys) && *chptr->mode.apass) {
+ /* Don't use compall for the apass, only a single key is allowed.
+ Test Apass first in case someone set Apass and upass equal. */
+ if (strcmp(chptr->mode.apass, keys) == 0) {
+ is_level0_op = 1;
+ flags &= ~CHFL_DEOPPED;
+ flags |= CHFL_CHANOP | CHFL_CHANNEL_MANAGER;
+ }
+ else if (*chptr->mode.upass && strcmp(chptr->mode.upass, keys) == 0) {
+ is_level0_op = 1;
+ flags &= ~CHFL_DEOPPED;
+ flags |= CHFL_CHANOP;
+ }
+ }
if (check_target_limit(sptr, chptr, chptr->chname, 0))
continue; /* exceeded target limit */
- else if ((i = can_join(sptr, chptr, keys))) {
+ else if (!is_level0_op && (i = can_join(sptr, chptr, keys))) {
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 if ((i = can_join(sptr, chptr, keys))) { */
+ } /* else if ((i = can_join(sptr, chptr, keys))) */
joinbuf_join(&join, chptr, flags);
+ if (is_level0_op)
+ {
+ joinbuf_flush(&join);
+ modebuf_init(&mbuf, &me, cptr, chptr,
+ MODEBUF_DEST_CHANNEL | /* Send mode to channel */
+ MODEBUF_DEST_SERVER); /* And send it to the other servers */
+ modebuf_mode_client(&mbuf,
+ MODE_ADD | MODE_CHANOP, sptr); /* Give ops to the level0 op */
+ modebuf_flush(&mbuf);
+ }
} else if (!(chptr = get_channel(sptr, name, CGT_CREATE)))
continue; /* couldn't get channel */
else if (check_target_limit(sptr, chptr, chptr->chname, 1)) {
/* Note: check_target_limit will only ever return 0 here */
- sub1_from_channel(chptr); /* created it... */
+ chptr->members = 0;
+ destruct_channel(chptr); /* created it... */
continue;
} else
- joinbuf_join(&create, chptr, flags);
+ joinbuf_join(&create, chptr, flags | CHFL_CHANNEL_MANAGER);
del_invite(sptr, chptr);
}
else { /* We have a valid channel? */
if ((member = find_member_link(chptr, sptr))) {
+ /* It is impossible to get here --Run */
if (!IsZombie(member)) /* already on channel */
continue;
chptr = FindChannel(name);
} else
flags = CHFL_DEOPPED | ((cli_flags(sptr) & FLAGS_TS8) ? CHFL_SERVOPOK : 0);
+ /* Always copy the timestamp when it is older, that is the only way to
+ ensure network-wide synchronization of creation times. */
+ if (creation && creation < chptr->creationtime)
+ chptr->creationtime = creation;
}
joinbuf_join(&join, chptr, flags);