diff --git a/CHANGELOG.md b/CHANGELOG.md index 360cba4f..96c5cf34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ New release of Oragono! ### Security ### Added +* Added `USERHOST` command (thanks @vegax87). ### Changed diff --git a/irc/commands.go b/irc/commands.go index 6f553443..ed811508 100644 --- a/irc/commands.go +++ b/irc/commands.go @@ -238,6 +238,10 @@ var Commands = map[string]Command{ usablePreReg: true, minParams: 4, }, + "USERHOST": { + handler: userhostHandler, + minParams: 1, + }, "VERSION": { handler: versionHandler, minParams: 0, diff --git a/irc/help.go b/irc/help.go index ec9290a3..bb89459f 100644 --- a/irc/help.go +++ b/irc/help.go @@ -370,6 +370,12 @@ For example: Used in connection registration, sets your username and realname to the given values (though your username may also be looked up with Ident).`, }, + + "userhost": { + text: `Show the nick, user and host of a user. Normally only used by the client or in scripts. +Note: if you are not an IRCOp then it will show a cloaked hostname if the user is +x (and it's not yourself). `, + }, + "version": { text: `VERSION [server] diff --git a/irc/server.go b/irc/server.go index b404b153..26516b90 100644 --- a/irc/server.go +++ b/irc/server.go @@ -1848,3 +1848,21 @@ func lusersHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool { client.Send(nil, server.name, RPL_LUSERME, client.nick, fmt.Sprintf("I have %d clients and %d servers", totalcount, 1)) return false } + +func userhostHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool { + nickname := msg.Params[0] + + casefoldedNickname, err := CasefoldName(nickname) + target := server.clients.Get(casefoldedNickname) + if err != nil || target == nil { + client.Send(nil, client.server.name, ERR_NOSUCHNICK, nickname, "No such nick") + return false + } + + if target.flags[Away] { + client.Send(nil, client.server.name, RPL_USERHOST, client.nick, fmt.Sprintf(strings.TrimSpace("%s =- %s @ %s"), target.nick, target.username, target.hostname)) + } else { + client.Send(nil, client.server.name, RPL_USERHOST, client.nick, fmt.Sprintf(strings.TrimSpace("%s =+ %s @ %s"), target.nick, target.username, target.hostname)) + } + return false +}