diff options
Diffstat (limited to 'util/libreboot-utils/lib/string.c')
| -rw-r--r-- | util/libreboot-utils/lib/string.c | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/util/libreboot-utils/lib/string.c b/util/libreboot-utils/lib/string.c new file mode 100644 index 00000000..cb37c1ba --- /dev/null +++ b/util/libreboot-utils/lib/string.c @@ -0,0 +1,146 @@ +/* SPDX-License-Identifier: MIT + * Copyright (c) 2026 Leah Rowe <leah@libreboot.org> + * + * String functions + */ + +#include <sys/types.h> +#include <sys/stat.h> + +#include <errno.h> +#include <stdarg.h> +#include <stddef.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> + +#include "../include/common.h" + +/* scmp() - strict string comparison + * + * strict string comparison + * similar to strncmp, but null and + * unterminated inputs do not produce + * a return value; on error, errno is + * set and -1 is returned. + * + * the real return value is stored in + * the 4th argument by pointer. + * + * the value at rval pointer is set, + * only upon success. callers should + * check the return value accordingly. + */ + +int +scmp(const char *a, + const char *b, + size_t maxlen, + int *rval) +{ + size_t ch; + unsigned char ac; + unsigned char bc; + + if (a == NULL || + b == NULL || + rval == NULL) { + + errno = EFAULT; + return -1; + } + + for (ch = 0; ch < maxlen; ch++) { + + ac = (unsigned char)a[ch]; + bc = (unsigned char)b[ch]; + + if (ac != bc) { + *rval = ac - bc; + return 0; + } + + if (ac == '\0') { + *rval = 0; + return 0; + } + } + + /* block unterminated strings */ + errno = EFAULT; + return -1; +} + +/* slen() - strict strict length + * + * strict string length calculation + * similar to strnlen, but null and + * unterminated inputs do not produce + * a return value; on error, errno is + * set and -1 is returned. + * + * the real return value is stored in + * the 3rd argument by pointer. + * + * the value at rval pointer is set, + * only upon success. callers should + * check the return value accordingly. + */ + +int +slen(const char *s, + size_t maxlen, + size_t *rval) +{ + size_t ch; + + if (s == NULL || + rval == NULL) { + + errno = EFAULT; + return -1; + } + + for (ch = 0; + ch < maxlen && s[ch] != '\0'; + ch++); + + if (ch == maxlen) { + /* unterminated */ + errno = EFAULT; + return -1; + } + + *rval = ch; + return 0; +} + +/* the one for nvmutil state is in state.c */ +/* this one just exits */ +void +err_no_cleanup(int nvm_errval, const char *msg, ...) +{ + va_list args; + +#if defined(__OpenBSD__) && defined(OpenBSD) +#if (OpenBSD) >= 509 + if (pledge("stdio", NULL) == -1) + fprintf(stderr, "pledge failure during exit"); +#endif +#endif + + if (!errno) + errno = ECANCELED; + + fprintf(stderr, "nvmutil: "); + + va_start(args, msg); + vfprintf(stderr, msg, args); + va_end(args); + + fprintf(stderr, ": %s\n", strerror(errno)); + + exit(EXIT_FAILURE); +} + |
