void displayroutes(int noresolve, int netstatfmt) { char devname[64], flags[16], sdest[16], sgw[16]; unsigned long int d, g, m; int flgs, ref, use, metric, mtu, win, ir; struct sockaddr_in s_addr; struct in_addr mask; FILE *fp = bb_xfopen("/proc/net/route", "r"); bb_printf("Kernel IP routing table\n" "Destination Gateway Genmask" " Flags %s Iface\n", netstatfmt ? " MSS Window irtt" : "Metric Ref Use"); if (fscanf(fp, "%*[^\n]\n") < 0) { /* Skip the first line. */ goto ERROR; /* Empty or missing line, or read error. */ } while (1) { int r; r = fscanf(fp, "%63s%lx%lx%X%d%d%d%lx%d%d%d\n", devname, &d, &g, &flgs, &ref, &use, &metric, &m, &mtu, &win, &ir); if (r != 11) { if ((r < 0) && feof(fp)) { /* EOF with no (nonspace) chars read. */ break; } ERROR: bb_error_msg_and_die("fscanf"); } if (!(flgs & RTF_UP)) { /* Skip interfaces that are down. */ continue; } set_flags(flags, (flgs & IPV4_MASK)); #ifdef RTF_REJECT if (flgs & RTF_REJECT) { flags[0] = '!'; } #endif memset(&s_addr, 0, sizeof(struct sockaddr_in)); s_addr.sin_family = AF_INET; s_addr.sin_addr.s_addr = d; INET_rresolve(sdest, sizeof(sdest), &s_addr, (noresolve | 0x8000), m); /* Default instead of *. */ s_addr.sin_addr.s_addr = g; INET_rresolve(sgw, sizeof(sgw), &s_addr, (noresolve | 0x4000), m); /* Host instead of net. */ mask.s_addr = m; bb_printf("%-16s%-16s%-16s%-6s", sdest, sgw, inet_ntoa(mask), flags); if (netstatfmt) { bb_printf("%5d %-5d %6d %s\n", mtu, win, ir, devname); } else { bb_printf("%-6d %-2d %7d %s\n", metric, ref, use, devname); } } }
int df_main(int argc, char **argv) { long blocks_used; long blocks_percent_used; #ifdef CONFIG_FEATURE_HUMAN_READABLE unsigned long df_disp_hr = KILOBYTE; #endif int status = EXIT_SUCCESS; unsigned long opt; FILE *mount_table; struct mntent *mount_entry; struct statfs s; static const char hdr_1k[] = "1k-blocks"; /* default display is kilobytes */ const char *disp_units_hdr = hdr_1k; #ifdef CONFIG_FEATURE_HUMAN_READABLE bb_opt_complementally = "h-km:k-hm:m-hk"; opt = bb_getopt_ulflags(argc, argv, "hmk"); if(opt & 1) { df_disp_hr = 0; disp_units_hdr = " Size"; } if(opt & 2) { df_disp_hr = MEGABYTE; disp_units_hdr = "1M-blocks"; } #else opt = bb_getopt_ulflags(argc, argv, "k"); #endif bb_printf("Filesystem%11s%-15sUsed Available Use%% Mounted on\n", "", disp_units_hdr); mount_table = NULL; argv += optind; if (optind >= argc) { if (!(mount_table = setmntent(bb_path_mtab_file, "r"))) { bb_perror_msg_and_die(bb_path_mtab_file); } } do { const char *device; const char *mount_point; if (mount_table) { if (!(mount_entry = getmntent(mount_table))) { endmntent(mount_table); break; } } else { if (!(mount_point = *argv++)) { break; } if (!(mount_entry = find_mount_point(mount_point, bb_path_mtab_file))) { bb_error_msg("%s: can't find mount point.", mount_point); SET_ERROR: status = EXIT_FAILURE; continue; } } device = mount_entry->mnt_fsname; mount_point = mount_entry->mnt_dir; if (statfs(mount_point, &s) != 0) { bb_perror_msg("%s", mount_point); goto SET_ERROR; } if ((s.f_blocks > 0) || !mount_table){ blocks_used = s.f_blocks - s.f_bfree; blocks_percent_used = 0; if (blocks_used + s.f_bavail) { blocks_percent_used = (((long long) blocks_used) * 100 + (blocks_used + s.f_bavail)/2 ) / (blocks_used + s.f_bavail); } if (strcmp(device, "rootfs") == 0) { continue; } else if (strcmp(device, "/dev/root") == 0) { /* Adjusts device to be the real root device, * or leaves device alone if it can't find it */ if ((device = find_block_device("/")) == NULL) { goto SET_ERROR; } } #ifdef CONFIG_FEATURE_HUMAN_READABLE bb_printf("%-20s %9s ", device, make_human_readable_str(s.f_blocks, s.f_bsize, df_disp_hr)); bb_printf("%9s ", make_human_readable_str( (s.f_blocks - s.f_bfree), s.f_bsize, df_disp_hr)); bb_printf("%9s %3ld%% %s\n", make_human_readable_str(s.f_bavail, s.f_bsize, df_disp_hr), blocks_percent_used, mount_point); #else bb_printf("%-20s %9ld %9ld %9ld %3ld%% %s\n", device, kscale(s.f_blocks, s.f_bsize), kscale(s.f_blocks-s.f_bfree, s.f_bsize), kscale(s.f_bavail, s.f_bsize), blocks_percent_used, mount_point); #endif } } while (1); bb_fflush_stdout_and_exit(status); }
extern int id_main(int argc, char **argv) { struct passwd *p; uid_t uid; gid_t gid; unsigned long flags; short status; /* Don't allow -n -r -nr -ug -rug -nug -rnug */ /* Don't allow more than one username */ bb_opt_complementally = "?1:?:u--g:g--u:r?ug:n?ug"; flags = bb_getopt_ulflags(argc, argv, "rnug"); /* This values could be overwritten later */ uid = geteuid(); gid = getegid(); if (flags & PRINT_REAL) { uid = getuid(); gid = getgid(); } if(argv[optind]) { p=getpwnam(argv[optind]); /* bb_xgetpwnam is needed because it exits on failure */ uid = bb_xgetpwnam(argv[optind]); gid = p->pw_gid; /* in this case PRINT_REAL is the same */ } if(flags & (JUST_GROUP | JUST_USER)) { /* JUST_GROUP and JUST_USER are mutually exclusive */ if(flags & NAME_NOT_NUMBER) { /* bb_getpwuid and bb_getgrgid exit on failure so puts cannot segfault */ puts((flags & JUST_USER) ? bb_getpwuid(NULL, uid, -1 ) : bb_getgrgid(NULL, gid, -1 )); } else { bb_printf("%u\n",(flags & JUST_USER) ? uid : gid); } /* exit */ bb_fflush_stdout_and_exit(EXIT_SUCCESS); } /* Print full info like GNU id */ /* bb_getpwuid doesn't exit on failure here */ status=printf_full(uid, bb_getpwuid(NULL, uid, 0), 'u'); putchar(' '); /* bb_getgrgid doesn't exit on failure here */ status|=printf_full(gid, bb_getgrgid(NULL, gid, 0), 'g'); #ifdef CONFIG_SELINUX if ( is_selinux_enabled() ) { security_context_t mysid; char context[80]; int len = sizeof(context); getcon(&mysid); context[0] = '\0'; if (mysid) { len = strlen(mysid)+1; safe_strncpy(context, mysid, len); freecon(mysid); }else{ safe_strncpy(context, "unknown",8); } bb_printf(" context=%s", context); } #endif putchar('\n'); bb_fflush_stdout_and_exit(status); }
static void INET6_displayroutes(int noresolve) { char addr6[128], naddr6[128]; /* In addr6x, we store both 40-byte ':'-delimited ipv6 addresses. * We read the non-delimited strings into the tail of the buffer * using fscanf and then modify the buffer by shifting forward * while inserting ':'s and the nul terminator for the first string. * Hence the strings are at addr6x and addr6x+40. This generates * _much_ less code than the previous (upstream) approach. */ char addr6x[80]; char iface[16], flags[16]; int iflags, metric, refcnt, use, prefix_len, slen; struct sockaddr_in6 snaddr6; FILE *fp = bb_xfopen("/proc/net/ipv6_route", "r"); bb_printf("Kernel IPv6 routing table\n%-44s%-40s" "Flags Metric Ref Use Iface\n", "Destination", "Next Hop"); while (1) { int r; r = fscanf(fp, "%32s%x%*s%x%32s%x%x%x%x%s\n", addr6x+14, &prefix_len, &slen, addr6x+40+7, &metric, &use, &refcnt, &iflags, iface); if (r != 9) { if ((r < 0) && feof(fp)) { /* EOF with no (nonspace) chars read. */ break; } ERROR: bb_error_msg_and_die("fscanf"); } /* Do the addr6x shift-and-insert changes to ':'-delimit addresses. * For now, always do this to validate the proc route format, even * if the interface is down. */ { int i = 0; char *p = addr6x+14; do { if (!*p) { if (i==40) { /* nul terminator for 1st address? */ addr6x[39] = 0; /* Fixup... need 0 instead of ':'. */ ++p; /* Skip and continue. */ continue; } goto ERROR; } addr6x[i++] = *p++; if (!((i+1)%5)) { addr6x[i++] = ':'; } } while (i < 40+28+7); } if (!(iflags & RTF_UP)) { /* Skip interfaces that are down. */ continue; } set_flags(flags, (iflags & IPV6_MASK)); r = 0; do { inet_pton(AF_INET6, addr6x + r, (struct sockaddr *) &snaddr6.sin6_addr); snaddr6.sin6_family = AF_INET6; INET6_rresolve(naddr6, sizeof(naddr6), (struct sockaddr_in6 *) &snaddr6, #if 0 (noresolve | 0x8000) /* Default instead of *. */ #else 0x0fff /* Apparently, upstream never resolves. */ #endif ); if (!r) { /* 1st pass */ snprintf(addr6, sizeof(addr6), "%s/%d", naddr6, prefix_len); r += 40; } else { /* 2nd pass */ /* Print the info. */ bb_printf("%-43s %-39s %-5s %-6d %-2d %7d %-8s\n", addr6, naddr6, flags, metric, refcnt, use, iface); break; } } while (1); } }