home *** CD-ROM | disk | FTP | other *** search
- #include "pt.h"
- #include "memory.h"
- #include "malloc.h"
- #include "string.h"
- #include "direct.h"
- #include "io.h"
- #include "process.h"
- #include "conio.h"
-
- extern struct openFile *files;
- extern struct diskBuffer *buffers;
- extern struct diskBuffer *bufHash[];
- extern nextBuffer;
-
- void pascal
- /* XTAG:initFileio */
- initFileio()
- {
- extern unsigned char msgBuffer[];
- extern struct piece *freePList;
- extern struct piece pieceTable[];
- extern unsigned char *bufferSpace;
- extern int nBuffers;
- extern unsigned int piecesLeft;
- extern unsigned int bytesLeft;
- extern unsigned int maxFiles;
- extern unsigned int debug;
- extern unsigned char *userMessages[];
-
- register int i;
- unsigned short segIncrement, *segPointer;
- long size;
- unsigned char huge *bs;
-
- for(i = 0; i < maxFiles; i++) {
- files[i].origHandle = -1;
- }
-
- /* set up the buffer hash scheme */
- for(i = 0; i < NBUFHASH; i++)
- bufHash[i] = NULL;
- nextBuffer = -1;
-
- /* allocate the space (out of this address space) for the buffers */
- retryAllocation:
- size = (long)BUFFERSIZE * (long)nBuffers;
- bs = halloc(size, 1);
- if( bs == 0L ) {
- /* if there is not enough space, try fewer buffers */
- if( nBuffers >= 25 ) {
- nBuffers -= 20;
- goto retryAllocation;
- }
- size -= (unsigned)16*(unsigned)i;
- cprintf(userMessages[NOBUFFERMEMORY], size);
- exit(1);
- }
-
- /* set up each buffer header to the segment address of the */
- /* allocated buffer. Buffer i is at buffers[i].bufferAddress */
- segIncrement = (unsigned short)(BUFFERSIZE / 16);
- for(i = 0; i < nBuffers; i++) {
- buffers[i].handle = -1;
- buffers[i].bufferAddress = (unsigned char far *)bs;
- /***bs += BUFFERSIZE;***/
- /* move the segment part of the address up */
- segPointer = ((unsigned short *)(&bs)) + 1;
- *segPointer += segIncrement;
- }
-
- /* set up the free piece list */
- freePList = NULL;
- piecesLeft = 0;
- bytesLeft = _memavl();
- }
-
- int pascal
- /* XTAG:getFileId */
- getFileId(origName)
- unsigned char *origName;
- {
- extern unsigned char msgBuffer[];
- extern unsigned char scratchFileName[];
- extern int addHandle;
- extern int readOnly;
- extern int maxFiles;
- extern int supressFileMsgs;
- #ifdef OVERLAYS
- extern int filesToOpen;
- extern struct openFile *ffsToOpen[];
- #endif
- extern unsigned char *userMessages[];
-
- int fileNumber, origHandle;
- int freeFileId;
- long size;
- register struct piece *pp;
- register struct openFile *ff;
- unsigned char *fullFilename;
-
- if( origName == NULL ) {
- scratchFileName[0] = '\0';
- fullFilename = &scratchFileName[0];
- } else
- fullFilename = makeFullPathname(origName);
-
- /* find a free file structure */
- freeFileId = -1;
- for(fileNumber = 0; fileNumber < maxFiles; fileNumber++) {
- if( files[fileNumber].origHandle == -1 ) {
- if( freeFileId == -1 )
- freeFileId = fileNumber;
- } else if(
- strcmpi(files[fileNumber].origName, fullFilename)
- == 0 ) {
- ++(files[fileNumber].useCount);
- return fileNumber;
- }
- }
- if( freeFileId == -1 ) {
- msg(userMessages[OUTOFFILESTRUCT], 3);
- return -1;
- } else
- fileNumber = freeFileId;
-
- /* open the original file */
- ff = &files[fileNumber];
- strncpy(ff->origName, fullFilename, FILENAMESIZE);
-
- if( fullFilename[0] == '\0' ) {
- origHandle = addHandle;
- } else {
- origHandle = openls(fullFilename, 0);
-
- if( origHandle == -4 ) {
- if( supressFileMsgs < 2 )
- msg(userMessages[HANDLEMSG], 3);
- if( supressFileMsgs == 1 )
- supressFileMsgs = 2;
- return -1;
- } else if( origHandle < 0 ) {
- sprintf(msgBuffer, userMessages[CANNOTOPEN],
- fullFilename);
- msg(msgBuffer, 3);
- return -1;
- }
-
- #ifdef OVERLAYS
- /* see if we were called from an overlay any have to */
- /* reopen the file after the overlay completes */
- if( filesToOpen > 0 ) {
- ffsToOpen[filesToOpen-1] = ff;
- ++filesToOpen;
- }
- #endif
- }
- ff->origHandle = origHandle;
-
- /* initialize the other fields */
- if( origHandle != addHandle ) {
- size = lseekls(origHandle, 0L, 2);
- lseekls(origHandle, 0L, 0);
- } else
- size = 0;
- ff->fileSize = size;
- ff->origFileSize = size;
- ff->useCount = 1;
- ff->bakMade = 0;
- ff->isChanged = 0; /* has not been edited yet */
- if( readOnly )
- ff->readOnly = 1;
- else if( origHandle == addHandle ) {
- ff->readOnly = 0;
- } else {
- /* check for read and write permissions (6 => RW) */
- /* edit in readOnly mode if the DOS file permissions */
- /* do not allow writing the file */
- ff->readOnly = (unsigned char)!(access(ff->origName, 6) == 0);
- }
-
- /* initialize the piece table */
- pp = getFreePiece();
- pp->file = ORIGFILE;
- pp->position = 0;
- pp->length = size;
- ff->pieceList = pp;
-
- /* initialize the optimization fields */
- ff->loLogPiece = 0;
- ff->hiLogPiece = size - 1;
- ff->logPiece = pp;
- ff->hiLogBuffer = -1L;
- ff->logBufSegment = NULL;
- ff->logBufOffset = NULL;
-
- /*return the fileId */
- return fileNumber;
- }
-
- void pascal
- /* XTAG:saveFile */
- saveFile(w)
- struct window *w;
- {
- extern unsigned char msgBuffer[];
- extern struct openFile *files;
- extern int addHandle;
- #ifdef OVERLAYS
- extern int filesToOpen;
- extern struct openFile *ffsToOpen[];
- #endif
- extern unsigned char *userMessages[];
-
- register struct openFile *ff;
- unsigned char *tempFile, *p;
- int i;
- long size;
- struct piece *pp;
-
- ff = &files[w->fileId];
-
- if( ff->readOnly ) {
- sprintf(msgBuffer, userMessages[READONLYFILE], ff->origName);
- msg(msgBuffer, 3);
- return;
- }
-
- tempFile = makeTempFor(ff->origName);
- sprintf(msgBuffer, userMessages[WRITINGFILE], ff->origName,
- ff->fileSize);
- msg(msgBuffer, 1);
-
- if( !doWrite(w->fileId, tempFile) )
- return;
-
- sprintf(msgBuffer, userMessages[FILEWRITTEN], ff->origName,
- ff->fileSize);
- msg(msgBuffer, 1);
-
- /* invalidate any buffers allocated to this open file */
- fidInvalid(ff->origHandle);
- ff->hiLogBuffer = -1L;
-
- /* reset the change flag */
- ff->isChanged = 0;
-
- /* close the original file for this open file */
- if( ff->origHandle != addHandle ) {
- i = closels(ff->origHandle);
- if( i != 0 ) {
- sprintf(msgBuffer, userMessages[CLOSEFAILED],
- ff->origName, i);
- msg(msgBuffer, 3);
- }
- }
-
- if( !ff->bakMade ) {
- /* generate the .bak name and rename the original file */
- /* rename the temporary file we copied it into */
- p = makeBak(ff->origName);
- delete(p); /* make sure any old .bak file is deleted */
- if( renamels(ff->origName, p) ) {
- sprintf(msgBuffer, userMessages[RENAMEFAILED],
- ff->origName, p, tempFile);
- msg(msgBuffer, 3);
- }
- ff->bakMade = 1;
- } else {
- if( delete(ff->origName) ) {
- sprintf(msgBuffer, userMessages[DELETEFAILED],
- ff->origName, tempFile);
- msg(msgBuffer, 3);
- }
- }
-
- if( renamels(tempFile, ff->origName) ) {
- sprintf(msgBuffer, userMessages[RENAMEFAILED2],
- tempFile, ff->origName, ff->origName, tempFile);
- msg(msgBuffer, 3);
- }
-
- /* open it up again */
- if( ff->origHandle != addHandle )
- ff->origHandle = openls(ff->origName, 0);
-
- #ifdef OVERLAYS
- /* see if we were called from an overlay any have to reopen */
- /* the file after the overlay completes */
- if( filesToOpen > 0 ) {
- ffsToOpen[filesToOpen-1] = ff;
- ++filesToOpen;
- }
- #endif
-
- /* re-initialize the other fields */
- size = lseekls(ff->origHandle, 0L, 2);
- ff->fileSize = size;
- ff->origFileSize = size;
- lseekls(ff->origHandle, 0L, 0);
-
- /* free all the pieces */
- freePieces(ff->pieceList);
-
- /* re-initialize the piece table */
- pp = getFreePiece();
- ff->pieceList = pp;
- pp->file = ORIGFILE;
- pp->position = 0;
- pp->length = size;
-
- /* re-initialize the optimization fields */
- ff->loLogPiece = 0;
- ff->hiLogPiece = size - 1;
- ff->logPiece = pp;
- ff->hiLogBuffer = -1L;
- ff->logBufSegment = NULL;
- ff->logBufOffset = NULL;
- }
-
- unsigned char * pascal
- /* XTAG:makeBak */
- makeBak(s)
- unsigned char *s;
- {
- static unsigned char name[64];
- register int i;
- int len;
-
- /* find the extension (if there is one) */
- len = strlen(s);
- for(i = len - 1; i > 0 && s[i] != '.' && s[i] != '\\'; --i)
- ;
- if( s[i] != '.' )
- /* if no extension then put the .bak at the end */
- i = len;
-
- /* compose the name */
- strcpy(name, s);
- name[i] = '.';
- name[++i] = 'b';
- name[++i] = 'a';
- name[++i] = 'k';
- name[++i] = '\0';
- return &name[0];
- }
-
- void pascal
- /* XTAG:writeFile */
- writeFile(w)
- struct window *w;
- {
- extern struct openFile *files;
- extern unsigned char msgBuffer[];
- extern unsigned char textBuffer[];
- extern unsigned char *userMessages[];
-
- unsigned char *tempFile;
-
- tempFile = getInput("File name to write to: ", "", 0);
- if( tempFile == NULL ) {
- cancel:
- msg(userMessages[WRITECANCELLED], 1);
- return;
- }
-
- /* check if the file already exists */
- if( access(tempFile, 0) == 0 ) {
- strcpy(textBuffer, tempFile);
- sprintf(msgBuffer, userMessages[FILEEXISTS], tempFile);
- tempFile = getInput(msgBuffer, "n", 1);
- if( tolower(*tempFile) != 'y' )
- goto cancel;
- tempFile = textBuffer;
- }
-
- sprintf(msgBuffer, userMessages[WRITINGFILE],
- tempFile, files[w->fileId].fileSize);
- msg(msgBuffer, 1);
-
- if( !doWrite(w->fileId, tempFile) )
- return;
-
- sprintf(msgBuffer, userMessages[FILEWRITTEN],
- tempFile, files[w->fileId].fileSize);
- msg(msgBuffer, 1);
- }
-
- int pascal
- /* XTAG:doWrite */
- doWrite(fileId, tempFile)
- int fileId;
- unsigned char *tempFile;
- {
- extern unsigned char msgBuffer[];
- extern struct SREGS segRegs;
- extern unsigned char *userMessages[];
-
- long cp, fSize;
- int fid, iBuffer, lineSize, n;
- unsigned char far *firstByte;
- unsigned char far *lastByte;
- unsigned char far *sBuffer;
- unsigned int sizeOfBuffer;
-
- fSize = fileSize(fileId);
-
- /* open the output file */
- fid = creatls(tempFile, 0);
- if( fid == -4 ) {
- msg(userMessages[HANDLEMSG], 3);
- return 0;
- } else if( fid == -97 ) {
- msg(userMessages[WRITEFAILED], 3);
- return 0;
- } else if( fid < 0 ) {
- sprintf(msgBuffer, userMessages[CREATEFAILED], tempFile, fid);
- msg(msgBuffer, 3);
- return 0;
- }
-
- /* allocate the IO buffer */
- sizeOfBuffer = 4096;
- while( 1 ) {
- sBuffer = _fmalloc(sizeOfBuffer);
- if( sBuffer == 0L ) {
- /* try again with a buffer half as large */
- sizeOfBuffer >>= 1;
- if( sizeOfBuffer < 64 ) {
- msg(userMessages[NOSPACEMSG], 3);
- return 0;
- }
- continue;
- } else
- break;
- }
-
- cp = 0;
- iBuffer = 0;
- while( 1 ) {
- /* special case for files of length 0 */
- if( fSize == 0 )
- fSize = 1;
- sprintf(msgBuffer, userMessages[WRITEPROGRESS],
- (int)( (100*cp) / fSize) );
- msg(msgBuffer, 1);
- if( getSpan(fileId, cp, &firstByte, &lastByte, 0) )
- break;
- lineSize = (int)(lastByte - firstByte + 1);
- cp = cp + lineSize;
-
- if( (iBuffer+lineSize) >= sizeOfBuffer ) {/* will it fit? */
- /* no, so write out the buffer to empty it */
- if( (n = writeFar(fid, sBuffer, iBuffer)) < iBuffer ) {
- error:
- _ffree(sBuffer);
- /* avoid recursive calls if msg tries to write disk */
- msg(userMessages[FULLMSG], 3);
- closels(fid);
- delete(tempFile);
- return 0;
- } else
- iBuffer = 0;
- }
- movedata(FP_SEG(firstByte), FP_OFF(firstByte), FP_SEG(sBuffer),
- FP_OFF(sBuffer)+iBuffer, (unsigned)lineSize);
- iBuffer += lineSize;
- }
- if( (n = writeFar(fid, sBuffer, iBuffer)) < iBuffer )
- goto error;
- closels(fid);
-
- /* all is ok */
- _ffree(sBuffer);
- return 1;
- }
-
- unsigned char * pascal
- /* XTAG:makeTempFor */
- makeTempFor(name)
- unsigned char *name;
- {
- static unsigned char tname[64];
- register int len;
- int pathEnd;
- unsigned char ch;
-
- len = 0;
- pathEnd = -1;
- while( 1 ) {
- if( (ch = name[len]) == '\0' )
- break;
- tname[len] = ch;
- switch( ch ) {
- case '/':
- case '\\':
- case ':':
- pathEnd = len;
- }
- ++len;
- }
- tname[pathEnd+1] = '\0';
- strcat(tname, "tempfile.pt");
- return &tname[0];
- }
-
- long pascal
- /* XTAG:fileSize */
- fileSize(fileNumber)
- int fileNumber;
- {
- return files[fileNumber].fileSize;
- }
-
- int pascal
- /* XTAG:closeFile */
- closeFile(fileId, ask)
- int fileId, ask;
- {
- extern unsigned char msgBuffer[];
- extern struct changeItem scrapBuffer;
- extern int addHandle;
- extern unsigned char *userMessages[];
-
- int i, writing;
- unsigned char *s, *tempFile;
- register struct openFile *ff;
-
- if( fileId == -1 )
- return 0;
-
- ff = &files[fileId];
-
- /* is this the last close? */
- if( --(ff->useCount) > 0 )
- return 0;
-
- /* see if we need to write the file */
- writing = 1;
- /* has the file changed? */
- if( ff->pieceList->nextPiece == NULL
- && ff->pieceList->file == ORIGFILE ) {
- if( ff->fileSize == ff->origFileSize )
- writing = 0;
- }
- if( ask == 2 ) /* quit and discard mode */
- writing = 0;
- /* do not write the messages file into itself */
- if( ff->origHandle == addHandle )
- writing = 0;
- /* see if we already saved these changes */
- if( !(ff->isChanged) )
- writing = 0;
- if( writing && ff->readOnly ) {
- sprintf(msgBuffer, userMessages[WASREADONLY], ff->origName);
- s = getInput(msgBuffer, "", 1);
- if( s == NULL )
- return -1;
- writing = 0;
- }
- if( writing ) {
- while( 1 ) {
- /* default place for s to point if no-ask mode */
- s = (unsigned char *)&i;
- if( ask ) {
- sprintf(msgBuffer, userMessages[YTOSAVE],
- ff->origName);
- s = getInput(msgBuffer, "y", 1);
- if( s == NULL ) {
- msg(userMessages[CLOSECANCELLED], 1);
- ++(ff->useCount);
- return -1;
- }
- } else
- s[0] = 'y';
- if( tolower(s[0]) == 'y' ) {
- tempFile = makeTempFor(ff->origName);
- sprintf(msgBuffer, userMessages[WRITINGFILE],
- ff->origName, ff->fileSize);
- msg(msgBuffer, 1);
- if( doWrite(fileId, tempFile) == 0 )
- return -1;
- sprintf(msgBuffer, userMessages[FILEWRITTEN],
- ff->origName, ff->fileSize);
- msg(msgBuffer, 1);
- writing = 1;
- break;
- } else if( tolower(s[0]) == 'n' ) {
- writing = 0;
- break;
- } /* else ask again */
- }
- }
-
- /* do the close */
- if( ff->origHandle == -1 ) {
- sprintf(msgBuffer, userMessages[NOTOPEN],
- ff->origName);
- msg(msgBuffer, 3);
- return 0;
- }
-
- /* see if the scrap points into this file */
- if( ff->origHandle == scrapBuffer.fileId && scrapBuffer.type == 0 )
- /* this call only copies the scrap text to the add file */
- /* it does not really do any insert (just using the code) */
- insScrap(0);
-
- /* invalidate any buffers allocated to this open file */
- if( ff->origHandle != addHandle )
- fidInvalid(ff->origHandle);
-
- /* close the original file for this open file */
- if( ff->origHandle != addHandle ) {
- i = closels(ff->origHandle);
- if( i != 0 ) {
- sprintf(msgBuffer, userMessages[CLOSEFAILED2],
- ff->origName, i);
- msg(msgBuffer, 3);
- }
- }
-
- /* free all the pieces */
- freePieces(ff->pieceList);
-
- /* indicate the file structure is free */
- ff->origHandle = -1;
-
- /* rename the saved file */
- if( writing == 1) {
- /* generate the .bak name and rename the original file */
- /* rename the temporary file we copied it into */
- s = makeBak(ff->origName);
- delete(s);
- if( renamels(ff->origName, s) ) {
- sprintf(msgBuffer, userMessages[REANMEFAILED2],
- ff->origName, s, tempFile);
- msg(msgBuffer, 3);
- }
- ff->bakMade = 1;
- if( renamels(tempFile, ff->origName) ) {
- sprintf(msgBuffer, userMessages[RENAMEFAILED3],
- tempFile, ff->origName, ff->origName, tempFile);
- msg(msgBuffer, 3);
- }
- }
- return 0; /* all ok */
- }
-