/* * 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"); } } } }