diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2013-02-28 12:20:06 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2013-02-28 12:20:06 +0100 |
commit | de6f14800675cd0401106876da81da7618de71c6 (patch) | |
tree | a242691aeeed2023f8c840de0a512e9e941c814b /networking/nc_bloaty.c | |
parent | a14f319805c288db25cc9feac3048d89f3d7b41a (diff) | |
download | busybox-w32-de6f14800675cd0401106876da81da7618de71c6.tar.gz busybox-w32-de6f14800675cd0401106876da81da7618de71c6.tar.bz2 busybox-w32-de6f14800675cd0401106876da81da7618de71c6.zip |
nc_bloaty: support -ll and -lk. Closes 2245
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/nc_bloaty.c')
-rw-r--r-- | networking/nc_bloaty.c | 58 |
1 files changed, 40 insertions, 18 deletions
diff --git a/networking/nc_bloaty.c b/networking/nc_bloaty.c index 62a025116..00ba6f114 100644 --- a/networking/nc_bloaty.c +++ b/networking/nc_bloaty.c | |||
@@ -63,6 +63,12 @@ | |||
63 | //usage: " -e PROG Run PROG after connect (must be last)" | 63 | //usage: " -e PROG Run PROG after connect (must be last)" |
64 | //usage: IF_NC_SERVER( | 64 | //usage: IF_NC_SERVER( |
65 | //usage: "\n -l Listen mode, for inbound connects" | 65 | //usage: "\n -l Listen mode, for inbound connects" |
66 | //usage: "\n -lk With -e, provides persistent server" | ||
67 | /* -ll does the same as -lk, but its our extension, while -k is BSD'd, | ||
68 | * presumably more widely known. Therefore we advertise it, not -ll. | ||
69 | * I would like to drop -ll support, but our "small" nc supports it, | ||
70 | * and Rob uses it. | ||
71 | */ | ||
66 | //usage: ) | 72 | //usage: ) |
67 | //usage: "\n -p PORT Local port" | 73 | //usage: "\n -p PORT Local port" |
68 | //usage: "\n -s ADDR Local address" | 74 | //usage: "\n -s ADDR Local address" |
@@ -166,18 +172,14 @@ enum { | |||
166 | OPT_v = (1 << 4), | 172 | OPT_v = (1 << 4), |
167 | OPT_w = (1 << 5), | 173 | OPT_w = (1 << 5), |
168 | OPT_l = (1 << 6) * ENABLE_NC_SERVER, | 174 | OPT_l = (1 << 6) * ENABLE_NC_SERVER, |
169 | OPT_i = (1 << (6+ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, | 175 | OPT_k = (1 << 7) * ENABLE_NC_SERVER, |
170 | OPT_o = (1 << (7+ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, | 176 | OPT_i = (1 << (7+2*ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, |
171 | OPT_z = (1 << (8+ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, | 177 | OPT_o = (1 << (8+2*ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, |
178 | OPT_z = (1 << (9+2*ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, | ||
172 | }; | 179 | }; |
173 | 180 | ||
174 | #define o_nflag (option_mask32 & OPT_n) | 181 | #define o_nflag (option_mask32 & OPT_n) |
175 | #define o_udpmode (option_mask32 & OPT_u) | 182 | #define o_udpmode (option_mask32 & OPT_u) |
176 | #if ENABLE_NC_SERVER | ||
177 | #define o_listen (option_mask32 & OPT_l) | ||
178 | #else | ||
179 | #define o_listen 0 | ||
180 | #endif | ||
181 | #if ENABLE_NC_EXTRA | 183 | #if ENABLE_NC_EXTRA |
182 | #define o_ofile (option_mask32 & OPT_o) | 184 | #define o_ofile (option_mask32 & OPT_o) |
183 | #define o_zero (option_mask32 & OPT_z) | 185 | #define o_zero (option_mask32 & OPT_z) |
@@ -298,7 +300,7 @@ static int connect_w_timeout(int fd) | |||
298 | incoming and returns an open connection *from* someplace. If we were | 300 | incoming and returns an open connection *from* someplace. If we were |
299 | given host/port args, any connections from elsewhere are rejected. This | 301 | given host/port args, any connections from elsewhere are rejected. This |
300 | in conjunction with local-address binding should limit things nicely... */ | 302 | in conjunction with local-address binding should limit things nicely... */ |
301 | static void dolisten(void) | 303 | static void dolisten(int is_persistent, char **proggie) |
302 | { | 304 | { |
303 | int rr; | 305 | int rr; |
304 | 306 | ||
@@ -371,6 +373,7 @@ create new one, and bind() it. TODO */ | |||
371 | xconnect(netfd, &remend.u.sa, ouraddr->len); | 373 | xconnect(netfd, &remend.u.sa, ouraddr->len); |
372 | } else { | 374 | } else { |
373 | /* TCP */ | 375 | /* TCP */ |
376 | another: | ||
374 | arm(o_wait); /* wrap this in a timer, too; 0 = forever */ | 377 | arm(o_wait); /* wrap this in a timer, too; 0 = forever */ |
375 | if (setjmp(jbuf) == 0) { | 378 | if (setjmp(jbuf) == 0) { |
376 | again: | 379 | again: |
@@ -405,6 +408,19 @@ create new one, and bind() it. TODO */ | |||
405 | unarm(); | 408 | unarm(); |
406 | } else | 409 | } else |
407 | bb_error_msg_and_die("timeout"); | 410 | bb_error_msg_and_die("timeout"); |
411 | |||
412 | if (is_persistent && proggie) { | ||
413 | /* -l -k -e PROG */ | ||
414 | signal(SIGCHLD, SIG_IGN); /* no zombies please */ | ||
415 | if (xvfork() != 0) { | ||
416 | /* parent: go back and accept more connections */ | ||
417 | close(rr); | ||
418 | goto another; | ||
419 | } | ||
420 | /* child */ | ||
421 | signal(SIGCHLD, SIG_DFL); | ||
422 | } | ||
423 | |||
408 | xmove_fd(rr, netfd); /* dump the old socket, here's our new one */ | 424 | xmove_fd(rr, netfd); /* dump the old socket, here's our new one */ |
409 | /* find out what address the connection was *to* on our end, in case we're | 425 | /* find out what address the connection was *to* on our end, in case we're |
410 | doing a listen-on-any on a multihomed machine. This allows one to | 426 | doing a listen-on-any on a multihomed machine. This allows one to |
@@ -454,6 +470,9 @@ create new one, and bind() it. TODO */ | |||
454 | if (!o_nflag) | 470 | if (!o_nflag) |
455 | free(remhostname); | 471 | free(remhostname); |
456 | } | 472 | } |
473 | |||
474 | if (proggie) | ||
475 | doexec(proggie); | ||
457 | } | 476 | } |
458 | 477 | ||
459 | /* udptest: | 478 | /* udptest: |
@@ -730,6 +749,7 @@ int nc_main(int argc UNUSED_PARAM, char **argv) | |||
730 | char *themdotted = themdotted; /* for compiler */ | 749 | char *themdotted = themdotted; /* for compiler */ |
731 | char **proggie; | 750 | char **proggie; |
732 | int x; | 751 | int x; |
752 | unsigned cnt_l = 0; | ||
733 | unsigned o_lport = 0; | 753 | unsigned o_lport = 0; |
734 | 754 | ||
735 | INIT_G(); | 755 | INIT_G(); |
@@ -760,7 +780,7 @@ int nc_main(int argc UNUSED_PARAM, char **argv) | |||
760 | if (proggie[0][0] == '-') { | 780 | if (proggie[0][0] == '-') { |
761 | char *optpos = *proggie + 1; | 781 | char *optpos = *proggie + 1; |
762 | /* Skip all valid opts w/o params */ | 782 | /* Skip all valid opts w/o params */ |
763 | optpos = optpos + strspn(optpos, "nuv"IF_NC_SERVER("l")IF_NC_EXTRA("z")); | 783 | optpos = optpos + strspn(optpos, "nuv"IF_NC_SERVER("lk")IF_NC_EXTRA("z")); |
764 | if (*optpos == 'e' && !optpos[1]) { | 784 | if (*optpos == 'e' && !optpos[1]) { |
765 | *optpos = '\0'; | 785 | *optpos = '\0'; |
766 | proggie++; | 786 | proggie++; |
@@ -774,17 +794,21 @@ int nc_main(int argc UNUSED_PARAM, char **argv) | |||
774 | e_found: | 794 | e_found: |
775 | 795 | ||
776 | // -g -G -t -r deleted, unimplemented -a deleted too | 796 | // -g -G -t -r deleted, unimplemented -a deleted too |
777 | opt_complementary = "?2:vv:w+"; /* max 2 params; -v is a counter; -w N */ | 797 | opt_complementary = "?2:vv:ll:w+"; /* max 2 params; -v and -l are counters; -w N */ |
778 | getopt32(argv, "np:s:uvw:" IF_NC_SERVER("l") | 798 | getopt32(argv, "np:s:uvw:" IF_NC_SERVER("lk") |
779 | IF_NC_EXTRA("i:o:z"), | 799 | IF_NC_EXTRA("i:o:z"), |
780 | &str_p, &str_s, &o_wait | 800 | &str_p, &str_s, &o_wait |
781 | IF_NC_EXTRA(, &str_i, &str_o), &o_verbose); | 801 | IF_NC_EXTRA(, &str_i, &str_o), &o_verbose IF_NC_SERVER(, &cnt_l)); |
782 | argv += optind; | 802 | argv += optind; |
783 | #if ENABLE_NC_EXTRA | 803 | #if ENABLE_NC_EXTRA |
784 | if (option_mask32 & OPT_i) /* line-interval time */ | 804 | if (option_mask32 & OPT_i) /* line-interval time */ |
785 | o_interval = xatou_range(str_i, 1, 0xffff); | 805 | o_interval = xatou_range(str_i, 1, 0xffff); |
786 | #endif | 806 | #endif |
807 | #if ENABLE_NC_SERVER | ||
787 | //if (option_mask32 & OPT_l) /* listen mode */ | 808 | //if (option_mask32 & OPT_l) /* listen mode */ |
809 | if (option_mask32 & OPT_k) /* persistent server mode */ | ||
810 | cnt_l = 2; | ||
811 | #endif | ||
788 | //if (option_mask32 & OPT_n) /* numeric-only, no DNS lookups */ | 812 | //if (option_mask32 & OPT_n) /* numeric-only, no DNS lookups */ |
789 | //if (option_mask32 & OPT_o) /* hexdump log */ | 813 | //if (option_mask32 & OPT_o) /* hexdump log */ |
790 | if (option_mask32 & OPT_p) { /* local source port */ | 814 | if (option_mask32 & OPT_p) { /* local source port */ |
@@ -833,7 +857,7 @@ int nc_main(int argc UNUSED_PARAM, char **argv) | |||
833 | if (o_udpmode) | 857 | if (o_udpmode) |
834 | socket_want_pktinfo(netfd); | 858 | socket_want_pktinfo(netfd); |
835 | if (!ENABLE_FEATURE_UNIX_LOCAL | 859 | if (!ENABLE_FEATURE_UNIX_LOCAL |
836 | || o_listen | 860 | || cnt_l != 0 /* listen */ |
837 | || ouraddr->u.sa.sa_family != AF_UNIX | 861 | || ouraddr->u.sa.sa_family != AF_UNIX |
838 | ) { | 862 | ) { |
839 | xbind(netfd, &ouraddr->u.sa, ouraddr->len); | 863 | xbind(netfd, &ouraddr->u.sa, ouraddr->len); |
@@ -862,11 +886,9 @@ int nc_main(int argc UNUSED_PARAM, char **argv) | |||
862 | xmove_fd(xopen(str_o, O_WRONLY|O_CREAT|O_TRUNC), ofd); | 886 | xmove_fd(xopen(str_o, O_WRONLY|O_CREAT|O_TRUNC), ofd); |
863 | #endif | 887 | #endif |
864 | 888 | ||
865 | if (o_listen) { | 889 | if (cnt_l != 0) { |
866 | dolisten(); | 890 | dolisten((cnt_l - 1), proggie); |
867 | /* dolisten does its own connect reporting */ | 891 | /* dolisten does its own connect reporting */ |
868 | if (proggie) /* -e given? */ | ||
869 | doexec(proggie); | ||
870 | x = readwrite(); /* it even works with UDP! */ | 892 | x = readwrite(); /* it even works with UDP! */ |
871 | } else { | 893 | } else { |
872 | /* Outbound connects. Now we're more picky about args... */ | 894 | /* Outbound connects. Now we're more picky about args... */ |