Somes changes at the new binary format.

This commit is contained in:
Andrea Mazzoleni 2013-08-19 11:19:26 +02:00
parent 2a35b00d16
commit 9d0af268d4

51
state.c
View file

@ -2134,8 +2134,8 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST
count_dir = 0;
crc_checked = 0;
ret = sread(f, buffer, 10);
if (ret < 0 || memcmp(buffer, "SnapRAID\n\3", 10) != 0) {
ret = sread(f, buffer, 12);
if (ret < 0 || memcmp(buffer, "SNAPCNT1\n\3\0\0", 12) != 0) {
decoding_error(path, f);
fprintf(stderr, "Invalid header!\n");
exit(EXIT_FAILURE);
@ -2174,6 +2174,13 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST
exit(EXIT_FAILURE);
}
/* check for impossible file size to avoid to crash for a too big allocation */
if (v_size / state->block_size > blockmax) {
decoding_error(path, f);
fprintf(stderr, "Internal inconsistency in file size!\n");
exit(EXIT_FAILURE);
}
ret = sgetb64(f, &v_mtime_sec);
if (ret < 0) {
decoding_error(path, f);
@ -2228,7 +2235,7 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST
block_off_t v_pos;
uint32_t v_count;
/* get the "blk"/"new"/"chg" command */
/* get the "subcommand */
c = sgetc(f);
ret = sgetb32(f, &v_pos);
@ -2432,7 +2439,6 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST
v_pos = 0;
while (v_pos < blockdiskmax) {
uint32_t flag;
uint32_t v_count;
ret = sgetb32(f, &v_count);
@ -2447,14 +2453,12 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST
exit(EXIT_FAILURE);
}
ret = sgetb32(f, &flag);
if (ret < 0) {
decoding_error(path, f);
exit(EXIT_FAILURE);
}
/* get the subcommand */
c = sgetc(f);
/* if it's a run of deleted blocks */
if ((flag & 1) != 0) {
switch (c) {
case 'o' :
/* if it's a run of deleted blocks */
while (v_count) {
struct snapraid_deleted* deleted;
@ -2488,9 +2492,15 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST
++v_pos;
--v_count;
}
} else {
break;
case 'O' :
/* go to the next run */
v_pos += v_count;
break;
default:
decoding_error(path, f);
fprintf(stderr, "Invalid hole type!\n");
exit(EXIT_FAILURE);
}
}
} else if (c == 's') {
@ -2628,7 +2638,9 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST
/* stat */
++count_dir;
} else if (c == 'c') {
/* get the subcommand */
c = sgetc(f);
switch (c) {
case 'u' :
state->hash = HASH_MURMUR3;
@ -2649,7 +2661,9 @@ static void state_read_binary(struct snapraid_state* state, const char* path, ST
exit(EXIT_FAILURE);
}
} else if (c == 'C') {
/* get the subcommand */
c = sgetc(f);
switch (c) {
case 'u' :
state->prevhash = HASH_MURMUR3;
@ -2792,7 +2806,7 @@ static void state_write_binary(struct snapraid_state* state, STREAM* f)
blockmax = parity_size(state);
/* write header */
swrite("SnapRAID\n\3", 10, f);
swrite("SNAPCNT1\n\3\0\0", 12, f);
/* clear the info for unused blocks */
/* and get some other info */
@ -2880,7 +2894,7 @@ static void state_write_binary(struct snapraid_state* state, STREAM* f)
sputb32(info_oldest, f);
/* read the blockmax, this is also going to be used in a lot of checks */
/* write blockmax, this is also going to be used in a lot of checks */
sputb32(blockmax, f);
/* write the info for each block */
@ -2906,7 +2920,7 @@ static void state_write_binary(struct snapraid_state* state, STREAM* f)
/* if there is info */
if (info) {
/* other flags */
flag = 1; /* time is present */
flag = 1; /* info is present */
if (info_get_bad(info))
flag |= 2;
if (info_get_rehash(info))
@ -3102,7 +3116,7 @@ static void state_write_binary(struct snapraid_state* state, STREAM* f)
if (is_deleted) {
/* write the run of deleted blocks with hash */
sputb32(1, f);
sputc('o', f);
/* write all the hash */
while (begin < end) {
@ -3115,7 +3129,7 @@ static void state_write_binary(struct snapraid_state* state, STREAM* f)
} else {
/* write the run of blocks without hash */
/* they can be either used or empty blocks */
sputb32(0, f);
sputc('O', f);
/* next begin position */
begin = end;
@ -3217,7 +3231,8 @@ void state_read(struct snapraid_state* state)
/* get the first char to detect the file type */
c = sgetc(f);
sungetc(c, f);
/* guess the file type from the first char */
if (c == 'S') {
state_read_binary(state, path, f);
} else {