static void write_normal_file(const char *name, struct archive *archive, struct archive_entry_linkresolver *resolver, const char *owner, const char *group) { char buf[16384]; ssize_t buf_len; struct archive_entry *entry, *sparse_entry; struct stat st; if (lstat(name, &st) == -1) err(2, "lstat failed for file %s", name); entry = archive_entry_new(); archive_entry_set_pathname(entry, name); archive_entry_copy_stat(entry, &st); if (owner != NULL) { uid_t uid; archive_entry_set_uname(entry, owner); if (uid_from_user(owner, &uid) == -1) errx(2, "user %s unknown", owner); archive_entry_set_uid(entry, uid); } else { archive_entry_set_uname(entry, user_from_uid(st.st_uid, 1)); } if (group != NULL) { gid_t gid; archive_entry_set_gname(entry, group); if (gid_from_group(group, &gid) == -1) errx(2, "group %s unknown", group); archive_entry_set_gid(entry, gid); } else { archive_entry_set_gname(entry, group_from_gid(st.st_gid, 1)); } if ((st.st_mode & S_IFMT) == S_IFLNK) { buf_len = readlink(name, buf, sizeof buf); if (buf_len < 0) err(2, "cannot read symlink %s", name); buf[buf_len] = '\0'; archive_entry_set_symlink(entry, buf); } archive_entry_linkify(resolver, &entry, &sparse_entry); if (entry != NULL) write_entry(archive, entry); if (sparse_entry != NULL) write_entry(archive, sparse_entry); }
static void update_ids(struct memory_file *file) { if (file->owner != NULL) { uid_t uid; if (uid_from_user(file->owner, &uid) == -1) errx(2, "user %s unknown", file->owner); file->st.st_uid = uid; } else { file->owner = xstrdup(user_from_uid(file->st.st_uid, 1)); } if (file->group != NULL) { gid_t gid; if (gid_from_group(file->group, &gid) == -1) errx(2, "group %s unknown", file->group); file->st.st_gid = gid; } else { file->group = xstrdup(group_from_gid(file->st.st_gid, 1)); } }
/* * Given a UID or user name in a string, return the UID. If an empty string * was given, returns -1. If silent is 0, exits on invalid user names/UIDs; * otherwise, returns -1. */ uid_t a_uid(const char *s, int silent) { const char *errstr; uid_t uid; if (*s == '\0') /* Argument was "[:.]gid". */ return ((uid_t)-1); /* User name was given. */ if (uid_from_user(s, &uid) != -1) return (uid); /* UID was given. */ uid = (uid_t)strtonum(s, 0, UID_MAX, &errstr); if (errstr) { if (silent) return ((uid_t)-1); else errx(1, "user is %s: %s", errstr, s); } return (uid); }
static int read_mtree_keywords(FILE *fp, fsnode *node) { char keyword[PATH_MAX]; char *name, *p, *value; gid_t gid; uid_t uid; struct stat *st, sb; intmax_t num; u_long flset, flclr; int error, istemp, type; st = &node->inode->st; do { error = skip_over(fp, " \t"); if (error) break; error = read_word(fp, keyword, sizeof(keyword)); if (error) break; if (keyword[0] == '\0') break; value = strchr(keyword, '='); if (value != NULL) *value++ = '\0'; /* * We use EINVAL, ENOATTR, ENOSYS and ENXIO to signal * certain conditions: * EINVAL - Value provided for a keyword that does * not take a value. The value is ignored. * ENOATTR - Value missing for a keyword that needs * a value. The keyword is ignored. * ENOSYS - Unsupported keyword encountered. The * keyword is ignored. * ENXIO - Value provided for a keyword that does * not take a value. The value is ignored. */ switch (keyword[0]) { case 'c': if (strcmp(keyword, "contents") == 0) { if (value == NULL) { error = ENOATTR; break; } node->contents = strdup(value); } else error = ENOSYS; break; case 'f': if (strcmp(keyword, "flags") == 0) { if (value == NULL) { error = ENOATTR; break; } flset = flclr = 0; if (!strtofflags(&value, &flset, &flclr)) { st->st_flags &= ~flclr; st->st_flags |= flset; } else error = errno; } else error = ENOSYS; break; case 'g': if (strcmp(keyword, "gid") == 0) { if (value == NULL) { error = ENOATTR; break; } error = read_number(value, 10, &num, 0, UINT_MAX); if (!error) st->st_gid = num; } else if (strcmp(keyword, "gname") == 0) { if (value == NULL) { error = ENOATTR; break; } if (gid_from_group(value, &gid) == 0) st->st_gid = gid; else error = EINVAL; } else error = ENOSYS; break; case 'l': if (strcmp(keyword, "link") == 0) { if (value == NULL) { error = ENOATTR; break; } node->symlink = strdup(value); } else error = ENOSYS; break; case 'm': if (strcmp(keyword, "mode") == 0) { if (value == NULL) { error = ENOATTR; break; } if (value[0] >= '0' && value[0] <= '9') { error = read_number(value, 8, &num, 0, 07777); if (!error) { st->st_mode &= S_IFMT; st->st_mode |= num; } } else { /* Symbolic mode not supported. */ error = EINVAL; break; } } else error = ENOSYS; break; case 'o': if (strcmp(keyword, "optional") == 0) { if (value != NULL) error = ENXIO; node->flags |= FSNODE_F_OPTIONAL; } else error = ENOSYS; break; case 's': if (strcmp(keyword, "size") == 0) { if (value == NULL) { error = ENOATTR; break; } error = read_number(value, 10, &num, 0, INTMAX_MAX); if (!error) st->st_size = num; } else error = ENOSYS; break; case 't': if (strcmp(keyword, "time") == 0) { if (value == NULL) { error = ENOATTR; break; } p = strchr(value, '.'); if (p != NULL) *p++ = '\0'; error = read_number(value, 10, &num, 0, INTMAX_MAX); if (error) break; st->st_atime = num; st->st_ctime = num; st->st_mtime = num; if (p == NULL) break; error = read_number(p, 10, &num, 0, INTMAX_MAX); if (error) break; if (num != 0) error = EINVAL; } else if (strcmp(keyword, "type") == 0) { if (value == NULL) { error = ENOATTR; break; } if (strcmp(value, "dir") == 0) node->type = S_IFDIR; else if (strcmp(value, "file") == 0) node->type = S_IFREG; else if (strcmp(value, "link") == 0) node->type = S_IFLNK; else error = EINVAL; } else error = ENOSYS; break; case 'u': if (strcmp(keyword, "uid") == 0) { if (value == NULL) { error = ENOATTR; break; } error = read_number(value, 10, &num, 0, UINT_MAX); if (!error) st->st_uid = num; } else if (strcmp(keyword, "uname") == 0) { if (value == NULL) { error = ENOATTR; break; } if (uid_from_user(value, &uid) == 0) st->st_uid = uid; else error = EINVAL; } else error = ENOSYS; break; default: error = ENOSYS; break; } switch (error) { case EINVAL: mtree_error("%s: invalid value '%s'", keyword, value); break; case ENOATTR: mtree_error("%s: keyword needs a value", keyword); break; case ENOSYS: mtree_warning("%s: unsupported keyword", keyword); break; case ENXIO: mtree_error("%s: keyword does not take a value", keyword); break; } } while (1); if (error) return (error); st->st_mode = (st->st_mode & ~S_IFMT) | node->type; /* Nothing more to do for the global defaults. */ if (node->name == NULL) return (0); /* * Be intelligent about the file type. */ if (node->contents != NULL) { if (node->symlink != NULL) { mtree_error("%s: both link and contents keywords " "defined", node->name); return (0); } type = S_IFREG; } else if (node->type != 0) { type = node->type; if (type == S_IFREG) { /* the named path is the default contents */ node->contents = mtree_file_path(node); } } else type = (node->symlink != NULL) ? S_IFLNK : S_IFDIR; if (node->type == 0) node->type = type; if (node->type != type) { mtree_error("%s: file type and defined keywords to not match", node->name); return (0); } st->st_mode = (st->st_mode & ~S_IFMT) | node->type; if (node->contents == NULL) return (0); name = mtree_resolve(node->contents, &istemp); if (name == NULL) return (errno); if (stat(name, &sb) != 0) { mtree_error("%s: contents file '%s' not found", node->name, name); free(name); return (0); } /* * Check for hardlinks. If the contents key is used, then the check * will only trigger if the contents file is a link even if it is used * by more than one file */ if (sb.st_nlink > 1) { fsinode *curino; st->st_ino = sb.st_ino; st->st_dev = sb.st_dev; curino = link_check(node->inode); if (curino != NULL) { free(node->inode); node->inode = curino; node->inode->nlink++; } } free(node->contents); node->contents = name; st->st_size = sb.st_size; return (0); }
int main(int argc, char **argv) { char *name, *p; mode_t mode; dev_t dev; pack_t *pack; u_long numbers[MAXARGS]; int n, ch, fifo, hasformat; int r_flag = 0; /* force: delete existing entry */ #ifdef KERN_DRIVERS int l_flag = 0; /* list device names and numbers */ int major; #endif void *modes = 0; uid_t uid = -1; gid_t gid = -1; int rval; dev = 0; fifo = hasformat = 0; pack = pack_native; #ifdef KERN_DRIVERS while ((ch = getopt(argc, argv, "lrRF:g:m:u:")) != -1) { #else while ((ch = getopt(argc, argv, "rRF:g:m:u:")) != -1) { #endif switch (ch) { #ifdef KERN_DRIVERS case 'l': l_flag = 1; break; #endif case 'r': r_flag = 1; break; case 'R': r_flag = 2; break; case 'F': pack = pack_find(optarg); if (pack == NULL) errx(1, "invalid format: %s", optarg); hasformat++; break; case 'g': if (optarg[0] == '#') { gid = strtol(optarg + 1, &p, 10); if (*p == 0) break; } if (gid_name(optarg, &gid) == 0) break; gid = strtol(optarg, &p, 10); if (*p == 0) break; errx(1, "%s: invalid group name", optarg); case 'm': modes = setmode(optarg); if (modes == NULL) err(1, "Cannot set file mode `%s'", optarg); break; case 'u': if (optarg[0] == '#') { uid = strtol(optarg + 1, &p, 10); if (*p == 0) break; } if (uid_from_user(optarg, &uid) == 0) break; uid = strtol(optarg, &p, 10); if (*p == 0) break; errx(1, "%s: invalid user name", optarg); default: case '?': usage(); } } argc -= optind; argv += optind; #ifdef KERN_DRIVERS if (l_flag) { print_device_info(argv); return 0; } #endif if (argc < 2 || argc > 10) usage(); name = *argv; argc--; argv++; umask(mode = umask(0)); mode = (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) & ~mode; if (argv[0][1] != '\0') goto badtype; switch (*argv[0]) { case 'c': mode |= S_IFCHR; break; case 'b': mode |= S_IFBLK; break; case 'p': if (hasformat) errx(1, "format is meaningless for fifos"); mode |= S_IFIFO; fifo = 1; break; default: badtype: errx(1, "node type must be 'b', 'c' or 'p'."); } argc--; argv++; if (fifo) { if (argc != 0) usage(); } else { if (argc < 1 || argc > MAXARGS) usage(); } for (n = 0; n < argc; n++) { errno = 0; numbers[n] = strtoul(argv[n], &p, 0); if (*p == 0 && errno == 0) continue; #ifdef KERN_DRIVERS if (argc == 2 && n == 0) { major = major_from_name(argv[0], mode); if (major != -1) { numbers[0] = major; continue; } if (!isdigit(*(unsigned char *)argv[0])) errx(1, "unknown driver: %s", argv[0]); } #endif errx(1, "invalid number: %s", argv[n]); } switch (argc) { case 0: dev = 0; break; case 1: dev = numbers[0]; break; default: dev = callPack(pack, argc, numbers); break; } if (modes != NULL) mode = getmode(modes, mode); umask(0); rval = fifo ? mkfifo(name, mode) : mknod(name, mode, dev); if (rval < 0 && errno == EEXIST && r_flag) { struct stat sb; if (lstat(name, &sb) != 0 || (!fifo && sb.st_rdev != dev)) sb.st_mode = 0; if ((sb.st_mode & S_IFMT) == (mode & S_IFMT)) { if (r_flag == 1) /* Ignore permissions and user/group */ return 0; if (sb.st_mode != mode) rval = chmod(name, mode); else rval = 0; } else { unlink(name); rval = fifo ? mkfifo(name, mode) : mknod(name, mode, dev); } } if (rval < 0) err(1, "%s", name); if ((uid != (uid_t)-1 || gid != (uid_t)-1) && chown(name, uid, gid) == -1) /* XXX Should we unlink the files here? */ warn("%s: uid/gid not changed", name); return 0; } static void usage(void) { const char *progname = getprogname(); (void)fprintf(stderr, "usage: %s [-rR] [-F format] [-m mode] [-u user] [-g group]\n", progname); (void)fprintf(stderr, #ifdef KERN_DRIVERS " [ name [b | c] [major | driver] minor\n" #else " [ name [b | c] major minor\n" #endif " | name [b | c] major unit subunit\n" " | name [b | c] number\n" " | name p ]\n"); #ifdef KERN_DRIVERS (void)fprintf(stderr, " %s -l [driver] ...\n", progname); #endif exit(1); } static int gid_name(const char *name, gid_t *gid) { struct group *g; g = getgrnam(name); if (!g) return -1; *gid = g->gr_gid; return 0; } static dev_t callPack(pack_t *f, int n, u_long *numbers) { dev_t d; const char *error = NULL; d = (*f)(n, numbers, &error); if (error != NULL) errx(1, "%s", error); return d; }
int main(int argc, char *argv[]) { struct stat from_sb, to_sb; mode_t *set; u_long fset; int ch, no_target; u_int iflags; char *p; const char *to_name; iflags = 0; group = owner = NULL; while ((ch = getopt(argc, argv, "B:bCcD:df:g:h:l:M:m:N:o:pSsT:Uv")) != -1) switch((char)ch) { case 'B': suffix = optarg; /* FALLTHROUGH */ case 'b': dobackup = 1; break; case 'C': docompare = 1; break; case 'c': /* For backwards compatibility. */ break; case 'D': destdir = optarg; break; case 'd': dodir = 1; break; case 'f': haveopt_f = 1; fflags = optarg; break; case 'g': haveopt_g = 1; group = optarg; break; case 'h': digest = optarg; break; case 'l': for (p = optarg; *p != '\0'; p++) switch (*p) { case 's': dolink &= ~(LN_HARD|LN_MIXED); dolink |= LN_SYMBOLIC; break; case 'h': dolink &= ~(LN_SYMBOLIC|LN_MIXED); dolink |= LN_HARD; break; case 'm': dolink &= ~(LN_SYMBOLIC|LN_HARD); dolink |= LN_MIXED; break; case 'a': dolink &= ~LN_RELATIVE; dolink |= LN_ABSOLUTE; break; case 'r': dolink &= ~LN_ABSOLUTE; dolink |= LN_RELATIVE; break; default: errx(1, "%c: invalid link type", *p); /* NOTREACHED */ } break; case 'M': metafile = optarg; break; case 'm': haveopt_m = 1; if (!(set = setmode(optarg))) errx(EX_USAGE, "invalid file mode: %s", optarg); mode = getmode(set, 0); free(set); break; case 'N': if (!setup_getid(optarg)) err(EX_OSERR, "Unable to use user and group " "databases in `%s'", optarg); break; case 'o': haveopt_o = 1; owner = optarg; break; case 'p': docompare = dopreserve = 1; break; case 'S': safecopy = 1; break; case 's': dostrip = 1; break; case 'T': tags = optarg; break; case 'U': dounpriv = 1; break; case 'v': verbose = 1; break; case '?': default: usage(); } argc -= optind; argv += optind; /* some options make no sense when creating directories */ if (dostrip && dodir) { warnx("-d and -s may not be specified together"); usage(); } if (getenv("DONTSTRIP") != NULL) { warnx("DONTSTRIP set - will not strip installed binaries"); dostrip = 0; } /* must have at least two arguments, except when creating directories */ if (argc == 0 || (argc == 1 && !dodir)) usage(); if (digest != NULL) { if (strcmp(digest, "none") == 0) { digesttype = DIGEST_NONE; } else if (strcmp(digest, "md5") == 0) { digesttype = DIGEST_MD5; } else if (strcmp(digest, "rmd160") == 0) { digesttype = DIGEST_RIPEMD160; } else if (strcmp(digest, "sha1") == 0) { digesttype = DIGEST_SHA1; } else if (strcmp(digest, "sha256") == 0) { digesttype = DIGEST_SHA256; } else if (strcmp(digest, "sha512") == 0) { digesttype = DIGEST_SHA512; } else { warnx("unknown digest `%s'", digest); usage(); } } /* need to make a temp copy so we can compare stripped version */ if (docompare && dostrip) safecopy = 1; /* get group and owner id's */ if (group != NULL && !dounpriv) { if (gid_from_group(group, &gid) == -1) { id_t id; if (!parseid(group, &id)) errx(1, "unknown group %s", group); gid = id; } } else gid = (gid_t)-1; if (owner != NULL && !dounpriv) { if (uid_from_user(owner, &uid) == -1) { id_t id; if (!parseid(owner, &id)) errx(1, "unknown user %s", owner); uid = id; } } else uid = (uid_t)-1; if (fflags != NULL && !dounpriv) { if (strtofflags(&fflags, &fset, NULL)) errx(EX_USAGE, "%s: invalid flag", fflags); iflags |= SETFLAGS; } if (metafile != NULL) { if ((metafp = fopen(metafile, "a")) == NULL) warn("open %s", metafile); } else digesttype = DIGEST_NONE; if (dodir) { for (; *argv != NULL; ++argv) install_dir(*argv); exit(EX_OK); /* NOTREACHED */ } to_name = argv[argc - 1]; no_target = stat(to_name, &to_sb); if (!no_target && S_ISDIR(to_sb.st_mode)) { if (dolink & LN_SYMBOLIC) { if (lstat(to_name, &to_sb) != 0) err(EX_OSERR, "%s vanished", to_name); if (S_ISLNK(to_sb.st_mode)) { if (argc != 2) { errno = ENOTDIR; err(EX_USAGE, "%s", to_name); } install(*argv, to_name, fset, iflags); exit(EX_OK); } } for (; *argv != to_name; ++argv) install(*argv, to_name, fset, iflags | DIRECTORY); exit(EX_OK); /* NOTREACHED */ } /* can't do file1 file2 directory/file */ if (argc != 2) { if (no_target) warnx("target directory `%s' does not exist", argv[argc - 1]); else warnx("target `%s' is not a directory", argv[argc - 1]); usage(); } if (!no_target && !dolink) { if (stat(*argv, &from_sb)) err(EX_OSERR, "%s", *argv); if (!S_ISREG(to_sb.st_mode)) { errno = EFTYPE; err(EX_OSERR, "%s", to_name); } if (to_sb.st_dev == from_sb.st_dev && to_sb.st_ino == from_sb.st_ino) errx(EX_USAGE, "%s and %s are the same file", *argv, to_name); } install(*argv, to_name, fset, iflags); exit(EX_OK); /* NOTREACHED */ }
int main(int argc, char *argv[]) { struct kinfo_proc *kp, **kinfo; struct varent *vent; struct winsize ws; dev_t ttydev; pid_t pid; uid_t uid; int all, ch, flag, i, fmt, lineno, nentries; int prtheader, showthreads, wflag, kflag, what, Uflag, xflg; char *nlistf, *memf, *swapf, *cols, errbuf[_POSIX2_LINE_MAX]; setlocale(LC_CTYPE, ""); termwidth = 0; if ((cols = getenv("COLUMNS")) != NULL) termwidth = strtonum(cols, 1, INT_MAX, NULL); if (termwidth == 0 && (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0 || ioctl(STDERR_FILENO, TIOCGWINSZ, &ws) == 0 || ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == 0) && ws.ws_col > 0) termwidth = ws.ws_col - 1; if (termwidth == 0) termwidth = 79; if (argc > 1) argv[1] = kludge_oldps_options(argv[1]); all = fmt = prtheader = showthreads = wflag = kflag = Uflag = xflg = 0; pid = -1; uid = 0; ttydev = NODEV; memf = nlistf = swapf = NULL; while ((ch = getopt(argc, argv, "AaCcegHhjkLlM:mN:O:o:p:rSTt:U:uvW:wx")) != -1) switch (ch) { case 'A': all = 1; xflg = 1; break; case 'a': all = 1; break; case 'C': break; /* no-op */ case 'c': commandonly = 1; break; case 'e': /* XXX set ufmt */ needenv = 1; break; case 'g': break; /* no-op */ case 'H': showthreads = 1; break; case 'h': prtheader = ws.ws_row > 5 ? ws.ws_row : 22; break; case 'j': parsefmt(jfmt); fmt = 1; jfmt[0] = '\0'; break; case 'k': kflag = 1; break; case 'L': showkey(); exit(0); case 'l': parsefmt(lfmt); fmt = 1; lfmt[0] = '\0'; break; case 'M': memf = optarg; break; case 'm': sortby = SORTMEM; break; case 'N': nlistf = optarg; break; case 'O': parsefmt(o1); parsefmt(optarg); parsefmt(o2); o1[0] = o2[0] = '\0'; fmt = 1; break; case 'o': parsefmt(optarg); fmt = 1; break; case 'p': pid = atol(optarg); xflg = 1; break; case 'r': sortby = SORTCPU; break; case 'S': sumrusage = 1; break; case 'T': if ((optarg = ttyname(STDIN_FILENO)) == NULL) errx(1, "stdin: not a terminal"); /* FALLTHROUGH */ case 't': { struct stat sb; char *ttypath, pathbuf[PATH_MAX]; if (strcmp(optarg, "co") == 0) ttypath = _PATH_CONSOLE; else if (*optarg != '/') { int r = snprintf(pathbuf, sizeof(pathbuf), "%s%s", _PATH_TTY, optarg); if (r < 0 || r > sizeof(pathbuf)) errx(1, "%s: too long\n", optarg); ttypath = pathbuf; } else ttypath = optarg; if (stat(ttypath, &sb) == -1) err(1, "%s", ttypath); if (!S_ISCHR(sb.st_mode)) errx(1, "%s: not a terminal", ttypath); ttydev = sb.st_rdev; break; } case 'U': if (uid_from_user(optarg, &uid) == -1) errx(1, "%s: no such user", optarg); Uflag = xflg = 1; break; case 'u': parsefmt(ufmt); sortby = SORTCPU; fmt = 1; ufmt[0] = '\0'; break; case 'v': parsefmt(vfmt); sortby = SORTMEM; fmt = 1; vfmt[0] = '\0'; break; case 'W': swapf = optarg; break; case 'w': if (wflag) termwidth = UNLIMITED; else if (termwidth < 131) termwidth = 131; wflag = 1; break; case 'x': xflg = 1; break; default: usage(); } argc -= optind; argv += optind; #define BACKWARD_COMPATIBILITY #ifdef BACKWARD_COMPATIBILITY if (*argv) { nlistf = *argv; if (*++argv) { memf = *argv; if (*++argv) swapf = *argv; } } #endif if (nlistf == NULL && memf == NULL && swapf == NULL) { kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf); kvm_sysctl_only = 1; } else { kd = kvm_openfiles(nlistf, memf, swapf, O_RDONLY, errbuf); } if (kd == NULL) errx(1, "%s", errbuf); if (unveil(_PATH_DEVDB, "r") == -1 && errno != ENOENT) err(1, "unveil"); if (unveil(_PATH_DEV, "r") == -1 && errno != ENOENT) err(1, "unveil"); if (swapf) if (unveil(swapf, "r") == -1) err(1, "unveil"); if (nlistf) if (unveil(nlistf, "r") == -1) err(1, "unveil"); if (memf) if (unveil(memf, "r") == -1) err(1, "unveil"); if (pledge("stdio rpath getpw ps", NULL) == -1) err(1, "pledge"); if (!fmt) { if (showthreads) parsefmt(tfmt); else parsefmt(dfmt); } /* XXX - should be cleaner */ if (!all && ttydev == NODEV && pid == -1 && !Uflag) { uid = getuid(); Uflag = 1; } /* * scan requested variables, noting what structures are needed, * and adjusting header widths as appropriate. */ scanvars(); if (neednlist && !nlistread) (void) donlist(); /* * get proc list */ if (Uflag) { what = KERN_PROC_UID; flag = uid; } else if (ttydev != NODEV) { what = KERN_PROC_TTY; flag = ttydev; } else if (pid != -1) { what = KERN_PROC_PID; flag = pid; } else if (kflag) { what = KERN_PROC_KTHREAD; flag = 0; } else { what = KERN_PROC_ALL; flag = 0; } if (showthreads) what |= KERN_PROC_SHOW_THREADS; /* * select procs */ kp = kvm_getprocs(kd, what, flag, sizeof(*kp), &nentries); if (kp == NULL) errx(1, "%s", kvm_geterr(kd)); /* * print header */ printheader(); if (nentries == 0) exit(1); /* * sort proc list, we convert from an array of structs to an array * of pointers to make the sort cheaper. */ if ((kinfo = reallocarray(NULL, nentries, sizeof(*kinfo))) == NULL) err(1, "failed to allocate memory for proc pointers"); for (i = 0; i < nentries; i++) kinfo[i] = &kp[i]; qsort(kinfo, nentries, sizeof(*kinfo), pscomp); /* * for each proc, call each variable output function. */ for (i = lineno = 0; i < nentries; i++) { if (showthreads == 0 && (kinfo[i]->p_flag & P_THREAD) != 0) continue; if (xflg == 0 && ((int)kinfo[i]->p_tdev == NODEV || (kinfo[i]->p_psflags & PS_CONTROLT ) == 0)) continue; if (showthreads && kinfo[i]->p_tid == -1) continue; for (vent = vhead; vent; vent = vent->next) { (vent->var->oproc)(kinfo[i], vent); if (vent->next != NULL) (void)putchar(' '); } (void)putchar('\n'); if (prtheader && lineno++ == prtheader - 4) { (void)putchar('\n'); printheader(); lineno = 0; } } exit(eval); }