/* @(#)testosu.c	19.1 (ESO-IPG) 02/25/03 14:33:06 */
/*===========================================================================
  Copyright (C) 1995 European Southern Observatory (ESO)
 
  This program is free software; you can redistribute it and/or 
  modify it under the terms of the GNU General Public License as 
  published by the Free Software Foundation; either version 2 of 
  the License, or (at your option) any later version.
 
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
 
  You should have received a copy of the GNU General Public 
  License along with this program; if not, write to the Free 
  Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, 
  MA 02139, USA.
 
  Corresponding concerning ESO-MIDAS should be addressed as follows:
	Internet e-mail: midas@eso.org
	Postal address: European Southern Observatory
			Data Management Division 
			Karl-Schwarzschild-Strasse 2
			D 85748 Garching bei Muenchen 
			GERMANY
===========================================================================*/
/*
 * Define _POSIX_SOURCE to indicate
 * that this is a POSIX program
 */
#define _POSIX_SOURCE 1

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#include <signal.h>
#include <osparms.h>

 /* 6: Unit status	*/
 
 struct unistat{
 	char *name;		/* Unit Name	*/
	long int usize;		/* Size in blocks, non meaningful for tapes */
 	int  blocksize;		/* Density / Sector size  */
 	int  density;		/* Density / Sector size  */
 	char device_type;	/* ? D T	*/
 };

int opentape(), closetape(), skiptape();
int wfmtape(), readtape(), writetape(), quit(), nothing();
int gfilenum(), skipblk(), gblknum(); 
void returnhere();

static char name[80] = "ns2!/dev/nrst2";

static int fd=0xffff;
static jmp_buf env;
static int verbose = 0;

struct msg_cmd {
	char *msg;
	int (*cmd)();
	} msg_cmd[] = {
	"\n0-	*****  MENU *****\n",		nothing,
	"1-	Open a tape device\n",		opentape,
	"2-	Close a tape device\n",		closetape,
	"3-	Read a sector\n",		readtape,
	"4-	Write a sector\n",		writetape,
	"5-	Close a file\n",		wfmtape,
	"6-	File seek \n",			skiptape,
	"7-	Get current file number\n",	gfilenum,
	"8-	Exit\n",			quit,
	(char *)0,				nothing
	};

main(argc, argv)
int argc;
char **argv;
{
	struct msg_cmd *m_c;
	int opt;
	char buff[80];

	if ( argc == 2 && strcmp(argv[1],"-v"))  verbose =1;
	/*
	 * I check now for DEVCAPFILE otherwise it will fail later in the
	 * osuopen. 
	 * A default place for DEVCAPFILE used to be:
	 *  $MIDASHOME/$MIDVERS/incl/devcap.dat
	 */
        if ( ! oshenv("DEVCAPFILE", (char *)0) ) {
                printf("Warning: variable DEVCAPFILE is undefined\n");
                /* ospexit(1); */
            }

	setjmp(env);
	signal(SIGINT,returnhere);
	while(1) {
		m_c = msg_cmd;
		while(m_c->msg != (char *)0)
			printf(m_c++->msg);
		printf("\nOption: ");
		if (!gets(buff))	break;
		if ((opt=atoi(buff)) >= (sizeof(msg_cmd)/sizeof(struct msg_cmd))) 
			printf("Bad option\n");
		else
			(*msg_cmd[opt].cmd)();
		}
	ospexit(0);
}

opentape()
{
	char aname[80], input[8];
	int den, mode;
	int pfd;

	printf("\nOPEN TAPE\n");
	printf("Enter name of device (%s): ",name);
	gets(aname);

        if (strlen(aname) != 0)
                strcpy(name,aname);

	printf("Enter open mode (2:READ_WRITE): ");
	mode=atoi(gets(input));
	if (strlen(input) == 0)
		mode=READ_WRITE;

	printf("Enter density of device (0): ");
	den=atoi(gets(input));

	if ((pfd = osuopen(name,mode,den)) == -1) {
		printf("Error opening %s, %s\n",
			name,osmsg());
		return;
		}
	fd=pfd;
	printf("OPEN %s succeded. \n",name);
}

closetape()
{
	printf("\nCLOSE TAPE\n");
	if (osuclose(fd) == -1) {
		printf("Error closing device, %s\n",osmsg());
		return;
		}
	printf("CLOSE succeded\n");
}

skiptape()
{
	char name[80];
	int ntm;
	long offset;
	int mode;
	int file_no;

	printf("Enter mode of addressing (0=FILE_START):");
	mode = atoi(gets(name));

	printf("Enter file to seek (0):");
	offset = atoi(gets(name));

	printf("\nSKIPPING TO FILE:%d IN MODE:%d\n",offset,mode);
	if ((file_no = osufseek(fd,offset,mode)) == -1) {
		printf("Error skipping to file %d in mode %d. %s\n",
			offset,mode,osmsg());
		return;
		}
	printf("SKIP succeded. Current file: %d\n",file_no);
}

wfmtape()
{
	printf("\nCLOSING A FILE\n");
	if (osufclose(fd) == -1) {
		printf("Error closing a file: %s\n",
			osmsg());
		return;
		}
	printf("CLOSING A FILE succeded\n");
}

writetape()
{
	char *pbuf;
	char name[80];
	int n_bytes;
	char pattern;
	int i;

	printf("\nWRITE A BUFFER\n");
	printf("Enter number of bytes to be written (1024): ");
	n_bytes = atoi(gets(name));
	if ( strlen(name) == 0)
		n_bytes=1024;

	if ((pbuf = malloc(n_bytes)) == (char *)0 ) { 
		printf("Max. memory allocation: %d bytes\n",n_bytes);
		return;
		}

	printf("Buffer allocated\n");
	printf("Enter pattern for buffer ('A'): ");
	if (strlen(gets(name)) == 0)
		pattern='A';
	else
		pattern=name[0];

	printf("Pattern=%c\n",pattern);

	for (i=0; i<n_bytes; i++)
		pbuf[i]=pattern;

/*	for(i=0; i<n_bytes; i++) 
/*		printf("%c ",pbuf[i]);
/*	getchar();
*/
	if (osuwrite(fd,pbuf,n_bytes) == -1) {
		printf("Error writing %d bytes, %s\n",
			n_bytes,osmsg());
		return;
		}
	printf("WRITE %d bytes succeded\n",n_bytes);
	free(pbuf);
}

readtape()
{
	char *pbuf;
	char name[80];
	int n_bytes, length;
	char pattern;
	int i;

	printf("\nREAD A BUFFER\n");
	printf("Enter number of bytes to be read (1024): ");
	n_bytes = atoi(gets(name));
	if ( strlen(name) == 0)
		n_bytes=1024;

	if ((pbuf = malloc(n_bytes)) == (char *)0 ) { 
		printf("Max. memory allocation: %d bytes\n",n_bytes);
		return;
		}

	printf("Buffer allocated\n");

	if ((length = osuread(fd,pbuf,n_bytes)) == -1) {
		printf("Error reading %d bytes, %s\n",
			n_bytes,osmsg());
		return;
		}

	printf("\nREAD %d bytes succeded.\n",length);
	if (length > 0) {
		printf("Pattern=%c\n",pbuf[0]);
		pattern=pbuf[0];
		if ( verbose )
		   for(i=0; i<length; i++) 
			if (pattern != pbuf[i])
				printf("Byte %d (%c) differs of pattern(%c)\n",
					i,pbuf[i],pattern);
		}
	free(pbuf);
}

gfilenum()
{
	int file_no;
	printf("\nGETTING CURRENT FILE NUMBER\n");
	if ((file_no = osuftell(fd)) == -1) {
		printf("Error getting current file number\n",
			osmsg());
		return;
		}
	printf("CURRENT FILE NUMBER: %d\n",file_no);
}

nothing()
{
}

void returnhere()
{
	longjmp(env,0);
}

quit()
{
	ospexit(0);
}
