version 1.2, 2011/05/09 14:36:33
|
version 1.6, 2014/02/04 16:58:17
|
Line 12 terms:
|
Line 12 terms:
|
All of the documentation and software included in the ELWIX and AITNET |
All of the documentation and software included in the ELWIX and AITNET |
Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org> |
Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org> |
|
|
Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 | Copyright 2004 - 2014 |
by Michael Pounov <misho@elwix.org>. All rights reserved. |
by Michael Pounov <misho@elwix.org>. All rights reserved. |
|
|
Redistribution and use in source and binary forms, with or without |
Redistribution and use in source and binary forms, with or without |
Line 54 static int sync_Errno;
|
Line 54 static int sync_Errno;
|
static char sync_Error[STRSIZ]; |
static char sync_Error[STRSIZ]; |
|
|
|
|
static inline int func_comp(sync_tag_t const *t1, sync_tag_t const *t2) | static inline int |
| func_comp(sync_tag_t const *t1, sync_tag_t const *t2) |
{ |
{ |
return t1->st_tag - t2->st_tag; |
return t1->st_tag - t2->st_tag; |
} |
} |
|
|
// | /* |
// Error maintenance functions ... | * Error maintenance functions ... |
// | */ |
|
|
// sync_GetErrno() Get error code of last operation |
// sync_GetErrno() Get error code of last operation |
inline int sync_GetErrno() | int |
| sync_GetErrno() |
{ |
{ |
return sync_Errno; |
return sync_Errno; |
} |
} |
|
|
// sync_GetError() Get error text of last operation |
// sync_GetError() Get error text of last operation |
inline const char *sync_GetError() | const char * |
| sync_GetError() |
{ |
{ |
return sync_Error; |
return sync_Error; |
} |
} |
|
|
// sync_SetErr() Set error to variables for internal use!!! |
// sync_SetErr() Set error to variables for internal use!!! |
inline void syncSetErr(int eno, char *estr, ...) | void |
| sync_SetErr(int eno, char *estr, ...) |
{ |
{ |
va_list lst; |
va_list lst; |
|
|
sync_Errno = eno; |
sync_Errno = eno; |
memset(sync_Error, 0, STRSIZ); | memset(sync_Error, 0, sizeof sync_Error); |
va_start(lst, estr); |
va_start(lst, estr); |
vsnprintf(sync_Error, STRSIZ, estr, lst); | vsnprintf(sync_Error, sizeof sync_Error, estr, lst); |
va_end(lst); |
va_end(lst); |
} |
} |
|
|
// ---------------------------------------------------------- | /* ---------------------------------------------------------- */ |
|
|
/* |
/* |
* syncSignature() Calculate and create signature for diff | * syncSignature() - Calculate and create signature for diff |
* @csInput = Input patched file name for calculating check sums | * |
| * @csInput = Input target file name for calculating check sums |
* @csSig = Output Signature file name |
* @csSig = Output Signature file name |
* @compress = 2 compress signatures output, 0 not compressed |
* @compress = 2 compress signatures output, 0 not compressed |
* return: -1 error, 0 ok |
* return: -1 error, 0 ok |
*/ |
*/ |
int syncSignature(const char *csInput, const char *csSig, int compress) | int |
| syncSignature(const char *csInput, const char *csSig, int compress) |
{ |
{ |
int inf, outf, f, ret; |
int inf, outf, f, ret; |
u_char buf[CHUNK_MAX]; |
u_char buf[CHUNK_MAX]; |
Line 105 int syncSignature(const char *csInput, const char *csS
|
Line 111 int syncSignature(const char *csInput, const char *csS
|
sync_chunk_t sc; |
sync_chunk_t sc; |
char szTemp[MAXPATHLEN]; |
char szTemp[MAXPATHLEN]; |
|
|
inf = syncOpen(csInput, O_RDONLY); | /* open work files */ |
| inf = sync_Open(csInput, O_RDONLY, 0); |
if (inf == -1) |
if (inf == -1) |
return inf; |
return inf; |
if (compress & 2) |
if (compress & 2) |
f = syncTemp(szTemp, MAXPATHLEN); | f = sync_Temp(szTemp, sizeof szTemp); |
else |
else |
f = syncOpen(csSig, O_WRONLY); | f = sync_Open(csSig, O_WRONLY, 0); |
if (f == -1) { |
if (f == -1) { |
syncClose(inf); | sync_Close(inf); |
return f; |
return f; |
} |
} |
|
|
Line 121 int syncSignature(const char *csInput, const char *csS
|
Line 128 int syncSignature(const char *csInput, const char *csS
|
memset(buf, 0, CHUNK_MAX); |
memset(buf, 0, CHUNK_MAX); |
ret = read(inf, buf, CHUNK_MAX); |
ret = read(inf, buf, CHUNK_MAX); |
if (ret == -1) { |
if (ret == -1) { |
SETERR; | LOGERR; |
break; |
break; |
} |
} |
|
|
// fill chunk | /* fill chunk */ |
sync_mksig(i, off, buf, ret, &sc); |
sync_mksig(i, off, buf, ret, &sc); |
|
|
if (write(f, &sc, sizeof sc) == -1) { |
if (write(f, &sc, sizeof sc) == -1) { |
SETERR; | LOGERR; |
break; |
break; |
} |
} |
} |
} |
|
|
/* Signatures is READY */ | /* Signatures are READY */ |
|
|
// build compressed delta file |
|
if (compress & 2) { |
if (compress & 2) { |
outf = syncOpen(csSig, O_WRONLY); | /* build compressed delta file */ |
| outf = sync_Open(csSig, O_WRONLY, 0); |
if (outf == -1) { |
if (outf == -1) { |
ret = outf; |
ret = outf; |
goto end; |
goto end; |
} |
} |
if (sync_Deflate(f, outf, Z_DEFAULT_COMPRESSION) == -1) { |
if (sync_Deflate(f, outf, Z_DEFAULT_COMPRESSION) == -1) { |
syncClose(outf); | sync_Close(outf); |
unlink(csSig); |
unlink(csSig); |
ret = -1; |
ret = -1; |
goto end; |
goto end; |
} |
} |
syncClose(outf); | sync_Close(outf); |
} |
} |
end: |
end: |
syncClose(f); | sync_Close(f); |
if (compress & 2) |
if (compress & 2) |
unlink(szTemp); |
unlink(szTemp); |
| sync_Close(inf); |
syncClose(inf); | |
return ret; |
return ret; |
} |
} |
|
|
/* |
/* |
* syncDelta() Create Delta patch file | * syncDelta() - Create Delta patch file |
| * |
* @csInput = Input original source file name for make delta patch file |
* @csInput = Input original source file name for make delta patch file |
* @csSig = Input Signature file name | * @csSig = Input target Signature file name |
* @csDelta = Output Delta patch file name |
* @csDelta = Output Delta patch file name |
* @compress = 3 everything compress, 2 compressed signatures, 1 compress delta output, 0 not compressed |
* @compress = 3 everything compress, 2 compressed signatures, 1 compress delta output, 0 not compressed |
* return: -1 error, 0 ok |
* return: -1 error, 0 ok |
*/ |
*/ |
int syncDelta(const char *csInput, const char *csSig, const char *csDelta, int compress) | int |
| syncDelta(const char *csInput, const char *csSig, const char *csDelta, int compress) |
{ |
{ |
int inf, outf, f, sigf, ret, cnt; |
int inf, outf, f, sigf, ret, cnt; |
size_t blk; |
size_t blk; |
Line 184 int syncDelta(const char *csInput, const char *csSig,
|
Line 192 int syncDelta(const char *csInput, const char *csSig,
|
/* load signatures */ |
/* load signatures */ |
|
|
if (compress & 2) { |
if (compress & 2) { |
f = syncOpen(csSig, O_RDONLY); | f = sync_Open(csSig, O_RDONLY, 0); |
if (-1 == f) |
if (-1 == f) |
return f; |
return f; |
sigf = syncTemp(szTemp, MAXPATHLEN); | sigf = sync_Temp(szTemp, sizeof szTemp); |
if (-1 == sigf) { |
if (-1 == sigf) { |
syncClose(f); | sync_Close(f); |
return sigf; |
return sigf; |
} |
} |
|
|
if (sync_Inflate(f, sigf) == -1) { |
if (sync_Inflate(f, sigf) == -1) { |
syncClose(sigf); | sync_Close(sigf); |
syncClose(f); | sync_Close(f); |
unlink(szTemp); |
unlink(szTemp); |
return -1; |
return -1; |
} else |
} else |
syncClose(f); | sync_Close(f); |
} else { |
} else { |
sigf = syncOpen(csSig, O_RDONLY); | sigf = sync_Open(csSig, O_RDONLY, 0); |
if (-1 == sigf) |
if (-1 == sigf) |
return sigf; |
return sigf; |
} |
} |
|
|
if (fstat(sigf, &sb) == -1) { |
if (fstat(sigf, &sb) == -1) { |
SETERR; | LOGERR; |
syncClose(sigf); | sync_Close(sigf); |
if (compress & 2) |
if (compress & 2) |
unlink(szTemp); |
unlink(szTemp); |
return -1; |
return -1; |
} else { |
} else { |
if (!sb.st_size) { |
if (!sb.st_size) { |
syncClose(sigf); | sync_Close(sigf); |
if (compress & 2) |
if (compress & 2) |
unlink(szTemp); |
unlink(szTemp); |
return 1; |
return 1; |
Line 222 int syncDelta(const char *csInput, const char *csSig,
|
Line 230 int syncDelta(const char *csInput, const char *csSig,
|
|
|
cnt = sb.st_size / sizeof(sync_chunk_t); |
cnt = sb.st_size / sizeof(sync_chunk_t); |
if (sb.st_size % sizeof(sync_chunk_t)) { |
if (sb.st_size % sizeof(sync_chunk_t)) { |
syncSetErr(ENOEXEC, "Error:: signature file is broken!\n"); | sync_SetErr(ENOEXEC, "Error:: signature file is broken!\n"); |
syncClose(sigf); | sync_Close(sigf); |
if (compress & 2) |
if (compress & 2) |
unlink(szTemp); |
unlink(szTemp); |
return -1; |
return -1; |
Line 231 int syncDelta(const char *csInput, const char *csSig,
|
Line 239 int syncDelta(const char *csInput, const char *csSig,
|
} |
} |
chunks = (sync_chunk_t*) mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, sigf, 0); |
chunks = (sync_chunk_t*) mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, sigf, 0); |
if (MAP_FAILED == chunks) { |
if (MAP_FAILED == chunks) { |
SETERR; | LOGERR; |
syncClose(sigf); | sync_Close(sigf); |
if (compress & 2) |
if (compress & 2) |
unlink(szTemp); |
unlink(szTemp); |
return -1; |
return -1; |
} else { |
} else { |
syncClose(sigf); | sync_Close(sigf); |
if (compress & 2) |
if (compress & 2) |
unlink(szTemp); |
unlink(szTemp); |
} |
} |
|
|
/* build from signatures sorted index and hashes */ |
/* build from signatures sorted index and hashes */ |
|
|
// init tags array | /* init first stage tags array index */ |
for (i = 0; i < TABLESIZ; i++) |
for (i = 0; i < TABLESIZ; i++) |
tags[i] = NULL_TAG; |
tags[i] = NULL_TAG; |
|
|
// build index from signature blocks | /* build second index from signature blocks */ |
tag_table = (sync_tag_t*) calloc(cnt, sizeof(sync_tag_t)); | tag_table = (sync_tag_t*) e_calloc(cnt, sizeof(sync_tag_t)); |
if (!tag_table) { |
if (!tag_table) { |
SETERR; | LOGERR; |
munmap(chunks, sb.st_size); |
munmap(chunks, sb.st_size); |
return -1; |
return -1; |
} else { |
} else { |
Line 260 int syncDelta(const char *csInput, const char *csSig,
|
Line 268 int syncDelta(const char *csInput, const char *csSig,
|
tag_table[i].st_tag = GETTAG(chunks[i].sc_roll); |
tag_table[i].st_tag = GETTAG(chunks[i].sc_roll); |
} |
} |
|
|
qsort(tag_table, cnt, sizeof(sync_tag_t), (int (*)(const void *, const void *)) func_comp); | qsort(tag_table, cnt, sizeof(sync_tag_t), |
| (int (*)(const void *, const void *)) func_comp); |
} |
} |
// assign less id position in tag_table to tags | /* assign less id position in tag_table to tags. |
| * It made relation between 1st & 2nd indexes */ |
for (i = cnt - 1; i > -1; i--) |
for (i = cnt - 1; i > -1; i--) |
tags[tag_table[i].st_tag] = i; |
tags[tag_table[i].st_tag] = i; |
|
|
|
|
/* build delta patch */ |
/* build delta patch */ |
|
|
inf = syncOpen(csInput, O_RDONLY); | inf = sync_Open(csInput, O_RDONLY, 0); |
if (inf == -1) { |
if (inf == -1) { |
free(tag_table); | e_free(tag_table); |
munmap(chunks, sb.st_size); |
munmap(chunks, sb.st_size); |
return inf; |
return inf; |
} |
} |
if (compress & 1) |
if (compress & 1) |
f = syncTemp(szTemp, MAXPATHLEN); | f = sync_Temp(szTemp, sizeof szTemp); |
else |
else |
f = syncOpen(csDelta, O_WRONLY); | f = sync_Open(csDelta, O_WRONLY, 0); |
if (f == -1) { |
if (f == -1) { |
syncClose(inf); | sync_Close(inf); |
free(tag_table); | e_free(tag_table); |
munmap(chunks, sb.st_size); |
munmap(chunks, sb.st_size); |
return f; |
return f; |
} |
} |
|
|
for (i = 0, off = 0ll, ret = -1, blk = 0; (ret = read(inf, buf, CHUNK_MAX)); i++, off += ret) { | for (i = 0, off = 0ll, ret = -1, blk = 0; |
| (ret = read(inf, buf, CHUNK_MAX)); i++, off += ret) { |
if (ret == -1) { |
if (ret == -1) { |
SETERR; | LOGERR; |
break; |
break; |
} |
} |
find = NULL; |
find = NULL; |
|
|
// printf("+ find=%p off=%llu i=%d blk=%d\n", find, off, i, blk); | #if 0 |
| printf("+ find=%p off=%llu i=%d blk=%d\n", find, off, i, blk); |
| #endif |
|
|
// check chunk for differences with signature | /* check chunk for differences with signature */ |
sync_mksig(i, off, buf, ret, &sc); |
sync_mksig(i, off, buf, ret, &sc); |
cx = GETTAG(sc.sc_roll); |
cx = GETTAG(sc.sc_roll); |
// find in hash -> hash_sorted_table | /* find in hash -> hash_sorted_table */ |
if (NULL_TAG != tags[cx] && tag_table[tags[cx]].st_tag == cx) { |
if (NULL_TAG != tags[cx] && tag_table[tags[cx]].st_tag == cx) { |
// find in hash_sorted_table crc == -> real chunks id | /* find in hash_sorted_table crc == -> real chunks id */ |
for (j = 0, c = tag_table[tags[cx]].st_id; tag_table[tags[cx] + j].st_tag == cx; | for (j = 0, c = tag_table[tags[cx]].st_id; |
| tag_table[tags[cx] + j].st_tag == cx; |
j++, c = tag_table[tags[cx] + j].st_id) { |
j++, c = tag_table[tags[cx] + j].st_id) { |
if (chunks[c].sc_magic == sc.sc_magic && chunks[c].sc_len == sc.sc_len && | if (chunks[c].sc_magic == sc.sc_magic && |
| chunks[c].sc_len == sc.sc_len && |
chunks[c].sc_roll == sc.sc_roll && |
chunks[c].sc_roll == sc.sc_roll && |
!memcmp(chunks[c].sc_cksum, sc.sc_cksum, MD5_DIGEST_LENGTH)) { |
!memcmp(chunks[c].sc_cksum, sc.sc_cksum, MD5_DIGEST_LENGTH)) { |
find = &chunks[c]; |
find = &chunks[c]; |
Line 311 int syncDelta(const char *csInput, const char *csSig,
|
Line 327 int syncDelta(const char *csInput, const char *csSig,
|
} |
} |
} |
} |
|
|
// printf("+ find=%p off=%llu i=%d blk=%d\n", find, off, i, blk); | #if 0 |
| printf("+ find=%p off=%llu i=%d blk=%d\n", find, off, i, blk); |
| #endif |
|
|
// if match chunk, check for previous match | /* if match chunk, check for previous match */ |
if (!blk && find) |
if (!blk && find) |
continue; |
continue; |
// if not find chunk in signature skip write to delta patch | /* if not find chunk in signature skip write to delta patch */ |
if (!find) { |
if (!find) { |
/* different piece, write it! */ | /* different piece, write it! |
// write signature of current chunk | * Write signature of current chunk */ |
ret = write(f, &sc, sizeof sc); |
ret = write(f, &sc, sizeof sc); |
if (-1 == ret) { |
if (-1 == ret) { |
SETERR; | LOGERR; |
break; |
break; |
} |
} |
// if write chunk len is differnt from requested len | /* if write chunk len is differnt from requested len */ |
if (ret != sizeof sc) { |
if (ret != sizeof sc) { |
syncSetErr(ENOEXEC, "Error:: delta file signature is broken!\n"); | sync_SetErr(ENOEXEC, "Error:: delta file signature is broken!\n"); |
ret = -1; |
ret = -1; |
break; |
break; |
} |
} |
// write current chunk ... | /* write current chunk data ... */ |
ret = write(f, buf, sc.sc_len); |
ret = write(f, buf, sc.sc_len); |
if (-1 == ret) { |
if (-1 == ret) { |
SETERR; | LOGERR; |
break; |
break; |
} |
} |
// if write chunk len is differnt from requested len | /* if write chunk len is differnt from requested len */ |
if (ret != sc.sc_len) { |
if (ret != sc.sc_len) { |
syncSetErr(ENOEXEC, "Error:: delta file data is broken!\n"); | sync_SetErr(ENOEXEC, "Error:: delta file data is broken!\n"); |
ret = -1; |
ret = -1; |
break; |
break; |
} |
} |
Line 347 int syncDelta(const char *csInput, const char *csSig,
|
Line 365 int syncDelta(const char *csInput, const char *csSig,
|
|
|
continue; |
continue; |
} |
} |
// match 1st block after difference and copy signature from B | /* match 1st block after difference and copy signature from B */ |
memcpy(&sc, find, sizeof sc); |
memcpy(&sc, find, sizeof sc); |
sc.sc_magic = SIGSYNC_MAGIC; |
sc.sc_magic = SIGSYNC_MAGIC; |
sc.sc_len = blk; |
sc.sc_len = blk; |
|
|
// write signature from chunk B | /* write signature from chunk B */ |
blk = write(f, &sc, sizeof sc); |
blk = write(f, &sc, sizeof sc); |
if (-1 == blk) { |
if (-1 == blk) { |
SETERR; | LOGERR; |
break; |
break; |
} |
} |
// if write chunk len is differnt from requested len | /* if write chunk len is differnt from requested len */ |
if (blk != sizeof sc) { |
if (blk != sizeof sc) { |
syncSetErr(ENOEXEC, "Error:: delta file end signature is broken!\n"); | sync_SetErr(ENOEXEC, "Error:: delta file end signature is broken!\n"); |
ret = -1; |
ret = -1; |
break; |
break; |
} |
} |
Line 368 int syncDelta(const char *csInput, const char *csSig,
|
Line 386 int syncDelta(const char *csInput, const char *csSig,
|
blk ^= blk; |
blk ^= blk; |
} |
} |
|
|
// check for error or empty delta file | /* check for error or empty delta file */ |
if (ret == -1) |
if (ret == -1) |
goto end; |
goto end; |
fsync(f); |
fsync(f); |
if (fstat(f, &sb_f) == -1) { |
if (fstat(f, &sb_f) == -1) { |
SETERR; | LOGERR; |
ret = -1; |
ret = -1; |
goto end; |
goto end; |
} |
} |
|
|
// No deferences, not needed delta.patch !!! | /* No deferences, not needed delta.patch !!! */ |
if (!sb_f.st_size) { |
if (!sb_f.st_size) { |
ret = 1; |
ret = 1; |
goto end; |
goto end; |
Line 386 int syncDelta(const char *csInput, const char *csSig,
|
Line 404 int syncDelta(const char *csInput, const char *csSig,
|
|
|
/* Delta patch is READY */ |
/* Delta patch is READY */ |
|
|
// build compressed delta file | /* build compressed delta file */ |
if (compress & 1) { |
if (compress & 1) { |
outf = syncOpen(csDelta, O_WRONLY); | outf = sync_Open(csDelta, O_WRONLY, 0); |
if (outf == -1) { |
if (outf == -1) { |
ret = outf; |
ret = outf; |
goto end; |
goto end; |
} |
} |
if (sync_Deflate(f, outf, Z_DEFAULT_COMPRESSION) == -1) { |
if (sync_Deflate(f, outf, Z_DEFAULT_COMPRESSION) == -1) { |
syncClose(outf); | sync_Close(outf); |
unlink(csDelta); |
unlink(csDelta); |
ret = -1; |
ret = -1; |
goto end; |
goto end; |
} |
} |
syncClose(outf); | sync_Close(outf); |
} |
} |
|
|
end: |
end: |
syncClose(f); | sync_Close(f); |
if (compress & 1) |
if (compress & 1) |
unlink(szTemp); |
unlink(szTemp); |
| sync_Close(inf); |
syncClose(inf); | e_free(tag_table); |
free(tag_table); | |
munmap(chunks, sb.st_size); |
munmap(chunks, sb.st_size); |
return ret; |
return ret; |
} |
} |
|
|
/* |
/* |
* syncPatch() Apply delta patch file to target | * syncPatch() - Apply delta patch file to target |
| * |
* @csInput = Input target file name for patch |
* @csInput = Input target file name for patch |
* @csDelta = Input Delta patch file name |
* @csDelta = Input Delta patch file name |
* @csPatch = After applied patch create new alternate target file, if != NULL |
* @csPatch = After applied patch create new alternate target file, if != NULL |
* @compress = 1 compress delta input, 0 not compressed |
* @compress = 1 compress delta input, 0 not compressed |
* return: -1 error, 0 ok, create delta patch, 1 ok, no differences and not create patch |
* return: -1 error, 0 ok, create delta patch, 1 ok, no differences and not create patch |
*/ |
*/ |
int syncPatch(const char *csInput, const char *csDelta, const char *csPatch, int compress) | int |
| syncPatch(const char *csInput, const char *csDelta, const char *csPatch, int compress) |
{ |
{ |
int inf, outf, f, d, ret, readlen; |
int inf, outf, f, d, ret, readlen; |
char szTemp[MAXPATHLEN]; |
char szTemp[MAXPATHLEN]; |
Line 434 int syncPatch(const char *csInput, const char *csDelta
|
Line 453 int syncPatch(const char *csInput, const char *csDelta
|
sync_chunk_t sc, *suffix; |
sync_chunk_t sc, *suffix; |
|
|
if (compress & 1) { |
if (compress & 1) { |
f = syncOpen(csDelta, O_RDONLY); | f = sync_Open(csDelta, O_RDONLY, 0); |
if (f == -1) |
if (f == -1) |
return f; |
return f; |
d = syncTemp(szTemp, MAXPATHLEN); | d = sync_Temp(szTemp, sizeof szTemp); |
if (d == -1) { |
if (d == -1) { |
syncClose(f); | sync_Close(f); |
return d; |
return d; |
} |
} |
|
|
if (sync_Inflate(f, d) == -1) { |
if (sync_Inflate(f, d) == -1) { |
syncClose(d); | sync_Close(d); |
syncClose(f); | sync_Close(f); |
unlink(szTemp); |
unlink(szTemp); |
return -1; |
return -1; |
} else |
} else |
syncClose(f); | sync_Close(f); |
} else { |
} else { |
d = syncOpen(csDelta, O_RDONLY); | d = sync_Open(csDelta, O_RDONLY, 0); |
if (d == -1) |
if (d == -1) |
return d; |
return d; |
} |
} |
|
|
if (fstat(d, &sb) == -1) { |
if (fstat(d, &sb) == -1) { |
SETERR; | LOGERR; |
syncClose(d); | sync_Close(d); |
if (compress & 1) |
if (compress & 1) |
unlink(szTemp); |
unlink(szTemp); |
return -1; |
return -1; |
} |
} |
delta = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, d, 0); |
delta = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, d, 0); |
if (MAP_FAILED == delta) { |
if (MAP_FAILED == delta) { |
SETERR; | LOGERR; |
syncClose(d); | sync_Close(d); |
if (compress & 1) |
if (compress & 1) |
unlink(szTemp); |
unlink(szTemp); |
return -1; |
return -1; |
} else { |
} else { |
syncClose(d); | sync_Close(d); |
if (compress & 1) |
if (compress & 1) |
unlink(szTemp); |
unlink(szTemp); |
} |
} |
|
|
if (sync_buildPatch(delta, sb.st_size, &pieces) == -1 || !pieces) { |
if (sync_buildPatch(delta, sb.st_size, &pieces) == -1 || !pieces) { |
syncSetErr(ENOEXEC, "Error:: patch file is broken!\n"); | sync_SetErr(ENOEXEC, "Error:: patch file is broken!\n"); |
munmap(delta, sb.st_size); |
munmap(delta, sb.st_size); |
return -1; |
return -1; |
} |
} |
|
|
inf = syncOpen(csInput, O_RDONLY); | inf = sync_Open(csInput, O_RDONLY, 0); |
if (inf == -1) { |
if (inf == -1) { |
if (pieces) | e_free(pieces); |
free(pieces); | |
munmap(delta, sb.st_size); |
munmap(delta, sb.st_size); |
return inf; |
return inf; |
} |
} |
outf = syncOpen(csPatch, O_WRONLY); | outf = sync_Open(csPatch, O_WRONLY, 0); |
if (outf == -1) { |
if (outf == -1) { |
syncClose(inf); | sync_Close(inf); |
if (pieces) | e_free(pieces); |
free(pieces); | |
munmap(delta, sb.st_size); |
munmap(delta, sb.st_size); |
return outf; |
return outf; |
} |
} |
|
|
if (fstat(inf, &sb) == -1) { |
if (fstat(inf, &sb) == -1) { |
SETERR; | LOGERR; |
ret = -1; |
ret = -1; |
goto end; |
goto end; |
} else { |
} else { |
Line 511 int syncPatch(const char *csInput, const char *csDelta
|
Line 528 int syncPatch(const char *csInput, const char *csDelta
|
|
|
ret = readlen = 0; |
ret = readlen = 0; |
buffer = NULL; |
buffer = NULL; |
for (i = 0, off = 0ll, suffix = NULL, piece = pieces; piece->pfx; i++, off += readlen) { | for (i = 0, off = 0ll, suffix = NULL, piece = pieces; piece->pfx; |
| i++, off += readlen) { |
| #if 0 |
| printf("i=%d off=%llu sfx=%p piece=%p\n", i, off, suffix, piece); |
| #endif |
|
|
// printf("i=%d off=%llu sfx=%p piece=%p\n", i, off, suffix, piece); | /* if input offset is less then input file size */ |
| |
// if input offset is less then input file size | |
if (off < sb.st_size) { |
if (off < sb.st_size) { |
readlen = read(inf, buf, CHUNK_MAX); |
readlen = read(inf, buf, CHUNK_MAX); |
if (readlen == -1) { |
if (readlen == -1) { |
SETERR; | LOGERR; |
ret = -1; |
ret = -1; |
break; |
break; |
} |
} |
// if suffix find, check for correct patch | /* if suffix find, check for correct patch */ |
if (suffix) { |
if (suffix) { |
if (suffix->sc_len != readlen || suffix->sc_off != off) { | if (suffix->sc_len != readlen || |
syncSetErr(ENOEXEC, "Error:: patch file is broken! (wrong suffix pos)\n"); | suffix->sc_off != off) { |
| sync_SetErr(ENOEXEC, "Error:: patch file is broken! " |
| "(wrong suffix pos)\n"); |
ret = -1; |
ret = -1; |
break; |
break; |
} |
} |
sync_mksig(i, off, buf, readlen, &sc); |
sync_mksig(i, off, buf, readlen, &sc); |
if (sc.sc_roll != suffix->sc_roll || |
if (sc.sc_roll != suffix->sc_roll || |
memcmp(sc.sc_cksum, suffix->sc_cksum, MD5_DIGEST_LENGTH)) { | memcmp(sc.sc_cksum, suffix->sc_cksum, |
syncSetErr(ENOEXEC, "Error:: patch file is broken! (wrong suffix crc)\n"); | MD5_DIGEST_LENGTH)) { |
| sync_SetErr(ENOEXEC, "Error:: patch file is broken! " |
| "(wrong suffix crc)\n"); |
ret = -1; |
ret = -1; |
break; |
break; |
} |
} |
Line 544 int syncPatch(const char *csInput, const char *csDelta
|
Line 567 int syncPatch(const char *csInput, const char *csDelta
|
buffer = buf; |
buffer = buf; |
} |
} |
|
|
// printf("i=%d off=%llu sfx=%p piece=%p pfx=%p pfx_off=%llu\n", i, off, suffix, piece, | #if 0 |
// piece ? piece->pfx : 0l, piece->pfx ? piece->pfx->sc_off : 0l); | printf("i=%d off=%llu sfx=%p piece=%p pfx=%p pfx_off=%llu\n", i, off, |
| suffix, piece, piece ? piece->pfx : 0l, |
| piece->pfx ? piece->pfx->sc_off : 0l); |
| #endif |
|
|
// if delta chunk match! | /* if delta chunk match! */ |
if (piece->pfx && piece->pfx->sc_off == off) { |
if (piece->pfx && piece->pfx->sc_off == off) { |
if (!piece->buf) { |
if (!piece->buf) { |
syncSetErr(ENOEXEC, "Error:: patch file is broken! (missing data)\n"); | sync_SetErr(ENOEXEC, "Error:: patch file is broken! " |
| "(missing data)\n"); |
ret = -1; |
ret = -1; |
break; |
break; |
} |
} |
Line 562 int syncPatch(const char *csInput, const char *csDelta
|
Line 589 int syncPatch(const char *csInput, const char *csDelta
|
piece++; |
piece++; |
|
|
if (suffix && off >= sb.st_size) { |
if (suffix && off >= sb.st_size) { |
syncSetErr(ENOEXEC, "Error:: patch file is broken! (after eof find suffix)\n"); | sync_SetErr(ENOEXEC, "Error:: patch file is broken! " |
| "(after eof find suffix)\n"); |
ret = -1; |
ret = -1; |
break; |
break; |
} |
} |
} else | } else if (off >= sb.st_size) { |
if (off >= sb.st_size) { | if (piece->pfx) { |
if (piece->pfx) { | sync_SetErr(ENOEXEC, "Error:: patch file is broken! " |
syncSetErr(ENOEXEC, "Error:: patch file is broken! (after eof find prefix)\n"); | "(after eof find prefix)\n"); |
ret = -1; | ret = -1; |
} | |
| |
break; | |
} |
} |
|
|
|
break; |
|
} |
|
|
ret = write(outf, buffer, readlen); |
ret = write(outf, buffer, readlen); |
if (ret == -1 || ret != readlen) { |
if (ret == -1 || ret != readlen) { |
SETERR; | LOGERR; |
break; |
break; |
} |
} |
} |
} |
|
|
end: |
end: |
syncClose(inf); | sync_Close(inf); |
syncClose(outf); | sync_Close(outf); |
if (pieces) | e_free(pieces); |
free(pieces); | |
munmap(delta, sb.st_size); |
munmap(delta, sb.st_size); |
return ret; |
return ret; |
} |
} |