static void do_join_0(struct Client *client_p, struct Client *source_p) { struct Channel *chptr=NULL; dlink_node *lp; /* Finish the flood grace period... */ if(MyClient(source_p) && !IsFloodDone(source_p)) flood_endgrace(source_p); sendto_server(client_p, NULL, NOCAPS, NOCAPS, ":%s JOIN 0", source_p->name); if (source_p->user->channel.head && MyConnect(source_p) && !IsOper(source_p)) check_spambot_warning(source_p, NULL); while ((lp = source_p->user->channel.head)) { chptr = lp->data; sendto_channel_local(ALL_MEMBERS,chptr, ":%s!%s@%s PART %s", source_p->name, source_p->username, source_p->host, chptr->chname); remove_user_from_channel(chptr, source_p); } }
/* part_one_client() * * inputs - pointer to server * - pointer to source client to remove * - char pointer of name of channel to remove from * output - none * side effects - remove ONE client given the channel name */ static void part_one_client(struct Client *client_p, struct Client *source_p, const char *name, char *reason) { struct Channel *chptr = NULL; struct Membership *ms = NULL; if ((chptr = hash_find_channel(name)) == NULL) { sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), me.name, source_p->name, name); return; } if ((ms = find_channel_link(source_p, chptr)) == NULL) { sendto_one(source_p, form_str(ERR_NOTONCHANNEL), me.name, source_p->name, name); return; } if (MyConnect(source_p) && !IsOper(source_p)) check_spambot_warning(source_p, NULL); /* * Remove user from the old channel (if any) * only allow /part reasons in -m chans */ if(msg_has_colors(reason) && (chptr->mode.mode & MODE_NOCOLOR)) reason = strip_color(reason); if (reason[0] && (!MyConnect(source_p) || ((can_send(chptr, source_p, ms) && (source_p->firsttime + ConfigFileEntry.anti_spam_exit_message_time) < CurrentTime)))) { sendto_server(client_p, chptr, CAP_TS6, NOCAPS, ":%s PART %s :%s", ID(source_p), chptr->chname, reason); sendto_server(client_p, chptr, NOCAPS, CAP_TS6, ":%s PART %s :%s", source_p->name, chptr->chname, reason); sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s!%s@%s PART %s :%s", source_p->name, source_p->username, source_p->host, chptr->chname, reason); } else { sendto_server(client_p, chptr, CAP_TS6, NOCAPS, ":%s PART %s", ID(source_p), chptr->chname); sendto_server(client_p, chptr, NOCAPS, CAP_TS6, ":%s PART %s", source_p->name, chptr->chname); sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s!%s@%s PART %s", source_p->name, source_p->username, source_p->host, chptr->chname); } remove_user_from_channel(ms); }
static int m_cycle(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { char *p, *name; char *s = LOCAL_COPY(parv[1]); struct Channel *chptr; struct membership *msptr; name = rb_strtok_r(s, ",", &p); /* Finish the flood grace period... */ if(MyClient(source_p) && !IsFloodDone(source_p)) flood_endgrace(source_p); while(name) { if((chptr = find_channel(name)) == NULL) { sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, form_str(ERR_NOSUCHCHANNEL), name); return 0; } msptr = find_channel_membership(chptr, source_p); if(msptr == NULL) { sendto_one_numeric(source_p, ERR_NOTONCHANNEL, form_str(ERR_NOTONCHANNEL), name); return 0; } if(MyConnect(source_p) && !IsOper(source_p) && !IsExemptSpambot(source_p)) check_spambot_warning(source_p, NULL); if((is_any_op(msptr) || !MyConnect(source_p) || ((can_send(chptr, source_p, msptr) > 0 && (source_p->localClient->firsttime + ConfigFileEntry.anti_spam_exit_message_time) < rb_current_time())))) { sendto_server(client_p, chptr, CAP_TS6, NOCAPS, ":%s PART %s :Cycling", use_id(source_p), chptr->chname); sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s :Cycling", source_p->name, source_p->username, source_p->host, chptr->chname); } else { sendto_server(client_p, chptr, CAP_TS6, NOCAPS, ":%s PART %s", use_id(source_p), chptr->chname); sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s", source_p->name, source_p->username, source_p->host, chptr->chname); } remove_user_from_channel(msptr); chptr = NULL; msptr = NULL; name = rb_strtok_r(NULL, ",", &p); } user_join(client_p, source_p, parv[1], parc > 2 ? parv[2] : NULL); return 0; }
/* * part_one_client * * inputs - pointer to server * - pointer to source client to remove * - char pointer of name of channel to remove from * output - none * side effects - remove ONE client given the channel name */ static void part_one_client(struct Client *client_p, struct Client *source_p, char *name, char *reason) { struct Channel *chptr; struct membership *msptr; if((chptr = find_channel(name)) == NULL) { sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, form_str(ERR_NOSUCHCHANNEL), name); return; } msptr = find_channel_membership(chptr, source_p); if(msptr == NULL) { sendto_one_numeric(source_p, ERR_NOTONCHANNEL, form_str(ERR_NOTONCHANNEL), name); return; } if(MyConnect(source_p) && !IsOper(source_p) && !IsExemptSpambot(source_p)) check_spambot_warning(source_p, NULL); /* * Remove user from the old channel (if any) * only allow /part reasons in -m chans */ if(reason[0] && (is_chanop(msptr) || !MyConnect(source_p) || ((can_send(chptr, source_p, msptr) > 0 && (source_p->localClient->firsttime + ConfigFileEntry.anti_spam_exit_message_time) < CurrentTime)))) { sendto_server(client_p, chptr, CAP_TS6, NOCAPS, ":%s PART %s :%s", use_id(source_p), chptr->chname, reason); sendto_server(client_p, chptr, NOCAPS, CAP_TS6, ":%s PART %s :%s", source_p->name, chptr->chname, reason); sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s :%s", source_p->name, source_p->username, source_p->host, chptr->chname, reason); } else { sendto_server(client_p, chptr, CAP_TS6, NOCAPS, ":%s PART %s", use_id(source_p), chptr->chname); sendto_server(client_p, chptr, NOCAPS, CAP_TS6, ":%s PART %s", source_p->name, chptr->chname); sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s", source_p->name, source_p->username, source_p->host, chptr->chname); } remove_user_from_channel(msptr); }
/* * part_one_client * * inputs - pointer to server * - pointer to source client to remove * - char pointer of name of channel to remove from * output - none * side effects - remove ONE client given the channel name */ static void part_one_client(struct Client *client_p, struct Client *source_p, char *name, char *reason) { struct Channel *chptr; struct membership *msptr; char reason2[BUFSIZE]; if((chptr = find_channel(name)) == NULL) { sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, form_str(ERR_NOSUCHCHANNEL), name); return; } msptr = find_channel_membership(chptr, source_p); if(msptr == NULL) { sendto_one_numeric(source_p, ERR_NOTONCHANNEL, form_str(ERR_NOTONCHANNEL), name); return; } if(MyConnect(source_p) && !IsOper(source_p) && !IsExemptSpambot(source_p)) check_spambot_warning(source_p, NULL); /* * Remove user from the old channel (if any) * only allow /part reasons in -m chans */ if(reason[0] && (is_any_op(msptr) || !MyConnect(source_p) || ((can_send(chptr, source_p, msptr) > 0 && ConfigFileEntry.use_part_messages && (source_p->localClient->firsttime + ConfigFileEntry.anti_spam_exit_message_time) < rb_current_time())))) { if(chptr->mode.mode & MODE_NOCOLOR && (!ConfigChannel.exempt_cmode_c || !is_any_op(msptr))) { rb_strlcpy(reason2, reason, BUFSIZE); strip_colour(reason2); reason = reason2; } sendto_server(client_p, chptr, CAP_TS6, NOCAPS, ":%s PART %s :%s", use_id(source_p), chptr->chname, reason); sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s :\"%s\"", source_p->name, source_p->username, source_p->host, chptr->chname, reason); } else { sendto_server(client_p, chptr, CAP_TS6, NOCAPS, ":%s PART %s", use_id(source_p), chptr->chname); sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s", source_p->name, source_p->username, source_p->host, chptr->chname); } remove_user_from_channel(msptr); }
/* * m_join * parv[0] = sender prefix * parv[1] = channel * parv[2] = channel password (key) */ static void m_join(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { struct Channel *chptr = NULL; char *name, *key = NULL; int i, flags = 0; char *p = NULL, *p2 = NULL; int successful_join_count = 0; /* Number of channels successfully joined */ if (*parv[1] == '\0') { sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "JOIN"); return; } if (parc > 2) { key = strtoken(&p2, parv[2], ","); } for (name = strtoken(&p, parv[1], ","); name; key = (key) ? strtoken(&p2, NULL, ",") : NULL, name = strtoken(&p, NULL, ",")) { if(!check_channel_name(name)) { sendto_one(source_p, form_str(ERR_BADCHANNAME), me.name, source_p->name, (unsigned char*)name); continue; } /* ** JOIN 0 sends out a part for all channels a user ** has joined. ** ** this should be either disabled or selectable in ** config file .. it's abused a lot more than it's ** used these days :/ --is */ if (*name == '0' && !atoi(name)) { if (source_p->user->channel.head == NULL) continue; do_join_0(&me,source_p); continue; } /* check it begins with # or & */ else if(!IsChannelName(name)) { sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), me.name, source_p->name, name); continue; } if(ConfigServerHide.disable_local_channels && (*name == '&')) { sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), me.name, source_p->name, name); continue; } /* check the length */ if (strlen(name) > CHANNELLEN) { sendto_one(source_p, form_str(ERR_BADCHANNAME), me.name, source_p->name, name); continue; } /* see if its resv'd */ if(find_channel_resv(name) && (!IsOper(source_p) || !ConfigChannel.no_oper_resvs)) { sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE), me.name, source_p->name, name); sendto_realops_flags(UMODE_SPY, L_ALL, "User %s (%s@%s) is attempting to join locally juped channel %s", source_p->name, source_p->username, source_p->host, name); continue; } /* look for the channel */ if((chptr = hash_find_channel(name)) != NULL) { if(IsMember(source_p, chptr)) return; if(splitmode && !IsOper(source_p) && (*name != '&') && ConfigChannel.no_join_on_split) { sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE), me.name, source_p->name, name); continue; } if (chptr->users == 0) flags = CHFL_CHANOP; else flags = 0; } else { if(splitmode && !IsOper(source_p) && (*name != '&') && (ConfigChannel.no_create_on_split || ConfigChannel.no_join_on_split)) { sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE), me.name, source_p->name, name); continue; } flags = CHFL_CHANOP; } if ((source_p->user->joined >= ConfigChannel.max_chans_per_user) && (!IsOper(source_p) || (source_p->user->joined >= ConfigChannel.max_chans_per_user*3))) { sendto_one(source_p, form_str(ERR_TOOMANYCHANNELS), me.name, parv[0], name); if(successful_join_count) source_p->localClient->last_join_time = CurrentTime; return; } if(flags == 0) /* if channel doesn't exist, don't penalize */ successful_join_count++; if(chptr == NULL) /* If I already have a chptr, no point doing this */ { chptr = get_or_create_channel(source_p, name, NULL); } if(chptr == NULL) { sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE), me.name, parv[0], name); if(successful_join_count > 0) successful_join_count--; continue; } if (!IsOper(source_p)) check_spambot_warning(source_p, name); /* can_join checks for +i key, bans etc */ if ( (i = can_join(source_p, chptr, key)) ) { sendto_one(source_p, form_str(i), me.name, parv[0], name); if(successful_join_count > 0) successful_join_count--; continue; } /* add the user to the channel */ add_user_to_channel(chptr, source_p, flags); /* we send the user their join here, because we could have to * send a mode out next. */ sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN :%s", source_p->name, source_p->username, source_p->host, chptr->chname); /* if theyre joining opped (ie, new chan or joining one thats * persisting) then set timestamp to current, set +nt and * broadcast the sjoin with its old modes, or +nt. */ if (flags & CHFL_CHANOP) { char mbuf[MODEBUFLEN]; char pbuf[MODEBUFLEN]; chptr->channelts = CurrentTime; chptr->mode.mode |= MODE_TOPICLIMIT; chptr->mode.mode |= MODE_NOPRIVMSGS; sendto_channel_local(ONLY_CHANOPS, chptr, ":%s MODE %s +nt", me.name, chptr->chname); if(*chptr->chname == '#') { channel_modes(chptr, source_p, mbuf, pbuf); strlcat(mbuf, " ", sizeof(mbuf)); if(pbuf[0] != '\0') strlcat(mbuf, pbuf, sizeof(mbuf)); /* note: mbuf here will have a trailing space. we add one above, * and channel_modes() will leave a trailing space on pbuf if * its used --fl */ sendto_server(client_p, chptr, NOCAPS, NOCAPS, ":%s SJOIN %lu %s %s:@%s", me.name, (unsigned long) chptr->channelts, chptr->chname, mbuf, parv[0]); } /* drop our +beI modes */ free_channel_list(&chptr->banlist); free_channel_list(&chptr->exceptlist); free_channel_list(&chptr->invexlist); } else { sendto_server(client_p, chptr, NOCAPS, NOCAPS, ":%s SJOIN %lu %s + :%s", me.name, (unsigned long) chptr->channelts, chptr->chname, parv[0]); } del_invite(chptr, source_p); if (chptr->topic != NULL) { sendto_one(source_p, form_str(RPL_TOPIC), me.name, parv[0], chptr->chname, chptr->topic); sendto_one(source_p, form_str(RPL_TOPICWHOTIME), me.name, parv[0], chptr->chname, chptr->topic_info, chptr->topic_time); } channel_member_names(source_p, chptr, chptr->chname, 1); if(successful_join_count) source_p->localClient->last_join_time = CurrentTime; } }
/* * part_one_client * * inputs - pointer to server * - pointer to source client to remove * - char pointer of name of channel to remove from * output - none * side effects - remove ONE client given the channel name */ static void part_one_client(struct Client *client_p, struct Client *source_p, char *name, char *reason) { struct Channel *chptr; struct Channel *bchan; if ((chptr = hash_find_channel(name)) == NULL) { sendto_one(source_p, form_str(source_p,ERR_NOSUCHCHANNEL), me.name, source_p->name, name); return; } #ifdef VCHANS if (IsVchan(chptr) || HasVchans(chptr)) { if(HasVchans(chptr)) { /* Set chptr to actual channel, bchan to the base channel */ bchan = chptr; chptr = map_vchan(bchan,source_p); } else { /* chptr = chptr; */ bchan = find_bchan(chptr); } } else #endif bchan = chptr; /* not a vchan */ if (!chptr || !bchan || !IsMember(source_p, chptr)) { sendto_one(source_p, form_str(source_p,ERR_NOTONCHANNEL), me.name, source_p->name, name); return; } if (MyConnect(source_p) && !IsOper(source_p)) check_spambot_warning(source_p, NULL); /* * Remove user from the old channel (if any) * only allow /part reasons in -m chans */ if(reason[0] && (is_any_op(chptr, source_p) || !MyConnect(source_p) || ((can_send(chptr, source_p) > 0 && (source_p->firsttime + ConfigFileEntry.anti_spam_exit_message_time) < CurrentTime)))) { /*strip_color(reason);*/ reason = strip_color(reason, 1); if (match("*http://*", reason) || match("*www*", reason)) reason = "<spam removed>"; sendto_server(client_p, NULL, chptr, CAP_UID, NOCAPS, NOFLAGS, ":%s PART %s :%s", ID(source_p), chptr->chname, reason); sendto_server(client_p, NULL, chptr, NOCAPS, CAP_UID, NOFLAGS, ":%s PART %s :%s", source_p->name, chptr->chname, reason); if (PaceChannel(chptr) && (chptr->parts < MAX_PACEJOIN)) add_pace(chptr, source_p, bchan->chname, 0, 0); else sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s :%s", source_p->name, source_p->username, source_p->host, bchan->chname, reason); } else { sendto_server(client_p, NULL, chptr, CAP_UID, NOCAPS, NOFLAGS, ":%s PART %s", ID(source_p), chptr->chname); sendto_server(client_p, NULL, chptr, NOCAPS, CAP_UID, NOFLAGS, ":%s PART %s", source_p->name, chptr->chname); if (PaceChannel(chptr) && (chptr->parts < MAX_PACEJOIN)) add_pace(chptr, source_p, bchan->chname, 0, 0); else sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s", source_p->name, source_p->username, source_p->host, bchan->chname); } remove_user_from_channel(chptr, source_p); if (MyConnect(source_p)) source_p->localClient->last_leave_time = CurrentTime; }