Skip to content

Commit

Permalink
Return more nuanced exit codes
Browse files Browse the repository at this point in the history
Follow the (BSD) sysexit.h definitions.

Signed-off-by: Tormod Volden <[email protected]>
  • Loading branch information
tormodvolden committed Nov 22, 2020
1 parent 689d5e3 commit dbe170a
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 54 deletions.
24 changes: 12 additions & 12 deletions src/dfu_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ void dfu_load_file(struct dfu_file *file, enum suffix_req check_suffix, enum pre
while (read_bytes == STDIN_CHUNK_SIZE) {
file->firmware = (uint8_t*) realloc(file->firmware, file->size.total + STDIN_CHUNK_SIZE);
if (!file->firmware)
err(EX_IOERR, "Could not allocate firmware buffer");
err(EX_SOFTWARE, "Could not allocate firmware buffer");
read_bytes = fread(file->firmware + file->size.total, 1, STDIN_CHUNK_SIZE, stdin);
file->size.total += read_bytes;
}
Expand All @@ -229,20 +229,20 @@ void dfu_load_file(struct dfu_file *file, enum suffix_req check_suffix, enum pre

f = open(file->name, O_RDONLY | O_BINARY);
if (f < 0)
err(EX_IOERR, "Could not open file %s for reading", file->name);
err(EX_NOINPUT, "Could not open file %s for reading", file->name);

offset = lseek(f, 0, SEEK_END);

if (offset < 0)
err(EX_IOERR, "File size is too big");
err(EX_SOFTWARE, "File size is too big");

if (lseek(f, 0, SEEK_SET) != 0)
err(EX_IOERR, "Could not seek to beginning");

file->size.total = offset;

if (file->size.total > SSIZE_MAX) {
err(EX_IOERR, "File too large for memory allocation on this platform");
err(EX_SOFTWARE, "File too large for memory allocation on this platform");
}
file->firmware = dfu_malloc(file->size.total);

Expand Down Expand Up @@ -314,12 +314,12 @@ void dfu_load_file(struct dfu_file *file, enum suffix_req check_suffix, enum pre
file->size.suffix = dfusuffix[11];

if (file->size.suffix < DFU_SUFFIX_LENGTH) {
errx(EX_IOERR, "Unsupported DFU suffix length %d",
errx(EX_DATAERR, "Unsupported DFU suffix length %d",
file->size.suffix);
}

if (file->size.suffix > file->size.total) {
errx(EX_IOERR, "Invalid DFU suffix length %d",
errx(EX_DATAERR, "Invalid DFU suffix length %d",
file->size.suffix);
}

Expand All @@ -331,23 +331,23 @@ void dfu_load_file(struct dfu_file *file, enum suffix_req check_suffix, enum pre
if (missing_suffix) {
if (check_suffix == NEEDS_SUFFIX) {
warnx("%s", reason);
errx(EX_IOERR, "Valid DFU suffix needed");
errx(EX_DATAERR, "Valid DFU suffix needed");
} else if (check_suffix == MAYBE_SUFFIX) {
warnx("Warning: %s", reason);
warnx("A valid DFU suffix will be required in "
"a future dfu-util release!!!");
}
} else {
if (check_suffix == NO_SUFFIX) {
errx(EX_SOFTWARE, "Please remove existing DFU suffix before adding a new one.\n");
errx(EX_DATAERR, "Please remove existing DFU suffix before adding a new one.\n");
}
}
}
res = probe_prefix(file);
if ((res || file->size.prefix == 0) && check_prefix == NEEDS_PREFIX)
errx(EX_IOERR, "Valid DFU prefix needed");
errx(EX_DATAERR, "Valid DFU prefix needed");
if (file->size.prefix && check_prefix == NO_PREFIX)
errx(EX_IOERR, "A prefix already exists, please delete it first");
errx(EX_DATAERR, "A prefix already exists, please delete it first");
if (file->size.prefix && verbose) {
uint8_t *data = file->firmware;
if (file->prefix_type == LMDFU_PREFIX)
Expand All @@ -364,7 +364,7 @@ void dfu_load_file(struct dfu_file *file, enum suffix_req check_suffix, enum pre
"Payload length: %d kiByte\n",
data[2] >>1 | (data[3] << 7) );
else
errx(EX_IOERR, "Unknown DFU prefix type");
errx(EX_DATAERR, "Unknown DFU prefix type");
}
}

Expand All @@ -375,7 +375,7 @@ void dfu_store_file(struct dfu_file *file, int write_suffix, int write_prefix)

f = open(file->name, O_WRONLY | O_BINARY | O_TRUNC | O_CREAT, 0666);
if (f < 0)
err(EX_IOERR, "Could not open file %s for writing", file->name);
err(EX_CANTCREAT, "Could not open file %s for writing", file->name);

/* write prefix, if any */
if (write_prefix) {
Expand Down
38 changes: 19 additions & 19 deletions src/dfuse.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ static void dfuse_parse_options(const char *options)
dfuse_address = number;
dfuse_address_present = 1;
} else {
errx(EX_IOERR, "Invalid dfuse address: %s", options);
errx(EX_USAGE, "Invalid dfuse address: %s", options);
}
options = endword;
}
Expand Down Expand Up @@ -116,7 +116,7 @@ static void dfuse_parse_options(const char *options)
if (end == endword) {
dfuse_length = number;
} else {
errx(EX_IOERR, "Invalid dfuse modifier: %s", options);
errx(EX_USAGE, "Invalid dfuse modifier: %s", options);
}
options = endword;
}
Expand Down Expand Up @@ -190,7 +190,7 @@ static int dfuse_special_command(struct dfu_if *dif, unsigned int address,

segment = find_segment(mem_layout, address);
if (!segment || !(segment->memtype & DFUSE_ERASABLE)) {
errx(EX_IOERR, "Page at 0x%08x can not be erased",
errx(EX_USAGE, "Page at 0x%08x can not be erased",
address);
}
page_size = segment->pagesize;
Expand All @@ -214,7 +214,7 @@ static int dfuse_special_command(struct dfu_if *dif, unsigned int address,
buf[0] = 0x92;
length = 1;
} else {
errx(EX_IOERR, "Non-supported special command %d", command);
errx(EX_SOFTWARE, "Non-supported special command %d", command);
}
buf[1] = address & 0xff;
buf[2] = (address >> 8) & 0xff;
Expand Down Expand Up @@ -247,7 +247,7 @@ static int dfuse_special_command(struct dfu_if *dif, unsigned int address,
fprintf(stderr, "state(%u) = %s, status(%u) = %s\n", dst.bState,
dfu_state_to_string(dst.bState), dst.bStatus,
dfu_status_to_string(dst.bStatus));
errx(EX_IOERR, "Wrong state after command \"%s\" download",
errx(EX_PROTOCOL, "Wrong state after command \"%s\" download",
dfuse_command_name[command]);
}
/* STM32F405 lies about mass erase timeout */
Expand Down Expand Up @@ -344,7 +344,7 @@ int dfuse_do_upload(struct dfu_if *dif, int xfer_size, int fd,
segment = find_segment(mem_layout, dfuse_address);
if (!dfuse_force &&
(!segment || !(segment->memtype & DFUSE_READABLE)))
errx(EX_IOERR, "Page at 0x%08x is not readable",
errx(EX_USAGE, "Page at 0x%08x is not readable",
dfuse_address);

if (!upload_limit) {
Expand Down Expand Up @@ -429,7 +429,7 @@ static int dfuse_dnload_element(struct dfu_if *dif, unsigned int dwElementAddres
find_segment(mem_layout, dwElementAddress + dwElementSize - 1);
if (!dfuse_force &&
(!segment || !(segment->memtype & DFUSE_WRITEABLE))) {
errx(EX_IOERR, "Last page at 0x%08x is not writeable",
errx(EX_USAGE, "Last page at 0x%08x is not writeable",
dwElementAddress + dwElementSize - 1);
}

Expand All @@ -446,7 +446,7 @@ static int dfuse_dnload_element(struct dfu_if *dif, unsigned int dwElementAddres
segment = find_segment(mem_layout, address);
if (!dfuse_force &&
(!segment || !(segment->memtype & DFUSE_WRITEABLE))) {
errx(EX_IOERR, "Page at 0x%08x is not writeable",
errx(EX_USAGE, "Page at 0x%08x is not writeable",
address);
}
/* If the location is not in the memory map we skip erasing */
Expand Down Expand Up @@ -527,7 +527,7 @@ static void
dfuse_memcpy(unsigned char *dst, unsigned char **src, int *rem, int size)
{
if (size > *rem) {
errx(EX_IOERR, "Corrupt DfuSe file: "
errx(EX_NOINPUT, "Corrupt DfuSe file: "
"Cannot read %d bytes from %d bytes", size, *rem);
}
if (dst != NULL)
Expand Down Expand Up @@ -591,17 +591,17 @@ static int dfuse_do_dfuse_dnload(struct dfu_if *dif, int xfer_size,
/* Must be larger than a minimal DfuSe header and suffix */
if (rem < (int)(sizeof(dfuprefix) +
sizeof(targetprefix) + sizeof(elementheader))) {
errx(EX_SOFTWARE, "File too small for a DfuSe file");
errx(EX_DATAERR, "File too small for a DfuSe file");
}

dfuse_memcpy(dfuprefix, &data, &rem, sizeof(dfuprefix));

if (strncmp((char *)dfuprefix, "DfuSe", 5)) {
errx(EX_IOERR, "No valid DfuSe signature");
errx(EX_DATAERR, "No valid DfuSe signature");
return -EINVAL;
}
if (dfuprefix[5] != 0x01) {
errx(EX_IOERR, "DFU format revision %i not supported",
errx(EX_DATAERR, "DFU format revision %i not supported",
dfuprefix[5]);
return -EINVAL;
}
Expand All @@ -615,7 +615,7 @@ static int dfuse_do_dfuse_dnload(struct dfu_if *dif, int xfer_size,
printf("parsing DFU image %i\n", image);
dfuse_memcpy(targetprefix, &data, &rem, sizeof(targetprefix));
if (strncmp((char *)targetprefix, "Target", 6)) {
errx(EX_IOERR, "No valid target signature");
errx(EX_DATAERR, "No valid target signature");
return -EINVAL;
}
bAlternateSetting = targetprefix[6];
Expand Down Expand Up @@ -649,7 +649,7 @@ static int dfuse_do_dfuse_dnload(struct dfu_if *dif, int xfer_size,
}
/* sanity check */
if ((int)dwElementSize > rem)
errx(EX_SOFTWARE, "File too small for element size");
errx(EX_DATAERR, "File too small for element size");

if (bAlternateSetting == dif->altsetting) {
ret = dfuse_dnload_element(dif, dwElementAddress,
Expand Down Expand Up @@ -689,17 +689,17 @@ int dfuse_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file,

if (dfuse_unprotect) {
if (!dfuse_force) {
errx(EX_IOERR, "The read unprotect command "
errx(EX_USAGE, "The read unprotect command "
"will erase the flash memory"
"and can only be used with force\n");
}
dfuse_special_command(dif, 0, READ_UNPROTECT);
printf("Device disconnects, erases flash and resets now\n");
exit(0);
exit(EX_OK);
}
if (dfuse_mass_erase) {
if (!dfuse_force) {
errx(EX_IOERR, "The mass erase command "
errx(EX_USAGE, "The mass erase command "
"can only be used with force");
}
printf("Performing mass erase, this can take a moment\n");
Expand All @@ -710,14 +710,14 @@ int dfuse_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file,
ret = 0;
} else if (dfuse_address_present) {
if (file->bcdDFU == 0x11a) {
errx(EX_IOERR, "This is a DfuSe file, not "
errx(EX_USAGE, "This is a DfuSe file, not "
"meant for raw download");
}
ret = dfuse_do_bin_dnload(dif, xfer_size, file, dfuse_address);
} else {
if (file->bcdDFU != 0x11a) {
warnx("Only DfuSe file version 1.1a is supported");
errx(EX_IOERR, "(for raw binary download, use the "
errx(EX_USAGE, "(for raw binary download, use the "
"--dfuse-address option)");
}
ret = dfuse_do_dfuse_dnload(dif, xfer_size, file);
Expand Down
29 changes: 16 additions & 13 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,11 @@ static int parse_number(char *str, char *nmb)

if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
|| (errno != 0 && val == 0) || (*endptr != '\0')) {
errx(EX_SOFTWARE, "Something went wrong with the argument of --%s\n", str);
errx(EX_USAGE, "Something went wrong with the argument of --%s\n", str);
}

if (endptr == nmb) {
errx(EX_SOFTWARE, "No digits were found from the argument of --%s\n", str);
errx(EX_USAGE, "No digits were found from the argument of --%s\n", str);
}

return (int)val;
Expand Down Expand Up @@ -195,7 +195,6 @@ static void help(void)
"\t\tforce\t\tYou really know what you are doing!\n"
"\t\t<length>\tLength of firmware to upload from device\n"
);
exit(EX_USAGE);
}

static void print_version(void)
Expand Down Expand Up @@ -268,6 +267,7 @@ int main(int argc, char **argv)
switch (c) {
case 'h':
help();
exit(EX_OK);
break;
case 'V':
mode = MODE_VERSION;
Expand Down Expand Up @@ -341,17 +341,19 @@ int main(int argc, char **argv)
break;
default:
help();
exit(EX_USAGE);
break;
}
}
if (optind != argc) {
fprintf(stderr, "Error: Unexpected argument: %s\n\n", argv[optind]);
help();
exit(EX_USAGE);
}

print_version();
if (mode == MODE_VERSION) {
exit(0);
exit(EX_OK);
}

#if defined(LIBUSB_API_VERSION) || defined(LIBUSBX_API_VERSION)
Expand All @@ -368,6 +370,7 @@ int main(int argc, char **argv)
if (mode == MODE_NONE && !dfuse_options) {
fprintf(stderr, "You need to specify one of -D or -U\n");
help();
exit(EX_USAGE);
}

if (match_config_index == 0) {
Expand Down Expand Up @@ -414,7 +417,7 @@ int main(int argc, char **argv)

if (mode == MODE_LIST) {
list_dfu_interfaces();
exit(0);
exit(EX_OK);
}

if (dfu_root == NULL) {
Expand Down Expand Up @@ -525,7 +528,7 @@ int main(int argc, char **argv)

if (mode == MODE_DETACH) {
libusb_exit(ctx);
exit(0);
exit(EX_OK);
}

/* keeping handles open might prevent re-enumeration */
Expand All @@ -549,7 +552,7 @@ int main(int argc, char **argv)

/* Check for DFU mode device */
if (!(dfu_root->flags | DFU_IFF_DFU))
errx(EX_SOFTWARE, "Device is not in DFU mode");
errx(EX_PROTOCOL, "Device is not in DFU mode");

printf("Opening DFU USB Device...\n");
ret = libusb_open(dfu_root->dev, &dfu_root->dev_handle);
Expand Down Expand Up @@ -599,7 +602,7 @@ int main(int argc, char **argv)
switch (status.bState) {
case DFU_STATE_appIDLE:
case DFU_STATE_appDETACH:
errx(EX_IOERR, "Device still in Runtime Mode!");
errx(EX_PROTOCOL, "Device still in Runtime Mode!");
break;
case DFU_STATE_dfuERROR:
printf("dfuERROR, clearing status\n");
Expand Down Expand Up @@ -632,7 +635,7 @@ int main(int argc, char **argv)
if (dfu_get_status(dfu_root, &status) < 0)
errx(EX_IOERR, "USB communication error");
if (DFU_STATUS_OK != status.bStatus)
errx(EX_SOFTWARE, "Status is not OK: %d", status.bStatus);
errx(EX_PROTOCOL, "Status is not OK: %d", status.bStatus);

milli_sleep(status.bwPollTimeout);
}
Expand All @@ -655,7 +658,7 @@ int main(int argc, char **argv)
printf("Warning: Overriding device-reported transfer size\n");
} else {
if (!transfer_size)
errx(EX_IOERR, "Transfer size must be specified");
errx(EX_USAGE, "Transfer size must be specified");
}

#ifdef HAVE_GETPAGESIZE
Expand All @@ -679,7 +682,7 @@ int main(int argc, char **argv)
/* open for "exclusive" writing */
fd = open(file.name, O_WRONLY | O_BINARY | O_CREAT | O_EXCL | O_TRUNC, 0666);
if (fd < 0)
err(EX_IOERR, "Cannot open file %s for writing", file.name);
err(EX_CANTCREAT, "Cannot open file %s for writing", file.name);

if (dfuse_device || dfuse_options) {
if (dfuse_do_upload(dfu_root, transfer_size, fd,
Expand All @@ -699,7 +702,7 @@ int main(int argc, char **argv)
(file.idProduct != 0xffff && file.idProduct != runtime_product)) &&
((file.idVendor != 0xffff && file.idVendor != dfu_root->vendor) ||
(file.idProduct != 0xffff && file.idProduct != dfu_root->product))) {
errx(EX_IOERR, "Error: File ID %04x:%04x does "
errx(EX_USAGE, "Error: File ID %04x:%04x does "
"not match device (%04x:%04x or %04x:%04x)",
file.idVendor, file.idProduct,
runtime_vendor, runtime_product,
Expand All @@ -720,7 +723,7 @@ int main(int argc, char **argv)
}
break;
default:
errx(EX_IOERR, "Unsupported mode: %u", mode);
errx(EX_SOFTWARE, "Unsupported mode: %u", mode);
break;
}

Expand Down
Loading

0 comments on commit dbe170a

Please sign in to comment.