summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util/nvmutil/nvmutil.c382
-rw-r--r--util/nvmutil/nvmutil.h21
2 files changed, 244 insertions, 159 deletions
diff --git a/util/nvmutil/nvmutil.c b/util/nvmutil/nvmutil.c
index 7652538a..33d20c9f 100644
--- a/util/nvmutil/nvmutil.c
+++ b/util/nvmutil/nvmutil.c
@@ -79,12 +79,12 @@ new_xstate(void)
CHECKSUM_READ, SKIP_CHECKSUM_WRITE,
GBE_PART_SIZE, O_RDONLY
}, {
- CMD_CAT16, "cat16", cmd_helper_cat, ARGC_3,
+ CMD_CAT16, "cat16", cmd_helper_cat16, ARGC_3,
ARG_NOPART,
CHECKSUM_READ, SKIP_CHECKSUM_WRITE,
GBE_PART_SIZE, O_RDONLY
}, {
- CMD_CAT128, "cat128", cmd_helper_cat, ARGC_3,
+ CMD_CAT128, "cat128", cmd_helper_cat128, ARGC_3,
ARG_NOPART,
CHECKSUM_READ, SKIP_CHECKSUM_WRITE,
GBE_PART_SIZE, O_RDONLY
@@ -107,7 +107,10 @@ new_xstate(void)
1,
/* .xsize (size of the stuct will be stored here later) */
- 0
+ 0,
+
+ /* .cat (cat helpers set this) */
+ -1
};
@@ -144,13 +147,17 @@ new_xstate(void)
return xs_new;
}
-static struct xstate *nv = NULL;
+static struct xstate *x = 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;
@@ -161,33 +168,21 @@ main(int argc, char *argv[])
err(EINVAL, "Unsupported char size");
#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];
if (argc < 3)
usage();
- f = &nv->f;
-
- f->fname = argv[1];
-
#ifdef NVMUTIL_UNVEIL
/*
* if global tmp is a different filesystem,
* 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
@@ -204,21 +199,41 @@ main(int argc, char *argv[])
#endif
#endif
+ x = new_xstate();
+
+ if (x == NULL)
+ err(errno, NULL);
+ if (x->f.buf == NULL)
+ err(EINVAL, "Work buffer not initialised");
+
+ x->argv0 = argv[0];
+ f = &x->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);
set_cmd_args(argc, argv);
- i = &nv->i;
- cmd = &nv->cmd[*i];
+ i = &x->i;
+ cmd = &x->cmd[*i];
#ifdef NVMUTIL_UNVEIL
- if (cmd->flags == O_RDONLY) {
- if (unveil(fname, "r") == -1)
- err(errno, "%s: unveil r", fname);
+ if ((cmd->flags & O_ACCMODE) == O_RDONLY) {
+ 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)
@@ -244,7 +259,7 @@ main(int argc, char *argv[])
run_cmd();
- if (cmd->flags == O_RDWR)
+ if ((cmd->flags & O_ACCMODE) == O_RDWR)
write_to_gbe_bin();
if (exit_cleanup() == -1)
@@ -266,7 +281,7 @@ void
sanitize_command_list(void)
{
unsigned long c;
- unsigned long num_commands = items(nv->cmd);
+ unsigned long num_commands = items(x->cmd);
for (c = 0; c < num_commands; c++)
sanitize_command_index(c);
@@ -280,7 +295,9 @@ sanitize_command_index(unsigned long c)
{
unsigned long gbe_rw_size;
- struct commands *cmd = &nv->cmd[c];
+ struct commands *cmd = &x->cmd[c];
+
+ int _flag;
check_command_num(c);
@@ -325,8 +342,10 @@ sanitize_command_index(unsigned long c)
err(EINVAL, "rw_size larger than GbE part: %lu",
(unsigned long)gbe_rw_size);
- if (cmd->flags != O_RDONLY &&
- cmd->flags != O_RDWR)
+ _flag = (cmd->flags & O_ACCMODE);
+
+ if (_flag != O_RDONLY &&
+ _flag != O_RDWR)
err(EINVAL, "invalid cmd.flags setting");
}
@@ -337,18 +356,18 @@ set_cmd(int argc, char *argv[])
unsigned long i = 0;
- for (i = 0; i < items(nv->cmd); i++) {
+ for (i = 0; i < items(x->cmd); i++) {
- cmd = nv->cmd[i].str;
+ cmd = x->cmd[i].str;
/* not the right command */
if (xstrxcmp(argv[2], cmd, MAX_CMD_LEN) != 0)
continue;
/* valid command found */
- if (argc >= nv->cmd[i].argc) {
- nv->no_cmd = 0;
- nv->i = i; /* set command */
+ if (argc >= x->cmd[i].argc) {
+ x->no_cmd = 0;
+ x->i = i; /* set command */
return;
}
@@ -357,7 +376,7 @@ set_cmd(int argc, char *argv[])
"Too few args on command '%s'", cmd);
}
- nv->no_cmd = 1;
+ x->no_cmd = 1;
}
void
@@ -369,16 +388,16 @@ set_cmd_args(int argc, char *argv[])
struct xfile *f;
struct commands *cmd;
- if (!valid_command(nv->i) || argc < 3)
+ if (!valid_command(x->i) || argc < 3)
usage();
- if (nv->no_cmd)
+ if (x->no_cmd)
usage();
- i = nv->i;
- f = &nv->f;
+ i = x->i;
+ f = &x->f;
- cmd = &nv->cmd[i];
+ cmd = &x->cmd[i];
arg_part = cmd->arg_part;
@@ -394,9 +413,9 @@ set_cmd_args(int argc, char *argv[])
if (i == CMD_SETMAC) {
if (argc >= 4)
- nv->mac.str = argv[3];
+ x->mac.str = argv[3];
else
- nv->mac.str = nv->mac.rmac;
+ x->mac.str = x->mac.rmac;
} else if (arg_part) {
@@ -467,11 +486,11 @@ open_gbe_file(void)
struct stat _st;
int _flags;
- unsigned long *i = &nv->i;
+ unsigned long *i = &x->i;
- struct commands *cmd = &nv->cmd[*i];
+ struct commands *cmd = &x->cmd[*i];
- struct xfile *f = &nv->f;
+ struct xfile *f = &x->f;
xopen(&f->gbe_fd, f->fname,
cmd->flags | O_BINARY |
@@ -513,19 +532,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;
@@ -583,7 +601,7 @@ xopen(int *fd_ptr, const char *path, int flags, struct stat *st)
void
copy_gbe(void)
{
- struct xfile *f = &nv->f;
+ struct xfile *f = &x->f;
read_file();
@@ -611,7 +629,7 @@ read_file(void)
long _r;
struct stat _st;
- struct xfile *f = &nv->f;
+ struct xfile *f = &x->f;
/* read main file */
_r = rw_file_exact(f->gbe_fd, f->buf, f->gbe_file_size,
@@ -671,8 +689,8 @@ read_checksums(void)
unsigned char _num_invalid;
unsigned char _max_invalid;
- struct xfile *f = &nv->f;
- struct commands *cmd = &nv->cmd[nv->i];
+ struct xfile *f = &x->f;
+ struct commands *cmd = &x->cmd[x->i];
f->part_valid[0] = 0;
f->part_valid[1] = 0;
@@ -728,18 +746,18 @@ good_checksum(unsigned long partnum)
void
run_cmd(void)
{
- unsigned long cmd_num;
- struct commands *cmd;
+ unsigned long i = x->i;
+ void (*run)(void) = x->cmd[i].run;
- cmd_num = nv->i;
- cmd = &nv->cmd[cmd_num];
+ check_command_num(i);
- check_command_num(cmd_num);
+ if (run == NULL)
+ err(EINVAL, "Command %lu: null ptr", i);
- if (cmd->run == NULL)
- err(EINVAL, "Command %lu: null ptr", cmd_num);
+ run();
- cmd->run();
+ for (i = 0; i < items(x->cmd); i++)
+ x->cmd[i].run = cmd_helper_err;
}
void
@@ -755,10 +773,10 @@ valid_command(unsigned long c)
{
struct commands *cmd;
- if (c >= items(nv->cmd))
+ if (c >= items(x->cmd))
return 0;
- cmd = &nv->cmd[c];
+ cmd = &x->cmd[c];
if (c != cmd->chk)
err(EINVAL,
@@ -772,7 +790,9 @@ void
cmd_helper_setmac(void)
{
unsigned long partnum;
- struct macaddr *mac = &nv->mac;
+ struct macaddr *mac = &x->mac;
+
+ check_cmd(cmd_helper_setmac, "setmac");
printf("MAC address to be written: %s\n", mac->str);
parse_mac_string();
@@ -786,9 +806,9 @@ parse_mac_string(void)
{
unsigned long mac_byte;
- struct macaddr *mac = &nv->mac;
+ struct macaddr *mac = &x->mac;
- if (xstrxlen(nv->mac.str, 18) != 17)
+ if (xstrxlen(x->mac.str, 18) != 17)
err(EINVAL, "MAC address is the wrong length");
memset(mac->mac_buf, 0, sizeof(mac->mac_buf));
@@ -837,7 +857,7 @@ set_mac_byte(unsigned long mac_byte_pos)
unsigned long mac_nib_pos;
char separator;
- struct macaddr *mac = &nv->mac;
+ struct macaddr *mac = &x->mac;
if (mac_str_pos < 15) {
if ((separator = mac->str[mac_str_pos + 2]) != ':')
@@ -856,7 +876,7 @@ set_mac_nib(unsigned long mac_str_pos,
char mac_ch;
unsigned short hex_num;
- struct macaddr *mac = &nv->mac;
+ struct macaddr *mac = &x->mac;
mac_ch = mac->str[mac_str_pos + mac_nib_pos];
@@ -1020,8 +1040,8 @@ write_mac_part(unsigned long partnum)
{
unsigned long w;
- struct xfile *f = &nv->f;
- struct macaddr *mac = &nv->mac;
+ struct xfile *f = &x->f;
+ struct macaddr *mac = &x->mac;
check_bin(partnum, "part number");
if (!f->part_valid[partnum])
@@ -1040,7 +1060,9 @@ cmd_helper_dump(void)
{
unsigned long partnum;
- struct xfile *f = &nv->f;
+ struct xfile *f = &x->f;
+
+ check_cmd(cmd_helper_dump, "dump");
f->part_valid[0] = good_checksum(0);
f->part_valid[1] = good_checksum(1);
@@ -1102,7 +1124,9 @@ hexdump(unsigned long partnum)
void
cmd_helper_swap(void)
{
- struct xfile *f = &nv->f;
+ struct xfile *f = &x->f;
+
+ check_cmd(cmd_helper_swap, "swap");
x_v_memcpy(
f->buf + (unsigned long)GBE_WORK_SIZE,
@@ -1126,7 +1150,9 @@ cmd_helper_swap(void)
void
cmd_helper_copy(void)
{
- struct xfile *f = &nv->f;
+ struct xfile *f = &x->f;
+
+ check_cmd(cmd_helper_copy, "copy");
x_v_memcpy(
f->buf + (unsigned long)((f->part ^ 1) * GBE_PART_SIZE),
@@ -1137,34 +1163,76 @@ cmd_helper_copy(void)
}
void
-cmd_helper_cat(void)
+cmd_helper_cat(void) {
+ check_cmd(cmd_helper_cat, "cat");
+
+ x->cat = 0;
+ cat(0);
+}
+
+void
+cmd_helper_cat16(void) {
+ check_cmd(cmd_helper_cat16, "cat16");
+
+ x->cat = 1;
+ cat(1);
+}
+
+void
+cmd_helper_cat128(void) {
+ check_cmd(cmd_helper_cat128, "cat128");
+
+ x->cat = 15;
+ cat(15);
+}
+
+void
+check_cmd(void (*fn)(void), const char *name)
+{
+ unsigned long i;
+
+ if (x->cmd[x->i].run != fn)
+ err(ECANCELED, "Running %s, but cmd %s is set",
+ name, x->cmd[x->i].str);
+
+ /*
+ * In addition to making sure we ran
+ * the right command, we now disable
+ * all commands from running again
+ *
+ * the _nop function will just call
+ * err() immediately
+ */
+
+ for (i = 0; i < items(x->cmd); i++)
+ x->cmd[i].run = cmd_helper_err;
+}
+
+void
+cmd_helper_err(void)
+{
+ err(ECANCELED, "Erroneously running command twice");
+}
+
+void
+cat(unsigned long nff)
{
- struct xfile *f = &nv->f;
+ struct xfile *f = &x->f;
+ struct commands *cmd = &x->cmd[x->i];
unsigned long p = 0;
unsigned long ff = 0;
- unsigned long nff = 0;
- unsigned long cmd_num = nv->i;
+ if ((unsigned long)x->cat != nff ||
+ !((cmd->run == cmd_helper_cat && nff == 0) ||
+ (cmd->run == cmd_helper_cat16 && nff == 1) ||
+ (cmd->run == cmd_helper_cat128 && nff == 15)))
+ err(ECANCELED, "erroneous call to cat");
fflush(NULL);
memset(f->pad, 0xff, GBE_PART_SIZE);
- switch (cmd_num) {
- case CMD_CAT:
- nff = 0;
- break;
- case CMD_CAT16:
- nff = 1;
- break;
- case CMD_CAT128:
- nff = 15;
- break;
- default:
- err(EINVAL, "erroneous call to cat");
- }
-
for (p = 0; p < 2; p++) {
cat_buf(f->bufcmp +
(unsigned long)(p * (f->gbe_file_size >> 1)));
@@ -1177,6 +1245,13 @@ cmd_helper_cat(void)
void
cat_buf(unsigned char *b)
{
+ struct commands *cmd = &x->cmd[x->i];
+
+ if (!((cmd->run == cmd_helper_cat && x->cat == 0) ||
+ (cmd->run == cmd_helper_cat16 && x->cat == 1) ||
+ (cmd->run == cmd_helper_cat128 && x->cat == 15)))
+ err(ECANCELED, "erroneous call to cat");
+
if (rw_file_exact(STDOUT_FILENO, b,
GBE_PART_SIZE, 0, IO_WRITE, LOOP_EAGAIN, LOOP_EINTR,
MAX_ZERO_RW_RETRY, OFF_ERR) < 0)
@@ -1192,10 +1267,10 @@ write_gbe_file(void)
unsigned long p;
unsigned char update_checksum;
- struct commands *cmd = &nv->cmd[nv->i];
- struct xfile *f = &nv->f;
+ struct commands *cmd = &x->cmd[x->i];
+ struct xfile *f = &x->f;
- if (cmd->flags == O_RDONLY)
+ if ((cmd->flags & O_ACCMODE) == O_RDONLY)
return;
if (fstat(f->gbe_fd, &_gbe_st) == -1)
@@ -1259,7 +1334,7 @@ calculated_checksum(unsigned long p)
unsigned short
nvm_word(unsigned long pos16, unsigned long p)
{
- struct xfile *f = &nv->f;
+ struct xfile *f = &x->f;
unsigned long pos;
@@ -1273,7 +1348,7 @@ nvm_word(unsigned long pos16, unsigned long p)
void
set_nvm_word(unsigned long pos16, unsigned long p, unsigned short val16)
{
- struct xfile *f = &nv->f;
+ struct xfile *f = &x->f;
unsigned long pos;
check_nvm_bound(pos16, p);
@@ -1288,7 +1363,7 @@ set_nvm_word(unsigned long pos16, unsigned long p, unsigned short val16)
void
set_part_modified(unsigned long p)
{
- struct xfile *f = &nv->f;
+ struct xfile *f = &x->f;
check_bin(p, "part number");
f->part_modified[p] = 1;
@@ -1322,8 +1397,8 @@ void
rw_gbe_file_part(unsigned long p, int rw_type,
const char *rw_type_str)
{
- struct xfile *f = &nv->f;
- struct commands *cmd = &nv->cmd[nv->i];
+ struct xfile *f = &x->f;
+ struct commands *cmd = &x->cmd[x->i];
long r;
unsigned long gbe_rw_size;
@@ -1356,14 +1431,14 @@ rw_gbe_file_part(unsigned long p, int rw_type,
void
write_to_gbe_bin(void)
{
- struct xfile *f = &nv->f;
+ struct xfile *f = &x->f;
int saved_errno;
int mv;
- struct commands *cmd = &nv->cmd[nv->i];
+ struct commands *cmd = &x->cmd[x->i];
- if (cmd->flags != O_RDWR)
+ if ((cmd->flags & O_ACCMODE) != O_RDWR)
return;
write_gbe_file();
@@ -1448,8 +1523,8 @@ write_to_gbe_bin(void)
void
check_written_part(unsigned long p)
{
- struct commands *cmd = &nv->cmd[nv->i];
- struct xfile *f = &nv->f;
+ struct commands *cmd = &x->cmd[x->i];
+ struct xfile *f = &x->f;
unsigned long gbe_rw_size;
unsigned char *mem_offset;
@@ -1507,7 +1582,7 @@ check_written_part(unsigned long p)
void
report_io_err_rw(void)
{
- struct xfile *f = &nv->f;
+ struct xfile *f = &x->f;
unsigned long p;
@@ -1562,7 +1637,7 @@ report_io_err_rw(void)
int
gbe_mv(void)
{
- struct xfile *f = &nv->f;
+ struct xfile *f = &x->f;
int r;
int saved_errno;
@@ -1796,7 +1871,7 @@ err_fsync_dir:
unsigned char *
gbe_mem_offset(unsigned long p, const char *f_op)
{
- struct xfile *f = &nv->f;
+ struct xfile *f = &x->f;
off_t gbe_off = gbe_x_offset(p, f_op, "mem",
GBE_PART_SIZE, GBE_WORK_SIZE);
@@ -1814,7 +1889,7 @@ gbe_mem_offset(unsigned long p, const char *f_op)
off_t
gbe_file_offset(unsigned long p, const char *f_op)
{
- struct xfile *f = &nv->f;
+ struct xfile *f = &x->f;
off_t gbe_file_half_size = f->gbe_file_size >> 1;
@@ -1826,7 +1901,7 @@ off_t
gbe_x_offset(unsigned long p, const char *f_op, const char *d_type,
off_t nsize, off_t ncmp)
{
- struct xfile *f = &nv->f;
+ struct xfile *f = &x->f;
off_t off;
@@ -1849,7 +1924,7 @@ long
rw_gbe_file_exact(int fd, unsigned char *mem, unsigned long nrw,
off_t off, int rw_type)
{
- struct xfile *f = &nv->f;
+ struct xfile *f = &x->f;
long r;
@@ -2340,8 +2415,6 @@ usage(void)
void
err(int nvm_errval, const char *msg, ...)
{
- struct xfile *f = &nv->f;
-
va_list args;
if (errno == 0)
@@ -2357,12 +2430,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);
}
@@ -2370,28 +2438,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 (x != NULL) {
+ f = &x->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;
@@ -2407,15 +2479,15 @@ getnvmprogname(void)
{
const char *p;
- if (nv->argv0 == NULL || *nv->argv0 == '\0')
+ if (x->argv0 == NULL || *x->argv0 == '\0')
return "";
- p = x_c_strrchr(nv->argv0, '/');
+ p = x_c_strrchr(x->argv0, '/');
if (p)
return p + 1;
else
- return nv->argv0;
+ return x->argv0;
}
/*
@@ -2445,8 +2517,6 @@ getnvmprogname(void)
char *
new_tmpfile(int *fd, int local, const char *path)
{
- struct xfile *f = &nv->f;
-
unsigned long maxlen;
struct stat st;
@@ -2563,7 +2633,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)
@@ -2582,10 +2665,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;
@@ -2594,19 +2673,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;
diff --git a/util/nvmutil/nvmutil.h b/util/nvmutil/nvmutil.h
index 831c161a..ce38772c 100644
--- a/util/nvmutil/nvmutil.h
+++ b/util/nvmutil/nvmutil.h
@@ -4,6 +4,11 @@
* Copyright (c) 2022-2026 Leah Rowe <leah@libreboot.org>
*/
+/* Use this shorthand in cmd helpers. e.g.
+ in cmd_setmac function:
+ check_cmd(cmd_helper_cat);
+*/
+
#ifndef NVMUTIL_H
#define NVMUTIL_H
@@ -66,6 +71,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
@@ -286,6 +295,10 @@ struct xstate {
/* store size of a struct here.
(can be used to copy old state) */
unsigned long xsize;
+
+ /* Cat commands set this.
+ the cat cmd helpers check it */
+ int cat;
};
@@ -311,7 +324,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);
/*
@@ -370,8 +383,14 @@ void cmd_helper_copy(void);
* cat, cat16 and cat128
*/
void cmd_helper_cat(void);
+void cmd_helper_cat16(void);
+void cmd_helper_cat128(void);
+void cat(unsigned long nff);
void cat_buf(unsigned char *b);
+void check_cmd(void (*fn)(void), const char *name);
+void cmd_helper_err(void);
+
/*
* After command processing, write
* the modified GbE file back.