mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-03-25 13:29:03 +02:00
Compare commits
17 Commits
9a9bcfe070
...
6fe909f9f7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6fe909f9f7 | ||
|
|
9573d872f3 | ||
|
|
d01aedd289 | ||
|
|
3fba6f2d64 | ||
|
|
16d50d42da | ||
|
|
dcdbd5eda1 | ||
|
|
952a3d52a5 | ||
|
|
63f0fe9702 | ||
|
|
fd1bafecd1 | ||
|
|
5ab3b11446 | ||
|
|
2cb1797acc | ||
|
|
cb8ac86bd4 | ||
|
|
b00fb6127e | ||
|
|
15b8cd7833 | ||
|
|
0db9cc321f | ||
|
|
6e63106dae | ||
|
|
6b1757da57 |
@@ -3,25 +3,42 @@
|
||||
# Copyright (c) 2023 Riku Viitanen <riku.viitanen@protonmail.com>
|
||||
|
||||
CC?=cc
|
||||
CSTD?=-std=c90
|
||||
WERROR?=-Werror
|
||||
CWARN?=-Wall -Wextra -pedantic
|
||||
COPT?=-Os
|
||||
CFLAGS?=$(CWARN) $(CSTD)
|
||||
HELLCC?=clang
|
||||
|
||||
CFLAGS?=
|
||||
LDFLAGS?=
|
||||
DESTDIR?=
|
||||
PREFIX?=/usr/local
|
||||
INSTALL?=install
|
||||
LDIR?=-I.
|
||||
|
||||
OPTS=$(LDIR) $(COPT) $(WERROR) $(CFLAGS) $(LDFLAGS)
|
||||
.SUFFIXES:
|
||||
|
||||
# maybe add -I. here when running make
|
||||
# e.g. make LDIR=-I.
|
||||
LDIR?=
|
||||
|
||||
PORTABLE?=$(LDIR) $(CFLAGS)
|
||||
WARN?=$(PORTABLE) -Wall -Wextra
|
||||
STRICT?=$(WARN) -std=c90 -pedantic -Werror
|
||||
HELLFLAGS?=$(STRICT) -Weverything
|
||||
|
||||
# program name
|
||||
PROG=nvmutil
|
||||
|
||||
all: $(PROG)
|
||||
|
||||
$(PROG): nvmutil.c
|
||||
$(CC) $(OPTS) nvmutil.c -o $(PROG)
|
||||
$(PROG): $(PROG).c
|
||||
$(CC) $(PORTABLE) $(PROG).c -o $(PROG) $(LDFLAGS)
|
||||
|
||||
warn: $(PROG).c
|
||||
$(CC) $(WARN) $(PROG).c -o $(PROG) $(LDFLAGS)
|
||||
|
||||
strict: $(PROG).c
|
||||
$(CC) $(STRICT) $(PROG).c -o $(PROG) $(LDFLAGS)
|
||||
|
||||
# clang-only extreme warnings (not portable)
|
||||
hell: $(PROG).c
|
||||
$(HELLCC) $(HELLFLAGS) $(PROG).c -o $(PROG) $(LDFLAGS)
|
||||
|
||||
install: $(PROG)
|
||||
$(INSTALL) -d $(DESTDIR)$(PREFIX)/bin
|
||||
@@ -36,4 +53,4 @@ clean:
|
||||
|
||||
distclean: clean
|
||||
|
||||
.PHONY: all install uninstall clean distclean
|
||||
.PHONY: all warn strict hell install uninstall clean distclean
|
||||
|
||||
@@ -94,7 +94,7 @@ new_xstate(void)
|
||||
/* ->mac */
|
||||
{NULL, "xx:xx:xx:xx:xx:xx", {0, 0, 0}}, /* .str, .rmac, .mac_buf */
|
||||
|
||||
/* .buf */
|
||||
/* .f */
|
||||
{0},
|
||||
|
||||
/* .argv0 (for our getprogname implementation) */
|
||||
@@ -144,30 +144,29 @@ new_xstate(void)
|
||||
return xs_new;
|
||||
}
|
||||
|
||||
struct xstate *nv = NULL;
|
||||
static struct xstate *nv = NULL;
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct commands *cmd;
|
||||
struct xfile *f;
|
||||
int fd;
|
||||
struct stat st;
|
||||
|
||||
char *tmp_path = NULL;
|
||||
|
||||
unsigned long *i;
|
||||
|
||||
nv = new_xstate();
|
||||
if (nv == NULL)
|
||||
err(errno, NULL);
|
||||
|
||||
nv->argv0 = argv[0];
|
||||
if (argc < 3)
|
||||
usage();
|
||||
|
||||
#ifndef CHAR_BIT
|
||||
err(ECANCELED, "Unknown char size");
|
||||
#else
|
||||
if (CHAR_BIT != 8)
|
||||
err(EINVAL, "Unsupported char size");
|
||||
#endif
|
||||
|
||||
f = &nv->f;
|
||||
|
||||
f->fname = argv[1];
|
||||
if (argc < 3)
|
||||
usage();
|
||||
|
||||
#ifdef NVMUTIL_UNVEIL
|
||||
/*
|
||||
@@ -175,12 +174,12 @@ main(int argc, char *argv[])
|
||||
* unveil would trap on final file rename
|
||||
* and we can't know the path in advance
|
||||
*/
|
||||
f->tname = new_tmpfile(&f->tmp_fd, 1, NULL);
|
||||
tmp_path = new_tmpfile(&fd, 1, NULL);
|
||||
#else
|
||||
f->tname = new_tmpfile(&f->tmp_fd, 0, NULL);
|
||||
tmp_path = new_tmpfile(&fd, 0, NULL);
|
||||
#endif
|
||||
|
||||
if (f->tname == NULL)
|
||||
if (tmp_path == NULL)
|
||||
err(errno, "Can't create tmpfile");
|
||||
|
||||
#ifdef NVMUTIL_PLEDGE
|
||||
@@ -197,6 +196,26 @@ main(int argc, char *argv[])
|
||||
#endif
|
||||
#endif
|
||||
|
||||
nv = new_xstate();
|
||||
|
||||
if (nv == NULL)
|
||||
err(errno, NULL);
|
||||
if (nv->f.buf == NULL)
|
||||
err(EINVAL, "Work buffer not initialised");
|
||||
|
||||
nv->argv0 = argv[0];
|
||||
f = &nv->f;
|
||||
|
||||
f->fname = argv[1];
|
||||
f->tname = tmp_path;
|
||||
f->tmp_fd = fd;
|
||||
|
||||
if(fstat(fd, &st) < 0)
|
||||
err(errno, "can't stat tmpfile");
|
||||
|
||||
f->tmp_dev = st.st_dev;
|
||||
f->tmp_ino = st.st_ino;
|
||||
|
||||
sanitize_command_list();
|
||||
|
||||
set_cmd(argc, argv);
|
||||
@@ -207,11 +226,11 @@ main(int argc, char *argv[])
|
||||
|
||||
#ifdef NVMUTIL_UNVEIL
|
||||
if (cmd->flags == O_RDONLY) {
|
||||
if (unveil(fname, "r") == -1)
|
||||
err(errno, "%s: unveil r", fname);
|
||||
if (unveil(f->fname, "r") == -1)
|
||||
err(errno, "%s: unveil r", f->fname);
|
||||
} else {
|
||||
if (unveil(fname, "rwc") == -1)
|
||||
err(errno, "%s: unveil rw", fname);
|
||||
if (unveil(f->tname, "rwc") == -1)
|
||||
err(errno, "%s: unveil rw", f->tname);
|
||||
}
|
||||
|
||||
if (unveil(tname, "rwc") == -1)
|
||||
@@ -506,19 +525,18 @@ open_gbe_file(void)
|
||||
err(EINVAL, "File size must be 8KB, 16KB or 128KB");
|
||||
}
|
||||
|
||||
if (lock_file(f->gbe_fd) == -1)
|
||||
if (lock_file(f->gbe_fd, cmd->flags) == -1)
|
||||
err(errno, "%s: can't lock", f->fname);
|
||||
}
|
||||
|
||||
int
|
||||
lock_file(int fd)
|
||||
lock_file(int fd, int flags)
|
||||
{
|
||||
struct flock fl;
|
||||
struct commands *cmd = &nv->cmd[nv->i];
|
||||
|
||||
memset(&fl, 0, sizeof(fl));
|
||||
|
||||
if (cmd->flags == O_RDONLY)
|
||||
if ((flags & O_ACCMODE) == O_RDONLY)
|
||||
fl.l_type = F_RDLCK;
|
||||
else
|
||||
fl.l_type = F_WRLCK;
|
||||
@@ -531,6 +549,21 @@ lock_file(int fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: make generic. S_ISREG: check every other
|
||||
* type, erring only if it doesn't match what was
|
||||
* passed as type requested.
|
||||
* also:
|
||||
* have variable need_seek, only err on seek if
|
||||
* need_seek is set.
|
||||
* also consider the stat check in this generic
|
||||
* context
|
||||
* make tthe return type an int, not a void.
|
||||
* return -1 with errno set to indicate error,
|
||||
* though the syscalls mostly handle that.
|
||||
* save errno before lseek, resetting it after
|
||||
* the check if return >-1
|
||||
*/
|
||||
void
|
||||
xopen(int *fd_ptr, const char *path, int flags, struct stat *st)
|
||||
{
|
||||
@@ -560,6 +593,31 @@ xopen(int *fd_ptr, const char *path, int flags, struct stat *st)
|
||||
*/
|
||||
void
|
||||
copy_gbe(void)
|
||||
{
|
||||
struct xfile *f = &nv->f;
|
||||
|
||||
read_file();
|
||||
|
||||
/*
|
||||
regular operations post-read operate only on the first
|
||||
8KB, because each GbE part is the first 4KB of each
|
||||
half of the file.
|
||||
|
||||
we no longer care about anything past 8KB, until we get
|
||||
to writing, at which point we will flush the buffer
|
||||
again
|
||||
*/
|
||||
|
||||
if (f->gbe_file_size == SIZE_8KB)
|
||||
return;
|
||||
|
||||
x_v_memcpy(f->buf + (unsigned long)GBE_PART_SIZE,
|
||||
f->buf + (unsigned long)(f->gbe_file_size >> 1),
|
||||
(unsigned long)GBE_PART_SIZE);
|
||||
}
|
||||
|
||||
void
|
||||
read_file(void)
|
||||
{
|
||||
long _r;
|
||||
struct stat _st;
|
||||
@@ -614,23 +672,6 @@ copy_gbe(void)
|
||||
if (x_i_memcmp(f->buf, f->bufcmp, f->gbe_file_size) != 0)
|
||||
err(errno, "%s: %s: read contents differ (pre-test)",
|
||||
f->fname, f->tname);
|
||||
|
||||
/*
|
||||
regular operations post-read operate only on the first
|
||||
8KB, because each GbE part is the first 4KB of each
|
||||
half of the file.
|
||||
|
||||
we no longer care about anything past 8KB, until we get
|
||||
to writing, at which point we will flush the buffer
|
||||
again
|
||||
*/
|
||||
|
||||
if (f->gbe_file_size == SIZE_8KB)
|
||||
return;
|
||||
|
||||
x_v_memcpy(f->buf + (unsigned long)GBE_PART_SIZE,
|
||||
f->buf + (unsigned long)(f->gbe_file_size >> 1),
|
||||
(unsigned long)GBE_PART_SIZE);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1434,7 +1475,6 @@ check_written_part(unsigned long p)
|
||||
|
||||
gbe_rw_size = cmd->rw_size;
|
||||
|
||||
/* invert not needed for pwrite */
|
||||
mem_offset = gbe_mem_offset(p, "pwrite");
|
||||
file_offset = (off_t)gbe_file_offset(p, "pwrite");
|
||||
|
||||
@@ -1553,8 +1593,10 @@ gbe_mv(void)
|
||||
|
||||
tmp_gbe_bin_exists = 0;
|
||||
|
||||
if (fsync_dir(f->fname) < 0)
|
||||
if (fsync_dir(f->fname) < 0) {
|
||||
f->io_err_gbe_bin = 1;
|
||||
r = -1;
|
||||
}
|
||||
|
||||
goto ret_gbe_mv;
|
||||
}
|
||||
@@ -1600,8 +1642,10 @@ gbe_mv(void)
|
||||
if (rename(dest_tmp, f->fname) == -1)
|
||||
goto ret_gbe_mv;
|
||||
|
||||
if (fsync_dir(f->fname) < 0)
|
||||
if (fsync_dir(f->fname) < 0) {
|
||||
f->io_err_gbe_bin = 1;
|
||||
goto ret_gbe_mv;
|
||||
}
|
||||
|
||||
free(dest_tmp);
|
||||
dest_tmp = NULL;
|
||||
@@ -1611,8 +1655,10 @@ ret_gbe_mv:
|
||||
if (f->gbe_fd > -1) {
|
||||
if (x_i_close(f->gbe_fd) < 0)
|
||||
r = -1;
|
||||
if (fsync_dir(f->fname) < 0)
|
||||
if (fsync_dir(f->fname) < 0) {
|
||||
f->io_err_gbe_bin = 1;
|
||||
r = -1;
|
||||
}
|
||||
f->gbe_fd = -1;
|
||||
}
|
||||
|
||||
@@ -1656,8 +1702,6 @@ ret_gbe_mv:
|
||||
int
|
||||
fsync_dir(const char *path)
|
||||
{
|
||||
struct xfile *f = &nv->f;
|
||||
|
||||
#if defined(PATH_LEN) && \
|
||||
(PATH_LEN) >= 256
|
||||
unsigned long maxlen = PATH_LEN;
|
||||
@@ -1742,7 +1786,7 @@ err_fsync_dir:
|
||||
errno = EIO;
|
||||
|
||||
if (errno != saved_errno)
|
||||
fprintf(stderr, "%s: %s\n", f->fname, strerror(errno));
|
||||
fprintf(stderr, "%s: %s\n", path, strerror(errno));
|
||||
|
||||
if (dirbuf != NULL)
|
||||
free(dirbuf);
|
||||
@@ -1750,7 +1794,6 @@ err_fsync_dir:
|
||||
if (dfd > -1)
|
||||
x_i_close(dfd);
|
||||
|
||||
f->io_err_gbe_bin = 1;
|
||||
errno = saved_errno;
|
||||
|
||||
return -1;
|
||||
@@ -2308,8 +2351,6 @@ usage(void)
|
||||
void
|
||||
err(int nvm_errval, const char *msg, ...)
|
||||
{
|
||||
struct xfile *f = &nv->f;
|
||||
|
||||
va_list args;
|
||||
|
||||
if (errno == 0)
|
||||
@@ -2325,12 +2366,7 @@ err(int nvm_errval, const char *msg, ...)
|
||||
vfprintf(stderr, msg, args);
|
||||
va_end(args);
|
||||
|
||||
fprintf(stderr, ": %s", strerror(errno));
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
if (f->tname != NULL)
|
||||
free(f->tname);
|
||||
fprintf(stderr, ": %s\n", strerror(errno));
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -2338,28 +2374,32 @@ err(int nvm_errval, const char *msg, ...)
|
||||
int
|
||||
exit_cleanup(void)
|
||||
{
|
||||
struct xfile *f = &nv->f;
|
||||
struct xfile *f;
|
||||
|
||||
int close_err = 0;
|
||||
int saved_errno = errno;
|
||||
|
||||
if (f->gbe_fd > -1) {
|
||||
if (x_i_close(f->gbe_fd) == -1)
|
||||
close_err = 1;
|
||||
f->gbe_fd = -1;
|
||||
}
|
||||
if (nv != NULL) {
|
||||
f = &nv->f;
|
||||
|
||||
if (f->tmp_fd > -1) {
|
||||
if (x_i_close(f->tmp_fd) == -1)
|
||||
close_err = 1;
|
||||
}
|
||||
if (f->gbe_fd > -1) {
|
||||
if (x_i_close(f->gbe_fd) == -1)
|
||||
close_err = 1;
|
||||
f->gbe_fd = -1;
|
||||
}
|
||||
|
||||
if (f->tname != NULL) {
|
||||
if (unlink(f->tname) == -1)
|
||||
close_err = 1;
|
||||
}
|
||||
if (f->tmp_fd > -1) {
|
||||
if (x_i_close(f->tmp_fd) == -1)
|
||||
close_err = 1;
|
||||
}
|
||||
|
||||
f->tmp_fd = -1;
|
||||
if (f->tname != NULL) {
|
||||
if (unlink(f->tname) == -1)
|
||||
close_err = 1;
|
||||
}
|
||||
|
||||
f->tmp_fd = -1;
|
||||
}
|
||||
|
||||
if (saved_errno)
|
||||
errno = saved_errno;
|
||||
@@ -2413,8 +2453,6 @@ getnvmprogname(void)
|
||||
char *
|
||||
new_tmpfile(int *fd, int local, const char *path)
|
||||
{
|
||||
struct xfile *f = &nv->f;
|
||||
|
||||
unsigned long maxlen;
|
||||
struct stat st;
|
||||
|
||||
@@ -2531,7 +2569,20 @@ new_tmpfile(int *fd, int local, const char *path)
|
||||
if (x_i_fchmod(fd_tmp, 0600) == -1)
|
||||
goto err_new_tmpfile;
|
||||
|
||||
if (lock_file(fd_tmp) == -1)
|
||||
flags = fcntl(fd_tmp, F_GETFL);
|
||||
|
||||
if (flags == -1)
|
||||
goto err_new_tmpfile;
|
||||
|
||||
/*
|
||||
* O_APPEND would permit offsets
|
||||
* to be ignored, which breaks
|
||||
* positional read/write
|
||||
*/
|
||||
if (flags & O_APPEND)
|
||||
goto err_new_tmpfile;
|
||||
|
||||
if (lock_file(fd_tmp, flags) == -1)
|
||||
goto err_new_tmpfile;
|
||||
|
||||
if (fstat(fd_tmp, &st) == -1)
|
||||
@@ -2550,10 +2601,6 @@ new_tmpfile(int *fd, int local, const char *path)
|
||||
if (lseek(fd_tmp, 0, SEEK_CUR) == (off_t)-1)
|
||||
goto err_new_tmpfile;
|
||||
|
||||
/* inode will be checked later on write */
|
||||
f->tmp_dev = st.st_dev;
|
||||
f->tmp_ino = st.st_ino;
|
||||
|
||||
/* tmpfile has >1 hardlinks */
|
||||
if (st.st_nlink > 1)
|
||||
goto err_new_tmpfile;
|
||||
@@ -2562,19 +2609,6 @@ new_tmpfile(int *fd, int local, const char *path)
|
||||
if (st.st_nlink == 0)
|
||||
goto err_new_tmpfile;
|
||||
|
||||
flags = fcntl(fd_tmp, F_GETFL);
|
||||
|
||||
if (flags == -1)
|
||||
goto err_new_tmpfile;
|
||||
|
||||
/*
|
||||
* O_APPEND would permit offsets
|
||||
* to be ignored, which breaks
|
||||
* positional read/write
|
||||
*/
|
||||
if (flags & O_APPEND)
|
||||
goto err_new_tmpfile;
|
||||
|
||||
*fd = fd_tmp;
|
||||
|
||||
return dest;
|
||||
@@ -2601,8 +2635,10 @@ x_i_mkstemp(char *template)
|
||||
unsigned long len;
|
||||
char *p;
|
||||
|
||||
char ch[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
unsigned long r = rlong();
|
||||
char ch[] =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
|
||||
unsigned long r;
|
||||
|
||||
len = xstrxlen(template, PATH_LEN);
|
||||
|
||||
@@ -2614,8 +2650,10 @@ x_i_mkstemp(char *template)
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
|
||||
for (j = 0; j < 6; j++)
|
||||
for (j = 0; j < 6; j++) {
|
||||
r = rlong();
|
||||
p[j] = ch[r % (sizeof(ch) - 1)];
|
||||
}
|
||||
|
||||
fd = open(template, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||
|
||||
@@ -2647,6 +2685,13 @@ x_c_strrchr(const char *s, int c)
|
||||
return (char *)p;
|
||||
}
|
||||
|
||||
/*
|
||||
* non-atomic rename
|
||||
*
|
||||
* commented because i can't sacrifice
|
||||
* exactly this property. nvmutil tries
|
||||
* to protect files against e.g. power loss
|
||||
*/
|
||||
/*
|
||||
int
|
||||
x_i_rename(const char *src, const char *dst)
|
||||
@@ -2743,12 +2788,9 @@ x_i_memcmp(const void *a, const void *b, unsigned long n)
|
||||
const unsigned char *pa = (const unsigned char *)a;
|
||||
const unsigned char *pb = (const unsigned char *)b;
|
||||
|
||||
while (n--) {
|
||||
for ( ; n--; ++pa, ++pb)
|
||||
if (*pa != *pb)
|
||||
return *pa - *pb;
|
||||
pa++;
|
||||
pb++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2838,63 +2880,3 @@ x_i_fsync(int fd)
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* type asserts */
|
||||
typedef char static_assert_char_is_8_bits[(CHAR_BIT == 8) ? 1 : -1];
|
||||
typedef char static_assert_char_is_1[(sizeof(char) == 1) ? 1 : -1];
|
||||
typedef char static_assert_unsigned_char_is_1[
|
||||
(sizeof(unsigned char) == 1) ? 1 : -1];
|
||||
typedef char static_assert_unsigned_short_is_2[
|
||||
(sizeof(unsigned short) >= 2) ? 1 : -1];
|
||||
typedef char static_assert_short_is_2[(sizeof(short) >= 2) ? 1 : -1];
|
||||
typedef char static_assert_unsigned_int_is_4[
|
||||
(sizeof(unsigned int) >= 4) ? 1 : -1];
|
||||
typedef char static_assert_unsigned_long_is_4[
|
||||
(sizeof(unsigned long) >= 4) ? 1 : -1];
|
||||
typedef char static_assert_int_ge_32[(sizeof(int) >= 4) ? 1 : -1];
|
||||
typedef char static_assert_twos_complement[
|
||||
((-1 & 3) == 3) ? 1 : -1
|
||||
];
|
||||
typedef char assert_unsigned_long_ptr[
|
||||
(sizeof(unsigned long) >= sizeof(void *)) ? 1 : -1
|
||||
];
|
||||
|
||||
/*
|
||||
* We set _FILE_OFFSET_BITS 64, but we only handle
|
||||
* but we only need smaller files, so require 4-bytes.
|
||||
* Some operating systems ignore the define, hence assert:
|
||||
*/
|
||||
typedef char static_assert_off_t_is_32[(sizeof(off_t) >= 4) ? 1 : -1];
|
||||
|
||||
/*
|
||||
* asserts (variables/defines sanity check)
|
||||
*/
|
||||
typedef char assert_argc3[(ARGC_3==3)?1:-1];
|
||||
typedef char assert_argc4[(ARGC_4==4)?1:-1];
|
||||
typedef char assert_read[(IO_READ==0)?1:-1];
|
||||
typedef char assert_write[(IO_WRITE==1)?1:-1];
|
||||
typedef char assert_pread[(IO_PREAD==2)?1:-1];
|
||||
typedef char assert_pwrite[(IO_PWRITE==3)?1:-1];
|
||||
typedef char assert_pathlen[(PATH_LEN>=256)?1:-1];
|
||||
/* commands */
|
||||
typedef char assert_cmd_dump[(CMD_DUMP==0)?1:-1];
|
||||
typedef char assert_cmd_setmac[(CMD_SETMAC==1)?1:-1];
|
||||
typedef char assert_cmd_swap[(CMD_SWAP==2)?1:-1];
|
||||
typedef char assert_cmd_copy[(CMD_COPY==3)?1:-1];
|
||||
typedef char assert_cmd_cat[(CMD_CAT==4)?1:-1];
|
||||
typedef char assert_cmd_cat16[(CMD_CAT16==5)?1:-1];
|
||||
typedef char assert_cmd_cat128[(CMD_CAT128==6)?1:-1];
|
||||
/* bool */
|
||||
typedef char bool_arg_nopart[(ARG_NOPART==0)?1:-1];
|
||||
typedef char bool_arg_part[(ARG_PART==1)?1:-1];
|
||||
typedef char bool_skip_checksum_read[(SKIP_CHECKSUM_READ==0)?1:-1];
|
||||
typedef char bool_checksum_read[(CHECKSUM_READ==1)?1:-1];
|
||||
typedef char bool_skip_checksum_write[(SKIP_CHECKSUM_WRITE==0)?1:-1];
|
||||
typedef char bool_checksum_write[(CHECKSUM_WRITE==1)?1:-1];
|
||||
typedef char bool_loop_eintr[(LOOP_EINTR==1||LOOP_EINTR==0)?1:-1];
|
||||
typedef char bool_loop_eagain[(LOOP_EAGAIN==1||LOOP_EAGAIN==0)?1:-1];
|
||||
typedef char bool_no_loop_eintr[(NO_LOOP_EINTR==0)?1:-1];
|
||||
typedef char bool_no_loop_eagain[(NO_LOOP_EAGAIN==0)?1:-1];
|
||||
typedef char bool_off_err[(OFF_ERR==0)?1:-1];
|
||||
typedef char bool_off_reset[(OFF_RESET==0||OFF_RESET==1)?1:-1];
|
||||
|
||||
|
||||
@@ -66,6 +66,10 @@
|
||||
#define EXIT_SUCCESS 0
|
||||
#endif
|
||||
|
||||
#ifndef O_ACCMODE
|
||||
#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
|
||||
#endif
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
@@ -291,6 +295,7 @@ struct xstate {
|
||||
|
||||
|
||||
|
||||
static struct xstate *new_xstate(void);
|
||||
|
||||
/*
|
||||
* Sanitize command tables.
|
||||
@@ -310,7 +315,7 @@ int xstrxcmp(const char *a, const char *b, unsigned long maxlen);
|
||||
* Prep files for reading
|
||||
*/
|
||||
void open_gbe_file(void);
|
||||
int lock_file(int fd);
|
||||
int lock_file(int fd, int flags);
|
||||
void xopen(int *fd, const char *path, int flags, struct stat *st);
|
||||
|
||||
/*
|
||||
@@ -320,6 +325,7 @@ void xopen(int *fd, const char *path, int flags, struct stat *st);
|
||||
* After this, we can run commands.
|
||||
*/
|
||||
void copy_gbe(void);
|
||||
void read_file(void);
|
||||
void read_checksums(void);
|
||||
int good_checksum(unsigned long partnum);
|
||||
|
||||
@@ -460,4 +466,69 @@ unsigned long x_conv_fd(char *buf,
|
||||
unsigned long n);
|
||||
int x_i_fsync(int fd);
|
||||
|
||||
|
||||
|
||||
|
||||
/* asserts */
|
||||
|
||||
/* type asserts */
|
||||
typedef char static_assert_char_is_8_bits[(CHAR_BIT == 8) ? 1 : -1];
|
||||
typedef char static_assert_char_is_1[(sizeof(char) == 1) ? 1 : -1];
|
||||
typedef char static_assert_unsigned_char_is_1[
|
||||
(sizeof(unsigned char) == 1) ? 1 : -1];
|
||||
typedef char static_assert_unsigned_short_is_2[
|
||||
(sizeof(unsigned short) >= 2) ? 1 : -1];
|
||||
typedef char static_assert_short_is_2[(sizeof(short) >= 2) ? 1 : -1];
|
||||
typedef char static_assert_unsigned_int_is_4[
|
||||
(sizeof(unsigned int) >= 4) ? 1 : -1];
|
||||
typedef char static_assert_unsigned_long_is_4[
|
||||
(sizeof(unsigned long) >= 4) ? 1 : -1];
|
||||
typedef char static_assert_int_ge_32[(sizeof(int) >= 4) ? 1 : -1];
|
||||
typedef char static_assert_twos_complement[
|
||||
((-1 & 3) == 3) ? 1 : -1
|
||||
];
|
||||
typedef char assert_unsigned_long_ptr[
|
||||
(sizeof(unsigned long) >= sizeof(void *)) ? 1 : -1
|
||||
];
|
||||
|
||||
/*
|
||||
* We set _FILE_OFFSET_BITS 64, but we only handle
|
||||
* but we only need smaller files, so require 4-bytes.
|
||||
* Some operating systems ignore the define, hence assert:
|
||||
*/
|
||||
typedef char static_assert_off_t_is_32[(sizeof(off_t) >= 4) ? 1 : -1];
|
||||
|
||||
/*
|
||||
* asserts (variables/defines sanity check)
|
||||
*/
|
||||
typedef char assert_argc3[(ARGC_3==3)?1:-1];
|
||||
typedef char assert_argc4[(ARGC_4==4)?1:-1];
|
||||
typedef char assert_read[(IO_READ==0)?1:-1];
|
||||
typedef char assert_write[(IO_WRITE==1)?1:-1];
|
||||
typedef char assert_pread[(IO_PREAD==2)?1:-1];
|
||||
typedef char assert_pwrite[(IO_PWRITE==3)?1:-1];
|
||||
typedef char assert_pathlen[(PATH_LEN>=256)?1:-1];
|
||||
/* commands */
|
||||
typedef char assert_cmd_dump[(CMD_DUMP==0)?1:-1];
|
||||
typedef char assert_cmd_setmac[(CMD_SETMAC==1)?1:-1];
|
||||
typedef char assert_cmd_swap[(CMD_SWAP==2)?1:-1];
|
||||
typedef char assert_cmd_copy[(CMD_COPY==3)?1:-1];
|
||||
typedef char assert_cmd_cat[(CMD_CAT==4)?1:-1];
|
||||
typedef char assert_cmd_cat16[(CMD_CAT16==5)?1:-1];
|
||||
typedef char assert_cmd_cat128[(CMD_CAT128==6)?1:-1];
|
||||
/* bool */
|
||||
typedef char bool_arg_nopart[(ARG_NOPART==0)?1:-1];
|
||||
typedef char bool_arg_part[(ARG_PART==1)?1:-1];
|
||||
typedef char bool_skip_checksum_read[(SKIP_CHECKSUM_READ==0)?1:-1];
|
||||
typedef char bool_checksum_read[(CHECKSUM_READ==1)?1:-1];
|
||||
typedef char bool_skip_checksum_write[(SKIP_CHECKSUM_WRITE==0)?1:-1];
|
||||
typedef char bool_checksum_write[(CHECKSUM_WRITE==1)?1:-1];
|
||||
typedef char bool_loop_eintr[(LOOP_EINTR==1||LOOP_EINTR==0)?1:-1];
|
||||
typedef char bool_loop_eagain[(LOOP_EAGAIN==1||LOOP_EAGAIN==0)?1:-1];
|
||||
typedef char bool_no_loop_eintr[(NO_LOOP_EINTR==0)?1:-1];
|
||||
typedef char bool_no_loop_eagain[(NO_LOOP_EAGAIN==0)?1:-1];
|
||||
typedef char bool_off_err[(OFF_ERR==0)?1:-1];
|
||||
typedef char bool_off_reset[(OFF_RESET==0||OFF_RESET==1)?1:-1];
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user