struct scan_ctx *scan_init(void) { struct scan_ctx *scan; scan = malloc(sizeof(struct scan_ctx)); if (!scan) goto unwind0; scan->buffer_size = 3 * (1<<24); scan->buffer[0] = malloc(scan->buffer_size); if (!scan->buffer[0]) goto unwind1; scan->buffer[1] = scan->buffer[0] + scan->buffer_size/3; scan->buffer[2] = scan->buffer[1] + scan->buffer_size/3; scan->buffer_end = scan->buffer[0] + scan->buffer_size; scan->p = scan->buffer[0]; scan->eof = 0; scan->bytes_left = 0; scan->source_offset = 0; scan->window_size = 48; scan->target_chunk_size = 1 << 18; scan->minimum_chunk_size = 1 << 16; scan->maximum_chunk_size = 1 << 24; scan->rabin_ctx = rabin_init(1103515245, scan->window_size); if (!scan->rabin_ctx) goto unwind2; scan->start_io = start_sync_io; scan->finish_io = finish_sync_io; return scan; unwind2: rabin_free(scan->rabin_ctx); unwind1: free(scan->buffer[0]); unwind0: return 0; }
int main(int argc, const char *argv[]) { int window_size = 48 ; int avg_seg_size = 4096; int min_seg_size = 2048; int max_seg_size = 8192; char fname[PATH_MAX] = {0}; int c; while ((c = getopt(argc, (char * const*)argv, "f:w:a:i:x:")) != -1) { switch (c) { case 'f': strncpy(fname, optarg, sizeof fname); break; case 'w': window_size = atoi(optarg); break; case 'a': avg_seg_size = atoi(optarg); break; case 'i': min_seg_size = atoi(optarg); break; case 'x': max_seg_size = atoi(optarg); break; default: usage(argv[0]); exit(1); } } int fd; if (fname[0]) { fd = open(fname, O_RDONLY); if (fd == -1) { perror("open failed:"); exit(2); } } else { /* Use stdin if filename was not specified */ fd = STDIN_FILENO; } /* printf("Window size : %d\n", window_size); printf("Avg segment size requested : %d\n", avg_seg_size); printf("Min segment size requested : %d\n", min_seg_size); printf("Max segment size requested : %d\n", max_seg_size); printf("Reading file %s\n", fname); */ rabinpoly_t *rp = rabin_init( window_size, avg_seg_size, min_seg_size, max_seg_size); if (!rp) { fprintf(stderr, "Failed to init rabinhash algorithm\n"); exit(1); } MD5_CTX ctx; unsigned char md5[MD5_DIGEST_LENGTH]; int new_segment = 0; int len, segment_len = 0, b; char buf[1024]; int bytes; MD5_Init(&ctx); while( (bytes = read(fd, buf, sizeof buf)) > 0 ) { char *buftoread = (char *)&buf[0]; while ((len = rabin_segment_next(rp, buftoread, bytes, &new_segment)) > 0) { MD5_Update(&ctx, buftoread, len); segment_len += len; if (new_segment) { MD5_Final(md5, &ctx); printf("%u ", segment_len); for(b = 0; b < MD5_DIGEST_LENGTH; b++) printf("%02x", md5[b]); printf("\n"); MD5_Init(&ctx); segment_len = 0; } buftoread += len; bytes -= len; if (!bytes) { break; } } if (len == -1) { fprintf(stderr, "Failed to process the segment\n"); exit(2); } } MD5_Final(md5, &ctx); printf("%u ", segment_len); for(b = 0; b < MD5_DIGEST_LENGTH; b++) { printf("%02x", md5[b]); } printf("\n"); rabin_free(&rp); return 0; }
void cdc_init () { rabin_init (BLOCK_WIN_SZ); }