Add a zero-fill command to lar. 

Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>

Index: util/lar/stream.c
Add hlen (header len) and maxsize (max size left in lar) functions. 

Index: util/lar/lib.h
Add function prototypes and new ZEROFILL enum.

Index: util/lar/lar.c
Add -z option and command support

Index: util/lar/lar.c
===================================================================
--- util/lar/lar.c	(revision 581)
+++ util/lar/lar.c	(working copy)
@@ -182,6 +182,39 @@
 	return 0;
 }
 
+int zerofill_lar(const char *archivename)
+{
+	struct lar_header *header;
+	int ret, hlen;
+	int pathlen;
+	u32 *walk,  csum;
+	u32 offset;
+	char *name = "zerofill";
+	int zerolen;
+	char *zero;
+
+	struct lar *lar = lar_open_archive(archivename);
+
+	if (lar == NULL) {
+		fprintf(stderr, "Unable to open LAR archive %s\n", archivename);
+		exit(1);
+	}
+
+	zerolen = maxsize(lar, name);
+	if (zerolen <= 0) {
+		fprintf(stderr, "No room for zerofill.\n");
+		return -1;
+	}
+
+	zero = malloc(zerolen);
+	memset(zero, 0xff, zerolen);
+
+	lar_add_entry(lar, name, zero, zerolen, zerolen,0, 0, 0);
+
+	lar_close_archive(lar);
+	return 0;
+}
+
 int extract_lar(const char *archivename, struct file *files)
 {
 	int ret;
@@ -218,6 +251,7 @@
 		{"elfparse", 1, 0, 'e'},
 		{"verbose", 0, 0, 'v'},
 		{"version", 0, 0, 'V'},
+		{"zerofill", 0, 0, 'z'},
 		{"help", 0, 0, 'h'},
 		{0, 0, 0, 0}
 	};
@@ -227,7 +261,7 @@
 		exit(1);
 	}
 
-	while ((opt = getopt_long(argc, argv, "acC:xels:b:vVh?",
+	while ((opt = getopt_long(argc, argv, "acC:xzels:b:vVh?",
 				  long_options, &option_index)) != EOF) {
 		switch (opt) {
 		case 'a':
@@ -253,6 +287,9 @@
 		case 'x':
 			larmode = EXTRACT;
 			break;
+		case 'z':
+			larmode = ZEROFILL;
+			break;
 		case 's':
 			parse_larsize(optarg);
 			break;
@@ -287,6 +324,8 @@
 			larmode = CREATE;
 		else if (strncmp(argv[optind], "l", 2) == 0)
 			larmode = LIST;
+		else if (strncmp(argv[optind], "z", 2) == 0)
+			larmode = ZEROFILL;
 
 		/* If larmode changed in this if branch,
 		 * eat a parameter
@@ -324,7 +363,7 @@
 
 	if (optind < argc) {
 		archivename = argv[optind++];
-	} else {
+	} else if (larmode != ZEROFILL) {
 
 		usage(argv[0]);
 		fprintf(stderr, "Error: No archive name.\n\n");
@@ -356,6 +395,9 @@
 	case LIST:
 		list_lar(archivename, get_files());
 		break;
+	case ZEROFILL:
+		zerofill_lar(archivename);
+		break;
 	}
 
 	free_files();
Index: util/lar/lib.h
===================================================================
--- util/lar/lib.h	(revision 581)
+++ util/lar/lib.h	(working copy)
@@ -33,7 +33,8 @@
 	ADD,
 	CREATE,
 	LIST,
-	EXTRACT
+	EXTRACT,
+	ZEROFILL,
 } larmodes;
 
 /* prototypes for lar.c functions */
@@ -58,6 +59,8 @@
 int lar_process_name(char *name, char **pfilename, char **ppathname, 
 		enum compalgo *thisalgo);
 u32 lar_compress(char *ptr, ssize_t size, char *temp, enum compalgo *thisalgo);
+int hlen(char *name);
+int maxsize(struct lar *lar, char *name);
 int lar_add_entry(struct lar *lar, char *pathname, void *data, 
 	u32 complen, u32 reallen, u32 loadaddress, u32 entry, 
 	enum compalgo thisalgo);
Index: util/lar/stream.c
===================================================================
--- util/lar/stream.c	(revision 581)
+++ util/lar/stream.c	(working copy)
@@ -784,6 +784,45 @@
 }
 
 /**
+ * Given a name, return the size of the header for that name.  
+ * 
+ * @param name header name
+ * @return  header size
+ */
+int hlen(char *pathname)
+{
+	int pathlen;
+	int len;
+
+	pathlen = strlen(pathname) + 1 > MAX_PATHLEN ? 
+		MAX_PATHLEN : strlen(pathname) + 1;
+	len = sizeof(struct lar_header) + pathlen;
+	len = (len + 15) & 0xFFFFFFF0;
+
+	return len;
+}
+
+/**
+ * Return the amount of space left in a lar, given a name for the entry
+ * @param Name of the entry
+ * @return Maximum possible size for the entry
+ */
+int maxsize(struct lar *lar, char *name)
+{
+	int size;
+	u32 offset;
+	int bootblock_size;
+
+	/* Find the beginning of the available space in the LAR */
+	offset = lar_empty_offset(lar);
+
+	/* Figure out how big our header will be */
+	size = get_bootblock_offset(lar->size) - offset - hlen(name) - 1;
+
+	return size;
+}
+
+/**
  * Compress an area according to an algorithm. If the area grows, 
  * use no compression. 
  * @param ptr data to be compressed
