xref: /openbsd/bin/pax/tty_subs.c (revision 5dea098c)
1 /*	$OpenBSD: tty_subs.c,v 1.18 2023/06/26 16:58:50 millert Exp $	*/
2 /*	$NetBSD: tty_subs.c,v 1.5 1995/03/21 09:07:52 cgd Exp $	*/
3 
4 /*-
5  * Copyright (c) 1992 Keith Muller.
6  * Copyright (c) 1992, 1993
7  *	The Regents of the University of California.  All rights reserved.
8  *
9  * This code is derived from software contributed to Berkeley by
10  * Keith Muller of the University of California, San Diego.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36 
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <fcntl.h>
40 #include <stdarg.h>
41 #include <stdio.h>
42 #include <string.h>
43 #include <unistd.h>
44 
45 #include "pax.h"
46 #include "extern.h"
47 
48 /*
49  * routines that deal with I/O to and from the user
50  */
51 
52 #define DEVTTY		"/dev/tty"	/* device for interactive i/o */
53 static FILE *ttyoutf = NULL;		/* output pointing at control tty */
54 static FILE *ttyinf = NULL;		/* input pointing at control tty */
55 
56 /*
57  * tty_init()
58  *	try to open the controlling terminal (if any) for this process. if the
59  *	open fails, future ops that require user input will get an EOF
60  */
61 
62 int
63 tty_init(void)
64 {
65 	int ttyfd;
66 
67 	if ((ttyfd = open(DEVTTY, O_RDWR | O_CLOEXEC)) >= 0) {
68 		if ((ttyoutf = fdopen(ttyfd, "w")) != NULL) {
69 			if ((ttyinf = fdopen(ttyfd, "r")) != NULL)
70 				return(0);
71 			(void)fclose(ttyoutf);
72 		}
73 		(void)close(ttyfd);
74 	}
75 
76 	if (iflag) {
77 		paxwarn(1, "Fatal error, cannot open %s", DEVTTY);
78 		return(-1);
79 	}
80 	return(0);
81 }
82 
83 /*
84  * tty_prnt()
85  *	print a message using the specified format to the controlling tty
86  *	if there is no controlling terminal, just return.
87  */
88 
89 void
90 tty_prnt(const char *fmt, ...)
91 {
92 	va_list ap;
93 	char buf[8192];
94 
95 	if (ttyoutf == NULL)
96 		return;
97 	va_start(ap, fmt);
98 	(void)vsnprintf(buf, sizeof(buf), fmt, ap);
99 	va_end(ap);
100 	safe_print(buf, ttyoutf);
101 	(void)fflush(ttyoutf);
102 }
103 
104 /*
105  * tty_read()
106  *	read a string from the controlling terminal if it is open into the
107  *	supplied buffer
108  * Return:
109  *	0 if data was read, -1 otherwise.
110  */
111 
112 int
113 tty_read(char *str, int len)
114 {
115 	if (ttyinf == NULL || fgets(str, len, ttyinf) == NULL)
116 		return(-1);
117 
118 	/*
119 	 * strip off that trailing newline
120 	 */
121 	str[strcspn(str, "\n")] = '\0';
122 	return(0);
123 }
124 
125 /*
126  * paxwarn()
127  *	write a warning message to stderr. if "set" the exit value of pax
128  *	will be non-zero.
129  */
130 
131 void
132 paxwarn(int set, const char *fmt, ...)
133 {
134 	va_list ap;
135 	char buf[8192];
136 
137 	if (set)
138 		exit_val = 1;
139 	/*
140 	 * when vflag we better ship out an extra \n to get this message on a
141 	 * line by itself
142 	 */
143 	if (vflag && vfpart) {
144 		(void)fflush(listf);
145 		(void)fputc('\n', stderr);
146 		vfpart = 0;
147 	}
148 	(void)fprintf(stderr, "%s: ", argv0);
149 	va_start(ap, fmt);
150 	(void)vsnprintf(buf, sizeof(buf), fmt, ap);
151 	va_end(ap);
152 	safe_print(buf, stderr);
153 	(void)fputc('\n', stderr);
154 }
155 
156 /*
157  * syswarn()
158  *	write a warning message to stderr. if "set" the exit value of pax
159  *	will be non-zero.
160  */
161 
162 void
163 syswarn(int set, int errnum, const char *fmt, ...)
164 {
165 	va_list ap;
166 	char buf[8192];
167 
168 	if (set)
169 		exit_val = 1;
170 	/*
171 	 * when vflag we better ship out an extra \n to get this message on a
172 	 * line by itself
173 	 */
174 	if (vflag && vfpart) {
175 		(void)fflush(listf);
176 		(void)fputc('\n', stderr);
177 		vfpart = 0;
178 	}
179 	(void)fprintf(stderr, "%s: ", argv0);
180 	va_start(ap, fmt);
181 	(void)vsnprintf(buf, sizeof(buf), fmt, ap);
182 	va_end(ap);
183 	safe_print(buf, stderr);
184 
185 	/*
186 	 * format and print the errno
187 	 */
188 	if (errnum > 0)
189 		(void)fprintf(stderr, ": %s", strerror(errnum));
190 	(void)fputc('\n', stderr);
191 }
192