[PATCH 08/65] overhaul: see CHANGES for changes

From: Hiltjo Posthuma <hiltjo_AT_codemadness.org>
Date: Wed, 16 Apr 2014 17:23:03 +0200

Signed-off-by: Hiltjo Posthuma <hiltjo_AT_codemadness.org>
---
 CHANGES |  15 ++
 ii.1    |   6 +-
 ii.c    | 489 ++++++++++++++++++++++++++++++++++++------------------------=
----
 3 files changed, 297 insertions(+), 213 deletions(-)
diff --git a/CHANGES b/CHANGES
index 3baaca2..5931c62 100644
--- a/CHANGES
+++ b/CHANGES
_AT_@ -1,3 +1,18 @@
+1.8 (2014-??-??)
+    - server host (-s) doesn't default to irc.freenode and is now a requir=
ed
+      parameter.
+    - remove "in" file when leaving a channel (enabled commented code).
+    - use IRC_MAX (512), instead of PIPE_BUF (4096) on most systems.
+    - use C99 and -D_POSIX_C_SOURCE=3D200809L.
+    - cleanup:
+        - use arg.h
+        - use sbase util functions (estrtol, eprintf).
+        - use OpenBSD strlcpy().
+    - style:
+        - linewrap to 79 characters.
+        - coding style fixes.
+        - non-roman numerals for LICENSE period.
+
 1.7 (2013-01-05)
     - -k now specifies an environment variable that contains the
       server key. This behaviour has been changed in order to not
diff --git a/ii.1 b/ii.1
index f094cd5..f5d1e61 100644
--- a/ii.1
+++ b/ii.1
_AT_@ -21,8 +21,8 @@ For example if you will join a channel just do echo "/j #=
channel" > in
 and ii creates a new channel directory with in and out file.
 .SH SYNOPSIS
 .B ii
-.RB [ \-s
-.IR servername ]
+.RB < \-s
+.IR servername >
 .RB [ \-p
 .IR port ]
 .RB [ \-k
_AT_@ -37,7 +37,7 @@ and ii creates a new channel directory with in and out fi=
le.
 .SH OPTIONS
 .TP
 .BI \-s " servername"
-lets you override the default servername (irc.freenode.net)
+server to connect to, for example: irc.freenode.net
 .TP
 .BI \-p " port"
 lets you override the default port (6667)
diff --git a/ii.c b/ii.c
index b710145..e5c80e7 100644
--- a/ii.c
+++ b/ii.c
_AT_@ -2,15 +2,15 @@
 #include <errno.h>
 #include <netdb.h>
 #include <sys/types.h>
-#include <sys/stat.h>
 #include <sys/socket.h>
 #include <sys/select.h>
+#include <sys/stat.h>
 #include <netinet/in.h>
+#include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <limits.h>
 #include <fcntl.h>
-#include <string.h>
 #include <pwd.h>
 #include <signal.h>
 #include <ctype.h>
_AT_@ -18,11 +18,12 @@
 #include <unistd.h>
=20
 #include "util.h"
-#ifndef PIPE_BUF /* FreeBSD don't know PIPE_BUF */
-#define PIPE_BUF 4096
-#endif
-#define PING_TIMEOUT 300
-#define SERVER_PORT 6667
+
+#define IRC_CHANNEL_MAX    50
+#define IRC_MSG_MAX       512
+#define PING_TIMEOUT      300
+#define SERVER_PORT      6667
+
 enum { TOK_NICKSRV =3D 0, TOK_USER, TOK_CMD, TOK_CHAN, TOK_ARG, TOK_TEXT, =
TOK_LAST };
=20
 typedef struct Channel Channel;
_AT_@ -32,39 +33,40 @@ struct Channel {
 	Channel *next;
 };
=20
-static int irc;
-static time_t last_response;
+static time_t last_response =3D 0;
 static Channel *channels =3D NULL;
-static char *host =3D "irc.freenode.net";
-static char nick[32];			/* might change while running */
-static char path[_POSIX_PATH_MAX];
-static char message[PIPE_BUF]; /* message buf used for communication */
-
-static void usage() {
-	fputs("ii - irc it - " VERSION "\n"
-	      "(C)opyright MMV-MMVI Anselm R. Garbe\n"
-	      "(C)opyright MMV-MMXI Nico Golde\n"
-	      "usage: ii [-i <irc dir>] [-s <host>] [-p <port>]\n"
-	      "          [-n <nick>] [-k <password>] [-f <fullname>]\n", stderr);
-	exit(EXIT_FAILURE);
+static char nick[32] =3D ""; /* might change while running */
+static char path[_POSIX_PATH_MAX] =3D ""; /* irc dir (-i) */
+static char msg[IRC_MSG_MAX] =3D ""; /* message buf used for communication=
 */
+
+static void
+usage(void) {
+	eprintf("ii-" VERSION ", =C2=A9 2005-2014 ii engineers, see LICENSE for d=
etails\n"
+	      "usage: %s <-s host> [-i <irc dir>] [-p <port>]\n"
+	      "          [-n <nick>] [-k <password>] [-f <fullname>]\n", argv0);
 }
=20
-static char *striplower(char *s) {
+static char *
+striplower(char *s) {
 	char *p =3D NULL;
+
 	for(p =3D s; p && *p; p++) {
-		if(*p =3D=3D '/') *p =3D ',';
+		if(*p =3D=3D '/')
+			*p =3D ',';
 		*p =3D tolower(*p);
 	}
 	return s;
 }
=20
 /* creates directories top-down, if necessary */
-static void create_dirtree(const char *dir) {
-	char tmp[256];
+static void
+create_dirtree(const char *dir) {
+	char tmp[_POSIX_PATH_MAX];
 	char *p =3D NULL;
 	size_t len;
-	snprintf(tmp, sizeof(tmp),"%s",dir);
-	len =3D strlen(tmp);
+
+	strlcpy(tmp, dir, sizeof(tmp));
+	len =3D strnlen(tmp, sizeof(tmp));
 	if(tmp[len - 1] =3D=3D '/')
 		tmp[len - 1] =3D 0;
 	for(p =3D tmp + 1; *p; p++)
_AT_@ -76,9 +78,11 @@ static void create_dirtree(const char *dir) {
 	mkdir(tmp, S_IRWXU);
 }
=20
-static int get_filepath(char *filepath, size_t len, char *channel, char *f=
ile) {
+/* TODO: dont call create_dirtree() in get_filepath() ? */
+static int
+get_filepath(char *filepath, size_t len, char *channel, char *file) {
 	if(channel) {
-		if(!snprintf(filepath, len, "%s/%s", path, channel))
+		if(snprintf(filepath, len, "%s/%s", path, channel) <=3D 0)
 			return 0;
 		create_dirtree(filepath);
 		return snprintf(filepath, len, "%s/%s/%s", path, channel, file);
_AT_@ -86,22 +90,24 @@ static int get_filepath(char *filepath, size_t len, cha=
r *channel, char *file) {
 	return snprintf(filepath, len, "%s/%s", path, file);
 }
=20
-static void create_filepath(char *filepath, size_t len, char *channel, cha=
r *suffix) {
-	if(!get_filepath(filepath, len, striplower(channel), suffix)) {
-		fputs("ii: path to irc directory too long\n", stderr);
-		exit(EXIT_FAILURE);
-	}
+static void
+create_filepath(char *filepath, size_t len, char *channel, char *suffix) {
+	if(get_filepath(filepath, len, striplower(channel), suffix) <=3D 0)
+		eprintf("path to irc directory too long");
 }
=20
-static int open_channel(char *name) {
-	static char infile[256];
+static int
+open_channel(char *name) {
+	char infile[_POSIX_PATH_MAX];
+
 	create_filepath(infile, sizeof(infile), name, "in");
 	if(access(infile, F_OK) =3D=3D -1)
 		mkfifo(infile, S_IRWXU);
 	return open(infile, O_RDONLY | O_NONBLOCK, 0);
 }
=20
-static void add_channel(char *cname) {
+static void
+add_channel(char *cname) {
 	Channel *c;
 	int fd;
 	char *name =3D striplower(cname);
_AT_@ -111,16 +117,14 @@ static void add_channel(char *cname) {
 			return; /* already handled */
=20
 	fd =3D open_channel(name);
-	if(fd =3D=3D -1) {
-		printf("ii: exiting, cannot create in channel: %s\n", name);
-		exit(EXIT_FAILURE);
-	}
-	c =3D calloc(1, sizeof(Channel));
-	if(!c) {
-		perror("ii: cannot allocate memory");
-		exit(EXIT_FAILURE);
-	}
-	if(!channels) channels =3D c;
+	if(fd =3D=3D -1)
+		eprintf("exiting, cannot create in channel: %s:", name);
+
+	if(!(c =3D calloc(1, sizeof(Channel))))
+		eprintf("cannot allocate memory:");
+
+	if(!channels)
+		channels =3D c;
 	else {
 		c->next =3D channels;
 		channels =3D c;
_AT_@ -129,63 +133,70 @@ static void add_channel(char *cname) {
 	c->name =3D strdup(name);
 }
=20
-static void rm_channel(Channel *c) {
+static void
+rm_channel(Channel *c) {
 	Channel *p;
-	if(channels =3D=3D c) channels =3D channels->next;
+
+	if(channels =3D=3D c)
+		channels =3D channels->next;
 	else {
 		for(p =3D channels; p && p->next !=3D c; p =3D p->next);
 		if(p->next =3D=3D c)
 			p->next =3D c->next;
 	}
 	free(c->name);
+	c->name =3D NULL;
 	free(c);
 }
=20
-static void login(char *key, char *fullname) {
-	if(key) snprintf(message, PIPE_BUF,
-				"PASS %s\r\nNICK %s\r\nUSER %s localhost %s :%s\r\n", key,
-				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 void
+login(int fd, char *host, char *key, char *fullname) {
+	if(key)
+		snprintf(msg, sizeof(msg),
+		         "PASS %s\r\nNICK %s\r\nUSER %s localhost %s :%s\r\n", key,
+		         nick, nick, host, fullname);
+	else
+		snprintf(msg, sizeof(msg), "NICK %s\r\nUSER %s localhost %s :%s\r\n",
+		         nick, nick, host, fullname);
+	write(fd, msg, strnlen(msg, sizeof(msg)));
 }
=20
-static int tcpopen(unsigned short port) {
+static int
+tcpopen(const char *host, unsigned short port) {
 	int fd;
 	struct sockaddr_in sin;
-	struct hostent *hp =3D gethostbyname(host);
+	struct hostent *hp;
=20
+	if(!(hp =3D gethostbyname(host)))
+		eprintf("cannot retrieve host information:");
 	memset(&sin, 0, sizeof(struct sockaddr_in));
-	if(!hp) {
-		perror("ii: cannot retrieve host information");
-		exit(EXIT_FAILURE);
-	}
 	sin.sin_family =3D AF_INET;
-	memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);
+	/* TODO: don't use h_addr or h_addr_list here, but getaddrinfo() */
+	memcpy(&sin.sin_addr, hp->h_addr_list[0], hp->h_length);
 	sin.sin_port =3D htons(port);
-	if((fd =3D 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);
-	}
+	if((fd =3D socket(AF_INET, SOCK_STREAM, 0)) < 0)
+		eprintf("cannot create socket:");
+
+	if(connect(fd, (const struct sockaddr *) &sin, sizeof(sin)) < 0)
+		eprintf("cannot connect to host:");
+
 	return fd;
 }
=20
-static size_t tokenize(char **result, size_t reslen, char *str, char delim=
) {
+static size_t
+tokenize(char **result, size_t reslen, char *str, char delim) {
 	char *p =3D NULL, *n =3D NULL;
-	size_t i;
+	size_t i =3D 0;
=20
 	if(!str)
 		return 0;
 	for(n =3D str; *n =3D=3D ' '; n++);
 	p =3D n;
-	for(i =3D 0; *n !=3D 0;) {
-		if(i =3D=3D reslen)
+	while(*n !=3D 0) {
+		if(i >=3D reslen)
 			return 0;
-		if(i > TOK_CHAN - TOK_CMD && strtol(result[0], NULL, 10) > 0) delim=3D':=
'; /* workaround non-RFC compliant messages */
+		if(i > TOK_CHAN - TOK_CMD && strtol(result[0], NULL, 10) > 0)
+			delim =3D ':'; /* workaround non-RFC compliant messages */
 		if(*n =3D=3D delim) {
 			*n =3D 0;
 			result[i++] =3D p;
_AT_@ -193,124 +204,138 @@ static size_t tokenize(char **result, size_t reslen=
, char *str, char delim) {
 		} else
 			n++;
 	}
-	if(i<reslen && p < n && strlen(p))
+	if(i < reslen && p < n && p && *p)
 		result[i++] =3D p;
-	return i;				/* number of tokens */
+	return i; /* number of tokens */
 }
=20
-static void print_out(char *channel, char *buf) {
-	static char outfile[256], server[256], buft[18];
+static void
+print_out(char *channel, char *buf) {
+	char outfile[_POSIX_PATH_MAX], server[IRC_CHANNEL_MAX + 6], buft[18];
 	FILE *out =3D NULL;
-	time_t t =3D time(0);
+	time_t t =3D time(NULL);
=20
-	if(channel) snprintf(server, sizeof(server), "-!- %s", channel);
-	if(strstr(buf, server)) channel=3D"";
+	if(channel)
+		snprintf(server, sizeof(server), "-!- %s", channel);
+	if(strstr(buf, server))
+		channel =3D "";
 	create_filepath(outfile, sizeof(outfile), channel, "out");
-	if(!(out =3D fopen(outfile, "a"))) return;
-	if(channel && channel[0]) add_channel(channel);
+	if(!(out =3D fopen(outfile, "a")))
+		return;
+	if(channel && channel[0])
+		add_channel(channel);
=20
 	strftime(buft, sizeof(buft), "%F %R", localtime(&t));
 	fprintf(out, "%s %s\n", buft, buf);
 	fclose(out);
 }
=20
-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));
+static void
+proc_channels_privmsg(int fd, char *channel, char *buf) {
+	snprintf(msg, sizeof(msg), "<%s> %s", nick, buf);
+	print_out(channel, msg);
+	snprintf(msg, sizeof(msg), "PRIVMSG %s :%s\r\n", channel, buf);
+	write(fd, msg, strnlen(msg, sizeof(msg)));
 }
=20
-static void proc_channels_input(Channel *c, char *buf) {
-	/* static char infile[256]; */
+static void
+proc_channels_input(Channel *c, char *buf) {
+	char infile[_POSIX_PATH_MAX];
 	char *p =3D NULL;
+	size_t buflen;
=20
 	if(buf[0] !=3D '/' && buf[0] !=3D 0) {
-		proc_channels_privmsg(c->name, buf);
+		proc_channels_privmsg(c->fd, c->name, buf);
 		return;
 	}
-	message[0] =3D '\0';
-	if(buf[2] =3D=3D ' ' || buf[2] =3D=3D '\0') switch (buf[1]) {
+	msg[0] =3D '\0';
+	if(buf[2] =3D=3D ' ' || buf[2] =3D=3D '\0') {
+		buflen =3D strlen(buf);
+		switch(buf[1]) {
 		case 'j':
 			p =3D strchr(&buf[3], ' ');
-			if(p) *p =3D 0;
-			if((buf[3]=3D=3D'#')||(buf[3]=3D=3D'&')||(buf[3]=3D=3D'+')||(buf[3]=3D=
=3D'!')){
-				if(p) snprintf(message, PIPE_BUF, "JOIN %s %s\r\n", &buf[3], p + 1); /=
* password protected channel */
-				else snprintf(message, PIPE_BUF, "JOIN %s\r\n", &buf[3]);
+			if(p)
+				*p =3D 0;
+			if((buf[3] =3D=3D '#') || (buf[3] =3D=3D '&') || (buf[3] =3D=3D '+') ||
+				(buf[3] =3D=3D '!'))
+			{
+				/* password protected channel */
+				if(p)
+					snprintf(msg, sizeof(msg), "JOIN %s %s\r\n", &buf[3], p + 1);
+				else
+					snprintf(msg, sizeof(msg), "JOIN %s\r\n", &buf[3]);
 				add_channel(&buf[3]);
 			}
-			else if(p){
+			else if(p) {
 				add_channel(&buf[3]);
-				proc_channels_privmsg(&buf[3], p + 1);
+				proc_channels_privmsg(c->fd, &buf[3], p + 1);
 				return;
 			}
 			break;
 		case 't':
-			if(strlen(buf)>=3D3) snprintf(message, PIPE_BUF, "TOPIC %s :%s\r\n", c-=
>name, &buf[3]);
+			if(buflen >=3D 3)
+				snprintf(msg, sizeof(msg), "TOPIC %s :%s\r\n", c->name, &buf[3]);
 			break;
 		case 'a':
-			if(strlen(buf)>=3D3){
-				snprintf(message, PIPE_BUF, "-!- %s is away \"%s\"", nick, &buf[3]);
-				print_out(c->name, message);
+			if(buflen >=3D 3) {
+				snprintf(msg, sizeof(msg), "-!- %s is away \"%s\"", nick, &buf[3]);
+				print_out(c->name, msg);
 			}
-			if(buf[2] =3D=3D 0 || strlen(buf)<3) /* or used to make else part safe =
*/
-				snprintf(message, PIPE_BUF, "AWAY\r\n");
+			if(buflen < 3)
+				snprintf(msg, sizeof(msg), "AWAY\r\n");
 			else
-				snprintf(message, PIPE_BUF, "AWAY :%s\r\n", &buf[3]);
+				snprintf(msg, sizeof(msg), "AWAY :%s\r\n", &buf[3]);
 			break;
 		case 'n':
-			if(strlen(buf)>=3D3){
-				snprintf(nick, sizeof(nick),"%s", &buf[3]);
-				snprintf(message, PIPE_BUF, "NICK %s\r\n", &buf[3]);
+			if(buflen >=3D 3) {
+				strlcpy(nick, &buf[3], sizeof(nick));
+				snprintf(msg, sizeof(msg), "NICK %s\r\n", &buf[3]);
 			}
 			break;
 		case 'l':
 			if(c->name[0] =3D=3D 0)
 				return;
-			if(buf[2] =3D=3D ' ' && strlen(buf)>=3D3)
-				snprintf(message, PIPE_BUF, "PART %s :%s\r\n", c->name, &buf[3]);
+			if(buf[2] =3D=3D ' ' && buflen >=3D 3)
+				snprintf(msg, sizeof(msg), "PART %s :%s\r\n", c->name, &buf[3]);
 			else
-				snprintf(message, PIPE_BUF,
-						"PART %s :ii - 500 SLOC are too much\r\n", c->name);
-			write(irc, message, strlen(message));
+				snprintf(msg, sizeof(msg),
+				         "PART %s :ii - 500 SLOC are too much\r\n", c->name);
+			write(c->fd, msg, strnlen(msg, sizeof(msg)));
 			close(c->fd);
-			/*create_filepath(infile, sizeof(infile), c->name, "in");
-			unlink(infile); */
+			/* TODO: dont create directory before deleting in file
+			 * just try to delete it immediately */
+			create_filepath(infile, sizeof(infile), c->name, "in");
+			unlink(infile);
 			rm_channel(c);
 			return;
 			break;
 		default:
-			snprintf(message, PIPE_BUF, "%s\r\n", &buf[1]);
+			snprintf(msg, sizeof(msg), "%s\r\n", &buf[1]);
 			break;
 		}
+	}
 	else
-		snprintf(message, PIPE_BUF, "%s\r\n", &buf[1]);
+		snprintf(msg, sizeof(msg), "%s\r\n", &buf[1]);
=20
-	if (message[0] !=3D '\0')
-		write(irc, message, strlen(message));
+	if(msg[0] !=3D '\0')
+		write(c->fd, msg, strnlen(msg, sizeof(msg)));
 }
=20
-static void proc_server_cmd(char *buf) {
+static void
+proc_server_cmd(int fd, char *buf) {
 	char *argv[TOK_LAST], *cmd =3D NULL, *p =3D NULL;
-	int i;
+	unsigned int i;
=20
-	if(!buf || *buf=3D=3D'\0')
+	if(!buf || *buf =3D=3D '\0')
 		return;
=20
 	for(i =3D 0; i < TOK_LAST; i++)
 		argv[i] =3D NULL;
-	/* <message>  ::=3D [':' <prefix> <SPACE> ] <command> <params> <crlf>
-	   <prefix>   ::=3D <servername> | <nick> [ '!' <user> ] [ '_AT_' <host> ]
-	   <command>  ::=3D <letter> { <letter> } | <number> <number> <number>
-	   <SPACE>    ::=3D ' ' { ' ' }
-	   <params>   ::=3D <SPACE> [ ':' <trailing> | <middle> <params> ]
-	   <middle>   ::=3D <Any *non-empty* sequence of octets not including SPA=
CE
-	   or NUL or CR or LF, the first of which may not be ':'>
-	   <trailing> ::=3D <Any, possibly *empty*, sequence of octets not includ=
ing NUL or CR or LF>
-	   <crlf>     ::=3D CR LF */
-
-	if(buf[0] =3D=3D ':') {		/* check prefix */
-		if (!(p =3D strchr(buf, ' '))) return;
+
+	/* check prefix */
+	if(buf[0] =3D=3D ':') {
+		if (!(p =3D strchr(buf, ' ')))
+			return;
 		*p =3D 0;
 		for(++p; *p =3D=3D ' '; p++);
 		cmd =3D p;
_AT_@ -337,59 +362,84 @@ static void proc_server_cmd(char *buf) {
 	if(!argv[TOK_CMD] || !strncmp("PONG", argv[TOK_CMD], 5)) {
 		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));
+		snprintf(msg, sizeof(msg), "PONG %s\r\n", argv[TOK_TEXT]);
+		write(fd, msg, strnlen(msg, sizeof(msg)));
 		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] : "");
-		print_out(0, message);
+	} else if(!argv[TOK_NICKSRV] || !argv[TOK_USER]) {
+		/* server command */
+		snprintf(msg, sizeof(msg), "%s%s",
+				argv[TOK_ARG] ? argv[TOK_ARG] : "",
+				argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
+		print_out(0, msg);
 		return;
 	} else if(!strncmp("ERROR", argv[TOK_CMD], 6))
-		snprintf(message, PIPE_BUF, "-!- error %s", argv[TOK_TEXT] ? argv[TOK_TE=
XT] : "unknown");
+		snprintf(msg, sizeof(msg), "-!- error %s",
+				argv[TOK_TEXT] ? argv[TOK_TEXT] : "unknown");
 	else if(!strncmp("JOIN", argv[TOK_CMD], 5)) {
 		if (argv[TOK_TEXT] !=3D NULL)
 			argv[TOK_CHAN] =3D argv[TOK_TEXT];
-		snprintf(message, PIPE_BUF, "-!- %s(%s) has joined %s", argv[TOK_NICKSRV=
], argv[TOK_USER], argv[TOK_CHAN]);
+		snprintf(msg, sizeof(msg), "-!- %s(%s) has joined %s",
+				argv[TOK_NICKSRV],argv[TOK_USER], argv[TOK_CHAN]);
 	} else if(!strncmp("PART", argv[TOK_CMD], 5)) {
-		snprintf(message, PIPE_BUF, "-!- %s(%s) has left %s", argv[TOK_NICKSRV],=
 argv[TOK_USER], argv[TOK_CHAN]);
+		snprintf(msg, sizeof(msg), "-!- %s(%s) has left %s",
+				argv[TOK_NICKSRV], argv[TOK_USER], argv[TOK_CHAN]);
 	} else if(!strncmp("MODE", argv[TOK_CMD], 5))
-		snprintf(message, PIPE_BUF, "-!- %s changed mode/%s -> %s %s", argv[TOK_=
NICKSRV], argv[TOK_CMD + 1] ? argv[TOK_CMD + 1] : "" , argv[TOK_CMD + 2]? a=
rgv[TOK_CMD + 2] : "", argv[TOK_CMD + 3] ? argv[TOK_CMD + 3] : "");
+		snprintf(msg, sizeof(msg), "-!- %s changed mode/%s -> %s %s",
+				argv[TOK_NICKSRV],
+				argv[TOK_CMD + 1] ? argv[TOK_CMD + 1] : "",
+				argv[TOK_CMD + 2] ? argv[TOK_CMD + 2] : "",
+				argv[TOK_CMD + 3] ? argv[TOK_CMD + 3] : "");
 	else if(!strncmp("QUIT", argv[TOK_CMD], 5))
-		snprintf(message, PIPE_BUF, "-!- %s(%s) has quit \"%s\"", argv[TOK_NICKS=
RV], argv[TOK_USER], argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
+		snprintf(msg, sizeof(msg), "-!- %s(%s) has quit \"%s\"",
+				argv[TOK_NICKSRV], argv[TOK_USER],
+				argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
 	else if(!strncmp("NICK", argv[TOK_CMD], 5))
-		snprintf(message, PIPE_BUF, "-!- %s changed nick to %s", argv[TOK_NICKSR=
V], argv[TOK_TEXT]);
+		snprintf(msg, sizeof(msg), "-!- %s changed nick to %s",
+				argv[TOK_NICKSRV], argv[TOK_TEXT]);
 	else if(!strncmp("TOPIC", argv[TOK_CMD], 6))
-		snprintf(message, PIPE_BUF, "-!- %s changed topic to \"%s\"", argv[TOK_N=
ICKSRV], argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
+		snprintf(msg, sizeof(msg), "-!- %s changed topic to \"%s\"",
+				argv[TOK_NICKSRV],
+				argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
 	else if(!strncmp("KICK", argv[TOK_CMD], 5))
-		snprintf(message, PIPE_BUF, "-!- %s kicked %s (\"%s\")", argv[TOK_NICKSR=
V], argv[TOK_ARG], argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
+		snprintf(msg, sizeof(msg), "-!- %s kicked %s (\"%s\")",
+				argv[TOK_NICKSRV], argv[TOK_ARG],
+				argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
 	else if(!strncmp("NOTICE", argv[TOK_CMD], 7))
-		snprintf(message, PIPE_BUF, "-!- \"%s\")", argv[TOK_TEXT] ? argv[TOK_TEX=
T] : "");
+		snprintf(msg, sizeof(msg), "-!- \"%s\")",
+				argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
 	else if(!strncmp("PRIVMSG", argv[TOK_CMD], 8))
-		snprintf(message, PIPE_BUF, "<%s> %s", argv[TOK_NICKSRV], argv[TOK_TEXT]=
 ? argv[TOK_TEXT] : "");
+		snprintf(msg, sizeof(msg), "<%s> %s", argv[TOK_NICKSRV],
+				argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
+
 	if(!argv[TOK_CHAN] || !strncmp(argv[TOK_CHAN], nick, strlen(nick)))
-		print_out(argv[TOK_NICKSRV], message);
+		print_out(argv[TOK_NICKSRV], msg);
 	else
-		print_out(argv[TOK_CHAN], message);
+		print_out(argv[TOK_CHAN], msg);
 }
=20
-static int read_line(int fd, size_t res_len, char *buf) {
+static int
+read_line(int fd, char *buf, size_t bufsiz) {
 	size_t i =3D 0;
 	char c =3D 0;
-	do {
+
+	for(i =3D 0; c !=3D '\n' && i < bufsiz; i++) {
 		if(read(fd, &c, sizeof(char)) !=3D sizeof(char))
 			return -1;
-		buf[i++] =3D c;
+		buf[i] =3D c;
 	}
-	while(c !=3D '\n' && i < res_len);
-	buf[i - 1] =3D 0;			/* eliminates '\n' */
+	if(i > 0 && i < bufsiz)
+		buf[i - 1] =3D 0; /* eliminates '\n' */
 	return 0;
 }
=20
-static void handle_channels_input(Channel *c) {
-	static char buf[PIPE_BUF];
-	if(read_line(c->fd, PIPE_BUF, buf) =3D=3D -1) {
+static void
+handle_channels_input(Channel *c) {
+	char buf[BUFSIZ] =3D "";
+	int fd;
+
+	if(read_line(c->fd, buf, sizeof(buf)) =3D=3D -1) {
 		close(c->fd);
-		int fd =3D open_channel(c->name);
+		fd =3D open_channel(c->name);
 		if(fd !=3D -1)
 			c->fd =3D fd;
 		else
_AT_@ -399,27 +449,28 @@ static void handle_channels_input(Channel *c) {
 	proc_channels_input(c, buf);
 }
=20
-static void handle_server_output() {
-	static char buf[PIPE_BUF];
-	if(read_line(irc, PIPE_BUF, buf) =3D=3D -1) {
-		perror("ii: remote host closed connection");
-		exit(EXIT_FAILURE);
-	}
-	proc_server_cmd(buf);
+static void
+handle_server_output(int fd) {
+	char buf[BUFSIZ] =3D "";
+
+	if(read_line(fd, buf, sizeof(buf)) =3D=3D -1)
+		eprintf("remote host closed connection:");
+	proc_server_cmd(fd, buf);
 }
=20
-static void run() {
+static void
+run(int fd, char *host) {
 	Channel *c;
 	int r, maxfd;
 	fd_set rd;
 	struct timeval tv;
-	char ping_msg[512];
+	char ping_msg[IRC_MSG_MAX];
=20
 	snprintf(ping_msg, sizeof(ping_msg), "PING %s\r\n", host);
 	for(;;) {
 		FD_ZERO(&rd);
-		maxfd =3D irc;
-		FD_SET(irc, &rd);
+		maxfd =3D fd;
+		FD_SET(fd, &rd);
 		for(c =3D channels; c; c =3D c->next) {
 			if(maxfd < c->fd)
 				maxfd =3D c->fd;
_AT_@ -432,18 +483,17 @@ static void run() {
 		if(r < 0) {
 			if(errno =3D=3D EINTR)
 				continue;
-			perror("ii: error on select()");
-			exit(EXIT_FAILURE);
+			eprintf("error on select():");
 		} else if(r =3D=3D 0) {
 			if(time(NULL) - last_response >=3D PING_TIMEOUT) {
 				print_out(NULL, "-!- ii shutting down: ping timeout");
 				exit(EXIT_FAILURE);
 			}
-			write(irc, ping_msg, strlen(ping_msg));
+			write(fd, ping_msg, strnlen(ping_msg, sizeof(ping_msg)));
 			continue;
 		}
-		if(FD_ISSET(irc, &rd)) {
-			handle_server_output();
+		if(FD_ISSET(fd, &rd)) {
+			handle_server_output(fd);
 			last_response =3D time(NULL);
 		}
 		for(c =3D channels; c; c =3D c->next)
_AT_@ -452,42 +502,61 @@ static void run() {
 	}
 }
=20
-int main(int argc, char *argv[]) {
-	int i;
-	unsigned short port =3D SERVER_PORT;
-	struct passwd *spw =3D getpwuid(getuid());
-	char *key =3D NULL, *fullname =3D NULL;
+int
+main(int argc, char *argv[]) {
+	struct passwd *spw;
+	long port =3D SERVER_PORT;
+	char *key =3D NULL, *fullname =3D NULL, *host =3D "";
 	char prefix[_POSIX_PATH_MAX];
+	int ircfd;
=20
-	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 <=3D 1 || (argc =3D=3D 2 && argv[1][0] =3D=3D '-' && argv[1][1] =
=3D=3D 'h')) usage();
-
-	for(i =3D 1; (i + 1 < argc) && (argv[i][0] =3D=3D '-'); i++) {
-		switch (argv[i][1]) {
-			case 'i': snprintf(prefix,sizeof(prefix),"%s", argv[++i]); break;
-			case 's': host =3D argv[++i]; break;
-			case 'p': port =3D strtol(argv[++i], NULL, 10); break;
-			case 'n': snprintf(nick,sizeof(nick),"%s", argv[++i]); break;
-			case 'k': key =3D getenv(argv[++i]); break;
-			case 'f': fullname =3D argv[++i]; break;
-			default: usage(); break;
-		}
-	}
-	irc =3D tcpopen(port);
-	if(!snprintf(path, sizeof(path), "%s/%s", prefix, host)) {
-		fputs("ii: path to irc directory too long\n", stderr);
-		exit(EXIT_FAILURE);
-	}
+	/* use nickname of user and homedir for irc running ii by default */
+	if(!(spw =3D getpwuid(getuid())))
+		eprintf("getpwuid() failed:");
+
+	strlcpy(nick, spw->pw_name, sizeof(nick));
+	snprintf(prefix, sizeof(prefix), "%s/irc", spw->pw_dir);
+
+	ARGBEGIN {
+		case 'h':
+		case 'v':
+			usage();
+			break;
+		case 'i':
+			strlcpy(prefix, EARGF(usage()), sizeof(prefix));
+			break;
+		case 's':
+			host =3D EARGF(usage());
+			break;
+		case 'p':
+			port =3D estrtol(EARGF(usage()),  10);
+			break;
+		case 'n':
+			strlcpy(nick, EARGF(usage()), sizeof(nick));
+			break;
+		case 'k':
+			if(!(key =3D getenv(EARGF(usage()))))
+				eprintf("can't get password from $%s", key);
+			break;
+		case 'f':
+			fullname =3D EARGF(usage());
+			break;
+		default:
+			usage();
+			break;
+	} ARGEND;
+
+	if (argc < 1 || !*host)
+		usage();
+
+	ircfd =3D tcpopen(host, port);
+	if(snprintf(path, sizeof(path), "%s/%s", prefix, host) <=3D 0)
+		eprintf("path to irc directory too long");
 	create_dirtree(path);
=20
 	add_channel(""); /* master channel */
-	login(key, fullname);
-	run();
+	login(ircfd, host, key, fullname ? fullname : nick);
+	run(ircfd, host);
=20
 	return EXIT_SUCCESS;
 }
--=20
2.4.10
--Multipart=_Mon__9_May_2016_17_21_10_+0200_I.6cpFVydhq75aaE
Content-Type: text/x-diff;
 name="0009-check-if-fullname-is-set-and-non-empty.patch"
Content-Disposition: attachment;
 filename="0009-check-if-fullname-is-set-and-non-empty.patch"
Content-Transfer-Encoding: 7bit
Received on Mon Sep 17 2001 - 00:00:00 CEST

This archive was generated by hypermail 2.3.0 : Mon May 09 2016 - 17:24:22 CEST