From 8f61a4a76806a3788f817d8833ac77a34c76484f Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Sat, 1 Aug 2020 10:31:15 +0300 Subject: [PATCH] flist request --- client/src/main.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++-- server/src/main.c | 1 + src/proto.c | 30 ++++++++++++++++++++++++++ src/proto.h | 3 +++ 4 files changed, 94 insertions(+), 2 deletions(-) diff --git a/client/src/main.c b/client/src/main.c index a4c3cf5..b76ef50 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -7,12 +7,18 @@ #include #include #include +#include "proto.h" + int main(int argc, char **argv) { - int s; + int i, s, sz; struct sockaddr_in addr; struct hostent *host; + char *resp, *ptr; + int resp_size, pending; + struct proto_flist *flist; + char buf[256]; if((s = socket(PF_INET, SOCK_STREAM, 0)) == -1) { perror("failed to create socket"); @@ -27,13 +33,65 @@ int main(int argc, char **argv) memset(&addr, 0, sizeof addr); addr.sin_family = AF_INET; addr.sin_port = htons(64357); - addr.sin_addr.s_addr = inet_addr(host->h_addr); + addr.sin_addr.s_addr = *(in_addr_t*)host->h_addr; + + printf("Connecting to %s ...\n", inet_ntoa(addr.sin_addr)); if(connect(s, (struct sockaddr*)&addr, sizeof addr) == -1) { fprintf(stderr, "Failed to connect to %s: %s\n", argv[1], strerror(errno)); return 1; } + if(read_line(s, buf, sizeof buf) == -1) { + fprintf(stderr, "Failed to read server identifier\n"); + return 1; + } + if(memcmp(buf, "reposerve-", 10) != 0) { + fprintf(stderr, "Protocol error, doesn't seem we're talking to reposerve at the other end\n"); + return 1; + } + + write(s, "flist\n", 6); + shutdown(s, SHUT_WR); + + if((resp_size = read_resp(s)) == -1) { + fprintf(stderr, "flist request failed\n"); + return -1; + } + if(!resp_size) { + fprintf(stderr, "flist response empty\n"); + return 0; + } + + if(!(resp = malloc(resp_size))) { + fprintf(stderr, "failed to allocate response buffer (%d bytes)\n", resp_size); + return -1; + } + ptr = resp; + pending = resp_size; + while(pending > 0 && (sz = read(s, ptr, pending)) > 0) { + pending -= sz; + ptr += sz; + } + if(pending > 0) { + fprintf(stderr, "failed to read complete response (%d/%d bytes)\n", + resp_size - pending, resp_size); + free(resp); + return -1; + } + + /* parse response */ + flist = (struct proto_flist*)resp; + ptr = resp + sizeof *flist + (flist->num_files - 1) * sizeof *flist->files; + for(i=0; inum_files; i++) { + char *name = ptr + flist->files[i].nameoffs; + int tmp = name[flist->files[i].namelen]; + name[flist->files[i].namelen] = 0; + + printf("%s\n", name); + name[flist->files[i].namelen] = tmp; + } + close(s); return 0; } diff --git a/server/src/main.c b/server/src/main.c index c1e19d9..56dbe6f 100644 --- a/server/src/main.c +++ b/server/src/main.c @@ -42,6 +42,7 @@ int main(int argc, char **argv) signal(SIGILL, sighandler); signal(SIGSEGV, sighandler); signal(SIGTERM, sighandler); + signal(SIGPIPE, SIG_IGN); if(repo_init(repo_path) == -1) { return 1; diff --git a/src/proto.c b/src/proto.c index 60e22b8..7d6466c 100644 --- a/src/proto.c +++ b/src/proto.c @@ -142,3 +142,33 @@ int flist_finalize(struct flist *flist) flist->final_size = newsz; return 0; } + +int read_line(int s, char *buf, int bufsz) +{ + char *ptr = buf; + while(bufsz > 1 && read(s, ptr, 1) > 0 && *ptr++ != '\n'); + *ptr = 0; + return ptr == buf ? -1 : 0; +} + +int read_resp(int s) +{ + int sz, msglen = 0; + char buf[64]; + char *ptr; + + while(msglen < 3 && (sz = read(s, buf + msglen, 3 - msglen)) > 0) { + msglen += sz; + } + if(msglen < 3) return -1; + + if(memcmp(buf, "ERR", 3) == 0) { + return -1; + } + + ptr = buf; + while(read(s, ptr, 1) > 0 && *ptr++ != '\n'); + *ptr = 0; + + return atoi(buf); +} diff --git a/src/proto.h b/src/proto.h index e7a043a..3ed1ae7 100644 --- a/src/proto.h +++ b/src/proto.h @@ -31,4 +31,7 @@ void flist_destroy(struct flist *flist); int flist_add(struct flist *flist, const char *fname, int contents); int flist_finalize(struct flist *flist); +int read_line(int s, char *buf, int bufsz); +int read_resp(int s); + #endif /* PROTO_H_ */ -- 1.7.10.4