#include #include #include #include bool verbose = true; bool quiet = false; bool serial = false; bool hash_mismatch_panic = false; uint8_t bcd_to_int(uint8_t val) { return (val & 0x0f) + ((val & 0xf0) >> 4) * 10; } uint8_t int_to_bcd(uint8_t val) { return (val % 10) | (val / 10) << 4; } int digit_to_int(char c) { if (c >= 'a' && c <= 'f') { return (c - 'a') + 10; } if (c >= 'A' && c <= 'F') { return (c - 'A') + 10; } if (c >= '0' && c <= '9'){ return c - '0'; } return -1; } uint64_t strtoui(const char *s, const char **end, int base) { uint64_t n = 0; for (size_t i = 0; ; i++) { int d = digit_to_int(s[i]); if (d == -1) { if (end != NULL) *end = &s[i]; break; } n = n * base + d; } return n; } void get_absolute_path(char *path_ptr, const char *path, const char *pwd) { char *orig_ptr = path_ptr; if (!*path) { strcpy(path_ptr, pwd); return; } if (*path != '/') { strcpy(path_ptr, pwd); path_ptr += strlen(path_ptr); } else { *path_ptr = '/'; path_ptr++; path++; } goto first_run; for (;;) { switch (*path) { case '/': path++; first_run: if (*path == '/') continue; if ((!strncmp(path, ".\0", 2)) || (!strncmp(path, "./\0", 3))) { goto term; } if ((!strncmp(path, "..\0", 3)) || (!strncmp(path, "../\0", 4))) { while (*path_ptr != '/') path_ptr--; if (path_ptr == orig_ptr) path_ptr++; goto term; } if (!strncmp(path, "../", 3)) { while (*path_ptr != '/') path_ptr--; if (path_ptr == orig_ptr) path_ptr++; path += 2; *path_ptr = 0; continue; } if (!strncmp(path, "./", 2)) { path += 1; continue; } if (((path_ptr - 1) != orig_ptr) && (*(path_ptr - 1) != '/')) { *path_ptr = '/'; path_ptr++; } continue; case '\0': term: if ((*(path_ptr - 1) == '/') && ((path_ptr - 1) != orig_ptr)) path_ptr--; *path_ptr = 0; return; default: *path_ptr = *path; path++; path_ptr++; continue; } } }