Index: uspace/app/bdsh/Makefile
===================================================================
--- uspace/app/bdsh/Makefile	(revision 86554e71a1dd77b66b874136837c0b9cd1957907)
+++ uspace/app/bdsh/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,139 +1,40 @@
-# Copyright (c) 2005,  Martin Decky
-# All rights reserved.
-# Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
+#
+# 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:
+# 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 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.
 #
-# 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.
+# 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.
 #
-# Neither the name of the original program's authors nor the names of its
-# contributors may be used to endorse or promote products derived from this
-# software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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 ../../../version
+include Makefile.common
 
-LIBC_PREFIX = ../../lib/libc
-SOFTINT_PREFIX = ../../lib/softint
-LIBBLOCK_PREFIX = ../../lib/libblock
+.PHONY: all clean
 
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-CFLAGS += -I../../srv/kbd/include -I$(LIBBLOCK_PREFIX)
-
-LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBC_PREFIX)/libc.a
-DEFS += -DRELEASE=$(RELEASE)
-
-PROGRAM = bdsh
-
-# Any directory that cleaning targets should know about
-SUBDIRS = \
-	./ \
-	cmds/ \
-	cmds/modules/ \
-	cmds/modules/help/ \
-	cmds/modules/mkdir/ \
-	cmds/modules/rm/ \
-	cmds/modules/bdd/ \
-	cmds/modules/cat/ \
-	cmds/modules/touch/ \
-	cmds/modules/ls/ \
-	cmds/modules/pwd/ \
-	cmds/modules/sleep/ \
-	cmds/modules/cp/ \
-	cmds/modules/mv/ \
-	cmds/modules/mount/ \
-	cmds/modules/kcon/ \
-	cmds/builtins/ \
-	cmds/builtins/exit/\
-	cmds/builtins/cd/
-
-SOURCES = \
-	cmds/modules/help/help.c \
-	cmds/modules/mkdir/mkdir.c \
-	cmds/modules/rm/rm.c \
-	cmds/modules/bdd/bdd.c \
-	cmds/modules/cat/cat.c \
-	cmds/modules/touch/touch.c \
-	cmds/modules/ls/ls.c \
-	cmds/modules/pwd/pwd.c \
-	cmds/modules/sleep/sleep.c \
-	cmds/modules/cp/cp.c \
-	cmds/modules/mv/mv.c \
-	cmds/modules/mount/mount.c \
-	cmds/modules/kcon/kcon.c \
-	cmds/builtins/exit/exit.c \
-	cmds/builtins/cd/cd.c \
-	cmds/mod_cmds.c \
-	cmds/builtin_cmds.c \
-	errors.c \
-	input.c \
-	util.c \
-	exec.c \
-	scli.c
-
-CFLAGS += -I. -Icmds/ -Icmds/builtins -Icmds/modules
-
-OBJECTS = $(SOURCES:.c=.o)
-
-# For easy cleaning, *.o is already handled
-CLEANDIRS := $(addsuffix *~,$(SUBDIRS))
-CLEANDIRS += $(addsuffix *.bak,$(SUBDIRS))
-CLEANDIRS += $(addsuffix *.tmp,$(SUBDIRS))
-CLEANDIRS += $(addsuffix *.out,$(SUBDIRS))
-CLEANDIRS += $(addsuffix *.d,$(SUBDIRS))
-CLEANDIRS += $(addsuffix *.gch,$(SUBDIRS) )
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(CFLAGS) $(INC) -c $< -o $@
-	@$(CC) -M $(CFLAGS) $(INC) $*.c > $*.d
-
-$(PROGRAM): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(PROGRAM).map
-
-# Everything else is a phony target
-.PHONY: all clean distclean depend disasm
-
-all: $(PROGRAM) disasm
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	@-rm -f $(OBJECTS)
-	@-rm -f $(PROGRAM)
-	@-rm -f $(PROGRAM).map
-	@-rm -f $(PROGRAM).disasm
-	@-rm -f $(CLEANDIRS)
-
-depend:
-	@echo ''
-
-disasm:
-	$(OBJDUMP) -d $(PROGRAM) >$(PROGRAM).disasm
-
-distclean: clean
-
-# Do not delete - dependencies
--include $(OBJECTS:.o=.d)
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/app/bdsh/Makefile.build
===================================================================
--- uspace/app/bdsh/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/bdsh/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,84 @@
+#
+# 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+CFLAGS += -I$(LIBBLOCK_PREFIX) -I. -Icmds/ -Icmds/builtins -Icmds/modules
+
+## Sources
+#
+
+SOURCES = \
+	cmds/modules/help/help.c \
+	cmds/modules/mkdir/mkdir.c \
+	cmds/modules/rm/rm.c \
+	cmds/modules/bdd/bdd.c \
+	cmds/modules/cat/cat.c \
+	cmds/modules/touch/touch.c \
+	cmds/modules/ls/ls.c \
+	cmds/modules/pwd/pwd.c \
+	cmds/modules/sleep/sleep.c \
+	cmds/modules/cp/cp.c \
+	cmds/modules/mv/mv.c \
+	cmds/modules/mount/mount.c \
+	cmds/modules/kcon/kcon.c \
+	cmds/builtins/exit/exit.c \
+	cmds/builtins/cd/cd.c \
+	cmds/mod_cmds.c \
+	cmds/builtin_cmds.c \
+	errors.c \
+	input.c \
+	util.c \
+	exec.c \
+	scli.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/app/bdsh/Makefile.common
===================================================================
--- uspace/app/bdsh/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/bdsh/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBBLOCK_PREFIX = ../../lib/libblock
+LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = bdsh
Index: uspace/app/bdsh/cmds/modules/bdd/bdd.c
===================================================================
--- uspace/app/bdsh/cmds/modules/bdd/bdd.c	(revision 86554e71a1dd77b66b874136837c0b9cd1957907)
+++ uspace/app/bdsh/cmds/modules/bdd/bdd.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -40,7 +40,10 @@
 #include <devmap.h>
 #include <errno.h>
+#include <assert.h>
 
-#define BLOCK_SIZE	512
-#define BPR		 16
+enum {
+	/* Number of bytes per row */
+	BPR = 16
+};
 
 static const char *cmdname = "bdd";
@@ -66,9 +69,9 @@
 	unsigned int i, j;
 	dev_handle_t handle;
-	block_t *block;
 	uint8_t *blk;
 	size_t size, bytes, rows;
+	size_t block_size;
 	int rc;
-	bn_t boff;
+	bn_t ba;
 	uint8_t b;
 
@@ -82,7 +85,7 @@
 
 	if (argc >= 3)
-		boff = strtol(argv[2], NULL, 0);
+		ba = strtol(argv[2], NULL, 0);
 	else
-		boff = 0;
+		ba = 0;
 
 	if (argc >= 4)
@@ -93,25 +96,37 @@
 	rc = devmap_device_get_handle(argv[1], &handle, 0);
 	if (rc != EOK) {
-		printf("Error: could not resolve device `%s'.\n", argv[1]);
+		printf("%s: Error resolving device `%s'.\n", cmdname, argv[1]);
 		return CMD_FAILURE;
 	}
 
-	rc = block_init(handle, BLOCK_SIZE);
+	rc = block_init(handle, 2048);
 	if (rc != EOK)  {
-		printf("Error: could not init libblock.\n");
+		printf("%s: Error initializing libblock.\n", cmdname);
 		return CMD_FAILURE;
 	}
 
-	rc = block_cache_init(handle, BLOCK_SIZE, 2, CACHE_MODE_WB);
+	rc = block_get_bsize(handle, &block_size);
 	if (rc != EOK) {
-		printf("Error: could not init block cache.\n");
+		printf("%s: Error determining device block size.\n", cmdname);
+		return CMD_FAILURE;
+	}
+
+	blk = malloc(block_size);
+	if (blk == NULL) {
+		printf("%s: Error allocating memory.\n", cmdname);
+		block_fini(handle);
 		return CMD_FAILURE;
 	}
 
 	while (size > 0) {
-		block = block_get(handle, boff, 0);
-		blk = (uint8_t *) block->data;
+		rc = block_read_direct(handle, ba, 1, blk);
+		if (rc != EOK) {
+			printf("%s: Error reading block %llu\n", cmdname, ba);
+			free(blk);
+			block_fini(handle);
+			return CMD_FAILURE;
+		}
 
-		bytes = (size < BLOCK_SIZE) ? size : BLOCK_SIZE;
+		bytes = (size < block_size) ? size : block_size;
 		rows = (bytes + BPR - 1) / BPR;
 
@@ -139,6 +154,4 @@
 		}
 
-		block_put(block);
-
 		if (size > rows * BPR)
 			size -= rows * BPR;
@@ -146,7 +159,9 @@
 			size = 0;
 
-		boff += rows * BPR;
+		/* Next block */
+		ba += 1;
 	}
 
+	free(blk);
 	block_fini(handle);
 
Index: uspace/app/bdsh/scli.c
===================================================================
--- uspace/app/bdsh/scli.c	(revision 86554e71a1dd77b66b874136837c0b9cd1957907)
+++ uspace/app/bdsh/scli.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -61,8 +61,6 @@
 	usr->line = (char *) NULL;
 	usr->name = "root";
-	usr->home = "/";
 	usr->cwd = (char *) NULL;
 	usr->prompt = (char *) NULL;
-	chdir(usr->home);
 	usr->lasterr = 0;
 	return (int) cli_set_prompt(usr);
Index: uspace/app/bdsh/scli.h
===================================================================
--- uspace/app/bdsh/scli.h	(revision 86554e71a1dd77b66b874136837c0b9cd1957907)
+++ uspace/app/bdsh/scli.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -7,5 +7,4 @@
 typedef struct {
 	char *name;
-	char *home;
 	char *line;
 	char *cwd;
Index: uspace/app/edit/Makefile
===================================================================
--- uspace/app/edit/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/edit/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,40 @@
+#
+# 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.
+#
+
+include Makefile.common
+
+.PHONY: all clean
+
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
+
+clean:
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/app/edit/Makefile.build
===================================================================
--- uspace/app/edit/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/edit/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,62 @@
+#
+# 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	edit.c \
+	sheet.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/app/edit/Makefile.common
===================================================================
--- uspace/app/edit/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/edit/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = edit
Index: uspace/app/edit/edit.c
===================================================================
--- uspace/app/edit/edit.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/edit/edit.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,686 @@
+/*
+ * Copyright (c) 2009 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 edit
+ * @brief Text editor.
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <vfs/vfs.h>
+#include <io/console.h>
+#include <io/color.h>
+#include <io/keycode.h>
+#include <errno.h>
+#include <align.h>
+#include <macros.h>
+#include <bool.h>
+
+#include "sheet.h"
+
+enum redraw_flags {
+	REDRAW_TEXT	= (1 << 0),
+	REDRAW_ROW	= (1 << 1),
+	REDRAW_STATUS	= (1 << 2),
+	REDRAW_CARET	= (1 << 3)
+};
+
+/** Pane
+ *
+ * A rectangular area of the screen used to edit a document. Different
+ * panes can be possibly used to edit the same document.
+ */
+typedef struct {
+	/* Pane dimensions */
+	int rows, columns;
+
+	/* Position of the visible area */
+	int sh_row, sh_column;
+
+	/** Bitmask of components that need redrawing */
+	enum redraw_flags rflags;
+
+	/** Current position of the caret */
+	tag_t caret_pos;
+
+	/** 
+	 * Ideal column where the caret should try to get. This is used
+	 * for maintaining the same column during vertical movement.
+	 */
+	int ideal_column;
+} pane_t;
+
+/** Document
+ *
+ * Associates a sheet with a file where it can be saved to.
+ */
+typedef struct {
+	char *file_name;
+	sheet_t sh;
+} doc_t;
+
+static int con;
+static doc_t doc;
+static bool done;
+static pane_t pane;
+
+static int scr_rows, scr_columns;
+
+#define ROW_BUF_SIZE 4096
+#define BUF_SIZE 64
+#define TAB_WIDTH 8
+#define ED_INFTY 65536
+
+static void key_handle_unmod(console_event_t const *ev);
+static void key_handle_ctrl(console_event_t const *ev);
+static int file_save(char const *fname);
+static int file_insert(char *fname);
+static int file_save_range(char const *fname, spt_t const *spos,
+    spt_t const *epos);
+static void pane_text_display(void);
+static void pane_row_display(void);
+static void pane_row_range_display(int r0, int r1);
+static void pane_status_display(void);
+static void pane_caret_display(void);
+static void insert_char(wchar_t c);
+static void delete_char_before(void);
+static void delete_char_after(void);
+static void caret_update(void);
+static void caret_move(int drow, int dcolumn, enum dir_spec align_dir);
+static void pt_get_sof(spt_t *pt);
+static void pt_get_eof(spt_t *pt);
+static void status_display(char const *str);
+
+
+int main(int argc, char *argv[])
+{
+	console_event_t ev;
+	coord_t coord;
+	bool new_file;
+
+	spt_t pt;
+
+	con = fphone(stdout);
+	console_clear(con);
+
+	console_get_size(con, &scr_columns, &scr_rows);
+
+	pane.rows = scr_rows - 1;
+	pane.columns = scr_columns;
+	pane.sh_row = 1;
+	pane.sh_column = 1;
+
+	/* Start with an empty sheet. */
+	sheet_init(&doc.sh);
+
+	/* Place caret at the beginning of file. */
+	coord.row = coord.column = 1;
+	sheet_get_cell_pt(&doc.sh, &coord, dir_before, &pt);
+	sheet_place_tag(&doc.sh, &pt, &pane.caret_pos);
+	pane.ideal_column = coord.column;
+
+	if (argc == 2) {
+		doc.file_name = argv[1];
+	} else if (argc > 1) {
+		printf("Invalid arguments.\n");
+		return -2;
+	} else {
+		doc.file_name = "/edit.txt";
+	}
+
+	new_file = false;
+
+	if (file_insert(doc.file_name) != EOK)
+		new_file = true;
+
+	/* Move to beginning of file. */
+	caret_move(-ED_INFTY, -ED_INFTY, dir_before);
+
+	/* Initial display */
+	console_clear(con);
+	pane_text_display();
+	pane_status_display();
+	if (new_file)
+		status_display("File not found. Created empty file.");
+	pane_caret_display();
+
+
+	done = false;
+
+	while (!done) {
+		console_get_event(con, &ev);
+		pane.rflags = 0;
+
+		if (ev.type == KEY_PRESS) {
+			/* Handle key press. */
+			if (((ev.mods & KM_ALT) == 0) &&
+			     (ev.mods & KM_CTRL) != 0) {
+				key_handle_ctrl(&ev);
+			} else if ((ev.mods & (KM_CTRL | KM_ALT)) == 0) {
+				key_handle_unmod(&ev);
+			}
+		}
+
+		/* Redraw as necessary. */
+
+		if (pane.rflags & REDRAW_TEXT)
+			pane_text_display();
+		if (pane.rflags & REDRAW_ROW)
+			pane_row_display();
+		if (pane.rflags & REDRAW_STATUS)
+			pane_status_display();
+		if (pane.rflags & REDRAW_CARET)
+			pane_caret_display();
+			
+	}
+
+	console_clear(con);
+
+	return 0;
+}
+
+/** Handle key without modifier. */
+static void key_handle_unmod(console_event_t const *ev)
+{
+	switch (ev->key) {
+	case KC_ENTER:
+		insert_char('\n');
+		caret_update();
+		break;
+	case KC_LEFT:
+		caret_move(0, -1, dir_before);
+		break;
+	case KC_RIGHT:
+		caret_move(0, 0, dir_after);
+		break;
+	case KC_UP:
+		caret_move(-1, 0, dir_before);
+		break;
+	case KC_DOWN:
+		caret_move(+1, 0, dir_before);
+		break;
+	case KC_HOME:
+		caret_move(0, -ED_INFTY, dir_before);
+		break;
+	case KC_END:
+		caret_move(0, +ED_INFTY, dir_before);
+		break;
+	case KC_PAGE_UP:
+		caret_move(-pane.rows, 0, dir_before);
+		break;
+	case KC_PAGE_DOWN:
+		caret_move(+pane.rows, 0, dir_before);
+		break;
+	case KC_BACKSPACE:
+		delete_char_before();
+		caret_update();
+		break;
+	case KC_DELETE:
+		delete_char_after();
+		caret_update();
+		break;
+	default:
+		if (ev->c >= 32 || ev->c == '\t') {
+			insert_char(ev->c);
+			caret_update();
+		}
+		break;
+	}
+}
+
+/** Handle Ctrl-key combination. */
+static void key_handle_ctrl(console_event_t const *ev)
+{
+	switch (ev->key) {
+	case KC_Q:
+		done = true;
+		break;
+	case KC_S:
+		(void) file_save(doc.file_name);
+		break;
+	default:
+		break;
+	}
+}
+
+
+/** Save the document. */
+static int file_save(char const *fname)
+{
+	spt_t sp, ep;
+	int rc;
+
+	status_display("Saving...");
+	pt_get_sof(&sp);
+	pt_get_eof(&ep);
+
+	rc = file_save_range(fname, &sp, &ep);
+	status_display("File saved.");
+
+	return rc;
+}
+
+/** Insert file at caret position.
+ *
+ * Reads in the contents of a file and inserts them at the current position
+ * of the caret.
+ */
+static int file_insert(char *fname)
+{
+	FILE *f;
+	wchar_t c;
+	char buf[BUF_SIZE];
+	int bcnt;
+	int n_read;
+	size_t off;
+
+	f = fopen(fname, "rt");
+	if (f == NULL)
+		return EINVAL;
+
+	bcnt = 0;
+
+	while (true) {
+		if (bcnt < STR_BOUNDS(1)) {
+			n_read = fread(buf + bcnt, 1, BUF_SIZE - bcnt, f);
+			bcnt += n_read;
+		}
+
+		off = 0;
+		c = str_decode(buf, &off, bcnt);
+		if (c == '\0')
+			break;
+
+		bcnt -= off;
+		memcpy(buf, buf + off, bcnt);
+
+		insert_char(c);
+	}
+
+	fclose(f);
+
+	return EOK;
+}
+
+/** Save a range of text into a file. */
+static int file_save_range(char const *fname, spt_t const *spos,
+    spt_t const *epos)
+{
+	FILE *f;
+	char buf[BUF_SIZE];
+	spt_t sp, bep;
+	size_t bytes, n_written;
+
+	f = fopen(fname, "wt");
+	if (f == NULL)
+		return EINVAL;
+
+	sp = *spos;
+
+	do {
+		sheet_copy_out(&doc.sh, &sp, epos, buf, BUF_SIZE, &bep);
+		bytes = str_size(buf);
+
+		n_written = fwrite(buf, 1, bytes, f);
+		if (n_written != bytes) {
+			return EIO;
+		}
+
+		sp = bep;
+	} while (!spt_equal(&bep, epos));
+
+	fclose(f);
+
+	return EOK;
+}
+
+static void pane_text_display(void)
+{
+	int sh_rows, rows;
+	int i, j;
+
+	sheet_get_num_rows(&doc.sh, &sh_rows);
+	rows = min(sh_rows - pane.sh_row + 1, pane.rows);
+
+	/* Draw rows from the sheet. */
+
+	console_goto(con, 0, 0);
+	pane_row_range_display(0, rows);
+
+	/* Clear the remaining rows if file is short. */
+
+	for (i = rows; i < pane.rows; ++i) {
+		console_goto(con, 0, i);
+		for (j = 0; j < scr_columns; ++j)
+			putchar(' ');
+		fflush(stdout);
+	}
+
+	pane.rflags |= (REDRAW_STATUS | REDRAW_CARET);
+	pane.rflags &= ~REDRAW_ROW;
+}
+
+/** Display just the row where the caret is. */
+static void pane_row_display(void)
+{
+	spt_t caret_pt;
+	coord_t coord;
+	int ridx;
+
+	tag_get_pt(&pane.caret_pos, &caret_pt);
+	spt_get_coord(&caret_pt, &coord);
+
+	ridx = coord.row - pane.sh_row;
+	pane_row_range_display(ridx, ridx + 1);
+	pane.rflags |= (REDRAW_STATUS | REDRAW_CARET);
+}
+
+static void pane_row_range_display(int r0, int r1)
+{
+	int i, j, fill;
+	spt_t rb, re, dep;
+	coord_t rbc, rec;
+	char row_buf[ROW_BUF_SIZE];
+	wchar_t c;
+	size_t pos, size;
+	unsigned s_column;
+
+	/* Draw rows from the sheet. */
+
+	console_goto(con, 0, 0);
+	for (i = r0; i < r1; ++i) {
+		/* Starting point for row display */
+		rbc.row = pane.sh_row + i;
+		rbc.column = pane.sh_column;
+		sheet_get_cell_pt(&doc.sh, &rbc, dir_before, &rb);
+
+		/* Ending point for row display */
+		rec.row = pane.sh_row + i;
+		rec.column = pane.sh_column + pane.columns;
+		sheet_get_cell_pt(&doc.sh, &rec, dir_before, &re);
+
+		/* Copy the text of the row to the buffer. */
+		sheet_copy_out(&doc.sh, &rb, &re, row_buf, ROW_BUF_SIZE, &dep);
+
+		/* Display text from the buffer. */
+
+		console_goto(con, 0, i);
+		size = str_size(row_buf);
+		pos = 0;
+		s_column = 1;
+		while (pos < size) {
+			c = str_decode(row_buf, &pos, size);
+			if (c != '\t') {
+				printf("%lc", c);
+				s_column += 1;
+			} else {
+				fill = 1 + ALIGN_UP(s_column, TAB_WIDTH)
+				    - s_column;
+
+				for (j = 0; j < fill; ++j)
+					putchar(' ');
+				s_column += fill;
+			}
+		}
+
+		/* Fill until the end of display area. */
+
+		if (str_length(row_buf) < (unsigned) scr_columns)
+			fill = scr_columns - str_length(row_buf);
+		else
+			fill = 0;
+
+		for (j = 0; j < fill; ++j)
+			putchar(' ');
+		fflush(stdout);
+	}
+
+	pane.rflags |= REDRAW_CARET;
+}
+
+/** Display pane status in the status line. */
+static void pane_status_display(void)
+{
+	spt_t caret_pt;
+	coord_t coord;
+	int n;
+
+	tag_get_pt(&pane.caret_pos, &caret_pt);
+	spt_get_coord(&caret_pt, &coord);
+
+	console_goto(con, 0, scr_rows - 1);
+	console_set_color(con, COLOR_WHITE, COLOR_BLACK, 0);
+	n = printf(" %d, %d: File '%s'. Ctrl-S Save  Ctrl-Q Quit",
+	    coord.row, coord.column, doc.file_name);
+	printf("%*s", scr_columns - 1 - n, "");
+	fflush(stdout);
+	console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);
+
+	pane.rflags |= REDRAW_CARET;
+}
+
+/** Set cursor to reflect position of the caret. */
+static void pane_caret_display(void)
+{
+	spt_t caret_pt;
+	coord_t coord;
+
+	tag_get_pt(&pane.caret_pos, &caret_pt);
+
+	spt_get_coord(&caret_pt, &coord);
+	console_goto(con, coord.column - pane.sh_column,
+	    coord.row - pane.sh_row);
+}
+
+/** Insert a character at caret position. */
+static void insert_char(wchar_t c)
+{
+	spt_t pt;
+	char cbuf[STR_BOUNDS(1) + 1];
+	size_t offs;
+
+	tag_get_pt(&pane.caret_pos, &pt);
+
+	offs = 0;
+	chr_encode(c, cbuf, &offs, STR_BOUNDS(1) + 1);
+	cbuf[offs] = '\0';
+
+	(void) sheet_insert(&doc.sh, &pt, dir_before, cbuf);
+
+	pane.rflags |= REDRAW_ROW;
+	if (c == '\n')
+		pane.rflags |= REDRAW_TEXT;
+}
+
+/** Delete the character before the caret. */
+static void delete_char_before(void)
+{
+	spt_t sp, ep;
+	coord_t coord;
+
+	tag_get_pt(&pane.caret_pos, &ep);
+	spt_get_coord(&ep, &coord);
+
+	coord.column -= 1;
+	sheet_get_cell_pt(&doc.sh, &coord, dir_before, &sp);
+
+	(void) sheet_delete(&doc.sh, &sp, &ep);
+
+	pane.rflags |= REDRAW_ROW;
+	if (coord.column < 1)
+		pane.rflags |= REDRAW_TEXT;
+}
+
+/** Delete the character after the caret. */
+static void delete_char_after(void)
+{
+	spt_t sp, ep;
+	coord_t sc, ec;
+
+	tag_get_pt(&pane.caret_pos, &sp);
+	spt_get_coord(&sp, &sc);
+
+	sheet_get_cell_pt(&doc.sh, &sc, dir_after, &ep);
+	spt_get_coord(&ep, &ec);
+
+	(void) sheet_delete(&doc.sh, &sp, &ep);
+
+	pane.rflags |= REDRAW_ROW;
+	if (ec.row != sc.row)
+		pane.rflags |= REDRAW_TEXT;
+}
+
+/** Scroll pane after caret has moved.
+ *
+ * After modifying the position of the caret, this is called to scroll
+ * the pane to ensure that the caret is in the visible area.
+ */
+static void caret_update(void)
+{
+	spt_t pt;
+	coord_t coord;
+
+	tag_get_pt(&pane.caret_pos, &pt);
+	spt_get_coord(&pt, &coord);
+
+	/* Scroll pane vertically. */
+
+	if (coord.row < pane.sh_row) {
+		pane.sh_row = coord.row;
+		pane.rflags |= REDRAW_TEXT;
+	}
+
+	if (coord.row > pane.sh_row + pane.rows - 1) {
+		pane.sh_row = coord.row - pane.rows + 1;
+		pane.rflags |= REDRAW_TEXT;
+	}
+
+	/* Scroll pane horizontally. */
+
+	if (coord.column < pane.sh_column) {
+		pane.sh_column = coord.column;
+		pane.rflags |= REDRAW_TEXT;
+	}
+
+	if (coord.column > pane.sh_column + pane.columns - 1) {
+		pane.sh_column = coord.column - pane.columns + 1;
+		pane.rflags |= REDRAW_TEXT;
+	}
+
+	pane.rflags |= (REDRAW_CARET | REDRAW_STATUS);
+}
+
+/** Change the caret position.
+ *
+ * Moves caret relatively to the current position. Looking at the first
+ * character cell after the caret and moving by @a drow and @a dcolumn, we get
+ * to a new character cell, and thus a new character. Then we either go to the
+ * point before the the character or after it, depending on @a align_dir.
+ */
+static void caret_move(int drow, int dcolumn, enum dir_spec align_dir)
+{
+	spt_t pt;
+	coord_t coord;
+	int num_rows;
+	bool pure_vertical;
+
+	tag_get_pt(&pane.caret_pos, &pt);
+	spt_get_coord(&pt, &coord);
+	coord.row += drow; coord.column += dcolumn;
+
+	/* Clamp coordinates. */
+	if (drow < 0 && coord.row < 1) coord.row = 1;
+	if (dcolumn < 0 && coord.column < 1) coord.column = 1;
+	if (drow > 0) {
+		sheet_get_num_rows(&doc.sh, &num_rows);
+		if (coord.row > num_rows) coord.row = num_rows;
+	}
+
+	/* For purely vertical movement try attaining @c ideal_column. */
+	pure_vertical = (dcolumn == 0 && align_dir == dir_before);
+	if (pure_vertical)
+		coord.column = pane.ideal_column;
+
+	/*
+	 * Select the point before or after the character at the designated
+	 * coordinates. The character can be wider than one cell (e.g. tab).
+	 */
+	sheet_get_cell_pt(&doc.sh, &coord, align_dir, &pt);
+	sheet_remove_tag(&doc.sh, &pane.caret_pos);
+	sheet_place_tag(&doc.sh, &pt, &pane.caret_pos);
+
+	/* For non-vertical movement set the new value for @c ideal_column. */
+	if (!pure_vertical) {
+		spt_get_coord(&pt, &coord);
+		pane.ideal_column = coord.column;
+	}
+
+	caret_update();
+}
+
+
+/** Get start-of-file s-point. */
+static void pt_get_sof(spt_t *pt)
+{
+	coord_t coord;
+
+	coord.row = coord.column = 1;
+	sheet_get_cell_pt(&doc.sh, &coord, dir_before, pt);
+}
+
+/** Get end-of-file s-point. */
+static void pt_get_eof(spt_t *pt)
+{
+	coord_t coord;
+	int num_rows;
+
+	sheet_get_num_rows(&doc.sh, &num_rows);
+	coord.row = num_rows + 1;
+	coord.column = 1;
+
+	sheet_get_cell_pt(&doc.sh, &coord, dir_after, pt);
+}
+
+/** Display text in the status line. */
+static void status_display(char const *str)
+{
+	console_goto(con, 0, scr_rows - 1);
+	console_set_color(con, COLOR_WHITE, COLOR_BLACK, 0);
+	printf(" %*s ", -(scr_columns - 3), str);
+	fflush(stdout);
+	console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);
+
+	pane.rflags |= REDRAW_CARET;
+}
+
+/** @}
+ */
Index: uspace/app/edit/sheet.c
===================================================================
--- uspace/app/edit/sheet.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/edit/sheet.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2009 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 edit
+ * @{
+ */
+/**
+ * @file
+ * @brief Prototype implementation of Sheet data structure.
+ *
+ * The sheet is an abstract data structure representing a piece of text.
+ * On top of this data structure we can implement a text editor. It is
+ * possible to implement the sheet such that the editor can make small
+ * changes to large files or files containing long lines efficiently.
+ *
+ * The sheet structure allows basic operations of text insertion, deletion,
+ * retrieval and mapping of coordinates to position in the file and vice
+ * versa. The text that is inserted or deleted can contain tabs and newlines
+ * which are interpreted and properly acted upon.
+ *
+ * This is a trivial implementation with poor efficiency with O(N+n)
+ * insertion and deletion and O(N) mapping (in both directions), where
+ * N is the size of the file and n is the size of the inserted/deleted text.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <adt/list.h>
+#include <align.h>
+#include <macros.h>
+
+#include "sheet.h"
+
+enum {
+	TAB_WIDTH	= 8,
+
+	/** Initial  of dat buffer in bytes */
+	INITIAL_SIZE	= 32
+};
+
+/** Initialize an empty sheet. */
+int sheet_init(sheet_t *sh)
+{
+	sh->dbuf_size = INITIAL_SIZE;
+	sh->text_size = 0;
+
+	sh->data = malloc(sh->dbuf_size);
+	if (sh->data == NULL)
+		return ENOMEM;
+
+	list_initialize(&sh->tags_head);
+
+	return EOK;
+}
+
+/** Insert text into sheet.
+ *
+ * @param sh	Sheet to insert to.
+ * @param pos	Point where to insert.
+ * @param dir	Whether to insert before or after the point (affects tags).
+ * @param str	The text to insert (printable characters, tabs, newlines).
+ *
+ * @return	EOK on success or negative error code.
+ *
+ * @note	@a dir affects which way tags that were placed on @a pos will
+ * 		move. If @a dir is @c dir_before, the tags will move forward
+ *		and vice versa.
+ */
+int sheet_insert(sheet_t *sh, spt_t *pos, enum dir_spec dir, char *str)
+{
+	char *ipp;
+	size_t sz;
+	link_t *link;
+	tag_t *tag;
+	char *newp;
+
+	sz = str_size(str);
+	if (sh->text_size + sz > sh->dbuf_size) {
+		/* Enlarge data buffer. */
+		newp = realloc(sh->data, sh->dbuf_size * 2);
+		if (newp == NULL)
+			return ELIMIT;
+
+		sh->data = newp;
+		sh->dbuf_size = sh->dbuf_size * 2;
+	}
+
+	ipp = sh->data + pos->b_off;
+
+	/* Copy data. */
+	memmove(ipp + sz, ipp, sh->text_size - pos->b_off);
+	memcpy(ipp, str, sz);
+	sh->text_size += sz;
+
+	/* Adjust tags. */
+
+	link = sh->tags_head.next;
+	while (link != &sh->tags_head) {
+		tag = list_get_instance(link, tag_t, link);
+
+		if (tag->b_off > pos->b_off)
+			tag->b_off += sz;
+		else if (tag->b_off == pos->b_off && dir == dir_before)
+			tag->b_off += sz;
+
+		link = link->next;
+	}
+
+	return EOK;
+}
+
+/** Delete text from sheet.
+ *
+ * Deletes the range of text between two points from the sheet.
+ *
+ * @param sh	Sheet to delete from.
+ * @param spos	Starting point.
+ * @param epos	Ending point.
+ *
+ * @return	EOK on success or negative error code.
+ **/
+int sheet_delete(sheet_t *sh, spt_t *spos, spt_t *epos)
+{
+	char *spp;
+	size_t sz;
+	link_t *link;
+	tag_t *tag;
+	char *newp;
+	size_t shrink_size;
+
+	spp = sh->data + spos->b_off;
+	sz = epos->b_off - spos->b_off;
+
+	memmove(spp, spp + sz, sh->text_size - (spos->b_off + sz));
+	sh->text_size -= sz;
+
+	/* Adjust tags. */
+	link = sh->tags_head.next;
+	while (link != &sh->tags_head) {
+		tag = list_get_instance(link, tag_t, link);
+
+		if (tag->b_off >= epos->b_off)
+			tag->b_off -= sz;
+		else if (tag->b_off >= spos->b_off)
+			tag->b_off = spos->b_off;
+
+		link = link->next;
+	}
+
+	/* See if we should free up some memory. */
+	shrink_size = max(sh->dbuf_size / 4, INITIAL_SIZE);
+	if (sh->text_size <= shrink_size && sh->dbuf_size > INITIAL_SIZE) {
+		/* Shrink data buffer. */
+		newp = realloc(sh->data, shrink_size);
+		if (newp == NULL) {
+			/* Failed to shrink buffer... no matter. */
+			return EOK;
+		}
+
+		sh->data = newp;
+		sh->dbuf_size = shrink_size;
+	}
+
+	return EOK;
+}
+
+/** Read text from sheet. */
+void sheet_copy_out(sheet_t *sh, spt_t const *spos, spt_t const *epos,
+    char *buf, size_t bufsize, spt_t *fpos)
+{
+	char *spp;
+	size_t range_sz;
+	size_t copy_sz;
+	size_t off, prev;
+	wchar_t c;
+
+	spp = sh->data + spos->b_off;
+	range_sz = epos->b_off - spos->b_off;
+	copy_sz = (range_sz < bufsize - 1) ? range_sz : bufsize - 1;
+
+	prev = off = 0;
+	do {
+		prev = off;
+		c = str_decode(spp, &off, copy_sz);
+	} while (c != '\0');
+
+	/* Crop copy_sz down to the last full character. */
+	copy_sz = prev;
+
+	memcpy(buf, spp, copy_sz);
+	buf[copy_sz] = '\0';
+
+	fpos->b_off = spos->b_off + copy_sz;
+	fpos->sh = sh;
+}
+
+/** Get point preceding or following character cell. */
+void sheet_get_cell_pt(sheet_t *sh, coord_t const *coord, enum dir_spec dir,
+    spt_t *pt)
+{
+	size_t cur_pos, prev_pos;
+	wchar_t c;
+	coord_t cc;
+
+	cc.row = cc.column = 1;
+	cur_pos = prev_pos = 0;
+	while (true) {
+		if (prev_pos >= sh->text_size) {
+			/* Cannot advance any further. */
+			break;
+		}
+
+		if ((cc.row >= coord->row && cc.column > coord->column) ||
+		    cc.row > coord->row) {
+			/* We are past the requested coordinates. */
+			break;
+		}
+
+		prev_pos = cur_pos;
+
+		c = str_decode(sh->data, &cur_pos, sh->text_size);
+		if (c == '\n') {
+			++cc.row;
+			cc.column = 1;
+		} else if (c == '\t') {
+			cc.column = 1 + ALIGN_UP(cc.column, TAB_WIDTH);
+		} else {
+			++cc.column;
+		}
+	}
+
+	pt->sh = sh;
+	pt->b_off = (dir == dir_before) ? prev_pos : cur_pos;
+}
+
+/** Get the number of character cells a row occupies. */
+void sheet_get_row_width(sheet_t *sh, int row, int *length)
+{
+	coord_t coord;
+	spt_t pt;
+
+	/* Especially nasty hack */
+	coord.row = row;
+	coord.column = 65536;
+	
+	sheet_get_cell_pt(sh, &coord, dir_before, &pt);
+	spt_get_coord(&pt, &coord);
+	*length = coord.column - 1;
+}
+
+/** Get the number of rows in a sheet. */
+void sheet_get_num_rows(sheet_t *sh, int *rows)
+{
+	int cnt;
+	size_t bo;
+
+	cnt = 1;
+	for (bo = 0; bo < sh->dbuf_size; ++bo) {
+		if (sh->data[bo] == '\n')
+			cnt += 1;
+	}
+
+	*rows = cnt;
+}
+
+/** Get the coordinates of an s-point. */
+void spt_get_coord(spt_t const *pos, coord_t *coord)
+{
+	size_t off;
+	coord_t cc;
+	wchar_t c;
+	sheet_t *sh;
+
+	sh = pos->sh;
+	cc.row = cc.column = 1;
+
+	off = 0;
+	while (off < pos->b_off && off < sh->text_size) {
+		c = str_decode(sh->data, &off, sh->text_size);
+		if (c == '\n') {
+			++cc.row;
+			cc.column = 1;
+		} else if (c == '\t') {
+			cc.column = 1 + ALIGN_UP(cc.column, TAB_WIDTH);
+		} else {
+			++cc.column;
+		}
+	}
+
+	*coord = cc;
+}
+
+/** Test if two s-points are equal. */
+bool spt_equal(spt_t const *a, spt_t const *b)
+{
+	return a->b_off == b->b_off;
+}
+
+/** Place a tag on the specified s-point. */
+void sheet_place_tag(sheet_t *sh, spt_t const *pt, tag_t *tag)
+{
+	tag->b_off = pt->b_off;
+	tag->sh = sh;
+	list_append(&tag->link, &sh->tags_head);
+}
+
+/** Remove a tag from the sheet. */
+void sheet_remove_tag(sheet_t *sh, tag_t *tag)
+{
+	list_remove(&tag->link);
+}
+
+/** Get s-point on which the tag is located right now. */
+void tag_get_pt(tag_t const *tag, spt_t *pt)
+{
+	pt->b_off = tag->b_off;
+	pt->sh = tag->sh;
+}
+
+/** @}
+ */
Index: uspace/app/edit/sheet.h
===================================================================
--- uspace/app/edit/sheet.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/edit/sheet.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2009 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 edit
+ * @{
+ */
+/**
+ * @file
+ */
+
+#ifndef SHEET_H__
+#define SHEET_H__
+
+#include <adt/list.h>
+#include <sys/types.h>
+#include <bool.h>
+
+/** Direction (in linear space) */
+enum dir_spec {
+	/** Before specified point */
+	dir_before,
+	/** After specified point */
+	dir_after
+};
+
+/** Sheet */
+typedef struct {
+	/* Note: This structure is opaque for the user. */
+
+	size_t text_size;
+	size_t dbuf_size;
+	char *data;
+
+	link_t tags_head;
+} sheet_t;
+
+/** Character cell coordinates
+ *
+ * These specify a character cell. The first cell is (1,1).
+ */
+typedef struct {
+	int row;
+	int column;
+} coord_t;
+
+/** S-point
+ *
+ * An s-point specifies the boundary between two successive characters
+ * in the linear file space (including the beginning of file or the end
+ * of file. An s-point only remains valid as long as no modifications
+ * (insertions/deletions) are performed on the sheet.
+ */
+typedef struct {
+	/* Note: This structure is opaque for the user. */
+	sheet_t *sh;
+	size_t b_off;
+} spt_t;
+
+/** Tag
+ *
+ * A tag is similar to an s-point, but remains valid over modifications
+ * to the sheet. A tag tends to 'stay put'. Any tag must be properly
+ * removed from the sheet before it is deallocated by the user.
+ */
+typedef struct {
+	/* Note: This structure is opaque for the user. */
+
+	/** Link to list of all tags in the sheet (see sheet_t.tags_head) */
+	link_t link;
+	sheet_t *sh;
+	size_t b_off;
+} tag_t;
+
+extern int sheet_init(sheet_t *);
+extern int sheet_insert(sheet_t *, spt_t *, enum dir_spec, char *);
+extern int sheet_delete(sheet_t *, spt_t *, spt_t *);
+extern void sheet_copy_out(sheet_t *, spt_t const *, spt_t const *, char *,
+    size_t, spt_t *);
+extern void sheet_get_cell_pt(sheet_t *, coord_t const *, enum dir_spec,
+    spt_t *);
+extern void sheet_get_row_width(sheet_t *, int, int *);
+extern void sheet_get_num_rows(sheet_t *, int *);
+extern void spt_get_coord(spt_t const *, coord_t *);
+extern bool spt_equal(spt_t const *, spt_t const *);
+
+extern void sheet_place_tag(sheet_t *, spt_t const *, tag_t *);
+extern void sheet_remove_tag(sheet_t *, tag_t *);
+extern void tag_get_pt(tag_t const *, spt_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/app/getvc/Makefile
===================================================================
--- uspace/app/getvc/Makefile	(revision 86554e71a1dd77b66b874136837c0b9cd1957907)
+++ uspace/app/getvc/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
-# Copyright (c) 2009 Martin Decky
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,53 +28,13 @@
 #
 
-include ../../../version
+include Makefile.common
 
-## Setup toolchain
-#
+.PHONY: all clean
 
-LIBC_PREFIX = ../../lib/libc
-SOFTINT_PREFIX = ../../lib/softint
-
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-LIBS = $(LIBC_PREFIX)/libc.a
-DEFS += -DRELEASE=$(RELEASE) "-DNAME=$(NAME)"
-
-## Sources
-#
-
-OUTPUT = getvc
-SOURCES = \
-	getvc.c \
-	version.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../version $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/app/getvc/Makefile.build
===================================================================
--- uspace/app/getvc/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/getvc/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,65 @@
+#
+# 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+include ../../../version
+
+DEFS += -DRELEASE=$(RELEASE) "-DNAME=$(NAME)"
+
+## Sources
+#
+
+SOURCES = \
+	getvc.c \
+	version.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/app/getvc/Makefile.common
===================================================================
--- uspace/app/getvc/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/getvc/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = getvc
Index: uspace/app/getvc/getvc.c
===================================================================
--- uspace/app/getvc/getvc.c	(revision 86554e71a1dd77b66b874136837c0b9cd1957907)
+++ uspace/app/getvc/getvc.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -36,4 +36,5 @@
 
 #include <sys/types.h>
+#include <fcntl.h>
 #include <unistd.h>
 #include <stdio.h>
@@ -46,23 +47,34 @@
 }
 
-static void closeall(void)
+static void reopen(FILE **stream, int fd, const char *path, int flags, const char *mode)
 {
-	fclose(stdin);
-	fclose(stdout);
-	fclose(stderr);
+	if (fclose(*stream))
+		return;
 	
-	close(0);
-	close(1);
-	close(2);
+	*stream = NULL;
+	
+	int oldfd = open(path, flags);
+	if (oldfd < 0)
+		return;
+	
+	if (oldfd != fd) {
+		if (dup2(oldfd, fd) != fd)
+			return;
+		
+		if (close(oldfd))
+			return;
+	}
+	
+	*stream = fdopen(fd, mode);
 }
 
 static task_id_t spawn(char *fname)
 {
-	char *argv[2];
+	char *args[2];
 	
-	argv[0] = fname;
-	argv[1] = NULL;
+	args[0] = fname;
+	args[1] = NULL;
 	
-	task_id_t id = task_spawn(fname, argv);
+	task_id_t id = task_spawn(fname, args);
 	
 	if (id == 0)
@@ -74,7 +86,4 @@
 int main(int argc, char *argv[])
 {
-	task_exit_t texit;
-	int retval;
-
 	if (argc < 3) {
 		usage();
@@ -82,26 +91,35 @@
 	}
 	
-	closeall();
+	reopen(&stdin, 0, argv[1], O_RDONLY, "r");
+	reopen(&stdout, 1, argv[1], O_WRONLY, "w");
+	reopen(&stderr, 2, argv[1], O_WRONLY, "w");
 	
-	stdin = fopen(argv[1], "r");
-	stdout = fopen(argv[1], "w");
-	stderr = fopen(argv[1], "w");
-
 	/*
-	 * FIXME: fopen() should actually detect that we are opening a console
+	 * FIXME: fdopen() should actually detect that we are opening a console
 	 * and it should set line-buffering mode automatically.
 	 */
 	setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
 	
-	if ((stdin == NULL)
-	    || (stdout == NULL)
-	    || (stderr == NULL))
+	if (stdin == NULL)
 		return -2;
+	
+	if (stdout == NULL)
+		return -3;
+	
+	if (stderr == NULL)
+		return -4;
 	
 	version_print(argv[1]);
 	task_id_t id = spawn(argv[2]);
-	task_wait(id, &texit, &retval);
 	
-	return 0;
+	if (id != 0) {
+		task_exit_t texit;
+		int retval;
+		task_wait(id, &texit, &retval);
+		
+		return 0;
+	}
+	
+	return -5;
 }
 
Index: uspace/app/init/Makefile
===================================================================
--- uspace/app/init/Makefile	(revision 86554e71a1dd77b66b874136837c0b9cd1957907)
+++ uspace/app/init/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
 # Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,50 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
-LIBC_PREFIX = ../../lib/libc
-SOFTINT_PREFIX = ../../lib/softint
+.PHONY: all clean
 
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-CFLAGS += -I../../..
-LIBS = $(LIBC_PREFIX)/libc.a
-
-## Sources
-#
-
-OUTPUT = init
-SOURCES = \
-	init.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/app/init/Makefile.build
===================================================================
--- uspace/app/init/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/init/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,61 @@
+#
+# 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	init.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/app/init/Makefile.common
===================================================================
--- uspace/app/init/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/init/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = init
Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision 86554e71a1dd77b66b874136837c0b9cd1957907)
+++ uspace/app/init/init.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -48,5 +48,4 @@
 #include <string.h>
 #include <devmap.h>
-#include <config.h>
 #include "init.h"
 
Index: uspace/app/klog/Makefile
===================================================================
--- uspace/app/klog/Makefile	(revision 86554e71a1dd77b66b874136837c0b9cd1957907)
+++ uspace/app/klog/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
 # Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,50 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
-LIBC_PREFIX = ../../lib/libc
-SOFTINT_PREFIX = ../../lib/softint
+.PHONY: all clean
 
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-LIBS = $(LIBC_PREFIX)/libc.a
-
-## Sources
-#
-
-OUTPUT = klog
-SOURCES = \
-	klog.c
-
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/app/klog/Makefile.build
===================================================================
--- uspace/app/klog/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/klog/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,61 @@
+#
+# 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	klog.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/app/klog/Makefile.common
===================================================================
--- uspace/app/klog/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/klog/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = klog
Index: uspace/app/klog/klog.c
===================================================================
--- uspace/app/klog/klog.c	(revision 86554e71a1dd77b66b874136837c0b9cd1957907)
+++ uspace/app/klog/klog.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -74,5 +74,5 @@
 	}
 	
-	int res = ipc_share_in_start_1_0(PHONE_NS, (void *) klog,
+	int res = async_share_in_start_1_0(PHONE_NS, (void *) klog,
 	    klog_size, SERVICE_MEM_KLOG);
 	if (res != EOK) {
Index: uspace/app/redir/Makefile
===================================================================
--- uspace/app/redir/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/redir/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,40 @@
+#
+# 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.
+#
+
+include Makefile.common
+
+.PHONY: all clean
+
+all: $(LIBC_PREFIX)/../../../version $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
+
+clean:
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/app/redir/Makefile.build
===================================================================
--- uspace/app/redir/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/redir/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,61 @@
+#
+# 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	redir.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/app/redir/Makefile.common
===================================================================
--- uspace/app/redir/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/redir/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = redir
Index: uspace/app/redir/redir.c
===================================================================
--- uspace/app/redir/redir.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/redir/redir.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2009 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 redir Redirector
+ * @brief Redirect stdin/stdout/stderr.
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <task.h>
+
+static void usage(void)
+{
+	printf("Usage: redir [-i <stdin>] [-o <stdout>] [-e <stderr>] -- <cmd> [args ...]\n");
+}
+
+static void reopen(FILE **stream, int fd, const char *path, int flags, const char *mode)
+{
+	if (fclose(*stream))
+		return;
+	
+	*stream = NULL;
+	
+	int oldfd = open(path, flags);
+	if (oldfd < 0)
+		return;
+	
+	if (oldfd != fd) {
+		if (dup2(oldfd, fd) != fd)
+			return;
+		
+		if (close(oldfd))
+			return;
+	}
+	
+	*stream = fdopen(fd, mode);
+}
+
+static task_id_t spawn(int argc, char *argv[])
+{
+	char **args = (char *) calloc(argc + 1, sizeof(char *));
+	if (!args) {
+		printf("No memory available\n");
+		return 0;
+	}
+	
+	int i;
+	for (i = 0; i < argc; i++)
+		args[i] = argv[i];
+	
+	args[argc] = NULL;
+	
+	task_id_t id = task_spawn(argv[0], args);
+	
+	free(args);
+	
+	if (id == 0)
+		printf("Error spawning %s\n", argv[0]);
+	
+	return id;
+}
+
+int main(int argc, char *argv[])
+{
+	if (argc < 3) {
+		usage();
+		return -1;
+	}
+	
+	int i;
+	for (i = 1; i < argc; i++) {
+		if (str_cmp(argv[i], "-i") == 0) {
+			i++;
+			if (i >= argc) {
+				usage();
+				return -2;
+			}
+			reopen(&stdin, 0, argv[i], O_RDONLY, "r");
+		} else if (str_cmp(argv[i], "-o") == 0) {
+			i++;
+			if (i >= argc) {
+				usage();
+				return -3;
+			}
+			reopen(&stdout, 1, argv[i], O_WRONLY | O_CREAT, "w");
+		} else if (str_cmp(argv[i], "-e") == 0) {
+			i++;
+			if (i >= argc) {
+				usage();
+				return -4;
+			}
+			reopen(&stderr, 2, argv[i], O_WRONLY | O_CREAT, "w");
+		} else if (str_cmp(argv[i], "--") == 0) {
+			i++;
+			break;
+		}
+	}
+	
+	if (i >= argc) {
+		usage();
+		return -5;
+	}
+	
+	/*
+	 * FIXME: fdopen() should actually detect that we are opening a console
+	 * and it should set line-buffering mode automatically.
+	 */
+	setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
+	
+	task_id_t id = spawn(argc - i, argv + i);
+	
+	if (id != 0) {
+		task_exit_t texit;
+		int retval;
+		task_wait(id, &texit, &retval);
+		
+		return retval;
+	}
+	
+	return -6;
+}
+
+/** @}
+ */
Index: uspace/app/tester/Makefile
===================================================================
--- uspace/app/tester/Makefile	(revision 86554e71a1dd77b66b874136837c0b9cd1957907)
+++ uspace/app/tester/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
 # Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,66 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
-LIBC_PREFIX = ../../lib/libc
-SOFTINT_PREFIX = ../../lib/softint
+.PHONY: all clean
 
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-CFLAGS += -I../../srv/kbd/include
-
-LIBS = $(LIBC_PREFIX)/libc.a
-
-## Sources
-#
-
-OUTPUT = tester
-SOURCES = tester.c \
-	thread/thread1.c \
-	print/print1.c \
-	print/print2.c \
-	print/print3.c \
-	print/print4.c \
-	console/console1.c \
-	stdio/stdio1.c \
-	stdio/stdio2.c \
-	fault/fault1.c \
-	fault/fault2.c \
-	vfs/vfs1.c \
-	ipc/ping_pong.c \
-	ipc/register.c \
-	ipc/connect.c \
-	loop/loop1.c \
-	mm/malloc1.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/app/tester/Makefile.build
===================================================================
--- uspace/app/tester/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/tester/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,77 @@
+#
+# 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	tester.c \
+	thread/thread1.c \
+	print/print1.c \
+	print/print2.c \
+	print/print3.c \
+	print/print4.c \
+	console/console1.c \
+	stdio/stdio1.c \
+	stdio/stdio2.c \
+	fault/fault1.c \
+	fault/fault2.c \
+	vfs/vfs1.c \
+	ipc/ping_pong.c \
+	ipc/register.c \
+	ipc/connect.c \
+	loop/loop1.c \
+	mm/malloc1.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/app/tester/Makefile.common
===================================================================
--- uspace/app/tester/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/tester/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = tester
Index: uspace/app/tetris/Makefile
===================================================================
--- uspace/app/tetris/Makefile	(revision 86554e71a1dd77b66b874136837c0b9cd1957907)
+++ uspace/app/tetris/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,39 +1,40 @@
-LIBC_PREFIX = ../../lib/libc
-SOFTINT_PREFIX = ../../lib/softint
+#
+# 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.
+#
 
-include $(LIBC_PREFIX)/Makefile.toolchain
+include Makefile.common
 
-LIBS = $(LIBC_PREFIX)/libc.a
+.PHONY: all clean
 
-OUTPUT = tetris
-SOURCES = shapes.c scores.c input.c tetris.c screen.c
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include Makefile.depend
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend *.o
-
-disasm: $(OUTPUT).disasm
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/app/tetris/Makefile.build
===================================================================
--- uspace/app/tetris/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/tetris/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,65 @@
+#
+# 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	shapes.c \
+	scores.c \
+	input.c \
+	tetris.c \
+	screen.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/app/tetris/Makefile.common
===================================================================
--- uspace/app/tetris/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/tetris/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = tetris
Index: uspace/app/tetris/screen.h
===================================================================
--- uspace/app/tetris/screen.h	(revision 86554e71a1dd77b66b874136837c0b9cd1957907)
+++ uspace/app/tetris/screen.h	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -51,6 +51,6 @@
 
 typedef struct {
-	ipcarg_t ws_row;
-	ipcarg_t ws_col;
+	int ws_row;
+	int ws_col;
 } winsize_t;
 
Index: uspace/app/trace/Makefile
===================================================================
--- uspace/app/trace/Makefile	(revision 86554e71a1dd77b66b874136837c0b9cd1957907)
+++ uspace/app/trace/Makefile	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -1,4 +1,5 @@
 #
 # Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
 # All rights reserved.
 #
@@ -27,53 +28,13 @@
 #
 
-## Setup toolchain
-#
+include Makefile.common
 
-LIBC_PREFIX = ../../lib/libc
-SOFTINT_PREFIX = ../../lib/softint
+.PHONY: all clean
 
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-CFLAGS += -I../../srv/kbd/include
-
-LIBS = $(LIBC_PREFIX)/libc.a
-
-## Sources
-#
-
-OUTPUT = trace
-SOURCES = trace.c \
-	syscalls.c \
-	ipcp.c \
-	ipc_desc.c \
-	proto.c \
-	errors.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all clean depend disasm
-
-all: $(OUTPUT) disasm
-
--include Makefile.depend
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build
 
 clean:
-	-rm -f $(OUTPUT) $(OBJECTS) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend
-
-depend:
-	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-disasm:
-	$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm
-
-%.o: %.S
-	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
-
-%.o: %.s
-	$(AS) $(AFLAGS) $< -o $@
-
-%.o: %.c
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+	rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/app/trace/Makefile.build
===================================================================
--- uspace/app/trace/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/trace/Makefile.build	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,66 @@
+#
+# 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+## Sources
+#
+
+SOURCES = \
+	trace.c \
+	syscalls.c \
+	ipcp.c \
+	ipc_desc.c \
+	proto.c \
+	errors.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/app/trace/Makefile.common
===================================================================
--- uspace/app/trace/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
+++ uspace/app/trace/Makefile.common	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBS = $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = trace
Index: uspace/app/trace/syscalls.c
===================================================================
--- uspace/app/trace/syscalls.c	(revision 86554e71a1dd77b66b874136837c0b9cd1957907)
+++ uspace/app/trace/syscalls.c	(revision 1787e527c803ec9bf678df8b19b0de9e18985f12)
@@ -62,4 +62,5 @@
     [SYS_IPC_FORWARD_SLOW] = { "ipc_forward_slow",	3,	V_ERRNO },
     [SYS_IPC_WAIT] = { "ipc_wait_for_call",		3,	V_HASH },
+    [SYS_IPC_POKE] = { "ipc_poke",			0,	V_ERRNO },
     [SYS_IPC_HANGUP] = { "ipc_hangup",			1,	V_ERRNO },
     [SYS_IPC_REGISTER_IRQ] = { "ipc_register_irq",	4,	V_ERRNO },
