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
usage(void)11 usage(void)
12 {
13 fprintf(stderr, "usage: api-exabgp [ -t timeout ] fifo\n");
14 exit(1);
15 }
16
17 static int
fifo_open(const char * name)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
main(int argc,char ** argv)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