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