From ec7b115817aa06ede0c2bf933ccdeeb893fdd831 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Fri, 31 Jul 2020 13:41:21 +0300 Subject: [PATCH] server responds to flist --- server/src/client.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- server/src/client.h | 1 + server/src/main.c | 33 +++++++++++++++++++++++++++++++-- src/proto.c | 5 ++++- 4 files changed, 78 insertions(+), 5 deletions(-) diff --git a/server/src/client.c b/server/src/client.c index bec2f11..e7f4d3c 100644 --- a/server/src/client.c +++ b/server/src/client.c @@ -1,12 +1,14 @@ #include #include #include +#include #include #include "client.h" #include "proto.h" #include "repo.h" static int proc_request(struct client *c); +static void print_invalid(const char *s); static int proc_flist(struct client *c, char *data, int datasz); static int proc_push(struct client *c, char *data, int datasz); static int proc_pull(struct client *c, char *data, int datasz); @@ -28,6 +30,8 @@ int handle_client(struct client *c) if(proc_request(c) == -1) { return -1; } + + if(sz == 0) return -1; return 0; } @@ -38,7 +42,12 @@ static int proc_request(struct client *c) int reqdata_len; while(endp < c->buf + c->bsz) { + if(*endp == '\r' && endp[1] == '\n') { + *endp++ = 0; + break; + } if(*endp == '\n') break; + endp++; } if(endp >= c->buf + c->bsz) { return 0; @@ -62,10 +71,27 @@ static int proc_request(struct client *c) return 0; } + print_invalid(c->buf); send_err(c); return 0; } +static void print_invalid(const char *s) +{ + int i; + printf("Recv invalid request: \""); + for(i=0; i<60; i++) { + if(!*s) break; + if(isprint(*s)) { + putchar(*s); + } else { + printf("\\x%x", (unsigned int)*s); + } + s++; + } + puts("\""); +} + void send_string(struct client *c, const char *s) { write(c->s, s, strlen(s)); @@ -85,8 +111,10 @@ void send_err(struct client *c) static struct flist *gen_flist(int contents) { - int i, count; + int i, count, len; struct flist *flist; + char *pathbuf = 0; + int pathbuf_sz = 0; if(!(flist = flist_create())) { return 0; @@ -98,10 +126,22 @@ static struct flist *gen_flist(int contents) count = repo_num_files(); for(i=0; ipath, contents); + len = strlen(repo_path) + strlen(repo_file(i)->path) + 1; + if(len > pathbuf_sz) { + free(pathbuf); + if(!(pathbuf = malloc(len + 1))) { + fprintf(stderr, "gen_flist: failed to allocate path buffer (%d bytes)\n", len + 1); + repo_cleanup(); + flist_destroy(flist); + return 0; + } + } + sprintf(pathbuf, "%s/%s", repo_path, repo_file(i)->path); + flist_add(flist, pathbuf, contents); } repo_cleanup(); + free(pathbuf); return flist; } diff --git a/server/src/client.h b/server/src/client.h index 10720db..341ff8f 100644 --- a/server/src/client.h +++ b/server/src/client.h @@ -7,6 +7,7 @@ enum { struct client { int s; + char *addr; unsigned int flags; char buf[16384]; int bsz; diff --git a/server/src/main.c b/server/src/main.c index ab5c055..c1e19d9 100644 --- a/server/src/main.c +++ b/server/src/main.c @@ -4,20 +4,25 @@ #include #include #include +#include #include +#include #include #include #include #include +#include #include "repo.h" #include "client.h" static const char *guess_repo_name(const char *path); +static void sighandler(int s); static int parse_args(int argc, char **argv); static const char *repo_name; static int lis = -1; static int port = 64357; +static int quit; static struct client *clients; @@ -32,6 +37,12 @@ int main(int argc, char **argv) return 1; } + signal(SIGINT, sighandler); + signal(SIGQUIT, sighandler); + signal(SIGILL, sighandler); + signal(SIGSEGV, sighandler); + signal(SIGTERM, sighandler); + if(repo_init(repo_path) == -1) { return 1; } @@ -49,6 +60,7 @@ int main(int argc, char **argv) fprintf(stderr, "failed to create socket: %s\n", strerror(errno)); return 1; } + fcntl(lis, F_SETFL, fcntl(lis, F_GETFL) | O_NONBLOCK); memset(&addr, 0, sizeof addr); addr.sin_family = AF_INET; @@ -80,7 +92,7 @@ int main(int argc, char **argv) perror("select failed"); break; } - + if(quit) break; if(res <= 0) continue; dummy.next = clients; @@ -90,7 +102,10 @@ int main(int argc, char **argv) if(handle_client(c->next) == -1) { struct client *tmp = c->next; c->next = tmp->next; + + printf("Client %s disconnected\n", tmp->addr ? tmp->addr : "unknown"); close(tmp->s); + free(tmp->addr); free(tmp); continue; } @@ -100,10 +115,15 @@ int main(int argc, char **argv) clients = dummy.next; if(FD_ISSET(lis, &rdset)) { - if((s = accept(lis, 0, 0)) == -1) { + struct sockaddr_in addr; + unsigned int addrsz = sizeof addr; + + if((s = accept(lis, (struct sockaddr*)&addr, &addrsz)) == -1) { perror("failed to accept connection"); continue; } + fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK); + if(!(c = calloc(1, sizeof *c))) { perror("failed to allocate memory for client structure"); close(s); @@ -111,12 +131,16 @@ int main(int argc, char **argv) } c->s = s; c->next = clients; + c->addr = strdup(inet_ntoa(addr.sin_addr)); clients = c; send_string(c, "reposerve-0.1 protocol:0\n"); + + printf("Connection from: %s\n", c->addr ? c->addr : "unknown"); } } + printf("Shutting down\n"); return 0; } @@ -146,6 +170,11 @@ fail: return 0; } +static void sighandler(int s) +{ + quit = 1; +} + static void print_usage(const char *argv0) { printf("Usage: %s [options] [repo path]\n", argv0); diff --git a/src/proto.c b/src/proto.c index 9d548a6..60e22b8 100644 --- a/src/proto.c +++ b/src/proto.c @@ -57,7 +57,7 @@ int flist_add(struct flist *flist, const char *fname, int contents) datalen += fent.size; } - if(flist->flist->num_files >= flist->max_files) { + if(!flist->flist || flist->flist->num_files >= flist->max_files) { struct proto_flist *tmp; int newsz = flist->max_files ? flist->max_files << 1 : 32; @@ -65,6 +65,9 @@ int flist_add(struct flist *flist, const char *fname, int contents) fprintf(stderr, "flist_add: failed to resize file list to %d entries\n", newsz); return -1; } + if(!flist->flist) { + tmp->num_files = 0; + } flist->flist = tmp; flist->max_files = newsz; } -- 1.7.10.4