summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2007-11-28 16:33:44 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2007-11-28 16:33:44 +0000
commit6f7c3a0e39179d0e37e9891c535f2c5814c88342 (patch)
tree48fdd0bd80be94d8f2ef70df2d2e61a314137837 /usr.sbin
parent49937de90c40cd165329fbfd7fe3227ba01ad165 (diff)
Be more careful with printf-style formats, and fix a few other niggles
ok tedu
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/pstat/pstat.813
-rw-r--r--usr.sbin/pstat/pstat.c93
2 files changed, 77 insertions, 29 deletions
diff --git a/usr.sbin/pstat/pstat.8 b/usr.sbin/pstat/pstat.8
index e756f187700..5118802848d 100644
--- a/usr.sbin/pstat/pstat.8
+++ b/usr.sbin/pstat/pstat.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: pstat.8,v 1.36 2007/11/28 15:49:11 jmc Exp $
+.\" $OpenBSD: pstat.8,v 1.37 2007/11/28 16:33:43 deraadt Exp $
.\" $NetBSD: pstat.8,v 1.9.4.1 1996/06/02 09:08:17 mrg Exp $
.\"
.\" Copyright (c) 1980, 1991, 1993, 1994
@@ -42,6 +42,7 @@
.Op Fl d Ar format
.Op Fl M Ar core
.Op Fl N Ar system
+.Op Ar symbols
.Sh DESCRIPTION
.Nm
displays open file entry, swap space utilization,
@@ -58,12 +59,14 @@ is specified.
The options are as follows:
.Bl -tag -width Ds
.It Fl d Ar format
-Print the values of symbols using the specified format.
+Print the values of
+.Ar symbols
+using the specified format.
.Ar format
is a
-.Xr printf 3
-format, without the leading percent.
-Symbol names are read from the remaining command line arguments.
+.Xr printf 3 Ns -style
+format, without the leading percent or precision specifiers.
+Symbol named are read from the remaining command line arguments.
Addresses may also be specified in hex.
.It Fl f
Print the open file table with these headings:
diff --git a/usr.sbin/pstat/pstat.c b/usr.sbin/pstat/pstat.c
index b790f00d2b6..d604b6861e4 100644
--- a/usr.sbin/pstat/pstat.c
+++ b/usr.sbin/pstat/pstat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pstat.c,v 1.68 2007/11/28 11:37:41 tedu Exp $ */
+/* $OpenBSD: pstat.c,v 1.69 2007/11/28 16:33:43 deraadt Exp $ */
/* $NetBSD: pstat.c,v 1.27 1996/10/23 22:50:06 cgd Exp $ */
/*-
@@ -40,7 +40,7 @@ static char copyright[] =
#if 0
from: static char sccsid[] = "@(#)pstat.c 8.9 (Berkeley) 2/16/94";
#else
-static char *rcsid = "$OpenBSD: pstat.c,v 1.68 2007/11/28 11:37:41 tedu Exp $";
+static char *rcsid = "$OpenBSD: pstat.c,v 1.69 2007/11/28 16:33:43 deraadt Exp $";
#endif
#endif /* not lint */
@@ -144,9 +144,8 @@ void vnodemode(void);
int
main(int argc, char *argv[])
{
- int fileflag = 0, swapflag = 0, ttyflag = 0, vnodeflag = 0;
+ int fileflag = 0, swapflag = 0, ttyflag = 0, vnodeflag = 0, ch;
char buf[_POSIX2_LINE_MAX];
- int ch;
const char *dformat = NULL;
extern char *optarg;
extern int optind;
@@ -196,6 +195,10 @@ main(int argc, char *argv[])
if (dformat && getuid())
errx(1, "Only root can use -k");
+
+ if ((dformat == 0 && argc > 0) || (dformat && argc == 0))
+ usage();
+
/*
* Discard setgid privileges if not the running kernel so that bad
* guys can't print interesting stuff from kernel memory.
@@ -214,15 +217,46 @@ main(int argc, char *argv[])
err(1, "setresgid");
if (dformat) {
struct nlist *nl;
- int longformat = 0, stringformat = 0;
- char format[5];
- if (*dformat == 'p' || *dformat == 'l')
+ int longformat = 0, stringformat = 0, error = 0, n;
+ char format[10], buf[1024];
+
+ n = strlen(dformat);
+ if (n == 0)
+ errx(1, "illegal format");
+
+ /*
+ * Support p, c, s, and {l, ll, h, hh, j, t, }[diouxX]
+ */
+ if (strcmp(dformat, "p") == 0)
longformat = sizeof(long) == 8;
- if (dformat[0] == 'l' && dformat[1] == 'l')
- longformat = 1;
+ else if (strcmp(dformat, "c") == 0)
+ ;
+ else if (strcmp(dformat, "s") == 0)
+ stringformat = 1;
+ else if (strchr("diouxX", dformat[n - 1])) {
+ char *ptable[] = { "l", "ll", "h", "hh", "j", "t", "" };
+ int i;
+
+ for (i = 0; i < sizeof(ptable)/sizeof(ptable[0]); i++) {
+ if (strlen(ptable[i]) == n - 1 &&
+ strncmp(ptable[i], dformat,
+ strlen(ptable[i])) == 0)
+ break;
+ }
+ if (i == sizeof(ptable)/sizeof(ptable[0]))
+ errx(1, "illegal format");
+
+ if (*dformat == 'l')
+ longformat = sizeof(long) == 8;
+ if (dformat[0] == 'l' && dformat[1] == 'l')
+ longformat = 1;
+ } else
+ errx(1, "illegal format");
+
if (*dformat == 's') {
stringformat = 1;
- snprintf(format, sizeof(format), "%%.8s");
+ snprintf(format, sizeof(format), "%%.%zus",
+ sizeof buf);
} else
snprintf(format, sizeof(format), "%%%s", dformat);
@@ -237,28 +271,39 @@ main(int argc, char *argv[])
kvm_nlist(kd, nl);
globalnl = nl;
for (i = 0; i < argc; i++) {
+ long long v;
+
printf("%s ", argv[i]);
if (!nl[i].n_value && argv[i][0] == '0') {
nl[i].n_value = strtoul(argv[i], NULL, 16);
nl[i].n_type = N_DATA;
}
- if (!nl[i].n_value)
+ if (!nl[i].n_value) {
printf("not found\n");
- else {
- long long v;
- printf("at %p: ", nl[i].n_value);
- if (nl[i].n_type == N_DATA) {
+ error++;
+ continue;
+ }
+
+ printf("at %p: ", (void *)nl[i].n_value);
+ if (nl[i].n_type == N_DATA) {
+ if (stringformat) {
+ KGET1(i, &buf, sizeof(buf), argv[i]);
+ buf[sizeof(buf) - 1] = '\0';
+ } else
KGET1(i, &v, sizeof(v), argv[i]);
- if (stringformat)
- printf(format, &v);
- else if (longformat)
- printf(format, v);
- else
- printf(format, (int)v);
- }
- printf("\n");
+ if (stringformat)
+ printf(format, &buf);
+ else if (longformat)
+ printf(format, v);
+ else
+ printf(format, (int)v);
}
+ printf("\n");
}
+ for (i = 0; i < argc; i++)
+ free(nl[i].n_name);
+ free(nl);
+ exit(error);
}
if (vnodeflag)
@@ -1143,6 +1188,6 @@ void
usage(void)
{
(void)fprintf(stderr,
- "usage: pstat [-fknsTtv] [-d format] [-M core] [-N system]\n");
+ "usage: pstat [-fknsTtv] [-d format] [-M core] [-N system] [symbols ...]\n");
exit(1);
}