|
14 | 14 |
|
15 | 15 | #include "htool_payload.h" |
16 | 16 |
|
| 17 | +#include <errno.h> |
| 18 | +#include <fcntl.h> |
17 | 19 | #include <stdio.h> |
18 | 20 | #include <stdlib.h> |
| 21 | +#include <string.h> |
| 22 | +#include <sys/mman.h> |
| 23 | +#include <sys/stat.h> |
| 24 | +#include <sys/types.h> |
| 25 | +#include <unistd.h> |
19 | 26 |
|
20 | 27 | #include "host_commands.h" |
21 | 28 | #include "htool.h" |
| 29 | +#include "protocol/payload_info.h" |
22 | 30 | #include "protocol/payload_status.h" |
23 | 31 |
|
24 | 32 | int htool_payload_status() { |
@@ -68,3 +76,69 @@ int htool_payload_status() { |
68 | 76 | } |
69 | 77 | return 0; |
70 | 78 | } |
| 79 | + |
| 80 | +int htool_payload_info(const struct htool_invocation* inv) { |
| 81 | + struct libhoth_device* dev = htool_libhoth_device(); |
| 82 | + if (!dev) { |
| 83 | + return -1; |
| 84 | + } |
| 85 | + |
| 86 | + const char* image_file; |
| 87 | + if (htool_get_param_string(inv, "source-file", &image_file) != 0) { |
| 88 | + return -1; |
| 89 | + } |
| 90 | + |
| 91 | + int fd = open(image_file, O_RDONLY, 0); |
| 92 | + if (fd == -1) { |
| 93 | + fprintf(stderr, "Error opening file %s: %s\n", image_file, strerror(errno)); |
| 94 | + return -1; |
| 95 | + } |
| 96 | + struct stat statbuf; |
| 97 | + if (fstat(fd, &statbuf)) { |
| 98 | + fprintf(stderr, "fstat error: %s\n", strerror(errno)); |
| 99 | + goto cleanup2; |
| 100 | + } |
| 101 | + if (statbuf.st_size > SIZE_MAX) { |
| 102 | + fprintf(stderr, "file too large\n"); |
| 103 | + goto cleanup2; |
| 104 | + } |
| 105 | + |
| 106 | + uint8_t* image = mmap(NULL, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); |
| 107 | + if (image == MAP_FAILED) { |
| 108 | + fprintf(stderr, "mmap error: %s\n", strerror(errno)); |
| 109 | + goto cleanup2; |
| 110 | + } |
| 111 | + |
| 112 | + struct payload_info info; |
| 113 | + if (!libhoth_payload_info(image, statbuf.st_size, &info)) { |
| 114 | + fprintf(stderr, "Failed to parse payload image. Is this a titan image?\n"); |
| 115 | + goto cleanup; |
| 116 | + } |
| 117 | + |
| 118 | + printf("Payload Info:\n"); |
| 119 | + printf(" name: %-32s\n", info.image_name); |
| 120 | + printf(" family: %u\n", info.image_family); |
| 121 | + printf(" version: %u.%u.%u.%u\n", info.image_version.major, |
| 122 | + info.image_version.minor, info.image_version.point, |
| 123 | + info.image_version.subpoint); |
| 124 | + printf(" type: %u\n", info.image_type); |
| 125 | + printf(" hash: "); |
| 126 | + for (int i = 0; i < sizeof(info.image_hash); i++) { |
| 127 | + printf("%02x", info.image_hash[i]); |
| 128 | + } |
| 129 | + printf("\n"); |
| 130 | + |
| 131 | +cleanup: |
| 132 | + if(munmap(image, statbuf.st_size) != 0) { |
| 133 | + fprintf(stderr, "munmap error: %s\n", strerror(errno)); |
| 134 | + return -1; |
| 135 | + } |
| 136 | + |
| 137 | +cleanup2: |
| 138 | + if (close(fd) != 0) { |
| 139 | + fprintf(stderr, "close error: %s\n", strerror(errno)); |
| 140 | + return -1; |
| 141 | + } |
| 142 | + |
| 143 | + return 0; |
| 144 | +} |
0 commit comments