
/*
 *
 *    zooarc.c ©1995 by Matthias Meixner
 *
 *
 */


/*****************************************
 *
 *    zoo-header
 *
 *****************************************/

#ifndef __ZOOARC_H
#define __ZOOARC_H

#define MWDEBUG 0

#if MWDEBUG
#include <sc:extras/MemLib/memwatch.h>
#endif

#include <exec/types.h>

struct zoo_header {
   BYTE text[20];     /* archive header text */
   ULONG zoo_tag;     /* identifies archives */
   LONG zoo_start;    /* where the archive's data starts */
   LONG zoo_minus;    /* for consistency checking of zoo_start */
   UBYTE major_ver;
   UBYTE minor_ver;   /* minimum version to extract all files   */
   UBYTE type;        /* type of archive header */
   LONG acmt_pos;     /* position of archive comment */
   USHORT acmt_len;   /* length of archive comment */
   UBYTE  vdata;      /* byte in archive;   data about versions */
};


#define   HeadOffset_text        0     /* text in header */
#define   HeadOffset_too_tag     20    /* zoo tag */
#define   HeadOffset_zoo_start   24    /* start offset */
#define   HeadOffset_zoo_minus   28    /* negative of start offset */
#define   HeadOffset_major_ver   32    /* major version */
#define   HeadOffset_minor_ver   33    /* minor version */
#define   HeadOffset_type        34    /* archive header type */
#define   HeadOffset_acmt_pos    35    /* position of archive comment */
#define   HeadOffset_acmt_len    39    /* length of archive comment */
#define   HeadOffset_vdata       41    /* version data */


#define HEADER_SIZE      42
#define SMALLHEADER_SIZE 34
#define HEADER_CONVTAB(var) char var[]={20,-4,-4,-4,3,-4,-2,1,0}
#define ZOO_TAG 0xFDC4A7DCUL /* A random choice */

#define PRINTHEAD(h) \
      printf("struct zoo_head {\n"\
             "   char text[20]   : %s\n"\
             "   ULONG zoo_tag   : %x\n"\
             "   LONG zoo_start  : %d\n"\
             "   LONG zoo_minus  : %d\n"\
             "   UBYTE major_ver : %d\n"\
             "   UBYTE minor_ver : %d\n"\
             "   UBYTE type      : %x\n"\
             "   LONG acmt_pos   : %x\n"\
             "   USHORT acmt_len : %d\n"\
             "   UBYTE  vdata    : %x\n"\
             "};\n",\
            (h).text,(h).zoo_tag,(h).zoo_start,(h).zoo_minus,\
            (h).major_ver,(h).minor_ver,(h).type,(h).acmt_pos,\
            (h).acmt_len,(h).vdata)


/*****************************************
 *
 *    file-entry
 *
 *****************************************/


struct direntry {
   ULONG zoo_tag;        /* tag -- redundancy check */
   UBYTE type;           /* type of directory entry.   always 1 for now */
   UBYTE packing_method; /* 0 = no packing, 1 = normal LZW */
   LONG next;            /* pos'n of next directory entry */
   LONG offset;          /* position of this file */
   USHORT date;          /* DOS format date */
   USHORT time;          /* DOS format time */
   USHORT file_crc;      /* CRC of this file */
   LONG org_size;
   LONG size_now;
   UBYTE major_ver;
   UBYTE minor_ver;      /* minimum version needed to extract */
   UBYTE deleted;        /* will be 1 if deleted, 0 if not */
   UBYTE struc;          /* file structure if any */
   LONG comment;         /* points to comment;  zero if none */
   USHORT cmt_size;      /* length of comment, 0 if none */
   BYTE fname[13];       /* filename */

   short var_dir_len;    /* length of variable part of dir entry */
   UBYTE tz;             /* timezone where file was archived */
   USHORT dir_crc;       /* CRC of directory entry */

   /* fields for variable part of directory entry follow */

   UBYTE namlen;         /* length of long filename */
   UBYTE dirlen;         /* length of directory name */
   BYTE lfname[256];     /* long filename */
   BYTE dirname[256];    /* directory name */
   USHORT system_id;     /* Filesystem ID */
   ULONG fattr;          /* File attributes -- 24 bits */
   UBYTE vflag;          /* version flag bits -- one byte in archive */
   USHORT version_no;    /* file version number if any */
};


#define DIRENT_CONVTAB1(var) char var[]={-4,2,-4,-4,-2,-2,-2,-4,-4,4,-4,-2,13,\
                                         -2,1,-2,2,0}
#define DIRENT_CONVTAB2(var) char var[]={-2,-3,1,-2,0}

#define DIRENTSIZE_TYPE1 51  /* length of type 1 directory entry */
#define DIRENTSIZE_TYPE2 56  /* length of type 2 directory entry */


#define   DirOffset_zoo_tag         0   /* tag within directory entry */
#define   DirOffset_type            4   /* type of directory entry */
#define   DirOffset_packing_method  5   /* packing method */
#define   DirOffset_next            6   /* pos'n of next directory entry */
#define   DirOffset_offset         10   /* position (offset) of this file */
#define   DirOffset_date           14   /* DOS format date */
#define   DirOffset_time           16   /* DOS format time */
#define   DirOffset_file_crc       18   /* CRC of this file */
#define   DirOffset_org_size       20   /* original size */
#define   DirOffset_size_now       24   /* size now */
#define   DirOffset_major_ver      28   /* major version number */
#define   DirOffset_minor_ver      29   /* minor version number */
#define   DirOffset_deleted        30   /* deleted or not */
#define   DirOffset_struc          31   /* file structure */
#define   DirOffset_comment        32   /* comment [offset] */
#define   DirOffset_cmt_size       36   /* comment size */
#define   DirOffset_fname          38   /* filename */

/*********************  Type 2  ***************************/
#define   DirOffset_var_dir_len    51   /* length of var. direntry */
#define   DirOffset_tz             53   /* timezone */
#define   DirOffset_dir_crc        54   /* CRC of directory entry */

/* Offsets within variable part of directory entry */
#define   DirOffset_namlen         56
#define   DirOffset_dirlen         57
#define   DirOffset_lfname         58


/* Value used to stuff into timezone field if it is not known */
#define   NO_TZ    127

/* Value for no file attributes */
#define   NO_FATTR    0L

/* version flag bits */
#define   VFL_ON   0x80      /* enable version numbering */
#define   VFL_GEN   0x0f      /* generation count */
#define   VFL_LAST 0x40      /* last generation of this file */

/* default generation value for archive */
#define   GEN_DEFAULT       3
/* max generation count, file or archive */
#define   MAXGEN            0x0f
/* version mask to prune down to correct size on large-word machines */
#define VER_MASK            0xffff


#define MAXDIRENT_SIZE (sizeof(struct direntry)-3)


#define PRINT_DIRENT(h) \
   printf("struct direntry {\n"\
          "   ULONG zoo_tag;        :%x\n"\
          "   UBYTE type;           :%d\n"\
          "   UBYTE packing_method; :%d\n"\
          "   LONG next;            :%d\n"\
          "   LONG offset;          :%d\n"\
          "   USHORT date;          :%x\n"\
          "   USHORT time;          :%x\n"\
          "   USHORT file_crc;      :%x\n"\
          "   LONG org_size;        :%d\n"\
          "   LONG size_now;        :%d\n"\
          "   UBYTE major_ver;      :%d\n"\
          "   UBYTE minor_ver;      :%d\n"\
          "   UBYTE deleted;        :%d\n"\
          "   UBYTE struc;          :%d\n"\
          "   LONG comment;         :%d\n"\
          "   USHORT cmt_size;      :%d\n"\
          "   BYTE fname[13];       :%s\n"\
          "\n"\
          "   short var_dir_len;    :%d\n"\
          "   UBYTE tz;             :%d\n"\
          "   USHORT dir_crc;       :%d\n"\
          "\n"\
          "   /* fields for variable part of directory entry follow */\n"\
          "\n"\
          "   UBYTE namlen;         :%d\n"\
          "   UBYTE dirlen;         :%d\n"\
          "   BYTE lfname[256];     :%s\n"\
          "   BYTE dirname[256];    :%s\n"\
          "   USHORT system_id;     :%d\n"\
          "   ULONG fattr;          :%x\n"\
          "   UBYTE vflag;          :%x\n"\
          "   USHORT version_no;    :%d\n"\
          "};\n",\
          (h).zoo_tag,(h).type,(h).packing_method,(h).next,(h).offset,\
          (h).date,(h).time,(h).file_crc,(h).org_size,(h).size_now,\
          (h).major_ver,(h).minor_ver,(h).deleted,(h).struc,(h).comment,\
          (h).cmt_size,(h).fname,(h).var_dir_len,(h).tz,(h).dir_crc,\
          (h).namlen,(h).dirlen,(h).lfname,(h).dirname,(h).system_id,\
          (h).fattr,(h).vflag,(h).version_no)


/* Values for direntry.system_id */
#define SYSID_NIX        0      /* UNIX and similar filesystems */
#define SYSID_MS         1      /* MS-DOS filesystem */
#define SYSID_PORTABLE   2      /* Portable syntax */

#ifndef TESTONLY

#include <libraries/xpkarchivesub.h>

struct ZooLock {
   struct XarSubLock Lock;
   LONG DirentPos,DataPos;
   LONG DirentSize;
   SHORT Method;                      /* Packing method */
   BYTE GFlag;
};

void Error(long);

extern FILE *arcfile;

long lzd(struct XarSubIO *);
int lzc(struct XarSubIO *);

void free_lzc(void);
void free_lzd(void);

#endif

#endif
