1 /* @(#)fifo_main.c	1.5 21/08/20 Copyright 1989, 2019-2021 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static	UConst char sccsid[] =
5 	"@(#)fifo_main.c	1.5 21/08/20 Copyright 1989, 2019-2021 J. Schilling";
6 #endif
7 /*
8  *	Copyright (c) 1989, 2019-2021 J. Schilling
9  *
10  */
11 /*
12  * The contents of this file are subject to the terms of the
13  * Common Development and Distribution License, Version 1.0 only
14  * (the "License").  You may not use this file except in compliance
15  * with the License.
16  *
17  * See the file CDDL.Schily.txt in this distribution for details.
18  * A copy of the CDDL is also available via the Internet at
19  * http://www.opensource.org/licenses/cddl1.txt
20  *
21  * When distributing Covered Code, include this CDDL HEADER in each
22  * file and include the License file CDDL.Schily.txt from this distribution.
23  */
24 
25 #include <schily/stdlib.h>
26 #include <schily/unistd.h>
27 #include <schily/limits.h>
28 #include <schily/stat.h>
29 #include <schily/signal.h>
30 #include <schily/wait.h>
31 #include <schily/errno.h>
32 #include <schily/nlsdefs.h>
33 #define	GT_COMERR		/* #define comerr gtcomerr */
34 #define	GT_ERROR		/* #define error gterror   */
35 #include <schily/schily.h>
36 #include <schily/nlsdefs.h>
37 #include "star.h"
38 #include "starsubs.h"
39 #include "fifo.h"
40 
41 #ifndef	PIPE_BUF
42 #define	PIPE_BUF	4096
43 #endif
44 
45 /* BEGIN CSTYLED */
46 char	options[] =
47 "help,version,debug,no-statistics,bs&,ibs&,obs&,fs&";
48 /* END CSTYLED */
49 
50 LOCAL	void	usage		__PR((int exitcode));
51 EXPORT	void	set_signal	__PR((int sig, RETSIGTYPE (*handler)(int)));
52 EXPORT	int	main		__PR((int ac, char **av));
53 LOCAL	int	getenum		__PR((char *arg, long *valp));
54 EXPORT	void	exprstats	__PR((int ret));
55 EXPORT	void	setprops	__PR((long htype));
56 EXPORT	void	changetape	__PR((BOOL donext));
57 EXPORT	void	closetape	__PR((void));
58 EXPORT	void	runnewvolscript	__PR((int volno, int nindex));
59 EXPORT	long	startvol	__PR((char *buf, long amount));
60 EXPORT	BOOL	verifyvol	__PR((char *buf, int amt, int volno,
61 								int *skipp));
62 LOCAL	BOOL	ispipe		__PR((int));
63 
64 BOOL	debug	  = FALSE;		/* -debug has been specified	*/
65 long	fs;				/* FIFO size			*/
66 long	bs;				/* TAPE block size (bytes)	*/
67 extern	long	ibs;
68 extern	long	obs;
69 int	tarfindex;			/* Current index in list	*/
70 BOOL	multivol = FALSE;		/* -multivol specified		*/
71 long	chdrtype  = H_UNDEF;		/* command line hdrtype		*/
72 BOOL	cflag	  = FALSE;		/* -c has been specified	*/
73 BOOL	copyflag  = FALSE;		/* -copy has been specified	*/
74 BOOL	lowmem	  = FALSE;		/* -lowmem use less memory	*/
75 BOOL	no_stats  = FALSE;		/* -no-statistics specified	*/
76 m_stats	*stats;
77 int	pid;
78 extern	m_head	*mp;
79 
80 GINFO	_ginfo;				/* Global (volhdr) information	*/
81 GINFO	_grinfo;			/* Global read information	*/
82 GINFO	*gip  = &_ginfo;		/* Global information pointer	*/
83 GINFO	*grip = &_grinfo;		/* Global read info pointer	*/
84 
85 long	bufsize	= 0;		/* Available buffer size */
86 char	*bigbuf	= NULL;
87 char	*bigptr	= NULL;
88 
89 LOCAL void
usage(exitcode)90 usage(exitcode)
91 	int	exitcode;
92 {
93 	error("Usage:	fifo [options]\n");
94 	error("Options:\n");
95 	error("	fs=#	set fifo size to #\n");
96 	error("	bs=#	set buffer size to #\n");
97 	error("	ibs=#	set input buffer size to #\n");
98 	error("	obs=#	set output buffer size to #\n");
99 	error("	-no-statistics	do not print fifo statistics\n");
100 	error("	-help	print this help\n");
101 	error("	-debug	print additional debug messages\n");
102 	error("	-version print version information and exit\n");
103 
104 	exit(exitcode);
105 }
106 
107 EXPORT void
set_signal(sig,handler)108 set_signal(sig, handler)
109 	int		sig;
110 	RETSIGTYPE	(*handler)	__PR((int));
111 {
112 #if	defined(HAVE_SIGPROCMASK) && defined(SA_RESTART)
113 	struct sigaction sa;
114 
115 	sigemptyset(&sa.sa_mask);
116 	sa.sa_handler = handler;
117 	sa.sa_flags = SA_RESTART;
118 	(void) sigaction(sig, &sa, (struct sigaction *)0);
119 #else
120 #ifdef	HAVE_SIGSETMASK
121 	struct sigvec	sv;
122 
123 	sv.sv_mask = 0;
124 	sv.sv_handler = handler;
125 	sv.sv_flags = 0;
126 	(void) sigvec(sig, &sv, (struct sigvec *)0);
127 #else
128 	(void) signal(sig, handler);
129 #endif
130 #endif
131 }
132 
133 
134 EXPORT int
main(ac,av)135 main(ac, av)
136 	int	ac;
137 	char	*av[];
138 {
139 	int	cac;
140 	char	*const *cav;
141 	BOOL	help = FALSE;
142 	BOOL	prvers = FALSE;
143 
144 	save_args(ac, av);
145 
146 	(void) setlocale(LC_ALL, "");
147 
148 #ifdef  USE_NLS
149 #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
150 #define	TEXT_DOMAIN "fifo"	/* Use this only if it weren't */
151 #endif
152 	{ char	*dir;
153 	dir = searchfileinpath("share/locale", F_OK,
154 					SIP_ANY_FILE|SIP_NO_PATH, NULL);
155 	if (dir)
156 		(void) bindtextdomain(TEXT_DOMAIN, dir);
157 	else
158 #if defined(PROTOTYPES) && defined(INS_BASE)
159 	(void) bindtextdomain(TEXT_DOMAIN, INS_BASE "/share/locale");
160 #else
161 	(void) bindtextdomain(TEXT_DOMAIN, "/usr/share/locale");
162 #endif
163 	(void) textdomain(TEXT_DOMAIN);
164 	}
165 #endif 	/* USE_NLS */
166 
167 	cac = --ac;
168 	cav = ++av;
169 
170 	if (getallargs(&cac, &cav, options, &help, &prvers,
171 			&debug, &no_stats,
172 			getenum, &bs,
173 			getenum, &ibs,
174 			getenum, &obs,
175 			getenum, &fs) < 0) {
176 		errmsgno(EX_BAD, "Bad flag: %s.\n", cav[0]);
177 		usage(EX_BAD);
178 	}
179 	cac = ac;
180 	cav = av;
181 	if (getfiles(&cac, &cav, options) > 0)
182 		comerrno(EX_BAD, "Too many args.\n");
183 
184 	if (help)
185 		usage(0);
186 	if (prvers) {
187 		/* BEGIN CSTYLED */
188 		gtprintf("fifo %s %s (%s-%s-%s)\n\n", "2.0", "2021/08/20", HOST_CPU, HOST_VENDOR, HOST_OS);
189 		gtprintf("Copyright (C) 1989, 2019-2021 %s\n", _("J�rg Schilling"));
190 		gtprintf("This is free software; see the source for copying conditions.  There is NO\n");
191 		gtprintf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
192 		/* END CSTYLED */
193 		exit(0);
194 	}
195 	if (bs == 0)
196 		bs = 512;
197 	if (ibs == 0) {
198 		if (ispipe(STDIN_FILENO))
199 			ibs = PIPE_BUF;
200 		else
201 			ibs = bs;
202 	}
203 	if (obs == 0) {
204 		if (ispipe(STDOUT_FILENO))
205 			obs = PIPE_BUF;
206 		else
207 			obs = bs;
208 	}
209 	initfifo();
210 	fifo_prmp(0);
211 	on_comerr((void(*)__PR((int, void *)))fifo_stats, (void *)0);
212 	runfifo(ac, av);
213 	if (pid != 0) {
214 		wait(0);
215 		fifo_stats();
216 	} else {
217 		exit(0);
218 	}
219 	exit(fifo_errno());
220 }
221 
222 LOCAL int
getenum(arg,valp)223 getenum(arg, valp)
224 	char	*arg;
225 	long	*valp;
226 {
227 	int ret = getnum(arg, valp);
228 
229 	if (ret != 1)
230 		errmsgno(EX_BAD, "Badly formed number '%s'.\n", arg);
231 	return (ret);
232 }
233 
234 EXPORT void
exprstats(ret)235 exprstats(ret)
236 	int	ret;
237 {
238 #if 0
239 	prstats();
240 	checkerrs();
241 	if (use_fifo)
242 		fifo_exit(ret);
243 #endif
244 	exit(ret);
245 }
246 
247 EXPORT void
setprops(htype)248 setprops(htype)
249 	long	htype;
250 {
251 }
252 
253 EXPORT void
changetape(donext)254 changetape(donext)
255 	BOOL	donext;
256 {
257 }
258 
259 EXPORT void
closetape()260 closetape()
261 {
262 }
263 
264 EXPORT void
runnewvolscript(volno,nindex)265 runnewvolscript(volno, nindex)
266 	int	volno;
267 	int	nindex;
268 {
269 }
270 
271 EXPORT long
startvol(buf,amount)272 startvol(buf, amount)
273 	char	*buf;		/* The original buffer address		*/
274 	long	amount;		/* The related requested transfer count	*/
275 {
276 	return (1);
277 }
278 
279 EXPORT BOOL
verifyvol(buf,amt,volno,skipp)280 verifyvol(buf, amt, volno, skipp)
281 	char	*buf;
282 	int	amt;
283 	int	volno;
284 	int	*skipp;
285 {
286 	return (TRUE);
287 }
288 
289 LOCAL BOOL
ispipe(f)290 ispipe(f)
291 	int	f;
292 {
293 	struct stat	sb;
294 
295 	if (fstat(f, &sb) < 0)
296 		return (FALSE);
297 
298 	if (S_ISFIFO(sb.st_mode))
299 		return (TRUE);
300 
301 	return (FALSE);
302 }
303 
304 EXPORT ssize_t
readtape(buf,amount)305 readtape(buf, amount)
306 	char	*buf;
307 	size_t	amount;
308 {
309 	register ssize_t	ret;
310 		int		oerrno = geterrno();
311 
312 	while ((ret = read(0, buf, amount)) < 0) {
313 		if (geterrno() == EINTR) {
314 			seterrno(oerrno);
315 			continue;
316 		}
317 	}
318 	return (ret);
319 }
320 
321 EXPORT ssize_t
writetape(buf,amount)322 writetape(buf, amount)
323 	char	*buf;
324 	size_t	amount;
325 {
326 	register ssize_t	ret;
327 		int		oerrno = geterrno();
328 
329 	while ((ret = write(1, buf, amount)) < 0) {
330 		if (geterrno() == EINTR) {
331 			seterrno(oerrno);
332 			continue;
333 		}
334 	}
335 	return (ret);
336 }
337