--- libaitsync/src/aitsync.c 2011/05/09 14:36:33 1.2 +++ libaitsync/src/aitsync.c 2012/11/13 14:19:39 1.4 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: aitsync.c,v 1.2 2011/05/09 14:36:33 misho Exp $ +* $Id: aitsync.c,v 1.4 2012/11/13 14:19:39 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -12,7 +12,7 @@ terms: All of the documentation and software included in the ELWIX and AITNET Releases is copyrighted by ELWIX - Sofia/Bulgaria -Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 +Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by Michael Pounov . All rights reserved. Redistribution and use in source and binary forms, with or without @@ -54,49 +54,55 @@ static int sync_Errno; 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; } -// -// Error maintenance functions ... -// +/* + * Error maintenance functions ... + */ // sync_GetErrno() Get error code of last operation -inline int sync_GetErrno() +inline int +sync_GetErrno() { return sync_Errno; } // sync_GetError() Get error text of last operation -inline const char *sync_GetError() +inline const char * +sync_GetError() { return sync_Error; } // sync_SetErr() Set error to variables for internal use!!! -inline void syncSetErr(int eno, char *estr, ...) +inline void +sync_SetErr(int eno, char *estr, ...) { va_list lst; sync_Errno = eno; - memset(sync_Error, 0, STRSIZ); + memset(sync_Error, 0, sizeof sync_Error); va_start(lst, estr); - vsnprintf(sync_Error, STRSIZ, estr, lst); + vsnprintf(sync_Error, sizeof sync_Error, estr, lst); va_end(lst); } -// ---------------------------------------------------------- +/* ---------------------------------------------------------- */ /* - * syncSignature() Calculate and create signature for diff - * @csInput = Input patched file name for calculating check sums + * syncSignature() - Calculate and create signature for diff + * + * @csInput = Input target file name for calculating check sums * @csSig = Output Signature file name * @compress = 2 compress signatures output, 0 not compressed * 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; u_char buf[CHUNK_MAX]; @@ -105,15 +111,16 @@ int syncSignature(const char *csInput, const char *csS sync_chunk_t sc; char szTemp[MAXPATHLEN]; - inf = syncOpen(csInput, O_RDONLY); + /* open work files */ + inf = sync_Open(csInput, O_RDONLY, 0); if (inf == -1) return inf; if (compress & 2) - f = syncTemp(szTemp, MAXPATHLEN); + f = sync_Temp(szTemp, sizeof szTemp); else - f = syncOpen(csSig, O_WRONLY); + f = sync_Open(csSig, O_WRONLY, 0); if (f == -1) { - syncClose(inf); + sync_Close(inf); return f; } @@ -121,54 +128,55 @@ int syncSignature(const char *csInput, const char *csS memset(buf, 0, CHUNK_MAX); ret = read(inf, buf, CHUNK_MAX); if (ret == -1) { - SETERR; + LOGERR; break; } - // fill chunk + /* fill chunk */ sync_mksig(i, off, buf, ret, &sc); if (write(f, &sc, sizeof sc) == -1) { - SETERR; + LOGERR; break; } } - /* Signatures is READY */ + /* Signatures are READY */ - // build compressed delta file if (compress & 2) { - outf = syncOpen(csSig, O_WRONLY); + /* build compressed delta file */ + outf = sync_Open(csSig, O_WRONLY, 0); if (outf == -1) { ret = outf; goto end; } if (sync_Deflate(f, outf, Z_DEFAULT_COMPRESSION) == -1) { - syncClose(outf); + sync_Close(outf); unlink(csSig); ret = -1; goto end; } - syncClose(outf); + sync_Close(outf); } end: - syncClose(f); + sync_Close(f); if (compress & 2) unlink(szTemp); - - syncClose(inf); + sync_Close(inf); return ret; } /* - * syncDelta() Create Delta patch file + * syncDelta() - Create 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 * @compress = 3 everything compress, 2 compressed signatures, 1 compress delta output, 0 not compressed * 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; size_t blk; @@ -184,37 +192,37 @@ int syncDelta(const char *csInput, const char *csSig, /* load signatures */ if (compress & 2) { - f = syncOpen(csSig, O_RDONLY); + f = sync_Open(csSig, O_RDONLY, 0); if (-1 == f) return f; - sigf = syncTemp(szTemp, MAXPATHLEN); + sigf = sync_Temp(szTemp, sizeof szTemp); if (-1 == sigf) { - syncClose(f); + sync_Close(f); return sigf; } if (sync_Inflate(f, sigf) == -1) { - syncClose(sigf); - syncClose(f); + sync_Close(sigf); + sync_Close(f); unlink(szTemp); return -1; } else - syncClose(f); + sync_Close(f); } else { - sigf = syncOpen(csSig, O_RDONLY); + sigf = sync_Open(csSig, O_RDONLY, 0); if (-1 == sigf) return sigf; } if (fstat(sigf, &sb) == -1) { - SETERR; - syncClose(sigf); + LOGERR; + sync_Close(sigf); if (compress & 2) unlink(szTemp); return -1; } else { if (!sb.st_size) { - syncClose(sigf); + sync_Close(sigf); if (compress & 2) unlink(szTemp); return 1; @@ -222,8 +230,8 @@ int syncDelta(const char *csInput, const char *csSig, cnt = sb.st_size / sizeof(sync_chunk_t); if (sb.st_size % sizeof(sync_chunk_t)) { - syncSetErr(ENOEXEC, "Error:: signature file is broken!\n"); - syncClose(sigf); + sync_SetErr(ENOEXEC, "Error:: signature file is broken!\n"); + sync_Close(sigf); if (compress & 2) unlink(szTemp); return -1; @@ -231,27 +239,27 @@ int syncDelta(const char *csInput, const char *csSig, } chunks = (sync_chunk_t*) mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, sigf, 0); if (MAP_FAILED == chunks) { - SETERR; - syncClose(sigf); + LOGERR; + sync_Close(sigf); if (compress & 2) unlink(szTemp); return -1; } else { - syncClose(sigf); + sync_Close(sigf); if (compress & 2) unlink(szTemp); } /* build from signatures sorted index and hashes */ - // init tags array + /* init first stage tags array index */ for (i = 0; i < TABLESIZ; i++) 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)); if (!tag_table) { - SETERR; + LOGERR; munmap(chunks, sb.st_size); return -1; } else { @@ -260,49 +268,57 @@ int syncDelta(const char *csInput, const char *csSig, 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--) tags[tag_table[i].st_tag] = i; + /* build delta patch */ - inf = syncOpen(csInput, O_RDONLY); + inf = sync_Open(csInput, O_RDONLY, 0); if (inf == -1) { free(tag_table); munmap(chunks, sb.st_size); return inf; } if (compress & 1) - f = syncTemp(szTemp, MAXPATHLEN); + f = sync_Temp(szTemp, sizeof szTemp); else - f = syncOpen(csDelta, O_WRONLY); + f = sync_Open(csDelta, O_WRONLY, 0); if (f == -1) { - syncClose(inf); + sync_Close(inf); free(tag_table); munmap(chunks, sb.st_size); 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) { - SETERR; + LOGERR; break; } 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); 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) { - // 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; + /* 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; 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 && !memcmp(chunks[c].sc_cksum, sc.sc_cksum, MD5_DIGEST_LENGTH)) { find = &chunks[c]; @@ -311,35 +327,37 @@ 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) 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) { - /* different piece, write it! */ - // write signature of current chunk + /* different piece, write it! + * Write signature of current chunk */ ret = write(f, &sc, sizeof sc); if (-1 == ret) { - SETERR; + LOGERR; break; } - // if write chunk len is differnt from requested len + /* if write chunk len is differnt from requested len */ 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; break; } - // write current chunk ... + /* write current chunk data ... */ ret = write(f, buf, sc.sc_len); if (-1 == ret) { - SETERR; + LOGERR; break; } - // if write chunk len is differnt from requested len + /* if write chunk len is differnt from requested 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; break; } @@ -347,20 +365,20 @@ int syncDelta(const char *csInput, const char *csSig, 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); sc.sc_magic = SIGSYNC_MAGIC; sc.sc_len = blk; - // write signature from chunk B + /* write signature from chunk B */ blk = write(f, &sc, sizeof sc); if (-1 == blk) { - SETERR; + LOGERR; break; } - // if write chunk len is differnt from requested len + /* if write chunk len is differnt from requested len */ 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; break; } @@ -368,17 +386,17 @@ int syncDelta(const char *csInput, const char *csSig, blk ^= blk; } - // check for error or empty delta file + /* check for error or empty delta file */ if (ret == -1) goto end; fsync(f); if (fstat(f, &sb_f) == -1) { - SETERR; + LOGERR; ret = -1; goto end; } - // No deferences, not needed delta.patch !!! + /* No deferences, not needed delta.patch !!! */ if (!sb_f.st_size) { ret = 1; goto end; @@ -386,42 +404,43 @@ int syncDelta(const char *csInput, const char *csSig, /* Delta patch is READY */ - // build compressed delta file + /* build compressed delta file */ if (compress & 1) { - outf = syncOpen(csDelta, O_WRONLY); + outf = sync_Open(csDelta, O_WRONLY, 0); if (outf == -1) { ret = outf; goto end; } if (sync_Deflate(f, outf, Z_DEFAULT_COMPRESSION) == -1) { - syncClose(outf); + sync_Close(outf); unlink(csDelta); ret = -1; goto end; } - syncClose(outf); + sync_Close(outf); } end: - syncClose(f); + sync_Close(f); if (compress & 1) unlink(szTemp); - - syncClose(inf); + sync_Close(inf); free(tag_table); munmap(chunks, sb.st_size); return ret; } /* - * syncPatch() Apply delta patch file to target + * syncPatch() - Apply delta patch file to target + * * @csInput = Input target file name for patch * @csDelta = Input Delta patch file name * @csPatch = After applied patch create new alternate target file, if != NULL * @compress = 1 compress delta input, 0 not compressed * 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; char szTemp[MAXPATHLEN]; @@ -434,64 +453,64 @@ int syncPatch(const char *csInput, const char *csDelta sync_chunk_t sc, *suffix; if (compress & 1) { - f = syncOpen(csDelta, O_RDONLY); + f = sync_Open(csDelta, O_RDONLY, 0); if (f == -1) return f; - d = syncTemp(szTemp, MAXPATHLEN); + d = sync_Temp(szTemp, sizeof szTemp); if (d == -1) { - syncClose(f); + sync_Close(f); return d; } if (sync_Inflate(f, d) == -1) { - syncClose(d); - syncClose(f); + sync_Close(d); + sync_Close(f); unlink(szTemp); return -1; } else - syncClose(f); + sync_Close(f); } else { - d = syncOpen(csDelta, O_RDONLY); + d = sync_Open(csDelta, O_RDONLY, 0); if (d == -1) return d; } if (fstat(d, &sb) == -1) { - SETERR; - syncClose(d); + LOGERR; + sync_Close(d); if (compress & 1) unlink(szTemp); return -1; } delta = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, d, 0); if (MAP_FAILED == delta) { - SETERR; - syncClose(d); + LOGERR; + sync_Close(d); if (compress & 1) unlink(szTemp); return -1; } else { - syncClose(d); + sync_Close(d); if (compress & 1) unlink(szTemp); } 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); return -1; } - inf = syncOpen(csInput, O_RDONLY); + inf = sync_Open(csInput, O_RDONLY, 0); if (inf == -1) { if (pieces) free(pieces); munmap(delta, sb.st_size); return inf; } - outf = syncOpen(csPatch, O_WRONLY); + outf = sync_Open(csPatch, O_WRONLY, 0); if (outf == -1) { - syncClose(inf); + sync_Close(inf); if (pieces) free(pieces); munmap(delta, sb.st_size); @@ -499,7 +518,7 @@ int syncPatch(const char *csInput, const char *csDelta } if (fstat(inf, &sb) == -1) { - SETERR; + LOGERR; ret = -1; goto end; } else { @@ -511,29 +530,35 @@ int syncPatch(const char *csInput, const char *csDelta ret = readlen = 0; 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) { readlen = read(inf, buf, CHUNK_MAX); if (readlen == -1) { - SETERR; + LOGERR; ret = -1; break; } - // if suffix find, check for correct patch + /* if suffix find, check for correct patch */ if (suffix) { - if (suffix->sc_len != readlen || suffix->sc_off != off) { - syncSetErr(ENOEXEC, "Error:: patch file is broken! (wrong suffix pos)\n"); + if (suffix->sc_len != readlen || + suffix->sc_off != off) { + sync_SetErr(ENOEXEC, "Error:: patch file is broken! " + "(wrong suffix pos)\n"); ret = -1; break; } sync_mksig(i, off, buf, readlen, &sc); if (sc.sc_roll != suffix->sc_roll || - memcmp(sc.sc_cksum, suffix->sc_cksum, MD5_DIGEST_LENGTH)) { - syncSetErr(ENOEXEC, "Error:: patch file is broken! (wrong suffix crc)\n"); + memcmp(sc.sc_cksum, suffix->sc_cksum, + MD5_DIGEST_LENGTH)) { + sync_SetErr(ENOEXEC, "Error:: patch file is broken! " + "(wrong suffix crc)\n"); ret = -1; break; } @@ -544,13 +569,17 @@ int syncPatch(const char *csInput, const char *csDelta buffer = buf; } - // 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); +#if 0 + 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->buf) { - syncSetErr(ENOEXEC, "Error:: patch file is broken! (missing data)\n"); + sync_SetErr(ENOEXEC, "Error:: patch file is broken! " + "(missing data)\n"); ret = -1; break; } @@ -562,30 +591,31 @@ int syncPatch(const char *csInput, const char *csDelta piece++; 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; break; } - } else - if (off >= sb.st_size) { - if (piece->pfx) { - syncSetErr(ENOEXEC, "Error:: patch file is broken! (after eof find prefix)\n"); - ret = -1; - } - - break; + } else if (off >= sb.st_size) { + if (piece->pfx) { + sync_SetErr(ENOEXEC, "Error:: patch file is broken! " + "(after eof find prefix)\n"); + ret = -1; } + break; + } + ret = write(outf, buffer, readlen); if (ret == -1 || ret != readlen) { - SETERR; + LOGERR; break; } } end: - syncClose(inf); - syncClose(outf); + sync_Close(inf); + sync_Close(outf); if (pieces) free(pieces); munmap(delta, sb.st_size);