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