[hackers] [ii][PATCH] Optional ucspi connection mode with -U parameter

From: Petr Vaněk <arkamar_AT_atlas.cz>
Date: Thu, 1 Sep 2022 10:27:09 +0200

This change is simple but a little bit noisy as it was necessary to
split ircfd to two, ircrfd and ircwfd, one for reading and second for
writing, because connection established by ucspi client tool[1-3] uses
different file descriptor for each direction.

Main inspiration were ucspi patches[4], but this change is less
intrusive and the feature is optional for users, which was one of
concerns back than, see original thread[5].

[1] http://cr.yp.to/ucspi-tcp.html
[2] http://skarnet.org/software/s6-networking/
[3] https://github.com/younix/ucspi
[4] http://tools.suckless.org/ii/patches/ucspi/
[5] http://lists.suckless.org/dev/1501/25129.html
---
 ii.1 |  5 +++++
 ii.c | 49 ++++++++++++++++++++++++++++---------------------
 2 files changed, 33 insertions(+), 21 deletions(-)
diff --git a/ii.1 b/ii.1
index 8e06af7..507112d 100644
--- a/ii.1
+++ b/ii.1
_AT_@ -31,6 +31,7 @@ and ii creates a new channel directory with in and out file.
 .IR realname ]
 .RB < \-u
 .IR sockname >
+.RB [ \-U ]
 .SH OPTIONS
 .TP
 .BI \-s " servername"
_AT_@ -39,6 +40,10 @@ server to connect to, for example: irc.freenode.net
 .BI \-u " sockname"
 connect to a UNIX domain socket instead of directly to a server.
 .TP
+.BI \-U
+use connection established in advance by ucspi tool with two file descriptors open, 6 and 7,
+the first one for reading and the later one for writing.
+.TP
 .BI \-p " port"
 lets you override the default port (6667)
 .TP
diff --git a/ii.c b/ii.c
index 0c9ae74..ec5b0a6 100644
--- a/ii.c
+++ b/ii.c
_AT_@ -59,7 +59,7 @@ static void      create_filepath(char *, size_t, const char *, const char *, con
 static void      die(const char *, ...);
 static void      ewritestr(int, const char *);
 static void      handle_channels_input(int, Channel *);
-static void      handle_server_output(int);
+static void      handle_server_output(int, int);
 static int       isnumeric(const char *);
 static void      loginkey(int, const char *);
 static void      loginuser(int, const char *, const char *);
_AT_@ -67,7 +67,7 @@ static void      proc_channels_input(int, Channel *, char *);
 static void      proc_channels_privmsg(int, Channel *, char *);
 static void      proc_server_cmd(int, char *);
 static int       read_line(int, char *, size_t);
-static void      run(int, const char *);
+static void      run(int, int, const char *);
 static void      setup(void);
 static void      sighandler(int);
 static int       tcpopen(const char *, const char *);
_AT_@ -100,7 +100,7 @@ usage(void)
 {
 	die("usage: %s <-s host> [-i <irc dir>] [-p <port>] "
 	        "[-u <sockname>] [-n <nick>] [-k <password>] "
-	        "[-f <fullname>]\n", argv0);
+	        "[-f <fullname>] [-U]\n", argv0);
 }
 
 static void
_AT_@ -699,16 +699,16 @@ handle_channels_input(int ircfd, Channel *c)
 }
 
 static void
-handle_server_output(int ircfd)
+handle_server_output(int ircrfd, int ircwfd)
 {
 	char buf[IRC_MSG_MAX];
 
-	if (read_line(ircfd, buf, sizeof(buf)) == -1)
+	if (read_line(ircrfd, buf, sizeof(buf)) == -1)
 		die("%s: remote host closed connection: %s\n", argv0, strerror(errno));
 
 	fprintf(stdout, "%lu %s\n", (unsigned long)time(NULL), buf);
 	fflush(stdout);
-	proc_server_cmd(ircfd, buf);
+	proc_server_cmd(ircwfd, buf);
 }
 
 static void
_AT_@ -730,7 +730,7 @@ setup(void)
 }
 
 static void
-run(int ircfd, const char *host)
+run(int ircrfd, int ircwfd, const char *host)
 {
 	Channel *c, *tmp;
 	fd_set rdset;
_AT_@ -740,9 +740,9 @@ run(int ircfd, const char *host)
 
 	snprintf(ping_msg, sizeof(ping_msg), "PING %s\r\n", host);
 	while (isrunning) {
-		maxfd = ircfd;
+		maxfd = ircrfd;
 		FD_ZERO(&rdset);
-		FD_SET(ircfd, &rdset);
+		FD_SET(ircrfd, &rdset);
 		for (c = channels; c; c = c->next) {
 			if (c->fdin > maxfd)
 				maxfd = c->fdin;
_AT_@ -760,17 +760,17 @@ run(int ircfd, const char *host)
 				channel_print(channelmaster, "-!- ii shutting down: ping timeout");
 				exit(2); /* status code 2 for timeout */
 			}
-			ewritestr(ircfd, ping_msg);
+			ewritestr(ircwfd, ping_msg);
 			continue;
 		}
-		if (FD_ISSET(ircfd, &rdset)) {
-			handle_server_output(ircfd);
+		if (FD_ISSET(ircrfd, &rdset)) {
+			handle_server_output(ircrfd, ircwfd);
 			last_response = time(NULL);
 		}
 		for (c = channels; c; c = tmp) {
 			tmp = c->next;
 			if (FD_ISSET(c->fdin, &rdset))
-				handle_channels_input(ircfd, c);
+				handle_channels_input(ircwfd, c);
 		}
 	}
 }
_AT_@ -783,7 +783,7 @@ main(int argc, char *argv[])
 	const char *key = NULL, *fullname = NULL, *host = "";
 	const char *uds = NULL, *service = "6667";
 	char prefix[PATH_MAX];
-	int ircfd, r;
+	int ircwfd, ircrfd, r, ucspi = 0;
 
 	/* use nickname and home dir of user by default */
 	if (!(spw = getpwuid(getuid())))
_AT_@ -814,6 +814,9 @@ main(int argc, char *argv[])
 	case 'u':
 		uds = EARGF(usage());
 		break;
+	case 'U':
+		ucspi = 1;
+		break;
 	default:
 		usage();
 		break;
_AT_@ -822,10 +825,14 @@ main(int argc, char *argv[])
 	if (!*host)
 		usage();
 
-	if (uds)
-		ircfd = udsopen(uds);
-	else
-		ircfd = tcpopen(host, service);
+	if (ucspi) {
+		ircrfd = 6;
+		ircwfd = 7;
+	} else if (uds) {
+		ircrfd = ircwfd = udsopen(uds);
+	} else {
+		ircrfd = ircwfd = tcpopen(host, service);
+	}
 
 #ifdef __OpenBSD__
 	/* OpenBSD pledge(2) support */
_AT_@ -840,10 +847,10 @@ main(int argc, char *argv[])
 
 	channelmaster = channel_add(""); /* master channel */
 	if (key)
-		loginkey(ircfd, key);
-	loginuser(ircfd, host, fullname && *fullname ? fullname : nick);
+		loginkey(ircwfd, key);
+	loginuser(ircwfd, host, fullname && *fullname ? fullname : nick);
 	setup();
-	run(ircfd, host);
+	run(ircrfd, ircwfd, host);
 	if (channelmaster)
 		channel_leave(channelmaster);
 
-- 
2.35.1
Received on Thu Sep 01 2022 - 10:27:09 CEST

This archive was generated by hypermail 2.3.0 : Thu Sep 01 2022 - 11:00:39 CEST