X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=daemon.go;h=ed708de9875a7b054f27e5a27bfad6e122ad90d3;hb=8702ace766119effc2c2ec4afa284bec6f24c4da;hp=1bb39598d3c9181678fda83a01803c7f18f6ce6f;hpb=cfeaaad88f71bf1b0846251b7f448bf41bde26d9;p=goircd.git diff --git a/daemon.go b/daemon.go index 1bb3959..ed708de 100644 --- a/daemon.go +++ b/daemon.go @@ -40,8 +40,10 @@ var ( 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 @@ -51,8 +53,8 @@ type Daemon struct { stateSink chan<- StateEvent } -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) @@ -73,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)) } @@ -108,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 { @@ -154,6 +159,12 @@ func (daemon *Daemon) SendList(client *Client, cols []string) { // When client finishes NICK/USER workflow, then MOTD and LUSERS are send to him. func (daemon *Daemon) ClientRegister(client *Client, command string, cols []string) { switch command { + case "PASS": + if len(cols) == 1 || len(cols[1]) < 1 { + client.ReplyNotEnoughParameters("PASS") + return + } + client.password = cols[1] case "NICK": if len(cols) == 1 || len(cols[1]) < 1 { client.ReplyParts("431", "No nickname given") @@ -185,13 +196,37 @@ func (daemon *Daemon) ClientRegister(client *Client, command string, cols []stri client.realname = strings.TrimLeft(args[3], ":") } if client.nickname != "*" && client.username != "" { + 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 + } + } + } + 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") } } @@ -247,6 +282,7 @@ func (daemon *Daemon) HandlerJoin(client *Client, cmd string) { continue } roomNew, roomSink := daemon.RoomRegister(room) + log.Println("Room", roomNew, "created") if key != "" { roomNew.key = key roomNew.StateSave() @@ -274,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") @@ -302,6 +338,7 @@ func (daemon *Daemon) Processor(events <-chan ClientEvent) { log.Println(client, "command", command) } if command == "QUIT" { + log.Println(client, "quit") delete(daemon.clients, client) delete(daemon.clientAliveness, client) client.conn.Close() @@ -313,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") @@ -323,7 +367,7 @@ func (daemon *Daemon) Processor(events <-chan ClientEvent) { case "LIST": daemon.SendList(client, cols) case "LUSERS": - go daemon.SendLusers(client) + daemon.SendLusers(client) case "MODE": if len(cols) == 1 || len(cols[1]) < 1 { client.ReplyNotEnoughParameters("MODE") @@ -369,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": @@ -388,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 } } @@ -436,7 +483,15 @@ func (daemon *Daemon) Processor(events <-chan ClientEvent) { } cols := strings.Split(cols[1], " ") nicknames := strings.Split(cols[len(cols)-1], ",") - go daemon.SendWhois(client, nicknames) + 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") }