Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision 1f383dde20a2b1e39baa81fbc44a73c126e508e4)
+++ uspace/app/init/init.c	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
@@ -57,9 +57,9 @@
 #define DEVFS_MOUNT_POINT  "/dev"
 
-#define SCRATCH_FS_TYPE      "tmpfs"
-#define SCRATCH_MOUNT_POINT  "/scratch"
+#define TMPFS_FS_TYPE      "tmpfs"
+#define TMPFS_MOUNT_POINT  "/tmp"
 
 #define DATA_FS_TYPE      "fat"
-#define DATA_DEVICE       "bd/disk0"
+#define DATA_DEVICE       "bd/ata1disk0"
 #define DATA_MOUNT_POINT  "/data"
 
@@ -235,9 +235,9 @@
 }
 
-static bool mount_scratch(void)
-{
-	int rc = mount(SCRATCH_FS_TYPE, SCRATCH_MOUNT_POINT, "", "", 0);
-	return mount_report("Scratch filesystem", SCRATCH_MOUNT_POINT,
-	    SCRATCH_FS_TYPE, NULL, rc);
+static bool mount_tmpfs(void)
+{
+	int rc = mount(TMPFS_FS_TYPE, TMPFS_MOUNT_POINT, "", "", 0);
+	return mount_report("Temporary filesystem", TMPFS_MOUNT_POINT,
+	    TMPFS_FS_TYPE, NULL, rc);
 }
 
@@ -271,5 +271,5 @@
 	}
 	
-	mount_scratch();
+	mount_tmpfs();
 	
 	spawn("/srv/fhc");
Index: uspace/app/kill/Makefile
===================================================================
--- uspace/app/kill/Makefile	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
+++ uspace/app/kill/Makefile	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
@@ -0,0 +1,37 @@
+#
+# 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.
+#
+
+USPACE_PREFIX = ../..
+LIBS =
+EXTRA_CFLAGS =
+BINARY = kill
+
+SOURCES = \
+	kill.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/kill/kill.c
===================================================================
--- uspace/app/kill/kill.c	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
+++ uspace/app/kill/kill.c	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
@@ -0,0 +1,76 @@
+/*
+ * 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 kill
+ * @{
+ */
+/**
+ * @file Forcefully terminate a task.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <task.h>
+#include <str_error.h>
+
+#define NAME  "kill"
+
+static void print_syntax(void)
+{
+	printf("Syntax: " NAME " <task ID>\n");
+}
+
+int main(int argc, char *argv[])
+{
+	char *eptr;
+	task_id_t taskid;
+	int rc;
+
+	if (argc != 2) {
+		print_syntax();
+		return 1;
+	}
+
+	taskid = strtoul(argv[1], &eptr, 0);
+	if (*eptr != '\0') {
+		printf("Invalid task ID argument '%s'.\n", argv[1]);
+		return 2;
+	}
+
+	rc = task_kill(taskid);
+	if (rc != EOK) {
+		printf("Failed to kill task ID %" PRIu64 ": %s\n",
+		    taskid, str_error(rc));
+		return 3;
+	}
+
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/app/killall/Makefile
===================================================================
--- uspace/app/killall/Makefile	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
+++ uspace/app/killall/Makefile	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2010 Martin Decky
+# 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 =
+EXTRA_CFLAGS =
+BINARY = killall
+
+SOURCES = \
+	killall.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/killall/killall.c
===================================================================
--- uspace/app/killall/killall.c	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
+++ uspace/app/killall/killall.c	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 killall
+ * @{
+ */
+/**
+ * @file Forcefully terminate a task specified by name.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <task.h>
+#include <stats.h>
+#include <str_error.h>
+#include <malloc.h>
+
+#define NAME  "killall"
+
+static void print_syntax(void)
+{
+	printf("Syntax: " NAME " <task name>\n");
+}
+
+int main(int argc, char *argv[])
+{
+	if (argc != 2) {
+		print_syntax();
+		return 1;
+	}
+	
+	size_t count;
+	stats_task_t *stats_tasks = stats_get_tasks(&count);
+	
+	if (stats_tasks == NULL) {
+		fprintf(stderr, "%s: Unable to get tasks\n", NAME);
+		return 2;
+	}
+	
+	size_t i;
+	for (i = 0; i < count; i++) {
+		if (str_cmp(stats_tasks[i].name, argv[1]) == 0) {
+			task_id_t taskid = stats_tasks[i].task_id;
+			int rc = task_kill(taskid);
+			if (rc != EOK)
+				printf("Failed to kill task ID %" PRIu64 ": %s\n",
+				    taskid, str_error(rc));
+			else
+				printf("Killed task ID %" PRIu64 "\n", taskid);
+		}
+	}
+	
+	free(stats_tasks);
+	
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/app/netecho/netecho.c
===================================================================
--- uspace/app/netecho/netecho.c	(revision 1f383dde20a2b1e39baa81fbc44a73c126e508e4)
+++ uspace/app/netecho/netecho.c	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
@@ -32,10 +32,13 @@
 
 /** @file
- * Network echo application.
- * Answers received packets.
+ * Network echo server.
+ *
+ * Sockets-based server that echoes incomming messages. If stream mode
+ * is selected, accepts incoming connections.
  */
 
-#include <malloc.h>
+#include <assert.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <str.h>
 #include <task.h>
@@ -50,178 +53,296 @@
 #include "print_error.h"
 
-/** Network echo module name. */
-#define NAME	"Network Echo"
+#define NAME "netecho"
+
+static int count = -1;
+static int family = PF_INET;
+static sock_type_t type = SOCK_DGRAM;
+static uint16_t port = 7;
+static int backlog = 3;
+static size_t size = 1024;
+static int verbose = 0;
+
+static char *reply = NULL;
+static size_t reply_length;
+
+static char *data;
 
 static void echo_print_help(void)
 {
 	printf(
-		"Network Echo aplication\n" \
-		"Usage: echo [options]\n" \
-		"Where options are:\n" \
-		"-b backlog | --backlog=size\n" \
-		"\tThe size of the accepted sockets queue. Only for SOCK_STREAM. The default is 3.\n" \
-		"\n" \
-		"-c count | --count=count\n" \
-		"\tThe number of received messages to handle. A negative number means infinity. The default is infinity.\n" \
-		"\n" \
-		"-f protocol_family | --family=protocol_family\n" \
-		"\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n"
-		"\n" \
-		"-h | --help\n" \
-		"\tShow this application help.\n"
-		"\n" \
-		"-p port_number | --port=port_number\n" \
-		"\tThe port number the application should listen at. The default is 7.\n" \
-		"\n" \
-		"-r reply_string | --reply=reply_string\n" \
-		"\tThe constant reply string. The default is the original data received.\n" \
-		"\n" \
-		"-s receive_size | --size=receive_size\n" \
-		"\tThe maximum receive data size the application should accept. The default is 1024 bytes.\n" \
-		"\n" \
-		"-t socket_type | --type=socket_type\n" \
-		"\tThe listenning socket type. Only the SOCK_DGRAM and the SOCK_STREAM are supported.\n" \
-		"\n" \
-		"-v | --verbose\n" \
-		"\tShow all output messages.\n"
+	    "Network echo server\n"
+	    "Usage: " NAME " [options]\n"
+	    "Where options are:\n"
+	    "-b backlog | --backlog=size\n"
+	    "\tThe size of the accepted sockets queue. Only for SOCK_STREAM. "
+	    "The default is 3.\n"
+	    "\n"
+	    "-c count | --count=count\n"
+	    "\tThe number of received messages to handle. A negative number "
+	    "means infinity. The default is infinity.\n"
+	    "\n"
+	    "-f protocol_family | --family=protocol_family\n"
+	    "\tThe listenning socket protocol family. Only the PF_INET and "
+	    "PF_INET6 are supported.\n"
+	    "\n"
+	    "-h | --help\n"
+	    "\tShow this application help.\n"
+	    "\n"
+	    "-p port_number | --port=port_number\n"
+	    "\tThe port number the application should listen at. The default "
+	    "is 7.\n"
+	    "\n"
+	    "-r reply_string | --reply=reply_string\n"
+	    "\tThe constant reply string. The default is the original data "
+	    "received.\n"
+	    "\n"
+	    "-s receive_size | --size=receive_size\n"
+	    "\tThe maximum receive data size the application should accept. "
+	    "The default is 1024 bytes.\n"
+	    "\n"
+	    "-t socket_type | --type=socket_type\n"
+	    "\tThe listenning socket type. Only the SOCK_DGRAM and the "
+	    "SOCK_STREAM are supported.\n"
+	    "\n"
+	    "-v | --verbose\n"
+	    "\tShow all output messages.\n"
 	);
 }
 
-int main(int argc, char *argv[])
+static int netecho_parse_option(int argc, char *argv[], int *index)
 {
-	size_t size = 1024;
-	int verbose = 0;
-	char *reply = NULL;
-	sock_type_t type = SOCK_DGRAM;
-	int count = -1;
-	int family = PF_INET;
-	uint16_t port = 7;
-	int backlog = 3;
-
-	socklen_t max_length = sizeof(struct sockaddr_in6);
-	uint8_t address_data[max_length];
-	struct sockaddr *address = (struct sockaddr *) address_data;
-	struct sockaddr_in *address_in = (struct sockaddr_in *) address;
-	struct sockaddr_in6 *address_in6 = (struct sockaddr_in6 *) address;
-	socklen_t addrlen;
-	char address_string[INET6_ADDRSTRLEN];
-	uint8_t *address_start;
-	int socket_id;
-	int listening_id;
-	char *data;
-	size_t length;
-	int index;
-	size_t reply_length;
 	int value;
 	int rc;
 
-	// parse the command line arguments
-	for (index = 1; index < argc; ++ index) {
-		if (argv[index][0] == '-') {
-			switch (argv[index][1]) {
-			case 'b':
-				rc = arg_parse_int(argc, argv, &index, &backlog, 0);
-				if (rc != EOK)
-					return rc;
-				break;
-			case 'c':
-				rc = arg_parse_int(argc, argv, &index, &count, 0);
-				if (rc != EOK)
-					return rc;
-				break;
-			case 'f':
-				rc = arg_parse_name_int(argc, argv, &index, &family, 0, socket_parse_protocol_family);
-				if (rc != EOK)
-					return rc;
-				break;
-			case 'h':
-				echo_print_help();
-				return EOK;
-				break;
-			case 'p':
-				rc = arg_parse_int(argc, argv, &index, &value, 0);
-				if (rc != EOK)
-					return rc;
-				port = (uint16_t) value;
-				break;
-			case 'r':
-				rc = arg_parse_string(argc, argv, &index, &reply, 0);
-				if (rc != EOK)
-					return rc;
-				break;
-			case 's':
-				rc = arg_parse_int(argc, argv, &index, &value, 0);
-				if (rc != EOK)
-					return rc;
-				size = (value >= 0) ? (size_t) value : 0;
-				break;
-			case 't':
-				rc = arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type);
-				if (rc != EOK)
-					return rc;
-				type = (sock_type_t) value;
-				break;
-			case 'v':
-				verbose = 1;
-				break;
-			// long options with the double minus sign ('-')
-			case '-':
-				if (str_lcmp(argv[index] + 2, "backlog=", 6) == 0) {
-					rc = arg_parse_int(argc, argv, &index, &backlog, 8);
-					if (rc != EOK)
-						return rc;
-				} else if (str_lcmp(argv[index] + 2, "count=", 6) == 0) {
-					rc = arg_parse_int(argc, argv, &index, &count, 8);
-					if (rc != EOK)
-						return rc;
-				} else if (str_lcmp(argv[index] + 2, "family=", 7) == 0) {
-					rc = arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family);
-					if (rc != EOK)
-						return rc;
-				} else if (str_lcmp(argv[index] + 2, "help", 5) == 0) {
-					echo_print_help();
-					return EOK;
-				} else if (str_lcmp(argv[index] + 2, "port=", 5) == 0) {
-					rc = arg_parse_int(argc, argv, &index, &value, 7);
-					if (rc != EOK)
-						return rc;
-					port = (uint16_t) value;
-				} else if (str_lcmp(argv[index] + 2, "reply=", 6) == 0) {
-					rc = arg_parse_string(argc, argv, &index, &reply, 8);
-					if (rc != EOK)
-						return rc;
-				} else if (str_lcmp(argv[index] + 2, "size=", 5) == 0) {
-					rc = arg_parse_int(argc, argv, &index, &value, 7);
-					if (rc != EOK)
-						return rc;
-					size = (value >= 0) ? (size_t) value : 0;
-				} else if (str_lcmp(argv[index] + 2, "type=", 5) == 0) {
-					rc = arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type);
-					if (rc != EOK)
-						return rc;
-					type = (sock_type_t) value;
-				} else if (str_lcmp(argv[index] + 2, "verbose", 8) == 0) {
-					verbose = 1;
-				} else {
-					echo_print_help();
-					return EINVAL;
-				}
-				break;
-			default:
-				echo_print_help();
-				return EINVAL;
-			}
+	switch (argv[*index][1]) {
+	case 'b':
+		rc = arg_parse_int(argc, argv, index, &backlog, 0);
+		if (rc != EOK)
+			return rc;
+		break;
+	case 'c':
+		rc = arg_parse_int(argc, argv, index, &count, 0);
+		if (rc != EOK)
+			return rc;
+		break;
+	case 'f':
+		rc = arg_parse_name_int(argc, argv, index, &family, 0,
+		    socket_parse_protocol_family);
+		if (rc != EOK)
+			return rc;
+		break;
+	case 'h':
+		echo_print_help();
+		exit(0);
+		break;
+	case 'p':
+		rc = arg_parse_int(argc, argv, index, &value, 0);
+		if (rc != EOK)
+			return rc;
+		port = (uint16_t) value;
+		break;
+	case 'r':
+		rc = arg_parse_string(argc, argv, index, &reply, 0);
+		if (rc != EOK)
+			return rc;
+		break;
+	case 's':
+		rc = arg_parse_int(argc, argv, index, &value, 0);
+		if (rc != EOK)
+			return rc;
+		size = (value >= 0) ? (size_t) value : 0;
+		break;
+	case 't':
+		rc = arg_parse_name_int(argc, argv, index, &value, 0,
+		    socket_parse_socket_type);
+		if (rc != EOK)
+			return rc;
+		type = (sock_type_t) value;
+		break;
+	case 'v':
+		verbose = 1;
+		break;
+	/* Long options with double dash */
+	case '-':
+		if (str_lcmp(argv[*index] + 2, "backlog=", 6) == 0) {
+			rc = arg_parse_int(argc, argv, index, &backlog, 8);
+			if (rc != EOK)
+				return rc;
+		} else if (str_lcmp(argv[*index] + 2, "count=", 6) == 0) {
+			rc = arg_parse_int(argc, argv, index, &count, 8);
+			if (rc != EOK)
+				return rc;
+		} else if (str_lcmp(argv[*index] + 2, "family=", 7) == 0) {
+			rc = arg_parse_name_int(argc, argv, index, &family, 9,
+			    socket_parse_protocol_family);
+			if (rc != EOK)
+				return rc;
+		} else if (str_lcmp(argv[*index] + 2, "help", 5) == 0) {
+			echo_print_help();
+			exit(0);
+		} else if (str_lcmp(argv[*index] + 2, "port=", 5) == 0) {
+			rc = arg_parse_int(argc, argv, index, &value, 7);
+			if (rc != EOK)
+				return rc;
+			port = (uint16_t) value;
+		} else if (str_lcmp(argv[*index] + 2, "reply=", 6) == 0) {
+			rc = arg_parse_string(argc, argv, index, &reply, 8);
+			if (rc != EOK)
+				return rc;
+		} else if (str_lcmp(argv[*index] + 2, "size=", 5) == 0) {
+			rc = arg_parse_int(argc, argv, index, &value, 7);
+			if (rc != EOK)
+				return rc;
+			size = (value >= 0) ? (size_t) value : 0;
+		} else if (str_lcmp(argv[*index] + 2, "type=", 5) == 0) {
+			rc = arg_parse_name_int(argc, argv, index, &value, 7,
+			    socket_parse_socket_type);
+			if (rc != EOK)
+				return rc;
+			type = (sock_type_t) value;
+		} else if (str_lcmp(argv[*index] + 2, "verbose", 8) == 0) {
+			verbose = 1;
 		} else {
 			echo_print_help();
 			return EINVAL;
 		}
-	}
-
-	// check the buffer size
+		break;
+	default:
+		echo_print_help();
+		return EINVAL;
+	}
+
+	return EOK;
+}
+
+/** Echo one message (accept one connection and echo message).
+ *
+ * @param listening_id	Listening socket.
+ * @return		EOK on success or negative error code.
+ */
+static int netecho_socket_process_message(int listening_id)
+{
+	uint8_t address_buf[sizeof(struct sockaddr_in6)];
+
+	socklen_t addrlen;
+	int socket_id;
+	ssize_t rcv_size;
+	size_t length;
+	uint8_t *address_start;
+
+	char address_string[INET6_ADDRSTRLEN];
+	struct sockaddr_in *address_in = (struct sockaddr_in *) address_buf;
+	struct sockaddr_in6 *address_in6 = (struct sockaddr_in6 *) address_buf;
+	struct sockaddr *address = (struct sockaddr *) address_buf;
+
+	int rc;
+
+	if (type == SOCK_STREAM) {
+		/* Accept a socket if a stream socket is used */
+		addrlen = sizeof(address_buf);
+            	socket_id = accept(listening_id, (void *) address_buf, &addrlen);
+		if (socket_id <= 0) {
+			socket_print_error(stderr, socket_id, "Socket accept: ", "\n");
+		} else {
+			if (verbose)
+				printf("Socket %d accepted\n", socket_id);
+		}
+
+		assert((size_t) addrlen <= sizeof(address_buf));
+	} else {
+		socket_id = listening_id;
+	}
+
+	/* if the datagram socket is used or the stream socked was accepted */
+	if (socket_id > 0) {
+
+		/* Receive a message to echo */
+		rcv_size = recvfrom(socket_id, data, size, 0, address,
+		    &addrlen);
+		if (rcv_size < 0) {
+			socket_print_error(stderr, rcv_size, "Socket receive: ", "\n");
+		} else {
+			length = (size_t) rcv_size;
+			if (verbose) {
+				/* Print the header */
+
+				/* Get the source port and prepare the address buffer */
+				address_start = NULL;
+				switch (address->sa_family) {
+				case AF_INET:
+					port = ntohs(address_in->sin_port);
+					address_start = (uint8_t *) &address_in->sin_addr.s_addr;
+					break;
+				case AF_INET6:
+					port = ntohs(address_in6->sin6_port);
+					address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr;
+					break;
+				default:
+					fprintf(stderr, "Address family %u (%#x) is not supported.\n",
+					    address->sa_family, address->sa_family);
+				}
+
+				/* Parse source address */
+				if (address_start) {
+					rc = inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string));
+					if (rc != EOK) {
+						fprintf(stderr, "Received address error %d\n", rc);
+					} else {
+						data[length] = '\0';
+						printf("Socket %d received %zu bytes from %s:%d\n%s\n",
+						    socket_id, length, address_string, port, data);
+					}
+				}
+			}
+
+			/* Answer the request either with the static reply or the original data */
+			rc = sendto(socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen);
+			if (rc != EOK)
+				socket_print_error(stderr, rc, "Socket send: ", "\n");
+		}
+
+		/* Close accepted stream socket */
+		if (type == SOCK_STREAM) {
+			rc = closesocket(socket_id);
+			if (rc != EOK)
+				socket_print_error(stderr, rc, "Close socket: ", "\n");
+		}
+
+	}
+
+	return EOK;
+}
+
+
+int main(int argc, char *argv[])
+{
+	struct sockaddr *address;;
+	struct sockaddr_in address_in;
+	struct sockaddr_in6 address_in6;
+	socklen_t addrlen;
+
+	int listening_id;
+	int index;
+	int rc;
+
+	/* Parse command line arguments */
+	for (index = 1; index < argc; ++index) {
+		if (argv[index][0] == '-') {
+			rc = netecho_parse_option(argc, argv, &index);
+			if (rc != EOK)
+				return rc;
+		} else {
+			echo_print_help();
+			return EINVAL;
+		}
+	}
+
+	/* Check buffer size */
 	if (size <= 0) {
 		fprintf(stderr, "Receive size too small (%zu). Using 1024 bytes instead.\n", size);
 		size = 1024;
 	}
-	// size plus the terminating null (\0)
+
+	/* size plus the terminating null character. */
 	data = (char *) malloc(size + 1);
 	if (!data) {
@@ -230,19 +351,20 @@
 	}
 
-	// set the reply size if set
+	/* Set the reply size if set */
 	reply_length = reply ? str_length(reply) : 0;
 
-	// prepare the address buffer
-	bzero(address_data, max_length);
+	/* Prepare the address buffer */
 	switch (family) {
 	case PF_INET:
-		address_in->sin_family = AF_INET;
-		address_in->sin_port = htons(port);
-		addrlen = sizeof(struct sockaddr_in);
+		address_in.sin_family = AF_INET;
+		address_in.sin_port = htons(port);
+		address = (struct sockaddr *) &address_in;
+		addrlen = sizeof(address_in);
 		break;
 	case PF_INET6:
-		address_in6->sin6_family = AF_INET6;
-		address_in6->sin6_port = htons(port);
-		addrlen = sizeof(struct sockaddr_in6);
+		address_in6.sin6_family = AF_INET6;
+		address_in6.sin6_port = htons(port);
+		address = (struct sockaddr *) &address_in6;
+		addrlen = sizeof(address_in6);
 		break;
 	default:
@@ -251,5 +373,5 @@
 	}
 
-	// get a listening socket
+	/* Get a listening socket */
 	listening_id = socket(family, type, 0);
 	if (listening_id < 0) {
@@ -258,12 +380,13 @@
 	}
 
-	// if the stream socket is used
+	/* if the stream socket is used */
 	if (type == SOCK_STREAM) {
-		// check the backlog
+		/* Check backlog size */
 		if (backlog <= 0) {
 			fprintf(stderr, "Accepted sockets queue size too small (%zu). Using 3 instead.\n", size);
 			backlog = 3;
 		}
-		// set the backlog
+
+		/* Set the backlog */
 		rc = listen(listening_id, backlog);
 		if (rc != EOK) {
@@ -273,5 +396,5 @@
 	}
 
-	// bind the listenning socket
+	/* Bind the listening socket */
 	rc = bind(listening_id, address, addrlen);
 	if (rc != EOK) {
@@ -283,82 +406,18 @@
 		printf("Socket %d listenning at %d\n", listening_id, port);
 
-	socket_id = listening_id;
-
-	// do count times
-	// or indefinitely if set to a negative value
+	/*
+	 * do count times
+	 * or indefinitely if set to a negative value
+	 */
 	while (count) {
-
-		addrlen = max_length;
-		if (type == SOCK_STREAM) {
-			// acceept a socket if the stream socket is used
-			socket_id = accept(listening_id, address, &addrlen);
-			if (socket_id <= 0) {
-				socket_print_error(stderr, socket_id, "Socket accept: ", "\n");
-			} else {
-				if (verbose)
-					printf("Socket %d accepted\n", socket_id);
-			}
-		}
-
-		// if the datagram socket is used or the stream socked was accepted
-		if (socket_id > 0) {
-
-			// receive an echo request
-			value = recvfrom(socket_id, data, size, 0, address, &addrlen);
-			if (value < 0) {
-				socket_print_error(stderr, value, "Socket receive: ", "\n");
-			} else {
-				length = (size_t) value;
-				if (verbose) {
-					// print the header
-
-					// get the source port and prepare the address buffer
-					address_start = NULL;
-					switch (address->sa_family) {
-					case AF_INET:
-						port = ntohs(address_in->sin_port);
-						address_start = (uint8_t *) &address_in->sin_addr.s_addr;
-						break;
-					case AF_INET6:
-						port = ntohs(address_in6->sin6_port);
-						address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr;
-						break;
-					default:
-						fprintf(stderr, "Address family %u (%#x) is not supported.\n",
-						    address->sa_family, address->sa_family);
-					}
-					// parse the source address
-					if (address_start) {
-						rc = inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string));
-						if (rc != EOK) {
-							fprintf(stderr, "Received address error %d\n", rc);
-						} else {
-							data[length] = '\0';
-							printf("Socket %d received %zu bytes from %s:%d\n%s\n",
-							    socket_id, length, address_string, port, data);
-						}
-					}
-				}
-
-				// answer the request either with the static reply or the original data
-				rc = sendto(socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen);
-				if (rc != EOK)
-					socket_print_error(stderr, rc, "Socket send: ", "\n");
-			}
-
-			// close the accepted stream socket
-			if (type == SOCK_STREAM) {
-				rc = closesocket(socket_id);
-				if (rc != EOK)
-					socket_print_error(stderr, rc, "Close socket: ", "\n");
-			}
-
-		}
-
-		// decrease the count if positive
+		rc = netecho_socket_process_message(listening_id);
+		if (rc != EOK)
+			break;
+
+		/* Decrease count if positive */
 		if (count > 0) {
 			count--;
 			if (verbose)
-				printf("Waiting for next %d packet(s)\n", count);
+				printf("Waiting for next %d message(s)\n", count);
 		}
 	}
@@ -367,5 +426,5 @@
 		printf("Closing the socket\n");
 
-	// close the listenning socket
+	/* Close listenning socket */
 	rc = closesocket(listening_id);
 	if (rc != EOK) {
Index: uspace/app/sysinfo/Makefile
===================================================================
--- uspace/app/sysinfo/Makefile	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
+++ uspace/app/sysinfo/Makefile	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
@@ -0,0 +1,36 @@
+#
+# 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.
+#
+
+USPACE_PREFIX = ../..
+EXTRA_CFLAGS = -Iinclude
+BINARY = sysinfo
+
+SOURCES = \
+	sysinfo.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/sysinfo/sysinfo.c
===================================================================
--- uspace/app/sysinfo/sysinfo.c	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
+++ uspace/app/sysinfo/sysinfo.c	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
@@ -0,0 +1,150 @@
+/*
+ * 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 sysinfo
+ * @{
+ */
+/** @file sysinfo.c
+ * @brief Print value of item from sysinfo tree.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <sysinfo.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);
+static void dump_bytes_text(char *data, size_t size);
+
+static void print_syntax(void);
+
+int main(int argc, char *argv[])
+{
+	int rc;
+	char *ipath;
+	sysinfo_item_tag_t tag;
+
+	if (argc != 2) {
+		print_syntax();
+		return 1;
+	}
+
+	ipath = argv[1];
+
+	tag = sysinfo_get_tag(ipath);
+
+	/* Silence warning */
+	rc = EOK;
+
+	switch (tag) {
+	case SYSINFO_VAL_UNDEFINED:
+		printf("Error: Sysinfo item '%s' not defined.\n", ipath);
+		rc = 2;
+		break;
+	case SYSINFO_VAL_VAL:
+		rc = print_item_val(ipath);
+		break;
+	case SYSINFO_VAL_DATA:
+		rc = print_item_data(ipath);
+		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");
+}
+
+/** @}
+ */
Index: uspace/app/taskdump/taskdump.c
===================================================================
--- uspace/app/taskdump/taskdump.c	(revision 1f383dde20a2b1e39baa81fbc44a73c126e508e4)
+++ uspace/app/taskdump/taskdump.c	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
@@ -326,5 +326,5 @@
 
 	sym_pc = fmt_sym_address(pc);
-	printf("Thread %p crashed at %s. FP = %p\n", (void *) thash,
+	printf("Thread %p: PC = %s. FP = %p\n", (void *) thash,
 	    sym_pc, (void *) fp);
 	free(sym_pc);
Index: uspace/app/tester/Makefile
===================================================================
--- uspace/app/tester/Makefile	(revision 1f383dde20a2b1e39baa81fbc44a73c126e508e4)
+++ uspace/app/tester/Makefile	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
@@ -51,8 +51,7 @@
 	vfs/vfs1.c \
 	ipc/ping_pong.c \
-	ipc/register.c \
-	ipc/connect.c \
 	loop/loop1.c \
 	mm/malloc1.c \
+	hw/misc/virtchar1.c \
 	hw/serial/serial1.c
 
Index: uspace/app/tester/hw/misc/virtchar1.c
===================================================================
--- uspace/app/tester/hw/misc/virtchar1.c	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
+++ uspace/app/tester/hw/misc/virtchar1.c	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2010 Vojtech Horky
+ * 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
+ * @brief Test the virtual char driver
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <inttypes.h>
+#include <errno.h>
+#include <str_error.h>
+#include <sys/types.h>
+#include <async.h>
+#include <device/char.h>
+#include <str.h>
+#include <vfs/vfs.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <device/char.h>
+#include "../../tester.h"
+
+#define DEVICE_PATH_NORMAL "/dev/devices/\\virt\\null"
+#define DEVICE_PATH_CLASSES "/dev/class/virt-null\\1"
+#define BUFFER_SIZE 64
+
+static const char *test_virtchar1_internal(const char *path)
+{
+	TPRINTF("Opening `%s'...\n", path);
+	int fd = open(path, O_RDONLY);
+	if (fd < 0) {
+		TPRINTF("   ...error: %s\n", str_error(fd));
+		if (fd == ENOENT) {
+			TPRINTF("   (error was ENOENT: " \
+			    "have you compiled test drivers?)\n");
+		}
+		return "Failed opening devman driver device for reading";
+	}
+	
+	TPRINTF("   ...file handle %d\n", fd);
+
+	TPRINTF(" Asking for phone...\n");
+	int phone = fd_phone(fd);
+	if (phone < 0) {
+		close(fd);
+		TPRINTF("   ...error: %s\n", str_error(phone));
+		return "Failed to get phone to device";
+	}
+	TPRINTF("   ...phone is %d\n", phone);
+	
+	TPRINTF(" Will try to read...\n");
+	size_t i;
+	char buffer[BUFFER_SIZE];
+	read_dev(phone, buffer, BUFFER_SIZE);
+	TPRINTF(" ...verifying that we read zeroes only...\n");
+	for (i = 0; i < BUFFER_SIZE; i++) {
+		if (buffer[i] != 0) {
+			return "Not all bytes are zeroes";
+		}
+	}
+	TPRINTF("   ...data read okay\n");
+	
+	/* Clean-up. */
+	TPRINTF(" Closing phones and file descriptors\n");
+	ipc_hangup(phone);
+	close(fd);
+	
+	return NULL;
+}
+
+const char *test_virtchar1(void)
+{;
+	const char *res;
+
+	res = test_virtchar1_internal(DEVICE_PATH_NORMAL);
+	if (res != NULL) {
+		return res;
+	}
+
+	res = test_virtchar1_internal(DEVICE_PATH_CLASSES);
+	if (res != NULL) {
+		return res;
+	}
+
+	return NULL;
+}
+
+/** @}
+ */
Index: uspace/app/tester/hw/misc/virtchar1.def
===================================================================
--- uspace/app/tester/hw/misc/virtchar1.def	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
+++ uspace/app/tester/hw/misc/virtchar1.def	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
@@ -0,0 +1,6 @@
+{
+	"virtchar1",
+	"Virtual char device test",
+	&test_virtchar1,
+	false
+},
Index: uspace/app/tester/ipc/connect.c
===================================================================
--- uspace/app/tester/ipc/connect.c	(revision 1f383dde20a2b1e39baa81fbc44a73c126e508e4)
+++ 	(revision )
@@ -1,73 +1,0 @@
-/*
- * Copyright (c) 2006 Ondrej Palkovsky
- * 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 <atomic.h>
-#include "../tester.h"
-
-static atomic_t finish;
-
-static void callback(void *priv, int retval, ipc_call_t *data)
-{
-	atomic_set(&finish, 1);
-}
-
-const char *test_connect(void)
-{
-	TPRINTF("Connecting to %u...", IPC_TEST_SERVICE);
-	int phone = ipc_connect_me_to(PHONE_NS, IPC_TEST_SERVICE, 0, 0);
-	if (phone > 0) {
-		TPRINTF("phoneid %d\n", phone);
-	} else {
-		TPRINTF("\n");
-		return "ipc_connect_me_to() failed";
-	}
-	
-	printf("Sending synchronous message...\n");
-	int retval = ipc_call_sync_0_0(phone, IPC_TEST_METHOD);
-	TPRINTF("Received response to synchronous message\n");
-	
-	TPRINTF("Sending asynchronous message...\n");
-	atomic_set(&finish, 0);
-	ipc_call_async_0(phone, IPC_TEST_METHOD, NULL, callback, 1);
-	while (atomic_get(&finish) != 1)
-		TPRINTF(".");
-	TPRINTF("Received response to asynchronous message\n");
-	
-	TPRINTF("Hanging up...");
-	retval = ipc_hangup(phone);
-	if (retval == 0) {
-		TPRINTF("OK\n");
-	} else {
-		TPRINTF("\n");
-		return "ipc_hangup() failed";
-	}
-	
-	return NULL;
-}
Index: uspace/app/tester/ipc/connect.def
===================================================================
--- uspace/app/tester/ipc/connect.def	(revision 1f383dde20a2b1e39baa81fbc44a73c126e508e4)
+++ 	(revision )
@@ -1,6 +1,0 @@
-{
-	"connect",
-	"IPC connection test (connect to other service)",
-	&test_connect,
-	true
-},
Index: uspace/app/tester/ipc/register.c
===================================================================
--- uspace/app/tester/ipc/register.c	(revision 1f383dde20a2b1e39baa81fbc44a73c126e508e4)
+++ 	(revision )
@@ -1,90 +1,0 @@
-/*
- * Copyright (c) 2006 Ondrej Palkovsky
- * 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 <inttypes.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <async.h>
-#include <errno.h>
-#include "../tester.h"
-
-#define MAX_CONNECTIONS  50
-
-static int connections[MAX_CONNECTIONS];
-
-static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
-{
-	unsigned int i;
-	
-	TPRINTF("Connected phone %" PRIun " accepting\n", icall->in_phone_hash);
-	ipc_answer_0(iid, EOK);
-	for (i = 0; i < MAX_CONNECTIONS; i++) {
-		if (!connections[i]) {
-			connections[i] = icall->in_phone_hash;
-			break;
-		}
-	}
-	
-	while (true) {
-		ipc_call_t call;
-		ipc_callid_t callid = async_get_call(&call);
-		int retval;
-		
-		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
-			TPRINTF("Phone %" PRIun " hung up\n", icall->in_phone_hash);
-			retval = 0;
-			break;
-		case IPC_TEST_METHOD:
-			TPRINTF("Received well known message from %" PRIun ": %" PRIun "\n",
-			    icall->in_phone_hash, callid);
-			ipc_answer_0(callid, EOK);
-			break;
-		default:
-			TPRINTF("Received unknown message from %" PRIun ": %" PRIun "\n",
-			    icall->in_phone_hash, callid);
-			ipc_answer_0(callid, ENOENT);
-			break;
-		}
-	}
-}
-
-const char *test_register(void)
-{
-	async_set_client_connection(client_connection);
-	
-	sysarg_t phonead;
-	int res = ipc_connect_to_me(PHONE_NS, IPC_TEST_SERVICE, 0, 0, &phonead);
-	if (res != 0)
-		return "Failed registering IPC service";
-	
-	TPRINTF("Registered as service %u, accepting connections\n", IPC_TEST_SERVICE);
-	async_manager();
-	
-	return NULL;
-}
Index: uspace/app/tester/ipc/register.def
===================================================================
--- uspace/app/tester/ipc/register.def	(revision 1f383dde20a2b1e39baa81fbc44a73c126e508e4)
+++ 	(revision )
@@ -1,6 +1,0 @@
-{
-	"register",
-	"IPC registration test",
-	&test_register,
-	true
-},
Index: uspace/app/tester/tester.c
===================================================================
--- uspace/app/tester/tester.c	(revision 1f383dde20a2b1e39baa81fbc44a73c126e508e4)
+++ uspace/app/tester/tester.c	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
@@ -60,10 +60,9 @@
 #include "vfs/vfs1.def"
 #include "ipc/ping_pong.def"
-#include "ipc/register.def"
-#include "ipc/connect.def"
 #include "loop/loop1.def"
 #include "mm/malloc1.def"
 #include "hw/serial/serial1.def"
 #include "adt/usbaddrkeep.def"
+#include "hw/misc/virtchar1.def"
 	{NULL, NULL, NULL, false}
 };
Index: uspace/app/tester/tester.h
===================================================================
--- uspace/app/tester/tester.h	(revision 1f383dde20a2b1e39baa81fbc44a73c126e508e4)
+++ uspace/app/tester/tester.h	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
@@ -77,10 +77,9 @@
 extern const char *test_vfs1(void);
 extern const char *test_ping_pong(void);
-extern const char *test_register(void);
-extern const char *test_connect(void);
 extern const char *test_loop1(void);
 extern const char *test_malloc1(void);
 extern const char *test_serial1(void);
 extern const char *test_usbaddrkeep(void);
+extern const char *test_virtchar1(void);
 
 extern test_t tests[];
Index: uspace/app/tester/vfs/vfs1.c
===================================================================
--- uspace/app/tester/vfs/vfs1.c	(revision 1f383dde20a2b1e39baa81fbc44a73c126e508e4)
+++ uspace/app/tester/vfs/vfs1.c	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
@@ -40,10 +40,5 @@
 #include "../tester.h"
 
-#define FS_TYPE      "tmpfs"
-#define MOUNT_POINT  "/tmp"
-#define OPTIONS      ""
-#define FLAGS        0
-
-#define TEST_DIRECTORY  MOUNT_POINT "/testdir"
+#define TEST_DIRECTORY  "/tmp/testdir"
 #define TEST_FILE       TEST_DIRECTORY "/testfile"
 #define TEST_FILE2      TEST_DIRECTORY "/nextfile"
@@ -75,23 +70,9 @@
 const char *test_vfs1(void)
 {
-	if (mkdir(MOUNT_POINT, 0) != 0)
+	int rc;
+	if ((rc = mkdir(TEST_DIRECTORY, 0)) != 0) {
+		TPRINTF("rc=%d\n", rc);
 		return "mkdir() failed";
-	TPRINTF("Created directory %s\n", MOUNT_POINT);
-	
-	int rc = mount(FS_TYPE, MOUNT_POINT, "", OPTIONS, FLAGS);
-	switch (rc) {
-	case EOK:
-		TPRINTF("Mounted %s on %s\n", FS_TYPE, MOUNT_POINT);
-		break;
-	case EBUSY:
-		TPRINTF("(INFO) Filesystem already mounted on %s\n", MOUNT_POINT);
-		break;
-	default:
-		TPRINTF("(ERR) IPC returned errno %d (is tmpfs loaded?)\n", rc);
-		return "mount() failed";
 	}
-	
-	if (mkdir(TEST_DIRECTORY, 0) != 0)
-		return "mkdir() failed";
 	TPRINTF("Created directory %s\n", TEST_DIRECTORY);
 	
Index: uspace/app/websrv/Makefile
===================================================================
--- uspace/app/websrv/Makefile	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
+++ uspace/app/websrv/Makefile	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
@@ -0,0 +1,37 @@
+#
+# 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.
+#
+
+USPACE_PREFIX = ../..
+LIBS =
+EXTRA_CFLAGS =
+BINARY = websrv
+
+SOURCES = \
+	websrv.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/websrv/websrv.c
===================================================================
--- uspace/app/websrv/websrv.c	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
+++ uspace/app/websrv/websrv.c	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
@@ -0,0 +1,143 @@
+/*
+ * 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 websrv
+ * @{
+ */
+/**
+ * @file (Less-than-skeleton) web server.
+ */
+
+#include <stdio.h>
+
+#include <net/in.h>
+#include <net/inet.h>
+#include <net/socket.h>
+
+#include <str.h>
+
+#define PORT_NUMBER 8080
+
+/** Buffer for receiving the request. */
+#define BUFFER_SIZE 1024
+static char buf[BUFFER_SIZE];
+
+/** Response to send to client. */
+static const char *response_msg =
+    "HTTP/1.0 200 OK\r\n"
+    "\r\n"
+    "<h1>Hello from HelenOS!</h1>\r\n";
+
+int main(int argc, char *argv[])
+{
+	struct sockaddr_in addr;
+	struct sockaddr_in raddr;
+
+	socklen_t raddr_len;
+
+	int listen_sd, conn_sd;
+	int rc;
+
+	size_t response_size;
+
+	addr.sin_family = AF_INET;
+	addr.sin_port = htons(PORT_NUMBER);
+
+	rc = inet_pton(AF_INET, "127.0.0.1", (void *) &addr.sin_addr.s_addr);
+	if (rc != EOK) {
+		printf("Error parsing network address.\n");
+		return 1;
+	}
+
+	printf("Creating socket.\n");
+
+	listen_sd = socket(PF_INET, SOCK_STREAM, 0);
+	if (listen_sd < 0) {
+		printf("Error creating listening socket.\n");
+		return 1;
+	}
+
+	rc = bind(listen_sd, (struct sockaddr *) &addr, sizeof(addr));
+	if (rc != EOK) {
+		printf("Error binding socket.\n");
+		return 1;
+	}
+
+	rc = listen(listen_sd, 1);
+	if (rc != EOK) {
+		printf("Error calling listen() (%d).\n", rc);
+		return 1;
+	}
+
+	response_size = str_size(response_msg);
+
+	printf("Listening for connections at port number %u.\n", PORT_NUMBER);
+	while (true) {
+		raddr_len = sizeof(raddr);
+		conn_sd = accept(listen_sd, (struct sockaddr *) &raddr,
+		    &raddr_len);
+
+		if (conn_sd < 0) {
+			printf("accept() failed.\n");
+			return 1;
+		}
+
+		printf("Accepted connection, sd=%d.\n", conn_sd);
+
+		printf("Wait for client request\n");
+
+		/* Really we should wait for a blank line. */
+		rc = recv(conn_sd, buf, BUFFER_SIZE, 0);
+		if (rc < 0) {
+			printf("recv() failed\n");
+			return 1;
+		}
+
+		/* Send a canned response. */
+                printf("Send response...\n");
+		rc = send(conn_sd, (void *) response_msg, response_size, 0);
+		if (rc < 0) {
+			printf("send() failed.\n");
+			return 1;
+		}
+
+		rc = closesocket(conn_sd);
+		if (rc != EOK) {
+			printf("Error closing connection socket: %d\n", rc);
+			return 1;
+		}
+
+		printf("Closed connection.\n");
+	}
+
+	/* Not reached. */
+	return 0;
+}
+
+/** @}
+ */
