133685Sbostic /* 245233Sborman * Copyright (c) 1988, 1990 Regents of the University of California. 333685Sbostic * All rights reserved. 433685Sbostic * 542770Sbostic * %sccs.include.redist.c% 633685Sbostic */ 733685Sbostic 833685Sbostic #ifndef lint 9*46808Sdab static char sccsid[] = "@(#)commands.c 5.3 (Berkeley) 03/01/91"; 1033685Sbostic #endif /* not lint */ 1133685Sbostic 1236274Sminshall #if defined(unix) 1345241Swilliam #include <sys/param.h> 14*46808Sdab #ifdef CRAY 15*46808Sdab #include <sys/types.h> 16*46808Sdab #endif 1736274Sminshall #include <sys/file.h> 1845241Swilliam #else 1945241Swilliam #include <sys/types.h> 2036274Sminshall #endif /* defined(unix) */ 2132144Sminshall #include <sys/socket.h> 2232144Sminshall #include <netinet/in.h> 2338689Sborman #ifdef CRAY 24*46808Sdab #include <fcntl.h> 2538810Sborman #endif /* CRAY */ 2632144Sminshall 2732144Sminshall #include <signal.h> 2832144Sminshall #include <netdb.h> 2932144Sminshall #include <ctype.h> 3045008Skarels #include <pwd.h> 3135298Sminshall #include <varargs.h> 32*46808Sdab #include <errno.h> 3332144Sminshall 3432144Sminshall #include <arpa/telnet.h> 3532144Sminshall 3634305Sminshall #include "general.h" 3734305Sminshall 3832381Sminshall #include "ring.h" 3932381Sminshall 4032144Sminshall #include "externs.h" 4132144Sminshall #include "defines.h" 4232144Sminshall #include "types.h" 4332144Sminshall 44*46808Sdab #ifndef CRAY 45*46808Sdab #include <netinet/in_systm.h> 46*46808Sdab # if (defined(vax) || defined(tahoe) || defined(hp300)) && !defined(ultrix) 47*46808Sdab # include <machine/endian.h> 48*46808Sdab # endif /* vax */ 49*46808Sdab #endif /* CRAY */ 5044361Sborman #include <netinet/ip.h> 5138689Sborman 5238689Sborman 53*46808Sdab #ifndef MAXHOSTNAMELEN 54*46808Sdab #define MAXHOSTNAMELEN 64 55*46808Sdab #endif MAXHOSTNAMELEN 5640248Sborman 5732144Sminshall char *hostname; 58*46808Sdab static char _hostname[MAXHOSTNAMELEN]; 59*46808Sdab 6038689Sborman extern char *getenv(); 6132144Sminshall 62*46808Sdab extern int isprefix(); 63*46808Sdab extern char **genget(); 64*46808Sdab extern int Ambiguous(); 65*46808Sdab 6644361Sborman static call(); 6732144Sminshall 6832144Sminshall typedef struct { 6932144Sminshall char *name; /* command name */ 7038689Sborman char *help; /* help string (NULL for no help) */ 7132144Sminshall int (*handler)(); /* routine which executes command */ 7232144Sminshall int needconnect; /* Do we need to be connected to execute? */ 7332144Sminshall } Command; 7432144Sminshall 7538689Sborman static char line[256]; 7638689Sborman static char saveline[256]; 7732144Sminshall static int margc; 7832144Sminshall static char *margv[20]; 7932144Sminshall 80*46808Sdab static void 8132144Sminshall makeargv() 8232144Sminshall { 8344361Sborman register char *cp, *cp2, c; 8432144Sminshall register char **argp = margv; 8532144Sminshall 8632144Sminshall margc = 0; 8732144Sminshall cp = line; 8832144Sminshall if (*cp == '!') { /* Special case shell escape */ 8938689Sborman strcpy(saveline, line); /* save for shell command */ 9032144Sminshall *argp++ = "!"; /* No room in string to get this */ 9132144Sminshall margc++; 9232144Sminshall cp++; 9332144Sminshall } 9444361Sborman while (c = *cp) { 9544361Sborman register int inquote = 0; 9644361Sborman while (isspace(c)) 9744361Sborman c = *++cp; 9844361Sborman if (c == '\0') 9932144Sminshall break; 10032144Sminshall *argp++ = cp; 10132144Sminshall margc += 1; 10244361Sborman for (cp2 = cp; c != '\0'; c = *++cp) { 10344361Sborman if (inquote) { 10444361Sborman if (c == inquote) { 10544361Sborman inquote = 0; 10644361Sborman continue; 10744361Sborman } 10844361Sborman } else { 10944361Sborman if (c == '\\') { 11044361Sborman if ((c = *++cp) == '\0') 11144361Sborman break; 11244361Sborman } else if (c == '"') { 11344361Sborman inquote = '"'; 11444361Sborman continue; 11544361Sborman } else if (c == '\'') { 11644361Sborman inquote = '\''; 11744361Sborman continue; 11844361Sborman } else if (isspace(c)) 11944361Sborman break; 12044361Sborman } 12144361Sborman *cp2++ = c; 12244361Sborman } 12344361Sborman *cp2 = '\0'; 12444361Sborman if (c == '\0') 12532144Sminshall break; 12644361Sborman cp++; 12732144Sminshall } 12832144Sminshall *argp++ = 0; 12932144Sminshall } 13032144Sminshall 13132144Sminshall /* 13232144Sminshall * Make a character string into a number. 13332144Sminshall * 13432144Sminshall * Todo: 1. Could take random integers (12, 0x12, 012, 0b1). 13532144Sminshall */ 13632144Sminshall 137*46808Sdab static 13832144Sminshall special(s) 139*46808Sdab register char *s; 14032144Sminshall { 14132144Sminshall register char c; 14232144Sminshall char b; 14332144Sminshall 14432144Sminshall switch (*s) { 14532144Sminshall case '^': 14632144Sminshall b = *++s; 14732144Sminshall if (b == '?') { 14832144Sminshall c = b | 0x40; /* DEL */ 14932144Sminshall } else { 15032144Sminshall c = b & 0x1f; 15132144Sminshall } 15232144Sminshall break; 15332144Sminshall default: 15432144Sminshall c = *s; 15532144Sminshall break; 15632144Sminshall } 15732144Sminshall return c; 15832144Sminshall } 15932144Sminshall 16032144Sminshall /* 16132144Sminshall * Construct a control character sequence 16232144Sminshall * for a special character. 16332144Sminshall */ 164*46808Sdab static char * 16532144Sminshall control(c) 16640245Sborman register cc_t c; 16732144Sminshall { 16844361Sborman static char buf[5]; 169*46808Sdab /* 170*46808Sdab * The only way I could get the Sun 3.5 compiler 171*46808Sdab * to shut up about 172*46808Sdab * if ((unsigned int)c >= 0x80) 173*46808Sdab * was to assign "c" to an unsigned int variable... 174*46808Sdab * Arggg.... 175*46808Sdab */ 176*46808Sdab register unsigned int uic = (unsigned int)c; 17732144Sminshall 178*46808Sdab if (uic == 0x7f) 17932144Sminshall return ("^?"); 18045233Sborman if (c == (cc_t)_POSIX_VDISABLE) { 18132144Sminshall return "off"; 18232144Sminshall } 183*46808Sdab if (uic >= 0x80) { 18444361Sborman buf[0] = '\\'; 18544361Sborman buf[1] = ((c>>6)&07) + '0'; 18644361Sborman buf[2] = ((c>>3)&07) + '0'; 18744361Sborman buf[3] = (c&07) + '0'; 18844361Sborman buf[4] = 0; 189*46808Sdab } else if (uic >= 0x20) { 19032144Sminshall buf[0] = c; 19132144Sminshall buf[1] = 0; 19232144Sminshall } else { 19332144Sminshall buf[0] = '^'; 19432144Sminshall buf[1] = '@'+c; 19532144Sminshall buf[2] = 0; 19632144Sminshall } 19732144Sminshall return (buf); 19832144Sminshall } 19932144Sminshall 20032144Sminshall 20132144Sminshall 20232144Sminshall /* 20332144Sminshall * The following are data structures and routines for 20432144Sminshall * the "send" command. 20532144Sminshall * 20632144Sminshall */ 20732144Sminshall 20832144Sminshall struct sendlist { 20932144Sminshall char *name; /* How user refers to it (case independent) */ 21032144Sminshall char *help; /* Help information (0 ==> no help) */ 211*46808Sdab int needconnect; /* Need to be connected */ 212*46808Sdab int narg; /* Number of arguments */ 21338689Sborman int (*handler)(); /* Routine to perform (for special ops) */ 214*46808Sdab int nbyte; /* Number of bytes to send this command */ 21538689Sborman int what; /* Character to be sent (<0 ==> special) */ 21632144Sminshall }; 21732144Sminshall 21832144Sminshall 219*46808Sdab extern int 220*46808Sdab send_esc P((void)), 221*46808Sdab send_help P((void)), 222*46808Sdab send_docmd P((char *)), 223*46808Sdab send_dontcmd P((char *)), 224*46808Sdab send_willcmd P((char *)), 225*46808Sdab send_wontcmd P((char *)); 226*46808Sdab 22732144Sminshall static struct sendlist Sendlist[] = { 228*46808Sdab { "ao", "Send Telnet Abort output", 1, 0, 0, 2, AO }, 229*46808Sdab { "ayt", "Send Telnet 'Are You There'", 1, 0, 0, 2, AYT }, 230*46808Sdab { "brk", "Send Telnet Break", 1, 0, 0, 2, BREAK }, 231*46808Sdab { "break", 0, 1, 0, 0, 2, BREAK }, 232*46808Sdab { "ec", "Send Telnet Erase Character", 1, 0, 0, 2, EC }, 233*46808Sdab { "el", "Send Telnet Erase Line", 1, 0, 0, 2, EL }, 234*46808Sdab { "escape", "Send current escape character", 1, 0, send_esc, 1, 0 }, 235*46808Sdab { "ga", "Send Telnet 'Go Ahead' sequence", 1, 0, 0, 2, GA }, 236*46808Sdab { "ip", "Send Telnet Interrupt Process", 1, 0, 0, 2, IP }, 237*46808Sdab { "intp", 0, 1, 0, 0, 2, IP }, 238*46808Sdab { "interrupt", 0, 1, 0, 0, 2, IP }, 239*46808Sdab { "intr", 0, 1, 0, 0, 2, IP }, 240*46808Sdab { "nop", "Send Telnet 'No operation'", 1, 0, 0, 2, NOP }, 241*46808Sdab { "eor", "Send Telnet 'End of Record'", 1, 0, 0, 2, EOR }, 242*46808Sdab { "abort", "Send Telnet 'Abort Process'", 1, 0, 0, 2, ABORT }, 243*46808Sdab { "susp", "Send Telnet 'Suspend Process'", 1, 0, 0, 2, SUSP }, 244*46808Sdab { "eof", "Send Telnet End of File Character", 1, 0, 0, 2, xEOF }, 245*46808Sdab { "synch", "Perform Telnet 'Synch operation'", 1, 0, dosynch, 2, 0 }, 246*46808Sdab { "getstatus", "Send request for STATUS", 1, 0, get_status, 6, 0 }, 247*46808Sdab { "?", "Display send options", 0, 0, send_help, 0, 0 }, 248*46808Sdab { "help", 0, 0, 0, send_help, 0, 0 }, 249*46808Sdab { "do", 0, 0, 1, send_docmd, 3, 0 }, 250*46808Sdab { "dont", 0, 0, 1, send_dontcmd, 3, 0 }, 251*46808Sdab { "will", 0, 0, 1, send_willcmd, 3, 0 }, 252*46808Sdab { "wont", 0, 0, 1, send_wontcmd, 3, 0 }, 25332144Sminshall { 0 } 25432144Sminshall }; 25532144Sminshall 256*46808Sdab #define GETSEND(name) ((struct sendlist *) genget(name, (char **) Sendlist, \ 257*46808Sdab sizeof(struct sendlist))) 25832144Sminshall 259*46808Sdab static int 26032144Sminshall sendcmd(argc, argv) 261*46808Sdab int argc; 262*46808Sdab char **argv; 26332144Sminshall { 26432144Sminshall int what; /* what we are sending this time */ 26532144Sminshall int count; /* how many bytes we are going to need to send */ 26632144Sminshall int i; 26732144Sminshall int question = 0; /* was at least one argument a question */ 26832144Sminshall struct sendlist *s; /* pointer to current command */ 269*46808Sdab int success = 0; 270*46808Sdab int needconnect = 0; 27132144Sminshall 27232144Sminshall if (argc < 2) { 27332144Sminshall printf("need at least one argument for 'send' command\n"); 27432144Sminshall printf("'send ?' for help\n"); 27532144Sminshall return 0; 27632144Sminshall } 27732144Sminshall /* 27832144Sminshall * First, validate all the send arguments. 27932144Sminshall * In addition, we see how much space we are going to need, and 28032144Sminshall * whether or not we will be doing a "SYNCH" operation (which 28132144Sminshall * flushes the network queue). 28232144Sminshall */ 28332144Sminshall count = 0; 28432144Sminshall for (i = 1; i < argc; i++) { 285*46808Sdab s = GETSEND(argv[i]); 28632144Sminshall if (s == 0) { 28732144Sminshall printf("Unknown send argument '%s'\n'send ?' for help.\n", 28832144Sminshall argv[i]); 28932144Sminshall return 0; 29032144Sminshall } else if (Ambiguous(s)) { 29132144Sminshall printf("Ambiguous send argument '%s'\n'send ?' for help.\n", 29232144Sminshall argv[i]); 29332144Sminshall return 0; 29432144Sminshall } 295*46808Sdab if (i + s->narg >= argc) { 296*46808Sdab fprintf(stderr, 297*46808Sdab "Need %d argument%s to 'send %s' command. 'send %s ?' for help.\n", 298*46808Sdab s->narg, s->narg == 1 ? "" : "s", s->name, s->name); 299*46808Sdab return 0; 30032144Sminshall } 301*46808Sdab count += s->nbyte; 302*46808Sdab if (s->handler == send_help) { 303*46808Sdab send_help(); 304*46808Sdab return 0; 305*46808Sdab } 306*46808Sdab 307*46808Sdab i += s->narg; 308*46808Sdab needconnect += s->needconnect; 30932144Sminshall } 310*46808Sdab if (!connected && needconnect) { 311*46808Sdab printf("?Need to be connected first.\n"); 312*46808Sdab printf("'send ?' for help\n"); 313*46808Sdab return 0; 31438689Sborman } 31532144Sminshall /* Now, do we have enough room? */ 31632144Sminshall if (NETROOM() < count) { 31732144Sminshall printf("There is not enough room in the buffer TO the network\n"); 31832144Sminshall printf("to process your request. Nothing will be done.\n"); 31932144Sminshall printf("('send synch' will throw away most data in the network\n"); 32032144Sminshall printf("buffer, if this might help.)\n"); 32132144Sminshall return 0; 32232144Sminshall } 32332144Sminshall /* OK, they are all OK, now go through again and actually send */ 324*46808Sdab count = 0; 32532144Sminshall for (i = 1; i < argc; i++) { 326*46808Sdab if ((s = GETSEND(argv[i])) == 0) { 32732144Sminshall fprintf(stderr, "Telnet 'send' error - argument disappeared!\n"); 32844361Sborman (void) quit(); 32932144Sminshall /*NOTREACHED*/ 33032144Sminshall } 33138689Sborman if (s->handler) { 332*46808Sdab count++; 333*46808Sdab success += (*s->handler)((s->narg > 0) ? argv[i+1] : 0, 334*46808Sdab (s->narg > 1) ? argv[i+2] : 0); 335*46808Sdab i += s->narg; 33632144Sminshall } else { 337*46808Sdab NET2ADD(IAC, what); 338*46808Sdab printoption("SENT", IAC, what); 339*46808Sdab } 340*46808Sdab } 341*46808Sdab return (count == success); 342*46808Sdab } 343*46808Sdab 344*46808Sdab static int 345*46808Sdab send_esc() 346*46808Sdab { 347*46808Sdab NETADD(escape); 348*46808Sdab return 1; 349*46808Sdab } 350*46808Sdab 351*46808Sdab static int 352*46808Sdab send_docmd(name) 353*46808Sdab char *name; 354*46808Sdab { 355*46808Sdab void send_do(); 356*46808Sdab return(send_tncmd(send_do, "do", name)); 357*46808Sdab } 358*46808Sdab 359*46808Sdab static int 360*46808Sdab send_dontcmd(name) 361*46808Sdab char *name; 362*46808Sdab { 363*46808Sdab void send_dont(); 364*46808Sdab return(send_tncmd(send_dont, "dont", name)); 365*46808Sdab } 366*46808Sdab static int 367*46808Sdab send_willcmd(name) 368*46808Sdab char *name; 369*46808Sdab { 370*46808Sdab void send_will(); 371*46808Sdab return(send_tncmd(send_will, "will", name)); 372*46808Sdab } 373*46808Sdab static int 374*46808Sdab send_wontcmd(name) 375*46808Sdab char *name; 376*46808Sdab { 377*46808Sdab void send_wont(); 378*46808Sdab return(send_tncmd(send_wont, "wont", name)); 379*46808Sdab } 380*46808Sdab 381*46808Sdab int 382*46808Sdab send_tncmd(func, cmd, name) 383*46808Sdab void (*func)(); 384*46808Sdab char *cmd, *name; 385*46808Sdab { 386*46808Sdab char **cpp; 387*46808Sdab extern char *telopts[]; 388*46808Sdab 389*46808Sdab if (isprefix(name, "help") || isprefix(name, "?")) { 390*46808Sdab register int col, len; 391*46808Sdab 392*46808Sdab printf("Usage: send %s <option>\n", cmd); 393*46808Sdab printf("Valid options are:\n\t"); 394*46808Sdab 395*46808Sdab col = 8; 396*46808Sdab for (cpp = telopts; *cpp; cpp++) { 397*46808Sdab len = strlen(*cpp) + 1; 398*46808Sdab if (col + len > 65) { 399*46808Sdab printf("\n\t"); 400*46808Sdab col = 8; 40132144Sminshall } 402*46808Sdab printf(" %s", *cpp); 403*46808Sdab col += len; 40432144Sminshall } 405*46808Sdab printf("\n"); 406*46808Sdab return 0; 40732144Sminshall } 408*46808Sdab cpp = (char **)genget(name, telopts, sizeof(char *)); 409*46808Sdab if (Ambiguous(cpp)) { 410*46808Sdab fprintf(stderr,"'%s': ambiguous argument ('send %s ?' for help).\n", 411*46808Sdab name, cmd); 412*46808Sdab return 0; 413*46808Sdab } 414*46808Sdab if (cpp == 0) { 415*46808Sdab fprintf(stderr, "'%s': unknown argument ('send %s ?' for help).\n", 416*46808Sdab name, cmd); 417*46808Sdab return 0; 418*46808Sdab } 419*46808Sdab if (!connected) { 420*46808Sdab printf("?Need to be connected first.\n"); 421*46808Sdab return 0; 422*46808Sdab } 423*46808Sdab (*func)(cpp - telopts, 1); 424*46808Sdab return 1; 42532144Sminshall } 426*46808Sdab 427*46808Sdab static int 428*46808Sdab send_help() 429*46808Sdab { 430*46808Sdab struct sendlist *s; /* pointer to current command */ 431*46808Sdab for (s = Sendlist; s->name; s++) { 432*46808Sdab if (s->help) 433*46808Sdab printf("%-15s %s\n", s->name, s->help); 434*46808Sdab } 435*46808Sdab return(0); 436*46808Sdab } 43732144Sminshall 43832144Sminshall /* 43932144Sminshall * The following are the routines and data structures referred 44032144Sminshall * to by the arguments to the "toggle" command. 44132144Sminshall */ 44232144Sminshall 443*46808Sdab static int 44432144Sminshall lclchars() 44532144Sminshall { 44632144Sminshall donelclchars = 1; 44732144Sminshall return 1; 44832144Sminshall } 44932144Sminshall 450*46808Sdab static int 45132144Sminshall togdebug() 45232144Sminshall { 45332144Sminshall #ifndef NOT43 45432144Sminshall if (net > 0 && 45532144Sminshall (SetSockOpt(net, SOL_SOCKET, SO_DEBUG, debug)) < 0) { 45632144Sminshall perror("setsockopt (SO_DEBUG)"); 45732144Sminshall } 45832144Sminshall #else /* NOT43 */ 45932144Sminshall if (debug) { 46032144Sminshall if (net > 0 && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 0, 0) < 0) 46132144Sminshall perror("setsockopt (SO_DEBUG)"); 46232144Sminshall } else 46332144Sminshall printf("Cannot turn off socket debugging\n"); 46432144Sminshall #endif /* NOT43 */ 46532144Sminshall return 1; 46632144Sminshall } 46732144Sminshall 46832144Sminshall 469*46808Sdab static int 47032144Sminshall togcrlf() 47132144Sminshall { 47232144Sminshall if (crlf) { 47332144Sminshall printf("Will send carriage returns as telnet <CR><LF>.\n"); 47432144Sminshall } else { 47532144Sminshall printf("Will send carriage returns as telnet <CR><NUL>.\n"); 47632144Sminshall } 47732144Sminshall return 1; 47832144Sminshall } 47932144Sminshall 48038909Sborman int binmode; 48132144Sminshall 482*46808Sdab static int 48338689Sborman togbinary(val) 484*46808Sdab int val; 48532144Sminshall { 48632144Sminshall donebinarytoggle = 1; 48732144Sminshall 48838909Sborman if (val >= 0) { 48938909Sborman binmode = val; 49038909Sborman } else { 49138909Sborman if (my_want_state_is_will(TELOPT_BINARY) && 49238909Sborman my_want_state_is_do(TELOPT_BINARY)) { 49338909Sborman binmode = 1; 49438909Sborman } else if (my_want_state_is_wont(TELOPT_BINARY) && 49538909Sborman my_want_state_is_dont(TELOPT_BINARY)) { 49638909Sborman binmode = 0; 49738909Sborman } 49838909Sborman val = binmode ? 0 : 1; 49938909Sborman } 50038909Sborman 50138909Sborman if (val == 1) { 50238909Sborman if (my_want_state_is_will(TELOPT_BINARY) && 50338909Sborman my_want_state_is_do(TELOPT_BINARY)) { 50438689Sborman printf("Already operating in binary mode with remote host.\n"); 50538909Sborman } else { 50638909Sborman printf("Negotiating binary mode with remote host.\n"); 50738909Sborman tel_enter_binary(3); 50838689Sborman } 50938909Sborman } else { 51038909Sborman if (my_want_state_is_wont(TELOPT_BINARY) && 51138909Sborman my_want_state_is_dont(TELOPT_BINARY)) { 51238689Sborman printf("Already in network ascii mode with remote host.\n"); 51338909Sborman } else { 51438909Sborman printf("Negotiating network ascii mode with remote host.\n"); 51538909Sborman tel_leave_binary(3); 51638689Sborman } 51732144Sminshall } 51832144Sminshall return 1; 51932144Sminshall } 52032144Sminshall 521*46808Sdab static int 52238909Sborman togrbinary(val) 523*46808Sdab int val; 52438909Sborman { 52538909Sborman donebinarytoggle = 1; 52632144Sminshall 52738909Sborman if (val == -1) 52838909Sborman val = my_want_state_is_do(TELOPT_BINARY) ? 0 : 1; 52932144Sminshall 53038909Sborman if (val == 1) { 53138909Sborman if (my_want_state_is_do(TELOPT_BINARY)) { 53238909Sborman printf("Already receiving in binary mode.\n"); 53338909Sborman } else { 53438909Sborman printf("Negotiating binary mode on input.\n"); 53538909Sborman tel_enter_binary(1); 53638909Sborman } 53738909Sborman } else { 53838909Sborman if (my_want_state_is_dont(TELOPT_BINARY)) { 53938909Sborman printf("Already receiving in network ascii mode.\n"); 54038909Sborman } else { 54138909Sborman printf("Negotiating network ascii mode on input.\n"); 54238909Sborman tel_leave_binary(1); 54338909Sborman } 54438909Sborman } 54538909Sborman return 1; 54638909Sborman } 54738909Sborman 548*46808Sdab static int 54938909Sborman togxbinary(val) 550*46808Sdab int val; 55138909Sborman { 55238909Sborman donebinarytoggle = 1; 55338909Sborman 55438909Sborman if (val == -1) 55538909Sborman val = my_want_state_is_will(TELOPT_BINARY) ? 0 : 1; 55638909Sborman 55738909Sborman if (val == 1) { 55838909Sborman if (my_want_state_is_will(TELOPT_BINARY)) { 55938909Sborman printf("Already transmitting in binary mode.\n"); 56038909Sborman } else { 56138909Sborman printf("Negotiating binary mode on output.\n"); 56238909Sborman tel_enter_binary(2); 56338909Sborman } 56438909Sborman } else { 56538909Sborman if (my_want_state_is_wont(TELOPT_BINARY)) { 56638909Sborman printf("Already transmitting in network ascii mode.\n"); 56738909Sborman } else { 56838909Sborman printf("Negotiating network ascii mode on output.\n"); 56938909Sborman tel_leave_binary(2); 57038909Sborman } 57138909Sborman } 57238909Sborman return 1; 57338909Sborman } 57438909Sborman 57538909Sborman 576*46808Sdab extern int togglehelp P((void)); 57732144Sminshall 57832144Sminshall struct togglelist { 57932144Sminshall char *name; /* name of toggle */ 58032144Sminshall char *help; /* help message */ 58132144Sminshall int (*handler)(); /* routine to do actual setting */ 58232144Sminshall int *variable; 58332144Sminshall char *actionexplanation; 58432144Sminshall }; 58532144Sminshall 58632144Sminshall static struct togglelist Togglelist[] = { 58732144Sminshall { "autoflush", 58838689Sborman "flushing of output when sending interrupt characters", 58932144Sminshall 0, 59038689Sborman &autoflush, 59138689Sborman "flush output when sending interrupt characters" }, 59232144Sminshall { "autosynch", 59338689Sborman "automatic sending of interrupt characters in urgent mode", 59432144Sminshall 0, 59538689Sborman &autosynch, 59638689Sborman "send interrupt characters in urgent mode" }, 59732144Sminshall { "binary", 59838689Sborman "sending and receiving of binary data", 59932144Sminshall togbinary, 60038689Sborman 0, 60138689Sborman 0 }, 60238909Sborman { "inbinary", 60338909Sborman "receiving of binary data", 60438909Sborman togrbinary, 60538909Sborman 0, 60638909Sborman 0 }, 60738909Sborman { "outbinary", 60838909Sborman "sending of binary data", 60938909Sborman togxbinary, 61038909Sborman 0, 61138909Sborman 0 }, 61232144Sminshall { "crlf", 61338689Sborman "sending carriage returns as telnet <CR><LF>", 61432144Sminshall togcrlf, 61538689Sborman &crlf, 61638689Sborman 0 }, 61732144Sminshall { "crmod", 61838689Sborman "mapping of received carriage returns", 61932144Sminshall 0, 62038689Sborman &crmod, 62138689Sborman "map carriage return on output" }, 62232144Sminshall { "localchars", 62338689Sborman "local recognition of certain control characters", 62432144Sminshall lclchars, 62538689Sborman &localchars, 62638689Sborman "recognize certain control characters" }, 62738689Sborman { " ", "", 0 }, /* empty line */ 62838208Sminshall #if defined(unix) && defined(TN3270) 62938920Sminshall { "apitrace", 63038920Sminshall "(debugging) toggle tracing of API transactions", 63138920Sminshall 0, 63238920Sminshall &apitrace, 63338920Sminshall "trace API transactions" }, 63438208Sminshall { "cursesdata", 63538208Sminshall "(debugging) toggle printing of hexadecimal curses data", 63638208Sminshall 0, 63738689Sborman &cursesdata, 63838689Sborman "print hexadecimal representation of curses data" }, 63938208Sminshall #endif /* defined(unix) && defined(TN3270) */ 64032144Sminshall { "debug", 64138689Sborman "debugging", 64232144Sminshall togdebug, 64338689Sborman &debug, 64438689Sborman "turn on socket level debugging" }, 64532144Sminshall { "netdata", 64638689Sborman "printing of hexadecimal network data (debugging)", 64732144Sminshall 0, 64838689Sborman &netdata, 64938689Sborman "print hexadecimal representation of network traffic" }, 65038689Sborman { "prettydump", 65138689Sborman "output of \"netdata\" to user readable format (debugging)", 65238689Sborman 0, 65338689Sborman &prettydump, 65438689Sborman "print user readable output for \"netdata\"" }, 65532144Sminshall { "options", 65638689Sborman "viewing of options processing (debugging)", 65732144Sminshall 0, 65838689Sborman &showoptions, 65938689Sborman "show option processing" }, 66038208Sminshall #if defined(unix) 66138208Sminshall { "termdata", 66238208Sminshall "(debugging) toggle printing of hexadecimal terminal data", 66338208Sminshall 0, 66438689Sborman &termdata, 66538689Sborman "print hexadecimal representation of terminal traffic" }, 66638208Sminshall #endif /* defined(unix) */ 66732144Sminshall { "?", 66838689Sborman 0, 66938689Sborman togglehelp }, 67032144Sminshall { "help", 67138689Sborman 0, 67238689Sborman togglehelp }, 67332144Sminshall { 0 } 67432144Sminshall }; 67532144Sminshall 676*46808Sdab static int 67732144Sminshall togglehelp() 67832144Sminshall { 67932144Sminshall struct togglelist *c; 68032144Sminshall 68132144Sminshall for (c = Togglelist; c->name; c++) { 68238689Sborman if (c->help) { 68338689Sborman if (*c->help) 68438689Sborman printf("%-15s toggle %s\n", c->name, c->help); 68538689Sborman else 68638689Sborman printf("\n"); 68732144Sminshall } 68832144Sminshall } 68938689Sborman printf("\n"); 69038689Sborman printf("%-15s %s\n", "?", "display help information"); 69132144Sminshall return 0; 69232144Sminshall } 69332144Sminshall 694*46808Sdab static void 69538689Sborman settogglehelp(set) 696*46808Sdab int set; 69738689Sborman { 69838689Sborman struct togglelist *c; 69938689Sborman 70038689Sborman for (c = Togglelist; c->name; c++) { 70138689Sborman if (c->help) { 70238689Sborman if (*c->help) 70338689Sborman printf("%-15s %s %s\n", c->name, set ? "enable" : "disable", 70438689Sborman c->help); 70538689Sborman else 70638689Sborman printf("\n"); 70738689Sborman } 70838689Sborman } 70938689Sborman } 71038689Sborman 711*46808Sdab #define GETTOGGLE(name) (struct togglelist *) \ 712*46808Sdab genget(name, (char **) Togglelist, sizeof(struct togglelist)) 71332144Sminshall 714*46808Sdab static int 71532144Sminshall toggle(argc, argv) 716*46808Sdab int argc; 717*46808Sdab char *argv[]; 71832144Sminshall { 71932144Sminshall int retval = 1; 72032144Sminshall char *name; 72132144Sminshall struct togglelist *c; 72232144Sminshall 72332144Sminshall if (argc < 2) { 72432144Sminshall fprintf(stderr, 72532144Sminshall "Need an argument to 'toggle' command. 'toggle ?' for help.\n"); 72632144Sminshall return 0; 72732144Sminshall } 72832144Sminshall argc--; 72932144Sminshall argv++; 73032144Sminshall while (argc--) { 73132144Sminshall name = *argv++; 732*46808Sdab c = GETTOGGLE(name); 73332144Sminshall if (Ambiguous(c)) { 73432144Sminshall fprintf(stderr, "'%s': ambiguous argument ('toggle ?' for help).\n", 73532144Sminshall name); 73632144Sminshall return 0; 73732144Sminshall } else if (c == 0) { 73832144Sminshall fprintf(stderr, "'%s': unknown argument ('toggle ?' for help).\n", 73932144Sminshall name); 74032144Sminshall return 0; 74132144Sminshall } else { 74232144Sminshall if (c->variable) { 74332144Sminshall *c->variable = !*c->variable; /* invert it */ 74432144Sminshall if (c->actionexplanation) { 74532144Sminshall printf("%s %s.\n", *c->variable? "Will" : "Won't", 74632144Sminshall c->actionexplanation); 74732144Sminshall } 74832144Sminshall } 74932144Sminshall if (c->handler) { 75038689Sborman retval &= (*c->handler)(-1); 75132144Sminshall } 75232144Sminshall } 75332144Sminshall } 75432144Sminshall return retval; 75532144Sminshall } 75632144Sminshall 75732144Sminshall /* 75832144Sminshall * The following perform the "set" command. 75932144Sminshall */ 76032144Sminshall 76138689Sborman #ifdef USE_TERMIO 76238689Sborman struct termio new_tc = { 0 }; 76338689Sborman #endif 76438689Sborman 76532144Sminshall struct setlist { 76632144Sminshall char *name; /* name */ 76732144Sminshall char *help; /* help information */ 76838689Sborman void (*handler)(); 76940245Sborman cc_t *charp; /* where it is located at */ 77032144Sminshall }; 77132144Sminshall 77232144Sminshall static struct setlist Setlist[] = { 77344361Sborman #ifdef KLUDGELINEMODE 77438689Sborman { "echo", "character to toggle local echoing on/off", 0, &echoc }, 77544361Sborman #endif 77638689Sborman { "escape", "character to escape back to telnet command mode", 0, &escape }, 777*46808Sdab { "rlogin", "rlogin escape character", 0, &rlogin }, 77845233Sborman { "tracefile", "file to write trace information to", SetNetTrace, (cc_t *)NetTraceFile}, 77932144Sminshall { " ", "" }, 78038689Sborman { " ", "The following need 'localchars' to be toggled true", 0, 0 }, 78145233Sborman { "flushoutput", "character to cause an Abort Output", 0, termFlushCharp }, 78238689Sborman { "interrupt", "character to cause an Interrupt Process", 0, termIntCharp }, 78338689Sborman { "quit", "character to cause an Abort process", 0, termQuitCharp }, 78438689Sborman { "eof", "character to cause an EOF ", 0, termEofCharp }, 78538689Sborman { " ", "" }, 78638689Sborman { " ", "The following are for local editing in linemode", 0, 0 }, 78738689Sborman { "erase", "character to use to erase a character", 0, termEraseCharp }, 78838689Sborman { "kill", "character to use to erase a line", 0, termKillCharp }, 78938689Sborman { "lnext", "character to use for literal next", 0, termLiteralNextCharp }, 79044361Sborman { "susp", "character to cause a Suspend Process", 0, termSuspCharp }, 79138689Sborman { "reprint", "character to use for line reprint", 0, termRprntCharp }, 79238689Sborman { "worderase", "character to use to erase a word", 0, termWerasCharp }, 79338689Sborman { "start", "character to use for XON", 0, termStartCharp }, 79444361Sborman { "stop", "character to use for XOFF", 0, termStopCharp }, 79544361Sborman { "forw1", "alternate end of line character", 0, termForw1Charp }, 79644361Sborman { "forw2", "alternate end of line character", 0, termForw2Charp }, 79745233Sborman { "ayt", "alternate AYT character", 0, termAytCharp }, 79832144Sminshall { 0 } 79932144Sminshall }; 80032144Sminshall 80145233Sborman #if defined(CRAY) && !defined(__STDC__) 80245233Sborman /* Work around compiler bug in pcc 4.1.5 */ 803*46808Sdab void 80438689Sborman _setlist_init() 80538689Sborman { 80644361Sborman #ifndef KLUDGELINEMODE 807*46808Sdab #define N 5 80844361Sborman #else 809*46808Sdab #define N 6 81044361Sborman #endif 81144361Sborman Setlist[N+0].charp = &termFlushChar; 81244361Sborman Setlist[N+1].charp = &termIntChar; 81344361Sborman Setlist[N+2].charp = &termQuitChar; 81444361Sborman Setlist[N+3].charp = &termEofChar; 81544361Sborman Setlist[N+6].charp = &termEraseChar; 81644361Sborman Setlist[N+7].charp = &termKillChar; 81744361Sborman Setlist[N+8].charp = &termLiteralNextChar; 81844361Sborman Setlist[N+9].charp = &termSuspChar; 81944361Sborman Setlist[N+10].charp = &termRprntChar; 82044361Sborman Setlist[N+11].charp = &termWerasChar; 82144361Sborman Setlist[N+12].charp = &termStartChar; 82244361Sborman Setlist[N+13].charp = &termStopChar; 82344361Sborman Setlist[N+14].charp = &termForw1Char; 82444361Sborman Setlist[N+15].charp = &termForw2Char; 82545233Sborman Setlist[N+16].charp = &termAytChar; 82644361Sborman #undef N 82738689Sborman } 82845233Sborman #endif /* defined(CRAY) && !defined(__STDC__) */ 82938689Sborman 830*46808Sdab static struct setlist * 83132144Sminshall getset(name) 832*46808Sdab char *name; 83332144Sminshall { 834*46808Sdab return (struct setlist *) 835*46808Sdab genget(name, (char **) Setlist, sizeof(struct setlist)); 83632144Sminshall } 83732144Sminshall 838*46808Sdab void 83944361Sborman set_escape_char(s) 840*46808Sdab char *s; 84144361Sborman { 842*46808Sdab if (rlogin != _POSIX_VDISABLE) { 843*46808Sdab rlogin = (s && *s) ? special(s) : _POSIX_VDISABLE; 844*46808Sdab printf("Telnet rlogin escape character is '%s'.\n", 845*46808Sdab control(rlogin)); 846*46808Sdab } else { 847*46808Sdab escape = (s && *s) ? special(s) : _POSIX_VDISABLE; 848*46808Sdab printf("Telnet escape character is '%s'.\n", control(escape)); 849*46808Sdab } 85044361Sborman } 85144361Sborman 852*46808Sdab static int 85332144Sminshall setcmd(argc, argv) 854*46808Sdab int argc; 855*46808Sdab char *argv[]; 85632144Sminshall { 85732144Sminshall int value; 85832144Sminshall struct setlist *ct; 85938689Sborman struct togglelist *c; 86032144Sminshall 86138689Sborman if (argc < 2 || argc > 3) { 86238689Sborman printf("Format is 'set Name Value'\n'set ?' for help.\n"); 86332144Sminshall return 0; 86432144Sminshall } 865*46808Sdab if ((argc == 2) && (isprefix(argv[1], "?") || isprefix(argv[1], "help"))) { 86638689Sborman for (ct = Setlist; ct->name; ct++) 86738689Sborman printf("%-15s %s\n", ct->name, ct->help); 86838689Sborman printf("\n"); 86938689Sborman settogglehelp(1); 87038689Sborman printf("%-15s %s\n", "?", "display help information"); 87138689Sborman return 0; 87238689Sborman } 87332144Sminshall 87432144Sminshall ct = getset(argv[1]); 87532144Sminshall if (ct == 0) { 876*46808Sdab c = GETTOGGLE(argv[1]); 87738689Sborman if (c == 0) { 87838689Sborman fprintf(stderr, "'%s': unknown argument ('set ?' for help).\n", 87932144Sminshall argv[1]); 88038689Sborman return 0; 88138689Sborman } else if (Ambiguous(c)) { 88238689Sborman fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n", 88338689Sborman argv[1]); 88438689Sborman return 0; 88538689Sborman } 88638689Sborman if (c->variable) { 88738689Sborman if ((argc == 2) || (strcmp("on", argv[2]) == 0)) 88838689Sborman *c->variable = 1; 88938689Sborman else if (strcmp("off", argv[2]) == 0) 89038689Sborman *c->variable = 0; 89138689Sborman else { 89238689Sborman printf("Format is 'set togglename [on|off]'\n'set ?' for help.\n"); 89338689Sborman return 0; 89438689Sborman } 89538689Sborman if (c->actionexplanation) { 89638689Sborman printf("%s %s.\n", *c->variable? "Will" : "Won't", 89738689Sborman c->actionexplanation); 89838689Sborman } 89938689Sborman } 90038689Sborman if (c->handler) 90138689Sborman (*c->handler)(1); 90238689Sborman } else if (argc != 3) { 90338689Sborman printf("Format is 'set Name Value'\n'set ?' for help.\n"); 90432144Sminshall return 0; 90532144Sminshall } else if (Ambiguous(ct)) { 90632144Sminshall fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n", 90732144Sminshall argv[1]); 90832144Sminshall return 0; 90938689Sborman } else if (ct->handler) { 91038689Sborman (*ct->handler)(argv[2]); 91144361Sborman printf("%s set to \"%s\".\n", ct->name, (char *)ct->charp); 91232144Sminshall } else { 91332144Sminshall if (strcmp("off", argv[2])) { 91432144Sminshall value = special(argv[2]); 91532144Sminshall } else { 91645233Sborman value = _POSIX_VDISABLE; 91732144Sminshall } 91840245Sborman *(ct->charp) = (cc_t)value; 91932144Sminshall printf("%s character is '%s'.\n", ct->name, control(*(ct->charp))); 92032144Sminshall } 92138689Sborman slc_check(); 92232144Sminshall return 1; 92332144Sminshall } 92438689Sborman 925*46808Sdab static int 92638689Sborman unsetcmd(argc, argv) 927*46808Sdab int argc; 928*46808Sdab char *argv[]; 92938689Sborman { 93038689Sborman struct setlist *ct; 93138689Sborman struct togglelist *c; 93238689Sborman register char *name; 93338689Sborman 93438689Sborman if (argc < 2) { 93538689Sborman fprintf(stderr, 93638689Sborman "Need an argument to 'unset' command. 'unset ?' for help.\n"); 93738689Sborman return 0; 93838689Sborman } 939*46808Sdab if (isprefix(argv[1], "?") || isprefix(argv[1], "help")) { 94038689Sborman for (ct = Setlist; ct->name; ct++) 94138689Sborman printf("%-15s %s\n", ct->name, ct->help); 94238689Sborman printf("\n"); 94338689Sborman settogglehelp(0); 94438689Sborman printf("%-15s %s\n", "?", "display help information"); 94538689Sborman return 0; 94638689Sborman } 94738689Sborman 94838689Sborman argc--; 94938689Sborman argv++; 95038689Sborman while (argc--) { 95138689Sborman name = *argv++; 95238689Sborman ct = getset(name); 95338689Sborman if (ct == 0) { 954*46808Sdab c = GETTOGGLE(name); 95538689Sborman if (c == 0) { 95638689Sborman fprintf(stderr, "'%s': unknown argument ('unset ?' for help).\n", 95738689Sborman name); 95838689Sborman return 0; 95938689Sborman } else if (Ambiguous(c)) { 96038689Sborman fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n", 96138689Sborman name); 96238689Sborman return 0; 96338689Sborman } 96438689Sborman if (c->variable) { 96538689Sborman *c->variable = 0; 96638689Sborman if (c->actionexplanation) { 96738689Sborman printf("%s %s.\n", *c->variable? "Will" : "Won't", 96838689Sborman c->actionexplanation); 96938689Sborman } 97038689Sborman } 97138689Sborman if (c->handler) 97238689Sborman (*c->handler)(0); 97338689Sborman } else if (Ambiguous(ct)) { 97438689Sborman fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n", 97538689Sborman name); 97638689Sborman return 0; 97738689Sborman } else if (ct->handler) { 97838689Sborman (*ct->handler)(0); 97944361Sborman printf("%s reset to \"%s\".\n", ct->name, (char *)ct->charp); 98038689Sborman } else { 98145233Sborman *(ct->charp) = _POSIX_VDISABLE; 98238689Sborman printf("%s character is '%s'.\n", ct->name, control(*(ct->charp))); 98338689Sborman } 98438689Sborman } 98538689Sborman return 1; 98638689Sborman } 98732144Sminshall 98832144Sminshall /* 98932144Sminshall * The following are the data structures and routines for the 99032144Sminshall * 'mode' command. 99132144Sminshall */ 99238689Sborman #ifdef KLUDGELINEMODE 99338689Sborman extern int kludgelinemode; 99444361Sborman 995*46808Sdab static int 99644361Sborman dokludgemode() 99744361Sborman { 99844361Sborman kludgelinemode = 1; 99944361Sborman send_wont(TELOPT_LINEMODE, 1); 100044361Sborman send_dont(TELOPT_SGA, 1); 100144361Sborman send_dont(TELOPT_ECHO, 1); 100244361Sborman } 100338689Sborman #endif 100432144Sminshall 1005*46808Sdab static int 100632144Sminshall dolinemode() 100732144Sminshall { 100838689Sborman #ifdef KLUDGELINEMODE 100938689Sborman if (kludgelinemode) 101038689Sborman send_dont(TELOPT_SGA, 1); 101138689Sborman #endif 101238689Sborman send_will(TELOPT_LINEMODE, 1); 101338689Sborman send_dont(TELOPT_ECHO, 1); 101432144Sminshall return 1; 101532144Sminshall } 101632144Sminshall 1017*46808Sdab static int 101832144Sminshall docharmode() 101932144Sminshall { 102038689Sborman #ifdef KLUDGELINEMODE 102138689Sborman if (kludgelinemode) 102238689Sborman send_do(TELOPT_SGA, 1); 102338689Sborman else 102438689Sborman #endif 102538689Sborman send_wont(TELOPT_LINEMODE, 1); 102638689Sborman send_do(TELOPT_ECHO, 1); 102738689Sborman return 1; 102838689Sborman } 102938689Sborman 1030*46808Sdab static int 103138689Sborman dolmmode(bit, on) 1032*46808Sdab int bit, on; 103338689Sborman { 1034*46808Sdab unsigned char c; 103538689Sborman extern int linemode; 103638689Sborman 103738689Sborman if (my_want_state_is_wont(TELOPT_LINEMODE)) { 103838689Sborman printf("?Need to have LINEMODE option enabled first.\n"); 103938689Sborman printf("'mode ?' for help.\n"); 104038689Sborman return 0; 104132144Sminshall } 104238689Sborman 104338689Sborman if (on) 104438689Sborman c = (linemode | bit); 104538689Sborman else 104638689Sborman c = (linemode & ~bit); 104738689Sborman lm_mode(&c, 1, 1); 104832144Sminshall return 1; 104932144Sminshall } 105032144Sminshall 1051*46808Sdab int 1052*46808Sdab setmode(bit) 1053*46808Sdab { 1054*46808Sdab return dolmmode(bit, 1); 1055*46808Sdab } 1056*46808Sdab 1057*46808Sdab int 1058*46808Sdab clearmode(bit) 1059*46808Sdab { 1060*46808Sdab return dolmmode(bit, 0); 1061*46808Sdab } 1062*46808Sdab 106338689Sborman struct modelist { 106438689Sborman char *name; /* command name */ 106538689Sborman char *help; /* help string */ 106638689Sborman int (*handler)(); /* routine which executes command */ 106738689Sborman int needconnect; /* Do we need to be connected to execute? */ 106838689Sborman int arg1; 106938689Sborman }; 107038689Sborman 107138689Sborman extern int modehelp(); 107238689Sborman 107338689Sborman static struct modelist ModeList[] = { 107438689Sborman { "character", "Disable LINEMODE option", docharmode, 1 }, 107539529Sborman #ifdef KLUDGELINEMODE 107639529Sborman { "", "(or disable obsolete line-by-line mode)", 0 }, 107738689Sborman #endif 107838689Sborman { "line", "Enable LINEMODE option", dolinemode, 1 }, 107939529Sborman #ifdef KLUDGELINEMODE 108039529Sborman { "", "(or enable obsolete line-by-line mode)", 0 }, 108138689Sborman #endif 108238689Sborman { "", "", 0 }, 108338689Sborman { "", "These require the LINEMODE option to be enabled", 0 }, 108438689Sborman { "isig", "Enable signal trapping", setmode, 1, MODE_TRAPSIG }, 108538689Sborman { "+isig", 0, setmode, 1, MODE_TRAPSIG }, 108638689Sborman { "-isig", "Disable signal trapping", clearmode, 1, MODE_TRAPSIG }, 108738689Sborman { "edit", "Enable character editing", setmode, 1, MODE_EDIT }, 108838689Sborman { "+edit", 0, setmode, 1, MODE_EDIT }, 108938689Sborman { "-edit", "Disable character editing", clearmode, 1, MODE_EDIT }, 109044361Sborman { "softtabs", "Enable tab expansion", setmode, 1, MODE_SOFT_TAB }, 109144361Sborman { "+softtabs", 0, setmode, 1, MODE_SOFT_TAB }, 109244361Sborman { "-softtabs", "Disable character editing", clearmode, 1, MODE_SOFT_TAB }, 109344361Sborman { "litecho", "Enable literal character echo", setmode, 1, MODE_LIT_ECHO }, 109444361Sborman { "+litecho", 0, setmode, 1, MODE_LIT_ECHO }, 109544361Sborman { "-litecho", "Disable literal character echo", clearmode, 1, MODE_LIT_ECHO }, 109638689Sborman { "help", 0, modehelp, 0 }, 109744361Sborman #ifdef KLUDGELINEMODE 109844361Sborman { "kludgeline", 0, dokludgemode, 1 }, 109944361Sborman #endif 110044361Sborman { "", "", 0 }, 110138689Sborman { "?", "Print help information", modehelp, 0 }, 110232144Sminshall { 0 }, 110332144Sminshall }; 110432144Sminshall 110532144Sminshall 1106*46808Sdab int 110738689Sborman modehelp() 110838689Sborman { 110938689Sborman struct modelist *mt; 111038689Sborman 111138689Sborman printf("format is: 'mode Mode', where 'Mode' is one of:\n\n"); 111238689Sborman for (mt = ModeList; mt->name; mt++) { 111338689Sborman if (mt->help) { 111438689Sborman if (*mt->help) 111538689Sborman printf("%-15s %s\n", mt->name, mt->help); 111638689Sborman else 111738689Sborman printf("\n"); 111838689Sborman } 111938689Sborman } 112038689Sborman return 0; 112138689Sborman } 112238689Sborman 1123*46808Sdab #define GETMODECMD(name) (struct modelist *) \ 1124*46808Sdab genget(name, (char **) ModeList, sizeof(struct modelist)) 1125*46808Sdab 1126*46808Sdab static int 112732144Sminshall modecmd(argc, argv) 1128*46808Sdab int argc; 1129*46808Sdab char *argv[]; 113032144Sminshall { 113138689Sborman struct modelist *mt; 113232144Sminshall 113338689Sborman if (argc != 2) { 113438689Sborman printf("'mode' command requires an argument\n"); 113538689Sborman printf("'mode ?' for help.\n"); 1136*46808Sdab } else if ((mt = GETMODECMD(argv[1])) == 0) { 113732144Sminshall fprintf(stderr, "Unknown mode '%s' ('mode ?' for help).\n", argv[1]); 113832144Sminshall } else if (Ambiguous(mt)) { 113932144Sminshall fprintf(stderr, "Ambiguous mode '%s' ('mode ?' for help).\n", argv[1]); 114038689Sborman } else if (mt->needconnect && !connected) { 114138689Sborman printf("?Need to be connected first.\n"); 114238689Sborman printf("'mode ?' for help.\n"); 114338689Sborman } else if (mt->handler) { 114438689Sborman return (*mt->handler)(mt->arg1); 114532144Sminshall } 114638689Sborman return 0; 114732144Sminshall } 114832144Sminshall 114932144Sminshall /* 115032144Sminshall * The following data structures and routines implement the 115132144Sminshall * "display" command. 115232144Sminshall */ 115332144Sminshall 1154*46808Sdab static int 115532144Sminshall display(argc, argv) 1156*46808Sdab int argc; 1157*46808Sdab char *argv[]; 115832144Sminshall { 1159*46808Sdab struct togglelist *tl; 1160*46808Sdab struct setlist *sl; 1161*46808Sdab 116232144Sminshall #define dotog(tl) if (tl->variable && tl->actionexplanation) { \ 116332144Sminshall if (*tl->variable) { \ 116432144Sminshall printf("will"); \ 116532144Sminshall } else { \ 116632144Sminshall printf("won't"); \ 116732144Sminshall } \ 116832144Sminshall printf(" %s.\n", tl->actionexplanation); \ 116932144Sminshall } 117032144Sminshall 117132144Sminshall #define doset(sl) if (sl->name && *sl->name != ' ') { \ 117238689Sborman if (sl->handler == 0) \ 117338689Sborman printf("%-15s [%s]\n", sl->name, control(*sl->charp)); \ 117438689Sborman else \ 117544361Sborman printf("%-15s \"%s\"\n", sl->name, (char *)sl->charp); \ 117632144Sminshall } 117732144Sminshall 117832144Sminshall if (argc == 1) { 117932144Sminshall for (tl = Togglelist; tl->name; tl++) { 118032144Sminshall dotog(tl); 118132144Sminshall } 118232144Sminshall printf("\n"); 118332144Sminshall for (sl = Setlist; sl->name; sl++) { 118432144Sminshall doset(sl); 118532144Sminshall } 118632144Sminshall } else { 118732144Sminshall int i; 118832144Sminshall 118932144Sminshall for (i = 1; i < argc; i++) { 119032144Sminshall sl = getset(argv[i]); 1191*46808Sdab tl = GETTOGGLE(argv[i]); 119232144Sminshall if (Ambiguous(sl) || Ambiguous(tl)) { 119332144Sminshall printf("?Ambiguous argument '%s'.\n", argv[i]); 119432144Sminshall return 0; 119532144Sminshall } else if (!sl && !tl) { 119632144Sminshall printf("?Unknown argument '%s'.\n", argv[i]); 119732144Sminshall return 0; 119832144Sminshall } else { 119932144Sminshall if (tl) { 120032144Sminshall dotog(tl); 120132144Sminshall } 120232144Sminshall if (sl) { 120332144Sminshall doset(sl); 120432144Sminshall } 120532144Sminshall } 120632144Sminshall } 120732144Sminshall } 120838689Sborman /*@*/optionstatus(); 1209*46808Sdab #if defined(ENCRYPT) 1210*46808Sdab EncryptStatus(); 1211*46808Sdab #endif 121232144Sminshall return 1; 121332144Sminshall #undef doset 121432144Sminshall #undef dotog 121532144Sminshall } 121632144Sminshall 121732144Sminshall /* 121832144Sminshall * The following are the data structures, and many of the routines, 121932144Sminshall * relating to command processing. 122032144Sminshall */ 122132144Sminshall 122232144Sminshall /* 122332144Sminshall * Set the escape character. 122432144Sminshall */ 1225*46808Sdab static int 122632144Sminshall setescape(argc, argv) 122732144Sminshall int argc; 122832144Sminshall char *argv[]; 122932144Sminshall { 123032144Sminshall register char *arg; 123132144Sminshall char buf[50]; 123232144Sminshall 123332144Sminshall printf( 123432144Sminshall "Deprecated usage - please use 'set escape%s%s' in the future.\n", 123532144Sminshall (argc > 2)? " ":"", (argc > 2)? argv[1]: ""); 123632144Sminshall if (argc > 2) 123732144Sminshall arg = argv[1]; 123832144Sminshall else { 123932144Sminshall printf("new escape character: "); 1240*46808Sdab (void) fgets(buf, sizeof(buf), stdin); 124132144Sminshall arg = buf; 124232144Sminshall } 124332144Sminshall if (arg[0] != '\0') 124432144Sminshall escape = arg[0]; 124532144Sminshall if (!In3270) { 124632144Sminshall printf("Escape character is '%s'.\n", control(escape)); 124732144Sminshall } 124834849Sminshall (void) fflush(stdout); 124932144Sminshall return 1; 125032144Sminshall } 125132144Sminshall 1252*46808Sdab /*VARARGS*/ 1253*46808Sdab static int 125432144Sminshall togcrmod() 125532144Sminshall { 125632144Sminshall crmod = !crmod; 125732144Sminshall printf("Deprecated usage - please use 'toggle crmod' in the future.\n"); 125832144Sminshall printf("%s map carriage return on output.\n", crmod ? "Will" : "Won't"); 125934849Sminshall (void) fflush(stdout); 126032144Sminshall return 1; 126132144Sminshall } 126232144Sminshall 1263*46808Sdab /*VARARGS*/ 1264*46808Sdab int 126532144Sminshall suspend() 126632144Sminshall { 126738689Sborman #ifdef SIGTSTP 126837219Sminshall setcommandmode(); 126937219Sminshall { 127044361Sborman long oldrows, oldcols, newrows, newcols, err; 127137219Sminshall 127244361Sborman err = TerminalWindowSize(&oldrows, &oldcols); 127334849Sminshall (void) kill(0, SIGTSTP); 127444361Sborman err += TerminalWindowSize(&newrows, &newcols); 127544361Sborman if (connected && !err && 127644361Sborman ((oldrows != newrows) || (oldcols != newcols))) { 127737219Sminshall sendnaws(); 127837219Sminshall } 127937219Sminshall } 128037219Sminshall /* reget parameters in case they were changed */ 128137219Sminshall TerminalSaveState(); 128238689Sborman setconnmode(0); 128338689Sborman #else 128438689Sborman printf("Suspend is not supported. Try the '!' command instead\n"); 128538689Sborman #endif 128637219Sminshall return 1; 128732144Sminshall } 128832144Sminshall 128938689Sborman #if !defined(TN3270) 1290*46808Sdab /*ARGSUSED*/ 1291*46808Sdab int 129238689Sborman shell(argc, argv) 1293*46808Sdab int argc; 1294*46808Sdab char *argv[]; 129538689Sborman { 129638689Sborman setcommandmode(); 129738689Sborman switch(vfork()) { 129838689Sborman case -1: 129938689Sborman perror("Fork failed\n"); 130038689Sborman break; 130138689Sborman 130238689Sborman case 0: 130338689Sborman { 130438689Sborman /* 130538689Sborman * Fire up the shell in the child. 130638689Sborman */ 1307*46808Sdab register char *shellp, *shellname; 1308*46808Sdab extern char *rindex(); 130938689Sborman 1310*46808Sdab shellp = getenv("SHELL"); 1311*46808Sdab if (shellp == NULL) 1312*46808Sdab shellp = "/bin/sh"; 1313*46808Sdab if ((shellname = rindex(shellp, '/')) == 0) 1314*46808Sdab shellname = shellp; 131538689Sborman else 131638689Sborman shellname++; 131738689Sborman if (argc > 1) 1318*46808Sdab execl(shellp, shellname, "-c", &saveline[1], 0); 131938689Sborman else 1320*46808Sdab execl(shellp, shellname, 0); 132138689Sborman perror("Execl"); 132238689Sborman _exit(1); 132338689Sborman } 132438689Sborman default: 132544361Sborman (void)wait((int *)0); /* Wait for the shell to complete */ 132638689Sborman } 1327*46808Sdab return 1; 132838689Sborman } 132938689Sborman #endif /* !defined(TN3270) */ 133038689Sborman 1331*46808Sdab /*VARARGS*/ 1332*46808Sdab static 133332144Sminshall bye(argc, argv) 1334*46808Sdab int argc; /* Number of arguments */ 1335*46808Sdab char *argv[]; /* arguments */ 133632144Sminshall { 1337*46808Sdab extern int resettermname; 1338*46808Sdab 133932144Sminshall if (connected) { 134034849Sminshall (void) shutdown(net, 2); 134132144Sminshall printf("Connection closed.\n"); 134234849Sminshall (void) NetClose(net); 134332144Sminshall connected = 0; 1344*46808Sdab resettermname = 1; 1345*46808Sdab #if defined(AUTHENTICATE) || defined(ENCRYPT) 1346*46808Sdab auth_encrypt_connect(connected); 1347*46808Sdab #endif 134832144Sminshall /* reset options */ 134932144Sminshall tninit(); 135032144Sminshall #if defined(TN3270) 135132144Sminshall SetIn3270(); /* Get out of 3270 mode */ 135232144Sminshall #endif /* defined(TN3270) */ 135332144Sminshall } 135432144Sminshall if ((argc != 2) || (strcmp(argv[1], "fromquit") != 0)) { 135532144Sminshall longjmp(toplevel, 1); 135632144Sminshall /* NOTREACHED */ 135732144Sminshall } 135832144Sminshall return 1; /* Keep lint, etc., happy */ 135932144Sminshall } 136032144Sminshall 136132144Sminshall /*VARARGS*/ 136232144Sminshall quit() 136332144Sminshall { 136432144Sminshall (void) call(bye, "bye", "fromquit", 0); 136532144Sminshall Exit(0); 136644361Sborman /*NOTREACHED*/ 136732144Sminshall } 1368*46808Sdab 1369*46808Sdab /*VARARGS*/ 1370*46808Sdab int 1371*46808Sdab logout() 1372*46808Sdab { 1373*46808Sdab send_do(TELOPT_LOGOUT, 1); 1374*46808Sdab (void) netflush(); 1375*46808Sdab return 1; 1376*46808Sdab } 1377*46808Sdab 137838689Sborman 137938689Sborman /* 138038689Sborman * The SLC command. 138138689Sborman */ 138232144Sminshall 138338689Sborman struct slclist { 138438689Sborman char *name; 138538689Sborman char *help; 1386*46808Sdab void (*handler)(); 138738689Sborman int arg; 138838689Sborman }; 138938689Sborman 1390*46808Sdab extern void slc_help(); 139138689Sborman 139238689Sborman struct slclist SlcList[] = { 139338689Sborman { "export", "Use local special character definitions", 139438689Sborman slc_mode_export, 0 }, 139538689Sborman { "import", "Use remote special character definitions", 139638689Sborman slc_mode_import, 1 }, 139738689Sborman { "check", "Verify remote special character definitions", 139838689Sborman slc_mode_import, 0 }, 139938689Sborman { "help", 0, slc_help, 0 }, 140038689Sborman { "?", "Print help information", slc_help, 0 }, 140138689Sborman { 0 }, 140238689Sborman }; 140338689Sborman 1404*46808Sdab static void 140538689Sborman slc_help() 140638689Sborman { 140738689Sborman struct slclist *c; 140838689Sborman 140938689Sborman for (c = SlcList; c->name; c++) { 141038689Sborman if (c->help) { 141138689Sborman if (*c->help) 141238689Sborman printf("%-15s %s\n", c->name, c->help); 141338689Sborman else 141438689Sborman printf("\n"); 141538689Sborman } 141638689Sborman } 141738689Sborman } 141838689Sborman 1419*46808Sdab static struct slclist * 142038689Sborman getslc(name) 1421*46808Sdab char *name; 142238689Sborman { 1423*46808Sdab return (struct slclist *) 1424*46808Sdab genget(name, (char **) SlcList, sizeof(struct slclist)); 142538689Sborman } 142638689Sborman 1427*46808Sdab static 142838689Sborman slccmd(argc, argv) 1429*46808Sdab int argc; 1430*46808Sdab char *argv[]; 143138689Sborman { 143238689Sborman struct slclist *c; 143338689Sborman 143438689Sborman if (argc != 2) { 143538689Sborman fprintf(stderr, 143638689Sborman "Need an argument to 'slc' command. 'slc ?' for help.\n"); 143738689Sborman return 0; 143838689Sborman } 143938689Sborman c = getslc(argv[1]); 144038689Sborman if (c == 0) { 144138689Sborman fprintf(stderr, "'%s': unknown argument ('slc ?' for help).\n", 144238689Sborman argv[1]); 144338689Sborman return 0; 144438689Sborman } 144538689Sborman if (Ambiguous(c)) { 144638689Sborman fprintf(stderr, "'%s': ambiguous argument ('slc ?' for help).\n", 144738689Sborman argv[1]); 144838689Sborman return 0; 144938689Sborman } 145038689Sborman (*c->handler)(c->arg); 145138689Sborman slcstate(); 145238689Sborman return 1; 145338689Sborman } 145444361Sborman 145544361Sborman /* 145644361Sborman * The ENVIRON command. 145744361Sborman */ 145838689Sborman 145944361Sborman struct envlist { 146044361Sborman char *name; 146144361Sborman char *help; 1462*46808Sdab void (*handler)(); 146344361Sborman int narg; 146444361Sborman }; 146544361Sborman 1466*46808Sdab extern struct env_lst * 1467*46808Sdab env_define P((unsigned char *, unsigned char *)); 1468*46808Sdab extern void 1469*46808Sdab env_undefine P((unsigned char *)), 1470*46808Sdab env_export P((unsigned char *)), 1471*46808Sdab env_unexport P((unsigned char *)), 1472*46808Sdab env_send P((unsigned char *)), 1473*46808Sdab env_list P((void)), 1474*46808Sdab env_help P((void)); 147544361Sborman 147644361Sborman struct envlist EnvList[] = { 147744361Sborman { "define", "Define an environment variable", 1478*46808Sdab (void (*)())env_define, 2 }, 147944361Sborman { "undefine", "Undefine an environment variable", 148044361Sborman env_undefine, 1 }, 148144361Sborman { "export", "Mark an environment variable for automatic export", 148244361Sborman env_export, 1 }, 1483*46808Sdab { "unexport", "Don't mark an environment variable for automatic export", 148444361Sborman env_unexport, 1 }, 148545233Sborman { "send", "Send an environment variable", env_send, 1 }, 148644361Sborman { "list", "List the current environment variables", 148744361Sborman env_list, 0 }, 148844361Sborman { "help", 0, env_help, 0 }, 148944361Sborman { "?", "Print help information", env_help, 0 }, 149044361Sborman { 0 }, 149144361Sborman }; 149244361Sborman 1493*46808Sdab static void 149444361Sborman env_help() 149544361Sborman { 149644361Sborman struct envlist *c; 149744361Sborman 149844361Sborman for (c = EnvList; c->name; c++) { 149944361Sborman if (c->help) { 150044361Sborman if (*c->help) 150144361Sborman printf("%-15s %s\n", c->name, c->help); 150244361Sborman else 150344361Sborman printf("\n"); 150444361Sborman } 150544361Sborman } 150644361Sborman } 150744361Sborman 1508*46808Sdab static struct envlist * 150944361Sborman getenvcmd(name) 1510*46808Sdab char *name; 151144361Sborman { 1512*46808Sdab return (struct envlist *) 1513*46808Sdab genget(name, (char **) EnvList, sizeof(struct envlist)); 151444361Sborman } 151544361Sborman 151644361Sborman env_cmd(argc, argv) 1517*46808Sdab int argc; 1518*46808Sdab char *argv[]; 151944361Sborman { 152044361Sborman struct envlist *c; 152144361Sborman 152244361Sborman if (argc < 2) { 152344361Sborman fprintf(stderr, 152444361Sborman "Need an argument to 'environ' command. 'environ ?' for help.\n"); 152544361Sborman return 0; 152644361Sborman } 152744361Sborman c = getenvcmd(argv[1]); 152844361Sborman if (c == 0) { 152944361Sborman fprintf(stderr, "'%s': unknown argument ('environ ?' for help).\n", 153044361Sborman argv[1]); 153144361Sborman return 0; 153244361Sborman } 153344361Sborman if (Ambiguous(c)) { 153444361Sborman fprintf(stderr, "'%s': ambiguous argument ('environ ?' for help).\n", 153544361Sborman argv[1]); 153644361Sborman return 0; 153744361Sborman } 153844361Sborman if (c->narg + 2 != argc) { 153944361Sborman fprintf(stderr, 154044361Sborman "Need %s%d argument%s to 'environ %s' command. 'environ ?' for help.\n", 154144361Sborman c->narg < argc + 2 ? "only " : "", 154244361Sborman c->narg, c->narg == 1 ? "" : "s", c->name); 154344361Sborman return 0; 154444361Sborman } 1545*46808Sdab (*c->handler)(argv[2], argv[3]); 154644361Sborman return 1; 154744361Sborman } 154844361Sborman 154944361Sborman struct env_lst { 155044361Sborman struct env_lst *next; /* pointer to next structure */ 155144361Sborman struct env_lst *prev; /* pointer to next structure */ 1552*46808Sdab unsigned char *var; /* pointer to variable name */ 1553*46808Sdab unsigned char *value; /* pointer to varialbe value */ 155444361Sborman int export; /* 1 -> export with default list of variables */ 155544361Sborman }; 155644361Sborman 155744361Sborman struct env_lst envlisthead; 155844361Sborman 1559*46808Sdab struct env_lst * 156044361Sborman env_find(var) 1561*46808Sdab unsigned char *var; 156244361Sborman { 156344361Sborman register struct env_lst *ep; 156444361Sborman 156544361Sborman for (ep = envlisthead.next; ep; ep = ep->next) { 1566*46808Sdab if (strcmp((char *)ep->var, (char *)var) == 0) 156744361Sborman return(ep); 156844361Sborman } 156944361Sborman return(NULL); 157044361Sborman } 157144361Sborman 1572*46808Sdab void 157344361Sborman env_init() 157444361Sborman { 1575*46808Sdab extern char **environ; 157644361Sborman register char **epp, *cp; 157744361Sborman register struct env_lst *ep; 1578*46808Sdab extern char *index(); 157944361Sborman 158044361Sborman for (epp = environ; *epp; epp++) { 158144361Sborman if (cp = index(*epp, '=')) { 158244361Sborman *cp = '\0'; 1583*46808Sdab ep = env_define((unsigned char *)*epp, 1584*46808Sdab (unsigned char *)cp+1); 158544361Sborman ep->export = 0; 158644361Sborman *cp = '='; 158744361Sborman } 158844361Sborman } 158944361Sborman /* 159044361Sborman * Special case for DISPLAY variable. If it is ":0.0" or 159144361Sborman * "unix:0.0", we have to get rid of "unix" and insert our 159244361Sborman * hostname. 159344361Sborman */ 1594*46808Sdab if ((ep = env_find("DISPLAY")) 1595*46808Sdab && ((*ep->value == ':') 1596*46808Sdab || (strncmp((char *)ep->value, "unix:", 5) == 0))) { 159744361Sborman char hbuf[256+1]; 1598*46808Sdab char *cp2 = index((char *)ep->value, ':'); 159944361Sborman 160044361Sborman gethostname(hbuf, 256); 160144361Sborman hbuf[256] = '\0'; 160244361Sborman cp = (char *)malloc(strlen(hbuf) + strlen(cp2) + 1); 1603*46808Sdab sprintf((char *)cp, "%s%s", hbuf, cp2); 160444361Sborman free(ep->value); 1605*46808Sdab ep->value = (unsigned char *)cp; 160644361Sborman } 160744361Sborman /* 160844361Sborman * If USER is not defined, but LOGNAME is, then add 160945233Sborman * USER with the value from LOGNAME. By default, we 161045233Sborman * don't export the USER variable. 161144361Sborman */ 161245233Sborman if ((env_find("USER") == NULL) && (ep = env_find("LOGNAME"))) { 1613*46808Sdab env_define((unsigned char *)"USER", ep->value); 1614*46808Sdab env_unexport((unsigned char *)"USER"); 161545233Sborman } 1616*46808Sdab env_export((unsigned char *)"DISPLAY"); 1617*46808Sdab env_export((unsigned char *)"PRINTER"); 161844361Sborman } 161944361Sborman 1620*46808Sdab struct env_lst * 162144361Sborman env_define(var, value) 1622*46808Sdab unsigned char *var, *value; 162344361Sborman { 162444361Sborman register struct env_lst *ep; 162544361Sborman 162644361Sborman if (ep = env_find(var)) { 162744361Sborman if (ep->var) 162844361Sborman free(ep->var); 162944361Sborman if (ep->value) 163044361Sborman free(ep->value); 163144361Sborman } else { 163244361Sborman ep = (struct env_lst *)malloc(sizeof(struct env_lst)); 163344361Sborman ep->next = envlisthead.next; 163444361Sborman envlisthead.next = ep; 163544361Sborman ep->prev = &envlisthead; 163644361Sborman if (ep->next) 163744361Sborman ep->next->prev = ep; 163844361Sborman } 163945009Skarels ep->export = 1; 1640*46808Sdab ep->var = (unsigned char *)strdup((char *)var); 1641*46808Sdab ep->value = (unsigned char *)strdup((char *)value); 164244361Sborman return(ep); 164344361Sborman } 164444361Sborman 1645*46808Sdab void 164644361Sborman env_undefine(var) 1647*46808Sdab unsigned char *var; 164844361Sborman { 164944361Sborman register struct env_lst *ep; 165044361Sborman 165144361Sborman if (ep = env_find(var)) { 165244361Sborman ep->prev->next = ep->next; 165345233Sborman if (ep->next) 165445233Sborman ep->next->prev = ep->prev; 165544361Sborman if (ep->var) 165644361Sborman free(ep->var); 165744361Sborman if (ep->value) 165844361Sborman free(ep->value); 165944361Sborman free(ep); 166044361Sborman } 166144361Sborman } 166244361Sborman 1663*46808Sdab void 166444361Sborman env_export(var) 1665*46808Sdab unsigned char *var; 166644361Sborman { 166744361Sborman register struct env_lst *ep; 166844361Sborman 166944361Sborman if (ep = env_find(var)) 167044361Sborman ep->export = 1; 167144361Sborman } 167244361Sborman 1673*46808Sdab void 167444361Sborman env_unexport(var) 1675*46808Sdab unsigned char *var; 167644361Sborman { 167744361Sborman register struct env_lst *ep; 167844361Sborman 167944361Sborman if (ep = env_find(var)) 168044361Sborman ep->export = 0; 168144361Sborman } 168244361Sborman 1683*46808Sdab void 168445233Sborman env_send(var) 1685*46808Sdab unsigned char *var; 168645233Sborman { 168745233Sborman register struct env_lst *ep; 168845233Sborman 168945233Sborman if (my_state_is_wont(TELOPT_ENVIRON)) { 169045233Sborman fprintf(stderr, 169145233Sborman "Cannot send '%s': Telnet ENVIRON option not enabled\n", 169245233Sborman var); 169345233Sborman return; 169445233Sborman } 169545233Sborman ep = env_find(var); 169645233Sborman if (ep == 0) { 169745233Sborman fprintf(stderr, "Cannot send '%s': variable not defined\n", 169845233Sborman var); 169945233Sborman return; 170045233Sborman } 170145233Sborman env_opt_start_info(); 170245233Sborman env_opt_add(ep->var); 170345233Sborman env_opt_end(0); 170445233Sborman } 170545233Sborman 1706*46808Sdab void 170744361Sborman env_list() 170844361Sborman { 170944361Sborman register struct env_lst *ep; 171044361Sborman 171144361Sborman for (ep = envlisthead.next; ep; ep = ep->next) { 171244361Sborman printf("%c %-20s %s\n", ep->export ? '*' : ' ', 171344361Sborman ep->var, ep->value); 171444361Sborman } 171544361Sborman } 171644361Sborman 1717*46808Sdab unsigned char * 171844361Sborman env_default(init) 1719*46808Sdab int init; 172044361Sborman { 172144361Sborman static struct env_lst *nep = NULL; 172244361Sborman 172344361Sborman if (init) { 172444361Sborman nep = &envlisthead; 172544361Sborman return; 172644361Sborman } 172744361Sborman if (nep) { 172844361Sborman while (nep = nep->next) { 172944361Sborman if (nep->export) 173044361Sborman return(nep->var); 173144361Sborman } 173244361Sborman } 173344361Sborman return(NULL); 173444361Sborman } 173544361Sborman 1736*46808Sdab unsigned char * 173744361Sborman env_getvalue(var) 1738*46808Sdab unsigned char *var; 173944361Sborman { 174044361Sborman register struct env_lst *ep; 174144361Sborman 174244361Sborman if (ep = env_find(var)) 174344361Sborman return(ep->value); 174444361Sborman return(NULL); 174544361Sborman } 174644361Sborman 1747*46808Sdab #if defined(AUTHENTICATE) 1748*46808Sdab /* 1749*46808Sdab * The AUTHENTICATE command. 1750*46808Sdab */ 1751*46808Sdab 1752*46808Sdab struct authlist { 1753*46808Sdab char *name; 1754*46808Sdab char *help; 1755*46808Sdab int (*handler)(); 1756*46808Sdab int narg; 1757*46808Sdab }; 1758*46808Sdab 1759*46808Sdab extern int 1760*46808Sdab auth_enable P((int)), 1761*46808Sdab auth_disable P((int)), 1762*46808Sdab auth_status P((void)), 1763*46808Sdab auth_togdebug P((void)), 1764*46808Sdab auth_help P((void)); 1765*46808Sdab 1766*46808Sdab struct authlist AuthList[] = { 1767*46808Sdab { "status", "Display current status of authentication information", 1768*46808Sdab auth_status, 0 }, 1769*46808Sdab { "debug", "Toggle authentication debugging", 1770*46808Sdab auth_togdebug, 0 }, 1771*46808Sdab { "disable", "Disable an authentication type ('auth disable ?' for more)", 1772*46808Sdab auth_disable, 1 }, 1773*46808Sdab { "enable", "Enable an authentication type ('auth enable ?' for more)", 1774*46808Sdab auth_enable, 1 }, 1775*46808Sdab { "help", 0, auth_help, 0 }, 1776*46808Sdab { "?", "Print help information", auth_help, 0 }, 1777*46808Sdab { 0 }, 1778*46808Sdab }; 1779*46808Sdab 1780*46808Sdab static int 1781*46808Sdab auth_help() 178244361Sborman { 1783*46808Sdab struct authlist *c; 1784*46808Sdab 1785*46808Sdab for (c = AuthList; c->name; c++) { 1786*46808Sdab if (c->help) { 1787*46808Sdab if (*c->help) 1788*46808Sdab printf("%-15s %s\n", c->name, c->help); 1789*46808Sdab else 1790*46808Sdab printf("\n"); 1791*46808Sdab } 1792*46808Sdab } 1793*46808Sdab return 0; 179444361Sborman } 1795*46808Sdab 1796*46808Sdab auth_cmd(argc, argv) 1797*46808Sdab int argc; 1798*46808Sdab char *argv[]; 1799*46808Sdab { 1800*46808Sdab struct authlist *c; 1801*46808Sdab 1802*46808Sdab c = (struct authlist *) 1803*46808Sdab genget(argv[1], (char **) AuthList, sizeof(struct authlist)); 1804*46808Sdab if (c == 0) { 1805*46808Sdab fprintf(stderr, "'%s': unknown argument ('auth ?' for help).\n", 1806*46808Sdab argv[1]); 1807*46808Sdab return 0; 1808*46808Sdab } 1809*46808Sdab if (Ambiguous(c)) { 1810*46808Sdab fprintf(stderr, "'%s': ambiguous argument ('auth ?' for help).\n", 1811*46808Sdab argv[1]); 1812*46808Sdab return 0; 1813*46808Sdab } 1814*46808Sdab if (c->narg + 2 != argc) { 1815*46808Sdab fprintf(stderr, 1816*46808Sdab "Need %s%d argument%s to 'auth %s' command. 'auth ?' for help.\n", 1817*46808Sdab c->narg < argc + 2 ? "only " : "", 1818*46808Sdab c->narg, c->narg == 1 ? "" : "s", c->name); 1819*46808Sdab return 0; 1820*46808Sdab } 1821*46808Sdab return((*c->handler)(argv[2], argv[3])); 1822*46808Sdab } 182345233Sborman #endif 182444361Sborman 1825*46808Sdab #if defined(ENCRYPT) 182632144Sminshall /* 1827*46808Sdab * The ENCRYPT command. 182836274Sminshall */ 182936274Sminshall 1830*46808Sdab struct encryptlist { 1831*46808Sdab char *name; 1832*46808Sdab char *help; 1833*46808Sdab int (*handler)(); 1834*46808Sdab int needconnect; 1835*46808Sdab int minarg; 1836*46808Sdab int maxarg; 1837*46808Sdab }; 1838*46808Sdab 1839*46808Sdab extern int 1840*46808Sdab EncryptEnable P((char *, char *)), 1841*46808Sdab EncryptType P((char *, char *)), 1842*46808Sdab EncryptStart P((char *)), 1843*46808Sdab EncryptStartInput P((void)), 1844*46808Sdab EncryptStartOutput P((void)), 1845*46808Sdab EncryptStop P((char *)), 1846*46808Sdab EncryptStopInput P((void)), 1847*46808Sdab EncryptStopOutput P((void)), 1848*46808Sdab EncryptTogAuto P((void)), 1849*46808Sdab EncryptTogDebug P((void)), 1850*46808Sdab EncryptTogVerbose P((void)), 1851*46808Sdab EncryptStatus P((void)), 1852*46808Sdab EncryptHelp P((void)); 1853*46808Sdab 1854*46808Sdab struct encryptlist EncryptList[] = { 1855*46808Sdab { "enable", "Enable encryption. ('encrypt enable ?' for more)", 1856*46808Sdab EncryptEnable, 1, 1, 2 }, 1857*46808Sdab { "type", "Set encryptiong type. ('encrypt type ?' for more)", 1858*46808Sdab EncryptType, 0, 1, 1 }, 1859*46808Sdab { "start", "Start encryption. ('encrypt start ?' for more)", 1860*46808Sdab EncryptStart, 1, 0, 1 }, 1861*46808Sdab { "stop", "Stop encryption. ('encrypt stop ?' for more)", 1862*46808Sdab EncryptStop, 1, 0, 1 }, 1863*46808Sdab { "input", "Start encrypting the input stream", 1864*46808Sdab EncryptStartInput, 1, 0, 0 }, 1865*46808Sdab { "-input", "Stop encrypting the input stream", 1866*46808Sdab EncryptStopInput, 1, 0, 0 }, 1867*46808Sdab { "output", "Start encrypting the output stream", 1868*46808Sdab EncryptStartOutput, 1, 0, 0 }, 1869*46808Sdab { "-output", "Stop encrypting the output stream", 1870*46808Sdab EncryptStopOutput, 1, 0, 0 }, 1871*46808Sdab 1872*46808Sdab { "status", "Display current status of authentication information", 1873*46808Sdab EncryptStatus, 0, 0, 0 }, 1874*46808Sdab { "auto", "Toggle automatic enabling of encryption", 1875*46808Sdab EncryptTogAuto, 0, 0, 0 }, 1876*46808Sdab { "verbose", "Toggle verbose encryption output", 1877*46808Sdab EncryptTogVerbose, 0, 0, 0 }, 1878*46808Sdab { "debug", "Toggle encryption debugging", 1879*46808Sdab EncryptTogDebug, 0, 0, 0 }, 1880*46808Sdab { "help", 0, EncryptHelp, 0, 0, 0 }, 1881*46808Sdab { "?", "Print help information", EncryptHelp, 0, 0, 0 }, 1882*46808Sdab { 0 }, 1883*46808Sdab }; 1884*46808Sdab 1885*46808Sdab static int 1886*46808Sdab EncryptHelp() 188736274Sminshall { 1888*46808Sdab struct encryptlist *c; 1889*46808Sdab 1890*46808Sdab for (c = EncryptList; c->name; c++) { 1891*46808Sdab if (c->help) { 1892*46808Sdab if (*c->help) 1893*46808Sdab printf("%-15s %s\n", c->name, c->help); 1894*46808Sdab else 1895*46808Sdab printf("\n"); 189636274Sminshall } 1897*46808Sdab } 1898*46808Sdab return 0; 1899*46808Sdab } 190036274Sminshall 1901*46808Sdab encrypt_cmd(argc, argv) 1902*46808Sdab int argc; 1903*46808Sdab char *argv[]; 1904*46808Sdab { 1905*46808Sdab struct encryptlist *c; 190636274Sminshall 1907*46808Sdab c = (struct encryptlist *) 1908*46808Sdab genget(argv[1], (char **) EncryptList, sizeof(struct encryptlist)); 1909*46808Sdab if (c == 0) { 1910*46808Sdab fprintf(stderr, "'%s': unknown argument ('encrypt ?' for help).\n", 1911*46808Sdab argv[1]); 1912*46808Sdab return 0; 1913*46808Sdab } 1914*46808Sdab if (Ambiguous(c)) { 1915*46808Sdab fprintf(stderr, "'%s': ambiguous argument ('encrypt ?' for help).\n", 1916*46808Sdab argv[1]); 1917*46808Sdab return 0; 1918*46808Sdab } 1919*46808Sdab argc -= 2; 1920*46808Sdab if (argc < c->minarg || argc > c->maxarg) { 1921*46808Sdab if (c->minarg == c->maxarg) { 1922*46808Sdab fprintf(stderr, "Need %s%d argument%s ", 1923*46808Sdab c->minarg < argc ? "only " : "", c->minarg, 1924*46808Sdab c->minarg == 1 ? "" : "s"); 1925*46808Sdab } else { 1926*46808Sdab fprintf(stderr, "Need %s%d-%d arguments ", 1927*46808Sdab c->maxarg < argc ? "only " : "", c->minarg, c->maxarg); 1928*46808Sdab } 1929*46808Sdab fprintf(stderr, "to 'encrypt %s' command. 'encrypt ?' for help.\n", 1930*46808Sdab c->name); 1931*46808Sdab return 0; 1932*46808Sdab } 1933*46808Sdab if (c->needconnect && !connected) { 1934*46808Sdab if (!(argc && (isprefix(argv[2], "help") || isprefix(argv[2], "?")))) { 1935*46808Sdab printf("?Need to be connected first.\n"); 1936*46808Sdab return 0; 1937*46808Sdab } 1938*46808Sdab } 1939*46808Sdab return ((*c->handler)(argc > 0 ? argv[2] : 0, 1940*46808Sdab argc > 1 ? argv[3] : 0, 1941*46808Sdab argc > 2 ? argv[4] : 0)); 1942*46808Sdab } 194336274Sminshall #endif 194436274Sminshall 1945*46808Sdab #if defined(unix) && defined(TN3270) 1946*46808Sdab static void 194736274Sminshall filestuff(fd) 1948*46808Sdab int fd; 194936274Sminshall { 195036274Sminshall int res; 195136274Sminshall 195238689Sborman #ifdef F_GETOWN 195338689Sborman setconnmode(0); 195436274Sminshall res = fcntl(fd, F_GETOWN, 0); 195536274Sminshall setcommandmode(); 195636274Sminshall 195736274Sminshall if (res == -1) { 195836274Sminshall perror("fcntl"); 195936274Sminshall return; 196036274Sminshall } 196136274Sminshall printf("\tOwner is %d.\n", res); 196238689Sborman #endif 196336274Sminshall 196438689Sborman setconnmode(0); 196536274Sminshall res = fcntl(fd, F_GETFL, 0); 196636274Sminshall setcommandmode(); 196736274Sminshall 196836274Sminshall if (res == -1) { 196936274Sminshall perror("fcntl"); 197036274Sminshall return; 197136274Sminshall } 197236274Sminshall printf("\tFlags are 0x%x: %s\n", res, decodeflags(res)); 197336274Sminshall } 1974*46808Sdab #endif /* defined(unix) && defined(TN3270) */ 197536274Sminshall 197636274Sminshall /* 197732144Sminshall * Print status about the connection. 197832144Sminshall */ 1979*46808Sdab /*ARGSUSED*/ 1980*46808Sdab static 198132144Sminshall status(argc, argv) 1982*46808Sdab int argc; 1983*46808Sdab char *argv[]; 198432144Sminshall { 198532144Sminshall if (connected) { 198632144Sminshall printf("Connected to %s.\n", hostname); 198736242Sminshall if ((argc < 2) || strcmp(argv[1], "notmuch")) { 198838689Sborman int mode = getconnmode(); 198938689Sborman 199038689Sborman if (my_want_state_is_will(TELOPT_LINEMODE)) { 199138689Sborman printf("Operating with LINEMODE option\n"); 199238689Sborman printf("%s line editing\n", (mode&MODE_EDIT) ? "Local" : "No"); 199338689Sborman printf("%s catching of signals\n", 199438689Sborman (mode&MODE_TRAPSIG) ? "Local" : "No"); 199538689Sborman slcstate(); 199638689Sborman #ifdef KLUDGELINEMODE 199739529Sborman } else if (kludgelinemode && my_want_state_is_dont(TELOPT_SGA)) { 199838689Sborman printf("Operating in obsolete linemode\n"); 199938689Sborman #endif 200038689Sborman } else { 200138689Sborman printf("Operating in single character mode\n"); 200238689Sborman if (localchars) 200338689Sborman printf("Catching signals locally\n"); 200432144Sminshall } 200538689Sborman printf("%s character echo\n", (mode&MODE_ECHO) ? "Local" : "Remote"); 200638689Sborman if (my_want_state_is_will(TELOPT_LFLOW)) 200738689Sborman printf("%s flow control\n", (mode&MODE_FLOW) ? "Local" : "No"); 2008*46808Sdab #if defined(ENCRYPT) 2009*46808Sdab encrypt_display(); 2010*46808Sdab #endif 201132144Sminshall } 201232144Sminshall } else { 201332144Sminshall printf("No connection.\n"); 201432144Sminshall } 201532144Sminshall # if !defined(TN3270) 201632144Sminshall printf("Escape character is '%s'.\n", control(escape)); 201734849Sminshall (void) fflush(stdout); 201832144Sminshall # else /* !defined(TN3270) */ 201932144Sminshall if ((!In3270) && ((argc < 2) || strcmp(argv[1], "notmuch"))) { 202032144Sminshall printf("Escape character is '%s'.\n", control(escape)); 202132144Sminshall } 202232144Sminshall # if defined(unix) 202336242Sminshall if ((argc >= 2) && !strcmp(argv[1], "everything")) { 202436242Sminshall printf("SIGIO received %d time%s.\n", 202536242Sminshall sigiocount, (sigiocount == 1)? "":"s"); 202636274Sminshall if (In3270) { 202736274Sminshall printf("Process ID %d, process group %d.\n", 202836274Sminshall getpid(), getpgrp(getpid())); 202936274Sminshall printf("Terminal input:\n"); 203036274Sminshall filestuff(tin); 203136274Sminshall printf("Terminal output:\n"); 203236274Sminshall filestuff(tout); 203336274Sminshall printf("Network socket:\n"); 203436274Sminshall filestuff(net); 203536274Sminshall } 203636242Sminshall } 203732144Sminshall if (In3270 && transcom) { 203832144Sminshall printf("Transparent mode command is '%s'.\n", transcom); 203932144Sminshall } 204032144Sminshall # endif /* defined(unix) */ 204134849Sminshall (void) fflush(stdout); 204232144Sminshall if (In3270) { 204332144Sminshall return 0; 204432144Sminshall } 204532144Sminshall # endif /* defined(TN3270) */ 204632144Sminshall return 1; 204732144Sminshall } 204832144Sminshall 204945233Sborman #ifdef SIGINFO 205045233Sborman /* 205145233Sborman * Function that gets called when SIGINFO is received. 205245233Sborman */ 205345233Sborman ayt_status() 205445233Sborman { 205545233Sborman (void) call(status, "status", "notmuch", 0); 205645233Sborman } 205745233Sborman #endif 205832144Sminshall 2059*46808Sdab int 206032144Sminshall tn(argc, argv) 2061*46808Sdab int argc; 2062*46808Sdab char *argv[]; 206332144Sminshall { 206432144Sminshall register struct hostent *host = 0; 206532144Sminshall struct sockaddr_in sin; 206632144Sminshall struct servent *sp = 0; 206738689Sborman unsigned long temp, inet_addr(); 206837219Sminshall extern char *inet_ntoa(); 2069*46808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 207038689Sborman char *srp = 0, *strrchr(); 207138689Sborman unsigned long sourceroute(), srlen; 207238689Sborman #endif 207344361Sborman char *cmd, *hostp = 0, *portp = 0, *user = 0; 207432144Sminshall 207545233Sborman /* clear the socket address prior to use */ 207645233Sborman bzero((char *)&sin, sizeof(sin)); 207732144Sminshall 207832144Sminshall if (connected) { 207932144Sminshall printf("?Already connected to %s\n", hostname); 2080*46808Sdab setuid(getuid()); 208132144Sminshall return 0; 208232144Sminshall } 208332144Sminshall if (argc < 2) { 2084*46808Sdab (void) strcpy(line, "open "); 208532144Sminshall printf("(to) "); 2086*46808Sdab (void) fgets(&line[strlen(line)], sizeof(line) - strlen(line), stdin); 208732144Sminshall makeargv(); 208832144Sminshall argc = margc; 208932144Sminshall argv = margv; 209032144Sminshall } 209144361Sborman cmd = *argv; 209244361Sborman --argc; ++argv; 209344361Sborman while (argc) { 2094*46808Sdab if (isprefix(*argv, "help") || isprefix(*argv, "?")) 2095*46808Sdab goto usage; 209644361Sborman if (strcmp(*argv, "-l") == 0) { 209744361Sborman --argc; ++argv; 209844361Sborman if (argc == 0) 209944361Sborman goto usage; 210044361Sborman user = *argv++; 210144361Sborman --argc; 210244361Sborman continue; 210344361Sborman } 210445233Sborman if (strcmp(*argv, "-a") == 0) { 210545233Sborman --argc; ++argv; 210645233Sborman autologin = 1; 210745233Sborman continue; 210845233Sborman } 210944361Sborman if (hostp == 0) { 211044361Sborman hostp = *argv++; 211144361Sborman --argc; 211244361Sborman continue; 211344361Sborman } 211444361Sborman if (portp == 0) { 211544361Sborman portp = *argv++; 211644361Sborman --argc; 211744361Sborman continue; 211844361Sborman } 211944361Sborman usage: 212045233Sborman printf("usage: %s [-l user] [-a] host-name [port]\n", cmd); 2121*46808Sdab setuid(getuid()); 212232144Sminshall return 0; 212332144Sminshall } 2124*46808Sdab if (hostp == 0) 2125*46808Sdab goto usage; 2126*46808Sdab 2127*46808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 212844361Sborman if (hostp[0] == '@' || hostp[0] == '!') { 212944361Sborman if ((hostname = strrchr(hostp, ':')) == NULL) 213044361Sborman hostname = strrchr(hostp, '@'); 213138689Sborman hostname++; 213238689Sborman srp = 0; 213344361Sborman temp = sourceroute(hostp, &srp, &srlen); 213438689Sborman if (temp == 0) { 213538689Sborman herror(srp); 2136*46808Sdab setuid(getuid()); 213738689Sborman return 0; 213838689Sborman } else if (temp == -1) { 213944361Sborman printf("Bad source route option: %s\n", hostp); 2140*46808Sdab setuid(getuid()); 214138689Sborman return 0; 214238689Sborman } else { 214338689Sborman sin.sin_addr.s_addr = temp; 214438689Sborman sin.sin_family = AF_INET; 214538689Sborman } 214632144Sminshall } else { 214738689Sborman #endif 214844361Sborman temp = inet_addr(hostp); 214938689Sborman if (temp != (unsigned long) -1) { 215038689Sborman sin.sin_addr.s_addr = temp; 215138689Sborman sin.sin_family = AF_INET; 2152*46808Sdab (void) strcpy(_hostname, hostp); 2153*46808Sdab hostname = _hostname; 215438689Sborman } else { 215544361Sborman host = gethostbyname(hostp); 215638689Sborman if (host) { 215738689Sborman sin.sin_family = host->h_addrtype; 215832144Sminshall #if defined(h_addr) /* In 4.3, this is a #define */ 215938689Sborman memcpy((caddr_t)&sin.sin_addr, 216032144Sminshall host->h_addr_list[0], host->h_length); 216132144Sminshall #else /* defined(h_addr) */ 216238689Sborman memcpy((caddr_t)&sin.sin_addr, host->h_addr, host->h_length); 216332144Sminshall #endif /* defined(h_addr) */ 2164*46808Sdab strncpy(_hostname, host->h_name, sizeof(_hostname)); 2165*46808Sdab _hostname[sizeof(_hostname)-1] = '\0'; 2166*46808Sdab hostname = _hostname; 216738689Sborman } else { 216844361Sborman herror(hostp); 2169*46808Sdab setuid(getuid()); 217038689Sborman return 0; 217138689Sborman } 217232144Sminshall } 2173*46808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 217432144Sminshall } 217538689Sborman #endif 217644361Sborman if (portp) { 217744361Sborman if (*portp == '-') { 217844361Sborman portp++; 217938689Sborman telnetport = 1; 218038689Sborman } else 218138689Sborman telnetport = 0; 218244361Sborman sin.sin_port = atoi(portp); 218332144Sminshall if (sin.sin_port == 0) { 218444361Sborman sp = getservbyname(portp, "tcp"); 218532144Sminshall if (sp) 218632144Sminshall sin.sin_port = sp->s_port; 218732144Sminshall else { 218844361Sborman printf("%s: bad port number\n", portp); 2189*46808Sdab setuid(getuid()); 219032144Sminshall return 0; 219132144Sminshall } 219232144Sminshall } else { 219334849Sminshall #if !defined(htons) 219434849Sminshall u_short htons(); 219534849Sminshall #endif /* !defined(htons) */ 219632144Sminshall sin.sin_port = htons(sin.sin_port); 219732144Sminshall } 219832144Sminshall } else { 219932144Sminshall if (sp == 0) { 220032144Sminshall sp = getservbyname("telnet", "tcp"); 220132144Sminshall if (sp == 0) { 220234849Sminshall fprintf(stderr, "telnet: tcp/telnet: unknown service\n"); 2203*46808Sdab setuid(getuid()); 220432144Sminshall return 0; 220532144Sminshall } 220632144Sminshall sin.sin_port = sp->s_port; 220732144Sminshall } 220832144Sminshall telnetport = 1; 220932144Sminshall } 221037219Sminshall printf("Trying %s...\n", inet_ntoa(sin.sin_addr)); 221132144Sminshall do { 221232144Sminshall net = socket(AF_INET, SOCK_STREAM, 0); 2213*46808Sdab setuid(getuid()); 221432144Sminshall if (net < 0) { 221532144Sminshall perror("telnet: socket"); 221632144Sminshall return 0; 221732144Sminshall } 2218*46808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 221938689Sborman if (srp && setsockopt(net, IPPROTO_IP, IP_OPTIONS, (char *)srp, srlen) < 0) 222038689Sborman perror("setsockopt (IP_OPTIONS)"); 222138689Sborman #endif 2222*46808Sdab #if defined(IPPROTO_IP) && defined(IP_TOS) 2223*46808Sdab { 2224*46808Sdab int tos = 020; /* Low Delay bit */ 2225*46808Sdab # if defined(HAS_GETTOS) 2226*46808Sdab struct tosent *tp; 2227*46808Sdab if (tp = gettosbyname("telnet", "tcp")) 2228*46808Sdab tos = tp->t_tos; 2229*46808Sdab # endif 2230*46808Sdab (void)setsockopt(net, IPPROTO_IP, IP_TOS, &tos, sizeof(int)); 2231*46808Sdab } 2232*46808Sdab #endif /* defined(IPPROTO_IP) && defined(IP_TOS) */ 223340245Sborman 223432144Sminshall if (debug && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 1) < 0) { 223532144Sminshall perror("setsockopt (SO_DEBUG)"); 223632144Sminshall } 223732144Sminshall 223832144Sminshall if (connect(net, (struct sockaddr *)&sin, sizeof (sin)) < 0) { 223932144Sminshall #if defined(h_addr) /* In 4.3, this is a #define */ 224032144Sminshall if (host && host->h_addr_list[1]) { 224132144Sminshall int oerrno = errno; 224232144Sminshall 224332144Sminshall fprintf(stderr, "telnet: connect to address %s: ", 224432144Sminshall inet_ntoa(sin.sin_addr)); 224532144Sminshall errno = oerrno; 224632144Sminshall perror((char *)0); 224732144Sminshall host->h_addr_list++; 224832144Sminshall memcpy((caddr_t)&sin.sin_addr, 224932144Sminshall host->h_addr_list[0], host->h_length); 225032144Sminshall (void) NetClose(net); 225132144Sminshall continue; 225232144Sminshall } 225332144Sminshall #endif /* defined(h_addr) */ 225432144Sminshall perror("telnet: Unable to connect to remote host"); 225532144Sminshall return 0; 225637219Sminshall } 225732144Sminshall connected++; 2258*46808Sdab #if defined(AUTHENTICATE) || defined(ENCRYPT) 2259*46808Sdab auth_encrypt_connect(connected); 2260*46808Sdab #endif 226132144Sminshall } while (connected == 0); 226244361Sborman cmdrc(hostp, hostname); 226345008Skarels if (autologin && user == NULL) { 226445008Skarels struct passwd *pw; 226545008Skarels 226645233Sborman user = getenv("USER"); 226745008Skarels if (user == NULL || 226845233Sborman (pw = getpwnam(user)) && pw->pw_uid != getuid()) { 226945233Sborman if (pw = getpwuid(getuid())) 227045008Skarels user = pw->pw_name; 227145008Skarels else 227245008Skarels user = NULL; 227345233Sborman } 227445008Skarels } 227545008Skarels if (user) { 2276*46808Sdab env_define((unsigned char *)"USER", (unsigned char *)user); 2277*46808Sdab env_export((unsigned char *)"USER"); 227845008Skarels } 227934849Sminshall (void) call(status, "status", "notmuch", 0); 228032144Sminshall if (setjmp(peerdied) == 0) 2281*46808Sdab telnet(user); 228234849Sminshall (void) NetClose(net); 228332381Sminshall ExitString("Connection closed by foreign host.\n",1); 228432144Sminshall /*NOTREACHED*/ 228532144Sminshall } 228632144Sminshall 228732144Sminshall #define HELPINDENT (sizeof ("connect")) 228832144Sminshall 228932144Sminshall static char 229032144Sminshall openhelp[] = "connect to a site", 229132144Sminshall closehelp[] = "close current connection", 2292*46808Sdab logouthelp[] = "forcibly logout remote user and close the connection", 229332144Sminshall quithelp[] = "exit telnet", 229432144Sminshall statushelp[] = "print status information", 229532144Sminshall helphelp[] = "print help information", 229632144Sminshall sendhelp[] = "transmit special characters ('send ?' for more)", 229732144Sminshall sethelp[] = "set operating parameters ('set ?' for more)", 229838689Sborman unsethelp[] = "unset operating parameters ('unset ?' for more)", 229932144Sminshall togglestring[] ="toggle operating parameters ('toggle ?' for more)", 230038689Sborman slchelp[] = "change state of special charaters ('slc ?' for more)", 230132144Sminshall displayhelp[] = "display operating parameters", 230232144Sminshall #if defined(TN3270) && defined(unix) 230332144Sminshall transcomhelp[] = "specify Unix command for transparent mode pipe", 230432144Sminshall #endif /* defined(TN3270) && defined(unix) */ 2305*46808Sdab #if defined(AUTHENTICATE) 2306*46808Sdab authhelp[] = "turn on (off) authentication ('auth ?' for more)", 2307*46808Sdab #endif 2308*46808Sdab #if defined(ENCRYPT) 2309*46808Sdab encrypthelp[] = "turn on (off) encryption ('encrypt ?' for more)", 2310*46808Sdab #endif 231132144Sminshall #if defined(unix) 231232144Sminshall zhelp[] = "suspend telnet", 231343317Skfall #endif /* defined(unix) */ 231432144Sminshall shellhelp[] = "invoke a subshell", 231544361Sborman envhelp[] = "change environment variables ('environ ?' for more)", 231644361Sborman modestring[] = "try to enter line or character mode ('mode ?' for more)"; 231732144Sminshall 2318*46808Sdab extern int help(); 231932144Sminshall 232032144Sminshall static Command cmdtab[] = { 232138689Sborman { "close", closehelp, bye, 1 }, 2322*46808Sdab { "logout", logouthelp, logout, 1 }, 232338689Sborman { "display", displayhelp, display, 0 }, 232438689Sborman { "mode", modestring, modecmd, 0 }, 232538689Sborman { "open", openhelp, tn, 0 }, 232638689Sborman { "quit", quithelp, quit, 0 }, 232738689Sborman { "send", sendhelp, sendcmd, 0 }, 232838689Sborman { "set", sethelp, setcmd, 0 }, 232938689Sborman { "unset", unsethelp, unsetcmd, 0 }, 233038689Sborman { "status", statushelp, status, 0 }, 233138689Sborman { "toggle", togglestring, toggle, 0 }, 233238689Sborman { "slc", slchelp, slccmd, 0 }, 233332144Sminshall #if defined(TN3270) && defined(unix) 233438689Sborman { "transcom", transcomhelp, settranscom, 0 }, 233532144Sminshall #endif /* defined(TN3270) && defined(unix) */ 2336*46808Sdab #if defined(AUTHENTICATE) 2337*46808Sdab { "auth", authhelp, auth_cmd, 0 }, 2338*46808Sdab #endif 2339*46808Sdab #if defined(ENCRYPT) 2340*46808Sdab { "encrypt", encrypthelp, encrypt_cmd, 0 }, 2341*46808Sdab #endif 234232144Sminshall #if defined(unix) 234338689Sborman { "z", zhelp, suspend, 0 }, 234432144Sminshall #endif /* defined(unix) */ 234532144Sminshall #if defined(TN3270) 234638689Sborman { "!", shellhelp, shell, 1 }, 234738689Sborman #else 234838689Sborman { "!", shellhelp, shell, 0 }, 234938689Sborman #endif 235044361Sborman { "environ", envhelp, env_cmd, 0 }, 235138689Sborman { "?", helphelp, help, 0 }, 235232144Sminshall 0 235332144Sminshall }; 235432144Sminshall 235532144Sminshall static char crmodhelp[] = "deprecated command -- use 'toggle crmod' instead"; 235632144Sminshall static char escapehelp[] = "deprecated command -- use 'set escape' instead"; 235732144Sminshall 235832144Sminshall static Command cmdtab2[] = { 235938689Sborman { "help", 0, help, 0 }, 236038689Sborman { "escape", escapehelp, setescape, 0 }, 236138689Sborman { "crmod", crmodhelp, togcrmod, 0 }, 236232144Sminshall 0 236332144Sminshall }; 236432144Sminshall 236535298Sminshall 236632144Sminshall /* 236732144Sminshall * Call routine with argc, argv set from args (terminated by 0). 236832144Sminshall */ 236935298Sminshall 2370*46808Sdab /*VARARGS1*/ 2371*46808Sdab static 237235298Sminshall call(va_alist) 2373*46808Sdab va_dcl 237432144Sminshall { 237535298Sminshall va_list ap; 237635298Sminshall typedef int (*intrtn_t)(); 237735298Sminshall intrtn_t routine; 237835298Sminshall char *args[100]; 237935298Sminshall int argno = 0; 238035298Sminshall 238135298Sminshall va_start(ap); 238235298Sminshall routine = (va_arg(ap, intrtn_t)); 238335495Sminshall while ((args[argno++] = va_arg(ap, char *)) != 0) { 238435298Sminshall ; 238535495Sminshall } 238635298Sminshall va_end(ap); 238735495Sminshall return (*routine)(argno-1, args); 238832144Sminshall } 238932144Sminshall 239035298Sminshall 2391*46808Sdab static Command * 239232144Sminshall getcmd(name) 2393*46808Sdab char *name; 239432144Sminshall { 239532144Sminshall Command *cm; 239632144Sminshall 2397*46808Sdab if (cm = (Command *) genget(name, (char **) cmdtab, sizeof(Command))) 239832144Sminshall return cm; 2399*46808Sdab return (Command *) genget(name, (char **) cmdtab2, sizeof(Command)); 240032144Sminshall } 240132144Sminshall 2402*46808Sdab void 240338689Sborman command(top, tbuf, cnt) 2404*46808Sdab int top; 2405*46808Sdab char *tbuf; 2406*46808Sdab int cnt; 240732144Sminshall { 240832144Sminshall register Command *c; 240932144Sminshall 241032144Sminshall setcommandmode(); 241132144Sminshall if (!top) { 241232144Sminshall putchar('\n'); 241337219Sminshall #if defined(unix) 241432144Sminshall } else { 241544361Sborman (void) signal(SIGINT, SIG_DFL); 241644361Sborman (void) signal(SIGQUIT, SIG_DFL); 241732144Sminshall #endif /* defined(unix) */ 241832144Sminshall } 241932144Sminshall for (;;) { 2420*46808Sdab if (rlogin == _POSIX_VDISABLE) 2421*46808Sdab printf("%s> ", prompt); 242238689Sborman if (tbuf) { 242338689Sborman register char *cp; 242438689Sborman cp = line; 242538689Sborman while (cnt > 0 && (*cp++ = *tbuf++) != '\n') 242638689Sborman cnt--; 242738689Sborman tbuf = 0; 242838689Sborman if (cp == line || *--cp != '\n' || cp == line) 242938689Sborman goto getline; 243038689Sborman *cp = '\0'; 2431*46808Sdab if (rlogin == _POSIX_VDISABLE) 2432*46808Sdab printf("%s\n", line); 243338689Sborman } else { 243438689Sborman getline: 2435*46808Sdab if (rlogin != _POSIX_VDISABLE) 2436*46808Sdab printf("%s> ", prompt); 2437*46808Sdab if (fgets(line, sizeof(line), stdin) == NULL) { 243844361Sborman if (feof(stdin) || ferror(stdin)) { 243944361Sborman (void) quit(); 244044361Sborman /*NOTREACHED*/ 244144361Sborman } 244238689Sborman break; 244338689Sborman } 244432144Sminshall } 244532144Sminshall if (line[0] == 0) 244632144Sminshall break; 244732144Sminshall makeargv(); 244837219Sminshall if (margv[0] == 0) { 244937219Sminshall break; 245037219Sminshall } 245132144Sminshall c = getcmd(margv[0]); 245232144Sminshall if (Ambiguous(c)) { 245332144Sminshall printf("?Ambiguous command\n"); 245432144Sminshall continue; 245532144Sminshall } 245632144Sminshall if (c == 0) { 245732144Sminshall printf("?Invalid command\n"); 245832144Sminshall continue; 245932144Sminshall } 246032144Sminshall if (c->needconnect && !connected) { 246132144Sminshall printf("?Need to be connected first.\n"); 246232144Sminshall continue; 246332144Sminshall } 246432144Sminshall if ((*c->handler)(margc, margv)) { 246532144Sminshall break; 246632144Sminshall } 246732144Sminshall } 246832144Sminshall if (!top) { 246932144Sminshall if (!connected) { 247032144Sminshall longjmp(toplevel, 1); 247132144Sminshall /*NOTREACHED*/ 247232144Sminshall } 247332144Sminshall #if defined(TN3270) 247432144Sminshall if (shell_active == 0) { 247538689Sborman setconnmode(0); 247632144Sminshall } 247732144Sminshall #else /* defined(TN3270) */ 247838689Sborman setconnmode(0); 247932144Sminshall #endif /* defined(TN3270) */ 248032144Sminshall } 248132144Sminshall } 248232144Sminshall 248332144Sminshall /* 248432144Sminshall * Help command. 248532144Sminshall */ 2486*46808Sdab static 248732144Sminshall help(argc, argv) 248832144Sminshall int argc; 248932144Sminshall char *argv[]; 249032144Sminshall { 249132144Sminshall register Command *c; 249232144Sminshall 249332144Sminshall if (argc == 1) { 249432144Sminshall printf("Commands may be abbreviated. Commands are:\n\n"); 249532144Sminshall for (c = cmdtab; c->name; c++) 249638689Sborman if (c->help) { 249732144Sminshall printf("%-*s\t%s\n", HELPINDENT, c->name, 249832144Sminshall c->help); 249932144Sminshall } 250032144Sminshall return 0; 250132144Sminshall } 250232144Sminshall while (--argc > 0) { 250332144Sminshall register char *arg; 250432144Sminshall arg = *++argv; 250532144Sminshall c = getcmd(arg); 250632144Sminshall if (Ambiguous(c)) 250732144Sminshall printf("?Ambiguous help command %s\n", arg); 250832144Sminshall else if (c == (Command *)0) 250932144Sminshall printf("?Invalid help command %s\n", arg); 251032144Sminshall else 251132144Sminshall printf("%s\n", c->help); 251232144Sminshall } 251332144Sminshall return 0; 251432144Sminshall } 251538689Sborman 251638689Sborman static char *rcname = 0; 251738689Sborman static char rcbuf[128]; 251838689Sborman 251938689Sborman cmdrc(m1, m2) 252038689Sborman char *m1, *m2; 252138689Sborman { 252238689Sborman register Command *c; 252338689Sborman FILE *rcfile; 252438689Sborman int gotmachine = 0; 252538689Sborman int l1 = strlen(m1); 252638689Sborman int l2 = strlen(m2); 252738689Sborman char m1save[64]; 252838689Sborman 252938689Sborman strcpy(m1save, m1); 253038689Sborman m1 = m1save; 253138689Sborman 253238689Sborman if (rcname == 0) { 253338689Sborman rcname = getenv("HOME"); 253438689Sborman if (rcname) 253538689Sborman strcpy(rcbuf, rcname); 253638689Sborman else 253738689Sborman rcbuf[0] = '\0'; 253838689Sborman strcat(rcbuf, "/.telnetrc"); 253938689Sborman rcname = rcbuf; 254038689Sborman } 254138689Sborman 254238689Sborman if ((rcfile = fopen(rcname, "r")) == 0) { 254338689Sborman return; 254438689Sborman } 254538689Sborman 254638689Sborman for (;;) { 254738689Sborman if (fgets(line, sizeof(line), rcfile) == NULL) 254838689Sborman break; 254938689Sborman if (line[0] == 0) 255038689Sborman break; 255138689Sborman if (line[0] == '#') 255238689Sborman continue; 255338689Sborman if (gotmachine == 0) { 255438689Sborman if (isspace(line[0])) 255538689Sborman continue; 255638689Sborman if (strncasecmp(line, m1, l1) == 0) 255738689Sborman strncpy(line, &line[l1], sizeof(line) - l1); 255838689Sborman else if (strncasecmp(line, m2, l2) == 0) 255938689Sborman strncpy(line, &line[l2], sizeof(line) - l2); 256038689Sborman else 256138689Sborman continue; 256238689Sborman gotmachine = 1; 256338689Sborman } else { 256438689Sborman if (!isspace(line[0])) { 256538689Sborman gotmachine = 0; 256638689Sborman continue; 256738689Sborman } 256838689Sborman } 256938689Sborman makeargv(); 257038689Sborman if (margv[0] == 0) 257138689Sborman continue; 257238689Sborman c = getcmd(margv[0]); 257338689Sborman if (Ambiguous(c)) { 257438689Sborman printf("?Ambiguous command: %s\n", margv[0]); 257538689Sborman continue; 257638689Sborman } 257738689Sborman if (c == 0) { 257838689Sborman printf("?Invalid command: %s\n", margv[0]); 257938689Sborman continue; 258038689Sborman } 258138689Sborman /* 258238689Sborman * This should never happen... 258338689Sborman */ 258438689Sborman if (c->needconnect && !connected) { 258538689Sborman printf("?Need to be connected first for %s.\n", margv[0]); 258638689Sborman continue; 258738689Sborman } 258838689Sborman (*c->handler)(margc, margv); 258938689Sborman } 259038689Sborman fclose(rcfile); 259138689Sborman } 259238689Sborman 2593*46808Sdab #if defined(IP_OPTIONS) && defined(IPPROTO_IP) 259438689Sborman 259538689Sborman /* 259638689Sborman * Source route is handed in as 259738689Sborman * [!]@hop1@hop2...[@|:]dst 259838689Sborman * If the leading ! is present, it is a 259938689Sborman * strict source route, otherwise it is 260038689Sborman * assmed to be a loose source route. 260138689Sborman * 260238689Sborman * We fill in the source route option as 260338689Sborman * hop1,hop2,hop3...dest 260438689Sborman * and return a pointer to hop1, which will 260538689Sborman * be the address to connect() to. 260638689Sborman * 260738689Sborman * Arguments: 260838689Sborman * arg: pointer to route list to decipher 260938689Sborman * 261038689Sborman * cpp: If *cpp is not equal to NULL, this is a 261138689Sborman * pointer to a pointer to a character array 261238689Sborman * that should be filled in with the option. 261338689Sborman * 261438689Sborman * lenp: pointer to an integer that contains the 261538689Sborman * length of *cpp if *cpp != NULL. 261638689Sborman * 261738689Sborman * Return values: 261838689Sborman * 261938689Sborman * Returns the address of the host to connect to. If the 262038689Sborman * return value is -1, there was a syntax error in the 262138689Sborman * option, either unknown characters, or too many hosts. 262238689Sborman * If the return value is 0, one of the hostnames in the 262338689Sborman * path is unknown, and *cpp is set to point to the bad 262438689Sborman * hostname. 262538689Sborman * 262638689Sborman * *cpp: If *cpp was equal to NULL, it will be filled 262738689Sborman * in with a pointer to our static area that has 262838689Sborman * the option filled in. This will be 32bit aligned. 262938689Sborman * 263038689Sborman * *lenp: This will be filled in with how long the option 263138689Sborman * pointed to by *cpp is. 263238689Sborman * 263338689Sborman */ 2634*46808Sdab unsigned long 263538689Sborman sourceroute(arg, cpp, lenp) 2636*46808Sdab char *arg; 2637*46808Sdab char **cpp; 2638*46808Sdab int *lenp; 263938689Sborman { 264038689Sborman static char lsr[44]; 2641*46808Sdab char *cp, *cp2, *lsrp, *lsrep; 264238689Sborman register int tmp; 264338689Sborman struct in_addr sin_addr; 264438689Sborman register struct hostent *host = 0; 264538689Sborman register char c; 264638689Sborman 264738689Sborman /* 264838689Sborman * Verify the arguments, and make sure we have 264938689Sborman * at least 7 bytes for the option. 265038689Sborman */ 265138689Sborman if (cpp == NULL || lenp == NULL) 265238689Sborman return((unsigned long)-1); 265338689Sborman if (*cpp != NULL && *lenp < 7) 265438689Sborman return((unsigned long)-1); 265538689Sborman /* 265638689Sborman * Decide whether we have a buffer passed to us, 265738689Sborman * or if we need to use our own static buffer. 265838689Sborman */ 265938689Sborman if (*cpp) { 266038689Sborman lsrp = *cpp; 266138689Sborman lsrep = lsrp + *lenp; 266238689Sborman } else { 266338689Sborman *cpp = lsrp = lsr; 266438689Sborman lsrep = lsrp + 44; 266538689Sborman } 266638689Sborman 266738689Sborman cp = arg; 266838689Sborman 266938689Sborman /* 267038689Sborman * Next, decide whether we have a loose source 267138689Sborman * route or a strict source route, and fill in 267238689Sborman * the begining of the option. 267338689Sborman */ 267438689Sborman if (*cp == '!') { 267538689Sborman cp++; 267638689Sborman *lsrp++ = IPOPT_SSRR; 267738689Sborman } else 267838689Sborman *lsrp++ = IPOPT_LSRR; 267938689Sborman 268038689Sborman if (*cp != '@') 268138689Sborman return((unsigned long)-1); 268238689Sborman 268338689Sborman lsrp++; /* skip over length, we'll fill it in later */ 268438689Sborman *lsrp++ = 4; 268538689Sborman 268638689Sborman cp++; 268738689Sborman 268838689Sborman sin_addr.s_addr = 0; 268938689Sborman 269038689Sborman for (c = 0;;) { 269138689Sborman if (c == ':') 269238689Sborman cp2 = 0; 269338689Sborman else for (cp2 = cp; c = *cp2; cp2++) { 269438689Sborman if (c == ',') { 269538689Sborman *cp2++ = '\0'; 269638689Sborman if (*cp2 == '@') 269738689Sborman cp2++; 269838689Sborman } else if (c == '@') { 269938689Sborman *cp2++ = '\0'; 270038689Sborman } else if (c == ':') { 270138689Sborman *cp2++ = '\0'; 270238689Sborman } else 270338689Sborman continue; 270438689Sborman break; 270538689Sborman } 270638689Sborman if (!c) 270738689Sborman cp2 = 0; 270838689Sborman 270938689Sborman if ((tmp = inet_addr(cp)) != -1) { 271038689Sborman sin_addr.s_addr = tmp; 271138689Sborman } else if (host = gethostbyname(cp)) { 271238689Sborman #if defined(h_addr) 271338689Sborman memcpy((caddr_t)&sin_addr, 271438689Sborman host->h_addr_list[0], host->h_length); 271538689Sborman #else 271638689Sborman memcpy((caddr_t)&sin_addr, host->h_addr, host->h_length); 271738689Sborman #endif 271838689Sborman } else { 271938689Sborman *cpp = cp; 272038689Sborman return(0); 272138689Sborman } 272238689Sborman memcpy(lsrp, (char *)&sin_addr, 4); 272338689Sborman lsrp += 4; 272438689Sborman if (cp2) 272538689Sborman cp = cp2; 272638689Sborman else 272738689Sborman break; 272838689Sborman /* 272938689Sborman * Check to make sure there is space for next address 273038689Sborman */ 273138689Sborman if (lsrp + 4 > lsrep) 273238689Sborman return((unsigned long)-1); 273338689Sborman } 273438689Sborman if ((*(*cpp+IPOPT_OLEN) = lsrp - *cpp) <= 7) { 273538689Sborman *cpp = 0; 273638689Sborman *lenp = 0; 273738689Sborman return((unsigned long)-1); 273838689Sborman } 273938689Sborman *lsrp++ = IPOPT_NOP; /* 32 bit word align it */ 274038689Sborman *lenp = lsrp - *cpp; 274138689Sborman return(sin_addr.s_addr); 274238689Sborman } 274338689Sborman #endif 2744