home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GRIPS 2: Government Rast…rocessing Software & Data
/
GRIPS_2.cdr
/
dos
/
ncsa_tel
/
tel_2_2_
/
source
/
look.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-07-15
|
55KB
|
2,282 lines
/*
* LOOK.C
* User interface code for NCSA Telnet
****************************************************************************
* *
* NCSA Telnet for the PC *
* by Tim Krauskopf, VT100 by Gaige Paulsen, Tek by Aaron Contorer *
* *
* National Center for Supercomputing Applications *
* 152 Computing Applications Building *
* 605 E. Springfield Ave. *
* Champaign, IL 61820 *
* *
* This program is in the public domain. *
* *
****************************************************************************
* Revisions:
* 10/1/87 Initial source release, Tim Krauskopf
* 7/5/88 Version 2.2 Tim Krauskopf
*/
#define WINMASTER
#define USETEK
/* #define USERAS */
#define HTELNET 23
#ifndef USETEK
#define leavetek() 0
#endif
#include "stdio.h"
#include "whatami.h"
#include "signal.h"
#include "fcntl.h"
#include "nkeys.h"
#include "windat.h"
#include "hostform.h"
struct twin *creatwindow(),*newin;
FILE *tekfp;
int stand=0,
basetype = VTTYPE,
ftpact=0, /* ftp transfer is active */
rcpact=0, /* rcp transfer is active */
viewmode=0, /* What are we looking at? */
transok=1, /* is file transfer enabled? */
temptek, /* where drawings go by default */
indev,outdev, /* for copying tek images */
rgdevice=0, /* tektronix device to draw on */
vton=1,
capon=0, /* overall capture on or not */
foundbreak=0, /* trap Ctrl-C */
machparm=0;
unsigned char s[550],parsedat[128],
colors[NCOLORS] = {2,1,0x70,0}, /* base colors */
myipnum[4],
*neterrstring(),
*malloc(),
*blankline = {" "};
int breakstop(),errhandle();
long int time(),n_clicks(),lastt;
struct config def; /* Default settings obtained from host file */
struct machinfo *mp=NULL; /* Pointer to a machine information structure */
#define PSDUMP 128
main(argc,argv)
int argc;
char *argv[];
{
int i,j;
n_clear(); /* do you know where your BP is? */
n_cur(0,0);
n_window(0,0,23,79); /* vt100 size */
n_color(2);
n_puts("NCSA Telnet, reading configuration file . . .");
#define USAGE printf("\n\nUsage: telnet [-s] [-t] [-c color] [-h hostfile] [machinename] ...")
if (*argv[1] == '?') {
USAGE;
n_row();
n_puts("\n\n -c 172471 sets the basic color scheme for console screen");
n_puts(" -h file full path specification of host information file");
n_puts(" -s standalone (server) mode for rcp and ftp");
n_puts(" -t disable direct writes to screen");
exit(1);
}
machparm = 1000; /* large number */
/*
* work on parms
*/
for (i=1; i<argc; i++) { /* look at each parm */
if (*argv[i] == '-') {
switch ( *(argv[i]+1)) {
case 'c': /* set foreground color */
i++;
for (j=0; j < NCOLORS && *(argv[i]+j*2); j++)
colors[j] = hexbyte(argv[i]+j*2);
break;
case 's':
stand = 1;
break;
case 't': /* Disable direct writes to screen */
Scwritemode(0);
break;
case 'h':
Shostfile(argv[++i]); /* set new name for host file */
break;
default:
USAGE;
exit(1);
}
}
else {
if (i < machparm)
machparm = i; /* where first machine name is */
}
}
for (i=0; i < NPORTS; i++)
wins[i] = NULL; /* we are using no windows yet */
/*
* create console window for errors, informative messages, etc.
*/
if (0 > VSinit(30)) { /* initialize GPs virtual screens */
n_puts("Virtual screen initialization failed.");
exit(1);
}
if (NULL == (console = creatwindow())) {
n_puts("Console memory allocation failed");
exit(1);
}
strcpy(console->mname,"Console");
/*
* introductions on the console window
*/
i = console->vs;
RSvis(-1);
vprint(i,"\n\n Console messages:\r\n\nNCSA Telnet\r\n");
vhead(i);
/*
* initialize network stuff
*/
if (j = Snetinit()) {
wrest(console);
errhandle();
vprint(i,"Error initializing network or getting configuration file\r\n");
if (j == -2) /* RARP failure, special case */
netshut();
exit(1);
}
netgetip(myipnum); /* what is my ip number? */
Sgetconfig(&def); /* get information provided in hosts file */
#ifdef USETEK
/*
* install tektronix
*/
if (stmode())
tekinit(def.video);
#endif
#ifdef USERAS
if (!VRinit()) {
vprint(i,"Error initializing raster support\r\n");
}
#endif
/*
* Display my ethernet and IP address for the curious people
*/
pcgetaddr(&s[200],def.address,def.ioaddr);
sprintf(s,"My Ethernet address: %x:%x:%x:%x:%x:%x\r\n",s[200],s[201],
s[202],s[203],s[204],s[205]);
vprint(console->vs,s);
sprintf(s,"My IP address: %d.%d.%d.%d\r\n\n",
myipnum[0],myipnum[1],myipnum[2],myipnum[3]);
vprint(console->vs,s);
#ifdef MSC
signal(SIGINT,&breakstop); /* Microsoft intercept of break */
#else
onbreak(&breakstop); /* Lattice intercept of break */
#endif
Stask(); /* any packets for me? (return ARPs) */
/*
* With the parameters left on the command line, open a connection
* to each machine named. Start up all of the configuration on open
* connections.
*/
for (i = machparm; i < argc; i++)
addsess(argv[i]);
if (current == NULL) { /* special viewmode for server mode */
current = console; /* special enter sequence avoids flicker */
viewmode = 6;
}
wrest(current); /* paint the first session's screen */
while (AF3 != dosessions()) /* serve all sessions, events */
;
endall();
}
/************************************************************************/
/* vhead
* place the header for new sessions in.
*/
vhead(v)
int v;
{
vprint(v,"\r\nNational Center for Supercomputing Applications\r\n");
vprint(v,"NCSA Telnet for the PC version 2.2S\r\n");
vprint(v,"\nAlt-H presents a summary of special keys \r\n\n");
}
/************************************************************************/
/* dosessions
* dosessions is an infinite loop serving three sources of external
* input in order of precedence:
* - changes to the video display properties
* - keyboard strokes
* - network events
*
* What the user sees is top priority followed by servicing the keyboard
* and when there is time left over, looks for network events.
*
* viewmode is a state variable which can determine if the screen should
* be re-drawn, etc.
*/
dosessions()
{
int i,j,c,cl,dat,cvs;
unsigned int sw;
struct twin *t1;
unsigned char *p;
i = 0;
switch (viewmode) {
case 0: /* no special mode, just check scroll lock */
default:
if (n_scrlck()) { /* scroll lock prevents text from printing */
viewmode = 1;
i = n_row();
j = n_col();
c = n_color(current->colors[2]);
n_cur(24,60);
n_draw("* Scroll Lock *",16); /* status in lower left */
n_color(c);
n_cur(i,j);
}
/*
* This gives precedence to the keyboard over the network.
*/
while (0 <= (c = newkey(current))) /* do all key translations */
if (c == AF3)
return(AF3);
break; /* no special viewing characterisitics */
case 1: /* scrollock is active */
if (!n_scrlck()) {
VSsetrgn(current->vs,0,0,79,23);
viewmode = 0; /* set back if appropriate */
statline();
}
/*
* In scroll lock mode, take keys only for the scrollback,
* The scrollback routine will never block, so we keep servicing events.
*/
scrollback();
break;
case 2: /* console is visible */
viewmode = 9; /* check keypress before redrawing */
break;
case 3: /* help screen view1 */
case 4: /* help screen view2 */
while (0 <= (c = n_chkchar())) {
if (c == AF3)
return(AF3);
if (viewmode == 3 && c == 27) {
viewmode = 4;
help2(c);
}
else { /* restore view 0 */
if (c > 128)
dokey(current,c);
/* dokey might change view, if so, don't reset view 0 */
if (viewmode >= 3 && viewmode <= 4)
viewmode = 10;
}
}
break;
case 5: /* DOS screen view */
viewmode = 9; /* wait for keypress */
break;
case 6: /* server mode */
vprint(console->vs,
"\r\nServer mode, press ESC to exit or ALT-A to begin a session\r\n");
viewmode = 7;
case 7: /* server mode 2 */
j = n_chkchar();
switch (j) {
case 27:
vprint(console->vs,"\r\n\n Ending server mode \r\n");
return(AF3); /* leave the program */
break;
case ALTA:
if (!addsess(NULL)) { /* start up a new one */
viewmode = 10;
}
else {
current = console;
viewmode = 6;
}
break;
case -1:
break; /* no keypress */
default:
vprint(console->vs,
"\r\nYou must have an open session to use other commands.\r\n");
viewmode = 6;
break;
}
break;
case 8:
if (graphit()) /* graphics menu screen */
viewmode = 10;
break;
case 9: /* reset current screen on keypress */
if (0 < n_chkchar())
viewmode = 10;
break;
case 10: /* Display current screen */
wrest(current);
viewmode = 0; /* return to standard mode */
statline();
break;
}
/*
* Check for any relevant events that need to be handled by me
*/
if (0 < (i = Sgetevent(USERCLASS | CONCLASS | ERRCLASS, &cl, &dat))) {
sw = cl*256 + i; /* class and event combination */
cvs = console->vs;
switch (sw) {
case CONCLASS*256+CONOPEN:
/* a connection has just opened */
t1 = wins[dat]; /* where the window pointer is stored */
if (!t1)
break;
t1->sstat = '/'; /* connection status */
netpush(dat);
netwrite(dat,"\377\375\001\377\375\003",6); /* telnet negotiate */
if (current != t1) {
current = t1;
viewmode = 10;
}
break;
case CONCLASS*256+CONCLOSE: /* connection is closing */
if (0 < netqlen(dat))
netputuev(CONCLASS,CONCLOSE,dat); /* call me again */
/* drop through, process any data */
case CONCLASS*256+CONDATA:
if (viewmode) { /* not ready for it */
netputuev(CONCLASS,CONDATA,dat);
break;
}
t1 = wins[dat]; /* where the window pointer is stored */
if (!t1)
break;
if (inprocess(t1))
return(AF3);
break;
case CONCLASS*256+CONFAIL: /* can't open connection */
t1 = wins[dat]; /* where the window pointer is stored */
if (!t1)
break; /* this don't count */
vprint(cvs,"\r\nCan't open connection, timed out\r\n");
netclose(dat); /* close out attempt */
if (!t1->next) {
wrest(console);
return(AF3);
}
if (t1 == current) {
current = current->next;
viewmode = 10;
}
delwindow(t1,1);
statline();
break;
/*
* domain nameserver results.
*/
case USERCLASS*256+DOMFAIL: /* domain failed */
mp = Slooknum(dat); /* get machine info */
vprint(cvs,"\r\nDOMAIN lookup failed for: ");
if (mp && mp->hname)
vprint(cvs,mp->hname);
else if (mp && mp->sname)
vprint(cvs,mp->sname);
vprint(cvs,"\r\n");
break;
case USERCLASS*256+DOMOK:
mp = Slooknum(dat); /* get machine info */
if (mp) {
vprint(cvs,"\r\nDOMAIN lookup OK for: ");
/* print session name and host name */
if (mp->hname)
vprint(cvs,mp->hname);
if (mp->sname) {
vprint(cvs," - ");
vprint(cvs,mp->sname);
addsess(mp->sname);
}
else
addsess(mp->hname);
vprint(cvs,"\r\n");
viewmode = 10;
}
break;
/*
* FTP status events.
*/
case USERCLASS*256+FTPBEGIN: /* data connection */
ftpact = dat;
Sftpname(s); /* get name */
vprint(cvs,"FTP transferring: ");
vprint(cvs,s);
vprint(cvs,"\r\n");
ftpstart(ftpact+2,s);
lastt = n_clicks();
break;
case USERCLASS*256+FTPLIST: /* LIST or NLST */
vprint(cvs,"FTP directory beginning\r\n");
break;
case USERCLASS*256+FTPEND: /* data connection ending */
ftpact = 0;
statline();
vprint(cvs,"FTP transfer done\r\n");
break;
case USERCLASS*256+FTPCOPEN: /* command connection */
vprint(cvs,"FTP server initiated from host: ");
Sftphost(s);
if ((NULL == (mp = Slookip(s))) || (NULL == mp->sname))
sprintf(&s[4],"%d.%d.%d.%d\r\n",s[0],s[1],s[2],s[3]);
else
sprintf(&s[4],"%s\r\n",mp->sname);
vprint(cvs,&s[4]);
break;
case USERCLASS*256+FTPUSER: /* user name entered */
vprint(cvs,"FTP user ");
Sftpuser(s);
vprint(cvs,s);
vprint(cvs," login request\r\n");
break;
case USERCLASS*256+FTPPWOK: /* user password verified */
vprint(cvs,"FTP Password verified\r\n");
break;
case USERCLASS*256+FTPPWNO: /* user password failed */
vprint(cvs,"FTP Password failed verification\r\n");
break;
case USERCLASS*256+FTPCLOSE: /* command connection ends */
vprint(cvs,"FTP server ending session\r\n");
break;
case USERCLASS*256+RCPBEGIN: /* rcp starting */
vprint(cvs,"rcp file transfer\r\n");
rcpact = 1;
break;
case USERCLASS*256+RCPEND: /* rcp ending */
vprint(cvs,"rcp ending\r\n");
rcpact = 0;
break;
#ifdef USETEK
case USERCLASS*256+PSDUMP: /* dump graphics screen */
if (VGpred(indev,outdev)) {
if (dat) {
endump();
vprint(cvs,"Graphics writing finished\r\n");
wrest(console);
viewmode = 2;
}
}
else
netputevent(USERCLASS,PSDUMP,dat); /* remind myself */
break;
#endif
case ERRCLASS*256+ERR1: /* error message */
p = neterrstring(dat);
VSwrite(cvs,p,strlen(p));
VSwrite(cvs,"\r\n",2);
default:
break;
}
}
/*
* update the FTP spinner if we are in ftp
*/
else if (ftpact && (n_clicks() > lastt + 10)) {
ftpstart(ftpact+2,s);
lastt = n_clicks();
}
return(c);
}
/*********************************************************************/
/* inprocess
* take incoming data and process it. Close the connection if it
* is the end of the connection.
*/
inprocess(tw)
struct twin *tw;
{
int cnt;
cnt = netread(tw->pnum,s,64); /* get some from incoming queue */
if (cnt < 0) { /* close this session, if over */
netclose(tw->pnum);
if (tw->capon) {
fclose(tw->capfp); /* close the capture file */
tw->capon = capon = 0;
}
n_color(tw->colors[0]);
if (tw->next == NULL) /* if this is the last one */
return(-1); /* signal no sessions open */
#ifdef USETEK
leavetek(); /* make Tek inactive */
#endif
if (tw != current) {
wrest(tw);
}
n_puts("\nConnection closed, press a key . . .");
if (tw == current)
current = tw->next;
delwindow(tw,1);
viewmode = 9;
return(0);
}
if (cnt)
parse(tw,s,cnt); /* display on screen, etc.*/
return(0);
}
/*********************************************************************/
/* endall
* clean up and leave
*/
endall()
{
netshut();
n_cur(24,0); /* go to bottom of screen */
n_color(7);
n_draw(blankline,80); /* blank it out */
exit(0); /* return to DOS */
}
/*********************************************************************/
/* errhandle
* write error messages to the console window
*/
errhandle()
{
char *errmsg;
int i,j;
while (ERR1 == Sgetevent(ERRCLASS,&i,&j)) {
errmsg = neterrstring(j);
VSwrite(console->vs,errmsg,strlen(errmsg));
VSwrite(console->vs,"\r\n",2);
}
}
/*********************************************************************/
/* vprint
* print to a virtual screen
*/
vprint(w,s)
int w;
char *s;
{
VSwrite(w,s,strlen(s));
}
/*********************************************************************/
helpmsg() {
int i;
leavetek();
i = n_color(current->colors[0]);
n_clear();
n_cur(0,0);
n_puts("Keyboard usage for NCSA telnet: \n");
n_puts("Alt-A add a session Alt-Y Interrupt Process");
n_puts("Alt-N next session Alt-O Abort Output");
n_puts("Alt-M message screen Alt-Q Are you there?");
n_puts("Alt-E escape to DOS shell Alt-U Erase line");
n_puts("Alt-G graphics menu Alt-K Erase Kharacter");
n_puts("Alt-C toggle capture on/off Alt-X close connection");
n_puts("Alt-R reset VT102 screen HOME exit graphics mode");
n_puts("Alt-H this help screen Ctrl-HOME clear/enter graphics mode");
n_puts("ScrLock pause/restart screen (DO NOT use Ctrl-NumLock)");
n_puts("ScrLock enter/exit scroll-back mode");
n_puts("Alt-T start file transfer as if typed: ftp [internet address]");
n_puts("Alt-I send my internet address to host as if typed");
n_puts("Alt-S skip scrolling, jump ahead");
n_puts("Alt-P change a parameter, one of:");
n_puts(" color, capture file name, backspace, session name, screen mode");
n_puts("Alt-F3 abort program completely. STRONGLY discouraged");
n_puts("\n\nPress ESC for information page, space bar to return to session:");
n_color(i);
}
help2(c)
int c;
{
int i;
i = n_color(current->colors[0]);
n_clear();
n_cur(0,0);
n_puts("NCSA Telnet for the IBM PC and Macintosh version 2.2S");
n_puts("\nNational Center for Supercomputing Applications, University of Illinois");
n_puts("written by Tim Krauskopf, Gaige B. Paulsen, and Aaron Contorer\n");
#ifndef beta
n_puts("This program is in the public domain.");
n_puts("Please retain the following notice:");
n_puts("\n Portions developed by the National Center for Supercomputing Applications");
n_puts(" at the University of Illinois, Urbana-Champaign.");
#else
n_puts("Authorized beta test version - open to technical users at your own risk.");
n_puts("Please report all problems that you wish fixed before July 1");
n_puts("All rights reserved.");
#endif
n_puts("\n\nFor information or for disks and manuals (there is a handling fee),");
n_puts("contact NCSA at:");
n_puts("152 Computing Applications Building");
n_puts("605 E. Springfield Ave.");
n_puts("Champaign, IL 61820");
n_puts("\nbugs and suggestions to telbug@ncsa.uiuc.edu");
n_puts("\nPress space bar to return to session");
n_color(i);
}
/*********************************************************************/
/* parse
* Do the telnet negotiation parsing.
*
* look at the string which has just come in from outside and
* check for special sequences that we are interested in.
*
* Tries to pass through routine strings immediately, waiting for special
* characters ESC and 255 to change modes.
*/
#define STNORM 0
#define GOAHEAD 249
#define WILLTEL 251
#define WONTTEL 252
#define DOTEL 253
#define DONTTEL 254
#define ESCFOUND 5
#define IACFOUND 6
parse(tw,st,cnt)
struct twin *tw;
int cnt;
unsigned char *st;
{
int i,cv;
unsigned char *mark,*orig;
cv = console->vs;
orig = st; /* remember beginning point */
mark = st + cnt; /* set to end of input string */
netpush(tw->pnum);
/*
* traverse string, looking for any special characters which indicate that
* we need to change modes.
*/
while (st < mark) {
switch (tw->telstate) {
case ESCFOUND:
#ifdef USETEK
if (*st == 12) { /* esc-FF */
if (tw->termstate == VTEKTYPE) {
vprint(cv,"\n\r Entering Tek mode \n\r");
tw->termstate = TEKTYPE;
VGgmode(rgdevice);
VGuncover(temptek);
current=tw;
}
VGwrite(temptek,"\033\014",2);
orig = ++st; /* pass by ESC-FF in data */
tw->telstate = STNORM;
break;
}
#endif
#ifdef USERAS
if (*st == '^') { /* esc-^ */
tw->termstate = RASTYPE;
tw->telstate = STNORM;
current=tw;
VRwrite("\033^",2); /* echo ^ */
orig = ++st;
break;
}
#endif
parsewrite(tw,"\033",1); /* send the missing ESC */
tw->telstate = STNORM;
break;
case IACFOUND: /* telnet option negotiation */
if (*st == 255) { /* real data = 255 */
st++; /* real 255 will get sent */
tw->telstate = STNORM;
break;
}
if ( 248 < *st ) {
tw->telstate = *st; /* by what the option is */
st++;
break;
}
vprint(cv,"\n\r strange telnet option\r\n");
orig = st;
tw->telstate = STNORM;
break;
case GOAHEAD:
tw->telstate = STNORM;
orig = st;
break;
case DOTEL:
sprintf(parsedat," telnet option %d %d\r\n",tw->telstate,*st);
vprint(cv,parsedat);
if (*st != 3) { /* anything but suppress go-ahead */
sprintf(parsedat,"%c%c%c",255,WONTTEL,*st++);
netwrite(tw->pnum,parsedat,3); /* refuse it */
}
else if (!tw->igoahead) { /* suppress go-ahead */
sprintf(parsedat,"%c%c%c",255,WILLTEL,*st++);
netwrite(tw->pnum,parsedat,3); /* take it */
tw->igoahead = 1;
}
tw->telstate = STNORM;
orig = st;
break;
case DONTTEL:
sprintf(parsedat," telnet option %d %d\r\n",tw->telstate,*st++);
vprint(cv,parsedat);
tw->telstate = STNORM;
orig = st;
break;
case WILLTEL:
sprintf(parsedat," telnet option %d %d\r\n",tw->telstate,*st);
vprint(cv,parsedat);
tw->telstate = STNORM;
switch(*st++) {
case 3: /* suppress go-ahead */
if (tw->ugoahead)
break;
tw->ugoahead = 1;
sprintf(parsedat,"%c%c%c",255,DOTEL,3); /* ack */
netwrite(tw->pnum,parsedat,3);
break;
case 1: /* echo */
if (tw->echo)
break;
tw->echo = 1;
sprintf(parsedat,"%c%c%c",255,DOTEL,1); /* ack */
netwrite(tw->pnum,parsedat,3);
netwrite(tw->pnum,tw->linemode,strlen(tw->linemode));
tw->linemode[0] = '\0';
break;
default:
sprintf(parsedat,"%c%c%c",255,DONTTEL,*(st-1));
netwrite(tw->pnum,parsedat,3); /* refuse it */
}
orig = st;
break;
case WONTTEL:
sprintf(parsedat," telnet option %d %d\r\n",tw->telstate,*st);
vprint(cv,parsedat);
tw->telstate = STNORM;
switch(*st++) { /* which option? */
case 1: /* echo */
if (!tw->echo)
break;
tw->echo = 0;
sprintf(parsedat,"%c%c%c",255,DONTTEL,1);
netwrite(tw->pnum,parsedat,3); /* OK with us */
break;
default:
break;
}
orig = st;
break;
default:
tw->telstate = STNORM;
break;
}
/*
* quick scan of the remaining string, skip chars while they are
* uninteresting
*/
if (tw->telstate == STNORM) {
/*
* skip along as fast as possible until an interesting character is found
*/
while (st < mark && *st != 27 && *st < 255) {
if (!tw->binary)
*st &= 127; /* mask off high bit */
st++;
}
parsewrite(tw,orig,st-orig);
orig = st; /* forget what we have sent already */
if (st < mark)
switch (*st) {
case 255: /* telnet IAC */
tw->telstate = IACFOUND;
st++;
break;
case 27: /* ESCape code */
if (st == mark-1 || *(st+1) == 12 || *(st+1) == '^') {
tw->telstate = ESCFOUND;
}
st++; /* strip or accept ESC char */
break;
default:
vprint(cv," strange char > 128\r\n");
st++;
break;
}
}
} /* end while */
}
/*********************************************************************/
/* parsewrite
* write out some chars from parse
* Has a choice of where to send the stuff
*/
parsewrite(tw,dat,len)
struct twin *tw;
char *dat;
int len;
{
int i;
/*
* send the string where it belongs
* 1. Check for a capture file. If so, echo a copy of the string
* 2. Check for dumb terminal type, convert special chars if so
* 3. Check for Tektronix mode, sending Tek stuff
* 3b. check for raster color type
* 4. or, send to virtual screen anyway
*/
if (tw->capon) /* capture to file? */
fwrite(dat,len,1,tw->capfp);
/*
* raw mode for debugging, passes through escape sequences and other
* special characters as <27> symbols
*/
if (tw->termstate == DUMBTYPE) {
for (i=0; i < len ; i++,dat++)
if (*dat == 27 || *dat > 126) {
sprintf(parsedat,"<%d>",*dat);
VSwrite(tw->vs,parsedat,strlen(parsedat));
}
else
VSwrite(tw->vs,dat,1);
}
else {
#ifdef USETEK
if (tw->termstate == TEKTYPE) {
i = VGwrite(temptek,dat,len);
if (i < len) {
leavetek();
viewmode=10;
parsewrite(tw,dat+i,len-i);
}
}
else
#endif
#ifdef USERAS
if (tw->termstate == RASTYPE) {
i = VRwrite(dat,len);
if (i < len) {
tw->termstate = VTEKTYPE;
parsewrite(tw,dat+i,len-i);
}
}
else
#endif
VSwrite(tw->vs,dat,len); /* send to virtual VT102 */
}
}
/*********************************************************************/
breakstop()
{
foundbreak = 1;
return(0);
}
/*********************************************************************/
/* newkey
* filter for command key sequences
*/
newkey(t1)
struct twin *t1;
{
int c;
if (foundbreak) {
foundbreak = 0;
c = '\003'; /* ctrl-c */
}
else {
if (t1->echo)
c = n_chkchar(); /* a char available ?*/
else if (t1->halfdup) { /* half duplex */
c = n_chkchar();
if (c == 13) {
parse(t1,"\r\n",2); /* echo crlf */
vt100key(13);
c = 10;
} else if (c > 0 && c < 128)
parse(t1,&c,1); /* echo char */
}
else { /* line mode */
c = RSgets(t1->vs,t1->linemode,79);
if (c == 13) { /* pressed return */
parse(t1,"\r\n",2); /* echo the return */
strcat(t1->linemode,"\r\n");
netpush(t1->pnum);
netwrite(t1->pnum,t1->linemode,strlen(t1->linemode));
t1->linemode[0] = '\0';
c = 0;
}
else if (c > 0) { /* write string, pass c to command interp */
if (t1->linemode[0]) {
netpush(t1->pnum);
netwrite(t1->pnum,t1->linemode,strlen(t1->linemode));
t1->linemode[0] = '\0';
}
}
}
}
if (c <= 0)
return(c);
return(dokey(t1,c));
}
/************************************************************************/
/* dokey
* translates and sends keys and filters for command keys
*
*/
dokey(t1,c)
struct twin *t1;
int c;
{
int i;
switch (c) {
case 8:
c = t1->bksp; /* allows auto del instead of bs */
break;
case 13: /* different CR mappings */
vt100key(13);
vt100key(t1->crfollow);
c = 0;
break;
case 127:
c = t1->del; /* switch bs around, too */
break;
case THENUL: /* user wants the true NUL char */
c = 0;
netwrite(t1->pnum, &c, 1); /* write a NUL */
break;
case CTRLHOME: /* tek clear screen */
if (current->termstate != TEKTYPE) {
current->termstate = TEKTYPE;
VGgmode(rgdevice);
VGuncover(temptek);
}
VGwrite(temptek,"\033\014",2); /* clear storage and screen */
c = 0;
break;
case HOME: /* clear to text */
if (leavetek()) {
viewmode = 10;
c = 0;
}
break;
case ALTH: /* help display */
viewmode = 3;
helpmsg();
c = 0;
break;
case ALTP: /* change a parameter */
parmchange();
c = 0;
break;
case ALTR: /* reset screen values */
if (!leavetek()) {
if (current->capon) {
fclose(current->capfp);
current->capon = capon = 0;
}
VSreset(current->vs); /* reset's emulator */
}
wrest(current);
c = 0;
break;
#ifdef USETEK
case ALTG: /* graphics manipulation */
c = 0;
leavetek();
dispgr();
break;
#endif
case ALTE:
leavetek();
n_window(0,0,24,79);
i = n_color(current->colors[0]);
dosescape();
viewmode = 5;
n_color(i);
c = 0;
break;
case ALTC: /* toggle capture */
if (capon && current->capon) { /* already on */
capstat("Capture off");
fclose(current->capfp); /* close the capture file */
current->capon = capon = 0;
}
else if (!capon) { /* I want one */
FILE *Sopencap();
if (NULL == (current->capfp = Sopencap())) {
vprint(console->vs,"\r\nCannot open capture file ");
break;
}
capstat("Capture on ");
current->capon = capon = 1;
}
else {
vprint(console->vs,"\r\nAnother session has capture file open, cannot open two at once\r\n");
wrest(console);
viewmode=2;
}
c=0;
break;
case ALTI: /* my internet address */
sprintf(s,"%d.%d.%d.%d",myipnum[0],myipnum[1],myipnum[2],myipnum[3]);
netwrite(t1->pnum,s,strlen(s));
if (!t1->echo)
parse(t1,s,strlen(s)); /* echo the string */
c = 0;
break;
case ALTT: /* an ftp command */
if (Sneedpass())
strcpy(s,"ftp ");
else
strcpy(s,"ftp -n ");
sprintf(&s[strlen(s)],"%d.%d.%d.%d\r\n",
myipnum[0],myipnum[1],myipnum[2],myipnum[3]);
netwrite(t1->pnum,s,strlen(s));
if (!t1->echo)
parse(t1,s,strlen(s)); /* echo the string */
c = 0;
break;
case ALTQ: /* are you there? */
netpush(t1->pnum);
netwrite(t1->pnum,"\377\366",2);
c = 0;
break;
case ALTO: /* abort output */
netpush(t1->pnum);
netwrite(t1->pnum,"\377\365",2);
c = 0;
break;
case ALTY: /* interrupt */
netpush(t1->pnum);
netwrite(t1->pnum,"\377\364",2);
c = 0;
break;
case ALTU: /* erase line */
netpush(t1->pnum);
netwrite(t1->pnum,"\377\370",2);
c = 0;
break;
case ALTK: /* erase char */
netpush(t1->pnum);
netwrite(t1->pnum,"\377\367",2);
c = 0;
break;
case ALTA: /* add session */
c = 0;
if (0 > addsess(NULL)) { /* start up a new one */
vprint(console->vs,"\r\nPress any key to continue . . .");
viewmode = 9;
}
else
viewmode = 10;
break;
case ALTM:
c = 0;
leavetek();
wrest(console);
viewmode = 2; /* console view mode */
break;
case ALTN: /* session switch */
c = 0;
leavetek();
if (current->next == NULL) /* are we only one ? */
break;
current = current->next;
viewmode = 10;
break;
case ALTS: /* skip to end */
c = 0;
RSvis(0);
while (0 < (i = netread(t1->pnum,s,500)))
parse(t1,s,i);
viewmode = 10;
break;
case ALTX: /* close the connection */
leavetek();
n_puts("\n Are you sure you want to close the connection? Y/N");
c = nbgetch(); /* get the answer */
if (tolower(c) == 'y') {
n_puts("\n Attempting to close . . .");
netclose(t1->pnum);
Stask();
netputuev(CONCLASS,CONCLOSE,t1->pnum);
}
else
viewmode=10; /* redraw screen */
c = 0;
break;
case AF9:
statcheck();
break;
case AF3:
return(AF3);
break;
default:
break;
}
if (c > 0)
vt100key(c); /* send it, with VT100 translation */
return(c);
}
/**************************************************************************/
/* dispgr
* display graphics menu screen
*/
dispgr()
{
int c,i,j,k,l;
c = n_color(current->colors[0]);
n_clear();
n_cur(0,0);
n_puts("ALT-G Graphics menu");
n_puts("< Press the appropriate function key or ESC to resume >\n");
strcpy(s," F1 - Write postscript to a file called: ");
strcat(s,def.psfile);
n_puts(s);
n_puts( " F2 - Change postscript output file name\n");
strcpy(s," F3 - Write HPGL code to a file called: ");
strcat(s,def.hpfile);
n_puts(s);
n_puts( " F4 - Change HPGL output file name\n");
strcpy(s," F5 - Write Tektronix 4014 codes to a file called: ");
strcat(s,def.tekfile);
n_puts(s);
n_puts( " F6 - Change Tektronix output file name\n");
VGwhatzoom(temptek,&i,&j,&k,&l);
sprintf(s," View region is currently: %d,%d,%d,%d",i,j,k,l);
n_puts(s);
n_puts(" F7 - Set a new view region (Zoom, Pan)");
n_puts(" RETURN - draw picture on screen in current zoom factor\n");
n_puts(" Enter choice:");
viewmode = 8;
n_color(c);
}
/***************************************************************************/
/* dosescape
* escape to dos for processing
* put the connections to automated sleep while in DOS
*/
dosescape()
{
int i;
n_clear();
n_cur(0,0);
n_puts("Warning, some programs will interfere with network communication and can");
n_puts("cause lost connections. Do not run any network programs from this DOS shell.");
n_puts("Type 'EXIT' to return to NCSA Telnet");
/*
* invoke a put-to-sleep routine which calls netsleep every 8/18ths of a sec
* Also: disable ftp,rcp when asleep and suppress error messages
*/
if (ftpact || rcpact) {
n_puts("Please wait until file transfer is finished");
n_puts("\nPress any key to continue");
return(0);
}
tinst();
i = system("command"); /* call DOS */
tdeinst();
if (i < 0) {
n_puts("\n\nError loading COMMAND.COM");
n_puts("Make sure COMMAND.COM is specified under COMSPEC.");
n_puts("It must also be in a directory which is in your PATH statement.");
}
n_row();
n_puts("\nPress any key to return to telnet");
return(0);
}
/***********************************************************************/
/* creatwindow
* returns a pointer to a new window
*/
struct twin *creatwindow()
{
struct twin *p;
int i;
p = (struct twin *)malloc(sizeof(struct twin));
if (!p)
return(NULL);
p->pnum = -1;
p->telstate = 0;
if (vton)
p->termstate = basetype;
else
p->termstate = DUMBTYPE;
p->linemode[0] = 0;
p->echo = 1;
p->binary = 0;
p->ugoahead = 0; /* we want goahead suppressed */
p->igoahead = 0; /* we want goahead suppressed */
p->capon = 0;
p->next = NULL;
p->prev = NULL;
p->sstat = '*'; /* connection not opened yet */
if (mp == NULL) {
p->bksp = 127;
p->del = 8;
p->crfollow = 10;
p->halfdup = 0;
for (i=0; i<3; i++) /* start default colors */
p->colors[i] = colors[i];
i = VSnewscreen(0,0,80,0); /* create a new virtual screen */
}
else {
p->bksp = mp->bksp;
if (p->bksp == 127)
p->del = 8;
else
p->del = 127;
p->crfollow = mp->crmap;
p->halfdup = mp->halfdup;
p->colors[0] = mp->nfcolor[0] + (mp->nbcolor[0]<<4);
p->colors[2] = mp->bfcolor[0] + (mp->bbcolor[0]<<4);
p->colors[1] = mp->ufcolor[0] + (mp->ubcolor[0]<<4);
i = VSnewscreen(mp->bkscroll,1,80,0); /* create a new virtual screen */
if (i >= 0 && mp->vtwrap)
VSwrite(i,"\033[?7h",5); /* turn wrap on */
VSscrolcontrol(i,-1,mp->clearsave); /* set clearsave flag */
}
if (i < 0)
return(NULL);
p->vs = i;
screens[i] = p; /* we need to know where it is */
return(p);
}
/***********************************************************************/
wrest(t)
struct twin *t;
{
RSvis(t->vs);
statline(); /* done before, moves cursor */
VSredraw(t->vs,0,0,79,23); /* redisplay, resets cursor correctly */
}
/***************************************************************************/
statline()
{
struct twin *t1,*t2;
int wn,i,c,sm,rw,cl;
if (current == NULL || current == console || current->termstate == TEKTYPE)
return(0);
c = n_color(current->colors[0]); /* save current color */
if (current->sstat != '*')
current->sstat = 254; /* this is current one */
rw = n_row();
cl = n_col();
t1 = t2 = current;
wn = 0;
sm = scmode();
do {
n_cur(24,wn*18);
n_color(t1->colors[2]);
if (t1->sstat == 254 && t1 != current)
t1->sstat = 176;
n_putchar(t1->sstat);
n_putchar(' ');
i = strlen(t1->mname);
if (sm) {
n_cheat(t1->mname,i); /* machine name of connection */
n_cheat(blankline,16-i); /* fill out to 16 spaces */
}
else {
n_draw(t1->mname,i); /* machine name of connection */
n_draw(blankline,16-i); /* fill out to 16 spaces */
}
if (t1->next) /* if not the only window open */
t1 = t1->next;
wn++;
} while (t1 != t2 && wn < 4);
n_color(current->colors[0]);
n_cur(24,wn*18);
if (sm)
n_cheat(blankline,80-wn*18); /* fill to edge of screen */
else
n_draw(blankline,80-wn*18); /* fill to edge of screen */
n_color(c);
n_cur(rw,cl);
}
/***********************************************************************/
/* inswindow
* insert a window into the circular linked list
*
* current is used as a reference point for the new entry, the new entry
* is put next in line past "current"
*/
inswindow(t,wtype)
struct twin *t;
int wtype;
{
struct twin *p,*q;
/*
* put it into the port number array
*/
if (wtype)
wins[t->pnum] = t;
/*
* check for the NULL case for current.
*/
if (current == NULL || current == console) {
current = t;
statline();
return(0);
}
p = current; /* find surrounding elements */
if (p->prev == NULL) { /* only one now, we are adding 2nd */
t->next = p;
t->prev = p;
p->next = t;
p->prev = t;
}
else { /* adding third or more */
q = p->next; /* find next one */
t->prev = p;
t->next = q; /* insert it as next after current */
q->prev = t;
p->next = t;
}
}
/***********************************************************************/
/* delwindow()
* take a window out of the linked list
*/
delwindow(t,wtype)
struct twin *t;
int wtype;
{
struct twin *p,*q;
if (wtype)
wins[t->pnum] = NULL; /* take out of array */
p = t->prev;
q = t->next;
if (p == NULL) { /* is only node */
freewin(t);
current = console;
return(0);
}
if (p == q) { /* two in list */
p->next = NULL;
p->prev = NULL;
}
else {
q->prev = p;
p->next = q; /* merge two links */
}
freewin(t); /* release the space */
return(0);
}
/************************************************************************/
/* freewin
* deallocate and detach all associated memory from a window
*/
freewin(t)
struct twin *t;
{
VSdetatch(t->vs);
free(t);
return(0);
}
/************************************************************************/
/*
* hexbyte
* return a byte taken from a string which contains hex digits
*/
hexbyte(st)
char *st;
{
int i;
if (*st >= 'A')
i = ((*st|32)-87)<<4;
else
i = (*st-48)<<4;
st++;
if (*st > 'A')
i |= (*st | 32)-87;
else
i += (*st-48);
return(i);
}
/***********************************************************************/
/* tekinit
* tektronix initialization
*/
#ifdef USETEK
tekinit(dev)
char *dev;
{
int i;
if (strlen(dev) < 1 )
return(0);
if (0 > VGinit()) {
vprint(console->vs,"\r\nCannot initialize Tektronix driver\r\n");
return(-1);
}
else
vprint(console->vs,"\r\nTektronix initialized\r\n");
if (!strcmp(dev,"no9"))
rgdevice = 4;
else if (!strcmp(dev,"ega"))
rgdevice = 1;
#ifdef why
else if (!strcmp(dev,"ps"))
rgdevice = 2;
and the hplot is dev 6
#endif
else if (!strcmp(dev,"hercules"))
rgdevice = 3;
else if (!strcmp(dev,"cga") || !strcmp(dev,"pga"))
rgdevice = 5;
else
rgdevice = 0; /* null device */
basetype = VTEKTYPE;
temptek = VGnewwin(rgdevice); /* default for drawing */
return(0);
}
/***********************************************************************/
/* function to write to file
*/
fdump(str)
char *str;
{
fputs(str,tekfp);
}
fdumpc(c)
char c;
{
fputc(c,tekfp);
}
endump()
{
VGclose(outdev);
if (indev != temptek) {
VGclose(indev);
if (tekfp) {
fclose(tekfp);
tekfp = NULL;
}
}
}
/***********************************************************************/
/* graphit
* Get some user choices and execute them
*/
graphit()
{
int i,j,k,l,c;
c = n_chkchar();
if (c == 27)
return(1);
if (c < 0)
return(0);
switch (c) {
case F2:
case F4:
case F6: /* prompting for file name */
n_puts("\nEnter new file name:");
nbgets(s,50);
if (s[0] && s[0] != ' ') {
switch (c) {
case F2:
Snewpsfile(s);
break;
case F4:
Snewhpfile(s);
break;
case F6:
Snewtekfile(s);
break;
}
Sgetconfig(&def);
}
dispgr(); /* leave in graphit mode */
return(0);
break;
case F1: /* postscript dump */
if (*def.psfile == '+') {
if (NULL == (tekfp = fopen(&def.psfile[1],"a")))
return(1);
fseek(tekfp,0L,2); /* to end */
}
else if (NULL == (tekfp = fopen(def.psfile,"w")))
return(1);
RGPoutfunc(&fdump); /* set function */
outdev = VGnewwin(2);
indev = temptek;
temptek = VGnewwin(rgdevice);
VGgmode(2);
VGzcpy(indev,temptek);
VGzcpy(indev,outdev);
VGuncover(outdev);
VGpage(outdev);
if (VGpred(indev,outdev))
endump();
else
netputevent(USERCLASS,PSDUMP,1); /* remind myself */
return(1);
break;
case F3: /* HPGL dump */
if (*def.hpfile == '+') { /* append feature */
if (NULL == (tekfp = fopen(&def.hpfile[1],"a")))
return(1);
fseek(tekfp,0L,2);
}
else if (NULL == (tekfp = fopen(def.hpfile,"w")))
return(1);
RGHPoutfunc(&fdump); /* set function */
outdev = VGnewwin(6);
indev = temptek;
temptek = VGnewwin(rgdevice);
VGgmode(6);
VGzcpy(indev,temptek);
VGzcpy(indev,outdev);
VGuncover(outdev);
VGpage(outdev);
if (VGpred(indev,outdev))
endump();
else
netputevent(USERCLASS,PSDUMP,1); /* remind myself */
return(1);
break;
case F5: /* tektronix dump */
if (*def.tekfile == '+') {
if (NULL == (tekfp = fopen(&def.tekfile[1],"ab")))
return(1);
fseek(tekfp,0L,2);
}
else if (NULL == (tekfp = fopen(def.tekfile,"wb")))
return(1);
fputs("\033\014",tekfp);
VGdumpstore(temptek,&fdumpc);
fclose(tekfp);
return(1);
break;
case F7: /* tek view region */
n_puts("\nEnter 0-4095 for lower left xy, upper right xy.");
n_puts("\nExample: 0,0,4095,3119 is full view. (default if you leave it blank)");
nbgets(s,30);
if (4 != sscanf(s,"%d,%d,%d,%d",&i,&j,&k,&l))
VGzoom(temptek,0,0,4096,3119);
else
VGzoom(temptek,i,j,k,l);
dispgr(); /* leave in graphit mode */
return(0);
break;
case 13:
current->termstate = TEKTYPE;
VGgmode(rgdevice);
VGuncover(temptek);
outdev = temptek; /* redraw to itself */
indev = temptek;
tekfp = NULL;
if (!VGpred(indev,outdev))
netputevent(USERCLASS,PSDUMP,0); /* remind myself */
viewmode = 0; /* normal logon state */
break;
default:
break;
}
return(0);
}
#endif
/***********************************************************************/
/* menu support
* New 5/22/88 - TK
* Provide menus with a reasonable user interface for the user to
* select colors or other parameters.
*
* This menu system provides two types of entries.
* 1. Up to nine static choices, 0-8. Each static choice is encoded
* into the data structure and automatically rotated by the user.
* The user cannot select an illegal value.
* 2. A string choice. A maximum string length is honored.
* There must be at least 20 characters open for each field, longer
* if the field is longer. Static choices cannot be longer than 20 chars.
*
*/
/*
* structure for the menu entries
*/
struct pt {
int posx,posy, /* row and col position on screen for field */
choice, /* which is the currently visible selection */
replen; /* length of reply if a string is allowed to be entered */
char *vals[9]; /* pointers to the actual choices */
};
#define LO 5
struct pt pc[] = {
/* session colors */
{LO+0,44,0,0,"black","blue","green","cyan","red","magenta","yellow","white",NULL},
{LO+1,44,0,0,"black","blue","green","cyan","red","magenta","yellow","white",NULL},
{LO+2,44,0,0,"black","blue","green","cyan","red","magenta","yellow","white",NULL},
{LO+3,44,0,0,"black","blue","green","cyan","red","magenta","yellow","white",NULL},
{LO+4,44,0,0,"black","blue","green","cyan","red","magenta","yellow","white",NULL},
{LO+5,44,0,0,"black","blue","green","cyan","red","magenta","yellow","white",NULL},
/* things which also apply to this session */
{LO+6,44,0,0,"Local echo","Remote echo",NULL},
{LO+7,44,1,0,"Backspace","Delete",NULL},
{LO+8,44,0,20,NULL," ",NULL},
{LO+9,44,0,0,"VT102 and Tek4014","Dumb TTY","VT102 only",NULL},
/* things which apply over all of telnet */
{LO+11,44,0,35,NULL," ",NULL},
{LO+12,44,1,0,"Use BIOS","Direct to screen",NULL},
{LO+13,44,0,0,"Disabled","Enabled",NULL},
{LO+0,0}
};
/************************************************************************/
/* menuit
* draw the current line at the required position.
* If the field length (replen) is longer than 20 chars, fill in the
* entire field width. All fields are padded with spaces to their
* length when printed, but stored without padding.
*/
menuit(p,n)
struct pt p[];
int n;
{
int i;
char fmt[12];
n_cur(p[n].posx,p[n].posy);
if ((i = p[n].replen) < 20) /* i = larger of replen and 20 */
i = 20;
sprintf(fmt,"%%-%d.%ds",i,i); /* create format string */
sprintf(s,fmt,p[n].vals[p[n].choice]); /* put out value */
n_puts(s);
}
/************************************************************************/
/* makechoice
* Allow the user to travel between choices on the screen, selecting
* from a list of legal options.
* Arrow keys change the selections on the screen. The data structure
* must be set up before entering this procedure.
*/
makechoice(p,maxp,spec)
struct pt p[];
int maxp,spec;
{
int i,oldln,ln,c;
oldln = ln = 0;
n_color(7);
for (i=1; i<maxp; i++) /* print the opening selections */
menuit(p,i);
/*
* For each keystroke, repaint the current line and travel around the
* data structure until the exit key is hit.
*/
do {
if (oldln != ln) {
n_color(7); /* re-write old line in normal color */
menuit(p,oldln);
}
n_color(0x70);
menuit(p,ln); /* write the current line in reverse */
if (spec)
makespecial(); /* display special requirements */
n_cur(p[ln].posx,p[ln].posy); /* reset cursor to current entry */
oldln = ln;
c = nbgetch();
switch (c) { /* act on user's key */
case CURUP:
if (ln)
ln--;
else
ln = maxp-1;
break;
case CURDN: /* up and down change current field */
if (++ln >= maxp)
ln = 0;
break;
case PGUP:
case HOME:
ln = 0;
break;
case PGDN:
case ENDKEY:
ln = maxp-1;
break;
case 32: /* space, tab and arrows change field contents */
case 9:
case CURRT:
i = ++p[ln].choice; /* if blank or non-existant, reset to 0 */
if (!p[ln].vals[i] || !(*p[ln].vals[i]) || ' ' == *p[ln].vals[i])
p[ln].choice = 0;
break;
case CURLF:
if (p[ln].choice)
p[ln].choice--;
else { /* if at zero, search for highest valid value */
i = 0;
while (p[ln].vals[i] && *p[ln].vals[i] && ' ' != *p[ln].vals[i])
i++;
if (i)
p[ln].choice = i-1;
}
break;
case 8:
case 21:
case 13:
/* BS, Ctrl-U, or return */
/*
* if allowed, the user can enter a string value.
* prepare the field, by printing in a different color to set it apart.
*/
if (p[ln].replen) {
p[ln].choice = 1;
n_color(1); /* underline color */
n_cur(p[ln].posx,p[ln].posy);
for (i=0; i<p[ln].replen; i++) /* blank out field */
n_putchar(' ');
n_cur(p[ln].posx,p[ln].posy);
c = nbgets(p[ln].vals[1],p[ln].replen);
}
break;
default:
break;
}
} while (c != F1 && c != F10 && c != 27);
return((c == F1) || (c == 27));
}
/************************************************************************/
/* makespecial
* Apart from standard menuing, we want to show an example of what the
* text is going to look like in each of the three attributes.
*/
makespecial()
{
n_cur(LO-1,15);
n_color(pc[0].choice + (pc[1].choice <<4));
n_puts("normal");
n_cur(LO-1,25);
n_color(pc[2].choice + (pc[3].choice <<4));
n_puts("reverse");
n_cur(LO-1,35);
n_color(pc[4].choice + (pc[5].choice <<4));
n_puts("underline");
}
/************************************************************************/
/* parmchange
* ALT-P from the user calls this routine to prompt the user for
* telnet parameter values.
* Set up the menuing system with the current values for this session.
* Call the menuing routines, then analyze the results when it returns.
*
* Affects the settings of:
* session color, name, local echo, backspace/del, terminal type
* overall file transfer enable, capture file name, screen access method
*
*/
parmchange()
{
int i,c,colsave;
/*
* set up the screen for the menus
* Positions of text interlock with fields of menu routines
*/
leavetek();
colsave = n_color(7);
n_clear();
n_cur(0,0);
n_puts("ALT-P Parameter menu ");
n_puts(" < Select parameters, F1 to accept, ESC to leave unchanged >\n");
n_puts(" --------------- Color setup and session parameters ----------------- ");
n_puts(" Text: ");
n_puts(" Normal Foreground (nfcolor) - ");
n_puts(" Normal Background (nbcolor) - ");
n_puts(" Reverse Foreground (rfcolor) - ");
n_puts(" Reverse Background (rbcolor) - ");
n_puts(" Underline Foreground (ufcolor) - ");
n_puts(" Underline Background (ubcolor) - ");
n_puts(" Use remote echo or local echo - ");
n_puts(" Backspace key sends - ");
n_puts(" Session name *>");
n_puts(" Terminal type - ");
n_puts(" -------------- Parameters which apply to all sessions -------------- ");
n_puts(" Capture file name *>");
n_puts(" Screen mode (for BIOS compatibility) - ");
n_puts(" File transfer is - ");
n_puts("\n\nUse arrow keys to select, Enter clears changeable field (*>)");
/*
* set values for menus from our telnet-stored values
*/
i = current->colors[0]; /* session colors */
pc[0].choice = i & 15;
pc[1].choice = i >> 4;
i = current->colors[2];
pc[2].choice = i & 15;
pc[3].choice = i >> 4;
i = current->colors[1];
pc[4].choice = i & 15;
pc[5].choice = i >> 4;
pc[6].choice = current->echo;
if (current->bksp == 8) /* backspace setting */
pc[7].choice = 0;
else
pc[7].choice = 1;
pc[8].vals[0] = current->mname; /* session name */
pc[9].choice = current->termstate - 1; /* terminal type */
pc[10].vals[0] = def.capture; /* capture file name */
pc[11].choice = scmode(); /* screen write mode */
pc[12].choice = transok; /* filetransfer enable */
if (makechoice(&pc,13,1)) { /* call it and check the results */
/*
* Work on results, only if user pressed 'F1', if ESC, this is skipped.
*
*
* check for new capture file name
*/
if (pc[10].choice) {
strcpy(s,pc[10].vals[1]);
if (s[0] && s[0] != ' ') { /* no NULL names */
Snewcap(s);
Sgetconfig(&def);
}
*pc[10].vals[1] = 0;
pc[10].choice = 0;
}
/*
* check for new screen mode, BIOS or not
*/
if (pc[11].choice != scmode())
Scwritemode(pc[11].choice); /* set to whatever choice is */
/*
* check whether to enable or disable file transfers
*/
if (pc[12].choice != transok) {
transok = pc[12].choice;
Sftpmode(transok);
Srcpmode(transok);
}
/*
* check remote or local echo mode
*/
if (pc[6].choice != current->echo) {
if (current->echo = pc[6].choice) { /* assign = is on purpose */
sprintf(s,"%c%c%c",255,DOTEL,1); /* telnet negotiation */
netpush(current->pnum);
netwrite(current->pnum,s,3);
}
else {
sprintf(s,"%c%c%c",255,DONTTEL,1);
netpush(current->pnum);
netwrite(current->pnum,s,3);
}
}
/*
* check function of backspace or delete
*/
if (pc[7].choice) {
current->bksp = 127; /* backspace/delete are swapped */
current->del = 8;
}
else {
current->bksp = 8; /* are normal */
current->del = 127;
}
/*
* check new session name
*/
if (pc[8].choice) {
strcpy(s,pc[8].vals[1]);
if (s[0] != ' ' && s[0]) { /* limit of 14 chars stored */
strncpy(current->mname,s,15);
current->mname[14] = 0;
}
*pc[8].vals[1] = 0;
pc[8].choice = 0;
}
/*
* check terminal type
*/
if (pc[6].choice != current->termstate-1)
current->termstate = pc[9].choice + 1;
/*
* assign new colors
*/
i = pc[0].choice + (pc[1].choice <<4); /* normal color */
if (i != current->colors[0]) {
current->colors[0] = i;
RSsetatt(127,current->vs); /* seed the current screen */
n_color(current->colors[0]); /* seed ncolor */
}
current->colors[1] = pc[4].choice + (pc[5].choice <<4);
current->colors[2] = pc[2].choice + (pc[3].choice <<4);
}
/*
* go back to telnet
*/
n_color(colsave);
wrest(current);
}
/*************************************************************************/
/* addsess
* Add a session to a named machine, or prompt for a machine to be named.
*/
addsess(st)
char *st;
{
int i,new,cv;
struct twin *newin;
leavetek();
cv = console->vs;
if (st == NULL) { /* no machine yet */
wrest(console);
vprint(cv,"\n\r\nEnter new machine name/address, ESC to return: \r\n");
s[0] = '\0';
while (0 >= (i = RSgets(cv,s,70)))
Stask();
if (i == 27 || !s[0])
return(1);
vprint(cv,"\r\n\n"); /* skip down a little */
st = s; /* make a copy of the pointer to s */
}
mp = Sgethost(st); /* gain access to host information */
errhandle();
if (!mp) {
if (Sdomain(st) > 0)
vprint(cv,"\r\nQuerying the DOMAIN name server\r\n");
else {
vprint(cv,"\r\nNo nameserver, cannot resolve IP address\r\n");
return(-1);
}
}
else {
/*
* tell user about it on the console
*/
vprint(cv,"\r\nTrying to open TCP connection to: ");
vprint(cv,st);
vprint(cv,"\r\n");
/* try to serve the request */
if ( 0 > (new = Snetopen(mp,HTELNET))) {
errhandle();
vprint(cv,"\r\nCould not open new connection to: ");
vprint(cv,st);
vprint(cv,"\r\n");
return(-1);
}
newin = creatwindow();
if (!newin) { /* mem error */
vprint(console->vs,"\r\nMemory Allocation error for window\r\n");
return(-1);
}
newin->pnum = new;
strncpy(newin->mname,st,14);
newin->mname[14] = 0;
inswindow(newin,1);
vhead(newin->vs);
}
return(0);
}
#ifdef USETEK
leavetek()
{
if (current->termstate == TEKTYPE) {
VGwrite(temptek,"\037",1); /* force to alpha */
current->termstate = VTEKTYPE;
VGtmode(rgdevice);
/* clear graphics mode */
return(1);
}
return(0); /* we did nothing */
}
#endif
/***********************************************************************/
/* capstat
*
*/
capstat(s)
char *s;
{
int r,c;
r = n_row();
c = n_col();
n_cur(24,54);
n_draw(s,strlen(s));
n_cur(r,c);
}
/***********************************************************************/
/* scrollback
* Take keyboard keys to manipulate the screen's scrollback
*
*/
scrollback()
{
int c;
if (current->termstate == TEKTYPE)
return(0);
while (0 < ( c = n_chkchar())) {
switch (c) {
case CURUP:
VSscrolback(current->vs,1);
break;
case CURDN:
VSscrolforward(current->vs,1);
break;
case PGUP:
VSscrolback(current->vs,22);
break;
case PGDN:
VSscrolforward(current->vs,22);
break;
default:
break;
}
}
}