]> err.no Git - voouiri/commitdiff
Skeleton implementation
authorTollef Fog Heen <tfheen@err.no>
Sat, 27 Dec 2008 13:12:08 +0000 (14:12 +0100)
committerTollef Fog Heen <tfheen@err.no>
Sat, 27 Dec 2008 13:12:08 +0000 (14:12 +0100)
src/main.c [new file with mode: 0644]

diff --git a/src/main.c b/src/main.c
new file mode 100644 (file)
index 0000000..e4ba30b
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2008, Tollef Fog Heen <tfheen@err.no>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <librsync.h>
+
+int server = 0;
+
+ssize_t write_chunked(int fd, const char *buf, size_t count)
+{
+       char csize[11];
+       int i;
+       i = snprintf(csize, 11, "%x\r\n",count);
+       return write(fd, csize, i) + write(fd, buf, count) + 
+               write(fd, "\r\n", 2);
+}
+
+ssize_t read_chunked(int fd, void *buf, size_t count)
+{
+       char b[1024];
+       size_t bu = 0;
+       ssize_t r;
+       long chunksize;
+
+       b[0] = b[1] = 0;
+       memset(b, 0, sizeof(b));
+
+       r = read(fd, b, 1);
+       while (r > 0 && strstr(b, "\r\n") == NULL) {
+               bu += r;
+               r = read(fd, b+bu, 1);
+       }
+       if (r <= 0) {
+               return r;
+       }
+       chunksize = strtol(b, NULL, 16);
+       if (count < chunksize) {
+               /* Ooops. */
+               fprintf(stderr, "count too small\n");
+               exit(1);
+       }
+       r = read(fd, buf, chunksize);
+       read(fd, b, 2); /* \r\n */
+       return r;
+
+}
+
+int do_server()
+{
+       char inbuf[2048], outbuf[2048];
+       ssize_t inused, outused;
+       ssize_t r;
+       rs_job_t *rs_job;
+       rs_signature_t *sigsum;
+       rs_buffers_t rs_buf;
+       rs_result rs_status;
+       char filename[1024];
+
+       /* Check that we get a SIG, try to load it. */
+       r = read(0, inbuf, 5); /* SIG\r\n */
+       if (r != 5) {
+               perror("read");
+               exit(1);
+       }
+
+       if (memcmp(inbuf, "SIG\r\n", 5) != 0) {
+               fprintf(stderr, "Protocol error, expected SIG");
+               exit(1);
+       }
+
+       rs_job = rs_loadsig_begin(&sigsum);
+
+       read_chunked(0, filename, 1024);
+       write(1, "", 0);
+
+       rs_buf.next_out = outbuf;
+       rs_buf.avail_out = sizeof(outbuf);
+       rs_status = RS_RUNNING;
+       inused = 1;
+       while (inused >= 0 && rs_buf.eof_in != 1) {
+               inused = read_chunked(0, inbuf, sizeof(inbuf));
+
+               if (inused == 0)
+                       rs_buf.eof_in = 1;
+               rs_buf.avail_in = inused;
+               rs_buf.next_in = inbuf;
+               rs_status = rs_job_iter(rs_job, &rs_buf);
+               fprintf(stderr, "%s\n", rs_strerror(rs_status));
+       }
+
+}
+
+int do_client(char *filename)
+{
+       int f;
+       char inbuf[2048], outbuf[2048];
+       ssize_t inused, outused;
+       rs_job_t *rs_job;
+       rs_buffers_t rs_buf;
+       rs_result rs_status;
+
+       f = open(filename, O_RDONLY);
+       if (f < 0) {
+               perror("open");
+               exit(1);
+       }
+       write(1, "SIG\r\n", 5);
+       write_chunked(1, filename, strlen(filename));
+
+       rs_job = rs_sig_begin(RS_DEFAULT_BLOCK_LEN,
+                             RS_DEFAULT_STRONG_LEN);
+       inused = read(f, inbuf, sizeof(inbuf));
+       while (inused >= 0 && rs_buf.eof_in != 1) {
+               if (inused < sizeof(inbuf))
+                       rs_buf.eof_in = 1;
+               rs_buf.avail_in = inused;
+               rs_buf.next_in = inbuf;
+               rs_buf.next_out = outbuf;
+               rs_buf.avail_out = sizeof(outbuf);
+               rs_status = rs_job_iter(rs_job, &rs_buf);
+               fprintf(stderr, "%s\n", rs_strerror(rs_status));
+               write_chunked(1, outbuf, rs_buf.next_out - outbuf);
+               if (rs_buf.avail_in > 0) {
+                       memmove(inbuf, rs_buf.next_in, rs_buf.avail_in);
+                       rs_buf.next_in = inbuf + rs_buf.avail_in;
+                       inused = rs_buf.avail_in;
+               } else {
+                       inused = 0;
+               }
+               inused += read(f, inbuf + inused, sizeof(inbuf) - inused);
+       }
+}
+
+int main(int argc, char **argv)
+{
+       if (argc < 2) {
+               /* FIXME Help */
+               exit(1);
+       }
+
+       if (strcmp(argv[1], "--server") == 0)
+               return do_server();
+       else
+               return do_client(argv[1]);
+}
+