sudo_logsrvd: silence most -Wconversion warnings.

This commit is contained in:
Todd C. Miller
2023-07-07 15:07:04 -06:00
parent 6734a99f8a
commit 4891f37a45
10 changed files with 50 additions and 48 deletions

View File

@@ -170,7 +170,7 @@ evlog_new(TimeSpec *submit_time, InfoMessage **info_msgs, size_t infolen,
errno = ERANGE; errno = ERANGE;
sudo_warn(U_("%s: %s"), source, "columns"); sudo_warn(U_("%s: %s"), source, "columns");
} else { } else {
evlog->columns = info->u.numval; evlog->columns = (int)info->u.numval;
} }
} }
continue; continue;
@@ -193,7 +193,7 @@ evlog_new(TimeSpec *submit_time, InfoMessage **info_msgs, size_t infolen,
errno = ERANGE; errno = ERANGE;
sudo_warn(U_("%s: %s"), source, "lines"); sudo_warn(U_("%s: %s"), source, "lines");
} else { } else {
evlog->lines = info->u.numval; evlog->lines = (int)info->u.numval;
} }
} }
continue; continue;
@@ -242,7 +242,7 @@ evlog_new(TimeSpec *submit_time, InfoMessage **info_msgs, size_t infolen,
errno = ERANGE; errno = ERANGE;
sudo_warn(U_("%s: %s"), source, "rungid"); sudo_warn(U_("%s: %s"), source, "rungid");
} else { } else {
evlog->rungid = info->u.numval; evlog->rungid = (gid_t)info->u.numval;
} }
} }
continue; continue;
@@ -263,7 +263,7 @@ evlog_new(TimeSpec *submit_time, InfoMessage **info_msgs, size_t infolen,
errno = ERANGE; errno = ERANGE;
sudo_warn(U_("%s: %s"), source, "runuid"); sudo_warn(U_("%s: %s"), source, "runuid");
} else { } else {
evlog->runuid = info->u.numval; evlog->runuid = (uid_t)info->u.numval;
} }
} }
continue; continue;
@@ -417,7 +417,7 @@ fill_seq(char *str, size_t strsize, void *v)
sudo_warnx(U_("%s: unable to format session id"), __func__); sudo_warnx(U_("%s: unable to format session id"), __func__);
debug_return_size_t(strsize); /* handle non-standard snprintf() */ debug_return_size_t(strsize); /* handle non-standard snprintf() */
} }
debug_return_size_t(len); debug_return_size_t((size_t)len);
} }
static size_t static size_t
@@ -527,7 +527,7 @@ create_iolog_path(struct connection_closure *closure)
struct eventlog *evlog = closure->evlog; struct eventlog *evlog = closure->evlog;
struct iolog_path_closure path_closure; struct iolog_path_closure path_closure;
char expanded_dir[PATH_MAX], expanded_file[PATH_MAX], pathbuf[PATH_MAX]; char expanded_dir[PATH_MAX], expanded_file[PATH_MAX], pathbuf[PATH_MAX];
size_t len; int len;
debug_decl(create_iolog_path, SUDO_DEBUG_UTIL); debug_decl(create_iolog_path, SUDO_DEBUG_UTIL);
path_closure.evlog = evlog; path_closure.evlog = evlog;
@@ -549,7 +549,7 @@ create_iolog_path(struct connection_closure *closure)
len = snprintf(pathbuf, sizeof(pathbuf), "%s/%s", expanded_dir, len = snprintf(pathbuf, sizeof(pathbuf), "%s/%s", expanded_dir,
expanded_file); expanded_file);
if (len >= sizeof(pathbuf)) { if (len < 0 || len >= ssizeof(pathbuf)) {
errno = ENAMETOOLONG; errno = ENAMETOOLONG;
sudo_warn("%s/%s", expanded_dir, expanded_file); sudo_warn("%s/%s", expanded_dir, expanded_file);
goto bad; goto bad;
@@ -681,14 +681,14 @@ iolog_copy(struct iolog_file *src, struct iolog_file *dst, off_t remainder,
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
"copying %lld bytes", (long long)remainder); "copying %lld bytes", (long long)remainder);
while (remainder > 0) { while (remainder > 0) {
const ssize_t toread = MIN(remainder, ssizeof(buf)); const size_t toread = MIN((size_t)remainder, sizeof(buf));
nread = iolog_read(src, buf, toread, errstr); nread = iolog_read(src, buf, toread, errstr);
if (nread == -1) if (nread == -1)
debug_return_bool(false); debug_return_bool(false);
remainder -= nread; remainder -= nread;
do { do {
ssize_t nwritten = iolog_write(dst, buf, nread, errstr); ssize_t nwritten = iolog_write(dst, buf, (size_t)nread, errstr);
if (nwritten == -1) if (nwritten == -1)
debug_return_bool(false); debug_return_bool(false);
nread -= nwritten; nread -= nwritten;
@@ -753,7 +753,7 @@ iolog_rewrite(const struct timespec *target, struct connection_closure *closure)
evlog->iolog_path, iolog_fd_to_name(timing.event)); evlog->iolog_path, iolog_fd_to_name(timing.event));
goto done; goto done;
} }
iolog_file_sizes[timing.event] += timing.u.nbytes; iolog_file_sizes[timing.event] += (off_t)timing.u.nbytes;
} }
if (sudo_timespeccmp(&closure->elapsed_time, target, >=)) { if (sudo_timespeccmp(&closure->elapsed_time, target, >=)) {

View File

@@ -166,7 +166,7 @@ iolog_seekto(int iolog_dir_fd, const char *iolog_path,
iolog_fd_to_name(timing.event)); iolog_fd_to_name(timing.event));
goto bad; goto bad;
} }
pos = iolog_seek(&iolog_files[timing.event], timing.u.nbytes, pos = iolog_seek(&iolog_files[timing.event], (off_t)timing.u.nbytes,
SEEK_CUR); SEEK_CUR);
if (pos == -1) { if (pos == -1) {
sudo_warn(U_("%s/%s: unable to seek forward %zu"), iolog_path, sudo_warn(U_("%s/%s: unable to seek forward %zu"), iolog_path,

View File

@@ -978,7 +978,7 @@ server_msg_cb(int fd, int what, void *v)
sudo_warn("%s: write", closure->ipaddr); sudo_warn("%s: write", closure->ipaddr);
goto finished; goto finished;
} }
buf->off += nwritten; buf->off += (size_t)nwritten;
if (buf->off == buf->len) { if (buf->off == buf->len) {
/* sent entire message, move buf to free list */ /* sent entire message, move buf to free list */
@@ -1102,7 +1102,7 @@ client_msg_cb(int fd, int what, void *v)
default: default:
break; break;
} }
buf->len += nread; buf->len += (size_t)nread;
while (buf->len - buf->off >= sizeof(msg_len)) { while (buf->len - buf->off >= sizeof(msg_len)) {
/* Read wire message size (uint32_t in network byte order). */ /* Read wire message size (uint32_t in network byte order). */
@@ -1207,7 +1207,7 @@ server_commit_cb(int unused, int what, void *v)
iolog_flush_all(closure); iolog_flush_all(closure);
commit_point.tv_sec = closure->elapsed_time.tv_sec; commit_point.tv_sec = closure->elapsed_time.tv_sec;
commit_point.tv_nsec = closure->elapsed_time.tv_nsec; commit_point.tv_nsec = (int32_t)closure->elapsed_time.tv_nsec;
if (!schedule_commit_point(&commit_point, closure)) if (!schedule_commit_point(&commit_point, closure))
connection_close(closure); connection_close(closure);

View File

@@ -468,7 +468,7 @@ cb_iolog_maxseq(struct logsrvd_config *config, const char *str, size_t offset)
unsigned int value; unsigned int value;
debug_decl(cb_iolog_maxseq, SUDO_DEBUG_UTIL); debug_decl(cb_iolog_maxseq, SUDO_DEBUG_UTIL);
value = sudo_strtonum(str, 0, SESSID_MAX, &errstr); value = (unsigned int)sudo_strtonum(str, 0, SESSID_MAX, &errstr);
if (errstr != NULL) { if (errstr != NULL) {
if (errno != ERANGE) { if (errno != ERANGE) {
sudo_warnx(U_("invalid value for %s: %s"), "maxseq", errstr); sudo_warnx(U_("invalid value for %s: %s"), "maxseq", errstr);
@@ -932,7 +932,7 @@ cb_syslog_maxlen(struct logsrvd_config *config, const char *str, size_t offset)
const char *errstr; const char *errstr;
debug_decl(cb_syslog_maxlen, SUDO_DEBUG_UTIL); debug_decl(cb_syslog_maxlen, SUDO_DEBUG_UTIL);
maxlen = sudo_strtonum(str, 1, UINT_MAX, &errstr); maxlen = (unsigned int)sudo_strtonum(str, 1, UINT_MAX, &errstr);
if (errstr != NULL) if (errstr != NULL)
debug_return_bool(false); debug_return_bool(false);

View File

@@ -90,7 +90,7 @@ journal_fdopen(int fd, const char *journal_path,
} }
static int static int
journal_mkstemp(const char *parent_dir, char *pathbuf, int pathlen) journal_mkstemp(const char *parent_dir, char *pathbuf, size_t pathsize)
{ {
int len, dfd = -1, fd = -1; int len, dfd = -1, fd = -1;
mode_t dirmode, oldmask; mode_t dirmode, oldmask;
@@ -105,9 +105,9 @@ journal_mkstemp(const char *parent_dir, char *pathbuf, int pathlen)
dirmode |= S_IXOTH; dirmode |= S_IXOTH;
oldmask = umask(ACCESSPERMS & ~dirmode); oldmask = umask(ACCESSPERMS & ~dirmode);
len = snprintf(pathbuf, pathlen, "%s/%s/%s", len = snprintf(pathbuf, pathsize, "%s/%s/%s",
logsrvd_conf_relay_dir(), parent_dir, RELAY_TEMPLATE); logsrvd_conf_relay_dir(), parent_dir, RELAY_TEMPLATE);
if (len >= pathlen) { if ((size_t)len >= pathsize) {
errno = ENAMETOOLONG; errno = ENAMETOOLONG;
sudo_warn("%s/%s/%s", logsrvd_conf_relay_dir(), parent_dir, sudo_warn("%s/%s/%s", logsrvd_conf_relay_dir(), parent_dir,
RELAY_TEMPLATE); RELAY_TEMPLATE);
@@ -120,7 +120,7 @@ journal_mkstemp(const char *parent_dir, char *pathbuf, int pathlen)
"unable to create parent dir for %s", pathbuf); "unable to create parent dir for %s", pathbuf);
goto done; goto done;
} }
template = pathbuf + (len - strlen(RELAY_TEMPLATE)); template = &pathbuf[(size_t)len - (sizeof(RELAY_TEMPLATE) - 1)];
if ((fd = mkostempsat(dfd, template, 0, 0)) == -1) { if ((fd = mkostempsat(dfd, template, 0, 0)) == -1) {
sudo_warn(U_("%s: %s"), "mkstemp", pathbuf); sudo_warn(U_("%s: %s"), "mkstemp", pathbuf);
goto done; goto done;

View File

@@ -430,6 +430,8 @@ store_exit_local(ExitMessage *msg, uint8_t *buf, size_t len,
} }
if (closure->log_io) { if (closure->log_io) {
mode_t mode;
/* Store the run time and exit status in log.json. */ /* Store the run time and exit status in log.json. */
if (!store_exit_info_json(closure->iolog_dir_fd, evlog)) { if (!store_exit_info_json(closure->iolog_dir_fd, evlog)) {
closure->errstr = _("error logging exit event"); closure->errstr = _("error logging exit event");
@@ -437,7 +439,7 @@ store_exit_local(ExitMessage *msg, uint8_t *buf, size_t len,
} }
/* Clear write bits from I/O timing file to indicate completion. */ /* Clear write bits from I/O timing file to indicate completion. */
mode_t mode = logsrvd_conf_iolog_mode(); mode = logsrvd_conf_iolog_mode();
CLR(mode, S_IWUSR|S_IWGRP|S_IWOTH); CLR(mode, S_IWUSR|S_IWGRP|S_IWOTH);
if (fchmodat(closure->iolog_dir_fd, "timing", mode, 0) == -1) { if (fchmodat(closure->iolog_dir_fd, "timing", mode, 0) == -1) {
sudo_warn("chmod 0%o %s/%s", (unsigned int)mode, "timing", sudo_warn("chmod 0%o %s/%s", (unsigned int)mode, "timing",
@@ -603,7 +605,7 @@ store_iobuf_local(int iofd, IoBuffer *iobuf, uint8_t *buf, size_t buflen,
/* Write timing data. */ /* Write timing data. */
if (!iolog_write(&closure->iolog_files[IOFD_TIMING], tbuf, if (!iolog_write(&closure->iolog_files[IOFD_TIMING], tbuf,
len, &errstr)) { (size_t)len, &errstr)) {
sudo_warnx(U_("%s/%s: %s"), evlog->iolog_path, sudo_warnx(U_("%s/%s: %s"), evlog->iolog_path,
iolog_fd_to_name(IOFD_TIMING), errstr); iolog_fd_to_name(IOFD_TIMING), errstr);
goto bad; goto bad;
@@ -651,7 +653,7 @@ store_winsize_local(ChangeWindowSize *msg, uint8_t *buf, size_t buflen,
/* Write timing data. */ /* Write timing data. */
if (!iolog_write(&closure->iolog_files[IOFD_TIMING], tbuf, if (!iolog_write(&closure->iolog_files[IOFD_TIMING], tbuf,
len, &errstr)) { (size_t)len, &errstr)) {
sudo_warnx(U_("%s/%s: %s"), closure->evlog->iolog_path, sudo_warnx(U_("%s/%s: %s"), closure->evlog->iolog_path,
iolog_fd_to_name(IOFD_TIMING), errstr); iolog_fd_to_name(IOFD_TIMING), errstr);
goto bad; goto bad;
@@ -686,7 +688,7 @@ store_suspend_local(CommandSuspend *msg, uint8_t *buf, size_t buflen,
/* Write timing data. */ /* Write timing data. */
if (!iolog_write(&closure->iolog_files[IOFD_TIMING], tbuf, if (!iolog_write(&closure->iolog_files[IOFD_TIMING], tbuf,
len, &errstr)) { (size_t)len, &errstr)) {
sudo_warnx(U_("%s/%s: %s"), closure->evlog->iolog_path, sudo_warnx(U_("%s/%s: %s"), closure->evlog->iolog_path,
iolog_fd_to_name(IOFD_TIMING), errstr); iolog_fd_to_name(IOFD_TIMING), errstr);
goto bad; goto bad;

View File

@@ -225,7 +225,7 @@ logsrvd_queue_scan(struct sudo_event_base *evbase)
sudo_warn("%s/outgoing/%s", logsrvd_conf_relay_dir(), RELAY_TEMPLATE); sudo_warn("%s/outgoing/%s", logsrvd_conf_relay_dir(), RELAY_TEMPLATE);
debug_return_bool(false); debug_return_bool(false);
} }
dirlen -= sizeof(RELAY_TEMPLATE) - 1; dirlen -= (int)sizeof(RELAY_TEMPLATE) - 1;
path[dirlen] = '\0'; path[dirlen] = '\0';
dirp = opendir(path); dirp = opendir(path);

View File

@@ -833,7 +833,7 @@ relay_server_msg_cb(int fd, int what, void *v)
default: default:
break; break;
} }
buf->len += nread; buf->len += (size_t)nread;
while (buf->len - buf->off >= sizeof(msg_len)) { while (buf->len - buf->off >= sizeof(msg_len)) {
/* Read wire message size (uint32_t in network byte order). */ /* Read wire message size (uint32_t in network byte order). */
@@ -984,7 +984,7 @@ relay_client_msg_cb(int fd, int what, void *v)
goto send_error; goto send_error;
} }
} }
buf->off += nwritten; buf->off += (size_t)nwritten;
if (buf->off == buf->len) { if (buf->off == buf->len) {
/* sent entire message, move buf to free list */ /* sent entire message, move buf to free list */

View File

@@ -181,7 +181,7 @@ int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{ {
char tempfile[] = "/tmp/logsrvd_conf.XXXXXX"; char tempfile[] = "/tmp/logsrvd_conf.XXXXXX";
size_t nwritten; ssize_t nwritten;
int fd; int fd;
initprogname("fuzz_logsrvd_conf"); initprogname("fuzz_logsrvd_conf");
@@ -193,7 +193,7 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
if (fd == -1) if (fd == -1)
return 0; return 0;
nwritten = write(fd, data, size); nwritten = write(fd, data, size);
if (nwritten != size) { if (nwritten == -1) {
close(fd); close(fd);
return 0; return 0;
} }

View File

@@ -279,7 +279,7 @@ read_io_buf(struct client_closure *closure)
{ {
struct timing_closure *timing = &closure->timing; struct timing_closure *timing = &closure->timing;
const char *errstr = NULL; const char *errstr = NULL;
size_t nread; ssize_t nread;
debug_decl(read_io_buf, SUDO_DEBUG_UTIL); debug_decl(read_io_buf, SUDO_DEBUG_UTIL);
if (!closure->iolog_files[timing->event].enabled) { if (!closure->iolog_files[timing->event].enabled) {
@@ -310,7 +310,7 @@ read_io_buf(struct client_closure *closure)
nread = iolog_read(&closure->iolog_files[timing->event], closure->buf, nread = iolog_read(&closure->iolog_files[timing->event], closure->buf,
timing->u.nbytes, &errstr); timing->u.nbytes, &errstr);
if (nread != timing->u.nbytes) { if (nread == -1) {
sudo_warnx(U_("unable to read %s/%s: %s"), iolog_dir, sudo_warnx(U_("unable to read %s/%s: %s"), iolog_dir,
iolog_fd_to_name(timing->event), errstr); iolog_fd_to_name(timing->event), errstr);
debug_return_bool(false); debug_return_bool(false);
@@ -665,8 +665,8 @@ fmt_reject_message(struct client_closure *closure)
} }
/* Sudo I/O logs only store start time in seconds. */ /* Sudo I/O logs only store start time in seconds. */
tv.tv_sec = closure->evlog->submit_time.tv_sec; tv.tv_sec = (int64_t)closure->evlog->submit_time.tv_sec;
tv.tv_nsec = closure->evlog->submit_time.tv_nsec; tv.tv_nsec = (int32_t)closure->evlog->submit_time.tv_nsec;
reject_msg.submit_time = &tv; reject_msg.submit_time = &tv;
/* Why the command was rejected. */ /* Why the command was rejected. */
@@ -724,8 +724,8 @@ fmt_accept_message(struct client_closure *closure)
} }
/* Sudo I/O logs only store start time in seconds. */ /* Sudo I/O logs only store start time in seconds. */
tv.tv_sec = closure->evlog->submit_time.tv_sec; tv.tv_sec = (int64_t)closure->evlog->submit_time.tv_sec;
tv.tv_nsec = closure->evlog->submit_time.tv_nsec; tv.tv_nsec = (int32_t)closure->evlog->submit_time.tv_nsec;
accept_msg.submit_time = &tv; accept_msg.submit_time = &tv;
/* Client will send IoBuffer messages. */ /* Client will send IoBuffer messages. */
@@ -776,8 +776,8 @@ fmt_restart_message(struct client_closure *closure)
"%s: sending RestartMessage, [%lld, %ld]", __func__, "%s: sending RestartMessage, [%lld, %ld]", __func__,
(long long)closure->restart.tv_sec, closure->restart.tv_nsec); (long long)closure->restart.tv_sec, closure->restart.tv_nsec);
tv.tv_sec = closure->restart.tv_sec; tv.tv_sec = (int64_t)closure->restart.tv_sec;
tv.tv_nsec = closure->restart.tv_nsec; tv.tv_nsec = (int32_t)closure->restart.tv_nsec;
restart_msg.resume_point = &tv; restart_msg.resume_point = &tv;
restart_msg.log_id = (char *)closure->iolog_id; restart_msg.log_id = (char *)closure->iolog_id;
@@ -811,8 +811,8 @@ fmt_exit_message(struct client_closure *closure)
if (evlog->exit_value != -1) if (evlog->exit_value != -1)
exit_msg.exit_value = evlog->exit_value; exit_msg.exit_value = evlog->exit_value;
if (sudo_timespecisset(&evlog->run_time)) { if (sudo_timespecisset(&evlog->run_time)) {
run_time.tv_sec = evlog->run_time.tv_sec; run_time.tv_sec = (int64_t)evlog->run_time.tv_sec;
run_time.tv_nsec = evlog->run_time.tv_nsec; run_time.tv_nsec = (int32_t)evlog->run_time.tv_nsec;
exit_msg.run_time = &run_time; exit_msg.run_time = &run_time;
} }
if (evlog->signal_name != NULL) { if (evlog->signal_name != NULL) {
@@ -863,8 +863,8 @@ fmt_io_buf(int type, struct client_closure *closure)
/* Fill in IoBuffer. */ /* Fill in IoBuffer. */
/* TODO: split buffer if it is too large */ /* TODO: split buffer if it is too large */
delay.tv_sec = closure->timing.delay.tv_sec; delay.tv_sec = (int64_t)closure->timing.delay.tv_sec;
delay.tv_nsec = closure->timing.delay.tv_nsec; delay.tv_nsec = (int32_t)closure->timing.delay.tv_nsec;
iobuf_msg.delay = &delay; iobuf_msg.delay = &delay;
iobuf_msg.data.data = (void *)closure->buf; iobuf_msg.data.data = (void *)closure->buf;
iobuf_msg.data.len = closure->timing.u.nbytes; iobuf_msg.data.len = closure->timing.u.nbytes;
@@ -901,8 +901,8 @@ fmt_winsize(struct client_closure *closure)
debug_decl(fmt_winsize, SUDO_DEBUG_UTIL); debug_decl(fmt_winsize, SUDO_DEBUG_UTIL);
/* Fill in ChangeWindowSize message. */ /* Fill in ChangeWindowSize message. */
delay.tv_sec = timing->delay.tv_sec; delay.tv_sec = (int64_t)timing->delay.tv_sec;
delay.tv_nsec = timing->delay.tv_nsec; delay.tv_nsec = (int32_t)timing->delay.tv_nsec;
winsize_msg.delay = &delay; winsize_msg.delay = &delay;
winsize_msg.rows = timing->u.winsize.lines; winsize_msg.rows = timing->u.winsize.lines;
winsize_msg.cols = timing->u.winsize.cols; winsize_msg.cols = timing->u.winsize.cols;
@@ -938,8 +938,8 @@ fmt_suspend(struct client_closure *closure)
debug_decl(fmt_suspend, SUDO_DEBUG_UTIL); debug_decl(fmt_suspend, SUDO_DEBUG_UTIL);
/* Fill in CommandSuspend message. */ /* Fill in CommandSuspend message. */
delay.tv_sec = timing->delay.tv_sec; delay.tv_sec = (int64_t)timing->delay.tv_sec;
delay.tv_nsec = timing->delay.tv_nsec; delay.tv_nsec = (int32_t)timing->delay.tv_nsec;
suspend_msg.delay = &delay; suspend_msg.delay = &delay;
if (sig2str(timing->u.signo, closure->buf) == -1) if (sig2str(timing->u.signo, closure->buf) == -1)
goto done; goto done;
@@ -1359,7 +1359,7 @@ server_msg_cb(int fd, int what, void *v)
default: default:
break; break;
} }
buf->len += nread; buf->len += (size_t)nread;
while (buf->len - buf->off >= sizeof(msg_len)) { while (buf->len - buf->off >= sizeof(msg_len)) {
/* Read wire message size (uint32_t in network byte order). */ /* Read wire message size (uint32_t in network byte order). */
@@ -1473,7 +1473,7 @@ client_msg_cb(int fd, int what, void *v)
sudo_warn("send"); sudo_warn("send");
goto bad; goto bad;
} }
buf->off += nwritten; buf->off += (size_t)nwritten;
if (buf->off == buf->len) { if (buf->off == buf->len) {
/* sent entire message */ /* sent entire message */
@@ -1742,7 +1742,7 @@ main(int argc, char *argv[])
goto bad; goto bad;
break; break;
case 't': case 't':
nr_of_conns = sudo_strtonum(optarg, 1, INT_MAX, &errstr); nr_of_conns = (int)sudo_strtonum(optarg, 1, INT_MAX, &errstr);
if (errstr != NULL) { if (errstr != NULL) {
sudo_warnx(U_("%s: %s"), optarg, U_(errstr)); sudo_warnx(U_("%s: %s"), optarg, U_(errstr));
goto bad; goto bad;