📄 m_join.c
字号:
sendto_channel_butserv(chptr, sptr, ":%s JOIN :%s", sptr->name, chptr->chname); sendto_serv_butone_token_opt(cptr, OPT_NOT_SJ3, sptr->name, MSG_JOIN, TOK_JOIN, "%s", chptr->chname);#ifdef JOIN_INSTEAD_OF_SJOIN_ON_REMOTEJOIN if ((MyClient(sptr) && !(flags & CHFL_CHANOP)) || !MyClient(sptr)) sendto_serv_butone_token_opt(cptr, OPT_SJ3, sptr->name, MSG_JOIN, TOK_JOIN, "%s", chptr->chname); if (flags & CHFL_CHANOP) {#endif /* I _know_ that the "@%s " look a bit wierd with the space and all .. but its to get around a SJOIN bug --stskeeps */ sendto_serv_butone_token_opt(cptr, OPT_SJ3|OPT_SJB64, me.name, MSG_SJOIN, TOK_SJOIN, "%B %s :%s%s ", (long)chptr->creationtime, chptr->chname, flags & CHFL_CHANOP ? "@" : "", sptr->name); sendto_serv_butone_token_opt(cptr, OPT_SJ3|OPT_NOT_SJB64, me.name, MSG_SJOIN, TOK_SJOIN, "%li %s :%s%s ", chptr->creationtime, chptr->chname, flags & CHFL_CHANOP ? "@" : "", sptr->name);#ifdef JOIN_INSTEAD_OF_SJOIN_ON_REMOTEJOIN }#endif if (MyClient(sptr)) { /* ** Make a (temporal) creationtime, if someone joins ** during a net.reconnect : between remote join and ** the mode with TS. --Run */ if (chptr->creationtime == 0) { chptr->creationtime = TStime(); sendto_serv_butone_token(cptr, me.name, MSG_MODE, TOK_MODE, "%s + %lu", chptr->chname, chptr->creationtime); } del_invite(sptr, chptr); if (flags & CHFL_CHANOP) sendto_serv_butone_token_opt(cptr, OPT_NOT_SJ3, me.name, MSG_MODE, TOK_MODE, "%s +o %s %lu", chptr->chname, sptr->name, chptr->creationtime); if (chptr->topic) { sendto_one(sptr, rpl_str(RPL_TOPIC), me.name, sptr->name, chptr->chname, chptr->topic); sendto_one(sptr, rpl_str(RPL_TOPICWHOTIME), me.name, sptr->name, chptr->chname, chptr->topic_nick, chptr->topic_time); } if (chptr->users == 1 && (MODES_ON_JOIN#ifdef EXTCMODE || iConf.modes_on_join.extmodes)#endif ) {#ifdef EXTCMODE int i; chptr->mode.extmode = iConf.modes_on_join.extmodes; /* Param fun */ for (i = 0; i <= Channelmode_highest; i++) { if (!Channelmode_Table[i].flag || !Channelmode_Table[i].paracount) continue; if (chptr->mode.extmode & Channelmode_Table[i].mode) { CmodeParam *p; p = Channelmode_Table[i].put_param(NULL, iConf.modes_on_join.extparams[i]); AddListItem(p, chptr->mode.extmodeparam); } }#endif chptr->mode.mode = MODES_ON_JOIN;#ifdef NEWCHFLOODPROT if (iConf.modes_on_join.floodprot.per) { chptr->mode.floodprot = MyMalloc(sizeof(ChanFloodProt)); memcpy(chptr->mode.floodprot, &iConf.modes_on_join.floodprot, sizeof(ChanFloodProt)); }#else chptr->mode.kmode = iConf.modes_on_join.kmode; chptr->mode.per = iConf.modes_on_join.per; chptr->mode.msgs = iConf.modes_on_join.msgs;#endif *modebuf = *parabuf = 0; channel_modes(sptr, modebuf, parabuf, chptr); /* This should probably be in the SJOIN stuff */ sendto_serv_butone_token(&me, me.name, MSG_MODE, TOK_MODE, "%s %s %s %lu", chptr->chname, modebuf, parabuf, chptr->creationtime); sendto_one(sptr, ":%s MODE %s %s %s", me.name, chptr->chname, modebuf, parabuf); } parv[0] = sptr->name; parv[1] = chptr->chname; do_cmd(cptr, sptr, "NAMES", 2, parv); RunHook4(HOOKTYPE_LOCAL_JOIN, cptr, sptr,chptr,parv); } else { RunHook4(HOOKTYPE_REMOTE_JOIN, cptr, sptr, chptr, parv); /* (rarely used) */ }#ifdef NEWCHFLOODPROT /* I'll explain this only once: * 1. if channel is +f * 2. local client OR synced server * 3. then, increase floodcounter * 4. if we reached the limit AND only if source was a local client.. do the action (+i). * Nr 4 is done because otherwise you would have a noticeflood with 'joinflood detected' * from all servers. */ if (chptr->mode.floodprot && (MyClient(sptr) || sptr->srvptr->serv->flags.synced) && !IsULine(sptr) && do_chanflood(chptr->mode.floodprot, FLD_JOIN) && MyClient(sptr)) { do_chanflood_action(chptr, FLD_JOIN, "join"); }#endif}/** User request to join a channel. * This routine can be called from both m_join or via do_join->can_join->do_join * if the channel is 'linked' (chmode +L). We use a counter 'bouncedtimes' which * is set to 0 in m_join, increased every time we enter this loop and decreased * anytime we leave the loop. So be carefull ;p. */DLLFUNC CMD_FUNC(_do_join){ char jbuf[BUFSIZE]; Membership *lp; aChannel *chptr; char *name, *key = NULL, *link = NULL; int i, flags = 0; char *p = NULL, *p2 = NULL;#define RET(x) { bouncedtimes--; return x; } if (parc < 2 || *parv[1] == '\0') { sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "JOIN"); return 0; } bouncedtimes++; /* don't use 'return x;' but 'RET(x)' from here ;p */ if (bouncedtimes > MAXBOUNCE) { /* bounced too many times */ sendto_one(sptr, ":%s %s %s :*** Couldn't join %s ! - Link setting was too bouncy", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", sptr->name, parv[1]); RET(0) } *jbuf = '\0'; /* ** Rebuild list of channels joined to be the actual result of the ** JOIN. Note that "JOIN 0" is the destructive problem. */ for (i = 0, name = strtoken(&p, parv[1], ","); name; name = strtoken(&p, NULL, ",")) { /* pathological case only on longest channel name. ** If not dealt with here, causes desynced channel ops ** since ChannelExists() doesn't see the same channel ** as one being joined. cute bug. Oct 11 1997, Dianora/comstud ** Copied from Dianora's "hybrid 5" ircd. */ if (strlen(name) > CHANNELLEN) /* same thing is done in get_channel() */ name[CHANNELLEN] = '\0'; if (MyConnect(sptr)) clean_channelname(name); if (check_channelmask(sptr, cptr, name) == -1) continue; if (*name == '0' && !atoi(name)) { (void)strcpy(jbuf, "0"); i = 1; continue; } else if (!IsChannelName(name)) { if (MyClient(sptr)) sendto_one(sptr, err_str(ERR_NOSUCHCHANNEL), me.name, parv[0], name); continue; } if (*jbuf) (void)strlcat(jbuf, ",", sizeof jbuf); (void)strlncat(jbuf, name, sizeof jbuf, sizeof(jbuf) - i - 1); i += strlen(name) + 1; } /* This strcpy should be safe since jbuf contains the "filtered" * result of parv[1] which should never be larger than the source. */ (void)strcpy(parv[1], jbuf); p = NULL; if (parv[2]) key = strtoken(&p2, parv[2], ","); parv[2] = NULL; /* for m_names call later, parv[parc] must == NULL */ for (name = strtoken(&p, jbuf, ","); name; key = (key) ? strtoken(&p2, NULL, ",") : NULL, name = strtoken(&p, NULL, ",")) { /* ** JOIN 0 sends out a part for all channels a user ** has joined. */ if (*name == '0' && !atoi(name)) { while ((lp = sptr->user->channel)) { chptr = lp->chptr; sendto_channel_butserv(chptr, sptr, PARTFMT2, parv[0], chptr->chname, "Left all channels"); if (MyConnect(sptr)) RunHook4(HOOKTYPE_LOCAL_PART, cptr, sptr, chptr, "Left all channels"); remove_user_from_channel(sptr, chptr); } sendto_serv_butone_token(cptr, parv[0], MSG_JOIN, TOK_JOIN, "0"); continue; } if (MyConnect(sptr)) { /* ** local client is first to enter previously nonexistant ** channel so make them (rightfully) the Channel ** Operator. */ /* Where did this come from? Potvin ? --Stskeeps flags = (ChannelExists(name)) ? CHFL_DEOPPED : CHFL_CHANOWNER; */ flags = (ChannelExists(name)) ? CHFL_DEOPPED : CHFL_CHANOP; if (!IsAnOper(sptr)) /* opers can join unlimited chans */ if (sptr->user->joined >= MAXCHANNELSPERUSER) { sendto_one(sptr, err_str (ERR_TOOMANYCHANNELS), me.name, parv[0], name); RET(0) }/* RESTRICTCHAN */ if (conf_deny_channel) { if (!IsOper(sptr) && !IsULine(sptr)) { ConfigItem_deny_channel *d; if ((d = Find_channel_allowed(name))) { if (d->warn) { sendto_snomask(SNO_EYES, "*** %s tried to join forbidden channel %s", get_client_name(sptr, 1), name); } if (d->reason) sendto_one(sptr, ":%s %s %s :*** Can not join %s: %s", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", sptr->name, name, d->reason); if (d->redirect) { sendto_one(sptr, ":%s %s %s :*** Redirecting you to %s", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", sptr->name, d->redirect); parv[0] = sptr->name; parv[1] = d->redirect; do_join(cptr, sptr, 2, parv); } continue; } } } /* ugly set::spamfilter::virus-help-channel-deny hack.. */ if (SPAMFILTER_VIRUSCHANDENY && SPAMFILTER_VIRUSCHAN && !strcasecmp(name, SPAMFILTER_VIRUSCHAN) && !IsAnOper(sptr) && !spamf_ugly_vchanoverride) { int invited = 0; Link *lp; aChannel *chptr = find_channel(name, NULL); if (chptr) { for (lp = sptr->user->invited; lp; lp = lp->next) if (lp->value.chptr == chptr) invited = 1; } if (!invited) { sendnotice(sptr, "*** Cannot join '%s' because it's the virus-help-channel which is " "reserved for infected users only", name); continue; } } } chptr = get_channel(sptr, name, CREATE); if (chptr && (lp = find_membership_link(sptr->user->channel, chptr))) continue; if (!chptr) continue; i = HOOK_CONTINUE; if (!MyConnect(sptr)) flags = CHFL_DEOPPED; else { Hook *h; for (h = Hooks[HOOKTYPE_PRE_LOCAL_JOIN]; h; h = h->next) { i = (*(h->func.intfunc))(sptr,chptr,parv); if (i == HOOK_DENY || i == HOOK_ALLOW) break; } /* Denied, get out now! */ if (i == HOOK_DENY) { /* Rejected... if we just created a new chan we should destroy it too. -- Syzop */ if (!chptr->users) sub1_from_channel(chptr); continue; } /* If they are allowed, don't check can_join */ if (i != HOOK_ALLOW && (i = can_join(cptr, sptr, chptr, key, link, parv))) { if (i != -1) sendto_one(sptr, err_str(i), me.name, parv[0], name); continue; }#ifdef JOINTHROTTLE cmodej_increase_usercounter(cptr, chptr);#endif } join_channel(chptr, cptr, sptr, flags); } RET(0)#undef RET}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -