home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Hack-Phreak Scene Programs
/
cleanhpvac.zip
/
cleanhpvac
/
HPACK78S.ZIP
/
tags.c
< prev
next >
Wrap
Text File
|
1992-12-03
|
22KB
|
721 lines
/****************************************************************************
* *
* HPACK Multi-System Archiver *
* =========================== *
* *
* HPACK Archive Tag Handling Code *
* TAGS.C Updated 08/09/92 *
* *
* This program is protected by copyright and as such any use or copying of *
* this code for your own purposes directly or indirectly is highly uncool *
* and if you do so there will be....trubble. *
* And remember: We know where your kids go to school. *
* *
* Copyright 1990 - 1992 Peter C.Gutmann. All rights reserved *
* *
****************************************************************************/
#ifdef __MAC__
#include "defs.h"
#include "error.h"
#include "hpacklib.h"
#include "system.h"
#include "tags.h"
#include "fastio.h"
#else
#include "defs.h"
#include "error.h"
#include "hpacklib.h"
#include "system.h"
#include "tags.h"
#include "io/fastio.h"
#endif /* __MAC__ */
/****************************************************************************
* *
* Read Tagged Data Routines *
* *
****************************************************************************/
/* Grovel through a tag field looking for tags we can handle */
int readTag( long *tagFieldSize, TAGINFO *tagInfo )
{
WORD theTag;
int tagClass = TAGCLASS_NONE;
LONG dataLength;
while( *tagFieldSize > 0 && !tagClass )
{
dataLength = 0L;
theTag = fgetWord();
/* Extract the tag ID and data length depending on the type of the tag */
if( theTag >= LONG_BASE )
{
/* Get 9-bit tag ID and tag length information */
tagInfo->tagID = ( ( ( theTag & 1 ) << 8 ) | fgetByte() ) + NO_SHORT_TAGS;
tagInfo->dataFormat = ( theTag & LONGTAG_FORMAT_MASK ) >> LONGTAG_FORMAT_SHIFT;
switch( theTag & LONGTAG_LENGTH_MASK )
{
case LONGTAG_BYTE_WORD:
tagInfo->dataLength = tagInfo->uncoprLength = ( LONG ) fgetByte();
dataLength += LONG_TAGSIZE + sizeof( BYTE );
if( tagInfo->dataFormat )
{
tagInfo->uncoprLength = ( LONG ) fgetWord();
dataLength += sizeof( WORD );
}
break;
case LONGTAG_WORD_WORD:
tagInfo->dataLength = tagInfo->uncoprLength = ( LONG ) fgetWord();
dataLength += LONG_TAGSIZE + sizeof( WORD );
if( tagInfo->dataFormat )
{
tagInfo->uncoprLength = ( LONG ) fgetWord();
dataLength += sizeof( WORD );
}
break;
case LONGTAG_WORD_LONG:
tagInfo->dataLength = tagInfo->uncoprLength = ( LONG ) fgetWord();
dataLength += LONG_TAGSIZE + sizeof( WORD );
if( tagInfo->dataFormat )
{
tagInfo->uncoprLength = fgetLong();
dataLength += sizeof( LONG );
}
break;
case LONGTAG_LONG_LONG:
tagInfo->dataLength = tagInfo->uncoprLength = fgetLong();
dataLength += LONG_TAGSIZE + sizeof( LONG );
if( tagInfo->dataFormat )
{
tagInfo->uncoprLength = fgetLong();
dataLength += sizeof( LONG );
}
break;
}
}
else
{
tagInfo->tagID = ( theTag & TAGID_MASK ) >> TAGID_SHIFT;
tagInfo->dataFormat = TAGFORMAT_STORED;
tagInfo->dataLength = tagInfo->uncoprLength = theTag & DATALEN_MASK;
dataLength += SHORT_TAGSIZE;
/* If it's an alternative short-form of a tag, convert the ID to
the usual form */
if( tagInfo->tagID == TAG_S_LONGNAME )
tagInfo->tagID = TAG_LONGNAME;
else
if( tagInfo->tagID == TAG_S_COMMENT )
tagInfo->tagID = TAG_COMMENT;
else
if( tagInfo->tagID == TAG_S_ERROR )
tagInfo->tagID = TAG_ERROR;
}
*tagFieldSize -= dataLength + tagInfo->dataLength;
/* If the length field has been corrupted, set the tagID to a non-
tag and perform error recovery later on */
if( *tagFieldSize < 0 )
tagInfo->tagID = BAD_TAGID;
/* Now handle each tag. At this point we only check whether we know
what to do with the tag, but don't do any processing. Any tags
which contain useless information (as well as those we don't know
about) are skipped */
switch( tagInfo->tagID )
{
case TAG_AMIGA_ATTR:
case TAG_APPLE_ATTR:
case TAG_ARC_ATTR:
case TAG_ATARI_ATTR:
case TAG_MAC_ATTR:
case TAG_MSDOS_ATTR:
case TAG_OS2_ATTR:
case TAG_UNIX_ATTR:
case TAG_VMS_ATTR:
tagClass = TAGCLASS_ATTRIBUTE;
break;
case TAG_COMMENT:
tagClass = TAGCLASS_COMMENT;
break;
case TAG_ACCESS_TIME:
case TAG_BACKUP_TIME:
case TAG_CREATION_TIME:
case TAG_EXPIRATION_TIME:
tagClass = TAGCLASS_TIME;
break;
case TAG_AMIGA_ICON:
case TAG_OS2_ICON:
tagClass = TAGCLASS_ICON;
break;
case TAG_EXECUTE_ADDRESS:
case TAG_LOAD_ADDRESS:
case TAG_LONGNAME:
case TAG_MAC_TYPE:
case TAG_MAC_CREATOR:
case TAG_OS2_MISC_EA:
case TAG_POSITION:
case TAG_SECURITY_INFO:
case TAG_RESOURCE_FORK:
case TAG_VERSION_NUMBER:
case TAG_WINSIZE:
tagClass = TAGCLASS_MISC;
break;
default:
/* Unrecognised tag, skip it and look for next one */
if( *tagFieldSize < 0 )
{
/* If the tag length field is corrupted, just skip
over whatever data is left */
skipSeek( *tagFieldSize + tagInfo->dataLength );
tagInfo->dataLength = tagInfo->uncoprLength = 0L;
*tagFieldSize = 0;
}
else
skipSeek( tagInfo->dataLength );
break;
}
}
return( tagClass );
}
/* Read in attribute data and translate it for the host OS. Note that
execute bits are never translated, for obvious reasons */
ATTR readAttributeData( const WORD attributeID )
{
WORD wordData;
BYTE byteData;
ATTR retVal = 0;
switch( attributeID )
{
case TAG_ATARI_ATTR:
case TAG_MSDOS_ATTR:
case TAG_OS2_ATTR:
byteData = fgetByte();
#if defined( __ATARI__ ) || defined( __MSDOS__ ) || defined( __OS2__ )
retVal = byteData & ~DIRECT; /* Can't set dir.attr */
#elif defined( __AMIGA__ )
retVal |= AMIGA_ATTR_READ | AMIGA_ATTR_WRITE | AMIGA_ATTR_DELETE;
if( byteData & MSDOS_ATTR_ARCHIVE )
retVal |= AMIGA_ATTR_ARCHIVE;
if( byteData & MSDOS_ATTR_RDONLY )
retVal ^= AMIGA_ATTR_READ;
if( byteData & MSDOS_ATTR_HIDDEN )
retVal |= AMIGA_ATTR_HIDDEN;
#elif defined( __MAC__ )
if( byteData & MSDOS_ATTR_ARCHIVE )
retVal |= MAC_ATTR_CHANGED;
if( byteData & MSDOS_ATTR_SYSTEM )
retVal |= MAC_ATTR_SYSTEM;
if( byteData & MSDOS_ATTR_HIDDEN )
retVal |= MAC_ATTR_INVISIBLE;
if( byteData & MSDOS_ATTR_RDONLY )
retVal |= MAC_ATTR_LOCKED;
#elif defined( __UNIX__ )
if( byteData & MSDOS_ATTR_RDONLY )
retVal = UNIX_ATTR_RBITS;
else
retVal = UNIX_ATTR_RBITS | UNIX_ATTR_WBITS;
#elif defined( __VMS__ )
if( byteData & MSDOS_ATTR_RDONLY )
retVal = VMS_ATTR_RBITS;
else
retVal = VMS_ATTR_RBITS | VMS_ATTR_DBITS;
#else
hprintf( "Don't know what to do with MSDOS attributes, TAGS.C line %d\n", __LINE__ );
#endif /* Various OS-specific defines */
break;
case TAG_AMIGA_ATTR:
byteData = fgetByte();
#if defined( __ATARI__ ) || defined( __MSDOS__ ) || defined( __OS2__ )
if( !( byteData & AMIGA_ATTR_WRITE ) )
retVal |= MSDOS_ATTR_RDONLY;
if( !( byteData & AMIGA_ATTR_ARCHIVE ) )
retVal |= MSDOS_ATTR_ARCHIVE;
#elif defined( __AMIGA__ )
retVal = byteData;
#elif defined( __MAC__ )
if( !( wordData & AMIGA_ATTR_WRITE ) )
retVal |= MAC_ATTR_LOCKED;
if( !( wordData & AMIGA_ATTR_ARCHIVE ) )
retVal |= MAC_ATTR_CHANGED;
#elif defined( __UNIX__ )
if( byteData & AMIGA_ATTR_READ )
retVal |= UNIX_ATTR_RBITS;
if( byteData & AMIGA_ATTR_WRITE )
retVal |= UNIX_ATTR_WBITS;
#elif defined( __VMS__ )
if( byteData & AMIGA_ATTR_READ )
retVal |= VMS_ATTR_RBITS;
if( byteData & AMIGA_ATTR_WRITE )
retVal |= VMS_ATTR_WBITS;
#else
hprintf( "Don't know what to do with Amiga attributes, TAGS.C line %d\n", __LINE__ );
#endif /* Various OS-specific defines */
break;
case TAG_APPLE_ATTR:
wordData = fgetWord();
#if defined( __ATARI__ ) || defined( __MSDOS__ ) || defined( __OS2__ )
if( !( wordData & APPLE_ATTR_WRITE ) )
retVal |= MSDOS_ATTR_RDONLY;
if( wordData & APPLE_ATTR_BACKUP )
retVal |= MSDOS_ATTR_ARCHIVE;
#elif defined( __AMIGA__ )
if( wordData & APPLE_ATTR_READ )
retVal |= AMIGA_ATTR_READ;
if( wordData & APPLE_ATTR_WRITE )
retVal |= AMIGA_ATTR_WRITE | AMIGA_ATTR_DELETE;
if( wordData & APPLE_ATTR_BACKUP )
retVal |= AMIGA_ATTR_ARCHIVE;
#elif defined( __UNIX__ )
if( wordData & APPLE_ATTR_READ )
retVal |= UNIX_ATTR_RBITS;
if( wordData & APPLE_ATTR_WRITE )
retVal |= UNIX_ATTR_WBITS;
#elif defined( __MAC__ )
if( !( wordData & APPLE_ATTR_WRITE ) )
retVal |= MAC_ATTR_LOCKED;
if( wordData & APPLE_ATTR_BACKUP )
retVal |= MAC_ATTR_CHANGED;
#elif defined( __UNIX__ )
if( wordData & APPLE_ATTR_READ )
retVal |= VMS_ATTR_RBITS;
if( wordData & APPLE_ATTR_WRITE )
retVal |= VMS_ATTR_WBITS;
#else
hprintf( "Don't know what to do with IIgs attributes, TAGS.C line %d\n", __LINE__ );
#endif /* Various OS-specific defines */
break;
case TAG_ARC_ATTR:
byteData = fgetByte();
#if defined( __ATARI__ ) || defined( __MSDOS__ ) || defined( __OS2__ )
if( byteData & ARC_ATTR_LOCKED )
retVal |= MSDOS_ATTR_RDONLY;
#elif defined( __AMIGA__ )
if( byteData & ARC_ATTR_READ_OWNER )
retVal |= AMIGA_ATTR_READ;
if( byteData & ARC_ATTR_WRITE_OWNER )
retVal |= AMIGA_ATTR_WRITE | AMIGA_ATTR_DELETE;
#elif defined( __MAC__ )
if( byteData & ARC_ATTR_LOCKED )
retVal |= MAC_ATTR_LOCKED;
#elif defined( __UNIX__ )
if( byteData & ARC_ATTR_READ_OWNER )
retVal |= UNIX_ATTR_OWNER_R;
if( byteData & ARC_ATTR_WRITE_OWNER )
retVal |= UNIX_ATTR_OWNER_W;
if( byteData & ARC_ATTR_READ_OTHER )
retVal |= UNIX_ATTR_GROUP_R | UNIX_ATTR_OTHER_W;
if( byteData & ARC_ATTR_WRITE_OTHER )
retVal |= UNIX_ATTR_GROUP_W | UNIX_ATTR_OTHER_W;
#elif defined( __VMS__ )
if( byteData & ARC_ATTR_READ_OWNER )
retVal |= VMS_ATTR_SYSTEM_R | VMS_ATTR_OWNER_R;
if( byteData & ARC_ATTR_WRITE_OWNER )
retVal |= VMS_ATTR_SYSTEM_W | VMS_ATTR_OWNER_W;
if( byteData & ARC_ATTR_READ_OTHER )
retVal |= VMS_ATTR_GROUP_R | VMS_ATTR_WORLD_R;
if( byteData & ARC_ATTR_WRITE_OTHER )
retVal |= VMS_ATTR_GROUP_W | VMS_ATTR_WORLD_W;
#else
hprintf( "Don't know what to do with Archimedes attributes, TAGS.C line %d\n", __LINE__ );
#endif /* Various OS-specific defines */
break;
case TAG_MAC_ATTR:
wordData = fgetWord();
#if defined( __ATARI__ ) || defined( __MSDOS__ ) || defined( __OS2__ )
if( wordData & MAC_ATTR_CHANGED )
retVal |= MSDOS_ATTR_ARCHIVE;
if( wordData & MAC_ATTR_SYSTEM )
retVal |= MSDOS_ATTR_SYSTEM;
if( wordData & MAC_ATTR_INVISIBLE )
retVal |= MSDOS_ATTR_HIDDEN;
if( wordData & MAC_ATTR_LOCKED )
retVal |= MSDOS_ATTR_RDONLY;
#elif defined( __AMIGA__ )
retVal |= AMIGA_ATTR_READ | AMIGA_ATTR_WRITE | AMIGA_ATTR_DELETE;
if( wordData & MAC_ATTR_CHANGED )
retVal |= AMIGA_ATTR_ARCHIVE;
if( wordData & MAC_ATTR_INVISIBLE )
retVal |= AMIGA_ATTR_HIDDEN;
if( wordData & MAC_ATTR_LOCKED )
retVal ^= AMIGA_ATTR_WRITE;
#elif defined( __MAC__ )
retVal = wordData;
#elif defined( __UNIX__ )
if( wordData & MAC_ATTR_LOCKED )
retVal = UNIX_ATTR_RBITS;
else
retVal = UNIX_ATTR_RBITS | UNIX_ATTR_WBITS;
#elif defined( __VMS__ )
if( wordData & MAC_ATTR_LOCKED )
retVal = VMS_ATTR_RBITS;
else
retVal = VMS_ATTR_RBITS | VMS_ATTR_DBITS;
#else
hprintf( "Don't know what to do with Mac attributes, TAGS.C line %d\n", __LINE__ );
#endif /* Various OS-specific defines */
break;
case TAG_UNIX_ATTR:
wordData = fgetWord();
#if defined( __ATARI__ ) || defined( __MSDOS__ ) || defined( __OS2__ )
if( !( wordData & UNIX_ATTR_OWNER_W ) )
retVal |= MSDOS_ATTR_RDONLY;
#elif defined( __AMIGA__ )
retVal |= AMIGA_ATTR_READ | AMIGA_ATTR_WRITE | AMIGA_ATTR_DELETE;
if( !( wordData & UNIX_ATTR_OWNER_R ) )
retVal ^= AMIGA_ATTR_READ;
if( !( wordData & UNIX_ATTR_OWNER_W ) )
retVal ^= ( AMIGA_ATTR_WRITE | AMIGA_ATTR_DELETE );
#elif defined( __MAC__ )
if( !( wordData & UNIX_ATTR_OWNER_W ) )
retVal |= MAC_ATTR_LOCKED;
#elif defined( __UNIX__ )
retVal = wordData;
#elif defined( __VMS__ )
if( wordData & UNIX_ATTR_OTHER_R )
retVal |= VMS_ATTR_WORLD_R;
if( wordData & UNIX_ATTR_OTHER_W )
retVal |= VMS_ATTR_WORLD_W | VMS_ATTR_WORLD_D;
if( wordData & UNIX_ATTR_GROUP_R )
retVal |= VMS_ATTR_GROUP_R;
if( wordData & UNIX_ATTR_GROUP_W )
retVal |= VMS_ATTR_GROUP_W | VMS_ATTR_GROUP_D;
if( wordData & UNIX_ATTR_OWNER_R )
retVal |= VMS_ATTR_OWNER_R;
if( wordData & UNIX_ATTR_OWNER_W )
retVal |= VMS_ATTR_OWNER_W | VMS_ATTR_OWNER_D;
#else
hprintf( "Don't know what to do with Unix attributes, TAGS.C line %d\n", __LINE__ );
#endif /* Various OS-specific defines */
break;
case TAG_VMS_ATTR:
wordData = fgetWord();
#if defined( __ATARI__ ) || defined( __MSDOS__ ) || defined( __OS2__ )
if( !( wordData & VMS_ATTR_OWNER_W ) )
retVal |= MSDOS_ATTR_RDONLY;
#elif defined( __AMIGA__ )
if( wordData & VMS_ATTR_OWNER_R )
retVal |= AMIGA_ATTR_READ;
if( wordData & VMS_ATTR_OWNER_W )
retVal |= AMIGA_ATTR_WRITE;
if( wordData & VMS_ATTR_OWNER_D )
retVal |= AMIGA_ATTR_DELETE;
#elif defined( __MAC__ )
if( !( wordData & VMS_ATTR_OWNER_W ) )
retVal |= MAC_ATTR_LOCKED;
#elif defined( __UNIX__ )
if( wordData & VMS_ATTR_WORLD_R )
retVal |= UNIX_ATTR_OTHER_R;
if( wordData & ( VMS_ATTR_WORLD_W | VMS_ATTR_WORLD_D ) )
retVal |= UNIX_ATTR_OTHER_W;
if( wordData & VMS_ATTR_GROUP_R )
retVal |= UNIX_ATTR_GROUP_R;
if( wordData & ( VMS_ATTR_GROUP_W | VMS_ATTR_GROUP_D ) )
retVal |= UNIX_ATTR_GROUP_W;
if( wordData & VMS_ATTR_OWNER_R )
retVal |= UNIX_ATTR_OWNER_R;
if( wordData & ( VMS_ATTR_OWNER_W | VMS_ATTR_OWNER_D ) )
retVal |= UNIX_ATTR_OWNER_W;
#elif defined( __VMS__ )
retVal = wordData;
#else
hprintf( "Don't know what to do with VMS attributes, TAGS.C line %d\n", __LINE__ );
#endif /* Various OS-specific defines */
}
return( retVal );
}
/****************************************************************************
* *
* Write Tagged Data Routines *
* *
****************************************************************************/
/* Write a long tag */
int writeTag( WORD tagID, const WORD store, const LONG dataLength, const LONG uncoprLength )
{
WORD tagLength = ( dataLength <= 0xFF ) ? LONGTAG_BYTE_WORD : \
( dataLength > 0xFFFF ) ? LONGTAG_LONG_LONG : \
( uncoprLength <= 0xFFFF ) ? LONGTAG_WORD_WORD : \
LONGTAG_WORD_LONG;
int headerLen = sizeof( WORD ) + sizeof( BYTE );
BOOLEAN isShortForm = ( store == TAGFORMAT_STORED ) && \
( dataLength < SHORT_TAGLEN ) && \
( tagID == TAG_LONGNAME || tagID == TAG_COMMENT || \
tagID == TAG_ERROR );
/* Determine whether we can write a short tag or not. We can do this
either if the tagID is a short tagID, or if there is a short form of
the tag and it fulfils the requirements for a short tag */
if( isShortTag( tagID ) || isShortForm )
{
/* If it's a short form tag, convert the ID to the short-form equivalent */
if( isShortForm )
{
if( tagID == TAG_LONGNAME )
tagID = TAG_S_LONGNAME;
else
if( tagID == TAG_COMMENT )
tagID = TAG_S_COMMENT;
else
tagID = TAG_S_ERROR;
}
fputWord( ( tagID << TAGID_SHIFT ) | ( WORD ) dataLength );
return( sizeof( WORD ) );
}
/* Write long tag ID, storage class, and 9-bit actual tag ID */
tagID -= NO_SHORT_TAGS; /* Convert to base value of zero */
fputWord( LONG_BASE | tagLength | ( store << LONGTAG_FORMAT_SHIFT ) | ( tagID >> 8 ) );
fputByte( tagID & 0xFF );
switch( tagLength )
{
case LONGTAG_BYTE_WORD:
fputByte( ( BYTE ) dataLength );
headerLen += sizeof( BYTE );
if( store )
{
fputWord( ( WORD ) uncoprLength );
headerLen += sizeof( WORD );
}
break;
case LONGTAG_WORD_WORD:
fputWord( ( WORD ) dataLength );
headerLen += sizeof( WORD );
if( store )
{
fputWord( ( WORD ) uncoprLength );
headerLen += sizeof( WORD );
}
break;
case LONGTAG_WORD_LONG:
fputWord( ( WORD ) dataLength );
headerLen += sizeof( WORD );
if( store )
{
fputLong( uncoprLength );
headerLen += sizeof( LONG );
}
break;
case LONGTAG_LONG_LONG:
fputLong( dataLength );
headerLen += sizeof( LONG );
if( store )
{
fputLong( uncoprLength );
headerLen += sizeof( LONG );
}
break;
}
return( headerLen );
}
#ifndef __MSDOS__ /* Save a bit of code size */
int writeDirTag( WORD tagID, const WORD store, const LONG dataLength, const LONG uncoprLength )
{
WORD tagLength = ( dataLength <= 0xFF ) ? LONGTAG_BYTE_WORD : \
( dataLength > 0xFFFF ) ? LONGTAG_LONG_LONG : \
( uncoprLength <= 0xFFFF ) ? LONGTAG_WORD_WORD : \
LONGTAG_WORD_LONG;
int headerLen = sizeof( WORD ) + sizeof( BYTE );
BOOLEAN isShortForm = ( store == TAGFORMAT_STORED ) && \
( dataLength < SHORT_TAGLEN ) && \
( tagID == TAG_LONGNAME || tagID == TAG_COMMENT || \
tagID == TAG_ERROR );
/* Determine whether we can write a short tag or not. We can do this
either if the tagID is a short tagID, or if there is a short form of
the tag and it fulfils the requirements for a short tag */
if( isShortTag( tagID ) || isShortForm )
{
/* If it's a short form tag, convert the ID to the short-form equivalent */
if( isShortForm )
{
if( tagID == TAG_LONGNAME )
tagID = TAG_S_LONGNAME;
else
if( tagID == TAG_COMMENT )
tagID = TAG_S_COMMENT;
else
tagID = TAG_S_ERROR;
}
fputDirWord( ( tagID << TAGID_SHIFT ) | ( WORD ) dataLength );
return( sizeof( WORD ) );
}
/* Write long tag ID, storage class, and 9-bit actual tag ID */
tagID -= NO_SHORT_TAGS; /* Convert to base value of zero */
fputDirWord( LONG_BASE | tagLength | ( store << LONGTAG_FORMAT_SHIFT ) | ( tagID >> 8 ) );
fputDirByte( tagID & 0xFF );
switch( tagLength )
{
case LONGTAG_BYTE_WORD:
fputDirByte( ( BYTE ) dataLength );
headerLen += sizeof( BYTE );
if( store )
{
fputDirWord( ( WORD ) uncoprLength );
headerLen += sizeof( WORD );
}
break;
case LONGTAG_WORD_WORD:
fputDirWord( ( WORD ) dataLength );
headerLen += sizeof( WORD );
if( store )
{
fputDirWord( ( WORD ) uncoprLength );
headerLen += sizeof( WORD );
}
break;
case LONGTAG_WORD_LONG:
fputDirWord( ( WORD ) dataLength );
headerLen += sizeof( WORD );
if( store )
{
fputDirLong( uncoprLength );
headerLen += sizeof( LONG );
}
break;
case LONGTAG_LONG_LONG:
fputDirLong( dataLength );
headerLen += sizeof( LONG );
if( store )
{
fputDirLong( uncoprLength );
headerLen += sizeof( LONG );
}
break;
}
return( headerLen );
}
#else
int writeDirTag( WORD tagID, const WORD store, const LONG dataLength, const LONG uncoprLength )
{
/* Minimal writeTag() routine - MSDOS doesn't need all this code */
fputDirWord( ( tagID << TAGID_SHIFT ) | ( WORD ) dataLength );
return( sizeof( WORD ) );
}
#endif /* __MSDOS__ */
/* The following routines are used to write variable-length tagged fields to
the archive or directory information files. Only some versions of HPACK
will need them */
#if 0
static BYTE *tempBuffer; /* Kludge for now */
extern BYTE *tempBuffer;
/* Try and compress tagged data using the auxiliary compressor */
static WORD compressTag( const BYTE *inBuffer, const BYTE *outBuffer, WORD count )
{
/* Get rid of "Unused parameter" warning */
if( inBuffer == outBuffer );
/* Do nothing at the moment */
return( count );
}
/* Write a tag to the archive */
WORD writeTag( WORD tagID, WORD tagLength, BYTE *dataBuffer )
{
WORD compressedTagLength, i = 0;
/* Write the tag itself as either a short or a long tag */
if( tagLength < SHORT_TAGLEN )
fputWord( tagID | tagLength );
else
{
/* Try and compress the tag data */
if( ( compressedTagLength = compressTag( dataBuffer, tempBuffer, tagLength ) ) > \
tagLength - sizeof( WORD ) )
{
/* Data couldn't be compressed, stored in uncompressed form */
fputWord( LONG_TAG( TAGFORMAT_STORED ) );
fputByte( ( BYTE ) tagID );
fputWord( tagLength );
}
else
{
/* Data was compressed, save uncompressed length at start of data */
fputWord( LONG_TAG( TAGFORMAT_PACKED ) );
fputByte( ( BYTE ) tagID );
fputWord( compressedTagLength );
fputWord( tagLength );
/* Process the compressed data not the original data */
tagLength = compressedTagLength;
dataBuffer = tempBuffer;
}
}
/* Get the tag length if it has an implicit length */
if( !tagLength )
tagLength = extractTagLen( tagID );
/* Write the data associated with the tag */
while( i < tagLength )
fputByte( dataBuffer[ i++ ] );
return( TAGSIZE + tagLength );
}
WORD writeDirTag( WORD tagID, WORD tagLength, BYTE *dataBuffer )
{
int i = 0;
/* Write the tag itself */
tagID |= tagLength;
fputDirWord( tagID );
/* Get the tag length if it has an implicit length */
if( !tagLength )
tagLength = extractTagLen( tagID );
/* Write the data associated with the tag */
while( i < tagLength )
fputDirByte( dataBuffer[ i++ ] );
return( TAGSIZE + tagLength );
}
#endif /* 0 */