Browse Source

Stuff is no longer completely broken. Just mostly.

tags/v0.1.0
Daniel Oaks 8 years ago
parent
commit
04442ddef1
9 changed files with 125 additions and 69 deletions
  1. 1
    0
      CHANGELOG.md
  2. 2
    2
      irc/capability.go
  3. 4
    4
      irc/client.go
  4. 1
    0
      irc/commandhandlers.go
  5. 3
    4
      irc/commands.go
  6. 2
    1
      irc/isupport.go
  7. 79
    33
      irc/modes.go
  8. 1
    0
      irc/numerics.go
  9. 32
    25
      irc/server.go

+ 1
- 0
CHANGELOG.md View File

25
 * Default channel modes are now (`+nt`), matching most other IRCds.
25
 * Default channel modes are now (`+nt`), matching most other IRCds.
26
 * CLI argument names made more consistent with typical software.
26
 * CLI argument names made more consistent with typical software.
27
 * ONICK: Renamed to SANICK to be more consistent with other IRCds.
27
 * ONICK: Renamed to SANICK to be more consistent with other IRCds.
28
+* USER: Prepend usernames set by the USER command with `"~"`.
28
 
29
 
29
 ### Removed
30
 ### Removed
30
 * Gitconfig config format completely removed and replaced with YAML.
31
 * Gitconfig config format completely removed and replaced with YAML.

+ 2
- 2
irc/capability.go View File

105
 		// make sure all capabilities actually exist
105
 		// make sure all capabilities actually exist
106
 		for capability := range capabilities {
106
 		for capability := range capabilities {
107
 			if !SupportedCapabilities[capability] {
107
 			if !SupportedCapabilities[capability] {
108
-				client.Send(nil, server.nameString, "CAP", client.nickString, subCommand, capString)
108
+				client.Send(nil, server.nameString, "CAP", client.nickString, "NAK", capString)
109
 				return false
109
 				return false
110
 			}
110
 			}
111
 		}
111
 		}
112
 		for capability := range capabilities {
112
 		for capability := range capabilities {
113
 			client.capabilities[capability] = true
113
 			client.capabilities[capability] = true
114
 		}
114
 		}
115
-		client.Send(nil, server.nameString, "CAP", client.nickString, subCommand, capString)
115
+		client.Send(nil, server.nameString, "CAP", client.nickString, "ACK", capString)
116
 
116
 
117
 	case "END":
117
 	case "END":
118
 		if !client.registered {
118
 		if !client.registered {

+ 4
- 4
irc/client.go View File

56
 		flags:        make(map[UserMode]bool),
56
 		flags:        make(map[UserMode]bool),
57
 		server:       server,
57
 		server:       server,
58
 		socket:       &socket,
58
 		socket:       &socket,
59
+		nickString:   "*", // * is used until actual nick is given
59
 	}
60
 	}
60
 	client.Touch()
61
 	client.Touch()
61
 	go client.run()
62
 	go client.run()
68
 //
69
 //
69
 
70
 
70
 func (client *Client) run() {
71
 func (client *Client) run() {
71
-	var command Command
72
 	var err error
72
 	var err error
73
 	var isExiting bool
73
 	var isExiting bool
74
 	var line string
74
 	var line string
88
 
88
 
89
 		msg, err = ircmsg.ParseLine(line)
89
 		msg, err = ircmsg.ParseLine(line)
90
 		if err != nil {
90
 		if err != nil {
91
-			client.Quit("received malformed command")
91
+			client.Quit("received malformed line")
92
 			break
92
 			break
93
 		}
93
 		}
94
 
94
 
95
 		cmd, exists := Commands[msg.Command]
95
 		cmd, exists := Commands[msg.Command]
96
 		if !exists {
96
 		if !exists {
97
-			//TODO(dan): Reply with 400 or whatever unknown cmd is
98
-			client.Quit("Received unknown command")
97
+			client.Send(nil, client.server.nameString, ERR_UNKNOWNCOMMAND, client.nickString, msg.Command, "Unknown command")
98
+			continue
99
 		}
99
 		}
100
 
100
 
101
 		isExiting = cmd.Run(client.server, client, msg)
101
 		isExiting = cmd.Run(client.server, client, msg)

+ 1
- 0
irc/commandhandlers.go View File

127
 	changes ChannelModeChanges
127
 	changes ChannelModeChanges
128
 }
128
 }
129
 
129
 
130
+/*
130
 // MODE <channel> ( "+" / "-" )? *( "+" / "-" / <mode character> ) *<modeparams>
131
 // MODE <channel> ( "+" / "-" )? *( "+" / "-" / <mode character> ) *<modeparams>
131
 func ParseChannelModeCommand(channel Name, args []string) (Command, error) {
132
 func ParseChannelModeCommand(channel Name, args []string) (Command, error) {
132
 	cmd := &ChannelModeCommand{
133
 	cmd := &ChannelModeCommand{

+ 3
- 4
irc/commands.go View File

23
 		// command silently ignored
23
 		// command silently ignored
24
 		return false
24
 		return false
25
 	}
25
 	}
26
-	if (!cmd.oper) && (!client.flags[Operator]) {
26
+	if cmd.oper && !client.flags[Operator] {
27
 		client.Send(nil, server.nameString, ERR_NOPRIVILEGES, client.nickString, "Permission Denied - You're not an IRC operator")
27
 		client.Send(nil, server.nameString, ERR_NOPRIVILEGES, client.nickString, "Permission Denied - You're not an IRC operator")
28
 		return false
28
 		return false
29
 	}
29
 	}
87
 		handler:   listHandler,
87
 		handler:   listHandler,
88
 		minParams: 0,
88
 		minParams: 0,
89
 	},
89
 	},
90
-	/*TODO(dan): ADD THIS BACK.
91
 	"MODE": Command{
90
 	"MODE": Command{
92
 		handler:   modeHandler,
91
 		handler:   modeHandler,
93
 		minParams: 1,
92
 		minParams: 1,
94
-	},*/
93
+	},
95
 	"MOTD": Command{
94
 	"MOTD": Command{
96
 		handler:   motdHandler,
95
 		handler:   motdHandler,
97
 		minParams: 0,
96
 		minParams: 0,
153
 		usablePreReg: true,
152
 		usablePreReg: true,
154
 		minParams:    0,
153
 		minParams:    0,
155
 	},
154
 	},
156
-	/*TODO(dan): ADD THIS BACK IN
155
+	/*TODO(dan): Add this back in
157
 	"THEATRE": Command{
156
 	"THEATRE": Command{
158
 		handler:   theatreHandler,
157
 		handler:   theatreHandler,
159
 		minParams: 1,
158
 		minParams: 1,

+ 2
- 1
irc/isupport.go View File

69
 
69
 
70
 func (client *Client) RplISupport() {
70
 func (client *Client) RplISupport() {
71
 	for _, tokenline := range client.server.isupport.CachedReply {
71
 	for _, tokenline := range client.server.isupport.CachedReply {
72
-		client.Send(nil, client.server.nameString, RPL_ISUPPORT, tokenline...)
72
+		// ugly trickery ahead
73
+		client.Send(nil, client.server.nameString, RPL_ISUPPORT, append([]string{client.nickString}, tokenline...)...)
73
 	}
74
 	}
74
 }
75
 }

+ 79
- 33
irc/modes.go View File

7
 
7
 
8
 import (
8
 import (
9
 	"strings"
9
 	"strings"
10
+
11
+	"github.com/DanielOaks/girc-go/ircmsg"
10
 )
12
 )
11
 
13
 
12
 // user mode flags
14
 // user mode flags
126
 // commands
128
 // commands
127
 //
129
 //
128
 
130
 
129
-/*
130
-func (m *ModeCommand) HandleServer(s *Server) {
131
-	client := m.Client()
132
-	target := s.clients.Get(m.nickname)
131
+// MODE <target> [<modestring> [<mode arguments>...]]
132
+func modeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
133
+	name := NewName(msg.Params[0])
134
+	if name.IsChannel() {
135
+		// return cmodeHandler(server, client, msg)
136
+		client.Notice("CMODEs are not yet supported!")
137
+		return false
138
+	} else {
139
+		return umodeHandler(server, client, msg)
140
+	}
141
+}
142
+
143
+// MODE <target> [<modestring> [<mode arguments>...]]
144
+func umodeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
145
+	nickname := NewName(msg.Params[0])
146
+
147
+	target := server.clients.Get(nickname)
133
 
148
 
134
 	if target == nil {
149
 	if target == nil {
135
-		client.ErrNoSuchNick(m.nickname)
136
-		return
150
+		client.Send(nil, server.nameString, ERR_NOSUCHNICK, client.nickString, msg.Params[0], "No such nick")
151
+		return false
137
 	}
152
 	}
138
 
153
 
154
+	//TODO(dan): restricting to Operator here should be done with SAMODE only
155
+	// point SAMODE at this handler too, if they are operator and SAMODE was called then fine
139
 	if client != target && !client.flags[Operator] {
156
 	if client != target && !client.flags[Operator] {
140
-		client.ErrUsersDontMatch()
141
-		return
157
+		if len(msg.Params) > 1 {
158
+			client.Send(nil, server.nameString, ERR_USERSDONTMATCH, client.nickString, "Can't change modes for other users")
159
+		} else {
160
+			client.Send(nil, server.nameString, ERR_USERSDONTMATCH, client.nickString, "Can't view modes for other users")
161
+		}
162
+		return false
142
 	}
163
 	}
143
 
164
 
144
-	changes := make(ModeChanges, 0, len(m.changes))
165
+	// assemble changes
166
+	changes := make(ModeChanges, 0)
167
+
168
+	if len(msg.Params) > 1 {
169
+		modeArg := msg.Params[0]
170
+		op := ModeOp(modeArg[0])
171
+		if (op == Add) || (op == Remove) {
172
+			modeArg = modeArg[1:]
173
+		} else {
174
+			client.Send(nil, server.nameString, ERR_UNKNOWNERROR, client.nickString, "MODE", "Mode string could not be parsed correctly")
175
+			return false
176
+		}
145
 
177
 
146
-	for _, change := range m.changes {
147
-		switch change.mode {
148
-		case Invisible, ServerNotice, WallOps:
149
-			switch change.op {
150
-			case Add:
151
-				if target.flags[change.mode] {
152
-					continue
153
-				}
154
-				target.flags[change.mode] = true
155
-				changes = append(changes, change)
178
+		for _, mode := range modeArg {
179
+			if mode == '-' || mode == '+' {
180
+				op = ModeOp(mode)
181
+				continue
182
+			}
183
+			changes = append(changes, &ModeChange{
184
+				mode: UserMode(mode),
185
+				op:   op,
186
+			})
187
+		}
156
 
188
 
157
-			case Remove:
158
-				if !target.flags[change.mode] {
159
-					continue
189
+		for _, change := range changes {
190
+			switch change.mode {
191
+			case Invisible, ServerNotice, WallOps:
192
+				switch change.op {
193
+				case Add:
194
+					if target.flags[change.mode] {
195
+						continue
196
+					}
197
+					target.flags[change.mode] = true
198
+					changes = append(changes, change)
199
+
200
+				case Remove:
201
+					if !target.flags[change.mode] {
202
+						continue
203
+					}
204
+					delete(target.flags, change.mode)
205
+					changes = append(changes, change)
160
 				}
206
 				}
161
-				delete(target.flags, change.mode)
162
-				changes = append(changes, change)
163
-			}
164
 
207
 
165
-		case Operator, LocalOperator:
166
-			if change.op == Remove {
167
-				if !target.flags[change.mode] {
168
-					continue
208
+			case Operator, LocalOperator:
209
+				if change.op == Remove {
210
+					if !target.flags[change.mode] {
211
+						continue
212
+					}
213
+					delete(target.flags, change.mode)
214
+					changes = append(changes, change)
169
 				}
215
 				}
170
-				delete(target.flags, change.mode)
171
-				changes = append(changes, change)
172
 			}
216
 			}
173
 		}
217
 		}
174
 	}
218
 	}
175
 
219
 
176
 	if len(changes) > 0 {
220
 	if len(changes) > 0 {
177
-		client.Reply(RplModeChanges(client, target, changes))
221
+		client.Send(nil, client.nickMaskString, "MODE", target.nickString, changes.String())
178
 	} else if client == target {
222
 	} else if client == target {
179
-		client.RplUModeIs(client)
223
+		client.Send(nil, target.nickMaskString, RPL_UMODEIS, target.nickString, target.ModeString())
180
 	}
224
 	}
225
+	return false
181
 }
226
 }
182
 
227
 
228
+/*
183
 func (msg *ChannelModeCommand) HandleServer(server *Server) {
229
 func (msg *ChannelModeCommand) HandleServer(server *Server) {
184
 	client := msg.Client()
230
 	client := msg.Client()
185
 	channel := server.channels.Get(msg.channel)
231
 	channel := server.channels.Get(msg.channel)

+ 1
- 0
irc/numerics.go View File

90
 	RPL_USERS             = "393"
90
 	RPL_USERS             = "393"
91
 	RPL_ENDOFUSERS        = "394"
91
 	RPL_ENDOFUSERS        = "394"
92
 	RPL_NOUSERS           = "395"
92
 	RPL_NOUSERS           = "395"
93
+	ERR_UNKNOWNERROR      = "400"
93
 	ERR_NOSUCHNICK        = "401"
94
 	ERR_NOSUCHNICK        = "401"
94
 	ERR_NOSUCHSERVER      = "402"
95
 	ERR_NOSUCHSERVER      = "402"
95
 	ERR_NOSUCHCHANNEL     = "403"
96
 	ERR_NOSUCHCHANNEL     = "403"

+ 32
- 25
irc/server.go View File

287
 	// send welcome text
287
 	// send welcome text
288
 	//NOTE(dan): we specifically use the NICK here instead of the nickmask
288
 	//NOTE(dan): we specifically use the NICK here instead of the nickmask
289
 	// see http://modern.ircdocs.horse/#rplwelcome-001 for details on why we avoid using the nickmask
289
 	// see http://modern.ircdocs.horse/#rplwelcome-001 for details on why we avoid using the nickmask
290
-	c.Send(nil, s.nameString, RPL_WELCOME, fmt.Sprintf("Welcome to the Internet Relay Network %s", c.nickString))
291
-	c.Send(nil, s.nameString, RPL_YOURHOST, fmt.Sprintf("Your host is %s, running version %s", s.nameString, SEM_VER))
292
-	c.Send(nil, s.nameString, RPL_CREATED, fmt.Sprintf("This server was created %s", s.ctime.Format(time.RFC1123)))
290
+	c.Send(nil, s.nameString, RPL_WELCOME, c.nickString, fmt.Sprintf("Welcome to the Internet Relay Network %s", c.nickString))
291
+	c.Send(nil, s.nameString, RPL_YOURHOST, c.nickString, fmt.Sprintf("Your host is %s, running version %s", s.nameString, SEM_VER))
292
+	c.Send(nil, s.nameString, RPL_CREATED, c.nickString, fmt.Sprintf("This server was created %s", s.ctime.Format(time.RFC1123)))
293
 	//TODO(dan): Look at adding last optional [<channel modes with a parameter>] parameter
293
 	//TODO(dan): Look at adding last optional [<channel modes with a parameter>] parameter
294
-	c.Send(nil, s.nameString, RPL_MYINFO, s.nameString, SEM_VER, supportedUserModesString, supportedChannelModesString)
294
+	c.Send(nil, s.nameString, RPL_MYINFO, c.nickString, s.nameString, SEM_VER, supportedUserModesString, supportedChannelModesString)
295
 	c.RplISupport()
295
 	c.RplISupport()
296
 	s.MOTD(c)
296
 	s.MOTD(c)
297
 }
297
 }
332
 		return false
332
 		return false
333
 	}
333
 	}
334
 
334
 
335
+	// if no password exists, skip checking
336
+	if len(server.password) == 0 {
337
+		client.authorized = true
338
+		return false
339
+	}
340
+
335
 	// check the provided password
341
 	// check the provided password
336
 	password := []byte(msg.Params[0])
342
 	password := []byte(msg.Params[0])
337
 	if ComparePassword(server.password, password) != nil {
343
 	if ComparePassword(server.password, password) != nil {
383
 	// we do it this way to ONLY replace what hasn't already been set
389
 	// we do it this way to ONLY replace what hasn't already been set
384
 	server.clients.Remove(client)
390
 	server.clients.Remove(client)
385
 
391
 
386
-	if client.username != "" {
387
-		client.username = Name(msg.Params[0])
392
+	if !client.HasUsername() {
393
+		client.username = Name("~" + msg.Params[0])
388
 		client.updateNickMask()
394
 		client.updateNickMask()
389
 	}
395
 	}
390
 	if client.realname != "" {
396
 	if client.realname != "" {
446
 	for i, nameString := range channels {
452
 	for i, nameString := range channels {
447
 		name = Name(nameString)
453
 		name = Name(nameString)
448
 		if !name.IsChannel() {
454
 		if !name.IsChannel() {
455
+			fmt.Println("ISN'T CHANNEL NAME:", nameString)
449
 			client.Send(nil, server.nameString, ERR_NOSUCHCHANNEL, client.nickString, nameString, "No such channel")
456
 			client.Send(nil, server.nameString, ERR_NOSUCHCHANNEL, client.nickString, nameString, "No such channel")
450
 			continue
457
 			continue
451
 		}
458
 		}
551
 // WHOIS [ <target> ] <mask> *( "," <mask> )
558
 // WHOIS [ <target> ] <mask> *( "," <mask> )
552
 func whoisHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
559
 func whoisHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
553
 	var masksString string
560
 	var masksString string
554
-	var target string
561
+	//var target string
555
 
562
 
556
 	if len(msg.Params) > 1 {
563
 	if len(msg.Params) > 1 {
557
-		target = msg.Params[0]
564
+		//target = msg.Params[0]
558
 		masksString = msg.Params[1]
565
 		masksString = msg.Params[1]
559
 	} else {
566
 	} else {
560
 		masksString = msg.Params[0]
567
 		masksString = msg.Params[0]
639
 
646
 
640
 	//TODO(dan): is this used and would I put this param in the Modern doc?
647
 	//TODO(dan): is this used and would I put this param in the Modern doc?
641
 	// if not, can we remove it?
648
 	// if not, can we remove it?
642
-	var operatorOnly bool
643
-	if len(msg.Params) > 1 && msg.Params[1] == "o" {
644
-		operatorOnly = true
645
-	}
649
+	//var operatorOnly bool
650
+	//if len(msg.Params) > 1 && msg.Params[1] == "o" {
651
+	//	operatorOnly = true
652
+	//}
646
 
653
 
647
 	if mask == "" {
654
 	if mask == "" {
648
 		for _, channel := range server.channels {
655
 		for _, channel := range server.channels {
679
 	}
686
 	}
680
 
687
 
681
 	client.flags[Operator] = true
688
 	client.flags[Operator] = true
682
-	client.Send(nil, server.nameString, RPL_YOUREOPER, client.nickString, "You are not an IRC operator")
689
+	client.Send(nil, server.nameString, RPL_YOUREOPER, client.nickString, "You are now an IRC operator")
683
 	//TODO(dan): Should this be sent automagically as part of setting the flag/mode?
690
 	//TODO(dan): Should this be sent automagically as part of setting the flag/mode?
684
 	modech := ModeChanges{&ModeChange{
691
 	modech := ModeChanges{&ModeChange{
685
 		mode: Operator,
692
 		mode: Operator,
740
 // MOTD [<target>]
747
 // MOTD [<target>]
741
 func motdHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
748
 func motdHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
742
 	//TODO(dan): hook this up when we have multiple servers I guess???
749
 	//TODO(dan): hook this up when we have multiple servers I guess???
743
-	var target string
744
-	if len(msg.Params) > 0 {
745
-		target = msg.Params[0]
746
-	}
750
+	//var target string
751
+	//if len(msg.Params) > 0 {
752
+	//	target = msg.Params[0]
753
+	//}
747
 
754
 
748
 	server.MOTD(client)
755
 	server.MOTD(client)
749
 	return false
756
 	return false
902
 	if len(msg.Params) > 0 {
909
 	if len(msg.Params) > 0 {
903
 		channels = strings.Split(msg.Params[0], ",")
910
 		channels = strings.Split(msg.Params[0], ",")
904
 	}
911
 	}
905
-	var target string
906
-	if len(msg.Params) > 1 {
907
-		target = msg.Params[1]
908
-	}
912
+	//var target string
913
+	//if len(msg.Params) > 1 {
914
+	//	target = msg.Params[1]
915
+	//}
909
 
916
 
910
 	if len(channels) == 0 {
917
 	if len(channels) == 0 {
911
 		for _, channel := range server.channels {
918
 		for _, channel := range server.channels {
1002
 	if len(msg.Params) > 1 {
1009
 	if len(msg.Params) > 1 {
1003
 		count, _ = strconv.ParseInt(msg.Params[1], 10, 64)
1010
 		count, _ = strconv.ParseInt(msg.Params[1], 10, 64)
1004
 	}
1011
 	}
1005
-	var target string
1006
-	if len(msg.Params) > 2 {
1007
-		target = msg.Params[2]
1008
-	}
1012
+	//var target string
1013
+	//if len(msg.Params) > 2 {
1014
+	//	target = msg.Params[2]
1015
+	//}
1009
 	for _, nickname := range nicknames {
1016
 	for _, nickname := range nicknames {
1010
 		results := server.whoWas.Find(Name(nickname), count)
1017
 		results := server.whoWas.Find(Name(nickname), count)
1011
 		if len(results) == 0 {
1018
 		if len(results) == 0 {

Loading…
Cancel
Save