Xinu7/contrib/distodt/src/odt.c

Compare this file to the similar file:
Show the results in this format:


/* 
 * odt.c - Connect the user's terminal to a backend machine
 * 
 * Author:	Shawn Oostermann/Jim Griffioen
 * 		Dept. of Computer Sciences
 * 		Purdue University
 * Date:	Thu Jun  9 22:02:03 1988
 *
 * Copyright (c) 1988 Shawn Oostermann/Jim Griffioen
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sgtty.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/file.h>

#include "../h/utils.h"
#include "../h/bed.h"
#include "../h/bmutils.h"
#include "../h/netutils.h"

extern char *getlogin();		/* get user id			*/

#define	STDOUT	1
#define	STDIN	0
#ifndef TRUE
#define TRUE	1
#define FALSE	0
typedef int	Bool;
#endif

#define BUFSIZE 100

int	flags;
struct	sgttyb	kttymode;		/* keyboard mode upon entry	*/
struct	sgttyb	cttymode;		/* changed keyboard mode	*/
int	baudrate;			/* rate line tty should be at	*/
int	timeout;			/* time keyboard can be idle	*/
int	pid;				/* process id of this process	*/
char	*class;				/* group of machines to use	*/
int	machnum;			/* number of requested machine	*/
char	*dev;
char	*lockfile;			/* name of lock file		*/


/*
 *---------------------------------------------------------------------------
 * main (csb, rgsb)
 *---------------------------------------------------------------------------
 */
main (csb, rgsb)
int csb;
char *rgsb[];
{
	int i;
	int sock;
	struct bm bm;
	int fdTcp;
	int len;
	int devfd;
	char *sb;
	int remoteport;
	int quit();
	char class[16];			/* class of machine desired	*/
	char femachine[MAXMACHINENAME];	/* front end machine to use	*/
	char bemachine[MAXMACHINENAME];	/* back end machine to use	*/
	struct genericreq *odtreq;	/* odt request structure	*/
	char unspecifiedclass;		/* user specified class?	*/

	if (csb > 3) {
		fprintf(stderr, "usage: odt [-cCLASS] [-mBACKENDMACHINE]\n");
		exit(1);
	}
	
	
	strcpy(class, DEFAULTCLASS);
	strcpy(femachine, "");
	strcpy(bemachine, "");
	unspecifiedclass = TRUE;

	for (i = 1; i < csb; i++) {
		if (strncmp(rgsb[i], "-c", 2) == 0) {
			strcpy(class, (char *) (rgsb[i]+2));
			unspecifiedclass = FALSE;
		}
		else if (strncmp(rgsb[i], "-m", 2) == 0) {
			strcpy(bemachine, (char *) (rgsb[i]+2));
		}
		else {
			fprintf(stderr, "unexpected argument '%s'\n", rgsb[i]);
			exit(1);
		}
	}
	
	if (obtainlock(class,femachine,bemachine,unspecifiedclass) != SYSOK) {
		if (strlen(bemachine) > 0)
		    fprintf(stderr, "machine %s is unavailable\n", bemachine);
		else if (strlen(class) > 0)
		    fprintf(stderr, "no machines in class %s available\n",
			    class);
		exit(1);
	}
	
	signal(SIGINT, quit);

	printf("using front end '%s':    Using backend '%s'\n",
	       femachine, bemachine);
	
	
	
	bm.ver = CURVER;
	sprintf(bm.cmd, "%d", REQ_ODT_CONNECT);
	odtreq = (struct genericreq *) bm.detail;
	sb = getlogin();
	strcpy(odtreq->uid, sb);
	if (gethostname(odtreq->hostid, MAXMACHINENAME) != 0) {
		strcpy(odtreq->hostid, "dunno");
		fprintf(stderr, "error getting local host name\n");
	}
	strcpy(odtreq->bename, bemachine);
	
	sock = ConnectUdp (femachine, KNOWN_UDP_PORT);
	
	if (bmsend (sock, &bm, lbm, 0) <= 0)
	    SysError ("send");
	
	len = bmrecv (sock, &bm, lbm, 0);
	if (len<=0) 
	    Error("recv(): response code %d\n",len);
	
	if (atoi(bm.cmd) != RESP_OK) {
		Error("recv(): bad response (%s) from daemon: '%s'\n",bm.cmd,bm.detail);
	}
	
	/* get the TCP port to use */
	remoteport = atoi(bm.detail);
	
	
	/*
	 * set up local terminal in cbreak mode
	 */
	if (ioctl(STDIN, TIOCGETP, &kttymode) < 0 ) {
		perror("Cannot set terminal modes");
		exit(1);
	}
	cttymode = kttymode;
	cttymode.sg_flags |= CBREAK;
	cttymode.sg_flags &= ~ECHO;
	cttymode.sg_flags &= ~CRMOD;
	if (ioctl(STDIN, TIOCSETP, &cttymode) < 0) {
		perror("Cannot set terminal modes");
		exit(1);
	}
	fdTcp = ConnectTcp(femachine, remoteport);
	
	STDINxTCP(fdTcp, STDIN);
	
	quit();
	
}

/*---------------------------------------------------------------------------
 * quit - exit odt
 *---------------------------------------------------------------------------
 */
quit()
{
	ioctl(STDIN, TIOCSETP, &kttymode);
	printf("\n");
	exit(0);
}


/*---------------------------------------------------------------------------
 * STDINxTCP - Take standard input and send it to BED process on frontend 
 *---------------------------------------------------------------------------
 */
STDINxTCP(fdTCP, fdStdin)
     int fdTCP, fdStdin;
{
	int bmaskRead;
	int bmaskResult;
	int zero = 0;
	int len;
	int esc;
	int idle;
	char buf[BUFSIZE];
	int i;
	
	bmaskRead = BITMASK(fdStdin) | BITMASK(fdTCP);	
	esc = 0;
	idle = 0;
	for (;;) {
		bmaskResult = bmaskRead;
		select(32, &bmaskResult, &zero, &zero, 0);
		
		if ((bmaskResult & BITMASK(fdTCP)) != 0) {
			len = read(fdTCP,buf,BUFSIZE);
			if (len <= 0) {
				if (len != 0)
				    fprintf(stderr,"Coupling: bad return from fdTCP read: %d\n",len);
				return;
			}
			if ( (len = write(fdStdin,buf,len)) <= 0)
			    SysError("Coupling: Bad return from fdStdin write");
		}
		if ((bmaskResult & BITMASK(fdStdin)) != 0) {
			len = read(fdStdin,buf,BUFSIZE);
			if (len <= 0) {
				if (len != 0)
				    fprintf(stderr,"Coupling: return from fdStdin read: %d\n",len);
				return;
			}
			idle = 0;
			for (i=0; i<len; ++i) {
				if ( esc ) {
					cttymode.sg_flags &= ~RAW;
					stty(fdStdin, &cttymode);
					esc = 0;
				}
				else if ( buf[i]=='\\' && esc==0 ) {
					cttymode.sg_flags |= RAW;
					stty(fdStdin,&cttymode);
					esc = 1;
				}
				
				if ( (len = write(fdTCP,buf+i,1)) <= 0) 
				    SysError("Coupling: bad return from fdTCP write");
			}
		}
	}
}