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

Last change on this file since 904 was 821, checked in by bruno, 13 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.