package sircd import ( "github.com/sirupsen/logrus" "net" ) type sircd struct { Running bool log *logrus.Logger netName string ircPort uint16 httpPort uint16 ircListener net.Listener ircClients map[*ircClient]bool newClients chan *ircClient deadClients chan *ircClient messageQueue chan *ircMessage } const ( CONN_HOST = "localhost" CONN_PORT = "6667" CONN_TYPE = "tcp" ) func NewSircd() *sircd { s := new(sircd) s.Running = true s.ircClients = make(map[*ircClient]bool) return s } func (s *sircd) SetLogger(l *logrus.Logger) { s.log = l } func (s *sircd) Start() { s.newClients = make(chan *ircClient, 128) s.deadClients = make(chan *ircClient, 128) s.messageQueue = make(chan *ircMessage, 128) var err error s.ircListener, err = net.Listen(CONN_TYPE, CONN_HOST+":"+CONN_PORT) if err != nil { s.log.Fatalln("Error listening:", err.Error()) } s.log.Println("Listening for irc on " + CONN_HOST + ":" + CONN_PORT) go func() { conn, err := s.ircListener.Accept() if err != nil { s.log.Panicf("Error accepting: ", err.Error()) } s.newClients <- newIrcClient(conn, s.log, s.messageQueue) }() go s.mainloop() } func (s *sircd) mainloop() { for { select { case client := <-s.newClients: s.ircClients[client] = true s.log.Println("new irc client: %s", client.Id) go func() { buf := make([]byte, 1024*1024) for { nbyte, err := client.conn.Read(buf) if err != nil { s.deadClients <- client break } else { fragment := make([]byte, nbyte) copy(fragment, buf[:nbyte]) // this will populate the message channel client.AppendInputBuffer(fragment) } } }() case deadClient := <-s.deadClients: delete(s.ircClients, deadClient) deadClient.Close() case message := <-s.messageQueue: s.processIRCMessage(message) } } } /* case publish := <-publishes: for conn, _ := range conns { go func(conn net.Conn) { totalWritten := 0 for totalWritten < len(publish) { writtenThisCall, err := conn.Write(publish[totalWritten:]) if err != nil { deadConns <- conn break } totalWritten += writtenThisCall } }(conn) } } } listener.Close() */