5 * $Header: io.c 1.14 95/08/01 $
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()
29 * Revision 1.7 92/12/07 17:18:25 duplain
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
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
63 /* BB changed next line */
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 */
79 * check for EOF or write/read errors on stream.
82 check_stream(FILE *fp
)
96 * read a byte from the input stream.
101 return ((Byte
) getc(ifp
));
105 * read a little-endian 2-byte halfword from the input stream.
108 read_halfword(FILE *ifp
)
113 Byte b
[sizeof(Halfword
)];
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 */
125 /* Ensure the data is in the correct order */
126 return (ret
.b
[0] | ret
.b
[1] << 8);
131 * read a little-endian 4-byte word from the input stream.
139 Byte b
[sizeof(Word
)];
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 */
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));
157 * write a byte to the output stream.
160 write_byte(FILE *ofp
, Byte byte
)
163 putc((int) byte
, ofp
);
169 * write a little-endian 2-byte halfword to the output stream.
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.
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);
193 * read a compression-header from the file
196 read_header(FILE *ifp
)
198 static Header header
;
203 memset((char *) &header
, '\0', sizeof(header
));
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
);
218 if (byte
< ' ' || byte
> '~')
221 else if (byte
== PATHSEP
) /* illegal in filename */
225 *cptr
= '\0'; /* null terminate */
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
);
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
)
255 read_sqsh_header(FILE *fp
, SqshHeader
*header
)
257 if (fread(header
->magic
, 1, 4, fp
) != 4)
261 if (strncmp(header
->magic
, "SQSH", 4) != 0)
263 error("Not a RISC OS squash file");
266 header
->origlen
= read_word(fp
);
267 header
->load
= read_word(fp
);
268 header
->exec
= read_word(fp
);
269 header
->reserved
= read_word(fp
);
275 sqsh_header_to_header(SqshHeader
*sqsh_header
, Header
*header
)
277 header
->load
= sqsh_header
->load
;
278 header
->exec
= sqsh_header
->exec
;
279 header
->origlen
= sqsh_header
->origlen
;
280 arcfs_fixtime(header
);