/* * Read an array of N counters in kernel memory into array of N uint64_t's. */ int kread_counters(u_long addr, void *buf, size_t size) { uint64_t *c; u_long *counters; size_t i, n; if (kvmd_init() < 0) return (-1); if (size % sizeof(uint64_t) != 0) { xo_warnx("kread_counters: invalid counter set size"); return (-1); } n = size / sizeof(uint64_t); if ((counters = malloc(n * sizeof(u_long))) == NULL) xo_err(-1, "malloc"); if (kread(addr, counters, n * sizeof(u_long)) < 0) { free(counters); return (-1); } c = buf; for (i = 0; i < n; i++) c[i] = kvm_counter_u64_fetch(kvmd, counters[i]); free(counters); return (0); }
/* * Process a file to set standard arp entries */ static int file(char *name) { FILE *fp; int i, retval; char line[100], arg[5][50], *args[5], *p; if ((fp = fopen(name, "r")) == NULL) xo_err(1, "cannot open %s", name); args[0] = &arg[0][0]; args[1] = &arg[1][0]; args[2] = &arg[2][0]; args[3] = &arg[3][0]; args[4] = &arg[4][0]; retval = 0; while(fgets(line, sizeof(line), fp) != NULL) { if ((p = strchr(line, '#')) != NULL) *p = '\0'; for (p = line; isblank(*p); p++); if (*p == '\n' || *p == '\0') continue; i = sscanf(p, "%49s %49s %49s %49s %49s", arg[0], arg[1], arg[2], arg[3], arg[4]); if (i < 2) { xo_warnx("bad line: %s", line); retval = 1; continue; } if (set(i, args)) retval = 1; } fclose(fp); return (retval); }
/* * Make a pass over the file system info in ``mntbuf'' filtering out * file system types not in vfslist and possibly re-stating to get * current (not cached) info. Returns the new count of valid statfs bufs. */ static size_t regetmntinfo(struct statfs **mntbufp, long mntsize, const char **vfslist) { int error, i, j; struct statfs *mntbuf; if (vfslist == NULL) return (nflag ? mntsize : getmntinfo(mntbufp, MNT_WAIT)); mntbuf = *mntbufp; for (j = 0, i = 0; i < mntsize; i++) { if (checkvfsname(mntbuf[i].f_fstypename, vfslist)) continue; /* * XXX statfs(2) can fail for various reasons. It may be * possible that the user does not have access to the * pathname, if this happens, we will fall back on * "stale" filesystem statistics. */ error = statfs(mntbuf[i].f_mntonname, &mntbuf[j]); if (nflag || error < 0) if (i != j) { if (error < 0) xo_warnx("%s stats possibly stale", mntbuf[i].f_mntonname); mntbuf[j] = mntbuf[i]; } j++; } return (j); }
void parsecolors(const char *cs) { int i; int j; size_t len; char c[2]; short legacy_warn = 0; if (cs == NULL) cs = ""; /* LSCOLORS not set */ len = strlen(cs); for (i = 0; i < (int)C_NUMCOLORS; i++) { colors[i].bold = 0; if (len <= 2 * (size_t)i) { c[0] = defcolors[2 * i]; c[1] = defcolors[2 * i + 1]; } else { c[0] = cs[2 * i]; c[1] = cs[2 * i + 1]; } for (j = 0; j < 2; j++) { /* Legacy colours used 0-7 */ if (c[j] >= '0' && c[j] <= '7') { colors[i].num[j] = c[j] - '0'; if (!legacy_warn) { xo_warnx("LSCOLORS should use " "characters a-h instead of 0-9 (" "see the manual page)"); } legacy_warn = 1; } else if (c[j] >= 'a' && c[j] <= 'h') colors[i].num[j] = c[j] - 'a'; else if (c[j] >= 'A' && c[j] <= 'H') { colors[i].num[j] = c[j] - 'A'; colors[i].bold = 1; } else if (tolower((unsigned char)c[j]) == 'x') colors[i].num[j] = -1; else { xo_warnx("invalid character '%c' in LSCOLORS" " env var", c[j]); colors[i].num[j] = -1; } } } }
/* * Read kernel memory, return 0 on success. */ int kread(u_long addr, void *buf, size_t size) { if (kvmd_init() < 0) return (-1); if (!buf) return (0); if (kvm_read(kvmd, addr, buf, size) != (ssize_t)size) { xo_warnx("%s", kvm_geterr(kvmd)); return (-1); } return (0); }
static int kvmd_init(void) { char errbuf[_POSIX2_LINE_MAX]; if (kvmd != NULL) return (0); kvmd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); setgid(getgid()); if (kvmd == NULL) { xo_warnx("kvm not available: %s", errbuf); return (-1); } return (0); }
/* * Given a hostname, fills up a (static) struct sockaddr_in with * the address of the host and returns a pointer to the * structure. */ static struct sockaddr_in * getaddr(char *host) { struct hostent *hp; static struct sockaddr_in reply; bzero(&reply, sizeof(reply)); reply.sin_len = sizeof(reply); reply.sin_family = AF_INET; reply.sin_addr.s_addr = inet_addr(host); if (reply.sin_addr.s_addr == INADDR_NONE) { if (!(hp = gethostbyname(host))) { xo_warnx("%s: %s", host, hstrerror(h_errno)); return (NULL); } bcopy((char *)hp->h_addr, (char *)&reply.sin_addr, sizeof reply.sin_addr); } return (&reply); }
static int pcblist_sysctl(int proto, const char *name, char **bufp) { const char *mibvar; char *buf; size_t len; switch (proto) { case IPPROTO_TCP: mibvar = "net.inet.tcp.pcblist"; break; case IPPROTO_UDP: mibvar = "net.inet.udp.pcblist"; break; case IPPROTO_DIVERT: mibvar = "net.inet.divert.pcblist"; break; default: mibvar = "net.inet.raw.pcblist"; break; } if (strncmp(name, "sdp", 3) == 0) mibvar = "net.inet.sdp.pcblist"; len = 0; if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) { if (errno != ENOENT) xo_warn("sysctl: %s", mibvar); return (0); } if ((buf = malloc(len)) == NULL) { xo_warnx("malloc %lu bytes", (u_long)len); return (0); } if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) { xo_warn("sysctl: %s", mibvar); free(buf); return (0); } *bufp = buf; return (1); }
/* * Dump IGMP statistics structure. */ void igmp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) { struct igmpstat igmpstat; if (fetch_stats("net.inet.igmp.stats", 0, &igmpstat, sizeof(igmpstat), kread) != 0) return; if (igmpstat.igps_version != IGPS_VERSION_3) { xo_warnx("%s: version mismatch (%d != %d)", __func__, igmpstat.igps_version, IGPS_VERSION_3); } if (igmpstat.igps_len != IGPS_VERSION3_LEN) { xo_warnx("%s: size mismatch (%d != %d)", __func__, igmpstat.igps_len, IGPS_VERSION3_LEN); } xo_open_container(name); xo_emit("{T:/%s}:\n", name); #define p64(f, m) if (igmpstat.f || sflag <= 1) \ xo_emit(m, (uintmax_t) igmpstat.f, plural(igmpstat.f)) #define py64(f, m) if (igmpstat.f || sflag <= 1) \ xo_emit(m, (uintmax_t) igmpstat.f, pluralies(igmpstat.f)) p64(igps_rcv_total, "\t{:received-messages/%ju} " "{N:/message%s received}\n"); p64(igps_rcv_tooshort, "\t{:dropped-too-short/%ju} " "{N:/message%s received with too few bytes}\n"); p64(igps_rcv_badttl, "\t{:dropped-wrong-ttl/%ju} " "{N:/message%s received with wrong TTL}\n"); p64(igps_rcv_badsum, "\t{:dropped-bad-checksum/%ju} " "{N:/message%s received with bad checksum}\n"); py64(igps_rcv_v1v2_queries, "\t{:received-membership-queries/%ju} " "{N:/V1\\/V2 membership quer%s received}\n"); py64(igps_rcv_v3_queries, "\t{:received-v3-membership-queries/%ju} " "{N:/V3 membership quer%s received}\n"); py64(igps_rcv_badqueries, "\t{:dropped-membership-queries/%ju} " "{N:/membership quer%s received with invalid field(s)}\n"); py64(igps_rcv_gen_queries, "\t{:received-general-queries/%ju} " "{N:/general quer%s received}\n"); py64(igps_rcv_group_queries, "\t{:received-group-queries/%ju} " "{N:/group quer%s received}\n"); py64(igps_rcv_gsr_queries, "\t{:received-group-source-queries/%ju} " "{N:/group-source quer%s received}\n"); py64(igps_drop_gsr_queries, "\t{:dropped-group-source-queries/%ju} " "{N:/group-source quer%s dropped}\n"); p64(igps_rcv_reports, "\t{:received-membership-requests/%ju} " "{N:/membership report%s received}\n"); p64(igps_rcv_badreports, "\t{:dropped-membership-reports/%ju} " "{N:/membership report%s received with invalid field(s)}\n"); p64(igps_rcv_ourreports, "\t" "{:received-membership-reports-matching/%ju} " "{N:/membership report%s received for groups to which we belong}" "\n"); p64(igps_rcv_nora, "\t{:received-v3-reports-no-router-alert/%ju} " "{N:/V3 report%s received without Router Alert}\n"); p64(igps_snd_reports, "\t{:sent-membership-reports/%ju} " "{N:/membership report%s sent}\n"); #undef p64 #undef py64 xo_close_container(name); }
/* * Display() takes a linked list of FTSENT structures and passes the list * along with any other necessary information to the print function. P * points to the parent directory of the display list. */ static void display(const FTSENT *p, FTSENT *list, int options) { struct stat *sp; DISPLAY d; FTSENT *cur; NAMES *np; off_t maxsize; long maxblock; uintmax_t maxinode; u_long btotal, labelstrlen, maxlen, maxnlink; u_long maxlabelstr; u_int sizelen; int maxflags; gid_t maxgroup; uid_t maxuser; size_t flen, ulen, glen; char *initmax; int entries, needstats; const char *user, *group; char *flags, *labelstr = NULL; char ngroup[STRBUF_SIZEOF(uid_t) + 1]; char nuser[STRBUF_SIZEOF(gid_t) + 1]; needstats = f_inode || f_longform || f_size; flen = 0; btotal = 0; initmax = getenv("LS_COLWIDTHS"); /* Fields match -lios order. New ones should be added at the end. */ maxlabelstr = maxblock = maxlen = maxnlink = 0; maxuser = maxgroup = maxflags = maxsize = 0; maxinode = 0; if (initmax != NULL && *initmax != '\0') { char *initmax2, *jinitmax; int ninitmax; /* Fill-in "::" as "0:0:0" for the sake of scanf. */ jinitmax = malloc(strlen(initmax) * 2 + 2); if (jinitmax == NULL) xo_err(1, "malloc"); initmax2 = jinitmax; if (*initmax == ':') strcpy(initmax2, "0:"), initmax2 += 2; else *initmax2++ = *initmax, *initmax2 = '\0'; for (initmax++; *initmax != '\0'; initmax++) { if (initmax[-1] == ':' && initmax[0] == ':') { *initmax2++ = '0'; *initmax2++ = initmax[0]; initmax2[1] = '\0'; } else { *initmax2++ = initmax[0]; initmax2[1] = '\0'; } } if (initmax2[-1] == ':') strcpy(initmax2, "0"); ninitmax = sscanf(jinitmax, " %ju : %ld : %lu : %u : %u : %i : %jd : %lu : %lu ", &maxinode, &maxblock, &maxnlink, &maxuser, &maxgroup, &maxflags, &maxsize, &maxlen, &maxlabelstr); f_notabs = 1; switch (ninitmax) { case 0: maxinode = 0; /* FALLTHROUGH */ case 1: maxblock = 0; /* FALLTHROUGH */ case 2: maxnlink = 0; /* FALLTHROUGH */ case 3: maxuser = 0; /* FALLTHROUGH */ case 4: maxgroup = 0; /* FALLTHROUGH */ case 5: maxflags = 0; /* FALLTHROUGH */ case 6: maxsize = 0; /* FALLTHROUGH */ case 7: maxlen = 0; /* FALLTHROUGH */ case 8: maxlabelstr = 0; /* FALLTHROUGH */ #ifdef COLORLS if (!f_color) #endif f_notabs = 0; /* FALLTHROUGH */ default: break; } MAKENINES(maxinode); MAKENINES(maxblock); MAKENINES(maxnlink); MAKENINES(maxsize); free(jinitmax); } d.s_size = 0; sizelen = 0; flags = NULL; for (cur = list, entries = 0; cur; cur = cur->fts_link) { if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) { xo_warnx("%s: %s", cur->fts_name, strerror(cur->fts_errno)); cur->fts_number = NO_PRINT; rval = 1; continue; } /* * P is NULL if list is the argv list, to which different rules * apply. */ if (p == NULL) { /* Directories will be displayed later. */ if (cur->fts_info == FTS_D && !f_listdir) { cur->fts_number = NO_PRINT; continue; } } else { /* Only display dot file if -a/-A set. */ if (cur->fts_name[0] == '.' && !f_listdot) { cur->fts_number = NO_PRINT; continue; } } if (cur->fts_namelen > maxlen) maxlen = cur->fts_namelen; if (f_octal || f_octal_escape) { u_long t = len_octal(cur->fts_name, cur->fts_namelen); if (t > maxlen) maxlen = t; } if (needstats) { sp = cur->fts_statp; if (sp->st_blocks > maxblock) maxblock = sp->st_blocks; if (sp->st_ino > maxinode) maxinode = sp->st_ino; if (sp->st_nlink > maxnlink) maxnlink = sp->st_nlink; if (sp->st_size > maxsize) maxsize = sp->st_size; btotal += sp->st_blocks; if (f_longform) { if (f_numericonly) { (void)snprintf(nuser, sizeof(nuser), "%u", sp->st_uid); (void)snprintf(ngroup, sizeof(ngroup), "%u", sp->st_gid); user = nuser; group = ngroup; } else { user = user_from_uid(sp->st_uid, 0); group = group_from_gid(sp->st_gid, 0); } if ((ulen = strlen(user)) > maxuser) maxuser = ulen; if ((glen = strlen(group)) > maxgroup) maxgroup = glen; if (f_flags) { flags = fflagstostr(sp->st_flags); if (flags != NULL && *flags == '\0') { free(flags); flags = strdup("-"); } if (flags == NULL) xo_err(1, "fflagstostr"); flen = strlen(flags); if (flen > (size_t)maxflags) maxflags = flen; } else flen = 0; labelstr = NULL; if (f_label) { char name[PATH_MAX + 1]; mac_t label; int error; error = mac_prepare_file_label(&label); if (error == -1) { xo_warn("MAC label for %s/%s", cur->fts_parent->fts_path, cur->fts_name); goto label_out; } if (cur->fts_level == FTS_ROOTLEVEL) snprintf(name, sizeof(name), "%s", cur->fts_name); else snprintf(name, sizeof(name), "%s/%s", cur->fts_parent-> fts_accpath, cur->fts_name); if (options & FTS_LOGICAL) error = mac_get_file(name, label); else error = mac_get_link(name, label); if (error == -1) { xo_warn("MAC label for %s/%s", cur->fts_parent->fts_path, cur->fts_name); mac_free(label); goto label_out; } error = mac_to_text(label, &labelstr); if (error == -1) { xo_warn("MAC label for %s/%s", cur->fts_parent->fts_path, cur->fts_name); mac_free(label); goto label_out; } mac_free(label); label_out: if (labelstr == NULL) labelstr = strdup("-"); labelstrlen = strlen(labelstr); if (labelstrlen > maxlabelstr) maxlabelstr = labelstrlen; } else labelstrlen = 0; if ((np = malloc(sizeof(NAMES) + labelstrlen + ulen + glen + flen + 4)) == NULL) xo_err(1, "malloc"); np->user = &np->data[0]; (void)strcpy(np->user, user); np->group = &np->data[ulen + 1]; (void)strcpy(np->group, group); if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode)) { sizelen = snprintf(NULL, 0, "%#jx", (uintmax_t)sp->st_rdev); if (d.s_size < sizelen) d.s_size = sizelen; } if (f_flags) { np->flags = &np->data[ulen + glen + 2]; (void)strcpy(np->flags, flags); free(flags); } if (f_label) { np->label = &np->data[ulen + glen + 2 + (f_flags ? flen + 1 : 0)]; (void)strcpy(np->label, labelstr); free(labelstr); } cur->fts_pointer = np; } } ++entries; } /* * If there are no entries to display, we normally stop right * here. However, we must continue if we have to display the * total block count. In this case, we display the total only * on the second (p != NULL) pass. */ if (!entries && (!(f_longform || f_size) || p == NULL)) return; d.list = list; d.entries = entries; d.maxlen = maxlen; if (needstats) { d.btotal = btotal; d.s_block = snprintf(NULL, 0, "%lu", howmany(maxblock, blocksize)); d.s_flags = maxflags; d.s_label = maxlabelstr; d.s_group = maxgroup; d.s_inode = snprintf(NULL, 0, "%ju", maxinode); d.s_nlink = snprintf(NULL, 0, "%lu", maxnlink); sizelen = f_humanval ? HUMANVALSTR_LEN : snprintf(NULL, 0, "%ju", maxsize); if (d.s_size < sizelen) d.s_size = sizelen; d.s_user = maxuser; } if (f_thousands) /* make space for commas */ d.s_size += (d.s_size - 1) / 3; printfcn(&d); output = 1; if (f_longform) for (cur = list; cur; cur = cur->fts_link) free(cur->fts_pointer); }
/* * Traverse() walks the logical directory structure specified by the argv list * in the order specified by the mastercmp() comparison function. During the * traversal it passes linked lists of structures to display() which represent * a superset (may be exact set) of the files to be displayed. */ static void traverse(int argc, char *argv[], int options) { FTS *ftsp; FTSENT *p, *chp; int ch_options; int first = 1; if ((ftsp = fts_open(argv, options, f_nosort ? NULL : mastercmp)) == NULL) xo_err(1, "fts_open"); /* * We ignore errors from fts_children here since they will be * replicated and signalled on the next call to fts_read() below. */ chp = fts_children(ftsp, 0); if (chp != NULL) display(NULL, chp, options); if (f_listdir) return; /* * If not recursing down this tree and don't need stat info, just get * the names. */ ch_options = !f_recursive && !f_label && options & FTS_NOSTAT ? FTS_NAMEONLY : 0; while ((p = fts_read(ftsp)) != NULL) switch (p->fts_info) { case FTS_DC: xo_warnx("%s: directory causes a cycle", p->fts_name); break; case FTS_DNR: case FTS_ERR: xo_warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); rval = 1; break; case FTS_D: if (p->fts_level != FTS_ROOTLEVEL && p->fts_name[0] == '.' && !f_listdot) break; if (first) { first = 0; xo_open_list("directory"); } xo_open_instance("directory"); /* * If already output something, put out a newline as * a separator. If multiple arguments, precede each * directory with its name. */ if (output) { xo_emit("\n"); (void)printname("path", p->fts_path); xo_emit(":\n"); } else if (argc > 1) { (void)printname("path", p->fts_path); xo_emit(":\n"); output = 1; } chp = fts_children(ftsp, ch_options); display(p, chp, options); xo_close_instance("directory"); if (!f_recursive && chp != NULL) (void)fts_set(ftsp, p, FTS_SKIP); break; default: break; } if (!first) xo_close_list("directory"); if (errno) xo_err(1, "fts_read"); }
int main(int argc, char *argv[]) { static char dot[] = ".", *dotav[] = {dot, NULL}; struct winsize win; int ch, fts_options, notused; char *p; const char *errstr = NULL; #ifdef COLORLS char termcapbuf[1024]; /* termcap definition buffer */ char tcapbuf[512]; /* capability buffer */ char *bp = tcapbuf; #endif (void)setlocale(LC_ALL, ""); /* Terminal defaults to -Cq, non-terminal defaults to -1. */ if (isatty(STDOUT_FILENO)) { termwidth = 80; if ((p = getenv("COLUMNS")) != NULL && *p != '\0') termwidth = strtonum(p, 0, INT_MAX, &errstr); else if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) != -1 && win.ws_col > 0) termwidth = win.ws_col; f_nonprint = 1; } else { f_singlecol = 1; /* retrieve environment variable, in case of explicit -C */ p = getenv("COLUMNS"); if (p) termwidth = strtonum(p, 0, INT_MAX, &errstr); } if (errstr) termwidth = 80; fts_options = FTS_PHYSICAL; if (getenv("LS_SAMESORT")) f_samesort = 1; argc = xo_parse_args(argc, argv); if (argc < 0) return (1); xo_set_flags(NULL, XOF_COLUMNS); xo_set_version(LS_XO_VERSION); while ((ch = getopt(argc, argv, "1ABCD:FGHILPRSTUWXZabcdfghiklmnopqrstuwxy,")) != -1) { switch (ch) { /* * The -1, -C, -x and -l options all override each other so * shell aliasing works right. */ case '1': f_singlecol = 1; f_longform = 0; f_stream = 0; break; case 'C': f_sortacross = f_longform = f_singlecol = 0; break; case 'l': f_longform = 1; f_singlecol = 0; f_stream = 0; break; case 'x': f_sortacross = 1; f_longform = 0; f_singlecol = 0; break; /* The -c, -u, and -U options override each other. */ case 'c': f_statustime = 1; f_accesstime = 0; f_birthtime = 0; break; case 'u': f_accesstime = 1; f_statustime = 0; f_birthtime = 0; break; case 'U': f_birthtime = 1; f_accesstime = 0; f_statustime = 0; break; case 'f': f_nosort = 1; /* FALLTHROUGH */ case 'a': fts_options |= FTS_SEEDOT; /* FALLTHROUGH */ case 'A': f_listdot = 1; break; /* The -t and -S options override each other. */ case 'S': f_sizesort = 1; f_timesort = 0; break; case 't': f_timesort = 1; f_sizesort = 0; break; /* Other flags. Please keep alphabetic. */ case ',': f_thousands = 1; break; case 'B': f_nonprint = 0; f_octal = 1; f_octal_escape = 0; break; case 'D': f_timeformat = optarg; break; case 'F': f_type = 1; f_slash = 0; break; case 'G': setenv("CLICOLOR", "", 1); break; case 'H': fts_options |= FTS_COMFOLLOW; f_nofollow = 0; break; case 'I': f_noautodot = 1; break; case 'L': fts_options &= ~FTS_PHYSICAL; fts_options |= FTS_LOGICAL; f_nofollow = 0; break; case 'P': fts_options &= ~FTS_COMFOLLOW; fts_options &= ~FTS_LOGICAL; fts_options |= FTS_PHYSICAL; f_nofollow = 1; break; case 'R': f_recursive = 1; break; case 'T': f_sectime = 1; break; case 'W': f_whiteout = 1; break; case 'Z': f_label = 1; break; case 'b': f_nonprint = 0; f_octal = 0; f_octal_escape = 1; break; /* The -d option turns off the -R option. */ case 'd': f_listdir = 1; f_recursive = 0; break; case 'g': /* Compatibility with 4.3BSD. */ break; case 'h': f_humanval = 1; break; case 'i': f_inode = 1; break; case 'k': f_humanval = 0; f_kblocks = 1; break; case 'm': f_stream = 1; f_singlecol = 0; f_longform = 0; break; case 'n': f_numericonly = 1; break; case 'o': f_flags = 1; break; case 'p': f_slash = 1; f_type = 1; break; case 'q': f_nonprint = 1; f_octal = 0; f_octal_escape = 0; break; case 'r': f_reversesort = 1; break; case 's': f_size = 1; break; case 'w': f_nonprint = 0; f_octal = 0; f_octal_escape = 0; break; case 'y': f_samesort = 1; break; default: case '?': usage(); } } argc -= optind; argv += optind; /* Root is -A automatically unless -I. */ if (!f_listdot && getuid() == (uid_t)0 && !f_noautodot) f_listdot = 1; /* Enabling of colours is conditional on the environment. */ if (getenv("CLICOLOR") && (isatty(STDOUT_FILENO) || getenv("CLICOLOR_FORCE"))) #ifdef COLORLS if (tgetent(termcapbuf, getenv("TERM")) == 1) { ansi_fgcol = tgetstr("AF", &bp); ansi_bgcol = tgetstr("AB", &bp); attrs_off = tgetstr("me", &bp); enter_bold = tgetstr("md", &bp); /* To switch colours off use 'op' if * available, otherwise use 'oc', or * don't do colours at all. */ ansi_coloff = tgetstr("op", &bp); if (!ansi_coloff) ansi_coloff = tgetstr("oc", &bp); if (ansi_fgcol && ansi_bgcol && ansi_coloff) f_color = 1; } #else xo_warnx("color support not compiled in"); #endif /*COLORLS*/ #ifdef COLORLS if (f_color) { /* * We can't put tabs and color sequences together: * column number will be incremented incorrectly * for "stty oxtabs" mode. */ f_notabs = 1; (void)signal(SIGINT, colorquit); (void)signal(SIGQUIT, colorquit); parsecolors(getenv("LSCOLORS")); } #endif /* * If not -F, -i, -l, -s, -S or -t options, don't require stat * information, unless in color mode in which case we do * need this to determine which colors to display. */ if (!f_inode && !f_longform && !f_size && !f_timesort && !f_sizesort && !f_type #ifdef COLORLS && !f_color #endif ) fts_options |= FTS_NOSTAT; /* * If not -F, -P, -d or -l options, follow any symbolic links listed on * the command line, unless in color mode in which case we need to * distinguish file type for a symbolic link itself and its target. */ if (!f_nofollow && !f_longform && !f_listdir && (!f_type || f_slash) #ifdef COLORLS && !f_color #endif ) fts_options |= FTS_COMFOLLOW; /* * If -W, show whiteout entries */ #ifdef FTS_WHITEOUT if (f_whiteout) fts_options |= FTS_WHITEOUT; #endif /* If -i, -l or -s, figure out block size. */ if (f_inode || f_longform || f_size) { if (f_kblocks) blocksize = 2; else { (void)getbsize(¬used, &blocksize); blocksize /= 512; } } /* Select a sort function. */ if (f_reversesort) { if (!f_timesort && !f_sizesort) sortfcn = revnamecmp; else if (f_sizesort) sortfcn = revsizecmp; else if (f_accesstime) sortfcn = revacccmp; else if (f_birthtime) sortfcn = revbirthcmp; else if (f_statustime) sortfcn = revstatcmp; else /* Use modification time. */ sortfcn = revmodcmp; } else { if (!f_timesort && !f_sizesort) sortfcn = namecmp; else if (f_sizesort) sortfcn = sizecmp; else if (f_accesstime) sortfcn = acccmp; else if (f_birthtime) sortfcn = birthcmp; else if (f_statustime) sortfcn = statcmp; else /* Use modification time. */ sortfcn = modcmp; } /* Select a print function. */ if (f_singlecol) printfcn = printscol; else if (f_longform) printfcn = printlong; else if (f_stream) printfcn = printstream; else printfcn = printcol; xo_open_container("file-information"); if (argc) traverse(argc, argv, fts_options); else traverse(1, dotav, fts_options); xo_close_container("file-information"); xo_finish(); exit(rval); }
void bpf_stats(char *ifname) { struct xbpf_d *d, *bd, zerostat; char *pname, flagbuf[12]; size_t size; if (zflag) { bzero(&zerostat, sizeof(zerostat)); if (sysctlbyname("net.bpf.stats", NULL, NULL, &zerostat, sizeof(zerostat)) < 0) xo_warn("failed to zero bpf counters"); return; } if (sysctlbyname("net.bpf.stats", NULL, &size, NULL, 0) < 0) { xo_warn("net.bpf.stats"); return; } if (size == 0) return; bd = malloc(size); if (bd == NULL) { xo_warn("malloc failed"); return; } if (sysctlbyname("net.bpf.stats", bd, &size, NULL, 0) < 0) { xo_warn("net.bpf.stats"); free(bd); return; } xo_emit("{T:/%5s} {T:/%6s} {T:/%7s} {T:/%9s} {T:/%9s} {T:/%9s} " "{T:/%5s} {T:/%5s} {T:/%s}\n", "Pid", "Netif", "Flags", "Recv", "Drop", "Match", "Sblen", "Hblen", "Command"); xo_open_container("bpf-statistics"); xo_open_list("bpf-entry"); for (d = &bd[0]; d < &bd[size / sizeof(*d)]; d++) { if (d->bd_structsize != sizeof(*d)) { xo_warnx("bpf_stats_extended: version mismatch"); return; } if (ifname && strcmp(ifname, d->bd_ifname) != 0) continue; xo_open_instance("bpf-entry"); pname = bpf_pidname(d->bd_pid); xo_emit("{k:pid/%5d} {k:interface-name/%6s} ", d->bd_pid, d->bd_ifname); bpf_flags(d, flagbuf); xo_emit("{d:flags/%7s} {:received-packets/%9ju} " "{:dropped-packets/%9ju} {:filter-packets/%9ju} " "{:store-buffer-length/%5d} {:hold-buffer-length/%5d} " "{:process/%s}\n", flagbuf, (uintmax_t)d->bd_rcount, (uintmax_t)d->bd_dcount, (uintmax_t)d->bd_fcount, d->bd_slen, d->bd_hlen, pname); free(pname); xo_close_instance("bpf-entry"); } xo_close_list("bpf-entry"); xo_close_container("bpf-statistics"); free(bd); }
static void sctp_process_tcb(struct xsctp_tcb *xstcb, char *buf, const size_t buflen, size_t *offset, int *indent) { int i, xl_total = 0, xr_total = 0, x_max; struct xsctp_raddr *xraddr; struct xsctp_laddr *xladdr; struct xladdr_entry *prev_xl = NULL, *xl = NULL, *xl_tmp; struct xraddr_entry *prev_xr = NULL, *xr = NULL, *xr_tmp; LIST_INIT(&xladdr_head); LIST_INIT(&xraddr_head); /* * Make `struct xladdr_list' list and `struct xraddr_list' list * to handle the address flexibly. */ while (*offset < buflen) { xladdr = (struct xsctp_laddr *)(buf + *offset); *offset += sizeof(struct xsctp_laddr); if (xladdr->last == 1) break; prev_xl = xl; xl = malloc(sizeof(struct xladdr_entry)); if (xl == NULL) { xo_warnx("malloc %lu bytes", (u_long)sizeof(struct xladdr_entry)); goto out; } xl->xladdr = xladdr; if (prev_xl == NULL) LIST_INSERT_HEAD(&xladdr_head, xl, xladdr_entries); else LIST_INSERT_AFTER(prev_xl, xl, xladdr_entries); xl_total++; } while (*offset < buflen) { xraddr = (struct xsctp_raddr *)(buf + *offset); *offset += sizeof(struct xsctp_raddr); if (xraddr->last == 1) break; prev_xr = xr; xr = malloc(sizeof(struct xraddr_entry)); if (xr == NULL) { xo_warnx("malloc %lu bytes", (u_long)sizeof(struct xraddr_entry)); goto out; } xr->xraddr = xraddr; if (prev_xr == NULL) LIST_INSERT_HEAD(&xraddr_head, xr, xraddr_entries); else LIST_INSERT_AFTER(prev_xr, xr, xraddr_entries); xr_total++; } /* * Let's print the address infos. */ xo_open_list("address"); xl = LIST_FIRST(&xladdr_head); xr = LIST_FIRST(&xraddr_head); x_max = MAX(xl_total, xr_total); for (i = 0; i < x_max; i++) { xo_open_instance("address"); if (((*indent == 0) && i > 0) || *indent > 0) xo_emit("{P:/%-12s} ", " "); if (xl != NULL) { sctp_print_address("local", &(xl->xladdr->address), htons(xstcb->local_port), numeric_port); } else { if (Wflag) { xo_emit("{P:/%-45s} ", " "); } else { xo_emit("{P:/%-22s} ", " "); } } if (xr != NULL && !Lflag) { sctp_print_address("remote", &(xr->xraddr->address), htons(xstcb->remote_port), numeric_port); } if (xl != NULL) xl = LIST_NEXT(xl, xladdr_entries); if (xr != NULL) xr = LIST_NEXT(xr, xraddr_entries); if (i == 0 && !Lflag) sctp_statesprint(xstcb->state); if (i < x_max) xo_emit("\n"); xo_close_instance("address"); } out: /* * Free the list which be used to handle the address. */ xl = LIST_FIRST(&xladdr_head); while (xl != NULL) { xl_tmp = LIST_NEXT(xl, xladdr_entries); free(xl); xl = xl_tmp; } xr = LIST_FIRST(&xraddr_head); while (xr != NULL) { xr_tmp = LIST_NEXT(xr, xraddr_entries); free(xr); xr = xr_tmp; } }
/* * Set an individual arp entry */ static int set(int argc, char **argv) { struct sockaddr_in *addr; struct sockaddr_in *dst; /* what are we looking for */ struct sockaddr_dl *sdl; struct rt_msghdr *rtm; struct ether_addr *ea; char *host = argv[0], *eaddr = argv[1]; struct sockaddr_dl sdl_m; argc -= 2; argv += 2; bzero(&sdl_m, sizeof(sdl_m)); sdl_m.sdl_len = sizeof(sdl_m); sdl_m.sdl_family = AF_LINK; dst = getaddr(host); if (dst == NULL) return (1); doing_proxy = flags = expire_time = 0; while (argc-- > 0) { if (strcmp(argv[0], "temp") == 0) { struct timespec tp; int max_age; size_t len = sizeof(max_age); clock_gettime(CLOCK_MONOTONIC, &tp); if (sysctlbyname("net.link.ether.inet.max_age", &max_age, &len, NULL, 0) != 0) xo_err(1, "sysctlbyname"); expire_time = tp.tv_sec + max_age; } else if (strcmp(argv[0], "pub") == 0) { flags |= RTF_ANNOUNCE; doing_proxy = 1; if (argc && strcmp(argv[1], "only") == 0) { /* * Compatibility: in pre FreeBSD 8 times * the "only" keyword used to mean that * an ARP entry should be announced, but * not installed into routing table. */ argc--; argv++; } } else if (strcmp(argv[0], "blackhole") == 0) { if (flags & RTF_REJECT) { xo_errx(1, "Choose one of blackhole or reject, " "not both."); } flags |= RTF_BLACKHOLE; } else if (strcmp(argv[0], "reject") == 0) { if (flags & RTF_BLACKHOLE) { xo_errx(1, "Choose one of blackhole or reject, " "not both."); } flags |= RTF_REJECT; } else { xo_warnx("Invalid parameter '%s'", argv[0]); usage(); } argv++; } ea = (struct ether_addr *)LLADDR(&sdl_m); if (doing_proxy && !strcmp(eaddr, "auto")) { if (!get_ether_addr(dst->sin_addr.s_addr, ea)) { xo_warnx("no interface found for %s", inet_ntoa(dst->sin_addr)); return (1); } sdl_m.sdl_alen = ETHER_ADDR_LEN; } else { struct ether_addr *ea1 = ether_aton(eaddr); if (ea1 == NULL) { xo_warnx("invalid Ethernet address '%s'", eaddr); return (1); } else { *ea = *ea1; sdl_m.sdl_alen = ETHER_ADDR_LEN; } } /* * In the case a proxy-arp entry is being added for * a remote end point, the RTF_ANNOUNCE flag in the * RTM_GET command is an indication to the kernel * routing code that the interface associated with * the prefix route covering the local end of the * PPP link should be returned, on which ARP applies. */ rtm = rtmsg(RTM_GET, dst, NULL); if (rtm == NULL) { xo_warn("%s", host); return (1); } addr = (struct sockaddr_in *)(rtm + 1); sdl = (struct sockaddr_dl *)(SA_SIZE(addr) + (char *)addr); if ((sdl->sdl_family != AF_LINK) || (rtm->rtm_flags & RTF_GATEWAY) || !valid_type(sdl->sdl_type)) { xo_warnx("cannot intuit interface index and type for %s", host); return (1); } sdl_m.sdl_type = sdl->sdl_type; sdl_m.sdl_index = sdl->sdl_index; return (rtmsg(RTM_ADD, dst, &sdl_m) == NULL); }