home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / disk / archive / nspark_1 / nspark-1.7.5 / io.c < prev    next >
C/C++ Source or Header  |  1994-12-12  |  5KB  |  267 lines

  1. /*
  2.  * file input/output
  3.  *
  4.  * $Header: io.c 1.13 94/12/12 $
  5.  * $Log:    io.c,v $
  6.  * Revision 1.13  94/12/12  17:30:45  arb
  7.  * Added code for ArcFS outputsize checking
  8.  *
  9.  * Revision 1.12  93/08/20  12:31:20  arb
  10.  * Added code for ArcFS archive headers
  11.  *
  12.  * Revision 1.11  93/08/20  10:30:50  arb
  13.  * Added code for -C option to convert filenames to lowercase
  14.  *
  15.  * Revision 1.10  93/08/20  10:30:51  arb
  16.  * Changed read_header() to allow top-bit-set characters in RISCOS filenames
  17.  *
  18.  * Revision 1.9  93/03/05  14:44:02  arb
  19.  * Added <string.h> for RISCOS, needed for memset
  20.  *
  21.  * Revision 1.8  92/12/09  11:40:30  duplain
  22.  * Changed ret in check_stream() from type int.  #ifdef'd out write_halfword()
  23.  * and write_word().
  24.  * 
  25.  * Revision 1.7  92/12/07  17:18:25  duplain
  26.  * reformatted source.
  27.  * 
  28.  * Revision 1.6  92/11/04  16:57:49  duplain
  29.  * Changed read_header() so it doesn't read the load/exec/attr fields if
  30.  * PC archive file.
  31.  * 
  32.  * Revision 1.5  92/10/07  10:36:56  duplain
  33.  * Changed order of function so no need to include "io.h" (gcc
  34.  * complained on some platforms).
  35.  * 
  36.  * Revision 1.4  92/10/05  11:01:07  duplain
  37.  * Recoded write_word() and write_halfword(). read_header() now clears the
  38.  * header structure prior to reading data into it.
  39.  * 
  40.  * Revision 1.3  92/10/02  17:41:49  duplain
  41.  * Fixed read_header() so it returns immediately if comptype & 0x7f == 0.
  42.  * 
  43.  * Revision 1.2  92/10/01  11:20:32  duplain
  44.  * Moved reading of STARTBYTE to unarc.c .
  45.  * 
  46.  * Revision 1.1  92/09/29  18:02:19  duplain
  47.  * Initial revision
  48.  * 
  49.  */
  50.  
  51. #include <stdio.h>
  52. #include <ctype.h>
  53. #include "spark.h"
  54. #include "main.h"
  55. #include "error.h"
  56. #include "arcfs.h"
  57. #ifdef UNIX
  58. #include "endian.h"
  59. #endif /* UNIX */
  60. #ifdef RISCOS
  61. #include <string.h>  /* for memset */
  62. #define isascii(x) 1
  63. #endif /* RISCOS */
  64.  
  65. #ifdef UNIX
  66. static char rcsid[] = "$Header: io.c 1.13 94/12/12 $";
  67. #endif /* UNIX */
  68.  
  69. /*
  70.  * check for EOF or write/read errors on stream.
  71.  */
  72. Ferror
  73. check_stream(fp)
  74.     FILE *fp;
  75. {
  76.     Ferror ret = FNOERR;
  77.  
  78.     if (feof(fp))
  79.     ret = FEND;
  80.     else if (ferror(fp))
  81.     ret = FRWERR;
  82.     if (ret != FNOERR)
  83.     clearerr(fp);
  84.     return (ret);
  85. }
  86.  
  87. /*
  88.  * read a byte from the input stream.
  89.  */
  90. Byte
  91. read_byte(ifp)
  92.     FILE *ifp;
  93. {
  94.     return ((Byte)getc(ifp));
  95. }
  96.  
  97. /*
  98.  * read a little-endian 2-byte halfword from the input stream.
  99.  */
  100. Halfword
  101. read_halfword(ifp)
  102.     FILE *ifp;
  103. {
  104.     union {
  105.     Halfword h;
  106.     Byte b[sizeof(Halfword)];
  107.     } ret;
  108.  
  109. #if defined(LITTLE_ENDIAN)
  110.     fread((char *)&ret.h, 1, sizeof(Halfword), ifp);
  111. #else
  112.     ret.b[HALFWORD0] = read_byte(ifp);
  113.     ret.b[HALFWORD1] = read_byte(ifp);
  114. #endif
  115.     return (ret.h);
  116. }
  117.  
  118. /*
  119.  * read a little-endian 4-byte word from the input stream.
  120.  */
  121. Word
  122. read_word(ifp)
  123.     FILE *ifp;
  124. {
  125.     union {
  126.     Word w;
  127.     Byte b[sizeof(Word)];
  128.     } ret;
  129.  
  130. #if defined(LITTLE_ENDIAN)
  131.     fread((char *)&ret.w, 1, sizeof(Word), ifp);
  132. #else
  133.     ret.b[WORD0] = read_byte(ifp);
  134.     ret.b[WORD1] = read_byte(ifp);
  135.     ret.b[WORD2] = read_byte(ifp);
  136.     ret.b[WORD3] = read_byte(ifp);
  137. #endif
  138.     return (ret.w);
  139. }
  140.  
  141. /*
  142.  * write a byte to the output stream.
  143.  */
  144. void
  145. write_byte(ofp, byte)
  146.     FILE *ofp;
  147.     Byte byte;
  148. {
  149.     if (writesize-- > 0)
  150.     putc((int)byte, ofp);
  151. }
  152.  
  153. #ifdef notyet
  154.  
  155. /*
  156.  * write a little-endian 2-byte halfword to the output stream.
  157.  */
  158. void
  159. write_halfword(ofp, halfword)
  160.     FILE *ofp;
  161.     Halfword halfword;
  162. {
  163.     union {
  164.     Halfword h;
  165.     Byte b[sizeof(Halfword)];
  166.     } un;
  167.  
  168.     un.h = halfword;
  169.  
  170. #if defined(LITTLE_ENDIAN)
  171.     fwrite((char *)&un.h, 1, sizeof(Halfword), ofp);
  172. #else
  173.     write_byte(ofp, un.b[HALFWORD0]);
  174.     write_byte(ofp, un.b[HALFWORD1]);
  175. #endif
  176. }
  177.  
  178. /*
  179.  * write a little-endian 4-byte word to the output stream.
  180.  */
  181. void
  182. write_word(ofp, word)
  183.     FILE *ofp;
  184.     Word word;
  185. {
  186.     union {
  187.     Word w;
  188.     Byte b[sizeof(Word)];
  189.     } un;
  190.  
  191.     un.w = word;
  192.  
  193. #if defined(LITTLE_ENDIAN)
  194.     fwrite((char *)&un.w, 1, sizeof(Word), ofp);
  195. #else
  196.     write_byte(ofp, un.b[WORD0]);
  197.     write_byte(ofp, un.b[WORD1]);
  198.     write_byte(ofp, un.b[WORD2]);
  199.     write_byte(ofp, un.b[WORD3]);
  200. #endif
  201. }    
  202.  
  203. #endif /* notyet */
  204.  
  205. /*
  206.  * read a compression-header from the file
  207.  */
  208. Header *
  209. read_header(ifp)
  210.     FILE *ifp;
  211. {
  212.     static Header header;
  213.     register i;
  214.     register char *cptr;
  215.     Byte byte;
  216.  
  217. #ifdef BSD
  218.     bzero((char *)&header, sizeof(header));
  219. #else /* not BSD */
  220.     memset((char *)&header, '\0', sizeof(header));
  221. #endif /* BSD */
  222.  
  223.     if (arcfs)
  224.     return(arcfs_read_header(ifp));
  225.  
  226.     header.comptype = read_byte(ifp);
  227.     if (!(header.comptype & ~ARCHPACK))
  228.     return (&header);    /* EOF */
  229.  
  230.     for (i = 0, cptr = header.name; i <= 12; i++, cptr++) {
  231.     byte = read_byte(ifp);
  232. #ifdef RISCOS
  233.     if (byte < ' ')
  234. #else
  235.     if (byte < ' ' || byte > '~')
  236. #endif
  237.         byte = '\0';
  238.     else if (byte == PATHSEP)    /* illegal in filename */
  239.         byte = '_';
  240.     *cptr = byte;
  241.     }
  242.     *cptr = '\0';            /* null terminate */
  243.     if (singlecase)
  244.     {
  245.     for (i = 0, cptr = header.name; i <= 12; i++, cptr++)
  246.         if (isascii(*cptr) && isupper(*cptr)) *cptr = tolower(*cptr);
  247.     }
  248.  
  249.     header.complen = read_word(ifp);
  250.     header.date = read_halfword(ifp);
  251.     header.time = read_halfword(ifp);
  252.     header.crc = read_halfword(ifp);
  253.     if ((header.comptype & ~ARCHPACK) > CT_NOTCOMP)
  254.     header.origlen = read_word(ifp);
  255.     else
  256.     header.origlen = header.complen;
  257.     if (header.comptype & ARCHPACK) {
  258.     header.load = read_word(ifp);
  259.     header.exec = read_word(ifp);
  260.     header.attr = read_word(ifp);
  261.     }
  262.  
  263.     if (check_stream(ifp) == FRWERR)
  264.     return (NULL);
  265.     return (&header);
  266. }
  267.