mirror of
https://github.com/sys-fs/tubes
synced 2025-02-19 23:13:33 -05:00
Restructure of the code for clarity.
This commit is contained in:
parent
eb2a0124ce
commit
c0d9536605
8
Makefile
8
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
|
||||
|
8
tubes.1
8
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 <audiobarrier@openmailbox.org>.
|
||||
|
235
tubes.c
235
tubes.c
@ -1,7 +1,4 @@
|
||||
/**
|
||||
* See the LICENSE file for licensing information
|
||||
*/
|
||||
|
||||
/* See the LICENSE file for licensing information */
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
@ -19,33 +16,92 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#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;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
snprintf(path, 100, "%s/%s", home, file);
|
||||
mknod(path, 0 | 0666, 0);
|
||||
fp = fopen(path, "w");
|
||||
|
||||
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);
|
||||
mkfifo(buf, 0660);
|
||||
if ((out = open(buf, O_RDWR)) < 0) {
|
||||
fprintf(log, "out: error on open()\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
atexit(mop);
|
||||
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user