
#include "V_s_lc.h"
#include "mem.h"

/*
* Note some facts about a newly-opened file. The nominal return value,
* r, is an index into the openfiles list.  We make a copy of the name,
* in case the caller wants to re-use the  space.   Note  that  we  are
* careful  to  free  the previous name, if it still exists, to prevent
* memory leaks; the close routines leave the  old  name  around  as  a
* relic  so that it can be used in messages.  This is a small waste of
* memory, but it has at times been useful after a file is closed.
*/
File* d_newfile(fl,f,n,m)
	int   fl;		/* Flags */
	int   f;		/* File number */
	char* n;		/* File name */
	char* m;		/* Message describing file */
{	File* r=0;		/* Index into openfiles list */
	int   i;
	Fenter("d_newfile");
	V6 "d_newfile(0%o,%d,\"%s\",\"%s\") ...",fl,f,N(n),N(m) D;
	if (Vlvl>5) d_chkfiles("before d_newfile");
	if (f > OPEN_MAX) {
		V2 "File f=%d >= OPEN_MAX=%d.",f,OPEN_MAX D;
		Fail;
	}
	while (openfilemax < f) {
		V6 "File %d descriptor must be created ...",f D;
		NewChunk(r,File,"openfile");
		if (openfilez) {
			V6 "File %d added to list ...",f D;
			openfilez->next = r;
		} else {
			V6 "File %d first in list ...",f D;
			openfiles = r;
		}
		openfilez = r;
		r->lfd = ++openfilemax;
	}
	for (i=0, r=openfiles; i!=f && r; i++, r = r->next)
		V6s "openfile %d: %lX lfd=%d flgs=%X \"%s\"",i,r,r->lfd,r->flgs,N(r->name.v) D;
		;
	if (!r) {
		V3 "Can't find File %d descriptor.",f D;
		Fail;
	}
	V6 "File %d descriptor is %lX.",f,r D;
	if (fl & File_REMOTE) {
		V3s "File %d is remote.",f D;
		V3s m_nothere D;
		r = 0;
		Fail;
	}
	V6s "File %d is local.",f D;
	if (! n) n = m_unknown;
	if (! m) m = n;
	MakStrMF(&r->name,n,-1,m);






	r->flgs = fl | File_OPEN;
	r->lfd  =
	r->rfd  = f;
	r->addr = 0;		/* No data so far */
	if (openfilemax < f)			/* Keep track of the highest open file */
		openfilemax = f;
	if (Vlvl>5) d_chkfiles("after d_newfile success");

	Fexit;
	return r;
fail:
	if (Vlvl>5) d_chkfiles("after d_newfile failure");
	V2 "### Failed for %s",Dsps(n,-1) D;
	Fexit;
	return 0;
}

File* d_openfile(f)
{	int   i;
	File* p;
	V6s "d_openfile(%d) ...",f D;
	if (Vlvl>5) d_chkfiles("before d_openfile");
	for (i=0, p=openfiles; i!=f && p; i++, p = p->next)
		V7s "openfile %d: %lX lfd=%d flgs=%X \"%s\"",i,p,p->lfd,p->flgs,N(p->name.v) D;
		;
	if ( p) V7s "d_openfile(%d)=%lX",f,p D;
	if (!p) V2s "d_openfile(%d) failed.",f D;
	if ( p) V6s "openfile %d: %lX lfd=%d flgs=%X \"%s\"",i,p,p->lfd,p->flgs,N(p->name.v) D;
	if (Vlvl>5) d_chkfiles("after d_openfile");
	return(i==f ? p : 0);
}

d_chkfiles(m)
	char*  m;
{	int    i;
	File*  p;
	for (i=0, p=openfiles; p; i++, p = p->next) {
		V7s "--- openfile %d: %lX lfd=%d flgs=%X \"%s\" [%s]",i,p,p->lfd,p->flgs,N(p->name.v),m D;
		if (p->lfd != i)
			V1 "### openfile %d: %lX lfd=%d flgs=%X \"%s\" [%s]",i,p,p->lfd,p->flgs,N(p->name.v),m D;
	}
	V6s "--- openfile list contains %d files.",i D;
}
