Metropoli BBS
VIEWER: look.c MODE: TEXT (ASCII)
/*
*    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
*   5/8/89   Version 2.3 Heeren Pathak & Quincey Koziol
*   1/21/91  Version 2.3 Chris Wilson & Quincey Koziol
*   6/19/91  Version 2.3 - Linemode reworked - Jeff Wiedemeier
*/

//#define UM
#define WINMASTER
#define REALTIME

#ifndef NOTEK
#define USETEK
#endif
/* #define USERAS */
#define HTELNET 23
/*#define DEBUG*/


#ifndef USETEK
#define leavetek() 0
#endif

#ifdef MSC
#define mousecl mousecml
#endif

#ifdef __TURBOC__
#include "turboc.h"
#endif
#ifdef MOUSE
#include "mouse.h"
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <ctype.h>
#include <direct.h>
#include <time.h>
#include <conio.h>
#include <process.h>
#include <stdarg.h>
#include <bios.h>
#ifdef MSC
#include <malloc.h>
#endif
#ifdef CHECKNULL
#include <dos.h>
#endif

#include "whatami.h"
#include "nkeys.h"
#include "windat.h"
#include "hostform.h"
#include "protocol.h"
#include "data.h"
#include "confile.h"
#include "telopts.h"
#include "vidinfo.h"
#include "version.h"
#include "externs.h"

#include "map_out.h"

FILE *tekfp;
#ifdef MAL_DEBUG
FILE *mem_file;
#endif
FILE *console_fp;       /* file pointer for the console output when active */

//extern int default_mapoutput; /* Apparantly no longer used. */
extern int beep_notify;
extern int bypass_passwd;  /* flag to bypass the password check for ftp'ing back to our own machine */

long size,            /* size of buffer */
  cstart,             /* starting location of VS copy buffer */
  cend,               /* ending location of VS copy buffer */
  cdist,              /* distance to base point */
	temp;

int stand=0,          /* whether telnet is operating in 'standalone' mode (remains active when all sessions are closed) */
    sound_on=0,
    basetype=VTTYPE,
    ftpact=0,					/* ftp transfer is active */
    rcpact=0,					/* rcp transfer is active */
    viewmode=0,       /* What are we looking at? */
    prevmode=0,       /* What were we looking at? (before the help screen) */
    ftpok=1,					/* is file transfer enabled? */
    ftpwok=1,         /* incoming ftp */
    rcpok=1,					/* remote copying enabled? */
    scroll,           /* which way do we scrool */
    cflag=0,					/* are we copying ? */
    cbuf=0,						/* do we have things in the buffer? */
    mcflag,						/* mouse button flag */
    ginon=0,					/* the tektronics Graphics INput (GIN) mode flag */
    vsrow=0,					/* VS row */
    mighty,						/* mouse present? */
    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=255,     /* the argument on the command line where the first machine is located */
    use_mouse=0,      /* use mouse for scrolling toggle */
    console_file_wanted=0,      /* should console be written to file ? */
    lpt_port=0;       /* port 0 == lpt1 (currently a hardwire) Also check out vsem.c */

int save_screen = TRUE;

unsigned char s[550],
    parsedat[256],
	path_name[_MAX_DRIVE+_MAX_DIR],		/* character storage for the path name */
    colors[NCOLORS]={4,2,0x70,0},       /* base colors */
	myipnum[4],
#ifdef CHECKNULL
    null_done=0,                /* flag to indicate that the null area has been snapshotted */
    nullbuf[1024],              /* buffer for debugging NULL overwrites */
#endif
    *copybuf=NULL,
    *lineend={"\r\n"},
    *blankline={"                                                                                       "};

unsigned int time_check=0;      /* variable to try to minimize the time spent checking the time */
time_t oldtime;					/* the last time the clock was updated */

long int lastt;

extern struct config def;		/* Default settings obtained from host file */

struct machinfo *mp=NULL;		/* Pointer to a machine information structure */

void CDECL (*attrptr)(int );    /* pointer to the routine to change the attribute of a character on the screen */

#define PSDUMP 128

#ifdef IP_ENHANCEMENTS					/* UNFINISHED message screen enhancements */
char *source_ip_num;					/* for error messages */
int port_num;               /* for error messages */
#endif

#define  USAGE   printf("\n\nUsage: telnet [-s] [-n] [-t] [-c color] [-h hostfile] [machinename] ...\n")

main(int argc,char *argv[])
{
    char temp_str[128];
    int i,j;
	char *config;

extern char keyboard_type;

    /* Check for CONFIG.TEL environment variable */
	config=(getenv("CONFIG.TEL"));
	if(config)
		Shostfile(config);

  /* work on parms */
  examineCommandLine(argc,argv);

  /* Initialize the video configuration, and retrieve it */
  initvideo();
  getvconfig(&tel_vid_info);
  getvstate(&tel_vid_state);

  if(save_screen)     /* save the screen if we are supposed to */
    init_text();

#ifdef __TURBOC__
	fnsplit(argv[0],path_name,s,temp_str,parsedat);		/* split the full path name of telbin.exe into it's components */
#else
	_splitpath(argv[0],path_name,s,temp_str,parsedat);	/* split the full path name of telbin.exe into it's components */
#endif
	strcat(path_name,s);	/* append the real path name to the drive specifier */

	install_keyboard();		/* determine what kind of keyboard this is */

  save_break();           /* preserve the status of the DOS BREAK setting */

  install_break((int *)&foundbreak);      /* install our BREAK handler */

  time(&oldtime);
#ifndef MOUSE
	mighty=initmouse();
#else
	mighty=nm_initmouse();
#endif
  n_clear();              /* do you know where your BP is? */
	n_cur(0,0);
  n_window(0,0,numline,79);   /* vt100 size */
	n_color(2);
  printf("%s, reading configuration file . . .\n",TEL_VERSION);

/*
* initialize the default keyboard settings
*/
#ifdef OLD_WAY /* Keyboard inits  rmg 931100 */
    if((j=initkbfile())<0) {    /* check for correct keyboard initialization */
        puts("Error reading default settings from keymap file.");
		getch();
    } /* end if */
#else
  memset(key_map_flags,0,1024);   /* initialize all the keyboard mapped flags to zero (not mapped) */
  memset(key_special_flags,0,1024); /* initialize all the keyboard special flags to zero (not special) */
#endif

  initoutputfile();   /* initialize the output mapping (to no mapping) */

/*
* initialize network stuff
*/
    if(j=Snetinit()) {  /* Read in the config.tel file and fire up the network */
		errhandle();
        printf("Error initializing network or getting configuration file\r\n");
		switch (j) {
			case -1:
                puts("Cannot initialize board.");
				break;

			case -5:
                puts("Error in config.tel file.");
				break;

			case -2:
                puts("RARP failed!!");
				break;

			case -3:
                puts("BOOTP failed!!");
				break;

			case -4:
                puts("X25 Initialization Failed!!");
				break;

			default:
                printf("Error from Snetinit()=%d\n",j);
				break;
          } /* end switch */
		if(j<-1)	/* network initialized, special case */
			netshut();
        remove_break();             /* restore the previous ctrl-c interupt handler */
        exit(1);
    }   /* end if */

#ifdef CHECKNULL
    /* Note: we snapshot the NULL area here, because some ethernet drivers modify the interrupt table when initialized */
    memcpy(nullbuf,MK_FP(0x0,0x0),1024);    /* make a copy of the NULL area */
    null_done=1;            /* set the flag for the NULL area */
#endif

    netgetip(myipnum);      /* what is my ip number? */
    Sgetconfig(&def);       /* get information provided in hosts file */

    ftpok=def.ftp;          /* what types of files transfers are allowed? */
    rcpok=def.rcp;
    ftpwok=def.ftpw;        /* Allow FTP writes? */
    for(i=0;i<3;i++)        /* set console colors to what's in config.tel */
      colors[i]=def.color[i];

    /* Check to see if we need to enter 43 or 50 line mode */
    if(def.ega43==1) {
		numline=41;
        ega43();
      } /* end if */
    else if(def.ega43==2) {
		numline=48;
        vga50();
      } /* end if */
	else {
		numline=23;				/***** NEED TO ADD SUPPORT FOR MODE CURRENT */
#ifndef AUX
    ega24();
#endif
	}

    n_window(0,0,numline,79);   /* vt100 size */

    if(def.cursortop!=-1 && def.cursorbottom!=-1)
		install_cursor((unsigned int)((def.cursortop<<8) | def.cursorbottom));

	if(Scmode())
		attrptr=n_attr;
	else
		attrptr=n_biosattr;

    n_clear();  /* clear the screen */

    for(i=0; i<NPORTS; i++)
		wins[i]=NULL;					/* we are using no window yet */

/*
* create console window for errors, informative messages, etc.
*/
    if(0>VSinit(NUM_WINDOWS))  {             /* initialize GPs virtual screens */
		n_puts("Virtual screen initialization failed.");
		exit(1);
    } /* end if */
    if(NULL==(console=creatwindow())) {
		n_puts("Console memory allocation failed");
		exit(1);
    }
    VSsetrgn(console->vs,0,0,79,numline);
    strcpy(console->mname,"Console");
/*
* introductions on the console window
*/
    i=console->vs;
    RSvis(-1);
    /* swapped around  rmg 931100 */
    //tprintf(i,"NCSA Telnet\r\n");
    vhead(i);
    tprintf(i,"\n\nConsole messages:\r\n");

#ifdef USETEK
/*
*  install tektronix
*/
	if(Stmode())
		tekinit(def.video);
#endif
#ifdef USERAS
	if(!VRinit())
        tprintf(i,"Error initializing raster support\r\n");
#endif
/*
*  Display my Ethernet (or Appletalk) and IP address for the curious people
*/
	pcgetaddr(&s[200],def.address,def.ioaddr);
    tprintf(console->vs,"My Ethernet address: %x:%x:%x:%x:%x:%x\r\n",s[200],s[201],s[202],s[203],s[204],s[205]);
    tprintf(console->vs,"My IP address: %d.%d.%d.%d\n\r\n",myipnum[0],myipnum[1],myipnum[2],myipnum[3]);

    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;
      } /* end if */

    atexit(endall);             /* set the function to call when exitting */
    wrest(current);             /* paint the first session's screen */
    while(EXIT_TELNET!=dosessions());  /* serve all sessions, events */

    exit(0);
}   /* end main() */

void examineCommandLine(int argc, char *argv[])
{
    int i,j,size=0;

    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]=(unsigned char)hexbyte(argv[i]+j*2);
					break;

                case 'd':
					console_file_wanted=1;
                    console_fp=fopen("console.dmp","wb+");
#ifdef OLD_WAY
                    setbuf(console_fp,NULL);    /* unbuffer the console output */
#else
                    setvbuf(console_fp,NULL,_IONBF,0);
#endif
					break;

                case 'e':
                    if(commandLineOveride) {
                      size=strlen(commandLineOveride);
#ifdef AUX /* RMG */
fprintf(stdaux," commandLineOverride is on ");
#endif
                    }
                    commandLineOveride=(char *)realloc(commandLineOveride,strlen(commandLineOveride)+strlen(argv[++i])+3);
                    *(commandLineOveride+size)=(char)NULL;
                    strcat(commandLineOveride,argv[i]);
                    *(commandLineOveride+strlen(commandLineOveride)+1)=(char)NULL;
                    *(commandLineOveride+strlen(commandLineOveride))=';';
                    break;

                case 'n':   /* disable screen restore */
                    save_screen = FALSE;
                    break;

                case 's':   /* set standalone/server flag */
					stand=1;
					break;

                case 't':   /*  Disable direct writes to screen  */
					Scwritemode(0);
					break;

                case 'h':   /* set new name for host file */
                    Shostfile(argv[++i]);   
					break;

                case '?':   /* help screen */
				default:
					USAGE;
                    printf("\n\n -c 172471    sets the basic color scheme for console screen\n");
                    printf(" -h file      full path specification of host information file\n");
                    printf(" -s           standalone (server) mode for rcp and ftp\n");
                    printf(" -t           disable direct writes to screen\n");
                    printf(" -n           disable screen restore\n");
                    exit(1);
              } /* end switch() */
          } /* end if */
		else {
            machparm=i;         /* where first machine name is */
            break;
          } /* end else */
      } /* end for */
}   /* end examineCommandLine() */

/************************************************************************/
/* vhead
*  place the header for new sessions in.
*/
void vhead(int v)
{
    tprintf(v,"\r\nNational Center for Supercomputing Applications\r\n");
    tprintf(v,"%s for the PC\r\n",TEL_VERSION);
    tprintf(v,"\nAlt-H presents a summary of special keys \n\r\n");
}   /* end vhead() */

/************************************************************************/
/*  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.
*/
int dosessions(void)
{
    static int scroll_row,scroll_col;   /* the row and column saved while in scroll back */
	time_t newtime;					/* variable to hold the new time for the clock */
	int clock_row,clock_col,		/* the row and column saved while updating the clock */
        i=0,j,ch,
        c,                          /* the color saved */
		cl,dat,cvs;
#ifdef BEFORE_GIN_FIX
    int m1,m2,m3,m4;        /* mouse variables */
#else
    int m1,m2,m3,m4,m3a,m4a;        /* mouse variables */
#endif
    int x1,x2,y1,y2;        /* temp variables for VSgetrgn test when exiting scrlback mode */
  unsigned int sw;
#ifdef BEFORE_GIN_FIX
  char gindata[5];    /* variable to store gin data in when returning fron VGgindata */
#else
  char gindata[6];    /* variable to store gin data in when returning fron VGgindata */
#endif
	struct twin *t1;
	static char lch=-1;
    char *p=NULL;
#ifdef CHECKNULL
    static unsigned int null_check=0;        /* don't try to check NULL every time */

/* If we are running in NULL debugging mode, check that */
    if(++null_check%8==0)
        check_null_area();
#endif

#ifdef USETEK
    if(ginon && current->termstate==TEKTYPE) { /* check for GIN mode for tektronics */
#ifdef BEFORE_GIN_FIX
      ch=n_chkchar();
      m1=3;
      m2=0;
      m3=0;
      m4=0;        /* mouse variables */
      mousecl(&m1,&m2,&m3,&m4);
      if((ch!=(-1)) || (m2&1)) {
        if((ch!='\r') && (ch!='\n') && (ch>0))
          lch=(char)ch;
        if((lch!=(-1)) && (m2&1)) {
          VGgindata(current->vs,m3,m4,lch,gindata);

#else /* this is gin_fix stuff */
      do {
        ch=kbhit();
        m1=3;
        m2=0;
        m3=0;
        m4=0;        /* mouse variables */
        mousecl(&m1,&m2,&m3,&m4);
      } while ((ch == 0) && (m2 == 0));  /* loop until mouse button or key pressed */

      if(ch==0)
        lch=(char)' ';  /* Mouse button pressed - return space */
      else
        lch=(char)getch();

    /* RMG ??? 940103 */
      if(ch==0)
        do {
          m1=3;
          m2=0;
          m3a=0;
          m4a=0;
          mousecl(&m1,&m2,&m3a,&m4a);
        } while (m2 != 0);  /*hold until mouse button released */

      VGgindata(current->vs,m3,m4,lch,gindata);       /* send the mouse cursor */
                                                      /* position to be translated */
                                                      /* by VGgindata with the */
                                                      /* information returned */
                                                      /* in gindata */
      gindata[5]='\r';                                /* add new-line char */
#endif /* before_gin_fix */

      RSsendstring(current->vs,gindata,6);    /* return GIN data across network */
      vt100key(0);

      lch=-1;                 /* clear last char buffer */
      resetgin();               /* reset GIN mode */
#ifdef BEFORE_GIN_FIX
              } /* end if */
          } /* end if */
#endif
    } /* end if */
#endif /* usetek */

	switch(viewmode) {
		case 0:					/* no special mode, just check scroll lock */
		default:
			if(n_scrlck()) {	/* scroll lock prevents text from printing */
				viewmode=1;
				vsrow=0;
				cstart=0;
				cend=0;
				cflag=0;
				cbuf=0;
				mcflag=0;
				scroll_row=n_row();
				scroll_col=n_col();
				c=n_color(current->colors[1]);
				n_cur(numline+1,61);
				n_draw("Scrl",4);	/* status in lower left */
				n_color(c);
				n_cur(scroll_row,scroll_col);
              } /* end if */
/*
*  This gives precedence to the keyboard over the network.
*/
            if((ginon) && (current->termstate==TEKTYPE))
                break;
            while(0<=(c=newkey(current)))   /* do all key translations */
				if(c==EXIT_TELNET)
          return(EXIT_TELNET);
			break;			/* no special viewing characterisitics */

		case 1:						/* scrollock is active */
			if(!n_scrlck()) {
				VSgetrgn(current->vs,&x1,&y1,&x2,&y2);
        if(y1!=0)
          VSsetrgn(current->vs,0,0,79,numline);
				viewmode=0;			/* set back if appropriate */
        if(y1==0)
          wrest(current);
				scroll=0;
				statline();
				n_cur(scroll_row,scroll_col);
      } /* end if */
/* 
*  In scroll lock mode, take keys only for the scrollback, 
*  The scrollback routine will never block, so we keep servicing events.
*/
      scrollback(current);
			break;

		case 2:						/* console is visible */
			if(n_scrlck()) {	/* scroll lock prevents text from printing */
				viewmode=13;
				vsrow=0;
				cstart=0;
				cend=0;
				cflag=0;
				cbuf=0;
				mcflag=0;
				scroll_row=n_row();
				scroll_col=n_col();
				c=n_color(console->colors[1]);
				n_cur(numline+1,61);
				n_draw("Scrl",4);	/* status in lower left */
				n_color(c);
				n_cur(scroll_row,scroll_col);
              } /* end if */
            if(0<n_chkchar())
				viewmode=10;	
			break;

		case 3:						/* help screen view1 */
		case 4:						/* help screen view2 */
			while(0<=(c=n_chkchar())) {	
				if(c==EXIT_TELNET)
					return(EXIT_TELNET);
				if(viewmode==3 && c==27) {
					viewmode=4;
          help2();
        } /* end if */
				else { 	 			/* restore view 0 */
          if(c==' ')
            viewmode=10;
#ifdef NOT /* rmg 931122 */
          else
            if(c>128)
              dokey(current,c); /* dokey might change view, if so, don't reset view 0 */
#endif
        } /* end else */
      } /* end while */
			break;

		case 5:						/* DOS screen view */
			viewmode=9;				/* wait for keypress */
			break;

		case 6:						/* server mode */
      statline();
      tprintf(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:
          tprintf(console->vs,"\n\r\n Ending server mode \r\n");
					return(EXIT_TELNET);	/* leave the program */

				case ALTA:
          if(!addsess(NULL))   /* start up a new one */
						viewmode=10;
          else {
						current=console;
						viewmode=6;
          } /* end else */
					break;

        case ALTE:      /* shell to dos */
					leavetek();
					n_window(0,0,numline+1,79);
					i=n_color(current->colors[0]);
					dosescape();
					wrest(console);
					viewmode=7;
					n_color(i);
					break;

        case ALTH:      /* help display (added to console window)  rmg 931100 */
          leavetek();
          prevmode=7;
          viewmode=3;
          helpmsg();
          break;

#ifdef FTP
        /* modified ALTW to query  rmg 931100 */
        case ALTW:        /* send our password to the machine we are connected to, for use in ftp'ing back to oneself */
          leavetek();
          if(bypass_passwd) {
            n_puts("\n OK then, we won't bypass the next FTP password after all.");
            bypass_passwd=0;
          }
          else {
            n_puts("\n Are you sure you want to bypass the FTP password once? Y/N");
            c=nbgetch();        /* get the answer */
            if(tolower(c)=='y') {
              n_puts("\n The next FTP connection will accept any password and give root access.");
              bypass_passwd=1;  /* set the flag to bypass the password check */
            } /* end if */
          }
          n_puts("\n Press any key to return");
          c=nbgetch();        /* get the answer */
          wrest(console);
          viewmode=7;      /* redraw screen */
          break;
#endif

				case -1:
					break;		/* no keypress */

				default:
          tprintf(console->vs,"\r\nYou must have an open session to use other commands.\r\n");
					viewmode=6;
					break;
      } /* end switch */
			break;

#ifdef USETEK
		case 8:
			if(graphit())				/* graphics menu screen */
				viewmode=10;
			break;
#endif

		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 */
      /* for help screen in server window  rmg 931100 */
      if(prevmode==7) {
        viewmode=prevmode;
        prevmode=0;
      }
//      statline();
			break;

		case 11:						/* paste copy buffer to current session */
			temp-=netwrite(current->pnum,(char *)&copybuf[(int)(size-temp)],(int)temp);
			if(!temp)
				viewmode=0;
			break;

		case 13:
			if(!n_scrlck()) {
				VSsetrgn(current->vs,0,0,79,numline);
				viewmode=2;			/* set back if appropriate */
				scroll=0;
				wrest(console);
				statline();
				n_cur(scroll_row,scroll_col);
              } /* end if */
/* 
*  In scroll lock mode, take keys only for the scrollback, 
*  The scrollback routine will never block, so we keep servicing events.
*/
			scrollback(console);
			break;
      } /* end switch */

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

				/* Start negotiation on network */
                start_negotiation(t1,cvs);

				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(EXIT_TELNET);
				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 */
                tprintf(cvs,"\r\nCan't open connection, timed out\r\n");
				netclose(dat);			/* close out attempt */
				if(!t1->next) {
					wrest(console);
					return(EXIT_TELNET);
				  }
				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 */
        tprintf(cvs,"\r\nDOMAIN lookup failed for: ");
				if(mp && mp->hname)
          tprintf(cvs,"%s\r\n",mp->hname);
				else 
					if(mp && mp->sname)
            tprintf(cvs,"%s\r\n",mp->sname);
				break;

			case USERCLASS*256+DOMOK:
				mp=Slooknum(dat);				/* get machine info */
				if(mp) {
          tprintf(cvs,"\r\nDOMAIN lookup OK for: ");   /* print session name and host name */
					if(mp->hname)
            tprintf(cvs,mp->hname);
					if(mp->sname) {
            tprintf(cvs," - %s",mp->sname);
						if(mp->port!=HTELNET) {
							char *s;

							if((s=(char *) malloc(strlen(mp->sname) + 6))!=NULL) {
								sprintf(s,"%s#%d",mp->sname,mp->port);
								mp->port=HTELNET;
								addsess(s);
								free(s);
							  }	/* end if */
						  }	/* end if */
						else
							addsess(mp->sname);
					  }
					else
						if(mp->port!=HTELNET) {
							char *s;

							if((s=(char *) malloc(strlen(mp->hname) + 6))!=NULL) {
								sprintf(s,"%s#%d",mp->hname,mp->port);
								mp->port=HTELNET;
								addsess(s);
								free(s);
							  }	/* end if */
						  }
						else
							addsess(mp->hname);
              tprintf(console->vs,"\r\nDomain Port is:%d\r\n",mp->port);
					viewmode=10;
				  }
				break;

/*
*  FTP status events.
*/
#ifdef FTP
			case USERCLASS*256+FTPBEGIN:		/* data connection */
                {
                    unsigned char host[4];

                    ftpact=dat;
                    Sftpname(s);                    /* get name */
                    Sftphost(host);
                    if (SftpDirection())
                        tprintf(cvs,"FTP: RECEIVING %s from host ", s);
                    else
                        tprintf(cvs,"FTP: SENDING %s to host ", s);
                    if((NULL==(mp=Slookip(host))) || (NULL==mp->sname))
                        tprintf(cvs,"%d.%d.%d.%d\r\n",host[0],host[1],host[2],host[3]);
                    else
                        tprintf(cvs,"%s\r\n",mp->sname);
                    ftpstart((char)(ftpact+2),s);
                    lastt=n_clicks();
                    break;
                }

			case USERCLASS*256+FTPLIST:			/* LIST or NLST */
        tprintf(cvs,"FTP directory beginning\r\n");
				break;

			case USERCLASS*256+FTPEND:			/* data connection ending */
				ftpact=0;
				statline();
        tprintf(cvs,"FTP transfer done\r\n");
				break;

			case USERCLASS*256+FTPCOPEN:		/* command connection */
        tprintf(cvs,"FTP server initiated from host: ");
				Sftphost(s);
				if((NULL==(mp=Slookip(s))) || (NULL==mp->sname)) 
                    tprintf(cvs,"%d.%d.%d.%d\r\n",s[0],s[1],s[2],s[3]);
				else
                    tprintf(cvs,"%s\r\n",mp->sname);
				break;

			case USERCLASS*256+FTPUSER:			/* user name entered */
                tprintf(cvs,"FTP user ");
        Sftpuser(s);
                tprintf(cvs,">> %s << login request\r\n",s);
				break;

      case USERCLASS*256+FTPANON:     /* passwordless user name entered */
                tprintf(cvs,"FTP user ");
				Sftpuser(s);
        Sftppass(parsedat);
                tprintf(cvs,">ANON< login request as: %s passwd: >> %s <<\r\n",s,parsedat);  /* parsedat is a rarely used global string */
				break;

      case USERCLASS*256+FTPPWOK:     /* user password verified */
                tprintf(cvs,"FTP Password verified\r\n");
				break;

      case USERCLASS*256+FTPPWSK1:     /* user password verified */
                tprintf(cvs,"FTP Password Skipped (no password file)\r\n");
				break;

      case USERCLASS*256+FTPPWSK2:     /* user password verified */
                tprintf(cvs,"FTP Password Skipped with Alt-W\r\n");
				break;

      case USERCLASS*256+FTPPWWT:     /* user password verified */
                tprintf(cvs,"FTP Password includes Write access\r\n");
				break;

      case USERCLASS*256+FTPPWRT:     /* user password verified */
                tprintf(cvs,"FTP Root access gained\r\n");
				break;

      case USERCLASS*256+FTPPWNO:     /* user password failed */
                tprintf(cvs,"FTP Password failed verification\r\n");
				break;

			case USERCLASS*256+FTPCLOSE:		/* command connection ends */
                tprintf(cvs,"FTP server ending session\r\n");
				break;
#endif

#ifdef RCP
			case USERCLASS*256+RCPBEGIN:		/* rcp starting */
                tprintf(cvs,"rcp file transfer\r\n");
				rcpact=1;
				break;

			case USERCLASS*256+RCPEND:			/* rcp ending */
                tprintf(cvs,"rcp ending\r\n");
				rcpact=0;
				break;
#endif

#ifdef USETEK
			case USERCLASS*256+PSDUMP:			/* dump graphics screen */
				if(VGpred(indev,outdev)) {
					if(dat) {
						endump();
                        tprintf(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);
                if(dat==407)
                    inv_port_err(0,0,NULL);

            default:
				break;
          } /* end switch */
      } /* end if */
/*
*	update the FTP spinner if we are in ftp, and update the clock
*/
	else {
#ifdef FTP
		if(ftpact && (n_clicks()>lastt + 10)) {
			ftpstart((char)(ftpact+2),s);
			lastt=n_clicks();
    }
#endif
		if(def.clock) {
      if((++time_check%4)==0 && (current->termstate<TEKTYPE) && (!ftpact)) { /* only check the time every four calls to dosessions to try to minimize the timer impact */
				time(&newtime);
				if(oldtime!=newtime) {
					strcpy(s,ctime(&newtime));
					clock_row=n_row();
					clock_col=n_col();
					c=n_color(current->colors[0]);
					n_cur(numline+1,72);
					set_cur(0);
					if(Scmode())	  /* check which screen writing mode to use */
						n_cheat(&s[11],9);
					else
						n_draw(&s[11],9);
					n_cur(clock_row,clock_col);
					n_color(c);
					oldtime=newtime;
					set_cur(1);
        } /* end if */
      } /* end if */
    } /* end if */
#ifdef NOT /* cRMG */
    if(scrolllocked) {
      ;
    }
#endif
  } /* end else */
	return(c);
}   /* end dosessions() */

/*********************************************************************/
/* inprocess
*  take incoming data and process it.  Close the connection if it
*  is the end of the connection.
*/
int inprocess(struct twin *tw)
{
	int cnt;

	cnt=netread(tw->pnum,s,200);	/* 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 */
			if(stand) {
				wins[tw->pnum]=NULL;
				freewin(tw);
				current=console;
				viewmode=6;
				wrest(current);
				return(0);
			  }	/* end if */
			else
				return(-1);		/* signal no sessions open */

#ifdef USETEK
		leavetek();					/* make Tek inactive */
#endif
		if(tw!=current)
			wrest(tw);

		if(!def.wingoaway)		/* check whether the window just goes away, or sticks around for a keypress */
			n_puts("\nConnection closed, press a key . . .");
		if(tw==current)
			current=tw->next;
		delwindow(tw,1);
		if(!def.wingoaway)		/* check whether the window just goes away, or sticks around for a keypress */
			viewmode=9;
		else
			viewmode=10;
		return(0);
      } /* end if */

    if(cnt)
        parse(tw,s,cnt);    /* display on screen, etc.*/
	return(0);
}   /* end inprocess() */

/*********************************************************************/
/* endall
*  clean up and leave
*/
void endall(void )
{
    netshut();      /* close down the network */

	n_cur(numline+1,0);			/* go to bottom of screen */
	n_color(7);
	n_draw(blankline,80);		/* blank it out */
	if(def.ega43>0)				/* restore screen */
		ega24();

	remove_break();				/* restore the previous ctrl-c interupt handler */
	restore_break();			/* restore the BREAK status */
    setvstate(&tel_vid_state);  /* restore the video state */
    if(save_screen)     /* is we saved the screen, restore it */
        end_text();
    if(console_file_wanted) /* is we were debugging the console, close the file */
        fclose(console_fp);
}   /* end endall() */

/*********************************************************************/
/*  errhandle
*   write error messages to the console window
*/
void errhandle(void )
{
	char *errmsg;
	int i,j;

	while(ERR1==Sgetevent(ERRCLASS,&i,&j)) {
		errmsg=neterrstring(j);
        tprintf(console->vs,"%s\r\n",errmsg);
        if(j==407)
			inv_port_err(0,0,NULL);
      } /* end while */
}   /* end errhandle() */

/*********************************************************************/
/*  vprint
*   print to a virtual screen
*/
void vprint(int w,char *str)
{
#ifdef CONSOLEDEBUG
	VSwrite(current->vs,str,strlen(str));		/* dump all messages to the current screen */
#else
    if(w==console->vs && console_file_wanted)
        fputs(str,console_fp);
    VSwrite(w,str,strlen(str));
#endif
}   /* vprint() */

/*********************************************************************/
/*  tprintf
*	print a formatted string to a virtual screen
*/
int tprintf(int w,char *fmt,...)
{
    char temp_str[256];     /* this may be a problem, if the string is too long */
    va_list arg_ptr;
    int str_len;            /* length of the formatted string */

	va_start(arg_ptr,fmt);		/* get a pointer to the variable arguement list */
    str_len=vsprintf(temp_str,fmt,arg_ptr); /* print the formatted string into a buffer */
	va_end(arg_ptr);
    if(str_len>0) {
        if(w==console->vs) {    /* write stuff to the console screen without going through the overhead of looking through the string for VT100 escape codes */
            if(console_file_wanted) {
                fputs(temp_str,console_fp);
                fflush(console_fp);
              } /* end if */
            VSdirectwrite(w,temp_str,str_len);
          } /* end if */
        else
#ifdef CONSOLEDEBUG
            VSwrite(current->vs,temp_str,str_len);     /* dump all messages to the current screen */
#else
            VSwrite(w,temp_str,str_len);
#endif
      } /* end if */
    return(str_len);
}   /* tprintf() */

/*********************************************************************/
/*  parsewrite
*   write out some chars from parse
*   Has a choice of where to send the stuff
*/
void parsewrite(struct twin *tw,char *dat,int len)
{
    char localdata[32];      /* local data for strings */
	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
*/

#ifdef UM  /* #define UM statement at top of file is commented out */
	if (localprint) {
    for(i=0; i<len-3; i++) {
      if ((dat[i]==27)&&(dat[i+1]=='[')&&(dat[i+2]=='4')&&(dat[i+3]=='i')) {
        localprint=0;
      }
		}
		if (localprint)
			for(i=0; i<len; i++)
#ifdef MSC
        _bios_printer(_PRINTER_WRITE,lpt_port,dat[i]);
#elif __TURBOC__
				biosprint(0,ptr[i],0);
#endif
	}
#endif
	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(localdata,"<%d>",*dat);
                VSwrite(tw->vs,localdata,strlen(localdata));
			  }
			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 */

	  }	/* end else */
}   /* end parsewrite() */

/*********************************************************************/
/* newkey
*  filter for command key sequences
*/
int newkey(struct twin *t1)
{
	int c;

	if(foundbreak) {
		foundbreak=0;
        c='\003';       /* ctrl-c */
        if(t1->lmflag) {       /* Telnet line mode is on */
            if(LMinterp_char(t1,c)) /* check if this character is a special line mode character */
                c=0;    /* don't want ^C on beginning of next line */
        } /* end if */
      } /* end if */
    else {
        if(ginon)
            c=0;
        else {
            if(t1->lmedit) {       /* Telnet line mode editting is on */
                c=LMgets(t1);
                if(c>0) {       /* check for an actual character */
#ifdef QAK
tprintf(console->vs,"Linemode on, c=%d, t1->linemode=%s\r\n",(int)c,t1->linemode);
#endif
                    if(LMinterp_char(t1,c))  /* check for a special line mode character */
                        c=0;    /* we handled this character */
                    else {  /* linemode routines didn't interpret this character */
                        if(t1->linemode[0]) {
#ifdef QAK
tprintf(console->vs,"c=%d, t1->linemode=%s\r\n",(int)c,t1->linemode);
#endif
                            netpush(t1->pnum);
                            netwrite(t1->pnum,t1->linemode,strlen(t1->linemode));
                            t1->linemode[0]='\0';
                          } /* end if */
                      } /* end else */
                  } /* end if */
              } /* end if */
            else {      /* no linemode */
                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;
                          } /* end if */
                        else
                            if(c>0 && c<128)
                                parse(t1,(char *)&c,1);     /* echo char */
                      } /* end if */
                    else {                      /* kludge linemode */
                        c=RSgets(t1->vs,t1->linemode,79,1);
                        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;
                          } /* end if */
                        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';
                                  } /* end if */
                              } /* end if */
                          } /* end else */
                      } /* end else */
                  } /* end else */
#ifdef QAK
if(c!=(-1))
    tprintf(console->vs,"c=%u:%x\r\n",(unsigned int)c,(unsigned int)c);
#endif
              } /* end else */
          } /* end else */
      } /* end else */

	if(c<=0)
		return(c);
	return(dokey(t1,c));
}   /* end newkey() */

/************************************************************************/
/*  screendump
*   dump the contents of the current screen into the capture file
*
*/
void screendump(struct twin *t1,int whole_scrollback)
{
	int y,			/* variable to count the line of the screen we are dumping */
        line_num,   /* the number of lines to dump */
		len;		/* the length of the line with trailing blanks eliminated */
	unsigned char *c,*d;	/* temporary pointers into the text for a line */

	if(t1->capfp) {		/* make certain the file is open */
        if(VSvalids(t1->vs))    /* make certain there is a virtual screen to dump */
			return;
		capstat("Dump",1);
        if(whole_scrollback)        /* check if we want to dump the entire scroll scrollback */
            line_num=VSIw->lines;
        else
            line_num=numline+1;
        for(y=0; y<line_num; y++) {    /* dump each line */
			c=&VSIw->linest[y]->text[0];	/* get the address of the text line */
			d=c+VSIw->allwidth;			/* allwidth =79 for an 80 width window */
			while((*d==' ' || *d==0) && d>c)		/* don't print trailing blanks */
				d--;
			len=d-c+1;
            fprintf(t1->capfp,"%*.*s\r\n",len,len,c);   /* store the line */
		  }	/* end for */
        fprintf(t1->capfp,"\f");    /* print formfeed */
    statline();   /* re-print the statline */
	  }	/* end if */
}	/* end screendump() */

/************************************************************************/
/*  dokey
*   translates and sends keys and filters for command keys
*
*/
int dokey(struct twin *t1,int c)
{
	int i;

#ifdef QAK
tprintf(console->vs,"t1=%p, c=%d\n",t1,c);
#endif
    switch(c) {
		case BACKSPACE:		/* backspace */
			c=t1->bksp;		/* allows auto del instead of bs */
			break;

		case 13:			/* different CR mappings */
                  /*   even more different now - rmg 931100 */
      if(!t1->crfollow) {   /* most common case avoids switch statemant */
        vt100key(13);
        vt100key(10);
      }
      else {
        switch(t1->crfollow) {
          case 1:
            vt100key(13);
            break;
          case 2:
            vt100key(10);
            break;
          case 3:
            vt100key(13);
            vt100key(0);
            break;
        }
      }
			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,(char *)&c,1);	/* write a NUL */
			break;

#ifdef USETEK
		case CTRLHOME:		/* tek clear screen */
		case E_CTRLHOME:	/* tek clear screen */
			if(def.tek) {	/* check whether we are allowed to go into tek mode */
                if(current->termstate!=TEKTYPE) {
					current->termstate=TEKTYPE;
					VGgmode(rgdevice);
					VGuncover(temptek);
                }
                VGwrite(temptek,"\033\014",2);  /* clear storage and screen */
				c=0;
			  }	/* end if */
			break;

		case HOME:			/* clear to text */
		case E_HOME:		/* clear to text */
			if(def.tek) {	/* check whether tektronix is enabled */
				if(leavetek()) {
					viewmode=10;
					c=0;
				  }
			  }	/* end if */
			break;
#endif

    case ALTA:        /* add session */
			c=0;
			if(0>addsess(NULL)) {		/* start up a new one */
        tprintf(console->vs,"\r\nPress any key to continue . . .");
				viewmode=9;
      }
			else
				viewmode=10;
			break;

		case ALTB:						/* session switch backwards */
			c=0;
			leavetek();
			if(current->prev==NULL)   /* are we only one ? */
				break;
			current=current->prev;
			viewmode=10;
			break;

		case ALTC:							/* toggle capture */
			if(capon && current->capon) {	/* already on */
				capstat("    ",0);
				fclose(current->capfp);		/* close the capture file */
				current->capon=capon=0;
			  }	/* end if */
			else 
				if(!capon) {				/* I want one */
					if(NULL==(current->capfp=Sopencap())) {
                        tprintf(console->vs,"\r\nCannot open capture file ");
						break;
					  }	/* end if */
					capstat("Capt",1);
					current->capon=capon=1;
				  }	/* end if */
				else {
                    tprintf(console->vs,"\r\nAnother session has capture file open, cannot open two at once\r\n");
					wrest(console);
					viewmode=2;
				  }	/* end else */
			c=0;
			break;

		case ALTD:		/* dump screen to capture file */
			c=0;
			if(!capon) {	/* if the capture file is not already open */
                if((current->capfp=Sopencap())==NULL) { /* try to open the capture file */
                    tprintf(console->vs,"\r\nCannot open capture file for screendump ");
					wrest(console);
					viewmode=2;
					break;
				  }	/* end if */
                screendump(current,0);    /* dump the current screen */
				fclose(current->capfp);
				current->capfp=NULL;
				break;
			  }	/* end if */
			if(current->capon && current->capfp)	/* ok, capture if on & the file is open */
                screendump(current,0);    /* dump the screen */
			else {
                tprintf(console->vs,"\r\nAnother session has a capture file open, cannot screendump\r\n");
				wrest(console);
				viewmode=2;
			  }	/* end else */
			break;

    case ALTE:    /* shell to commmand processor (DOS) */
			leavetek();
			n_window(0,0,numline+1,79);
			i=n_color(current->colors[0]); 
      if(!dosescape())
        viewmode=10;
      else
        viewmode=5;  /* error, pause */
			n_color(i);
			c=0;
			break;

#ifdef FTP
		case ALTF:							/* an ftp command */
			strcpy(s,"ftp ");
#ifdef AUX /* RMG */
fprintf(stdaux," ftpoptions %s ",current->ftpopts);
#endif
      //if((!Sneedpass()) && (current->ftpopts)) {  What's needpass() here for??
      if(current->ftpopts) {
				strcat(s,current->ftpopts);
				strcat(s," ");
      } /* end if */
      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;
#endif

#ifdef USETEK
		case ALTG:			/* graphics manipulation */
			if(Stmode()) {		/* make certain that tektronix has been initialized */
				c=0;
				leavetek();
				dispgr();
			  } /* end if */
			break;
#endif

		case ALTH:				/* help display */
			if(viewmode!=3) {
        leavetek();
        viewmode=3;
        helpmsg();
        c=0;
      } /* end if */
			break;

		case ALTI:							/* my internet address */
      sprintf(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 ALTJ:      /* for debuggin' purposes */
#ifdef MAL_DEBUG
            mem_file=fopen("c:\mem_dump","w");
            if(mem_file) {
                Mem_Display(mem_file);
                tprintf(console->vs,"wrote mem_file.\r\n");
                fclose(mem_file);
              } /* end if */
            else
                tprintf(console->vs,"failed mem_file write.\r\n");
#endif
#ifdef QAK
            mcb();
#endif
#ifdef QAK
            for(i=0; i<256; i++)
                fprintf(console_fp,"%d: %d -> %d\n",i,i,(int)outputtable[i]);
#endif
#ifdef CHECKNULL
            check_null_area();
#endif
            tprintf(console->vs,"numline=%d\n",numline);
            c=0;
			break;

		case ALTK:				/* erase char */
			netpush(t1->pnum);
			netwrite(t1->pnum,"\377\367",2);
			c=0;
            break;

        case ALTL:
            sound_on=!sound_on;
            c=0;
            break;
				
        case ALTM:                  /* mouse control on/off */
			c=0;
			use_mouse=!use_mouse;
			break;

		case ALTN:						/* session switch forwards */
			c=0;
			leavetek();
			if(current->next==NULL)   /* are we only one ? */
				break;
			current=current->next;
			viewmode=10;
			break;

		case ALTO:				/* abort output */
			netpush(t1->pnum);
			netwrite(t1->pnum,"\377\365",2);
			c=0;
			break;
				
		case ALTP:				/* change a parameter */
			parmchange();
			c=0;
			break;

		case ALTQ:				/* are you there? */
			netpush(t1->pnum);
			netwrite(t1->pnum,"\377\366",2);
			c=0;
			break;

		case ALTR:				/* reset screen values */
			if(!leavetek()) {
				if(current->capon) {
					fclose(current->capfp);
					current->capon=capon=0;
                  } /* end if */
				VSreset(current->vs);		/* reset's emulator */
              } /* end if */
			wrest(current);
			c=0;
			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 ALTT:        /* reload keyboard file */
      c=0;
      if(read_keyboard_file(Scon.keyfile)<0) { /* rmg  940216 */
        leavetek();
        n_puts("\nError reading settings from keymap file.");
        n_puts("\n Press any key to return");
        nbgetch();
        wrest(console);
        viewmode=7;
      } /* end if */
      break;

		case ALTU:				/* erase line */
			netpush(t1->pnum);
			netwrite(t1->pnum,"\377\370",2);
			c=0;
			break;
				
		case ALTV:				/* paste clipboard into buffer */
			if(copybuf!=NULL) {
				temp=size;
				viewmode=11;
              } /* end if */
			c=0;
			break;

#ifdef FTP
    case ALTW:				/* send our password to the machine we are connected to, for use in ftp'ing back to oneself */
      leavetek();
      if(bypass_passwd) {
        n_puts("\n OK then, we won't bypass the next FTP password after all.");
        bypass_passwd=0;
      }
      else {
        n_puts("\n Are you sure you want to bypass the FTP password once? Y/N");
        c=nbgetch();        /* get the answer */
        if(tolower(c)=='y') {
          n_puts("\n The next FTP connection will accept any password and give root access.");
          bypass_passwd=1;  /* set the flag to bypass the password check */
        } /* end if */
      }
      n_puts("\n Press any key to return");
      c=nbgetch();        /* get the answer */
      viewmode=10;      /* redraw screen */
      c=0;
      break;
#endif

		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);
      } /* end if */
			else
				viewmode=10;			/* redraw screen */
			c=0;
			break;

		case ALTY:				/* interrupt */
			netpush(t1->pnum);
			netwrite(t1->pnum,"\377\364",2);
			t1->timing=1;
			netwrite(t1->pnum,"\377\375\006",3);
			c=0;
			break;

		case ALTZ:					/* view console */
			c=0;
			leavetek();
			wrest(console);
			viewmode=2;				/* console view mode */
			break;

#ifdef DEBUG
		case AF9:
      statcheck();
			break;
#endif

		case EXIT_TELNET:			/* abort Telnet */
			return(EXIT_TELNET);

		default:
			break;
	  }	/* end switch */

	if(c>0)
		vt100key(c);			/* send it, with VT100 translation */
	return(c);
}   /* end dokey() */

/***************************************************************************/
/*  dosescape
*  escape to dos for processing
*  put the connections to automated sleep while in DOS
*  As telnet has grown, this feature has deteriorated in practicality.
*/
int dosescape(void )
{
	int i;
	char *command_shell;		/* the command shell to shell out to */
  char oldDir[_MAX_PATH];
  struct vidstate shell_vid_state;   /* the video state before we shelled out */

	if(ftpact || rcpact) {
		n_puts("Please wait until file transfer is finished");
		n_puts("\nPress any key to continue");
    return 1;
      } /* end if */

    getcwd(oldDir,_MAX_PATH);

    getvstate(&shell_vid_state);   /* get the current video state */
    setvstate(&tel_vid_state);     /* restore the user's previous video state */

    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 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
*/
	restore_break();		/* restore the break status */
    remove_break();         /* restore the previous ctrl-c interupt handler */

    netsleep(0);

    tinst();  /* Will crash if Stack checking is on */

  command_shell = getenv("COMSPEC");    /* search for the user's COMSPEC */

    if(command_shell!=NULL)     /* make certain that the COMSPEC exists */
      i=system(command_shell);        /* call DOS */
    else    /* tell the user if it doesn't */
      i=-1;

    tdeinst();

    chgdir(oldDir);

    install_break((int *)&foundbreak);      /* install our ctrl-c interupt handler */
    save_break();           /* save the break state again */

    setvstate(&shell_vid_state);    /* restore the telnet graphics state */

/* RMG */
#ifdef AUX
  i= -1;
#endif

    if(i<0) {
      n_puts("\n\nError loading DOS shell");
      n_puts("Make sure DOS shell is specified under COMSPEC.");
      n_puts(command_shell);
      //n_puts("It must also be in a directory which is in your PATH statement.");
      n_puts("Telnet does not always leave enough free memory for a DOS shell.");
      sprintf(s,"%d",_memavl());
      n_puts(s);
      n_row();
      n_puts("\nPress any key to return to telnet");
    } /* end if */

#ifdef Pauseme
    n_row();
    n_puts("\nPress any key to return to telnet"); /** rmg: no dont ***/
#endif

    viewmode=10;

#ifdef CHECKNULL
    for(i=0x88; i<=0x8b; i++)   /* patch to correct the change DOS makes to the INT 22h address when returning to the program */
        nullbuf[i]=*((unsigned char far *)i);
#endif

return(i<0);
}   /* end dosescape() */

/***********************************************************************/

void wrest(struct twin *t)
{
	RSvis(t->vs);
	statline();						/* done before, moves cursor */
    VSredraw(t->vs,0,0,79,numline);     /* redisplay, resets cursor correctly */
}   /* end wrest() */

/***************************************************************************/
void statline(void )
{
	struct twin *t1,*t2;
	int wn;
	int i,c,sm,rw,cl;

  if(current==NULL || current->termstate==TEKTYPE)
		return;
	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();
  if(current!=console)  /* rmg 931122 */
    do {
      n_cur(numline+1,wn*15);
      n_color(t1->colors[2]);
      if(t1->sstat==254 && t1!=current)
        t1->sstat=176;
      n_putchar((char)t1->sstat);
      n_putchar(' ');
      i=strlen(t1->mname);
      if(i>=13) {   /* check for too long of a name */
        if(sm)
          n_cheat(t1->mname,13);        /* machine name of connection */
        else
          n_draw(t1->mname,13);       /* machine name of connection */
        } /* end if */
      else {
        if(sm) {
          n_cheat(t1->mname,i);       /* machine name of connection */
          n_cheat(blankline,13-i);    /* fill out to 13 spaces */
          }
        else {
          n_draw(t1->mname,i);        /* machine name of connection */
          n_draw(blankline,13-i);     /* fill out to 13 spaces */
          }
        } /* end else */
      if(t1->next)            /* if not the only window open */
        t1=t1->next;
      wn++;
    } while(t1!=current && wn<4);
	n_color(current->colors[0]);
	n_cur(numline+1,wn*15);
	if(def.clock)	/* if we have a clock, then only fill up to the edge of the capture indicator */
		if(sm)
			n_cheat(blankline,71-wn*15);			/* fill to edge of screen */
		else
			n_draw(blankline,71-wn*15); 			/* fill to edge of screen */
	else		/* for no clock, fill all the way across the bottom of the screen */
		if(sm)
			n_cheat(blankline,80-wn*15);			/* fill to edge of screen */
		else
			n_draw(blankline,80-wn*15);				/* fill to edge of screen */

	if(wn>3 && (t1!=t2)) {		/* check whether to display the '\' */
		i=176;		/* display a '\' if any of the windows has data and those windows don't appear on the statline, (windows>4) */
        while(t1!=t2 && i!=14) {
            if(t1->sstat!=254 && t1->sstat!=176)    /* check for a different status character */
				i=t1->sstat;
			if(t1->next)	/* go to the next window if there is one */
				t1=t1->next;
   } /* end while */
		n_color(current->colors[0]);
		n_cur(numline+1,71);
		n_putchar((char)i);
	  }	/* end if */
	else {	/* just display a blank */
		n_color(current->colors[0]);
        n_cur(numline+1,71);
		n_putchar((char)' ');
      } /* end else */

	if(current->capon)	  						/* put capture flag status */
		capstat("Capt",1);
	else
		capstat("    ",0);

	n_color(c);
	n_cur(rw,cl);
}   /* end statline() */

/***********************************************************************/
/*  creatwindow
*   returns a pointer to a new window
*/
struct twin *creatwindow(void )
{
	struct twin *p;
	int i;

	p=(struct twin *)malloc(sizeof(struct twin));
	if(p==NULL)
		return(NULL);
	p->pnum=-1;
	p->telstate=0;
	p->substate=0;
	p->termsent=0;
	if(vton)
		p->termstate=basetype;
	else
		p->termstate=DUMBTYPE;
	p->linemode[0]=0;
#ifdef OLD_WAY
	p->echo=1;
#else
    p->echo=0;
#endif
    p->ibinary=0;       /* I'm sending NVT ASCII data */
    p->iwantbinary=0;   /* I'm not the one who asked for binary transmission from me */
    p->ubinary=0;       /* Server is sending NVT ASCII data */
    p->uwantbinary=0;   /* I'm not the one who asked for server to begin binary transmission */
    p->ugoahead=0;      /* we want goahead suppressed */
	p->igoahead=0;		/* we want goahead suppressed */
	p->timing=0;
	p->capon=0;
	p->next=NULL;
	p->prev=NULL;
    p->lmflag=0;
    p->lmedit=0;        /* turn off the telnet linemode editting initially */
    p->litflag=0;       /* turn off the literal flag initially */
    p->litecho=0;       /* turn off the literal echo initially */
    p->softtab=0;       /* turn off the soft tabbing initially */
    p->trapsig=0;       /* turn off the signal trapping initially */
    p->linemode_mask=0; /* set the linemode mask to remote editting and signal processing */
    for(i=1; i<=NUMLMODEOPTIONS; i++) {
		p->slc[i]=-1;
        p->slm[i]=SLC_NOSUPPORT;
      } /* end for */
    p->rows=numline+1;
    p->slm[SLC_BRK]|=SLC_SUPPORTED;     /* set the supported flag for the SLC functions we can handle */
    p->slm[SLC_IP]|=SLC_SUPPORTED;
    p->slm[SLC_AO]|=SLC_SUPPORTED;
    p->slm[SLC_AYT]|=SLC_SUPPORTED;
    p->slm[SLC_ABORT]|=SLC_SUPPORTED;
    p->slm[SLC_EOF]|=SLC_SUPPORTED;
    p->slm[SLC_SUSP]|=SLC_SUPPORTED;
    p->slm[SLC_EC]|=SLC_SUPPORTED;
    p->slm[SLC_EL]|=SLC_SUPPORTED;
    p->slm[SLC_EW]|=SLC_SUPPORTED;
    p->slm[SLC_RP]|=SLC_SUPPORTED;
    p->slm[SLC_LNEXT]|=SLC_SUPPORTED;
    p->slm[SLC_XON]|=SLC_SUPPORTED;
    p->slm[SLC_XOFF]|=SLC_SUPPORTED;
    p->slm[SLC_FORW1]|=SLC_SUPPORTED;
    p->slm[SLC_FORW2]|=SLC_SUPPORTED;
    p->sstat='*';               /* connection not opened yet */

	if(mp==NULL) {
		p->bksp=127;
		p->del=8;
    p->crfollow=0;
		p->halfdup=0;
		p->vtwrap=1;
#ifdef OLD_WAY
		p->bkscroll=0;
#else
    p->bkscroll=500;
#endif
		p->width=80;
    p->slc[SLC_EC]=127;
    p->ftpopts=NULL;
    p->condebug=0;
    p->mapoutput=0;     /* turn off output mapping for console */

		for(i=0; i<3; i++)					/* start default colors */
			p->colors[i]=colors[i];

    /****!*!*!*!*!*!*!*!*!*!*!*!*****/
		i=VSnewscreen(500,1,80,0);			/* create a new virtual screen */
    if(i<0) {
        free(p);
        return(NULL);
      } /* end if */
    p->vs=i;
    screens[i]=p;                       /* we need to know where it is */
    VSsetlines(i,numline+1);
		VSsetrgn(i,0,0,79,numline);
  } /* end if */
	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->vtwrap=mp->vtwrap;
		p->bkscroll=mp->bkscroll;
		p->width=mp->vtwidth;
		p->colors[0]=mp->nfcolor + (mp->nbcolor<<4);
		p->colors[1]=mp->ufcolor + (mp->ubcolor<<4);
		p->colors[2]=mp->bfcolor + (mp->bbcolor<<4);
    p->slc[SLC_EC]=mp->bksp;
    p->ftpopts=mp->ftpoptions;
    p->condebug=mp->consoledebug;
    p->mapoutput=mp->mapoutflag;     /* turn output mapping on if specified */

		i=VSnewscreen(mp->bkscroll,1,80,0);	/* create a new virtual screen */
        if(i<0) {
            free(p);
            return(NULL);
          } /* end if */
        p->vs=i;
        screens[i]=p;                       /* we need to know where it is */
        VSsetlines(i,numline+1);
		VSsetrgn(i,0,0,79,numline);

		if(i>=0 && mp->vtwrap)
			VSwrite(i,"\033[?7h",5);		/* turn wrap on */
		VSscrolcontrol(i,-1,mp->clearsave);	/* set clearsave flag */
      } /* end else */

#ifdef OLD_WAY
	if(i<0)
		return(NULL);
	p->vs=i;
	screens[i]=p;						/* we need to know where it is */
#endif
	return(p);
}   /* end creatwindow() */

/***********************************************************************/
/*  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"
*/
void inswindow(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;
	  }
	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;
	  }
}   /* end inswindow() */

/***********************************************************************/
/*  delwindow()
*   take a window out of the linked list
*/
void delwindow(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;
	  }	/* end if */
	if(p==q) {				/* two in list */
		p->next=NULL;
		p->prev=NULL;
	  }	/* end if */
	else {
		q->prev=p;
		p->next=q;			/* merge two links */
	  }	/* end else */
	freewin(t);				/* release the space */
}	/* end delwindow() */

/************************************************************************/
/*  freewin
*   deallocate and detach all associated memory from a window
*/
void freewin(struct twin *t)
{
	VSdetatch(t->vs);
	free(t);
}	/* end freewin() */

/************************************************************************/
/*
*  hexbyte
*   return a byte taken from a string which contains hex digits
*/
int hexbyte(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);
}   /* end hexbyte() */

#ifdef USETEK

/***********************************************************************/
/* tekinit
*  tektronix initialization
*/
int tekinit(char *dev)
{
	if(strlen(dev)<1)
		return(0);
#ifdef OLD_WAY
	if(0>VGinit()) {
        tprintf(console->vs,"\r\nCannot initialize Tektronix driver\r\n");
		return(-1);
	  }
	else
        tprintf(console->vs,"\r\nTektronix initialized\r\n");
#else
	VGinit();
    tprintf(console->vs,"\r\nTektronix initialized\r\n");
#endif
	if(!strcmp(dev,"vga")) 
		rgdevice=7;
	  	/* end if */
	else if(!strcmp(dev,"no9"))
		rgdevice=4;
	else if(!strcmp(dev,"ega"))
		rgdevice=1;
	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);
}   /* end tekinit() */

/***********************************************************************/
/*  function to write to file
*/
void fdump(char *str)
{
	fputs(str,tekfp);
}   /* end fdump() */

void fdumpc(int c)
{
	fputc(c,tekfp);
}   /* end fdumpc() */

void endump(void )
{
	VGclose(outdev);
	if(indev!=temptek) {
		VGclose(indev);
		if(tekfp) {
			fclose(tekfp);
			tekfp=NULL;
		 }
	  }
}   /* end endump() */

/***********************************************************************/
/* graphit
*  Get some user choices and execute them
*/
int graphit(void )
{
	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);

		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);
#ifdef MSC
			RGPoutfunc(fdump);		/* set function */
#else
			RGPoutfunc(&fdump);		/* set function */
#endif
			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);
					
		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);
#ifdef MSC
			RGHPoutfunc(fdump);		/* set function */
#else
			RGHPoutfunc(&fdump);		/* set function */
#endif
			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);

		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);
#ifdef MSC
			VGdumpstore(temptek,fdumpc);
#else
			VGdumpstore(temptek,&fdumpc);
#endif
			fclose(tekfp);
			return(1);

		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);

		case 13:
			if (!def.tek) break;
			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);
}   /* end graphit() */
#endif /* usetek */

/*************************************************************************/
/*  addsess
*   Add a session to a named machine, or prompt for a machine to be named.
*/
int addsess(char *st)
{
	int i,new,cv,pflag=0,port=0;
	struct twin *newin;

	leavetek();
	cv=console->vs;
	if(st==NULL) {			/* no machine yet */
		wrest(console);
    tprintf(cv,"\n\r\nEnter new machine name/address, ESC to return: \r\n");
		s[0]='\0';
		while(0>=(i=RSgets(cv,s,70,1)))
			Stask();
		if(i==27 || !s[0])
			return(1);
        tprintf(cv,"\n\r\n");    /* skip down a little */
		st=s;					/* make a copy of the pointer to s */
  }
/*
*	Find out what port to open to
*/
    for(i=0; (st[i]!=' ') && (st[i]!='#') && (st[i]!='\0'); i++);

	if((st[i]=='#') || (st[i]==' ')) {
		st[i++]='\0';
		new=i;
		pflag=1;
    for( ; (st[i]!='\0') && isdigit(st[i]); i++);
 		if(st[i]!='\0') 
			pflag=0;
		if(pflag) 
			port=(unsigned int)atoi(&st[new]);
  } /* end if */
	mp=Sgethost(st);			/* gain access to host information */
	errhandle();
	if(!mp) {
		if(pflag)
			st[strlen(st)]='#';	/* Append port number */
		if(Sdomain(st)>0) 
      tprintf(cv,"\r\nQuerying the DOMAIN name server\r\n");
		else {
      tprintf(cv,"\r\nNo nameserver, cannot resolve IP address\r\n");
			return(-1);
    }
  } /* end if */
	else {
/*
*   tell user about it on the console
*/
    tprintf(cv,"\r\nTrying to open TCP connection to: %s\r\n",st);
		if(!pflag) 
			port=mp->port;

	/* try to serve the request */
    if(0>(new=Snetopen(mp,port))) {
			errhandle();
      tprintf(cv,"\r\nCould not open new connection to: %s\r\n",st);
			return(-1);
    } /* end if */
		newin=creatwindow();
		if(!newin) {				/* mem error */
      tprintf(console->vs,"\r\nMemory Allocation error for window\r\n");
      return(-1);
    } /* end if */
		newin->pnum=new;
		strncpy(newin->mname,st,14);
		newin->mname[14]='\0';
		inswindow(newin,1);
		vhead(newin->vs);
  } /* end else */
	return(0);
}   /* end addsess() */

#ifdef USETEK
int leavetek(void )
{
    if(current!=NULL && current->termstate==TEKTYPE) {
		VGwrite(temptek,"\037",1);			/* force to alpha */
		current->termstate=VTEKTYPE;
		VGtmode(rgdevice);
		resetgin();				/* make sure to reset the GIN mode */
								/* clear graphics mode */
        if(def.ega43==1)
			ega43();
        else if(def.ega43==2)
            vga50();
		return(1);
    }
	return(0);					/* we did nothing */
}   /* end leavtek() */
#endif

/***********************************************************************/
/*  capstat
*	Print the capture status on the screen
*/
void capstat(char *str,int i)
{
	int r,c,color;

	r=n_row();
	c=n_col();
	color=n_color(current->colors[i]);
	n_cur(numline+1,66);
	n_draw(str,strlen(str));
	n_color(color);
	n_cur(r,c);
}   /* end capstat() */

/***********************************************************************/
/*  set_vtwrap
*	QAK - 7/29/90
*	set the vtwrap parameter for any telnet window, added because changing
*	a virtual screen's auto-wrapping had no way to change the telnet window's
*	wrapping state
*/
void set_vtwrap(int vs_win,int value)
{
	struct twin *temp_window;

	temp_window=screens[vs_win];		/* get a pointer to the window for the virtual screen */
	if(temp_window!=NULL)
		temp_window->vtwrap=(unsigned char)value;		/* set the virtual screen's wrapping */
}	/* end set_vtwrap() */

/***********************************************************************/
/*  strchar
*   QAK - 2/24/92
*   Append a character to a string
*/
void strchar(char *s,char c)
{
    while(*s)
        s++;    /* find the terminating zero in the string */
    *s++=c;     /* replace the terminating zero with the character */
    *s='\0';    /* terminate the new string */
}   /* end strchar() */

#ifdef CHECKNULL
void check_null_area(void)
{
    unsigned u;
    unsigned char *s;

    if(null_done && memcmp(nullbuf,MK_FP(0x0,0x0),1024)) {
        puts("NULL overwritten!");
        s=MK_FP(0x0,0x0);
        for(u=0; u<1024; u++,s++)
            if(*s!=nullbuf[u])
                printf("s=%p, u=%u, val=%u\n",s,u,(unsigned int)*s);
        getch();
      } /* end if */
}   /* end check_null_area() */
#endif

#ifdef DEBUG
void heapdump(void)
{

	struct _heapinfo hinfo;
	long free_mem=0;
	int heapstatus;

	hinfo._pentry = NULL;
	while ((heapstatus = _heapwalk(&hinfo)) == _HEAPOK){
		free_mem+= (hinfo._useflag == _USEDENTRY ? 0 : hinfo._size);
		printf("%6s block at %p of size %4.4X\n",
				(hinfo._useflag == _USEDENTRY ? "USED" : "FREE"),
				hinfo._pentry, hinfo._size);

		}
	switch(heapstatus){
		case _HEAPEMPTY:
			printf("OK - empty heap\n\n");
			break;
		case _HEAPEND:
			printf("OK - end of heap \n\n");
			break;
		case _HEAPBADPTR:
			printf("ERROR - bad pointer to heap \n\n");
			break;
		case _HEAPBADBEGIN:
			printf("ERROR - bad start of heap \n\n");
			break;
		case _HEAPBADNODE:
			printf("ERROR - bad node in heap \n\n");
	}
	printf("free_mem=%ld\n",free_mem);
}   /* end heapdump() */

void print_windowlist(void )
{

	struct twin *p, *q;

	wrest(console);
	n_clear();
	p=q=current;
	printf("List of Machines following NEXT list\n");
	do{
		printf("Host is %s\n",p->mname);
		p=p->next;
		} while(p!=q);
	printf("Hit any key for prev list\n");
	getch();
	n_clear();
	p=q=current;
	printf("List of Machines following PREV list\n");
	do{
		printf("Host is %s\n",p->mname);
		p=p->prev;
		} while(p!=q);
	printf("Hit any key to return to normal\n");
	getch();
}   /* end print_windowlist() */
#endif

[ RETURN TO DIRECTORY ]