home *** CD-ROM | disk | FTP | other *** search
- /* infl_disk.c = Inflate a compressed file onto a disk
- ** Copyright (C) 1997,1998 Karl J. Ots
- **
- ** 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 of the License, 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, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <devices/trackdisk.h>
- #include <dos/dos.h>
- #include <clib/exec_protos.h>
- #include <clib/dos_protos.h>
-
- #include <string.h>
-
- #include "zlib.h"
-
- #include "infl_disk.h"
- #include "main.h"
- #include "mem_chunks.h"
- #include "td.h"
- #include "util.h"
- #include "errors.h"
-
-
- #define ID_FBSIZE (32*1024) /* Bytes in id_FileBuf */
- #define ID_TBTRACKS 1 /* Tracks in id_TrackBuf */
- #define ID_TBSIZE (ID_TBTRACKS * TRACK_SIZE) /* Bytes in id_TrackBuf */
-
- UBYTE *id_FileBuf; /* Our input buffer - reads from file. */
- UBYTE *id_TrackBuf; /* Our output buffer - writes to disk. */
- UBYTE *id_VTrackBuf; /* Buffer for verifiying data if required. */
-
- /*
- ** Inflate a file into a disk.
- ** Expects all fields of adfPkt to be set.
- */
- void inflDisk (struct ADF_Packet *adfPkt, STRPTR origName, ULONG fileType)
- {
- static z_stream infl_stream;
- ULONG nextTrack, CRC, USize, origCRC, origUSize;
- LONG DOSError;
- BYTE TDError;
- int zerr, winbits;
-
-
- /* Output info header */
- FPrintf (StdOut, "Inflating from %s to TrackDisk Unit %ld (DF%ld:).\n",
- adfPkt->ADFileName,
- adfPkt->diskUnit,
- adfPkt->diskUnit);
-
- FPrintf (StdOut, "Starting at track %ld, Ending at track %ld.\n",
- (adfPkt->startTrack>>1),
- (adfPkt->endTrack>>1));
-
- FPuts (StdOut, "Input is a ");
- switch (fileType) {
- case FT_ZLIB: FPuts (StdOut, "ZLib"); break;
- case FT_GZIP: FPuts (StdOut, "GZip"); break;
- case FT_PKZIP: FPuts (StdOut, "PKZip"); break;
- }
- FPuts (StdOut, " file, decompressing.\n");
-
-
- /* Allocate the buffers */
- id_TrackBuf = (UBYTE *)myAllocMem (ID_TBSIZE, MEMF_CLEAR);
- id_FileBuf = (UBYTE *)myAllocMem (ID_FBSIZE, MEMF_CLEAR);
- if (!id_TrackBuf || !id_FileBuf)
- {
- /* No Memory */
- FPrintf (StdErr, "%s: Out of memory.\n", ProgName);
- cleanExit(RETURN_FAIL, ERROR_NO_FREE_STORE);
- }
-
- if (adfPkt->verify)
- {
- id_VTrackBuf = (UBYTE *) myAllocMem (ID_TBSIZE, MEMF_CLEAR);
- if (!id_VTrackBuf)
- {
- /* Out of memory! */
- FPrintf (StdErr, "%s: Out of memory.\n", ProgName);
- cleanExit (RETURN_FAIL, ERROR_NO_FREE_STORE);
- }
- }
-
- /* Consume file header */
- if (skipHead (adfPkt->ADFile, origName, fileType) == FALSE)
- {
- DOSError = IoErr();
-
- FPrintf (StdErr, "%s: Couldn't read file header.\n",ProgName);
-
- if (DOSError)
- reportDOSError (DOSError);
-
- cleanExit (RETURN_FAIL, NULL);
- }
-
-
- /* Initialise the z_stream */
- if (fileType == FT_ZLIB) winbits = 15;
- else winbits = -15; /* windowBits is passed < 0 to suppress zlib header */
- infl_stream.zalloc = Z_NULL;
- infl_stream.zfree = Z_NULL;
- infl_stream.opaque = Z_NULL;
- zerr = inflateInit2 (&infl_stream, winbits);
- if (zerr != Z_OK)
- {
- FPrintf (StdErr, "%s: Inflate Init Error - ", ProgName);
- reportZLibError (zerr);
- if (infl_stream.msg) FPrintf (StdErr, "\t(%s)\n", infl_stream.msg);
- cleanExit (RETURN_FAIL, NULL);
- }
-
- /* Start inflating */
- infl_stream.avail_in = 0; /* Input buffer is empty */
- infl_stream.next_out = id_TrackBuf; /* Pointer to output buffer */
- infl_stream.avail_out = ID_TBSIZE; /* output buffer is empty */
- CRC = crc32 (NULL, Z_NULL, 0); /* Initialise the CRC */
- nextTrack = adfPkt->startTrack;
- while (1)
- {
- if (infl_stream.avail_in == 0) /* Input is empty */
- {
- /* Fill the input buffer from file */
- infl_stream.next_in = id_FileBuf;
- infl_stream.avail_in = Read (adfPkt->ADFile, id_FileBuf, ID_FBSIZE);
- if (infl_stream.avail_in == 0)
- {
- FPrintf (StdErr, "%s: Error - Unexpected End-Of-File.\n", ProgName);
- cleanExit (RETURN_ERROR, NULL);
- }
- }
-
- /* Fill the output buffer with inflated data */
- while (1)
- {
- /* Check for Control-C break */
- if (CTRL_C)
- {
- FPutC (StdOut, '\n');
- FPrintf (StdErr, "%s - %s\n", breakText, ProgName);
- inflateEnd (&infl_stream);
- cleanExit (RETURN_WARN, NULL);
- }
-
- /* Upate progress report */
- FPuts (StdOut, "\rInflating ");
- Flush (StdOut);
-
- zerr = inflate (&infl_stream, Z_NO_FLUSH);
- if (zerr < Z_OK)
- {
- FPutC (StdOut, '\n');
- FPrintf (StdErr, "%s: Inflate error - ", ProgName);
- reportZLibError (zerr);
- if (infl_stream.msg) FPrintf (StdErr, "\t%s\n", infl_stream.msg);
- inflateEnd (&infl_stream);
- cleanExit (RETURN_FAIL, NULL);
- }
-
- /* Only flush the output buffer when it is completely full */
- if (infl_stream.avail_out == 0)
- {
- if (nextTrack <= adfPkt->endTrack)
- {
- /* Update the CRC */
- CRC = crc32 (CRC, id_TrackBuf, ID_TBSIZE);
-
- /* Update progress report */
- FPuts (StdOut, "\rWriting ");
- FPUTS_TS (nextTrack, StdOut);
- Flush (StdOut);
-
- /* Write to the disk */
- TDError = writeTrack (id_TrackBuf, ID_TBTRACKS, nextTrack,
- adfPkt->diskReq);
- if (TDError)
- {
- FPutC (StdOut, '\n');
- FPrintf (StdErr, "%s: Error writing to DF%ld: - ",
- ProgName,adfPkt->diskUnit);
- reportTDError (TDError);
- inflateEnd (&infl_stream);
- cleanExit (RETURN_FAIL, NULL);
- }
-
- if (adfPkt->verify)
- {
- /* Verify that the data was written correctly */
- FPuts (StdOut, "\rVerifying ");
- FPUTS_TS (nextTrack, StdOut);
- Flush (StdOut);
-
- flushTrack (adfPkt->diskReq);
- TDError = readTrack (id_VTrackBuf, ID_TBTRACKS, nextTrack,
- adfPkt->diskReq);
- if (TDError)
- {
- FPutC (StdOut, '\n');
- FPrintf (StdErr, "%s: Error reading from DF%ld - ", ProgName,
- adfPkt->diskUnit);
- reportTDError (TDError);
- inflateEnd (&infl_stream);
- cleanExit (RETURN_ERROR, NULL);
- }
-
- /* Check that the two buffers are identical */
- if (memcmp (id_TrackBuf, id_VTrackBuf, ID_TBSIZE) != 0)
- {
- /* Verification error */
- FPutC (StdOut, '\n');
- FPrintf (StdErr, "%s: Verification Error on DF%ld:\n", ProgName,
- adfPkt->diskUnit);
- inflateEnd (&infl_stream);
- cleanExit (RETURN_ERROR, NULL);
- }
- }
-
- infl_stream.next_out = id_TrackBuf;
- infl_stream.avail_out = ID_TBSIZE;
- nextTrack++;
- }
- else
- /* We've reached the end */
- zerr = Z_STREAM_END;
- }
- else
- /* The buffer is not full, move along */
- break;
-
- if (zerr == Z_STREAM_END)
- /* Reached endTrack, or we reached the end of the */
- /* compressed data stream. */
- break;
- }
- if (zerr == Z_STREAM_END) break;
- }
- USize = infl_stream.total_out;
-
- FPrintf (StdOut, "\rInflated: %ld ==> %ld ", infl_stream.total_in,
- USize);
- Flush (StdOut);
-
- /* End the deflate process */
- zerr = inflateEnd (&infl_stream);
- if (zerr != Z_OK)
- {
- FPutC (StdOut, '\n');
- FPrintf (StdErr, "%s: Inflate End Error - ", ProgName);
- reportZLibError (zerr);
- if (infl_stream.msg) FPrintf (StdErr, "\t(%s)\n", infl_stream.msg);
- cleanExit (RETURN_FAIL, NULL);
- }
-
- /* Check the CRC and USize */
- if ( readTail (adfPkt->ADFile, &origCRC, &origUSize, fileType) == FALSE)
- {
- FPutC (StdOut, '\n');
- FPrintf (StdErr, "%s: Couldn't read CRC or Size from file.\n",
- ProgName);
- cleanExit (RETURN_FAIL, NULL);
- }
-
- if (fileType != FT_ZLIB)
- {
- if (CRC != origCRC)
- {
- FPutC (StdOut, '\n');
- FPuts (StdErr, "Error: CRC Mismatch!\n");
- cleanExit (RETURN_ERROR, NULL);
- }
-
- if (USize != origUSize)
- {
- FPutC (StdOut, '\n');
- FPuts (StdErr, "Error: Size mismatch!\n");
- cleanExit (RETURN_ERROR, NULL);
- }
- }
-
- /* Free and clear buffers */
- myFreeMem (id_TrackBuf);
- myFreeMem (id_FileBuf);
- if (id_VTrackBuf)
- myFreeMem (id_VTrackBuf);
- }
-