133685Sbostic /* 233685Sbostic * Copyright (c) 1988 Regents of the University of California. 333685Sbostic * All rights reserved. 433685Sbostic * 542770Sbostic * %sccs.include.redist.c% 633685Sbostic */ 733685Sbostic 833685Sbostic #ifndef lint 9*43317Skfall static char sccsid[] = "@(#)commands.c 1.28 (Berkeley) 06/20/90"; 1033685Sbostic #endif /* not lint */ 1133685Sbostic 1232144Sminshall #include <sys/types.h> 1336274Sminshall #if defined(unix) 1436274Sminshall #include <sys/file.h> 1536274Sminshall #endif /* defined(unix) */ 1632144Sminshall #include <sys/socket.h> 1732144Sminshall #include <netinet/in.h> 1838689Sborman #ifdef CRAY 1938689Sborman #include <sys/fcntl.h> 2038810Sborman #endif /* CRAY */ 2132144Sminshall 2232144Sminshall #include <signal.h> 2332144Sminshall #include <netdb.h> 2432144Sminshall #include <ctype.h> 2535298Sminshall #include <varargs.h> 2632144Sminshall 2732144Sminshall #include <arpa/telnet.h> 2832144Sminshall 2934305Sminshall #include "general.h" 3034305Sminshall 3132381Sminshall #include "ring.h" 3232381Sminshall 3332144Sminshall #include "externs.h" 3432144Sminshall #include "defines.h" 3532144Sminshall #include "types.h" 3632144Sminshall 3738689Sborman #ifdef SRCRT 3838810Sborman # ifndef CRAY 3938810Sborman # include <netinet/in_systm.h> 4042250Sbostic # if defined(vax) || defined(tahoe) || defined(hp300) 4138810Sborman # include <machine/endian.h> 4239529Sborman # endif /* vax */ 4338810Sborman # endif /* CRAY */ 4438689Sborman #include <netinet/ip.h> 4538810Sborman #endif /* SRCRT */ 4638689Sborman 4740248Sborman #if defined(CRAY) && defined(IP_TOS) && !defined(HAS_IP_TOS) 4840248Sborman # define HAS_IP_TOS 4940248Sborman #endif 5038689Sborman 5140248Sborman 5232144Sminshall char *hostname; 5338689Sborman extern char *getenv(); 5432144Sminshall 5536180Sminshall #define Ambiguous(s) ((char **)s == &ambiguous) 5632144Sminshall static char *ambiguous; /* special return value for command routines */ 5732144Sminshall 5832144Sminshall typedef struct { 5932144Sminshall char *name; /* command name */ 6038689Sborman char *help; /* help string (NULL for no help) */ 6132144Sminshall int (*handler)(); /* routine which executes command */ 6232144Sminshall int needconnect; /* Do we need to be connected to execute? */ 6332144Sminshall } Command; 6432144Sminshall 6538689Sborman static char line[256]; 6638689Sborman static char saveline[256]; 6732144Sminshall static int margc; 6832144Sminshall static char *margv[20]; 6932144Sminshall 7032144Sminshall /* 7132144Sminshall * Various utility routines. 7232144Sminshall */ 7332144Sminshall 7436180Sminshall #if !defined(BSD) || (BSD <= 43) 7536180Sminshall 7636180Sminshall char *h_errlist[] = { 7736180Sminshall "Error 0", 7836180Sminshall "Unknown host", /* 1 HOST_NOT_FOUND */ 7936180Sminshall "Host name lookup failure", /* 2 TRY_AGAIN */ 8036180Sminshall "Unknown server error", /* 3 NO_RECOVERY */ 8136180Sminshall "No address associated with name", /* 4 NO_ADDRESS */ 8236180Sminshall }; 8336180Sminshall int h_nerr = { sizeof(h_errlist)/sizeof(h_errlist[0]) }; 8436180Sminshall 8536274Sminshall int h_errno; /* In some version of SunOS this is necessary */ 8636180Sminshall 8736180Sminshall /* 8836180Sminshall * herror -- 8936180Sminshall * print the error indicated by the h_errno value. 9036180Sminshall */ 9136180Sminshall herror(s) 9236180Sminshall char *s; 9336180Sminshall { 9436180Sminshall if (s && *s) { 9536180Sminshall fprintf(stderr, "%s: ", s); 9636180Sminshall } 9736180Sminshall if ((h_errno < 0) || (h_errno >= h_nerr)) { 9836180Sminshall fprintf(stderr, "Unknown error\n"); 9936274Sminshall } else if (h_errno == 0) { 10036274Sminshall #if defined(sun) 10136274Sminshall fprintf(stderr, "Host unknown\n"); 10236274Sminshall #endif /* defined(sun) */ 10336180Sminshall } else { 10436180Sminshall fprintf(stderr, "%s\n", h_errlist[h_errno]); 10536180Sminshall } 10636180Sminshall } 10736180Sminshall #endif /* !define(BSD) || (BSD <= 43) */ 10836180Sminshall 10932144Sminshall static void 11032144Sminshall makeargv() 11132144Sminshall { 11232144Sminshall register char *cp; 11332144Sminshall register char **argp = margv; 11432144Sminshall 11532144Sminshall margc = 0; 11632144Sminshall cp = line; 11732144Sminshall if (*cp == '!') { /* Special case shell escape */ 11838689Sborman strcpy(saveline, line); /* save for shell command */ 11932144Sminshall *argp++ = "!"; /* No room in string to get this */ 12032144Sminshall margc++; 12132144Sminshall cp++; 12232144Sminshall } 12332144Sminshall while (*cp) { 12432144Sminshall while (isspace(*cp)) 12532144Sminshall cp++; 12632144Sminshall if (*cp == '\0') 12732144Sminshall break; 12832144Sminshall *argp++ = cp; 12932144Sminshall margc += 1; 13032144Sminshall while (*cp != '\0' && !isspace(*cp)) 13132144Sminshall cp++; 13232144Sminshall if (*cp == '\0') 13332144Sminshall break; 13432144Sminshall *cp++ = '\0'; 13532144Sminshall } 13632144Sminshall *argp++ = 0; 13732144Sminshall } 13832144Sminshall 13932144Sminshall 14032144Sminshall static char ** 14132144Sminshall genget(name, table, next) 14232144Sminshall char *name; /* name to match */ 14332144Sminshall char **table; /* name entry in table */ 14432144Sminshall char **(*next)(); /* routine to return next entry in table */ 14532144Sminshall { 14632144Sminshall register char *p, *q; 14732144Sminshall register char **c, **found; 14832144Sminshall register int nmatches, longest; 14932144Sminshall 15032144Sminshall if (name == 0) { 15132144Sminshall return 0; 15232144Sminshall } 15332144Sminshall longest = 0; 15432144Sminshall nmatches = 0; 15532144Sminshall found = 0; 15632144Sminshall for (c = table; (p = *c) != 0; c = (*next)(c)) { 15732144Sminshall for (q = name; 15832144Sminshall (*q == *p) || (isupper(*q) && tolower(*q) == *p); p++, q++) 15932144Sminshall if (*q == 0) /* exact match? */ 16032144Sminshall return (c); 16132144Sminshall if (!*q) { /* the name was a prefix */ 16232144Sminshall if (q - name > longest) { 16332144Sminshall longest = q - name; 16432144Sminshall nmatches = 1; 16532144Sminshall found = c; 16632144Sminshall } else if (q - name == longest) 16732144Sminshall nmatches++; 16832144Sminshall } 16932144Sminshall } 17032144Sminshall if (nmatches > 1) 17136180Sminshall return &ambiguous; 17232144Sminshall return (found); 17332144Sminshall } 17432144Sminshall 17532144Sminshall /* 17632144Sminshall * Make a character string into a number. 17732144Sminshall * 17832144Sminshall * Todo: 1. Could take random integers (12, 0x12, 012, 0b1). 17932144Sminshall */ 18032144Sminshall 18132144Sminshall static 18232144Sminshall special(s) 18332144Sminshall register char *s; 18432144Sminshall { 18532144Sminshall register char c; 18632144Sminshall char b; 18732144Sminshall 18832144Sminshall switch (*s) { 18932144Sminshall case '^': 19032144Sminshall b = *++s; 19132144Sminshall if (b == '?') { 19232144Sminshall c = b | 0x40; /* DEL */ 19332144Sminshall } else { 19432144Sminshall c = b & 0x1f; 19532144Sminshall } 19632144Sminshall break; 19732144Sminshall default: 19832144Sminshall c = *s; 19932144Sminshall break; 20032144Sminshall } 20132144Sminshall return c; 20232144Sminshall } 20332144Sminshall 20432144Sminshall /* 20532144Sminshall * Construct a control character sequence 20632144Sminshall * for a special character. 20732144Sminshall */ 20832144Sminshall static char * 20932144Sminshall control(c) 21040245Sborman register cc_t c; 21132144Sminshall { 21232144Sminshall static char buf[3]; 21332144Sminshall 21432144Sminshall if (c == 0x7f) 21532144Sminshall return ("^?"); 21640245Sborman if (c == (cc_t)-1) { 21732144Sminshall return "off"; 21832144Sminshall } 21932144Sminshall if (c >= 0x20) { 22032144Sminshall buf[0] = c; 22132144Sminshall buf[1] = 0; 22232144Sminshall } else { 22332144Sminshall buf[0] = '^'; 22432144Sminshall buf[1] = '@'+c; 22532144Sminshall buf[2] = 0; 22632144Sminshall } 22732144Sminshall return (buf); 22832144Sminshall } 22932144Sminshall 23032144Sminshall 23132144Sminshall 23232144Sminshall /* 23332144Sminshall * The following are data structures and routines for 23432144Sminshall * the "send" command. 23532144Sminshall * 23632144Sminshall */ 23732144Sminshall 23832144Sminshall struct sendlist { 23932144Sminshall char *name; /* How user refers to it (case independent) */ 24032144Sminshall char *help; /* Help information (0 ==> no help) */ 24132144Sminshall #if defined(NOT43) 24238689Sborman int (*handler)(); /* Routine to perform (for special ops) */ 24332144Sminshall #else /* defined(NOT43) */ 24438689Sborman void (*handler)(); /* Routine to perform (for special ops) */ 24532144Sminshall #endif /* defined(NOT43) */ 24638689Sborman int what; /* Character to be sent (<0 ==> special) */ 24732144Sminshall }; 24832144Sminshall 24932144Sminshall #define SENDQUESTION -1 25032144Sminshall #define SENDESCAPE -3 25132144Sminshall 25232144Sminshall static struct sendlist Sendlist[] = { 25338689Sborman { "ao", "Send Telnet Abort output", 0, AO }, 25438689Sborman { "ayt", "Send Telnet 'Are You There'", 0, AYT }, 25538689Sborman { "brk", "Send Telnet Break", 0, BREAK }, 25638689Sborman { "ec", "Send Telnet Erase Character", 0, EC }, 25738689Sborman { "el", "Send Telnet Erase Line", 0, EL }, 25838689Sborman { "escape", "Send current escape character", 0, SENDESCAPE }, 25938689Sborman { "ga", "Send Telnet 'Go Ahead' sequence", 0, GA }, 26038689Sborman { "ip", "Send Telnet Interrupt Process", 0, IP }, 26138689Sborman { "nop", "Send Telnet 'No operation'", 0, NOP }, 26238689Sborman { "eor", "Send Telnet 'End of Record'", 0, EOR }, 26338689Sborman { "abort", "Send Telnet 'Abort Process'", 0, ABORT }, 26438689Sborman { "susp", "Send Telnet 'Suspend Process'", 0, SUSP }, 26538689Sborman { "eof", "Send Telnet End of File Character", 0, xEOF }, 26638689Sborman { "synch", "Perform Telnet 'Synch operation'", dosynch, SYNCH }, 26738909Sborman { "getstatus", "Send request for STATUS", get_status, 0 }, 26838689Sborman { "?", "Display send options", 0, SENDQUESTION }, 26932144Sminshall { 0 } 27032144Sminshall }; 27132144Sminshall 27232144Sminshall static struct sendlist Sendlist2[] = { /* some synonyms */ 27338689Sborman { "break", 0, 0, BREAK }, 27432144Sminshall 27538689Sborman { "intp", 0, 0, IP }, 27638689Sborman { "interrupt", 0, 0, IP }, 27738689Sborman { "intr", 0, 0, IP }, 27832144Sminshall 27938689Sborman { "help", 0, 0, SENDQUESTION }, 28032144Sminshall 28138689Sborman { 0 } 28232144Sminshall }; 28332144Sminshall 28432144Sminshall static char ** 28532144Sminshall getnextsend(name) 28632144Sminshall char *name; 28732144Sminshall { 28832144Sminshall struct sendlist *c = (struct sendlist *) name; 28932144Sminshall 29032144Sminshall return (char **) (c+1); 29132144Sminshall } 29232144Sminshall 29332144Sminshall static struct sendlist * 29432144Sminshall getsend(name) 29532144Sminshall char *name; 29632144Sminshall { 29732144Sminshall struct sendlist *sl; 29832144Sminshall 29932144Sminshall if ((sl = (struct sendlist *) 30032144Sminshall genget(name, (char **) Sendlist, getnextsend)) != 0) { 30132144Sminshall return sl; 30232144Sminshall } else { 30332144Sminshall return (struct sendlist *) 30432144Sminshall genget(name, (char **) Sendlist2, getnextsend); 30532144Sminshall } 30632144Sminshall } 30732144Sminshall 30832144Sminshall static 30932144Sminshall sendcmd(argc, argv) 31032144Sminshall int argc; 31132144Sminshall char **argv; 31232144Sminshall { 31332144Sminshall int what; /* what we are sending this time */ 31432144Sminshall int count; /* how many bytes we are going to need to send */ 31532144Sminshall int i; 31632144Sminshall int question = 0; /* was at least one argument a question */ 31732144Sminshall struct sendlist *s; /* pointer to current command */ 31832144Sminshall 31932144Sminshall if (argc < 2) { 32032144Sminshall printf("need at least one argument for 'send' command\n"); 32132144Sminshall printf("'send ?' for help\n"); 32232144Sminshall return 0; 32332144Sminshall } 32432144Sminshall /* 32532144Sminshall * First, validate all the send arguments. 32632144Sminshall * In addition, we see how much space we are going to need, and 32732144Sminshall * whether or not we will be doing a "SYNCH" operation (which 32832144Sminshall * flushes the network queue). 32932144Sminshall */ 33032144Sminshall count = 0; 33132144Sminshall for (i = 1; i < argc; i++) { 33232144Sminshall s = getsend(argv[i]); 33332144Sminshall if (s == 0) { 33432144Sminshall printf("Unknown send argument '%s'\n'send ?' for help.\n", 33532144Sminshall argv[i]); 33632144Sminshall return 0; 33732144Sminshall } else if (Ambiguous(s)) { 33832144Sminshall printf("Ambiguous send argument '%s'\n'send ?' for help.\n", 33932144Sminshall argv[i]); 34032144Sminshall return 0; 34132144Sminshall } 34232144Sminshall switch (s->what) { 34332144Sminshall case SENDQUESTION: 34438689Sborman question = 1; 34532144Sminshall break; 34632144Sminshall case SENDESCAPE: 34732144Sminshall count += 1; 34832144Sminshall break; 34932144Sminshall case SYNCH: 35032144Sminshall count += 2; 35132144Sminshall break; 35232144Sminshall default: 35332144Sminshall count += 2; 35432144Sminshall break; 35532144Sminshall } 35632144Sminshall } 35738689Sborman if (!connected) { 35838689Sborman if (count) 35938689Sborman printf("?Need to be connected first.\n"); 36038689Sborman if (question) { 36138689Sborman for (s = Sendlist; s->name; s++) 36238689Sborman if (s->help) 36338689Sborman printf("%-15s %s\n", s->name, s->help); 36438689Sborman } else 36538689Sborman printf("'send ?' for help\n"); 36638689Sborman return !question; 36738689Sborman } 36832144Sminshall /* Now, do we have enough room? */ 36932144Sminshall if (NETROOM() < count) { 37032144Sminshall printf("There is not enough room in the buffer TO the network\n"); 37132144Sminshall printf("to process your request. Nothing will be done.\n"); 37232144Sminshall printf("('send synch' will throw away most data in the network\n"); 37332144Sminshall printf("buffer, if this might help.)\n"); 37432144Sminshall return 0; 37532144Sminshall } 37632144Sminshall /* OK, they are all OK, now go through again and actually send */ 37732144Sminshall for (i = 1; i < argc; i++) { 37832144Sminshall if ((s = getsend(argv[i])) == 0) { 37932144Sminshall fprintf(stderr, "Telnet 'send' error - argument disappeared!\n"); 38032144Sminshall quit(); 38132144Sminshall /*NOTREACHED*/ 38232144Sminshall } 38338689Sborman if (s->handler) { 38438689Sborman (*s->handler)(s); 38532144Sminshall } else { 38632144Sminshall switch (what = s->what) { 38732144Sminshall case SYNCH: 38832144Sminshall dosynch(); 38932144Sminshall break; 39032144Sminshall case SENDQUESTION: 39132144Sminshall for (s = Sendlist; s->name; s++) { 39238689Sborman if (s->help) 39338689Sborman printf("%-15s %s\n", s->name, s->help); 39432144Sminshall } 39532144Sminshall question = 1; 39632144Sminshall break; 39732144Sminshall case SENDESCAPE: 39832144Sminshall NETADD(escape); 39932144Sminshall break; 40032144Sminshall default: 40132144Sminshall NET2ADD(IAC, what); 40232144Sminshall break; 40332144Sminshall } 40432144Sminshall } 40532144Sminshall } 40632144Sminshall return !question; 40732144Sminshall } 40832144Sminshall 40932144Sminshall /* 41032144Sminshall * The following are the routines and data structures referred 41132144Sminshall * to by the arguments to the "toggle" command. 41232144Sminshall */ 41332144Sminshall 41432144Sminshall static 41532144Sminshall lclchars() 41632144Sminshall { 41732144Sminshall donelclchars = 1; 41832144Sminshall return 1; 41932144Sminshall } 42032144Sminshall 42132144Sminshall static 42232144Sminshall togdebug() 42332144Sminshall { 42432144Sminshall #ifndef NOT43 42532144Sminshall if (net > 0 && 42632144Sminshall (SetSockOpt(net, SOL_SOCKET, SO_DEBUG, debug)) < 0) { 42732144Sminshall perror("setsockopt (SO_DEBUG)"); 42832144Sminshall } 42932144Sminshall #else /* NOT43 */ 43032144Sminshall if (debug) { 43132144Sminshall if (net > 0 && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 0, 0) < 0) 43232144Sminshall perror("setsockopt (SO_DEBUG)"); 43332144Sminshall } else 43432144Sminshall printf("Cannot turn off socket debugging\n"); 43532144Sminshall #endif /* NOT43 */ 43632144Sminshall return 1; 43732144Sminshall } 43832144Sminshall 43932144Sminshall 44032144Sminshall static int 44132144Sminshall togcrlf() 44232144Sminshall { 44332144Sminshall if (crlf) { 44432144Sminshall printf("Will send carriage returns as telnet <CR><LF>.\n"); 44532144Sminshall } else { 44632144Sminshall printf("Will send carriage returns as telnet <CR><NUL>.\n"); 44732144Sminshall } 44832144Sminshall return 1; 44932144Sminshall } 45032144Sminshall 45138909Sborman int binmode; 45232144Sminshall 45332144Sminshall static int 45438689Sborman togbinary(val) 45538689Sborman int val; 45632144Sminshall { 45732144Sminshall donebinarytoggle = 1; 45832144Sminshall 45938909Sborman if (val >= 0) { 46038909Sborman binmode = val; 46138909Sborman } else { 46238909Sborman if (my_want_state_is_will(TELOPT_BINARY) && 46338909Sborman my_want_state_is_do(TELOPT_BINARY)) { 46438909Sborman binmode = 1; 46538909Sborman } else if (my_want_state_is_wont(TELOPT_BINARY) && 46638909Sborman my_want_state_is_dont(TELOPT_BINARY)) { 46738909Sborman binmode = 0; 46838909Sborman } 46938909Sborman val = binmode ? 0 : 1; 47038909Sborman } 47138909Sborman 47238909Sborman if (val == 1) { 47338909Sborman if (my_want_state_is_will(TELOPT_BINARY) && 47438909Sborman my_want_state_is_do(TELOPT_BINARY)) { 47538689Sborman printf("Already operating in binary mode with remote host.\n"); 47638909Sborman } else { 47738909Sborman printf("Negotiating binary mode with remote host.\n"); 47838909Sborman tel_enter_binary(3); 47938689Sborman } 48038909Sborman } else { 48138909Sborman if (my_want_state_is_wont(TELOPT_BINARY) && 48238909Sborman my_want_state_is_dont(TELOPT_BINARY)) { 48338689Sborman printf("Already in network ascii mode with remote host.\n"); 48438909Sborman } else { 48538909Sborman printf("Negotiating network ascii mode with remote host.\n"); 48638909Sborman tel_leave_binary(3); 48738689Sborman } 48832144Sminshall } 48932144Sminshall return 1; 49032144Sminshall } 49132144Sminshall 49238909Sborman static int 49338909Sborman togrbinary(val) 49438909Sborman int val; 49538909Sborman { 49638909Sborman donebinarytoggle = 1; 49732144Sminshall 49838909Sborman if (val == -1) 49938909Sborman val = my_want_state_is_do(TELOPT_BINARY) ? 0 : 1; 50032144Sminshall 50138909Sborman if (val == 1) { 50238909Sborman if (my_want_state_is_do(TELOPT_BINARY)) { 50338909Sborman printf("Already receiving in binary mode.\n"); 50438909Sborman } else { 50538909Sborman printf("Negotiating binary mode on input.\n"); 50638909Sborman tel_enter_binary(1); 50738909Sborman } 50838909Sborman } else { 50938909Sborman if (my_want_state_is_dont(TELOPT_BINARY)) { 51038909Sborman printf("Already receiving in network ascii mode.\n"); 51138909Sborman } else { 51238909Sborman printf("Negotiating network ascii mode on input.\n"); 51338909Sborman tel_leave_binary(1); 51438909Sborman } 51538909Sborman } 51638909Sborman return 1; 51738909Sborman } 51838909Sborman 51938909Sborman static int 52038909Sborman togxbinary(val) 52138909Sborman int val; 52238909Sborman { 52338909Sborman donebinarytoggle = 1; 52438909Sborman 52538909Sborman if (val == -1) 52638909Sborman val = my_want_state_is_will(TELOPT_BINARY) ? 0 : 1; 52738909Sborman 52838909Sborman if (val == 1) { 52938909Sborman if (my_want_state_is_will(TELOPT_BINARY)) { 53038909Sborman printf("Already transmitting in binary mode.\n"); 53138909Sborman } else { 53238909Sborman printf("Negotiating binary mode on output.\n"); 53338909Sborman tel_enter_binary(2); 53438909Sborman } 53538909Sborman } else { 53638909Sborman if (my_want_state_is_wont(TELOPT_BINARY)) { 53738909Sborman printf("Already transmitting in network ascii mode.\n"); 53838909Sborman } else { 53938909Sborman printf("Negotiating network ascii mode on output.\n"); 54038909Sborman tel_leave_binary(2); 54138909Sborman } 54238909Sborman } 54338909Sborman return 1; 54438909Sborman } 54538909Sborman 54638909Sborman 54732144Sminshall extern int togglehelp(); 54838689Sborman extern int slc_check(); 54932144Sminshall 55032144Sminshall struct togglelist { 55132144Sminshall char *name; /* name of toggle */ 55232144Sminshall char *help; /* help message */ 55332144Sminshall int (*handler)(); /* routine to do actual setting */ 55432144Sminshall int *variable; 55532144Sminshall char *actionexplanation; 55632144Sminshall }; 55732144Sminshall 55832144Sminshall static struct togglelist Togglelist[] = { 55932144Sminshall { "autoflush", 56038689Sborman "flushing of output when sending interrupt characters", 56132144Sminshall 0, 56238689Sborman &autoflush, 56338689Sborman "flush output when sending interrupt characters" }, 56432144Sminshall { "autosynch", 56538689Sborman "automatic sending of interrupt characters in urgent mode", 56632144Sminshall 0, 56738689Sborman &autosynch, 56838689Sborman "send interrupt characters in urgent mode" }, 56932144Sminshall { "binary", 57038689Sborman "sending and receiving of binary data", 57132144Sminshall togbinary, 57238689Sborman 0, 57338689Sborman 0 }, 57438909Sborman { "inbinary", 57538909Sborman "receiving of binary data", 57638909Sborman togrbinary, 57738909Sborman 0, 57838909Sborman 0 }, 57938909Sborman { "outbinary", 58038909Sborman "sending of binary data", 58138909Sborman togxbinary, 58238909Sborman 0, 58338909Sborman 0 }, 58432144Sminshall { "crlf", 58538689Sborman "sending carriage returns as telnet <CR><LF>", 58632144Sminshall togcrlf, 58738689Sborman &crlf, 58838689Sborman 0 }, 58932144Sminshall { "crmod", 59038689Sborman "mapping of received carriage returns", 59132144Sminshall 0, 59238689Sborman &crmod, 59338689Sborman "map carriage return on output" }, 59432144Sminshall { "localchars", 59538689Sborman "local recognition of certain control characters", 59632144Sminshall lclchars, 59738689Sborman &localchars, 59838689Sborman "recognize certain control characters" }, 599*43317Skfall #ifdef KERBEROS 600*43317Skfall { "kerberos", 601*43317Skfall "toggle use of Kerberos authentication", 602*43317Skfall 0, 603*43317Skfall &kerberized, 604*43317Skfall "use Kerberos authentication" }, 605*43317Skfall #endif 60638689Sborman { " ", "", 0 }, /* empty line */ 60738208Sminshall #if defined(unix) && defined(TN3270) 60838920Sminshall { "apitrace", 60938920Sminshall "(debugging) toggle tracing of API transactions", 61038920Sminshall 0, 61138920Sminshall &apitrace, 61238920Sminshall "trace API transactions" }, 61338208Sminshall { "cursesdata", 61438208Sminshall "(debugging) toggle printing of hexadecimal curses data", 61538208Sminshall 0, 61638689Sborman &cursesdata, 61738689Sborman "print hexadecimal representation of curses data" }, 61838208Sminshall #endif /* defined(unix) && defined(TN3270) */ 61932144Sminshall { "debug", 62038689Sborman "debugging", 62132144Sminshall togdebug, 62238689Sborman &debug, 62338689Sborman "turn on socket level debugging" }, 62432144Sminshall { "netdata", 62538689Sborman "printing of hexadecimal network data (debugging)", 62632144Sminshall 0, 62738689Sborman &netdata, 62838689Sborman "print hexadecimal representation of network traffic" }, 62938689Sborman { "prettydump", 63038689Sborman "output of \"netdata\" to user readable format (debugging)", 63138689Sborman 0, 63238689Sborman &prettydump, 63338689Sborman "print user readable output for \"netdata\"" }, 63432144Sminshall { "options", 63538689Sborman "viewing of options processing (debugging)", 63632144Sminshall 0, 63738689Sborman &showoptions, 63838689Sborman "show option processing" }, 63938208Sminshall #if defined(unix) 64038208Sminshall { "termdata", 64138208Sminshall "(debugging) toggle printing of hexadecimal terminal data", 64238208Sminshall 0, 64338689Sborman &termdata, 64438689Sborman "print hexadecimal representation of terminal traffic" }, 64538208Sminshall #endif /* defined(unix) */ 64632144Sminshall { "?", 64738689Sborman 0, 64838689Sborman togglehelp }, 64932144Sminshall { "help", 65038689Sborman 0, 65138689Sborman togglehelp }, 65232144Sminshall { 0 } 65332144Sminshall }; 65432144Sminshall 65532144Sminshall static 65632144Sminshall togglehelp() 65732144Sminshall { 65832144Sminshall struct togglelist *c; 65932144Sminshall 66032144Sminshall for (c = Togglelist; c->name; c++) { 66138689Sborman if (c->help) { 66238689Sborman if (*c->help) 66338689Sborman printf("%-15s toggle %s\n", c->name, c->help); 66438689Sborman else 66538689Sborman printf("\n"); 66632144Sminshall } 66732144Sminshall } 66838689Sborman printf("\n"); 66938689Sborman printf("%-15s %s\n", "?", "display help information"); 67032144Sminshall return 0; 67132144Sminshall } 67232144Sminshall 67338689Sborman static 67438689Sborman settogglehelp(set) 67538689Sborman int set; 67638689Sborman { 67738689Sborman struct togglelist *c; 67838689Sborman 67938689Sborman for (c = Togglelist; c->name; c++) { 68038689Sborman if (c->help) { 68138689Sborman if (*c->help) 68238689Sborman printf("%-15s %s %s\n", c->name, set ? "enable" : "disable", 68338689Sborman c->help); 68438689Sborman else 68538689Sborman printf("\n"); 68638689Sborman } 68738689Sborman } 68838689Sborman } 68938689Sborman 69032144Sminshall static char ** 69132144Sminshall getnexttoggle(name) 69232144Sminshall char *name; 69332144Sminshall { 69432144Sminshall struct togglelist *c = (struct togglelist *) name; 69532144Sminshall 69632144Sminshall return (char **) (c+1); 69732144Sminshall } 69832144Sminshall 69932144Sminshall static struct togglelist * 70032144Sminshall gettoggle(name) 70132144Sminshall char *name; 70232144Sminshall { 70332144Sminshall return (struct togglelist *) 70432144Sminshall genget(name, (char **) Togglelist, getnexttoggle); 70532144Sminshall } 70632144Sminshall 70732144Sminshall static 70832144Sminshall toggle(argc, argv) 70932144Sminshall int argc; 71032144Sminshall char *argv[]; 71132144Sminshall { 71232144Sminshall int retval = 1; 71332144Sminshall char *name; 71432144Sminshall struct togglelist *c; 71532144Sminshall 71632144Sminshall if (argc < 2) { 71732144Sminshall fprintf(stderr, 71832144Sminshall "Need an argument to 'toggle' command. 'toggle ?' for help.\n"); 71932144Sminshall return 0; 72032144Sminshall } 72132144Sminshall argc--; 72232144Sminshall argv++; 72332144Sminshall while (argc--) { 72432144Sminshall name = *argv++; 72532144Sminshall c = gettoggle(name); 72632144Sminshall if (Ambiguous(c)) { 72732144Sminshall fprintf(stderr, "'%s': ambiguous argument ('toggle ?' for help).\n", 72832144Sminshall name); 72932144Sminshall return 0; 73032144Sminshall } else if (c == 0) { 73132144Sminshall fprintf(stderr, "'%s': unknown argument ('toggle ?' for help).\n", 73232144Sminshall name); 73332144Sminshall return 0; 73432144Sminshall } else { 73532144Sminshall if (c->variable) { 73632144Sminshall *c->variable = !*c->variable; /* invert it */ 73732144Sminshall if (c->actionexplanation) { 73832144Sminshall printf("%s %s.\n", *c->variable? "Will" : "Won't", 73932144Sminshall c->actionexplanation); 74032144Sminshall } 74132144Sminshall } 74232144Sminshall if (c->handler) { 74338689Sborman retval &= (*c->handler)(-1); 74432144Sminshall } 74532144Sminshall } 74632144Sminshall } 74732144Sminshall return retval; 74832144Sminshall } 74932144Sminshall 75032144Sminshall /* 75132144Sminshall * The following perform the "set" command. 75232144Sminshall */ 75332144Sminshall 75438689Sborman #ifdef USE_TERMIO 75538689Sborman struct termio new_tc = { 0 }; 75638689Sborman #endif 75738689Sborman 75832144Sminshall struct setlist { 75932144Sminshall char *name; /* name */ 76032144Sminshall char *help; /* help information */ 76138689Sborman void (*handler)(); 76240245Sborman cc_t *charp; /* where it is located at */ 76332144Sminshall }; 76432144Sminshall 76532144Sminshall static struct setlist Setlist[] = { 76638689Sborman { "echo", "character to toggle local echoing on/off", 0, &echoc }, 76738689Sborman { "escape", "character to escape back to telnet command mode", 0, &escape }, 76840245Sborman { "tracefile", "file to write trace intormation to", SetNetTrace, (cc_t *)NetTraceFile}, 76932144Sminshall { " ", "" }, 77038689Sborman { " ", "The following need 'localchars' to be toggled true", 0, 0 }, 77138689Sborman { "flushoutput", "character to cause an Abort Oubput", 0, termFlushCharp }, 77238689Sborman { "interrupt", "character to cause an Interrupt Process", 0, termIntCharp }, 77338689Sborman { "quit", "character to cause an Abort process", 0, termQuitCharp }, 77438689Sborman { "eof", "character to cause an EOF ", 0, termEofCharp }, 77538689Sborman { " ", "" }, 77638689Sborman { " ", "The following are for local editing in linemode", 0, 0 }, 77738689Sborman { "erase", "character to use to erase a character", 0, termEraseCharp }, 77838689Sborman { "kill", "character to use to erase a line", 0, termKillCharp }, 77938689Sborman { "lnext", "character to use for literal next", 0, termLiteralNextCharp }, 78038689Sborman { "susp", "character to cuase a Suspend Process", 0, termSuspCharp }, 78138689Sborman { "reprint", "character to use for line reprint", 0, termRprntCharp }, 78238689Sborman { "worderase", "character to use to erase a word", 0, termWerasCharp }, 78338689Sborman { "start", "character to use for XON", 0, termStartCharp }, 78438689Sborman { "stop", "character to sue for XOFF", 0, termStopCharp }, 78532144Sminshall { 0 } 78632144Sminshall }; 78732144Sminshall 78838689Sborman #ifdef CRAY 78938689Sborman /* Work around compiler bug */ 79038689Sborman _setlist_init() 79138689Sborman { 79239529Sborman Setlist[5].charp = &termFlushChar; 79338689Sborman Setlist[6].charp = &termIntChar; 79438689Sborman Setlist[7].charp = &termQuitChar; 79538689Sborman Setlist[8].charp = &termEofChar; 79638689Sborman Setlist[11].charp = &termEraseChar; 79738689Sborman Setlist[12].charp = &termKillChar; 79839529Sborman Setlist[13].charp = &termLiteralNextChar; 79939529Sborman Setlist[14].charp = &termSuspChar; 80039529Sborman Setlist[15].charp = &termRprntChar; 80139529Sborman Setlist[16].charp = &termWerasChar; 80239529Sborman Setlist[17].charp = &termStartChar; 80339529Sborman Setlist[18].charp = &termStopChar; 80438689Sborman } 80538810Sborman #endif /* CRAY */ 80638689Sborman 80732144Sminshall static char ** 80832144Sminshall getnextset(name) 80932144Sminshall char *name; 81032144Sminshall { 81132144Sminshall struct setlist *c = (struct setlist *)name; 81232144Sminshall 81332144Sminshall return (char **) (c+1); 81432144Sminshall } 81532144Sminshall 81632144Sminshall static struct setlist * 81732144Sminshall getset(name) 81832144Sminshall char *name; 81932144Sminshall { 82032144Sminshall return (struct setlist *) genget(name, (char **) Setlist, getnextset); 82132144Sminshall } 82232144Sminshall 82332144Sminshall static 82432144Sminshall setcmd(argc, argv) 82532144Sminshall int argc; 82632144Sminshall char *argv[]; 82732144Sminshall { 82832144Sminshall int value; 82932144Sminshall struct setlist *ct; 83038689Sborman struct togglelist *c; 83132144Sminshall 83238689Sborman if (argc < 2 || argc > 3) { 83338689Sborman printf("Format is 'set Name Value'\n'set ?' for help.\n"); 83432144Sminshall return 0; 83532144Sminshall } 83638689Sborman if ((argc == 2) && 83738689Sborman ((!strcmp(argv[1], "?")) || (!strcmp(argv[1], "help")))) { 83838689Sborman for (ct = Setlist; ct->name; ct++) 83938689Sborman printf("%-15s %s\n", ct->name, ct->help); 84038689Sborman printf("\n"); 84138689Sborman settogglehelp(1); 84238689Sborman printf("%-15s %s\n", "?", "display help information"); 84338689Sborman return 0; 84438689Sborman } 84532144Sminshall 84632144Sminshall ct = getset(argv[1]); 84732144Sminshall if (ct == 0) { 84838689Sborman c = gettoggle(argv[1]); 84938689Sborman if (c == 0) { 85038689Sborman fprintf(stderr, "'%s': unknown argument ('set ?' for help).\n", 85132144Sminshall argv[1]); 85238689Sborman return 0; 85338689Sborman } else if (Ambiguous(c)) { 85438689Sborman fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n", 85538689Sborman argv[1]); 85638689Sborman return 0; 85738689Sborman } 85838689Sborman if (c->variable) { 85938689Sborman if ((argc == 2) || (strcmp("on", argv[2]) == 0)) 86038689Sborman *c->variable = 1; 86138689Sborman else if (strcmp("off", argv[2]) == 0) 86238689Sborman *c->variable = 0; 86338689Sborman else { 86438689Sborman printf("Format is 'set togglename [on|off]'\n'set ?' for help.\n"); 86538689Sborman return 0; 86638689Sborman } 86738689Sborman if (c->actionexplanation) { 86838689Sborman printf("%s %s.\n", *c->variable? "Will" : "Won't", 86938689Sborman c->actionexplanation); 87038689Sborman } 87138689Sborman } 87238689Sborman if (c->handler) 87338689Sborman (*c->handler)(1); 87438689Sborman } else if (argc != 3) { 87538689Sborman printf("Format is 'set Name Value'\n'set ?' for help.\n"); 87632144Sminshall return 0; 87732144Sminshall } else if (Ambiguous(ct)) { 87832144Sminshall fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n", 87932144Sminshall argv[1]); 88032144Sminshall return 0; 88138689Sborman } else if (ct->handler) { 88238689Sborman (*ct->handler)(argv[2]); 88340245Sborman printf("%s set to \"%s\".\n", ct->name, (unsigned char *)ct->charp); 88432144Sminshall } else { 88532144Sminshall if (strcmp("off", argv[2])) { 88632144Sminshall value = special(argv[2]); 88732144Sminshall } else { 88832144Sminshall value = -1; 88932144Sminshall } 89040245Sborman *(ct->charp) = (cc_t)value; 89132144Sminshall printf("%s character is '%s'.\n", ct->name, control(*(ct->charp))); 89232144Sminshall } 89338689Sborman slc_check(); 89432144Sminshall return 1; 89532144Sminshall } 89638689Sborman 89738689Sborman static 89838689Sborman unsetcmd(argc, argv) 89938689Sborman int argc; 90038689Sborman char *argv[]; 90138689Sborman { 90238689Sborman int value; 90338689Sborman struct setlist *ct; 90438689Sborman struct togglelist *c; 90538689Sborman register char *name; 90638689Sborman 90738689Sborman if (argc < 2) { 90838689Sborman fprintf(stderr, 90938689Sborman "Need an argument to 'unset' command. 'unset ?' for help.\n"); 91038689Sborman return 0; 91138689Sborman } 91238689Sborman if ((!strcmp(argv[1], "?")) || (!strcmp(argv[1], "help"))) { 91338689Sborman for (ct = Setlist; ct->name; ct++) 91438689Sborman printf("%-15s %s\n", ct->name, ct->help); 91538689Sborman printf("\n"); 91638689Sborman settogglehelp(0); 91738689Sborman printf("%-15s %s\n", "?", "display help information"); 91838689Sborman return 0; 91938689Sborman } 92038689Sborman 92138689Sborman argc--; 92238689Sborman argv++; 92338689Sborman while (argc--) { 92438689Sborman name = *argv++; 92538689Sborman ct = getset(name); 92638689Sborman if (ct == 0) { 92738689Sborman c = gettoggle(name); 92838689Sborman if (c == 0) { 92938689Sborman fprintf(stderr, "'%s': unknown argument ('unset ?' for help).\n", 93038689Sborman name); 93138689Sborman return 0; 93238689Sborman } else if (Ambiguous(c)) { 93338689Sborman fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n", 93438689Sborman name); 93538689Sborman return 0; 93638689Sborman } 93738689Sborman if (c->variable) { 93838689Sborman *c->variable = 0; 93938689Sborman if (c->actionexplanation) { 94038689Sborman printf("%s %s.\n", *c->variable? "Will" : "Won't", 94138689Sborman c->actionexplanation); 94238689Sborman } 94338689Sborman } 94438689Sborman if (c->handler) 94538689Sborman (*c->handler)(0); 94638689Sborman } else if (Ambiguous(ct)) { 94738689Sborman fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n", 94838689Sborman name); 94938689Sborman return 0; 95038689Sborman } else if (ct->handler) { 95138689Sborman (*ct->handler)(0); 95238689Sborman printf("%s reset to \"%s\".\n", ct->name, ct->charp); 95338689Sborman } else { 95438689Sborman value = -1; 95538689Sborman *(ct->charp) = -1; 95638689Sborman printf("%s character is '%s'.\n", ct->name, control(*(ct->charp))); 95738689Sborman } 95838689Sborman } 95938689Sborman return 1; 96038689Sborman } 96132144Sminshall 96232144Sminshall /* 96332144Sminshall * The following are the data structures and routines for the 96432144Sminshall * 'mode' command. 96532144Sminshall */ 96638689Sborman #ifdef KLUDGELINEMODE 96738689Sborman extern int kludgelinemode; 96838689Sborman #endif 96932144Sminshall 97032144Sminshall static 97132144Sminshall dolinemode() 97232144Sminshall { 97338689Sborman #ifdef KLUDGELINEMODE 97438689Sborman if (kludgelinemode) 97538689Sborman send_dont(TELOPT_SGA, 1); 97638689Sborman #endif 97738689Sborman send_will(TELOPT_LINEMODE, 1); 97838689Sborman send_dont(TELOPT_ECHO, 1); 97932144Sminshall return 1; 98032144Sminshall } 98132144Sminshall 98232144Sminshall static 98332144Sminshall docharmode() 98432144Sminshall { 98538689Sborman #ifdef KLUDGELINEMODE 98638689Sborman if (kludgelinemode) 98738689Sborman send_do(TELOPT_SGA, 1); 98838689Sborman else 98938689Sborman #endif 99038689Sborman send_wont(TELOPT_LINEMODE, 1); 99138689Sborman send_do(TELOPT_ECHO, 1); 99238689Sborman return 1; 99338689Sborman } 99438689Sborman 99538689Sborman setmode(bit) 99638689Sborman { 99738689Sborman return dolmmode(bit, 1); 99838689Sborman } 99938689Sborman 100038689Sborman clearmode(bit) 100138689Sborman { 100238689Sborman return dolmmode(bit, 0); 100338689Sborman } 100438689Sborman 100538689Sborman dolmmode(bit, on) 100638689Sborman int bit, on; 100738689Sborman { 100838689Sborman char c; 100938689Sborman extern int linemode; 101038689Sborman 101138689Sborman if (my_want_state_is_wont(TELOPT_LINEMODE)) { 101238689Sborman printf("?Need to have LINEMODE option enabled first.\n"); 101338689Sborman printf("'mode ?' for help.\n"); 101438689Sborman return 0; 101532144Sminshall } 101638689Sborman 101738689Sborman if (on) 101838689Sborman c = (linemode | bit); 101938689Sborman else 102038689Sborman c = (linemode & ~bit); 102138689Sborman lm_mode(&c, 1, 1); 102232144Sminshall return 1; 102332144Sminshall } 102432144Sminshall 102538689Sborman struct modelist { 102638689Sborman char *name; /* command name */ 102738689Sborman char *help; /* help string */ 102838689Sborman int (*handler)(); /* routine which executes command */ 102938689Sborman int needconnect; /* Do we need to be connected to execute? */ 103038689Sborman int arg1; 103138689Sborman }; 103238689Sborman 103338689Sborman extern int modehelp(); 103438689Sborman 103538689Sborman static struct modelist ModeList[] = { 103638689Sborman { "character", "Disable LINEMODE option", docharmode, 1 }, 103739529Sborman #ifdef KLUDGELINEMODE 103839529Sborman { "", "(or disable obsolete line-by-line mode)", 0 }, 103938689Sborman #endif 104038689Sborman { "line", "Enable LINEMODE option", dolinemode, 1 }, 104139529Sborman #ifdef KLUDGELINEMODE 104239529Sborman { "", "(or enable obsolete line-by-line mode)", 0 }, 104338689Sborman #endif 104438689Sborman { "", "", 0 }, 104538689Sborman { "", "These require the LINEMODE option to be enabled", 0 }, 104638689Sborman { "isig", "Enable signal trapping", setmode, 1, MODE_TRAPSIG }, 104738689Sborman { "+isig", 0, setmode, 1, MODE_TRAPSIG }, 104838689Sborman { "-isig", "Disable signal trapping", clearmode, 1, MODE_TRAPSIG }, 104938689Sborman { "edit", "Enable character editing", setmode, 1, MODE_EDIT }, 105038689Sborman { "+edit", 0, setmode, 1, MODE_EDIT }, 105138689Sborman { "-edit", "Disable character editing", clearmode, 1, MODE_EDIT }, 105238689Sborman { "help", 0, modehelp, 0 }, 105338689Sborman { "?", "Print help information", modehelp, 0 }, 105432144Sminshall { 0 }, 105532144Sminshall }; 105632144Sminshall 105732144Sminshall static char ** 105832144Sminshall getnextmode(name) 105932144Sminshall char *name; 106032144Sminshall { 106138689Sborman return (char **) (((struct modelist *)name)+1); 106232144Sminshall } 106332144Sminshall 106438689Sborman static struct modelist * 106532144Sminshall getmodecmd(name) 106632144Sminshall char *name; 106732144Sminshall { 106838689Sborman return (struct modelist *) genget(name, (char **) ModeList, getnextmode); 106932144Sminshall } 107032144Sminshall 107138689Sborman modehelp() 107238689Sborman { 107338689Sborman struct modelist *mt; 107438689Sborman 107538689Sborman printf("format is: 'mode Mode', where 'Mode' is one of:\n\n"); 107638689Sborman for (mt = ModeList; mt->name; mt++) { 107738689Sborman if (mt->help) { 107838689Sborman if (*mt->help) 107938689Sborman printf("%-15s %s\n", mt->name, mt->help); 108038689Sborman else 108138689Sborman printf("\n"); 108238689Sborman } 108338689Sborman } 108438689Sborman return 0; 108538689Sborman } 108638689Sborman 108732144Sminshall static 108832144Sminshall modecmd(argc, argv) 108932144Sminshall int argc; 109032144Sminshall char *argv[]; 109132144Sminshall { 109238689Sborman struct modelist *mt; 109332144Sminshall 109438689Sborman if (argc != 2) { 109538689Sborman printf("'mode' command requires an argument\n"); 109638689Sborman printf("'mode ?' for help.\n"); 109738689Sborman } else if ((mt = getmodecmd(argv[1])) == 0) { 109832144Sminshall fprintf(stderr, "Unknown mode '%s' ('mode ?' for help).\n", argv[1]); 109932144Sminshall } else if (Ambiguous(mt)) { 110032144Sminshall fprintf(stderr, "Ambiguous mode '%s' ('mode ?' for help).\n", argv[1]); 110138689Sborman } else if (mt->needconnect && !connected) { 110238689Sborman printf("?Need to be connected first.\n"); 110338689Sborman printf("'mode ?' for help.\n"); 110438689Sborman } else if (mt->handler) { 110538689Sborman return (*mt->handler)(mt->arg1); 110632144Sminshall } 110738689Sborman return 0; 110832144Sminshall } 110932144Sminshall 111032144Sminshall /* 111132144Sminshall * The following data structures and routines implement the 111232144Sminshall * "display" command. 111332144Sminshall */ 111432144Sminshall 111532144Sminshall static 111632144Sminshall display(argc, argv) 111732144Sminshall int argc; 111832144Sminshall char *argv[]; 111932144Sminshall { 112032144Sminshall #define dotog(tl) if (tl->variable && tl->actionexplanation) { \ 112132144Sminshall if (*tl->variable) { \ 112232144Sminshall printf("will"); \ 112332144Sminshall } else { \ 112432144Sminshall printf("won't"); \ 112532144Sminshall } \ 112632144Sminshall printf(" %s.\n", tl->actionexplanation); \ 112732144Sminshall } 112832144Sminshall 112932144Sminshall #define doset(sl) if (sl->name && *sl->name != ' ') { \ 113038689Sborman if (sl->handler == 0) \ 113138689Sborman printf("%-15s [%s]\n", sl->name, control(*sl->charp)); \ 113238689Sborman else \ 113338689Sborman printf("%-15s \"%s\"\n", sl->name, sl->charp); \ 113432144Sminshall } 113532144Sminshall 113632144Sminshall struct togglelist *tl; 113732144Sminshall struct setlist *sl; 113832144Sminshall 113932144Sminshall if (argc == 1) { 114032144Sminshall for (tl = Togglelist; tl->name; tl++) { 114132144Sminshall dotog(tl); 114232144Sminshall } 114332144Sminshall printf("\n"); 114432144Sminshall for (sl = Setlist; sl->name; sl++) { 114532144Sminshall doset(sl); 114632144Sminshall } 114732144Sminshall } else { 114832144Sminshall int i; 114932144Sminshall 115032144Sminshall for (i = 1; i < argc; i++) { 115132144Sminshall sl = getset(argv[i]); 115232144Sminshall tl = gettoggle(argv[i]); 115332144Sminshall if (Ambiguous(sl) || Ambiguous(tl)) { 115432144Sminshall printf("?Ambiguous argument '%s'.\n", argv[i]); 115532144Sminshall return 0; 115632144Sminshall } else if (!sl && !tl) { 115732144Sminshall printf("?Unknown argument '%s'.\n", argv[i]); 115832144Sminshall return 0; 115932144Sminshall } else { 116032144Sminshall if (tl) { 116132144Sminshall dotog(tl); 116232144Sminshall } 116332144Sminshall if (sl) { 116432144Sminshall doset(sl); 116532144Sminshall } 116632144Sminshall } 116732144Sminshall } 116832144Sminshall } 116938689Sborman /*@*/optionstatus(); 117032144Sminshall return 1; 117132144Sminshall #undef doset 117232144Sminshall #undef dotog 117332144Sminshall } 117432144Sminshall 117532144Sminshall /* 117632144Sminshall * The following are the data structures, and many of the routines, 117732144Sminshall * relating to command processing. 117832144Sminshall */ 117932144Sminshall 118032144Sminshall /* 118132144Sminshall * Set the escape character. 118232144Sminshall */ 118332144Sminshall static 118432144Sminshall setescape(argc, argv) 118532144Sminshall int argc; 118632144Sminshall char *argv[]; 118732144Sminshall { 118832144Sminshall register char *arg; 118932144Sminshall char buf[50]; 119032144Sminshall 119132144Sminshall printf( 119232144Sminshall "Deprecated usage - please use 'set escape%s%s' in the future.\n", 119332144Sminshall (argc > 2)? " ":"", (argc > 2)? argv[1]: ""); 119432144Sminshall if (argc > 2) 119532144Sminshall arg = argv[1]; 119632144Sminshall else { 119732144Sminshall printf("new escape character: "); 119834849Sminshall (void) gets(buf); 119932144Sminshall arg = buf; 120032144Sminshall } 120132144Sminshall if (arg[0] != '\0') 120232144Sminshall escape = arg[0]; 120332144Sminshall if (!In3270) { 120432144Sminshall printf("Escape character is '%s'.\n", control(escape)); 120532144Sminshall } 120634849Sminshall (void) fflush(stdout); 120732144Sminshall return 1; 120832144Sminshall } 120932144Sminshall 121032144Sminshall /*VARARGS*/ 121132144Sminshall static 121232144Sminshall togcrmod() 121332144Sminshall { 121432144Sminshall crmod = !crmod; 121532144Sminshall printf("Deprecated usage - please use 'toggle crmod' in the future.\n"); 121632144Sminshall printf("%s map carriage return on output.\n", crmod ? "Will" : "Won't"); 121734849Sminshall (void) fflush(stdout); 121832144Sminshall return 1; 121932144Sminshall } 122032144Sminshall 122132144Sminshall /*VARARGS*/ 122232144Sminshall suspend() 122332144Sminshall { 122438689Sborman #ifdef SIGTSTP 122537219Sminshall setcommandmode(); 122637219Sminshall { 122737219Sminshall long oldrows, oldcols, newrows, newcols; 122837219Sminshall 122937219Sminshall TerminalWindowSize(&oldrows, &oldcols); 123034849Sminshall (void) kill(0, SIGTSTP); 123137219Sminshall TerminalWindowSize(&newrows, &newcols); 123237219Sminshall if ((oldrows != newrows) || (oldcols != newcols)) { 123337219Sminshall if (connected) { 123437219Sminshall sendnaws(); 123537219Sminshall } 123637219Sminshall } 123737219Sminshall } 123837219Sminshall /* reget parameters in case they were changed */ 123937219Sminshall TerminalSaveState(); 124038689Sborman setconnmode(0); 124138689Sborman #else 124238689Sborman printf("Suspend is not supported. Try the '!' command instead\n"); 124338689Sborman #endif 124437219Sminshall return 1; 124532144Sminshall } 124632144Sminshall 124738689Sborman #if !defined(TN3270) 124838689Sborman shell(argc, argv) 124938689Sborman int argc; 125038689Sborman char *argv[]; 125138689Sborman { 125238689Sborman extern char *rindex(); 125338689Sborman char cmdbuf[256]; 125438689Sborman 125538689Sborman setcommandmode(); 125638689Sborman switch(vfork()) { 125738689Sborman case -1: 125838689Sborman perror("Fork failed\n"); 125938689Sborman break; 126038689Sborman 126138689Sborman case 0: 126238689Sborman { 126338689Sborman /* 126438689Sborman * Fire up the shell in the child. 126538689Sborman */ 126638689Sborman register char *shell, *shellname; 126738689Sborman 126838689Sborman shell = getenv("SHELL"); 126938689Sborman if (shell == NULL) 127038689Sborman shell = "/bin/sh"; 127138689Sborman if ((shellname = rindex(shell, '/')) == 0) 127238689Sborman shellname = shell; 127338689Sborman else 127438689Sborman shellname++; 127538689Sborman if (argc > 1) 127638689Sborman execl(shell, shellname, "-c", &saveline[1], 0); 127738689Sborman else 127838689Sborman execl(shell, shellname, 0); 127938689Sborman perror("Execl"); 128038689Sborman _exit(1); 128138689Sborman } 128238689Sborman default: 128338689Sborman wait((int *)0); /* Wait for the shell to complete */ 128438689Sborman } 128538689Sborman } 128638689Sborman #endif /* !defined(TN3270) */ 128738689Sborman 128832144Sminshall /*VARARGS*/ 128932144Sminshall static 129032144Sminshall bye(argc, argv) 129132144Sminshall int argc; /* Number of arguments */ 129232144Sminshall char *argv[]; /* arguments */ 129332144Sminshall { 129432144Sminshall if (connected) { 129534849Sminshall (void) shutdown(net, 2); 129632144Sminshall printf("Connection closed.\n"); 129734849Sminshall (void) NetClose(net); 129832144Sminshall connected = 0; 129932144Sminshall /* reset options */ 130032144Sminshall tninit(); 130132144Sminshall #if defined(TN3270) 130232144Sminshall SetIn3270(); /* Get out of 3270 mode */ 130332144Sminshall #endif /* defined(TN3270) */ 130432144Sminshall } 130532144Sminshall if ((argc != 2) || (strcmp(argv[1], "fromquit") != 0)) { 130632144Sminshall longjmp(toplevel, 1); 130732144Sminshall /* NOTREACHED */ 130832144Sminshall } 130932144Sminshall return 1; /* Keep lint, etc., happy */ 131032144Sminshall } 131132144Sminshall 131232144Sminshall /*VARARGS*/ 131332144Sminshall quit() 131432144Sminshall { 131532144Sminshall (void) call(bye, "bye", "fromquit", 0); 131632144Sminshall Exit(0); 131732144Sminshall return 1; /* just to keep lint happy */ 131832144Sminshall } 131938689Sborman 132038689Sborman /* 132138689Sborman * The SLC command. 132238689Sborman */ 132332144Sminshall 132438689Sborman struct slclist { 132538689Sborman char *name; 132638689Sborman char *help; 132738689Sborman int (*handler)(); 132838689Sborman int arg; 132938689Sborman }; 133038689Sborman 133138689Sborman extern int slc_help(); 133238689Sborman extern int slc_mode_export(), slc_mode_import(), slcstate(); 133338689Sborman 133438689Sborman struct slclist SlcList[] = { 133538689Sborman { "export", "Use local special character definitions", 133638689Sborman slc_mode_export, 0 }, 133738689Sborman { "import", "Use remote special character definitions", 133838689Sborman slc_mode_import, 1 }, 133938689Sborman { "check", "Verify remote special character definitions", 134038689Sborman slc_mode_import, 0 }, 134138689Sborman { "help", 0, slc_help, 0 }, 134238689Sborman { "?", "Print help information", slc_help, 0 }, 134338689Sborman { 0 }, 134438689Sborman }; 134538689Sborman 134638689Sborman static 134738689Sborman slc_help() 134838689Sborman { 134938689Sborman struct slclist *c; 135038689Sborman 135138689Sborman for (c = SlcList; c->name; c++) { 135238689Sborman if (c->help) { 135338689Sborman if (*c->help) 135438689Sborman printf("%-15s %s\n", c->name, c->help); 135538689Sborman else 135638689Sborman printf("\n"); 135738689Sborman } 135838689Sborman } 135938689Sborman } 136038689Sborman 136138689Sborman static char ** 136238689Sborman getnextslc(name) 136338689Sborman char *name; 136438689Sborman { 136538689Sborman return (char **)(((struct slclist *)name)+1); 136638689Sborman } 136738689Sborman 136838689Sborman static struct slclist * 136938689Sborman getslc(name) 137038689Sborman char *name; 137138689Sborman { 137238689Sborman return (struct slclist *)genget(name, (char **) SlcList, getnextslc); 137338689Sborman } 137438689Sborman 137538689Sborman static 137638689Sborman slccmd(argc, argv) 137738689Sborman int argc; 137838689Sborman char *argv[]; 137938689Sborman { 138038689Sborman struct slclist *c; 138138689Sborman 138238689Sborman if (argc != 2) { 138338689Sborman fprintf(stderr, 138438689Sborman "Need an argument to 'slc' command. 'slc ?' for help.\n"); 138538689Sborman return 0; 138638689Sborman } 138738689Sborman c = getslc(argv[1]); 138838689Sborman if (c == 0) { 138938689Sborman fprintf(stderr, "'%s': unknown argument ('slc ?' for help).\n", 139038689Sborman argv[1]); 139138689Sborman return 0; 139238689Sborman } 139338689Sborman if (Ambiguous(c)) { 139438689Sborman fprintf(stderr, "'%s': ambiguous argument ('slc ?' for help).\n", 139538689Sborman argv[1]); 139638689Sborman return 0; 139738689Sborman } 139838689Sborman (*c->handler)(c->arg); 139938689Sborman slcstate(); 140038689Sborman return 1; 140138689Sborman } 140238689Sborman 140336274Sminshall #if defined(unix) 140432144Sminshall /* 140536274Sminshall * Some information about our file descriptors. 140636274Sminshall */ 140736274Sminshall 140836274Sminshall char * 140936274Sminshall decodeflags(mask) 141036274Sminshall int mask; 141136274Sminshall { 141236274Sminshall static char buffer[100]; 141336274Sminshall #define do(m,s) \ 141436274Sminshall if (mask&(m)) { \ 141536274Sminshall strcat(buffer, (s)); \ 141636274Sminshall } 141736274Sminshall 141836274Sminshall buffer[0] = 0; /* Terminate it */ 141936274Sminshall 142036274Sminshall #ifdef FREAD 142136274Sminshall do(FREAD, " FREAD"); 142236274Sminshall #endif 142336274Sminshall #ifdef FWRITE 142436274Sminshall do(FWRITE, " FWRITE"); 142536274Sminshall #endif 142636274Sminshall #ifdef F_DUPFP 142736274Sminshall do(F_DUPFD, " F_DUPFD"); 142836274Sminshall #endif 142936274Sminshall #ifdef FNDELAY 143036274Sminshall do(FNDELAY, " FNDELAY"); 143136274Sminshall #endif 143236274Sminshall #ifdef FAPPEND 143336274Sminshall do(FAPPEND, " FAPPEND"); 143436274Sminshall #endif 143536274Sminshall #ifdef FMARK 143636274Sminshall do(FMARK, " FMARK"); 143736274Sminshall #endif 143836274Sminshall #ifdef FDEFER 143936274Sminshall do(FDEFER, " FDEFER"); 144036274Sminshall #endif 144136274Sminshall #ifdef FASYNC 144236274Sminshall do(FASYNC, " FASYNC"); 144336274Sminshall #endif 144436274Sminshall #ifdef FSHLOCK 144536274Sminshall do(FSHLOCK, " FSHLOCK"); 144636274Sminshall #endif 144736274Sminshall #ifdef FEXLOCK 144836274Sminshall do(FEXLOCK, " FEXLOCK"); 144936274Sminshall #endif 145036274Sminshall #ifdef FCREAT 145136274Sminshall do(FCREAT, " FCREAT"); 145236274Sminshall #endif 145336274Sminshall #ifdef FTRUNC 145436274Sminshall do(FTRUNC, " FTRUNC"); 145536274Sminshall #endif 145636274Sminshall #ifdef FEXCL 145736274Sminshall do(FEXCL, " FEXCL"); 145836274Sminshall #endif 145936274Sminshall 146036274Sminshall return buffer; 146136274Sminshall } 146236274Sminshall #undef do 146336274Sminshall 146436274Sminshall static void 146536274Sminshall filestuff(fd) 146636274Sminshall int fd; 146736274Sminshall { 146836274Sminshall int res; 146936274Sminshall 147038689Sborman #ifdef F_GETOWN 147138689Sborman setconnmode(0); 147236274Sminshall res = fcntl(fd, F_GETOWN, 0); 147336274Sminshall setcommandmode(); 147436274Sminshall 147536274Sminshall if (res == -1) { 147636274Sminshall perror("fcntl"); 147736274Sminshall return; 147836274Sminshall } 147936274Sminshall printf("\tOwner is %d.\n", res); 148038689Sborman #endif 148136274Sminshall 148238689Sborman setconnmode(0); 148336274Sminshall res = fcntl(fd, F_GETFL, 0); 148436274Sminshall setcommandmode(); 148536274Sminshall 148636274Sminshall if (res == -1) { 148736274Sminshall perror("fcntl"); 148836274Sminshall return; 148936274Sminshall } 149036274Sminshall printf("\tFlags are 0x%x: %s\n", res, decodeflags(res)); 149136274Sminshall } 149236274Sminshall 149336274Sminshall 149436274Sminshall #endif /* defined(unix) */ 149536274Sminshall 149636274Sminshall /* 149732144Sminshall * Print status about the connection. 149832144Sminshall */ 149934849Sminshall /*ARGSUSED*/ 150032144Sminshall static 150132144Sminshall status(argc, argv) 150232144Sminshall int argc; 150332144Sminshall char *argv[]; 150432144Sminshall { 150532144Sminshall if (connected) { 150632144Sminshall printf("Connected to %s.\n", hostname); 150736242Sminshall if ((argc < 2) || strcmp(argv[1], "notmuch")) { 150838689Sborman int mode = getconnmode(); 150938689Sborman 151038689Sborman if (my_want_state_is_will(TELOPT_LINEMODE)) { 151138689Sborman printf("Operating with LINEMODE option\n"); 151238689Sborman printf("%s line editing\n", (mode&MODE_EDIT) ? "Local" : "No"); 151338689Sborman printf("%s catching of signals\n", 151438689Sborman (mode&MODE_TRAPSIG) ? "Local" : "No"); 151538689Sborman slcstate(); 151638689Sborman #ifdef KLUDGELINEMODE 151739529Sborman } else if (kludgelinemode && my_want_state_is_dont(TELOPT_SGA)) { 151838689Sborman printf("Operating in obsolete linemode\n"); 151938689Sborman #endif 152038689Sborman } else { 152138689Sborman printf("Operating in single character mode\n"); 152238689Sborman if (localchars) 152338689Sborman printf("Catching signals locally\n"); 152432144Sminshall } 152538689Sborman printf("%s character echo\n", (mode&MODE_ECHO) ? "Local" : "Remote"); 152638689Sborman if (my_want_state_is_will(TELOPT_LFLOW)) 152738689Sborman printf("%s flow control\n", (mode&MODE_FLOW) ? "Local" : "No"); 152832144Sminshall } 152932144Sminshall } else { 153032144Sminshall printf("No connection.\n"); 153132144Sminshall } 153232144Sminshall # if !defined(TN3270) 153332144Sminshall printf("Escape character is '%s'.\n", control(escape)); 153434849Sminshall (void) fflush(stdout); 153532144Sminshall # else /* !defined(TN3270) */ 153632144Sminshall if ((!In3270) && ((argc < 2) || strcmp(argv[1], "notmuch"))) { 153732144Sminshall printf("Escape character is '%s'.\n", control(escape)); 153832144Sminshall } 153932144Sminshall # if defined(unix) 154036242Sminshall if ((argc >= 2) && !strcmp(argv[1], "everything")) { 154136242Sminshall printf("SIGIO received %d time%s.\n", 154236242Sminshall sigiocount, (sigiocount == 1)? "":"s"); 154336274Sminshall if (In3270) { 154436274Sminshall printf("Process ID %d, process group %d.\n", 154536274Sminshall getpid(), getpgrp(getpid())); 154636274Sminshall printf("Terminal input:\n"); 154736274Sminshall filestuff(tin); 154836274Sminshall printf("Terminal output:\n"); 154936274Sminshall filestuff(tout); 155036274Sminshall printf("Network socket:\n"); 155136274Sminshall filestuff(net); 155236274Sminshall } 155336242Sminshall } 155432144Sminshall if (In3270 && transcom) { 155532144Sminshall printf("Transparent mode command is '%s'.\n", transcom); 155632144Sminshall } 155732144Sminshall # endif /* defined(unix) */ 155834849Sminshall (void) fflush(stdout); 155932144Sminshall if (In3270) { 156032144Sminshall return 0; 156132144Sminshall } 156232144Sminshall # endif /* defined(TN3270) */ 156332144Sminshall return 1; 156432144Sminshall } 156532144Sminshall 156632144Sminshall 156740248Sborman #if defined(NEED_GETTOS) 156840245Sborman struct tosent { 156940245Sborman char *t_name; /* name */ 157040245Sborman char **t_aliases; /* alias list */ 157140245Sborman char *t_proto; /* protocol */ 157240245Sborman int t_tos; /* Type Of Service bits */ 157340245Sborman }; 157432144Sminshall 157540245Sborman struct tosent * 157640245Sborman gettosbyname(name, proto) 157740245Sborman char *name, *proto; 157840245Sborman { 157940245Sborman static struct tosent te; 158040245Sborman static char *aliasp = 0; 158140245Sborman 158240245Sborman te.t_name = name; 158340245Sborman te.t_aliases = &aliasp; 158440245Sborman te.t_proto = proto; 158540245Sborman te.t_tos = 020; /* Low Delay bit */ 158640245Sborman return(&te); 158740245Sborman } 158840245Sborman #endif 158940245Sborman 159032144Sminshall int 159132144Sminshall tn(argc, argv) 159232144Sminshall int argc; 159332144Sminshall char *argv[]; 159432144Sminshall { 159532144Sminshall register struct hostent *host = 0; 159632144Sminshall struct sockaddr_in sin; 159732144Sminshall struct servent *sp = 0; 159832144Sminshall static char hnamebuf[32]; 159938689Sborman unsigned long temp, inet_addr(); 160037219Sminshall extern char *inet_ntoa(); 160138689Sborman #if defined(SRCRT) && defined(IPPROTO_IP) 160238689Sborman char *srp = 0, *strrchr(); 160338689Sborman unsigned long sourceroute(), srlen; 160438689Sborman #endif 160540248Sborman #if defined(HAS_IP_TOS) || defined(NEED_GETTOS) 160640245Sborman struct tosent *tp; 160740248Sborman #endif /* defined(HAS_IP_TOS) || defined(NEED_GETTOS) */ 160832144Sminshall 160932144Sminshall 161032144Sminshall if (connected) { 161132144Sminshall printf("?Already connected to %s\n", hostname); 161232144Sminshall return 0; 161332144Sminshall } 161432144Sminshall if (argc < 2) { 161532144Sminshall (void) strcpy(line, "Connect "); 161632144Sminshall printf("(to) "); 161734849Sminshall (void) gets(&line[strlen(line)]); 161832144Sminshall makeargv(); 161932144Sminshall argc = margc; 162032144Sminshall argv = margv; 162132144Sminshall } 162232144Sminshall if ((argc < 2) || (argc > 3)) { 162332144Sminshall printf("usage: %s host-name [port]\n", argv[0]); 162432144Sminshall return 0; 162532144Sminshall } 162638689Sborman #if defined(SRCRT) && defined(IPPROTO_IP) 162738689Sborman if (argv[1][0] == '@' || argv[1][0] == '!') { 162838689Sborman if ((hostname = strrchr(argv[1], ':')) == NULL) 162938689Sborman hostname = strrchr(argv[1], '@'); 163038689Sborman hostname++; 163138689Sborman srp = 0; 163238689Sborman temp = sourceroute(argv[1], &srp, &srlen); 163338689Sborman if (temp == 0) { 163438689Sborman herror(srp); 163538689Sborman return 0; 163638689Sborman } else if (temp == -1) { 163738689Sborman printf("Bad source route option: %s\n", argv[1]); 163838689Sborman return 0; 163938689Sborman } else { 164038689Sborman sin.sin_addr.s_addr = temp; 164138689Sborman sin.sin_family = AF_INET; 164238689Sborman } 164332144Sminshall } else { 164438689Sborman #endif 164538689Sborman temp = inet_addr(argv[1]); 164638689Sborman if (temp != (unsigned long) -1) { 164738689Sborman sin.sin_addr.s_addr = temp; 164838689Sborman sin.sin_family = AF_INET; 164938689Sborman (void) strcpy(hnamebuf, argv[1]); 165038689Sborman hostname = hnamebuf; 165138689Sborman } else { 165238689Sborman host = gethostbyname(argv[1]); 165338689Sborman if (host) { 165438689Sborman sin.sin_family = host->h_addrtype; 165532144Sminshall #if defined(h_addr) /* In 4.3, this is a #define */ 165638689Sborman memcpy((caddr_t)&sin.sin_addr, 165732144Sminshall host->h_addr_list[0], host->h_length); 165832144Sminshall #else /* defined(h_addr) */ 165938689Sborman memcpy((caddr_t)&sin.sin_addr, host->h_addr, host->h_length); 166032144Sminshall #endif /* defined(h_addr) */ 166138689Sborman hostname = host->h_name; 166238689Sborman } else { 166338689Sborman herror(argv[1]); 166438689Sborman return 0; 166538689Sborman } 166632144Sminshall } 166738689Sborman #if defined(SRCRT) && defined(IPPROTO_IP) 166832144Sminshall } 166938689Sborman #endif 167032144Sminshall if (argc == 3) { 167138689Sborman int tmp; 167238689Sborman 167338689Sborman if (*argv[2] == '-') { 167438689Sborman argv[2]++; 167538689Sborman telnetport = 1; 167638689Sborman } else 167738689Sborman telnetport = 0; 167832144Sminshall sin.sin_port = atoi(argv[2]); 167932144Sminshall if (sin.sin_port == 0) { 168032144Sminshall sp = getservbyname(argv[2], "tcp"); 168132144Sminshall if (sp) 168232144Sminshall sin.sin_port = sp->s_port; 168332144Sminshall else { 168432144Sminshall printf("%s: bad port number\n", argv[2]); 168532144Sminshall return 0; 168632144Sminshall } 168732144Sminshall } else { 168834849Sminshall #if !defined(htons) 168934849Sminshall u_short htons(); 169034849Sminshall #endif /* !defined(htons) */ 169132144Sminshall sin.sin_port = htons(sin.sin_port); 169232144Sminshall } 169332144Sminshall } else { 169432144Sminshall if (sp == 0) { 169532144Sminshall sp = getservbyname("telnet", "tcp"); 169632144Sminshall if (sp == 0) { 169734849Sminshall fprintf(stderr, "telnet: tcp/telnet: unknown service\n"); 169832144Sminshall return 0; 169932144Sminshall } 170032144Sminshall sin.sin_port = sp->s_port; 170132144Sminshall } 170232144Sminshall telnetport = 1; 170332144Sminshall } 170437219Sminshall printf("Trying %s...\n", inet_ntoa(sin.sin_addr)); 170532144Sminshall do { 170632144Sminshall net = socket(AF_INET, SOCK_STREAM, 0); 170732144Sminshall if (net < 0) { 170832144Sminshall perror("telnet: socket"); 170932144Sminshall return 0; 171032144Sminshall } 171138689Sborman #if defined(SRCRT) && defined(IPPROTO_IP) 171238689Sborman if (srp && setsockopt(net, IPPROTO_IP, IP_OPTIONS, (char *)srp, srlen) < 0) 171338689Sborman perror("setsockopt (IP_OPTIONS)"); 171438689Sborman #endif 171540248Sborman #if defined(HAS_IP_TOS) || defined(NEED_GETTOS) 171640245Sborman if ((tp = gettosbyname("telnet", "tcp")) && 171740245Sborman (setsockopt(net, IPPROTO_IP, IP_TOS, &tp->t_tos, sizeof(int)) < 0)) 171840245Sborman perror("telnet: setsockopt TOS (ignored)"); 171940248Sborman #endif /* defined(HAS_IP_TOS) || defined(NEED_GETTOS) */ 172040245Sborman 172132144Sminshall if (debug && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 1) < 0) { 172232144Sminshall perror("setsockopt (SO_DEBUG)"); 172332144Sminshall } 172432144Sminshall 172532144Sminshall if (connect(net, (struct sockaddr *)&sin, sizeof (sin)) < 0) { 172632144Sminshall #if defined(h_addr) /* In 4.3, this is a #define */ 172732144Sminshall if (host && host->h_addr_list[1]) { 172832144Sminshall int oerrno = errno; 172932144Sminshall 173032144Sminshall fprintf(stderr, "telnet: connect to address %s: ", 173132144Sminshall inet_ntoa(sin.sin_addr)); 173232144Sminshall errno = oerrno; 173332144Sminshall perror((char *)0); 173432144Sminshall host->h_addr_list++; 173532144Sminshall memcpy((caddr_t)&sin.sin_addr, 173632144Sminshall host->h_addr_list[0], host->h_length); 173732144Sminshall (void) NetClose(net); 173832144Sminshall continue; 173932144Sminshall } 174032144Sminshall #endif /* defined(h_addr) */ 174132144Sminshall perror("telnet: Unable to connect to remote host"); 174232144Sminshall return 0; 174337219Sminshall } 174432144Sminshall connected++; 174532144Sminshall } while (connected == 0); 174638689Sborman cmdrc(argv[1], hostname); 174734849Sminshall (void) call(status, "status", "notmuch", 0); 174832144Sminshall if (setjmp(peerdied) == 0) 174932144Sminshall telnet(); 175034849Sminshall (void) NetClose(net); 175132381Sminshall ExitString("Connection closed by foreign host.\n",1); 175232144Sminshall /*NOTREACHED*/ 175332144Sminshall } 175432144Sminshall 175532144Sminshall 175632144Sminshall #define HELPINDENT (sizeof ("connect")) 175732144Sminshall 175832144Sminshall static char 175932144Sminshall openhelp[] = "connect to a site", 176032144Sminshall closehelp[] = "close current connection", 176132144Sminshall quithelp[] = "exit telnet", 176232144Sminshall statushelp[] = "print status information", 176332144Sminshall helphelp[] = "print help information", 176432144Sminshall sendhelp[] = "transmit special characters ('send ?' for more)", 176532144Sminshall sethelp[] = "set operating parameters ('set ?' for more)", 176638689Sborman unsethelp[] = "unset operating parameters ('unset ?' for more)", 176732144Sminshall togglestring[] ="toggle operating parameters ('toggle ?' for more)", 176838689Sborman slchelp[] = "change state of special charaters ('slc ?' for more)", 176932144Sminshall displayhelp[] = "display operating parameters", 177032144Sminshall #if defined(TN3270) && defined(unix) 177132144Sminshall transcomhelp[] = "specify Unix command for transparent mode pipe", 177232144Sminshall #endif /* defined(TN3270) && defined(unix) */ 177332144Sminshall #if defined(unix) 177432144Sminshall zhelp[] = "suspend telnet", 1775*43317Skfall #endif /* defined(unix) */ 177632144Sminshall shellhelp[] = "invoke a subshell", 177738689Sborman modestring[] = "try to enter line-by-line or character-at-a-time mode"; 177832144Sminshall 177932144Sminshall extern int help(), shell(); 178032144Sminshall 178132144Sminshall static Command cmdtab[] = { 178238689Sborman { "close", closehelp, bye, 1 }, 178338689Sborman { "display", displayhelp, display, 0 }, 178438689Sborman { "mode", modestring, modecmd, 0 }, 178538689Sborman { "open", openhelp, tn, 0 }, 178638689Sborman { "quit", quithelp, quit, 0 }, 178738689Sborman { "send", sendhelp, sendcmd, 0 }, 178838689Sborman { "set", sethelp, setcmd, 0 }, 178938689Sborman { "unset", unsethelp, unsetcmd, 0 }, 179038689Sborman { "status", statushelp, status, 0 }, 179138689Sborman { "toggle", togglestring, toggle, 0 }, 179238689Sborman { "slc", slchelp, slccmd, 0 }, 179332144Sminshall #if defined(TN3270) && defined(unix) 179438689Sborman { "transcom", transcomhelp, settranscom, 0 }, 179532144Sminshall #endif /* defined(TN3270) && defined(unix) */ 179632144Sminshall #if defined(unix) 179738689Sborman { "z", zhelp, suspend, 0 }, 179832144Sminshall #endif /* defined(unix) */ 179932144Sminshall #if defined(TN3270) 180038689Sborman { "!", shellhelp, shell, 1 }, 180138689Sborman #else 180238689Sborman { "!", shellhelp, shell, 0 }, 180338689Sborman #endif 180438689Sborman { "?", helphelp, help, 0 }, 180532144Sminshall 0 180632144Sminshall }; 180732144Sminshall 180832144Sminshall static char crmodhelp[] = "deprecated command -- use 'toggle crmod' instead"; 180932144Sminshall static char escapehelp[] = "deprecated command -- use 'set escape' instead"; 181032144Sminshall 181132144Sminshall static Command cmdtab2[] = { 181238689Sborman { "help", 0, help, 0 }, 181338689Sborman { "escape", escapehelp, setescape, 0 }, 181438689Sborman { "crmod", crmodhelp, togcrmod, 0 }, 181532144Sminshall 0 181632144Sminshall }; 181732144Sminshall 181835298Sminshall 181932144Sminshall /* 182032144Sminshall * Call routine with argc, argv set from args (terminated by 0). 182132144Sminshall */ 182235298Sminshall 182335417Sminshall /*VARARGS1*/ 182432144Sminshall static 182535298Sminshall call(va_alist) 182635298Sminshall va_dcl 182732144Sminshall { 182835298Sminshall va_list ap; 182935298Sminshall typedef int (*intrtn_t)(); 183035298Sminshall intrtn_t routine; 183135298Sminshall char *args[100]; 183235298Sminshall int argno = 0; 183335298Sminshall 183435298Sminshall va_start(ap); 183535298Sminshall routine = (va_arg(ap, intrtn_t)); 183635495Sminshall while ((args[argno++] = va_arg(ap, char *)) != 0) { 183735298Sminshall ; 183835495Sminshall } 183935298Sminshall va_end(ap); 184035495Sminshall return (*routine)(argno-1, args); 184132144Sminshall } 184232144Sminshall 184335298Sminshall 184432144Sminshall static char ** 184532144Sminshall getnextcmd(name) 184632144Sminshall char *name; 184732144Sminshall { 184832144Sminshall Command *c = (Command *) name; 184932144Sminshall 185032144Sminshall return (char **) (c+1); 185132144Sminshall } 185232144Sminshall 185332144Sminshall static Command * 185432144Sminshall getcmd(name) 185532144Sminshall char *name; 185632144Sminshall { 185732144Sminshall Command *cm; 185832144Sminshall 185932144Sminshall if ((cm = (Command *) genget(name, (char **) cmdtab, getnextcmd)) != 0) { 186032144Sminshall return cm; 186132144Sminshall } else { 186232144Sminshall return (Command *) genget(name, (char **) cmdtab2, getnextcmd); 186332144Sminshall } 186432144Sminshall } 186532144Sminshall 186632144Sminshall void 186738689Sborman command(top, tbuf, cnt) 186832144Sminshall int top; 186938689Sborman char *tbuf; 187038689Sborman int cnt; 187132144Sminshall { 187232144Sminshall register Command *c; 187332144Sminshall 187432144Sminshall setcommandmode(); 187532144Sminshall if (!top) { 187632144Sminshall putchar('\n'); 187737219Sminshall #if defined(unix) 187832144Sminshall } else { 187932144Sminshall signal(SIGINT, SIG_DFL); 188032144Sminshall signal(SIGQUIT, SIG_DFL); 188132144Sminshall #endif /* defined(unix) */ 188232144Sminshall } 188332144Sminshall for (;;) { 188432144Sminshall printf("%s> ", prompt); 188538689Sborman if (tbuf) { 188638689Sborman register char *cp; 188738689Sborman cp = line; 188838689Sborman while (cnt > 0 && (*cp++ = *tbuf++) != '\n') 188938689Sborman cnt--; 189038689Sborman tbuf = 0; 189138689Sborman if (cp == line || *--cp != '\n' || cp == line) 189238689Sborman goto getline; 189338689Sborman *cp = '\0'; 189438689Sborman printf("%s\n", line); 189538689Sborman } else { 189638689Sborman getline: 189738689Sborman if (gets(line) == NULL) { 189838689Sborman if (feof(stdin) || ferror(stdin)) 189938689Sborman quit(); 190038689Sborman break; 190138689Sborman } 190232144Sminshall } 190332144Sminshall if (line[0] == 0) 190432144Sminshall break; 190532144Sminshall makeargv(); 190637219Sminshall if (margv[0] == 0) { 190737219Sminshall break; 190837219Sminshall } 190932144Sminshall c = getcmd(margv[0]); 191032144Sminshall if (Ambiguous(c)) { 191132144Sminshall printf("?Ambiguous command\n"); 191232144Sminshall continue; 191332144Sminshall } 191432144Sminshall if (c == 0) { 191532144Sminshall printf("?Invalid command\n"); 191632144Sminshall continue; 191732144Sminshall } 191832144Sminshall if (c->needconnect && !connected) { 191932144Sminshall printf("?Need to be connected first.\n"); 192032144Sminshall continue; 192132144Sminshall } 192232144Sminshall if ((*c->handler)(margc, margv)) { 192332144Sminshall break; 192432144Sminshall } 192532144Sminshall } 192632144Sminshall if (!top) { 192732144Sminshall if (!connected) { 192832144Sminshall longjmp(toplevel, 1); 192932144Sminshall /*NOTREACHED*/ 193032144Sminshall } 193132144Sminshall #if defined(TN3270) 193232144Sminshall if (shell_active == 0) { 193338689Sborman setconnmode(0); 193432144Sminshall } 193532144Sminshall #else /* defined(TN3270) */ 193638689Sborman setconnmode(0); 193732144Sminshall #endif /* defined(TN3270) */ 193832144Sminshall } 193932144Sminshall } 194032144Sminshall 194132144Sminshall /* 194232144Sminshall * Help command. 194332144Sminshall */ 194432144Sminshall static 194532144Sminshall help(argc, argv) 194632144Sminshall int argc; 194732144Sminshall char *argv[]; 194832144Sminshall { 194932144Sminshall register Command *c; 195032144Sminshall 195132144Sminshall if (argc == 1) { 195232144Sminshall printf("Commands may be abbreviated. Commands are:\n\n"); 195332144Sminshall for (c = cmdtab; c->name; c++) 195438689Sborman if (c->help) { 195532144Sminshall printf("%-*s\t%s\n", HELPINDENT, c->name, 195632144Sminshall c->help); 195732144Sminshall } 195832144Sminshall return 0; 195932144Sminshall } 196032144Sminshall while (--argc > 0) { 196132144Sminshall register char *arg; 196232144Sminshall arg = *++argv; 196332144Sminshall c = getcmd(arg); 196432144Sminshall if (Ambiguous(c)) 196532144Sminshall printf("?Ambiguous help command %s\n", arg); 196632144Sminshall else if (c == (Command *)0) 196732144Sminshall printf("?Invalid help command %s\n", arg); 196832144Sminshall else 196932144Sminshall printf("%s\n", c->help); 197032144Sminshall } 197132144Sminshall return 0; 197232144Sminshall } 197338689Sborman 197438689Sborman static char *rcname = 0; 197538689Sborman static char rcbuf[128]; 197638689Sborman 197738689Sborman cmdrc(m1, m2) 197838689Sborman char *m1, *m2; 197938689Sborman { 198038689Sborman register Command *c; 198138689Sborman FILE *rcfile; 198238689Sborman int gotmachine = 0; 198338689Sborman int l1 = strlen(m1); 198438689Sborman int l2 = strlen(m2); 198538689Sborman char m1save[64]; 198638689Sborman 198738689Sborman strcpy(m1save, m1); 198838689Sborman m1 = m1save; 198938689Sborman 199038689Sborman if (rcname == 0) { 199138689Sborman rcname = getenv("HOME"); 199238689Sborman if (rcname) 199338689Sborman strcpy(rcbuf, rcname); 199438689Sborman else 199538689Sborman rcbuf[0] = '\0'; 199638689Sborman strcat(rcbuf, "/.telnetrc"); 199738689Sborman rcname = rcbuf; 199838689Sborman } 199938689Sborman 200038689Sborman if ((rcfile = fopen(rcname, "r")) == 0) { 200138689Sborman return; 200238689Sborman } 200338689Sborman 200438689Sborman for (;;) { 200538689Sborman if (fgets(line, sizeof(line), rcfile) == NULL) 200638689Sborman break; 200738689Sborman if (line[0] == 0) 200838689Sborman break; 200938689Sborman if (line[0] == '#') 201038689Sborman continue; 201138689Sborman if (gotmachine == 0) { 201238689Sborman if (isspace(line[0])) 201338689Sborman continue; 201438689Sborman if (strncasecmp(line, m1, l1) == 0) 201538689Sborman strncpy(line, &line[l1], sizeof(line) - l1); 201638689Sborman else if (strncasecmp(line, m2, l2) == 0) 201738689Sborman strncpy(line, &line[l2], sizeof(line) - l2); 201838689Sborman else 201938689Sborman continue; 202038689Sborman gotmachine = 1; 202138689Sborman } else { 202238689Sborman if (!isspace(line[0])) { 202338689Sborman gotmachine = 0; 202438689Sborman continue; 202538689Sborman } 202638689Sborman } 202738689Sborman makeargv(); 202838689Sborman if (margv[0] == 0) 202938689Sborman continue; 203038689Sborman c = getcmd(margv[0]); 203138689Sborman if (Ambiguous(c)) { 203238689Sborman printf("?Ambiguous command: %s\n", margv[0]); 203338689Sborman continue; 203438689Sborman } 203538689Sborman if (c == 0) { 203638689Sborman printf("?Invalid command: %s\n", margv[0]); 203738689Sborman continue; 203838689Sborman } 203938689Sborman /* 204038689Sborman * This should never happen... 204138689Sborman */ 204238689Sborman if (c->needconnect && !connected) { 204338689Sborman printf("?Need to be connected first for %s.\n", margv[0]); 204438689Sborman continue; 204538689Sborman } 204638689Sborman (*c->handler)(margc, margv); 204738689Sborman } 204838689Sborman fclose(rcfile); 204938689Sborman } 205038689Sborman 205138689Sborman #if defined(SRCRT) && defined(IPPROTO_IP) 205238689Sborman 205338689Sborman /* 205438689Sborman * Source route is handed in as 205538689Sborman * [!]@hop1@hop2...[@|:]dst 205638689Sborman * If the leading ! is present, it is a 205738689Sborman * strict source route, otherwise it is 205838689Sborman * assmed to be a loose source route. 205938689Sborman * 206038689Sborman * We fill in the source route option as 206138689Sborman * hop1,hop2,hop3...dest 206238689Sborman * and return a pointer to hop1, which will 206338689Sborman * be the address to connect() to. 206438689Sborman * 206538689Sborman * Arguments: 206638689Sborman * arg: pointer to route list to decipher 206738689Sborman * 206838689Sborman * cpp: If *cpp is not equal to NULL, this is a 206938689Sborman * pointer to a pointer to a character array 207038689Sborman * that should be filled in with the option. 207138689Sborman * 207238689Sborman * lenp: pointer to an integer that contains the 207338689Sborman * length of *cpp if *cpp != NULL. 207438689Sborman * 207538689Sborman * Return values: 207638689Sborman * 207738689Sborman * Returns the address of the host to connect to. If the 207838689Sborman * return value is -1, there was a syntax error in the 207938689Sborman * option, either unknown characters, or too many hosts. 208038689Sborman * If the return value is 0, one of the hostnames in the 208138689Sborman * path is unknown, and *cpp is set to point to the bad 208238689Sborman * hostname. 208338689Sborman * 208438689Sborman * *cpp: If *cpp was equal to NULL, it will be filled 208538689Sborman * in with a pointer to our static area that has 208638689Sborman * the option filled in. This will be 32bit aligned. 208738689Sborman * 208838689Sborman * *lenp: This will be filled in with how long the option 208938689Sborman * pointed to by *cpp is. 209038689Sborman * 209138689Sborman */ 209238689Sborman unsigned long 209338689Sborman sourceroute(arg, cpp, lenp) 209438689Sborman char *arg; 209538689Sborman char **cpp; 209638689Sborman int *lenp; 209738689Sborman { 209838689Sborman static char lsr[44]; 209938689Sborman char *cp, *cp2, *lsrp, *lsrep, *index(); 210038689Sborman register int tmp; 210138689Sborman struct in_addr sin_addr; 210238689Sborman register struct hostent *host = 0; 210338689Sborman register char c; 210438689Sborman 210538689Sborman /* 210638689Sborman * Verify the arguments, and make sure we have 210738689Sborman * at least 7 bytes for the option. 210838689Sborman */ 210938689Sborman if (cpp == NULL || lenp == NULL) 211038689Sborman return((unsigned long)-1); 211138689Sborman if (*cpp != NULL && *lenp < 7) 211238689Sborman return((unsigned long)-1); 211338689Sborman /* 211438689Sborman * Decide whether we have a buffer passed to us, 211538689Sborman * or if we need to use our own static buffer. 211638689Sborman */ 211738689Sborman if (*cpp) { 211838689Sborman lsrp = *cpp; 211938689Sborman lsrep = lsrp + *lenp; 212038689Sborman } else { 212138689Sborman *cpp = lsrp = lsr; 212238689Sborman lsrep = lsrp + 44; 212338689Sborman } 212438689Sborman 212538689Sborman cp = arg; 212638689Sborman 212738689Sborman /* 212838689Sborman * Next, decide whether we have a loose source 212938689Sborman * route or a strict source route, and fill in 213038689Sborman * the begining of the option. 213138689Sborman */ 213238689Sborman if (*cp == '!') { 213338689Sborman cp++; 213438689Sborman *lsrp++ = IPOPT_SSRR; 213538689Sborman } else 213638689Sborman *lsrp++ = IPOPT_LSRR; 213738689Sborman 213838689Sborman if (*cp != '@') 213938689Sborman return((unsigned long)-1); 214038689Sborman 214138689Sborman lsrp++; /* skip over length, we'll fill it in later */ 214238689Sborman *lsrp++ = 4; 214338689Sborman 214438689Sborman cp++; 214538689Sborman 214638689Sborman sin_addr.s_addr = 0; 214738689Sborman 214838689Sborman for (c = 0;;) { 214938689Sborman if (c == ':') 215038689Sborman cp2 = 0; 215138689Sborman else for (cp2 = cp; c = *cp2; cp2++) { 215238689Sborman if (c == ',') { 215338689Sborman *cp2++ = '\0'; 215438689Sborman if (*cp2 == '@') 215538689Sborman cp2++; 215638689Sborman } else if (c == '@') { 215738689Sborman *cp2++ = '\0'; 215838689Sborman } else if (c == ':') { 215938689Sborman *cp2++ = '\0'; 216038689Sborman } else 216138689Sborman continue; 216238689Sborman break; 216338689Sborman } 216438689Sborman if (!c) 216538689Sborman cp2 = 0; 216638689Sborman 216738689Sborman if ((tmp = inet_addr(cp)) != -1) { 216838689Sborman sin_addr.s_addr = tmp; 216938689Sborman } else if (host = gethostbyname(cp)) { 217038689Sborman #if defined(h_addr) 217138689Sborman memcpy((caddr_t)&sin_addr, 217238689Sborman host->h_addr_list[0], host->h_length); 217338689Sborman #else 217438689Sborman memcpy((caddr_t)&sin_addr, host->h_addr, host->h_length); 217538689Sborman #endif 217638689Sborman } else { 217738689Sborman *cpp = cp; 217838689Sborman return(0); 217938689Sborman } 218038689Sborman memcpy(lsrp, (char *)&sin_addr, 4); 218138689Sborman lsrp += 4; 218238689Sborman if (cp2) 218338689Sborman cp = cp2; 218438689Sborman else 218538689Sborman break; 218638689Sborman /* 218738689Sborman * Check to make sure there is space for next address 218838689Sborman */ 218938689Sborman if (lsrp + 4 > lsrep) 219038689Sborman return((unsigned long)-1); 219138689Sborman } 219238689Sborman if ((*(*cpp+IPOPT_OLEN) = lsrp - *cpp) <= 7) { 219338689Sborman *cpp = 0; 219438689Sborman *lenp = 0; 219538689Sborman return((unsigned long)-1); 219638689Sborman } 219738689Sborman *lsrp++ = IPOPT_NOP; /* 32 bit word align it */ 219838689Sborman *lenp = lsrp - *cpp; 219938689Sborman return(sin_addr.s_addr); 220038689Sborman } 220138689Sborman #endif 220238689Sborman 220338909Sborman #if defined(NOSTRNCASECMP) 220438689Sborman strncasecmp(p1, p2, len) 220538689Sborman register char *p1, *p2; 220638689Sborman int len; 220738689Sborman { 220838689Sborman while (len--) { 220938689Sborman if (tolower(*p1) != tolower(*p2)) 221038689Sborman return(tolower(*p1) - tolower(*p2)); 221138689Sborman if (*p1 == '\0') 221238689Sborman return(0); 221338689Sborman p1++, p2++; 221438689Sborman } 221538689Sborman return(0); 221638689Sborman } 221738689Sborman #endif 2218