mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-07-11 22:12:40 +02:00
d2abde5303
where possible, try not to clobber sys errno. override it only when relatively safe. also: when a syscall succeeds, it may set errno. this is rare, but permitted (nothing specified against it in specs, and the specs say that errno is undefined on success). i'm not libc, but i'm wrapping around it, so i need to be careful in how i handle the errno value. also: i removed the requirement for directories to be executable, in mkhtemp.c, because this isn't required and will only break certain setups. in world_writeable and sticky, i made the checks stricter: the faccessat check was being skipped on some paths, so i've closed that loophole now. i also generally cleaned up some code, as part of the errno handling refactoring, where it made sense to do so, plus a few other bits of code cleanup. Signed-off-by: Leah Rowe <leah@libreboot.org>
118 lines
2.2 KiB
C
118 lines
2.2 KiB
C
/* SPDX-License-Identifier: MIT
|
|
* Copyright (c) 2026 Leah Rowe <leah@libreboot.org>
|
|
*
|
|
* Non-randomisation-related numerical functions.
|
|
* For rand functions, see: rand.c
|
|
*/
|
|
|
|
#ifdef __OpenBSD__
|
|
#include <sys/param.h>
|
|
#endif
|
|
#include <sys/types.h>
|
|
|
|
#include <errno.h>
|
|
#if !((defined(__OpenBSD__) && (OpenBSD) >= 201) || \
|
|
defined(__FreeBSD__) || \
|
|
defined(__NetBSD__) || defined(__APPLE__))
|
|
#include <fcntl.h> /* if not arc4random: /dev/urandom */
|
|
#endif
|
|
#include <ctype.h>
|
|
#include <limits.h>
|
|
#include <stddef.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include "../include/common.h"
|
|
|
|
unsigned short
|
|
hextonum(char ch_s)
|
|
{
|
|
unsigned char ch;
|
|
size_t rval;
|
|
|
|
ch = (unsigned char)ch_s;
|
|
|
|
if ((unsigned int)(ch - '0') <= 9)
|
|
return ch - '0';
|
|
|
|
ch |= 0x20;
|
|
|
|
if ((unsigned int)(ch - 'a') <= 5)
|
|
return ch - 'a' + 10;
|
|
|
|
if (ch == '?' || ch == 'x') /* random */
|
|
return (short)rsize(16); /* <-- with rejection sampling! */
|
|
|
|
return 16;
|
|
}
|
|
|
|
/* basically hexdump -C */
|
|
/*
|
|
TODO: optimise this
|
|
write a full util for hexdump
|
|
how to optimise:
|
|
don't call print tens of thousands of times!
|
|
convert the numbers manually, and cache everything
|
|
in a BUFSIZ sized buffer, with everything properly
|
|
aligned. i worked out that i could fit 79 rows
|
|
in a 8KB buffer (1264 bytes of numbers represented
|
|
as strings in hex)
|
|
this depends on the OS, and would be calculated at
|
|
runtime.
|
|
then:
|
|
don't use printf. just write it to stdout (basically
|
|
a simple cat implementation)
|
|
*/
|
|
void
|
|
spew_hex(const void *data, size_t len)
|
|
{
|
|
const unsigned char *buf = (const unsigned char *)data;
|
|
unsigned char c;
|
|
size_t i;
|
|
size_t j;
|
|
|
|
if (buf == NULL ||
|
|
len == 0)
|
|
return;
|
|
|
|
for (i = 0; i < len; i += 16) {
|
|
|
|
if (len <= 4294967296) /* below 4GB */
|
|
printf("%08zx ", i);
|
|
else
|
|
printf("%0*zx ", sizeof(size_t) * 2, i);
|
|
|
|
for (j = 0; j < 16; j++) {
|
|
|
|
if (i + j < len)
|
|
printf("%02x ", buf[i + j]);
|
|
else
|
|
printf(" ");
|
|
|
|
if (j == 7)
|
|
printf(" ");
|
|
}
|
|
|
|
printf(" |");
|
|
|
|
for (j = 0; j < 16 && i + j < len; j++) {
|
|
|
|
c = buf[i + j];
|
|
printf("%c", isprint(c) ? c : '.');
|
|
}
|
|
|
|
printf("|\n");
|
|
}
|
|
|
|
printf("%08zx\n", len);
|
|
}
|
|
|
|
void
|
|
check_bin(size_t a, const char *a_name)
|
|
{
|
|
if (a > 1)
|
|
err_exit(EINVAL, "%s must be 0 or 1, but is %lu",
|
|
a_name, (size_t)a);
|
|
}
|