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>
27 #include <sys/ioctl.h>
30 static void timeout(int signum)
32 bb_error_msg_and_die("Timed out");
35 int nc_main(int argc, char **argv)
37 int do_listen = 0, lport = 0, delay = 0, wsecs = 0, tmpfd, opt, sfd, x;
39 #ifdef CONFIG_NC_GAPING_SECURITY_HOLE
43 struct sockaddr_in address;
44 struct hostent *hostinfo;
46 fd_set readfds, testfds;
48 while ((opt = getopt(argc, argv, "lp:i:e:w:")) > 0) {
54 lport = bb_lookup_port(optarg, "tcp", 0);
59 #ifdef CONFIG_NC_GAPING_SECURITY_HOLE
72 if ((do_listen && optind != argc) || (!do_listen && optind + 2 != argc))
75 sfd = bb_xsocket(AF_INET, SOCK_STREAM, 0);
77 if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof (x)) == -1)
78 bb_perror_msg_and_die("reuseaddr");
79 address.sin_family = AF_INET;
82 signal(SIGALRM, timeout);
87 memset(&address.sin_addr, 0, sizeof(address.sin_addr));
88 address.sin_port = lport;
90 bb_xbind(sfd, (struct sockaddr *) &address, sizeof(address));
94 socklen_t addrlen = sizeof(address);
97 if ((tmpfd = accept(sfd, (struct sockaddr *) &address, &addrlen)) < 0)
98 bb_perror_msg_and_die("accept");
103 hostinfo = xgethostbyname(argv[optind]);
105 address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list;
106 address.sin_port = bb_lookup_port(argv[optind+1], "tcp", 0);
108 if (connect(sfd, (struct sockaddr *) &address, sizeof(address)) < 0)
109 bb_perror_msg_and_die("connect");
114 signal(SIGALRM, SIG_DFL);
117 #ifdef CONFIG_NC_GAPING_SECURITY_HOLE
124 execl(pr00gie, pr00gie, NULL);
125 /* Don't print stuff or it will go over the wire.... */
128 #endif /* CONFIG_NC_GAPING_SECURITY_HOLE */
131 FD_SET(sfd, &readfds);
132 FD_SET(STDIN_FILENO, &readfds);
141 if (select(FD_SETSIZE, &testfds, NULL, NULL, NULL) < 0)
142 bb_perror_msg_and_die("select");
144 for (fd = 0; fd < FD_SETSIZE; fd++) {
145 if (FD_ISSET(fd, &testfds)) {
146 if ((nread = safe_read(fd, bb_common_bufsiz1,
147 sizeof(bb_common_bufsiz1))) < 0)
149 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, bb_common_bufsiz1, nread) < 0)
166 bb_perror_msg_and_die(bb_msg_write_error);