home *** CD-ROM | disk | FTP | other *** search
- /***
- *fileio.c - disked file I/O
- *
- *Copyright (c) 1991-1995, Gregg Jennings. All wrongs reserved.
- * P O Box 200, Falmouth, MA 02541-0200
- *
- *Purpose:
- * File read/write functions.
- *
- *Notice:
- * This progam may be freely used and distributed. Any distrubution
- * with modifications must retain the above copyright statement and
- * modifications noted.
- * No pulp-publication, in whole or in part, permitted without
- * permission (magazines or books).
- *******************************************************************************/
-
- /*
- Versions
-
- 1.0 10-Nov-1994 added calls to new error functions (see ERROR.C)
- 0.1 07-Sep-1994 created
- */
-
- #include <stdio.h>
- #include <conio.h> /* for kbhit() */
- #include <stdlib.h>
- #include <ctype.h>
- #include <fcntl.h> /* uses both stream and handle */
- #include <io.h>
- #include <sys\types.h>
- #include <sys\stat.h>
- #include <errno.h>
- #include <setjmp.h>
-
- #include "disked.h" /* append() declaration */
- #include "diskio.h" /* drive parameters */
- #include "console.h" /* print(), output(), */
- #include "error.h" /* error handling */
-
- /* globals referenced here
-
- data_buf
- byte_cnt
- max_bytes
- log_sector
- num_sectors
- sec_buf
- sec_size
- Display
- harderr_list
-
- */
-
- /* NO globals defined here */
-
-
- /* internal data */
-
- static FILE *fh;
- static int fd;
- static jmp_buf mark; /* address for long jump to jump to */
- static int jmpret;
-
- /*
- I think I finally found a good use for setjmp() and longjump().
- All examples I have found is based on a simple floating point
- error handler.
-
- For each of the file I/O functions, the stack is saved via
- setjmp(). On error fio_error() is called which returns via
- longjmp().
-
- The next level of abstraction would to be somehow return
- directly to the caller!
- */
-
- static void fio_error(char *);
-
- /***
- *putfile -
- *
- ****/
-
- extern int putfile(char *filename, int xlate, int m, int s, int c)
- {
- register int ch;
- unsigned int i;
- char *func = "putfile";
-
- errno = 0;
- jmpret = setjmp(mark);
-
- if (jmpret == 0)
- {
- if ((fh = fopen(filename,"w+b")) == NULL)
- fio_error(func);
- for (i = 0; i < byte_cnt; i++)
- {
- if (kbhit())
- break;
-
- ch = data_buf[i]&0xff;
- if (xlate && !isprint(ch) && !isspace(ch))
- {
- if (s) /* do we strip? */
- continue;
- else if (m) /* do we mask ? */
- {
- ch &= 0x7F;
- if ((ch = putc(ch,fh)) != ch)
- break;
- }
- else if (c) /* do we convert? */
- {
- if (fprintf(fh,"<%02x>",ch) != 4)
- break;
- }
- }
- else if ((ch = putc(ch,fh)) != ch) /* no mask, just put */
- break;
- }
- if (fclose(fh) == -1)
- {
- fh = NULL;
- fio_error(func);
- }
- return 1;
- }
- return -1;
- }
-
- #ifdef __BORLANDC__
- #pragma warn +par
- #endif
-
- /***
- *getfile -
- *
- ****/
-
- extern int getfile(char *filename, int xlate, int m, int s, int c)
- {
- int i;
- char *func = "getfile";
- unsigned char buffer[512];
-
- errno = 0;
-
- jmpret = setjmp(mark);
-
- if (jmpret == 0)
- {
- if ((fd = _open(filename,_O_RDONLY|_O_BINARY)) == -1)
- {
- if (error.num != -1)
- return -1;
- fio_error(func);
- }
- while ((i = _read(fd,buffer,512)) > 0)
- {
- if (kbhit())
- break;
-
- if (xlate)
- append(s,m,c,buffer,i);
- else
- append(0,0,0,buffer,i);
- if (byte_cnt == max_bytes)
- return -2;
- }
- if (i == -1)
- fio_error(func);
- if (close(fd) == -1)
- fio_error(func);
- return 1;
- }
- return -1;
- }
-
- /***
- *putsectors - put sectors to a file
- *
- ****/
-
- #define o_flag (_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR)
- #define p_mode (_S_IWRITE|_S_IREAD)
-
- extern int putsectors(char *file, long start, int num)
- {
- int i;
- char *func = "putsects";
-
- errno = 0;
- jmpret = setjmp(mark);
- savesector();
-
- if (jmpret == 0)
- {
- if ((fd = _open(file,o_flag,p_mode)) == ERROR)
- fio_error(func);
- if (start == 0)
- log_sector = num_sectors-1;
- else
- log_sector = start-1;
- for (i = 0; i < num; i++)
- {
- if (kbhit()) /* abort if like errors or something */
- break;
-
- if (Display)
- put(print("%d",i),8);
-
- nextsector();
- if (_write(fd,sec_buf,sec_size) != (int)sec_size)
- fio_error(func);
- }
- _close(fd);
- restoresector();
- return 1;
- }
- restoresector();
- return -1;
- }
-
- /***
- *fio_error - error handler
- *
- ****/
-
- static void fio_error(char *func)
- {
- char *msg;
-
- if (fh) /* close file stream if open */
- fclose(fh);
- if (fd > 0) /* close file handle if open */
- close(fd);
- if (!errno) /* if errno NOT set, set it now */
- errno = exterror();
- if (errno < 16) /* sys_nerr is 37! */
- msg = sys_errlist[errno];
- else if (errno >= 19 && errno <= 31)
- msg = (char *)harderr_list[errno-19];
- else
- {
- msg = "DOS error code: ";
- set_err_arg("%02Xh",errno);
- }
- set_error(msg,"fileio",errno,func);
- longjmp(mark,-1);
- }
-
- /***
- *append - Append bytes into the databuffer. The bytes are from the
- * sectorbuffer or a file.
- *
- * returns OK or ERROR if full
- ****/
-
- extern int append(int s, int m, int c, unsigned char *buffer, unsigned int nbytes)
- {
- register int ch;
- register int h;
- unsigned int i;
-
- for (i = 0; i < nbytes; i++)
- {
- ch = buffer[i]&0xff;
- if (!isprint(ch) && !isspace(ch))
- {
- if (s) /* do we strip? */
- continue;
- if (m && ch > 0x7f) /* do we mask ? */
- {
- data_buf[byte_cnt++] = (char)(ch&0x7f);
- continue;
- }
- if (c && byte_cnt < max_bytes-4) /* do we convert? */
- {
- data_buf[byte_cnt++] = '<';
- h = (ch>>4)&0x0f;
- data_buf[byte_cnt++] = (unsigned char)((h>9) ? (h+'a'-10) : (h+'0'));
- h = ch&0x0f;
- data_buf[byte_cnt++] = (unsigned char)((h>9) ? (h+'a'-10) : (h+'0'));
- data_buf[byte_cnt++] = '>';
- }
- else
- data_buf[byte_cnt++] = (char)ch; /* no mask, just put */
- }
- else
- data_buf[byte_cnt++] = (char)ch; /* no mask, just put */
- if (byte_cnt == max_bytes)
- return ERROR;
- }
- return 1;
- }
-
- extern long filesize(const char *file)
- {
- int fd;
- long l;
-
- if ((fd = _open(file,0)) != -1)
- {
- l = _filelength(fd);
- _close(fd);
- }
- else
- l = -1L;
-
- return l;
- }
-