--- tarout.c.ORIG	2004-10-14 23:07:58.000000000 +0300
+++ tarout.c	2014-09-03 12:45:50.900264517 +0300
@@ -3,6 +3,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
 
 int tarout_init(struct tar_stream *t, int fd)
 {
@@ -43,11 +44,48 @@
 int tarout_octal(struct tar_stream *t, unsigned long long o, int digits, int size)
 {
 	char mask[32], data[64];
+
+	if (o >= ((unsigned long long)1 << (3 * digits))) {
+		fprintf(stderr, "tarout_octal: too large number: %llo\n", o);
+		abort();
+	}
 	sprintf(mask, "%%%dllo ", digits);
 	return tarout_nullpad(t, data,
 			sprintf(data, mask, (unsigned long long)o), size);
 }
 
+int tarout_base256(struct tar_stream *t, unsigned long long val, int size)
+{
+	unsigned char data[16];
+	unsigned char *ptr = data;
+
+	if (size > 16) {
+		fprintf(stderr, "tarout_base256: too large size, %d\n", size);
+		abort();
+	}
+
+	while (size > 0) {
+		*ptr++ = (unsigned char) val;
+		val >>= 8;
+		size--;
+	}
+
+	*(ptr-1) |= 0x80;	/* mark as base256 coded in octal field */
+
+	while (ptr > data) {
+		if (!tarout_addch(t, *(--ptr))) return 0;
+	}
+
+	return 1;
+}
+
+int tarout_octal256(struct tar_stream *t, unsigned long long val, int digits, int size)
+{
+	if (val >= ((unsigned long long)1 << (3 * digits)))
+		return tarout_base256(t, val, size);
+	return tarout_octal(t, val, digits, size);
+}
+
 int tarout_heading(struct tar_stream *t, int type,
 		const char *filename, int mode, int uid, int gid,
 		unsigned long long size, time_t mtime,
@@ -128,7 +166,7 @@
 	if (!tarout_octal(t, (unsigned long long)mode, 6, 8)) return 0;
 	if (!tarout_octal(t, (unsigned long long)uid, 6, 8)) return 0;
 	if (!tarout_octal(t, (unsigned long long)gid, 6, 8)) return 0;
-	if (!tarout_octal(t, (unsigned long long)size, 11, 12)) return 0;
+	if (!tarout_octal256(t, (unsigned long long)size, 11, 12)) return 0;
 	if (!tarout_octal(t, (unsigned long long)mtime, 11, 12)) return 0;
 	if (!tarout_nullpad(t, "        ", 8, 8)) return 0; /* checksum */
 	if (!tarout_addch(t, type)) return 0;
