X-Git-Url: http://git.pk910.de/?p=ircu2.10.12-pk.git;a=blobdiff_plain;f=ircd%2Fm_join.c;h=63c93d55d6bc2244f1a666bd685c3a0078be24f3;hp=0dc5ecf0d311d1a85a77856c7764f270c0d46ec0;hb=f6892ecd79c6113544106e32374075f489bf95a7;hpb=c3727b053aa20cecf3984cc0c9c23b0140edf52c diff --git a/ircd/m_join.c b/ircd/m_join.c index 0dc5ecf..63c93d5 100644 --- a/ircd/m_join.c +++ b/ircd/m_join.c @@ -157,7 +157,9 @@ int m_join(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) send_reply(sptr, ERR_TOOMANYCHANNELS, name); break; /* no point processing the other channels */ } - + + int flags = 0; + /* BADCHANed channel */ if ((gline = gline_find(name, GLINE_BADCHAN)) && GlineIsActive(gline) && !IsAnOper(sptr)) { @@ -192,7 +194,7 @@ int m_join(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) } else if (check_target_limit(sptr, chptr, chptr->chname, 0)) { continue; } else { - int flags = CHFL_DEOPPED; + flags = CHFL_DEOPPED; int err = 0; int override = 0; @@ -214,6 +216,8 @@ int m_join(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) err = ERR_CHANNELISFULL; else if ((chptr->mode.mode & MODE_REGONLY) && !IsAccount(sptr)) err = ERR_NEEDREGGEDNICK; + else if ((chptr->mode.mode & MODE_SSLCHAN) && !IsSSL(sptr)) + err = ERR_SSLCHANNEL; else if (find_ban(sptr, chptr->banlist)) err = ERR_BANNEDFROMCHAN; else if (*chptr->mode.key && (!key || strcmp(key, chptr->mode.key))) @@ -250,6 +254,7 @@ int m_join(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) case ERR_BANNEDFROMCHAN: err = 'b'; break; case ERR_BADCHANNELKEY: err = 'k'; break; case ERR_NEEDREGGEDNICK: err = 'r'; break; + case ERR_SSLCHANNEL: err = 'S'; break; default: err = '?'; break; } /* send accountability notice */ @@ -260,7 +265,7 @@ int m_join(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) override = 1; } - if(!err && !override && !IsInvited(sptr, chptr) && chptr->mode.access && chptr->mode.access > 0 && chptr->mode.access < 500 && feature_bool(FEAT_CHMODE_A_ENABLE)) { + if(!err && !override && !IsInvited(sptr, chptr) && chptr->mode.access && chptr->mode.access > 0 && chptr->mode.access <= 500 && feature_bool(FEAT_CHMODE_A_ENABLE)) { //We have to check the users channel access... struct Client *acptr; if(feature_str(FEAT_CHMODE_A_TARGET) && (acptr = FindUser(feature_str(FEAT_CHMODE_A_TARGET))) && IsNetServ(acptr) && IsService(cli_user(acptr)->server)) { @@ -278,35 +283,68 @@ int m_join(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) char *altchan = chptr->mode.altchan; if (!(chptrb = FindChannel(altchan))) { - if (((altchan[0] == '&') && !feature_bool(FEAT_LOCAL_CHANNELS)) || strlen(altchan) > IRCD_MIN(CHANNELLEN, feature_int(FEAT_CHANNELLEN))) { - //we don't send an error message here - that would be very strange for the user, because they normaly don't know that mode +F is set - } else if ((chptrb = get_channel(sptr, altchan, CGT_CREATE))) { - joinbuf_join(&create, chptrb, CHFL_CHANOP | CHFL_CHANNEL_MANAGER); - do_names(sptr, chptrb, NAMES_ALL|NAMES_EON); - } + if (((altchan[0] == '&') && !feature_bool(FEAT_LOCAL_CHANNELS)) || strlen(altchan) > IRCD_MIN(CHANNELLEN, feature_int(FEAT_CHANNELLEN))) { + //we don't send an error message here - that would be very strange for the user, because they normaly don't know that mode +F is set + } else if ((chptrb = get_channel(sptr, altchan, CGT_CREATE))) { + joinbuf_join(&create, chptrb, CHFL_CHANOP | CHFL_CHANNEL_MANAGER); + do_names(sptr, chptrb, NAMES_ALL|NAMES_EON); + } } else { - joinbuf_join(&join, chptrb, flags); - del_invite(sptr, chptrb); - if (chptrb->topic[0]) { - send_reply(sptr, RPL_TOPIC, chptrb->chname, chptrb->topic); - send_reply(sptr, RPL_TOPICWHOTIME, chptrb->chname, chptrb->topic_nick, chptrb->topic_time); - } - do_names(sptr, chptrb, NAMES_ALL|NAMES_EON); /* send /names list */ - } + if(find_member_link(chptrb, sptr)) + continue; //we have already joined this channel + //first of all check if we may even join this channel + int err2 = 0; + if (chptrb->users == 0 && !chptrb->mode.apass[0] && !(chptrb->mode.mode & MODE_PERSIST)) { + /* Joining a zombie channel (zannel): give ops and increment TS. */ + flags = CHFL_CHANOP; + chptrb->creationtime++; + } else if (IsInvited(sptr, chptrb)) { + /* Invites and key=OVERRIDE bypass these other checks. */ + } else if (chptrb->mode.mode & MODE_INVITEONLY) + err2 = ERR_INVITEONLYCHAN; + else if (chptrb->mode.limit && (chptrb->users >= chptrb->mode.limit)) + err2 = ERR_CHANNELISFULL; + else if ((chptrb->mode.mode & MODE_REGONLY) && !IsAccount(sptr)) + err2 = ERR_NEEDREGGEDNICK; + else if ((chptrb->mode.mode & MODE_SSLCHAN) && !IsSSL(sptr)) + err2 = ERR_SSLCHANNEL; + else if (find_ban(sptr, chptrb->banlist)) + err2 = ERR_BANNEDFROMCHAN; + else if (*chptrb->mode.key && (!key || strcmp(key, chptrb->mode.key))) + err2 = ERR_BADCHANNELKEY; + if(!err2) { + joinbuf_join(&join, chptrb, flags); + del_invite(sptr, chptrb); + if (chptrb->topic[0]) { + send_reply(sptr, RPL_TOPIC, chptrb->chname, chptrb->topic); + send_reply(sptr, RPL_TOPICWHOTIME, chptrb->chname, chptrb->topic_nick, chptrb->topic_time); + } + do_names(sptr, chptrb, NAMES_ALL|NAMES_EON|(((chptrb->mode.mode & MODE_AUDITORIUM) && !(flags & CHFL_CHANOP)) ? NAMES_OPS : 0)); /* send /names list */ + } + } } if (err) { - switch(err) { - case ERR_NEEDREGGEDNICK: - send_reply(sptr, - ERR_NEEDREGGEDNICK, - chptr->chname, - feature_str(FEAT_URLREG)); - break; - default: + const char *error = NULL; + if (err == ERR_CHANNELISFULL) + error = feature_str(FEAT_ERR_CHANNELISFULL); + else if (err == ERR_INVITEONLYCHAN) + error = feature_str(FEAT_ERR_INVITEONLYCHAN); + else if (err == ERR_BANNEDFROMCHAN) + error = feature_str(FEAT_ERR_BANNEDFROMCHAN); + else if (err == ERR_BADCHANNELKEY) + error = feature_str(FEAT_ERR_BADCHANNELKEY); + else if (err == ERR_NEEDREGGEDNICK) + error = feature_str(FEAT_ERR_NEEDREGGEDNICK); + else if (err == ERR_SSLCHANNEL) + error = feature_str(FEAT_ERR_SSLCHANNEL); + else if (err == ERR_JOINACCESS) + error = feature_str(FEAT_ERR_JOINACCESS); + + if (error) + send_reply(sptr, err, chptr->chname, error); + else send_reply(sptr, err, chptr->chname); - break; - } continue; } @@ -334,7 +372,7 @@ int m_join(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) chptr->topic_time); } - do_names(sptr, chptr, NAMES_ALL|NAMES_EON); /* send /names list */ + do_names(sptr, chptr, NAMES_ALL|NAMES_EON|(((chptr->mode.mode & MODE_AUDITORIUM) && !(flags & CHFL_CHANOP)) ? NAMES_OPS : 0)); /* send /names list */ } joinbuf_flush(&join); /* must be first, if there's a JOIN 0 */