xref: /openbsd-src/regress/usr.sbin/bgpd/integrationtests/api-exabgp.c (revision 1c7a6114d887a7b4772ad1e87fc55f5ed55c634c)
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