Example #1
0
// Input goroutine function for a client.
// Own readings on the socket.
func input(c *Client) {

	// Stop panics here, so they only disconnect the client they affect.
	//defer func() {
	//	recover()
	//}()

	// Delete the client when this returns.
	errMsg := "Input Error"
	defer func() {
		c.mutex.Lock()
		c.disconnecting |= 4 // Marks input as done.
		c.delete(errMsg)
		c.mutex.Unlock()
	}()

	irc.ReadLine(c.conn, make([]byte, 2096), func(line []byte) {
		// Parse the line, ignoring any specified origin.
		_, command, params, perr := irc.Parse(Commands, line,
			c.u.Registered())

		// If we successfully got a command, run it.
		if command != nil {

			// If it's an oper command, check permissions.
			if command.OperFlag != "" && !perm.HasOperCommand(c.u, command.OperFlag, command.Name) {
				c.SendLineTo(nil, "481", ":You do not have the appropriate privileges to use this command.")
				return
			}
			command.Handler(c, params)
		} else if perr != nil {

			// The IRC protocol is stupid.
			switch perr.Num {
			case irc.CmdNotFound:
				if c.u.Registered() {
					c.SendLineTo(nil, "421", "%s :%s",
						perr.CmdName, perr)
				}
			case irc.CmdForRegistered:
				c.SendFrom(nil, "451 %s :%s", perr.CmdName, perr)
			case irc.CmdForUnregistered:
				c.SendFrom(nil, "462 %s :%s", c.u.Nick(), perr)
			default:
				c.SendFrom(nil, "461 %s %s :%s", c.u.Nick(),
					perr.CmdName, perr)
			}
		}
	})
}
Example #2
0
// Handle a single (potential) server link.
// outgoing indicates whether it is outgoing or incoming.
func link(c *net.TCPConn, outgoing bool) {
	errMsg := "Input Error"

	serverMutex.Lock()

	// Create a new server, and add it to the server list.
	l := new(local)
	l.local = l
	l.next = servers
	if servers != nil {
		servers.prev = &(l.server)
	}
	servers = &(l.server)
	l.c = c

	serverMutex.Unlock()

	// Defer deletion of the server. If it's already deleted, no harm done.
	defer func() {
		l.Delete(errMsg)
	}()

	if outgoing {
		link_auth(l)
	}

	errMsg = irc.ReadLine(l.c, make([]byte, 20960), func(line []byte) {

		// Parse the line.
		prefix, command, params, perr := irc.Parse(commands, line, l.authed)

		// Look up the server or user this command is from.
		var source interface{}
		if len(prefix) == 9 {
			u := core.GetUser(string(prefix))
			if u == nil {
				source = nil
			} else if u.Owner() != me {
				source = nil
			} else {
				userver := u.Owndata().(*server)
				if userver.local == l {
					source = u
				}
			}
		} else if len(prefix) == 3 {
			v := core.GetSID(string(prefix))
			if v == nil {
				source = nil
			} else if s, ok := v.(*server); ok {
				if s.local == l {
					source = s
				}
			}
		} else if len(prefix) == 0 {
			// No prefix; it's from this server.
			source = &(l.server)
		} else {
			// Prefix is gibberish.
			source = nil
		}

		// If we successfully got a command and source, run it.
		if source != nil && command != nil {
			command.Handler(source, params)
		} else if perr != nil {

			// The IRC protocol is stupid.
			switch perr.Num {
			case irc.CmdNotFound:
				irc.SendLine(l, from(nil), l.sid, "421", "%s :%s",
					perr.CmdName, perr)
			case irc.CmdForRegistered:
				irc.SendFrom(l, from(nil), "451 %s :%s", perr.CmdName,
					perr)
			case irc.CmdForUnregistered:
				irc.SendFrom(l, from(nil), "462 %s :%s", l.sid, perr)
			default:
				irc.SendFrom(l, from(nil), "461 %s %s :%s", l.sid,
					perr.CmdName, perr)
			}
		}
	})
}