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