commit 1dfd648a8a904ec313daf0a6a9ff4c591db281c8
parent f87b7718b8506a257c3518319e89ebd06367ee5c
Author: William Casarin <jb55@jb55.com>
Date: Sun, 5 Jul 2020 21:43:25 -0700
client/server
Signed-off-by: William Casarin <jb55@jb55.com>
Diffstat:
7 files changed, 167 insertions(+), 10 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,7 +1,7 @@
CFLAGS = -Wno-error=unused-function -O1 -g -std=c89 -Wall -Wextra -Werror -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations -Wdeclaration-after-statement
-OBJS = io.o parse.o cursor.o describe.o
+OBJS = io.o parse.o cursor.o describe.o serve.o client.o
protoverse: protoverse.c $(OBJS)
$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@
diff --git a/client.c b/client.c
@@ -0,0 +1,54 @@
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "client.h"
+
+int inet_aton(const char *cp, struct in_addr *inp);
+
+int protoverse_connect(const char *server_ip_str, int port)
+{
+ int sockfd;
+ struct in_addr server_in_addr;
+ struct sockaddr_in server_addr;
+ static char buf[2048];
+ ssize_t sent;
+ const char msg[] = "hello, world";
+
+ if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
+ printf("socket creation failed: %s\n", strerror(errno));
+ return 0;
+ }
+
+ if (inet_aton(server_ip_str, &server_in_addr) == 0) {
+ printf("could not parse server ip: %s\n", strerror(errno));
+ return 0;
+ }
+
+ server_addr.sin_family = AF_INET;
+ server_addr.sin_port = port == 0 || port == -1 ? 1988 : port;
+ server_addr.sin_addr = server_in_addr;
+
+ strncpy(buf, msg, sizeof(buf));
+
+ printf("sending '%s' to %s\n", msg, server_ip_str);
+ sent = sendto(sockfd, buf, sizeof(msg), MSG_CONFIRM,
+ (struct sockaddr*)&server_addr,
+ sizeof(server_addr));
+
+ printf("does this work?\n");
+
+ if (sent != sizeof(msg)) {
+ printf("expected to send %ld, sent %ld instead\n",
+ sizeof(msg), sent);
+ exit(1);
+ }
+
+ return 1;
+}
diff --git a/client.h b/client.h
@@ -0,0 +1,7 @@
+
+#ifndef PROTOVERSE_CLIENT_H
+#define PROTOVERSE_CLIENT_H
+
+int protoverse_connect(const char *server_ip_str, int port);
+
+#endif /* PROTOVERSE_CLIENT_H */
diff --git a/protocol.h b/protocol.h
@@ -0,0 +1 @@
+
diff --git a/protoverse.c b/protoverse.c
@@ -2,8 +2,13 @@
#include "io.h"
#include "parse.h"
#include "describe.h"
+#include "serve.h"
+#include "client.h"
#include <assert.h>
+#include <string.h>
+
+#define streq(a, b) strcmp(a,b) == 0
static void print_all_cells(struct parser *parser)
{
@@ -108,28 +113,56 @@ static int describe(struct parser *parser, u16 root_cell)
make_cursor((u8*)strbuf, (u8*)strbuf + sizeof(strbuf), &strs);
- describe_cells(cell, parser, &strs, 2, 0);
+ describe_cells(cell, parser, &strs, 10, 0);
printf("\n\ndescription\n-----------\n\n%s\n", strbuf);
return 1;
}
+static int usage(void)
+{
+ printf("usage: protoverse <command> [args]\n\n");
+ printf(" COMMANDS\n\n");
+ printf(" parse file.space\n");
+ printf(" serve file.space\n");
+ printf(" client\n");
+
+ return 1;
+}
+
int main(int argc, const char *argv[])
{
const char *space;
+ const char *cmd;
struct parser parser;
u16 root;
int ok;
- space = argc == 2 ? argv[1] : "satoshis-citadel.space";
-
- ok = parse_file(&parser, space, &root);
- if (!ok) return 1;
-
- print_cell_tree(&parser, root, 0);
-
- describe(&parser, root);
+ if (argc < 2)
+ return usage();
+
+ cmd = argv[1];
+
+ if (streq(cmd, "parse")) {
+ if (argc != 3)
+ return usage();
+ space = argv[2];
+ ok = parse_file(&parser, space, &root);
+ if (!ok) return 1;
+
+ print_cell_tree(&parser, root, 0);
+
+ describe(&parser, root);
+ } else if (streq(cmd, "serve")) {
+ if (argc != 3)
+ return usage();
+ space = argv[2];
+ printf("serving protoverse on port 1988...\n");
+ protoverse_serve("127.0.0.1", 1988);
+ } else if (streq(cmd, "client")) {
+ protoverse_connect("127.0.0.1", 1988);
+ }
return 0;
}
diff --git a/serve.c b/serve.c
@@ -0,0 +1,55 @@
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "serve.h"
+
+int inet_aton(const char *cp, struct in_addr *inp);
+
+int protoverse_serve(const char *bind_addr_str, int port)
+{
+ int fd;
+ struct in_addr my_addr;
+ struct sockaddr_in bind_addr;
+ struct sockaddr addr;
+ socklen_t addrlen;
+ ssize_t recv_len;
+ static char buf[1024];
+ int err;
+
+ if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
+ printf("socket creation failed: %s\n", strerror(errno));
+ return 0;
+ }
+
+ if (inet_aton(bind_addr_str, &my_addr) == 0) {
+ printf("inet_aton failed: %s\n", strerror(errno));
+ return 0;
+ }
+
+ bind_addr.sin_family = AF_INET;
+ bind_addr.sin_port = port == 0 || port == -1 ? 1988 : port;
+ bind_addr.sin_addr = my_addr;
+
+ err = bind(fd, (struct sockaddr*)&bind_addr,
+ sizeof(bind_addr)) == -1;
+
+ if (err) {
+ printf("bind failed: %s\n", strerror(errno));
+ return 0;
+ }
+
+ while (1) {
+ recv_len = recvfrom(fd, buf, sizeof(buf), 0, &addr,
+ &addrlen);
+
+ printf("got '%.*s'\n", (int)recv_len, buf);
+ }
+}
+
+
diff --git a/serve.h b/serve.h
@@ -0,0 +1,7 @@
+
+#ifndef PROTOVERSE_SERVE_H
+#define PROTOVERSE_SERVE_H
+
+int protoverse_serve(const char *bind, int port);
+
+#endif