/*! \brief USERHOST command handler * * \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] = command * - parv[1] = space-separated list of up to 5 nicknames */ static int m_userhost(struct Client *source_p, int parc, char *parv[]) { char buf[IRCD_BUFSIZE]; char response[NICKLEN + USERLEN + HOSTLEN + 6]; /* +6 for "*=+@ \0" */ char *t = NULL, *p = NULL; int i = 0; int cur_len; int rl; cur_len = snprintf(buf, sizeof(buf), numeric_form(RPL_USERHOST), me.name, source_p->name, ""); t = buf + cur_len; for (const char *name = strtok_r(parv[1], " ", &p); name && i++ < 5; name = strtok_r(NULL, " ", &p)) { const struct Client *target_p; if ((target_p = find_person(source_p, name))) { /* * Show real IP address for USERHOST on yourself. * This is needed for things like mIRC, which do a server-based * lookup (USERHOST) to figure out what the clients' local IP * is. Useful for things like NAT, and dynamic dial-up users. */ if (target_p == source_p) { rl = snprintf(response, sizeof(response), "%s%s=%c%s@%s ", target_p->name, HasUMode(target_p, UMODE_OPER) ? "*" : "", (target_p->away[0]) ? '-' : '+', target_p->username, target_p->sockhost); } else { rl = snprintf(response, sizeof(response), "%s%s=%c%s@%s ", target_p->name, (HasUMode(target_p, UMODE_OPER) && (!HasUMode(target_p, UMODE_HIDDEN) || HasUMode(source_p, UMODE_OPER))) ? "*" : "", (target_p->away[0]) ? '-' : '+', target_p->username, target_p->host); } if ((rl + cur_len) < (IRCD_BUFSIZE - 10)) { sprintf(t, "%s", response); t += rl; cur_len += rl; } else break; } } sendto_one(source_p, "%s", buf); return 0; }
/*! \brief ISON command handler * * \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] = command * - parv[1] = space-separated list of nicknames */ static int m_ison(struct Client *source_p, int parc, char *parv[]) { struct Client *target_p = NULL; char *nick; char *p = NULL; char *current_insert_point = NULL; char buf[IRCD_BUFSIZE]; int len, cut = 0; len = snprintf(buf, sizeof(buf), numeric_form(RPL_ISON), me.name, source_p->name); current_insert_point = buf + len; for (nick = strtok_r(parv[1], " ", &p); nick; nick = strtok_r(NULL, " ", &p)) { if ((target_p = find_person(source_p, nick))) { len = strlen(target_p->name); if ((current_insert_point + (len + 5)) < (buf + sizeof(buf))) { cut = 1; strlcpy(current_insert_point, target_p->name, len + 1); current_insert_point += len; *current_insert_point++ = ' '; } else break; } } *(current_insert_point - cut) = '\0'; sendto_one(source_p, "%s", buf); return 0; }