1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 1992 Christopher G. Demetriou
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote
16 *    products derived from this software without specific written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: stable/11/sbin/comcontrol/comcontrol.c 330449 2018-03-05 07:26:05Z eadler $");
33
34#include <ctype.h>
35#include <err.h>
36#include <errno.h>
37#include <fcntl.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41#include <unistd.h>
42#include <sys/types.h>
43#include <sys/ioctl.h>
44
45static void usage(void);
46
47static void
48usage(void)
49{
50	fprintf(stderr,
51	"usage: comcontrol <filename> [dtrwait <n>] [drainwait <n>]\n");
52	exit(1);
53}
54
55int
56main(int argc, char *argv[])
57{
58	int	fd;
59	int     res = 0;
60	int     print_dtrwait = 1, print_drainwait = 1;
61	int     dtrwait = -1, drainwait = -1;
62
63	if (argc < 2)
64		usage();
65
66	if (strcmp(argv[1], "-") == 0)
67		fd = STDIN_FILENO;
68	else {
69		fd = open(argv[1], O_RDONLY|O_NONBLOCK, 0);
70		if (fd < 0) {
71			warn("couldn't open file %s", argv[1]);
72			return 1;
73		}
74	}
75	if (argc == 2) {
76		if (ioctl(fd, TIOCMGDTRWAIT, &dtrwait) < 0) {
77			print_dtrwait = 0;
78			if (errno != ENOTTY) {
79				res = 1;
80				warn("TIOCMGDTRWAIT");
81			}
82		}
83		if (ioctl(fd, TIOCGDRAINWAIT, &drainwait) < 0) {
84			print_drainwait = 0;
85			if (errno != ENOTTY) {
86				res = 1;
87				warn("TIOCGDRAINWAIT");
88			}
89		}
90		if (print_dtrwait)
91			printf("dtrwait %d ", dtrwait);
92		if (print_drainwait)
93			printf("drainwait %d ", drainwait);
94		printf("\n");
95	} else {
96		while (argv[2] != NULL) {
97			if (!strcmp(argv[2],"dtrwait")) {
98				if (dtrwait >= 0)
99					usage();
100				if (argv[3] == NULL || !isdigit(argv[3][0]))
101					usage();
102				dtrwait = atoi(argv[3]);
103				argv += 2;
104			} else if (!strcmp(argv[2],"drainwait")) {
105				if (drainwait >= 0)
106					usage();
107				if (argv[3] == NULL || !isdigit(argv[3][0]))
108					usage();
109				drainwait = atoi(argv[3]);
110				argv += 2;
111			} else
112				usage();
113		}
114		if (dtrwait >= 0) {
115			if (ioctl(fd, TIOCMSDTRWAIT, &dtrwait) < 0) {
116				res = 1;
117				warn("TIOCMSDTRWAIT");
118			}
119		}
120		if (drainwait >= 0) {
121			if (ioctl(fd, TIOCSDRAINWAIT, &drainwait) < 0) {
122				res = 1;
123				warn("TIOCSDRAINWAIT");
124			}
125		}
126	}
127
128	close(fd);
129	return res;
130}
131