diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2006-10-16 01:10:28 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2006-10-16 01:10:28 +0000 |
| commit | d0e70af9d1065400a3ed478393dcd3873d1cb7d8 (patch) | |
| tree | 82e9c52a15ed4c24dec593834188cefcc82a8382 | |
| parent | bf39216cc4e095a7ce9a4b33b778c903b916e18b (diff) | |
| download | busybox-w32-d0e70af9d1065400a3ed478393dcd3873d1cb7d8.tar.gz busybox-w32-d0e70af9d1065400a3ed478393dcd3873d1cb7d8.tar.bz2 busybox-w32-d0e70af9d1065400a3ed478393dcd3873d1cb7d8.zip | |
nc: fix 2 my own buglets, and few someone else's too.
| -rw-r--r-- | include/usage.h | 26 | ||||
| -rw-r--r-- | libbb/xatol.c | 2 | ||||
| -rw-r--r-- | networking/nc.c | 95 |
3 files changed, 75 insertions, 48 deletions
diff --git a/include/usage.h b/include/usage.h index 320294c8a..287d5a1c8 100644 --- a/include/usage.h +++ b/include/usage.h | |||
| @@ -2109,31 +2109,31 @@ USE_FEATURE_MDEV_CONFIG( \ | |||
| 2109 | #if ENABLE_NC_SERVER || ENABLE_NC_EXTRA | 2109 | #if ENABLE_NC_SERVER || ENABLE_NC_EXTRA |
| 2110 | #define NC_BR1 "[" | 2110 | #define NC_BR1 "[" |
| 2111 | #define NC_BR2 "]" | 2111 | #define NC_BR2 "]" |
| 2112 | #define NC_OPTIONS_STR "\n\nOptions:" | ||
| 2112 | #else | 2113 | #else |
| 2113 | #define NC_BR1 | 2114 | #define NC_BR1 |
| 2114 | #define NC_BR2 | 2115 | #define NC_BR2 |
| 2116 | #define NC_OPTIONS_STR | ||
| 2115 | #endif | 2117 | #endif |
| 2116 | 2118 | ||
| 2117 | #define nc_trivial_usage \ | 2119 | #define nc_trivial_usage \ |
| 2118 | "[" \ | 2120 | NC_BR1 USE_NC_EXTRA("iw")USE_NC_SERVER("-l") NC_BR2 USE_NC_SERVER(" [-p PORT]") \ |
| 2119 | NC_BR1 USE_NC_SERVER("-lp")USE_NC_EXTRA("iwf") NC_BR2 \ | 2121 | " [" USE_NC_EXTRA("-f FILENAME|") "{IPADDR PORTNUM}]" USE_NC_EXTRA(" [-e COMMAND]") |
| 2120 | " ["USE_NC_EXTRA("FILENAME|")"{IPADDR PORTNUM}]"USE_NC_EXTRA(" [-e COMMAND]") | ||
| 2121 | #define nc_full_usage \ | 2122 | #define nc_full_usage \ |
| 2122 | "Netcat opens a pipe, either to IP:port\n\n" \ | 2123 | "Netcat opens a pipe to IP:port" USE_NC_EXTRA(" or file") \ |
| 2123 | "Options:" \ | 2124 | NC_OPTIONS_STR \ |
| 2124 | USE_NC_EXTRA( \ | 2125 | USE_NC_EXTRA( \ |
| 2125 | "\n\t-e\t\texec rest of command line after connect\n" \ | 2126 | "\n\t-e\texec rest of command line after connect\n" \ |
| 2126 | "\t-i SECS\t\tdelay interval for lines sent\n" \ | 2127 | "\t-i SECS\tdelay interval for lines sent\n" \ |
| 2127 | "\t-w SECS\t\ttimeout for connect\n" \ | 2128 | "\t-w SECS\ttimeout for connect\n" \ |
| 2128 | "\t-f filename\tuse file (ala /dev/ttyS0) instead of network" \ | 2129 | "\t-f file\tuse file (ala /dev/ttyS0) instead of network" \ |
| 2129 | ) \ | 2130 | ) \ |
| 2130 | USE_NC_SERVER( \ | 2131 | USE_NC_SERVER( \ |
| 2131 | "\n\t-l\t\tlisten mode, for inbound connects\n" \ | 2132 | "\n\t-l\tlisten mode, for inbound connects\n" \ |
| 2132 | USE_NC_EXTRA("\t\t\t(use -l twice with -e for persistent server)\n") \ | 2133 | USE_NC_EXTRA("\t\t(use -l twice with -e for persistent server)\n") \ |
| 2133 | "\t-p PORT\t\tlocal port number" \ | 2134 | "\t-p PORT\tlocal port number" \ |
| 2134 | ) | 2135 | ) |
| 2135 | 2136 | ||
| 2136 | |||
| 2137 | #define nc_notes_usage "" \ | 2137 | #define nc_notes_usage "" \ |
| 2138 | USE_NC_EXTRA( \ | 2138 | USE_NC_EXTRA( \ |
| 2139 | "To use netcat as a terminal emulator on a serial port:\n\n" \ | 2139 | "To use netcat as a terminal emulator on a serial port:\n\n" \ |
diff --git a/libbb/xatol.c b/libbb/xatol.c index 1b281b1e9..74a3b9917 100644 --- a/libbb/xatol.c +++ b/libbb/xatol.c | |||
| @@ -127,7 +127,7 @@ unsigned long xatoul_range(const char *numstr, | |||
| 127 | unsigned long lower, | 127 | unsigned long lower, |
| 128 | unsigned long upper) | 128 | unsigned long upper) |
| 129 | { | 129 | { |
| 130 | return xstrtol_range_sfx(numstr, 10, lower, upper, NULL); | 130 | return xstrtoul_range_sfx(numstr, 10, lower, upper, NULL); |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | unsigned long xatoul(const char *numstr) | 133 | unsigned long xatoul(const char *numstr) |
diff --git a/networking/nc.c b/networking/nc.c index bde5e6600..a940d8a5d 100644 --- a/networking/nc.c +++ b/networking/nc.c | |||
| @@ -16,51 +16,78 @@ static void timeout(int signum) | |||
| 16 | 16 | ||
| 17 | int nc_main(int argc, char **argv) | 17 | int nc_main(int argc, char **argv) |
| 18 | { | 18 | { |
| 19 | int sfd = 0, cfd; | 19 | int sfd = 0; |
| 20 | unsigned opt; | 20 | int cfd = 0; |
| 21 | unsigned lport = 0, wsecs = 0, delay = 0; | 21 | SKIP_NC_SERVER(const) unsigned do_listen = 0; |
| 22 | unsigned do_listen = 0, execflag = 0; | 22 | SKIP_NC_SERVER(const) unsigned lport = 0; |
| 23 | SKIP_NC_EXTRA (const) unsigned wsecs = 0; | ||
| 24 | SKIP_NC_EXTRA (const) unsigned delay = 0; | ||
| 25 | SKIP_NC_EXTRA (const int execparam = 0;) | ||
| 26 | USE_NC_EXTRA (char **execparam = NULL;) | ||
| 23 | struct sockaddr_in address; | 27 | struct sockaddr_in address; |
| 24 | struct hostent *hostinfo; | 28 | struct hostent *hostinfo; |
| 25 | fd_set readfds, testfds; | 29 | fd_set readfds, testfds; |
| 26 | char *infile = NULL; | 30 | int opt; /* must be signed (getopt returns -1) */ |
| 27 | 31 | ||
| 28 | memset(&address, 0, sizeof(address)); | 32 | memset(&address, 0, sizeof(address)); |
| 29 | 33 | ||
| 30 | if (ENABLE_NC_SERVER || ENABLE_NC_EXTRA) { | 34 | if (ENABLE_NC_SERVER || ENABLE_NC_EXTRA) { |
| 31 | while ((opt = getopt(argc, argv, "lp:" USE_NC_EXTRA("i:ew:f:"))) > 0) { | 35 | /* getopt32 is _almost_ usable: |
| 32 | if (ENABLE_NC_SERVER && opt=='l') do_listen++; | 36 | ** it cannot handle "... -e prog -prog-opt" */ |
| 33 | else if (ENABLE_NC_SERVER && opt=='p') | 37 | while ((opt = getopt(argc, argv, |
| 34 | lport = bb_lookup_port(optarg, "tcp", 0); | 38 | "" USE_NC_SERVER("lp:") USE_NC_EXTRA("w:i:f:e:") )) > 0 |
| 35 | else if (ENABLE_NC_EXTRA && opt=='w') wsecs = xatou(optarg); | 39 | ) { |
| 36 | else if (ENABLE_NC_EXTRA && opt=='i') delay = xatou(optarg); | 40 | if (ENABLE_NC_SERVER && opt=='l') USE_NC_SERVER(do_listen++); |
| 37 | else if (ENABLE_NC_EXTRA && opt=='f') infile = optarg; | 41 | else if (ENABLE_NC_SERVER && opt=='p') USE_NC_SERVER(lport = bb_lookup_port(optarg, "tcp", 0)); |
| 38 | else if (ENABLE_NC_EXTRA && opt=='e' && optind!=argc) { | 42 | else if (ENABLE_NC_EXTRA && opt=='w') USE_NC_EXTRA( wsecs = xatou(optarg)); |
| 39 | execflag++; | 43 | else if (ENABLE_NC_EXTRA && opt=='i') USE_NC_EXTRA( delay = xatou(optarg)); |
| 40 | break; | 44 | else if (ENABLE_NC_EXTRA && opt=='f') USE_NC_EXTRA( cfd = xopen(optarg, O_RDWR)); |
| 45 | else if (ENABLE_NC_EXTRA && opt=='e' && optind<=argc) { | ||
| 46 | /* We cannot just 'break'. We should let getopt finish. | ||
| 47 | ** Or else we won't be able to find where | ||
| 48 | ** 'host' and 'port' params are | ||
| 49 | ** (think "nc -w 60 host port -e prog"). */ | ||
| 50 | USE_NC_EXTRA( | ||
| 51 | char **p; | ||
| 52 | // +2: one for progname (optarg) and one for NULL | ||
| 53 | execparam = xzalloc(sizeof(char*) * (argc - optind + 2)); | ||
| 54 | p = execparam; | ||
| 55 | *p++ = optarg; | ||
| 56 | while (optind < argc) { | ||
| 57 | *p++ = argv[optind++]; | ||
| 58 | } | ||
| 59 | ) | ||
| 60 | /* optind points to argv[arvc] (NULL) now. | ||
| 61 | ** FIXME: we assume that getopt will not count options | ||
| 62 | ** possibly present on "-e prog args" and will not | ||
| 63 | ** include them into final value of optind | ||
| 64 | ** which is to be used ... */ | ||
| 41 | } else bb_show_usage(); | 65 | } else bb_show_usage(); |
| 42 | } | 66 | } |
| 43 | } | 67 | argv += optind; /* ... here! */ |
| 44 | 68 | argc -= optind; | |
| 45 | // For listen or file we need zero arguments, dialout is 2. | 69 | // -l and -f don't mix |
| 46 | // For exec we need at least one more argument at the end, more ok | 70 | if (do_listen && cfd) bb_show_usage(); |
| 47 | 71 | // Listen or file modes need zero arguments, client mode needs 2 | |
| 48 | opt = (do_listen || infile) ? 0 : 2 + execflag; | 72 | opt = ((do_listen || cfd) ? 0 : 2); |
| 49 | if (execflag ? argc-optind < opt : argc-optind!=opt || | 73 | if (argc != opt) |
| 50 | (infile && do_listen)) | ||
| 51 | bb_show_usage(); | 74 | bb_show_usage(); |
| 75 | } else { | ||
| 76 | if (argc != 3) bb_show_usage(); | ||
| 77 | argc--; | ||
| 78 | argv++; | ||
| 79 | } | ||
| 52 | 80 | ||
| 53 | if (wsecs) { | 81 | if (wsecs) { |
| 54 | signal(SIGALRM, timeout); | 82 | signal(SIGALRM, timeout); |
| 55 | alarm(wsecs); | 83 | alarm(wsecs); |
| 56 | } | 84 | } |
| 57 | 85 | ||
| 58 | if (infile) cfd = xopen(infile, O_RDWR); | 86 | if (!cfd) { |
| 59 | else { | ||
| 60 | opt = 1; | ||
| 61 | sfd = xsocket(AF_INET, SOCK_STREAM, 0); | 87 | sfd = xsocket(AF_INET, SOCK_STREAM, 0); |
| 62 | fcntl(sfd, F_SETFD, FD_CLOEXEC); | 88 | fcntl(sfd, F_SETFD, FD_CLOEXEC); |
| 63 | setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)); | 89 | opt = 1; |
| 90 | setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); | ||
| 64 | address.sin_family = AF_INET; | 91 | address.sin_family = AF_INET; |
| 65 | 92 | ||
| 66 | // Set local port. | 93 | // Set local port. |
| @@ -82,17 +109,17 @@ int nc_main(int argc, char **argv) | |||
| 82 | getsockname(sfd, &address, &len); | 109 | getsockname(sfd, &address, &len); |
| 83 | fdprintf(2, "%d\n", SWAP_BE16(address.sin_port)); | 110 | fdprintf(2, "%d\n", SWAP_BE16(address.sin_port)); |
| 84 | } | 111 | } |
| 85 | repeatyness: | 112 | repeatyness: |
| 86 | cfd = accept(sfd, (struct sockaddr *) &address, &addrlen); | 113 | cfd = accept(sfd, (struct sockaddr *) &address, &addrlen); |
| 87 | if (cfd < 0) | 114 | if (cfd < 0) |
| 88 | bb_perror_msg_and_die("accept"); | 115 | bb_perror_msg_and_die("accept"); |
| 89 | 116 | ||
| 90 | if (!execflag) close(sfd); | 117 | if (!execparam) close(sfd); |
| 91 | } else { | 118 | } else { |
| 92 | hostinfo = xgethostbyname(argv[optind]); | 119 | hostinfo = xgethostbyname(argv[0]); |
| 93 | 120 | ||
| 94 | address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list; | 121 | address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list; |
| 95 | address.sin_port = bb_lookup_port(argv[optind+1], "tcp", 0); | 122 | address.sin_port = bb_lookup_port(argv[1], "tcp", 0); |
| 96 | 123 | ||
| 97 | if (connect(sfd, (struct sockaddr *) &address, sizeof(address)) < 0) | 124 | if (connect(sfd, (struct sockaddr *) &address, sizeof(address)) < 0) |
| 98 | bb_perror_msg_and_die("connect"); | 125 | bb_perror_msg_and_die("connect"); |
| @@ -106,8 +133,8 @@ repeatyness: | |||
| 106 | } | 133 | } |
| 107 | 134 | ||
| 108 | /* -e given? */ | 135 | /* -e given? */ |
| 109 | if (execflag) { | 136 | if (execparam) { |
| 110 | if(cfd) { | 137 | if (cfd) { |
| 111 | signal(SIGCHLD, SIG_IGN); | 138 | signal(SIGCHLD, SIG_IGN); |
| 112 | dup2(cfd, 0); | 139 | dup2(cfd, 0); |
| 113 | close(cfd); | 140 | close(cfd); |
| @@ -128,7 +155,7 @@ repeatyness: | |||
| 128 | 155 | ||
| 129 | goto repeatyness; | 156 | goto repeatyness; |
| 130 | } | 157 | } |
| 131 | execvp(argv[optind], argv+optind); | 158 | USE_NC_EXTRA(execvp(execparam[0], execparam);) |
| 132 | /* Don't print stuff or it will go over the wire.... */ | 159 | /* Don't print stuff or it will go over the wire.... */ |
| 133 | _exit(127); | 160 | _exit(127); |
| 134 | } | 161 | } |
