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: |
