/* * 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(IsOperAuspex(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]; char topic[BUFSIZE]; 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) == 0 || is_chanop(msptr)) && can_send(chptr, source_p, msptr))) { if(IsOverride(source_p)) sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "%s is overriding TOPIC on [%s]", get_oper_name(source_p), chptr->chname); else { sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED), get_id(&me, source_p), get_id(source_p, source_p), name); return 0; } } rb_strlcpy(topic, parv[2], BUFSIZE); strip_colour(topic); rb_sprintf(topic_info, "%s!%s@%s", source_p->name, source_p->username, source_p->host); set_channel_topic(chptr, topic, 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_mode - MODE command handler * parv[1] - channel */ static int m_mode(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct Channel *chptr = NULL; struct membership *msptr; int n = 2; const char *dest; int operspy = 0; dest = parv[1]; if(IsOperAuspex(source_p) && *dest == '!') { dest++; operspy = 1; if(EmptyString(dest)) { sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, source_p->name, "MODE"); return 0; } } /* Now, try to find the channel in question */ if(!IsChanPrefix(*dest)) { /* if here, it has to be a non-channel name */ user_mode(client_p, source_p, parc, parv); return 0; } if(!check_channel_name(dest)) { sendto_one_numeric(source_p, ERR_BADCHANNAME, form_str(ERR_BADCHANNAME), parv[1]); return 0; } chptr = find_channel(dest); if(chptr == NULL) { sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, form_str(ERR_NOSUCHCHANNEL), parv[1]); return 0; } /* Now know the channel exists */ if(parc < n + 1) { if(operspy) report_operspy(source_p, "MODE", chptr->chname); sendto_one(source_p, form_str(RPL_CHANNELMODEIS), me.name, source_p->name, parv[1], operspy ? channel_modes(chptr, &me) : channel_modes(chptr, source_p)); sendto_one(source_p, form_str(RPL_CREATIONTIME), me.name, source_p->name, parv[1], chptr->channelts); } else { msptr = find_channel_membership(chptr, source_p); /* Finish the flood grace period... */ if(MyClient(source_p) && !IsFloodDone(source_p)) { if(!((parc == 3) && (parv[2][0] == 'b') && (parv[2][1] == '\0'))) flood_endgrace(source_p); } set_channel_mode(client_p, source_p, chptr, msptr, parc - n, parv + n); } return 0; }