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*58972Sdab static char sccsid[] = "@(#)commands.c 5.10 (Berkeley) 04/05/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 59657213Sdab #if defined(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)); 60147609Sdab #endif 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 63457213Sdab #if defined(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" }, 65547609Sdab #endif 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(); 127357213Sdab #if defined(ENCRYPTION) 127446808Sdab EncryptStatus(); 127546808Sdab #endif 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 } 140738689Sborman #endif /* !defined(TN3270) */ 140838689Sborman 140946808Sdab /*VARARGS*/ 141046808Sdab static 141132144Sminshall bye(argc, argv) 141246808Sdab int argc; /* Number of arguments */ 141346808Sdab char *argv[]; /* arguments */ 141432144Sminshall { 141546808Sdab extern int resettermname; 141646808Sdab 141732144Sminshall if (connected) { 141834849Sminshall (void) shutdown(net, 2); 141932144Sminshall printf("Connection closed.\n"); 142034849Sminshall (void) NetClose(net); 142132144Sminshall connected = 0; 142246808Sdab resettermname = 1; 142357213Sdab #if defined(AUTHENTICATION) || defined(ENCRYPTION) 142446808Sdab auth_encrypt_connect(connected); 142546808Sdab #endif 142632144Sminshall /* reset options */ 142732144Sminshall tninit(); 142832144Sminshall #if defined(TN3270) 142932144Sminshall SetIn3270(); /* Get out of 3270 mode */ 143032144Sminshall #endif /* defined(TN3270) */ 143132144Sminshall } 143232144Sminshall if ((argc != 2) || (strcmp(argv[1], "fromquit") != 0)) { 143332144Sminshall longjmp(toplevel, 1); 143432144Sminshall /* NOTREACHED */ 143532144Sminshall } 143632144Sminshall return 1; /* Keep lint, etc., happy */ 143732144Sminshall } 143832144Sminshall 143932144Sminshall /*VARARGS*/ 144032144Sminshall quit() 144132144Sminshall { 144232144Sminshall (void) call(bye, "bye", "fromquit", 0); 144332144Sminshall Exit(0); 144444361Sborman /*NOTREACHED*/ 144532144Sminshall } 144646808Sdab 144746808Sdab /*VARARGS*/ 144846808Sdab int 144946808Sdab logout() 145046808Sdab { 145146808Sdab send_do(TELOPT_LOGOUT, 1); 145246808Sdab (void) netflush(); 145346808Sdab return 1; 145446808Sdab } 145546808Sdab 145638689Sborman 145738689Sborman /* 145838689Sborman * The SLC command. 145938689Sborman */ 146032144Sminshall 146138689Sborman struct slclist { 146238689Sborman char *name; 146338689Sborman char *help; 146446808Sdab void (*handler)(); 146538689Sborman int arg; 146638689Sborman }; 146738689Sborman 146856642Sralph static void slc_help(); 146938689Sborman 147038689Sborman struct slclist SlcList[] = { 147138689Sborman { "export", "Use local special character definitions", 147238689Sborman slc_mode_export, 0 }, 147338689Sborman { "import", "Use remote special character definitions", 147438689Sborman slc_mode_import, 1 }, 147538689Sborman { "check", "Verify remote special character definitions", 147638689Sborman slc_mode_import, 0 }, 147738689Sborman { "help", 0, slc_help, 0 }, 147838689Sborman { "?", "Print help information", slc_help, 0 }, 147938689Sborman { 0 }, 148038689Sborman }; 148138689Sborman 148246808Sdab static void 148338689Sborman slc_help() 148438689Sborman { 148538689Sborman struct slclist *c; 148638689Sborman 148738689Sborman for (c = SlcList; c->name; c++) { 148838689Sborman if (c->help) { 148938689Sborman if (*c->help) 149038689Sborman printf("%-15s %s\n", c->name, c->help); 149138689Sborman else 149238689Sborman printf("\n"); 149338689Sborman } 149438689Sborman } 149538689Sborman } 149638689Sborman 149746808Sdab static struct slclist * 149838689Sborman getslc(name) 149946808Sdab char *name; 150038689Sborman { 150146808Sdab return (struct slclist *) 150246808Sdab genget(name, (char **) SlcList, sizeof(struct slclist)); 150338689Sborman } 150438689Sborman 150546808Sdab static 150638689Sborman slccmd(argc, argv) 150746808Sdab int argc; 150846808Sdab char *argv[]; 150938689Sborman { 151038689Sborman struct slclist *c; 151138689Sborman 151238689Sborman if (argc != 2) { 151338689Sborman fprintf(stderr, 151438689Sborman "Need an argument to 'slc' command. 'slc ?' for help.\n"); 151538689Sborman return 0; 151638689Sborman } 151738689Sborman c = getslc(argv[1]); 151838689Sborman if (c == 0) { 151938689Sborman fprintf(stderr, "'%s': unknown argument ('slc ?' for help).\n", 152038689Sborman argv[1]); 152138689Sborman return 0; 152238689Sborman } 152338689Sborman if (Ambiguous(c)) { 152438689Sborman fprintf(stderr, "'%s': ambiguous argument ('slc ?' for help).\n", 152538689Sborman argv[1]); 152638689Sborman return 0; 152738689Sborman } 152838689Sborman (*c->handler)(c->arg); 152938689Sborman slcstate(); 153038689Sborman return 1; 153138689Sborman } 153244361Sborman 153344361Sborman /* 153444361Sborman * The ENVIRON command. 153544361Sborman */ 153638689Sborman 153744361Sborman struct envlist { 153844361Sborman char *name; 153944361Sborman char *help; 154046808Sdab void (*handler)(); 154144361Sborman int narg; 154244361Sborman }; 154344361Sborman 154446808Sdab extern struct env_lst * 154546808Sdab env_define P((unsigned char *, unsigned char *)); 154646808Sdab extern void 154746808Sdab env_undefine P((unsigned char *)), 154846808Sdab env_export P((unsigned char *)), 154946808Sdab env_unexport P((unsigned char *)), 155046808Sdab env_send P((unsigned char *)), 1551*58972Sdab #ifdef ENV_HACK 1552*58972Sdab env_varval P((unsigned char *)), 1553*58972Sdab #endif 155456642Sralph env_list P((void)); 155556642Sralph static void 155646808Sdab env_help P((void)); 155744361Sborman 155844361Sborman struct envlist EnvList[] = { 155944361Sborman { "define", "Define an environment variable", 156046808Sdab (void (*)())env_define, 2 }, 156144361Sborman { "undefine", "Undefine an environment variable", 156244361Sborman env_undefine, 1 }, 156344361Sborman { "export", "Mark an environment variable for automatic export", 156444361Sborman env_export, 1 }, 156546808Sdab { "unexport", "Don't mark an environment variable for automatic export", 156644361Sborman env_unexport, 1 }, 156745233Sborman { "send", "Send an environment variable", env_send, 1 }, 156844361Sborman { "list", "List the current environment variables", 156944361Sborman env_list, 0 }, 1570*58972Sdab #ifdef ENV_HACK 1571*58972Sdab { "varval", "Reverse VAR and VALUE (auto, right, wrong, status)", 1572*58972Sdab env_varval, 1 }, 1573*58972Sdab #endif 157444361Sborman { "help", 0, env_help, 0 }, 157544361Sborman { "?", "Print help information", env_help, 0 }, 157644361Sborman { 0 }, 157744361Sborman }; 157844361Sborman 157946808Sdab static void 158044361Sborman env_help() 158144361Sborman { 158244361Sborman struct envlist *c; 158344361Sborman 158444361Sborman for (c = EnvList; c->name; c++) { 158544361Sborman if (c->help) { 158644361Sborman if (*c->help) 158744361Sborman printf("%-15s %s\n", c->name, c->help); 158844361Sborman else 158944361Sborman printf("\n"); 159044361Sborman } 159144361Sborman } 159244361Sborman } 159344361Sborman 159446808Sdab static struct envlist * 159544361Sborman getenvcmd(name) 159646808Sdab char *name; 159744361Sborman { 159846808Sdab return (struct envlist *) 159946808Sdab genget(name, (char **) EnvList, sizeof(struct envlist)); 160044361Sborman } 160144361Sborman 160244361Sborman env_cmd(argc, argv) 160346808Sdab int argc; 160446808Sdab char *argv[]; 160544361Sborman { 160644361Sborman struct envlist *c; 160744361Sborman 160844361Sborman if (argc < 2) { 160944361Sborman fprintf(stderr, 161044361Sborman "Need an argument to 'environ' command. 'environ ?' for help.\n"); 161144361Sborman return 0; 161244361Sborman } 161344361Sborman c = getenvcmd(argv[1]); 161444361Sborman if (c == 0) { 161544361Sborman fprintf(stderr, "'%s': unknown argument ('environ ?' for help).\n", 161644361Sborman argv[1]); 161744361Sborman return 0; 161844361Sborman } 161944361Sborman if (Ambiguous(c)) { 162044361Sborman fprintf(stderr, "'%s': ambiguous argument ('environ ?' for help).\n", 162144361Sborman argv[1]); 162244361Sborman return 0; 162344361Sborman } 162444361Sborman if (c->narg + 2 != argc) { 162544361Sborman fprintf(stderr, 162644361Sborman "Need %s%d argument%s to 'environ %s' command. 'environ ?' for help.\n", 162744361Sborman c->narg < argc + 2 ? "only " : "", 162844361Sborman c->narg, c->narg == 1 ? "" : "s", c->name); 162944361Sborman return 0; 163044361Sborman } 163146808Sdab (*c->handler)(argv[2], argv[3]); 163244361Sborman return 1; 163344361Sborman } 163444361Sborman 163544361Sborman struct env_lst { 163644361Sborman struct env_lst *next; /* pointer to next structure */ 163757213Sdab struct env_lst *prev; /* pointer to previous structure */ 163846808Sdab unsigned char *var; /* pointer to variable name */ 163957213Sdab unsigned char *value; /* pointer to variable value */ 164044361Sborman int export; /* 1 -> export with default list of variables */ 164157213Sdab int welldefined; /* A well defined variable */ 164244361Sborman }; 164344361Sborman 164444361Sborman struct env_lst envlisthead; 164544361Sborman 164646808Sdab struct env_lst * 164744361Sborman env_find(var) 164846808Sdab unsigned char *var; 164944361Sborman { 165044361Sborman register struct env_lst *ep; 165144361Sborman 165244361Sborman for (ep = envlisthead.next; ep; ep = ep->next) { 165346808Sdab if (strcmp((char *)ep->var, (char *)var) == 0) 165444361Sborman return(ep); 165544361Sborman } 165644361Sborman return(NULL); 165744361Sborman } 165844361Sborman 165946808Sdab void 166044361Sborman env_init() 166144361Sborman { 166246808Sdab extern char **environ; 166344361Sborman register char **epp, *cp; 166444361Sborman register struct env_lst *ep; 166546808Sdab extern char *index(); 166644361Sborman 166744361Sborman for (epp = environ; *epp; epp++) { 166844361Sborman if (cp = index(*epp, '=')) { 166944361Sborman *cp = '\0'; 167046808Sdab ep = env_define((unsigned char *)*epp, 167146808Sdab (unsigned char *)cp+1); 167244361Sborman ep->export = 0; 167344361Sborman *cp = '='; 167444361Sborman } 167544361Sborman } 167644361Sborman /* 167744361Sborman * Special case for DISPLAY variable. If it is ":0.0" or 167844361Sborman * "unix:0.0", we have to get rid of "unix" and insert our 167944361Sborman * hostname. 168044361Sborman */ 168146808Sdab if ((ep = env_find("DISPLAY")) 168246808Sdab && ((*ep->value == ':') 168346808Sdab || (strncmp((char *)ep->value, "unix:", 5) == 0))) { 168444361Sborman char hbuf[256+1]; 168546808Sdab char *cp2 = index((char *)ep->value, ':'); 168644361Sborman 168744361Sborman gethostname(hbuf, 256); 168844361Sborman hbuf[256] = '\0'; 168944361Sborman cp = (char *)malloc(strlen(hbuf) + strlen(cp2) + 1); 169046808Sdab sprintf((char *)cp, "%s%s", hbuf, cp2); 169144361Sborman free(ep->value); 169246808Sdab ep->value = (unsigned char *)cp; 169344361Sborman } 169444361Sborman /* 169544361Sborman * If USER is not defined, but LOGNAME is, then add 169645233Sborman * USER with the value from LOGNAME. By default, we 169745233Sborman * don't export the USER variable. 169844361Sborman */ 169945233Sborman if ((env_find("USER") == NULL) && (ep = env_find("LOGNAME"))) { 170046808Sdab env_define((unsigned char *)"USER", ep->value); 170146808Sdab env_unexport((unsigned char *)"USER"); 170245233Sborman } 170346808Sdab env_export((unsigned char *)"DISPLAY"); 170446808Sdab env_export((unsigned char *)"PRINTER"); 170544361Sborman } 170644361Sborman 170746808Sdab struct env_lst * 170844361Sborman env_define(var, value) 170946808Sdab unsigned char *var, *value; 171044361Sborman { 171144361Sborman register struct env_lst *ep; 171244361Sborman 171344361Sborman if (ep = env_find(var)) { 171444361Sborman if (ep->var) 171544361Sborman free(ep->var); 171644361Sborman if (ep->value) 171744361Sborman free(ep->value); 171844361Sborman } else { 171944361Sborman ep = (struct env_lst *)malloc(sizeof(struct env_lst)); 172044361Sborman ep->next = envlisthead.next; 172144361Sborman envlisthead.next = ep; 172244361Sborman ep->prev = &envlisthead; 172344361Sborman if (ep->next) 172444361Sborman ep->next->prev = ep; 172544361Sborman } 172657213Sdab ep->welldefined = opt_welldefined(var); 172745009Skarels ep->export = 1; 172846808Sdab ep->var = (unsigned char *)strdup((char *)var); 172946808Sdab ep->value = (unsigned char *)strdup((char *)value); 173044361Sborman return(ep); 173144361Sborman } 173244361Sborman 173346808Sdab void 173444361Sborman env_undefine(var) 173546808Sdab unsigned char *var; 173644361Sborman { 173744361Sborman register struct env_lst *ep; 173844361Sborman 173944361Sborman if (ep = env_find(var)) { 174044361Sborman ep->prev->next = ep->next; 174145233Sborman if (ep->next) 174245233Sborman ep->next->prev = ep->prev; 174344361Sborman if (ep->var) 174444361Sborman free(ep->var); 174544361Sborman if (ep->value) 174644361Sborman free(ep->value); 174744361Sborman free(ep); 174844361Sborman } 174944361Sborman } 175044361Sborman 175146808Sdab void 175244361Sborman env_export(var) 175346808Sdab unsigned char *var; 175444361Sborman { 175544361Sborman register struct env_lst *ep; 175644361Sborman 175744361Sborman if (ep = env_find(var)) 175844361Sborman ep->export = 1; 175944361Sborman } 176044361Sborman 176146808Sdab void 176244361Sborman env_unexport(var) 176346808Sdab unsigned char *var; 176444361Sborman { 176544361Sborman register struct env_lst *ep; 176644361Sborman 176744361Sborman if (ep = env_find(var)) 176844361Sborman ep->export = 0; 176944361Sborman } 177044361Sborman 177146808Sdab void 177245233Sborman env_send(var) 177346808Sdab unsigned char *var; 177445233Sborman { 177545233Sborman register struct env_lst *ep; 177645233Sborman 177745233Sborman if (my_state_is_wont(TELOPT_ENVIRON)) { 177845233Sborman fprintf(stderr, 177945233Sborman "Cannot send '%s': Telnet ENVIRON option not enabled\n", 178045233Sborman var); 178145233Sborman return; 178245233Sborman } 178345233Sborman ep = env_find(var); 178445233Sborman if (ep == 0) { 178545233Sborman fprintf(stderr, "Cannot send '%s': variable not defined\n", 178645233Sborman var); 178745233Sborman return; 178845233Sborman } 178945233Sborman env_opt_start_info(); 179045233Sborman env_opt_add(ep->var); 179145233Sborman env_opt_end(0); 179245233Sborman } 179345233Sborman 179446808Sdab void 179544361Sborman env_list() 179644361Sborman { 179744361Sborman register struct env_lst *ep; 179844361Sborman 179944361Sborman for (ep = envlisthead.next; ep; ep = ep->next) { 180044361Sborman printf("%c %-20s %s\n", ep->export ? '*' : ' ', 180144361Sborman ep->var, ep->value); 180244361Sborman } 180344361Sborman } 180444361Sborman 180546808Sdab unsigned char * 180657213Sdab env_default(init, welldefined) 180746808Sdab int init; 180844361Sborman { 180944361Sborman static struct env_lst *nep = NULL; 181044361Sborman 181144361Sborman if (init) { 181244361Sborman nep = &envlisthead; 181344361Sborman return; 181444361Sborman } 181544361Sborman if (nep) { 181644361Sborman while (nep = nep->next) { 181757213Sdab if (nep->export && (nep->welldefined == welldefined)) 181844361Sborman return(nep->var); 181944361Sborman } 182044361Sborman } 182144361Sborman return(NULL); 182244361Sborman } 182344361Sborman 182446808Sdab unsigned char * 182544361Sborman env_getvalue(var) 182646808Sdab unsigned char *var; 182744361Sborman { 182844361Sborman register struct env_lst *ep; 182944361Sborman 183044361Sborman if (ep = env_find(var)) 183144361Sborman return(ep->value); 183244361Sborman return(NULL); 183344361Sborman } 183444361Sborman 1835*58972Sdab #ifdef ENV_HACK 1836*58972Sdab void 1837*58972Sdab env_varval(what) 1838*58972Sdab unsigned char *what; 1839*58972Sdab { 1840*58972Sdab extern int env_var, env_value, env_auto; 1841*58972Sdab int len = strlen(what); 1842*58972Sdab 1843*58972Sdab if (len == 0) 1844*58972Sdab goto unknown; 1845*58972Sdab 1846*58972Sdab if (strncasecmp(what, "status", len) == 0) { 1847*58972Sdab if (env_auto) 1848*58972Sdab printf("%s%s", "VAR and VALUE are/will be ", 1849*58972Sdab "determined automatically\n"); 1850*58972Sdab if (env_var == ENV_VAR) 1851*58972Sdab printf("VAR and VALUE set to correct definitions\n"); 1852*58972Sdab else 1853*58972Sdab printf("VAR and VALUE definitions are reversed\n"); 1854*58972Sdab } else if (strncasecmp(what, "auto", len) == 0) { 1855*58972Sdab env_auto = 1; 1856*58972Sdab env_var = ENV_VALUE; 1857*58972Sdab env_value = ENV_VAR; 1858*58972Sdab } else if (strncasecmp(what, "right", len) == 0) { 1859*58972Sdab env_auto = 0; 1860*58972Sdab env_var = ENV_VAR; 1861*58972Sdab env_value = ENV_VALUE; 1862*58972Sdab } else if (strncasecmp(what, "wrong", len) == 0) { 1863*58972Sdab env_auto = 0; 1864*58972Sdab env_var = ENV_VALUE; 1865*58972Sdab env_value = ENV_VAR; 1866*58972Sdab } else { 1867*58972Sdab unknown: 1868*58972Sdab printf("Unknown \"varval\" command. (\"auto\", \"right\", \"wrong\", \"status\")\n"); 1869*58972Sdab } 1870*58972Sdab } 1871*58972Sdab #endif 1872*58972Sdab 187357213Sdab #if defined(AUTHENTICATION) 187446808Sdab /* 187546808Sdab * The AUTHENTICATE command. 187646808Sdab */ 187746808Sdab 187846808Sdab struct authlist { 187946808Sdab char *name; 188046808Sdab char *help; 188146808Sdab int (*handler)(); 188246808Sdab int narg; 188346808Sdab }; 188446808Sdab 188546808Sdab extern int 188646808Sdab auth_enable P((int)), 188746808Sdab auth_disable P((int)), 188856642Sralph auth_status P((void)); 188956642Sralph static int 189046808Sdab auth_help P((void)); 189146808Sdab 189246808Sdab struct authlist AuthList[] = { 189346808Sdab { "status", "Display current status of authentication information", 189446808Sdab auth_status, 0 }, 189546808Sdab { "disable", "Disable an authentication type ('auth disable ?' for more)", 189646808Sdab auth_disable, 1 }, 189746808Sdab { "enable", "Enable an authentication type ('auth enable ?' for more)", 189846808Sdab auth_enable, 1 }, 189946808Sdab { "help", 0, auth_help, 0 }, 190046808Sdab { "?", "Print help information", auth_help, 0 }, 190146808Sdab { 0 }, 190246808Sdab }; 190346808Sdab 190446808Sdab static int 190546808Sdab auth_help() 190644361Sborman { 190746808Sdab struct authlist *c; 190846808Sdab 190946808Sdab for (c = AuthList; c->name; c++) { 191046808Sdab if (c->help) { 191146808Sdab if (*c->help) 191246808Sdab printf("%-15s %s\n", c->name, c->help); 191346808Sdab else 191446808Sdab printf("\n"); 191546808Sdab } 191646808Sdab } 191746808Sdab return 0; 191844361Sborman } 191946808Sdab 192046808Sdab auth_cmd(argc, argv) 192146808Sdab int argc; 192246808Sdab char *argv[]; 192346808Sdab { 192446808Sdab struct authlist *c; 192546808Sdab 192646808Sdab c = (struct authlist *) 192746808Sdab genget(argv[1], (char **) AuthList, sizeof(struct authlist)); 192846808Sdab if (c == 0) { 192946808Sdab fprintf(stderr, "'%s': unknown argument ('auth ?' for help).\n", 193046808Sdab argv[1]); 193146808Sdab return 0; 193246808Sdab } 193346808Sdab if (Ambiguous(c)) { 193446808Sdab fprintf(stderr, "'%s': ambiguous argument ('auth ?' for help).\n", 193546808Sdab argv[1]); 193646808Sdab return 0; 193746808Sdab } 193846808Sdab if (c->narg + 2 != argc) { 193946808Sdab fprintf(stderr, 194046808Sdab "Need %s%d argument%s to 'auth %s' command. 'auth ?' for help.\n", 194146808Sdab c->narg < argc + 2 ? "only " : "", 194246808Sdab c->narg, c->narg == 1 ? "" : "s", c->name); 194346808Sdab return 0; 194446808Sdab } 194546808Sdab return((*c->handler)(argv[2], argv[3])); 194646808Sdab } 194745233Sborman #endif 194844361Sborman 194957213Sdab #if defined(ENCRYPTION) 195032144Sminshall /* 195146808Sdab * The ENCRYPT command. 195236274Sminshall */ 195336274Sminshall 195446808Sdab struct encryptlist { 195546808Sdab char *name; 195646808Sdab char *help; 195746808Sdab int (*handler)(); 195846808Sdab int needconnect; 195946808Sdab int minarg; 196046808Sdab int maxarg; 196146808Sdab }; 196246808Sdab 196346808Sdab extern int 196446808Sdab EncryptEnable P((char *, char *)), 196547609Sdab EncryptDisable P((char *, char *)), 196646808Sdab EncryptType P((char *, char *)), 196746808Sdab EncryptStart P((char *)), 196846808Sdab EncryptStartInput P((void)), 196946808Sdab EncryptStartOutput P((void)), 197046808Sdab EncryptStop P((char *)), 197146808Sdab EncryptStopInput P((void)), 197246808Sdab EncryptStopOutput P((void)), 197356642Sralph EncryptStatus P((void)); 197456642Sralph static int 197546808Sdab EncryptHelp P((void)); 197646808Sdab 197746808Sdab struct encryptlist EncryptList[] = { 197846808Sdab { "enable", "Enable encryption. ('encrypt enable ?' for more)", 197946808Sdab EncryptEnable, 1, 1, 2 }, 198047609Sdab { "disable", "Disable encryption. ('encrypt enable ?' for more)", 198147609Sdab EncryptDisable, 0, 1, 2 }, 198246808Sdab { "type", "Set encryptiong type. ('encrypt type ?' for more)", 198346808Sdab EncryptType, 0, 1, 1 }, 198446808Sdab { "start", "Start encryption. ('encrypt start ?' for more)", 198546808Sdab EncryptStart, 1, 0, 1 }, 198646808Sdab { "stop", "Stop encryption. ('encrypt stop ?' for more)", 198746808Sdab EncryptStop, 1, 0, 1 }, 198846808Sdab { "input", "Start encrypting the input stream", 198946808Sdab EncryptStartInput, 1, 0, 0 }, 199046808Sdab { "-input", "Stop encrypting the input stream", 199146808Sdab EncryptStopInput, 1, 0, 0 }, 199246808Sdab { "output", "Start encrypting the output stream", 199346808Sdab EncryptStartOutput, 1, 0, 0 }, 199446808Sdab { "-output", "Stop encrypting the output stream", 199546808Sdab EncryptStopOutput, 1, 0, 0 }, 199646808Sdab 199746808Sdab { "status", "Display current status of authentication information", 199846808Sdab EncryptStatus, 0, 0, 0 }, 199946808Sdab { "help", 0, EncryptHelp, 0, 0, 0 }, 200046808Sdab { "?", "Print help information", EncryptHelp, 0, 0, 0 }, 200146808Sdab { 0 }, 200246808Sdab }; 200346808Sdab 200446808Sdab static int 200546808Sdab EncryptHelp() 200636274Sminshall { 200746808Sdab struct encryptlist *c; 200846808Sdab 200946808Sdab for (c = EncryptList; c->name; c++) { 201046808Sdab if (c->help) { 201146808Sdab if (*c->help) 201246808Sdab printf("%-15s %s\n", c->name, c->help); 201346808Sdab else 201446808Sdab printf("\n"); 201536274Sminshall } 201646808Sdab } 201746808Sdab return 0; 201846808Sdab } 201936274Sminshall 202046808Sdab encrypt_cmd(argc, argv) 202146808Sdab int argc; 202246808Sdab char *argv[]; 202346808Sdab { 202446808Sdab struct encryptlist *c; 202536274Sminshall 202646808Sdab c = (struct encryptlist *) 202746808Sdab genget(argv[1], (char **) EncryptList, sizeof(struct encryptlist)); 202846808Sdab if (c == 0) { 202946808Sdab fprintf(stderr, "'%s': unknown argument ('encrypt ?' for help).\n", 203046808Sdab argv[1]); 203146808Sdab return 0; 203246808Sdab } 203346808Sdab if (Ambiguous(c)) { 203446808Sdab fprintf(stderr, "'%s': ambiguous argument ('encrypt ?' for help).\n", 203546808Sdab argv[1]); 203646808Sdab return 0; 203746808Sdab } 203846808Sdab argc -= 2; 203946808Sdab if (argc < c->minarg || argc > c->maxarg) { 204046808Sdab if (c->minarg == c->maxarg) { 204146808Sdab fprintf(stderr, "Need %s%d argument%s ", 204246808Sdab c->minarg < argc ? "only " : "", c->minarg, 204346808Sdab c->minarg == 1 ? "" : "s"); 204446808Sdab } else { 204546808Sdab fprintf(stderr, "Need %s%d-%d arguments ", 204646808Sdab c->maxarg < argc ? "only " : "", c->minarg, c->maxarg); 204746808Sdab } 204846808Sdab fprintf(stderr, "to 'encrypt %s' command. 'encrypt ?' for help.\n", 204946808Sdab c->name); 205046808Sdab return 0; 205146808Sdab } 205246808Sdab if (c->needconnect && !connected) { 205346808Sdab if (!(argc && (isprefix(argv[2], "help") || isprefix(argv[2], "?")))) { 205446808Sdab printf("?Need to be connected first.\n"); 205546808Sdab return 0; 205646808Sdab } 205746808Sdab } 205846808Sdab return ((*c->handler)(argc > 0 ? argv[2] : 0, 205946808Sdab argc > 1 ? argv[3] : 0, 206046808Sdab argc > 2 ? argv[4] : 0)); 206146808Sdab } 206236274Sminshall #endif 206336274Sminshall 206446808Sdab #if defined(unix) && defined(TN3270) 206546808Sdab static void 206636274Sminshall filestuff(fd) 206746808Sdab int fd; 206836274Sminshall { 206936274Sminshall int res; 207036274Sminshall 207138689Sborman #ifdef F_GETOWN 207238689Sborman setconnmode(0); 207336274Sminshall res = fcntl(fd, F_GETOWN, 0); 207436274Sminshall setcommandmode(); 207536274Sminshall 207636274Sminshall if (res == -1) { 207736274Sminshall perror("fcntl"); 207836274Sminshall return; 207936274Sminshall } 208036274Sminshall printf("\tOwner is %d.\n", res); 208138689Sborman #endif 208236274Sminshall 208338689Sborman setconnmode(0); 208436274Sminshall res = fcntl(fd, F_GETFL, 0); 208536274Sminshall setcommandmode(); 208636274Sminshall 208736274Sminshall if (res == -1) { 208836274Sminshall perror("fcntl"); 208936274Sminshall return; 209036274Sminshall } 209136274Sminshall printf("\tFlags are 0x%x: %s\n", res, decodeflags(res)); 209236274Sminshall } 209346808Sdab #endif /* defined(unix) && defined(TN3270) */ 209436274Sminshall 209536274Sminshall /* 209632144Sminshall * Print status about the connection. 209732144Sminshall */ 209846808Sdab /*ARGSUSED*/ 209946808Sdab static 210032144Sminshall status(argc, argv) 210146808Sdab int argc; 210246808Sdab char *argv[]; 210332144Sminshall { 210432144Sminshall if (connected) { 210532144Sminshall printf("Connected to %s.\n", hostname); 210636242Sminshall if ((argc < 2) || strcmp(argv[1], "notmuch")) { 210738689Sborman int mode = getconnmode(); 210838689Sborman 210938689Sborman if (my_want_state_is_will(TELOPT_LINEMODE)) { 211038689Sborman printf("Operating with LINEMODE option\n"); 211138689Sborman printf("%s line editing\n", (mode&MODE_EDIT) ? "Local" : "No"); 211238689Sborman printf("%s catching of signals\n", 211338689Sborman (mode&MODE_TRAPSIG) ? "Local" : "No"); 211438689Sborman slcstate(); 211538689Sborman #ifdef KLUDGELINEMODE 211639529Sborman } else if (kludgelinemode && my_want_state_is_dont(TELOPT_SGA)) { 211738689Sborman printf("Operating in obsolete linemode\n"); 211838689Sborman #endif 211938689Sborman } else { 212038689Sborman printf("Operating in single character mode\n"); 212138689Sborman if (localchars) 212238689Sborman printf("Catching signals locally\n"); 212332144Sminshall } 212438689Sborman printf("%s character echo\n", (mode&MODE_ECHO) ? "Local" : "Remote"); 212538689Sborman if (my_want_state_is_will(TELOPT_LFLOW)) 212638689Sborman printf("%s flow control\n", (mode&MODE_FLOW) ? "Local" : "No"); 212757213Sdab #if defined(ENCRYPTION) 212846808Sdab encrypt_display(); 212946808Sdab #endif 213032144Sminshall } 213132144Sminshall } else { 213232144Sminshall printf("No connection.\n"); 213332144Sminshall } 213432144Sminshall # if !defined(TN3270) 213532144Sminshall printf("Escape character is '%s'.\n", control(escape)); 213634849Sminshall (void) fflush(stdout); 213732144Sminshall # else /* !defined(TN3270) */ 213832144Sminshall if ((!In3270) && ((argc < 2) || strcmp(argv[1], "notmuch"))) { 213932144Sminshall printf("Escape character is '%s'.\n", control(escape)); 214032144Sminshall } 214132144Sminshall # if defined(unix) 214236242Sminshall if ((argc >= 2) && !strcmp(argv[1], "everything")) { 214336242Sminshall printf("SIGIO received %d time%s.\n", 214436242Sminshall sigiocount, (sigiocount == 1)? "":"s"); 214536274Sminshall if (In3270) { 214636274Sminshall printf("Process ID %d, process group %d.\n", 214736274Sminshall getpid(), getpgrp(getpid())); 214836274Sminshall printf("Terminal input:\n"); 214936274Sminshall filestuff(tin); 215036274Sminshall printf("Terminal output:\n"); 215136274Sminshall filestuff(tout); 215236274Sminshall printf("Network socket:\n"); 215336274Sminshall filestuff(net); 215436274Sminshall } 215536242Sminshall } 215632144Sminshall if (In3270 && transcom) { 215732144Sminshall printf("Transparent mode command is '%s'.\n", transcom); 215832144Sminshall } 215932144Sminshall # endif /* defined(unix) */ 216034849Sminshall (void) fflush(stdout); 216132144Sminshall if (In3270) { 216232144Sminshall return 0; 216332144Sminshall } 216432144Sminshall # endif /* defined(TN3270) */ 216532144Sminshall return 1; 216632144Sminshall } 216732144Sminshall 216845233Sborman #ifdef SIGINFO 216945233Sborman /* 217045233Sborman * Function that gets called when SIGINFO is received. 217145233Sborman */ 217245233Sborman ayt_status() 217345233Sborman { 217445233Sborman (void) call(status, "status", "notmuch", 0); 217545233Sborman } 217645233Sborman #endif 217732144Sminshall 2178*58972Sdab unsigned long inet_addr(); 2179*58972Sdab 218046808Sdab int 218132144Sminshall tn(argc, argv) 218246808Sdab int argc; 218346808Sdab char *argv[]; 218432144Sminshall { 218532144Sminshall register struct hostent *host = 0; 218632144Sminshall struct sockaddr_in sin; 218732144Sminshall struct servent *sp = 0; 2188*58972Sdab unsigned long temp; 218937219Sminshall extern char *inet_ntoa(); 219046808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 219138689Sborman char *srp = 0, *strrchr(); 219238689Sborman unsigned long sourceroute(), srlen; 219338689Sborman #endif 219444361Sborman char *cmd, *hostp = 0, *portp = 0, *user = 0; 219532144Sminshall 219645233Sborman /* clear the socket address prior to use */ 219745233Sborman bzero((char *)&sin, sizeof(sin)); 219832144Sminshall 219932144Sminshall if (connected) { 220032144Sminshall printf("?Already connected to %s\n", hostname); 220146808Sdab setuid(getuid()); 220232144Sminshall return 0; 220332144Sminshall } 220432144Sminshall if (argc < 2) { 220546808Sdab (void) strcpy(line, "open "); 220632144Sminshall printf("(to) "); 220746808Sdab (void) fgets(&line[strlen(line)], sizeof(line) - strlen(line), stdin); 220832144Sminshall makeargv(); 220932144Sminshall argc = margc; 221032144Sminshall argv = margv; 221132144Sminshall } 221244361Sborman cmd = *argv; 221344361Sborman --argc; ++argv; 221444361Sborman while (argc) { 221546808Sdab if (isprefix(*argv, "help") || isprefix(*argv, "?")) 221646808Sdab goto usage; 221744361Sborman if (strcmp(*argv, "-l") == 0) { 221844361Sborman --argc; ++argv; 221944361Sborman if (argc == 0) 222044361Sborman goto usage; 222144361Sborman user = *argv++; 222244361Sborman --argc; 222344361Sborman continue; 222444361Sborman } 222545233Sborman if (strcmp(*argv, "-a") == 0) { 222645233Sborman --argc; ++argv; 222745233Sborman autologin = 1; 222845233Sborman continue; 222945233Sborman } 223044361Sborman if (hostp == 0) { 223144361Sborman hostp = *argv++; 223244361Sborman --argc; 223344361Sborman continue; 223444361Sborman } 223544361Sborman if (portp == 0) { 223644361Sborman portp = *argv++; 223744361Sborman --argc; 223844361Sborman continue; 223944361Sborman } 224044361Sborman usage: 224145233Sborman printf("usage: %s [-l user] [-a] host-name [port]\n", cmd); 224246808Sdab setuid(getuid()); 224332144Sminshall return 0; 224432144Sminshall } 224546808Sdab if (hostp == 0) 224646808Sdab goto usage; 224746808Sdab 224846808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 224944361Sborman if (hostp[0] == '@' || hostp[0] == '!') { 225044361Sborman if ((hostname = strrchr(hostp, ':')) == NULL) 225144361Sborman hostname = strrchr(hostp, '@'); 225238689Sborman hostname++; 225338689Sborman srp = 0; 225444361Sborman temp = sourceroute(hostp, &srp, &srlen); 225538689Sborman if (temp == 0) { 225638689Sborman herror(srp); 225746808Sdab setuid(getuid()); 225838689Sborman return 0; 225938689Sborman } else if (temp == -1) { 226044361Sborman printf("Bad source route option: %s\n", hostp); 226146808Sdab setuid(getuid()); 226238689Sborman return 0; 226338689Sborman } else { 226438689Sborman sin.sin_addr.s_addr = temp; 226538689Sborman sin.sin_family = AF_INET; 226638689Sborman } 226732144Sminshall } else { 226838689Sborman #endif 226944361Sborman temp = inet_addr(hostp); 227038689Sborman if (temp != (unsigned long) -1) { 227138689Sborman sin.sin_addr.s_addr = temp; 227238689Sborman sin.sin_family = AF_INET; 227346808Sdab (void) strcpy(_hostname, hostp); 227446808Sdab hostname = _hostname; 227538689Sborman } else { 227644361Sborman host = gethostbyname(hostp); 227738689Sborman if (host) { 227838689Sborman sin.sin_family = host->h_addrtype; 227932144Sminshall #if defined(h_addr) /* In 4.3, this is a #define */ 228038689Sborman memcpy((caddr_t)&sin.sin_addr, 228132144Sminshall host->h_addr_list[0], host->h_length); 228232144Sminshall #else /* defined(h_addr) */ 228338689Sborman memcpy((caddr_t)&sin.sin_addr, host->h_addr, host->h_length); 228432144Sminshall #endif /* defined(h_addr) */ 228546808Sdab strncpy(_hostname, host->h_name, sizeof(_hostname)); 228646808Sdab _hostname[sizeof(_hostname)-1] = '\0'; 228746808Sdab hostname = _hostname; 228838689Sborman } else { 228944361Sborman herror(hostp); 229046808Sdab setuid(getuid()); 229138689Sborman return 0; 229238689Sborman } 229332144Sminshall } 229446808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 229532144Sminshall } 229638689Sborman #endif 229744361Sborman if (portp) { 229844361Sborman if (*portp == '-') { 229944361Sborman portp++; 230038689Sborman telnetport = 1; 230138689Sborman } else 230238689Sborman telnetport = 0; 230344361Sborman sin.sin_port = atoi(portp); 230432144Sminshall if (sin.sin_port == 0) { 230544361Sborman sp = getservbyname(portp, "tcp"); 230632144Sminshall if (sp) 230732144Sminshall sin.sin_port = sp->s_port; 230832144Sminshall else { 230944361Sborman printf("%s: bad port number\n", portp); 231046808Sdab setuid(getuid()); 231132144Sminshall return 0; 231232144Sminshall } 231332144Sminshall } else { 231457213Sdab #if !defined(htons) 231557213Sdab u_short htons(); 231657213Sdab #endif /* !defined(htons) */ 231732144Sminshall sin.sin_port = htons(sin.sin_port); 231832144Sminshall } 231932144Sminshall } else { 232032144Sminshall if (sp == 0) { 232132144Sminshall sp = getservbyname("telnet", "tcp"); 232232144Sminshall if (sp == 0) { 232334849Sminshall fprintf(stderr, "telnet: tcp/telnet: unknown service\n"); 232446808Sdab setuid(getuid()); 232532144Sminshall return 0; 232632144Sminshall } 232732144Sminshall sin.sin_port = sp->s_port; 232832144Sminshall } 232932144Sminshall telnetport = 1; 233032144Sminshall } 233137219Sminshall printf("Trying %s...\n", inet_ntoa(sin.sin_addr)); 233232144Sminshall do { 233332144Sminshall net = socket(AF_INET, SOCK_STREAM, 0); 233446808Sdab setuid(getuid()); 233532144Sminshall if (net < 0) { 233632144Sminshall perror("telnet: socket"); 233732144Sminshall return 0; 233832144Sminshall } 233946808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 234038689Sborman if (srp && setsockopt(net, IPPROTO_IP, IP_OPTIONS, (char *)srp, srlen) < 0) 234138689Sborman perror("setsockopt (IP_OPTIONS)"); 234238689Sborman #endif 234346808Sdab #if defined(IPPROTO_IP) && defined(IP_TOS) 234446808Sdab { 234546808Sdab # if defined(HAS_GETTOS) 234646808Sdab struct tosent *tp; 234746815Sdab if (tos < 0 && (tp = gettosbyname("telnet", "tcp"))) 234846808Sdab tos = tp->t_tos; 234946808Sdab # endif 235046815Sdab if (tos < 0) 235146815Sdab tos = 020; /* Low Delay bit */ 235246815Sdab if (tos 235357213Sdab && (setsockopt(net, IPPROTO_IP, IP_TOS, 235457213Sdab (char *)&tos, sizeof(int)) < 0) 235546815Sdab && (errno != ENOPROTOOPT)) 235646815Sdab perror("telnet: setsockopt (IP_TOS) (ignored)"); 235746808Sdab } 235846808Sdab #endif /* defined(IPPROTO_IP) && defined(IP_TOS) */ 235940245Sborman 236032144Sminshall if (debug && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 1) < 0) { 236132144Sminshall perror("setsockopt (SO_DEBUG)"); 236232144Sminshall } 236332144Sminshall 236432144Sminshall if (connect(net, (struct sockaddr *)&sin, sizeof (sin)) < 0) { 236532144Sminshall #if defined(h_addr) /* In 4.3, this is a #define */ 236632144Sminshall if (host && host->h_addr_list[1]) { 236732144Sminshall int oerrno = errno; 236832144Sminshall 236932144Sminshall fprintf(stderr, "telnet: connect to address %s: ", 237032144Sminshall inet_ntoa(sin.sin_addr)); 237132144Sminshall errno = oerrno; 237232144Sminshall perror((char *)0); 237332144Sminshall host->h_addr_list++; 237432144Sminshall memcpy((caddr_t)&sin.sin_addr, 237532144Sminshall host->h_addr_list[0], host->h_length); 237632144Sminshall (void) NetClose(net); 237732144Sminshall continue; 237832144Sminshall } 237932144Sminshall #endif /* defined(h_addr) */ 238032144Sminshall perror("telnet: Unable to connect to remote host"); 238132144Sminshall return 0; 238237219Sminshall } 238332144Sminshall connected++; 238457213Sdab #if defined(AUTHENTICATION) || defined(ENCRYPTION) 238546808Sdab auth_encrypt_connect(connected); 238646808Sdab #endif 238732144Sminshall } while (connected == 0); 238844361Sborman cmdrc(hostp, hostname); 238945008Skarels if (autologin && user == NULL) { 239045008Skarels struct passwd *pw; 239145008Skarels 239245233Sborman user = getenv("USER"); 239345008Skarels if (user == NULL || 239445233Sborman (pw = getpwnam(user)) && pw->pw_uid != getuid()) { 239545233Sborman if (pw = getpwuid(getuid())) 239645008Skarels user = pw->pw_name; 239745008Skarels else 239845008Skarels user = NULL; 239945233Sborman } 240045008Skarels } 240145008Skarels if (user) { 240246808Sdab env_define((unsigned char *)"USER", (unsigned char *)user); 240346808Sdab env_export((unsigned char *)"USER"); 240445008Skarels } 240534849Sminshall (void) call(status, "status", "notmuch", 0); 240632144Sminshall if (setjmp(peerdied) == 0) 240746808Sdab telnet(user); 240834849Sminshall (void) NetClose(net); 240932381Sminshall ExitString("Connection closed by foreign host.\n",1); 241032144Sminshall /*NOTREACHED*/ 241132144Sminshall } 241232144Sminshall 241332144Sminshall #define HELPINDENT (sizeof ("connect")) 241432144Sminshall 241532144Sminshall static char 241632144Sminshall openhelp[] = "connect to a site", 241732144Sminshall closehelp[] = "close current connection", 241846808Sdab logouthelp[] = "forcibly logout remote user and close the connection", 241932144Sminshall quithelp[] = "exit telnet", 242032144Sminshall statushelp[] = "print status information", 242132144Sminshall helphelp[] = "print help information", 242232144Sminshall sendhelp[] = "transmit special characters ('send ?' for more)", 242332144Sminshall sethelp[] = "set operating parameters ('set ?' for more)", 242438689Sborman unsethelp[] = "unset operating parameters ('unset ?' for more)", 242532144Sminshall togglestring[] ="toggle operating parameters ('toggle ?' for more)", 242638689Sborman slchelp[] = "change state of special charaters ('slc ?' for more)", 242732144Sminshall displayhelp[] = "display operating parameters", 242832144Sminshall #if defined(TN3270) && defined(unix) 242932144Sminshall transcomhelp[] = "specify Unix command for transparent mode pipe", 243032144Sminshall #endif /* defined(TN3270) && defined(unix) */ 243157213Sdab #if defined(AUTHENTICATION) 243246808Sdab authhelp[] = "turn on (off) authentication ('auth ?' for more)", 243346808Sdab #endif 243457213Sdab #if defined(ENCRYPTION) 243546808Sdab encrypthelp[] = "turn on (off) encryption ('encrypt ?' for more)", 243646808Sdab #endif 243732144Sminshall #if defined(unix) 243832144Sminshall zhelp[] = "suspend telnet", 243943317Skfall #endif /* defined(unix) */ 244032144Sminshall shellhelp[] = "invoke a subshell", 244144361Sborman envhelp[] = "change environment variables ('environ ?' for more)", 244244361Sborman modestring[] = "try to enter line or character mode ('mode ?' for more)"; 244332144Sminshall 244456642Sralph static int help(); 244532144Sminshall 244632144Sminshall static Command cmdtab[] = { 244738689Sborman { "close", closehelp, bye, 1 }, 244846808Sdab { "logout", logouthelp, logout, 1 }, 244938689Sborman { "display", displayhelp, display, 0 }, 245038689Sborman { "mode", modestring, modecmd, 0 }, 245138689Sborman { "open", openhelp, tn, 0 }, 245238689Sborman { "quit", quithelp, quit, 0 }, 245338689Sborman { "send", sendhelp, sendcmd, 0 }, 245438689Sborman { "set", sethelp, setcmd, 0 }, 245538689Sborman { "unset", unsethelp, unsetcmd, 0 }, 245638689Sborman { "status", statushelp, status, 0 }, 245738689Sborman { "toggle", togglestring, toggle, 0 }, 245838689Sborman { "slc", slchelp, slccmd, 0 }, 245932144Sminshall #if defined(TN3270) && defined(unix) 246038689Sborman { "transcom", transcomhelp, settranscom, 0 }, 246132144Sminshall #endif /* defined(TN3270) && defined(unix) */ 246257213Sdab #if defined(AUTHENTICATION) 246346808Sdab { "auth", authhelp, auth_cmd, 0 }, 246446808Sdab #endif 246557213Sdab #if defined(ENCRYPTION) 246646808Sdab { "encrypt", encrypthelp, encrypt_cmd, 0 }, 246746808Sdab #endif 246832144Sminshall #if defined(unix) 246938689Sborman { "z", zhelp, suspend, 0 }, 247032144Sminshall #endif /* defined(unix) */ 247132144Sminshall #if defined(TN3270) 247238689Sborman { "!", shellhelp, shell, 1 }, 247338689Sborman #else 247438689Sborman { "!", shellhelp, shell, 0 }, 247538689Sborman #endif 247644361Sborman { "environ", envhelp, env_cmd, 0 }, 247738689Sborman { "?", helphelp, help, 0 }, 247832144Sminshall 0 247932144Sminshall }; 248032144Sminshall 248132144Sminshall static char crmodhelp[] = "deprecated command -- use 'toggle crmod' instead"; 248232144Sminshall static char escapehelp[] = "deprecated command -- use 'set escape' instead"; 248332144Sminshall 248432144Sminshall static Command cmdtab2[] = { 248538689Sborman { "help", 0, help, 0 }, 248638689Sborman { "escape", escapehelp, setescape, 0 }, 248738689Sborman { "crmod", crmodhelp, togcrmod, 0 }, 248832144Sminshall 0 248932144Sminshall }; 249032144Sminshall 249135298Sminshall 249232144Sminshall /* 249332144Sminshall * Call routine with argc, argv set from args (terminated by 0). 249432144Sminshall */ 249535298Sminshall 249646808Sdab /*VARARGS1*/ 249746808Sdab static 249835298Sminshall call(va_alist) 249946808Sdab va_dcl 250032144Sminshall { 250135298Sminshall va_list ap; 250235298Sminshall typedef int (*intrtn_t)(); 250335298Sminshall intrtn_t routine; 250435298Sminshall char *args[100]; 250535298Sminshall int argno = 0; 250635298Sminshall 250735298Sminshall va_start(ap); 250835298Sminshall routine = (va_arg(ap, intrtn_t)); 250935495Sminshall while ((args[argno++] = va_arg(ap, char *)) != 0) { 251035298Sminshall ; 251135495Sminshall } 251235298Sminshall va_end(ap); 251335495Sminshall return (*routine)(argno-1, args); 251432144Sminshall } 251532144Sminshall 251635298Sminshall 251746808Sdab static Command * 251832144Sminshall getcmd(name) 251946808Sdab char *name; 252032144Sminshall { 252132144Sminshall Command *cm; 252232144Sminshall 252346808Sdab if (cm = (Command *) genget(name, (char **) cmdtab, sizeof(Command))) 252432144Sminshall return cm; 252546808Sdab return (Command *) genget(name, (char **) cmdtab2, sizeof(Command)); 252632144Sminshall } 252732144Sminshall 252846808Sdab void 252938689Sborman command(top, tbuf, cnt) 253046808Sdab int top; 253146808Sdab char *tbuf; 253246808Sdab int cnt; 253332144Sminshall { 253432144Sminshall register Command *c; 253532144Sminshall 253632144Sminshall setcommandmode(); 253732144Sminshall if (!top) { 253832144Sminshall putchar('\n'); 253937219Sminshall #if defined(unix) 254032144Sminshall } else { 254144361Sborman (void) signal(SIGINT, SIG_DFL); 254244361Sborman (void) signal(SIGQUIT, SIG_DFL); 254332144Sminshall #endif /* defined(unix) */ 254432144Sminshall } 254532144Sminshall for (;;) { 254646808Sdab if (rlogin == _POSIX_VDISABLE) 254746808Sdab printf("%s> ", prompt); 254838689Sborman if (tbuf) { 254938689Sborman register char *cp; 255038689Sborman cp = line; 255138689Sborman while (cnt > 0 && (*cp++ = *tbuf++) != '\n') 255238689Sborman cnt--; 255338689Sborman tbuf = 0; 255438689Sborman if (cp == line || *--cp != '\n' || cp == line) 255538689Sborman goto getline; 255638689Sborman *cp = '\0'; 255746808Sdab if (rlogin == _POSIX_VDISABLE) 255846808Sdab printf("%s\n", line); 255938689Sborman } else { 256038689Sborman getline: 256146808Sdab if (rlogin != _POSIX_VDISABLE) 256246808Sdab printf("%s> ", prompt); 256346808Sdab if (fgets(line, sizeof(line), stdin) == NULL) { 256444361Sborman if (feof(stdin) || ferror(stdin)) { 256544361Sborman (void) quit(); 256644361Sborman /*NOTREACHED*/ 256744361Sborman } 256838689Sborman break; 256938689Sborman } 257032144Sminshall } 257132144Sminshall if (line[0] == 0) 257232144Sminshall break; 257332144Sminshall makeargv(); 257437219Sminshall if (margv[0] == 0) { 257537219Sminshall break; 257637219Sminshall } 257732144Sminshall c = getcmd(margv[0]); 257832144Sminshall if (Ambiguous(c)) { 257932144Sminshall printf("?Ambiguous command\n"); 258032144Sminshall continue; 258132144Sminshall } 258232144Sminshall if (c == 0) { 258332144Sminshall printf("?Invalid command\n"); 258432144Sminshall continue; 258532144Sminshall } 258632144Sminshall if (c->needconnect && !connected) { 258732144Sminshall printf("?Need to be connected first.\n"); 258832144Sminshall continue; 258932144Sminshall } 259032144Sminshall if ((*c->handler)(margc, margv)) { 259132144Sminshall break; 259232144Sminshall } 259332144Sminshall } 259432144Sminshall if (!top) { 259532144Sminshall if (!connected) { 259632144Sminshall longjmp(toplevel, 1); 259732144Sminshall /*NOTREACHED*/ 259832144Sminshall } 259932144Sminshall #if defined(TN3270) 260032144Sminshall if (shell_active == 0) { 260138689Sborman setconnmode(0); 260232144Sminshall } 260332144Sminshall #else /* defined(TN3270) */ 260438689Sborman setconnmode(0); 260532144Sminshall #endif /* defined(TN3270) */ 260632144Sminshall } 260732144Sminshall } 260832144Sminshall 260932144Sminshall /* 261032144Sminshall * Help command. 261132144Sminshall */ 261246808Sdab static 261332144Sminshall help(argc, argv) 261432144Sminshall int argc; 261532144Sminshall char *argv[]; 261632144Sminshall { 261732144Sminshall register Command *c; 261832144Sminshall 261932144Sminshall if (argc == 1) { 262032144Sminshall printf("Commands may be abbreviated. Commands are:\n\n"); 262132144Sminshall for (c = cmdtab; c->name; c++) 262238689Sborman if (c->help) { 262332144Sminshall printf("%-*s\t%s\n", HELPINDENT, c->name, 262432144Sminshall c->help); 262532144Sminshall } 262632144Sminshall return 0; 262732144Sminshall } 262832144Sminshall while (--argc > 0) { 262932144Sminshall register char *arg; 263032144Sminshall arg = *++argv; 263132144Sminshall c = getcmd(arg); 263232144Sminshall if (Ambiguous(c)) 263332144Sminshall printf("?Ambiguous help command %s\n", arg); 263432144Sminshall else if (c == (Command *)0) 263532144Sminshall printf("?Invalid help command %s\n", arg); 263632144Sminshall else 263732144Sminshall printf("%s\n", c->help); 263832144Sminshall } 263932144Sminshall return 0; 264032144Sminshall } 264138689Sborman 264238689Sborman static char *rcname = 0; 264338689Sborman static char rcbuf[128]; 264438689Sborman 264538689Sborman cmdrc(m1, m2) 264638689Sborman char *m1, *m2; 264738689Sborman { 264838689Sborman register Command *c; 264938689Sborman FILE *rcfile; 265038689Sborman int gotmachine = 0; 265138689Sborman int l1 = strlen(m1); 265238689Sborman int l2 = strlen(m2); 265338689Sborman char m1save[64]; 265438689Sborman 265547609Sdab if (skiprc) 265647609Sdab return; 265747609Sdab 265838689Sborman strcpy(m1save, m1); 265938689Sborman m1 = m1save; 266038689Sborman 266138689Sborman if (rcname == 0) { 266238689Sborman rcname = getenv("HOME"); 266338689Sborman if (rcname) 266438689Sborman strcpy(rcbuf, rcname); 266538689Sborman else 266638689Sborman rcbuf[0] = '\0'; 266738689Sborman strcat(rcbuf, "/.telnetrc"); 266838689Sborman rcname = rcbuf; 266938689Sborman } 267038689Sborman 267138689Sborman if ((rcfile = fopen(rcname, "r")) == 0) { 267238689Sborman return; 267338689Sborman } 267438689Sborman 267538689Sborman for (;;) { 267638689Sborman if (fgets(line, sizeof(line), rcfile) == NULL) 267738689Sborman break; 267838689Sborman if (line[0] == 0) 267938689Sborman break; 268038689Sborman if (line[0] == '#') 268138689Sborman continue; 268247609Sdab if (gotmachine) { 268347609Sdab if (!isspace(line[0])) 268447609Sdab gotmachine = 0; 268547609Sdab } 268638689Sborman if (gotmachine == 0) { 268738689Sborman if (isspace(line[0])) 268838689Sborman continue; 268938689Sborman if (strncasecmp(line, m1, l1) == 0) 269038689Sborman strncpy(line, &line[l1], sizeof(line) - l1); 269138689Sborman else if (strncasecmp(line, m2, l2) == 0) 269238689Sborman strncpy(line, &line[l2], sizeof(line) - l2); 269347609Sdab else if (strncasecmp(line, "DEFAULT", 7) == 0) 269447609Sdab strncpy(line, &line[7], sizeof(line) - 7); 269538689Sborman else 269638689Sborman continue; 269747609Sdab if (line[0] != ' ' && line[0] != '\t' && line[0] != '\n') 269847609Sdab continue; 269938689Sborman gotmachine = 1; 270038689Sborman } 270138689Sborman makeargv(); 270238689Sborman if (margv[0] == 0) 270338689Sborman continue; 270438689Sborman c = getcmd(margv[0]); 270538689Sborman if (Ambiguous(c)) { 270638689Sborman printf("?Ambiguous command: %s\n", margv[0]); 270738689Sborman continue; 270838689Sborman } 270938689Sborman if (c == 0) { 271038689Sborman printf("?Invalid command: %s\n", margv[0]); 271138689Sborman continue; 271238689Sborman } 271338689Sborman /* 271438689Sborman * This should never happen... 271538689Sborman */ 271638689Sborman if (c->needconnect && !connected) { 271738689Sborman printf("?Need to be connected first for %s.\n", margv[0]); 271838689Sborman continue; 271938689Sborman } 272038689Sborman (*c->handler)(margc, margv); 272138689Sborman } 272238689Sborman fclose(rcfile); 272338689Sborman } 272438689Sborman 272546808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 272638689Sborman 272738689Sborman /* 272838689Sborman * Source route is handed in as 272938689Sborman * [!]@hop1@hop2...[@|:]dst 273038689Sborman * If the leading ! is present, it is a 273138689Sborman * strict source route, otherwise it is 273238689Sborman * assmed to be a loose source route. 273338689Sborman * 273438689Sborman * We fill in the source route option as 273538689Sborman * hop1,hop2,hop3...dest 273638689Sborman * and return a pointer to hop1, which will 273738689Sborman * be the address to connect() to. 273838689Sborman * 273938689Sborman * Arguments: 274038689Sborman * arg: pointer to route list to decipher 274138689Sborman * 274238689Sborman * cpp: If *cpp is not equal to NULL, this is a 274338689Sborman * pointer to a pointer to a character array 274438689Sborman * that should be filled in with the option. 274538689Sborman * 274638689Sborman * lenp: pointer to an integer that contains the 274738689Sborman * length of *cpp if *cpp != NULL. 274838689Sborman * 274938689Sborman * Return values: 275038689Sborman * 275138689Sborman * Returns the address of the host to connect to. If the 275238689Sborman * return value is -1, there was a syntax error in the 275338689Sborman * option, either unknown characters, or too many hosts. 275438689Sborman * If the return value is 0, one of the hostnames in the 275538689Sborman * path is unknown, and *cpp is set to point to the bad 275638689Sborman * hostname. 275738689Sborman * 275838689Sborman * *cpp: If *cpp was equal to NULL, it will be filled 275938689Sborman * in with a pointer to our static area that has 276038689Sborman * the option filled in. This will be 32bit aligned. 276138689Sborman * 276238689Sborman * *lenp: This will be filled in with how long the option 276338689Sborman * pointed to by *cpp is. 276438689Sborman * 276538689Sborman */ 276646808Sdab unsigned long 276738689Sborman sourceroute(arg, cpp, lenp) 276846808Sdab char *arg; 276946808Sdab char **cpp; 277046808Sdab int *lenp; 277138689Sborman { 277238689Sborman static char lsr[44]; 277357213Sdab #ifdef sysV88 277457213Sdab static IOPTN ipopt; 277557213Sdab #endif 277646808Sdab char *cp, *cp2, *lsrp, *lsrep; 277738689Sborman register int tmp; 277838689Sborman struct in_addr sin_addr; 277938689Sborman register struct hostent *host = 0; 278038689Sborman register char c; 278138689Sborman 278238689Sborman /* 278338689Sborman * Verify the arguments, and make sure we have 278438689Sborman * at least 7 bytes for the option. 278538689Sborman */ 278638689Sborman if (cpp == NULL || lenp == NULL) 278738689Sborman return((unsigned long)-1); 278838689Sborman if (*cpp != NULL && *lenp < 7) 278938689Sborman return((unsigned long)-1); 279038689Sborman /* 279138689Sborman * Decide whether we have a buffer passed to us, 279238689Sborman * or if we need to use our own static buffer. 279338689Sborman */ 279438689Sborman if (*cpp) { 279538689Sborman lsrp = *cpp; 279638689Sborman lsrep = lsrp + *lenp; 279738689Sborman } else { 279838689Sborman *cpp = lsrp = lsr; 279938689Sborman lsrep = lsrp + 44; 280038689Sborman } 280138689Sborman 280238689Sborman cp = arg; 280338689Sborman 280438689Sborman /* 280538689Sborman * Next, decide whether we have a loose source 280638689Sborman * route or a strict source route, and fill in 280738689Sborman * the begining of the option. 280838689Sborman */ 280957213Sdab #ifndef sysV88 281038689Sborman if (*cp == '!') { 281138689Sborman cp++; 281238689Sborman *lsrp++ = IPOPT_SSRR; 281338689Sborman } else 281438689Sborman *lsrp++ = IPOPT_LSRR; 281557213Sdab #else 281657213Sdab if (*cp == '!') { 281757213Sdab cp++; 281857213Sdab ipopt.io_type = IPOPT_SSRR; 281957213Sdab } else 282057213Sdab ipopt.io_type = IPOPT_LSRR; 282157213Sdab #endif 282238689Sborman 282338689Sborman if (*cp != '@') 282438689Sborman return((unsigned long)-1); 282538689Sborman 282657213Sdab #ifndef sysV88 282738689Sborman lsrp++; /* skip over length, we'll fill it in later */ 282838689Sborman *lsrp++ = 4; 282957213Sdab #endif 283038689Sborman 283138689Sborman cp++; 283238689Sborman 283338689Sborman sin_addr.s_addr = 0; 283438689Sborman 283538689Sborman for (c = 0;;) { 283638689Sborman if (c == ':') 283738689Sborman cp2 = 0; 283838689Sborman else for (cp2 = cp; c = *cp2; cp2++) { 283938689Sborman if (c == ',') { 284038689Sborman *cp2++ = '\0'; 284138689Sborman if (*cp2 == '@') 284238689Sborman cp2++; 284338689Sborman } else if (c == '@') { 284438689Sborman *cp2++ = '\0'; 284538689Sborman } else if (c == ':') { 284638689Sborman *cp2++ = '\0'; 284738689Sborman } else 284838689Sborman continue; 284938689Sborman break; 285038689Sborman } 285138689Sborman if (!c) 285238689Sborman cp2 = 0; 285338689Sborman 285438689Sborman if ((tmp = inet_addr(cp)) != -1) { 285538689Sborman sin_addr.s_addr = tmp; 285638689Sborman } else if (host = gethostbyname(cp)) { 285738689Sborman #if defined(h_addr) 285838689Sborman memcpy((caddr_t)&sin_addr, 285938689Sborman host->h_addr_list[0], host->h_length); 286038689Sborman #else 286138689Sborman memcpy((caddr_t)&sin_addr, host->h_addr, host->h_length); 286238689Sborman #endif 286338689Sborman } else { 286438689Sborman *cpp = cp; 286538689Sborman return(0); 286638689Sborman } 286738689Sborman memcpy(lsrp, (char *)&sin_addr, 4); 286838689Sborman lsrp += 4; 286938689Sborman if (cp2) 287038689Sborman cp = cp2; 287138689Sborman else 287238689Sborman break; 287338689Sborman /* 287438689Sborman * Check to make sure there is space for next address 287538689Sborman */ 287638689Sborman if (lsrp + 4 > lsrep) 287738689Sborman return((unsigned long)-1); 287838689Sborman } 287957213Sdab #ifndef sysV88 288038689Sborman if ((*(*cpp+IPOPT_OLEN) = lsrp - *cpp) <= 7) { 288138689Sborman *cpp = 0; 288238689Sborman *lenp = 0; 288338689Sborman return((unsigned long)-1); 288438689Sborman } 288538689Sborman *lsrp++ = IPOPT_NOP; /* 32 bit word align it */ 288638689Sborman *lenp = lsrp - *cpp; 288757213Sdab #else 288857213Sdab ipopt.io_len = lsrp - *cpp; 288957213Sdab if (ipopt.io_len <= 5) { /* Is 3 better ? */ 289057213Sdab *cpp = 0; 289157213Sdab *lenp = 0; 289257213Sdab return((unsigned long)-1); 289357213Sdab } 289457213Sdab *lenp = sizeof(ipopt); 289557213Sdab *cpp = (char *) &ipopt; 289657213Sdab #endif 289738689Sborman return(sin_addr.s_addr); 289838689Sborman } 289938689Sborman #endif 2900