Index: uspace/app/bdsh/cmds/modules/mount/mount.c
===================================================================
--- uspace/app/bdsh/cmds/modules/mount/mount.c	(revision afe1d1e203e5c589222f7579368f84a24d325f3c)
+++ uspace/app/bdsh/cmds/modules/mount/mount.c	(revision 5e3eea10eab5547b0c0e9d45abbeb98d19f9474d)
@@ -51,5 +51,5 @@
 {
 	static char helpfmt[] =
-	    "Usage:  %s <fstype> <mp> <dev> [<moptions>]\n";
+	    "Usage:  %s <fstype> <mp> [dev] [<moptions>]\n";
 	if (level == HELP_SHORT) {
 		printf("'%s' mounts a file system.\n", cmdname);
@@ -66,4 +66,5 @@
 	unsigned int argc;
 	const char *mopts = "";
+	const char *dev = "";
 	int rc, c, opt_ind;
 
@@ -79,13 +80,15 @@
 	}
 
-	if ((argc < 4) || (argc > 5)) {
+	if ((argc < 3) || (argc > 5)) {
 		printf("%s: invalid number of arguments. Try `mount --help'\n",
 		    cmdname);
 		return CMD_FAILURE;
 	}
+	if (argc > 3)
+		dev = argv[3];
 	if (argc == 5)
 		mopts = argv[4];
 
-	rc = mount(argv[1], argv[2], argv[3], mopts, 0);
+	rc = mount(argv[1], argv[2], dev, mopts, 0);
 	if (rc != EOK) {
 		printf("Unable to mount %s filesystem to %s on %s (rc=%d)\n",
Index: uspace/app/blkdump/Makefile
===================================================================
--- uspace/app/blkdump/Makefile	(revision 5e3eea10eab5547b0c0e9d45abbeb98d19f9474d)
+++ uspace/app/blkdump/Makefile	(revision 5e3eea10eab5547b0c0e9d45abbeb98d19f9474d)
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+USPACE_PREFIX = ../..
+LIBS = $(LIBBLOCK_PREFIX)/libblock.a
+EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX)
+BINARY = blkdump
+
+SOURCES = \
+	blkdump.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/blkdump/blkdump.c
===================================================================
--- uspace/app/blkdump/blkdump.c	(revision 5e3eea10eab5547b0c0e9d45abbeb98d19f9474d)
+++ uspace/app/blkdump/blkdump.c	(revision 5e3eea10eab5547b0c0e9d45abbeb98d19f9474d)
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2011 Martin Sucha
+ * Copyright (c) 2010 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup fs
+ * @{
+ */
+
+/**
+ * @file	blockdump.c
+ * @brief	Tool for dumping content of block devices
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <libblock.h>
+#include <mem.h>
+#include <devmap.h>
+#include <byteorder.h>
+#include <sys/types.h>
+#include <sys/typefmt.h>
+#include <inttypes.h>
+#include <errno.h>
+
+#define NAME	"blkdump"
+
+static void syntax_print(void);
+static void print_hex_row(uint8_t *data, size_t length, size_t bytes_per_row);
+
+int main(int argc, char **argv)
+{
+
+	int rc;
+	char *dev_path;
+	devmap_handle_t handle;
+	size_t block_size;
+	char *endptr;
+	aoff64_t block_offset = 0;
+	aoff64_t block_count = 1;
+	aoff64_t dev_nblocks;
+	uint8_t *data;
+	size_t data_offset;
+	aoff64_t current;
+	aoff64_t limit;
+	bool relative = false;
+	
+	if (argc < 2) {
+		printf(NAME ": Error, argument missing.\n");
+		syntax_print();
+		return 1;
+	}
+
+	--argc; ++argv;
+
+	if (str_cmp(*argv, "--relative") == 0) {
+		--argc; ++argv;
+		relative = true;
+	}
+	
+	if (str_cmp(*argv, "--offset") == 0) {
+		--argc; ++argv;
+		if (*argv == NULL) {
+			printf(NAME ": Error, argument missing (offset).\n");
+			syntax_print();
+			return 1;
+		}
+
+		block_offset = strtol(*argv, &endptr, 10);
+		if (*endptr != '\0') {
+			printf(NAME ": Error, invalid argument (offset).\n");
+			syntax_print();
+			return 1;
+		}
+
+		--argc; ++argv;
+	}
+	
+	if (str_cmp(*argv, "--count") == 0) {
+		--argc; ++argv;
+		if (*argv == NULL) {
+			printf(NAME ": Error, argument missing (count).\n");
+			syntax_print();
+			return 1;
+		}
+
+		block_count = strtol(*argv, &endptr, 10);
+		if (*endptr != '\0') {
+			printf(NAME ": Error, invalid argument (count).\n");
+			syntax_print();
+			return 1;
+		}
+
+		--argc; ++argv;
+	}
+
+	if (argc != 1) {
+		printf(NAME ": Error, unexpected argument.\n");
+		syntax_print();
+		return 1;
+	}
+
+	dev_path = *argv;
+
+	rc = devmap_device_get_handle(dev_path, &handle, 0);
+	if (rc != EOK) {
+		printf(NAME ": Error resolving device `%s'.\n", dev_path);
+		return 2;
+	}
+
+	rc = block_init(handle, 2048);
+	if (rc != EOK)  {
+		printf(NAME ": Error initializing libblock.\n");
+		return 2;
+	}
+
+	rc = block_get_bsize(handle, &block_size);
+	if (rc != EOK) {
+		printf(NAME ": Error determining device block size.\n");
+		return 2;
+	}
+
+	rc = block_get_nblocks(handle, &dev_nblocks);
+	if (rc != EOK) {
+		printf(NAME ": Warning, failed to obtain block device size.\n");
+	}
+
+	printf("Device %s has %" PRIuOFF64 " blocks, %" PRIuOFF64 " bytes each\n", dev_path, dev_nblocks, (aoff64_t) block_size);
+
+	data = malloc(block_size);
+	if (data == NULL) {
+		printf(NAME ": Error allocating data buffer of %" PRIuOFF64 " bytes", (aoff64_t) block_size);
+		block_fini(handle);
+		return 3;
+	}
+	
+	limit = block_offset + block_count;
+	for (current = block_offset; current < limit; current++) {
+		rc = block_read_direct(handle, current, 1, data);
+		if (rc != EOK) {
+			printf(NAME ": Error reading block at %" PRIuOFF64 " \n", current);
+			free(data);
+			return 3;
+		}
+		
+		printf("---- Block %" PRIuOFF64 " (at %" PRIuOFF64 ") ----\n", current, current*block_size);
+		
+		for (data_offset = 0; data_offset < block_size; data_offset += 16) {
+			if (relative) {
+				printf("%8" PRIxOFF64 ": ", (aoff64_t) data_offset);
+			}
+			else {
+				printf("%8" PRIxOFF64 ": ", current*block_size + data_offset);
+			}
+			print_hex_row(data+data_offset, block_size-data_offset, 16);
+			printf("\n");
+		}
+		printf("\n");
+	}
+	
+	free(data);
+
+	block_fini(handle);
+
+	return 0;
+}
+
+/**
+ * Print a row of 16 bytes as commonly seen in hexadecimal dumps
+ */
+static void print_hex_row(uint8_t *data, size_t length, size_t bytes_per_row) {
+	size_t pos;
+	uint8_t b;
+	
+	if (length > bytes_per_row) {
+		length = bytes_per_row;
+	}
+	
+	// Print hexadecimal values
+	for (pos = 0; pos < length; pos++) {
+		if (pos == length/2) {
+			printf(" ");
+		}
+		printf("%02hhX ", data[pos]);
+	}
+	
+	// pad with spaces if we have less than 16 bytes
+	for (pos = length; pos < bytes_per_row; pos++) {
+		if (pos == length/2) {
+			printf(" ");
+		}
+		printf("   ");
+	}
+	
+	// Print printable characters
+	for (pos = 0; pos < length; pos++) {
+		if (pos == length/2) {
+			printf(" ");
+		}
+		b = data[pos];
+		if (b >= 32 && b < 128) {
+			putchar(b);
+		}
+		else {
+			putchar('.');
+		}
+	}
+}
+
+static void syntax_print(void)
+{
+	printf("syntax: blkdump [--relative] [--offset <num_blocks>] [--count <num_blocks>] <device_name>\n");
+}
+
+/**
+ * @}
+ */
Index: uspace/app/ext2info/Makefile
===================================================================
--- uspace/app/ext2info/Makefile	(revision 5e3eea10eab5547b0c0e9d45abbeb98d19f9474d)
+++ uspace/app/ext2info/Makefile	(revision 5e3eea10eab5547b0c0e9d45abbeb98d19f9474d)
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+USPACE_PREFIX = ../..
+LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBEXT2_PREFIX)/libext2.a
+EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX) -I$(LIBEXT2_PREFIX)
+BINARY = ext2info
+
+SOURCES = \
+	ext2info.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/ext2info/ext2info.c
===================================================================
--- uspace/app/ext2info/ext2info.c	(revision 5e3eea10eab5547b0c0e9d45abbeb98d19f9474d)
+++ uspace/app/ext2info/ext2info.c	(revision 5e3eea10eab5547b0c0e9d45abbeb98d19f9474d)
@@ -0,0 +1,550 @@
+/*
+ * Copyright (c) 2011 Martin Sucha
+ * Copyright (c) 2010 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup fs
+ * @{
+ */
+
+/**
+ * @file	ext2info.c
+ * @brief	Tool for displaying information about ext2 filesystem
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <libblock.h>
+#include <mem.h>
+#include <devmap.h>
+#include <byteorder.h>
+#include <sys/types.h>
+#include <sys/typefmt.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <libext2.h>
+
+#define NAME	"ext2info"
+
+static void syntax_print(void);
+static void print_superblock(ext2_superblock_t *);
+static void print_block_groups(ext2_filesystem_t *);
+static void print_block_group(ext2_block_group_t *);
+static void print_inode_by_number(ext2_filesystem_t *, uint32_t, bool, uint32_t,
+    bool);
+static void print_data(unsigned char *, size_t);
+static void print_inode(ext2_filesystem_t *, ext2_inode_t *);
+static void print_inode_data(ext2_filesystem_t *, ext2_inode_t *, uint32_t);
+static void print_directory_contents(ext2_filesystem_t *, ext2_inode_ref_t *);
+
+#define ARG_SUPERBLOCK 1
+#define ARG_BLOCK_GROUPS 2
+#define ARG_INODE 4
+#define ARG_STRICT_CHECK 8
+#define ARG_INODE_DATA 16
+#define ARG_INODE_LIST 32
+#define ARG_COMMON (ARG_SUPERBLOCK | ARG_BLOCK_GROUPS)
+#define ARG_ALL (ARG_COMMON | ARG_INODE)
+
+
+int main(int argc, char **argv)
+{
+
+	int rc;
+	char *endptr;
+	char *dev_path;
+	devmap_handle_t handle;
+	ext2_filesystem_t filesystem;
+	int arg_flags;
+	uint32_t inode = 0;
+	uint32_t inode_data = 0;
+	
+	arg_flags = 0;
+	
+	if (argc < 2) {
+		printf(NAME ": Error, argument missing.\n");
+		syntax_print();
+		return 1;
+	}
+	
+	// Skip program name
+	--argc; ++argv;
+	
+	if (str_cmp(*argv, "--strict-check") == 0) {
+		--argc; ++argv;
+		arg_flags |= ARG_STRICT_CHECK;
+	}
+	
+	if (str_cmp(*argv, "--superblock") == 0) {
+		--argc; ++argv;
+		arg_flags |= ARG_SUPERBLOCK;
+	}
+	
+	if (str_cmp(*argv, "--block-groups") == 0) {
+		--argc; ++argv;
+		arg_flags |= ARG_BLOCK_GROUPS;
+	}
+	
+	if (str_cmp(*argv, "--inode") == 0) {
+		--argc; ++argv;
+		if (argc == 0) {
+			printf(NAME ": Argument expected for --inode\n");
+			return 2;
+		}
+		
+		inode = strtol(*argv, &endptr, 10);
+		if (*endptr != '\0') {
+			printf(NAME ": Error, invalid argument for --inode.\n");
+			syntax_print();
+			return 1;
+		}
+		
+		arg_flags |= ARG_INODE;
+		--argc; ++argv;
+		
+		if (str_cmp(*argv, "--inode-data") == 0) {
+			--argc; ++argv;
+			if (argc == 0) {
+				printf(NAME ": Argument expected for --inode-data\n");
+				return 2;
+			}
+			
+			inode_data = strtol(*argv, &endptr, 10);
+			if (*endptr != '\0') {
+				printf(NAME ": Error, invalid argument for --inode-data.\n");
+				syntax_print();
+				return 1;
+			}
+			
+			arg_flags |= ARG_INODE_DATA;
+			--argc; ++argv;
+		}
+		
+		if (str_cmp(*argv, "--list") == 0) {
+			--argc; ++argv;
+			arg_flags |= ARG_INODE_LIST;
+		}
+	}
+
+	if (argc != 1) {
+		printf(NAME ": Error, unexpected argument.\n");
+		syntax_print();
+		return 1;
+	}
+	
+	// Display common things by default
+	if ((arg_flags & ARG_ALL) == 0) {
+		arg_flags = ARG_COMMON;
+	}
+
+	dev_path = *argv;
+
+	rc = devmap_device_get_handle(dev_path, &handle, 0);
+	if (rc != EOK) {
+		printf(NAME ": Error resolving device `%s'.\n", dev_path);
+		return 2;
+	}
+
+	rc = ext2_filesystem_init(&filesystem, handle);
+	if (rc != EOK)  {
+		printf(NAME ": Error initializing libext2.\n");
+		return 3;
+	}
+	
+	rc = ext2_filesystem_check_sanity(&filesystem);
+	if (rc != EOK) {
+		printf(NAME ": Filesystem did not pass sanity check.\n");
+		if (arg_flags & ARG_STRICT_CHECK) {
+			return 3;
+		}
+	}
+	
+	if (arg_flags & ARG_SUPERBLOCK) {
+		print_superblock(filesystem.superblock);
+	}
+	
+	if (arg_flags & ARG_BLOCK_GROUPS) {
+		print_block_groups(&filesystem);
+	}
+	
+	if (arg_flags & ARG_INODE) {
+		print_inode_by_number(&filesystem, inode, arg_flags & ARG_INODE_DATA,
+		    inode_data, arg_flags & ARG_INODE_LIST);
+	}
+
+	ext2_filesystem_fini(&filesystem);
+
+	return 0;
+}
+
+
+static void syntax_print(void)
+{
+	printf("syntax: ext2info [--strict-check] [--superblock] [--block-groups] "
+	    "[--inode <i-number> [--inode-data <block-number>] [--list]] <device_name>\n");
+}
+
+static void print_superblock(ext2_superblock_t *superblock)
+{
+	uint16_t magic;
+	uint32_t first_block;
+	uint32_t block_size;
+	uint32_t fragment_size;
+	uint32_t blocks_per_group;
+	uint32_t fragments_per_group;
+	uint32_t rev_major;
+	uint16_t rev_minor;
+	uint16_t state;
+	uint32_t first_inode;
+	uint16_t inode_size;
+	uint32_t total_blocks;
+	uint32_t reserved_blocks;
+	uint32_t free_blocks;
+	uint32_t total_inodes;
+	uint32_t free_inodes;	
+	uint32_t os;
+	
+	int pos;
+	unsigned char c;
+	
+	magic = ext2_superblock_get_magic(superblock);
+	first_block = ext2_superblock_get_first_block(superblock);
+	block_size = ext2_superblock_get_block_size(superblock);
+	fragment_size = ext2_superblock_get_fragment_size(superblock);
+	blocks_per_group = ext2_superblock_get_blocks_per_group(superblock);
+	fragments_per_group = ext2_superblock_get_fragments_per_group(superblock);
+	rev_major = ext2_superblock_get_rev_major(superblock);
+	rev_minor = ext2_superblock_get_rev_minor(superblock);
+	state = ext2_superblock_get_state(superblock);
+	first_inode = ext2_superblock_get_first_inode(superblock);
+	inode_size = ext2_superblock_get_inode_size(superblock);
+	total_blocks = ext2_superblock_get_total_block_count(superblock);
+	reserved_blocks = ext2_superblock_get_reserved_block_count(superblock);
+	free_blocks = ext2_superblock_get_free_block_count(superblock);
+	total_inodes = ext2_superblock_get_total_inode_count(superblock);
+	free_inodes = ext2_superblock_get_free_inode_count(superblock);
+	os = ext2_superblock_get_os(superblock);
+	
+	printf("Superblock:\n");
+	
+	if (magic == EXT2_SUPERBLOCK_MAGIC) {
+		printf("  Magic value: %X (correct)\n", magic);
+	}
+	else {
+		printf("  Magic value: %X (incorrect)\n", magic);
+	}
+	
+	printf("  Revision: %u.%hu\n", rev_major, rev_minor);
+	printf("  State: %hu\n", state);
+	printf("  Creator OS: %u\n", os);
+	printf("  First block: %u\n", first_block);
+	printf("  Block size: %u bytes (%u KiB)\n", block_size, block_size/1024);
+	printf("  Blocks per group: %u\n", blocks_per_group);
+	printf("  Total blocks: %u\n", total_blocks);
+	printf("  Reserved blocks: %u\n", reserved_blocks);
+	printf("  Free blocks: %u\n", free_blocks);
+	printf("  Fragment size: %u bytes (%u KiB)\n", fragment_size,
+	    fragment_size/1024);
+	printf("  Fragments per group: %u\n", fragments_per_group);
+	printf("  First inode: %u\n", first_inode);
+	printf("  Inode size: %hu bytes\n", inode_size);
+	printf("  Total inodes: %u\n", total_inodes);
+	printf("  Free inodes: %u\n", free_inodes);
+	
+	
+	if (rev_major == 1) {
+		printf("  UUID: ");
+		for (pos = 0; pos < 16; pos++) {
+			printf("%02x", superblock->uuid[pos]);
+		}
+		printf("\n");
+		
+		printf("  Volume label: ");
+		for (pos = 0; pos < 16; pos++) {
+			c = superblock->volume_name[pos];
+			if (c >= 32 && c < 128) {
+				putchar(c);
+			}
+			else {
+				putchar(' ');
+			}
+		}
+		printf("\n");
+	}
+	
+}
+
+void print_block_groups(ext2_filesystem_t *filesystem)
+{
+	uint32_t block_group_count;
+	uint32_t i;
+	ext2_block_group_ref_t *block_group_ref;
+	int rc;
+	
+	printf("Block groups:\n");
+	
+	block_group_count = ext2_superblock_get_block_group_count(
+	    filesystem->superblock);
+	
+	for (i = 0; i < block_group_count; i++) {
+		printf("  Block group %u\n", i);
+		rc = ext2_filesystem_get_block_group_ref(filesystem, i, &block_group_ref);
+		if (rc != EOK) {
+			printf("    Failed reading block group\n");
+			continue;
+		}
+		
+		print_block_group(block_group_ref->block_group);
+		
+		rc = ext2_filesystem_put_block_group_ref(block_group_ref);
+		if (rc != EOK) {
+			printf("    Failed freeing block group\n");
+		}
+	}
+	
+}
+
+void print_block_group(ext2_block_group_t *bg)
+{
+	uint32_t block_bitmap_block;
+	uint32_t inode_bitmap_block;
+	uint32_t inode_table_first_block;
+	uint16_t free_block_count;
+	uint16_t free_inode_count;
+	uint16_t directory_inode_count;
+	
+	block_bitmap_block = ext2_block_group_get_block_bitmap_block(bg);
+	inode_bitmap_block = ext2_block_group_get_inode_bitmap_block(bg);
+	inode_table_first_block = ext2_block_group_get_inode_table_first_block(bg);
+	free_block_count = ext2_block_group_get_free_block_count(bg);
+	free_inode_count = ext2_block_group_get_free_inode_count(bg);
+	directory_inode_count = ext2_block_group_get_directory_inode_count(bg);
+	
+	printf("    Block bitmap block: %u\n", block_bitmap_block);
+	printf("    Inode bitmap block: %u\n", inode_bitmap_block);
+	printf("    Inode table's first block: %u\n", inode_table_first_block);
+	printf("    Free blocks: %u\n", free_block_count);
+	printf("    Free inodes: %u\n", free_inode_count);
+	printf("    Directory inodes: %u\n", directory_inode_count);
+}
+
+void print_inode_by_number(ext2_filesystem_t *fs, uint32_t inode, 
+    bool print_data, uint32_t data, bool list)
+{
+	int rc;
+	ext2_inode_ref_t *inode_ref;
+	
+	printf("Inode %u\n", inode);
+	
+	rc = ext2_filesystem_get_inode_ref(fs, inode, &inode_ref);
+	if (rc != EOK) {
+		printf("  Failed getting inode ref\n");
+		return;
+	}
+	
+	print_inode(fs, inode_ref->inode);
+	if (print_data) {
+		print_inode_data(fs, inode_ref->inode, data);
+	}
+	
+	if (list && ext2_inode_is_type(fs->superblock, inode_ref->inode,
+	    EXT2_INODE_MODE_DIRECTORY)) {
+		print_directory_contents(fs, inode_ref);
+	}
+	
+	rc = ext2_filesystem_put_inode_ref(inode_ref);
+	if (rc != EOK) {
+		printf("  Failed putting inode ref\n");
+	}
+}
+
+void print_inode(ext2_filesystem_t *fs, ext2_inode_t *inode)
+{
+	uint32_t mode;
+	uint32_t mode_type;
+	uint32_t user_id;
+	uint32_t group_id;
+	uint64_t size;
+	uint16_t usage_count;
+	uint32_t flags;
+	uint16_t access;
+	const char *type;
+	uint32_t block;
+	uint32_t total_blocks;
+	int i;
+	bool all_blocks = false;
+	
+	mode = ext2_inode_get_mode(fs->superblock, inode);
+	mode_type = mode & EXT2_INODE_MODE_TYPE_MASK;
+	user_id = ext2_inode_get_user_id(fs->superblock, inode);
+	group_id = ext2_inode_get_group_id(fs->superblock, inode);
+	size = ext2_inode_get_size(fs->superblock, inode);
+	usage_count = ext2_inode_get_usage_count(inode);
+	flags = ext2_inode_get_flags(inode);
+	total_blocks = ext2_inode_get_reserved_blocks(fs->superblock, inode);
+	
+	type = "Unknown";
+	if (mode_type == EXT2_INODE_MODE_BLOCKDEV) {
+		type = "Block device";
+	}
+	else if (mode_type == EXT2_INODE_MODE_FIFO) {
+		type = "Fifo (pipe)";
+	}
+	else if (mode_type == EXT2_INODE_MODE_CHARDEV) {
+		type = "Character device";
+	}
+	else if (mode_type == EXT2_INODE_MODE_DIRECTORY) {
+		type = "Directory";
+	}
+	else if (mode_type == EXT2_INODE_MODE_FILE) {
+		type = "File";
+	}
+	else if (mode_type == EXT2_INODE_MODE_SOFTLINK) {
+		type = "Soft link";
+	}
+	else if (mode_type == EXT2_INODE_MODE_SOCKET) {
+		type = "Socket";
+	}
+	
+	access = mode & EXT2_INODE_MODE_ACCESS_MASK;
+	
+	
+	printf("  Mode: %08x (Type: %s, Access bits: %04ho)\n", mode, type, access);
+	printf("  User ID: %u\n", user_id);
+	printf("  Group ID: %u\n", group_id);
+	printf("  Size: %" PRIu64 "\n", size);
+	printf("  Usage (link) count: %u\n", usage_count);
+	printf("  Flags: %u\n", flags);
+	printf("  Total allocated blocks: %u\n", total_blocks);
+	printf("  Block list: ");
+	for (i = 0; i < 12; i++) {
+		block = ext2_inode_get_direct_block(inode, i);
+		if (block == 0) {
+			all_blocks = true;
+			break;
+		}
+		printf("%u ", block);
+	}
+	all_blocks = all_blocks || ext2_inode_get_indirect_block(inode, 0) == 0;
+	if (!all_blocks) {
+		printf(" and more...");
+	}
+	printf("\n");
+}
+
+void print_data(unsigned char *data, size_t size)
+{
+	unsigned char c;
+	size_t i;
+	
+	for (i = 0; i < size; i++) {
+		c = data[i];
+		if (c >= 32 && c < 127) {
+			putchar(c);
+		}
+		else {
+			putchar('.');
+		}
+	}
+}
+
+void print_inode_data(ext2_filesystem_t *fs, ext2_inode_t *inode, uint32_t data)
+{
+	int rc;
+	uint32_t data_block_index;
+	block_t *block;
+	
+	rc = ext2_filesystem_get_inode_data_block_index(fs, inode, data,
+	    &data_block_index);
+	
+	if (rc != EOK) {
+		printf("Failed getting data block #%u\n", data);
+		return;
+	}
+	
+	printf("Data for inode contents block #%u is located in filesystem "
+	    "block %u\n", data, data_block_index);
+	
+	printf("Data preview (only printable characters):\n");
+	
+	rc = block_get(&block, fs->device, data_block_index, 0);
+	if (rc != EOK) {
+		printf("Failed reading filesystem block %u\n", data_block_index);
+		return;
+	}
+	
+	print_data(block->data, block->size);
+	printf("\n");	
+	
+	rc = block_put(block);
+	if (rc != EOK) {
+		printf("Failed putting filesystem block\n");
+	}
+	
+}
+
+void print_directory_contents(ext2_filesystem_t *fs,
+    ext2_inode_ref_t *inode_ref)
+{
+	int rc;
+	ext2_directory_iterator_t it;
+	size_t name_size;
+	
+	printf("  Directory contents:\n");
+	
+	rc = ext2_directory_iterator_init(&it, fs, inode_ref);
+	if (rc != EOK) {
+		printf("Failed initializing directory iterator\n");
+		return;
+	}
+	
+	while (it.current != NULL) {
+		name_size = ext2_directory_entry_ll_get_name_length(fs->superblock,
+		    it.current);
+		printf("    ");
+		print_data(&it.current->name, name_size);
+		printf(" --> %u\n", it.current->inode);
+		
+		rc = ext2_directory_iterator_next(&it);
+		if (rc != EOK) {
+			printf("Failed reading directory contents\n");
+			goto cleanup;
+		}
+	}
+
+cleanup:
+	rc = ext2_directory_iterator_fini(&it);
+	if (rc != EOK) {
+		printf("Failed cleaning-up directory iterator\n");
+	}
+	
+}
+
+/**
+ * @}
+ */
Index: uspace/app/redir/redir.c
===================================================================
--- uspace/app/redir/redir.c	(revision afe1d1e203e5c589222f7579368f84a24d325f3c)
+++ uspace/app/redir/redir.c	(revision 5e3eea10eab5547b0c0e9d45abbeb98d19f9474d)
@@ -49,5 +49,5 @@
 static void usage(void)
 {
-	printf("Usage: %s [-i <stdin>] [-o <stdout>] [-e <stderr>] -- <cmd> [args ...]\n",
+	fprintf(stderr, "Usage: %s [-i <stdin>] [-o <stdout>] [-e <stderr>] -- <cmd> [args ...]\n",
 	    NAME);
 }
@@ -83,5 +83,5 @@
 	args = (const char **) calloc(argc + 1, sizeof(char *));
 	if (!args) {
-		printf("No memory available\n");
+		fprintf(stderr, "No memory available\n");
 		return 0;
 	}
@@ -98,6 +98,7 @@
 	
 	if (rc != EOK) {
-		printf("%s: Error spawning %s (%s)\n", NAME, argv[0],
+		fprintf(stderr, "%s: Error spawning %s (%s)\n", NAME, argv[0],
 		    str_error(rc));
+		return 0;
 	}
 	
Index: uspace/app/tester/Makefile
===================================================================
--- uspace/app/tester/Makefile	(revision afe1d1e203e5c589222f7579368f84a24d325f3c)
+++ uspace/app/tester/Makefile	(revision 5e3eea10eab5547b0c0e9d45abbeb98d19f9474d)
@@ -29,8 +29,11 @@
 
 USPACE_PREFIX = ../..
+LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBEXT2_PREFIX)/libext2.a
+EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX) -I$(LIBEXT2_PREFIX)
 BINARY = tester
 
 SOURCES = \
 	tester.c \
+	util.c \
 	thread/thread1.c \
 	print/print1.c \
@@ -50,5 +53,6 @@
 	mm/malloc1.c \
 	hw/misc/virtchar1.c \
-	hw/serial/serial1.c
+	hw/serial/serial1.c \
+	libext2/libext2_1.c
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/tester/libext2/libext2_1.c
===================================================================
--- uspace/app/tester/libext2/libext2_1.c	(revision 5e3eea10eab5547b0c0e9d45abbeb98d19f9474d)
+++ uspace/app/tester/libext2/libext2_1.c	(revision 5e3eea10eab5547b0c0e9d45abbeb98d19f9474d)
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2005 Jakub Vana
+ * Copyright (c) 2005 Jakub Jermar
+ * Copyright (c) 2011 Martin Sucha
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include "../tester.h"
+#include "../util.h"
+#include <libext2.h>
+#include <malloc.h>
+
+static ext2_superblock_t *fake_superblock1()
+{
+	uint8_t *buf;
+	int i;
+	
+	buf = malloc(EXT2_SUPERBLOCK_SIZE);
+	if (buf == NULL) {
+		return NULL;
+	}
+	
+	for (i = 0; i < EXT2_SUPERBLOCK_SIZE; i++) {
+		buf[i] = i % 256;
+	}
+	
+	return (ext2_superblock_t *) buf;
+}
+
+const char *test_libext2_1(void)
+{
+	ext2_superblock_t *fake1;
+	
+	TPRINTF("Testing libext2 superblock getters...\n");
+	TPRINTF("Simple test for correct position and byte order\n");
+	
+	fake1 = fake_superblock1();
+	if (fake1 == NULL) {
+		return "Failed allocating memory for test superblock 1";
+	}
+	
+	ASSERT_EQ_32(0x03020100, ext2_superblock_get_total_inode_count(fake1),
+	    "Failed getting total inode count");
+	ASSERT_EQ_32(0x07060504, ext2_superblock_get_total_block_count(fake1),
+	    "Failed getting total block count");
+	ASSERT_EQ_32(0x0B0A0908, ext2_superblock_get_reserved_block_count(fake1),
+	    "Failed getting reserved block count");
+	ASSERT_EQ_32(0x0F0E0D0C, ext2_superblock_get_free_block_count(fake1),
+	    "Failed getting free block count");
+	ASSERT_EQ_32(0x13121110, ext2_superblock_get_free_inode_count(fake1),
+	    "Failed getting free inode count");
+	ASSERT_EQ_32(0x17161514, ext2_superblock_get_first_block(fake1),
+	    "Failed getting first block number");
+	ASSERT_EQ_32(0x1B1A1918, ext2_superblock_get_block_size_log2(fake1),
+	    "Failed getting log block size");
+	ASSERT_EQ_32(0x1F1E1D1C, ext2_superblock_get_fragment_size_log2(fake1),
+	    "Failed getting log fragment size");
+	ASSERT_EQ_32(0x23222120, ext2_superblock_get_blocks_per_group(fake1),
+	    "Failed getting blocks per group");
+	ASSERT_EQ_32(0x27262524, ext2_superblock_get_fragments_per_group(fake1),
+	    "Failed getting fragments per group");
+	ASSERT_EQ_32(0x2B2A2928, ext2_superblock_get_inodes_per_group(fake1),
+	    "Failed getting inodes per group");
+	ASSERT_EQ_16(0x3938, ext2_superblock_get_magic(fake1),
+	    "Failed getting magic number");
+	ASSERT_EQ_16(0x3B3A, ext2_superblock_get_state(fake1),
+	    "Failed getting state");
+	ASSERT_EQ_16(0x3F3E, ext2_superblock_get_rev_minor(fake1),
+	    "Failed getting minor revision number");
+	ASSERT_EQ_32(0x4B4A4948, ext2_superblock_get_os(fake1),
+	    "Failed getting OS");
+	ASSERT_EQ_32(0x4F4E4D4C, ext2_superblock_get_rev_major(fake1),
+	    "Failed getting major revision number");
+	ASSERT_EQ_32(0x57565554, ext2_superblock_get_first_inode(fake1),
+	    "Failed getting first inode number");
+	ASSERT_EQ_16(0x5958, ext2_superblock_get_inode_size(fake1),
+	    "Failed getting size");
+	ASSERT_EQ_8(0x68, fake1->uuid[0], "UUID position is incorrect");
+	ASSERT_EQ_8(0x78, fake1->volume_name[0],
+	    "Volume name position is incorrect");
+	
+	return NULL;
+}
Index: uspace/app/tester/libext2/libext2_1.def
===================================================================
--- uspace/app/tester/libext2/libext2_1.def	(revision 5e3eea10eab5547b0c0e9d45abbeb98d19f9474d)
+++ uspace/app/tester/libext2/libext2_1.def	(revision 5e3eea10eab5547b0c0e9d45abbeb98d19f9474d)
@@ -0,0 +1,6 @@
+{
+	"libext2_1",
+	"Superblock getters test",
+	&test_libext2_1,
+	true
+},
Index: uspace/app/tester/tester.c
===================================================================
--- uspace/app/tester/tester.c	(revision afe1d1e203e5c589222f7579368f84a24d325f3c)
+++ uspace/app/tester/tester.c	(revision 5e3eea10eab5547b0c0e9d45abbeb98d19f9474d)
@@ -64,4 +64,5 @@
 #include "hw/serial/serial1.def"
 #include "hw/misc/virtchar1.def"
+#include "libext2/libext2_1.def"
 	{NULL, NULL, NULL, false}
 };
Index: uspace/app/tester/tester.h
===================================================================
--- uspace/app/tester/tester.h	(revision afe1d1e203e5c589222f7579368f84a24d325f3c)
+++ uspace/app/tester/tester.h	(revision 5e3eea10eab5547b0c0e9d45abbeb98d19f9474d)
@@ -80,4 +80,5 @@
 extern const char *test_serial1(void);
 extern const char *test_virtchar1(void);
+extern const char *test_libext2_1(void);
 
 extern test_t tests[];
Index: uspace/app/tester/util.c
===================================================================
--- uspace/app/tester/util.c	(revision 5e3eea10eab5547b0c0e9d45abbeb98d19f9474d)
+++ uspace/app/tester/util.c	(revision 5e3eea10eab5547b0c0e9d45abbeb98d19f9474d)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2011 Martin Sucha
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup tester
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include "util.h"
+#undef ASSERT_EQ_FN_DEF
+#define ASSERT_EQ_FN_DEF(type, fmt, fmtx) \
+bool assert_eq_fn_##type(type exp, type act, const char *act_desc) \
+{ \
+	if (exp != act) { \
+		fprintf(stderr, "Expected %s to be %" fmt " (0x%" fmtx "),"\
+		    " but was %" fmt " (0x%" fmtx ") \n", \
+		    act_desc, exp, exp, act, act); \
+	} \
+	return exp != act; \
+}
+
+#include "util_functions.def"
+
+
+/** @}
+ */
Index: uspace/app/tester/util.h
===================================================================
--- uspace/app/tester/util.h	(revision 5e3eea10eab5547b0c0e9d45abbeb98d19f9474d)
+++ uspace/app/tester/util.h	(revision 5e3eea10eab5547b0c0e9d45abbeb98d19f9474d)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2011 Martin Sucha
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup tester
+ * @{
+ */
+/** @file
+ */
+
+#ifndef UTIL_H_
+#define UTIL_H_
+
+#include <stdio.h>
+#include "tester.h"
+
+#define ASSERT_EQ_FN_DEF(type, fmt, fmtx) \
+extern bool assert_eq_fn_##type(type, type, const char *);
+
+#include "util_functions.def"
+
+#define ASSERT_EQ_64(exp, act, msg) \
+{if (assert_eq_fn_uint64_t(exp, act, #act)) {return msg;}}
+
+#define ASSERT_EQ_32(exp, act, msg) \
+{if (assert_eq_fn_uint32_t(exp, act, #act)) {return msg;}}
+
+#define ASSERT_EQ_16(exp, act, msg) \
+{if (assert_eq_fn_uint16_t(exp, act, #act)) {return msg;}}
+
+#define ASSERT_EQ_8(exp, act, msg) \
+{if (assert_eq_fn_uint8_t(exp, act, #act)) {return msg;}}
+
+#endif
+
+/** @}
+ */
Index: uspace/app/tester/util_functions.def
===================================================================
--- uspace/app/tester/util_functions.def	(revision 5e3eea10eab5547b0c0e9d45abbeb98d19f9474d)
+++ uspace/app/tester/util_functions.def	(revision 5e3eea10eab5547b0c0e9d45abbeb98d19f9474d)
@@ -0,0 +1,4 @@
+ASSERT_EQ_FN_DEF(uint8_t, "hhu", "hhx")
+ASSERT_EQ_FN_DEF(uint16_t, "hu", "hx")
+ASSERT_EQ_FN_DEF(uint32_t, "u", "x")
+ASSERT_EQ_FN_DEF(uint64_t, PRIu64, PRIx64)
