Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/networking/nc.c


Ignore:
Timestamp:
Feb 25, 2011, 9:26:54 PM (13 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mindi-busybox/networking/nc.c

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    2 /*  nc: mini-netcat - built from the ground up for LRP
     2/* nc: mini-netcat - built from the ground up for LRP
    33 *
    4  *  Copyright (C) 1998, 1999  Charles P. Wright
    5  *  Copyright (C) 1998  Dave Cinege
     4 * Copyright (C) 1998, 1999  Charles P. Wright
     5 * Copyright (C) 1998  Dave Cinege
    66 *
    7  *  Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    88 */
    99
    1010#include "libbb.h"
    1111
    12 #if ENABLE_DESKTOP
    13 #include "nc_bloaty.c"
     12//config:config NC
     13//config:   bool "nc"
     14//config:   default y
     15//config:   help
     16//config:     A simple Unix utility which reads and writes data across network
     17//config:     connections.
     18//config:
     19//config:config NC_SERVER
     20//config:   bool "Netcat server options (-l)"
     21//config:   default y
     22//config:   depends on NC
     23//config:   help
     24//config:     Allow netcat to act as a server.
     25//config:
     26//config:config NC_EXTRA
     27//config:   bool "Netcat extensions (-eiw and filename)"
     28//config:   default y
     29//config:   depends on NC
     30//config:   help
     31//config:     Add -e (support for executing the rest of the command line after
     32//config:     making or receiving a successful connection), -i (delay interval for
     33//config:     lines sent), -w (timeout for initial connection).
     34//config:
     35//config:config NC_110_COMPAT
     36//config:   bool "Netcat 1.10 compatibility (+2.5k)"
     37//config:   default n  # off specially for Rob
     38//config:   depends on NC
     39//config:   help
     40//config:     This option makes nc closely follow original nc-1.10.
     41//config:     The code is about 2.5k bigger. It enables
     42//config:     -s ADDR, -n, -u, -v, -o FILE, -z options, but loses
     43//config:     busybox-specific extensions: -f FILE and -ll.
     44
     45#if ENABLE_NC_110_COMPAT
     46# include "nc_bloaty.c"
    1447#else
     48
     49//usage:#if !ENABLE_NC_110_COMPAT
     50//usage:
     51//usage:#if ENABLE_NC_SERVER || ENABLE_NC_EXTRA
     52//usage:#define NC_OPTIONS_STR "\n\nOptions:"
     53//usage:#else
     54//usage:#define NC_OPTIONS_STR
     55//usage:#endif
     56//usage:
     57//usage:#define nc_trivial_usage
     58//usage:    IF_NC_EXTRA("[-iN] [-wN] ")IF_NC_SERVER("[-l] [-p PORT] ")
     59//usage:       "["IF_NC_EXTRA("-f FILE|")"IPADDR PORT]"IF_NC_EXTRA(" [-e PROG]")
     60//usage:#define nc_full_usage "\n\n"
     61//usage:       "Open a pipe to IP:PORT" IF_NC_EXTRA(" or FILE")
     62//usage:    NC_OPTIONS_STR
     63//usage:    IF_NC_EXTRA(
     64//usage:     "\n    -e PROG Run PROG after connect"
     65//usage:    IF_NC_SERVER(
     66//usage:     "\n    -l  Listen mode, for inbound connects"
     67//usage:    IF_NC_EXTRA(
     68//usage:     "\n        (use -l twice with -e for persistent server)")
     69//usage:     "\n    -p PORT Local port"
     70//usage:    )
     71//usage:     "\n    -w SEC  Timeout for connect"
     72//usage:     "\n    -i SEC  Delay interval for lines sent"
     73//usage:     "\n    -f FILE Use file (ala /dev/ttyS0) instead of network"
     74//usage:    )
     75//usage:
     76//usage:#define nc_notes_usage ""
     77//usage:    IF_NC_EXTRA(
     78//usage:       "To use netcat as a terminal emulator on a serial port:\n\n"
     79//usage:       "$ stty 115200 -F /dev/ttyS0\n"
     80//usage:       "$ stty raw -echo -ctlecho && nc -f /dev/ttyS0\n"
     81//usage:    )
     82//usage:
     83//usage:#define nc_example_usage
     84//usage:       "$ nc foobar.somedomain.com 25\n"
     85//usage:       "220 foobar ESMTP Exim 3.12 #1 Sat, 15 Apr 2000 00:03:02 -0600\n"
     86//usage:       "help\n"
     87//usage:       "214-Commands supported:\n"
     88//usage:       "214-    HELO EHLO MAIL RCPT DATA AUTH\n"
     89//usage:       "214     NOOP QUIT RSET HELP\n"
     90//usage:       "quit\n"
     91//usage:       "221 foobar closing connection\n"
     92//usage:
     93//usage:#endif
    1594
    1695/* Lots of small differences in features
     
    1897 */
    1998
    20 static void timeout(int signum)
     99static void timeout(int signum UNUSED_PARAM)
    21100{
    22101    bb_error_msg_and_die("timed out");
    23102}
    24103
    25 int nc_main(int argc, char **argv);
     104int nc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
    26105int nc_main(int argc, char **argv)
    27106{
     
    30109    int cfd = 0;
    31110    unsigned lport = 0;
    32     SKIP_NC_SERVER(const) unsigned do_listen = 0;
    33     SKIP_NC_EXTRA (const) unsigned wsecs = 0;
    34     SKIP_NC_EXTRA (const) unsigned delay = 0;
    35     SKIP_NC_EXTRA (const int execparam = 0;)
    36     USE_NC_EXTRA  (char **execparam = NULL;)
    37     len_and_sockaddr *lsa;
     111    IF_NOT_NC_SERVER(const) unsigned do_listen = 0;
     112    IF_NOT_NC_EXTRA (const) unsigned wsecs = 0;
     113    IF_NOT_NC_EXTRA (const) unsigned delay = 0;
     114    IF_NOT_NC_EXTRA (const int execparam = 0;)
     115    IF_NC_EXTRA     (char **execparam = NULL;)
    38116    fd_set readfds, testfds;
    39117    int opt; /* must be signed (getopt returns -1) */
     
    41119    if (ENABLE_NC_SERVER || ENABLE_NC_EXTRA) {
    42120        /* getopt32 is _almost_ usable:
    43         ** it cannot handle "... -e prog -prog-opt" */
     121        ** it cannot handle "... -e PROG -prog-opt" */
    44122        while ((opt = getopt(argc, argv,
    45                 "" USE_NC_SERVER("lp:") USE_NC_EXTRA("w:i:f:e:") )) > 0
     123                "" IF_NC_SERVER("lp:") IF_NC_EXTRA("w:i:f:e:") )) > 0
    46124        ) {
    47             if (ENABLE_NC_SERVER && opt=='l')      USE_NC_SERVER(do_listen++);
    48             else if (ENABLE_NC_SERVER && opt=='p') {
    49                 USE_NC_SERVER(lport = bb_lookup_port(optarg, "tcp", 0));
    50             }
    51             else if (ENABLE_NC_EXTRA && opt=='w') USE_NC_EXTRA( wsecs = xatou(optarg));
    52             else if (ENABLE_NC_EXTRA && opt=='i') USE_NC_EXTRA( delay = xatou(optarg));
    53             else if (ENABLE_NC_EXTRA && opt=='f') USE_NC_EXTRA( cfd = xopen(optarg, O_RDWR));
    54             else if (ENABLE_NC_EXTRA && opt=='e' && optind<=argc) {
     125            if (ENABLE_NC_SERVER && opt == 'l')
     126                IF_NC_SERVER(do_listen++);
     127            else if (ENABLE_NC_SERVER && opt == 'p')
     128                IF_NC_SERVER(lport = bb_lookup_port(optarg, "tcp", 0));
     129            else if (ENABLE_NC_EXTRA && opt == 'w')
     130                IF_NC_EXTRA( wsecs = xatou(optarg));
     131            else if (ENABLE_NC_EXTRA && opt == 'i')
     132                IF_NC_EXTRA( delay = xatou(optarg));
     133            else if (ENABLE_NC_EXTRA && opt == 'f')
     134                IF_NC_EXTRA( cfd = xopen(optarg, O_RDWR));
     135            else if (ENABLE_NC_EXTRA && opt == 'e' && optind <= argc) {
    55136                /* We cannot just 'break'. We should let getopt finish.
    56137                ** Or else we won't be able to find where
    57138                ** 'host' and 'port' params are
    58                 ** (think "nc -w 60 host port -e prog"). */
    59                 USE_NC_EXTRA(
     139                ** (think "nc -w 60 host port -e PROG"). */
     140                IF_NC_EXTRA(
    60141                    char **p;
    61142                    // +2: one for progname (optarg) and one for NULL
     
    69150                /* optind points to argv[arvc] (NULL) now.
    70151                ** FIXME: we assume that getopt will not count options
    71                 ** possibly present on "-e prog args" and will not
     152                ** possibly present on "-e PROG ARGS" and will not
    72153                ** include them into final value of optind
    73154                ** which is to be used ...  */
     
    78159        // -l and -f don't mix
    79160        if (do_listen && cfd) bb_show_usage();
    80         // Listen or file modes need zero arguments, client mode needs 2
    81         if (do_listen || cfd) {
     161        // File mode needs need zero arguments, listen mode needs zero or one,
     162        // client mode needs one or two
     163        if (cfd) {
    82164            if (argc) bb_show_usage();
     165        } else if (do_listen) {
     166            if (argc > 1) bb_show_usage();
    83167        } else {
    84168            if (!argc || argc > 2) bb_show_usage();
     
    97181    if (!cfd) {
    98182        if (do_listen) {
    99             /* create_and_bind_stream_or_die(NULL, lport)
    100              * would've work wonderfully, but we need
    101              * to know lsa */
    102             sfd = xsocket_stream(&lsa);
    103             if (lport)
    104                 set_nport(lsa, htons(lport));
    105             setsockopt_reuseaddr(sfd);
    106             xbind(sfd, &lsa->sa, lsa->len);
     183            sfd = create_and_bind_stream_or_die(argv[0], lport);
    107184            xlisten(sfd, do_listen); /* can be > 1 */
     185#if 0  /* nc-1.10 does not do this (without -v) */
    108186            /* If we didn't specify a port number,
    109187             * query and print it after listen() */
    110188            if (!lport) {
    111                 socklen_t addrlen = lsa->len;
    112                 getsockname(sfd, &lsa->sa, &addrlen);
    113                 lport = get_nport(&lsa->sa);
     189                len_and_sockaddr lsa;
     190                lsa.len = LSA_SIZEOF_SA;
     191                getsockname(sfd, &lsa.u.sa, &lsa.len);
     192                lport = get_nport(&lsa.u.sa);
    114193                fdprintf(2, "%d\n", ntohs(lport));
    115194            }
    116             fcntl(sfd, F_SETFD, FD_CLOEXEC);
     195#endif
     196            close_on_exec_on(sfd);
    117197 accept_again:
    118198            cfd = accept(sfd, NULL, 0);
     
    129209    if (wsecs) {
    130210        alarm(0);
    131         signal(SIGALRM, SIG_DFL);
     211        /* Non-ignored signals revert to SIG_DFL on exec anyway */
     212        /*signal(SIGALRM, SIG_DFL);*/
    132213    }
    133214
    134215    /* -e given? */
    135216    if (execparam) {
    136         signal(SIGCHLD, SIG_IGN);
    137         // With more than one -l, repeatedly act as server.
    138         if (do_listen > 1 && vfork()) {
     217        pid_t pid;
     218        /* With more than one -l, repeatedly act as server */
     219        if (do_listen > 1 && (pid = xvfork()) != 0) {
    139220            /* parent */
    140             // This is a bit weird as cleanup goes, since we wind up with no
    141             // stdin/stdout/stderr.  But it's small and shouldn't hurt anything.
    142             // We check for cfd == 0 above.
    143             logmode = LOGMODE_NONE;
    144             close(0);
    145             close(1);
    146             close(2);
     221            /* prevent zombies */
     222            signal(SIGCHLD, SIG_IGN);
     223            close(cfd);
    147224            goto accept_again;
    148225        }
    149         /* child (or main thread if no multiple -l) */
    150         if (cfd) {
    151             dup2(cfd, 0);
    152             close(cfd);
    153         }
    154         dup2(0, 1);
    155         dup2(0, 2);
    156         USE_NC_EXTRA(BB_EXECVP(execparam[0], execparam);)
    157         /* Don't print stuff or it will go over the wire.... */
     226        /* child, or main thread if only one -l */
     227        xmove_fd(cfd, 0);
     228        xdup2(0, 1);
     229        xdup2(0, 2);
     230        IF_NC_EXTRA(BB_EXECVP(execparam[0], execparam);)
     231        /* Don't print stuff or it will go over the wire... */
    158232        _exit(127);
    159233    }
    160234
    161     // Select loop copying stdin to cfd, and cfd to stdout.
     235    /* Select loop copying stdin to cfd, and cfd to stdout */
    162236
    163237    FD_ZERO(&readfds);
     
    172246        testfds = readfds;
    173247
    174         if (select(FD_SETSIZE, &testfds, NULL, NULL, NULL) < 0)
     248        if (select(cfd + 1, &testfds, NULL, NULL, NULL) < 0)
    175249            bb_perror_msg_and_die("select");
    176250
    177251#define iobuf bb_common_bufsiz1
    178         for (fd = 0; fd < FD_SETSIZE; fd++) {
     252        fd = STDIN_FILENO;
     253        while (1) {
    179254            if (FD_ISSET(fd, &testfds)) {
    180255                nread = safe_read(fd, iobuf, sizeof(iobuf));
    181256                if (fd == cfd) {
    182257                    if (nread < 1)
    183                         exit(0);
     258                        exit(EXIT_SUCCESS);
    184259                    ofd = STDOUT_FILENO;
    185260                } else {
    186                     if (nread<1) {
    187                         // Close outgoing half-connection so they get EOF, but
    188                         // leave incoming alone so we can see response.
     261                    if (nread < 1) {
     262                        /* Close outgoing half-connection so they get EOF,
     263                         * but leave incoming alone so we can see response */
    189264                        shutdown(cfd, 1);
    190265                        FD_CLR(STDIN_FILENO, &readfds);
     
    193268                }
    194269                xwrite(ofd, iobuf, nread);
    195                 if (delay > 0) sleep(delay);
     270                if (delay > 0)
     271                    sleep(delay);
    196272            }
     273            if (fd == cfd)
     274                break;
     275            fd = cfd;
    197276        }
    198277    }
Note: See TracChangeset for help on using the changeset viewer.