From fbc6c84a012ff1bf9dd95e9a70055b9fcd852f86 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Thu, 9 May 2019 14:18:30 -0400 Subject: [PATCH 1/4] add client compatibility switches --- irc/client.go | 3 ++- irc/config.go | 18 +++++++++++++++--- irc/getters.go | 15 ++++++++------- irc/handlers.go | 11 ++++++++++- irc/server.go | 9 ++++----- oragono.yaml | 15 +++++++++++++++ 6 files changed, 54 insertions(+), 17 deletions(-) diff --git a/irc/client.go b/irc/client.go index e7cb33a1..4fb37046 100644 --- a/irc/client.go +++ b/irc/client.go @@ -1085,7 +1085,8 @@ var ( func (session *Session) SendRawMessage(message ircmsg.IrcMessage, blocking bool) error { // use dumb hack to force the last param to be a trailing param if required var usedTrailingHack bool - if commandsThatMustUseTrailing[message.Command] && len(message.Params) > 0 { + config := session.client.server.Config() + if config.Server.Compatibility.forceTrailing && commandsThatMustUseTrailing[message.Command] && len(message.Params) > 0 { lastParam := message.Params[len(message.Params)-1] // to force trailing, we ensure the final param contains a space if strings.IndexByte(lastParam, ' ') == -1 { diff --git a/irc/config.go b/irc/config.go index c585601b..c79d43cd 100644 --- a/irc/config.go +++ b/irc/config.go @@ -286,9 +286,14 @@ type Config struct { WebIRC []webircConfig `yaml:"webirc"` MaxSendQString string `yaml:"max-sendq"` MaxSendQBytes int - AllowPlaintextResume bool `yaml:"allow-plaintext-resume"` - ConnectionLimiter connection_limits.LimiterConfig `yaml:"connection-limits"` - ConnectionThrottler connection_limits.ThrottlerConfig `yaml:"connection-throttling"` + AllowPlaintextResume bool `yaml:"allow-plaintext-resume"` + Compatibility struct { + ForceTrailing *bool `yaml:"force-trailing"` + forceTrailing bool + SendUnprefixedSasl bool `yaml:"send-unprefixed-sasl"` + } + ConnectionLimiter connection_limits.LimiterConfig `yaml:"connection-limits"` + ConnectionThrottler connection_limits.ThrottlerConfig `yaml:"connection-throttling"` } Languages struct { @@ -698,6 +703,13 @@ func LoadConfig(filename string) (config *Config, err error) { config.Channels.Registration.MaxChannelsPerAccount = 15 } + forceTrailingPtr := config.Server.Compatibility.ForceTrailing + if forceTrailingPtr != nil { + config.Server.Compatibility.forceTrailing = *forceTrailingPtr + } else { + config.Server.Compatibility.forceTrailing = true + } + // in the current implementation, we disable history by creating a history buffer // with zero capacity. but the `enabled` config option MUST be respected regardless // of this detail diff --git a/irc/getters.go b/irc/getters.go index ac3e5124..7ee029ec 100644 --- a/irc/getters.go +++ b/irc/getters.go @@ -4,7 +4,9 @@ package irc import ( + "sync/atomic" "time" + "unsafe" "github.com/oragono/oragono/irc/isupport" "github.com/oragono/oragono/irc/languages" @@ -12,10 +14,11 @@ import ( ) func (server *Server) Config() (config *Config) { - server.configurableStateMutex.RLock() - config = server.config - server.configurableStateMutex.RUnlock() - return + return (*Config)(atomic.LoadPointer(&server.config)) +} + +func (server *Server) SetConfig(config *Config) { + atomic.StorePointer(&server.config, unsafe.Pointer(config)) } func (server *Server) ISupport() *isupport.List { @@ -53,9 +56,7 @@ func (server *Server) GetOperator(name string) (oper *Oper) { if err != nil { return } - server.configurableStateMutex.RLock() - defer server.configurableStateMutex.RUnlock() - return server.config.operators[name] + return server.Config().operators[name] } func (server *Server) Languages() (lm *languages.Manager) { diff --git a/irc/handlers.go b/irc/handlers.go index de67ccfd..d47d4569 100644 --- a/irc/handlers.go +++ b/irc/handlers.go @@ -298,7 +298,9 @@ func accVerifyHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb // AUTHENTICATE [||*] func authenticateHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool { + config := server.Config() details := client.Details() + if details.account != "" { rb.Add(nil, server.name, ERR_SASLALREADY, details.nick, client.t("You're already logged into an account")) return false @@ -321,7 +323,14 @@ func authenticateHandler(server *Server, client *Client, msg ircmsg.IrcMessage, if mechanismIsEnabled { client.saslInProgress = true client.saslMechanism = mechanism - rb.Add(nil, server.name, "AUTHENTICATE", "+") + if !config.Server.Compatibility.SendUnprefixedSasl { + // normal behavior + rb.Add(nil, server.name, "AUTHENTICATE", "+") + } else { + // gross hack: send a raw message to ensure no tags or prefix + rb.Flush(true) + rb.session.SendRawMessage(ircmsg.MakeMessage(nil, "", "AUTHENTICATE", "+"), true) + } } else { rb.Add(nil, server.name, ERR_SASLFAIL, details.nick, client.t("SASL authentication failed")) } diff --git a/irc/server.go b/irc/server.go index fc628098..c9a0b1ce 100644 --- a/irc/server.go +++ b/irc/server.go @@ -19,6 +19,7 @@ import ( "sync" "syscall" "time" + "unsafe" "github.com/goshuirc/irc-go/ircfmt" "github.com/oragono/oragono/irc/caps" @@ -65,7 +66,7 @@ type Server struct { channels ChannelManager channelRegistry ChannelRegistry clients ClientManager - config *Config + config unsafe.Pointer configFilename string configurableStateMutex sync.RWMutex // tier 1; generic protection for server state modified by rehash() connectionLimiter *connection_limits.Limiter @@ -602,7 +603,7 @@ func (server *Server) applyConfig(config *Config, initial bool) (err error) { return fmt.Errorf("Maximum line length (linelen) cannot be changed after launching the server, rehash aborted") } else if server.name != config.Server.Name { return fmt.Errorf("Server name cannot be changed after launching the server, rehash aborted") - } else if server.config.Datastore.Path != config.Datastore.Path { + } else if server.Config().Datastore.Path != config.Datastore.Path { return fmt.Errorf("Datastore path cannot be changed after launching the server, rehash aborted") } } @@ -776,9 +777,7 @@ func (server *Server) applyConfig(config *Config, initial bool) (err error) { server.loadMOTD(config.Server.MOTD, config.Server.MOTDFormatting) // save a pointer to the new config - server.configurableStateMutex.Lock() - server.config = config - server.configurableStateMutex.Unlock() + server.SetConfig(config) server.logger.Info("server", "Using datastore", config.Datastore.Path) if initial { diff --git a/oragono.yaml b/oragono.yaml index dd38c929..0e5e68e5 100644 --- a/oragono.yaml +++ b/oragono.yaml @@ -125,6 +125,21 @@ server: # this should be big enough to hold bursts of channel/direct messages max-sendq: 16k + # compatibility with legacy clients + compatibility: + # many clients require that the final parameter of certain messages be an + # RFC1459 trailing parameter, i.e., prefixed with :, whether or not this is + # actually required. this forces Oragono to send those parameters + # as trailings. this is recommended unless you're testing clients for conformance; + # defaults to true when unset for that reason. + force-trailing: true + + # some clients (ZNC 1.6.x and lower, Pidgin 2.12 and lower, Adium) do not + # respond correctly to SASL messages with the server name as a prefix: + # https://github.com/znc/znc/issues/1212 + # this works around that bug, allowing them to use SASL. + send-unprefixed-sasl: true + # maximum number of connections per subnet connection-limits: # whether to enforce connection limits or not From 61d666a25bf3ea99a408bc5b87e7d79100e465da Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Fri, 10 May 2019 00:07:22 -0400 Subject: [PATCH 2/4] load motd directly into the config object --- irc/config.go | 3 +++ irc/server.go | 26 +++++++------------------- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/irc/config.go b/irc/config.go index c79d43cd..71943a22 100644 --- a/irc/config.go +++ b/irc/config.go @@ -280,6 +280,7 @@ type Config struct { STS STSConfig CheckIdent bool `yaml:"check-ident"` MOTD string + motdLines []string MOTDFormatting bool `yaml:"motd-formatting"` ProxyAllowedFrom []string `yaml:"proxy-allowed-from"` proxyAllowedFromNets []net.IPNet @@ -710,6 +711,8 @@ func LoadConfig(filename string) (config *Config, err error) { config.Server.Compatibility.forceTrailing = true } + config.loadMOTD() + // in the current implementation, we disable history by creating a history buffer // with zero capacity. but the `enabled` config option MUST be respected regardless // of this detail diff --git a/irc/server.go b/irc/server.go index c9a0b1ce..29c03926 100644 --- a/irc/server.go +++ b/irc/server.go @@ -468,9 +468,7 @@ func (client *Client) t(originalString string) string { // MOTD serves the Message of the Day. func (server *Server) MOTD(client *Client, rb *ResponseBuffer) { - server.configurableStateMutex.RLock() - motdLines := server.motdLines - server.configurableStateMutex.RUnlock() + motdLines := server.Config().Server.motdLines if len(motdLines) < 1 { rb.Add(nil, server.name, ERR_NOMOTD, client.nick, client.t("MOTD File is missing")) @@ -774,8 +772,6 @@ func (server *Server) applyConfig(config *Config, initial bool) (err error) { } } - server.loadMOTD(config.Server.MOTD, config.Server.MOTDFormatting) - // save a pointer to the new config server.SetConfig(config) @@ -851,11 +847,9 @@ func (server *Server) setupPprofListener(config *Config) { } } -func (server *Server) loadMOTD(motdPath string, useFormatting bool) error { - server.logger.Info("server", "Using MOTD", motdPath) - motdLines := make([]string, 0) - if motdPath != "" { - file, err := os.Open(motdPath) +func (config *Config) loadMOTD() (err error) { + if config.Server.MOTD != "" { + file, err := os.Open(config.Server.MOTD) if err == nil { defer file.Close() @@ -867,7 +861,7 @@ func (server *Server) loadMOTD(motdPath string, useFormatting bool) error { } line = strings.TrimRight(line, "\r\n") - if useFormatting { + if config.Server.MOTDFormatting { line = ircfmt.Unescape(line) } @@ -875,17 +869,11 @@ func (server *Server) loadMOTD(motdPath string, useFormatting bool) error { // bursting it out to clients easier line = fmt.Sprintf("- %s", line) - motdLines = append(motdLines, line) + config.Server.motdLines = append(config.Server.motdLines, line) } - } else { - return err } } - - server.configurableStateMutex.Lock() - server.motdLines = motdLines - server.configurableStateMutex.Unlock() - return nil + return } func (server *Server) loadDatastore(config *Config) error { From ce6a3e42df6b9410fb45e70f3fc4f172c33b8295 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Fri, 10 May 2019 00:27:28 -0400 Subject: [PATCH 3/4] load isupport directly into the config object eliminates Server.configurableStateMutex --- irc/client.go | 3 +- irc/config.go | 7 ++++ irc/getters.go | 7 ---- irc/isupport/list.go | 6 +++- irc/server.go | 84 ++++++++++++++++++-------------------------- 5 files changed, 49 insertions(+), 58 deletions(-) diff --git a/irc/client.go b/irc/client.go index 4fb37046..5e1ac12e 100644 --- a/irc/client.go +++ b/irc/client.go @@ -836,7 +836,8 @@ func (client *Client) LoggedIntoAccount() bool { func (client *Client) RplISupport(rb *ResponseBuffer) { translatedISupport := client.t("are supported by this server") nick := client.Nick() - for _, cachedTokenLine := range client.server.ISupport().CachedReply { + config := client.server.Config() + for _, cachedTokenLine := range config.Server.isupport.CachedReply { length := len(cachedTokenLine) + 2 tokenline := make([]string, length) tokenline[0] = nick diff --git a/irc/config.go b/irc/config.go index 71943a22..437893b5 100644 --- a/irc/config.go +++ b/irc/config.go @@ -20,6 +20,7 @@ import ( "code.cloudfoundry.org/bytefmt" "github.com/oragono/oragono/irc/connection_limits" "github.com/oragono/oragono/irc/custime" + "github.com/oragono/oragono/irc/isupport" "github.com/oragono/oragono/irc/languages" "github.com/oragono/oragono/irc/logger" "github.com/oragono/oragono/irc/modes" @@ -293,6 +294,7 @@ type Config struct { forceTrailing bool SendUnprefixedSasl bool `yaml:"send-unprefixed-sasl"` } + isupport isupport.List ConnectionLimiter connection_limits.LimiterConfig `yaml:"connection-limits"` ConnectionThrottler connection_limits.ThrottlerConfig `yaml:"connection-throttling"` } @@ -713,6 +715,11 @@ func LoadConfig(filename string) (config *Config, err error) { config.loadMOTD() + err = config.generateISupport() + if err != nil { + return nil, err + } + // in the current implementation, we disable history by creating a history buffer // with zero capacity. but the `enabled` config option MUST be respected regardless // of this detail diff --git a/irc/getters.go b/irc/getters.go index 7ee029ec..089b4ebe 100644 --- a/irc/getters.go +++ b/irc/getters.go @@ -8,7 +8,6 @@ import ( "time" "unsafe" - "github.com/oragono/oragono/irc/isupport" "github.com/oragono/oragono/irc/languages" "github.com/oragono/oragono/irc/modes" ) @@ -21,12 +20,6 @@ func (server *Server) SetConfig(config *Config) { atomic.StorePointer(&server.config, unsafe.Pointer(config)) } -func (server *Server) ISupport() *isupport.List { - server.configurableStateMutex.RLock() - defer server.configurableStateMutex.RUnlock() - return server.isupport -} - func (server *Server) Limits() Limits { return server.Config().Limits } diff --git a/irc/isupport/list.go b/irc/isupport/list.go index cede85e3..61215e54 100644 --- a/irc/isupport/list.go +++ b/irc/isupport/list.go @@ -22,9 +22,13 @@ type List struct { // NewList returns a new List func NewList() *List { var il List + il.Initialize() + return &il +} + +func (il *List) Initialize() { il.Tokens = make(map[string]*string) il.CachedReply = make([][]string, 0) - return &il } // Add adds an RPL_ISUPPORT token to our internal list diff --git a/irc/server.go b/irc/server.go index 29c03926..d4200253 100644 --- a/irc/server.go +++ b/irc/server.go @@ -62,37 +62,36 @@ type ListenerWrapper struct { // Server is the main Oragono server. type Server struct { - accounts AccountManager - channels ChannelManager - channelRegistry ChannelRegistry - clients ClientManager - config unsafe.Pointer - configFilename string - configurableStateMutex sync.RWMutex // tier 1; generic protection for server state modified by rehash() - connectionLimiter *connection_limits.Limiter - connectionThrottler *connection_limits.Throttler - ctime time.Time - dlines *DLineManager - helpIndexManager HelpIndexManager - isupport *isupport.List - klines *KLineManager - listeners map[string]*ListenerWrapper - logger *logger.Manager - monitorManager *MonitorManager - motdLines []string - name string - nameCasefolded string - rehashMutex sync.Mutex // tier 4 - rehashSignal chan os.Signal - pprofServer *http.Server - resumeManager ResumeManager - signals chan os.Signal - snomasks *SnoManager - store *buntdb.DB - torLimiter connection_limits.TorLimiter - whoWas WhoWasList - stats Stats - semaphores ServerSemaphores + accounts AccountManager + channels ChannelManager + channelRegistry ChannelRegistry + clients ClientManager + config unsafe.Pointer + configFilename string + connectionLimiter *connection_limits.Limiter + connectionThrottler *connection_limits.Throttler + ctime time.Time + dlines *DLineManager + helpIndexManager HelpIndexManager + isupport *isupport.List + klines *KLineManager + listeners map[string]*ListenerWrapper + logger *logger.Manager + monitorManager *MonitorManager + motdLines []string + name string + nameCasefolded string + rehashMutex sync.Mutex // tier 4 + rehashSignal chan os.Signal + pprofServer *http.Server + resumeManager ResumeManager + signals chan os.Signal + snomasks *SnoManager + store *buntdb.DB + torLimiter connection_limits.TorLimiter + whoWas WhoWasList + stats Stats + semaphores ServerSemaphores } var ( @@ -141,13 +140,12 @@ func NewServer(config *Config, logger *logger.Manager) (*Server, error) { } // setISupport sets up our RPL_ISUPPORT reply. -func (server *Server) setISupport() (err error) { +func (config *Config) generateISupport() (err error) { maxTargetsString := strconv.Itoa(maxTargets) - config := server.Config() - // add RPL_ISUPPORT tokens - isupport := isupport.NewList() + isupport := &config.Server.isupport + isupport.Initialize() isupport.Add("AWAYLEN", strconv.Itoa(config.Limits.AwayLen)) isupport.Add("CASEMAPPING", "ascii") isupport.Add("CHANMODES", strings.Join([]string{modes.Modes{modes.BanMask, modes.ExceptMask, modes.InviteMask}.String(), "", modes.Modes{modes.UserLimit, modes.Key}.String(), modes.Modes{modes.InviteOnly, modes.Moderated, modes.NoOutside, modes.OpOnlyTopic, modes.ChanRoleplaying, modes.Secret}.String()}, ",")) @@ -175,13 +173,6 @@ func (server *Server) setISupport() (err error) { isupport.Add("UTF8MAPPING", casemappingName) err = isupport.RegenerateCachedReply() - if err != nil { - return - } - - server.configurableStateMutex.Lock() - server.isupport = isupport - server.configurableStateMutex.Unlock() return } @@ -786,13 +777,8 @@ func (server *Server) applyConfig(config *Config, initial bool) (err error) { // set RPL_ISUPPORT var newISupportReplies [][]string - oldISupportList := server.ISupport() - err = server.setISupport() - if err != nil { - return err - } - if oldISupportList != nil { - newISupportReplies = oldISupportList.GetDifference(server.ISupport()) + if oldConfig != nil { + newISupportReplies = oldConfig.Server.isupport.GetDifference(&config.Server.isupport) } // we are now open for business From c193def606459b58b5e9551dd3c915df0192bb5f Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Fri, 10 May 2019 01:44:14 -0400 Subject: [PATCH 4/4] fix some issues found with staticcheck.io --- irc/accounts.go | 4 +--- irc/channel.go | 28 ---------------------------- irc/client.go | 2 -- irc/config.go | 2 +- irc/handlers.go | 16 +++++----------- irc/modes/modes.go | 2 +- irc/semaphores.go | 1 - irc/server.go | 14 +------------- irc/snomanager.go | 6 +++--- 9 files changed, 12 insertions(+), 63 deletions(-) diff --git a/irc/accounts.go b/irc/accounts.go index b68b0f7f..85601d4a 100644 --- a/irc/accounts.go +++ b/irc/accounts.go @@ -5,7 +5,6 @@ package irc import ( "encoding/json" - "errors" "fmt" "net/smtp" "strconv" @@ -480,7 +479,7 @@ func (am *AccountManager) dispatchCallback(client *Client, casefoldedAccount str } else if callbackNamespace == "mailto" { return am.dispatchMailtoCallback(client, casefoldedAccount, callbackValue) } else { - return "", errors.New(fmt.Sprintf("Callback not implemented: %s", callbackNamespace)) + return "", fmt.Errorf("Callback not implemented: %s", callbackNamespace) } } @@ -1262,7 +1261,6 @@ func (am *AccountManager) Logout(client *Client) { } } am.accountToClients[casefoldedAccount] = remainingClients - return } var ( diff --git a/irc/channel.go b/irc/channel.go index 6bd15f4b..190060cc 100644 --- a/irc/channel.go +++ b/irc/channel.go @@ -1043,34 +1043,6 @@ func (channel *Channel) ShowMaskList(client *Client, mode modes.Mode, rb *Respon rb.Add(nil, client.server.name, rplendoflist, nick, channel.name, client.t("End of list")) } -func (channel *Channel) applyModeMask(client *Client, mode modes.Mode, op modes.ModeOp, mask string, rb *ResponseBuffer) bool { - list := channel.lists[mode] - if list == nil { - // This should never happen, but better safe than panicky. - return false - } - - if (op == modes.List) || (mask == "") { - channel.ShowMaskList(client, mode, rb) - return false - } - - if !channel.ClientIsAtLeast(client, modes.ChannelOperator) { - rb.Add(nil, client.server.name, ERR_CHANOPRIVSNEEDED, client.Nick(), channel.Name(), client.t("You're not a channel operator")) - return false - } - - if op == modes.Add { - return list.Add(mask) - } - - if op == modes.Remove { - return list.Remove(mask) - } - - return false -} - // Quit removes the given client from the channel func (channel *Channel) Quit(client *Client) { channelEmpty := func() bool { diff --git a/irc/client.go b/irc/client.go index 5e1ac12e..6544eef6 100644 --- a/irc/client.go +++ b/irc/client.go @@ -538,14 +538,12 @@ func (client *Client) tryResume() (success bool) { func (client *Client) tryResumeChannels() { details := client.resumeDetails - channels := make([]*Channel, len(details.Channels)) for _, name := range details.Channels { channel := client.server.channels.Get(name) if channel == nil { continue } channel.Resume(client, details.OldClient, details.Timestamp) - channels = append(channels, channel) } // replay direct PRIVSMG history diff --git a/irc/config.go b/irc/config.go index 437893b5..597b9309 100644 --- a/irc/config.go +++ b/irc/config.go @@ -393,7 +393,7 @@ func (conf *Config) OperatorClasses() (map[string]*OperClass, error) { // get inhereted info from other operclasses if len(info.Extends) > 0 { - einfo, _ := ocs[info.Extends] + einfo := ocs[info.Extends] for capab := range einfo.Capabilities { oc.Capabilities[capab] = true diff --git a/irc/handlers.go b/irc/handlers.go index d47d4569..ccb37094 100644 --- a/irc/handlers.go +++ b/irc/handlers.go @@ -1184,20 +1184,14 @@ func inviteHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Re func isonHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool { var nicks = msg.Params - var err error - var casefoldedNick string - ison := make([]string, 0) + ison := make([]string, 0, len(msg.Params)) for _, nick := range nicks { - casefoldedNick, err = CasefoldName(nick) - if err != nil { - continue - } - if iclient := server.clients.Get(casefoldedNick); iclient != nil { - ison = append(ison, iclient.nick) + if iclient := server.clients.Get(nick); iclient != nil { + ison = append(ison, iclient.Nick()) } } - rb.Add(nil, server.name, RPL_ISON, client.nick, strings.Join(nicks, " ")) + rb.Add(nil, server.name, RPL_ISON, client.nick, strings.Join(ison, " ")) return false } @@ -2099,7 +2093,7 @@ func npcaHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp // OPER func operHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool { - if client.HasMode(modes.Operator) == true { + if client.HasMode(modes.Operator) { rb.Add(nil, server.name, ERR_UNKNOWNERROR, client.Nick(), "OPER", client.t("You're already opered-up!")) return false } diff --git a/irc/modes/modes.go b/irc/modes/modes.go index 0aca61c6..05e93938 100644 --- a/irc/modes/modes.go +++ b/irc/modes/modes.go @@ -170,7 +170,7 @@ func SplitChannelMembershipPrefixes(target string) (prefixes string, name string prefixes = target[:i+1] name = target[i+1:] default: - break + return } } diff --git a/irc/semaphores.go b/irc/semaphores.go index d6008c58..1ee4df2c 100644 --- a/irc/semaphores.go +++ b/irc/semaphores.go @@ -36,5 +36,4 @@ func (serversem *ServerSemaphores) Initialize() { capacity = MaxServerSemaphoreCapacity } serversem.ClientDestroy.Initialize(capacity) - return } diff --git a/irc/server.go b/irc/server.go index d4200253..bd615bd5 100644 --- a/irc/server.go +++ b/irc/server.go @@ -24,7 +24,6 @@ import ( "github.com/goshuirc/irc-go/ircfmt" "github.com/oragono/oragono/irc/caps" "github.com/oragono/oragono/irc/connection_limits" - "github.com/oragono/oragono/irc/isupport" "github.com/oragono/oragono/irc/logger" "github.com/oragono/oragono/irc/modes" "github.com/oragono/oragono/irc/sno" @@ -73,12 +72,10 @@ type Server struct { ctime time.Time dlines *DLineManager helpIndexManager HelpIndexManager - isupport *isupport.List klines *KLineManager listeners map[string]*ListenerWrapper logger *logger.Manager monitorManager *MonitorManager - motdLines []string name string nameCasefolded string rehashMutex sync.Mutex // tier 4 @@ -176,13 +173,6 @@ func (config *Config) generateISupport() (err error) { return } -func loadChannelList(channel *Channel, list string, maskMode modes.Mode) { - if list == "" { - return - } - channel.lists[maskMode].AddAll(strings.Split(list, " ")) -} - // Shutdown shuts down the server. func (server *Server) Shutdown() { //TODO(dan): Make sure we disallow new nicks @@ -518,9 +508,7 @@ func (client *Client) getWhoisOf(target *Client, rb *ResponseBuffer) { tLanguages := target.Languages() if 0 < len(tLanguages) { params := []string{cnick, tnick} - for _, str := range client.server.Languages().Codes(tLanguages) { - params = append(params, str) - } + params = append(params, client.server.Languages().Codes(tLanguages)...) params = append(params, client.t("can speak these languages")) rb.Add(nil, client.server.name, RPL_WHOISLANGUAGE, params...) } diff --git a/irc/snomanager.go b/irc/snomanager.go index 38ab8d6c..d6f3b657 100644 --- a/irc/snomanager.go +++ b/irc/snomanager.go @@ -52,7 +52,7 @@ func (m *SnoManager) RemoveMasks(client *Client, masks ...sno.Mask) { for _, mask := range masks { currentClientList := m.sendLists[mask] - if currentClientList == nil || len(currentClientList) == 0 { + if len(currentClientList) == 0 { continue } @@ -70,7 +70,7 @@ func (m *SnoManager) RemoveClient(client *Client) { for mask := range m.sendLists { currentClientList := m.sendLists[mask] - if currentClientList == nil || len(currentClientList) == 0 { + if len(currentClientList) == 0 { continue } @@ -87,7 +87,7 @@ func (m *SnoManager) Send(mask sno.Mask, content string) { currentClientList := m.sendLists[mask] - if currentClientList == nil || len(currentClientList) == 0 { + if len(currentClientList) == 0 { return }