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
@@ -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"
@@ -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
@@ -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 *);
@@ -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 *);
@@ -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
@@ -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
@@ -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;
@@ -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;
@@ -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);
                }
        }
 }
@@ -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())))
@@ -814,6 +814,9 @@ main(int argc, char *argv[])
        case 'u':
                uds = EARGF(usage());
                break;
+       case 'U':
+               ucspi = 1;
+               break;
        default:
                usage();
                break;
@@ -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 */
@@ -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


Reply via email to