home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / HPACK78S.ZIP / store / store.c next >
C/C++ Source or Header  |  1992-10-08  |  8KB  |  282 lines

  1. /****************************************************************************
  2. *                                                                           *
  3. *                          HPACK Multi-System Archiver                         *
  4. *                          ===========================                      *
  5. *                                                                           *
  6. *                       High-Speed Data Movement Routines                   *
  7. *                            STORE.C  Updated 12/07/91                        *
  8. *                                                                           *
  9. * This program is protected by copyright and as such any use or copying of    *
  10. *  this code for your own purposes directly or indirectly is highly uncool    *
  11. *                      and if you do so there will be....trubble.                *
  12. *                 And remember: We know where your kids go to school.            *
  13. *                                                                           *
  14. *         Copyright 1989 - 1991  Peter C.Gutmann.  All rights reserved           *
  15. *                                                                           *
  16. ****************************************************************************/
  17.  
  18. #include <ctype.h>
  19. #include <string.h>
  20. #ifdef __MAC__
  21.   #include "defs.h"
  22.   #include "error.h"
  23.   #include "hpacklib.h"
  24.   #include "system.h"
  25.   #include "crc16.h"
  26.   #include "crypt.h"
  27.   #include "fastio.h"
  28.   #include "hpackio.h"
  29.   #include "store.h"
  30. #else
  31.   #include "defs.h"
  32.   #include "error.h"
  33.   #include "hpacklib.h"
  34.   #include "system.h"
  35.   #include "crc/crc16.h"
  36.   #include "crypt/crypt.h"
  37.   #include "io/fastio.h"
  38.   #include "io/hpackio.h"
  39.   #include "store/store.h"
  40. #endif /* __MAC__ */
  41.  
  42. /* Prototypes for functions in GUI.C */
  43.  
  44. void updateProgressReport( void );
  45.  
  46. /* The following are defined in FASTIO.C */
  47.  
  48. extern BOOLEAN doCryptOut;
  49. extern int cryptMark;
  50.  
  51. /****************************************************************************
  52. *                                                                            *
  53. *                    Store Data in an Archive without Compression            *
  54. *                                                                            *
  55. ****************************************************************************/
  56.  
  57. /* Store data in an archive with no compression.  This routine must take
  58.    care to correctly handle any data already in the buffer, unlike
  59.    unstore() which assumes the buffer is empty when first called */
  60.  
  61. LONG store( BOOLEAN *isText )
  62.     {
  63.     LONG byteCount = 0L;
  64.     int bytesRead, bytesToRead, printCount = 0;
  65.     int sampleCount = 0, textByteCount = 0;
  66.     BOOLEAN moreData = TRUE;
  67.     BYTE ch;
  68.  
  69.     crc16 = 0;
  70.  
  71.     while( moreData )
  72.         {
  73.         /* Read as much as we can into the remaining buffer space */
  74.         bytesToRead = _BUFSIZE - _outByteCount;
  75.         byteCount += bytesRead = hread( _inFD, _outBuffer + _outByteCount, bytesToRead );
  76.  
  77.         /* Update CRC for the data read and encrypt it and any other data
  78.            still in the buffer if necessary */
  79.         crc16buffer( _outBuffer + _outByteCount, bytesRead );
  80.         if( doCryptOut )
  81.             encryptCFB( _outBuffer + _outByteCount, bytesRead );
  82.  
  83.         /* See if the file is text or binary */
  84.         while( sampleCount < 50 && sampleCount <= bytesRead )
  85.             {
  86.             if( isprint( ch = _outBuffer[ _outByteCount + sampleCount ] ) || \
  87.                          ch == '\r' || ch == '\n' || ch == '\t' )
  88.                 textByteCount++;
  89.             sampleCount++;        /* isprint() has side effects - eek! */
  90.             }
  91.  
  92.         if( _outByteCount + bytesRead == _BUFSIZE )
  93.             {
  94.             /* We've filled the buffer, so flush it */
  95.             writeBuffer( _BUFSIZE );
  96.  
  97.             /* Check for special case of file size being exactly what we've
  98.                just read in */
  99.             if( !bytesRead )
  100.                 moreData = FALSE;
  101.             }
  102.         else
  103.             {
  104.             /* There's still room for more in the buffer */
  105.             _outByteCount += bytesRead;
  106.             if( doCryptOut )
  107.                 cryptMark += bytesRead;
  108.             moreData = FALSE;
  109.             }
  110.  
  111.         /* Print a dit if necessary */
  112.         printCount += bytesRead;
  113. #ifdef GUI
  114.         while( printCount >= 2048 )
  115.             {
  116.             updateProgressReport();
  117.             printCount -= 2048;
  118.             }
  119. #else
  120.         while( printCount >= 4096 )
  121.             {
  122.             hputchars( 'O' );
  123.             hflush( stdout );
  124.             printCount -= 4096;
  125.             }
  126. #endif /* GUI */
  127.         }
  128.  
  129.     fputWord( crc16 );
  130.     if( doCryptOut )
  131.         {
  132.         /* Encrypt crc16 in outBuffer */
  133.         encryptCFB( _outBuffer + cryptMark, _outByteCount - cryptMark );
  134.         cryptMark = _outByteCount;
  135.         }
  136.  
  137.     /* If at least 95% of the file's chars are text, we assume it's text.
  138.        This test uses absolute values rather than percentages since for
  139.        files smaller than 50 bytes it may be hard to reliably determine
  140.        whether it is text or not */
  141.     *isText = ( textByteCount > 47 ) ? TRUE : FALSE;
  142.  
  143.     return( byteCount + sizeof( WORD ) );
  144.     }
  145.  
  146. /****************************************************************************
  147. *                                                                            *
  148. *                    Unstore Uncompressed Data from an Archive                *
  149. *                                                                            *
  150. ****************************************************************************/
  151.  
  152. /* Retrieve uncompressed data from an archive.  In order to handle the stream
  153.    buffering we can't just read data into the _outBuffer, but have to read it
  154.    into the _inBuffer, copy it to the _outBuffer, and then write the
  155.    _outBuffer */
  156.  
  157. BOOLEAN unstore( long noBytes )
  158.     {
  159.     int bytesToProcess = _BUFSIZE - _inByteCount, printCount;
  160.     WORD checkSum;
  161.  
  162.     crc16 = 0;
  163.  
  164.     noBytes -= sizeof( WORD );    /* Don't move the checksum at the end */
  165.     _outByteCount = 0;
  166.     if( bytesToProcess )
  167.         {
  168.         /* Don't move more data than necessary */
  169.         if( bytesToProcess > noBytes )
  170.             bytesToProcess = ( int ) noBytes;
  171.  
  172.         /* Write out any data still in the buffer */
  173.         memcpy( _outBuffer, _inBuffer + _inByteCount, bytesToProcess );
  174.         writeBuffer( bytesToProcess );
  175.         noBytes -= bytesToProcess;
  176.         _inByteCount += bytesToProcess;
  177.  
  178.         /* Update CRC for data in buffer */
  179.         crc16buffer( _outBuffer, bytesToProcess );
  180.         }
  181.  
  182.     /* Print a dit if necessary */
  183.     printCount = bytesToProcess;
  184. #ifdef GUI
  185.     while( printCount >= 2048 )
  186.         {
  187.         updateProgressReport();
  188.         printCount -= 2048;
  189.         }
  190. #else
  191.     while( printCount >= 4096 )
  192.         {
  193.         hputchars( 'O' );
  194.         hflush( stdout );
  195.         printCount -= 4096;
  196.         }
  197. #endif /* GUI */
  198.  
  199.     while( noBytes )
  200.         {
  201.         _inBytesRead = vread( _inBuffer, _BUFSIZE );
  202.         bytesToProcess = ( noBytes < _inBytesRead ) ? \
  203.                          ( int ) noBytes : _inBytesRead;
  204.         memcpy( _outBuffer, _inBuffer, bytesToProcess );
  205.         writeBuffer( bytesToProcess);
  206.         noBytes -= bytesToProcess;
  207.         _inByteCount = bytesToProcess;
  208.  
  209.         /* Update CRC for data in buffer */
  210.         crc16buffer( _outBuffer, bytesToProcess );
  211.  
  212.         /* Print a dit if necessary */
  213.         printCount += bytesToProcess;
  214. #ifdef GUI
  215.         while( printCount >= 2048 )
  216.             {
  217.             updateProgressReport();
  218.             printCount -= 2048;
  219.             }
  220. #else
  221.         while( printCount >= 4096 )
  222.             {
  223.             hputchars( 'O' );
  224.             hflush( stdout );
  225.             printCount -= 4096;
  226.             }
  227. #endif /* GUI */
  228.  
  229.         /* If we run out of input, make sure we don't go into an endless loop */
  230.         if( !_inBytesRead )
  231.             return( FALSE );            /* Data corrupted */
  232.         }
  233.  
  234.     flushBuffer();
  235.     checkSum = fgetWord();
  236.     return( crc16 == checkSum );
  237.     }
  238.  
  239. /****************************************************************************
  240. *                                                                            *
  241. *                        High-speed Data Move Routine                        *
  242. *                                                                            *
  243. ****************************************************************************/
  244.  
  245. /* Move data from one file to another without doing a CRC check.  This
  246.    routine must take care to correctly handle any data already in the buffer.
  247.    Note that this is a pure data moving routine and doesn't handle things
  248.    like encryption */
  249.  
  250. void moveData( long noBytes )
  251.     {
  252.     int bytesRead, bytesToRead = _BUFSIZE - _outByteCount;
  253.  
  254.     /* Read as much as we can into the remaining buffer space */
  255.     bytesRead = vread( _outBuffer + _outByteCount, ( noBytes < bytesToRead ) ? \
  256.                                                    ( int ) noBytes : bytesToRead );
  257.  
  258.     if( _outByteCount + bytesRead == _BUFSIZE )
  259.         {
  260.         /* We've filled the buffer, so flush it */
  261.         writeBuffer( _BUFSIZE );
  262.         noBytes -= bytesRead;
  263.         }
  264.     else
  265.         {
  266.         /* There's still room for more in the buffer */
  267.         _outByteCount += bytesRead;
  268.         noBytes = 0L;
  269.         }
  270.  
  271.     /* Now blast the data through the buffer */
  272.     while( noBytes )
  273.         {
  274.         bytesToRead = ( noBytes < _BUFSIZE ) ? ( int ) noBytes : _BUFSIZE;
  275.         _outByteCount = vread( _outBuffer, bytesToRead );
  276.         if( _outByteCount == _BUFSIZE )
  277.             /* We've filled the buffer, so flush it */
  278.             writeBuffer( bytesToRead );
  279.         noBytes -= bytesToRead;
  280.         }
  281.     }
  282.