📄 commands.c
字号:
/* * Copyright (c) 1988, 1990, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)commands.c 8.4 (Berkeley) 5/30/95";#endif /* not lint */#ifdef HAVE_CONFIG_H#include <config.h>#endif#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#ifdef HAVE_SYS_PARAM_H# include <sys/param.h>#endif#ifdef HAVE_SYS_TYPES_H# include <sys/types.h>#endif#include <sys/file.h>#include <sys/socket.h>#include <netinet/in.h>#ifdef HAVE_FCNTL_H# include <fcntl.h>#endif /* CRAY */#include <signal.h>#include <netdb.h>#include <ctype.h>#include <pwd.h>#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__#include <stdarg.h>#else#include <varargs.h>#endif#include <errno.h>#if defined(STDC_HEADERS) || defined(HAVE_STDLIB_H)#include <stdlib.h>#endif#ifdef HAVE_MALLOC_H#include <malloc.h>#endif#include <arpa/telnet.h>#include "general.h"#include "ring.h"#include "externs.h"#include "defines.h"#include "types.h"#if !defined(CRAY) && !defined(sysV88)#ifdef HAVE_NETINET_IN_SYSTM_H#include <netinet/in_systm.h>#endif# if (defined(vax) || defined(tahoe) || defined(hp300)) && !defined(ultrix)# include <machine/endian.h># endif /* vax */#endif /* !defined(CRAY) && !defined(sysV88) */#ifdef HAVE_NETINET_IP_H#include <netinet/ip.h>#endif#if defined(IPPROTO_IP) && defined(IP_TOS)int tos = -1;#endif /* defined(IPPROTO_IP) && defined(IP_TOS) */char *hostname;static char *_hostname = 0;extern char *getenv __P((const char *));extern int isprefix __P((register char *s1, register char *s2));extern char **genget __P((char *, char **, int ));extern int Ambiguous __P(());typedef int (*intrtn_t) __P((int, char *[]));static int call __P((intrtn_t, ...));typedef struct { const char *name; /* command name */ const char *help; /* help string (NULL for no help) */ int (*handler) ();/* routine which executes command */ int needconnect; /* Do we need to be connected to execute? */} Command;static char line[256];static char saveline[256];static int margc;static char *margv[20];static voidmakeargv(void){ register char *cp, *cp2, c; register char **argp = margv; margc = 0; cp = line; if (*cp == '!') { /* Special case shell escape */ strcpy(saveline, line); /* save for shell command */ *argp++ = "!"; /* No room in string to get this */ margc++; cp++; } while (c = *cp) { register int inquote = 0; while (isspace(c)) c = *++cp; if (c == '\0') break; *argp++ = cp; margc += 1; for (cp2 = cp; c != '\0'; c = *++cp) { if (inquote) { if (c == inquote) { inquote = 0; continue; } } else { if (c == '\\') { if ((c = *++cp) == '\0') break; } else if (c == '"') { inquote = '"'; continue; } else if (c == '\'') { inquote = '\''; continue; } else if (isspace(c)) break; } *cp2++ = c; } *cp2 = '\0'; if (c == '\0') break; cp++; } *argp++ = 0;}/* * Make a character string into a number. * * Todo: 1. Could take random integers (12, 0x12, 012, 0b1). */static intspecial(register char *s){ register char c; char b; switch (*s) { case '^': b = *++s; if (b == '?') { c = b | 0x40; /* DEL */ } else { c = b & 0x1f; } break; default: c = *s; break; } return c;}/* * Construct a control character sequence * for a special character. */static const char *control(register cc_t c){ static char buf[5]; /* * The only way I could get the Sun 3.5 compiler * to shut up about * if ((unsigned int)c >= 0x80) * was to assign "c" to an unsigned int variable... * Arggg.... */ register unsigned int uic = (unsigned int)c; if (uic == 0x7f) return ("^?"); if (c == (cc_t)_POSIX_VDISABLE) { return "off"; } if (uic >= 0x80) { buf[0] = '\\'; buf[1] = ((c>>6)&07) + '0'; buf[2] = ((c>>3)&07) + '0'; buf[3] = (c&07) + '0'; buf[4] = 0; } else if (uic >= 0x20) { buf[0] = c; buf[1] = 0; } else { buf[0] = '^'; buf[1] = '@'+c; buf[2] = 0; } return (buf);}/* * The following are data structures and routines for * the "send" command. * */struct sendlist { const char *name; /* How user refers to it (case independent) */ const char *help; /* Help information (0 ==> no help) */ int needconnect; /* Need to be connected */ int narg; /* Number of arguments */ int (*handler)(); /* Routine to perform (for special ops) */ int nbyte; /* Number of bytes to send this command */ int what; /* Character to be sent (<0 ==> special) */};static int send_esc P((void)), send_help P((void)), send_docmd P((char *)), send_dontcmd P((char *)), send_willcmd P((char *)), send_wontcmd P((char *));static struct sendlist Sendlist[] = { { "ao", "Send Telnet Abort output", 1, 0, 0, 2, AO }, { "ayt", "Send Telnet 'Are You There'", 1, 0, 0, 2, AYT }, { "brk", "Send Telnet Break", 1, 0, 0, 2, BREAK }, { "break", 0, 1, 0, 0, 2, BREAK }, { "ec", "Send Telnet Erase Character", 1, 0, 0, 2, EC }, { "el", "Send Telnet Erase Line", 1, 0, 0, 2, EL }, { "escape", "Send current escape character", 1, 0, send_esc, 1, 0 }, { "ga", "Send Telnet 'Go Ahead' sequence", 1, 0, 0, 2, GA }, { "ip", "Send Telnet Interrupt Process", 1, 0, 0, 2, IP }, { "intp", 0, 1, 0, 0, 2, IP }, { "interrupt", 0, 1, 0, 0, 2, IP }, { "intr", 0, 1, 0, 0, 2, IP }, { "nop", "Send Telnet 'No operation'", 1, 0, 0, 2, NOP }, { "eor", "Send Telnet 'End of Record'", 1, 0, 0, 2, EOR }, { "abort", "Send Telnet 'Abort Process'", 1, 0, 0, 2, ABORT }, { "susp", "Send Telnet 'Suspend Process'", 1, 0, 0, 2, SUSP }, { "eof", "Send Telnet End of File Character", 1, 0, 0, 2, xEOF }, { "synch", "Perform Telnet 'Synch operation'", 1, 0, dosynch, 2, 0 }, { "getstatus", "Send request for STATUS", 1, 0, get_status, 6, 0 }, { "?", "Display send options", 0, 0, send_help, 0, 0 }, { "help", 0, 0, 0, send_help, 0, 0 }, { "do", 0, 0, 1, send_docmd, 3, 0 }, { "dont", 0, 0, 1, send_dontcmd, 3, 0 }, { "will", 0, 0, 1, send_willcmd, 3, 0 }, { "wont", 0, 0, 1, send_wontcmd, 3, 0 }, { NULL, 0, 0, 0, NULL, 0, 0 }};#define GETSEND(name) ((struct sendlist *) genget(name, (char **) Sendlist, \ sizeof(struct sendlist)))static intsendcmd(int argc, char **argv){ int count; /* how many bytes we are going to need to send */ int i; int question = 0; /* was at least one argument a question */ struct sendlist *s; /* pointer to current command */ int success = 0; int needconnect = 0; if (argc < 2) { printf("need at least one argument for 'send' command\n"); printf("'send ?' for help\n"); return 0; } /* * First, validate all the send arguments. * In addition, we see how much space we are going to need, and * whether or not we will be doing a "SYNCH" operation (which * flushes the network queue). */ count = 0; for (i = 1; i < argc; i++) { s = GETSEND(argv[i]); if (s == 0) { printf("Unknown send argument '%s'\n'send ?' for help.\n", argv[i]); return 0; } else if (Ambiguous(s)) { printf("Ambiguous send argument '%s'\n'send ?' for help.\n", argv[i]); return 0; } if (i + s->narg >= argc) { fprintf(stderr, "Need %d argument%s to 'send %s' command. 'send %s ?' for help.\n", s->narg, s->narg == 1 ? "" : "s", s->name, s->name); return 0; } count += s->nbyte; if (s->handler == send_help) { send_help(); return 0; } i += s->narg; needconnect += s->needconnect; } if (!connected && needconnect) { printf("?Need to be connected first.\n"); printf("'send ?' for help\n"); return 0; } /* Now, do we have enough room? */ if (NETROOM() < count) { printf("There is not enough room in the buffer TO the network\n"); printf("to process your request. Nothing will be done.\n"); printf("('send synch' will throw away most data in the network\n"); printf("buffer, if this might help.)\n"); return 0; } /* OK, they are all OK, now go through again and actually send */ count = 0; for (i = 1; i < argc; i++) { if ((s = GETSEND(argv[i])) == 0) { fprintf(stderr, "Telnet 'send' error - argument disappeared!\n"); (void) quit(); /*NOTREACHED*/ } if (s->handler) { count++; success += (*s->handler)((s->narg > 0) ? argv[i+1] : 0, (s->narg > 1) ? argv[i+2] : 0); i += s->narg; } else { NET2ADD(IAC, s->what); printoption("SENT", IAC, s->what); } } return (count == success);}static intsend_esc(){ NETADD(escape); return 1;}static intsend_docmd(char *name){ return(send_tncmd(send_do, "do", name));}static intsend_dontcmd(char *name){ return(send_tncmd(send_dont, "dont", name));}static intsend_willcmd(char *name){ return(send_tncmd(send_will, "will", name));}static intsend_wontcmd(char *name){ return(send_tncmd(send_wont, "wont", name));}intsend_tncmd(void (*func)(), char *cmd, char *name){ char **cpp; extern char *telopts[]; register int val = 0; if (isprefix(name, "help") || isprefix(name, "?")) { register int col, len; printf("Usage: send %s <value|option>\n", cmd); printf("\"value\" must be from 0 to 255\n"); printf("Valid options are:\n\t"); col = 8; for (cpp = telopts; *cpp; cpp++) { len = strlen(*cpp) + 3; if (col + len > 65) { printf("\n\t"); col = 8; } printf(" \"%s\"", *cpp); col += len; } printf("\n"); return 0; } cpp = (char **)genget(name, telopts, sizeof(char *)); if (Ambiguous(cpp)) { fprintf(stderr,"'%s': ambiguous argument ('send %s ?' for help).\n", name, cmd); return 0; } if (cpp) { val = cpp - telopts; } else { register char *cp = name; while (*cp >= '0' && *cp <= '9') { val *= 10; val += *cp - '0'; cp++; } if (*cp != 0) { fprintf(stderr, "'%s': unknown argument ('send %s ?' for help).\n", name, cmd); return 0; } else if (val < 0 || val > 255) { fprintf(stderr, "'%s': bad value ('send %s ?' for help).\n", name, cmd); return 0; } } if (!connected) { printf("?Need to be connected first.\n"); return 0; } (*func)(val, 1); return 1;}static intsend_help(){ struct sendlist *s; /* pointer to current command */ for (s = Sendlist; s->name; s++) { if (s->help) printf("%-15s %s\n", s->name, s->help); } return(0);}/* * The following are the routines and data structures referred * to by the arguments to the "toggle" command. */static intlclchars(){ donelclchars = 1; return 1;}static inttogdebug(){#ifndef NOT43 if (net > 0 && (SetSockOpt(net, SOL_SOCKET, SO_DEBUG, debug)) < 0) { perror("setsockopt (SO_DEBUG)"); }#else /* NOT43 */ if (debug) { if (net > 0 && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 0, 0) < 0) perror("setsockopt (SO_DEBUG)"); } else printf("Cannot turn off socket debugging\n");#endif /* NOT43 */ return 1;}static inttogcrlf(){ if (crlf) { printf("Will send carriage returns as telnet <CR><LF>.\n"); } else { printf("Will send carriage returns as telnet <CR><NUL>.\n"); } return 1;}int binmode;static inttogbinary(int val){ donebinarytoggle = 1; if (val >= 0) { binmode = val; } else { if (my_want_state_is_will(TELOPT_BINARY) && my_want_state_is_do(TELOPT_BINARY)) { binmode = 1; } else if (my_want_state_is_wont(TELOPT_BINARY) && my_want_state_is_dont(TELOPT_BINARY)) { binmode = 0; } val = binmode ? 0 : 1; } if (val == 1) { if (my_want_state_is_will(TELOPT_BINARY) && my_want_state_is_do(TELOPT_BINARY)) { printf("Already operating in binary mode with remote host.\n"); } else { printf("Negotiating binary mode with remote host.\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -