Ejemplo n.º 1
0
// accept handles the initial negotiation phase for connecting to the
// server. This is basically in 4 parts:
//
// * PASS
// * NICK
// * USER
//
// On success a RPL_WELCOME response is returned to the new client.
func (s *Server) accept(conn net.Conn) bool {
	r := bufio.NewReader(conn)

	line, err := r.ReadBytes('\n')
	if err != nil {
		log.Println(err)
		return false
	}

	parsed := message.Parse(string(line))

	if parsed.Command != "PASS" {
		return false
	}

	if !parsed.Params.Any() {
		conn.Write([]byte(errors.NeedMoreParams(s.Name(), "PASS").String()))
		return false
	}

	password := parsed.Params.Get(0)
	if password != "test" {
		return false
	}

	client := NewClient("", conn, s)
	s.clients.Add(client)

	return true
}
Ejemplo n.º 2
0
func Whois(c Client, s Server, args []string) {
	if len(args) < 1 {
		c.Send(errors.NeedMoreParams(s.Name(), "WHOIS"))
		return
	}

	subject, ok := s.Find(args[0])
	user, isClient := subject.(Client)

	if !ok || !isClient {
		c.Send(errors.NoSuchNick(s.Name(), args[0]))
		c.Send(reply.EndOfWhois(s.Name(), args[0]))
		return
	}

	if user.AwayMessage() != "" {
		c.Send(reply.Away(s.Name(), user.Name(), user.AwayMessage()))
	}

	c.Send(reply.WhoIsUser(s.Name(), user.Name(), user.UserName(), user.RealName()))
	c.Send(reply.WhoIsServer(s.Name(), user.Name()))

	if user.Channels().Any() {
		resp := reply.WhoIsChannels(s.Name(), user.Name(), user.Channels().Names())
		for _, part := range resp.Parts() {
			c.Send(part)
		}
	}

	c.Send(reply.WhoIsIdle(s.Name(), user.Name(), 0))
	c.Send(reply.EndOfWhois(s.Name(), args[0]))
}
Ejemplo n.º 3
0
func Invite(c Client, s Server, args []string) {
	if len(args) < 2 {
		c.Send(errors.NeedMoreParams(s.Name(), "INVITE"))
		return
	}

	subject, ok := s.Find(args[0])
	user, isClient := subject.(Client)

	if !ok || !isClient {
		c.Send(errors.NoSuchNick(s.Name(), args[0]))
		return
	}

	if _, ok := c.Channels().Find(args[1]); !ok {
		c.Send(errors.NotOnChannel(s.Name(), args[1]))
		return
	}

	if _, ok := user.Channels().Find(args[1]); ok {
		c.Send(errors.UserOnChannel(s.Name(), user.Name(), args[1]))
		return
	}

	subject.Send(reply.Invite(c.Name(), c.UserName(), s.Name(), subject.Name(), args[1]))
}
Ejemplo n.º 4
0
func Notice(c Client, s Server, args []string) {
	if len(args) < 2 {
		c.Send(errors.NeedMoreParams(s.Name(), "NOTICE"))
		return
	}

	subject, ok := s.Find(args[0])
	if ok {
		msg := reply.Notice(c.Name(), c.UserName(), s.Name(), args[0], args[1])
		subject.SendExcept(msg, c.Name())
	}
}
Ejemplo n.º 5
0
func Join(c Client, s Server, args []string) {
	if len(args) < 1 {
		c.Send(errors.NeedMoreParams(s.Name(), "JOIN"))
		return
	}

	names := strings.Split(args[0], ",")

	for _, name := range names {
		channel := s.Join(c, name)
		channel.Send(reply.Join(c.Name(), c.UserName(), s.Name(), channel.Name()))
		c.Channels().Add(channel)
		Topic(c, s, []string{name})
	}
}
Ejemplo n.º 6
0
func Part(c Client, s Server, args []string) {
	if len(args) < 1 {
		c.Send(errors.NeedMoreParams(s.Name(), "PART"))
		return
	}

	channel, ok := c.Channels().Find(args[0])

	if !ok {
		c.Send(errors.NotOnChannel(s.Name(), args[0]))
		return
	}

	channel.Send(reply.Part(c.Name(), c.UserName(), s.Name(), channel.Name()))
	s.Part(c, args[0])
}
Ejemplo n.º 7
0
func PrivMsg(c Client, s Server, args []string) {
	if len(args) < 2 {
		c.Send(errors.NeedMoreParams(s.Name(), "PRIVMSG"))
		return
	}

	subject, ok := s.Find(args[0])
	if ok {
		msg := reply.PrivMsg(c.Name(), c.UserName(), s.Name(), args[0], args[1])
		subject.SendExcept(msg, c.Name())

		if other, ok := subject.(Client); ok && other.AwayMessage() != "" {
			c.Send(reply.Away(s.Name(), subject.Name(), other.AwayMessage()))
		}
	}
}
Ejemplo n.º 8
0
func Names(c Client, s Server, args []string) {
	if len(args) < 1 {
		c.Send(errors.NeedMoreParams(s.Name(), "NAMES"))
		return
	}

	channel := s.FindChannel(args[0])

	resp := reply.NameReply(s.Name(), c.Name(), channel.Name(), channel.Names())

	for _, part := range resp.Parts() {
		c.Send(part)
	}

	c.Send(reply.EndOfNames(s.Name(), c.Name(), channel.Name()))
}
Ejemplo n.º 9
0
func User(c Client, s Server, args []string) {
	if len(args) < 4 {
		c.Send(errors.NeedMoreParams(s.Name(), "USER"))
		return
	}

	if c.RealName() != "" {
		c.Send(errors.AlreadyRegistered(s.Name()))
		return
	}

	// <user> <mode> <unused> <realname>
	c.SetUserName(args[0])
	c.SetMode(args[1])
	c.SetRealName(args[3])
	c.Send(reply.Welcome(s.Name(), c.Name()))
}
Ejemplo n.º 10
0
func Topic(c Client, s Server, args []string) {
	switch len(args) {
	case 1:
		channel := s.FindChannel(args[0])
		if channel.Topic == "" {
			c.Send(reply.NoTopic(s.Name(), channel.Name()))
		} else {
			c.Send(reply.Topic(s.Name(), channel.Name(), channel.Topic))
		}

	case 2:
		channel := s.FindChannel(args[0])
		channel.Topic = args[1]
		channel.Send(reply.TopicChange(c.Name(), c.UserName(), s.Name(), channel.Name(), channel.Topic))

	default:
		c.Send(errors.NeedMoreParams(s.Name(), "TOPIC"))
	}
}
Ejemplo n.º 11
0
func Mode(c Client, s Server, args []string) {
	if len(args) < 1 {
		c.Send(errors.NeedMoreParams(s.Name(), "MODE"))
		return
	}

	subject, ok := s.Find(args[0])

	if !ok {
		return
	}

	if _, ok := subject.(Client); ok {
		c.Send(reply.UserModeIs(s.Name(), c.Name()))
	} else {
		if len(args) == 2 && strings.Contains(args[1], "b") {
			c.Send(reply.EndOfBanList(s.Name(), c.Name(), subject.Name()))
		} else {
			c.Send(reply.ChannelModeIs(s.Name(), c.Name(), subject.Name()))
		}
	}
}
Ejemplo n.º 12
0
func Who(c Client, s Server, args []string) {
	if len(args) < 1 {
		c.Send(errors.NeedMoreParams(s.Name(), "WHO"))
		return
	}

	subject, ok := s.Find(args[0])

	if ok {
		if user, ok := subject.(Client); ok {
			c.Send(reply.WhoReply(s.Name(), c.Name(), args[0], user.UserName(), user.Name(), user.RealName()))
		} else {
			channel, _ := subject.(*channel.Channel)
			for _, client := range channel.Clients() {
				user, _ := client.(Client)
				c.Send(reply.WhoReply(s.Name(), c.Name(), args[0], user.UserName(), user.Name(), user.RealName()))
			}
		}
	}

	c.Send(reply.EndOfWho(s.Name(), c.Name(), args[0]))
}