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 * 4. Neither the name of the University nor the names of its contributors
181556Srgrimes *    may be used to endorse or promote products derived from this software
191556Srgrimes *    without specific prior written permission.
201556Srgrimes *
211556Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221556Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231556Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241556Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251556Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261556Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271556Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281556Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291556Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301556Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311556Srgrimes * SUCH DAMAGE.
321556Srgrimes */
331556Srgrimes
341556Srgrimes#ifndef lint
3536049Scharnier#if 0
3636049Scharnierstatic char sccsid[] = "@(#)tty_subs.c	8.2 (Berkeley) 4/18/94";
3736049Scharnier#endif
381556Srgrimes#endif /* not lint */
3999110Sobrien#include <sys/cdefs.h>
4099110Sobrien__FBSDID("$FreeBSD$");
411556Srgrimes
421556Srgrimes#include <sys/types.h>
431556Srgrimes#include <sys/stat.h>
441556Srgrimes#include <fcntl.h>
451556Srgrimes#include <stdio.h>
461556Srgrimes#include <unistd.h>
471556Srgrimes#include <stdlib.h>
481556Srgrimes#include <string.h>
491556Srgrimes#include "pax.h"
501556Srgrimes#include "extern.h"
511556Srgrimes#include <stdarg.h>
521556Srgrimes
531556Srgrimes/*
541556Srgrimes * routines that deal with I/O to and from the user
551556Srgrimes */
561556Srgrimes
5776019Skris#define DEVTTY	  "/dev/tty"      /* device for interactive i/o */
581556Srgrimesstatic FILE *ttyoutf = NULL;		/* output pointing at control tty */
591556Srgrimesstatic FILE *ttyinf = NULL;		/* input pointing at control tty */
601556Srgrimes
611556Srgrimes/*
621556Srgrimes * tty_init()
6346684Skris *	try to open the controlling terminal (if any) for this process. if the
641556Srgrimes *	open fails, future ops that require user input will get an EOF
651556Srgrimes */
661556Srgrimes
671556Srgrimesint
681556Srgrimestty_init(void)
691556Srgrimes{
701556Srgrimes	int ttyfd;
711556Srgrimes
7276019Skris	if ((ttyfd = open(DEVTTY, O_RDWR)) >= 0) {
731556Srgrimes		if ((ttyoutf = fdopen(ttyfd, "w")) != NULL) {
741556Srgrimes			if ((ttyinf = fdopen(ttyfd, "r")) != NULL)
751556Srgrimes				return(0);
761556Srgrimes			(void)fclose(ttyoutf);
771556Srgrimes		}
781556Srgrimes		(void)close(ttyfd);
791556Srgrimes	}
801556Srgrimes
811556Srgrimes	if (iflag) {
8276017Skris		paxwarn(1, "Fatal error, cannot open %s", DEVTTY);
831556Srgrimes		return(-1);
841556Srgrimes	}
851556Srgrimes	return(0);
861556Srgrimes}
871556Srgrimes
881556Srgrimes/*
891556Srgrimes * tty_prnt()
901556Srgrimes *	print a message using the specified format to the controlling tty
911556Srgrimes *	if there is no controlling terminal, just return.
921556Srgrimes */
931556Srgrimes
941556Srgrimesvoid
9575577Skristty_prnt(const char *fmt, ...)
961556Srgrimes{
971556Srgrimes	va_list ap;
981556Srgrimes	if (ttyoutf == NULL)
991556Srgrimes		return;
100104560Stjr	va_start(ap, fmt);
1011556Srgrimes	(void)vfprintf(ttyoutf, fmt, ap);
1021556Srgrimes	va_end(ap);
1031556Srgrimes	(void)fflush(ttyoutf);
1041556Srgrimes}
1051556Srgrimes
1061556Srgrimes/*
1071556Srgrimes * tty_read()
1081556Srgrimes *	read a string from the controlling terminal if it is open into the
1091556Srgrimes *	supplied buffer
1101556Srgrimes * Return:
1111556Srgrimes *	0 if data was read, -1 otherwise.
1121556Srgrimes */
1131556Srgrimes
1141556Srgrimesint
1151556Srgrimestty_read(char *str, int len)
1161556Srgrimes{
11790113Simp	char *pt;
1181556Srgrimes
1191556Srgrimes	if ((--len <= 0) || (ttyinf == NULL) || (fgets(str,len,ttyinf) == NULL))
1201556Srgrimes		return(-1);
1211556Srgrimes	*(str + len) = '\0';
1221556Srgrimes
1231556Srgrimes	/*
1241556Srgrimes	 * strip off that trailing newline
1251556Srgrimes	 */
1261556Srgrimes	if ((pt = strchr(str, '\n')) != NULL)
1271556Srgrimes		*pt = '\0';
1281556Srgrimes	return(0);
1291556Srgrimes}
1301556Srgrimes
1311556Srgrimes/*
13276017Skris * paxwarn()
13376017Skris *	write a warning message to stderr. if "set" the exit value of pax
1341556Srgrimes *	will be non-zero.
1351556Srgrimes */
1361556Srgrimes
1371556Srgrimesvoid
13876017Skrispaxwarn(int set, const char *fmt, ...)
1391556Srgrimes{
1401556Srgrimes	va_list ap;
1411556Srgrimes	va_start(ap, fmt);
1421556Srgrimes	if (set)
1431556Srgrimes		exit_val = 1;
1441556Srgrimes	/*
1451556Srgrimes	 * when vflag we better ship out an extra \n to get this message on a
1461556Srgrimes	 * line by itself
1471556Srgrimes	 */
1481556Srgrimes	if (vflag && vfpart) {
14976351Skris		(void)fflush(listf);
1501556Srgrimes		(void)fputc('\n', stderr);
1511556Srgrimes		vfpart = 0;
1521556Srgrimes	}
1531556Srgrimes	(void)fprintf(stderr, "%s: ", argv0);
1541556Srgrimes	(void)vfprintf(stderr, fmt, ap);
1551556Srgrimes	va_end(ap);
1561556Srgrimes	(void)fputc('\n', stderr);
1571556Srgrimes}
1581556Srgrimes
1591556Srgrimes/*
16076017Skris * syswarn()
16176017Skris *	write a warning message to stderr. if "set" the exit value of pax
1621556Srgrimes *	will be non-zero.
1631556Srgrimes */
1641556Srgrimes
1651556Srgrimesvoid
16676017Skrissyswarn(int set, int errnum, const char *fmt, ...)
1671556Srgrimes{
1681556Srgrimes	va_list ap;
1691556Srgrimes	va_start(ap, fmt);
1701556Srgrimes	if (set)
1711556Srgrimes		exit_val = 1;
1721556Srgrimes	/*
1731556Srgrimes	 * when vflag we better ship out an extra \n to get this message on a
1741556Srgrimes	 * line by itself
1751556Srgrimes	 */
1761556Srgrimes	if (vflag && vfpart) {
17776351Skris		(void)fflush(listf);
1781556Srgrimes		(void)fputc('\n', stderr);
1791556Srgrimes		vfpart = 0;
1801556Srgrimes	}
1811556Srgrimes	(void)fprintf(stderr, "%s: ", argv0);
1821556Srgrimes	(void)vfprintf(stderr, fmt, ap);
1831556Srgrimes	va_end(ap);
1841556Srgrimes
1851556Srgrimes	/*
1861556Srgrimes	 * format and print the errno
1871556Srgrimes	 */
1881556Srgrimes	if (errnum > 0)
18976017Skris		(void)fprintf(stderr, " <%s>", strerror(errnum));
1901556Srgrimes	(void)fputc('\n', stderr);
1911556Srgrimes}
192