summaryrefslogtreecommitdiffstats
path: root/lib/x1000-installer/src/xf_package.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/x1000-installer/src/xf_package.c')
-rw-r--r--lib/x1000-installer/src/xf_package.c261
1 files changed, 0 insertions, 261 deletions
diff --git a/lib/x1000-installer/src/xf_package.c b/lib/x1000-installer/src/xf_package.c
deleted file mode 100644
index fb107aef72..0000000000
--- a/lib/x1000-installer/src/xf_package.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Copyright (C) 2021 Aidan MacDonald
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-
-#include "xf_package.h"
-#include "xf_error.h"
-#include "pathfuncs.h"
-#include "file.h"
-#include "core_alloc.h"
-#include "md5.h"
-#include "system.h"
-#include <stdbool.h>
-#include <string.h>
-
-#ifdef ROCKBOX
-# include "microtar-rockbox.h"
-#else
-# include "microtar-stdio.h"
-#endif
-
-#define METADATA_SIZE 4096 /* size of the metadata buffer */
-#define MAX_MAP_SIZE 32 /* maximum number of map entries */
-
-static int pkg_alloc(struct xf_package* pkg)
-{
- memset(pkg, 0, sizeof(*pkg));
-
- /* calculate allocation size */
- size_t alloc_size = 0;
- alloc_size += ALIGN_UP_P2(sizeof(mtar_t), 3);
- alloc_size += ALIGN_UP_P2(sizeof(struct xf_map) * MAX_MAP_SIZE, 3);
- alloc_size += ALIGN_UP_P2(METADATA_SIZE, 3);
- alloc_size += 7; /* for alignment */
-
- pkg->alloc_handle = core_alloc_ex("xf_package", alloc_size, &buflib_ops_locked);
- if(pkg->alloc_handle < 0)
- return XF_E_OUT_OF_MEMORY;
-
- /* distribute memory */
- uint8_t* buf = (uint8_t*)core_get_data(pkg->alloc_handle);
- memset(buf, 0, alloc_size);
- ALIGN_BUFFER(buf, alloc_size, 8);
-
- pkg->tar = (mtar_t*)buf;
- buf += ALIGN_UP_P2(sizeof(mtar_t), 3);
-
- pkg->map = (struct xf_map*)buf;
- buf += ALIGN_UP_P2(sizeof(struct xf_map) * MAX_MAP_SIZE, 3);
-
- pkg->metadata = (char*)buf;
- buf += ALIGN_UP_P2(METADATA_SIZE, 3);
-
- return XF_E_SUCCESS;
-}
-
-static int read_meta_line_cb(int n, char* buf, void* arg)
-{
- struct xf_package* pkg = (struct xf_package*)arg;
- size_t length = strlen(buf);
-
- /* skip blank lines and the first line (it's reserved for old format) */
- if(n == 0 || length == 0)
- return 0;
-
- /* metadata lines require an '=' sign to separate key and value */
- if(!strchr(buf, '='))
- return XF_E_SYNTAX_ERROR;
-
- /* we need space to copy the key-value pair plus a null terminator */
- if(length + 1 >= METADATA_SIZE - pkg->metadata_len)
- return XF_E_BUF_OVERFLOW;
-
- memcpy(&pkg->metadata[pkg->metadata_len], buf, length + 1);
- pkg->metadata_len += length + 1;
- return 0;
-}
-
-static int pkg_read_meta(struct xf_package* pkg)
-{
- struct xf_stream stream;
- int rc = xf_open_tar(pkg->tar, "bootloader-info.txt", &stream);
- if(rc)
- return XF_E_CANNOT_OPEN_FILE;
-
- char buf[200];
- rc = xf_stream_read_lines(&stream, buf, sizeof(buf), read_meta_line_cb, pkg);
- xf_stream_close(&stream);
- return rc;
-}
-
-static int pkg_read_map(struct xf_package* pkg,
- const struct xf_map* dflt_map, int dflt_map_size)
-{
- /* Attempt to load and parse the map file */
- struct xf_stream stream;
- int rc = xf_open_tar(pkg->tar, "flashmap.txt", &stream);
-
- /* If the flash map is absent but a default map has been provided,
- * then the update is in the old fixed format. */
- if(rc == MTAR_ENOTFOUND && dflt_map) {
- if(dflt_map_size > MAX_MAP_SIZE)
- return XF_E_INVALID_PARAMETER;
-
- for(int i = 0; i < dflt_map_size; ++i) {
- pkg->map[i] = dflt_map[i];
- pkg->map[i].flags &= ~(XF_MAP_HAS_MD5 | XF_MAP_HAS_FILE_LENGTH);
- }
-
- pkg->map_size = dflt_map_size;
- return XF_E_SUCCESS;
- }
-
- if(rc != MTAR_ESUCCESS)
- return XF_E_CANNOT_OPEN_FILE;
-
- rc = xf_map_parse(&stream, pkg->map, MAX_MAP_SIZE);
- if(rc < 0)
- goto err;
-
- /* Sort the map; reject it if there is any overlap. */
- pkg->map_size = rc;
- if(xf_map_sort(pkg->map, pkg->map_size)) {
- rc = XF_E_INVALID_PARAMETER;
- goto err;
- }
-
- /* All packages in the 'new' format are required to have MD5 sums. */
- for(int i = 0; i < pkg->map_size; ++i) {
- if(!(pkg->map[i].flags & XF_MAP_HAS_MD5) ||
- !(pkg->map[i].flags & XF_MAP_HAS_FILE_LENGTH)) {
- rc = XF_E_VERIFY_FAILED;
- goto err;
- }
- }
-
- rc = XF_E_SUCCESS;
-
- err:
- xf_stream_close(&stream);
- return rc;
-}
-
-static int pkg_verify(struct xf_package* pkg)
-{
- struct xf_stream stream;
- md5_context ctx;
- uint8_t buffer[128];
-
- for(int i = 0; i < pkg->map_size; ++i) {
- /* At a bare minimum, check that the file exists. */
- int rc = xf_open_tar(pkg->tar, pkg->map[i].name, &stream);
- if(rc)
- return XF_E_VERIFY_FAILED;
-
- /* Also check that it isn't bigger than the update region.
- * That would normally indicate a problem. */
- off_t streamsize = xf_stream_get_size(&stream);
- if(streamsize > (off_t)pkg->map[i].length) {
- rc = XF_E_VERIFY_FAILED;
- goto err;
- }
-
- /* Check against the listed file length. */
- if(pkg->map[i].flags & XF_MAP_HAS_FILE_LENGTH) {
- if(streamsize != (off_t)pkg->map[i].file_length) {
- rc = XF_E_VERIFY_FAILED;
- goto err;
- }
- }
-
- /* Check the MD5 sum if we have it. */
- if(pkg->map[i].flags & XF_MAP_HAS_MD5) {
- md5_starts(&ctx);
- while(1) {
- ssize_t n = xf_stream_read(&stream, buffer, sizeof(buffer));
- if(n < 0) {
- rc = XF_E_IO;
- goto err;
- }
-
- md5_update(&ctx, buffer, n);
- if((size_t)n < sizeof(buffer))
- break;
- }
-
- md5_finish(&ctx, buffer);
- if(memcpy(buffer, pkg->map[i].md5, 16)) {
- rc = XF_E_VERIFY_FAILED;
- goto err;
- }
- }
-
- err:
- xf_stream_close(&stream);
- if(rc)
- return rc;
- }
-
- /* All files passed verification */
- return XF_E_SUCCESS;
-}
-
-int xf_package_open_ex(struct xf_package* pkg, const char* file,
- const struct xf_map* dflt_map, int dflt_map_size)
-{
- int rc = pkg_alloc(pkg);
- if(rc)
- return rc;
-
-#ifdef ROCKBOX
- rc = mtar_open(pkg->tar, file, O_RDONLY);
-#else
- rc = mtar_open(pkg->tar, file, "r");
-#endif
- if(rc != MTAR_ESUCCESS) {
- rc = XF_E_CANNOT_OPEN_FILE;
- goto err;
- }
-
- rc = pkg_read_meta(pkg);
- if(rc)
- goto err;
-
- rc = pkg_read_map(pkg, dflt_map, dflt_map_size);
- if(rc)
- goto err;
-
- rc = pkg_verify(pkg);
- if(rc)
- goto err;
-
- err:
- if(rc)
- xf_package_close(pkg);
- return rc;
-}
-
-void xf_package_close(struct xf_package* pkg)
-{
- if(mtar_is_open(pkg->tar))
- mtar_close(pkg->tar);
-
- pkg->alloc_handle = core_free(pkg->alloc_handle);
-}