X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=ircd%2Fm_join.c;h=e0049667ca8a1eb691f603312e453ad0bb8688b6;hb=53db8a34fb699436ab64a51fe5ac88e88e8c1bec;hp=cec63571b75a29dc5267787dff552f0917f36f5c;hpb=411df45b6a2410b07e62affaaa3e07a4e9d45e2d;p=ircu2.10.12-pk.git diff --git a/ircd/m_join.c b/ircd/m_join.c index cec6357..e004966 100644 --- a/ircd/m_join.c +++ b/ircd/m_join.c @@ -158,7 +158,7 @@ int m_join(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) if (!(chptr = FindChannel(name))) { if (((name[0] == '&') && !feature_bool(FEAT_LOCAL_CHANNELS)) - || strlen(name) >= IRCD_MIN(CHANNELLEN, feature_int(FEAT_CHANNELLEN))) { + || strlen(name) > IRCD_MIN(CHANNELLEN, feature_int(FEAT_CHANNELLEN))) { send_reply(sptr, ERR_NOSUCHCHANNEL, name); continue; } @@ -239,24 +239,30 @@ int m_join(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) /* Is there some reason the user may not join? */ if (err) { - send_reply(sptr, err, chptr->chname); + switch(err) { + case ERR_NEEDREGGEDNICK: + send_reply(sptr, + ERR_NEEDREGGEDNICK, + chptr->chname, + feature_str(FEAT_URLREG)); + break; + default: + send_reply(sptr, err, chptr->chname); + break; + } continue; } joinbuf_join(&join, chptr, flags); if (flags & CHFL_CHANOP) { struct ModeBuf mbuf; -#if 0 - /* Send a MODE to the other servers. If the user used the A/U pass, - * let his server op him, otherwise let him op himself. */ - modebuf_init(&mbuf, chptr->mode.apass[0] ? &me : sptr, cptr, chptr, MODEBUF_DEST_SERVER); -#else /* Always let the server op him: this is needed on a net with older servers because they 'destruct' channels immediately when they become empty without sending out a DESTRUCT message. As a result, they would always bounce a mode - (as HACK(2)) when the user ops himself. */ + (as HACK(2)) when the user ops himself. + (There is also no particularly good reason to have the user op himself.) + */ modebuf_init(&mbuf, &me, cptr, chptr, MODEBUF_DEST_SERVER); -#endif modebuf_mode_client(&mbuf, MODE_ADD | MODE_CHANOP, sptr, chptr->mode.apass[0] ? ((flags & CHFL_CHANNEL_MANAGER) ? 0 : 1) : MAXOPLEVEL); modebuf_flush(&mbuf); @@ -364,7 +370,7 @@ int ms_join(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) empty (also here) and when this channel doesn't have +A set. To prevent this from allowing net-rides on the channel, we - clear all ops from the channel. + clear all modes from the channel. (Scenario for a net ride: c1 - s1 - s2 - c2, with c1 the only user in the channel; c1 parts and rejoins, gaining ops. @@ -381,17 +387,42 @@ int ms_join(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) struct ModeBuf mbuf; chptr->creationtime = creation; - /* Deop the current ops. (This will go in both directions on - * the network, and revise the channel timestamp as it goes, - * avoiding further traffic due to the JOIN.) - */ - modebuf_init(&mbuf, sptr, cptr, chptr, MODEBUF_DEST_CHANNEL | MODEBUF_DEST_HACK3 | MODEBUF_DEST_SERVER); + /* Wipe out the current modes on the channel. */ + modebuf_init(&mbuf, sptr, cptr, chptr, MODEBUF_DEST_CHANNEL | MODEBUF_DEST_HACK3); + + modebuf_mode(&mbuf, MODE_DEL | chptr->mode.mode); + chptr->mode.mode &= MODE_BURSTADDED | MODE_WASDELJOINS; + + if (chptr->mode.limit) { + modebuf_mode_uint(&mbuf, MODE_DEL | MODE_LIMIT, chptr->mode.limit); + chptr->mode.limit = 0; + } + + if (chptr->mode.key[0]) { + modebuf_mode_string(&mbuf, MODE_DEL | MODE_KEY, chptr->mode.key, 0); + chptr->mode.key[0] = '\0'; + } + + if (chptr->mode.upass[0]) { + modebuf_mode_string(&mbuf, MODE_DEL | MODE_UPASS, chptr->mode.upass, 0); + chptr->mode.upass[0] = '\0'; + } + + if (chptr->mode.apass[0]) { + modebuf_mode_string(&mbuf, MODE_DEL | MODE_APASS, chptr->mode.apass, 0); + chptr->mode.apass[0] = '\0'; + } + for (member = chptr->members; member; member = member->next_member) { if (IsChanOp(member)) { modebuf_mode_client(&mbuf, MODE_DEL | MODE_CHANOP, member->user, OpLevel(member)); member->status &= ~CHFL_CHANOP; } + if (HasVoice(member)) { + modebuf_mode_client(&mbuf, MODE_DEL | MODE_VOICE, member->user, OpLevel(member)); + member->status &= ~CHFL_VOICE; + } } modebuf_flush(&mbuf); }