1 /* vi: set sw=4 ts=4: */
2 /* nc: mini-netcat - built from the ground up for LRP
3 Copyright (C) 1998 Charles P. Wright
6 0.0.2 5K Smaller and you can also check the exit condition if you wish.
9 19980918 Busy Boxed! Dave Cinege
10 19990512 Uses Select. Charles P. Wright
11 19990513 Fixes stdin stupidity and uses buffers. Charles P. Wright
13 Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <netinet/in.h>
25 #include <arpa/inet.h>
28 #include <sys/ioctl.h>
31 static void timeout(int signum)
33 bb_error_msg_and_die("Timed out");
36 int nc_main(int argc, char **argv)
38 int do_listen = 0, lport = 0, delay = 0, wsecs = 0, tmpfd, opt, sfd, x;
40 #define buf bb_common_bufsiz1
42 #ifdef CONFIG_NC_GAPING_SECURITY_HOLE
46 struct sockaddr_in address;
47 struct hostent *hostinfo;
49 fd_set readfds, testfds;
51 while ((opt = getopt(argc, argv, "lp:i:e:w:")) > 0) {
57 lport = bb_lookup_port(optarg, "tcp", 0);
62 #ifdef CONFIG_NC_GAPING_SECURITY_HOLE
75 if ((do_listen && optind != argc) || (!do_listen && optind + 2 != argc))
78 sfd = bb_xsocket(AF_INET, SOCK_STREAM, 0);
80 if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof (x)) == -1)
81 bb_perror_msg_and_die("reuseaddr");
82 address.sin_family = AF_INET;
85 signal(SIGALRM, timeout);
90 memset(&address.sin_addr, 0, sizeof(address.sin_addr));
91 address.sin_port = lport;
93 if (bind(sfd, (struct sockaddr *) &address, sizeof(address)) < 0)
94 bb_perror_msg_and_die("bind");
98 socklen_t addrlen = sizeof(address);
100 if (listen(sfd, 1) < 0)
101 bb_perror_msg_and_die("listen");
103 if ((tmpfd = accept(sfd, (struct sockaddr *) &address, &addrlen)) < 0)
104 bb_perror_msg_and_die("accept");
109 hostinfo = xgethostbyname(argv[optind]);
111 address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list;
112 address.sin_port = bb_lookup_port(argv[optind+1], "tcp", 0);
114 if (connect(sfd, (struct sockaddr *) &address, sizeof(address)) < 0)
115 bb_perror_msg_and_die("connect");
120 signal(SIGALRM, SIG_DFL);
123 #ifdef CONFIG_NC_GAPING_SECURITY_HOLE
130 execl(pr00gie, pr00gie, NULL);
131 /* Don't print stuff or it will go over the wire.... */
134 #endif /* CONFIG_NC_GAPING_SECURITY_HOLE */
137 FD_SET(sfd, &readfds);
138 FD_SET(STDIN_FILENO, &readfds);
147 if (select(FD_SETSIZE, &testfds, NULL, NULL, NULL) < 0)
148 bb_perror_msg_and_die("select");
150 for (fd = 0; fd < FD_SETSIZE; fd++) {
151 if (FD_ISSET(fd, &testfds)) {
152 if ((nread = safe_read(fd, buf, sizeof(buf))) < 0)
153 bb_perror_msg_and_die(bb_msg_read_error);
161 shutdown(sfd, 1 /* send */ );
163 FD_CLR(STDIN_FILENO, &readfds);
168 if (bb_full_write(ofd, buf, nread) < 0)
169 bb_perror_msg_and_die(bb_msg_write_error);