133685Sbostic /* 262309Sbostic * Copyright (c) 1988, 1990, 1993 362309Sbostic * The Regents of the University of California. All rights reserved. 433685Sbostic * 542770Sbostic * %sccs.include.redist.c% 633685Sbostic */ 733685Sbostic 833685Sbostic #ifndef lint 9*65157Sdab static char sccsid[] = "@(#)commands.c 8.2 (Berkeley) 12/15/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 return(send_tncmd(send_do, "do", name)); 35946808Sdab } 36046808Sdab 36146808Sdab static int 36246808Sdab send_dontcmd(name) 36346808Sdab char *name; 36446808Sdab { 36546808Sdab return(send_tncmd(send_dont, "dont", name)); 36646808Sdab } 36746808Sdab static int 36846808Sdab send_willcmd(name) 36946808Sdab char *name; 37046808Sdab { 37146808Sdab return(send_tncmd(send_will, "will", name)); 37246808Sdab } 37346808Sdab static int 37446808Sdab send_wontcmd(name) 37546808Sdab char *name; 37646808Sdab { 37746808Sdab return(send_tncmd(send_wont, "wont", name)); 37846808Sdab } 37946808Sdab 38046808Sdab int 38146808Sdab send_tncmd(func, cmd, name) 38246808Sdab void (*func)(); 38346808Sdab char *cmd, *name; 38446808Sdab { 38546808Sdab char **cpp; 38646808Sdab extern char *telopts[]; 38757213Sdab register int val = 0; 38846808Sdab 38946808Sdab if (isprefix(name, "help") || isprefix(name, "?")) { 39046808Sdab register int col, len; 39146808Sdab 39257213Sdab printf("Usage: send %s <value|option>\n", cmd); 39357213Sdab printf("\"value\" must be from 0 to 255\n"); 39446808Sdab printf("Valid options are:\n\t"); 39546808Sdab 39646808Sdab col = 8; 39746808Sdab for (cpp = telopts; *cpp; cpp++) { 39857213Sdab len = strlen(*cpp) + 3; 39946808Sdab if (col + len > 65) { 40046808Sdab printf("\n\t"); 40146808Sdab col = 8; 40232144Sminshall } 40357213Sdab printf(" \"%s\"", *cpp); 40446808Sdab col += len; 40532144Sminshall } 40646808Sdab printf("\n"); 40746808Sdab return 0; 40832144Sminshall } 40946808Sdab cpp = (char **)genget(name, telopts, sizeof(char *)); 41046808Sdab if (Ambiguous(cpp)) { 41146808Sdab fprintf(stderr,"'%s': ambiguous argument ('send %s ?' for help).\n", 41246808Sdab name, cmd); 41346808Sdab return 0; 41446808Sdab } 41557213Sdab if (cpp) { 41657213Sdab val = cpp - telopts; 41757213Sdab } else { 41857213Sdab register char *cp = name; 41957213Sdab 42057213Sdab while (*cp >= '0' && *cp <= '9') { 42157213Sdab val *= 10; 42257213Sdab val += *cp - '0'; 42357213Sdab cp++; 42457213Sdab } 42557213Sdab if (*cp != 0) { 42657213Sdab fprintf(stderr, "'%s': unknown argument ('send %s ?' for help).\n", 42746808Sdab name, cmd); 42857213Sdab return 0; 42957213Sdab } else if (val < 0 || val > 255) { 43057213Sdab fprintf(stderr, "'%s': bad value ('send %s ?' for help).\n", 43157213Sdab name, cmd); 43257213Sdab return 0; 43357213Sdab } 43446808Sdab } 43546808Sdab if (!connected) { 43646808Sdab printf("?Need to be connected first.\n"); 43746808Sdab return 0; 43846808Sdab } 43957213Sdab (*func)(val, 1); 44046808Sdab return 1; 44132144Sminshall } 44246808Sdab 44346808Sdab static int 44446808Sdab send_help() 44546808Sdab { 44646808Sdab struct sendlist *s; /* pointer to current command */ 44746808Sdab for (s = Sendlist; s->name; s++) { 44846808Sdab if (s->help) 44946808Sdab printf("%-15s %s\n", s->name, s->help); 45046808Sdab } 45146808Sdab return(0); 45246808Sdab } 45332144Sminshall 45432144Sminshall /* 45532144Sminshall * The following are the routines and data structures referred 45632144Sminshall * to by the arguments to the "toggle" command. 45732144Sminshall */ 45832144Sminshall 45946808Sdab static int 46032144Sminshall lclchars() 46132144Sminshall { 46232144Sminshall donelclchars = 1; 46332144Sminshall return 1; 46432144Sminshall } 46532144Sminshall 46646808Sdab static int 46732144Sminshall togdebug() 46832144Sminshall { 46932144Sminshall #ifndef NOT43 47032144Sminshall if (net > 0 && 47132144Sminshall (SetSockOpt(net, SOL_SOCKET, SO_DEBUG, debug)) < 0) { 47232144Sminshall perror("setsockopt (SO_DEBUG)"); 47332144Sminshall } 47432144Sminshall #else /* NOT43 */ 47532144Sminshall if (debug) { 47632144Sminshall if (net > 0 && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 0, 0) < 0) 47732144Sminshall perror("setsockopt (SO_DEBUG)"); 47832144Sminshall } else 47932144Sminshall printf("Cannot turn off socket debugging\n"); 48032144Sminshall #endif /* NOT43 */ 48132144Sminshall return 1; 48232144Sminshall } 48332144Sminshall 48432144Sminshall 48546808Sdab static int 48632144Sminshall togcrlf() 48732144Sminshall { 48832144Sminshall if (crlf) { 48932144Sminshall printf("Will send carriage returns as telnet <CR><LF>.\n"); 49032144Sminshall } else { 49132144Sminshall printf("Will send carriage returns as telnet <CR><NUL>.\n"); 49232144Sminshall } 49332144Sminshall return 1; 49432144Sminshall } 49532144Sminshall 49638909Sborman int binmode; 49732144Sminshall 49846808Sdab static int 49938689Sborman togbinary(val) 50046808Sdab int val; 50132144Sminshall { 50232144Sminshall donebinarytoggle = 1; 50332144Sminshall 50438909Sborman if (val >= 0) { 50538909Sborman binmode = val; 50638909Sborman } else { 50738909Sborman if (my_want_state_is_will(TELOPT_BINARY) && 50838909Sborman my_want_state_is_do(TELOPT_BINARY)) { 50938909Sborman binmode = 1; 51038909Sborman } else if (my_want_state_is_wont(TELOPT_BINARY) && 51138909Sborman my_want_state_is_dont(TELOPT_BINARY)) { 51238909Sborman binmode = 0; 51338909Sborman } 51438909Sborman val = binmode ? 0 : 1; 51538909Sborman } 51638909Sborman 51738909Sborman if (val == 1) { 51838909Sborman if (my_want_state_is_will(TELOPT_BINARY) && 51938909Sborman my_want_state_is_do(TELOPT_BINARY)) { 52038689Sborman printf("Already operating in binary mode with remote host.\n"); 52138909Sborman } else { 52238909Sborman printf("Negotiating binary mode with remote host.\n"); 52338909Sborman tel_enter_binary(3); 52438689Sborman } 52538909Sborman } else { 52638909Sborman if (my_want_state_is_wont(TELOPT_BINARY) && 52738909Sborman my_want_state_is_dont(TELOPT_BINARY)) { 52838689Sborman printf("Already in network ascii mode with remote host.\n"); 52938909Sborman } else { 53038909Sborman printf("Negotiating network ascii mode with remote host.\n"); 53138909Sborman tel_leave_binary(3); 53238689Sborman } 53332144Sminshall } 53432144Sminshall return 1; 53532144Sminshall } 53632144Sminshall 53746808Sdab static int 53838909Sborman togrbinary(val) 53946808Sdab int val; 54038909Sborman { 54138909Sborman donebinarytoggle = 1; 54232144Sminshall 54338909Sborman if (val == -1) 54438909Sborman val = my_want_state_is_do(TELOPT_BINARY) ? 0 : 1; 54532144Sminshall 54638909Sborman if (val == 1) { 54738909Sborman if (my_want_state_is_do(TELOPT_BINARY)) { 54838909Sborman printf("Already receiving in binary mode.\n"); 54938909Sborman } else { 55038909Sborman printf("Negotiating binary mode on input.\n"); 55138909Sborman tel_enter_binary(1); 55238909Sborman } 55338909Sborman } else { 55438909Sborman if (my_want_state_is_dont(TELOPT_BINARY)) { 55538909Sborman printf("Already receiving in network ascii mode.\n"); 55638909Sborman } else { 55738909Sborman printf("Negotiating network ascii mode on input.\n"); 55838909Sborman tel_leave_binary(1); 55938909Sborman } 56038909Sborman } 56138909Sborman return 1; 56238909Sborman } 56338909Sborman 56446808Sdab static int 56538909Sborman togxbinary(val) 56646808Sdab int val; 56738909Sborman { 56838909Sborman donebinarytoggle = 1; 56938909Sborman 57038909Sborman if (val == -1) 57138909Sborman val = my_want_state_is_will(TELOPT_BINARY) ? 0 : 1; 57238909Sborman 57338909Sborman if (val == 1) { 57438909Sborman if (my_want_state_is_will(TELOPT_BINARY)) { 57538909Sborman printf("Already transmitting in binary mode.\n"); 57638909Sborman } else { 57738909Sborman printf("Negotiating binary mode on output.\n"); 57838909Sborman tel_enter_binary(2); 57938909Sborman } 58038909Sborman } else { 58138909Sborman if (my_want_state_is_wont(TELOPT_BINARY)) { 58238909Sborman printf("Already transmitting in network ascii mode.\n"); 58338909Sborman } else { 58438909Sborman printf("Negotiating network ascii mode on output.\n"); 58538909Sborman tel_leave_binary(2); 58638909Sborman } 58738909Sborman } 58838909Sborman return 1; 58938909Sborman } 59038909Sborman 59138909Sborman 59256642Sralph static int togglehelp P((void)); 59357213Sdab #if defined(AUTHENTICATION) 59447609Sdab extern int auth_togdebug P((int)); 59547609Sdab #endif 59660149Sdab #ifdef ENCRYPTION 59747609Sdab extern int EncryptAutoEnc P((int)); 59847609Sdab extern int EncryptAutoDec P((int)); 59947609Sdab extern int EncryptDebug P((int)); 60047609Sdab extern int EncryptVerbose P((int)); 60160149Sdab #endif /* ENCRYPTION */ 60232144Sminshall 60332144Sminshall struct togglelist { 60432144Sminshall char *name; /* name of toggle */ 60532144Sminshall char *help; /* help message */ 60632144Sminshall int (*handler)(); /* routine to do actual setting */ 60732144Sminshall int *variable; 60832144Sminshall char *actionexplanation; 60932144Sminshall }; 61032144Sminshall 61132144Sminshall static struct togglelist Togglelist[] = { 61232144Sminshall { "autoflush", 61338689Sborman "flushing of output when sending interrupt characters", 61432144Sminshall 0, 61538689Sborman &autoflush, 61638689Sborman "flush output when sending interrupt characters" }, 61732144Sminshall { "autosynch", 61838689Sborman "automatic sending of interrupt characters in urgent mode", 61932144Sminshall 0, 62038689Sborman &autosynch, 62138689Sborman "send interrupt characters in urgent mode" }, 62257213Sdab #if defined(AUTHENTICATION) 62347609Sdab { "autologin", 62447609Sdab "automatic sending of login and/or authentication info", 62547609Sdab 0, 62647609Sdab &autologin, 62747609Sdab "send login name and/or authentication information" }, 62847609Sdab { "authdebug", 62947609Sdab "Toggle authentication debugging", 63047609Sdab auth_togdebug, 63147609Sdab 0, 63247609Sdab "print authentication debugging information" }, 63347609Sdab #endif 63460149Sdab #ifdef ENCRYPTION 63547609Sdab { "autoencrypt", 63647609Sdab "automatic encryption of data stream", 63747609Sdab EncryptAutoEnc, 63847609Sdab 0, 63947609Sdab "automatically encrypt output" }, 64047609Sdab { "autodecrypt", 64147609Sdab "automatic decryption of data stream", 64247609Sdab EncryptAutoDec, 64347609Sdab 0, 64447609Sdab "automatically decrypt input" }, 64547609Sdab { "verbose_encrypt", 64647609Sdab "Toggle verbose encryption output", 64747609Sdab EncryptVerbose, 64847609Sdab 0, 64947609Sdab "print verbose encryption output" }, 65047609Sdab { "encdebug", 65147609Sdab "Toggle encryption debugging", 65247609Sdab EncryptDebug, 65347609Sdab 0, 65447609Sdab "print encryption debugging information" }, 65560149Sdab #endif /* ENCRYPTION */ 65647609Sdab { "skiprc", 65747609Sdab "don't read ~/.telnetrc file", 65847609Sdab 0, 65947609Sdab &skiprc, 66057848Sdab "skip reading of ~/.telnetrc file" }, 66132144Sminshall { "binary", 66238689Sborman "sending and receiving of binary data", 66332144Sminshall togbinary, 66438689Sborman 0, 66538689Sborman 0 }, 66638909Sborman { "inbinary", 66738909Sborman "receiving of binary data", 66838909Sborman togrbinary, 66938909Sborman 0, 67038909Sborman 0 }, 67138909Sborman { "outbinary", 67238909Sborman "sending of binary data", 67338909Sborman togxbinary, 67438909Sborman 0, 67538909Sborman 0 }, 67632144Sminshall { "crlf", 67738689Sborman "sending carriage returns as telnet <CR><LF>", 67832144Sminshall togcrlf, 67938689Sborman &crlf, 68038689Sborman 0 }, 68132144Sminshall { "crmod", 68238689Sborman "mapping of received carriage returns", 68332144Sminshall 0, 68438689Sborman &crmod, 68538689Sborman "map carriage return on output" }, 68632144Sminshall { "localchars", 68738689Sborman "local recognition of certain control characters", 68832144Sminshall lclchars, 68938689Sborman &localchars, 69038689Sborman "recognize certain control characters" }, 69138689Sborman { " ", "", 0 }, /* empty line */ 69238208Sminshall #if defined(unix) && defined(TN3270) 69338920Sminshall { "apitrace", 69438920Sminshall "(debugging) toggle tracing of API transactions", 69538920Sminshall 0, 69638920Sminshall &apitrace, 69738920Sminshall "trace API transactions" }, 69838208Sminshall { "cursesdata", 69938208Sminshall "(debugging) toggle printing of hexadecimal curses data", 70038208Sminshall 0, 70138689Sborman &cursesdata, 70238689Sborman "print hexadecimal representation of curses data" }, 70338208Sminshall #endif /* defined(unix) && defined(TN3270) */ 70432144Sminshall { "debug", 70538689Sborman "debugging", 70632144Sminshall togdebug, 70738689Sborman &debug, 70838689Sborman "turn on socket level debugging" }, 70932144Sminshall { "netdata", 71038689Sborman "printing of hexadecimal network data (debugging)", 71132144Sminshall 0, 71238689Sborman &netdata, 71338689Sborman "print hexadecimal representation of network traffic" }, 71438689Sborman { "prettydump", 71538689Sborman "output of \"netdata\" to user readable format (debugging)", 71638689Sborman 0, 71738689Sborman &prettydump, 71838689Sborman "print user readable output for \"netdata\"" }, 71932144Sminshall { "options", 72038689Sborman "viewing of options processing (debugging)", 72132144Sminshall 0, 72238689Sborman &showoptions, 72338689Sborman "show option processing" }, 72438208Sminshall #if defined(unix) 72538208Sminshall { "termdata", 72638208Sminshall "(debugging) toggle printing of hexadecimal terminal data", 72738208Sminshall 0, 72838689Sborman &termdata, 72938689Sborman "print hexadecimal representation of terminal traffic" }, 73038208Sminshall #endif /* defined(unix) */ 73132144Sminshall { "?", 73238689Sborman 0, 73338689Sborman togglehelp }, 73432144Sminshall { "help", 73538689Sborman 0, 73638689Sborman togglehelp }, 73732144Sminshall { 0 } 73832144Sminshall }; 73932144Sminshall 74046808Sdab static int 74132144Sminshall togglehelp() 74232144Sminshall { 74332144Sminshall struct togglelist *c; 74432144Sminshall 74532144Sminshall for (c = Togglelist; c->name; c++) { 74638689Sborman if (c->help) { 74738689Sborman if (*c->help) 74838689Sborman printf("%-15s toggle %s\n", c->name, c->help); 74938689Sborman else 75038689Sborman printf("\n"); 75132144Sminshall } 75232144Sminshall } 75338689Sborman printf("\n"); 75438689Sborman printf("%-15s %s\n", "?", "display help information"); 75532144Sminshall return 0; 75632144Sminshall } 75732144Sminshall 75846808Sdab static void 75938689Sborman settogglehelp(set) 76046808Sdab int set; 76138689Sborman { 76238689Sborman struct togglelist *c; 76338689Sborman 76438689Sborman for (c = Togglelist; c->name; c++) { 76538689Sborman if (c->help) { 76638689Sborman if (*c->help) 76738689Sborman printf("%-15s %s %s\n", c->name, set ? "enable" : "disable", 76838689Sborman c->help); 76938689Sborman else 77038689Sborman printf("\n"); 77138689Sborman } 77238689Sborman } 77338689Sborman } 77438689Sborman 77546808Sdab #define GETTOGGLE(name) (struct togglelist *) \ 77646808Sdab genget(name, (char **) Togglelist, sizeof(struct togglelist)) 77732144Sminshall 77846808Sdab static int 77932144Sminshall toggle(argc, argv) 78046808Sdab int argc; 78146808Sdab char *argv[]; 78232144Sminshall { 78332144Sminshall int retval = 1; 78432144Sminshall char *name; 78532144Sminshall struct togglelist *c; 78632144Sminshall 78732144Sminshall if (argc < 2) { 78832144Sminshall fprintf(stderr, 78932144Sminshall "Need an argument to 'toggle' command. 'toggle ?' for help.\n"); 79032144Sminshall return 0; 79132144Sminshall } 79232144Sminshall argc--; 79332144Sminshall argv++; 79432144Sminshall while (argc--) { 79532144Sminshall name = *argv++; 79646808Sdab c = GETTOGGLE(name); 79732144Sminshall if (Ambiguous(c)) { 79832144Sminshall fprintf(stderr, "'%s': ambiguous argument ('toggle ?' for help).\n", 79932144Sminshall name); 80032144Sminshall return 0; 80132144Sminshall } else if (c == 0) { 80232144Sminshall fprintf(stderr, "'%s': unknown argument ('toggle ?' for help).\n", 80332144Sminshall name); 80432144Sminshall return 0; 80532144Sminshall } else { 80632144Sminshall if (c->variable) { 80732144Sminshall *c->variable = !*c->variable; /* invert it */ 80832144Sminshall if (c->actionexplanation) { 80932144Sminshall printf("%s %s.\n", *c->variable? "Will" : "Won't", 81032144Sminshall c->actionexplanation); 81132144Sminshall } 81232144Sminshall } 81332144Sminshall if (c->handler) { 81438689Sborman retval &= (*c->handler)(-1); 81532144Sminshall } 81632144Sminshall } 81732144Sminshall } 81832144Sminshall return retval; 81932144Sminshall } 82032144Sminshall 82132144Sminshall /* 82232144Sminshall * The following perform the "set" command. 82332144Sminshall */ 82432144Sminshall 82538689Sborman #ifdef USE_TERMIO 82638689Sborman struct termio new_tc = { 0 }; 82738689Sborman #endif 82838689Sborman 82932144Sminshall struct setlist { 83032144Sminshall char *name; /* name */ 83132144Sminshall char *help; /* help information */ 83238689Sborman void (*handler)(); 83340245Sborman cc_t *charp; /* where it is located at */ 83432144Sminshall }; 83532144Sminshall 83632144Sminshall static struct setlist Setlist[] = { 83744361Sborman #ifdef KLUDGELINEMODE 83838689Sborman { "echo", "character to toggle local echoing on/off", 0, &echoc }, 83944361Sborman #endif 84038689Sborman { "escape", "character to escape back to telnet command mode", 0, &escape }, 84146808Sdab { "rlogin", "rlogin escape character", 0, &rlogin }, 84245233Sborman { "tracefile", "file to write trace information to", SetNetTrace, (cc_t *)NetTraceFile}, 84332144Sminshall { " ", "" }, 84438689Sborman { " ", "The following need 'localchars' to be toggled true", 0, 0 }, 84545233Sborman { "flushoutput", "character to cause an Abort Output", 0, termFlushCharp }, 84638689Sborman { "interrupt", "character to cause an Interrupt Process", 0, termIntCharp }, 84738689Sborman { "quit", "character to cause an Abort process", 0, termQuitCharp }, 84838689Sborman { "eof", "character to cause an EOF ", 0, termEofCharp }, 84938689Sborman { " ", "" }, 85038689Sborman { " ", "The following are for local editing in linemode", 0, 0 }, 85138689Sborman { "erase", "character to use to erase a character", 0, termEraseCharp }, 85238689Sborman { "kill", "character to use to erase a line", 0, termKillCharp }, 85338689Sborman { "lnext", "character to use for literal next", 0, termLiteralNextCharp }, 85444361Sborman { "susp", "character to cause a Suspend Process", 0, termSuspCharp }, 85538689Sborman { "reprint", "character to use for line reprint", 0, termRprntCharp }, 85638689Sborman { "worderase", "character to use to erase a word", 0, termWerasCharp }, 85738689Sborman { "start", "character to use for XON", 0, termStartCharp }, 85844361Sborman { "stop", "character to use for XOFF", 0, termStopCharp }, 85944361Sborman { "forw1", "alternate end of line character", 0, termForw1Charp }, 86044361Sborman { "forw2", "alternate end of line character", 0, termForw2Charp }, 86145233Sborman { "ayt", "alternate AYT character", 0, termAytCharp }, 86232144Sminshall { 0 } 86332144Sminshall }; 86432144Sminshall 86545233Sborman #if defined(CRAY) && !defined(__STDC__) 86645233Sborman /* Work around compiler bug in pcc 4.1.5 */ 86746808Sdab void 86838689Sborman _setlist_init() 86938689Sborman { 87044361Sborman #ifndef KLUDGELINEMODE 87146808Sdab #define N 5 87244361Sborman #else 87346808Sdab #define N 6 87444361Sborman #endif 87544361Sborman Setlist[N+0].charp = &termFlushChar; 87644361Sborman Setlist[N+1].charp = &termIntChar; 87744361Sborman Setlist[N+2].charp = &termQuitChar; 87844361Sborman Setlist[N+3].charp = &termEofChar; 87944361Sborman Setlist[N+6].charp = &termEraseChar; 88044361Sborman Setlist[N+7].charp = &termKillChar; 88144361Sborman Setlist[N+8].charp = &termLiteralNextChar; 88244361Sborman Setlist[N+9].charp = &termSuspChar; 88344361Sborman Setlist[N+10].charp = &termRprntChar; 88444361Sborman Setlist[N+11].charp = &termWerasChar; 88544361Sborman Setlist[N+12].charp = &termStartChar; 88644361Sborman Setlist[N+13].charp = &termStopChar; 88744361Sborman Setlist[N+14].charp = &termForw1Char; 88844361Sborman Setlist[N+15].charp = &termForw2Char; 88945233Sborman Setlist[N+16].charp = &termAytChar; 89044361Sborman #undef N 89138689Sborman } 89245233Sborman #endif /* defined(CRAY) && !defined(__STDC__) */ 89338689Sborman 89446808Sdab static struct setlist * 89532144Sminshall getset(name) 89646808Sdab char *name; 89732144Sminshall { 89846808Sdab return (struct setlist *) 89946808Sdab genget(name, (char **) Setlist, sizeof(struct setlist)); 90032144Sminshall } 90132144Sminshall 90246808Sdab void 90344361Sborman set_escape_char(s) 90446808Sdab char *s; 90544361Sborman { 90646808Sdab if (rlogin != _POSIX_VDISABLE) { 90746808Sdab rlogin = (s && *s) ? special(s) : _POSIX_VDISABLE; 90846808Sdab printf("Telnet rlogin escape character is '%s'.\n", 90946808Sdab control(rlogin)); 91046808Sdab } else { 91146808Sdab escape = (s && *s) ? special(s) : _POSIX_VDISABLE; 91246808Sdab printf("Telnet escape character is '%s'.\n", control(escape)); 91346808Sdab } 91444361Sborman } 91544361Sborman 91646808Sdab static int 91732144Sminshall setcmd(argc, argv) 91846808Sdab int argc; 91946808Sdab char *argv[]; 92032144Sminshall { 92132144Sminshall int value; 92232144Sminshall struct setlist *ct; 92338689Sborman struct togglelist *c; 92432144Sminshall 92538689Sborman if (argc < 2 || argc > 3) { 92638689Sborman printf("Format is 'set Name Value'\n'set ?' for help.\n"); 92732144Sminshall return 0; 92832144Sminshall } 92946808Sdab if ((argc == 2) && (isprefix(argv[1], "?") || isprefix(argv[1], "help"))) { 93038689Sborman for (ct = Setlist; ct->name; ct++) 93138689Sborman printf("%-15s %s\n", ct->name, ct->help); 93238689Sborman printf("\n"); 93338689Sborman settogglehelp(1); 93438689Sborman printf("%-15s %s\n", "?", "display help information"); 93538689Sborman return 0; 93638689Sborman } 93732144Sminshall 93832144Sminshall ct = getset(argv[1]); 93932144Sminshall if (ct == 0) { 94046808Sdab c = GETTOGGLE(argv[1]); 94138689Sborman if (c == 0) { 94238689Sborman fprintf(stderr, "'%s': unknown argument ('set ?' for help).\n", 94332144Sminshall argv[1]); 94438689Sborman return 0; 94538689Sborman } else if (Ambiguous(c)) { 94638689Sborman fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n", 94738689Sborman argv[1]); 94838689Sborman return 0; 94938689Sborman } 95038689Sborman if (c->variable) { 95138689Sborman if ((argc == 2) || (strcmp("on", argv[2]) == 0)) 95238689Sborman *c->variable = 1; 95338689Sborman else if (strcmp("off", argv[2]) == 0) 95438689Sborman *c->variable = 0; 95538689Sborman else { 95638689Sborman printf("Format is 'set togglename [on|off]'\n'set ?' for help.\n"); 95738689Sborman return 0; 95838689Sborman } 95938689Sborman if (c->actionexplanation) { 96038689Sborman printf("%s %s.\n", *c->variable? "Will" : "Won't", 96138689Sborman c->actionexplanation); 96238689Sborman } 96338689Sborman } 96438689Sborman if (c->handler) 96538689Sborman (*c->handler)(1); 96638689Sborman } else if (argc != 3) { 96738689Sborman printf("Format is 'set Name Value'\n'set ?' for help.\n"); 96832144Sminshall return 0; 96932144Sminshall } else if (Ambiguous(ct)) { 97032144Sminshall fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n", 97132144Sminshall argv[1]); 97232144Sminshall return 0; 97338689Sborman } else if (ct->handler) { 97438689Sborman (*ct->handler)(argv[2]); 97544361Sborman printf("%s set to \"%s\".\n", ct->name, (char *)ct->charp); 97632144Sminshall } else { 97732144Sminshall if (strcmp("off", argv[2])) { 97832144Sminshall value = special(argv[2]); 97932144Sminshall } else { 98045233Sborman value = _POSIX_VDISABLE; 98132144Sminshall } 98240245Sborman *(ct->charp) = (cc_t)value; 98332144Sminshall printf("%s character is '%s'.\n", ct->name, control(*(ct->charp))); 98432144Sminshall } 98538689Sborman slc_check(); 98632144Sminshall return 1; 98732144Sminshall } 98838689Sborman 98946808Sdab static int 99038689Sborman unsetcmd(argc, argv) 99146808Sdab int argc; 99246808Sdab char *argv[]; 99338689Sborman { 99438689Sborman struct setlist *ct; 99538689Sborman struct togglelist *c; 99638689Sborman register char *name; 99738689Sborman 99838689Sborman if (argc < 2) { 99938689Sborman fprintf(stderr, 100038689Sborman "Need an argument to 'unset' command. 'unset ?' for help.\n"); 100138689Sborman return 0; 100238689Sborman } 100346808Sdab if (isprefix(argv[1], "?") || isprefix(argv[1], "help")) { 100438689Sborman for (ct = Setlist; ct->name; ct++) 100538689Sborman printf("%-15s %s\n", ct->name, ct->help); 100638689Sborman printf("\n"); 100738689Sborman settogglehelp(0); 100838689Sborman printf("%-15s %s\n", "?", "display help information"); 100938689Sborman return 0; 101038689Sborman } 101138689Sborman 101238689Sborman argc--; 101338689Sborman argv++; 101438689Sborman while (argc--) { 101538689Sborman name = *argv++; 101638689Sborman ct = getset(name); 101738689Sborman if (ct == 0) { 101846808Sdab c = GETTOGGLE(name); 101938689Sborman if (c == 0) { 102038689Sborman fprintf(stderr, "'%s': unknown argument ('unset ?' for help).\n", 102138689Sborman name); 102238689Sborman return 0; 102338689Sborman } else if (Ambiguous(c)) { 102438689Sborman fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n", 102538689Sborman name); 102638689Sborman return 0; 102738689Sborman } 102838689Sborman if (c->variable) { 102938689Sborman *c->variable = 0; 103038689Sborman if (c->actionexplanation) { 103138689Sborman printf("%s %s.\n", *c->variable? "Will" : "Won't", 103238689Sborman c->actionexplanation); 103338689Sborman } 103438689Sborman } 103538689Sborman if (c->handler) 103638689Sborman (*c->handler)(0); 103738689Sborman } else if (Ambiguous(ct)) { 103838689Sborman fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n", 103938689Sborman name); 104038689Sborman return 0; 104138689Sborman } else if (ct->handler) { 104238689Sborman (*ct->handler)(0); 104344361Sborman printf("%s reset to \"%s\".\n", ct->name, (char *)ct->charp); 104438689Sborman } else { 104545233Sborman *(ct->charp) = _POSIX_VDISABLE; 104638689Sborman printf("%s character is '%s'.\n", ct->name, control(*(ct->charp))); 104738689Sborman } 104838689Sborman } 104938689Sborman return 1; 105038689Sborman } 105132144Sminshall 105232144Sminshall /* 105332144Sminshall * The following are the data structures and routines for the 105432144Sminshall * 'mode' command. 105532144Sminshall */ 105638689Sborman #ifdef KLUDGELINEMODE 105738689Sborman extern int kludgelinemode; 105844361Sborman 105946808Sdab static int 106044361Sborman dokludgemode() 106144361Sborman { 106244361Sborman kludgelinemode = 1; 106344361Sborman send_wont(TELOPT_LINEMODE, 1); 106444361Sborman send_dont(TELOPT_SGA, 1); 106544361Sborman send_dont(TELOPT_ECHO, 1); 106644361Sborman } 106738689Sborman #endif 106832144Sminshall 106946808Sdab static int 107032144Sminshall dolinemode() 107132144Sminshall { 107238689Sborman #ifdef KLUDGELINEMODE 107338689Sborman if (kludgelinemode) 107438689Sborman send_dont(TELOPT_SGA, 1); 107538689Sborman #endif 107638689Sborman send_will(TELOPT_LINEMODE, 1); 107738689Sborman send_dont(TELOPT_ECHO, 1); 107832144Sminshall return 1; 107932144Sminshall } 108032144Sminshall 108146808Sdab static int 108232144Sminshall docharmode() 108332144Sminshall { 108438689Sborman #ifdef KLUDGELINEMODE 108538689Sborman if (kludgelinemode) 108638689Sborman send_do(TELOPT_SGA, 1); 108738689Sborman else 108838689Sborman #endif 108938689Sborman send_wont(TELOPT_LINEMODE, 1); 109038689Sborman send_do(TELOPT_ECHO, 1); 109138689Sborman return 1; 109238689Sborman } 109338689Sborman 109446808Sdab static int 109538689Sborman dolmmode(bit, on) 109646808Sdab int bit, on; 109738689Sborman { 109846808Sdab unsigned char c; 109938689Sborman extern int linemode; 110038689Sborman 110138689Sborman if (my_want_state_is_wont(TELOPT_LINEMODE)) { 110238689Sborman printf("?Need to have LINEMODE option enabled first.\n"); 110338689Sborman printf("'mode ?' for help.\n"); 110438689Sborman return 0; 110532144Sminshall } 110638689Sborman 110738689Sborman if (on) 110838689Sborman c = (linemode | bit); 110938689Sborman else 111038689Sborman c = (linemode & ~bit); 111138689Sborman lm_mode(&c, 1, 1); 111232144Sminshall return 1; 111332144Sminshall } 111432144Sminshall 111546808Sdab int 111646808Sdab setmode(bit) 111746808Sdab { 111846808Sdab return dolmmode(bit, 1); 111946808Sdab } 112046808Sdab 112146808Sdab int 112246808Sdab clearmode(bit) 112346808Sdab { 112446808Sdab return dolmmode(bit, 0); 112546808Sdab } 112646808Sdab 112738689Sborman struct modelist { 112838689Sborman char *name; /* command name */ 112938689Sborman char *help; /* help string */ 113038689Sborman int (*handler)(); /* routine which executes command */ 113138689Sborman int needconnect; /* Do we need to be connected to execute? */ 113238689Sborman int arg1; 113338689Sborman }; 113438689Sborman 113538689Sborman extern int modehelp(); 113638689Sborman 113738689Sborman static struct modelist ModeList[] = { 113838689Sborman { "character", "Disable LINEMODE option", docharmode, 1 }, 113939529Sborman #ifdef KLUDGELINEMODE 114039529Sborman { "", "(or disable obsolete line-by-line mode)", 0 }, 114138689Sborman #endif 114238689Sborman { "line", "Enable LINEMODE option", dolinemode, 1 }, 114339529Sborman #ifdef KLUDGELINEMODE 114439529Sborman { "", "(or enable obsolete line-by-line mode)", 0 }, 114538689Sborman #endif 114638689Sborman { "", "", 0 }, 114738689Sborman { "", "These require the LINEMODE option to be enabled", 0 }, 114838689Sborman { "isig", "Enable signal trapping", setmode, 1, MODE_TRAPSIG }, 114938689Sborman { "+isig", 0, setmode, 1, MODE_TRAPSIG }, 115038689Sborman { "-isig", "Disable signal trapping", clearmode, 1, MODE_TRAPSIG }, 115138689Sborman { "edit", "Enable character editing", setmode, 1, MODE_EDIT }, 115238689Sborman { "+edit", 0, setmode, 1, MODE_EDIT }, 115338689Sborman { "-edit", "Disable character editing", clearmode, 1, MODE_EDIT }, 115444361Sborman { "softtabs", "Enable tab expansion", setmode, 1, MODE_SOFT_TAB }, 115544361Sborman { "+softtabs", 0, setmode, 1, MODE_SOFT_TAB }, 115644361Sborman { "-softtabs", "Disable character editing", clearmode, 1, MODE_SOFT_TAB }, 115744361Sborman { "litecho", "Enable literal character echo", setmode, 1, MODE_LIT_ECHO }, 115844361Sborman { "+litecho", 0, setmode, 1, MODE_LIT_ECHO }, 115944361Sborman { "-litecho", "Disable literal character echo", clearmode, 1, MODE_LIT_ECHO }, 116038689Sborman { "help", 0, modehelp, 0 }, 116144361Sborman #ifdef KLUDGELINEMODE 116244361Sborman { "kludgeline", 0, dokludgemode, 1 }, 116344361Sborman #endif 116444361Sborman { "", "", 0 }, 116538689Sborman { "?", "Print help information", modehelp, 0 }, 116632144Sminshall { 0 }, 116732144Sminshall }; 116832144Sminshall 116932144Sminshall 117046808Sdab int 117138689Sborman modehelp() 117238689Sborman { 117338689Sborman struct modelist *mt; 117438689Sborman 117538689Sborman printf("format is: 'mode Mode', where 'Mode' is one of:\n\n"); 117638689Sborman for (mt = ModeList; mt->name; mt++) { 117738689Sborman if (mt->help) { 117838689Sborman if (*mt->help) 117938689Sborman printf("%-15s %s\n", mt->name, mt->help); 118038689Sborman else 118138689Sborman printf("\n"); 118238689Sborman } 118338689Sborman } 118438689Sborman return 0; 118538689Sborman } 118638689Sborman 118746808Sdab #define GETMODECMD(name) (struct modelist *) \ 118846808Sdab genget(name, (char **) ModeList, sizeof(struct modelist)) 118946808Sdab 119046808Sdab static int 119132144Sminshall modecmd(argc, argv) 119246808Sdab int argc; 119346808Sdab char *argv[]; 119432144Sminshall { 119538689Sborman struct modelist *mt; 119632144Sminshall 119738689Sborman if (argc != 2) { 119838689Sborman printf("'mode' command requires an argument\n"); 119938689Sborman printf("'mode ?' for help.\n"); 120046808Sdab } else if ((mt = GETMODECMD(argv[1])) == 0) { 120132144Sminshall fprintf(stderr, "Unknown mode '%s' ('mode ?' for help).\n", argv[1]); 120232144Sminshall } else if (Ambiguous(mt)) { 120332144Sminshall fprintf(stderr, "Ambiguous mode '%s' ('mode ?' for help).\n", argv[1]); 120438689Sborman } else if (mt->needconnect && !connected) { 120538689Sborman printf("?Need to be connected first.\n"); 120638689Sborman printf("'mode ?' for help.\n"); 120738689Sborman } else if (mt->handler) { 120838689Sborman return (*mt->handler)(mt->arg1); 120932144Sminshall } 121038689Sborman return 0; 121132144Sminshall } 121232144Sminshall 121332144Sminshall /* 121432144Sminshall * The following data structures and routines implement the 121532144Sminshall * "display" command. 121632144Sminshall */ 121732144Sminshall 121846808Sdab static int 121932144Sminshall display(argc, argv) 122046808Sdab int argc; 122146808Sdab char *argv[]; 122232144Sminshall { 122346808Sdab struct togglelist *tl; 122446808Sdab struct setlist *sl; 122546808Sdab 122632144Sminshall #define dotog(tl) if (tl->variable && tl->actionexplanation) { \ 122732144Sminshall if (*tl->variable) { \ 122832144Sminshall printf("will"); \ 122932144Sminshall } else { \ 123032144Sminshall printf("won't"); \ 123132144Sminshall } \ 123232144Sminshall printf(" %s.\n", tl->actionexplanation); \ 123332144Sminshall } 123432144Sminshall 123532144Sminshall #define doset(sl) if (sl->name && *sl->name != ' ') { \ 123638689Sborman if (sl->handler == 0) \ 123738689Sborman printf("%-15s [%s]\n", sl->name, control(*sl->charp)); \ 123838689Sborman else \ 123944361Sborman printf("%-15s \"%s\"\n", sl->name, (char *)sl->charp); \ 124032144Sminshall } 124132144Sminshall 124232144Sminshall if (argc == 1) { 124332144Sminshall for (tl = Togglelist; tl->name; tl++) { 124432144Sminshall dotog(tl); 124532144Sminshall } 124632144Sminshall printf("\n"); 124732144Sminshall for (sl = Setlist; sl->name; sl++) { 124832144Sminshall doset(sl); 124932144Sminshall } 125032144Sminshall } else { 125132144Sminshall int i; 125232144Sminshall 125332144Sminshall for (i = 1; i < argc; i++) { 125432144Sminshall sl = getset(argv[i]); 125546808Sdab tl = GETTOGGLE(argv[i]); 125632144Sminshall if (Ambiguous(sl) || Ambiguous(tl)) { 125732144Sminshall printf("?Ambiguous argument '%s'.\n", argv[i]); 125832144Sminshall return 0; 125932144Sminshall } else if (!sl && !tl) { 126032144Sminshall printf("?Unknown argument '%s'.\n", argv[i]); 126132144Sminshall return 0; 126232144Sminshall } else { 126332144Sminshall if (tl) { 126432144Sminshall dotog(tl); 126532144Sminshall } 126632144Sminshall if (sl) { 126732144Sminshall doset(sl); 126832144Sminshall } 126932144Sminshall } 127032144Sminshall } 127132144Sminshall } 127238689Sborman /*@*/optionstatus(); 127360149Sdab #ifdef ENCRYPTION 127446808Sdab EncryptStatus(); 127560149Sdab #endif /* ENCRYPTION */ 127632144Sminshall return 1; 127732144Sminshall #undef doset 127832144Sminshall #undef dotog 127932144Sminshall } 128032144Sminshall 128132144Sminshall /* 128232144Sminshall * The following are the data structures, and many of the routines, 128332144Sminshall * relating to command processing. 128432144Sminshall */ 128532144Sminshall 128632144Sminshall /* 128732144Sminshall * Set the escape character. 128832144Sminshall */ 128946808Sdab static int 129032144Sminshall setescape(argc, argv) 129132144Sminshall int argc; 129232144Sminshall char *argv[]; 129332144Sminshall { 129432144Sminshall register char *arg; 129532144Sminshall char buf[50]; 129632144Sminshall 129732144Sminshall printf( 129832144Sminshall "Deprecated usage - please use 'set escape%s%s' in the future.\n", 129932144Sminshall (argc > 2)? " ":"", (argc > 2)? argv[1]: ""); 130032144Sminshall if (argc > 2) 130132144Sminshall arg = argv[1]; 130232144Sminshall else { 130332144Sminshall printf("new escape character: "); 130446808Sdab (void) fgets(buf, sizeof(buf), stdin); 130532144Sminshall arg = buf; 130632144Sminshall } 130732144Sminshall if (arg[0] != '\0') 130832144Sminshall escape = arg[0]; 130932144Sminshall if (!In3270) { 131032144Sminshall printf("Escape character is '%s'.\n", control(escape)); 131132144Sminshall } 131234849Sminshall (void) fflush(stdout); 131332144Sminshall return 1; 131432144Sminshall } 131532144Sminshall 131646808Sdab /*VARARGS*/ 131746808Sdab static int 131832144Sminshall togcrmod() 131932144Sminshall { 132032144Sminshall crmod = !crmod; 132132144Sminshall printf("Deprecated usage - please use 'toggle crmod' in the future.\n"); 132232144Sminshall printf("%s map carriage return on output.\n", crmod ? "Will" : "Won't"); 132334849Sminshall (void) fflush(stdout); 132432144Sminshall return 1; 132532144Sminshall } 132632144Sminshall 132746808Sdab /*VARARGS*/ 132846808Sdab int 132932144Sminshall suspend() 133032144Sminshall { 133138689Sborman #ifdef SIGTSTP 133237219Sminshall setcommandmode(); 133337219Sminshall { 133444361Sborman long oldrows, oldcols, newrows, newcols, err; 133537219Sminshall 133657213Sdab err = (TerminalWindowSize(&oldrows, &oldcols) == 0) ? 1 : 0; 133734849Sminshall (void) kill(0, SIGTSTP); 133857213Sdab /* 133957213Sdab * If we didn't get the window size before the SUSPEND, but we 134057213Sdab * can get them now (???), then send the NAWS to make sure that 134157213Sdab * we are set up for the right window size. 134257213Sdab */ 134357213Sdab if (TerminalWindowSize(&newrows, &newcols) && connected && 134457213Sdab (err || ((oldrows != newrows) || (oldcols != newcols)))) { 134537219Sminshall sendnaws(); 134637219Sminshall } 134737219Sminshall } 134837219Sminshall /* reget parameters in case they were changed */ 134937219Sminshall TerminalSaveState(); 135038689Sborman setconnmode(0); 135138689Sborman #else 135238689Sborman printf("Suspend is not supported. Try the '!' command instead\n"); 135338689Sborman #endif 135437219Sminshall return 1; 135532144Sminshall } 135632144Sminshall 135738689Sborman #if !defined(TN3270) 135846808Sdab /*ARGSUSED*/ 135946808Sdab int 136038689Sborman shell(argc, argv) 136146808Sdab int argc; 136246808Sdab char *argv[]; 136338689Sborman { 136457213Sdab long oldrows, oldcols, newrows, newcols, err; 136557213Sdab 136638689Sborman setcommandmode(); 136757213Sdab 136857213Sdab err = (TerminalWindowSize(&oldrows, &oldcols) == 0) ? 1 : 0; 136938689Sborman switch(vfork()) { 137038689Sborman case -1: 137138689Sborman perror("Fork failed\n"); 137238689Sborman break; 137338689Sborman 137438689Sborman case 0: 137538689Sborman { 137638689Sborman /* 137738689Sborman * Fire up the shell in the child. 137838689Sborman */ 137946808Sdab register char *shellp, *shellname; 138046808Sdab extern char *rindex(); 138138689Sborman 138246808Sdab shellp = getenv("SHELL"); 138346808Sdab if (shellp == NULL) 138446808Sdab shellp = "/bin/sh"; 138546808Sdab if ((shellname = rindex(shellp, '/')) == 0) 138646808Sdab shellname = shellp; 138738689Sborman else 138838689Sborman shellname++; 138938689Sborman if (argc > 1) 139046808Sdab execl(shellp, shellname, "-c", &saveline[1], 0); 139138689Sborman else 139246808Sdab execl(shellp, shellname, 0); 139338689Sborman perror("Execl"); 139438689Sborman _exit(1); 139538689Sborman } 139638689Sborman default: 139744361Sborman (void)wait((int *)0); /* Wait for the shell to complete */ 139857213Sdab 139957213Sdab if (TerminalWindowSize(&newrows, &newcols) && connected && 140057213Sdab (err || ((oldrows != newrows) || (oldcols != newcols)))) { 140157213Sdab sendnaws(); 140257213Sdab } 140357213Sdab break; 140438689Sborman } 140546808Sdab return 1; 140638689Sborman } 140759893Sbostic #else /* !defined(TN3270) */ 140859893Sbostic extern int shell(); 140938689Sborman #endif /* !defined(TN3270) */ 141038689Sborman 141146808Sdab /*VARARGS*/ 141246808Sdab static 141332144Sminshall bye(argc, argv) 141446808Sdab int argc; /* Number of arguments */ 141546808Sdab char *argv[]; /* arguments */ 141632144Sminshall { 141746808Sdab extern int resettermname; 141846808Sdab 141932144Sminshall if (connected) { 142034849Sminshall (void) shutdown(net, 2); 142132144Sminshall printf("Connection closed.\n"); 142234849Sminshall (void) NetClose(net); 142332144Sminshall connected = 0; 142446808Sdab resettermname = 1; 142557213Sdab #if defined(AUTHENTICATION) || defined(ENCRYPTION) 142646808Sdab auth_encrypt_connect(connected); 142760149Sdab #endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */ 142832144Sminshall /* reset options */ 142932144Sminshall tninit(); 143032144Sminshall #if defined(TN3270) 143132144Sminshall SetIn3270(); /* Get out of 3270 mode */ 143232144Sminshall #endif /* defined(TN3270) */ 143332144Sminshall } 143432144Sminshall if ((argc != 2) || (strcmp(argv[1], "fromquit") != 0)) { 143532144Sminshall longjmp(toplevel, 1); 143632144Sminshall /* NOTREACHED */ 143732144Sminshall } 143832144Sminshall return 1; /* Keep lint, etc., happy */ 143932144Sminshall } 144032144Sminshall 144132144Sminshall /*VARARGS*/ 144232144Sminshall quit() 144332144Sminshall { 144432144Sminshall (void) call(bye, "bye", "fromquit", 0); 144532144Sminshall Exit(0); 144644361Sborman /*NOTREACHED*/ 144732144Sminshall } 144846808Sdab 144946808Sdab /*VARARGS*/ 145046808Sdab int 145146808Sdab logout() 145246808Sdab { 145346808Sdab send_do(TELOPT_LOGOUT, 1); 145446808Sdab (void) netflush(); 145546808Sdab return 1; 145646808Sdab } 145746808Sdab 145838689Sborman 145938689Sborman /* 146038689Sborman * The SLC command. 146138689Sborman */ 146232144Sminshall 146338689Sborman struct slclist { 146438689Sborman char *name; 146538689Sborman char *help; 146646808Sdab void (*handler)(); 146738689Sborman int arg; 146838689Sborman }; 146938689Sborman 147056642Sralph static void slc_help(); 147138689Sborman 147238689Sborman struct slclist SlcList[] = { 147338689Sborman { "export", "Use local special character definitions", 147438689Sborman slc_mode_export, 0 }, 147538689Sborman { "import", "Use remote special character definitions", 147638689Sborman slc_mode_import, 1 }, 147738689Sborman { "check", "Verify remote special character definitions", 147838689Sborman slc_mode_import, 0 }, 147938689Sborman { "help", 0, slc_help, 0 }, 148038689Sborman { "?", "Print help information", slc_help, 0 }, 148138689Sborman { 0 }, 148238689Sborman }; 148338689Sborman 148446808Sdab static void 148538689Sborman slc_help() 148638689Sborman { 148738689Sborman struct slclist *c; 148838689Sborman 148938689Sborman for (c = SlcList; c->name; c++) { 149038689Sborman if (c->help) { 149138689Sborman if (*c->help) 149238689Sborman printf("%-15s %s\n", c->name, c->help); 149338689Sborman else 149438689Sborman printf("\n"); 149538689Sborman } 149638689Sborman } 149738689Sborman } 149838689Sborman 149946808Sdab static struct slclist * 150038689Sborman getslc(name) 150146808Sdab char *name; 150238689Sborman { 150346808Sdab return (struct slclist *) 150446808Sdab genget(name, (char **) SlcList, sizeof(struct slclist)); 150538689Sborman } 150638689Sborman 150746808Sdab static 150838689Sborman slccmd(argc, argv) 150946808Sdab int argc; 151046808Sdab char *argv[]; 151138689Sborman { 151238689Sborman struct slclist *c; 151338689Sborman 151438689Sborman if (argc != 2) { 151538689Sborman fprintf(stderr, 151638689Sborman "Need an argument to 'slc' command. 'slc ?' for help.\n"); 151738689Sborman return 0; 151838689Sborman } 151938689Sborman c = getslc(argv[1]); 152038689Sborman if (c == 0) { 152138689Sborman fprintf(stderr, "'%s': unknown argument ('slc ?' for help).\n", 152238689Sborman argv[1]); 152338689Sborman return 0; 152438689Sborman } 152538689Sborman if (Ambiguous(c)) { 152638689Sborman fprintf(stderr, "'%s': ambiguous argument ('slc ?' for help).\n", 152738689Sborman argv[1]); 152838689Sborman return 0; 152938689Sborman } 153038689Sborman (*c->handler)(c->arg); 153138689Sborman slcstate(); 153238689Sborman return 1; 153338689Sborman } 153444361Sborman 153544361Sborman /* 153644361Sborman * The ENVIRON command. 153744361Sborman */ 153838689Sborman 153944361Sborman struct envlist { 154044361Sborman char *name; 154144361Sborman char *help; 154246808Sdab void (*handler)(); 154344361Sborman int narg; 154444361Sborman }; 154544361Sborman 154646808Sdab extern struct env_lst * 154746808Sdab env_define P((unsigned char *, unsigned char *)); 154846808Sdab extern void 154946808Sdab env_undefine P((unsigned char *)), 155046808Sdab env_export P((unsigned char *)), 155146808Sdab env_unexport P((unsigned char *)), 155246808Sdab env_send P((unsigned char *)), 1553*65157Sdab #if defined(OLD_ENVIRON) && defined(ENV_HACK) 155458972Sdab env_varval P((unsigned char *)), 155558972Sdab #endif 155656642Sralph env_list P((void)); 155756642Sralph static void 155846808Sdab env_help P((void)); 155944361Sborman 156044361Sborman struct envlist EnvList[] = { 156144361Sborman { "define", "Define an environment variable", 156246808Sdab (void (*)())env_define, 2 }, 156344361Sborman { "undefine", "Undefine an environment variable", 156444361Sborman env_undefine, 1 }, 156544361Sborman { "export", "Mark an environment variable for automatic export", 156644361Sborman env_export, 1 }, 156746808Sdab { "unexport", "Don't mark an environment variable for automatic export", 156844361Sborman env_unexport, 1 }, 156945233Sborman { "send", "Send an environment variable", env_send, 1 }, 157044361Sborman { "list", "List the current environment variables", 157144361Sborman env_list, 0 }, 1572*65157Sdab #if defined(OLD_ENVIRON) && defined(ENV_HACK) 157358972Sdab { "varval", "Reverse VAR and VALUE (auto, right, wrong, status)", 157458972Sdab env_varval, 1 }, 157558972Sdab #endif 157644361Sborman { "help", 0, env_help, 0 }, 157744361Sborman { "?", "Print help information", env_help, 0 }, 157844361Sborman { 0 }, 157944361Sborman }; 158044361Sborman 158146808Sdab static void 158244361Sborman env_help() 158344361Sborman { 158444361Sborman struct envlist *c; 158544361Sborman 158644361Sborman for (c = EnvList; c->name; c++) { 158744361Sborman if (c->help) { 158844361Sborman if (*c->help) 158944361Sborman printf("%-15s %s\n", c->name, c->help); 159044361Sborman else 159144361Sborman printf("\n"); 159244361Sborman } 159344361Sborman } 159444361Sborman } 159544361Sborman 159646808Sdab static struct envlist * 159744361Sborman getenvcmd(name) 159846808Sdab char *name; 159944361Sborman { 160046808Sdab return (struct envlist *) 160146808Sdab genget(name, (char **) EnvList, sizeof(struct envlist)); 160244361Sborman } 160344361Sborman 160444361Sborman env_cmd(argc, argv) 160546808Sdab int argc; 160646808Sdab char *argv[]; 160744361Sborman { 160844361Sborman struct envlist *c; 160944361Sborman 161044361Sborman if (argc < 2) { 161144361Sborman fprintf(stderr, 161244361Sborman "Need an argument to 'environ' command. 'environ ?' for help.\n"); 161344361Sborman return 0; 161444361Sborman } 161544361Sborman c = getenvcmd(argv[1]); 161644361Sborman if (c == 0) { 161744361Sborman fprintf(stderr, "'%s': unknown argument ('environ ?' for help).\n", 161844361Sborman argv[1]); 161944361Sborman return 0; 162044361Sborman } 162144361Sborman if (Ambiguous(c)) { 162244361Sborman fprintf(stderr, "'%s': ambiguous argument ('environ ?' for help).\n", 162344361Sborman argv[1]); 162444361Sborman return 0; 162544361Sborman } 162644361Sborman if (c->narg + 2 != argc) { 162744361Sborman fprintf(stderr, 162844361Sborman "Need %s%d argument%s to 'environ %s' command. 'environ ?' for help.\n", 162944361Sborman c->narg < argc + 2 ? "only " : "", 163044361Sborman c->narg, c->narg == 1 ? "" : "s", c->name); 163144361Sborman return 0; 163244361Sborman } 163346808Sdab (*c->handler)(argv[2], argv[3]); 163444361Sborman return 1; 163544361Sborman } 163644361Sborman 163744361Sborman struct env_lst { 163844361Sborman struct env_lst *next; /* pointer to next structure */ 163957213Sdab struct env_lst *prev; /* pointer to previous structure */ 164046808Sdab unsigned char *var; /* pointer to variable name */ 164157213Sdab unsigned char *value; /* pointer to variable value */ 164244361Sborman int export; /* 1 -> export with default list of variables */ 164357213Sdab int welldefined; /* A well defined variable */ 164444361Sborman }; 164544361Sborman 164644361Sborman struct env_lst envlisthead; 164744361Sborman 164846808Sdab struct env_lst * 164944361Sborman env_find(var) 165046808Sdab unsigned char *var; 165144361Sborman { 165244361Sborman register struct env_lst *ep; 165344361Sborman 165444361Sborman for (ep = envlisthead.next; ep; ep = ep->next) { 165546808Sdab if (strcmp((char *)ep->var, (char *)var) == 0) 165644361Sborman return(ep); 165744361Sborman } 165844361Sborman return(NULL); 165944361Sborman } 166044361Sborman 166146808Sdab void 166244361Sborman env_init() 166344361Sborman { 166446808Sdab extern char **environ; 166544361Sborman register char **epp, *cp; 166644361Sborman register struct env_lst *ep; 166746808Sdab extern char *index(); 166844361Sborman 166944361Sborman for (epp = environ; *epp; epp++) { 167044361Sborman if (cp = index(*epp, '=')) { 167144361Sborman *cp = '\0'; 167246808Sdab ep = env_define((unsigned char *)*epp, 167346808Sdab (unsigned char *)cp+1); 167444361Sborman ep->export = 0; 167544361Sborman *cp = '='; 167644361Sborman } 167744361Sborman } 167844361Sborman /* 167944361Sborman * Special case for DISPLAY variable. If it is ":0.0" or 168044361Sborman * "unix:0.0", we have to get rid of "unix" and insert our 168144361Sborman * hostname. 168244361Sborman */ 168346808Sdab if ((ep = env_find("DISPLAY")) 168446808Sdab && ((*ep->value == ':') 168546808Sdab || (strncmp((char *)ep->value, "unix:", 5) == 0))) { 168644361Sborman char hbuf[256+1]; 168746808Sdab char *cp2 = index((char *)ep->value, ':'); 168844361Sborman 168944361Sborman gethostname(hbuf, 256); 169044361Sborman hbuf[256] = '\0'; 169144361Sborman cp = (char *)malloc(strlen(hbuf) + strlen(cp2) + 1); 169246808Sdab sprintf((char *)cp, "%s%s", hbuf, cp2); 169344361Sborman free(ep->value); 169446808Sdab ep->value = (unsigned char *)cp; 169544361Sborman } 169644361Sborman /* 169744361Sborman * If USER is not defined, but LOGNAME is, then add 169845233Sborman * USER with the value from LOGNAME. By default, we 169945233Sborman * don't export the USER variable. 170044361Sborman */ 170145233Sborman if ((env_find("USER") == NULL) && (ep = env_find("LOGNAME"))) { 170246808Sdab env_define((unsigned char *)"USER", ep->value); 170346808Sdab env_unexport((unsigned char *)"USER"); 170445233Sborman } 170546808Sdab env_export((unsigned char *)"DISPLAY"); 170646808Sdab env_export((unsigned char *)"PRINTER"); 170744361Sborman } 170844361Sborman 170946808Sdab struct env_lst * 171044361Sborman env_define(var, value) 171146808Sdab unsigned char *var, *value; 171244361Sborman { 171344361Sborman register struct env_lst *ep; 171444361Sborman 171544361Sborman if (ep = env_find(var)) { 171644361Sborman if (ep->var) 171744361Sborman free(ep->var); 171844361Sborman if (ep->value) 171944361Sborman free(ep->value); 172044361Sborman } else { 172144361Sborman ep = (struct env_lst *)malloc(sizeof(struct env_lst)); 172244361Sborman ep->next = envlisthead.next; 172344361Sborman envlisthead.next = ep; 172444361Sborman ep->prev = &envlisthead; 172544361Sborman if (ep->next) 172644361Sborman ep->next->prev = ep; 172744361Sborman } 172857213Sdab ep->welldefined = opt_welldefined(var); 172945009Skarels ep->export = 1; 173046808Sdab ep->var = (unsigned char *)strdup((char *)var); 173146808Sdab ep->value = (unsigned char *)strdup((char *)value); 173244361Sborman return(ep); 173344361Sborman } 173444361Sborman 173546808Sdab void 173644361Sborman env_undefine(var) 173746808Sdab unsigned char *var; 173844361Sborman { 173944361Sborman register struct env_lst *ep; 174044361Sborman 174144361Sborman if (ep = env_find(var)) { 174244361Sborman ep->prev->next = ep->next; 174345233Sborman if (ep->next) 174445233Sborman ep->next->prev = ep->prev; 174544361Sborman if (ep->var) 174644361Sborman free(ep->var); 174744361Sborman if (ep->value) 174844361Sborman free(ep->value); 174944361Sborman free(ep); 175044361Sborman } 175144361Sborman } 175244361Sborman 175346808Sdab void 175444361Sborman env_export(var) 175546808Sdab unsigned char *var; 175644361Sborman { 175744361Sborman register struct env_lst *ep; 175844361Sborman 175944361Sborman if (ep = env_find(var)) 176044361Sborman ep->export = 1; 176144361Sborman } 176244361Sborman 176346808Sdab void 176444361Sborman env_unexport(var) 176546808Sdab unsigned char *var; 176644361Sborman { 176744361Sborman register struct env_lst *ep; 176844361Sborman 176944361Sborman if (ep = env_find(var)) 177044361Sborman ep->export = 0; 177144361Sborman } 177244361Sborman 177346808Sdab void 177445233Sborman env_send(var) 177546808Sdab unsigned char *var; 177645233Sborman { 177745233Sborman register struct env_lst *ep; 177845233Sborman 1779*65157Sdab if (my_state_is_wont(TELOPT_NEW_ENVIRON) 1780*65157Sdab #ifdef OLD_ENVIRON 1781*65157Sdab && my_state_is_wont(TELOPT_OLD_ENVIRON) 1782*65157Sdab #endif 1783*65157Sdab ) { 178445233Sborman fprintf(stderr, 178545233Sborman "Cannot send '%s': Telnet ENVIRON option not enabled\n", 178645233Sborman var); 178745233Sborman return; 178845233Sborman } 178945233Sborman ep = env_find(var); 179045233Sborman if (ep == 0) { 179145233Sborman fprintf(stderr, "Cannot send '%s': variable not defined\n", 179245233Sborman var); 179345233Sborman return; 179445233Sborman } 179545233Sborman env_opt_start_info(); 179645233Sborman env_opt_add(ep->var); 179745233Sborman env_opt_end(0); 179845233Sborman } 179945233Sborman 180046808Sdab void 180144361Sborman env_list() 180244361Sborman { 180344361Sborman register struct env_lst *ep; 180444361Sborman 180544361Sborman for (ep = envlisthead.next; ep; ep = ep->next) { 180644361Sborman printf("%c %-20s %s\n", ep->export ? '*' : ' ', 180744361Sborman ep->var, ep->value); 180844361Sborman } 180944361Sborman } 181044361Sborman 181146808Sdab unsigned char * 181257213Sdab env_default(init, welldefined) 181346808Sdab int init; 181444361Sborman { 181544361Sborman static struct env_lst *nep = NULL; 181644361Sborman 181744361Sborman if (init) { 181844361Sborman nep = &envlisthead; 181944361Sborman return; 182044361Sborman } 182144361Sborman if (nep) { 182244361Sborman while (nep = nep->next) { 182357213Sdab if (nep->export && (nep->welldefined == welldefined)) 182444361Sborman return(nep->var); 182544361Sborman } 182644361Sborman } 182744361Sborman return(NULL); 182844361Sborman } 182944361Sborman 183046808Sdab unsigned char * 183144361Sborman env_getvalue(var) 183246808Sdab unsigned char *var; 183344361Sborman { 183444361Sborman register struct env_lst *ep; 183544361Sborman 183644361Sborman if (ep = env_find(var)) 183744361Sborman return(ep->value); 183844361Sborman return(NULL); 183944361Sborman } 184044361Sborman 1841*65157Sdab #if defined(OLD_ENVIRON) && defined(ENV_HACK) 184258972Sdab void 184358972Sdab env_varval(what) 184458972Sdab unsigned char *what; 184558972Sdab { 1846*65157Sdab extern int old_env_var, old_env_value, env_auto; 1847*65157Sdab int len = strlen((char *)what); 184858972Sdab 184958972Sdab if (len == 0) 185058972Sdab goto unknown; 185158972Sdab 1852*65157Sdab if (strncasecmp((char *)what, "status", len) == 0) { 185358972Sdab if (env_auto) 185458972Sdab printf("%s%s", "VAR and VALUE are/will be ", 185558972Sdab "determined automatically\n"); 1856*65157Sdab if (old_env_var == OLD_ENV_VAR) 185758972Sdab printf("VAR and VALUE set to correct definitions\n"); 185858972Sdab else 185958972Sdab printf("VAR and VALUE definitions are reversed\n"); 1860*65157Sdab } else if (strncasecmp((char *)what, "auto", len) == 0) { 186158972Sdab env_auto = 1; 1862*65157Sdab old_env_var = OLD_ENV_VALUE; 1863*65157Sdab old_env_value = OLD_ENV_VAR; 1864*65157Sdab } else if (strncasecmp((char *)what, "right", len) == 0) { 186558972Sdab env_auto = 0; 1866*65157Sdab old_env_var = OLD_ENV_VAR; 1867*65157Sdab old_env_value = OLD_ENV_VALUE; 1868*65157Sdab } else if (strncasecmp((char *)what, "wrong", len) == 0) { 186958972Sdab env_auto = 0; 1870*65157Sdab old_env_var = OLD_ENV_VALUE; 1871*65157Sdab old_env_value = OLD_ENV_VAR; 187258972Sdab } else { 187358972Sdab unknown: 187458972Sdab printf("Unknown \"varval\" command. (\"auto\", \"right\", \"wrong\", \"status\")\n"); 187558972Sdab } 187658972Sdab } 187758972Sdab #endif 187858972Sdab 187957213Sdab #if defined(AUTHENTICATION) 188046808Sdab /* 188146808Sdab * The AUTHENTICATE command. 188246808Sdab */ 188346808Sdab 188446808Sdab struct authlist { 188546808Sdab char *name; 188646808Sdab char *help; 188746808Sdab int (*handler)(); 188846808Sdab int narg; 188946808Sdab }; 189046808Sdab 189146808Sdab extern int 189246808Sdab auth_enable P((int)), 189346808Sdab auth_disable P((int)), 189456642Sralph auth_status P((void)); 189556642Sralph static int 189646808Sdab auth_help P((void)); 189746808Sdab 189846808Sdab struct authlist AuthList[] = { 189946808Sdab { "status", "Display current status of authentication information", 190046808Sdab auth_status, 0 }, 190146808Sdab { "disable", "Disable an authentication type ('auth disable ?' for more)", 190246808Sdab auth_disable, 1 }, 190346808Sdab { "enable", "Enable an authentication type ('auth enable ?' for more)", 190446808Sdab auth_enable, 1 }, 190546808Sdab { "help", 0, auth_help, 0 }, 190646808Sdab { "?", "Print help information", auth_help, 0 }, 190746808Sdab { 0 }, 190846808Sdab }; 190946808Sdab 191046808Sdab static int 191146808Sdab auth_help() 191244361Sborman { 191346808Sdab struct authlist *c; 191446808Sdab 191546808Sdab for (c = AuthList; c->name; c++) { 191646808Sdab if (c->help) { 191746808Sdab if (*c->help) 191846808Sdab printf("%-15s %s\n", c->name, c->help); 191946808Sdab else 192046808Sdab printf("\n"); 192146808Sdab } 192246808Sdab } 192346808Sdab return 0; 192444361Sborman } 192546808Sdab 192646808Sdab auth_cmd(argc, argv) 192746808Sdab int argc; 192846808Sdab char *argv[]; 192946808Sdab { 193046808Sdab struct authlist *c; 193146808Sdab 193246808Sdab c = (struct authlist *) 193346808Sdab genget(argv[1], (char **) AuthList, sizeof(struct authlist)); 193446808Sdab if (c == 0) { 193546808Sdab fprintf(stderr, "'%s': unknown argument ('auth ?' for help).\n", 193646808Sdab argv[1]); 193746808Sdab return 0; 193846808Sdab } 193946808Sdab if (Ambiguous(c)) { 194046808Sdab fprintf(stderr, "'%s': ambiguous argument ('auth ?' for help).\n", 194146808Sdab argv[1]); 194246808Sdab return 0; 194346808Sdab } 194446808Sdab if (c->narg + 2 != argc) { 194546808Sdab fprintf(stderr, 194646808Sdab "Need %s%d argument%s to 'auth %s' command. 'auth ?' for help.\n", 194746808Sdab c->narg < argc + 2 ? "only " : "", 194846808Sdab c->narg, c->narg == 1 ? "" : "s", c->name); 194946808Sdab return 0; 195046808Sdab } 195146808Sdab return((*c->handler)(argv[2], argv[3])); 195246808Sdab } 195345233Sborman #endif 195444361Sborman 195560149Sdab #ifdef ENCRYPTION 195632144Sminshall /* 195746808Sdab * The ENCRYPT command. 195836274Sminshall */ 195936274Sminshall 196046808Sdab struct encryptlist { 196146808Sdab char *name; 196246808Sdab char *help; 196346808Sdab int (*handler)(); 196446808Sdab int needconnect; 196546808Sdab int minarg; 196646808Sdab int maxarg; 196746808Sdab }; 196846808Sdab 196946808Sdab extern int 197046808Sdab EncryptEnable P((char *, char *)), 197147609Sdab EncryptDisable P((char *, char *)), 197246808Sdab EncryptType P((char *, char *)), 197346808Sdab EncryptStart P((char *)), 197446808Sdab EncryptStartInput P((void)), 197546808Sdab EncryptStartOutput P((void)), 197646808Sdab EncryptStop P((char *)), 197746808Sdab EncryptStopInput P((void)), 197846808Sdab EncryptStopOutput P((void)), 197956642Sralph EncryptStatus P((void)); 198056642Sralph static int 198146808Sdab EncryptHelp P((void)); 198246808Sdab 198346808Sdab struct encryptlist EncryptList[] = { 198446808Sdab { "enable", "Enable encryption. ('encrypt enable ?' for more)", 198546808Sdab EncryptEnable, 1, 1, 2 }, 198647609Sdab { "disable", "Disable encryption. ('encrypt enable ?' for more)", 198747609Sdab EncryptDisable, 0, 1, 2 }, 198846808Sdab { "type", "Set encryptiong type. ('encrypt type ?' for more)", 198946808Sdab EncryptType, 0, 1, 1 }, 199046808Sdab { "start", "Start encryption. ('encrypt start ?' for more)", 199146808Sdab EncryptStart, 1, 0, 1 }, 199246808Sdab { "stop", "Stop encryption. ('encrypt stop ?' for more)", 199346808Sdab EncryptStop, 1, 0, 1 }, 199446808Sdab { "input", "Start encrypting the input stream", 199546808Sdab EncryptStartInput, 1, 0, 0 }, 199646808Sdab { "-input", "Stop encrypting the input stream", 199746808Sdab EncryptStopInput, 1, 0, 0 }, 199846808Sdab { "output", "Start encrypting the output stream", 199946808Sdab EncryptStartOutput, 1, 0, 0 }, 200046808Sdab { "-output", "Stop encrypting the output stream", 200146808Sdab EncryptStopOutput, 1, 0, 0 }, 200246808Sdab 200346808Sdab { "status", "Display current status of authentication information", 200446808Sdab EncryptStatus, 0, 0, 0 }, 200546808Sdab { "help", 0, EncryptHelp, 0, 0, 0 }, 200646808Sdab { "?", "Print help information", EncryptHelp, 0, 0, 0 }, 200746808Sdab { 0 }, 200846808Sdab }; 200946808Sdab 201046808Sdab static int 201146808Sdab EncryptHelp() 201236274Sminshall { 201346808Sdab struct encryptlist *c; 201446808Sdab 201546808Sdab for (c = EncryptList; c->name; c++) { 201646808Sdab if (c->help) { 201746808Sdab if (*c->help) 201846808Sdab printf("%-15s %s\n", c->name, c->help); 201946808Sdab else 202046808Sdab printf("\n"); 202136274Sminshall } 202246808Sdab } 202346808Sdab return 0; 202446808Sdab } 202536274Sminshall 202646808Sdab encrypt_cmd(argc, argv) 202746808Sdab int argc; 202846808Sdab char *argv[]; 202946808Sdab { 203046808Sdab struct encryptlist *c; 203136274Sminshall 203246808Sdab c = (struct encryptlist *) 203346808Sdab genget(argv[1], (char **) EncryptList, sizeof(struct encryptlist)); 203446808Sdab if (c == 0) { 203546808Sdab fprintf(stderr, "'%s': unknown argument ('encrypt ?' for help).\n", 203646808Sdab argv[1]); 203746808Sdab return 0; 203846808Sdab } 203946808Sdab if (Ambiguous(c)) { 204046808Sdab fprintf(stderr, "'%s': ambiguous argument ('encrypt ?' for help).\n", 204146808Sdab argv[1]); 204246808Sdab return 0; 204346808Sdab } 204446808Sdab argc -= 2; 204546808Sdab if (argc < c->minarg || argc > c->maxarg) { 204646808Sdab if (c->minarg == c->maxarg) { 204746808Sdab fprintf(stderr, "Need %s%d argument%s ", 204846808Sdab c->minarg < argc ? "only " : "", c->minarg, 204946808Sdab c->minarg == 1 ? "" : "s"); 205046808Sdab } else { 205146808Sdab fprintf(stderr, "Need %s%d-%d arguments ", 205246808Sdab c->maxarg < argc ? "only " : "", c->minarg, c->maxarg); 205346808Sdab } 205446808Sdab fprintf(stderr, "to 'encrypt %s' command. 'encrypt ?' for help.\n", 205546808Sdab c->name); 205646808Sdab return 0; 205746808Sdab } 205846808Sdab if (c->needconnect && !connected) { 205946808Sdab if (!(argc && (isprefix(argv[2], "help") || isprefix(argv[2], "?")))) { 206046808Sdab printf("?Need to be connected first.\n"); 206146808Sdab return 0; 206246808Sdab } 206346808Sdab } 206446808Sdab return ((*c->handler)(argc > 0 ? argv[2] : 0, 206546808Sdab argc > 1 ? argv[3] : 0, 206646808Sdab argc > 2 ? argv[4] : 0)); 206746808Sdab } 206860149Sdab #endif /* ENCRYPTION */ 206936274Sminshall 207046808Sdab #if defined(unix) && defined(TN3270) 207146808Sdab static void 207236274Sminshall filestuff(fd) 207346808Sdab int fd; 207436274Sminshall { 207536274Sminshall int res; 207636274Sminshall 207738689Sborman #ifdef F_GETOWN 207838689Sborman setconnmode(0); 207936274Sminshall res = fcntl(fd, F_GETOWN, 0); 208036274Sminshall setcommandmode(); 208136274Sminshall 208236274Sminshall if (res == -1) { 208336274Sminshall perror("fcntl"); 208436274Sminshall return; 208536274Sminshall } 208636274Sminshall printf("\tOwner is %d.\n", res); 208738689Sborman #endif 208836274Sminshall 208938689Sborman setconnmode(0); 209036274Sminshall res = fcntl(fd, F_GETFL, 0); 209136274Sminshall setcommandmode(); 209236274Sminshall 209336274Sminshall if (res == -1) { 209436274Sminshall perror("fcntl"); 209536274Sminshall return; 209636274Sminshall } 209759893Sbostic #ifdef notdef 209836274Sminshall printf("\tFlags are 0x%x: %s\n", res, decodeflags(res)); 209959893Sbostic #endif 210036274Sminshall } 210146808Sdab #endif /* defined(unix) && defined(TN3270) */ 210236274Sminshall 210336274Sminshall /* 210432144Sminshall * Print status about the connection. 210532144Sminshall */ 210646808Sdab /*ARGSUSED*/ 210746808Sdab static 210832144Sminshall status(argc, argv) 210946808Sdab int argc; 211046808Sdab char *argv[]; 211132144Sminshall { 211232144Sminshall if (connected) { 211332144Sminshall printf("Connected to %s.\n", hostname); 211436242Sminshall if ((argc < 2) || strcmp(argv[1], "notmuch")) { 211538689Sborman int mode = getconnmode(); 211638689Sborman 211738689Sborman if (my_want_state_is_will(TELOPT_LINEMODE)) { 211838689Sborman printf("Operating with LINEMODE option\n"); 211938689Sborman printf("%s line editing\n", (mode&MODE_EDIT) ? "Local" : "No"); 212038689Sborman printf("%s catching of signals\n", 212138689Sborman (mode&MODE_TRAPSIG) ? "Local" : "No"); 212238689Sborman slcstate(); 212338689Sborman #ifdef KLUDGELINEMODE 212439529Sborman } else if (kludgelinemode && my_want_state_is_dont(TELOPT_SGA)) { 212538689Sborman printf("Operating in obsolete linemode\n"); 212638689Sborman #endif 212738689Sborman } else { 212838689Sborman printf("Operating in single character mode\n"); 212938689Sborman if (localchars) 213038689Sborman printf("Catching signals locally\n"); 213132144Sminshall } 213238689Sborman printf("%s character echo\n", (mode&MODE_ECHO) ? "Local" : "Remote"); 213338689Sborman if (my_want_state_is_will(TELOPT_LFLOW)) 213438689Sborman printf("%s flow control\n", (mode&MODE_FLOW) ? "Local" : "No"); 213560149Sdab #ifdef ENCRYPTION 213646808Sdab encrypt_display(); 213760149Sdab #endif /* ENCRYPTION */ 213832144Sminshall } 213932144Sminshall } else { 214032144Sminshall printf("No connection.\n"); 214132144Sminshall } 214232144Sminshall # if !defined(TN3270) 214332144Sminshall printf("Escape character is '%s'.\n", control(escape)); 214434849Sminshall (void) fflush(stdout); 214532144Sminshall # else /* !defined(TN3270) */ 214632144Sminshall if ((!In3270) && ((argc < 2) || strcmp(argv[1], "notmuch"))) { 214732144Sminshall printf("Escape character is '%s'.\n", control(escape)); 214832144Sminshall } 214932144Sminshall # if defined(unix) 215036242Sminshall if ((argc >= 2) && !strcmp(argv[1], "everything")) { 215136242Sminshall printf("SIGIO received %d time%s.\n", 215236242Sminshall sigiocount, (sigiocount == 1)? "":"s"); 215336274Sminshall if (In3270) { 215436274Sminshall printf("Process ID %d, process group %d.\n", 215536274Sminshall getpid(), getpgrp(getpid())); 215636274Sminshall printf("Terminal input:\n"); 215736274Sminshall filestuff(tin); 215836274Sminshall printf("Terminal output:\n"); 215936274Sminshall filestuff(tout); 216036274Sminshall printf("Network socket:\n"); 216136274Sminshall filestuff(net); 216236274Sminshall } 216336242Sminshall } 216432144Sminshall if (In3270 && transcom) { 216532144Sminshall printf("Transparent mode command is '%s'.\n", transcom); 216632144Sminshall } 216732144Sminshall # endif /* defined(unix) */ 216834849Sminshall (void) fflush(stdout); 216932144Sminshall if (In3270) { 217032144Sminshall return 0; 217132144Sminshall } 217232144Sminshall # endif /* defined(TN3270) */ 217332144Sminshall return 1; 217432144Sminshall } 217532144Sminshall 217645233Sborman #ifdef SIGINFO 217745233Sborman /* 217845233Sborman * Function that gets called when SIGINFO is received. 217945233Sborman */ 218045233Sborman ayt_status() 218145233Sborman { 218245233Sborman (void) call(status, "status", "notmuch", 0); 218345233Sborman } 218445233Sborman #endif 218532144Sminshall 218658972Sdab unsigned long inet_addr(); 218758972Sdab 218846808Sdab int 218932144Sminshall tn(argc, argv) 219046808Sdab int argc; 219146808Sdab char *argv[]; 219232144Sminshall { 219332144Sminshall register struct hostent *host = 0; 219432144Sminshall struct sockaddr_in sin; 219532144Sminshall struct servent *sp = 0; 219658972Sdab unsigned long temp; 219737219Sminshall extern char *inet_ntoa(); 219846808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 219938689Sborman char *srp = 0, *strrchr(); 220038689Sborman unsigned long sourceroute(), srlen; 220138689Sborman #endif 220244361Sborman char *cmd, *hostp = 0, *portp = 0, *user = 0; 220332144Sminshall 220445233Sborman /* clear the socket address prior to use */ 220545233Sborman bzero((char *)&sin, sizeof(sin)); 220632144Sminshall 220732144Sminshall if (connected) { 220832144Sminshall printf("?Already connected to %s\n", hostname); 220946808Sdab setuid(getuid()); 221032144Sminshall return 0; 221132144Sminshall } 221232144Sminshall if (argc < 2) { 221346808Sdab (void) strcpy(line, "open "); 221432144Sminshall printf("(to) "); 221546808Sdab (void) fgets(&line[strlen(line)], sizeof(line) - strlen(line), stdin); 221632144Sminshall makeargv(); 221732144Sminshall argc = margc; 221832144Sminshall argv = margv; 221932144Sminshall } 222044361Sborman cmd = *argv; 222144361Sborman --argc; ++argv; 222244361Sborman while (argc) { 222346808Sdab if (isprefix(*argv, "help") || isprefix(*argv, "?")) 222446808Sdab goto usage; 222544361Sborman if (strcmp(*argv, "-l") == 0) { 222644361Sborman --argc; ++argv; 222744361Sborman if (argc == 0) 222844361Sborman goto usage; 222944361Sborman user = *argv++; 223044361Sborman --argc; 223144361Sborman continue; 223244361Sborman } 223345233Sborman if (strcmp(*argv, "-a") == 0) { 223445233Sborman --argc; ++argv; 223545233Sborman autologin = 1; 223645233Sborman continue; 223745233Sborman } 223844361Sborman if (hostp == 0) { 223944361Sborman hostp = *argv++; 224044361Sborman --argc; 224144361Sborman continue; 224244361Sborman } 224344361Sborman if (portp == 0) { 224444361Sborman portp = *argv++; 224544361Sborman --argc; 224644361Sborman continue; 224744361Sborman } 224844361Sborman usage: 224945233Sborman printf("usage: %s [-l user] [-a] host-name [port]\n", cmd); 225046808Sdab setuid(getuid()); 225132144Sminshall return 0; 225232144Sminshall } 225346808Sdab if (hostp == 0) 225446808Sdab goto usage; 225546808Sdab 225646808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 225744361Sborman if (hostp[0] == '@' || hostp[0] == '!') { 225844361Sborman if ((hostname = strrchr(hostp, ':')) == NULL) 225944361Sborman hostname = strrchr(hostp, '@'); 226038689Sborman hostname++; 226138689Sborman srp = 0; 226244361Sborman temp = sourceroute(hostp, &srp, &srlen); 226338689Sborman if (temp == 0) { 226438689Sborman herror(srp); 226546808Sdab setuid(getuid()); 226638689Sborman return 0; 226738689Sborman } else if (temp == -1) { 226844361Sborman printf("Bad source route option: %s\n", hostp); 226946808Sdab setuid(getuid()); 227038689Sborman return 0; 227138689Sborman } else { 227238689Sborman sin.sin_addr.s_addr = temp; 227338689Sborman sin.sin_family = AF_INET; 227438689Sborman } 227532144Sminshall } else { 227638689Sborman #endif 227744361Sborman temp = inet_addr(hostp); 227838689Sborman if (temp != (unsigned long) -1) { 227938689Sborman sin.sin_addr.s_addr = temp; 228038689Sborman sin.sin_family = AF_INET; 228146808Sdab (void) strcpy(_hostname, hostp); 228246808Sdab hostname = _hostname; 228338689Sborman } else { 228444361Sborman host = gethostbyname(hostp); 228538689Sborman if (host) { 228638689Sborman sin.sin_family = host->h_addrtype; 228732144Sminshall #if defined(h_addr) /* In 4.3, this is a #define */ 228838689Sborman memcpy((caddr_t)&sin.sin_addr, 228932144Sminshall host->h_addr_list[0], host->h_length); 229032144Sminshall #else /* defined(h_addr) */ 229138689Sborman memcpy((caddr_t)&sin.sin_addr, host->h_addr, host->h_length); 229232144Sminshall #endif /* defined(h_addr) */ 229346808Sdab strncpy(_hostname, host->h_name, sizeof(_hostname)); 229446808Sdab _hostname[sizeof(_hostname)-1] = '\0'; 229546808Sdab hostname = _hostname; 229638689Sborman } else { 229744361Sborman herror(hostp); 229846808Sdab setuid(getuid()); 229938689Sborman return 0; 230038689Sborman } 230132144Sminshall } 230246808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 230332144Sminshall } 230438689Sborman #endif 230544361Sborman if (portp) { 230644361Sborman if (*portp == '-') { 230744361Sborman portp++; 230838689Sborman telnetport = 1; 230938689Sborman } else 231038689Sborman telnetport = 0; 231144361Sborman sin.sin_port = atoi(portp); 231232144Sminshall if (sin.sin_port == 0) { 231344361Sborman sp = getservbyname(portp, "tcp"); 231432144Sminshall if (sp) 231532144Sminshall sin.sin_port = sp->s_port; 231632144Sminshall else { 231744361Sborman printf("%s: bad port number\n", portp); 231846808Sdab setuid(getuid()); 231932144Sminshall return 0; 232032144Sminshall } 232132144Sminshall } else { 232257213Sdab #if !defined(htons) 232360890Sdab u_short htons P((unsigned short)); 232457213Sdab #endif /* !defined(htons) */ 232532144Sminshall sin.sin_port = htons(sin.sin_port); 232632144Sminshall } 232732144Sminshall } else { 232832144Sminshall if (sp == 0) { 232932144Sminshall sp = getservbyname("telnet", "tcp"); 233032144Sminshall if (sp == 0) { 233134849Sminshall fprintf(stderr, "telnet: tcp/telnet: unknown service\n"); 233246808Sdab setuid(getuid()); 233332144Sminshall return 0; 233432144Sminshall } 233532144Sminshall sin.sin_port = sp->s_port; 233632144Sminshall } 233732144Sminshall telnetport = 1; 233832144Sminshall } 233937219Sminshall printf("Trying %s...\n", inet_ntoa(sin.sin_addr)); 234032144Sminshall do { 234132144Sminshall net = socket(AF_INET, SOCK_STREAM, 0); 234246808Sdab setuid(getuid()); 234332144Sminshall if (net < 0) { 234432144Sminshall perror("telnet: socket"); 234532144Sminshall return 0; 234632144Sminshall } 234746808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 234838689Sborman if (srp && setsockopt(net, IPPROTO_IP, IP_OPTIONS, (char *)srp, srlen) < 0) 234938689Sborman perror("setsockopt (IP_OPTIONS)"); 235038689Sborman #endif 235146808Sdab #if defined(IPPROTO_IP) && defined(IP_TOS) 235246808Sdab { 235346808Sdab # if defined(HAS_GETTOS) 235446808Sdab struct tosent *tp; 235546815Sdab if (tos < 0 && (tp = gettosbyname("telnet", "tcp"))) 235646808Sdab tos = tp->t_tos; 235746808Sdab # endif 235846815Sdab if (tos < 0) 235946815Sdab tos = 020; /* Low Delay bit */ 236046815Sdab if (tos 236157213Sdab && (setsockopt(net, IPPROTO_IP, IP_TOS, 236257213Sdab (char *)&tos, sizeof(int)) < 0) 236346815Sdab && (errno != ENOPROTOOPT)) 236446815Sdab perror("telnet: setsockopt (IP_TOS) (ignored)"); 236546808Sdab } 236646808Sdab #endif /* defined(IPPROTO_IP) && defined(IP_TOS) */ 236740245Sborman 236832144Sminshall if (debug && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 1) < 0) { 236932144Sminshall perror("setsockopt (SO_DEBUG)"); 237032144Sminshall } 237132144Sminshall 237232144Sminshall if (connect(net, (struct sockaddr *)&sin, sizeof (sin)) < 0) { 237332144Sminshall #if defined(h_addr) /* In 4.3, this is a #define */ 237432144Sminshall if (host && host->h_addr_list[1]) { 237532144Sminshall int oerrno = errno; 237632144Sminshall 237732144Sminshall fprintf(stderr, "telnet: connect to address %s: ", 237832144Sminshall inet_ntoa(sin.sin_addr)); 237932144Sminshall errno = oerrno; 238032144Sminshall perror((char *)0); 238132144Sminshall host->h_addr_list++; 238232144Sminshall memcpy((caddr_t)&sin.sin_addr, 238332144Sminshall host->h_addr_list[0], host->h_length); 238432144Sminshall (void) NetClose(net); 238532144Sminshall continue; 238632144Sminshall } 238732144Sminshall #endif /* defined(h_addr) */ 238832144Sminshall perror("telnet: Unable to connect to remote host"); 238932144Sminshall return 0; 239037219Sminshall } 239132144Sminshall connected++; 239257213Sdab #if defined(AUTHENTICATION) || defined(ENCRYPTION) 239346808Sdab auth_encrypt_connect(connected); 239460149Sdab #endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */ 239532144Sminshall } while (connected == 0); 239644361Sborman cmdrc(hostp, hostname); 239745008Skarels if (autologin && user == NULL) { 239845008Skarels struct passwd *pw; 239945008Skarels 240045233Sborman user = getenv("USER"); 240145008Skarels if (user == NULL || 240245233Sborman (pw = getpwnam(user)) && pw->pw_uid != getuid()) { 240345233Sborman if (pw = getpwuid(getuid())) 240445008Skarels user = pw->pw_name; 240545008Skarels else 240645008Skarels user = NULL; 240745233Sborman } 240845008Skarels } 240945008Skarels if (user) { 241046808Sdab env_define((unsigned char *)"USER", (unsigned char *)user); 241146808Sdab env_export((unsigned char *)"USER"); 241245008Skarels } 241334849Sminshall (void) call(status, "status", "notmuch", 0); 241432144Sminshall if (setjmp(peerdied) == 0) 241546808Sdab telnet(user); 241634849Sminshall (void) NetClose(net); 241732381Sminshall ExitString("Connection closed by foreign host.\n",1); 241832144Sminshall /*NOTREACHED*/ 241932144Sminshall } 242032144Sminshall 242132144Sminshall #define HELPINDENT (sizeof ("connect")) 242232144Sminshall 242332144Sminshall static char 242432144Sminshall openhelp[] = "connect to a site", 242532144Sminshall closehelp[] = "close current connection", 242646808Sdab logouthelp[] = "forcibly logout remote user and close the connection", 242732144Sminshall quithelp[] = "exit telnet", 242832144Sminshall statushelp[] = "print status information", 242932144Sminshall helphelp[] = "print help information", 243032144Sminshall sendhelp[] = "transmit special characters ('send ?' for more)", 243132144Sminshall sethelp[] = "set operating parameters ('set ?' for more)", 243238689Sborman unsethelp[] = "unset operating parameters ('unset ?' for more)", 243332144Sminshall togglestring[] ="toggle operating parameters ('toggle ?' for more)", 243438689Sborman slchelp[] = "change state of special charaters ('slc ?' for more)", 243532144Sminshall displayhelp[] = "display operating parameters", 243632144Sminshall #if defined(TN3270) && defined(unix) 243732144Sminshall transcomhelp[] = "specify Unix command for transparent mode pipe", 243832144Sminshall #endif /* defined(TN3270) && defined(unix) */ 243957213Sdab #if defined(AUTHENTICATION) 244046808Sdab authhelp[] = "turn on (off) authentication ('auth ?' for more)", 244146808Sdab #endif 244260149Sdab #ifdef ENCRYPTION 244346808Sdab encrypthelp[] = "turn on (off) encryption ('encrypt ?' for more)", 244460149Sdab #endif /* ENCRYPTION */ 244532144Sminshall #if defined(unix) 244632144Sminshall zhelp[] = "suspend telnet", 244743317Skfall #endif /* defined(unix) */ 244832144Sminshall shellhelp[] = "invoke a subshell", 244944361Sborman envhelp[] = "change environment variables ('environ ?' for more)", 245044361Sborman modestring[] = "try to enter line or character mode ('mode ?' for more)"; 245132144Sminshall 245256642Sralph static int help(); 245332144Sminshall 245432144Sminshall static Command cmdtab[] = { 245538689Sborman { "close", closehelp, bye, 1 }, 245646808Sdab { "logout", logouthelp, logout, 1 }, 245738689Sborman { "display", displayhelp, display, 0 }, 245838689Sborman { "mode", modestring, modecmd, 0 }, 245938689Sborman { "open", openhelp, tn, 0 }, 246038689Sborman { "quit", quithelp, quit, 0 }, 246138689Sborman { "send", sendhelp, sendcmd, 0 }, 246238689Sborman { "set", sethelp, setcmd, 0 }, 246338689Sborman { "unset", unsethelp, unsetcmd, 0 }, 246438689Sborman { "status", statushelp, status, 0 }, 246538689Sborman { "toggle", togglestring, toggle, 0 }, 246638689Sborman { "slc", slchelp, slccmd, 0 }, 246732144Sminshall #if defined(TN3270) && defined(unix) 246838689Sborman { "transcom", transcomhelp, settranscom, 0 }, 246932144Sminshall #endif /* defined(TN3270) && defined(unix) */ 247057213Sdab #if defined(AUTHENTICATION) 247146808Sdab { "auth", authhelp, auth_cmd, 0 }, 247246808Sdab #endif 247360149Sdab #ifdef ENCRYPTION 247446808Sdab { "encrypt", encrypthelp, encrypt_cmd, 0 }, 247560149Sdab #endif /* ENCRYPTION */ 247632144Sminshall #if defined(unix) 247738689Sborman { "z", zhelp, suspend, 0 }, 247832144Sminshall #endif /* defined(unix) */ 247932144Sminshall #if defined(TN3270) 248038689Sborman { "!", shellhelp, shell, 1 }, 248138689Sborman #else 248238689Sborman { "!", shellhelp, shell, 0 }, 248338689Sborman #endif 248444361Sborman { "environ", envhelp, env_cmd, 0 }, 248538689Sborman { "?", helphelp, help, 0 }, 248632144Sminshall 0 248732144Sminshall }; 248832144Sminshall 248932144Sminshall static char crmodhelp[] = "deprecated command -- use 'toggle crmod' instead"; 249032144Sminshall static char escapehelp[] = "deprecated command -- use 'set escape' instead"; 249132144Sminshall 249232144Sminshall static Command cmdtab2[] = { 249338689Sborman { "help", 0, help, 0 }, 249438689Sborman { "escape", escapehelp, setescape, 0 }, 249538689Sborman { "crmod", crmodhelp, togcrmod, 0 }, 249632144Sminshall 0 249732144Sminshall }; 249832144Sminshall 249935298Sminshall 250032144Sminshall /* 250132144Sminshall * Call routine with argc, argv set from args (terminated by 0). 250232144Sminshall */ 250335298Sminshall 250446808Sdab /*VARARGS1*/ 250546808Sdab static 250635298Sminshall call(va_alist) 250746808Sdab va_dcl 250832144Sminshall { 250935298Sminshall va_list ap; 251035298Sminshall typedef int (*intrtn_t)(); 251135298Sminshall intrtn_t routine; 251235298Sminshall char *args[100]; 251335298Sminshall int argno = 0; 251435298Sminshall 251535298Sminshall va_start(ap); 251635298Sminshall routine = (va_arg(ap, intrtn_t)); 251735495Sminshall while ((args[argno++] = va_arg(ap, char *)) != 0) { 251835298Sminshall ; 251935495Sminshall } 252035298Sminshall va_end(ap); 252135495Sminshall return (*routine)(argno-1, args); 252232144Sminshall } 252332144Sminshall 252435298Sminshall 252546808Sdab static Command * 252632144Sminshall getcmd(name) 252746808Sdab char *name; 252832144Sminshall { 252932144Sminshall Command *cm; 253032144Sminshall 253146808Sdab if (cm = (Command *) genget(name, (char **) cmdtab, sizeof(Command))) 253232144Sminshall return cm; 253346808Sdab return (Command *) genget(name, (char **) cmdtab2, sizeof(Command)); 253432144Sminshall } 253532144Sminshall 253646808Sdab void 253738689Sborman command(top, tbuf, cnt) 253846808Sdab int top; 253946808Sdab char *tbuf; 254046808Sdab int cnt; 254132144Sminshall { 254232144Sminshall register Command *c; 254332144Sminshall 254432144Sminshall setcommandmode(); 254532144Sminshall if (!top) { 254632144Sminshall putchar('\n'); 254737219Sminshall #if defined(unix) 254832144Sminshall } else { 254944361Sborman (void) signal(SIGINT, SIG_DFL); 255044361Sborman (void) signal(SIGQUIT, SIG_DFL); 255132144Sminshall #endif /* defined(unix) */ 255232144Sminshall } 255332144Sminshall for (;;) { 255446808Sdab if (rlogin == _POSIX_VDISABLE) 255546808Sdab printf("%s> ", prompt); 255638689Sborman if (tbuf) { 255738689Sborman register char *cp; 255838689Sborman cp = line; 255938689Sborman while (cnt > 0 && (*cp++ = *tbuf++) != '\n') 256038689Sborman cnt--; 256138689Sborman tbuf = 0; 256238689Sborman if (cp == line || *--cp != '\n' || cp == line) 256338689Sborman goto getline; 256438689Sborman *cp = '\0'; 256546808Sdab if (rlogin == _POSIX_VDISABLE) 256646808Sdab printf("%s\n", line); 256738689Sborman } else { 256838689Sborman getline: 256946808Sdab if (rlogin != _POSIX_VDISABLE) 257046808Sdab printf("%s> ", prompt); 257146808Sdab if (fgets(line, sizeof(line), stdin) == NULL) { 257244361Sborman if (feof(stdin) || ferror(stdin)) { 257344361Sborman (void) quit(); 257444361Sborman /*NOTREACHED*/ 257544361Sborman } 257638689Sborman break; 257738689Sborman } 257832144Sminshall } 257932144Sminshall if (line[0] == 0) 258032144Sminshall break; 258132144Sminshall makeargv(); 258237219Sminshall if (margv[0] == 0) { 258337219Sminshall break; 258437219Sminshall } 258532144Sminshall c = getcmd(margv[0]); 258632144Sminshall if (Ambiguous(c)) { 258732144Sminshall printf("?Ambiguous command\n"); 258832144Sminshall continue; 258932144Sminshall } 259032144Sminshall if (c == 0) { 259132144Sminshall printf("?Invalid command\n"); 259232144Sminshall continue; 259332144Sminshall } 259432144Sminshall if (c->needconnect && !connected) { 259532144Sminshall printf("?Need to be connected first.\n"); 259632144Sminshall continue; 259732144Sminshall } 259832144Sminshall if ((*c->handler)(margc, margv)) { 259932144Sminshall break; 260032144Sminshall } 260132144Sminshall } 260232144Sminshall if (!top) { 260332144Sminshall if (!connected) { 260432144Sminshall longjmp(toplevel, 1); 260532144Sminshall /*NOTREACHED*/ 260632144Sminshall } 260732144Sminshall #if defined(TN3270) 260832144Sminshall if (shell_active == 0) { 260938689Sborman setconnmode(0); 261032144Sminshall } 261132144Sminshall #else /* defined(TN3270) */ 261238689Sborman setconnmode(0); 261332144Sminshall #endif /* defined(TN3270) */ 261432144Sminshall } 261532144Sminshall } 261632144Sminshall 261732144Sminshall /* 261832144Sminshall * Help command. 261932144Sminshall */ 262046808Sdab static 262132144Sminshall help(argc, argv) 262232144Sminshall int argc; 262332144Sminshall char *argv[]; 262432144Sminshall { 262532144Sminshall register Command *c; 262632144Sminshall 262732144Sminshall if (argc == 1) { 262832144Sminshall printf("Commands may be abbreviated. Commands are:\n\n"); 262932144Sminshall for (c = cmdtab; c->name; c++) 263038689Sborman if (c->help) { 263132144Sminshall printf("%-*s\t%s\n", HELPINDENT, c->name, 263232144Sminshall c->help); 263332144Sminshall } 263432144Sminshall return 0; 263532144Sminshall } 263632144Sminshall while (--argc > 0) { 263732144Sminshall register char *arg; 263832144Sminshall arg = *++argv; 263932144Sminshall c = getcmd(arg); 264032144Sminshall if (Ambiguous(c)) 264132144Sminshall printf("?Ambiguous help command %s\n", arg); 264232144Sminshall else if (c == (Command *)0) 264332144Sminshall printf("?Invalid help command %s\n", arg); 264432144Sminshall else 264532144Sminshall printf("%s\n", c->help); 264632144Sminshall } 264732144Sminshall return 0; 264832144Sminshall } 264938689Sborman 265038689Sborman static char *rcname = 0; 265138689Sborman static char rcbuf[128]; 265238689Sborman 265338689Sborman cmdrc(m1, m2) 265438689Sborman char *m1, *m2; 265538689Sborman { 265638689Sborman register Command *c; 265738689Sborman FILE *rcfile; 265838689Sborman int gotmachine = 0; 265938689Sborman int l1 = strlen(m1); 266038689Sborman int l2 = strlen(m2); 266138689Sborman char m1save[64]; 266238689Sborman 266347609Sdab if (skiprc) 266447609Sdab return; 266547609Sdab 266638689Sborman strcpy(m1save, m1); 266738689Sborman m1 = m1save; 266838689Sborman 266938689Sborman if (rcname == 0) { 267038689Sborman rcname = getenv("HOME"); 267138689Sborman if (rcname) 267238689Sborman strcpy(rcbuf, rcname); 267338689Sborman else 267438689Sborman rcbuf[0] = '\0'; 267538689Sborman strcat(rcbuf, "/.telnetrc"); 267638689Sborman rcname = rcbuf; 267738689Sborman } 267838689Sborman 267938689Sborman if ((rcfile = fopen(rcname, "r")) == 0) { 268038689Sborman return; 268138689Sborman } 268238689Sborman 268338689Sborman for (;;) { 268438689Sborman if (fgets(line, sizeof(line), rcfile) == NULL) 268538689Sborman break; 268638689Sborman if (line[0] == 0) 268738689Sborman break; 268838689Sborman if (line[0] == '#') 268938689Sborman continue; 269047609Sdab if (gotmachine) { 269147609Sdab if (!isspace(line[0])) 269247609Sdab gotmachine = 0; 269347609Sdab } 269438689Sborman if (gotmachine == 0) { 269538689Sborman if (isspace(line[0])) 269638689Sborman continue; 269738689Sborman if (strncasecmp(line, m1, l1) == 0) 269838689Sborman strncpy(line, &line[l1], sizeof(line) - l1); 269938689Sborman else if (strncasecmp(line, m2, l2) == 0) 270038689Sborman strncpy(line, &line[l2], sizeof(line) - l2); 270147609Sdab else if (strncasecmp(line, "DEFAULT", 7) == 0) 270247609Sdab strncpy(line, &line[7], sizeof(line) - 7); 270338689Sborman else 270438689Sborman continue; 270547609Sdab if (line[0] != ' ' && line[0] != '\t' && line[0] != '\n') 270647609Sdab continue; 270738689Sborman gotmachine = 1; 270838689Sborman } 270938689Sborman makeargv(); 271038689Sborman if (margv[0] == 0) 271138689Sborman continue; 271238689Sborman c = getcmd(margv[0]); 271338689Sborman if (Ambiguous(c)) { 271438689Sborman printf("?Ambiguous command: %s\n", margv[0]); 271538689Sborman continue; 271638689Sborman } 271738689Sborman if (c == 0) { 271838689Sborman printf("?Invalid command: %s\n", margv[0]); 271938689Sborman continue; 272038689Sborman } 272138689Sborman /* 272238689Sborman * This should never happen... 272338689Sborman */ 272438689Sborman if (c->needconnect && !connected) { 272538689Sborman printf("?Need to be connected first for %s.\n", margv[0]); 272638689Sborman continue; 272738689Sborman } 272838689Sborman (*c->handler)(margc, margv); 272938689Sborman } 273038689Sborman fclose(rcfile); 273138689Sborman } 273238689Sborman 273346808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 273438689Sborman 273538689Sborman /* 273638689Sborman * Source route is handed in as 273738689Sborman * [!]@hop1@hop2...[@|:]dst 273838689Sborman * If the leading ! is present, it is a 273938689Sborman * strict source route, otherwise it is 274038689Sborman * assmed to be a loose source route. 274138689Sborman * 274238689Sborman * We fill in the source route option as 274338689Sborman * hop1,hop2,hop3...dest 274438689Sborman * and return a pointer to hop1, which will 274538689Sborman * be the address to connect() to. 274638689Sborman * 274738689Sborman * Arguments: 274838689Sborman * arg: pointer to route list to decipher 274938689Sborman * 275038689Sborman * cpp: If *cpp is not equal to NULL, this is a 275138689Sborman * pointer to a pointer to a character array 275238689Sborman * that should be filled in with the option. 275338689Sborman * 275438689Sborman * lenp: pointer to an integer that contains the 275538689Sborman * length of *cpp if *cpp != NULL. 275638689Sborman * 275738689Sborman * Return values: 275838689Sborman * 275938689Sborman * Returns the address of the host to connect to. If the 276038689Sborman * return value is -1, there was a syntax error in the 276138689Sborman * option, either unknown characters, or too many hosts. 276238689Sborman * If the return value is 0, one of the hostnames in the 276338689Sborman * path is unknown, and *cpp is set to point to the bad 276438689Sborman * hostname. 276538689Sborman * 276638689Sborman * *cpp: If *cpp was equal to NULL, it will be filled 276738689Sborman * in with a pointer to our static area that has 276838689Sborman * the option filled in. This will be 32bit aligned. 276938689Sborman * 277038689Sborman * *lenp: This will be filled in with how long the option 277138689Sborman * pointed to by *cpp is. 277238689Sborman * 277338689Sborman */ 277446808Sdab unsigned long 277538689Sborman sourceroute(arg, cpp, lenp) 277646808Sdab char *arg; 277746808Sdab char **cpp; 277846808Sdab int *lenp; 277938689Sborman { 278038689Sborman static char lsr[44]; 278157213Sdab #ifdef sysV88 278257213Sdab static IOPTN ipopt; 278357213Sdab #endif 278446808Sdab char *cp, *cp2, *lsrp, *lsrep; 278538689Sborman register int tmp; 278638689Sborman struct in_addr sin_addr; 278738689Sborman register struct hostent *host = 0; 278838689Sborman register char c; 278938689Sborman 279038689Sborman /* 279138689Sborman * Verify the arguments, and make sure we have 279238689Sborman * at least 7 bytes for the option. 279338689Sborman */ 279438689Sborman if (cpp == NULL || lenp == NULL) 279538689Sborman return((unsigned long)-1); 279638689Sborman if (*cpp != NULL && *lenp < 7) 279738689Sborman return((unsigned long)-1); 279838689Sborman /* 279938689Sborman * Decide whether we have a buffer passed to us, 280038689Sborman * or if we need to use our own static buffer. 280138689Sborman */ 280238689Sborman if (*cpp) { 280338689Sborman lsrp = *cpp; 280438689Sborman lsrep = lsrp + *lenp; 280538689Sborman } else { 280638689Sborman *cpp = lsrp = lsr; 280738689Sborman lsrep = lsrp + 44; 280838689Sborman } 280938689Sborman 281038689Sborman cp = arg; 281138689Sborman 281238689Sborman /* 281338689Sborman * Next, decide whether we have a loose source 281438689Sborman * route or a strict source route, and fill in 281538689Sborman * the begining of the option. 281638689Sborman */ 281757213Sdab #ifndef sysV88 281838689Sborman if (*cp == '!') { 281938689Sborman cp++; 282038689Sborman *lsrp++ = IPOPT_SSRR; 282138689Sborman } else 282238689Sborman *lsrp++ = IPOPT_LSRR; 282357213Sdab #else 282457213Sdab if (*cp == '!') { 282557213Sdab cp++; 282657213Sdab ipopt.io_type = IPOPT_SSRR; 282757213Sdab } else 282857213Sdab ipopt.io_type = IPOPT_LSRR; 282957213Sdab #endif 283038689Sborman 283138689Sborman if (*cp != '@') 283238689Sborman return((unsigned long)-1); 283338689Sborman 283457213Sdab #ifndef sysV88 283538689Sborman lsrp++; /* skip over length, we'll fill it in later */ 283638689Sborman *lsrp++ = 4; 283757213Sdab #endif 283838689Sborman 283938689Sborman cp++; 284038689Sborman 284138689Sborman sin_addr.s_addr = 0; 284238689Sborman 284338689Sborman for (c = 0;;) { 284438689Sborman if (c == ':') 284538689Sborman cp2 = 0; 284638689Sborman else for (cp2 = cp; c = *cp2; cp2++) { 284738689Sborman if (c == ',') { 284838689Sborman *cp2++ = '\0'; 284938689Sborman if (*cp2 == '@') 285038689Sborman cp2++; 285138689Sborman } else if (c == '@') { 285238689Sborman *cp2++ = '\0'; 285338689Sborman } else if (c == ':') { 285438689Sborman *cp2++ = '\0'; 285538689Sborman } else 285638689Sborman continue; 285738689Sborman break; 285838689Sborman } 285938689Sborman if (!c) 286038689Sborman cp2 = 0; 286138689Sborman 286238689Sborman if ((tmp = inet_addr(cp)) != -1) { 286338689Sborman sin_addr.s_addr = tmp; 286438689Sborman } else if (host = gethostbyname(cp)) { 286538689Sborman #if defined(h_addr) 286638689Sborman memcpy((caddr_t)&sin_addr, 286738689Sborman host->h_addr_list[0], host->h_length); 286838689Sborman #else 286938689Sborman memcpy((caddr_t)&sin_addr, host->h_addr, host->h_length); 287038689Sborman #endif 287138689Sborman } else { 287238689Sborman *cpp = cp; 287338689Sborman return(0); 287438689Sborman } 287538689Sborman memcpy(lsrp, (char *)&sin_addr, 4); 287638689Sborman lsrp += 4; 287738689Sborman if (cp2) 287838689Sborman cp = cp2; 287938689Sborman else 288038689Sborman break; 288138689Sborman /* 288238689Sborman * Check to make sure there is space for next address 288338689Sborman */ 288438689Sborman if (lsrp + 4 > lsrep) 288538689Sborman return((unsigned long)-1); 288638689Sborman } 288757213Sdab #ifndef sysV88 288838689Sborman if ((*(*cpp+IPOPT_OLEN) = lsrp - *cpp) <= 7) { 288938689Sborman *cpp = 0; 289038689Sborman *lenp = 0; 289138689Sborman return((unsigned long)-1); 289238689Sborman } 289338689Sborman *lsrp++ = IPOPT_NOP; /* 32 bit word align it */ 289438689Sborman *lenp = lsrp - *cpp; 289557213Sdab #else 289657213Sdab ipopt.io_len = lsrp - *cpp; 289757213Sdab if (ipopt.io_len <= 5) { /* Is 3 better ? */ 289857213Sdab *cpp = 0; 289957213Sdab *lenp = 0; 290057213Sdab return((unsigned long)-1); 290157213Sdab } 290257213Sdab *lenp = sizeof(ipopt); 290357213Sdab *cpp = (char *) &ipopt; 290457213Sdab #endif 290538689Sborman return(sin_addr.s_addr); 290638689Sborman } 290738689Sborman #endif 2908