2 * Splice from network to stdout
11 #include <netinet/in.h>
12 #include <arpa/inet.h>
20 static unsigned int splice_size = SPLICE_SIZE;
21 static unsigned int splice_flags;
22 static int wait_for_poll;
24 static int usage(char *name)
26 fprintf(stderr, "%s: [-s splice size] [-w wait for poll] [-n non-blocking] port\n", name);
30 static int splice_from_net(int fd)
41 ret = poll(&pfd, 1, -1);
47 if (!(pfd.revents & POLLIN))
51 ret = ssplice(fd, NULL, STDOUT_FILENO, NULL, splice_size, 0);
54 return error("splice");
62 static int get_connect(int fd, struct sockaddr_in *addr)
64 socklen_t socklen = sizeof(*addr);
73 ret = poll(&pfd, 1, -1);
79 connfd = accept(fd, (struct sockaddr *) addr, &socklen);
81 return error("accept");
88 static int parse_options(int argc, char *argv[])
92 while ((c = getopt(argc, argv, "s:w:n")) != -1) {
95 splice_size = atoi(optarg);
99 wait_for_poll = atoi(optarg);
103 splice_flags |= SPLICE_F_NONBLOCK;
115 int main(int argc, char *argv[])
117 struct sockaddr_in addr;
119 int connfd, opt, fd, index;
122 return usage(argv[0]);
124 if (check_output_pipe())
125 return usage(argv[0]);
127 index = parse_options(argc, argv);
128 if (index == -1 || index + 1 > argc)
129 return usage(argv[0]);
131 port = atoi(argv[index]);
133 fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
135 return error("socket");
138 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0)
139 return error("setsockopt");
141 memset(&addr, 0, sizeof(addr));
142 addr.sin_family = AF_INET;
143 addr.sin_addr.s_addr = htonl(INADDR_ANY);
144 addr.sin_port = htons(port);
146 if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
147 return error("bind");
148 if (listen(fd, 1) < 0)
149 return error("listen");
151 connfd = get_connect(fd, &addr);
155 return splice_from_net(connfd);