133685Sbostic /* 245233Sborman * Copyright (c) 1988, 1990 Regents of the University of California. 333685Sbostic * All rights reserved. 433685Sbostic * 542770Sbostic * %sccs.include.redist.c% 633685Sbostic */ 733685Sbostic 833685Sbostic #ifndef lint 9*60149Sdab static char sccsid[] = "@(#)commands.c 5.12 (Berkeley) 05/20/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 596*60149Sdab #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)); 601*60149Sdab #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 634*60149Sdab #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" }, 655*60149Sdab #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(); 1273*60149Sdab #ifdef ENCRYPTION 127446808Sdab EncryptStatus(); 1275*60149Sdab #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); 1427*60149Sdab #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 *)), 155358972Sdab #ifdef 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 }, 157258972Sdab #ifdef 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 177945233Sborman if (my_state_is_wont(TELOPT_ENVIRON)) { 178045233Sborman fprintf(stderr, 178145233Sborman "Cannot send '%s': Telnet ENVIRON option not enabled\n", 178245233Sborman var); 178345233Sborman return; 178445233Sborman } 178545233Sborman ep = env_find(var); 178645233Sborman if (ep == 0) { 178745233Sborman fprintf(stderr, "Cannot send '%s': variable not defined\n", 178845233Sborman var); 178945233Sborman return; 179045233Sborman } 179145233Sborman env_opt_start_info(); 179245233Sborman env_opt_add(ep->var); 179345233Sborman env_opt_end(0); 179445233Sborman } 179545233Sborman 179646808Sdab void 179744361Sborman env_list() 179844361Sborman { 179944361Sborman register struct env_lst *ep; 180044361Sborman 180144361Sborman for (ep = envlisthead.next; ep; ep = ep->next) { 180244361Sborman printf("%c %-20s %s\n", ep->export ? '*' : ' ', 180344361Sborman ep->var, ep->value); 180444361Sborman } 180544361Sborman } 180644361Sborman 180746808Sdab unsigned char * 180857213Sdab env_default(init, welldefined) 180946808Sdab int init; 181044361Sborman { 181144361Sborman static struct env_lst *nep = NULL; 181244361Sborman 181344361Sborman if (init) { 181444361Sborman nep = &envlisthead; 181544361Sborman return; 181644361Sborman } 181744361Sborman if (nep) { 181844361Sborman while (nep = nep->next) { 181957213Sdab if (nep->export && (nep->welldefined == welldefined)) 182044361Sborman return(nep->var); 182144361Sborman } 182244361Sborman } 182344361Sborman return(NULL); 182444361Sborman } 182544361Sborman 182646808Sdab unsigned char * 182744361Sborman env_getvalue(var) 182846808Sdab unsigned char *var; 182944361Sborman { 183044361Sborman register struct env_lst *ep; 183144361Sborman 183244361Sborman if (ep = env_find(var)) 183344361Sborman return(ep->value); 183444361Sborman return(NULL); 183544361Sborman } 183644361Sborman 183758972Sdab #ifdef ENV_HACK 183858972Sdab void 183958972Sdab env_varval(what) 184058972Sdab unsigned char *what; 184158972Sdab { 184258972Sdab extern int env_var, env_value, env_auto; 184358972Sdab int len = strlen(what); 184458972Sdab 184558972Sdab if (len == 0) 184658972Sdab goto unknown; 184758972Sdab 184858972Sdab if (strncasecmp(what, "status", len) == 0) { 184958972Sdab if (env_auto) 185058972Sdab printf("%s%s", "VAR and VALUE are/will be ", 185158972Sdab "determined automatically\n"); 185258972Sdab if (env_var == ENV_VAR) 185358972Sdab printf("VAR and VALUE set to correct definitions\n"); 185458972Sdab else 185558972Sdab printf("VAR and VALUE definitions are reversed\n"); 185658972Sdab } else if (strncasecmp(what, "auto", len) == 0) { 185758972Sdab env_auto = 1; 185858972Sdab env_var = ENV_VALUE; 185958972Sdab env_value = ENV_VAR; 186058972Sdab } else if (strncasecmp(what, "right", len) == 0) { 186158972Sdab env_auto = 0; 186258972Sdab env_var = ENV_VAR; 186358972Sdab env_value = ENV_VALUE; 186458972Sdab } else if (strncasecmp(what, "wrong", len) == 0) { 186558972Sdab env_auto = 0; 186658972Sdab env_var = ENV_VALUE; 186758972Sdab env_value = ENV_VAR; 186858972Sdab } else { 186958972Sdab unknown: 187058972Sdab printf("Unknown \"varval\" command. (\"auto\", \"right\", \"wrong\", \"status\")\n"); 187158972Sdab } 187258972Sdab } 187358972Sdab #endif 187458972Sdab 187557213Sdab #if defined(AUTHENTICATION) 187646808Sdab /* 187746808Sdab * The AUTHENTICATE command. 187846808Sdab */ 187946808Sdab 188046808Sdab struct authlist { 188146808Sdab char *name; 188246808Sdab char *help; 188346808Sdab int (*handler)(); 188446808Sdab int narg; 188546808Sdab }; 188646808Sdab 188746808Sdab extern int 188846808Sdab auth_enable P((int)), 188946808Sdab auth_disable P((int)), 189056642Sralph auth_status P((void)); 189156642Sralph static int 189246808Sdab auth_help P((void)); 189346808Sdab 189446808Sdab struct authlist AuthList[] = { 189546808Sdab { "status", "Display current status of authentication information", 189646808Sdab auth_status, 0 }, 189746808Sdab { "disable", "Disable an authentication type ('auth disable ?' for more)", 189846808Sdab auth_disable, 1 }, 189946808Sdab { "enable", "Enable an authentication type ('auth enable ?' for more)", 190046808Sdab auth_enable, 1 }, 190146808Sdab { "help", 0, auth_help, 0 }, 190246808Sdab { "?", "Print help information", auth_help, 0 }, 190346808Sdab { 0 }, 190446808Sdab }; 190546808Sdab 190646808Sdab static int 190746808Sdab auth_help() 190844361Sborman { 190946808Sdab struct authlist *c; 191046808Sdab 191146808Sdab for (c = AuthList; c->name; c++) { 191246808Sdab if (c->help) { 191346808Sdab if (*c->help) 191446808Sdab printf("%-15s %s\n", c->name, c->help); 191546808Sdab else 191646808Sdab printf("\n"); 191746808Sdab } 191846808Sdab } 191946808Sdab return 0; 192044361Sborman } 192146808Sdab 192246808Sdab auth_cmd(argc, argv) 192346808Sdab int argc; 192446808Sdab char *argv[]; 192546808Sdab { 192646808Sdab struct authlist *c; 192746808Sdab 192846808Sdab c = (struct authlist *) 192946808Sdab genget(argv[1], (char **) AuthList, sizeof(struct authlist)); 193046808Sdab if (c == 0) { 193146808Sdab fprintf(stderr, "'%s': unknown argument ('auth ?' for help).\n", 193246808Sdab argv[1]); 193346808Sdab return 0; 193446808Sdab } 193546808Sdab if (Ambiguous(c)) { 193646808Sdab fprintf(stderr, "'%s': ambiguous argument ('auth ?' for help).\n", 193746808Sdab argv[1]); 193846808Sdab return 0; 193946808Sdab } 194046808Sdab if (c->narg + 2 != argc) { 194146808Sdab fprintf(stderr, 194246808Sdab "Need %s%d argument%s to 'auth %s' command. 'auth ?' for help.\n", 194346808Sdab c->narg < argc + 2 ? "only " : "", 194446808Sdab c->narg, c->narg == 1 ? "" : "s", c->name); 194546808Sdab return 0; 194646808Sdab } 194746808Sdab return((*c->handler)(argv[2], argv[3])); 194846808Sdab } 194945233Sborman #endif 195044361Sborman 1951*60149Sdab #ifdef ENCRYPTION 195232144Sminshall /* 195346808Sdab * The ENCRYPT command. 195436274Sminshall */ 195536274Sminshall 195646808Sdab struct encryptlist { 195746808Sdab char *name; 195846808Sdab char *help; 195946808Sdab int (*handler)(); 196046808Sdab int needconnect; 196146808Sdab int minarg; 196246808Sdab int maxarg; 196346808Sdab }; 196446808Sdab 196546808Sdab extern int 196646808Sdab EncryptEnable P((char *, char *)), 196747609Sdab EncryptDisable P((char *, char *)), 196846808Sdab EncryptType P((char *, char *)), 196946808Sdab EncryptStart P((char *)), 197046808Sdab EncryptStartInput P((void)), 197146808Sdab EncryptStartOutput P((void)), 197246808Sdab EncryptStop P((char *)), 197346808Sdab EncryptStopInput P((void)), 197446808Sdab EncryptStopOutput P((void)), 197556642Sralph EncryptStatus P((void)); 197656642Sralph static int 197746808Sdab EncryptHelp P((void)); 197846808Sdab 197946808Sdab struct encryptlist EncryptList[] = { 198046808Sdab { "enable", "Enable encryption. ('encrypt enable ?' for more)", 198146808Sdab EncryptEnable, 1, 1, 2 }, 198247609Sdab { "disable", "Disable encryption. ('encrypt enable ?' for more)", 198347609Sdab EncryptDisable, 0, 1, 2 }, 198446808Sdab { "type", "Set encryptiong type. ('encrypt type ?' for more)", 198546808Sdab EncryptType, 0, 1, 1 }, 198646808Sdab { "start", "Start encryption. ('encrypt start ?' for more)", 198746808Sdab EncryptStart, 1, 0, 1 }, 198846808Sdab { "stop", "Stop encryption. ('encrypt stop ?' for more)", 198946808Sdab EncryptStop, 1, 0, 1 }, 199046808Sdab { "input", "Start encrypting the input stream", 199146808Sdab EncryptStartInput, 1, 0, 0 }, 199246808Sdab { "-input", "Stop encrypting the input stream", 199346808Sdab EncryptStopInput, 1, 0, 0 }, 199446808Sdab { "output", "Start encrypting the output stream", 199546808Sdab EncryptStartOutput, 1, 0, 0 }, 199646808Sdab { "-output", "Stop encrypting the output stream", 199746808Sdab EncryptStopOutput, 1, 0, 0 }, 199846808Sdab 199946808Sdab { "status", "Display current status of authentication information", 200046808Sdab EncryptStatus, 0, 0, 0 }, 200146808Sdab { "help", 0, EncryptHelp, 0, 0, 0 }, 200246808Sdab { "?", "Print help information", EncryptHelp, 0, 0, 0 }, 200346808Sdab { 0 }, 200446808Sdab }; 200546808Sdab 200646808Sdab static int 200746808Sdab EncryptHelp() 200836274Sminshall { 200946808Sdab struct encryptlist *c; 201046808Sdab 201146808Sdab for (c = EncryptList; c->name; c++) { 201246808Sdab if (c->help) { 201346808Sdab if (*c->help) 201446808Sdab printf("%-15s %s\n", c->name, c->help); 201546808Sdab else 201646808Sdab printf("\n"); 201736274Sminshall } 201846808Sdab } 201946808Sdab return 0; 202046808Sdab } 202136274Sminshall 202246808Sdab encrypt_cmd(argc, argv) 202346808Sdab int argc; 202446808Sdab char *argv[]; 202546808Sdab { 202646808Sdab struct encryptlist *c; 202736274Sminshall 202846808Sdab c = (struct encryptlist *) 202946808Sdab genget(argv[1], (char **) EncryptList, sizeof(struct encryptlist)); 203046808Sdab if (c == 0) { 203146808Sdab fprintf(stderr, "'%s': unknown argument ('encrypt ?' for help).\n", 203246808Sdab argv[1]); 203346808Sdab return 0; 203446808Sdab } 203546808Sdab if (Ambiguous(c)) { 203646808Sdab fprintf(stderr, "'%s': ambiguous argument ('encrypt ?' for help).\n", 203746808Sdab argv[1]); 203846808Sdab return 0; 203946808Sdab } 204046808Sdab argc -= 2; 204146808Sdab if (argc < c->minarg || argc > c->maxarg) { 204246808Sdab if (c->minarg == c->maxarg) { 204346808Sdab fprintf(stderr, "Need %s%d argument%s ", 204446808Sdab c->minarg < argc ? "only " : "", c->minarg, 204546808Sdab c->minarg == 1 ? "" : "s"); 204646808Sdab } else { 204746808Sdab fprintf(stderr, "Need %s%d-%d arguments ", 204846808Sdab c->maxarg < argc ? "only " : "", c->minarg, c->maxarg); 204946808Sdab } 205046808Sdab fprintf(stderr, "to 'encrypt %s' command. 'encrypt ?' for help.\n", 205146808Sdab c->name); 205246808Sdab return 0; 205346808Sdab } 205446808Sdab if (c->needconnect && !connected) { 205546808Sdab if (!(argc && (isprefix(argv[2], "help") || isprefix(argv[2], "?")))) { 205646808Sdab printf("?Need to be connected first.\n"); 205746808Sdab return 0; 205846808Sdab } 205946808Sdab } 206046808Sdab return ((*c->handler)(argc > 0 ? argv[2] : 0, 206146808Sdab argc > 1 ? argv[3] : 0, 206246808Sdab argc > 2 ? argv[4] : 0)); 206346808Sdab } 2064*60149Sdab #endif /* ENCRYPTION */ 206536274Sminshall 206646808Sdab #if defined(unix) && defined(TN3270) 206746808Sdab static void 206836274Sminshall filestuff(fd) 206946808Sdab int fd; 207036274Sminshall { 207136274Sminshall int res; 207236274Sminshall 207338689Sborman #ifdef F_GETOWN 207438689Sborman setconnmode(0); 207536274Sminshall res = fcntl(fd, F_GETOWN, 0); 207636274Sminshall setcommandmode(); 207736274Sminshall 207836274Sminshall if (res == -1) { 207936274Sminshall perror("fcntl"); 208036274Sminshall return; 208136274Sminshall } 208236274Sminshall printf("\tOwner is %d.\n", res); 208338689Sborman #endif 208436274Sminshall 208538689Sborman setconnmode(0); 208636274Sminshall res = fcntl(fd, F_GETFL, 0); 208736274Sminshall setcommandmode(); 208836274Sminshall 208936274Sminshall if (res == -1) { 209036274Sminshall perror("fcntl"); 209136274Sminshall return; 209236274Sminshall } 209359893Sbostic #ifdef notdef 209436274Sminshall printf("\tFlags are 0x%x: %s\n", res, decodeflags(res)); 209559893Sbostic #endif 209636274Sminshall } 209746808Sdab #endif /* defined(unix) && defined(TN3270) */ 209836274Sminshall 209936274Sminshall /* 210032144Sminshall * Print status about the connection. 210132144Sminshall */ 210246808Sdab /*ARGSUSED*/ 210346808Sdab static 210432144Sminshall status(argc, argv) 210546808Sdab int argc; 210646808Sdab char *argv[]; 210732144Sminshall { 210832144Sminshall if (connected) { 210932144Sminshall printf("Connected to %s.\n", hostname); 211036242Sminshall if ((argc < 2) || strcmp(argv[1], "notmuch")) { 211138689Sborman int mode = getconnmode(); 211238689Sborman 211338689Sborman if (my_want_state_is_will(TELOPT_LINEMODE)) { 211438689Sborman printf("Operating with LINEMODE option\n"); 211538689Sborman printf("%s line editing\n", (mode&MODE_EDIT) ? "Local" : "No"); 211638689Sborman printf("%s catching of signals\n", 211738689Sborman (mode&MODE_TRAPSIG) ? "Local" : "No"); 211838689Sborman slcstate(); 211938689Sborman #ifdef KLUDGELINEMODE 212039529Sborman } else if (kludgelinemode && my_want_state_is_dont(TELOPT_SGA)) { 212138689Sborman printf("Operating in obsolete linemode\n"); 212238689Sborman #endif 212338689Sborman } else { 212438689Sborman printf("Operating in single character mode\n"); 212538689Sborman if (localchars) 212638689Sborman printf("Catching signals locally\n"); 212732144Sminshall } 212838689Sborman printf("%s character echo\n", (mode&MODE_ECHO) ? "Local" : "Remote"); 212938689Sborman if (my_want_state_is_will(TELOPT_LFLOW)) 213038689Sborman printf("%s flow control\n", (mode&MODE_FLOW) ? "Local" : "No"); 2131*60149Sdab #ifdef ENCRYPTION 213246808Sdab encrypt_display(); 2133*60149Sdab #endif /* ENCRYPTION */ 213432144Sminshall } 213532144Sminshall } else { 213632144Sminshall printf("No connection.\n"); 213732144Sminshall } 213832144Sminshall # if !defined(TN3270) 213932144Sminshall printf("Escape character is '%s'.\n", control(escape)); 214034849Sminshall (void) fflush(stdout); 214132144Sminshall # else /* !defined(TN3270) */ 214232144Sminshall if ((!In3270) && ((argc < 2) || strcmp(argv[1], "notmuch"))) { 214332144Sminshall printf("Escape character is '%s'.\n", control(escape)); 214432144Sminshall } 214532144Sminshall # if defined(unix) 214636242Sminshall if ((argc >= 2) && !strcmp(argv[1], "everything")) { 214736242Sminshall printf("SIGIO received %d time%s.\n", 214836242Sminshall sigiocount, (sigiocount == 1)? "":"s"); 214936274Sminshall if (In3270) { 215036274Sminshall printf("Process ID %d, process group %d.\n", 215136274Sminshall getpid(), getpgrp(getpid())); 215236274Sminshall printf("Terminal input:\n"); 215336274Sminshall filestuff(tin); 215436274Sminshall printf("Terminal output:\n"); 215536274Sminshall filestuff(tout); 215636274Sminshall printf("Network socket:\n"); 215736274Sminshall filestuff(net); 215836274Sminshall } 215936242Sminshall } 216032144Sminshall if (In3270 && transcom) { 216132144Sminshall printf("Transparent mode command is '%s'.\n", transcom); 216232144Sminshall } 216332144Sminshall # endif /* defined(unix) */ 216434849Sminshall (void) fflush(stdout); 216532144Sminshall if (In3270) { 216632144Sminshall return 0; 216732144Sminshall } 216832144Sminshall # endif /* defined(TN3270) */ 216932144Sminshall return 1; 217032144Sminshall } 217132144Sminshall 217245233Sborman #ifdef SIGINFO 217345233Sborman /* 217445233Sborman * Function that gets called when SIGINFO is received. 217545233Sborman */ 217645233Sborman ayt_status() 217745233Sborman { 217845233Sborman (void) call(status, "status", "notmuch", 0); 217945233Sborman } 218045233Sborman #endif 218132144Sminshall 218258972Sdab unsigned long inet_addr(); 218358972Sdab 218446808Sdab int 218532144Sminshall tn(argc, argv) 218646808Sdab int argc; 218746808Sdab char *argv[]; 218832144Sminshall { 218932144Sminshall register struct hostent *host = 0; 219032144Sminshall struct sockaddr_in sin; 219132144Sminshall struct servent *sp = 0; 219258972Sdab unsigned long temp; 219337219Sminshall extern char *inet_ntoa(); 219446808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 219538689Sborman char *srp = 0, *strrchr(); 219638689Sborman unsigned long sourceroute(), srlen; 219738689Sborman #endif 219844361Sborman char *cmd, *hostp = 0, *portp = 0, *user = 0; 219932144Sminshall 220045233Sborman /* clear the socket address prior to use */ 220145233Sborman bzero((char *)&sin, sizeof(sin)); 220232144Sminshall 220332144Sminshall if (connected) { 220432144Sminshall printf("?Already connected to %s\n", hostname); 220546808Sdab setuid(getuid()); 220632144Sminshall return 0; 220732144Sminshall } 220832144Sminshall if (argc < 2) { 220946808Sdab (void) strcpy(line, "open "); 221032144Sminshall printf("(to) "); 221146808Sdab (void) fgets(&line[strlen(line)], sizeof(line) - strlen(line), stdin); 221232144Sminshall makeargv(); 221332144Sminshall argc = margc; 221432144Sminshall argv = margv; 221532144Sminshall } 221644361Sborman cmd = *argv; 221744361Sborman --argc; ++argv; 221844361Sborman while (argc) { 221946808Sdab if (isprefix(*argv, "help") || isprefix(*argv, "?")) 222046808Sdab goto usage; 222144361Sborman if (strcmp(*argv, "-l") == 0) { 222244361Sborman --argc; ++argv; 222344361Sborman if (argc == 0) 222444361Sborman goto usage; 222544361Sborman user = *argv++; 222644361Sborman --argc; 222744361Sborman continue; 222844361Sborman } 222945233Sborman if (strcmp(*argv, "-a") == 0) { 223045233Sborman --argc; ++argv; 223145233Sborman autologin = 1; 223245233Sborman continue; 223345233Sborman } 223444361Sborman if (hostp == 0) { 223544361Sborman hostp = *argv++; 223644361Sborman --argc; 223744361Sborman continue; 223844361Sborman } 223944361Sborman if (portp == 0) { 224044361Sborman portp = *argv++; 224144361Sborman --argc; 224244361Sborman continue; 224344361Sborman } 224444361Sborman usage: 224545233Sborman printf("usage: %s [-l user] [-a] host-name [port]\n", cmd); 224646808Sdab setuid(getuid()); 224732144Sminshall return 0; 224832144Sminshall } 224946808Sdab if (hostp == 0) 225046808Sdab goto usage; 225146808Sdab 225246808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 225344361Sborman if (hostp[0] == '@' || hostp[0] == '!') { 225444361Sborman if ((hostname = strrchr(hostp, ':')) == NULL) 225544361Sborman hostname = strrchr(hostp, '@'); 225638689Sborman hostname++; 225738689Sborman srp = 0; 225844361Sborman temp = sourceroute(hostp, &srp, &srlen); 225938689Sborman if (temp == 0) { 226038689Sborman herror(srp); 226146808Sdab setuid(getuid()); 226238689Sborman return 0; 226338689Sborman } else if (temp == -1) { 226444361Sborman printf("Bad source route option: %s\n", hostp); 226546808Sdab setuid(getuid()); 226638689Sborman return 0; 226738689Sborman } else { 226838689Sborman sin.sin_addr.s_addr = temp; 226938689Sborman sin.sin_family = AF_INET; 227038689Sborman } 227132144Sminshall } else { 227238689Sborman #endif 227344361Sborman temp = inet_addr(hostp); 227438689Sborman if (temp != (unsigned long) -1) { 227538689Sborman sin.sin_addr.s_addr = temp; 227638689Sborman sin.sin_family = AF_INET; 227746808Sdab (void) strcpy(_hostname, hostp); 227846808Sdab hostname = _hostname; 227938689Sborman } else { 228044361Sborman host = gethostbyname(hostp); 228138689Sborman if (host) { 228238689Sborman sin.sin_family = host->h_addrtype; 228332144Sminshall #if defined(h_addr) /* In 4.3, this is a #define */ 228438689Sborman memcpy((caddr_t)&sin.sin_addr, 228532144Sminshall host->h_addr_list[0], host->h_length); 228632144Sminshall #else /* defined(h_addr) */ 228738689Sborman memcpy((caddr_t)&sin.sin_addr, host->h_addr, host->h_length); 228832144Sminshall #endif /* defined(h_addr) */ 228946808Sdab strncpy(_hostname, host->h_name, sizeof(_hostname)); 229046808Sdab _hostname[sizeof(_hostname)-1] = '\0'; 229146808Sdab hostname = _hostname; 229238689Sborman } else { 229344361Sborman herror(hostp); 229446808Sdab setuid(getuid()); 229538689Sborman return 0; 229638689Sborman } 229732144Sminshall } 229846808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 229932144Sminshall } 230038689Sborman #endif 230144361Sborman if (portp) { 230244361Sborman if (*portp == '-') { 230344361Sborman portp++; 230438689Sborman telnetport = 1; 230538689Sborman } else 230638689Sborman telnetport = 0; 230744361Sborman sin.sin_port = atoi(portp); 230832144Sminshall if (sin.sin_port == 0) { 230944361Sborman sp = getservbyname(portp, "tcp"); 231032144Sminshall if (sp) 231132144Sminshall sin.sin_port = sp->s_port; 231232144Sminshall else { 231344361Sborman printf("%s: bad port number\n", portp); 231446808Sdab setuid(getuid()); 231532144Sminshall return 0; 231632144Sminshall } 231732144Sminshall } else { 231857213Sdab #if !defined(htons) 231957213Sdab u_short htons(); 232057213Sdab #endif /* !defined(htons) */ 232132144Sminshall sin.sin_port = htons(sin.sin_port); 232232144Sminshall } 232332144Sminshall } else { 232432144Sminshall if (sp == 0) { 232532144Sminshall sp = getservbyname("telnet", "tcp"); 232632144Sminshall if (sp == 0) { 232734849Sminshall fprintf(stderr, "telnet: tcp/telnet: unknown service\n"); 232846808Sdab setuid(getuid()); 232932144Sminshall return 0; 233032144Sminshall } 233132144Sminshall sin.sin_port = sp->s_port; 233232144Sminshall } 233332144Sminshall telnetport = 1; 233432144Sminshall } 233537219Sminshall printf("Trying %s...\n", inet_ntoa(sin.sin_addr)); 233632144Sminshall do { 233732144Sminshall net = socket(AF_INET, SOCK_STREAM, 0); 233846808Sdab setuid(getuid()); 233932144Sminshall if (net < 0) { 234032144Sminshall perror("telnet: socket"); 234132144Sminshall return 0; 234232144Sminshall } 234346808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 234438689Sborman if (srp && setsockopt(net, IPPROTO_IP, IP_OPTIONS, (char *)srp, srlen) < 0) 234538689Sborman perror("setsockopt (IP_OPTIONS)"); 234638689Sborman #endif 234746808Sdab #if defined(IPPROTO_IP) && defined(IP_TOS) 234846808Sdab { 234946808Sdab # if defined(HAS_GETTOS) 235046808Sdab struct tosent *tp; 235146815Sdab if (tos < 0 && (tp = gettosbyname("telnet", "tcp"))) 235246808Sdab tos = tp->t_tos; 235346808Sdab # endif 235446815Sdab if (tos < 0) 235546815Sdab tos = 020; /* Low Delay bit */ 235646815Sdab if (tos 235757213Sdab && (setsockopt(net, IPPROTO_IP, IP_TOS, 235857213Sdab (char *)&tos, sizeof(int)) < 0) 235946815Sdab && (errno != ENOPROTOOPT)) 236046815Sdab perror("telnet: setsockopt (IP_TOS) (ignored)"); 236146808Sdab } 236246808Sdab #endif /* defined(IPPROTO_IP) && defined(IP_TOS) */ 236340245Sborman 236432144Sminshall if (debug && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 1) < 0) { 236532144Sminshall perror("setsockopt (SO_DEBUG)"); 236632144Sminshall } 236732144Sminshall 236832144Sminshall if (connect(net, (struct sockaddr *)&sin, sizeof (sin)) < 0) { 236932144Sminshall #if defined(h_addr) /* In 4.3, this is a #define */ 237032144Sminshall if (host && host->h_addr_list[1]) { 237132144Sminshall int oerrno = errno; 237232144Sminshall 237332144Sminshall fprintf(stderr, "telnet: connect to address %s: ", 237432144Sminshall inet_ntoa(sin.sin_addr)); 237532144Sminshall errno = oerrno; 237632144Sminshall perror((char *)0); 237732144Sminshall host->h_addr_list++; 237832144Sminshall memcpy((caddr_t)&sin.sin_addr, 237932144Sminshall host->h_addr_list[0], host->h_length); 238032144Sminshall (void) NetClose(net); 238132144Sminshall continue; 238232144Sminshall } 238332144Sminshall #endif /* defined(h_addr) */ 238432144Sminshall perror("telnet: Unable to connect to remote host"); 238532144Sminshall return 0; 238637219Sminshall } 238732144Sminshall connected++; 238857213Sdab #if defined(AUTHENTICATION) || defined(ENCRYPTION) 238946808Sdab auth_encrypt_connect(connected); 2390*60149Sdab #endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */ 239132144Sminshall } while (connected == 0); 239244361Sborman cmdrc(hostp, hostname); 239345008Skarels if (autologin && user == NULL) { 239445008Skarels struct passwd *pw; 239545008Skarels 239645233Sborman user = getenv("USER"); 239745008Skarels if (user == NULL || 239845233Sborman (pw = getpwnam(user)) && pw->pw_uid != getuid()) { 239945233Sborman if (pw = getpwuid(getuid())) 240045008Skarels user = pw->pw_name; 240145008Skarels else 240245008Skarels user = NULL; 240345233Sborman } 240445008Skarels } 240545008Skarels if (user) { 240646808Sdab env_define((unsigned char *)"USER", (unsigned char *)user); 240746808Sdab env_export((unsigned char *)"USER"); 240845008Skarels } 240934849Sminshall (void) call(status, "status", "notmuch", 0); 241032144Sminshall if (setjmp(peerdied) == 0) 241146808Sdab telnet(user); 241234849Sminshall (void) NetClose(net); 241332381Sminshall ExitString("Connection closed by foreign host.\n",1); 241432144Sminshall /*NOTREACHED*/ 241532144Sminshall } 241632144Sminshall 241732144Sminshall #define HELPINDENT (sizeof ("connect")) 241832144Sminshall 241932144Sminshall static char 242032144Sminshall openhelp[] = "connect to a site", 242132144Sminshall closehelp[] = "close current connection", 242246808Sdab logouthelp[] = "forcibly logout remote user and close the connection", 242332144Sminshall quithelp[] = "exit telnet", 242432144Sminshall statushelp[] = "print status information", 242532144Sminshall helphelp[] = "print help information", 242632144Sminshall sendhelp[] = "transmit special characters ('send ?' for more)", 242732144Sminshall sethelp[] = "set operating parameters ('set ?' for more)", 242838689Sborman unsethelp[] = "unset operating parameters ('unset ?' for more)", 242932144Sminshall togglestring[] ="toggle operating parameters ('toggle ?' for more)", 243038689Sborman slchelp[] = "change state of special charaters ('slc ?' for more)", 243132144Sminshall displayhelp[] = "display operating parameters", 243232144Sminshall #if defined(TN3270) && defined(unix) 243332144Sminshall transcomhelp[] = "specify Unix command for transparent mode pipe", 243432144Sminshall #endif /* defined(TN3270) && defined(unix) */ 243557213Sdab #if defined(AUTHENTICATION) 243646808Sdab authhelp[] = "turn on (off) authentication ('auth ?' for more)", 243746808Sdab #endif 2438*60149Sdab #ifdef ENCRYPTION 243946808Sdab encrypthelp[] = "turn on (off) encryption ('encrypt ?' for more)", 2440*60149Sdab #endif /* ENCRYPTION */ 244132144Sminshall #if defined(unix) 244232144Sminshall zhelp[] = "suspend telnet", 244343317Skfall #endif /* defined(unix) */ 244432144Sminshall shellhelp[] = "invoke a subshell", 244544361Sborman envhelp[] = "change environment variables ('environ ?' for more)", 244644361Sborman modestring[] = "try to enter line or character mode ('mode ?' for more)"; 244732144Sminshall 244856642Sralph static int help(); 244932144Sminshall 245032144Sminshall static Command cmdtab[] = { 245138689Sborman { "close", closehelp, bye, 1 }, 245246808Sdab { "logout", logouthelp, logout, 1 }, 245338689Sborman { "display", displayhelp, display, 0 }, 245438689Sborman { "mode", modestring, modecmd, 0 }, 245538689Sborman { "open", openhelp, tn, 0 }, 245638689Sborman { "quit", quithelp, quit, 0 }, 245738689Sborman { "send", sendhelp, sendcmd, 0 }, 245838689Sborman { "set", sethelp, setcmd, 0 }, 245938689Sborman { "unset", unsethelp, unsetcmd, 0 }, 246038689Sborman { "status", statushelp, status, 0 }, 246138689Sborman { "toggle", togglestring, toggle, 0 }, 246238689Sborman { "slc", slchelp, slccmd, 0 }, 246332144Sminshall #if defined(TN3270) && defined(unix) 246438689Sborman { "transcom", transcomhelp, settranscom, 0 }, 246532144Sminshall #endif /* defined(TN3270) && defined(unix) */ 246657213Sdab #if defined(AUTHENTICATION) 246746808Sdab { "auth", authhelp, auth_cmd, 0 }, 246846808Sdab #endif 2469*60149Sdab #ifdef ENCRYPTION 247046808Sdab { "encrypt", encrypthelp, encrypt_cmd, 0 }, 2471*60149Sdab #endif /* ENCRYPTION */ 247232144Sminshall #if defined(unix) 247338689Sborman { "z", zhelp, suspend, 0 }, 247432144Sminshall #endif /* defined(unix) */ 247532144Sminshall #if defined(TN3270) 247638689Sborman { "!", shellhelp, shell, 1 }, 247738689Sborman #else 247838689Sborman { "!", shellhelp, shell, 0 }, 247938689Sborman #endif 248044361Sborman { "environ", envhelp, env_cmd, 0 }, 248138689Sborman { "?", helphelp, help, 0 }, 248232144Sminshall 0 248332144Sminshall }; 248432144Sminshall 248532144Sminshall static char crmodhelp[] = "deprecated command -- use 'toggle crmod' instead"; 248632144Sminshall static char escapehelp[] = "deprecated command -- use 'set escape' instead"; 248732144Sminshall 248832144Sminshall static Command cmdtab2[] = { 248938689Sborman { "help", 0, help, 0 }, 249038689Sborman { "escape", escapehelp, setescape, 0 }, 249138689Sborman { "crmod", crmodhelp, togcrmod, 0 }, 249232144Sminshall 0 249332144Sminshall }; 249432144Sminshall 249535298Sminshall 249632144Sminshall /* 249732144Sminshall * Call routine with argc, argv set from args (terminated by 0). 249832144Sminshall */ 249935298Sminshall 250046808Sdab /*VARARGS1*/ 250146808Sdab static 250235298Sminshall call(va_alist) 250346808Sdab va_dcl 250432144Sminshall { 250535298Sminshall va_list ap; 250635298Sminshall typedef int (*intrtn_t)(); 250735298Sminshall intrtn_t routine; 250835298Sminshall char *args[100]; 250935298Sminshall int argno = 0; 251035298Sminshall 251135298Sminshall va_start(ap); 251235298Sminshall routine = (va_arg(ap, intrtn_t)); 251335495Sminshall while ((args[argno++] = va_arg(ap, char *)) != 0) { 251435298Sminshall ; 251535495Sminshall } 251635298Sminshall va_end(ap); 251735495Sminshall return (*routine)(argno-1, args); 251832144Sminshall } 251932144Sminshall 252035298Sminshall 252146808Sdab static Command * 252232144Sminshall getcmd(name) 252346808Sdab char *name; 252432144Sminshall { 252532144Sminshall Command *cm; 252632144Sminshall 252746808Sdab if (cm = (Command *) genget(name, (char **) cmdtab, sizeof(Command))) 252832144Sminshall return cm; 252946808Sdab return (Command *) genget(name, (char **) cmdtab2, sizeof(Command)); 253032144Sminshall } 253132144Sminshall 253246808Sdab void 253338689Sborman command(top, tbuf, cnt) 253446808Sdab int top; 253546808Sdab char *tbuf; 253646808Sdab int cnt; 253732144Sminshall { 253832144Sminshall register Command *c; 253932144Sminshall 254032144Sminshall setcommandmode(); 254132144Sminshall if (!top) { 254232144Sminshall putchar('\n'); 254337219Sminshall #if defined(unix) 254432144Sminshall } else { 254544361Sborman (void) signal(SIGINT, SIG_DFL); 254644361Sborman (void) signal(SIGQUIT, SIG_DFL); 254732144Sminshall #endif /* defined(unix) */ 254832144Sminshall } 254932144Sminshall for (;;) { 255046808Sdab if (rlogin == _POSIX_VDISABLE) 255146808Sdab printf("%s> ", prompt); 255238689Sborman if (tbuf) { 255338689Sborman register char *cp; 255438689Sborman cp = line; 255538689Sborman while (cnt > 0 && (*cp++ = *tbuf++) != '\n') 255638689Sborman cnt--; 255738689Sborman tbuf = 0; 255838689Sborman if (cp == line || *--cp != '\n' || cp == line) 255938689Sborman goto getline; 256038689Sborman *cp = '\0'; 256146808Sdab if (rlogin == _POSIX_VDISABLE) 256246808Sdab printf("%s\n", line); 256338689Sborman } else { 256438689Sborman getline: 256546808Sdab if (rlogin != _POSIX_VDISABLE) 256646808Sdab printf("%s> ", prompt); 256746808Sdab if (fgets(line, sizeof(line), stdin) == NULL) { 256844361Sborman if (feof(stdin) || ferror(stdin)) { 256944361Sborman (void) quit(); 257044361Sborman /*NOTREACHED*/ 257144361Sborman } 257238689Sborman break; 257338689Sborman } 257432144Sminshall } 257532144Sminshall if (line[0] == 0) 257632144Sminshall break; 257732144Sminshall makeargv(); 257837219Sminshall if (margv[0] == 0) { 257937219Sminshall break; 258037219Sminshall } 258132144Sminshall c = getcmd(margv[0]); 258232144Sminshall if (Ambiguous(c)) { 258332144Sminshall printf("?Ambiguous command\n"); 258432144Sminshall continue; 258532144Sminshall } 258632144Sminshall if (c == 0) { 258732144Sminshall printf("?Invalid command\n"); 258832144Sminshall continue; 258932144Sminshall } 259032144Sminshall if (c->needconnect && !connected) { 259132144Sminshall printf("?Need to be connected first.\n"); 259232144Sminshall continue; 259332144Sminshall } 259432144Sminshall if ((*c->handler)(margc, margv)) { 259532144Sminshall break; 259632144Sminshall } 259732144Sminshall } 259832144Sminshall if (!top) { 259932144Sminshall if (!connected) { 260032144Sminshall longjmp(toplevel, 1); 260132144Sminshall /*NOTREACHED*/ 260232144Sminshall } 260332144Sminshall #if defined(TN3270) 260432144Sminshall if (shell_active == 0) { 260538689Sborman setconnmode(0); 260632144Sminshall } 260732144Sminshall #else /* defined(TN3270) */ 260838689Sborman setconnmode(0); 260932144Sminshall #endif /* defined(TN3270) */ 261032144Sminshall } 261132144Sminshall } 261232144Sminshall 261332144Sminshall /* 261432144Sminshall * Help command. 261532144Sminshall */ 261646808Sdab static 261732144Sminshall help(argc, argv) 261832144Sminshall int argc; 261932144Sminshall char *argv[]; 262032144Sminshall { 262132144Sminshall register Command *c; 262232144Sminshall 262332144Sminshall if (argc == 1) { 262432144Sminshall printf("Commands may be abbreviated. Commands are:\n\n"); 262532144Sminshall for (c = cmdtab; c->name; c++) 262638689Sborman if (c->help) { 262732144Sminshall printf("%-*s\t%s\n", HELPINDENT, c->name, 262832144Sminshall c->help); 262932144Sminshall } 263032144Sminshall return 0; 263132144Sminshall } 263232144Sminshall while (--argc > 0) { 263332144Sminshall register char *arg; 263432144Sminshall arg = *++argv; 263532144Sminshall c = getcmd(arg); 263632144Sminshall if (Ambiguous(c)) 263732144Sminshall printf("?Ambiguous help command %s\n", arg); 263832144Sminshall else if (c == (Command *)0) 263932144Sminshall printf("?Invalid help command %s\n", arg); 264032144Sminshall else 264132144Sminshall printf("%s\n", c->help); 264232144Sminshall } 264332144Sminshall return 0; 264432144Sminshall } 264538689Sborman 264638689Sborman static char *rcname = 0; 264738689Sborman static char rcbuf[128]; 264838689Sborman 264938689Sborman cmdrc(m1, m2) 265038689Sborman char *m1, *m2; 265138689Sborman { 265238689Sborman register Command *c; 265338689Sborman FILE *rcfile; 265438689Sborman int gotmachine = 0; 265538689Sborman int l1 = strlen(m1); 265638689Sborman int l2 = strlen(m2); 265738689Sborman char m1save[64]; 265838689Sborman 265947609Sdab if (skiprc) 266047609Sdab return; 266147609Sdab 266238689Sborman strcpy(m1save, m1); 266338689Sborman m1 = m1save; 266438689Sborman 266538689Sborman if (rcname == 0) { 266638689Sborman rcname = getenv("HOME"); 266738689Sborman if (rcname) 266838689Sborman strcpy(rcbuf, rcname); 266938689Sborman else 267038689Sborman rcbuf[0] = '\0'; 267138689Sborman strcat(rcbuf, "/.telnetrc"); 267238689Sborman rcname = rcbuf; 267338689Sborman } 267438689Sborman 267538689Sborman if ((rcfile = fopen(rcname, "r")) == 0) { 267638689Sborman return; 267738689Sborman } 267838689Sborman 267938689Sborman for (;;) { 268038689Sborman if (fgets(line, sizeof(line), rcfile) == NULL) 268138689Sborman break; 268238689Sborman if (line[0] == 0) 268338689Sborman break; 268438689Sborman if (line[0] == '#') 268538689Sborman continue; 268647609Sdab if (gotmachine) { 268747609Sdab if (!isspace(line[0])) 268847609Sdab gotmachine = 0; 268947609Sdab } 269038689Sborman if (gotmachine == 0) { 269138689Sborman if (isspace(line[0])) 269238689Sborman continue; 269338689Sborman if (strncasecmp(line, m1, l1) == 0) 269438689Sborman strncpy(line, &line[l1], sizeof(line) - l1); 269538689Sborman else if (strncasecmp(line, m2, l2) == 0) 269638689Sborman strncpy(line, &line[l2], sizeof(line) - l2); 269747609Sdab else if (strncasecmp(line, "DEFAULT", 7) == 0) 269847609Sdab strncpy(line, &line[7], sizeof(line) - 7); 269938689Sborman else 270038689Sborman continue; 270147609Sdab if (line[0] != ' ' && line[0] != '\t' && line[0] != '\n') 270247609Sdab continue; 270338689Sborman gotmachine = 1; 270438689Sborman } 270538689Sborman makeargv(); 270638689Sborman if (margv[0] == 0) 270738689Sborman continue; 270838689Sborman c = getcmd(margv[0]); 270938689Sborman if (Ambiguous(c)) { 271038689Sborman printf("?Ambiguous command: %s\n", margv[0]); 271138689Sborman continue; 271238689Sborman } 271338689Sborman if (c == 0) { 271438689Sborman printf("?Invalid command: %s\n", margv[0]); 271538689Sborman continue; 271638689Sborman } 271738689Sborman /* 271838689Sborman * This should never happen... 271938689Sborman */ 272038689Sborman if (c->needconnect && !connected) { 272138689Sborman printf("?Need to be connected first for %s.\n", margv[0]); 272238689Sborman continue; 272338689Sborman } 272438689Sborman (*c->handler)(margc, margv); 272538689Sborman } 272638689Sborman fclose(rcfile); 272738689Sborman } 272838689Sborman 272946808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 273038689Sborman 273138689Sborman /* 273238689Sborman * Source route is handed in as 273338689Sborman * [!]@hop1@hop2...[@|:]dst 273438689Sborman * If the leading ! is present, it is a 273538689Sborman * strict source route, otherwise it is 273638689Sborman * assmed to be a loose source route. 273738689Sborman * 273838689Sborman * We fill in the source route option as 273938689Sborman * hop1,hop2,hop3...dest 274038689Sborman * and return a pointer to hop1, which will 274138689Sborman * be the address to connect() to. 274238689Sborman * 274338689Sborman * Arguments: 274438689Sborman * arg: pointer to route list to decipher 274538689Sborman * 274638689Sborman * cpp: If *cpp is not equal to NULL, this is a 274738689Sborman * pointer to a pointer to a character array 274838689Sborman * that should be filled in with the option. 274938689Sborman * 275038689Sborman * lenp: pointer to an integer that contains the 275138689Sborman * length of *cpp if *cpp != NULL. 275238689Sborman * 275338689Sborman * Return values: 275438689Sborman * 275538689Sborman * Returns the address of the host to connect to. If the 275638689Sborman * return value is -1, there was a syntax error in the 275738689Sborman * option, either unknown characters, or too many hosts. 275838689Sborman * If the return value is 0, one of the hostnames in the 275938689Sborman * path is unknown, and *cpp is set to point to the bad 276038689Sborman * hostname. 276138689Sborman * 276238689Sborman * *cpp: If *cpp was equal to NULL, it will be filled 276338689Sborman * in with a pointer to our static area that has 276438689Sborman * the option filled in. This will be 32bit aligned. 276538689Sborman * 276638689Sborman * *lenp: This will be filled in with how long the option 276738689Sborman * pointed to by *cpp is. 276838689Sborman * 276938689Sborman */ 277046808Sdab unsigned long 277138689Sborman sourceroute(arg, cpp, lenp) 277246808Sdab char *arg; 277346808Sdab char **cpp; 277446808Sdab int *lenp; 277538689Sborman { 277638689Sborman static char lsr[44]; 277757213Sdab #ifdef sysV88 277857213Sdab static IOPTN ipopt; 277957213Sdab #endif 278046808Sdab char *cp, *cp2, *lsrp, *lsrep; 278138689Sborman register int tmp; 278238689Sborman struct in_addr sin_addr; 278338689Sborman register struct hostent *host = 0; 278438689Sborman register char c; 278538689Sborman 278638689Sborman /* 278738689Sborman * Verify the arguments, and make sure we have 278838689Sborman * at least 7 bytes for the option. 278938689Sborman */ 279038689Sborman if (cpp == NULL || lenp == NULL) 279138689Sborman return((unsigned long)-1); 279238689Sborman if (*cpp != NULL && *lenp < 7) 279338689Sborman return((unsigned long)-1); 279438689Sborman /* 279538689Sborman * Decide whether we have a buffer passed to us, 279638689Sborman * or if we need to use our own static buffer. 279738689Sborman */ 279838689Sborman if (*cpp) { 279938689Sborman lsrp = *cpp; 280038689Sborman lsrep = lsrp + *lenp; 280138689Sborman } else { 280238689Sborman *cpp = lsrp = lsr; 280338689Sborman lsrep = lsrp + 44; 280438689Sborman } 280538689Sborman 280638689Sborman cp = arg; 280738689Sborman 280838689Sborman /* 280938689Sborman * Next, decide whether we have a loose source 281038689Sborman * route or a strict source route, and fill in 281138689Sborman * the begining of the option. 281238689Sborman */ 281357213Sdab #ifndef sysV88 281438689Sborman if (*cp == '!') { 281538689Sborman cp++; 281638689Sborman *lsrp++ = IPOPT_SSRR; 281738689Sborman } else 281838689Sborman *lsrp++ = IPOPT_LSRR; 281957213Sdab #else 282057213Sdab if (*cp == '!') { 282157213Sdab cp++; 282257213Sdab ipopt.io_type = IPOPT_SSRR; 282357213Sdab } else 282457213Sdab ipopt.io_type = IPOPT_LSRR; 282557213Sdab #endif 282638689Sborman 282738689Sborman if (*cp != '@') 282838689Sborman return((unsigned long)-1); 282938689Sborman 283057213Sdab #ifndef sysV88 283138689Sborman lsrp++; /* skip over length, we'll fill it in later */ 283238689Sborman *lsrp++ = 4; 283357213Sdab #endif 283438689Sborman 283538689Sborman cp++; 283638689Sborman 283738689Sborman sin_addr.s_addr = 0; 283838689Sborman 283938689Sborman for (c = 0;;) { 284038689Sborman if (c == ':') 284138689Sborman cp2 = 0; 284238689Sborman else for (cp2 = cp; c = *cp2; cp2++) { 284338689Sborman if (c == ',') { 284438689Sborman *cp2++ = '\0'; 284538689Sborman if (*cp2 == '@') 284638689Sborman cp2++; 284738689Sborman } else if (c == '@') { 284838689Sborman *cp2++ = '\0'; 284938689Sborman } else if (c == ':') { 285038689Sborman *cp2++ = '\0'; 285138689Sborman } else 285238689Sborman continue; 285338689Sborman break; 285438689Sborman } 285538689Sborman if (!c) 285638689Sborman cp2 = 0; 285738689Sborman 285838689Sborman if ((tmp = inet_addr(cp)) != -1) { 285938689Sborman sin_addr.s_addr = tmp; 286038689Sborman } else if (host = gethostbyname(cp)) { 286138689Sborman #if defined(h_addr) 286238689Sborman memcpy((caddr_t)&sin_addr, 286338689Sborman host->h_addr_list[0], host->h_length); 286438689Sborman #else 286538689Sborman memcpy((caddr_t)&sin_addr, host->h_addr, host->h_length); 286638689Sborman #endif 286738689Sborman } else { 286838689Sborman *cpp = cp; 286938689Sborman return(0); 287038689Sborman } 287138689Sborman memcpy(lsrp, (char *)&sin_addr, 4); 287238689Sborman lsrp += 4; 287338689Sborman if (cp2) 287438689Sborman cp = cp2; 287538689Sborman else 287638689Sborman break; 287738689Sborman /* 287838689Sborman * Check to make sure there is space for next address 287938689Sborman */ 288038689Sborman if (lsrp + 4 > lsrep) 288138689Sborman return((unsigned long)-1); 288238689Sborman } 288357213Sdab #ifndef sysV88 288438689Sborman if ((*(*cpp+IPOPT_OLEN) = lsrp - *cpp) <= 7) { 288538689Sborman *cpp = 0; 288638689Sborman *lenp = 0; 288738689Sborman return((unsigned long)-1); 288838689Sborman } 288938689Sborman *lsrp++ = IPOPT_NOP; /* 32 bit word align it */ 289038689Sborman *lenp = lsrp - *cpp; 289157213Sdab #else 289257213Sdab ipopt.io_len = lsrp - *cpp; 289357213Sdab if (ipopt.io_len <= 5) { /* Is 3 better ? */ 289457213Sdab *cpp = 0; 289557213Sdab *lenp = 0; 289657213Sdab return((unsigned long)-1); 289757213Sdab } 289857213Sdab *lenp = sizeof(ipopt); 289957213Sdab *cpp = (char *) &ipopt; 290057213Sdab #endif 290138689Sborman return(sin_addr.s_addr); 290238689Sborman } 290338689Sborman #endif 2904