home *** CD-ROM | disk | FTP | other *** search
- /*
- * The routines in this file read and write ASCII files from the disk. All of
- * the knowledge about files are here.
- */
-
- #include <stdio.h>
- #include "estruct.h"
- #include "edef.h"
- #if FINDER
- #if MPW
- #include <errors.h>
- #define CtoPstr c2pstr
- #include <Memory.h>
- #include <Resources.h>
- #else
- #include <MemoryMgr.h>
- #include <ResourceMgr.h>
- #endif
- Handle hfline = NULL;
- char *CtoPstr();
- short _iovrefnum;
- static short _iofrefnum;
- #else
- FILE *ffp; /* File pointer, all functions. */
- int eofflag; /* end-of-file flag */
- #endif
- #if FINDER
- static char eolstr[1] = "\r";
- #define eolchar eolstr[0]
- /*
- * PBClear() - Clear all fields of a ParamBlockRec.
- * Better safe than sorry. This also saves code size, since other
- * routines do not need to clear fields explicitly.
- */
- PBClear(pb)
- long *pb;
- {
- int i = sizeof(ParamBlockRec)/4;
- for(;i--;){
- *pb++ = 0L;
- }
- }
- #endif
- /*
- * Open a file for reading.
- */
- ffropen(fn)
- char *fn;
- {
- #if MAC
- char pname[NFILEN];
- FInfo info;
- strcpy(pname,fn);
- CtoPstr(pname);
- if(FSOpen(pname,_iovrefnum,&_iofrefnum)!=noErr){
- mlwrite("File not found.");
- return FIOFNF;
- }
- /*
- * Three file types are defined.
- * 'TEXT' is for regular MacOS files. Line ends with '\r'.
- *
- * 'A/UX' is for A/UX 1.0 files. This is undocumented. Line ends with '\012'.
- *
- * Any other file type, we assume it is a binary file, and use '\0'
- * as the line separator. This is handy for patching object libraries,
- * but is not so good for other file types which happen to have real
- * text embedded in them.
- *
- * Hey, we can't know everything, can we?
- *
- */
- GetFInfo(pname,_iovrefnum,&info);
- if(info.fdType == 'A/UX'){
- eolchar = '\012';
- }else if(info.fdType == 'TEXT'){
- eolchar = '\015';
- }else{
- eolchar = '\0';
- }
- #else
- if ((ffp=fopen(fn, "r")) == NULL)
- return (FIOFNF);
- eofflag = FALSE;
- #endif
- return (FIOSUC);
- }
-
- /*
- * Open a file for writing. Return TRUE if all is well, and FALSE on error
- * (cannot create).
- */
- ffwopen(fn)
- char *fn;
- {
- #if MAC
- char pname[NFILEN];
- register LINE *lp;
- register long bytes;
- long nbytes;
- FInfo info;
- strcpy(pname,fn);
- CtoPstr(pname);
- /*
- * If the file exists, open it for writing, set the EOF of the data
- * fork to 0L, allocate enough space to save the current buffer,
- * leave the present Resource Fork intact. Otherwise, create a
- * new file with no Resource Fork.
- */
- if(FSOpen(pname,curbp->b_ioWDDirID,&_iofrefnum)!=noErr){
- if(Create(pname,_iovrefnum,'Earl','TEXT')!=noErr){
- mlwrite("New file not created");
- return FIOERR;
- }
- else if(FSOpen(pname,curbp->b_ioWDDirID,&_iofrefnum)!=noErr){
- mlwrite("New file not opened!");
- return FIOERR;
- }
- }
- GetFInfo(pname,curbp->b_ioWDDirID,&info);
- if(info.fdType == 'A/UX'){
- eolchar = '\012';
- }else if(info.fdType == 'TEXT'){
- eolchar = '\015';
- }else{
- eolchar = '\0';
- }
-
- lp = lforw(curbp->b_linep);
- bytes = 0L;
- while (lp != curbp->b_linep) { /* Count bytes in buffer. */
- bytes += (long)llength(lp)+1L;
- lp = lforw(lp);
- }
- bytes++; /* Might write extra newline! */
- /*
- * Error if not enough disk space, or cannot get/set EOF.
- */
- if(GetEOF(_iofrefnum,&nbytes)!=noErr){
- mlwrite("Cannot get EOF");
- (void)FSClose(_iofrefnum);
- return FIOERR;
- }
- if(nbytes < bytes){
- nbytes = bytes - nbytes;
- if(SetFPos(_iofrefnum,fsFromLEOF,0L)!=noErr){
- mlwrite("Cannot set file position");
- (void)FSClose(_iofrefnum);
- return FIOERR;
- }
- if(Allocate(_iofrefnum,&nbytes) != noErr){
- mlwrite("Insufficient disk space, sorry.");
- (void)FSClose(_iofrefnum);
- return FIOERR;
- }
- }
- nbytes = bytes;
- if(SetEOF(_iofrefnum,0L)!=noErr){
- mlwrite("Cannot set EOF");
- (void)FSClose(_iofrefnum);
- return FIOERR;
- }
- if(SetFPos(_iofrefnum,fsFromStart,0L)!=noErr){
- mlwrite("Cannot set file position");
- (void)FSClose(_iofrefnum);
- return FIOERR;
- }
- return FIOSUC;
- #else
- #if VMS
- register int fd;
-
- if ((fd=creat(fn, 0666, "rfm=var", "rat=cr")) < 0
- || (ffp=fdopen(fd, "w")) == NULL) {
- #else
- if ((ffp=fopen(fn, "w")) == NULL) {
- #endif
- mlwrite("Cannot open file for writing");
- return (FIOERR);
- }
- return (FIOSUC);
- #endif
- }
-
- /*
- * Close a file. Should look at the status in all systems.
- */
- ffclose()
- {
- #if FINDER
- ParamBlockRec iopb;
- register ParmBlkPtr pb = &iopb;
- if(hfline != NULL){
- DisposHandle(hfline);
- hfline = NULL;
- fline = NULL;
- flen = 0;
- }
- #else
- /* free this since we do not need it anymore */
- if (fline != NULL) {
- free(fline);
- fline = NULL;
- flen = 0;
- }
- #endif
- #if FINDER
- if(FSClose(_iofrefnum) != noErr){
- return FIOERR;
- }else{
- PBClear(pb);
- pb->volumeParam.ioVRefNum = curbp->b_ioWDDirID;
- PBGetVInfo(pb,false);
- PBFlushVol(pb,false); /* Make sure it winds up on disk. */
- }
- return FIOSUC;
- }
- #else
- #if MSDOS & CTRLZ
- fputc(26, ffp); /* add a ^Z at the end of the file */
- #endif
-
- #if V7 | USG | BSD | (MSDOS & (LATTICE | MSC | TURBO)) | (ST520 & MWC)
- if (fclose(ffp) != FALSE) {
- mlwrite("Error closing file");
- return(FIOERR);
- }
- return(FIOSUC);
- #else
- fclose(ffp);
- return (FIOSUC);
- #endif
- }
- #endif
-
- /*
- * Write a line to the already opened file. The "buf" points to the buffer,
- * and the "nbuf" is its length, less the free newline. Return the status.
- * Check only at the newline.
- */
- ffputline(buf, nbuf)
- char buf[];
- {
- #if FINDER /* We don't do CRYPT. */
- long lnbuf = nbuf;
- if(FSWrite(_iofrefnum,&lnbuf,buf) != noErr){
- mlwrite("Write I/O error");
- return (FIOERR);
- }
- lnbuf = 1L;
- if(FSWrite(_iofrefnum,&lnbuf,eolstr) != noErr){
- mlwrite("Write I/O error");
- return (FIOERR);
- }
- return (FIOSUC);
- #else
- register int i;
- #if CRYPT
- char c; /* character to translate */
-
- if (cryptflag) {
- for (i = 0; i < nbuf; ++i) {
- c = buf[i] & 0xff;
- crypt(&c, 1);
- fputc(c, ffp);
- }
- } else
- for (i = 0; i < nbuf; ++i)
- fputc(buf[i]&0xFF, ffp);
- #else
- for (i = 0; i < nbuf; ++i)
- fputc(buf[i]&0xFF, ffp);
- #endif
- #if ST520 & ADDCR
- fputc(CR, ffp);
- #endif
- fputc(eolchar, ffp);
-
- if (ferror(ffp)) {
- mlwrite("Write I/O error");
- return (FIOERR);
- }
-
- return (FIOSUC);
- #endif
- }
-
- /*
- * Read a line from a file, and store the bytes in the supplied buffer. The
- * "nbuf" is the length of the buffer. Complain about long lines and lines
- * at the end of the file that don't have a newline present. Check for I/O
- * errors too. Return status.
- * Macintosh note: In this implementation, "fline" is actually a dereferenced
- * Handle. If we get a long line, we unlock and resize the Handle, then set
- * fline to the new pointer. Definitely superior to the vanilla code, below!
- */
- ffgetline(n)
- int *n;
- {
- #if FINDER
- ParamBlockRec iopb;
- register ParmBlkPtr pb = &iopb;
- #endif
- register int c; /* current character read */
- register int i; /* current index into fline */
- register char *tmpline; /* temp storage for expanding line */
-
- /* if we are at the end...return it */
- #if FINDER
- if(hfline == NULL){
- hfline = NewHandle((long)NSTRING);
- if(hfline == NULL) return FIOMEM;
- HLock(hfline);
- fline = *hfline;
- flen = NSTRING;
- }
- if(flen > NSTRING){
- HUnlock(hfline);
- SetHandleSize(hfline,(long)NSTRING); /* No error (smaller). */
- HLock(hfline);
- fline = *hfline;
- flen = NSTRING;
- }
- #else
-
- if (eofflag)
- return(FIOEOF);
- /* dump fline if it ended up too big */
- if (flen > NSTRING && fline != NULL) {
- free(fline);
- fline = NULL;
- flen = 0;
- }
-
- /* if we don't have an fline, allocate one */
- if (fline == NULL)
- if ((fline = malloc(flen = NSTRING)) == NULL){
- flen = 0;
- return(FIOMEM);
- }
- #endif
- #if FINDER
- tmpline = fline;
- i=0;
- PBClear(pb);
- retry:
- pb->ioParam.ioRefNum = _iofrefnum;
- pb->ioParam.ioPosMode = 0x0080 | (eolchar << 8);
- pb->ioParam.ioBuffer = tmpline;
- pb->ioParam.ioReqCount = NSTRING;
- PBRead(pb,FALSE);
- i += (int)pb->ioParam.ioActCount;
- pb->ioParam.ioResult =
- (pb->ioParam.ioResult == eofErr ? 0 : pb->ioParam.ioResult);
- if ((int)pb->ioParam.ioActCount >= NSTRING) {
- HUnlock(hfline);
- SetHandleSize(hfline,(long)(flen+=NSTRING));
- if(MemError() != noErr){
- DisposHandle(hfline);
- hfline = NULL;
- fline = NULL;
- flen = 0;
- return FIOMEM;
- }else{
- HLock(hfline);
- fline = *hfline;
- }
- tmpline = fline + flen - NSTRING;
- goto retry;
- }
- if (pb->ioParam.ioResult) {
- mlwrite("File read error");
- return (FIOERR);
- }
-
- if ((int)pb->ioParam.ioActCount == 0) return (FIOEOF);
- if(fline[i-1] == eolchar)
- i--;
- #else
- /* read the line in */
- i = 0;
- while ((c = fgetc(ffp)) != EOF && c != eolchar) {
- fline[i++] = c;
- /* if it's longer, get more room */
- if (i >= flen) {
- if ((tmpline = malloc(flen+NSTRING)) == NULL)
- return(FIOMEM);
- strncpy(tmpline, fline, flen);
- flen += NSTRING;
- free(fline);
- fline = tmpline;
- }
- }
-
- #if ST520
- if(fline[i-1] == CR)
- i--;
- #endif
-
- /* test for any errors that may have occured */
- if (c == EOF) {
- if (ferror(ffp)) {
- mlwrite("File read error");
- return(FIOERR);
- }
-
- if (i != 0)
- eofflag = TRUE;
- else
- return(FIOEOF);
- }
-
- /* terminate and decrypt the string */
- #endif
- fline[i] = 0;
-
- #if CRYPT
- if (cryptflag)
- crypt(fline, strlen(fline));
- #endif
- *n = i;
- return(FIOSUC);
- }
- #if FINDER
- /*
- * Does a file exist? Used by startup code.
- */
- fexist(fn)
- char *fn;
- {
- #if FINDER
- ParamBlockRec iopb;
- register ParmBlkPtr pb = &iopb;
- #endif
- int result;
- char pname[NFILEN];
- strcpy(pname,fn);
- CtoPstr(pname);
- PBClear(pb);
- pb->ioParam.ioNamePtr = (StringPtr)pname;
- pb->ioParam.ioVRefNum = _iovrefnum;
- if(PBGetFInfo(pb,FALSE))return (FALSE);
- else return TRUE;
- }
- #else
-
- int fexist(fname) /* does <fname> exist on disk? */
-
- char *fname; /* file to check for existance */
-
- {
- FILE *fp;
-
- /* try to open the file for reading */
- fp = fopen(fname, "r");
-
- /* if it fails, just return false! */
- if (fp == NULL)
- return(FALSE);
-
- /* otherwise, close it and report true */
- fclose(fp);
- return(TRUE);
- }
- #endif
- #if AZTEC & MSDOS
- #undef fgetc
- /* a1getc: Get an ascii char from the file input stream
- but DO NOT strip the high bit
- */
-
- int a1getc(fp)
-
- FILE *fp;
-
- {
- int c; /* translated character */
-
- c = getc(fp); /* get the character */
-
- /* if its a <LF> char, throw it out */
- while (c == 10)
- c = getc(fp);
-
- /* if its a <RETURN> char, change it to a LF */
- if (c == CR)
- c = LF;
-
- /* if its a ^Z, its an EOF */
- if (c == 26)
- c = EOF;
-
- return(c);
- }
- #endif
-