grep: add proper support for pattern_list
[oweals/busybox.git] / networking / netstat.c
index 2a83af3ace7fac2ec187367a892b50cacee4a43d..c7934423ba0da9b08db41d338375b1e519e86929 100644 (file)
  *
  * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  */
+//config:config NETSTAT
+//config:      bool "netstat (10 kb)"
+//config:      default y
+//config:      select PLATFORM_LINUX
+//config:      help
+//config:      netstat prints information about the Linux networking subsystem.
+//config:
+//config:config FEATURE_NETSTAT_WIDE
+//config:      bool "Enable wide output"
+//config:      default y
+//config:      depends on NETSTAT
+//config:      help
+//config:      Add support for wide columns. Useful when displaying IPv6 addresses
+//config:      (-W option).
+//config:
+//config:config FEATURE_NETSTAT_PRG
+//config:      bool "Enable PID/Program name output"
+//config:      default y
+//config:      depends on NETSTAT
+//config:      help
+//config:      Add support for -p flag to print out PID and program name.
+//config:      +700 bytes of code.
+
+//applet:IF_NETSTAT(APPLET(netstat, BB_DIR_BIN, BB_SUID_DROP))
+
+//kbuild:lib-$(CONFIG_NETSTAT) += netstat.o
 
 #include "libbb.h"
 #include "inet_common.h"
@@ -21,7 +47,6 @@
 //usage:       "[-"IF_ROUTE("r")"al] [-tuwx] [-en"IF_FEATURE_NETSTAT_WIDE("W")IF_FEATURE_NETSTAT_PRG("p")"]"
 //usage:#define netstat_full_usage "\n\n"
 //usage:       "Display networking information\n"
-//usage:     "\nOptions:"
 //usage:       IF_ROUTE(
 //usage:     "\n       -r      Routing table"
 //usage:       )
@@ -120,16 +145,16 @@ typedef enum {
 #define ADDR_NORMAL_WIDTH        23
 /* When there are IPv6 connections the IPv6 addresses will be
  * truncated to none-recognition. The '-W' option makes the
- * address columns wide enough to accomodate for longest possible
+ * address columns wide enough to accommodate for longest possible
  * IPv6 addresses, i.e. addresses of the form
  * xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:ddd.ddd.ddd.ddd
  */
 #define ADDR_WIDE                51  /* INET6_ADDRSTRLEN + 5 for the port number */
 #if ENABLE_FEATURE_NETSTAT_WIDE
-# define FMT_NET_CONN_DATA       "%s   %6ld %6ld %-*s %-*s %-12s"
+# define FMT_NET_CONN_DATA       "%s   %6lu %6lu %-*s %-*s %-12s"
 # define FMT_NET_CONN_HEADER     "\nProto Recv-Q Send-Q %-*s %-*s State       %s\n"
 #else
-# define FMT_NET_CONN_DATA       "%s   %6ld %6ld %-23s %-23s %-12s"
+# define FMT_NET_CONN_DATA       "%s   %6lu %6lu %-23s %-23s %-12s"
 # define FMT_NET_CONN_HEADER     "\nProto Recv-Q Send-Q %-23s %-23s State       %s\n"
 #endif
 
@@ -147,7 +172,7 @@ struct prg_node {
 #define PRG_HASH_SIZE 211
 
 struct globals {
-       smallint flags;
+       smalluint flags;
 #if ENABLE_FEATURE_NETSTAT_PRG
        smallint prg_cache_loaded;
        struct prg_node *prg_hash[PRG_HASH_SIZE];
@@ -188,7 +213,7 @@ static void prg_cache_add(long inode, char *name)
        for (pnp = prg_hash + hi; (pn = *pnp) != NULL; pnp = &pn->next) {
                if (pn->inode == inode) {
                        /* Some warning should be appropriate here
-                          as we got multiple processes for one i-node */
+                        * as we got multiple processes for one i-node */
                        return;
                }
        }
@@ -229,12 +254,12 @@ static long extract_socket_inode(const char *lname)
 {
        long inode = -1;
 
-       if (strncmp(lname, "socket:[", sizeof("socket:[")-1) == 0) {
+       if (is_prefixed_with(lname, "socket:[")) {
                /* "socket:[12345]", extract the "12345" as inode */
                inode = bb_strtoul(lname + sizeof("socket:[")-1, (char**)&lname, 0);
                if (*lname != ']')
                        inode = -1;
-       } else if (strncmp(lname, "[0000]:", sizeof("[0000]:")-1) == 0) {
+       } else if (is_prefixed_with(lname, "[0000]:")) {
                /* "[0000]:12345", extract the "12345" as inode */
                inode = bb_strtoul(lname + sizeof("[0000]:")-1, NULL, 0);
                if (errno) /* not NUL terminated? */
@@ -318,9 +343,9 @@ static void prg_cache_load(void)
                return;
 
        if (prg_cache_loaded == 1)
-               bb_error_msg("can't scan /proc - are you root?");
+               bb_simple_error_msg("can't scan /proc - are you root?");
        else
-               bb_error_msg("showing only processes with your user ID");
+               bb_simple_error_msg("showing only processes with your user ID");
 }
 
 #else
@@ -372,8 +397,11 @@ static char *ip_port_str(struct sockaddr *addr, int port, const char *proto, int
        /* Code which used "*" for INADDR_ANY is removed: it's ambiguous
         * in IPv6, while "0.0.0.0" is not. */
 
-       host = numeric ? xmalloc_sockaddr2dotted_noport(addr)
-                      : xmalloc_sockaddr2host_noport(addr);
+       host = NULL;
+       if (!numeric)
+               host = xmalloc_sockaddr2host_noport(addr);
+       if (!host)
+               host = xmalloc_sockaddr2dotted_noport(addr);
 
        host_port = xasprintf("%s:%s", host, get_sname(htons(port), proto, numeric));
        free(host);
@@ -404,7 +432,7 @@ static int scan_inet_proc_line(struct inet_params *param, char *line)
                        "%*d: %32[0-9A-Fa-f]:%X "
                        "%32[0-9A-Fa-f]:%X %X "
                        "%lX:%lX %*X:%*X "
-                       "%*X %d %*d %ld ",
+                       "%*X %d %*d %lu ",
                        local_addr, &param->local_port,
                        rem_addr, &param->rem_port, &param->state,
                        &param->txq, &param->rxq,
@@ -612,7 +640,7 @@ static int FAST_FUNC unix_do_one(char *line)
                strcat(ss_flags, "N ");
        strcat(ss_flags, "]");
 
-       printf("%-5s %-6ld %-11s %-10s %-13s %6lu ",
+       printf("%-5s %-6lu %-11s %-10s %-13s %6lu ",
                ss_proto, refcnt, ss_flags, ss_type, ss_state, inode
                );
 
@@ -623,7 +651,7 @@ static int FAST_FUNC unix_do_one(char *line)
 
        /* TODO: currently we stop at first NUL byte. Is it a problem? */
        line += path_ofs;
-       *strchrnul(line, '\n') = '\0';
+       chomp(line);
        while (*line)
                fputc_printable(*line++, stdout);
        bb_putchar('\n');
@@ -699,7 +727,7 @@ int netstat_main(int argc UNUSED_PARAM, char **argv)
                flags |= opt;
        }
        if (flags & (NETSTAT_TCP|NETSTAT_UDP|NETSTAT_RAW)) {
-               printf("Active Internet connections "); /* xxx */
+               printf("Active Internet connections "); /* xxx */
 
                if ((flags & (NETSTAT_LISTENING|NETSTAT_CONNECTED)) == (NETSTAT_LISTENING|NETSTAT_CONNECTED))
                        printf("(servers and established)");