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*56859Storek static char sccsid[] = "@(#)commands.c 5.7 (Berkeley) 11/16/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 22356642Sralph 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 count; /* how many bytes we are going to need to send */ 26932144Sminshall int i; 27032144Sminshall int question = 0; /* was at least one argument a question */ 27132144Sminshall struct sendlist *s; /* pointer to current command */ 27246808Sdab int success = 0; 27346808Sdab int needconnect = 0; 27432144Sminshall 27532144Sminshall if (argc < 2) { 27632144Sminshall printf("need at least one argument for 'send' command\n"); 27732144Sminshall printf("'send ?' for help\n"); 27832144Sminshall return 0; 27932144Sminshall } 28032144Sminshall /* 28132144Sminshall * First, validate all the send arguments. 28232144Sminshall * In addition, we see how much space we are going to need, and 28332144Sminshall * whether or not we will be doing a "SYNCH" operation (which 28432144Sminshall * flushes the network queue). 28532144Sminshall */ 28632144Sminshall count = 0; 28732144Sminshall for (i = 1; i < argc; i++) { 28846808Sdab s = GETSEND(argv[i]); 28932144Sminshall if (s == 0) { 29032144Sminshall printf("Unknown send argument '%s'\n'send ?' for help.\n", 29132144Sminshall argv[i]); 29232144Sminshall return 0; 29332144Sminshall } else if (Ambiguous(s)) { 29432144Sminshall printf("Ambiguous send argument '%s'\n'send ?' for help.\n", 29532144Sminshall argv[i]); 29632144Sminshall return 0; 29732144Sminshall } 29846808Sdab if (i + s->narg >= argc) { 29946808Sdab fprintf(stderr, 30046808Sdab "Need %d argument%s to 'send %s' command. 'send %s ?' for help.\n", 30146808Sdab s->narg, s->narg == 1 ? "" : "s", s->name, s->name); 30246808Sdab return 0; 30332144Sminshall } 30446808Sdab count += s->nbyte; 30546808Sdab if (s->handler == send_help) { 30646808Sdab send_help(); 30746808Sdab return 0; 30846808Sdab } 30946808Sdab 31046808Sdab i += s->narg; 31146808Sdab needconnect += s->needconnect; 31232144Sminshall } 31346808Sdab if (!connected && needconnect) { 31446808Sdab printf("?Need to be connected first.\n"); 31546808Sdab printf("'send ?' for help\n"); 31646808Sdab return 0; 31738689Sborman } 31832144Sminshall /* Now, do we have enough room? */ 31932144Sminshall if (NETROOM() < count) { 32032144Sminshall printf("There is not enough room in the buffer TO the network\n"); 32132144Sminshall printf("to process your request. Nothing will be done.\n"); 32232144Sminshall printf("('send synch' will throw away most data in the network\n"); 32332144Sminshall printf("buffer, if this might help.)\n"); 32432144Sminshall return 0; 32532144Sminshall } 32632144Sminshall /* OK, they are all OK, now go through again and actually send */ 32746808Sdab count = 0; 32832144Sminshall for (i = 1; i < argc; i++) { 32946808Sdab if ((s = GETSEND(argv[i])) == 0) { 33032144Sminshall fprintf(stderr, "Telnet 'send' error - argument disappeared!\n"); 33144361Sborman (void) quit(); 33232144Sminshall /*NOTREACHED*/ 33332144Sminshall } 33438689Sborman if (s->handler) { 33546808Sdab count++; 33646808Sdab success += (*s->handler)((s->narg > 0) ? argv[i+1] : 0, 33746808Sdab (s->narg > 1) ? argv[i+2] : 0); 33846808Sdab i += s->narg; 33932144Sminshall } else { 340*56859Storek NET2ADD(IAC, s->what); 341*56859Storek printoption("SENT", IAC, s->what); 34246808Sdab } 34346808Sdab } 34446808Sdab return (count == success); 34546808Sdab } 34646808Sdab 34746808Sdab static int 34846808Sdab send_esc() 34946808Sdab { 35046808Sdab NETADD(escape); 35146808Sdab return 1; 35246808Sdab } 35346808Sdab 35446808Sdab static int 35546808Sdab send_docmd(name) 35646808Sdab char *name; 35746808Sdab { 35846808Sdab void send_do(); 35946808Sdab return(send_tncmd(send_do, "do", name)); 36046808Sdab } 36146808Sdab 36246808Sdab static int 36346808Sdab send_dontcmd(name) 36446808Sdab char *name; 36546808Sdab { 36646808Sdab void send_dont(); 36746808Sdab return(send_tncmd(send_dont, "dont", name)); 36846808Sdab } 36946808Sdab static int 37046808Sdab send_willcmd(name) 37146808Sdab char *name; 37246808Sdab { 37346808Sdab void send_will(); 37446808Sdab return(send_tncmd(send_will, "will", name)); 37546808Sdab } 37646808Sdab static int 37746808Sdab send_wontcmd(name) 37846808Sdab char *name; 37946808Sdab { 38046808Sdab void send_wont(); 38146808Sdab return(send_tncmd(send_wont, "wont", name)); 38246808Sdab } 38346808Sdab 38446808Sdab int 38546808Sdab send_tncmd(func, cmd, name) 38646808Sdab void (*func)(); 38746808Sdab char *cmd, *name; 38846808Sdab { 38946808Sdab char **cpp; 39046808Sdab extern char *telopts[]; 39146808Sdab 39246808Sdab if (isprefix(name, "help") || isprefix(name, "?")) { 39346808Sdab register int col, len; 39446808Sdab 39546808Sdab printf("Usage: send %s <option>\n", cmd); 39646808Sdab printf("Valid options are:\n\t"); 39746808Sdab 39846808Sdab col = 8; 39946808Sdab for (cpp = telopts; *cpp; cpp++) { 40046808Sdab len = strlen(*cpp) + 1; 40146808Sdab if (col + len > 65) { 40246808Sdab printf("\n\t"); 40346808Sdab col = 8; 40432144Sminshall } 40546808Sdab printf(" %s", *cpp); 40646808Sdab col += len; 40732144Sminshall } 40846808Sdab printf("\n"); 40946808Sdab return 0; 41032144Sminshall } 41146808Sdab cpp = (char **)genget(name, telopts, sizeof(char *)); 41246808Sdab if (Ambiguous(cpp)) { 41346808Sdab fprintf(stderr,"'%s': ambiguous argument ('send %s ?' for help).\n", 41446808Sdab name, cmd); 41546808Sdab return 0; 41646808Sdab } 41746808Sdab if (cpp == 0) { 41846808Sdab fprintf(stderr, "'%s': unknown argument ('send %s ?' for help).\n", 41946808Sdab name, cmd); 42046808Sdab return 0; 42146808Sdab } 42246808Sdab if (!connected) { 42346808Sdab printf("?Need to be connected first.\n"); 42446808Sdab return 0; 42546808Sdab } 42646808Sdab (*func)(cpp - telopts, 1); 42746808Sdab return 1; 42832144Sminshall } 42946808Sdab 43046808Sdab static int 43146808Sdab send_help() 43246808Sdab { 43346808Sdab struct sendlist *s; /* pointer to current command */ 43446808Sdab for (s = Sendlist; s->name; s++) { 43546808Sdab if (s->help) 43646808Sdab printf("%-15s %s\n", s->name, s->help); 43746808Sdab } 43846808Sdab return(0); 43946808Sdab } 44032144Sminshall 44132144Sminshall /* 44232144Sminshall * The following are the routines and data structures referred 44332144Sminshall * to by the arguments to the "toggle" command. 44432144Sminshall */ 44532144Sminshall 44646808Sdab static int 44732144Sminshall lclchars() 44832144Sminshall { 44932144Sminshall donelclchars = 1; 45032144Sminshall return 1; 45132144Sminshall } 45232144Sminshall 45346808Sdab static int 45432144Sminshall togdebug() 45532144Sminshall { 45632144Sminshall #ifndef NOT43 45732144Sminshall if (net > 0 && 45832144Sminshall (SetSockOpt(net, SOL_SOCKET, SO_DEBUG, debug)) < 0) { 45932144Sminshall perror("setsockopt (SO_DEBUG)"); 46032144Sminshall } 46132144Sminshall #else /* NOT43 */ 46232144Sminshall if (debug) { 46332144Sminshall if (net > 0 && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 0, 0) < 0) 46432144Sminshall perror("setsockopt (SO_DEBUG)"); 46532144Sminshall } else 46632144Sminshall printf("Cannot turn off socket debugging\n"); 46732144Sminshall #endif /* NOT43 */ 46832144Sminshall return 1; 46932144Sminshall } 47032144Sminshall 47132144Sminshall 47246808Sdab static int 47332144Sminshall togcrlf() 47432144Sminshall { 47532144Sminshall if (crlf) { 47632144Sminshall printf("Will send carriage returns as telnet <CR><LF>.\n"); 47732144Sminshall } else { 47832144Sminshall printf("Will send carriage returns as telnet <CR><NUL>.\n"); 47932144Sminshall } 48032144Sminshall return 1; 48132144Sminshall } 48232144Sminshall 48338909Sborman int binmode; 48432144Sminshall 48546808Sdab static int 48638689Sborman togbinary(val) 48746808Sdab int val; 48832144Sminshall { 48932144Sminshall donebinarytoggle = 1; 49032144Sminshall 49138909Sborman if (val >= 0) { 49238909Sborman binmode = val; 49338909Sborman } else { 49438909Sborman if (my_want_state_is_will(TELOPT_BINARY) && 49538909Sborman my_want_state_is_do(TELOPT_BINARY)) { 49638909Sborman binmode = 1; 49738909Sborman } else if (my_want_state_is_wont(TELOPT_BINARY) && 49838909Sborman my_want_state_is_dont(TELOPT_BINARY)) { 49938909Sborman binmode = 0; 50038909Sborman } 50138909Sborman val = binmode ? 0 : 1; 50238909Sborman } 50338909Sborman 50438909Sborman if (val == 1) { 50538909Sborman if (my_want_state_is_will(TELOPT_BINARY) && 50638909Sborman my_want_state_is_do(TELOPT_BINARY)) { 50738689Sborman printf("Already operating in binary mode with remote host.\n"); 50838909Sborman } else { 50938909Sborman printf("Negotiating binary mode with remote host.\n"); 51038909Sborman tel_enter_binary(3); 51138689Sborman } 51238909Sborman } else { 51338909Sborman if (my_want_state_is_wont(TELOPT_BINARY) && 51438909Sborman my_want_state_is_dont(TELOPT_BINARY)) { 51538689Sborman printf("Already in network ascii mode with remote host.\n"); 51638909Sborman } else { 51738909Sborman printf("Negotiating network ascii mode with remote host.\n"); 51838909Sborman tel_leave_binary(3); 51938689Sborman } 52032144Sminshall } 52132144Sminshall return 1; 52232144Sminshall } 52332144Sminshall 52446808Sdab static int 52538909Sborman togrbinary(val) 52646808Sdab int val; 52738909Sborman { 52838909Sborman donebinarytoggle = 1; 52932144Sminshall 53038909Sborman if (val == -1) 53138909Sborman val = my_want_state_is_do(TELOPT_BINARY) ? 0 : 1; 53232144Sminshall 53338909Sborman if (val == 1) { 53438909Sborman if (my_want_state_is_do(TELOPT_BINARY)) { 53538909Sborman printf("Already receiving in binary mode.\n"); 53638909Sborman } else { 53738909Sborman printf("Negotiating binary mode on input.\n"); 53838909Sborman tel_enter_binary(1); 53938909Sborman } 54038909Sborman } else { 54138909Sborman if (my_want_state_is_dont(TELOPT_BINARY)) { 54238909Sborman printf("Already receiving in network ascii mode.\n"); 54338909Sborman } else { 54438909Sborman printf("Negotiating network ascii mode on input.\n"); 54538909Sborman tel_leave_binary(1); 54638909Sborman } 54738909Sborman } 54838909Sborman return 1; 54938909Sborman } 55038909Sborman 55146808Sdab static int 55238909Sborman togxbinary(val) 55346808Sdab int val; 55438909Sborman { 55538909Sborman donebinarytoggle = 1; 55638909Sborman 55738909Sborman if (val == -1) 55838909Sborman val = my_want_state_is_will(TELOPT_BINARY) ? 0 : 1; 55938909Sborman 56038909Sborman if (val == 1) { 56138909Sborman if (my_want_state_is_will(TELOPT_BINARY)) { 56238909Sborman printf("Already transmitting in binary mode.\n"); 56338909Sborman } else { 56438909Sborman printf("Negotiating binary mode on output.\n"); 56538909Sborman tel_enter_binary(2); 56638909Sborman } 56738909Sborman } else { 56838909Sborman if (my_want_state_is_wont(TELOPT_BINARY)) { 56938909Sborman printf("Already transmitting in network ascii mode.\n"); 57038909Sborman } else { 57138909Sborman printf("Negotiating network ascii mode on output.\n"); 57238909Sborman tel_leave_binary(2); 57338909Sborman } 57438909Sborman } 57538909Sborman return 1; 57638909Sborman } 57738909Sborman 57838909Sborman 57956642Sralph static int togglehelp P((void)); 58047609Sdab #if defined(AUTHENTICATE) 58147609Sdab extern int auth_togdebug P((int)); 58247609Sdab #endif 58347609Sdab #if defined(ENCRYPT) 58447609Sdab extern int EncryptAutoEnc P((int)); 58547609Sdab extern int EncryptAutoDec P((int)); 58647609Sdab extern int EncryptDebug P((int)); 58747609Sdab extern int EncryptVerbose P((int)); 58847609Sdab #endif 58932144Sminshall 59032144Sminshall struct togglelist { 59132144Sminshall char *name; /* name of toggle */ 59232144Sminshall char *help; /* help message */ 59332144Sminshall int (*handler)(); /* routine to do actual setting */ 59432144Sminshall int *variable; 59532144Sminshall char *actionexplanation; 59632144Sminshall }; 59732144Sminshall 59832144Sminshall static struct togglelist Togglelist[] = { 59932144Sminshall { "autoflush", 60038689Sborman "flushing of output when sending interrupt characters", 60132144Sminshall 0, 60238689Sborman &autoflush, 60338689Sborman "flush output when sending interrupt characters" }, 60432144Sminshall { "autosynch", 60538689Sborman "automatic sending of interrupt characters in urgent mode", 60632144Sminshall 0, 60738689Sborman &autosynch, 60838689Sborman "send interrupt characters in urgent mode" }, 60947609Sdab #if defined(AUTHENTICATE) 61047609Sdab { "autologin", 61147609Sdab "automatic sending of login and/or authentication info", 61247609Sdab 0, 61347609Sdab &autologin, 61447609Sdab "send login name and/or authentication information" }, 61547609Sdab { "authdebug", 61647609Sdab "Toggle authentication debugging", 61747609Sdab auth_togdebug, 61847609Sdab 0, 61947609Sdab "print authentication debugging information" }, 62047609Sdab #endif 62147609Sdab #if defined(ENCRYPT) 62247609Sdab { "autoencrypt", 62347609Sdab "automatic encryption of data stream", 62447609Sdab EncryptAutoEnc, 62547609Sdab 0, 62647609Sdab "automatically encrypt output" }, 62747609Sdab { "autodecrypt", 62847609Sdab "automatic decryption of data stream", 62947609Sdab EncryptAutoDec, 63047609Sdab 0, 63147609Sdab "automatically decrypt input" }, 63247609Sdab { "verbose_encrypt", 63347609Sdab "Toggle verbose encryption output", 63447609Sdab EncryptVerbose, 63547609Sdab 0, 63647609Sdab "print verbose encryption output" }, 63747609Sdab { "encdebug", 63847609Sdab "Toggle encryption debugging", 63947609Sdab EncryptDebug, 64047609Sdab 0, 64147609Sdab "print encryption debugging information" }, 64247609Sdab #endif 64347609Sdab { "skiprc", 64447609Sdab "don't read ~/.telnetrc file", 64547609Sdab 0, 64647609Sdab &skiprc, 64747609Sdab "read ~/.telnetrc file" }, 64832144Sminshall { "binary", 64938689Sborman "sending and receiving of binary data", 65032144Sminshall togbinary, 65138689Sborman 0, 65238689Sborman 0 }, 65338909Sborman { "inbinary", 65438909Sborman "receiving of binary data", 65538909Sborman togrbinary, 65638909Sborman 0, 65738909Sborman 0 }, 65838909Sborman { "outbinary", 65938909Sborman "sending of binary data", 66038909Sborman togxbinary, 66138909Sborman 0, 66238909Sborman 0 }, 66332144Sminshall { "crlf", 66438689Sborman "sending carriage returns as telnet <CR><LF>", 66532144Sminshall togcrlf, 66638689Sborman &crlf, 66738689Sborman 0 }, 66832144Sminshall { "crmod", 66938689Sborman "mapping of received carriage returns", 67032144Sminshall 0, 67138689Sborman &crmod, 67238689Sborman "map carriage return on output" }, 67332144Sminshall { "localchars", 67438689Sborman "local recognition of certain control characters", 67532144Sminshall lclchars, 67638689Sborman &localchars, 67738689Sborman "recognize certain control characters" }, 67838689Sborman { " ", "", 0 }, /* empty line */ 67938208Sminshall #if defined(unix) && defined(TN3270) 68038920Sminshall { "apitrace", 68138920Sminshall "(debugging) toggle tracing of API transactions", 68238920Sminshall 0, 68338920Sminshall &apitrace, 68438920Sminshall "trace API transactions" }, 68538208Sminshall { "cursesdata", 68638208Sminshall "(debugging) toggle printing of hexadecimal curses data", 68738208Sminshall 0, 68838689Sborman &cursesdata, 68938689Sborman "print hexadecimal representation of curses data" }, 69038208Sminshall #endif /* defined(unix) && defined(TN3270) */ 69132144Sminshall { "debug", 69238689Sborman "debugging", 69332144Sminshall togdebug, 69438689Sborman &debug, 69538689Sborman "turn on socket level debugging" }, 69632144Sminshall { "netdata", 69738689Sborman "printing of hexadecimal network data (debugging)", 69832144Sminshall 0, 69938689Sborman &netdata, 70038689Sborman "print hexadecimal representation of network traffic" }, 70138689Sborman { "prettydump", 70238689Sborman "output of \"netdata\" to user readable format (debugging)", 70338689Sborman 0, 70438689Sborman &prettydump, 70538689Sborman "print user readable output for \"netdata\"" }, 70632144Sminshall { "options", 70738689Sborman "viewing of options processing (debugging)", 70832144Sminshall 0, 70938689Sborman &showoptions, 71038689Sborman "show option processing" }, 71138208Sminshall #if defined(unix) 71238208Sminshall { "termdata", 71338208Sminshall "(debugging) toggle printing of hexadecimal terminal data", 71438208Sminshall 0, 71538689Sborman &termdata, 71638689Sborman "print hexadecimal representation of terminal traffic" }, 71738208Sminshall #endif /* defined(unix) */ 71832144Sminshall { "?", 71938689Sborman 0, 72038689Sborman togglehelp }, 72132144Sminshall { "help", 72238689Sborman 0, 72338689Sborman togglehelp }, 72432144Sminshall { 0 } 72532144Sminshall }; 72632144Sminshall 72746808Sdab static int 72832144Sminshall togglehelp() 72932144Sminshall { 73032144Sminshall struct togglelist *c; 73132144Sminshall 73232144Sminshall for (c = Togglelist; c->name; c++) { 73338689Sborman if (c->help) { 73438689Sborman if (*c->help) 73538689Sborman printf("%-15s toggle %s\n", c->name, c->help); 73638689Sborman else 73738689Sborman printf("\n"); 73832144Sminshall } 73932144Sminshall } 74038689Sborman printf("\n"); 74138689Sborman printf("%-15s %s\n", "?", "display help information"); 74232144Sminshall return 0; 74332144Sminshall } 74432144Sminshall 74546808Sdab static void 74638689Sborman settogglehelp(set) 74746808Sdab int set; 74838689Sborman { 74938689Sborman struct togglelist *c; 75038689Sborman 75138689Sborman for (c = Togglelist; c->name; c++) { 75238689Sborman if (c->help) { 75338689Sborman if (*c->help) 75438689Sborman printf("%-15s %s %s\n", c->name, set ? "enable" : "disable", 75538689Sborman c->help); 75638689Sborman else 75738689Sborman printf("\n"); 75838689Sborman } 75938689Sborman } 76038689Sborman } 76138689Sborman 76246808Sdab #define GETTOGGLE(name) (struct togglelist *) \ 76346808Sdab genget(name, (char **) Togglelist, sizeof(struct togglelist)) 76432144Sminshall 76546808Sdab static int 76632144Sminshall toggle(argc, argv) 76746808Sdab int argc; 76846808Sdab char *argv[]; 76932144Sminshall { 77032144Sminshall int retval = 1; 77132144Sminshall char *name; 77232144Sminshall struct togglelist *c; 77332144Sminshall 77432144Sminshall if (argc < 2) { 77532144Sminshall fprintf(stderr, 77632144Sminshall "Need an argument to 'toggle' command. 'toggle ?' for help.\n"); 77732144Sminshall return 0; 77832144Sminshall } 77932144Sminshall argc--; 78032144Sminshall argv++; 78132144Sminshall while (argc--) { 78232144Sminshall name = *argv++; 78346808Sdab c = GETTOGGLE(name); 78432144Sminshall if (Ambiguous(c)) { 78532144Sminshall fprintf(stderr, "'%s': ambiguous argument ('toggle ?' for help).\n", 78632144Sminshall name); 78732144Sminshall return 0; 78832144Sminshall } else if (c == 0) { 78932144Sminshall fprintf(stderr, "'%s': unknown argument ('toggle ?' for help).\n", 79032144Sminshall name); 79132144Sminshall return 0; 79232144Sminshall } else { 79332144Sminshall if (c->variable) { 79432144Sminshall *c->variable = !*c->variable; /* invert it */ 79532144Sminshall if (c->actionexplanation) { 79632144Sminshall printf("%s %s.\n", *c->variable? "Will" : "Won't", 79732144Sminshall c->actionexplanation); 79832144Sminshall } 79932144Sminshall } 80032144Sminshall if (c->handler) { 80138689Sborman retval &= (*c->handler)(-1); 80232144Sminshall } 80332144Sminshall } 80432144Sminshall } 80532144Sminshall return retval; 80632144Sminshall } 80732144Sminshall 80832144Sminshall /* 80932144Sminshall * The following perform the "set" command. 81032144Sminshall */ 81132144Sminshall 81238689Sborman #ifdef USE_TERMIO 81338689Sborman struct termio new_tc = { 0 }; 81438689Sborman #endif 81538689Sborman 81632144Sminshall struct setlist { 81732144Sminshall char *name; /* name */ 81832144Sminshall char *help; /* help information */ 81938689Sborman void (*handler)(); 82040245Sborman cc_t *charp; /* where it is located at */ 82132144Sminshall }; 82232144Sminshall 82332144Sminshall static struct setlist Setlist[] = { 82444361Sborman #ifdef KLUDGELINEMODE 82538689Sborman { "echo", "character to toggle local echoing on/off", 0, &echoc }, 82644361Sborman #endif 82738689Sborman { "escape", "character to escape back to telnet command mode", 0, &escape }, 82846808Sdab { "rlogin", "rlogin escape character", 0, &rlogin }, 82945233Sborman { "tracefile", "file to write trace information to", SetNetTrace, (cc_t *)NetTraceFile}, 83032144Sminshall { " ", "" }, 83138689Sborman { " ", "The following need 'localchars' to be toggled true", 0, 0 }, 83245233Sborman { "flushoutput", "character to cause an Abort Output", 0, termFlushCharp }, 83338689Sborman { "interrupt", "character to cause an Interrupt Process", 0, termIntCharp }, 83438689Sborman { "quit", "character to cause an Abort process", 0, termQuitCharp }, 83538689Sborman { "eof", "character to cause an EOF ", 0, termEofCharp }, 83638689Sborman { " ", "" }, 83738689Sborman { " ", "The following are for local editing in linemode", 0, 0 }, 83838689Sborman { "erase", "character to use to erase a character", 0, termEraseCharp }, 83938689Sborman { "kill", "character to use to erase a line", 0, termKillCharp }, 84038689Sborman { "lnext", "character to use for literal next", 0, termLiteralNextCharp }, 84144361Sborman { "susp", "character to cause a Suspend Process", 0, termSuspCharp }, 84238689Sborman { "reprint", "character to use for line reprint", 0, termRprntCharp }, 84338689Sborman { "worderase", "character to use to erase a word", 0, termWerasCharp }, 84438689Sborman { "start", "character to use for XON", 0, termStartCharp }, 84544361Sborman { "stop", "character to use for XOFF", 0, termStopCharp }, 84644361Sborman { "forw1", "alternate end of line character", 0, termForw1Charp }, 84744361Sborman { "forw2", "alternate end of line character", 0, termForw2Charp }, 84845233Sborman { "ayt", "alternate AYT character", 0, termAytCharp }, 84932144Sminshall { 0 } 85032144Sminshall }; 85132144Sminshall 85245233Sborman #if defined(CRAY) && !defined(__STDC__) 85345233Sborman /* Work around compiler bug in pcc 4.1.5 */ 85446808Sdab void 85538689Sborman _setlist_init() 85638689Sborman { 85744361Sborman #ifndef KLUDGELINEMODE 85846808Sdab #define N 5 85944361Sborman #else 86046808Sdab #define N 6 86144361Sborman #endif 86244361Sborman Setlist[N+0].charp = &termFlushChar; 86344361Sborman Setlist[N+1].charp = &termIntChar; 86444361Sborman Setlist[N+2].charp = &termQuitChar; 86544361Sborman Setlist[N+3].charp = &termEofChar; 86644361Sborman Setlist[N+6].charp = &termEraseChar; 86744361Sborman Setlist[N+7].charp = &termKillChar; 86844361Sborman Setlist[N+8].charp = &termLiteralNextChar; 86944361Sborman Setlist[N+9].charp = &termSuspChar; 87044361Sborman Setlist[N+10].charp = &termRprntChar; 87144361Sborman Setlist[N+11].charp = &termWerasChar; 87244361Sborman Setlist[N+12].charp = &termStartChar; 87344361Sborman Setlist[N+13].charp = &termStopChar; 87444361Sborman Setlist[N+14].charp = &termForw1Char; 87544361Sborman Setlist[N+15].charp = &termForw2Char; 87645233Sborman Setlist[N+16].charp = &termAytChar; 87744361Sborman #undef N 87838689Sborman } 87945233Sborman #endif /* defined(CRAY) && !defined(__STDC__) */ 88038689Sborman 88146808Sdab static struct setlist * 88232144Sminshall getset(name) 88346808Sdab char *name; 88432144Sminshall { 88546808Sdab return (struct setlist *) 88646808Sdab genget(name, (char **) Setlist, sizeof(struct setlist)); 88732144Sminshall } 88832144Sminshall 88946808Sdab void 89044361Sborman set_escape_char(s) 89146808Sdab char *s; 89244361Sborman { 89346808Sdab if (rlogin != _POSIX_VDISABLE) { 89446808Sdab rlogin = (s && *s) ? special(s) : _POSIX_VDISABLE; 89546808Sdab printf("Telnet rlogin escape character is '%s'.\n", 89646808Sdab control(rlogin)); 89746808Sdab } else { 89846808Sdab escape = (s && *s) ? special(s) : _POSIX_VDISABLE; 89946808Sdab printf("Telnet escape character is '%s'.\n", control(escape)); 90046808Sdab } 90144361Sborman } 90244361Sborman 90346808Sdab static int 90432144Sminshall setcmd(argc, argv) 90546808Sdab int argc; 90646808Sdab char *argv[]; 90732144Sminshall { 90832144Sminshall int value; 90932144Sminshall struct setlist *ct; 91038689Sborman struct togglelist *c; 91132144Sminshall 91238689Sborman if (argc < 2 || argc > 3) { 91338689Sborman printf("Format is 'set Name Value'\n'set ?' for help.\n"); 91432144Sminshall return 0; 91532144Sminshall } 91646808Sdab if ((argc == 2) && (isprefix(argv[1], "?") || isprefix(argv[1], "help"))) { 91738689Sborman for (ct = Setlist; ct->name; ct++) 91838689Sborman printf("%-15s %s\n", ct->name, ct->help); 91938689Sborman printf("\n"); 92038689Sborman settogglehelp(1); 92138689Sborman printf("%-15s %s\n", "?", "display help information"); 92238689Sborman return 0; 92338689Sborman } 92432144Sminshall 92532144Sminshall ct = getset(argv[1]); 92632144Sminshall if (ct == 0) { 92746808Sdab c = GETTOGGLE(argv[1]); 92838689Sborman if (c == 0) { 92938689Sborman fprintf(stderr, "'%s': unknown argument ('set ?' for help).\n", 93032144Sminshall argv[1]); 93138689Sborman return 0; 93238689Sborman } else if (Ambiguous(c)) { 93338689Sborman fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n", 93438689Sborman argv[1]); 93538689Sborman return 0; 93638689Sborman } 93738689Sborman if (c->variable) { 93838689Sborman if ((argc == 2) || (strcmp("on", argv[2]) == 0)) 93938689Sborman *c->variable = 1; 94038689Sborman else if (strcmp("off", argv[2]) == 0) 94138689Sborman *c->variable = 0; 94238689Sborman else { 94338689Sborman printf("Format is 'set togglename [on|off]'\n'set ?' for help.\n"); 94438689Sborman return 0; 94538689Sborman } 94638689Sborman if (c->actionexplanation) { 94738689Sborman printf("%s %s.\n", *c->variable? "Will" : "Won't", 94838689Sborman c->actionexplanation); 94938689Sborman } 95038689Sborman } 95138689Sborman if (c->handler) 95238689Sborman (*c->handler)(1); 95338689Sborman } else if (argc != 3) { 95438689Sborman printf("Format is 'set Name Value'\n'set ?' for help.\n"); 95532144Sminshall return 0; 95632144Sminshall } else if (Ambiguous(ct)) { 95732144Sminshall fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n", 95832144Sminshall argv[1]); 95932144Sminshall return 0; 96038689Sborman } else if (ct->handler) { 96138689Sborman (*ct->handler)(argv[2]); 96244361Sborman printf("%s set to \"%s\".\n", ct->name, (char *)ct->charp); 96332144Sminshall } else { 96432144Sminshall if (strcmp("off", argv[2])) { 96532144Sminshall value = special(argv[2]); 96632144Sminshall } else { 96745233Sborman value = _POSIX_VDISABLE; 96832144Sminshall } 96940245Sborman *(ct->charp) = (cc_t)value; 97032144Sminshall printf("%s character is '%s'.\n", ct->name, control(*(ct->charp))); 97132144Sminshall } 97238689Sborman slc_check(); 97332144Sminshall return 1; 97432144Sminshall } 97538689Sborman 97646808Sdab static int 97738689Sborman unsetcmd(argc, argv) 97846808Sdab int argc; 97946808Sdab char *argv[]; 98038689Sborman { 98138689Sborman struct setlist *ct; 98238689Sborman struct togglelist *c; 98338689Sborman register char *name; 98438689Sborman 98538689Sborman if (argc < 2) { 98638689Sborman fprintf(stderr, 98738689Sborman "Need an argument to 'unset' command. 'unset ?' for help.\n"); 98838689Sborman return 0; 98938689Sborman } 99046808Sdab if (isprefix(argv[1], "?") || isprefix(argv[1], "help")) { 99138689Sborman for (ct = Setlist; ct->name; ct++) 99238689Sborman printf("%-15s %s\n", ct->name, ct->help); 99338689Sborman printf("\n"); 99438689Sborman settogglehelp(0); 99538689Sborman printf("%-15s %s\n", "?", "display help information"); 99638689Sborman return 0; 99738689Sborman } 99838689Sborman 99938689Sborman argc--; 100038689Sborman argv++; 100138689Sborman while (argc--) { 100238689Sborman name = *argv++; 100338689Sborman ct = getset(name); 100438689Sborman if (ct == 0) { 100546808Sdab c = GETTOGGLE(name); 100638689Sborman if (c == 0) { 100738689Sborman fprintf(stderr, "'%s': unknown argument ('unset ?' for help).\n", 100838689Sborman name); 100938689Sborman return 0; 101038689Sborman } else if (Ambiguous(c)) { 101138689Sborman fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n", 101238689Sborman name); 101338689Sborman return 0; 101438689Sborman } 101538689Sborman if (c->variable) { 101638689Sborman *c->variable = 0; 101738689Sborman if (c->actionexplanation) { 101838689Sborman printf("%s %s.\n", *c->variable? "Will" : "Won't", 101938689Sborman c->actionexplanation); 102038689Sborman } 102138689Sborman } 102238689Sborman if (c->handler) 102338689Sborman (*c->handler)(0); 102438689Sborman } else if (Ambiguous(ct)) { 102538689Sborman fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n", 102638689Sborman name); 102738689Sborman return 0; 102838689Sborman } else if (ct->handler) { 102938689Sborman (*ct->handler)(0); 103044361Sborman printf("%s reset to \"%s\".\n", ct->name, (char *)ct->charp); 103138689Sborman } else { 103245233Sborman *(ct->charp) = _POSIX_VDISABLE; 103338689Sborman printf("%s character is '%s'.\n", ct->name, control(*(ct->charp))); 103438689Sborman } 103538689Sborman } 103638689Sborman return 1; 103738689Sborman } 103832144Sminshall 103932144Sminshall /* 104032144Sminshall * The following are the data structures and routines for the 104132144Sminshall * 'mode' command. 104232144Sminshall */ 104338689Sborman #ifdef KLUDGELINEMODE 104438689Sborman extern int kludgelinemode; 104544361Sborman 104646808Sdab static int 104744361Sborman dokludgemode() 104844361Sborman { 104944361Sborman kludgelinemode = 1; 105044361Sborman send_wont(TELOPT_LINEMODE, 1); 105144361Sborman send_dont(TELOPT_SGA, 1); 105244361Sborman send_dont(TELOPT_ECHO, 1); 105344361Sborman } 105438689Sborman #endif 105532144Sminshall 105646808Sdab static int 105732144Sminshall dolinemode() 105832144Sminshall { 105938689Sborman #ifdef KLUDGELINEMODE 106038689Sborman if (kludgelinemode) 106138689Sborman send_dont(TELOPT_SGA, 1); 106238689Sborman #endif 106338689Sborman send_will(TELOPT_LINEMODE, 1); 106438689Sborman send_dont(TELOPT_ECHO, 1); 106532144Sminshall return 1; 106632144Sminshall } 106732144Sminshall 106846808Sdab static int 106932144Sminshall docharmode() 107032144Sminshall { 107138689Sborman #ifdef KLUDGELINEMODE 107238689Sborman if (kludgelinemode) 107338689Sborman send_do(TELOPT_SGA, 1); 107438689Sborman else 107538689Sborman #endif 107638689Sborman send_wont(TELOPT_LINEMODE, 1); 107738689Sborman send_do(TELOPT_ECHO, 1); 107838689Sborman return 1; 107938689Sborman } 108038689Sborman 108146808Sdab static int 108238689Sborman dolmmode(bit, on) 108346808Sdab int bit, on; 108438689Sborman { 108546808Sdab unsigned char c; 108638689Sborman extern int linemode; 108738689Sborman 108838689Sborman if (my_want_state_is_wont(TELOPT_LINEMODE)) { 108938689Sborman printf("?Need to have LINEMODE option enabled first.\n"); 109038689Sborman printf("'mode ?' for help.\n"); 109138689Sborman return 0; 109232144Sminshall } 109338689Sborman 109438689Sborman if (on) 109538689Sborman c = (linemode | bit); 109638689Sborman else 109738689Sborman c = (linemode & ~bit); 109838689Sborman lm_mode(&c, 1, 1); 109932144Sminshall return 1; 110032144Sminshall } 110132144Sminshall 110246808Sdab int 110346808Sdab setmode(bit) 110446808Sdab { 110546808Sdab return dolmmode(bit, 1); 110646808Sdab } 110746808Sdab 110846808Sdab int 110946808Sdab clearmode(bit) 111046808Sdab { 111146808Sdab return dolmmode(bit, 0); 111246808Sdab } 111346808Sdab 111438689Sborman struct modelist { 111538689Sborman char *name; /* command name */ 111638689Sborman char *help; /* help string */ 111738689Sborman int (*handler)(); /* routine which executes command */ 111838689Sborman int needconnect; /* Do we need to be connected to execute? */ 111938689Sborman int arg1; 112038689Sborman }; 112138689Sborman 112238689Sborman extern int modehelp(); 112338689Sborman 112438689Sborman static struct modelist ModeList[] = { 112538689Sborman { "character", "Disable LINEMODE option", docharmode, 1 }, 112639529Sborman #ifdef KLUDGELINEMODE 112739529Sborman { "", "(or disable obsolete line-by-line mode)", 0 }, 112838689Sborman #endif 112938689Sborman { "line", "Enable LINEMODE option", dolinemode, 1 }, 113039529Sborman #ifdef KLUDGELINEMODE 113139529Sborman { "", "(or enable obsolete line-by-line mode)", 0 }, 113238689Sborman #endif 113338689Sborman { "", "", 0 }, 113438689Sborman { "", "These require the LINEMODE option to be enabled", 0 }, 113538689Sborman { "isig", "Enable signal trapping", setmode, 1, MODE_TRAPSIG }, 113638689Sborman { "+isig", 0, setmode, 1, MODE_TRAPSIG }, 113738689Sborman { "-isig", "Disable signal trapping", clearmode, 1, MODE_TRAPSIG }, 113838689Sborman { "edit", "Enable character editing", setmode, 1, MODE_EDIT }, 113938689Sborman { "+edit", 0, setmode, 1, MODE_EDIT }, 114038689Sborman { "-edit", "Disable character editing", clearmode, 1, MODE_EDIT }, 114144361Sborman { "softtabs", "Enable tab expansion", setmode, 1, MODE_SOFT_TAB }, 114244361Sborman { "+softtabs", 0, setmode, 1, MODE_SOFT_TAB }, 114344361Sborman { "-softtabs", "Disable character editing", clearmode, 1, MODE_SOFT_TAB }, 114444361Sborman { "litecho", "Enable literal character echo", setmode, 1, MODE_LIT_ECHO }, 114544361Sborman { "+litecho", 0, setmode, 1, MODE_LIT_ECHO }, 114644361Sborman { "-litecho", "Disable literal character echo", clearmode, 1, MODE_LIT_ECHO }, 114738689Sborman { "help", 0, modehelp, 0 }, 114844361Sborman #ifdef KLUDGELINEMODE 114944361Sborman { "kludgeline", 0, dokludgemode, 1 }, 115044361Sborman #endif 115144361Sborman { "", "", 0 }, 115238689Sborman { "?", "Print help information", modehelp, 0 }, 115332144Sminshall { 0 }, 115432144Sminshall }; 115532144Sminshall 115632144Sminshall 115746808Sdab int 115838689Sborman modehelp() 115938689Sborman { 116038689Sborman struct modelist *mt; 116138689Sborman 116238689Sborman printf("format is: 'mode Mode', where 'Mode' is one of:\n\n"); 116338689Sborman for (mt = ModeList; mt->name; mt++) { 116438689Sborman if (mt->help) { 116538689Sborman if (*mt->help) 116638689Sborman printf("%-15s %s\n", mt->name, mt->help); 116738689Sborman else 116838689Sborman printf("\n"); 116938689Sborman } 117038689Sborman } 117138689Sborman return 0; 117238689Sborman } 117338689Sborman 117446808Sdab #define GETMODECMD(name) (struct modelist *) \ 117546808Sdab genget(name, (char **) ModeList, sizeof(struct modelist)) 117646808Sdab 117746808Sdab static int 117832144Sminshall modecmd(argc, argv) 117946808Sdab int argc; 118046808Sdab char *argv[]; 118132144Sminshall { 118238689Sborman struct modelist *mt; 118332144Sminshall 118438689Sborman if (argc != 2) { 118538689Sborman printf("'mode' command requires an argument\n"); 118638689Sborman printf("'mode ?' for help.\n"); 118746808Sdab } else if ((mt = GETMODECMD(argv[1])) == 0) { 118832144Sminshall fprintf(stderr, "Unknown mode '%s' ('mode ?' for help).\n", argv[1]); 118932144Sminshall } else if (Ambiguous(mt)) { 119032144Sminshall fprintf(stderr, "Ambiguous mode '%s' ('mode ?' for help).\n", argv[1]); 119138689Sborman } else if (mt->needconnect && !connected) { 119238689Sborman printf("?Need to be connected first.\n"); 119338689Sborman printf("'mode ?' for help.\n"); 119438689Sborman } else if (mt->handler) { 119538689Sborman return (*mt->handler)(mt->arg1); 119632144Sminshall } 119738689Sborman return 0; 119832144Sminshall } 119932144Sminshall 120032144Sminshall /* 120132144Sminshall * The following data structures and routines implement the 120232144Sminshall * "display" command. 120332144Sminshall */ 120432144Sminshall 120546808Sdab static int 120632144Sminshall display(argc, argv) 120746808Sdab int argc; 120846808Sdab char *argv[]; 120932144Sminshall { 121046808Sdab struct togglelist *tl; 121146808Sdab struct setlist *sl; 121246808Sdab 121332144Sminshall #define dotog(tl) if (tl->variable && tl->actionexplanation) { \ 121432144Sminshall if (*tl->variable) { \ 121532144Sminshall printf("will"); \ 121632144Sminshall } else { \ 121732144Sminshall printf("won't"); \ 121832144Sminshall } \ 121932144Sminshall printf(" %s.\n", tl->actionexplanation); \ 122032144Sminshall } 122132144Sminshall 122232144Sminshall #define doset(sl) if (sl->name && *sl->name != ' ') { \ 122338689Sborman if (sl->handler == 0) \ 122438689Sborman printf("%-15s [%s]\n", sl->name, control(*sl->charp)); \ 122538689Sborman else \ 122644361Sborman printf("%-15s \"%s\"\n", sl->name, (char *)sl->charp); \ 122732144Sminshall } 122832144Sminshall 122932144Sminshall if (argc == 1) { 123032144Sminshall for (tl = Togglelist; tl->name; tl++) { 123132144Sminshall dotog(tl); 123232144Sminshall } 123332144Sminshall printf("\n"); 123432144Sminshall for (sl = Setlist; sl->name; sl++) { 123532144Sminshall doset(sl); 123632144Sminshall } 123732144Sminshall } else { 123832144Sminshall int i; 123932144Sminshall 124032144Sminshall for (i = 1; i < argc; i++) { 124132144Sminshall sl = getset(argv[i]); 124246808Sdab tl = GETTOGGLE(argv[i]); 124332144Sminshall if (Ambiguous(sl) || Ambiguous(tl)) { 124432144Sminshall printf("?Ambiguous argument '%s'.\n", argv[i]); 124532144Sminshall return 0; 124632144Sminshall } else if (!sl && !tl) { 124732144Sminshall printf("?Unknown argument '%s'.\n", argv[i]); 124832144Sminshall return 0; 124932144Sminshall } else { 125032144Sminshall if (tl) { 125132144Sminshall dotog(tl); 125232144Sminshall } 125332144Sminshall if (sl) { 125432144Sminshall doset(sl); 125532144Sminshall } 125632144Sminshall } 125732144Sminshall } 125832144Sminshall } 125938689Sborman /*@*/optionstatus(); 126046808Sdab #if defined(ENCRYPT) 126146808Sdab EncryptStatus(); 126246808Sdab #endif 126332144Sminshall return 1; 126432144Sminshall #undef doset 126532144Sminshall #undef dotog 126632144Sminshall } 126732144Sminshall 126832144Sminshall /* 126932144Sminshall * The following are the data structures, and many of the routines, 127032144Sminshall * relating to command processing. 127132144Sminshall */ 127232144Sminshall 127332144Sminshall /* 127432144Sminshall * Set the escape character. 127532144Sminshall */ 127646808Sdab static int 127732144Sminshall setescape(argc, argv) 127832144Sminshall int argc; 127932144Sminshall char *argv[]; 128032144Sminshall { 128132144Sminshall register char *arg; 128232144Sminshall char buf[50]; 128332144Sminshall 128432144Sminshall printf( 128532144Sminshall "Deprecated usage - please use 'set escape%s%s' in the future.\n", 128632144Sminshall (argc > 2)? " ":"", (argc > 2)? argv[1]: ""); 128732144Sminshall if (argc > 2) 128832144Sminshall arg = argv[1]; 128932144Sminshall else { 129032144Sminshall printf("new escape character: "); 129146808Sdab (void) fgets(buf, sizeof(buf), stdin); 129232144Sminshall arg = buf; 129332144Sminshall } 129432144Sminshall if (arg[0] != '\0') 129532144Sminshall escape = arg[0]; 129632144Sminshall if (!In3270) { 129732144Sminshall printf("Escape character is '%s'.\n", control(escape)); 129832144Sminshall } 129934849Sminshall (void) fflush(stdout); 130032144Sminshall return 1; 130132144Sminshall } 130232144Sminshall 130346808Sdab /*VARARGS*/ 130446808Sdab static int 130532144Sminshall togcrmod() 130632144Sminshall { 130732144Sminshall crmod = !crmod; 130832144Sminshall printf("Deprecated usage - please use 'toggle crmod' in the future.\n"); 130932144Sminshall printf("%s map carriage return on output.\n", crmod ? "Will" : "Won't"); 131034849Sminshall (void) fflush(stdout); 131132144Sminshall return 1; 131232144Sminshall } 131332144Sminshall 131446808Sdab /*VARARGS*/ 131546808Sdab int 131632144Sminshall suspend() 131732144Sminshall { 131838689Sborman #ifdef SIGTSTP 131937219Sminshall setcommandmode(); 132037219Sminshall { 132144361Sborman long oldrows, oldcols, newrows, newcols, err; 132237219Sminshall 132344361Sborman err = TerminalWindowSize(&oldrows, &oldcols); 132434849Sminshall (void) kill(0, SIGTSTP); 132544361Sborman err += TerminalWindowSize(&newrows, &newcols); 132644361Sborman if (connected && !err && 132744361Sborman ((oldrows != newrows) || (oldcols != newcols))) { 132837219Sminshall sendnaws(); 132937219Sminshall } 133037219Sminshall } 133137219Sminshall /* reget parameters in case they were changed */ 133237219Sminshall TerminalSaveState(); 133338689Sborman setconnmode(0); 133438689Sborman #else 133538689Sborman printf("Suspend is not supported. Try the '!' command instead\n"); 133638689Sborman #endif 133737219Sminshall return 1; 133832144Sminshall } 133932144Sminshall 134038689Sborman #if !defined(TN3270) 134146808Sdab /*ARGSUSED*/ 134246808Sdab int 134338689Sborman shell(argc, argv) 134446808Sdab int argc; 134546808Sdab char *argv[]; 134638689Sborman { 134738689Sborman setcommandmode(); 134838689Sborman switch(vfork()) { 134938689Sborman case -1: 135038689Sborman perror("Fork failed\n"); 135138689Sborman break; 135238689Sborman 135338689Sborman case 0: 135438689Sborman { 135538689Sborman /* 135638689Sborman * Fire up the shell in the child. 135738689Sborman */ 135846808Sdab register char *shellp, *shellname; 135946808Sdab extern char *rindex(); 136038689Sborman 136146808Sdab shellp = getenv("SHELL"); 136246808Sdab if (shellp == NULL) 136346808Sdab shellp = "/bin/sh"; 136446808Sdab if ((shellname = rindex(shellp, '/')) == 0) 136546808Sdab shellname = shellp; 136638689Sborman else 136738689Sborman shellname++; 136838689Sborman if (argc > 1) 136946808Sdab execl(shellp, shellname, "-c", &saveline[1], 0); 137038689Sborman else 137146808Sdab execl(shellp, shellname, 0); 137238689Sborman perror("Execl"); 137338689Sborman _exit(1); 137438689Sborman } 137538689Sborman default: 137644361Sborman (void)wait((int *)0); /* Wait for the shell to complete */ 137738689Sborman } 137846808Sdab return 1; 137938689Sborman } 138038689Sborman #endif /* !defined(TN3270) */ 138138689Sborman 138246808Sdab /*VARARGS*/ 138346808Sdab static 138432144Sminshall bye(argc, argv) 138546808Sdab int argc; /* Number of arguments */ 138646808Sdab char *argv[]; /* arguments */ 138732144Sminshall { 138846808Sdab extern int resettermname; 138946808Sdab 139032144Sminshall if (connected) { 139134849Sminshall (void) shutdown(net, 2); 139232144Sminshall printf("Connection closed.\n"); 139334849Sminshall (void) NetClose(net); 139432144Sminshall connected = 0; 139546808Sdab resettermname = 1; 139646808Sdab #if defined(AUTHENTICATE) || defined(ENCRYPT) 139746808Sdab auth_encrypt_connect(connected); 139846808Sdab #endif 139932144Sminshall /* reset options */ 140032144Sminshall tninit(); 140132144Sminshall #if defined(TN3270) 140232144Sminshall SetIn3270(); /* Get out of 3270 mode */ 140332144Sminshall #endif /* defined(TN3270) */ 140432144Sminshall } 140532144Sminshall if ((argc != 2) || (strcmp(argv[1], "fromquit") != 0)) { 140632144Sminshall longjmp(toplevel, 1); 140732144Sminshall /* NOTREACHED */ 140832144Sminshall } 140932144Sminshall return 1; /* Keep lint, etc., happy */ 141032144Sminshall } 141132144Sminshall 141232144Sminshall /*VARARGS*/ 141332144Sminshall quit() 141432144Sminshall { 141532144Sminshall (void) call(bye, "bye", "fromquit", 0); 141632144Sminshall Exit(0); 141744361Sborman /*NOTREACHED*/ 141832144Sminshall } 141946808Sdab 142046808Sdab /*VARARGS*/ 142146808Sdab int 142246808Sdab logout() 142346808Sdab { 142446808Sdab send_do(TELOPT_LOGOUT, 1); 142546808Sdab (void) netflush(); 142646808Sdab return 1; 142746808Sdab } 142846808Sdab 142938689Sborman 143038689Sborman /* 143138689Sborman * The SLC command. 143238689Sborman */ 143332144Sminshall 143438689Sborman struct slclist { 143538689Sborman char *name; 143638689Sborman char *help; 143746808Sdab void (*handler)(); 143838689Sborman int arg; 143938689Sborman }; 144038689Sborman 144156642Sralph static void slc_help(); 144238689Sborman 144338689Sborman struct slclist SlcList[] = { 144438689Sborman { "export", "Use local special character definitions", 144538689Sborman slc_mode_export, 0 }, 144638689Sborman { "import", "Use remote special character definitions", 144738689Sborman slc_mode_import, 1 }, 144838689Sborman { "check", "Verify remote special character definitions", 144938689Sborman slc_mode_import, 0 }, 145038689Sborman { "help", 0, slc_help, 0 }, 145138689Sborman { "?", "Print help information", slc_help, 0 }, 145238689Sborman { 0 }, 145338689Sborman }; 145438689Sborman 145546808Sdab static void 145638689Sborman slc_help() 145738689Sborman { 145838689Sborman struct slclist *c; 145938689Sborman 146038689Sborman for (c = SlcList; c->name; c++) { 146138689Sborman if (c->help) { 146238689Sborman if (*c->help) 146338689Sborman printf("%-15s %s\n", c->name, c->help); 146438689Sborman else 146538689Sborman printf("\n"); 146638689Sborman } 146738689Sborman } 146838689Sborman } 146938689Sborman 147046808Sdab static struct slclist * 147138689Sborman getslc(name) 147246808Sdab char *name; 147338689Sborman { 147446808Sdab return (struct slclist *) 147546808Sdab genget(name, (char **) SlcList, sizeof(struct slclist)); 147638689Sborman } 147738689Sborman 147846808Sdab static 147938689Sborman slccmd(argc, argv) 148046808Sdab int argc; 148146808Sdab char *argv[]; 148238689Sborman { 148338689Sborman struct slclist *c; 148438689Sborman 148538689Sborman if (argc != 2) { 148638689Sborman fprintf(stderr, 148738689Sborman "Need an argument to 'slc' command. 'slc ?' for help.\n"); 148838689Sborman return 0; 148938689Sborman } 149038689Sborman c = getslc(argv[1]); 149138689Sborman if (c == 0) { 149238689Sborman fprintf(stderr, "'%s': unknown argument ('slc ?' for help).\n", 149338689Sborman argv[1]); 149438689Sborman return 0; 149538689Sborman } 149638689Sborman if (Ambiguous(c)) { 149738689Sborman fprintf(stderr, "'%s': ambiguous argument ('slc ?' for help).\n", 149838689Sborman argv[1]); 149938689Sborman return 0; 150038689Sborman } 150138689Sborman (*c->handler)(c->arg); 150238689Sborman slcstate(); 150338689Sborman return 1; 150438689Sborman } 150544361Sborman 150644361Sborman /* 150744361Sborman * The ENVIRON command. 150844361Sborman */ 150938689Sborman 151044361Sborman struct envlist { 151144361Sborman char *name; 151244361Sborman char *help; 151346808Sdab void (*handler)(); 151444361Sborman int narg; 151544361Sborman }; 151644361Sborman 151746808Sdab extern struct env_lst * 151846808Sdab env_define P((unsigned char *, unsigned char *)); 151946808Sdab extern void 152046808Sdab env_undefine P((unsigned char *)), 152146808Sdab env_export P((unsigned char *)), 152246808Sdab env_unexport P((unsigned char *)), 152346808Sdab env_send P((unsigned char *)), 152456642Sralph env_list P((void)); 152556642Sralph static void 152646808Sdab env_help P((void)); 152744361Sborman 152844361Sborman struct envlist EnvList[] = { 152944361Sborman { "define", "Define an environment variable", 153046808Sdab (void (*)())env_define, 2 }, 153144361Sborman { "undefine", "Undefine an environment variable", 153244361Sborman env_undefine, 1 }, 153344361Sborman { "export", "Mark an environment variable for automatic export", 153444361Sborman env_export, 1 }, 153546808Sdab { "unexport", "Don't mark an environment variable for automatic export", 153644361Sborman env_unexport, 1 }, 153745233Sborman { "send", "Send an environment variable", env_send, 1 }, 153844361Sborman { "list", "List the current environment variables", 153944361Sborman env_list, 0 }, 154044361Sborman { "help", 0, env_help, 0 }, 154144361Sborman { "?", "Print help information", env_help, 0 }, 154244361Sborman { 0 }, 154344361Sborman }; 154444361Sborman 154546808Sdab static void 154644361Sborman env_help() 154744361Sborman { 154844361Sborman struct envlist *c; 154944361Sborman 155044361Sborman for (c = EnvList; c->name; c++) { 155144361Sborman if (c->help) { 155244361Sborman if (*c->help) 155344361Sborman printf("%-15s %s\n", c->name, c->help); 155444361Sborman else 155544361Sborman printf("\n"); 155644361Sborman } 155744361Sborman } 155844361Sborman } 155944361Sborman 156046808Sdab static struct envlist * 156144361Sborman getenvcmd(name) 156246808Sdab char *name; 156344361Sborman { 156446808Sdab return (struct envlist *) 156546808Sdab genget(name, (char **) EnvList, sizeof(struct envlist)); 156644361Sborman } 156744361Sborman 156844361Sborman env_cmd(argc, argv) 156946808Sdab int argc; 157046808Sdab char *argv[]; 157144361Sborman { 157244361Sborman struct envlist *c; 157344361Sborman 157444361Sborman if (argc < 2) { 157544361Sborman fprintf(stderr, 157644361Sborman "Need an argument to 'environ' command. 'environ ?' for help.\n"); 157744361Sborman return 0; 157844361Sborman } 157944361Sborman c = getenvcmd(argv[1]); 158044361Sborman if (c == 0) { 158144361Sborman fprintf(stderr, "'%s': unknown argument ('environ ?' for help).\n", 158244361Sborman argv[1]); 158344361Sborman return 0; 158444361Sborman } 158544361Sborman if (Ambiguous(c)) { 158644361Sborman fprintf(stderr, "'%s': ambiguous argument ('environ ?' for help).\n", 158744361Sborman argv[1]); 158844361Sborman return 0; 158944361Sborman } 159044361Sborman if (c->narg + 2 != argc) { 159144361Sborman fprintf(stderr, 159244361Sborman "Need %s%d argument%s to 'environ %s' command. 'environ ?' for help.\n", 159344361Sborman c->narg < argc + 2 ? "only " : "", 159444361Sborman c->narg, c->narg == 1 ? "" : "s", c->name); 159544361Sborman return 0; 159644361Sborman } 159746808Sdab (*c->handler)(argv[2], argv[3]); 159844361Sborman return 1; 159944361Sborman } 160044361Sborman 160144361Sborman struct env_lst { 160244361Sborman struct env_lst *next; /* pointer to next structure */ 160344361Sborman struct env_lst *prev; /* pointer to next structure */ 160446808Sdab unsigned char *var; /* pointer to variable name */ 160546808Sdab unsigned char *value; /* pointer to varialbe value */ 160644361Sborman int export; /* 1 -> export with default list of variables */ 160744361Sborman }; 160844361Sborman 160944361Sborman struct env_lst envlisthead; 161044361Sborman 161146808Sdab struct env_lst * 161244361Sborman env_find(var) 161346808Sdab unsigned char *var; 161444361Sborman { 161544361Sborman register struct env_lst *ep; 161644361Sborman 161744361Sborman for (ep = envlisthead.next; ep; ep = ep->next) { 161846808Sdab if (strcmp((char *)ep->var, (char *)var) == 0) 161944361Sborman return(ep); 162044361Sborman } 162144361Sborman return(NULL); 162244361Sborman } 162344361Sborman 162446808Sdab void 162544361Sborman env_init() 162644361Sborman { 162746808Sdab extern char **environ; 162844361Sborman register char **epp, *cp; 162944361Sborman register struct env_lst *ep; 163046808Sdab extern char *index(); 163144361Sborman 163244361Sborman for (epp = environ; *epp; epp++) { 163344361Sborman if (cp = index(*epp, '=')) { 163444361Sborman *cp = '\0'; 163546808Sdab ep = env_define((unsigned char *)*epp, 163646808Sdab (unsigned char *)cp+1); 163744361Sborman ep->export = 0; 163844361Sborman *cp = '='; 163944361Sborman } 164044361Sborman } 164144361Sborman /* 164244361Sborman * Special case for DISPLAY variable. If it is ":0.0" or 164344361Sborman * "unix:0.0", we have to get rid of "unix" and insert our 164444361Sborman * hostname. 164544361Sborman */ 164646808Sdab if ((ep = env_find("DISPLAY")) 164746808Sdab && ((*ep->value == ':') 164846808Sdab || (strncmp((char *)ep->value, "unix:", 5) == 0))) { 164944361Sborman char hbuf[256+1]; 165046808Sdab char *cp2 = index((char *)ep->value, ':'); 165144361Sborman 165244361Sborman gethostname(hbuf, 256); 165344361Sborman hbuf[256] = '\0'; 165444361Sborman cp = (char *)malloc(strlen(hbuf) + strlen(cp2) + 1); 165546808Sdab sprintf((char *)cp, "%s%s", hbuf, cp2); 165644361Sborman free(ep->value); 165746808Sdab ep->value = (unsigned char *)cp; 165844361Sborman } 165944361Sborman /* 166044361Sborman * If USER is not defined, but LOGNAME is, then add 166145233Sborman * USER with the value from LOGNAME. By default, we 166245233Sborman * don't export the USER variable. 166344361Sborman */ 166445233Sborman if ((env_find("USER") == NULL) && (ep = env_find("LOGNAME"))) { 166546808Sdab env_define((unsigned char *)"USER", ep->value); 166646808Sdab env_unexport((unsigned char *)"USER"); 166745233Sborman } 166846808Sdab env_export((unsigned char *)"DISPLAY"); 166946808Sdab env_export((unsigned char *)"PRINTER"); 167044361Sborman } 167144361Sborman 167246808Sdab struct env_lst * 167344361Sborman env_define(var, value) 167446808Sdab unsigned char *var, *value; 167544361Sborman { 167644361Sborman register struct env_lst *ep; 167744361Sborman 167844361Sborman if (ep = env_find(var)) { 167944361Sborman if (ep->var) 168044361Sborman free(ep->var); 168144361Sborman if (ep->value) 168244361Sborman free(ep->value); 168344361Sborman } else { 168444361Sborman ep = (struct env_lst *)malloc(sizeof(struct env_lst)); 168544361Sborman ep->next = envlisthead.next; 168644361Sborman envlisthead.next = ep; 168744361Sborman ep->prev = &envlisthead; 168844361Sborman if (ep->next) 168944361Sborman ep->next->prev = ep; 169044361Sborman } 169145009Skarels ep->export = 1; 169246808Sdab ep->var = (unsigned char *)strdup((char *)var); 169346808Sdab ep->value = (unsigned char *)strdup((char *)value); 169444361Sborman return(ep); 169544361Sborman } 169644361Sborman 169746808Sdab void 169844361Sborman env_undefine(var) 169946808Sdab unsigned char *var; 170044361Sborman { 170144361Sborman register struct env_lst *ep; 170244361Sborman 170344361Sborman if (ep = env_find(var)) { 170444361Sborman ep->prev->next = ep->next; 170545233Sborman if (ep->next) 170645233Sborman ep->next->prev = ep->prev; 170744361Sborman if (ep->var) 170844361Sborman free(ep->var); 170944361Sborman if (ep->value) 171044361Sborman free(ep->value); 171144361Sborman free(ep); 171244361Sborman } 171344361Sborman } 171444361Sborman 171546808Sdab void 171644361Sborman env_export(var) 171746808Sdab unsigned char *var; 171844361Sborman { 171944361Sborman register struct env_lst *ep; 172044361Sborman 172144361Sborman if (ep = env_find(var)) 172244361Sborman ep->export = 1; 172344361Sborman } 172444361Sborman 172546808Sdab void 172644361Sborman env_unexport(var) 172746808Sdab unsigned char *var; 172844361Sborman { 172944361Sborman register struct env_lst *ep; 173044361Sborman 173144361Sborman if (ep = env_find(var)) 173244361Sborman ep->export = 0; 173344361Sborman } 173444361Sborman 173546808Sdab void 173645233Sborman env_send(var) 173746808Sdab unsigned char *var; 173845233Sborman { 173945233Sborman register struct env_lst *ep; 174045233Sborman 174145233Sborman if (my_state_is_wont(TELOPT_ENVIRON)) { 174245233Sborman fprintf(stderr, 174345233Sborman "Cannot send '%s': Telnet ENVIRON option not enabled\n", 174445233Sborman var); 174545233Sborman return; 174645233Sborman } 174745233Sborman ep = env_find(var); 174845233Sborman if (ep == 0) { 174945233Sborman fprintf(stderr, "Cannot send '%s': variable not defined\n", 175045233Sborman var); 175145233Sborman return; 175245233Sborman } 175345233Sborman env_opt_start_info(); 175445233Sborman env_opt_add(ep->var); 175545233Sborman env_opt_end(0); 175645233Sborman } 175745233Sborman 175846808Sdab void 175944361Sborman env_list() 176044361Sborman { 176144361Sborman register struct env_lst *ep; 176244361Sborman 176344361Sborman for (ep = envlisthead.next; ep; ep = ep->next) { 176444361Sborman printf("%c %-20s %s\n", ep->export ? '*' : ' ', 176544361Sborman ep->var, ep->value); 176644361Sborman } 176744361Sborman } 176844361Sborman 176946808Sdab unsigned char * 177044361Sborman env_default(init) 177146808Sdab int init; 177244361Sborman { 177344361Sborman static struct env_lst *nep = NULL; 177444361Sborman 177544361Sborman if (init) { 177644361Sborman nep = &envlisthead; 177744361Sborman return; 177844361Sborman } 177944361Sborman if (nep) { 178044361Sborman while (nep = nep->next) { 178144361Sborman if (nep->export) 178244361Sborman return(nep->var); 178344361Sborman } 178444361Sborman } 178544361Sborman return(NULL); 178644361Sborman } 178744361Sborman 178846808Sdab unsigned char * 178944361Sborman env_getvalue(var) 179046808Sdab unsigned char *var; 179144361Sborman { 179244361Sborman register struct env_lst *ep; 179344361Sborman 179444361Sborman if (ep = env_find(var)) 179544361Sborman return(ep->value); 179644361Sborman return(NULL); 179744361Sborman } 179844361Sborman 179946808Sdab #if defined(AUTHENTICATE) 180046808Sdab /* 180146808Sdab * The AUTHENTICATE command. 180246808Sdab */ 180346808Sdab 180446808Sdab struct authlist { 180546808Sdab char *name; 180646808Sdab char *help; 180746808Sdab int (*handler)(); 180846808Sdab int narg; 180946808Sdab }; 181046808Sdab 181146808Sdab extern int 181246808Sdab auth_enable P((int)), 181346808Sdab auth_disable P((int)), 181456642Sralph auth_status P((void)); 181556642Sralph static int 181646808Sdab auth_help P((void)); 181746808Sdab 181846808Sdab struct authlist AuthList[] = { 181946808Sdab { "status", "Display current status of authentication information", 182046808Sdab auth_status, 0 }, 182146808Sdab { "disable", "Disable an authentication type ('auth disable ?' for more)", 182246808Sdab auth_disable, 1 }, 182346808Sdab { "enable", "Enable an authentication type ('auth enable ?' for more)", 182446808Sdab auth_enable, 1 }, 182546808Sdab { "help", 0, auth_help, 0 }, 182646808Sdab { "?", "Print help information", auth_help, 0 }, 182746808Sdab { 0 }, 182846808Sdab }; 182946808Sdab 183046808Sdab static int 183146808Sdab auth_help() 183244361Sborman { 183346808Sdab struct authlist *c; 183446808Sdab 183546808Sdab for (c = AuthList; c->name; c++) { 183646808Sdab if (c->help) { 183746808Sdab if (*c->help) 183846808Sdab printf("%-15s %s\n", c->name, c->help); 183946808Sdab else 184046808Sdab printf("\n"); 184146808Sdab } 184246808Sdab } 184346808Sdab return 0; 184444361Sborman } 184546808Sdab 184646808Sdab auth_cmd(argc, argv) 184746808Sdab int argc; 184846808Sdab char *argv[]; 184946808Sdab { 185046808Sdab struct authlist *c; 185146808Sdab 185246808Sdab c = (struct authlist *) 185346808Sdab genget(argv[1], (char **) AuthList, sizeof(struct authlist)); 185446808Sdab if (c == 0) { 185546808Sdab fprintf(stderr, "'%s': unknown argument ('auth ?' for help).\n", 185646808Sdab argv[1]); 185746808Sdab return 0; 185846808Sdab } 185946808Sdab if (Ambiguous(c)) { 186046808Sdab fprintf(stderr, "'%s': ambiguous argument ('auth ?' for help).\n", 186146808Sdab argv[1]); 186246808Sdab return 0; 186346808Sdab } 186446808Sdab if (c->narg + 2 != argc) { 186546808Sdab fprintf(stderr, 186646808Sdab "Need %s%d argument%s to 'auth %s' command. 'auth ?' for help.\n", 186746808Sdab c->narg < argc + 2 ? "only " : "", 186846808Sdab c->narg, c->narg == 1 ? "" : "s", c->name); 186946808Sdab return 0; 187046808Sdab } 187146808Sdab return((*c->handler)(argv[2], argv[3])); 187246808Sdab } 187345233Sborman #endif 187444361Sborman 187546808Sdab #if defined(ENCRYPT) 187632144Sminshall /* 187746808Sdab * The ENCRYPT command. 187836274Sminshall */ 187936274Sminshall 188046808Sdab struct encryptlist { 188146808Sdab char *name; 188246808Sdab char *help; 188346808Sdab int (*handler)(); 188446808Sdab int needconnect; 188546808Sdab int minarg; 188646808Sdab int maxarg; 188746808Sdab }; 188846808Sdab 188946808Sdab extern int 189046808Sdab EncryptEnable P((char *, char *)), 189147609Sdab EncryptDisable P((char *, char *)), 189246808Sdab EncryptType P((char *, char *)), 189346808Sdab EncryptStart P((char *)), 189446808Sdab EncryptStartInput P((void)), 189546808Sdab EncryptStartOutput P((void)), 189646808Sdab EncryptStop P((char *)), 189746808Sdab EncryptStopInput P((void)), 189846808Sdab EncryptStopOutput P((void)), 189956642Sralph EncryptStatus P((void)); 190056642Sralph static int 190146808Sdab EncryptHelp P((void)); 190246808Sdab 190346808Sdab struct encryptlist EncryptList[] = { 190446808Sdab { "enable", "Enable encryption. ('encrypt enable ?' for more)", 190546808Sdab EncryptEnable, 1, 1, 2 }, 190647609Sdab { "disable", "Disable encryption. ('encrypt enable ?' for more)", 190747609Sdab EncryptDisable, 0, 1, 2 }, 190846808Sdab { "type", "Set encryptiong type. ('encrypt type ?' for more)", 190946808Sdab EncryptType, 0, 1, 1 }, 191046808Sdab { "start", "Start encryption. ('encrypt start ?' for more)", 191146808Sdab EncryptStart, 1, 0, 1 }, 191246808Sdab { "stop", "Stop encryption. ('encrypt stop ?' for more)", 191346808Sdab EncryptStop, 1, 0, 1 }, 191446808Sdab { "input", "Start encrypting the input stream", 191546808Sdab EncryptStartInput, 1, 0, 0 }, 191646808Sdab { "-input", "Stop encrypting the input stream", 191746808Sdab EncryptStopInput, 1, 0, 0 }, 191846808Sdab { "output", "Start encrypting the output stream", 191946808Sdab EncryptStartOutput, 1, 0, 0 }, 192046808Sdab { "-output", "Stop encrypting the output stream", 192146808Sdab EncryptStopOutput, 1, 0, 0 }, 192246808Sdab 192346808Sdab { "status", "Display current status of authentication information", 192446808Sdab EncryptStatus, 0, 0, 0 }, 192546808Sdab { "help", 0, EncryptHelp, 0, 0, 0 }, 192646808Sdab { "?", "Print help information", EncryptHelp, 0, 0, 0 }, 192746808Sdab { 0 }, 192846808Sdab }; 192946808Sdab 193046808Sdab static int 193146808Sdab EncryptHelp() 193236274Sminshall { 193346808Sdab struct encryptlist *c; 193446808Sdab 193546808Sdab for (c = EncryptList; c->name; c++) { 193646808Sdab if (c->help) { 193746808Sdab if (*c->help) 193846808Sdab printf("%-15s %s\n", c->name, c->help); 193946808Sdab else 194046808Sdab printf("\n"); 194136274Sminshall } 194246808Sdab } 194346808Sdab return 0; 194446808Sdab } 194536274Sminshall 194646808Sdab encrypt_cmd(argc, argv) 194746808Sdab int argc; 194846808Sdab char *argv[]; 194946808Sdab { 195046808Sdab struct encryptlist *c; 195136274Sminshall 195246808Sdab c = (struct encryptlist *) 195346808Sdab genget(argv[1], (char **) EncryptList, sizeof(struct encryptlist)); 195446808Sdab if (c == 0) { 195546808Sdab fprintf(stderr, "'%s': unknown argument ('encrypt ?' for help).\n", 195646808Sdab argv[1]); 195746808Sdab return 0; 195846808Sdab } 195946808Sdab if (Ambiguous(c)) { 196046808Sdab fprintf(stderr, "'%s': ambiguous argument ('encrypt ?' for help).\n", 196146808Sdab argv[1]); 196246808Sdab return 0; 196346808Sdab } 196446808Sdab argc -= 2; 196546808Sdab if (argc < c->minarg || argc > c->maxarg) { 196646808Sdab if (c->minarg == c->maxarg) { 196746808Sdab fprintf(stderr, "Need %s%d argument%s ", 196846808Sdab c->minarg < argc ? "only " : "", c->minarg, 196946808Sdab c->minarg == 1 ? "" : "s"); 197046808Sdab } else { 197146808Sdab fprintf(stderr, "Need %s%d-%d arguments ", 197246808Sdab c->maxarg < argc ? "only " : "", c->minarg, c->maxarg); 197346808Sdab } 197446808Sdab fprintf(stderr, "to 'encrypt %s' command. 'encrypt ?' for help.\n", 197546808Sdab c->name); 197646808Sdab return 0; 197746808Sdab } 197846808Sdab if (c->needconnect && !connected) { 197946808Sdab if (!(argc && (isprefix(argv[2], "help") || isprefix(argv[2], "?")))) { 198046808Sdab printf("?Need to be connected first.\n"); 198146808Sdab return 0; 198246808Sdab } 198346808Sdab } 198446808Sdab return ((*c->handler)(argc > 0 ? argv[2] : 0, 198546808Sdab argc > 1 ? argv[3] : 0, 198646808Sdab argc > 2 ? argv[4] : 0)); 198746808Sdab } 198836274Sminshall #endif 198936274Sminshall 199046808Sdab #if defined(unix) && defined(TN3270) 199146808Sdab static void 199236274Sminshall filestuff(fd) 199346808Sdab int fd; 199436274Sminshall { 199536274Sminshall int res; 199636274Sminshall 199738689Sborman #ifdef F_GETOWN 199838689Sborman setconnmode(0); 199936274Sminshall res = fcntl(fd, F_GETOWN, 0); 200036274Sminshall setcommandmode(); 200136274Sminshall 200236274Sminshall if (res == -1) { 200336274Sminshall perror("fcntl"); 200436274Sminshall return; 200536274Sminshall } 200636274Sminshall printf("\tOwner is %d.\n", res); 200738689Sborman #endif 200836274Sminshall 200938689Sborman setconnmode(0); 201036274Sminshall res = fcntl(fd, F_GETFL, 0); 201136274Sminshall setcommandmode(); 201236274Sminshall 201336274Sminshall if (res == -1) { 201436274Sminshall perror("fcntl"); 201536274Sminshall return; 201636274Sminshall } 201736274Sminshall printf("\tFlags are 0x%x: %s\n", res, decodeflags(res)); 201836274Sminshall } 201946808Sdab #endif /* defined(unix) && defined(TN3270) */ 202036274Sminshall 202136274Sminshall /* 202232144Sminshall * Print status about the connection. 202332144Sminshall */ 202446808Sdab /*ARGSUSED*/ 202546808Sdab static 202632144Sminshall status(argc, argv) 202746808Sdab int argc; 202846808Sdab char *argv[]; 202932144Sminshall { 203032144Sminshall if (connected) { 203132144Sminshall printf("Connected to %s.\n", hostname); 203236242Sminshall if ((argc < 2) || strcmp(argv[1], "notmuch")) { 203338689Sborman int mode = getconnmode(); 203438689Sborman 203538689Sborman if (my_want_state_is_will(TELOPT_LINEMODE)) { 203638689Sborman printf("Operating with LINEMODE option\n"); 203738689Sborman printf("%s line editing\n", (mode&MODE_EDIT) ? "Local" : "No"); 203838689Sborman printf("%s catching of signals\n", 203938689Sborman (mode&MODE_TRAPSIG) ? "Local" : "No"); 204038689Sborman slcstate(); 204138689Sborman #ifdef KLUDGELINEMODE 204239529Sborman } else if (kludgelinemode && my_want_state_is_dont(TELOPT_SGA)) { 204338689Sborman printf("Operating in obsolete linemode\n"); 204438689Sborman #endif 204538689Sborman } else { 204638689Sborman printf("Operating in single character mode\n"); 204738689Sborman if (localchars) 204838689Sborman printf("Catching signals locally\n"); 204932144Sminshall } 205038689Sborman printf("%s character echo\n", (mode&MODE_ECHO) ? "Local" : "Remote"); 205138689Sborman if (my_want_state_is_will(TELOPT_LFLOW)) 205238689Sborman printf("%s flow control\n", (mode&MODE_FLOW) ? "Local" : "No"); 205346808Sdab #if defined(ENCRYPT) 205446808Sdab encrypt_display(); 205546808Sdab #endif 205632144Sminshall } 205732144Sminshall } else { 205832144Sminshall printf("No connection.\n"); 205932144Sminshall } 206032144Sminshall # if !defined(TN3270) 206132144Sminshall printf("Escape character is '%s'.\n", control(escape)); 206234849Sminshall (void) fflush(stdout); 206332144Sminshall # else /* !defined(TN3270) */ 206432144Sminshall if ((!In3270) && ((argc < 2) || strcmp(argv[1], "notmuch"))) { 206532144Sminshall printf("Escape character is '%s'.\n", control(escape)); 206632144Sminshall } 206732144Sminshall # if defined(unix) 206836242Sminshall if ((argc >= 2) && !strcmp(argv[1], "everything")) { 206936242Sminshall printf("SIGIO received %d time%s.\n", 207036242Sminshall sigiocount, (sigiocount == 1)? "":"s"); 207136274Sminshall if (In3270) { 207236274Sminshall printf("Process ID %d, process group %d.\n", 207336274Sminshall getpid(), getpgrp(getpid())); 207436274Sminshall printf("Terminal input:\n"); 207536274Sminshall filestuff(tin); 207636274Sminshall printf("Terminal output:\n"); 207736274Sminshall filestuff(tout); 207836274Sminshall printf("Network socket:\n"); 207936274Sminshall filestuff(net); 208036274Sminshall } 208136242Sminshall } 208232144Sminshall if (In3270 && transcom) { 208332144Sminshall printf("Transparent mode command is '%s'.\n", transcom); 208432144Sminshall } 208532144Sminshall # endif /* defined(unix) */ 208634849Sminshall (void) fflush(stdout); 208732144Sminshall if (In3270) { 208832144Sminshall return 0; 208932144Sminshall } 209032144Sminshall # endif /* defined(TN3270) */ 209132144Sminshall return 1; 209232144Sminshall } 209332144Sminshall 209445233Sborman #ifdef SIGINFO 209545233Sborman /* 209645233Sborman * Function that gets called when SIGINFO is received. 209745233Sborman */ 209845233Sborman ayt_status() 209945233Sborman { 210045233Sborman (void) call(status, "status", "notmuch", 0); 210145233Sborman } 210245233Sborman #endif 210332144Sminshall 210446808Sdab int 210532144Sminshall tn(argc, argv) 210646808Sdab int argc; 210746808Sdab char *argv[]; 210832144Sminshall { 210932144Sminshall register struct hostent *host = 0; 211032144Sminshall struct sockaddr_in sin; 211132144Sminshall struct servent *sp = 0; 211238689Sborman unsigned long temp, inet_addr(); 211337219Sminshall extern char *inet_ntoa(); 211446808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 211538689Sborman char *srp = 0, *strrchr(); 211638689Sborman unsigned long sourceroute(), srlen; 211738689Sborman #endif 211844361Sborman char *cmd, *hostp = 0, *portp = 0, *user = 0; 211932144Sminshall 212045233Sborman /* clear the socket address prior to use */ 212145233Sborman bzero((char *)&sin, sizeof(sin)); 212232144Sminshall 212332144Sminshall if (connected) { 212432144Sminshall printf("?Already connected to %s\n", hostname); 212546808Sdab setuid(getuid()); 212632144Sminshall return 0; 212732144Sminshall } 212832144Sminshall if (argc < 2) { 212946808Sdab (void) strcpy(line, "open "); 213032144Sminshall printf("(to) "); 213146808Sdab (void) fgets(&line[strlen(line)], sizeof(line) - strlen(line), stdin); 213232144Sminshall makeargv(); 213332144Sminshall argc = margc; 213432144Sminshall argv = margv; 213532144Sminshall } 213644361Sborman cmd = *argv; 213744361Sborman --argc; ++argv; 213844361Sborman while (argc) { 213946808Sdab if (isprefix(*argv, "help") || isprefix(*argv, "?")) 214046808Sdab goto usage; 214144361Sborman if (strcmp(*argv, "-l") == 0) { 214244361Sborman --argc; ++argv; 214344361Sborman if (argc == 0) 214444361Sborman goto usage; 214544361Sborman user = *argv++; 214644361Sborman --argc; 214744361Sborman continue; 214844361Sborman } 214945233Sborman if (strcmp(*argv, "-a") == 0) { 215045233Sborman --argc; ++argv; 215145233Sborman autologin = 1; 215245233Sborman continue; 215345233Sborman } 215444361Sborman if (hostp == 0) { 215544361Sborman hostp = *argv++; 215644361Sborman --argc; 215744361Sborman continue; 215844361Sborman } 215944361Sborman if (portp == 0) { 216044361Sborman portp = *argv++; 216144361Sborman --argc; 216244361Sborman continue; 216344361Sborman } 216444361Sborman usage: 216545233Sborman printf("usage: %s [-l user] [-a] host-name [port]\n", cmd); 216646808Sdab setuid(getuid()); 216732144Sminshall return 0; 216832144Sminshall } 216946808Sdab if (hostp == 0) 217046808Sdab goto usage; 217146808Sdab 217246808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 217344361Sborman if (hostp[0] == '@' || hostp[0] == '!') { 217444361Sborman if ((hostname = strrchr(hostp, ':')) == NULL) 217544361Sborman hostname = strrchr(hostp, '@'); 217638689Sborman hostname++; 217738689Sborman srp = 0; 217844361Sborman temp = sourceroute(hostp, &srp, &srlen); 217938689Sborman if (temp == 0) { 218038689Sborman herror(srp); 218146808Sdab setuid(getuid()); 218238689Sborman return 0; 218338689Sborman } else if (temp == -1) { 218444361Sborman printf("Bad source route option: %s\n", hostp); 218546808Sdab setuid(getuid()); 218638689Sborman return 0; 218738689Sborman } else { 218838689Sborman sin.sin_addr.s_addr = temp; 218938689Sborman sin.sin_family = AF_INET; 219038689Sborman } 219132144Sminshall } else { 219238689Sborman #endif 219344361Sborman temp = inet_addr(hostp); 219438689Sborman if (temp != (unsigned long) -1) { 219538689Sborman sin.sin_addr.s_addr = temp; 219638689Sborman sin.sin_family = AF_INET; 219746808Sdab (void) strcpy(_hostname, hostp); 219846808Sdab hostname = _hostname; 219938689Sborman } else { 220044361Sborman host = gethostbyname(hostp); 220138689Sborman if (host) { 220238689Sborman sin.sin_family = host->h_addrtype; 220332144Sminshall #if defined(h_addr) /* In 4.3, this is a #define */ 220438689Sborman memcpy((caddr_t)&sin.sin_addr, 220532144Sminshall host->h_addr_list[0], host->h_length); 220632144Sminshall #else /* defined(h_addr) */ 220738689Sborman memcpy((caddr_t)&sin.sin_addr, host->h_addr, host->h_length); 220832144Sminshall #endif /* defined(h_addr) */ 220946808Sdab strncpy(_hostname, host->h_name, sizeof(_hostname)); 221046808Sdab _hostname[sizeof(_hostname)-1] = '\0'; 221146808Sdab hostname = _hostname; 221238689Sborman } else { 221344361Sborman herror(hostp); 221446808Sdab setuid(getuid()); 221538689Sborman return 0; 221638689Sborman } 221732144Sminshall } 221846808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 221932144Sminshall } 222038689Sborman #endif 222144361Sborman if (portp) { 222244361Sborman if (*portp == '-') { 222344361Sborman portp++; 222438689Sborman telnetport = 1; 222538689Sborman } else 222638689Sborman telnetport = 0; 222744361Sborman sin.sin_port = atoi(portp); 222832144Sminshall if (sin.sin_port == 0) { 222944361Sborman sp = getservbyname(portp, "tcp"); 223032144Sminshall if (sp) 223132144Sminshall sin.sin_port = sp->s_port; 223232144Sminshall else { 223344361Sborman printf("%s: bad port number\n", portp); 223446808Sdab setuid(getuid()); 223532144Sminshall return 0; 223632144Sminshall } 223732144Sminshall } else { 223832144Sminshall sin.sin_port = htons(sin.sin_port); 223932144Sminshall } 224032144Sminshall } else { 224132144Sminshall if (sp == 0) { 224232144Sminshall sp = getservbyname("telnet", "tcp"); 224332144Sminshall if (sp == 0) { 224434849Sminshall fprintf(stderr, "telnet: tcp/telnet: unknown service\n"); 224546808Sdab setuid(getuid()); 224632144Sminshall return 0; 224732144Sminshall } 224832144Sminshall sin.sin_port = sp->s_port; 224932144Sminshall } 225032144Sminshall telnetport = 1; 225132144Sminshall } 225237219Sminshall printf("Trying %s...\n", inet_ntoa(sin.sin_addr)); 225332144Sminshall do { 225432144Sminshall net = socket(AF_INET, SOCK_STREAM, 0); 225546808Sdab setuid(getuid()); 225632144Sminshall if (net < 0) { 225732144Sminshall perror("telnet: socket"); 225832144Sminshall return 0; 225932144Sminshall } 226046808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 226138689Sborman if (srp && setsockopt(net, IPPROTO_IP, IP_OPTIONS, (char *)srp, srlen) < 0) 226238689Sborman perror("setsockopt (IP_OPTIONS)"); 226338689Sborman #endif 226446808Sdab #if defined(IPPROTO_IP) && defined(IP_TOS) 226546808Sdab { 226646808Sdab # if defined(HAS_GETTOS) 226746808Sdab struct tosent *tp; 226846815Sdab if (tos < 0 && (tp = gettosbyname("telnet", "tcp"))) 226946808Sdab tos = tp->t_tos; 227046808Sdab # endif 227146815Sdab if (tos < 0) 227246815Sdab tos = 020; /* Low Delay bit */ 227346815Sdab if (tos 227446815Sdab && (setsockopt(net, IPPROTO_IP, IP_TOS, &tos, sizeof(int)) < 0) 227546815Sdab && (errno != ENOPROTOOPT)) 227646815Sdab perror("telnet: setsockopt (IP_TOS) (ignored)"); 227746808Sdab } 227846808Sdab #endif /* defined(IPPROTO_IP) && defined(IP_TOS) */ 227940245Sborman 228032144Sminshall if (debug && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 1) < 0) { 228132144Sminshall perror("setsockopt (SO_DEBUG)"); 228232144Sminshall } 228332144Sminshall 228432144Sminshall if (connect(net, (struct sockaddr *)&sin, sizeof (sin)) < 0) { 228532144Sminshall #if defined(h_addr) /* In 4.3, this is a #define */ 228632144Sminshall if (host && host->h_addr_list[1]) { 228732144Sminshall int oerrno = errno; 228832144Sminshall 228932144Sminshall fprintf(stderr, "telnet: connect to address %s: ", 229032144Sminshall inet_ntoa(sin.sin_addr)); 229132144Sminshall errno = oerrno; 229232144Sminshall perror((char *)0); 229332144Sminshall host->h_addr_list++; 229432144Sminshall memcpy((caddr_t)&sin.sin_addr, 229532144Sminshall host->h_addr_list[0], host->h_length); 229632144Sminshall (void) NetClose(net); 229732144Sminshall continue; 229832144Sminshall } 229932144Sminshall #endif /* defined(h_addr) */ 230032144Sminshall perror("telnet: Unable to connect to remote host"); 230132144Sminshall return 0; 230237219Sminshall } 230332144Sminshall connected++; 230446808Sdab #if defined(AUTHENTICATE) || defined(ENCRYPT) 230546808Sdab auth_encrypt_connect(connected); 230646808Sdab #endif 230732144Sminshall } while (connected == 0); 230844361Sborman cmdrc(hostp, hostname); 230945008Skarels if (autologin && user == NULL) { 231045008Skarels struct passwd *pw; 231145008Skarels 231245233Sborman user = getenv("USER"); 231345008Skarels if (user == NULL || 231445233Sborman (pw = getpwnam(user)) && pw->pw_uid != getuid()) { 231545233Sborman if (pw = getpwuid(getuid())) 231645008Skarels user = pw->pw_name; 231745008Skarels else 231845008Skarels user = NULL; 231945233Sborman } 232045008Skarels } 232145008Skarels if (user) { 232246808Sdab env_define((unsigned char *)"USER", (unsigned char *)user); 232346808Sdab env_export((unsigned char *)"USER"); 232445008Skarels } 232534849Sminshall (void) call(status, "status", "notmuch", 0); 232632144Sminshall if (setjmp(peerdied) == 0) 232746808Sdab telnet(user); 232834849Sminshall (void) NetClose(net); 232932381Sminshall ExitString("Connection closed by foreign host.\n",1); 233032144Sminshall /*NOTREACHED*/ 233132144Sminshall } 233232144Sminshall 233332144Sminshall #define HELPINDENT (sizeof ("connect")) 233432144Sminshall 233532144Sminshall static char 233632144Sminshall openhelp[] = "connect to a site", 233732144Sminshall closehelp[] = "close current connection", 233846808Sdab logouthelp[] = "forcibly logout remote user and close the connection", 233932144Sminshall quithelp[] = "exit telnet", 234032144Sminshall statushelp[] = "print status information", 234132144Sminshall helphelp[] = "print help information", 234232144Sminshall sendhelp[] = "transmit special characters ('send ?' for more)", 234332144Sminshall sethelp[] = "set operating parameters ('set ?' for more)", 234438689Sborman unsethelp[] = "unset operating parameters ('unset ?' for more)", 234532144Sminshall togglestring[] ="toggle operating parameters ('toggle ?' for more)", 234638689Sborman slchelp[] = "change state of special charaters ('slc ?' for more)", 234732144Sminshall displayhelp[] = "display operating parameters", 234832144Sminshall #if defined(TN3270) && defined(unix) 234932144Sminshall transcomhelp[] = "specify Unix command for transparent mode pipe", 235032144Sminshall #endif /* defined(TN3270) && defined(unix) */ 235146808Sdab #if defined(AUTHENTICATE) 235246808Sdab authhelp[] = "turn on (off) authentication ('auth ?' for more)", 235346808Sdab #endif 235446808Sdab #if defined(ENCRYPT) 235546808Sdab encrypthelp[] = "turn on (off) encryption ('encrypt ?' for more)", 235646808Sdab #endif 235732144Sminshall #if defined(unix) 235832144Sminshall zhelp[] = "suspend telnet", 235943317Skfall #endif /* defined(unix) */ 236032144Sminshall shellhelp[] = "invoke a subshell", 236144361Sborman envhelp[] = "change environment variables ('environ ?' for more)", 236244361Sborman modestring[] = "try to enter line or character mode ('mode ?' for more)"; 236332144Sminshall 236456642Sralph static int help(); 236532144Sminshall 236632144Sminshall static Command cmdtab[] = { 236738689Sborman { "close", closehelp, bye, 1 }, 236846808Sdab { "logout", logouthelp, logout, 1 }, 236938689Sborman { "display", displayhelp, display, 0 }, 237038689Sborman { "mode", modestring, modecmd, 0 }, 237138689Sborman { "open", openhelp, tn, 0 }, 237238689Sborman { "quit", quithelp, quit, 0 }, 237338689Sborman { "send", sendhelp, sendcmd, 0 }, 237438689Sborman { "set", sethelp, setcmd, 0 }, 237538689Sborman { "unset", unsethelp, unsetcmd, 0 }, 237638689Sborman { "status", statushelp, status, 0 }, 237738689Sborman { "toggle", togglestring, toggle, 0 }, 237838689Sborman { "slc", slchelp, slccmd, 0 }, 237932144Sminshall #if defined(TN3270) && defined(unix) 238038689Sborman { "transcom", transcomhelp, settranscom, 0 }, 238132144Sminshall #endif /* defined(TN3270) && defined(unix) */ 238246808Sdab #if defined(AUTHENTICATE) 238346808Sdab { "auth", authhelp, auth_cmd, 0 }, 238446808Sdab #endif 238546808Sdab #if defined(ENCRYPT) 238646808Sdab { "encrypt", encrypthelp, encrypt_cmd, 0 }, 238746808Sdab #endif 238832144Sminshall #if defined(unix) 238938689Sborman { "z", zhelp, suspend, 0 }, 239032144Sminshall #endif /* defined(unix) */ 239132144Sminshall #if defined(TN3270) 239238689Sborman { "!", shellhelp, shell, 1 }, 239338689Sborman #else 239438689Sborman { "!", shellhelp, shell, 0 }, 239538689Sborman #endif 239644361Sborman { "environ", envhelp, env_cmd, 0 }, 239738689Sborman { "?", helphelp, help, 0 }, 239832144Sminshall 0 239932144Sminshall }; 240032144Sminshall 240132144Sminshall static char crmodhelp[] = "deprecated command -- use 'toggle crmod' instead"; 240232144Sminshall static char escapehelp[] = "deprecated command -- use 'set escape' instead"; 240332144Sminshall 240432144Sminshall static Command cmdtab2[] = { 240538689Sborman { "help", 0, help, 0 }, 240638689Sborman { "escape", escapehelp, setescape, 0 }, 240738689Sborman { "crmod", crmodhelp, togcrmod, 0 }, 240832144Sminshall 0 240932144Sminshall }; 241032144Sminshall 241135298Sminshall 241232144Sminshall /* 241332144Sminshall * Call routine with argc, argv set from args (terminated by 0). 241432144Sminshall */ 241535298Sminshall 241646808Sdab /*VARARGS1*/ 241746808Sdab static 241835298Sminshall call(va_alist) 241946808Sdab va_dcl 242032144Sminshall { 242135298Sminshall va_list ap; 242235298Sminshall typedef int (*intrtn_t)(); 242335298Sminshall intrtn_t routine; 242435298Sminshall char *args[100]; 242535298Sminshall int argno = 0; 242635298Sminshall 242735298Sminshall va_start(ap); 242835298Sminshall routine = (va_arg(ap, intrtn_t)); 242935495Sminshall while ((args[argno++] = va_arg(ap, char *)) != 0) { 243035298Sminshall ; 243135495Sminshall } 243235298Sminshall va_end(ap); 243335495Sminshall return (*routine)(argno-1, args); 243432144Sminshall } 243532144Sminshall 243635298Sminshall 243746808Sdab static Command * 243832144Sminshall getcmd(name) 243946808Sdab char *name; 244032144Sminshall { 244132144Sminshall Command *cm; 244232144Sminshall 244346808Sdab if (cm = (Command *) genget(name, (char **) cmdtab, sizeof(Command))) 244432144Sminshall return cm; 244546808Sdab return (Command *) genget(name, (char **) cmdtab2, sizeof(Command)); 244632144Sminshall } 244732144Sminshall 244846808Sdab void 244938689Sborman command(top, tbuf, cnt) 245046808Sdab int top; 245146808Sdab char *tbuf; 245246808Sdab int cnt; 245332144Sminshall { 245432144Sminshall register Command *c; 245532144Sminshall 245632144Sminshall setcommandmode(); 245732144Sminshall if (!top) { 245832144Sminshall putchar('\n'); 245937219Sminshall #if defined(unix) 246032144Sminshall } else { 246144361Sborman (void) signal(SIGINT, SIG_DFL); 246244361Sborman (void) signal(SIGQUIT, SIG_DFL); 246332144Sminshall #endif /* defined(unix) */ 246432144Sminshall } 246532144Sminshall for (;;) { 246646808Sdab if (rlogin == _POSIX_VDISABLE) 246746808Sdab printf("%s> ", prompt); 246838689Sborman if (tbuf) { 246938689Sborman register char *cp; 247038689Sborman cp = line; 247138689Sborman while (cnt > 0 && (*cp++ = *tbuf++) != '\n') 247238689Sborman cnt--; 247338689Sborman tbuf = 0; 247438689Sborman if (cp == line || *--cp != '\n' || cp == line) 247538689Sborman goto getline; 247638689Sborman *cp = '\0'; 247746808Sdab if (rlogin == _POSIX_VDISABLE) 247846808Sdab printf("%s\n", line); 247938689Sborman } else { 248038689Sborman getline: 248146808Sdab if (rlogin != _POSIX_VDISABLE) 248246808Sdab printf("%s> ", prompt); 248346808Sdab if (fgets(line, sizeof(line), stdin) == NULL) { 248444361Sborman if (feof(stdin) || ferror(stdin)) { 248544361Sborman (void) quit(); 248644361Sborman /*NOTREACHED*/ 248744361Sborman } 248838689Sborman break; 248938689Sborman } 249032144Sminshall } 249132144Sminshall if (line[0] == 0) 249232144Sminshall break; 249332144Sminshall makeargv(); 249437219Sminshall if (margv[0] == 0) { 249537219Sminshall break; 249637219Sminshall } 249732144Sminshall c = getcmd(margv[0]); 249832144Sminshall if (Ambiguous(c)) { 249932144Sminshall printf("?Ambiguous command\n"); 250032144Sminshall continue; 250132144Sminshall } 250232144Sminshall if (c == 0) { 250332144Sminshall printf("?Invalid command\n"); 250432144Sminshall continue; 250532144Sminshall } 250632144Sminshall if (c->needconnect && !connected) { 250732144Sminshall printf("?Need to be connected first.\n"); 250832144Sminshall continue; 250932144Sminshall } 251032144Sminshall if ((*c->handler)(margc, margv)) { 251132144Sminshall break; 251232144Sminshall } 251332144Sminshall } 251432144Sminshall if (!top) { 251532144Sminshall if (!connected) { 251632144Sminshall longjmp(toplevel, 1); 251732144Sminshall /*NOTREACHED*/ 251832144Sminshall } 251932144Sminshall #if defined(TN3270) 252032144Sminshall if (shell_active == 0) { 252138689Sborman setconnmode(0); 252232144Sminshall } 252332144Sminshall #else /* defined(TN3270) */ 252438689Sborman setconnmode(0); 252532144Sminshall #endif /* defined(TN3270) */ 252632144Sminshall } 252732144Sminshall } 252832144Sminshall 252932144Sminshall /* 253032144Sminshall * Help command. 253132144Sminshall */ 253246808Sdab static 253332144Sminshall help(argc, argv) 253432144Sminshall int argc; 253532144Sminshall char *argv[]; 253632144Sminshall { 253732144Sminshall register Command *c; 253832144Sminshall 253932144Sminshall if (argc == 1) { 254032144Sminshall printf("Commands may be abbreviated. Commands are:\n\n"); 254132144Sminshall for (c = cmdtab; c->name; c++) 254238689Sborman if (c->help) { 254332144Sminshall printf("%-*s\t%s\n", HELPINDENT, c->name, 254432144Sminshall c->help); 254532144Sminshall } 254632144Sminshall return 0; 254732144Sminshall } 254832144Sminshall while (--argc > 0) { 254932144Sminshall register char *arg; 255032144Sminshall arg = *++argv; 255132144Sminshall c = getcmd(arg); 255232144Sminshall if (Ambiguous(c)) 255332144Sminshall printf("?Ambiguous help command %s\n", arg); 255432144Sminshall else if (c == (Command *)0) 255532144Sminshall printf("?Invalid help command %s\n", arg); 255632144Sminshall else 255732144Sminshall printf("%s\n", c->help); 255832144Sminshall } 255932144Sminshall return 0; 256032144Sminshall } 256138689Sborman 256238689Sborman static char *rcname = 0; 256338689Sborman static char rcbuf[128]; 256438689Sborman 256538689Sborman cmdrc(m1, m2) 256638689Sborman char *m1, *m2; 256738689Sborman { 256838689Sborman register Command *c; 256938689Sborman FILE *rcfile; 257038689Sborman int gotmachine = 0; 257138689Sborman int l1 = strlen(m1); 257238689Sborman int l2 = strlen(m2); 257338689Sborman char m1save[64]; 257438689Sborman 257547609Sdab if (skiprc) 257647609Sdab return; 257747609Sdab 257838689Sborman strcpy(m1save, m1); 257938689Sborman m1 = m1save; 258038689Sborman 258138689Sborman if (rcname == 0) { 258238689Sborman rcname = getenv("HOME"); 258338689Sborman if (rcname) 258438689Sborman strcpy(rcbuf, rcname); 258538689Sborman else 258638689Sborman rcbuf[0] = '\0'; 258738689Sborman strcat(rcbuf, "/.telnetrc"); 258838689Sborman rcname = rcbuf; 258938689Sborman } 259038689Sborman 259138689Sborman if ((rcfile = fopen(rcname, "r")) == 0) { 259238689Sborman return; 259338689Sborman } 259438689Sborman 259538689Sborman for (;;) { 259638689Sborman if (fgets(line, sizeof(line), rcfile) == NULL) 259738689Sborman break; 259838689Sborman if (line[0] == 0) 259938689Sborman break; 260038689Sborman if (line[0] == '#') 260138689Sborman continue; 260247609Sdab if (gotmachine) { 260347609Sdab if (!isspace(line[0])) 260447609Sdab gotmachine = 0; 260547609Sdab } 260638689Sborman if (gotmachine == 0) { 260738689Sborman if (isspace(line[0])) 260838689Sborman continue; 260938689Sborman if (strncasecmp(line, m1, l1) == 0) 261038689Sborman strncpy(line, &line[l1], sizeof(line) - l1); 261138689Sborman else if (strncasecmp(line, m2, l2) == 0) 261238689Sborman strncpy(line, &line[l2], sizeof(line) - l2); 261347609Sdab else if (strncasecmp(line, "DEFAULT", 7) == 0) 261447609Sdab strncpy(line, &line[7], sizeof(line) - 7); 261538689Sborman else 261638689Sborman continue; 261747609Sdab if (line[0] != ' ' && line[0] != '\t' && line[0] != '\n') 261847609Sdab continue; 261938689Sborman gotmachine = 1; 262038689Sborman } 262138689Sborman makeargv(); 262238689Sborman if (margv[0] == 0) 262338689Sborman continue; 262438689Sborman c = getcmd(margv[0]); 262538689Sborman if (Ambiguous(c)) { 262638689Sborman printf("?Ambiguous command: %s\n", margv[0]); 262738689Sborman continue; 262838689Sborman } 262938689Sborman if (c == 0) { 263038689Sborman printf("?Invalid command: %s\n", margv[0]); 263138689Sborman continue; 263238689Sborman } 263338689Sborman /* 263438689Sborman * This should never happen... 263538689Sborman */ 263638689Sborman if (c->needconnect && !connected) { 263738689Sborman printf("?Need to be connected first for %s.\n", margv[0]); 263838689Sborman continue; 263938689Sborman } 264038689Sborman (*c->handler)(margc, margv); 264138689Sborman } 264238689Sborman fclose(rcfile); 264338689Sborman } 264438689Sborman 264546808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 264638689Sborman 264738689Sborman /* 264838689Sborman * Source route is handed in as 264938689Sborman * [!]@hop1@hop2...[@|:]dst 265038689Sborman * If the leading ! is present, it is a 265138689Sborman * strict source route, otherwise it is 265238689Sborman * assmed to be a loose source route. 265338689Sborman * 265438689Sborman * We fill in the source route option as 265538689Sborman * hop1,hop2,hop3...dest 265638689Sborman * and return a pointer to hop1, which will 265738689Sborman * be the address to connect() to. 265838689Sborman * 265938689Sborman * Arguments: 266038689Sborman * arg: pointer to route list to decipher 266138689Sborman * 266238689Sborman * cpp: If *cpp is not equal to NULL, this is a 266338689Sborman * pointer to a pointer to a character array 266438689Sborman * that should be filled in with the option. 266538689Sborman * 266638689Sborman * lenp: pointer to an integer that contains the 266738689Sborman * length of *cpp if *cpp != NULL. 266838689Sborman * 266938689Sborman * Return values: 267038689Sborman * 267138689Sborman * Returns the address of the host to connect to. If the 267238689Sborman * return value is -1, there was a syntax error in the 267338689Sborman * option, either unknown characters, or too many hosts. 267438689Sborman * If the return value is 0, one of the hostnames in the 267538689Sborman * path is unknown, and *cpp is set to point to the bad 267638689Sborman * hostname. 267738689Sborman * 267838689Sborman * *cpp: If *cpp was equal to NULL, it will be filled 267938689Sborman * in with a pointer to our static area that has 268038689Sborman * the option filled in. This will be 32bit aligned. 268138689Sborman * 268238689Sborman * *lenp: This will be filled in with how long the option 268338689Sborman * pointed to by *cpp is. 268438689Sborman * 268538689Sborman */ 268646808Sdab unsigned long 268738689Sborman sourceroute(arg, cpp, lenp) 268846808Sdab char *arg; 268946808Sdab char **cpp; 269046808Sdab int *lenp; 269138689Sborman { 269238689Sborman static char lsr[44]; 269346808Sdab char *cp, *cp2, *lsrp, *lsrep; 269438689Sborman register int tmp; 269538689Sborman struct in_addr sin_addr; 269638689Sborman register struct hostent *host = 0; 269738689Sborman register char c; 269838689Sborman 269938689Sborman /* 270038689Sborman * Verify the arguments, and make sure we have 270138689Sborman * at least 7 bytes for the option. 270238689Sborman */ 270338689Sborman if (cpp == NULL || lenp == NULL) 270438689Sborman return((unsigned long)-1); 270538689Sborman if (*cpp != NULL && *lenp < 7) 270638689Sborman return((unsigned long)-1); 270738689Sborman /* 270838689Sborman * Decide whether we have a buffer passed to us, 270938689Sborman * or if we need to use our own static buffer. 271038689Sborman */ 271138689Sborman if (*cpp) { 271238689Sborman lsrp = *cpp; 271338689Sborman lsrep = lsrp + *lenp; 271438689Sborman } else { 271538689Sborman *cpp = lsrp = lsr; 271638689Sborman lsrep = lsrp + 44; 271738689Sborman } 271838689Sborman 271938689Sborman cp = arg; 272038689Sborman 272138689Sborman /* 272238689Sborman * Next, decide whether we have a loose source 272338689Sborman * route or a strict source route, and fill in 272438689Sborman * the begining of the option. 272538689Sborman */ 272638689Sborman if (*cp == '!') { 272738689Sborman cp++; 272838689Sborman *lsrp++ = IPOPT_SSRR; 272938689Sborman } else 273038689Sborman *lsrp++ = IPOPT_LSRR; 273138689Sborman 273238689Sborman if (*cp != '@') 273338689Sborman return((unsigned long)-1); 273438689Sborman 273538689Sborman lsrp++; /* skip over length, we'll fill it in later */ 273638689Sborman *lsrp++ = 4; 273738689Sborman 273838689Sborman cp++; 273938689Sborman 274038689Sborman sin_addr.s_addr = 0; 274138689Sborman 274238689Sborman for (c = 0;;) { 274338689Sborman if (c == ':') 274438689Sborman cp2 = 0; 274538689Sborman else for (cp2 = cp; c = *cp2; cp2++) { 274638689Sborman if (c == ',') { 274738689Sborman *cp2++ = '\0'; 274838689Sborman if (*cp2 == '@') 274938689Sborman cp2++; 275038689Sborman } else if (c == '@') { 275138689Sborman *cp2++ = '\0'; 275238689Sborman } else if (c == ':') { 275338689Sborman *cp2++ = '\0'; 275438689Sborman } else 275538689Sborman continue; 275638689Sborman break; 275738689Sborman } 275838689Sborman if (!c) 275938689Sborman cp2 = 0; 276038689Sborman 276138689Sborman if ((tmp = inet_addr(cp)) != -1) { 276238689Sborman sin_addr.s_addr = tmp; 276338689Sborman } else if (host = gethostbyname(cp)) { 276438689Sborman #if defined(h_addr) 276538689Sborman memcpy((caddr_t)&sin_addr, 276638689Sborman host->h_addr_list[0], host->h_length); 276738689Sborman #else 276838689Sborman memcpy((caddr_t)&sin_addr, host->h_addr, host->h_length); 276938689Sborman #endif 277038689Sborman } else { 277138689Sborman *cpp = cp; 277238689Sborman return(0); 277338689Sborman } 277438689Sborman memcpy(lsrp, (char *)&sin_addr, 4); 277538689Sborman lsrp += 4; 277638689Sborman if (cp2) 277738689Sborman cp = cp2; 277838689Sborman else 277938689Sborman break; 278038689Sborman /* 278138689Sborman * Check to make sure there is space for next address 278238689Sborman */ 278338689Sborman if (lsrp + 4 > lsrep) 278438689Sborman return((unsigned long)-1); 278538689Sborman } 278638689Sborman if ((*(*cpp+IPOPT_OLEN) = lsrp - *cpp) <= 7) { 278738689Sborman *cpp = 0; 278838689Sborman *lenp = 0; 278938689Sborman return((unsigned long)-1); 279038689Sborman } 279138689Sborman *lsrp++ = IPOPT_NOP; /* 32 bit word align it */ 279238689Sborman *lenp = lsrp - *cpp; 279338689Sborman return(sin_addr.s_addr); 279438689Sborman } 279538689Sborman #endif 2796