From: Tollef Fog Heen Date: Sat, 27 Dec 2008 13:12:08 +0000 (+0100) Subject: Skeleton implementation X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9ad51cb1305261640d6eef3d0a32d0228d9d8aeb;p=voouiri Skeleton implementation --- diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..e4ba30b --- /dev/null +++ b/src/main.c @@ -0,0 +1,168 @@ +/* + * Copyright 2008, Tollef Fog Heen + * + * 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 +#include +#include +#include +#include +#include +#include + +#include + +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]); +} +