reposerve server half way done
[reposerve] / server / src / client.c
diff --git a/server/src/client.c b/server/src/client.c
new file mode 100644 (file)
index 0000000..bec2f11
--- /dev/null
@@ -0,0 +1,135 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "client.h"
+#include "proto.h"
+#include "repo.h"
+
+static int proc_request(struct client *c);
+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);
+
+const char *repo_path;
+
+int handle_client(struct client *c)
+{
+       char buf[512];
+       int sz, left;
+
+       while((sz = read(c->s, buf, sizeof buf)) > 0) {
+               left = sizeof c->buf - c->bsz;
+               if(sz > left) sz = left;
+               memcpy(c->buf + c->bsz, buf, sz);
+               c->bsz += sz;
+       }
+
+       if(proc_request(c) == -1) {
+               return -1;
+       }
+       return 0;
+}
+
+static int proc_request(struct client *c)
+{
+       char *endp = c->buf;
+       char *reqdata;
+       int reqdata_len;
+
+       while(endp < c->buf + c->bsz) {
+               if(*endp == '\n') break;
+       }
+       if(endp >= c->buf + c->bsz) {
+               return 0;
+       }
+       *endp = 0;
+
+       reqdata = endp + 1;
+       reqdata_len = c->bsz - (reqdata - c->buf);
+
+       c->bsz = 0;
+
+       if(strcmp(c->buf, "flist") == 0) {
+               return proc_flist(c, reqdata, reqdata_len);
+       } else if(strcmp(c->buf, "push") == 0) {
+               return proc_push(c, reqdata, reqdata_len);
+       } else if(strcmp(c->buf, "pull") == 0) {
+               return proc_pull(c, reqdata, reqdata_len);
+       } else if(strcmp(c->buf, "dos") == 0) {
+               c->flags |= CLIENT_DOS;
+               send_ok(c, 0);
+               return 0;
+       }
+
+       send_err(c);
+       return 0;
+}
+
+void send_string(struct client *c, const char *s)
+{
+       write(c->s, s, strlen(s));
+}
+
+void send_ok(struct client *c, int resp_sz)
+{
+       char buf[32];
+       sprintf(buf, "OK %d\n", resp_sz < 0 ? 0 : resp_sz);
+       send_string(c, buf);
+}
+
+void send_err(struct client *c)
+{
+       send_string(c, "ERR\n");
+}
+
+static struct flist *gen_flist(int contents)
+{
+       int i, count;
+       struct flist *flist;
+
+       if(!(flist = flist_create())) {
+               return 0;
+       }
+
+       if(repo_init(repo_path) == -1) {
+               return 0;
+       }
+       count = repo_num_files();
+
+       for(i=0; i<count; i++) {
+               flist_add(flist, repo_file(i)->path, contents);
+       }
+       repo_cleanup();
+
+       return flist;
+}
+
+static int proc_flist(struct client *c, char *data, int datasz)
+{
+       struct flist *flist;
+
+       if(!(flist = gen_flist(0))) {
+               send_err(c);
+               return -1;
+       }
+       flist_finalize(flist);
+
+       send_ok(c, flist->final_size);
+       write(c->s, flist->flist, flist->final_size);
+
+       flist_destroy(flist);
+       return 0;
+}
+
+static int proc_push(struct client *c, char *data, int datasz)
+{
+       send_err(c);
+       return 0;
+}
+
+static int proc_pull(struct client *c, char *data, int datasz)
+{
+       send_err(c);
+       return 0;
+}