]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - progs/tset.c
ncurses 4.2
[ncurses.git] / progs / tset.c
index e6a075d9b6f83bba47f1480015685059f915618a..1df3fd64986923cdb79957030eefbd81dd91b315 100644 (file)
@@ -1,23 +1,35 @@
-
-/***************************************************************************
-*                            COPYRIGHT NOTICE                              *
-****************************************************************************
-*                ncurses is copyright (C) 1992-1995                        *
-*                          Zeyd M. Ben-Halim                               *
-*                          zmbenhal@netcom.com                             *
-*                          Eric S. Raymond                                 *
-*                          esr@snark.thyrsus.com                           *
-*                                                                          *
-*        Permission is hereby granted to reproduce and distribute ncurses  *
-*        by any means and for any fee, whether alone or as part of a       *
-*        larger distribution, in source or in binary form, PROVIDED        *
-*        this notice is included with any such distribution, and is not    *
-*        removed from any of its header files. Mention of ncurses in any   *
-*        applications linked with it is highly appreciated.                *
-*                                                                          *
-*        ncurses comes AS IS with no warranty, implied or expressed.       *
-*                                                                          *
-***************************************************************************/
+/****************************************************************************
+ * Copyright (c) 1998 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>                         *
+ ****************************************************************************/
 
 
 /*
@@ -66,7 +78,6 @@
 
 #include <errno.h>
 #include <stdio.h>
-#include <ctype.h>
 #include <termcap.h>
 #include <fcntl.h>
 
@@ -82,7 +93,7 @@ char *ttyname(int fd);
 # include <sys/ioctl.h>
 #endif
 
-#if SYSTEM_LOOKS_LIKE_SCO
+#if NEED_PTEM_H
 /* they neglected to define struct winsize in termios.h -- it's only
    in termio.h */
 #include       <sys/stream.h>
@@ -92,7 +103,7 @@ char *ttyname(int fd);
 #include <curses.h>    /* for bool typedef */
 #include <dump_entry.h>
 
-MODULE_ID("$Id: tset.c,v 0.23 1997/05/10 17:44:47 tom Exp $")
+MODULE_ID("$Id: tset.c,v 0.31 1998/02/11 12:14:02 tom Exp $")
 
 extern char **environ;
 
@@ -103,10 +114,10 @@ const char *_nc_progname = "tset";
 
 static TTY mode, oldmode;
 
-static int     terasechar;             /* new erase character */
-static int     intrchar;               /* new interrupt character */
+static int     terasechar = -1;        /* new erase character */
+static int     intrchar = -1;          /* new interrupt character */
 static int     isreset;                /* invoked as reset */
-static int     tkillchar;              /* new kill character */
+static int     tkillchar = -1;         /* new kill character */
 static int     tlines, tcolumns;               /* window size */
 
 #define LOWERCASE(c) ((isalpha(c) && isupper(c)) ? tolower(c) : (c))
@@ -161,7 +172,7 @@ static void
 cat(char *file)
 {
        register int fd, nr, nw;
-       char buf[1024];
+       char buf[BUFSIZ];
 
        if ((fd = open(file, O_RDONLY, 0)) < 0)
                failed(file);
@@ -265,6 +276,32 @@ static const SPEEDS speeds[] = {
        { "38400",      B38400 },
        { "19200",      B19200 },
        { "38400",      B38400 },
+#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 }
 };
 
@@ -464,8 +501,10 @@ get_termcap_entry(char *userarg)
        const char *ttype;
 #if HAVE_GETTTYNAM
        struct ttyent *t;
-       char *ttypath;
+#else
+       FILE *fp;
 #endif
+       char *ttypath;
 
        if (userarg) {
                ttype = userarg;
@@ -476,23 +515,46 @@ get_termcap_entry(char *userarg)
        if ((ttype = getenv("TERM")) != 0)
                goto map;
 
-#if HAVE_GETTTYNAM
-       /*
-        * We have the 4.3BSD library call getttynam(3); that means
-        * there's an /etc/ttys to look up device-to-type mappings in.
-        * Try ttyname(3); check for dialup or other mapping.
-        */
        if ((ttypath = ttyname(STDERR_FILENO)) != 0) {
                if ((p = strrchr(ttypath, '/')) != 0)
                        ++p;
                else
                        p = ttypath;
+#if HAVE_GETTTYNAM
+               /*
+                * We have the 4.3BSD library call getttynam(3); that means
+                * there's an /etc/ttys to look up device-to-type mappings in.
+                * Try ttyname(3); check for dialup or other mapping.
+                */
                if ((t = getttynam(p))) {
                        ttype = t->ty_type;
                        goto map;
                }
+#else
+               if ((fp = fopen("/etc/ttytype", "r")) != 0
+                || (fp = fopen("/etc/ttys", "r")) != 0) {
+                       char buffer[BUFSIZ];
+                       char *s, *t, *d;
+
+                       while (fgets(buffer, sizeof(buffer)-1, fp) != 0) {
+                               for (s = buffer, t = d = 0; *s; s++) {
+                                       if (isspace(*s))
+                                               *s = '\0';
+                                       else if (t == 0)
+                                               t = s;
+                                       else if (d == 0 && s != buffer && s[-1] == '\0')
+                                               d = s;
+                               }
+                               if (t != 0 && d != 0 && !strcmp(d,p)) {
+                                       ttype = strdup(t);
+                                       fclose(fp);
+                                       goto map;
+                               }
+                       }
+                       fclose(fp);
+               }
+#endif /* HAVE_GETTTYNAM */
        }
-#endif /* BSD */
 
        /* If still undefined, use "unknown". */
        ttype = "unknown";
@@ -562,6 +624,8 @@ found:      if ((p = getenv("TERMCAP")) != 0 && *p != '/') {
 #undef CERASE
 #undef CINTR
 #undef CKILL
+#undef CLNEXT
+#undef CRPRNT
 #undef CQUIT
 #undef CSTART
 #undef CSTOP
@@ -572,14 +636,8 @@ found:     if ((p = getenv("TERMCAP")) != 0 && *p != '/') {
 #define CERASE CTRL('H')
 #define CINTR  127             /* ^? */
 #define CKILL  CTRL('U')
-#if defined(CLNEXT)
-#undef CLNEXT
 #define CLNEXT  CTRL('v')
-#endif
-#if defined(CRPRNT)
-#undef CRPRNT
 #define CRPRNT  CTRL('r')
-#endif
 #define CQUIT  CTRL('\\')
 #define CSTART CTRL('Q')
 #define CSTOP  CTRL('S')
@@ -710,59 +768,43 @@ reset_mode(void)
 }
 
 /*
- * Determine the erase, interrupt, and kill characters from the termcap
- * entry and command line and update their values in 'mode'.
+ * Returns a "good" value for the erase character.  This is loosely based on
+ * the BSD4.4 logic.
  */
-static void
-set_control_chars(void)
+static int
+default_erase(void)
 {
-#ifdef __OBSOLETE__
-       /*
-        * 4.4BSD logic for setting erasechar, left here in case there is some
-        * necessary subtlety missed in the production code below that really
-        * needs to be added someday (in particular, I don't understand what
-        * the second if-statement involving the os flag is doing, and it makes
-        * my head hurt when I try and follow out all the combinations).
-        */
-       char *bp, *p, bs_char, buf[1024];
-
-       bp = buf;
-       p = tgetstr("kb", &bp);
-       if (p == 0 || p[1] != '\0')
-               p = tgetstr("bc", &bp);
-       if (p != 0 && p[1] == '\0')
-               bs_char = p[0];
-       else if (tgetflag("bs"))
-               bs_char = CTRL('h');
-       else
-               bs_char = 0;
+       int result;
 
-       if (terasechar==0 && !tgetflag("os") && mode.c_cc[VERASE] != CERASE) {
-               if (tgetflag("bs") || bs_char != 0)
-                       terasechar = -1;
-       }
-       if (terasechar < 0)
-               terasechar = (bs_char != 0) ? bs_char : CTRL('h');
-#else
-       /* the real erasechar logic used now */
-       char bs_char = 0;
-
-       if (key_backspace != (char *)0)
-               bs_char = key_backspace[0];
+       if (over_strike
+        && key_backspace != 0
+        && strlen(key_backspace) == 1)
+               result = key_backspace[0];
+       else
+               result = CERASE;
 
-       if (terasechar <= 0)
-           terasechar = (bs_char != 0) ? bs_char : CTRL('h');
-#endif /* __OBSOLETE__ */
+       return result;
+}
 
+/*
+ * Update the values of the erase, interrupt, and kill characters in 'mode'.
+ *
+ * SVr4 tset (e.g., Solaris 2.5) only modifies the intr, quit or erase
+ * characters if they're unset, or if we specify them as options.  This differs
+ * from BSD 4.4 tset, which always sets erase.
+ */
+static void
+set_control_chars(void)
+{
 #ifdef TERMIOS
-       if (mode.c_cc[VERASE] == 0 || terasechar != 0)
-               mode.c_cc[VERASE] = terasechar ? terasechar : CERASE;
+       if (mode.c_cc[VERASE] == 0 || terasechar >= 0)
+               mode.c_cc[VERASE] = terasechar >= 0 ? terasechar : default_erase();
 
-       if (mode.c_cc[VINTR] == 0 || intrchar != 0)
-                mode.c_cc[VINTR] = intrchar ? intrchar : CINTR;
+       if (mode.c_cc[VINTR] == 0 || intrchar >= 0)
+                mode.c_cc[VINTR] = intrchar >= 0 ? intrchar : CINTR;
 
-       if (mode.c_cc[VKILL] == 0 || tkillchar != 0)
-               mode.c_cc[VKILL] = tkillchar ? tkillchar : CKILL;
+       if (mode.c_cc[VKILL] == 0 || tkillchar >= 0)
+               mode.c_cc[VKILL] = tkillchar >= 0 ? tkillchar : CKILL;
 #endif
 }
 
@@ -876,7 +918,7 @@ set_init(void)
        if (settle) {
                (void)putc('\r', stderr);
                (void)fflush(stderr);
-               (void)sleep(1);                 /* Settle the terminal. */
+               (void)napms(1000);      /* Settle the terminal. */
        }
 }
 
@@ -926,28 +968,32 @@ static void
 report(const char *name, int which, u_int def)
 {
 #ifdef TERMIOS
-       u_int old, new;
+       u_int older, newer;
        char *p;
 
-       new = mode.c_cc[which];
-       old = oldmode.c_cc[which];
+       newer = mode.c_cc[which];
+       older = oldmode.c_cc[which];
 
-       if (old == new && old == def)
+       if (older == newer && older == def)
                return;
 
-       (void)fprintf(stderr, "%s %s ", name, old == new ? "is" : "set to");
+       (void)fprintf(stderr, "%s %s ", name, older == newer ? "is" : "set to");
 
-       if ((p = key_backspace) != 0
-        && new == (u_int)p[0]
+       /*
+        * Check 'delete' before 'backspace', since the key_backspace value
+        * is ambiguous.
+        */
+       if (newer == 0177)
+               (void)fprintf(stderr, "delete.\n");
+       else if ((p = key_backspace) != 0
+        && newer == (u_int)p[0]
         && p[1] == '\0')
                (void)fprintf(stderr, "backspace.\n");
-       else if (new == 0177)
-               (void)fprintf(stderr, "delete.\n");
-       else if (new < 040) {
-               new ^= 0100;
-               (void)fprintf(stderr, "control-%c (^%c).\n", new, new);
+       else if (newer < 040) {
+               newer ^= 0100;
+               (void)fprintf(stderr, "control-%c (^%c).\n", newer, newer);
        } else
-               (void)fprintf(stderr, "%c.\n", new);
+               (void)fprintf(stderr, "%c.\n", newer);
 #endif
 }
 
@@ -994,10 +1040,17 @@ usage(const char* pname)
        exit(EXIT_FAILURE);
 }
 
+static char arg_to_char(void)
+{
+       return (optarg[0] == '^' && optarg[1] != '\0')
+               ? ((optarg[1] == '?') ? '\177' : CTRL(optarg[1]))
+               : optarg[0];
+}
+
 int
 main(int argc, char **argv)
 {
-#ifdef TIOCGWINSZ
+#if defined(TIOCGWINSZ) && defined(TIOCSWINSZ)
        struct winsize win;
 #endif
        int ch, noinit, noset, quiet, Sflag, sflag, showterm;
@@ -1041,22 +1094,16 @@ main(int argc, char **argv)
                        add_mapping("dialup", optarg);
                        break;
                case 'e':               /* erase character */
-                       terasechar = optarg[0] == '^' && optarg[1] != '\0' ?
-                           optarg[1] == '?' ? '\177' : CTRL(optarg[1]) :
-                           optarg[0];
+                       terasechar = arg_to_char();
                        break;
                case 'I':               /* no initialization strings */
                        noinit = 1;
                        break;
                case 'i':               /* interrupt character */
-                       intrchar = optarg[0] == '^' && optarg[1] != '\0' ?
-                           optarg[1] == '?' ? '\177' : CTRL(optarg[1]) :
-                           optarg[0];
+                       intrchar = arg_to_char();
                        break;
                case 'k':               /* kill character */
-                       tkillchar = optarg[0] == '^' && optarg[1] != '\0' ?
-                           optarg[1] == '?' ? '\177' : CTRL(optarg[1]) :
-                           optarg[0];
+                       tkillchar = arg_to_char();
                        break;
                case 'm':               /* map identifier to type */
                        add_mapping(0, optarg);
@@ -1095,7 +1142,7 @@ main(int argc, char **argv)
                tcolumns = columns;
                tlines = lines;
 
-#ifdef TIOCGWINSZ
+#if defined(TIOCGWINSZ) && defined(TIOCSWINSZ)
                /* Set window size */
                (void)ioctl(STDERR_FILENO, TIOCGWINSZ, &win);
                if (win.ws_row == 0 && win.ws_col == 0 &&