133685Sbostic /* 245233Sborman * Copyright (c) 1988, 1990 Regents of the University of California. 333685Sbostic * All rights reserved. 433685Sbostic * 542770Sbostic * %sccs.include.redist.c% 633685Sbostic */ 733685Sbostic 833685Sbostic #ifndef lint 9*56642Sralph static char sccsid[] = "@(#)commands.c 5.6 (Berkeley) 10/24/92"; 1033685Sbostic #endif /* not lint */ 1133685Sbostic 1236274Sminshall #if defined(unix) 1345241Swilliam #include <sys/param.h> 1446808Sdab #ifdef CRAY 1546808Sdab #include <sys/types.h> 1646808Sdab #endif 1736274Sminshall #include <sys/file.h> 1845241Swilliam #else 1945241Swilliam #include <sys/types.h> 2036274Sminshall #endif /* defined(unix) */ 2132144Sminshall #include <sys/socket.h> 2232144Sminshall #include <netinet/in.h> 2338689Sborman #ifdef CRAY 2446808Sdab #include <fcntl.h> 2538810Sborman #endif /* CRAY */ 2632144Sminshall 2732144Sminshall #include <signal.h> 2832144Sminshall #include <netdb.h> 2932144Sminshall #include <ctype.h> 3045008Skarels #include <pwd.h> 3135298Sminshall #include <varargs.h> 3246808Sdab #include <errno.h> 3332144Sminshall 3432144Sminshall #include <arpa/telnet.h> 3532144Sminshall 3634305Sminshall #include "general.h" 3734305Sminshall 3832381Sminshall #include "ring.h" 3932381Sminshall 4032144Sminshall #include "externs.h" 4132144Sminshall #include "defines.h" 4232144Sminshall #include "types.h" 4332144Sminshall 4446808Sdab #ifndef CRAY 4546808Sdab #include <netinet/in_systm.h> 4646808Sdab # if (defined(vax) || defined(tahoe) || defined(hp300)) && !defined(ultrix) 4746808Sdab # include <machine/endian.h> 4846808Sdab # endif /* vax */ 4946808Sdab #endif /* CRAY */ 5044361Sborman #include <netinet/ip.h> 5138689Sborman 5238689Sborman 5346808Sdab #ifndef MAXHOSTNAMELEN 5446808Sdab #define MAXHOSTNAMELEN 64 5546808Sdab #endif MAXHOSTNAMELEN 5640248Sborman 5746815Sdab #if defined(IPPROTO_IP) && defined(IP_TOS) 5846815Sdab int tos = -1; 5946815Sdab #endif /* defined(IPPROTO_IP) && defined(IP_TOS) */ 6046815Sdab 6132144Sminshall char *hostname; 6246808Sdab static char _hostname[MAXHOSTNAMELEN]; 6346808Sdab 6438689Sborman extern char *getenv(); 6532144Sminshall 6646808Sdab extern int isprefix(); 6746808Sdab extern char **genget(); 6846808Sdab extern int Ambiguous(); 6946808Sdab 7044361Sborman static call(); 7132144Sminshall 7232144Sminshall typedef struct { 7332144Sminshall char *name; /* command name */ 7438689Sborman char *help; /* help string (NULL for no help) */ 7532144Sminshall int (*handler)(); /* routine which executes command */ 7632144Sminshall int needconnect; /* Do we need to be connected to execute? */ 7732144Sminshall } Command; 7832144Sminshall 7938689Sborman static char line[256]; 8038689Sborman static char saveline[256]; 8132144Sminshall static int margc; 8232144Sminshall static char *margv[20]; 8332144Sminshall 8446808Sdab static void 8532144Sminshall makeargv() 8632144Sminshall { 8744361Sborman register char *cp, *cp2, c; 8832144Sminshall register char **argp = margv; 8932144Sminshall 9032144Sminshall margc = 0; 9132144Sminshall cp = line; 9232144Sminshall if (*cp == '!') { /* Special case shell escape */ 9338689Sborman strcpy(saveline, line); /* save for shell command */ 9432144Sminshall *argp++ = "!"; /* No room in string to get this */ 9532144Sminshall margc++; 9632144Sminshall cp++; 9732144Sminshall } 9844361Sborman while (c = *cp) { 9944361Sborman register int inquote = 0; 10044361Sborman while (isspace(c)) 10144361Sborman c = *++cp; 10244361Sborman if (c == '\0') 10332144Sminshall break; 10432144Sminshall *argp++ = cp; 10532144Sminshall margc += 1; 10644361Sborman for (cp2 = cp; c != '\0'; c = *++cp) { 10744361Sborman if (inquote) { 10844361Sborman if (c == inquote) { 10944361Sborman inquote = 0; 11044361Sborman continue; 11144361Sborman } 11244361Sborman } else { 11344361Sborman if (c == '\\') { 11444361Sborman if ((c = *++cp) == '\0') 11544361Sborman break; 11644361Sborman } else if (c == '"') { 11744361Sborman inquote = '"'; 11844361Sborman continue; 11944361Sborman } else if (c == '\'') { 12044361Sborman inquote = '\''; 12144361Sborman continue; 12244361Sborman } else if (isspace(c)) 12344361Sborman break; 12444361Sborman } 12544361Sborman *cp2++ = c; 12644361Sborman } 12744361Sborman *cp2 = '\0'; 12844361Sborman if (c == '\0') 12932144Sminshall break; 13044361Sborman cp++; 13132144Sminshall } 13232144Sminshall *argp++ = 0; 13332144Sminshall } 13432144Sminshall 13532144Sminshall /* 13632144Sminshall * Make a character string into a number. 13732144Sminshall * 13832144Sminshall * Todo: 1. Could take random integers (12, 0x12, 012, 0b1). 13932144Sminshall */ 14032144Sminshall 14146808Sdab static 14232144Sminshall special(s) 14346808Sdab register char *s; 14432144Sminshall { 14532144Sminshall register char c; 14632144Sminshall char b; 14732144Sminshall 14832144Sminshall switch (*s) { 14932144Sminshall case '^': 15032144Sminshall b = *++s; 15132144Sminshall if (b == '?') { 15232144Sminshall c = b | 0x40; /* DEL */ 15332144Sminshall } else { 15432144Sminshall c = b & 0x1f; 15532144Sminshall } 15632144Sminshall break; 15732144Sminshall default: 15832144Sminshall c = *s; 15932144Sminshall break; 16032144Sminshall } 16132144Sminshall return c; 16232144Sminshall } 16332144Sminshall 16432144Sminshall /* 16532144Sminshall * Construct a control character sequence 16632144Sminshall * for a special character. 16732144Sminshall */ 16846808Sdab static char * 16932144Sminshall control(c) 17040245Sborman register cc_t c; 17132144Sminshall { 17244361Sborman static char buf[5]; 17346808Sdab /* 17446808Sdab * The only way I could get the Sun 3.5 compiler 17546808Sdab * to shut up about 17646808Sdab * if ((unsigned int)c >= 0x80) 17746808Sdab * was to assign "c" to an unsigned int variable... 17846808Sdab * Arggg.... 17946808Sdab */ 18046808Sdab register unsigned int uic = (unsigned int)c; 18132144Sminshall 18246808Sdab if (uic == 0x7f) 18332144Sminshall return ("^?"); 18445233Sborman if (c == (cc_t)_POSIX_VDISABLE) { 18532144Sminshall return "off"; 18632144Sminshall } 18746808Sdab if (uic >= 0x80) { 18844361Sborman buf[0] = '\\'; 18944361Sborman buf[1] = ((c>>6)&07) + '0'; 19044361Sborman buf[2] = ((c>>3)&07) + '0'; 19144361Sborman buf[3] = (c&07) + '0'; 19244361Sborman buf[4] = 0; 19346808Sdab } else if (uic >= 0x20) { 19432144Sminshall buf[0] = c; 19532144Sminshall buf[1] = 0; 19632144Sminshall } else { 19732144Sminshall buf[0] = '^'; 19832144Sminshall buf[1] = '@'+c; 19932144Sminshall buf[2] = 0; 20032144Sminshall } 20132144Sminshall return (buf); 20232144Sminshall } 20332144Sminshall 20432144Sminshall 20532144Sminshall 20632144Sminshall /* 20732144Sminshall * The following are data structures and routines for 20832144Sminshall * the "send" command. 20932144Sminshall * 21032144Sminshall */ 21132144Sminshall 21232144Sminshall struct sendlist { 21332144Sminshall char *name; /* How user refers to it (case independent) */ 21432144Sminshall char *help; /* Help information (0 ==> no help) */ 21546808Sdab int needconnect; /* Need to be connected */ 21646808Sdab int narg; /* Number of arguments */ 21738689Sborman int (*handler)(); /* Routine to perform (for special ops) */ 21846808Sdab int nbyte; /* Number of bytes to send this command */ 21938689Sborman int what; /* Character to be sent (<0 ==> special) */ 22032144Sminshall }; 22132144Sminshall 22232144Sminshall 223*56642Sralph static int 22446808Sdab send_esc P((void)), 22546808Sdab send_help P((void)), 22646808Sdab send_docmd P((char *)), 22746808Sdab send_dontcmd P((char *)), 22846808Sdab send_willcmd P((char *)), 22946808Sdab send_wontcmd P((char *)); 23046808Sdab 23132144Sminshall static struct sendlist Sendlist[] = { 23246808Sdab { "ao", "Send Telnet Abort output", 1, 0, 0, 2, AO }, 23346808Sdab { "ayt", "Send Telnet 'Are You There'", 1, 0, 0, 2, AYT }, 23446808Sdab { "brk", "Send Telnet Break", 1, 0, 0, 2, BREAK }, 23546808Sdab { "break", 0, 1, 0, 0, 2, BREAK }, 23646808Sdab { "ec", "Send Telnet Erase Character", 1, 0, 0, 2, EC }, 23746808Sdab { "el", "Send Telnet Erase Line", 1, 0, 0, 2, EL }, 23846808Sdab { "escape", "Send current escape character", 1, 0, send_esc, 1, 0 }, 23946808Sdab { "ga", "Send Telnet 'Go Ahead' sequence", 1, 0, 0, 2, GA }, 24046808Sdab { "ip", "Send Telnet Interrupt Process", 1, 0, 0, 2, IP }, 24146808Sdab { "intp", 0, 1, 0, 0, 2, IP }, 24246808Sdab { "interrupt", 0, 1, 0, 0, 2, IP }, 24346808Sdab { "intr", 0, 1, 0, 0, 2, IP }, 24446808Sdab { "nop", "Send Telnet 'No operation'", 1, 0, 0, 2, NOP }, 24546808Sdab { "eor", "Send Telnet 'End of Record'", 1, 0, 0, 2, EOR }, 24646808Sdab { "abort", "Send Telnet 'Abort Process'", 1, 0, 0, 2, ABORT }, 24746808Sdab { "susp", "Send Telnet 'Suspend Process'", 1, 0, 0, 2, SUSP }, 24846808Sdab { "eof", "Send Telnet End of File Character", 1, 0, 0, 2, xEOF }, 24946808Sdab { "synch", "Perform Telnet 'Synch operation'", 1, 0, dosynch, 2, 0 }, 25046808Sdab { "getstatus", "Send request for STATUS", 1, 0, get_status, 6, 0 }, 25146808Sdab { "?", "Display send options", 0, 0, send_help, 0, 0 }, 25246808Sdab { "help", 0, 0, 0, send_help, 0, 0 }, 25346808Sdab { "do", 0, 0, 1, send_docmd, 3, 0 }, 25446808Sdab { "dont", 0, 0, 1, send_dontcmd, 3, 0 }, 25546808Sdab { "will", 0, 0, 1, send_willcmd, 3, 0 }, 25646808Sdab { "wont", 0, 0, 1, send_wontcmd, 3, 0 }, 25732144Sminshall { 0 } 25832144Sminshall }; 25932144Sminshall 26046808Sdab #define GETSEND(name) ((struct sendlist *) genget(name, (char **) Sendlist, \ 26146808Sdab sizeof(struct sendlist))) 26232144Sminshall 26346808Sdab static int 26432144Sminshall sendcmd(argc, argv) 26546808Sdab int argc; 26646808Sdab char **argv; 26732144Sminshall { 26832144Sminshall int what; /* what we are sending this time */ 26932144Sminshall int count; /* how many bytes we are going to need to send */ 27032144Sminshall int i; 27132144Sminshall int question = 0; /* was at least one argument a question */ 27232144Sminshall struct sendlist *s; /* pointer to current command */ 27346808Sdab int success = 0; 27446808Sdab int needconnect = 0; 27532144Sminshall 27632144Sminshall if (argc < 2) { 27732144Sminshall printf("need at least one argument for 'send' command\n"); 27832144Sminshall printf("'send ?' for help\n"); 27932144Sminshall return 0; 28032144Sminshall } 28132144Sminshall /* 28232144Sminshall * First, validate all the send arguments. 28332144Sminshall * In addition, we see how much space we are going to need, and 28432144Sminshall * whether or not we will be doing a "SYNCH" operation (which 28532144Sminshall * flushes the network queue). 28632144Sminshall */ 28732144Sminshall count = 0; 28832144Sminshall for (i = 1; i < argc; i++) { 28946808Sdab s = GETSEND(argv[i]); 29032144Sminshall if (s == 0) { 29132144Sminshall printf("Unknown send argument '%s'\n'send ?' for help.\n", 29232144Sminshall argv[i]); 29332144Sminshall return 0; 29432144Sminshall } else if (Ambiguous(s)) { 29532144Sminshall printf("Ambiguous send argument '%s'\n'send ?' for help.\n", 29632144Sminshall argv[i]); 29732144Sminshall return 0; 29832144Sminshall } 29946808Sdab if (i + s->narg >= argc) { 30046808Sdab fprintf(stderr, 30146808Sdab "Need %d argument%s to 'send %s' command. 'send %s ?' for help.\n", 30246808Sdab s->narg, s->narg == 1 ? "" : "s", s->name, s->name); 30346808Sdab return 0; 30432144Sminshall } 30546808Sdab count += s->nbyte; 30646808Sdab if (s->handler == send_help) { 30746808Sdab send_help(); 30846808Sdab return 0; 30946808Sdab } 31046808Sdab 31146808Sdab i += s->narg; 31246808Sdab needconnect += s->needconnect; 31332144Sminshall } 31446808Sdab if (!connected && needconnect) { 31546808Sdab printf("?Need to be connected first.\n"); 31646808Sdab printf("'send ?' for help\n"); 31746808Sdab return 0; 31838689Sborman } 31932144Sminshall /* Now, do we have enough room? */ 32032144Sminshall if (NETROOM() < count) { 32132144Sminshall printf("There is not enough room in the buffer TO the network\n"); 32232144Sminshall printf("to process your request. Nothing will be done.\n"); 32332144Sminshall printf("('send synch' will throw away most data in the network\n"); 32432144Sminshall printf("buffer, if this might help.)\n"); 32532144Sminshall return 0; 32632144Sminshall } 32732144Sminshall /* OK, they are all OK, now go through again and actually send */ 32846808Sdab count = 0; 32932144Sminshall for (i = 1; i < argc; i++) { 33046808Sdab if ((s = GETSEND(argv[i])) == 0) { 33132144Sminshall fprintf(stderr, "Telnet 'send' error - argument disappeared!\n"); 33244361Sborman (void) quit(); 33332144Sminshall /*NOTREACHED*/ 33432144Sminshall } 33538689Sborman if (s->handler) { 33646808Sdab count++; 33746808Sdab success += (*s->handler)((s->narg > 0) ? argv[i+1] : 0, 33846808Sdab (s->narg > 1) ? argv[i+2] : 0); 33946808Sdab i += s->narg; 34032144Sminshall } else { 34146808Sdab NET2ADD(IAC, what); 34246808Sdab printoption("SENT", IAC, what); 34346808Sdab } 34446808Sdab } 34546808Sdab return (count == success); 34646808Sdab } 34746808Sdab 34846808Sdab static int 34946808Sdab send_esc() 35046808Sdab { 35146808Sdab NETADD(escape); 35246808Sdab return 1; 35346808Sdab } 35446808Sdab 35546808Sdab static int 35646808Sdab send_docmd(name) 35746808Sdab char *name; 35846808Sdab { 35946808Sdab void send_do(); 36046808Sdab return(send_tncmd(send_do, "do", name)); 36146808Sdab } 36246808Sdab 36346808Sdab static int 36446808Sdab send_dontcmd(name) 36546808Sdab char *name; 36646808Sdab { 36746808Sdab void send_dont(); 36846808Sdab return(send_tncmd(send_dont, "dont", name)); 36946808Sdab } 37046808Sdab static int 37146808Sdab send_willcmd(name) 37246808Sdab char *name; 37346808Sdab { 37446808Sdab void send_will(); 37546808Sdab return(send_tncmd(send_will, "will", name)); 37646808Sdab } 37746808Sdab static int 37846808Sdab send_wontcmd(name) 37946808Sdab char *name; 38046808Sdab { 38146808Sdab void send_wont(); 38246808Sdab return(send_tncmd(send_wont, "wont", name)); 38346808Sdab } 38446808Sdab 38546808Sdab int 38646808Sdab send_tncmd(func, cmd, name) 38746808Sdab void (*func)(); 38846808Sdab char *cmd, *name; 38946808Sdab { 39046808Sdab char **cpp; 39146808Sdab extern char *telopts[]; 39246808Sdab 39346808Sdab if (isprefix(name, "help") || isprefix(name, "?")) { 39446808Sdab register int col, len; 39546808Sdab 39646808Sdab printf("Usage: send %s <option>\n", cmd); 39746808Sdab printf("Valid options are:\n\t"); 39846808Sdab 39946808Sdab col = 8; 40046808Sdab for (cpp = telopts; *cpp; cpp++) { 40146808Sdab len = strlen(*cpp) + 1; 40246808Sdab if (col + len > 65) { 40346808Sdab printf("\n\t"); 40446808Sdab col = 8; 40532144Sminshall } 40646808Sdab printf(" %s", *cpp); 40746808Sdab col += len; 40832144Sminshall } 40946808Sdab printf("\n"); 41046808Sdab return 0; 41132144Sminshall } 41246808Sdab cpp = (char **)genget(name, telopts, sizeof(char *)); 41346808Sdab if (Ambiguous(cpp)) { 41446808Sdab fprintf(stderr,"'%s': ambiguous argument ('send %s ?' for help).\n", 41546808Sdab name, cmd); 41646808Sdab return 0; 41746808Sdab } 41846808Sdab if (cpp == 0) { 41946808Sdab fprintf(stderr, "'%s': unknown argument ('send %s ?' for help).\n", 42046808Sdab name, cmd); 42146808Sdab return 0; 42246808Sdab } 42346808Sdab if (!connected) { 42446808Sdab printf("?Need to be connected first.\n"); 42546808Sdab return 0; 42646808Sdab } 42746808Sdab (*func)(cpp - telopts, 1); 42846808Sdab return 1; 42932144Sminshall } 43046808Sdab 43146808Sdab static int 43246808Sdab send_help() 43346808Sdab { 43446808Sdab struct sendlist *s; /* pointer to current command */ 43546808Sdab for (s = Sendlist; s->name; s++) { 43646808Sdab if (s->help) 43746808Sdab printf("%-15s %s\n", s->name, s->help); 43846808Sdab } 43946808Sdab return(0); 44046808Sdab } 44132144Sminshall 44232144Sminshall /* 44332144Sminshall * The following are the routines and data structures referred 44432144Sminshall * to by the arguments to the "toggle" command. 44532144Sminshall */ 44632144Sminshall 44746808Sdab static int 44832144Sminshall lclchars() 44932144Sminshall { 45032144Sminshall donelclchars = 1; 45132144Sminshall return 1; 45232144Sminshall } 45332144Sminshall 45446808Sdab static int 45532144Sminshall togdebug() 45632144Sminshall { 45732144Sminshall #ifndef NOT43 45832144Sminshall if (net > 0 && 45932144Sminshall (SetSockOpt(net, SOL_SOCKET, SO_DEBUG, debug)) < 0) { 46032144Sminshall perror("setsockopt (SO_DEBUG)"); 46132144Sminshall } 46232144Sminshall #else /* NOT43 */ 46332144Sminshall if (debug) { 46432144Sminshall if (net > 0 && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 0, 0) < 0) 46532144Sminshall perror("setsockopt (SO_DEBUG)"); 46632144Sminshall } else 46732144Sminshall printf("Cannot turn off socket debugging\n"); 46832144Sminshall #endif /* NOT43 */ 46932144Sminshall return 1; 47032144Sminshall } 47132144Sminshall 47232144Sminshall 47346808Sdab static int 47432144Sminshall togcrlf() 47532144Sminshall { 47632144Sminshall if (crlf) { 47732144Sminshall printf("Will send carriage returns as telnet <CR><LF>.\n"); 47832144Sminshall } else { 47932144Sminshall printf("Will send carriage returns as telnet <CR><NUL>.\n"); 48032144Sminshall } 48132144Sminshall return 1; 48232144Sminshall } 48332144Sminshall 48438909Sborman int binmode; 48532144Sminshall 48646808Sdab static int 48738689Sborman togbinary(val) 48846808Sdab int val; 48932144Sminshall { 49032144Sminshall donebinarytoggle = 1; 49132144Sminshall 49238909Sborman if (val >= 0) { 49338909Sborman binmode = val; 49438909Sborman } else { 49538909Sborman if (my_want_state_is_will(TELOPT_BINARY) && 49638909Sborman my_want_state_is_do(TELOPT_BINARY)) { 49738909Sborman binmode = 1; 49838909Sborman } else if (my_want_state_is_wont(TELOPT_BINARY) && 49938909Sborman my_want_state_is_dont(TELOPT_BINARY)) { 50038909Sborman binmode = 0; 50138909Sborman } 50238909Sborman val = binmode ? 0 : 1; 50338909Sborman } 50438909Sborman 50538909Sborman if (val == 1) { 50638909Sborman if (my_want_state_is_will(TELOPT_BINARY) && 50738909Sborman my_want_state_is_do(TELOPT_BINARY)) { 50838689Sborman printf("Already operating in binary mode with remote host.\n"); 50938909Sborman } else { 51038909Sborman printf("Negotiating binary mode with remote host.\n"); 51138909Sborman tel_enter_binary(3); 51238689Sborman } 51338909Sborman } else { 51438909Sborman if (my_want_state_is_wont(TELOPT_BINARY) && 51538909Sborman my_want_state_is_dont(TELOPT_BINARY)) { 51638689Sborman printf("Already in network ascii mode with remote host.\n"); 51738909Sborman } else { 51838909Sborman printf("Negotiating network ascii mode with remote host.\n"); 51938909Sborman tel_leave_binary(3); 52038689Sborman } 52132144Sminshall } 52232144Sminshall return 1; 52332144Sminshall } 52432144Sminshall 52546808Sdab static int 52638909Sborman togrbinary(val) 52746808Sdab int val; 52838909Sborman { 52938909Sborman donebinarytoggle = 1; 53032144Sminshall 53138909Sborman if (val == -1) 53238909Sborman val = my_want_state_is_do(TELOPT_BINARY) ? 0 : 1; 53332144Sminshall 53438909Sborman if (val == 1) { 53538909Sborman if (my_want_state_is_do(TELOPT_BINARY)) { 53638909Sborman printf("Already receiving in binary mode.\n"); 53738909Sborman } else { 53838909Sborman printf("Negotiating binary mode on input.\n"); 53938909Sborman tel_enter_binary(1); 54038909Sborman } 54138909Sborman } else { 54238909Sborman if (my_want_state_is_dont(TELOPT_BINARY)) { 54338909Sborman printf("Already receiving in network ascii mode.\n"); 54438909Sborman } else { 54538909Sborman printf("Negotiating network ascii mode on input.\n"); 54638909Sborman tel_leave_binary(1); 54738909Sborman } 54838909Sborman } 54938909Sborman return 1; 55038909Sborman } 55138909Sborman 55246808Sdab static int 55338909Sborman togxbinary(val) 55446808Sdab int val; 55538909Sborman { 55638909Sborman donebinarytoggle = 1; 55738909Sborman 55838909Sborman if (val == -1) 55938909Sborman val = my_want_state_is_will(TELOPT_BINARY) ? 0 : 1; 56038909Sborman 56138909Sborman if (val == 1) { 56238909Sborman if (my_want_state_is_will(TELOPT_BINARY)) { 56338909Sborman printf("Already transmitting in binary mode.\n"); 56438909Sborman } else { 56538909Sborman printf("Negotiating binary mode on output.\n"); 56638909Sborman tel_enter_binary(2); 56738909Sborman } 56838909Sborman } else { 56938909Sborman if (my_want_state_is_wont(TELOPT_BINARY)) { 57038909Sborman printf("Already transmitting in network ascii mode.\n"); 57138909Sborman } else { 57238909Sborman printf("Negotiating network ascii mode on output.\n"); 57338909Sborman tel_leave_binary(2); 57438909Sborman } 57538909Sborman } 57638909Sborman return 1; 57738909Sborman } 57838909Sborman 57938909Sborman 580*56642Sralph static int togglehelp P((void)); 58147609Sdab #if defined(AUTHENTICATE) 58247609Sdab extern int auth_togdebug P((int)); 58347609Sdab #endif 58447609Sdab #if defined(ENCRYPT) 58547609Sdab extern int EncryptAutoEnc P((int)); 58647609Sdab extern int EncryptAutoDec P((int)); 58747609Sdab extern int EncryptDebug P((int)); 58847609Sdab extern int EncryptVerbose P((int)); 58947609Sdab #endif 59032144Sminshall 59132144Sminshall struct togglelist { 59232144Sminshall char *name; /* name of toggle */ 59332144Sminshall char *help; /* help message */ 59432144Sminshall int (*handler)(); /* routine to do actual setting */ 59532144Sminshall int *variable; 59632144Sminshall char *actionexplanation; 59732144Sminshall }; 59832144Sminshall 59932144Sminshall static struct togglelist Togglelist[] = { 60032144Sminshall { "autoflush", 60138689Sborman "flushing of output when sending interrupt characters", 60232144Sminshall 0, 60338689Sborman &autoflush, 60438689Sborman "flush output when sending interrupt characters" }, 60532144Sminshall { "autosynch", 60638689Sborman "automatic sending of interrupt characters in urgent mode", 60732144Sminshall 0, 60838689Sborman &autosynch, 60938689Sborman "send interrupt characters in urgent mode" }, 61047609Sdab #if defined(AUTHENTICATE) 61147609Sdab { "autologin", 61247609Sdab "automatic sending of login and/or authentication info", 61347609Sdab 0, 61447609Sdab &autologin, 61547609Sdab "send login name and/or authentication information" }, 61647609Sdab { "authdebug", 61747609Sdab "Toggle authentication debugging", 61847609Sdab auth_togdebug, 61947609Sdab 0, 62047609Sdab "print authentication debugging information" }, 62147609Sdab #endif 62247609Sdab #if defined(ENCRYPT) 62347609Sdab { "autoencrypt", 62447609Sdab "automatic encryption of data stream", 62547609Sdab EncryptAutoEnc, 62647609Sdab 0, 62747609Sdab "automatically encrypt output" }, 62847609Sdab { "autodecrypt", 62947609Sdab "automatic decryption of data stream", 63047609Sdab EncryptAutoDec, 63147609Sdab 0, 63247609Sdab "automatically decrypt input" }, 63347609Sdab { "verbose_encrypt", 63447609Sdab "Toggle verbose encryption output", 63547609Sdab EncryptVerbose, 63647609Sdab 0, 63747609Sdab "print verbose encryption output" }, 63847609Sdab { "encdebug", 63947609Sdab "Toggle encryption debugging", 64047609Sdab EncryptDebug, 64147609Sdab 0, 64247609Sdab "print encryption debugging information" }, 64347609Sdab #endif 64447609Sdab { "skiprc", 64547609Sdab "don't read ~/.telnetrc file", 64647609Sdab 0, 64747609Sdab &skiprc, 64847609Sdab "read ~/.telnetrc file" }, 64932144Sminshall { "binary", 65038689Sborman "sending and receiving of binary data", 65132144Sminshall togbinary, 65238689Sborman 0, 65338689Sborman 0 }, 65438909Sborman { "inbinary", 65538909Sborman "receiving of binary data", 65638909Sborman togrbinary, 65738909Sborman 0, 65838909Sborman 0 }, 65938909Sborman { "outbinary", 66038909Sborman "sending of binary data", 66138909Sborman togxbinary, 66238909Sborman 0, 66338909Sborman 0 }, 66432144Sminshall { "crlf", 66538689Sborman "sending carriage returns as telnet <CR><LF>", 66632144Sminshall togcrlf, 66738689Sborman &crlf, 66838689Sborman 0 }, 66932144Sminshall { "crmod", 67038689Sborman "mapping of received carriage returns", 67132144Sminshall 0, 67238689Sborman &crmod, 67338689Sborman "map carriage return on output" }, 67432144Sminshall { "localchars", 67538689Sborman "local recognition of certain control characters", 67632144Sminshall lclchars, 67738689Sborman &localchars, 67838689Sborman "recognize certain control characters" }, 67938689Sborman { " ", "", 0 }, /* empty line */ 68038208Sminshall #if defined(unix) && defined(TN3270) 68138920Sminshall { "apitrace", 68238920Sminshall "(debugging) toggle tracing of API transactions", 68338920Sminshall 0, 68438920Sminshall &apitrace, 68538920Sminshall "trace API transactions" }, 68638208Sminshall { "cursesdata", 68738208Sminshall "(debugging) toggle printing of hexadecimal curses data", 68838208Sminshall 0, 68938689Sborman &cursesdata, 69038689Sborman "print hexadecimal representation of curses data" }, 69138208Sminshall #endif /* defined(unix) && defined(TN3270) */ 69232144Sminshall { "debug", 69338689Sborman "debugging", 69432144Sminshall togdebug, 69538689Sborman &debug, 69638689Sborman "turn on socket level debugging" }, 69732144Sminshall { "netdata", 69838689Sborman "printing of hexadecimal network data (debugging)", 69932144Sminshall 0, 70038689Sborman &netdata, 70138689Sborman "print hexadecimal representation of network traffic" }, 70238689Sborman { "prettydump", 70338689Sborman "output of \"netdata\" to user readable format (debugging)", 70438689Sborman 0, 70538689Sborman &prettydump, 70638689Sborman "print user readable output for \"netdata\"" }, 70732144Sminshall { "options", 70838689Sborman "viewing of options processing (debugging)", 70932144Sminshall 0, 71038689Sborman &showoptions, 71138689Sborman "show option processing" }, 71238208Sminshall #if defined(unix) 71338208Sminshall { "termdata", 71438208Sminshall "(debugging) toggle printing of hexadecimal terminal data", 71538208Sminshall 0, 71638689Sborman &termdata, 71738689Sborman "print hexadecimal representation of terminal traffic" }, 71838208Sminshall #endif /* defined(unix) */ 71932144Sminshall { "?", 72038689Sborman 0, 72138689Sborman togglehelp }, 72232144Sminshall { "help", 72338689Sborman 0, 72438689Sborman togglehelp }, 72532144Sminshall { 0 } 72632144Sminshall }; 72732144Sminshall 72846808Sdab static int 72932144Sminshall togglehelp() 73032144Sminshall { 73132144Sminshall struct togglelist *c; 73232144Sminshall 73332144Sminshall for (c = Togglelist; c->name; c++) { 73438689Sborman if (c->help) { 73538689Sborman if (*c->help) 73638689Sborman printf("%-15s toggle %s\n", c->name, c->help); 73738689Sborman else 73838689Sborman printf("\n"); 73932144Sminshall } 74032144Sminshall } 74138689Sborman printf("\n"); 74238689Sborman printf("%-15s %s\n", "?", "display help information"); 74332144Sminshall return 0; 74432144Sminshall } 74532144Sminshall 74646808Sdab static void 74738689Sborman settogglehelp(set) 74846808Sdab int set; 74938689Sborman { 75038689Sborman struct togglelist *c; 75138689Sborman 75238689Sborman for (c = Togglelist; c->name; c++) { 75338689Sborman if (c->help) { 75438689Sborman if (*c->help) 75538689Sborman printf("%-15s %s %s\n", c->name, set ? "enable" : "disable", 75638689Sborman c->help); 75738689Sborman else 75838689Sborman printf("\n"); 75938689Sborman } 76038689Sborman } 76138689Sborman } 76238689Sborman 76346808Sdab #define GETTOGGLE(name) (struct togglelist *) \ 76446808Sdab genget(name, (char **) Togglelist, sizeof(struct togglelist)) 76532144Sminshall 76646808Sdab static int 76732144Sminshall toggle(argc, argv) 76846808Sdab int argc; 76946808Sdab char *argv[]; 77032144Sminshall { 77132144Sminshall int retval = 1; 77232144Sminshall char *name; 77332144Sminshall struct togglelist *c; 77432144Sminshall 77532144Sminshall if (argc < 2) { 77632144Sminshall fprintf(stderr, 77732144Sminshall "Need an argument to 'toggle' command. 'toggle ?' for help.\n"); 77832144Sminshall return 0; 77932144Sminshall } 78032144Sminshall argc--; 78132144Sminshall argv++; 78232144Sminshall while (argc--) { 78332144Sminshall name = *argv++; 78446808Sdab c = GETTOGGLE(name); 78532144Sminshall if (Ambiguous(c)) { 78632144Sminshall fprintf(stderr, "'%s': ambiguous argument ('toggle ?' for help).\n", 78732144Sminshall name); 78832144Sminshall return 0; 78932144Sminshall } else if (c == 0) { 79032144Sminshall fprintf(stderr, "'%s': unknown argument ('toggle ?' for help).\n", 79132144Sminshall name); 79232144Sminshall return 0; 79332144Sminshall } else { 79432144Sminshall if (c->variable) { 79532144Sminshall *c->variable = !*c->variable; /* invert it */ 79632144Sminshall if (c->actionexplanation) { 79732144Sminshall printf("%s %s.\n", *c->variable? "Will" : "Won't", 79832144Sminshall c->actionexplanation); 79932144Sminshall } 80032144Sminshall } 80132144Sminshall if (c->handler) { 80238689Sborman retval &= (*c->handler)(-1); 80332144Sminshall } 80432144Sminshall } 80532144Sminshall } 80632144Sminshall return retval; 80732144Sminshall } 80832144Sminshall 80932144Sminshall /* 81032144Sminshall * The following perform the "set" command. 81132144Sminshall */ 81232144Sminshall 81338689Sborman #ifdef USE_TERMIO 81438689Sborman struct termio new_tc = { 0 }; 81538689Sborman #endif 81638689Sborman 81732144Sminshall struct setlist { 81832144Sminshall char *name; /* name */ 81932144Sminshall char *help; /* help information */ 82038689Sborman void (*handler)(); 82140245Sborman cc_t *charp; /* where it is located at */ 82232144Sminshall }; 82332144Sminshall 82432144Sminshall static struct setlist Setlist[] = { 82544361Sborman #ifdef KLUDGELINEMODE 82638689Sborman { "echo", "character to toggle local echoing on/off", 0, &echoc }, 82744361Sborman #endif 82838689Sborman { "escape", "character to escape back to telnet command mode", 0, &escape }, 82946808Sdab { "rlogin", "rlogin escape character", 0, &rlogin }, 83045233Sborman { "tracefile", "file to write trace information to", SetNetTrace, (cc_t *)NetTraceFile}, 83132144Sminshall { " ", "" }, 83238689Sborman { " ", "The following need 'localchars' to be toggled true", 0, 0 }, 83345233Sborman { "flushoutput", "character to cause an Abort Output", 0, termFlushCharp }, 83438689Sborman { "interrupt", "character to cause an Interrupt Process", 0, termIntCharp }, 83538689Sborman { "quit", "character to cause an Abort process", 0, termQuitCharp }, 83638689Sborman { "eof", "character to cause an EOF ", 0, termEofCharp }, 83738689Sborman { " ", "" }, 83838689Sborman { " ", "The following are for local editing in linemode", 0, 0 }, 83938689Sborman { "erase", "character to use to erase a character", 0, termEraseCharp }, 84038689Sborman { "kill", "character to use to erase a line", 0, termKillCharp }, 84138689Sborman { "lnext", "character to use for literal next", 0, termLiteralNextCharp }, 84244361Sborman { "susp", "character to cause a Suspend Process", 0, termSuspCharp }, 84338689Sborman { "reprint", "character to use for line reprint", 0, termRprntCharp }, 84438689Sborman { "worderase", "character to use to erase a word", 0, termWerasCharp }, 84538689Sborman { "start", "character to use for XON", 0, termStartCharp }, 84644361Sborman { "stop", "character to use for XOFF", 0, termStopCharp }, 84744361Sborman { "forw1", "alternate end of line character", 0, termForw1Charp }, 84844361Sborman { "forw2", "alternate end of line character", 0, termForw2Charp }, 84945233Sborman { "ayt", "alternate AYT character", 0, termAytCharp }, 85032144Sminshall { 0 } 85132144Sminshall }; 85232144Sminshall 85345233Sborman #if defined(CRAY) && !defined(__STDC__) 85445233Sborman /* Work around compiler bug in pcc 4.1.5 */ 85546808Sdab void 85638689Sborman _setlist_init() 85738689Sborman { 85844361Sborman #ifndef KLUDGELINEMODE 85946808Sdab #define N 5 86044361Sborman #else 86146808Sdab #define N 6 86244361Sborman #endif 86344361Sborman Setlist[N+0].charp = &termFlushChar; 86444361Sborman Setlist[N+1].charp = &termIntChar; 86544361Sborman Setlist[N+2].charp = &termQuitChar; 86644361Sborman Setlist[N+3].charp = &termEofChar; 86744361Sborman Setlist[N+6].charp = &termEraseChar; 86844361Sborman Setlist[N+7].charp = &termKillChar; 86944361Sborman Setlist[N+8].charp = &termLiteralNextChar; 87044361Sborman Setlist[N+9].charp = &termSuspChar; 87144361Sborman Setlist[N+10].charp = &termRprntChar; 87244361Sborman Setlist[N+11].charp = &termWerasChar; 87344361Sborman Setlist[N+12].charp = &termStartChar; 87444361Sborman Setlist[N+13].charp = &termStopChar; 87544361Sborman Setlist[N+14].charp = &termForw1Char; 87644361Sborman Setlist[N+15].charp = &termForw2Char; 87745233Sborman Setlist[N+16].charp = &termAytChar; 87844361Sborman #undef N 87938689Sborman } 88045233Sborman #endif /* defined(CRAY) && !defined(__STDC__) */ 88138689Sborman 88246808Sdab static struct setlist * 88332144Sminshall getset(name) 88446808Sdab char *name; 88532144Sminshall { 88646808Sdab return (struct setlist *) 88746808Sdab genget(name, (char **) Setlist, sizeof(struct setlist)); 88832144Sminshall } 88932144Sminshall 89046808Sdab void 89144361Sborman set_escape_char(s) 89246808Sdab char *s; 89344361Sborman { 89446808Sdab if (rlogin != _POSIX_VDISABLE) { 89546808Sdab rlogin = (s && *s) ? special(s) : _POSIX_VDISABLE; 89646808Sdab printf("Telnet rlogin escape character is '%s'.\n", 89746808Sdab control(rlogin)); 89846808Sdab } else { 89946808Sdab escape = (s && *s) ? special(s) : _POSIX_VDISABLE; 90046808Sdab printf("Telnet escape character is '%s'.\n", control(escape)); 90146808Sdab } 90244361Sborman } 90344361Sborman 90446808Sdab static int 90532144Sminshall setcmd(argc, argv) 90646808Sdab int argc; 90746808Sdab char *argv[]; 90832144Sminshall { 90932144Sminshall int value; 91032144Sminshall struct setlist *ct; 91138689Sborman struct togglelist *c; 91232144Sminshall 91338689Sborman if (argc < 2 || argc > 3) { 91438689Sborman printf("Format is 'set Name Value'\n'set ?' for help.\n"); 91532144Sminshall return 0; 91632144Sminshall } 91746808Sdab if ((argc == 2) && (isprefix(argv[1], "?") || isprefix(argv[1], "help"))) { 91838689Sborman for (ct = Setlist; ct->name; ct++) 91938689Sborman printf("%-15s %s\n", ct->name, ct->help); 92038689Sborman printf("\n"); 92138689Sborman settogglehelp(1); 92238689Sborman printf("%-15s %s\n", "?", "display help information"); 92338689Sborman return 0; 92438689Sborman } 92532144Sminshall 92632144Sminshall ct = getset(argv[1]); 92732144Sminshall if (ct == 0) { 92846808Sdab c = GETTOGGLE(argv[1]); 92938689Sborman if (c == 0) { 93038689Sborman fprintf(stderr, "'%s': unknown argument ('set ?' for help).\n", 93132144Sminshall argv[1]); 93238689Sborman return 0; 93338689Sborman } else if (Ambiguous(c)) { 93438689Sborman fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n", 93538689Sborman argv[1]); 93638689Sborman return 0; 93738689Sborman } 93838689Sborman if (c->variable) { 93938689Sborman if ((argc == 2) || (strcmp("on", argv[2]) == 0)) 94038689Sborman *c->variable = 1; 94138689Sborman else if (strcmp("off", argv[2]) == 0) 94238689Sborman *c->variable = 0; 94338689Sborman else { 94438689Sborman printf("Format is 'set togglename [on|off]'\n'set ?' for help.\n"); 94538689Sborman return 0; 94638689Sborman } 94738689Sborman if (c->actionexplanation) { 94838689Sborman printf("%s %s.\n", *c->variable? "Will" : "Won't", 94938689Sborman c->actionexplanation); 95038689Sborman } 95138689Sborman } 95238689Sborman if (c->handler) 95338689Sborman (*c->handler)(1); 95438689Sborman } else if (argc != 3) { 95538689Sborman printf("Format is 'set Name Value'\n'set ?' for help.\n"); 95632144Sminshall return 0; 95732144Sminshall } else if (Ambiguous(ct)) { 95832144Sminshall fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n", 95932144Sminshall argv[1]); 96032144Sminshall return 0; 96138689Sborman } else if (ct->handler) { 96238689Sborman (*ct->handler)(argv[2]); 96344361Sborman printf("%s set to \"%s\".\n", ct->name, (char *)ct->charp); 96432144Sminshall } else { 96532144Sminshall if (strcmp("off", argv[2])) { 96632144Sminshall value = special(argv[2]); 96732144Sminshall } else { 96845233Sborman value = _POSIX_VDISABLE; 96932144Sminshall } 97040245Sborman *(ct->charp) = (cc_t)value; 97132144Sminshall printf("%s character is '%s'.\n", ct->name, control(*(ct->charp))); 97232144Sminshall } 97338689Sborman slc_check(); 97432144Sminshall return 1; 97532144Sminshall } 97638689Sborman 97746808Sdab static int 97838689Sborman unsetcmd(argc, argv) 97946808Sdab int argc; 98046808Sdab char *argv[]; 98138689Sborman { 98238689Sborman struct setlist *ct; 98338689Sborman struct togglelist *c; 98438689Sborman register char *name; 98538689Sborman 98638689Sborman if (argc < 2) { 98738689Sborman fprintf(stderr, 98838689Sborman "Need an argument to 'unset' command. 'unset ?' for help.\n"); 98938689Sborman return 0; 99038689Sborman } 99146808Sdab if (isprefix(argv[1], "?") || isprefix(argv[1], "help")) { 99238689Sborman for (ct = Setlist; ct->name; ct++) 99338689Sborman printf("%-15s %s\n", ct->name, ct->help); 99438689Sborman printf("\n"); 99538689Sborman settogglehelp(0); 99638689Sborman printf("%-15s %s\n", "?", "display help information"); 99738689Sborman return 0; 99838689Sborman } 99938689Sborman 100038689Sborman argc--; 100138689Sborman argv++; 100238689Sborman while (argc--) { 100338689Sborman name = *argv++; 100438689Sborman ct = getset(name); 100538689Sborman if (ct == 0) { 100646808Sdab c = GETTOGGLE(name); 100738689Sborman if (c == 0) { 100838689Sborman fprintf(stderr, "'%s': unknown argument ('unset ?' for help).\n", 100938689Sborman name); 101038689Sborman return 0; 101138689Sborman } else if (Ambiguous(c)) { 101238689Sborman fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n", 101338689Sborman name); 101438689Sborman return 0; 101538689Sborman } 101638689Sborman if (c->variable) { 101738689Sborman *c->variable = 0; 101838689Sborman if (c->actionexplanation) { 101938689Sborman printf("%s %s.\n", *c->variable? "Will" : "Won't", 102038689Sborman c->actionexplanation); 102138689Sborman } 102238689Sborman } 102338689Sborman if (c->handler) 102438689Sborman (*c->handler)(0); 102538689Sborman } else if (Ambiguous(ct)) { 102638689Sborman fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n", 102738689Sborman name); 102838689Sborman return 0; 102938689Sborman } else if (ct->handler) { 103038689Sborman (*ct->handler)(0); 103144361Sborman printf("%s reset to \"%s\".\n", ct->name, (char *)ct->charp); 103238689Sborman } else { 103345233Sborman *(ct->charp) = _POSIX_VDISABLE; 103438689Sborman printf("%s character is '%s'.\n", ct->name, control(*(ct->charp))); 103538689Sborman } 103638689Sborman } 103738689Sborman return 1; 103838689Sborman } 103932144Sminshall 104032144Sminshall /* 104132144Sminshall * The following are the data structures and routines for the 104232144Sminshall * 'mode' command. 104332144Sminshall */ 104438689Sborman #ifdef KLUDGELINEMODE 104538689Sborman extern int kludgelinemode; 104644361Sborman 104746808Sdab static int 104844361Sborman dokludgemode() 104944361Sborman { 105044361Sborman kludgelinemode = 1; 105144361Sborman send_wont(TELOPT_LINEMODE, 1); 105244361Sborman send_dont(TELOPT_SGA, 1); 105344361Sborman send_dont(TELOPT_ECHO, 1); 105444361Sborman } 105538689Sborman #endif 105632144Sminshall 105746808Sdab static int 105832144Sminshall dolinemode() 105932144Sminshall { 106038689Sborman #ifdef KLUDGELINEMODE 106138689Sborman if (kludgelinemode) 106238689Sborman send_dont(TELOPT_SGA, 1); 106338689Sborman #endif 106438689Sborman send_will(TELOPT_LINEMODE, 1); 106538689Sborman send_dont(TELOPT_ECHO, 1); 106632144Sminshall return 1; 106732144Sminshall } 106832144Sminshall 106946808Sdab static int 107032144Sminshall docharmode() 107132144Sminshall { 107238689Sborman #ifdef KLUDGELINEMODE 107338689Sborman if (kludgelinemode) 107438689Sborman send_do(TELOPT_SGA, 1); 107538689Sborman else 107638689Sborman #endif 107738689Sborman send_wont(TELOPT_LINEMODE, 1); 107838689Sborman send_do(TELOPT_ECHO, 1); 107938689Sborman return 1; 108038689Sborman } 108138689Sborman 108246808Sdab static int 108338689Sborman dolmmode(bit, on) 108446808Sdab int bit, on; 108538689Sborman { 108646808Sdab unsigned char c; 108738689Sborman extern int linemode; 108838689Sborman 108938689Sborman if (my_want_state_is_wont(TELOPT_LINEMODE)) { 109038689Sborman printf("?Need to have LINEMODE option enabled first.\n"); 109138689Sborman printf("'mode ?' for help.\n"); 109238689Sborman return 0; 109332144Sminshall } 109438689Sborman 109538689Sborman if (on) 109638689Sborman c = (linemode | bit); 109738689Sborman else 109838689Sborman c = (linemode & ~bit); 109938689Sborman lm_mode(&c, 1, 1); 110032144Sminshall return 1; 110132144Sminshall } 110232144Sminshall 110346808Sdab int 110446808Sdab setmode(bit) 110546808Sdab { 110646808Sdab return dolmmode(bit, 1); 110746808Sdab } 110846808Sdab 110946808Sdab int 111046808Sdab clearmode(bit) 111146808Sdab { 111246808Sdab return dolmmode(bit, 0); 111346808Sdab } 111446808Sdab 111538689Sborman struct modelist { 111638689Sborman char *name; /* command name */ 111738689Sborman char *help; /* help string */ 111838689Sborman int (*handler)(); /* routine which executes command */ 111938689Sborman int needconnect; /* Do we need to be connected to execute? */ 112038689Sborman int arg1; 112138689Sborman }; 112238689Sborman 112338689Sborman extern int modehelp(); 112438689Sborman 112538689Sborman static struct modelist ModeList[] = { 112638689Sborman { "character", "Disable LINEMODE option", docharmode, 1 }, 112739529Sborman #ifdef KLUDGELINEMODE 112839529Sborman { "", "(or disable obsolete line-by-line mode)", 0 }, 112938689Sborman #endif 113038689Sborman { "line", "Enable LINEMODE option", dolinemode, 1 }, 113139529Sborman #ifdef KLUDGELINEMODE 113239529Sborman { "", "(or enable obsolete line-by-line mode)", 0 }, 113338689Sborman #endif 113438689Sborman { "", "", 0 }, 113538689Sborman { "", "These require the LINEMODE option to be enabled", 0 }, 113638689Sborman { "isig", "Enable signal trapping", setmode, 1, MODE_TRAPSIG }, 113738689Sborman { "+isig", 0, setmode, 1, MODE_TRAPSIG }, 113838689Sborman { "-isig", "Disable signal trapping", clearmode, 1, MODE_TRAPSIG }, 113938689Sborman { "edit", "Enable character editing", setmode, 1, MODE_EDIT }, 114038689Sborman { "+edit", 0, setmode, 1, MODE_EDIT }, 114138689Sborman { "-edit", "Disable character editing", clearmode, 1, MODE_EDIT }, 114244361Sborman { "softtabs", "Enable tab expansion", setmode, 1, MODE_SOFT_TAB }, 114344361Sborman { "+softtabs", 0, setmode, 1, MODE_SOFT_TAB }, 114444361Sborman { "-softtabs", "Disable character editing", clearmode, 1, MODE_SOFT_TAB }, 114544361Sborman { "litecho", "Enable literal character echo", setmode, 1, MODE_LIT_ECHO }, 114644361Sborman { "+litecho", 0, setmode, 1, MODE_LIT_ECHO }, 114744361Sborman { "-litecho", "Disable literal character echo", clearmode, 1, MODE_LIT_ECHO }, 114838689Sborman { "help", 0, modehelp, 0 }, 114944361Sborman #ifdef KLUDGELINEMODE 115044361Sborman { "kludgeline", 0, dokludgemode, 1 }, 115144361Sborman #endif 115244361Sborman { "", "", 0 }, 115338689Sborman { "?", "Print help information", modehelp, 0 }, 115432144Sminshall { 0 }, 115532144Sminshall }; 115632144Sminshall 115732144Sminshall 115846808Sdab int 115938689Sborman modehelp() 116038689Sborman { 116138689Sborman struct modelist *mt; 116238689Sborman 116338689Sborman printf("format is: 'mode Mode', where 'Mode' is one of:\n\n"); 116438689Sborman for (mt = ModeList; mt->name; mt++) { 116538689Sborman if (mt->help) { 116638689Sborman if (*mt->help) 116738689Sborman printf("%-15s %s\n", mt->name, mt->help); 116838689Sborman else 116938689Sborman printf("\n"); 117038689Sborman } 117138689Sborman } 117238689Sborman return 0; 117338689Sborman } 117438689Sborman 117546808Sdab #define GETMODECMD(name) (struct modelist *) \ 117646808Sdab genget(name, (char **) ModeList, sizeof(struct modelist)) 117746808Sdab 117846808Sdab static int 117932144Sminshall modecmd(argc, argv) 118046808Sdab int argc; 118146808Sdab char *argv[]; 118232144Sminshall { 118338689Sborman struct modelist *mt; 118432144Sminshall 118538689Sborman if (argc != 2) { 118638689Sborman printf("'mode' command requires an argument\n"); 118738689Sborman printf("'mode ?' for help.\n"); 118846808Sdab } else if ((mt = GETMODECMD(argv[1])) == 0) { 118932144Sminshall fprintf(stderr, "Unknown mode '%s' ('mode ?' for help).\n", argv[1]); 119032144Sminshall } else if (Ambiguous(mt)) { 119132144Sminshall fprintf(stderr, "Ambiguous mode '%s' ('mode ?' for help).\n", argv[1]); 119238689Sborman } else if (mt->needconnect && !connected) { 119338689Sborman printf("?Need to be connected first.\n"); 119438689Sborman printf("'mode ?' for help.\n"); 119538689Sborman } else if (mt->handler) { 119638689Sborman return (*mt->handler)(mt->arg1); 119732144Sminshall } 119838689Sborman return 0; 119932144Sminshall } 120032144Sminshall 120132144Sminshall /* 120232144Sminshall * The following data structures and routines implement the 120332144Sminshall * "display" command. 120432144Sminshall */ 120532144Sminshall 120646808Sdab static int 120732144Sminshall display(argc, argv) 120846808Sdab int argc; 120946808Sdab char *argv[]; 121032144Sminshall { 121146808Sdab struct togglelist *tl; 121246808Sdab struct setlist *sl; 121346808Sdab 121432144Sminshall #define dotog(tl) if (tl->variable && tl->actionexplanation) { \ 121532144Sminshall if (*tl->variable) { \ 121632144Sminshall printf("will"); \ 121732144Sminshall } else { \ 121832144Sminshall printf("won't"); \ 121932144Sminshall } \ 122032144Sminshall printf(" %s.\n", tl->actionexplanation); \ 122132144Sminshall } 122232144Sminshall 122332144Sminshall #define doset(sl) if (sl->name && *sl->name != ' ') { \ 122438689Sborman if (sl->handler == 0) \ 122538689Sborman printf("%-15s [%s]\n", sl->name, control(*sl->charp)); \ 122638689Sborman else \ 122744361Sborman printf("%-15s \"%s\"\n", sl->name, (char *)sl->charp); \ 122832144Sminshall } 122932144Sminshall 123032144Sminshall if (argc == 1) { 123132144Sminshall for (tl = Togglelist; tl->name; tl++) { 123232144Sminshall dotog(tl); 123332144Sminshall } 123432144Sminshall printf("\n"); 123532144Sminshall for (sl = Setlist; sl->name; sl++) { 123632144Sminshall doset(sl); 123732144Sminshall } 123832144Sminshall } else { 123932144Sminshall int i; 124032144Sminshall 124132144Sminshall for (i = 1; i < argc; i++) { 124232144Sminshall sl = getset(argv[i]); 124346808Sdab tl = GETTOGGLE(argv[i]); 124432144Sminshall if (Ambiguous(sl) || Ambiguous(tl)) { 124532144Sminshall printf("?Ambiguous argument '%s'.\n", argv[i]); 124632144Sminshall return 0; 124732144Sminshall } else if (!sl && !tl) { 124832144Sminshall printf("?Unknown argument '%s'.\n", argv[i]); 124932144Sminshall return 0; 125032144Sminshall } else { 125132144Sminshall if (tl) { 125232144Sminshall dotog(tl); 125332144Sminshall } 125432144Sminshall if (sl) { 125532144Sminshall doset(sl); 125632144Sminshall } 125732144Sminshall } 125832144Sminshall } 125932144Sminshall } 126038689Sborman /*@*/optionstatus(); 126146808Sdab #if defined(ENCRYPT) 126246808Sdab EncryptStatus(); 126346808Sdab #endif 126432144Sminshall return 1; 126532144Sminshall #undef doset 126632144Sminshall #undef dotog 126732144Sminshall } 126832144Sminshall 126932144Sminshall /* 127032144Sminshall * The following are the data structures, and many of the routines, 127132144Sminshall * relating to command processing. 127232144Sminshall */ 127332144Sminshall 127432144Sminshall /* 127532144Sminshall * Set the escape character. 127632144Sminshall */ 127746808Sdab static int 127832144Sminshall setescape(argc, argv) 127932144Sminshall int argc; 128032144Sminshall char *argv[]; 128132144Sminshall { 128232144Sminshall register char *arg; 128332144Sminshall char buf[50]; 128432144Sminshall 128532144Sminshall printf( 128632144Sminshall "Deprecated usage - please use 'set escape%s%s' in the future.\n", 128732144Sminshall (argc > 2)? " ":"", (argc > 2)? argv[1]: ""); 128832144Sminshall if (argc > 2) 128932144Sminshall arg = argv[1]; 129032144Sminshall else { 129132144Sminshall printf("new escape character: "); 129246808Sdab (void) fgets(buf, sizeof(buf), stdin); 129332144Sminshall arg = buf; 129432144Sminshall } 129532144Sminshall if (arg[0] != '\0') 129632144Sminshall escape = arg[0]; 129732144Sminshall if (!In3270) { 129832144Sminshall printf("Escape character is '%s'.\n", control(escape)); 129932144Sminshall } 130034849Sminshall (void) fflush(stdout); 130132144Sminshall return 1; 130232144Sminshall } 130332144Sminshall 130446808Sdab /*VARARGS*/ 130546808Sdab static int 130632144Sminshall togcrmod() 130732144Sminshall { 130832144Sminshall crmod = !crmod; 130932144Sminshall printf("Deprecated usage - please use 'toggle crmod' in the future.\n"); 131032144Sminshall printf("%s map carriage return on output.\n", crmod ? "Will" : "Won't"); 131134849Sminshall (void) fflush(stdout); 131232144Sminshall return 1; 131332144Sminshall } 131432144Sminshall 131546808Sdab /*VARARGS*/ 131646808Sdab int 131732144Sminshall suspend() 131832144Sminshall { 131938689Sborman #ifdef SIGTSTP 132037219Sminshall setcommandmode(); 132137219Sminshall { 132244361Sborman long oldrows, oldcols, newrows, newcols, err; 132337219Sminshall 132444361Sborman err = TerminalWindowSize(&oldrows, &oldcols); 132534849Sminshall (void) kill(0, SIGTSTP); 132644361Sborman err += TerminalWindowSize(&newrows, &newcols); 132744361Sborman if (connected && !err && 132844361Sborman ((oldrows != newrows) || (oldcols != newcols))) { 132937219Sminshall sendnaws(); 133037219Sminshall } 133137219Sminshall } 133237219Sminshall /* reget parameters in case they were changed */ 133337219Sminshall TerminalSaveState(); 133438689Sborman setconnmode(0); 133538689Sborman #else 133638689Sborman printf("Suspend is not supported. Try the '!' command instead\n"); 133738689Sborman #endif 133837219Sminshall return 1; 133932144Sminshall } 134032144Sminshall 134138689Sborman #if !defined(TN3270) 134246808Sdab /*ARGSUSED*/ 134346808Sdab int 134438689Sborman shell(argc, argv) 134546808Sdab int argc; 134646808Sdab char *argv[]; 134738689Sborman { 134838689Sborman setcommandmode(); 134938689Sborman switch(vfork()) { 135038689Sborman case -1: 135138689Sborman perror("Fork failed\n"); 135238689Sborman break; 135338689Sborman 135438689Sborman case 0: 135538689Sborman { 135638689Sborman /* 135738689Sborman * Fire up the shell in the child. 135838689Sborman */ 135946808Sdab register char *shellp, *shellname; 136046808Sdab extern char *rindex(); 136138689Sborman 136246808Sdab shellp = getenv("SHELL"); 136346808Sdab if (shellp == NULL) 136446808Sdab shellp = "/bin/sh"; 136546808Sdab if ((shellname = rindex(shellp, '/')) == 0) 136646808Sdab shellname = shellp; 136738689Sborman else 136838689Sborman shellname++; 136938689Sborman if (argc > 1) 137046808Sdab execl(shellp, shellname, "-c", &saveline[1], 0); 137138689Sborman else 137246808Sdab execl(shellp, shellname, 0); 137338689Sborman perror("Execl"); 137438689Sborman _exit(1); 137538689Sborman } 137638689Sborman default: 137744361Sborman (void)wait((int *)0); /* Wait for the shell to complete */ 137838689Sborman } 137946808Sdab return 1; 138038689Sborman } 138138689Sborman #endif /* !defined(TN3270) */ 138238689Sborman 138346808Sdab /*VARARGS*/ 138446808Sdab static 138532144Sminshall bye(argc, argv) 138646808Sdab int argc; /* Number of arguments */ 138746808Sdab char *argv[]; /* arguments */ 138832144Sminshall { 138946808Sdab extern int resettermname; 139046808Sdab 139132144Sminshall if (connected) { 139234849Sminshall (void) shutdown(net, 2); 139332144Sminshall printf("Connection closed.\n"); 139434849Sminshall (void) NetClose(net); 139532144Sminshall connected = 0; 139646808Sdab resettermname = 1; 139746808Sdab #if defined(AUTHENTICATE) || defined(ENCRYPT) 139846808Sdab auth_encrypt_connect(connected); 139946808Sdab #endif 140032144Sminshall /* reset options */ 140132144Sminshall tninit(); 140232144Sminshall #if defined(TN3270) 140332144Sminshall SetIn3270(); /* Get out of 3270 mode */ 140432144Sminshall #endif /* defined(TN3270) */ 140532144Sminshall } 140632144Sminshall if ((argc != 2) || (strcmp(argv[1], "fromquit") != 0)) { 140732144Sminshall longjmp(toplevel, 1); 140832144Sminshall /* NOTREACHED */ 140932144Sminshall } 141032144Sminshall return 1; /* Keep lint, etc., happy */ 141132144Sminshall } 141232144Sminshall 141332144Sminshall /*VARARGS*/ 141432144Sminshall quit() 141532144Sminshall { 141632144Sminshall (void) call(bye, "bye", "fromquit", 0); 141732144Sminshall Exit(0); 141844361Sborman /*NOTREACHED*/ 141932144Sminshall } 142046808Sdab 142146808Sdab /*VARARGS*/ 142246808Sdab int 142346808Sdab logout() 142446808Sdab { 142546808Sdab send_do(TELOPT_LOGOUT, 1); 142646808Sdab (void) netflush(); 142746808Sdab return 1; 142846808Sdab } 142946808Sdab 143038689Sborman 143138689Sborman /* 143238689Sborman * The SLC command. 143338689Sborman */ 143432144Sminshall 143538689Sborman struct slclist { 143638689Sborman char *name; 143738689Sborman char *help; 143846808Sdab void (*handler)(); 143938689Sborman int arg; 144038689Sborman }; 144138689Sborman 1442*56642Sralph static void slc_help(); 144338689Sborman 144438689Sborman struct slclist SlcList[] = { 144538689Sborman { "export", "Use local special character definitions", 144638689Sborman slc_mode_export, 0 }, 144738689Sborman { "import", "Use remote special character definitions", 144838689Sborman slc_mode_import, 1 }, 144938689Sborman { "check", "Verify remote special character definitions", 145038689Sborman slc_mode_import, 0 }, 145138689Sborman { "help", 0, slc_help, 0 }, 145238689Sborman { "?", "Print help information", slc_help, 0 }, 145338689Sborman { 0 }, 145438689Sborman }; 145538689Sborman 145646808Sdab static void 145738689Sborman slc_help() 145838689Sborman { 145938689Sborman struct slclist *c; 146038689Sborman 146138689Sborman for (c = SlcList; c->name; c++) { 146238689Sborman if (c->help) { 146338689Sborman if (*c->help) 146438689Sborman printf("%-15s %s\n", c->name, c->help); 146538689Sborman else 146638689Sborman printf("\n"); 146738689Sborman } 146838689Sborman } 146938689Sborman } 147038689Sborman 147146808Sdab static struct slclist * 147238689Sborman getslc(name) 147346808Sdab char *name; 147438689Sborman { 147546808Sdab return (struct slclist *) 147646808Sdab genget(name, (char **) SlcList, sizeof(struct slclist)); 147738689Sborman } 147838689Sborman 147946808Sdab static 148038689Sborman slccmd(argc, argv) 148146808Sdab int argc; 148246808Sdab char *argv[]; 148338689Sborman { 148438689Sborman struct slclist *c; 148538689Sborman 148638689Sborman if (argc != 2) { 148738689Sborman fprintf(stderr, 148838689Sborman "Need an argument to 'slc' command. 'slc ?' for help.\n"); 148938689Sborman return 0; 149038689Sborman } 149138689Sborman c = getslc(argv[1]); 149238689Sborman if (c == 0) { 149338689Sborman fprintf(stderr, "'%s': unknown argument ('slc ?' for help).\n", 149438689Sborman argv[1]); 149538689Sborman return 0; 149638689Sborman } 149738689Sborman if (Ambiguous(c)) { 149838689Sborman fprintf(stderr, "'%s': ambiguous argument ('slc ?' for help).\n", 149938689Sborman argv[1]); 150038689Sborman return 0; 150138689Sborman } 150238689Sborman (*c->handler)(c->arg); 150338689Sborman slcstate(); 150438689Sborman return 1; 150538689Sborman } 150644361Sborman 150744361Sborman /* 150844361Sborman * The ENVIRON command. 150944361Sborman */ 151038689Sborman 151144361Sborman struct envlist { 151244361Sborman char *name; 151344361Sborman char *help; 151446808Sdab void (*handler)(); 151544361Sborman int narg; 151644361Sborman }; 151744361Sborman 151846808Sdab extern struct env_lst * 151946808Sdab env_define P((unsigned char *, unsigned char *)); 152046808Sdab extern void 152146808Sdab env_undefine P((unsigned char *)), 152246808Sdab env_export P((unsigned char *)), 152346808Sdab env_unexport P((unsigned char *)), 152446808Sdab env_send P((unsigned char *)), 1525*56642Sralph env_list P((void)); 1526*56642Sralph static void 152746808Sdab env_help P((void)); 152844361Sborman 152944361Sborman struct envlist EnvList[] = { 153044361Sborman { "define", "Define an environment variable", 153146808Sdab (void (*)())env_define, 2 }, 153244361Sborman { "undefine", "Undefine an environment variable", 153344361Sborman env_undefine, 1 }, 153444361Sborman { "export", "Mark an environment variable for automatic export", 153544361Sborman env_export, 1 }, 153646808Sdab { "unexport", "Don't mark an environment variable for automatic export", 153744361Sborman env_unexport, 1 }, 153845233Sborman { "send", "Send an environment variable", env_send, 1 }, 153944361Sborman { "list", "List the current environment variables", 154044361Sborman env_list, 0 }, 154144361Sborman { "help", 0, env_help, 0 }, 154244361Sborman { "?", "Print help information", env_help, 0 }, 154344361Sborman { 0 }, 154444361Sborman }; 154544361Sborman 154646808Sdab static void 154744361Sborman env_help() 154844361Sborman { 154944361Sborman struct envlist *c; 155044361Sborman 155144361Sborman for (c = EnvList; c->name; c++) { 155244361Sborman if (c->help) { 155344361Sborman if (*c->help) 155444361Sborman printf("%-15s %s\n", c->name, c->help); 155544361Sborman else 155644361Sborman printf("\n"); 155744361Sborman } 155844361Sborman } 155944361Sborman } 156044361Sborman 156146808Sdab static struct envlist * 156244361Sborman getenvcmd(name) 156346808Sdab char *name; 156444361Sborman { 156546808Sdab return (struct envlist *) 156646808Sdab genget(name, (char **) EnvList, sizeof(struct envlist)); 156744361Sborman } 156844361Sborman 156944361Sborman env_cmd(argc, argv) 157046808Sdab int argc; 157146808Sdab char *argv[]; 157244361Sborman { 157344361Sborman struct envlist *c; 157444361Sborman 157544361Sborman if (argc < 2) { 157644361Sborman fprintf(stderr, 157744361Sborman "Need an argument to 'environ' command. 'environ ?' for help.\n"); 157844361Sborman return 0; 157944361Sborman } 158044361Sborman c = getenvcmd(argv[1]); 158144361Sborman if (c == 0) { 158244361Sborman fprintf(stderr, "'%s': unknown argument ('environ ?' for help).\n", 158344361Sborman argv[1]); 158444361Sborman return 0; 158544361Sborman } 158644361Sborman if (Ambiguous(c)) { 158744361Sborman fprintf(stderr, "'%s': ambiguous argument ('environ ?' for help).\n", 158844361Sborman argv[1]); 158944361Sborman return 0; 159044361Sborman } 159144361Sborman if (c->narg + 2 != argc) { 159244361Sborman fprintf(stderr, 159344361Sborman "Need %s%d argument%s to 'environ %s' command. 'environ ?' for help.\n", 159444361Sborman c->narg < argc + 2 ? "only " : "", 159544361Sborman c->narg, c->narg == 1 ? "" : "s", c->name); 159644361Sborman return 0; 159744361Sborman } 159846808Sdab (*c->handler)(argv[2], argv[3]); 159944361Sborman return 1; 160044361Sborman } 160144361Sborman 160244361Sborman struct env_lst { 160344361Sborman struct env_lst *next; /* pointer to next structure */ 160444361Sborman struct env_lst *prev; /* pointer to next structure */ 160546808Sdab unsigned char *var; /* pointer to variable name */ 160646808Sdab unsigned char *value; /* pointer to varialbe value */ 160744361Sborman int export; /* 1 -> export with default list of variables */ 160844361Sborman }; 160944361Sborman 161044361Sborman struct env_lst envlisthead; 161144361Sborman 161246808Sdab struct env_lst * 161344361Sborman env_find(var) 161446808Sdab unsigned char *var; 161544361Sborman { 161644361Sborman register struct env_lst *ep; 161744361Sborman 161844361Sborman for (ep = envlisthead.next; ep; ep = ep->next) { 161946808Sdab if (strcmp((char *)ep->var, (char *)var) == 0) 162044361Sborman return(ep); 162144361Sborman } 162244361Sborman return(NULL); 162344361Sborman } 162444361Sborman 162546808Sdab void 162644361Sborman env_init() 162744361Sborman { 162846808Sdab extern char **environ; 162944361Sborman register char **epp, *cp; 163044361Sborman register struct env_lst *ep; 163146808Sdab extern char *index(); 163244361Sborman 163344361Sborman for (epp = environ; *epp; epp++) { 163444361Sborman if (cp = index(*epp, '=')) { 163544361Sborman *cp = '\0'; 163646808Sdab ep = env_define((unsigned char *)*epp, 163746808Sdab (unsigned char *)cp+1); 163844361Sborman ep->export = 0; 163944361Sborman *cp = '='; 164044361Sborman } 164144361Sborman } 164244361Sborman /* 164344361Sborman * Special case for DISPLAY variable. If it is ":0.0" or 164444361Sborman * "unix:0.0", we have to get rid of "unix" and insert our 164544361Sborman * hostname. 164644361Sborman */ 164746808Sdab if ((ep = env_find("DISPLAY")) 164846808Sdab && ((*ep->value == ':') 164946808Sdab || (strncmp((char *)ep->value, "unix:", 5) == 0))) { 165044361Sborman char hbuf[256+1]; 165146808Sdab char *cp2 = index((char *)ep->value, ':'); 165244361Sborman 165344361Sborman gethostname(hbuf, 256); 165444361Sborman hbuf[256] = '\0'; 165544361Sborman cp = (char *)malloc(strlen(hbuf) + strlen(cp2) + 1); 165646808Sdab sprintf((char *)cp, "%s%s", hbuf, cp2); 165744361Sborman free(ep->value); 165846808Sdab ep->value = (unsigned char *)cp; 165944361Sborman } 166044361Sborman /* 166144361Sborman * If USER is not defined, but LOGNAME is, then add 166245233Sborman * USER with the value from LOGNAME. By default, we 166345233Sborman * don't export the USER variable. 166444361Sborman */ 166545233Sborman if ((env_find("USER") == NULL) && (ep = env_find("LOGNAME"))) { 166646808Sdab env_define((unsigned char *)"USER", ep->value); 166746808Sdab env_unexport((unsigned char *)"USER"); 166845233Sborman } 166946808Sdab env_export((unsigned char *)"DISPLAY"); 167046808Sdab env_export((unsigned char *)"PRINTER"); 167144361Sborman } 167244361Sborman 167346808Sdab struct env_lst * 167444361Sborman env_define(var, value) 167546808Sdab unsigned char *var, *value; 167644361Sborman { 167744361Sborman register struct env_lst *ep; 167844361Sborman 167944361Sborman if (ep = env_find(var)) { 168044361Sborman if (ep->var) 168144361Sborman free(ep->var); 168244361Sborman if (ep->value) 168344361Sborman free(ep->value); 168444361Sborman } else { 168544361Sborman ep = (struct env_lst *)malloc(sizeof(struct env_lst)); 168644361Sborman ep->next = envlisthead.next; 168744361Sborman envlisthead.next = ep; 168844361Sborman ep->prev = &envlisthead; 168944361Sborman if (ep->next) 169044361Sborman ep->next->prev = ep; 169144361Sborman } 169245009Skarels ep->export = 1; 169346808Sdab ep->var = (unsigned char *)strdup((char *)var); 169446808Sdab ep->value = (unsigned char *)strdup((char *)value); 169544361Sborman return(ep); 169644361Sborman } 169744361Sborman 169846808Sdab void 169944361Sborman env_undefine(var) 170046808Sdab unsigned char *var; 170144361Sborman { 170244361Sborman register struct env_lst *ep; 170344361Sborman 170444361Sborman if (ep = env_find(var)) { 170544361Sborman ep->prev->next = ep->next; 170645233Sborman if (ep->next) 170745233Sborman ep->next->prev = ep->prev; 170844361Sborman if (ep->var) 170944361Sborman free(ep->var); 171044361Sborman if (ep->value) 171144361Sborman free(ep->value); 171244361Sborman free(ep); 171344361Sborman } 171444361Sborman } 171544361Sborman 171646808Sdab void 171744361Sborman env_export(var) 171846808Sdab unsigned char *var; 171944361Sborman { 172044361Sborman register struct env_lst *ep; 172144361Sborman 172244361Sborman if (ep = env_find(var)) 172344361Sborman ep->export = 1; 172444361Sborman } 172544361Sborman 172646808Sdab void 172744361Sborman env_unexport(var) 172846808Sdab unsigned char *var; 172944361Sborman { 173044361Sborman register struct env_lst *ep; 173144361Sborman 173244361Sborman if (ep = env_find(var)) 173344361Sborman ep->export = 0; 173444361Sborman } 173544361Sborman 173646808Sdab void 173745233Sborman env_send(var) 173846808Sdab unsigned char *var; 173945233Sborman { 174045233Sborman register struct env_lst *ep; 174145233Sborman 174245233Sborman if (my_state_is_wont(TELOPT_ENVIRON)) { 174345233Sborman fprintf(stderr, 174445233Sborman "Cannot send '%s': Telnet ENVIRON option not enabled\n", 174545233Sborman var); 174645233Sborman return; 174745233Sborman } 174845233Sborman ep = env_find(var); 174945233Sborman if (ep == 0) { 175045233Sborman fprintf(stderr, "Cannot send '%s': variable not defined\n", 175145233Sborman var); 175245233Sborman return; 175345233Sborman } 175445233Sborman env_opt_start_info(); 175545233Sborman env_opt_add(ep->var); 175645233Sborman env_opt_end(0); 175745233Sborman } 175845233Sborman 175946808Sdab void 176044361Sborman env_list() 176144361Sborman { 176244361Sborman register struct env_lst *ep; 176344361Sborman 176444361Sborman for (ep = envlisthead.next; ep; ep = ep->next) { 176544361Sborman printf("%c %-20s %s\n", ep->export ? '*' : ' ', 176644361Sborman ep->var, ep->value); 176744361Sborman } 176844361Sborman } 176944361Sborman 177046808Sdab unsigned char * 177144361Sborman env_default(init) 177246808Sdab int init; 177344361Sborman { 177444361Sborman static struct env_lst *nep = NULL; 177544361Sborman 177644361Sborman if (init) { 177744361Sborman nep = &envlisthead; 177844361Sborman return; 177944361Sborman } 178044361Sborman if (nep) { 178144361Sborman while (nep = nep->next) { 178244361Sborman if (nep->export) 178344361Sborman return(nep->var); 178444361Sborman } 178544361Sborman } 178644361Sborman return(NULL); 178744361Sborman } 178844361Sborman 178946808Sdab unsigned char * 179044361Sborman env_getvalue(var) 179146808Sdab unsigned char *var; 179244361Sborman { 179344361Sborman register struct env_lst *ep; 179444361Sborman 179544361Sborman if (ep = env_find(var)) 179644361Sborman return(ep->value); 179744361Sborman return(NULL); 179844361Sborman } 179944361Sborman 180046808Sdab #if defined(AUTHENTICATE) 180146808Sdab /* 180246808Sdab * The AUTHENTICATE command. 180346808Sdab */ 180446808Sdab 180546808Sdab struct authlist { 180646808Sdab char *name; 180746808Sdab char *help; 180846808Sdab int (*handler)(); 180946808Sdab int narg; 181046808Sdab }; 181146808Sdab 181246808Sdab extern int 181346808Sdab auth_enable P((int)), 181446808Sdab auth_disable P((int)), 1815*56642Sralph auth_status P((void)); 1816*56642Sralph static int 181746808Sdab auth_help P((void)); 181846808Sdab 181946808Sdab struct authlist AuthList[] = { 182046808Sdab { "status", "Display current status of authentication information", 182146808Sdab auth_status, 0 }, 182246808Sdab { "disable", "Disable an authentication type ('auth disable ?' for more)", 182346808Sdab auth_disable, 1 }, 182446808Sdab { "enable", "Enable an authentication type ('auth enable ?' for more)", 182546808Sdab auth_enable, 1 }, 182646808Sdab { "help", 0, auth_help, 0 }, 182746808Sdab { "?", "Print help information", auth_help, 0 }, 182846808Sdab { 0 }, 182946808Sdab }; 183046808Sdab 183146808Sdab static int 183246808Sdab auth_help() 183344361Sborman { 183446808Sdab struct authlist *c; 183546808Sdab 183646808Sdab for (c = AuthList; c->name; c++) { 183746808Sdab if (c->help) { 183846808Sdab if (*c->help) 183946808Sdab printf("%-15s %s\n", c->name, c->help); 184046808Sdab else 184146808Sdab printf("\n"); 184246808Sdab } 184346808Sdab } 184446808Sdab return 0; 184544361Sborman } 184646808Sdab 184746808Sdab auth_cmd(argc, argv) 184846808Sdab int argc; 184946808Sdab char *argv[]; 185046808Sdab { 185146808Sdab struct authlist *c; 185246808Sdab 185346808Sdab c = (struct authlist *) 185446808Sdab genget(argv[1], (char **) AuthList, sizeof(struct authlist)); 185546808Sdab if (c == 0) { 185646808Sdab fprintf(stderr, "'%s': unknown argument ('auth ?' for help).\n", 185746808Sdab argv[1]); 185846808Sdab return 0; 185946808Sdab } 186046808Sdab if (Ambiguous(c)) { 186146808Sdab fprintf(stderr, "'%s': ambiguous argument ('auth ?' for help).\n", 186246808Sdab argv[1]); 186346808Sdab return 0; 186446808Sdab } 186546808Sdab if (c->narg + 2 != argc) { 186646808Sdab fprintf(stderr, 186746808Sdab "Need %s%d argument%s to 'auth %s' command. 'auth ?' for help.\n", 186846808Sdab c->narg < argc + 2 ? "only " : "", 186946808Sdab c->narg, c->narg == 1 ? "" : "s", c->name); 187046808Sdab return 0; 187146808Sdab } 187246808Sdab return((*c->handler)(argv[2], argv[3])); 187346808Sdab } 187445233Sborman #endif 187544361Sborman 187646808Sdab #if defined(ENCRYPT) 187732144Sminshall /* 187846808Sdab * The ENCRYPT command. 187936274Sminshall */ 188036274Sminshall 188146808Sdab struct encryptlist { 188246808Sdab char *name; 188346808Sdab char *help; 188446808Sdab int (*handler)(); 188546808Sdab int needconnect; 188646808Sdab int minarg; 188746808Sdab int maxarg; 188846808Sdab }; 188946808Sdab 189046808Sdab extern int 189146808Sdab EncryptEnable P((char *, char *)), 189247609Sdab EncryptDisable P((char *, char *)), 189346808Sdab EncryptType P((char *, char *)), 189446808Sdab EncryptStart P((char *)), 189546808Sdab EncryptStartInput P((void)), 189646808Sdab EncryptStartOutput P((void)), 189746808Sdab EncryptStop P((char *)), 189846808Sdab EncryptStopInput P((void)), 189946808Sdab EncryptStopOutput P((void)), 1900*56642Sralph EncryptStatus P((void)); 1901*56642Sralph static int 190246808Sdab EncryptHelp P((void)); 190346808Sdab 190446808Sdab struct encryptlist EncryptList[] = { 190546808Sdab { "enable", "Enable encryption. ('encrypt enable ?' for more)", 190646808Sdab EncryptEnable, 1, 1, 2 }, 190747609Sdab { "disable", "Disable encryption. ('encrypt enable ?' for more)", 190847609Sdab EncryptDisable, 0, 1, 2 }, 190946808Sdab { "type", "Set encryptiong type. ('encrypt type ?' for more)", 191046808Sdab EncryptType, 0, 1, 1 }, 191146808Sdab { "start", "Start encryption. ('encrypt start ?' for more)", 191246808Sdab EncryptStart, 1, 0, 1 }, 191346808Sdab { "stop", "Stop encryption. ('encrypt stop ?' for more)", 191446808Sdab EncryptStop, 1, 0, 1 }, 191546808Sdab { "input", "Start encrypting the input stream", 191646808Sdab EncryptStartInput, 1, 0, 0 }, 191746808Sdab { "-input", "Stop encrypting the input stream", 191846808Sdab EncryptStopInput, 1, 0, 0 }, 191946808Sdab { "output", "Start encrypting the output stream", 192046808Sdab EncryptStartOutput, 1, 0, 0 }, 192146808Sdab { "-output", "Stop encrypting the output stream", 192246808Sdab EncryptStopOutput, 1, 0, 0 }, 192346808Sdab 192446808Sdab { "status", "Display current status of authentication information", 192546808Sdab EncryptStatus, 0, 0, 0 }, 192646808Sdab { "help", 0, EncryptHelp, 0, 0, 0 }, 192746808Sdab { "?", "Print help information", EncryptHelp, 0, 0, 0 }, 192846808Sdab { 0 }, 192946808Sdab }; 193046808Sdab 193146808Sdab static int 193246808Sdab EncryptHelp() 193336274Sminshall { 193446808Sdab struct encryptlist *c; 193546808Sdab 193646808Sdab for (c = EncryptList; c->name; c++) { 193746808Sdab if (c->help) { 193846808Sdab if (*c->help) 193946808Sdab printf("%-15s %s\n", c->name, c->help); 194046808Sdab else 194146808Sdab printf("\n"); 194236274Sminshall } 194346808Sdab } 194446808Sdab return 0; 194546808Sdab } 194636274Sminshall 194746808Sdab encrypt_cmd(argc, argv) 194846808Sdab int argc; 194946808Sdab char *argv[]; 195046808Sdab { 195146808Sdab struct encryptlist *c; 195236274Sminshall 195346808Sdab c = (struct encryptlist *) 195446808Sdab genget(argv[1], (char **) EncryptList, sizeof(struct encryptlist)); 195546808Sdab if (c == 0) { 195646808Sdab fprintf(stderr, "'%s': unknown argument ('encrypt ?' for help).\n", 195746808Sdab argv[1]); 195846808Sdab return 0; 195946808Sdab } 196046808Sdab if (Ambiguous(c)) { 196146808Sdab fprintf(stderr, "'%s': ambiguous argument ('encrypt ?' for help).\n", 196246808Sdab argv[1]); 196346808Sdab return 0; 196446808Sdab } 196546808Sdab argc -= 2; 196646808Sdab if (argc < c->minarg || argc > c->maxarg) { 196746808Sdab if (c->minarg == c->maxarg) { 196846808Sdab fprintf(stderr, "Need %s%d argument%s ", 196946808Sdab c->minarg < argc ? "only " : "", c->minarg, 197046808Sdab c->minarg == 1 ? "" : "s"); 197146808Sdab } else { 197246808Sdab fprintf(stderr, "Need %s%d-%d arguments ", 197346808Sdab c->maxarg < argc ? "only " : "", c->minarg, c->maxarg); 197446808Sdab } 197546808Sdab fprintf(stderr, "to 'encrypt %s' command. 'encrypt ?' for help.\n", 197646808Sdab c->name); 197746808Sdab return 0; 197846808Sdab } 197946808Sdab if (c->needconnect && !connected) { 198046808Sdab if (!(argc && (isprefix(argv[2], "help") || isprefix(argv[2], "?")))) { 198146808Sdab printf("?Need to be connected first.\n"); 198246808Sdab return 0; 198346808Sdab } 198446808Sdab } 198546808Sdab return ((*c->handler)(argc > 0 ? argv[2] : 0, 198646808Sdab argc > 1 ? argv[3] : 0, 198746808Sdab argc > 2 ? argv[4] : 0)); 198846808Sdab } 198936274Sminshall #endif 199036274Sminshall 199146808Sdab #if defined(unix) && defined(TN3270) 199246808Sdab static void 199336274Sminshall filestuff(fd) 199446808Sdab int fd; 199536274Sminshall { 199636274Sminshall int res; 199736274Sminshall 199838689Sborman #ifdef F_GETOWN 199938689Sborman setconnmode(0); 200036274Sminshall res = fcntl(fd, F_GETOWN, 0); 200136274Sminshall setcommandmode(); 200236274Sminshall 200336274Sminshall if (res == -1) { 200436274Sminshall perror("fcntl"); 200536274Sminshall return; 200636274Sminshall } 200736274Sminshall printf("\tOwner is %d.\n", res); 200838689Sborman #endif 200936274Sminshall 201038689Sborman setconnmode(0); 201136274Sminshall res = fcntl(fd, F_GETFL, 0); 201236274Sminshall setcommandmode(); 201336274Sminshall 201436274Sminshall if (res == -1) { 201536274Sminshall perror("fcntl"); 201636274Sminshall return; 201736274Sminshall } 201836274Sminshall printf("\tFlags are 0x%x: %s\n", res, decodeflags(res)); 201936274Sminshall } 202046808Sdab #endif /* defined(unix) && defined(TN3270) */ 202136274Sminshall 202236274Sminshall /* 202332144Sminshall * Print status about the connection. 202432144Sminshall */ 202546808Sdab /*ARGSUSED*/ 202646808Sdab static 202732144Sminshall status(argc, argv) 202846808Sdab int argc; 202946808Sdab char *argv[]; 203032144Sminshall { 203132144Sminshall if (connected) { 203232144Sminshall printf("Connected to %s.\n", hostname); 203336242Sminshall if ((argc < 2) || strcmp(argv[1], "notmuch")) { 203438689Sborman int mode = getconnmode(); 203538689Sborman 203638689Sborman if (my_want_state_is_will(TELOPT_LINEMODE)) { 203738689Sborman printf("Operating with LINEMODE option\n"); 203838689Sborman printf("%s line editing\n", (mode&MODE_EDIT) ? "Local" : "No"); 203938689Sborman printf("%s catching of signals\n", 204038689Sborman (mode&MODE_TRAPSIG) ? "Local" : "No"); 204138689Sborman slcstate(); 204238689Sborman #ifdef KLUDGELINEMODE 204339529Sborman } else if (kludgelinemode && my_want_state_is_dont(TELOPT_SGA)) { 204438689Sborman printf("Operating in obsolete linemode\n"); 204538689Sborman #endif 204638689Sborman } else { 204738689Sborman printf("Operating in single character mode\n"); 204838689Sborman if (localchars) 204938689Sborman printf("Catching signals locally\n"); 205032144Sminshall } 205138689Sborman printf("%s character echo\n", (mode&MODE_ECHO) ? "Local" : "Remote"); 205238689Sborman if (my_want_state_is_will(TELOPT_LFLOW)) 205338689Sborman printf("%s flow control\n", (mode&MODE_FLOW) ? "Local" : "No"); 205446808Sdab #if defined(ENCRYPT) 205546808Sdab encrypt_display(); 205646808Sdab #endif 205732144Sminshall } 205832144Sminshall } else { 205932144Sminshall printf("No connection.\n"); 206032144Sminshall } 206132144Sminshall # if !defined(TN3270) 206232144Sminshall printf("Escape character is '%s'.\n", control(escape)); 206334849Sminshall (void) fflush(stdout); 206432144Sminshall # else /* !defined(TN3270) */ 206532144Sminshall if ((!In3270) && ((argc < 2) || strcmp(argv[1], "notmuch"))) { 206632144Sminshall printf("Escape character is '%s'.\n", control(escape)); 206732144Sminshall } 206832144Sminshall # if defined(unix) 206936242Sminshall if ((argc >= 2) && !strcmp(argv[1], "everything")) { 207036242Sminshall printf("SIGIO received %d time%s.\n", 207136242Sminshall sigiocount, (sigiocount == 1)? "":"s"); 207236274Sminshall if (In3270) { 207336274Sminshall printf("Process ID %d, process group %d.\n", 207436274Sminshall getpid(), getpgrp(getpid())); 207536274Sminshall printf("Terminal input:\n"); 207636274Sminshall filestuff(tin); 207736274Sminshall printf("Terminal output:\n"); 207836274Sminshall filestuff(tout); 207936274Sminshall printf("Network socket:\n"); 208036274Sminshall filestuff(net); 208136274Sminshall } 208236242Sminshall } 208332144Sminshall if (In3270 && transcom) { 208432144Sminshall printf("Transparent mode command is '%s'.\n", transcom); 208532144Sminshall } 208632144Sminshall # endif /* defined(unix) */ 208734849Sminshall (void) fflush(stdout); 208832144Sminshall if (In3270) { 208932144Sminshall return 0; 209032144Sminshall } 209132144Sminshall # endif /* defined(TN3270) */ 209232144Sminshall return 1; 209332144Sminshall } 209432144Sminshall 209545233Sborman #ifdef SIGINFO 209645233Sborman /* 209745233Sborman * Function that gets called when SIGINFO is received. 209845233Sborman */ 209945233Sborman ayt_status() 210045233Sborman { 210145233Sborman (void) call(status, "status", "notmuch", 0); 210245233Sborman } 210345233Sborman #endif 210432144Sminshall 210546808Sdab int 210632144Sminshall tn(argc, argv) 210746808Sdab int argc; 210846808Sdab char *argv[]; 210932144Sminshall { 211032144Sminshall register struct hostent *host = 0; 211132144Sminshall struct sockaddr_in sin; 211232144Sminshall struct servent *sp = 0; 211338689Sborman unsigned long temp, inet_addr(); 211437219Sminshall extern char *inet_ntoa(); 211546808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 211638689Sborman char *srp = 0, *strrchr(); 211738689Sborman unsigned long sourceroute(), srlen; 211838689Sborman #endif 211944361Sborman char *cmd, *hostp = 0, *portp = 0, *user = 0; 212032144Sminshall 212145233Sborman /* clear the socket address prior to use */ 212245233Sborman bzero((char *)&sin, sizeof(sin)); 212332144Sminshall 212432144Sminshall if (connected) { 212532144Sminshall printf("?Already connected to %s\n", hostname); 212646808Sdab setuid(getuid()); 212732144Sminshall return 0; 212832144Sminshall } 212932144Sminshall if (argc < 2) { 213046808Sdab (void) strcpy(line, "open "); 213132144Sminshall printf("(to) "); 213246808Sdab (void) fgets(&line[strlen(line)], sizeof(line) - strlen(line), stdin); 213332144Sminshall makeargv(); 213432144Sminshall argc = margc; 213532144Sminshall argv = margv; 213632144Sminshall } 213744361Sborman cmd = *argv; 213844361Sborman --argc; ++argv; 213944361Sborman while (argc) { 214046808Sdab if (isprefix(*argv, "help") || isprefix(*argv, "?")) 214146808Sdab goto usage; 214244361Sborman if (strcmp(*argv, "-l") == 0) { 214344361Sborman --argc; ++argv; 214444361Sborman if (argc == 0) 214544361Sborman goto usage; 214644361Sborman user = *argv++; 214744361Sborman --argc; 214844361Sborman continue; 214944361Sborman } 215045233Sborman if (strcmp(*argv, "-a") == 0) { 215145233Sborman --argc; ++argv; 215245233Sborman autologin = 1; 215345233Sborman continue; 215445233Sborman } 215544361Sborman if (hostp == 0) { 215644361Sborman hostp = *argv++; 215744361Sborman --argc; 215844361Sborman continue; 215944361Sborman } 216044361Sborman if (portp == 0) { 216144361Sborman portp = *argv++; 216244361Sborman --argc; 216344361Sborman continue; 216444361Sborman } 216544361Sborman usage: 216645233Sborman printf("usage: %s [-l user] [-a] host-name [port]\n", cmd); 216746808Sdab setuid(getuid()); 216832144Sminshall return 0; 216932144Sminshall } 217046808Sdab if (hostp == 0) 217146808Sdab goto usage; 217246808Sdab 217346808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 217444361Sborman if (hostp[0] == '@' || hostp[0] == '!') { 217544361Sborman if ((hostname = strrchr(hostp, ':')) == NULL) 217644361Sborman hostname = strrchr(hostp, '@'); 217738689Sborman hostname++; 217838689Sborman srp = 0; 217944361Sborman temp = sourceroute(hostp, &srp, &srlen); 218038689Sborman if (temp == 0) { 218138689Sborman herror(srp); 218246808Sdab setuid(getuid()); 218338689Sborman return 0; 218438689Sborman } else if (temp == -1) { 218544361Sborman printf("Bad source route option: %s\n", hostp); 218646808Sdab setuid(getuid()); 218738689Sborman return 0; 218838689Sborman } else { 218938689Sborman sin.sin_addr.s_addr = temp; 219038689Sborman sin.sin_family = AF_INET; 219138689Sborman } 219232144Sminshall } else { 219338689Sborman #endif 219444361Sborman temp = inet_addr(hostp); 219538689Sborman if (temp != (unsigned long) -1) { 219638689Sborman sin.sin_addr.s_addr = temp; 219738689Sborman sin.sin_family = AF_INET; 219846808Sdab (void) strcpy(_hostname, hostp); 219946808Sdab hostname = _hostname; 220038689Sborman } else { 220144361Sborman host = gethostbyname(hostp); 220238689Sborman if (host) { 220338689Sborman sin.sin_family = host->h_addrtype; 220432144Sminshall #if defined(h_addr) /* In 4.3, this is a #define */ 220538689Sborman memcpy((caddr_t)&sin.sin_addr, 220632144Sminshall host->h_addr_list[0], host->h_length); 220732144Sminshall #else /* defined(h_addr) */ 220838689Sborman memcpy((caddr_t)&sin.sin_addr, host->h_addr, host->h_length); 220932144Sminshall #endif /* defined(h_addr) */ 221046808Sdab strncpy(_hostname, host->h_name, sizeof(_hostname)); 221146808Sdab _hostname[sizeof(_hostname)-1] = '\0'; 221246808Sdab hostname = _hostname; 221338689Sborman } else { 221444361Sborman herror(hostp); 221546808Sdab setuid(getuid()); 221638689Sborman return 0; 221738689Sborman } 221832144Sminshall } 221946808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 222032144Sminshall } 222138689Sborman #endif 222244361Sborman if (portp) { 222344361Sborman if (*portp == '-') { 222444361Sborman portp++; 222538689Sborman telnetport = 1; 222638689Sborman } else 222738689Sborman telnetport = 0; 222844361Sborman sin.sin_port = atoi(portp); 222932144Sminshall if (sin.sin_port == 0) { 223044361Sborman sp = getservbyname(portp, "tcp"); 223132144Sminshall if (sp) 223232144Sminshall sin.sin_port = sp->s_port; 223332144Sminshall else { 223444361Sborman printf("%s: bad port number\n", portp); 223546808Sdab setuid(getuid()); 223632144Sminshall return 0; 223732144Sminshall } 223832144Sminshall } else { 223932144Sminshall sin.sin_port = htons(sin.sin_port); 224032144Sminshall } 224132144Sminshall } else { 224232144Sminshall if (sp == 0) { 224332144Sminshall sp = getservbyname("telnet", "tcp"); 224432144Sminshall if (sp == 0) { 224534849Sminshall fprintf(stderr, "telnet: tcp/telnet: unknown service\n"); 224646808Sdab setuid(getuid()); 224732144Sminshall return 0; 224832144Sminshall } 224932144Sminshall sin.sin_port = sp->s_port; 225032144Sminshall } 225132144Sminshall telnetport = 1; 225232144Sminshall } 225337219Sminshall printf("Trying %s...\n", inet_ntoa(sin.sin_addr)); 225432144Sminshall do { 225532144Sminshall net = socket(AF_INET, SOCK_STREAM, 0); 225646808Sdab setuid(getuid()); 225732144Sminshall if (net < 0) { 225832144Sminshall perror("telnet: socket"); 225932144Sminshall return 0; 226032144Sminshall } 226146808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 226238689Sborman if (srp && setsockopt(net, IPPROTO_IP, IP_OPTIONS, (char *)srp, srlen) < 0) 226338689Sborman perror("setsockopt (IP_OPTIONS)"); 226438689Sborman #endif 226546808Sdab #if defined(IPPROTO_IP) && defined(IP_TOS) 226646808Sdab { 226746808Sdab # if defined(HAS_GETTOS) 226846808Sdab struct tosent *tp; 226946815Sdab if (tos < 0 && (tp = gettosbyname("telnet", "tcp"))) 227046808Sdab tos = tp->t_tos; 227146808Sdab # endif 227246815Sdab if (tos < 0) 227346815Sdab tos = 020; /* Low Delay bit */ 227446815Sdab if (tos 227546815Sdab && (setsockopt(net, IPPROTO_IP, IP_TOS, &tos, sizeof(int)) < 0) 227646815Sdab && (errno != ENOPROTOOPT)) 227746815Sdab perror("telnet: setsockopt (IP_TOS) (ignored)"); 227846808Sdab } 227946808Sdab #endif /* defined(IPPROTO_IP) && defined(IP_TOS) */ 228040245Sborman 228132144Sminshall if (debug && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 1) < 0) { 228232144Sminshall perror("setsockopt (SO_DEBUG)"); 228332144Sminshall } 228432144Sminshall 228532144Sminshall if (connect(net, (struct sockaddr *)&sin, sizeof (sin)) < 0) { 228632144Sminshall #if defined(h_addr) /* In 4.3, this is a #define */ 228732144Sminshall if (host && host->h_addr_list[1]) { 228832144Sminshall int oerrno = errno; 228932144Sminshall 229032144Sminshall fprintf(stderr, "telnet: connect to address %s: ", 229132144Sminshall inet_ntoa(sin.sin_addr)); 229232144Sminshall errno = oerrno; 229332144Sminshall perror((char *)0); 229432144Sminshall host->h_addr_list++; 229532144Sminshall memcpy((caddr_t)&sin.sin_addr, 229632144Sminshall host->h_addr_list[0], host->h_length); 229732144Sminshall (void) NetClose(net); 229832144Sminshall continue; 229932144Sminshall } 230032144Sminshall #endif /* defined(h_addr) */ 230132144Sminshall perror("telnet: Unable to connect to remote host"); 230232144Sminshall return 0; 230337219Sminshall } 230432144Sminshall connected++; 230546808Sdab #if defined(AUTHENTICATE) || defined(ENCRYPT) 230646808Sdab auth_encrypt_connect(connected); 230746808Sdab #endif 230832144Sminshall } while (connected == 0); 230944361Sborman cmdrc(hostp, hostname); 231045008Skarels if (autologin && user == NULL) { 231145008Skarels struct passwd *pw; 231245008Skarels 231345233Sborman user = getenv("USER"); 231445008Skarels if (user == NULL || 231545233Sborman (pw = getpwnam(user)) && pw->pw_uid != getuid()) { 231645233Sborman if (pw = getpwuid(getuid())) 231745008Skarels user = pw->pw_name; 231845008Skarels else 231945008Skarels user = NULL; 232045233Sborman } 232145008Skarels } 232245008Skarels if (user) { 232346808Sdab env_define((unsigned char *)"USER", (unsigned char *)user); 232446808Sdab env_export((unsigned char *)"USER"); 232545008Skarels } 232634849Sminshall (void) call(status, "status", "notmuch", 0); 232732144Sminshall if (setjmp(peerdied) == 0) 232846808Sdab telnet(user); 232934849Sminshall (void) NetClose(net); 233032381Sminshall ExitString("Connection closed by foreign host.\n",1); 233132144Sminshall /*NOTREACHED*/ 233232144Sminshall } 233332144Sminshall 233432144Sminshall #define HELPINDENT (sizeof ("connect")) 233532144Sminshall 233632144Sminshall static char 233732144Sminshall openhelp[] = "connect to a site", 233832144Sminshall closehelp[] = "close current connection", 233946808Sdab logouthelp[] = "forcibly logout remote user and close the connection", 234032144Sminshall quithelp[] = "exit telnet", 234132144Sminshall statushelp[] = "print status information", 234232144Sminshall helphelp[] = "print help information", 234332144Sminshall sendhelp[] = "transmit special characters ('send ?' for more)", 234432144Sminshall sethelp[] = "set operating parameters ('set ?' for more)", 234538689Sborman unsethelp[] = "unset operating parameters ('unset ?' for more)", 234632144Sminshall togglestring[] ="toggle operating parameters ('toggle ?' for more)", 234738689Sborman slchelp[] = "change state of special charaters ('slc ?' for more)", 234832144Sminshall displayhelp[] = "display operating parameters", 234932144Sminshall #if defined(TN3270) && defined(unix) 235032144Sminshall transcomhelp[] = "specify Unix command for transparent mode pipe", 235132144Sminshall #endif /* defined(TN3270) && defined(unix) */ 235246808Sdab #if defined(AUTHENTICATE) 235346808Sdab authhelp[] = "turn on (off) authentication ('auth ?' for more)", 235446808Sdab #endif 235546808Sdab #if defined(ENCRYPT) 235646808Sdab encrypthelp[] = "turn on (off) encryption ('encrypt ?' for more)", 235746808Sdab #endif 235832144Sminshall #if defined(unix) 235932144Sminshall zhelp[] = "suspend telnet", 236043317Skfall #endif /* defined(unix) */ 236132144Sminshall shellhelp[] = "invoke a subshell", 236244361Sborman envhelp[] = "change environment variables ('environ ?' for more)", 236344361Sborman modestring[] = "try to enter line or character mode ('mode ?' for more)"; 236432144Sminshall 2365*56642Sralph static int help(); 236632144Sminshall 236732144Sminshall static Command cmdtab[] = { 236838689Sborman { "close", closehelp, bye, 1 }, 236946808Sdab { "logout", logouthelp, logout, 1 }, 237038689Sborman { "display", displayhelp, display, 0 }, 237138689Sborman { "mode", modestring, modecmd, 0 }, 237238689Sborman { "open", openhelp, tn, 0 }, 237338689Sborman { "quit", quithelp, quit, 0 }, 237438689Sborman { "send", sendhelp, sendcmd, 0 }, 237538689Sborman { "set", sethelp, setcmd, 0 }, 237638689Sborman { "unset", unsethelp, unsetcmd, 0 }, 237738689Sborman { "status", statushelp, status, 0 }, 237838689Sborman { "toggle", togglestring, toggle, 0 }, 237938689Sborman { "slc", slchelp, slccmd, 0 }, 238032144Sminshall #if defined(TN3270) && defined(unix) 238138689Sborman { "transcom", transcomhelp, settranscom, 0 }, 238232144Sminshall #endif /* defined(TN3270) && defined(unix) */ 238346808Sdab #if defined(AUTHENTICATE) 238446808Sdab { "auth", authhelp, auth_cmd, 0 }, 238546808Sdab #endif 238646808Sdab #if defined(ENCRYPT) 238746808Sdab { "encrypt", encrypthelp, encrypt_cmd, 0 }, 238846808Sdab #endif 238932144Sminshall #if defined(unix) 239038689Sborman { "z", zhelp, suspend, 0 }, 239132144Sminshall #endif /* defined(unix) */ 239232144Sminshall #if defined(TN3270) 239338689Sborman { "!", shellhelp, shell, 1 }, 239438689Sborman #else 239538689Sborman { "!", shellhelp, shell, 0 }, 239638689Sborman #endif 239744361Sborman { "environ", envhelp, env_cmd, 0 }, 239838689Sborman { "?", helphelp, help, 0 }, 239932144Sminshall 0 240032144Sminshall }; 240132144Sminshall 240232144Sminshall static char crmodhelp[] = "deprecated command -- use 'toggle crmod' instead"; 240332144Sminshall static char escapehelp[] = "deprecated command -- use 'set escape' instead"; 240432144Sminshall 240532144Sminshall static Command cmdtab2[] = { 240638689Sborman { "help", 0, help, 0 }, 240738689Sborman { "escape", escapehelp, setescape, 0 }, 240838689Sborman { "crmod", crmodhelp, togcrmod, 0 }, 240932144Sminshall 0 241032144Sminshall }; 241132144Sminshall 241235298Sminshall 241332144Sminshall /* 241432144Sminshall * Call routine with argc, argv set from args (terminated by 0). 241532144Sminshall */ 241635298Sminshall 241746808Sdab /*VARARGS1*/ 241846808Sdab static 241935298Sminshall call(va_alist) 242046808Sdab va_dcl 242132144Sminshall { 242235298Sminshall va_list ap; 242335298Sminshall typedef int (*intrtn_t)(); 242435298Sminshall intrtn_t routine; 242535298Sminshall char *args[100]; 242635298Sminshall int argno = 0; 242735298Sminshall 242835298Sminshall va_start(ap); 242935298Sminshall routine = (va_arg(ap, intrtn_t)); 243035495Sminshall while ((args[argno++] = va_arg(ap, char *)) != 0) { 243135298Sminshall ; 243235495Sminshall } 243335298Sminshall va_end(ap); 243435495Sminshall return (*routine)(argno-1, args); 243532144Sminshall } 243632144Sminshall 243735298Sminshall 243846808Sdab static Command * 243932144Sminshall getcmd(name) 244046808Sdab char *name; 244132144Sminshall { 244232144Sminshall Command *cm; 244332144Sminshall 244446808Sdab if (cm = (Command *) genget(name, (char **) cmdtab, sizeof(Command))) 244532144Sminshall return cm; 244646808Sdab return (Command *) genget(name, (char **) cmdtab2, sizeof(Command)); 244732144Sminshall } 244832144Sminshall 244946808Sdab void 245038689Sborman command(top, tbuf, cnt) 245146808Sdab int top; 245246808Sdab char *tbuf; 245346808Sdab int cnt; 245432144Sminshall { 245532144Sminshall register Command *c; 245632144Sminshall 245732144Sminshall setcommandmode(); 245832144Sminshall if (!top) { 245932144Sminshall putchar('\n'); 246037219Sminshall #if defined(unix) 246132144Sminshall } else { 246244361Sborman (void) signal(SIGINT, SIG_DFL); 246344361Sborman (void) signal(SIGQUIT, SIG_DFL); 246432144Sminshall #endif /* defined(unix) */ 246532144Sminshall } 246632144Sminshall for (;;) { 246746808Sdab if (rlogin == _POSIX_VDISABLE) 246846808Sdab printf("%s> ", prompt); 246938689Sborman if (tbuf) { 247038689Sborman register char *cp; 247138689Sborman cp = line; 247238689Sborman while (cnt > 0 && (*cp++ = *tbuf++) != '\n') 247338689Sborman cnt--; 247438689Sborman tbuf = 0; 247538689Sborman if (cp == line || *--cp != '\n' || cp == line) 247638689Sborman goto getline; 247738689Sborman *cp = '\0'; 247846808Sdab if (rlogin == _POSIX_VDISABLE) 247946808Sdab printf("%s\n", line); 248038689Sborman } else { 248138689Sborman getline: 248246808Sdab if (rlogin != _POSIX_VDISABLE) 248346808Sdab printf("%s> ", prompt); 248446808Sdab if (fgets(line, sizeof(line), stdin) == NULL) { 248544361Sborman if (feof(stdin) || ferror(stdin)) { 248644361Sborman (void) quit(); 248744361Sborman /*NOTREACHED*/ 248844361Sborman } 248938689Sborman break; 249038689Sborman } 249132144Sminshall } 249232144Sminshall if (line[0] == 0) 249332144Sminshall break; 249432144Sminshall makeargv(); 249537219Sminshall if (margv[0] == 0) { 249637219Sminshall break; 249737219Sminshall } 249832144Sminshall c = getcmd(margv[0]); 249932144Sminshall if (Ambiguous(c)) { 250032144Sminshall printf("?Ambiguous command\n"); 250132144Sminshall continue; 250232144Sminshall } 250332144Sminshall if (c == 0) { 250432144Sminshall printf("?Invalid command\n"); 250532144Sminshall continue; 250632144Sminshall } 250732144Sminshall if (c->needconnect && !connected) { 250832144Sminshall printf("?Need to be connected first.\n"); 250932144Sminshall continue; 251032144Sminshall } 251132144Sminshall if ((*c->handler)(margc, margv)) { 251232144Sminshall break; 251332144Sminshall } 251432144Sminshall } 251532144Sminshall if (!top) { 251632144Sminshall if (!connected) { 251732144Sminshall longjmp(toplevel, 1); 251832144Sminshall /*NOTREACHED*/ 251932144Sminshall } 252032144Sminshall #if defined(TN3270) 252132144Sminshall if (shell_active == 0) { 252238689Sborman setconnmode(0); 252332144Sminshall } 252432144Sminshall #else /* defined(TN3270) */ 252538689Sborman setconnmode(0); 252632144Sminshall #endif /* defined(TN3270) */ 252732144Sminshall } 252832144Sminshall } 252932144Sminshall 253032144Sminshall /* 253132144Sminshall * Help command. 253232144Sminshall */ 253346808Sdab static 253432144Sminshall help(argc, argv) 253532144Sminshall int argc; 253632144Sminshall char *argv[]; 253732144Sminshall { 253832144Sminshall register Command *c; 253932144Sminshall 254032144Sminshall if (argc == 1) { 254132144Sminshall printf("Commands may be abbreviated. Commands are:\n\n"); 254232144Sminshall for (c = cmdtab; c->name; c++) 254338689Sborman if (c->help) { 254432144Sminshall printf("%-*s\t%s\n", HELPINDENT, c->name, 254532144Sminshall c->help); 254632144Sminshall } 254732144Sminshall return 0; 254832144Sminshall } 254932144Sminshall while (--argc > 0) { 255032144Sminshall register char *arg; 255132144Sminshall arg = *++argv; 255232144Sminshall c = getcmd(arg); 255332144Sminshall if (Ambiguous(c)) 255432144Sminshall printf("?Ambiguous help command %s\n", arg); 255532144Sminshall else if (c == (Command *)0) 255632144Sminshall printf("?Invalid help command %s\n", arg); 255732144Sminshall else 255832144Sminshall printf("%s\n", c->help); 255932144Sminshall } 256032144Sminshall return 0; 256132144Sminshall } 256238689Sborman 256338689Sborman static char *rcname = 0; 256438689Sborman static char rcbuf[128]; 256538689Sborman 256638689Sborman cmdrc(m1, m2) 256738689Sborman char *m1, *m2; 256838689Sborman { 256938689Sborman register Command *c; 257038689Sborman FILE *rcfile; 257138689Sborman int gotmachine = 0; 257238689Sborman int l1 = strlen(m1); 257338689Sborman int l2 = strlen(m2); 257438689Sborman char m1save[64]; 257538689Sborman 257647609Sdab if (skiprc) 257747609Sdab return; 257847609Sdab 257938689Sborman strcpy(m1save, m1); 258038689Sborman m1 = m1save; 258138689Sborman 258238689Sborman if (rcname == 0) { 258338689Sborman rcname = getenv("HOME"); 258438689Sborman if (rcname) 258538689Sborman strcpy(rcbuf, rcname); 258638689Sborman else 258738689Sborman rcbuf[0] = '\0'; 258838689Sborman strcat(rcbuf, "/.telnetrc"); 258938689Sborman rcname = rcbuf; 259038689Sborman } 259138689Sborman 259238689Sborman if ((rcfile = fopen(rcname, "r")) == 0) { 259338689Sborman return; 259438689Sborman } 259538689Sborman 259638689Sborman for (;;) { 259738689Sborman if (fgets(line, sizeof(line), rcfile) == NULL) 259838689Sborman break; 259938689Sborman if (line[0] == 0) 260038689Sborman break; 260138689Sborman if (line[0] == '#') 260238689Sborman continue; 260347609Sdab if (gotmachine) { 260447609Sdab if (!isspace(line[0])) 260547609Sdab gotmachine = 0; 260647609Sdab } 260738689Sborman if (gotmachine == 0) { 260838689Sborman if (isspace(line[0])) 260938689Sborman continue; 261038689Sborman if (strncasecmp(line, m1, l1) == 0) 261138689Sborman strncpy(line, &line[l1], sizeof(line) - l1); 261238689Sborman else if (strncasecmp(line, m2, l2) == 0) 261338689Sborman strncpy(line, &line[l2], sizeof(line) - l2); 261447609Sdab else if (strncasecmp(line, "DEFAULT", 7) == 0) 261547609Sdab strncpy(line, &line[7], sizeof(line) - 7); 261638689Sborman else 261738689Sborman continue; 261847609Sdab if (line[0] != ' ' && line[0] != '\t' && line[0] != '\n') 261947609Sdab continue; 262038689Sborman gotmachine = 1; 262138689Sborman } 262238689Sborman makeargv(); 262338689Sborman if (margv[0] == 0) 262438689Sborman continue; 262538689Sborman c = getcmd(margv[0]); 262638689Sborman if (Ambiguous(c)) { 262738689Sborman printf("?Ambiguous command: %s\n", margv[0]); 262838689Sborman continue; 262938689Sborman } 263038689Sborman if (c == 0) { 263138689Sborman printf("?Invalid command: %s\n", margv[0]); 263238689Sborman continue; 263338689Sborman } 263438689Sborman /* 263538689Sborman * This should never happen... 263638689Sborman */ 263738689Sborman if (c->needconnect && !connected) { 263838689Sborman printf("?Need to be connected first for %s.\n", margv[0]); 263938689Sborman continue; 264038689Sborman } 264138689Sborman (*c->handler)(margc, margv); 264238689Sborman } 264338689Sborman fclose(rcfile); 264438689Sborman } 264538689Sborman 264646808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 264738689Sborman 264838689Sborman /* 264938689Sborman * Source route is handed in as 265038689Sborman * [!]@hop1@hop2...[@|:]dst 265138689Sborman * If the leading ! is present, it is a 265238689Sborman * strict source route, otherwise it is 265338689Sborman * assmed to be a loose source route. 265438689Sborman * 265538689Sborman * We fill in the source route option as 265638689Sborman * hop1,hop2,hop3...dest 265738689Sborman * and return a pointer to hop1, which will 265838689Sborman * be the address to connect() to. 265938689Sborman * 266038689Sborman * Arguments: 266138689Sborman * arg: pointer to route list to decipher 266238689Sborman * 266338689Sborman * cpp: If *cpp is not equal to NULL, this is a 266438689Sborman * pointer to a pointer to a character array 266538689Sborman * that should be filled in with the option. 266638689Sborman * 266738689Sborman * lenp: pointer to an integer that contains the 266838689Sborman * length of *cpp if *cpp != NULL. 266938689Sborman * 267038689Sborman * Return values: 267138689Sborman * 267238689Sborman * Returns the address of the host to connect to. If the 267338689Sborman * return value is -1, there was a syntax error in the 267438689Sborman * option, either unknown characters, or too many hosts. 267538689Sborman * If the return value is 0, one of the hostnames in the 267638689Sborman * path is unknown, and *cpp is set to point to the bad 267738689Sborman * hostname. 267838689Sborman * 267938689Sborman * *cpp: If *cpp was equal to NULL, it will be filled 268038689Sborman * in with a pointer to our static area that has 268138689Sborman * the option filled in. This will be 32bit aligned. 268238689Sborman * 268338689Sborman * *lenp: This will be filled in with how long the option 268438689Sborman * pointed to by *cpp is. 268538689Sborman * 268638689Sborman */ 268746808Sdab unsigned long 268838689Sborman sourceroute(arg, cpp, lenp) 268946808Sdab char *arg; 269046808Sdab char **cpp; 269146808Sdab int *lenp; 269238689Sborman { 269338689Sborman static char lsr[44]; 269446808Sdab char *cp, *cp2, *lsrp, *lsrep; 269538689Sborman register int tmp; 269638689Sborman struct in_addr sin_addr; 269738689Sborman register struct hostent *host = 0; 269838689Sborman register char c; 269938689Sborman 270038689Sborman /* 270138689Sborman * Verify the arguments, and make sure we have 270238689Sborman * at least 7 bytes for the option. 270338689Sborman */ 270438689Sborman if (cpp == NULL || lenp == NULL) 270538689Sborman return((unsigned long)-1); 270638689Sborman if (*cpp != NULL && *lenp < 7) 270738689Sborman return((unsigned long)-1); 270838689Sborman /* 270938689Sborman * Decide whether we have a buffer passed to us, 271038689Sborman * or if we need to use our own static buffer. 271138689Sborman */ 271238689Sborman if (*cpp) { 271338689Sborman lsrp = *cpp; 271438689Sborman lsrep = lsrp + *lenp; 271538689Sborman } else { 271638689Sborman *cpp = lsrp = lsr; 271738689Sborman lsrep = lsrp + 44; 271838689Sborman } 271938689Sborman 272038689Sborman cp = arg; 272138689Sborman 272238689Sborman /* 272338689Sborman * Next, decide whether we have a loose source 272438689Sborman * route or a strict source route, and fill in 272538689Sborman * the begining of the option. 272638689Sborman */ 272738689Sborman if (*cp == '!') { 272838689Sborman cp++; 272938689Sborman *lsrp++ = IPOPT_SSRR; 273038689Sborman } else 273138689Sborman *lsrp++ = IPOPT_LSRR; 273238689Sborman 273338689Sborman if (*cp != '@') 273438689Sborman return((unsigned long)-1); 273538689Sborman 273638689Sborman lsrp++; /* skip over length, we'll fill it in later */ 273738689Sborman *lsrp++ = 4; 273838689Sborman 273938689Sborman cp++; 274038689Sborman 274138689Sborman sin_addr.s_addr = 0; 274238689Sborman 274338689Sborman for (c = 0;;) { 274438689Sborman if (c == ':') 274538689Sborman cp2 = 0; 274638689Sborman else for (cp2 = cp; c = *cp2; cp2++) { 274738689Sborman if (c == ',') { 274838689Sborman *cp2++ = '\0'; 274938689Sborman if (*cp2 == '@') 275038689Sborman cp2++; 275138689Sborman } else if (c == '@') { 275238689Sborman *cp2++ = '\0'; 275338689Sborman } else if (c == ':') { 275438689Sborman *cp2++ = '\0'; 275538689Sborman } else 275638689Sborman continue; 275738689Sborman break; 275838689Sborman } 275938689Sborman if (!c) 276038689Sborman cp2 = 0; 276138689Sborman 276238689Sborman if ((tmp = inet_addr(cp)) != -1) { 276338689Sborman sin_addr.s_addr = tmp; 276438689Sborman } else if (host = gethostbyname(cp)) { 276538689Sborman #if defined(h_addr) 276638689Sborman memcpy((caddr_t)&sin_addr, 276738689Sborman host->h_addr_list[0], host->h_length); 276838689Sborman #else 276938689Sborman memcpy((caddr_t)&sin_addr, host->h_addr, host->h_length); 277038689Sborman #endif 277138689Sborman } else { 277238689Sborman *cpp = cp; 277338689Sborman return(0); 277438689Sborman } 277538689Sborman memcpy(lsrp, (char *)&sin_addr, 4); 277638689Sborman lsrp += 4; 277738689Sborman if (cp2) 277838689Sborman cp = cp2; 277938689Sborman else 278038689Sborman break; 278138689Sborman /* 278238689Sborman * Check to make sure there is space for next address 278338689Sborman */ 278438689Sborman if (lsrp + 4 > lsrep) 278538689Sborman return((unsigned long)-1); 278638689Sborman } 278738689Sborman if ((*(*cpp+IPOPT_OLEN) = lsrp - *cpp) <= 7) { 278838689Sborman *cpp = 0; 278938689Sborman *lenp = 0; 279038689Sborman return((unsigned long)-1); 279138689Sborman } 279238689Sborman *lsrp++ = IPOPT_NOP; /* 32 bit word align it */ 279338689Sborman *lenp = lsrp - *cpp; 279438689Sborman return(sin_addr.s_addr); 279538689Sborman } 279638689Sborman #endif 2797