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