home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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
-
- #define NUMLMODEOPTIONS 30
- /* #define NEGOTIATEDEBUG /* define this to enable -d option for console file */
- /* and hex dump of incoming data */
-
- #define USETEK
- /* #define USERAS */
- #define HTELNET 23
- /*#define DEBUG*/
-
- #define LMODE /* to compile with LINEMODE enabled */
-
- #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 MEMORY_DEBUG
- #include "memdebug.h"
- #endif
-
- #include "whatami.h"
- #include "nkeys.h"
- #include "windat.h"
- #include "hostform.h"
- #include "protocol.h"
- #include "data.h"
- #include "externs.h"
-
- FILE *tekfp, *mem_file;
- extern int localprint;
- extern int default_mapoutput;
- int sound_on=0;
-
- 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,
- basetype = VTTYPE,
- ftpact=0, /* ftp transfer is active */
- rcpact=0, /* rcp transfer is active */
- viewmode=0, /* What are we looking at? */
- ftpok=1, /* is file transfer enabled? */
- 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 */
- bypass_passwd=0, /* flag whether to bypass the password check for ftp'ing back to our own machine */
- vton=1,
- capon=0, /* overall capture on or not */
- foundbreak=0, /* trap Ctrl-C */
- machparm=0,
- domacro=-1,
- use_mouse=0, /* use mouse for scrolling toggle */
- console_file_wanted=0; /* should console be written to file ? */
-
- extern int beep_notify;
- int save_screen = TRUE;
-
- unsigned char s[550],parsedat[256],
- temp_str[128],
- path_name[_MAX_DRIVE+_MAX_DIR], /* character storage for the path name */
- colors[NCOLORS] = {2,1,0x70,0}, /* base colors */
- myipnum[4],
- *copybuf,
- *lineend = {"\r\n"},
- *blankline = {" "};
-
- 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 (*attrptr)(int ); /* pointer to the routine to change the attribute of a character on the screen */
-
- #define PSDUMP 128
-
- /* Definitions for telnet protocol */
-
- #define STNORM 0
-
- #define TEL_EOF 36
- #define SUSP 237
- #define ABORT 238
- #define SE 240
- #define NOP 241
- #define DM 242
- #define BREAK 243
- #define IP 244
- #define AO 245
- #define AYT 246
- #define EC 247
- #define EL 248
- #define GOAHEAD 249
- #define SB 250
- #define WILLTEL 251
- #define WONTTEL 252
- #define DOTEL 253
- #define DONTTEL 254
- #define IAC 255
-
-
- /* Assigned Telnet Options */
- #define BINARY 0
- #define ECHO 1
- #define RECONNECT 2
- #define SGA 3
- #define AMSN 4
- #define STATUS 5
- #define TIMING 6
- #define RCTAN 7
- #define OLW 8
- #define OPS 9
- #define OCRD 10
- #define OHTS 11
- #define OHTD 12
- #define OFFD 13
- #define OVTS 14
- #define OVTD 15
- #define OLFD 16
- #define XASCII 17
- #define LOGOUT 18
- #define BYTEM 19
- #define DET 20
- #define SUPDUP 21
- #define SUPDUPOUT 22
- #define SENDLOC 23
- #define TERMTYPE 24
- #define EOR 25
- #define TACACSUID 26
- #define OUTPUTMARK 27
- #define TERMLOCNUM 28
- #define REGIME3270 29
- #define X3PAD 30
- #define NAWS 31
- #define TERMSPEED 32
- #define TFLOWCNTRL 33
- #define LINEMODE 34
- #define MODE 1
- #define EDIT 1
- #define TRAPSIG 2
- #define MODE_ACK 4
- #define SOFT_TAB 8
- #define LIT_ECHO 16
-
- #define FORWARDMASK 2
-
- #define SLC 3
- #define NO_SUPPORT 0
- #define CANTCHANGE 1
- #define SLC_VALUE 2
- #define SLC_DEFAULT 3
- #define SLC_LEVELBITS 3
- #define SLC_ACK 128
-
- #define SLC_SYNCH 1
- #define SLC_BRK 2
- #define SLC_IP 3
- #define SLC_AO 4
- #define SLC_AYT 5
- #define SLC_EOR 6
- #define SLC_ABORT 7
- #define SLC_EOF 8
- #define SLC_SUSP 9
- #define SLC_EC 10
- #define SLC_EL 11
- #define SLC_EW 12
- #define SLC_RP 13
- #define SLC_LNEXT 14
- #define SLC_XON 15
- #define SLC_XOFF 16
- #define SLC_FORW1 17
- #define SLC_FORW2 18
- #define SLC_MCL 19
- #define SLC_MCR 20
- #define SLC_MCWL 21
- #define SLC_MCWR 22
- #define SLC_MCBOL 23
- #define SLC_MCEOL 24
- #define SLC_INSRT 25
- #define SLC_OVER 26
- #define SLC_ECR 27
- #define SLC_EWR 28
- #define SLC_EBOL 29
- #define SLC_EEOL 30
-
- #define XDISPLOC 35
- #define XOPTIONS 255
-
-
- #define ESCFOUND 5
- #define IACFOUND 6
- #define NEGOTIATE 1
-
- char *telstates[]={
- "Subnegotiation End",
- "NOP",
- "Data Mark",
- "Break",
- "Interrupt Process",
- "Abort Output",
- "Are You There",
- "Erase Character",
- "Erase Line",
- "Go Ahead",
- "Subnegotiate",
- "Will",
- "Won't",
- "Do",
- "Don't"
- };
-
- char *teloptions[256]={
- "Binary", /* 0 */
- "Echo",
- "Reconnection",
- "Supress Go Ahead",
- "Message Size Negotiation",
- "Status", /* 5 */
- "Timing Mark",
- "Remote Controlled Trans and Echo",
- "Output Line Width",
- "Output Page Size",
- "Output Carriage-Return Disposition", /* 10 */
- "Output Horizontal Tab Stops",
- "Output Horizontal Tab Disposition",
- "Output Formfeed Disposition",
- "Output Vertical Tabstops",
- "Output Vertical Tab Disposition", /* 15 */
- "Output Linefeed Disposition",
- "Extended ASCII",
- "Logout",
- "Byte Macro",
- "Data Entry Terminal", /* 20 */
- "SUPDUP",
- "SUPDUP Output",
- "Send Location",
- "Terminal Type",
- "End of Record", /* 25 */
- "TACACS User Identification",
- "Output Marking",
- "Terminal Location Number",
- "3270 Regime",
- "X.3 PAD", /* 30 */
- "Negotiate About Window Size",
- "Terminal Speed",
- "Toggle Flow Control",
- "Linemode",
- "X Display Location", /* 35 */
- "36","37","38","39",
- "40","41","42","43","44","45","46","47","48","49",
- "50","51","52","53","54","55","56","57","58","59",
- "60","61","62","63","64","65","66","67","68","69",
- "70","71","72","73","74","75","76","77","78","79",
- "80","81","82","83","84","85","86","87","88","89",
- "90","91","92","93","94","95","96","97","98","99",
- "100","101","102","103","104","105","106","107","108","109",
- "110","111","112","113","114","115","116","117","118","119",
- "120","121","122","123","124","125","126","127","128","129",
- "130","131","132","133","134","135","136","137","138","139",
- "140","141","142","143","144","145","146","147","148","149",
- "150","151","152","153","154","155","156","157","158","159",
- "160","161","162","163","164","165","166","167","168","169",
- "170","171","172","173","174","175","176","177","178","179",
- "180","181","182","183","184","185","186","187","188","189",
- "190","191","192","193","194","195","196","197","198","199",
- "200","201","202","203","204","205","206","207","208","209",
- "210","211","212","213","214","215","216","217","218","219",
- "220","221","222","223","224","225","226","227","228","229",
- "230","231","232","233","234","235","236","237","238","239",
- "240","241","242","243","244","245","246","247","248","249",
- "250","251","252","253","254",
- "Extended Options List" /* 255 */
- };
-
- char *LMoptions[]={
- "None",
- "SYNCH",
- "BREAK",
- "IP",
- "ABORT OUTPUT",
- "AYT",
- "EOR",
- "ABORT",
- "EOF",
- "SUSP",
- "EC",
- "EL",
- "EW",
- "RP",
- "LNEXT",
- "XON",
- "XOFF",
- "FORW1",
- "FORW2",
- "MCL",
- "MCR",
- "MCWL",
- "MCWR",
- "MCBOL",
- "MCEOL",
- "INSRT",
- "OVER",
- "ECR",
- "EWR",
- "EBOL",
- "EEOL"
- };
-
- char *LMflags[]={
- "NOSUPPORT",
- "CANTCHANGE",
- "VALUE",
- "DEFAULT"
- };
-
- #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] ...")
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- int i,j;
- char *config;
-
- numline=23;
- copybuf=NULL;
- machparm = 1000; /* large number */
-
- config=(getenv("CONFIG.TEL"));
- if(config)
- Shostfile(config);
-
- /*
- * work on parms
- */
-
- examineCommandLine(argc,argv);
-
- if (save_screen)
- 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 */
- save_cursor(); /* save the user's keyboard cursor type */
- 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);
- n_puts("NCSA Telnet 2.3.03, reading configuration file . . .");
-
- if(*argv[1]=='?' || argc==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");
- n_puts(" -n disable screen restore\n");
- exit(1);
- }
-
- /*
- * initialize the default keyboard settings
- */
- if((j=initkbfile())<0) { /* check for correct keyboard initialization */
- printf("Error reading default settings from telnet.key\n");
- printf("Please make certain this file is in the same directory as telbin.exe\n");
- getch();
- } /* end if */
- initoutputfile(); /* initialize the output mapping */
-
- /*
- * initialize network stuff
- */
- if(j=Snetinit()) {
- wrest(console);
- errhandle();
- printf("Error initializing network or getting configuration file\n\r");
- switch (j) {
- case -1:
- printf("Cannot initialize board.\n");
- break;
-
- case -5:
- printf("Error in config.tel file.\n");
- break;
-
- case -2:
- printf("RARP failed!!\n");
- break;
-
- case -3:
- printf("BOOTP failed!!\n");
- break;
-
- case -4:
- printf("X25 Initialization Failed!!\n");
- break;
-
- default:
- printf("Error from Snetinit()=%d\n",j);
- break;
- }
- if(j<-1) /* network initialized, special case */
- netshut();
- exit(1);
- }
-
- 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;
-
- /* Check to see if we need to enter 43 or 50 line mode */
- if(def.ega43==1)
- numline=41;
- else if (def.ega43==2)
- numline=48;
- else {
- numline=23; /***** NEED TO ADD SUPPORT FOR MODE CURRENT */
- ega24();
- }
-
- n_window(0,0,numline,79); /* vt100 size */
- if(def.ega43)
- ega43();
- 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();
-
- VSsetrgn(console->vs,0,0,79,numline);
- 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(30)) { /* 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);
- }
- strcpy(console->mname,"Console");
- /*
- * introductions on the console window
- */
- i=console->vs;
- RSvis(-1);
- vprint(i,"\n\n Console messages:\n\r\nNCSA Telnet\r\n");
- vhead(i);
-
- #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 (or Appletelk) 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]);
-
- install_break((int *)&foundbreak); /* install our BREAK handler */
-
- 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 (EXIT_TELNET!=dosessions()); /* serve all sessions, events */
- endall();
- return(0);
- }
-
- extern char *commandLineOveride; /* defined in confile.h */
-
- 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;
- break;
-
- case 'e':
- if (commandLineOveride)
- size = strlen(commandLineOveride);
- 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':
- 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 */
- }
- }
- }
-
- /************************************************************************/
- /* vhead
- * place the header for new sessions in.
- */
- void vhead(v)
- int v;
- {
- vprint(v,"\r\nNational Center for Supercomputing Applications\r\n");
- vprint(v,"NCSA Telnet for the PC version 2.3.03\r\n");
- vprint(v,"\nAlt-H presents a summary of special keys \n\r\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.
- */
-
- 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, ginkey=0,ch,
- c, /* the color saved */
- cl,dat,cvs;
- int m1=3,m2=0,m3=0,m4=0; /* mouse variables */
- int x1,x2,y1,y2; /* temp variables for VSgetrgn test when exiting scrlback mode */
- unsigned int sw;
- char gindata[5]; /* variable to store gin data in when returning fron VGgindata */
- struct twin *t1;
- static char lch=-1;
- char *p=NULL, *outstring=NULL;
-
- if (ginon && current->termstate==TEKTYPE) { /* check for GIN mode for tektronics */
- ch=n_chkchar();
- mousecl(&m1,&m2,&m3,&m4);
- if ((ch!= -1)||(m2&1)) {
- printf("ch == %d\n",ch);
- if ((ch!='\r')&&(ch!='\n')&&(ch>0)) lch=(char) ch;
- printf("lch %d\n",lch);
- printf("mousecl returned m2== %x\n",m2);
- if ((lch!= -1)&&(m2&1)) {
- printf("sending info. lch= %c\n",lch);
- VGgindata(current->vs,m3,m4,lch,gindata); /* send the mouse cursor */
- /* position to be translated */
- /* by VGgindata and the */
- /* information returned */
- /* in gindata */
-
- #ifndef NOT
- RSsendstring(current->vs,gindata,5); /* return GIN data across network */
- #else
- printf("netwrite returned %d\n",netwrite(screens[current->vs]->pnum,gindata,5));
- #endif
- lch=-1; /* clear last char buffer */
- resetgin(); /* reset GIN mode */
- } /* end if */
- } /* end if */
- }
-
- 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);
- }
- /*
- * 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);
- }
- /*
- * 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);
- }
- 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();
- }
- else { /* restore view 0 */
- if(c==' ') {
- viewmode=10;
- } else
- if(c>128)
- dokey(current,c); /* dokey might change view, if so, don't reset view 0 */
- }
- }
- 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,"\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;
- }
- 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 -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;
-
- case 11: /* paste copy buffer to current session */
- temp-=netwrite(current->pnum,(char *)©buf[(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);
- }
- /*
- * In scroll lock mode, take keys only for the scrollback,
- * The scrollback routine will never block, so we keep servicing events.
- */
- scrollback(console);
- 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);
-
- /* Start negotiation on network */
- sprintf(parsedat,"%c%c%c",IAC,DOTEL,ECHO);
- netwrite(dat,parsedat,3);
- sprintf(parsedat,"%c%c%c",IAC,DOTEL,SGA);
- netwrite(dat,parsedat,3);
- sprintf(parsedat,"%c%c%c",IAC,WILLTEL,NAWS);
- netwrite(dat,parsedat,3);
-
- /* Print to the console what we just did */
- tprintf(cvs,"SEND: %s %s\r\n",telstates[DOTEL-SE],teloptions[ECHO]);
- tprintf(cvs,"SEND: %s %s\r\n",telstates[DOTEL-SE],teloptions[SGA]);
- tprintf(cvs,"SEND: %s %s\r\n",telstates[WILLTEL-SE],teloptions[TERMTYPE]);
- tprintf(cvs,"SEND: %s %s\r\n",telstates[WILLTEL-SE],teloptions[LINEMODE]);
- tprintf(cvs,"SEND: %s %s\r\n",telstates[WILLTEL-SE],teloptions[NAWS]);
-
- 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 */
- vprint(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 */
- 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);
- 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);
- vprint(cvs,"\r\n");
- tprintf(console->vs,"Domain Port is:%d\r\n",mp->port);
- viewmode=10;
- }
- break;
-
- /*
- * FTP status events.
- */
- 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 */
- 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);
- if (dat == 407)
- inv_port_err(0,0,NULL);
- default:
- break;
- }
- }
- /*
- * update the FTP spinner if we are in ftp, and update the clock
- */
- else {
- if(ftpact && (n_clicks()>lastt + 10)) {
- ftpstart((char)(ftpact+2),s);
- lastt=n_clicks();
- }
- if(def.clock) {
- if((current->termstate<TEKTYPE) && (!ftpact)) {
- 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 */
- } /* end else */
- return(c);
- }
-
- /*********************************************************************/
- /* inprocess
- * take incoming data and process it. Close the connection if it
- * is the end of the connection.
- */
- int inprocess(tw)
- 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);
- }
-
- if(cnt)
- parse(tw,s,cnt); /* display on screen, etc.*/
- return(0);
- }
-
- /*********************************************************************/
- /* endall
- * clean up and leave
- */
- void endall()
- {
- netshut();
-
- 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 */
- restore_cursor(); /* restore the keyboard cursor */
- if (save_screen)
- end_text();
- exit(0); /* return to DOS */
- }
-
- /*********************************************************************/
- /* errhandle
- * write error messages to the console window
- */
- void 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);
- if (j == 407)
- inv_port_err(0,0,NULL);
- }
- }
-
- /*********************************************************************/
- /* vprint
- * print to a virtual screen
- */
- void vprint(w,str)
- int w;
- char *str;
- {
- #ifdef CONSOLEDEBUG
- VSwrite(current->vs,str,strlen(str)); /* dump all messages to the current screen */
- #else
- VSwrite(w,str,strlen(str));
- #endif
- }
-
- /*********************************************************************/
- /* tprintf
- * print a formatted string to a virtual screen
- */
- #ifdef __TURBOC__
- void tprintf(int w,char *fmt,...)
- #else
- void tprintf(w,fmt,...)
- int w;
- char *fmt;
- #endif
- {
- va_list arg_ptr;
-
- va_start(arg_ptr,fmt); /* get a pointer to the variable arguement list */
- vsprintf(temp_str,fmt,arg_ptr); /* print the formatted string into a buffer */
- va_end(arg_ptr);
- #ifdef CONSOLEDEBUG
- VSwrite(current->vs,temp_str,strlen(temp_str)); /* dump all messages to the current screen */
- #else
- VSwrite(w,temp_str,strlen(temp_str));
- #endif
- }
-
- /*********************************************************************/
- /* 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 IAC to change modes.
- */
- void parse(tw,st,cnt)
- struct twin *tw;
- int cnt;
- unsigned char *st;
- {
- int cv,i;
- unsigned char *mark,*orig;
-
- cv=console->vs;
-
- #ifdef NEGOTIATEDEBUG
- vprint(cv,"\r\n");
- for(i = 0; i < cnt; i++) {
- int j;
- for(j=0; (j < 16) && ((i + j) < cnt); j++) {
- tprintf(cv,"%2.2X ", *(unsigned char *) (st + i + j));
- }
- i += j - 1;
- vprint(cv,"\r\n");
- }
- vprint(cv,"\r\n");
- #endif /* NEGOTIATEDEBUG */
-
- 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)&&(def.tek)) { /* esc-FF */
- if(tw->termstate==VTEKTYPE) {
- vprint(cv,"\r\n Entering Tek mode \r\n");
- 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==IAC) { /* real data=255 */
- st++; /* real 255 will get sent */
- tw->telstate=STNORM;
- break;
- }
-
- if(*st>239) {
- tw->telstate=*st++; /* by what the option is */
- break;
- }
-
- tprintf(cv,"\r\n strange telnet option %s",itoa(*st,s,10));
- orig=st;
- tw->telstate=STNORM;
- break;
-
- case EL: /* received a telnet erase line command */
- case EC: /* received a telnet erase character command */
- case AYT: /* received a telnet Are-You-There command */
- case AO: /* received a telnet Abort Output command */
- case IP: /* received a telnet Interrupt Process command */
- case BREAK: /* received a telnet Break command */
- case DM: /* received a telnet Data Mark command */
- case NOP: /* received a telnet No Operation command */
- case SE: /* received a telnet Subnegotiation End command */
- tprintf(cv,"RECV: %s\r\n",telstates[tw->telstate-SE]);
- tw->telstate=STNORM;
- orig=st;
- break;
-
- case GOAHEAD: /* telnet go ahead option*/
- tw->telstate=STNORM;
- orig=st;
- break;
-
- case DOTEL: /* received a telnet DO negotiation */
- tprintf(cv,"RECV: %s %s\r\n",telstates[tw->telstate-SE],teloptions[*st]);
- switch(*st) {
- case SGA: /* Suppress go-ahead */
- if(!tw->igoahead) { /* suppress go-ahead */
- tprintf(cv,"SEND: %s %s\r\n",telstates[WILLTEL-SE],teloptions[*st]);
- sprintf(parsedat,"%c%c%c",IAC,WILLTEL,*st);
- netwrite(tw->pnum,parsedat,3); /* take it */
- tw->igoahead=1;
- }
- else
- tprintf(cv,"NO REPLY NEEDED: %s %s\r\n",telstates[WILLTEL-SE],teloptions[SGA]);
- tw->telstate=STNORM;
- orig=++st;
- break;
-
- case TERMTYPE: /* terminal type negotiation */
- if(!tw->termsent) {
- tw->termsent=1;
- tprintf(cv,"SEND: %s %s\r\n",telstates[WILLTEL-SE],teloptions[*st]);
- sprintf(parsedat,"%c%c%c",IAC,WILLTEL,*st);
- netwrite(tw->pnum,parsedat,3);
- } /* end if */
- else
- tprintf(cv,"NO REPLY NEEDED: %s %s\r\n",telstates[WILLTEL-SE],teloptions[TERMTYPE]);
- tw->telstate=STNORM;
- orig=++st;
- break;
-
- #ifdef LMODE
- case LINEMODE: /* linemode negotiation */
- sprintf(parsedat,"%c%c%c",IAC,WILLTEL,LINEMODE);
- netwrite(tw->pnum,parsedat,3);
- vprint(cv,"SEND: SB LINEMODE SLC\r\n");
- sprintf(parsedat,"%c%c%c%c",IAC,SB,LINEMODE,SLC);
- netwrite(tw->pnum,parsedat,4);
-
- for(i=1; i<NUMLMODEOPTIONS; i++) {
- if(tw->slc[i]==-1)
- sprintf(parsedat,"%c%c%c",i,NO_SUPPORT,0);
- else
- sprintf(parsedat,"%c%c%c",i,CANTCHANGE,(char)tw->slc[i]);
-
- netwrite(tw->pnum,parsedat,3);
- tprintf(cv," %s %s %s\r\n",LMoptions[i],(tw->slc[i]==-1) ? "NO_SUPPORT" : "CANTCHANGE",(tw->slc[i]==-1) ? "0" : itoa(tw->slc[i],s,10));
- } /* end for */
-
- sprintf(parsedat,"%c%c",IAC,SE);
- netwrite(tw->pnum,parsedat,2);
- vprint(cv,"\r\n");
- tw->telstate=STNORM;
- orig=++st;
- break;
- #endif /* LMODE */
-
-
- case NAWS: /* Negotiate About Window Size */
- sprintf(parsedat,"%c%c%c%c%c%c%c%c%c",IAC,SB,NAWS,(char)0,(char)tw->width,(char)0,(char)tw->rows,IAC,SE);
- netwrite(tw->pnum,parsedat,9);
- vprint(cv,"SEND: SB NAWS 0 ");
- vprint(cv,itoa(tw->width,parsedat,10));
- vprint(cv," 0 ");
- vprint(cv,itoa(tw->rows,parsedat,10));
- vprint(cv," IAC SE");
- tw->telstate=STNORM;
- /* new */ orig=++st;
- break;
-
- default:
- tprintf(cv,"SEND: %s %s\r\n",telstates[WONTTEL-SE],teloptions[*st]);
- sprintf(parsedat,"%c%c%c",IAC,WONTTEL,*st++);
- netwrite(tw->pnum,parsedat,3); /* refuse it */
- tw->telstate=STNORM;
- orig=st;
- break;
-
- }
- break;
-
- case DONTTEL: /* Received a telnet DONT option */
- tprintf(cv,"RECV: %s %s\r\n",telstates[tw->telstate-SE],teloptions[*st]);
- tw->telstate=STNORM;
- orig=++st;
- break;
-
- case WILLTEL: /* received a telnet WILL option */
- tprintf(cv,"RECV: %s %s\r\n",telstates[tw->telstate-SE],teloptions[*st]);
- tw->telstate=STNORM;
- switch(*st++) {
- case SGA: /* suppress go-ahead */
- if(tw->ugoahead)
- break;
-
- tw->ugoahead=1;
- tprintf(cv,"SEND: %s %s\r\n",telstates[DOTEL-SE],teloptions[*st]);
- sprintf(parsedat,"%c%c%c",IAC,DOTEL,3); /* ack */
- netwrite(tw->pnum,parsedat,3);
- break;
-
- case ECHO: /* echo */
- if(tw->echo)
- break;
-
- tw->echo=1;
- tprintf(cv,"SEND: %s %s\r\n",telstates[DOTEL-SE],teloptions[*st]);
- sprintf(parsedat,"%c%c%c",IAC,DOTEL,1); /* ack */
- netwrite(tw->pnum,parsedat,3);
- netwrite(tw->pnum,tw->linemode,strlen(tw->linemode));
- tw->linemode[0]='\0';
- break;
-
- case TIMING: /* Timing mark */
- tw->timing=0;
- break;
-
- default:
- tprintf(cv,"SEND: %s %s\r\n",telstates[DONTTEL-SE],teloptions[*st]);
- sprintf(parsedat,"%c%c%c",IAC,DONTTEL,*(st-1));
- netwrite(tw->pnum,parsedat,3); /* refuse it */
- break;
- } /* end switch */
- orig=st;
- break;
-
- case WONTTEL: /* Received a telnet WONT option */
- tprintf(cv,"RECV: %s %s\r\n",telstates[tw->telstate-SE],teloptions[*st]);
- tw->telstate=STNORM;
- switch(*st++) { /* which option? */
- case ECHO: /* echo */
- if(!tw->echo)
- break;
-
- tw->echo=0;
- sprintf(parsedat,"%c%c%c",IAC,DONTTEL,ECHO);
- netwrite(tw->pnum,parsedat,3); /* OK with us */
- break;
-
- case TIMING: /* Telnet timing mark option */
- tw->timing=0;
- break;
-
- default:
- break;
- }
- orig=st;
- break;
-
- case SB: /* telnet sub-options negotiation */
- tw->telstate=NEGOTIATE;
- orig=st;
- i=tw->substate=0; /* Defined for each */
- break;
-
- case NEGOTIATE:
- if(tw->substate<200) {
- switch(*st) {
- case IAC:
- if(*(st+1)==IAC) { /* skip over double IAC's */
- parsedat[i++]=*st++;
- parsedat[i++]=*st++;
- } /* end if */
- else {
- parsedat[i]='\0';
- tw->substate=*st++;
- } /* end else */
- break;
-
- default:
- parsedat[i++]=*st++;
- break;
- } /* end switch */
- } /* end if */
- else {
- switch(tw->substate) {
- case IAC:
- tw->substate=*st++;
- if(tw->substate==SE) {
- switch(parsedat[0]) {
- case TERMTYPE:
- if(parsedat[1]==1) {
- char s[100];
-
- netwrite(tw->pnum,"\377\372\030\000",4);
- sprintf(s,"%s\377\360",def.termtype);
- netwrite(tw->pnum, s, strlen(s));
- tprintf(cv,"RECV: SB TERMINAL-TYPE SEND\r\nSEND: SB TERMINAL-TYPE IS %s\r\n",def.termtype);
- } /* end if */
- break;
-
- case LINEMODE:
- switch(parsedat[1]) {
- char s[50];
-
- case MODE:
- if(parsedat[2] & EDIT)
- tw->lmflag=1;
- else
- tw->lmflag=0;
-
- sprintf(s,"%c%c%c%c",IAC,SB,LINEMODE,MODE);
- netwrite(tw->pnum,s,4);
- sprintf(s,"%c%c%c",parsedat[2]|MODE_ACK,IAC,SE);
- netwrite(tw->pnum,s,3);
- vprint(cv,"RECV: LINEMODE MODE ");
- vprint(cv,itoa(parsedat[2],s,10));
- vprint(cv,"\r\n");
- break;
-
- case DOTEL:
- netwrite(tw->pnum,"\377\372\042",3);
- sprintf(s,"%c\002\377\360",WONTTEL);
- netwrite(tw->pnum,s,strlen(s));
- break;
-
- case WILLTEL:
- netwrite(tw->pnum,"\377\372\042",3);
- sprintf(s,"%c\002\377\360",DONTTEL);
- netwrite(tw->pnum,s,strlen(s));
- break;
-
- case SLC:
- vprint(cv,"RECV: SB LINEMODE SLC\r\n");
- for(i=2;(parsedat[i]!='\0') && (parsedat[i]!=IAC); i+=3) {
- if(parsedat[i+1] & SLC_ACK)
- tprintf(cv," [%2.2X %2.2X %2.2X] (%d) %s %s|ACK %d\r\n",
- parsedat[i], parsedat[i+1], parsedat[i+2], parsedat[i] ,
- LMoptions[parsedat[i]],LMflags[parsedat[i+1] & SLC_LEVELBITS],
- parsedat[i+2]);
- else
- tprintf(cv," [%2.2X %2.2X %2.2X] (%d) %s %s %d\r\n",
- parsedat[i], parsedat[i+1], parsedat[i+2], parsedat[i] ,
- LMoptions[parsedat[i]],LMflags[parsedat[i+1] & SLC_LEVELBITS],
- parsedat[i+2]);
- if (parsedat[i+2]==IAC) i++;
- } /* end for */
-
- /* First check to see if we need to reply */
-
- for(i=2; (parsedat[i]!='\0') && (parsedat[i]!=IAC); i+=3)
- if(!(parsedat[i+1] & SLC_ACK))
- break;
-
- /* if we do then send a reply */
- if((parsedat[i]!=IAC) && (parsedat[i]!='\0')) {
- vprint(cv,"SEND: SB LINEMODE SLC\r\n");
- sprintf(s,"%c%c%c%c",IAC,SB,LINEMODE,SLC);
- netwrite(tw->pnum,s,4);
-
- /*--------------------------------------------------------------------*/
- for (i=2; (parsedat[i]!='\0') && (parsedat[i]!=IAC); i+=3) {
-
- if (!(parsedat[i+1] & SLC_ACK)) { /* no response of ACK set */
- if (parsedat[i+1]!=NO_SUPPORT) {
- if (tw->slc[parsedat[i]]==-1) {
- sprintf(s,"%c%c%c",parsedat[i],NO_SUPPORT,0);
-
- tprintf(cv, " [%2.2X %2.2X %2.2X] (%d) %s %s %d\r\n",
- s[0], s[1], s[2], parsedat[i],
- LMoptions[parsedat[i]], "NO_SUPPORT", 0);
- } else {
- sprintf(s,"%c%c%c",parsedat[i],CANTCHANGE,
- tw->slc[parsedat[i]]);
-
- tprintf(cv, " [%2.2X %2.2X %2.2X] (%d) %s %s %d\r\n",
- s[0], s[1], s[2], parsedat[i],
- LMoptions[parsedat[i]], "CANTCHANGE",tw->slc[parsedat[i]]);
- }
- } else { /* No_Support case */
- if (tw->slc[parsedat[i]] != -1) { /* only need to do */
- /* something if we support*/
- if (parsedat[i] < NUMLMODEOPTIONS)
- tw->slc[parsedat[i]] = -1;
- sprintf(s,"%c%c%c",parsedat[i],
- (unsigned char)(NO_SUPPORT | SLC_ACK), 0);
-
- tprintf(cv, " [%2.2X %2.2X %2.2X] (%d) %s %s %d\r\n",
- s[0], (unsigned char) s[1], s[2], parsedat[i],
- LMoptions[parsedat[i]], "NO_SUPPORT|ACK", 0);
- }
- }
- netwrite(tw->pnum,s,3);
- }
- if (parsedat[i+2]==IAC) i++;
- }
- /*----------------------------------------------------------------------*/
-
- sprintf(s,"%c%c",IAC,SE);
- netwrite(tw->pnum,s,2);
- } /* end if */
-
- /* otherwise just exit */
- break;
-
- default:
- break;
- } /* end switch */
- break;
-
- default:
- break;
- } /* end switch */
- } /* end if */
- orig=st;
- tw->telstate=STNORM;
- break;
-
- default:
- orig=st;
- tw->telstate=STNORM;
- break;
- } /* end switch */
- } /* end else */
- 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<IAC) {
- if((!tw->binary) && (!tw->mapoutput))
- *st &= 127; /* mask off high bit */
- st++;
- }
- if(!tw->timing)
- parsewrite(tw,orig,st-orig);
- orig=st; /* forget what we have sent already */
- if(st<mark)
- switch (*st) {
- case IAC: /* 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 switch */
- } /* end if */
- } /* end while */
- }
-
- /*********************************************************************/
- /* parsewrite
- * write out some chars from parse
- * Has a choice of where to send the stuff
- */
- void 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
- */
-
- #ifndef UM
- 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,0,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(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 */
-
- } /* end else */
- }
-
-
- /*********************************************************************/
- /* newkey
- * filter for command key sequences
- */
- int newkey(t1)
- struct twin *t1;
- {
- int c;
- char s[3];
-
- if(foundbreak) {
- foundbreak=0;
- c='\003'; /* ctrl-c */
- if(t1->lmflag) { /* Telnet line mode is on */
- sprintf(s, "%c%c", IAC, IP);
- netwrite(t1->pnum, s, 2);
- vprint(console->vs, "SEND: IAC IP\r\n");
- c = 0; /* don't want ^C on beginning of next line */
- } /* end if */
- } else {
- if(ginon)
- c=0;
- else
- if(t1->lmflag) { /* Telnet line mode is on */
- c=RSgets(t1->vs,t1->linemode,79,(char)(!t1->echo));
- if((c==13) || (c == t1->slc[SLC_SUSP])) { /* pressed return or susp */
- parse(t1,"\r\n",2); /* echo the return */
- strcat(t1->linemode,"\n");
- netpush(t1->pnum);
- netwrite(t1->pnum,t1->linemode,strlen(t1->linemode));
- t1->linemode[0]='\0';
- if (c == t1->slc[SLC_SUSP]) {
- sprintf(s, "%c%c", IAC, SUSP);
- netwrite(t1->pnum, s, 2);
- vprint(console->vs, "SEND: IAC SUSP\r\n");
- }
- 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';
- }
- }
- }
- 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,(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 */
-
- if(c<=0)
- return(c);
- return(dokey(t1,c));
- }
-
- /************************************************************************/
- /* screendump
- * dump the contents of the current screen into the capture file
- *
- */
- void screendump(struct twin *t1)
- {
- int y, /* variable to count the line of the screen we are dumping */
- 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);
- for(y=0; y<numline+1; 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(t1,c)
- struct twin *t1;
- int c;
- {
- int i;
-
- switch (c) {
- case BACKSPACE: /* backspace */
- 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,(char *)&c,1); /* write a NUL */
- break;
-
- 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;
-
- 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 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())) {
- vprint(console->vs,"\r\nCannot open capture file ");
- break;
- } /* end if */
- capstat("Capt",1);
- current->capon=capon=1;
- } /* end if */
- else {
- vprint(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 t he capture file */
- vprint(console->vs,"\r\nCannot open capture file for screendump ");
- wrest(console);
- viewmode=2;
- break;
- } /* end if */
- screendump(current); /* 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); /* dump the screen */
- else {
- vprint(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]);
- dosescape();
- viewmode=5;
- n_color(i);
- c=0;
- break;
-
- case ALTF: /* an ftp command */
- strcpy(s,"ftp ");
- if((!Sneedpass())&&(current->ftpopts)) {
- strcat(s,current->ftpopts);
- strcat(s," ");
- }
- 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;
-
- #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;
- }
- 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;
-
- #ifdef MEMORY_DEBUG
- case ALTJ: /* for debuggin' purposes */
- mem_file=fopen("c:\mem_dump","w");
- if (mem_file) {
- Mem_Display(mem_file);
- vprint(console->vs,"wrote mem_file.\r\n");
- fclose(mem_file);
- }
- else vprint(console->vs,"failed mem_file write.\r\n");
-
- c=0;
- break;
- #endif
-
- 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;
- }
- VSreset(current->vs); /* reset's emulator */
- }
- 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 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;
- }
- c=0;
- break;
-
- case ALTW: /* send our password to the machine we are connected to, for use in ftp'ing back to oneself */
- bypass_passwd=1; /* set the flag to bypass the password check */
- c=0;
- 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 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);
- }
-
- /***************************************************************************/
- /* dosescape
- * escape to dos for processing
- * put the connections to automated sleep while in DOS
- */
- void dosescape(void )
- {
- int i;
- char *command_shell; /* the command shell to shell out to */
- char oldDir[1024];
-
- if(ftpact || rcpact) {
- n_puts("Please wait until file transfer is finished");
- n_puts("\nPress any key to continue");
- return;
- }
-
- getcwd(oldDir,1023);
- 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
- */
- restore_break(); /* restore the break status */
- /* if(def.ega43>0) /* if we are 43 or 50 line switch to 24 line */
- /* ega24(); */
- restore_cursor(); /* restore the user's keyboard cursor */
- remove_break(); /* restore the previous ctrl-c interupt handler */
-
- netsleep(0);
-
- tinst();
-
- /* set_mode(); /* set video mode to what it was before telnet */
-
- 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();
-
- if(i<0) {
- n_puts("\n\nError loading DOS shell");
- n_puts("Make sure DOS shell is specified under COMSPEC.");
- n_puts("It must also be in a directory which is in your PATH statement.");
- }
- chdir(oldDir);
-
- install_break((int *)&foundbreak); /* install our ctrl-c interupt handler */
- save_cursor(); /* save the user's keyboard cursor */
- /* if(def.ega43) */
- /* ega43(); /* switch back to 43 line mode */
- /* else */
- /* ega24(); */
- n_row();
- n_puts("\nPress any key to return to telnet");
- save_break(); /* save the break state again */
- }
-
- /***********************************************************************/
- /* 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;
- p->echo=1;
- p->binary=0;
- 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->mapoutput=default_mapoutput; /* turn output mapping on if specified */
- for(i=1; i<NUMLMODEOPTIONS; i++)
- p->slc[i]=-1;
- p->sstat='*'; /* connection not opened yet */
-
- if(mp==NULL) {
- p->bksp=127;
- p->del=8;
- p->crfollow=10;
- p->halfdup=0;
- p->vtwrap=1;
- p->bkscroll=0;
- p->width=80;
- p->rows=numline+1;
- p->slc[SLC_IP]=3;
- p->slc[SLC_EC]=127;
- p->slc[SLC_EL]=21;
- p->slc[SLC_SUSP]=26;
- p->slc[SLC_EOF]=4;
- p->slc[SLC_ABORT]=3;
- p->ftpopts=NULL;
-
- 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 */
- VSsetlines(i,numline+1);
- VSsetrgn(i,0,0,79,numline);
- }
- 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->rows=numline+1;
- 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_IP]=3;
- p->slc[SLC_EC]=mp->bksp;
- p->slc[SLC_EL]=21;
- p->slc[SLC_EOF]=4;
- p->slc[SLC_SUSP]=26;
- p->slc[SLC_ABORT]=3;
- p->ftpopts=mp->ftpoptions;
-
- i=VSnewscreen(mp->bkscroll,1,80,0); /* create a new virtual screen */
- 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 */
- }
-
- if(i<0)
- return(NULL);
- p->vs=i;
- screens[i]=p; /* we need to know where it is */
- return(p);
- }
-
- /***********************************************************************/
-
- void wrest(t)
- struct twin *t;
- {
- RSvis(t->vs);
- statline(); /* done before, moves cursor */
- VSredraw(t->vs,0,0,79,numline); /* redisplay, resets cursor correctly */
- }
-
- /***************************************************************************/
- void statline(void )
- {
- struct twin *t1,*t2;
- int wn;
- int i,c,sm,rw,cl;
-
- if(current==NULL || current==console || 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();
- 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);
- }
-
- /***********************************************************************/
- /* 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(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;
- }
- 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
- */
- void 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;
- } /* 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(t)
- struct twin *t;
- {
- VSdetatch(t->vs);
- free(t);
- } /* end freewin() */
-
- /************************************************************************/
- /*
- * hexbyte
- * return a byte taken from a string which contains hex digits
- */
- int 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
- int tekinit(dev)
- char *dev;
- {
- if(strlen(dev)<1)
- return(0);
- #ifdef OLD_WAY
- if(0>VGinit()) {
- vprint(console->vs,"\r\nCannot initialize Tektronix driver\r\n");
- return(-1);
- }
- else
- vprint(console->vs,"\r\nTektronix initialized\r\n");
- #else
- VGinit();
- vprint(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);
- }
-
- /***********************************************************************/
- /* function to write to file
- */
- void fdump(str)
- char *str;
- {
- fputs(str,tekfp);
- }
-
- void fdumpc(c)
- int c;
- {
- fputc(c,tekfp);
- }
-
- void endump(void )
- {
- VGclose(outdev);
- if(indev!=temptek) {
- VGclose(indev);
- if(tekfp) {
- fclose(tekfp);
- tekfp=NULL;
- }
- }
- }
-
- /***********************************************************************/
- /* 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);
- }
- #endif
-
- /*************************************************************************/
- /* addsess
- * Add a session to a named machine, or prompt for a machine to be named.
- */
- int addsess(st)
- 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);
- vprint(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);
- vprint(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]);
- }
- mp=Sgethost(st); /* gain access to host information */
- errhandle();
- if(!mp) {
- if(pflag)
- st[strlen(st)]='#'; /* Append port number */
- 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");
- if(!pflag)
- port=mp->port;
-
-
- /* try to serve the request */
- if( 0>(new=Snetopen(mp,port))) {
- 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
- int leavetek(void )
- {
- if(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)
- ega43();
- return(1);
- }
- return(0); /* we did nothing */
- }
- #endif
-
- /***********************************************************************/
- /* capstat
- * Print the capture status on the screen
- */
- void capstat(str,i)
- 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);
- }
-
- /***********************************************************************/
- /* 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(vs_win,value)
- int vs_win,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() */
-
- #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);
- }
-
- 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();
- }
- #endif
-