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*57848Sdab static char sccsid[] = "@(#)commands.c 5.9 (Berkeley) 02/04/93"; 1033685Sbostic #endif /* not lint */ 1133685Sbostic 1236274Sminshall #if defined(unix) 1345241Swilliam #include <sys/param.h> 1457213Sdab #if defined(CRAY) || defined(sysV88) 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 4457213Sdab #if !defined(CRAY) && !defined(sysV88) 4546808Sdab #include <netinet/in_systm.h> 4646808Sdab # if (defined(vax) || defined(tahoe) || defined(hp300)) && !defined(ultrix) 4746808Sdab # include <machine/endian.h> 4846808Sdab # endif /* vax */ 4957213Sdab #endif /* !defined(CRAY) && !defined(sysV88) */ 5044361Sborman #include <netinet/ip.h> 5138689Sborman 5238689Sborman 5346808Sdab #ifndef MAXHOSTNAMELEN 5446808Sdab #define MAXHOSTNAMELEN 64 5546808Sdab #endif MAXHOSTNAMELEN 5640248Sborman 5746815Sdab #if defined(IPPROTO_IP) && defined(IP_TOS) 5846815Sdab int tos = -1; 5946815Sdab #endif /* defined(IPPROTO_IP) && defined(IP_TOS) */ 6046815Sdab 6132144Sminshall char *hostname; 6246808Sdab static char _hostname[MAXHOSTNAMELEN]; 6346808Sdab 6438689Sborman extern char *getenv(); 6532144Sminshall 6646808Sdab extern int isprefix(); 6746808Sdab extern char **genget(); 6846808Sdab extern int Ambiguous(); 6946808Sdab 7044361Sborman static call(); 7132144Sminshall 7232144Sminshall typedef struct { 7332144Sminshall char *name; /* command name */ 7438689Sborman char *help; /* help string (NULL for no help) */ 7532144Sminshall int (*handler)(); /* routine which executes command */ 7632144Sminshall int needconnect; /* Do we need to be connected to execute? */ 7732144Sminshall } Command; 7832144Sminshall 7938689Sborman static char line[256]; 8038689Sborman static char saveline[256]; 8132144Sminshall static int margc; 8232144Sminshall static char *margv[20]; 8332144Sminshall 8446808Sdab static void 8532144Sminshall makeargv() 8632144Sminshall { 8744361Sborman register char *cp, *cp2, c; 8832144Sminshall register char **argp = margv; 8932144Sminshall 9032144Sminshall margc = 0; 9132144Sminshall cp = line; 9232144Sminshall if (*cp == '!') { /* Special case shell escape */ 9338689Sborman strcpy(saveline, line); /* save for shell command */ 9432144Sminshall *argp++ = "!"; /* No room in string to get this */ 9532144Sminshall margc++; 9632144Sminshall cp++; 9732144Sminshall } 9844361Sborman while (c = *cp) { 9944361Sborman register int inquote = 0; 10044361Sborman while (isspace(c)) 10144361Sborman c = *++cp; 10244361Sborman if (c == '\0') 10332144Sminshall break; 10432144Sminshall *argp++ = cp; 10532144Sminshall margc += 1; 10644361Sborman for (cp2 = cp; c != '\0'; c = *++cp) { 10744361Sborman if (inquote) { 10844361Sborman if (c == inquote) { 10944361Sborman inquote = 0; 11044361Sborman continue; 11144361Sborman } 11244361Sborman } else { 11344361Sborman if (c == '\\') { 11444361Sborman if ((c = *++cp) == '\0') 11544361Sborman break; 11644361Sborman } else if (c == '"') { 11744361Sborman inquote = '"'; 11844361Sborman continue; 11944361Sborman } else if (c == '\'') { 12044361Sborman inquote = '\''; 12144361Sborman continue; 12244361Sborman } else if (isspace(c)) 12344361Sborman break; 12444361Sborman } 12544361Sborman *cp2++ = c; 12644361Sborman } 12744361Sborman *cp2 = '\0'; 12844361Sborman if (c == '\0') 12932144Sminshall break; 13044361Sborman cp++; 13132144Sminshall } 13232144Sminshall *argp++ = 0; 13332144Sminshall } 13432144Sminshall 13532144Sminshall /* 13632144Sminshall * Make a character string into a number. 13732144Sminshall * 13832144Sminshall * Todo: 1. Could take random integers (12, 0x12, 012, 0b1). 13932144Sminshall */ 14032144Sminshall 14146808Sdab static 14232144Sminshall special(s) 14346808Sdab register char *s; 14432144Sminshall { 14532144Sminshall register char c; 14632144Sminshall char b; 14732144Sminshall 14832144Sminshall switch (*s) { 14932144Sminshall case '^': 15032144Sminshall b = *++s; 15132144Sminshall if (b == '?') { 15232144Sminshall c = b | 0x40; /* DEL */ 15332144Sminshall } else { 15432144Sminshall c = b & 0x1f; 15532144Sminshall } 15632144Sminshall break; 15732144Sminshall default: 15832144Sminshall c = *s; 15932144Sminshall break; 16032144Sminshall } 16132144Sminshall return c; 16232144Sminshall } 16332144Sminshall 16432144Sminshall /* 16532144Sminshall * Construct a control character sequence 16632144Sminshall * for a special character. 16732144Sminshall */ 16846808Sdab static char * 16932144Sminshall control(c) 17040245Sborman register cc_t c; 17132144Sminshall { 17244361Sborman static char buf[5]; 17346808Sdab /* 17446808Sdab * The only way I could get the Sun 3.5 compiler 17546808Sdab * to shut up about 17646808Sdab * if ((unsigned int)c >= 0x80) 17746808Sdab * was to assign "c" to an unsigned int variable... 17846808Sdab * Arggg.... 17946808Sdab */ 18046808Sdab register unsigned int uic = (unsigned int)c; 18132144Sminshall 18246808Sdab if (uic == 0x7f) 18332144Sminshall return ("^?"); 18445233Sborman if (c == (cc_t)_POSIX_VDISABLE) { 18532144Sminshall return "off"; 18632144Sminshall } 18746808Sdab if (uic >= 0x80) { 18844361Sborman buf[0] = '\\'; 18944361Sborman buf[1] = ((c>>6)&07) + '0'; 19044361Sborman buf[2] = ((c>>3)&07) + '0'; 19144361Sborman buf[3] = (c&07) + '0'; 19244361Sborman buf[4] = 0; 19346808Sdab } else if (uic >= 0x20) { 19432144Sminshall buf[0] = c; 19532144Sminshall buf[1] = 0; 19632144Sminshall } else { 19732144Sminshall buf[0] = '^'; 19832144Sminshall buf[1] = '@'+c; 19932144Sminshall buf[2] = 0; 20032144Sminshall } 20132144Sminshall return (buf); 20232144Sminshall } 20332144Sminshall 20432144Sminshall 20532144Sminshall 20632144Sminshall /* 20732144Sminshall * The following are data structures and routines for 20832144Sminshall * the "send" command. 20932144Sminshall * 21032144Sminshall */ 21132144Sminshall 21232144Sminshall struct sendlist { 21332144Sminshall char *name; /* How user refers to it (case independent) */ 21432144Sminshall char *help; /* Help information (0 ==> no help) */ 21546808Sdab int needconnect; /* Need to be connected */ 21646808Sdab int narg; /* Number of arguments */ 21738689Sborman int (*handler)(); /* Routine to perform (for special ops) */ 21846808Sdab int nbyte; /* Number of bytes to send this command */ 21938689Sborman int what; /* Character to be sent (<0 ==> special) */ 22032144Sminshall }; 22132144Sminshall 22232144Sminshall 22356642Sralph static int 22446808Sdab send_esc P((void)), 22546808Sdab send_help P((void)), 22646808Sdab send_docmd P((char *)), 22746808Sdab send_dontcmd P((char *)), 22846808Sdab send_willcmd P((char *)), 22946808Sdab send_wontcmd P((char *)); 23046808Sdab 23132144Sminshall static struct sendlist Sendlist[] = { 23246808Sdab { "ao", "Send Telnet Abort output", 1, 0, 0, 2, AO }, 23346808Sdab { "ayt", "Send Telnet 'Are You There'", 1, 0, 0, 2, AYT }, 23446808Sdab { "brk", "Send Telnet Break", 1, 0, 0, 2, BREAK }, 23546808Sdab { "break", 0, 1, 0, 0, 2, BREAK }, 23646808Sdab { "ec", "Send Telnet Erase Character", 1, 0, 0, 2, EC }, 23746808Sdab { "el", "Send Telnet Erase Line", 1, 0, 0, 2, EL }, 23846808Sdab { "escape", "Send current escape character", 1, 0, send_esc, 1, 0 }, 23946808Sdab { "ga", "Send Telnet 'Go Ahead' sequence", 1, 0, 0, 2, GA }, 24046808Sdab { "ip", "Send Telnet Interrupt Process", 1, 0, 0, 2, IP }, 24146808Sdab { "intp", 0, 1, 0, 0, 2, IP }, 24246808Sdab { "interrupt", 0, 1, 0, 0, 2, IP }, 24346808Sdab { "intr", 0, 1, 0, 0, 2, IP }, 24446808Sdab { "nop", "Send Telnet 'No operation'", 1, 0, 0, 2, NOP }, 24546808Sdab { "eor", "Send Telnet 'End of Record'", 1, 0, 0, 2, EOR }, 24646808Sdab { "abort", "Send Telnet 'Abort Process'", 1, 0, 0, 2, ABORT }, 24746808Sdab { "susp", "Send Telnet 'Suspend Process'", 1, 0, 0, 2, SUSP }, 24846808Sdab { "eof", "Send Telnet End of File Character", 1, 0, 0, 2, xEOF }, 24946808Sdab { "synch", "Perform Telnet 'Synch operation'", 1, 0, dosynch, 2, 0 }, 25046808Sdab { "getstatus", "Send request for STATUS", 1, 0, get_status, 6, 0 }, 25146808Sdab { "?", "Display send options", 0, 0, send_help, 0, 0 }, 25246808Sdab { "help", 0, 0, 0, send_help, 0, 0 }, 25346808Sdab { "do", 0, 0, 1, send_docmd, 3, 0 }, 25446808Sdab { "dont", 0, 0, 1, send_dontcmd, 3, 0 }, 25546808Sdab { "will", 0, 0, 1, send_willcmd, 3, 0 }, 25646808Sdab { "wont", 0, 0, 1, send_wontcmd, 3, 0 }, 25732144Sminshall { 0 } 25832144Sminshall }; 25932144Sminshall 26046808Sdab #define GETSEND(name) ((struct sendlist *) genget(name, (char **) Sendlist, \ 26146808Sdab sizeof(struct sendlist))) 26232144Sminshall 26346808Sdab static int 26432144Sminshall sendcmd(argc, argv) 26546808Sdab int argc; 26646808Sdab char **argv; 26732144Sminshall { 26832144Sminshall int count; /* how many bytes we are going to need to send */ 26932144Sminshall int i; 27032144Sminshall int question = 0; /* was at least one argument a question */ 27132144Sminshall struct sendlist *s; /* pointer to current command */ 27246808Sdab int success = 0; 27346808Sdab int needconnect = 0; 27432144Sminshall 27532144Sminshall if (argc < 2) { 27632144Sminshall printf("need at least one argument for 'send' command\n"); 27732144Sminshall printf("'send ?' for help\n"); 27832144Sminshall return 0; 27932144Sminshall } 28032144Sminshall /* 28132144Sminshall * First, validate all the send arguments. 28232144Sminshall * In addition, we see how much space we are going to need, and 28332144Sminshall * whether or not we will be doing a "SYNCH" operation (which 28432144Sminshall * flushes the network queue). 28532144Sminshall */ 28632144Sminshall count = 0; 28732144Sminshall for (i = 1; i < argc; i++) { 28846808Sdab s = GETSEND(argv[i]); 28932144Sminshall if (s == 0) { 29032144Sminshall printf("Unknown send argument '%s'\n'send ?' for help.\n", 29132144Sminshall argv[i]); 29232144Sminshall return 0; 29332144Sminshall } else if (Ambiguous(s)) { 29432144Sminshall printf("Ambiguous send argument '%s'\n'send ?' for help.\n", 29532144Sminshall argv[i]); 29632144Sminshall return 0; 29732144Sminshall } 29846808Sdab if (i + s->narg >= argc) { 29946808Sdab fprintf(stderr, 30046808Sdab "Need %d argument%s to 'send %s' command. 'send %s ?' for help.\n", 30146808Sdab s->narg, s->narg == 1 ? "" : "s", s->name, s->name); 30246808Sdab return 0; 30332144Sminshall } 30446808Sdab count += s->nbyte; 30546808Sdab if (s->handler == send_help) { 30646808Sdab send_help(); 30746808Sdab return 0; 30846808Sdab } 30946808Sdab 31046808Sdab i += s->narg; 31146808Sdab needconnect += s->needconnect; 31232144Sminshall } 31346808Sdab if (!connected && needconnect) { 31446808Sdab printf("?Need to be connected first.\n"); 31546808Sdab printf("'send ?' for help\n"); 31646808Sdab return 0; 31738689Sborman } 31832144Sminshall /* Now, do we have enough room? */ 31932144Sminshall if (NETROOM() < count) { 32032144Sminshall printf("There is not enough room in the buffer TO the network\n"); 32132144Sminshall printf("to process your request. Nothing will be done.\n"); 32232144Sminshall printf("('send synch' will throw away most data in the network\n"); 32332144Sminshall printf("buffer, if this might help.)\n"); 32432144Sminshall return 0; 32532144Sminshall } 32632144Sminshall /* OK, they are all OK, now go through again and actually send */ 32746808Sdab count = 0; 32832144Sminshall for (i = 1; i < argc; i++) { 32946808Sdab if ((s = GETSEND(argv[i])) == 0) { 33032144Sminshall fprintf(stderr, "Telnet 'send' error - argument disappeared!\n"); 33144361Sborman (void) quit(); 33232144Sminshall /*NOTREACHED*/ 33332144Sminshall } 33438689Sborman if (s->handler) { 33546808Sdab count++; 33646808Sdab success += (*s->handler)((s->narg > 0) ? argv[i+1] : 0, 33746808Sdab (s->narg > 1) ? argv[i+2] : 0); 33846808Sdab i += s->narg; 33932144Sminshall } else { 34056859Storek NET2ADD(IAC, s->what); 34156859Storek printoption("SENT", IAC, s->what); 34246808Sdab } 34346808Sdab } 34446808Sdab return (count == success); 34546808Sdab } 34646808Sdab 34746808Sdab static int 34846808Sdab send_esc() 34946808Sdab { 35046808Sdab NETADD(escape); 35146808Sdab return 1; 35246808Sdab } 35346808Sdab 35446808Sdab static int 35546808Sdab send_docmd(name) 35646808Sdab char *name; 35746808Sdab { 35846808Sdab void send_do(); 35946808Sdab return(send_tncmd(send_do, "do", name)); 36046808Sdab } 36146808Sdab 36246808Sdab static int 36346808Sdab send_dontcmd(name) 36446808Sdab char *name; 36546808Sdab { 36646808Sdab void send_dont(); 36746808Sdab return(send_tncmd(send_dont, "dont", name)); 36846808Sdab } 36946808Sdab static int 37046808Sdab send_willcmd(name) 37146808Sdab char *name; 37246808Sdab { 37346808Sdab void send_will(); 37446808Sdab return(send_tncmd(send_will, "will", name)); 37546808Sdab } 37646808Sdab static int 37746808Sdab send_wontcmd(name) 37846808Sdab char *name; 37946808Sdab { 38046808Sdab void send_wont(); 38146808Sdab return(send_tncmd(send_wont, "wont", name)); 38246808Sdab } 38346808Sdab 38446808Sdab int 38546808Sdab send_tncmd(func, cmd, name) 38646808Sdab void (*func)(); 38746808Sdab char *cmd, *name; 38846808Sdab { 38946808Sdab char **cpp; 39046808Sdab extern char *telopts[]; 39157213Sdab register int val = 0; 39246808Sdab 39346808Sdab if (isprefix(name, "help") || isprefix(name, "?")) { 39446808Sdab register int col, len; 39546808Sdab 39657213Sdab printf("Usage: send %s <value|option>\n", cmd); 39757213Sdab printf("\"value\" must be from 0 to 255\n"); 39846808Sdab printf("Valid options are:\n\t"); 39946808Sdab 40046808Sdab col = 8; 40146808Sdab for (cpp = telopts; *cpp; cpp++) { 40257213Sdab len = strlen(*cpp) + 3; 40346808Sdab if (col + len > 65) { 40446808Sdab printf("\n\t"); 40546808Sdab col = 8; 40632144Sminshall } 40757213Sdab printf(" \"%s\"", *cpp); 40846808Sdab col += len; 40932144Sminshall } 41046808Sdab printf("\n"); 41146808Sdab return 0; 41232144Sminshall } 41346808Sdab cpp = (char **)genget(name, telopts, sizeof(char *)); 41446808Sdab if (Ambiguous(cpp)) { 41546808Sdab fprintf(stderr,"'%s': ambiguous argument ('send %s ?' for help).\n", 41646808Sdab name, cmd); 41746808Sdab return 0; 41846808Sdab } 41957213Sdab if (cpp) { 42057213Sdab val = cpp - telopts; 42157213Sdab } else { 42257213Sdab register char *cp = name; 42357213Sdab 42457213Sdab while (*cp >= '0' && *cp <= '9') { 42557213Sdab val *= 10; 42657213Sdab val += *cp - '0'; 42757213Sdab cp++; 42857213Sdab } 42957213Sdab if (*cp != 0) { 43057213Sdab fprintf(stderr, "'%s': unknown argument ('send %s ?' for help).\n", 43146808Sdab name, cmd); 43257213Sdab return 0; 43357213Sdab } else if (val < 0 || val > 255) { 43457213Sdab fprintf(stderr, "'%s': bad value ('send %s ?' for help).\n", 43557213Sdab name, cmd); 43657213Sdab return 0; 43757213Sdab } 43846808Sdab } 43946808Sdab if (!connected) { 44046808Sdab printf("?Need to be connected first.\n"); 44146808Sdab return 0; 44246808Sdab } 44357213Sdab (*func)(val, 1); 44446808Sdab return 1; 44532144Sminshall } 44646808Sdab 44746808Sdab static int 44846808Sdab send_help() 44946808Sdab { 45046808Sdab struct sendlist *s; /* pointer to current command */ 45146808Sdab for (s = Sendlist; s->name; s++) { 45246808Sdab if (s->help) 45346808Sdab printf("%-15s %s\n", s->name, s->help); 45446808Sdab } 45546808Sdab return(0); 45646808Sdab } 45732144Sminshall 45832144Sminshall /* 45932144Sminshall * The following are the routines and data structures referred 46032144Sminshall * to by the arguments to the "toggle" command. 46132144Sminshall */ 46232144Sminshall 46346808Sdab static int 46432144Sminshall lclchars() 46532144Sminshall { 46632144Sminshall donelclchars = 1; 46732144Sminshall return 1; 46832144Sminshall } 46932144Sminshall 47046808Sdab static int 47132144Sminshall togdebug() 47232144Sminshall { 47332144Sminshall #ifndef NOT43 47432144Sminshall if (net > 0 && 47532144Sminshall (SetSockOpt(net, SOL_SOCKET, SO_DEBUG, debug)) < 0) { 47632144Sminshall perror("setsockopt (SO_DEBUG)"); 47732144Sminshall } 47832144Sminshall #else /* NOT43 */ 47932144Sminshall if (debug) { 48032144Sminshall if (net > 0 && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 0, 0) < 0) 48132144Sminshall perror("setsockopt (SO_DEBUG)"); 48232144Sminshall } else 48332144Sminshall printf("Cannot turn off socket debugging\n"); 48432144Sminshall #endif /* NOT43 */ 48532144Sminshall return 1; 48632144Sminshall } 48732144Sminshall 48832144Sminshall 48946808Sdab static int 49032144Sminshall togcrlf() 49132144Sminshall { 49232144Sminshall if (crlf) { 49332144Sminshall printf("Will send carriage returns as telnet <CR><LF>.\n"); 49432144Sminshall } else { 49532144Sminshall printf("Will send carriage returns as telnet <CR><NUL>.\n"); 49632144Sminshall } 49732144Sminshall return 1; 49832144Sminshall } 49932144Sminshall 50038909Sborman int binmode; 50132144Sminshall 50246808Sdab static int 50338689Sborman togbinary(val) 50446808Sdab int val; 50532144Sminshall { 50632144Sminshall donebinarytoggle = 1; 50732144Sminshall 50838909Sborman if (val >= 0) { 50938909Sborman binmode = val; 51038909Sborman } else { 51138909Sborman if (my_want_state_is_will(TELOPT_BINARY) && 51238909Sborman my_want_state_is_do(TELOPT_BINARY)) { 51338909Sborman binmode = 1; 51438909Sborman } else if (my_want_state_is_wont(TELOPT_BINARY) && 51538909Sborman my_want_state_is_dont(TELOPT_BINARY)) { 51638909Sborman binmode = 0; 51738909Sborman } 51838909Sborman val = binmode ? 0 : 1; 51938909Sborman } 52038909Sborman 52138909Sborman if (val == 1) { 52238909Sborman if (my_want_state_is_will(TELOPT_BINARY) && 52338909Sborman my_want_state_is_do(TELOPT_BINARY)) { 52438689Sborman printf("Already operating in binary mode with remote host.\n"); 52538909Sborman } else { 52638909Sborman printf("Negotiating binary mode with remote host.\n"); 52738909Sborman tel_enter_binary(3); 52838689Sborman } 52938909Sborman } else { 53038909Sborman if (my_want_state_is_wont(TELOPT_BINARY) && 53138909Sborman my_want_state_is_dont(TELOPT_BINARY)) { 53238689Sborman printf("Already in network ascii mode with remote host.\n"); 53338909Sborman } else { 53438909Sborman printf("Negotiating network ascii mode with remote host.\n"); 53538909Sborman tel_leave_binary(3); 53638689Sborman } 53732144Sminshall } 53832144Sminshall return 1; 53932144Sminshall } 54032144Sminshall 54146808Sdab static int 54238909Sborman togrbinary(val) 54346808Sdab int val; 54438909Sborman { 54538909Sborman donebinarytoggle = 1; 54632144Sminshall 54738909Sborman if (val == -1) 54838909Sborman val = my_want_state_is_do(TELOPT_BINARY) ? 0 : 1; 54932144Sminshall 55038909Sborman if (val == 1) { 55138909Sborman if (my_want_state_is_do(TELOPT_BINARY)) { 55238909Sborman printf("Already receiving in binary mode.\n"); 55338909Sborman } else { 55438909Sborman printf("Negotiating binary mode on input.\n"); 55538909Sborman tel_enter_binary(1); 55638909Sborman } 55738909Sborman } else { 55838909Sborman if (my_want_state_is_dont(TELOPT_BINARY)) { 55938909Sborman printf("Already receiving in network ascii mode.\n"); 56038909Sborman } else { 56138909Sborman printf("Negotiating network ascii mode on input.\n"); 56238909Sborman tel_leave_binary(1); 56338909Sborman } 56438909Sborman } 56538909Sborman return 1; 56638909Sborman } 56738909Sborman 56846808Sdab static int 56938909Sborman togxbinary(val) 57046808Sdab int val; 57138909Sborman { 57238909Sborman donebinarytoggle = 1; 57338909Sborman 57438909Sborman if (val == -1) 57538909Sborman val = my_want_state_is_will(TELOPT_BINARY) ? 0 : 1; 57638909Sborman 57738909Sborman if (val == 1) { 57838909Sborman if (my_want_state_is_will(TELOPT_BINARY)) { 57938909Sborman printf("Already transmitting in binary mode.\n"); 58038909Sborman } else { 58138909Sborman printf("Negotiating binary mode on output.\n"); 58238909Sborman tel_enter_binary(2); 58338909Sborman } 58438909Sborman } else { 58538909Sborman if (my_want_state_is_wont(TELOPT_BINARY)) { 58638909Sborman printf("Already transmitting in network ascii mode.\n"); 58738909Sborman } else { 58838909Sborman printf("Negotiating network ascii mode on output.\n"); 58938909Sborman tel_leave_binary(2); 59038909Sborman } 59138909Sborman } 59238909Sborman return 1; 59338909Sborman } 59438909Sborman 59538909Sborman 59656642Sralph static int togglehelp P((void)); 59757213Sdab #if defined(AUTHENTICATION) 59847609Sdab extern int auth_togdebug P((int)); 59947609Sdab #endif 60057213Sdab #if defined(ENCRYPTION) 60147609Sdab extern int EncryptAutoEnc P((int)); 60247609Sdab extern int EncryptAutoDec P((int)); 60347609Sdab extern int EncryptDebug P((int)); 60447609Sdab extern int EncryptVerbose P((int)); 60547609Sdab #endif 60632144Sminshall 60732144Sminshall struct togglelist { 60832144Sminshall char *name; /* name of toggle */ 60932144Sminshall char *help; /* help message */ 61032144Sminshall int (*handler)(); /* routine to do actual setting */ 61132144Sminshall int *variable; 61232144Sminshall char *actionexplanation; 61332144Sminshall }; 61432144Sminshall 61532144Sminshall static struct togglelist Togglelist[] = { 61632144Sminshall { "autoflush", 61738689Sborman "flushing of output when sending interrupt characters", 61832144Sminshall 0, 61938689Sborman &autoflush, 62038689Sborman "flush output when sending interrupt characters" }, 62132144Sminshall { "autosynch", 62238689Sborman "automatic sending of interrupt characters in urgent mode", 62332144Sminshall 0, 62438689Sborman &autosynch, 62538689Sborman "send interrupt characters in urgent mode" }, 62657213Sdab #if defined(AUTHENTICATION) 62747609Sdab { "autologin", 62847609Sdab "automatic sending of login and/or authentication info", 62947609Sdab 0, 63047609Sdab &autologin, 63147609Sdab "send login name and/or authentication information" }, 63247609Sdab { "authdebug", 63347609Sdab "Toggle authentication debugging", 63447609Sdab auth_togdebug, 63547609Sdab 0, 63647609Sdab "print authentication debugging information" }, 63747609Sdab #endif 63857213Sdab #if defined(ENCRYPTION) 63947609Sdab { "autoencrypt", 64047609Sdab "automatic encryption of data stream", 64147609Sdab EncryptAutoEnc, 64247609Sdab 0, 64347609Sdab "automatically encrypt output" }, 64447609Sdab { "autodecrypt", 64547609Sdab "automatic decryption of data stream", 64647609Sdab EncryptAutoDec, 64747609Sdab 0, 64847609Sdab "automatically decrypt input" }, 64947609Sdab { "verbose_encrypt", 65047609Sdab "Toggle verbose encryption output", 65147609Sdab EncryptVerbose, 65247609Sdab 0, 65347609Sdab "print verbose encryption output" }, 65447609Sdab { "encdebug", 65547609Sdab "Toggle encryption debugging", 65647609Sdab EncryptDebug, 65747609Sdab 0, 65847609Sdab "print encryption debugging information" }, 65947609Sdab #endif 66047609Sdab { "skiprc", 66147609Sdab "don't read ~/.telnetrc file", 66247609Sdab 0, 66347609Sdab &skiprc, 664*57848Sdab "skip reading of ~/.telnetrc file" }, 66532144Sminshall { "binary", 66638689Sborman "sending and receiving of binary data", 66732144Sminshall togbinary, 66838689Sborman 0, 66938689Sborman 0 }, 67038909Sborman { "inbinary", 67138909Sborman "receiving of binary data", 67238909Sborman togrbinary, 67338909Sborman 0, 67438909Sborman 0 }, 67538909Sborman { "outbinary", 67638909Sborman "sending of binary data", 67738909Sborman togxbinary, 67838909Sborman 0, 67938909Sborman 0 }, 68032144Sminshall { "crlf", 68138689Sborman "sending carriage returns as telnet <CR><LF>", 68232144Sminshall togcrlf, 68338689Sborman &crlf, 68438689Sborman 0 }, 68532144Sminshall { "crmod", 68638689Sborman "mapping of received carriage returns", 68732144Sminshall 0, 68838689Sborman &crmod, 68938689Sborman "map carriage return on output" }, 69032144Sminshall { "localchars", 69138689Sborman "local recognition of certain control characters", 69232144Sminshall lclchars, 69338689Sborman &localchars, 69438689Sborman "recognize certain control characters" }, 69538689Sborman { " ", "", 0 }, /* empty line */ 69638208Sminshall #if defined(unix) && defined(TN3270) 69738920Sminshall { "apitrace", 69838920Sminshall "(debugging) toggle tracing of API transactions", 69938920Sminshall 0, 70038920Sminshall &apitrace, 70138920Sminshall "trace API transactions" }, 70238208Sminshall { "cursesdata", 70338208Sminshall "(debugging) toggle printing of hexadecimal curses data", 70438208Sminshall 0, 70538689Sborman &cursesdata, 70638689Sborman "print hexadecimal representation of curses data" }, 70738208Sminshall #endif /* defined(unix) && defined(TN3270) */ 70832144Sminshall { "debug", 70938689Sborman "debugging", 71032144Sminshall togdebug, 71138689Sborman &debug, 71238689Sborman "turn on socket level debugging" }, 71332144Sminshall { "netdata", 71438689Sborman "printing of hexadecimal network data (debugging)", 71532144Sminshall 0, 71638689Sborman &netdata, 71738689Sborman "print hexadecimal representation of network traffic" }, 71838689Sborman { "prettydump", 71938689Sborman "output of \"netdata\" to user readable format (debugging)", 72038689Sborman 0, 72138689Sborman &prettydump, 72238689Sborman "print user readable output for \"netdata\"" }, 72332144Sminshall { "options", 72438689Sborman "viewing of options processing (debugging)", 72532144Sminshall 0, 72638689Sborman &showoptions, 72738689Sborman "show option processing" }, 72838208Sminshall #if defined(unix) 72938208Sminshall { "termdata", 73038208Sminshall "(debugging) toggle printing of hexadecimal terminal data", 73138208Sminshall 0, 73238689Sborman &termdata, 73338689Sborman "print hexadecimal representation of terminal traffic" }, 73438208Sminshall #endif /* defined(unix) */ 73532144Sminshall { "?", 73638689Sborman 0, 73738689Sborman togglehelp }, 73832144Sminshall { "help", 73938689Sborman 0, 74038689Sborman togglehelp }, 74132144Sminshall { 0 } 74232144Sminshall }; 74332144Sminshall 74446808Sdab static int 74532144Sminshall togglehelp() 74632144Sminshall { 74732144Sminshall struct togglelist *c; 74832144Sminshall 74932144Sminshall for (c = Togglelist; c->name; c++) { 75038689Sborman if (c->help) { 75138689Sborman if (*c->help) 75238689Sborman printf("%-15s toggle %s\n", c->name, c->help); 75338689Sborman else 75438689Sborman printf("\n"); 75532144Sminshall } 75632144Sminshall } 75738689Sborman printf("\n"); 75838689Sborman printf("%-15s %s\n", "?", "display help information"); 75932144Sminshall return 0; 76032144Sminshall } 76132144Sminshall 76246808Sdab static void 76338689Sborman settogglehelp(set) 76446808Sdab int set; 76538689Sborman { 76638689Sborman struct togglelist *c; 76738689Sborman 76838689Sborman for (c = Togglelist; c->name; c++) { 76938689Sborman if (c->help) { 77038689Sborman if (*c->help) 77138689Sborman printf("%-15s %s %s\n", c->name, set ? "enable" : "disable", 77238689Sborman c->help); 77338689Sborman else 77438689Sborman printf("\n"); 77538689Sborman } 77638689Sborman } 77738689Sborman } 77838689Sborman 77946808Sdab #define GETTOGGLE(name) (struct togglelist *) \ 78046808Sdab genget(name, (char **) Togglelist, sizeof(struct togglelist)) 78132144Sminshall 78246808Sdab static int 78332144Sminshall toggle(argc, argv) 78446808Sdab int argc; 78546808Sdab char *argv[]; 78632144Sminshall { 78732144Sminshall int retval = 1; 78832144Sminshall char *name; 78932144Sminshall struct togglelist *c; 79032144Sminshall 79132144Sminshall if (argc < 2) { 79232144Sminshall fprintf(stderr, 79332144Sminshall "Need an argument to 'toggle' command. 'toggle ?' for help.\n"); 79432144Sminshall return 0; 79532144Sminshall } 79632144Sminshall argc--; 79732144Sminshall argv++; 79832144Sminshall while (argc--) { 79932144Sminshall name = *argv++; 80046808Sdab c = GETTOGGLE(name); 80132144Sminshall if (Ambiguous(c)) { 80232144Sminshall fprintf(stderr, "'%s': ambiguous argument ('toggle ?' for help).\n", 80332144Sminshall name); 80432144Sminshall return 0; 80532144Sminshall } else if (c == 0) { 80632144Sminshall fprintf(stderr, "'%s': unknown argument ('toggle ?' for help).\n", 80732144Sminshall name); 80832144Sminshall return 0; 80932144Sminshall } else { 81032144Sminshall if (c->variable) { 81132144Sminshall *c->variable = !*c->variable; /* invert it */ 81232144Sminshall if (c->actionexplanation) { 81332144Sminshall printf("%s %s.\n", *c->variable? "Will" : "Won't", 81432144Sminshall c->actionexplanation); 81532144Sminshall } 81632144Sminshall } 81732144Sminshall if (c->handler) { 81838689Sborman retval &= (*c->handler)(-1); 81932144Sminshall } 82032144Sminshall } 82132144Sminshall } 82232144Sminshall return retval; 82332144Sminshall } 82432144Sminshall 82532144Sminshall /* 82632144Sminshall * The following perform the "set" command. 82732144Sminshall */ 82832144Sminshall 82938689Sborman #ifdef USE_TERMIO 83038689Sborman struct termio new_tc = { 0 }; 83138689Sborman #endif 83238689Sborman 83332144Sminshall struct setlist { 83432144Sminshall char *name; /* name */ 83532144Sminshall char *help; /* help information */ 83638689Sborman void (*handler)(); 83740245Sborman cc_t *charp; /* where it is located at */ 83832144Sminshall }; 83932144Sminshall 84032144Sminshall static struct setlist Setlist[] = { 84144361Sborman #ifdef KLUDGELINEMODE 84238689Sborman { "echo", "character to toggle local echoing on/off", 0, &echoc }, 84344361Sborman #endif 84438689Sborman { "escape", "character to escape back to telnet command mode", 0, &escape }, 84546808Sdab { "rlogin", "rlogin escape character", 0, &rlogin }, 84645233Sborman { "tracefile", "file to write trace information to", SetNetTrace, (cc_t *)NetTraceFile}, 84732144Sminshall { " ", "" }, 84838689Sborman { " ", "The following need 'localchars' to be toggled true", 0, 0 }, 84945233Sborman { "flushoutput", "character to cause an Abort Output", 0, termFlushCharp }, 85038689Sborman { "interrupt", "character to cause an Interrupt Process", 0, termIntCharp }, 85138689Sborman { "quit", "character to cause an Abort process", 0, termQuitCharp }, 85238689Sborman { "eof", "character to cause an EOF ", 0, termEofCharp }, 85338689Sborman { " ", "" }, 85438689Sborman { " ", "The following are for local editing in linemode", 0, 0 }, 85538689Sborman { "erase", "character to use to erase a character", 0, termEraseCharp }, 85638689Sborman { "kill", "character to use to erase a line", 0, termKillCharp }, 85738689Sborman { "lnext", "character to use for literal next", 0, termLiteralNextCharp }, 85844361Sborman { "susp", "character to cause a Suspend Process", 0, termSuspCharp }, 85938689Sborman { "reprint", "character to use for line reprint", 0, termRprntCharp }, 86038689Sborman { "worderase", "character to use to erase a word", 0, termWerasCharp }, 86138689Sborman { "start", "character to use for XON", 0, termStartCharp }, 86244361Sborman { "stop", "character to use for XOFF", 0, termStopCharp }, 86344361Sborman { "forw1", "alternate end of line character", 0, termForw1Charp }, 86444361Sborman { "forw2", "alternate end of line character", 0, termForw2Charp }, 86545233Sborman { "ayt", "alternate AYT character", 0, termAytCharp }, 86632144Sminshall { 0 } 86732144Sminshall }; 86832144Sminshall 86945233Sborman #if defined(CRAY) && !defined(__STDC__) 87045233Sborman /* Work around compiler bug in pcc 4.1.5 */ 87146808Sdab void 87238689Sborman _setlist_init() 87338689Sborman { 87444361Sborman #ifndef KLUDGELINEMODE 87546808Sdab #define N 5 87644361Sborman #else 87746808Sdab #define N 6 87844361Sborman #endif 87944361Sborman Setlist[N+0].charp = &termFlushChar; 88044361Sborman Setlist[N+1].charp = &termIntChar; 88144361Sborman Setlist[N+2].charp = &termQuitChar; 88244361Sborman Setlist[N+3].charp = &termEofChar; 88344361Sborman Setlist[N+6].charp = &termEraseChar; 88444361Sborman Setlist[N+7].charp = &termKillChar; 88544361Sborman Setlist[N+8].charp = &termLiteralNextChar; 88644361Sborman Setlist[N+9].charp = &termSuspChar; 88744361Sborman Setlist[N+10].charp = &termRprntChar; 88844361Sborman Setlist[N+11].charp = &termWerasChar; 88944361Sborman Setlist[N+12].charp = &termStartChar; 89044361Sborman Setlist[N+13].charp = &termStopChar; 89144361Sborman Setlist[N+14].charp = &termForw1Char; 89244361Sborman Setlist[N+15].charp = &termForw2Char; 89345233Sborman Setlist[N+16].charp = &termAytChar; 89444361Sborman #undef N 89538689Sborman } 89645233Sborman #endif /* defined(CRAY) && !defined(__STDC__) */ 89738689Sborman 89846808Sdab static struct setlist * 89932144Sminshall getset(name) 90046808Sdab char *name; 90132144Sminshall { 90246808Sdab return (struct setlist *) 90346808Sdab genget(name, (char **) Setlist, sizeof(struct setlist)); 90432144Sminshall } 90532144Sminshall 90646808Sdab void 90744361Sborman set_escape_char(s) 90846808Sdab char *s; 90944361Sborman { 91046808Sdab if (rlogin != _POSIX_VDISABLE) { 91146808Sdab rlogin = (s && *s) ? special(s) : _POSIX_VDISABLE; 91246808Sdab printf("Telnet rlogin escape character is '%s'.\n", 91346808Sdab control(rlogin)); 91446808Sdab } else { 91546808Sdab escape = (s && *s) ? special(s) : _POSIX_VDISABLE; 91646808Sdab printf("Telnet escape character is '%s'.\n", control(escape)); 91746808Sdab } 91844361Sborman } 91944361Sborman 92046808Sdab static int 92132144Sminshall setcmd(argc, argv) 92246808Sdab int argc; 92346808Sdab char *argv[]; 92432144Sminshall { 92532144Sminshall int value; 92632144Sminshall struct setlist *ct; 92738689Sborman struct togglelist *c; 92832144Sminshall 92938689Sborman if (argc < 2 || argc > 3) { 93038689Sborman printf("Format is 'set Name Value'\n'set ?' for help.\n"); 93132144Sminshall return 0; 93232144Sminshall } 93346808Sdab if ((argc == 2) && (isprefix(argv[1], "?") || isprefix(argv[1], "help"))) { 93438689Sborman for (ct = Setlist; ct->name; ct++) 93538689Sborman printf("%-15s %s\n", ct->name, ct->help); 93638689Sborman printf("\n"); 93738689Sborman settogglehelp(1); 93838689Sborman printf("%-15s %s\n", "?", "display help information"); 93938689Sborman return 0; 94038689Sborman } 94132144Sminshall 94232144Sminshall ct = getset(argv[1]); 94332144Sminshall if (ct == 0) { 94446808Sdab c = GETTOGGLE(argv[1]); 94538689Sborman if (c == 0) { 94638689Sborman fprintf(stderr, "'%s': unknown argument ('set ?' for help).\n", 94732144Sminshall argv[1]); 94838689Sborman return 0; 94938689Sborman } else if (Ambiguous(c)) { 95038689Sborman fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n", 95138689Sborman argv[1]); 95238689Sborman return 0; 95338689Sborman } 95438689Sborman if (c->variable) { 95538689Sborman if ((argc == 2) || (strcmp("on", argv[2]) == 0)) 95638689Sborman *c->variable = 1; 95738689Sborman else if (strcmp("off", argv[2]) == 0) 95838689Sborman *c->variable = 0; 95938689Sborman else { 96038689Sborman printf("Format is 'set togglename [on|off]'\n'set ?' for help.\n"); 96138689Sborman return 0; 96238689Sborman } 96338689Sborman if (c->actionexplanation) { 96438689Sborman printf("%s %s.\n", *c->variable? "Will" : "Won't", 96538689Sborman c->actionexplanation); 96638689Sborman } 96738689Sborman } 96838689Sborman if (c->handler) 96938689Sborman (*c->handler)(1); 97038689Sborman } else if (argc != 3) { 97138689Sborman printf("Format is 'set Name Value'\n'set ?' for help.\n"); 97232144Sminshall return 0; 97332144Sminshall } else if (Ambiguous(ct)) { 97432144Sminshall fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n", 97532144Sminshall argv[1]); 97632144Sminshall return 0; 97738689Sborman } else if (ct->handler) { 97838689Sborman (*ct->handler)(argv[2]); 97944361Sborman printf("%s set to \"%s\".\n", ct->name, (char *)ct->charp); 98032144Sminshall } else { 98132144Sminshall if (strcmp("off", argv[2])) { 98232144Sminshall value = special(argv[2]); 98332144Sminshall } else { 98445233Sborman value = _POSIX_VDISABLE; 98532144Sminshall } 98640245Sborman *(ct->charp) = (cc_t)value; 98732144Sminshall printf("%s character is '%s'.\n", ct->name, control(*(ct->charp))); 98832144Sminshall } 98938689Sborman slc_check(); 99032144Sminshall return 1; 99132144Sminshall } 99238689Sborman 99346808Sdab static int 99438689Sborman unsetcmd(argc, argv) 99546808Sdab int argc; 99646808Sdab char *argv[]; 99738689Sborman { 99838689Sborman struct setlist *ct; 99938689Sborman struct togglelist *c; 100038689Sborman register char *name; 100138689Sborman 100238689Sborman if (argc < 2) { 100338689Sborman fprintf(stderr, 100438689Sborman "Need an argument to 'unset' command. 'unset ?' for help.\n"); 100538689Sborman return 0; 100638689Sborman } 100746808Sdab if (isprefix(argv[1], "?") || isprefix(argv[1], "help")) { 100838689Sborman for (ct = Setlist; ct->name; ct++) 100938689Sborman printf("%-15s %s\n", ct->name, ct->help); 101038689Sborman printf("\n"); 101138689Sborman settogglehelp(0); 101238689Sborman printf("%-15s %s\n", "?", "display help information"); 101338689Sborman return 0; 101438689Sborman } 101538689Sborman 101638689Sborman argc--; 101738689Sborman argv++; 101838689Sborman while (argc--) { 101938689Sborman name = *argv++; 102038689Sborman ct = getset(name); 102138689Sborman if (ct == 0) { 102246808Sdab c = GETTOGGLE(name); 102338689Sborman if (c == 0) { 102438689Sborman fprintf(stderr, "'%s': unknown argument ('unset ?' for help).\n", 102538689Sborman name); 102638689Sborman return 0; 102738689Sborman } else if (Ambiguous(c)) { 102838689Sborman fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n", 102938689Sborman name); 103038689Sborman return 0; 103138689Sborman } 103238689Sborman if (c->variable) { 103338689Sborman *c->variable = 0; 103438689Sborman if (c->actionexplanation) { 103538689Sborman printf("%s %s.\n", *c->variable? "Will" : "Won't", 103638689Sborman c->actionexplanation); 103738689Sborman } 103838689Sborman } 103938689Sborman if (c->handler) 104038689Sborman (*c->handler)(0); 104138689Sborman } else if (Ambiguous(ct)) { 104238689Sborman fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n", 104338689Sborman name); 104438689Sborman return 0; 104538689Sborman } else if (ct->handler) { 104638689Sborman (*ct->handler)(0); 104744361Sborman printf("%s reset to \"%s\".\n", ct->name, (char *)ct->charp); 104838689Sborman } else { 104945233Sborman *(ct->charp) = _POSIX_VDISABLE; 105038689Sborman printf("%s character is '%s'.\n", ct->name, control(*(ct->charp))); 105138689Sborman } 105238689Sborman } 105338689Sborman return 1; 105438689Sborman } 105532144Sminshall 105632144Sminshall /* 105732144Sminshall * The following are the data structures and routines for the 105832144Sminshall * 'mode' command. 105932144Sminshall */ 106038689Sborman #ifdef KLUDGELINEMODE 106138689Sborman extern int kludgelinemode; 106244361Sborman 106346808Sdab static int 106444361Sborman dokludgemode() 106544361Sborman { 106644361Sborman kludgelinemode = 1; 106744361Sborman send_wont(TELOPT_LINEMODE, 1); 106844361Sborman send_dont(TELOPT_SGA, 1); 106944361Sborman send_dont(TELOPT_ECHO, 1); 107044361Sborman } 107138689Sborman #endif 107232144Sminshall 107346808Sdab static int 107432144Sminshall dolinemode() 107532144Sminshall { 107638689Sborman #ifdef KLUDGELINEMODE 107738689Sborman if (kludgelinemode) 107838689Sborman send_dont(TELOPT_SGA, 1); 107938689Sborman #endif 108038689Sborman send_will(TELOPT_LINEMODE, 1); 108138689Sborman send_dont(TELOPT_ECHO, 1); 108232144Sminshall return 1; 108332144Sminshall } 108432144Sminshall 108546808Sdab static int 108632144Sminshall docharmode() 108732144Sminshall { 108838689Sborman #ifdef KLUDGELINEMODE 108938689Sborman if (kludgelinemode) 109038689Sborman send_do(TELOPT_SGA, 1); 109138689Sborman else 109238689Sborman #endif 109338689Sborman send_wont(TELOPT_LINEMODE, 1); 109438689Sborman send_do(TELOPT_ECHO, 1); 109538689Sborman return 1; 109638689Sborman } 109738689Sborman 109846808Sdab static int 109938689Sborman dolmmode(bit, on) 110046808Sdab int bit, on; 110138689Sborman { 110246808Sdab unsigned char c; 110338689Sborman extern int linemode; 110438689Sborman 110538689Sborman if (my_want_state_is_wont(TELOPT_LINEMODE)) { 110638689Sborman printf("?Need to have LINEMODE option enabled first.\n"); 110738689Sborman printf("'mode ?' for help.\n"); 110838689Sborman return 0; 110932144Sminshall } 111038689Sborman 111138689Sborman if (on) 111238689Sborman c = (linemode | bit); 111338689Sborman else 111438689Sborman c = (linemode & ~bit); 111538689Sborman lm_mode(&c, 1, 1); 111632144Sminshall return 1; 111732144Sminshall } 111832144Sminshall 111946808Sdab int 112046808Sdab setmode(bit) 112146808Sdab { 112246808Sdab return dolmmode(bit, 1); 112346808Sdab } 112446808Sdab 112546808Sdab int 112646808Sdab clearmode(bit) 112746808Sdab { 112846808Sdab return dolmmode(bit, 0); 112946808Sdab } 113046808Sdab 113138689Sborman struct modelist { 113238689Sborman char *name; /* command name */ 113338689Sborman char *help; /* help string */ 113438689Sborman int (*handler)(); /* routine which executes command */ 113538689Sborman int needconnect; /* Do we need to be connected to execute? */ 113638689Sborman int arg1; 113738689Sborman }; 113838689Sborman 113938689Sborman extern int modehelp(); 114038689Sborman 114138689Sborman static struct modelist ModeList[] = { 114238689Sborman { "character", "Disable LINEMODE option", docharmode, 1 }, 114339529Sborman #ifdef KLUDGELINEMODE 114439529Sborman { "", "(or disable obsolete line-by-line mode)", 0 }, 114538689Sborman #endif 114638689Sborman { "line", "Enable LINEMODE option", dolinemode, 1 }, 114739529Sborman #ifdef KLUDGELINEMODE 114839529Sborman { "", "(or enable obsolete line-by-line mode)", 0 }, 114938689Sborman #endif 115038689Sborman { "", "", 0 }, 115138689Sborman { "", "These require the LINEMODE option to be enabled", 0 }, 115238689Sborman { "isig", "Enable signal trapping", setmode, 1, MODE_TRAPSIG }, 115338689Sborman { "+isig", 0, setmode, 1, MODE_TRAPSIG }, 115438689Sborman { "-isig", "Disable signal trapping", clearmode, 1, MODE_TRAPSIG }, 115538689Sborman { "edit", "Enable character editing", setmode, 1, MODE_EDIT }, 115638689Sborman { "+edit", 0, setmode, 1, MODE_EDIT }, 115738689Sborman { "-edit", "Disable character editing", clearmode, 1, MODE_EDIT }, 115844361Sborman { "softtabs", "Enable tab expansion", setmode, 1, MODE_SOFT_TAB }, 115944361Sborman { "+softtabs", 0, setmode, 1, MODE_SOFT_TAB }, 116044361Sborman { "-softtabs", "Disable character editing", clearmode, 1, MODE_SOFT_TAB }, 116144361Sborman { "litecho", "Enable literal character echo", setmode, 1, MODE_LIT_ECHO }, 116244361Sborman { "+litecho", 0, setmode, 1, MODE_LIT_ECHO }, 116344361Sborman { "-litecho", "Disable literal character echo", clearmode, 1, MODE_LIT_ECHO }, 116438689Sborman { "help", 0, modehelp, 0 }, 116544361Sborman #ifdef KLUDGELINEMODE 116644361Sborman { "kludgeline", 0, dokludgemode, 1 }, 116744361Sborman #endif 116844361Sborman { "", "", 0 }, 116938689Sborman { "?", "Print help information", modehelp, 0 }, 117032144Sminshall { 0 }, 117132144Sminshall }; 117232144Sminshall 117332144Sminshall 117446808Sdab int 117538689Sborman modehelp() 117638689Sborman { 117738689Sborman struct modelist *mt; 117838689Sborman 117938689Sborman printf("format is: 'mode Mode', where 'Mode' is one of:\n\n"); 118038689Sborman for (mt = ModeList; mt->name; mt++) { 118138689Sborman if (mt->help) { 118238689Sborman if (*mt->help) 118338689Sborman printf("%-15s %s\n", mt->name, mt->help); 118438689Sborman else 118538689Sborman printf("\n"); 118638689Sborman } 118738689Sborman } 118838689Sborman return 0; 118938689Sborman } 119038689Sborman 119146808Sdab #define GETMODECMD(name) (struct modelist *) \ 119246808Sdab genget(name, (char **) ModeList, sizeof(struct modelist)) 119346808Sdab 119446808Sdab static int 119532144Sminshall modecmd(argc, argv) 119646808Sdab int argc; 119746808Sdab char *argv[]; 119832144Sminshall { 119938689Sborman struct modelist *mt; 120032144Sminshall 120138689Sborman if (argc != 2) { 120238689Sborman printf("'mode' command requires an argument\n"); 120338689Sborman printf("'mode ?' for help.\n"); 120446808Sdab } else if ((mt = GETMODECMD(argv[1])) == 0) { 120532144Sminshall fprintf(stderr, "Unknown mode '%s' ('mode ?' for help).\n", argv[1]); 120632144Sminshall } else if (Ambiguous(mt)) { 120732144Sminshall fprintf(stderr, "Ambiguous mode '%s' ('mode ?' for help).\n", argv[1]); 120838689Sborman } else if (mt->needconnect && !connected) { 120938689Sborman printf("?Need to be connected first.\n"); 121038689Sborman printf("'mode ?' for help.\n"); 121138689Sborman } else if (mt->handler) { 121238689Sborman return (*mt->handler)(mt->arg1); 121332144Sminshall } 121438689Sborman return 0; 121532144Sminshall } 121632144Sminshall 121732144Sminshall /* 121832144Sminshall * The following data structures and routines implement the 121932144Sminshall * "display" command. 122032144Sminshall */ 122132144Sminshall 122246808Sdab static int 122332144Sminshall display(argc, argv) 122446808Sdab int argc; 122546808Sdab char *argv[]; 122632144Sminshall { 122746808Sdab struct togglelist *tl; 122846808Sdab struct setlist *sl; 122946808Sdab 123032144Sminshall #define dotog(tl) if (tl->variable && tl->actionexplanation) { \ 123132144Sminshall if (*tl->variable) { \ 123232144Sminshall printf("will"); \ 123332144Sminshall } else { \ 123432144Sminshall printf("won't"); \ 123532144Sminshall } \ 123632144Sminshall printf(" %s.\n", tl->actionexplanation); \ 123732144Sminshall } 123832144Sminshall 123932144Sminshall #define doset(sl) if (sl->name && *sl->name != ' ') { \ 124038689Sborman if (sl->handler == 0) \ 124138689Sborman printf("%-15s [%s]\n", sl->name, control(*sl->charp)); \ 124238689Sborman else \ 124344361Sborman printf("%-15s \"%s\"\n", sl->name, (char *)sl->charp); \ 124432144Sminshall } 124532144Sminshall 124632144Sminshall if (argc == 1) { 124732144Sminshall for (tl = Togglelist; tl->name; tl++) { 124832144Sminshall dotog(tl); 124932144Sminshall } 125032144Sminshall printf("\n"); 125132144Sminshall for (sl = Setlist; sl->name; sl++) { 125232144Sminshall doset(sl); 125332144Sminshall } 125432144Sminshall } else { 125532144Sminshall int i; 125632144Sminshall 125732144Sminshall for (i = 1; i < argc; i++) { 125832144Sminshall sl = getset(argv[i]); 125946808Sdab tl = GETTOGGLE(argv[i]); 126032144Sminshall if (Ambiguous(sl) || Ambiguous(tl)) { 126132144Sminshall printf("?Ambiguous argument '%s'.\n", argv[i]); 126232144Sminshall return 0; 126332144Sminshall } else if (!sl && !tl) { 126432144Sminshall printf("?Unknown argument '%s'.\n", argv[i]); 126532144Sminshall return 0; 126632144Sminshall } else { 126732144Sminshall if (tl) { 126832144Sminshall dotog(tl); 126932144Sminshall } 127032144Sminshall if (sl) { 127132144Sminshall doset(sl); 127232144Sminshall } 127332144Sminshall } 127432144Sminshall } 127532144Sminshall } 127638689Sborman /*@*/optionstatus(); 127757213Sdab #if defined(ENCRYPTION) 127846808Sdab EncryptStatus(); 127946808Sdab #endif 128032144Sminshall return 1; 128132144Sminshall #undef doset 128232144Sminshall #undef dotog 128332144Sminshall } 128432144Sminshall 128532144Sminshall /* 128632144Sminshall * The following are the data structures, and many of the routines, 128732144Sminshall * relating to command processing. 128832144Sminshall */ 128932144Sminshall 129032144Sminshall /* 129132144Sminshall * Set the escape character. 129232144Sminshall */ 129346808Sdab static int 129432144Sminshall setescape(argc, argv) 129532144Sminshall int argc; 129632144Sminshall char *argv[]; 129732144Sminshall { 129832144Sminshall register char *arg; 129932144Sminshall char buf[50]; 130032144Sminshall 130132144Sminshall printf( 130232144Sminshall "Deprecated usage - please use 'set escape%s%s' in the future.\n", 130332144Sminshall (argc > 2)? " ":"", (argc > 2)? argv[1]: ""); 130432144Sminshall if (argc > 2) 130532144Sminshall arg = argv[1]; 130632144Sminshall else { 130732144Sminshall printf("new escape character: "); 130846808Sdab (void) fgets(buf, sizeof(buf), stdin); 130932144Sminshall arg = buf; 131032144Sminshall } 131132144Sminshall if (arg[0] != '\0') 131232144Sminshall escape = arg[0]; 131332144Sminshall if (!In3270) { 131432144Sminshall printf("Escape character is '%s'.\n", control(escape)); 131532144Sminshall } 131634849Sminshall (void) fflush(stdout); 131732144Sminshall return 1; 131832144Sminshall } 131932144Sminshall 132046808Sdab /*VARARGS*/ 132146808Sdab static int 132232144Sminshall togcrmod() 132332144Sminshall { 132432144Sminshall crmod = !crmod; 132532144Sminshall printf("Deprecated usage - please use 'toggle crmod' in the future.\n"); 132632144Sminshall printf("%s map carriage return on output.\n", crmod ? "Will" : "Won't"); 132734849Sminshall (void) fflush(stdout); 132832144Sminshall return 1; 132932144Sminshall } 133032144Sminshall 133146808Sdab /*VARARGS*/ 133246808Sdab int 133332144Sminshall suspend() 133432144Sminshall { 133538689Sborman #ifdef SIGTSTP 133637219Sminshall setcommandmode(); 133737219Sminshall { 133844361Sborman long oldrows, oldcols, newrows, newcols, err; 133937219Sminshall 134057213Sdab err = (TerminalWindowSize(&oldrows, &oldcols) == 0) ? 1 : 0; 134134849Sminshall (void) kill(0, SIGTSTP); 134257213Sdab /* 134357213Sdab * If we didn't get the window size before the SUSPEND, but we 134457213Sdab * can get them now (???), then send the NAWS to make sure that 134557213Sdab * we are set up for the right window size. 134657213Sdab */ 134757213Sdab if (TerminalWindowSize(&newrows, &newcols) && connected && 134857213Sdab (err || ((oldrows != newrows) || (oldcols != newcols)))) { 134937219Sminshall sendnaws(); 135037219Sminshall } 135137219Sminshall } 135237219Sminshall /* reget parameters in case they were changed */ 135337219Sminshall TerminalSaveState(); 135438689Sborman setconnmode(0); 135538689Sborman #else 135638689Sborman printf("Suspend is not supported. Try the '!' command instead\n"); 135738689Sborman #endif 135837219Sminshall return 1; 135932144Sminshall } 136032144Sminshall 136138689Sborman #if !defined(TN3270) 136246808Sdab /*ARGSUSED*/ 136346808Sdab int 136438689Sborman shell(argc, argv) 136546808Sdab int argc; 136646808Sdab char *argv[]; 136738689Sborman { 136857213Sdab long oldrows, oldcols, newrows, newcols, err; 136957213Sdab 137038689Sborman setcommandmode(); 137157213Sdab 137257213Sdab err = (TerminalWindowSize(&oldrows, &oldcols) == 0) ? 1 : 0; 137338689Sborman switch(vfork()) { 137438689Sborman case -1: 137538689Sborman perror("Fork failed\n"); 137638689Sborman break; 137738689Sborman 137838689Sborman case 0: 137938689Sborman { 138038689Sborman /* 138138689Sborman * Fire up the shell in the child. 138238689Sborman */ 138346808Sdab register char *shellp, *shellname; 138446808Sdab extern char *rindex(); 138538689Sborman 138646808Sdab shellp = getenv("SHELL"); 138746808Sdab if (shellp == NULL) 138846808Sdab shellp = "/bin/sh"; 138946808Sdab if ((shellname = rindex(shellp, '/')) == 0) 139046808Sdab shellname = shellp; 139138689Sborman else 139238689Sborman shellname++; 139338689Sborman if (argc > 1) 139446808Sdab execl(shellp, shellname, "-c", &saveline[1], 0); 139538689Sborman else 139646808Sdab execl(shellp, shellname, 0); 139738689Sborman perror("Execl"); 139838689Sborman _exit(1); 139938689Sborman } 140038689Sborman default: 140144361Sborman (void)wait((int *)0); /* Wait for the shell to complete */ 140257213Sdab 140357213Sdab if (TerminalWindowSize(&newrows, &newcols) && connected && 140457213Sdab (err || ((oldrows != newrows) || (oldcols != newcols)))) { 140557213Sdab sendnaws(); 140657213Sdab } 140757213Sdab break; 140838689Sborman } 140946808Sdab return 1; 141038689Sborman } 141138689Sborman #endif /* !defined(TN3270) */ 141238689Sborman 141346808Sdab /*VARARGS*/ 141446808Sdab static 141532144Sminshall bye(argc, argv) 141646808Sdab int argc; /* Number of arguments */ 141746808Sdab char *argv[]; /* arguments */ 141832144Sminshall { 141946808Sdab extern int resettermname; 142046808Sdab 142132144Sminshall if (connected) { 142234849Sminshall (void) shutdown(net, 2); 142332144Sminshall printf("Connection closed.\n"); 142434849Sminshall (void) NetClose(net); 142532144Sminshall connected = 0; 142646808Sdab resettermname = 1; 142757213Sdab #if defined(AUTHENTICATION) || defined(ENCRYPTION) 142846808Sdab auth_encrypt_connect(connected); 142946808Sdab #endif 143032144Sminshall /* reset options */ 143132144Sminshall tninit(); 143232144Sminshall #if defined(TN3270) 143332144Sminshall SetIn3270(); /* Get out of 3270 mode */ 143432144Sminshall #endif /* defined(TN3270) */ 143532144Sminshall } 143632144Sminshall if ((argc != 2) || (strcmp(argv[1], "fromquit") != 0)) { 143732144Sminshall longjmp(toplevel, 1); 143832144Sminshall /* NOTREACHED */ 143932144Sminshall } 144032144Sminshall return 1; /* Keep lint, etc., happy */ 144132144Sminshall } 144232144Sminshall 144332144Sminshall /*VARARGS*/ 144432144Sminshall quit() 144532144Sminshall { 144632144Sminshall (void) call(bye, "bye", "fromquit", 0); 144732144Sminshall Exit(0); 144844361Sborman /*NOTREACHED*/ 144932144Sminshall } 145046808Sdab 145146808Sdab /*VARARGS*/ 145246808Sdab int 145346808Sdab logout() 145446808Sdab { 145546808Sdab send_do(TELOPT_LOGOUT, 1); 145646808Sdab (void) netflush(); 145746808Sdab return 1; 145846808Sdab } 145946808Sdab 146038689Sborman 146138689Sborman /* 146238689Sborman * The SLC command. 146338689Sborman */ 146432144Sminshall 146538689Sborman struct slclist { 146638689Sborman char *name; 146738689Sborman char *help; 146846808Sdab void (*handler)(); 146938689Sborman int arg; 147038689Sborman }; 147138689Sborman 147256642Sralph static void slc_help(); 147338689Sborman 147438689Sborman struct slclist SlcList[] = { 147538689Sborman { "export", "Use local special character definitions", 147638689Sborman slc_mode_export, 0 }, 147738689Sborman { "import", "Use remote special character definitions", 147838689Sborman slc_mode_import, 1 }, 147938689Sborman { "check", "Verify remote special character definitions", 148038689Sborman slc_mode_import, 0 }, 148138689Sborman { "help", 0, slc_help, 0 }, 148238689Sborman { "?", "Print help information", slc_help, 0 }, 148338689Sborman { 0 }, 148438689Sborman }; 148538689Sborman 148646808Sdab static void 148738689Sborman slc_help() 148838689Sborman { 148938689Sborman struct slclist *c; 149038689Sborman 149138689Sborman for (c = SlcList; c->name; c++) { 149238689Sborman if (c->help) { 149338689Sborman if (*c->help) 149438689Sborman printf("%-15s %s\n", c->name, c->help); 149538689Sborman else 149638689Sborman printf("\n"); 149738689Sborman } 149838689Sborman } 149938689Sborman } 150038689Sborman 150146808Sdab static struct slclist * 150238689Sborman getslc(name) 150346808Sdab char *name; 150438689Sborman { 150546808Sdab return (struct slclist *) 150646808Sdab genget(name, (char **) SlcList, sizeof(struct slclist)); 150738689Sborman } 150838689Sborman 150946808Sdab static 151038689Sborman slccmd(argc, argv) 151146808Sdab int argc; 151246808Sdab char *argv[]; 151338689Sborman { 151438689Sborman struct slclist *c; 151538689Sborman 151638689Sborman if (argc != 2) { 151738689Sborman fprintf(stderr, 151838689Sborman "Need an argument to 'slc' command. 'slc ?' for help.\n"); 151938689Sborman return 0; 152038689Sborman } 152138689Sborman c = getslc(argv[1]); 152238689Sborman if (c == 0) { 152338689Sborman fprintf(stderr, "'%s': unknown argument ('slc ?' for help).\n", 152438689Sborman argv[1]); 152538689Sborman return 0; 152638689Sborman } 152738689Sborman if (Ambiguous(c)) { 152838689Sborman fprintf(stderr, "'%s': ambiguous argument ('slc ?' for help).\n", 152938689Sborman argv[1]); 153038689Sborman return 0; 153138689Sborman } 153238689Sborman (*c->handler)(c->arg); 153338689Sborman slcstate(); 153438689Sborman return 1; 153538689Sborman } 153644361Sborman 153744361Sborman /* 153844361Sborman * The ENVIRON command. 153944361Sborman */ 154038689Sborman 154144361Sborman struct envlist { 154244361Sborman char *name; 154344361Sborman char *help; 154446808Sdab void (*handler)(); 154544361Sborman int narg; 154644361Sborman }; 154744361Sborman 154846808Sdab extern struct env_lst * 154946808Sdab env_define P((unsigned char *, unsigned char *)); 155046808Sdab extern void 155146808Sdab env_undefine P((unsigned char *)), 155246808Sdab env_export P((unsigned char *)), 155346808Sdab env_unexport P((unsigned char *)), 155446808Sdab env_send P((unsigned char *)), 155556642Sralph env_list P((void)); 155656642Sralph static void 155746808Sdab env_help P((void)); 155844361Sborman 155944361Sborman struct envlist EnvList[] = { 156044361Sborman { "define", "Define an environment variable", 156146808Sdab (void (*)())env_define, 2 }, 156244361Sborman { "undefine", "Undefine an environment variable", 156344361Sborman env_undefine, 1 }, 156444361Sborman { "export", "Mark an environment variable for automatic export", 156544361Sborman env_export, 1 }, 156646808Sdab { "unexport", "Don't mark an environment variable for automatic export", 156744361Sborman env_unexport, 1 }, 156845233Sborman { "send", "Send an environment variable", env_send, 1 }, 156944361Sborman { "list", "List the current environment variables", 157044361Sborman env_list, 0 }, 157144361Sborman { "help", 0, env_help, 0 }, 157244361Sborman { "?", "Print help information", env_help, 0 }, 157344361Sborman { 0 }, 157444361Sborman }; 157544361Sborman 157646808Sdab static void 157744361Sborman env_help() 157844361Sborman { 157944361Sborman struct envlist *c; 158044361Sborman 158144361Sborman for (c = EnvList; c->name; c++) { 158244361Sborman if (c->help) { 158344361Sborman if (*c->help) 158444361Sborman printf("%-15s %s\n", c->name, c->help); 158544361Sborman else 158644361Sborman printf("\n"); 158744361Sborman } 158844361Sborman } 158944361Sborman } 159044361Sborman 159146808Sdab static struct envlist * 159244361Sborman getenvcmd(name) 159346808Sdab char *name; 159444361Sborman { 159546808Sdab return (struct envlist *) 159646808Sdab genget(name, (char **) EnvList, sizeof(struct envlist)); 159744361Sborman } 159844361Sborman 159944361Sborman env_cmd(argc, argv) 160046808Sdab int argc; 160146808Sdab char *argv[]; 160244361Sborman { 160344361Sborman struct envlist *c; 160444361Sborman 160544361Sborman if (argc < 2) { 160644361Sborman fprintf(stderr, 160744361Sborman "Need an argument to 'environ' command. 'environ ?' for help.\n"); 160844361Sborman return 0; 160944361Sborman } 161044361Sborman c = getenvcmd(argv[1]); 161144361Sborman if (c == 0) { 161244361Sborman fprintf(stderr, "'%s': unknown argument ('environ ?' for help).\n", 161344361Sborman argv[1]); 161444361Sborman return 0; 161544361Sborman } 161644361Sborman if (Ambiguous(c)) { 161744361Sborman fprintf(stderr, "'%s': ambiguous argument ('environ ?' for help).\n", 161844361Sborman argv[1]); 161944361Sborman return 0; 162044361Sborman } 162144361Sborman if (c->narg + 2 != argc) { 162244361Sborman fprintf(stderr, 162344361Sborman "Need %s%d argument%s to 'environ %s' command. 'environ ?' for help.\n", 162444361Sborman c->narg < argc + 2 ? "only " : "", 162544361Sborman c->narg, c->narg == 1 ? "" : "s", c->name); 162644361Sborman return 0; 162744361Sborman } 162846808Sdab (*c->handler)(argv[2], argv[3]); 162944361Sborman return 1; 163044361Sborman } 163144361Sborman 163244361Sborman struct env_lst { 163344361Sborman struct env_lst *next; /* pointer to next structure */ 163457213Sdab struct env_lst *prev; /* pointer to previous structure */ 163546808Sdab unsigned char *var; /* pointer to variable name */ 163657213Sdab unsigned char *value; /* pointer to variable value */ 163744361Sborman int export; /* 1 -> export with default list of variables */ 163857213Sdab int welldefined; /* A well defined variable */ 163944361Sborman }; 164044361Sborman 164144361Sborman struct env_lst envlisthead; 164244361Sborman 164346808Sdab struct env_lst * 164444361Sborman env_find(var) 164546808Sdab unsigned char *var; 164644361Sborman { 164744361Sborman register struct env_lst *ep; 164844361Sborman 164944361Sborman for (ep = envlisthead.next; ep; ep = ep->next) { 165046808Sdab if (strcmp((char *)ep->var, (char *)var) == 0) 165144361Sborman return(ep); 165244361Sborman } 165344361Sborman return(NULL); 165444361Sborman } 165544361Sborman 165646808Sdab void 165744361Sborman env_init() 165844361Sborman { 165946808Sdab extern char **environ; 166044361Sborman register char **epp, *cp; 166144361Sborman register struct env_lst *ep; 166246808Sdab extern char *index(); 166344361Sborman 166444361Sborman for (epp = environ; *epp; epp++) { 166544361Sborman if (cp = index(*epp, '=')) { 166644361Sborman *cp = '\0'; 166746808Sdab ep = env_define((unsigned char *)*epp, 166846808Sdab (unsigned char *)cp+1); 166944361Sborman ep->export = 0; 167044361Sborman *cp = '='; 167144361Sborman } 167244361Sborman } 167344361Sborman /* 167444361Sborman * Special case for DISPLAY variable. If it is ":0.0" or 167544361Sborman * "unix:0.0", we have to get rid of "unix" and insert our 167644361Sborman * hostname. 167744361Sborman */ 167846808Sdab if ((ep = env_find("DISPLAY")) 167946808Sdab && ((*ep->value == ':') 168046808Sdab || (strncmp((char *)ep->value, "unix:", 5) == 0))) { 168144361Sborman char hbuf[256+1]; 168246808Sdab char *cp2 = index((char *)ep->value, ':'); 168344361Sborman 168444361Sborman gethostname(hbuf, 256); 168544361Sborman hbuf[256] = '\0'; 168644361Sborman cp = (char *)malloc(strlen(hbuf) + strlen(cp2) + 1); 168746808Sdab sprintf((char *)cp, "%s%s", hbuf, cp2); 168844361Sborman free(ep->value); 168946808Sdab ep->value = (unsigned char *)cp; 169044361Sborman } 169144361Sborman /* 169244361Sborman * If USER is not defined, but LOGNAME is, then add 169345233Sborman * USER with the value from LOGNAME. By default, we 169445233Sborman * don't export the USER variable. 169544361Sborman */ 169645233Sborman if ((env_find("USER") == NULL) && (ep = env_find("LOGNAME"))) { 169746808Sdab env_define((unsigned char *)"USER", ep->value); 169846808Sdab env_unexport((unsigned char *)"USER"); 169945233Sborman } 170046808Sdab env_export((unsigned char *)"DISPLAY"); 170146808Sdab env_export((unsigned char *)"PRINTER"); 170244361Sborman } 170344361Sborman 170446808Sdab struct env_lst * 170544361Sborman env_define(var, value) 170646808Sdab unsigned char *var, *value; 170744361Sborman { 170844361Sborman register struct env_lst *ep; 170944361Sborman 171044361Sborman if (ep = env_find(var)) { 171144361Sborman if (ep->var) 171244361Sborman free(ep->var); 171344361Sborman if (ep->value) 171444361Sborman free(ep->value); 171544361Sborman } else { 171644361Sborman ep = (struct env_lst *)malloc(sizeof(struct env_lst)); 171744361Sborman ep->next = envlisthead.next; 171844361Sborman envlisthead.next = ep; 171944361Sborman ep->prev = &envlisthead; 172044361Sborman if (ep->next) 172144361Sborman ep->next->prev = ep; 172244361Sborman } 172357213Sdab ep->welldefined = opt_welldefined(var); 172445009Skarels ep->export = 1; 172546808Sdab ep->var = (unsigned char *)strdup((char *)var); 172646808Sdab ep->value = (unsigned char *)strdup((char *)value); 172744361Sborman return(ep); 172844361Sborman } 172944361Sborman 173046808Sdab void 173144361Sborman env_undefine(var) 173246808Sdab unsigned char *var; 173344361Sborman { 173444361Sborman register struct env_lst *ep; 173544361Sborman 173644361Sborman if (ep = env_find(var)) { 173744361Sborman ep->prev->next = ep->next; 173845233Sborman if (ep->next) 173945233Sborman ep->next->prev = ep->prev; 174044361Sborman if (ep->var) 174144361Sborman free(ep->var); 174244361Sborman if (ep->value) 174344361Sborman free(ep->value); 174444361Sborman free(ep); 174544361Sborman } 174644361Sborman } 174744361Sborman 174846808Sdab void 174944361Sborman env_export(var) 175046808Sdab unsigned char *var; 175144361Sborman { 175244361Sborman register struct env_lst *ep; 175344361Sborman 175444361Sborman if (ep = env_find(var)) 175544361Sborman ep->export = 1; 175644361Sborman } 175744361Sborman 175846808Sdab void 175944361Sborman env_unexport(var) 176046808Sdab unsigned char *var; 176144361Sborman { 176244361Sborman register struct env_lst *ep; 176344361Sborman 176444361Sborman if (ep = env_find(var)) 176544361Sborman ep->export = 0; 176644361Sborman } 176744361Sborman 176846808Sdab void 176945233Sborman env_send(var) 177046808Sdab unsigned char *var; 177145233Sborman { 177245233Sborman register struct env_lst *ep; 177345233Sborman 177445233Sborman if (my_state_is_wont(TELOPT_ENVIRON)) { 177545233Sborman fprintf(stderr, 177645233Sborman "Cannot send '%s': Telnet ENVIRON option not enabled\n", 177745233Sborman var); 177845233Sborman return; 177945233Sborman } 178045233Sborman ep = env_find(var); 178145233Sborman if (ep == 0) { 178245233Sborman fprintf(stderr, "Cannot send '%s': variable not defined\n", 178345233Sborman var); 178445233Sborman return; 178545233Sborman } 178645233Sborman env_opt_start_info(); 178745233Sborman env_opt_add(ep->var); 178845233Sborman env_opt_end(0); 178945233Sborman } 179045233Sborman 179146808Sdab void 179244361Sborman env_list() 179344361Sborman { 179444361Sborman register struct env_lst *ep; 179544361Sborman 179644361Sborman for (ep = envlisthead.next; ep; ep = ep->next) { 179744361Sborman printf("%c %-20s %s\n", ep->export ? '*' : ' ', 179844361Sborman ep->var, ep->value); 179944361Sborman } 180044361Sborman } 180144361Sborman 180246808Sdab unsigned char * 180357213Sdab env_default(init, welldefined) 180446808Sdab int init; 180544361Sborman { 180644361Sborman static struct env_lst *nep = NULL; 180744361Sborman 180844361Sborman if (init) { 180944361Sborman nep = &envlisthead; 181044361Sborman return; 181144361Sborman } 181244361Sborman if (nep) { 181344361Sborman while (nep = nep->next) { 181457213Sdab if (nep->export && (nep->welldefined == welldefined)) 181544361Sborman return(nep->var); 181644361Sborman } 181744361Sborman } 181844361Sborman return(NULL); 181944361Sborman } 182044361Sborman 182146808Sdab unsigned char * 182244361Sborman env_getvalue(var) 182346808Sdab unsigned char *var; 182444361Sborman { 182544361Sborman register struct env_lst *ep; 182644361Sborman 182744361Sborman if (ep = env_find(var)) 182844361Sborman return(ep->value); 182944361Sborman return(NULL); 183044361Sborman } 183144361Sborman 183257213Sdab #if defined(AUTHENTICATION) 183346808Sdab /* 183446808Sdab * The AUTHENTICATE command. 183546808Sdab */ 183646808Sdab 183746808Sdab struct authlist { 183846808Sdab char *name; 183946808Sdab char *help; 184046808Sdab int (*handler)(); 184146808Sdab int narg; 184246808Sdab }; 184346808Sdab 184446808Sdab extern int 184546808Sdab auth_enable P((int)), 184646808Sdab auth_disable P((int)), 184756642Sralph auth_status P((void)); 184856642Sralph static int 184946808Sdab auth_help P((void)); 185046808Sdab 185146808Sdab struct authlist AuthList[] = { 185246808Sdab { "status", "Display current status of authentication information", 185346808Sdab auth_status, 0 }, 185446808Sdab { "disable", "Disable an authentication type ('auth disable ?' for more)", 185546808Sdab auth_disable, 1 }, 185646808Sdab { "enable", "Enable an authentication type ('auth enable ?' for more)", 185746808Sdab auth_enable, 1 }, 185846808Sdab { "help", 0, auth_help, 0 }, 185946808Sdab { "?", "Print help information", auth_help, 0 }, 186046808Sdab { 0 }, 186146808Sdab }; 186246808Sdab 186346808Sdab static int 186446808Sdab auth_help() 186544361Sborman { 186646808Sdab struct authlist *c; 186746808Sdab 186846808Sdab for (c = AuthList; c->name; c++) { 186946808Sdab if (c->help) { 187046808Sdab if (*c->help) 187146808Sdab printf("%-15s %s\n", c->name, c->help); 187246808Sdab else 187346808Sdab printf("\n"); 187446808Sdab } 187546808Sdab } 187646808Sdab return 0; 187744361Sborman } 187846808Sdab 187946808Sdab auth_cmd(argc, argv) 188046808Sdab int argc; 188146808Sdab char *argv[]; 188246808Sdab { 188346808Sdab struct authlist *c; 188446808Sdab 188546808Sdab c = (struct authlist *) 188646808Sdab genget(argv[1], (char **) AuthList, sizeof(struct authlist)); 188746808Sdab if (c == 0) { 188846808Sdab fprintf(stderr, "'%s': unknown argument ('auth ?' for help).\n", 188946808Sdab argv[1]); 189046808Sdab return 0; 189146808Sdab } 189246808Sdab if (Ambiguous(c)) { 189346808Sdab fprintf(stderr, "'%s': ambiguous argument ('auth ?' for help).\n", 189446808Sdab argv[1]); 189546808Sdab return 0; 189646808Sdab } 189746808Sdab if (c->narg + 2 != argc) { 189846808Sdab fprintf(stderr, 189946808Sdab "Need %s%d argument%s to 'auth %s' command. 'auth ?' for help.\n", 190046808Sdab c->narg < argc + 2 ? "only " : "", 190146808Sdab c->narg, c->narg == 1 ? "" : "s", c->name); 190246808Sdab return 0; 190346808Sdab } 190446808Sdab return((*c->handler)(argv[2], argv[3])); 190546808Sdab } 190645233Sborman #endif 190744361Sborman 190857213Sdab #if defined(ENCRYPTION) 190932144Sminshall /* 191046808Sdab * The ENCRYPT command. 191136274Sminshall */ 191236274Sminshall 191346808Sdab struct encryptlist { 191446808Sdab char *name; 191546808Sdab char *help; 191646808Sdab int (*handler)(); 191746808Sdab int needconnect; 191846808Sdab int minarg; 191946808Sdab int maxarg; 192046808Sdab }; 192146808Sdab 192246808Sdab extern int 192346808Sdab EncryptEnable P((char *, char *)), 192447609Sdab EncryptDisable P((char *, char *)), 192546808Sdab EncryptType P((char *, char *)), 192646808Sdab EncryptStart P((char *)), 192746808Sdab EncryptStartInput P((void)), 192846808Sdab EncryptStartOutput P((void)), 192946808Sdab EncryptStop P((char *)), 193046808Sdab EncryptStopInput P((void)), 193146808Sdab EncryptStopOutput P((void)), 193256642Sralph EncryptStatus P((void)); 193356642Sralph static int 193446808Sdab EncryptHelp P((void)); 193546808Sdab 193646808Sdab struct encryptlist EncryptList[] = { 193746808Sdab { "enable", "Enable encryption. ('encrypt enable ?' for more)", 193846808Sdab EncryptEnable, 1, 1, 2 }, 193947609Sdab { "disable", "Disable encryption. ('encrypt enable ?' for more)", 194047609Sdab EncryptDisable, 0, 1, 2 }, 194146808Sdab { "type", "Set encryptiong type. ('encrypt type ?' for more)", 194246808Sdab EncryptType, 0, 1, 1 }, 194346808Sdab { "start", "Start encryption. ('encrypt start ?' for more)", 194446808Sdab EncryptStart, 1, 0, 1 }, 194546808Sdab { "stop", "Stop encryption. ('encrypt stop ?' for more)", 194646808Sdab EncryptStop, 1, 0, 1 }, 194746808Sdab { "input", "Start encrypting the input stream", 194846808Sdab EncryptStartInput, 1, 0, 0 }, 194946808Sdab { "-input", "Stop encrypting the input stream", 195046808Sdab EncryptStopInput, 1, 0, 0 }, 195146808Sdab { "output", "Start encrypting the output stream", 195246808Sdab EncryptStartOutput, 1, 0, 0 }, 195346808Sdab { "-output", "Stop encrypting the output stream", 195446808Sdab EncryptStopOutput, 1, 0, 0 }, 195546808Sdab 195646808Sdab { "status", "Display current status of authentication information", 195746808Sdab EncryptStatus, 0, 0, 0 }, 195846808Sdab { "help", 0, EncryptHelp, 0, 0, 0 }, 195946808Sdab { "?", "Print help information", EncryptHelp, 0, 0, 0 }, 196046808Sdab { 0 }, 196146808Sdab }; 196246808Sdab 196346808Sdab static int 196446808Sdab EncryptHelp() 196536274Sminshall { 196646808Sdab struct encryptlist *c; 196746808Sdab 196846808Sdab for (c = EncryptList; c->name; c++) { 196946808Sdab if (c->help) { 197046808Sdab if (*c->help) 197146808Sdab printf("%-15s %s\n", c->name, c->help); 197246808Sdab else 197346808Sdab printf("\n"); 197436274Sminshall } 197546808Sdab } 197646808Sdab return 0; 197746808Sdab } 197836274Sminshall 197946808Sdab encrypt_cmd(argc, argv) 198046808Sdab int argc; 198146808Sdab char *argv[]; 198246808Sdab { 198346808Sdab struct encryptlist *c; 198436274Sminshall 198546808Sdab c = (struct encryptlist *) 198646808Sdab genget(argv[1], (char **) EncryptList, sizeof(struct encryptlist)); 198746808Sdab if (c == 0) { 198846808Sdab fprintf(stderr, "'%s': unknown argument ('encrypt ?' for help).\n", 198946808Sdab argv[1]); 199046808Sdab return 0; 199146808Sdab } 199246808Sdab if (Ambiguous(c)) { 199346808Sdab fprintf(stderr, "'%s': ambiguous argument ('encrypt ?' for help).\n", 199446808Sdab argv[1]); 199546808Sdab return 0; 199646808Sdab } 199746808Sdab argc -= 2; 199846808Sdab if (argc < c->minarg || argc > c->maxarg) { 199946808Sdab if (c->minarg == c->maxarg) { 200046808Sdab fprintf(stderr, "Need %s%d argument%s ", 200146808Sdab c->minarg < argc ? "only " : "", c->minarg, 200246808Sdab c->minarg == 1 ? "" : "s"); 200346808Sdab } else { 200446808Sdab fprintf(stderr, "Need %s%d-%d arguments ", 200546808Sdab c->maxarg < argc ? "only " : "", c->minarg, c->maxarg); 200646808Sdab } 200746808Sdab fprintf(stderr, "to 'encrypt %s' command. 'encrypt ?' for help.\n", 200846808Sdab c->name); 200946808Sdab return 0; 201046808Sdab } 201146808Sdab if (c->needconnect && !connected) { 201246808Sdab if (!(argc && (isprefix(argv[2], "help") || isprefix(argv[2], "?")))) { 201346808Sdab printf("?Need to be connected first.\n"); 201446808Sdab return 0; 201546808Sdab } 201646808Sdab } 201746808Sdab return ((*c->handler)(argc > 0 ? argv[2] : 0, 201846808Sdab argc > 1 ? argv[3] : 0, 201946808Sdab argc > 2 ? argv[4] : 0)); 202046808Sdab } 202136274Sminshall #endif 202236274Sminshall 202346808Sdab #if defined(unix) && defined(TN3270) 202446808Sdab static void 202536274Sminshall filestuff(fd) 202646808Sdab int fd; 202736274Sminshall { 202836274Sminshall int res; 202936274Sminshall 203038689Sborman #ifdef F_GETOWN 203138689Sborman setconnmode(0); 203236274Sminshall res = fcntl(fd, F_GETOWN, 0); 203336274Sminshall setcommandmode(); 203436274Sminshall 203536274Sminshall if (res == -1) { 203636274Sminshall perror("fcntl"); 203736274Sminshall return; 203836274Sminshall } 203936274Sminshall printf("\tOwner is %d.\n", res); 204038689Sborman #endif 204136274Sminshall 204238689Sborman setconnmode(0); 204336274Sminshall res = fcntl(fd, F_GETFL, 0); 204436274Sminshall setcommandmode(); 204536274Sminshall 204636274Sminshall if (res == -1) { 204736274Sminshall perror("fcntl"); 204836274Sminshall return; 204936274Sminshall } 205036274Sminshall printf("\tFlags are 0x%x: %s\n", res, decodeflags(res)); 205136274Sminshall } 205246808Sdab #endif /* defined(unix) && defined(TN3270) */ 205336274Sminshall 205436274Sminshall /* 205532144Sminshall * Print status about the connection. 205632144Sminshall */ 205746808Sdab /*ARGSUSED*/ 205846808Sdab static 205932144Sminshall status(argc, argv) 206046808Sdab int argc; 206146808Sdab char *argv[]; 206232144Sminshall { 206332144Sminshall if (connected) { 206432144Sminshall printf("Connected to %s.\n", hostname); 206536242Sminshall if ((argc < 2) || strcmp(argv[1], "notmuch")) { 206638689Sborman int mode = getconnmode(); 206738689Sborman 206838689Sborman if (my_want_state_is_will(TELOPT_LINEMODE)) { 206938689Sborman printf("Operating with LINEMODE option\n"); 207038689Sborman printf("%s line editing\n", (mode&MODE_EDIT) ? "Local" : "No"); 207138689Sborman printf("%s catching of signals\n", 207238689Sborman (mode&MODE_TRAPSIG) ? "Local" : "No"); 207338689Sborman slcstate(); 207438689Sborman #ifdef KLUDGELINEMODE 207539529Sborman } else if (kludgelinemode && my_want_state_is_dont(TELOPT_SGA)) { 207638689Sborman printf("Operating in obsolete linemode\n"); 207738689Sborman #endif 207838689Sborman } else { 207938689Sborman printf("Operating in single character mode\n"); 208038689Sborman if (localchars) 208138689Sborman printf("Catching signals locally\n"); 208232144Sminshall } 208338689Sborman printf("%s character echo\n", (mode&MODE_ECHO) ? "Local" : "Remote"); 208438689Sborman if (my_want_state_is_will(TELOPT_LFLOW)) 208538689Sborman printf("%s flow control\n", (mode&MODE_FLOW) ? "Local" : "No"); 208657213Sdab #if defined(ENCRYPTION) 208746808Sdab encrypt_display(); 208846808Sdab #endif 208932144Sminshall } 209032144Sminshall } else { 209132144Sminshall printf("No connection.\n"); 209232144Sminshall } 209332144Sminshall # if !defined(TN3270) 209432144Sminshall printf("Escape character is '%s'.\n", control(escape)); 209534849Sminshall (void) fflush(stdout); 209632144Sminshall # else /* !defined(TN3270) */ 209732144Sminshall if ((!In3270) && ((argc < 2) || strcmp(argv[1], "notmuch"))) { 209832144Sminshall printf("Escape character is '%s'.\n", control(escape)); 209932144Sminshall } 210032144Sminshall # if defined(unix) 210136242Sminshall if ((argc >= 2) && !strcmp(argv[1], "everything")) { 210236242Sminshall printf("SIGIO received %d time%s.\n", 210336242Sminshall sigiocount, (sigiocount == 1)? "":"s"); 210436274Sminshall if (In3270) { 210536274Sminshall printf("Process ID %d, process group %d.\n", 210636274Sminshall getpid(), getpgrp(getpid())); 210736274Sminshall printf("Terminal input:\n"); 210836274Sminshall filestuff(tin); 210936274Sminshall printf("Terminal output:\n"); 211036274Sminshall filestuff(tout); 211136274Sminshall printf("Network socket:\n"); 211236274Sminshall filestuff(net); 211336274Sminshall } 211436242Sminshall } 211532144Sminshall if (In3270 && transcom) { 211632144Sminshall printf("Transparent mode command is '%s'.\n", transcom); 211732144Sminshall } 211832144Sminshall # endif /* defined(unix) */ 211934849Sminshall (void) fflush(stdout); 212032144Sminshall if (In3270) { 212132144Sminshall return 0; 212232144Sminshall } 212332144Sminshall # endif /* defined(TN3270) */ 212432144Sminshall return 1; 212532144Sminshall } 212632144Sminshall 212745233Sborman #ifdef SIGINFO 212845233Sborman /* 212945233Sborman * Function that gets called when SIGINFO is received. 213045233Sborman */ 213145233Sborman ayt_status() 213245233Sborman { 213345233Sborman (void) call(status, "status", "notmuch", 0); 213445233Sborman } 213545233Sborman #endif 213632144Sminshall 213746808Sdab int 213832144Sminshall tn(argc, argv) 213946808Sdab int argc; 214046808Sdab char *argv[]; 214132144Sminshall { 214232144Sminshall register struct hostent *host = 0; 214332144Sminshall struct sockaddr_in sin; 214432144Sminshall struct servent *sp = 0; 214538689Sborman unsigned long temp, inet_addr(); 214637219Sminshall extern char *inet_ntoa(); 214746808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 214838689Sborman char *srp = 0, *strrchr(); 214938689Sborman unsigned long sourceroute(), srlen; 215038689Sborman #endif 215144361Sborman char *cmd, *hostp = 0, *portp = 0, *user = 0; 215232144Sminshall 215345233Sborman /* clear the socket address prior to use */ 215445233Sborman bzero((char *)&sin, sizeof(sin)); 215532144Sminshall 215632144Sminshall if (connected) { 215732144Sminshall printf("?Already connected to %s\n", hostname); 215846808Sdab setuid(getuid()); 215932144Sminshall return 0; 216032144Sminshall } 216132144Sminshall if (argc < 2) { 216246808Sdab (void) strcpy(line, "open "); 216332144Sminshall printf("(to) "); 216446808Sdab (void) fgets(&line[strlen(line)], sizeof(line) - strlen(line), stdin); 216532144Sminshall makeargv(); 216632144Sminshall argc = margc; 216732144Sminshall argv = margv; 216832144Sminshall } 216944361Sborman cmd = *argv; 217044361Sborman --argc; ++argv; 217144361Sborman while (argc) { 217246808Sdab if (isprefix(*argv, "help") || isprefix(*argv, "?")) 217346808Sdab goto usage; 217444361Sborman if (strcmp(*argv, "-l") == 0) { 217544361Sborman --argc; ++argv; 217644361Sborman if (argc == 0) 217744361Sborman goto usage; 217844361Sborman user = *argv++; 217944361Sborman --argc; 218044361Sborman continue; 218144361Sborman } 218245233Sborman if (strcmp(*argv, "-a") == 0) { 218345233Sborman --argc; ++argv; 218445233Sborman autologin = 1; 218545233Sborman continue; 218645233Sborman } 218744361Sborman if (hostp == 0) { 218844361Sborman hostp = *argv++; 218944361Sborman --argc; 219044361Sborman continue; 219144361Sborman } 219244361Sborman if (portp == 0) { 219344361Sborman portp = *argv++; 219444361Sborman --argc; 219544361Sborman continue; 219644361Sborman } 219744361Sborman usage: 219845233Sborman printf("usage: %s [-l user] [-a] host-name [port]\n", cmd); 219946808Sdab setuid(getuid()); 220032144Sminshall return 0; 220132144Sminshall } 220246808Sdab if (hostp == 0) 220346808Sdab goto usage; 220446808Sdab 220546808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 220644361Sborman if (hostp[0] == '@' || hostp[0] == '!') { 220744361Sborman if ((hostname = strrchr(hostp, ':')) == NULL) 220844361Sborman hostname = strrchr(hostp, '@'); 220938689Sborman hostname++; 221038689Sborman srp = 0; 221144361Sborman temp = sourceroute(hostp, &srp, &srlen); 221238689Sborman if (temp == 0) { 221338689Sborman herror(srp); 221446808Sdab setuid(getuid()); 221538689Sborman return 0; 221638689Sborman } else if (temp == -1) { 221744361Sborman printf("Bad source route option: %s\n", hostp); 221846808Sdab setuid(getuid()); 221938689Sborman return 0; 222038689Sborman } else { 222138689Sborman sin.sin_addr.s_addr = temp; 222238689Sborman sin.sin_family = AF_INET; 222338689Sborman } 222432144Sminshall } else { 222538689Sborman #endif 222644361Sborman temp = inet_addr(hostp); 222738689Sborman if (temp != (unsigned long) -1) { 222838689Sborman sin.sin_addr.s_addr = temp; 222938689Sborman sin.sin_family = AF_INET; 223046808Sdab (void) strcpy(_hostname, hostp); 223146808Sdab hostname = _hostname; 223238689Sborman } else { 223344361Sborman host = gethostbyname(hostp); 223438689Sborman if (host) { 223538689Sborman sin.sin_family = host->h_addrtype; 223632144Sminshall #if defined(h_addr) /* In 4.3, this is a #define */ 223738689Sborman memcpy((caddr_t)&sin.sin_addr, 223832144Sminshall host->h_addr_list[0], host->h_length); 223932144Sminshall #else /* defined(h_addr) */ 224038689Sborman memcpy((caddr_t)&sin.sin_addr, host->h_addr, host->h_length); 224132144Sminshall #endif /* defined(h_addr) */ 224246808Sdab strncpy(_hostname, host->h_name, sizeof(_hostname)); 224346808Sdab _hostname[sizeof(_hostname)-1] = '\0'; 224446808Sdab hostname = _hostname; 224538689Sborman } else { 224644361Sborman herror(hostp); 224746808Sdab setuid(getuid()); 224838689Sborman return 0; 224938689Sborman } 225032144Sminshall } 225146808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 225232144Sminshall } 225338689Sborman #endif 225444361Sborman if (portp) { 225544361Sborman if (*portp == '-') { 225644361Sborman portp++; 225738689Sborman telnetport = 1; 225838689Sborman } else 225938689Sborman telnetport = 0; 226044361Sborman sin.sin_port = atoi(portp); 226132144Sminshall if (sin.sin_port == 0) { 226244361Sborman sp = getservbyname(portp, "tcp"); 226332144Sminshall if (sp) 226432144Sminshall sin.sin_port = sp->s_port; 226532144Sminshall else { 226644361Sborman printf("%s: bad port number\n", portp); 226746808Sdab setuid(getuid()); 226832144Sminshall return 0; 226932144Sminshall } 227032144Sminshall } else { 227157213Sdab #if !defined(htons) 227257213Sdab u_short htons(); 227357213Sdab #endif /* !defined(htons) */ 227432144Sminshall sin.sin_port = htons(sin.sin_port); 227532144Sminshall } 227632144Sminshall } else { 227732144Sminshall if (sp == 0) { 227832144Sminshall sp = getservbyname("telnet", "tcp"); 227932144Sminshall if (sp == 0) { 228034849Sminshall fprintf(stderr, "telnet: tcp/telnet: unknown service\n"); 228146808Sdab setuid(getuid()); 228232144Sminshall return 0; 228332144Sminshall } 228432144Sminshall sin.sin_port = sp->s_port; 228532144Sminshall } 228632144Sminshall telnetport = 1; 228732144Sminshall } 228837219Sminshall printf("Trying %s...\n", inet_ntoa(sin.sin_addr)); 228932144Sminshall do { 229032144Sminshall net = socket(AF_INET, SOCK_STREAM, 0); 229146808Sdab setuid(getuid()); 229232144Sminshall if (net < 0) { 229332144Sminshall perror("telnet: socket"); 229432144Sminshall return 0; 229532144Sminshall } 229646808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 229738689Sborman if (srp && setsockopt(net, IPPROTO_IP, IP_OPTIONS, (char *)srp, srlen) < 0) 229838689Sborman perror("setsockopt (IP_OPTIONS)"); 229938689Sborman #endif 230046808Sdab #if defined(IPPROTO_IP) && defined(IP_TOS) 230146808Sdab { 230246808Sdab # if defined(HAS_GETTOS) 230346808Sdab struct tosent *tp; 230446815Sdab if (tos < 0 && (tp = gettosbyname("telnet", "tcp"))) 230546808Sdab tos = tp->t_tos; 230646808Sdab # endif 230746815Sdab if (tos < 0) 230846815Sdab tos = 020; /* Low Delay bit */ 230946815Sdab if (tos 231057213Sdab && (setsockopt(net, IPPROTO_IP, IP_TOS, 231157213Sdab (char *)&tos, sizeof(int)) < 0) 231246815Sdab && (errno != ENOPROTOOPT)) 231346815Sdab perror("telnet: setsockopt (IP_TOS) (ignored)"); 231446808Sdab } 231546808Sdab #endif /* defined(IPPROTO_IP) && defined(IP_TOS) */ 231640245Sborman 231732144Sminshall if (debug && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 1) < 0) { 231832144Sminshall perror("setsockopt (SO_DEBUG)"); 231932144Sminshall } 232032144Sminshall 232132144Sminshall if (connect(net, (struct sockaddr *)&sin, sizeof (sin)) < 0) { 232232144Sminshall #if defined(h_addr) /* In 4.3, this is a #define */ 232332144Sminshall if (host && host->h_addr_list[1]) { 232432144Sminshall int oerrno = errno; 232532144Sminshall 232632144Sminshall fprintf(stderr, "telnet: connect to address %s: ", 232732144Sminshall inet_ntoa(sin.sin_addr)); 232832144Sminshall errno = oerrno; 232932144Sminshall perror((char *)0); 233032144Sminshall host->h_addr_list++; 233132144Sminshall memcpy((caddr_t)&sin.sin_addr, 233232144Sminshall host->h_addr_list[0], host->h_length); 233332144Sminshall (void) NetClose(net); 233432144Sminshall continue; 233532144Sminshall } 233632144Sminshall #endif /* defined(h_addr) */ 233732144Sminshall perror("telnet: Unable to connect to remote host"); 233832144Sminshall return 0; 233937219Sminshall } 234032144Sminshall connected++; 234157213Sdab #if defined(AUTHENTICATION) || defined(ENCRYPTION) 234246808Sdab auth_encrypt_connect(connected); 234346808Sdab #endif 234432144Sminshall } while (connected == 0); 234544361Sborman cmdrc(hostp, hostname); 234645008Skarels if (autologin && user == NULL) { 234745008Skarels struct passwd *pw; 234845008Skarels 234945233Sborman user = getenv("USER"); 235045008Skarels if (user == NULL || 235145233Sborman (pw = getpwnam(user)) && pw->pw_uid != getuid()) { 235245233Sborman if (pw = getpwuid(getuid())) 235345008Skarels user = pw->pw_name; 235445008Skarels else 235545008Skarels user = NULL; 235645233Sborman } 235745008Skarels } 235845008Skarels if (user) { 235946808Sdab env_define((unsigned char *)"USER", (unsigned char *)user); 236046808Sdab env_export((unsigned char *)"USER"); 236145008Skarels } 236234849Sminshall (void) call(status, "status", "notmuch", 0); 236332144Sminshall if (setjmp(peerdied) == 0) 236446808Sdab telnet(user); 236534849Sminshall (void) NetClose(net); 236632381Sminshall ExitString("Connection closed by foreign host.\n",1); 236732144Sminshall /*NOTREACHED*/ 236832144Sminshall } 236932144Sminshall 237032144Sminshall #define HELPINDENT (sizeof ("connect")) 237132144Sminshall 237232144Sminshall static char 237332144Sminshall openhelp[] = "connect to a site", 237432144Sminshall closehelp[] = "close current connection", 237546808Sdab logouthelp[] = "forcibly logout remote user and close the connection", 237632144Sminshall quithelp[] = "exit telnet", 237732144Sminshall statushelp[] = "print status information", 237832144Sminshall helphelp[] = "print help information", 237932144Sminshall sendhelp[] = "transmit special characters ('send ?' for more)", 238032144Sminshall sethelp[] = "set operating parameters ('set ?' for more)", 238138689Sborman unsethelp[] = "unset operating parameters ('unset ?' for more)", 238232144Sminshall togglestring[] ="toggle operating parameters ('toggle ?' for more)", 238338689Sborman slchelp[] = "change state of special charaters ('slc ?' for more)", 238432144Sminshall displayhelp[] = "display operating parameters", 238532144Sminshall #if defined(TN3270) && defined(unix) 238632144Sminshall transcomhelp[] = "specify Unix command for transparent mode pipe", 238732144Sminshall #endif /* defined(TN3270) && defined(unix) */ 238857213Sdab #if defined(AUTHENTICATION) 238946808Sdab authhelp[] = "turn on (off) authentication ('auth ?' for more)", 239046808Sdab #endif 239157213Sdab #if defined(ENCRYPTION) 239246808Sdab encrypthelp[] = "turn on (off) encryption ('encrypt ?' for more)", 239346808Sdab #endif 239432144Sminshall #if defined(unix) 239532144Sminshall zhelp[] = "suspend telnet", 239643317Skfall #endif /* defined(unix) */ 239732144Sminshall shellhelp[] = "invoke a subshell", 239844361Sborman envhelp[] = "change environment variables ('environ ?' for more)", 239944361Sborman modestring[] = "try to enter line or character mode ('mode ?' for more)"; 240032144Sminshall 240156642Sralph static int help(); 240232144Sminshall 240332144Sminshall static Command cmdtab[] = { 240438689Sborman { "close", closehelp, bye, 1 }, 240546808Sdab { "logout", logouthelp, logout, 1 }, 240638689Sborman { "display", displayhelp, display, 0 }, 240738689Sborman { "mode", modestring, modecmd, 0 }, 240838689Sborman { "open", openhelp, tn, 0 }, 240938689Sborman { "quit", quithelp, quit, 0 }, 241038689Sborman { "send", sendhelp, sendcmd, 0 }, 241138689Sborman { "set", sethelp, setcmd, 0 }, 241238689Sborman { "unset", unsethelp, unsetcmd, 0 }, 241338689Sborman { "status", statushelp, status, 0 }, 241438689Sborman { "toggle", togglestring, toggle, 0 }, 241538689Sborman { "slc", slchelp, slccmd, 0 }, 241632144Sminshall #if defined(TN3270) && defined(unix) 241738689Sborman { "transcom", transcomhelp, settranscom, 0 }, 241832144Sminshall #endif /* defined(TN3270) && defined(unix) */ 241957213Sdab #if defined(AUTHENTICATION) 242046808Sdab { "auth", authhelp, auth_cmd, 0 }, 242146808Sdab #endif 242257213Sdab #if defined(ENCRYPTION) 242346808Sdab { "encrypt", encrypthelp, encrypt_cmd, 0 }, 242446808Sdab #endif 242532144Sminshall #if defined(unix) 242638689Sborman { "z", zhelp, suspend, 0 }, 242732144Sminshall #endif /* defined(unix) */ 242832144Sminshall #if defined(TN3270) 242938689Sborman { "!", shellhelp, shell, 1 }, 243038689Sborman #else 243138689Sborman { "!", shellhelp, shell, 0 }, 243238689Sborman #endif 243344361Sborman { "environ", envhelp, env_cmd, 0 }, 243438689Sborman { "?", helphelp, help, 0 }, 243532144Sminshall 0 243632144Sminshall }; 243732144Sminshall 243832144Sminshall static char crmodhelp[] = "deprecated command -- use 'toggle crmod' instead"; 243932144Sminshall static char escapehelp[] = "deprecated command -- use 'set escape' instead"; 244032144Sminshall 244132144Sminshall static Command cmdtab2[] = { 244238689Sborman { "help", 0, help, 0 }, 244338689Sborman { "escape", escapehelp, setescape, 0 }, 244438689Sborman { "crmod", crmodhelp, togcrmod, 0 }, 244532144Sminshall 0 244632144Sminshall }; 244732144Sminshall 244835298Sminshall 244932144Sminshall /* 245032144Sminshall * Call routine with argc, argv set from args (terminated by 0). 245132144Sminshall */ 245235298Sminshall 245346808Sdab /*VARARGS1*/ 245446808Sdab static 245535298Sminshall call(va_alist) 245646808Sdab va_dcl 245732144Sminshall { 245835298Sminshall va_list ap; 245935298Sminshall typedef int (*intrtn_t)(); 246035298Sminshall intrtn_t routine; 246135298Sminshall char *args[100]; 246235298Sminshall int argno = 0; 246335298Sminshall 246435298Sminshall va_start(ap); 246535298Sminshall routine = (va_arg(ap, intrtn_t)); 246635495Sminshall while ((args[argno++] = va_arg(ap, char *)) != 0) { 246735298Sminshall ; 246835495Sminshall } 246935298Sminshall va_end(ap); 247035495Sminshall return (*routine)(argno-1, args); 247132144Sminshall } 247232144Sminshall 247335298Sminshall 247446808Sdab static Command * 247532144Sminshall getcmd(name) 247646808Sdab char *name; 247732144Sminshall { 247832144Sminshall Command *cm; 247932144Sminshall 248046808Sdab if (cm = (Command *) genget(name, (char **) cmdtab, sizeof(Command))) 248132144Sminshall return cm; 248246808Sdab return (Command *) genget(name, (char **) cmdtab2, sizeof(Command)); 248332144Sminshall } 248432144Sminshall 248546808Sdab void 248638689Sborman command(top, tbuf, cnt) 248746808Sdab int top; 248846808Sdab char *tbuf; 248946808Sdab int cnt; 249032144Sminshall { 249132144Sminshall register Command *c; 249232144Sminshall 249332144Sminshall setcommandmode(); 249432144Sminshall if (!top) { 249532144Sminshall putchar('\n'); 249637219Sminshall #if defined(unix) 249732144Sminshall } else { 249844361Sborman (void) signal(SIGINT, SIG_DFL); 249944361Sborman (void) signal(SIGQUIT, SIG_DFL); 250032144Sminshall #endif /* defined(unix) */ 250132144Sminshall } 250232144Sminshall for (;;) { 250346808Sdab if (rlogin == _POSIX_VDISABLE) 250446808Sdab printf("%s> ", prompt); 250538689Sborman if (tbuf) { 250638689Sborman register char *cp; 250738689Sborman cp = line; 250838689Sborman while (cnt > 0 && (*cp++ = *tbuf++) != '\n') 250938689Sborman cnt--; 251038689Sborman tbuf = 0; 251138689Sborman if (cp == line || *--cp != '\n' || cp == line) 251238689Sborman goto getline; 251338689Sborman *cp = '\0'; 251446808Sdab if (rlogin == _POSIX_VDISABLE) 251546808Sdab printf("%s\n", line); 251638689Sborman } else { 251738689Sborman getline: 251846808Sdab if (rlogin != _POSIX_VDISABLE) 251946808Sdab printf("%s> ", prompt); 252046808Sdab if (fgets(line, sizeof(line), stdin) == NULL) { 252144361Sborman if (feof(stdin) || ferror(stdin)) { 252244361Sborman (void) quit(); 252344361Sborman /*NOTREACHED*/ 252444361Sborman } 252538689Sborman break; 252638689Sborman } 252732144Sminshall } 252832144Sminshall if (line[0] == 0) 252932144Sminshall break; 253032144Sminshall makeargv(); 253137219Sminshall if (margv[0] == 0) { 253237219Sminshall break; 253337219Sminshall } 253432144Sminshall c = getcmd(margv[0]); 253532144Sminshall if (Ambiguous(c)) { 253632144Sminshall printf("?Ambiguous command\n"); 253732144Sminshall continue; 253832144Sminshall } 253932144Sminshall if (c == 0) { 254032144Sminshall printf("?Invalid command\n"); 254132144Sminshall continue; 254232144Sminshall } 254332144Sminshall if (c->needconnect && !connected) { 254432144Sminshall printf("?Need to be connected first.\n"); 254532144Sminshall continue; 254632144Sminshall } 254732144Sminshall if ((*c->handler)(margc, margv)) { 254832144Sminshall break; 254932144Sminshall } 255032144Sminshall } 255132144Sminshall if (!top) { 255232144Sminshall if (!connected) { 255332144Sminshall longjmp(toplevel, 1); 255432144Sminshall /*NOTREACHED*/ 255532144Sminshall } 255632144Sminshall #if defined(TN3270) 255732144Sminshall if (shell_active == 0) { 255838689Sborman setconnmode(0); 255932144Sminshall } 256032144Sminshall #else /* defined(TN3270) */ 256138689Sborman setconnmode(0); 256232144Sminshall #endif /* defined(TN3270) */ 256332144Sminshall } 256432144Sminshall } 256532144Sminshall 256632144Sminshall /* 256732144Sminshall * Help command. 256832144Sminshall */ 256946808Sdab static 257032144Sminshall help(argc, argv) 257132144Sminshall int argc; 257232144Sminshall char *argv[]; 257332144Sminshall { 257432144Sminshall register Command *c; 257532144Sminshall 257632144Sminshall if (argc == 1) { 257732144Sminshall printf("Commands may be abbreviated. Commands are:\n\n"); 257832144Sminshall for (c = cmdtab; c->name; c++) 257938689Sborman if (c->help) { 258032144Sminshall printf("%-*s\t%s\n", HELPINDENT, c->name, 258132144Sminshall c->help); 258232144Sminshall } 258332144Sminshall return 0; 258432144Sminshall } 258532144Sminshall while (--argc > 0) { 258632144Sminshall register char *arg; 258732144Sminshall arg = *++argv; 258832144Sminshall c = getcmd(arg); 258932144Sminshall if (Ambiguous(c)) 259032144Sminshall printf("?Ambiguous help command %s\n", arg); 259132144Sminshall else if (c == (Command *)0) 259232144Sminshall printf("?Invalid help command %s\n", arg); 259332144Sminshall else 259432144Sminshall printf("%s\n", c->help); 259532144Sminshall } 259632144Sminshall return 0; 259732144Sminshall } 259838689Sborman 259938689Sborman static char *rcname = 0; 260038689Sborman static char rcbuf[128]; 260138689Sborman 260238689Sborman cmdrc(m1, m2) 260338689Sborman char *m1, *m2; 260438689Sborman { 260538689Sborman register Command *c; 260638689Sborman FILE *rcfile; 260738689Sborman int gotmachine = 0; 260838689Sborman int l1 = strlen(m1); 260938689Sborman int l2 = strlen(m2); 261038689Sborman char m1save[64]; 261138689Sborman 261247609Sdab if (skiprc) 261347609Sdab return; 261447609Sdab 261538689Sborman strcpy(m1save, m1); 261638689Sborman m1 = m1save; 261738689Sborman 261838689Sborman if (rcname == 0) { 261938689Sborman rcname = getenv("HOME"); 262038689Sborman if (rcname) 262138689Sborman strcpy(rcbuf, rcname); 262238689Sborman else 262338689Sborman rcbuf[0] = '\0'; 262438689Sborman strcat(rcbuf, "/.telnetrc"); 262538689Sborman rcname = rcbuf; 262638689Sborman } 262738689Sborman 262838689Sborman if ((rcfile = fopen(rcname, "r")) == 0) { 262938689Sborman return; 263038689Sborman } 263138689Sborman 263238689Sborman for (;;) { 263338689Sborman if (fgets(line, sizeof(line), rcfile) == NULL) 263438689Sborman break; 263538689Sborman if (line[0] == 0) 263638689Sborman break; 263738689Sborman if (line[0] == '#') 263838689Sborman continue; 263947609Sdab if (gotmachine) { 264047609Sdab if (!isspace(line[0])) 264147609Sdab gotmachine = 0; 264247609Sdab } 264338689Sborman if (gotmachine == 0) { 264438689Sborman if (isspace(line[0])) 264538689Sborman continue; 264638689Sborman if (strncasecmp(line, m1, l1) == 0) 264738689Sborman strncpy(line, &line[l1], sizeof(line) - l1); 264838689Sborman else if (strncasecmp(line, m2, l2) == 0) 264938689Sborman strncpy(line, &line[l2], sizeof(line) - l2); 265047609Sdab else if (strncasecmp(line, "DEFAULT", 7) == 0) 265147609Sdab strncpy(line, &line[7], sizeof(line) - 7); 265238689Sborman else 265338689Sborman continue; 265447609Sdab if (line[0] != ' ' && line[0] != '\t' && line[0] != '\n') 265547609Sdab continue; 265638689Sborman gotmachine = 1; 265738689Sborman } 265838689Sborman makeargv(); 265938689Sborman if (margv[0] == 0) 266038689Sborman continue; 266138689Sborman c = getcmd(margv[0]); 266238689Sborman if (Ambiguous(c)) { 266338689Sborman printf("?Ambiguous command: %s\n", margv[0]); 266438689Sborman continue; 266538689Sborman } 266638689Sborman if (c == 0) { 266738689Sborman printf("?Invalid command: %s\n", margv[0]); 266838689Sborman continue; 266938689Sborman } 267038689Sborman /* 267138689Sborman * This should never happen... 267238689Sborman */ 267338689Sborman if (c->needconnect && !connected) { 267438689Sborman printf("?Need to be connected first for %s.\n", margv[0]); 267538689Sborman continue; 267638689Sborman } 267738689Sborman (*c->handler)(margc, margv); 267838689Sborman } 267938689Sborman fclose(rcfile); 268038689Sborman } 268138689Sborman 268246808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 268338689Sborman 268438689Sborman /* 268538689Sborman * Source route is handed in as 268638689Sborman * [!]@hop1@hop2...[@|:]dst 268738689Sborman * If the leading ! is present, it is a 268838689Sborman * strict source route, otherwise it is 268938689Sborman * assmed to be a loose source route. 269038689Sborman * 269138689Sborman * We fill in the source route option as 269238689Sborman * hop1,hop2,hop3...dest 269338689Sborman * and return a pointer to hop1, which will 269438689Sborman * be the address to connect() to. 269538689Sborman * 269638689Sborman * Arguments: 269738689Sborman * arg: pointer to route list to decipher 269838689Sborman * 269938689Sborman * cpp: If *cpp is not equal to NULL, this is a 270038689Sborman * pointer to a pointer to a character array 270138689Sborman * that should be filled in with the option. 270238689Sborman * 270338689Sborman * lenp: pointer to an integer that contains the 270438689Sborman * length of *cpp if *cpp != NULL. 270538689Sborman * 270638689Sborman * Return values: 270738689Sborman * 270838689Sborman * Returns the address of the host to connect to. If the 270938689Sborman * return value is -1, there was a syntax error in the 271038689Sborman * option, either unknown characters, or too many hosts. 271138689Sborman * If the return value is 0, one of the hostnames in the 271238689Sborman * path is unknown, and *cpp is set to point to the bad 271338689Sborman * hostname. 271438689Sborman * 271538689Sborman * *cpp: If *cpp was equal to NULL, it will be filled 271638689Sborman * in with a pointer to our static area that has 271738689Sborman * the option filled in. This will be 32bit aligned. 271838689Sborman * 271938689Sborman * *lenp: This will be filled in with how long the option 272038689Sborman * pointed to by *cpp is. 272138689Sborman * 272238689Sborman */ 272346808Sdab unsigned long 272438689Sborman sourceroute(arg, cpp, lenp) 272546808Sdab char *arg; 272646808Sdab char **cpp; 272746808Sdab int *lenp; 272838689Sborman { 272938689Sborman static char lsr[44]; 273057213Sdab #ifdef sysV88 273157213Sdab static IOPTN ipopt; 273257213Sdab #endif 273346808Sdab char *cp, *cp2, *lsrp, *lsrep; 273438689Sborman register int tmp; 273538689Sborman struct in_addr sin_addr; 273638689Sborman register struct hostent *host = 0; 273738689Sborman register char c; 273838689Sborman 273938689Sborman /* 274038689Sborman * Verify the arguments, and make sure we have 274138689Sborman * at least 7 bytes for the option. 274238689Sborman */ 274338689Sborman if (cpp == NULL || lenp == NULL) 274438689Sborman return((unsigned long)-1); 274538689Sborman if (*cpp != NULL && *lenp < 7) 274638689Sborman return((unsigned long)-1); 274738689Sborman /* 274838689Sborman * Decide whether we have a buffer passed to us, 274938689Sborman * or if we need to use our own static buffer. 275038689Sborman */ 275138689Sborman if (*cpp) { 275238689Sborman lsrp = *cpp; 275338689Sborman lsrep = lsrp + *lenp; 275438689Sborman } else { 275538689Sborman *cpp = lsrp = lsr; 275638689Sborman lsrep = lsrp + 44; 275738689Sborman } 275838689Sborman 275938689Sborman cp = arg; 276038689Sborman 276138689Sborman /* 276238689Sborman * Next, decide whether we have a loose source 276338689Sborman * route or a strict source route, and fill in 276438689Sborman * the begining of the option. 276538689Sborman */ 276657213Sdab #ifndef sysV88 276738689Sborman if (*cp == '!') { 276838689Sborman cp++; 276938689Sborman *lsrp++ = IPOPT_SSRR; 277038689Sborman } else 277138689Sborman *lsrp++ = IPOPT_LSRR; 277257213Sdab #else 277357213Sdab if (*cp == '!') { 277457213Sdab cp++; 277557213Sdab ipopt.io_type = IPOPT_SSRR; 277657213Sdab } else 277757213Sdab ipopt.io_type = IPOPT_LSRR; 277857213Sdab #endif 277938689Sborman 278038689Sborman if (*cp != '@') 278138689Sborman return((unsigned long)-1); 278238689Sborman 278357213Sdab #ifndef sysV88 278438689Sborman lsrp++; /* skip over length, we'll fill it in later */ 278538689Sborman *lsrp++ = 4; 278657213Sdab #endif 278738689Sborman 278838689Sborman cp++; 278938689Sborman 279038689Sborman sin_addr.s_addr = 0; 279138689Sborman 279238689Sborman for (c = 0;;) { 279338689Sborman if (c == ':') 279438689Sborman cp2 = 0; 279538689Sborman else for (cp2 = cp; c = *cp2; cp2++) { 279638689Sborman if (c == ',') { 279738689Sborman *cp2++ = '\0'; 279838689Sborman if (*cp2 == '@') 279938689Sborman cp2++; 280038689Sborman } else if (c == '@') { 280138689Sborman *cp2++ = '\0'; 280238689Sborman } else if (c == ':') { 280338689Sborman *cp2++ = '\0'; 280438689Sborman } else 280538689Sborman continue; 280638689Sborman break; 280738689Sborman } 280838689Sborman if (!c) 280938689Sborman cp2 = 0; 281038689Sborman 281138689Sborman if ((tmp = inet_addr(cp)) != -1) { 281238689Sborman sin_addr.s_addr = tmp; 281338689Sborman } else if (host = gethostbyname(cp)) { 281438689Sborman #if defined(h_addr) 281538689Sborman memcpy((caddr_t)&sin_addr, 281638689Sborman host->h_addr_list[0], host->h_length); 281738689Sborman #else 281838689Sborman memcpy((caddr_t)&sin_addr, host->h_addr, host->h_length); 281938689Sborman #endif 282038689Sborman } else { 282138689Sborman *cpp = cp; 282238689Sborman return(0); 282338689Sborman } 282438689Sborman memcpy(lsrp, (char *)&sin_addr, 4); 282538689Sborman lsrp += 4; 282638689Sborman if (cp2) 282738689Sborman cp = cp2; 282838689Sborman else 282938689Sborman break; 283038689Sborman /* 283138689Sborman * Check to make sure there is space for next address 283238689Sborman */ 283338689Sborman if (lsrp + 4 > lsrep) 283438689Sborman return((unsigned long)-1); 283538689Sborman } 283657213Sdab #ifndef sysV88 283738689Sborman if ((*(*cpp+IPOPT_OLEN) = lsrp - *cpp) <= 7) { 283838689Sborman *cpp = 0; 283938689Sborman *lenp = 0; 284038689Sborman return((unsigned long)-1); 284138689Sborman } 284238689Sborman *lsrp++ = IPOPT_NOP; /* 32 bit word align it */ 284338689Sborman *lenp = lsrp - *cpp; 284457213Sdab #else 284557213Sdab ipopt.io_len = lsrp - *cpp; 284657213Sdab if (ipopt.io_len <= 5) { /* Is 3 better ? */ 284757213Sdab *cpp = 0; 284857213Sdab *lenp = 0; 284957213Sdab return((unsigned long)-1); 285057213Sdab } 285157213Sdab *lenp = sizeof(ipopt); 285257213Sdab *cpp = (char *) &ipopt; 285357213Sdab #endif 285438689Sborman return(sin_addr.s_addr); 285538689Sborman } 285638689Sborman #endif 2857