blob: 61a82d6f414dc083d5cf10d3bf0cb9c7911e5e8e [file] [log] [blame]
Andrew Scull18834872018-10-12 11:48:09 +01001/*
Andrew Walbran692b3252019-03-07 15:51:31 +00002 * Copyright 2018 The Hafnium Authors.
Andrew Scull18834872018-10-12 11:48:09 +01003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andrew Scull18c78fc2018-08-20 12:57:41 +010017#include "hf/cpio.h"
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010018
19#include <stdint.h>
20
Andrew Scull8d9e1212019-04-05 13:52:55 +010021#include "hf/std.h"
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010022
23#pragma pack(push, 1)
24struct cpio_header {
25 uint16_t magic;
26 uint16_t dev;
27 uint16_t ino;
28 uint16_t mode;
29 uint16_t uid;
30 uint16_t gid;
31 uint16_t nlink;
32 uint16_t rdev;
33 uint16_t mtime[2];
34 uint16_t namesize;
35 uint16_t filesize[2];
36};
37#pragma pack(pop)
38
Wedson Almeida Filho9ee60e92018-07-23 18:56:56 +010039/**
40 * Retrieves the next file stored in the cpio archive stored in the cpio, and
41 * advances the iterator such that another call to this function would return
42 * the following file.
43 */
44bool cpio_next(struct memiter *iter, const char **name, const void **contents,
Andrew Scull4f170f52018-07-19 12:58:20 +010045 size_t *size)
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010046{
Wedson Almeida Filho9ee60e92018-07-23 18:56:56 +010047 size_t len;
48 struct memiter lit = *iter;
49 const struct cpio_header *h = (const struct cpio_header *)lit.next;
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010050
Wedson Almeida Filho9ee60e92018-07-23 18:56:56 +010051 if (!memiter_advance(&lit, sizeof(struct cpio_header))) {
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010052 return false;
Andrew Scull7364a8e2018-07-19 15:39:29 +010053 }
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010054
Wedson Almeida Filho9ee60e92018-07-23 18:56:56 +010055 *name = lit.next;
56
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010057 /* TODO: Check magic. */
58
Wedson Almeida Filho9ee60e92018-07-23 18:56:56 +010059 len = (h->namesize + 1) & ~1;
60 if (!memiter_advance(&lit, len)) {
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010061 return false;
Andrew Scull7364a8e2018-07-19 15:39:29 +010062 }
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010063
Wedson Almeida Filho9ee60e92018-07-23 18:56:56 +010064 *contents = lit.next;
65
66 len = (size_t)h->filesize[0] << 16 | h->filesize[1];
67 if (!memiter_advance(&lit, (len + 1) & ~1)) {
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010068 return false;
Andrew Scull7364a8e2018-07-19 15:39:29 +010069 }
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010070
71 /* TODO: Check that string is null-terminated. */
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010072
73 /* Stop enumerating files when we hit the end marker. */
Wedson Almeida Filho9ee60e92018-07-23 18:56:56 +010074 if (!strcmp(*name, "TRAILER!!!")) {
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010075 return false;
Andrew Scull7364a8e2018-07-19 15:39:29 +010076 }
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010077
Wedson Almeida Filho9ee60e92018-07-23 18:56:56 +010078 *size = len;
79 *iter = lit;
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010080
81 return true;
82}