Save 0.5K.
No binary (build failed)
—
(log yok)
| @@ -15,7 +15,7 @@ | |
| * that either displays or sets the characteristics of | |
| * one or more of the system's networking interfaces. | |
| * | |
| - | * Version: $Id: interface.c,v 1.18 2003/07/28 06:35:32 andersen Exp $ |
| + | * Version: $Id: interface.c,v 1.19 2003/08/02 00:04:18 mjn3 Exp $ |
| * | |
| * Author: Fred N. van Kempen, <[email protected]> | |
| * and others. Copyright 1993 MicroWalt Corporation | |
| @@ -87,8 +87,6 @@ | |
| #define new(p) ((p) = xcalloc(1,sizeof(*(p)))) | |
| #define KRELEASE(maj,min,patch) ((maj) * 65536 + (min)*256 + (patch)) | |
| - | static int procnetdev_vsn = 1; |
| - | |
| #ifdef HAVE_HWSLIP | |
| #include <net/if_slip.h> | |
| #endif | |
| @@ -1021,71 +1019,76 @@ static char *get_name(char *name, char *p) | |
| return p; | |
| } | |
| - | static int get_dev_fields(char *bp, struct interface *ife) |
| + | /* If scanf supports size qualifiers for %n conversions, then we can |
| + | * use a modified fmt that simply stores the position in the fields |
| + | * having no associated fields in the proc string. Of course, we need |
| + | * to zero them again when we're done. But that is smaller than the |
| + | * old approach of multiple scanf occurrences with large numbers of |
| + | * args. */ |
| + | |
| + | /* static const char *ss_fmt[] = { */ |
| + | /* "%Ln%Lu%lu%lu%lu%lu%ln%ln%Ln%Lu%lu%lu%lu%lu%lu", */ |
| + | /* "%Lu%Lu%lu%lu%lu%lu%ln%ln%Lu%Lu%lu%lu%lu%lu%lu", */ |
| + | /* "%Lu%Lu%lu%lu%lu%lu%lu%lu%Lu%Lu%lu%lu%lu%lu%lu%lu" */ |
| + | /* }; */ |
| + | |
| + | /* Lie about the size of the int pointed to for %n. */ |
| + | #if INT_MAX == LONG_MAX |
| + | static const char *ss_fmt[] = { |
| + | "%n%Lu%u%u%u%u%n%n%n%Lu%u%u%u%u%u", |
| + | "%Lu%Lu%u%u%u%u%n%n%Lu%Lu%u%u%u%u%u", |
| + | "%Lu%Lu%u%u%u%u%u%u%Lu%Lu%u%u%u%u%u%u" |
| + | }; |
| + | #else |
| + | static const char *ss_fmt[] = { |
| + | "%n%Lu%lu%lu%lu%lu%n%n%n%Lu%lu%lu%lu%lu%lu", |
| + | "%Lu%Lu%lu%lu%lu%lu%n%n%Lu%Lu%lu%lu%lu%lu%lu", |
| + | "%Lu%Lu%lu%lu%lu%lu%lu%lu%Lu%Lu%lu%lu%lu%lu%lu%lu" |
| + | }; |
| + | |
| + | #endif |
| + | |
| + | static void get_dev_fields(char *bp, struct interface *ife, int procnetdev_vsn) |
| { | |
| - | switch (procnetdev_vsn) { |
| - | case 3: |
| - | sscanf(bp, |
| - | "%Lu %Lu %lu %lu %lu %lu %lu %lu %Lu %Lu %lu %lu %lu %lu %lu %lu", |
| - | &ife->stats.rx_bytes, |
| - | &ife->stats.rx_packets, |
| - | &ife->stats.rx_errors, |
| - | &ife->stats.rx_dropped, |
| - | &ife->stats.rx_fifo_errors, |
| - | &ife->stats.rx_frame_errors, |
| - | &ife->stats.rx_compressed, |
| - | &ife->stats.rx_multicast, |
| - | &ife->stats.tx_bytes, |
| - | &ife->stats.tx_packets, |
| - | &ife->stats.tx_errors, |
| - | &ife->stats.tx_dropped, |
| - | &ife->stats.tx_fifo_errors, |
| - | &ife->stats.collisions, |
| - | &ife->stats.tx_carrier_errors, &ife->stats.tx_compressed); |
| - | break; |
| - | case 2: |
| - | sscanf(bp, "%Lu %Lu %lu %lu %lu %lu %Lu %Lu %lu %lu %lu %lu %lu", |
| - | &ife->stats.rx_bytes, |
| - | &ife->stats.rx_packets, |
| - | &ife->stats.rx_errors, |
| - | &ife->stats.rx_dropped, |
| - | &ife->stats.rx_fifo_errors, |
| - | &ife->stats.rx_frame_errors, |
| - | &ife->stats.tx_bytes, |
| - | &ife->stats.tx_packets, |
| - | &ife->stats.tx_errors, |
| - | &ife->stats.tx_dropped, |
| - | &ife->stats.tx_fifo_errors, |
| - | &ife->stats.collisions, &ife->stats.tx_carrier_errors); |
| - | ife->stats.rx_multicast = 0; |
| - | break; |
| - | case 1: |
| - | sscanf(bp, "%Lu %lu %lu %lu %lu %Lu %lu %lu %lu %lu %lu", |
| - | &ife->stats.rx_packets, |
| - | &ife->stats.rx_errors, |
| - | &ife->stats.rx_dropped, |
| - | &ife->stats.rx_fifo_errors, |
| - | &ife->stats.rx_frame_errors, |
| - | &ife->stats.tx_packets, |
| - | &ife->stats.tx_errors, |
| - | &ife->stats.tx_dropped, |
| - | &ife->stats.tx_fifo_errors, |
| - | &ife->stats.collisions, &ife->stats.tx_carrier_errors); |
| - | ife->stats.rx_bytes = 0; |
| - | ife->stats.tx_bytes = 0; |
| + | memset(&ife->stats, 0, sizeof(struct user_net_device_stats)); |
| + | |
| + | sscanf(bp, ss_fmt[procnetdev_vsn], |
| + | &ife->stats.rx_bytes, /* missing for 0 */ |
| + | &ife->stats.rx_packets, |
| + | &ife->stats.rx_errors, |
| + | &ife->stats.rx_dropped, |
| + | &ife->stats.rx_fifo_errors, |
| + | &ife->stats.rx_frame_errors, |
| + | &ife->stats.rx_compressed, /* missing for <= 1 */ |
| + | &ife->stats.rx_multicast, /* missing for <= 1 */ |
| + | &ife->stats.tx_bytes, /* missing for 0 */ |
| + | &ife->stats.tx_packets, |
| + | &ife->stats.tx_errors, |
| + | &ife->stats.tx_dropped, |
| + | &ife->stats.tx_fifo_errors, |
| + | &ife->stats.collisions, |
| + | &ife->stats.tx_carrier_errors, |
| + | &ife->stats.tx_compressed /* missing for <= 1 */ |
| + | ); |
| + | |
| + | if (procnetdev_vsn <= 1) { |
| + | if (procnetdev_vsn == 0) { |
| + | ife->stats.rx_bytes = 0; |
| + | ife->stats.tx_bytes = 0; |
| + | } |
| ife->stats.rx_multicast = 0; | |
| - | break; |
| + | ife->stats.rx_compressed = 0; |
| + | ife->stats.tx_compressed = 0; |
| } | |
| - | return 0; |
| } | |
| static inline int procnetdev_version(char *buf) | |
| { | |
| if (strstr(buf, "compressed")) | |
| - | return 3; |
| - | if (strstr(buf, "bytes")) |
| return 2; | |
| - | return 1; |
| + | if (strstr(buf, "bytes")) |
| + | return 1; |
| + | return 0; |
| } | |
| static int if_readlist_proc(char *target) | |
| @@ -1094,7 +1097,7 @@ static int if_readlist_proc(char *target) | |
| FILE *fh; | |
| char buf[512]; | |
| struct interface *ife; | |
| - | int err; |
| + | int err, procnetdev_vsn; |
| if (proc_read) | |
| return 0; | |
| @@ -1109,28 +1112,7 @@ static int if_readlist_proc(char *target) | |
| fgets(buf, sizeof buf, fh); /* eat line */ | |
| fgets(buf, sizeof buf, fh); | |
| - | #if 0 /* pretty, but can't cope with missing fields */ |
| - | fmt = proc_gen_fmt(_PATH_PROCNET_DEV, 1, fh, "face", "", /* parsed separately */ |
| - | "bytes", "%lu", |
| - | "packets", "%lu", |
| - | "errs", "%lu", |
| - | "drop", "%lu", |
| - | "fifo", "%lu", |
| - | "frame", "%lu", |
| - | "compressed", "%lu", |
| - | "multicast", "%lu", |
| - | "bytes", "%lu", |
| - | "packets", "%lu", |
| - | "errs", "%lu", |
| - | "drop", "%lu", |
| - | "fifo", "%lu", |
| - | "colls", "%lu", |
| - | "carrier", "%lu", "compressed", "%lu", NULL); |
| - | if (!fmt) |
| - | return -1; |
| - | #else |
| procnetdev_vsn = procnetdev_version(buf); | |
| - | #endif |
| err = 0; | |
| while (fgets(buf, sizeof buf, fh)) { | |
| @@ -1138,7 +1120,7 @@ static int if_readlist_proc(char *target) | |
| s = get_name(name, buf); | |
| ife = add_interface(name); | |
| - | get_dev_fields(s, ife); |
| + | get_dev_fields(s, ife, procnetdev_vsn); |
| ife->statistics_valid = 1; | |
| if (target && !strcmp(target, name)) | |
| break; | |
| @@ -1148,9 +1130,6 @@ static int if_readlist_proc(char *target) | |
| err = -1; | |
| proc_read = 0; | |
| } | |
| - | #if 0 |
| - | free(fmt); |
| - | #endif |
| fclose(fh); | |
| return err; | |
| } | |
| @@ -1670,7 +1649,8 @@ static void hwinit() | |
| #endif /* KEEP_UNUSED */ | |
| #ifdef IFF_PORTSEL | |
| - | static const char *if_port_text[][4] = { |
| + | #if 0 |
| + | static const char * const if_port_text[][4] = { |
| /* Keep in step with <linux/netdevice.h> */ | |
| {"unknown", NULL, NULL, NULL}, | |
| {"10base2", "bnc", "coax", NULL}, | |
| @@ -1681,6 +1661,19 @@ static const char *if_port_text[][4] = { | |
| {"100baseFX", NULL, NULL, NULL}, | |
| {NULL, NULL, NULL, NULL}, | |
| }; | |
| + | #else |
| + | static const char * const if_port_text[] = { |
| + | /* Keep in step with <linux/netdevice.h> */ |
| + | "unknown", |
| + | "10base2", |
| + | "10baseT", |
| + | "AUI", |
| + | "100baseT", |
| + | "100baseTX", |
| + | "100baseFX", |
| + | NULL |
| + | }; |
| + | #endif |
| #endif | |
| /* Check our hardware type table for this type. */ | |
| @@ -1714,29 +1707,83 @@ static int hw_null_address(struct hwtype *hw, void *ap) | |
| return 1; | |
| } | |
| - | static const char TRext[] = "\0\0k\0M"; |
| + | #warning devel code |
| + | static const char TRext[] = "\0\0\0Ki\0Mi\0Gi\0Ti"; |
| static void print_bytes_scaled(unsigned long long ull, const char *end) | |
| { | |
| unsigned long long int_part; | |
| - | unsigned long frac_part; |
| const char *ext; | |
| + | unsigned int frac_part; |
| int i; | |
| frac_part = 0; | |
| ext = TRext; | |
| int_part = ull; | |
| - | for (i = 0; i < 2; i++) { |
| + | i = 4; |
| + | do { |
| + | #if 0 |
| + | /* This does correct rounding and is a little larger. But it |
| + | * uses KiB as the smallest displayed unit. */ |
| + | if ((int_part < (1024*1024 - 51)) || !--i) { |
| + | i = 0; |
| + | int_part += 51; /* 1024*.05 = 51.2 */ |
| + | frac_part = ((((unsigned int) int_part) & (1024-1)) * 10) / 1024; |
| + | } |
| + | int_part /= 1024; |
| + | ext += 3; /* KiB, MiB, GiB, TiB */ |
| + | #else |
| if (int_part >= 1024) { | |
| - | frac_part = ((int_part % 1024) * 10) / 1024; |
| + | frac_part = ((((unsigned int) int_part) & (1024-1)) * 10) / 1024; |
| int_part /= 1024; | |
| - | ext += 2; /* Kb, Mb */ |
| + | ext += 3; /* KiB, MiB, GiB, TiB */ |
| } | |
| - | } |
| + | --i; |
| + | #endif |
| + | } while (i); |
| - | printf("X bytes:%Lu (%Lu.%lu %siB)%s", ull, int_part, frac_part, ext, end); |
| + | printf("X bytes:%Lu (%Lu.%u %sB)%s", ull, int_part, frac_part, ext, end); |
| } | |
| + | static const char * const ife_print_flags_strs[] = { |
| + | "UP ", |
| + | "BROADCAST ", |
| + | "DEBUG ", |
| + | "LOOPBACK ", |
| + | "POINTOPOINT ", |
| + | "NOTRAILERS ", |
| + | "RUNNING ", |
| + | "NOARP ", |
| + | "PROMISC ", |
| + | "ALLMULTI ", |
| + | "SLAVE ", |
| + | "MASTER ", |
| + | "MULTICAST ", |
| + | #ifdef HAVE_DYNAMIC |
| + | "DYNAMIC " |
| + | #endif |
| + | }; |
| + | |
| + | static const unsigned short ife_print_flags_mask[] = { |
| + | IFF_UP, |
| + | IFF_BROADCAST, |
| + | IFF_DEBUG, |
| + | IFF_LOOPBACK, |
| + | IFF_POINTOPOINT, |
| + | IFF_NOTRAILERS, |
| + | IFF_RUNNING, |
| + | IFF_NOARP, |
| + | IFF_PROMISC, |
| + | IFF_ALLMULTI, |
| + | IFF_SLAVE, |
| + | IFF_MASTER, |
| + | IFF_MULTICAST, |
| + | #ifdef HAVE_DYNAMIC |
| + | IFF_DYNAMIC |
| + | #endif |
| + | 0 |
| + | }; |
| + | |
| static void ife_print(struct interface *ptr) | |
| { | |
| struct aftype *ap; | |
| @@ -1782,7 +1829,7 @@ static void ife_print(struct interface *ptr) | |
| printf(_("HWaddr %s "), hw->print(ptr->hwaddr)); | |
| #ifdef IFF_PORTSEL | |
| if (ptr->flags & IFF_PORTSEL) { | |
| - | printf(_("Media:%s"), if_port_text[ptr->map.port][0]); |
| + | printf(_("Media:%s"), if_port_text[ptr->map.port] /* [0] */); |
| if (ptr->flags & IFF_AUTOMEDIA) | |
| printf(_("(auto)")); | |
| } | |
| @@ -1907,38 +1954,18 @@ static void ife_print(struct interface *ptr) | |
| printf(" "); | |
| /* DONT FORGET TO ADD THE FLAGS IN ife_print_short, too */ | |
| - | if (ptr->flags == 0) |
| + | |
| + | if (ptr->flags == 0) { |
| printf(_("[NO FLAGS] ")); | |
| - | if (ptr->flags & IFF_UP) |
| - | printf(_("UP ")); |
| - | if (ptr->flags & IFF_BROADCAST) |
| - | printf(_("BROADCAST ")); |
| - | if (ptr->flags & IFF_DEBUG) |
| - | printf(_("DEBUG ")); |
| - | if (ptr->flags & IFF_LOOPBACK) |
| - | printf(_("LOOPBACK ")); |
| - | if (ptr->flags & IFF_POINTOPOINT) |
| - | printf(_("POINTOPOINT ")); |
| - | if (ptr->flags & IFF_NOTRAILERS) |
| - | printf(_("NOTRAILERS ")); |
| - | if (ptr->flags & IFF_RUNNING) |
| - | printf(_("RUNNING ")); |
| - | if (ptr->flags & IFF_NOARP) |
| - | printf(_("NOARP ")); |
| - | if (ptr->flags & IFF_PROMISC) |
| - | printf(_("PROMISC ")); |
| - | if (ptr->flags & IFF_ALLMULTI) |
| - | printf(_("ALLMULTI ")); |
| - | if (ptr->flags & IFF_SLAVE) |
| - | printf(_("SLAVE ")); |
| - | if (ptr->flags & IFF_MASTER) |
| - | printf(_("MASTER ")); |
| - | if (ptr->flags & IFF_MULTICAST) |
| - | printf(_("MULTICAST ")); |
| - | #ifdef HAVE_DYNAMIC |
| - | if (ptr->flags & IFF_DYNAMIC) |
| - | printf(_("DYNAMIC ")); |
| - | #endif |
| + | } else { |
| + | int i = 0; |
| + | do { |
| + | if (ptr->flags & ife_print_flags_mask[i]) { |
| + | printf(_(ife_print_flags_strs[i])); |
| + | } |
| + | } while (ife_print_flags_mask[++i]); |
| + | } |
| + | |
| /* DONT FORGET TO ADD THE FLAGS IN ife_print_short */ | |
| printf(_(" MTU:%d Metric:%d"), ptr->mtu, ptr->metric ? ptr->metric : 1); | |
| #ifdef SIOCSKEEPALIVE | |
| @@ -1956,8 +1983,7 @@ static void ife_print(struct interface *ptr) | |
| */ | |
| printf(" "); | |
| - | printf(_ |
| - | ("RX packets:%Lu errors:%lu dropped:%lu overruns:%lu frame:%lu\n"), |
| + | printf(_("RX packets:%Lu errors:%lu dropped:%lu overruns:%lu frame:%lu\n"), |
| ptr->stats.rx_packets, ptr->stats.rx_errors, | |
| ptr->stats.rx_dropped, ptr->stats.rx_fifo_errors, | |
| ptr->stats.rx_frame_errors); | |
| @@ -1965,8 +1991,7 @@ static void ife_print(struct interface *ptr) | |
| printf(_(" compressed:%lu\n"), | |
| ptr->stats.rx_compressed); | |
| printf(" "); | |
| - | printf(_ |
| - | ("TX packets:%Lu errors:%lu dropped:%lu overruns:%lu carrier:%lu\n"), |
| + | printf(_("TX packets:%Lu errors:%lu dropped:%lu overruns:%lu carrier:%lu\n"), |
| ptr->stats.tx_packets, ptr->stats.tx_errors, | |
| ptr->stats.tx_dropped, ptr->stats.tx_fifo_errors, | |
| ptr->stats.tx_carrier_errors); | |