📄 unzip.c
字号:
if( error > PK_WARN ) /* if error occurred, see if user ejected media during long inflation job */
return( -1 );
return( count );
}
int unzip_seek( LONGINT val, ARCHIVE * arc )
{
LONGINT request = val/*+extra_bytes*/,
inbuf_offset = request % INBUFSIZ,
bufstart = request - inbuf_offset;
if( request < 0 )
{
return( -1 );
}
else
{
if( bufstart != arc -> start_buffer )
{
arc -> start_buffer = lseek( arc -> os_handle, (LONGINT)bufstart, SEEK_SET );
if(( arc -> tmp_in_count = read( arc -> os_handle,(char *)arc -> tmp_in_buffer, INBUFSIZ )) <= 0 )
return( -1 );
arc -> tmp_in_ptr = arc -> tmp_in_buffer + inbuf_offset;
arc -> tmp_in_count -= (int)inbuf_offset;
}
else
{
arc -> tmp_in_count += (arc -> tmp_in_ptr - arc -> tmp_in_buffer) - inbuf_offset;
arc -> tmp_in_ptr = arc -> tmp_in_buffer + inbuf_offset;
}
}
return( 0 ); /* success (i guess) */
}
/* =======================================================
FUNCTION: getfiletomem()
PURPOSE: Unpack the file.
PARAMETERS: ...
RETURNS: Error code if any.
======================================================= */
#if 0
int getfiletomem( char * myfile, char **retbuf, long * size, COMPRESSED_FILE * cmp ) /* return PK-type error code */
{
int error;
struct direntry * entry;
if(( entry = getentry(myfile)) == NULL )
return -1;
if((int)entry -> file_position < 0 )
{
int fd;
char filename[_MAX_PATH];
construct_path(local_file_dir, filename, myfile, entry->file_position);
// sprintf(filename, "%s%s", local_file_dir, myfile);
if((fd = open(filename, O_BINARY|O_RDONLY)) >= 0 )
{
#ifdef USE_SH_POOLS
if((cmp -> out_buffer = (char *)MemAllocPtr( gResmgrMemPool, entry->file_size + strlen(myfile) + 1, 0 )) == NULL )
return -1;
#else
if((cmp -> out_buffer = (char *)MemMalloc( entry->file_size + strlen(myfile) + 1, myfile )) == NULL )
return -1;
#endif
read(fd, cmp -> out_buffer, entry->file_size);
strcpy(cmp -> out_buffer + entry->file_size, myfile);
close(fd);
}
else
{
return -1;
}
}
else
{
if( entry->file_csize > INPUTBUFSIZE )
{
cmp -> in_size = INPUTBUFSIZE;
}
else
{
cmp -> in_size = entry->file_csize; /* alloced size should be either 2K or 10K already*/
}
cmp -> in_ptr = cmp -> in_buffer;
cmp -> in_count = 0;
/*
* just about to extract file: if extracting to disk, check if
* already exists, and if so, take appropriate action according to
* fflag/uflag/overwrite_all/etc. (we couldn't do this in upper
* loop because we don't store the possibly renamed filename[] in
* info[])
*/
#ifdef USE_SH_POOLS
if((cmp -> out_buffer = (char *)MemAllocPtr( gResmgrMemPool, entry->file_size + strlen(myfile) + 1, 0 )) == NULL )
return -1;
#else
if((cmp -> out_buffer = (char *)MemMalloc( entry->file_size + strlen(myfile) + 1, myfile )) == NULL )
return -1;
#endif
outcnt = 0;
lseek( tmp -> archive -> os_handle, entry->file_position, SEEK_SET );
if((error = extract_or_test_member( entry->method, entry->file_csize, cmp )) != PK_COOL)
{
#ifdef USE_SH_POOLS
MemFreePtr( tmp -> out_buffer );
#else
MemFree( tmp -> out_buffer );
#endif
return -1; /* (unless disk full) */
}
strcpy( tmp -> out_buffer + entry -> file_size, myfile );
}
*retbuf = tmp -> out_buffer;
if( size != NULL )
*size = entry->file_size;
return( 0 );
}
#endif
/* =======================================================
FUNCTION: makeword
PURPOSE: Convert Intel style 'short' integer to
non-Intel non-16-bit host format. This
routine also takes care of byte-ordering.
PARAMETERS: Short (cast to unsigned char).
RETURNS: Unsigned Short.
======================================================= */
static ush makeword(uch *b)
{
return (ush)((b[1] << 8) | b[0]);
}
/* =======================================================
FUNCTION: makelong
PURPOSE: Convert Intel style 'long' integer to
non-Intel non-16-bit host format. This
routine also takes care of byte-ordering.
PARAMETERS: Long (cast to unsigned char).
RETURNS: Unsigned Long.
======================================================= */
static ulg makelong(uch *sig)
{
return (((ulg)sig[3])<<24)|(((ulg)sig[2])<<16)|(((ulg)sig[1])<<8)|((ulg)sig[0]);
}
/* =======================================================
FUNCTION: process_cdir_file_hdr()
PURPOSE: Get central directory info, save host and
method numbers, and set flag for lowercase
conversion of filename, depending on the
OS from which the file is coming.
PARAMETERS: ptr to ...
RETURNS: Error if any.
======================================================= */
static int process_cdir_file_hdr( cdir_file_hdr * crec, ARCHIVE * arc )
{
int error;
if((error = get_cdir_file_hdr(crec, arc)) != 0)
return( error );
return( PK_COOL );
}
/* =======================================================
FUNCTION: extract_or_test_member()
PURPOSE: Unpack the file.
PARAMETERS: Compression method, compressed file size1,
ptr to an archive.
RETURNS: Error code if any.
======================================================= */
int extract_or_test_member( int method, long fcsize, COMPRESSED_FILE * cmp )
{
int r,
error = PK_COOL;
char * pos;
switch( method )
{
case STORED:
pos = (char *)cmp -> out_buffer;
seeklocked = TRUE;
do
{
r = (fcsize > INPUTBUFSIZE) ? INPUTBUFSIZE : fcsize;
read( cmp -> archive -> os_handle, pos, r );
pos += r;
fcsize -= r;
} while( fcsize > 0 );
seeklocked = FALSE;
break;
#ifndef SFX
case SHRUNK:
break;
case REDUCED1:
case REDUCED2:
case REDUCED3:
case REDUCED4:
break;
case IMPLODED:
break;
#endif /* !SFX */
case DEFLATED:
cmp -> csize = fcsize;
seeklocked = TRUE;
if ((r = inflate( cmp )) != 0)
error = (r == 3)? PK_MEM2 : PK_ERR;
/* free allocated memory */
seeklocked = FALSE;
inflate_free();
break;
default: /* should never get to this point */
/* close and delete file before return? */
error = PK_WARN;
break;
} /* end switch (compression method) */
/* NOTE THAT WE ****DISABLE**** crc checking on here..... and in fileio */
return( error );
}
/* =======================================================
FUNCTION: readbuf()
PURPOSE: ...
PARAMETERS: Ptr to buffer, num bytes.
RETURNS: Number of bytes read into buffer.
======================================================= */
int readbuf( char * buf, unsigned size, ARCHIVE * arc )
{
register int count;
int n;
n = size;
while( size ) {
if( arc -> tmp_in_count == 0 ) {
if(( arc -> tmp_in_count = read( arc -> os_handle, (char *)arc -> tmp_in_buffer, arc -> tmp_in_size )) == 0 ) {
//arc -> start_buffer += arc -> tmp_in_size;
return( (int)(n-size) );
}
else {
if( arc -> tmp_in_count < 0 ) {
//arc -> start_buffer += arc -> tmp_in_size;
return( -1 ); /* discarding some data, but better than lockup */
}
}
/* buffer ALWAYS starts on a block boundary: */
arc -> start_buffer += arc -> tmp_in_size; /* NUKE??? */
arc -> tmp_in_ptr = arc -> tmp_in_buffer;
}
count = MIN( size, (unsigned)arc -> tmp_in_count );
memcpy( buf, arc -> tmp_in_ptr, count );
buf += count;
arc -> tmp_in_ptr += count;
arc -> tmp_in_count -= count;
size -= count;
}
return( n );
}
/* =======================================================
FUNCTION: readbyte()
PURPOSE: Refill the input buffer and return a byte
if available - otherwise return 'EOF'.
PARAMETERS: Ptr to a compressed file structure
RETURNS: Byte read or EOF token.
======================================================= */
int readbyte( COMPRESSED_FILE * cmp )
{
if((cmp -> in_count = read(cmp -> archive -> os_handle, (char *)cmp -> in_buffer, cmp -> in_size )) <= 0 )
return( EOF );
// nuke(?) cmp -> start_buffer += cmp -> in_size; /* always starts on a block boundary */
cmp -> in_ptr = cmp -> in_buffer;
--cmp -> in_count;
// return( (*(int*)(cmp -> in_ptr))++ );
return(*cmp->in_ptr++);
}
/* =======================================================
FUNCTION: flush()
PURPOSE: ...
PARAMETERS: Ptr to buffer, size, ...
RETURNS: Byte read or EOF token.
NOTE: Only called from inflate.h!
--- archive_entry should be compress_file ---
======================================================= */
int flush( uch * rawbuf, ulg size, int unshrink, COMPRESSED_FILE * cmp )
{
if( size == 0L ) /* testing or nothing to write: all done */
return( 0 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -