home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / disk / misc / TransADF.lha / TransADF / Source / infl_disk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-05  |  10.4 KB  |  328 lines

  1. /* infl_disk.c = Inflate a compressed file onto a disk
  2. ** Copyright (C) 1997,1998 Karl J. Ots
  3. ** 
  4. ** This program is free software; you can redistribute it and/or modify
  5. ** it under the terms of the GNU General Public License as published by
  6. ** the Free Software Foundation; either version 2 of the License, or
  7. ** (at your option) any later version.
  8. ** 
  9. ** This program is distributed in the hope that it will be useful,
  10. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ** GNU General Public License for more details.
  13. ** 
  14. ** You should have received a copy of the GNU General Public License
  15. ** along with this program; if not, write to the Free Software
  16. ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17. */
  18.  
  19. #include <exec/types.h>
  20. #include <exec/memory.h>
  21. #include <devices/trackdisk.h>
  22. #include <dos/dos.h>
  23. #include <clib/exec_protos.h>
  24. #include <clib/dos_protos.h>
  25.  
  26. #include <string.h>
  27.  
  28. #include "zlib.h"
  29.  
  30. #include "infl_disk.h"
  31. #include "main.h"
  32. #include "mem_chunks.h"
  33. #include "device.h"
  34. #include "util.h"
  35. #include "errors.h"
  36.  
  37.  
  38. #define ID_FBSIZE   (32*1024)                   /* Bytes in id_FileBuf   */
  39. #define ID_TBTRACKS 1                           /* Tracks in id_TrackBuf */
  40. #define ID_TBSIZE   (ID_TBTRACKS * trackSize)   /* Bytes in id_TrackBuf  */
  41.  
  42. UBYTE *id_FileBuf;     /* Our input buffer - reads from file.     */
  43. UBYTE *id_TrackBuf;    /* Our output buffer - writes to disk.     */
  44. UBYTE *id_VTrackBuf;   /* Buffer for verifiying data if required. */
  45.  
  46. /*
  47. ** Inflate a file into a disk.
  48. ** Expects all fields of adfPkt to be set.
  49. */
  50. void inflDisk (struct ADF_Packet *adfPkt, STRPTR origName, ULONG fileType)
  51. {
  52.   static z_stream infl_stream;
  53.   ULONG nextTrack, CRC, USize, origCRC, origUSize;
  54.   LONG DOSError;
  55.   BYTE IOError;
  56.   int zerr, winbits;
  57.   
  58.   
  59.   /* Output info header */
  60.   FPrintf (StdOut, "Inflating from %s to %s unit %ld (%s:).\n",
  61.                    adfPkt->ADFileName,
  62.                    adfPkt->devInfo->deviceName,
  63.                    adfPkt->devInfo->deviceUnit,
  64.                    adfPkt->devInfo->dosName);
  65.   
  66.   FPrintf (StdOut, "Starting at track %ld, Ending at track %ld.\n",
  67.                    (adfPkt->startTrack/adfPkt->devInfo->numHeads),
  68.                    (adfPkt->endTrack/adfPkt->devInfo->numHeads));
  69.   
  70.   FPuts (StdOut, "Input is a ");
  71.   switch (fileType) {
  72.   case FT_ZLIB:  FPuts (StdOut, "ZLib");  break;
  73.   case FT_GZIP:  FPuts (StdOut, "GZip");  break;
  74.   case FT_PKZIP: FPuts (StdOut, "PKZip"); break;
  75.   }
  76.   FPuts (StdOut, " file, decompressing.\n");
  77.   
  78.   
  79.   /* Allocate the buffers */
  80.   id_TrackBuf = (UBYTE *)myAllocMem (ID_TBSIZE, MEMF_CLEAR);
  81.   id_FileBuf  = (UBYTE *)myAllocMem (ID_FBSIZE, MEMF_CLEAR);
  82.   if (!id_TrackBuf || !id_FileBuf)
  83.   {
  84.     /* No Memory */
  85.     FPrintf (StdErr, "%s: Out of memory.\n", ProgName);
  86.     cleanExit(RETURN_FAIL, ERROR_NO_FREE_STORE);
  87.   }
  88.  
  89.   if (adfPkt->verify)
  90.   {
  91.     id_VTrackBuf = (UBYTE *) myAllocMem (ID_TBSIZE, MEMF_CLEAR);
  92.     if (!id_VTrackBuf)
  93.     {
  94.       /* Out of memory! */
  95.       FPrintf (StdErr, "%s: Out of memory.\n", ProgName);
  96.       cleanExit (RETURN_FAIL, ERROR_NO_FREE_STORE);
  97.     }
  98.   }
  99.   
  100.   /* Consume file header */
  101.   if (skipHead (adfPkt->ADFile, origName, fileType) == FALSE)
  102.   {
  103.     DOSError = IoErr();
  104.     
  105.     FPrintf (StdErr, "%s: Couldn't read file header.\n",ProgName);
  106.     
  107.     if (DOSError)
  108.       reportDOSError (DOSError);
  109.     
  110.     cleanExit (RETURN_FAIL, NULL);
  111.   }
  112.   
  113.   
  114.   /* Initialise the z_stream */
  115.   if (fileType == FT_ZLIB) winbits = 15;
  116.   else winbits = -15; /* windowBits is passed < 0 to suppress zlib header */    
  117.   infl_stream.zalloc = Z_NULL;
  118.   infl_stream.zfree  = Z_NULL;
  119.   infl_stream.opaque = Z_NULL;
  120.   zerr = inflateInit2 (&infl_stream, winbits);
  121.   if (zerr != Z_OK)
  122.   {
  123.     FPrintf (StdErr, "%s: Inflate Init Error - ", ProgName);
  124.     reportZLibError (zerr);
  125.     if (infl_stream.msg) FPrintf (StdErr, "\t(%s)\n", infl_stream.msg);
  126.     cleanExit (RETURN_FAIL, NULL);
  127.   }
  128.   
  129.   /* Start inflating */
  130.   infl_stream.avail_in  = 0;            /* Input buffer is empty    */
  131.   infl_stream.next_out  = id_TrackBuf;  /* Pointer to output buffer */
  132.   infl_stream.avail_out = ID_TBSIZE;    /* output buffer is empty   */
  133.   CRC = crc32 (NULL, Z_NULL, 0);        /* Initialise the CRC       */
  134.   nextTrack = adfPkt->startTrack;
  135.   while (1)
  136.   {
  137.     if (infl_stream.avail_in == 0)  /* Input is empty */
  138.     {
  139.       /* Fill the input buffer from file */
  140.       infl_stream.next_in  = id_FileBuf;
  141.       infl_stream.avail_in = Read (adfPkt->ADFile, id_FileBuf, ID_FBSIZE);
  142.       if (infl_stream.avail_in == 0)
  143.       {
  144.         FPrintf (StdErr, "%s: Error - Unexpected End-Of-File.\n", ProgName);
  145.         cleanExit (RETURN_ERROR, NULL);
  146.       }
  147.     }
  148.     
  149.     /* Fill the output buffer with inflated data */
  150.     while (1)
  151.     {
  152.       /* Check for Control-C break */
  153.       if (CTRL_C)
  154.       {
  155.         FPutC (StdOut, '\n');
  156.         FPrintf (StdErr, "%s - %s\n", breakText, ProgName);
  157.         inflateEnd (&infl_stream);
  158.         cleanExit (RETURN_WARN, NULL);
  159.       }
  160.       
  161.       /* Upate progress report */
  162.       FPuts (StdOut, "\rInflating  ");
  163.       Flush (StdOut);
  164.       
  165.       zerr = inflate (&infl_stream, Z_NO_FLUSH);
  166.       if (zerr < Z_OK)
  167.       {
  168.         FPutC (StdOut, '\n');
  169.         FPrintf (StdErr, "%s: Inflate error - ", ProgName);
  170.         reportZLibError (zerr);
  171.         if (infl_stream.msg) FPrintf (StdErr, "\t%s\n", infl_stream.msg);
  172.         inflateEnd (&infl_stream);
  173.         cleanExit (RETURN_FAIL, NULL);
  174.       }
  175.       
  176.       /* Only flush the output buffer when it is completely full */
  177.       if (infl_stream.avail_out == 0)
  178.       {
  179.         if (nextTrack <= adfPkt->endTrack)
  180.         {
  181.           /* Update the CRC */
  182.           CRC = crc32 (CRC, id_TrackBuf, ID_TBSIZE);
  183.           
  184.           if (adfPkt->format)
  185.           {
  186.             /* Format the track */
  187.           
  188.             /* Update progress report */
  189.             FPrintf (StdOut, "\rFormatting track %ld side %ld",
  190.                              (nextTrack/adfPkt->devInfo->numHeads),
  191.                              (nextTrack%adfPkt->devInfo->numHeads));
  192.             Flush (StdOut);
  193.             
  194.             /* Format the track */
  195.             IOError = formatTrack (id_TrackBuf, ID_TBTRACKS, nextTrack,
  196.                                    adfPkt->diskReq);
  197.             if (IOError)
  198.             {
  199.               FPutC (StdOut, '\n');
  200.               FPrintf (StdErr, "%s: Error formatting %s: - ",
  201.                                ProgName, adfPkt->devInfo->dosName);
  202.               reportIOError (IOError);
  203.               inflateEnd (&infl_stream);
  204.               cleanExit (RETURN_FAIL, NULL);
  205.             }
  206.           }
  207.  
  208.           /* Update progress report */
  209.           FPrintf (StdOut, "\rWriting    track %ld side %ld",
  210.                            (nextTrack/adfPkt->devInfo->numHeads),
  211.                            (nextTrack%adfPkt->devInfo->numHeads));
  212.           Flush (StdOut);
  213.           
  214.           /* Write to the disk */
  215.           IOError = writeTrack (id_TrackBuf, ID_TBTRACKS, nextTrack,
  216.                                 adfPkt->diskReq);
  217.           if (IOError)
  218.           {
  219.             FPutC (StdOut, '\n');
  220.             FPrintf (StdErr, "%s: Error writing to %s: - ",
  221.                              ProgName, adfPkt->devInfo->dosName);
  222.             reportIOError (IOError);
  223.             inflateEnd (&infl_stream);
  224.             cleanExit (RETURN_FAIL, NULL);
  225.           }
  226.           
  227.           if (adfPkt->verify)
  228.           {
  229.             /* Verify that the data was written correctly */
  230.             FPrintf (StdOut, "\rVerifying track %ld side %ld",
  231.                              (nextTrack/adfPkt->devInfo->numHeads),
  232.                              (nextTrack%adfPkt->devInfo->numHeads));
  233.             Flush (StdOut);
  234.             
  235.             flushTrack (adfPkt->diskReq);
  236.             IOError = readTrack (id_VTrackBuf, ID_TBTRACKS, nextTrack, 
  237.                                  adfPkt->diskReq);
  238.             if (IOError)
  239.             {
  240.               FPutC (StdOut, '\n');
  241.               FPrintf (StdErr, "%s: Error reading from %s: - ", ProgName,
  242.                                                             adfPkt->devInfo->dosName);
  243.               reportIOError (IOError);
  244.               inflateEnd (&infl_stream);
  245.               cleanExit (RETURN_ERROR, NULL);
  246.             }
  247.       
  248.             /* Check that the two buffers are identical */
  249.             if (memcmp (id_TrackBuf, id_VTrackBuf, ID_TBSIZE) != 0)
  250.             {
  251.               /* Verification error */
  252.               FPutC (StdOut, '\n');
  253.               FPrintf (StdErr, "%s: Verification Error on %s:\n", ProgName,
  254.                                                             adfPkt->devInfo->deviceUnit);
  255.               inflateEnd (&infl_stream);
  256.               cleanExit (RETURN_ERROR, NULL);
  257.             }
  258.           }
  259.           
  260.           infl_stream.next_out  = id_TrackBuf;
  261.           infl_stream.avail_out = ID_TBSIZE;
  262.           nextTrack++;
  263.         }
  264.         else
  265.           /* We've reached the end */
  266.           zerr = Z_STREAM_END;
  267.       }
  268.       else
  269.         /* The buffer is not full, move along */
  270.         break;
  271.       
  272.       if (zerr == Z_STREAM_END)
  273.         /* Reached endTrack, or we reached the end of the */
  274.         /* compressed data stream.                        */
  275.         break;
  276.     }
  277.     if (zerr == Z_STREAM_END) break;
  278.   }
  279.   USize = infl_stream.total_out;
  280.   
  281.   FPrintf (StdOut, "\rInflated: %ld ==> %ld         ", infl_stream.total_in,
  282.                                                        USize);
  283.   Flush (StdOut);
  284.   
  285.   /* End the deflate process */
  286.   zerr = inflateEnd (&infl_stream);
  287.   if (zerr != Z_OK)
  288.   {
  289.     FPutC (StdOut, '\n');
  290.     FPrintf (StdErr, "%s: Inflate End Error - ", ProgName);
  291.     reportZLibError (zerr);
  292.     if (infl_stream.msg) FPrintf (StdErr, "\t(%s)\n", infl_stream.msg);
  293.     cleanExit (RETURN_FAIL, NULL);
  294.   }
  295.   
  296.   /* Check the CRC and USize */
  297.   if ( readTail (adfPkt->ADFile, &origCRC, &origUSize, fileType) == FALSE)
  298.   {
  299.     FPutC (StdOut, '\n');
  300.     FPrintf (StdErr, "%s: Couldn't read CRC or Size from file.\n", 
  301.                      ProgName);
  302.     cleanExit (RETURN_FAIL, NULL);
  303.   }
  304.   
  305.   if (fileType != FT_ZLIB)
  306.   {
  307.     if (CRC != origCRC)
  308.     {
  309.       FPutC (StdOut, '\n');
  310.       FPuts (StdErr, "Error: CRC Mismatch!\n");
  311.       cleanExit (RETURN_ERROR, NULL);
  312.     }
  313.     
  314.     if (USize != origUSize)
  315.     {
  316.       FPutC (StdOut, '\n');
  317.       FPuts (StdErr, "Error: Size mismatch!\n");
  318.       cleanExit (RETURN_ERROR, NULL);
  319.     }
  320.   }
  321.   
  322.   /* Free and clear buffers */
  323.   myFreeMem (id_TrackBuf);
  324.   myFreeMem (id_FileBuf);
  325.   if (id_VTrackBuf)
  326.     myFreeMem (id_VTrackBuf);
  327. }
  328.