diff options
Diffstat (limited to 'send')
-rw-r--r-- | send/Makefile | 24 | ||||
-rw-r--r-- | send/arg.h | 63 | ||||
-rwxr-xr-x | send/send | bin | 0 -> 24680 bytes | |||
-rw-r--r-- | send/send.c | 127 | ||||
-rw-r--r-- | send/send.o | bin | 0 -> 14112 bytes | |||
-rwxr-xr-x | send/sendd | bin | 0 -> 25568 bytes | |||
-rw-r--r-- | send/sendd.c | 207 | ||||
-rw-r--r-- | send/sendd.o | bin | 0 -> 16528 bytes | |||
-rw-r--r-- | send/users.c | 13 | ||||
-rw-r--r-- | send/users.h | 1 | ||||
-rw-r--r-- | send/users.o | bin | 0 -> 6984 bytes | |||
-rw-r--r-- | send/util.h | 27 |
12 files changed, 462 insertions, 0 deletions
diff --git a/send/Makefile b/send/Makefile new file mode 100644 index 0000000..100e6df --- /dev/null +++ b/send/Makefile @@ -0,0 +1,24 @@ +CFLAGS = -ggdb -D_GNU_SOURCE +LIBS = `pkg-config --libs openssl` + +SRC = sendd.c send.c users.c +OBJ = $(SRC:.c=.o) + +all: sendd + +.c.o: + cc -c ${CFLAGS} $< + +sendd: sendd.o send.o users.o + cc sendd.o users.o -o sendd ${CFLAGS} ${LIBS} + cc send.o users.o -o send ${CFLAGS} ${LIBS} + +install: sendd + cp sendd send addevent delevent sortevents agenda /usr/local/bin/ + +uninstall: + rm /usr/local/bin/sendd + rm /usr/local/bin/send + +clean: + rm -rf *.o sendd send diff --git a/send/arg.h b/send/arg.h new file mode 100644 index 0000000..4df77a7 --- /dev/null +++ b/send/arg.h @@ -0,0 +1,63 @@ +/* + * Copy me if you can. + * by 20h + */ + +#ifndef ARG_H__ +#define ARG_H__ + +extern char *argv0; + +/* use main(int argc, char *argv[]) */ +#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\ + argv[0] && argv[0][1]\ + && argv[0][0] == '-';\ + argc--, argv++) {\ + char argc_;\ + char **argv_;\ + int brk_;\ + if (argv[0][1] == '-' && argv[0][2] == '\0') {\ + argv++;\ + argc--;\ + break;\ + }\ + for (brk_ = 0, argv[0]++, argv_ = argv;\ + argv[0][0] && !brk_;\ + argv[0]++) {\ + if (argv_ != argv)\ + break;\ + argc_ = argv[0][0];\ + switch (argc_) + +/* Handles obsolete -NUM syntax */ +#define ARGNUM case '0':\ + case '1':\ + case '2':\ + case '3':\ + case '4':\ + case '5':\ + case '6':\ + case '7':\ + case '8':\ + case '9' + +#define ARGEND }\ + } + +#define ARGC() argc_ + +#define ARGNUMF(base) (brk_ = 1, estrtol(argv[0], (base))) + +#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\ + ((x), abort(), (char *)0) :\ + (brk_ = 1, (argv[0][1] != '\0')?\ + (&argv[0][1]) :\ + (argc--, argv++, argv[0]))) + +#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\ + (char *)0 :\ + (brk_ = 1, (argv[0][1] != '\0')?\ + (&argv[0][1]) :\ + (argc--, argv++, argv[0]))) + +#endif diff --git a/send/send b/send/send Binary files differnew file mode 100755 index 0000000..0cb238c --- /dev/null +++ b/send/send diff --git a/send/send.c b/send/send.c new file mode 100644 index 0000000..aae33c2 --- /dev/null +++ b/send/send.c @@ -0,0 +1,127 @@ +#include <sys/socket.h> +#include <arpa/inet.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <unistd.h> +#include <string.h> +#include <time.h> + +#include "util.h" +#include "arg.h" +#include "users.h" + +FILE *fout; +char *argv0; + +static int +init_client(char *host, int port) { + int s = socket(AF_INET, SOCK_STREAM, 0); + + struct sockaddr_in addr = {AF_INET, htons(port)}; + if (!inet_pton(AF_INET, host, &addr.sin_addr)) + error("couldn't resolve host"); + + if (connect(s, (struct sockaddr *)&addr, sizeof(addr))) + error("Failed to connect"); + + return s; +} + +static void +stop_client(int s) { + close(s); +} + +static void +connect_client(int s, char *nick) { + char *msg; + int len = asprintf(&msg, "connect %s", nick); + send(s, msg, len, 0); + free(msg); +} + +static void +send_msg(int s, char *contents) { + char *msg; + time_t t = time(NULL); + + int len = asprintf(&msg, "msg %.5d %s", strlen(contents), contents); + + send(s, msg, len, 0); + send(s, &t, sizeof(time_t), 0); + free(msg); +} + +static void +resend_msg(int s, char *contents) { + char *msg; + time_t t = time(NULL); + + int len = asprintf(&msg, "remsg %.5d %s", strlen(contents), contents); + + send(s, msg, len, 0); + send(s, &t, sizeof(time_t), 0); + free(msg); +} + +static void +usage() { + fprintf(stderr, "send [-h host] [-p port] [-P password] [-n nick] -m msg\n"); + exit(1); +} + +static int +recv_response(int s) { + int i; + recv(s, &i, sizeof(int), 0); + return i; +} + +int +main(int argc, char **argv) { + char *host = "127.0.0.1"; + int port = 1543; + char *nick = getenv("SENDUSER"); + char *pass = getenv("SENDPASS"); + char *msg = NULL; + + ARGBEGIN { + case 'h': + host = EARGF(usage()); + break; + case 'p': + port = atoi(EARGF(usage())); + break; + case 'P': + pass = EARGF(usage()); + break; + case 'n': + nick = EARGF(usage()); + break; + case 'm': + msg = EARGF(usage()); + break; + } ARGEND; + + if (!msg) + usage(); + if (!nick) + error("failed to get nickname, use -n!"); + if (!pass) + error("failed to get password, use -p!"); + + int s = init_client(host, port); + connect_client(s, nick); + + int msg_hash = make_mhash(msg); + + send_msg(s, msg); + + while (recv_response(s) != msg_hash) + resend_msg(s, msg); + + printf("valid msg sent\n"); + + stop_client(s); +} diff --git a/send/send.o b/send/send.o Binary files differnew file mode 100644 index 0000000..2be577e --- /dev/null +++ b/send/send.o diff --git a/send/sendd b/send/sendd Binary files differnew file mode 100755 index 0000000..cf79a9e --- /dev/null +++ b/send/sendd diff --git a/send/sendd.c b/send/sendd.c new file mode 100644 index 0000000..1b0c34e --- /dev/null +++ b/send/sendd.c @@ -0,0 +1,207 @@ +#include <sys/socket.h> +#include <arpa/inet.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <unistd.h> +#include <string.h> +#include <netinet/in.h> +#include <netinet/tcp.h> +#include <ctype.h> +#include <stdbool.h> + +#include "util.h" + +/* + * CONNECT MSG: "connect NAME" + * SEND MSG: "msg XXXXX CONTENTS TIME" + * VALID MSG: 0 + * INVALID MSG: 1 + */ + +typedef struct client { + char *name; + int fd; + bool connected; +} client; + +typedef struct msg { + client *sender; + char *contents; + time_t time; +} msg; + +FILE *fout; +int VALID = 0; +int INVALID = 1; + +static int +init_daemon(int port) { + int s = socket(AF_INET, SOCK_STREAM, 0); + + struct sockaddr_in addr = {AF_INET, htons(port), INADDR_ANY}; + + if (bind(s, (struct sockaddr *)&addr, sizeof(addr))) + error("Failed to bind"); + + int flags = 10; + if (setsockopt(s, SOL_TCP, TCP_KEEPIDLE, (void *)&flags, sizeof(flags))) + error("Couldn't set socket opts"); + + flags = 5; + if (setsockopt(s, SOL_TCP, TCP_KEEPCNT, (void *)&flags, sizeof(flags))) + error("Couldn't set socket opts"); + + flags = 5; + if (setsockopt(s, SOL_TCP, TCP_KEEPINTVL, (void *)&flags, sizeof(flags))) + error("Couldn't set socket opts"); + + listen(s, 10); + return s; +} + +static void +stop_daemon(int s) { + close(s); +} + +static client * +accept_client(int s) { + client *c = malloc(sizeof(client)); + c->fd = accept(s, NULL, NULL); + + char buf[256] = {0}; + char *Pbuf = buf; + int n = recv(c->fd, buf, 256, 0); + if (n <= 0) { + warn("Client hungup"); + close(c->fd); + return NULL; + } + if (n <= 8) { + warn("Malformed connect msg"); + close(c->fd); + return NULL; + } + + if (memcmp(buf, "connect ", 8) != 0) { + warn("Malformed connect msg"); + close(c->fd); + return NULL; + } + + Pbuf += 8; + c->name = strdup(Pbuf); + c->connected = true; + + return c; +} + +static void +close_client(client *c) { + close(c->fd); + free(c->name); + free(c); +} + +static msg* +recv_msg(client *c) { + char buf[11] = {0}; + char *Pbuf = buf + 4; + int n = recv(c->fd, buf, 10, 0); + if (n <= 0) { + warn("Client hungup"); + close(c->fd); + c->connected = false; + return NULL; + } + if (n < 10) { + warn("Malformed msg msg"); + send(c->fd, &INVALID, sizeof(int), 0); + return NULL; + } + if (memcmp(buf, "msg ", 4) != 0) { + warn("Malformed msg msg"); + send(c->fd, &INVALID, sizeof(int), 0); + return NULL; + } + for (int i = 4; buf[i] != 0 && i < 9; i++) { + if (!isdigit(buf[i])) { + warn("Malformed msg msg"); + send(c->fd, &INVALID, sizeof(int), 0); + return NULL; + } + } + + int len = atoi(Pbuf); + char *contents = malloc(len); + memset(contents, 0, len); + + n = recv(c->fd, contents, len, 0); + if (n <= 0) { + warn("Client hungup"); + c->connected = false; + close(c->fd); + return NULL; + } + + msg *m = malloc(sizeof(msg)); + m->sender = c; + m->contents = contents; + + time_t t; + n = recv(c->fd, &t, sizeof(time_t), 0); + if (n <= 0) { + warn("Client hungup"); + c->connected = false; + close(c->fd); + return NULL; + } + m->time = t; + + send(c->fd, &VALID, sizeof(int), 0); + + return m; +} + +static void +free_msg(msg *m) { + free(m->contents); + free(m); +} + +static void +msg_loop(client *c) { + msg *m; + while (c->connected && (m = recv_msg(c))) { + fprintf(fout, "%lld:%s:%s\n", m->time, m->sender->name, m->contents); + free_msg(m); + } + close_client(c); + exit(0); +} + +int +main(int argc, char **argv) { + char *out; + if (argc <= 1) + out = "/dev/stdout"; + else + out = argv[1]; + + if (!(fout = fopen(out, "w"))) + error("Couldn't open outfile"); + + int s = init_daemon(1543); + + pid_t pid; + for (;;) { + client *c = accept_client(s); + if ((pid = fork()) == 0) + msg_loop(c); + else + continue; + } + + stop_daemon(s); +} diff --git a/send/sendd.o b/send/sendd.o Binary files differnew file mode 100644 index 0000000..0d37b2e --- /dev/null +++ b/send/sendd.o diff --git a/send/users.c b/send/users.c new file mode 100644 index 0000000..7b161f9 --- /dev/null +++ b/send/users.c @@ -0,0 +1,13 @@ +#include <stdio.h> +#include <stdlib.h> +#include <openssl/sha.h> + +#include "util.h" + +char * +make_userid(char *nick, char *pass) { + char *prehash, *hash; + int len = asprintf(&prehash, "%s:%s", nick, pass); + hash = SHA1(prehash, len, NULL); + return hash; +} diff --git a/send/users.h b/send/users.h new file mode 100644 index 0000000..47577fb --- /dev/null +++ b/send/users.h @@ -0,0 +1 @@ +char *make_userid(char *nick, char *pass); diff --git a/send/users.o b/send/users.o Binary files differnew file mode 100644 index 0000000..131ef6f --- /dev/null +++ b/send/users.o diff --git a/send/util.h b/send/util.h new file mode 100644 index 0000000..5f1a698 --- /dev/null +++ b/send/util.h @@ -0,0 +1,27 @@ +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> + +static void +warn(const char *msg) { + if (errno != 0) + perror(msg); + else + fprintf(stderr, "error: %s\n", msg); +} + +static void +error(const char *msg) { + warn(msg); + exit(1); +} + +static int +make_mhash(char *m) { + int hash = 0; + while (*m != 0) { + hash += *m; + m++; + } + return hash; +} |