diff mbox

[7/7] tools: add copy functionality

Message ID 1469600360-19292-8-git-send-email-aik@ozlabs.ru
State Accepted
Headers show

Commit Message

Alexey Kardashevskiy July 27, 2016, 6:19 a.m. UTC
From: Adrian Reber <adrian@lisas.de>

sloffs can now copy a SLOF flash image from one file to
another. This is especially useful when the input is not
a regular file, but the slof_flash device. The -c, --copy
parameter copies only the actual SLOF flash image instead
of the whole device. This should result in a file, which
is identical to the file from the SLOF build process.

(cherry picked from commit 587eb035ac1fb17c3b8ab236bb06e793f08bb3ea)

Cherry picked from https://lisas.de/~adrian/slof/slof.git/

Signed-off-by: Adrian Reber <adrian@lisas.de>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
 tools/sloffs.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 63 insertions(+), 1 deletion(-)
diff mbox

Patch

diff --git a/tools/sloffs.c b/tools/sloffs.c
index 4d998bb..91a23c3 100644
--- a/tools/sloffs.c
+++ b/tools/sloffs.c
@@ -580,6 +580,57 @@  sloffs_list(const int fd)
 }
 
 static void
+sloffs_copy(const int file, const char *name)
+{
+	uint64_t len;
+	int out;
+	unsigned char *write_buf;
+	int i;
+	struct stH *header;
+
+	header = sloffs_header(file);
+
+	if (!header)
+		return;
+
+	len = be64_to_cpu(header->flashlen);
+	free(header);
+
+	out = open(name, O_CREAT | O_RDWR | O_TRUNC, 00666);
+
+	if (out == -1) {
+		perror(name);
+		exit(1);
+	}
+	/* write byte at the end to be able to mmap it */
+	lseek(out, len - 1, SEEK_SET);
+	write(out, "", 1);
+	write_buf = mmap(NULL, len, PROT_WRITE, MAP_SHARED, out, 0);
+
+	if (write_buf == MAP_FAILED) {
+		perror("mmap");
+		exit(1);
+	}
+
+	lseek(file, 0, SEEK_SET);
+
+	for (;;) {
+		i = read(file, write_buf, len);
+		if (i < 0) {
+			perror("read");
+			exit(1);
+		}
+		if (i == 0)
+			break;
+		write_buf += i;
+		len -= i;
+	}
+
+	munmap(write_buf, len);
+	close(out);
+}
+
+static void
 usage(void)
 {
 	printf("sloffs lists or changes a SLOF flash image\n\n");
@@ -595,6 +646,9 @@  usage(void)
 	printf("  -o, --output=FILENAME  if appending a file this parameter\n");
 	printf("                         is necessary to specify the name of\n");
 	printf("                         the output file\n");
+	printf("  -c, --copy=FILENAME    copy SLOF image to specified file\n");
+	printf("                         this is especially useful if the\n");
+	printf("                         source file is /dev/slof_flash\n");
 	printf("\n");
 	exit(1);
 }
@@ -610,9 +664,10 @@  main(int argc, char *argv[])
 		{ "dump", 0, NULL, 'd' },
 		{ "append", 1, NULL, 'a' },
 		{ "output", 1, NULL, 'o' },
+		{ "copy", 1, NULL, 'o' },
 		{ 0, 0, 0, 0 }
 	};
-	const char *soption = "dhlva:o:";
+	const char *soption = "dhlva:o:c:";
 	int c;
 	char mode = 0;
 	char *append = NULL;
@@ -639,6 +694,10 @@  main(int argc, char *argv[])
 		case 'o':
 			output = strdup(optarg);
 			break;
+		case 'c':
+			mode = 'c';
+			output = strdup(optarg);
+			break;
 		case 'h':
 		default:
 			usage();
@@ -672,6 +731,9 @@  main(int argc, char *argv[])
 		}
 		sloffs_append(fd, append, output);
 		break;
+	case 'c':
+		sloffs_copy(fd, output);
+		break;
 	}
 
 	free(append);