X-Git-Url: http://dolda2000.com/gitweb/?a=blobdiff_plain;f=config%2Fcmd%2Ftthsum.c;fp=config%2Fcmd%2Ftthsum.c;h=6d7d5ed6180d23c324e26d8507d907af85fc525a;hb=7df0ddad481bb2e644bba361d0d3defdbd68494e;hp=0000000000000000000000000000000000000000;hpb=d6af9cf30349e4c09b4e9e60342bf1ddd142abd1;p=doldaconnect.git diff --git a/config/cmd/tthsum.c b/config/cmd/tthsum.c new file mode 100644 index 0000000..6d7d5ed --- /dev/null +++ b/config/cmd/tthsum.c @@ -0,0 +1,272 @@ +/* + * Dolda Connect - Modular multiuser Direct Connect-style client + * Copyright (C) 2004 Fredrik Tolf (fredrik@dolda2000.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 +*/ + +/* This frankenfile is built from bits and pieces of the daemon. The + * copying and pasting is very ugly, but it doesn't *really* + * matter. */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include + +char buf[32768]; + +static char *base64enc2(char *data, size_t datalen) +{ + static char *res = NULL; + + if(res != NULL) + free(res); + res = base64encode(data, datalen); + return(res); +} + +static char *base64dec2(char *data, size_t *datalen) +{ + static char *res = NULL; + + if(res != NULL) + free(res); + res = base64decode(data, datalen); + return(res); +} + +int main(int argc, char **argv) +{ + int i, ret; + size_t size; + int c, fd, outfd; + int len, len2; + int filter, output; + struct tigertreehash tth; + char *dec, *enc; + char res[24]; + char *statefile; + FILE *state; + int progress, bytes; + struct stat sb; + + filter = 0; + output = 4; + outfd = 3; + progress = 0; + statefile = NULL; + while((c = getopt(argc, argv, "phf456F:s:")) != -1) { + switch(c) { + case '4': + case '5': + case '6': + output = c - '0'; + break; + case 'p': + progress = 1; + break; + case 'f': + filter = 1; + break; + case 'F': + outfd = atoi(optarg); + break; + case 's': + statefile = optarg; + break; + case 'h': + case ':': + case '?': + default: + fprintf(stderr, "usage: tigersum [-h456] FILE...\n"); + fprintf(stderr, " tigersum [-h456] [-F OUTFD] [-s STATEFILE] -f\n"); + exit((c == 'h')?0:1); + } + } + if(filter) { + inittigertree(&tth); + if(statefile != NULL) + { + if(((state = fopen(statefile, "r")) == NULL) && (errno != ENOENT)) { + fprintf(stderr, "tigersum: %s: %s\n", statefile, strerror(errno)); + exit(1); + } + if(state != NULL) { + if(fgets(buf, sizeof(buf), state) == NULL) { + fprintf(stderr, "tigersum: %s: could not read entire state\n", statefile); + exit(1); + } + tth.blocks = atoi(buf); + if(fgets(buf, sizeof(buf), state) == NULL) { + fprintf(stderr, "tigersum: %s: could not read entire state\n", statefile); + exit(1); + } + tth.depth = atoi(buf); + for(i = 0; i < tth.depth; i++) { + if(fgets(buf, sizeof(buf), state) == NULL) { + fprintf(stderr, "tigersum: %s: could not read entire state\n", statefile); + exit(1); + } + dec = base64dec2(buf, &size); + if(size != 24) { + fprintf(stderr, "tigersum: %s: illegal state\n", statefile); + exit(1); + } + memcpy(tth.stack[i], dec, 24); + } + if(fgets(buf, sizeof(buf), state) == NULL) { + fprintf(stderr, "tigersum: %s: could not read entire state\n", statefile); + exit(1); + } + tth.offset = atoi(buf); + if(fgets(buf, sizeof(buf), state) == NULL) { + fprintf(stderr, "tigersum: %s: could not read entire state\n", statefile); + exit(1); + } + dec = base64dec2(buf, &size); + if(size != tth.offset) { + fprintf(stderr, "tigersum: %s: illegal state\n", statefile); + exit(1); + } + memcpy(&tth.block, dec, tth.offset); + fclose(state); + unlink(statefile); + } + } + while(1) { + ret = read(0, buf, sizeof(buf)); + if(ret < 0) { + perror("tigersum: read"); + exit(1); + } + if(ret == 0) + break; + len = ret; + for(len2 = 0; len2 < len; len2 += ret) { + if((ret = write(1, buf, ret)) < 0) { + perror("tigersum: write"); + exit(1); + } + } + dotigertree(&tth, buf, len); + } + if(statefile != NULL) { + if((state = fopen(statefile, "w")) == NULL) { + fprintf(stderr, "tigersum: %s: %s\n", statefile, strerror(errno)); + exit(1); + } + fprintf(state, "%i\n", tth.blocks); + fprintf(state, "%i\n", tth.depth); + for(i = 0; i < tth.depth; i++) { + enc = base64enc2(tth.stack[i], 24); + fprintf(state, "%s\n", enc); + } + fprintf(state, "%i\n", tth.offset); + enc = base64enc2(tth.block, tth.offset); + fputs(enc, state); + fputc('\n', state); + fclose(state); + } + synctigertree(&tth); + restigertree(&tth, res); + if(output == 4) + enc = hexencode(res, 24); + else if(output == 5) + enc = base32encode(res, 24); + else if(output == 6) + enc = base64encode(res, 24); + for(len = 0; len < strlen(enc); len += ret) { + if((ret = write(outfd, enc + len, strlen(enc) - len)) < 0) { + perror("tigersum: output"); + exit(1); + } + } + free(enc); + write(outfd, "\n", 1); + } else { + for(i = optind; i < argc; i++) { + if(!strcmp(argv[i], "-")) { + fd = 0; + } else { + if((fd = open(argv[i], O_RDONLY)) < 0) { + fprintf(stderr, "tigersum: %s: %s\n", argv[i], strerror(errno)); + exit(1); + } + } + if(progress) { + fstat(fd, &sb); + if(!S_ISREG(sb.st_mode)) + sb.st_size = -1; + bytes = 0; + } + inittigertree(&tth); + while(1) { + ret = read(fd, buf, sizeof(buf)); + if(ret < 0) { + perror("tigersum: read"); + exit(1); + } + if(progress) { + if((bytes == 0) || ((bytes & ~0xFFFFF) != ((bytes + ret) & ~0xFFFFF))) { + bytes += ret; + fprintf(stderr, "\033[1G"); + if(argc - optind > 1) + fprintf(stderr, "%s: ", argv[i]); + if(sb.st_size < 0) { + fprintf(stderr, "%i", bytes); + } else { + fprintf(stderr, "%i%%", (int)(((float)bytes / (float)sb.st_size) * 100.0)); + } + fprintf(stderr, "\033[K"); + fflush(stderr); + } else { + bytes += ret; + } + } + if(ret == 0) + break; + dotigertree(&tth, buf, ret); + } + if(progress) + fprintf(stderr, "\n"); + synctigertree(&tth); + restigertree(&tth, res); + if(output == 4) + enc = hexencode(res, 24); + else if(output == 5) + enc = base32encode(res, 24); + else if(output == 6) + enc = base64encode(res, 24); + if(argc - optind > 1) + printf("%s %s\n", enc, argv[i]); + else + printf("%s\n", enc); + free(enc); + fflush(stdout); + close(fd); + } + } + return(0); +}