traceroute: code shrink

Move init code to a separate function.

function                                             old     new   delta
traceroute_init                                        -    1203   +1203
common_traceroute_main                              3391    2141   -1250
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 0/1 up/down: 1203/-1250)        Total: -47 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
diff --git a/networking/traceroute.c b/networking/traceroute.c
index 588570f..e6afdd8 100644
--- a/networking/traceroute.c
+++ b/networking/traceroute.c
@@ -394,8 +394,12 @@
 	int packlen;                    /* total length of packet */
 	int pmtu;                       /* Path MTU Discovery (RFC1191) */
 	uint32_t ident;
-	uint16_t port; // 33434;        /* start udp dest port # for probe packets */
-	int waittime; // 5;             /* time to wait for response (in seconds) */
+	uint16_t port;                  /* start udp dest port # for probe packets */
+	int waittime;                   /* time to wait for response (in seconds) */
+	int first_ttl;
+	int nprobes;
+	unsigned pausemsecs;
+	int max_ttl;
 	unsigned char recv_pkt[512];    /* last inbound (icmp) packet */
 };
 
@@ -412,8 +416,6 @@
 #define gwlist    (G.gwlist   )
 #define INIT_G() do { \
 	SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
-	port = 33434; \
-	waittime = 5; \
 } while (0)
 
 #define outudp   ((struct udphdr *)(outip + 1))
@@ -862,22 +864,16 @@
 	printf("  %u.%03u ms", tt / 1000, tt % 1000);
 }
 
-/*
- * Usage: [-dFIlnrvx] [-g gateway] [-i iface] [-f first_ttl]
- * [-m max_ttl] [ -p port] [-q nqueries] [-s src_addr] [-t tos]
- * [-w waittime] [-z pausemsecs] host [packetlen]"
+/* Keeping init code in a separate (not inlined!) function
+ * for stack use reduction and better register allocation in main loop.
  */
-static int
-common_traceroute_main(int op, char **argv)
+static NOINLINE void
+traceroute_init(int op, char **argv)
 {
 	int minpacket;
 #ifdef IP_TOS
 	int tos = 0;
 #endif
-	int max_ttl = 30;
-	int nprobes = 3;
-	int first_ttl = 1;
-	unsigned pausemsecs = 0;
 	char *source;
 	char *device;
 	char *tos_str;
@@ -893,14 +889,16 @@
 #else
 	enum { af = AF_INET };
 #endif
-	int ttl;
-	int seq;
-	struct sockaddr *lastaddr;
 
 	/* Ensure the socket fds won't be 0, 1 or 2 */
 	bb_sanitize_stdio();
 
 	INIT_G();
+	port = 33434;
+	waittime = 5;
+	G.first_ttl = 1;
+	G.nprobes = 3;
+	G.max_ttl = 30;
 
 	op |= getopt32(argv, "^"
 		OPT_STRING
@@ -919,17 +917,17 @@
 		tos = xatou_range(tos_str, 0, 255);
 #endif
 	if (op & OPT_MAX_TTL)
-		max_ttl = xatou_range(max_ttl_str, 1, 255);
+		G.max_ttl = xatou_range(max_ttl_str, 1, 255);
 	if (op & OPT_PORT)
 		port = xatou16(port_str);
 	if (op & OPT_NPROBES)
-		nprobes = xatou_range(nprobes_str, 1, INT_MAX);
+		G.nprobes = xatou_range(nprobes_str, 1, INT_MAX);
 	if (op & OPT_WAITTIME)
 		waittime = xatou_range(waittime_str, 1, 24 * 60 * 60);
 	if (op & OPT_PAUSE_MS)
-		pausemsecs = xatou_range(pausemsecs_str, 0, 60 * 60 * 1000);
+		G.pausemsecs = xatou_range(pausemsecs_str, 0, 60 * 60 * 1000);
 	if (op & OPT_FIRST_TTL)
-		first_ttl = xatou_range(first_ttl_str, 1, max_ttl);
+		G.first_ttl = xatou_range(first_ttl_str, 1, G.max_ttl);
 
 	/* Process destination and optional packet size */
 	minpacket = sizeof(struct ip)
@@ -961,6 +959,9 @@
 #else
 	dest_lsa = xhost2sockaddr(argv[0], port);
 #endif
+	G.from_lsa = xmemdup(dest_lsa, LSA_LEN_SIZE + dest_lsa->len);
+	G.to = xzalloc(dest_lsa->len);
+
 	packlen = minpacket;
 	if (argv[1])
 		packlen = xatoul_range(argv[1], minpacket, 32 * 1024);
@@ -1102,20 +1103,28 @@
 
 	if (op & OPT_SOURCE)
 		printf(" from %s", source);
-	printf(", %d hops max, %d byte packets\n", max_ttl, packlen);
+	printf(", %d hops max, %d byte packets\n", G.max_ttl, packlen);
+}
+
+static int
+common_traceroute_main(int op, char **argv)
+{
+	int ttl;
+	int seq;
+	struct sockaddr *lastaddr;
+
+	traceroute_init(op, argv);
 
 	lastaddr = xzalloc(dest_lsa->len);
-	G.from_lsa = xmemdup(dest_lsa, LSA_LEN_SIZE + dest_lsa->len);
-	G.to = xzalloc(dest_lsa->len);
 	seq = 0;
-	for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
+	for (ttl = G.first_ttl; ttl <= G.max_ttl; ++ttl) {
 		int probe;
 		int unreachable = 0; /* counter */
 		int gotlastaddr = 0; /* flags */
 		int got_there = 0;
 
 		printf("%2d", ttl);
-		for (probe = 0; probe < nprobes; ++probe) {
+		for (probe = 0; probe < G.nprobes; ++probe) {
 			int read_len;
 			unsigned t1;
 			unsigned t2;
@@ -1123,14 +1132,15 @@
 
 			fflush_all();
 			if (probe != 0)
-				msleep(pausemsecs);
+				msleep(G.pausemsecs);
 
 			send_probe(++seq, ttl);
 			t2 = t1 = monotonic_us();
 
 			left_ms = waittime * 1000;
-			/* NB: wait_for_reply() fills "G.from_lsa" and "G.to"
-			 * with "where it came from" and "to which local address it arrived".
+			/* NB: wait_for_reply() fills "G.from_lsa" and "G.to" with
+			 * "where it came from" and "what local address it arrived to"
+			 * addresses.
 			 */
 			while ((read_len = wait_for_reply(&t2, &left_ms)) != 0) {
 				int icmp_code;
@@ -1255,7 +1265,7 @@
 
 		bb_putchar('\n');
 		if (got_there
-		 || (unreachable > 0 && unreachable >= nprobes - 1)
+		 || (unreachable > 0 && unreachable >= G.nprobes - 1)
 		) {
 			break;
 		}