1  | 
     | 
     | 
    /*	$OpenBSD: commands.c,v 1.85 2017/07/19 12:25:52 deraadt Exp $	*/  | 
    
    
    2  | 
     | 
     | 
    /*	$NetBSD: commands.c,v 1.14 1996/03/24 22:03:48 jtk Exp $	*/  | 
    
    
    3  | 
     | 
     | 
     | 
    
    
    4  | 
     | 
     | 
    /*  | 
    
    
    5  | 
     | 
     | 
     * Copyright (c) 1988, 1990, 1993  | 
    
    
    6  | 
     | 
     | 
     *	The Regents of the University of California.  All rights reserved.  | 
    
    
    7  | 
     | 
     | 
     *  | 
    
    
    8  | 
     | 
     | 
     * Redistribution and use in source and binary forms, with or without  | 
    
    
    9  | 
     | 
     | 
     * modification, are permitted provided that the following conditions  | 
    
    
    10  | 
     | 
     | 
     * are met:  | 
    
    
    11  | 
     | 
     | 
     * 1. Redistributions of source code must retain the above copyright  | 
    
    
    12  | 
     | 
     | 
     *    notice, this list of conditions and the following disclaimer.  | 
    
    
    13  | 
     | 
     | 
     * 2. Redistributions in binary form must reproduce the above copyright  | 
    
    
    14  | 
     | 
     | 
     *    notice, this list of conditions and the following disclaimer in the  | 
    
    
    15  | 
     | 
     | 
     *    documentation and/or other materials provided with the distribution.  | 
    
    
    16  | 
     | 
     | 
     * 3. Neither the name of the University nor the names of its contributors  | 
    
    
    17  | 
     | 
     | 
     *    may be used to endorse or promote products derived from this software  | 
    
    
    18  | 
     | 
     | 
     *    without specific prior written permission.  | 
    
    
    19  | 
     | 
     | 
     *  | 
    
    
    20  | 
     | 
     | 
     * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND  | 
    
    
    21  | 
     | 
     | 
     * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE  | 
    
    
    22  | 
     | 
     | 
     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  | 
    
    
    23  | 
     | 
     | 
     * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE  | 
    
    
    24  | 
     | 
     | 
     * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL  | 
    
    
    25  | 
     | 
     | 
     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS  | 
    
    
    26  | 
     | 
     | 
     * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)  | 
    
    
    27  | 
     | 
     | 
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  | 
    
    
    28  | 
     | 
     | 
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY  | 
    
    
    29  | 
     | 
     | 
     * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  | 
    
    
    30  | 
     | 
     | 
     * SUCH DAMAGE.  | 
    
    
    31  | 
     | 
     | 
     */  | 
    
    
    32  | 
     | 
     | 
     | 
    
    
    33  | 
     | 
     | 
    #include "telnet_locl.h"  | 
    
    
    34  | 
     | 
     | 
     | 
    
    
    35  | 
     | 
     | 
    #include <sys/socket.h>  | 
    
    
    36  | 
     | 
     | 
    #include <netinet/in.h>  | 
    
    
    37  | 
     | 
     | 
    #include <netinet/ip.h>  | 
    
    
    38  | 
     | 
     | 
    #include <arpa/inet.h>  | 
    
    
    39  | 
     | 
     | 
    #include <arpa/telnet.h>  | 
    
    
    40  | 
     | 
     | 
     | 
    
    
    41  | 
     | 
     | 
    #include <ctype.h>  | 
    
    
    42  | 
     | 
     | 
    #include <err.h>  | 
    
    
    43  | 
     | 
     | 
    #include <errno.h>  | 
    
    
    44  | 
     | 
     | 
    #include <netdb.h>  | 
    
    
    45  | 
     | 
     | 
    #include <pwd.h>  | 
    
    
    46  | 
     | 
     | 
    #include <stdarg.h>  | 
    
    
    47  | 
     | 
     | 
    #include <stdlib.h>  | 
    
    
    48  | 
     | 
     | 
    #include <string.h>  | 
    
    
    49  | 
     | 
     | 
    #include <unistd.h>  | 
    
    
    50  | 
     | 
     | 
    #include <limits.h>  | 
    
    
    51  | 
     | 
     | 
     | 
    
    
    52  | 
     | 
     | 
    char	*hostname;  | 
    
    
    53  | 
     | 
     | 
     | 
    
    
    54  | 
     | 
     | 
    typedef struct { | 
    
    
    55  | 
     | 
     | 
    	char	*name;		/* command name */  | 
    
    
    56  | 
     | 
     | 
    	char	*help;		/* help string (NULL for no help) */  | 
    
    
    57  | 
     | 
     | 
    	int	(*handler)(int, char **);/* routine which executes command */  | 
    
    
    58  | 
     | 
     | 
    	int	needconnect;	/* Do we need to be connected to execute? */  | 
    
    
    59  | 
     | 
     | 
    } Command;  | 
    
    
    60  | 
     | 
     | 
     | 
    
    
    61  | 
     | 
     | 
    static char line[256];  | 
    
    
    62  | 
     | 
     | 
    static int margc;  | 
    
    
    63  | 
     | 
     | 
    static char *margv[20];  | 
    
    
    64  | 
     | 
     | 
     | 
    
    
    65  | 
     | 
     | 
    static void  | 
    
    
    66  | 
     | 
     | 
    makeargv(void)  | 
    
    
    67  | 
     | 
     | 
    { | 
    
    
    68  | 
     | 
     | 
        char *cp, *cp2, c;  | 
    
    
    69  | 
     | 
     | 
        char **argp = margv;  | 
    
    
    70  | 
     | 
     | 
     | 
    
    
    71  | 
     | 
     | 
        margc = 0;  | 
    
    
    72  | 
     | 
     | 
        cp = line;  | 
    
    
    73  | 
     | 
     | 
        while ((c = *cp)) { | 
    
    
    74  | 
     | 
     | 
    	int inquote = 0;  | 
    
    
    75  | 
     | 
     | 
    	while (isspace((unsigned char)c))  | 
    
    
    76  | 
     | 
     | 
    	    c = *++cp;  | 
    
    
    77  | 
     | 
     | 
    	if (c == '\0')  | 
    
    
    78  | 
     | 
     | 
    	    break;  | 
    
    
    79  | 
     | 
     | 
    	*argp++ = cp;  | 
    
    
    80  | 
     | 
     | 
    	margc += 1;  | 
    
    
    81  | 
     | 
     | 
    	for (cp2 = cp; c != '\0'; c = *++cp) { | 
    
    
    82  | 
     | 
     | 
    	    if (inquote) { | 
    
    
    83  | 
     | 
     | 
    		if (c == inquote) { | 
    
    
    84  | 
     | 
     | 
    		    inquote = 0;  | 
    
    
    85  | 
     | 
     | 
    		    continue;  | 
    
    
    86  | 
     | 
     | 
    		}  | 
    
    
    87  | 
     | 
     | 
    	    } else { | 
    
    
    88  | 
     | 
     | 
    		if (c == '\\') { | 
    
    
    89  | 
     | 
     | 
    		    if ((c = *++cp) == '\0')  | 
    
    
    90  | 
     | 
     | 
    			break;  | 
    
    
    91  | 
     | 
     | 
    		} else if (c == '"') { | 
    
    
    92  | 
     | 
     | 
    		    inquote = '"';  | 
    
    
    93  | 
     | 
     | 
    		    continue;  | 
    
    
    94  | 
     | 
     | 
    		} else if (c == '\'') { | 
    
    
    95  | 
     | 
     | 
    		    inquote = '\'';  | 
    
    
    96  | 
     | 
     | 
    		    continue;  | 
    
    
    97  | 
     | 
     | 
    		} else if (isspace((unsigned char)c))  | 
    
    
    98  | 
     | 
     | 
    		    break;  | 
    
    
    99  | 
     | 
     | 
    	    }  | 
    
    
    100  | 
     | 
     | 
    	    *cp2++ = c;  | 
    
    
    101  | 
     | 
     | 
    	}  | 
    
    
    102  | 
     | 
     | 
    	*cp2 = '\0';  | 
    
    
    103  | 
     | 
     | 
    	if (c == '\0')  | 
    
    
    104  | 
     | 
     | 
    	    break;  | 
    
    
    105  | 
     | 
     | 
    	cp++;  | 
    
    
    106  | 
     | 
     | 
        }  | 
    
    
    107  | 
     | 
     | 
        *argp++ = 0;  | 
    
    
    108  | 
     | 
     | 
    }  | 
    
    
    109  | 
     | 
     | 
     | 
    
    
    110  | 
     | 
     | 
    /*  | 
    
    
    111  | 
     | 
     | 
     * Make a character string into a number.  | 
    
    
    112  | 
     | 
     | 
     *  | 
    
    
    113  | 
     | 
     | 
     * Todo:  1.  Could take random integers (12, 0x12, 012, 0b1).  | 
    
    
    114  | 
     | 
     | 
     */  | 
    
    
    115  | 
     | 
     | 
     | 
    
    
    116  | 
     | 
     | 
    static char  | 
    
    
    117  | 
     | 
     | 
    special(char *s)  | 
    
    
    118  | 
     | 
     | 
    { | 
    
    
    119  | 
     | 
     | 
    	char c;  | 
    
    
    120  | 
     | 
     | 
    	char b;  | 
    
    
    121  | 
     | 
     | 
     | 
    
    
    122  | 
     | 
     | 
    	switch (*s) { | 
    
    
    123  | 
     | 
     | 
    	case '^':  | 
    
    
    124  | 
     | 
     | 
    		b = *++s;  | 
    
    
    125  | 
     | 
     | 
    		if (b == '?') { | 
    
    
    126  | 
     | 
     | 
    		    c = b | 0x40;		/* DEL */  | 
    
    
    127  | 
     | 
     | 
    		} else { | 
    
    
    128  | 
     | 
     | 
    		    c = b & 0x1f;  | 
    
    
    129  | 
     | 
     | 
    		}  | 
    
    
    130  | 
     | 
     | 
    		break;  | 
    
    
    131  | 
     | 
     | 
    	default:  | 
    
    
    132  | 
     | 
     | 
    		c = *s;  | 
    
    
    133  | 
     | 
     | 
    		break;  | 
    
    
    134  | 
     | 
     | 
    	}  | 
    
    
    135  | 
     | 
     | 
    	return c;  | 
    
    
    136  | 
     | 
     | 
    }  | 
    
    
    137  | 
     | 
     | 
     | 
    
    
    138  | 
     | 
     | 
    /*  | 
    
    
    139  | 
     | 
     | 
     * Construct a control character sequence  | 
    
    
    140  | 
     | 
     | 
     * for a special character.  | 
    
    
    141  | 
     | 
     | 
     */  | 
    
    
    142  | 
     | 
     | 
    static char *  | 
    
    
    143  | 
     | 
     | 
    control(cc_t c)  | 
    
    
    144  | 
     | 
     | 
    { | 
    
    
    145  | 
     | 
     | 
    	static char buf[5];  | 
    
    
    146  | 
     | 
     | 
    	/*  | 
    
    
    147  | 
     | 
     | 
    	 * The only way I could get the Sun 3.5 compiler  | 
    
    
    148  | 
     | 
     | 
    	 * to shut up about  | 
    
    
    149  | 
     | 
     | 
    	 *	if ((unsigned int)c >= 0x80)  | 
    
    
    150  | 
     | 
     | 
    	 * was to assign "c" to an unsigned int variable...  | 
    
    
    151  | 
     | 
     | 
    	 * Arggg....  | 
    
    
    152  | 
     | 
     | 
    	 */  | 
    
    
    153  | 
     | 
     | 
    	unsigned int uic = (unsigned int)c;  | 
    
    
    154  | 
     | 
     | 
     | 
    
    
    155  | 
     | 
     | 
    	if (uic == 0x7f)  | 
    
    
    156  | 
     | 
     | 
    		return ("^?"); | 
    
    
    157  | 
     | 
     | 
    	if (c == (cc_t)_POSIX_VDISABLE) { | 
    
    
    158  | 
     | 
     | 
    		return "off";  | 
    
    
    159  | 
     | 
     | 
    	}  | 
    
    
    160  | 
     | 
     | 
    	if (uic >= 0x80) { | 
    
    
    161  | 
     | 
     | 
    		buf[0] = '\\';  | 
    
    
    162  | 
     | 
     | 
    		buf[1] = ((c>>6)&07) + '0';  | 
    
    
    163  | 
     | 
     | 
    		buf[2] = ((c>>3)&07) + '0';  | 
    
    
    164  | 
     | 
     | 
    		buf[3] = (c&07) + '0';  | 
    
    
    165  | 
     | 
     | 
    		buf[4] = 0;  | 
    
    
    166  | 
     | 
     | 
    	} else if (uic >= 0x20) { | 
    
    
    167  | 
     | 
     | 
    		buf[0] = c;  | 
    
    
    168  | 
     | 
     | 
    		buf[1] = 0;  | 
    
    
    169  | 
     | 
     | 
    	} else { | 
    
    
    170  | 
     | 
     | 
    		buf[0] = '^';  | 
    
    
    171  | 
     | 
     | 
    		buf[1] = '@'+c;  | 
    
    
    172  | 
     | 
     | 
    		buf[2] = 0;  | 
    
    
    173  | 
     | 
     | 
    	}  | 
    
    
    174  | 
     | 
     | 
    	return (buf);  | 
    
    
    175  | 
     | 
     | 
    }  | 
    
    
    176  | 
     | 
     | 
     | 
    
    
    177  | 
     | 
     | 
    /*  | 
    
    
    178  | 
     | 
     | 
     *	The following are data structures and routines for  | 
    
    
    179  | 
     | 
     | 
     *	the "send" command.  | 
    
    
    180  | 
     | 
     | 
     *  | 
    
    
    181  | 
     | 
     | 
     */  | 
    
    
    182  | 
     | 
     | 
     | 
    
    
    183  | 
     | 
     | 
    struct sendlist { | 
    
    
    184  | 
     | 
     | 
        char	*name;		/* How user refers to it (case independent) */  | 
    
    
    185  | 
     | 
     | 
        char	*help;		/* Help information (0 ==> no help) */  | 
    
    
    186  | 
     | 
     | 
        int		needconnect;	/* Need to be connected */  | 
    
    
    187  | 
     | 
     | 
        int		narg;		/* Number of arguments */  | 
    
    
    188  | 
     | 
     | 
        int		(*handler)();	/* Routine to perform (for special ops) */  | 
    
    
    189  | 
     | 
     | 
        int		nbyte;		/* Number of bytes to send this command */  | 
    
    
    190  | 
     | 
     | 
        int		what;		/* Character to be sent (<0 ==> special) */  | 
    
    
    191  | 
     | 
     | 
    };  | 
    
    
    192  | 
     | 
     | 
     | 
    
    
    193  | 
     | 
     | 
     | 
    
    
    194  | 
     | 
     | 
    static int  | 
    
    
    195  | 
     | 
     | 
    	send_esc(void),  | 
    
    
    196  | 
     | 
     | 
    	send_help(void),  | 
    
    
    197  | 
     | 
     | 
    	send_docmd(char *),  | 
    
    
    198  | 
     | 
     | 
    	send_dontcmd(char *),  | 
    
    
    199  | 
     | 
     | 
    	send_willcmd(char *),  | 
    
    
    200  | 
     | 
     | 
    	send_wontcmd(char *);  | 
    
    
    201  | 
     | 
     | 
     | 
    
    
    202  | 
     | 
     | 
    static struct sendlist Sendlist[] = { | 
    
    
    203  | 
     | 
     | 
        { "ao",	"Send Telnet Abort output",		1, 0, 0, 2, AO }, | 
    
    
    204  | 
     | 
     | 
        { "ayt",	"Send Telnet 'Are You There'",		1, 0, 0, 2, AYT }, | 
    
    
    205  | 
     | 
     | 
        { "brk",	"Send Telnet Break",			1, 0, 0, 2, BREAK }, | 
    
    
    206  | 
     | 
     | 
        { "break",	0,					1, 0, 0, 2, BREAK }, | 
    
    
    207  | 
     | 
     | 
        { "ec",	"Send Telnet Erase Character",		1, 0, 0, 2, EC }, | 
    
    
    208  | 
     | 
     | 
        { "el",	"Send Telnet Erase Line",		1, 0, 0, 2, EL }, | 
    
    
    209  | 
     | 
     | 
        { "escape",	"Send current escape character",	1, 0, send_esc, 1, 0 }, | 
    
    
    210  | 
     | 
     | 
        { "ga",	"Send Telnet 'Go Ahead' sequence",	1, 0, 0, 2, GA }, | 
    
    
    211  | 
     | 
     | 
        { "ip",	"Send Telnet Interrupt Process",	1, 0, 0, 2, IP }, | 
    
    
    212  | 
     | 
     | 
        { "intp",	0,					1, 0, 0, 2, IP }, | 
    
    
    213  | 
     | 
     | 
        { "interrupt", 0,					1, 0, 0, 2, IP }, | 
    
    
    214  | 
     | 
     | 
        { "intr",	0,					1, 0, 0, 2, IP }, | 
    
    
    215  | 
     | 
     | 
        { "nop",	"Send Telnet 'No operation'",		1, 0, 0, 2, NOP }, | 
    
    
    216  | 
     | 
     | 
        { "eor",	"Send Telnet 'End of Record'",		1, 0, 0, 2, EOR }, | 
    
    
    217  | 
     | 
     | 
        { "abort",	"Send Telnet 'Abort Process'",		1, 0, 0, 2, ABORT }, | 
    
    
    218  | 
     | 
     | 
        { "susp",	"Send Telnet 'Suspend Process'",	1, 0, 0, 2, SUSP }, | 
    
    
    219  | 
     | 
     | 
        { "eof",	"Send Telnet End of File Character",	1, 0, 0, 2, xEOF }, | 
    
    
    220  | 
     | 
     | 
        { "synch",	"Perform Telnet 'Synch operation'",	1, 0, dosynch, 2, 0 }, | 
    
    
    221  | 
     | 
     | 
        { "getstatus", "Send request for STATUS",		1, 0, get_status, 6, 0 }, | 
    
    
    222  | 
     | 
     | 
        { "?",	"Display send options",			0, 0, send_help, 0, 0 }, | 
    
    
    223  | 
     | 
     | 
        { "help",	0,					0, 0, send_help, 0, 0 }, | 
    
    
    224  | 
     | 
     | 
        { "do",	0,					0, 1, send_docmd, 3, 0 }, | 
    
    
    225  | 
     | 
     | 
        { "dont",	0,					0, 1, send_dontcmd, 3, 0 }, | 
    
    
    226  | 
     | 
     | 
        { "will",	0,					0, 1, send_willcmd, 3, 0 }, | 
    
    
    227  | 
     | 
     | 
        { "wont",	0,					0, 1, send_wontcmd, 3, 0 }, | 
    
    
    228  | 
     | 
     | 
        { 0 } | 
    
    
    229  | 
     | 
     | 
    };  | 
    
    
    230  | 
     | 
     | 
     | 
    
    
    231  | 
     | 
     | 
    #define	GETSEND(name) ((struct sendlist *) genget(name, (char **) Sendlist, \  | 
    
    
    232  | 
     | 
     | 
    				sizeof(struct sendlist)))  | 
    
    
    233  | 
     | 
     | 
     | 
    
    
    234  | 
     | 
     | 
    static int  | 
    
    
    235  | 
     | 
     | 
    sendcmd(int argc, char **argv)  | 
    
    
    236  | 
     | 
     | 
    { | 
    
    
    237  | 
     | 
     | 
        int count;		/* how many bytes we are going to need to send */  | 
    
    
    238  | 
     | 
     | 
        int i;  | 
    
    
    239  | 
     | 
     | 
        struct sendlist *s;	/* pointer to current command */  | 
    
    
    240  | 
     | 
     | 
        int success = 0;  | 
    
    
    241  | 
     | 
     | 
        int needconnect = 0;  | 
    
    
    242  | 
     | 
     | 
     | 
    
    
    243  | 
     | 
     | 
        if (argc < 2) { | 
    
    
    244  | 
     | 
     | 
    	printf("need at least one argument for 'send' command\r\n"); | 
    
    
    245  | 
     | 
     | 
    	printf("'send ?' for help\r\n"); | 
    
    
    246  | 
     | 
     | 
    	return 0;  | 
    
    
    247  | 
     | 
     | 
        }  | 
    
    
    248  | 
     | 
     | 
        /*  | 
    
    
    249  | 
     | 
     | 
         * First, validate all the send arguments.  | 
    
    
    250  | 
     | 
     | 
         * In addition, we see how much space we are going to need, and  | 
    
    
    251  | 
     | 
     | 
         * whether or not we will be doing a "SYNCH" operation (which  | 
    
    
    252  | 
     | 
     | 
         * flushes the network queue).  | 
    
    
    253  | 
     | 
     | 
         */  | 
    
    
    254  | 
     | 
     | 
        count = 0;  | 
    
    
    255  | 
     | 
     | 
        for (i = 1; i < argc; i++) { | 
    
    
    256  | 
     | 
     | 
    	s = GETSEND(argv[i]);  | 
    
    
    257  | 
     | 
     | 
    	if (s == 0) { | 
    
    
    258  | 
     | 
     | 
    	    printf("Unknown send argument '%s'\r\n'send ?' for help.\r\n", | 
    
    
    259  | 
     | 
     | 
    			argv[i]);  | 
    
    
    260  | 
     | 
     | 
    	    return 0;  | 
    
    
    261  | 
     | 
     | 
    	} else if (Ambiguous(s)) { | 
    
    
    262  | 
     | 
     | 
    	    printf("Ambiguous send argument '%s'\r\n'send ?' for help.\r\n", | 
    
    
    263  | 
     | 
     | 
    			argv[i]);  | 
    
    
    264  | 
     | 
     | 
    	    return 0;  | 
    
    
    265  | 
     | 
     | 
    	}  | 
    
    
    266  | 
     | 
     | 
    	if (i + s->narg >= argc) { | 
    
    
    267  | 
     | 
     | 
    	    fprintf(stderr,  | 
    
    
    268  | 
     | 
     | 
    	    "Need %d argument%s to 'send %s' command.  'send %s ?' for help.\r\n",  | 
    
    
    269  | 
     | 
     | 
    		s->narg, s->narg == 1 ? "" : "s", s->name, s->name);  | 
    
    
    270  | 
     | 
     | 
    	    return 0;  | 
    
    
    271  | 
     | 
     | 
    	}  | 
    
    
    272  | 
     | 
     | 
    	count += s->nbyte;  | 
    
    
    273  | 
     | 
     | 
    	if (s->handler == send_help) { | 
    
    
    274  | 
     | 
     | 
    	    send_help();  | 
    
    
    275  | 
     | 
     | 
    	    return 0;  | 
    
    
    276  | 
     | 
     | 
    	}  | 
    
    
    277  | 
     | 
     | 
     | 
    
    
    278  | 
     | 
     | 
    	i += s->narg;  | 
    
    
    279  | 
     | 
     | 
    	needconnect += s->needconnect;  | 
    
    
    280  | 
     | 
     | 
        }  | 
    
    
    281  | 
     | 
     | 
        if (!connected && needconnect) { | 
    
    
    282  | 
     | 
     | 
    	printf("?Need to be connected first.\r\n"); | 
    
    
    283  | 
     | 
     | 
    	printf("'send ?' for help\r\n"); | 
    
    
    284  | 
     | 
     | 
    	return 0;  | 
    
    
    285  | 
     | 
     | 
        }  | 
    
    
    286  | 
     | 
     | 
        /* Now, do we have enough room? */  | 
    
    
    287  | 
     | 
     | 
        if (NETROOM() < count) { | 
    
    
    288  | 
     | 
     | 
    	printf("There is not enough room in the buffer TO the network\r\n"); | 
    
    
    289  | 
     | 
     | 
    	printf("to process your request.  Nothing will be done.\r\n"); | 
    
    
    290  | 
     | 
     | 
    	printf("('send synch' will throw away most data in the network\r\n"); | 
    
    
    291  | 
     | 
     | 
    	printf("buffer, if this might help.)\r\n"); | 
    
    
    292  | 
     | 
     | 
    	return 0;  | 
    
    
    293  | 
     | 
     | 
        }  | 
    
    
    294  | 
     | 
     | 
        /* OK, they are all OK, now go through again and actually send */  | 
    
    
    295  | 
     | 
     | 
        count = 0;  | 
    
    
    296  | 
     | 
     | 
        for (i = 1; i < argc; i++) { | 
    
    
    297  | 
     | 
     | 
    	if ((s = GETSEND(argv[i])) == 0) { | 
    
    
    298  | 
     | 
     | 
    	    fprintf(stderr, "Telnet 'send' error - argument disappeared!\r\n");  | 
    
    
    299  | 
     | 
     | 
    	    quit();  | 
    
    
    300  | 
     | 
     | 
    	}  | 
    
    
    301  | 
     | 
     | 
    	if (s->handler) { | 
    
    
    302  | 
     | 
     | 
    	    count++;  | 
    
    
    303  | 
     | 
     | 
    	    success += (*s->handler)((s->narg > 0) ? argv[i+1] : 0,  | 
    
    
    304  | 
     | 
     | 
    				  (s->narg > 1) ? argv[i+2] : 0);  | 
    
    
    305  | 
     | 
     | 
    	    i += s->narg;  | 
    
    
    306  | 
     | 
     | 
    	} else { | 
    
    
    307  | 
     | 
     | 
    	    NET2ADD(IAC, s->what);  | 
    
    
    308  | 
     | 
     | 
    	    printoption("SENT", IAC, s->what); | 
    
    
    309  | 
     | 
     | 
    	}  | 
    
    
    310  | 
     | 
     | 
        }  | 
    
    
    311  | 
     | 
     | 
        return (count == success);  | 
    
    
    312  | 
     | 
     | 
    }  | 
    
    
    313  | 
     | 
     | 
     | 
    
    
    314  | 
     | 
     | 
    static int send_tncmd(void (*func)(int, int), char *cmd, char *name);  | 
    
    
    315  | 
     | 
     | 
     | 
    
    
    316  | 
     | 
     | 
    static int  | 
    
    
    317  | 
     | 
     | 
    send_esc(void)  | 
    
    
    318  | 
     | 
     | 
    { | 
    
    
    319  | 
     | 
     | 
        NETADD(escape);  | 
    
    
    320  | 
     | 
     | 
        return 1;  | 
    
    
    321  | 
     | 
     | 
    }  | 
    
    
    322  | 
     | 
     | 
     | 
    
    
    323  | 
     | 
     | 
    static int  | 
    
    
    324  | 
     | 
     | 
    send_docmd(char *name)  | 
    
    
    325  | 
     | 
     | 
    { | 
    
    
    326  | 
     | 
     | 
        return(send_tncmd(send_do, "do", name));  | 
    
    
    327  | 
     | 
     | 
    }  | 
    
    
    328  | 
     | 
     | 
     | 
    
    
    329  | 
     | 
     | 
    static int  | 
    
    
    330  | 
     | 
     | 
    send_dontcmd(char *name)  | 
    
    
    331  | 
     | 
     | 
    { | 
    
    
    332  | 
     | 
     | 
        return(send_tncmd(send_dont, "dont", name));  | 
    
    
    333  | 
     | 
     | 
    }  | 
    
    
    334  | 
     | 
     | 
     | 
    
    
    335  | 
     | 
     | 
    static int  | 
    
    
    336  | 
     | 
     | 
    send_willcmd(char *name)  | 
    
    
    337  | 
     | 
     | 
    { | 
    
    
    338  | 
     | 
     | 
        return(send_tncmd(send_will, "will", name));  | 
    
    
    339  | 
     | 
     | 
    }  | 
    
    
    340  | 
     | 
     | 
     | 
    
    
    341  | 
     | 
     | 
    static int  | 
    
    
    342  | 
     | 
     | 
    send_wontcmd(char *name)  | 
    
    
    343  | 
     | 
     | 
    { | 
    
    
    344  | 
     | 
     | 
        return(send_tncmd(send_wont, "wont", name));  | 
    
    
    345  | 
     | 
     | 
    }  | 
    
    
    346  | 
     | 
     | 
     | 
    
    
    347  | 
     | 
     | 
    int  | 
    
    
    348  | 
     | 
     | 
    send_tncmd(void (*func)(int, int), char *cmd, char *name)  | 
    
    
    349  | 
     | 
     | 
    { | 
    
    
    350  | 
     | 
     | 
        char **cpp;  | 
    
    
    351  | 
     | 
     | 
        extern char *telopts[];  | 
    
    
    352  | 
     | 
     | 
        int val = 0;  | 
    
    
    353  | 
     | 
     | 
     | 
    
    
    354  | 
     | 
     | 
        if (isprefix(name, "help") || isprefix(name, "?")) { | 
    
    
    355  | 
     | 
     | 
    	int col, len;  | 
    
    
    356  | 
     | 
     | 
     | 
    
    
    357  | 
     | 
     | 
    	printf("Usage: send %s <value|option>\r\n", cmd); | 
    
    
    358  | 
     | 
     | 
    	printf("\"value\" must be from 0 to 255\r\n"); | 
    
    
    359  | 
     | 
     | 
    	printf("Valid options are:\r\n\t"); | 
    
    
    360  | 
     | 
     | 
     | 
    
    
    361  | 
     | 
     | 
    	col = 8;  | 
    
    
    362  | 
     | 
     | 
    	for (cpp = telopts; *cpp; cpp++) { | 
    
    
    363  | 
     | 
     | 
    	    len = strlen(*cpp) + 3;  | 
    
    
    364  | 
     | 
     | 
    	    if (col + len > 65) { | 
    
    
    365  | 
     | 
     | 
    		printf("\r\n\t"); | 
    
    
    366  | 
     | 
     | 
    		col = 8;  | 
    
    
    367  | 
     | 
     | 
    	    }  | 
    
    
    368  | 
     | 
     | 
    	    printf(" \"%s\"", *cpp); | 
    
    
    369  | 
     | 
     | 
    	    col += len;  | 
    
    
    370  | 
     | 
     | 
    	}  | 
    
    
    371  | 
     | 
     | 
    	printf("\r\n"); | 
    
    
    372  | 
     | 
     | 
    	return 0;  | 
    
    
    373  | 
     | 
     | 
        }  | 
    
    
    374  | 
     | 
     | 
        cpp = (char **)genget(name, telopts, sizeof(char *));  | 
    
    
    375  | 
     | 
     | 
        if (Ambiguous(cpp)) { | 
    
    
    376  | 
     | 
     | 
    	fprintf(stderr,"'%s': ambiguous argument ('send %s ?' for help).\r\n", | 
    
    
    377  | 
     | 
     | 
    					name, cmd);  | 
    
    
    378  | 
     | 
     | 
    	return 0;  | 
    
    
    379  | 
     | 
     | 
        }  | 
    
    
    380  | 
     | 
     | 
        if (cpp) { | 
    
    
    381  | 
     | 
     | 
    	val = cpp - telopts;  | 
    
    
    382  | 
     | 
     | 
        } else { | 
    
    
    383  | 
     | 
     | 
    	char *cp = name;  | 
    
    
    384  | 
     | 
     | 
     | 
    
    
    385  | 
     | 
     | 
    	while (*cp >= '0' && *cp <= '9') { | 
    
    
    386  | 
     | 
     | 
    	    val *= 10;  | 
    
    
    387  | 
     | 
     | 
    	    val += *cp - '0';  | 
    
    
    388  | 
     | 
     | 
    	    cp++;  | 
    
    
    389  | 
     | 
     | 
    	}  | 
    
    
    390  | 
     | 
     | 
    	if (*cp != 0) { | 
    
    
    391  | 
     | 
     | 
    	    fprintf(stderr, "'%s': unknown argument ('send %s ?' for help).\r\n", | 
    
    
    392  | 
     | 
     | 
    					name, cmd);  | 
    
    
    393  | 
     | 
     | 
    	    return 0;  | 
    
    
    394  | 
     | 
     | 
    	} else if (val < 0 || val > 255) { | 
    
    
    395  | 
     | 
     | 
    	    fprintf(stderr, "'%s': bad value ('send %s ?' for help).\r\n", | 
    
    
    396  | 
     | 
     | 
    					name, cmd);  | 
    
    
    397  | 
     | 
     | 
    	    return 0;  | 
    
    
    398  | 
     | 
     | 
    	}  | 
    
    
    399  | 
     | 
     | 
        }  | 
    
    
    400  | 
     | 
     | 
        if (!connected) { | 
    
    
    401  | 
     | 
     | 
    	printf("?Need to be connected first.\r\n"); | 
    
    
    402  | 
     | 
     | 
    	return 0;  | 
    
    
    403  | 
     | 
     | 
        }  | 
    
    
    404  | 
     | 
     | 
        (*func)(val, 1);  | 
    
    
    405  | 
     | 
     | 
        return 1;  | 
    
    
    406  | 
     | 
     | 
    }  | 
    
    
    407  | 
     | 
     | 
     | 
    
    
    408  | 
     | 
     | 
    static int  | 
    
    
    409  | 
     | 
     | 
    send_help(void)  | 
    
    
    410  | 
     | 
     | 
    { | 
    
    
    411  | 
     | 
     | 
        struct sendlist *s;	/* pointer to current command */  | 
    
    
    412  | 
     | 
     | 
        for (s = Sendlist; s->name; s++) { | 
    
    
    413  | 
     | 
     | 
    	if (s->help)  | 
    
    
    414  | 
     | 
     | 
    	    printf("%-15s %s\r\n", s->name, s->help); | 
    
    
    415  | 
     | 
     | 
        }  | 
    
    
    416  | 
     | 
     | 
        return(0);  | 
    
    
    417  | 
     | 
     | 
    }  | 
    
    
    418  | 
     | 
     | 
     | 
    
    
    419  | 
     | 
     | 
    /*  | 
    
    
    420  | 
     | 
     | 
     * The following are the routines and data structures referred  | 
    
    
    421  | 
     | 
     | 
     * to by the arguments to the "toggle" command.  | 
    
    
    422  | 
     | 
     | 
     */  | 
    
    
    423  | 
     | 
     | 
     | 
    
    
    424  | 
     | 
     | 
    static int  | 
    
    
    425  | 
     | 
     | 
    lclchars(int unused)  | 
    
    
    426  | 
     | 
     | 
    { | 
    
    
    427  | 
     | 
     | 
        donelclchars = 1;  | 
    
    
    428  | 
     | 
     | 
        return 1;  | 
    
    
    429  | 
     | 
     | 
    }  | 
    
    
    430  | 
     | 
     | 
     | 
    
    
    431  | 
     | 
     | 
    static int  | 
    
    
    432  | 
     | 
     | 
    togcrlf(int unused)  | 
    
    
    433  | 
     | 
     | 
    { | 
    
    
    434  | 
     | 
     | 
        if (crlf) { | 
    
    
    435  | 
     | 
     | 
    	printf("Will send carriage returns as telnet <CR><LF>.\r\n"); | 
    
    
    436  | 
     | 
     | 
        } else { | 
    
    
    437  | 
     | 
     | 
    	printf("Will send carriage returns as telnet <CR><NUL>.\r\n"); | 
    
    
    438  | 
     | 
     | 
        }  | 
    
    
    439  | 
     | 
     | 
        return 1;  | 
    
    
    440  | 
     | 
     | 
    }  | 
    
    
    441  | 
     | 
     | 
     | 
    
    
    442  | 
     | 
     | 
    int binmode;  | 
    
    
    443  | 
     | 
     | 
     | 
    
    
    444  | 
     | 
     | 
    static int  | 
    
    
    445  | 
     | 
     | 
    togbinary(int val)  | 
    
    
    446  | 
     | 
     | 
    { | 
    
    
    447  | 
     | 
     | 
        donebinarytoggle = 1;  | 
    
    
    448  | 
     | 
     | 
     | 
    
    
    449  | 
     | 
     | 
        if (val >= 0) { | 
    
    
    450  | 
     | 
     | 
    	binmode = val;  | 
    
    
    451  | 
     | 
     | 
        } else { | 
    
    
    452  | 
     | 
     | 
    	if (my_want_state_is_will(TELOPT_BINARY) &&  | 
    
    
    453  | 
     | 
     | 
    				my_want_state_is_do(TELOPT_BINARY)) { | 
    
    
    454  | 
     | 
     | 
    	    binmode = 1;  | 
    
    
    455  | 
     | 
     | 
    	} else if (my_want_state_is_wont(TELOPT_BINARY) &&  | 
    
    
    456  | 
     | 
     | 
    				my_want_state_is_dont(TELOPT_BINARY)) { | 
    
    
    457  | 
     | 
     | 
    	    binmode = 0;  | 
    
    
    458  | 
     | 
     | 
    	}  | 
    
    
    459  | 
     | 
     | 
    	val = binmode ? 0 : 1;  | 
    
    
    460  | 
     | 
     | 
        }  | 
    
    
    461  | 
     | 
     | 
     | 
    
    
    462  | 
     | 
     | 
        if (val == 1) { | 
    
    
    463  | 
     | 
     | 
    	if (my_want_state_is_will(TELOPT_BINARY) &&  | 
    
    
    464  | 
     | 
     | 
    					my_want_state_is_do(TELOPT_BINARY)) { | 
    
    
    465  | 
     | 
     | 
    	    printf("Already operating in binary mode with remote host.\r\n"); | 
    
    
    466  | 
     | 
     | 
    	} else { | 
    
    
    467  | 
     | 
     | 
    	    printf("Negotiating binary mode with remote host.\r\n"); | 
    
    
    468  | 
     | 
     | 
    	    tel_enter_binary(3);  | 
    
    
    469  | 
     | 
     | 
    	}  | 
    
    
    470  | 
     | 
     | 
        } else { | 
    
    
    471  | 
     | 
     | 
    	if (my_want_state_is_wont(TELOPT_BINARY) &&  | 
    
    
    472  | 
     | 
     | 
    					my_want_state_is_dont(TELOPT_BINARY)) { | 
    
    
    473  | 
     | 
     | 
    	    printf("Already in network ascii mode with remote host.\r\n"); | 
    
    
    474  | 
     | 
     | 
    	} else { | 
    
    
    475  | 
     | 
     | 
    	    printf("Negotiating network ascii mode with remote host.\r\n"); | 
    
    
    476  | 
     | 
     | 
    	    tel_leave_binary(3);  | 
    
    
    477  | 
     | 
     | 
    	}  | 
    
    
    478  | 
     | 
     | 
        }  | 
    
    
    479  | 
     | 
     | 
        return 1;  | 
    
    
    480  | 
     | 
     | 
    }  | 
    
    
    481  | 
     | 
     | 
     | 
    
    
    482  | 
     | 
     | 
    static int  | 
    
    
    483  | 
     | 
     | 
    togrbinary(int val)  | 
    
    
    484  | 
     | 
     | 
    { | 
    
    
    485  | 
     | 
     | 
        donebinarytoggle = 1;  | 
    
    
    486  | 
     | 
     | 
     | 
    
    
    487  | 
     | 
     | 
        if (val == -1)  | 
    
    
    488  | 
     | 
     | 
    	val = my_want_state_is_do(TELOPT_BINARY) ? 0 : 1;  | 
    
    
    489  | 
     | 
     | 
     | 
    
    
    490  | 
     | 
     | 
        if (val == 1) { | 
    
    
    491  | 
     | 
     | 
    	if (my_want_state_is_do(TELOPT_BINARY)) { | 
    
    
    492  | 
     | 
     | 
    	    printf("Already receiving in binary mode.\r\n"); | 
    
    
    493  | 
     | 
     | 
    	} else { | 
    
    
    494  | 
     | 
     | 
    	    printf("Negotiating binary mode on input.\r\n"); | 
    
    
    495  | 
     | 
     | 
    	    tel_enter_binary(1);  | 
    
    
    496  | 
     | 
     | 
    	}  | 
    
    
    497  | 
     | 
     | 
        } else { | 
    
    
    498  | 
     | 
     | 
    	if (my_want_state_is_dont(TELOPT_BINARY)) { | 
    
    
    499  | 
     | 
     | 
    	    printf("Already receiving in network ascii mode.\r\n"); | 
    
    
    500  | 
     | 
     | 
    	} else { | 
    
    
    501  | 
     | 
     | 
    	    printf("Negotiating network ascii mode on input.\r\n"); | 
    
    
    502  | 
     | 
     | 
    	    tel_leave_binary(1);  | 
    
    
    503  | 
     | 
     | 
    	}  | 
    
    
    504  | 
     | 
     | 
        }  | 
    
    
    505  | 
     | 
     | 
        return 1;  | 
    
    
    506  | 
     | 
     | 
    }  | 
    
    
    507  | 
     | 
     | 
     | 
    
    
    508  | 
     | 
     | 
    static int  | 
    
    
    509  | 
     | 
     | 
    togxbinary(int val)  | 
    
    
    510  | 
     | 
     | 
    { | 
    
    
    511  | 
     | 
     | 
        donebinarytoggle = 1;  | 
    
    
    512  | 
     | 
     | 
     | 
    
    
    513  | 
     | 
     | 
        if (val == -1)  | 
    
    
    514  | 
     | 
     | 
    	val = my_want_state_is_will(TELOPT_BINARY) ? 0 : 1;  | 
    
    
    515  | 
     | 
     | 
     | 
    
    
    516  | 
     | 
     | 
        if (val == 1) { | 
    
    
    517  | 
     | 
     | 
    	if (my_want_state_is_will(TELOPT_BINARY)) { | 
    
    
    518  | 
     | 
     | 
    	    printf("Already transmitting in binary mode.\r\n"); | 
    
    
    519  | 
     | 
     | 
    	} else { | 
    
    
    520  | 
     | 
     | 
    	    printf("Negotiating binary mode on output.\r\n"); | 
    
    
    521  | 
     | 
     | 
    	    tel_enter_binary(2);  | 
    
    
    522  | 
     | 
     | 
    	}  | 
    
    
    523  | 
     | 
     | 
        } else { | 
    
    
    524  | 
     | 
     | 
    	if (my_want_state_is_wont(TELOPT_BINARY)) { | 
    
    
    525  | 
     | 
     | 
    	    printf("Already transmitting in network ascii mode.\r\n"); | 
    
    
    526  | 
     | 
     | 
    	} else { | 
    
    
    527  | 
     | 
     | 
    	    printf("Negotiating network ascii mode on output.\r\n"); | 
    
    
    528  | 
     | 
     | 
    	    tel_leave_binary(2);  | 
    
    
    529  | 
     | 
     | 
    	}  | 
    
    
    530  | 
     | 
     | 
        }  | 
    
    
    531  | 
     | 
     | 
        return 1;  | 
    
    
    532  | 
     | 
     | 
    }  | 
    
    
    533  | 
     | 
     | 
     | 
    
    
    534  | 
     | 
     | 
     | 
    
    
    535  | 
     | 
     | 
    static int togglehelp(int);  | 
    
    
    536  | 
     | 
     | 
     | 
    
    
    537  | 
     | 
     | 
    struct togglelist { | 
    
    
    538  | 
     | 
     | 
        char	*name;			/* name of toggle */  | 
    
    
    539  | 
     | 
     | 
        char	*help;			/* help message */  | 
    
    
    540  | 
     | 
     | 
        int		(*handler)(int);	/* routine to do actual setting */  | 
    
    
    541  | 
     | 
     | 
        int		*variable;  | 
    
    
    542  | 
     | 
     | 
        char	*actionexplanation;  | 
    
    
    543  | 
     | 
     | 
        int		needconnect;	/* Need to be connected */  | 
    
    
    544  | 
     | 
     | 
    };  | 
    
    
    545  | 
     | 
     | 
     | 
    
    
    546  | 
     | 
     | 
    static struct togglelist Togglelist[] = { | 
    
    
    547  | 
     | 
     | 
        { "autoflush", | 
    
    
    548  | 
     | 
     | 
    	"flushing of output when sending interrupt characters",  | 
    
    
    549  | 
     | 
     | 
    	    0,  | 
    
    
    550  | 
     | 
     | 
    		&autoflush,  | 
    
    
    551  | 
     | 
     | 
    		    "flush output when sending interrupt characters" },  | 
    
    
    552  | 
     | 
     | 
        { "autosynch", | 
    
    
    553  | 
     | 
     | 
    	"automatic sending of interrupt characters in urgent mode",  | 
    
    
    554  | 
     | 
     | 
    	    0,  | 
    
    
    555  | 
     | 
     | 
    		&autosynch,  | 
    
    
    556  | 
     | 
     | 
    		    "send interrupt characters in urgent mode" },  | 
    
    
    557  | 
     | 
     | 
        { "autologin", | 
    
    
    558  | 
     | 
     | 
    	"automatic sending of login name",  | 
    
    
    559  | 
     | 
     | 
    	    0,  | 
    
    
    560  | 
     | 
     | 
    		&autologin,  | 
    
    
    561  | 
     | 
     | 
    		    "send login name" },  | 
    
    
    562  | 
     | 
     | 
        { "skiprc", | 
    
    
    563  | 
     | 
     | 
    	"don't read ~/.telnetrc file",  | 
    
    
    564  | 
     | 
     | 
    	    0,  | 
    
    
    565  | 
     | 
     | 
    		&skiprc,  | 
    
    
    566  | 
     | 
     | 
    		    "skip reading of ~/.telnetrc file" },  | 
    
    
    567  | 
     | 
     | 
        { "binary", | 
    
    
    568  | 
     | 
     | 
    	"sending and receiving of binary data",  | 
    
    
    569  | 
     | 
     | 
    	    togbinary,  | 
    
    
    570  | 
     | 
     | 
    		0,  | 
    
    
    571  | 
     | 
     | 
    		    0 },  | 
    
    
    572  | 
     | 
     | 
        { "inbinary", | 
    
    
    573  | 
     | 
     | 
    	"receiving of binary data",  | 
    
    
    574  | 
     | 
     | 
    	    togrbinary,  | 
    
    
    575  | 
     | 
     | 
    		0,  | 
    
    
    576  | 
     | 
     | 
    		    0 },  | 
    
    
    577  | 
     | 
     | 
        { "outbinary", | 
    
    
    578  | 
     | 
     | 
    	"sending of binary data",  | 
    
    
    579  | 
     | 
     | 
    	    togxbinary,  | 
    
    
    580  | 
     | 
     | 
    		0,  | 
    
    
    581  | 
     | 
     | 
    		    0 },  | 
    
    
    582  | 
     | 
     | 
        { "crlf", | 
    
    
    583  | 
     | 
     | 
    	"sending carriage returns as telnet <CR><LF>",  | 
    
    
    584  | 
     | 
     | 
    	    togcrlf,  | 
    
    
    585  | 
     | 
     | 
    		&crlf,  | 
    
    
    586  | 
     | 
     | 
    		    0 },  | 
    
    
    587  | 
     | 
     | 
        { "crmod", | 
    
    
    588  | 
     | 
     | 
    	"mapping of received carriage returns",  | 
    
    
    589  | 
     | 
     | 
    	    0,  | 
    
    
    590  | 
     | 
     | 
    		&crmod,  | 
    
    
    591  | 
     | 
     | 
    		    "map carriage return on output" },  | 
    
    
    592  | 
     | 
     | 
        { "localchars", | 
    
    
    593  | 
     | 
     | 
    	"local recognition of certain control characters",  | 
    
    
    594  | 
     | 
     | 
    	    lclchars,  | 
    
    
    595  | 
     | 
     | 
    		&localchars,  | 
    
    
    596  | 
     | 
     | 
    		    "recognize certain control characters" },  | 
    
    
    597  | 
     | 
     | 
        { " ", "", 0, 0 },		/* empty line */ | 
    
    
    598  | 
     | 
     | 
        { "netdata", | 
    
    
    599  | 
     | 
     | 
    	"printing of hexadecimal network data (debugging)",  | 
    
    
    600  | 
     | 
     | 
    	    0,  | 
    
    
    601  | 
     | 
     | 
    		&netdata,  | 
    
    
    602  | 
     | 
     | 
    		    "print hexadecimal representation of network traffic" },  | 
    
    
    603  | 
     | 
     | 
        { "prettydump", | 
    
    
    604  | 
     | 
     | 
    	"output of \"netdata\" to user readable format (debugging)",  | 
    
    
    605  | 
     | 
     | 
    	    0,  | 
    
    
    606  | 
     | 
     | 
    		&prettydump,  | 
    
    
    607  | 
     | 
     | 
    		    "print user readable output for \"netdata\"" },  | 
    
    
    608  | 
     | 
     | 
        { "options", | 
    
    
    609  | 
     | 
     | 
    	"viewing of options processing (debugging)",  | 
    
    
    610  | 
     | 
     | 
    	    0,  | 
    
    
    611  | 
     | 
     | 
    		&showoptions,  | 
    
    
    612  | 
     | 
     | 
    		    "show option processing" },  | 
    
    
    613  | 
     | 
     | 
        { "termdata", | 
    
    
    614  | 
     | 
     | 
    	"(debugging) toggle printing of hexadecimal terminal data",  | 
    
    
    615  | 
     | 
     | 
    	    0,  | 
    
    
    616  | 
     | 
     | 
    		&termdata,  | 
    
    
    617  | 
     | 
     | 
    		    "print hexadecimal representation of terminal traffic" },  | 
    
    
    618  | 
     | 
     | 
        { "?", | 
    
    
    619  | 
     | 
     | 
    	0,  | 
    
    
    620  | 
     | 
     | 
    	    togglehelp },  | 
    
    
    621  | 
     | 
     | 
        { "help", | 
    
    
    622  | 
     | 
     | 
    	0,  | 
    
    
    623  | 
     | 
     | 
    	    togglehelp },  | 
    
    
    624  | 
     | 
     | 
        { 0 } | 
    
    
    625  | 
     | 
     | 
    };  | 
    
    
    626  | 
     | 
     | 
     | 
    
    
    627  | 
     | 
     | 
    static int  | 
    
    
    628  | 
     | 
     | 
    togglehelp(int unused)  | 
    
    
    629  | 
     | 
     | 
    { | 
    
    
    630  | 
     | 
     | 
        struct togglelist *c;  | 
    
    
    631  | 
     | 
     | 
     | 
    
    
    632  | 
     | 
     | 
        for (c = Togglelist; c->name; c++) { | 
    
    
    633  | 
     | 
     | 
    	if (c->help) { | 
    
    
    634  | 
     | 
     | 
    	    if (*c->help)  | 
    
    
    635  | 
     | 
     | 
    		printf("%-15s toggle %s\r\n", c->name, c->help); | 
    
    
    636  | 
     | 
     | 
    	    else  | 
    
    
    637  | 
     | 
     | 
    		printf("\r\n"); | 
    
    
    638  | 
     | 
     | 
    	}  | 
    
    
    639  | 
     | 
     | 
        }  | 
    
    
    640  | 
     | 
     | 
        printf("\r\n"); | 
    
    
    641  | 
     | 
     | 
        printf("%-15s %s\r\n", "?", "display help information"); | 
    
    
    642  | 
     | 
     | 
        return 0;  | 
    
    
    643  | 
     | 
     | 
    }  | 
    
    
    644  | 
     | 
     | 
     | 
    
    
    645  | 
     | 
     | 
    static void  | 
    
    
    646  | 
     | 
     | 
    settogglehelp(int set)  | 
    
    
    647  | 
     | 
     | 
    { | 
    
    
    648  | 
     | 
     | 
        struct togglelist *c;  | 
    
    
    649  | 
     | 
     | 
     | 
    
    
    650  | 
     | 
     | 
        for (c = Togglelist; c->name; c++) { | 
    
    
    651  | 
     | 
     | 
    	if (c->help) { | 
    
    
    652  | 
     | 
     | 
    	    if (*c->help)  | 
    
    
    653  | 
     | 
     | 
    		printf("%-15s %s %s\r\n", c->name, set ? "enable" : "disable", | 
    
    
    654  | 
     | 
     | 
    						c->help);  | 
    
    
    655  | 
     | 
     | 
    	    else  | 
    
    
    656  | 
     | 
     | 
    		printf("\r\n"); | 
    
    
    657  | 
     | 
     | 
    	}  | 
    
    
    658  | 
     | 
     | 
        }  | 
    
    
    659  | 
     | 
     | 
    }  | 
    
    
    660  | 
     | 
     | 
     | 
    
    
    661  | 
     | 
     | 
    #define	GETTOGGLE(name) (struct togglelist *) \  | 
    
    
    662  | 
     | 
     | 
    		genget(name, (char **) Togglelist, sizeof(struct togglelist))  | 
    
    
    663  | 
     | 
     | 
     | 
    
    
    664  | 
     | 
     | 
    static int  | 
    
    
    665  | 
     | 
     | 
    toggle(int argc, char *argv[])  | 
    
    
    666  | 
     | 
     | 
    { | 
    
    
    667  | 
     | 
     | 
        int retval = 1;  | 
    
    
    668  | 
     | 
     | 
        char *name;  | 
    
    
    669  | 
     | 
     | 
        struct togglelist *c;  | 
    
    
    670  | 
     | 
     | 
     | 
    
    
    671  | 
     | 
     | 
        if (argc < 2) { | 
    
    
    672  | 
     | 
     | 
    	fprintf(stderr,  | 
    
    
    673  | 
     | 
     | 
    	    "Need an argument to 'toggle' command.  'toggle ?' for help.\r\n");  | 
    
    
    674  | 
     | 
     | 
    	return 0;  | 
    
    
    675  | 
     | 
     | 
        }  | 
    
    
    676  | 
     | 
     | 
        argc--;  | 
    
    
    677  | 
     | 
     | 
        argv++;  | 
    
    
    678  | 
     | 
     | 
        while (argc--) { | 
    
    
    679  | 
     | 
     | 
    	name = *argv++;  | 
    
    
    680  | 
     | 
     | 
    	c = GETTOGGLE(name);  | 
    
    
    681  | 
     | 
     | 
    	if (Ambiguous(c)) { | 
    
    
    682  | 
     | 
     | 
    	    fprintf(stderr, "'%s': ambiguous argument ('toggle ?' for help).\r\n", | 
    
    
    683  | 
     | 
     | 
    					name);  | 
    
    
    684  | 
     | 
     | 
    	    return 0;  | 
    
    
    685  | 
     | 
     | 
    	} else if (c == 0) { | 
    
    
    686  | 
     | 
     | 
    	    fprintf(stderr, "'%s': unknown argument ('toggle ?' for help).\r\n", | 
    
    
    687  | 
     | 
     | 
    					name);  | 
    
    
    688  | 
     | 
     | 
    	    return 0;  | 
    
    
    689  | 
     | 
     | 
    	} else if (!connected && c->needconnect) { | 
    
    
    690  | 
     | 
     | 
    	    printf("?Need to be connected first.\r\n"); | 
    
    
    691  | 
     | 
     | 
    	    printf("'send ?' for help\r\n"); | 
    
    
    692  | 
     | 
     | 
    	    return 0;  | 
    
    
    693  | 
     | 
     | 
    	} else { | 
    
    
    694  | 
     | 
     | 
    	    if (c->variable) { | 
    
    
    695  | 
     | 
     | 
    		*c->variable = !*c->variable;		/* invert it */  | 
    
    
    696  | 
     | 
     | 
    		if (c->actionexplanation) { | 
    
    
    697  | 
     | 
     | 
    		    printf("%s %s.\r\n", *c->variable? "Will" : "Won't", | 
    
    
    698  | 
     | 
     | 
    							c->actionexplanation);  | 
    
    
    699  | 
     | 
     | 
    		}  | 
    
    
    700  | 
     | 
     | 
    	    }  | 
    
    
    701  | 
     | 
     | 
    	    if (c->handler) { | 
    
    
    702  | 
     | 
     | 
    		retval &= (*c->handler)(-1);  | 
    
    
    703  | 
     | 
     | 
    	    }  | 
    
    
    704  | 
     | 
     | 
    	}  | 
    
    
    705  | 
     | 
     | 
        }  | 
    
    
    706  | 
     | 
     | 
        return retval;  | 
    
    
    707  | 
     | 
     | 
    }  | 
    
    
    708  | 
     | 
     | 
     | 
    
    
    709  | 
     | 
     | 
    /*  | 
    
    
    710  | 
     | 
     | 
     * The following perform the "set" command.  | 
    
    
    711  | 
     | 
     | 
     */  | 
    
    
    712  | 
     | 
     | 
     | 
    
    
    713  | 
     | 
     | 
    struct termios new_tc = { 0 }; | 
    
    
    714  | 
     | 
     | 
     | 
    
    
    715  | 
     | 
     | 
    struct setlist { | 
    
    
    716  | 
     | 
     | 
        char *name;				/* name */  | 
    
    
    717  | 
     | 
     | 
        char *help;				/* help information */  | 
    
    
    718  | 
     | 
     | 
        void (*handler)(const char *);  | 
    
    
    719  | 
     | 
     | 
        cc_t *charp;			/* where it is located at */  | 
    
    
    720  | 
     | 
     | 
    };  | 
    
    
    721  | 
     | 
     | 
     | 
    
    
    722  | 
     | 
     | 
    static struct setlist Setlist[] = { | 
    
    
    723  | 
     | 
     | 
    #ifdef	KLUDGELINEMODE  | 
    
    
    724  | 
     | 
     | 
        { "echo", 	"character to toggle local echoing on/off", 0, &echoc }, | 
    
    
    725  | 
     | 
     | 
    #endif  | 
    
    
    726  | 
     | 
     | 
        { "escape",	"character to escape back to telnet command mode", 0, &escape }, | 
    
    
    727  | 
     | 
     | 
        { "rlogin", "rlogin escape character", 0, &rlogin }, | 
    
    
    728  | 
     | 
     | 
        { " ", "" }, | 
    
    
    729  | 
     | 
     | 
        { " ", "The following need 'localchars' to be toggled true", 0, 0 }, | 
    
    
    730  | 
     | 
     | 
        { "flushoutput", "character to cause an Abort Output", 0, &termFlushChar }, | 
    
    
    731  | 
     | 
     | 
        { "interrupt", "character to cause an Interrupt Process", 0, &termIntChar }, | 
    
    
    732  | 
     | 
     | 
        { "quit",	"character to cause an Abort process", 0, &termQuitChar }, | 
    
    
    733  | 
     | 
     | 
        { "eof",	"character to cause an EOF ", 0, &termEofChar }, | 
    
    
    734  | 
     | 
     | 
        { " ", "" }, | 
    
    
    735  | 
     | 
     | 
        { " ", "The following are for local editing in linemode", 0, 0 }, | 
    
    
    736  | 
     | 
     | 
        { "erase",	"character to use to erase a character", 0, &termEraseChar }, | 
    
    
    737  | 
     | 
     | 
        { "kill",	"character to use to erase a line", 0, &termKillChar }, | 
    
    
    738  | 
     | 
     | 
        { "lnext",	"character to use for literal next", 0, &termLiteralNextChar }, | 
    
    
    739  | 
     | 
     | 
        { "susp",	"character to cause a Suspend Process", 0, &termSuspChar }, | 
    
    
    740  | 
     | 
     | 
        { "reprint", "character to use for line reprint", 0, &termRprntChar }, | 
    
    
    741  | 
     | 
     | 
        { "worderase", "character to use to erase a word", 0, &termWerasChar }, | 
    
    
    742  | 
     | 
     | 
        { "start",	"character to use for XON", 0, &termStartChar }, | 
    
    
    743  | 
     | 
     | 
        { "stop",	"character to use for XOFF", 0, &termStopChar }, | 
    
    
    744  | 
     | 
     | 
        { "forw1",	"alternate end of line character", 0, &termForw1Char }, | 
    
    
    745  | 
     | 
     | 
        { "forw2",	"alternate end of line character", 0, &termForw2Char }, | 
    
    
    746  | 
     | 
     | 
        { "ayt",	"alternate AYT character", 0, &termAytChar }, | 
    
    
    747  | 
     | 
     | 
        { 0 } | 
    
    
    748  | 
     | 
     | 
    };  | 
    
    
    749  | 
     | 
     | 
     | 
    
    
    750  | 
     | 
     | 
    static struct setlist *  | 
    
    
    751  | 
     | 
     | 
    getset(char *name)  | 
    
    
    752  | 
     | 
     | 
    { | 
    
    
    753  | 
     | 
     | 
        return (struct setlist *)  | 
    
    
    754  | 
     | 
     | 
    		genget(name, (char **) Setlist, sizeof(struct setlist));  | 
    
    
    755  | 
     | 
     | 
    }  | 
    
    
    756  | 
     | 
     | 
     | 
    
    
    757  | 
     | 
     | 
    void  | 
    
    
    758  | 
     | 
     | 
    set_escape_char(char *s)  | 
    
    
    759  | 
     | 
     | 
    { | 
    
    
    760  | 
     | 
     | 
    	if (rlogin != _POSIX_VDISABLE) { | 
    
    
    761  | 
     | 
     | 
    		rlogin = (s && *s) ? special(s) : _POSIX_VDISABLE;  | 
    
    
    762  | 
     | 
     | 
    		printf("Telnet rlogin escape character is '%s'.\r\n", | 
    
    
    763  | 
     | 
     | 
    					control(rlogin));  | 
    
    
    764  | 
     | 
     | 
    	} else { | 
    
    
    765  | 
     | 
     | 
    		escape = (s && *s) ? special(s) : _POSIX_VDISABLE;  | 
    
    
    766  | 
     | 
     | 
    		printf("Telnet escape character is '%s'.\r\n", control(escape)); | 
    
    
    767  | 
     | 
     | 
    	}  | 
    
    
    768  | 
     | 
     | 
    }  | 
    
    
    769  | 
     | 
     | 
     | 
    
    
    770  | 
     | 
     | 
    static int  | 
    
    
    771  | 
     | 
     | 
    setcmd(int argc, char *argv[])  | 
    
    
    772  | 
     | 
     | 
    { | 
    
    
    773  | 
     | 
     | 
        int value;  | 
    
    
    774  | 
     | 
     | 
        struct setlist *ct;  | 
    
    
    775  | 
     | 
     | 
        struct togglelist *c;  | 
    
    
    776  | 
     | 
     | 
     | 
    
    
    777  | 
     | 
     | 
        if (argc < 2 || argc > 3) { | 
    
    
    778  | 
     | 
     | 
    	printf("Format is 'set Name Value'\r\n'set ?' for help.\r\n"); | 
    
    
    779  | 
     | 
     | 
    	return 0;  | 
    
    
    780  | 
     | 
     | 
        }  | 
    
    
    781  | 
     | 
     | 
        if ((argc == 2) && (isprefix(argv[1], "?") || isprefix(argv[1], "help"))) { | 
    
    
    782  | 
     | 
     | 
    	for (ct = Setlist; ct->name; ct++)  | 
    
    
    783  | 
     | 
     | 
    	    printf("%-15s %s\r\n", ct->name, ct->help); | 
    
    
    784  | 
     | 
     | 
    	printf("\r\n"); | 
    
    
    785  | 
     | 
     | 
    	settogglehelp(1);  | 
    
    
    786  | 
     | 
     | 
    	printf("%-15s %s\r\n", "?", "display help information"); | 
    
    
    787  | 
     | 
     | 
    	return 0;  | 
    
    
    788  | 
     | 
     | 
        }  | 
    
    
    789  | 
     | 
     | 
     | 
    
    
    790  | 
     | 
     | 
        ct = getset(argv[1]);  | 
    
    
    791  | 
     | 
     | 
        if (ct == 0) { | 
    
    
    792  | 
     | 
     | 
    	c = GETTOGGLE(argv[1]);  | 
    
    
    793  | 
     | 
     | 
    	if (c == 0) { | 
    
    
    794  | 
     | 
     | 
    	    fprintf(stderr, "'%s': unknown argument ('set ?' for help).\r\n", | 
    
    
    795  | 
     | 
     | 
    			argv[1]);  | 
    
    
    796  | 
     | 
     | 
    	    return 0;  | 
    
    
    797  | 
     | 
     | 
    	} else if (Ambiguous(c)) { | 
    
    
    798  | 
     | 
     | 
    	    fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\r\n", | 
    
    
    799  | 
     | 
     | 
    			argv[1]);  | 
    
    
    800  | 
     | 
     | 
    	    return 0;  | 
    
    
    801  | 
     | 
     | 
    	} else if (!connected && c->needconnect) { | 
    
    
    802  | 
     | 
     | 
    	    printf("?Need to be connected first.\r\n"); | 
    
    
    803  | 
     | 
     | 
    	    printf("'send ?' for help\r\n"); | 
    
    
    804  | 
     | 
     | 
    	    return 0;  | 
    
    
    805  | 
     | 
     | 
    	}  | 
    
    
    806  | 
     | 
     | 
     | 
    
    
    807  | 
     | 
     | 
    	if (c->variable) { | 
    
    
    808  | 
     | 
     | 
    	    if ((argc == 2) || (strcmp("on", argv[2]) == 0)) | 
    
    
    809  | 
     | 
     | 
    		*c->variable = 1;  | 
    
    
    810  | 
     | 
     | 
    	    else if (strcmp("off", argv[2]) == 0) | 
    
    
    811  | 
     | 
     | 
    		*c->variable = 0;  | 
    
    
    812  | 
     | 
     | 
    	    else { | 
    
    
    813  | 
     | 
     | 
    		printf("Format is 'set togglename [on|off]'\r\n'set ?' for help.\r\n"); | 
    
    
    814  | 
     | 
     | 
    		return 0;  | 
    
    
    815  | 
     | 
     | 
    	    }  | 
    
    
    816  | 
     | 
     | 
    	    if (c->actionexplanation) { | 
    
    
    817  | 
     | 
     | 
    		printf("%s %s.\r\n", *c->variable? "Will" : "Won't", | 
    
    
    818  | 
     | 
     | 
    							c->actionexplanation);  | 
    
    
    819  | 
     | 
     | 
    	    }  | 
    
    
    820  | 
     | 
     | 
    	}  | 
    
    
    821  | 
     | 
     | 
    	if (c->handler)  | 
    
    
    822  | 
     | 
     | 
    	    (*c->handler)(1);  | 
    
    
    823  | 
     | 
     | 
        } else if (argc != 3) { | 
    
    
    824  | 
     | 
     | 
    	printf("Format is 'set Name Value'\r\n'set ?' for help.\r\n"); | 
    
    
    825  | 
     | 
     | 
    	return 0;  | 
    
    
    826  | 
     | 
     | 
        } else if (Ambiguous(ct)) { | 
    
    
    827  | 
     | 
     | 
    	fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\r\n", | 
    
    
    828  | 
     | 
     | 
    			argv[1]);  | 
    
    
    829  | 
     | 
     | 
    	return 0;  | 
    
    
    830  | 
     | 
     | 
        } else if (ct->handler) { | 
    
    
    831  | 
     | 
     | 
    	(*ct->handler)(argv[2]);  | 
    
    
    832  | 
     | 
     | 
    	printf("%s set to \"%s\".\r\n", ct->name, (char *)ct->charp); | 
    
    
    833  | 
     | 
     | 
        } else { | 
    
    
    834  | 
     | 
     | 
    	if (strcmp("off", argv[2])) { | 
    
    
    835  | 
     | 
     | 
    	    value = special(argv[2]);  | 
    
    
    836  | 
     | 
     | 
    	} else { | 
    
    
    837  | 
     | 
     | 
    	    value = _POSIX_VDISABLE;  | 
    
    
    838  | 
     | 
     | 
    	}  | 
    
    
    839  | 
     | 
     | 
    	*(ct->charp) = (cc_t)value;  | 
    
    
    840  | 
     | 
     | 
    	printf("%s character is '%s'.\r\n", ct->name, control(*(ct->charp))); | 
    
    
    841  | 
     | 
     | 
        }  | 
    
    
    842  | 
     | 
     | 
        slc_check();  | 
    
    
    843  | 
     | 
     | 
        return 1;  | 
    
    
    844  | 
     | 
     | 
    }  | 
    
    
    845  | 
     | 
     | 
     | 
    
    
    846  | 
     | 
     | 
    static int  | 
    
    
    847  | 
     | 
     | 
    unsetcmd(int argc, char *argv[])  | 
    
    
    848  | 
     | 
     | 
    { | 
    
    
    849  | 
     | 
     | 
        struct setlist *ct;  | 
    
    
    850  | 
     | 
     | 
        struct togglelist *c;  | 
    
    
    851  | 
     | 
     | 
        char *name;  | 
    
    
    852  | 
     | 
     | 
     | 
    
    
    853  | 
     | 
     | 
        if (argc < 2) { | 
    
    
    854  | 
     | 
     | 
    	fprintf(stderr,  | 
    
    
    855  | 
     | 
     | 
    	    "Need an argument to 'unset' command.  'unset ?' for help.\r\n");  | 
    
    
    856  | 
     | 
     | 
    	return 0;  | 
    
    
    857  | 
     | 
     | 
        }  | 
    
    
    858  | 
     | 
     | 
        if (isprefix(argv[1], "?") || isprefix(argv[1], "help")) { | 
    
    
    859  | 
     | 
     | 
    	for (ct = Setlist; ct->name; ct++)  | 
    
    
    860  | 
     | 
     | 
    	    printf("%-15s %s\r\n", ct->name, ct->help); | 
    
    
    861  | 
     | 
     | 
    	printf("\r\n"); | 
    
    
    862  | 
     | 
     | 
    	settogglehelp(0);  | 
    
    
    863  | 
     | 
     | 
    	printf("%-15s %s\r\n", "?", "display help information"); | 
    
    
    864  | 
     | 
     | 
    	return 0;  | 
    
    
    865  | 
     | 
     | 
        }  | 
    
    
    866  | 
     | 
     | 
     | 
    
    
    867  | 
     | 
     | 
        argc--;  | 
    
    
    868  | 
     | 
     | 
        argv++;  | 
    
    
    869  | 
     | 
     | 
        while (argc--) { | 
    
    
    870  | 
     | 
     | 
    	name = *argv++;  | 
    
    
    871  | 
     | 
     | 
    	ct = getset(name);  | 
    
    
    872  | 
     | 
     | 
    	if (ct == 0) { | 
    
    
    873  | 
     | 
     | 
    	    c = GETTOGGLE(name);  | 
    
    
    874  | 
     | 
     | 
    	    if (c == 0) { | 
    
    
    875  | 
     | 
     | 
    		fprintf(stderr, "'%s': unknown argument ('unset ?' for help).\r\n", | 
    
    
    876  | 
     | 
     | 
    			name);  | 
    
    
    877  | 
     | 
     | 
    		return 0;  | 
    
    
    878  | 
     | 
     | 
    	    } else if (Ambiguous(c)) { | 
    
    
    879  | 
     | 
     | 
    		fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\r\n", | 
    
    
    880  | 
     | 
     | 
    			name);  | 
    
    
    881  | 
     | 
     | 
    		return 0;  | 
    
    
    882  | 
     | 
     | 
    	    }  | 
    
    
    883  | 
     | 
     | 
    	    if (c->variable) { | 
    
    
    884  | 
     | 
     | 
    		*c->variable = 0;  | 
    
    
    885  | 
     | 
     | 
    		if (c->actionexplanation) { | 
    
    
    886  | 
     | 
     | 
    		    printf("%s %s.\r\n", *c->variable? "Will" : "Won't", | 
    
    
    887  | 
     | 
     | 
    							c->actionexplanation);  | 
    
    
    888  | 
     | 
     | 
    		}  | 
    
    
    889  | 
     | 
     | 
    	    }  | 
    
    
    890  | 
     | 
     | 
    	    if (c->handler)  | 
    
    
    891  | 
     | 
     | 
    		(*c->handler)(0);  | 
    
    
    892  | 
     | 
     | 
    	} else if (Ambiguous(ct)) { | 
    
    
    893  | 
     | 
     | 
    	    fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\r\n", | 
    
    
    894  | 
     | 
     | 
    			name);  | 
    
    
    895  | 
     | 
     | 
    	    return 0;  | 
    
    
    896  | 
     | 
     | 
    	} else if (ct->handler) { | 
    
    
    897  | 
     | 
     | 
    	    (*ct->handler)(NULL);  | 
    
    
    898  | 
     | 
     | 
    	    printf("%s reset to \"%s\".\r\n", ct->name, (char *)ct->charp); | 
    
    
    899  | 
     | 
     | 
    	} else { | 
    
    
    900  | 
     | 
     | 
    	    *(ct->charp) = _POSIX_VDISABLE;  | 
    
    
    901  | 
     | 
     | 
    	    printf("%s character is '%s'.\r\n", ct->name, control(*(ct->charp))); | 
    
    
    902  | 
     | 
     | 
    	}  | 
    
    
    903  | 
     | 
     | 
        }  | 
    
    
    904  | 
     | 
     | 
        return 1;  | 
    
    
    905  | 
     | 
     | 
    }  | 
    
    
    906  | 
     | 
     | 
     | 
    
    
    907  | 
     | 
     | 
    /*  | 
    
    
    908  | 
     | 
     | 
     * The following are the data structures and routines for the  | 
    
    
    909  | 
     | 
     | 
     * 'mode' command.  | 
    
    
    910  | 
     | 
     | 
     */  | 
    
    
    911  | 
     | 
     | 
    #ifdef	KLUDGELINEMODE  | 
    
    
    912  | 
     | 
     | 
    static int  | 
    
    
    913  | 
     | 
     | 
    dokludgemode(int unused)  | 
    
    
    914  | 
     | 
     | 
    { | 
    
    
    915  | 
     | 
     | 
        kludgelinemode = 1;  | 
    
    
    916  | 
     | 
     | 
        send_wont(TELOPT_LINEMODE, 1);  | 
    
    
    917  | 
     | 
     | 
        send_dont(TELOPT_SGA, 1);  | 
    
    
    918  | 
     | 
     | 
        send_dont(TELOPT_ECHO, 1);  | 
    
    
    919  | 
     | 
     | 
        return 1;  | 
    
    
    920  | 
     | 
     | 
    }  | 
    
    
    921  | 
     | 
     | 
    #endif  | 
    
    
    922  | 
     | 
     | 
     | 
    
    
    923  | 
     | 
     | 
    static int  | 
    
    
    924  | 
     | 
     | 
    dolinemode(int unused)  | 
    
    
    925  | 
     | 
     | 
    { | 
    
    
    926  | 
     | 
     | 
    #ifdef	KLUDGELINEMODE  | 
    
    
    927  | 
     | 
     | 
        if (kludgelinemode)  | 
    
    
    928  | 
     | 
     | 
    	send_dont(TELOPT_SGA, 1);  | 
    
    
    929  | 
     | 
     | 
    #endif  | 
    
    
    930  | 
     | 
     | 
        send_will(TELOPT_LINEMODE, 1);  | 
    
    
    931  | 
     | 
     | 
        send_dont(TELOPT_ECHO, 1);  | 
    
    
    932  | 
     | 
     | 
        return 1;  | 
    
    
    933  | 
     | 
     | 
    }  | 
    
    
    934  | 
     | 
     | 
     | 
    
    
    935  | 
     | 
     | 
    static int  | 
    
    
    936  | 
     | 
     | 
    docharmode(int unused)  | 
    
    
    937  | 
     | 
     | 
    { | 
    
    
    938  | 
     | 
     | 
    #ifdef	KLUDGELINEMODE  | 
    
    
    939  | 
     | 
     | 
        if (kludgelinemode)  | 
    
    
    940  | 
     | 
     | 
    	send_do(TELOPT_SGA, 1);  | 
    
    
    941  | 
     | 
     | 
        else  | 
    
    
    942  | 
     | 
     | 
    #endif  | 
    
    
    943  | 
     | 
     | 
        send_wont(TELOPT_LINEMODE, 1);  | 
    
    
    944  | 
     | 
     | 
        send_do(TELOPT_ECHO, 1);  | 
    
    
    945  | 
     | 
     | 
        return 1;  | 
    
    
    946  | 
     | 
     | 
    }  | 
    
    
    947  | 
     | 
     | 
     | 
    
    
    948  | 
     | 
     | 
    static int  | 
    
    
    949  | 
     | 
     | 
    dolmmode(int bit, int on)  | 
    
    
    950  | 
     | 
     | 
    { | 
    
    
    951  | 
     | 
     | 
        unsigned char c;  | 
    
    
    952  | 
     | 
     | 
     | 
    
    
    953  | 
     | 
     | 
        if (my_want_state_is_wont(TELOPT_LINEMODE)) { | 
    
    
    954  | 
     | 
     | 
    	printf("?Need to have LINEMODE option enabled first.\r\n"); | 
    
    
    955  | 
     | 
     | 
    	printf("'mode ?' for help.\r\n"); | 
    
    
    956  | 
     | 
     | 
    	return 0;  | 
    
    
    957  | 
     | 
     | 
        }  | 
    
    
    958  | 
     | 
     | 
     | 
    
    
    959  | 
     | 
     | 
        if (on)  | 
    
    
    960  | 
     | 
     | 
    	c = (linemode | bit);  | 
    
    
    961  | 
     | 
     | 
        else  | 
    
    
    962  | 
     | 
     | 
    	c = (linemode & ~bit);  | 
    
    
    963  | 
     | 
     | 
        lm_mode(&c, 1, 1);  | 
    
    
    964  | 
     | 
     | 
        return 1;  | 
    
    
    965  | 
     | 
     | 
    }  | 
    
    
    966  | 
     | 
     | 
     | 
    
    
    967  | 
     | 
     | 
    int  | 
    
    
    968  | 
     | 
     | 
    tn_setmode(int bit)  | 
    
    
    969  | 
     | 
     | 
    { | 
    
    
    970  | 
     | 
     | 
        return dolmmode(bit, 1);  | 
    
    
    971  | 
     | 
     | 
    }  | 
    
    
    972  | 
     | 
     | 
     | 
    
    
    973  | 
     | 
     | 
    int  | 
    
    
    974  | 
     | 
     | 
    tn_clearmode(int bit)  | 
    
    
    975  | 
     | 
     | 
    { | 
    
    
    976  | 
     | 
     | 
        return dolmmode(bit, 0);  | 
    
    
    977  | 
     | 
     | 
    }  | 
    
    
    978  | 
     | 
     | 
     | 
    
    
    979  | 
     | 
     | 
    struct modelist { | 
    
    
    980  | 
     | 
     | 
    	char	*name;		/* command name */  | 
    
    
    981  | 
     | 
     | 
    	char	*help;		/* help string */  | 
    
    
    982  | 
     | 
     | 
    	int	(*handler)(int);/* routine which executes command */  | 
    
    
    983  | 
     | 
     | 
    	int	needconnect;	/* Do we need to be connected to execute? */  | 
    
    
    984  | 
     | 
     | 
    	int	arg1;  | 
    
    
    985  | 
     | 
     | 
    };  | 
    
    
    986  | 
     | 
     | 
     | 
    
    
    987  | 
     | 
     | 
    static int modehelp(int);  | 
    
    
    988  | 
     | 
     | 
     | 
    
    
    989  | 
     | 
     | 
    static struct modelist ModeList[] = { | 
    
    
    990  | 
     | 
     | 
        { "character", "Disable LINEMODE option",	docharmode, 1 }, | 
    
    
    991  | 
     | 
     | 
    #ifdef	KLUDGELINEMODE  | 
    
    
    992  | 
     | 
     | 
        { "",	"(or disable obsolete line-by-line mode)", 0 }, | 
    
    
    993  | 
     | 
     | 
    #endif  | 
    
    
    994  | 
     | 
     | 
        { "line",	"Enable LINEMODE option",	dolinemode, 1 }, | 
    
    
    995  | 
     | 
     | 
    #ifdef	KLUDGELINEMODE  | 
    
    
    996  | 
     | 
     | 
        { "",	"(or enable obsolete line-by-line mode)", 0 }, | 
    
    
    997  | 
     | 
     | 
    #endif  | 
    
    
    998  | 
     | 
     | 
        { "", "", 0 }, | 
    
    
    999  | 
     | 
     | 
        { "",	"These require the LINEMODE option to be enabled", 0 }, | 
    
    
    1000  | 
     | 
     | 
        { "isig",	"Enable signal trapping",	tn_setmode, 1, MODE_TRAPSIG }, | 
    
    
    1001  | 
     | 
     | 
        { "+isig",	0,				tn_setmode, 1, MODE_TRAPSIG }, | 
    
    
    1002  | 
     | 
     | 
        { "-isig",	"Disable signal trapping",	tn_clearmode, 1, MODE_TRAPSIG }, | 
    
    
    1003  | 
     | 
     | 
        { "edit",	"Enable character editing",	tn_setmode, 1, MODE_EDIT }, | 
    
    
    1004  | 
     | 
     | 
        { "+edit",	0,				tn_setmode, 1, MODE_EDIT }, | 
    
    
    1005  | 
     | 
     | 
        { "-edit",	"Disable character editing",	tn_clearmode, 1, MODE_EDIT }, | 
    
    
    1006  | 
     | 
     | 
        { "softtabs", "Enable tab expansion",	tn_setmode, 1, MODE_SOFT_TAB }, | 
    
    
    1007  | 
     | 
     | 
        { "+softtabs", 0,				tn_setmode, 1, MODE_SOFT_TAB }, | 
    
    
    1008  | 
     | 
     | 
        { "-softtabs", "Disable character editing",	tn_clearmode, 1, MODE_SOFT_TAB }, | 
    
    
    1009  | 
     | 
     | 
        { "litecho", "Enable literal character echo", tn_setmode, 1, MODE_LIT_ECHO }, | 
    
    
    1010  | 
     | 
     | 
        { "+litecho", 0,				tn_setmode, 1, MODE_LIT_ECHO }, | 
    
    
    1011  | 
     | 
     | 
        { "-litecho", "Disable literal character echo", tn_clearmode, 1, MODE_LIT_ECHO }, | 
    
    
    1012  | 
     | 
     | 
        { "help",	0,				modehelp, 0 }, | 
    
    
    1013  | 
     | 
     | 
    #ifdef	KLUDGELINEMODE  | 
    
    
    1014  | 
     | 
     | 
        { "kludgeline", 0,				dokludgemode, 1 }, | 
    
    
    1015  | 
     | 
     | 
    #endif  | 
    
    
    1016  | 
     | 
     | 
        { "", "", 0 }, | 
    
    
    1017  | 
     | 
     | 
        { "?",	"Print help information",	modehelp, 0 }, | 
    
    
    1018  | 
     | 
     | 
        { 0 }, | 
    
    
    1019  | 
     | 
     | 
    };  | 
    
    
    1020  | 
     | 
     | 
     | 
    
    
    1021  | 
     | 
     | 
    static int  | 
    
    
    1022  | 
     | 
     | 
    modehelp(int unused)  | 
    
    
    1023  | 
     | 
     | 
    { | 
    
    
    1024  | 
     | 
     | 
        struct modelist *mt;  | 
    
    
    1025  | 
     | 
     | 
     | 
    
    
    1026  | 
     | 
     | 
        printf("format is:  'mode Mode', where 'Mode' is one of:\r\n\r\n"); | 
    
    
    1027  | 
     | 
     | 
        for (mt = ModeList; mt->name; mt++) { | 
    
    
    1028  | 
     | 
     | 
    	if (mt->help) { | 
    
    
    1029  | 
     | 
     | 
    	    if (*mt->help)  | 
    
    
    1030  | 
     | 
     | 
    		printf("%-15s %s\r\n", mt->name, mt->help); | 
    
    
    1031  | 
     | 
     | 
    	    else  | 
    
    
    1032  | 
     | 
     | 
    		printf("\r\n"); | 
    
    
    1033  | 
     | 
     | 
    	}  | 
    
    
    1034  | 
     | 
     | 
        }  | 
    
    
    1035  | 
     | 
     | 
        return 0;  | 
    
    
    1036  | 
     | 
     | 
    }  | 
    
    
    1037  | 
     | 
     | 
     | 
    
    
    1038  | 
     | 
     | 
    #define	GETMODECMD(name) (struct modelist *) \  | 
    
    
    1039  | 
     | 
     | 
    		genget(name, (char **) ModeList, sizeof(struct modelist))  | 
    
    
    1040  | 
     | 
     | 
     | 
    
    
    1041  | 
     | 
     | 
    static int  | 
    
    
    1042  | 
     | 
     | 
    modecmd(int argc, char *argv[])  | 
    
    
    1043  | 
     | 
     | 
    { | 
    
    
    1044  | 
     | 
     | 
        struct modelist *mt;  | 
    
    
    1045  | 
     | 
     | 
     | 
    
    
    1046  | 
     | 
     | 
        if (argc != 2) { | 
    
    
    1047  | 
     | 
     | 
    	printf("'mode' command requires an argument\r\n"); | 
    
    
    1048  | 
     | 
     | 
    	printf("'mode ?' for help.\r\n"); | 
    
    
    1049  | 
     | 
     | 
        } else if ((mt = GETMODECMD(argv[1])) == 0) { | 
    
    
    1050  | 
     | 
     | 
    	fprintf(stderr, "Unknown mode '%s' ('mode ?' for help).\r\n", argv[1]); | 
    
    
    1051  | 
     | 
     | 
        } else if (Ambiguous(mt)) { | 
    
    
    1052  | 
     | 
     | 
    	fprintf(stderr, "Ambiguous mode '%s' ('mode ?' for help).\r\n", argv[1]); | 
    
    
    1053  | 
     | 
     | 
        } else if (mt->needconnect && !connected) { | 
    
    
    1054  | 
     | 
     | 
    	printf("?Need to be connected first.\r\n"); | 
    
    
    1055  | 
     | 
     | 
    	printf("'mode ?' for help.\r\n"); | 
    
    
    1056  | 
     | 
     | 
        } else if (mt->handler) { | 
    
    
    1057  | 
     | 
     | 
    	return (*mt->handler)(mt->arg1);  | 
    
    
    1058  | 
     | 
     | 
        }  | 
    
    
    1059  | 
     | 
     | 
        return 0;  | 
    
    
    1060  | 
     | 
     | 
    }  | 
    
    
    1061  | 
     | 
     | 
     | 
    
    
    1062  | 
     | 
     | 
    /*  | 
    
    
    1063  | 
     | 
     | 
     * The following data structures and routines implement the  | 
    
    
    1064  | 
     | 
     | 
     * "display" command.  | 
    
    
    1065  | 
     | 
     | 
     */  | 
    
    
    1066  | 
     | 
     | 
     | 
    
    
    1067  | 
     | 
     | 
    static int  | 
    
    
    1068  | 
     | 
     | 
    display(int argc, char *argv[])  | 
    
    
    1069  | 
     | 
     | 
    { | 
    
    
    1070  | 
     | 
     | 
        struct togglelist *tl;  | 
    
    
    1071  | 
     | 
     | 
        struct setlist *sl;  | 
    
    
    1072  | 
     | 
     | 
     | 
    
    
    1073  | 
     | 
     | 
    #define	dotog(tl)	if (tl->variable && tl->actionexplanation) { \ | 
    
    
    1074  | 
     | 
     | 
    			    if (*tl->variable) { \ | 
    
    
    1075  | 
     | 
     | 
    				printf("will"); \ | 
    
    
    1076  | 
     | 
     | 
    			    } else { \ | 
    
    
    1077  | 
     | 
     | 
    				printf("won't"); \ | 
    
    
    1078  | 
     | 
     | 
    			    } \  | 
    
    
    1079  | 
     | 
     | 
    			    printf(" %s.\r\n", tl->actionexplanation); \ | 
    
    
    1080  | 
     | 
     | 
    			}  | 
    
    
    1081  | 
     | 
     | 
     | 
    
    
    1082  | 
     | 
     | 
    #define	doset(sl)   if (sl->name && *sl->name != ' ') { \ | 
    
    
    1083  | 
     | 
     | 
    			if (sl->handler == 0) \  | 
    
    
    1084  | 
     | 
     | 
    			    printf("%-15s [%s]\r\n", sl->name, control(*sl->charp)); \ | 
    
    
    1085  | 
     | 
     | 
    			else \  | 
    
    
    1086  | 
     | 
     | 
    			    printf("%-15s \"%s\"\r\n", sl->name, (char *)sl->charp); \ | 
    
    
    1087  | 
     | 
     | 
    		    }  | 
    
    
    1088  | 
     | 
     | 
     | 
    
    
    1089  | 
     | 
     | 
        if (argc == 1) { | 
    
    
    1090  | 
     | 
     | 
    	for (tl = Togglelist; tl->name; tl++) { | 
    
    
    1091  | 
     | 
     | 
    	    dotog(tl);  | 
    
    
    1092  | 
     | 
     | 
    	}  | 
    
    
    1093  | 
     | 
     | 
    	printf("\r\n"); | 
    
    
    1094  | 
     | 
     | 
    	for (sl = Setlist; sl->name; sl++) { | 
    
    
    1095  | 
     | 
     | 
    	    doset(sl);  | 
    
    
    1096  | 
     | 
     | 
    	}  | 
    
    
    1097  | 
     | 
     | 
        } else { | 
    
    
    1098  | 
     | 
     | 
    	int i;  | 
    
    
    1099  | 
     | 
     | 
     | 
    
    
    1100  | 
     | 
     | 
    	for (i = 1; i < argc; i++) { | 
    
    
    1101  | 
     | 
     | 
    	    sl = getset(argv[i]);  | 
    
    
    1102  | 
     | 
     | 
    	    tl = GETTOGGLE(argv[i]);  | 
    
    
    1103  | 
     | 
     | 
    	    if (Ambiguous(sl) || Ambiguous(tl)) { | 
    
    
    1104  | 
     | 
     | 
    		printf("?Ambiguous argument '%s'.\r\n", argv[i]); | 
    
    
    1105  | 
     | 
     | 
    		return 0;  | 
    
    
    1106  | 
     | 
     | 
    	    } else if (!sl && !tl) { | 
    
    
    1107  | 
     | 
     | 
    		printf("?Unknown argument '%s'.\r\n", argv[i]); | 
    
    
    1108  | 
     | 
     | 
    		return 0;  | 
    
    
    1109  | 
     | 
     | 
    	    } else { | 
    
    
    1110  | 
     | 
     | 
    		if (tl) { | 
    
    
    1111  | 
     | 
     | 
    		    dotog(tl);  | 
    
    
    1112  | 
     | 
     | 
    		}  | 
    
    
    1113  | 
     | 
     | 
    		if (sl) { | 
    
    
    1114  | 
     | 
     | 
    		    doset(sl);  | 
    
    
    1115  | 
     | 
     | 
    		}  | 
    
    
    1116  | 
     | 
     | 
    	    }  | 
    
    
    1117  | 
     | 
     | 
    	}  | 
    
    
    1118  | 
     | 
     | 
        }  | 
    
    
    1119  | 
     | 
     | 
    /*@*/optionstatus();  | 
    
    
    1120  | 
     | 
     | 
        return 1;  | 
    
    
    1121  | 
     | 
     | 
    #undef	doset  | 
    
    
    1122  | 
     | 
     | 
    #undef	dotog  | 
    
    
    1123  | 
     | 
     | 
    }  | 
    
    
    1124  | 
     | 
     | 
     | 
    
    
    1125  | 
     | 
     | 
    /*  | 
    
    
    1126  | 
     | 
     | 
     * The following are the data structures, and many of the routines,  | 
    
    
    1127  | 
     | 
     | 
     * relating to command processing.  | 
    
    
    1128  | 
     | 
     | 
     */  | 
    
    
    1129  | 
     | 
     | 
     | 
    
    
    1130  | 
     | 
     | 
    /*  | 
    
    
    1131  | 
     | 
     | 
     * Set the escape character.  | 
    
    
    1132  | 
     | 
     | 
     */  | 
    
    
    1133  | 
     | 
     | 
    static int  | 
    
    
    1134  | 
     | 
     | 
    setescape(int argc, char *argv[])  | 
    
    
    1135  | 
     | 
     | 
    { | 
    
    
    1136  | 
     | 
     | 
    	char *arg;  | 
    
    
    1137  | 
     | 
     | 
    	char buf[50];  | 
    
    
    1138  | 
     | 
     | 
     | 
    
    
    1139  | 
     | 
     | 
    	printf(  | 
    
    
    1140  | 
     | 
     | 
    	    "Deprecated usage - please use 'set escape%s%s' in the future.\r\n",  | 
    
    
    1141  | 
     | 
     | 
    				(argc > 2)? " ":"", (argc > 2)? argv[1]: "");  | 
    
    
    1142  | 
     | 
     | 
    	if (argc > 2)  | 
    
    
    1143  | 
     | 
     | 
    		arg = argv[1];  | 
    
    
    1144  | 
     | 
     | 
    	else { | 
    
    
    1145  | 
     | 
     | 
    		printf("new escape character: "); | 
    
    
    1146  | 
     | 
     | 
    		(void) fgets(buf, sizeof(buf), stdin);  | 
    
    
    1147  | 
     | 
     | 
    		arg = buf;  | 
    
    
    1148  | 
     | 
     | 
    	}  | 
    
    
    1149  | 
     | 
     | 
    	if (arg[0] != '\0')  | 
    
    
    1150  | 
     | 
     | 
    		escape = arg[0];  | 
    
    
    1151  | 
     | 
     | 
    	printf("Escape character is '%s'.\r\n", control(escape)); | 
    
    
    1152  | 
     | 
     | 
    	(void) fflush(stdout);  | 
    
    
    1153  | 
     | 
     | 
    	return 1;  | 
    
    
    1154  | 
     | 
     | 
    }  | 
    
    
    1155  | 
     | 
     | 
     | 
    
    
    1156  | 
     | 
     | 
    static int  | 
    
    
    1157  | 
     | 
     | 
    togcrmod(int unused1, char *unused2[])  | 
    
    
    1158  | 
     | 
     | 
    { | 
    
    
    1159  | 
     | 
     | 
        crmod = !crmod;  | 
    
    
    1160  | 
     | 
     | 
        printf("Deprecated usage - please use 'toggle crmod' in the future.\r\n"); | 
    
    
    1161  | 
     | 
     | 
        printf("%s map carriage return on output.\r\n", crmod ? "Will" : "Won't"); | 
    
    
    1162  | 
     | 
     | 
        (void) fflush(stdout);  | 
    
    
    1163  | 
     | 
     | 
        return 1;  | 
    
    
    1164  | 
     | 
     | 
    }  | 
    
    
    1165  | 
     | 
     | 
     | 
    
    
    1166  | 
     | 
     | 
    int  | 
    
    
    1167  | 
     | 
     | 
    telnetsuspend(int unused1, char *unused2[])  | 
    
    
    1168  | 
     | 
     | 
    { | 
    
    
    1169  | 
     | 
     | 
        setcommandmode();  | 
    
    
    1170  | 
     | 
     | 
        { | 
    
    
    1171  | 
     | 
     | 
    	long oldrows, oldcols, newrows, newcols, err;  | 
    
    
    1172  | 
     | 
     | 
     | 
    
    
    1173  | 
     | 
     | 
    	err = (TerminalWindowSize(&oldrows, &oldcols) == 0) ? 1 : 0;  | 
    
    
    1174  | 
     | 
     | 
    	(void) kill(0, SIGTSTP);  | 
    
    
    1175  | 
     | 
     | 
    	/*  | 
    
    
    1176  | 
     | 
     | 
    	 * If we didn't get the window size before the SUSPEND, but we  | 
    
    
    1177  | 
     | 
     | 
    	 * can get them now (?), then send the NAWS to make sure that  | 
    
    
    1178  | 
     | 
     | 
    	 * we are set up for the right window size.  | 
    
    
    1179  | 
     | 
     | 
    	 */  | 
    
    
    1180  | 
     | 
     | 
    	if (TerminalWindowSize(&newrows, &newcols) && connected &&  | 
    
    
    1181  | 
     | 
     | 
    	    (err || ((oldrows != newrows) || (oldcols != newcols)))) { | 
    
    
    1182  | 
     | 
     | 
    		sendnaws();  | 
    
    
    1183  | 
     | 
     | 
    	}  | 
    
    
    1184  | 
     | 
     | 
        }  | 
    
    
    1185  | 
     | 
     | 
        /* reget parameters in case they were changed */  | 
    
    
    1186  | 
     | 
     | 
        TerminalSaveState();  | 
    
    
    1187  | 
     | 
     | 
        setconnmode(0);  | 
    
    
    1188  | 
     | 
     | 
        return 1;  | 
    
    
    1189  | 
     | 
     | 
    }  | 
    
    
    1190  | 
     | 
     | 
     | 
    
    
    1191  | 
     | 
     | 
    static void  | 
    
    
    1192  | 
     | 
     | 
    close_connection(void)  | 
    
    
    1193  | 
     | 
     | 
    { | 
    
    
    1194  | 
     | 
     | 
    	if (connected) { | 
    
    
    1195  | 
     | 
     | 
    		(void) shutdown(net, SHUT_RDWR);  | 
    
    
    1196  | 
     | 
     | 
    		printf("Connection closed.\r\n"); | 
    
    
    1197  | 
     | 
     | 
    		(void)close(net);  | 
    
    
    1198  | 
     | 
     | 
    		connected = 0;  | 
    
    
    1199  | 
     | 
     | 
    		resettermname = 1;  | 
    
    
    1200  | 
     | 
     | 
    		/* reset options */  | 
    
    
    1201  | 
     | 
     | 
    		tninit();  | 
    
    
    1202  | 
     | 
     | 
    	}  | 
    
    
    1203  | 
     | 
     | 
    }  | 
    
    
    1204  | 
     | 
     | 
     | 
    
    
    1205  | 
     | 
     | 
    static int  | 
    
    
    1206  | 
     | 
     | 
    bye(int argc, char *argv[])  | 
    
    
    1207  | 
     | 
     | 
    { | 
    
    
    1208  | 
     | 
     | 
    	close_connection();  | 
    
    
    1209  | 
     | 
     | 
    	longjmp(toplevel, 1);  | 
    
    
    1210  | 
     | 
     | 
    }  | 
    
    
    1211  | 
     | 
     | 
     | 
    
    
    1212  | 
     | 
     | 
    void  | 
    
    
    1213  | 
     | 
     | 
    quit(void)  | 
    
    
    1214  | 
     | 
     | 
    { | 
    
    
    1215  | 
     | 
     | 
    	close_connection();  | 
    
    
    1216  | 
     | 
     | 
    	Exit(0);  | 
    
    
    1217  | 
     | 
     | 
    }  | 
    
    
    1218  | 
     | 
     | 
     | 
    
    
    1219  | 
     | 
     | 
    static int  | 
    
    
    1220  | 
     | 
     | 
    quitcmd(int unused1, char *unused2[])  | 
    
    
    1221  | 
     | 
     | 
    { | 
    
    
    1222  | 
     | 
     | 
    	quit();  | 
    
    
    1223  | 
     | 
     | 
    }  | 
    
    
    1224  | 
     | 
     | 
     | 
    
    
    1225  | 
     | 
     | 
    static int  | 
    
    
    1226  | 
     | 
     | 
    logout(int unused1, char *unused2[])  | 
    
    
    1227  | 
     | 
     | 
    { | 
    
    
    1228  | 
     | 
     | 
    	send_do(TELOPT_LOGOUT, 1);  | 
    
    
    1229  | 
     | 
     | 
    	(void) netflush();  | 
    
    
    1230  | 
     | 
     | 
    	return 1;  | 
    
    
    1231  | 
     | 
     | 
    }  | 
    
    
    1232  | 
     | 
     | 
     | 
    
    
    1233  | 
     | 
     | 
     | 
    
    
    1234  | 
     | 
     | 
    /*  | 
    
    
    1235  | 
     | 
     | 
     * The SLC command.  | 
    
    
    1236  | 
     | 
     | 
     */  | 
    
    
    1237  | 
     | 
     | 
     | 
    
    
    1238  | 
     | 
     | 
    struct slclist { | 
    
    
    1239  | 
     | 
     | 
    	char	*name;  | 
    
    
    1240  | 
     | 
     | 
    	char	*help;  | 
    
    
    1241  | 
     | 
     | 
    	void	(*handler)(int);  | 
    
    
    1242  | 
     | 
     | 
    	int	arg;  | 
    
    
    1243  | 
     | 
     | 
    };  | 
    
    
    1244  | 
     | 
     | 
     | 
    
    
    1245  | 
     | 
     | 
    static void slc_help(int);  | 
    
    
    1246  | 
     | 
     | 
     | 
    
    
    1247  | 
     | 
     | 
    struct slclist SlcList[] = { | 
    
    
    1248  | 
     | 
     | 
        { "export",	"Use local special character definitions", | 
    
    
    1249  | 
     | 
     | 
    						slc_mode_export,	0 },  | 
    
    
    1250  | 
     | 
     | 
        { "import",	"Use remote special character definitions", | 
    
    
    1251  | 
     | 
     | 
    						slc_mode_import,	1 },  | 
    
    
    1252  | 
     | 
     | 
        { "check",	"Verify remote special character definitions", | 
    
    
    1253  | 
     | 
     | 
    						slc_mode_import,	0 },  | 
    
    
    1254  | 
     | 
     | 
        { "help",	0,				slc_help,		0 }, | 
    
    
    1255  | 
     | 
     | 
        { "?",	"Print help information",	slc_help,		0 }, | 
    
    
    1256  | 
     | 
     | 
        { 0 }, | 
    
    
    1257  | 
     | 
     | 
    };  | 
    
    
    1258  | 
     | 
     | 
     | 
    
    
    1259  | 
     | 
     | 
    static void  | 
    
    
    1260  | 
     | 
     | 
    slc_help(int unused)  | 
    
    
    1261  | 
     | 
     | 
    { | 
    
    
    1262  | 
     | 
     | 
        struct slclist *c;  | 
    
    
    1263  | 
     | 
     | 
     | 
    
    
    1264  | 
     | 
     | 
        for (c = SlcList; c->name; c++) { | 
    
    
    1265  | 
     | 
     | 
    	if (c->help) { | 
    
    
    1266  | 
     | 
     | 
    	    if (*c->help)  | 
    
    
    1267  | 
     | 
     | 
    		printf("%-15s %s\r\n", c->name, c->help); | 
    
    
    1268  | 
     | 
     | 
    	    else  | 
    
    
    1269  | 
     | 
     | 
    		printf("\r\n"); | 
    
    
    1270  | 
     | 
     | 
    	}  | 
    
    
    1271  | 
     | 
     | 
        }  | 
    
    
    1272  | 
     | 
     | 
    }  | 
    
    
    1273  | 
     | 
     | 
     | 
    
    
    1274  | 
     | 
     | 
    static struct slclist *  | 
    
    
    1275  | 
     | 
     | 
    getslc(char *name)  | 
    
    
    1276  | 
     | 
     | 
    { | 
    
    
    1277  | 
     | 
     | 
        return (struct slclist *)  | 
    
    
    1278  | 
     | 
     | 
    		genget(name, (char **) SlcList, sizeof(struct slclist));  | 
    
    
    1279  | 
     | 
     | 
    }  | 
    
    
    1280  | 
     | 
     | 
     | 
    
    
    1281  | 
     | 
     | 
    static int  | 
    
    
    1282  | 
     | 
     | 
    slccmd(int argc, char *argv[])  | 
    
    
    1283  | 
     | 
     | 
    { | 
    
    
    1284  | 
     | 
     | 
        struct slclist *c;  | 
    
    
    1285  | 
     | 
     | 
     | 
    
    
    1286  | 
     | 
     | 
        if (argc != 2) { | 
    
    
    1287  | 
     | 
     | 
    	fprintf(stderr,  | 
    
    
    1288  | 
     | 
     | 
    	    "Need an argument to 'slc' command.  'slc ?' for help.\r\n");  | 
    
    
    1289  | 
     | 
     | 
    	return 0;  | 
    
    
    1290  | 
     | 
     | 
        }  | 
    
    
    1291  | 
     | 
     | 
        c = getslc(argv[1]);  | 
    
    
    1292  | 
     | 
     | 
        if (c == 0) { | 
    
    
    1293  | 
     | 
     | 
    	fprintf(stderr, "'%s': unknown argument ('slc ?' for help).\r\n", | 
    
    
    1294  | 
     | 
     | 
        				argv[1]);  | 
    
    
    1295  | 
     | 
     | 
    	return 0;  | 
    
    
    1296  | 
     | 
     | 
        }  | 
    
    
    1297  | 
     | 
     | 
        if (Ambiguous(c)) { | 
    
    
    1298  | 
     | 
     | 
    	fprintf(stderr, "'%s': ambiguous argument ('slc ?' for help).\r\n", | 
    
    
    1299  | 
     | 
     | 
        				argv[1]);  | 
    
    
    1300  | 
     | 
     | 
    	return 0;  | 
    
    
    1301  | 
     | 
     | 
        }  | 
    
    
    1302  | 
     | 
     | 
        (*c->handler)(c->arg);  | 
    
    
    1303  | 
     | 
     | 
        slcstate();  | 
    
    
    1304  | 
     | 
     | 
        return 1;  | 
    
    
    1305  | 
     | 
     | 
    }  | 
    
    
    1306  | 
     | 
     | 
     | 
    
    
    1307  | 
     | 
     | 
    /*  | 
    
    
    1308  | 
     | 
     | 
     * The ENVIRON command.  | 
    
    
    1309  | 
     | 
     | 
     */  | 
    
    
    1310  | 
     | 
     | 
     | 
    
    
    1311  | 
     | 
     | 
    struct envlist { | 
    
    
    1312  | 
     | 
     | 
    	char	*name;  | 
    
    
    1313  | 
     | 
     | 
    	char	*help;  | 
    
    
    1314  | 
     | 
     | 
    	void	(*handler)();  | 
    
    
    1315  | 
     | 
     | 
    	int	narg;  | 
    
    
    1316  | 
     | 
     | 
    };  | 
    
    
    1317  | 
     | 
     | 
     | 
    
    
    1318  | 
     | 
     | 
    static void	env_help(void);  | 
    
    
    1319  | 
     | 
     | 
    static void	env_undefine(const char *);  | 
    
    
    1320  | 
     | 
     | 
    static void	env_export(const char *);  | 
    
    
    1321  | 
     | 
     | 
    static void	env_unexport(const char *);  | 
    
    
    1322  | 
     | 
     | 
    static void	env_send(const char *);  | 
    
    
    1323  | 
     | 
     | 
    static void	env_list(void);  | 
    
    
    1324  | 
     | 
     | 
    static struct env_lst *env_find(const char *var);  | 
    
    
    1325  | 
     | 
     | 
     | 
    
    
    1326  | 
     | 
     | 
    struct envlist EnvList[] = { | 
    
    
    1327  | 
     | 
     | 
        { "define",	"Define an environment variable", | 
    
    
    1328  | 
     | 
     | 
    						(void (*)())env_define,	2 },  | 
    
    
    1329  | 
     | 
     | 
        { "undefine", "Undefine an environment variable", | 
    
    
    1330  | 
     | 
     | 
    						env_undefine,	1 },  | 
    
    
    1331  | 
     | 
     | 
        { "export",	"Mark an environment variable for automatic export", | 
    
    
    1332  | 
     | 
     | 
    						env_export,	1 },  | 
    
    
    1333  | 
     | 
     | 
        { "unexport", "Don't mark an environment variable for automatic export", | 
    
    
    1334  | 
     | 
     | 
    						env_unexport,	1 },  | 
    
    
    1335  | 
     | 
     | 
        { "send",	"Send an environment variable", env_send,	1 }, | 
    
    
    1336  | 
     | 
     | 
        { "list",	"List the current environment variables", | 
    
    
    1337  | 
     | 
     | 
    						env_list,	0 },  | 
    
    
    1338  | 
     | 
     | 
        { "help",	0,				env_help,		0 }, | 
    
    
    1339  | 
     | 
     | 
        { "?",	"Print help information",	env_help,		0 }, | 
    
    
    1340  | 
     | 
     | 
        { 0 }, | 
    
    
    1341  | 
     | 
     | 
    };  | 
    
    
    1342  | 
     | 
     | 
     | 
    
    
    1343  | 
     | 
     | 
    static void  | 
    
    
    1344  | 
     | 
     | 
    env_help(void)  | 
    
    
    1345  | 
     | 
     | 
    { | 
    
    
    1346  | 
     | 
     | 
        struct envlist *c;  | 
    
    
    1347  | 
     | 
     | 
     | 
    
    
    1348  | 
     | 
     | 
        for (c = EnvList; c->name; c++) { | 
    
    
    1349  | 
     | 
     | 
    	if (c->help) { | 
    
    
    1350  | 
     | 
     | 
    	    if (*c->help)  | 
    
    
    1351  | 
     | 
     | 
    		printf("%-15s %s\r\n", c->name, c->help); | 
    
    
    1352  | 
     | 
     | 
    	    else  | 
    
    
    1353  | 
     | 
     | 
    		printf("\r\n"); | 
    
    
    1354  | 
     | 
     | 
    	}  | 
    
    
    1355  | 
     | 
     | 
        }  | 
    
    
    1356  | 
     | 
     | 
    }  | 
    
    
    1357  | 
     | 
     | 
     | 
    
    
    1358  | 
     | 
     | 
    static struct envlist *  | 
    
    
    1359  | 
     | 
     | 
    getenvcmd(char *name)  | 
    
    
    1360  | 
     | 
     | 
    { | 
    
    
    1361  | 
     | 
     | 
        return (struct envlist *)  | 
    
    
    1362  | 
     | 
     | 
    		genget(name, (char **) EnvList, sizeof(struct envlist));  | 
    
    
    1363  | 
     | 
     | 
    }  | 
    
    
    1364  | 
     | 
     | 
     | 
    
    
    1365  | 
     | 
     | 
    static int  | 
    
    
    1366  | 
     | 
     | 
    env_cmd(int argc, char *argv[])  | 
    
    
    1367  | 
     | 
     | 
    { | 
    
    
    1368  | 
     | 
     | 
        struct envlist *c;  | 
    
    
    1369  | 
     | 
     | 
     | 
    
    
    1370  | 
     | 
     | 
        if (argc < 2) { | 
    
    
    1371  | 
     | 
     | 
    	fprintf(stderr,  | 
    
    
    1372  | 
     | 
     | 
    	    "Need an argument to 'environ' command.  'environ ?' for help.\r\n");  | 
    
    
    1373  | 
     | 
     | 
    	return 0;  | 
    
    
    1374  | 
     | 
     | 
        }  | 
    
    
    1375  | 
     | 
     | 
        c = getenvcmd(argv[1]);  | 
    
    
    1376  | 
     | 
     | 
        if (c == 0) { | 
    
    
    1377  | 
     | 
     | 
    	fprintf(stderr, "'%s': unknown argument ('environ ?' for help).\r\n", | 
    
    
    1378  | 
     | 
     | 
        				argv[1]);  | 
    
    
    1379  | 
     | 
     | 
    	return 0;  | 
    
    
    1380  | 
     | 
     | 
        }  | 
    
    
    1381  | 
     | 
     | 
        if (Ambiguous(c)) { | 
    
    
    1382  | 
     | 
     | 
    	fprintf(stderr, "'%s': ambiguous argument ('environ ?' for help).\r\n", | 
    
    
    1383  | 
     | 
     | 
        				argv[1]);  | 
    
    
    1384  | 
     | 
     | 
    	return 0;  | 
    
    
    1385  | 
     | 
     | 
        }  | 
    
    
    1386  | 
     | 
     | 
        if (c->narg + 2 != argc) { | 
    
    
    1387  | 
     | 
     | 
    	fprintf(stderr,  | 
    
    
    1388  | 
     | 
     | 
    	    "Need %s%d argument%s to 'environ %s' command.  'environ ?' for help.\r\n",  | 
    
    
    1389  | 
     | 
     | 
    		c->narg < argc + 2 ? "only " : "",  | 
    
    
    1390  | 
     | 
     | 
    		c->narg, c->narg == 1 ? "" : "s", c->name);  | 
    
    
    1391  | 
     | 
     | 
    	return 0;  | 
    
    
    1392  | 
     | 
     | 
        }  | 
    
    
    1393  | 
     | 
     | 
        (*c->handler)(argv[2], argv[3]);  | 
    
    
    1394  | 
     | 
     | 
        return 1;  | 
    
    
    1395  | 
     | 
     | 
    }  | 
    
    
    1396  | 
     | 
     | 
     | 
    
    
    1397  | 
     | 
     | 
    struct env_lst { | 
    
    
    1398  | 
     | 
     | 
    	struct env_lst *next;	/* pointer to next structure */  | 
    
    
    1399  | 
     | 
     | 
    	struct env_lst *prev;	/* pointer to previous structure */  | 
    
    
    1400  | 
     | 
     | 
    	char *var;		/* pointer to variable name */  | 
    
    
    1401  | 
     | 
     | 
    	char *value;		/* pointer to variable value */  | 
    
    
    1402  | 
     | 
     | 
    	int export;		/* 1 -> export with default list of variables */  | 
    
    
    1403  | 
     | 
     | 
    	int welldefined;	/* A well defined variable */  | 
    
    
    1404  | 
     | 
     | 
    };  | 
    
    
    1405  | 
     | 
     | 
     | 
    
    
    1406  | 
     | 
     | 
    struct env_lst envlisthead;  | 
    
    
    1407  | 
     | 
     | 
     | 
    
    
    1408  | 
     | 
     | 
    static struct env_lst *  | 
    
    
    1409  | 
     | 
     | 
    env_find(const char *var)  | 
    
    
    1410  | 
     | 
     | 
    { | 
    
    
    1411  | 
     | 
     | 
    	struct env_lst *ep;  | 
    
    
    1412  | 
     | 
     | 
     | 
    
    
    1413  | 
     | 
     | 
    	for (ep = envlisthead.next; ep; ep = ep->next) { | 
    
    
    1414  | 
     | 
     | 
    		if (strcmp(ep->var, var) == 0)  | 
    
    
    1415  | 
     | 
     | 
    			return(ep);  | 
    
    
    1416  | 
     | 
     | 
    	}  | 
    
    
    1417  | 
     | 
     | 
    	return(NULL);  | 
    
    
    1418  | 
     | 
     | 
    }  | 
    
    
    1419  | 
     | 
     | 
     | 
    
    
    1420  | 
     | 
     | 
    void  | 
    
    
    1421  | 
     | 
     | 
    env_init(void)  | 
    
    
    1422  | 
     | 
     | 
    { | 
    
    
    1423  | 
     | 
     | 
    	extern char **environ;  | 
    
    
    1424  | 
     | 
     | 
    	char **epp, *cp;  | 
    
    
    1425  | 
     | 
     | 
    	struct env_lst *ep;  | 
    
    
    1426  | 
     | 
     | 
     | 
    
    
    1427  | 
     | 
     | 
    	for (epp = environ; *epp; epp++) { | 
    
    
    1428  | 
     | 
     | 
    		if ((cp = strchr(*epp, '='))) { | 
    
    
    1429  | 
     | 
     | 
    			*cp = '\0';  | 
    
    
    1430  | 
     | 
     | 
    			ep = env_define(*epp, cp+1);  | 
    
    
    1431  | 
     | 
     | 
    			ep->export = 0;  | 
    
    
    1432  | 
     | 
     | 
    			*cp = '=';  | 
    
    
    1433  | 
     | 
     | 
    		}  | 
    
    
    1434  | 
     | 
     | 
    	}  | 
    
    
    1435  | 
     | 
     | 
    	/*  | 
    
    
    1436  | 
     | 
     | 
    	 * Special case for DISPLAY variable.  If it is ":0.0" or  | 
    
    
    1437  | 
     | 
     | 
    	 * "unix:0.0", we have to get rid of "unix" and insert our  | 
    
    
    1438  | 
     | 
     | 
    	 * hostname.  | 
    
    
    1439  | 
     | 
     | 
    	 */  | 
    
    
    1440  | 
     | 
     | 
    	if ((ep = env_find("DISPLAY")) | 
    
    
    1441  | 
     | 
     | 
    	    && ((*ep->value == ':')  | 
    
    
    1442  | 
     | 
     | 
    		|| (strncmp(ep->value, "unix:", 5) == 0))) { | 
    
    
    1443  | 
     | 
     | 
    		char hbuf[HOST_NAME_MAX+1];  | 
    
    
    1444  | 
     | 
     | 
    		char *cp2 = strchr(ep->value, ':');  | 
    
    
    1445  | 
     | 
     | 
     | 
    
    
    1446  | 
     | 
     | 
    		gethostname(hbuf, sizeof hbuf);  | 
    
    
    1447  | 
     | 
     | 
     | 
    
    
    1448  | 
     | 
     | 
    		if (asprintf (&cp, "%s%s", hbuf, cp2) == -1)  | 
    
    
    1449  | 
     | 
     | 
    			err(1, "asprintf");  | 
    
    
    1450  | 
     | 
     | 
     | 
    
    
    1451  | 
     | 
     | 
    		free(ep->value);  | 
    
    
    1452  | 
     | 
     | 
    		ep->value = cp;  | 
    
    
    1453  | 
     | 
     | 
    	}  | 
    
    
    1454  | 
     | 
     | 
    	/*  | 
    
    
    1455  | 
     | 
     | 
    	 * If USER is not defined, but LOGNAME is, then add  | 
    
    
    1456  | 
     | 
     | 
    	 * USER with the value from LOGNAME.  By default, we  | 
    
    
    1457  | 
     | 
     | 
    	 * don't export the USER variable.  | 
    
    
    1458  | 
     | 
     | 
    	 */  | 
    
    
    1459  | 
     | 
     | 
    	if ((env_find("USER") == NULL) && (ep = env_find("LOGNAME"))) { | 
    
    
    1460  | 
     | 
     | 
    		env_define("USER", ep->value); | 
    
    
    1461  | 
     | 
     | 
    		env_unexport("USER"); | 
    
    
    1462  | 
     | 
     | 
    	}  | 
    
    
    1463  | 
     | 
     | 
    	env_export("DISPLAY"); | 
    
    
    1464  | 
     | 
     | 
    	env_export("PRINTER"); | 
    
    
    1465  | 
     | 
     | 
    	env_export("XAUTHORITY"); | 
    
    
    1466  | 
     | 
     | 
    }  | 
    
    
    1467  | 
     | 
     | 
     | 
    
    
    1468  | 
     | 
     | 
    struct env_lst *  | 
    
    
    1469  | 
     | 
     | 
    env_define(const char *var, const char *value)  | 
    
    
    1470  | 
     | 
     | 
    { | 
    
    
    1471  | 
     | 
     | 
    	struct env_lst *ep;  | 
    
    
    1472  | 
     | 
     | 
     | 
    
    
    1473  | 
     | 
     | 
    	if ((ep = env_find(var))) { | 
    
    
    1474  | 
     | 
     | 
    		free(ep->var);  | 
    
    
    1475  | 
     | 
     | 
    		free(ep->value);  | 
    
    
    1476  | 
     | 
     | 
    	} else { | 
    
    
    1477  | 
     | 
     | 
    		if ((ep = malloc(sizeof(struct env_lst))) == NULL)  | 
    
    
    1478  | 
     | 
     | 
    			err(1, "malloc");  | 
    
    
    1479  | 
     | 
     | 
    		ep->next = envlisthead.next;  | 
    
    
    1480  | 
     | 
     | 
    		envlisthead.next = ep;  | 
    
    
    1481  | 
     | 
     | 
    		ep->prev = &envlisthead;  | 
    
    
    1482  | 
     | 
     | 
    		if (ep->next)  | 
    
    
    1483  | 
     | 
     | 
    			ep->next->prev = ep;  | 
    
    
    1484  | 
     | 
     | 
    	}  | 
    
    
    1485  | 
     | 
     | 
    	ep->welldefined = opt_welldefined(var);  | 
    
    
    1486  | 
     | 
     | 
    	ep->export = 1;  | 
    
    
    1487  | 
     | 
     | 
    	if ((ep->var = strdup(var)) == NULL)  | 
    
    
    1488  | 
     | 
     | 
    		err(1, "strdup");  | 
    
    
    1489  | 
     | 
     | 
    	if ((ep->value = strdup(value)) == NULL)  | 
    
    
    1490  | 
     | 
     | 
    		err(1, "strdup");  | 
    
    
    1491  | 
     | 
     | 
    	return(ep);  | 
    
    
    1492  | 
     | 
     | 
    }  | 
    
    
    1493  | 
     | 
     | 
     | 
    
    
    1494  | 
     | 
     | 
    static void  | 
    
    
    1495  | 
     | 
     | 
    env_undefine(const char *var)  | 
    
    
    1496  | 
     | 
     | 
    { | 
    
    
    1497  | 
     | 
     | 
    	struct env_lst *ep;  | 
    
    
    1498  | 
     | 
     | 
     | 
    
    
    1499  | 
     | 
     | 
    	if ((ep = env_find(var))) { | 
    
    
    1500  | 
     | 
     | 
    		ep->prev->next = ep->next;  | 
    
    
    1501  | 
     | 
     | 
    		if (ep->next)  | 
    
    
    1502  | 
     | 
     | 
    			ep->next->prev = ep->prev;  | 
    
    
    1503  | 
     | 
     | 
    		free(ep->var);  | 
    
    
    1504  | 
     | 
     | 
    		free(ep->value);  | 
    
    
    1505  | 
     | 
     | 
    		free(ep);  | 
    
    
    1506  | 
     | 
     | 
    	}  | 
    
    
    1507  | 
     | 
     | 
    }  | 
    
    
    1508  | 
     | 
     | 
     | 
    
    
    1509  | 
     | 
     | 
    static void  | 
    
    
    1510  | 
     | 
     | 
    env_export(const char *var)  | 
    
    
    1511  | 
     | 
     | 
    { | 
    
    
    1512  | 
     | 
     | 
    	struct env_lst *ep;  | 
    
    
    1513  | 
     | 
     | 
     | 
    
    
    1514  | 
     | 
     | 
    	if ((ep = env_find(var)))  | 
    
    
    1515  | 
     | 
     | 
    		ep->export = 1;  | 
    
    
    1516  | 
     | 
     | 
    }  | 
    
    
    1517  | 
     | 
     | 
     | 
    
    
    1518  | 
     | 
     | 
    static void  | 
    
    
    1519  | 
     | 
     | 
    env_unexport(const char *var)  | 
    
    
    1520  | 
     | 
     | 
    { | 
    
    
    1521  | 
     | 
     | 
    	struct env_lst *ep;  | 
    
    
    1522  | 
     | 
     | 
     | 
    
    
    1523  | 
     | 
     | 
    	if ((ep = env_find(var)) != NULL)  | 
    
    
    1524  | 
     | 
     | 
    		ep->export = 0;  | 
    
    
    1525  | 
     | 
     | 
    }  | 
    
    
    1526  | 
     | 
     | 
     | 
    
    
    1527  | 
     | 
     | 
    static void  | 
    
    
    1528  | 
     | 
     | 
    env_send(const char *var)  | 
    
    
    1529  | 
     | 
     | 
    { | 
    
    
    1530  | 
     | 
     | 
    	struct env_lst *ep;  | 
    
    
    1531  | 
     | 
     | 
     | 
    
    
    1532  | 
     | 
     | 
    	if (my_state_is_wont(TELOPT_NEW_ENVIRON)  | 
    
    
    1533  | 
     | 
     | 
    		) { | 
    
    
    1534  | 
     | 
     | 
    		fprintf(stderr,  | 
    
    
    1535  | 
     | 
     | 
    		    "Cannot send '%s': Telnet ENVIRON option not enabled\r\n",  | 
    
    
    1536  | 
     | 
     | 
    									var);  | 
    
    
    1537  | 
     | 
     | 
    		return;  | 
    
    
    1538  | 
     | 
     | 
    	}  | 
    
    
    1539  | 
     | 
     | 
    	ep = env_find(var);  | 
    
    
    1540  | 
     | 
     | 
    	if (ep == 0) { | 
    
    
    1541  | 
     | 
     | 
    		fprintf(stderr, "Cannot send '%s': variable not defined\r\n",  | 
    
    
    1542  | 
     | 
     | 
    									var);  | 
    
    
    1543  | 
     | 
     | 
    		return;  | 
    
    
    1544  | 
     | 
     | 
    	}  | 
    
    
    1545  | 
     | 
     | 
    	env_opt_start_info();  | 
    
    
    1546  | 
     | 
     | 
    	env_opt_add(ep->var);  | 
    
    
    1547  | 
     | 
     | 
    	env_opt_end(0);  | 
    
    
    1548  | 
     | 
     | 
    }  | 
    
    
    1549  | 
     | 
     | 
     | 
    
    
    1550  | 
     | 
     | 
    static void  | 
    
    
    1551  | 
     | 
     | 
    env_list(void)  | 
    
    
    1552  | 
     | 
     | 
    { | 
    
    
    1553  | 
     | 
     | 
    	struct env_lst *ep;  | 
    
    
    1554  | 
     | 
     | 
     | 
    
    
    1555  | 
     | 
     | 
    	for (ep = envlisthead.next; ep; ep = ep->next) { | 
    
    
    1556  | 
     | 
     | 
    		printf("%c %-20s %s\r\n", ep->export ? '*' : ' ', | 
    
    
    1557  | 
     | 
     | 
    					ep->var, ep->value);  | 
    
    
    1558  | 
     | 
     | 
    	}  | 
    
    
    1559  | 
     | 
     | 
    }  | 
    
    
    1560  | 
     | 
     | 
     | 
    
    
    1561  | 
     | 
     | 
    char *  | 
    
    
    1562  | 
     | 
     | 
    env_default(int init, int welldefined)  | 
    
    
    1563  | 
     | 
     | 
    { | 
    
    
    1564  | 
     | 
     | 
    	static struct env_lst *nep = NULL;  | 
    
    
    1565  | 
     | 
     | 
     | 
    
    
    1566  | 
     | 
     | 
    	if (init) { | 
    
    
    1567  | 
     | 
     | 
    		nep = &envlisthead;  | 
    
    
    1568  | 
     | 
     | 
    		return NULL;  | 
    
    
    1569  | 
     | 
     | 
    	}  | 
    
    
    1570  | 
     | 
     | 
    	if (nep) { | 
    
    
    1571  | 
     | 
     | 
    		while ((nep = nep->next)) { | 
    
    
    1572  | 
     | 
     | 
    			if (nep->export && (nep->welldefined == welldefined))  | 
    
    
    1573  | 
     | 
     | 
    				return(nep->var);  | 
    
    
    1574  | 
     | 
     | 
    		}  | 
    
    
    1575  | 
     | 
     | 
    	}  | 
    
    
    1576  | 
     | 
     | 
    	return(NULL);  | 
    
    
    1577  | 
     | 
     | 
    }  | 
    
    
    1578  | 
     | 
     | 
     | 
    
    
    1579  | 
     | 
     | 
    char *  | 
    
    
    1580  | 
     | 
     | 
    env_getvalue(const char *var, int exported_only)  | 
    
    
    1581  | 
     | 
     | 
    { | 
    
    
    1582  | 
     | 
     | 
    	struct env_lst *ep;  | 
    
    
    1583  | 
     | 
     | 
     | 
    
    
    1584  | 
     | 
     | 
    	if ((ep = env_find(var)) && (!exported_only || ep->export))  | 
    
    
    1585  | 
     | 
     | 
    		return(ep->value);  | 
    
    
    1586  | 
     | 
     | 
    	return(NULL);  | 
    
    
    1587  | 
     | 
     | 
    }  | 
    
    
    1588  | 
     | 
     | 
     | 
    
    
    1589  | 
     | 
     | 
    static void  | 
    
    
    1590  | 
     | 
     | 
    connection_status(int local_only)  | 
    
    
    1591  | 
     | 
     | 
    { | 
    
    
    1592  | 
     | 
     | 
    	if (!connected)  | 
    
    
    1593  | 
     | 
     | 
    		printf("No connection.\r\n"); | 
    
    
    1594  | 
     | 
     | 
    	else { | 
    
    
    1595  | 
     | 
     | 
    		printf("Connected to %s.\r\n", hostname); | 
    
    
    1596  | 
     | 
     | 
    		if (!local_only) { | 
    
    
    1597  | 
     | 
     | 
    			int mode = getconnmode();  | 
    
    
    1598  | 
     | 
     | 
     | 
    
    
    1599  | 
     | 
     | 
    			printf("Operating "); | 
    
    
    1600  | 
     | 
     | 
    			if (my_want_state_is_will(TELOPT_LINEMODE)) { | 
    
    
    1601  | 
     | 
     | 
    				printf("with LINEMODE option\r\n" | 
    
    
    1602  | 
     | 
     | 
    				    "%s line editing\r\n"  | 
    
    
    1603  | 
     | 
     | 
    				    "%s catching of signals\r\n",  | 
    
    
    1604  | 
     | 
     | 
    				    (mode & MODE_EDIT) ? "Local" : "No",  | 
    
    
    1605  | 
     | 
     | 
    				    (mode & MODE_TRAPSIG) ? "Local" : "No");  | 
    
    
    1606  | 
     | 
     | 
    				slcstate();  | 
    
    
    1607  | 
     | 
     | 
    #ifdef	KLUDGELINEMODE  | 
    
    
    1608  | 
     | 
     | 
    			} else if (kludgelinemode &&  | 
    
    
    1609  | 
     | 
     | 
    			    my_want_state_is_dont(TELOPT_SGA)) { | 
    
    
    1610  | 
     | 
     | 
    				printf("in obsolete linemode\r\n"); | 
    
    
    1611  | 
     | 
     | 
    #endif  | 
    
    
    1612  | 
     | 
     | 
    			} else { | 
    
    
    1613  | 
     | 
     | 
    				printf("in single character mode\r\n"); | 
    
    
    1614  | 
     | 
     | 
    				if (localchars)  | 
    
    
    1615  | 
     | 
     | 
    					printf("Catching signals locally\r\n"); | 
    
    
    1616  | 
     | 
     | 
    			}  | 
    
    
    1617  | 
     | 
     | 
     | 
    
    
    1618  | 
     | 
     | 
    			printf("%s character echo\r\n", | 
    
    
    1619  | 
     | 
     | 
    			    (mode & MODE_ECHO) ? "Local" : "Remote");  | 
    
    
    1620  | 
     | 
     | 
    			if (my_want_state_is_will(TELOPT_LFLOW))  | 
    
    
    1621  | 
     | 
     | 
    				printf("%s flow control\r\n", | 
    
    
    1622  | 
     | 
     | 
    				    (mode & MODE_FLOW) ? "Local" : "No");  | 
    
    
    1623  | 
     | 
     | 
    		}  | 
    
    
    1624  | 
     | 
     | 
    	}  | 
    
    
    1625  | 
     | 
     | 
    	printf("Escape character is '%s'.\r\n", control(escape)); | 
    
    
    1626  | 
     | 
     | 
    	(void) fflush(stdout);  | 
    
    
    1627  | 
     | 
     | 
    }  | 
    
    
    1628  | 
     | 
     | 
     | 
    
    
    1629  | 
     | 
     | 
    /*  | 
    
    
    1630  | 
     | 
     | 
     * Print status about the connection.  | 
    
    
    1631  | 
     | 
     | 
     */  | 
    
    
    1632  | 
     | 
     | 
    static int  | 
    
    
    1633  | 
     | 
     | 
    status(int argc, char *argv[])  | 
    
    
    1634  | 
     | 
     | 
    { | 
    
    
    1635  | 
     | 
     | 
    	connection_status(0);  | 
    
    
    1636  | 
     | 
     | 
    	return 1;  | 
    
    
    1637  | 
     | 
     | 
    }  | 
    
    
    1638  | 
     | 
     | 
     | 
    
    
    1639  | 
     | 
     | 
    /*  | 
    
    
    1640  | 
     | 
     | 
     * Function that gets called when SIGINFO is received.  | 
    
    
    1641  | 
     | 
     | 
     */  | 
    
    
    1642  | 
     | 
     | 
    void  | 
    
    
    1643  | 
     | 
     | 
    ayt_status(int sig)  | 
    
    
    1644  | 
     | 
     | 
    { | 
    
    
    1645  | 
     | 
     | 
    	connection_status(1);  | 
    
    
    1646  | 
     | 
     | 
    }  | 
    
    
    1647  | 
     | 
     | 
     | 
    
    
    1648  | 
     | 
     | 
    static Command *getcmd(char *name);  | 
    
    
    1649  | 
     | 
     | 
     | 
    
    
    1650  | 
     | 
     | 
    static void  | 
    
    
    1651  | 
     | 
     | 
    cmdrc(char *m1, char *m2)  | 
    
    
    1652  | 
     | 
     | 
    { | 
    
    
    1653  | 
     | 
     | 
        static char rcname[128];  | 
    
    
    1654  | 
     | 
     | 
        Command *c;  | 
    
    
    1655  | 
     | 
     | 
        FILE *rcfile;  | 
    
    
    1656  | 
     | 
     | 
        int gotmachine = 0;  | 
    
    
    1657  | 
     | 
     | 
        int l1 = strlen(m1);  | 
    
    
    1658  | 
     | 
     | 
        int l2 = strlen(m2);  | 
    
    
    1659  | 
     | 
     | 
        char m1save[HOST_NAME_MAX+1];  | 
    
    
    1660  | 
     | 
     | 
     | 
    
    
    1661  | 
     | 
     | 
        if (skiprc)  | 
    
    
    1662  | 
     | 
     | 
    	return;  | 
    
    
    1663  | 
     | 
     | 
     | 
    
    
    1664  | 
     | 
     | 
        strlcpy(m1save, m1, sizeof(m1save));  | 
    
    
    1665  | 
     | 
     | 
        m1 = m1save;  | 
    
    
    1666  | 
     | 
     | 
     | 
    
    
    1667  | 
     | 
     | 
        if (rcname[0] == 0) { | 
    
    
    1668  | 
     | 
     | 
    	char *home = getenv("HOME"); | 
    
    
    1669  | 
     | 
     | 
     | 
    
    
    1670  | 
     | 
     | 
    	if (home == NULL || *home == '\0')  | 
    
    
    1671  | 
     | 
     | 
    	    return;  | 
    
    
    1672  | 
     | 
     | 
    	snprintf (rcname, sizeof(rcname), "%s/.telnetrc",  | 
    
    
    1673  | 
     | 
     | 
    		  home ? home : "");  | 
    
    
    1674  | 
     | 
     | 
        }  | 
    
    
    1675  | 
     | 
     | 
     | 
    
    
    1676  | 
     | 
     | 
        if ((rcfile = fopen(rcname, "r")) == 0) { | 
    
    
    1677  | 
     | 
     | 
    	return;  | 
    
    
    1678  | 
     | 
     | 
        }  | 
    
    
    1679  | 
     | 
     | 
     | 
    
    
    1680  | 
     | 
     | 
        for (;;) { | 
    
    
    1681  | 
     | 
     | 
    	if (fgets(line, sizeof(line), rcfile) == NULL)  | 
    
    
    1682  | 
     | 
     | 
    	    break;  | 
    
    
    1683  | 
     | 
     | 
    	if (line[0] == 0)  | 
    
    
    1684  | 
     | 
     | 
    	    break;  | 
    
    
    1685  | 
     | 
     | 
    	if (line[0] == '#')  | 
    
    
    1686  | 
     | 
     | 
    	    continue;  | 
    
    
    1687  | 
     | 
     | 
    	if (gotmachine) { | 
    
    
    1688  | 
     | 
     | 
    	    if (!isspace((unsigned char)line[0]))  | 
    
    
    1689  | 
     | 
     | 
    		gotmachine = 0;  | 
    
    
    1690  | 
     | 
     | 
    	}  | 
    
    
    1691  | 
     | 
     | 
    	if (gotmachine == 0) { | 
    
    
    1692  | 
     | 
     | 
    	    if (isspace((unsigned char)line[0]))  | 
    
    
    1693  | 
     | 
     | 
    		continue;  | 
    
    
    1694  | 
     | 
     | 
    	    if (strncasecmp(line, m1, l1) == 0)  | 
    
    
    1695  | 
     | 
     | 
    		strncpy(line, &line[l1], sizeof(line) - l1);  | 
    
    
    1696  | 
     | 
     | 
    	    else if (strncasecmp(line, m2, l2) == 0)  | 
    
    
    1697  | 
     | 
     | 
    		strncpy(line, &line[l2], sizeof(line) - l2);  | 
    
    
    1698  | 
     | 
     | 
    	    else if (strncasecmp(line, "DEFAULT", 7) == 0)  | 
    
    
    1699  | 
     | 
     | 
    		strncpy(line, &line[7], sizeof(line) - 7);  | 
    
    
    1700  | 
     | 
     | 
    	    else  | 
    
    
    1701  | 
     | 
     | 
    		continue;  | 
    
    
    1702  | 
     | 
     | 
    	    if (line[0] != ' ' && line[0] != '\t' && line[0] != '\n')  | 
    
    
    1703  | 
     | 
     | 
    		continue;  | 
    
    
    1704  | 
     | 
     | 
    	    gotmachine = 1;  | 
    
    
    1705  | 
     | 
     | 
    	}  | 
    
    
    1706  | 
     | 
     | 
    	makeargv();  | 
    
    
    1707  | 
     | 
     | 
    	if (margv[0] == 0)  | 
    
    
    1708  | 
     | 
     | 
    	    continue;  | 
    
    
    1709  | 
     | 
     | 
    	c = getcmd(margv[0]);  | 
    
    
    1710  | 
     | 
     | 
    	if (Ambiguous(c)) { | 
    
    
    1711  | 
     | 
     | 
    	    printf("?Ambiguous command: %s\r\n", margv[0]); | 
    
    
    1712  | 
     | 
     | 
    	    continue;  | 
    
    
    1713  | 
     | 
     | 
    	}  | 
    
    
    1714  | 
     | 
     | 
    	if (c == 0) { | 
    
    
    1715  | 
     | 
     | 
    	    printf("?Invalid command: %s\r\n", margv[0]); | 
    
    
    1716  | 
     | 
     | 
    	    continue;  | 
    
    
    1717  | 
     | 
     | 
    	}  | 
    
    
    1718  | 
     | 
     | 
    	/*  | 
    
    
    1719  | 
     | 
     | 
    	 * This should never happen...  | 
    
    
    1720  | 
     | 
     | 
    	 */  | 
    
    
    1721  | 
     | 
     | 
    	if (c->needconnect && !connected) { | 
    
    
    1722  | 
     | 
     | 
    	    printf("?Need to be connected first for %s.\r\n", margv[0]); | 
    
    
    1723  | 
     | 
     | 
    	    continue;  | 
    
    
    1724  | 
     | 
     | 
    	}  | 
    
    
    1725  | 
     | 
     | 
    	(*c->handler)(margc, margv);  | 
    
    
    1726  | 
     | 
     | 
        }  | 
    
    
    1727  | 
     | 
     | 
        fclose(rcfile);  | 
    
    
    1728  | 
     | 
     | 
    }  | 
    
    
    1729  | 
     | 
     | 
     | 
    
    
    1730  | 
     | 
     | 
    int  | 
    
    
    1731  | 
     | 
     | 
    tn(int argc, char *argv[])  | 
    
    
    1732  | 
     | 
     | 
    { | 
    
    
    1733  | 
     | 
     | 
        struct addrinfo hints, *res, *res0;  | 
    
    
    1734  | 
     | 
     | 
        char *cmd, *hostp = 0, *portp = 0, *user = 0, *aliasp = 0;  | 
    
    
    1735  | 
     | 
     | 
        int error, retry;  | 
    
    
    1736  | 
     | 
     | 
        const int niflags = NI_NUMERICHOST, tos = IPTOS_LOWDELAY;  | 
    
    
    1737  | 
     | 
     | 
     | 
    
    
    1738  | 
     | 
     | 
        if (connected) { | 
    
    
    1739  | 
     | 
     | 
    	printf("?Already connected to %s\r\n", hostname); | 
    
    
    1740  | 
     | 
     | 
    	return 0;  | 
    
    
    1741  | 
     | 
     | 
        }  | 
    
    
    1742  | 
     | 
     | 
        if (connections) { | 
    
    
    1743  | 
     | 
     | 
    	printf("Repeated connections not supported\r\n"); | 
    
    
    1744  | 
     | 
     | 
    	return 0;  | 
    
    
    1745  | 
     | 
     | 
        }  | 
    
    
    1746  | 
     | 
     | 
        if (argc < 2) { | 
    
    
    1747  | 
     | 
     | 
    	strlcpy(line, "open ", sizeof(line));  | 
    
    
    1748  | 
     | 
     | 
    	printf("(to) "); | 
    
    
    1749  | 
     | 
     | 
    	(void) fgets(&line[strlen(line)], sizeof(line) - strlen(line), stdin);  | 
    
    
    1750  | 
     | 
     | 
    	makeargv();  | 
    
    
    1751  | 
     | 
     | 
    	argc = margc;  | 
    
    
    1752  | 
     | 
     | 
    	argv = margv;  | 
    
    
    1753  | 
     | 
     | 
        }  | 
    
    
    1754  | 
     | 
     | 
        cmd = *argv;  | 
    
    
    1755  | 
     | 
     | 
        --argc; ++argv;  | 
    
    
    1756  | 
     | 
     | 
        while (argc) { | 
    
    
    1757  | 
     | 
     | 
    	if (strcmp(*argv, "help") == 0 || isprefix(*argv, "?"))  | 
    
    
    1758  | 
     | 
     | 
    	    goto usage;  | 
    
    
    1759  | 
     | 
     | 
    	if (strcmp(*argv, "-l") == 0) { | 
    
    
    1760  | 
     | 
     | 
    	    --argc; ++argv;  | 
    
    
    1761  | 
     | 
     | 
    	    if (argc == 0)  | 
    
    
    1762  | 
     | 
     | 
    		goto usage;  | 
    
    
    1763  | 
     | 
     | 
    	    if ((user = strdup(*argv++)) == NULL)  | 
    
    
    1764  | 
     | 
     | 
    		err(1, "strdup");  | 
    
    
    1765  | 
     | 
     | 
    	    --argc;  | 
    
    
    1766  | 
     | 
     | 
    	    continue;  | 
    
    
    1767  | 
     | 
     | 
    	}  | 
    
    
    1768  | 
     | 
     | 
    	if (strcmp(*argv, "-b") == 0) { | 
    
    
    1769  | 
     | 
     | 
    	    --argc; ++argv;  | 
    
    
    1770  | 
     | 
     | 
    	    if (argc == 0)  | 
    
    
    1771  | 
     | 
     | 
    		goto usage;  | 
    
    
    1772  | 
     | 
     | 
    	    aliasp = *argv++;  | 
    
    
    1773  | 
     | 
     | 
    	    --argc;  | 
    
    
    1774  | 
     | 
     | 
    	    continue;  | 
    
    
    1775  | 
     | 
     | 
    	}  | 
    
    
    1776  | 
     | 
     | 
    	if (strcmp(*argv, "-a") == 0) { | 
    
    
    1777  | 
     | 
     | 
    	    --argc; ++argv;  | 
    
    
    1778  | 
     | 
     | 
    	    autologin = 1;  | 
    
    
    1779  | 
     | 
     | 
    	    continue;  | 
    
    
    1780  | 
     | 
     | 
    	}  | 
    
    
    1781  | 
     | 
     | 
    	if (hostp == 0) { | 
    
    
    1782  | 
     | 
     | 
    	    hostp = *argv++;  | 
    
    
    1783  | 
     | 
     | 
    	    --argc;  | 
    
    
    1784  | 
     | 
     | 
    	    continue;  | 
    
    
    1785  | 
     | 
     | 
    	}  | 
    
    
    1786  | 
     | 
     | 
    	if (portp == 0) { | 
    
    
    1787  | 
     | 
     | 
    	    portp = *argv++;  | 
    
    
    1788  | 
     | 
     | 
    	    --argc;  | 
    
    
    1789  | 
     | 
     | 
    	    continue;  | 
    
    
    1790  | 
     | 
     | 
    	}  | 
    
    
    1791  | 
     | 
     | 
        usage:  | 
    
    
    1792  | 
     | 
     | 
    	printf("usage: %s [-a] [-b hostalias] [-l user] host-name [port]\r\n", cmd); | 
    
    
    1793  | 
     | 
     | 
    	return 0;  | 
    
    
    1794  | 
     | 
     | 
        }  | 
    
    
    1795  | 
     | 
     | 
        if (hostp == 0)  | 
    
    
    1796  | 
     | 
     | 
    	goto usage;  | 
    
    
    1797  | 
     | 
     | 
     | 
    
    
    1798  | 
     | 
     | 
        hostname = hostp;  | 
    
    
    1799  | 
     | 
     | 
        memset(&hints, 0, sizeof(hints));  | 
    
    
    1800  | 
     | 
     | 
        hints.ai_family = family;  | 
    
    
    1801  | 
     | 
     | 
        hints.ai_socktype = SOCK_STREAM;  | 
    
    
    1802  | 
     | 
     | 
        hints.ai_flags = AI_CANONNAME;  | 
    
    
    1803  | 
     | 
     | 
        if (portp == NULL) { | 
    
    
    1804  | 
     | 
     | 
            portp = "telnet";  | 
    
    
    1805  | 
     | 
     | 
            telnetport = 1;  | 
    
    
    1806  | 
     | 
     | 
        } else if (*portp == '-') { | 
    
    
    1807  | 
     | 
     | 
            portp++;  | 
    
    
    1808  | 
     | 
     | 
            telnetport = 1;  | 
    
    
    1809  | 
     | 
     | 
        } else  | 
    
    
    1810  | 
     | 
     | 
            telnetport = 0;  | 
    
    
    1811  | 
     | 
     | 
        error = getaddrinfo(hostp, portp, &hints, &res0);  | 
    
    
    1812  | 
     | 
     | 
        if (error) { | 
    
    
    1813  | 
     | 
     | 
            if (error == EAI_SERVICE)  | 
    
    
    1814  | 
     | 
     | 
                warnx("%s: bad port", portp); | 
    
    
    1815  | 
     | 
     | 
            else  | 
    
    
    1816  | 
     | 
     | 
                warnx("%s: %s", hostp, gai_strerror(error)); | 
    
    
    1817  | 
     | 
     | 
            return 0;  | 
    
    
    1818  | 
     | 
     | 
        }  | 
    
    
    1819  | 
     | 
     | 
     | 
    
    
    1820  | 
     | 
     | 
        net = -1;  | 
    
    
    1821  | 
     | 
     | 
        retry = 0;  | 
    
    
    1822  | 
     | 
     | 
        for (res = res0; res; res = res->ai_next) { | 
    
    
    1823  | 
     | 
     | 
    	if (1 /* retry */) { | 
    
    
    1824  | 
     | 
     | 
    	    char hbuf[NI_MAXHOST];  | 
    
    
    1825  | 
     | 
     | 
     | 
    
    
    1826  | 
     | 
     | 
    	    if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),  | 
    
    
    1827  | 
     | 
     | 
    		    NULL, 0, niflags) != 0) { | 
    
    
    1828  | 
     | 
     | 
    		strlcpy(hbuf, "(invalid)", sizeof(hbuf));  | 
    
    
    1829  | 
     | 
     | 
    	    }  | 
    
    
    1830  | 
     | 
     | 
    	    printf("Trying %s...\r\n", hbuf); | 
    
    
    1831  | 
     | 
     | 
    	}  | 
    
    
    1832  | 
     | 
     | 
    	net = socket(res->ai_family, res->ai_socktype, res->ai_protocol);  | 
    
    
    1833  | 
     | 
     | 
    	if (net < 0)  | 
    
    
    1834  | 
     | 
     | 
    	    continue;  | 
    
    
    1835  | 
     | 
     | 
     | 
    
    
    1836  | 
     | 
     | 
    	if (aliasp) { | 
    
    
    1837  | 
     | 
     | 
    	    struct addrinfo ahints, *ares;  | 
    
    
    1838  | 
     | 
     | 
     | 
    
    
    1839  | 
     | 
     | 
    	    memset(&ahints, 0, sizeof(ahints));  | 
    
    
    1840  | 
     | 
     | 
    	    ahints.ai_family = family;  | 
    
    
    1841  | 
     | 
     | 
    	    ahints.ai_socktype = SOCK_STREAM;  | 
    
    
    1842  | 
     | 
     | 
    	    ahints.ai_flags = AI_PASSIVE;  | 
    
    
    1843  | 
     | 
     | 
    	    error = getaddrinfo(aliasp, "0", &ahints, &ares);  | 
    
    
    1844  | 
     | 
     | 
    	    if (error) { | 
    
    
    1845  | 
     | 
     | 
    		warn("%s: %s", aliasp, gai_strerror(error)); | 
    
    
    1846  | 
     | 
     | 
    		close(net);  | 
    
    
    1847  | 
     | 
     | 
    		net = -1;  | 
    
    
    1848  | 
     | 
     | 
    		continue;  | 
    
    
    1849  | 
     | 
     | 
    	    }  | 
    
    
    1850  | 
     | 
     | 
    	    if (bind(net, ares->ai_addr, ares->ai_addrlen) < 0) { | 
    
    
    1851  | 
     | 
     | 
    		perror(aliasp);  | 
    
    
    1852  | 
     | 
     | 
    		(void) close(net);   /* dump descriptor */  | 
    
    
    1853  | 
     | 
     | 
    		net = -1;  | 
    
    
    1854  | 
     | 
     | 
    		freeaddrinfo(ares);  | 
    
    
    1855  | 
     | 
     | 
    		continue;  | 
    
    
    1856  | 
     | 
     | 
                }  | 
    
    
    1857  | 
     | 
     | 
    	    freeaddrinfo(ares);  | 
    
    
    1858  | 
     | 
     | 
    	}  | 
    
    
    1859  | 
     | 
     | 
     | 
    
    
    1860  | 
     | 
     | 
    	switch (res->ai_family) { | 
    
    
    1861  | 
     | 
     | 
    	case AF_INET:  | 
    
    
    1862  | 
     | 
     | 
    		if (setsockopt(net, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0  | 
    
    
    1863  | 
     | 
     | 
    		    && errno != ENOPROTOOPT)  | 
    
    
    1864  | 
     | 
     | 
    			perror("telnet: setsockopt (IP_TOS) (ignored)"); | 
    
    
    1865  | 
     | 
     | 
    		break;  | 
    
    
    1866  | 
     | 
     | 
    	case AF_INET6:  | 
    
    
    1867  | 
     | 
     | 
    		if (setsockopt(net, IPPROTO_IPV6, IPV6_TCLASS, &tos,  | 
    
    
    1868  | 
     | 
     | 
    		    sizeof(tos)) < 0 && errno != ENOPROTOOPT)  | 
    
    
    1869  | 
     | 
     | 
    			perror("telnet: setsockopt (IPV6_TCLASS) (ignored)"); | 
    
    
    1870  | 
     | 
     | 
    		break;  | 
    
    
    1871  | 
     | 
     | 
    	}  | 
    
    
    1872  | 
     | 
     | 
     | 
    
    
    1873  | 
     | 
     | 
    	if (connect(net, res->ai_addr, res->ai_addrlen) < 0) { | 
    
    
    1874  | 
     | 
     | 
    	    char hbuf[NI_MAXHOST];  | 
    
    
    1875  | 
     | 
     | 
     | 
    
    
    1876  | 
     | 
     | 
    	    if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),  | 
    
    
    1877  | 
     | 
     | 
    		    NULL, 0, niflags) != 0) { | 
    
    
    1878  | 
     | 
     | 
    		strlcpy(hbuf, "(invalid)", sizeof(hbuf));  | 
    
    
    1879  | 
     | 
     | 
    	    }  | 
    
    
    1880  | 
     | 
     | 
    	    fprintf(stderr, "telnet: connect to address %s: %s\n", hbuf,  | 
    
    
    1881  | 
     | 
     | 
    		strerror(errno));  | 
    
    
    1882  | 
     | 
     | 
     | 
    
    
    1883  | 
     | 
     | 
    	    close(net);  | 
    
    
    1884  | 
     | 
     | 
    	    net = -1;  | 
    
    
    1885  | 
     | 
     | 
    	    retry++;  | 
    
    
    1886  | 
     | 
     | 
    	    continue;  | 
    
    
    1887  | 
     | 
     | 
    	}  | 
    
    
    1888  | 
     | 
     | 
     | 
    
    
    1889  | 
     | 
     | 
    	connected++;  | 
    
    
    1890  | 
     | 
     | 
    	break;  | 
    
    
    1891  | 
     | 
     | 
        }  | 
    
    
    1892  | 
     | 
     | 
        freeaddrinfo(res0);  | 
    
    
    1893  | 
     | 
     | 
        if (net < 0) { | 
    
    
    1894  | 
     | 
     | 
    	return 0;  | 
    
    
    1895  | 
     | 
     | 
        }  | 
    
    
    1896  | 
     | 
     | 
        cmdrc(hostp, hostname);  | 
    
    
    1897  | 
     | 
     | 
        if (autologin && user == NULL) { | 
    
    
    1898  | 
     | 
     | 
    	struct passwd *pw;  | 
    
    
    1899  | 
     | 
     | 
     | 
    
    
    1900  | 
     | 
     | 
    	user = getlogin();  | 
    
    
    1901  | 
     | 
     | 
    	if (user == NULL ||  | 
    
    
    1902  | 
     | 
     | 
    	    (pw = getpwnam(user)) == NULL || pw->pw_uid != getuid()) { | 
    
    
    1903  | 
     | 
     | 
    		if ((pw = getpwuid(getuid())) != NULL)  | 
    
    
    1904  | 
     | 
     | 
    			user = pw->pw_name;  | 
    
    
    1905  | 
     | 
     | 
    		else  | 
    
    
    1906  | 
     | 
     | 
    			user = NULL;  | 
    
    
    1907  | 
     | 
     | 
    	}  | 
    
    
    1908  | 
     | 
     | 
        }  | 
    
    
    1909  | 
     | 
     | 
        if (user) { | 
    
    
    1910  | 
     | 
     | 
    	env_define("USER", user); | 
    
    
    1911  | 
     | 
     | 
    	env_export("USER"); | 
    
    
    1912  | 
     | 
     | 
        }  | 
    
    
    1913  | 
     | 
     | 
        connection_status(1);  | 
    
    
    1914  | 
     | 
     | 
        if (setjmp(peerdied) == 0)  | 
    
    
    1915  | 
     | 
     | 
    	telnet(user);  | 
    
    
    1916  | 
     | 
     | 
        (void)close(net);  | 
    
    
    1917  | 
     | 
     | 
        ExitString("Connection closed by foreign host.\r\n",1); | 
    
    
    1918  | 
     | 
     | 
    }  | 
    
    
    1919  | 
     | 
     | 
     | 
    
    
    1920  | 
     | 
     | 
    #define HELPINDENT (sizeof ("connect")) | 
    
    
    1921  | 
     | 
     | 
     | 
    
    
    1922  | 
     | 
     | 
    static char  | 
    
    
    1923  | 
     | 
     | 
    	openhelp[] =	"connect to a site",  | 
    
    
    1924  | 
     | 
     | 
    	closehelp[] =	"close current connection",  | 
    
    
    1925  | 
     | 
     | 
    	logouthelp[] =	"forcibly logout remote user and close the connection",  | 
    
    
    1926  | 
     | 
     | 
    	quithelp[] =	"exit telnet",  | 
    
    
    1927  | 
     | 
     | 
    	statushelp[] =	"print status information",  | 
    
    
    1928  | 
     | 
     | 
    	helphelp[] =	"print help information",  | 
    
    
    1929  | 
     | 
     | 
    	sendhelp[] =	"transmit special characters ('send ?' for more)", | 
    
    
    1930  | 
     | 
     | 
    	sethelp[] = 	"set operating parameters ('set ?' for more)", | 
    
    
    1931  | 
     | 
     | 
    	unsethelp[] = 	"unset operating parameters ('unset ?' for more)", | 
    
    
    1932  | 
     | 
     | 
    	togglestring[] ="toggle operating parameters ('toggle ?' for more)", | 
    
    
    1933  | 
     | 
     | 
    	slchelp[] =	"change state of special charaters ('slc ?' for more)", | 
    
    
    1934  | 
     | 
     | 
    	displayhelp[] =	"display operating parameters",  | 
    
    
    1935  | 
     | 
     | 
    	zhelp[] =	"suspend telnet",  | 
    
    
    1936  | 
     | 
     | 
    	envhelp[] =	"change environment variables ('environ ?' for more)", | 
    
    
    1937  | 
     | 
     | 
    	modestring[] = "try to enter line or character mode ('mode ?' for more)"; | 
    
    
    1938  | 
     | 
     | 
     | 
    
    
    1939  | 
     | 
     | 
    static int	help(int, char**);  | 
    
    
    1940  | 
     | 
     | 
     | 
    
    
    1941  | 
     | 
     | 
    static Command cmdtab[] = { | 
    
    
    1942  | 
     | 
     | 
    	{ "close",	closehelp,	bye,		1 }, | 
    
    
    1943  | 
     | 
     | 
    	{ "logout",	logouthelp,	logout,		1 }, | 
    
    
    1944  | 
     | 
     | 
    	{ "display",	displayhelp,	display,	0 }, | 
    
    
    1945  | 
     | 
     | 
    	{ "mode",	modestring,	modecmd,	0 }, | 
    
    
    1946  | 
     | 
     | 
    	{ "open",	openhelp,	tn,		0 }, | 
    
    
    1947  | 
     | 
     | 
    	{ "quit",	quithelp,	quitcmd,	0 }, | 
    
    
    1948  | 
     | 
     | 
    	{ "send",	sendhelp,	sendcmd,	0 }, | 
    
    
    1949  | 
     | 
     | 
    	{ "set",	sethelp,	setcmd,		0 }, | 
    
    
    1950  | 
     | 
     | 
    	{ "unset",	unsethelp,	unsetcmd,	0 }, | 
    
    
    1951  | 
     | 
     | 
    	{ "status",	statushelp,	status,		0 }, | 
    
    
    1952  | 
     | 
     | 
    	{ "toggle",	togglestring,	toggle,		0 }, | 
    
    
    1953  | 
     | 
     | 
    	{ "slc",	slchelp,	slccmd,		0 }, | 
    
    
    1954  | 
     | 
     | 
     | 
    
    
    1955  | 
     | 
     | 
    	{ "z",		zhelp,		telnetsuspend,	0 }, | 
    
    
    1956  | 
     | 
     | 
    	{ "environ",	envhelp,	env_cmd,	0 }, | 
    
    
    1957  | 
     | 
     | 
    	{ "?",		helphelp,	help,		0 }, | 
    
    
    1958  | 
     | 
     | 
    	{ 0,		0,		0,		0 } | 
    
    
    1959  | 
     | 
     | 
    };  | 
    
    
    1960  | 
     | 
     | 
     | 
    
    
    1961  | 
     | 
     | 
    static char	crmodhelp[] =	"deprecated command -- use 'toggle crmod' instead";  | 
    
    
    1962  | 
     | 
     | 
    static char	escapehelp[] =	"deprecated command -- use 'set escape' instead";  | 
    
    
    1963  | 
     | 
     | 
     | 
    
    
    1964  | 
     | 
     | 
    static Command cmdtab2[] = { | 
    
    
    1965  | 
     | 
     | 
    	{ "help",	0,		help,		0 }, | 
    
    
    1966  | 
     | 
     | 
    	{ "escape",	escapehelp,	setescape,	0 }, | 
    
    
    1967  | 
     | 
     | 
    	{ "crmod",	crmodhelp,	togcrmod,	0 }, | 
    
    
    1968  | 
     | 
     | 
    	{ 0,		0,		0,		0 } | 
    
    
    1969  | 
     | 
     | 
    };  | 
    
    
    1970  | 
     | 
     | 
     | 
    
    
    1971  | 
     | 
     | 
     | 
    
    
    1972  | 
     | 
     | 
    static Command *  | 
    
    
    1973  | 
     | 
     | 
    getcmd(char *name)  | 
    
    
    1974  | 
     | 
     | 
    { | 
    
    
    1975  | 
     | 
     | 
        Command *cm;  | 
    
    
    1976  | 
     | 
     | 
     | 
    
    
    1977  | 
     | 
     | 
        if ((cm = (Command *) genget(name, (char **) cmdtab, sizeof(Command))))  | 
    
    
    1978  | 
     | 
     | 
    	return cm;  | 
    
    
    1979  | 
     | 
     | 
        return (Command *) genget(name, (char **) cmdtab2, sizeof(Command));  | 
    
    
    1980  | 
     | 
     | 
    }  | 
    
    
    1981  | 
     | 
     | 
     | 
    
    
    1982  | 
     | 
     | 
    void  | 
    
    
    1983  | 
     | 
     | 
    command(int top, char *tbuf, int cnt)  | 
    
    
    1984  | 
     | 
     | 
    { | 
    
    
    1985  | 
     | 
     | 
        Command *c;  | 
    
    
    1986  | 
     | 
     | 
     | 
    
    
    1987  | 
     | 
     | 
        setcommandmode();  | 
    
    
    1988  | 
     | 
     | 
        if (!top) { | 
    
    
    1989  | 
     | 
     | 
    	putchar('\n'); | 
    
    
    1990  | 
     | 
     | 
        } else { | 
    
    
    1991  | 
     | 
     | 
    	(void) signal(SIGINT, SIG_DFL);  | 
    
    
    1992  | 
     | 
     | 
    	(void) signal(SIGQUIT, SIG_DFL);  | 
    
    
    1993  | 
     | 
     | 
        }  | 
    
    
    1994  | 
     | 
     | 
        for (;;) { | 
    
    
    1995  | 
     | 
     | 
    	if (rlogin == _POSIX_VDISABLE)  | 
    
    
    1996  | 
     | 
     | 
    		printf("%s> ", prompt); | 
    
    
    1997  | 
     | 
     | 
    	if (tbuf) { | 
    
    
    1998  | 
     | 
     | 
    	    char *cp;  | 
    
    
    1999  | 
     | 
     | 
    	    cp = line;  | 
    
    
    2000  | 
     | 
     | 
    	    while (cnt > 0 && (*cp++ = *tbuf++) != '\n')  | 
    
    
    2001  | 
     | 
     | 
    		cnt--;  | 
    
    
    2002  | 
     | 
     | 
    	    tbuf = 0;  | 
    
    
    2003  | 
     | 
     | 
    	    if (cp == line || *--cp != '\n' || cp == line)  | 
    
    
    2004  | 
     | 
     | 
    		goto getline;  | 
    
    
    2005  | 
     | 
     | 
    	    *cp = '\0';  | 
    
    
    2006  | 
     | 
     | 
    	    if (rlogin == _POSIX_VDISABLE)  | 
    
    
    2007  | 
     | 
     | 
    		printf("%s\r\n", line); | 
    
    
    2008  | 
     | 
     | 
    	} else { | 
    
    
    2009  | 
     | 
     | 
    	getline:  | 
    
    
    2010  | 
     | 
     | 
    	    if (rlogin != _POSIX_VDISABLE)  | 
    
    
    2011  | 
     | 
     | 
    		printf("%s> ", prompt); | 
    
    
    2012  | 
     | 
     | 
    	    if (fgets(line, sizeof(line), stdin) == NULL) { | 
    
    
    2013  | 
     | 
     | 
    		if (feof(stdin) || ferror(stdin))  | 
    
    
    2014  | 
     | 
     | 
    		    quit();  | 
    
    
    2015  | 
     | 
     | 
    		break;  | 
    
    
    2016  | 
     | 
     | 
    	    }  | 
    
    
    2017  | 
     | 
     | 
    	}  | 
    
    
    2018  | 
     | 
     | 
    	if (line[0] == 0)  | 
    
    
    2019  | 
     | 
     | 
    	    break;  | 
    
    
    2020  | 
     | 
     | 
    	makeargv();  | 
    
    
    2021  | 
     | 
     | 
    	if (margv[0] == 0) { | 
    
    
    2022  | 
     | 
     | 
    	    break;  | 
    
    
    2023  | 
     | 
     | 
    	}  | 
    
    
    2024  | 
     | 
     | 
    	c = getcmd(margv[0]);  | 
    
    
    2025  | 
     | 
     | 
    	if (Ambiguous(c)) { | 
    
    
    2026  | 
     | 
     | 
    	    printf("?Ambiguous command\r\n"); | 
    
    
    2027  | 
     | 
     | 
    	    continue;  | 
    
    
    2028  | 
     | 
     | 
    	}  | 
    
    
    2029  | 
     | 
     | 
    	if (c == 0) { | 
    
    
    2030  | 
     | 
     | 
    	    printf("?Invalid command\r\n"); | 
    
    
    2031  | 
     | 
     | 
    	    continue;  | 
    
    
    2032  | 
     | 
     | 
    	}  | 
    
    
    2033  | 
     | 
     | 
    	if (c->needconnect && !connected) { | 
    
    
    2034  | 
     | 
     | 
    	    printf("?Need to be connected first.\r\n"); | 
    
    
    2035  | 
     | 
     | 
    	    continue;  | 
    
    
    2036  | 
     | 
     | 
    	}  | 
    
    
    2037  | 
     | 
     | 
    	if ((*c->handler)(margc, margv)) { | 
    
    
    2038  | 
     | 
     | 
    	    break;  | 
    
    
    2039  | 
     | 
     | 
    	}  | 
    
    
    2040  | 
     | 
     | 
        }  | 
    
    
    2041  | 
     | 
     | 
        if (!top) { | 
    
    
    2042  | 
     | 
     | 
    	if (!connected)  | 
    
    
    2043  | 
     | 
     | 
    	    longjmp(toplevel, 1);  | 
    
    
    2044  | 
     | 
     | 
    	setconnmode(0);  | 
    
    
    2045  | 
     | 
     | 
        }  | 
    
    
    2046  | 
     | 
     | 
    }  | 
    
    
    2047  | 
     | 
     | 
     | 
    
    
    2048  | 
     | 
     | 
    /*  | 
    
    
    2049  | 
     | 
     | 
     * Help command.  | 
    
    
    2050  | 
     | 
     | 
     */  | 
    
    
    2051  | 
     | 
     | 
    static int  | 
    
    
    2052  | 
     | 
     | 
    help(int argc, char *argv[])  | 
    
    
    2053  | 
     | 
     | 
    { | 
    
    
    2054  | 
     | 
     | 
    	Command *c;  | 
    
    
    2055  | 
     | 
     | 
     | 
    
    
    2056  | 
     | 
     | 
    	if (argc == 1) { | 
    
    
    2057  | 
     | 
     | 
    		printf("Commands may be abbreviated.  Commands are:\r\n\r\n"); | 
    
    
    2058  | 
     | 
     | 
    		for (c = cmdtab; c->name; c++)  | 
    
    
    2059  | 
     | 
     | 
    			if (c->help) { | 
    
    
    2060  | 
     | 
     | 
    				printf("%-*s\t%s\r\n", (int)HELPINDENT, c->name, | 
    
    
    2061  | 
     | 
     | 
    								    c->help);  | 
    
    
    2062  | 
     | 
     | 
    			}  | 
    
    
    2063  | 
     | 
     | 
    		return 0;  | 
    
    
    2064  | 
     | 
     | 
    	}  | 
    
    
    2065  | 
     | 
     | 
    	while (--argc > 0) { | 
    
    
    2066  | 
     | 
     | 
    		char *arg;  | 
    
    
    2067  | 
     | 
     | 
    		arg = *++argv;  | 
    
    
    2068  | 
     | 
     | 
    		c = getcmd(arg);  | 
    
    
    2069  | 
     | 
     | 
    		if (Ambiguous(c))  | 
    
    
    2070  | 
     | 
     | 
    			printf("?Ambiguous help command %s\r\n", arg); | 
    
    
    2071  | 
     | 
     | 
    		else if (c == NULL)  | 
    
    
    2072  | 
     | 
     | 
    			printf("?Invalid help command %s\r\n", arg); | 
    
    
    2073  | 
     | 
     | 
    		else  | 
    
    
    2074  | 
     | 
     | 
    			printf("%s\r\n", c->help); | 
    
    
    2075  | 
     | 
     | 
    	}  | 
    
    
    2076  | 
     | 
     | 
    	return 0;  | 
    
    
    2077  | 
     | 
     | 
    }  |