/* UNARJ.H, UNARJ, R JUNG, 05/30/91
 * Include file
 * Copyright (c) 1990 by Robert K Jung.  All rights reserved.
 *
 *   This code may be freely used in programs that are NOT archivers.
 *
 *   If you wish to distribute a modified version of this program, you
 *   must include the source code.
 *
 *   If you modify this program, I would appreciate a copy of the new
 *   source code.  I am holding the copyright on the source code, so
 *   please do not delete my name from the program files or from the
 *   documentation.
 *
 * Modification history:
 * Date      Programmer  Description of modification.
 * 04/05/91  R. Jung	 Rewrote code.
 * 04/23/91  M. Adler	 Portabilized.
 * 04/29/91  R. Jung	 Added volume label support.
 * 05/30/91  R. Jung	 Added SEEK_END definition.
 *
 */

#ifndef _ARH_DEF_
#define _ARH_DEF_

/* Use prototypes and ANSI libraries if __STDC__ */
#ifdef __STDC__
#  define MODERN
#endif /* __STDC__ */

/* Use prototypes and ANSI libraries if __TURBOC__ */
#ifdef __TURBOC__
#  define MODERN
#endif /* __TURBOC__ */

/* Use prototypes and ANSI libraries if _QC */
#ifdef _QC
#  define MODERN
#endif /* __TURBOC__ */

/* Use prototypes and ANSI libraries if _OS2 */
#ifdef _OS2
#  define MODERN
#endif /* _OS2 */

/* Used to remove arguments in function prototypes for non-ANSI C */
#ifdef MODERN
#  define OF(a) a
#else /* !MODERN */
#  define OF(a) ()
#endif /* ?MODERN */

#ifdef MODERN
   typedef void voidp;
#else /* !MODERN */
#  define void int
   typedef char voidp;
#endif /* ?MODERN */

#include <stdio.h>
#ifdef MODERN
#  include <limits.h>
#else /* !MODERN */
#  ifndef UCHAR_MAX
#    define UCHAR_MAX (255)
#  endif
#  ifndef CHAR_BIT
#    define CHAR_BIT  (8)
#  endif
#  ifndef LONG_MAX
#    define LONG_MAX  (0x7FFFFFFFL)
#  endif
#endif /* ?MODERN */

#ifndef SEEK_SET
#  define SEEK_SET 0
#endif

#ifndef SEEK_CUR
#  define SEEK_CUR 1
#endif

#ifndef SEEK_END
#  define SEEK_END 2
#endif

typedef unsigned char  uchar;	/*  8 bits or more */
typedef unsigned int   uint;	/* 16 - 32 bits or more */
typedef unsigned short ushort;	/* 16 bits or more */
typedef unsigned long  ulong;	/* 32 bits or more */

#define USHRT_BIT   (CHAR_BIT * sizeof(ushort))

/* ********************************************************* */
/* Environment definitions (implementation dependent)	     */
/* ********************************************************* */

#ifdef _QC
#define __MSDOS__
#endif

#ifdef __MSDOS__
#define OS		    0
#define PATH_SEPARATORS     "\\:"
#define PATH_CHAR	    '\\'
#define MAXSFX		    25000L
#define ARJ_SUFFIX	    ".ARJ"
#endif

#ifdef _OS2
#define OS		    0		/* ??? */
#define PATH_SEPARATORS     "\\:"
#define PATH_CHAR	    '\\'
#define SWITCH_CHARS	    "-/"
#define MAXSFX		    25000L
#define ARJ_SUFFIX	    ".ARJ"
#endif

#ifdef __CI
#define PRIME		    1
#define OS		    1
#define PATH_SEPARATORS     ">"
#define PATH_CHAR	    '>'
#define FIX_PARITY(c)	    c |= ~ASCII_MASK
#define DEFAULT_DIR	    "*>"
#define ARJ_SUFFIX	    ".ARJ"
#endif

/* Error levels */

#ifndef ERROR_DEFINES

#define ERROR_OK	0	/* success */
#define ERROR_WARN	1	/* minor problem (file not found) */
#define ERROR_FAIL	2	/* fatal error */
#define ERROR_CRC	3	/* CRC error */
#define ERROR_SECURE	4	/* ARJ security invalid or not found */
#define ERROR_WRITE	5	/* disk full */
#define ERROR_OPEN	6	/* can't open file */
#define ERROR_USER	7	/* user specified bad parameters */
#define ERROR_MEMORY	8	/* not enough memory */

#endif

#ifndef MAXSFX		    /* size of self-extracting prefix */
#define MAXSFX		    500000L
#endif
#ifndef FNAME_MAX
#define FNAME_MAX	    512
#endif
#ifndef SWITCH_CHARS
#define SWITCH_CHARS	    "-"
#endif
#ifndef FIX_PARITY
#define FIX_PARITY(c)	    c &= ASCII_MASK
#endif
#ifndef ARJ_SUFFIX
#define ARJ_SUFFIX	    ".arj"
#endif
#ifndef ARJ_DOT
#define ARJ_DOT 	    '.'
#endif
#ifndef DEFAULT_DIR
#define DEFAULT_DIR	    ""
#endif
#ifndef OS
#define OS		    2
#endif
#ifndef PATH_SEPARATORS
#define PATH_SEPARATORS     "/"
#endif
#ifndef PATH_CHAR
#define PATH_CHAR	    '/'
#endif

/* ********************************************************* */
/* end of environmental defines 			     */
/* ********************************************************* */

/* ********************************************************* */
/*
 * Structure of archive block (low order byte first):
 *
 *  2  header id (comment and local file) = 0xEA60 or 60000U
 *  2  basic header size (from 'first_hdr_size' thru 'comment' below)
 *	     = first_hdr_size + strlen(filename) + 1 + strlen(comment) + 1
 *	     = 0 if end of archive
 *
 *  1  first_hdr_size (size up to 'extra data')
 *  1  archiver version number
 *  1  minimum archiver version to extract
 *  1  host OS	 (0 = MSDOS, 1 = PRIMOS, 2 = UNIX, 3 = AMIGA, 4 = MACDOS)
 *  1  arj flags (0x01 = GARBLED_FLAG, 0x02 = RESERVED)
 *		 (0x04 = VOLUME_FLAG,  0x08 = EXTFILE_FLAG)
 *		 (0x10 = PATHSYM_FLAG)
 *  1  method	 (0 = stored, 1 = compressed most ... 4 compressed fastest)
 *  1  file type (0 = binary, 1 = text, 2 = comment header)
 *		 (3 = directory, 4 = volume label)
 *  1  reserved
 *  4  date time stamp modified
 *  4  compressed size
 *  4  original size
 *  4  original file's CRC
 *  2  entryname position in filename
 *  2  file access mode
 *  2  host data
 *  ?  extra data
 *     4 bytes for extended file position
 *
 *  ?  filename (null-terminated)
 *  ?  comment	(null-terminated)
 *
 *  4  basic header CRC
 *
 *  2  1st extended header size (0 if none)
 *  ?  1st extended header
 *  4  1st extended header's CRC (not present if 0 extended header size)
 *  ...
 *  ?  compressed file
 *
 * ********************************************************* */

/* ********************************************************* */
/*							     */
/*     Time stamp format:				     */
/*							     */
/*	31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16      */
/*     |<---- year-1980 --->|<- month ->|<--- day ---->|     */
/*							     */
/*	15 14 13 12 11 10  9  8  7  6  5  4  3	2  1  0      */
/*     |<--- hour --->|<---- minute --->|<- second/2 ->|     */
/*							     */
/* ********************************************************* */

#define CODE_BIT	  16

#define NULL_CHAR	'\0'
#define MAXMETHOD	   4

#define ARJ_VERSION	   3
#define ARJ_X_VERSION	   3	/* decoder version */
#define ARJ_X1_VERSION	   1
#define DEFAULT_METHOD	   1
#define DEFAULT_TYPE	   0	/* if type_sw is selected */
#define HEADER_ID     0xEA60
#define HEADER_ID_HI	0xEA
#define HEADER_ID_LO	0x60
#define FIRST_HDR_SIZE	  30
#define FIRST_HDR_SIZE_V  34
#define COMMENT_MAX	2048
#define HEADERSIZE_MAX	 (FIRST_HDR_SIZE + 10 + FNAME_MAX + COMMENT_MAX)
#define BINARY_TYPE	   0	/* This must line up with binary/text strings */
#define TEXT_TYPE	   1
#define COMMENT_TYPE	   2
#define DIR_TYPE	   3
#define LABEL_TYPE	   4

#define GARBLE_FLAG	0x01
#define VOLUME_FLAG	0x04
#define EXTFILE_FLAG	0x08
#define PATHSYM_FLAG	0x10

typedef ulong UCRC;	/* CRC-32 */

#define CRC_MASK	0xFFFFFFFFL

#define ARJ_PATH_CHAR	'/'

#define FA_RDONLY	0x01		/* Read only attribute */
#define FA_HIDDEN	0x02		/* Hidden file */
#define FA_SYSTEM	0x04		/* System file */
#define FA_LABEL	0x08		/* Volume label */
#define FA_DIREC	0x10		/* Directory */
#define FA_ARCH 	0x20		/* Archive */

#define HOST_OS_NAMES  { "MS-DOS","PRIMOS","UNIX","AMIGA","MAC-OS",NULL }

/* Timestamp macros */

#define get_tx(m,d,h,n) (((ulong)m<<21)+((ulong)d<<16)+((ulong)h<<11)+(n<<5))
#define get_tstamp(y,m,d,h,n,s) ((((ulong)(y-1980))<<25)+get_tx(m,d,h,n)+(s/2))

#define ts_year(ts)  ((uint)((ts >> 25) & 0x7f) + 1980)
#define ts_month(ts) ((uint)(ts >> 21) & 0x0f)	    /* 1..12 means Jan..Dec */
#define ts_day(ts)   ((uint)(ts >> 16) & 0x1f)	    /* 1..31 means 1st..31st */
#define ts_hour(ts)  ((uint)(ts >> 11) & 0x1f)
#define ts_min(ts)   ((uint)(ts >> 5) & 0x3f)
#define ts_sec(ts)   ((uint)((ts & 0x1f) * 2))

/* unarj.c */

extern long origsize;
extern long compsize;

extern UCRC crc;

extern FILE *arcfile;
extern FILE *outfile;

extern ushort bitbuf;

extern uchar subbitbuf;
extern uchar header[HEADERSIZE_MAX];

extern char arc_name[FNAME_MAX];

extern int bitcount;
extern int file_type;
extern int error_count;

/* Global functions */

/* unarj.c */

void   strupper OF((char *str));
voidp  *malloc_msg OF((int size));
void   disp_clock OF((void));
void   error OF((char *fmt, char *arg));
void   fillbuf OF((int n));
ushort getbits OF((int n));
void   fwrite_txt_crc OF((uchar *p, int n));
void   init_getbits OF((void));

/* environ.c */

FILE   *file_open OF((char *name, char *mode));
int    file_read OF((char *buf, int size, int nitems, FILE *stream));
int    file_seek OF((FILE *stream, long offset, int mode));
long   file_tell OF((FILE *stream));
int    file_write OF((char *buf, int size, int nitems, FILE *stream));
voidp  *xmalloc OF((int size));
void   case_path OF((char *name));
int    file_exists OF((char *name));
void   get_mode_str OF((char *str, ushort fmode));
int    set_ftime_mode OF((char *name, ulong timestamp, uint fmode, uchar host));

/* decode.c */

void	decode OF((void));
void	decode_f OF((void));

/* Message strings */

extern char M_VERSION [];

extern char M_ARCDATE [];
extern char M_BADCOMND[];
extern char M_BADCOMNT[];
extern char M_BADHEADR[];
extern char M_BADTABLE[];
extern char M_CANTOPEN[];
extern char M_CANTREAD[];
extern char M_CANTWRIT[];
extern char M_CRCERROR[];
extern char M_CRCOK   [];
extern char M_DIFFHOST[];
extern char M_ENCRYPT [];
extern char M_ERRORCNT[];
extern char M_EXTRACT [];
extern char M_FEXISTS [];
extern char M_HEADRCRC[];
extern char M_NBRFILES[];
extern char M_NOMEMORY[];
extern char M_NOTARJ  [];
extern char M_PROCARC [];
extern char M_SKIPPED [];
extern char M_SUFFIX  [];
extern char M_TESTING [];
extern char M_UNKNMETH[];
extern char M_UNKNTYPE[];
extern char M_UNKNVERS[];

#endif

/* end UNARJ.H */
