174206d12Sclaudio #include <err.h>
274206d12Sclaudio #include <fcntl.h>
374206d12Sclaudio #include <poll.h>
474206d12Sclaudio #include <stdlib.h>
574206d12Sclaudio #include <stdio.h>
674206d12Sclaudio #include <string.h>
774206d12Sclaudio #include <time.h>
874206d12Sclaudio #include <unistd.h>
974206d12Sclaudio
1074206d12Sclaudio static void
usage(void)1174206d12Sclaudio usage(void)
1274206d12Sclaudio {
1374206d12Sclaudio fprintf(stderr, "usage: api-exabgp [ -t timeout ] fifo\n");
1474206d12Sclaudio exit(1);
1574206d12Sclaudio }
1674206d12Sclaudio
1774206d12Sclaudio static int
fifo_open(const char * name)1874206d12Sclaudio fifo_open(const char *name)
1974206d12Sclaudio {
2074206d12Sclaudio int fd;
2174206d12Sclaudio
2274206d12Sclaudio fd = open(name, O_RDONLY | O_NONBLOCK);
2374206d12Sclaudio if (fd == -1)
2474206d12Sclaudio err(1, "open %s", name);
2574206d12Sclaudio return fd;
2674206d12Sclaudio }
2774206d12Sclaudio
2874206d12Sclaudio int
main(int argc,char ** argv)2974206d12Sclaudio main(int argc, char **argv)
3074206d12Sclaudio {
3174206d12Sclaudio struct pollfd pfd[2];
3274206d12Sclaudio char buf[512];
3374206d12Sclaudio const char *errstr, *fifo;
3474206d12Sclaudio int fd, ch, timeout = 0;
3574206d12Sclaudio time_t end, now;
3674206d12Sclaudio ssize_t n;
3774206d12Sclaudio
3874206d12Sclaudio while ((ch = getopt(argc, argv, "t:")) != -1) {
3974206d12Sclaudio switch (ch) {
4074206d12Sclaudio case 't':
4174206d12Sclaudio timeout = strtonum(optarg, 0, 120, &errstr);
4274206d12Sclaudio if (errstr != NULL)
4374206d12Sclaudio errx(1, "timeout is %s: %s", errstr, optarg);
4474206d12Sclaudio break;
4574206d12Sclaudio default:
4674206d12Sclaudio usage();
4774206d12Sclaudio }
4874206d12Sclaudio }
4974206d12Sclaudio argc -= optind;
5074206d12Sclaudio argv += optind;
5174206d12Sclaudio
5274206d12Sclaudio if (argv[0] == NULL)
5374206d12Sclaudio usage();
5474206d12Sclaudio fifo = argv[0];
5574206d12Sclaudio
5674206d12Sclaudio pfd[0].fd = 0;
5774206d12Sclaudio pfd[0].events = POLLIN;
5874206d12Sclaudio pfd[1].fd = fd = fifo_open(fifo);
5974206d12Sclaudio pfd[1].events = POLLIN;
6074206d12Sclaudio
6174206d12Sclaudio end = time(NULL) + timeout;
6274206d12Sclaudio while (1) {
6374206d12Sclaudio now = time(NULL);
6474206d12Sclaudio if (timeout != 0 && end < now) {
6574206d12Sclaudio if (write(1, "shutdown\n", 9) != 9)
6674206d12Sclaudio errx(1, "bad write to stdout");
6774206d12Sclaudio }
6874206d12Sclaudio if (poll(pfd, 2, 1000) == -1)
6974206d12Sclaudio err(1, "poll");
7074206d12Sclaudio
7174206d12Sclaudio if (pfd[0].revents & POLLIN) {
7274206d12Sclaudio n = read(0, buf, sizeof(buf));
7374206d12Sclaudio if (n == -1)
7474206d12Sclaudio err(1, "read stdin");
75*1c7a6114Sclaudio if (n > 2 && strncmp(buf + n - 2, "\n\n", 2) == 0)
76*1c7a6114Sclaudio n--;
77*1c7a6114Sclaudio if (write(2, buf, n) != n)
7874206d12Sclaudio errx(1, "bad write to stderr");
7974206d12Sclaudio if (n > 8 && strncmp(buf, "shutdown", 8) == 0)
8074206d12Sclaudio errx(0, "exabgp shutdown");
8174206d12Sclaudio }
8274206d12Sclaudio if (pfd[1].revents & POLLIN) {
8374206d12Sclaudio n = read(fd, buf, sizeof(buf));
8474206d12Sclaudio if (n == -1)
8574206d12Sclaudio err(1, "read fifo");
8674206d12Sclaudio if (n > 0) {
8774206d12Sclaudio if (write(1, buf, n) != n)
8874206d12Sclaudio errx(1, "bad write to stdout");
8974206d12Sclaudio }
9074206d12Sclaudio }
9174206d12Sclaudio if (pfd[1].revents & POLLHUP) {
9274206d12Sclaudio /* re-open fifo */
9374206d12Sclaudio close(fd);
9474206d12Sclaudio pfd[1].fd = fd = fifo_open(fifo);
9574206d12Sclaudio }
9674206d12Sclaudio }
9774206d12Sclaudio }
98