1d4afb5ceSopenharmony_ci/* 2d4afb5ceSopenharmony_ci * Copyright (C) 2017 National Institute of Advanced Industrial Science 3d4afb5ceSopenharmony_ci * and Technology (AIST) 4d4afb5ceSopenharmony_ci * 5d4afb5ceSopenharmony_ci * All rights reserved. 6d4afb5ceSopenharmony_ci * 7d4afb5ceSopenharmony_ci * Redistribution and use in source and binary forms, with or without 8d4afb5ceSopenharmony_ci * modification, are permitted provided that the following conditions are met: 9d4afb5ceSopenharmony_ci * 10d4afb5ceSopenharmony_ci * Redistributions of source code must retain the above copyright notice, this 11d4afb5ceSopenharmony_ci * list of conditions and the following disclaimer. 12d4afb5ceSopenharmony_ci * 13d4afb5ceSopenharmony_ci * Redistributions in binary form must reproduce the above copyright notice, 14d4afb5ceSopenharmony_ci * this list of conditions and the following disclaimer in the documentation 15d4afb5ceSopenharmony_ci * and/or other materials provided with the distribution. 16d4afb5ceSopenharmony_ci * 17d4afb5ceSopenharmony_ci * Neither the name of AIST nor the names of its contributors may be used 18d4afb5ceSopenharmony_ci * to endorse or promote products derived from this software without specific 19d4afb5ceSopenharmony_ci * prior written permission. 20d4afb5ceSopenharmony_ci * 21d4afb5ceSopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22d4afb5ceSopenharmony_ci * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23d4afb5ceSopenharmony_ci * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24d4afb5ceSopenharmony_ci * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25d4afb5ceSopenharmony_ci * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26d4afb5ceSopenharmony_ci * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27d4afb5ceSopenharmony_ci * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28d4afb5ceSopenharmony_ci * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29d4afb5ceSopenharmony_ci * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30d4afb5ceSopenharmony_ci * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31d4afb5ceSopenharmony_ci * POSSIBILITY OF SUCH DAMAGE. 32d4afb5ceSopenharmony_ci */ 33d4afb5ceSopenharmony_ci 34d4afb5ceSopenharmony_ci#include <libwebsockets.h> 35d4afb5ceSopenharmony_ci#include <string.h> 36d4afb5ceSopenharmony_ci#include <stdint.h> 37d4afb5ceSopenharmony_ci#include <stdio.h> 38d4afb5ceSopenharmony_ci#include "romfs.h" 39d4afb5ceSopenharmony_ci#if defined(LWS_WITH_ESP32) 40d4afb5ceSopenharmony_ci#include "esp_spi_flash.h" 41d4afb5ceSopenharmony_ci#endif 42d4afb5ceSopenharmony_ci 43d4afb5ceSopenharmony_ci#define RFS_STRING_MAX 96 44d4afb5ceSopenharmony_ci 45d4afb5ceSopenharmony_cistatic u32_be_t cache[(RFS_STRING_MAX + 32) / 4]; 46d4afb5ceSopenharmony_cistatic romfs_inode_t ci = (romfs_inode_t)cache; 47d4afb5ceSopenharmony_cistatic romfs_t cr = (romfs_t)cache; 48d4afb5ceSopenharmony_ci 49d4afb5ceSopenharmony_cistatic void 50d4afb5ceSopenharmony_ciset_cache(romfs_inode_t inode, size_t len) 51d4afb5ceSopenharmony_ci{ 52d4afb5ceSopenharmony_ci#if defined(LWS_WITH_ESP32) 53d4afb5ceSopenharmony_ci spi_flash_read((uint32_t)inode, cache, len); 54d4afb5ceSopenharmony_ci#endif 55d4afb5ceSopenharmony_ci} 56d4afb5ceSopenharmony_ci 57d4afb5ceSopenharmony_cistatic uint32_t 58d4afb5ceSopenharmony_ciuntohl(const u32_be_t be) 59d4afb5ceSopenharmony_ci{ 60d4afb5ceSopenharmony_ci return ((be >> 24) & 0xff) | 61d4afb5ceSopenharmony_ci ((be >> 16) & 0xff) << 8 | 62d4afb5ceSopenharmony_ci ((be >> 8) & 0xff) << 16 | 63d4afb5ceSopenharmony_ci (be & 0xff) << 24; 64d4afb5ceSopenharmony_ci} 65d4afb5ceSopenharmony_cistatic romfs_inode_t 66d4afb5ceSopenharmony_ciromfs_lookup(romfs_t romfs, romfs_inode_t start, const char *path); 67d4afb5ceSopenharmony_ci 68d4afb5ceSopenharmony_cistatic int 69d4afb5ceSopenharmony_ciplus_padding(const uint8_t *s) 70d4afb5ceSopenharmony_ci{ 71d4afb5ceSopenharmony_ci int n; 72d4afb5ceSopenharmony_ci 73d4afb5ceSopenharmony_ci set_cache((romfs_inode_t)s, RFS_STRING_MAX); 74d4afb5ceSopenharmony_ci n = strlen((const char *)cache); 75d4afb5ceSopenharmony_ci 76d4afb5ceSopenharmony_ci if (!(n & 15)) 77d4afb5ceSopenharmony_ci n += 0x10; 78d4afb5ceSopenharmony_ci 79d4afb5ceSopenharmony_ci return (n + 15) & ~15; 80d4afb5ceSopenharmony_ci} 81d4afb5ceSopenharmony_ci 82d4afb5ceSopenharmony_cistatic romfs_inode_t 83d4afb5ceSopenharmony_ciskip_and_pad(romfs_inode_t ri) 84d4afb5ceSopenharmony_ci{ 85d4afb5ceSopenharmony_ci const uint8_t *p = ((const uint8_t *)ri) + sizeof(*ri); 86d4afb5ceSopenharmony_ci 87d4afb5ceSopenharmony_ci return (romfs_inode_t)(p + plus_padding(p)); 88d4afb5ceSopenharmony_ci} 89d4afb5ceSopenharmony_ci 90d4afb5ceSopenharmony_cisize_t 91d4afb5ceSopenharmony_ciromfs_mount_check(romfs_t romfs) 92d4afb5ceSopenharmony_ci{ 93d4afb5ceSopenharmony_ci set_cache((romfs_inode_t)romfs, sizeof(*romfs)); 94d4afb5ceSopenharmony_ci 95d4afb5ceSopenharmony_ci if (cr->magic1 != 0x6d6f722d || 96d4afb5ceSopenharmony_ci cr->magic2 != 0x2d736631) 97d4afb5ceSopenharmony_ci return 0; 98d4afb5ceSopenharmony_ci 99d4afb5ceSopenharmony_ci return untohl(cr->size); 100d4afb5ceSopenharmony_ci} 101d4afb5ceSopenharmony_ci 102d4afb5ceSopenharmony_cistatic romfs_inode_t 103d4afb5ceSopenharmony_ciromfs_symlink(romfs_t romfs, romfs_inode_t level, romfs_inode_t i) 104d4afb5ceSopenharmony_ci{ 105d4afb5ceSopenharmony_ci const char *p = (const char *)skip_and_pad(i); 106d4afb5ceSopenharmony_ci 107d4afb5ceSopenharmony_ci if (*p == '/') { 108d4afb5ceSopenharmony_ci level = skip_and_pad((romfs_inode_t)romfs); 109d4afb5ceSopenharmony_ci p++; 110d4afb5ceSopenharmony_ci } 111d4afb5ceSopenharmony_ci 112d4afb5ceSopenharmony_ci return romfs_lookup(romfs, level, p); 113d4afb5ceSopenharmony_ci} 114d4afb5ceSopenharmony_ci 115d4afb5ceSopenharmony_cistatic romfs_inode_t 116d4afb5ceSopenharmony_cidir_link(romfs_t romfs, romfs_inode_t i) 117d4afb5ceSopenharmony_ci{ 118d4afb5ceSopenharmony_ci set_cache(i, sizeof(*i)); 119d4afb5ceSopenharmony_ci return (romfs_inode_t)((const uint8_t *)romfs + 120d4afb5ceSopenharmony_ci untohl(ci->dir_start)); 121d4afb5ceSopenharmony_ci} 122d4afb5ceSopenharmony_ci 123d4afb5ceSopenharmony_cistatic romfs_inode_t 124d4afb5ceSopenharmony_ciromfs_lookup(romfs_t romfs, romfs_inode_t start, const char *path) 125d4afb5ceSopenharmony_ci{ 126d4afb5ceSopenharmony_ci romfs_inode_t level, i = start, i_in; 127d4afb5ceSopenharmony_ci const char *p, *cp; 128d4afb5ceSopenharmony_ci uint32_t next_be; 129d4afb5ceSopenharmony_ci 130d4afb5ceSopenharmony_ci if (start == (romfs_inode_t)romfs) 131d4afb5ceSopenharmony_ci i = skip_and_pad((romfs_inode_t)romfs); 132d4afb5ceSopenharmony_ci level = i; 133d4afb5ceSopenharmony_ci while (i != (romfs_inode_t)romfs) { 134d4afb5ceSopenharmony_ci const char *n = ((const char *)i) + sizeof(*i); 135d4afb5ceSopenharmony_ci 136d4afb5ceSopenharmony_ci p = path; 137d4afb5ceSopenharmony_ci i_in = i; 138d4afb5ceSopenharmony_ci 139d4afb5ceSopenharmony_ci set_cache(i, sizeof(*i)); 140d4afb5ceSopenharmony_ci next_be = ci->next; 141d4afb5ceSopenharmony_ci 142d4afb5ceSopenharmony_ci cp = (const char *)cache; 143d4afb5ceSopenharmony_ci set_cache((romfs_inode_t)n, RFS_STRING_MAX); 144d4afb5ceSopenharmony_ci 145d4afb5ceSopenharmony_ci while (*p && *p != '/' && *cp && *p == *cp && 146d4afb5ceSopenharmony_ci (p - path) < RFS_STRING_MAX) { 147d4afb5ceSopenharmony_ci p++; 148d4afb5ceSopenharmony_ci n++; 149d4afb5ceSopenharmony_ci cp++; 150d4afb5ceSopenharmony_ci } 151d4afb5ceSopenharmony_ci 152d4afb5ceSopenharmony_ci while (*p == '/' && p[1] == '/') 153d4afb5ceSopenharmony_ci p++; 154d4afb5ceSopenharmony_ci 155d4afb5ceSopenharmony_ci if (!*cp && (!*p || *p == '/') && 156d4afb5ceSopenharmony_ci (untohl(next_be) & 7) == RFST_HARDLINK) { 157d4afb5ceSopenharmony_ci set_cache(i, sizeof(*i)); 158d4afb5ceSopenharmony_ci return (romfs_inode_t) 159d4afb5ceSopenharmony_ci ((const uint8_t *)romfs + 160d4afb5ceSopenharmony_ci (untohl(ci->dir_start) & ~15)); 161d4afb5ceSopenharmony_ci } 162d4afb5ceSopenharmony_ci 163d4afb5ceSopenharmony_ci if (!*p && !*cp) { 164d4afb5ceSopenharmony_ci set_cache(i, sizeof(*i)); 165d4afb5ceSopenharmony_ci if ((untohl(ci->next) & 7) == RFST_SYMLINK) { 166d4afb5ceSopenharmony_ci i = romfs_symlink(romfs, level, i); 167d4afb5ceSopenharmony_ci continue; 168d4afb5ceSopenharmony_ci } 169d4afb5ceSopenharmony_ci return i; 170d4afb5ceSopenharmony_ci } 171d4afb5ceSopenharmony_ci 172d4afb5ceSopenharmony_ci if (!*p && *cp == '/') 173d4afb5ceSopenharmony_ci return NULL; 174d4afb5ceSopenharmony_ci 175d4afb5ceSopenharmony_ci while (*p == '/' && p[1] == '/') 176d4afb5ceSopenharmony_ci p++; 177d4afb5ceSopenharmony_ci 178d4afb5ceSopenharmony_ci if (*p == '/' && !*cp) { 179d4afb5ceSopenharmony_ci set_cache(i, sizeof(*i)); 180d4afb5ceSopenharmony_ci switch (untohl(ci->next) & 7) { 181d4afb5ceSopenharmony_ci case RFST_SYMLINK: 182d4afb5ceSopenharmony_ci i = romfs_symlink(romfs, level, i); 183d4afb5ceSopenharmony_ci if (!i) 184d4afb5ceSopenharmony_ci return NULL; 185d4afb5ceSopenharmony_ci i = dir_link(romfs, i); 186d4afb5ceSopenharmony_ci while (*path != '/' && *path) 187d4afb5ceSopenharmony_ci path++; 188d4afb5ceSopenharmony_ci if (!*path) 189d4afb5ceSopenharmony_ci return NULL; 190d4afb5ceSopenharmony_ci path++; 191d4afb5ceSopenharmony_ci continue; 192d4afb5ceSopenharmony_ci case RFST_DIR: 193d4afb5ceSopenharmony_ci path = p + 1; 194d4afb5ceSopenharmony_ci i = dir_link(romfs, i); 195d4afb5ceSopenharmony_ci break; 196d4afb5ceSopenharmony_ci default: 197d4afb5ceSopenharmony_ci path = p + 1; 198d4afb5ceSopenharmony_ci i = skip_and_pad(i); 199d4afb5ceSopenharmony_ci break; 200d4afb5ceSopenharmony_ci } 201d4afb5ceSopenharmony_ci level = i; 202d4afb5ceSopenharmony_ci continue; 203d4afb5ceSopenharmony_ci } 204d4afb5ceSopenharmony_ci 205d4afb5ceSopenharmony_ci set_cache(i, sizeof(*i)); 206d4afb5ceSopenharmony_ci if (!(untohl(ci->next) & ~15)) 207d4afb5ceSopenharmony_ci return NULL; 208d4afb5ceSopenharmony_ci 209d4afb5ceSopenharmony_ci i = (romfs_inode_t)((const uint8_t *)romfs + 210d4afb5ceSopenharmony_ci (untohl(ci->next) & ~15)); 211d4afb5ceSopenharmony_ci if (i == i_in) 212d4afb5ceSopenharmony_ci return NULL; 213d4afb5ceSopenharmony_ci } 214d4afb5ceSopenharmony_ci 215d4afb5ceSopenharmony_ci return NULL; 216d4afb5ceSopenharmony_ci} 217d4afb5ceSopenharmony_ci 218d4afb5ceSopenharmony_ciconst void * 219d4afb5ceSopenharmony_ciromfs_get_info(romfs_t romfs, const char *path, size_t *len, size_t *csum) 220d4afb5ceSopenharmony_ci{ 221d4afb5ceSopenharmony_ci romfs_inode_t i; 222d4afb5ceSopenharmony_ci 223d4afb5ceSopenharmony_ci if (*path == '/') 224d4afb5ceSopenharmony_ci path++; 225d4afb5ceSopenharmony_ci 226d4afb5ceSopenharmony_ci i = romfs_lookup(romfs, (romfs_inode_t)romfs, path); 227d4afb5ceSopenharmony_ci 228d4afb5ceSopenharmony_ci if (!i) 229d4afb5ceSopenharmony_ci return NULL; 230d4afb5ceSopenharmony_ci 231d4afb5ceSopenharmony_ci set_cache(i, sizeof(*i)); 232d4afb5ceSopenharmony_ci *len = untohl(ci->size); 233d4afb5ceSopenharmony_ci if (csum) 234d4afb5ceSopenharmony_ci *csum = untohl(ci->checksum); 235d4afb5ceSopenharmony_ci 236d4afb5ceSopenharmony_ci return (void *)skip_and_pad(i); 237d4afb5ceSopenharmony_ci} 238