home *** CD-ROM | disk | FTP | other *** search
- /*
- * file input/output
- *
- * $Header: io.c 1.13 94/12/12 $
- * $Log: io.c,v $
- * Revision 1.13 94/12/12 17:30:45 arb
- * Added code for ArcFS outputsize checking
- *
- * Revision 1.12 93/08/20 12:31:20 arb
- * Added code for ArcFS archive headers
- *
- * Revision 1.11 93/08/20 10:30:50 arb
- * Added code for -C option to convert filenames to lowercase
- *
- * Revision 1.10 93/08/20 10:30:51 arb
- * Changed read_header() to allow top-bit-set characters in RISCOS filenames
- *
- * Revision 1.9 93/03/05 14:44:02 arb
- * Added <string.h> for RISCOS, needed for memset
- *
- * Revision 1.8 92/12/09 11:40:30 duplain
- * Changed ret in check_stream() from type int. #ifdef'd out write_halfword()
- * and write_word().
- *
- * Revision 1.7 92/12/07 17:18:25 duplain
- * reformatted source.
- *
- * Revision 1.6 92/11/04 16:57:49 duplain
- * Changed read_header() so it doesn't read the load/exec/attr fields if
- * PC archive file.
- *
- * Revision 1.5 92/10/07 10:36:56 duplain
- * Changed order of function so no need to include "io.h" (gcc
- * complained on some platforms).
- *
- * Revision 1.4 92/10/05 11:01:07 duplain
- * Recoded write_word() and write_halfword(). read_header() now clears the
- * header structure prior to reading data into it.
- *
- * Revision 1.3 92/10/02 17:41:49 duplain
- * Fixed read_header() so it returns immediately if comptype & 0x7f == 0.
- *
- * Revision 1.2 92/10/01 11:20:32 duplain
- * Moved reading of STARTBYTE to unarc.c .
- *
- * Revision 1.1 92/09/29 18:02:19 duplain
- * Initial revision
- *
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include "spark.h"
- #include "main.h"
- #include "error.h"
- #include "arcfs.h"
- #ifdef UNIX
- #include "endian.h"
- #endif /* UNIX */
- #ifdef RISCOS
- #include <string.h> /* for memset */
- #define isascii(x) 1
- #endif /* RISCOS */
-
- #ifdef UNIX
- static char rcsid[] = "$Header: io.c 1.13 94/12/12 $";
- #endif /* UNIX */
-
- /*
- * check for EOF or write/read errors on stream.
- */
- Ferror
- check_stream(fp)
- FILE *fp;
- {
- Ferror ret = FNOERR;
-
- if (feof(fp))
- ret = FEND;
- else if (ferror(fp))
- ret = FRWERR;
- if (ret != FNOERR)
- clearerr(fp);
- return (ret);
- }
-
- /*
- * read a byte from the input stream.
- */
- Byte
- read_byte(ifp)
- FILE *ifp;
- {
- return ((Byte)getc(ifp));
- }
-
- /*
- * read a little-endian 2-byte halfword from the input stream.
- */
- Halfword
- read_halfword(ifp)
- FILE *ifp;
- {
- union {
- Halfword h;
- Byte b[sizeof(Halfword)];
- } ret;
-
- #if defined(LITTLE_ENDIAN)
- fread((char *)&ret.h, 1, sizeof(Halfword), ifp);
- #else
- ret.b[HALFWORD0] = read_byte(ifp);
- ret.b[HALFWORD1] = read_byte(ifp);
- #endif
- return (ret.h);
- }
-
- /*
- * read a little-endian 4-byte word from the input stream.
- */
- Word
- read_word(ifp)
- FILE *ifp;
- {
- union {
- Word w;
- Byte b[sizeof(Word)];
- } ret;
-
- #if defined(LITTLE_ENDIAN)
- fread((char *)&ret.w, 1, sizeof(Word), ifp);
- #else
- ret.b[WORD0] = read_byte(ifp);
- ret.b[WORD1] = read_byte(ifp);
- ret.b[WORD2] = read_byte(ifp);
- ret.b[WORD3] = read_byte(ifp);
- #endif
- return (ret.w);
- }
-
- /*
- * write a byte to the output stream.
- */
- void
- write_byte(ofp, byte)
- FILE *ofp;
- Byte byte;
- {
- if (writesize-- > 0)
- putc((int)byte, ofp);
- }
-
- #ifdef notyet
-
- /*
- * write a little-endian 2-byte halfword to the output stream.
- */
- void
- write_halfword(ofp, halfword)
- FILE *ofp;
- Halfword halfword;
- {
- union {
- Halfword h;
- Byte b[sizeof(Halfword)];
- } un;
-
- un.h = halfword;
-
- #if defined(LITTLE_ENDIAN)
- fwrite((char *)&un.h, 1, sizeof(Halfword), ofp);
- #else
- write_byte(ofp, un.b[HALFWORD0]);
- write_byte(ofp, un.b[HALFWORD1]);
- #endif
- }
-
- /*
- * write a little-endian 4-byte word to the output stream.
- */
- void
- write_word(ofp, word)
- FILE *ofp;
- Word word;
- {
- union {
- Word w;
- Byte b[sizeof(Word)];
- } un;
-
- un.w = word;
-
- #if defined(LITTLE_ENDIAN)
- fwrite((char *)&un.w, 1, sizeof(Word), ofp);
- #else
- write_byte(ofp, un.b[WORD0]);
- write_byte(ofp, un.b[WORD1]);
- write_byte(ofp, un.b[WORD2]);
- write_byte(ofp, un.b[WORD3]);
- #endif
- }
-
- #endif /* notyet */
-
- /*
- * read a compression-header from the file
- */
- Header *
- read_header(ifp)
- FILE *ifp;
- {
- static Header header;
- register i;
- register char *cptr;
- Byte byte;
-
- #ifdef BSD
- bzero((char *)&header, sizeof(header));
- #else /* not BSD */
- memset((char *)&header, '\0', sizeof(header));
- #endif /* BSD */
-
- if (arcfs)
- return(arcfs_read_header(ifp));
-
- header.comptype = read_byte(ifp);
- if (!(header.comptype & ~ARCHPACK))
- return (&header); /* EOF */
-
- for (i = 0, cptr = header.name; i <= 12; i++, cptr++) {
- byte = read_byte(ifp);
- #ifdef RISCOS
- if (byte < ' ')
- #else
- if (byte < ' ' || byte > '~')
- #endif
- byte = '\0';
- else if (byte == PATHSEP) /* illegal in filename */
- byte = '_';
- *cptr = byte;
- }
- *cptr = '\0'; /* null terminate */
- if (singlecase)
- {
- for (i = 0, cptr = header.name; i <= 12; i++, cptr++)
- if (isascii(*cptr) && isupper(*cptr)) *cptr = tolower(*cptr);
- }
-
- header.complen = read_word(ifp);
- header.date = read_halfword(ifp);
- header.time = read_halfword(ifp);
- header.crc = read_halfword(ifp);
- if ((header.comptype & ~ARCHPACK) > CT_NOTCOMP)
- header.origlen = read_word(ifp);
- else
- header.origlen = header.complen;
- if (header.comptype & ARCHPACK) {
- header.load = read_word(ifp);
- header.exec = read_word(ifp);
- header.attr = read_word(ifp);
- }
-
- if (check_stream(ifp) == FRWERR)
- return (NULL);
- return (&header);
- }
-