Commit ff17c390 authored by Leigh B. Stoller's avatar Leigh B. Stoller
Browse files

Convert imagezip to optionally using stdout instead of a file by giving

it "-" for the output filename. This means we cannot seek, and so the
little bit of stuff we do for netdisk cannot be done, but so what.
It also means that output errors are fatal, and so no reason to retry
them (like we do for writes to an NFS file).

Convert imageunzip to optionally using stdin instead of a file, by
giving it "-" for the input name. I added an 1MB chunk buffer to,
which reads are buffered into. I also changed unified the interface
from the the Frisbee client, which got rid of some ifdefs.
parent 9d6cc72e
......@@ -627,29 +627,15 @@ PlayFrisbee(void)
*
* XXX We copy out the data. Need to change this interface to avoid that.
*/
static int ImageUnzipOffset;
static int ImageUnzipBuffer;
extern int inflate_subblock(void);
extern int inflate_subblock(char *);
static int
ImageUnzip(int slot)
{
ImageUnzipBuffer = slot;
ImageUnzipOffset = 0;
char *data = (char *) &ChunkBuffer[slot].blocks;
if (inflate_subblock())
if (inflate_subblock(data))
pfatal("ImageUnzip: inflate_subblock failed");
return 0;
}
int
FrisbeeRead(void **buf, size_t count)
{
char *data = (char *) &ChunkBuffer[ImageUnzipBuffer].blocks;
data += ImageUnzipOffset;
*buf = data;
ImageUnzipOffset += count;
return count;
}
......@@ -48,8 +48,9 @@ static int infd, outfd;
static int doseek = 0;
static int debug = 0;
static long long total = 0;
static char chunkbuf[SUBBLOCKSIZE];
int inflate_subblock(void);
int inflate_subblock(char *);
void writezeros(off_t zcount);
#ifdef linux
......@@ -122,10 +123,15 @@ main(int argc, char **argv)
usage();
}
if ((infd = open(argv[0], O_RDONLY, 0666)) < 0) {
perror("opening input file");
exit(1);
if (strcmp(argv[0], "-")) {
if ((infd = open(argv[0], O_RDONLY, 0666)) < 0) {
perror("opening input file");
exit(1);
}
}
else
infd = fileno(stdin);
if (argc == 2) {
if ((outfd =
open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0) {
......@@ -155,30 +161,30 @@ main(int argc, char **argv)
gettimeofday(&stamp, 0);
while (1) {
off_t offset, correction;
int count = sizeof(chunkbuf);
char *bp = chunkbuf;
/*
* Decompress one subblock at a time. After its done
* make sure the input file pointer is at a block
* boundry. Move it up if not.
* Decompress one subblock at a time. We read the entire
* chunk and had it off. Since we might be reading from
* stdin, we have to make sure we get the entire amount.
*/
if (inflate_subblock())
break;
if ((offset = lseek(infd, (off_t) 0, SEEK_CUR)) < 0) {
perror("Getting current seek pointer");
exit(1);
}
if (offset & (SUBBLOCKSIZE - 1)) {
correction = SUBBLOCKSIZE -
(offset & (SUBBLOCKSIZE - 1));
if ((offset = lseek(infd, correction, SEEK_CUR)) < 0) {
perror("correcting seek pointer");
while (count) {
int cc;
if ((cc = read(infd, bp, count)) <= 0) {
if (cc == 0)
goto done;
perror("reading zipped image");
exit(1);
}
count -= cc;
bp += cc;
}
if (inflate_subblock(chunkbuf))
break;
}
done:
close(infd);
gettimeofday(&estamp, 0);
......@@ -218,7 +224,7 @@ ImageUnzipInit(char *filename, int slice, int dbg)
#endif
int
inflate_subblock(void)
inflate_subblock(char *chunkbufp)
{
int cc, ccres, err, count, ibsize = 0, ibleft = 0;
z_stream d_stream; /* inflation stream */
......@@ -226,8 +232,8 @@ inflate_subblock(void)
struct blockhdr *blockhdr;
struct region *curregion;
off_t offset, size;
char blockbuf[DEFAULTREGIONSIZE], *bbuf = blockbuf;
char *buf = inbuf;
int chunkbytes = SUBBLOCKSIZE;
d_stream.zalloc = (alloc_func)0;
d_stream.zfree = (free_func)0;
......@@ -240,22 +246,13 @@ inflate_subblock(void)
CHECK_ERR(err, "inflateInit");
/*
* Read the header. It is uncompressed, and holds the real
* image size and the magic number.
* Grab the header. It is uncompressed, and holds the real
* image size and the magic number. Advance the pointer too.
*/
#ifdef FRISBEE
if ((cc = FrisbeeRead(&bbuf, DEFAULTREGIONSIZE)) <= 0) {
#else
if ((cc = read(infd, bbuf, DEFAULTREGIONSIZE)) <= 0) {
#endif
if (cc == 0)
return 1;
perror("reading zipped image header goo");
exit(1);
}
assert(cc == DEFAULTREGIONSIZE);
blockhdr = (struct blockhdr *) bbuf;
blockhdr = (struct blockhdr *) chunkbufp;
chunkbufp += DEFAULTREGIONSIZE;
chunkbytes -= DEFAULTREGIONSIZE;
if (blockhdr->magic != COMPRESSED_MAGIC) {
fprintf(stderr, "Bad Magic Number!\n");
exit(1);
......@@ -299,23 +296,14 @@ inflate_subblock(void)
count = sizeof(inbuf);
else
count = blockhdr->size;
#ifdef FRISBEE
if ((cc = FrisbeeRead(&buf, count)) <= 0) {
#else
if ((cc = read(infd, buf, count)) <= 0) {
#endif
if (cc == 0) {
return 1;
}
perror("reading zipped image");
exit(1);
}
assert(cc == count);
blockhdr->size -= cc;
memcpy(buf, chunkbufp, count);
chunkbufp += count;
chunkbytes -= count;
assert(chunkbytes >= 0);
blockhdr->size -= count;
d_stream.next_in = buf;
d_stream.avail_in = cc;
d_stream.avail_in = count;
inflate_again:
/*
* Must operate on multiples of the sector size!
......
......@@ -31,9 +31,9 @@
#define DOSPTYP_EXT 5 /* DOS extended partition */
#endif
int infd, outfd;
int infd, outfd, outcanseek;
int secsize = 512; /* XXX bytes. */
int debug = 1;
int debug = 0;
int info = 0;
int slicemode = 0;
int maxmode = 0;
......@@ -110,8 +110,9 @@ mywrite(int fd, const void *buf, size_t nbytes)
int cc, i, count = 0;
off_t startoffset, endoffset;
int maxretries = 10;
if ((startoffset = lseek(fd, (off_t) 0, SEEK_CUR)) < 0) {
if (outcanseek &&
((startoffset = lseek(fd, (off_t) 0, SEEK_CUR)) < 0)) {
perror("mywrite: seeking to get output file ptr");
exit(1);
}
......@@ -126,8 +127,15 @@ mywrite(int fd, const void *buf, size_t nbytes)
count += cc;
continue;
}
if (!outcanseek) {
if (cc < 0)
perror("mywrite: writing");
else
fprintf(stderr, "mywrite: writing\n");
exit(1);
}
if (i == 0)
if (i == 0)
perror("write error: will retry");
sleep(1);
......@@ -136,7 +144,7 @@ mywrite(int fd, const void *buf, size_t nbytes)
count = 0;
goto again;
}
if (fsync(fd) < 0) {
if (outcanseek && fsync(fd) < 0) {
perror("fsync error: will retry");
sleep(1);
nbytes += count;
......@@ -245,23 +253,34 @@ main(argc, argv)
rval = read_image();
#endif
sortskips();
if (debug > 2)
if (debug)
dumpskips();
makeranges();
fflush(stderr);
if (info) {
close(infd);
exit(0);
}
if ((outfd = open(outfilename, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0) {
perror("opening output file");
exit(1);
if (strcmp(outfilename, "-")) {
if ((outfd = open(outfilename, O_RDWR|O_CREAT|O_TRUNC, 0666))
< 0) {
perror("opening output file");
exit(1);
}
outcanseek = 1;
}
else {
outfd = fileno(stdout);
outcanseek = 0;
}
compress_image();
fflush(stderr);
close(infd);
close(outfd);
if (outcanseek)
close(outfd);
exit(0);
}
......@@ -296,30 +315,30 @@ read_image()
}
if (debug) {
printf("DOS Partitions:\n");
fprintf(stderr, "DOS Partitions:\n");
for (i = 0; i < NDOSPART; i++) {
printf(" P%d: ", i + 1 /* DOS Numbering */);
fprintf(stderr, " P%d: ", i + 1 /* DOS Numbering */);
switch (doslabel.parts[i].dp_typ) {
case DOSPTYP_386BSD:
printf(" BSD ");
fprintf(stderr, " BSD ");
break;
case DOSPTYP_LINSWP:
printf(" LSWAP ");
fprintf(stderr, " LSWAP ");
break;
case DOSPTYP_LINUX:
printf(" LINUX ");
fprintf(stderr, " LINUX ");
break;
case DOSPTYP_EXT:
printf(" DOS ");
fprintf(stderr, " DOS ");
break;
default:
printf(" UNKNO ");
fprintf(stderr, " UNKNO ");
}
printf(" start %9d, size %9d\n",
fprintf(stderr, " start %9d, size %9d\n",
doslabel.parts[i].dp_start,
doslabel.parts[i].dp_size);
}
printf("\n");
fprintf(stderr, "\n");
}
/*
......@@ -359,7 +378,8 @@ read_image()
rval = read_linuxslice(i, start, size);
break;
default:
printf(" Slice %d is an unknown type. Skipping ...\n",
fprintf(stderr,
" Slice %d is an unknown type. Skipping.\n",
i + 1 /* DOS Numbering */);
if (start != size)
addskip(start, size);
......@@ -392,7 +412,8 @@ read_bsdslice(int slice, u_int32_t start, u_int32_t size)
} dlabel;
if (debug)
printf(" P%d (BSD Slice)\n", slice + 1 /* DOS Numbering */);
fprintf(stderr,
" P%d (BSD Slice)\n", slice + 1 /* DOS Numbering */);
if (devlseek(infd, ((off_t)start) * secsize, SEEK_SET) < 0) {
warn("Could not seek to beginning of BSD slice");
......@@ -436,9 +457,9 @@ read_bsdslice(int slice, u_int32_t start, u_int32_t size)
continue;
if (debug) {
printf(" %c ", BSDPARTNAME(i));
fprintf(stderr, " %c ", BSDPARTNAME(i));
printf(" start %9d, size %9d\t(%s)\n",
fprintf(stderr, " start %9d, size %9d\t(%s)\n",
dlabel.label.d_partitions[i].p_offset,
dlabel.label.d_partitions[i].p_size,
fstypenames[dlabel.label.d_partitions[i].p_fstype]);
......@@ -503,7 +524,7 @@ read_bsdpartition(struct disklabel *dlabel, int part)
}
if (debug) {
printf(" bfree %9d, size %9d\n",
fprintf(stderr, " bfree %9d, size %9d\n",
fs.fs.fs_cstotal.cs_nbfree, fs.fs.fs_bsize);
}
......@@ -528,8 +549,9 @@ read_bsdpartition(struct disklabel *dlabel, int part)
return 1;
}
if (debug > 1) {
printf(" CG%d\t offset %9d, bfree %6d\n",
i, cgoff, cg.cg.cg_cs.cs_nbfree);
fprintf(stderr,
" CG%d\t offset %9d, bfree %6d\n",
i, cgoff, cg.cg.cg_cs.cs_nbfree);
}
rval = read_bsdcg(&fs.fs, &cg.cg, dboff);
......@@ -563,7 +585,7 @@ read_bsdcg(struct fs *fsp, struct cg *cgp, unsigned int dbstart)
*/
if (debug > 2)
printf(" ");
fprintf(stderr, " ");
for (count = i = 0; i < max; i++)
if (isset(p, i)) {
j = i;
......@@ -582,17 +604,18 @@ read_bsdcg(struct fs *fsp, struct cg *cgp, unsigned int dbstart)
if (debug > 2) {
if (count)
printf(",%s",
count % 4 ? " " :
"\n ");
printf("%u:%d", dboff, dbcount);
fprintf(stderr, ",%s",
count % 4 ? " " :
"\n ");
fprintf(stderr,
"%u:%d", dboff, dbcount);
}
addskip(dboff, dbcount);
count++;
}
}
if (debug > 2)
printf("\n");
fprintf(stderr, "\n");
return 0;
}
#endif
......@@ -624,7 +647,7 @@ read_linuxslice(int slice, u_int32_t start, u_int32_t size)
assert((sizeof(groups) & ~LINUX_SUPERBLOCK_SIZE) == 0);
if (debug)
printf(" P%d (Linux Slice)\n", dosslice);
fprintf(stderr, " P%d (Linux Slice)\n", dosslice);
/*
* Skip ahead to the superblock.
......@@ -651,7 +674,7 @@ read_linuxslice(int slice, u_int32_t start, u_int32_t size)
}
if (debug) {
printf(" bfree %9d, size %9d\n",
fprintf(stderr, " bfree %9d, size %9d\n",
fs.s_free_blocks_count, EXT2_BLOCK_SIZE(&fs));
}
numgroups = fs.s_blocks_count / fs.s_blocks_per_group;
......@@ -693,9 +716,10 @@ read_linuxslice(int slice, u_int32_t start, u_int32_t size)
}
if (debug) {
printf(" Group:%-2d\tBitmap %9d, bfree %9d\n",
i, groups[gix].bg_block_bitmap,
groups[gix].bg_free_blocks_count);
fprintf(stderr,
" Group:%-2d\tBitmap %9d, bfree %9d\n",
i, groups[gix].bg_block_bitmap,
groups[gix].bg_free_blocks_count);
}
rval = read_linuxgroup(&fs, &groups[gix], i, start);
......@@ -761,7 +785,7 @@ read_linuxgroup(struct ext2_super_block *super,
((EXT2_BLOCK_SIZE(super) / secsize) * (count))
if (debug > 2)
printf(" ");
fprintf(stderr, " ");
for (count = i = 0; i < max; i++)
if (!isset(p, i)) {
j = i;
......@@ -786,10 +810,10 @@ read_linuxgroup(struct ext2_super_block *super,
if (debug > 2) {
if (count)
printf(",%s",
count % 4 ? " " :
"\n ");
printf("%u:%d %d:%d",
fprintf(stderr, ",%s",
count % 4 ? " " :
"\n ");
fprintf(stderr, "%u:%d %d:%d",
dboff, dbcount, j, i);
}
addskip(dboff, dbcount);
......@@ -797,7 +821,7 @@ read_linuxgroup(struct ext2_super_block *super,
}
}
if (debug > 2)
printf("\n");
fprintf(stderr, "\n");
return 0;
}
......@@ -810,9 +834,11 @@ int
read_linuxswap(int slice, u_int32_t start, u_int32_t size)
{
if (debug) {
printf(" P%d (Linux Swap)\n", slice + 1 /* DOS Numbering */);
printf(" start %12d, size %9d\n",
start, size);
fprintf(stderr,
" P%d (Linux Swap)\n", slice + 1 /* DOS Numbering */);
fprintf(stderr,
" start %12d, size %9d\n",
start, size);
}
start += 0x8000 / secsize;
......@@ -837,8 +863,8 @@ read_raw(void)
}
if (debug) {
printf(" Raw Image\n");
printf(" start %12d, size %12qd\n", 0, size);
fprintf(stderr, " Raw Image\n");
fprintf(stderr, " start %12d, size %12qd\n", 0, size);
}
return 0;
}
......@@ -942,17 +968,22 @@ dumpskips(void)
if (!skips)
return;
printf("Skip ranges (start/size) in sectors:\n");
if (debug > 2)
fprintf(stderr, "Skip ranges (start/size) in sectors:\n");
pskip = skips;
while (pskip) {
printf(" %12d %9d\n", pskip->start, pskip->size);
if (debug > 2)
fprintf(stderr,
" %12d %9d\n", pskip->start, pskip->size);
total += pskip->size;
pskip = pskip->next;
}
if (debug > 2)
fprintf(stderr, "\n");
printf("\nTotal Number of Free Sectors: %d (bytes %qd)\n",
fprintf(stderr, "Total Number of Free Sectors: %d (bytes %qd)\n",
total, (off_t)total * (off_t)secsize);
}
......@@ -1031,7 +1062,8 @@ makeranges(void)
if (debug > 2) {
range = ranges;
while (range) {
printf(" %12d %9d\n", range->start, range->size);
fprintf(stderr,
" %12d %9d\n", range->start, range->size);
range = range->next;
}
}
......@@ -1095,8 +1127,9 @@ compress_image(void)
buffer_offset = DEFAULTREGIONSIZE;
if (debug) {
printf("Compressing range: %14qd --> ", inputoffset);
fflush(stdout);
fprintf(stderr,
"Compressing range: %14qd --> ", inputoffset);
fflush(stderr);
}
/*
......@@ -1115,7 +1148,7 @@ compress_image(void)
size = compress_chunk(size, &partial, &blkhdr->size);
if (debug)
printf("%12qd\n", inputoffset + size);
fprintf(stderr, "%12qd\n", inputoffset + size);
totalinput += size;
......@@ -1202,34 +1235,35 @@ compress_image(void)
* Compress the chunk.
*/
if (debug > 0 && debug < 3) {
printf("Compressing range: %14qd --> ", inputoffset);
fflush(stdout);
fprintf(stderr,
"Compressing range: %14qd --> ", inputoffset);
fflush(stderr);
}
size = compress_chunk(rangesize, &partial, &blkhdr->size);
if (debug >= 3) {
printf("%14qd -> %12qd %10d %10d %10d %d\n",
inputoffset, inputoffset + size,
prange->start - inputminsec,
(int) (size / secsize),
blkhdr->size, partial);
fprintf(stderr, "%14qd -> %12qd %10d %10d %10d %d\n",
inputoffset, inputoffset + size,
prange->start - inputminsec,
(int) (size / secsize),
blkhdr->size, partial);
}
else if (debug) {
gettimeofday(&estamp, 0);
estamp.tv_sec -= stamp.tv_sec;
printf("%12qd in %ld seconds.\n",
inputoffset + size, estamp.tv_sec);
fprintf(stderr, "%12qd in %ld seconds.\n",
inputoffset + size, estamp.tv_sec);
}
else {
static int pos;
putchar('.');
putc('.', stderr);
if (pos++ >= 60) {
putchar('\n');
putc('\n', stderr);
pos = 0;
}
fflush(stdout);
fflush(stderr);
}
/*
......@@ -1337,11 +1371,19 @@ compress_image(void)
if (debug) {
gettimeofday(&estamp, 0);
estamp.tv_sec -= stamp.tv_sec;
printf("Done in %ld seconds!\n", estamp.tv_sec);
fprintf(stderr, "Done in %ld seconds!\n", estamp.tv_sec);
}
else
putchar('\n');
putc('\n', stderr);
fflush(stderr);
/*
* Skip the rest if not able to seek on output. netdisk will
* not be able to read the file, but so what.
*/
if (!outcanseek)
return 0;
/*
* Get the total filesize, and then number the subblocks.
* Useful, for netdisk.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment