Index: uspace/app/untar/main.c
===================================================================
--- uspace/app/untar/main.c	(revision 1433ecda9b732f3f185f902feb26826ec2496e03)
+++ uspace/app/untar/main.c	(revision 95faa4dec13caf69ef6b5a19e578aecba68ea63a)
@@ -34,87 +34,43 @@
 
 #include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <str_error.h>
-#include <vfs/vfs.h>
-#include "tar.h"
+#include <stdarg.h>
+#include <untar.h>
 
-static size_t get_block_count(size_t bytes)
+const char *filename;
+
+static int tar_open(tar_file_t *tar)
 {
-	return (bytes + TAR_BLOCK_SIZE - 1) / TAR_BLOCK_SIZE;
-}
+	FILE *file = fopen(filename, "rb");
+	if (file == NULL)
+		return errno;
 
-static errno_t skip_blocks(FILE *tarfile, size_t valid_data_size)
-{
-	size_t blocks_to_read = get_block_count(valid_data_size);
-	while (blocks_to_read > 0) {
-		uint8_t block[TAR_BLOCK_SIZE];
-		size_t actually_read = fread(block, TAR_BLOCK_SIZE, 1, tarfile);
-		if (actually_read != 1) {
-			return errno;
-		}
-		blocks_to_read--;
-	}
+	tar->data = (void *) file;
 	return EOK;
 }
 
-static errno_t handle_normal_file(const tar_header_t *header, FILE *tarfile)
+static void tar_close(tar_file_t *tar)
 {
-	// FIXME: create the directory first
-
-	FILE *file = fopen(header->filename, "wb");
-	if (file == NULL) {
-		fprintf(stderr, "Failed to create %s: %s.\n", header->filename,
-		    str_error(errno));
-		return errno;
-	}
-
-	errno_t rc = EOK;
-	size_t bytes_remaining = header->size;
-	size_t blocks = get_block_count(bytes_remaining);
-	while (blocks > 0) {
-		uint8_t block[TAR_BLOCK_SIZE];
-		size_t actually_read = fread(block, 1, TAR_BLOCK_SIZE, tarfile);
-		if (actually_read != TAR_BLOCK_SIZE) {
-			rc = errno;
-			fprintf(stderr, "Failed to read block for %s: %s.\n",
-			    header->filename, str_error(rc));
-			break;
-		}
-		size_t to_write = TAR_BLOCK_SIZE;
-		if (bytes_remaining < TAR_BLOCK_SIZE) {
-			to_write = bytes_remaining;
-		}
-		size_t actually_written = fwrite(block, 1, to_write, file);
-		if (actually_written != to_write) {
-			rc = errno;
-			fprintf(stderr, "Failed to write to %s: %s.\n",
-			    header->filename, str_error(rc));
-			break;
-		}
-		blocks--;
-		bytes_remaining -= TAR_BLOCK_SIZE;
-	}
-
+	FILE *file = (FILE *) tar->data;
 	fclose(file);
-
-	return rc;
 }
 
-static errno_t handle_directory(const tar_header_t *header, FILE *tarfile)
+static size_t tar_read(tar_file_t *tar, void *data, size_t size)
 {
-	errno_t rc;
+	FILE *file = (FILE *) tar->data;
+	return fread(data, 1, size, file);
+}
 
-	rc = vfs_link_path(header->filename, KIND_DIRECTORY, NULL);
-	if (rc != EOK) {
-		if (rc != EEXIST) {
-			fprintf(stderr, "Failed to create directory %s: %s.\n",
-			    header->filename, str_error(rc));
-			return rc;
-		}
-	}
+static void tar_vreport(tar_file_t *tar, const char *fmt, va_list args)
+{
+	vfprintf(stderr, fmt, args);
+}
 
-	return skip_blocks(tarfile, header->size);
-}
+tar_file_t tar = {
+	.open = tar_open,
+	.close = tar_close,
+
+	.read = tar_read,
+	.vreport = tar_vreport
+};
 
 int main(int argc, char *argv[])
@@ -125,52 +81,6 @@
 	}
 
-	const char *filename = argv[1];
-
-	FILE *tarfile = fopen(filename, "rb");
-	if (tarfile == NULL) {
-		fprintf(stderr, "Failed to open `%s': %s.\n", filename, str_error(errno));
-		return 2;
-	}
-
-	while (true) {
-		size_t header_ok;
-		tar_header_raw_t header_raw;
-		tar_header_t header;
-		header_ok = fread(&header_raw, sizeof(header_raw), 1, tarfile);
-		if (header_ok != 1) {
-			break;
-		}
-		errno_t rc = tar_header_parse(&header, &header_raw);
-		if (rc == EEMPTY) {
-			continue;
-		}
-		if (rc != EOK) {
-			fprintf(stderr, "Failed parsing TAR header: %s.\n", str_error(rc));
-			break;
-		}
-
-		//printf(" ==> %s (%zuB, type %s)\n", header.filename,
-		//    header.size, tar_type_str(header.type));
-
-		switch (header.type) {
-		case TAR_TYPE_DIRECTORY:
-			rc = handle_directory(&header, tarfile);
-			break;
-		case TAR_TYPE_NORMAL:
-			rc = handle_normal_file(&header, tarfile);
-			break;
-		default:
-			rc = skip_blocks(tarfile, header.size);
-			break;
-		}
-		if (rc != EOK) {
-			break;
-		}
-
-	}
-
-	fclose(tarfile);
-
-	return 0;
+	filename = argv[1];
+	return untar(&tar);
 }
 
