📄 tset.c
字号:
/**************************************************************************** * Copyright (c) 1998-2004,2005 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * * "Software"), to deal in the Software without restriction, including * * without limitation the rights to use, copy, modify, merge, publish, * * distribute, distribute with modifications, sublicense, and/or sell * * copies of the Software, and to permit persons to whom the Software is * * furnished to do so, subject to the following conditions: * * * * The above copyright notice and this permission notice shall be included * * in all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * * * Except as contained in this notice, the name(s) of the above copyright * * holders shall not be used in advertising or otherwise to promote the * * sale, use or other dealings in this Software without prior written * * authorization. * ****************************************************************************//**************************************************************************** * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * * and: Eric S. Raymond <esr@snark.thyrsus.com> * * and: Thomas E. Dickey 1996-on * ****************************************************************************//* * tset.c - terminal initialization utility * * This code was mostly swiped from 4.4BSD tset, with some obsolescent * cruft removed and substantial portions rewritten. A Regents of the * University of California copyright applies to some portions of the * code, and is reproduced below: *//*- * Copyright (c) 1980, 1991, 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 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. */#define __INTERNAL_CAPS_VISIBLE /* we need to see has_hardware_tabs */#include <progs.priv.h>#include <errno.h>#include <stdio.h>#include <termcap.h>#include <fcntl.h>#if HAVE_GETTTYNAM && HAVE_TTYENT_H#include <ttyent.h>#endif#ifdef NeXTchar *ttyname(int fd);#endif/* this is just to stifle a missing-prototype warning */#ifdef linux# include <sys/ioctl.h>#endif#if NEED_PTEM_H/* they neglected to define struct winsize in termios.h -- it's only in termio.h */#include <sys/stream.h>#include <sys/ptem.h>#endif#include <dump_entry.h>#include <transform.h>MODULE_ID("$Id: tset.c,v 1.60 2005/09/25 00:43:52 tom Exp $")extern char **environ;#undef CTRL#define CTRL(x) ((x) & 0x1f)const char *_nc_progname = "tset";static TTY mode, oldmode, original;static bool opt_c; /* set control-chars */static bool opt_w; /* set window-size */static bool can_restore = FALSE;static bool isreset = FALSE; /* invoked as reset */static int terasechar = -1; /* new erase character */static int intrchar = -1; /* new interrupt character */static int tkillchar = -1; /* new kill character */static int tlines, tcolumns; /* window size */#define LOWERCASE(c) ((isalpha(UChar(c)) && isupper(UChar(c))) ? tolower(UChar(c)) : (c))static intCaselessCmp(const char *a, const char *b){ /* strcasecmp isn't portable */ while (*a && *b) { int cmp = LOWERCASE(*a) - LOWERCASE(*b); if (cmp != 0) break; a++, b++; } return LOWERCASE(*a) - LOWERCASE(*b);}static voidexit_error(void){ if (can_restore) SET_TTY(STDERR_FILENO, &original); (void) fprintf(stderr, "\n"); fflush(stderr); ExitProgram(EXIT_FAILURE); /* NOTREACHED */}static voiderr(const char *fmt,...){ va_list ap; va_start(ap, fmt); (void) fprintf(stderr, "%s: ", _nc_progname); (void) vfprintf(stderr, fmt, ap); va_end(ap); exit_error(); /* NOTREACHED */}static voidfailed(const char *msg){ char temp[BUFSIZ]; unsigned len = strlen(_nc_progname) + 2; if (len < sizeof(temp) - 12) { strcpy(temp, _nc_progname); strcat(temp, ": "); } else { strcpy(temp, "tset: "); } perror(strncat(temp, msg, sizeof(temp) - strlen(temp) - 2)); exit_error(); /* NOTREACHED */}static voidcat(char *file){ FILE *fp; size_t nr; char buf[BUFSIZ]; if ((fp = fopen(file, "r")) == 0) failed(file); while ((nr = fread(buf, sizeof(char), sizeof(buf), fp)) != 0) if (fwrite(buf, sizeof(char), nr, stderr) != nr) failed("write to stderr"); fclose(fp);}static intoutc(int c){ return putc(c, stderr);}/* Prompt the user for a terminal type. */static const char *askuser(const char *dflt){ static char answer[256]; char *p; /* We can get recalled; if so, don't continue uselessly. */ clearerr(stdin); if (feof(stdin) || ferror(stdin)) { (void) fprintf(stderr, "\n"); exit_error(); /* NOTREACHED */ } for (;;) { if (dflt) (void) fprintf(stderr, "Terminal type? [%s] ", dflt); else (void) fprintf(stderr, "Terminal type? "); (void) fflush(stderr); if (fgets(answer, sizeof(answer), stdin) == 0) { if (dflt == 0) { exit_error(); /* NOTREACHED */ } return (dflt); } if ((p = strchr(answer, '\n')) != 0) *p = '\0'; if (answer[0]) return (answer); if (dflt != 0) return (dflt); }}/************************************************************************** * * Mapping logic begins here * **************************************************************************//* Baud rate conditionals for mapping. */#define GT 0x01#define EQ 0x02#define LT 0x04#define NOT 0x08#define GE (GT | EQ)#define LE (LT | EQ)typedef struct map { struct map *next; /* Linked list of maps. */ const char *porttype; /* Port type, or "" for any. */ const char *type; /* Terminal type to select. */ int conditional; /* Baud rate conditionals bitmask. */ int speed; /* Baud rate to compare against. */} MAP;static MAP *cur, *maplist;typedef struct speeds { const char *string; int speed;} SPEEDS;static const SPEEDS speeds[] ={ {"0", B0}, {"50", B50}, {"75", B75}, {"110", B110}, {"134", B134}, {"134.5", B134}, {"150", B150}, {"200", B200}, {"300", B300}, {"600", B600}, {"1200", B1200}, {"1800", B1800}, {"2400", B2400}, {"4800", B4800}, {"9600", B9600}, /* sgttyb may define up to this point */#ifdef B19200 {"19200", B19200},#endif#ifdef B38400 {"38400", B38400},#endif#ifdef B19200 {"19200", B19200},#endif#ifdef B38400 {"38400", B38400},#endif#ifdef B19200 {"19200", B19200},#else#ifdef EXTA {"19200", EXTA},#endif#endif#ifdef B38400 {"38400", B38400},#else#ifdef EXTB {"38400", EXTB},#endif#endif#ifdef B57600 {"57600", B57600},#endif#ifdef B115200 {"115200", B115200},#endif#ifdef B230400 {"230400", B230400},#endif#ifdef B460800 {"460800", B460800},#endif {(char *) 0, 0}};static inttbaudrate(char *rate){ const SPEEDS *sp; int found = FALSE; /* The baudrate number can be preceded by a 'B', which is ignored. */ if (*rate == 'B') ++rate; for (sp = speeds; sp->string; ++sp) { if (!CaselessCmp(rate, sp->string)) { found = TRUE; break; } } if (!found) err("unknown baud rate %s", rate); return (sp->speed);}/* * Syntax for -m: * [port-type][test baudrate]:terminal-type * The baud rate tests are: >, <, @, =, ! */static voidadd_mapping(const char *port, char *arg){ MAP *mapp; char *copy, *p; const char *termp; char *base = 0; copy = strdup(arg); mapp = (MAP *) malloc(sizeof(MAP)); if (copy == 0 || mapp == 0) failed("malloc"); mapp->next = 0; if (maplist == 0) cur = maplist = mapp; else { cur->next = mapp; cur = mapp; } mapp->porttype = arg; mapp->conditional = 0; arg = strpbrk(arg, "><@=!:"); if (arg == 0) { /* [?]term */ mapp->type = mapp->porttype; mapp->porttype = 0; goto done; } if (arg == mapp->porttype) /* [><@=! baud]:term */ termp = mapp->porttype = 0; else termp = base = arg; for (;; ++arg) { /* Optional conditionals. */ switch (*arg) { case '<': if (mapp->conditional & GT) goto badmopt; mapp->conditional |= LT; break; case '>': if (mapp->conditional & LT) goto badmopt; mapp->conditional |= GT; break; case '@': case '=': /* Not documented. */ mapp->conditional |= EQ; break; case '!': mapp->conditional |= NOT; break; default: goto next; } } next: if (*arg == ':') { if (mapp->conditional) goto badmopt; ++arg; } else { /* Optional baudrate. */ arg = strchr(p = arg, ':'); if (arg == 0) goto badmopt; *arg++ = '\0'; mapp->speed = tbaudrate(p); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -