// 
// Miscellaneous support functions for Cassandra
// Copyright (c) 1989, 1990, 1991 by Jiro Nakamura. All Rights Reserved.
//
// misc.m
//
//	by Jiro Nakamura (jiro@shaman.com)
//
// RCS Information
// Revision Number->	$Revision: 2.6 $
// Last Revised->	$Date: 91/11/01 17:24:26 $
//
static char rcsid[] = "$Id: misc.m,v 2.6 91/11/01 17:24:26 jiro Exp Locker: jiro $";

#ifdef DEBUG
	#undef DEBUG
#endif

#import <stdio.h>
#import "cass.h"
#import <strings.h>
#import <appkit/Panel.h>       /* for NXRunAlertPanel */
#import <sys/file.h>
#import <libc.h>			/* for open(), close(), exit() */
#import "misc.h"
#import "errno.h"

// Function: 	fileOpen(filename, mode, message)
// Arguments:	char * filename -> name of file to be opened
//		char * mode	-> mode using fopen() (e.g. "r", "a+")
//		char * message	-> message to be shown if fopen() fails
// Description:	Opens the file <filename> with mode <mode>
//		using fopen(). If it is successful, a FILE *
//		is returned. If it fails, fileOpen tries
//		to create the file with creat() mode 0600.
//		If that fails too, it uses NXRunAlertPane()
//		to show <message>, then exit()s the program.
// Returns:	FILE * to open file
FILE *fileOpen(filename,mode,message)
char *filename, *mode, *message;
{
	FILE *fd, *fopen();

	#ifdef DEBUG
		fprintf(stderr,"fileOpened <%s> with mode %s\n",
				filename, mode);
	#endif

	if( (fd = fopen(filename, mode)) == NULL)
		{
		int ifd;
		char	dumbChar[5];
		
		// dumb references to some static constants, just
		// to avoid warning messages from the compiler (Garance)
		dumbChar[0] = rcsid[0];		// dumb de dumb

		fprintf(stderr,"%s: Creating file "
				"%s with mode %s....\n",
				PROGNAME, filename,mode);
		
		ifd = open( filename, O_CREAT, 0600);
		close(ifd);
		if( (fd = fopen(filename, mode)) == NULL)
			{
			NXRunAlertPanel("File Error",message,"Quit",NULL,NULL);
			exit(1);
			}
		}
	return fd;
}

// Seek file to this position
FILE *fileSeek(source, here, errormsg)
FILE *source;
int here;
char *errormsg;
{	
	#ifdef DEBUG
		fprintf(stderr,"Seeking to %d in fileSeek\n",here);
	#endif


	if(  here < 0)
		{
		fprintf(stderr,"%s: Error in fileSeek, "
			"cannot seek to negative number %d\n", 
			PROGNAME, here);
		NXRunAlertPanel("File Seek Error", 
			"Cannot seek to a negative number.",
			"OK",NULL,NULL);
		return NULL;
		}
	
	/* Seek to the correct position */
	if( fseek( source, (long) FILE_LEN * here, SEEK_SET) == -1) 	
		{		
		if( errno == EIO)
			{
			fprintf(stderr, "%s: I/O Error on read. ", PROGNAME);
			NXRunAlertPanel("Seek error", 
				"An IO error occured while seeking.",
				"OK",NULL,NULL);
			return NULL;
			}

		/* If we can't seek to the end because the file */
		/* is too short, then */
		/* seek to the end of file and add newlines*/			
		fseek(source, 0L, SEEK_END);		
		do
			{
			#ifdef DEBUG
				fprintf(stderr,"Looping: ftell(source) = "
					"%d \n",ftell(source));
			#endif

			fputc('\n', source);
			}
		while( ftell(source) < FILE_LEN * here + 5);
		
		/* Try again */
		if( fseek( source, (long) FILE_LEN * here, 0) == -1) 		
			{
			fprintf(stderr, 
			"%s: We have an error fseek()-ing to %d....\n"
			"%s: Error Numbers are as follows: errno = %d, EIO =%d"
			"%s: Calling procedure says: %s\n",
			PROGNAME, here, 
			PROGNAME, errno, EIO,
			PROGNAME, errormsg);

			NXRunAlertPanel( "Seek error", errormsg, 
				"Quit", NULL, NULL);
			fclose(source);
			exit(1);
			}
		}
	return source;
}

