static i64 unzip_literal(rzip_control *control, void *ss, i64 len, uint32 *cksum) { i64 stream_read; uchar *buf; if (unlikely(len < 0)) failure_return(("len %lld is negative in unzip_literal!\n",len), -1); buf = (uchar *)malloc(len); if (unlikely(!buf)) fatal_return(("Failed to malloc literal buffer of size %lld\n", len), -1); stream_read = read_stream(control, ss, 1, buf, len); if (unlikely(stream_read == -1 )) { free(buf); fatal_return(("Failed to read_stream in unzip_literal\n"), -1); } if (unlikely(write_1g(control, buf, (size_t)stream_read) != (ssize_t)stream_read)) { free(buf); fatal_return(("Failed to write literal buffer of size %lld\n", stream_read), -1); } if (!HAS_MD5) *cksum = CrcUpdate(*cksum, buf, stream_read); if (!NO_MD5) md5_process_bytes(buf, stream_read, &control->ctx); free(buf); return stream_read; }
static i64 unzip_match(rzip_control *control, void *ss, i64 len, uint32 *cksum, int chunk_bytes) { i64 offset, n, total, cur_pos; uchar *buf, *off_buf; if (unlikely(len < 0)) failure_return(("len %lld is negative in unzip_match!\n",len), -1); total = 0; cur_pos = seekcur_fdout(control); if (unlikely(cur_pos == -1)) fatal_return(("Seek failed on out file in unzip_match.\n"), -1); /* Note the offset is in a different format v0.40+ */ offset = read_vchars(control, ss, 0, chunk_bytes); if (unlikely(offset == -1)) return -1; if (unlikely(seekto_fdhist(control, cur_pos - offset) == -1)) fatal_return(("Seek failed by %d from %d on history file in unzip_match\n", offset, cur_pos), -1); buf = (uchar *)malloc(len); if (unlikely(!buf)) fatal_return(("Failed to malloc match buffer of size %lld\n", len), -1); off_buf = buf; while (len) { n = MIN(len, offset); if (unlikely(read_fdhist(control, off_buf, (size_t)n) != (ssize_t)n)) { free(buf); fatal_return(("Failed to read %d bytes in unzip_match\n", n), -1); } if (unlikely(write_1g(control, off_buf, (size_t)n) != (ssize_t)n)) { free(buf); fatal_return(("Failed to write %d bytes in unzip_match\n", n), -1); } if (!HAS_MD5) *cksum = CrcUpdate(*cksum, off_buf, n); if (!NO_MD5) md5_process_bytes(off_buf, n, &control->ctx); len -= n; off_buf += n; total += n; } free(buf); return total; }
/* write to a file, return 0 on success and -1 on failure */ static int write_buf(int f, uchar *p, i64 len) { ssize_t ret; ret = write_1g(f, p, (size_t)len); if (ret == -1) { err_msg("Write of length %d failed - %s\n", len, strerror(errno)); return -1; } if (ret != (ssize_t)len) { err_msg("Partial write!? asked for %d bytes but got %d\n", len, ret); return -1; } return 0; }