shithub: ircd

Download patch

ref: 564f0cc5963d4055fe4ac30e6d4f6a63e9ca086b
parent: e31571ccd655aabc78d736047c6211f024ead09c
author: sirjofri <sirjofri@sirjofri.de>
date: Tue Jul 22 17:03:29 EDT 2025

adds more commands, privmsg now works

--- a/cmd.c
+++ b/cmd.c
@@ -8,6 +8,7 @@
 static void
 cversion(Client *c, Request *r)
 {
+	/* (/lib/rfc/rfc2812:/^3.4.3) */
 	if (r->args[0]) {
 		fprint(2, "get version of '%s' (not implemented yet!)\n", r->args[0]);
 		reply(c, Enosuchserver, r->args[0]);
@@ -19,15 +20,14 @@
 static void
 cuser(Client *c, Request *r)
 {
+	/* (/lib/rfc/rfc2812:/^3.1.3) */
 	User *u;
 	if (!r->args[3]) {
-		fprint(2, "user without enough args%R\n", *r);
 		reply(c, Eneedmoreparams, r->cmd->name);
 		return;
 	}
 	u = finduser(r->args[0]);
 	if (u) {
-		fprint(2, "user already registered%R\n", *r);
 		reply(c, Ealreadyregistered);
 		return;
 	}
@@ -44,6 +44,7 @@
 static void
 cnick(Client *c, Request *r)
 {
+	/* (/lib/rfc/rfc2812:/^3.1.2) */
 	if (!r->args[0]) {
 		reply(c, Enonicknamegiven);
 		return;
@@ -65,6 +66,7 @@
 static void
 cwhois(Client *c, Request *r)
 {
+	/* (/lib/rfc/rfc2812:/^3.6.2) */
 	// TODO: implement remaining replies: (/lib/rfc/rfc2812:/^3.6.2)
 	int start = 0;
 	char *server = nil;
@@ -100,11 +102,55 @@
 	}
 }
 
+static void
+cprivmsg(Client *c, Request *r)
+{
+	/* (/lib/rfc/rfc2812:/^3.3.1) */
+	Client *tgt;
+	if (!r->args[0]) {
+		reply(c, Enorecipient, "PRIVMSG");
+		return;
+	}
+	if (!r->args[1]) {
+		reply(c, Enotexttosend);
+		return;
+	}
+	tgt = findnick(r->args[0]);
+	if (!tgt) {
+		reply(c, Enosuchnick, r->args[0]);
+		return;
+	}
+	if (tgt->away) {
+		reply(c, Raway, r->args[0], tgt->away);
+		return;
+	}
+	ircsend(tgt, c, Sprivmsg, r->args[0], r->args[1]);
+}
+
+static void
+caway(Client *c, Request *r)
+{
+	/* (/lib/rfc/rfc2812:/^4.1) */
+	if (r->args[0]) {
+		if (c->away)
+			free(c->away);
+		c->away = strdup(r->args[0]);
+		reply(c, Rnowaway);
+		return;
+	}
+	if (c->away)
+		free(c->away);
+	c->away = nil;
+	reply(c, Runaway);
+}
+
 static Command commands[] = {
 	{ "whois", cwhois },
 	{ "version", cversion },
 	{ "user", cuser },
 	{ "nick", cnick },
+	{ "privmsg", cprivmsg },
+	{ "away", caway },
 };
 int ncommands = sizeof(commands) / sizeof(Command);
 
--- a/cmd.h
+++ b/cmd.h
@@ -3,6 +3,21 @@
 	.msg = ":%s %s!%s@%s",
 };
 
+Reply Raway = {
+	.nr = 301,
+	.msg = "%s :%s",
+};
+
+Reply Runaway = {
+	.nr = 305,
+	.msg = ":You are no longer marked as being away",
+};
+
+Reply Rnowaway = {
+	.nr = 306,
+	.msg = ":You have been marked as being away",
+};
+
 Reply Rwhoisuser = {
 	.nr = 311,
 	.msg = "%s %s %s * :%s",
@@ -28,6 +43,16 @@
 	.msg = "%s :No such server",
 };
 
+Reply Enorecipient = {
+	.nr = 411,
+	.msg = ":No recipient given (%s)",
+};
+
+Reply Enotexttosend = {
+	.nr = 412,
+	.msg = ":No text to send",
+};
+
 Reply Enonicknamegiven = {
 	.nr = 431,
 	.msg = ":No nickname given",
@@ -51,4 +76,8 @@
 Reply Erestricted = {
 	.nr = 484,
 	.msg = ":Your connection is restricted!",
+};
+
+Reply Sprivmsg = {
+	.msg = "PRIVMSG %s :%s",
 };
--- a/dat.h
+++ b/dat.h
@@ -43,11 +43,9 @@
 struct User
 {
 	char *name;
+	char *host; /* if nil, local use (use sysname) */
 	char *realname;
 	int greeted;
-	
-	User *prev;
-	User *next;
 };
 
 struct Client
@@ -56,6 +54,7 @@
 	Replybuffer replies;
 	User *user;
 	char *nick;
+	char *away;
 	
 	Client *next;
 	Client *prev;
--- a/fns.h
+++ b/fns.h
@@ -6,6 +6,7 @@
 void clearrequest(Request);
 
 void reply(Client*, Reply, ...);
+void ircsend(Client*, Client*, Reply, ...);
 char *getreplies(Client*);
 void flushreplies(Client*);
 
--- a/reply.c
+++ b/reply.c
@@ -26,7 +26,7 @@
 	char buf[1024];
 	int i;
 	va_list arg;
-	String *s = c->replies.reply;
+	String *s;
 	
 	i = snprint(buf, sizeof buf, ":%s %03d ", sysnameb, repl.nr);
 	
@@ -38,5 +38,35 @@
 	
 	if (debug > 1)
 		fprint(2, "reply: '%s'\n", buf);
+	qlock(&c->replies);
+	s = c->replies.reply;
 	s_append(s, buf);
+	qunlock(&c->replies);
+}
+
+void
+ircsend(Client *c, Client *sender, Reply repl, ...)
+{
+	char buf[1024];
+	int i;
+	va_list arg;
+	String *s;
+	
+	i = snprint(buf, sizeof buf, ":%s!%s@%s ",
+		sender->nick, sender->user->name,
+		sender->user->host ? sender->user->host : sysnameb);
+	
+	va_start(arg, repl);
+	i += vsnprint(&buf[i], sizeof(buf) - i, repl.msg, arg);
+	va_end(arg);
+	
+	snprint(&buf[i], sizeof(buf) - i, "\r\n");
+	
+	if (debug > 1)
+		fprint(2, "ircsend: '%s'\n", buf);
+	
+	qlock(&c->replies);
+	s = c->replies.reply;
+	s_append(s, buf);
+	qunlock(&c->replies);
 }
--