Commit f551802e authored by Mike Hibler's avatar Mike Hibler
Browse files

Make -U take an argument to explicitly name the new signature file.

parent a6a2fb96
......@@ -356,14 +356,13 @@ int hashmap_blocksize(void)
/*
* Write out hash (signature) info associated with the named image.
* Signature file will be <name>.sig.
* Signature file will be given either the explicit 'fname' or will
* be derived from 'iname' if 'fname' is ''.
*/
int hashmap_write_hashfile(char *name, uint32_t ssect)
int hashmap_write_hashfile(char *fname, char *iname, uint32_t ssect)
{
int ofd, i, cc, count;
char *hfile;
struct stat sb;
struct timeval tm[2];
if (nhinfo == NULL) {
fprintf(stderr, "No hashinfo to write!?\n");
......@@ -379,13 +378,26 @@ int hashmap_write_hashfile(char *name, uint32_t ssect)
hreg->region.start -= ssect;
}
hfile = malloc(strlen(name) + 5);
/*
* Figure out a derived name if fname == ''.
*/
if (fname[0] == '\0') {
/* Hmm...writing to stdout, call it "/tmp/stdout.sig" */
if (strcmp(iname, "-") == 0)
hfile = strdup("/tmp/stdout.sig");
else {
hfile = malloc(strlen(iname) + 5);
if (hfile) {
strcpy(hfile, iname);
strcpy(hfile + strlen(hfile), ".sig");
}
}
} else
hfile = strdup(fname);
if (hfile == NULL) {
fprintf(stderr, "%s: out of memory\n", name);
fprintf(stderr, "%s: out of memory\n", iname);
return -1;
}
strcpy(hfile, name);
strcpy(hfile + strlen(hfile), ".sig");
ofd = open(hfile, O_RDWR|O_CREAT|O_TRUNC, 0666);
if (ofd < 0) {
......@@ -394,7 +406,6 @@ int hashmap_write_hashfile(char *name, uint32_t ssect)
hfile = malloc(strlen("/tmp/000000.sig") + 1);
if (hfile) {
sprintf(hfile, "/tmp/%06d.sig", getpid());
fprintf(stderr, "Saving to %s instead...\n", hfile);
ofd = open(hfile, O_RDWR|O_CREAT|O_TRUNC, 0666);
if (ofd < 0) {
perror(hfile);
......@@ -413,7 +424,8 @@ int hashmap_write_hashfile(char *name, uint32_t ssect)
perror(hfile);
else
fprintf(stderr,
"%s: incomplete write (%d)\n", hfile, cc);
"%s: incomplete write (%d) to sigfile %s\n",
iname, cc, hfile);
free(hfile);
return -1;
}
......@@ -423,23 +435,30 @@ int hashmap_write_hashfile(char *name, uint32_t ssect)
* This is a crude (but fast!) method for matching images with
* signatures.
*/
cc = stat(name, &sb);
if (cc >= 0) {
if (strcmp(iname, "-") != 0) {
struct stat sb;
struct timeval tm[2];
cc = stat(iname, &sb);
if (cc >= 0) {
#ifdef linux
tm[0].tv_sec = sb.st_atime;
tm[0].tv_usec = 0;
tm[1].tv_sec = sb.st_mtime;
tm[1].tv_usec = 0;
tm[0].tv_sec = sb.st_atime;
tm[0].tv_usec = 0;
tm[1].tv_sec = sb.st_mtime;
tm[1].tv_usec = 0;
#else
TIMESPEC_TO_TIMEVAL(&tm[0], &sb.st_atimespec);
TIMESPEC_TO_TIMEVAL(&tm[1], &sb.st_mtimespec);
TIMESPEC_TO_TIMEVAL(&tm[0], &sb.st_atimespec);
TIMESPEC_TO_TIMEVAL(&tm[1], &sb.st_mtimespec);
#endif
cc = utimes(hfile, tm);
cc = utimes(hfile, tm);
}
if (cc < 0)
fprintf(stderr,
"%s: WARNING: could not set mtime (%s)\n",
hfile, strerror(errno));
}
if (cc < 0)
fprintf(stderr, "%s: WARNING: could not set mtime (%s)\n",
hfile, strerror(errno));
fprintf(stderr, "%s: new signature written to %s\n", iname, hfile);
free(hfile);
return 0;
}
......@@ -591,7 +610,8 @@ hashmap_update_chunk(uint32_t ssect, uint32_t lsect, int chunkno)
*/
int
hashmap_compute_delta(struct range *curranges, char *hfile, int infd,
uint32_t ssect, int newhash, struct range **nranges)
uint32_t ssect, char *newhashfile,
struct range **nranges)
{
uint32_t gapstart, gapsize, lastdrangeend = 0;
unsigned char hash[HASH_MAXSIZE];
......@@ -666,7 +686,7 @@ hashmap_compute_delta(struct range *curranges, char *hfile, int infd,
* Copy the fixup list since we are going to have to apply fixups
* before computing new hashes and applying fixups is destructive.
*/
if (newhash) {
if (newhashfile) {
#ifdef DEBUG
extern int numfixups;
#endif
......@@ -716,7 +736,7 @@ hashmap_compute_delta(struct range *curranges, char *hfile, int infd,
goto error;
/* Add hash entries for this range. */
if (newhash &&
if (newhashfile &&
add_to_hashmap(&nhinfo, drange->start,
drange->size, NULL))
goto error;
......@@ -781,7 +801,7 @@ hashmap_compute_delta(struct range *curranges, char *hfile, int infd,
#endif
/* Add hash entries for this range. */
if (newhash &&
if (newhashfile &&
add_to_hashmap(&nhinfo, drange->start, before,
NULL))
goto error;
......@@ -853,7 +873,7 @@ hashmap_compute_delta(struct range *curranges, char *hfile, int infd,
* the new contents of the old hrange.
* Add that hrange with the new hash.
*/
if (newhash &&
if (newhashfile &&
add_to_hashmap(&nhinfo, hreg->region.start,
hreg->region.size, hash))
goto error;
......@@ -955,7 +975,7 @@ hashmap_compute_delta(struct range *curranges, char *hfile, int infd,
* added the entry with the correct hash,
* otherwise add hash entries.
*/
if (changed > 1 && newhash &&
if (changed > 1 && newhashfile &&
add_to_hashmap(&nhinfo, curstart,
curend - curstart,
NULL))
......@@ -1085,7 +1105,7 @@ hashmap_compute_delta(struct range *curranges, char *hfile, int infd,
#endif
/* Add hash entries for this range. */
if (newhash &&
if (newhashfile &&
add_to_hashmap(&nhinfo, drange->start, drange->size, NULL))
goto error;
......@@ -1099,11 +1119,9 @@ hashmap_compute_delta(struct range *curranges, char *hfile, int infd,
* the old one. Even if there are no ranges in the current
* image, we create a valid (null) hashfile.
*/
if (newhash) {
if (*nranges == NULL) {
assert(nhinfo == NULL);
if (newhashfile) {
if (nhinfo == NULL)
nhinfo = calloc(1, sizeof(*nhinfo));
}
assert(nhinfo != NULL);
strcpy((char *)nhinfo->magic, HASH_MAGIC);
nhinfo->version = HASH_VERSION_2;
......@@ -1112,7 +1130,7 @@ hashmap_compute_delta(struct range *curranges, char *hfile, int infd,
HASHBLK_SIZE : hinfo->blksize;
}
if (newhash) {
if (newhashfile) {
#ifdef DEBUG
extern int numfixups;
fprintf(stderr, "%d fixups left-over (should be zero!)\n",
......@@ -1127,7 +1145,7 @@ hashmap_compute_delta(struct range *curranges, char *hfile, int infd,
return 0;
error:
if (newhash) {
if (newhashfile) {
#ifdef DEBUG
extern int numfixups;
fprintf(stderr, "%d fixups left-over\n", numfixups);
......
......@@ -23,7 +23,7 @@
int hashmap_blocksize(void);
void hashmap_update_chunk(uint32_t, uint32_t, int);
int hashmap_compute_delta(struct range *, char *, int, u_int32_t, int,
int hashmap_compute_delta(struct range *, char *, int, u_int32_t, char *,
struct range **);
int hashmap_write_hashfile(char *, u_int32_t);
int hashmap_write_hashfile(char *, char *, u_int32_t);
void hashmap_dump_stats(int pnum);
......@@ -112,7 +112,7 @@ static unsigned char imageid[UUID_LENGTH];
#ifdef WITH_HASH
char *hashfile;
int newhashfile;
char *newhashfile;
int deltapct = -1;
#endif
......@@ -444,7 +444,7 @@ main(int argc, char *argv[])
memset(imageid, '\0', UUID_LENGTH);
gettimeofday(&sstamp, 0);
while ((ch = getopt(argc, argv, "vlbnNdihrs:c:z:ofI:13F:DR:S:XxH:UP:Me:k:u:a:Z")) != -1)
while ((ch = getopt(argc, argv, "vlbnNdihrs:c:z:ofI:13F:DR:S:XxH:U:P:Me:k:u:a:Z")) != -1)
switch(ch) {
case 'v':
version++;
......@@ -526,7 +526,7 @@ main(int argc, char *argv[])
hashfile = optarg;
break;
case 'U':
newhashfile = 1;
newhashfile = optarg;
break;
case 'P':
deltapct = atoi(optarg);
......@@ -659,16 +659,8 @@ main(int argc, char *argv[])
fprintf(stderr, "Must specify an output filename!\n\n");
usage();
}
else {
else
outfilename = argv[1];
#ifdef WITH_HASH
if (strcmp(outfilename, "-") == 0 && newhashfile) {
fprintf(stderr,
"Cannot create hashfile with outfile==stdout\n");
usage();
}
#endif
}
if (!slicemode && !filemode && dorelocs)
dorelocs = 0;
......@@ -804,7 +796,7 @@ main(int argc, char *argv[])
* The result is a new list of ranges that are currently allocated
* and that have changed from the signature version.
*
* If we are creating a new signature file (newhashfile != 0)
* If we are creating a new signature file (newhashfile != NULL)
* then we also collect hashinfo along the way, writing out the
* newfile when done.
*/
......@@ -897,7 +889,7 @@ main(int argc, char *argv[])
* Write out new signature file.
*/
if (newhashfile &&
hashmap_write_hashfile(outfilename, inputminsec))
hashmap_write_hashfile(newhashfile, outfilename, inputminsec))
fprintf(stderr, "Could not write new hashfile!\n");
#endif
}
......@@ -1197,7 +1189,8 @@ char *usagestr =
" -D Do `dangerous' writes (don't check for async errors)\n"
" -1 Output a version one image file\n"
" -H hashfile Use the specified imagehash-generated signature to produce a delta image\n"
" -U Update or create the signature file to reflect the new image\n"
" -U sigfile Update or create the signature to reflect the new image.\n"
" Image is written to named sigfile or <outfile>.sig if ''.\n"
" -P pct With -H, if the resulting delta would be <pct> percent or\n"
" greater of the (uncompressed) size of a full image, create\n"
" a full image instead\n"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment