From 06423cab58569ef01eb526e5f0d2f5c0c8917aa0 Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Tue, 23 Nov 2021 20:13:52 +0000 Subject: x1000-installer: Initial commit of new framework This is a new flash installer framework for the X1000 targets. A bunch of this code is *UNTESTED* but there is an external test harness which allows the library to be built and tested on a PC. Once tests are written and the bugs are ironed out this framework will replace the existing installer code. New features: - Update tarballs are MD5-checksummed to guarantee integrity. - The flash map is no longer fixed -- updates are self describing and carry a map file which specifies the areas to update. - Can take full or partial backups with checksums computed on the fly. - Supports an additional verification mode which reads back data after writing to ensure the flash contents were not silently corrupted. Change-Id: I29a89190c7ff566019f6a844ad0571f01fb7192f --- lib/x1000-installer/test_lib/pathfuncs.c | 130 +++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 lib/x1000-installer/test_lib/pathfuncs.c (limited to 'lib/x1000-installer/test_lib/pathfuncs.c') diff --git a/lib/x1000-installer/test_lib/pathfuncs.c b/lib/x1000-installer/test_lib/pathfuncs.c new file mode 100644 index 0000000000..341efd4730 --- /dev/null +++ b/lib/x1000-installer/test_lib/pathfuncs.c @@ -0,0 +1,130 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2014 by Michael Sevakis + * + * 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 "pathfuncs.h" +#include "strlcpy.h" +#include "system.h" +#include + +static const char* GOBBLE_PATH_SEPCH(const char* p) +{ + int c; + while((c = *p) == PATH_SEPCH) + ++p; + return p; +} + +static const char* GOBBLE_PATH_COMP(const char* p) +{ + int c; + while((c = *p) && c != PATH_SEPCH) + ++p; + return p; +} + +/* Strips the trailing component from the path + * "" *nameptr->NUL, len=0: "" + * "/" *nameptr->/, len=1: "/" + * "//" *nameptr->2nd /, len=1: "/" + * "/a" *nameptr->/, len=1: "/" + * "a/" *nameptr->a, len=0: "" + * "/a/bc" *nameptr->/, len=2: "/a" + * "d" *nameptr->d, len=0: "" + * "ef/gh" *nameptr->e, len=2: "ef" + * + * Notes: * Interpret len=0 as ".". + * * In the same string, path_dirname() returns a pointer with the + * same or lower address as path_basename(). + * * Pasting a separator between the returns of path_dirname() and + * path_basename() will result in a path equivalent to the input. + * + */ +size_t path_dirname(const char *name, const char **nameptr) +{ + const char *p = GOBBLE_PATH_SEPCH(name); + const char *q = name; + const char *r = p; + + while (*(p = GOBBLE_PATH_COMP(p))) + { + const char *s = p; + + if (!*(p = GOBBLE_PATH_SEPCH(p))) + break; + + q = s; + } + + if (q == name && r > name) + name = r, q = name--; /* root - return last slash */ + + *nameptr = name; + return q - name; +} + +/* Appends one path to another, adding separators between components if needed. + * Return value and behavior is otherwise as strlcpy so that truncation may be + * detected. + * + * For basepath and component: + * PA_SEP_HARD adds a separator even if the base path is empty + * PA_SEP_SOFT adds a separator only if the base path is not empty + */ +size_t path_append(char *buf, const char *basepath, + const char *component, size_t bufsize) +{ + const char *base = basepath && basepath[0] ? basepath : buf; + if (!base) + return bufsize; /* won't work to get lengths from buf */ + + if (!buf) + bufsize = 0; + + if (path_is_absolute(component)) + { + /* 'component' is absolute; replace all */ + basepath = component; + component = ""; + } + + /* if basepath is not null or empty, buffer contents are replaced, + otherwise buf contains the base path */ + size_t len = base == buf ? strlen(buf) : my_strlcpy(buf, basepath, bufsize); + + bool separate = false; + + if (!basepath || !component) + separate = !len || base[len-1] != PATH_SEPCH; + else if (component[0]) + separate = len && base[len-1] != PATH_SEPCH; + + /* caller might lie about size of buf yet use buf as the base */ + if (base == buf && bufsize && len >= bufsize) + buf[bufsize - 1] = '\0'; + + buf += len; + bufsize -= MIN(len, bufsize); + + if (separate && (len++, bufsize > 0) && --bufsize > 0) + *buf++ = PATH_SEPCH; + + return len + my_strlcpy(buf, component ?: "", bufsize); +} -- cgit v1.2.3