diff options
author | Matt Kraai <kraai@debian.org> | 2000-12-15 22:34:34 +0000 |
---|---|---|
committer | Matt Kraai <kraai@debian.org> | 2000-12-15 22:34:34 +0000 |
commit | bfa7967c4a18c9a7addbe853cf9f736ac34b4e5b (patch) | |
tree | 8269fa410bbc0b34bcd732c08054dca087b07ba3 | |
parent | 8677d7b6ec95cc9fa5c98b077680fc7ed4254d40 (diff) | |
download | busybox-w32-bfa7967c4a18c9a7addbe853cf9f736ac34b4e5b.tar.gz busybox-w32-bfa7967c4a18c9a7addbe853cf9f736ac34b4e5b.tar.bz2 busybox-w32-bfa7967c4a18c9a7addbe853cf9f736ac34b4e5b.zip |
Rewrite nc to be simpler, smaller, and to check syscalls for errors.
-rw-r--r-- | busybox.h | 1 | ||||
-rw-r--r-- | include/busybox.h | 1 | ||||
-rw-r--r-- | nc.c | 57 | ||||
-rw-r--r-- | networking/nc.c | 57 | ||||
-rw-r--r-- | utility.c | 15 |
5 files changed, 46 insertions, 85 deletions
@@ -147,6 +147,7 @@ int makeString(int argc, const char **argv, char *buf, int bufLen); | |||
147 | char *getChunk(int size); | 147 | char *getChunk(int size); |
148 | char *chunkstrdup(const char *str); | 148 | char *chunkstrdup(const char *str); |
149 | void freeChunks(void); | 149 | void freeChunks(void); |
150 | ssize_t safe_read(int fd, void *buf, size_t count); | ||
150 | int full_write(int fd, const char *buf, int len); | 151 | int full_write(int fd, const char *buf, int len); |
151 | int full_read(int fd, char *buf, int len); | 152 | int full_read(int fd, char *buf, int len); |
152 | int recursive_action(const char *fileName, int recurse, int followLinks, int depthFirst, | 153 | int recursive_action(const char *fileName, int recurse, int followLinks, int depthFirst, |
diff --git a/include/busybox.h b/include/busybox.h index 41421ae56..5ff3975b9 100644 --- a/include/busybox.h +++ b/include/busybox.h | |||
@@ -147,6 +147,7 @@ int makeString(int argc, const char **argv, char *buf, int bufLen); | |||
147 | char *getChunk(int size); | 147 | char *getChunk(int size); |
148 | char *chunkstrdup(const char *str); | 148 | char *chunkstrdup(const char *str); |
149 | void freeChunks(void); | 149 | void freeChunks(void); |
150 | ssize_t safe_read(int fd, void *buf, size_t count); | ||
150 | int full_write(int fd, const char *buf, int len); | 151 | int full_write(int fd, const char *buf, int len); |
151 | int full_read(int fd, char *buf, int len); | 152 | int full_read(int fd, char *buf, int len); |
152 | int recursive_action(const char *fileName, int recurse, int followLinks, int depthFirst, | 153 | int recursive_action(const char *fileName, int recurse, int followLinks, int depthFirst, |
@@ -38,14 +38,10 @@ | |||
38 | #include <sys/time.h> | 38 | #include <sys/time.h> |
39 | #include <sys/ioctl.h> | 39 | #include <sys/ioctl.h> |
40 | 40 | ||
41 | #define BUFSIZE 100 | ||
42 | |||
43 | int nc_main(int argc, char **argv) | 41 | int nc_main(int argc, char **argv) |
44 | { | 42 | { |
45 | int sfd; | 43 | int sfd; |
46 | int result; | 44 | char buf[BUFSIZ]; |
47 | int len; | ||
48 | char ch[BUFSIZE]; | ||
49 | 45 | ||
50 | struct sockaddr_in address; | 46 | struct sockaddr_in address; |
51 | struct hostent *hostinfo; | 47 | struct hostent *hostinfo; |
@@ -54,34 +50,26 @@ int nc_main(int argc, char **argv) | |||
54 | 50 | ||
55 | argc--; | 51 | argc--; |
56 | argv++; | 52 | argv++; |
57 | if (argc < 2 || **(argv + 1) == '-') { | 53 | if (argc < 2 || **argv == '-') { |
58 | usage(nc_usage); | 54 | usage(nc_usage); |
59 | } | 55 | } |
60 | 56 | ||
61 | sfd = socket(AF_INET, SOCK_STREAM, 0); | 57 | if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) |
62 | 58 | perror_msg_and_die("socket"); | |
63 | hostinfo = (struct hostent *) gethostbyname(*argv); | ||
64 | 59 | ||
65 | if (!hostinfo) { | 60 | if ((hostinfo = gethostbyname(*argv)) == NULL) |
66 | error_msg_and_die("cannot resolve %s\n", *argv); | 61 | error_msg_and_die("cannot resolve %s\n", *argv); |
67 | } | ||
68 | 62 | ||
69 | address.sin_family = AF_INET; | 63 | address.sin_family = AF_INET; |
70 | address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list; | 64 | address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list; |
71 | address.sin_port = htons(atoi(*(++argv))); | 65 | address.sin_port = htons(atoi(*(++argv))); |
72 | 66 | ||
73 | len = sizeof(address); | 67 | if (connect(sfd, (struct sockaddr *) &address, sizeof(address)) < 0) |
74 | 68 | perror_msg_and_die("connect"); | |
75 | result = connect(sfd, (struct sockaddr *) &address, len); | ||
76 | |||
77 | if (result < 0) { | ||
78 | perror("nc: connect"); | ||
79 | exit(2); | ||
80 | } | ||
81 | 69 | ||
82 | FD_ZERO(&readfds); | 70 | FD_ZERO(&readfds); |
83 | FD_SET(sfd, &readfds); | 71 | FD_SET(sfd, &readfds); |
84 | FD_SET(fileno(stdin), &readfds); | 72 | FD_SET(STDIN_FILENO, &readfds); |
85 | 73 | ||
86 | while (1) { | 74 | while (1) { |
87 | int fd; | 75 | int fd; |
@@ -90,41 +78,26 @@ int nc_main(int argc, char **argv) | |||
90 | 78 | ||
91 | testfds = readfds; | 79 | testfds = readfds; |
92 | 80 | ||
93 | result = | 81 | if (select(FD_SETSIZE, &testfds, NULL, NULL, NULL) < 0) |
94 | select(FD_SETSIZE, &testfds, (fd_set *) NULL, (fd_set *) NULL, | 82 | perror_msg_and_die("select"); |
95 | (struct timeval *) 0); | ||
96 | |||
97 | if (result < 1) { | ||
98 | perror("nc: select"); | ||
99 | exit(3); | ||
100 | } | ||
101 | 83 | ||
102 | for (fd = 0; fd < FD_SETSIZE; fd++) { | 84 | for (fd = 0; fd < FD_SETSIZE; fd++) { |
103 | if (FD_ISSET(fd, &testfds)) { | 85 | if (FD_ISSET(fd, &testfds)) { |
104 | int trn = 0; | 86 | if ((nread = safe_read(fd, buf, sizeof(buf))) < 0) |
105 | int rn; | 87 | perror_msg_and_die("read"); |
106 | |||
107 | ioctl(fd, FIONREAD, &nread); | ||
108 | 88 | ||
109 | if (fd == sfd) { | 89 | if (fd == sfd) { |
110 | if (nread == 0) | 90 | if (nread == 0) |
111 | exit(0); | 91 | exit(0); |
112 | ofd = fileno(stdout); | 92 | ofd = STDOUT_FILENO; |
113 | } else { | 93 | } else { |
114 | if (nread == 0) | 94 | if (nread == 0) |
115 | shutdown(sfd, 1); | 95 | shutdown(sfd, 1); |
116 | ofd = sfd; | 96 | ofd = sfd; |
117 | } | 97 | } |
118 | 98 | ||
119 | 99 | if (full_write(ofd, buf, nread) < 0) | |
120 | 100 | perror_msg_and_die("write"); | |
121 | do { | ||
122 | rn = (BUFSIZE < nread - trn) ? BUFSIZE : nread - trn; | ||
123 | trn += rn; | ||
124 | read(fd, ch, rn); | ||
125 | write(ofd, ch, rn); | ||
126 | } | ||
127 | while (trn < nread); | ||
128 | } | 101 | } |
129 | } | 102 | } |
130 | } | 103 | } |
diff --git a/networking/nc.c b/networking/nc.c index 84c1a815e..a2be8ec46 100644 --- a/networking/nc.c +++ b/networking/nc.c | |||
@@ -38,14 +38,10 @@ | |||
38 | #include <sys/time.h> | 38 | #include <sys/time.h> |
39 | #include <sys/ioctl.h> | 39 | #include <sys/ioctl.h> |
40 | 40 | ||
41 | #define BUFSIZE 100 | ||
42 | |||
43 | int nc_main(int argc, char **argv) | 41 | int nc_main(int argc, char **argv) |
44 | { | 42 | { |
45 | int sfd; | 43 | int sfd; |
46 | int result; | 44 | char buf[BUFSIZ]; |
47 | int len; | ||
48 | char ch[BUFSIZE]; | ||
49 | 45 | ||
50 | struct sockaddr_in address; | 46 | struct sockaddr_in address; |
51 | struct hostent *hostinfo; | 47 | struct hostent *hostinfo; |
@@ -54,34 +50,26 @@ int nc_main(int argc, char **argv) | |||
54 | 50 | ||
55 | argc--; | 51 | argc--; |
56 | argv++; | 52 | argv++; |
57 | if (argc < 2 || **(argv + 1) == '-') { | 53 | if (argc < 2 || **argv == '-') { |
58 | usage(nc_usage); | 54 | usage(nc_usage); |
59 | } | 55 | } |
60 | 56 | ||
61 | sfd = socket(AF_INET, SOCK_STREAM, 0); | 57 | if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) |
62 | 58 | perror_msg_and_die("socket"); | |
63 | hostinfo = (struct hostent *) gethostbyname(*argv); | ||
64 | 59 | ||
65 | if (!hostinfo) { | 60 | if ((hostinfo = gethostbyname(*argv)) == NULL) |
66 | error_msg_and_die("cannot resolve %s\n", *argv); | 61 | error_msg_and_die("cannot resolve %s\n", *argv); |
67 | } | ||
68 | 62 | ||
69 | address.sin_family = AF_INET; | 63 | address.sin_family = AF_INET; |
70 | address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list; | 64 | address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list; |
71 | address.sin_port = htons(atoi(*(++argv))); | 65 | address.sin_port = htons(atoi(*(++argv))); |
72 | 66 | ||
73 | len = sizeof(address); | 67 | if (connect(sfd, (struct sockaddr *) &address, sizeof(address)) < 0) |
74 | 68 | perror_msg_and_die("connect"); | |
75 | result = connect(sfd, (struct sockaddr *) &address, len); | ||
76 | |||
77 | if (result < 0) { | ||
78 | perror("nc: connect"); | ||
79 | exit(2); | ||
80 | } | ||
81 | 69 | ||
82 | FD_ZERO(&readfds); | 70 | FD_ZERO(&readfds); |
83 | FD_SET(sfd, &readfds); | 71 | FD_SET(sfd, &readfds); |
84 | FD_SET(fileno(stdin), &readfds); | 72 | FD_SET(STDIN_FILENO, &readfds); |
85 | 73 | ||
86 | while (1) { | 74 | while (1) { |
87 | int fd; | 75 | int fd; |
@@ -90,41 +78,26 @@ int nc_main(int argc, char **argv) | |||
90 | 78 | ||
91 | testfds = readfds; | 79 | testfds = readfds; |
92 | 80 | ||
93 | result = | 81 | if (select(FD_SETSIZE, &testfds, NULL, NULL, NULL) < 0) |
94 | select(FD_SETSIZE, &testfds, (fd_set *) NULL, (fd_set *) NULL, | 82 | perror_msg_and_die("select"); |
95 | (struct timeval *) 0); | ||
96 | |||
97 | if (result < 1) { | ||
98 | perror("nc: select"); | ||
99 | exit(3); | ||
100 | } | ||
101 | 83 | ||
102 | for (fd = 0; fd < FD_SETSIZE; fd++) { | 84 | for (fd = 0; fd < FD_SETSIZE; fd++) { |
103 | if (FD_ISSET(fd, &testfds)) { | 85 | if (FD_ISSET(fd, &testfds)) { |
104 | int trn = 0; | 86 | if ((nread = safe_read(fd, buf, sizeof(buf))) < 0) |
105 | int rn; | 87 | perror_msg_and_die("read"); |
106 | |||
107 | ioctl(fd, FIONREAD, &nread); | ||
108 | 88 | ||
109 | if (fd == sfd) { | 89 | if (fd == sfd) { |
110 | if (nread == 0) | 90 | if (nread == 0) |
111 | exit(0); | 91 | exit(0); |
112 | ofd = fileno(stdout); | 92 | ofd = STDOUT_FILENO; |
113 | } else { | 93 | } else { |
114 | if (nread == 0) | 94 | if (nread == 0) |
115 | shutdown(sfd, 1); | 95 | shutdown(sfd, 1); |
116 | ofd = sfd; | 96 | ofd = sfd; |
117 | } | 97 | } |
118 | 98 | ||
119 | 99 | if (full_write(ofd, buf, nread) < 0) | |
120 | 100 | perror_msg_and_die("write"); | |
121 | do { | ||
122 | rn = (BUFSIZE < nread - trn) ? BUFSIZE : nread - trn; | ||
123 | trn += rn; | ||
124 | read(fd, ch, rn); | ||
125 | write(ofd, ch, rn); | ||
126 | } | ||
127 | while (trn < nread); | ||
128 | } | 101 | } |
129 | } | 102 | } |
130 | } | 103 | } |
@@ -536,7 +536,7 @@ const char *time_string(time_t timeVal) | |||
536 | } | 536 | } |
537 | #endif /* BB_TAR || BB_AR */ | 537 | #endif /* BB_TAR || BB_AR */ |
538 | 538 | ||
539 | #if defined BB_TAR || defined BB_CP_MV || defined BB_AR || defined BB_DD | 539 | #if defined BB_AR || defined BB_CP_MV || defined BB_DD || defined BB_NC || defined BB_TAR |
540 | /* | 540 | /* |
541 | * Write all of the supplied buffer out to a file. | 541 | * Write all of the supplied buffer out to a file. |
542 | * This does multiple writes as necessary. | 542 | * This does multiple writes as necessary. |
@@ -1791,6 +1791,19 @@ int applet_name_compare(const void *x, const void *y) | |||
1791 | return strcmp(applet1->name, applet2->name); | 1791 | return strcmp(applet1->name, applet2->name); |
1792 | } | 1792 | } |
1793 | 1793 | ||
1794 | #if defined BB_NC | ||
1795 | ssize_t safe_read(int fd, void *buf, size_t count) | ||
1796 | { | ||
1797 | ssize_t n; | ||
1798 | |||
1799 | do { | ||
1800 | n = read(fd, buf, count); | ||
1801 | } while (n < 0 && errno == EINTR); | ||
1802 | |||
1803 | return n; | ||
1804 | } | ||
1805 | #endif | ||
1806 | |||
1794 | /* END CODE */ | 1807 | /* END CODE */ |
1795 | /* | 1808 | /* |
1796 | Local Variables: | 1809 | Local Variables: |