source: MondoRescue/trunk/mindi-busybox/networking/nc.c@ 904

Last change on this file since 904 was 821, checked in by Bruno Cornec, 18 years ago

Addition of busybox 1.2.1 as a mindi-busybox new package
This should avoid delivering binary files in mindi not built there (Fedora and Debian are quite serious about that)

File size: 3.7 KB
Line 
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
4
5 0.0.1 6K It works.
6 0.0.2 5K Smaller and you can also check the exit condition if you wish.
7 0.0.3 Uses select()
8
9 19980918 Busy Boxed! Dave Cinege
10 19990512 Uses Select. Charles P. Wright
11 19990513 Fixes stdin stupidity and uses buffers. Charles P. Wright
12
13 Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
14*/
15
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19#include <unistd.h>
20#include <signal.h>
21
22#include <sys/types.h>
23#include <sys/socket.h>
24#include <netinet/in.h>
25#include <arpa/inet.h>
26#include <netdb.h>
27#include <sys/ioctl.h>
28#include "busybox.h"
29
30static void timeout(int signum)
31{
32 bb_error_msg_and_die("Timed out");
33}
34
35int nc_main(int argc, char **argv)
36{
37 int do_listen = 0, lport = 0, delay = 0, wsecs = 0, tmpfd, opt, sfd, x;
38
39#ifdef CONFIG_NC_GAPING_SECURITY_HOLE
40 char *pr00gie = NULL;
41#endif
42
43 struct sockaddr_in address;
44 struct hostent *hostinfo;
45
46 fd_set readfds, testfds;
47
48 while ((opt = getopt(argc, argv, "lp:i:e:w:")) > 0) {
49 switch (opt) {
50 case 'l':
51 do_listen++;
52 break;
53 case 'p':
54 lport = bb_lookup_port(optarg, "tcp", 0);
55 break;
56 case 'i':
57 delay = atoi(optarg);
58 break;
59#ifdef CONFIG_NC_GAPING_SECURITY_HOLE
60 case 'e':
61 pr00gie = optarg;
62 break;
63#endif
64 case 'w':
65 wsecs = atoi(optarg);
66 break;
67 default:
68 bb_show_usage();
69 }
70 }
71
72 if ((do_listen && optind != argc) || (!do_listen && optind + 2 != argc))
73 bb_show_usage();
74
75 sfd = bb_xsocket(AF_INET, SOCK_STREAM, 0);
76 x = 1;
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;
80
81 if (wsecs) {
82 signal(SIGALRM, timeout);
83 alarm(wsecs);
84 }
85
86 if (lport != 0) {
87 memset(&address.sin_addr, 0, sizeof(address.sin_addr));
88 address.sin_port = lport;
89
90 bb_xbind(sfd, (struct sockaddr *) &address, sizeof(address));
91 }
92
93 if (do_listen) {
94 socklen_t addrlen = sizeof(address);
95
96 bb_xlisten(sfd, 1);
97 if ((tmpfd = accept(sfd, (struct sockaddr *) &address, &addrlen)) < 0)
98 bb_perror_msg_and_die("accept");
99
100 close(sfd);
101 sfd = tmpfd;
102 } else {
103 hostinfo = xgethostbyname(argv[optind]);
104
105 address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list;
106 address.sin_port = bb_lookup_port(argv[optind+1], "tcp", 0);
107
108 if (connect(sfd, (struct sockaddr *) &address, sizeof(address)) < 0)
109 bb_perror_msg_and_die("connect");
110 }
111
112 if (wsecs) {
113 alarm(0);
114 signal(SIGALRM, SIG_DFL);
115 }
116
117#ifdef CONFIG_NC_GAPING_SECURITY_HOLE
118 /* -e given? */
119 if (pr00gie) {
120 dup2(sfd, 0);
121 close(sfd);
122 dup2(0, 1);
123 dup2(0, 2);
124 execl(pr00gie, pr00gie, NULL);
125 /* Don't print stuff or it will go over the wire.... */
126 _exit(-1);
127 }
128#endif /* CONFIG_NC_GAPING_SECURITY_HOLE */
129
130 FD_ZERO(&readfds);
131 FD_SET(sfd, &readfds);
132 FD_SET(STDIN_FILENO, &readfds);
133
134 while (1) {
135 int fd;
136 int ofd;
137 int nread;
138
139 testfds = readfds;
140
141 if (select(FD_SETSIZE, &testfds, NULL, NULL, NULL) < 0)
142 bb_perror_msg_and_die("select");
143
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)
148 {
149 bb_perror_msg_and_die(bb_msg_read_error);
150 }
151
152 if (fd == sfd) {
153 if (nread == 0)
154 exit(0);
155 ofd = STDOUT_FILENO;
156 } else {
157 if (nread <= 0) {
158 shutdown(sfd, 1 /* send */ );
159 close(STDIN_FILENO);
160 FD_CLR(STDIN_FILENO, &readfds);
161 }
162 ofd = sfd;
163 }
164
165 if (bb_full_write(ofd, bb_common_bufsiz1, nread) < 0)
166 bb_perror_msg_and_die(bb_msg_write_error);
167 if (delay > 0) {
168 sleep(delay);
169 }
170 }
171 }
172 }
173}
Note: See TracBrowser for help on using the repository browser.