Bug Summary

File:src/usr.bin/tset/tset.c
Warning:line 1208, column 5
Value stored to 'ttype' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name tset.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.bin/tset/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.bin/tset/../../lib/libcurses -I /usr/src/usr.bin/tset/../tic -I /usr/src/usr.bin/tset -I . -D HAVE_GETTTYNAM -D HAVE_TTYENT_H -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.bin/tset/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.bin/tset/tset.c
1/* $OpenBSD: tset.c,v 1.43 2021/06/22 18:33:48 tb Exp $ */
2
3/****************************************************************************
4 * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. *
5 * *
6 * Permission is hereby granted, free of charge, to any person obtaining a *
7 * copy of this software and associated documentation files (the *
8 * "Software"), to deal in the Software without restriction, including *
9 * without limitation the rights to use, copy, modify, merge, publish, *
10 * distribute, distribute with modifications, sublicense, and/or sell *
11 * copies of the Software, and to permit persons to whom the Software is *
12 * furnished to do so, subject to the following conditions: *
13 * *
14 * The above copyright notice and this permission notice shall be included *
15 * in all copies or substantial portions of the Software. *
16 * *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
20 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
23 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
24 * *
25 * Except as contained in this notice, the name(s) of the above copyright *
26 * holders shall not be used in advertising or otherwise to promote the *
27 * sale, use or other dealings in this Software without prior written *
28 * authorization. *
29 ****************************************************************************/
30
31/****************************************************************************
32 * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
33 * and: Eric S. Raymond <esr@snark.thyrsus.com> *
34 * and: Thomas E. Dickey 1996-on *
35 ****************************************************************************/
36
37/*
38 * tset.c - terminal initialization utility
39 *
40 * This code was mostly swiped from 4.4BSD tset, with some obsolescent
41 * cruft removed and substantial portions rewritten. A Regents of the
42 * University of California copyright applies to some portions of the
43 * code, and is reproduced below:
44 */
45/*-
46 * Copyright (c) 1980, 1991, 1993
47 * The Regents of the University of California. All rights reserved.
48 *
49 * Redistribution and use in source and binary forms, with or without
50 * modification, are permitted provided that the following conditions
51 * are met:
52 * 1. Redistributions of source code must retain the above copyright
53 * notice, this list of conditions and the following disclaimer.
54 * 2. Redistributions in binary form must reproduce the above copyright
55 * notice, this list of conditions and the following disclaimer in the
56 * documentation and/or other materials provided with the distribution.
57 * 3. Neither the name of the University nor the names of its contributors
58 * may be used to endorse or promote products derived from this software
59 * without specific prior written permission.
60 *
61 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
62 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
63 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
64 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
65 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
66 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
67 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
68 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
69 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
70 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
71 * SUCH DAMAGE.
72 */
73
74#define USE_LIBTINFO
75#define __INTERNAL_CAPS_VISIBLE /* we need to see has_hardware_tabs */
76#include <progs.priv.h>
77
78#include <errno(*__errno()).h>
79#include <stdio.h>
80#include <termcap.h>
81#include <fcntl.h>
82
83#if HAVE_GETTTYNAM1 && HAVE_TTYENT_H1
84#include <ttyent.h>
85#endif
86#ifdef NeXT
87char *ttyname(int fd);
88#endif
89
90#if HAVE_SIZECHANGE1
91# if !defined(sun) || !TERMIOS1
92# if HAVE_SYS_IOCTL_H1
93# include <sys/ioctl.h>
94# endif
95# endif
96#endif
97
98#if NEED_PTEM_H0
99/* they neglected to define struct winsize in termios.h -- it's only
100 in termio.h */
101#include <sys/stream.h>
102#include <sys/ptem.h>
103#endif
104
105#include <dump_entry.h>
106#include <transform.h>
107
108extern char **environ;
109
110#undef CTRL
111#define CTRL(x)((x) & 0x1f) ((x) & 0x1f)
112
113const char *_nc_progname;
114
115static TTYstruct termios mode, oldmode, original;
116
117static bool_Bool opt_c; /* set control-chars */
118static bool_Bool opt_w; /* set window-size */
119
120static bool_Bool can_restore = FALSE0;
121static bool_Bool isreset = FALSE0; /* invoked as reset */
122static int terasechar = -1; /* new erase character */
123static int intrchar = -1; /* new interrupt character */
124static int tkillchar = -1; /* new kill character */
125static int tlines, tcolumns; /* window size */
126
127#define LOWERCASE(c)((isalpha(((unsigned char)(c))) && isupper(((unsigned
char)(c)))) ? tolower(((unsigned char)(c))) : (c))
((isalpha(UChar(c)((unsigned char)(c))) && isupper(UChar(c)((unsigned char)(c)))) ? tolower(UChar(c)((unsigned char)(c))) : (c))
128
129static int
130CaselessCmp(const char *a, const char *b)
131{ /* strcasecmp isn't portable */
132 while (*a && *b) {
133 int cmp = LOWERCASE(*a)((isalpha(((unsigned char)(*a))) && isupper(((unsigned
char)(*a)))) ? tolower(((unsigned char)(*a))) : (*a))
- LOWERCASE(*b)((isalpha(((unsigned char)(*b))) && isupper(((unsigned
char)(*b)))) ? tolower(((unsigned char)(*b))) : (*b))
;
134 if (cmp != 0)
135 break;
136 a++, b++;
137 }
138 return LOWERCASE(*a)((isalpha(((unsigned char)(*a))) && isupper(((unsigned
char)(*a)))) ? tolower(((unsigned char)(*a))) : (*a))
- LOWERCASE(*b)((isalpha(((unsigned char)(*b))) && isupper(((unsigned
char)(*b)))) ? tolower(((unsigned char)(*b))) : (*b))
;
139}
140
141static void
142exit_error(void)
143{
144 if (can_restore)
145 tcsetattr(STDERR_FILENO2, TCSADRAIN1, &original);
146 (void) fprintf(stderr(&__sF[2]), "\n");
147 fflush(stderr(&__sF[2]));
148 ExitProgram(EXIT_FAILURE)exit(1);
149 /* NOTREACHED */
150}
151
152static void
153err(const char *fmt,...)
154{
155 va_list ap;
156 va_start(ap, fmt)__builtin_va_start(ap, fmt);
157 (void) fprintf(stderr(&__sF[2]), "%s: ", _nc_progname);
158 (void) vfprintf(stderr(&__sF[2]), fmt, ap);
159 va_end(ap)__builtin_va_end(ap);
160 exit_error();
161 /* NOTREACHED */
162}
163
164static void
165failed(const char *msg)
166{
167 fprintf(stderr(&__sF[2]), "%s: ", _nc_progname);
168 perror(msg);
169 exit_error();
170 /* NOTREACHED */
171}
172
173static void
174cat(char *file)
175{
176 FILE *fp;
177 size_t nr;
178 char buf[BUFSIZ1024];
179
180 if ((fp = fopen(file, "r")) == 0)
181 failed(file);
182
183 while ((nr = fread(buf, sizeof(char), sizeof(buf), fp)) != 0)
184 if (fwrite(buf, sizeof(char), nr, stderr(&__sF[2])) != nr)
185 failed("write to stderr");
186 fclose(fp);
187}
188
189static int
190outc(int c)
191{
192 return putc(c, stderr)(!__isthreaded ? __sputc(c, (&__sF[2])) : (putc)(c, (&
__sF[2])))
;
193}
194
195/* Prompt the user for a terminal type. */
196static const char *
197askuser(const char *dflt)
198{
199 static char answer[256];
200
201 /* We can get recalled; if so, don't continue uselessly. */
202 clearerr(stdin)(!__isthreaded ? ((void)(((&__sF[0]))->_flags &= ~
(0x0040|0x0020))) : (clearerr)((&__sF[0])))
;
203 if (feof(stdin)(!__isthreaded ? ((((&__sF[0]))->_flags & 0x0020) !=
0) : (feof)((&__sF[0])))
|| ferror(stdin)(!__isthreaded ? ((((&__sF[0]))->_flags & 0x0040) !=
0) : (ferror)((&__sF[0])))
) {
204 (void) fprintf(stderr(&__sF[2]), "\n");
205 exit_error();
206 /* NOTREACHED */
207 }
208 for (;;) {
209 if (dflt)
210 (void) fprintf(stderr(&__sF[2]), "Terminal type? [%s] ", dflt);
211 else
212 (void) fprintf(stderr(&__sF[2]), "Terminal type? ");
213 (void) fflush(stderr(&__sF[2]));
214
215 if (fgets(answer, sizeof(answer), stdin(&__sF[0])) == NULL((void *)0)) {
216 if (dflt == 0) {
217 exit_error();
218 /* NOTREACHED */
219 }
220 return (dflt);
221 }
222
223 answer[strcspn(answer, "\n")] = '\0';
224 if (answer[0])
225 return (answer);
226 if (dflt != 0)
227 return (dflt);
228 }
229}
230
231/**************************************************************************
232 *
233 * Mapping logic begins here
234 *
235 **************************************************************************/
236
237/* Baud rate conditionals for mapping. */
238#define GT0x01 0x01
239#define EQ0x02 0x02
240#define LT0x04 0x04
241#define NOT0x08 0x08
242#define GE(0x01 | 0x02) (GT0x01 | EQ0x02)
243#define LE(0x04 | 0x02) (LT0x04 | EQ0x02)
244
245typedef struct map {
246 struct map *next; /* Linked list of maps. */
247 const char *porttype; /* Port type, or "" for any. */
248 const char *type; /* Terminal type to select. */
249 int conditional; /* Baud rate conditionals bitmask. */
250 int speed; /* Baud rate to compare against. */
251} MAP;
252
253static MAP *cur, *maplist;
254
255typedef struct speeds {
256 const char *string;
257 int speed;
258} SPEEDS;
259
260static const SPEEDS speeds[] =
261{
262 {"0", B00},
263 {"50", B5050},
264 {"75", B7575},
265 {"110", B110110},
266 {"134", B134134},
267 {"134.5", B134134},
268 {"150", B150150},
269 {"200", B200200},
270 {"300", B300300},
271 {"600", B600600},
272 {"1200", B12001200},
273 {"1800", B18001800},
274 {"2400", B24002400},
275 {"4800", B48004800},
276 {"9600", B96009600},
277 /* sgttyb may define up to this point */
278#ifdef B1920019200
279 {"19200", B1920019200},
280#endif
281#ifdef B3840038400
282 {"38400", B3840038400},
283#endif
284#ifdef B1920019200
285 {"19200", B1920019200},
286#endif
287#ifdef B3840038400
288 {"38400", B3840038400},
289#endif
290#ifdef B1920019200
291 {"19200", B1920019200},
292#else
293#ifdef EXTA19200
294 {"19200", EXTA19200},
295#endif
296#endif
297#ifdef B3840038400
298 {"38400", B3840038400},
299#else
300#ifdef EXTB38400
301 {"38400", EXTB38400},
302#endif
303#endif
304#ifdef B5760057600
305 {"57600", B5760057600},
306#endif
307#ifdef B115200115200
308 {"115200", B115200115200},
309#endif
310#ifdef B230400230400
311 {"230400", B230400230400},
312#endif
313#ifdef B460800
314 {"460800", B460800},
315#endif
316 {(char *) 0, 0}
317};
318
319static int
320tbaudrate(char *rate)
321{
322 const SPEEDS *sp;
323 int found = FALSE0;
324
325 /* The baudrate number can be preceded by a 'B', which is ignored. */
326 if (*rate == 'B')
327 ++rate;
328
329 for (sp = speeds; sp->string; ++sp) {
330 if (!CaselessCmp(rate, sp->string)) {
331 found = TRUE1;
332 break;
333 }
334 }
335 if (!found)
336 err("unknown baud rate %s", rate);
337 return (sp->speed);
338}
339
340/*
341 * Syntax for -m:
342 * [port-type][test baudrate]:terminal-type
343 * The baud rate tests are: >, <, @, =, !
344 */
345static void
346add_mapping(const char *port, char *arg)
347{
348 MAP *mapp;
349 char *copy, *p;
350 const char *termp;
351 char *base = 0;
352
353 copy = strdup(arg);
354 mapp = malloc(sizeof(MAP));
355 if (copy == 0 || mapp == 0)
356 failed("malloc");
357 mapp->next = 0;
358 if (maplist == 0)
359 cur = maplist = mapp;
360 else {
361 cur->next = mapp;
362 cur = mapp;
363 }
364
365 mapp->porttype = arg;
366 mapp->conditional = 0;
367
368 arg = strpbrk(arg, "><@=!:");
369
370 if (arg == 0) { /* [?]term */
371 mapp->type = mapp->porttype;
372 mapp->porttype = 0;
373 goto done;
374 }
375
376 if (arg == mapp->porttype) /* [><@=! baud]:term */
377 termp = mapp->porttype = 0;
378 else
379 termp = base = arg;
380
381 for (;; ++arg) { /* Optional conditionals. */
382 switch (*arg) {
383 case '<':
384 if (mapp->conditional & GT0x01)
385 goto badmopt;
386 mapp->conditional |= LT0x04;
387 break;
388 case '>':
389 if (mapp->conditional & LT0x04)
390 goto badmopt;
391 mapp->conditional |= GT0x01;
392 break;
393 case '@':
394 case '=': /* Not documented. */
395 mapp->conditional |= EQ0x02;
396 break;
397 case '!':
398 mapp->conditional |= NOT0x08;
399 break;
400 default:
401 goto next;
402 }
403 }
404
405 next:
406 if (*arg == ':') {
407 if (mapp->conditional)
408 goto badmopt;
409 ++arg;
410 } else { /* Optional baudrate. */
411 arg = strchr(p = arg, ':');
412 if (arg == 0)
413 goto badmopt;
414 *arg++ = '\0';
415 mapp->speed = tbaudrate(p);
416 }
417
418 if (arg == (char *) 0) /* Non-optional type. */
419 goto badmopt;
420
421 mapp->type = arg;
422
423 /* Terminate porttype, if specified. */
424 if (termp != 0)
425 *base = '\0';
426
427 /* If a NOT conditional, reverse the test. */
428 if (mapp->conditional & NOT0x08)
429 mapp->conditional = ~mapp->conditional & (EQ0x02 | GT0x01 | LT0x04);
430
431 /* If user specified a port with an option flag, set it. */
432 done:
433 if (port) {
434 if (mapp->porttype) {
435 badmopt:
436 err("illegal -m option format: %s", copy);
437 }
438 mapp->porttype = port;
439 }
440 free(copy);
441#ifdef MAPDEBUG
442 (void) printf("port: %s\n", mapp->porttype ? mapp->porttype : "ANY");
443 (void) printf("type: %s\n", mapp->type);
444 (void) printf("conditional: ");
445 p = "";
446 if (mapp->conditional & GT0x01) {
447 (void) printf("GT");
448 p = "/";
449 }
450 if (mapp->conditional & EQ0x02) {
451 (void) printf("%sEQ", p);
452 p = "/";
453 }
454 if (mapp->conditional & LT0x04)
455 (void) printf("%sLT", p);
456 (void) printf("\nspeed: %d\n", mapp->speed);
457#endif
458}
459
460/*
461 * Return the type of terminal to use for a port of type 'type', as specified
462 * by the first applicable mapping in 'map'. If no mappings apply, return
463 * 'type'.
464 */
465static const char *
466mapped(const char *type)
467{
468 MAP *mapp;
469 int match;
470
471 for (mapp = maplist; mapp; mapp = mapp->next)
472 if (mapp->porttype == 0 || !strcmp(mapp->porttype, type)) {
473 switch (mapp->conditional) {
474 case 0: /* No test specified. */
475 match = TRUE1;
476 break;
477 case EQ0x02:
478 match = (ospeed == mapp->speed);
479 break;
480 case GE(0x01 | 0x02):
481 match = (ospeed >= mapp->speed);
482 break;
483 case GT0x01:
484 match = (ospeed > mapp->speed);
485 break;
486 case LE(0x04 | 0x02):
487 match = (ospeed <= mapp->speed);
488 break;
489 case LT0x04:
490 match = (ospeed < mapp->speed);
491 break;
492 default:
493 match = FALSE0;
494 }
495 if (match)
496 return (mapp->type);
497 }
498 /* No match found; return given type. */
499 return (type);
500}
501
502/**************************************************************************
503 *
504 * Entry fetching
505 *
506 **************************************************************************/
507
508/*
509 * Figure out what kind of terminal we're dealing with, and then read in
510 * its termcap entry.
511 */
512static const char *
513get_termcap_entry(char *userarg)
514{
515 int errret;
516 char *p;
517 const char *ttype;
518#if HAVE_GETTTYNAM1
519 struct ttyent *t;
520#else
521 FILE *fp;
522#endif
523 char *ttypath;
524
525 if (userarg) {
526 ttype = userarg;
527 goto found;
528 }
529
530 /* Try the environment. */
531 if ((ttype = getenv("TERM")) != 0)
532 goto map;
533
534 if ((ttypath = ttyname(STDERR_FILENO2)) != 0) {
535 p = _nc_basename(ttypath);
536#if HAVE_GETTTYNAM1
537 /*
538 * We have the 4.3BSD library call getttynam(3); that means
539 * there's an /etc/ttys to look up device-to-type mappings in.
540 * Try ttyname(3); check for dialup or other mapping.
541 */
542 if ((t = getttynam(p))) {
543 ttype = t->ty_type;
544 goto map;
545 }
546#else
547 if ((fp = fopen("/etc/ttytype", "r")) != 0
548 || (fp = fopen("/etc/ttys", "r")) != 0) {
549 char buffer[BUFSIZ1024];
550 char *s, *t, *d;
551
552 while (fgets(buffer, sizeof(buffer), fp) != NULL((void *)0)) {
553 for (s = buffer, t = d = 0; *s; s++) {
554 if (isspace(UChar(*s)((unsigned char)(*s))))
555 *s = '\0';
556 else if (t == 0)
557 t = s;
558 else if (d == 0 && s != buffer && s[-1] == '\0')
559 d = s;
560 }
561 if (t != 0 && d != 0 && !strcmp(d, p)) {
562 ttype = strdup(t);
563 fclose(fp);
564 goto map;
565 }
566 }
567 fclose(fp);
568 }
569#endif /* HAVE_GETTTYNAM */
570 }
571
572 /* If still undefined, use "unknown". */
573 ttype = "unknown";
574
575 map:ttype = mapped(ttype);
576
577 /*
578 * If not a path, remove TERMCAP from the environment so we get a
579 * real entry from /etc/termcap. This prevents us from being fooled
580 * by out of date stuff in the environment.
581 */
582 found:if ((p = getenv("TERMCAP")) != 0 && !_nc_is_abs_path(p)) {
583 /* 'unsetenv("TERMCAP")' is not portable.
584 * The 'environ' array is better.
585 */
586 int n;
587 for (n = 0; environ[n] != 0; n++) {
588 if (!strncmp("TERMCAP=", environ[n], 8)) {
589 while ((environ[n] = environ[n + 1]) != 0) {
590 n++;
591 }
592 break;
593 }
594 }
595 }
596
597 /*
598 * ttype now contains a pointer to the type of the terminal.
599 * If the first character is '?', ask the user.
600 */
601 if (ttype[0] == '?') {
602 if (ttype[1] != '\0')
603 ttype = askuser(ttype + 1);
604 else
605 ttype = askuser(0);
606 }
607 /* Find the terminfo entry. If it doesn't exist, ask the user. */
608 while (setupterm((NCURSES_CONSTconst char *) ttype, STDOUT_FILENO1, &errret)
609 != OK(0)) {
610 if (errret == 0) {
611 (void) fprintf(stderr(&__sF[2]), "%s: unknown terminal type %s\n",
612 _nc_progname, ttype);
613 ttype = 0;
614 } else {
615 (void) fprintf(stderr(&__sF[2]),
616 "%s: can't initialize terminal type %s (error %d)\n",
617 _nc_progname, ttype, errret);
618 ttype = 0;
619 }
620 ttype = askuser(ttype);
621 }
622#if BROKEN_LINKER0
623 tgetflag("am"); /* force lib_termcap.o to be linked for 'ospeed' */
624#endif
625 return (ttype);
626}
627
628/**************************************************************************
629 *
630 * Mode-setting logic
631 *
632 **************************************************************************/
633
634/* some BSD systems have these built in, some systems are missing
635 * one or more definitions. The safest solution is to override unless the
636 * commonly-altered ones are defined.
637 */
638#if !(defined(CERASE0177) && defined(CINTR(('c') & 0x1f)) && defined(CKILL(('u') & 0x1f)) && defined(CQUIT034))
639#undef CEOF(('d') & 0x1f)
640#undef CERASE0177
641#undef CINTR(('c') & 0x1f)
642#undef CKILL(('u') & 0x1f)
643#undef CLNEXT(('v') & 0x1f)
644#undef CRPRNT(('r') & 0x1f)
645#undef CQUIT034
646#undef CSTART(('q') & 0x1f)
647#undef CSTOP(('s') & 0x1f)
648#undef CSUSP(('z') & 0x1f)
649#endif
650
651/* control-character defaults */
652#ifndef CEOF(('d') & 0x1f)
653#define CEOF(('d') & 0x1f) CTRL('D')(('D') & 0x1f)
654#endif
655#ifndef CERASE0177
656#define CERASE0177 CTRL('H')(('H') & 0x1f)
657#endif
658#ifndef CINTR(('c') & 0x1f)
659#define CINTR(('c') & 0x1f) 127 /* ^? */
660#endif
661#ifndef CKILL(('u') & 0x1f)
662#define CKILL(('u') & 0x1f) CTRL('U')(('U') & 0x1f)
663#endif
664#ifndef CLNEXT(('v') & 0x1f)
665#define CLNEXT(('v') & 0x1f) CTRL('v')(('v') & 0x1f)
666#endif
667#ifndef CRPRNT(('r') & 0x1f)
668#define CRPRNT(('r') & 0x1f) CTRL('r')(('r') & 0x1f)
669#endif
670#ifndef CQUIT034
671#define CQUIT034 CTRL('\\')(('\\') & 0x1f)
672#endif
673#ifndef CSTART(('q') & 0x1f)
674#define CSTART(('q') & 0x1f) CTRL('Q')(('Q') & 0x1f)
675#endif
676#ifndef CSTOP(('s') & 0x1f)
677#define CSTOP(('s') & 0x1f) CTRL('S')(('S') & 0x1f)
678#endif
679#ifndef CSUSP(('z') & 0x1f)
680#define CSUSP(('z') & 0x1f) CTRL('Z')(('Z') & 0x1f)
681#endif
682
683#if defined(_POSIX_VDISABLE(0377))
684#define DISABLED(val)((((0377) != -1) && ((val) == (0377))) || ((val) <=
0))
(((_POSIX_VDISABLE(0377) != -1) \
685 && ((val) == _POSIX_VDISABLE(0377))) \
686 || ((val) <= 0))
687#else
688#define DISABLED(val)((((0377) != -1) && ((val) == (0377))) || ((val) <=
0))
((int)(val) <= 0)
689#endif
690
691#define CHK(val, dft)(((((0377) != -1) && ((val) == (0377))) || ((val) <=
0)) ? dft : val)
(DISABLED(val)((((0377) != -1) && ((val) == (0377))) || ((val) <=
0))
? dft : val)
692
693static bool_Bool set_tabs(void);
694
695/*
696 * Reset the terminal mode bits to a sensible state. Very useful after
697 * a child program dies in raw mode.
698 */
699static void
700reset_mode(void)
701{
702#ifdef TERMIOS1
703 tcgetattr(STDERR_FILENO2, &mode);
704#else
705 stty(STDERR_FILENO2, &mode);
706#endif
707
708#ifdef TERMIOS1
709#if defined(VDISCARD15) && defined(CDISCARD(('o') & 0x1f))
710 mode.c_cc[VDISCARD15] = CHK(mode.c_cc[VDISCARD], CDISCARD)(((((0377) != -1) && ((mode.c_cc[15]) == (0377))) || (
(mode.c_cc[15]) <= 0)) ? (('o') & 0x1f) : mode.c_cc[15
])
;
711#endif
712 mode.c_cc[VEOF0] = CHK(mode.c_cc[VEOF], CEOF)(((((0377) != -1) && ((mode.c_cc[0]) == (0377))) || (
(mode.c_cc[0]) <= 0)) ? (('d') & 0x1f) : mode.c_cc[0])
;
713 mode.c_cc[VERASE3] = CHK(mode.c_cc[VERASE], CERASE)(((((0377) != -1) && ((mode.c_cc[3]) == (0377))) || (
(mode.c_cc[3]) <= 0)) ? 0177 : mode.c_cc[3])
;
714#if defined(VFLUSH) && defined(CFLUSH(('o') & 0x1f))
715 mode.c_cc[VFLUSH] = CHK(mode.c_cc[VFLUSH], CFLUSH)(((((0377) != -1) && ((mode.c_cc[VFLUSH]) == (0377)))
|| ((mode.c_cc[VFLUSH]) <= 0)) ? (('o') & 0x1f) : mode
.c_cc[VFLUSH])
;
716#endif
717 mode.c_cc[VINTR8] = CHK(mode.c_cc[VINTR], CINTR)(((((0377) != -1) && ((mode.c_cc[8]) == (0377))) || (
(mode.c_cc[8]) <= 0)) ? (('c') & 0x1f) : mode.c_cc[8])
;
718 mode.c_cc[VKILL5] = CHK(mode.c_cc[VKILL], CKILL)(((((0377) != -1) && ((mode.c_cc[5]) == (0377))) || (
(mode.c_cc[5]) <= 0)) ? (('u') & 0x1f) : mode.c_cc[5])
;
719#if defined(VLNEXT14) && defined(CLNEXT(('v') & 0x1f))
720 mode.c_cc[VLNEXT14] = CHK(mode.c_cc[VLNEXT], CLNEXT)(((((0377) != -1) && ((mode.c_cc[14]) == (0377))) || (
(mode.c_cc[14]) <= 0)) ? (('v') & 0x1f) : mode.c_cc[14
])
;
721#endif
722 mode.c_cc[VQUIT9] = CHK(mode.c_cc[VQUIT], CQUIT)(((((0377) != -1) && ((mode.c_cc[9]) == (0377))) || (
(mode.c_cc[9]) <= 0)) ? 034 : mode.c_cc[9])
;
723#if defined(VREPRINT6) && defined(CRPRNT(('r') & 0x1f))
724 mode.c_cc[VREPRINT6] = CHK(mode.c_cc[VREPRINT], CRPRNT)(((((0377) != -1) && ((mode.c_cc[6]) == (0377))) || (
(mode.c_cc[6]) <= 0)) ? (('r') & 0x1f) : mode.c_cc[6])
;
725#endif
726#if defined(VSTART12) && defined(CSTART(('q') & 0x1f))
727 mode.c_cc[VSTART12] = CHK(mode.c_cc[VSTART], CSTART)(((((0377) != -1) && ((mode.c_cc[12]) == (0377))) || (
(mode.c_cc[12]) <= 0)) ? (('q') & 0x1f) : mode.c_cc[12
])
;
728#endif
729#if defined(VSTOP13) && defined(CSTOP(('s') & 0x1f))
730 mode.c_cc[VSTOP13] = CHK(mode.c_cc[VSTOP], CSTOP)(((((0377) != -1) && ((mode.c_cc[13]) == (0377))) || (
(mode.c_cc[13]) <= 0)) ? (('s') & 0x1f) : mode.c_cc[13
])
;
731#endif
732#if defined(VSUSP10) && defined(CSUSP(('z') & 0x1f))
733 mode.c_cc[VSUSP10] = CHK(mode.c_cc[VSUSP], CSUSP)(((((0377) != -1) && ((mode.c_cc[10]) == (0377))) || (
(mode.c_cc[10]) <= 0)) ? (('z') & 0x1f) : mode.c_cc[10
])
;
734#endif
735#if defined(VWERASE4) && defined(CWERASE(('w') & 0x1f))
736 mode.c_cc[VWERASE4] = CHK(mode.c_cc[VWERASE], CWERASE)(((((0377) != -1) && ((mode.c_cc[4]) == (0377))) || (
(mode.c_cc[4]) <= 0)) ? (('w') & 0x1f) : mode.c_cc[4])
;
737#endif
738
739 mode.c_iflag &= ~(IGNBRK0x00000001 | PARMRK0x00000008 | INPCK0x00000010 | ISTRIP0x00000020 | INLCR0x00000040 | IGNCR0x00000080
740#ifdef IUCLC0x00001000
741 | IUCLC0x00001000
742#endif
743#ifdef IXANY0x00000800
744 | IXANY0x00000800
745#endif
746 | IXOFF0x00000400);
747
748 mode.c_iflag |= (BRKINT0x00000002 | IGNPAR0x00000004 | ICRNL0x00000100 | IXON0x00000200
749#ifdef IMAXBEL0x00002000
750 | IMAXBEL0x00002000
751#endif
752 );
753
754 mode.c_oflag &= ~(0
755#ifdef OLCUC0x00000020
756 | OLCUC0x00000020
757#endif
758#ifdef OCRNL0x00000010
759 | OCRNL0x00000010
760#endif
761#ifdef ONOCR0x00000040
762 | ONOCR0x00000040
763#endif
764#ifdef ONLRET0x00000080
765 | ONLRET0x00000080
766#endif
767#ifdef OFILL
768 | OFILL
769#endif
770#ifdef OFDEL
771 | OFDEL
772#endif
773#ifdef NLDLY
774 | NLDLY
775#endif
776#ifdef CRDLY
777 | CRDLY
778#endif
779#ifdef TABDLY
780 | TABDLY
781#endif
782#ifdef BSDLY
783 | BSDLY
784#endif
785#ifdef VTDLY
786 | VTDLY
787#endif
788#ifdef FFDLY
789 | FFDLY
790#endif
791 );
792
793 mode.c_oflag |= (OPOST0x00000001
794#ifdef ONLCR0x00000002
795 | ONLCR0x00000002
796#endif
797 );
798
799 mode.c_cflag &= ~(CSIZE0x00000300 | CSTOPB0x00000400 | PARENB0x00001000 | PARODD0x00002000 | CLOCAL0x00008000);
800 mode.c_cflag |= (CS80x00000300 | CREAD0x00000800);
801 mode.c_lflag &= ~(ECHONL0x00000010 | NOFLSH0x80000000
802#ifdef TOSTOP0x00400000
803 | TOSTOP0x00400000
804#endif
805#ifdef ECHOPTR
806 | ECHOPRT0x00000020
807#endif
808#ifdef XCASE0x01000000
809 | XCASE0x01000000
810#endif
811 );
812
813 mode.c_lflag |= (ISIG0x00000080 | ICANON0x00000100 | ECHO0x00000008 | ECHOE0x00000002 | ECHOK0x00000004
814#ifdef ECHOCTL0x00000040
815 | ECHOCTL0x00000040
816#endif
817#ifdef ECHOKE0x00000001
818 | ECHOKE0x00000001
819#endif
820 );
821#endif
822
823 tcsetattr(STDERR_FILENO2, TCSADRAIN1, &mode);
824}
825
826/*
827 * Returns a "good" value for the erase character. This is loosely based on
828 * the BSD4.4 logic.
829 */
830#ifdef TERMIOS1
831static int
832default_erase(void)
833{
834 int result;
835
836 if (over_strikecur_term->type. Booleans[15]
837 && key_backspacecur_term->type. Strings[55] != 0
838 && strlen(key_backspacecur_term->type. Strings[55]) == 1)
839 result = key_backspacecur_term->type. Strings[55][0];
840 else
841 result = CERASE0177;
842
843 return result;
844}
845#endif
846
847/*
848 * Update the values of the erase, interrupt, and kill characters in 'mode'.
849 *
850 * SVr4 tset (e.g., Solaris 2.5) only modifies the intr, quit or erase
851 * characters if they're unset, or if we specify them as options. This differs
852 * from BSD 4.4 tset, which always sets erase.
853 */
854static void
855set_control_chars(void)
856{
857#ifdef TERMIOS1
858 if (DISABLED(mode.c_cc[VERASE])((((0377) != -1) && ((mode.c_cc[3]) == (0377))) || ((
mode.c_cc[3]) <= 0))
|| terasechar >= 0)
859 mode.c_cc[VERASE3] = (terasechar >= 0) ? terasechar : default_erase();
860
861 if (DISABLED(mode.c_cc[VINTR])((((0377) != -1) && ((mode.c_cc[8]) == (0377))) || ((
mode.c_cc[8]) <= 0))
|| intrchar >= 0)
862 mode.c_cc[VINTR8] = (intrchar >= 0) ? intrchar : CINTR(('c') & 0x1f);
863
864 if (DISABLED(mode.c_cc[VKILL])((((0377) != -1) && ((mode.c_cc[5]) == (0377))) || ((
mode.c_cc[5]) <= 0))
|| tkillchar >= 0)
865 mode.c_cc[VKILL5] = (tkillchar >= 0) ? tkillchar : CKILL(('u') & 0x1f);
866#endif
867}
868
869/*
870 * Set up various conversions in 'mode', including parity, tabs, returns,
871 * echo, and case, according to the termcap entry. If the program we're
872 * running was named with a leading upper-case character, map external
873 * uppercase to internal lowercase.
874 */
875static void
876set_conversions(void)
877{
878#ifdef __OBSOLETE__
879 /*
880 * Conversion logic for some *really* ancient terminal glitches,
881 * not supported in terminfo. Left here for succeeding generations
882 * to marvel at.
883 */
884 if (tgetflag("UC")) {
885#ifdef IUCLC0x00001000
886 mode.c_iflag |= IUCLC0x00001000;
887 mode.c_oflag |= OLCUC0x00000020;
888#endif
889 } else if (tgetflag("LC")) {
890#ifdef IUCLC0x00001000
891 mode.c_iflag &= ~IUCLC0x00001000;
892 mode.c_oflag &= ~OLCUC0x00000020;
893#endif
894 }
895 mode.c_iflag &= ~(PARMRK0x00000008 | INPCK0x00000010);
896 mode.c_lflag |= ICANON0x00000100;
897 if (tgetflag("EP")) {
898 mode.c_cflag |= PARENB0x00001000;
899 mode.c_cflag &= ~PARODD0x00002000;
900 }
901 if (tgetflag("OP")) {
902 mode.c_cflag |= PARENB0x00001000;
903 mode.c_cflag |= PARODD0x00002000;
904 }
905#endif /* __OBSOLETE__ */
906
907#ifdef TERMIOS1
908#ifdef ONLCR0x00000002
909 mode.c_oflag |= ONLCR0x00000002;
910#endif
911 mode.c_iflag |= ICRNL0x00000100;
912 mode.c_lflag |= ECHO0x00000008;
913#ifdef OXTABS0x00000004
914 mode.c_oflag |= OXTABS0x00000004;
915#endif /* OXTABS */
916
917 /* test used to be tgetflag("NL") */
918 if (newlinecur_term->type. Strings[103] != (char *) 0 && newlinecur_term->type. Strings[103][0] == '\n' && !newlinecur_term->type. Strings[103][1]) {
919 /* Newline, not linefeed. */
920#ifdef ONLCR0x00000002
921 mode.c_oflag &= ~ONLCR0x00000002;
922#endif
923 mode.c_iflag &= ~ICRNL0x00000100;
924 }
925#ifdef __OBSOLETE__
926 if (tgetflag("HD")) /* Half duplex. */
927 mode.c_lflag &= ~ECHO0x00000008;
928#endif /* __OBSOLETE__ */
929#ifdef OXTABS0x00000004
930 /* test used to be tgetflag("pt") */
931 if (VALID_STRING(set_tab)((cur_term->type. Strings[132]) != (char *)(-1) &&
(cur_term->type. Strings[132]) != (char *)0)
&& VALID_STRING(clear_all_tabs)((cur_term->type. Strings[4]) != (char *)(-1) && (
cur_term->type. Strings[4]) != (char *)0)
)
932 mode.c_oflag &= ~OXTABS0x00000004;
933#endif /* OXTABS */
934 mode.c_lflag |= (ECHOE0x00000002 | ECHOK0x00000004);
935#endif
936}
937
938/* Output startup string. */
939static void
940set_init(void)
941{
942 char *p;
943 bool_Bool settle;
944
945#ifdef __OBSOLETE__
946 if (pad_charcur_term->type. Strings[104] != (char *) 0) /* Get/set pad character. */
947 PC = pad_charcur_term->type. Strings[104][0];
948#endif /* OBSOLETE */
949
950#ifdef TAB3
951 if (oldmode.c_oflag & (TAB3 | ONLCR0x00000002 | OCRNL0x00000010 | ONLRET0x00000080)) {
952 oldmode.c_oflag &= (TAB3 | ONLCR0x00000002 | OCRNL0x00000010 | ONLRET0x00000080);
953 tcsetattr(STDERR_FILENO2, TCSADRAIN1, &oldmode);
954 }
955#endif
956 settle = set_tabs();
957
958 if (isreset) {
959 if ((p = reset_1stringcur_term->type. Strings[122]) != 0) {
960 tputs(p, 0, outc);
961 settle = TRUE1;
962 }
963 if ((p = reset_2stringcur_term->type. Strings[123]) != 0) {
964 tputs(p, 0, outc);
965 settle = TRUE1;
966 }
967 /* What about rf, rs3, as per terminfo man page? */
968 /* also might be nice to send rmacs, rmul, rmm */
969 if ((p = reset_filecur_term->type. Strings[125]) != 0
970 || (p = init_filecur_term->type. Strings[51]) != 0) {
971 cat(p);
972 settle = TRUE1;
973 }
974 }
975
976 if (settle) {
977 (void) putc('\r', stderr)(!__isthreaded ? __sputc('\r', (&__sF[2])) : (putc)('\r',
(&__sF[2])))
;
978 (void) fflush(stderr(&__sF[2]));
979 (void) napms(1000); /* Settle the terminal. */
980 }
981}
982
983/*
984 * Set the hardware tabs on the terminal, using the ct (clear all tabs),
985 * st (set one tab) and ch (horizontal cursor addressing) capabilities.
986 * This is done before if and is, so they can patch in case we blow this.
987 * Return TRUE if we set any tab stops, FALSE if not.
988 */
989static bool_Bool
990set_tabs(void)
991{
992 if (set_tabcur_term->type. Strings[132] && clear_all_tabscur_term->type. Strings[4]) {
993 int c;
994
995 (void) putc('\r', stderr)(!__isthreaded ? __sputc('\r', (&__sF[2])) : (putc)('\r',
(&__sF[2])))
; /* Force to left margin. */
996 tputs(clear_all_tabscur_term->type. Strings[4], 0, outc);
997
998 for (c = 8; c < tcolumns; c += 8) {
999 /* Get to the right column. In BSD tset, this
1000 * used to try a bunch of half-clever things
1001 * with cup and hpa, for an average saving of
1002 * somewhat less than two character times per
1003 * tab stop, less than .01 sec at 2400cps. We
1004 * lost all this cruft because it seemed to be
1005 * introducing some odd bugs.
1006 * -----------12345678----------- */
1007 (void) fputs(" ", stderr(&__sF[2]));
1008 tputs(set_tabcur_term->type. Strings[132], 0, outc);
1009 }
1010 putc('\r', stderr)(!__isthreaded ? __sputc('\r', (&__sF[2])) : (putc)('\r',
(&__sF[2])))
;
1011 return (TRUE1);
1012 }
1013 return (FALSE0);
1014}
1015
1016/**************************************************************************
1017 *
1018 * Main sequence
1019 *
1020 **************************************************************************/
1021
1022/*
1023 * Tell the user if a control key has been changed from the default value.
1024 */
1025#ifdef TERMIOS1
1026static void
1027report(const char *name, int which, unsigned def)
1028{
1029 unsigned older, newer;
1030 char *p;
1031
1032 newer = mode.c_cc[which];
1033 older = oldmode.c_cc[which];
1034
1035 if (older == newer && older == def)
1036 return;
1037
1038 (void) fprintf(stderr(&__sF[2]), "%s %s ", name, older == newer ? "is" : "set to");
1039
1040 if (DISABLED(newer)((((0377) != -1) && ((newer) == (0377))) || ((newer) <=
0))
)
1041 (void) fprintf(stderr(&__sF[2]), "undef.\n");
1042 /*
1043 * Check 'delete' before 'backspace', since the key_backspace value
1044 * is ambiguous.
1045 */
1046 else if (newer == 0177)
1047 (void) fprintf(stderr(&__sF[2]), "delete.\n");
1048 else if ((p = key_backspacecur_term->type. Strings[55]) != 0
1049 && newer == (unsigned char) p[0]
1050 && p[1] == '\0')
1051 (void) fprintf(stderr(&__sF[2]), "backspace.\n");
1052 else if (newer < 040) {
1053 newer ^= 0100;
1054 (void) fprintf(stderr(&__sF[2]), "control-%c (^%c).\n", UChar(newer)((unsigned char)(newer)), UChar(newer)((unsigned char)(newer)));
1055 } else
1056 (void) fprintf(stderr(&__sF[2]), "%c.\n", UChar(newer)((unsigned char)(newer)));
1057}
1058#endif
1059
1060/*
1061 * Convert the obsolete argument forms into something that getopt can handle.
1062 * This means that -e, -i and -k get default arguments supplied for them.
1063 */
1064static void
1065obsolete(char **argv)
1066{
1067 for (; *argv; ++argv) {
1068 char *parm = argv[0];
1069
1070 if (parm[0] == '-' && parm[1] == '\0') {
1071 argv[0] = strdup("-q");
1072 continue;
1073 }
1074
1075 if ((parm[0] != '-')
1076 || (argv[1] && argv[1][0] != '-')
1077 || (parm[1] != 'e' && parm[1] != 'i' && parm[1] != 'k')
1078 || (parm[2] != '\0'))
1079 continue;
1080 switch (argv[0][1]) {
1081 case 'e':
1082 argv[0] = strdup("-e^H");
1083 break;
1084 case 'i':
1085 argv[0] = strdup("-i^C");
1086 break;
1087 case 'k':
1088 argv[0] = strdup("-k^U");
1089 break;
1090 }
1091 }
1092}
1093
1094static void
1095usage(void)
1096{
1097 (void) fprintf(stderr(&__sF[2]), "usage: %s [-cIQqrsVw] [-] "
1098 "[-e ch] [-i ch] [-k ch] [-m mapping] [terminal]",
1099 _nc_progname);
1100
1101 exit_error();
1102 /* NOTREACHED */
1103}
1104
1105static char
1106arg_to_char(void)
1107{
1108 return (char) ((optarg[0] == '^' && optarg[1] != '\0')
1109 ? ((optarg[1] == '?') ? '\177' : CTRL(optarg[1])((optarg[1]) & 0x1f))
1110 : optarg[0]);
1111}
1112
1113int
1114main(int argc, char **argv)
1115{
1116 int ch, noinit, noset, quiet, Sflag, sflag, showterm;
1117 const char *p;
1118 const char *ttype;
1119
1120 _nc_progname = _nc_rootname(*argv);
1121
1122 if (pledge("stdio rpath wpath tty", NULL((void *)0)) == -1)
1123 err("pledge: %s", strerror(errno(*__errno())));
1124
1125 obsolete(argv);
1126 noinit = noset = quiet = Sflag = sflag = showterm = 0;
1127 while ((ch = getopt(argc, argv, "a:cd:e:Ii:k:m:np:qQSrsVw")) != -1) {
1128 switch (ch) {
1129 case 'c': /* set control-chars */
1130 opt_c = TRUE1;
1131 break;
1132 case 'a': /* OBSOLETE: map identifier to type */
1133 add_mapping("arpanet", optarg);
1134 break;
1135 case 'd': /* OBSOLETE: map identifier to type */
1136 add_mapping("dialup", optarg);
1137 break;
1138 case 'e': /* erase character */
1139 terasechar = arg_to_char();
1140 break;
1141 case 'I': /* no initialization strings */
1142 noinit = 1;
1143 break;
1144 case 'i': /* interrupt character */
1145 intrchar = arg_to_char();
1146 break;
1147 case 'k': /* kill character */
1148 tkillchar = arg_to_char();
1149 break;
1150 case 'm': /* map identifier to type */
1151 add_mapping(0, optarg);
1152 break;
1153 case 'n': /* OBSOLETE: set new tty driver */
1154 break;
1155 case 'p': /* OBSOLETE: map identifier to type */
1156 add_mapping("plugboard", optarg);
1157 break;
1158 case 'Q': /* don't output control key settings */
1159 quiet = 1;
1160 break;
1161 case 'q': /* display term only */
1162 noset = 1;
1163 break;
1164 case 'r': /* display term on stderr */
1165 showterm = 1;
1166 break;
1167 case 'S': /* OBSOLETE: output TERM & TERMCAP */
1168 Sflag = 1;
1169 break;
1170 case 's': /* output TERM set command */
1171 sflag = 1;
1172 break;
1173 case 'V': /* print curses-version */
1174 puts(curses_version());
1175 ExitProgram(EXIT_SUCCESS)exit(0);
1176 case 'w': /* set window-size */
1177 opt_w = TRUE1;
1178 break;
1179 case '?':
1180 default:
1181 usage();
1182 }
1183 }
1184 argc -= optind;
1185 argv += optind;
1186
1187 if (argc > 1)
1188 usage();
1189
1190 if (!opt_c && !opt_w)
1191 opt_c = opt_w = TRUE1;
1192
1193 if (tcgetattr(STDERR_FILENO2, &mode) < 0)
1194 failed("standard error");
1195 can_restore = TRUE1;
1196 original = oldmode = mode;
1197#ifdef TERMIOS1
1198 ospeed = (NCURSES_OSPEEDint) cfgetospeed(&mode);
1199#else
1200 ospeed = (NCURSES_OSPEEDint) mode.sg_ospeed;
1201#endif
1202
1203 if (!strcmp(_nc_progname, PROG_RESET"reset")) {
1204 isreset = TRUE1;
1205 reset_mode();
1206 }
1207
1208 ttype = get_termcap_entry(*argv);
Value stored to 'ttype' is never read
1209
1210 if (!noset) {
1211 tcolumns = columnscur_term->type. Numbers[0];
1212 tlines = linescur_term->type. Numbers[2];
1213
1214#if HAVE_SIZECHANGE1
1215 if (opt_w) {
1216 struct winsize win;
1217 /* Set window size if not set already */
1218 if (ioctl(STDERR_FILENO2, TIOCGWINSZ((unsigned long)0x40000000 | ((sizeof(struct winsize) & 0x1fff
) << 16) | ((('t')) << 8) | ((104)))
, &win) == 0) {
1219 if (win.ws_row == 0 &&
1220 win.ws_col == 0 &&
1221 tlines > 0 && tcolumns > 0) {
1222 win.ws_row = tlines;
1223 win.ws_col = tcolumns;
1224 (void) ioctl(STDERR_FILENO2, TIOCSWINSZ((unsigned long)0x80000000 | ((sizeof(struct winsize) & 0x1fff
) << 16) | ((('t')) << 8) | ((103)))
, &win);
1225 }
1226 }
1227 }
1228#endif
1229 if (opt_c) {
1230 set_control_chars();
1231 set_conversions();
1232
1233 if (!noinit)
1234 set_init();
1235
1236 /* Set the modes if they've changed. */
1237 if (memcmp(&mode, &oldmode, sizeof(mode))) {
1238 tcsetattr(STDERR_FILENO2, TCSADRAIN1, &mode);
1239 }
1240 }
1241 }
1242
1243 /* Get the terminal name from the entry. */
1244 ttype = _nc_first_name(cur_term->type.term_names);
1245
1246 if (noset)
1247 (void) printf("%s\n", ttype);
1248 else {
1249 if (showterm)
1250 (void) fprintf(stderr(&__sF[2]), "Terminal type is %s.\n", ttype);
1251 /*
1252 * If erase, kill and interrupt characters could have been
1253 * modified and not -Q, display the changes.
1254 */
1255#ifdef TERMIOS1
1256 if (!quiet) {
1257 report("Erase", VERASE3, CERASE0177);
1258 report("Kill", VKILL5, CKILL(('u') & 0x1f));
1259 report("Interrupt", VINTR8, CINTR(('c') & 0x1f));
1260 }
1261#endif
1262 }
1263
1264 if (Sflag)
1265 err("The -S option is not supported under terminfo.");
1266
1267 if (sflag) {
1268 int len;
1269 char *var;
1270 char *leaf;
1271 /*
1272 * Figure out what shell we're using. A hack, we look for an
1273 * environmental variable SHELL ending in "csh".
1274 */
1275 if ((var = getenv("SHELL")) != 0
1276 && ((len = (int) strlen(leaf = _nc_basename(var))) >= 3)
1277 && !strcmp(leaf + len - 3, "csh"))
1278 p = "set noglob;\nsetenv TERM %s;\nunset noglob;\n";
1279 else
1280 p = "TERM=%s;\n";
1281 (void) printf(p, ttype);
1282 }
1283
1284 ExitProgram(EXIT_SUCCESS)exit(0);
1285}