/* * mr_nick() * * parv[0] = sender prefix * parv[1] = nickname */ static void mr_nick(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { struct Client *target_p; char nick[NICKLEN]; char *s; if(parc < 2 || BadPtr(parv[1])) { sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN), me.name, BadPtr(parv[0]) ? "*" : parv[0]); return; } /* Terminate the nick at the first ~ */ if((s = strchr(parv[1], '~'))) *s = '\0'; /* and if the first ~ was the first letter.. */ if(BadPtr(parv[1])) { sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), me.name, BadPtr(parv[0]) ? "*" : parv[0], parv[1]); return; } /* copy the nick and terminate it */ strlcpy(nick, parv[1], sizeof(nick)); /* check the nickname is ok */ if(!clean_nick_name(nick)) { sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), me.name, BadPtr(parv[0]) ? "*" : parv[0], parv[1]); return; } /* check if the nick is resv'd */ if(find_nick_resv(nick)) { sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), me.name, BadPtr(parv[0]) ? "*" : parv[0], nick); return; } if((target_p = find_client(nick)) == NULL) { set_initial_nick(client_p, source_p, nick); return; } else if(source_p == target_p) { strcpy(source_p->name, nick); return; } else { sendto_one(source_p, form_str(ERR_NICKNAMEINUSE), me.name, "*", nick); } }
/* check_clean_nick() * * input - pointer to source * - * - nickname * - truncated nickname * - origin of client * - pointer to server nick is coming from * output - none * side effects - if nickname is erroneous, or a different length to * truncated nickname, return 1 */ static int check_clean_nick(struct Client *client_p, struct Client *source_p, char *nick, struct Client *server_p) { /* the old code did some wacky stuff here, if the nick is invalid, kill it * and dont bother messing at all */ if (!clean_nick_name(nick, 0)) { ++ServerStats.is_kill; sendto_realops_flags(UMODE_DEBUG, L_ALL, "Bad/long Nick: %s From: %s(via %s)", nick, server_p->name, client_p->name); sendto_one(client_p, ":%s KILL %s :%s (Bad Nickname)", me.name, nick, me.name); /* bad nick change */ if (source_p != client_p) { kill_client_ll_serv_butone(client_p, source_p, "%s (Bad Nickname)", me.name); SetKilled(source_p); exit_client(source_p, &me, "Bad Nickname"); } return 1; } return 0; }
/* * check_clean_nick() * * input - pointer to source * - nickname * - truncated nickname * - origin of client * output - none * side effects - if nickname is erroneous, or a different length to * truncated nickname, return 1 */ static int check_clean_nick(struct Client *client_p, struct Client *source_p, char *nick, char *newnick, char *server) { /* the old code did some wacky stuff here, if the nick is invalid, kill it * and dont bother messing at all */ /* * Zero length nicks are bad too..this shouldn't happen but.. */ if(!clean_nick_name(nick) || strcmp(nick, newnick) || nick[0] == '\0') { ServerStats->is_kill++; sendto_realops_flags(UMODE_DEBUG, L_ALL, "Bad Nick: %s From: %s(via %s)", nick, server, client_p->name); sendto_one(client_p, ":%s KILL %s :%s (Bad Nickname)", me.name, newnick, me.name); /* bad nick change */ if(source_p != client_p) { kill_client_serv_butone(client_p, source_p, "%s (Bad Nickname)", me.name); source_p->flags |= FLAGS_KILLED; exit_client(client_p, source_p, &me, "Bad Nickname"); } return 1; } return 0; }
/*! \brief NICK command handler (called by unregistered, * locally connected clients) * * \param client_p Pointer to allocated Client struct with physical connection * to this server, i.e. with an open socket connected. * \param source_p Pointer to allocated Client struct from which the message * originally comes from. This can be a local or remote client. * \param parc Integer holding the number of supplied arguments. * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL * pointers. * \note Valid arguments for this command are: * - parv[0] = sender prefix * - parv[1] = nickname */ static void mr_nick(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { struct Client *target_p = NULL; char nick[NICKLEN]; char *s = NULL; if (parc < 2 || EmptyString(parv[1])) { sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN), me.name, EmptyString(parv[0]) ? "*" : parv[0]); return; } /* Terminate the nick at the first ~ */ if ((s = strchr(parv[1], '~')) != NULL) *s = '\0'; /* copy the nick and terminate it */ strlcpy(nick, parv[1], sizeof(nick)); /* check the nickname is ok */ if (!clean_nick_name(nick, 1)) { sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), me.name, EmptyString(parv[0]) ? "*" : parv[0], parv[1]); return; } /* check if the nick is resv'd */ if (find_matching_name_conf(NRESV_TYPE, nick, NULL, NULL, 0) && !IsExemptResv(source_p)) { sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), me.name, EmptyString(parv[0]) ? "*" : parv[0], nick); return; } if ((target_p = find_client(nick)) == NULL) set_initial_nick(source_p, nick); else if (source_p == target_p) strlcpy(source_p->name, nick, sizeof(source_p->name)); else sendto_one(source_p, form_str(ERR_NICKNAMEINUSE), me.name, "*", nick); }
/*! \brief NICK command handler (called by already registered, * locally connected clients) * * \param client_p Pointer to allocated Client struct with physical connection * to this server, i.e. with an open socket connected. * \param source_p Pointer to allocated Client struct from which the message * originally comes from. This can be a local or remote client. * \param parc Integer holding the number of supplied arguments. * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL * pointers. * \note Valid arguments for this command are: * - parv[0] = sender prefix * - parv[1] = nickname */ static void m_nick(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { char nick[NICKLEN]; struct Client *target_p = NULL; if (parc < 2 || EmptyString(parv[1])) { sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN), me.name, source_p->name); return; } /* mark end of grace period, to prevent nickflooding */ if (!IsFloodDone(source_p)) flood_endgrace(source_p); /* terminate nick to NICKLEN */ strlcpy(nick, parv[1], sizeof(nick)); /* check the nickname is ok */ if (!clean_nick_name(nick, 1)) { sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), me.name, source_p->name, nick); return; } if (find_matching_name_conf(NRESV_TYPE, nick, NULL, NULL, 0) && !IsExemptResv(source_p) && !(IsOper(source_p) && ConfigFileEntry.oper_pass_resv)) { sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), me.name, source_p->name, nick); return; } if ((target_p = find_client(nick)) == NULL) change_local_nick(client_p, source_p, nick); else if (target_p == source_p) { /* * If (target_p == source_p) the client is changing nicks between * equivalent nicknames ie: [nick] -> {nick} */ /* check the nick isnt exactly the same */ if (strcmp(target_p->name, nick)) change_local_nick(client_p, source_p, nick); } else if (IsUnknown(target_p)) { /* * if the client that has the nick isn't registered yet (nick but no * user) then drop the unregged client */ exit_client(target_p, &me, "Overridden"); change_local_nick(client_p, source_p, nick); } else sendto_one(source_p, form_str(ERR_NICKNAMEINUSE), me.name, source_p->name, nick); }
/* * m_nick() * * parv[0] = sender prefix * parv[1] = nickname */ static void m_nick(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { char nick[NICKLEN]; struct Client *target_p; if(parc < 2 || BadPtr(parv[1])) { sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN), me.name, parv[0]); return; } /* mark end of grace period, to prevent nickflooding */ if(!IsFloodDone(source_p)) flood_endgrace(source_p); /* terminate nick to NICKLEN */ strlcpy(nick, parv[1], sizeof(nick)); /* check the nickname is ok */ if(!clean_nick_name(nick)) { sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), me.name, parv[0], nick); return; } if(find_nick_resv(nick)) { sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), me.name, parv[0], nick); return; } if((target_p = find_client(nick))) { /* If(target_p == source_p) the client is changing nicks between * equivalent nicknames ie: [nick] -> {nick} */ if(target_p == source_p) { /* check the nick isnt exactly the same */ if(strcmp(target_p->name, nick)) { change_local_nick(client_p, source_p, nick); return; } else { /* client is doing :old NICK old * ignore it.. */ return; } } /* if the client that has the nick isnt registered yet (nick but no * user) then drop the unregged client */ if(IsUnknown(target_p)) { /* the old code had an if(MyConnect(target_p)) here.. but I cant see * how that can happen, m_nick() is local only --fl_ */ exit_client(NULL, target_p, &me, "Overridden"); change_local_nick(client_p, source_p, nick); return; } else { sendto_one(source_p, form_str(ERR_NICKNAMEINUSE), me.name, parv[0], nick); return; } } else { change_local_nick(client_p, source_p, nick); return; } }
/* * ms_svsnick() * * parv[0] = sender prefix * parv[1] = oldnick * parv[2] = newnick */ static void ms_svsnick(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { char oldnick[NICKLEN]; char newnick[NICKLEN]; struct Client *oldnickname; struct Client *newnickname; if (!IsServer(source_p)) return; /* XXX BadPtr is needed */ if(parc < 3 || BadPtr(parv[1]) || BadPtr(parv[2])) { sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN), me.name, parv[0]); return; } /* terminate nick to NICKLEN */ strlcpy(oldnick, parv[1], NICKLEN); strlcpy(newnick, parv[2], NICKLEN); if(!clean_nick_name(oldnick)) { sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), me.name, parv[0], oldnick); return; } /* check the nickname is ok */ if(!clean_nick_name(newnick)) { sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), me.name, parv[0], newnick); return; } if(find_nick_resv(newnick) && !(IsOper(source_p) && ConfigChannel.oper_pass_resv)) { sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE), me.name, parv[0], newnick); return; } if(!(oldnickname = find_client(oldnick))) { sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, source_p->name, oldnick); return; } if(newnickname = find_client(newnick)) { sendto_one(source_p, form_str(ERR_NICKNAMEINUSE), me.name, parv[0], newnick); return; } if(MyConnect(oldnickname)) { if(!IsFloodDone(oldnickname)) flood_endgrace(oldnickname); if (newnickname = find_client(oldnick)) { if(newnickname == oldnickname) { /* check the nick isnt exactly the same */ if(strcmp(oldnickname->name, newnick)) { change_local_nick(oldnickname->servptr, oldnickname, newnick); return; } else { /* client is doing :old NICK old * ignore it.. */ return; } } /* if the client that has the nick isnt registered yet (nick but no * user) then drop the unregged client */ if(IsUnknown(newnickname)) { /* the old code had an if(MyConnect(target_p)) here.. but I cant see * how that can happen, m_nick() is local only --fl_ */ exit_client(NULL, newnickname, &me, "Overridden"); change_local_nick(oldnickname->servptr, oldnickname, newnick); return; } else { sendto_one(source_p, form_str(ERR_NICKNAMEINUSE), me.name, parv[0], newnick); return; } } else { if(!ServerInfo.hub && uplink && IsCapable(uplink, CAP_LL)) { /* The uplink might know someone by this name already. */ sendto_one(uplink, ":%s NBURST %s %s %s", me.name, newnick, newnick, oldnickname->name); return; } else { change_local_nick(oldnickname->servptr, oldnickname, newnick); return; } } } else { sendto_server(client_p, source_p, NULL, CAP_SVNICK, NOCAPS, NOFLAGS, ":%s SVSNICK %s %s", me.name, oldnick, newnick); return; } }