1/* $OpenBSD: tty_subs.c,v 1.12 2003/06/02 23:32:09 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#ifndef lint 38#if 0 39static const char sccsid[] = "@(#)tty_subs.c 8.2 (Berkeley) 4/18/94"; 40#else 41static const char rcsid[] = "$OpenBSD: tty_subs.c,v 1.12 2003/06/02 23:32:09 millert 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 <errno.h> 52#include <unistd.h> 53#include <stdlib.h> 54#include <string.h> 55#include "pax.h" 56#include "extern.h" 57#include <stdarg.h> 58 59/* 60 * routines that deal with I/O to and from the user 61 */ 62 63#define DEVTTY "/dev/tty" /* device for interactive i/o */ 64static FILE *ttyoutf = NULL; /* output pointing at control tty */ 65static FILE *ttyinf = NULL; /* input pointing at control tty */ 66 67/* 68 * tty_init() 69 * try to open the controlling terminal (if any) for this process. if the 70 * open fails, future ops that require user input will get an EOF 71 */ 72 73int 74tty_init(void) 75{ 76 int ttyfd; 77 78 if ((ttyfd = open(DEVTTY, O_RDWR)) >= 0) { 79 if ((ttyoutf = fdopen(ttyfd, "w")) != NULL) { 80 if ((ttyinf = fdopen(ttyfd, "r")) != NULL) 81 return(0); 82 (void)fclose(ttyoutf); 83 } 84 (void)close(ttyfd); 85 } 86 87 if (iflag) { 88 paxwarn(1, "Fatal error, cannot open %s", DEVTTY); 89 return(-1); 90 } 91 return(0); 92} 93 94/* 95 * tty_prnt() 96 * print a message using the specified format to the controlling tty 97 * if there is no controlling terminal, just return. 98 */ 99 100void 101tty_prnt(const char *fmt, ...) 102{ 103 va_list ap; 104 if (ttyoutf == NULL) 105 return; 106 va_start(ap, fmt); 107 (void)vfprintf(ttyoutf, fmt, ap); 108 va_end(ap); 109 (void)fflush(ttyoutf); 110} 111 112/* 113 * tty_read() 114 * read a string from the controlling terminal if it is open into the 115 * supplied buffer 116 * Return: 117 * 0 if data was read, -1 otherwise. 118 */ 119 120int 121tty_read(char *str, int len) 122{ 123 char *pt; 124 125 if ((--len <= 0) || (ttyinf == NULL) || (fgets(str,len,ttyinf) == NULL)) 126 return(-1); 127 *(str + len) = '\0'; 128 129 /* 130 * strip off that trailing newline 131 */ 132 if ((pt = strchr(str, '\n')) != NULL) 133 *pt = '\0'; 134 return(0); 135} 136 137/* 138 * paxwarn() 139 * write a warning message to stderr. if "set" the exit value of pax 140 * will be non-zero. 141 */ 142 143void 144paxwarn(int set, const char *fmt, ...) 145{ 146 va_list ap; 147 148 va_start(ap, fmt); 149 if (set && (pax_invalid_action==0)) 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)fflush(listf); 157 (void)fputc('\n', stderr); 158 vfpart = 0; 159 } 160 (void)fprintf(stderr, "%s: ", argv0); 161 (void)vfprintf(stderr, fmt, ap); 162 va_end(ap); 163 (void)fputc('\n', stderr); 164} 165 166/* 167 * syswarn() 168 * write a warning message to stderr. if "set" the exit value of pax 169 * will be non-zero. 170 */ 171 172void 173syswarn(int set, int errnum, const char *fmt, ...) 174{ 175 va_list ap; 176 177 va_start(ap, fmt); 178 if (set) 179 exit_val = 1; 180 /* 181 * when vflag we better ship out an extra \n to get this message on a 182 * line by itself 183 */ 184 if (vflag && vfpart) { 185 (void)fflush(listf); 186 (void)fputc('\n', stderr); 187 vfpart = 0; 188 } 189 (void)fprintf(stderr, "%s: ", argv0); 190 (void)vfprintf(stderr, fmt, ap); 191 va_end(ap); 192 193 /* 194 * format and print the errno 195 */ 196 if (errnum > 0) 197 (void)fprintf(stderr, " <%s>", strerror(errnum)); 198 (void)fputc('\n', stderr); 199} 200