X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=daemon.go;h=ed708de9875a7b054f27e5a27bfad6e122ad90d3;hb=8702ace766119effc2c2ec4afa284bec6f24c4da;hp=ffd2ef1ffb06c059c4e52e9f76c753a500bbda09;hpb=a939b027fdb6ce1d0822e76ec50814678ff0050a;p=goircd.git diff --git a/daemon.go b/daemon.go index ffd2ef1..ed708de 100644 --- a/daemon.go +++ b/daemon.go @@ -25,7 +25,6 @@ import ( "regexp" "sort" "strings" - "sync" "time" ) @@ -39,12 +38,12 @@ var ( RENickname = regexp.MustCompile("^[a-zA-Z0-9-]{1,9}$") ) -var passwordsRefreshLock sync.Mutex - type Daemon struct { Verbose bool - hostname string - motd string + version string + hostname *string + motd *string + passwords *string clients map[*Client]bool clientAliveness map[*Client]*ClientAlivenessState rooms map[string]*Room @@ -52,11 +51,10 @@ type Daemon struct { lastAlivenessCheck time.Time logSink chan<- LogEvent stateSink chan<- StateEvent - passwords map[string]string } -func NewDaemon(hostname, motd string, logSink chan<- LogEvent, stateSink chan<- StateEvent) *Daemon { - daemon := Daemon{hostname: hostname, motd: motd} +func NewDaemon(version string, hostname, motd, passwords *string, logSink chan<- LogEvent, stateSink chan<- StateEvent) *Daemon { + daemon := Daemon{version: version, hostname: hostname, motd: motd, passwords: passwords} daemon.clients = make(map[*Client]bool) daemon.clientAliveness = make(map[*Client]*ClientAlivenessState) daemon.rooms = make(map[string]*Room) @@ -77,19 +75,19 @@ func (daemon *Daemon) SendLusers(client *Client) { } func (daemon *Daemon) SendMotd(client *Client) { - if len(daemon.motd) == 0 { + if daemon.motd == nil || *daemon.motd == "" { client.ReplyNicknamed("422", "MOTD File is missing") return } - motd, err := ioutil.ReadFile(daemon.motd) + motd, err := ioutil.ReadFile(*daemon.motd) if err != nil { - log.Printf("Can not read motd file %s: %v", daemon.motd, err) + log.Printf("Can not read motd file %s: %v", *daemon.motd, err) client.ReplyNicknamed("422", "Error reading MOTD File") return } - client.ReplyNicknamed("375", "- "+daemon.hostname+" Message of the day -") + client.ReplyNicknamed("375", "- "+*daemon.hostname+" Message of the day -") for _, s := range strings.Split(strings.Trim(string(motd), "\n"), "\n") { client.ReplyNicknamed("372", "- "+string(s)) } @@ -112,7 +110,10 @@ func (daemon *Daemon) SendWhois(client *Client, nicknames []string) { h = "Unknown" } client.ReplyNicknamed("311", c.nickname, c.username, h, "*", c.realname) - client.ReplyNicknamed("312", c.nickname, daemon.hostname, daemon.hostname) + client.ReplyNicknamed("312", c.nickname, *daemon.hostname, *daemon.hostname) + if c.away != nil { + client.ReplyNicknamed("301", c.nickname, *c.away) + } subscriptions := []string{} for _, room := range daemon.rooms { for subscriber := range room.members { @@ -195,19 +196,34 @@ func (daemon *Daemon) ClientRegister(client *Client, command string, cols []stri client.realname = strings.TrimLeft(args[3], ":") } if client.nickname != "*" && client.username != "" { - passwordsRefreshLock.Lock() - if daemon.passwords != nil && (client.password == "" || daemon.passwords[client.nickname] != client.password) { - passwordsRefreshLock.Unlock() - client.ReplyParts("462", "You may not register") - client.conn.Close() - return + if daemon.passwords != nil && *daemon.passwords != "" { + if client.password == "" { + client.ReplyParts("462", "You may not register") + client.conn.Close() + return + } + contents, err := ioutil.ReadFile(*daemon.passwords) + if err != nil { + log.Fatalf("Can no read passwords file %s: %s", *daemon.passwords, err) + return + } + for _, entry := range strings.Split(string(contents), "\n") { + if entry == "" { + continue + } + if lp := strings.Split(entry, ":"); lp[0] == client.nickname && lp[1] != client.password { + client.ReplyParts("462", "You may not register") + client.conn.Close() + return + } + } } - passwordsRefreshLock.Unlock() + client.registered = true client.ReplyNicknamed("001", "Hi, welcome to IRC") - client.ReplyNicknamed("002", "Your host is "+daemon.hostname+", running goircd") + client.ReplyNicknamed("002", "Your host is "+*daemon.hostname+", running goircd "+daemon.version) client.ReplyNicknamed("003", "This server was created sometime") - client.ReplyNicknamed("004", daemon.hostname+" goircd o o") + client.ReplyNicknamed("004", *daemon.hostname+" goircd o o") daemon.SendLusers(client) daemon.SendMotd(client) log.Println(client, "logged in") @@ -294,7 +310,7 @@ func (daemon *Daemon) Processor(events <-chan ClientEvent) { } if !aliveness.pingSent && aliveness.timestamp.Add(PingThreshold).Before(now) { if c.registered { - c.Msg("PING :" + daemon.hostname) + c.Msg("PING :" + *daemon.hostname) aliveness.pingSent = true } else { log.Println(c, "ping timeout") @@ -334,7 +350,14 @@ func (daemon *Daemon) Processor(events <-chan ClientEvent) { } switch command { case "AWAY": - continue + if len(cols) == 1 { + client.away = nil + client.ReplyNicknamed("305", "You are no longer marked as being away") + continue + } + msg := strings.TrimLeft(cols[1], ":") + client.away = &msg + client.ReplyNicknamed("306", "You have been marked as being away") case "JOIN": if len(cols) == 1 || len(cols[1]) < 1 { client.ReplyNotEnoughParameters("JOIN") @@ -390,7 +413,7 @@ func (daemon *Daemon) Processor(events <-chan ClientEvent) { client.ReplyNicknamed("409", "No origin specified") continue } - client.Reply(fmt.Sprintf("PONG %s :%s", daemon.hostname, cols[1])) + client.Reply(fmt.Sprintf("PONG %s :%s", *daemon.hostname, cols[1])) case "PONG": continue case "NOTICE", "PRIVMSG": @@ -409,6 +432,9 @@ func (daemon *Daemon) Processor(events <-chan ClientEvent) { if c.nickname == target { msg = fmt.Sprintf(":%s %s %s %s", client, command, c.nickname, cols[1]) c.Msg(msg) + if c.away != nil { + client.ReplyNicknamed("301", c.nickname, *c.away) + } break } } @@ -458,6 +484,14 @@ func (daemon *Daemon) Processor(events <-chan ClientEvent) { cols := strings.Split(cols[1], " ") nicknames := strings.Split(cols[len(cols)-1], ",") daemon.SendWhois(client, nicknames) + case "VERSION": + var debug string + if daemon.Verbose { + debug = "debug" + } else { + debug = "" + } + client.ReplyNicknamed("351", fmt.Sprintf("%s.%s %s :", daemon.version, debug, *daemon.hostname)) default: client.ReplyNicknamed("421", command, "Unknown command") } @@ -468,22 +502,3 @@ func (daemon *Daemon) Processor(events <-chan ClientEvent) { } } } - -func (daemon *Daemon) PasswordsRefresh() { - contents, err := ioutil.ReadFile(*passwords) - if err != nil { - log.Fatalf("Can no read passwords file %s: %s", *passwords, err) - return - } - processed := make(map[string]string) - for _, entry := range strings.Split(string(contents), "\n") { - loginAndPassword := strings.Split(entry, ":") - if len(loginAndPassword) == 2 { - processed[loginAndPassword[0]] = loginAndPassword[1] - } - } - log.Printf("Read %d passwords", len(processed)) - passwordsRefreshLock.Lock() - daemon.passwords = processed - passwordsRefreshLock.Unlock() -}