---
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