1 #include <err.h>
2 #include <fcntl.h>
3 #include <poll.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <time.h>
8 #include <unistd.h>
9 
10 static void
11 usage(void)
12 {
13 	fprintf(stderr, "usage: api-exabgp [ -t timeout ] fifo\n");
14 	exit(1);
15 }
16 
17 static int
18 fifo_open(const char *name)
19 {
20 	int fd;
21 
22 	fd = open(name, O_RDONLY | O_NONBLOCK);
23 	if (fd == -1)
24 		err(1, "open %s", name);
25 	return fd;
26 }
27 
28 int
29 main(int argc, char **argv)
30 {
31 	struct pollfd	pfd[2];
32 	char buf[512];
33 	const char *errstr, *fifo;
34 	int fd, ch, timeout = 0;
35 	time_t end, now;
36 	ssize_t n;
37 
38 	while ((ch = getopt(argc, argv, "t:")) != -1) {
39 		switch (ch) {
40 		case 't':
41 			timeout = strtonum(optarg, 0, 120, &errstr);
42 			if (errstr != NULL)
43 				errx(1, "timeout is %s: %s", errstr, optarg);
44 			break;
45 		default:
46 			usage();
47 		}
48 	}
49 	argc -= optind;
50 	argv += optind;
51 
52 	if (argv[0] == NULL)
53 		usage();
54 	fifo = argv[0];
55 
56 	pfd[0].fd = 0;
57 	pfd[0].events = POLLIN;
58 	pfd[1].fd = fd = fifo_open(fifo);
59 	pfd[1].events = POLLIN;
60 
61 	end = time(NULL) + timeout;
62 	while (1) {
63 		now = time(NULL);
64 		if (timeout != 0 && end < now) {
65 			if (write(1, "shutdown\n", 9) != 9)
66 				errx(1, "bad write to stdout");
67 		}
68 		if (poll(pfd, 2, 1000) == -1)
69 			err(1, "poll");
70 
71 		if (pfd[0].revents & POLLIN) {
72 			n = read(0, buf, sizeof(buf));
73 			if (n == -1)
74 				err(1, "read stdin");
75 			if (n > 2 && strncmp(buf + n - 2, "\n\n", 2) == 0)
76 				n--;
77 			if (write(2, buf, n) != n)
78 				errx(1, "bad write to stderr");
79 			if (n > 8 && strncmp(buf, "shutdown", 8) == 0)
80 				errx(0, "exabgp shutdown");
81 		}
82 		if (pfd[1].revents & POLLIN) {
83 			n = read(fd, buf, sizeof(buf));
84 			if (n == -1)
85 				err(1, "read fifo");
86 			if (n > 0) {
87 				if (write(1, buf, n) != n)
88 					errx(1, "bad write to stdout");
89 			}
90 		}
91 		if (pfd[1].revents & POLLHUP) {
92 			/* re-open fifo */
93 			close(fd);
94 			pfd[1].fd = fd = fifo_open(fifo);
95 		}
96 	}
97 }
98