Index: uspace/app/bdsh/cmds/modules/cat/cat.c
===================================================================
--- uspace/app/bdsh/cmds/modules/cat/cat.c	(revision ed2c8ff4610f93c20b234a94ff648c9cf0d4bd42)
+++ uspace/app/bdsh/cmds/modules/cat/cat.c	(revision fb2ceebd30add3c4203e742c03bc8a900863c575)
@@ -1,3 +1,4 @@
 /* Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
+ * Copyright (c) 2011, Martin Sucha
  * All rights reserved.
  *
@@ -35,4 +36,10 @@
 #include <str.h>
 #include <fcntl.h>
+#include <io/console.h>
+#include <io/color.h>
+#include <io/style.h>
+#include <errno.h>
+#include <vfs/vfs.h>
+#include <assert.h>
 
 #include "config.h"
@@ -48,4 +55,11 @@
 
 static const char *cat_oops = "That option is not yet supported\n";
+static const char *hexchars = "0123456789abcdef";
+
+static bool paging_enabled = false;
+static size_t chars_remaining = 0;
+static size_t lines_remaining = 0;
+static sysarg_t console_cols = 0;
+static sysarg_t console_rows = 0;
 
 static struct option const long_options[] = {
@@ -56,4 +70,5 @@
 	{ "buffer", required_argument, 0, 'b' },
 	{ "more", no_argument, 0, 'm' },
+	{ "hex", no_argument, 0, 'x' },
 	{ 0, 0, 0, 0 }
 };
@@ -75,4 +90,5 @@
 		"  -b, --buffer ##  Set the read buffer size to ##\n"
 		"  -m, --more       Pause after each screen full\n"
+		"  -x, --hex        Print bytes as hex values\n"
 		"Currently, %s is under development, some options don't work.\n",
 		cmdname, cmdname);
@@ -82,9 +98,60 @@
 }
 
-static unsigned int cat_file(const char *fname, size_t blen)
+static void waitprompt()
+{
+	console_set_pos(fphone(stdout), 0, console_rows-1);
+	console_set_color(fphone(stdout), COLOR_BLUE, COLOR_WHITE, 0);
+	printf("Press any key to continue");
+	fflush(stdout);
+	console_set_style(fphone(stdout), STYLE_NORMAL);
+}
+
+static void waitkey()
+{
+	console_event_t ev;
+	
+	while (true) {
+		if (!console_get_event(fphone(stdin), &ev)) {
+			return;
+		}
+		if (ev.type == KEY_PRESS) {
+			return;
+		}
+	}
+	assert(false);
+}
+
+static void newpage()
+{
+	console_clear(fphone(stdout));
+	chars_remaining = console_cols;
+	lines_remaining = console_rows-1;
+}
+
+static void paged_char(wchar_t c)
+{
+	putchar(c);
+	if (paging_enabled) {
+		chars_remaining--;
+		if (c == '\n' || chars_remaining == 0) {
+			chars_remaining = console_cols;
+			lines_remaining--;
+		}
+		if (lines_remaining == 0) {
+			fflush(stdout);
+			waitprompt();
+			waitkey();
+			newpage();
+		}
+	}
+}
+
+static unsigned int cat_file(const char *fname, size_t blen, bool hex)
 {
 	int fd, bytes = 0, count = 0, reads = 0;
 	off64_t total = 0;
 	char *buff = NULL;
+	int i;
+	size_t offset = 0;
 
 	fd = open(fname, O_RDONLY);
@@ -109,5 +176,20 @@
 			count += bytes;
 			buff[bytes] = '\0';
-			printf("%s", buff);
+			offset = 0;
+			for (i = 0; i < bytes; i++) {
+				if (hex) {
+					paged_char(hexchars[((uint8_t)buff[i])/16]);
+					paged_char(hexchars[((uint8_t)buff[i])%16]);
+				}
+				else {
+					wchar_t c = str_decode(buff, &offset, bytes);
+					if (c == 0) {
+						// reached end of string
+						break;
+					}
+					paged_char(c);
+				}
+				
+			}
 			reads++;
 		}
@@ -131,9 +213,21 @@
 	unsigned int argc, i, ret = 0, buffer = 0;
 	int c, opt_ind;
+	bool hex = false;
+	bool more = false;
+	sysarg_t rows, cols;
+	int rc;
+	
+	// reset global state
+	// TODO: move to structure?
+	paging_enabled = false;
+	chars_remaining = 0;
+	lines_remaining = 0;
+	console_cols = 0;
+	console_rows = 0;
 
 	argc = cli_count_args(argv);
 
 	for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
-		c = getopt_long(argc, argv, "hvmH:t:b:", long_options, &opt_ind);
+		c = getopt_long(argc, argv, "xhvmH:t:b:", long_options, &opt_ind);
 		switch (c) {
 		case 'h':
@@ -153,6 +247,9 @@
 			break;
 		case 'm':
-			printf("%s", cat_oops);
-			return CMD_FAILURE;
+			more = true;
+			break;
+		case 'x':
+			hex = true;
+			break;
 		}
 	}
@@ -168,7 +265,19 @@
 	if (buffer <= 0)
 		buffer = CAT_DEFAULT_BUFLEN;
+	
+	if (more) {
+		rc = console_get_size(fphone(stdout), &cols, &rows);
+		if (rc != EOK) {
+			printf("%s - cannot get console size\n", cmdname);
+			return CMD_FAILURE;
+		}
+		console_cols = cols;
+		console_rows = rows;
+		paging_enabled = true;
+		newpage();
+	}
 
 	for (i = optind; argv[i] != NULL; i++)
-		ret += cat_file(argv[i], buffer);
+		ret += cat_file(argv[i], buffer, hex);
 
 	if (ret)
Index: uspace/app/bdsh/cmds/modules/cat/cat.h
===================================================================
--- uspace/app/bdsh/cmds/modules/cat/cat.h	(revision ed2c8ff4610f93c20b234a94ff648c9cf0d4bd42)
+++ uspace/app/bdsh/cmds/modules/cat/cat.h	(revision fb2ceebd30add3c4203e742c03bc8a900863c575)
@@ -4,5 +4,5 @@
 /* Prototypes for the cat command, excluding entry points */
 
-static unsigned int cat_file(const char *, size_t);
+static unsigned int cat_file(const char *, size_t, bool);
 
 #endif /* CAT_H */
