I am building a git clone and working on the hash-file command. I am currently trying to compute the SHA1 hash of a known string and have this code and the following issue:
#include <openssl/sha.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int hashFile(char *file_name, int ww) {
int i, ret;
size_t size_len;
unsigned long file_size;
char path[56];
unsigned char hash[SHA_DIGEST_LENGTH];
char *token, *type, *blob_content, *content;
FILE *src = fopen(file_name, "r");
if (ferror(src)) {
perror("Unable to read file");
return 1;
}
fseek(src, 0L, SEEK_END);
file_size = ftell(src);
rewind(src);
size_len = snprintf(NULL, 0, "%lu", file_size);
char *buffer = (char *)malloc((size_t)file_size + 1);
fread(buffer, sizeof(char), file_size, src);
buffer[file_size] = '\0';
blob_content = (char *)malloc((7 + sizeof(unsigned long) + file_size + 1) *
sizeof(char));
snprintf(blob_content, 7 + size_len + 1, "blob %lu\\0", file_size);
strcat(blob_content, buffer);
SHA1((unsigned char *)blob_content, strlen(blob_content), hash);
printf("%s\n", hash);
free(blob_content);
free(buffer);
return 0;
}
void printHashHelp() {
printf("usage: twat hash-file [options] <file_name>\n");
printf("\n");
printf("options:\n");
printf("\t-w: write contents to objects store\n");
}
$ clang --std=c17 -fmodules -fprebuilt-module-path=. -I/opt/homebrew/opt/openssl/include cmd.c comp.c init.c cat.c hash.c -o twat -v
...
Undefined symbols for architecture arm64:
"_SHA1", referenced from:
_hashFile in hash-fc3ff3.o
ld: symbol(s) not found for architecture arm64
How should I go about linking and enabling SHA1 to work on the M2 Max? What clang
command should I be using if this is incorrect?
I have been trying different methods of linking openssl/sha.h
and believed to have got it but have not got the function to work currently.
Following: How to use SHA1 hashing in C programming I attempted to use the linked library but got a compiler linking failure.
Append
-L/opt/homebrew/lib -lcrypto
to your command line.
Also, your malloc and snprintf looks weird. The whole +1 and +7 looks error prone
This would be better:
char header[100] = {0}; // 100 is big enough for the entire "blob 12345" thing regardless of how big the file is
SHA1_CTX ctx = {0};
SHA1_Init(&ctx);
sprintf(header, "blob %lu", file_size);
SHA1_Update(&ctx, header, strlen(header));
SHA1_Update(&ctx, buffer, file_size);
SHA1_Final(hash, &ctx);
And then if you really want to be pedantic, make sure you open the file as binary on non-Unix:
#ifdef _WIN32
char* flags = "rb";
#else
char* flags = "r";
#endif
FILE *src = fopen(file_name, flags);