2 * A tee implementation using sys_tee. Sends out the data received over
3 * stdin to the given host:port and over stdout.
10 #include <netinet/in.h>
11 #include <arpa/inet.h>
14 #include <sys/types.h>
20 static int do_splice(int infd, int outfd, unsigned int len, char *msg)
23 int written = splice(infd, NULL, outfd, NULL, len, 0);
34 static int usage(char *name)
36 fprintf(stderr, "%s: hostname:port\n", name);
40 int main(int argc, char *argv[])
42 struct sockaddr_in addr;
48 return usage(argv[0]);
50 if (fstat(STDIN_FILENO, &sb) < 0)
52 if (!S_ISFIFO(sb.st_mode)) {
53 fprintf(stderr, "stdin must be a pipe\n");
57 hname = strdup(argv[1]);
58 p = strstr(hname, ":");
60 return usage(argv[0]);
62 memset(&addr, 0, sizeof(addr));
63 addr.sin_family = AF_INET;
64 addr.sin_port = htons(atoi(p + 1));
67 if (inet_aton(hname, &addr.sin_addr) != 1) {
68 struct hostent *hent = gethostbyname(hname);
71 return error("gethostbyname");
73 memcpy(&addr.sin_addr, hent->h_addr, 4);
76 fd = socket(AF_INET, SOCK_STREAM, 0);
78 return error("socket");
80 if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
81 return error("connect");
84 int tee_len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
87 if (errno == EAGAIN) {
96 * Send output to file, also consumes input pipe.
98 if (do_splice(STDIN_FILENO, fd, tee_len, "splice-net"))