splice flags are unsigned int, not unsigned long
[splice.git] / splice-fromnet.c
CommitLineData
beeecb44 1/*
27e4ade6 2 * Splice from network to stdout
beeecb44
JA
3 */
4#include <stdio.h>
5#include <stdlib.h>
6#include <unistd.h>
7#include <netdb.h>
8#include <unistd.h>
9#include <fcntl.h>
10#include <signal.h>
11#include <netinet/in.h>
12#include <arpa/inet.h>
13#include <string.h>
14#include <sys/time.h>
15#include <errno.h>
27e4ade6 16#include <sys/poll.h>
beeecb44
JA
17
18#include "splice.h"
19
beeecb44
JA
20static int usage(char *name)
21{
27e4ade6 22 fprintf(stderr, "%s: port\n", name);
beeecb44
JA
23 return 1;
24}
25
27e4ade6 26static int splice_from_net(int fd)
beeecb44 27{
27e4ade6
JA
28 while (1) {
29 struct pollfd pfd = {
30 .fd = fd,
31 .events = POLLIN,
32 };
33 int ret;
beeecb44 34
27e4ade6
JA
35 ret = poll(&pfd, 1, -1);
36 if (ret < 0)
37 return error("poll");
38 else if (!ret)
39 continue;
beeecb44 40
27e4ade6
JA
41 if (!(pfd.revents & POLLIN))
42 continue;
beeecb44 43
13b72067 44 ret = ssplice(fd, NULL, STDOUT_FILENO, NULL, SPLICE_SIZE, 0);
beeecb44 45
27e4ade6
JA
46 if (ret < 0)
47 return error("splice");
48 else if (!ret)
beeecb44 49 break;
27e4ade6 50 }
beeecb44
JA
51
52 return 0;
53}
54
27e4ade6 55static int get_connect(int fd, struct sockaddr_in *addr)
beeecb44 56{
27e4ade6
JA
57 socklen_t socklen = sizeof(*addr);
58 int ret, connfd;
beeecb44 59
27e4ade6
JA
60 do {
61 struct pollfd pfd = {
62 .fd = fd,
63 .events = POLLIN,
64 };
65
66 ret = poll(&pfd, 1, -1);
67 if (ret < 0)
68 return error("poll");
69 else if (!ret)
70 continue;
71
72 connfd = accept(fd, (struct sockaddr *) addr, &socklen);
73 if (connfd < 0)
74 return error("accept");
75 break;
76 } while (1);
77
78 return connfd;
beeecb44
JA
79}
80
81int main(int argc, char *argv[])
82{
83 struct sockaddr_in addr;
84 unsigned short port;
27e4ade6 85 int connfd, opt, fd;
beeecb44 86
27e4ade6 87 if (argc < 2)
beeecb44
JA
88 return usage(argv[0]);
89
27e4ade6 90 if (check_output_pipe())
beeecb44
JA
91 return usage(argv[0]);
92
27e4ade6 93 port = atoi(argv[1]);
beeecb44 94
27e4ade6 95 fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
beeecb44
JA
96 if (fd < 0)
97 return error("socket");
98
99 opt = 1;
100 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0)
101 return error("setsockopt");
102
103 memset(&addr, 0, sizeof(addr));
27e4ade6 104 addr.sin_family = AF_INET;
beeecb44
JA
105 addr.sin_addr.s_addr = htonl(INADDR_ANY);
106 addr.sin_port = htons(port);
107
108 if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
109 return error("bind");
beeecb44
JA
110 if (listen(fd, 1) < 0)
111 return error("listen");
112
27e4ade6
JA
113 connfd = get_connect(fd, &addr);
114 if (connfd < 0)
115 return connfd;
beeecb44 116
27e4ade6 117 return splice_from_net(connfd);
beeecb44 118}