Changeset 3621 in MondoRescue for branches/3.3/mindi-busybox/networking/nc_bloaty.c
- Timestamp:
- Dec 20, 2016, 4:07:32 PM (7 years ago)
- Location:
- branches/3.3
- Files:
-
- 1 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/3.3/mindi-busybox/networking/nc_bloaty.c
r3232 r3621 49 49 * on the command line, but accept() says that it came from different addr) 50 50 * are closed, but we don't exit - we continue to listen/accept. 51 * Since bbox 1.22: 52 * - nc exits when _both_ stdin and network are closed. 53 * This makes these two commands: 54 * echo "Yes" | nc 127.0.0.1 1234 55 * echo "no" | nc -lp 1234 56 * exchange their data _and exit_ instead of being stuck. 51 57 */ 52 58 … … 64 70 //usage: IF_NC_SERVER( 65 71 //usage: "\n -l Listen mode, for inbound connects" 72 //usage: "\n -lk With -e, provides persistent server" 73 /* -ll does the same as -lk, but its our extension, while -k is BSD'd, 74 * presumably more widely known. Therefore we advertise it, not -ll. 75 * I would like to drop -ll support, but our "small" nc supports it, 76 * and Rob uses it. 77 */ 66 78 //usage: ) 67 79 //usage: "\n -p PORT Local port" … … 129 141 jmp_buf jbuf; /* timer crud */ 130 142 131 fd_set ding1; /* for select loop */132 fd_set ding2;133 143 char bigbuf_in[BIGSIZ]; /* data buffers */ 134 144 char bigbuf_net[BIGSIZ]; … … 142 152 #define remend (G.remend ) 143 153 #define jbuf (G.jbuf ) 144 #define ding1 (G.ding1 )145 #define ding2 (G.ding2 )146 154 #define bigbuf_in (G.bigbuf_in ) 147 155 #define bigbuf_net (G.bigbuf_net) … … 167 175 OPT_w = (1 << 5), 168 176 OPT_l = (1 << 6) * ENABLE_NC_SERVER, 169 OPT_i = (1 << (6+ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, 170 OPT_o = (1 << (7+ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, 171 OPT_z = (1 << (8+ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, 177 OPT_k = (1 << 7) * ENABLE_NC_SERVER, 178 OPT_i = (1 << (6+2*ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, 179 OPT_o = (1 << (7+2*ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, 180 OPT_z = (1 << (8+2*ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, 172 181 }; 173 182 174 183 #define o_nflag (option_mask32 & OPT_n) 175 184 #define o_udpmode (option_mask32 & OPT_u) 176 #if ENABLE_NC_SERVER177 #define o_listen (option_mask32 & OPT_l)178 #else179 #define o_listen 0180 #endif181 185 #if ENABLE_NC_EXTRA 182 186 #define o_ofile (option_mask32 & OPT_o) … … 299 303 given host/port args, any connections from elsewhere are rejected. This 300 304 in conjunction with local-address binding should limit things nicely... */ 301 static void dolisten( void)305 static void dolisten(int is_persistent, char **proggie) 302 306 { 303 307 int rr; … … 372 376 } else { 373 377 /* TCP */ 378 another: 374 379 arm(o_wait); /* wrap this in a timer, too; 0 = forever */ 375 380 if (setjmp(jbuf) == 0) { … … 406 411 } else 407 412 bb_error_msg_and_die("timeout"); 413 414 if (is_persistent && proggie) { 415 /* -l -k -e PROG */ 416 signal(SIGCHLD, SIG_IGN); /* no zombies please */ 417 if (xvfork() != 0) { 418 /* parent: go back and accept more connections */ 419 close(rr); 420 goto another; 421 } 422 /* child */ 423 signal(SIGCHLD, SIG_DFL); 424 } 425 408 426 xmove_fd(rr, netfd); /* dump the old socket, here's our new one */ 409 427 /* find out what address the connection was *to* on our end, in case we're … … 455 473 free(remhostname); 456 474 } 475 476 if (proggie) 477 doexec(proggie); 457 478 } 458 479 … … 572 593 unsigned rnleft; 573 594 unsigned netretry; /* net-read retry counter */ 574 unsigned wretry; /* net-write sanity counter */ 575 unsigned wfirst; /* one-shot flag to skip first net read */ 595 unsigned fds_open; 576 596 577 597 /* if you don't have all this FD_* macro hair in sys/types.h, you'll have to 578 598 either find it or do your own bit-bashing: *ding1 |= (1 << fd), etc... */ 579 FD_SET(netfd, &ding1); /* global: the net is open */ 599 fd_set ding1; /* for select loop */ 600 fd_set ding2; 601 FD_ZERO(&ding1); 602 FD_SET(netfd, &ding1); 603 FD_SET(STDIN_FILENO, &ding1); 604 fds_open = 2; 605 580 606 netretry = 2; 581 wfirst = 0;582 607 rzleft = rnleft = 0; 583 608 if (o_interval) 584 609 sleep(o_interval); /* pause *before* sending stuff, too */ 585 610 586 errno = 0; /* clear from sleep, close, whatever */587 611 /* and now the big ol' select shoveling loop ... */ 588 while (FD_ISSET(netfd, &ding1)) { /* i.e. till the *net* closes! */ 589 wretry = 8200; /* more than we'll ever hafta write */ 590 if (wfirst) { /* any saved stdin buffer? */ 591 wfirst = 0; /* clear flag for the duration */ 592 goto shovel; /* and go handle it first */ 593 } 612 /* nc 1.10 has "while (FD_ISSET(netfd)" here */ 613 while (fds_open) { 614 unsigned wretry = 8200; /* net-write sanity counter */ 615 594 616 ding2 = ding1; /* FD_COPY ain't portable... */ 595 617 /* some systems, notably linux, crap into their select timers on return, so … … 611 633 from the net during that time, assume it's dead and close it too. */ 612 634 if (rr == 0) { 613 if (!FD_ISSET(STDIN_FILENO, &ding1)) 635 if (!FD_ISSET(STDIN_FILENO, &ding1)) { 614 636 netretry--; /* we actually try a coupla times. */ 615 if (!netretry) { 616 if (o_verbose > 1) /* normally we don't care */ 617 fprintf(stderr, "net timeout\n"); 618 close(netfd); 619 return 0; /* not an error! */ 637 if (!netretry) { 638 if (o_verbose > 1) /* normally we don't care */ 639 fprintf(stderr, "net timeout\n"); 640 /*close(netfd); - redundant, exit will do it */ 641 return 0; /* not an error! */ 642 } 620 643 } 621 644 } /* select timeout */ … … 631 654 bb_perror_msg("net read"); 632 655 } 633 FD_CLR(netfd, &ding1); /* net closed, we'll finish up... */ 656 FD_CLR(netfd, &ding1); /* net closed */ 657 fds_open--; 634 658 rzleft = 0; /* can't write anymore: broken pipe */ 635 659 } else { … … 651 675 mobygrams are kinda fun and exercise the reassembler. */ 652 676 if (rr <= 0) { /* at end, or fukt, or ... */ 653 FD_CLR(STDIN_FILENO, &ding1); /* disable and close stdin */ 654 close(STDIN_FILENO); 655 // Does it make sense to shutdown(net_fd, SHUT_WR) 656 // to let other side know that we won't write anything anymore? 657 // (and what about keeping compat if we do that?) 677 FD_CLR(STDIN_FILENO, &ding1); /* disable stdin */ 678 /*close(STDIN_FILENO); - not really necessary */ 679 /* Let peer know we have no more data */ 680 /* nc 1.10 doesn't do this: */ 681 shutdown(netfd, SHUT_WR); 682 fds_open--; 658 683 } else { 659 684 rzleft = rr; … … 666 691 not sure if the order of this matters, but write net -> stdout first. */ 667 692 668 /* sanity check. Works because they're both unsigned... */669 if ((rzleft > 8200) || (rnleft > 8200)) {670 holler_error("bogus buffers: %u, %u", rzleft, rnleft);671 rzleft = rnleft = 0;672 }673 /* net write retries sometimes happen on UDP connections */674 if (!wretry) { /* is something hung? */675 holler_error("too many output retries");676 return 1;677 }678 693 if (rnleft) { 679 694 rr = write(STDOUT_FILENO, np, rnleft); … … 681 696 if (o_ofile) /* log the stdout */ 682 697 oprint('<', (unsigned char *)np, rr); 683 np += rr; /* fix up ptrs and whatnot */684 rnleft -= rr; /* will get sanity-checked above */685 wrote_out += rr; 698 np += rr; 699 rnleft -= rr; 700 wrote_out += rr; /* global count */ 686 701 } 687 702 Debug("wrote %d to stdout, errno %d", rr, errno); … … 698 713 zp += rr; 699 714 rzleft -= rr; 700 wrote_net += rr; 715 wrote_net += rr; /* global count */ 701 716 } 702 717 Debug("wrote %d to net, errno %d", rr, errno); … … 704 719 if (o_interval) { /* cycle between slow lines, or ... */ 705 720 sleep(o_interval); 706 errno = 0; /* clear from sleep */707 721 continue; /* ...with hairy select loop... */ 708 722 } 709 if ( (rzleft) || (rnleft)) {/* shovel that shit till they ain't */723 if (rzleft || rnleft) { /* shovel that shit till they ain't */ 710 724 wretry--; /* none left, and get another load */ 725 /* net write retries sometimes happen on UDP connections */ 726 if (!wretry) { /* is something hung? */ 727 holler_error("too many output retries"); 728 return 1; 729 } 711 730 goto shovel; 712 731 } 713 } /* while ding1:netfd is open*/732 } /* while (fds_open) */ 714 733 715 734 /* XXX: maybe want a more graceful shutdown() here, or screw around with … … 731 750 char **proggie; 732 751 int x; 752 unsigned cnt_l = 0; 733 753 unsigned o_lport = 0; 734 754 … … 761 781 char *optpos = *proggie + 1; 762 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 784 if (*optpos == 'e' && !optpos[1]) { 765 785 *optpos = '\0'; … … 775 795 776 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 */778 getopt32(argv, "np:s:uvw:" IF_NC_SERVER("l ")797 opt_complementary = "?2:vv:ll:w+"; /* max 2 params; -v and -l are counters; -w N */ 798 getopt32(argv, "np:s:uvw:" IF_NC_SERVER("lk") 779 799 IF_NC_EXTRA("i:o:z"), 780 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 802 argv += optind; 783 803 #if ENABLE_NC_EXTRA … … 785 805 o_interval = xatou_range(str_i, 1, 0xffff); 786 806 #endif 807 #if ENABLE_NC_SERVER 787 808 //if (option_mask32 & OPT_l) /* listen mode */ 809 if (option_mask32 & OPT_k) /* persistent server mode */ 810 cnt_l = 2; 811 #endif 788 812 //if (option_mask32 & OPT_n) /* numeric-only, no DNS lookups */ 789 813 //if (option_mask32 & OPT_o) /* hexdump log */ … … 834 858 socket_want_pktinfo(netfd); 835 859 if (!ENABLE_FEATURE_UNIX_LOCAL 836 || o_listen860 || cnt_l != 0 /* listen */ 837 861 || ouraddr->u.sa.sa_family != AF_UNIX 838 862 ) { … … 840 864 } 841 865 #if 0 842 setsockopt (netfd, SOL_SOCKET, SO_RCVBUF, &o_rcvbuf, sizeofo_rcvbuf);843 setsockopt (netfd, SOL_SOCKET, SO_SNDBUF, &o_sndbuf, sizeofo_sndbuf);866 setsockopt_SOL_SOCKET_int(netfd, SO_RCVBUF, o_rcvbuf); 867 setsockopt_SOL_SOCKET_int(netfd, SO_SNDBUF, o_sndbuf); 844 868 #endif 845 869 … … 853 877 #endif 854 878 855 FD_SET(STDIN_FILENO, &ding1); /* stdin *is* initially open */856 879 if (proggie) { 857 close( 0); /* won't need stdin */880 close(STDIN_FILENO); /* won't need stdin */ 858 881 option_mask32 &= ~OPT_o; /* -o with -e is meaningless! */ 859 882 } … … 863 886 #endif 864 887 865 if ( o_listen) {866 dolisten( );888 if (cnt_l != 0) { 889 dolisten((cnt_l - 1), proggie); 867 890 /* dolisten does its own connect reporting */ 868 if (proggie) /* -e given? */869 doexec(proggie);870 891 x = readwrite(); /* it even works with UDP! */ 871 892 } else {
Note:
See TracChangeset
for help on using the changeset viewer.