summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--handle.c28
-rw-r--r--reply.c5
2 files changed, 29 insertions, 4 deletions
diff --git a/handle.c b/handle.c
index c825ec6..31a11c1 100644
--- a/handle.c
+++ b/handle.c
@@ -74,12 +74,19 @@ join(struct Message *msg, struct Peer *peer)
 }
 
 static int
-mode(struct Message *msg, struct Peer *peer)
+mode_channel(struct Message *msg, struct Peer *peer)
+{
+	(void)msg;
+	(void)peer;
+	return 0;
+}
+
+static int
+mode_peer(struct Message *msg, struct Peer *peer)
 {
 	int set = 1, m;
 
-	ensure(peer->type, reply(peer, 451), 0);
-	ensure(msg->params[0] && *msg->params[0], reply(peer, 431), 0);
+	ensure(!strcmp(msg->params[0], peer->nick), reply(peer, 502, msg->params[0]), 0);
 	ensure(msg->params[1] && *msg->params[1], reply(peer, 221), 0);
 
 	switch (*msg->params[1])
@@ -104,7 +111,7 @@ mode(struct Message *msg, struct Peer *peer)
 
 			if (set && !(m & (OPER | LOCALOPER)))
 				peer->modes |= m;
-			else if (!(m & RESTRICTED))
+			else if (!set && !(m & RESTRICTED))
 				peer->modes &= ~m;
 		}
 	}
@@ -114,6 +121,19 @@ mode(struct Message *msg, struct Peer *peer)
 }
 
 static int
+mode(struct Message *msg, struct Peer *peer)
+{
+	ensure(peer->type, reply(peer, 451), 0);
+	ensure(msg->params[0] && *msg->params[0], reply(peer, 431), 0);
+
+	switch (*msg->params[0])
+	{
+	break; case '#': case '!': case '+': case '&': return mode_channel(msg, peer);
+	break; default: return mode_peer(msg, peer);
+	}
+}
+
+static int
 names(struct Message *msg, struct Peer *peer)
 {
 	static char buf[MESSAGE_MAX];
diff --git a/reply.c b/reply.c
index c5609e9..04a00c2 100644
--- a/reply.c
+++ b/reply.c
@@ -263,6 +263,11 @@ vreply(const struct Peer *peer, int number, va_list ap)
 		getnick(peer),
 		*m
 	), m, _);
+	REPLY(502, WRITE(
+		":%s 502 %s :Cannot change mode for other users",
+		hostname,
+		getnick(peer)
+	), _);
 	default: warn("unknown reply: %d", number); return WRITE(
 		":%s 421 %s err :Reply %d is not implemented yet",
 		hostname,