From c0d9536605400cf6b05fef5c147630f00295c28c Mon Sep 17 00:00:00 2001 From: Thomas Mannay Date: Fri, 23 Sep 2016 02:57:44 +0100 Subject: [PATCH] Restructure of the code for clarity. --- Makefile | 8 +-- tubes.1 | 8 +-- tubes.c | 235 ++++++++++++++++++++++++++++++--------------------------------- 3 files changed, 119 insertions(+), 132 deletions(-) diff --git a/Makefile b/Makefile index 3794748..5b78c5e 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,11 @@ CC=cc -override CFLAGS+=-Wall -Wpedantic -O2 +override CFLAGS+=-Wall -pedantic -O2 LDFLAGS=-lcrypto -lssl PREFIX=/usr/local -MANPREFIX=${PREFIX}/man -#Ubuntu uses the one below -#MANPREFIX=${PREFIX}/share/man +MANPREFIX=${PREFIX}/share/man it: - ${CC} tubes.c ${CFLAGS} ${LDFLAGS} -o tubes + ${CC} -s tubes.c ${CFLAGS} ${LDFLAGS} -o tubes install: it echo installing executable to ${DESTDIR}${PREFIX}/bin diff --git a/tubes.1 b/tubes.1 index 6c420de..d8d8d29 100644 --- a/tubes.1 +++ b/tubes.1 @@ -1,4 +1,4 @@ -.TH TUBES 1 tubes-1.1.0 +.TH TUBES 1 tubes-1.1.1 .SH NAME tubes \- irc pipes .SH SYNOPSIS @@ -28,13 +28,13 @@ Use a host other than the default (chat.freenode.net) Use a port other than the default (6667) .TP .B \-v -Prints version information and exits +Print version information and exit .SH FILES The incoming and outgoing FIFO buffers are stored in /tmp and are named for the server tubes is connected to with .in or .out appended to the end. -~/.tubes.err is used to store a string explaining why tubes has exited, if any. +~/.tubes.err is used to store an error string if tubes exits with -1. .SH RETURN VALUE -Returns -1 when something has gone wrong or 0 on success. +Returns -1 on error, 0 on success. .SH AUTHOR Copyright \(co 2016 Thomas Mannay . diff --git a/tubes.c b/tubes.c index 831fc1b..018e41d 100644 --- a/tubes.c +++ b/tubes.c @@ -1,7 +1,4 @@ -/** - * See the LICENSE file for licensing information - */ - +/* See the LICENSE file for licensing information */ #include #include #include @@ -19,33 +16,92 @@ #include #define PING_TIMEOUT 240 -#define VERSION "1.1.0" +#define VERSION "1.1.1" -static char *server = "chat.freenode.net"; -static char port[6] = "6667"; -static FILE *log; static SSL_CTX *ctx; static SSL *ssl; +static char *server = "chat.freenode.net"; +static int port = 6667; +static FILE *log; static short use_ssl = 0; static unsigned int last_response; -/* connect to irc server */ -int dial(char *server, char *port); -/* get SSL up and running */ -int sslify(int *sockfd); -/* set up the error logging file */ -FILE *slog(char *file); -/* mop up so we exit cleanly */ -void mop(void); +FILE * +slog(char *file) +{ + const char *home = getenv("HOME"); + char path[100]; + FILE *fp; + + snprintf(path, 100, "%s/%s", home, file); + mknod(path, 0 | 0666, 0); + fp = fopen(path, "w"); -int main(int argc, char **argv) + return fp; +} + +int +dial(char *server, int port) +{ + int sockfd, err; + struct addrinfo hints, *serv; + + char tmp[8]; + snprintf(tmp, 8, "%d", port); + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + if ((err = getaddrinfo(server, tmp, &hints, &serv)) != 0) { + fprintf(log, "getaddrinfo: %s\n", gai_strerror(err)); + return -1; + } else if ((sockfd = socket(serv->ai_family, serv->ai_socktype, + serv->ai_protocol)) == -1) { + fprintf(log, "tubes: error on socket()\n"); + return -1; + } else if (connect(sockfd, serv->ai_addr, serv->ai_addrlen) == -1) { + fprintf(log, "tubes: error on connect().\n"); + close(sockfd); + return -1; + } + freeaddrinfo(serv); + + return sockfd; +} + +int +sslify(int *sockfd) +{ + int r; + + SSL_library_init(); + SSL_load_error_strings(); + + ctx = SSL_CTX_new(SSLv23_client_method()); + SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 + | SSL_OP_SINGLE_DH_USE); + ssl = SSL_new(ctx); + SSL_set_fd(ssl, *sockfd); + SSL_set_connect_state(ssl); + + if ((r = SSL_connect(ssl)) < 1) { + fprintf(log, "sslify: %s\n", strerror(SSL_get_error(ssl, r))); + SSL_CTX_free(ctx); + return -1; + } + + return 0; +} + +int +main(int argc, char **argv) { int sockfd, in, out; int maxfd; fd_set rd; struct timeval tv; char buf[512]; - int i, r; + int i, r, status; for (i = 1; i < argc; i++) { char c = argv[i][1]; @@ -54,7 +110,7 @@ int main(int argc, char **argv) switch (c) { case 'S': use_ssl = 1; - snprintf(port, 6, "6697"); + port = 6697; break; case 's': if (++i < argc) @@ -62,47 +118,44 @@ int main(int argc, char **argv) break; case 'p': if (++i < argc) - snprintf(port, 6, "%s", argv[i]); + port = atoi(argv[i]); break; - case 'v': - fprintf(stderr, "tubes-%s © 2016 Thomas Mannay\n", VERSION); - exit(0); + case 'v': /* fall through */ default: - fprintf(stderr, - "usage: tubes [-S] [-s server] [-p port] [-v]\n"); + fprintf(stderr, "tubes-%s © 2016 Thomas Mannay\n", VERSION); exit(0); } } if ((log = slog(".tubes.err")) == NULL) { - fprintf(stderr, "tubes: error on slog()"); + fprintf(stderr, "error on slog()"); exit(-1); } - if (daemon(0, 0) == -1) { - fprintf(log, "tubes: error on daemon()\n"); + fprintf(log, "error on daemon()\n"); exit(-1); } - - if ((sockfd = dial(server, port)) == -1) exit(-1); - if (use_ssl && sslify(&sockfd) == -1) exit(-1); snprintf(buf, 512, "/tmp/%s.in", server); unlink(buf); - mknod(buf, S_IFIFO | 0660, 0); - in = open(buf, O_RDWR | O_NONBLOCK); + mkfifo(buf, 0660); + if ((in = open(buf, O_RDWR | O_NONBLOCK)) < 0) { + fprintf(log, "in: error on open()\n"); + exit(-1); + } snprintf(buf, 512, "/tmp/%s.out", server); unlink(buf); - mknod(buf, S_IFIFO | 0660, 0); - out = open(buf, O_RDWR); - - atexit(mop); + mkfifo(buf, 0660); + if ((out = open(buf, O_RDWR)) < 0) { + fprintf(log, "out: error on open()\n"); + exit(-1); + } - for (;;) { + for (status = 0;;) { FD_ZERO(&rd); maxfd = (out >= sockfd) ? out : sockfd; FD_SET(out, &rd); @@ -114,13 +167,13 @@ int main(int argc, char **argv) if (r < 0) { if (errno == EINTR) continue; - fprintf(log, "tubes: error on select()\n"); - exit(-1); - } else if (r == 0) { - if (time(NULL) - last_response >= PING_TIMEOUT) { - fprintf(log, "tubes: ping timeout\n"); - exit(-1); - } + fprintf(log, "error on select()\n"); + status = -1; + break; + } else if (r == 0 && last_response-time(NULL) >= PING_TIMEOUT) { + fprintf(log, "ping timeout\n"); + status = -1; + break; } if (FD_ISSET(out, &rd)) if ((i = read(out, buf, sizeof(buf))) > 0) { @@ -144,91 +197,26 @@ int main(int argc, char **argv) i = recv(sockfd, buf, sizeof(buf), 0); if (i != -1) { if (i == 0) { - fprintf(log, "tubes: connection closed\n"); - close(sockfd); - if (use_ssl) - SSL_CTX_free(ctx); - exit(0); + fprintf(log, "connection closed\n"); + break; } buf[i] = 0; if (write(in, buf, strlen(buf)) < 0) { if (errno == EINTR) continue; - fprintf(log, "tubes: error on write()\n"); - exit(-1); + fprintf(log, "error on write()\n"); + status = -1; + break; } last_response = time(NULL); } } } - return 0; -} - -int dial(char *server, char *port) -{ - int sockfd, err; - struct addrinfo hints, *serv; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - if ((err = getaddrinfo(server, port, &hints, &serv)) != 0) { - fprintf(log, "getaddrinfo: %s\n", gai_strerror(err)); - return -1; - } else if ((sockfd = socket(serv->ai_family, serv->ai_socktype, - serv->ai_protocol)) == -1) { - fprintf(log, "tubes: error on socket()\n"); - return -1; - } else if (connect(sockfd, serv->ai_addr, serv->ai_addrlen) == -1) { - fprintf(log, "tubes: error on connect().\n"); - close(sockfd); - return -1; - } - freeaddrinfo(serv); - - return sockfd; -} - -int sslify(int *sockfd) -{ - int r; - - SSL_library_init(); - SSL_load_error_strings(); - - ctx = SSL_CTX_new(SSLv23_client_method()); - SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 - | SSL_OP_SINGLE_DH_USE); - ssl = SSL_new(ctx); - SSL_set_fd(ssl, *sockfd); - SSL_set_connect_state(ssl); - - if ((r = SSL_connect(ssl)) < 1) { - fprintf(log, "tubes: %s\n", strerror(SSL_get_error(ssl, r))); - SSL_CTX_free(ctx); - return -1; - } - - return 0; -} - -FILE *slog(char *file) -{ - const char *home = getenv("HOME"); - char path[100]; - FILE *fp; - - snprintf(path, 100, "%s/%s", home, file); - mknod(path, 0 | 0666, 0); - fp = fopen(path, "w"); - - return fp; -} - -void mop(void) -{ - char str[512]; + close(sockfd); + close(in); + close(out); + fclose(log); ERR_free_strings(); EVP_cleanup(); @@ -236,8 +224,9 @@ void mop(void) SSL_free(ssl); SSL_CTX_free(ctx); - snprintf(str, 512, "/tmp/%s.in", server); - unlink(str); - snprintf(str, 512, "/tmp/%s.out", server); - unlink(str); + snprintf(buf, 512, "/tmp/%s.in", server); + unlink(buf); + snprintf(buf, 512, "/tmp/%s.out", server); + unlink(buf); + exit(status); }