/* * 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); }
static void h_can_send(void *vdata) { char *text, *filtered; hook_data_channel_approval *data = (hook_data_channel_approval *) vdata; if(data->chptr->mode.mode & mymode && ((strchr(ConfigChannel.exemptchanops, 'c') == NULL) || !is_any_op(data->msptr))) { /* colour == 3 */ text = ((char **)data->data)[3]; /* Filtered == 0 */ filtered = ((char **)data->data)[0]; if (EmptyString(text)) { if(data->cmd == COMMAND_PRIVMSG) sendto_one(data->client, form_str(ERR_NOTEXTTOSEND), me.name, data->client->name); data->approved = CAN_SEND_NO_NONOTIFY; return; } /* Copy coloured into filtered */ rb_strlcpy(filtered, text, BUFSIZE); } return; }
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; }
static void h_can_send(void *vdata) { hook_data_channel_approval *data = (hook_data_channel_approval *) vdata; if (!(data->cmd == COMMAND_NOTICE)) return; if(data->chptr->mode.mode & mymode && ((strchr(ConfigChannel.exemptchanops, 'T') == NULL) || !is_any_op(data->msptr))) { sendto_one_numeric(data->client, 404, "%s :Cannot send to channel - Notices are disallowed (+T set)", data->chptr->chname); data->approved = CAN_SEND_NO_NONOTIFY; } return; }
static void h_can_send(void *vdata) { char *text; size_t contor; int caps = 0; int len = 0; hook_data_channel_approval *data = (hook_data_channel_approval *) vdata; if ((data->chptr->mode.mode & mymode) && ((strchr(ConfigChannel.exemptchanops, 'G') == NULL) || !is_any_op(data->msptr))) { /* 2 == unprintable */ text = ((char **)data->data)[2]; if(strlen(text) < 10) return; for(contor = 0; contor < strlen(text); contor++) { if(IsUpper(text[contor]) && !isdigit(text[contor])) caps++; len++; } /* Added divide by 0 check --alxbl */ if(len > 0 && ((caps * 100) / len) >= conf_threshold) { if(data->cmd == COMMAND_PRIVMSG) sendto_one_numeric(data->client, 404, "%s :Cannot send to channel - Your message contains more than %d%% capital letters (+G set)", data->chptr->chname, conf_threshold); data->approved = CAN_SEND_NO_NONOTIFY; return; } } return; }
static void h_can_send(void *vdata) { char text[BUFSIZE]; hook_data_channel_approval *data = (hook_data_channel_approval *) vdata; if(data->chptr->mode.mode & mymode && (!ConfigChannel.exempt_cmode_c || !is_any_op(data->msptr))) { strip_colour((char *)data->data, text, BUFSIZE); if (EmptyString(text)) { if(data->cmd == COMMAND_PRIVMSG) sendto_one(data->client, form_str(ERR_NOTEXTTOSEND), me.name, data->client->name); data->approved = CAN_SEND_NO_NONOTIFY; return; } /* Copy it */ rb_strlcpy(data->data, text, BUFSIZE); } return; }
/* * mo_omode - MODE command handler * parv[1] - channel */ static int mo_omode(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct Channel *chptr = NULL; struct membership *msptr; char params[512]; int i; int wasonchannel; /* admins only */ if (!IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "admin"); return 0; } /* Now, try to find the channel in question */ if (!IsChanPrefix(parv[1][0]) || !check_channel_name(parv[1])) { sendto_one_numeric(source_p, ERR_BADCHANNAME, form_str(ERR_BADCHANNAME), parv[1]); return 0; } chptr = find_channel(parv[1]); if (chptr == NULL) { sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, form_str(ERR_NOSUCHCHANNEL), parv[1]); return 0; } /* Now know the channel exists */ msptr = find_channel_membership(chptr, source_p); wasonchannel = msptr != NULL; if (is_any_op(msptr)) { sendto_one_notice(source_p, ":Use a normal MODE you idiot"); return 0; } params[0] = '\0'; for (i = 2; i < parc; i++) { if (i != 2) rb_strlcat(params, " ", sizeof params); rb_strlcat(params, parv[i], sizeof params); } sendto_wallops_flags(UMODE_WALLOP, &me, "OMODE called for [%s] [%s] by %s!%s@%s", parv[1], params, source_p->name, source_p->username, source_p->host); ilog(L_MAIN, "OMODE called for [%s] [%s] by %s", parv[1], params, get_oper_name(source_p)); if (*chptr->chname != '&') sendto_server(NULL, NULL, NOCAPS, NOCAPS, ":%s WALLOPS :OMODE called for [%s] [%s] by %s!%s@%s", me.name, parv[1], params, source_p->name, source_p->username, source_p->host); #if 0 set_channel_mode(client_p, source_p->servptr, chptr, msptr, parc - 2, parv + 2); #else if (parc == 4 && !strcmp(parv[2], "+y") && !irccmp(parv[3], source_p->name)) { /* Ownering themselves */ if (!wasonchannel) { sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL, form_str(ERR_USERNOTINCHANNEL), parv[3], chptr->chname); return 0; } sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +y %s", me.name, parv[1], source_p->name); sendto_server(NULL, chptr, CAP_TS6, NOCAPS, ":%s TMODE %ld %s +y %s", me.id, (long) chptr->channelts, parv[1], source_p->id); msptr->flags |= CHFL_OWNER; } else if (parc == 4 && !strcmp(parv[2], "+a") && !irccmp(parv[3], source_p->name)) { /* Admining themselves */ if (!wasonchannel) { sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL, form_str(ERR_USERNOTINCHANNEL), parv[3], chptr->chname); return 0; } sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +a %s", me.name, parv[1], source_p->name); sendto_server(NULL, chptr, CAP_TS6, NOCAPS, ":%s TMODE %ld %s +a %s", me.id, (long) chptr->channelts, parv[1], source_p->id); msptr->flags |= CHFL_ADMIN; } else if (parc == 4 && !strcmp(parv[2], "+o") && !irccmp(parv[3], source_p->name)) { /* Opping themselves */ if (!wasonchannel) { sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL, form_str(ERR_USERNOTINCHANNEL), parv[3], chptr->chname); return 0; } sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +o %s", me.name, parv[1], source_p->name); sendto_server(NULL, chptr, CAP_TS6, NOCAPS, ":%s TMODE %ld %s +o %s", me.id, (long) chptr->channelts, parv[1], source_p->id); msptr->flags |= CHFL_CHANOP; } else if (parc == 4 && !strcmp(parv[2], "+h") && !irccmp(parv[3], source_p->name)) { /* Halfopping themselves */ if (!wasonchannel) { sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL, form_str(ERR_USERNOTINCHANNEL), parv[3], chptr->chname); return 0; } sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +h %s", me.name, parv[1], source_p->name); sendto_server(NULL, chptr, CAP_TS6, NOCAPS, ":%s TMODE %ld %s +h %s", me.id, (long) chptr->channelts, parv[1], source_p->id); msptr->flags |= CHFL_HALFOP; } else if (ConfigChannel.use_owner) { /* I hope this is correct. * -- Kabaka */ /* Hack it so set_channel_mode() will accept */ if (wasonchannel) msptr->flags |= CHFL_OWNER; else { add_user_to_channel(chptr, source_p, CHFL_CHANOP); msptr = find_channel_membership(chptr, source_p); } set_channel_mode(client_p, source_p, chptr, msptr, parc - 2, parv + 2); if (wasonchannel) msptr->flags &= ~CHFL_OWNER; else remove_user_from_channel(msptr); } else if (ConfigChannel.use_admin) { /* Hack it so set_channel_mode() will accept */ if (wasonchannel) msptr->flags |= CHFL_ADMIN; else { add_user_to_channel(chptr, source_p, CHFL_CHANOP); msptr = find_channel_membership(chptr, source_p); } set_channel_mode(client_p, source_p, chptr, msptr, parc - 2, parv + 2); /* We know they were not opped before and they can't have opped * themselves as set_channel_mode() does not allow that * -- jilles */ if (wasonchannel) msptr->flags &= ~CHFL_ADMIN; else remove_user_from_channel(msptr); } else { /* CHFL_ADMIN is only useful if admin is enabled * so hack it with op if it is not. */ if (wasonchannel) msptr->flags |= CHFL_CHANOP; else { add_user_to_channel(chptr, source_p, CHFL_CHANOP); msptr = find_channel_membership(chptr, source_p); } set_channel_mode(client_p, source_p, chptr, msptr, parc - 2, parv + 2); /* We know they were not opped before and they can't have opped * themselves as set_channel_mode() does not allow that * -- jilles */ if (wasonchannel) msptr->flags &= ~CHFL_CHANOP; else remove_user_from_channel(msptr); } #endif return 0; }
static int build_target_list(int p_or_n, char *command, struct Client *client_p, struct Client *source_p, char *nicks_channels, char *text) { int type; char *p, *nick, *target_list, ncbuf[BUFSIZE]; struct Channel *chptr=NULL; struct Client *target_p; /* Sigh, we can't mutilate parv[1] incase we need it to send to a hub */ if (!ServerInfo.hub && (uplink != NULL) && IsCapable(uplink, CAP_LL)) { strncpy(ncbuf, nicks_channels, BUFSIZE); target_list = ncbuf; } else target_list = nicks_channels; /* skip strcpy for non-lazyleafs */ ntargets = 0; for (nick = strtoken(&p, target_list, ","); nick; nick = strtoken(&p, (char *)NULL, ",")) { char *with_prefix; /* * channels are privmsg'd a lot more than other clients, moved up * here plain old channel msg? */ if (IsChanPrefix(*nick)) { /* ignore send of local channel to a server (should not happen) */ if (IsServer(client_p) && *nick == '&') continue; if ((chptr = hash_find_channel(nick)) != NULL) { if (!duplicate_ptr(chptr)) { if (ntargets >= ConfigFileEntry.max_targets) { sendto_one(source_p, form_str(source_p,ERR_TOOMANYTARGETS), me.name, source_p->name, nick); return (1); } targets[ntargets].ptr = (void *)chptr; targets[ntargets++].type = ENTITY_CHANNEL; } } else { if (!ServerInfo.hub && (uplink != NULL) && IsCapable(uplink, CAP_LL)) return -1; else if (p_or_n != NOTICE) sendto_one(source_p, form_str(source_p,ERR_NOSUCHNICK), me.name, source_p->name, nick); } continue; } /* look for a privmsg to another client */ if ((target_p = find_person(nick)) != NULL) { if (!duplicate_ptr(target_p)) { if (ntargets >= ConfigFileEntry.max_targets) { sendto_one(source_p, form_str(source_p,ERR_TOOMANYTARGETS), me.name, source_p->name, nick); return (1); } targets[ntargets].ptr = (void *)target_p; targets[ntargets].type = ENTITY_CLIENT; targets[ntargets++].flags = 0; } continue; } /* @#channel or +#channel message ? */ type = 0; with_prefix = nick; /* allow %+@ if someone wants to do that */ for (;;) { if (*nick == '@') type |= MODE_CHANOP; else if (*nick == '%') type |= MODE_CHANOP | MODE_HALFOP; else if (*nick == '+') type |= MODE_CHANOP | MODE_HALFOP | MODE_VOICE; else break; nick++; } if (type != 0) { /* suggested by Mortiis */ if (*nick == '\0') /* if its a '\0' dump it, there is no recipient */ { sendto_one(source_p, form_str(source_p,ERR_NORECIPIENT), me.name, source_p->name, command); continue; } /* At this point, nick+1 should be a channel name i.e. #foo or &foo * if the channel is found, fine, if not report an error */ if ((chptr = hash_find_channel(nick)) != NULL) { if(!is_any_op(chptr, source_p) && !is_voiced(chptr, source_p)) { sendto_one(source_p, form_str(source_p,ERR_CHANOPRIVSNEEDED), me.name, source_p->name, with_prefix); return(-1); } if (!duplicate_ptr(chptr)) { if (ntargets >= ConfigFileEntry.max_targets) { sendto_one(source_p, form_str(source_p,ERR_TOOMANYTARGETS), me.name, source_p->name, nick); return (1); } targets[ntargets].ptr = (void *)chptr; targets[ntargets].type = ENTITY_CHANOPS_ON_CHANNEL; targets[ntargets++].flags = type; } } else { if (!ServerInfo.hub && (uplink != NULL) && IsCapable(uplink, CAP_LL)) return -1; else if (p_or_n != NOTICE) sendto_one(source_p, form_str(source_p,ERR_NOSUCHNICK), me.name, source_p->name, nick); } continue; } if(IsOper(source_p) && ((*nick == '$') || strchr(nick, '@'))) { handle_opers(p_or_n, command, client_p, source_p, nick, text); } else { if (!ServerInfo.hub && (uplink != NULL) && IsCapable(uplink, CAP_LL)) return -1; else if(p_or_n != NOTICE) sendto_one(source_p, form_str(source_p,ERR_NOSUCHNICK), me.name, source_p->name, nick); } /* continue; */ } return (1); }
/* * m_topic * parv[1] = channel name * parv[2] = new topic, if setting topic */ static int m_topic(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct Channel *chptr = NULL; struct membership *msptr; char *p = NULL; const char *name; int operspy = 0; if((p = strchr(parv[1], ','))) *p = '\0'; name = parv[1]; if(IsOperSpy(source_p) && parv[1][0] == '!') { name++; operspy = 1; if(EmptyString(name)) { sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, source_p->name, "TOPIC"); return 0; } } if(MyClient(source_p) && !IsFloodDone(source_p)) flood_endgrace(source_p); if(!IsChannelName(name)) { sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, form_str(ERR_NOSUCHCHANNEL), name); return 0; } chptr = find_channel(name); if(chptr == NULL) { sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, form_str(ERR_NOSUCHCHANNEL), name); return 0; } /* setting topic */ if(parc > 2) { char topic_info[USERHOST_REPLYLEN]; 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(MyClient(source_p) && !is_chanop_voiced(msptr) && !IsOper(source_p) && !add_channel_target(source_p, chptr)) { sendto_one(source_p, form_str(ERR_TARGCHANGE), me.name, source_p->name, chptr->chname); return 0; } if(MyClient(source_p) && (chptr->mode.mode & MODE_TOPICLIMIT) && !is_any_op(msptr)) { if(IsOverride(source_p)) { sendto_wallops_flags(UMODE_WALLOP, &me, "%s is overriding TOPIC on [%s]", get_oper_name(source_p), chptr->chname); sendto_server(NULL, chptr, NOCAPS, NOCAPS, ":%s WALLOPS :%s is overriding TOPIC on [%s]", me.name, get_oper_name(source_p), chptr->chname); } else { sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED), me.name, source_p->name, parv[1]); return 0; } } if(ConfigChannel.host_in_topic) sprintf(topic_info, "%s!%s@%s", source_p->name, source_p->username, source_p->host); else rb_strlcpy(topic_info, source_p->name, sizeof(topic_info)); set_channel_topic(chptr, parv[2], topic_info, rb_current_time()); sendto_server(client_p, chptr, CAP_TS6, NOCAPS, ":%s TOPIC %s :%s", use_id(source_p), chptr->chname, chptr->topic == NULL ? "" : chptr->topic); sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s TOPIC %s :%s", source_p->name, source_p->username, source_p->host, chptr->chname, chptr->topic == NULL ? "" : chptr->topic); } else if(MyClient(source_p)) { if(operspy) report_operspy(source_p, "TOPIC", chptr->chname); if(!IsMember(source_p, chptr) && SecretChannel(chptr) && !operspy) { sendto_one_numeric(source_p, ERR_NOTONCHANNEL, form_str(ERR_NOTONCHANNEL), name); return 0; } if(chptr->topic == NULL) sendto_one(source_p, form_str(RPL_NOTOPIC), me.name, source_p->name, name); else { sendto_one(source_p, form_str(RPL_TOPIC), me.name, source_p->name, chptr->chname, chptr->topic); sendto_one(source_p, form_str(RPL_TOPICWHOTIME), me.name, source_p->name, chptr->chname, chptr->topic_info, chptr->topic_time); } } return 0; }
/* * m_topic * parv[0] = sender prefix * parv[1] = channel name * parv[2] = new topic, if setting topic */ static void m_topic(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { struct Channel *chptr = NULL; struct Channel *root_chan; char *p = NULL; #ifdef VCHANS struct Channel *vchan; #endif if ((p = strchr(parv[1],','))) *p = '\0'; if(MyClient(source_p) && !IsFloodDone(source_p)) flood_endgrace(source_p); if (parv[1] && IsChannelName(parv[1])) { chptr = hash_find_channel(parv[1]); if(chptr == NULL) { /* if chptr isn't found locally, it =could= exist * on the uplink. so forward reqeuest */ if(!ServerInfo.hub && uplink && IsCapable(uplink, CAP_LL)) { sendto_one(uplink, ":%s TOPIC %s %s", source_p->name, parv[1], ((parc > 2) ? parv[2] : "")); return; } else { sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), me.name, parv[0], parv[1]); return; } } root_chan = chptr; #ifdef VCHANS if (HasVchans(chptr)) { vchan = map_vchan(chptr,source_p); if(vchan != NULL) chptr = vchan; } else if (IsVchan(chptr)) root_chan = RootChan(chptr); #endif /* setting topic */ if (parc > 2) { if (!IsMember(source_p, chptr)) { sendto_one(source_p, form_str(ERR_NOTONCHANNEL), me.name, parv[0], parv[1]); return; } if ((chptr->mode.mode & MODE_TOPICLIMIT) == 0 || is_any_op(chptr,source_p)) { char topic_info[USERHOST_REPLYLEN]; ircsprintf(topic_info, "%s!%s@%s", source_p->name, source_p->username, source_p->host); set_channel_topic(chptr, parv[2], topic_info, CurrentTime); sendto_server(client_p, NULL, chptr, NOCAPS, NOCAPS, NOFLAGS, ":%s TOPIC %s :%s", parv[0], chptr->chname, chptr->topic == NULL ? "" : chptr->topic); if(chptr->mode.mode & MODE_HIDEOPS) { sendto_channel_local(ONLY_CHANOPS_HALFOPS, chptr, ":%s!%s@%s TOPIC %s :%s", source_p->name, source_p->username, source_p->host, root_chan->chname, chptr->topic == NULL ? "" : chptr->topic); sendto_channel_local(NON_CHANOPS, chptr, ":%s TOPIC %s :%s", me.name, root_chan->chname, chptr->topic == NULL ? "" : chptr->topic); } else { sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s TOPIC %s :%s", source_p->name, source_p->username, source_p->host, root_chan->chname, chptr->topic == NULL ? "" : chptr->topic); } } else sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED), me.name, parv[0], parv[1]); } else /* only asking for topic */ { if (!IsMember(source_p, chptr) && SecretChannel(chptr)) { sendto_one(source_p, form_str(ERR_NOTONCHANNEL), me.name, parv[0], parv[1]); return; } if (chptr->topic == NULL) sendto_one(source_p, form_str(RPL_NOTOPIC), me.name, parv[0], parv[1]); else { sendto_one(source_p, form_str(RPL_TOPIC), me.name, parv[0], root_chan->chname, chptr->topic); if(!(chptr->mode.mode & MODE_HIDEOPS) || is_any_op(chptr,source_p)) { sendto_one(source_p, form_str(RPL_TOPICWHOTIME), me.name, parv[0], root_chan->chname, chptr->topic_info, chptr->topic_time); } /* client on LL needing the topic - if we have serverhide, say * its the actual LL server that set the topic, not us the * uplink -- fl_ */ else if(ConfigServerHide.hide_servers && !MyClient(source_p) && IsCapable(client_p, CAP_LL) && ServerInfo.hub) { sendto_one(source_p, form_str(RPL_TOPICWHOTIME), me.name, parv[0], root_chan->chname, client_p->name, chptr->topic_time); } /* just normal topic hiding.. */ else { sendto_one(source_p, form_str(RPL_TOPICWHOTIME), me.name, parv[0], root_chan->chname, me.name, chptr->topic_time); } } } } else { sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), me.name, parv[0], parv[1]); } }
/* * 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; }