]>
git.saurik.com Git - apple/network_cmds.git/blob - telnet.tproj/commands.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
25 * Copyright (c) 1988, 1990, 1993
26 * The Regents of the University of California. All rights reserved.
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
31 * 1. Redistributions of source code must retain the above copyright
32 * notice, this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright
34 * notice, this list of conditions and the following disclaimer in the
35 * documentation and/or other materials provided with the distribution.
36 * 3. All advertising materials mentioning features or use of this software
37 * must display the following acknowledgement:
38 * This product includes software developed by the University of
39 * California, Berkeley and its contributors.
40 * 4. Neither the name of the University nor the names of its contributors
41 * may be used to endorse or promote products derived from this software
42 * without specific prior written permission.
44 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 static char sccsid
[] = "@(#)commands.c 8.4 (Berkeley) 5/30/95";
61 #if defined(unix) || defined(__APPLE__)
62 #include <sys/param.h>
63 #if defined(CRAY) || defined(sysV88)
64 #include <sys/types.h>
68 #include <sys/types.h>
69 #endif /* defined(unix) || defined(__APPLE__) */
70 #include <sys/socket.h>
71 #include <netinet/in.h>
80 #if !defined(__APPLE__)
85 #include <arpa/telnet.h>
95 #if !defined(CRAY) && !defined(sysV88)
96 #include <netinet/in_systm.h>
97 # if (defined(vax) || defined(tahoe) || defined(hp300)) && !defined(ultrix)
98 # include <machine/endian.h>
100 #endif /* !defined(CRAY) && !defined(sysV88) */
101 #include <netinet/ip.h>
104 #ifndef MAXHOSTNAMELEN
105 #define MAXHOSTNAMELEN 64
106 #endif MAXHOSTNAMELEN
108 #if defined(IPPROTO_IP) && defined(IP_TOS)
110 #endif /* defined(IPPROTO_IP) && defined(IP_TOS) */
113 static char _hostname
[MAXHOSTNAMELEN
];
115 extern char *getenv();
117 extern int isprefix();
118 extern char **genget();
119 extern int Ambiguous();
121 typedef int (*intrtn_t
)();
123 static call(intrtn_t routine
, ...);
129 char *name
; /* command name */
130 char *help
; /* help string (NULL for no help) */
131 int (*handler
)(); /* routine which executes command */
132 int needconnect
; /* Do we need to be connected to execute? */
135 static char line
[256];
136 static char saveline
[256];
138 static char *margv
[20];
143 register char *cp
, *cp2
, c
;
144 register char **argp
= margv
;
148 if (*cp
== '!') { /* Special case shell escape */
149 strcpy(saveline
, line
); /* save for shell command */
150 *argp
++ = "!"; /* No room in string to get this */
155 register int inquote
= 0;
162 for (cp2
= cp
; c
!= '\0'; c
= *++cp
) {
170 if ((c
= *++cp
) == '\0')
172 } else if (c
== '"') {
175 } else if (c
== '\'') {
178 } else if (isspace(c
))
192 * Make a character string into a number.
194 * Todo: 1. Could take random integers (12, 0x12, 012, 0b1).
208 c
= b
| 0x40; /* DEL */
221 * Construct a control character sequence
222 * for a special character.
230 * The only way I could get the Sun 3.5 compiler
232 * if ((unsigned int)c >= 0x80)
233 * was to assign "c" to an unsigned int variable...
236 register unsigned int uic
= (unsigned int)c
;
240 if (c
== (cc_t
)_POSIX_VDISABLE
) {
245 buf
[1] = ((c
>>6)&07) + '0';
246 buf
[2] = ((c
>>3)&07) + '0';
247 buf
[3] = (c
&07) + '0';
249 } else if (uic
>= 0x20) {
263 * The following are data structures and routines for
264 * the "send" command.
269 char *name
; /* How user refers to it (case independent) */
270 char *help
; /* Help information (0 ==> no help) */
271 int needconnect
; /* Need to be connected */
272 int narg
; /* Number of arguments */
273 int (*handler
)(); /* Routine to perform (for special ops) */
274 int nbyte
; /* Number of bytes to send this command */
275 int what
; /* Character to be sent (<0 ==> special) */
282 send_docmd
P((char *)),
283 send_dontcmd
P((char *)),
284 send_willcmd
P((char *)),
285 send_wontcmd
P((char *));
287 static struct sendlist Sendlist
[] = {
288 { "ao", "Send Telnet Abort output", 1, 0, 0, 2, AO
},
289 { "ayt", "Send Telnet 'Are You There'", 1, 0, 0, 2, AYT
},
290 { "brk", "Send Telnet Break", 1, 0, 0, 2, BREAK
},
291 { "break", 0, 1, 0, 0, 2, BREAK
},
292 { "ec", "Send Telnet Erase Character", 1, 0, 0, 2, EC
},
293 { "el", "Send Telnet Erase Line", 1, 0, 0, 2, EL
},
294 { "escape", "Send current escape character", 1, 0, send_esc
, 1, 0 },
295 { "ga", "Send Telnet 'Go Ahead' sequence", 1, 0, 0, 2, GA
},
296 { "ip", "Send Telnet Interrupt Process", 1, 0, 0, 2, IP
},
297 { "intp", 0, 1, 0, 0, 2, IP
},
298 { "interrupt", 0, 1, 0, 0, 2, IP
},
299 { "intr", 0, 1, 0, 0, 2, IP
},
300 { "nop", "Send Telnet 'No operation'", 1, 0, 0, 2, NOP
},
301 { "eor", "Send Telnet 'End of Record'", 1, 0, 0, 2, EOR
},
302 { "abort", "Send Telnet 'Abort Process'", 1, 0, 0, 2, ABORT
},
303 { "susp", "Send Telnet 'Suspend Process'", 1, 0, 0, 2, SUSP
},
304 { "eof", "Send Telnet End of File Character", 1, 0, 0, 2, xEOF
},
305 { "synch", "Perform Telnet 'Synch operation'", 1, 0, dosynch
, 2, 0 },
306 { "getstatus", "Send request for STATUS", 1, 0, get_status
, 6, 0 },
307 { "?", "Display send options", 0, 0, send_help
, 0, 0 },
308 { "help", 0, 0, 0, send_help
, 0, 0 },
309 { "do", 0, 0, 1, send_docmd
, 3, 0 },
310 { "dont", 0, 0, 1, send_dontcmd
, 3, 0 },
311 { "will", 0, 0, 1, send_willcmd
, 3, 0 },
312 { "wont", 0, 0, 1, send_wontcmd
, 3, 0 },
316 #define GETSEND(name) ((struct sendlist *) genget(name, (char **) Sendlist, \
317 sizeof(struct sendlist)))
324 int count
; /* how many bytes we are going to need to send */
326 int question
= 0; /* was at least one argument a question */
327 struct sendlist
*s
; /* pointer to current command */
332 printf("need at least one argument for 'send' command\n");
333 printf("'send ?' for help\n");
337 * First, validate all the send arguments.
338 * In addition, we see how much space we are going to need, and
339 * whether or not we will be doing a "SYNCH" operation (which
340 * flushes the network queue).
343 for (i
= 1; i
< argc
; i
++) {
344 s
= GETSEND(argv
[i
]);
346 printf("Unknown send argument '%s'\n'send ?' for help.\n",
349 } else if (Ambiguous(s
)) {
350 printf("Ambiguous send argument '%s'\n'send ?' for help.\n",
354 if (i
+ s
->narg
>= argc
) {
356 "Need %d argument%s to 'send %s' command. 'send %s ?' for help.\n",
357 s
->narg
, s
->narg
== 1 ? "" : "s", s
->name
, s
->name
);
361 if (s
->handler
== send_help
) {
367 needconnect
+= s
->needconnect
;
369 if (!connected
&& needconnect
) {
370 printf("?Need to be connected first.\n");
371 printf("'send ?' for help\n");
374 /* Now, do we have enough room? */
375 if (NETROOM() < count
) {
376 printf("There is not enough room in the buffer TO the network\n");
377 printf("to process your request. Nothing will be done.\n");
378 printf("('send synch' will throw away most data in the network\n");
379 printf("buffer, if this might help.)\n");
382 /* OK, they are all OK, now go through again and actually send */
384 for (i
= 1; i
< argc
; i
++) {
385 if ((s
= GETSEND(argv
[i
])) == 0) {
386 fprintf(stderr
, "Telnet 'send' error - argument disappeared!\n");
392 success
+= (*s
->handler
)((s
->narg
> 0) ? argv
[i
+1] : 0,
393 (s
->narg
> 1) ? argv
[i
+2] : 0);
396 NET2ADD(IAC
, s
->what
);
397 printoption("SENT", IAC
, s
->what
);
400 return (count
== success
);
414 return(send_tncmd(send_do
, "do", name
));
421 return(send_tncmd(send_dont
, "dont", name
));
427 return(send_tncmd(send_will
, "will", name
));
433 return(send_tncmd(send_wont
, "wont", name
));
437 send_tncmd(func
, cmd
, name
)
442 extern char *telopts
[];
443 register int val
= 0;
445 if (isprefix(name
, "help") || isprefix(name
, "?")) {
446 register int col
, len
;
448 printf("Usage: send %s <value|option>\n", cmd
);
449 printf("\"value\" must be from 0 to 255\n");
450 printf("Valid options are:\n\t");
453 for (cpp
= telopts
; *cpp
; cpp
++) {
454 len
= strlen(*cpp
) + 3;
455 if (col
+ len
> 65) {
459 printf(" \"%s\"", *cpp
);
465 cpp
= (char **)genget(name
, telopts
, sizeof(char *));
466 if (Ambiguous(cpp
)) {
467 fprintf(stderr
,"'%s': ambiguous argument ('send %s ?' for help).\n",
474 register char *cp
= name
;
476 while (*cp
>= '0' && *cp
<= '9') {
482 fprintf(stderr
, "'%s': unknown argument ('send %s ?' for help).\n",
485 } else if (val
< 0 || val
> 255) {
486 fprintf(stderr
, "'%s': bad value ('send %s ?' for help).\n",
492 printf("?Need to be connected first.\n");
502 struct sendlist
*s
; /* pointer to current command */
503 for (s
= Sendlist
; s
->name
; s
++) {
505 printf("%-15s %s\n", s
->name
, s
->help
);
511 * The following are the routines and data structures referred
512 * to by the arguments to the "toggle" command.
527 (SetSockOpt(net
, SOL_SOCKET
, SO_DEBUG
, debug
)) < 0) {
528 perror("setsockopt (SO_DEBUG)");
532 if (net
> 0 && SetSockOpt(net
, SOL_SOCKET
, SO_DEBUG
, 0, 0) < 0)
533 perror("setsockopt (SO_DEBUG)");
535 printf("Cannot turn off socket debugging\n");
545 printf("Will send carriage returns as telnet <CR><LF>.\n");
547 printf("Will send carriage returns as telnet <CR><NUL>.\n");
558 donebinarytoggle
= 1;
563 if (my_want_state_is_will(TELOPT_BINARY
) &&
564 my_want_state_is_do(TELOPT_BINARY
)) {
566 } else if (my_want_state_is_wont(TELOPT_BINARY
) &&
567 my_want_state_is_dont(TELOPT_BINARY
)) {
570 val
= binmode
? 0 : 1;
574 if (my_want_state_is_will(TELOPT_BINARY
) &&
575 my_want_state_is_do(TELOPT_BINARY
)) {
576 printf("Already operating in binary mode with remote host.\n");
578 printf("Negotiating binary mode with remote host.\n");
582 if (my_want_state_is_wont(TELOPT_BINARY
) &&
583 my_want_state_is_dont(TELOPT_BINARY
)) {
584 printf("Already in network ascii mode with remote host.\n");
586 printf("Negotiating network ascii mode with remote host.\n");
597 donebinarytoggle
= 1;
600 val
= my_want_state_is_do(TELOPT_BINARY
) ? 0 : 1;
603 if (my_want_state_is_do(TELOPT_BINARY
)) {
604 printf("Already receiving in binary mode.\n");
606 printf("Negotiating binary mode on input.\n");
610 if (my_want_state_is_dont(TELOPT_BINARY
)) {
611 printf("Already receiving in network ascii mode.\n");
613 printf("Negotiating network ascii mode on input.\n");
624 donebinarytoggle
= 1;
627 val
= my_want_state_is_will(TELOPT_BINARY
) ? 0 : 1;
630 if (my_want_state_is_will(TELOPT_BINARY
)) {
631 printf("Already transmitting in binary mode.\n");
633 printf("Negotiating binary mode on output.\n");
637 if (my_want_state_is_wont(TELOPT_BINARY
)) {
638 printf("Already transmitting in network ascii mode.\n");
640 printf("Negotiating network ascii mode on output.\n");
648 static int togglehelp
P((void));
649 #if defined(AUTHENTICATION)
650 extern int auth_togdebug
P((int));
653 extern int EncryptAutoEnc
P((int));
654 extern int EncryptAutoDec
P((int));
655 extern int EncryptDebug
P((int));
656 extern int EncryptVerbose
P((int));
657 #endif /* ENCRYPTION */
660 char *name
; /* name of toggle */
661 char *help
; /* help message */
662 int (*handler
)(); /* routine to do actual setting */
664 char *actionexplanation
;
667 static struct togglelist Togglelist
[] = {
669 "flushing of output when sending interrupt characters",
672 "flush output when sending interrupt characters" },
674 "automatic sending of interrupt characters in urgent mode",
677 "send interrupt characters in urgent mode" },
678 #if defined(AUTHENTICATION)
680 "automatic sending of login and/or authentication info",
683 "send login name and/or authentication information" },
685 "Toggle authentication debugging",
688 "print authentication debugging information" },
692 "automatic encryption of data stream",
695 "automatically encrypt output" },
697 "automatic decryption of data stream",
700 "automatically decrypt input" },
702 "Toggle verbose encryption output",
705 "print verbose encryption output" },
707 "Toggle encryption debugging",
710 "print encryption debugging information" },
711 #endif /* ENCRYPTION */
713 "don't read ~/.telnetrc file",
716 "skip reading of ~/.telnetrc file" },
718 "sending and receiving of binary data",
723 "receiving of binary data",
728 "sending of binary data",
733 "sending carriage returns as telnet <CR><LF>",
738 "mapping of received carriage returns",
741 "map carriage return on output" },
743 "local recognition of certain control characters",
746 "recognize certain control characters" },
747 { " ", "", 0 }, /* empty line */
748 #if (defined(unix) || defined(__APPLE__)) && defined(TN3270)
750 "(debugging) toggle tracing of API transactions",
753 "trace API transactions" },
755 "(debugging) toggle printing of hexadecimal curses data",
758 "print hexadecimal representation of curses data" },
759 #endif /* (defined(unix) || defined(__APPLE__)) && defined(TN3270) */
764 "turn on socket level debugging" },
766 "printing of hexadecimal network data (debugging)",
769 "print hexadecimal representation of network traffic" },
771 "output of \"netdata\" to user readable format (debugging)",
774 "print user readable output for \"netdata\"" },
776 "viewing of options processing (debugging)",
779 "show option processing" },
780 #if defined(unix) || defined(__APPLE__)
782 "(debugging) toggle printing of hexadecimal terminal data",
785 "print hexadecimal representation of terminal traffic" },
786 #endif /* defined(unix) || defined(__APPLE__) */
799 struct togglelist
*c
;
801 for (c
= Togglelist
; c
->name
; c
++) {
804 printf("%-15s toggle %s\n", c
->name
, c
->help
);
810 printf("%-15s %s\n", "?", "display help information");
818 struct togglelist
*c
;
820 for (c
= Togglelist
; c
->name
; c
++) {
823 printf("%-15s %s %s\n", c
->name
, set
? "enable" : "disable",
831 #define GETTOGGLE(name) (struct togglelist *) \
832 genget(name, (char **) Togglelist, sizeof(struct togglelist))
841 struct togglelist
*c
;
845 "Need an argument to 'toggle' command. 'toggle ?' for help.\n");
854 fprintf(stderr
, "'%s': ambiguous argument ('toggle ?' for help).\n",
858 fprintf(stderr
, "'%s': unknown argument ('toggle ?' for help).\n",
863 *c
->variable
= !*c
->variable
; /* invert it */
864 if (c
->actionexplanation
) {
865 printf("%s %s.\n", *c
->variable
? "Will" : "Won't",
866 c
->actionexplanation
);
870 retval
&= (*c
->handler
)(-1);
878 * The following perform the "set" command.
882 struct termio new_tc
= { 0 };
886 char *name
; /* name */
887 char *help
; /* help information */
889 cc_t
*charp
; /* where it is located at */
892 static struct setlist Setlist
[] = {
893 #ifdef KLUDGELINEMODE
894 { "echo", "character to toggle local echoing on/off", 0, &echoc
},
896 { "escape", "character to escape back to telnet command mode", 0, &escape
},
897 { "rlogin", "rlogin escape character", 0, &rlogin
},
898 { "tracefile", "file to write trace information to", SetNetTrace
, (cc_t
*)NetTraceFile
},
900 { " ", "The following need 'localchars' to be toggled true", 0, 0 },
901 { "flushoutput", "character to cause an Abort Output", 0, termFlushCharp
},
902 { "interrupt", "character to cause an Interrupt Process", 0, termIntCharp
},
903 { "quit", "character to cause an Abort process", 0, termQuitCharp
},
904 { "eof", "character to cause an EOF ", 0, termEofCharp
},
906 { " ", "The following are for local editing in linemode", 0, 0 },
907 { "erase", "character to use to erase a character", 0, termEraseCharp
},
908 { "kill", "character to use to erase a line", 0, termKillCharp
},
909 { "lnext", "character to use for literal next", 0, termLiteralNextCharp
},
910 { "susp", "character to cause a Suspend Process", 0, termSuspCharp
},
911 { "reprint", "character to use for line reprint", 0, termRprntCharp
},
912 { "worderase", "character to use to erase a word", 0, termWerasCharp
},
913 { "start", "character to use for XON", 0, termStartCharp
},
914 { "stop", "character to use for XOFF", 0, termStopCharp
},
915 { "forw1", "alternate end of line character", 0, termForw1Charp
},
916 { "forw2", "alternate end of line character", 0, termForw2Charp
},
917 { "ayt", "alternate AYT character", 0, termAytCharp
},
921 #if defined(CRAY) && !defined(__STDC__)
922 /* Work around compiler bug in pcc 4.1.5 */
926 #ifndef KLUDGELINEMODE
931 Setlist
[N
+0].charp
= &termFlushChar
;
932 Setlist
[N
+1].charp
= &termIntChar
;
933 Setlist
[N
+2].charp
= &termQuitChar
;
934 Setlist
[N
+3].charp
= &termEofChar
;
935 Setlist
[N
+6].charp
= &termEraseChar
;
936 Setlist
[N
+7].charp
= &termKillChar
;
937 Setlist
[N
+8].charp
= &termLiteralNextChar
;
938 Setlist
[N
+9].charp
= &termSuspChar
;
939 Setlist
[N
+10].charp
= &termRprntChar
;
940 Setlist
[N
+11].charp
= &termWerasChar
;
941 Setlist
[N
+12].charp
= &termStartChar
;
942 Setlist
[N
+13].charp
= &termStopChar
;
943 Setlist
[N
+14].charp
= &termForw1Char
;
944 Setlist
[N
+15].charp
= &termForw2Char
;
945 Setlist
[N
+16].charp
= &termAytChar
;
948 #endif /* defined(CRAY) && !defined(__STDC__) */
950 static struct setlist
*
954 return (struct setlist
*)
955 genget(name
, (char **) Setlist
, sizeof(struct setlist
));
962 if (rlogin
!= _POSIX_VDISABLE
) {
963 rlogin
= (s
&& *s
) ? special(s
) : _POSIX_VDISABLE
;
964 printf("Telnet rlogin escape character is '%s'.\n",
967 escape
= (s
&& *s
) ? special(s
) : _POSIX_VDISABLE
;
968 printf("Telnet escape character is '%s'.\n", control(escape
));
979 struct togglelist
*c
;
981 if (argc
< 2 || argc
> 3) {
982 printf("Format is 'set Name Value'\n'set ?' for help.\n");
985 if ((argc
== 2) && (isprefix(argv
[1], "?") || isprefix(argv
[1], "help"))) {
986 for (ct
= Setlist
; ct
->name
; ct
++)
987 printf("%-15s %s\n", ct
->name
, ct
->help
);
990 printf("%-15s %s\n", "?", "display help information");
994 ct
= getset(argv
[1]);
996 c
= GETTOGGLE(argv
[1]);
998 fprintf(stderr
, "'%s': unknown argument ('set ?' for help).\n",
1001 } else if (Ambiguous(c
)) {
1002 fprintf(stderr
, "'%s': ambiguous argument ('set ?' for help).\n",
1007 if ((argc
== 2) || (strcmp("on", argv
[2]) == 0))
1009 else if (strcmp("off", argv
[2]) == 0)
1012 printf("Format is 'set togglename [on|off]'\n'set ?' for help.\n");
1015 if (c
->actionexplanation
) {
1016 printf("%s %s.\n", *c
->variable
? "Will" : "Won't",
1017 c
->actionexplanation
);
1022 } else if (argc
!= 3) {
1023 printf("Format is 'set Name Value'\n'set ?' for help.\n");
1025 } else if (Ambiguous(ct
)) {
1026 fprintf(stderr
, "'%s': ambiguous argument ('set ?' for help).\n",
1029 } else if (ct
->handler
) {
1030 (*ct
->handler
)(argv
[2]);
1031 printf("%s set to \"%s\".\n", ct
->name
, (char *)ct
->charp
);
1033 if (strcmp("off", argv
[2])) {
1034 value
= special(argv
[2]);
1036 value
= _POSIX_VDISABLE
;
1038 *(ct
->charp
) = (cc_t
)value
;
1039 printf("%s character is '%s'.\n", ct
->name
, control(*(ct
->charp
)));
1046 unsetcmd(argc
, argv
)
1051 struct togglelist
*c
;
1052 register char *name
;
1056 "Need an argument to 'unset' command. 'unset ?' for help.\n");
1059 if (isprefix(argv
[1], "?") || isprefix(argv
[1], "help")) {
1060 for (ct
= Setlist
; ct
->name
; ct
++)
1061 printf("%-15s %s\n", ct
->name
, ct
->help
);
1064 printf("%-15s %s\n", "?", "display help information");
1074 c
= GETTOGGLE(name
);
1076 fprintf(stderr
, "'%s': unknown argument ('unset ?' for help).\n",
1079 } else if (Ambiguous(c
)) {
1080 fprintf(stderr
, "'%s': ambiguous argument ('unset ?' for help).\n",
1086 if (c
->actionexplanation
) {
1087 printf("%s %s.\n", *c
->variable
? "Will" : "Won't",
1088 c
->actionexplanation
);
1093 } else if (Ambiguous(ct
)) {
1094 fprintf(stderr
, "'%s': ambiguous argument ('unset ?' for help).\n",
1097 } else if (ct
->handler
) {
1099 printf("%s reset to \"%s\".\n", ct
->name
, (char *)ct
->charp
);
1101 *(ct
->charp
) = _POSIX_VDISABLE
;
1102 printf("%s character is '%s'.\n", ct
->name
, control(*(ct
->charp
)));
1109 * The following are the data structures and routines for the
1112 #ifdef KLUDGELINEMODE
1113 extern int kludgelinemode
;
1119 send_wont(TELOPT_LINEMODE
, 1);
1120 send_dont(TELOPT_SGA
, 1);
1121 send_dont(TELOPT_ECHO
, 1);
1128 #ifdef KLUDGELINEMODE
1130 send_dont(TELOPT_SGA
, 1);
1132 send_will(TELOPT_LINEMODE
, 1);
1133 send_dont(TELOPT_ECHO
, 1);
1140 #ifdef KLUDGELINEMODE
1142 send_do(TELOPT_SGA
, 1);
1145 send_wont(TELOPT_LINEMODE
, 1);
1146 send_do(TELOPT_ECHO
, 1);
1155 extern int linemode
;
1157 if (my_want_state_is_wont(TELOPT_LINEMODE
)) {
1158 printf("?Need to have LINEMODE option enabled first.\n");
1159 printf("'mode ?' for help.\n");
1164 c
= (linemode
| bit
);
1166 c
= (linemode
& ~bit
);
1174 return dolmmode(bit
, 1);
1180 return dolmmode(bit
, 0);
1184 char *name
; /* command name */
1185 char *help
; /* help string */
1186 int (*handler
)(); /* routine which executes command */
1187 int needconnect
; /* Do we need to be connected to execute? */
1191 extern int modehelp();
1193 static struct modelist ModeList
[] = {
1194 { "character", "Disable LINEMODE option", docharmode
, 1 },
1195 #ifdef KLUDGELINEMODE
1196 { "", "(or disable obsolete line-by-line mode)", 0 },
1198 { "line", "Enable LINEMODE option", dolinemode
, 1 },
1199 #ifdef KLUDGELINEMODE
1200 { "", "(or enable obsolete line-by-line mode)", 0 },
1203 { "", "These require the LINEMODE option to be enabled", 0 },
1204 { "isig", "Enable signal trapping", setmode
, 1, MODE_TRAPSIG
},
1205 { "+isig", 0, setmode
, 1, MODE_TRAPSIG
},
1206 { "-isig", "Disable signal trapping", clearmode
, 1, MODE_TRAPSIG
},
1207 { "edit", "Enable character editing", setmode
, 1, MODE_EDIT
},
1208 { "+edit", 0, setmode
, 1, MODE_EDIT
},
1209 { "-edit", "Disable character editing", clearmode
, 1, MODE_EDIT
},
1210 { "softtabs", "Enable tab expansion", setmode
, 1, MODE_SOFT_TAB
},
1211 { "+softtabs", 0, setmode
, 1, MODE_SOFT_TAB
},
1212 { "-softtabs", "Disable character editing", clearmode
, 1, MODE_SOFT_TAB
},
1213 { "litecho", "Enable literal character echo", setmode
, 1, MODE_LIT_ECHO
},
1214 { "+litecho", 0, setmode
, 1, MODE_LIT_ECHO
},
1215 { "-litecho", "Disable literal character echo", clearmode
, 1, MODE_LIT_ECHO
},
1216 { "help", 0, modehelp
, 0 },
1217 #ifdef KLUDGELINEMODE
1218 { "kludgeline", 0, dokludgemode
, 1 },
1221 { "?", "Print help information", modehelp
, 0 },
1229 struct modelist
*mt
;
1231 printf("format is: 'mode Mode', where 'Mode' is one of:\n\n");
1232 for (mt
= ModeList
; mt
->name
; mt
++) {
1235 printf("%-15s %s\n", mt
->name
, mt
->help
);
1243 #define GETMODECMD(name) (struct modelist *) \
1244 genget(name, (char **) ModeList, sizeof(struct modelist))
1251 struct modelist
*mt
;
1254 printf("'mode' command requires an argument\n");
1255 printf("'mode ?' for help.\n");
1256 } else if ((mt
= GETMODECMD(argv
[1])) == 0) {
1257 fprintf(stderr
, "Unknown mode '%s' ('mode ?' for help).\n", argv
[1]);
1258 } else if (Ambiguous(mt
)) {
1259 fprintf(stderr
, "Ambiguous mode '%s' ('mode ?' for help).\n", argv
[1]);
1260 } else if (mt
->needconnect
&& !connected
) {
1261 printf("?Need to be connected first.\n");
1262 printf("'mode ?' for help.\n");
1263 } else if (mt
->handler
) {
1264 return (*mt
->handler
)(mt
->arg1
);
1270 * The following data structures and routines implement the
1271 * "display" command.
1279 struct togglelist
*tl
;
1282 #define dotog(tl) if (tl->variable && tl->actionexplanation) { \
1283 if (*tl->variable) { \
1288 printf(" %s.\n", tl->actionexplanation); \
1291 #define doset(sl) if (sl->name && *sl->name != ' ') { \
1292 if (sl->handler == 0) \
1293 printf("%-15s [%s]\n", sl->name, control(*sl->charp)); \
1295 printf("%-15s \"%s\"\n", sl->name, (char *)sl->charp); \
1299 for (tl
= Togglelist
; tl
->name
; tl
++) {
1303 for (sl
= Setlist
; sl
->name
; sl
++) {
1309 for (i
= 1; i
< argc
; i
++) {
1310 sl
= getset(argv
[i
]);
1311 tl
= GETTOGGLE(argv
[i
]);
1312 if (Ambiguous(sl
) || Ambiguous(tl
)) {
1313 printf("?Ambiguous argument '%s'.\n", argv
[i
]);
1315 } else if (!sl
&& !tl
) {
1316 printf("?Unknown argument '%s'.\n", argv
[i
]);
1328 /*@*/optionstatus();
1331 #endif /* ENCRYPTION */
1338 * The following are the data structures, and many of the routines,
1339 * relating to command processing.
1343 * Set the escape character.
1346 setescape(argc
, argv
)
1354 "Deprecated usage - please use 'set escape%s%s' in the future.\n",
1355 (argc
> 2)? " ":"", (argc
> 2)? argv
[1]: "");
1359 printf("new escape character: ");
1360 (void) fgets(buf
, sizeof(buf
), stdin
);
1366 printf("Escape character is '%s'.\n", control(escape
));
1368 (void) fflush(stdout
);
1377 printf("Deprecated usage - please use 'toggle crmod' in the future.\n");
1378 printf("%s map carriage return on output.\n", crmod
? "Will" : "Won't");
1379 (void) fflush(stdout
);
1390 long oldrows
, oldcols
, newrows
, newcols
, err
;
1392 err
= (TerminalWindowSize(&oldrows
, &oldcols
) == 0) ? 1 : 0;
1393 (void) kill(0, SIGTSTP
);
1395 * If we didn't get the window size before the SUSPEND, but we
1396 * can get them now (?), then send the NAWS to make sure that
1397 * we are set up for the right window size.
1399 if (TerminalWindowSize(&newrows
, &newcols
) && connected
&&
1400 (err
|| ((oldrows
!= newrows
) || (oldcols
!= newcols
)))) {
1404 /* reget parameters in case they were changed */
1405 TerminalSaveState();
1408 printf("Suspend is not supported. Try the '!' command instead\n");
1413 #if !defined(TN3270)
1420 long oldrows
, oldcols
, newrows
, newcols
, err
;
1424 err
= (TerminalWindowSize(&oldrows
, &oldcols
) == 0) ? 1 : 0;
1427 perror("Fork failed\n");
1433 * Fire up the shell in the child.
1435 register char *shellp
, *shellname
;
1436 extern char *strrchr();
1438 shellp
= getenv("SHELL");
1441 if ((shellname
= strrchr(shellp
, '/')) == 0)
1446 execl(shellp
, shellname
, "-c", &saveline
[1], 0);
1448 execl(shellp
, shellname
, 0);
1453 (void)wait((int *)0); /* Wait for the shell to complete */
1455 if (TerminalWindowSize(&newrows
, &newcols
) && connected
&&
1456 (err
|| ((oldrows
!= newrows
) || (oldcols
!= newcols
)))) {
1463 #else /* !defined(TN3270) */
1465 #endif /* !defined(TN3270) */
1470 int argc
; /* Number of arguments */
1471 char *argv
[]; /* arguments */
1473 extern int resettermname
;
1476 (void) shutdown(net
, 2);
1477 printf("Connection closed.\n");
1478 (void) NetClose(net
);
1481 #if defined(AUTHENTICATION) || defined(ENCRYPTION)
1482 auth_encrypt_connect(connected
);
1483 #endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */
1487 SetIn3270(); /* Get out of 3270 mode */
1488 #endif /* defined(TN3270) */
1490 if ((argc
!= 2) || (strcmp(argv
[1], "fromquit") != 0)) {
1491 longjmp(toplevel
, 1);
1494 return 1; /* Keep lint, etc., happy */
1500 (void) call(bye
, "bye", "fromquit", 0);
1509 send_do(TELOPT_LOGOUT
, 1);
1526 static void slc_help();
1528 struct slclist SlcList
[] = {
1529 { "export", "Use local special character definitions",
1530 slc_mode_export
, 0 },
1531 { "import", "Use remote special character definitions",
1532 slc_mode_import
, 1 },
1533 { "check", "Verify remote special character definitions",
1534 slc_mode_import
, 0 },
1535 { "help", 0, slc_help
, 0 },
1536 { "?", "Print help information", slc_help
, 0 },
1545 for (c
= SlcList
; c
->name
; c
++) {
1548 printf("%-15s %s\n", c
->name
, c
->help
);
1555 static struct slclist
*
1559 return (struct slclist
*)
1560 genget(name
, (char **) SlcList
, sizeof(struct slclist
));
1572 "Need an argument to 'slc' command. 'slc ?' for help.\n");
1575 c
= getslc(argv
[1]);
1577 fprintf(stderr
, "'%s': unknown argument ('slc ?' for help).\n",
1582 fprintf(stderr
, "'%s': ambiguous argument ('slc ?' for help).\n",
1586 (*c
->handler
)(c
->arg
);
1592 * The ENVIRON command.
1602 extern struct env_lst
*
1603 env_define
P((unsigned char *, unsigned char *));
1605 env_undefine
P((unsigned char *)),
1606 env_export
P((unsigned char *)),
1607 env_unexport
P((unsigned char *)),
1608 env_send
P((unsigned char *)),
1609 #if defined(OLD_ENVIRON) && defined(ENV_HACK)
1610 env_varval
P((unsigned char *)),
1616 struct envlist EnvList
[] = {
1617 { "define", "Define an environment variable",
1618 (void (*)())env_define
, 2 },
1619 { "undefine", "Undefine an environment variable",
1621 { "export", "Mark an environment variable for automatic export",
1623 { "unexport", "Don't mark an environment variable for automatic export",
1625 { "send", "Send an environment variable", env_send
, 1 },
1626 { "list", "List the current environment variables",
1628 #if defined(OLD_ENVIRON) && defined(ENV_HACK)
1629 { "varval", "Reverse VAR and VALUE (auto, right, wrong, status)",
1632 { "help", 0, env_help
, 0 },
1633 { "?", "Print help information", env_help
, 0 },
1642 for (c
= EnvList
; c
->name
; c
++) {
1645 printf("%-15s %s\n", c
->name
, c
->help
);
1652 static struct envlist
*
1656 return (struct envlist
*)
1657 genget(name
, (char **) EnvList
, sizeof(struct envlist
));
1668 "Need an argument to 'environ' command. 'environ ?' for help.\n");
1671 c
= getenvcmd(argv
[1]);
1673 fprintf(stderr
, "'%s': unknown argument ('environ ?' for help).\n",
1678 fprintf(stderr
, "'%s': ambiguous argument ('environ ?' for help).\n",
1682 if (c
->narg
+ 2 != argc
) {
1684 "Need %s%d argument%s to 'environ %s' command. 'environ ?' for help.\n",
1685 c
->narg
< argc
+ 2 ? "only " : "",
1686 c
->narg
, c
->narg
== 1 ? "" : "s", c
->name
);
1689 (*c
->handler
)(argv
[2], argv
[3]);
1694 struct env_lst
*next
; /* pointer to next structure */
1695 struct env_lst
*prev
; /* pointer to previous structure */
1696 unsigned char *var
; /* pointer to variable name */
1697 unsigned char *value
; /* pointer to variable value */
1698 int export
; /* 1 -> export with default list of variables */
1699 int welldefined
; /* A well defined variable */
1702 struct env_lst envlisthead
;
1708 register struct env_lst
*ep
;
1710 for (ep
= envlisthead
.next
; ep
; ep
= ep
->next
) {
1711 if (strcmp((char *)ep
->var
, (char *)var
) == 0)
1720 extern char **environ
;
1721 register char **epp
, *cp
;
1722 register struct env_lst
*ep
;
1723 extern char *strchr();
1725 for (epp
= environ
; *epp
; epp
++) {
1726 if (cp
= strchr(*epp
, '=')) {
1728 ep
= env_define((unsigned char *)*epp
,
1729 (unsigned char *)cp
+1);
1735 * Special case for DISPLAY variable. If it is ":0.0" or
1736 * "unix:0.0", we have to get rid of "unix" and insert our
1739 if ((ep
= env_find("DISPLAY"))
1740 && ((*ep
->value
== ':')
1741 || (strncmp((char *)ep
->value
, "unix:", 5) == 0))) {
1743 char *cp2
= strchr((char *)ep
->value
, ':');
1745 gethostname(hbuf
, 256);
1747 cp
= (char *)malloc(strlen(hbuf
) + strlen(cp2
) + 1);
1748 sprintf((char *)cp
, "%s%s", hbuf
, cp2
);
1750 ep
->value
= (unsigned char *)cp
;
1753 * If USER is not defined, but LOGNAME is, then add
1754 * USER with the value from LOGNAME. By default, we
1755 * don't export the USER variable.
1757 if ((env_find("USER") == NULL
) && (ep
= env_find("LOGNAME"))) {
1758 env_define((unsigned char *)"USER", ep
->value
);
1759 env_unexport((unsigned char *)"USER");
1761 env_export((unsigned char *)"DISPLAY");
1762 env_export((unsigned char *)"PRINTER");
1766 env_define(var
, value
)
1767 unsigned char *var
, *value
;
1769 register struct env_lst
*ep
;
1771 if (ep
= env_find(var
)) {
1777 ep
= (struct env_lst
*)malloc(sizeof(struct env_lst
));
1778 ep
->next
= envlisthead
.next
;
1779 envlisthead
.next
= ep
;
1780 ep
->prev
= &envlisthead
;
1782 ep
->next
->prev
= ep
;
1784 ep
->welldefined
= opt_welldefined(var
);
1786 ep
->var
= (unsigned char *)strdup((char *)var
);
1787 ep
->value
= (unsigned char *)strdup((char *)value
);
1795 register struct env_lst
*ep
;
1797 if (ep
= env_find(var
)) {
1798 ep
->prev
->next
= ep
->next
;
1800 ep
->next
->prev
= ep
->prev
;
1813 register struct env_lst
*ep
;
1815 if (ep
= env_find(var
))
1823 register struct env_lst
*ep
;
1825 if (ep
= env_find(var
))
1833 register struct env_lst
*ep
;
1835 if (my_state_is_wont(TELOPT_NEW_ENVIRON
)
1837 && my_state_is_wont(TELOPT_OLD_ENVIRON
)
1841 "Cannot send '%s': Telnet ENVIRON option not enabled\n",
1847 fprintf(stderr
, "Cannot send '%s': variable not defined\n",
1851 env_opt_start_info();
1852 env_opt_add(ep
->var
);
1859 register struct env_lst
*ep
;
1861 for (ep
= envlisthead
.next
; ep
; ep
= ep
->next
) {
1862 printf("%c %-20s %s\n", ep
->export
? '*' : ' ',
1863 ep
->var
, ep
->value
);
1868 env_default(init
, welldefined
)
1871 static struct env_lst
*nep
= NULL
;
1878 while (nep
= nep
->next
) {
1879 if (nep
->export
&& (nep
->welldefined
== welldefined
))
1890 register struct env_lst
*ep
;
1892 if (ep
= env_find(var
))
1897 #if defined(OLD_ENVIRON) && defined(ENV_HACK)
1900 unsigned char *what
;
1902 extern int old_env_var
, old_env_value
, env_auto
;
1903 int len
= strlen((char *)what
);
1908 if (strncasecmp((char *)what
, "status", len
) == 0) {
1910 printf("%s%s", "VAR and VALUE are/will be ",
1911 "determined automatically\n");
1912 if (old_env_var
== OLD_ENV_VAR
)
1913 printf("VAR and VALUE set to correct definitions\n");
1915 printf("VAR and VALUE definitions are reversed\n");
1916 } else if (strncasecmp((char *)what
, "auto", len
) == 0) {
1918 old_env_var
= OLD_ENV_VALUE
;
1919 old_env_value
= OLD_ENV_VAR
;
1920 } else if (strncasecmp((char *)what
, "right", len
) == 0) {
1922 old_env_var
= OLD_ENV_VAR
;
1923 old_env_value
= OLD_ENV_VALUE
;
1924 } else if (strncasecmp((char *)what
, "wrong", len
) == 0) {
1926 old_env_var
= OLD_ENV_VALUE
;
1927 old_env_value
= OLD_ENV_VAR
;
1930 printf("Unknown \"varval\" command. (\"auto\", \"right\", \"wrong\", \"status\")\n");
1935 #if defined(AUTHENTICATION)
1937 * The AUTHENTICATE command.
1948 auth_enable
P((char *)),
1949 auth_disable
P((char *)),
1950 auth_status
P((void));
1952 auth_help
P((void));
1954 struct authlist AuthList
[] = {
1955 { "status", "Display current status of authentication information",
1957 { "disable", "Disable an authentication type ('auth disable ?' for more)",
1959 { "enable", "Enable an authentication type ('auth enable ?' for more)",
1961 { "help", 0, auth_help
, 0 },
1962 { "?", "Print help information", auth_help
, 0 },
1971 for (c
= AuthList
; c
->name
; c
++) {
1974 printf("%-15s %s\n", c
->name
, c
->help
);
1982 auth_cmd(argc
, argv
)
1990 "Need an argument to 'auth' command. 'auth ?' for help.\n");
1994 c
= (struct authlist
*)
1995 genget(argv
[1], (char **) AuthList
, sizeof(struct authlist
));
1997 fprintf(stderr
, "'%s': unknown argument ('auth ?' for help).\n",
2002 fprintf(stderr
, "'%s': ambiguous argument ('auth ?' for help).\n",
2006 if (c
->narg
+ 2 != argc
) {
2008 "Need %s%d argument%s to 'auth %s' command. 'auth ?' for help.\n",
2009 c
->narg
< argc
+ 2 ? "only " : "",
2010 c
->narg
, c
->narg
== 1 ? "" : "s", c
->name
);
2013 return((*c
->handler
)(argv
[2], argv
[3]));
2019 * The ENCRYPT command.
2022 struct encryptlist
{
2032 EncryptEnable
P((char *, char *)),
2033 EncryptDisable
P((char *, char *)),
2034 EncryptType
P((char *, char *)),
2035 EncryptStart
P((char *)),
2036 EncryptStartInput
P((void)),
2037 EncryptStartOutput
P((void)),
2038 EncryptStop
P((char *)),
2039 EncryptStopInput
P((void)),
2040 EncryptStopOutput
P((void)),
2041 EncryptStatus
P((void));
2043 EncryptHelp
P((void));
2045 struct encryptlist EncryptList
[] = {
2046 { "enable", "Enable encryption. ('encrypt enable ?' for more)",
2047 EncryptEnable
, 1, 1, 2 },
2048 { "disable", "Disable encryption. ('encrypt enable ?' for more)",
2049 EncryptDisable
, 0, 1, 2 },
2050 { "type", "Set encryption type. ('encrypt type ?' for more)",
2051 EncryptType
, 0, 1, 1 },
2052 { "start", "Start encryption. ('encrypt start ?' for more)",
2053 EncryptStart
, 1, 0, 1 },
2054 { "stop", "Stop encryption. ('encrypt stop ?' for more)",
2055 EncryptStop
, 1, 0, 1 },
2056 { "input", "Start encrypting the input stream",
2057 EncryptStartInput
, 1, 0, 0 },
2058 { "-input", "Stop encrypting the input stream",
2059 EncryptStopInput
, 1, 0, 0 },
2060 { "output", "Start encrypting the output stream",
2061 EncryptStartOutput
, 1, 0, 0 },
2062 { "-output", "Stop encrypting the output stream",
2063 EncryptStopOutput
, 1, 0, 0 },
2065 { "status", "Display current status of authentication information",
2066 EncryptStatus
, 0, 0, 0 },
2067 { "help", 0, EncryptHelp
, 0, 0, 0 },
2068 { "?", "Print help information", EncryptHelp
, 0, 0, 0 },
2075 struct encryptlist
*c
;
2077 for (c
= EncryptList
; c
->name
; c
++) {
2080 printf("%-15s %s\n", c
->name
, c
->help
);
2088 encrypt_cmd(argc
, argv
)
2092 struct encryptlist
*c
;
2096 "Need an argument to 'encrypt' command. 'encrypt ?' for help.\n");
2100 c
= (struct encryptlist
*)
2101 genget(argv
[1], (char **) EncryptList
, sizeof(struct encryptlist
));
2103 fprintf(stderr
, "'%s': unknown argument ('encrypt ?' for help).\n",
2108 fprintf(stderr
, "'%s': ambiguous argument ('encrypt ?' for help).\n",
2113 if (argc
< c
->minarg
|| argc
> c
->maxarg
) {
2114 if (c
->minarg
== c
->maxarg
) {
2115 fprintf(stderr
, "Need %s%d argument%s ",
2116 c
->minarg
< argc
? "only " : "", c
->minarg
,
2117 c
->minarg
== 1 ? "" : "s");
2119 fprintf(stderr
, "Need %s%d-%d arguments ",
2120 c
->maxarg
< argc
? "only " : "", c
->minarg
, c
->maxarg
);
2122 fprintf(stderr
, "to 'encrypt %s' command. 'encrypt ?' for help.\n",
2126 if (c
->needconnect
&& !connected
) {
2127 if (!(argc
&& (isprefix(argv
[2], "help") || isprefix(argv
[2], "?")))) {
2128 printf("?Need to be connected first.\n");
2132 return ((*c
->handler
)(argc
> 0 ? argv
[2] : 0,
2133 argc
> 1 ? argv
[3] : 0,
2134 argc
> 2 ? argv
[4] : 0));
2136 #endif /* ENCRYPTION */
2138 #if (defined(unix) || defined(__APPLE__)) && defined(TN3270)
2147 res
= fcntl(fd
, F_GETOWN
, 0);
2154 printf("\tOwner is %d.\n", res
);
2158 res
= fcntl(fd
, F_GETFL
, 0);
2166 printf("\tFlags are 0x%x: %s\n", res
, decodeflags(res
));
2169 #endif /* (defined(unix) || defined(__APPLE__)) && defined(TN3270) */
2172 * Print status about the connection.
2181 printf("Connected to %s.\n", hostname
);
2182 if ((argc
< 2) || strcmp(argv
[1], "notmuch")) {
2183 int mode
= getconnmode();
2185 if (my_want_state_is_will(TELOPT_LINEMODE
)) {
2186 printf("Operating with LINEMODE option\n");
2187 printf("%s line editing\n", (mode
&MODE_EDIT
) ? "Local" : "No");
2188 printf("%s catching of signals\n",
2189 (mode
&MODE_TRAPSIG
) ? "Local" : "No");
2191 #ifdef KLUDGELINEMODE
2192 } else if (kludgelinemode
&& my_want_state_is_dont(TELOPT_SGA
)) {
2193 printf("Operating in obsolete linemode\n");
2196 printf("Operating in single character mode\n");
2198 printf("Catching signals locally\n");
2200 printf("%s character echo\n", (mode
&MODE_ECHO
) ? "Local" : "Remote");
2201 if (my_want_state_is_will(TELOPT_LFLOW
))
2202 printf("%s flow control\n", (mode
&MODE_FLOW
) ? "Local" : "No");
2205 #endif /* ENCRYPTION */
2208 printf("No connection.\n");
2210 # if !defined(TN3270)
2211 printf("Escape character is '%s'.\n", control(escape
));
2212 (void) fflush(stdout
);
2213 # else /* !defined(TN3270) */
2214 if ((!In3270
) && ((argc
< 2) || strcmp(argv
[1], "notmuch"))) {
2215 printf("Escape character is '%s'.\n", control(escape
));
2217 # if defined(unix) || defined(__APPLE__)
2218 if ((argc
>= 2) && !strcmp(argv
[1], "everything")) {
2219 printf("SIGIO received %d time%s.\n",
2220 sigiocount
, (sigiocount
== 1)? "":"s");
2222 printf("Process ID %d, process group %d.\n",
2223 getpid(), getpgrp(getpid()));
2224 printf("Terminal input:\n");
2226 printf("Terminal output:\n");
2228 printf("Network socket:\n");
2232 if (In3270
&& transcom
) {
2233 printf("Transparent mode command is '%s'.\n", transcom
);
2235 # endif /* defined(unix) || defined(__APPLE__) */
2236 (void) fflush(stdout
);
2240 # endif /* defined(TN3270) */
2246 * Function that gets called when SIGINFO is received.
2250 (void) call(status
, "status", "notmuch", 0);
2254 unsigned long inet_addr();
2261 register struct hostent
*host
= 0;
2262 struct sockaddr_in sin
;
2263 struct servent
*sp
= 0;
2265 extern char *inet_ntoa();
2266 #if defined(IP_OPTIONS) && defined(IPPROTO_IP)
2267 char *srp
= 0, *strrchr();
2268 unsigned long sourceroute(), srlen
;
2270 char *cmd
, *hostp
= 0, *portp
= 0, *user
= 0;
2272 /* clear the socket address prior to use */
2273 memset((char *)&sin
, 0, sizeof(sin
));
2276 printf("?Already connected to %s\n", hostname
);
2281 (void) strcpy(line
, "open ");
2283 (void) fgets(&line
[strlen(line
)], sizeof(line
) - strlen(line
), stdin
);
2291 if (strcmp(*argv
, "help") == 0 || isprefix(*argv
, "?"))
2293 if (strcmp(*argv
, "-l") == 0) {
2301 if (strcmp(*argv
, "-a") == 0) {
2317 printf("usage: %s [-l user] [-a] host-name [port]\n", cmd
);
2324 #if defined(IP_OPTIONS) && defined(IPPROTO_IP)
2325 if (hostp
[0] == '@' || hostp
[0] == '!') {
2326 if ((hostname
= strrchr(hostp
, ':')) == NULL
)
2327 hostname
= strrchr(hostp
, '@');
2330 temp
= sourceroute(hostp
, &srp
, &srlen
);
2335 } else if (temp
== -1) {
2336 printf("Bad source route option: %s\n", hostp
);
2340 sin
.sin_addr
.s_addr
= temp
;
2341 sin
.sin_family
= AF_INET
;
2345 temp
= inet_addr(hostp
);
2346 if (temp
!= (unsigned long) -1) {
2347 sin
.sin_addr
.s_addr
= temp
;
2348 sin
.sin_family
= AF_INET
;
2349 (void) strcpy(_hostname
, hostp
);
2350 hostname
= _hostname
;
2352 host
= gethostbyname(hostp
);
2354 sin
.sin_family
= host
->h_addrtype
;
2355 #if defined(h_addr) /* In 4.3, this is a #define */
2356 memmove((caddr_t
)&sin
.sin_addr
,
2357 host
->h_addr_list
[0], host
->h_length
);
2358 #else /* defined(h_addr) */
2359 memmove((caddr_t
)&sin
.sin_addr
, host
->h_addr
, host
->h_length
);
2360 #endif /* defined(h_addr) */
2361 strncpy(_hostname
, host
->h_name
, sizeof(_hostname
));
2362 _hostname
[sizeof(_hostname
)-1] = '\0';
2363 hostname
= _hostname
;
2370 #if defined(IP_OPTIONS) && defined(IPPROTO_IP)
2374 if (*portp
== '-') {
2379 sin
.sin_port
= atoi(portp
);
2380 if (sin
.sin_port
== 0) {
2381 sp
= getservbyname(portp
, "tcp");
2383 sin
.sin_port
= sp
->s_port
;
2385 printf("%s: bad port number\n", portp
);
2391 u_short htons
P((unsigned short));
2392 #endif /* !defined(htons) */
2393 sin
.sin_port
= htons(sin
.sin_port
);
2397 sp
= getservbyname("telnet", "tcp");
2399 fprintf(stderr
, "telnet: tcp/telnet: unknown service\n");
2403 sin
.sin_port
= sp
->s_port
;
2407 printf("Trying %s...\n", inet_ntoa(sin
.sin_addr
));
2409 net
= socket(AF_INET
, SOCK_STREAM
, 0);
2412 perror("telnet: socket");
2415 #if defined(IP_OPTIONS) && defined(IPPROTO_IP)
2416 if (srp
&& setsockopt(net
, IPPROTO_IP
, IP_OPTIONS
, (char *)srp
, srlen
) < 0)
2417 perror("setsockopt (IP_OPTIONS)");
2419 #if defined(IPPROTO_IP) && defined(IP_TOS)
2421 # if defined(HAS_GETTOS)
2423 if (tos
< 0 && (tp
= gettosbyname("telnet", "tcp")))
2427 tos
= 020; /* Low Delay bit */
2429 && (setsockopt(net
, IPPROTO_IP
, IP_TOS
,
2430 (char *)&tos
, sizeof(int)) < 0)
2431 && (errno
!= ENOPROTOOPT
))
2432 perror("telnet: setsockopt (IP_TOS) (ignored)");
2434 #endif /* defined(IPPROTO_IP) && defined(IP_TOS) */
2436 if (debug
&& SetSockOpt(net
, SOL_SOCKET
, SO_DEBUG
, 1) < 0) {
2437 perror("setsockopt (SO_DEBUG)");
2440 if (connect(net
, (struct sockaddr
*)&sin
, sizeof (sin
)) < 0) {
2441 #if defined(h_addr) /* In 4.3, this is a #define */
2442 if (host
&& host
->h_addr_list
[1]) {
2445 fprintf(stderr
, "telnet: connect to address %s: ",
2446 inet_ntoa(sin
.sin_addr
));
2449 host
->h_addr_list
++;
2450 memmove((caddr_t
)&sin
.sin_addr
,
2451 host
->h_addr_list
[0], host
->h_length
);
2452 (void) NetClose(net
);
2455 #endif /* defined(h_addr) */
2456 perror("telnet: Unable to connect to remote host");
2460 #if defined(AUTHENTICATION) || defined(ENCRYPTION)
2461 auth_encrypt_connect(connected
);
2462 #endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */
2463 } while (connected
== 0);
2464 cmdrc(hostp
, hostname
);
2465 if (autologin
&& user
== NULL
) {
2468 user
= getenv("USER");
2470 (pw
= getpwnam(user
)) && pw
->pw_uid
!= getuid()) {
2471 if (pw
= getpwuid(getuid()))
2478 env_define((unsigned char *)"USER", (unsigned char *)user
);
2479 env_export((unsigned char *)"USER");
2481 (void) call(status
, "status", "notmuch", 0);
2482 if (setjmp(peerdied
) == 0)
2484 (void) NetClose(net
);
2485 ExitString("Connection closed by foreign host.\n",1);
2489 #define HELPINDENT (sizeof ("connect"))
2492 openhelp
[] = "connect to a site",
2493 closehelp
[] = "close current connection",
2494 logouthelp
[] = "forcibly logout remote user and close the connection",
2495 quithelp
[] = "exit telnet",
2496 statushelp
[] = "print status information",
2497 helphelp
[] = "print help information",
2498 sendhelp
[] = "transmit special characters ('send ?' for more)",
2499 sethelp
[] = "set operating parameters ('set ?' for more)",
2500 unsethelp
[] = "unset operating parameters ('unset ?' for more)",
2501 togglestring
[] ="toggle operating parameters ('toggle ?' for more)",
2502 slchelp
[] = "change state of special charaters ('slc ?' for more)",
2503 displayhelp
[] = "display operating parameters",
2504 #if defined(TN3270) && (defined(unix) || defined(__APPLE__))
2505 transcomhelp
[] = "specify Unix command for transparent mode pipe",
2506 #endif /* defined(TN3270) && (defined(unix) || defined(__APPLE__)) */
2507 #if defined(AUTHENTICATION)
2508 authhelp
[] = "turn on (off) authentication ('auth ?' for more)",
2511 encrypthelp
[] = "turn on (off) encryption ('encrypt ?' for more)",
2512 #endif /* ENCRYPTION */
2513 #if defined(unix) || defined(__APPLE__)
2514 zhelp
[] = "suspend telnet",
2515 #endif /* defined(unix) || defined(__APPLE__) */
2516 shellhelp
[] = "invoke a subshell",
2517 envhelp
[] = "change environment variables ('environ ?' for more)",
2518 modestring
[] = "try to enter line or character mode ('mode ?' for more)";
2522 static Command cmdtab
[] = {
2523 { "close", closehelp
, bye
, 1 },
2524 { "logout", logouthelp
, logout
, 1 },
2525 { "display", displayhelp
, display
, 0 },
2526 { "mode", modestring
, modecmd
, 0 },
2527 { "open", openhelp
, tn
, 0 },
2528 { "quit", quithelp
, quit
, 0 },
2529 { "send", sendhelp
, sendcmd
, 0 },
2530 { "set", sethelp
, setcmd
, 0 },
2531 { "unset", unsethelp
, unsetcmd
, 0 },
2532 { "status", statushelp
, status
, 0 },
2533 { "toggle", togglestring
, toggle
, 0 },
2534 { "slc", slchelp
, slccmd
, 0 },
2535 #if defined(TN3270) && (defined(unix) || defined(__APPLE__))
2536 { "transcom", transcomhelp
, settranscom
, 0 },
2537 #endif /* defined(TN3270) && (defined(unix) || defined(__APPLE__)) */
2538 #if defined(AUTHENTICATION)
2539 { "auth", authhelp
, auth_cmd
, 0 },
2542 { "encrypt", encrypthelp
, encrypt_cmd
, 0 },
2543 #endif /* ENCRYPTION */
2544 #if defined(unix) || defined(__APPLE__)
2545 { "z", zhelp
, suspend
, 0 },
2546 #endif /* defined(unix) || defined(__APPLE__) */
2548 { "!", shellhelp
, shell
, 1 },
2550 { "!", shellhelp
, shell
, 0 },
2552 { "environ", envhelp
, env_cmd
, 0 },
2553 { "?", helphelp
, help
, 0 },
2557 static char crmodhelp
[] = "deprecated command -- use 'toggle crmod' instead";
2558 static char escapehelp
[] = "deprecated command -- use 'set escape' instead";
2560 static Command cmdtab2
[] = {
2561 { "help", 0, help
, 0 },
2562 { "escape", escapehelp
, setescape
, 0 },
2563 { "crmod", crmodhelp
, togcrmod
, 0 },
2569 * Call routine with argc, argv set from args (terminated by 0).
2575 #include <varargs.h>
2582 call(intrtn_t routine
, ...)
2595 va_start(ap
, routine
);
2598 routine
= (va_arg(ap
, intrtn_t
));
2600 while ((args
[argno
++] = va_arg(ap
, char *)) != 0) {
2604 return (*routine
)(argno
-1, args
);
2614 if (cm
= (Command
*) genget(name
, (char **) cmdtab
, sizeof(Command
)))
2616 return (Command
*) genget(name
, (char **) cmdtab2
, sizeof(Command
));
2620 command(top
, tbuf
, cnt
)
2625 register Command
*c
;
2630 #if defined(unix) || defined(__APPLE__)
2632 (void) signal(SIGINT
, SIG_DFL
);
2633 (void) signal(SIGQUIT
, SIG_DFL
);
2634 #endif /* defined(unix) || defined(__APPLE__) */
2637 if (rlogin
== _POSIX_VDISABLE
)
2638 printf("%s> ", prompt
);
2642 while (cnt
> 0 && (*cp
++ = *tbuf
++) != '\n')
2645 if (cp
== line
|| *--cp
!= '\n' || cp
== line
)
2648 if (rlogin
== _POSIX_VDISABLE
)
2649 printf("%s\n", line
);
2652 if (rlogin
!= _POSIX_VDISABLE
)
2653 printf("%s> ", prompt
);
2654 if (fgets(line
, sizeof(line
), stdin
) == NULL
) {
2655 if (feof(stdin
) || ferror(stdin
)) {
2665 if (margv
[0] == 0) {
2668 c
= getcmd(margv
[0]);
2670 printf("?Ambiguous command\n");
2674 printf("?Invalid command\n");
2677 if (c
->needconnect
&& !connected
) {
2678 printf("?Need to be connected first.\n");
2681 if ((*c
->handler
)(margc
, margv
)) {
2687 longjmp(toplevel
, 1);
2691 if (shell_active
== 0) {
2694 #else /* defined(TN3270) */
2696 #endif /* defined(TN3270) */
2708 register Command
*c
;
2711 printf("Commands may be abbreviated. Commands are:\n\n");
2712 for (c
= cmdtab
; c
->name
; c
++)
2714 printf("%-*s\t%s\n", HELPINDENT
, c
->name
,
2719 while (--argc
> 0) {
2724 printf("?Ambiguous help command %s\n", arg
);
2725 else if (c
== (Command
*)0)
2726 printf("?Invalid help command %s\n", arg
);
2728 printf("%s\n", c
->help
);
2733 static char *rcname
= 0;
2734 static char rcbuf
[128];
2739 register Command
*c
;
2742 int l1
= strlen(m1
);
2743 int l2
= strlen(m2
);
2753 rcname
= getenv("HOME");
2755 strcpy(rcbuf
, rcname
);
2758 strcat(rcbuf
, "/.telnetrc");
2762 if ((rcfile
= fopen(rcname
, "r")) == 0) {
2767 if (fgets(line
, sizeof(line
), rcfile
) == NULL
)
2774 if (!isspace(line
[0]))
2777 if (gotmachine
== 0) {
2778 if (isspace(line
[0]))
2780 if (strncasecmp(line
, m1
, l1
) == 0)
2781 strncpy(line
, &line
[l1
], sizeof(line
) - l1
);
2782 else if (strncasecmp(line
, m2
, l2
) == 0)
2783 strncpy(line
, &line
[l2
], sizeof(line
) - l2
);
2784 else if (strncasecmp(line
, "DEFAULT", 7) == 0)
2785 strncpy(line
, &line
[7], sizeof(line
) - 7);
2788 if (line
[0] != ' ' && line
[0] != '\t' && line
[0] != '\n')
2795 c
= getcmd(margv
[0]);
2797 printf("?Ambiguous command: %s\n", margv
[0]);
2801 printf("?Invalid command: %s\n", margv
[0]);
2805 * This should never happen...
2807 if (c
->needconnect
&& !connected
) {
2808 printf("?Need to be connected first for %s.\n", margv
[0]);
2811 (*c
->handler
)(margc
, margv
);
2816 #if defined(IP_OPTIONS) && defined(IPPROTO_IP)
2819 * Source route is handed in as
2820 * [!]@hop1@hop2...[@|:]dst
2821 * If the leading ! is present, it is a
2822 * strict source route, otherwise it is
2823 * assmed to be a loose source route.
2825 * We fill in the source route option as
2826 * hop1,hop2,hop3...dest
2827 * and return a pointer to hop1, which will
2828 * be the address to connect() to.
2831 * arg: pointer to route list to decipher
2833 * cpp: If *cpp is not equal to NULL, this is a
2834 * pointer to a pointer to a character array
2835 * that should be filled in with the option.
2837 * lenp: pointer to an integer that contains the
2838 * length of *cpp if *cpp != NULL.
2842 * Returns the address of the host to connect to. If the
2843 * return value is -1, there was a syntax error in the
2844 * option, either unknown characters, or too many hosts.
2845 * If the return value is 0, one of the hostnames in the
2846 * path is unknown, and *cpp is set to point to the bad
2849 * *cpp: If *cpp was equal to NULL, it will be filled
2850 * in with a pointer to our static area that has
2851 * the option filled in. This will be 32bit aligned.
2853 * *lenp: This will be filled in with how long the option
2854 * pointed to by *cpp is.
2858 sourceroute(arg
, cpp
, lenp
)
2863 static char lsr
[44];
2867 char *cp
, *cp2
, *lsrp
, *lsrep
;
2869 struct in_addr sin_addr
;
2870 register struct hostent
*host
= 0;
2874 * Verify the arguments, and make sure we have
2875 * at least 7 bytes for the option.
2877 if (cpp
== NULL
|| lenp
== NULL
)
2878 return((unsigned long)-1);
2879 if (*cpp
!= NULL
&& *lenp
< 7)
2880 return((unsigned long)-1);
2882 * Decide whether we have a buffer passed to us,
2883 * or if we need to use our own static buffer.
2887 lsrep
= lsrp
+ *lenp
;
2896 * Next, decide whether we have a loose source
2897 * route or a strict source route, and fill in
2898 * the begining of the option.
2903 *lsrp
++ = IPOPT_SSRR
;
2905 *lsrp
++ = IPOPT_LSRR
;
2909 ipopt
.io_type
= IPOPT_SSRR
;
2911 ipopt
.io_type
= IPOPT_LSRR
;
2915 return((unsigned long)-1);
2918 lsrp
++; /* skip over length, we'll fill it in later */
2924 sin_addr
.s_addr
= 0;
2929 else for (cp2
= cp
; c
= *cp2
; cp2
++) {
2934 } else if (c
== '@') {
2936 } else if (c
== ':') {
2945 if ((tmp
= inet_addr(cp
)) != -1) {
2946 sin_addr
.s_addr
= tmp
;
2947 } else if (host
= gethostbyname(cp
)) {
2949 memmove((caddr_t
)&sin_addr
,
2950 host
->h_addr_list
[0], host
->h_length
);
2952 memmove((caddr_t
)&sin_addr
, host
->h_addr
, host
->h_length
);
2958 memmove(lsrp
, (char *)&sin_addr
, 4);
2965 * Check to make sure there is space for next address
2967 if (lsrp
+ 4 > lsrep
)
2968 return((unsigned long)-1);
2971 if ((*(*cpp
+IPOPT_OLEN
) = lsrp
- *cpp
) <= 7) {
2974 return((unsigned long)-1);
2976 *lsrp
++ = IPOPT_NOP
; /* 32 bit word align it */
2977 *lenp
= lsrp
- *cpp
;
2979 ipopt
.io_len
= lsrp
- *cpp
;
2980 if (ipopt
.io_len
<= 5) { /* Is 3 better ? */
2983 return((unsigned long)-1);
2985 *lenp
= sizeof(ipopt
);
2986 *cpp
= (char *) &ipopt
;
2988 return(sin_addr
.s_addr
);