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