From ef2d54ebc86eff5ddebfbb96f4bdfbd1970b57e9 Mon Sep 17 00:00:00 2001
From: Peter Hellberg <peter@c7.se>
Date: Mon, 15 Dec 2014 01:12:19 +0100
Subject: [PATCH] Fix all lint issues (mainly ALL_CAPS and comments)

---
 client.go  | 62 +++++++++++++++++++++++++++--------------
 cmd.go     |  3 +-
 colors.go  | 46 ++++++++++++++++++++++---------
 history.go |  5 ++++
 server.go  | 81 ++++++++++++++++++++++++++++++++++++------------------
 5 files changed, 137 insertions(+), 60 deletions(-)

diff --git a/client.go b/client.go
index 7e570c2..57d9406 100644
--- a/client.go
+++ b/client.go
@@ -9,10 +9,15 @@ import (
 	"golang.org/x/crypto/ssh/terminal"
 )
 
-const MSG_BUFFER int = 50
-const MAX_MSG_LENGTH int = 512
+const (
+	// MsgBuffer is the length of the message buffer
+	MsgBuffer int = 50
 
-const HELP_TEXT string = SYSTEM_MESSAGE_FORMAT + `-> Available commands:
+	// MaxMsgLength is the maximum length of a message
+	MaxMsgLength int = 512
+
+	// HelpText is the text returned by /help
+	HelpText string = systemMessageFormat + `-> Available commands:
    /about               - About this chat.
    /exit                - Exit the chat.
    /help                - Show this help text.
@@ -23,18 +28,20 @@ const HELP_TEXT string = SYSTEM_MESSAGE_FORMAT + `-> Available commands:
    /whois $NAME         - Display information about another connected user.
    /msg $NAME $MESSAGE  - Sends a private message to a user.
    /motd                - Prints the Message of the Day
-` + RESET
+` + Reset
 
-const OP_HELP_TEXT string = SYSTEM_MESSAGE_FORMAT + `-> Available operator commands:
+	// OpHelpText is the additional text returned by /help if the client is an Op
+	OpHelpText string = systemMessageFormat + `-> Available operator commands:
    /ban $NAME                - Banish a user from the chat
    /kick $NAME               - Kick em' out.
    /op $NAME                 - Promote a user to server operator.
    /silence $NAME            - Revoke a user's ability to speak.
    /motd $MESSAGE            - Sets the Message of the Day
    /whitelist $FINGERPRINT   - Adds pubkey fingerprint to the connection whitelist
-` + RESET
+` + Reset
 
-const ABOUT_TEXT string = SYSTEM_MESSAGE_FORMAT + `-> ssh-chat is made by @shazow.
+	// AboutText is the text returned by /about
+	AboutText string = systemMessageFormat + `-> ssh-chat is made by @shazow.
 
    It is a custom ssh server built in Go to serve a chat experience
    instead of a shell.
@@ -42,10 +49,13 @@ const ABOUT_TEXT string = SYSTEM_MESSAGE_FORMAT + `-> ssh-chat is made by @shazo
    Source: https://github.com/shazow/ssh-chat
 
    For more, visit shazow.net or follow at twitter.com/shazow
-` + RESET
+` + Reset
 
-const REQUIRED_WAIT time.Duration = time.Second / 2
+	// RequiredWait is the time a client is required to wait between messages
+	RequiredWait time.Duration = time.Second / 2
+)
 
+// Client holds all the fields used by the client
 type Client struct {
 	Server        *Server
 	Conn          *ssh.ServerConn
@@ -62,38 +72,44 @@ type Client struct {
 	beepMe        bool
 }
 
+// NewClient constructs a new client
 func NewClient(server *Server, conn *ssh.ServerConn) *Client {
 	return &Client{
 		Server: server,
 		Conn:   conn,
 		Name:   conn.User(),
 		Color:  RandomColor256(),
-		Msg:    make(chan string, MSG_BUFFER),
+		Msg:    make(chan string, MsgBuffer),
 		ready:  make(chan struct{}, 1),
 		lastTX: time.Now(),
 	}
 }
 
+// ColoredName returns the client name in its color
 func (c *Client) ColoredName() string {
 	return ColorString(c.Color, c.Name)
 }
 
+// SysMsg sends a message in continuous format over the message channel
 func (c *Client) SysMsg(msg string, args ...interface{}) {
-	c.Msg <- ContinuousFormat(SYSTEM_MESSAGE_FORMAT, "-> "+fmt.Sprintf(msg, args...))
+	c.Msg <- ContinuousFormat(systemMessageFormat, "-> "+fmt.Sprintf(msg, args...))
 }
 
+// Write writes the given message
 func (c *Client) Write(msg string) {
 	c.term.Write([]byte(msg + "\r\n"))
 }
 
+// WriteLines writes multiple messages
 func (c *Client) WriteLines(msg []string) {
 	for _, line := range msg {
 		c.Write(line)
 	}
 }
 
+// Send sends the given message
 func (c *Client) Send(msg string) {
-	if len(msg) > MAX_MSG_LENGTH {
+	if len(msg) > MaxMsgLength {
 		return
 	}
 	select {
@@ -104,21 +120,25 @@ func (c *Client) Send(msg string) {
 	}
 }
 
+// SendLines sends multiple messages
 func (c *Client) SendLines(msg []string) {
 	for _, line := range msg {
 		c.Send(line)
 	}
 }
 
+// IsSilenced checks if the client is silenced
 func (c *Client) IsSilenced() bool {
 	return c.silencedUntil.After(time.Now())
 }
 
+// Silence silences a client for the given duration
 func (c *Client) Silence(d time.Duration) {
 	c.silencedUntil = time.Now().Add(d)
 }
 
-func (c *Client) Resize(width int, height int) error {
+// Resize resizes the client to the given width and height
+func (c *Client) Resize(width, height int) error {
 	err := c.term.SetSize(width, height)
 	if err != nil {
 		logger.Errorf("Resize failed: %dx%d", width, height)
@@ -128,11 +148,13 @@ func (c *Client) Resize(width int, height int) error {
 	return nil
 }
 
+// Rename renames the client to the given name
 func (c *Client) Rename(name string) {
 	c.Name = name
 	c.term.SetPrompt(fmt.Sprintf("[%s] ", c.ColoredName()))
 }
 
+// Fingerprint returns the fingerprint
 func (c *Client) Fingerprint() string {
 	return c.Conn.Permissions.Extensions["fingerprint"]
 }
@@ -172,12 +194,12 @@ func (c *Client) handleShell(channel ssh.Channel) {
 			case "/exit":
 				channel.Close()
 			case "/help":
-				c.WriteLines(strings.Split(HELP_TEXT, "\n"))
+				c.WriteLines(strings.Split(HelpText, "\n"))
 				if c.Server.IsOp(c) {
-					c.WriteLines(strings.Split(OP_HELP_TEXT, "\n"))
+					c.WriteLines(strings.Split(OpHelpText, "\n"))
 				}
 			case "/about":
-				c.WriteLines(strings.Split(ABOUT_TEXT, "\n"))
+				c.WriteLines(strings.Split(AboutText, "\n"))
 			case "/uptime":
 				c.Write(c.Server.Uptime())
 			case "/beep":
@@ -208,7 +230,7 @@ func (c *Client) handleShell(channel ssh.Channel) {
 				if len(parts) == 2 {
 					client := c.Server.Who(parts[1])
 					if client != nil {
-						version := RE_STRIP_TEXT.ReplaceAllString(string(client.Conn.ClientVersion()), "")
+						version := reStripText.ReplaceAllString(string(client.Conn.ClientVersion()), "")
 						if len(version) > 100 {
 							version = "Evil Jerk with a superlong string"
 						}
@@ -223,7 +245,7 @@ func (c *Client) handleShell(channel ssh.Channel) {
 				names := ""
 				nameList := c.Server.List(nil)
 				for _, name := range nameList {
-					names += c.Server.Who(name).ColoredName() + SYSTEM_MESSAGE_FORMAT + ", "
+					names += c.Server.Who(name).ColoredName() + systemMessageFormat + ", "
 				}
 				if len(names) > 2 {
 					names = names[:len(names)-2]
@@ -317,7 +339,7 @@ func (c *Client) handleShell(channel ssh.Channel) {
 					c.Server.MotdUnicast(c)
 				} else {
 					var newmotd string
-					if (len(parts) == 2) {
+					if len(parts) == 2 {
 						newmotd = parts[1]
 					} else {
 						newmotd = parts[1] + " " + parts[2]
@@ -344,7 +366,7 @@ func (c *Client) handleShell(channel ssh.Channel) {
 
 		msg := fmt.Sprintf("%s: %s", c.ColoredName(), line)
 		/* Rate limit */
-		if time.Now().Sub(c.lastTX) < REQUIRED_WAIT {
+		if time.Now().Sub(c.lastTX) < RequiredWait {
 			c.SysMsg("Rate limiting in effect.")
 			continue
 		}
diff --git a/cmd.go b/cmd.go
index cfedf85..9f5ea84 100644
--- a/cmd.go
+++ b/cmd.go
@@ -4,15 +4,16 @@ import (
 	"bufio"
 	"fmt"
 	"io/ioutil"
-	"strings"
 	"os"
 	"os/signal"
+	"strings"
 
 	"github.com/alexcesaro/log"
 	"github.com/alexcesaro/log/golog"
 	"github.com/jessevdk/go-flags"
 )
 
+// Options contains the flag options
 type Options struct {
 	Verbose   []bool   `short:"v" long:"verbose" description:"Show verbose logging."`
 	Identity  string   `short:"i" long:"identity" description:"Private key to identify server with." default:"~/.ssh/id_rsa"`
diff --git a/colors.go b/colors.go
index 1e85441..64fc64e 100644
--- a/colors.go
+++ b/colors.go
@@ -2,40 +2,60 @@ package main
 
 import (
 	"fmt"
+	"math/rand"
 	"strings"
-    "math/rand"
 	"time"
 )
 
-const RESET string =     "\033[0m"
-const BOLD string =      "\033[1m"
-const DIM string =       "\033[2m"
-const ITALIC string =    "\033[3m"
-const UNDERLINE string = "\033[4m"
-const BLINK string =     "\033[5m"
-const INVERT string =    "\033[7m"
+const (
+	// Reset resets the color
+	Reset = "\033[0m"
 
-var colors = []string { "31", "32", "33", "34", "35", "36", "37", "91", "92", "93", "94", "95", "96", "97" }
+	// Bold makes the following text bold
+	Bold = "\033[1m"
 
+	// Dim dims the following text
+	Dim = "\033[2m"
+
+	// Italic makes the following text italic
+	Italic = "\033[3m"
+
+	// Underline underlines the following text
+	Underline = "\033[4m"
+
+	// Blink blinks the following text
+	Blink = "\033[5m"
+
+	// Invert inverts the following text
+	Invert = "\033[7m"
+)
+
+var colors = []string{"31", "32", "33", "34", "35", "36", "37", "91", "92", "93", "94", "95", "96", "97"}
+
+// RandomColor256 returns a random (of 256) color
 func RandomColor256() string {
 	return fmt.Sprintf("38;05;%d", rand.Intn(256))
 }
 
+// RandomColor returns a random color
 func RandomColor() string {
 	return colors[rand.Intn(len(colors))]
 }
 
+// ColorString returns a message in the given color
 func ColorString(color string, msg string) string {
-	return BOLD + "\033[" + color + "m" + msg + RESET
+	return Bold + "\033[" + color + "m" + msg + Reset
 }
 
+// RandomColorInit initializes the random seed
 func RandomColorInit() {
 	rand.Seed(time.Now().UTC().UnixNano())
 }
 
-// Horrible hack to "continue" the previous string color and format
-//  after a RESET has been encountered.
+// ContinuousFormat is a horrible hack to "continue" the previous string color
+// and format after a RESET has been encountered.
+//
 // This is not HTML where you can just do a </style> to resume your previous formatting!
 func ContinuousFormat(format string, str string) string {
-	return SYSTEM_MESSAGE_FORMAT + strings.Replace(str, RESET, format, -1) + RESET
+	return systemMessageFormat + strings.Replace(str, Reset, format, -1) + Reset
 }
diff --git a/history.go b/history.go
index 698b72f..74ef513 100644
--- a/history.go
+++ b/history.go
@@ -3,6 +3,7 @@ package main
 
 import "sync"
 
+// History contains the history entries
 type History struct {
 	entries []string
 	head    int
@@ -10,12 +11,14 @@ type History struct {
 	lock    sync.Mutex
 }
 
+// NewHistory constructs a new history of the given size
 func NewHistory(size int) *History {
 	return &History{
 		entries: make([]string, size),
 	}
 }
 
+// Add adds the given entry to the entries in the history
 func (h *History) Add(entry string) {
 	h.lock.Lock()
 	defer h.lock.Unlock()
@@ -28,10 +31,12 @@ func (h *History) Add(entry string) {
 	}
 }
 
+// Len returns the number of entries in the history
 func (h *History) Len() int {
 	return h.size
 }
 
+// Get the entry with the given number
 func (h *History) Get(num int) []string {
 	h.lock.Lock()
 	defer h.lock.Unlock()
diff --git a/server.go b/server.go
index f360d13..dd94743 100644
--- a/server.go
+++ b/server.go
@@ -13,17 +13,22 @@ import (
 	"golang.org/x/crypto/ssh"
 )
 
-const MAX_NAME_LENGTH = 32
-const HISTORY_LEN = 20
+const (
+	maxNameLength        = 32
+	historyLength        = 20
+	systemMessageFormat  = "\033[1;3;90m"
+	privateMessageFormat = "\033[3m"
+	beep                 = "\007"
+)
 
-const SYSTEM_MESSAGE_FORMAT string = "\033[1;3;90m"
-const PRIVATE_MESSAGE_FORMAT string = "\033[3m"
-const BEEP string = "\007"
-
-var RE_STRIP_TEXT = regexp.MustCompile("[^0-9A-Za-z_.-]")
+var (
+	reStripText = regexp.MustCompile("[^0-9A-Za-z_.-]")
+)
 
+// Clients is a map of clients
 type Clients map[string]*Client
 
+// Server holds all the fields used by a server
 type Server struct {
 	sshConfig *ssh.ServerConfig
 	done      chan struct{}
@@ -34,11 +39,12 @@ type Server struct {
 	whitelist map[string]struct{}   // fingerprint lookup
 	admins    map[string]struct{}   // fingerprint lookup
 	bannedPk  map[string]*time.Time // fingerprint lookup
-	bannedIp  map[net.Addr]*time.Time
+	bannedIP  map[net.Addr]*time.Time
 	started   time.Time
 	sync.Mutex
 }
 
+// NewServer constructs a new server
 func NewServer(privateKey []byte) (*Server, error) {
 	signer, err := ssh.ParsePrivateKey(privateKey)
 	if err != nil {
@@ -49,12 +55,12 @@ func NewServer(privateKey []byte) (*Server, error) {
 		done:      make(chan struct{}),
 		clients:   Clients{},
 		count:     0,
-		history:   NewHistory(HISTORY_LEN),
+		history:   NewHistory(historyLength),
 		motd:      "Message of the Day! Modify with /motd",
 		whitelist: map[string]struct{}{},
 		admins:    map[string]struct{}{},
 		bannedPk:  map[string]*time.Time{},
-		bannedIp:  map[net.Addr]*time.Time{},
+		bannedIP:  map[net.Addr]*time.Time{},
 		started:   time.Now(),
 	}
 
@@ -80,14 +86,17 @@ func NewServer(privateKey []byte) (*Server, error) {
 	return &server, nil
 }
 
+// Len returns the number of clients
 func (s *Server) Len() int {
 	return len(s.clients)
 }
 
+// SysMsg broadcasts the given message to everyone
 func (s *Server) SysMsg(msg string, args ...interface{}) {
-	s.Broadcast(ContinuousFormat(SYSTEM_MESSAGE_FORMAT, " * "+fmt.Sprintf(msg, args...)), nil)
+	s.Broadcast(ContinuousFormat(systemMessageFormat, " * "+fmt.Sprintf(msg, args...)), nil)
 }
 
+// Broadcast broadcasts the given message to everyone except for the given client
 func (s *Server) Broadcast(msg string, except *Client) {
 	logger.Debugf("Broadcast to %d: %s", s.Len(), msg)
 	s.history.Add(msg)
@@ -99,45 +108,49 @@ func (s *Server) Broadcast(msg string, except *Client) {
 
 		if strings.Contains(msg, client.Name) {
 			// Turn message red if client's name is mentioned, and send BEL if they have enabled beeping
-			tmpMsg := strings.Split(msg, RESET)
+			tmpMsg := strings.Split(msg, Reset)
 			if client.beepMe {
-				tmpMsg[0] += BEEP
+				tmpMsg[0] += beep
 			}
-			client.Send(strings.Join(tmpMsg, RESET + BOLD + "\033[31m") + RESET)
+			client.Send(strings.Join(tmpMsg, Reset+Bold+"\033[31m") + Reset)
 		} else {
 			client.Send(msg)
 		}
 	}
 }
 
-/* Send a message to a particular nick, if it exists */
+// Privmsg sends a message to a particular nick, if it exists
 func (s *Server) Privmsg(nick, message string, sender *Client) error {
-	/* Get the recipient */
+	// Get the recipient
 	target, ok := s.clients[nick]
 	if !ok {
 		return fmt.Errorf("no client with that nick")
 	}
-	/* Send the message */
-	target.Msg <- fmt.Sprintf(BEEP+"[PM from %v] %s%v%s", sender.ColoredName(), PRIVATE_MESSAGE_FORMAT, message, RESET)
+	// Send the message
+	target.Msg <- fmt.Sprintf(beep+"[PM from %v] %s%v%s", sender.ColoredName(), privateMessageFormat, message, Reset)
 	logger.Debugf("PM from %v to %v: %v", sender.Name, nick, message)
 	return nil
 }
 
+// SetMotd sets the Message of the Day (MOTD)
 func (s *Server) SetMotd(motd string) {
 	s.Lock()
 	s.motd = motd
 	s.Unlock()
 }
 
+// MotdUnicast sends the MOTD as a SysMsg
 func (s *Server) MotdUnicast(client *Client) {
 	client.SysMsg("MOTD:\r\n" + ColorString("36", s.motd)) /* a nice cyan color */
 }
 
+// MotdBroadcast broadcasts the MOTD
 func (s *Server) MotdBroadcast(client *Client) {
-	s.Broadcast(ContinuousFormat(SYSTEM_MESSAGE_FORMAT, fmt.Sprintf(" * New MOTD set by %s.", client.ColoredName())), client)
+	s.Broadcast(ContinuousFormat(systemMessageFormat, fmt.Sprintf(" * New MOTD set by %s.", client.ColoredName())), client)
 	s.Broadcast(ColorString("36", s.motd), client)
 }
 
+// Add adds the client to the list of clients
 func (s *Server) Add(client *Client) {
 	go func() {
 		s.MotdUnicast(client)
@@ -158,9 +171,10 @@ func (s *Server) Add(client *Client) {
 	num := len(s.clients)
 	s.Unlock()
 
-	s.Broadcast(ContinuousFormat(SYSTEM_MESSAGE_FORMAT, fmt.Sprintf(" * %s joined. (Total connected: %d)", client.ColoredName(), num)), client)
+	s.Broadcast(ContinuousFormat(systemMessageFormat, fmt.Sprintf(" * %s joined. (Total connected: %d)", client.ColoredName(), num)), client)
 }
 
+// Remove removes the given client from the list of clients
 func (s *Server) Remove(client *Client) {
 	s.Lock()
 	delete(s.clients, client.Name)
@@ -172,23 +186,24 @@ func (s *Server) Remove(client *Client) {
 func (s *Server) proposeName(name string) (string, error) {
 	// Assumes caller holds lock.
 	var err error
-	name = RE_STRIP_TEXT.ReplaceAllString(name, "")
+	name = reStripText.ReplaceAllString(name, "")
 
-	if len(name) > MAX_NAME_LENGTH {
-		name = name[:MAX_NAME_LENGTH]
+	if len(name) > maxNameLength {
+		name = name[:maxNameLength]
 	} else if len(name) == 0 {
 		name = fmt.Sprintf("Guest%d", s.count)
 	}
 
 	_, collision := s.clients[name]
 	if collision {
-		err = fmt.Errorf("%s is not available.", name)
+		err = fmt.Errorf("%s is not available", name)
 		name = fmt.Sprintf("Guest%d", s.count)
 	}
 
 	return name, err
 }
 
+// Rename renames the given client (user)
 func (s *Server) Rename(client *Client, newName string) {
 	s.Lock()
 
@@ -209,10 +224,11 @@ func (s *Server) Rename(client *Client, newName string) {
 	s.SysMsg("%s is now known as %s.", ColorString(client.Color, oldName), ColorString(client.Color, newName))
 }
 
+// List lists the clients with the given prefix
 func (s *Server) List(prefix *string) []string {
 	r := []string{}
 
-	for name, _ := range s.clients {
+	for name := range s.clients {
 		if prefix != nil && !strings.HasPrefix(name, *prefix) {
 			continue
 		}
@@ -222,10 +238,12 @@ func (s *Server) List(prefix *string) []string {
 	return r
 }
 
+// Who returns the client with a given name
 func (s *Server) Who(name string) *Client {
 	return s.clients[name]
 }
 
+// Op adds the given fingerprint to the list of admins
 func (s *Server) Op(fingerprint string) {
 	logger.Infof("Adding admin: %s", fingerprint)
 	s.Lock()
@@ -233,6 +251,7 @@ func (s *Server) Op(fingerprint string) {
 	s.Unlock()
 }
 
+// Whitelist adds the given fingerprint to the whitelist
 func (s *Server) Whitelist(fingerprint string) {
 	logger.Infof("Adding whitelist: %s", fingerprint)
 	s.Lock()
@@ -240,15 +259,18 @@ func (s *Server) Whitelist(fingerprint string) {
 	s.Unlock()
 }
 
+// Uptime returns the time since the server was started
 func (s *Server) Uptime() string {
 	return time.Now().Sub(s.started).String()
 }
 
+// IsOp checks if the given client is Op
 func (s *Server) IsOp(client *Client) bool {
 	_, r := s.admins[client.Fingerprint()]
 	return r
 }
 
+// IsWhitelisted checks if the given fingerprint is whitelisted
 func (s *Server) IsWhitelisted(fingerprint string) bool {
 	/* if no whitelist, anyone is welcome */
 	if len(s.whitelist) == 0 {
@@ -260,6 +282,7 @@ func (s *Server) IsWhitelisted(fingerprint string) bool {
 	return r
 }
 
+// IsBanned checks if the given fingerprint is banned
 func (s *Server) IsBanned(fingerprint string) bool {
 	ban, hasBan := s.bannedPk[fingerprint]
 	if !hasBan {
@@ -275,6 +298,7 @@ func (s *Server) IsBanned(fingerprint string) bool {
 	return true
 }
 
+// Ban bans a fingerprint for the given duration
 func (s *Server) Ban(fingerprint string, duration *time.Duration) {
 	var until *time.Time
 	s.Lock()
@@ -286,12 +310,14 @@ func (s *Server) Ban(fingerprint string, duration *time.Duration) {
 	s.Unlock()
 }
 
+// Unban unbans a banned fingerprint
 func (s *Server) Unban(fingerprint string) {
 	s.Lock()
 	delete(s.bannedPk, fingerprint)
 	s.Unlock()
 }
 
+// Start starts the server
 func (s *Server) Start(laddr string) error {
 	// Once a ServerConfig has been configured, connections can be
 	// accepted.
@@ -324,7 +350,7 @@ func (s *Server) Start(laddr string) error {
 					return
 				}
 
-				version := RE_STRIP_TEXT.ReplaceAllString(string(sshConn.ClientVersion()), "")
+				version := reStripText.ReplaceAllString(string(sshConn.ClientVersion()), "")
 				if len(version) > 100 {
 					version = "Evil Jerk with a superlong string"
 				}
@@ -346,6 +372,7 @@ func (s *Server) Start(laddr string) error {
 	return nil
 }
 
+// AutoCompleteFunction handles auto completion of nicks
 func (s *Server) AutoCompleteFunction(line string, pos int, key rune) (newLine string, newPos int, ok bool) {
 	if key == 9 {
 		shortLine := strings.Split(line[:pos], " ")
@@ -372,6 +399,7 @@ func (s *Server) AutoCompleteFunction(line string, pos int, key rune) (newLine s
 	return
 }
 
+// Stop stops the server
 func (s *Server) Stop() {
 	for _, client := range s.clients {
 		client.Conn.Close()
@@ -380,6 +408,7 @@ func (s *Server) Stop() {
 	close(s.done)
 }
 
+// Fingerprint returns the fingerprint based on a public key
 func Fingerprint(k ssh.PublicKey) string {
 	hash := md5.Sum(k.Marshal())
 	r := fmt.Sprintf("% x", hash)