diff --git a/README.md b/README.md index 5d1923b..cc4b53d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![Build Status](https://travis-ci.org/shazow/ssh-chat.svg?branch=master)](https://travis-ci.org/shazow/ssh-chat) + # ssh-chat Custom SSH server written in Go. Instead of a shell, you get a chat prompt. @@ -57,6 +59,7 @@ See notes in the header of our Dockerfile for details on building your own image If you're developing on this repo, there is a handy Makefile that should set things up with `make run`. +Additionally, `make debug` runs the server with an http `pprof` server. This allows you to open [http://localhost:6060/debug/pprof/]() and view profiling data. See [net/http/pprof](http://golang.org/pkg/net/http/pprof/) for more information about `pprof`. ## License diff --git a/cmd.go b/cmd.go index ab41788..82398b5 100644 --- a/cmd.go +++ b/cmd.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "os" "os/signal" + "os/user" "strings" "net/http" @@ -61,7 +62,15 @@ func main() { logLevel := logLevels[numVerbose] logger = golog.New(os.Stderr, logLevel) - privateKey, err := ioutil.ReadFile(options.Identity) + privateKeyPath := options.Identity + if strings.HasPrefix(privateKeyPath, "~") { + user, err := user.Current() + if err == nil { + privateKeyPath = strings.Replace(privateKeyPath, "~", user.HomeDir, 1) + } + } + + privateKey, err := ioutil.ReadFile(privateKeyPath) if err != nil { logger.Errorf("Failed to load identity: %v", err) return diff --git a/server.go b/server.go index dd47bba..431f32d 100644 --- a/server.go +++ b/server.go @@ -120,7 +120,7 @@ func (s *Server) Broadcast(msg string, except *Client) { // Privmsg sends a message to a particular nick, if it exists func (s *Server) Privmsg(nick, message string, sender *Client) error { // Get the recipient - target, ok := s.clients[nick] + target, ok := s.clients[strings.ToLower(nick)] if !ok { return fmt.Errorf("no client with that nick") } @@ -170,7 +170,7 @@ func (s *Server) Add(client *Client) { } client.Rename(newName) - s.clients[client.Name] = client + s.clients[strings.ToLower(client.Name)] = client num := len(s.clients) s.Unlock() @@ -180,7 +180,7 @@ func (s *Server) Add(client *Client) { // Remove removes the given client from the list of clients func (s *Server) Remove(client *Client) { s.Lock() - delete(s.clients, client.Name) + delete(s.clients, strings.ToLower(client.Name)) s.Unlock() s.SysMsg("%s left.", client.ColoredName()) @@ -197,7 +197,7 @@ func (s *Server) proposeName(name string) (string, error) { name = fmt.Sprintf("Guest%d", s.count) } - _, collision := s.clients[name] + _, collision := s.clients[strings.ToLower(name)] if collision { err = fmt.Errorf("%s is not available", name) name = fmt.Sprintf("Guest%d", s.count) @@ -209,21 +209,25 @@ func (s *Server) proposeName(name string) (string, error) { // Rename renames the given client (user) func (s *Server) Rename(client *Client, newName string) { s.Lock() + var oldName string + if strings.ToLower(newName) == strings.ToLower(client.Name) { + oldName = client.Name + client.Rename(newName) + } else { + newName, err := s.proposeName(newName) + if err != nil { + client.SysMsg("%s", err) + s.Unlock() + return + } - newName, err := s.proposeName(newName) - if err != nil { - client.SysMsg("%s", err) + // TODO: Use a channel/goroutine for adding clients, rather than locks? + delete(s.clients, strings.ToLower(client.Name)) + oldName = client.Name + client.Rename(newName) + s.clients[strings.ToLower(client.Name)] = client s.Unlock() - return } - - // TODO: Use a channel/goroutine for adding clients, rather than locks? - delete(s.clients, client.Name) - oldName := client.Name - client.Rename(newName) - s.clients[client.Name] = client - s.Unlock() - s.SysMsg("%s is now known as %s.", ColorString(client.Color, oldName), ColorString(client.Color, newName)) } @@ -243,7 +247,7 @@ func (s *Server) List(prefix *string) []string { // Who returns the client with a given name func (s *Server) Who(name string) *Client { - return s.clients[name] + return s.clients[strings.ToLower(name)] } // Op adds the given fingerprint to the list of admins