 
/******************************************************************************

	ZOpOut()

	This function creates (and opens) an output file.  The name of
the file to be created is pointed to by FBfBeg.  FBfPtr points to the
character following the last character of the file name.  The function must

	1.  return ERR_OFO if an output file is currently open
	2.  attempt to create (and open) the output file
	3.  return an error message if the creation attempt failed
	4.  set OFile to something other that -1 if the create worked

*****************************************************************************/

#include "ZPort.h"		/* define portability identifiers */
#include "ZFiles.h"		/* define file data block structures */
#include "DefTeco.h"		/* define general identifiers */
#include "DefError.h"		/* define identifiers for error messages */

EXTERN	char	FBfBeg[];	/* beginning of file specification buffer */
EXTERN	char	*FBfPtr;	/* pointer into file specification buffer */
EXTERN	BOOLEAN	IsOpnO[];
EXTERN	struct	OFDBST	OFiles[];

VOID	ErrMsg();		/* display an error message */



#ifdef UNKNOWN
DEFAULT ZOpOut(OfIndx)			/* open output file */
DEFAULT	OfIndx;				/* index into OFiles array */
{
	puts("Terminating in function ZOpOut.\n");
	exit(1);
}
#endif



#ifdef vax11c
#include "DefChars.h"	/* define identifiers for characters */
#include rmsdef		/* define RMS return status identifiers */
#include ssdef		/* define system service return identifiers */

VOID	lib$stop();		/* terminate image with stack dump */
int	sys$putmsg();		/* VAX/VMS "put message" system service */
int	sys$connect();		/* RMS CONNECT service */
int	sys$create();		/* RMS CREATE service */
VOID	ZDspCh();		/* display a character on the terminal */

EXTERN	struct	message_vector msgvec;


DEFAULT ZOpOut(OfIndx)			/* open output file */
DEFAULT	OfIndx;				/* index into OFiles array */
{
	char	ExpFBf[NAM$C_MAXRSS];	/* expanded filespec buffer */
	struct	FAB	*OF;
	struct	NAM	*ON;
	struct	RAB	*OR;
	int	status;

#if DEBUGGING
DbgInd+=2;if(DbgLvl>=1){DbgMsg();DbgDBf("ZOpOut: called with FBf = \"");
TypBuf(FBfBeg,FBfPtr);DbgDBf("\"\015\012");DbgROf();}
#endif

	if (IsOpnO[OfIndx])		/* if output file is open */
		{
		ErrMsg(ERR_OFO);	/* OFO = output file already open */
#if DEBUGGING
if(DbgLvl>=1)
{DbgMsg();DbgDBf("ZOpOut: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
		return(FAILURE);
		}

	ON = &OFiles[OfIndx].ONam;
	*ON = cc$rms_nam;		/* initialize NAM defaults */
	ON->nam$l_esa = ExpFBf;		/* expanded file spec buffer address */
	ON->nam$b_ess = sizeof ExpFBf;	/* expanded file spec buffer size */
	ON->nam$l_rsa = FBfBeg;		/* resultant file spec buffer address */
	ON->nam$b_rss = NAM$C_MAXRSS;	/* resultant file spec buffer size */

	OF = &OFiles[OfIndx].OFab;
	*OF = cc$rms_fab;		/* initialize FAB defaults */
	OF->fab$b_fac = FAB$M_PUT;	/* file access = write only */
	OF->fab$b_org = FAB$C_SEQ;	/* file organization = sequential */
	OF->fab$b_rat = FAB$M_CR;	/* carriage return record attribute */
	OF->fab$b_rfm = FAB$C_VAR;	/* variable length record format */
	OF->fab$b_shr = FAB$M_NIL;	/* no sharing */
	OF->fab$l_nam = ON;		/* address of NAM block */
	OF->fab$l_fna = FBfBeg;		/* file name address */
	OF->fab$b_fns = FBfPtr - FBfBeg;	/* file name size */

	OR = &OFiles[OfIndx].ORab;
	*OR = cc$rms_rab;		/* initialize RAB defaults */
	OR->rab$l_fab = OF;		/* address of associated FAB */
	OR->rab$b_rac = RAB$C_SEQ;	/* record access mode = sequential */

	status = sys$create(OF);		/* create the file */
	if (status != RMS$_NORMAL)
		{
		msgvec.msgcod = status;
		msgvec.rmsstv = OF->fab$l_stv;
		status = sys$putmsg(	&msgvec,/* message vector */
					0,	/* action routine */
					0);	/* facility name */
		if (status != SS$_NORMAL)
			lib$stop(status);
		ZDspCh(LINEFD);
#if DEBUGGING
if(DbgLvl>=1)
{DbgMsg();DbgDBf("ZOpOut: sys$create failed, returning FAILURE.\015\012");
DbgROf();}DbgInd-=2;
#endif
		return(FAILURE);
		}

	FBfPtr = FBfBeg + ON->nam$b_rsl;	/* resultant name length */

	status = sys$connect(OR);		/* connect RAB to FAB */
	if (status != RMS$_NORMAL)
		{
		msgvec.msgcod = status;
		msgvec.rmsstv = OR->rab$l_stv;
		status = sys$putmsg(	&msgvec,/* message vector */
					0,	/* action routine */
					0);	/* facility name */
		if (status != SS$_NORMAL)
			lib$stop(status);
		ZDspCh(LINEFD);
		status = sys$close(OF);	/* close the file */
#if DEBUGGING
if(DbgLvl>=1)
{DbgMsg();DbgDBf("ZOpOut: sys$connect failed, returning FAILURE.\015\012");
DbgROf();}DbgInd-=2;
#endif
		return(FAILURE);
		}

	IsOpnO[OfIndx] = YES;
#if DEBUGGING
if(DbgLvl>=1){DbgMsg();DbgDBf("ZOpOut: returning SUCCESS, FBf = \"");
TypBuf(FBfBeg,FBfPtr);DbgDBf("\"\015\012");DbgROf();}DbgInd-=2;
#endif
	return(SUCCESS);
}
#endif



#ifdef XENIX
/*
  XENIX does not have version numbers,  so we have to deal with creating
  ".bak" versions of files.  For output files,  this means that when the
  output file is opened,  we check if a file with the same name already
  exists.  If a file already exists,  then we open a temporary output file
  and,  when the file is closed,  the close routine will deal with renaming
  things to make them come out right.  If no file with the same name already
  exists,  then the output file can simply be opened.  The close routine
  will only rename files if a temporary file was created by this routine.
*/

DEFAULT	access();		/* standard C library function */
DEFAULT	creat();		/* standard C library function */
VOID	exit();			/* standard C library function */
char	*mktemp();		/* standard C library function */
FILE	*fdopen();		/* standard C library function */
char	*strcat();		/* standard C library function */
VOID	StCopy();		/* string copy */
VOID	ZDspBf();		/* display a buffer on the terminal */


DEFAULT ZOpOut(OfIndx)			/* open output file */
DEFAULT	OfIndx;				/* index into OFiles array */
{

#if DEBUGGING
char *DbgPtr;
DbgInd+=2;if(DbgLvl>=1){DbgMsg();DbgDBf("ZOpOut: called with FBf = \"");
TypBuf(FBfBeg,FBfPtr);DbgDBf("\"\015\012");DbgROf();}
#endif
	if (IsOpnO[OfIndx])		/* if output file is open */
		{
		ErrMsg(ERR_OFO);	/* OFO = output file already open */
#if DEBUGGING
if(DbgLvl>=1)
{DbgMsg();DbgDBf("ZOpOut: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
		return(FAILURE);
		}

	*FBfPtr = '\0';
	if (access(FBfBeg, 0) == 0)		/* if file already exists */
		{
		StCopy(OFiles[OfIndx].OFNam, "XXXXXX");
		mktemp(OFiles[OfIndx].OFNam);
		strcat(OFiles[OfIndx].OFNam, ".tmp");
		StCopy(OFiles[OfIndx].OTNam, FBfBeg);
		}
	else
		{
		StCopy(OFiles[OfIndx].OFNam, FBfBeg);
		OFiles[OfIndx].OTNam[0] = '\0';
		}

#if DEBUGGING
if(DbgLvl>=1){DbgMsg(); DbgDBf("ZOpOut: creating file \"");
DbgPtr=OFiles[OfIndx].OFNam;while(*DbgPtr)DbgPtr++;
TypBuf(OFiles[OfIndx].OFNam,DbgPtr);DbgDBf("\"\015\012");DbgROf();}
#endif
	OFiles[OfIndx].OFD = creat(OFiles[OfIndx].OFNam,0644);
	if (OFiles[OfIndx].OFD == -1)
		{
		ErrMsg(ERR_NRO);		/* NRO = no room for output */ 
#if DEBUGGING
if(DbgLvl>=1)
{DbgMsg();DbgDBf("ZOpOut: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
		return(FAILURE);
		}
	OFiles[OfIndx].OStrem = fdopen(OFiles[OfIndx].OFD, "w");
	IsOpnO[OfIndx] = YES;

#if DEBUGGING
if(DbgLvl>=1)
{DbgMsg();DbgDBf("ZOpOut: returning SUCCESS.\015\012");DbgROf();}DbgInd-=2;
#endif
	return(SUCCESS);
}
#endif
