[dev] [ii] Patch to use ii with UCSPI backend

From: younix <j.klemkow_AT_wemelug.de>
Date: Thu, 15 Jan 2015 22:39:34 +0100

Hi,

this diff changes the network connection of ii to the UCSPI[1] protocol.
This makes ii much more flexible. With the UCSPI protocol you could use
features like IPv6[2], SOCKSv5[3] or even TLS[3]. This diff extracts
the socket handling infrastructure to an external program like
tcpclient. So it shrinks the codebase and complexity.

What is your opinion about this diff? At least it would be great to put
this patch at the ii suckless webpage. So I could made an OpenBSD port
(flavor) of it.

You can uses ii in the following manner:

1. Direct plain IRC connection

   tcpclient irc.freenode.net 6667 ii

2. TLS encrypted connection

   tcpclient irc.freenode.net 6697 tlsc ii

3. TLS connection in combination with a SOCKS proxy

   tcpclient 127.0.0.1 1080 socks irc.freenode.net 6697 tlsc ii

 [1]: http://cr.yp.to/proto/ucspi.txt
 [2]: http://www.fefe.de/ucspi/
 [3]: https://github.com/younix/ucspi

bye,
younix

commit 6109304028cba410862dfe2e827f7941ba5dfa2f
Author: Jan Klemkow <j.klemkow_AT_wemelug.de>
Date: Mon Jan 12 18:05:42 2015 +0100

    change network access through ucspi

diff --git a/ii.c b/ii.c
index d93266c..fad523c 100644
--- a/ii.c
+++ b/ii.c
_AT_@ -19,6 +19,9 @@
 #include <time.h>
 #include <unistd.h>
 
+#define UCSPI_READ 7
+#define UCSPI_WRITE 6
+
 #ifndef PIPE_BUF /* FreeBSD don't know PIPE_BUF */
 #define PIPE_BUF 4096
 #endif
_AT_@ -33,10 +36,9 @@ struct Channel {
         Channel *next;
 };
 
-static int irc;
 static time_t last_response;
 static Channel *channels = NULL;
-static char *host = "irc.freenode.net";
+static char *host = NULL;
 static char nick[32]; /* might change while running */
 static char path[_POSIX_PATH_MAX];
 static char message[PIPE_BUF]; /* message buf used for communication */
_AT_@ -148,31 +150,7 @@ static void login(char *key, char *fullname) {
                                 nick, nick, host, fullname ? fullname : nick);
         else snprintf(message, PIPE_BUF, "NICK %s\r\nUSER %s localhost %s :%s\r\n",
                                 nick, nick, host, fullname ? fullname : nick);
- write(irc, message, strlen(message)); /* login */
-}
-
-static int tcpopen(unsigned short port) {
- int fd;
- struct sockaddr_in sin;
- struct hostent *hp = gethostbyname(host);
-
- memset(&sin, 0, sizeof(struct sockaddr_in));
- if(!hp) {
- perror("ii: cannot retrieve host information");
- exit(EXIT_FAILURE);
- }
- sin.sin_family = AF_INET;
- memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);
- sin.sin_port = htons(port);
- if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- perror("ii: cannot create socket");
- exit(EXIT_FAILURE);
- }
- if(connect(fd, (const struct sockaddr *) &sin, sizeof(sin)) < 0) {
- perror("ii: cannot connect to host");
- exit(EXIT_FAILURE);
- }
- return fd;
+ write(UCSPI_WRITE, message, strlen(message)); /* login */
 }
 
 static size_t tokenize(char **result, size_t reslen, char *str, char delim) {
_AT_@ -219,7 +197,7 @@ static void proc_channels_privmsg(char *channel, char *buf) {
         snprintf(message, PIPE_BUF, "<%s> %s", nick, buf);
         print_out(channel, message);
         snprintf(message, PIPE_BUF, "PRIVMSG %s :%s\r\n", channel, buf);
- write(irc, message, strlen(message));
+ write(UCSPI_WRITE, message, strlen(message));
 }
 
 static void proc_channels_input(Channel *c, char *buf) {
_AT_@ -273,7 +251,7 @@ static void proc_channels_input(Channel *c, char *buf) {
                         else
                                 snprintf(message, PIPE_BUF,
                                                 "PART %s :ii - 500 SLOC are too much\r\n", c->name);
- write(irc, message, strlen(message));
+ write(UCSPI_WRITE, message, strlen(message));
                         close(c->fd);
                         /*create_filepath(infile, sizeof(infile), c->name, "in");
                         unlink(infile); */
_AT_@ -288,7 +266,7 @@ static void proc_channels_input(Channel *c, char *buf) {
                 snprintf(message, PIPE_BUF, "%s\r\n", &buf[1]);
 
         if (message[0] != '\0')
- write(irc, message, strlen(message));
+ write(UCSPI_WRITE, message, strlen(message));
 }
 
 static void proc_server_cmd(char *buf) {
_AT_@ -339,7 +317,7 @@ static void proc_server_cmd(char *buf) {
                 return;
         } else if(!strncmp("PING", argv[TOK_CMD], 5)) {
                 snprintf(message, PIPE_BUF, "PONG %s\r\n", argv[TOK_TEXT]);
- write(irc, message, strlen(message));
+ write(UCSPI_WRITE, message, strlen(message));
                 return;
         } else if(!argv[TOK_NICKSRV] || !argv[TOK_USER]) { /* server command */
                 snprintf(message, PIPE_BUF, "%s%s", argv[TOK_ARG] ? argv[TOK_ARG] : "", argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
_AT_@ -402,7 +380,7 @@ static void handle_channels_input(Channel *c) {
 
 static void handle_server_output() {
         static char buf[PIPE_BUF];
- if(read_line(irc, PIPE_BUF, buf) == -1) {
+ if(read_line(UCSPI_READ, PIPE_BUF, buf) == -1) {
                 perror("ii: remote host closed connection");
                 exit(EXIT_FAILURE);
         }
_AT_@ -419,8 +397,8 @@ static void run() {
         snprintf(ping_msg, sizeof(ping_msg), "PING %s\r\n", host);
         for(;;) {
                 FD_ZERO(&rd);
- maxfd = irc;
- FD_SET(irc, &rd);
+ maxfd = UCSPI_READ;
+ FD_SET(UCSPI_READ, &rd);
                 for(c = channels; c; c = c->next) {
                         if(maxfd < c->fd)
                                 maxfd = c->fd;
_AT_@ -440,10 +418,10 @@ static void run() {
                                 print_out(NULL, "-!- ii shutting down: ping timeout");
                                 exit(EXIT_FAILURE);
                         }
- write(irc, ping_msg, strlen(ping_msg));
+ write(UCSPI_WRITE, ping_msg, strlen(ping_msg));
                         continue;
                 }
- if(FD_ISSET(irc, &rd)) {
+ if(FD_ISSET(UCSPI_READ, &rd)) {
                         handle_server_output();
                         last_response = time(NULL);
                 }
_AT_@ -460,13 +438,17 @@ int main(int argc, char *argv[]) {
         char *key = NULL, *fullname = NULL;
         char prefix[_POSIX_PATH_MAX];
 
+ if ((host = getenv("TCPREMOTEHOST")) == NULL)
+ if ((host = getenv("TCPREMOTEIP")) == NULL)
+ host = "irc.freenode.net";
+
         if(!spw) {
                 fputs("ii: getpwuid() failed\n", stderr);
                 exit(EXIT_FAILURE);
         }
         snprintf(nick, sizeof(nick), "%s", spw->pw_name);
         snprintf(prefix, sizeof(prefix),"%s/irc", spw->pw_dir);
- if (argc <= 1 || (argc == 2 && argv[1][0] == '-' && argv[1][1] == 'h')) usage();
+ if ((argc == 2 && argv[1][0] == '-' && argv[1][1] == 'h')) usage();
 
         for(i = 1; (i + 1 < argc) && (argv[i][0] == '-'); i++) {
                 switch (argv[i][1]) {
_AT_@ -479,7 +461,6 @@ int main(int argc, char *argv[]) {
                         default: usage(); break;
                 }
         }
- irc = tcpopen(port);
         if(!snprintf(path, sizeof(path), "%s/%s", prefix, host)) {
                 fputs("ii: path to irc directory too long\n", stderr);
                 exit(EXIT_FAILURE);
Received on Thu Jan 15 2015 - 22:39:34 CET

This archive was generated by hypermail 2.3.0 : Thu Jan 15 2015 - 22:48:07 CET