Fix WINNT build.
[debian-nspark.git] / io.c
blob5283c54a74335ca2eabf503a9d66d655e9593139
2 /*
3 * file input/output
5 * $Header: io.c 1.14 95/08/01 $
6 * $Log: io.c,v $
7 * Revision 1.14 95/08/01 xx:xx:xx BB
8 * Fixed for Borland C/C++
10 * Revision 1.13 94/12/12 17:30:45 arb
11 * Added code for ArcFS outputsize checking
13 * Revision 1.12 93/08/20 12:31:20 arb
14 * Added code for ArcFS archive headers
16 * Revision 1.11 93/08/20 10:30:50 arb
17 * Added code for -C option to convert filenames to lowercase
19 * Revision 1.10 93/08/20 10:30:51 arb
20 * Changed read_header() to allow top-bit-set characters in RISCOS filenames
22 * Revision 1.9 93/03/05 14:44:02 arb
23 * Added <string.h> for RISCOS, needed for memset
25 * Revision 1.8 92/12/09 11:40:30 duplain
26 * Changed ret in check_stream() from type int. #ifdef'd out write_halfword()
27 * and write_word().
29 * Revision 1.7 92/12/07 17:18:25 duplain
30 * reformatted source.
32 * Revision 1.6 92/11/04 16:57:49 duplain
33 * Changed read_header() so it doesn't read the load/exec/attr fields if
34 * PC archive file.
36 * Revision 1.5 92/10/07 10:36:56 duplain
37 * Changed order of function so no need to include "io.h" (gcc
38 * complained on some platforms).
40 * Revision 1.4 92/10/05 11:01:07 duplain
41 * Recoded write_word() and write_halfword(). read_header() now clears the
42 * header structure prior to reading data into it.
44 * Revision 1.3 92/10/02 17:41:49 duplain
45 * Fixed read_header() so it returns immediately if comptype & 0x7f == 0.
47 * Revision 1.2 92/10/01 11:20:32 duplain
48 * Moved reading of STARTBYTE to unarc.c .
50 * Revision 1.1 92/09/29 18:02:19 duplain
51 * Initial revision
55 #include <stdio.h>
56 #include <ctype.h>
57 #include <string.h>
58 #include "spark.h"
59 #include "main.h"
60 #include "error.h"
61 #include "arcfs.h"
63 /* BB changed next line */
65 /* #ifdef RISCOS */
66 #if defined(RISCOS) || defined(__MSDOS__)
67 #include <string.h> /* for memset */
69 /* BB added next two lines */
70 #endif /* RISCOS || __MSDOS__ */
71 #ifdef RISCOS /* next line RISC OS only */
72 #define isascii(x) 1
73 #endif /* RISCOS */
75 #include "nsparkio.h"
79 * check for EOF or write/read errors on stream.
81 Ferror
82 check_stream(FILE *fp)
84 Ferror ret = FNOERR;
86 if (feof(fp))
87 ret = FEND;
88 else if (ferror(fp))
89 ret = FRWERR;
90 if (ret != FNOERR)
91 clearerr(fp);
92 return (ret);
96 * read a byte from the input stream.
98 Byte
99 read_byte(FILE *ifp)
101 return ((Byte) getc(ifp));
105 * read a little-endian 2-byte halfword from the input stream.
107 Halfword
108 read_halfword(FILE *ifp)
110 union
112 Halfword h;
113 Byte b[sizeof(Halfword)];
115 ret;
117 if (fread((char *) &ret.h, 1, sizeof(Halfword), ifp)!=sizeof(Halfword)) {
118 error("Read error!");
120 #if defined(__MSDOS__)
121 /* MSDOS reads bytes in the correct order. Save a bit of time
122 * by returning the value */
123 return (ret.h);
124 #else
125 /* Ensure the data is in the correct order */
126 return (ret.b[0] | ret.b[1] << 8);
127 #endif
131 * read a little-endian 4-byte word from the input stream.
133 Word
134 read_word(FILE *ifp)
136 union
138 Word w;
139 Byte b[sizeof(Word)];
141 ret;
143 if (fread((char *) &ret.w, 1, sizeof(Word), ifp)!=sizeof(Word)) {
144 error("Read error!");
146 #if defined(__MSDOS__)
147 /* MSDOS reads bytes in the correct order. Save a bit of time
148 * by returning the value */
149 return (ret.w);
150 #else
151 /* Ensure the data is in the correct order */
152 return (ret.b[0] | (ret.b[1] << 8) | (ret.b[2] << 16) | (ret.b[3] << 24));
153 #endif
157 * write a byte to the output stream.
159 void
160 write_byte(FILE *ofp, Byte byte)
162 if (writesize-- > 0)
163 putc((int) byte, ofp);
166 #ifdef notyet
169 * write a little-endian 2-byte halfword to the output stream.
171 void
172 write_halfword(FILE *ofp, Halfword halfword)
174 write_byte(ofp, halfword & 0xff);
175 write_byte(ofp, (halfword >> 8) & 0xff);
179 * write a little-endian 4-byte word to the output stream.
181 void
182 write_word(FILE *ofp, Word word)
184 write_byte(ofp, word & 0xff);
185 write_byte(ofp, (word >> 8) & 0xff);
186 write_byte(ofp, (word >> 16) & 0xff);
187 write_byte(ofp, (word >> 24) & 0xff);
190 #endif /* notyet */
193 * read a compression-header from the file
195 Header *
196 read_header(FILE *ifp)
198 static Header header;
199 register int i;
200 register char *cptr;
201 Byte byte;
203 memset((char *) &header, '\0', sizeof(header));
205 if (arcfs)
206 return (arcfs_read_header(ifp));
208 header.comptype = read_byte(ifp);
209 if (!(header.comptype & ~ARCHPACK))
210 return (&header); /* EOF */
212 for (i = 0, cptr = header.name; i <= 12; i++, cptr++)
214 byte = read_byte(ifp);
215 #ifdef RISCOS
216 if (byte < ' ')
217 #else
218 if (byte < ' ' || byte > '~')
219 #endif
220 byte = '\0';
221 else if (byte == PATHSEP) /* illegal in filename */
222 byte = '_';
223 *cptr = byte;
225 *cptr = '\0'; /* null terminate */
226 if (singlecase)
228 for (i = 0, cptr = header.name; i <= 12; i++, cptr++)
229 if (isascii(*cptr) && isupper(*cptr))
230 *cptr = tolower(*cptr);
233 header.complen = read_word(ifp);
234 header.date = read_halfword(ifp);
235 header.time = read_halfword(ifp);
236 header.crc = read_halfword(ifp);
237 if ((header.comptype & ~ARCHPACK) > CT_NOTCOMP)
238 header.origlen = read_word(ifp);
239 else
240 header.origlen = header.complen;
241 if (header.comptype & ARCHPACK)
243 header.load = read_word(ifp);
244 header.exec = read_word(ifp);
245 header.attr = read_word(ifp);
248 if (check_stream(ifp) == FRWERR)
249 return (NULL);
250 return (&header);