diff options
Diffstat (limited to 'jslinux-2019-12-21/tinyemu-2019-12-21/fs_utils.c')
| -rw-r--r-- | jslinux-2019-12-21/tinyemu-2019-12-21/fs_utils.c | 370 |
1 files changed, 370 insertions, 0 deletions
diff --git a/jslinux-2019-12-21/tinyemu-2019-12-21/fs_utils.c b/jslinux-2019-12-21/tinyemu-2019-12-21/fs_utils.c new file mode 100644 index 0000000..37f399d --- /dev/null +++ b/jslinux-2019-12-21/tinyemu-2019-12-21/fs_utils.c @@ -0,0 +1,370 @@ +/* + * Misc FS utilities + * + * Copyright (c) 2016-2017 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <inttypes.h> +#include <assert.h> +#include <fcntl.h> +#include <errno.h> +#include <unistd.h> +#include <time.h> +#include <ctype.h> +#include <sys/file.h> + +#include "cutils.h" +#include "list.h" +#include "fs_utils.h" + +/* last byte is the version */ +const uint8_t encrypted_file_magic[4] = { 0xfb, 0xa2, 0xe9, 0x01 }; + +char *compose_path(const char *path, const char *name) +{ + int path_len, name_len; + char *d, *q; + + if (path[0] == '\0') { + d = strdup(name); + } else { + path_len = strlen(path); + name_len = strlen(name); + d = malloc(path_len + 1 + name_len + 1); + q = d; + memcpy(q, path, path_len); + q += path_len; + if (path[path_len - 1] != '/') + *q++ = '/'; + memcpy(q, name, name_len + 1); + } + return d; +} + +char *compose_url(const char *base_url, const char *name) +{ + if (strchr(name, ':')) { + return strdup(name); + } else { + return compose_path(base_url, name); + } +} + +void skip_line(const char **pp) +{ + const char *p; + p = *pp; + while (*p != '\n' && *p != '\0') + p++; + if (*p == '\n') + p++; + *pp = p; +} + +char *quoted_str(const char *str) +{ + const char *s; + char *q; + int c; + char *buf; + + if (str[0] == '\0') + goto use_quote; + s = str; + while (*s != '\0') { + if (*s <= ' ' || *s > '~') + goto use_quote; + s++; + } + return strdup(str); + use_quote: + buf = malloc(strlen(str) * 4 + 2 + 1); + q = buf; + s = str; + *q++ = '"'; + while (*s != '\0') { + c = *(uint8_t *)s; + if (c < ' ' || c == 127) { + q += sprintf(q, "\\x%02x", c); + } else if (c == '\\' || c == '\"') { + q += sprintf(q, "\\%c", c); + } else { + *q++ = c; + } + s++; + } + *q++ = '"'; + *q = '\0'; + return buf; +} + +int parse_fname(char *buf, int buf_size, const char **pp) +{ + const char *p; + char *q; + int c, h; + + p = *pp; + while (isspace_nolf(*p)) + p++; + if (*p == '\0') + return -1; + q = buf; + if (*p == '"') { + p++; + for(;;) { + c = *p++; + if (c == '\0' || c == '\n') { + return -1; + } else if (c == '\"') { + break; + } else if (c == '\\') { + c = *p++; + switch(c) { + case '\'': + case '\"': + case '\\': + goto add_char; + case 'n': + c = '\n'; + goto add_char; + case 'r': + c = '\r'; + goto add_char; + case 't': + c = '\t'; + goto add_char; + case 'x': + h = from_hex(*p++); + if (h < 0) + return -1; + c = h << 4; + h = from_hex(*p++); + if (h < 0) + return -1; + c |= h; + goto add_char; + default: + return -1; + } + } else { + add_char: + if (q >= buf + buf_size - 1) + return -1; + *q++ = c; + } + } + } else { + while (!isspace_nolf(*p) && *p != '\0' && *p != '\n') { + if (q >= buf + buf_size - 1) + return -1; + *q++ = *p++; + } + } + *q = '\0'; + *pp = p; + return 0; +} + +int parse_uint32_base(uint32_t *pval, const char **pp, int base) +{ + const char *p, *p1; + p = *pp; + while (isspace_nolf(*p)) + p++; + *pval = strtoul(p, (char **)&p1, base); + if (p1 == p) + return -1; + *pp = p1; + return 0; +} + +int parse_uint64_base(uint64_t *pval, const char **pp, int base) +{ + const char *p, *p1; + p = *pp; + while (isspace_nolf(*p)) + p++; + *pval = strtoull(p, (char **)&p1, base); + if (p1 == p) + return -1; + *pp = p1; + return 0; +} + +int parse_uint64(uint64_t *pval, const char **pp) +{ + return parse_uint64_base(pval, pp, 0); +} + +int parse_uint32(uint32_t *pval, const char **pp) +{ + return parse_uint32_base(pval, pp, 0); +} + +int parse_time(uint32_t *psec, uint32_t *pnsec, const char **pp) +{ + const char *p; + uint32_t v, m; + p = *pp; + if (parse_uint32(psec, &p) < 0) + return -1; + v = 0; + if (*p == '.') { + p++; + /* XXX: inefficient */ + m = 1000000000; + v = 0; + while (*p >= '0' && *p <= '9') { + m /= 10; + v += (*p - '0') * m; + p++; + } + } + *pnsec = v; + *pp = p; + return 0; +} + +int parse_file_id(FSFileID *pval, const char **pp) +{ + return parse_uint64_base(pval, pp, 16); +} + +char *file_id_to_filename(char *buf, FSFileID file_id) +{ + sprintf(buf, "%016" PRIx64, file_id); + return buf; +} + +void encode_hex(char *str, const uint8_t *buf, int len) +{ + int i; + for(i = 0; i < len; i++) + sprintf(str + 2 * i, "%02x", buf[i]); +} + +int decode_hex(uint8_t *buf, const char *str, int len) +{ + int h0, h1, i; + + for(i = 0; i < len; i++) { + h0 = from_hex(str[2 * i]); + if (h0 < 0) + return -1; + h1 = from_hex(str[2 * i + 1]); + if (h1 < 0) + return -1; + buf[i] = (h0 << 4) | h1; + } + return 0; +} + +/* return NULL if no end of header found */ +const char *skip_header(const char *p) +{ + p = strstr(p, "\n\n"); + if (!p) + return NULL; + return p + 2; +} + +/* return 0 if OK, < 0 if error */ +int parse_tag(char *buf, int buf_size, const char *str, const char *tag) +{ + char tagname[128], *q; + const char *p, *p1; + int len; + + p = str; + for(;;) { + if (*p == '\0' || *p == '\n') + break; + q = tagname; + while (*p != ':' && *p != '\n' && *p != '\0') { + if ((q - tagname) < sizeof(tagname) - 1) + *q++ = *p; + p++; + } + *q = '\0'; + if (*p != ':') + return -1; + p++; + while (isspace_nolf(*p)) + p++; + p1 = p; + p = strchr(p, '\n'); + if (!p) + len = strlen(p1); + else + len = p - p1; + if (!strcmp(tagname, tag)) { + if (len > buf_size - 1) + len = buf_size - 1; + memcpy(buf, p1, len); + buf[len] = '\0'; + return 0; + } + if (!p) + break; + else + p++; + } + return -1; +} + +int parse_tag_uint64(uint64_t *pval, const char *str, const char *tag) +{ + char buf[64]; + const char *p; + if (parse_tag(buf, sizeof(buf), str, tag)) + return -1; + p = buf; + return parse_uint64(pval, &p); +} + +int parse_tag_file_id(FSFileID *pval, const char *str, const char *tag) +{ + char buf[64]; + const char *p; + if (parse_tag(buf, sizeof(buf), str, tag)) + return -1; + p = buf; + return parse_uint64_base(pval, &p, 16); +} + +int parse_tag_version(const char *str) +{ + uint64_t version; + if (parse_tag_uint64(&version, str, "Version")) + return -1; + return version; +} + +BOOL is_url(const char *path) +{ + return (strstart(path, "http:", NULL) || + strstart(path, "https:", NULL) || + strstart(path, "file:", NULL)); +} |
