/* @(#)testosx.c	19.1 (ES0-DMD) 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
===========================================================================*/

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.TYPE        Module
.NAME        testosx.c
.LANGUAGE    C
.AUTHOR      Carlos Guirao. IPG-ESO Garching
.CATEGORY    Tests of host operating system interfaces. 
.COMMENTS    This test exercises the functions of the module "osx".
	
.REMARKS     A hanged condition has been detected for this test. It happens
	     when a procces is waiting for data to come from a socket, and
	     the connection is already stablished with a sender. If the
	     sender, for any reason, denies the data, the procces will hang
	     forever (or CTRL-C). SIGALRM does not work for this porpose
	     because the system call "read" ignores it when there is a 
	     stablished connection.
.VERSION 1.1 05-Jul-1990   Implementation     C. Guirao
.ENVIRONMENT UNIX
------------------------------------------------------------*/

#include <stdio.h>
#include <setjmp.h>
#include <signal.h>
#include <osparms.h>

char *osmsg();

int opencom(), closecom(), readcom(), writecom(), getinfo();
int quit(), nothing();

static char host_name[] = "ns2";
/*static char name_default[] = "mtape"; */
static char name_default[] = "midserv";

static int fd=0xffff;
static jmp_buf env;

struct msg_cmd {
	char *msg;
	int (*cmd)();
	} msg_cmd[] = {
	"\n0-	*****  MENU *****\n",			nothing,
	"1-	Open a communication channel\n",	opencom,
	"2-	Close a communication channel\n",	closecom,
	"3-	Read from a channel\n",			readcom,
	"4-	Write into a channel\n",		writecom,
	"5-	Get info of a channel\n",		getinfo,
	"6-	Exit\n",			quit,
	(char *)0,				nothing
	};

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

main()
{
	struct msg_cmd *m_c;
	int opt;
	char buff[80];
	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)();
		}
}

opencom()
{
	char name[80], host[80], input[8];
	char *channame[2];
	int den, mode;
	int pfd;

	printf("\nOPEN COMMUNICATION CHANNEL\n");
	printf("Enter mode	(0:server local,   1:client local)\n");
	printf("          	(2:server network, 3:client network): ");
	mode=atoi(gets(input));
	if (strlen(input) == 0)
		mode=0;

	printf("\nEnter name of service (%s): ", name_default);
	channame[0]=name;
	gets(name);
	if (strlen(name) == 0)
		channame[0]=name_default;

	if (mode == 2) channame[1]="network";
	if (mode == 3) {
		printf("\nEnter host name (%s): ", host_name);
		channame[1]=host;
		gets(host);
		if (strlen(host) == 0)
			channame[1]=host_name;
		}

	if ((pfd = osxopen(channame,mode)) == -1) {
		printf("Error opening %s: %s\n", channame[0],osmsg());
		return;
		}
	fd=pfd;
	printf("OPEN %s succeded. \n",channame[0]);
}

closecom()
{
	printf("\nCLOSE COMMUNICATION CHANNEL\n");
	if (osxclose(fd) == -1) {
		printf("Error closing channel: %s\n",osmsg());
		return;
		}
	printf("CLOSE succeded\n");
}

readcom()
{
	char *malloc();
	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 (512): ");
	n_bytes = atoi(gets(name));
	if ( strlen(name) == 0)
		n_bytes=512;

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

	printf("Buffer allocated\n");

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

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

	printf("\nREAD %d bytes succeded.\n",length);

	for(i=0; i<length; i++) 
		printf("%c ",pbuf[i]);

/*
	if (length > 0) {
		printf("Pattern=%c\n",pbuf[0]);
		pattern=pbuf[0];
		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);
}

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

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

	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;

	if ((length=osxwrite(fd,pbuf,n_bytes,'C')) <= 0) {
		printf("Error writing %d bytes: %s\n", n_bytes,osmsg());
		return;
		}
	printf("WRITE %d bytes succeded\n",length);
	free(pbuf);
}

getinfo()
{
	printf("\nGET INFO OF A CHANNEL\n");
	switch (osxinfo(fd,0,0)) {
	case NODATA:
		printf("No data available.\n");
		break;
	case NOCONN:
		printf("No client connection yet.\n");
		break;
	case DATARDY:
		printf("Data ready to be read.\n"); 
		break;
	default:
		printf("Error getting info from channel: %s\n",osmsg());
		break;
	}
}

nothing()
{
}

quit()
{
	exit(0);
}
