Index: uspace/app/sysinfo/sysinfo.c
===================================================================
--- uspace/app/sysinfo/sysinfo.c	(revision 9a426d1f629f275455938b21d553365bb5146fb0)
+++ uspace/app/sysinfo/sysinfo.c	(revision dabbe28b7f002b874c6ae98cc216d63fe2c65d82)
@@ -37,32 +37,104 @@
 #include <stdio.h>
 #include <sysinfo.h>
+#include <malloc.h>
 #include <sys/types.h>
 
-static int print_item_val(char *ipath);
-static int print_item_data(char *ipath);
+static void dump_bytes_hex(char *data, size_t size)
+{
+	for (size_t i = 0; i < size; i++) {
+		if (i > 0)
+			putchar(' ');
+		printf("0x%02x", (uint8_t) data[i]);
+	}
+}
 
-static void dump_bytes_hex(char *data, size_t size);
-static void dump_bytes_text(char *data, size_t size);
+static void dump_bytes_text(char *data, size_t size)
+{
+	size_t offset = 0;
+	
+	while (offset < size) {
+		wchar_t c = str_decode(data, &offset, size);
+		printf("%lc", (wint_t) c);
+	}
+}
 
-static void print_syntax(void);
+static int print_item_val(char *ipath)
+{
+	sysarg_t value;
+	int rc = sysinfo_get_value(ipath, &value);
+	if (rc != EOK) {
+		printf("Error reading item '%s'.\n", ipath);
+		return rc;
+	}
+	
+	printf("%s -> %" PRIu64 " (0x%" PRIx64 ")\n", ipath,
+	    (uint64_t) value, (uint64_t) value);
+	
+	return EOK;
+}
+
+static int print_item_data(char *ipath)
+{
+	size_t size;
+	void *data = sysinfo_get_data(ipath, &size);
+	if (data == NULL) {
+		printf("Error reading item '%s'.\n", ipath);
+		return -1;
+	}
+	
+	printf("%s -> ", ipath);
+	dump_bytes_hex(data, size);
+	fputs(" ('", stdout);
+	dump_bytes_text(data, size);
+	fputs("')\n", stdout);
+	
+	return EOK;
+}
+
+static void print_keys(const char *path)
+{
+	size_t size;
+	char *keys = sysinfo_get_keys(path, &size);
+	if ((keys == NULL) || (size == 0))
+		return;
+	
+	size_t pos = 0;
+	while (pos < size) {
+		/* Process each key with sanity checks */
+		size_t cur_size = str_nsize(keys + pos, size - pos);
+		size_t path_size = str_size(path) + cur_size + 2;
+		char *cur_path = (char *) malloc(path_size);
+		if (cur_path == NULL)
+			break;
+		
+		if (path[0] != 0)
+			snprintf(cur_path, path_size, "%s.%s", path, keys + pos);
+		else
+			snprintf(cur_path, path_size, "%s", keys + pos);
+		
+		printf("%s\n", cur_path);
+		print_keys(cur_path);
+		
+		free(cur_path);
+		pos += cur_size + 1;
+	}
+	
+	free(keys);
+}
 
 int main(int argc, char *argv[])
 {
-	int rc;
-	char *ipath;
-	sysinfo_item_val_type_t tag;
-
 	if (argc != 2) {
-		print_syntax();
-		return 1;
+		/* Print keys */
+		print_keys("");
+		return 0;
 	}
-
-	ipath = argv[1];
-
-	tag = sysinfo_get_val_type(ipath);
-
+	
+	char *ipath = argv[1];
+	sysinfo_item_val_type_t tag = sysinfo_get_val_type(ipath);
+	
 	/* Silence warning */
-	rc = EOK;
-
+	int rc = 0;
+	
 	switch (tag) {
 	case SYSINFO_VAL_UNDEFINED:
@@ -82,72 +154,6 @@
 		break;
 	}
-
+	
 	return rc;
-}
-
-static int print_item_val(char *ipath)
-{
-	sysarg_t value;
-	int rc;
-
-	rc = sysinfo_get_value(ipath, &value);
-	if (rc != EOK) {
-		printf("Error reading item '%s'.\n", ipath);
-		return rc;
-	}
-
-	printf("%s -> %" PRIu64 " (0x%" PRIx64 ")\n", ipath,
-	    (uint64_t) value, (uint64_t) value);
-
-	return EOK;
-}
-
-static int print_item_data(char *ipath)
-{
-	void *data;
-	size_t size;
-
-	data = sysinfo_get_data(ipath, &size);
-	if (data == NULL) {
-		printf("Error reading item '%s'.\n", ipath);
-		return -1;
-	}
-
-	printf("%s -> ", ipath);
-	dump_bytes_hex(data, size);
-	fputs(" ('", stdout);
-	dump_bytes_text(data, size);
-	fputs("')\n", stdout);
-
-	return EOK;
-}
-
-static void dump_bytes_hex(char *data, size_t size)
-{
-	size_t i;
-
-	for (i = 0; i < size; ++i) {
-		if (i > 0) putchar(' ');
-		printf("0x%02x", (uint8_t) data[i]);
-	}
-}
-
-static void dump_bytes_text(char *data, size_t size)
-{
-	wchar_t c;
-	size_t offset;
-
-	offset = 0;
-
-	while (offset < size) {
-		c = str_decode(data, &offset, size);
-		printf("%lc", (wint_t) c);
-	}
-}
-
-
-static void print_syntax(void)
-{
-	printf("Syntax: sysinfo <item_path>\n");
 }
 
