/* SPDX-License-Identifier: MIT * Copyright (c) 2026 Leah Rowe * * String functions */ #include #include #include #include #include #include #include #include #include #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); }