mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-03-25 13:29:03 +02:00
i have my own getprogname implementation, because not every libc is good enough to include one. Signed-off-by: Leah Rowe <leah@libreboot.org>
207 lines
3.2 KiB
C
207 lines
3.2 KiB
C
/* 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;
|
|
int saved_errno = errno;
|
|
const char *p;
|
|
|
|
#if defined(__OpenBSD__) && defined(OpenBSD)
|
|
#if (OpenBSD) >= 509
|
|
if (pledge("stdio", NULL) == -1)
|
|
fprintf(stderr, "pledge failure during exit");
|
|
#endif
|
|
#endif
|
|
if (!errno)
|
|
saved_errno = errno = ECANCELED;
|
|
|
|
if ((p = getnvmprogname()) != NULL)
|
|
fprintf(stderr, "%s: ", p);
|
|
|
|
va_start(args, msg);
|
|
vfprintf(stderr, msg, args);
|
|
va_end(args);
|
|
|
|
fprintf(stderr, ": %s\n", strerror(errno));
|
|
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
const char *
|
|
getnvmprogname(void)
|
|
{
|
|
static char *rval = NULL;
|
|
static char *p;
|
|
static int setname = 0;
|
|
|
|
if (!setname) {
|
|
if ((rval = lbgetprogname(NULL)) == NULL)
|
|
return NULL;
|
|
|
|
p = strrchr(rval, '/');
|
|
if (p)
|
|
rval = p + 1;
|
|
|
|
setname = 1;
|
|
}
|
|
|
|
return rval;
|
|
}
|
|
|
|
/* singleton. if string not null,
|
|
sets the string. after set,
|
|
will not set anymore. either
|
|
way, returns the string
|
|
*/
|
|
char *
|
|
lbgetprogname(char *argv0)
|
|
{
|
|
static int setname = 0;
|
|
static char *progname = NULL;
|
|
size_t len;
|
|
|
|
if (!setname) {
|
|
if (if_err(argv0 == NULL || *argv0 == '\0', EFAULT) ||
|
|
slen(argv0, 4096, &len) < 0 ||
|
|
(progname = malloc(len + 1)) == NULL)
|
|
return NULL;
|
|
|
|
memcpy(progname, argv0, len + 1);
|
|
setname = 1;
|
|
}
|
|
|
|
return progname;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|