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