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 bb_xbind(sfd, (struct sockaddr *) &address, sizeof(address));
97 socklen_t addrlen = sizeof(address);
100 if ((tmpfd = accept(sfd, (struct sockaddr *) &address, &addrlen)) < 0)
101 bb_perror_msg_and_die("accept");
106 hostinfo = xgethostbyname(argv[optind]);
108 address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list;
109 address.sin_port = bb_lookup_port(argv[optind+1], "tcp", 0);
111 if (connect(sfd, (struct sockaddr *) &address, sizeof(address)) < 0)
112 bb_perror_msg_and_die("connect");
117 signal(SIGALRM, SIG_DFL);
120 #ifdef CONFIG_NC_GAPING_SECURITY_HOLE
127 execl(pr00gie, pr00gie, NULL);
128 /* Don't print stuff or it will go over the wire.... */
131 #endif /* CONFIG_NC_GAPING_SECURITY_HOLE */
134 FD_SET(sfd, &readfds);
135 FD_SET(STDIN_FILENO, &readfds);
144 if (select(FD_SETSIZE, &testfds, NULL, NULL, NULL) < 0)
145 bb_perror_msg_and_die("select");
147 for (fd = 0; fd < FD_SETSIZE; fd++) {
148 if (FD_ISSET(fd, &testfds)) {
149 if ((nread = safe_read(fd, buf, sizeof(buf))) < 0)
150 bb_perror_msg_and_die(bb_msg_read_error);
158 shutdown(sfd, 1 /* send */ );
160 FD_CLR(STDIN_FILENO, &readfds);
165 if (bb_full_write(ofd, buf, nread) < 0)
166 bb_perror_msg_and_die(bb_msg_write_error);