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*46815Sdab static char sccsid[] = "@(#)commands.c 5.4 (Berkeley) 03/01/91"; 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 57*46815Sdab #if defined(IPPROTO_IP) && defined(IP_TOS) 58*46815Sdab int tos = -1; 59*46815Sdab #endif /* defined(IPPROTO_IP) && defined(IP_TOS) */ 60*46815Sdab 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 22346808Sdab extern int 22446808Sdab send_esc P((void)), 22546808Sdab send_help P((void)), 22646808Sdab send_docmd P((char *)), 22746808Sdab send_dontcmd P((char *)), 22846808Sdab send_willcmd P((char *)), 22946808Sdab send_wontcmd P((char *)); 23046808Sdab 23132144Sminshall static struct sendlist Sendlist[] = { 23246808Sdab { "ao", "Send Telnet Abort output", 1, 0, 0, 2, AO }, 23346808Sdab { "ayt", "Send Telnet 'Are You There'", 1, 0, 0, 2, AYT }, 23446808Sdab { "brk", "Send Telnet Break", 1, 0, 0, 2, BREAK }, 23546808Sdab { "break", 0, 1, 0, 0, 2, BREAK }, 23646808Sdab { "ec", "Send Telnet Erase Character", 1, 0, 0, 2, EC }, 23746808Sdab { "el", "Send Telnet Erase Line", 1, 0, 0, 2, EL }, 23846808Sdab { "escape", "Send current escape character", 1, 0, send_esc, 1, 0 }, 23946808Sdab { "ga", "Send Telnet 'Go Ahead' sequence", 1, 0, 0, 2, GA }, 24046808Sdab { "ip", "Send Telnet Interrupt Process", 1, 0, 0, 2, IP }, 24146808Sdab { "intp", 0, 1, 0, 0, 2, IP }, 24246808Sdab { "interrupt", 0, 1, 0, 0, 2, IP }, 24346808Sdab { "intr", 0, 1, 0, 0, 2, IP }, 24446808Sdab { "nop", "Send Telnet 'No operation'", 1, 0, 0, 2, NOP }, 24546808Sdab { "eor", "Send Telnet 'End of Record'", 1, 0, 0, 2, EOR }, 24646808Sdab { "abort", "Send Telnet 'Abort Process'", 1, 0, 0, 2, ABORT }, 24746808Sdab { "susp", "Send Telnet 'Suspend Process'", 1, 0, 0, 2, SUSP }, 24846808Sdab { "eof", "Send Telnet End of File Character", 1, 0, 0, 2, xEOF }, 24946808Sdab { "synch", "Perform Telnet 'Synch operation'", 1, 0, dosynch, 2, 0 }, 25046808Sdab { "getstatus", "Send request for STATUS", 1, 0, get_status, 6, 0 }, 25146808Sdab { "?", "Display send options", 0, 0, send_help, 0, 0 }, 25246808Sdab { "help", 0, 0, 0, send_help, 0, 0 }, 25346808Sdab { "do", 0, 0, 1, send_docmd, 3, 0 }, 25446808Sdab { "dont", 0, 0, 1, send_dontcmd, 3, 0 }, 25546808Sdab { "will", 0, 0, 1, send_willcmd, 3, 0 }, 25646808Sdab { "wont", 0, 0, 1, send_wontcmd, 3, 0 }, 25732144Sminshall { 0 } 25832144Sminshall }; 25932144Sminshall 26046808Sdab #define GETSEND(name) ((struct sendlist *) genget(name, (char **) Sendlist, \ 26146808Sdab sizeof(struct sendlist))) 26232144Sminshall 26346808Sdab static int 26432144Sminshall sendcmd(argc, argv) 26546808Sdab int argc; 26646808Sdab char **argv; 26732144Sminshall { 26832144Sminshall int what; /* what we are sending this time */ 26932144Sminshall int count; /* how many bytes we are going to need to send */ 27032144Sminshall int i; 27132144Sminshall int question = 0; /* was at least one argument a question */ 27232144Sminshall struct sendlist *s; /* pointer to current command */ 27346808Sdab int success = 0; 27446808Sdab int needconnect = 0; 27532144Sminshall 27632144Sminshall if (argc < 2) { 27732144Sminshall printf("need at least one argument for 'send' command\n"); 27832144Sminshall printf("'send ?' for help\n"); 27932144Sminshall return 0; 28032144Sminshall } 28132144Sminshall /* 28232144Sminshall * First, validate all the send arguments. 28332144Sminshall * In addition, we see how much space we are going to need, and 28432144Sminshall * whether or not we will be doing a "SYNCH" operation (which 28532144Sminshall * flushes the network queue). 28632144Sminshall */ 28732144Sminshall count = 0; 28832144Sminshall for (i = 1; i < argc; i++) { 28946808Sdab s = GETSEND(argv[i]); 29032144Sminshall if (s == 0) { 29132144Sminshall printf("Unknown send argument '%s'\n'send ?' for help.\n", 29232144Sminshall argv[i]); 29332144Sminshall return 0; 29432144Sminshall } else if (Ambiguous(s)) { 29532144Sminshall printf("Ambiguous send argument '%s'\n'send ?' for help.\n", 29632144Sminshall argv[i]); 29732144Sminshall return 0; 29832144Sminshall } 29946808Sdab if (i + s->narg >= argc) { 30046808Sdab fprintf(stderr, 30146808Sdab "Need %d argument%s to 'send %s' command. 'send %s ?' for help.\n", 30246808Sdab s->narg, s->narg == 1 ? "" : "s", s->name, s->name); 30346808Sdab return 0; 30432144Sminshall } 30546808Sdab count += s->nbyte; 30646808Sdab if (s->handler == send_help) { 30746808Sdab send_help(); 30846808Sdab return 0; 30946808Sdab } 31046808Sdab 31146808Sdab i += s->narg; 31246808Sdab needconnect += s->needconnect; 31332144Sminshall } 31446808Sdab if (!connected && needconnect) { 31546808Sdab printf("?Need to be connected first.\n"); 31646808Sdab printf("'send ?' for help\n"); 31746808Sdab return 0; 31838689Sborman } 31932144Sminshall /* Now, do we have enough room? */ 32032144Sminshall if (NETROOM() < count) { 32132144Sminshall printf("There is not enough room in the buffer TO the network\n"); 32232144Sminshall printf("to process your request. Nothing will be done.\n"); 32332144Sminshall printf("('send synch' will throw away most data in the network\n"); 32432144Sminshall printf("buffer, if this might help.)\n"); 32532144Sminshall return 0; 32632144Sminshall } 32732144Sminshall /* OK, they are all OK, now go through again and actually send */ 32846808Sdab count = 0; 32932144Sminshall for (i = 1; i < argc; i++) { 33046808Sdab if ((s = GETSEND(argv[i])) == 0) { 33132144Sminshall fprintf(stderr, "Telnet 'send' error - argument disappeared!\n"); 33244361Sborman (void) quit(); 33332144Sminshall /*NOTREACHED*/ 33432144Sminshall } 33538689Sborman if (s->handler) { 33646808Sdab count++; 33746808Sdab success += (*s->handler)((s->narg > 0) ? argv[i+1] : 0, 33846808Sdab (s->narg > 1) ? argv[i+2] : 0); 33946808Sdab i += s->narg; 34032144Sminshall } else { 34146808Sdab NET2ADD(IAC, what); 34246808Sdab printoption("SENT", IAC, what); 34346808Sdab } 34446808Sdab } 34546808Sdab return (count == success); 34646808Sdab } 34746808Sdab 34846808Sdab static int 34946808Sdab send_esc() 35046808Sdab { 35146808Sdab NETADD(escape); 35246808Sdab return 1; 35346808Sdab } 35446808Sdab 35546808Sdab static int 35646808Sdab send_docmd(name) 35746808Sdab char *name; 35846808Sdab { 35946808Sdab void send_do(); 36046808Sdab return(send_tncmd(send_do, "do", name)); 36146808Sdab } 36246808Sdab 36346808Sdab static int 36446808Sdab send_dontcmd(name) 36546808Sdab char *name; 36646808Sdab { 36746808Sdab void send_dont(); 36846808Sdab return(send_tncmd(send_dont, "dont", name)); 36946808Sdab } 37046808Sdab static int 37146808Sdab send_willcmd(name) 37246808Sdab char *name; 37346808Sdab { 37446808Sdab void send_will(); 37546808Sdab return(send_tncmd(send_will, "will", name)); 37646808Sdab } 37746808Sdab static int 37846808Sdab send_wontcmd(name) 37946808Sdab char *name; 38046808Sdab { 38146808Sdab void send_wont(); 38246808Sdab return(send_tncmd(send_wont, "wont", name)); 38346808Sdab } 38446808Sdab 38546808Sdab int 38646808Sdab send_tncmd(func, cmd, name) 38746808Sdab void (*func)(); 38846808Sdab char *cmd, *name; 38946808Sdab { 39046808Sdab char **cpp; 39146808Sdab extern char *telopts[]; 39246808Sdab 39346808Sdab if (isprefix(name, "help") || isprefix(name, "?")) { 39446808Sdab register int col, len; 39546808Sdab 39646808Sdab printf("Usage: send %s <option>\n", cmd); 39746808Sdab printf("Valid options are:\n\t"); 39846808Sdab 39946808Sdab col = 8; 40046808Sdab for (cpp = telopts; *cpp; cpp++) { 40146808Sdab len = strlen(*cpp) + 1; 40246808Sdab if (col + len > 65) { 40346808Sdab printf("\n\t"); 40446808Sdab col = 8; 40532144Sminshall } 40646808Sdab printf(" %s", *cpp); 40746808Sdab col += len; 40832144Sminshall } 40946808Sdab printf("\n"); 41046808Sdab return 0; 41132144Sminshall } 41246808Sdab cpp = (char **)genget(name, telopts, sizeof(char *)); 41346808Sdab if (Ambiguous(cpp)) { 41446808Sdab fprintf(stderr,"'%s': ambiguous argument ('send %s ?' for help).\n", 41546808Sdab name, cmd); 41646808Sdab return 0; 41746808Sdab } 41846808Sdab if (cpp == 0) { 41946808Sdab fprintf(stderr, "'%s': unknown argument ('send %s ?' for help).\n", 42046808Sdab name, cmd); 42146808Sdab return 0; 42246808Sdab } 42346808Sdab if (!connected) { 42446808Sdab printf("?Need to be connected first.\n"); 42546808Sdab return 0; 42646808Sdab } 42746808Sdab (*func)(cpp - telopts, 1); 42846808Sdab return 1; 42932144Sminshall } 43046808Sdab 43146808Sdab static int 43246808Sdab send_help() 43346808Sdab { 43446808Sdab struct sendlist *s; /* pointer to current command */ 43546808Sdab for (s = Sendlist; s->name; s++) { 43646808Sdab if (s->help) 43746808Sdab printf("%-15s %s\n", s->name, s->help); 43846808Sdab } 43946808Sdab return(0); 44046808Sdab } 44132144Sminshall 44232144Sminshall /* 44332144Sminshall * The following are the routines and data structures referred 44432144Sminshall * to by the arguments to the "toggle" command. 44532144Sminshall */ 44632144Sminshall 44746808Sdab static int 44832144Sminshall lclchars() 44932144Sminshall { 45032144Sminshall donelclchars = 1; 45132144Sminshall return 1; 45232144Sminshall } 45332144Sminshall 45446808Sdab static int 45532144Sminshall togdebug() 45632144Sminshall { 45732144Sminshall #ifndef NOT43 45832144Sminshall if (net > 0 && 45932144Sminshall (SetSockOpt(net, SOL_SOCKET, SO_DEBUG, debug)) < 0) { 46032144Sminshall perror("setsockopt (SO_DEBUG)"); 46132144Sminshall } 46232144Sminshall #else /* NOT43 */ 46332144Sminshall if (debug) { 46432144Sminshall if (net > 0 && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 0, 0) < 0) 46532144Sminshall perror("setsockopt (SO_DEBUG)"); 46632144Sminshall } else 46732144Sminshall printf("Cannot turn off socket debugging\n"); 46832144Sminshall #endif /* NOT43 */ 46932144Sminshall return 1; 47032144Sminshall } 47132144Sminshall 47232144Sminshall 47346808Sdab static int 47432144Sminshall togcrlf() 47532144Sminshall { 47632144Sminshall if (crlf) { 47732144Sminshall printf("Will send carriage returns as telnet <CR><LF>.\n"); 47832144Sminshall } else { 47932144Sminshall printf("Will send carriage returns as telnet <CR><NUL>.\n"); 48032144Sminshall } 48132144Sminshall return 1; 48232144Sminshall } 48332144Sminshall 48438909Sborman int binmode; 48532144Sminshall 48646808Sdab static int 48738689Sborman togbinary(val) 48846808Sdab int val; 48932144Sminshall { 49032144Sminshall donebinarytoggle = 1; 49132144Sminshall 49238909Sborman if (val >= 0) { 49338909Sborman binmode = val; 49438909Sborman } else { 49538909Sborman if (my_want_state_is_will(TELOPT_BINARY) && 49638909Sborman my_want_state_is_do(TELOPT_BINARY)) { 49738909Sborman binmode = 1; 49838909Sborman } else if (my_want_state_is_wont(TELOPT_BINARY) && 49938909Sborman my_want_state_is_dont(TELOPT_BINARY)) { 50038909Sborman binmode = 0; 50138909Sborman } 50238909Sborman val = binmode ? 0 : 1; 50338909Sborman } 50438909Sborman 50538909Sborman if (val == 1) { 50638909Sborman if (my_want_state_is_will(TELOPT_BINARY) && 50738909Sborman my_want_state_is_do(TELOPT_BINARY)) { 50838689Sborman printf("Already operating in binary mode with remote host.\n"); 50938909Sborman } else { 51038909Sborman printf("Negotiating binary mode with remote host.\n"); 51138909Sborman tel_enter_binary(3); 51238689Sborman } 51338909Sborman } else { 51438909Sborman if (my_want_state_is_wont(TELOPT_BINARY) && 51538909Sborman my_want_state_is_dont(TELOPT_BINARY)) { 51638689Sborman printf("Already in network ascii mode with remote host.\n"); 51738909Sborman } else { 51838909Sborman printf("Negotiating network ascii mode with remote host.\n"); 51938909Sborman tel_leave_binary(3); 52038689Sborman } 52132144Sminshall } 52232144Sminshall return 1; 52332144Sminshall } 52432144Sminshall 52546808Sdab static int 52638909Sborman togrbinary(val) 52746808Sdab int val; 52838909Sborman { 52938909Sborman donebinarytoggle = 1; 53032144Sminshall 53138909Sborman if (val == -1) 53238909Sborman val = my_want_state_is_do(TELOPT_BINARY) ? 0 : 1; 53332144Sminshall 53438909Sborman if (val == 1) { 53538909Sborman if (my_want_state_is_do(TELOPT_BINARY)) { 53638909Sborman printf("Already receiving in binary mode.\n"); 53738909Sborman } else { 53838909Sborman printf("Negotiating binary mode on input.\n"); 53938909Sborman tel_enter_binary(1); 54038909Sborman } 54138909Sborman } else { 54238909Sborman if (my_want_state_is_dont(TELOPT_BINARY)) { 54338909Sborman printf("Already receiving in network ascii mode.\n"); 54438909Sborman } else { 54538909Sborman printf("Negotiating network ascii mode on input.\n"); 54638909Sborman tel_leave_binary(1); 54738909Sborman } 54838909Sborman } 54938909Sborman return 1; 55038909Sborman } 55138909Sborman 55246808Sdab static int 55338909Sborman togxbinary(val) 55446808Sdab int val; 55538909Sborman { 55638909Sborman donebinarytoggle = 1; 55738909Sborman 55838909Sborman if (val == -1) 55938909Sborman val = my_want_state_is_will(TELOPT_BINARY) ? 0 : 1; 56038909Sborman 56138909Sborman if (val == 1) { 56238909Sborman if (my_want_state_is_will(TELOPT_BINARY)) { 56338909Sborman printf("Already transmitting in binary mode.\n"); 56438909Sborman } else { 56538909Sborman printf("Negotiating binary mode on output.\n"); 56638909Sborman tel_enter_binary(2); 56738909Sborman } 56838909Sborman } else { 56938909Sborman if (my_want_state_is_wont(TELOPT_BINARY)) { 57038909Sborman printf("Already transmitting in network ascii mode.\n"); 57138909Sborman } else { 57238909Sborman printf("Negotiating network ascii mode on output.\n"); 57338909Sborman tel_leave_binary(2); 57438909Sborman } 57538909Sborman } 57638909Sborman return 1; 57738909Sborman } 57838909Sborman 57938909Sborman 58046808Sdab extern int togglehelp P((void)); 58132144Sminshall 58232144Sminshall struct togglelist { 58332144Sminshall char *name; /* name of toggle */ 58432144Sminshall char *help; /* help message */ 58532144Sminshall int (*handler)(); /* routine to do actual setting */ 58632144Sminshall int *variable; 58732144Sminshall char *actionexplanation; 58832144Sminshall }; 58932144Sminshall 59032144Sminshall static struct togglelist Togglelist[] = { 59132144Sminshall { "autoflush", 59238689Sborman "flushing of output when sending interrupt characters", 59332144Sminshall 0, 59438689Sborman &autoflush, 59538689Sborman "flush output when sending interrupt characters" }, 59632144Sminshall { "autosynch", 59738689Sborman "automatic sending of interrupt characters in urgent mode", 59832144Sminshall 0, 59938689Sborman &autosynch, 60038689Sborman "send interrupt characters in urgent mode" }, 60132144Sminshall { "binary", 60238689Sborman "sending and receiving of binary data", 60332144Sminshall togbinary, 60438689Sborman 0, 60538689Sborman 0 }, 60638909Sborman { "inbinary", 60738909Sborman "receiving of binary data", 60838909Sborman togrbinary, 60938909Sborman 0, 61038909Sborman 0 }, 61138909Sborman { "outbinary", 61238909Sborman "sending of binary data", 61338909Sborman togxbinary, 61438909Sborman 0, 61538909Sborman 0 }, 61632144Sminshall { "crlf", 61738689Sborman "sending carriage returns as telnet <CR><LF>", 61832144Sminshall togcrlf, 61938689Sborman &crlf, 62038689Sborman 0 }, 62132144Sminshall { "crmod", 62238689Sborman "mapping of received carriage returns", 62332144Sminshall 0, 62438689Sborman &crmod, 62538689Sborman "map carriage return on output" }, 62632144Sminshall { "localchars", 62738689Sborman "local recognition of certain control characters", 62832144Sminshall lclchars, 62938689Sborman &localchars, 63038689Sborman "recognize certain control characters" }, 63138689Sborman { " ", "", 0 }, /* empty line */ 63238208Sminshall #if defined(unix) && defined(TN3270) 63338920Sminshall { "apitrace", 63438920Sminshall "(debugging) toggle tracing of API transactions", 63538920Sminshall 0, 63638920Sminshall &apitrace, 63738920Sminshall "trace API transactions" }, 63838208Sminshall { "cursesdata", 63938208Sminshall "(debugging) toggle printing of hexadecimal curses data", 64038208Sminshall 0, 64138689Sborman &cursesdata, 64238689Sborman "print hexadecimal representation of curses data" }, 64338208Sminshall #endif /* defined(unix) && defined(TN3270) */ 64432144Sminshall { "debug", 64538689Sborman "debugging", 64632144Sminshall togdebug, 64738689Sborman &debug, 64838689Sborman "turn on socket level debugging" }, 64932144Sminshall { "netdata", 65038689Sborman "printing of hexadecimal network data (debugging)", 65132144Sminshall 0, 65238689Sborman &netdata, 65338689Sborman "print hexadecimal representation of network traffic" }, 65438689Sborman { "prettydump", 65538689Sborman "output of \"netdata\" to user readable format (debugging)", 65638689Sborman 0, 65738689Sborman &prettydump, 65838689Sborman "print user readable output for \"netdata\"" }, 65932144Sminshall { "options", 66038689Sborman "viewing of options processing (debugging)", 66132144Sminshall 0, 66238689Sborman &showoptions, 66338689Sborman "show option processing" }, 66438208Sminshall #if defined(unix) 66538208Sminshall { "termdata", 66638208Sminshall "(debugging) toggle printing of hexadecimal terminal data", 66738208Sminshall 0, 66838689Sborman &termdata, 66938689Sborman "print hexadecimal representation of terminal traffic" }, 67038208Sminshall #endif /* defined(unix) */ 67132144Sminshall { "?", 67238689Sborman 0, 67338689Sborman togglehelp }, 67432144Sminshall { "help", 67538689Sborman 0, 67638689Sborman togglehelp }, 67732144Sminshall { 0 } 67832144Sminshall }; 67932144Sminshall 68046808Sdab static int 68132144Sminshall togglehelp() 68232144Sminshall { 68332144Sminshall struct togglelist *c; 68432144Sminshall 68532144Sminshall for (c = Togglelist; c->name; c++) { 68638689Sborman if (c->help) { 68738689Sborman if (*c->help) 68838689Sborman printf("%-15s toggle %s\n", c->name, c->help); 68938689Sborman else 69038689Sborman printf("\n"); 69132144Sminshall } 69232144Sminshall } 69338689Sborman printf("\n"); 69438689Sborman printf("%-15s %s\n", "?", "display help information"); 69532144Sminshall return 0; 69632144Sminshall } 69732144Sminshall 69846808Sdab static void 69938689Sborman settogglehelp(set) 70046808Sdab int set; 70138689Sborman { 70238689Sborman struct togglelist *c; 70338689Sborman 70438689Sborman for (c = Togglelist; c->name; c++) { 70538689Sborman if (c->help) { 70638689Sborman if (*c->help) 70738689Sborman printf("%-15s %s %s\n", c->name, set ? "enable" : "disable", 70838689Sborman c->help); 70938689Sborman else 71038689Sborman printf("\n"); 71138689Sborman } 71238689Sborman } 71338689Sborman } 71438689Sborman 71546808Sdab #define GETTOGGLE(name) (struct togglelist *) \ 71646808Sdab genget(name, (char **) Togglelist, sizeof(struct togglelist)) 71732144Sminshall 71846808Sdab static int 71932144Sminshall toggle(argc, argv) 72046808Sdab int argc; 72146808Sdab char *argv[]; 72232144Sminshall { 72332144Sminshall int retval = 1; 72432144Sminshall char *name; 72532144Sminshall struct togglelist *c; 72632144Sminshall 72732144Sminshall if (argc < 2) { 72832144Sminshall fprintf(stderr, 72932144Sminshall "Need an argument to 'toggle' command. 'toggle ?' for help.\n"); 73032144Sminshall return 0; 73132144Sminshall } 73232144Sminshall argc--; 73332144Sminshall argv++; 73432144Sminshall while (argc--) { 73532144Sminshall name = *argv++; 73646808Sdab c = GETTOGGLE(name); 73732144Sminshall if (Ambiguous(c)) { 73832144Sminshall fprintf(stderr, "'%s': ambiguous argument ('toggle ?' for help).\n", 73932144Sminshall name); 74032144Sminshall return 0; 74132144Sminshall } else if (c == 0) { 74232144Sminshall fprintf(stderr, "'%s': unknown argument ('toggle ?' for help).\n", 74332144Sminshall name); 74432144Sminshall return 0; 74532144Sminshall } else { 74632144Sminshall if (c->variable) { 74732144Sminshall *c->variable = !*c->variable; /* invert it */ 74832144Sminshall if (c->actionexplanation) { 74932144Sminshall printf("%s %s.\n", *c->variable? "Will" : "Won't", 75032144Sminshall c->actionexplanation); 75132144Sminshall } 75232144Sminshall } 75332144Sminshall if (c->handler) { 75438689Sborman retval &= (*c->handler)(-1); 75532144Sminshall } 75632144Sminshall } 75732144Sminshall } 75832144Sminshall return retval; 75932144Sminshall } 76032144Sminshall 76132144Sminshall /* 76232144Sminshall * The following perform the "set" command. 76332144Sminshall */ 76432144Sminshall 76538689Sborman #ifdef USE_TERMIO 76638689Sborman struct termio new_tc = { 0 }; 76738689Sborman #endif 76838689Sborman 76932144Sminshall struct setlist { 77032144Sminshall char *name; /* name */ 77132144Sminshall char *help; /* help information */ 77238689Sborman void (*handler)(); 77340245Sborman cc_t *charp; /* where it is located at */ 77432144Sminshall }; 77532144Sminshall 77632144Sminshall static struct setlist Setlist[] = { 77744361Sborman #ifdef KLUDGELINEMODE 77838689Sborman { "echo", "character to toggle local echoing on/off", 0, &echoc }, 77944361Sborman #endif 78038689Sborman { "escape", "character to escape back to telnet command mode", 0, &escape }, 78146808Sdab { "rlogin", "rlogin escape character", 0, &rlogin }, 78245233Sborman { "tracefile", "file to write trace information to", SetNetTrace, (cc_t *)NetTraceFile}, 78332144Sminshall { " ", "" }, 78438689Sborman { " ", "The following need 'localchars' to be toggled true", 0, 0 }, 78545233Sborman { "flushoutput", "character to cause an Abort Output", 0, termFlushCharp }, 78638689Sborman { "interrupt", "character to cause an Interrupt Process", 0, termIntCharp }, 78738689Sborman { "quit", "character to cause an Abort process", 0, termQuitCharp }, 78838689Sborman { "eof", "character to cause an EOF ", 0, termEofCharp }, 78938689Sborman { " ", "" }, 79038689Sborman { " ", "The following are for local editing in linemode", 0, 0 }, 79138689Sborman { "erase", "character to use to erase a character", 0, termEraseCharp }, 79238689Sborman { "kill", "character to use to erase a line", 0, termKillCharp }, 79338689Sborman { "lnext", "character to use for literal next", 0, termLiteralNextCharp }, 79444361Sborman { "susp", "character to cause a Suspend Process", 0, termSuspCharp }, 79538689Sborman { "reprint", "character to use for line reprint", 0, termRprntCharp }, 79638689Sborman { "worderase", "character to use to erase a word", 0, termWerasCharp }, 79738689Sborman { "start", "character to use for XON", 0, termStartCharp }, 79844361Sborman { "stop", "character to use for XOFF", 0, termStopCharp }, 79944361Sborman { "forw1", "alternate end of line character", 0, termForw1Charp }, 80044361Sborman { "forw2", "alternate end of line character", 0, termForw2Charp }, 80145233Sborman { "ayt", "alternate AYT character", 0, termAytCharp }, 80232144Sminshall { 0 } 80332144Sminshall }; 80432144Sminshall 80545233Sborman #if defined(CRAY) && !defined(__STDC__) 80645233Sborman /* Work around compiler bug in pcc 4.1.5 */ 80746808Sdab void 80838689Sborman _setlist_init() 80938689Sborman { 81044361Sborman #ifndef KLUDGELINEMODE 81146808Sdab #define N 5 81244361Sborman #else 81346808Sdab #define N 6 81444361Sborman #endif 81544361Sborman Setlist[N+0].charp = &termFlushChar; 81644361Sborman Setlist[N+1].charp = &termIntChar; 81744361Sborman Setlist[N+2].charp = &termQuitChar; 81844361Sborman Setlist[N+3].charp = &termEofChar; 81944361Sborman Setlist[N+6].charp = &termEraseChar; 82044361Sborman Setlist[N+7].charp = &termKillChar; 82144361Sborman Setlist[N+8].charp = &termLiteralNextChar; 82244361Sborman Setlist[N+9].charp = &termSuspChar; 82344361Sborman Setlist[N+10].charp = &termRprntChar; 82444361Sborman Setlist[N+11].charp = &termWerasChar; 82544361Sborman Setlist[N+12].charp = &termStartChar; 82644361Sborman Setlist[N+13].charp = &termStopChar; 82744361Sborman Setlist[N+14].charp = &termForw1Char; 82844361Sborman Setlist[N+15].charp = &termForw2Char; 82945233Sborman Setlist[N+16].charp = &termAytChar; 83044361Sborman #undef N 83138689Sborman } 83245233Sborman #endif /* defined(CRAY) && !defined(__STDC__) */ 83338689Sborman 83446808Sdab static struct setlist * 83532144Sminshall getset(name) 83646808Sdab char *name; 83732144Sminshall { 83846808Sdab return (struct setlist *) 83946808Sdab genget(name, (char **) Setlist, sizeof(struct setlist)); 84032144Sminshall } 84132144Sminshall 84246808Sdab void 84344361Sborman set_escape_char(s) 84446808Sdab char *s; 84544361Sborman { 84646808Sdab if (rlogin != _POSIX_VDISABLE) { 84746808Sdab rlogin = (s && *s) ? special(s) : _POSIX_VDISABLE; 84846808Sdab printf("Telnet rlogin escape character is '%s'.\n", 84946808Sdab control(rlogin)); 85046808Sdab } else { 85146808Sdab escape = (s && *s) ? special(s) : _POSIX_VDISABLE; 85246808Sdab printf("Telnet escape character is '%s'.\n", control(escape)); 85346808Sdab } 85444361Sborman } 85544361Sborman 85646808Sdab static int 85732144Sminshall setcmd(argc, argv) 85846808Sdab int argc; 85946808Sdab char *argv[]; 86032144Sminshall { 86132144Sminshall int value; 86232144Sminshall struct setlist *ct; 86338689Sborman struct togglelist *c; 86432144Sminshall 86538689Sborman if (argc < 2 || argc > 3) { 86638689Sborman printf("Format is 'set Name Value'\n'set ?' for help.\n"); 86732144Sminshall return 0; 86832144Sminshall } 86946808Sdab if ((argc == 2) && (isprefix(argv[1], "?") || isprefix(argv[1], "help"))) { 87038689Sborman for (ct = Setlist; ct->name; ct++) 87138689Sborman printf("%-15s %s\n", ct->name, ct->help); 87238689Sborman printf("\n"); 87338689Sborman settogglehelp(1); 87438689Sborman printf("%-15s %s\n", "?", "display help information"); 87538689Sborman return 0; 87638689Sborman } 87732144Sminshall 87832144Sminshall ct = getset(argv[1]); 87932144Sminshall if (ct == 0) { 88046808Sdab c = GETTOGGLE(argv[1]); 88138689Sborman if (c == 0) { 88238689Sborman fprintf(stderr, "'%s': unknown argument ('set ?' for help).\n", 88332144Sminshall argv[1]); 88438689Sborman return 0; 88538689Sborman } else if (Ambiguous(c)) { 88638689Sborman fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n", 88738689Sborman argv[1]); 88838689Sborman return 0; 88938689Sborman } 89038689Sborman if (c->variable) { 89138689Sborman if ((argc == 2) || (strcmp("on", argv[2]) == 0)) 89238689Sborman *c->variable = 1; 89338689Sborman else if (strcmp("off", argv[2]) == 0) 89438689Sborman *c->variable = 0; 89538689Sborman else { 89638689Sborman printf("Format is 'set togglename [on|off]'\n'set ?' for help.\n"); 89738689Sborman return 0; 89838689Sborman } 89938689Sborman if (c->actionexplanation) { 90038689Sborman printf("%s %s.\n", *c->variable? "Will" : "Won't", 90138689Sborman c->actionexplanation); 90238689Sborman } 90338689Sborman } 90438689Sborman if (c->handler) 90538689Sborman (*c->handler)(1); 90638689Sborman } else if (argc != 3) { 90738689Sborman printf("Format is 'set Name Value'\n'set ?' for help.\n"); 90832144Sminshall return 0; 90932144Sminshall } else if (Ambiguous(ct)) { 91032144Sminshall fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n", 91132144Sminshall argv[1]); 91232144Sminshall return 0; 91338689Sborman } else if (ct->handler) { 91438689Sborman (*ct->handler)(argv[2]); 91544361Sborman printf("%s set to \"%s\".\n", ct->name, (char *)ct->charp); 91632144Sminshall } else { 91732144Sminshall if (strcmp("off", argv[2])) { 91832144Sminshall value = special(argv[2]); 91932144Sminshall } else { 92045233Sborman value = _POSIX_VDISABLE; 92132144Sminshall } 92240245Sborman *(ct->charp) = (cc_t)value; 92332144Sminshall printf("%s character is '%s'.\n", ct->name, control(*(ct->charp))); 92432144Sminshall } 92538689Sborman slc_check(); 92632144Sminshall return 1; 92732144Sminshall } 92838689Sborman 92946808Sdab static int 93038689Sborman unsetcmd(argc, argv) 93146808Sdab int argc; 93246808Sdab char *argv[]; 93338689Sborman { 93438689Sborman struct setlist *ct; 93538689Sborman struct togglelist *c; 93638689Sborman register char *name; 93738689Sborman 93838689Sborman if (argc < 2) { 93938689Sborman fprintf(stderr, 94038689Sborman "Need an argument to 'unset' command. 'unset ?' for help.\n"); 94138689Sborman return 0; 94238689Sborman } 94346808Sdab if (isprefix(argv[1], "?") || isprefix(argv[1], "help")) { 94438689Sborman for (ct = Setlist; ct->name; ct++) 94538689Sborman printf("%-15s %s\n", ct->name, ct->help); 94638689Sborman printf("\n"); 94738689Sborman settogglehelp(0); 94838689Sborman printf("%-15s %s\n", "?", "display help information"); 94938689Sborman return 0; 95038689Sborman } 95138689Sborman 95238689Sborman argc--; 95338689Sborman argv++; 95438689Sborman while (argc--) { 95538689Sborman name = *argv++; 95638689Sborman ct = getset(name); 95738689Sborman if (ct == 0) { 95846808Sdab c = GETTOGGLE(name); 95938689Sborman if (c == 0) { 96038689Sborman fprintf(stderr, "'%s': unknown argument ('unset ?' for help).\n", 96138689Sborman name); 96238689Sborman return 0; 96338689Sborman } else if (Ambiguous(c)) { 96438689Sborman fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n", 96538689Sborman name); 96638689Sborman return 0; 96738689Sborman } 96838689Sborman if (c->variable) { 96938689Sborman *c->variable = 0; 97038689Sborman if (c->actionexplanation) { 97138689Sborman printf("%s %s.\n", *c->variable? "Will" : "Won't", 97238689Sborman c->actionexplanation); 97338689Sborman } 97438689Sborman } 97538689Sborman if (c->handler) 97638689Sborman (*c->handler)(0); 97738689Sborman } else if (Ambiguous(ct)) { 97838689Sborman fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n", 97938689Sborman name); 98038689Sborman return 0; 98138689Sborman } else if (ct->handler) { 98238689Sborman (*ct->handler)(0); 98344361Sborman printf("%s reset to \"%s\".\n", ct->name, (char *)ct->charp); 98438689Sborman } else { 98545233Sborman *(ct->charp) = _POSIX_VDISABLE; 98638689Sborman printf("%s character is '%s'.\n", ct->name, control(*(ct->charp))); 98738689Sborman } 98838689Sborman } 98938689Sborman return 1; 99038689Sborman } 99132144Sminshall 99232144Sminshall /* 99332144Sminshall * The following are the data structures and routines for the 99432144Sminshall * 'mode' command. 99532144Sminshall */ 99638689Sborman #ifdef KLUDGELINEMODE 99738689Sborman extern int kludgelinemode; 99844361Sborman 99946808Sdab static int 100044361Sborman dokludgemode() 100144361Sborman { 100244361Sborman kludgelinemode = 1; 100344361Sborman send_wont(TELOPT_LINEMODE, 1); 100444361Sborman send_dont(TELOPT_SGA, 1); 100544361Sborman send_dont(TELOPT_ECHO, 1); 100644361Sborman } 100738689Sborman #endif 100832144Sminshall 100946808Sdab static int 101032144Sminshall dolinemode() 101132144Sminshall { 101238689Sborman #ifdef KLUDGELINEMODE 101338689Sborman if (kludgelinemode) 101438689Sborman send_dont(TELOPT_SGA, 1); 101538689Sborman #endif 101638689Sborman send_will(TELOPT_LINEMODE, 1); 101738689Sborman send_dont(TELOPT_ECHO, 1); 101832144Sminshall return 1; 101932144Sminshall } 102032144Sminshall 102146808Sdab static int 102232144Sminshall docharmode() 102332144Sminshall { 102438689Sborman #ifdef KLUDGELINEMODE 102538689Sborman if (kludgelinemode) 102638689Sborman send_do(TELOPT_SGA, 1); 102738689Sborman else 102838689Sborman #endif 102938689Sborman send_wont(TELOPT_LINEMODE, 1); 103038689Sborman send_do(TELOPT_ECHO, 1); 103138689Sborman return 1; 103238689Sborman } 103338689Sborman 103446808Sdab static int 103538689Sborman dolmmode(bit, on) 103646808Sdab int bit, on; 103738689Sborman { 103846808Sdab unsigned char c; 103938689Sborman extern int linemode; 104038689Sborman 104138689Sborman if (my_want_state_is_wont(TELOPT_LINEMODE)) { 104238689Sborman printf("?Need to have LINEMODE option enabled first.\n"); 104338689Sborman printf("'mode ?' for help.\n"); 104438689Sborman return 0; 104532144Sminshall } 104638689Sborman 104738689Sborman if (on) 104838689Sborman c = (linemode | bit); 104938689Sborman else 105038689Sborman c = (linemode & ~bit); 105138689Sborman lm_mode(&c, 1, 1); 105232144Sminshall return 1; 105332144Sminshall } 105432144Sminshall 105546808Sdab int 105646808Sdab setmode(bit) 105746808Sdab { 105846808Sdab return dolmmode(bit, 1); 105946808Sdab } 106046808Sdab 106146808Sdab int 106246808Sdab clearmode(bit) 106346808Sdab { 106446808Sdab return dolmmode(bit, 0); 106546808Sdab } 106646808Sdab 106738689Sborman struct modelist { 106838689Sborman char *name; /* command name */ 106938689Sborman char *help; /* help string */ 107038689Sborman int (*handler)(); /* routine which executes command */ 107138689Sborman int needconnect; /* Do we need to be connected to execute? */ 107238689Sborman int arg1; 107338689Sborman }; 107438689Sborman 107538689Sborman extern int modehelp(); 107638689Sborman 107738689Sborman static struct modelist ModeList[] = { 107838689Sborman { "character", "Disable LINEMODE option", docharmode, 1 }, 107939529Sborman #ifdef KLUDGELINEMODE 108039529Sborman { "", "(or disable obsolete line-by-line mode)", 0 }, 108138689Sborman #endif 108238689Sborman { "line", "Enable LINEMODE option", dolinemode, 1 }, 108339529Sborman #ifdef KLUDGELINEMODE 108439529Sborman { "", "(or enable obsolete line-by-line mode)", 0 }, 108538689Sborman #endif 108638689Sborman { "", "", 0 }, 108738689Sborman { "", "These require the LINEMODE option to be enabled", 0 }, 108838689Sborman { "isig", "Enable signal trapping", setmode, 1, MODE_TRAPSIG }, 108938689Sborman { "+isig", 0, setmode, 1, MODE_TRAPSIG }, 109038689Sborman { "-isig", "Disable signal trapping", clearmode, 1, MODE_TRAPSIG }, 109138689Sborman { "edit", "Enable character editing", setmode, 1, MODE_EDIT }, 109238689Sborman { "+edit", 0, setmode, 1, MODE_EDIT }, 109338689Sborman { "-edit", "Disable character editing", clearmode, 1, MODE_EDIT }, 109444361Sborman { "softtabs", "Enable tab expansion", setmode, 1, MODE_SOFT_TAB }, 109544361Sborman { "+softtabs", 0, setmode, 1, MODE_SOFT_TAB }, 109644361Sborman { "-softtabs", "Disable character editing", clearmode, 1, MODE_SOFT_TAB }, 109744361Sborman { "litecho", "Enable literal character echo", setmode, 1, MODE_LIT_ECHO }, 109844361Sborman { "+litecho", 0, setmode, 1, MODE_LIT_ECHO }, 109944361Sborman { "-litecho", "Disable literal character echo", clearmode, 1, MODE_LIT_ECHO }, 110038689Sborman { "help", 0, modehelp, 0 }, 110144361Sborman #ifdef KLUDGELINEMODE 110244361Sborman { "kludgeline", 0, dokludgemode, 1 }, 110344361Sborman #endif 110444361Sborman { "", "", 0 }, 110538689Sborman { "?", "Print help information", modehelp, 0 }, 110632144Sminshall { 0 }, 110732144Sminshall }; 110832144Sminshall 110932144Sminshall 111046808Sdab int 111138689Sborman modehelp() 111238689Sborman { 111338689Sborman struct modelist *mt; 111438689Sborman 111538689Sborman printf("format is: 'mode Mode', where 'Mode' is one of:\n\n"); 111638689Sborman for (mt = ModeList; mt->name; mt++) { 111738689Sborman if (mt->help) { 111838689Sborman if (*mt->help) 111938689Sborman printf("%-15s %s\n", mt->name, mt->help); 112038689Sborman else 112138689Sborman printf("\n"); 112238689Sborman } 112338689Sborman } 112438689Sborman return 0; 112538689Sborman } 112638689Sborman 112746808Sdab #define GETMODECMD(name) (struct modelist *) \ 112846808Sdab genget(name, (char **) ModeList, sizeof(struct modelist)) 112946808Sdab 113046808Sdab static int 113132144Sminshall modecmd(argc, argv) 113246808Sdab int argc; 113346808Sdab char *argv[]; 113432144Sminshall { 113538689Sborman struct modelist *mt; 113632144Sminshall 113738689Sborman if (argc != 2) { 113838689Sborman printf("'mode' command requires an argument\n"); 113938689Sborman printf("'mode ?' for help.\n"); 114046808Sdab } else if ((mt = GETMODECMD(argv[1])) == 0) { 114132144Sminshall fprintf(stderr, "Unknown mode '%s' ('mode ?' for help).\n", argv[1]); 114232144Sminshall } else if (Ambiguous(mt)) { 114332144Sminshall fprintf(stderr, "Ambiguous mode '%s' ('mode ?' for help).\n", argv[1]); 114438689Sborman } else if (mt->needconnect && !connected) { 114538689Sborman printf("?Need to be connected first.\n"); 114638689Sborman printf("'mode ?' for help.\n"); 114738689Sborman } else if (mt->handler) { 114838689Sborman return (*mt->handler)(mt->arg1); 114932144Sminshall } 115038689Sborman return 0; 115132144Sminshall } 115232144Sminshall 115332144Sminshall /* 115432144Sminshall * The following data structures and routines implement the 115532144Sminshall * "display" command. 115632144Sminshall */ 115732144Sminshall 115846808Sdab static int 115932144Sminshall display(argc, argv) 116046808Sdab int argc; 116146808Sdab char *argv[]; 116232144Sminshall { 116346808Sdab struct togglelist *tl; 116446808Sdab struct setlist *sl; 116546808Sdab 116632144Sminshall #define dotog(tl) if (tl->variable && tl->actionexplanation) { \ 116732144Sminshall if (*tl->variable) { \ 116832144Sminshall printf("will"); \ 116932144Sminshall } else { \ 117032144Sminshall printf("won't"); \ 117132144Sminshall } \ 117232144Sminshall printf(" %s.\n", tl->actionexplanation); \ 117332144Sminshall } 117432144Sminshall 117532144Sminshall #define doset(sl) if (sl->name && *sl->name != ' ') { \ 117638689Sborman if (sl->handler == 0) \ 117738689Sborman printf("%-15s [%s]\n", sl->name, control(*sl->charp)); \ 117838689Sborman else \ 117944361Sborman printf("%-15s \"%s\"\n", sl->name, (char *)sl->charp); \ 118032144Sminshall } 118132144Sminshall 118232144Sminshall if (argc == 1) { 118332144Sminshall for (tl = Togglelist; tl->name; tl++) { 118432144Sminshall dotog(tl); 118532144Sminshall } 118632144Sminshall printf("\n"); 118732144Sminshall for (sl = Setlist; sl->name; sl++) { 118832144Sminshall doset(sl); 118932144Sminshall } 119032144Sminshall } else { 119132144Sminshall int i; 119232144Sminshall 119332144Sminshall for (i = 1; i < argc; i++) { 119432144Sminshall sl = getset(argv[i]); 119546808Sdab tl = GETTOGGLE(argv[i]); 119632144Sminshall if (Ambiguous(sl) || Ambiguous(tl)) { 119732144Sminshall printf("?Ambiguous argument '%s'.\n", argv[i]); 119832144Sminshall return 0; 119932144Sminshall } else if (!sl && !tl) { 120032144Sminshall printf("?Unknown argument '%s'.\n", argv[i]); 120132144Sminshall return 0; 120232144Sminshall } else { 120332144Sminshall if (tl) { 120432144Sminshall dotog(tl); 120532144Sminshall } 120632144Sminshall if (sl) { 120732144Sminshall doset(sl); 120832144Sminshall } 120932144Sminshall } 121032144Sminshall } 121132144Sminshall } 121238689Sborman /*@*/optionstatus(); 121346808Sdab #if defined(ENCRYPT) 121446808Sdab EncryptStatus(); 121546808Sdab #endif 121632144Sminshall return 1; 121732144Sminshall #undef doset 121832144Sminshall #undef dotog 121932144Sminshall } 122032144Sminshall 122132144Sminshall /* 122232144Sminshall * The following are the data structures, and many of the routines, 122332144Sminshall * relating to command processing. 122432144Sminshall */ 122532144Sminshall 122632144Sminshall /* 122732144Sminshall * Set the escape character. 122832144Sminshall */ 122946808Sdab static int 123032144Sminshall setescape(argc, argv) 123132144Sminshall int argc; 123232144Sminshall char *argv[]; 123332144Sminshall { 123432144Sminshall register char *arg; 123532144Sminshall char buf[50]; 123632144Sminshall 123732144Sminshall printf( 123832144Sminshall "Deprecated usage - please use 'set escape%s%s' in the future.\n", 123932144Sminshall (argc > 2)? " ":"", (argc > 2)? argv[1]: ""); 124032144Sminshall if (argc > 2) 124132144Sminshall arg = argv[1]; 124232144Sminshall else { 124332144Sminshall printf("new escape character: "); 124446808Sdab (void) fgets(buf, sizeof(buf), stdin); 124532144Sminshall arg = buf; 124632144Sminshall } 124732144Sminshall if (arg[0] != '\0') 124832144Sminshall escape = arg[0]; 124932144Sminshall if (!In3270) { 125032144Sminshall printf("Escape character is '%s'.\n", control(escape)); 125132144Sminshall } 125234849Sminshall (void) fflush(stdout); 125332144Sminshall return 1; 125432144Sminshall } 125532144Sminshall 125646808Sdab /*VARARGS*/ 125746808Sdab static int 125832144Sminshall togcrmod() 125932144Sminshall { 126032144Sminshall crmod = !crmod; 126132144Sminshall printf("Deprecated usage - please use 'toggle crmod' in the future.\n"); 126232144Sminshall printf("%s map carriage return on output.\n", crmod ? "Will" : "Won't"); 126334849Sminshall (void) fflush(stdout); 126432144Sminshall return 1; 126532144Sminshall } 126632144Sminshall 126746808Sdab /*VARARGS*/ 126846808Sdab int 126932144Sminshall suspend() 127032144Sminshall { 127138689Sborman #ifdef SIGTSTP 127237219Sminshall setcommandmode(); 127337219Sminshall { 127444361Sborman long oldrows, oldcols, newrows, newcols, err; 127537219Sminshall 127644361Sborman err = TerminalWindowSize(&oldrows, &oldcols); 127734849Sminshall (void) kill(0, SIGTSTP); 127844361Sborman err += TerminalWindowSize(&newrows, &newcols); 127944361Sborman if (connected && !err && 128044361Sborman ((oldrows != newrows) || (oldcols != newcols))) { 128137219Sminshall sendnaws(); 128237219Sminshall } 128337219Sminshall } 128437219Sminshall /* reget parameters in case they were changed */ 128537219Sminshall TerminalSaveState(); 128638689Sborman setconnmode(0); 128738689Sborman #else 128838689Sborman printf("Suspend is not supported. Try the '!' command instead\n"); 128938689Sborman #endif 129037219Sminshall return 1; 129132144Sminshall } 129232144Sminshall 129338689Sborman #if !defined(TN3270) 129446808Sdab /*ARGSUSED*/ 129546808Sdab int 129638689Sborman shell(argc, argv) 129746808Sdab int argc; 129846808Sdab char *argv[]; 129938689Sborman { 130038689Sborman setcommandmode(); 130138689Sborman switch(vfork()) { 130238689Sborman case -1: 130338689Sborman perror("Fork failed\n"); 130438689Sborman break; 130538689Sborman 130638689Sborman case 0: 130738689Sborman { 130838689Sborman /* 130938689Sborman * Fire up the shell in the child. 131038689Sborman */ 131146808Sdab register char *shellp, *shellname; 131246808Sdab extern char *rindex(); 131338689Sborman 131446808Sdab shellp = getenv("SHELL"); 131546808Sdab if (shellp == NULL) 131646808Sdab shellp = "/bin/sh"; 131746808Sdab if ((shellname = rindex(shellp, '/')) == 0) 131846808Sdab shellname = shellp; 131938689Sborman else 132038689Sborman shellname++; 132138689Sborman if (argc > 1) 132246808Sdab execl(shellp, shellname, "-c", &saveline[1], 0); 132338689Sborman else 132446808Sdab execl(shellp, shellname, 0); 132538689Sborman perror("Execl"); 132638689Sborman _exit(1); 132738689Sborman } 132838689Sborman default: 132944361Sborman (void)wait((int *)0); /* Wait for the shell to complete */ 133038689Sborman } 133146808Sdab return 1; 133238689Sborman } 133338689Sborman #endif /* !defined(TN3270) */ 133438689Sborman 133546808Sdab /*VARARGS*/ 133646808Sdab static 133732144Sminshall bye(argc, argv) 133846808Sdab int argc; /* Number of arguments */ 133946808Sdab char *argv[]; /* arguments */ 134032144Sminshall { 134146808Sdab extern int resettermname; 134246808Sdab 134332144Sminshall if (connected) { 134434849Sminshall (void) shutdown(net, 2); 134532144Sminshall printf("Connection closed.\n"); 134634849Sminshall (void) NetClose(net); 134732144Sminshall connected = 0; 134846808Sdab resettermname = 1; 134946808Sdab #if defined(AUTHENTICATE) || defined(ENCRYPT) 135046808Sdab auth_encrypt_connect(connected); 135146808Sdab #endif 135232144Sminshall /* reset options */ 135332144Sminshall tninit(); 135432144Sminshall #if defined(TN3270) 135532144Sminshall SetIn3270(); /* Get out of 3270 mode */ 135632144Sminshall #endif /* defined(TN3270) */ 135732144Sminshall } 135832144Sminshall if ((argc != 2) || (strcmp(argv[1], "fromquit") != 0)) { 135932144Sminshall longjmp(toplevel, 1); 136032144Sminshall /* NOTREACHED */ 136132144Sminshall } 136232144Sminshall return 1; /* Keep lint, etc., happy */ 136332144Sminshall } 136432144Sminshall 136532144Sminshall /*VARARGS*/ 136632144Sminshall quit() 136732144Sminshall { 136832144Sminshall (void) call(bye, "bye", "fromquit", 0); 136932144Sminshall Exit(0); 137044361Sborman /*NOTREACHED*/ 137132144Sminshall } 137246808Sdab 137346808Sdab /*VARARGS*/ 137446808Sdab int 137546808Sdab logout() 137646808Sdab { 137746808Sdab send_do(TELOPT_LOGOUT, 1); 137846808Sdab (void) netflush(); 137946808Sdab return 1; 138046808Sdab } 138146808Sdab 138238689Sborman 138338689Sborman /* 138438689Sborman * The SLC command. 138538689Sborman */ 138632144Sminshall 138738689Sborman struct slclist { 138838689Sborman char *name; 138938689Sborman char *help; 139046808Sdab void (*handler)(); 139138689Sborman int arg; 139238689Sborman }; 139338689Sborman 139446808Sdab extern void slc_help(); 139538689Sborman 139638689Sborman struct slclist SlcList[] = { 139738689Sborman { "export", "Use local special character definitions", 139838689Sborman slc_mode_export, 0 }, 139938689Sborman { "import", "Use remote special character definitions", 140038689Sborman slc_mode_import, 1 }, 140138689Sborman { "check", "Verify remote special character definitions", 140238689Sborman slc_mode_import, 0 }, 140338689Sborman { "help", 0, slc_help, 0 }, 140438689Sborman { "?", "Print help information", slc_help, 0 }, 140538689Sborman { 0 }, 140638689Sborman }; 140738689Sborman 140846808Sdab static void 140938689Sborman slc_help() 141038689Sborman { 141138689Sborman struct slclist *c; 141238689Sborman 141338689Sborman for (c = SlcList; c->name; c++) { 141438689Sborman if (c->help) { 141538689Sborman if (*c->help) 141638689Sborman printf("%-15s %s\n", c->name, c->help); 141738689Sborman else 141838689Sborman printf("\n"); 141938689Sborman } 142038689Sborman } 142138689Sborman } 142238689Sborman 142346808Sdab static struct slclist * 142438689Sborman getslc(name) 142546808Sdab char *name; 142638689Sborman { 142746808Sdab return (struct slclist *) 142846808Sdab genget(name, (char **) SlcList, sizeof(struct slclist)); 142938689Sborman } 143038689Sborman 143146808Sdab static 143238689Sborman slccmd(argc, argv) 143346808Sdab int argc; 143446808Sdab char *argv[]; 143538689Sborman { 143638689Sborman struct slclist *c; 143738689Sborman 143838689Sborman if (argc != 2) { 143938689Sborman fprintf(stderr, 144038689Sborman "Need an argument to 'slc' command. 'slc ?' for help.\n"); 144138689Sborman return 0; 144238689Sborman } 144338689Sborman c = getslc(argv[1]); 144438689Sborman if (c == 0) { 144538689Sborman fprintf(stderr, "'%s': unknown argument ('slc ?' for help).\n", 144638689Sborman argv[1]); 144738689Sborman return 0; 144838689Sborman } 144938689Sborman if (Ambiguous(c)) { 145038689Sborman fprintf(stderr, "'%s': ambiguous argument ('slc ?' for help).\n", 145138689Sborman argv[1]); 145238689Sborman return 0; 145338689Sborman } 145438689Sborman (*c->handler)(c->arg); 145538689Sborman slcstate(); 145638689Sborman return 1; 145738689Sborman } 145844361Sborman 145944361Sborman /* 146044361Sborman * The ENVIRON command. 146144361Sborman */ 146238689Sborman 146344361Sborman struct envlist { 146444361Sborman char *name; 146544361Sborman char *help; 146646808Sdab void (*handler)(); 146744361Sborman int narg; 146844361Sborman }; 146944361Sborman 147046808Sdab extern struct env_lst * 147146808Sdab env_define P((unsigned char *, unsigned char *)); 147246808Sdab extern void 147346808Sdab env_undefine P((unsigned char *)), 147446808Sdab env_export P((unsigned char *)), 147546808Sdab env_unexport P((unsigned char *)), 147646808Sdab env_send P((unsigned char *)), 147746808Sdab env_list P((void)), 147846808Sdab env_help P((void)); 147944361Sborman 148044361Sborman struct envlist EnvList[] = { 148144361Sborman { "define", "Define an environment variable", 148246808Sdab (void (*)())env_define, 2 }, 148344361Sborman { "undefine", "Undefine an environment variable", 148444361Sborman env_undefine, 1 }, 148544361Sborman { "export", "Mark an environment variable for automatic export", 148644361Sborman env_export, 1 }, 148746808Sdab { "unexport", "Don't mark an environment variable for automatic export", 148844361Sborman env_unexport, 1 }, 148945233Sborman { "send", "Send an environment variable", env_send, 1 }, 149044361Sborman { "list", "List the current environment variables", 149144361Sborman env_list, 0 }, 149244361Sborman { "help", 0, env_help, 0 }, 149344361Sborman { "?", "Print help information", env_help, 0 }, 149444361Sborman { 0 }, 149544361Sborman }; 149644361Sborman 149746808Sdab static void 149844361Sborman env_help() 149944361Sborman { 150044361Sborman struct envlist *c; 150144361Sborman 150244361Sborman for (c = EnvList; c->name; c++) { 150344361Sborman if (c->help) { 150444361Sborman if (*c->help) 150544361Sborman printf("%-15s %s\n", c->name, c->help); 150644361Sborman else 150744361Sborman printf("\n"); 150844361Sborman } 150944361Sborman } 151044361Sborman } 151144361Sborman 151246808Sdab static struct envlist * 151344361Sborman getenvcmd(name) 151446808Sdab char *name; 151544361Sborman { 151646808Sdab return (struct envlist *) 151746808Sdab genget(name, (char **) EnvList, sizeof(struct envlist)); 151844361Sborman } 151944361Sborman 152044361Sborman env_cmd(argc, argv) 152146808Sdab int argc; 152246808Sdab char *argv[]; 152344361Sborman { 152444361Sborman struct envlist *c; 152544361Sborman 152644361Sborman if (argc < 2) { 152744361Sborman fprintf(stderr, 152844361Sborman "Need an argument to 'environ' command. 'environ ?' for help.\n"); 152944361Sborman return 0; 153044361Sborman } 153144361Sborman c = getenvcmd(argv[1]); 153244361Sborman if (c == 0) { 153344361Sborman fprintf(stderr, "'%s': unknown argument ('environ ?' for help).\n", 153444361Sborman argv[1]); 153544361Sborman return 0; 153644361Sborman } 153744361Sborman if (Ambiguous(c)) { 153844361Sborman fprintf(stderr, "'%s': ambiguous argument ('environ ?' for help).\n", 153944361Sborman argv[1]); 154044361Sborman return 0; 154144361Sborman } 154244361Sborman if (c->narg + 2 != argc) { 154344361Sborman fprintf(stderr, 154444361Sborman "Need %s%d argument%s to 'environ %s' command. 'environ ?' for help.\n", 154544361Sborman c->narg < argc + 2 ? "only " : "", 154644361Sborman c->narg, c->narg == 1 ? "" : "s", c->name); 154744361Sborman return 0; 154844361Sborman } 154946808Sdab (*c->handler)(argv[2], argv[3]); 155044361Sborman return 1; 155144361Sborman } 155244361Sborman 155344361Sborman struct env_lst { 155444361Sborman struct env_lst *next; /* pointer to next structure */ 155544361Sborman struct env_lst *prev; /* pointer to next structure */ 155646808Sdab unsigned char *var; /* pointer to variable name */ 155746808Sdab unsigned char *value; /* pointer to varialbe value */ 155844361Sborman int export; /* 1 -> export with default list of variables */ 155944361Sborman }; 156044361Sborman 156144361Sborman struct env_lst envlisthead; 156244361Sborman 156346808Sdab struct env_lst * 156444361Sborman env_find(var) 156546808Sdab unsigned char *var; 156644361Sborman { 156744361Sborman register struct env_lst *ep; 156844361Sborman 156944361Sborman for (ep = envlisthead.next; ep; ep = ep->next) { 157046808Sdab if (strcmp((char *)ep->var, (char *)var) == 0) 157144361Sborman return(ep); 157244361Sborman } 157344361Sborman return(NULL); 157444361Sborman } 157544361Sborman 157646808Sdab void 157744361Sborman env_init() 157844361Sborman { 157946808Sdab extern char **environ; 158044361Sborman register char **epp, *cp; 158144361Sborman register struct env_lst *ep; 158246808Sdab extern char *index(); 158344361Sborman 158444361Sborman for (epp = environ; *epp; epp++) { 158544361Sborman if (cp = index(*epp, '=')) { 158644361Sborman *cp = '\0'; 158746808Sdab ep = env_define((unsigned char *)*epp, 158846808Sdab (unsigned char *)cp+1); 158944361Sborman ep->export = 0; 159044361Sborman *cp = '='; 159144361Sborman } 159244361Sborman } 159344361Sborman /* 159444361Sborman * Special case for DISPLAY variable. If it is ":0.0" or 159544361Sborman * "unix:0.0", we have to get rid of "unix" and insert our 159644361Sborman * hostname. 159744361Sborman */ 159846808Sdab if ((ep = env_find("DISPLAY")) 159946808Sdab && ((*ep->value == ':') 160046808Sdab || (strncmp((char *)ep->value, "unix:", 5) == 0))) { 160144361Sborman char hbuf[256+1]; 160246808Sdab char *cp2 = index((char *)ep->value, ':'); 160344361Sborman 160444361Sborman gethostname(hbuf, 256); 160544361Sborman hbuf[256] = '\0'; 160644361Sborman cp = (char *)malloc(strlen(hbuf) + strlen(cp2) + 1); 160746808Sdab sprintf((char *)cp, "%s%s", hbuf, cp2); 160844361Sborman free(ep->value); 160946808Sdab ep->value = (unsigned char *)cp; 161044361Sborman } 161144361Sborman /* 161244361Sborman * If USER is not defined, but LOGNAME is, then add 161345233Sborman * USER with the value from LOGNAME. By default, we 161445233Sborman * don't export the USER variable. 161544361Sborman */ 161645233Sborman if ((env_find("USER") == NULL) && (ep = env_find("LOGNAME"))) { 161746808Sdab env_define((unsigned char *)"USER", ep->value); 161846808Sdab env_unexport((unsigned char *)"USER"); 161945233Sborman } 162046808Sdab env_export((unsigned char *)"DISPLAY"); 162146808Sdab env_export((unsigned char *)"PRINTER"); 162244361Sborman } 162344361Sborman 162446808Sdab struct env_lst * 162544361Sborman env_define(var, value) 162646808Sdab unsigned char *var, *value; 162744361Sborman { 162844361Sborman register struct env_lst *ep; 162944361Sborman 163044361Sborman if (ep = env_find(var)) { 163144361Sborman if (ep->var) 163244361Sborman free(ep->var); 163344361Sborman if (ep->value) 163444361Sborman free(ep->value); 163544361Sborman } else { 163644361Sborman ep = (struct env_lst *)malloc(sizeof(struct env_lst)); 163744361Sborman ep->next = envlisthead.next; 163844361Sborman envlisthead.next = ep; 163944361Sborman ep->prev = &envlisthead; 164044361Sborman if (ep->next) 164144361Sborman ep->next->prev = ep; 164244361Sborman } 164345009Skarels ep->export = 1; 164446808Sdab ep->var = (unsigned char *)strdup((char *)var); 164546808Sdab ep->value = (unsigned char *)strdup((char *)value); 164644361Sborman return(ep); 164744361Sborman } 164844361Sborman 164946808Sdab void 165044361Sborman env_undefine(var) 165146808Sdab unsigned char *var; 165244361Sborman { 165344361Sborman register struct env_lst *ep; 165444361Sborman 165544361Sborman if (ep = env_find(var)) { 165644361Sborman ep->prev->next = ep->next; 165745233Sborman if (ep->next) 165845233Sborman ep->next->prev = ep->prev; 165944361Sborman if (ep->var) 166044361Sborman free(ep->var); 166144361Sborman if (ep->value) 166244361Sborman free(ep->value); 166344361Sborman free(ep); 166444361Sborman } 166544361Sborman } 166644361Sborman 166746808Sdab void 166844361Sborman env_export(var) 166946808Sdab unsigned char *var; 167044361Sborman { 167144361Sborman register struct env_lst *ep; 167244361Sborman 167344361Sborman if (ep = env_find(var)) 167444361Sborman ep->export = 1; 167544361Sborman } 167644361Sborman 167746808Sdab void 167844361Sborman env_unexport(var) 167946808Sdab unsigned char *var; 168044361Sborman { 168144361Sborman register struct env_lst *ep; 168244361Sborman 168344361Sborman if (ep = env_find(var)) 168444361Sborman ep->export = 0; 168544361Sborman } 168644361Sborman 168746808Sdab void 168845233Sborman env_send(var) 168946808Sdab unsigned char *var; 169045233Sborman { 169145233Sborman register struct env_lst *ep; 169245233Sborman 169345233Sborman if (my_state_is_wont(TELOPT_ENVIRON)) { 169445233Sborman fprintf(stderr, 169545233Sborman "Cannot send '%s': Telnet ENVIRON option not enabled\n", 169645233Sborman var); 169745233Sborman return; 169845233Sborman } 169945233Sborman ep = env_find(var); 170045233Sborman if (ep == 0) { 170145233Sborman fprintf(stderr, "Cannot send '%s': variable not defined\n", 170245233Sborman var); 170345233Sborman return; 170445233Sborman } 170545233Sborman env_opt_start_info(); 170645233Sborman env_opt_add(ep->var); 170745233Sborman env_opt_end(0); 170845233Sborman } 170945233Sborman 171046808Sdab void 171144361Sborman env_list() 171244361Sborman { 171344361Sborman register struct env_lst *ep; 171444361Sborman 171544361Sborman for (ep = envlisthead.next; ep; ep = ep->next) { 171644361Sborman printf("%c %-20s %s\n", ep->export ? '*' : ' ', 171744361Sborman ep->var, ep->value); 171844361Sborman } 171944361Sborman } 172044361Sborman 172146808Sdab unsigned char * 172244361Sborman env_default(init) 172346808Sdab int init; 172444361Sborman { 172544361Sborman static struct env_lst *nep = NULL; 172644361Sborman 172744361Sborman if (init) { 172844361Sborman nep = &envlisthead; 172944361Sborman return; 173044361Sborman } 173144361Sborman if (nep) { 173244361Sborman while (nep = nep->next) { 173344361Sborman if (nep->export) 173444361Sborman return(nep->var); 173544361Sborman } 173644361Sborman } 173744361Sborman return(NULL); 173844361Sborman } 173944361Sborman 174046808Sdab unsigned char * 174144361Sborman env_getvalue(var) 174246808Sdab unsigned char *var; 174344361Sborman { 174444361Sborman register struct env_lst *ep; 174544361Sborman 174644361Sborman if (ep = env_find(var)) 174744361Sborman return(ep->value); 174844361Sborman return(NULL); 174944361Sborman } 175044361Sborman 175146808Sdab #if defined(AUTHENTICATE) 175246808Sdab /* 175346808Sdab * The AUTHENTICATE command. 175446808Sdab */ 175546808Sdab 175646808Sdab struct authlist { 175746808Sdab char *name; 175846808Sdab char *help; 175946808Sdab int (*handler)(); 176046808Sdab int narg; 176146808Sdab }; 176246808Sdab 176346808Sdab extern int 176446808Sdab auth_enable P((int)), 176546808Sdab auth_disable P((int)), 176646808Sdab auth_status P((void)), 176746808Sdab auth_togdebug P((void)), 176846808Sdab auth_help P((void)); 176946808Sdab 177046808Sdab struct authlist AuthList[] = { 177146808Sdab { "status", "Display current status of authentication information", 177246808Sdab auth_status, 0 }, 177346808Sdab { "debug", "Toggle authentication debugging", 177446808Sdab auth_togdebug, 0 }, 177546808Sdab { "disable", "Disable an authentication type ('auth disable ?' for more)", 177646808Sdab auth_disable, 1 }, 177746808Sdab { "enable", "Enable an authentication type ('auth enable ?' for more)", 177846808Sdab auth_enable, 1 }, 177946808Sdab { "help", 0, auth_help, 0 }, 178046808Sdab { "?", "Print help information", auth_help, 0 }, 178146808Sdab { 0 }, 178246808Sdab }; 178346808Sdab 178446808Sdab static int 178546808Sdab auth_help() 178644361Sborman { 178746808Sdab struct authlist *c; 178846808Sdab 178946808Sdab for (c = AuthList; c->name; c++) { 179046808Sdab if (c->help) { 179146808Sdab if (*c->help) 179246808Sdab printf("%-15s %s\n", c->name, c->help); 179346808Sdab else 179446808Sdab printf("\n"); 179546808Sdab } 179646808Sdab } 179746808Sdab return 0; 179844361Sborman } 179946808Sdab 180046808Sdab auth_cmd(argc, argv) 180146808Sdab int argc; 180246808Sdab char *argv[]; 180346808Sdab { 180446808Sdab struct authlist *c; 180546808Sdab 180646808Sdab c = (struct authlist *) 180746808Sdab genget(argv[1], (char **) AuthList, sizeof(struct authlist)); 180846808Sdab if (c == 0) { 180946808Sdab fprintf(stderr, "'%s': unknown argument ('auth ?' for help).\n", 181046808Sdab argv[1]); 181146808Sdab return 0; 181246808Sdab } 181346808Sdab if (Ambiguous(c)) { 181446808Sdab fprintf(stderr, "'%s': ambiguous argument ('auth ?' for help).\n", 181546808Sdab argv[1]); 181646808Sdab return 0; 181746808Sdab } 181846808Sdab if (c->narg + 2 != argc) { 181946808Sdab fprintf(stderr, 182046808Sdab "Need %s%d argument%s to 'auth %s' command. 'auth ?' for help.\n", 182146808Sdab c->narg < argc + 2 ? "only " : "", 182246808Sdab c->narg, c->narg == 1 ? "" : "s", c->name); 182346808Sdab return 0; 182446808Sdab } 182546808Sdab return((*c->handler)(argv[2], argv[3])); 182646808Sdab } 182745233Sborman #endif 182844361Sborman 182946808Sdab #if defined(ENCRYPT) 183032144Sminshall /* 183146808Sdab * The ENCRYPT command. 183236274Sminshall */ 183336274Sminshall 183446808Sdab struct encryptlist { 183546808Sdab char *name; 183646808Sdab char *help; 183746808Sdab int (*handler)(); 183846808Sdab int needconnect; 183946808Sdab int minarg; 184046808Sdab int maxarg; 184146808Sdab }; 184246808Sdab 184346808Sdab extern int 184446808Sdab EncryptEnable P((char *, char *)), 184546808Sdab EncryptType P((char *, char *)), 184646808Sdab EncryptStart P((char *)), 184746808Sdab EncryptStartInput P((void)), 184846808Sdab EncryptStartOutput P((void)), 184946808Sdab EncryptStop P((char *)), 185046808Sdab EncryptStopInput P((void)), 185146808Sdab EncryptStopOutput P((void)), 185246808Sdab EncryptTogAuto P((void)), 185346808Sdab EncryptTogDebug P((void)), 185446808Sdab EncryptTogVerbose P((void)), 185546808Sdab EncryptStatus P((void)), 185646808Sdab EncryptHelp P((void)); 185746808Sdab 185846808Sdab struct encryptlist EncryptList[] = { 185946808Sdab { "enable", "Enable encryption. ('encrypt enable ?' for more)", 186046808Sdab EncryptEnable, 1, 1, 2 }, 186146808Sdab { "type", "Set encryptiong type. ('encrypt type ?' for more)", 186246808Sdab EncryptType, 0, 1, 1 }, 186346808Sdab { "start", "Start encryption. ('encrypt start ?' for more)", 186446808Sdab EncryptStart, 1, 0, 1 }, 186546808Sdab { "stop", "Stop encryption. ('encrypt stop ?' for more)", 186646808Sdab EncryptStop, 1, 0, 1 }, 186746808Sdab { "input", "Start encrypting the input stream", 186846808Sdab EncryptStartInput, 1, 0, 0 }, 186946808Sdab { "-input", "Stop encrypting the input stream", 187046808Sdab EncryptStopInput, 1, 0, 0 }, 187146808Sdab { "output", "Start encrypting the output stream", 187246808Sdab EncryptStartOutput, 1, 0, 0 }, 187346808Sdab { "-output", "Stop encrypting the output stream", 187446808Sdab EncryptStopOutput, 1, 0, 0 }, 187546808Sdab 187646808Sdab { "status", "Display current status of authentication information", 187746808Sdab EncryptStatus, 0, 0, 0 }, 187846808Sdab { "auto", "Toggle automatic enabling of encryption", 187946808Sdab EncryptTogAuto, 0, 0, 0 }, 188046808Sdab { "verbose", "Toggle verbose encryption output", 188146808Sdab EncryptTogVerbose, 0, 0, 0 }, 188246808Sdab { "debug", "Toggle encryption debugging", 188346808Sdab EncryptTogDebug, 0, 0, 0 }, 188446808Sdab { "help", 0, EncryptHelp, 0, 0, 0 }, 188546808Sdab { "?", "Print help information", EncryptHelp, 0, 0, 0 }, 188646808Sdab { 0 }, 188746808Sdab }; 188846808Sdab 188946808Sdab static int 189046808Sdab EncryptHelp() 189136274Sminshall { 189246808Sdab struct encryptlist *c; 189346808Sdab 189446808Sdab for (c = EncryptList; c->name; c++) { 189546808Sdab if (c->help) { 189646808Sdab if (*c->help) 189746808Sdab printf("%-15s %s\n", c->name, c->help); 189846808Sdab else 189946808Sdab printf("\n"); 190036274Sminshall } 190146808Sdab } 190246808Sdab return 0; 190346808Sdab } 190436274Sminshall 190546808Sdab encrypt_cmd(argc, argv) 190646808Sdab int argc; 190746808Sdab char *argv[]; 190846808Sdab { 190946808Sdab struct encryptlist *c; 191036274Sminshall 191146808Sdab c = (struct encryptlist *) 191246808Sdab genget(argv[1], (char **) EncryptList, sizeof(struct encryptlist)); 191346808Sdab if (c == 0) { 191446808Sdab fprintf(stderr, "'%s': unknown argument ('encrypt ?' for help).\n", 191546808Sdab argv[1]); 191646808Sdab return 0; 191746808Sdab } 191846808Sdab if (Ambiguous(c)) { 191946808Sdab fprintf(stderr, "'%s': ambiguous argument ('encrypt ?' for help).\n", 192046808Sdab argv[1]); 192146808Sdab return 0; 192246808Sdab } 192346808Sdab argc -= 2; 192446808Sdab if (argc < c->minarg || argc > c->maxarg) { 192546808Sdab if (c->minarg == c->maxarg) { 192646808Sdab fprintf(stderr, "Need %s%d argument%s ", 192746808Sdab c->minarg < argc ? "only " : "", c->minarg, 192846808Sdab c->minarg == 1 ? "" : "s"); 192946808Sdab } else { 193046808Sdab fprintf(stderr, "Need %s%d-%d arguments ", 193146808Sdab c->maxarg < argc ? "only " : "", c->minarg, c->maxarg); 193246808Sdab } 193346808Sdab fprintf(stderr, "to 'encrypt %s' command. 'encrypt ?' for help.\n", 193446808Sdab c->name); 193546808Sdab return 0; 193646808Sdab } 193746808Sdab if (c->needconnect && !connected) { 193846808Sdab if (!(argc && (isprefix(argv[2], "help") || isprefix(argv[2], "?")))) { 193946808Sdab printf("?Need to be connected first.\n"); 194046808Sdab return 0; 194146808Sdab } 194246808Sdab } 194346808Sdab return ((*c->handler)(argc > 0 ? argv[2] : 0, 194446808Sdab argc > 1 ? argv[3] : 0, 194546808Sdab argc > 2 ? argv[4] : 0)); 194646808Sdab } 194736274Sminshall #endif 194836274Sminshall 194946808Sdab #if defined(unix) && defined(TN3270) 195046808Sdab static void 195136274Sminshall filestuff(fd) 195246808Sdab int fd; 195336274Sminshall { 195436274Sminshall int res; 195536274Sminshall 195638689Sborman #ifdef F_GETOWN 195738689Sborman setconnmode(0); 195836274Sminshall res = fcntl(fd, F_GETOWN, 0); 195936274Sminshall setcommandmode(); 196036274Sminshall 196136274Sminshall if (res == -1) { 196236274Sminshall perror("fcntl"); 196336274Sminshall return; 196436274Sminshall } 196536274Sminshall printf("\tOwner is %d.\n", res); 196638689Sborman #endif 196736274Sminshall 196838689Sborman setconnmode(0); 196936274Sminshall res = fcntl(fd, F_GETFL, 0); 197036274Sminshall setcommandmode(); 197136274Sminshall 197236274Sminshall if (res == -1) { 197336274Sminshall perror("fcntl"); 197436274Sminshall return; 197536274Sminshall } 197636274Sminshall printf("\tFlags are 0x%x: %s\n", res, decodeflags(res)); 197736274Sminshall } 197846808Sdab #endif /* defined(unix) && defined(TN3270) */ 197936274Sminshall 198036274Sminshall /* 198132144Sminshall * Print status about the connection. 198232144Sminshall */ 198346808Sdab /*ARGSUSED*/ 198446808Sdab static 198532144Sminshall status(argc, argv) 198646808Sdab int argc; 198746808Sdab char *argv[]; 198832144Sminshall { 198932144Sminshall if (connected) { 199032144Sminshall printf("Connected to %s.\n", hostname); 199136242Sminshall if ((argc < 2) || strcmp(argv[1], "notmuch")) { 199238689Sborman int mode = getconnmode(); 199338689Sborman 199438689Sborman if (my_want_state_is_will(TELOPT_LINEMODE)) { 199538689Sborman printf("Operating with LINEMODE option\n"); 199638689Sborman printf("%s line editing\n", (mode&MODE_EDIT) ? "Local" : "No"); 199738689Sborman printf("%s catching of signals\n", 199838689Sborman (mode&MODE_TRAPSIG) ? "Local" : "No"); 199938689Sborman slcstate(); 200038689Sborman #ifdef KLUDGELINEMODE 200139529Sborman } else if (kludgelinemode && my_want_state_is_dont(TELOPT_SGA)) { 200238689Sborman printf("Operating in obsolete linemode\n"); 200338689Sborman #endif 200438689Sborman } else { 200538689Sborman printf("Operating in single character mode\n"); 200638689Sborman if (localchars) 200738689Sborman printf("Catching signals locally\n"); 200832144Sminshall } 200938689Sborman printf("%s character echo\n", (mode&MODE_ECHO) ? "Local" : "Remote"); 201038689Sborman if (my_want_state_is_will(TELOPT_LFLOW)) 201138689Sborman printf("%s flow control\n", (mode&MODE_FLOW) ? "Local" : "No"); 201246808Sdab #if defined(ENCRYPT) 201346808Sdab encrypt_display(); 201446808Sdab #endif 201532144Sminshall } 201632144Sminshall } else { 201732144Sminshall printf("No connection.\n"); 201832144Sminshall } 201932144Sminshall # if !defined(TN3270) 202032144Sminshall printf("Escape character is '%s'.\n", control(escape)); 202134849Sminshall (void) fflush(stdout); 202232144Sminshall # else /* !defined(TN3270) */ 202332144Sminshall if ((!In3270) && ((argc < 2) || strcmp(argv[1], "notmuch"))) { 202432144Sminshall printf("Escape character is '%s'.\n", control(escape)); 202532144Sminshall } 202632144Sminshall # if defined(unix) 202736242Sminshall if ((argc >= 2) && !strcmp(argv[1], "everything")) { 202836242Sminshall printf("SIGIO received %d time%s.\n", 202936242Sminshall sigiocount, (sigiocount == 1)? "":"s"); 203036274Sminshall if (In3270) { 203136274Sminshall printf("Process ID %d, process group %d.\n", 203236274Sminshall getpid(), getpgrp(getpid())); 203336274Sminshall printf("Terminal input:\n"); 203436274Sminshall filestuff(tin); 203536274Sminshall printf("Terminal output:\n"); 203636274Sminshall filestuff(tout); 203736274Sminshall printf("Network socket:\n"); 203836274Sminshall filestuff(net); 203936274Sminshall } 204036242Sminshall } 204132144Sminshall if (In3270 && transcom) { 204232144Sminshall printf("Transparent mode command is '%s'.\n", transcom); 204332144Sminshall } 204432144Sminshall # endif /* defined(unix) */ 204534849Sminshall (void) fflush(stdout); 204632144Sminshall if (In3270) { 204732144Sminshall return 0; 204832144Sminshall } 204932144Sminshall # endif /* defined(TN3270) */ 205032144Sminshall return 1; 205132144Sminshall } 205232144Sminshall 205345233Sborman #ifdef SIGINFO 205445233Sborman /* 205545233Sborman * Function that gets called when SIGINFO is received. 205645233Sborman */ 205745233Sborman ayt_status() 205845233Sborman { 205945233Sborman (void) call(status, "status", "notmuch", 0); 206045233Sborman } 206145233Sborman #endif 206232144Sminshall 206346808Sdab int 206432144Sminshall tn(argc, argv) 206546808Sdab int argc; 206646808Sdab char *argv[]; 206732144Sminshall { 206832144Sminshall register struct hostent *host = 0; 206932144Sminshall struct sockaddr_in sin; 207032144Sminshall struct servent *sp = 0; 207138689Sborman unsigned long temp, inet_addr(); 207237219Sminshall extern char *inet_ntoa(); 207346808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 207438689Sborman char *srp = 0, *strrchr(); 207538689Sborman unsigned long sourceroute(), srlen; 207638689Sborman #endif 207744361Sborman char *cmd, *hostp = 0, *portp = 0, *user = 0; 207832144Sminshall 207945233Sborman /* clear the socket address prior to use */ 208045233Sborman bzero((char *)&sin, sizeof(sin)); 208132144Sminshall 208232144Sminshall if (connected) { 208332144Sminshall printf("?Already connected to %s\n", hostname); 208446808Sdab setuid(getuid()); 208532144Sminshall return 0; 208632144Sminshall } 208732144Sminshall if (argc < 2) { 208846808Sdab (void) strcpy(line, "open "); 208932144Sminshall printf("(to) "); 209046808Sdab (void) fgets(&line[strlen(line)], sizeof(line) - strlen(line), stdin); 209132144Sminshall makeargv(); 209232144Sminshall argc = margc; 209332144Sminshall argv = margv; 209432144Sminshall } 209544361Sborman cmd = *argv; 209644361Sborman --argc; ++argv; 209744361Sborman while (argc) { 209846808Sdab if (isprefix(*argv, "help") || isprefix(*argv, "?")) 209946808Sdab goto usage; 210044361Sborman if (strcmp(*argv, "-l") == 0) { 210144361Sborman --argc; ++argv; 210244361Sborman if (argc == 0) 210344361Sborman goto usage; 210444361Sborman user = *argv++; 210544361Sborman --argc; 210644361Sborman continue; 210744361Sborman } 210845233Sborman if (strcmp(*argv, "-a") == 0) { 210945233Sborman --argc; ++argv; 211045233Sborman autologin = 1; 211145233Sborman continue; 211245233Sborman } 211344361Sborman if (hostp == 0) { 211444361Sborman hostp = *argv++; 211544361Sborman --argc; 211644361Sborman continue; 211744361Sborman } 211844361Sborman if (portp == 0) { 211944361Sborman portp = *argv++; 212044361Sborman --argc; 212144361Sborman continue; 212244361Sborman } 212344361Sborman usage: 212445233Sborman printf("usage: %s [-l user] [-a] host-name [port]\n", cmd); 212546808Sdab setuid(getuid()); 212632144Sminshall return 0; 212732144Sminshall } 212846808Sdab if (hostp == 0) 212946808Sdab goto usage; 213046808Sdab 213146808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 213244361Sborman if (hostp[0] == '@' || hostp[0] == '!') { 213344361Sborman if ((hostname = strrchr(hostp, ':')) == NULL) 213444361Sborman hostname = strrchr(hostp, '@'); 213538689Sborman hostname++; 213638689Sborman srp = 0; 213744361Sborman temp = sourceroute(hostp, &srp, &srlen); 213838689Sborman if (temp == 0) { 213938689Sborman herror(srp); 214046808Sdab setuid(getuid()); 214138689Sborman return 0; 214238689Sborman } else if (temp == -1) { 214344361Sborman printf("Bad source route option: %s\n", hostp); 214446808Sdab setuid(getuid()); 214538689Sborman return 0; 214638689Sborman } else { 214738689Sborman sin.sin_addr.s_addr = temp; 214838689Sborman sin.sin_family = AF_INET; 214938689Sborman } 215032144Sminshall } else { 215138689Sborman #endif 215244361Sborman temp = inet_addr(hostp); 215338689Sborman if (temp != (unsigned long) -1) { 215438689Sborman sin.sin_addr.s_addr = temp; 215538689Sborman sin.sin_family = AF_INET; 215646808Sdab (void) strcpy(_hostname, hostp); 215746808Sdab hostname = _hostname; 215838689Sborman } else { 215944361Sborman host = gethostbyname(hostp); 216038689Sborman if (host) { 216138689Sborman sin.sin_family = host->h_addrtype; 216232144Sminshall #if defined(h_addr) /* In 4.3, this is a #define */ 216338689Sborman memcpy((caddr_t)&sin.sin_addr, 216432144Sminshall host->h_addr_list[0], host->h_length); 216532144Sminshall #else /* defined(h_addr) */ 216638689Sborman memcpy((caddr_t)&sin.sin_addr, host->h_addr, host->h_length); 216732144Sminshall #endif /* defined(h_addr) */ 216846808Sdab strncpy(_hostname, host->h_name, sizeof(_hostname)); 216946808Sdab _hostname[sizeof(_hostname)-1] = '\0'; 217046808Sdab hostname = _hostname; 217138689Sborman } else { 217244361Sborman herror(hostp); 217346808Sdab setuid(getuid()); 217438689Sborman return 0; 217538689Sborman } 217632144Sminshall } 217746808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 217832144Sminshall } 217938689Sborman #endif 218044361Sborman if (portp) { 218144361Sborman if (*portp == '-') { 218244361Sborman portp++; 218338689Sborman telnetport = 1; 218438689Sborman } else 218538689Sborman telnetport = 0; 218644361Sborman sin.sin_port = atoi(portp); 218732144Sminshall if (sin.sin_port == 0) { 218844361Sborman sp = getservbyname(portp, "tcp"); 218932144Sminshall if (sp) 219032144Sminshall sin.sin_port = sp->s_port; 219132144Sminshall else { 219244361Sborman printf("%s: bad port number\n", portp); 219346808Sdab setuid(getuid()); 219432144Sminshall return 0; 219532144Sminshall } 219632144Sminshall } else { 219734849Sminshall #if !defined(htons) 219834849Sminshall u_short htons(); 219934849Sminshall #endif /* !defined(htons) */ 220032144Sminshall sin.sin_port = htons(sin.sin_port); 220132144Sminshall } 220232144Sminshall } else { 220332144Sminshall if (sp == 0) { 220432144Sminshall sp = getservbyname("telnet", "tcp"); 220532144Sminshall if (sp == 0) { 220634849Sminshall fprintf(stderr, "telnet: tcp/telnet: unknown service\n"); 220746808Sdab setuid(getuid()); 220832144Sminshall return 0; 220932144Sminshall } 221032144Sminshall sin.sin_port = sp->s_port; 221132144Sminshall } 221232144Sminshall telnetport = 1; 221332144Sminshall } 221437219Sminshall printf("Trying %s...\n", inet_ntoa(sin.sin_addr)); 221532144Sminshall do { 221632144Sminshall net = socket(AF_INET, SOCK_STREAM, 0); 221746808Sdab setuid(getuid()); 221832144Sminshall if (net < 0) { 221932144Sminshall perror("telnet: socket"); 222032144Sminshall return 0; 222132144Sminshall } 222246808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 222338689Sborman if (srp && setsockopt(net, IPPROTO_IP, IP_OPTIONS, (char *)srp, srlen) < 0) 222438689Sborman perror("setsockopt (IP_OPTIONS)"); 222538689Sborman #endif 222646808Sdab #if defined(IPPROTO_IP) && defined(IP_TOS) 222746808Sdab { 222846808Sdab # if defined(HAS_GETTOS) 222946808Sdab struct tosent *tp; 2230*46815Sdab if (tos < 0 && (tp = gettosbyname("telnet", "tcp"))) 223146808Sdab tos = tp->t_tos; 223246808Sdab # endif 2233*46815Sdab if (tos < 0) 2234*46815Sdab tos = 020; /* Low Delay bit */ 2235*46815Sdab if (tos 2236*46815Sdab && (setsockopt(net, IPPROTO_IP, IP_TOS, &tos, sizeof(int)) < 0) 2237*46815Sdab && (errno != ENOPROTOOPT)) 2238*46815Sdab perror("telnet: setsockopt (IP_TOS) (ignored)"); 223946808Sdab } 224046808Sdab #endif /* defined(IPPROTO_IP) && defined(IP_TOS) */ 224140245Sborman 224232144Sminshall if (debug && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 1) < 0) { 224332144Sminshall perror("setsockopt (SO_DEBUG)"); 224432144Sminshall } 224532144Sminshall 224632144Sminshall if (connect(net, (struct sockaddr *)&sin, sizeof (sin)) < 0) { 224732144Sminshall #if defined(h_addr) /* In 4.3, this is a #define */ 224832144Sminshall if (host && host->h_addr_list[1]) { 224932144Sminshall int oerrno = errno; 225032144Sminshall 225132144Sminshall fprintf(stderr, "telnet: connect to address %s: ", 225232144Sminshall inet_ntoa(sin.sin_addr)); 225332144Sminshall errno = oerrno; 225432144Sminshall perror((char *)0); 225532144Sminshall host->h_addr_list++; 225632144Sminshall memcpy((caddr_t)&sin.sin_addr, 225732144Sminshall host->h_addr_list[0], host->h_length); 225832144Sminshall (void) NetClose(net); 225932144Sminshall continue; 226032144Sminshall } 226132144Sminshall #endif /* defined(h_addr) */ 226232144Sminshall perror("telnet: Unable to connect to remote host"); 226332144Sminshall return 0; 226437219Sminshall } 226532144Sminshall connected++; 226646808Sdab #if defined(AUTHENTICATE) || defined(ENCRYPT) 226746808Sdab auth_encrypt_connect(connected); 226846808Sdab #endif 226932144Sminshall } while (connected == 0); 227044361Sborman cmdrc(hostp, hostname); 227145008Skarels if (autologin && user == NULL) { 227245008Skarels struct passwd *pw; 227345008Skarels 227445233Sborman user = getenv("USER"); 227545008Skarels if (user == NULL || 227645233Sborman (pw = getpwnam(user)) && pw->pw_uid != getuid()) { 227745233Sborman if (pw = getpwuid(getuid())) 227845008Skarels user = pw->pw_name; 227945008Skarels else 228045008Skarels user = NULL; 228145233Sborman } 228245008Skarels } 228345008Skarels if (user) { 228446808Sdab env_define((unsigned char *)"USER", (unsigned char *)user); 228546808Sdab env_export((unsigned char *)"USER"); 228645008Skarels } 228734849Sminshall (void) call(status, "status", "notmuch", 0); 228832144Sminshall if (setjmp(peerdied) == 0) 228946808Sdab telnet(user); 229034849Sminshall (void) NetClose(net); 229132381Sminshall ExitString("Connection closed by foreign host.\n",1); 229232144Sminshall /*NOTREACHED*/ 229332144Sminshall } 229432144Sminshall 229532144Sminshall #define HELPINDENT (sizeof ("connect")) 229632144Sminshall 229732144Sminshall static char 229832144Sminshall openhelp[] = "connect to a site", 229932144Sminshall closehelp[] = "close current connection", 230046808Sdab logouthelp[] = "forcibly logout remote user and close the connection", 230132144Sminshall quithelp[] = "exit telnet", 230232144Sminshall statushelp[] = "print status information", 230332144Sminshall helphelp[] = "print help information", 230432144Sminshall sendhelp[] = "transmit special characters ('send ?' for more)", 230532144Sminshall sethelp[] = "set operating parameters ('set ?' for more)", 230638689Sborman unsethelp[] = "unset operating parameters ('unset ?' for more)", 230732144Sminshall togglestring[] ="toggle operating parameters ('toggle ?' for more)", 230838689Sborman slchelp[] = "change state of special charaters ('slc ?' for more)", 230932144Sminshall displayhelp[] = "display operating parameters", 231032144Sminshall #if defined(TN3270) && defined(unix) 231132144Sminshall transcomhelp[] = "specify Unix command for transparent mode pipe", 231232144Sminshall #endif /* defined(TN3270) && defined(unix) */ 231346808Sdab #if defined(AUTHENTICATE) 231446808Sdab authhelp[] = "turn on (off) authentication ('auth ?' for more)", 231546808Sdab #endif 231646808Sdab #if defined(ENCRYPT) 231746808Sdab encrypthelp[] = "turn on (off) encryption ('encrypt ?' for more)", 231846808Sdab #endif 231932144Sminshall #if defined(unix) 232032144Sminshall zhelp[] = "suspend telnet", 232143317Skfall #endif /* defined(unix) */ 232232144Sminshall shellhelp[] = "invoke a subshell", 232344361Sborman envhelp[] = "change environment variables ('environ ?' for more)", 232444361Sborman modestring[] = "try to enter line or character mode ('mode ?' for more)"; 232532144Sminshall 232646808Sdab extern int help(); 232732144Sminshall 232832144Sminshall static Command cmdtab[] = { 232938689Sborman { "close", closehelp, bye, 1 }, 233046808Sdab { "logout", logouthelp, logout, 1 }, 233138689Sborman { "display", displayhelp, display, 0 }, 233238689Sborman { "mode", modestring, modecmd, 0 }, 233338689Sborman { "open", openhelp, tn, 0 }, 233438689Sborman { "quit", quithelp, quit, 0 }, 233538689Sborman { "send", sendhelp, sendcmd, 0 }, 233638689Sborman { "set", sethelp, setcmd, 0 }, 233738689Sborman { "unset", unsethelp, unsetcmd, 0 }, 233838689Sborman { "status", statushelp, status, 0 }, 233938689Sborman { "toggle", togglestring, toggle, 0 }, 234038689Sborman { "slc", slchelp, slccmd, 0 }, 234132144Sminshall #if defined(TN3270) && defined(unix) 234238689Sborman { "transcom", transcomhelp, settranscom, 0 }, 234332144Sminshall #endif /* defined(TN3270) && defined(unix) */ 234446808Sdab #if defined(AUTHENTICATE) 234546808Sdab { "auth", authhelp, auth_cmd, 0 }, 234646808Sdab #endif 234746808Sdab #if defined(ENCRYPT) 234846808Sdab { "encrypt", encrypthelp, encrypt_cmd, 0 }, 234946808Sdab #endif 235032144Sminshall #if defined(unix) 235138689Sborman { "z", zhelp, suspend, 0 }, 235232144Sminshall #endif /* defined(unix) */ 235332144Sminshall #if defined(TN3270) 235438689Sborman { "!", shellhelp, shell, 1 }, 235538689Sborman #else 235638689Sborman { "!", shellhelp, shell, 0 }, 235738689Sborman #endif 235844361Sborman { "environ", envhelp, env_cmd, 0 }, 235938689Sborman { "?", helphelp, help, 0 }, 236032144Sminshall 0 236132144Sminshall }; 236232144Sminshall 236332144Sminshall static char crmodhelp[] = "deprecated command -- use 'toggle crmod' instead"; 236432144Sminshall static char escapehelp[] = "deprecated command -- use 'set escape' instead"; 236532144Sminshall 236632144Sminshall static Command cmdtab2[] = { 236738689Sborman { "help", 0, help, 0 }, 236838689Sborman { "escape", escapehelp, setescape, 0 }, 236938689Sborman { "crmod", crmodhelp, togcrmod, 0 }, 237032144Sminshall 0 237132144Sminshall }; 237232144Sminshall 237335298Sminshall 237432144Sminshall /* 237532144Sminshall * Call routine with argc, argv set from args (terminated by 0). 237632144Sminshall */ 237735298Sminshall 237846808Sdab /*VARARGS1*/ 237946808Sdab static 238035298Sminshall call(va_alist) 238146808Sdab va_dcl 238232144Sminshall { 238335298Sminshall va_list ap; 238435298Sminshall typedef int (*intrtn_t)(); 238535298Sminshall intrtn_t routine; 238635298Sminshall char *args[100]; 238735298Sminshall int argno = 0; 238835298Sminshall 238935298Sminshall va_start(ap); 239035298Sminshall routine = (va_arg(ap, intrtn_t)); 239135495Sminshall while ((args[argno++] = va_arg(ap, char *)) != 0) { 239235298Sminshall ; 239335495Sminshall } 239435298Sminshall va_end(ap); 239535495Sminshall return (*routine)(argno-1, args); 239632144Sminshall } 239732144Sminshall 239835298Sminshall 239946808Sdab static Command * 240032144Sminshall getcmd(name) 240146808Sdab char *name; 240232144Sminshall { 240332144Sminshall Command *cm; 240432144Sminshall 240546808Sdab if (cm = (Command *) genget(name, (char **) cmdtab, sizeof(Command))) 240632144Sminshall return cm; 240746808Sdab return (Command *) genget(name, (char **) cmdtab2, sizeof(Command)); 240832144Sminshall } 240932144Sminshall 241046808Sdab void 241138689Sborman command(top, tbuf, cnt) 241246808Sdab int top; 241346808Sdab char *tbuf; 241446808Sdab int cnt; 241532144Sminshall { 241632144Sminshall register Command *c; 241732144Sminshall 241832144Sminshall setcommandmode(); 241932144Sminshall if (!top) { 242032144Sminshall putchar('\n'); 242137219Sminshall #if defined(unix) 242232144Sminshall } else { 242344361Sborman (void) signal(SIGINT, SIG_DFL); 242444361Sborman (void) signal(SIGQUIT, SIG_DFL); 242532144Sminshall #endif /* defined(unix) */ 242632144Sminshall } 242732144Sminshall for (;;) { 242846808Sdab if (rlogin == _POSIX_VDISABLE) 242946808Sdab printf("%s> ", prompt); 243038689Sborman if (tbuf) { 243138689Sborman register char *cp; 243238689Sborman cp = line; 243338689Sborman while (cnt > 0 && (*cp++ = *tbuf++) != '\n') 243438689Sborman cnt--; 243538689Sborman tbuf = 0; 243638689Sborman if (cp == line || *--cp != '\n' || cp == line) 243738689Sborman goto getline; 243838689Sborman *cp = '\0'; 243946808Sdab if (rlogin == _POSIX_VDISABLE) 244046808Sdab printf("%s\n", line); 244138689Sborman } else { 244238689Sborman getline: 244346808Sdab if (rlogin != _POSIX_VDISABLE) 244446808Sdab printf("%s> ", prompt); 244546808Sdab if (fgets(line, sizeof(line), stdin) == NULL) { 244644361Sborman if (feof(stdin) || ferror(stdin)) { 244744361Sborman (void) quit(); 244844361Sborman /*NOTREACHED*/ 244944361Sborman } 245038689Sborman break; 245138689Sborman } 245232144Sminshall } 245332144Sminshall if (line[0] == 0) 245432144Sminshall break; 245532144Sminshall makeargv(); 245637219Sminshall if (margv[0] == 0) { 245737219Sminshall break; 245837219Sminshall } 245932144Sminshall c = getcmd(margv[0]); 246032144Sminshall if (Ambiguous(c)) { 246132144Sminshall printf("?Ambiguous command\n"); 246232144Sminshall continue; 246332144Sminshall } 246432144Sminshall if (c == 0) { 246532144Sminshall printf("?Invalid command\n"); 246632144Sminshall continue; 246732144Sminshall } 246832144Sminshall if (c->needconnect && !connected) { 246932144Sminshall printf("?Need to be connected first.\n"); 247032144Sminshall continue; 247132144Sminshall } 247232144Sminshall if ((*c->handler)(margc, margv)) { 247332144Sminshall break; 247432144Sminshall } 247532144Sminshall } 247632144Sminshall if (!top) { 247732144Sminshall if (!connected) { 247832144Sminshall longjmp(toplevel, 1); 247932144Sminshall /*NOTREACHED*/ 248032144Sminshall } 248132144Sminshall #if defined(TN3270) 248232144Sminshall if (shell_active == 0) { 248338689Sborman setconnmode(0); 248432144Sminshall } 248532144Sminshall #else /* defined(TN3270) */ 248638689Sborman setconnmode(0); 248732144Sminshall #endif /* defined(TN3270) */ 248832144Sminshall } 248932144Sminshall } 249032144Sminshall 249132144Sminshall /* 249232144Sminshall * Help command. 249332144Sminshall */ 249446808Sdab static 249532144Sminshall help(argc, argv) 249632144Sminshall int argc; 249732144Sminshall char *argv[]; 249832144Sminshall { 249932144Sminshall register Command *c; 250032144Sminshall 250132144Sminshall if (argc == 1) { 250232144Sminshall printf("Commands may be abbreviated. Commands are:\n\n"); 250332144Sminshall for (c = cmdtab; c->name; c++) 250438689Sborman if (c->help) { 250532144Sminshall printf("%-*s\t%s\n", HELPINDENT, c->name, 250632144Sminshall c->help); 250732144Sminshall } 250832144Sminshall return 0; 250932144Sminshall } 251032144Sminshall while (--argc > 0) { 251132144Sminshall register char *arg; 251232144Sminshall arg = *++argv; 251332144Sminshall c = getcmd(arg); 251432144Sminshall if (Ambiguous(c)) 251532144Sminshall printf("?Ambiguous help command %s\n", arg); 251632144Sminshall else if (c == (Command *)0) 251732144Sminshall printf("?Invalid help command %s\n", arg); 251832144Sminshall else 251932144Sminshall printf("%s\n", c->help); 252032144Sminshall } 252132144Sminshall return 0; 252232144Sminshall } 252338689Sborman 252438689Sborman static char *rcname = 0; 252538689Sborman static char rcbuf[128]; 252638689Sborman 252738689Sborman cmdrc(m1, m2) 252838689Sborman char *m1, *m2; 252938689Sborman { 253038689Sborman register Command *c; 253138689Sborman FILE *rcfile; 253238689Sborman int gotmachine = 0; 253338689Sborman int l1 = strlen(m1); 253438689Sborman int l2 = strlen(m2); 253538689Sborman char m1save[64]; 253638689Sborman 253738689Sborman strcpy(m1save, m1); 253838689Sborman m1 = m1save; 253938689Sborman 254038689Sborman if (rcname == 0) { 254138689Sborman rcname = getenv("HOME"); 254238689Sborman if (rcname) 254338689Sborman strcpy(rcbuf, rcname); 254438689Sborman else 254538689Sborman rcbuf[0] = '\0'; 254638689Sborman strcat(rcbuf, "/.telnetrc"); 254738689Sborman rcname = rcbuf; 254838689Sborman } 254938689Sborman 255038689Sborman if ((rcfile = fopen(rcname, "r")) == 0) { 255138689Sborman return; 255238689Sborman } 255338689Sborman 255438689Sborman for (;;) { 255538689Sborman if (fgets(line, sizeof(line), rcfile) == NULL) 255638689Sborman break; 255738689Sborman if (line[0] == 0) 255838689Sborman break; 255938689Sborman if (line[0] == '#') 256038689Sborman continue; 256138689Sborman if (gotmachine == 0) { 256238689Sborman if (isspace(line[0])) 256338689Sborman continue; 256438689Sborman if (strncasecmp(line, m1, l1) == 0) 256538689Sborman strncpy(line, &line[l1], sizeof(line) - l1); 256638689Sborman else if (strncasecmp(line, m2, l2) == 0) 256738689Sborman strncpy(line, &line[l2], sizeof(line) - l2); 256838689Sborman else 256938689Sborman continue; 257038689Sborman gotmachine = 1; 257138689Sborman } else { 257238689Sborman if (!isspace(line[0])) { 257338689Sborman gotmachine = 0; 257438689Sborman continue; 257538689Sborman } 257638689Sborman } 257738689Sborman makeargv(); 257838689Sborman if (margv[0] == 0) 257938689Sborman continue; 258038689Sborman c = getcmd(margv[0]); 258138689Sborman if (Ambiguous(c)) { 258238689Sborman printf("?Ambiguous command: %s\n", margv[0]); 258338689Sborman continue; 258438689Sborman } 258538689Sborman if (c == 0) { 258638689Sborman printf("?Invalid command: %s\n", margv[0]); 258738689Sborman continue; 258838689Sborman } 258938689Sborman /* 259038689Sborman * This should never happen... 259138689Sborman */ 259238689Sborman if (c->needconnect && !connected) { 259338689Sborman printf("?Need to be connected first for %s.\n", margv[0]); 259438689Sborman continue; 259538689Sborman } 259638689Sborman (*c->handler)(margc, margv); 259738689Sborman } 259838689Sborman fclose(rcfile); 259938689Sborman } 260038689Sborman 260146808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 260238689Sborman 260338689Sborman /* 260438689Sborman * Source route is handed in as 260538689Sborman * [!]@hop1@hop2...[@|:]dst 260638689Sborman * If the leading ! is present, it is a 260738689Sborman * strict source route, otherwise it is 260838689Sborman * assmed to be a loose source route. 260938689Sborman * 261038689Sborman * We fill in the source route option as 261138689Sborman * hop1,hop2,hop3...dest 261238689Sborman * and return a pointer to hop1, which will 261338689Sborman * be the address to connect() to. 261438689Sborman * 261538689Sborman * Arguments: 261638689Sborman * arg: pointer to route list to decipher 261738689Sborman * 261838689Sborman * cpp: If *cpp is not equal to NULL, this is a 261938689Sborman * pointer to a pointer to a character array 262038689Sborman * that should be filled in with the option. 262138689Sborman * 262238689Sborman * lenp: pointer to an integer that contains the 262338689Sborman * length of *cpp if *cpp != NULL. 262438689Sborman * 262538689Sborman * Return values: 262638689Sborman * 262738689Sborman * Returns the address of the host to connect to. If the 262838689Sborman * return value is -1, there was a syntax error in the 262938689Sborman * option, either unknown characters, or too many hosts. 263038689Sborman * If the return value is 0, one of the hostnames in the 263138689Sborman * path is unknown, and *cpp is set to point to the bad 263238689Sborman * hostname. 263338689Sborman * 263438689Sborman * *cpp: If *cpp was equal to NULL, it will be filled 263538689Sborman * in with a pointer to our static area that has 263638689Sborman * the option filled in. This will be 32bit aligned. 263738689Sborman * 263838689Sborman * *lenp: This will be filled in with how long the option 263938689Sborman * pointed to by *cpp is. 264038689Sborman * 264138689Sborman */ 264246808Sdab unsigned long 264338689Sborman sourceroute(arg, cpp, lenp) 264446808Sdab char *arg; 264546808Sdab char **cpp; 264646808Sdab int *lenp; 264738689Sborman { 264838689Sborman static char lsr[44]; 264946808Sdab char *cp, *cp2, *lsrp, *lsrep; 265038689Sborman register int tmp; 265138689Sborman struct in_addr sin_addr; 265238689Sborman register struct hostent *host = 0; 265338689Sborman register char c; 265438689Sborman 265538689Sborman /* 265638689Sborman * Verify the arguments, and make sure we have 265738689Sborman * at least 7 bytes for the option. 265838689Sborman */ 265938689Sborman if (cpp == NULL || lenp == NULL) 266038689Sborman return((unsigned long)-1); 266138689Sborman if (*cpp != NULL && *lenp < 7) 266238689Sborman return((unsigned long)-1); 266338689Sborman /* 266438689Sborman * Decide whether we have a buffer passed to us, 266538689Sborman * or if we need to use our own static buffer. 266638689Sborman */ 266738689Sborman if (*cpp) { 266838689Sborman lsrp = *cpp; 266938689Sborman lsrep = lsrp + *lenp; 267038689Sborman } else { 267138689Sborman *cpp = lsrp = lsr; 267238689Sborman lsrep = lsrp + 44; 267338689Sborman } 267438689Sborman 267538689Sborman cp = arg; 267638689Sborman 267738689Sborman /* 267838689Sborman * Next, decide whether we have a loose source 267938689Sborman * route or a strict source route, and fill in 268038689Sborman * the begining of the option. 268138689Sborman */ 268238689Sborman if (*cp == '!') { 268338689Sborman cp++; 268438689Sborman *lsrp++ = IPOPT_SSRR; 268538689Sborman } else 268638689Sborman *lsrp++ = IPOPT_LSRR; 268738689Sborman 268838689Sborman if (*cp != '@') 268938689Sborman return((unsigned long)-1); 269038689Sborman 269138689Sborman lsrp++; /* skip over length, we'll fill it in later */ 269238689Sborman *lsrp++ = 4; 269338689Sborman 269438689Sborman cp++; 269538689Sborman 269638689Sborman sin_addr.s_addr = 0; 269738689Sborman 269838689Sborman for (c = 0;;) { 269938689Sborman if (c == ':') 270038689Sborman cp2 = 0; 270138689Sborman else for (cp2 = cp; c = *cp2; cp2++) { 270238689Sborman if (c == ',') { 270338689Sborman *cp2++ = '\0'; 270438689Sborman if (*cp2 == '@') 270538689Sborman cp2++; 270638689Sborman } else if (c == '@') { 270738689Sborman *cp2++ = '\0'; 270838689Sborman } else if (c == ':') { 270938689Sborman *cp2++ = '\0'; 271038689Sborman } else 271138689Sborman continue; 271238689Sborman break; 271338689Sborman } 271438689Sborman if (!c) 271538689Sborman cp2 = 0; 271638689Sborman 271738689Sborman if ((tmp = inet_addr(cp)) != -1) { 271838689Sborman sin_addr.s_addr = tmp; 271938689Sborman } else if (host = gethostbyname(cp)) { 272038689Sborman #if defined(h_addr) 272138689Sborman memcpy((caddr_t)&sin_addr, 272238689Sborman host->h_addr_list[0], host->h_length); 272338689Sborman #else 272438689Sborman memcpy((caddr_t)&sin_addr, host->h_addr, host->h_length); 272538689Sborman #endif 272638689Sborman } else { 272738689Sborman *cpp = cp; 272838689Sborman return(0); 272938689Sborman } 273038689Sborman memcpy(lsrp, (char *)&sin_addr, 4); 273138689Sborman lsrp += 4; 273238689Sborman if (cp2) 273338689Sborman cp = cp2; 273438689Sborman else 273538689Sborman break; 273638689Sborman /* 273738689Sborman * Check to make sure there is space for next address 273838689Sborman */ 273938689Sborman if (lsrp + 4 > lsrep) 274038689Sborman return((unsigned long)-1); 274138689Sborman } 274238689Sborman if ((*(*cpp+IPOPT_OLEN) = lsrp - *cpp) <= 7) { 274338689Sborman *cpp = 0; 274438689Sborman *lenp = 0; 274538689Sborman return((unsigned long)-1); 274638689Sborman } 274738689Sborman *lsrp++ = IPOPT_NOP; /* 32 bit word align it */ 274838689Sborman *lenp = lsrp - *cpp; 274938689Sborman return(sin_addr.s_addr); 275038689Sborman } 275138689Sborman #endif 2752