Compute the SHA-256 of a file in-process (no external hashing tool — those * differ per OS, may be absent, and mis-quote paths under cmd.exe). Writes a * 64-char hex digest + NUL to out. Returns 0 on success. Not static: * exercised directly by the self-update checksum regression test. */
| 6767 | * 64-char hex digest + NUL to out. Returns 0 on success. Not static: |
| 6768 | * exercised directly by the self-update checksum regression test. */ |
| 6769 | int cbm_cli_sha256_file(const char *path, char *out, size_t out_size) { |
| 6770 | if (out_size < SHA256_BUF_SIZE) { |
| 6771 | return CLI_ERR; |
| 6772 | } |
| 6773 | FILE *fp = cbm_fopen(path, "rb"); |
| 6774 | if (!fp) { |
| 6775 | return CLI_ERR; |
| 6776 | } |
| 6777 | cbm_sha256_ctx ctx; |
| 6778 | cbm_sha256_init(&ctx); |
| 6779 | unsigned char buf[CLI_BUF_1K]; |
| 6780 | size_t n; |
| 6781 | while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) { |
| 6782 | cbm_sha256_update(&ctx, buf, n); |
| 6783 | } |
| 6784 | int read_err = ferror(fp); |
| 6785 | fclose(fp); |
| 6786 | if (read_err) { |
| 6787 | return CLI_ERR; |
| 6788 | } |
| 6789 | uint8_t digest[CBM_SHA256_DIGEST_LEN]; |
| 6790 | cbm_sha256_final(&ctx, digest); |
| 6791 | static const char hex[] = "0123456789abcdef"; |
| 6792 | for (int i = 0; i < CBM_SHA256_DIGEST_LEN; i++) { |
| 6793 | out[i * 2] = hex[digest[i] >> 4]; |
| 6794 | out[i * 2 + 1] = hex[digest[i] & 0x0f]; |
| 6795 | } |
| 6796 | out[SHA256_HEX_LEN] = '\0'; |
| 6797 | return 0; |
| 6798 | } |
| 6799 | |
| 6800 | static int cli_checksum_hex_nibble(unsigned char value) { |
| 6801 | if (value >= (unsigned char)'0' && value <= (unsigned char)'9') { |