133685Sbostic /*
262309Sbostic * Copyright (c) 1988, 1990, 1993
362309Sbostic * The Regents of the University of California. All rights reserved.
433685Sbostic *
542770Sbostic * %sccs.include.redist.c%
633685Sbostic */
733685Sbostic
833685Sbostic #ifndef lint
9*69785Sdab static char sccsid[] = "@(#)commands.c 8.4 (Berkeley) 05/30/95";
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
53*69785Sdab #ifndef MAXHOSTNAMELEN
54*69785Sdab #define MAXHOSTNAMELEN 64
55*69785Sdab #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
makeargv()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
special(s)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 *
control(c)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 */
211*69785Sdab
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
sendcmd(argc,argv)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
send_esc()34846808Sdab send_esc()
34946808Sdab {
35046808Sdab NETADD(escape);
35146808Sdab return 1;
35246808Sdab }
35346808Sdab
35446808Sdab static int
send_docmd(name)35546808Sdab send_docmd(name)
35646808Sdab char *name;
35746808Sdab {
35846808Sdab return(send_tncmd(send_do, "do", name));
35946808Sdab }
36046808Sdab
36146808Sdab static int
send_dontcmd(name)36246808Sdab send_dontcmd(name)
36346808Sdab char *name;
36446808Sdab {
36546808Sdab return(send_tncmd(send_dont, "dont", name));
36646808Sdab }
36746808Sdab static int
send_willcmd(name)36846808Sdab send_willcmd(name)
36946808Sdab char *name;
37046808Sdab {
37146808Sdab return(send_tncmd(send_will, "will", name));
37246808Sdab }
37346808Sdab static int
send_wontcmd(name)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
send_help()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
lclchars()46032144Sminshall lclchars()
46132144Sminshall {
46232144Sminshall donelclchars = 1;
46332144Sminshall return 1;
46432144Sminshall }
46532144Sminshall
46646808Sdab static int
togdebug()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
togcrlf()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
togbinary(val)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
togrbinary(val)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
togxbinary(val)56538909Sborman togxbinary(val)
56646808Sdab int val;
56738909Sborman {
56838909Sborman donebinarytoggle = 1;
56938909Sborman
57038909Sborman if (val == -1)
57138909Sborman val = my_want_state_is_will(TELOPT_BINARY) ? 0 : 1;
57238909Sborman
57338909Sborman if (val == 1) {
57438909Sborman if (my_want_state_is_will(TELOPT_BINARY)) {
57538909Sborman printf("Already transmitting in binary mode.\n");
57638909Sborman } else {
57738909Sborman printf("Negotiating binary mode on output.\n");
57838909Sborman tel_enter_binary(2);
57938909Sborman }
58038909Sborman } else {
58138909Sborman if (my_want_state_is_wont(TELOPT_BINARY)) {
58238909Sborman printf("Already transmitting in network ascii mode.\n");
58338909Sborman } else {
58438909Sborman printf("Negotiating network ascii mode on output.\n");
58538909Sborman tel_leave_binary(2);
58638909Sborman }
58738909Sborman }
58838909Sborman return 1;
58938909Sborman }
59038909Sborman
59138909Sborman
59256642Sralph static int togglehelp P((void));
59357213Sdab #if defined(AUTHENTICATION)
59447609Sdab extern int auth_togdebug P((int));
59547609Sdab #endif
59660149Sdab #ifdef ENCRYPTION
59747609Sdab extern int EncryptAutoEnc P((int));
59847609Sdab extern int EncryptAutoDec P((int));
59947609Sdab extern int EncryptDebug P((int));
60047609Sdab extern int EncryptVerbose P((int));
60160149Sdab #endif /* ENCRYPTION */
60232144Sminshall
60332144Sminshall struct togglelist {
60432144Sminshall char *name; /* name of toggle */
60532144Sminshall char *help; /* help message */
60632144Sminshall int (*handler)(); /* routine to do actual setting */
60732144Sminshall int *variable;
60832144Sminshall char *actionexplanation;
60932144Sminshall };
61032144Sminshall
61132144Sminshall static struct togglelist Togglelist[] = {
61232144Sminshall { "autoflush",
61338689Sborman "flushing of output when sending interrupt characters",
61432144Sminshall 0,
61538689Sborman &autoflush,
61638689Sborman "flush output when sending interrupt characters" },
61732144Sminshall { "autosynch",
61838689Sborman "automatic sending of interrupt characters in urgent mode",
61932144Sminshall 0,
62038689Sborman &autosynch,
62138689Sborman "send interrupt characters in urgent mode" },
62257213Sdab #if defined(AUTHENTICATION)
62347609Sdab { "autologin",
62447609Sdab "automatic sending of login and/or authentication info",
62547609Sdab 0,
62647609Sdab &autologin,
62747609Sdab "send login name and/or authentication information" },
62847609Sdab { "authdebug",
62947609Sdab "Toggle authentication debugging",
63047609Sdab auth_togdebug,
63147609Sdab 0,
63247609Sdab "print authentication debugging information" },
63347609Sdab #endif
63460149Sdab #ifdef ENCRYPTION
63547609Sdab { "autoencrypt",
63647609Sdab "automatic encryption of data stream",
63747609Sdab EncryptAutoEnc,
63847609Sdab 0,
63947609Sdab "automatically encrypt output" },
64047609Sdab { "autodecrypt",
64147609Sdab "automatic decryption of data stream",
64247609Sdab EncryptAutoDec,
64347609Sdab 0,
64447609Sdab "automatically decrypt input" },
64547609Sdab { "verbose_encrypt",
64647609Sdab "Toggle verbose encryption output",
64747609Sdab EncryptVerbose,
64847609Sdab 0,
64947609Sdab "print verbose encryption output" },
65047609Sdab { "encdebug",
65147609Sdab "Toggle encryption debugging",
65247609Sdab EncryptDebug,
65347609Sdab 0,
65447609Sdab "print encryption debugging information" },
65560149Sdab #endif /* ENCRYPTION */
65647609Sdab { "skiprc",
65747609Sdab "don't read ~/.telnetrc file",
65847609Sdab 0,
65947609Sdab &skiprc,
66057848Sdab "skip reading of ~/.telnetrc file" },
66132144Sminshall { "binary",
66238689Sborman "sending and receiving of binary data",
66332144Sminshall togbinary,
66438689Sborman 0,
66538689Sborman 0 },
66638909Sborman { "inbinary",
66738909Sborman "receiving of binary data",
66838909Sborman togrbinary,
66938909Sborman 0,
67038909Sborman 0 },
67138909Sborman { "outbinary",
67238909Sborman "sending of binary data",
67338909Sborman togxbinary,
67438909Sborman 0,
67538909Sborman 0 },
67632144Sminshall { "crlf",
67738689Sborman "sending carriage returns as telnet <CR><LF>",
67832144Sminshall togcrlf,
67938689Sborman &crlf,
68038689Sborman 0 },
68132144Sminshall { "crmod",
68238689Sborman "mapping of received carriage returns",
68332144Sminshall 0,
68438689Sborman &crmod,
68538689Sborman "map carriage return on output" },
68632144Sminshall { "localchars",
68738689Sborman "local recognition of certain control characters",
68832144Sminshall lclchars,
68938689Sborman &localchars,
69038689Sborman "recognize certain control characters" },
69138689Sborman { " ", "", 0 }, /* empty line */
69238208Sminshall #if defined(unix) && defined(TN3270)
69338920Sminshall { "apitrace",
69438920Sminshall "(debugging) toggle tracing of API transactions",
69538920Sminshall 0,
69638920Sminshall &apitrace,
69738920Sminshall "trace API transactions" },
69838208Sminshall { "cursesdata",
69938208Sminshall "(debugging) toggle printing of hexadecimal curses data",
70038208Sminshall 0,
70138689Sborman &cursesdata,
70238689Sborman "print hexadecimal representation of curses data" },
70338208Sminshall #endif /* defined(unix) && defined(TN3270) */
70432144Sminshall { "debug",
70538689Sborman "debugging",
70632144Sminshall togdebug,
70738689Sborman &debug,
70838689Sborman "turn on socket level debugging" },
70932144Sminshall { "netdata",
71038689Sborman "printing of hexadecimal network data (debugging)",
71132144Sminshall 0,
71238689Sborman &netdata,
71338689Sborman "print hexadecimal representation of network traffic" },
71438689Sborman { "prettydump",
71538689Sborman "output of \"netdata\" to user readable format (debugging)",
71638689Sborman 0,
71738689Sborman &prettydump,
71838689Sborman "print user readable output for \"netdata\"" },
71932144Sminshall { "options",
72038689Sborman "viewing of options processing (debugging)",
72132144Sminshall 0,
72238689Sborman &showoptions,
72338689Sborman "show option processing" },
72438208Sminshall #if defined(unix)
72538208Sminshall { "termdata",
72638208Sminshall "(debugging) toggle printing of hexadecimal terminal data",
72738208Sminshall 0,
72838689Sborman &termdata,
72938689Sborman "print hexadecimal representation of terminal traffic" },
73038208Sminshall #endif /* defined(unix) */
73132144Sminshall { "?",
73238689Sborman 0,
73338689Sborman togglehelp },
73432144Sminshall { "help",
73538689Sborman 0,
73638689Sborman togglehelp },
73732144Sminshall { 0 }
73832144Sminshall };
73932144Sminshall
74046808Sdab static int
togglehelp()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
settogglehelp(set)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
toggle(argc,argv)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
_setlist_init()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 *
getset(name)89532144Sminshall getset(name)
89646808Sdab char *name;
89732144Sminshall {
89846808Sdab return (struct setlist *)
89946808Sdab genget(name, (char **) Setlist, sizeof(struct setlist));
90032144Sminshall }
90132144Sminshall
90246808Sdab void
set_escape_char(s)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
setcmd(argc,argv)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
unsetcmd(argc,argv)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
dokludgemode()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
dolinemode()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
docharmode()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
dolmmode(bit,on)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
setmode(bit)111646808Sdab setmode(bit)
111746808Sdab {
111846808Sdab return dolmmode(bit, 1);
111946808Sdab }
112046808Sdab
112146808Sdab int
clearmode(bit)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
modehelp()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
modecmd(argc,argv)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
display(argc,argv)121932144Sminshall display(argc, argv)
122046808Sdab int argc;
122146808Sdab char *argv[];
122232144Sminshall {
122346808Sdab struct togglelist *tl;
122446808Sdab struct setlist *sl;
122546808Sdab
122632144Sminshall #define dotog(tl) if (tl->variable && tl->actionexplanation) { \
122732144Sminshall if (*tl->variable) { \
122832144Sminshall printf("will"); \
122932144Sminshall } else { \
123032144Sminshall printf("won't"); \
123132144Sminshall } \
123232144Sminshall printf(" %s.\n", tl->actionexplanation); \
123332144Sminshall }
123432144Sminshall
123532144Sminshall #define doset(sl) if (sl->name && *sl->name != ' ') { \
123638689Sborman if (sl->handler == 0) \
123738689Sborman printf("%-15s [%s]\n", sl->name, control(*sl->charp)); \
123838689Sborman else \
123944361Sborman printf("%-15s \"%s\"\n", sl->name, (char *)sl->charp); \
124032144Sminshall }
124132144Sminshall
124232144Sminshall if (argc == 1) {
124332144Sminshall for (tl = Togglelist; tl->name; tl++) {
124432144Sminshall dotog(tl);
124532144Sminshall }
124632144Sminshall printf("\n");
124732144Sminshall for (sl = Setlist; sl->name; sl++) {
124832144Sminshall doset(sl);
124932144Sminshall }
125032144Sminshall } else {
125132144Sminshall int i;
125232144Sminshall
125332144Sminshall for (i = 1; i < argc; i++) {
125432144Sminshall sl = getset(argv[i]);
125546808Sdab tl = GETTOGGLE(argv[i]);
125632144Sminshall if (Ambiguous(sl) || Ambiguous(tl)) {
125732144Sminshall printf("?Ambiguous argument '%s'.\n", argv[i]);
125832144Sminshall return 0;
125932144Sminshall } else if (!sl && !tl) {
126032144Sminshall printf("?Unknown argument '%s'.\n", argv[i]);
126132144Sminshall return 0;
126232144Sminshall } else {
126332144Sminshall if (tl) {
126432144Sminshall dotog(tl);
126532144Sminshall }
126632144Sminshall if (sl) {
126732144Sminshall doset(sl);
126832144Sminshall }
126932144Sminshall }
127032144Sminshall }
127132144Sminshall }
127238689Sborman /*@*/optionstatus();
127360149Sdab #ifdef ENCRYPTION
127446808Sdab EncryptStatus();
127560149Sdab #endif /* ENCRYPTION */
127632144Sminshall return 1;
127732144Sminshall #undef doset
127832144Sminshall #undef dotog
127932144Sminshall }
128032144Sminshall
128132144Sminshall /*
128232144Sminshall * The following are the data structures, and many of the routines,
128332144Sminshall * relating to command processing.
128432144Sminshall */
128532144Sminshall
128632144Sminshall /*
128732144Sminshall * Set the escape character.
128832144Sminshall */
128946808Sdab static int
setescape(argc,argv)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
togcrmod()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
suspend()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
1340*69785Sdab * 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
shell(argc,argv)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;
1380*69785Sdab extern char *strrchr();
138138689Sborman
138246808Sdab shellp = getenv("SHELL");
138346808Sdab if (shellp == NULL)
138446808Sdab shellp = "/bin/sh";
1385*69785Sdab if ((shellname = strrchr(shellp, '/')) == 0)
138646808Sdab shellname = shellp;
138738689Sborman else
138838689Sborman shellname++;
138938689Sborman if (argc > 1)
139046808Sdab execl(shellp, shellname, "-c", &saveline[1], 0);
139138689Sborman else
139246808Sdab execl(shellp, shellname, 0);
139338689Sborman perror("Execl");
139438689Sborman _exit(1);
139538689Sborman }
139638689Sborman default:
139744361Sborman (void)wait((int *)0); /* Wait for the shell to complete */
139857213Sdab
139957213Sdab if (TerminalWindowSize(&newrows, &newcols) && connected &&
140057213Sdab (err || ((oldrows != newrows) || (oldcols != newcols)))) {
140157213Sdab sendnaws();
140257213Sdab }
140357213Sdab break;
140438689Sborman }
140546808Sdab return 1;
140638689Sborman }
140759893Sbostic #else /* !defined(TN3270) */
140859893Sbostic extern int shell();
140938689Sborman #endif /* !defined(TN3270) */
141038689Sborman
141146808Sdab /*VARARGS*/
141246808Sdab static
bye(argc,argv)141332144Sminshall bye(argc, argv)
141446808Sdab int argc; /* Number of arguments */
141546808Sdab char *argv[]; /* arguments */
141632144Sminshall {
141746808Sdab extern int resettermname;
141846808Sdab
141932144Sminshall if (connected) {
142034849Sminshall (void) shutdown(net, 2);
142132144Sminshall printf("Connection closed.\n");
142234849Sminshall (void) NetClose(net);
142332144Sminshall connected = 0;
142446808Sdab resettermname = 1;
142557213Sdab #if defined(AUTHENTICATION) || defined(ENCRYPTION)
142646808Sdab auth_encrypt_connect(connected);
142760149Sdab #endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */
142832144Sminshall /* reset options */
142932144Sminshall tninit();
143032144Sminshall #if defined(TN3270)
143132144Sminshall SetIn3270(); /* Get out of 3270 mode */
143232144Sminshall #endif /* defined(TN3270) */
143332144Sminshall }
143432144Sminshall if ((argc != 2) || (strcmp(argv[1], "fromquit") != 0)) {
143532144Sminshall longjmp(toplevel, 1);
143632144Sminshall /* NOTREACHED */
143732144Sminshall }
143832144Sminshall return 1; /* Keep lint, etc., happy */
143932144Sminshall }
144032144Sminshall
144132144Sminshall /*VARARGS*/
quit()144232144Sminshall quit()
144332144Sminshall {
144432144Sminshall (void) call(bye, "bye", "fromquit", 0);
144532144Sminshall Exit(0);
144644361Sborman /*NOTREACHED*/
144732144Sminshall }
144846808Sdab
144946808Sdab /*VARARGS*/
145046808Sdab int
logout()145146808Sdab logout()
145246808Sdab {
145346808Sdab send_do(TELOPT_LOGOUT, 1);
145446808Sdab (void) netflush();
145546808Sdab return 1;
145646808Sdab }
145746808Sdab
145838689Sborman
145938689Sborman /*
146038689Sborman * The SLC command.
146138689Sborman */
146232144Sminshall
146338689Sborman struct slclist {
146438689Sborman char *name;
146538689Sborman char *help;
146646808Sdab void (*handler)();
146738689Sborman int arg;
146838689Sborman };
146938689Sborman
147056642Sralph static void slc_help();
147138689Sborman
147238689Sborman struct slclist SlcList[] = {
147338689Sborman { "export", "Use local special character definitions",
147438689Sborman slc_mode_export, 0 },
147538689Sborman { "import", "Use remote special character definitions",
147638689Sborman slc_mode_import, 1 },
147738689Sborman { "check", "Verify remote special character definitions",
147838689Sborman slc_mode_import, 0 },
147938689Sborman { "help", 0, slc_help, 0 },
148038689Sborman { "?", "Print help information", slc_help, 0 },
148138689Sborman { 0 },
148238689Sborman };
148338689Sborman
148446808Sdab static void
slc_help()148538689Sborman slc_help()
148638689Sborman {
148738689Sborman struct slclist *c;
148838689Sborman
148938689Sborman for (c = SlcList; c->name; c++) {
149038689Sborman if (c->help) {
149138689Sborman if (*c->help)
149238689Sborman printf("%-15s %s\n", c->name, c->help);
149338689Sborman else
149438689Sborman printf("\n");
149538689Sborman }
149638689Sborman }
149738689Sborman }
149838689Sborman
149946808Sdab static struct slclist *
getslc(name)150038689Sborman getslc(name)
150146808Sdab char *name;
150238689Sborman {
150346808Sdab return (struct slclist *)
150446808Sdab genget(name, (char **) SlcList, sizeof(struct slclist));
150538689Sborman }
150638689Sborman
150746808Sdab static
slccmd(argc,argv)150838689Sborman slccmd(argc, argv)
150946808Sdab int argc;
151046808Sdab char *argv[];
151138689Sborman {
151238689Sborman struct slclist *c;
151338689Sborman
151438689Sborman if (argc != 2) {
151538689Sborman fprintf(stderr,
151638689Sborman "Need an argument to 'slc' command. 'slc ?' for help.\n");
151738689Sborman return 0;
151838689Sborman }
151938689Sborman c = getslc(argv[1]);
152038689Sborman if (c == 0) {
1521*69785Sdab fprintf(stderr, "'%s': unknown argument ('slc ?' for help).\n",
152238689Sborman argv[1]);
1523*69785Sdab return 0;
152438689Sborman }
152538689Sborman if (Ambiguous(c)) {
1526*69785Sdab fprintf(stderr, "'%s': ambiguous argument ('slc ?' for help).\n",
152738689Sborman argv[1]);
1528*69785Sdab return 0;
152938689Sborman }
153038689Sborman (*c->handler)(c->arg);
153138689Sborman slcstate();
153238689Sborman return 1;
153338689Sborman }
153444361Sborman
153544361Sborman /*
153644361Sborman * The ENVIRON command.
153744361Sborman */
153838689Sborman
153944361Sborman struct envlist {
154044361Sborman char *name;
154144361Sborman char *help;
154246808Sdab void (*handler)();
154344361Sborman int narg;
154444361Sborman };
154544361Sborman
154646808Sdab extern struct env_lst *
154746808Sdab env_define P((unsigned char *, unsigned char *));
154846808Sdab extern void
154946808Sdab env_undefine P((unsigned char *)),
155046808Sdab env_export P((unsigned char *)),
155146808Sdab env_unexport P((unsigned char *)),
155246808Sdab env_send P((unsigned char *)),
155365157Sdab #if defined(OLD_ENVIRON) && defined(ENV_HACK)
155458972Sdab env_varval P((unsigned char *)),
155558972Sdab #endif
155656642Sralph env_list P((void));
155756642Sralph static void
155846808Sdab env_help P((void));
155944361Sborman
156044361Sborman struct envlist EnvList[] = {
156144361Sborman { "define", "Define an environment variable",
156246808Sdab (void (*)())env_define, 2 },
156344361Sborman { "undefine", "Undefine an environment variable",
156444361Sborman env_undefine, 1 },
156544361Sborman { "export", "Mark an environment variable for automatic export",
156644361Sborman env_export, 1 },
156746808Sdab { "unexport", "Don't mark an environment variable for automatic export",
156844361Sborman env_unexport, 1 },
156945233Sborman { "send", "Send an environment variable", env_send, 1 },
157044361Sborman { "list", "List the current environment variables",
157144361Sborman env_list, 0 },
157265157Sdab #if defined(OLD_ENVIRON) && defined(ENV_HACK)
157358972Sdab { "varval", "Reverse VAR and VALUE (auto, right, wrong, status)",
157458972Sdab env_varval, 1 },
157558972Sdab #endif
157644361Sborman { "help", 0, env_help, 0 },
157744361Sborman { "?", "Print help information", env_help, 0 },
157844361Sborman { 0 },
157944361Sborman };
158044361Sborman
158146808Sdab static void
env_help()158244361Sborman env_help()
158344361Sborman {
158444361Sborman struct envlist *c;
158544361Sborman
158644361Sborman for (c = EnvList; c->name; c++) {
158744361Sborman if (c->help) {
158844361Sborman if (*c->help)
158944361Sborman printf("%-15s %s\n", c->name, c->help);
159044361Sborman else
159144361Sborman printf("\n");
159244361Sborman }
159344361Sborman }
159444361Sborman }
159544361Sborman
159646808Sdab static struct envlist *
getenvcmd(name)159744361Sborman getenvcmd(name)
159846808Sdab char *name;
159944361Sborman {
160046808Sdab return (struct envlist *)
160146808Sdab genget(name, (char **) EnvList, sizeof(struct envlist));
160244361Sborman }
160344361Sborman
env_cmd(argc,argv)160444361Sborman env_cmd(argc, argv)
160546808Sdab int argc;
160646808Sdab char *argv[];
160744361Sborman {
160844361Sborman struct envlist *c;
160944361Sborman
161044361Sborman if (argc < 2) {
161144361Sborman fprintf(stderr,
161244361Sborman "Need an argument to 'environ' command. 'environ ?' for help.\n");
161344361Sborman return 0;
161444361Sborman }
161544361Sborman c = getenvcmd(argv[1]);
161644361Sborman if (c == 0) {
1617*69785Sdab fprintf(stderr, "'%s': unknown argument ('environ ?' for help).\n",
161844361Sborman argv[1]);
1619*69785Sdab return 0;
162044361Sborman }
162144361Sborman if (Ambiguous(c)) {
1622*69785Sdab fprintf(stderr, "'%s': ambiguous argument ('environ ?' for help).\n",
162344361Sborman argv[1]);
1624*69785Sdab return 0;
162544361Sborman }
162644361Sborman if (c->narg + 2 != argc) {
162744361Sborman fprintf(stderr,
162844361Sborman "Need %s%d argument%s to 'environ %s' command. 'environ ?' for help.\n",
162944361Sborman c->narg < argc + 2 ? "only " : "",
163044361Sborman c->narg, c->narg == 1 ? "" : "s", c->name);
163144361Sborman return 0;
163244361Sborman }
163346808Sdab (*c->handler)(argv[2], argv[3]);
163444361Sborman return 1;
163544361Sborman }
163644361Sborman
163744361Sborman struct env_lst {
163844361Sborman struct env_lst *next; /* pointer to next structure */
163957213Sdab struct env_lst *prev; /* pointer to previous structure */
164046808Sdab unsigned char *var; /* pointer to variable name */
164157213Sdab unsigned char *value; /* pointer to variable value */
164244361Sborman int export; /* 1 -> export with default list of variables */
164357213Sdab int welldefined; /* A well defined variable */
164444361Sborman };
164544361Sborman
164644361Sborman struct env_lst envlisthead;
164744361Sborman
164846808Sdab struct env_lst *
env_find(var)164944361Sborman env_find(var)
165046808Sdab unsigned char *var;
165144361Sborman {
165244361Sborman register struct env_lst *ep;
165344361Sborman
165444361Sborman for (ep = envlisthead.next; ep; ep = ep->next) {
165546808Sdab if (strcmp((char *)ep->var, (char *)var) == 0)
165644361Sborman return(ep);
165744361Sborman }
165844361Sborman return(NULL);
165944361Sborman }
166044361Sborman
166146808Sdab void
env_init()166244361Sborman env_init()
166344361Sborman {
166446808Sdab extern char **environ;
166544361Sborman register char **epp, *cp;
166644361Sborman register struct env_lst *ep;
1667*69785Sdab extern char *strchr();
166844361Sborman
166944361Sborman for (epp = environ; *epp; epp++) {
1670*69785Sdab if (cp = strchr(*epp, '=')) {
167144361Sborman *cp = '\0';
167246808Sdab ep = env_define((unsigned char *)*epp,
167346808Sdab (unsigned char *)cp+1);
167444361Sborman ep->export = 0;
167544361Sborman *cp = '=';
167644361Sborman }
167744361Sborman }
167844361Sborman /*
167944361Sborman * Special case for DISPLAY variable. If it is ":0.0" or
168044361Sborman * "unix:0.0", we have to get rid of "unix" and insert our
168144361Sborman * hostname.
168244361Sborman */
168346808Sdab if ((ep = env_find("DISPLAY"))
168446808Sdab && ((*ep->value == ':')
1685*69785Sdab || (strncmp((char *)ep->value, "unix:", 5) == 0))) {
168644361Sborman char hbuf[256+1];
1687*69785Sdab char *cp2 = strchr((char *)ep->value, ':');
168844361Sborman
168944361Sborman gethostname(hbuf, 256);
169044361Sborman hbuf[256] = '\0';
169144361Sborman cp = (char *)malloc(strlen(hbuf) + strlen(cp2) + 1);
169246808Sdab sprintf((char *)cp, "%s%s", hbuf, cp2);
169344361Sborman free(ep->value);
169446808Sdab ep->value = (unsigned char *)cp;
169544361Sborman }
169644361Sborman /*
169744361Sborman * If USER is not defined, but LOGNAME is, then add
169845233Sborman * USER with the value from LOGNAME. By default, we
169945233Sborman * don't export the USER variable.
170044361Sborman */
170145233Sborman if ((env_find("USER") == NULL) && (ep = env_find("LOGNAME"))) {
170246808Sdab env_define((unsigned char *)"USER", ep->value);
170346808Sdab env_unexport((unsigned char *)"USER");
170445233Sborman }
170546808Sdab env_export((unsigned char *)"DISPLAY");
170646808Sdab env_export((unsigned char *)"PRINTER");
170744361Sborman }
170844361Sborman
170946808Sdab struct env_lst *
env_define(var,value)171044361Sborman env_define(var, value)
171146808Sdab unsigned char *var, *value;
171244361Sborman {
171344361Sborman register struct env_lst *ep;
171444361Sborman
171544361Sborman if (ep = env_find(var)) {
171644361Sborman if (ep->var)
171744361Sborman free(ep->var);
171844361Sborman if (ep->value)
171944361Sborman free(ep->value);
172044361Sborman } else {
172144361Sborman ep = (struct env_lst *)malloc(sizeof(struct env_lst));
172244361Sborman ep->next = envlisthead.next;
172344361Sborman envlisthead.next = ep;
172444361Sborman ep->prev = &envlisthead;
172544361Sborman if (ep->next)
172644361Sborman ep->next->prev = ep;
172744361Sborman }
172857213Sdab ep->welldefined = opt_welldefined(var);
172945009Skarels ep->export = 1;
173046808Sdab ep->var = (unsigned char *)strdup((char *)var);
173146808Sdab ep->value = (unsigned char *)strdup((char *)value);
173244361Sborman return(ep);
173344361Sborman }
173444361Sborman
173546808Sdab void
env_undefine(var)173644361Sborman env_undefine(var)
173746808Sdab unsigned char *var;
173844361Sborman {
173944361Sborman register struct env_lst *ep;
174044361Sborman
174144361Sborman if (ep = env_find(var)) {
174244361Sborman ep->prev->next = ep->next;
174345233Sborman if (ep->next)
174445233Sborman ep->next->prev = ep->prev;
174544361Sborman if (ep->var)
174644361Sborman free(ep->var);
174744361Sborman if (ep->value)
174844361Sborman free(ep->value);
174944361Sborman free(ep);
175044361Sborman }
175144361Sborman }
175244361Sborman
175346808Sdab void
env_export(var)175444361Sborman env_export(var)
175546808Sdab unsigned char *var;
175644361Sborman {
175744361Sborman register struct env_lst *ep;
175844361Sborman
175944361Sborman if (ep = env_find(var))
176044361Sborman ep->export = 1;
176144361Sborman }
176244361Sborman
176346808Sdab void
env_unexport(var)176444361Sborman env_unexport(var)
176546808Sdab unsigned char *var;
176644361Sborman {
176744361Sborman register struct env_lst *ep;
176844361Sborman
176944361Sborman if (ep = env_find(var))
177044361Sborman ep->export = 0;
177144361Sborman }
177244361Sborman
177346808Sdab void
env_send(var)177445233Sborman env_send(var)
177546808Sdab unsigned char *var;
177645233Sborman {
177745233Sborman register struct env_lst *ep;
177845233Sborman
1779*69785Sdab if (my_state_is_wont(TELOPT_NEW_ENVIRON)
178065157Sdab #ifdef OLD_ENVIRON
178165157Sdab && my_state_is_wont(TELOPT_OLD_ENVIRON)
178265157Sdab #endif
178365157Sdab ) {
178445233Sborman fprintf(stderr,
178545233Sborman "Cannot send '%s': Telnet ENVIRON option not enabled\n",
178645233Sborman var);
178745233Sborman return;
178845233Sborman }
178945233Sborman ep = env_find(var);
179045233Sborman if (ep == 0) {
179145233Sborman fprintf(stderr, "Cannot send '%s': variable not defined\n",
179245233Sborman var);
179345233Sborman return;
179445233Sborman }
179545233Sborman env_opt_start_info();
179645233Sborman env_opt_add(ep->var);
179745233Sborman env_opt_end(0);
179845233Sborman }
179945233Sborman
180046808Sdab void
env_list()180144361Sborman env_list()
180244361Sborman {
180344361Sborman register struct env_lst *ep;
180444361Sborman
180544361Sborman for (ep = envlisthead.next; ep; ep = ep->next) {
180644361Sborman printf("%c %-20s %s\n", ep->export ? '*' : ' ',
180744361Sborman ep->var, ep->value);
180844361Sborman }
180944361Sborman }
181044361Sborman
181146808Sdab unsigned char *
env_default(init,welldefined)181257213Sdab env_default(init, welldefined)
181346808Sdab int init;
181444361Sborman {
181544361Sborman static struct env_lst *nep = NULL;
181644361Sborman
181744361Sborman if (init) {
181844361Sborman nep = &envlisthead;
181944361Sborman return;
182044361Sborman }
182144361Sborman if (nep) {
182244361Sborman while (nep = nep->next) {
182357213Sdab if (nep->export && (nep->welldefined == welldefined))
182444361Sborman return(nep->var);
182544361Sborman }
182644361Sborman }
182744361Sborman return(NULL);
182844361Sborman }
182944361Sborman
183046808Sdab unsigned char *
env_getvalue(var)183144361Sborman env_getvalue(var)
183246808Sdab unsigned char *var;
183344361Sborman {
183444361Sborman register struct env_lst *ep;
183544361Sborman
183644361Sborman if (ep = env_find(var))
183744361Sborman return(ep->value);
183844361Sborman return(NULL);
183944361Sborman }
184044361Sborman
184165157Sdab #if defined(OLD_ENVIRON) && defined(ENV_HACK)
184258972Sdab void
env_varval(what)184358972Sdab env_varval(what)
184458972Sdab unsigned char *what;
184558972Sdab {
184665157Sdab extern int old_env_var, old_env_value, env_auto;
184765157Sdab int len = strlen((char *)what);
184858972Sdab
184958972Sdab if (len == 0)
185058972Sdab goto unknown;
185158972Sdab
185265157Sdab if (strncasecmp((char *)what, "status", len) == 0) {
185358972Sdab if (env_auto)
185458972Sdab printf("%s%s", "VAR and VALUE are/will be ",
185558972Sdab "determined automatically\n");
185665157Sdab if (old_env_var == OLD_ENV_VAR)
185758972Sdab printf("VAR and VALUE set to correct definitions\n");
185858972Sdab else
185958972Sdab printf("VAR and VALUE definitions are reversed\n");
186065157Sdab } else if (strncasecmp((char *)what, "auto", len) == 0) {
186158972Sdab env_auto = 1;
186265157Sdab old_env_var = OLD_ENV_VALUE;
186365157Sdab old_env_value = OLD_ENV_VAR;
186465157Sdab } else if (strncasecmp((char *)what, "right", len) == 0) {
186558972Sdab env_auto = 0;
186665157Sdab old_env_var = OLD_ENV_VAR;
186765157Sdab old_env_value = OLD_ENV_VALUE;
186865157Sdab } else if (strncasecmp((char *)what, "wrong", len) == 0) {
186958972Sdab env_auto = 0;
187065157Sdab old_env_var = OLD_ENV_VALUE;
187165157Sdab old_env_value = OLD_ENV_VAR;
187258972Sdab } else {
187358972Sdab unknown:
187458972Sdab printf("Unknown \"varval\" command. (\"auto\", \"right\", \"wrong\", \"status\")\n");
187558972Sdab }
187658972Sdab }
187758972Sdab #endif
187858972Sdab
187957213Sdab #if defined(AUTHENTICATION)
188046808Sdab /*
188146808Sdab * The AUTHENTICATE command.
188246808Sdab */
188346808Sdab
188446808Sdab struct authlist {
188546808Sdab char *name;
188646808Sdab char *help;
188746808Sdab int (*handler)();
188846808Sdab int narg;
188946808Sdab };
189046808Sdab
189146808Sdab extern int
189268343Sdab auth_enable P((char *)),
189368343Sdab auth_disable P((char *)),
189456642Sralph auth_status P((void));
189556642Sralph static int
189646808Sdab auth_help P((void));
189746808Sdab
189846808Sdab struct authlist AuthList[] = {
189946808Sdab { "status", "Display current status of authentication information",
190046808Sdab auth_status, 0 },
190146808Sdab { "disable", "Disable an authentication type ('auth disable ?' for more)",
190246808Sdab auth_disable, 1 },
190346808Sdab { "enable", "Enable an authentication type ('auth enable ?' for more)",
190446808Sdab auth_enable, 1 },
190546808Sdab { "help", 0, auth_help, 0 },
190646808Sdab { "?", "Print help information", auth_help, 0 },
190746808Sdab { 0 },
190846808Sdab };
190946808Sdab
191046808Sdab static int
auth_help()191146808Sdab auth_help()
191244361Sborman {
191346808Sdab struct authlist *c;
191446808Sdab
191546808Sdab for (c = AuthList; c->name; c++) {
191646808Sdab if (c->help) {
191746808Sdab if (*c->help)
191846808Sdab printf("%-15s %s\n", c->name, c->help);
191946808Sdab else
192046808Sdab printf("\n");
192146808Sdab }
192246808Sdab }
192346808Sdab return 0;
192444361Sborman }
192546808Sdab
auth_cmd(argc,argv)192646808Sdab auth_cmd(argc, argv)
192746808Sdab int argc;
192846808Sdab char *argv[];
192946808Sdab {
193046808Sdab struct authlist *c;
193146808Sdab
193268343Sdab if (argc < 2) {
193368343Sdab fprintf(stderr,
193468343Sdab "Need an argument to 'auth' command. 'auth ?' for help.\n");
193568343Sdab return 0;
193668343Sdab }
193768343Sdab
193846808Sdab c = (struct authlist *)
193946808Sdab genget(argv[1], (char **) AuthList, sizeof(struct authlist));
194046808Sdab if (c == 0) {
1941*69785Sdab fprintf(stderr, "'%s': unknown argument ('auth ?' for help).\n",
194246808Sdab argv[1]);
1943*69785Sdab return 0;
194446808Sdab }
194546808Sdab if (Ambiguous(c)) {
1946*69785Sdab fprintf(stderr, "'%s': ambiguous argument ('auth ?' for help).\n",
194746808Sdab argv[1]);
1948*69785Sdab return 0;
194946808Sdab }
195046808Sdab if (c->narg + 2 != argc) {
195146808Sdab fprintf(stderr,
195246808Sdab "Need %s%d argument%s to 'auth %s' command. 'auth ?' for help.\n",
195346808Sdab c->narg < argc + 2 ? "only " : "",
195446808Sdab c->narg, c->narg == 1 ? "" : "s", c->name);
195546808Sdab return 0;
195646808Sdab }
195746808Sdab return((*c->handler)(argv[2], argv[3]));
195846808Sdab }
195945233Sborman #endif
196044361Sborman
196160149Sdab #ifdef ENCRYPTION
196232144Sminshall /*
196346808Sdab * The ENCRYPT command.
196436274Sminshall */
196536274Sminshall
196646808Sdab struct encryptlist {
196746808Sdab char *name;
196846808Sdab char *help;
196946808Sdab int (*handler)();
197046808Sdab int needconnect;
197146808Sdab int minarg;
197246808Sdab int maxarg;
197346808Sdab };
197446808Sdab
197546808Sdab extern int
197646808Sdab EncryptEnable P((char *, char *)),
197747609Sdab EncryptDisable P((char *, char *)),
197846808Sdab EncryptType P((char *, char *)),
197946808Sdab EncryptStart P((char *)),
198046808Sdab EncryptStartInput P((void)),
198146808Sdab EncryptStartOutput P((void)),
198246808Sdab EncryptStop P((char *)),
198346808Sdab EncryptStopInput P((void)),
198446808Sdab EncryptStopOutput P((void)),
198556642Sralph EncryptStatus P((void));
198656642Sralph static int
198746808Sdab EncryptHelp P((void));
198846808Sdab
198946808Sdab struct encryptlist EncryptList[] = {
199046808Sdab { "enable", "Enable encryption. ('encrypt enable ?' for more)",
199146808Sdab EncryptEnable, 1, 1, 2 },
199247609Sdab { "disable", "Disable encryption. ('encrypt enable ?' for more)",
199347609Sdab EncryptDisable, 0, 1, 2 },
199468343Sdab { "type", "Set encryption type. ('encrypt type ?' for more)",
199546808Sdab EncryptType, 0, 1, 1 },
199646808Sdab { "start", "Start encryption. ('encrypt start ?' for more)",
199746808Sdab EncryptStart, 1, 0, 1 },
199846808Sdab { "stop", "Stop encryption. ('encrypt stop ?' for more)",
199946808Sdab EncryptStop, 1, 0, 1 },
200046808Sdab { "input", "Start encrypting the input stream",
200146808Sdab EncryptStartInput, 1, 0, 0 },
200246808Sdab { "-input", "Stop encrypting the input stream",
200346808Sdab EncryptStopInput, 1, 0, 0 },
200446808Sdab { "output", "Start encrypting the output stream",
200546808Sdab EncryptStartOutput, 1, 0, 0 },
200646808Sdab { "-output", "Stop encrypting the output stream",
200746808Sdab EncryptStopOutput, 1, 0, 0 },
200846808Sdab
200946808Sdab { "status", "Display current status of authentication information",
201046808Sdab EncryptStatus, 0, 0, 0 },
201146808Sdab { "help", 0, EncryptHelp, 0, 0, 0 },
201246808Sdab { "?", "Print help information", EncryptHelp, 0, 0, 0 },
201346808Sdab { 0 },
201446808Sdab };
201546808Sdab
201646808Sdab static int
EncryptHelp()201746808Sdab EncryptHelp()
201836274Sminshall {
201946808Sdab struct encryptlist *c;
202046808Sdab
202146808Sdab for (c = EncryptList; c->name; c++) {
202246808Sdab if (c->help) {
202346808Sdab if (*c->help)
202446808Sdab printf("%-15s %s\n", c->name, c->help);
202546808Sdab else
202646808Sdab printf("\n");
202736274Sminshall }
202846808Sdab }
202946808Sdab return 0;
203046808Sdab }
203136274Sminshall
encrypt_cmd(argc,argv)203246808Sdab encrypt_cmd(argc, argv)
203346808Sdab int argc;
203446808Sdab char *argv[];
203546808Sdab {
203646808Sdab struct encryptlist *c;
203736274Sminshall
203868343Sdab if (argc < 2) {
203968343Sdab fprintf(stderr,
204068343Sdab "Need an argument to 'encrypt' command. 'encrypt ?' for help.\n");
204168343Sdab return 0;
204268343Sdab }
204368343Sdab
204446808Sdab c = (struct encryptlist *)
204546808Sdab genget(argv[1], (char **) EncryptList, sizeof(struct encryptlist));
204646808Sdab if (c == 0) {
2047*69785Sdab fprintf(stderr, "'%s': unknown argument ('encrypt ?' for help).\n",
204846808Sdab argv[1]);
2049*69785Sdab return 0;
205046808Sdab }
205146808Sdab if (Ambiguous(c)) {
2052*69785Sdab fprintf(stderr, "'%s': ambiguous argument ('encrypt ?' for help).\n",
205346808Sdab argv[1]);
2054*69785Sdab return 0;
205546808Sdab }
205646808Sdab argc -= 2;
205746808Sdab if (argc < c->minarg || argc > c->maxarg) {
205846808Sdab if (c->minarg == c->maxarg) {
205946808Sdab fprintf(stderr, "Need %s%d argument%s ",
206046808Sdab c->minarg < argc ? "only " : "", c->minarg,
206146808Sdab c->minarg == 1 ? "" : "s");
206246808Sdab } else {
206346808Sdab fprintf(stderr, "Need %s%d-%d arguments ",
206446808Sdab c->maxarg < argc ? "only " : "", c->minarg, c->maxarg);
206546808Sdab }
206646808Sdab fprintf(stderr, "to 'encrypt %s' command. 'encrypt ?' for help.\n",
206746808Sdab c->name);
206846808Sdab return 0;
206946808Sdab }
207046808Sdab if (c->needconnect && !connected) {
207146808Sdab if (!(argc && (isprefix(argv[2], "help") || isprefix(argv[2], "?")))) {
207246808Sdab printf("?Need to be connected first.\n");
207346808Sdab return 0;
207446808Sdab }
207546808Sdab }
207646808Sdab return ((*c->handler)(argc > 0 ? argv[2] : 0,
207746808Sdab argc > 1 ? argv[3] : 0,
207846808Sdab argc > 2 ? argv[4] : 0));
207946808Sdab }
208060149Sdab #endif /* ENCRYPTION */
208136274Sminshall
208246808Sdab #if defined(unix) && defined(TN3270)
208346808Sdab static void
filestuff(fd)208436274Sminshall filestuff(fd)
208546808Sdab int fd;
208636274Sminshall {
208736274Sminshall int res;
208836274Sminshall
208938689Sborman #ifdef F_GETOWN
209038689Sborman setconnmode(0);
209136274Sminshall res = fcntl(fd, F_GETOWN, 0);
209236274Sminshall setcommandmode();
209336274Sminshall
209436274Sminshall if (res == -1) {
209536274Sminshall perror("fcntl");
209636274Sminshall return;
209736274Sminshall }
209836274Sminshall printf("\tOwner is %d.\n", res);
209938689Sborman #endif
210036274Sminshall
210138689Sborman setconnmode(0);
210236274Sminshall res = fcntl(fd, F_GETFL, 0);
210336274Sminshall setcommandmode();
210436274Sminshall
210536274Sminshall if (res == -1) {
210636274Sminshall perror("fcntl");
210736274Sminshall return;
210836274Sminshall }
210959893Sbostic #ifdef notdef
211036274Sminshall printf("\tFlags are 0x%x: %s\n", res, decodeflags(res));
211159893Sbostic #endif
211236274Sminshall }
211346808Sdab #endif /* defined(unix) && defined(TN3270) */
211436274Sminshall
211536274Sminshall /*
211632144Sminshall * Print status about the connection.
211732144Sminshall */
211846808Sdab /*ARGSUSED*/
211946808Sdab static
status(argc,argv)212032144Sminshall status(argc, argv)
212146808Sdab int argc;
212246808Sdab char *argv[];
212332144Sminshall {
212432144Sminshall if (connected) {
212532144Sminshall printf("Connected to %s.\n", hostname);
212636242Sminshall if ((argc < 2) || strcmp(argv[1], "notmuch")) {
212738689Sborman int mode = getconnmode();
212838689Sborman
212938689Sborman if (my_want_state_is_will(TELOPT_LINEMODE)) {
213038689Sborman printf("Operating with LINEMODE option\n");
213138689Sborman printf("%s line editing\n", (mode&MODE_EDIT) ? "Local" : "No");
213238689Sborman printf("%s catching of signals\n",
213338689Sborman (mode&MODE_TRAPSIG) ? "Local" : "No");
213438689Sborman slcstate();
213538689Sborman #ifdef KLUDGELINEMODE
213639529Sborman } else if (kludgelinemode && my_want_state_is_dont(TELOPT_SGA)) {
213738689Sborman printf("Operating in obsolete linemode\n");
213838689Sborman #endif
213938689Sborman } else {
214038689Sborman printf("Operating in single character mode\n");
214138689Sborman if (localchars)
214238689Sborman printf("Catching signals locally\n");
214332144Sminshall }
214438689Sborman printf("%s character echo\n", (mode&MODE_ECHO) ? "Local" : "Remote");
214538689Sborman if (my_want_state_is_will(TELOPT_LFLOW))
214638689Sborman printf("%s flow control\n", (mode&MODE_FLOW) ? "Local" : "No");
214760149Sdab #ifdef ENCRYPTION
214846808Sdab encrypt_display();
214960149Sdab #endif /* ENCRYPTION */
215032144Sminshall }
215132144Sminshall } else {
215232144Sminshall printf("No connection.\n");
215332144Sminshall }
215432144Sminshall # if !defined(TN3270)
215532144Sminshall printf("Escape character is '%s'.\n", control(escape));
215634849Sminshall (void) fflush(stdout);
215732144Sminshall # else /* !defined(TN3270) */
215832144Sminshall if ((!In3270) && ((argc < 2) || strcmp(argv[1], "notmuch"))) {
215932144Sminshall printf("Escape character is '%s'.\n", control(escape));
216032144Sminshall }
216132144Sminshall # if defined(unix)
216236242Sminshall if ((argc >= 2) && !strcmp(argv[1], "everything")) {
216336242Sminshall printf("SIGIO received %d time%s.\n",
216436242Sminshall sigiocount, (sigiocount == 1)? "":"s");
216536274Sminshall if (In3270) {
216636274Sminshall printf("Process ID %d, process group %d.\n",
216736274Sminshall getpid(), getpgrp(getpid()));
216836274Sminshall printf("Terminal input:\n");
216936274Sminshall filestuff(tin);
217036274Sminshall printf("Terminal output:\n");
217136274Sminshall filestuff(tout);
217236274Sminshall printf("Network socket:\n");
217336274Sminshall filestuff(net);
217436274Sminshall }
217536242Sminshall }
217632144Sminshall if (In3270 && transcom) {
217732144Sminshall printf("Transparent mode command is '%s'.\n", transcom);
217832144Sminshall }
217932144Sminshall # endif /* defined(unix) */
218034849Sminshall (void) fflush(stdout);
218132144Sminshall if (In3270) {
218232144Sminshall return 0;
218332144Sminshall }
218432144Sminshall # endif /* defined(TN3270) */
218532144Sminshall return 1;
218632144Sminshall }
218732144Sminshall
218845233Sborman #ifdef SIGINFO
218945233Sborman /*
219045233Sborman * Function that gets called when SIGINFO is received.
219145233Sborman */
ayt_status()219245233Sborman ayt_status()
219345233Sborman {
219445233Sborman (void) call(status, "status", "notmuch", 0);
219545233Sborman }
219645233Sborman #endif
219732144Sminshall
219858972Sdab unsigned long inet_addr();
219958972Sdab
220046808Sdab int
tn(argc,argv)220132144Sminshall tn(argc, argv)
220246808Sdab int argc;
220346808Sdab char *argv[];
220432144Sminshall {
220532144Sminshall register struct hostent *host = 0;
220632144Sminshall struct sockaddr_in sin;
220732144Sminshall struct servent *sp = 0;
220858972Sdab unsigned long temp;
220937219Sminshall extern char *inet_ntoa();
221046808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP)
221138689Sborman char *srp = 0, *strrchr();
221238689Sborman unsigned long sourceroute(), srlen;
221338689Sborman #endif
221444361Sborman char *cmd, *hostp = 0, *portp = 0, *user = 0;
221532144Sminshall
221645233Sborman /* clear the socket address prior to use */
2217*69785Sdab memset((char *)&sin, 0, sizeof(sin));
221832144Sminshall
221932144Sminshall if (connected) {
222032144Sminshall printf("?Already connected to %s\n", hostname);
222146808Sdab setuid(getuid());
222232144Sminshall return 0;
222332144Sminshall }
222432144Sminshall if (argc < 2) {
222546808Sdab (void) strcpy(line, "open ");
222632144Sminshall printf("(to) ");
222746808Sdab (void) fgets(&line[strlen(line)], sizeof(line) - strlen(line), stdin);
222832144Sminshall makeargv();
222932144Sminshall argc = margc;
223032144Sminshall argv = margv;
223132144Sminshall }
223244361Sborman cmd = *argv;
223344361Sborman --argc; ++argv;
223444361Sborman while (argc) {
223568343Sdab if (strcmp(*argv, "help") == 0 || isprefix(*argv, "?"))
223646808Sdab goto usage;
223744361Sborman if (strcmp(*argv, "-l") == 0) {
223844361Sborman --argc; ++argv;
223944361Sborman if (argc == 0)
224044361Sborman goto usage;
224144361Sborman user = *argv++;
224244361Sborman --argc;
224344361Sborman continue;
224444361Sborman }
224545233Sborman if (strcmp(*argv, "-a") == 0) {
224645233Sborman --argc; ++argv;
224745233Sborman autologin = 1;
224845233Sborman continue;
224945233Sborman }
225044361Sborman if (hostp == 0) {
225144361Sborman hostp = *argv++;
225244361Sborman --argc;
225344361Sborman continue;
225444361Sborman }
225544361Sborman if (portp == 0) {
225644361Sborman portp = *argv++;
225744361Sborman --argc;
225844361Sborman continue;
225944361Sborman }
226044361Sborman usage:
226145233Sborman printf("usage: %s [-l user] [-a] host-name [port]\n", cmd);
226246808Sdab setuid(getuid());
226332144Sminshall return 0;
226432144Sminshall }
226546808Sdab if (hostp == 0)
226646808Sdab goto usage;
226746808Sdab
226846808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP)
226944361Sborman if (hostp[0] == '@' || hostp[0] == '!') {
227044361Sborman if ((hostname = strrchr(hostp, ':')) == NULL)
227144361Sborman hostname = strrchr(hostp, '@');
227238689Sborman hostname++;
227338689Sborman srp = 0;
227444361Sborman temp = sourceroute(hostp, &srp, &srlen);
227538689Sborman if (temp == 0) {
227638689Sborman herror(srp);
227746808Sdab setuid(getuid());
227838689Sborman return 0;
227938689Sborman } else if (temp == -1) {
228044361Sborman printf("Bad source route option: %s\n", hostp);
228146808Sdab setuid(getuid());
228238689Sborman return 0;
228338689Sborman } else {
228438689Sborman sin.sin_addr.s_addr = temp;
228538689Sborman sin.sin_family = AF_INET;
228638689Sborman }
228732144Sminshall } else {
228838689Sborman #endif
228944361Sborman temp = inet_addr(hostp);
229038689Sborman if (temp != (unsigned long) -1) {
229138689Sborman sin.sin_addr.s_addr = temp;
229238689Sborman sin.sin_family = AF_INET;
229346808Sdab (void) strcpy(_hostname, hostp);
229446808Sdab hostname = _hostname;
229538689Sborman } else {
229644361Sborman host = gethostbyname(hostp);
229738689Sborman if (host) {
229838689Sborman sin.sin_family = host->h_addrtype;
229932144Sminshall #if defined(h_addr) /* In 4.3, this is a #define */
2300*69785Sdab memmove((caddr_t)&sin.sin_addr,
230132144Sminshall host->h_addr_list[0], host->h_length);
230232144Sminshall #else /* defined(h_addr) */
2303*69785Sdab memmove((caddr_t)&sin.sin_addr, host->h_addr, host->h_length);
230432144Sminshall #endif /* defined(h_addr) */
230546808Sdab strncpy(_hostname, host->h_name, sizeof(_hostname));
230646808Sdab _hostname[sizeof(_hostname)-1] = '\0';
230746808Sdab hostname = _hostname;
230838689Sborman } else {
230944361Sborman herror(hostp);
2310*69785Sdab setuid(getuid());
231138689Sborman return 0;
231238689Sborman }
231332144Sminshall }
231446808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP)
231532144Sminshall }
231638689Sborman #endif
231744361Sborman if (portp) {
231844361Sborman if (*portp == '-') {
231944361Sborman portp++;
232038689Sborman telnetport = 1;
232138689Sborman } else
232238689Sborman telnetport = 0;
232344361Sborman sin.sin_port = atoi(portp);
232432144Sminshall if (sin.sin_port == 0) {
232544361Sborman sp = getservbyname(portp, "tcp");
232632144Sminshall if (sp)
232732144Sminshall sin.sin_port = sp->s_port;
232832144Sminshall else {
232944361Sborman printf("%s: bad port number\n", portp);
2330*69785Sdab setuid(getuid());
233132144Sminshall return 0;
233232144Sminshall }
233332144Sminshall } else {
233457213Sdab #if !defined(htons)
233560890Sdab u_short htons P((unsigned short));
233657213Sdab #endif /* !defined(htons) */
233732144Sminshall sin.sin_port = htons(sin.sin_port);
233832144Sminshall }
233932144Sminshall } else {
234032144Sminshall if (sp == 0) {
234132144Sminshall sp = getservbyname("telnet", "tcp");
234232144Sminshall if (sp == 0) {
234334849Sminshall fprintf(stderr, "telnet: tcp/telnet: unknown service\n");
2344*69785Sdab setuid(getuid());
234532144Sminshall return 0;
234632144Sminshall }
234732144Sminshall sin.sin_port = sp->s_port;
234832144Sminshall }
234932144Sminshall telnetport = 1;
235032144Sminshall }
235137219Sminshall printf("Trying %s...\n", inet_ntoa(sin.sin_addr));
235232144Sminshall do {
235332144Sminshall net = socket(AF_INET, SOCK_STREAM, 0);
235446808Sdab setuid(getuid());
235532144Sminshall if (net < 0) {
235632144Sminshall perror("telnet: socket");
235732144Sminshall return 0;
235832144Sminshall }
235946808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP)
236038689Sborman if (srp && setsockopt(net, IPPROTO_IP, IP_OPTIONS, (char *)srp, srlen) < 0)
236138689Sborman perror("setsockopt (IP_OPTIONS)");
236238689Sborman #endif
236346808Sdab #if defined(IPPROTO_IP) && defined(IP_TOS)
236446808Sdab {
236546808Sdab # if defined(HAS_GETTOS)
236646808Sdab struct tosent *tp;
236746815Sdab if (tos < 0 && (tp = gettosbyname("telnet", "tcp")))
236846808Sdab tos = tp->t_tos;
236946808Sdab # endif
237046815Sdab if (tos < 0)
237146815Sdab tos = 020; /* Low Delay bit */
237246815Sdab if (tos
237357213Sdab && (setsockopt(net, IPPROTO_IP, IP_TOS,
237457213Sdab (char *)&tos, sizeof(int)) < 0)
237546815Sdab && (errno != ENOPROTOOPT))
237646815Sdab perror("telnet: setsockopt (IP_TOS) (ignored)");
237746808Sdab }
237846808Sdab #endif /* defined(IPPROTO_IP) && defined(IP_TOS) */
237940245Sborman
238032144Sminshall if (debug && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 1) < 0) {
238132144Sminshall perror("setsockopt (SO_DEBUG)");
238232144Sminshall }
238332144Sminshall
238432144Sminshall if (connect(net, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
238532144Sminshall #if defined(h_addr) /* In 4.3, this is a #define */
238632144Sminshall if (host && host->h_addr_list[1]) {
238732144Sminshall int oerrno = errno;
238832144Sminshall
238932144Sminshall fprintf(stderr, "telnet: connect to address %s: ",
239032144Sminshall inet_ntoa(sin.sin_addr));
239132144Sminshall errno = oerrno;
239232144Sminshall perror((char *)0);
239332144Sminshall host->h_addr_list++;
2394*69785Sdab memmove((caddr_t)&sin.sin_addr,
239532144Sminshall host->h_addr_list[0], host->h_length);
239632144Sminshall (void) NetClose(net);
239732144Sminshall continue;
239832144Sminshall }
239932144Sminshall #endif /* defined(h_addr) */
240032144Sminshall perror("telnet: Unable to connect to remote host");
240132144Sminshall return 0;
240237219Sminshall }
240332144Sminshall connected++;
240457213Sdab #if defined(AUTHENTICATION) || defined(ENCRYPTION)
240546808Sdab auth_encrypt_connect(connected);
240660149Sdab #endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */
240732144Sminshall } while (connected == 0);
240844361Sborman cmdrc(hostp, hostname);
240945008Skarels if (autologin && user == NULL) {
241045008Skarels struct passwd *pw;
241145008Skarels
241245233Sborman user = getenv("USER");
241345008Skarels if (user == NULL ||
241445233Sborman (pw = getpwnam(user)) && pw->pw_uid != getuid()) {
241545233Sborman if (pw = getpwuid(getuid()))
241645008Skarels user = pw->pw_name;
241745008Skarels else
241845008Skarels user = NULL;
241945233Sborman }
242045008Skarels }
242145008Skarels if (user) {
242246808Sdab env_define((unsigned char *)"USER", (unsigned char *)user);
242346808Sdab env_export((unsigned char *)"USER");
242445008Skarels }
242534849Sminshall (void) call(status, "status", "notmuch", 0);
242632144Sminshall if (setjmp(peerdied) == 0)
242746808Sdab telnet(user);
242834849Sminshall (void) NetClose(net);
242932381Sminshall ExitString("Connection closed by foreign host.\n",1);
243032144Sminshall /*NOTREACHED*/
243132144Sminshall }
243232144Sminshall
243332144Sminshall #define HELPINDENT (sizeof ("connect"))
243432144Sminshall
243532144Sminshall static char
243632144Sminshall openhelp[] = "connect to a site",
243732144Sminshall closehelp[] = "close current connection",
243846808Sdab logouthelp[] = "forcibly logout remote user and close the connection",
243932144Sminshall quithelp[] = "exit telnet",
244032144Sminshall statushelp[] = "print status information",
244132144Sminshall helphelp[] = "print help information",
244232144Sminshall sendhelp[] = "transmit special characters ('send ?' for more)",
244332144Sminshall sethelp[] = "set operating parameters ('set ?' for more)",
244438689Sborman unsethelp[] = "unset operating parameters ('unset ?' for more)",
244532144Sminshall togglestring[] ="toggle operating parameters ('toggle ?' for more)",
244638689Sborman slchelp[] = "change state of special charaters ('slc ?' for more)",
244732144Sminshall displayhelp[] = "display operating parameters",
244832144Sminshall #if defined(TN3270) && defined(unix)
244932144Sminshall transcomhelp[] = "specify Unix command for transparent mode pipe",
245032144Sminshall #endif /* defined(TN3270) && defined(unix) */
245157213Sdab #if defined(AUTHENTICATION)
245246808Sdab authhelp[] = "turn on (off) authentication ('auth ?' for more)",
245346808Sdab #endif
245460149Sdab #ifdef ENCRYPTION
245546808Sdab encrypthelp[] = "turn on (off) encryption ('encrypt ?' for more)",
245660149Sdab #endif /* ENCRYPTION */
245732144Sminshall #if defined(unix)
245832144Sminshall zhelp[] = "suspend telnet",
245943317Skfall #endif /* defined(unix) */
246032144Sminshall shellhelp[] = "invoke a subshell",
246144361Sborman envhelp[] = "change environment variables ('environ ?' for more)",
246244361Sborman modestring[] = "try to enter line or character mode ('mode ?' for more)";
246332144Sminshall
246456642Sralph static int help();
246532144Sminshall
246632144Sminshall static Command cmdtab[] = {
246738689Sborman { "close", closehelp, bye, 1 },
246846808Sdab { "logout", logouthelp, logout, 1 },
246938689Sborman { "display", displayhelp, display, 0 },
247038689Sborman { "mode", modestring, modecmd, 0 },
247138689Sborman { "open", openhelp, tn, 0 },
247238689Sborman { "quit", quithelp, quit, 0 },
247338689Sborman { "send", sendhelp, sendcmd, 0 },
247438689Sborman { "set", sethelp, setcmd, 0 },
247538689Sborman { "unset", unsethelp, unsetcmd, 0 },
247638689Sborman { "status", statushelp, status, 0 },
247738689Sborman { "toggle", togglestring, toggle, 0 },
247838689Sborman { "slc", slchelp, slccmd, 0 },
247932144Sminshall #if defined(TN3270) && defined(unix)
248038689Sborman { "transcom", transcomhelp, settranscom, 0 },
248132144Sminshall #endif /* defined(TN3270) && defined(unix) */
248257213Sdab #if defined(AUTHENTICATION)
248346808Sdab { "auth", authhelp, auth_cmd, 0 },
248446808Sdab #endif
248560149Sdab #ifdef ENCRYPTION
248646808Sdab { "encrypt", encrypthelp, encrypt_cmd, 0 },
248760149Sdab #endif /* ENCRYPTION */
248832144Sminshall #if defined(unix)
248938689Sborman { "z", zhelp, suspend, 0 },
249032144Sminshall #endif /* defined(unix) */
249132144Sminshall #if defined(TN3270)
249238689Sborman { "!", shellhelp, shell, 1 },
249338689Sborman #else
249438689Sborman { "!", shellhelp, shell, 0 },
249538689Sborman #endif
249644361Sborman { "environ", envhelp, env_cmd, 0 },
249738689Sborman { "?", helphelp, help, 0 },
249832144Sminshall 0
249932144Sminshall };
250032144Sminshall
250132144Sminshall static char crmodhelp[] = "deprecated command -- use 'toggle crmod' instead";
250232144Sminshall static char escapehelp[] = "deprecated command -- use 'set escape' instead";
250332144Sminshall
250432144Sminshall static Command cmdtab2[] = {
250538689Sborman { "help", 0, help, 0 },
250638689Sborman { "escape", escapehelp, setescape, 0 },
250738689Sborman { "crmod", crmodhelp, togcrmod, 0 },
250832144Sminshall 0
250932144Sminshall };
251032144Sminshall
251135298Sminshall
251232144Sminshall /*
251332144Sminshall * Call routine with argc, argv set from args (terminated by 0).
251432144Sminshall */
251535298Sminshall
251646808Sdab /*VARARGS1*/
251746808Sdab static
call(va_alist)251835298Sminshall call(va_alist)
251946808Sdab va_dcl
252032144Sminshall {
252135298Sminshall va_list ap;
252235298Sminshall typedef int (*intrtn_t)();
252335298Sminshall intrtn_t routine;
252435298Sminshall char *args[100];
252535298Sminshall int argno = 0;
252635298Sminshall
252735298Sminshall va_start(ap);
252835298Sminshall routine = (va_arg(ap, intrtn_t));
252935495Sminshall while ((args[argno++] = va_arg(ap, char *)) != 0) {
253035298Sminshall ;
253135495Sminshall }
253235298Sminshall va_end(ap);
253335495Sminshall return (*routine)(argno-1, args);
253432144Sminshall }
253532144Sminshall
253635298Sminshall
253746808Sdab static Command *
getcmd(name)253832144Sminshall getcmd(name)
253946808Sdab char *name;
254032144Sminshall {
254132144Sminshall Command *cm;
254232144Sminshall
254346808Sdab if (cm = (Command *) genget(name, (char **) cmdtab, sizeof(Command)))
254432144Sminshall return cm;
254546808Sdab return (Command *) genget(name, (char **) cmdtab2, sizeof(Command));
254632144Sminshall }
254732144Sminshall
254846808Sdab void
command(top,tbuf,cnt)254938689Sborman command(top, tbuf, cnt)
255046808Sdab int top;
255146808Sdab char *tbuf;
255246808Sdab int cnt;
255332144Sminshall {
255432144Sminshall register Command *c;
255532144Sminshall
255632144Sminshall setcommandmode();
255732144Sminshall if (!top) {
255832144Sminshall putchar('\n');
255937219Sminshall #if defined(unix)
256032144Sminshall } else {
256144361Sborman (void) signal(SIGINT, SIG_DFL);
256244361Sborman (void) signal(SIGQUIT, SIG_DFL);
256332144Sminshall #endif /* defined(unix) */
256432144Sminshall }
256532144Sminshall for (;;) {
256646808Sdab if (rlogin == _POSIX_VDISABLE)
256746808Sdab printf("%s> ", prompt);
256838689Sborman if (tbuf) {
256938689Sborman register char *cp;
257038689Sborman cp = line;
257138689Sborman while (cnt > 0 && (*cp++ = *tbuf++) != '\n')
257238689Sborman cnt--;
257338689Sborman tbuf = 0;
257438689Sborman if (cp == line || *--cp != '\n' || cp == line)
257538689Sborman goto getline;
257638689Sborman *cp = '\0';
257746808Sdab if (rlogin == _POSIX_VDISABLE)
2578*69785Sdab printf("%s\n", line);
257938689Sborman } else {
258038689Sborman getline:
258146808Sdab if (rlogin != _POSIX_VDISABLE)
258246808Sdab printf("%s> ", prompt);
258346808Sdab if (fgets(line, sizeof(line), stdin) == NULL) {
258444361Sborman if (feof(stdin) || ferror(stdin)) {
258544361Sborman (void) quit();
258644361Sborman /*NOTREACHED*/
258744361Sborman }
258838689Sborman break;
258938689Sborman }
259032144Sminshall }
259132144Sminshall if (line[0] == 0)
259232144Sminshall break;
259332144Sminshall makeargv();
259437219Sminshall if (margv[0] == 0) {
259537219Sminshall break;
259637219Sminshall }
259732144Sminshall c = getcmd(margv[0]);
259832144Sminshall if (Ambiguous(c)) {
259932144Sminshall printf("?Ambiguous command\n");
260032144Sminshall continue;
260132144Sminshall }
260232144Sminshall if (c == 0) {
260332144Sminshall printf("?Invalid command\n");
260432144Sminshall continue;
260532144Sminshall }
260632144Sminshall if (c->needconnect && !connected) {
260732144Sminshall printf("?Need to be connected first.\n");
260832144Sminshall continue;
260932144Sminshall }
261032144Sminshall if ((*c->handler)(margc, margv)) {
261132144Sminshall break;
261232144Sminshall }
261332144Sminshall }
261432144Sminshall if (!top) {
261532144Sminshall if (!connected) {
261632144Sminshall longjmp(toplevel, 1);
261732144Sminshall /*NOTREACHED*/
261832144Sminshall }
261932144Sminshall #if defined(TN3270)
262032144Sminshall if (shell_active == 0) {
262138689Sborman setconnmode(0);
262232144Sminshall }
262332144Sminshall #else /* defined(TN3270) */
262438689Sborman setconnmode(0);
262532144Sminshall #endif /* defined(TN3270) */
262632144Sminshall }
262732144Sminshall }
262832144Sminshall
262932144Sminshall /*
263032144Sminshall * Help command.
263132144Sminshall */
263246808Sdab static
help(argc,argv)263332144Sminshall help(argc, argv)
263432144Sminshall int argc;
263532144Sminshall char *argv[];
263632144Sminshall {
263732144Sminshall register Command *c;
263832144Sminshall
263932144Sminshall if (argc == 1) {
264032144Sminshall printf("Commands may be abbreviated. Commands are:\n\n");
264132144Sminshall for (c = cmdtab; c->name; c++)
264238689Sborman if (c->help) {
264332144Sminshall printf("%-*s\t%s\n", HELPINDENT, c->name,
264432144Sminshall c->help);
264532144Sminshall }
264632144Sminshall return 0;
264732144Sminshall }
264832144Sminshall while (--argc > 0) {
264932144Sminshall register char *arg;
265032144Sminshall arg = *++argv;
265132144Sminshall c = getcmd(arg);
265232144Sminshall if (Ambiguous(c))
265332144Sminshall printf("?Ambiguous help command %s\n", arg);
265432144Sminshall else if (c == (Command *)0)
265532144Sminshall printf("?Invalid help command %s\n", arg);
265632144Sminshall else
265732144Sminshall printf("%s\n", c->help);
265832144Sminshall }
265932144Sminshall return 0;
266032144Sminshall }
266138689Sborman
266238689Sborman static char *rcname = 0;
266338689Sborman static char rcbuf[128];
266438689Sborman
cmdrc(m1,m2)266538689Sborman cmdrc(m1, m2)
266638689Sborman char *m1, *m2;
266738689Sborman {
266838689Sborman register Command *c;
266938689Sborman FILE *rcfile;
267038689Sborman int gotmachine = 0;
267138689Sborman int l1 = strlen(m1);
267238689Sborman int l2 = strlen(m2);
267338689Sborman char m1save[64];
267438689Sborman
267547609Sdab if (skiprc)
267647609Sdab return;
267747609Sdab
267838689Sborman strcpy(m1save, m1);
267938689Sborman m1 = m1save;
268038689Sborman
268138689Sborman if (rcname == 0) {
268238689Sborman rcname = getenv("HOME");
268338689Sborman if (rcname)
268438689Sborman strcpy(rcbuf, rcname);
268538689Sborman else
268638689Sborman rcbuf[0] = '\0';
268738689Sborman strcat(rcbuf, "/.telnetrc");
268838689Sborman rcname = rcbuf;
268938689Sborman }
269038689Sborman
269138689Sborman if ((rcfile = fopen(rcname, "r")) == 0) {
269238689Sborman return;
269338689Sborman }
269438689Sborman
269538689Sborman for (;;) {
269638689Sborman if (fgets(line, sizeof(line), rcfile) == NULL)
269738689Sborman break;
269838689Sborman if (line[0] == 0)
269938689Sborman break;
270038689Sborman if (line[0] == '#')
270138689Sborman continue;
270247609Sdab if (gotmachine) {
270347609Sdab if (!isspace(line[0]))
270447609Sdab gotmachine = 0;
270547609Sdab }
270638689Sborman if (gotmachine == 0) {
270738689Sborman if (isspace(line[0]))
270838689Sborman continue;
270938689Sborman if (strncasecmp(line, m1, l1) == 0)
271038689Sborman strncpy(line, &line[l1], sizeof(line) - l1);
271138689Sborman else if (strncasecmp(line, m2, l2) == 0)
271238689Sborman strncpy(line, &line[l2], sizeof(line) - l2);
271347609Sdab else if (strncasecmp(line, "DEFAULT", 7) == 0)
271447609Sdab strncpy(line, &line[7], sizeof(line) - 7);
271538689Sborman else
271638689Sborman continue;
271747609Sdab if (line[0] != ' ' && line[0] != '\t' && line[0] != '\n')
271847609Sdab continue;
271938689Sborman gotmachine = 1;
272038689Sborman }
272138689Sborman makeargv();
272238689Sborman if (margv[0] == 0)
272338689Sborman continue;
272438689Sborman c = getcmd(margv[0]);
272538689Sborman if (Ambiguous(c)) {
272638689Sborman printf("?Ambiguous command: %s\n", margv[0]);
272738689Sborman continue;
272838689Sborman }
272938689Sborman if (c == 0) {
273038689Sborman printf("?Invalid command: %s\n", margv[0]);
273138689Sborman continue;
273238689Sborman }
273338689Sborman /*
273438689Sborman * This should never happen...
273538689Sborman */
273638689Sborman if (c->needconnect && !connected) {
273738689Sborman printf("?Need to be connected first for %s.\n", margv[0]);
273838689Sborman continue;
273938689Sborman }
274038689Sborman (*c->handler)(margc, margv);
274138689Sborman }
274238689Sborman fclose(rcfile);
274338689Sborman }
274438689Sborman
274546808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP)
274638689Sborman
274738689Sborman /*
274838689Sborman * Source route is handed in as
274938689Sborman * [!]@hop1@hop2...[@|:]dst
275038689Sborman * If the leading ! is present, it is a
275138689Sborman * strict source route, otherwise it is
275238689Sborman * assmed to be a loose source route.
275338689Sborman *
275438689Sborman * We fill in the source route option as
275538689Sborman * hop1,hop2,hop3...dest
275638689Sborman * and return a pointer to hop1, which will
275738689Sborman * be the address to connect() to.
275838689Sborman *
275938689Sborman * Arguments:
276038689Sborman * arg: pointer to route list to decipher
276138689Sborman *
276238689Sborman * cpp: If *cpp is not equal to NULL, this is a
276338689Sborman * pointer to a pointer to a character array
276438689Sborman * that should be filled in with the option.
276538689Sborman *
276638689Sborman * lenp: pointer to an integer that contains the
276738689Sborman * length of *cpp if *cpp != NULL.
276838689Sborman *
276938689Sborman * Return values:
277038689Sborman *
277138689Sborman * Returns the address of the host to connect to. If the
277238689Sborman * return value is -1, there was a syntax error in the
277338689Sborman * option, either unknown characters, or too many hosts.
277438689Sborman * If the return value is 0, one of the hostnames in the
277538689Sborman * path is unknown, and *cpp is set to point to the bad
277638689Sborman * hostname.
277738689Sborman *
277838689Sborman * *cpp: If *cpp was equal to NULL, it will be filled
277938689Sborman * in with a pointer to our static area that has
278038689Sborman * the option filled in. This will be 32bit aligned.
2781*69785Sdab *
278238689Sborman * *lenp: This will be filled in with how long the option
278338689Sborman * pointed to by *cpp is.
2784*69785Sdab *
278538689Sborman */
278646808Sdab unsigned long
sourceroute(arg,cpp,lenp)278738689Sborman sourceroute(arg, cpp, lenp)
278846808Sdab char *arg;
278946808Sdab char **cpp;
279046808Sdab int *lenp;
279138689Sborman {
279238689Sborman static char lsr[44];
279357213Sdab #ifdef sysV88
279457213Sdab static IOPTN ipopt;
279557213Sdab #endif
279646808Sdab char *cp, *cp2, *lsrp, *lsrep;
279738689Sborman register int tmp;
279838689Sborman struct in_addr sin_addr;
279938689Sborman register struct hostent *host = 0;
280038689Sborman register char c;
280138689Sborman
280238689Sborman /*
280338689Sborman * Verify the arguments, and make sure we have
280438689Sborman * at least 7 bytes for the option.
280538689Sborman */
280638689Sborman if (cpp == NULL || lenp == NULL)
280738689Sborman return((unsigned long)-1);
280838689Sborman if (*cpp != NULL && *lenp < 7)
280938689Sborman return((unsigned long)-1);
281038689Sborman /*
281138689Sborman * Decide whether we have a buffer passed to us,
281238689Sborman * or if we need to use our own static buffer.
281338689Sborman */
281438689Sborman if (*cpp) {
281538689Sborman lsrp = *cpp;
281638689Sborman lsrep = lsrp + *lenp;
281738689Sborman } else {
281838689Sborman *cpp = lsrp = lsr;
281938689Sborman lsrep = lsrp + 44;
282038689Sborman }
282138689Sborman
282238689Sborman cp = arg;
282338689Sborman
282438689Sborman /*
282538689Sborman * Next, decide whether we have a loose source
282638689Sborman * route or a strict source route, and fill in
282738689Sborman * the begining of the option.
282838689Sborman */
282957213Sdab #ifndef sysV88
283038689Sborman if (*cp == '!') {
283138689Sborman cp++;
283238689Sborman *lsrp++ = IPOPT_SSRR;
283338689Sborman } else
283438689Sborman *lsrp++ = IPOPT_LSRR;
283557213Sdab #else
283657213Sdab if (*cp == '!') {
283757213Sdab cp++;
283857213Sdab ipopt.io_type = IPOPT_SSRR;
283957213Sdab } else
284057213Sdab ipopt.io_type = IPOPT_LSRR;
284157213Sdab #endif
284238689Sborman
284338689Sborman if (*cp != '@')
284438689Sborman return((unsigned long)-1);
284538689Sborman
284657213Sdab #ifndef sysV88
284738689Sborman lsrp++; /* skip over length, we'll fill it in later */
284838689Sborman *lsrp++ = 4;
284957213Sdab #endif
285038689Sborman
285138689Sborman cp++;
285238689Sborman
285338689Sborman sin_addr.s_addr = 0;
285438689Sborman
285538689Sborman for (c = 0;;) {
285638689Sborman if (c == ':')
285738689Sborman cp2 = 0;
285838689Sborman else for (cp2 = cp; c = *cp2; cp2++) {
285938689Sborman if (c == ',') {
286038689Sborman *cp2++ = '\0';
286138689Sborman if (*cp2 == '@')
286238689Sborman cp2++;
286338689Sborman } else if (c == '@') {
286438689Sborman *cp2++ = '\0';
286538689Sborman } else if (c == ':') {
286638689Sborman *cp2++ = '\0';
286738689Sborman } else
286838689Sborman continue;
286938689Sborman break;
287038689Sborman }
287138689Sborman if (!c)
287238689Sborman cp2 = 0;
287338689Sborman
287438689Sborman if ((tmp = inet_addr(cp)) != -1) {
287538689Sborman sin_addr.s_addr = tmp;
287638689Sborman } else if (host = gethostbyname(cp)) {
287738689Sborman #if defined(h_addr)
2878*69785Sdab memmove((caddr_t)&sin_addr,
287938689Sborman host->h_addr_list[0], host->h_length);
288038689Sborman #else
2881*69785Sdab memmove((caddr_t)&sin_addr, host->h_addr, host->h_length);
288238689Sborman #endif
288338689Sborman } else {
288438689Sborman *cpp = cp;
288538689Sborman return(0);
288638689Sborman }
2887*69785Sdab memmove(lsrp, (char *)&sin_addr, 4);
288838689Sborman lsrp += 4;
288938689Sborman if (cp2)
289038689Sborman cp = cp2;
289138689Sborman else
289238689Sborman break;
289338689Sborman /*
289438689Sborman * Check to make sure there is space for next address
289538689Sborman */
289638689Sborman if (lsrp + 4 > lsrep)
289738689Sborman return((unsigned long)-1);
289838689Sborman }
289957213Sdab #ifndef sysV88
290038689Sborman if ((*(*cpp+IPOPT_OLEN) = lsrp - *cpp) <= 7) {
290138689Sborman *cpp = 0;
290238689Sborman *lenp = 0;
290338689Sborman return((unsigned long)-1);
290438689Sborman }
290538689Sborman *lsrp++ = IPOPT_NOP; /* 32 bit word align it */
290638689Sborman *lenp = lsrp - *cpp;
290757213Sdab #else
290857213Sdab ipopt.io_len = lsrp - *cpp;
290957213Sdab if (ipopt.io_len <= 5) { /* Is 3 better ? */
291057213Sdab *cpp = 0;
291157213Sdab *lenp = 0;
291257213Sdab return((unsigned long)-1);
291357213Sdab }
291457213Sdab *lenp = sizeof(ipopt);
291557213Sdab *cpp = (char *) &ipopt;
291657213Sdab #endif
291738689Sborman return(sin_addr.s_addr);
291838689Sborman }
291938689Sborman #endif
2920