/*
* rcksum/lib - library for using the rsync algorithm to determine
* which parts of a file you have and which you need.
* Copyright (C) 2004,2005 Colin Phipps <cph@moria.org.uk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the Artistic License v2 (see the accompanying
* file COPYING for the full license terms), or, at your option, any later
* version of the same license.
*
* 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
* COPYING file for details.
*/
/* Effectively the constructor and destructor for the rcksum object.
* Also handles the file handles on the temporary stote.
*/
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "config.h"
#include "rcksum.h"
#include "internal.h"
struct rcksum_state* rcksum_init(zs_blockid nblocks, size_t blocksize, int rsum_bytes, int checksum_bytes, int require_consecutive_matches)
{
struct rcksum_state* z = malloc(sizeof(struct rcksum_state));
if (z != NULL) {
/* Setup blocksize and shift. Size must be a power of two. */
z->blocksize = blocksize;
z->blocks = nblocks;
z->rsum_a_mask = rsum_bytes < 3 ? 0 : rsum_bytes == 3 ? 0xff : 0xffff;
z->checksum_bytes = checksum_bytes;
z->seq_matches = require_consecutive_matches;
z->context = blocksize * require_consecutive_matches;
z->gotblocks = 0;
z->filename = strdup("rcksum-XXXXXX");
memset(&(z->stats),0,sizeof(z->stats));
if (!(z->blocksize & (z->blocksize - 1)) && z->filename != NULL && z->blocks) {
z->fd = mkstemp(z->filename);
if (z->fd == -1) {
perror("open");
} else {
{
int i;
for (i = 0; i < 32; i++)
if (z->blocksize == (1 << i)) {
z->blockshift = i; break;
}
}
z->ranges = NULL;
z->rsum_hash = NULL;
z->numranges = 0;
z->blockhashes = malloc(sizeof(z->blockhashes[0]) * (z->blocks+z->seq_matches));
if (z->blockhashes != NULL)
return z;
/* All below is error handling */
}
}
free(z->filename);
free(z);
}
return NULL;
}
char* rcksum_filename(struct rcksum_state* z)
{
char* p = z->filename;
z->filename = NULL;
return p;
}
int rcksum_filehandle(struct rcksum_state* z)
{
int h = z->fd;
z->fd = -1;
return h;
}
void rcksum_end(struct rcksum_state* z)
{
if (z->fd != -1)
close(z->fd);
if (z->filename) {
unlink(z->filename);
free(z->filename);
}
free(z->rsum_hash);
free(z->blockhashes);
free(z->bithash);
free(z->ranges); // Should be NULL already
#ifdef DEBUG
fprintf(stderr,"hashhit %d, weakhit %d, checksummed %d, stronghit %d\n",z->stats.hashhit, z->stats.weakhit, z->stats.checksummed, z->stats.stronghit);
#endif
free(z);
}
syntax highlighted by Code2HTML, v. 0.9.1