📄 volzip.cxx
字号:
/* * Copyright (C) 1998, 1999, Jonathan S. Shapiro. * * This file is part of the EROS Operating System. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <sys/fcntl.h>#include <sys/stat.h>#include <assert.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <memory.h>#include <errno.h>#include <erosimg/App.hxx>#include <erosimg/Volume.hxx>#include "zlib.h"static unsigned char in_buf[EROS_SECTOR_SIZE];static unsigned char out_buf[EROS_SECTOR_SIZE];#define COMPRESS_LVL Z_DEFAULT_COMPRESSION#define min(x,y) ((x) > (y) ? (y) : (x))uint32_tVolume::fill_input(z_stream_s& z, int fd, uint32_t len){ if (z.avail_in == 0 && len > 0) { int sz = min(len, EROS_SECTOR_SIZE); if (::read(fd, in_buf, sz) != sz) Diag::fatal(3, "Compressed read failed\n"); z.avail_in = sz; z.next_in = in_buf; len -= sz; } return len;}voidVolume::flush_output(z_stream_s& z, int fd){ int out_count = EROS_SECTOR_SIZE - z.avail_out; if (out_count) { if (::write(fd, out_buf, out_count) != out_count) Diag::fatal(3, "Cannot write decompressed image\n"); z.next_out = out_buf; z.avail_out = EROS_SECTOR_SIZE; }}/* If this is a compressed volume, decompress it to a temporary file. */intVolume::DecompressTarget(){ assert (working_fd == target_fd); if ((volHdr.BootFlags & VolHdr::VF_COMPRESSED) == 0) return 0; /* success */ /* Note /working_fd/ may be -1 at this point... */ if (target_fd == working_fd) { char wkname[] = "/tmp/volzip-XXXXXX"; mkstemp(wkname); working_fd = ::open(wkname, O_RDWR|O_CREAT, 0666); if (working_fd < 0) return errno; unlink(wkname); } if (::lseek(target_fd, (int) 0, SEEK_SET) < 0) return false; /* Copy the bootstrap portion unmodified. */ for (uint32_t s = 0; s < volHdr.BootSectors; s++) { if (::read(target_fd, in_buf, EROS_SECTOR_SIZE) != EROS_SECTOR_SIZE) Diag::fatal(3, "Cannot read compressed image\n"); if (::write(working_fd, in_buf, EROS_SECTOR_SIZE) != EROS_SECTOR_SIZE) Diag::fatal(3, "Cannot write decompressed image\n"); } /* Now decompress the rest. */ int err; int mode = Z_NO_FLUSH; z_stream z; z.total_in = 0; z.avail_in = 0; z.next_out = out_buf; z.total_out = 0; z.avail_out = EROS_SECTOR_SIZE; z.zalloc = (alloc_func)0; z.zfree = (free_func)0; z.opaque = (voidpf)0; z.msg = NULL; err = inflateInit(&z); if (err != Z_OK) Diag::fatal(3, "Could not initialize decompression library\n"); uint32_t len = volHdr.zipLen; do { mode = Z_NO_FLUSH; len = fill_input(z, target_fd, len); if (z.avail_in == 0) mode = Z_FINISH; flush_output(z, working_fd); } while ((err = inflate(&z, mode)) == Z_OK); flush_output(z, working_fd); inflateEnd(&z); if (err != Z_STREAM_END) Diag::fatal(3, "Decompression failed with code %d\n", err); return err;}intVolume::CompressTarget(){ int err = Z_OK; if (volHdr.BootFlags & VolHdr::VF_COMPRESSED) { if (target_fd == working_fd) { /* target_fd is an open file descriptor onto the named file, so * we regrettably need to preserve that file descriptor. First * step is therefore to xerox the WORKING file. */ struct stat wkstat; fstat(working_fd, &wkstat); char wkname[] = "/tmp/working-XXXXXX"; mkstemp(wkname); working_fd = ::open(wkname, O_RDWR|O_CREAT, 0666); if (working_fd < 0) return errno; unlink(wkname); if (::lseek(target_fd, (int) 0, SEEK_SET) < 0) Diag::fatal(3, "Cannot seek target file\n"); int len = wkstat.st_size; while (len) { int sz = min(len, EROS_SECTOR_SIZE); if (::read(target_fd, in_buf, sz) != sz) Diag::fatal(3, "Cannot read to copy image\n"); if (::write(working_fd, in_buf, sz) != sz) Diag::fatal(3, "Cannot write to copy image\n"); len -= sz; } if (::lseek(target_fd, (int) 0, SEEK_SET) < 0) Diag::fatal(3, "Cannot seek target file\n"); if (ftruncate(target_fd, 0) < 0) Diag::fatal(3, "Cannot truncate target file\n"); } assert (target_fd != -1); assert (working_fd != -1); assert (target_fd != working_fd); if (::lseek(working_fd, (int) 0, SEEK_SET) < 0) Diag::fatal(3, "Cannot seek working file\n"); if (::lseek(target_fd, (int) 0, SEEK_SET) < 0) Diag::fatal(3, "Cannot seek target file\n"); /* Copy the bootstrap portion unmodified. */ for (uint32_t s = 0; s < volHdr.BootSectors; s++) { if (::read(working_fd, in_buf, EROS_SECTOR_SIZE) != EROS_SECTOR_SIZE) Diag::fatal(3, "Cannot read decompressed image\n"); if (::write(target_fd, in_buf, EROS_SECTOR_SIZE) != EROS_SECTOR_SIZE) Diag::fatal(3, "Cannot write compressed image\n"); } /* Now compress the rest. */ int mode = Z_NO_FLUSH; z_stream z; z.total_in = 0; z.avail_in = 0; z.next_out = out_buf; z.total_out = 0; z.avail_out = EROS_SECTOR_SIZE; z.zalloc = (alloc_func)0; z.zfree = (free_func)0; z.opaque = (voidpf)0; z.msg = NULL; err = deflateInit(&z, COMPRESS_LVL); if (err != Z_OK) Diag::fatal(3, "Could not initialize decompression library\n"); uint32_t len = volHdr.VolSectors - volHdr.BootSectors; len *= EROS_SECTOR_SIZE; do { mode = Z_NO_FLUSH; len = fill_input(z, working_fd, len); if (z.avail_in == 0) mode = Z_FINISH; flush_output(z, target_fd); } while ((err = deflate(&z, mode)) == Z_OK); flush_output(z, target_fd); deflateEnd(&z); if (err != Z_STREAM_END) Diag::fatal(3, "Decompression failed with code %d\n", err); err = Z_OK; assert(needSyncHdr == 0); volHdr.zipLen = z.total_out; } else { if (target_fd != working_fd) { /* Need to copy the decompressed image into the target file. */ struct stat wkstat; fstat(working_fd, &wkstat); if (ftruncate(target_fd, 0) < 0) Diag::fatal(3, "Cannot truncate target file\n"); if (::lseek(target_fd, (int) 0, SEEK_SET) < 0) Diag::fatal(3, "Cannot seek target file\n"); if (::lseek(working_fd, (int) 0, SEEK_SET) < 0) Diag::fatal(3, "Cannot seek working file\n"); int len = wkstat.st_size; while (len) { int sz = min(len, EROS_SECTOR_SIZE); if (::read(working_fd, in_buf, sz) != sz) Diag::fatal(3, "Cannot read to copy image\n"); if (::write(target_fd, in_buf, sz) != sz) Diag::fatal(3, "Cannot write to copy image\n"); len -= sz; } } volHdr.zipLen = 0; } char buf[EROS_PAGE_SIZE]; if (::lseek(target_fd, (int) 0, SEEK_SET) < 0) Diag::fatal(3, "Cannot seek target file\n"); ::read(target_fd, buf, EROS_PAGE_SIZE); if (::lseek(target_fd, (int) 0, SEEK_SET) < 0) Diag::fatal(3, "Cannot seek target file\n"); memcpy(buf, &volHdr, sizeof(volHdr)); ::write(target_fd, buf, EROS_PAGE_SIZE); return err;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -