=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tset/tset.c,v retrieving revision 1.15 retrieving revision 1.16 diff -c -r1.15 -r1.16 *** src/usr.bin/tset/tset.c 1999/12/04 22:25:02 1.15 --- src/usr.bin/tset/tset.c 2000/03/10 01:35:06 1.16 *************** *** 1,5 **** /**************************************************************************** ! * 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 * --- 1,5 ---- /**************************************************************************** ! * Copyright (c) 1998,1999,2000 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 * *************** *** 31,37 **** * and: Eric S. Raymond * ****************************************************************************/ - /* * tset.c - terminal initialization utility * --- 31,36 ---- *************** *** 100,109 **** #include #endif ! #include /* for bool typedef */ #include ! MODULE_ID("$From: tset.c,v 0.37 1999/03/14 12:30:02 tom Exp $") extern char **environ; --- 99,108 ---- #include #endif ! #include /* for bool typedef */ #include ! MODULE_ID("$From: tset.c,v 0.40 2000/03/05 04:37:53 tom Exp $") extern char **environ; *************** *** 114,223 **** static TTY mode, oldmode; ! static int terasechar = -1; /* new erase character */ ! static int intrchar = -1; /* new interrupt character */ ! static int isreset; /* invoked as reset */ ! static int tkillchar = -1; /* new kill character */ ! static int tlines, tcolumns; /* window size */ #define LOWERCASE(c) ((isalpha(c) && isupper(c)) ? tolower(c) : (c)) static int ! CaselessCmp(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); } - #if !HAVE_STRDUP - #define strdup _nc_strdup - extern char *_nc_strdup(const char *); - #endif /* not HAVE_STRDUP */ - static void ! err(const char *fmt, ...) { ! va_list ap; ! va_start(ap, fmt); ! (void)fprintf(stderr, "tset: "); ! (void)vfprintf(stderr, fmt, ap); ! va_end(ap); ! (void)fprintf(stderr, "\n"); ! exit(EXIT_FAILURE); ! /* NOTREACHED */ } static void failed(const char *msg) { ! (void)fputs("tset: ", stderr); ! perror(msg); ! exit(EXIT_FAILURE); ! /* NOTREACHED */ } static void cat(char *file) { ! register int fd, nr, nw; ! char buf[BUFSIZ]; ! if ((fd = open(file, O_RDONLY, 0)) < 0) ! failed(file); ! while ((nr = read(fd, buf, sizeof(buf))) > 0) ! if ((nw = write(STDERR_FILENO, buf, (size_t)nr)) == -1) ! failed("write to stderr"); ! if (nr != 0) ! failed(file); ! (void)close(fd); } static int outc(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. */ ! if (feof(stdin) || ferror(stdin)) { ! (void)fprintf(stderr, "\n"); exit(EXIT_FAILURE); } - 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) { ! (void)fprintf(stderr, "\n"); ! exit(EXIT_FAILURE); ! } ! return (dflt); ! } ! ! if ((p = strchr(answer, '\n')) != 0) ! *p = '\0'; ! if (answer[0]) ! return (answer); ! if (dflt != 0) ! return (dflt); ! } } /************************************************************************** --- 113,217 ---- static TTY mode, oldmode; ! static int terasechar = -1; /* new erase character */ ! static int intrchar = -1; /* new interrupt character */ ! static int isreset; /* invoked as reset */ ! static int tkillchar = -1; /* new kill character */ ! static int tlines, tcolumns; /* window size */ #define LOWERCASE(c) ((isalpha(c) && isupper(c)) ? tolower(c) : (c)) static int ! CaselessCmp(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 void ! err(const char *fmt,...) { ! va_list ap; ! va_start(ap, fmt); ! (void) fprintf(stderr, "tset: "); ! (void) vfprintf(stderr, fmt, ap); ! va_end(ap); ! (void) fprintf(stderr, "\n"); ! exit(EXIT_FAILURE); ! /* NOTREACHED */ } static void failed(const char *msg) { ! (void)fputs("tset: ", stderr); ! perror(msg); ! exit(EXIT_FAILURE); ! /* NOTREACHED */ } static void cat(char *file) { ! register int fd, nr, nw; ! char buf[BUFSIZ]; ! if ((fd = open(file, O_RDONLY, 0)) < 0) ! failed(file); ! while ((nr = read(fd, buf, sizeof(buf))) > 0) ! if ((nw = write(STDERR_FILENO, buf, (size_t) nr)) == -1) ! failed("write to stderr"); ! if (nr != 0) ! failed(file); ! (void) close(fd); } static int outc(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. */ ! if (feof(stdin) || ferror(stdin)) { ! (void) fprintf(stderr, "\n"); ! exit(EXIT_FAILURE); ! } ! 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) { ! (void) fprintf(stderr, "\n"); exit(EXIT_FAILURE); + } + return (dflt); } ! if ((p = strchr(answer, '\n')) != 0) ! *p = '\0'; ! if (answer[0]) ! return (answer); ! if (dflt != 0) ! return (dflt); ! } } /************************************************************************** *************** *** 235,322 **** #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. */ ! speed_t 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 }, ! { "19200", B19200 }, ! { "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 } }; static int tbaudrate(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); } /* --- 229,317 ---- #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. */ ! speed_t 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}, ! {"19200", B19200}, ! {"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} }; static int tbaudrate(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); } /* *************** *** 327,436 **** static void add_mapping(const char *port, char *arg) { ! MAP *mapp; ! char *copy, *p; ! const char *termp; ! char *base = 0; ! copy = strdup(arg); ! mapp = 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); } ! if (arg == (char *)0) /* Non-optional type. */ ! goto badmopt; ! mapp->type = arg; ! /* Terminate porttype, if specified. */ ! if (termp != 0) ! *base = '\0'; ! /* If a NOT conditional, reverse the test. */ ! if (mapp->conditional & NOT) ! mapp->conditional = ~mapp->conditional & (EQ | GT | LT); ! /* If user specified a port with an option flag, set it. */ ! done: if (port) { ! if (mapp->porttype) ! badmopt: err("illegal -m option format: %s", copy); ! mapp->porttype = port; ! } #ifdef MAPDEBUG ! (void)printf("port: %s\n", mapp->porttype ? mapp->porttype : "ANY"); ! (void)printf("type: %s\n", mapp->type); ! (void)printf("conditional: "); ! p = ""; ! if (mapp->conditional & GT) { ! (void)printf("GT"); ! p = "/"; ! } ! if (mapp->conditional & EQ) { ! (void)printf("%sEQ", p); ! p = "/"; ! } ! if (mapp->conditional & LT) ! (void)printf("%sLT", p); ! (void)printf("\nspeed: %d\n", mapp->speed); #endif } --- 322,430 ---- static void add_mapping(const char *port, char *arg) { ! MAP *mapp; ! char *copy, *p; ! const char *termp; ! char *base = 0; ! copy = strdup(arg); ! mapp = 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); ! } ! if (arg == (char *) 0) /* Non-optional type. */ ! goto badmopt; ! mapp->type = arg; ! /* Terminate porttype, if specified. */ ! if (termp != 0) ! *base = '\0'; ! /* If a NOT conditional, reverse the test. */ ! if (mapp->conditional & NOT) ! mapp->conditional = ~mapp->conditional & (EQ | GT | LT); + /* If user specified a port with an option flag, set it. */ + done:if (port) { + if (mapp->porttype) + badmopt:err("illegal -m option format: %s", copy); + mapp->porttype = port; + } #ifdef MAPDEBUG ! (void) printf("port: %s\n", mapp->porttype ? mapp->porttype : "ANY"); ! (void) printf("type: %s\n", mapp->type); ! (void) printf("conditional: "); ! p = ""; ! if (mapp->conditional & GT) { ! (void) printf("GT"); ! p = "/"; ! } ! if (mapp->conditional & EQ) { ! (void) printf("%sEQ", p); ! p = "/"; ! } ! if (mapp->conditional & LT) ! (void) printf("%sLT", p); ! (void) printf("\nspeed: %d\n", mapp->speed); #endif } *************** *** 442,479 **** static const char * mapped(const char *type) { ! MAP *mapp; ! int match; ! for (mapp = maplist; mapp; mapp = mapp->next) ! if (mapp->porttype == 0 || !strcmp(mapp->porttype, type)) { ! switch (mapp->conditional) { ! case 0: /* No test specified. */ ! match = TRUE; ! break; ! case EQ: ! match = (ospeed == mapp->speed); ! break; ! case GE: ! match = (ospeed >= mapp->speed); ! break; ! case GT: ! match = (ospeed > mapp->speed); ! break; ! case LE: ! match = (ospeed <= mapp->speed); ! break; ! case LT: ! match = (ospeed < mapp->speed); ! break; ! default: ! match = FALSE; ! } ! if (match) ! return (mapp->type); ! } ! /* No match found; return given type. */ ! return (type); } /************************************************************************** --- 436,473 ---- static const char * mapped(const char *type) { ! MAP *mapp; ! int match; ! for (mapp = maplist; mapp; mapp = mapp->next) ! if (mapp->porttype == 0 || !strcmp(mapp->porttype, type)) { ! switch (mapp->conditional) { ! case 0: /* No test specified. */ ! match = TRUE; ! break; ! case EQ: ! match = (ospeed == mapp->speed); ! break; ! case GE: ! match = (ospeed >= mapp->speed); ! break; ! case GT: ! match = (ospeed > mapp->speed); ! break; ! case LE: ! match = (ospeed <= mapp->speed); ! break; ! case LT: ! match = (ospeed < mapp->speed); ! break; ! default: ! match = FALSE; ! } ! if (match) ! return (mapp->type); ! } ! /* No match found; return given type. */ ! return (type); } /************************************************************************** *************** *** 489,606 **** static const char * get_termcap_entry(char *userarg) { ! int rval, errret; ! char *p; ! const char *ttype; #if HAVE_GETTTYNAM ! struct ttyent *t; #else ! FILE *fp; #endif ! char *ttypath; ! if (userarg) { ! ttype = userarg; ! goto found; ! } ! /* Try the environment. */ ! if ((ttype = getenv("TERM")) != 0) ! goto map; ! 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 */ } ! /* If still undefined, use "unknown". */ ! ttype = "unknown"; ! map: ttype = mapped(ttype); ! /* ! * If not a path, remove TERMCAP from the environment so we get a ! * real entry from /etc/termcap. This prevents us from being fooled ! * by out of date stuff in the environment. */ ! found: if ((p = getenv("TERMCAP")) != 0 && *p != '/') { ! /* 'unsetenv("TERMCAP")' is not portable. ! * The 'environ' array is better. ! */ ! int n; ! for (n = 0; environ[n] != 0; n++) { ! if (!strncmp("TERMCAP=", environ[n], 8)) { ! while ((environ[n] = environ[n+1]) != 0) { ! n++; ! } ! break; ! } } } ! /* ! * ttype now contains a pointer to the type of the terminal. ! * If the first character is '?', ask the user. ! */ ! if (ttype[0] == '?') { ! if (ttype[1] != '\0') ! ttype = askuser(ttype + 1); ! else ! ttype = askuser(0); } ! /* Find the terminfo entry. If it doesn't exist, ask the user. */ ! while ((rval = setupterm((NCURSES_CONST char *)ttype, STDOUT_FILENO, &errret)) != OK) { ! if (errret == 0) { ! (void)fprintf(stderr, "tset: unknown terminal type %s\n", ! ttype); ! ttype = 0; ! } ! else { ! (void)fprintf(stderr, "tset: can't initialize terminal type %s (error %d)\n", ttype, errret); ! ttype = 0; ! } ! ttype = askuser(ttype); ! } #if BROKEN_LINKER ! tgetflag("am"); /* force lib_termcap.o to be linked for 'ospeed' */ #endif ! return (ttype); } /************************************************************************** --- 483,602 ---- static const char * get_termcap_entry(char *userarg) { ! int rval, errret; ! char *p; ! const char *ttype; #if HAVE_GETTTYNAM ! struct ttyent *t; #else ! FILE *fp; #endif ! char *ttypath; ! if (userarg) { ! ttype = userarg; ! goto found; ! } ! /* Try the environment. */ ! if ((ttype = getenv("TERM")) != 0) ! goto map; ! 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 */ + } ! /* If still undefined, use "unknown". */ ! ttype = "unknown"; ! map:ttype = mapped(ttype); ! /* ! * If not a path, remove TERMCAP from the environment so we get a ! * real entry from /etc/termcap. This prevents us from being fooled ! * by out of date stuff in the environment. ! */ ! found:if ((p = getenv("TERMCAP")) != 0 && *p != '/') { ! /* 'unsetenv("TERMCAP")' is not portable. ! * The 'environ' array is better. */ ! int n; ! for (n = 0; environ[n] != 0; n++) { ! if (!strncmp("TERMCAP=", environ[n], 8)) { ! while ((environ[n] = environ[n + 1]) != 0) { ! n++; } + break; + } } + } ! /* ! * ttype now contains a pointer to the type of the terminal. ! * If the first character is '?', ask the user. ! */ ! if (ttype[0] == '?') { ! if (ttype[1] != '\0') ! ttype = askuser(ttype + 1); ! else ! ttype = askuser(0); ! } ! /* Find the terminfo entry. If it doesn't exist, ask the user. */ ! while ((rval = setupterm((NCURSES_CONST char *) ttype, STDOUT_FILENO, ! &errret)) != OK) { ! if (errret == 0) { ! (void) fprintf(stderr, "tset: unknown terminal type %s\n", ! ttype); ! ttype = 0; ! } else { ! (void) fprintf(stderr, ! "tset: can't initialize terminal type %s (error %d)\n", ! ttype, errret); ! ttype = 0; } ! ttype = askuser(ttype); ! } #if BROKEN_LINKER ! tgetflag("am"); /* force lib_termcap.o to be linked for 'ospeed' */ #endif ! return (ttype); } /************************************************************************** *************** *** 637,643 **** #define CHK(val, dft) ((int)val <= 0 ? dft : val) ! static bool set_tabs (void); /* * Reset the terminal mode bits to a sensible state. Very useful after --- 633,639 ---- #define CHK(val, dft) ((int)val <= 0 ? dft : val) ! static bool set_tabs(void); /* * Reset the terminal mode bits to a sensible state. Very useful after *************** *** 647,761 **** reset_mode(void) { #ifdef TERMIOS ! tcgetattr(STDERR_FILENO, &mode); #else ! stty(STDERR_FILENO,&mode); #endif #ifdef TERMIOS #if defined(VDISCARD) && defined(CDISCARD) ! mode.c_cc[VDISCARD] = CHK(mode.c_cc[VDISCARD], CDISCARD); #endif ! mode.c_cc[VEOF] = CHK(mode.c_cc[VEOF], CEOF); ! mode.c_cc[VERASE] = CHK(mode.c_cc[VERASE], CERASE); #if defined(VFLUSH) && defined(CFLUSH) ! mode.c_cc[VFLUSH] = CHK(mode.c_cc[VFLUSH], CFLUSH); #endif ! mode.c_cc[VINTR] = CHK(mode.c_cc[VINTR], CINTR); ! mode.c_cc[VKILL] = CHK(mode.c_cc[VKILL], CKILL); #if defined(VLNEXT) && defined(CLNEXT) ! mode.c_cc[VLNEXT] = CHK(mode.c_cc[VLNEXT], CLNEXT); #endif ! mode.c_cc[VQUIT] = CHK(mode.c_cc[VQUIT], CQUIT); #if defined(VREPRINT) && defined(CRPRNT) ! mode.c_cc[VREPRINT] = CHK(mode.c_cc[VREPRINT], CRPRNT); #endif #if defined(VSTART) && defined(CSTART) ! mode.c_cc[VSTART] = CHK(mode.c_cc[VSTART], CSTART); #endif #if defined(VSTOP) && defined(CSTOP) ! mode.c_cc[VSTOP] = CHK(mode.c_cc[VSTOP], CSTOP); #endif #if defined(VSUSP) && defined(CSUSP) ! mode.c_cc[VSUSP] = CHK(mode.c_cc[VSUSP], CSUSP); #endif #if defined(VWERASE) && defined(CWERASE) ! mode.c_cc[VWERASE] = CHK(mode.c_cc[VWERASE], CWERASE); #endif ! mode.c_iflag &= ~(IGNBRK | PARMRK | INPCK | ISTRIP | INLCR | IGNCR #ifdef IUCLC ! | IUCLC #endif #ifdef IXANY ! | IXANY #endif ! | IXOFF); ! mode.c_iflag |= (BRKINT | IGNPAR | ICRNL | IXON #ifdef IMAXBEL ! | IMAXBEL #endif ! ); ! mode.c_oflag &= ~(0 #ifdef OLCUC ! | OLCUC #endif #ifdef OCRNL ! | OCRNL #endif #ifdef ONOCR ! | ONOCR #endif #ifdef ONLRET ! | ONLRET #endif #ifdef OFILL ! | OFILL #endif #ifdef OFDEL ! | OFDEL #endif #ifdef NLDLY ! | NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY #endif ! ); ! mode.c_oflag |= (OPOST #ifdef ONLCR ! | ONLCR #endif ! ); ! mode.c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD | CLOCAL); ! mode.c_cflag |= (CS8 | CREAD); ! mode.c_lflag &= ~(ECHONL | NOFLSH #ifdef TOSTOP ! | TOSTOP #endif #ifdef ECHOPTR ! | ECHOPRT #endif #ifdef XCASE ! | XCASE #endif ! ); ! mode.c_lflag |= (ISIG | ICANON | ECHO | ECHOE | ECHOK #ifdef ECHOCTL ! | ECHOCTL #endif #ifdef ECHOKE ! | ECHOKE #endif ! ); #endif #ifdef TERMIOS ! tcsetattr(STDERR_FILENO, TCSADRAIN, &mode); #else ! stty(STDERR_FILENO, &mode); #endif } --- 643,757 ---- reset_mode(void) { #ifdef TERMIOS ! tcgetattr(STDERR_FILENO, &mode); #else ! stty(STDERR_FILENO, &mode); #endif #ifdef TERMIOS #if defined(VDISCARD) && defined(CDISCARD) ! mode.c_cc[VDISCARD] = CHK(mode.c_cc[VDISCARD], CDISCARD); #endif ! mode.c_cc[VEOF] = CHK(mode.c_cc[VEOF], CEOF); ! mode.c_cc[VERASE] = CHK(mode.c_cc[VERASE], CERASE); #if defined(VFLUSH) && defined(CFLUSH) ! mode.c_cc[VFLUSH] = CHK(mode.c_cc[VFLUSH], CFLUSH); #endif ! mode.c_cc[VINTR] = CHK(mode.c_cc[VINTR], CINTR); ! mode.c_cc[VKILL] = CHK(mode.c_cc[VKILL], CKILL); #if defined(VLNEXT) && defined(CLNEXT) ! mode.c_cc[VLNEXT] = CHK(mode.c_cc[VLNEXT], CLNEXT); #endif ! mode.c_cc[VQUIT] = CHK(mode.c_cc[VQUIT], CQUIT); #if defined(VREPRINT) && defined(CRPRNT) ! mode.c_cc[VREPRINT] = CHK(mode.c_cc[VREPRINT], CRPRNT); #endif #if defined(VSTART) && defined(CSTART) ! mode.c_cc[VSTART] = CHK(mode.c_cc[VSTART], CSTART); #endif #if defined(VSTOP) && defined(CSTOP) ! mode.c_cc[VSTOP] = CHK(mode.c_cc[VSTOP], CSTOP); #endif #if defined(VSUSP) && defined(CSUSP) ! mode.c_cc[VSUSP] = CHK(mode.c_cc[VSUSP], CSUSP); #endif #if defined(VWERASE) && defined(CWERASE) ! mode.c_cc[VWERASE] = CHK(mode.c_cc[VWERASE], CWERASE); #endif ! mode.c_iflag &= ~(IGNBRK | PARMRK | INPCK | ISTRIP | INLCR | IGNCR #ifdef IUCLC ! | IUCLC #endif #ifdef IXANY ! | IXANY #endif ! | IXOFF); ! mode.c_iflag |= (BRKINT | IGNPAR | ICRNL | IXON #ifdef IMAXBEL ! | IMAXBEL #endif ! ); ! mode.c_oflag &= ~(0 #ifdef OLCUC ! | OLCUC #endif #ifdef OCRNL ! | OCRNL #endif #ifdef ONOCR ! | ONOCR #endif #ifdef ONLRET ! | ONLRET #endif #ifdef OFILL ! | OFILL #endif #ifdef OFDEL ! | OFDEL #endif #ifdef NLDLY ! | NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY #endif ! ); ! mode.c_oflag |= (OPOST #ifdef ONLCR ! | ONLCR #endif ! ); ! mode.c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD | CLOCAL); ! mode.c_cflag |= (CS8 | CREAD); ! mode.c_lflag &= ~(ECHONL | NOFLSH #ifdef TOSTOP ! | TOSTOP #endif #ifdef ECHOPTR ! | ECHOPRT #endif #ifdef XCASE ! | XCASE #endif ! ); ! mode.c_lflag |= (ISIG | ICANON | ECHO | ECHOE | ECHOK #ifdef ECHOCTL ! | ECHOCTL #endif #ifdef ECHOKE ! | ECHOKE #endif ! ); #endif #ifdef TERMIOS ! tcsetattr(STDERR_FILENO, TCSADRAIN, &mode); #else ! stty(STDERR_FILENO, &mode); #endif } *************** *** 766,781 **** static int default_erase(void) { ! int result; ! if (over_strike ! && key_backspace != 0 ! && strlen(key_backspace) == 1) ! result = key_backspace[0]; ! else ! result = CERASE; ! return result; } /* --- 762,777 ---- static int default_erase(void) { ! int result; ! if (over_strike ! && key_backspace != 0 ! && strlen(key_backspace) == 1) ! result = key_backspace[0]; ! else ! result = CERASE; ! return result; } /* *************** *** 789,802 **** set_control_chars(void) { #ifdef TERMIOS ! 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 >= 0 ? intrchar : CINTR; ! if (mode.c_cc[VKILL] == 0 || tkillchar >= 0) ! mode.c_cc[VKILL] = tkillchar >= 0 ? tkillchar : CKILL; #endif } --- 785,798 ---- set_control_chars(void) { #ifdef TERMIOS ! 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 >= 0 ? intrchar : CINTR; ! if (mode.c_cc[VKILL] == 0 || tkillchar >= 0) ! mode.c_cc[VKILL] = tkillchar >= 0 ? tkillchar : CKILL; #endif } *************** *** 810,871 **** set_conversions(void) { #ifdef __OBSOLETE__ ! /* ! * Conversion logic for some *really* ancient terminal glitches, ! * not supported in terminfo. Left here for succeeding generations ! * to marvel at. ! */ ! if (tgetflag("UC")) { #ifdef IUCLC ! mode.c_iflag |= IUCLC; ! mode.c_oflag |= OLCUC; #endif ! } else if (tgetflag("LC")) { #ifdef IUCLC ! mode.c_iflag &= ~IUCLC; ! mode.c_oflag &= ~OLCUC; #endif ! } ! mode.c_iflag &= ~(PARMRK | INPCK); ! mode.c_lflag |= ICANON; ! if (tgetflag("EP")) { ! mode.c_cflag |= PARENB; ! mode.c_cflag &= ~PARODD; ! } ! if (tgetflag("OP")) { ! mode.c_cflag |= PARENB; ! mode.c_cflag |= PARODD; ! } #endif /* __OBSOLETE__ */ #ifdef TERMIOS #ifdef ONLCR ! mode.c_oflag |= ONLCR; #endif ! mode.c_iflag |= ICRNL; ! mode.c_lflag |= ECHO; #ifdef OXTABS ! mode.c_oflag |= OXTABS; #endif /* OXTABS */ ! /* test used to be tgetflag("NL") */ ! if (newline != (char *)0 && newline[0] == '\n' && !newline[1]) { ! /* Newline, not linefeed. */ #ifdef ONLCR ! mode.c_oflag &= ~ONLCR; #endif ! mode.c_iflag &= ~ICRNL; ! } #ifdef __OBSOLETE__ ! if (tgetflag("HD")) /* Half duplex. */ ! mode.c_lflag &= ~ECHO; #endif /* __OBSOLETE__ */ #ifdef OXTABS ! /* test used to be tgetflag("pt") */ ! if (has_hardware_tabs) /* Print tabs. */ ! mode.c_oflag &= ~OXTABS; #endif /* OXTABS */ ! mode.c_lflag |= (ECHOE | ECHOK); #endif } --- 806,867 ---- set_conversions(void) { #ifdef __OBSOLETE__ ! /* ! * Conversion logic for some *really* ancient terminal glitches, ! * not supported in terminfo. Left here for succeeding generations ! * to marvel at. ! */ ! if (tgetflag("UC")) { #ifdef IUCLC ! mode.c_iflag |= IUCLC; ! mode.c_oflag |= OLCUC; #endif ! } else if (tgetflag("LC")) { #ifdef IUCLC ! mode.c_iflag &= ~IUCLC; ! mode.c_oflag &= ~OLCUC; #endif ! } ! mode.c_iflag &= ~(PARMRK | INPCK); ! mode.c_lflag |= ICANON; ! if (tgetflag("EP")) { ! mode.c_cflag |= PARENB; ! mode.c_cflag &= ~PARODD; ! } ! if (tgetflag("OP")) { ! mode.c_cflag |= PARENB; ! mode.c_cflag |= PARODD; ! } #endif /* __OBSOLETE__ */ #ifdef TERMIOS #ifdef ONLCR ! mode.c_oflag |= ONLCR; #endif ! mode.c_iflag |= ICRNL; ! mode.c_lflag |= ECHO; #ifdef OXTABS ! mode.c_oflag |= OXTABS; #endif /* OXTABS */ ! /* test used to be tgetflag("NL") */ ! if (newline != (char *) 0 && newline[0] == '\n' && !newline[1]) { ! /* Newline, not linefeed. */ #ifdef ONLCR ! mode.c_oflag &= ~ONLCR; #endif ! mode.c_iflag &= ~ICRNL; ! } #ifdef __OBSOLETE__ ! if (tgetflag("HD")) /* Half duplex. */ ! mode.c_lflag &= ~ECHO; #endif /* __OBSOLETE__ */ #ifdef OXTABS ! /* test used to be tgetflag("pt") */ ! if (has_hardware_tabs) /* Print tabs. */ ! mode.c_oflag &= ~OXTABS; #endif /* OXTABS */ ! mode.c_lflag |= (ECHOE | ECHOK); #endif } *************** *** 873,917 **** static void set_init(void) { ! char *p; ! bool settle; #ifdef __OBSOLETE__ ! if (pad_char != (char *)0) /* Get/set pad character. */ ! PC = pad_char[0]; #endif /* OBSOLETE */ #ifdef TAB3 ! if (oldmode.c_oflag & (TAB3 | ONLCR | OCRNL | ONLRET)) { ! oldmode.c_oflag &= (TAB3 | ONLCR | OCRNL | ONLRET); ! tcsetattr(STDERR_FILENO, TCSADRAIN, &oldmode); ! } #endif ! settle = set_tabs(); ! if (isreset) { ! if ((p = reset_1string) != 0) { ! tputs(p, 0, outc); ! settle = TRUE; ! } ! if ((p = reset_2string) != 0) { ! tputs(p, 0, outc); ! settle = TRUE; ! } ! /* What about rf, rs3, as per terminfo man page? */ ! /* also might be nice to send rmacs, rmul, rmm */ ! if ((p = reset_file) != 0 ! || (p = init_file) != 0) { ! cat(p); ! settle = TRUE; ! } } ! ! if (settle) { ! (void)putc('\r', stderr); ! (void)fflush(stderr); ! (void)napms(1000); /* Settle the terminal. */ } } /* --- 869,913 ---- static void set_init(void) { ! char *p; ! bool settle; #ifdef __OBSOLETE__ ! if (pad_char != (char *) 0) /* Get/set pad character. */ ! PC = pad_char[0]; #endif /* OBSOLETE */ #ifdef TAB3 ! if (oldmode.c_oflag & (TAB3 | ONLCR | OCRNL | ONLRET)) { ! oldmode.c_oflag &= (TAB3 | ONLCR | OCRNL | ONLRET); ! tcsetattr(STDERR_FILENO, TCSADRAIN, &oldmode); ! } #endif ! settle = set_tabs(); ! if (isreset) { ! if ((p = reset_1string) != 0) { ! tputs(p, 0, outc); ! settle = TRUE; } ! if ((p = reset_2string) != 0) { ! tputs(p, 0, outc); ! settle = TRUE; } + /* What about rf, rs3, as per terminfo man page? */ + /* also might be nice to send rmacs, rmul, rmm */ + if ((p = reset_file) != 0 + || (p = init_file) != 0) { + cat(p); + settle = TRUE; + } + } + + if (settle) { + (void) putc('\r', stderr); + (void) fflush(stderr); + (void) napms(1000); /* Settle the terminal. */ + } } /* *************** *** 923,950 **** static bool set_tabs() { ! if (set_tab && clear_all_tabs) { ! int c; ! (void)putc('\r', stderr); /* Force to left margin. */ ! tputs(clear_all_tabs, 0, outc); ! for (c = 8; c < tcolumns; c += 8) { ! /* Get to the right column. In BSD tset, this ! * used to try a bunch of half-clever things ! * with cup and hpa, for an average saving of ! * somewhat less than two character times per ! * tab stop, less that .01 sec at 2400cps. We ! * lost all this cruft because it seemed to be ! * introducing some odd bugs. ! * ----------12345678----------- */ ! (void)fputs(" ", stderr); ! tputs(set_tab, 0, outc); ! } ! putc('\r', stderr); ! return (TRUE); } ! return (FALSE); } /************************************************************************** --- 919,946 ---- static bool set_tabs() { ! if (set_tab && clear_all_tabs) { ! int c; ! (void) putc('\r', stderr); /* Force to left margin. */ ! tputs(clear_all_tabs, 0, outc); ! for (c = 8; c < tcolumns; c += 8) { ! /* Get to the right column. In BSD tset, this ! * used to try a bunch of half-clever things ! * with cup and hpa, for an average saving of ! * somewhat less than two character times per ! * tab stop, less that .01 sec at 2400cps. We ! * lost all this cruft because it seemed to be ! * introducing some odd bugs. ! * ----------12345678----------- */ ! (void) fputs(" ", stderr); ! tputs(set_tab, 0, outc); } ! putc('\r', stderr); ! return (TRUE); ! } ! return (FALSE); } /************************************************************************** *************** *** 960,991 **** report(const char *name, int which, unsigned def) { #ifdef TERMIOS ! unsigned older, newer; ! char *p; ! newer = mode.c_cc[which]; ! older = oldmode.c_cc[which]; ! if (older == newer && older == def) ! return; ! (void)fprintf(stderr, "%s %s ", name, older == newer ? "is" : "set to"); ! /* ! * 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 == (unsigned char)p[0] ! && p[1] == '\0') ! (void)fprintf(stderr, "backspace.\n"); ! else if (newer < 040) { ! newer ^= 0100; ! (void)fprintf(stderr, "control-%c (^%c).\n", newer, newer); ! } else ! (void)fprintf(stderr, "%c.\n", newer); #endif } --- 956,987 ---- report(const char *name, int which, unsigned def) { #ifdef TERMIOS ! unsigned older, newer; ! char *p; ! newer = mode.c_cc[which]; ! older = oldmode.c_cc[which]; ! if (older == newer && older == def) ! return; ! (void) fprintf(stderr, "%s %s ", name, older == newer ? "is" : "set to"); ! /* ! * 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 == (unsigned char) p[0] ! && p[1] == '\0') ! (void) fprintf(stderr, "backspace.\n"); ! else if (newer < 040) { ! newer ^= 0100; ! (void) fprintf(stderr, "control-%c (^%c).\n", newer, newer); ! } else ! (void) fprintf(stderr, "%c.\n", newer); #endif } *************** *** 996,1256 **** static void obsolete(char **argv) { ! for (; *argv; ++argv) { ! char *parm = argv[0]; ! if (parm[0] == '-' && parm[1] == '\0') ! { ! argv[0] = strdup("-q"); ! continue; ! } ! if ((parm[0] != '-') ! || (argv[1] && argv[1][0] != '-') ! || (parm[1] != 'e' && parm[1] != 'i' && parm[1] != 'k') ! || (parm[2] != '\0')) ! continue; ! switch(argv[0][1]) { ! case 'e': ! argv[0] = strdup("-e^H"); ! break; ! case 'i': ! argv[0] = strdup("-i^C"); ! break; ! case 'k': ! argv[0] = strdup("-k^U"); ! break; ! } } } static void ! usage(const char* pname) { ! (void)fprintf(stderr, ! "usage: %s [-IQrs] [-] [-e ch] [-i ch] [-k ch] [-m mapping] [terminal]\n", 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) { #if defined(TIOCGWINSZ) && defined(TIOCSWINSZ) ! struct winsize win; #endif ! int ch, noinit, noset, quiet, Sflag, sflag, showterm; ! const char *p; ! const char *ttype; #ifdef __OpenBSD__ ! char tcapbuf[1024], *t; ! int tcgetent(char *, const char *); ! void wrtermcap (char *); ! #endif #ifdef TERMIOS ! if (tcgetattr(STDERR_FILENO, &mode) < 0) ! failed("standard error"); ! oldmode = mode; ! ospeed = cfgetospeed(&mode); #else ! if (gtty(STDERR_FILENO, &mode) < 0) ! failed("standard error"); ! oldmode = mode; ! ospeed = mode.sg_ospeed; #endif ! if ((p = strrchr(*argv, '/')) != 0) ! ++p; ! else ! p = *argv; ! if (!CaselessCmp(p, "reset")) { ! isreset = 1; ! reset_mode(); ! } ! obsolete(argv); ! noinit = noset = quiet = Sflag = sflag = showterm = 0; ! while ((ch = getopt(argc, argv, "a:d:e:Ii:k:m:np:qQSrs")) != -1) { ! switch (ch) { ! case 'q': /* display term only */ ! noset = 1; ! break; ! case 'a': /* OBSOLETE: map identifier to type */ ! add_mapping("arpanet", optarg); ! break; ! case 'd': /* OBSOLETE: map identifier to type */ ! add_mapping("dialup", optarg); ! break; ! case 'e': /* erase character */ ! terasechar = arg_to_char(); ! break; ! case 'I': /* no initialization strings */ ! noinit = 1; ! break; ! case 'i': /* interrupt character */ ! intrchar = arg_to_char(); ! break; ! case 'k': /* kill character */ ! tkillchar = arg_to_char(); ! break; ! case 'm': /* map identifier to type */ ! add_mapping(0, optarg); ! break; ! case 'n': /* OBSOLETE: set new tty driver */ ! break; ! case 'p': /* OBSOLETE: map identifier to type */ ! add_mapping("plugboard", optarg); ! break; ! case 'Q': /* don't output control key settings */ ! quiet = 1; ! break; ! case 'S': /* OBSOLETE: output TERM & TERMCAP */ ! Sflag = 1; ! break; ! case 'r': /* display term on stderr */ ! showterm = 1; ! break; ! case 's': /* output TERM set command */ ! sflag = 1; ! break; ! case '?': ! default: ! usage(*argv); ! } } ! argc -= optind; ! argv += optind; ! if (argc > 1) ! usage(*argv); ! ttype = get_termcap_entry(*argv); #ifdef __OpenBSD__ ! if (tcgetent(tcapbuf, ttype) < 0) ! tcapbuf[0] = '\0'; ! #endif ! if (!noset) { ! tcolumns = columns; ! tlines = lines; #if defined(TIOCGWINSZ) && defined(TIOCSWINSZ) ! /* Set window size */ ! (void)ioctl(STDERR_FILENO, TIOCGWINSZ, &win); ! if (win.ws_row == 0 && win.ws_col == 0 && ! tlines > 0 && tcolumns > 0) { ! win.ws_row = tlines; ! win.ws_col = tcolumns; ! (void)ioctl(STDERR_FILENO, TIOCSWINSZ, &win); ! } #endif ! set_control_chars(); ! set_conversions(); ! if (!noinit) ! set_init(); ! /* Set the modes if they've changed. */ ! if (memcmp(&mode, &oldmode, sizeof(mode))) #ifdef TERMIOS ! tcsetattr(STDERR_FILENO, TCSADRAIN, &mode); #else ! stty(STDERR_FILENO, &mode); #endif ! } ! /* Get the terminal name from the entry. */ ! ttype = _nc_first_name(cur_term->type.term_names); ! if (noset) ! (void)printf("%s\n", ttype); ! else { ! if (showterm) ! (void)fprintf(stderr, "Terminal type is %s.\n", ttype); ! /* ! * If erase, kill and interrupt characters could have been ! * modified and not -Q, display the changes. ! */ ! if (!quiet) { ! report("Erase", VERASE, CERASE); ! report("Kill", VKILL, CINTR); ! report("Interrupt", VINTR, CKILL); ! } } #ifdef __OpenBSD__ ! if (Sflag) { ! if (tcapbuf[0]) { ! (void) printf("%s ", ttype); ! wrtermcap(tcapbuf); ! } else ! err("No termcap entry for %s, only terminfo.", ttype); ! } ! #else ! if (Sflag) ! err("The -S option is not supported under terminfo."); #endif /* __OpenBSD__ */ #ifdef __OpenBSD__ ! if (sflag) { ! /* ! * Figure out what shell we're using. A hack, we look for an ! * environmental variable SHELL ending in "csh". ! */ ! if ((p = getenv("SHELL")) != 0 ! && !strcmp(p + strlen(p) - 3, "csh")) { ! if (tcapbuf[0]) ! p = "set noglob histchars="";\nsetenv TERM %s;\nsetenv TERMCAP "; ! else ! p = "set noglob histchars="";\nsetenv TERM %s;\n"; ! t = "unset noglob histchars;\n"; } else { ! if (tcapbuf) { ! p = "TERM=%s;\nTERMCAP="; ! t = "export TERMCAP TERM;\n"; ! } else { ! if (tcapbuf) { ! p = "TERM=%s;\nTERMCAP="; ! t = "export TERMCAP TERM;\n"; ! } else { ! p = "TERM=%s;\n"; ! t = "export TERMCAP;\n"; ! } ! } } ! (void) printf(p, ttype); ! if (tcapbuf[0]) { ! putchar('\''); ! wrtermcap(tcapbuf); ! fputs("';\n", stdout); ! } ! (void)printf(t); } ! #else ! if (sflag) { ! /* ! * Figure out what shell we're using. A hack, we look for an ! * environmental variable SHELL ending in "csh". ! */ ! if ((p = getenv("SHELL")) != 0 ! && !strcmp(p + strlen(p) - 3, "csh")) ! p = "set noglob;\nsetenv TERM %s;\nunset noglob;\n"; ! else ! p = "TERM=%s;\n"; ! (void) printf(p, ttype); } #endif /* __OpenBSD__ */ ! return EXIT_SUCCESS; } /* tset.c ends here */ --- 992,1251 ---- static void obsolete(char **argv) { ! for (; *argv; ++argv) { ! char *parm = argv[0]; ! if (parm[0] == '-' && parm[1] == '\0') { ! argv[0] = strdup("-q"); ! continue; ! } ! if ((parm[0] != '-') ! || (argv[1] && argv[1][0] != '-') ! || (parm[1] != 'e' && parm[1] != 'i' && parm[1] != 'k') ! || (parm[2] != '\0')) ! continue; ! switch (argv[0][1]) { ! case 'e': ! argv[0] = strdup("-e^H"); ! break; ! case 'i': ! argv[0] = strdup("-i^C"); ! break; ! case 'k': ! argv[0] = strdup("-k^U"); ! break; } + } } static void ! usage(const char *pname) { ! (void) fprintf(stderr, ! "usage: %s [-IQrs] [-] [-e ch] [-i ch] [-k ch] [-m mapping] [terminal]\n", 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) { #if defined(TIOCGWINSZ) && defined(TIOCSWINSZ) ! struct winsize win; #endif ! int ch, noinit, noset, quiet, Sflag, sflag, showterm; ! const char *p; ! const char *ttype; #ifdef __OpenBSD__ ! char tcapbuf[1024], *t; ! int tcgetent(char *, const char *); ! void wrtermcap (char *); ! #endif /* __OpenBSD__ */ #ifdef TERMIOS ! if (tcgetattr(STDERR_FILENO, &mode) < 0) ! failed("standard error"); ! oldmode = mode; ! ospeed = cfgetospeed(&mode); #else ! if (gtty(STDERR_FILENO, &mode) < 0) ! failed("standard error"); ! oldmode = mode; ! ospeed = mode.sg_ospeed; #endif ! if ((p = strrchr(*argv, '/')) != 0) ! ++p; ! else ! p = *argv; ! if (!CaselessCmp(p, "reset")) { ! isreset = 1; ! reset_mode(); ! } ! obsolete(argv); ! noinit = noset = quiet = Sflag = sflag = showterm = 0; ! while ((ch = getopt(argc, argv, "a:d:e:Ii:k:m:np:qQSrs")) != -1) { ! switch (ch) { ! case 'q': /* display term only */ ! noset = 1; ! break; ! case 'a': /* OBSOLETE: map identifier to type */ ! add_mapping("arpanet", optarg); ! break; ! case 'd': /* OBSOLETE: map identifier to type */ ! add_mapping("dialup", optarg); ! break; ! case 'e': /* erase character */ ! terasechar = arg_to_char(); ! break; ! case 'I': /* no initialization strings */ ! noinit = 1; ! break; ! case 'i': /* interrupt character */ ! intrchar = arg_to_char(); ! break; ! case 'k': /* kill character */ ! tkillchar = arg_to_char(); ! break; ! case 'm': /* map identifier to type */ ! add_mapping(0, optarg); ! break; ! case 'n': /* OBSOLETE: set new tty driver */ ! break; ! case 'p': /* OBSOLETE: map identifier to type */ ! add_mapping("plugboard", optarg); ! break; ! case 'Q': /* don't output control key settings */ ! quiet = 1; ! break; ! case 'S': /* OBSOLETE: output TERM & TERMCAP */ ! Sflag = 1; ! break; ! case 'r': /* display term on stderr */ ! showterm = 1; ! break; ! case 's': /* output TERM set command */ ! sflag = 1; ! break; ! case '?': ! default: ! usage(*argv); } ! } ! argc -= optind; ! argv += optind; ! if (argc > 1) ! usage(*argv); ! ttype = get_termcap_entry(*argv); #ifdef __OpenBSD__ ! if (tcgetent(tcapbuf, ttype) < 0) ! tcapbuf[0] = '\0'; ! #endif /* __OpenBSD__ */ ! if (!noset) { ! tcolumns = columns; ! tlines = lines; #if defined(TIOCGWINSZ) && defined(TIOCSWINSZ) ! /* Set window size */ ! (void) ioctl(STDERR_FILENO, TIOCGWINSZ, &win); ! if (win.ws_row == 0 && win.ws_col == 0 && ! tlines > 0 && tcolumns > 0) { ! win.ws_row = tlines; ! win.ws_col = tcolumns; ! (void) ioctl(STDERR_FILENO, TIOCSWINSZ, &win); ! } #endif ! set_control_chars(); ! set_conversions(); ! if (!noinit) ! set_init(); ! /* Set the modes if they've changed. */ ! if (memcmp(&mode, &oldmode, sizeof(mode))) #ifdef TERMIOS ! tcsetattr(STDERR_FILENO, TCSADRAIN, &mode); #else ! stty(STDERR_FILENO, &mode); #endif ! } ! /* Get the terminal name from the entry. */ ! ttype = _nc_first_name(cur_term->type.term_names); ! if (noset) ! (void) printf("%s\n", ttype); ! else { ! if (showterm) ! (void) fprintf(stderr, "Terminal type is %s.\n", ttype); ! /* ! * If erase, kill and interrupt characters could have been ! * modified and not -Q, display the changes. ! */ ! if (!quiet) { ! report("Erase", VERASE, CERASE); ! report("Kill", VKILL, CINTR); ! report("Interrupt", VINTR, CKILL); } + } #ifdef __OpenBSD__ ! if (Sflag) { ! if (tcapbuf[0]) { ! (void) printf("%s ", ttype); ! wrtermcap(tcapbuf); ! } else ! err("No termcap entry for %s, only terminfo.", ttype); ! } ! #else ! if (Sflag) ! err("The -S option is not supported under terminfo."); #endif /* __OpenBSD__ */ #ifdef __OpenBSD__ ! if (sflag) { ! /* ! * Figure out what shell we're using. A hack, we look for an ! * environmental variable SHELL ending in "csh". ! */ ! if ((p = getenv("SHELL")) != 0 && !strcmp(p + strlen(p) - 3, "csh")) { ! if (tcapbuf[0]) ! p = "set noglob histchars="";\nsetenv TERM %s;\nsetenv TERMCAP "; ! else ! p = "set noglob histchars="";\nsetenv TERM %s;\n"; ! t = "unset noglob histchars;\n"; ! } else { ! if (tcapbuf) { ! p = "TERM=%s;\nTERMCAP="; ! t = "export TERMCAP TERM;\n"; ! } else { ! if (tcapbuf) { ! p = "TERM=%s;\nTERMCAP="; ! t = "export TERMCAP TERM;\n"; } else { ! p = "TERM=%s;\n"; ! t = "export TERMCAP;\n"; } ! } } ! (void) printf(p, ttype); ! if (tcapbuf[0]) { ! putchar('\''); ! wrtermcap(tcapbuf); ! fputs("';\n", stdout); } + (void)printf(t); + } + #else + if (sflag) { + /* + * Figure out what shell we're using. A hack, we look for an + * environmental variable SHELL ending in "csh". + */ + if ((p = getenv("SHELL")) != 0 + && !strcmp(p + strlen(p) - 3, "csh")) + p = "set noglob;\nsetenv TERM %s;\nunset noglob;\n"; + else + p = "TERM=%s;\n"; + (void) printf(p, ttype); + } #endif /* __OpenBSD__ */ ! return EXIT_SUCCESS; } /* tset.c ends here */