tty_subs.c revision 36049
11556Srgrimes/*-
21556Srgrimes * Copyright (c) 1992 Keith Muller.
31556Srgrimes * Copyright (c) 1992, 1993
41556Srgrimes *	The Regents of the University of California.  All rights reserved.
51556Srgrimes *
61556Srgrimes * This code is derived from software contributed to Berkeley by
71556Srgrimes * Keith Muller of the University of California, San Diego.
81556Srgrimes *
91556Srgrimes * Redistribution and use in source and binary forms, with or without
101556Srgrimes * modification, are permitted provided that the following conditions
111556Srgrimes * are met:
121556Srgrimes * 1. Redistributions of source code must retain the above copyright
131556Srgrimes *    notice, this list of conditions and the following disclaimer.
141556Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
151556Srgrimes *    notice, this list of conditions and the following disclaimer in the
161556Srgrimes *    documentation and/or other materials provided with the distribution.
171556Srgrimes * 3. All advertising materials mentioning features or use of this software
181556Srgrimes *    must display the following acknowledgement:
191556Srgrimes *	This product includes software developed by the University of
201556Srgrimes *	California, Berkeley and its contributors.
211556Srgrimes * 4. Neither the name of the University nor the names of its contributors
221556Srgrimes *    may be used to endorse or promote products derived from this software
231556Srgrimes *    without specific prior written permission.
241556Srgrimes *
251556Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
261556Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
271556Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
281556Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
291556Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
301556Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
311556Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
321556Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
331556Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
341556Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
351556Srgrimes * SUCH DAMAGE.
361556Srgrimes */
371556Srgrimes
381556Srgrimes#ifndef lint
3936049Scharnier#if 0
4036049Scharnierstatic char sccsid[] = "@(#)tty_subs.c	8.2 (Berkeley) 4/18/94";
4136049Scharnier#endif
4236049Scharnierstatic const char rcsid[] =
4336049Scharnier	"$Id$";
441556Srgrimes#endif /* not lint */
451556Srgrimes
461556Srgrimes#include <sys/types.h>
471556Srgrimes#include <sys/stat.h>
481556Srgrimes#include <fcntl.h>
491556Srgrimes#include <stdio.h>
501556Srgrimes#include <unistd.h>
511556Srgrimes#include <stdlib.h>
521556Srgrimes#include <string.h>
531556Srgrimes#include "pax.h"
541556Srgrimes#include "extern.h"
551556Srgrimes#if __STDC__
561556Srgrimes#include <stdarg.h>
571556Srgrimes#else
581556Srgrimes#include <varargs.h>
591556Srgrimes#endif
601556Srgrimes
611556Srgrimes/*
621556Srgrimes * routines that deal with I/O to and from the user
631556Srgrimes */
641556Srgrimes
651556Srgrimes#define DEVTTY          "/dev/tty"      /* device for interactive i/o */
661556Srgrimesstatic FILE *ttyoutf = NULL;		/* output pointing at control tty */
671556Srgrimesstatic FILE *ttyinf = NULL;		/* input pointing at control tty */
681556Srgrimes
691556Srgrimes/*
701556Srgrimes * tty_init()
711556Srgrimes *	try to open the controlling termina (if any) for this process. if the
721556Srgrimes *	open fails, future ops that require user input will get an EOF
731556Srgrimes */
741556Srgrimes
751556Srgrimes#if __STDC__
761556Srgrimesint
771556Srgrimestty_init(void)
781556Srgrimes#else
791556Srgrimesint
801556Srgrimestty_init()
811556Srgrimes#endif
821556Srgrimes{
831556Srgrimes	int ttyfd;
841556Srgrimes
851556Srgrimes        if ((ttyfd = open(DEVTTY, O_RDWR)) >= 0) {
861556Srgrimes		if ((ttyoutf = fdopen(ttyfd, "w")) != NULL) {
871556Srgrimes			if ((ttyinf = fdopen(ttyfd, "r")) != NULL)
881556Srgrimes				return(0);
891556Srgrimes			(void)fclose(ttyoutf);
901556Srgrimes		}
911556Srgrimes		(void)close(ttyfd);
921556Srgrimes	}
931556Srgrimes
941556Srgrimes	if (iflag) {
9528904Ssos		pax_warn(1, "Fatal error, cannot open %s", DEVTTY);
961556Srgrimes		return(-1);
971556Srgrimes	}
981556Srgrimes	return(0);
991556Srgrimes}
1001556Srgrimes
1011556Srgrimes/*
1021556Srgrimes * tty_prnt()
1031556Srgrimes *	print a message using the specified format to the controlling tty
1041556Srgrimes *	if there is no controlling terminal, just return.
1051556Srgrimes */
1061556Srgrimes
1071556Srgrimes#if __STDC__
1081556Srgrimesvoid
1091556Srgrimestty_prnt(char *fmt, ...)
1101556Srgrimes#else
1111556Srgrimesvoid
1121556Srgrimestty_prnt(fmt, va_alist)
1131556Srgrimes	char *fmt;
1141556Srgrimes	va_dcl
1151556Srgrimes#endif
1161556Srgrimes{
1171556Srgrimes	va_list ap;
1181556Srgrimes#	if __STDC__
1191556Srgrimes	va_start(ap, fmt);
1201556Srgrimes#	else
1211556Srgrimes	va_start(ap);
1221556Srgrimes#	endif
1231556Srgrimes	if (ttyoutf == NULL)
1241556Srgrimes		return;
1251556Srgrimes	(void)vfprintf(ttyoutf, fmt, ap);
1261556Srgrimes	va_end(ap);
1271556Srgrimes	(void)fflush(ttyoutf);
1281556Srgrimes}
1291556Srgrimes
1301556Srgrimes/*
1311556Srgrimes * tty_read()
1321556Srgrimes *	read a string from the controlling terminal if it is open into the
1331556Srgrimes *	supplied buffer
1341556Srgrimes * Return:
1351556Srgrimes *	0 if data was read, -1 otherwise.
1361556Srgrimes */
1371556Srgrimes
1381556Srgrimes#if __STDC__
1391556Srgrimesint
1401556Srgrimestty_read(char *str, int len)
1411556Srgrimes#else
1421556Srgrimesint
1431556Srgrimestty_read(str, len)
1441556Srgrimes	char *str;
1451556Srgrimes	int len;
1461556Srgrimes#endif
1471556Srgrimes{
1481556Srgrimes	register char *pt;
1491556Srgrimes
1501556Srgrimes	if ((--len <= 0) || (ttyinf == NULL) || (fgets(str,len,ttyinf) == NULL))
1511556Srgrimes		return(-1);
1521556Srgrimes	*(str + len) = '\0';
1531556Srgrimes
1541556Srgrimes	/*
1551556Srgrimes	 * strip off that trailing newline
1561556Srgrimes	 */
1571556Srgrimes	if ((pt = strchr(str, '\n')) != NULL)
1581556Srgrimes		*pt = '\0';
1591556Srgrimes	return(0);
1601556Srgrimes}
1611556Srgrimes
1621556Srgrimes/*
16328904Ssos * pax_warn()
16428904Ssos *	write a pax_warning message to stderr. if "set" the exit value of pax
1651556Srgrimes *	will be non-zero.
1661556Srgrimes */
1671556Srgrimes
1681556Srgrimes#if __STDC__
1691556Srgrimesvoid
17028904Ssospax_warn(int set, char *fmt, ...)
1711556Srgrimes#else
1721556Srgrimesvoid
17328904Ssospax_warn(set, fmt, va_alist)
1741556Srgrimes	int set;
1751556Srgrimes	char *fmt;
1761556Srgrimes	va_dcl
1771556Srgrimes#endif
1781556Srgrimes{
1791556Srgrimes	va_list ap;
1801556Srgrimes#	if __STDC__
1811556Srgrimes	va_start(ap, fmt);
1821556Srgrimes#	else
1831556Srgrimes	va_start(ap);
1841556Srgrimes#	endif
1851556Srgrimes	if (set)
1861556Srgrimes		exit_val = 1;
1871556Srgrimes	/*
1881556Srgrimes	 * when vflag we better ship out an extra \n to get this message on a
1891556Srgrimes	 * line by itself
1901556Srgrimes	 */
1911556Srgrimes	if (vflag && vfpart) {
1921556Srgrimes		(void)fputc('\n', stderr);
1931556Srgrimes		vfpart = 0;
1941556Srgrimes	}
1951556Srgrimes	(void)fprintf(stderr, "%s: ", argv0);
1961556Srgrimes	(void)vfprintf(stderr, fmt, ap);
1971556Srgrimes	va_end(ap);
1981556Srgrimes	(void)fputc('\n', stderr);
1991556Srgrimes}
2001556Srgrimes
2011556Srgrimes/*
20228904Ssos * sys_warn()
20328904Ssos *	write a pax_warning message to stderr. if "set" the exit value of pax
2041556Srgrimes *	will be non-zero.
2051556Srgrimes */
2061556Srgrimes
2071556Srgrimes#if __STDC__
2081556Srgrimesvoid
20928904Ssossys_warn(int set, int errnum, char *fmt, ...)
2101556Srgrimes#else
2111556Srgrimesvoid
21228904Ssossys_warn(set, errnum, fmt, va_alist)
2131556Srgrimes	int set;
2141556Srgrimes	int errnum;
2151556Srgrimes	char *fmt;
2161556Srgrimes	va_dcl
2171556Srgrimes#endif
2181556Srgrimes{
2191556Srgrimes	va_list ap;
2201556Srgrimes#	if __STDC__
2211556Srgrimes	va_start(ap, fmt);
2221556Srgrimes#	else
2231556Srgrimes	va_start(ap);
2241556Srgrimes#	endif
2251556Srgrimes	if (set)
2261556Srgrimes		exit_val = 1;
2271556Srgrimes	/*
2281556Srgrimes	 * when vflag we better ship out an extra \n to get this message on a
2291556Srgrimes	 * line by itself
2301556Srgrimes	 */
2311556Srgrimes	if (vflag && vfpart) {
2321556Srgrimes		(void)fputc('\n', stderr);
2331556Srgrimes		vfpart = 0;
2341556Srgrimes	}
2351556Srgrimes	(void)fprintf(stderr, "%s: ", argv0);
2361556Srgrimes	(void)vfprintf(stderr, fmt, ap);
2371556Srgrimes	va_end(ap);
2381556Srgrimes
2391556Srgrimes	/*
2401556Srgrimes	 * format and print the errno
2411556Srgrimes	 */
2421556Srgrimes	if (errnum > 0)
2431556Srgrimes		(void)fprintf(stderr, " <%s>", sys_errlist[errnum]);
2441556Srgrimes	(void)fputc('\n', stderr);
2451556Srgrimes}
246