c7df53487e8fa2372fea36cc093a82cb33bf18f2
[splice.git] / splice-net.c
1 /*
2  * Splice stdin to net
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 <sys/stat.h>
16 #include <errno.h>
17
18 #include "splice.h"
19
20 static int usage(char *name)
21 {
22         fprintf(stderr, "%s: target port\n", name);
23         return 1;
24 }
25
26 int main(int argc, char *argv[])
27 {
28         struct sockaddr_in addr;
29         unsigned short port;
30         int fd, ret;
31         struct stat sb;
32
33         if (argc < 3)
34                 return usage(argv[0]);
35
36         if (fstat(STDIN_FILENO, &sb) < 0)
37                 return error("stat");
38         if (!S_ISFIFO(sb.st_mode)) {
39                 fprintf(stderr, "stdin must be a pipe\n");
40                 return usage(argv[0]);
41         }
42
43         port = atoi(argv[2]);
44
45         memset(&addr, 0, sizeof(addr));
46         addr.sin_family = AF_INET;
47         addr.sin_port = htons(port);
48
49         if (inet_aton(argv[1], &addr.sin_addr) != 1) {
50                 struct hostent *hent = gethostbyname(argv[1]);
51
52                 if (!hent)
53                         return error("gethostbyname");
54
55                 memcpy(&addr.sin_addr, hent->h_addr, 4);
56         }
57
58         printf("Connecting to %s/%d\n", argv[1], port);
59
60         fd = socket(AF_INET, SOCK_STREAM, 0);
61         if (fd < 0)
62                 return error("socket");
63
64         if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
65                 return error("connect");
66
67         do {
68                 ret = splice(STDIN_FILENO, NULL, fd, NULL, SPLICE_SIZE, SPLICE_F_NONBLOCK);
69                 if (ret < 0) {
70                         if (errno == EAGAIN) {
71                                 usleep(100);
72                                 continue;
73                         }
74                         return error("splice");
75                 } else if (!ret)
76                         break;
77         } while (1);
78
79         close(fd);
80         return 0;
81 }