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 * @(#)tty_subs.c 8.2 (Berkeley) 4/18/94 38 * $FreeBSD: src/bin/pax/tty_subs.c,v 1.11.2.1 2001/08/01 05:03:12 obrien Exp $ 39 * $DragonFly: src/bin/pax/tty_subs.c,v 1.6 2004/11/07 20:54:51 eirikn Exp $ 40 */ 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 fclose(ttyoutf); 77 } 78 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 va_start(ap, fmt); 99 if (ttyoutf == NULL) 100 return; 101 vfprintf(ttyoutf, fmt, ap); 102 va_end(ap); 103 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 fflush(listf); 150 fputc('\n', stderr); 151 vfpart = 0; 152 } 153 fprintf(stderr, "%s: ", argv0); 154 vfprintf(stderr, fmt, ap); 155 va_end(ap); 156 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 fflush(listf); 178 fputc('\n', stderr); 179 vfpart = 0; 180 } 181 fprintf(stderr, "%s: ", argv0); 182 vfprintf(stderr, fmt, ap); 183 va_end(ap); 184 185 /* 186 * format and print the errno 187 */ 188 if (errnum > 0) 189 fprintf(stderr, " <%s>", strerror(errnum)); 190 fputc('\n', stderr); 191 } 192