bool DelFile(const std::string& file) { if(!WriteOp()) return false; printf("file %s delete\n", file.c_str()); unsigned short len = file.size(); int bzerror; BZ2_bzWrite(&bzerror, _bzpatch, &len, sizeof(len)); if(bzerror!=BZ_OK) return false; BZ2_bzWrite(&bzerror, _bzpatch, "*", 1); if(bzerror!=BZ_OK) return false; BZ2_bzWrite(&bzerror, _bzpatch, (void*)file.c_str(), len); if(bzerror!=BZ_OK) return false; return true; }
bool AddOperatorAppend(size_t size, size_t _patch_offset) { if(!WriteOp()) return false; printf("-append %d %d\n", size, _patch_offset); int bzerror; unsigned char code = OPERATOR_APPEND; BZ2_bzWrite(&bzerror, _bzpatch, &code, sizeof(code)); if(bzerror!=BZ_OK) return false; BZ2_bzWrite(&bzerror, _bzpatch, &size, 4); if(bzerror!=BZ_OK) return false; BZ2_bzWrite(&bzerror, _bzpatch, &_patch_offset, 4); if(bzerror!=BZ_OK) return false; return true; }
static void write_bz2(int f, int fd, const char *arg) { BZFILE* b; int nBuf; char buf[BUFFER_SIZE]; int bzerror; b = BZ2_bzWriteOpen(&bzerror, fdopen(f,"wb"), 9, 0, 0); if (bzerror != BZ_OK) { BZ2_bzWriteClose(&bzerror, b, 0,0,0); // error // the writer will get smitten with sigpipe close(fd); return; } bzerror = BZ_OK; while ((nBuf=read(fd, buf, BUFFER_SIZE))>0) { BZ2_bzWrite(&bzerror, b, buf, nBuf); if (bzerror!=BZ_OK) { BZ2_bzWriteClose(&bzerror, b, 0,0,0); close(fd); return; } } BZ2_bzWriteClose(&bzerror, b, 0,0,0); close(fd); }
static void bzip_write( const char *buffer, size_t buffer_length, BZFILE *file) { int bzerror; BZ2_bzWrite(&bzerror, file, (void *) buffer, buffer_length); }
void BZ2Stream::write(void* ptr, size_t size) { BZ2_bzWrite(&bzerror_, bzfile_, ptr, size); switch (bzerror_) { case BZ_IO_ERROR: throw BagException("BZ_IO_ERROR: error writing the compressed file"); } setCompressedIn(getCompressedIn() + size); }
bool Bz2::Write(const void *buffer, size_t size, size_t count) { m_errcode = BZ_OK; BZ2_bzWrite(&m_errcode, m_bzFile, (void*)buffer, (int)(size * count)); if (m_errcode != BZ_OK) { return false; } return true; }
bool AddOperatorEnd() { if(!WriteOp()) return false; printf("-end\n"); int bzerror; unsigned char code = OPERATOR_END; BZ2_bzWrite(&bzerror, _bzpatch, &code, sizeof(code)); return true; }
void NBBZip2::create() { int error; // Write to the bz2 file created above std::ifstream ifile( qPrintable( fileName ), std::ifstream::binary ); off_t fileSize = QFileInfo( fileName ).size(); if ( fileSize < MAX_READ_SIZE ) { char buffer[ MAX_READ_SIZE ] = { "\x00" }; ifile.read( buffer, fileSize ); BZ2_bzWrite( &error, bz2, buffer, fileSize ); } else { off_t nextChunkSize = MAX_READ_SIZE, remaining = fileSize - MAX_READ_SIZE; while ( nextChunkSize > 0 ) { char buffer[ MAX_READ_SIZE ] = { "\x00" }; ifile.read( buffer, nextChunkSize ); BZ2_bzWrite( &error, bz2, buffer, nextChunkSize ); nextChunkSize = ( remaining > MAX_READ_SIZE ) ? MAX_READ_SIZE : remaining; remaining -= nextChunkSize; } } if ( error != BZ_OK ) return; fflush( bzFile ); // Close the file unsigned int inBytes, outBytes; BZ2_bzWriteClose( &error, bz2, 0, &inBytes, &outBytes ); if ( error != BZ_OK ) return; fclose( bzFile ); return; }
bool Bz2LineWriter::writeLine(string line) { if (uncompressed) { *out << line; // if (line.find('\n') != string::npos) *out << flush; return !(*out).fail(); } else { #ifdef __debug_writer__ // Debugger(); wcerr << L"Trying to write a line… (finished is " << finished << L", bzerror is " << bzerror << L")" << endl; #endif while (line.size() > bufSize) { /* get data to write into buf, and set nBuf appropriately */ strncpy(buf, line.c_str(), bufSize); line = line.substr(bufSize); BZ2_bzWrite(&bzerror, bzip2Handle, buf, bufSize); if (bzerror == BZ_IO_ERROR) { BZ2_bzWriteClose(&bzerror, bzip2Handle, 0, NULL, NULL); fclose(plainHandle); /* handle error */ wcout << L"Trouble writing the stupid file again!!!" << endl; exit(7); } } if (line.size() > 0) { strncpy(buf, line.c_str(), line.size()); BZ2_bzWrite(&bzerror, bzip2Handle, buf, (int)line.size()); if (bzerror == BZ_IO_ERROR) { BZ2_bzWriteClose(&bzerror, bzip2Handle, 0, NULL, NULL); fclose(plainHandle); /* handle error */ wcout << L"Trouble writing the stupid file again!!!" << endl; exit(8); } } return true; } }
static void compressed_write(pcu_file* pf, void const* data, size_t size) { int bzerror; int len; void* bzip2_is_not_const_correct; assert(size < INT_MAX); len = size; bzip2_is_not_const_correct = (void*)data; BZ2_bzWrite(&bzerror, pf->bzf, bzip2_is_not_const_correct, len); if (bzerror != BZ_OK) reel_fail("BZ2_bzWrite failed with code %d", bzerror); }
bool WriteOp() { int bzerror; unsigned char code = _Op; switch(_Op) { case OPERATOR_NA: break; case OPERATOR_APPEND: // size, patch BZ2_bzWrite(&bzerror, _bzpatch, &code, sizeof(code)); if(bzerror!=BZ_OK) return false; BZ2_bzWrite(&bzerror, _bzpatch, &_size, 4); if(bzerror!=BZ_OK) return false; BZ2_bzWrite(&bzerror, _bzpatch, &_patch_offset, 4); if(bzerror!=BZ_OK) return false; break; case OPERATOR_COPY: // size, offset printf("-copy %d %d\n", _size, _offset); BZ2_bzWrite(&bzerror, _bzpatch, &code, sizeof(code)); if(bzerror!=BZ_OK) return false; BZ2_bzWrite(&bzerror, _bzpatch, &_size, 4); if(bzerror!=BZ_OK) return false; BZ2_bzWrite(&bzerror, _bzpatch, &_offset, 4); if(bzerror!=BZ_OK) return false; break; case OPERATOR_PATCH: // offset, size, patch BZ2_bzWrite(&bzerror, _bzpatch, &code, sizeof(code)); if(bzerror!=BZ_OK) return false; BZ2_bzWrite(&bzerror, _bzpatch, &_offset, 4); if(bzerror!=BZ_OK) return false; BZ2_bzWrite(&bzerror, _bzpatch, &_size, 4); if(bzerror!=BZ_OK) return false; BZ2_bzWrite(&bzerror, _bzpatch, &_patch_offset, 4); if(bzerror!=BZ_OK) return false; break; default: return false; } _Op = OPERATOR_NA; return true; }
bool AddFile(const std::string& file, const std::string src_md5, const std::string dst_md5) { if(!WriteOp()) return false; printf("file %s\n", file.c_str()); int bzerror; unsigned short len = file.size(); BZ2_bzWrite(&bzerror, _bzpatch, &len, sizeof(len)); if(bzerror!=BZ_OK) return false; BZ2_bzWrite(&bzerror, _bzpatch, (void*)file.c_str(), len); if(bzerror!=BZ_OK) return false; len = (unsigned short)src_md5.size(); BZ2_bzWrite(&bzerror, _bzpatch, &len, sizeof(len)); if(bzerror!=BZ_OK) return false; BZ2_bzWrite(&bzerror, _bzpatch, (void*)src_md5.c_str(), len); if(bzerror!=BZ_OK) return false; len = (unsigned short)dst_md5.size(); BZ2_bzWrite(&bzerror, _bzpatch, &len, sizeof(len)); if(bzerror!=BZ_OK) return false; BZ2_bzWrite(&bzerror, _bzpatch, (void*)dst_md5.c_str(), len); if(bzerror!=BZ_OK) return false; return true; }
size_t BzipOutputStream::write(const void* buf, size_t size) { assert(m_fp); assert(m_cf); int err = BZ_OK; BZ2_bzWrite(&err, m_fp, (void*)buf, size); if (BZ_OK != err) { std::ostringstream oss; oss << "BZ2_bzWrite err=" << strbzerr(err) << ", in " << BOOST_CURRENT_FUNCTION; throw IOException(oss.str().c_str()); } return size; }
int fsWriteCompressed(FILESYSTEM_FILE *f, void *data, int len) { BZFILE *bzf; int err; if (!f) return -1; if (!(bzf = BZ2_bzWriteOpen(&err, f->fp, 9, 0, 0))) return -1; BZ2_bzWrite(&err, bzf, data, len); BZ2_bzWriteClose(&err, bzf, 0, NULL, NULL); f->pos = ftell(f->fp); return 0; }
int main() { enum { nBuf = 100 }; char buf[nBuf]; for (int i = 0; i < nBuf; ++i) { buf[i] = static_cast<char>(i); } int bzerror(0); int abandon(0); unsigned int nbytes_in(0); unsigned int nbytes_out(0); FILE* f = fopen("myfile.bz2", "w"); if (!f) { std::cerr << "fopen failed" << std::endl; return EXIT_FAILURE; } BZFILE* b = BZ2_bzWriteOpen(&bzerror, f, 9, 0, 0); if (bzerror != BZ_OK) { BZ2_bzWriteClose(&bzerror, b, abandon, &nbytes_in, &nbytes_out); std::cerr << "BZ2_bzWriteOpen failed" << std::endl; return EXIT_FAILURE; } BZ2_bzWrite(&bzerror, b, buf, nBuf); if (bzerror == BZ_IO_ERROR) { BZ2_bzWriteClose(&bzerror, b, abandon, &nbytes_in, &nbytes_out); std::cerr << "BZ_IO_ERROR (write)" << std::endl; return EXIT_FAILURE; } BZ2_bzWriteClose(&bzerror, b, abandon, &nbytes_in, &nbytes_out); if (bzerror == BZ_IO_ERROR) { std::cerr << "BZ_IO_ERROR (close)" << std::endl; return EXIT_FAILURE; } }
int bz2streambuf::overflow(int c) { Assert(write); int w = pptr() - pbase(); if (c != EOF) { *pptr() = c; ++w; } BZ2_bzWrite(&bzerror, bzfile, pbase(), w * sizeof(char)); if (bzerror == BZ_OK) { setp(buf, buf + bufsize - 1); return 0; } else { error = true; setp(0, 0); return EOF; } }
int mpk_package_packmpk(struct mpk_pkginfo *pkg, const char *srcdir, const char *outdir) { TAR *tar; BZFILE *bz2; FILE *tbz2_file; int tar_fd; int bzerr; char src[PATH_MAX + 1]; char dst[PATH_MAX + 1]; char tar_fpath[PATH_MAX + 1]; char tbz2_fpath[PATH_MAX + 1]; unsigned char buffer[CHUNKSIZE]; int size; struct mpk_file *file; /* create tar */ sprintf(tar_fpath, "/tmp/%s_files.tar", pkg->name); if (access(tar_fpath, F_OK) == 0) if (unlink(tar_fpath) != 0) goto err0; if (tar_open(&tar, tar_fpath, NULL, O_WRONLY|O_CREAT, 0644, 0) != 0) goto err0; for (file = pkg->tool.lh_first; file; file = file->items.le_next) { sprintf(src, "%s/tool/%s", srcdir, file->name); sprintf(dst, "tool/%s", file->name); if (tar_append_tree(tar, src, dst) != 0) goto err2; } for (file = pkg->data.lh_first; file; file = file->items.le_next) { if (file->type == MPK_FILE_TYPE_R || file->type == MPK_FILE_TYPE_EXE || file->type == MPK_FILE_TYPE_W || file->type == MPK_FILE_TYPE_S) { sprintf(src, "%s/data/%s", srcdir, file->name); sprintf(dst, "data/%s", file->name); if (tar_append_tree(tar, src, dst) != 0) goto err2; } } sprintf(src, "%s/manifest.txt", srcdir); if (tar_append_file(tar, src, "manifest.txt") != 0) goto err2; tar_close(tar); /* compress using bz2 */ int version_str_len = mpk_version_serializedsize(&pkg->version); char *version_str; if (!(version_str = malloc(version_str_len + 1))) goto err2; if (mpk_version_serialize(version_str, NULL, version_str_len, &pkg->version) != MPK_SUCCESS) { free(version_str); goto err2; } version_str[version_str_len] = 0; sprintf(tbz2_fpath, "%s/%s-%s.mpk", outdir, pkg->name, version_str); free(version_str); printf("path:%s\n", tbz2_fpath); if ((tar_fd = open(tar_fpath, O_RDONLY)) == -1) goto err1; if ((tbz2_file = fopen(tbz2_fpath, "wb")) == NULL) goto err3; bz2 = BZ2_bzWriteOpen(&bzerr, tbz2_file, 9, 0, 30); if (bzerr != BZ_OK) goto err4; while ((size = read(tar_fd, buffer, CHUNKSIZE)) > 0) BZ2_bzWrite(&bzerr, bz2, buffer, size); BZ2_bzWriteClose(&bzerr, bz2, 0, NULL, NULL); fclose(tbz2_file); close(tar_fd); if (bzerr != BZ_OK || size < 0) goto err1; if (unlink(tar_fpath) != 0) goto err0; return MPK_SUCCESS; err4: fclose(tbz2_file); err3: close(tar_fd); goto err1; err2: tar_close(tar); err1: unlink(tar_fpath); err0: return MPK_FAILURE; }
int bsdiff(u_char* old, off_t oldsize, u_char* newp, off_t newsize, FILE* pf) { size_t offset; off_t *I=NULL,*V=NULL; off_t scan,pos = 0,len; off_t lastscan,lastpos,lastoffset; off_t oldscore,scsc; off_t s,Sf,lenf,Sb,lenb; off_t overlap,Ss,lens; off_t i; off_t dblen,eblen; u_char *db=NULL,*eb=NULL; u_char buf[8]; u_char header[32]; BZFILE * pfbz2=NULL; int bz2err; unsigned int nbytes_in; unsigned int nbytes_out; if(((I=malloc((oldsize+1)*sizeof(off_t)))==NULL) || ((V=malloc((oldsize+1)*sizeof(off_t)))==NULL)) { goto error; } qsufsort(I,V,old,oldsize); free(V); V = NULL; if(((db=malloc(newsize+1))==NULL) || ((eb=malloc(newsize+1))==NULL)) { goto error; } dblen=0; eblen=0; offset = ftell(pf); /* Header is 0 8 length of newp file 8 8 length of bzip2ed ctrl block 16 8 length of bzip2ed diff block 24 8 length of bzip2ed extra block */ /* File is 0 32 Header 32 ?? Bzip2ed ctrl block ?? ?? Bzip2ed diff block ?? ?? Bzip2ed extra block */ memcpy(header, "BSDIFFXX", 8); offtout(0, header + 8); offtout(0, header + 16); offtout(newsize, header + 24); if (fwrite(header, 32, 1, pf) != 1) { printf("fwrite(%s)", "patch_file"); goto error; } /* Compute the differences, writing ctrl as we go */ if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL) { printf("BZ2_bzWriteOpen, bz2err = %d", bz2err); goto error; } scan=0;len=0; lastscan=0;lastpos=0;lastoffset=0; while(scan<newsize) { oldscore=0; for(scsc=scan+=len;scan<newsize;scan++) { len=search(I,old,oldsize,newp+scan,newsize-scan, 0,oldsize,&pos); for(;scsc<scan+len;scsc++) if((scsc+lastoffset<oldsize) && (old[scsc+lastoffset] == newp[scsc])) oldscore++; if(((len==oldscore) && (len!=0)) || (len>oldscore+8)) break; if((scan+lastoffset<oldsize) && (old[scan+lastoffset] == newp[scan])) oldscore--; }; if((len!=oldscore) || (scan==newsize)) { s=0;Sf=0;lenf=0; for(i=0;(lastscan+i<scan)&&(lastpos+i<oldsize);) { if(old[lastpos+i]==newp[lastscan+i]) s++; i++; if(s*2-i>Sf*2-lenf) { Sf=s; lenf=i; }; }; lenb=0; if(scan<newsize) { s=0;Sb=0; for(i=1;(scan>=lastscan+i)&&(pos>=i);i++) { if(old[pos-i]==newp[scan-i]) s++; if(s*2-i>Sb*2-lenb) { Sb=s; lenb=i; }; }; }; if(lastscan+lenf>scan-lenb) { overlap=(lastscan+lenf)-(scan-lenb); s=0;Ss=0;lens=0; for(i=0;i<overlap;i++) { if(newp[lastscan+lenf-overlap+i]== old[lastpos+lenf-overlap+i]) s++; if(newp[scan-lenb+i]== old[pos-lenb+i]) s--; if(s>Ss) { Ss=s; lens=i+1; }; }; lenf+=lens-overlap; lenb-=lens; }; for(i=0;i<lenf;i++) db[dblen+i]=newp[lastscan+i]-old[lastpos+i]; for(i=0;i<(scan-lenb)-(lastscan+lenf);i++) eb[eblen+i]=newp[lastscan+lenf+i]; dblen+=lenf; eblen+=(scan-lenb)-(lastscan+lenf); offtout(lenf,buf); BZ2_bzWrite(&bz2err, pfbz2, buf, 8); if (bz2err != BZ_OK) { printf("BZ2_bzWrite, bz2err = %d", bz2err); goto error; } offtout((scan-lenb)-(lastscan+lenf),buf); BZ2_bzWrite(&bz2err, pfbz2, buf, 8); if (bz2err != BZ_OK) { printf("BZ2_bzWrite, bz2err = %d", bz2err); goto error; } offtout((pos-lenb)-(lastpos+lenf),buf); BZ2_bzWrite(&bz2err, pfbz2, buf, 8); if (bz2err != BZ_OK) { printf("BZ2_bzWrite, bz2err = %d", bz2err); goto error; } lastscan=scan-lenb; lastpos=pos-lenb; lastoffset=pos-scan; }; }; BZ2_bzWriteClose(&bz2err, pfbz2, 0, &nbytes_in, &nbytes_out); pfbz2 = NULL; if (bz2err != BZ_OK) { printf("BZ2_bzWriteClose, bz2err = %d", bz2err); goto error; } /* Compute size of compressed ctrl data */ if ((len = ftell(pf)) == -1) { printf("ftello"); goto error; } offtout((off_t)(len-32-offset), header + 8); printf("--ctrl data %d %d %d\n", len-32-offset, nbytes_in, nbytes_out); /* Write compressed diff data */ if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL) { printf("BZ2_bzWriteOpen, bz2err = %d", bz2err); goto error; } BZ2_bzWrite(&bz2err, pfbz2, db, dblen); if (bz2err != BZ_OK) { printf("BZ2_bzWrite, bz2err = %d", bz2err); goto error; } BZ2_bzWriteClose(&bz2err, pfbz2, 0, &nbytes_in, &nbytes_out); pfbz2 = NULL; if (bz2err != BZ_OK) { printf("BZ2_bzWriteClose, bz2err = %d", bz2err); goto error; } /* Compute size of compressed diff data */ if ((newsize = ftell(pf)) == -1) { printf("ftello"); goto error; } offtout(newsize - len, header + 16); printf("--diff data %d %d %d\n", newsize - len, nbytes_in, nbytes_out); /* Write compressed extra data */ if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL) { printf("BZ2_bzWriteOpen, bz2err = %d", bz2err); goto error; } BZ2_bzWrite(&bz2err, pfbz2, eb, eblen); if (bz2err != BZ_OK) { printf("BZ2_bzWrite, bz2err = %d", bz2err); goto error; } BZ2_bzWriteClose(&bz2err, pfbz2, 0, &nbytes_in, &nbytes_out); pfbz2 = NULL; if (bz2err != BZ_OK) { printf("BZ2_bzWriteClose, bz2err = %d", bz2err); goto error; } if ((len = ftell(pf)) == -1) { printf("ftello"); goto error; } printf("--extra data %d %d %d\n", len - newsize, nbytes_in, nbytes_out); printf("--total %d\n", len - offset); /* Seek to the beginning, write the header, and close the file */ if (fseek(pf, (long)(0+offset), SEEK_SET)) { printf("fseeko"); goto error; } if (fwrite(header, 32, 1, pf) != 1) { printf("fwrite(%s)", "patch_file"); goto error; } fseek(pf, len, SEEK_SET); /* Free the memory we used */ free(db); free(eb); free(I); return 0; error: if(pfbz2) BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL); if(I) free(I); if(V) free(V); if(db) free(db); if(eb) free(eb); return -1; }
static int file_load(char *fn_in, char *infmt, char *outfmt) { char buf_in[BUFLEN], buf_out[BUFLEN]; FILE *fp_in, *fp_out; BZFILE *bzf_in, *bzf_out; gzFile gzf_in, gzf_out; lzma_stream lzma_str = LZMA_STREAM_INIT; struct timeval tv_start, tv_stop; int ret, err, fmt_in, fmt_out, sl, buf_in_pos, buf_in_len, buf_out_len; uint64_t bytes, usec; fp_in = fp_out = bzf_in = bzf_out = gzf_in = gzf_out = NULL; fmt_in = str2fmt(infmt); fmt_out = str2fmt(outfmt); //printf("fmt_in %u fmt_out %u\n", fmt_in, fmt_out); if(fmt_in == fmt_out) { fprintf(stderr, "fmt_in %d == fmt_out %d. not supported.\n", fmt_in, fmt_out); return -1; } ret = gettimeofday(&tv_start, NULL); if(ret != 0) { fprintf(stderr, "gettimeofday failed\n"); } if(fmt_in == FMT_GZIP) { gzf_in = gzopen(fn_in, "rb"); if(!gzf_in) { printf("file_load: gzopen failed\n"); return -1; } } else { fp_in = fopen(fn_in, "rb"); if(!fp_in) { printf("file_load: fopen failed\n"); return -1; } if(fmt_in == FMT_BZIP2) { bzf_in = BZ2_bzReadOpen(&err, fp_in, 0, 0, NULL, 0); if(!bzf_in) { fprintf(stderr, "bzReadOpen bzerr %d\n", err); fclose(fp_in); return -1; } } else if(fmt_in == FMT_XZ) { ret = xz_dec_init(&lzma_str); if(ret != LZMA_OK) { printf("xz_enc_init failed %d\n", ret); fclose(fp_out); return -1; } } } sl = strlen(fn_in); fn_in[sl-strlen(infmt)-1] = 0; snprintf(buf_out, FILENAME_MAX, "%s.%s", fn_in, outfmt); buf_out[FILENAME_MAX-1] = 0; fn_in[sl-strlen(infmt)-1] = '.'; printf("%s -> %s", fn_in, buf_out); if(fmt_out == FMT_GZIP) { gzf_out = gzopen(buf_out, "wb9"); if(gzf_out == NULL) { printf("file_load: gzopen failed\n"); return -1; } } else { fp_out = fopen(buf_out, "wb"); if(!fp_out) { printf("fp_out fopen failed\n"); return 1; } if(fmt_out == FMT_BZIP2) { bzf_out = BZ2_bzWriteOpen(&err, fp_out, 9, 0, 0); if(!bzf_out) { printf("bzerr %d\n", err); fclose(fp_out); return -1; } } else if(fmt_out == FMT_XZ) { ret = xz_enc_init(&lzma_str); if(ret != LZMA_OK) { printf("xz_enc_init failed %d\n", ret); fclose(fp_out); return -1; } } } buf_in_pos = 0; buf_in_len = 0; bytes = 0; while(1) { switch(fmt_in) { case FMT_BZIP2: { ret = BZ2_bzRead(&err, bzf_in, buf_out, BUFLEN); break; } case FMT_GZIP: { ret = gzread(gzf_in, buf_out, BUFLEN); err = BZ_OK; break; } case FMT_RAW: { ret = fread(buf_out, BUFLEN, 1, fp_in); err = BZ_OK; break; } case FMT_XZ: { if(buf_in_len == 0) { ret = fread(buf_in, BUFLEN, 1, fp_in); } ret = xz_dec_read(&lzma_str, buf_in + buf_in_pos, &buf_in_len, buf_out, &buf_out_len); break; } default: { printf("unknown fmt_in\n"); ret = 0; break; } } /* process here */ if((ret > 0) && ((err == BZ_OK) || (err == BZ_STREAM_END))) { bytes += ret; switch(fmt_out) { case FMT_BZIP2: { BZ2_bzWrite(&err, bzf_out, buf_out, ret); break; } case FMT_GZIP: { ret = gzwrite(gzf_out, buf_out, ret); break; } case FMT_XZ: { ret = xz_enc_write(&lzma_str, buf_out, ret, fp_out); break; } case FMT_RAW: { ret = fwrite(buf_out, ret, 1, fp_out); break; } case FMT_NULL: default: { break; } } } else { break; } } switch(fmt_in) { case FMT_BZIP2: { BZ2_bzReadClose(&err, bzf_in); if(err != BZ_OK) { printf("close bzerr %d\n", err); } fclose(fp_in); break; } case FMT_GZIP: { gzclose(gzf_in); break; } case FMT_RAW: { fclose(fp_in); break; } default: { break; } } switch(fmt_out) { case FMT_BZIP2: { BZ2_bzWriteClose(&err, bzf_out, 0, NULL, NULL); if(err != BZ_OK) { printf("close bzerr %d\n", err); } fclose(fp_out); break; } case FMT_GZIP: { gzclose(gzf_out); break; } case FMT_XZ: { ret = xz_enc_exit(&lzma_str, fp_out); fclose(fp_out); break; } case FMT_RAW: { fclose(fp_out); break; } default: { break; } } ret = gettimeofday(&tv_stop, NULL); if(ret != 0) { printf("WARN: gettimeofday failed\n"); } usec = (tv_stop.tv_sec - tv_start.tv_sec) * 1000000 + (tv_stop.tv_usec - tv_start.tv_usec); printf(" [%" PRIu64 " bytes; %" PRIu64 " MiB/s]\n", bytes, bytes / usec); return 0; }
//Private methods bool CtbzPlugin::Compress(const std::string& input, const std::string& output, IProgressbar* callback) { bool Ret = false; FILE* Out = fopen(output.c_str(), "wb"); // Open up the output file if(!Out) { std::cout << i8n("Error out file!") << '\n'; Ret = false; } else { BZFILE* BZ = 0; int Err = 0; BZ = BZ2_bzWriteOpen(&Err, Out, 9, 0, 90); if(Err != BZ_OK) { std::cout << i8n("Error bzWriteOpen!") << '\n'; Ret = false; } else { // Open up the input file std::ifstream In(input.c_str(), std::ios::in | std::ios::binary); if(!In.good()) { std::cout << i8n("Error in file!") << '\n'; Ret = false; } else { // Get the file size. (I hate C I/O, so don't use them :D ) struct stat Info; double Total; //Try to stat file. if(stat(input.c_str(), &Info) == -1) { std::cout << i8n("Cannot stat ") << input.c_str() << '\n'; Ret = false; } else { char Buffer[4096]; memset(Buffer, 0, 4096); Total = Info.st_size; double Done = 0; do { In.read(Buffer, 4096); std::streamsize BytesRead = In.gcount(); Done += BytesRead; int Result = static_cast<int>((Done*50)/Total)+50; std::string Mess(i8n("bz2 compression of\n")); std::stringstream DoneStr; DoneStr << (Result-50)*2; Mess += output + " : " + DoneStr.str() + "%"; bool Continue = callback->UpdateProgress(Mess, false, Result); if(!Continue) break; BZ2_bzWrite(&Err, BZ, Buffer, BytesRead); } while(In.good()); if( In.bad() || !In.eof() ) Ret = false; else Ret = true; In.close(); } // Close up. BZ2_bzWriteClose(&Err, BZ, 0, 0, 0); fclose(Out); Out = 0; } } } return Ret; }
bool GenPatch(const char* patch_file, CBundle& Origin, CBundle& Lastest) { CBundlePatcher patcher; if(!patcher.Open(patch_file)) return false; std::map<std::string, CFile>::iterator i; for(i=Origin._Files.begin(); i!=Origin._Files.end(); i++) { if(Lastest._Files.find(i->first)==Lastest._Files.end()) { if(!patcher.DelFile(i->first)) return false; } } for(i=Lastest._Files.begin(); i!=Lastest._Files.end(); i++) { if(Origin._Files.find(i->first)==Origin._Files.end()) { if(!patcher.AddFile(i->first, "", i->second._MD5)) return false; void* mem; size_t size, offset; if(!ReadFile(i->second, mem, size)) return false; offset = ftell(patcher._stub); if(!patcher.AddOperatorAppend(size, offset)) return false; int bzerror; BZFILE* bzf = BZ2_bzWriteOpen(&bzerror, patcher._stub, 9, 0, 0); if(bzf==NULL) { free(mem); return false; } BZ2_bzWrite(&bzerror, bzf, mem, size); free(mem); if(bzerror!=BZ_OK) { BZ2_bzWriteClose(&bzerror, bzf, 0, NULL, NULL); return false; } unsigned int inbytes, outbytes; BZ2_bzWriteClose(&bzerror, bzf, 0, &inbytes, &outbytes); if(bzerror!=BZ_OK) { return false; } if(!patcher.AddOperatorEnd()) return false; } else { CFile& srcf = Origin._Files[i->first]; CFile& dstf = i->second; if(srcf._MD5!=dstf._MD5) { if(!patcher.AddFile(i->first, srcf._MD5, dstf._MD5)) return false; void* src = NULL; void* dst = NULL; size_t src_size, dst_size, offset; for(size_t i=0; i<dstf._Sections.size(); i++) { offset = ftell(patcher._stub); CSection* s = srcf.GetSectionByMD5(dstf._Sections[i]._MD5); if(s==NULL) { s = srcf.GetSectionByName(dstf._Sections[i]._Name); } if(s) { if(s->_MD5==dstf._Sections[i]._MD5) { // copy patcher.AddOperatorCopy(s->_Size, s->_Offset); } else { if(src==NULL && !ReadFile(srcf, src, src_size)) return false; if(dst==NULL && !ReadFile(dstf, dst, dst_size)) return false; // patch patcher.AddOperatorPatch(s->_Offset, s->_Size, offset); bsdiff((u_char*)src+s->_Offset, s->_Size, (u_char*)dst+dstf._Sections[i]._Offset, dstf._Sections[i]._Size, patcher._stub); } } else { if(dst==NULL && !ReadFile(dstf, dst, dst_size)) return false; // append if(!patcher.AddOperatorAppend(dstf._Sections[i]._Size, offset)) return false; int bzerror; BZFILE* bzf = BZ2_bzWriteOpen(&bzerror, patcher._stub, 9, 0, 0); if(bzf==NULL) return false; BZ2_bzWrite(&bzerror, bzf, (char*)dst+dstf._Sections[i]._Offset, dstf._Sections[i]._Size); if(bzerror!=BZ_OK) { BZ2_bzWriteClose(&bzerror, bzf, 0, NULL, NULL); return false; } unsigned int inbytes, outbytes; BZ2_bzWriteClose(&bzerror, bzf, 0, &inbytes, &outbytes); if(bzerror!=BZ_OK) { return false; } } } if(!patcher.AddOperatorEnd()) return false; if(src) free(src); if(dst) free(dst); } } } if(!patcher.DelFile("")) return false; if(!patcher.Close(true)) return false; return true; }
int _nrrdEncodingBzip2_write(FILE *file, const void *_data, size_t elNum, const Nrrd *nrrd, NrrdIoState *nio) { char me[]="_nrrdEncodingBzip2_write", err[BIFF_STRLEN]; #if TEEM_BZIP2 size_t bsize, total_written, block_size; int bs, bzerror=BZ_OK; char *data; BZFILE* bzfout; bsize = nrrdElementSize(nrrd)*elNum; /* Set compression block size. */ if (1 <= nio->bzip2BlockSize && nio->bzip2BlockSize <= 9) { bs = nio->bzip2BlockSize; } else { bs = 9; } /* Open bzfile for writing. Verbosity and work factor are set to default values. */ bzfout = BZ2_bzWriteOpen(&bzerror, file, bs, 0, 0); if (BZ_OK != bzerror) { sprintf(err, "%s: error opening BZFILE: %s", me, BZ2_bzerror(bzfout, &bzerror)); biffAdd(NRRD, err); BZ2_bzWriteClose(&bzerror, bzfout, 0, NULL, NULL); return 1; } /* bzip2 can handle data sizes up to INT_MAX, so we can't just pass in the bsize, because it might be too large for an int. Therefore it must be read in chunks if the bsize is larger than INT_MAX. */ if (bsize <= INT_MAX) { block_size = bsize; } else { block_size = INT_MAX; } /* This counter will help us to make sure that we write as much data as we think we should. */ total_written = 0; /* Pointer to the blocks as we write them. */ data = (char *)_data; /* Ok, now we can begin writing. */ bzerror = BZ_OK; while (bsize - total_written > block_size) { BZ2_bzWrite(&bzerror, bzfout, data, block_size); if (BZ_OK != bzerror) break; /* Increment the data pointer to the next available spot. */ data += block_size; total_written += block_size; } /* write the last (possibly smaller) block when its humungous data; write the whole data when its small */ if (BZ_OK == bzerror) { block_size = bsize >= total_written ? bsize - total_written : 0; BZ2_bzWrite(&bzerror, bzfout, data, block_size); total_written += block_size; } if (BZ_OK != bzerror) { sprintf(err, "%s: error writing to BZFILE: %s", me, BZ2_bzerror(bzfout, &bzerror)); biffAdd(NRRD, err); return 1; } /* Close the BZFILE. */ BZ2_bzWriteClose(&bzerror, bzfout, 0, NULL, NULL); if (BZ_OK != bzerror) { sprintf(err, "%s: error closing BZFILE: %s", me, BZ2_bzerror(bzfout, &bzerror)); biffAdd(NRRD, err); return 1; } /* Check to see if we got out as much as we thought we should. */ if (total_written != bsize) { sprintf(err, "%s: expected to write " _AIR_SIZE_T_CNV " bytes, but only " "wrote " _AIR_SIZE_T_CNV, me, bsize, total_written); biffAdd(NRRD, err); return 1; } return 0; #else AIR_UNUSED(file); AIR_UNUSED(_data); AIR_UNUSED(elNum); AIR_UNUSED(nrrd); AIR_UNUSED(nio); sprintf(err, "%s: sorry, this nrrd not compiled with bzip2 enabled", me); biffAdd(NRRD, err); return 1; #endif }
void file_read_func(gpointer data, gpointer user_data) { tp_args_t* tp_arg = (tp_args_t*) data; gchar buf[READBUFZ]; size_t nread=0, currPos=tp_arg->startPos, readSz=READBUFZ; FILE* fd = fopen(tp_arg->filen, "r"); FILE* tmpFd = fopen(tp_arg->tmpFilen, "w"); BZFILE* b; int bzerror; gint processed = 0; unsigned int bytesIn=0, bytesOut=0; if (!fd) { /* handle error */ perror("couln't open input file"); g_atomic_int_set(&(tp_arg->error), TRUE); return; } if (!tmpFd) { /* handle error */ perror("couln't open tempfile"); g_atomic_int_set(&(tp_arg->error), TRUE); return; } b = BZ2_bzWriteOpen( &bzerror, tmpFd, 9, 0, 0 ); if (bzerror != BZ_OK) { /* handle error */ fprintf(stderr, "BZError %d\n", bzerror); if (!errno) perror("system Error"); g_atomic_int_set(&(tp_arg->error), TRUE); BZ2_bzWriteClose(&bzerror, b, FALSE, NULL, NULL); return; } fseek(fd, tp_arg->startPos, SEEK_SET); while (currPos < tp_arg->endPos && !feof(fd) && !_recieved_SIGINT) { if (currPos + readSz > tp_arg->endPos) readSz = tp_arg->endPos - currPos; nread = fread(&(buf[0]), 1, readSz, fd); currPos += nread; if (tp_arg->verbose) { processed = (currPos - tp_arg->startPos)/(double)(tp_arg->endPos - tp_arg->startPos) * 100; g_atomic_int_set(&(tp_arg->processed), processed); } /* fprintf(stderr, "Read %d, %ld remain\n", nread, tp_arg->endPos - currPos); */ BZ2_bzWrite(&bzerror, b, &(buf[0]), nread); if (bzerror == BZ_IO_ERROR) { BZ2_bzWriteClose(&bzerror, b, FALSE, NULL, NULL); /* handle error */ fprintf(stderr, "BZError %d\n", bzerror); if (!errno) perror("system Error"); g_atomic_int_set(&(tp_arg->error), TRUE); break; } } BZ2_bzWriteClose(&bzerror, b, FALSE, &bytesIn, &bytesOut); if (bzerror == BZ_IO_ERROR) { /* handle error */ fprintf(stderr, "BZError %d\n", bzerror); if (!errno) perror("system Error"); g_atomic_int_set(&(tp_arg->error), TRUE); } fclose(fd); fclose(tmpFd); g_atomic_int_set(&(tp_arg->done), TRUE); }
// This is main() from bsdiff.c, with the following changes: // // - old, oldsize, newdata, newsize are arguments; we don't load this // data from files. old and newdata are owned by the caller; we // don't free them at the end. // // - the "I" block of memory is owned by the caller, who passes a // pointer to *I, which can be NULL. This way if we call // bsdiff() multiple times with the same 'old' data, we only do // the qsufsort() step the first time. // int bsdiff(u_char* old, off_t oldsize, off_t** IP, u_char* newdata, off_t newsize, const char* patch_filename) { int fd; off_t *I; off_t scan,pos,len; off_t lastscan,lastpos,lastoffset; off_t oldscore,scsc; off_t s,Sf,lenf,Sb,lenb; off_t overlap,Ss,lens; off_t i; off_t dblen,eblen; u_char *db,*eb; u_char buf[8]; u_char header[32]; FILE * pf; BZFILE * pfbz2; int bz2err; if (*IP == NULL) { off_t* V; *IP = reinterpret_cast<off_t*>(malloc((oldsize+1) * sizeof(off_t))); V = reinterpret_cast<off_t*>(malloc((oldsize+1) * sizeof(off_t))); qsufsort(*IP, V, old, oldsize); free(V); } I = *IP; if(((db=reinterpret_cast<u_char*>(malloc(newsize+1)))==NULL) || ((eb=reinterpret_cast<u_char*>(malloc(newsize+1)))==NULL)) err(1,NULL); dblen=0; eblen=0; /* Create the patch file */ if ((pf = fopen(patch_filename, "w")) == NULL) err(1, "%s", patch_filename); /* Header is 0 8 "BSDIFF40" 8 8 length of bzip2ed ctrl block 16 8 length of bzip2ed diff block 24 8 length of new file */ /* File is 0 32 Header 32 ?? Bzip2ed ctrl block ?? ?? Bzip2ed diff block ?? ?? Bzip2ed extra block */ memcpy(header,"BSDIFF40",8); offtout(0, header + 8); offtout(0, header + 16); offtout(newsize, header + 24); if (fwrite(header, 32, 1, pf) != 1) err(1, "fwrite(%s)", patch_filename); /* Compute the differences, writing ctrl as we go */ if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL) errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err); scan=0; len=0; lastscan=0; lastpos=0; lastoffset=0; while(scan<newsize) { oldscore=0; for(scsc=scan+=len; scan<newsize; scan++) { len=search(I,old,oldsize,newdata+scan,newsize-scan, 0,oldsize,&pos); for(; scsc<scan+len; scsc++) if((scsc+lastoffset<oldsize) && (old[scsc+lastoffset] == newdata[scsc])) oldscore++; if(((len==oldscore) && (len!=0)) || (len>oldscore+8)) break; if((scan+lastoffset<oldsize) && (old[scan+lastoffset] == newdata[scan])) oldscore--; }; if((len!=oldscore) || (scan==newsize)) { s=0; Sf=0; lenf=0; for(i=0; (lastscan+i<scan)&&(lastpos+i<oldsize);) { if(old[lastpos+i]==newdata[lastscan+i]) s++; i++; if(s*2-i>Sf*2-lenf) { Sf=s; lenf=i; }; }; lenb=0; if(scan<newsize) { s=0; Sb=0; for(i=1; (scan>=lastscan+i)&&(pos>=i); i++) { if(old[pos-i]==newdata[scan-i]) s++; if(s*2-i>Sb*2-lenb) { Sb=s; lenb=i; }; }; }; if(lastscan+lenf>scan-lenb) { overlap=(lastscan+lenf)-(scan-lenb); s=0; Ss=0; lens=0; for(i=0; i<overlap; i++) { if(newdata[lastscan+lenf-overlap+i]== old[lastpos+lenf-overlap+i]) s++; if(newdata[scan-lenb+i]== old[pos-lenb+i]) s--; if(s>Ss) { Ss=s; lens=i+1; }; }; lenf+=lens-overlap; lenb-=lens; }; for(i=0; i<lenf; i++) db[dblen+i]=newdata[lastscan+i]-old[lastpos+i]; for(i=0; i<(scan-lenb)-(lastscan+lenf); i++) eb[eblen+i]=newdata[lastscan+lenf+i]; dblen+=lenf; eblen+=(scan-lenb)-(lastscan+lenf); offtout(lenf,buf); BZ2_bzWrite(&bz2err, pfbz2, buf, 8); if (bz2err != BZ_OK) errx(1, "BZ2_bzWrite, bz2err = %d", bz2err); offtout((scan-lenb)-(lastscan+lenf),buf); BZ2_bzWrite(&bz2err, pfbz2, buf, 8); if (bz2err != BZ_OK) errx(1, "BZ2_bzWrite, bz2err = %d", bz2err); offtout((pos-lenb)-(lastpos+lenf),buf); BZ2_bzWrite(&bz2err, pfbz2, buf, 8); if (bz2err != BZ_OK) errx(1, "BZ2_bzWrite, bz2err = %d", bz2err); lastscan=scan-lenb; lastpos=pos-lenb; lastoffset=pos-scan; }; }; BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL); if (bz2err != BZ_OK) errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err); /* Compute size of compressed ctrl data */ if ((len = ftello(pf)) == -1) err(1, "ftello"); offtout(len-32, header + 8); /* Write compressed diff data */ if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL) errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err); BZ2_bzWrite(&bz2err, pfbz2, db, dblen); if (bz2err != BZ_OK) errx(1, "BZ2_bzWrite, bz2err = %d", bz2err); BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL); if (bz2err != BZ_OK) errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err); /* Compute size of compressed diff data */ if ((newsize = ftello(pf)) == -1) err(1, "ftello"); offtout(newsize - len, header + 16); /* Write compressed extra data */ if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL) errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err); BZ2_bzWrite(&bz2err, pfbz2, eb, eblen); if (bz2err != BZ_OK) errx(1, "BZ2_bzWrite, bz2err = %d", bz2err); BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL); if (bz2err != BZ_OK) errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err); /* Seek to the beginning, write the header, and close the file */ if (fseeko(pf, 0, SEEK_SET)) err(1, "fseeko"); if (fwrite(header, 32, 1, pf) != 1) err(1, "fwrite(%s)", patch_filename); if (fclose(pf)) err(1, "fclose"); /* Free the memory we used */ free(db); free(eb); return 0; }
bool ApplyPatch(const char* patch_file, const char* path) { FILE* patch = fopen(patch_file, "rb"); int bzerror; FILE* tmp_file = NULL; FILE* src_file = NULL; BZFILE* bzs = NULL; BZFILE* bzf = NULL; if(!patch) { goto error; } char header[16]; fread(header, 1, 16, patch); if(memcmp(header, "JPATCH10", 8)!=0) { goto error; } unsigned int ctrl_offset = (unsigned int)(*((unsigned int*)(header+8 ))); unsigned int data_offset = (unsigned int)(*((unsigned int*)(header+12))); bzs = NULL; bzf = BZ2_bzReadOpen(&bzerror, patch, 0, 0, NULL, 0); if(!bzf) { goto error; } for(;;) { unsigned short len; char fname[500], src_md5[60], dst_md5[60]; BZ2_bzRead(&bzerror, bzf, &len, sizeof(len)); if(bzerror!=BZ_OK) { goto error; } BZ2_bzRead(&bzerror, bzf, &fname, len); if(bzerror!=BZ_OK) { if(bzerror==BZ_STREAM_END) { break; } else { goto error; } } fname[len] = '\0'; BZ2_bzRead(&bzerror, bzf, &len, sizeof(len)); if(bzerror!=BZ_OK) { goto error; } if(len>=sizeof(src_md5)) { goto error; } BZ2_bzRead(&bzerror, bzf, &src_md5, len); if(bzerror!=BZ_OK) { goto error; } src_md5[len] = '\0'; BZ2_bzRead(&bzerror, bzf, &len, sizeof(len)); if(bzerror!=BZ_OK) { goto error; } if(len>=sizeof(dst_md5)) { goto error; } BZ2_bzRead(&bzerror, bzf, &dst_md5, len); if(bzerror!=BZ_OK) { goto error; } dst_md5[len] = '\0'; char dst_filename[400]; sprintf(dst_filename, "%s%s", path, fname); char tmp_filename[400]; sprintf(tmp_filename, "%s.tmp", dst_filename); bool skip = false; src_file = fopen(dst_filename, "rb"); if(src_file) { char md5[60]; if(!GetMD5(src_file, md5)) { goto error; } if(strcmp(md5, dst_md5)==0) { skip = true; } else { if(src_md5[0]!='\0' && strcmp(md5, src_md5)!=0) { goto error; } } } else { if(src_md5[0]!='\0') { goto error; } MakeDir_P(tmp_filename); tmp_file = fopen(tmp_filename, "wb"); if(!tmp_file) { goto error; } } for(;;) { unsigned char code; BZ2_bzRead(&bzerror, bzf, &code, sizeof(code)); if(bzerror!=BZ_OK) { goto error; } if(code==OPERATOR_END) break; if(code==OPERATOR_APPEND) { printf("%s\n", fname); unsigned int size, offset; BZ2_bzRead(&bzerror, bzf, &size, sizeof(size)); if(bzerror!=BZ_OK) { goto error; } BZ2_bzRead(&bzerror, bzf, &offset, sizeof(offset)); if(bzerror!=BZ_OK) { goto error; } printf("- append %d %d\n", size, offset); if(!skip) { fseek(patch, offset+data_offset, SEEK_SET); bzs = BZ2_bzReadOpen(&bzerror, patch, 0, 0, NULL, 0); if(!bzs) { goto error; } while(size>0) { char mem[1000]; size_t rsize = size>sizeof(mem)?sizeof(mem):size; BZ2_bzRead(&bzerror, bzs, mem, rsize); if(bzerror!=BZ_OK && size!=rsize && bzerror!=BZ_STREAM_END) { goto error; } if(fwrite(mem, 1, rsize, tmp_file)!=rsize) { goto error; } size -= rsize; } BZ2_bzReadClose(&bzerror, bzs); bzs = NULL; if(bzerror!=BZ_OK) { goto error; } } continue; } if(code==OPERATOR_PATCH) { printf("%s\n", fname); unsigned int offset, size, patch_offset; BZ2_bzRead(&bzerror, bzf, &offset, sizeof(offset)); if(bzerror!=BZ_OK) { goto error; } BZ2_bzRead(&bzerror, bzf, &size, sizeof(size)); if(bzerror!=BZ_OK) { goto error; } BZ2_bzRead(&bzerror, bzf, &patch_offset, sizeof(patch_offset)); if(bzerror!=BZ_OK) { goto error; } if(!skip) { void* mem; mem = ReadFile(src_file, size, offset); if(!mem) { goto error; } fseek(patch, patch_offset+data_offset, SEEK_SET); u_char* newp; off_t newsize; if(bspatch((u_char*)mem, (off_t)size, patch, &newp, &newsize)!=0) { free(mem); goto error; } if(fwrite(newp, 1, newsize, tmp_file)!=newsize) { free(newp); free(mem); goto error; } free(newp); free(mem); } continue; } if(code==OPERATOR_COPY) { unsigned int size, offset; BZ2_bzWrite(&bzerror, bzf, &size, 4); if(bzerror!=BZ_OK) { goto error; } BZ2_bzWrite(&bzerror, bzf, &offset, 4); if(bzerror!=BZ_OK) { goto error; } fseek(src_file, offset, SEEK_SET); while(size>0) { char data[10*1024]; unsigned int s = size; if(s>sizeof(data)) s = sizeof(data); if(fread(data, 1, s, src_file)!=s) { goto error; } if(fwrite(data, 1, s, tmp_file)!=s) { goto error; } size -= s; } continue; } goto error; } if(src_file) { fclose(src_file); src_file = NULL; } fclose(tmp_file); tmp_file = NULL; if(_unlink(dst_filename)!=0 && errno!=ENOENT) goto error; if(rename(tmp_filename, dst_filename)!=0) goto error; } BZ2_bzReadClose(&bzerror, bzf); fclose(patch); return true; error: if(bzs) BZ2_bzReadClose(&bzerror, bzs); if(bzf) BZ2_bzReadClose(&bzerror, bzf); if(patch) fclose(patch); if(tmp_file) fclose(tmp_file); if(src_file) fclose(src_file); return false; }
virtual int write (const void *buffer, int size) { int bzError = BZ_OK; BZ2_bzWrite (&bzError, bzf_, const_cast<void *> (buffer), size); return (bzError == BZ_OK) ? size : 0; }
int DIFF_main(int argc,char *argv[]) { int fd; u_char *old,*_new; off_t oldsize,newsize; off_t *I,*V; off_t scan,pos,len; off_t lastscan,lastpos,lastoffset; off_t oldscore,scsc; off_t s,Sf,lenf,Sb,lenb; off_t overlap,Ss,lens; off_t i; off_t dblen,eblen; u_char *db,*eb; u_char buf[8]; u_char header[32]; FILE * pf; BZFILE * pfbz2; int bz2err; int bytesWritten=0; if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]); /* Allocate oldsize+1 bytes instead of oldsize bytes to ensure that we never try to malloc(0) and get a NULL pointer */ if(((fd=open(argv[1],O_RDONLY|O_BINARY,0))<0) || ((oldsize=lseek(fd,0,SEEK_END))==-1) || ((old=(u_char*)malloc(oldsize+1))==NULL) || (lseek(fd,0,SEEK_SET)!=0) || (read(fd,old,oldsize)!=oldsize) || (close(fd)==-1)) err(1,"%s",argv[1]); if(((I=(off_t*)malloc((oldsize+1)*sizeof(off_t)))==NULL) || ((V=(off_t*)malloc((oldsize+1)*sizeof(off_t)))==NULL)) err(1,NULL); qsufsort(I,V,old,oldsize); free(V); /* Allocate newsize+1 bytes instead of newsize bytes to ensure that we never try to malloc(0) and get a NULL pointer */ if(((fd=open(argv[2],O_RDONLY|O_BINARY,0))<0) || ((newsize=lseek(fd,0,SEEK_END))==-1) || ((_new=(u_char*)malloc(newsize+1))==NULL) || (lseek(fd,0,SEEK_SET)!=0) || (read(fd,_new,newsize)!=newsize) || (close(fd)==-1)) err(1,"%s",argv[2]); if(((db=(u_char*)malloc(newsize+1))==NULL) || ((eb=(u_char*)malloc(newsize+1))==NULL)) err(1,NULL); dblen=0; eblen=0; /* Create the patch file */ if ((pf = fopen(argv[3], "wb")) == NULL) err(1, "%s", argv[3]); /* Header is 0 8 "BSDIFF40" 8 8 length of bzip2ed ctrl block 16 8 length of bzip2ed diff block 24 8 length of new file */ /* File is 0 32 Header 32 ?? Bzip2ed ctrl block ?? ?? Bzip2ed diff block ?? ?? Bzip2ed extra block */ memcpy(header,"BSDIFF40",8); offtout(0, header + 8); offtout(0, header + 16); offtout(newsize, header + 24); if (fwrite(header, 32, 1, pf) != 1) err(1, "fwrite(%s)", argv[3]); /* Compute the differences, writing ctrl as we go */ if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL) errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err); scan=0;len=0; lastscan=0;lastpos=0;lastoffset=0; while(scan<newsize) { oldscore=0; for(scsc=scan+=len;scan<newsize;scan++) { len=search(I,old,oldsize,_new+scan,newsize-scan, 0,oldsize,&pos); for(;scsc<scan+len;scsc++) if((scsc+lastoffset<oldsize) && (old[scsc+lastoffset] == _new[scsc])) oldscore++; if(((len==oldscore) && (len!=0)) || (len>oldscore+8)) break; if((scan+lastoffset<oldsize) && (old[scan+lastoffset] == _new[scan])) oldscore--; }; if((len!=oldscore) || (scan==newsize)) { s=0;Sf=0;lenf=0; for(i=0;(lastscan+i<scan)&&(lastpos+i<oldsize);) { if(old[lastpos+i]==_new[lastscan+i]) s++; i++; if(s*2-i>Sf*2-lenf) { Sf=s; lenf=i; }; }; lenb=0; if(scan<newsize) { s=0;Sb=0; for(i=1;(scan>=lastscan+i)&&(pos>=i);i++) { if(old[pos-i]==_new[scan-i]) s++; if(s*2-i>Sb*2-lenb) { Sb=s; lenb=i; }; }; }; if(lastscan+lenf>scan-lenb) { overlap=(lastscan+lenf)-(scan-lenb); s=0;Ss=0;lens=0; for(i=0;i<overlap;i++) { if(_new[lastscan+lenf-overlap+i]== old[lastpos+lenf-overlap+i]) s++; if(_new[scan-lenb+i]== old[pos-lenb+i]) s--; if(s>Ss) { Ss=s; lens=i+1; }; }; lenf+=lens-overlap; lenb-=lens; }; for(i=0;i<lenf;i++) db[dblen+i]=_new[lastscan+i]-old[lastpos+i]; for(i=0;i<(scan-lenb)-(lastscan+lenf);i++) eb[eblen+i]=_new[lastscan+lenf+i]; dblen+=lenf; eblen+=(scan-lenb)-(lastscan+lenf); offtout(lenf,buf); BZ2_bzWrite(&bz2err, pfbz2, buf, 8); if (bz2err != BZ_OK) errx(1, "BZ2_bzWrite, bz2err = %d", bz2err); bytesWritten+=8; // printf("bz2err 8 %i\n", bytesWritten); offtout((scan-lenb)-(lastscan+lenf),buf); BZ2_bzWrite(&bz2err, pfbz2, buf, 8); if (bz2err != BZ_OK) errx(1, "BZ2_bzWrite, bz2err = %d", bz2err); bytesWritten+=8; // printf("bz2err 8 %i\n", bytesWritten); offtout((pos-lenb)-(lastpos+lenf),buf); BZ2_bzWrite(&bz2err, pfbz2, buf, 8); if (bz2err != BZ_OK) errx(1, "BZ2_bzWrite, bz2err = %d", bz2err); bytesWritten+=8; // printf("bz2err 8 %i\n", bytesWritten); lastscan=scan-lenb; lastpos=pos-lenb; lastoffset=pos-scan; }; }; BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL); if (bz2err != BZ_OK) errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err); /* Compute size of compressed ctrl data */ if ((len = ftello(pf)) == -1) err(1, "ftello"); offtout(len-32, header + 8); /* Write compressed diff data */ if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL) errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err); BZ2_bzWrite(&bz2err, pfbz2, db, dblen); bytesWritten+=dblen; // printf("bz2err dblen %i %i\n", dblen, bytesWritten); if (bz2err != BZ_OK) errx(1, "BZ2_bzWrite, bz2err = %d", bz2err); BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL); if (bz2err != BZ_OK) errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err); /* Compute size of compressed diff data */ if ((newsize = ftello(pf)) == -1) err(1, "ftello"); offtout(newsize - len, header + 16); /* Write compressed extra data */ if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL) errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err); BZ2_bzWrite(&bz2err, pfbz2, eb, eblen); if (bz2err != BZ_OK) errx(1, "BZ2_bzWrite, bz2err = %d", bz2err); bytesWritten+=eblen; //printf("bz2err eblen %i %i\n", eblen, bytesWritten); BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL); if (bz2err != BZ_OK) errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err); // REMOVEME // if ((newsize = ftello(pf)) == -1) // err(1, "ftello"); /* Seek to the beginning, write the header, and close the file */ if (fseeko(pf, 0, SEEK_SET)) err(1, "fseeko"); if (fwrite(header, 32, 1, pf) != 1) err(1, "fwrite(%s)", argv[3]); if (fclose(pf)) err(1, "fclose"); /* Free the memory we used */ free(db); free(eb); free(I); free(old); free(_new); return 0; }