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 #ifdef RISCOS /* next line RISC OS only */
71 * check for EOF or write/read errors on stream.
74 check_stream(FILE *fp
)
88 * read a byte from the input stream.
93 return ((Byte
) getc(ifp
));
97 * read a little-endian 2-byte halfword from the input stream.
100 read_halfword(FILE *ifp
)
105 Byte b
[sizeof(Halfword
)];
109 if (fread((char *) &ret
.h
, 1, sizeof(Halfword
), ifp
)!=sizeof(Halfword
)) {
110 error("Read error!");
112 #if defined(__MSDOS__)
113 /* MSDOS reads bytes in the correct order. Save a bit of time
114 * by returning the value */
117 /* Ensure the data is in the correct order */
118 return (ret
.b
[0] | ret
.b
[1] << 8);
123 * read a little-endian 4-byte word from the input stream.
131 Byte b
[sizeof(Word
)];
135 if (fread((char *) &ret
.w
, 1, sizeof(Word
), ifp
)!=sizeof(Word
)) {
136 error("Read error!");
138 #if defined(__MSDOS__)
139 /* MSDOS reads bytes in the correct order. Save a bit of time
140 * by returning the value */
143 /* Ensure the data is in the correct order */
144 return (ret
.b
[0] | (ret
.b
[1] << 8) | (ret
.b
[2] << 16) | (ret
.b
[3] << 24));
149 * write a byte to the output stream.
152 write_byte(FILE *ofp
, Byte byte
)
155 putc((int) byte
, ofp
);
161 * write a little-endian 2-byte halfword to the output stream.
164 write_halfword(FILE *ofp
, Halfword halfword
)
166 write_byte(ofp
, halfword
& 0xff);
167 write_byte(ofp
, (halfword
>> 8) & 0xff);
171 * write a little-endian 4-byte word to the output stream.
174 write_word(FILE *ofp
, Word word
)
176 write_byte(ofp
, word
& 0xff);
177 write_byte(ofp
, (word
>> 8) & 0xff);
178 write_byte(ofp
, (word
>> 16) & 0xff);
179 write_byte(ofp
, (word
>> 24) & 0xff);
185 * read a compression-header from the file
188 read_header(FILE *ifp
)
190 static Header header
;
195 memset((char *) &header
, '\0', sizeof(header
));
198 return (arcfs_read_header(ifp
));
200 header
.comptype
= read_byte(ifp
);
201 if (!(header
.comptype
& ~ARCHPACK
))
202 return (&header
); /* EOF */
204 for (i
= 0, cptr
= header
.name
; i
<= 12; i
++, cptr
++)
206 byte
= read_byte(ifp
);
210 if (byte
< ' ' || byte
> '~')
213 else if (byte
== PATHSEP
) /* illegal in filename */
217 *cptr
= '\0'; /* null terminate */
220 for (i
= 0, cptr
= header
.name
; i
<= 12; i
++, cptr
++)
221 if (isascii(*cptr
) && isupper(*cptr
))
222 *cptr
= tolower(*cptr
);
225 header
.complen
= read_word(ifp
);
226 header
.date
= read_halfword(ifp
);
227 header
.time
= read_halfword(ifp
);
228 header
.crc
= read_halfword(ifp
);
229 if ((header
.comptype
& ~ARCHPACK
) > CT_NOTCOMP
)
230 header
.origlen
= read_word(ifp
);
232 header
.origlen
= header
.complen
;
233 if (header
.comptype
& ARCHPACK
)
235 header
.load
= read_word(ifp
);
236 header
.exec
= read_word(ifp
);
237 header
.attr
= read_word(ifp
);
240 if (check_stream(ifp
) == FRWERR
)
246 read_sqsh_header(FILE *fp
, SqshHeader
*header
)
248 if (fread(header
->magic
, 1, 4, fp
) != 4)
252 if (strncmp(header
->magic
, "SQSH", 4) != 0)
254 error("Not a RISC OS squash file");
257 header
->origlen
= read_word(fp
);
258 header
->load
= read_word(fp
);
259 header
->exec
= read_word(fp
);
260 header
->reserved
= read_word(fp
);
266 sqsh_header_to_header(SqshHeader
*sqsh_header
, Header
*header
)
268 header
->load
= sqsh_header
->load
;
269 header
->exec
= sqsh_header
->exec
;
270 header
->origlen
= sqsh_header
->origlen
;
271 arcfs_fixtime(header
);