Module Name:    src
Committed By:   pooka
Date:           Sun Apr 11 15:08:17 UTC 2010

Modified Files:
        src/usr.sbin/puffs/mount_sysctlfs: mount_sysctlfs.8 sysctlfs.c

Log Message:
Add raw mode, which skips ASCII'ification and can be used if reading
structures from the kernel into debug program memory is desired.


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/usr.sbin/puffs/mount_sysctlfs/mount_sysctlfs.8
cvs rdiff -u -r1.13 -r1.14 src/usr.sbin/puffs/mount_sysctlfs/sysctlfs.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.sbin/puffs/mount_sysctlfs/mount_sysctlfs.8
diff -u src/usr.sbin/puffs/mount_sysctlfs/mount_sysctlfs.8:1.1 src/usr.sbin/puffs/mount_sysctlfs/mount_sysctlfs.8:1.2
--- src/usr.sbin/puffs/mount_sysctlfs/mount_sysctlfs.8:1.1	Fri Aug 10 07:59:32 2007
+++ src/usr.sbin/puffs/mount_sysctlfs/mount_sysctlfs.8	Sun Apr 11 15:08:17 2010
@@ -1,4 +1,4 @@
-.\"	$NetBSD: mount_sysctlfs.8,v 1.1 2007/08/10 07:59:32 pooka Exp $
+.\"	$NetBSD: mount_sysctlfs.8,v 1.2 2010/04/11 15:08:17 pooka Exp $
 .\"
 .\" Copyright (c) 2007 Antti Kantee.  All rights reserved.
 .\"
@@ -23,7 +23,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd August 10, 2007
+.Dd April 11, 2010
 .Dt MOUNT_SYSCTLFS 8
 .Os
 .Sh NAME
@@ -32,6 +32,7 @@
 .Sh SYNOPSIS
 .Nm
 .Op Fl o Ar mntopts
+.Op Fl r
 .Ar sysctlfs
 .Ar mount_point
 .Sh DESCRIPTION
@@ -41,6 +42,11 @@
 .Xr sysctl 8
 hierarchy through the file system namespace.
 It is possible to browse the tree, query node values and modify them.
+By default, the node contents are interpreted as ASCII.
+If the
+.Fl r
+flag is given, the server uses raw mode and displays node contents as
+they are received from the kernel (binary).
 .Sh SEE ALSO
 .Xr puffs 3 ,
 .Xr puffs 4 ,
@@ -52,4 +58,6 @@
 utility first appeared in
 .Nx 5.0 .
 .Sh CAVEATS
-Tree nodes of type "struct" are not accessible through this interface.
+Raw mode
+.Op Fl r
+does not currently support node modification.

Index: src/usr.sbin/puffs/mount_sysctlfs/sysctlfs.c
diff -u src/usr.sbin/puffs/mount_sysctlfs/sysctlfs.c:1.13 src/usr.sbin/puffs/mount_sysctlfs/sysctlfs.c:1.14
--- src/usr.sbin/puffs/mount_sysctlfs/sysctlfs.c:1.13	Sun Apr 11 08:30:17 2010
+++ src/usr.sbin/puffs/mount_sysctlfs/sysctlfs.c	Sun Apr 11 15:08:17 2010
@@ -1,6 +1,6 @@
-/*	$NetBSD: sysctlfs.c,v 1.13 2010/04/11 08:30:17 pooka Exp $	*/
+/*	$NetBSD: sysctlfs.c,v 1.14 2010/04/11 15:08:17 pooka Exp $	*/
 
-/*
+/*-
  * Copyright (c) 2006, 2007  Antti Kantee.  All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -33,7 +33,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: sysctlfs.c,v 1.13 2010/04/11 08:30:17 pooka Exp $");
+__RCSID("$NetBSD: sysctlfs.c,v 1.14 2010/04/11 15:08:17 pooka Exp $");
 #endif /* !lint */
 
 #include <sys/types.h>
@@ -77,6 +77,8 @@
 static uid_t fileuid;
 static gid_t filegid;
 
+static int rflag;
+
 #define ISADIR(a) ((SYSCTL_TYPE(a->sysctl_flags) == CTLTYPE_NODE))
 #define SFS_MAXFILE 32768
 #define SFS_NODEPERDIR 128
@@ -115,7 +117,7 @@
 
 static int
 sysctlfs_pathtransform(struct puffs_usermount *pu,
-	const struct puffs_pathobj *p, const const struct puffs_cn *pcn,
+	const struct puffs_pathobj *p, const struct puffs_cn *pcn,
 	struct puffs_pathobj *res)
 {
 
@@ -230,7 +232,7 @@
 
 	mntflags = pflags = 0;
 	detach = 1;
-	while ((ch = getopt(argc, argv, "o:s")) != -1) {
+	while ((ch = getopt(argc, argv, "o:rs")) != -1) {
 		switch (ch) {
 		case 'o':
 			mp = getmntopts(optarg, puffsmopts, &mntflags, &pflags);
@@ -238,6 +240,9 @@
 				err(1, "getmntopts");
 			freemntopts(mp);
 			break;
+		case 'r':
+			rflag = 1;
+			break;
 		case 's':
 			detach = 0;
 			break;
@@ -370,29 +375,42 @@
 }
 
 static void
-doprint(struct sfsnode *sfs, struct puffs_pathobj *po,
-	char *buf, size_t bufsize)
+getnodedata(struct sfsnode *sfs, struct puffs_pathobj *po,
+	char *buf, size_t *bufsize)
 {
 	size_t sz;
+	int error = 0;
 
 	assert(!ISADIR(sfs));
 
-	memset(buf, 0, bufsize);
+	memset(buf, 0, *bufsize);
 	switch (SYSCTL_TYPE(sfs->sysctl_flags)) {
 	case CTLTYPE_INT: {
 		int i;
 		sz = sizeof(int);
-		if (sysctl(po->po_path, po->po_len, &i, &sz, NULL, 0) == -1)
+		assert(sz <= *bufsize);
+		if (sysctl(po->po_path, po->po_len, &i, &sz, NULL, 0) == -1) {
+			error = errno;
 			break;
-		snprintf(buf, bufsize, "%d", i);
+		}
+		if (rflag)
+			memcpy(buf, &i, sz);
+		else
+			snprintf(buf, *bufsize, "%d", i);
 		break;
 	}
 	case CTLTYPE_QUAD: {
 		quad_t q;
 		sz = sizeof(q);
-		if (sysctl(po->po_path, po->po_len, &q, &sz, NULL, 0) == -1)
+		assert(sz <= *bufsize);
+		if (sysctl(po->po_path, po->po_len, &q, &sz, NULL, 0) == -1) {
+			error = errno;
 			break;
-		snprintf(buf, bufsize, "%" PRId64, q);
+		}
+		if (rflag)
+			memcpy(buf, &q, sz);
+		else
+			snprintf(buf, *bufsize, "%" PRId64, q);
 		break;
 	}
 	case CTLTYPE_STRUCT: {
@@ -400,24 +418,44 @@
 		unsigned i;
 
 		sz = sizeof(snode);
-		if (sysctl(po->po_path, po->po_len, snode, &sz, NULL, 0) == -1)
+		assert(sz <= *bufsize);
+		if (sysctl(po->po_path, po->po_len, snode, &sz, NULL, 0) == -1){
+			error = errno;
 			break;
-		for (i = 0; i < sz && 2*i < bufsize; i++) {
-			sprintf(&buf[2*i], "%02x", snode[i]);
 		}
-		buf[2*i] = '\0';
+		if (rflag) {
+			memcpy(buf, &snode, sz);
+		} else {
+			for (i = 0; i < sz && 2*i < *bufsize; i++) {
+				sprintf(&buf[2*i], "%02x", snode[i]);
+			}
+			buf[2*i] = '\0';
+		}
 		break;
 	}
 	case CTLTYPE_STRING: {
-		sz = bufsize;
-		if (sysctl(po->po_path, po->po_len, buf, &sz, NULL, 0) == -1)
+		sz = *bufsize;
+		assert(sz <= *bufsize);
+		if (sysctl(po->po_path, po->po_len, buf, &sz, NULL, 0) == -1) {
+			error = errno;
 			break;
+		}
 		break;
 	}
 	default:
-		snprintf(buf, bufsize, "invalid sysctl CTLTYPE");
+		snprintf(buf, *bufsize, "invalid sysctl CTLTYPE");
 		break;
 	}
+
+	if (error) {
+		*bufsize = 0;
+		return;
+	}
+
+	if (rflag)
+		*bufsize = sz;
+	else
+		*bufsize = strlen(buf);
 }
 
 static int
@@ -448,12 +486,16 @@
 getsize(struct sfsnode *sfs, struct puffs_pathobj *po)
 {
 	char buf[SFS_MAXFILE];
+	size_t sz = sizeof(buf);
 
 	if (ISADIR(sfs))
 		return getlinks(sfs, po) * 16; /* totally arbitrary */
 
-	doprint(sfs, po, buf, sizeof(buf));
-	return strlen(buf) + 1;
+	getnodedata(sfs, po, buf, &sz);
+	if (rflag)
+		return sz;
+	else
+		return sz + 1; /* for \n, not \0 */
 }
 
 int
@@ -630,16 +672,17 @@
 	char localbuf[SFS_MAXFILE];
 	struct puffs_node *pn = opc;
 	struct sfsnode *sfs = pn->pn_data;
+	size_t sz = sizeof(localbuf);
 	int xfer;
 
 	if (ISADIR(sfs))
 		return EISDIR;
 
-	doprint(sfs, &pn->pn_po, localbuf, sizeof(localbuf));
-	if ((ssize_t)strlen(localbuf) < offset)
+	getnodedata(sfs, &pn->pn_po, localbuf, &sz);
+	if ((ssize_t)sz < offset)
 		xfer = 0;
 	else
-		xfer = MIN(*resid, strlen(localbuf) - offset);
+		xfer = MIN(*resid, sz - offset);
 
 	if (xfer <= 0)
 		return 0;
@@ -647,7 +690,7 @@
 	memcpy(buf, localbuf + offset, xfer);
 	*resid -= xfer;
 
-	if (*resid) {
+	if (*resid && !rflag) {
 		buf[xfer] = '\n';
 		(*resid)--;
 	}
@@ -665,6 +708,14 @@
 	long long ll;
 	int i, rv;
 
+	/*
+	 * I picked the wrong day to ... um, the wrong place to return errors
+	 */
+
+	/* easy to support, but just unavailable now */
+	if (rflag)
+		return EOPNOTSUPP;
+
 	if (puffs_cred_isjuggernaut(cred) == 0)
 		return EACCES;
 

Reply via email to