commands.c revision 47973
129088Smarkm/* 229088Smarkm * Copyright (c) 1988, 1990, 1993 329088Smarkm * The Regents of the University of California. All rights reserved. 429088Smarkm * 529088Smarkm * Redistribution and use in source and binary forms, with or without 629088Smarkm * modification, are permitted provided that the following conditions 729088Smarkm * are met: 829088Smarkm * 1. Redistributions of source code must retain the above copyright 929088Smarkm * notice, this list of conditions and the following disclaimer. 1029088Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1129088Smarkm * notice, this list of conditions and the following disclaimer in the 1229088Smarkm * documentation and/or other materials provided with the distribution. 1329088Smarkm * 3. All advertising materials mentioning features or use of this software 1429088Smarkm * must display the following acknowledgement: 1529088Smarkm * This product includes software developed by the University of 1629088Smarkm * California, Berkeley and its contributors. 1729088Smarkm * 4. Neither the name of the University nor the names of its contributors 1829088Smarkm * may be used to endorse or promote products derived from this software 1929088Smarkm * without specific prior written permission. 2029088Smarkm * 2129088Smarkm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2229088Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2329088Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2429088Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2529088Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2629088Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2729088Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2829088Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2929088Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3029088Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3129088Smarkm * SUCH DAMAGE. 3229088Smarkm */ 3329088Smarkm 3429088Smarkm#ifndef lint 3529181Smarkmstatic const char sccsid[] = "@(#)commands.c 8.4 (Berkeley) 5/30/95"; 3629088Smarkm#endif /* not lint */ 3729088Smarkm 3829088Smarkm#if defined(unix) 3929088Smarkm#include <sys/param.h> 4029088Smarkm#if defined(CRAY) || defined(sysV88) 4129088Smarkm#include <sys/types.h> 4229088Smarkm#endif 4329088Smarkm#include <sys/file.h> 4429088Smarkm#else 4529088Smarkm#include <sys/types.h> 4629088Smarkm#endif /* defined(unix) */ 4729088Smarkm#include <sys/socket.h> 4829088Smarkm#include <netinet/in.h> 4929088Smarkm#ifdef CRAY 5029088Smarkm#include <fcntl.h> 5129088Smarkm#endif /* CRAY */ 5229088Smarkm 5329088Smarkm#include <signal.h> 5429088Smarkm#include <netdb.h> 5529088Smarkm#include <ctype.h> 5629088Smarkm#include <pwd.h> 5729088Smarkm#include <varargs.h> 5829088Smarkm#include <errno.h> 5929181Smarkm#include <unistd.h> 6029181Smarkm#include <stdlib.h> 6129088Smarkm 6229088Smarkm#include <arpa/telnet.h> 6329088Smarkm 6429088Smarkm#include "general.h" 6529088Smarkm 6629088Smarkm#include "ring.h" 6729088Smarkm 6829088Smarkm#include "externs.h" 6929088Smarkm#include "defines.h" 7029088Smarkm#include "types.h" 7129088Smarkm 7229181Smarkm#if defined(AUTHENTICATION) 7329181Smarkm#include <libtelnet/auth.h> 7429181Smarkm#endif 7529181Smarkm#if defined(ENCRYPTION) 7629181Smarkm#include <libtelnet/encrypt.h> 7729181Smarkm#endif 7829181Smarkm 7929088Smarkm#if !defined(CRAY) && !defined(sysV88) 8029088Smarkm#include <netinet/in_systm.h> 8129088Smarkm# if (defined(vax) || defined(tahoe) || defined(hp300)) && !defined(ultrix) 8229088Smarkm# include <machine/endian.h> 8329088Smarkm# endif /* vax */ 8429088Smarkm#endif /* !defined(CRAY) && !defined(sysV88) */ 8529088Smarkm#include <netinet/ip.h> 8629088Smarkm 8729088Smarkm 8829088Smarkm#ifndef MAXHOSTNAMELEN 8929088Smarkm#define MAXHOSTNAMELEN 64 9029088Smarkm#endif MAXHOSTNAMELEN 9129088Smarkm 9229088Smarkm#if defined(IPPROTO_IP) && defined(IP_TOS) 9329088Smarkmint tos = -1; 9429088Smarkm#endif /* defined(IPPROTO_IP) && defined(IP_TOS) */ 9529088Smarkm 9629088Smarkmchar *hostname; 9729088Smarkmstatic char _hostname[MAXHOSTNAMELEN]; 9829088Smarkm 9929088Smarkmextern char *getenv(); 10029088Smarkm 10129088Smarkmextern int isprefix(); 10229088Smarkmextern char **genget(); 10329088Smarkmextern int Ambiguous(); 10429088Smarkm 10529181Smarkmstatic int help(int argc, char *argv[]); 10629181Smarkmstatic int call(); 10729181Smarkmstatic void cmdrc(char *m1, char *m2); 10829088Smarkm 10929181Smarkmint quit(void); 11029181Smarkm 11129088Smarkmtypedef struct { 11229088Smarkm char *name; /* command name */ 11329088Smarkm char *help; /* help string (NULL for no help) */ 11429088Smarkm int (*handler)(); /* routine which executes command */ 11529088Smarkm int needconnect; /* Do we need to be connected to execute? */ 11629088Smarkm} Command; 11729088Smarkm 11829088Smarkmstatic char line[256]; 11929088Smarkmstatic char saveline[256]; 12029088Smarkmstatic int margc; 12129088Smarkmstatic char *margv[20]; 12229088Smarkm 12329181Smarkm#if defined(SKEY) 12429181Smarkm#include <sys/wait.h> 12529181Smarkm#define PATH_SKEY "/usr/bin/key" 12629181Smarkm int 12729181Smarkmskey_calc(argc, argv) 12829181Smarkm int argc; 12929181Smarkm char **argv; 13029181Smarkm{ 13129181Smarkm int status; 13229181Smarkm 13329181Smarkm if(argc != 3) { 13429181Smarkm printf("%s sequence challenge\n", argv[0]); 13529181Smarkm return; 13629181Smarkm } 13729181Smarkm 13829181Smarkm switch(fork()) { 13929181Smarkm case 0: 14029181Smarkm execv(PATH_SKEY, argv); 14129181Smarkm exit (1); 14229181Smarkm case -1: 14329181Smarkm perror("fork"); 14429181Smarkm break; 14529181Smarkm default: 14629181Smarkm (void) wait(&status); 14729181Smarkm if (WIFEXITED(status)) 14829181Smarkm return (WEXITSTATUS(status)); 14929181Smarkm return (0); 15029181Smarkm } 15129181Smarkm} 15229181Smarkm#endif 15329181Smarkm 15429088Smarkm static void 15529088Smarkmmakeargv() 15629088Smarkm{ 15729088Smarkm register char *cp, *cp2, c; 15829088Smarkm register char **argp = margv; 15929088Smarkm 16029088Smarkm margc = 0; 16129088Smarkm cp = line; 16229088Smarkm if (*cp == '!') { /* Special case shell escape */ 16329088Smarkm strcpy(saveline, line); /* save for shell command */ 16429088Smarkm *argp++ = "!"; /* No room in string to get this */ 16529088Smarkm margc++; 16629088Smarkm cp++; 16729088Smarkm } 16829181Smarkm while ((c = *cp)) { 16929088Smarkm register int inquote = 0; 17029088Smarkm while (isspace(c)) 17129088Smarkm c = *++cp; 17229088Smarkm if (c == '\0') 17329088Smarkm break; 17429088Smarkm *argp++ = cp; 17529088Smarkm margc += 1; 17629088Smarkm for (cp2 = cp; c != '\0'; c = *++cp) { 17729088Smarkm if (inquote) { 17829088Smarkm if (c == inquote) { 17929088Smarkm inquote = 0; 18029088Smarkm continue; 18129088Smarkm } 18229088Smarkm } else { 18329088Smarkm if (c == '\\') { 18429088Smarkm if ((c = *++cp) == '\0') 18529088Smarkm break; 18629088Smarkm } else if (c == '"') { 18729088Smarkm inquote = '"'; 18829088Smarkm continue; 18929088Smarkm } else if (c == '\'') { 19029088Smarkm inquote = '\''; 19129088Smarkm continue; 19229088Smarkm } else if (isspace(c)) 19329088Smarkm break; 19429088Smarkm } 19529088Smarkm *cp2++ = c; 19629088Smarkm } 19729088Smarkm *cp2 = '\0'; 19829088Smarkm if (c == '\0') 19929088Smarkm break; 20029088Smarkm cp++; 20129088Smarkm } 20229088Smarkm *argp++ = 0; 20329088Smarkm} 20429088Smarkm 20529088Smarkm/* 20629088Smarkm * Make a character string into a number. 20729088Smarkm * 20829088Smarkm * Todo: 1. Could take random integers (12, 0x12, 012, 0b1). 20929088Smarkm */ 21029088Smarkm 21129181Smarkm static int 21229088Smarkmspecial(s) 21329088Smarkm register char *s; 21429088Smarkm{ 21529088Smarkm register char c; 21629088Smarkm char b; 21729088Smarkm 21829088Smarkm switch (*s) { 21929088Smarkm case '^': 22029088Smarkm b = *++s; 22129088Smarkm if (b == '?') { 22229088Smarkm c = b | 0x40; /* DEL */ 22329088Smarkm } else { 22429088Smarkm c = b & 0x1f; 22529088Smarkm } 22629088Smarkm break; 22729088Smarkm default: 22829088Smarkm c = *s; 22929088Smarkm break; 23029088Smarkm } 23129088Smarkm return c; 23229088Smarkm} 23329088Smarkm 23429088Smarkm/* 23529088Smarkm * Construct a control character sequence 23629088Smarkm * for a special character. 23729088Smarkm */ 23829088Smarkm static char * 23929088Smarkmcontrol(c) 24029088Smarkm register cc_t c; 24129088Smarkm{ 24229088Smarkm static char buf[5]; 24329088Smarkm /* 24429088Smarkm * The only way I could get the Sun 3.5 compiler 24529088Smarkm * to shut up about 24629088Smarkm * if ((unsigned int)c >= 0x80) 24729088Smarkm * was to assign "c" to an unsigned int variable... 24829088Smarkm * Arggg.... 24929088Smarkm */ 25029088Smarkm register unsigned int uic = (unsigned int)c; 25129088Smarkm 25229088Smarkm if (uic == 0x7f) 25329088Smarkm return ("^?"); 25429088Smarkm if (c == (cc_t)_POSIX_VDISABLE) { 25529088Smarkm return "off"; 25629088Smarkm } 25729088Smarkm if (uic >= 0x80) { 25829088Smarkm buf[0] = '\\'; 25929088Smarkm buf[1] = ((c>>6)&07) + '0'; 26029088Smarkm buf[2] = ((c>>3)&07) + '0'; 26129088Smarkm buf[3] = (c&07) + '0'; 26229088Smarkm buf[4] = 0; 26329088Smarkm } else if (uic >= 0x20) { 26429088Smarkm buf[0] = c; 26529088Smarkm buf[1] = 0; 26629088Smarkm } else { 26729088Smarkm buf[0] = '^'; 26829088Smarkm buf[1] = '@'+c; 26929088Smarkm buf[2] = 0; 27029088Smarkm } 27129088Smarkm return (buf); 27229088Smarkm} 27329088Smarkm 27429088Smarkm 27529088Smarkm 27629088Smarkm/* 27729088Smarkm * The following are data structures and routines for 27829088Smarkm * the "send" command. 27929088Smarkm * 28029088Smarkm */ 28129088Smarkm 28229088Smarkmstruct sendlist { 28329088Smarkm char *name; /* How user refers to it (case independent) */ 28429088Smarkm char *help; /* Help information (0 ==> no help) */ 28529088Smarkm int needconnect; /* Need to be connected */ 28629088Smarkm int narg; /* Number of arguments */ 28729088Smarkm int (*handler)(); /* Routine to perform (for special ops) */ 28829088Smarkm int nbyte; /* Number of bytes to send this command */ 28929088Smarkm int what; /* Character to be sent (<0 ==> special) */ 29029088Smarkm}; 29129088Smarkm 29229088Smarkm 29329088Smarkmstatic int 29429088Smarkm send_esc P((void)), 29529088Smarkm send_help P((void)), 29629088Smarkm send_docmd P((char *)), 29729088Smarkm send_dontcmd P((char *)), 29829088Smarkm send_willcmd P((char *)), 29929088Smarkm send_wontcmd P((char *)); 30029088Smarkm 30129088Smarkmstatic struct sendlist Sendlist[] = { 30229088Smarkm { "ao", "Send Telnet Abort output", 1, 0, 0, 2, AO }, 30329088Smarkm { "ayt", "Send Telnet 'Are You There'", 1, 0, 0, 2, AYT }, 30429088Smarkm { "brk", "Send Telnet Break", 1, 0, 0, 2, BREAK }, 30529088Smarkm { "break", 0, 1, 0, 0, 2, BREAK }, 30629088Smarkm { "ec", "Send Telnet Erase Character", 1, 0, 0, 2, EC }, 30729088Smarkm { "el", "Send Telnet Erase Line", 1, 0, 0, 2, EL }, 30829088Smarkm { "escape", "Send current escape character", 1, 0, send_esc, 1, 0 }, 30929088Smarkm { "ga", "Send Telnet 'Go Ahead' sequence", 1, 0, 0, 2, GA }, 31029088Smarkm { "ip", "Send Telnet Interrupt Process", 1, 0, 0, 2, IP }, 31129088Smarkm { "intp", 0, 1, 0, 0, 2, IP }, 31229088Smarkm { "interrupt", 0, 1, 0, 0, 2, IP }, 31329088Smarkm { "intr", 0, 1, 0, 0, 2, IP }, 31429088Smarkm { "nop", "Send Telnet 'No operation'", 1, 0, 0, 2, NOP }, 31529088Smarkm { "eor", "Send Telnet 'End of Record'", 1, 0, 0, 2, EOR }, 31629088Smarkm { "abort", "Send Telnet 'Abort Process'", 1, 0, 0, 2, ABORT }, 31729088Smarkm { "susp", "Send Telnet 'Suspend Process'", 1, 0, 0, 2, SUSP }, 31829088Smarkm { "eof", "Send Telnet End of File Character", 1, 0, 0, 2, xEOF }, 31929088Smarkm { "synch", "Perform Telnet 'Synch operation'", 1, 0, dosynch, 2, 0 }, 32029088Smarkm { "getstatus", "Send request for STATUS", 1, 0, get_status, 6, 0 }, 32129088Smarkm { "?", "Display send options", 0, 0, send_help, 0, 0 }, 32229088Smarkm { "help", 0, 0, 0, send_help, 0, 0 }, 32329088Smarkm { "do", 0, 0, 1, send_docmd, 3, 0 }, 32429088Smarkm { "dont", 0, 0, 1, send_dontcmd, 3, 0 }, 32529088Smarkm { "will", 0, 0, 1, send_willcmd, 3, 0 }, 32629088Smarkm { "wont", 0, 0, 1, send_wontcmd, 3, 0 }, 32729088Smarkm { 0 } 32829088Smarkm}; 32929088Smarkm 33029088Smarkm#define GETSEND(name) ((struct sendlist *) genget(name, (char **) Sendlist, \ 33129088Smarkm sizeof(struct sendlist))) 33229088Smarkm 33329088Smarkm static int 33429088Smarkmsendcmd(argc, argv) 33529088Smarkm int argc; 33629088Smarkm char **argv; 33729088Smarkm{ 33829088Smarkm int count; /* how many bytes we are going to need to send */ 33929088Smarkm int i; 34029088Smarkm struct sendlist *s; /* pointer to current command */ 34129088Smarkm int success = 0; 34229088Smarkm int needconnect = 0; 34329088Smarkm 34429088Smarkm if (argc < 2) { 34529088Smarkm printf("need at least one argument for 'send' command\n"); 34629088Smarkm printf("'send ?' for help\n"); 34729088Smarkm return 0; 34829088Smarkm } 34929088Smarkm /* 35029088Smarkm * First, validate all the send arguments. 35129088Smarkm * In addition, we see how much space we are going to need, and 35229088Smarkm * whether or not we will be doing a "SYNCH" operation (which 35329088Smarkm * flushes the network queue). 35429088Smarkm */ 35529088Smarkm count = 0; 35629088Smarkm for (i = 1; i < argc; i++) { 35729088Smarkm s = GETSEND(argv[i]); 35829088Smarkm if (s == 0) { 35929088Smarkm printf("Unknown send argument '%s'\n'send ?' for help.\n", 36029088Smarkm argv[i]); 36129088Smarkm return 0; 36229088Smarkm } else if (Ambiguous(s)) { 36329088Smarkm printf("Ambiguous send argument '%s'\n'send ?' for help.\n", 36429088Smarkm argv[i]); 36529088Smarkm return 0; 36629088Smarkm } 36729088Smarkm if (i + s->narg >= argc) { 36829088Smarkm fprintf(stderr, 36929088Smarkm "Need %d argument%s to 'send %s' command. 'send %s ?' for help.\n", 37029088Smarkm s->narg, s->narg == 1 ? "" : "s", s->name, s->name); 37129088Smarkm return 0; 37229088Smarkm } 37329088Smarkm count += s->nbyte; 37429088Smarkm if (s->handler == send_help) { 37529088Smarkm send_help(); 37629088Smarkm return 0; 37729088Smarkm } 37829088Smarkm 37929088Smarkm i += s->narg; 38029088Smarkm needconnect += s->needconnect; 38129088Smarkm } 38229088Smarkm if (!connected && needconnect) { 38329088Smarkm printf("?Need to be connected first.\n"); 38429088Smarkm printf("'send ?' for help\n"); 38529088Smarkm return 0; 38629088Smarkm } 38729088Smarkm /* Now, do we have enough room? */ 38829088Smarkm if (NETROOM() < count) { 38929088Smarkm printf("There is not enough room in the buffer TO the network\n"); 39029088Smarkm printf("to process your request. Nothing will be done.\n"); 39129088Smarkm printf("('send synch' will throw away most data in the network\n"); 39229088Smarkm printf("buffer, if this might help.)\n"); 39329088Smarkm return 0; 39429088Smarkm } 39529088Smarkm /* OK, they are all OK, now go through again and actually send */ 39629088Smarkm count = 0; 39729088Smarkm for (i = 1; i < argc; i++) { 39829088Smarkm if ((s = GETSEND(argv[i])) == 0) { 39929088Smarkm fprintf(stderr, "Telnet 'send' error - argument disappeared!\n"); 40029088Smarkm (void) quit(); 40129088Smarkm /*NOTREACHED*/ 40229088Smarkm } 40329088Smarkm if (s->handler) { 40429088Smarkm count++; 40529088Smarkm success += (*s->handler)((s->narg > 0) ? argv[i+1] : 0, 40629088Smarkm (s->narg > 1) ? argv[i+2] : 0); 40729088Smarkm i += s->narg; 40829088Smarkm } else { 40929088Smarkm NET2ADD(IAC, s->what); 41029088Smarkm printoption("SENT", IAC, s->what); 41129088Smarkm } 41229088Smarkm } 41329088Smarkm return (count == success); 41429088Smarkm} 41529088Smarkm 41629088Smarkm static int 41729088Smarkmsend_esc() 41829088Smarkm{ 41929088Smarkm NETADD(escape); 42029088Smarkm return 1; 42129088Smarkm} 42229088Smarkm 42329088Smarkm static int 42429088Smarkmsend_docmd(name) 42529088Smarkm char *name; 42629088Smarkm{ 42729088Smarkm return(send_tncmd(send_do, "do", name)); 42829088Smarkm} 42929088Smarkm 43029088Smarkm static int 43129088Smarkmsend_dontcmd(name) 43229088Smarkm char *name; 43329088Smarkm{ 43429088Smarkm return(send_tncmd(send_dont, "dont", name)); 43529088Smarkm} 43629088Smarkm static int 43729088Smarkmsend_willcmd(name) 43829088Smarkm char *name; 43929088Smarkm{ 44029088Smarkm return(send_tncmd(send_will, "will", name)); 44129088Smarkm} 44229088Smarkm static int 44329088Smarkmsend_wontcmd(name) 44429088Smarkm char *name; 44529088Smarkm{ 44629088Smarkm return(send_tncmd(send_wont, "wont", name)); 44729088Smarkm} 44829088Smarkm 44929088Smarkm int 45029088Smarkmsend_tncmd(func, cmd, name) 45129088Smarkm void (*func)(); 45229088Smarkm char *cmd, *name; 45329088Smarkm{ 45429088Smarkm char **cpp; 45529088Smarkm extern char *telopts[]; 45629088Smarkm register int val = 0; 45729088Smarkm 45829088Smarkm if (isprefix(name, "help") || isprefix(name, "?")) { 45929088Smarkm register int col, len; 46029088Smarkm 46129088Smarkm printf("Usage: send %s <value|option>\n", cmd); 46229088Smarkm printf("\"value\" must be from 0 to 255\n"); 46329088Smarkm printf("Valid options are:\n\t"); 46429088Smarkm 46529088Smarkm col = 8; 46629088Smarkm for (cpp = telopts; *cpp; cpp++) { 46729088Smarkm len = strlen(*cpp) + 3; 46829088Smarkm if (col + len > 65) { 46929088Smarkm printf("\n\t"); 47029088Smarkm col = 8; 47129088Smarkm } 47229088Smarkm printf(" \"%s\"", *cpp); 47329088Smarkm col += len; 47429088Smarkm } 47529088Smarkm printf("\n"); 47629088Smarkm return 0; 47729088Smarkm } 47829088Smarkm cpp = (char **)genget(name, telopts, sizeof(char *)); 47929088Smarkm if (Ambiguous(cpp)) { 48029088Smarkm fprintf(stderr,"'%s': ambiguous argument ('send %s ?' for help).\n", 48129088Smarkm name, cmd); 48229088Smarkm return 0; 48329088Smarkm } 48429088Smarkm if (cpp) { 48529088Smarkm val = cpp - telopts; 48629088Smarkm } else { 48729088Smarkm register char *cp = name; 48829088Smarkm 48929088Smarkm while (*cp >= '0' && *cp <= '9') { 49029088Smarkm val *= 10; 49129088Smarkm val += *cp - '0'; 49229088Smarkm cp++; 49329088Smarkm } 49429088Smarkm if (*cp != 0) { 49529088Smarkm fprintf(stderr, "'%s': unknown argument ('send %s ?' for help).\n", 49629088Smarkm name, cmd); 49729088Smarkm return 0; 49829088Smarkm } else if (val < 0 || val > 255) { 49929088Smarkm fprintf(stderr, "'%s': bad value ('send %s ?' for help).\n", 50029088Smarkm name, cmd); 50129088Smarkm return 0; 50229088Smarkm } 50329088Smarkm } 50429088Smarkm if (!connected) { 50529088Smarkm printf("?Need to be connected first.\n"); 50629088Smarkm return 0; 50729088Smarkm } 50829088Smarkm (*func)(val, 1); 50929088Smarkm return 1; 51029088Smarkm} 51129088Smarkm 51229088Smarkm static int 51329088Smarkmsend_help() 51429088Smarkm{ 51529088Smarkm struct sendlist *s; /* pointer to current command */ 51629088Smarkm for (s = Sendlist; s->name; s++) { 51729088Smarkm if (s->help) 51829088Smarkm printf("%-15s %s\n", s->name, s->help); 51929088Smarkm } 52029088Smarkm return(0); 52129088Smarkm} 52229088Smarkm 52329088Smarkm/* 52429088Smarkm * The following are the routines and data structures referred 52529088Smarkm * to by the arguments to the "toggle" command. 52629088Smarkm */ 52729088Smarkm 52829088Smarkm static int 52929088Smarkmlclchars() 53029088Smarkm{ 53129088Smarkm donelclchars = 1; 53229088Smarkm return 1; 53329088Smarkm} 53429088Smarkm 53529088Smarkm static int 53629088Smarkmtogdebug() 53729088Smarkm{ 53829088Smarkm#ifndef NOT43 53929088Smarkm if (net > 0 && 54029088Smarkm (SetSockOpt(net, SOL_SOCKET, SO_DEBUG, debug)) < 0) { 54129088Smarkm perror("setsockopt (SO_DEBUG)"); 54229088Smarkm } 54329088Smarkm#else /* NOT43 */ 54429088Smarkm if (debug) { 54529181Smarkm if (net > 0 && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 1) < 0) 54629088Smarkm perror("setsockopt (SO_DEBUG)"); 54729088Smarkm } else 54829088Smarkm printf("Cannot turn off socket debugging\n"); 54929088Smarkm#endif /* NOT43 */ 55029088Smarkm return 1; 55129088Smarkm} 55229088Smarkm 55329088Smarkm 55429088Smarkm static int 55529088Smarkmtogcrlf() 55629088Smarkm{ 55729088Smarkm if (crlf) { 55829088Smarkm printf("Will send carriage returns as telnet <CR><LF>.\n"); 55929088Smarkm } else { 56029088Smarkm printf("Will send carriage returns as telnet <CR><NUL>.\n"); 56129088Smarkm } 56229088Smarkm return 1; 56329088Smarkm} 56429088Smarkm 56529088Smarkmint binmode; 56629088Smarkm 56729088Smarkm static int 56829088Smarkmtogbinary(val) 56929088Smarkm int val; 57029088Smarkm{ 57129088Smarkm donebinarytoggle = 1; 57229088Smarkm 57329088Smarkm if (val >= 0) { 57429088Smarkm binmode = val; 57529088Smarkm } else { 57629088Smarkm if (my_want_state_is_will(TELOPT_BINARY) && 57729088Smarkm my_want_state_is_do(TELOPT_BINARY)) { 57829088Smarkm binmode = 1; 57929088Smarkm } else if (my_want_state_is_wont(TELOPT_BINARY) && 58029088Smarkm my_want_state_is_dont(TELOPT_BINARY)) { 58129088Smarkm binmode = 0; 58229088Smarkm } 58329088Smarkm val = binmode ? 0 : 1; 58429088Smarkm } 58529088Smarkm 58629088Smarkm if (val == 1) { 58729088Smarkm if (my_want_state_is_will(TELOPT_BINARY) && 58829088Smarkm my_want_state_is_do(TELOPT_BINARY)) { 58929088Smarkm printf("Already operating in binary mode with remote host.\n"); 59029088Smarkm } else { 59129088Smarkm printf("Negotiating binary mode with remote host.\n"); 59229088Smarkm tel_enter_binary(3); 59329088Smarkm } 59429088Smarkm } else { 59529088Smarkm if (my_want_state_is_wont(TELOPT_BINARY) && 59629088Smarkm my_want_state_is_dont(TELOPT_BINARY)) { 59729088Smarkm printf("Already in network ascii mode with remote host.\n"); 59829088Smarkm } else { 59929088Smarkm printf("Negotiating network ascii mode with remote host.\n"); 60029088Smarkm tel_leave_binary(3); 60129088Smarkm } 60229088Smarkm } 60329088Smarkm return 1; 60429088Smarkm} 60529088Smarkm 60629088Smarkm static int 60729088Smarkmtogrbinary(val) 60829088Smarkm int val; 60929088Smarkm{ 61029088Smarkm donebinarytoggle = 1; 61129088Smarkm 61229088Smarkm if (val == -1) 61329088Smarkm val = my_want_state_is_do(TELOPT_BINARY) ? 0 : 1; 61429088Smarkm 61529088Smarkm if (val == 1) { 61629088Smarkm if (my_want_state_is_do(TELOPT_BINARY)) { 61729088Smarkm printf("Already receiving in binary mode.\n"); 61829088Smarkm } else { 61929088Smarkm printf("Negotiating binary mode on input.\n"); 62029088Smarkm tel_enter_binary(1); 62129088Smarkm } 62229088Smarkm } else { 62329088Smarkm if (my_want_state_is_dont(TELOPT_BINARY)) { 62429088Smarkm printf("Already receiving in network ascii mode.\n"); 62529088Smarkm } else { 62629088Smarkm printf("Negotiating network ascii mode on input.\n"); 62729088Smarkm tel_leave_binary(1); 62829088Smarkm } 62929088Smarkm } 63029088Smarkm return 1; 63129088Smarkm} 63229088Smarkm 63329088Smarkm static int 63429088Smarkmtogxbinary(val) 63529088Smarkm int val; 63629088Smarkm{ 63729088Smarkm donebinarytoggle = 1; 63829088Smarkm 63929088Smarkm if (val == -1) 64029088Smarkm val = my_want_state_is_will(TELOPT_BINARY) ? 0 : 1; 64129088Smarkm 64229088Smarkm if (val == 1) { 64329088Smarkm if (my_want_state_is_will(TELOPT_BINARY)) { 64429088Smarkm printf("Already transmitting in binary mode.\n"); 64529088Smarkm } else { 64629088Smarkm printf("Negotiating binary mode on output.\n"); 64729088Smarkm tel_enter_binary(2); 64829088Smarkm } 64929088Smarkm } else { 65029088Smarkm if (my_want_state_is_wont(TELOPT_BINARY)) { 65129088Smarkm printf("Already transmitting in network ascii mode.\n"); 65229088Smarkm } else { 65329088Smarkm printf("Negotiating network ascii mode on output.\n"); 65429088Smarkm tel_leave_binary(2); 65529088Smarkm } 65629088Smarkm } 65729088Smarkm return 1; 65829088Smarkm} 65929088Smarkm 66029088Smarkm 66129088Smarkmstatic int togglehelp P((void)); 66229088Smarkm#if defined(AUTHENTICATION) 66329088Smarkmextern int auth_togdebug P((int)); 66429088Smarkm#endif 66529088Smarkm#ifdef ENCRYPTION 66629088Smarkmextern int EncryptAutoEnc P((int)); 66729088Smarkmextern int EncryptAutoDec P((int)); 66829088Smarkmextern int EncryptDebug P((int)); 66929088Smarkmextern int EncryptVerbose P((int)); 67029088Smarkm#endif /* ENCRYPTION */ 67129088Smarkm 67229088Smarkmstruct togglelist { 67329088Smarkm char *name; /* name of toggle */ 67429088Smarkm char *help; /* help message */ 67529088Smarkm int (*handler)(); /* routine to do actual setting */ 67629088Smarkm int *variable; 67729088Smarkm char *actionexplanation; 67829088Smarkm}; 67929088Smarkm 68029088Smarkmstatic struct togglelist Togglelist[] = { 68129088Smarkm { "autoflush", 68229088Smarkm "flushing of output when sending interrupt characters", 68329088Smarkm 0, 68429088Smarkm &autoflush, 68529088Smarkm "flush output when sending interrupt characters" }, 68629088Smarkm { "autosynch", 68729088Smarkm "automatic sending of interrupt characters in urgent mode", 68829088Smarkm 0, 68929088Smarkm &autosynch, 69029088Smarkm "send interrupt characters in urgent mode" }, 69129088Smarkm#if defined(AUTHENTICATION) 69229088Smarkm { "autologin", 69329088Smarkm "automatic sending of login and/or authentication info", 69429088Smarkm 0, 69529088Smarkm &autologin, 69629088Smarkm "send login name and/or authentication information" }, 69729088Smarkm { "authdebug", 69829088Smarkm "Toggle authentication debugging", 69929088Smarkm auth_togdebug, 70029088Smarkm 0, 70129088Smarkm "print authentication debugging information" }, 70229088Smarkm#endif 70329088Smarkm#ifdef ENCRYPTION 70429088Smarkm { "autoencrypt", 70529088Smarkm "automatic encryption of data stream", 70629088Smarkm EncryptAutoEnc, 70729088Smarkm 0, 70829088Smarkm "automatically encrypt output" }, 70929088Smarkm { "autodecrypt", 71029088Smarkm "automatic decryption of data stream", 71129088Smarkm EncryptAutoDec, 71229088Smarkm 0, 71329088Smarkm "automatically decrypt input" }, 71429088Smarkm { "verbose_encrypt", 71529088Smarkm "Toggle verbose encryption output", 71629088Smarkm EncryptVerbose, 71729088Smarkm 0, 71829088Smarkm "print verbose encryption output" }, 71929088Smarkm { "encdebug", 72029088Smarkm "Toggle encryption debugging", 72129088Smarkm EncryptDebug, 72229088Smarkm 0, 72329088Smarkm "print encryption debugging information" }, 72429088Smarkm#endif /* ENCRYPTION */ 72529088Smarkm { "skiprc", 72629088Smarkm "don't read ~/.telnetrc file", 72729088Smarkm 0, 72829088Smarkm &skiprc, 72929088Smarkm "skip reading of ~/.telnetrc file" }, 73029088Smarkm { "binary", 73129088Smarkm "sending and receiving of binary data", 73229088Smarkm togbinary, 73329088Smarkm 0, 73429088Smarkm 0 }, 73529088Smarkm { "inbinary", 73629088Smarkm "receiving of binary data", 73729088Smarkm togrbinary, 73829088Smarkm 0, 73929088Smarkm 0 }, 74029088Smarkm { "outbinary", 74129088Smarkm "sending of binary data", 74229088Smarkm togxbinary, 74329088Smarkm 0, 74429088Smarkm 0 }, 74529088Smarkm { "crlf", 74629088Smarkm "sending carriage returns as telnet <CR><LF>", 74729088Smarkm togcrlf, 74829088Smarkm &crlf, 74929088Smarkm 0 }, 75029088Smarkm { "crmod", 75129088Smarkm "mapping of received carriage returns", 75229088Smarkm 0, 75329088Smarkm &crmod, 75429088Smarkm "map carriage return on output" }, 75529088Smarkm { "localchars", 75629088Smarkm "local recognition of certain control characters", 75729088Smarkm lclchars, 75829088Smarkm &localchars, 75929088Smarkm "recognize certain control characters" }, 76029088Smarkm { " ", "", 0 }, /* empty line */ 76129088Smarkm#if defined(unix) && defined(TN3270) 76229088Smarkm { "apitrace", 76329088Smarkm "(debugging) toggle tracing of API transactions", 76429088Smarkm 0, 76529088Smarkm &apitrace, 76629088Smarkm "trace API transactions" }, 76729088Smarkm { "cursesdata", 76829088Smarkm "(debugging) toggle printing of hexadecimal curses data", 76929088Smarkm 0, 77029088Smarkm &cursesdata, 77129088Smarkm "print hexadecimal representation of curses data" }, 77229088Smarkm#endif /* defined(unix) && defined(TN3270) */ 77329088Smarkm { "debug", 77429088Smarkm "debugging", 77529088Smarkm togdebug, 77629088Smarkm &debug, 77729088Smarkm "turn on socket level debugging" }, 77829088Smarkm { "netdata", 77929088Smarkm "printing of hexadecimal network data (debugging)", 78029088Smarkm 0, 78129088Smarkm &netdata, 78229088Smarkm "print hexadecimal representation of network traffic" }, 78329088Smarkm { "prettydump", 78429088Smarkm "output of \"netdata\" to user readable format (debugging)", 78529088Smarkm 0, 78629088Smarkm &prettydump, 78729088Smarkm "print user readable output for \"netdata\"" }, 78829088Smarkm { "options", 78929088Smarkm "viewing of options processing (debugging)", 79029088Smarkm 0, 79129088Smarkm &showoptions, 79229088Smarkm "show option processing" }, 79329088Smarkm#if defined(unix) 79429088Smarkm { "termdata", 79529088Smarkm "(debugging) toggle printing of hexadecimal terminal data", 79629088Smarkm 0, 79729088Smarkm &termdata, 79829088Smarkm "print hexadecimal representation of terminal traffic" }, 79929088Smarkm#endif /* defined(unix) */ 80029088Smarkm { "?", 80129088Smarkm 0, 80229088Smarkm togglehelp }, 80329088Smarkm { "help", 80429088Smarkm 0, 80529088Smarkm togglehelp }, 80629088Smarkm { 0 } 80729088Smarkm}; 80829088Smarkm 80929088Smarkm static int 81029088Smarkmtogglehelp() 81129088Smarkm{ 81229088Smarkm struct togglelist *c; 81329088Smarkm 81429088Smarkm for (c = Togglelist; c->name; c++) { 81529088Smarkm if (c->help) { 81629088Smarkm if (*c->help) 81729088Smarkm printf("%-15s toggle %s\n", c->name, c->help); 81829088Smarkm else 81929088Smarkm printf("\n"); 82029088Smarkm } 82129088Smarkm } 82229088Smarkm printf("\n"); 82329088Smarkm printf("%-15s %s\n", "?", "display help information"); 82429088Smarkm return 0; 82529088Smarkm} 82629088Smarkm 82729088Smarkm static void 82829088Smarkmsettogglehelp(set) 82929088Smarkm int set; 83029088Smarkm{ 83129088Smarkm struct togglelist *c; 83229088Smarkm 83329088Smarkm for (c = Togglelist; c->name; c++) { 83429088Smarkm if (c->help) { 83529088Smarkm if (*c->help) 83629088Smarkm printf("%-15s %s %s\n", c->name, set ? "enable" : "disable", 83729088Smarkm c->help); 83829088Smarkm else 83929088Smarkm printf("\n"); 84029088Smarkm } 84129088Smarkm } 84229088Smarkm} 84329088Smarkm 84429088Smarkm#define GETTOGGLE(name) (struct togglelist *) \ 84529088Smarkm genget(name, (char **) Togglelist, sizeof(struct togglelist)) 84629088Smarkm 84729088Smarkm static int 84829088Smarkmtoggle(argc, argv) 84929088Smarkm int argc; 85029088Smarkm char *argv[]; 85129088Smarkm{ 85229088Smarkm int retval = 1; 85329088Smarkm char *name; 85429088Smarkm struct togglelist *c; 85529088Smarkm 85629088Smarkm if (argc < 2) { 85729088Smarkm fprintf(stderr, 85829088Smarkm "Need an argument to 'toggle' command. 'toggle ?' for help.\n"); 85929088Smarkm return 0; 86029088Smarkm } 86129088Smarkm argc--; 86229088Smarkm argv++; 86329088Smarkm while (argc--) { 86429088Smarkm name = *argv++; 86529088Smarkm c = GETTOGGLE(name); 86629088Smarkm if (Ambiguous(c)) { 86729088Smarkm fprintf(stderr, "'%s': ambiguous argument ('toggle ?' for help).\n", 86829088Smarkm name); 86929088Smarkm return 0; 87029088Smarkm } else if (c == 0) { 87129088Smarkm fprintf(stderr, "'%s': unknown argument ('toggle ?' for help).\n", 87229088Smarkm name); 87329088Smarkm return 0; 87429088Smarkm } else { 87529088Smarkm if (c->variable) { 87629088Smarkm *c->variable = !*c->variable; /* invert it */ 87729088Smarkm if (c->actionexplanation) { 87829088Smarkm printf("%s %s.\n", *c->variable? "Will" : "Won't", 87929088Smarkm c->actionexplanation); 88029088Smarkm } 88129088Smarkm } 88229088Smarkm if (c->handler) { 88329088Smarkm retval &= (*c->handler)(-1); 88429088Smarkm } 88529088Smarkm } 88629088Smarkm } 88729088Smarkm return retval; 88829088Smarkm} 88929088Smarkm 89029088Smarkm/* 89129088Smarkm * The following perform the "set" command. 89229088Smarkm */ 89329088Smarkm 89429088Smarkm#ifdef USE_TERMIO 89529088Smarkmstruct termio new_tc = { 0 }; 89629088Smarkm#endif 89729088Smarkm 89829088Smarkmstruct setlist { 89929088Smarkm char *name; /* name */ 90029088Smarkm char *help; /* help information */ 90129088Smarkm void (*handler)(); 90229088Smarkm cc_t *charp; /* where it is located at */ 90329088Smarkm}; 90429088Smarkm 90529088Smarkmstatic struct setlist Setlist[] = { 90629088Smarkm#ifdef KLUDGELINEMODE 90729088Smarkm { "echo", "character to toggle local echoing on/off", 0, &echoc }, 90829088Smarkm#endif 90929088Smarkm { "escape", "character to escape back to telnet command mode", 0, &escape }, 91029088Smarkm { "rlogin", "rlogin escape character", 0, &rlogin }, 91129088Smarkm { "tracefile", "file to write trace information to", SetNetTrace, (cc_t *)NetTraceFile}, 91229088Smarkm { " ", "" }, 91329088Smarkm { " ", "The following need 'localchars' to be toggled true", 0, 0 }, 91429088Smarkm { "flushoutput", "character to cause an Abort Output", 0, termFlushCharp }, 91529088Smarkm { "interrupt", "character to cause an Interrupt Process", 0, termIntCharp }, 91629088Smarkm { "quit", "character to cause an Abort process", 0, termQuitCharp }, 91729088Smarkm { "eof", "character to cause an EOF ", 0, termEofCharp }, 91829088Smarkm { " ", "" }, 91929088Smarkm { " ", "The following are for local editing in linemode", 0, 0 }, 92029088Smarkm { "erase", "character to use to erase a character", 0, termEraseCharp }, 92129088Smarkm { "kill", "character to use to erase a line", 0, termKillCharp }, 92229088Smarkm { "lnext", "character to use for literal next", 0, termLiteralNextCharp }, 92329088Smarkm { "susp", "character to cause a Suspend Process", 0, termSuspCharp }, 92429088Smarkm { "reprint", "character to use for line reprint", 0, termRprntCharp }, 92529088Smarkm { "worderase", "character to use to erase a word", 0, termWerasCharp }, 92629088Smarkm { "start", "character to use for XON", 0, termStartCharp }, 92729088Smarkm { "stop", "character to use for XOFF", 0, termStopCharp }, 92829088Smarkm { "forw1", "alternate end of line character", 0, termForw1Charp }, 92929088Smarkm { "forw2", "alternate end of line character", 0, termForw2Charp }, 93029088Smarkm { "ayt", "alternate AYT character", 0, termAytCharp }, 93129088Smarkm { 0 } 93229088Smarkm}; 93329088Smarkm 93429088Smarkm#if defined(CRAY) && !defined(__STDC__) 93529088Smarkm/* Work around compiler bug in pcc 4.1.5 */ 93629088Smarkm void 93729088Smarkm_setlist_init() 93829088Smarkm{ 93929088Smarkm#ifndef KLUDGELINEMODE 94029088Smarkm#define N 5 94129088Smarkm#else 94229088Smarkm#define N 6 94329088Smarkm#endif 94429088Smarkm Setlist[N+0].charp = &termFlushChar; 94529088Smarkm Setlist[N+1].charp = &termIntChar; 94629088Smarkm Setlist[N+2].charp = &termQuitChar; 94729088Smarkm Setlist[N+3].charp = &termEofChar; 94829088Smarkm Setlist[N+6].charp = &termEraseChar; 94929088Smarkm Setlist[N+7].charp = &termKillChar; 95029088Smarkm Setlist[N+8].charp = &termLiteralNextChar; 95129088Smarkm Setlist[N+9].charp = &termSuspChar; 95229088Smarkm Setlist[N+10].charp = &termRprntChar; 95329088Smarkm Setlist[N+11].charp = &termWerasChar; 95429088Smarkm Setlist[N+12].charp = &termStartChar; 95529088Smarkm Setlist[N+13].charp = &termStopChar; 95629088Smarkm Setlist[N+14].charp = &termForw1Char; 95729088Smarkm Setlist[N+15].charp = &termForw2Char; 95829088Smarkm Setlist[N+16].charp = &termAytChar; 95929088Smarkm#undef N 96029088Smarkm} 96129088Smarkm#endif /* defined(CRAY) && !defined(__STDC__) */ 96229088Smarkm 96329088Smarkm static struct setlist * 96429088Smarkmgetset(name) 96529088Smarkm char *name; 96629088Smarkm{ 96729088Smarkm return (struct setlist *) 96829088Smarkm genget(name, (char **) Setlist, sizeof(struct setlist)); 96929088Smarkm} 97029088Smarkm 97129088Smarkm void 97229088Smarkmset_escape_char(s) 97329088Smarkm char *s; 97429088Smarkm{ 97529088Smarkm if (rlogin != _POSIX_VDISABLE) { 97629088Smarkm rlogin = (s && *s) ? special(s) : _POSIX_VDISABLE; 97729088Smarkm printf("Telnet rlogin escape character is '%s'.\n", 97829088Smarkm control(rlogin)); 97929088Smarkm } else { 98029088Smarkm escape = (s && *s) ? special(s) : _POSIX_VDISABLE; 98129088Smarkm printf("Telnet escape character is '%s'.\n", control(escape)); 98229088Smarkm } 98329088Smarkm} 98429088Smarkm 98529088Smarkm static int 98629088Smarkmsetcmd(argc, argv) 98729088Smarkm int argc; 98829088Smarkm char *argv[]; 98929088Smarkm{ 99029088Smarkm int value; 99129088Smarkm struct setlist *ct; 99229088Smarkm struct togglelist *c; 99329088Smarkm 99429088Smarkm if (argc < 2 || argc > 3) { 99529088Smarkm printf("Format is 'set Name Value'\n'set ?' for help.\n"); 99629088Smarkm return 0; 99729088Smarkm } 99829088Smarkm if ((argc == 2) && (isprefix(argv[1], "?") || isprefix(argv[1], "help"))) { 99929088Smarkm for (ct = Setlist; ct->name; ct++) 100029088Smarkm printf("%-15s %s\n", ct->name, ct->help); 100129088Smarkm printf("\n"); 100229088Smarkm settogglehelp(1); 100329088Smarkm printf("%-15s %s\n", "?", "display help information"); 100429088Smarkm return 0; 100529088Smarkm } 100629088Smarkm 100729088Smarkm ct = getset(argv[1]); 100829088Smarkm if (ct == 0) { 100929088Smarkm c = GETTOGGLE(argv[1]); 101029088Smarkm if (c == 0) { 101129088Smarkm fprintf(stderr, "'%s': unknown argument ('set ?' for help).\n", 101229088Smarkm argv[1]); 101329088Smarkm return 0; 101429088Smarkm } else if (Ambiguous(c)) { 101529088Smarkm fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n", 101629088Smarkm argv[1]); 101729088Smarkm return 0; 101829088Smarkm } 101929088Smarkm if (c->variable) { 102029088Smarkm if ((argc == 2) || (strcmp("on", argv[2]) == 0)) 102129088Smarkm *c->variable = 1; 102229088Smarkm else if (strcmp("off", argv[2]) == 0) 102329088Smarkm *c->variable = 0; 102429088Smarkm else { 102529088Smarkm printf("Format is 'set togglename [on|off]'\n'set ?' for help.\n"); 102629088Smarkm return 0; 102729088Smarkm } 102829088Smarkm if (c->actionexplanation) { 102929088Smarkm printf("%s %s.\n", *c->variable? "Will" : "Won't", 103029088Smarkm c->actionexplanation); 103129088Smarkm } 103229088Smarkm } 103329088Smarkm if (c->handler) 103429088Smarkm (*c->handler)(1); 103529088Smarkm } else if (argc != 3) { 103629088Smarkm printf("Format is 'set Name Value'\n'set ?' for help.\n"); 103729088Smarkm return 0; 103829088Smarkm } else if (Ambiguous(ct)) { 103929088Smarkm fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n", 104029088Smarkm argv[1]); 104129088Smarkm return 0; 104229088Smarkm } else if (ct->handler) { 104329088Smarkm (*ct->handler)(argv[2]); 104429088Smarkm printf("%s set to \"%s\".\n", ct->name, (char *)ct->charp); 104529088Smarkm } else { 104629088Smarkm if (strcmp("off", argv[2])) { 104729088Smarkm value = special(argv[2]); 104829088Smarkm } else { 104929088Smarkm value = _POSIX_VDISABLE; 105029088Smarkm } 105129088Smarkm *(ct->charp) = (cc_t)value; 105229088Smarkm printf("%s character is '%s'.\n", ct->name, control(*(ct->charp))); 105329088Smarkm } 105429088Smarkm slc_check(); 105529088Smarkm return 1; 105629088Smarkm} 105729088Smarkm 105829088Smarkm static int 105929088Smarkmunsetcmd(argc, argv) 106029088Smarkm int argc; 106129088Smarkm char *argv[]; 106229088Smarkm{ 106329088Smarkm struct setlist *ct; 106429088Smarkm struct togglelist *c; 106529088Smarkm register char *name; 106629088Smarkm 106729088Smarkm if (argc < 2) { 106829088Smarkm fprintf(stderr, 106929088Smarkm "Need an argument to 'unset' command. 'unset ?' for help.\n"); 107029088Smarkm return 0; 107129088Smarkm } 107229088Smarkm if (isprefix(argv[1], "?") || isprefix(argv[1], "help")) { 107329088Smarkm for (ct = Setlist; ct->name; ct++) 107429088Smarkm printf("%-15s %s\n", ct->name, ct->help); 107529088Smarkm printf("\n"); 107629088Smarkm settogglehelp(0); 107729088Smarkm printf("%-15s %s\n", "?", "display help information"); 107829088Smarkm return 0; 107929088Smarkm } 108029088Smarkm 108129088Smarkm argc--; 108229088Smarkm argv++; 108329088Smarkm while (argc--) { 108429088Smarkm name = *argv++; 108529088Smarkm ct = getset(name); 108629088Smarkm if (ct == 0) { 108729088Smarkm c = GETTOGGLE(name); 108829088Smarkm if (c == 0) { 108929088Smarkm fprintf(stderr, "'%s': unknown argument ('unset ?' for help).\n", 109029088Smarkm name); 109129088Smarkm return 0; 109229088Smarkm } else if (Ambiguous(c)) { 109329088Smarkm fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n", 109429088Smarkm name); 109529088Smarkm return 0; 109629088Smarkm } 109729088Smarkm if (c->variable) { 109829088Smarkm *c->variable = 0; 109929088Smarkm if (c->actionexplanation) { 110029088Smarkm printf("%s %s.\n", *c->variable? "Will" : "Won't", 110129088Smarkm c->actionexplanation); 110229088Smarkm } 110329088Smarkm } 110429088Smarkm if (c->handler) 110529088Smarkm (*c->handler)(0); 110629088Smarkm } else if (Ambiguous(ct)) { 110729088Smarkm fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n", 110829088Smarkm name); 110929088Smarkm return 0; 111029088Smarkm } else if (ct->handler) { 111129088Smarkm (*ct->handler)(0); 111229088Smarkm printf("%s reset to \"%s\".\n", ct->name, (char *)ct->charp); 111329088Smarkm } else { 111429088Smarkm *(ct->charp) = _POSIX_VDISABLE; 111529088Smarkm printf("%s character is '%s'.\n", ct->name, control(*(ct->charp))); 111629088Smarkm } 111729088Smarkm } 111829088Smarkm return 1; 111929088Smarkm} 112029088Smarkm 112129088Smarkm/* 112229088Smarkm * The following are the data structures and routines for the 112329088Smarkm * 'mode' command. 112429088Smarkm */ 112529088Smarkm#ifdef KLUDGELINEMODE 112629088Smarkmextern int kludgelinemode; 112729088Smarkm 112847973Sru static int 112929088Smarkmdokludgemode() 113029088Smarkm{ 113129088Smarkm kludgelinemode = 1; 113229088Smarkm send_wont(TELOPT_LINEMODE, 1); 113329088Smarkm send_dont(TELOPT_SGA, 1); 113429088Smarkm send_dont(TELOPT_ECHO, 1); 113529088Smarkm} 113629088Smarkm#endif 113729088Smarkm 113829088Smarkm static int 113929088Smarkmdolinemode() 114029088Smarkm{ 114129088Smarkm#ifdef KLUDGELINEMODE 114229088Smarkm if (kludgelinemode) 114329088Smarkm send_dont(TELOPT_SGA, 1); 114429088Smarkm#endif 114529088Smarkm send_will(TELOPT_LINEMODE, 1); 114629088Smarkm send_dont(TELOPT_ECHO, 1); 114729088Smarkm return 1; 114829088Smarkm} 114929088Smarkm 115029088Smarkm static int 115129088Smarkmdocharmode() 115229088Smarkm{ 115329088Smarkm#ifdef KLUDGELINEMODE 115429088Smarkm if (kludgelinemode) 115529088Smarkm send_do(TELOPT_SGA, 1); 115629088Smarkm else 115729088Smarkm#endif 115829088Smarkm send_wont(TELOPT_LINEMODE, 1); 115929088Smarkm send_do(TELOPT_ECHO, 1); 116029088Smarkm return 1; 116129088Smarkm} 116229088Smarkm 116329088Smarkm static int 116429088Smarkmdolmmode(bit, on) 116529088Smarkm int bit, on; 116629088Smarkm{ 116729088Smarkm unsigned char c; 116829088Smarkm extern int linemode; 116929088Smarkm 117029088Smarkm if (my_want_state_is_wont(TELOPT_LINEMODE)) { 117129088Smarkm printf("?Need to have LINEMODE option enabled first.\n"); 117229088Smarkm printf("'mode ?' for help.\n"); 117329088Smarkm return 0; 117429088Smarkm } 117529088Smarkm 117629088Smarkm if (on) 117729088Smarkm c = (linemode | bit); 117829088Smarkm else 117929088Smarkm c = (linemode & ~bit); 118029088Smarkm lm_mode(&c, 1, 1); 118129088Smarkm return 1; 118229088Smarkm} 118329088Smarkm 118429088Smarkm int 118529181Smarkmsetmod(bit) 118629088Smarkm{ 118729088Smarkm return dolmmode(bit, 1); 118829088Smarkm} 118929088Smarkm 119029088Smarkm int 119129088Smarkmclearmode(bit) 119229088Smarkm{ 119329088Smarkm return dolmmode(bit, 0); 119429088Smarkm} 119529088Smarkm 119629088Smarkmstruct modelist { 119729088Smarkm char *name; /* command name */ 119829088Smarkm char *help; /* help string */ 119929088Smarkm int (*handler)(); /* routine which executes command */ 120029088Smarkm int needconnect; /* Do we need to be connected to execute? */ 120129088Smarkm int arg1; 120229088Smarkm}; 120329088Smarkm 120429088Smarkmextern int modehelp(); 120529088Smarkm 120629088Smarkmstatic struct modelist ModeList[] = { 120729088Smarkm { "character", "Disable LINEMODE option", docharmode, 1 }, 120829088Smarkm#ifdef KLUDGELINEMODE 120929088Smarkm { "", "(or disable obsolete line-by-line mode)", 0 }, 121029088Smarkm#endif 121129088Smarkm { "line", "Enable LINEMODE option", dolinemode, 1 }, 121229088Smarkm#ifdef KLUDGELINEMODE 121329088Smarkm { "", "(or enable obsolete line-by-line mode)", 0 }, 121429088Smarkm#endif 121529088Smarkm { "", "", 0 }, 121629088Smarkm { "", "These require the LINEMODE option to be enabled", 0 }, 121729181Smarkm { "isig", "Enable signal trapping", setmod, 1, MODE_TRAPSIG }, 121829181Smarkm { "+isig", 0, setmod, 1, MODE_TRAPSIG }, 121929088Smarkm { "-isig", "Disable signal trapping", clearmode, 1, MODE_TRAPSIG }, 122029181Smarkm { "edit", "Enable character editing", setmod, 1, MODE_EDIT }, 122129181Smarkm { "+edit", 0, setmod, 1, MODE_EDIT }, 122229088Smarkm { "-edit", "Disable character editing", clearmode, 1, MODE_EDIT }, 122329181Smarkm { "softtabs", "Enable tab expansion", setmod, 1, MODE_SOFT_TAB }, 122429181Smarkm { "+softtabs", 0, setmod, 1, MODE_SOFT_TAB }, 122529088Smarkm { "-softtabs", "Disable character editing", clearmode, 1, MODE_SOFT_TAB }, 122629181Smarkm { "litecho", "Enable literal character echo", setmod, 1, MODE_LIT_ECHO }, 122729181Smarkm { "+litecho", 0, setmod, 1, MODE_LIT_ECHO }, 122829088Smarkm { "-litecho", "Disable literal character echo", clearmode, 1, MODE_LIT_ECHO }, 122929088Smarkm { "help", 0, modehelp, 0 }, 123029088Smarkm#ifdef KLUDGELINEMODE 123129088Smarkm { "kludgeline", 0, dokludgemode, 1 }, 123229088Smarkm#endif 123329088Smarkm { "", "", 0 }, 123429088Smarkm { "?", "Print help information", modehelp, 0 }, 123529088Smarkm { 0 }, 123629088Smarkm}; 123729088Smarkm 123829088Smarkm 123929088Smarkm int 124029088Smarkmmodehelp() 124129088Smarkm{ 124229088Smarkm struct modelist *mt; 124329088Smarkm 124429088Smarkm printf("format is: 'mode Mode', where 'Mode' is one of:\n\n"); 124529088Smarkm for (mt = ModeList; mt->name; mt++) { 124629088Smarkm if (mt->help) { 124729088Smarkm if (*mt->help) 124829088Smarkm printf("%-15s %s\n", mt->name, mt->help); 124929088Smarkm else 125029088Smarkm printf("\n"); 125129088Smarkm } 125229088Smarkm } 125329088Smarkm return 0; 125429088Smarkm} 125529088Smarkm 125629088Smarkm#define GETMODECMD(name) (struct modelist *) \ 125729088Smarkm genget(name, (char **) ModeList, sizeof(struct modelist)) 125829088Smarkm 125929088Smarkm static int 126029088Smarkmmodecmd(argc, argv) 126129088Smarkm int argc; 126229088Smarkm char *argv[]; 126329088Smarkm{ 126429088Smarkm struct modelist *mt; 126529088Smarkm 126629088Smarkm if (argc != 2) { 126729088Smarkm printf("'mode' command requires an argument\n"); 126829088Smarkm printf("'mode ?' for help.\n"); 126929088Smarkm } else if ((mt = GETMODECMD(argv[1])) == 0) { 127029088Smarkm fprintf(stderr, "Unknown mode '%s' ('mode ?' for help).\n", argv[1]); 127129088Smarkm } else if (Ambiguous(mt)) { 127229088Smarkm fprintf(stderr, "Ambiguous mode '%s' ('mode ?' for help).\n", argv[1]); 127329088Smarkm } else if (mt->needconnect && !connected) { 127429088Smarkm printf("?Need to be connected first.\n"); 127529088Smarkm printf("'mode ?' for help.\n"); 127629088Smarkm } else if (mt->handler) { 127729088Smarkm return (*mt->handler)(mt->arg1); 127829088Smarkm } 127929088Smarkm return 0; 128029088Smarkm} 128129088Smarkm 128229088Smarkm/* 128329088Smarkm * The following data structures and routines implement the 128429088Smarkm * "display" command. 128529088Smarkm */ 128629088Smarkm 128729088Smarkm static int 128829088Smarkmdisplay(argc, argv) 128929088Smarkm int argc; 129029088Smarkm char *argv[]; 129129088Smarkm{ 129229088Smarkm struct togglelist *tl; 129329088Smarkm struct setlist *sl; 129429088Smarkm 129529088Smarkm#define dotog(tl) if (tl->variable && tl->actionexplanation) { \ 129629088Smarkm if (*tl->variable) { \ 129729088Smarkm printf("will"); \ 129829088Smarkm } else { \ 129929088Smarkm printf("won't"); \ 130029088Smarkm } \ 130129088Smarkm printf(" %s.\n", tl->actionexplanation); \ 130229088Smarkm } 130329088Smarkm 130429088Smarkm#define doset(sl) if (sl->name && *sl->name != ' ') { \ 130529088Smarkm if (sl->handler == 0) \ 130629088Smarkm printf("%-15s [%s]\n", sl->name, control(*sl->charp)); \ 130729088Smarkm else \ 130829088Smarkm printf("%-15s \"%s\"\n", sl->name, (char *)sl->charp); \ 130929088Smarkm } 131029088Smarkm 131129088Smarkm if (argc == 1) { 131229088Smarkm for (tl = Togglelist; tl->name; tl++) { 131329088Smarkm dotog(tl); 131429088Smarkm } 131529088Smarkm printf("\n"); 131629088Smarkm for (sl = Setlist; sl->name; sl++) { 131729088Smarkm doset(sl); 131829088Smarkm } 131929088Smarkm } else { 132029088Smarkm int i; 132129088Smarkm 132229088Smarkm for (i = 1; i < argc; i++) { 132329088Smarkm sl = getset(argv[i]); 132429088Smarkm tl = GETTOGGLE(argv[i]); 132529088Smarkm if (Ambiguous(sl) || Ambiguous(tl)) { 132629088Smarkm printf("?Ambiguous argument '%s'.\n", argv[i]); 132729088Smarkm return 0; 132829088Smarkm } else if (!sl && !tl) { 132929088Smarkm printf("?Unknown argument '%s'.\n", argv[i]); 133029088Smarkm return 0; 133129088Smarkm } else { 133229088Smarkm if (tl) { 133329088Smarkm dotog(tl); 133429088Smarkm } 133529088Smarkm if (sl) { 133629088Smarkm doset(sl); 133729088Smarkm } 133829088Smarkm } 133929088Smarkm } 134029088Smarkm } 134129088Smarkm/*@*/optionstatus(); 134229088Smarkm#ifdef ENCRYPTION 134329088Smarkm EncryptStatus(); 134429088Smarkm#endif /* ENCRYPTION */ 134529088Smarkm return 1; 134629088Smarkm#undef doset 134729088Smarkm#undef dotog 134829088Smarkm} 134929088Smarkm 135029088Smarkm/* 135129088Smarkm * The following are the data structures, and many of the routines, 135229088Smarkm * relating to command processing. 135329088Smarkm */ 135429088Smarkm 135529088Smarkm/* 135629088Smarkm * Set the escape character. 135729088Smarkm */ 135829088Smarkm static int 135929088Smarkmsetescape(argc, argv) 136029088Smarkm int argc; 136129088Smarkm char *argv[]; 136229088Smarkm{ 136329088Smarkm register char *arg; 136429088Smarkm char buf[50]; 136529088Smarkm 136629088Smarkm printf( 136729088Smarkm "Deprecated usage - please use 'set escape%s%s' in the future.\n", 136829088Smarkm (argc > 2)? " ":"", (argc > 2)? argv[1]: ""); 136929088Smarkm if (argc > 2) 137029088Smarkm arg = argv[1]; 137129088Smarkm else { 137229088Smarkm printf("new escape character: "); 137329088Smarkm (void) fgets(buf, sizeof(buf), stdin); 137429088Smarkm arg = buf; 137529088Smarkm } 137629088Smarkm if (arg[0] != '\0') 137729088Smarkm escape = arg[0]; 137829088Smarkm if (!In3270) { 137929088Smarkm printf("Escape character is '%s'.\n", control(escape)); 138029088Smarkm } 138129088Smarkm (void) fflush(stdout); 138229088Smarkm return 1; 138329088Smarkm} 138429088Smarkm 138529088Smarkm /*VARARGS*/ 138629088Smarkm static int 138729088Smarkmtogcrmod() 138829088Smarkm{ 138929088Smarkm crmod = !crmod; 139029088Smarkm printf("Deprecated usage - please use 'toggle crmod' in the future.\n"); 139129088Smarkm printf("%s map carriage return on output.\n", crmod ? "Will" : "Won't"); 139229088Smarkm (void) fflush(stdout); 139329088Smarkm return 1; 139429088Smarkm} 139529088Smarkm 139629088Smarkm /*VARARGS*/ 139729088Smarkm int 139829088Smarkmsuspend() 139929088Smarkm{ 140029088Smarkm#ifdef SIGTSTP 140129088Smarkm setcommandmode(); 140229088Smarkm { 140329088Smarkm long oldrows, oldcols, newrows, newcols, err; 140429088Smarkm 140529088Smarkm err = (TerminalWindowSize(&oldrows, &oldcols) == 0) ? 1 : 0; 140629088Smarkm (void) kill(0, SIGTSTP); 140729088Smarkm /* 140829088Smarkm * If we didn't get the window size before the SUSPEND, but we 140929088Smarkm * can get them now (?), then send the NAWS to make sure that 141029088Smarkm * we are set up for the right window size. 141129088Smarkm */ 141229088Smarkm if (TerminalWindowSize(&newrows, &newcols) && connected && 141329088Smarkm (err || ((oldrows != newrows) || (oldcols != newcols)))) { 141429088Smarkm sendnaws(); 141529088Smarkm } 141629088Smarkm } 141729088Smarkm /* reget parameters in case they were changed */ 141829088Smarkm TerminalSaveState(); 141929088Smarkm setconnmode(0); 142029088Smarkm#else 142129088Smarkm printf("Suspend is not supported. Try the '!' command instead\n"); 142229088Smarkm#endif 142329088Smarkm return 1; 142429088Smarkm} 142529088Smarkm 142629088Smarkm#if !defined(TN3270) 142729088Smarkm /*ARGSUSED*/ 142829088Smarkm int 142929088Smarkmshell(argc, argv) 143029088Smarkm int argc; 143129088Smarkm char *argv[]; 143229088Smarkm{ 143329088Smarkm long oldrows, oldcols, newrows, newcols, err; 143429088Smarkm 143529088Smarkm setcommandmode(); 143629088Smarkm 143729088Smarkm err = (TerminalWindowSize(&oldrows, &oldcols) == 0) ? 1 : 0; 143829088Smarkm switch(vfork()) { 143929088Smarkm case -1: 144029088Smarkm perror("Fork failed\n"); 144129088Smarkm break; 144229088Smarkm 144329088Smarkm case 0: 144429088Smarkm { 144529088Smarkm /* 144629088Smarkm * Fire up the shell in the child. 144729088Smarkm */ 144829088Smarkm register char *shellp, *shellname; 144929088Smarkm extern char *strrchr(); 145029088Smarkm 145129088Smarkm shellp = getenv("SHELL"); 145229088Smarkm if (shellp == NULL) 145329088Smarkm shellp = "/bin/sh"; 145429088Smarkm if ((shellname = strrchr(shellp, '/')) == 0) 145529088Smarkm shellname = shellp; 145629088Smarkm else 145729088Smarkm shellname++; 145829088Smarkm if (argc > 1) 145929088Smarkm execl(shellp, shellname, "-c", &saveline[1], 0); 146029088Smarkm else 146129088Smarkm execl(shellp, shellname, 0); 146229088Smarkm perror("Execl"); 146329088Smarkm _exit(1); 146429088Smarkm } 146529088Smarkm default: 146629088Smarkm (void)wait((int *)0); /* Wait for the shell to complete */ 146729088Smarkm 146829088Smarkm if (TerminalWindowSize(&newrows, &newcols) && connected && 146929088Smarkm (err || ((oldrows != newrows) || (oldcols != newcols)))) { 147029088Smarkm sendnaws(); 147129088Smarkm } 147229088Smarkm break; 147329088Smarkm } 147429088Smarkm return 1; 147529088Smarkm} 147629088Smarkm#else /* !defined(TN3270) */ 147729088Smarkmextern int shell(); 147829088Smarkm#endif /* !defined(TN3270) */ 147929088Smarkm 148029088Smarkm /*VARARGS*/ 148129181Smarkm static int 148229088Smarkmbye(argc, argv) 148329088Smarkm int argc; /* Number of arguments */ 148429088Smarkm char *argv[]; /* arguments */ 148529088Smarkm{ 148629088Smarkm extern int resettermname; 148729088Smarkm 148829088Smarkm if (connected) { 148929088Smarkm (void) shutdown(net, 2); 149029088Smarkm printf("Connection closed.\n"); 149129088Smarkm (void) NetClose(net); 149229088Smarkm connected = 0; 149329088Smarkm resettermname = 1; 149429088Smarkm#if defined(AUTHENTICATION) || defined(ENCRYPTION) 149529088Smarkm auth_encrypt_connect(connected); 149629088Smarkm#endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */ 149729088Smarkm /* reset options */ 149829088Smarkm tninit(); 149929088Smarkm#if defined(TN3270) 150029088Smarkm SetIn3270(); /* Get out of 3270 mode */ 150129088Smarkm#endif /* defined(TN3270) */ 150229088Smarkm } 150329088Smarkm if ((argc != 2) || (strcmp(argv[1], "fromquit") != 0)) { 150429088Smarkm longjmp(toplevel, 1); 150529088Smarkm /* NOTREACHED */ 150629088Smarkm } 150729088Smarkm return 1; /* Keep lint, etc., happy */ 150829088Smarkm} 150929088Smarkm 151029088Smarkm/*VARARGS*/ 151129181Smarkm int 151229088Smarkmquit() 151329088Smarkm{ 151429088Smarkm (void) call(bye, "bye", "fromquit", 0); 151529088Smarkm Exit(0); 151629088Smarkm /*NOTREACHED*/ 151729088Smarkm} 151829088Smarkm 151929088Smarkm/*VARARGS*/ 152029088Smarkm int 152129088Smarkmlogout() 152229088Smarkm{ 152329088Smarkm send_do(TELOPT_LOGOUT, 1); 152429088Smarkm (void) netflush(); 152529088Smarkm return 1; 152629088Smarkm} 152729088Smarkm 152829088Smarkm 152929088Smarkm/* 153029088Smarkm * The SLC command. 153129088Smarkm */ 153229088Smarkm 153329088Smarkmstruct slclist { 153429088Smarkm char *name; 153529088Smarkm char *help; 153629088Smarkm void (*handler)(); 153729088Smarkm int arg; 153829088Smarkm}; 153929088Smarkm 154029088Smarkmstatic void slc_help(); 154129088Smarkm 154229088Smarkmstruct slclist SlcList[] = { 154329088Smarkm { "export", "Use local special character definitions", 154429088Smarkm slc_mode_export, 0 }, 154529088Smarkm { "import", "Use remote special character definitions", 154629088Smarkm slc_mode_import, 1 }, 154729088Smarkm { "check", "Verify remote special character definitions", 154829088Smarkm slc_mode_import, 0 }, 154929088Smarkm { "help", 0, slc_help, 0 }, 155029088Smarkm { "?", "Print help information", slc_help, 0 }, 155129088Smarkm { 0 }, 155229088Smarkm}; 155329088Smarkm 155429088Smarkm static void 155529088Smarkmslc_help() 155629088Smarkm{ 155729088Smarkm struct slclist *c; 155829088Smarkm 155929088Smarkm for (c = SlcList; c->name; c++) { 156029088Smarkm if (c->help) { 156129088Smarkm if (*c->help) 156229088Smarkm printf("%-15s %s\n", c->name, c->help); 156329088Smarkm else 156429088Smarkm printf("\n"); 156529088Smarkm } 156629088Smarkm } 156729088Smarkm} 156829088Smarkm 156929088Smarkm static struct slclist * 157029088Smarkmgetslc(name) 157129088Smarkm char *name; 157229088Smarkm{ 157329088Smarkm return (struct slclist *) 157429088Smarkm genget(name, (char **) SlcList, sizeof(struct slclist)); 157529088Smarkm} 157629088Smarkm 157729181Smarkm static int 157829088Smarkmslccmd(argc, argv) 157929088Smarkm int argc; 158029088Smarkm char *argv[]; 158129088Smarkm{ 158229088Smarkm struct slclist *c; 158329088Smarkm 158429088Smarkm if (argc != 2) { 158529088Smarkm fprintf(stderr, 158629088Smarkm "Need an argument to 'slc' command. 'slc ?' for help.\n"); 158729088Smarkm return 0; 158829088Smarkm } 158929088Smarkm c = getslc(argv[1]); 159029088Smarkm if (c == 0) { 159129088Smarkm fprintf(stderr, "'%s': unknown argument ('slc ?' for help).\n", 159229088Smarkm argv[1]); 159329088Smarkm return 0; 159429088Smarkm } 159529088Smarkm if (Ambiguous(c)) { 159629088Smarkm fprintf(stderr, "'%s': ambiguous argument ('slc ?' for help).\n", 159729088Smarkm argv[1]); 159829088Smarkm return 0; 159929088Smarkm } 160029088Smarkm (*c->handler)(c->arg); 160129088Smarkm slcstate(); 160229088Smarkm return 1; 160329088Smarkm} 160429088Smarkm 160529088Smarkm/* 160629088Smarkm * The ENVIRON command. 160729088Smarkm */ 160829088Smarkm 160929088Smarkmstruct envlist { 161029088Smarkm char *name; 161129088Smarkm char *help; 161229088Smarkm void (*handler)(); 161329088Smarkm int narg; 161429088Smarkm}; 161529088Smarkm 161629088Smarkmextern struct env_lst * 161729088Smarkm env_define P((unsigned char *, unsigned char *)); 161829088Smarkmextern void 161929088Smarkm env_undefine P((unsigned char *)), 162029088Smarkm env_export P((unsigned char *)), 162129088Smarkm env_unexport P((unsigned char *)), 162229088Smarkm env_send P((unsigned char *)), 162329088Smarkm#if defined(OLD_ENVIRON) && defined(ENV_HACK) 162429088Smarkm env_varval P((unsigned char *)), 162529088Smarkm#endif 162629088Smarkm env_list P((void)); 162729088Smarkmstatic void 162829088Smarkm env_help P((void)); 162929088Smarkm 163029088Smarkmstruct envlist EnvList[] = { 163129088Smarkm { "define", "Define an environment variable", 163229088Smarkm (void (*)())env_define, 2 }, 163329088Smarkm { "undefine", "Undefine an environment variable", 163429088Smarkm env_undefine, 1 }, 163529088Smarkm { "export", "Mark an environment variable for automatic export", 163629088Smarkm env_export, 1 }, 163729088Smarkm { "unexport", "Don't mark an environment variable for automatic export", 163829088Smarkm env_unexport, 1 }, 163929088Smarkm { "send", "Send an environment variable", env_send, 1 }, 164029088Smarkm { "list", "List the current environment variables", 164129088Smarkm env_list, 0 }, 164229088Smarkm#if defined(OLD_ENVIRON) && defined(ENV_HACK) 164329088Smarkm { "varval", "Reverse VAR and VALUE (auto, right, wrong, status)", 164429088Smarkm env_varval, 1 }, 164529088Smarkm#endif 164629088Smarkm { "help", 0, env_help, 0 }, 164729088Smarkm { "?", "Print help information", env_help, 0 }, 164829088Smarkm { 0 }, 164929088Smarkm}; 165029088Smarkm 165129088Smarkm static void 165229088Smarkmenv_help() 165329088Smarkm{ 165429088Smarkm struct envlist *c; 165529088Smarkm 165629088Smarkm for (c = EnvList; c->name; c++) { 165729088Smarkm if (c->help) { 165829088Smarkm if (*c->help) 165929088Smarkm printf("%-15s %s\n", c->name, c->help); 166029088Smarkm else 166129088Smarkm printf("\n"); 166229088Smarkm } 166329088Smarkm } 166429088Smarkm} 166529088Smarkm 166629088Smarkm static struct envlist * 166729088Smarkmgetenvcmd(name) 166829088Smarkm char *name; 166929088Smarkm{ 167029088Smarkm return (struct envlist *) 167129088Smarkm genget(name, (char **) EnvList, sizeof(struct envlist)); 167229088Smarkm} 167329088Smarkm 167429181Smarkm int 167529088Smarkmenv_cmd(argc, argv) 167629088Smarkm int argc; 167729088Smarkm char *argv[]; 167829088Smarkm{ 167929088Smarkm struct envlist *c; 168029088Smarkm 168129088Smarkm if (argc < 2) { 168229088Smarkm fprintf(stderr, 168329088Smarkm "Need an argument to 'environ' command. 'environ ?' for help.\n"); 168429088Smarkm return 0; 168529088Smarkm } 168629088Smarkm c = getenvcmd(argv[1]); 168729088Smarkm if (c == 0) { 168829088Smarkm fprintf(stderr, "'%s': unknown argument ('environ ?' for help).\n", 168929088Smarkm argv[1]); 169029088Smarkm return 0; 169129088Smarkm } 169229088Smarkm if (Ambiguous(c)) { 169329088Smarkm fprintf(stderr, "'%s': ambiguous argument ('environ ?' for help).\n", 169429088Smarkm argv[1]); 169529088Smarkm return 0; 169629088Smarkm } 169729088Smarkm if (c->narg + 2 != argc) { 169829088Smarkm fprintf(stderr, 169929088Smarkm "Need %s%d argument%s to 'environ %s' command. 'environ ?' for help.\n", 170029088Smarkm c->narg < argc + 2 ? "only " : "", 170129088Smarkm c->narg, c->narg == 1 ? "" : "s", c->name); 170229088Smarkm return 0; 170329088Smarkm } 170429088Smarkm (*c->handler)(argv[2], argv[3]); 170529088Smarkm return 1; 170629088Smarkm} 170729088Smarkm 170829088Smarkmstruct env_lst { 170929088Smarkm struct env_lst *next; /* pointer to next structure */ 171029088Smarkm struct env_lst *prev; /* pointer to previous structure */ 171129088Smarkm unsigned char *var; /* pointer to variable name */ 171229088Smarkm unsigned char *value; /* pointer to variable value */ 171329088Smarkm int export; /* 1 -> export with default list of variables */ 171429088Smarkm int welldefined; /* A well defined variable */ 171529088Smarkm}; 171629088Smarkm 171729088Smarkmstruct env_lst envlisthead; 171829088Smarkm 171929088Smarkm struct env_lst * 172029088Smarkmenv_find(var) 172129088Smarkm unsigned char *var; 172229088Smarkm{ 172329088Smarkm register struct env_lst *ep; 172429088Smarkm 172529088Smarkm for (ep = envlisthead.next; ep; ep = ep->next) { 172629088Smarkm if (strcmp((char *)ep->var, (char *)var) == 0) 172729088Smarkm return(ep); 172829088Smarkm } 172929088Smarkm return(NULL); 173029088Smarkm} 173129088Smarkm 173229088Smarkm void 173329088Smarkmenv_init() 173429088Smarkm{ 173529088Smarkm extern char **environ; 173629088Smarkm register char **epp, *cp; 173729088Smarkm register struct env_lst *ep; 173829088Smarkm extern char *strchr(); 173929088Smarkm 174029088Smarkm for (epp = environ; *epp; epp++) { 174129181Smarkm if ((cp = strchr(*epp, '='))) { 174229088Smarkm *cp = '\0'; 174329088Smarkm ep = env_define((unsigned char *)*epp, 174429088Smarkm (unsigned char *)cp+1); 174529088Smarkm ep->export = 0; 174629088Smarkm *cp = '='; 174729088Smarkm } 174829088Smarkm } 174929088Smarkm /* 175029088Smarkm * Special case for DISPLAY variable. If it is ":0.0" or 175129088Smarkm * "unix:0.0", we have to get rid of "unix" and insert our 175229088Smarkm * hostname. 175329088Smarkm */ 175429088Smarkm if ((ep = env_find("DISPLAY")) 175529088Smarkm && ((*ep->value == ':') 175629088Smarkm || (strncmp((char *)ep->value, "unix:", 5) == 0))) { 175729088Smarkm char hbuf[256+1]; 175829088Smarkm char *cp2 = strchr((char *)ep->value, ':'); 175929088Smarkm 176029088Smarkm gethostname(hbuf, 256); 176129088Smarkm hbuf[256] = '\0'; 176229088Smarkm cp = (char *)malloc(strlen(hbuf) + strlen(cp2) + 1); 176329088Smarkm sprintf((char *)cp, "%s%s", hbuf, cp2); 176429088Smarkm free(ep->value); 176529088Smarkm ep->value = (unsigned char *)cp; 176629088Smarkm } 176729088Smarkm /* 176829088Smarkm * If USER is not defined, but LOGNAME is, then add 176929088Smarkm * USER with the value from LOGNAME. By default, we 177029088Smarkm * don't export the USER variable. 177129088Smarkm */ 177229088Smarkm if ((env_find("USER") == NULL) && (ep = env_find("LOGNAME"))) { 177329088Smarkm env_define((unsigned char *)"USER", ep->value); 177429088Smarkm env_unexport((unsigned char *)"USER"); 177529088Smarkm } 177629088Smarkm env_export((unsigned char *)"DISPLAY"); 177729088Smarkm env_export((unsigned char *)"PRINTER"); 177829088Smarkm} 177929088Smarkm 178029088Smarkm struct env_lst * 178129088Smarkmenv_define(var, value) 178229088Smarkm unsigned char *var, *value; 178329088Smarkm{ 178429088Smarkm register struct env_lst *ep; 178529088Smarkm 178629181Smarkm if ((ep = env_find(var))) { 178729088Smarkm if (ep->var) 178829088Smarkm free(ep->var); 178929088Smarkm if (ep->value) 179029088Smarkm free(ep->value); 179129088Smarkm } else { 179229088Smarkm ep = (struct env_lst *)malloc(sizeof(struct env_lst)); 179329088Smarkm ep->next = envlisthead.next; 179429088Smarkm envlisthead.next = ep; 179529088Smarkm ep->prev = &envlisthead; 179629088Smarkm if (ep->next) 179729088Smarkm ep->next->prev = ep; 179829088Smarkm } 179929088Smarkm ep->welldefined = opt_welldefined(var); 180029088Smarkm ep->export = 1; 180129088Smarkm ep->var = (unsigned char *)strdup((char *)var); 180229088Smarkm ep->value = (unsigned char *)strdup((char *)value); 180329088Smarkm return(ep); 180429088Smarkm} 180529088Smarkm 180629088Smarkm void 180729088Smarkmenv_undefine(var) 180829088Smarkm unsigned char *var; 180929088Smarkm{ 181029088Smarkm register struct env_lst *ep; 181129088Smarkm 181229181Smarkm if ((ep = env_find(var))) { 181329088Smarkm ep->prev->next = ep->next; 181429088Smarkm if (ep->next) 181529088Smarkm ep->next->prev = ep->prev; 181629088Smarkm if (ep->var) 181729088Smarkm free(ep->var); 181829088Smarkm if (ep->value) 181929088Smarkm free(ep->value); 182029088Smarkm free(ep); 182129088Smarkm } 182229088Smarkm} 182329088Smarkm 182429088Smarkm void 182529088Smarkmenv_export(var) 182629088Smarkm unsigned char *var; 182729088Smarkm{ 182829088Smarkm register struct env_lst *ep; 182929088Smarkm 183029181Smarkm if ((ep = env_find(var))) 183129088Smarkm ep->export = 1; 183229088Smarkm} 183329088Smarkm 183429088Smarkm void 183529088Smarkmenv_unexport(var) 183629088Smarkm unsigned char *var; 183729088Smarkm{ 183829088Smarkm register struct env_lst *ep; 183929088Smarkm 184029181Smarkm if ((ep = env_find(var))) 184129088Smarkm ep->export = 0; 184229088Smarkm} 184329088Smarkm 184429088Smarkm void 184529088Smarkmenv_send(var) 184629088Smarkm unsigned char *var; 184729088Smarkm{ 184829088Smarkm register struct env_lst *ep; 184929088Smarkm 185029088Smarkm if (my_state_is_wont(TELOPT_NEW_ENVIRON) 185129088Smarkm#ifdef OLD_ENVIRON 185229088Smarkm && my_state_is_wont(TELOPT_OLD_ENVIRON) 185329088Smarkm#endif 185429088Smarkm ) { 185529088Smarkm fprintf(stderr, 185629088Smarkm "Cannot send '%s': Telnet ENVIRON option not enabled\n", 185729088Smarkm var); 185829088Smarkm return; 185929088Smarkm } 186029088Smarkm ep = env_find(var); 186129088Smarkm if (ep == 0) { 186229088Smarkm fprintf(stderr, "Cannot send '%s': variable not defined\n", 186329088Smarkm var); 186429088Smarkm return; 186529088Smarkm } 186629088Smarkm env_opt_start_info(); 186729088Smarkm env_opt_add(ep->var); 186829088Smarkm env_opt_end(0); 186929088Smarkm} 187029088Smarkm 187129088Smarkm void 187229088Smarkmenv_list() 187329088Smarkm{ 187429088Smarkm register struct env_lst *ep; 187529088Smarkm 187629088Smarkm for (ep = envlisthead.next; ep; ep = ep->next) { 187729088Smarkm printf("%c %-20s %s\n", ep->export ? '*' : ' ', 187829088Smarkm ep->var, ep->value); 187929088Smarkm } 188029088Smarkm} 188129088Smarkm 188229088Smarkm unsigned char * 188329088Smarkmenv_default(init, welldefined) 188429088Smarkm int init; 188529088Smarkm{ 188629088Smarkm static struct env_lst *nep = NULL; 188729088Smarkm 188829088Smarkm if (init) { 188929088Smarkm nep = &envlisthead; 189029181Smarkm return(NULL); 189129088Smarkm } 189229088Smarkm if (nep) { 189329181Smarkm while ((nep = nep->next)) { 189429088Smarkm if (nep->export && (nep->welldefined == welldefined)) 189529088Smarkm return(nep->var); 189629088Smarkm } 189729088Smarkm } 189829088Smarkm return(NULL); 189929088Smarkm} 190029088Smarkm 190129088Smarkm unsigned char * 190229088Smarkmenv_getvalue(var) 190329088Smarkm unsigned char *var; 190429088Smarkm{ 190529088Smarkm register struct env_lst *ep; 190629088Smarkm 190729181Smarkm if ((ep = env_find(var))) 190829088Smarkm return(ep->value); 190929088Smarkm return(NULL); 191029088Smarkm} 191129088Smarkm 191229088Smarkm#if defined(OLD_ENVIRON) && defined(ENV_HACK) 191329088Smarkm void 191429088Smarkmenv_varval(what) 191529088Smarkm unsigned char *what; 191629088Smarkm{ 191729088Smarkm extern int old_env_var, old_env_value, env_auto; 191829088Smarkm int len = strlen((char *)what); 191929088Smarkm 192029088Smarkm if (len == 0) 192129088Smarkm goto unknown; 192229088Smarkm 192329088Smarkm if (strncasecmp((char *)what, "status", len) == 0) { 192429088Smarkm if (env_auto) 192529088Smarkm printf("%s%s", "VAR and VALUE are/will be ", 192629088Smarkm "determined automatically\n"); 192729088Smarkm if (old_env_var == OLD_ENV_VAR) 192829088Smarkm printf("VAR and VALUE set to correct definitions\n"); 192929088Smarkm else 193029088Smarkm printf("VAR and VALUE definitions are reversed\n"); 193129088Smarkm } else if (strncasecmp((char *)what, "auto", len) == 0) { 193229088Smarkm env_auto = 1; 193329088Smarkm old_env_var = OLD_ENV_VALUE; 193429088Smarkm old_env_value = OLD_ENV_VAR; 193529088Smarkm } else if (strncasecmp((char *)what, "right", len) == 0) { 193629088Smarkm env_auto = 0; 193729088Smarkm old_env_var = OLD_ENV_VAR; 193829088Smarkm old_env_value = OLD_ENV_VALUE; 193929088Smarkm } else if (strncasecmp((char *)what, "wrong", len) == 0) { 194029088Smarkm env_auto = 0; 194129088Smarkm old_env_var = OLD_ENV_VALUE; 194229088Smarkm old_env_value = OLD_ENV_VAR; 194329088Smarkm } else { 194429088Smarkmunknown: 194529088Smarkm printf("Unknown \"varval\" command. (\"auto\", \"right\", \"wrong\", \"status\")\n"); 194629088Smarkm } 194729088Smarkm} 194829088Smarkm#endif 194929088Smarkm 195029088Smarkm#if defined(AUTHENTICATION) 195129088Smarkm/* 195229088Smarkm * The AUTHENTICATE command. 195329088Smarkm */ 195429088Smarkm 195529088Smarkmstruct authlist { 195629088Smarkm char *name; 195729088Smarkm char *help; 195829088Smarkm int (*handler)(); 195929088Smarkm int narg; 196029088Smarkm}; 196129088Smarkm 196229088Smarkmextern int 196329088Smarkm auth_enable P((char *)), 196429088Smarkm auth_disable P((char *)), 196529088Smarkm auth_status P((void)); 196629088Smarkmstatic int 196729088Smarkm auth_help P((void)); 196829088Smarkm 196929088Smarkmstruct authlist AuthList[] = { 197029088Smarkm { "status", "Display current status of authentication information", 197129088Smarkm auth_status, 0 }, 197229088Smarkm { "disable", "Disable an authentication type ('auth disable ?' for more)", 197329088Smarkm auth_disable, 1 }, 197429088Smarkm { "enable", "Enable an authentication type ('auth enable ?' for more)", 197529088Smarkm auth_enable, 1 }, 197629088Smarkm { "help", 0, auth_help, 0 }, 197729088Smarkm { "?", "Print help information", auth_help, 0 }, 197829088Smarkm { 0 }, 197929088Smarkm}; 198029088Smarkm 198129088Smarkm static int 198229088Smarkmauth_help() 198329088Smarkm{ 198429088Smarkm struct authlist *c; 198529088Smarkm 198629088Smarkm for (c = AuthList; c->name; c++) { 198729088Smarkm if (c->help) { 198829088Smarkm if (*c->help) 198929088Smarkm printf("%-15s %s\n", c->name, c->help); 199029088Smarkm else 199129088Smarkm printf("\n"); 199229088Smarkm } 199329088Smarkm } 199429088Smarkm return 0; 199529088Smarkm} 199629088Smarkm 199729181Smarkm int 199829088Smarkmauth_cmd(argc, argv) 199929088Smarkm int argc; 200029088Smarkm char *argv[]; 200129088Smarkm{ 200229088Smarkm struct authlist *c; 200329088Smarkm 200429088Smarkm if (argc < 2) { 200529088Smarkm fprintf(stderr, 200629088Smarkm "Need an argument to 'auth' command. 'auth ?' for help.\n"); 200729088Smarkm return 0; 200829088Smarkm } 200929088Smarkm 201029088Smarkm c = (struct authlist *) 201129088Smarkm genget(argv[1], (char **) AuthList, sizeof(struct authlist)); 201229088Smarkm if (c == 0) { 201329088Smarkm fprintf(stderr, "'%s': unknown argument ('auth ?' for help).\n", 201429088Smarkm argv[1]); 201529088Smarkm return 0; 201629088Smarkm } 201729088Smarkm if (Ambiguous(c)) { 201829088Smarkm fprintf(stderr, "'%s': ambiguous argument ('auth ?' for help).\n", 201929088Smarkm argv[1]); 202029088Smarkm return 0; 202129088Smarkm } 202229088Smarkm if (c->narg + 2 != argc) { 202329088Smarkm fprintf(stderr, 202429088Smarkm "Need %s%d argument%s to 'auth %s' command. 'auth ?' for help.\n", 202529088Smarkm c->narg < argc + 2 ? "only " : "", 202629088Smarkm c->narg, c->narg == 1 ? "" : "s", c->name); 202729088Smarkm return 0; 202829088Smarkm } 202929088Smarkm return((*c->handler)(argv[2], argv[3])); 203029088Smarkm} 203129088Smarkm#endif 203229088Smarkm 203329088Smarkm#ifdef ENCRYPTION 203429088Smarkm/* 203529088Smarkm * The ENCRYPT command. 203629088Smarkm */ 203729088Smarkm 203829088Smarkmstruct encryptlist { 203929088Smarkm char *name; 204029088Smarkm char *help; 204129088Smarkm int (*handler)(); 204229088Smarkm int needconnect; 204329088Smarkm int minarg; 204429088Smarkm int maxarg; 204529088Smarkm}; 204629088Smarkm 204729088Smarkmextern int 204829088Smarkm EncryptEnable P((char *, char *)), 204929088Smarkm EncryptDisable P((char *, char *)), 205029088Smarkm EncryptType P((char *, char *)), 205129088Smarkm EncryptStart P((char *)), 205229088Smarkm EncryptStartInput P((void)), 205329088Smarkm EncryptStartOutput P((void)), 205429088Smarkm EncryptStop P((char *)), 205529088Smarkm EncryptStopInput P((void)), 205629088Smarkm EncryptStopOutput P((void)), 205729088Smarkm EncryptStatus P((void)); 205829088Smarkmstatic int 205929088Smarkm EncryptHelp P((void)); 206029088Smarkm 206129088Smarkmstruct encryptlist EncryptList[] = { 206229088Smarkm { "enable", "Enable encryption. ('encrypt enable ?' for more)", 206329088Smarkm EncryptEnable, 1, 1, 2 }, 206429088Smarkm { "disable", "Disable encryption. ('encrypt enable ?' for more)", 206529088Smarkm EncryptDisable, 0, 1, 2 }, 206629088Smarkm { "type", "Set encryption type. ('encrypt type ?' for more)", 206729088Smarkm EncryptType, 0, 1, 1 }, 206829088Smarkm { "start", "Start encryption. ('encrypt start ?' for more)", 206929088Smarkm EncryptStart, 1, 0, 1 }, 207029088Smarkm { "stop", "Stop encryption. ('encrypt stop ?' for more)", 207129088Smarkm EncryptStop, 1, 0, 1 }, 207229088Smarkm { "input", "Start encrypting the input stream", 207329088Smarkm EncryptStartInput, 1, 0, 0 }, 207429088Smarkm { "-input", "Stop encrypting the input stream", 207529088Smarkm EncryptStopInput, 1, 0, 0 }, 207629088Smarkm { "output", "Start encrypting the output stream", 207729088Smarkm EncryptStartOutput, 1, 0, 0 }, 207829088Smarkm { "-output", "Stop encrypting the output stream", 207929088Smarkm EncryptStopOutput, 1, 0, 0 }, 208029088Smarkm 208129088Smarkm { "status", "Display current status of authentication information", 208229088Smarkm EncryptStatus, 0, 0, 0 }, 208329088Smarkm { "help", 0, EncryptHelp, 0, 0, 0 }, 208429088Smarkm { "?", "Print help information", EncryptHelp, 0, 0, 0 }, 208529088Smarkm { 0 }, 208629088Smarkm}; 208729088Smarkm 208829088Smarkm static int 208929088SmarkmEncryptHelp() 209029088Smarkm{ 209129088Smarkm struct encryptlist *c; 209229088Smarkm 209329088Smarkm for (c = EncryptList; c->name; c++) { 209429088Smarkm if (c->help) { 209529088Smarkm if (*c->help) 209629088Smarkm printf("%-15s %s\n", c->name, c->help); 209729088Smarkm else 209829088Smarkm printf("\n"); 209929088Smarkm } 210029088Smarkm } 210129088Smarkm return 0; 210229088Smarkm} 210329088Smarkm 210429181Smarkm int 210529088Smarkmencrypt_cmd(argc, argv) 210629088Smarkm int argc; 210729088Smarkm char *argv[]; 210829088Smarkm{ 210929088Smarkm struct encryptlist *c; 211029088Smarkm 211129088Smarkm if (argc < 2) { 211229088Smarkm fprintf(stderr, 211329088Smarkm "Need an argument to 'encrypt' command. 'encrypt ?' for help.\n"); 211429088Smarkm return 0; 211529088Smarkm } 211629088Smarkm 211729088Smarkm c = (struct encryptlist *) 211829088Smarkm genget(argv[1], (char **) EncryptList, sizeof(struct encryptlist)); 211929088Smarkm if (c == 0) { 212029088Smarkm fprintf(stderr, "'%s': unknown argument ('encrypt ?' for help).\n", 212129088Smarkm argv[1]); 212229088Smarkm return 0; 212329088Smarkm } 212429088Smarkm if (Ambiguous(c)) { 212529088Smarkm fprintf(stderr, "'%s': ambiguous argument ('encrypt ?' for help).\n", 212629088Smarkm argv[1]); 212729088Smarkm return 0; 212829088Smarkm } 212929088Smarkm argc -= 2; 213029088Smarkm if (argc < c->minarg || argc > c->maxarg) { 213129088Smarkm if (c->minarg == c->maxarg) { 213229088Smarkm fprintf(stderr, "Need %s%d argument%s ", 213329088Smarkm c->minarg < argc ? "only " : "", c->minarg, 213429088Smarkm c->minarg == 1 ? "" : "s"); 213529088Smarkm } else { 213629088Smarkm fprintf(stderr, "Need %s%d-%d arguments ", 213729088Smarkm c->maxarg < argc ? "only " : "", c->minarg, c->maxarg); 213829088Smarkm } 213929088Smarkm fprintf(stderr, "to 'encrypt %s' command. 'encrypt ?' for help.\n", 214029088Smarkm c->name); 214129088Smarkm return 0; 214229088Smarkm } 214329088Smarkm if (c->needconnect && !connected) { 214429088Smarkm if (!(argc && (isprefix(argv[2], "help") || isprefix(argv[2], "?")))) { 214529088Smarkm printf("?Need to be connected first.\n"); 214629088Smarkm return 0; 214729088Smarkm } 214829088Smarkm } 214929088Smarkm return ((*c->handler)(argc > 0 ? argv[2] : 0, 215029088Smarkm argc > 1 ? argv[3] : 0, 215129088Smarkm argc > 2 ? argv[4] : 0)); 215229088Smarkm} 215329088Smarkm#endif /* ENCRYPTION */ 215429088Smarkm 215529088Smarkm#if defined(unix) && defined(TN3270) 215629088Smarkm static void 215729088Smarkmfilestuff(fd) 215829088Smarkm int fd; 215929088Smarkm{ 216029088Smarkm int res; 216129088Smarkm 216229088Smarkm#ifdef F_GETOWN 216329088Smarkm setconnmode(0); 216429088Smarkm res = fcntl(fd, F_GETOWN, 0); 216529088Smarkm setcommandmode(); 216629088Smarkm 216729088Smarkm if (res == -1) { 216829088Smarkm perror("fcntl"); 216929088Smarkm return; 217029088Smarkm } 217129088Smarkm printf("\tOwner is %d.\n", res); 217229088Smarkm#endif 217329088Smarkm 217429088Smarkm setconnmode(0); 217529088Smarkm res = fcntl(fd, F_GETFL, 0); 217629088Smarkm setcommandmode(); 217729088Smarkm 217829088Smarkm if (res == -1) { 217929088Smarkm perror("fcntl"); 218029088Smarkm return; 218129088Smarkm } 218229088Smarkm#ifdef notdef 218329088Smarkm printf("\tFlags are 0x%x: %s\n", res, decodeflags(res)); 218429088Smarkm#endif 218529088Smarkm} 218629088Smarkm#endif /* defined(unix) && defined(TN3270) */ 218729088Smarkm 218829088Smarkm/* 218929088Smarkm * Print status about the connection. 219029088Smarkm */ 219129088Smarkm /*ARGSUSED*/ 219229181Smarkm static int 219329088Smarkmstatus(argc, argv) 219429088Smarkm int argc; 219529088Smarkm char *argv[]; 219629088Smarkm{ 219729088Smarkm if (connected) { 219829088Smarkm printf("Connected to %s.\n", hostname); 219929088Smarkm if ((argc < 2) || strcmp(argv[1], "notmuch")) { 220029088Smarkm int mode = getconnmode(); 220129088Smarkm 220229088Smarkm if (my_want_state_is_will(TELOPT_LINEMODE)) { 220329088Smarkm printf("Operating with LINEMODE option\n"); 220429088Smarkm printf("%s line editing\n", (mode&MODE_EDIT) ? "Local" : "No"); 220529088Smarkm printf("%s catching of signals\n", 220629088Smarkm (mode&MODE_TRAPSIG) ? "Local" : "No"); 220729088Smarkm slcstate(); 220829088Smarkm#ifdef KLUDGELINEMODE 220929088Smarkm } else if (kludgelinemode && my_want_state_is_dont(TELOPT_SGA)) { 221029088Smarkm printf("Operating in obsolete linemode\n"); 221129088Smarkm#endif 221229088Smarkm } else { 221329088Smarkm printf("Operating in single character mode\n"); 221429088Smarkm if (localchars) 221529088Smarkm printf("Catching signals locally\n"); 221629088Smarkm } 221729088Smarkm printf("%s character echo\n", (mode&MODE_ECHO) ? "Local" : "Remote"); 221829088Smarkm if (my_want_state_is_will(TELOPT_LFLOW)) 221929088Smarkm printf("%s flow control\n", (mode&MODE_FLOW) ? "Local" : "No"); 222029088Smarkm#ifdef ENCRYPTION 222129088Smarkm encrypt_display(); 222229088Smarkm#endif /* ENCRYPTION */ 222329088Smarkm } 222429088Smarkm } else { 222529088Smarkm printf("No connection.\n"); 222629088Smarkm } 222729088Smarkm# if !defined(TN3270) 222829088Smarkm printf("Escape character is '%s'.\n", control(escape)); 222929088Smarkm (void) fflush(stdout); 223029088Smarkm# else /* !defined(TN3270) */ 223129088Smarkm if ((!In3270) && ((argc < 2) || strcmp(argv[1], "notmuch"))) { 223229088Smarkm printf("Escape character is '%s'.\n", control(escape)); 223329088Smarkm } 223429088Smarkm# if defined(unix) 223529088Smarkm if ((argc >= 2) && !strcmp(argv[1], "everything")) { 223629088Smarkm printf("SIGIO received %d time%s.\n", 223729088Smarkm sigiocount, (sigiocount == 1)? "":"s"); 223829088Smarkm if (In3270) { 223929088Smarkm printf("Process ID %d, process group %d.\n", 224029088Smarkm getpid(), getpgrp(getpid())); 224129088Smarkm printf("Terminal input:\n"); 224229088Smarkm filestuff(tin); 224329088Smarkm printf("Terminal output:\n"); 224429088Smarkm filestuff(tout); 224529088Smarkm printf("Network socket:\n"); 224629088Smarkm filestuff(net); 224729088Smarkm } 224829088Smarkm } 224929088Smarkm if (In3270 && transcom) { 225029088Smarkm printf("Transparent mode command is '%s'.\n", transcom); 225129088Smarkm } 225229088Smarkm# endif /* defined(unix) */ 225329088Smarkm (void) fflush(stdout); 225429088Smarkm if (In3270) { 225529088Smarkm return 0; 225629088Smarkm } 225729088Smarkm# endif /* defined(TN3270) */ 225829088Smarkm return 1; 225929088Smarkm} 226029088Smarkm 226129088Smarkm#ifdef SIGINFO 226229088Smarkm/* 226329088Smarkm * Function that gets called when SIGINFO is received. 226429088Smarkm */ 226529181Smarkm void 226629088Smarkmayt_status() 226729088Smarkm{ 226829088Smarkm (void) call(status, "status", "notmuch", 0); 226929088Smarkm} 227029088Smarkm#endif 227129088Smarkm 227229088Smarkmunsigned long inet_addr(); 227329088Smarkm 227429088Smarkm int 227529088Smarkmtn(argc, argv) 227629088Smarkm int argc; 227729088Smarkm char *argv[]; 227829088Smarkm{ 227929088Smarkm register struct hostent *host = 0; 228047973Sru struct sockaddr_in sin, src_sin; 228129088Smarkm struct servent *sp = 0; 228229088Smarkm unsigned long temp; 228329088Smarkm extern char *inet_ntoa(); 228429088Smarkm#if defined(IP_OPTIONS) && defined(IPPROTO_IP) 228529088Smarkm char *srp = 0, *strrchr(); 228629088Smarkm unsigned long sourceroute(), srlen; 228729088Smarkm#endif 228829088Smarkm char *cmd, *hostp = 0, *portp = 0, *user = 0; 228947973Sru char *src_addr = NULL; 229029088Smarkm 229129088Smarkm /* clear the socket address prior to use */ 229229088Smarkm memset((char *)&sin, 0, sizeof(sin)); 229329088Smarkm 229429088Smarkm if (connected) { 229529088Smarkm printf("?Already connected to %s\n", hostname); 229629088Smarkm setuid(getuid()); 229729088Smarkm return 0; 229829088Smarkm } 229929088Smarkm if (argc < 2) { 230029088Smarkm (void) strcpy(line, "open "); 230129088Smarkm printf("(to) "); 230229088Smarkm (void) fgets(&line[strlen(line)], sizeof(line) - strlen(line), stdin); 230329088Smarkm makeargv(); 230429088Smarkm argc = margc; 230529088Smarkm argv = margv; 230629088Smarkm } 230729088Smarkm cmd = *argv; 230829088Smarkm --argc; ++argv; 230929088Smarkm while (argc) { 231029088Smarkm if (strcmp(*argv, "help") == 0 || isprefix(*argv, "?")) 231129088Smarkm goto usage; 231229088Smarkm if (strcmp(*argv, "-l") == 0) { 231329088Smarkm --argc; ++argv; 231429088Smarkm if (argc == 0) 231529088Smarkm goto usage; 231629088Smarkm user = *argv++; 231729088Smarkm --argc; 231829088Smarkm continue; 231929088Smarkm } 232029088Smarkm if (strcmp(*argv, "-a") == 0) { 232129088Smarkm --argc; ++argv; 232229088Smarkm autologin = 1; 232329088Smarkm continue; 232429088Smarkm } 232547973Sru if (strcmp(*argv, "-s") == 0) { 232647973Sru --argc; ++argv; 232747973Sru if (argc == 0) 232847973Sru goto usage; 232947973Sru src_addr = *argv++; 233047973Sru --argc; 233147973Sru continue; 233247973Sru } 233329088Smarkm if (hostp == 0) { 233429088Smarkm hostp = *argv++; 233529088Smarkm --argc; 233629088Smarkm continue; 233729088Smarkm } 233829088Smarkm if (portp == 0) { 233929088Smarkm portp = *argv++; 234029088Smarkm --argc; 234129088Smarkm continue; 234229088Smarkm } 234329088Smarkm usage: 234447973Sru printf("usage: %s [-l user] [-a] [-s src_addr] host-name [port]\n", cmd); 234529088Smarkm setuid(getuid()); 234629088Smarkm return 0; 234729088Smarkm } 234829088Smarkm if (hostp == 0) 234929088Smarkm goto usage; 235029088Smarkm 235147973Sru if (src_addr != NULL) { 235247973Sru bzero((char *)&src_sin, sizeof(src_sin)); 235347973Sru src_sin.sin_family = AF_INET; 235447973Sru if (!inet_aton(src_addr, &src_sin.sin_addr)) { 235547973Sru host = gethostbyname2(src_addr, AF_INET); 235647973Sru if (host == NULL) { 235747973Sru herror(src_addr); 235847973Sru return 0; 235947973Sru } 236047973Sru if (host->h_length != sizeof(src_sin.sin_addr)) { 236147973Sru fprintf(stderr, "telnet: gethostbyname2: invalid address\n"); 236247973Sru return 0; 236347973Sru } 236447973Sru memcpy((void *)&src_sin.sin_addr, (void *)host->h_addr_list[0], 236547973Sru sizeof(src_sin.sin_addr)); 236647973Sru } 236747973Sru } 236847973Sru 236929088Smarkm#if defined(IP_OPTIONS) && defined(IPPROTO_IP) 237029088Smarkm if (hostp[0] == '@' || hostp[0] == '!') { 237129088Smarkm if ((hostname = strrchr(hostp, ':')) == NULL) 237229088Smarkm hostname = strrchr(hostp, '@'); 237329088Smarkm hostname++; 237429088Smarkm srp = 0; 237529088Smarkm temp = sourceroute(hostp, &srp, &srlen); 237629088Smarkm if (temp == 0) { 237729088Smarkm herror(srp); 237829088Smarkm setuid(getuid()); 237929088Smarkm return 0; 238029088Smarkm } else if (temp == -1) { 238129088Smarkm printf("Bad source route option: %s\n", hostp); 238229088Smarkm setuid(getuid()); 238329088Smarkm return 0; 238429088Smarkm } else { 238529088Smarkm sin.sin_addr.s_addr = temp; 238629088Smarkm sin.sin_family = AF_INET; 238729088Smarkm } 238829088Smarkm } else { 238929088Smarkm#endif 239029088Smarkm temp = inet_addr(hostp); 239129181Smarkm if (temp != INADDR_NONE) { 239229088Smarkm sin.sin_addr.s_addr = temp; 239329088Smarkm sin.sin_family = AF_INET; 239447973Sru if (doaddrlookup) 239547973Sru host = gethostbyaddr((char *)&temp, sizeof(temp), AF_INET); 239629181Smarkm if (host) 239729181Smarkm (void) strncpy(_hostname, host->h_name, sizeof(_hostname)); 239829181Smarkm else 239929181Smarkm (void) strncpy(_hostname, hostp, sizeof(_hostname)); 240029181Smarkm _hostname[sizeof(_hostname)-1] = '\0'; 240129088Smarkm hostname = _hostname; 240229088Smarkm } else { 240329088Smarkm host = gethostbyname(hostp); 240429088Smarkm if (host) { 240529088Smarkm sin.sin_family = host->h_addrtype; 240629088Smarkm#if defined(h_addr) /* In 4.3, this is a #define */ 240729088Smarkm memmove((caddr_t)&sin.sin_addr, 240829088Smarkm host->h_addr_list[0], host->h_length); 240929088Smarkm#else /* defined(h_addr) */ 241029088Smarkm memmove((caddr_t)&sin.sin_addr, host->h_addr, host->h_length); 241129088Smarkm#endif /* defined(h_addr) */ 241229088Smarkm strncpy(_hostname, host->h_name, sizeof(_hostname)); 241329088Smarkm _hostname[sizeof(_hostname)-1] = '\0'; 241429088Smarkm hostname = _hostname; 241529088Smarkm } else { 241629088Smarkm herror(hostp); 241729088Smarkm setuid(getuid()); 241829088Smarkm return 0; 241929088Smarkm } 242029088Smarkm } 242129088Smarkm#if defined(IP_OPTIONS) && defined(IPPROTO_IP) 242229088Smarkm } 242329088Smarkm#endif 242429088Smarkm if (portp) { 242529088Smarkm if (*portp == '-') { 242629088Smarkm portp++; 242729088Smarkm telnetport = 1; 242829088Smarkm } else 242929088Smarkm telnetport = 0; 243029088Smarkm sin.sin_port = atoi(portp); 243129088Smarkm if (sin.sin_port == 0) { 243229088Smarkm sp = getservbyname(portp, "tcp"); 243329088Smarkm if (sp) 243429088Smarkm sin.sin_port = sp->s_port; 243529088Smarkm else { 243629088Smarkm printf("%s: bad port number\n", portp); 243729088Smarkm setuid(getuid()); 243829088Smarkm return 0; 243929088Smarkm } 244029088Smarkm } else { 244129088Smarkm#if !defined(htons) 244229088Smarkm u_short htons P((unsigned short)); 244329088Smarkm#endif /* !defined(htons) */ 244429088Smarkm sin.sin_port = htons(sin.sin_port); 244529088Smarkm } 244629088Smarkm } else { 244729088Smarkm if (sp == 0) { 244829088Smarkm sp = getservbyname("telnet", "tcp"); 244929088Smarkm if (sp == 0) { 245029088Smarkm fprintf(stderr, "telnet: tcp/telnet: unknown service\n"); 245129088Smarkm setuid(getuid()); 245229088Smarkm return 0; 245329088Smarkm } 245429088Smarkm sin.sin_port = sp->s_port; 245529088Smarkm } 245629088Smarkm telnetport = 1; 245729088Smarkm } 245829088Smarkm printf("Trying %s...\n", inet_ntoa(sin.sin_addr)); 245929088Smarkm do { 246029088Smarkm net = socket(AF_INET, SOCK_STREAM, 0); 246129088Smarkm setuid(getuid()); 246229088Smarkm if (net < 0) { 246329088Smarkm perror("telnet: socket"); 246429088Smarkm return 0; 246529088Smarkm } 246629088Smarkm#if defined(IP_OPTIONS) && defined(IPPROTO_IP) 246729088Smarkm if (srp && setsockopt(net, IPPROTO_IP, IP_OPTIONS, (char *)srp, srlen) < 0) 246829088Smarkm perror("setsockopt (IP_OPTIONS)"); 246929088Smarkm#endif 247029088Smarkm#if defined(IPPROTO_IP) && defined(IP_TOS) 247129088Smarkm { 247229088Smarkm# if defined(HAS_GETTOS) 247329088Smarkm struct tosent *tp; 247429088Smarkm if (tos < 0 && (tp = gettosbyname("telnet", "tcp"))) 247529088Smarkm tos = tp->t_tos; 247629088Smarkm# endif 247729088Smarkm if (tos < 0) 247829088Smarkm tos = 020; /* Low Delay bit */ 247929088Smarkm if (tos 248029088Smarkm && (setsockopt(net, IPPROTO_IP, IP_TOS, 248129088Smarkm (char *)&tos, sizeof(int)) < 0) 248229088Smarkm && (errno != ENOPROTOOPT)) 248329088Smarkm perror("telnet: setsockopt (IP_TOS) (ignored)"); 248429088Smarkm } 248529088Smarkm#endif /* defined(IPPROTO_IP) && defined(IP_TOS) */ 248629088Smarkm 248729088Smarkm if (debug && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 1) < 0) { 248829088Smarkm perror("setsockopt (SO_DEBUG)"); 248929088Smarkm } 249029088Smarkm 249147973Sru if (src_addr != NULL) { 249247973Sru if (bind(net, (struct sockaddr *)&src_sin, sizeof(src_sin)) == -1) { 249347973Sru perror("bind"); 249447973Sru return 0; 249547973Sru } 249647973Sru } 249747973Sru 249829088Smarkm if (connect(net, (struct sockaddr *)&sin, sizeof (sin)) < 0) { 249929088Smarkm#if defined(h_addr) /* In 4.3, this is a #define */ 250029088Smarkm if (host && host->h_addr_list[1]) { 250129088Smarkm int oerrno = errno; 250229088Smarkm 250329088Smarkm fprintf(stderr, "telnet: connect to address %s: ", 250429088Smarkm inet_ntoa(sin.sin_addr)); 250529088Smarkm errno = oerrno; 250629088Smarkm perror((char *)0); 250729088Smarkm host->h_addr_list++; 250829088Smarkm memmove((caddr_t)&sin.sin_addr, 250929088Smarkm host->h_addr_list[0], host->h_length); 251029088Smarkm (void) NetClose(net); 251129088Smarkm continue; 251229088Smarkm } 251329088Smarkm#endif /* defined(h_addr) */ 251429088Smarkm perror("telnet: Unable to connect to remote host"); 251529088Smarkm return 0; 251629088Smarkm } 251729088Smarkm connected++; 251829088Smarkm#if defined(AUTHENTICATION) || defined(ENCRYPTION) 251929088Smarkm auth_encrypt_connect(connected); 252029088Smarkm#endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */ 252129088Smarkm } while (connected == 0); 252229088Smarkm cmdrc(hostp, hostname); 252329088Smarkm if (autologin && user == NULL) { 252429088Smarkm struct passwd *pw; 252529088Smarkm 252629088Smarkm user = getenv("USER"); 252729088Smarkm if (user == NULL || 252829181Smarkm ((pw = getpwnam(user)) && pw->pw_uid != getuid())) { 252929181Smarkm if ((pw = getpwuid(getuid()))) 253029088Smarkm user = pw->pw_name; 253129088Smarkm else 253229088Smarkm user = NULL; 253329088Smarkm } 253429088Smarkm } 253529088Smarkm if (user) { 253629088Smarkm env_define((unsigned char *)"USER", (unsigned char *)user); 253729088Smarkm env_export((unsigned char *)"USER"); 253829088Smarkm } 253929088Smarkm (void) call(status, "status", "notmuch", 0); 254029088Smarkm if (setjmp(peerdied) == 0) 254129088Smarkm telnet(user); 254229088Smarkm (void) NetClose(net); 254329088Smarkm ExitString("Connection closed by foreign host.\n",1); 254429088Smarkm /*NOTREACHED*/ 254529088Smarkm} 254629088Smarkm 254729088Smarkm#define HELPINDENT (sizeof ("connect")) 254829088Smarkm 254929088Smarkmstatic char 255029088Smarkm openhelp[] = "connect to a site", 255129088Smarkm closehelp[] = "close current connection", 255229088Smarkm logouthelp[] = "forcibly logout remote user and close the connection", 255329088Smarkm quithelp[] = "exit telnet", 255429088Smarkm statushelp[] = "print status information", 255529088Smarkm helphelp[] = "print help information", 255629088Smarkm sendhelp[] = "transmit special characters ('send ?' for more)", 255729088Smarkm sethelp[] = "set operating parameters ('set ?' for more)", 255829088Smarkm unsethelp[] = "unset operating parameters ('unset ?' for more)", 255929088Smarkm togglestring[] ="toggle operating parameters ('toggle ?' for more)", 256029088Smarkm slchelp[] = "change state of special charaters ('slc ?' for more)", 256129088Smarkm displayhelp[] = "display operating parameters", 256229088Smarkm#if defined(TN3270) && defined(unix) 256329088Smarkm transcomhelp[] = "specify Unix command for transparent mode pipe", 256429088Smarkm#endif /* defined(TN3270) && defined(unix) */ 256529088Smarkm#if defined(AUTHENTICATION) 256629088Smarkm authhelp[] = "turn on (off) authentication ('auth ?' for more)", 256729088Smarkm#endif 256829088Smarkm#ifdef ENCRYPTION 256929088Smarkm encrypthelp[] = "turn on (off) encryption ('encrypt ?' for more)", 257029088Smarkm#endif /* ENCRYPTION */ 257129088Smarkm#if defined(unix) 257229088Smarkm zhelp[] = "suspend telnet", 257329088Smarkm#endif /* defined(unix) */ 257429181Smarkm#if defined(SKEY) 257529181Smarkm skeyhelp[] = "compute response to s/key challenge", 257629181Smarkm#endif 257729088Smarkm shellhelp[] = "invoke a subshell", 257829088Smarkm envhelp[] = "change environment variables ('environ ?' for more)", 257929088Smarkm modestring[] = "try to enter line or character mode ('mode ?' for more)"; 258029088Smarkm 258129088Smarkmstatic Command cmdtab[] = { 258229088Smarkm { "close", closehelp, bye, 1 }, 258329088Smarkm { "logout", logouthelp, logout, 1 }, 258429088Smarkm { "display", displayhelp, display, 0 }, 258529088Smarkm { "mode", modestring, modecmd, 0 }, 258629088Smarkm { "open", openhelp, tn, 0 }, 258729088Smarkm { "quit", quithelp, quit, 0 }, 258829088Smarkm { "send", sendhelp, sendcmd, 0 }, 258929088Smarkm { "set", sethelp, setcmd, 0 }, 259029088Smarkm { "unset", unsethelp, unsetcmd, 0 }, 259129088Smarkm { "status", statushelp, status, 0 }, 259229088Smarkm { "toggle", togglestring, toggle, 0 }, 259329088Smarkm { "slc", slchelp, slccmd, 0 }, 259429088Smarkm#if defined(TN3270) && defined(unix) 259529088Smarkm { "transcom", transcomhelp, settranscom, 0 }, 259629088Smarkm#endif /* defined(TN3270) && defined(unix) */ 259729088Smarkm#if defined(AUTHENTICATION) 259829088Smarkm { "auth", authhelp, auth_cmd, 0 }, 259929088Smarkm#endif 260029088Smarkm#ifdef ENCRYPTION 260129088Smarkm { "encrypt", encrypthelp, encrypt_cmd, 0 }, 260229088Smarkm#endif /* ENCRYPTION */ 260329088Smarkm#if defined(unix) 260429088Smarkm { "z", zhelp, suspend, 0 }, 260529088Smarkm#endif /* defined(unix) */ 260629088Smarkm#if defined(TN3270) 260729088Smarkm { "!", shellhelp, shell, 1 }, 260829088Smarkm#else 260929088Smarkm { "!", shellhelp, shell, 0 }, 261029088Smarkm#endif 261129088Smarkm { "environ", envhelp, env_cmd, 0 }, 261229088Smarkm { "?", helphelp, help, 0 }, 261329181Smarkm#if defined(SKEY) 261429181Smarkm { "skey", skeyhelp, skey_calc, 0 }, 261529181Smarkm#endif 261629181Smarkm { 0, 0, 0, 0 } 261729088Smarkm}; 261829088Smarkm 261929088Smarkmstatic char crmodhelp[] = "deprecated command -- use 'toggle crmod' instead"; 262029088Smarkmstatic char escapehelp[] = "deprecated command -- use 'set escape' instead"; 262129088Smarkm 262229088Smarkmstatic Command cmdtab2[] = { 262329088Smarkm { "help", 0, help, 0 }, 262429088Smarkm { "escape", escapehelp, setescape, 0 }, 262529088Smarkm { "crmod", crmodhelp, togcrmod, 0 }, 262629181Smarkm { 0, 0, 0, 0 } 262729088Smarkm}; 262829088Smarkm 262929088Smarkm 263029088Smarkm/* 263129088Smarkm * Call routine with argc, argv set from args (terminated by 0). 263229088Smarkm */ 263329088Smarkm 263429088Smarkm /*VARARGS1*/ 263529181Smarkm static int 263629088Smarkmcall(va_alist) 263729088Smarkm va_dcl 263829088Smarkm{ 263929088Smarkm va_list ap; 264029088Smarkm typedef int (*intrtn_t)(); 264129088Smarkm intrtn_t routine; 264229088Smarkm char *args[100]; 264329088Smarkm int argno = 0; 264429088Smarkm 264529088Smarkm va_start(ap); 264629088Smarkm routine = (va_arg(ap, intrtn_t)); 264729088Smarkm while ((args[argno++] = va_arg(ap, char *)) != 0) { 264829088Smarkm ; 264929088Smarkm } 265029088Smarkm va_end(ap); 265129088Smarkm return (*routine)(argno-1, args); 265229088Smarkm} 265329088Smarkm 265429088Smarkm 265529088Smarkm static Command * 265629088Smarkmgetcmd(name) 265729088Smarkm char *name; 265829088Smarkm{ 265929088Smarkm Command *cm; 266029088Smarkm 266129181Smarkm if ((cm = (Command *) genget(name, (char **) cmdtab, sizeof(Command)))) 266229088Smarkm return cm; 266329088Smarkm return (Command *) genget(name, (char **) cmdtab2, sizeof(Command)); 266429088Smarkm} 266529088Smarkm 266629088Smarkm void 266729088Smarkmcommand(top, tbuf, cnt) 266829088Smarkm int top; 266929088Smarkm char *tbuf; 267029088Smarkm int cnt; 267129088Smarkm{ 267229088Smarkm register Command *c; 267329088Smarkm 267429088Smarkm setcommandmode(); 267529088Smarkm if (!top) { 267629088Smarkm putchar('\n'); 267729088Smarkm#if defined(unix) 267829088Smarkm } else { 267929088Smarkm (void) signal(SIGINT, SIG_DFL); 268029088Smarkm (void) signal(SIGQUIT, SIG_DFL); 268129088Smarkm#endif /* defined(unix) */ 268229088Smarkm } 268329088Smarkm for (;;) { 268429088Smarkm if (rlogin == _POSIX_VDISABLE) 268529088Smarkm printf("%s> ", prompt); 268629088Smarkm if (tbuf) { 268729088Smarkm register char *cp; 268829088Smarkm cp = line; 268929088Smarkm while (cnt > 0 && (*cp++ = *tbuf++) != '\n') 269029088Smarkm cnt--; 269129088Smarkm tbuf = 0; 269229088Smarkm if (cp == line || *--cp != '\n' || cp == line) 269329088Smarkm goto getline; 269429088Smarkm *cp = '\0'; 269529088Smarkm if (rlogin == _POSIX_VDISABLE) 269629088Smarkm printf("%s\n", line); 269729088Smarkm } else { 269829088Smarkm getline: 269929088Smarkm if (rlogin != _POSIX_VDISABLE) 270029088Smarkm printf("%s> ", prompt); 270129088Smarkm if (fgets(line, sizeof(line), stdin) == NULL) { 270229088Smarkm if (feof(stdin) || ferror(stdin)) { 270329088Smarkm (void) quit(); 270429088Smarkm /*NOTREACHED*/ 270529088Smarkm } 270629088Smarkm break; 270729088Smarkm } 270829088Smarkm } 270929088Smarkm if (line[0] == 0) 271029088Smarkm break; 271129088Smarkm makeargv(); 271229088Smarkm if (margv[0] == 0) { 271329088Smarkm break; 271429088Smarkm } 271529088Smarkm c = getcmd(margv[0]); 271629088Smarkm if (Ambiguous(c)) { 271729088Smarkm printf("?Ambiguous command\n"); 271829088Smarkm continue; 271929088Smarkm } 272029088Smarkm if (c == 0) { 272129088Smarkm printf("?Invalid command\n"); 272229088Smarkm continue; 272329088Smarkm } 272429088Smarkm if (c->needconnect && !connected) { 272529088Smarkm printf("?Need to be connected first.\n"); 272629088Smarkm continue; 272729088Smarkm } 272829088Smarkm if ((*c->handler)(margc, margv)) { 272929088Smarkm break; 273029088Smarkm } 273129088Smarkm } 273229088Smarkm if (!top) { 273329088Smarkm if (!connected) { 273429088Smarkm longjmp(toplevel, 1); 273529088Smarkm /*NOTREACHED*/ 273629088Smarkm } 273729088Smarkm#if defined(TN3270) 273829088Smarkm if (shell_active == 0) { 273929088Smarkm setconnmode(0); 274029088Smarkm } 274129088Smarkm#else /* defined(TN3270) */ 274229088Smarkm setconnmode(0); 274329088Smarkm#endif /* defined(TN3270) */ 274429088Smarkm } 274529088Smarkm} 274629088Smarkm 274729088Smarkm/* 274829088Smarkm * Help command. 274929088Smarkm */ 275029181Smarkm static int 275129088Smarkmhelp(argc, argv) 275229088Smarkm int argc; 275329088Smarkm char *argv[]; 275429088Smarkm{ 275529088Smarkm register Command *c; 275629088Smarkm 275729088Smarkm if (argc == 1) { 275829088Smarkm printf("Commands may be abbreviated. Commands are:\n\n"); 275929088Smarkm for (c = cmdtab; c->name; c++) 276029088Smarkm if (c->help) { 276129088Smarkm printf("%-*s\t%s\n", HELPINDENT, c->name, 276229088Smarkm c->help); 276329088Smarkm } 276429088Smarkm } 276529181Smarkm else while (--argc > 0) { 276629088Smarkm register char *arg; 276729088Smarkm arg = *++argv; 276829088Smarkm c = getcmd(arg); 276929088Smarkm if (Ambiguous(c)) 277029088Smarkm printf("?Ambiguous help command %s\n", arg); 277129088Smarkm else if (c == (Command *)0) 277229088Smarkm printf("?Invalid help command %s\n", arg); 277329088Smarkm else 277429088Smarkm printf("%s\n", c->help); 277529088Smarkm } 277629181Smarkm return(0); 277729088Smarkm} 277829088Smarkm 277929088Smarkmstatic char *rcname = 0; 278029088Smarkmstatic char rcbuf[128]; 278129088Smarkm 278229181Smarkm void 278329088Smarkmcmdrc(m1, m2) 278429088Smarkm char *m1, *m2; 278529088Smarkm{ 278629088Smarkm register Command *c; 278729088Smarkm FILE *rcfile; 278829088Smarkm int gotmachine = 0; 278929088Smarkm int l1 = strlen(m1); 279029088Smarkm int l2 = strlen(m2); 279129088Smarkm char m1save[64]; 279229088Smarkm 279329088Smarkm if (skiprc) 279429088Smarkm return; 279529088Smarkm 279629088Smarkm strcpy(m1save, m1); 279729088Smarkm m1 = m1save; 279829088Smarkm 279929088Smarkm if (rcname == 0) { 280029088Smarkm rcname = getenv("HOME"); 280129181Smarkm if (rcname && (strlen(rcname) + 10) < sizeof(rcbuf)) 280229088Smarkm strcpy(rcbuf, rcname); 280329088Smarkm else 280429088Smarkm rcbuf[0] = '\0'; 280529088Smarkm strcat(rcbuf, "/.telnetrc"); 280629088Smarkm rcname = rcbuf; 280729088Smarkm } 280829088Smarkm 280929088Smarkm if ((rcfile = fopen(rcname, "r")) == 0) { 281029088Smarkm return; 281129088Smarkm } 281229088Smarkm 281329088Smarkm for (;;) { 281429088Smarkm if (fgets(line, sizeof(line), rcfile) == NULL) 281529088Smarkm break; 281629088Smarkm if (line[0] == 0) 281729088Smarkm break; 281829088Smarkm if (line[0] == '#') 281929088Smarkm continue; 282029088Smarkm if (gotmachine) { 282129088Smarkm if (!isspace(line[0])) 282229088Smarkm gotmachine = 0; 282329088Smarkm } 282429088Smarkm if (gotmachine == 0) { 282529088Smarkm if (isspace(line[0])) 282629088Smarkm continue; 282729088Smarkm if (strncasecmp(line, m1, l1) == 0) 282829088Smarkm strncpy(line, &line[l1], sizeof(line) - l1); 282929088Smarkm else if (strncasecmp(line, m2, l2) == 0) 283029088Smarkm strncpy(line, &line[l2], sizeof(line) - l2); 283129088Smarkm else if (strncasecmp(line, "DEFAULT", 7) == 0) 283229088Smarkm strncpy(line, &line[7], sizeof(line) - 7); 283329088Smarkm else 283429088Smarkm continue; 283529088Smarkm if (line[0] != ' ' && line[0] != '\t' && line[0] != '\n') 283629088Smarkm continue; 283729088Smarkm gotmachine = 1; 283829088Smarkm } 283929088Smarkm makeargv(); 284029088Smarkm if (margv[0] == 0) 284129088Smarkm continue; 284229088Smarkm c = getcmd(margv[0]); 284329088Smarkm if (Ambiguous(c)) { 284429088Smarkm printf("?Ambiguous command: %s\n", margv[0]); 284529088Smarkm continue; 284629088Smarkm } 284729088Smarkm if (c == 0) { 284829088Smarkm printf("?Invalid command: %s\n", margv[0]); 284929088Smarkm continue; 285029088Smarkm } 285129088Smarkm /* 285229088Smarkm * This should never happen... 285329088Smarkm */ 285429088Smarkm if (c->needconnect && !connected) { 285529088Smarkm printf("?Need to be connected first for %s.\n", margv[0]); 285629088Smarkm continue; 285729088Smarkm } 285829088Smarkm (*c->handler)(margc, margv); 285929088Smarkm } 286029088Smarkm fclose(rcfile); 286129088Smarkm} 286229088Smarkm 286329088Smarkm#if defined(IP_OPTIONS) && defined(IPPROTO_IP) 286429088Smarkm 286529088Smarkm/* 286629088Smarkm * Source route is handed in as 286729088Smarkm * [!]@hop1@hop2...[@|:]dst 286829088Smarkm * If the leading ! is present, it is a 286929088Smarkm * strict source route, otherwise it is 287029088Smarkm * assmed to be a loose source route. 287129088Smarkm * 287229088Smarkm * We fill in the source route option as 287329088Smarkm * hop1,hop2,hop3...dest 287429088Smarkm * and return a pointer to hop1, which will 287529088Smarkm * be the address to connect() to. 287629088Smarkm * 287729088Smarkm * Arguments: 287829088Smarkm * arg: pointer to route list to decipher 287929088Smarkm * 288029088Smarkm * cpp: If *cpp is not equal to NULL, this is a 288129088Smarkm * pointer to a pointer to a character array 288229088Smarkm * that should be filled in with the option. 288329088Smarkm * 288429088Smarkm * lenp: pointer to an integer that contains the 288529088Smarkm * length of *cpp if *cpp != NULL. 288629088Smarkm * 288729088Smarkm * Return values: 288829088Smarkm * 288929088Smarkm * Returns the address of the host to connect to. If the 289029088Smarkm * return value is -1, there was a syntax error in the 289129088Smarkm * option, either unknown characters, or too many hosts. 289229088Smarkm * If the return value is 0, one of the hostnames in the 289329088Smarkm * path is unknown, and *cpp is set to point to the bad 289429088Smarkm * hostname. 289529088Smarkm * 289629088Smarkm * *cpp: If *cpp was equal to NULL, it will be filled 289729088Smarkm * in with a pointer to our static area that has 289829088Smarkm * the option filled in. This will be 32bit aligned. 289929088Smarkm * 290029088Smarkm * *lenp: This will be filled in with how long the option 290129088Smarkm * pointed to by *cpp is. 290229088Smarkm * 290329088Smarkm */ 290429088Smarkm unsigned long 290529088Smarkmsourceroute(arg, cpp, lenp) 290629088Smarkm char *arg; 290729088Smarkm char **cpp; 290829088Smarkm int *lenp; 290929088Smarkm{ 291029088Smarkm static char lsr[44]; 291129088Smarkm#ifdef sysV88 291229088Smarkm static IOPTN ipopt; 291329088Smarkm#endif 291429088Smarkm char *cp, *cp2, *lsrp, *lsrep; 291529088Smarkm register int tmp; 291629088Smarkm struct in_addr sin_addr; 291729088Smarkm register struct hostent *host = 0; 291829088Smarkm register char c; 291929088Smarkm 292029088Smarkm /* 292129088Smarkm * Verify the arguments, and make sure we have 292229088Smarkm * at least 7 bytes for the option. 292329088Smarkm */ 292429088Smarkm if (cpp == NULL || lenp == NULL) 292529088Smarkm return((unsigned long)-1); 292629088Smarkm if (*cpp != NULL && *lenp < 7) 292729088Smarkm return((unsigned long)-1); 292829088Smarkm /* 292929088Smarkm * Decide whether we have a buffer passed to us, 293029088Smarkm * or if we need to use our own static buffer. 293129088Smarkm */ 293229088Smarkm if (*cpp) { 293329088Smarkm lsrp = *cpp; 293429088Smarkm lsrep = lsrp + *lenp; 293529088Smarkm } else { 293629088Smarkm *cpp = lsrp = lsr; 293729088Smarkm lsrep = lsrp + 44; 293829088Smarkm } 293929088Smarkm 294029088Smarkm cp = arg; 294129088Smarkm 294229088Smarkm /* 294329088Smarkm * Next, decide whether we have a loose source 294429088Smarkm * route or a strict source route, and fill in 294529088Smarkm * the begining of the option. 294629088Smarkm */ 294729088Smarkm#ifndef sysV88 294829088Smarkm if (*cp == '!') { 294929088Smarkm cp++; 295029088Smarkm *lsrp++ = IPOPT_SSRR; 295129088Smarkm } else 295229088Smarkm *lsrp++ = IPOPT_LSRR; 295329088Smarkm#else 295429088Smarkm if (*cp == '!') { 295529088Smarkm cp++; 295629088Smarkm ipopt.io_type = IPOPT_SSRR; 295729088Smarkm } else 295829088Smarkm ipopt.io_type = IPOPT_LSRR; 295929088Smarkm#endif 296029088Smarkm 296129088Smarkm if (*cp != '@') 296229088Smarkm return((unsigned long)-1); 296329088Smarkm 296429088Smarkm#ifndef sysV88 296529088Smarkm lsrp++; /* skip over length, we'll fill it in later */ 296629088Smarkm *lsrp++ = 4; 296729088Smarkm#endif 296829088Smarkm 296929088Smarkm cp++; 297029088Smarkm 297129088Smarkm sin_addr.s_addr = 0; 297229088Smarkm 297329088Smarkm for (c = 0;;) { 297429088Smarkm if (c == ':') 297529088Smarkm cp2 = 0; 297629181Smarkm else for (cp2 = cp; (c = *cp2); cp2++) { 297729088Smarkm if (c == ',') { 297829088Smarkm *cp2++ = '\0'; 297929088Smarkm if (*cp2 == '@') 298029088Smarkm cp2++; 298129088Smarkm } else if (c == '@') { 298229088Smarkm *cp2++ = '\0'; 298329088Smarkm } else if (c == ':') { 298429088Smarkm *cp2++ = '\0'; 298529088Smarkm } else 298629088Smarkm continue; 298729088Smarkm break; 298829088Smarkm } 298929088Smarkm if (!c) 299029088Smarkm cp2 = 0; 299129088Smarkm 299229088Smarkm if ((tmp = inet_addr(cp)) != -1) { 299329088Smarkm sin_addr.s_addr = tmp; 299429181Smarkm } else if ((host = gethostbyname(cp))) { 299529088Smarkm#if defined(h_addr) 299629088Smarkm memmove((caddr_t)&sin_addr, 299729088Smarkm host->h_addr_list[0], host->h_length); 299829088Smarkm#else 299929088Smarkm memmove((caddr_t)&sin_addr, host->h_addr, host->h_length); 300029088Smarkm#endif 300129088Smarkm } else { 300229088Smarkm *cpp = cp; 300329088Smarkm return(0); 300429088Smarkm } 300529088Smarkm memmove(lsrp, (char *)&sin_addr, 4); 300629088Smarkm lsrp += 4; 300729088Smarkm if (cp2) 300829088Smarkm cp = cp2; 300929088Smarkm else 301029088Smarkm break; 301129088Smarkm /* 301229088Smarkm * Check to make sure there is space for next address 301329088Smarkm */ 301429088Smarkm if (lsrp + 4 > lsrep) 301529088Smarkm return((unsigned long)-1); 301629088Smarkm } 301729088Smarkm#ifndef sysV88 301829088Smarkm if ((*(*cpp+IPOPT_OLEN) = lsrp - *cpp) <= 7) { 301929088Smarkm *cpp = 0; 302029088Smarkm *lenp = 0; 302129088Smarkm return((unsigned long)-1); 302229088Smarkm } 302329088Smarkm *lsrp++ = IPOPT_NOP; /* 32 bit word align it */ 302429088Smarkm *lenp = lsrp - *cpp; 302529088Smarkm#else 302629088Smarkm ipopt.io_len = lsrp - *cpp; 302729088Smarkm if (ipopt.io_len <= 5) { /* Is 3 better ? */ 302829088Smarkm *cpp = 0; 302929088Smarkm *lenp = 0; 303029088Smarkm return((unsigned long)-1); 303129088Smarkm } 303229088Smarkm *lenp = sizeof(ipopt); 303329088Smarkm *cpp = (char *) &ipopt; 303429088Smarkm#endif 303529088Smarkm return(sin_addr.s_addr); 303629088Smarkm} 303729088Smarkm#endif 3038