summaryrefslogtreecommitdiff
path: root/tools/omar/omar.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/omar/omar.c')
-rw-r--r--tools/omar/omar.c41
1 files changed, 32 insertions, 9 deletions
diff --git a/tools/omar/omar.c b/tools/omar/omar.c
index 129303e..a4c7ad6 100644
--- a/tools/omar/omar.c
+++ b/tools/omar/omar.c
@@ -53,6 +53,9 @@
#define OMAR_ARCHIVE 0
#define OMAR_EXTRACT 1
+/* Revision */
+#define OMAR_REV 2
+
#define ALIGN_UP(value, align) (((value) + (align)-1) & ~((align)-1))
#define BLOCK_SIZE 512
@@ -68,12 +71,16 @@ static const char *outpath = NULL;
* @magic: Header magic ("OMAR")
* @len: Length of the file
* @namelen: Length of the filename
+ * @rev: OMAR revision
+ * @mode: File permissions
*/
struct omar_hdr {
char magic[4];
uint8_t type;
uint8_t namelen;
uint32_t len;
+ uint8_t rev;
+ uint32_t mode;
} __attribute__((packed));
static inline void
@@ -112,7 +119,7 @@ strip_root(const char *path)
* Recursive mkdir
*/
static void
-mkpath(const char *path)
+mkpath(struct omar_hdr *hdr, const char *path)
{
size_t len;
char buf[256];
@@ -126,12 +133,12 @@ mkpath(const char *path)
for (p = (char *)buf + 1; *p != '\0'; ++p) {
if (*p == '/') {
*p = '\0';
- mkdir(buf, 0700);
+ mkdir(buf, hdr->mode);
*p = '/';
}
}
- mkdir(buf, 0700);
+ mkdir(buf, hdr->mode);
}
/*
@@ -166,9 +173,11 @@ file_push(const char *pathname, const char *name)
if (S_ISDIR(sb.st_mode)) {
hdr.type = OMAR_DIR;
}
+ hdr.mode = sb.st_mode;
}
hdr.len = (pathname == NULL) ? 0 : sb.st_size;
+ hdr.rev = OMAR_REV;
hdr.namelen = strlen(name);
/*
@@ -282,16 +291,17 @@ archive_create(const char *base, const char *dirname)
/*
* Extract a single file
*
+ * @hp: File header
* @data: Data to extract
* @len: Length of data
* @path: Path to output file
*/
static int
-extract_single(char *data, size_t len, const char *path)
+extract_single(struct omar_hdr *hp, char *data, size_t len, const char *path)
{
int fd;
- if ((fd = open(path, O_WRONLY | O_CREAT, 0700)) < 0) {
+ if ((fd = open(path, O_WRONLY | O_CREAT, hp->mode)) < 0) {
return fd;
}
@@ -312,8 +322,10 @@ archive_extract(void)
struct stat sb;
struct omar_hdr *hdr;
int fd, error;
+ size_t len;
off_t off;
char namebuf[256];
+ char pathbuf[256];
if ((fd = open(inpath, O_RDONLY)) < 0) {
perror("open");
@@ -351,20 +363,31 @@ archive_extract(void)
fprintf(stderr, "bad magic\n");
break;
}
+ if (hdr->rev != OMAR_REV) {
+ fprintf(stderr, "cannot extract rev %d archive\n", hdr->rev);
+ fprintf(stderr, "current OMAR revision: %d\n", OMAR_REV);
+ }
name = (char *)hdr + sizeof(struct omar_hdr);
memcpy(namebuf, name, hdr->namelen);
namebuf[hdr->namelen] = '\0';
- printf("unpacking %s\n", namebuf);
+
+ /* Get the full path */
+ len = snprintf(pathbuf, sizeof(pathbuf), "%s/%s", outpath, namebuf);
+ if (len < 0) {
+ free(buf);
+ return len;
+ }
+ printf("unpacking %s\n", pathbuf);
if (hdr->type == OMAR_DIR) {
off = 512;
- mkpath(namebuf);
+ mkpath(hdr, pathbuf);
} else {
- off = ALIGN_UP(sizeof(hdr) + hdr->namelen + hdr->len, BLOCK_SIZE);
+ off = ALIGN_UP(sizeof(*hdr) + hdr->namelen + hdr->len, BLOCK_SIZE);
p = (char *)hdr + sizeof(struct omar_hdr);
p += hdr->namelen;
- extract_single(p, hdr->len, namebuf);
+ extract_single(hdr, p, hdr->len, pathbuf);
}
hdr = (struct omar_hdr *)((char *)hdr + off);