home *** CD-ROM | disk | FTP | other *** search
/ CD-ROM Aktief 1995 #6 / CDA_6.iso / shell / utils / disked29.arj / SOURCE.ZIP / FILEIO.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-18  |  7.1 KB  |  314 lines

  1. /***
  2. *fileio.c - disked file I/O
  3. *
  4. *Copyright (c) 1991-1995, Gregg Jennings.  All wrongs reserved.
  5. *   P O Box 200, Falmouth, MA 02541-0200
  6. *
  7. *Purpose:
  8. *   File read/write functions.
  9. *
  10. *Notice:
  11. *   This progam may be freely used and distributed.  Any distrubution
  12. *   with modifications must retain the above copyright statement and
  13. *   modifications noted.
  14. *   No pulp-publication, in whole or in part, permitted without
  15. *   permission (magazines or books).
  16. *******************************************************************************/
  17.  
  18. /*
  19.    Versions
  20.  
  21.    1.0   10-Nov-1994    added calls to new error functions (see ERROR.C)
  22.    0.1   07-Sep-1994    created
  23. */
  24.  
  25. #include <stdio.h>
  26. #include <conio.h>         /* for kbhit() */
  27. #include <stdlib.h>
  28. #include <ctype.h>
  29. #include <fcntl.h>         /* uses both stream and handle */
  30. #include <io.h>
  31. #include <sys\types.h>
  32. #include <sys\stat.h>
  33. #include <errno.h>
  34. #include <setjmp.h>
  35.  
  36. #include "disked.h"        /* append() declaration */
  37. #include "diskio.h"        /* drive parameters */
  38. #include "console.h"       /* print(), output(), */
  39. #include "error.h"         /* error handling */
  40.  
  41. /* globals referenced here 
  42.  
  43.    data_buf
  44.    byte_cnt
  45.    max_bytes
  46.    log_sector
  47.    num_sectors
  48.    sec_buf
  49.    sec_size
  50.    Display
  51.    harderr_list
  52.  
  53. */
  54.  
  55. /* NO globals defined here */
  56.  
  57.  
  58. /* internal data */
  59.  
  60. static FILE *fh;
  61. static int fd;
  62. static jmp_buf mark;                /* address for long jump to jump to */
  63. static int jmpret;
  64.  
  65. /*
  66.    I think I finally found a good use for setjmp() and longjump().
  67.    All examples I have found is based on a simple floating point
  68.    error handler.
  69.  
  70.    For each of the file I/O functions, the stack is saved via
  71.    setjmp().  On error fio_error() is called which returns via
  72.    longjmp().
  73.  
  74.    The next level of abstraction would to be somehow return
  75.    directly to the caller!
  76. */
  77.  
  78. static void fio_error(char *);
  79.  
  80. /***
  81. *putfile -
  82. *
  83. ****/
  84.  
  85. extern int putfile(char *filename, int xlate, int m, int s, int c)
  86. {
  87. register int ch;
  88. unsigned int i;
  89. char *func = "putfile";
  90.  
  91.    errno = 0;
  92.    jmpret = setjmp(mark);
  93.  
  94.    if (jmpret == 0)
  95.    {
  96.       if ((fh = fopen(filename,"w+b")) == NULL)
  97.          fio_error(func);
  98.       for (i = 0; i < byte_cnt; i++)
  99.       {
  100.          if (kbhit())
  101.             break;
  102.  
  103.          ch = data_buf[i]&0xff;
  104.          if (xlate && !isprint(ch) && !isspace(ch))
  105.          {
  106.             if (s)                              /* do we strip? */
  107.                continue;
  108.             else if (m)                         /* do we mask ? */
  109.             {
  110.                ch &= 0x7F;
  111.                if ((ch = putc(ch,fh)) != ch)
  112.                   break;
  113.             }
  114.             else if (c)                         /* do we convert? */
  115.             {
  116.                if (fprintf(fh,"<%02x>",ch) != 4)
  117.                   break;
  118.             }
  119.          }
  120.          else if ((ch = putc(ch,fh)) != ch)     /* no mask, just put */
  121.             break;
  122.       }
  123.       if (fclose(fh) == -1)
  124.       {
  125.          fh = NULL;
  126.          fio_error(func);
  127.       }
  128.       return 1;
  129.    }
  130.    return -1;
  131. }
  132.  
  133. #ifdef __BORLANDC__
  134. #pragma warn +par
  135. #endif
  136.  
  137. /***
  138. *getfile -
  139. *
  140. ****/
  141.  
  142. extern int getfile(char *filename, int xlate, int m, int s, int c)
  143. {
  144. int i;
  145. char *func = "getfile";
  146. unsigned char buffer[512];
  147.  
  148.    errno = 0;
  149.  
  150.    jmpret = setjmp(mark);
  151.  
  152.    if (jmpret == 0)
  153.    {
  154.       if ((fd = _open(filename,_O_RDONLY|_O_BINARY)) == -1)
  155.       {
  156.          if (error.num != -1)
  157.             return -1;
  158.          fio_error(func);
  159.       }
  160.       while ((i = _read(fd,buffer,512)) > 0)
  161.       {
  162.          if (kbhit())
  163.             break;
  164.  
  165.          if (xlate)
  166.             append(s,m,c,buffer,i);
  167.          else
  168.             append(0,0,0,buffer,i);
  169.          if (byte_cnt == max_bytes)
  170.             return -2;
  171.       }
  172.       if (i == -1)
  173.          fio_error(func);
  174.       if (close(fd) == -1)
  175.          fio_error(func);
  176.       return 1;
  177.    }
  178.    return -1;
  179. }
  180.  
  181. /***
  182. *putsectors -  put sectors to a file
  183. *
  184. ****/
  185.  
  186. #define o_flag (_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR)
  187. #define p_mode (_S_IWRITE|_S_IREAD)
  188.  
  189. extern int putsectors(char *file, long start, int num)
  190. {
  191. int i;
  192. char *func = "putsects";
  193.  
  194.    errno = 0;
  195.    jmpret = setjmp(mark);
  196.    savesector();
  197.  
  198.    if (jmpret == 0)
  199.    {
  200.       if ((fd = _open(file,o_flag,p_mode)) == ERROR)
  201.          fio_error(func);
  202.       if (start == 0)
  203.          log_sector = num_sectors-1;
  204.       else
  205.          log_sector = start-1;
  206.       for (i = 0; i < num; i++)
  207.       {
  208.          if (kbhit())            /* abort if like errors or something */
  209.             break;
  210.  
  211.          if (Display)
  212.             put(print("%d",i),8);
  213.  
  214.          nextsector();
  215.          if (_write(fd,sec_buf,sec_size) != (int)sec_size)
  216.             fio_error(func);
  217.       }
  218.       _close(fd);
  219.       restoresector();
  220.       return 1;
  221.    }
  222.    restoresector();
  223.    return -1;
  224. }
  225.  
  226. /***
  227. *fio_error  -  error handler
  228. *
  229. ****/
  230.  
  231. static void fio_error(char *func)
  232. {
  233. char *msg;
  234.  
  235.    if (fh)                             /* close file stream if open */
  236.       fclose(fh);
  237.    if (fd > 0)                         /* close file handle if open */
  238.       close(fd);
  239.    if (!errno)                         /* if errno NOT set, set it now */
  240.       errno = exterror();
  241.    if (errno < 16)                     /* sys_nerr is 37! */
  242.       msg = sys_errlist[errno];
  243.    else if (errno >= 19 && errno <= 31)
  244.       msg = (char *)harderr_list[errno-19];
  245.    else
  246.    {
  247.       msg = "DOS error code: ";
  248.       set_err_arg("%02Xh",errno);
  249.    }
  250.    set_error(msg,"fileio",errno,func);
  251.    longjmp(mark,-1);
  252. }
  253.  
  254. /***
  255. *append  -  Append bytes into the databuffer.  The bytes are from the
  256. *           sectorbuffer or a file.
  257. *
  258. *           returns OK or ERROR if full
  259. ****/
  260.  
  261. extern int append(int s, int m, int c, unsigned char *buffer, unsigned int nbytes)
  262. {
  263. register int ch;
  264. register int h;
  265. unsigned int i;
  266.  
  267.    for (i = 0; i < nbytes; i++)
  268.    {
  269.       ch = buffer[i]&0xff;
  270.       if (!isprint(ch) && !isspace(ch))
  271.       {
  272.          if (s)                              /* do we strip? */
  273.             continue;
  274.          if (m && ch > 0x7f)                 /* do we mask ? */
  275.          {
  276.             data_buf[byte_cnt++] = (char)(ch&0x7f);
  277.             continue;
  278.          }
  279.          if (c && byte_cnt < max_bytes-4)    /* do we convert? */
  280.          {
  281.             data_buf[byte_cnt++] = '<';
  282.             h = (ch>>4)&0x0f;
  283.             data_buf[byte_cnt++] = (unsigned char)((h>9) ? (h+'a'-10) : (h+'0'));
  284.             h = ch&0x0f;
  285.             data_buf[byte_cnt++] = (unsigned char)((h>9) ? (h+'a'-10) : (h+'0'));
  286.             data_buf[byte_cnt++] = '>';
  287.          }
  288.          else
  289.             data_buf[byte_cnt++] = (char)ch; /* no mask, just put */
  290.       }
  291.       else
  292.          data_buf[byte_cnt++] = (char)ch;    /* no mask, just put */
  293.       if (byte_cnt == max_bytes)
  294.          return ERROR;
  295.    }
  296.    return 1;
  297. }
  298.  
  299. extern long filesize(const char *file)
  300. {
  301. int fd;
  302. long l;
  303.  
  304.    if ((fd = _open(file,0)) != -1)
  305.    {
  306.       l = _filelength(fd);
  307.       _close(fd);
  308.    }
  309.    else
  310.       l = -1L;
  311.  
  312.    return l;
  313. }
  314.