zcip: fix unaligned trap on ARM
[oweals/busybox.git] / networking / nc_bloaty.c
index 173f5a8677d78e552293b22418f4ba9b3b8a4c67..ab82465310c6914b7b387380304150833006eb5f 100644 (file)
@@ -48,7 +48,7 @@
  *   are closed, but nc doesn't exit - continues to listen/accept.
  */
 
-/* done in nc.c: #include "busybox.h" */
+/* done in nc.c: #include "libbb.h" */
 
 enum {
        SLEAZE_PORT = 31337,               /* for UDP-scan RTT trick, change if ya want */
@@ -149,29 +149,34 @@ enum {
 /* Debug: squirt whatever message and sleep a bit so we can see it go by. */
 /* Beware: writes to stdOUT... */
 #if 0
-#define Debug(...) do { printf(__VA_ARGS__); printf("\n"); fflush(stdout); sleep(1); } while(0)
+#define Debug(...) do { printf(__VA_ARGS__); printf("\n"); fflush(stdout); sleep(1); } while (0)
 #else
-#define Debug(...) do { } while(0)
+#define Debug(...) do { } while (0)
 #endif
 
-#define holler_error(...)  do { if (o_verbose) bb_error_msg(__VA_ARGS__); } while(0)
-#define holler_perror(...) do { if (o_verbose) bb_perror_msg(__VA_ARGS__); } while(0)
+#define holler_error(...)  do { if (o_verbose) bb_error_msg(__VA_ARGS__); } while (0)
+#define holler_perror(...) do { if (o_verbose) bb_perror_msg(__VA_ARGS__); } while (0)
 
 /* catch: no-brainer interrupt handler */
 static void catch(int sig)
 {
-       errno = 0;
        if (o_verbose > 1)                /* normally we don't care */
                fprintf(stderr, SENT_N_RECV_M, wrote_net, wrote_out);
        fprintf(stderr, "punt!\n");
        exit(1);
 }
 
-/* timeout and other signal handling cruft */
-static void tmtravel(int sig)
+/* unarm  */
+static void unarm(void)
 {
        signal(SIGALRM, SIG_IGN);
        alarm(0);
+}
+
+/* timeout and other signal handling cruft */
+static void tmtravel(int sig)
+{
+       unarm();
        longjmp(jbuf, 1);
 }
 
@@ -182,13 +187,6 @@ static void arm(unsigned secs)
        alarm(secs);
 }
 
-/* unarm  */
-static void unarm(void)
-{
-       signal(SIGALRM, SIG_IGN);
-       alarm(0);
-}
-
 /* findline:
  find the next newline in a buffer; return inclusive size of that "line",
  or the entire buffer size, so the caller knows how much to then write().
@@ -246,11 +244,11 @@ static int connect_w_timeout(int fd)
        arm(o_wait);
        if (setjmp(jbuf) == 0) {
                rr = connect(fd, &themaddr->sa, themaddr->len);
+               unarm();
        } else { /* setjmp: connect failed... */
                rr = -1;
                errno = ETIMEDOUT; /* fake it */
        }
-       unarm();
        return rr;
 }
 
@@ -280,7 +278,7 @@ static void dolisten(void)
                rr = getsockname(netfd, &ouraddr->sa, &ouraddr->len);
                if (rr < 0)
                        bb_perror_msg_and_die("getsockname after bind");
-               addr = xmalloc_sockaddr2dotted(&ouraddr->sa, ouraddr->len);
+               addr = xmalloc_sockaddr2dotted(&ouraddr->sa);
                fprintf(stderr, "listening on %s ...\n", addr);
                free(addr);
        }
@@ -319,9 +317,9 @@ static void dolisten(void)
                                &remend.sa, &ouraddr->sa, ouraddr->len);
                        if (rr < 0)
                                bb_perror_msg_and_die("recvfrom");
+                       unarm();
                } else
                        bb_error_msg_and_die("timeout");
-               unarm();
 /* Now we learned *to which IP* peer has connected, and we want to anchor
 our socket on it, so that our outbound packets will have correct local IP.
 Unfortunately, bind() on already bound socket will fail now (EINVAL):
@@ -343,17 +341,16 @@ create new one, and bind() it. TODO */
                                /* nc 1.10 bails out instead, and its error message
                                 * is not suppressed by o_verbose */
                                if (o_verbose) {
-                                       char *remaddr = xmalloc_sockaddr2dotted(&remend.sa, remend.len);
+                                       char *remaddr = xmalloc_sockaddr2dotted(&remend.sa);
                                        bb_error_msg("connect from wrong ip/port %s ignored", remaddr);
                                        free(remaddr);
                                }
                                close(rr);
                                goto again;
                        }
-                       
+                       unarm();
                } else
                        bb_error_msg_and_die("timeout");
-               unarm();
                xmove_fd(rr, netfd); /* dump the old socket, here's our new one */
                /* find out what address the connection was *to* on our end, in case we're
                 doing a listen-on-any on a multihomed machine.  This allows one to
@@ -396,9 +393,9 @@ create new one, and bind() it. TODO */
         accept the connection and then reject undesireable ones by closing.
         In other words, we need a TCP MSG_PEEK. */
        /* bbox: removed most of it */
-               lcladdr = xmalloc_sockaddr2dotted(&ouraddr->sa, ouraddr->len);
-               remaddr = xmalloc_sockaddr2dotted(&remend.sa, remend.len);
-               remhostname = o_nflag ? remaddr : xmalloc_sockaddr2host(&remend.sa, remend.len);
+               lcladdr = xmalloc_sockaddr2dotted(&ouraddr->sa);
+               remaddr = xmalloc_sockaddr2dotted(&remend.sa);
+               remhostname = o_nflag ? remaddr : xmalloc_sockaddr2host(&remend.sa);
                fprintf(stderr, "connect to %s from %s (%s)\n",
                                lcladdr, remhostname, remaddr);
                free(lcladdr);
@@ -462,68 +459,54 @@ int udptest(void);
  what when.  Adapted from dgaudet's original example -- but must be ripping
  *fast*, since we don't want to be too disk-bound... */
 #if ENABLE_NC_EXTRA
-static void oprint(int direction, unsigned char *p, int bc)
+static void oprint(int direction, unsigned char *p, unsigned bc)
 {
-       int obc;                /* current "global" offset */
-       int soc;                /* stage write count */
+       unsigned obc;           /* current "global" offset */
+       unsigned x;
        unsigned char *op;      /* out hexdump ptr */
-       unsigned char *a;       /* out asc-dump ptr */
-       int x;
+       unsigned char *ap;      /* out asc-dump ptr */
        unsigned char stage[100];
 
        if (bc == 0)
                return;
 
-       op = stage;
        obc = wrote_net; /* use the globals! */
        if (direction == '<')
                obc = wrote_out;
-       *op++ = direction;
-       *op = ' ';
-       stage[59] = '#';                /* preload separator */
+       stage[0] = direction;
+       stage[59] = '#'; /* preload separator */
        stage[60] = ' ';
 
-       while (bc) {                        /* for chunk-o-data ... */
+       do {    /* for chunk-o-data ... */
                x = 16;
-               soc = 78;                        /* len of whole formatted line */
-               if (bc < x) {
-                       soc = soc - 16 + bc;        /* fiddle for however much is left */
-                       x = (bc * 3) + 11;        /* 2 digits + space per, after D & offset */
-                       op = &stage[x];
-                       x = 16 - bc;
-                       while (x) {
-                               *op++ = ' ';                /* preload filler spaces */
-                               *op++ = ' ';
-                               *op++ = ' ';
-                               x--;
-                       }
-                       x = bc;                        /* re-fix current linecount */
-               } /* if bc < x */
-
-               bc -= x;                        /* fix wrt current line size */
-               sprintf(&stage[2], "%8.8x ", obc);                /* xxx: still slow? */
-               obc += x;                        /* fix current offset */
-               op = &stage[11];                /* where hex starts */
-               a = &stage[61];                /* where ascii starts */
+               if (bc < 16) {
+                       /* memset(&stage[bc*3 + 11], ' ', 16*3 - bc*3); */
+                       memset(&stage[11], ' ', 16*3);
+                       x = bc;
+               }
+               sprintf(&stage[1], " %8.8x ", obc);  /* xxx: still slow? */
+               bc -= x;          /* fix current count */
+               obc += x;         /* fix current offset */
+               op = &stage[11];  /* where hex starts */
+               ap = &stage[61];  /* where ascii starts */
 
-               while (x) {  /* for line of dump, however long ... */
+               do {  /* for line of dump, however long ... */
                        *op++ = 0x20 | bb_hexdigits_upcase[*p >> 4];
                        *op++ = 0x20 | bb_hexdigits_upcase[*p & 0x0f];
                        *op++ = ' ';
                        if ((*p > 31) && (*p < 127))
-                               *a = *p;                /* printing */
+                               *ap = *p;   /* printing */
                        else
-                               *a = '.';                /* nonprinting, loose def */
-                       a++;
+                               *ap = '.';  /* nonprinting, loose def */
+                       ap++;
                        p++;
-                       x--;
-               } /* while x */
-               *a = '\n';                        /* finish the line */
-               xwrite(ofd, stage, soc);
-       } /* while bc */
+               } while (--x);
+               *ap++ = '\n';  /* finish the line */
+               xwrite(ofd, stage, ap - stage);
+       } while (bc);
 }
 #else
-void oprint(int direction, unsigned char *p, int bc);
+void oprint(int direction, unsigned char *p, unsigned bc);
 #endif
 
 /* readwrite:
@@ -720,10 +703,10 @@ int nc_main(int argc, char **argv)
        }
        proggie = NULL;
  e_found:
-               
+
        // -g -G -t -r deleted, unimplemented -a deleted too
        opt_complementary = "?2:vv"; /* max 2 params, -v is a counter */
-       getopt32(argc, argv, "hnp:s:uvw:" USE_NC_SERVER("l")
+       getopt32(argv, "hnp:s:uvw:" USE_NC_SERVER("l")
                        USE_NC_EXTRA("i:o:z"),
                        &str_p, &str_s, &str_w
                        USE_NC_EXTRA(, &str_i, &str_o, &o_verbose));
@@ -751,6 +734,13 @@ int nc_main(int argc, char **argv)
        /* We manage our fd's so that they are never 0,1,2 */
        /*bb_sanitize_stdio(); - not needed */
 
+       if (argv[0]) {
+               themaddr = xhost2sockaddr(argv[0],
+                       argv[1]
+                       ? bb_lookup_port(argv[1], o_udpmode ? "udp" : "tcp", 0)
+                       : 0);
+       }
+
        /* create & bind network socket */
        x = (o_udpmode ? SOCK_DGRAM : SOCK_STREAM);
        if (option_mask32 & OPT_s) { /* local address */
@@ -758,7 +748,11 @@ int nc_main(int argc, char **argv)
                ouraddr = xhost2sockaddr(str_s, o_lport);
                x = xsocket(ouraddr->sa.sa_family, x, 0);
        } else {
-               x = xsocket_type(&ouraddr, x);
+               /* We try IPv6, then IPv4, unless addr family is
+                * implicitly set by way of remote addr/port spec */
+               x = xsocket_type(&ouraddr,
+                               USE_FEATURE_IPV6((themaddr ? themaddr->sa.sa_family : AF_UNSPEC),)
+                               x);
                if (o_lport)
                        set_nport(ouraddr, htons(o_lport));
        }
@@ -789,14 +783,6 @@ int nc_main(int argc, char **argv)
                xmove_fd(xopen(str_o, O_WRONLY|O_CREAT|O_TRUNC), ofd);
 #endif
 
-       if (argv[0]) {
-               themaddr = xhost2sockaddr(argv[0],
-                       argv[1]
-                       ? bb_lookup_port(argv[1], o_udpmode ? "udp" : "tcp", 0)
-                       : 0);
-///what if sa_family won't match??
-       }
-
        if (o_listen) {
                dolisten();
                /* dolisten does its own connect reporting */
@@ -810,7 +796,7 @@ int nc_main(int argc, char **argv)
 
                remend = *themaddr;
                if (o_verbose)
-                       themdotted = xmalloc_sockaddr2dotted(&themaddr->sa, themaddr->len);
+                       themdotted = xmalloc_sockaddr2dotted(&themaddr->sa);
 
                x = connect_w_timeout(netfd);
                if (o_zero && x == 0 && o_udpmode)        /* if UDP scanning... */