home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 10
/
Fresh_Fish_10_2352.bin
/
useful
/
util
/
edit
/
mg
/
src.lzh
/
amiga
/
fileio.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-05-23
|
14KB
|
638 lines
/*
* Name: MG 2a401 Commodore Amiga file I/O. Last edit: 05-May-88
* swalton@solar.stanford.edu Next-to-Last edit: 16-Dec-87
* mic@emx.utexas.edu Created: 23-Jul-86 mic@emx.utexas.edu
*
* Read and write ASCII files. All of the low level file I/O knowledge is here.
* Uses AmigaDOS standard I/O and does its own dynamic buffering; this seems
* to save about 2K worth of space in the executable image.
*/
#undef LATTICE
#undef MANX
#include "compiler.h"
#include "no_backup.h"
#include "no_startup.h"
#include "no_dir.h"
#include "no_dired.h"
#ifdef LATTICE
#include <stdlib.h>
#include <string.h>
#include <exec/types.h>
#endif
#include "use_arp.h"
#include "foob.h"
#include <exec/memory.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#ifdef USE_ARP
#include <arpfunctions.h>
#include <libraries/arpbase.h>
#else
#define FCHARS 32L
#endif
#ifdef LATTICE
#include <proto/all.h>
#else
#include <functions.h>
#endif
#undef TRUE
#undef FALSE
#include "def.h"
#include "line.h"
#include "buffer.h"
#ifdef ANSI
#undef EOF
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#endif
#ifndef NO_PROTO
char *mktemp PROTO((char *));
#endif
#ifdef LATTICE
#undef LATTICE
#include <dos.h>
#define isdirectory(x) (getfa(x) == 1)
#endif
#define NIOBUF 4096
static VOID FlushBuf PROTO((VOID));
static BPTR ffh = 0;
static UBYTE *iobuf;
static int ibufo, niobuf;
static LONG iostat, access_mode;
#ifdef MANX
extern char *strncpy(), *strncat(), *index(), *rindex();
#endif
#ifdef LATTICE
static void TackOn(char *path, char *file);
#define index strchr
#define rindex strrchr
#endif
#define getch() (ibufo == niobuf) ? FillBuf() : iobuf[ibufo++]
#define putch(c) {if (niobuf == NIOBUF) FlushBuf(); iobuf[niobuf++] = c;}
/*
* Open the Emacs internal file for reading.
*/
ffropen(fn)
char *fn;
{
if ((iobuf = AllocMem((ULONG) NIOBUF, 0L)) == NULL)
return (FIOERR);
if ((ffh = Open(fn, access_mode = MODE_OLDFILE)) == 0L) {
FreeMem(iobuf, (ULONG) NIOBUF);
return (FIOFNF);
}
ibufo = niobuf = 0;
return (FIOSUC);
}
/*
* Open a file for writing. Return TRUE if all is well, and FALSE on error
* (cannot create).
*/
ffwopen(fn)
char *fn;
{
if ((iobuf = AllocMem((ULONG) NIOBUF, 0L)) == NULL)
return (FIOERR);
if ((ffh = Open(fn, access_mode = MODE_NEWFILE)) == 0L) {
ewprintf("Cannot open file for writing");
FreeMem(iobuf, (ULONG) NIOBUF);
return (FIOERR);
}
niobuf = 0;
iostat = NIOBUF; /* pretend we wrote out a full buffer last
* time */
return (FIOSUC);
}
/*
* Close a file, flushing the output buffer. Should look at the status.
*/
ffclose()
{
if (access_mode == MODE_NEWFILE)
FlushBuf();
if (ffh)
(void) Close(ffh);
if (iobuf)
FreeMem(iobuf, (ULONG) NIOBUF);
return (FIOSUC);
}
/*
* Write a buffer to the already opened file. bp points to the buffer. Return
* the status. Check only at the newline and end of buffer.
*/
ffputbuf(bp)
struct buffer *bp;
{
register char *cp;
register char *cpend;
register struct line *lp;
register struct line *lpend;
lpend = bp->b_linep;
lp = lforw(lpend);
do {
cp = <ext(lp)[0]; /* begining of line */
cpend = &cp[llength(lp)]; /* end of line */
while (cp != cpend)
putch(*(cp++)); /* putch only evalutes its arg once */
lp = lforw(lp);
if (lp == lpend)
break; /* no implied newline on last line */
putch('\n');
} while (iostat > 0L);
if (iostat == -1L) {
ewprintf("Write I/O error");
return FIOERR;
}
return FIOSUC;
}
/*
* Read a line from a file, and store the bytes in the supplied buffer. Stop
* on end of file or end of line. When FIOEOF is returned, there is a valid
* line of data without the normally implied \n.
*/
ffgetline(buf, nbuf, nbytes)
register char *buf;
register int nbuf;
register int *nbytes;
{
register int c;
register int i;
i = 0;
while ((c = getch()) != EOF && (c & 0xFF) != '\n') {
buf[i++] = c;
if (i >= nbuf)
return FIOLONG;
}
if (c == EOF && (iostat == -1L)) {
ewprintf("File read error");
return FIOERR;
}
*nbytes = i;
return c == EOF ? FIOEOF : FIOSUC;
}
#ifndef NO_BACKUP
#include "backup_suffix.h"
/*
* Rename the current file into a backup copy, possibly after deleting the
* original file.
*/
fbackupfile(fname)
char *fname;
{
BPTR twiddle, lock;
char buffer[NFILEN];
if (!fname)
return FALSE;
(void) strncpy(buffer, fname, NFILEN - 1);
(void) strcat(buffer, BACKUP_SUFFIX);
lock = Lock(fname, (ULONG) EXCLUSIVE_LOCK); /* does file exist? */
if (!lock)
return (FALSE); /* nope, return error */
twiddle = Lock(buffer, (ULONG) EXCLUSIVE_LOCK);
if (twiddle) { /* delete old backup */
UnLock(twiddle);/* let it go */
if (!DeleteFile(buffer)) {
UnLock(lock);
return (FALSE);
}
twiddle = NULL;
}
/*
* rename file to backup name (after unlocking the file)
*/
UnLock(lock);
return (int) Rename(fname, buffer);
}
#endif /* NO_BACKUP */
#ifdef FOOB
#define DEFAULT_FOOB (0L)
FOOB
getfoob(fname)
char *fname;
{
struct FileInfoBlock *fib;
BPTR lock;
FOOB out;
if (fname == NULL)
return DEFAULT_FOOB;
if ((lock = Lock(fname, ACCESS_READ)) == NULL) /* New file? */
return DEFAULT_FOOB;
if ((fib = (struct FileInfoBlock *)
AllocMem(sizeof(struct FileInfoBlock), 0L)) == NULL) {
ewprintf("Couldn't get %d bytes", sizeof(struct FileInfoBlock));
UnLock(lock);
return DEFAULT_FOOB;
}
if (Examine(lock, fib))
out = fib->fib_Protection;
else {
ewprintf("Couldn't get protection bits for %s", fname);
out = DEFAULT_FOOB;
}
UnLock(lock);
FreeMem(fib, sizeof(struct FileInfoBlock));
return out;
}
void
putfoob(name, mask)
char *name;
FOOB mask;
{
SetProtection(name, mask & ~FIBF_ARCHIVE);
}
#endif
#ifndef NO_STARTUP
/*
* Return name of user's startup file. On Amiga, make it .mg in the current
* directory, then s:mg-startup
*/
static char startname[] = ".mg";
static char altstartname[] = "s:mg-startup";
char *
startupfile()
{
BPTR lock;
if (lock = Lock(startname, (ULONG) SHARED_LOCK)) {
UnLock(lock);
return (startname);
}
if (lock = Lock(altstartname, (ULONG) SHARED_LOCK)) { /* alternate */
UnLock(lock);
return (altstartname);
}
return (NULL);
}
#endif /* NO_STARTUP */
/*
* The string "fn" is a file name. Perform any required name adjustments,
* including conversion to a fully qualified path if NO_DIR isn't defined.
*/
extern char *MyDirName;
char *
adjustname(fn)
register char *fn;
{
#ifndef NO_DIR
static char fnb[MAXPATH];
BPTR lock;
unsigned long PathName();
void TackOn();
char *dup, *p;
if (!fn)
return fn;
if (!index(fn, ':')) { /* no device */
strcpy(fnb, MyDirName);
TackOn(fnb, fn);
if (!index(fn, '/')) /* completely bare name */
return fnb;
} else
strcpy(fnb, fn);
/*
* Else fn has some path components in it. We try to PathName the
* whole thing first, but since the file specified by fn may not
* exist, we PathName the leading part and TackOn the trailing part
* if it doesn't.
*/
if (lock = Lock(fnb, SHARED_LOCK)) {
if (PathName(lock, fnb, (long) MAXPATH) != 0) {
UnLock(lock);
return fnb;
}
ewprintf("adjustname: PathName() failed!");
UnLock(lock);
return fn;
}
if (!(p = rindex(fnb, '/')))
p = index(fnb, ':');
p++;
strcpy((dup = malloc(strlen(p) + 1)), p);
*p = '\0';
if (lock = Lock(fnb, SHARED_LOCK)) {
if (PathName(lock, fnb, (long) MAXPATH) != 0) {
UnLock(lock);
TackOn(fnb, dup);
free(dup);
return fnb;
}
ewprintf("adjustname: PathName() failed!");
UnLock(lock);
}
free(dup);
#endif
return fn; /* if all else fails */
}
/*
* Functions to read/write into the I/O buffer
*/
VOID
FlushBuf()
{
if (niobuf > 0) {
iostat = Write(ffh, iobuf, (long) niobuf);
niobuf = 0;
}
}
/*
* Fill up the input buffer and return the first character in it.
*/
int
FillBuf()
{
if ((iostat = Read(ffh, iobuf, (long) NIOBUF)) <= 0L)
return (EOF);
ibufo = 0;
niobuf = (int) iostat;
return (int) (iobu