func listQuery(conn *irc.Conn, channelName string) (*Result, error) { conn.SendRawf("LIST %s", channelName) numusers := 0 topic := "" received322 := false for { ev, err := conn.WaitUntil( "322", // RPL_LIST "323", // RPL_LISTEND "401", // ERR_NOSUCHNICK (nick/channel) "403", // ERR_NOSUCHCHANNEL ) if err != nil { return nil, err } switch ev.Code { case "322": received322 = true if len(ev.Args) < 4 { return nil, fmt.Errorf("Unexpectedly short LIST response on %s", channelName) } numusers, err = strconv.Atoi(ev.Args[2]) if err != nil { return nil, fmt.Errorf("Failed to parse number of channel users: %s", err.Error()) } topic = ev.Args[3] case "323": if received322 == false { return nil, fmt.Errorf("No status data for %s received on query", channelName) } goto ret case "401": fallthrough case "403": return nil, fmt.Errorf("No such channel, '%s'", channelName) } } ret: return &Result{ NumberOfUsers: numusers, Topic: topic, }, nil }
func joinQuery(conn *irc.Conn, channelName string) (*Result, error) { conn.SendRawf("JOIN %s", channelName) conn.SendRawf("TOPIC %s", channelName) numusers := 0 topic := "" receivedTopic, receivedNames := false, false for { ev, err := conn.WaitUntil( "353", // RPL_NAMREPLY "366", // RPL_ENDOFNAMES "331", // RPL_NOTOPIC "332", // RPL_TOPIC "422", // ERR_NOMOTD ) if err != nil { return nil, err } switch ev.Code { case "353": if len(ev.Args) != 0 { numusers += len(strings.Split(ev.Args[len(ev.Args)-1], " ")) } case "332": topic = ev.Args[len(ev.Args)-1] receivedTopic = true case "366": receivedNames = true case "422": continue case "331": receivedTopic = true } if receivedNames && receivedTopic { break } } // TODO: Make it possible to add a parting message conn.SendRawf("PART %s", channelName) return &Result{ NumberOfUsers: numusers, Topic: topic, }, nil }