lelegram: stuckness fixes, timeout

Change-Id: I3c1ad4e589ea66db846a56aab8a2c1698bdee539
diff --git a/personal/q3k/lelegram/irc/conn.go b/personal/q3k/lelegram/irc/conn.go
index 7f130ca..9f1f4ef 100644
--- a/personal/q3k/lelegram/irc/conn.go
+++ b/personal/q3k/lelegram/irc/conn.go
@@ -4,6 +4,7 @@
 	"context"
 	"fmt"
 	"net"
+	"regexp"
 	"strings"
 	"sync"
 	"sync/atomic"
@@ -52,6 +53,8 @@
 	connected int64
 }
 
+var reIRCNick = regexp.MustCompile(`[^a-z0-09]`)
+
 // Say is called by the Manager when a message should be sent out by the
 // connection.
 func (i *ircconn) Say(msg *controlMessage) {
@@ -100,10 +103,14 @@
 	}
 
 	// Generate IRC nick from username.
-	nick := user
+	nick := reIRCNick.ReplaceAllString(user, "")
 	if len(nick) > 13 {
 		nick = nick[:13]
 	}
+	if len(nick) == 0 {
+		glog.Errorf("Could not create IRC nick for %q", user)
+		nick = "wtf"
+	}
 	nick += "[t]"
 
 	// Configure IRC client to populate the IRC Queue.
@@ -186,7 +193,7 @@
 			})
 			if err != nil {
 				glog.Errorf("IRC/%s: WriteMessage: %v", i.user, err)
-				die()
+				die(err)
 				s.done <- err
 				return
 			}
diff --git a/personal/q3k/lelegram/irc/manager_control.go b/personal/q3k/lelegram/irc/manager_control.go
index 68e9002..4e6b0b7 100644
--- a/personal/q3k/lelegram/irc/manager_control.go
+++ b/personal/q3k/lelegram/irc/manager_control.go
@@ -8,16 +8,23 @@
 )
 
 // Control: send a message to IRC.
-func (m *Manager) SendMessage(user, text string) error {
+func (m *Manager) SendMessage(ctx context.Context, user, text string) error {
 	done := make(chan error)
-	m.ctrl <- &control{
+
+	msg := &control{
 		message: &controlMessage{
 			from:    user,
 			message: text,
 			done:    done,
 		},
 	}
-	return <-done
+
+	select {
+	case <-ctx.Done():
+		return ctx.Err()
+	case m.ctrl <- msg:
+		return <-done
+	}
 }
 
 // Control: subscribe to notifiactions.