Skip to content
Snippets Groups Projects
Commit a7545470 authored by tanguy.cavagna's avatar tanguy.cavagna :desktop:
Browse files

Finished standalone. Need make lib

parent 504f0356
No related branches found
No related tags found
No related merge requests found
...@@ -8,28 +8,24 @@ LIBS = -lssl -lcrypto ...@@ -8,28 +8,24 @@ LIBS = -lssl -lcrypto
BIN = bin BIN = bin
# Get source and object # Get source and object
SRCS = $(filter-out $(wildcard mdtest.c), $(wildcard *.c */*.c)) SRCS = $(filter-out mdtest.c, $(wildcard *.c */*.c))
OBJS = $(addprefix $(BIN)/, $(SRCS:.c=.o)) OBJS = $(addprefix $(BIN)/, $(SRCS:.c=.o))
SRCS_TEST = $(filter-out $(wildcard main.c */main.c gfx/*), $(wildcard *.c */*.c))
OBJS_TEST = $(addprefix $(BIN)/, $(SRCS_TEST:.c=.o)) .PHONY: digest libdigest all clean
# Create the target # Create the target
main: $(OBJS) digest: $(OBJS)
$(CC) $(CFLAGS) -o $(BIN)/$@ $^ $(LIBS) $(LDFLAGS) $(CC) $(CFLAGS) -o $(BIN)/digest $(addprefix $(BIN)/, $(notdir $^)) $(LIBS) $(LDFLAGS)
./$(BIN)/$@ $(ARGS)
# Convert the source in object, but before all, run `$(BIN)` aka mkdir # Convert the source in object
$(BIN)/%.o: %.c $(BIN)/%.o: %.c
mkdir -p $(@D) mkdir -p $(BIN)
$(CC) $(CFLAGS) -o $@ -c $< $(LDFLAGS) $(CC) $(CFLAGS) -o $(BIN)/$(notdir $@) -c $< $(LDFLAGS)
# Echo the source and object values # Echo the source and object values
help: help:
@echo "src: $(SRCS)" @echo "src: $(SRCS)"
@echo "obj: $(OBJS)" @echo "obj: $(OBJS)"
@echo "obj_test: $(OBJ_TEST)"
clean: clean:
rm -rf $(BIN) rm -rf $(BIN)
.PHONY: test-draw help clean main
#include "digest.h"
#define BUF_MAXSIZE 4096
//=========================
// PRIVATE
//=========================
/**
* @brief Stringify the given bytes digest
*
* @param md_len
* @param md_value
* @return char*
*/
static char *stringify_digest(unsigned int md_len, unsigned char md_value[]) {
size_t hexlen = 2;
size_t outdigestlen = md_len * hexlen;
char *digest = malloc(outdigestlen + 1);
char *hex = digest;
for (size_t i = 0; i < md_len; i++) {
hex += sprintf(hex, "%02x", md_value[i]);
}
return digest;
}
/**
* @brief Initialize the EVP context
*
* @param digest_method
* @return EVP_MD_CTX*
*/
EVP_MD_CTX *EVP_context_init(char *digest_method) {
EVP_MD_CTX *mdctx;
const EVP_MD *md;
if (digest_method == NULL) {
fprintf(stderr, "Digest method not provided.\n");
exit(ENOMSG);
}
md = EVP_get_digestbyname(digest_method);
if (md == NULL) {
fprintf(stderr, "Digest method not found.\n");
exit(ENOPROTOOPT);
}
mdctx = EVP_MD_CTX_new();
EVP_DigestInit_ex2(mdctx, md, NULL);
return mdctx;
}
//=========================
// PUBLIC
//=========================
char *str_digest(char *foo, char *digest_method) {
EVP_MD_CTX *mdctx = EVP_context_init(digest_method);
unsigned char md_value[EVP_MAX_MD_SIZE];
unsigned int md_len;
EVP_DigestUpdate(mdctx, foo, strlen(foo));
EVP_DigestFinal_ex(mdctx, md_value, &md_len);
EVP_MD_CTX_free(mdctx);
return stringify_digest(md_len, md_value);
}
char *file_digest(char *filename, char *digest_method) {
EVP_MD_CTX *mdctx = EVP_context_init(digest_method);
unsigned char md_value[EVP_MAX_MD_SIZE];
unsigned int md_len;
FILE *f;
char buf[BUF_MAXSIZE];
// case of STDIN
if (filename == NULL) {
f = stdin;
} else {
if ((f = fopen(filename, "r")) == NULL) {
perror(filename);
exit(ENOENT);
}
}
while (fgets(buf, BUF_MAXSIZE, f) != NULL) {
EVP_DigestUpdate(mdctx, buf, strlen(buf));
}
EVP_DigestFinal_ex(mdctx, md_value, &md_len);
EVP_MD_CTX_free(mdctx);
return stringify_digest(md_len, md_value);
}
#ifndef DIGEST_H #ifndef DIGEST_H
#define DIGEST_H #define DIGEST_H
#include <errno.h>
#include <openssl/evp.h>
#include <string.h>
/**
* @brief Make the digest of the given string
*
* @param foo
* @param digest_method
* @return char*
*/
char *str_digest(char *foo, char *digest_method);
/**
* @brief Make the digest of the given file
*
* @param filename If null, read STDIN
* @param digest_method
* @return char*
*/
char *file_digest(char *filename, char *digest_method);
#endif // DIGEST_H #endif // DIGEST_H
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include "digest/digest.h" #include "digest/digest.h"
#include "options/opt.h" #include "options/opt.h"
/**
* @brief Join an array of string
* @see https://stackoverflow.com/a/4681415
*
* @param foo
* @param count
* @return char*
*/
char *join(char *foo[], int count) {
char *out = NULL;
size_t total_len = 0;
for (int i = 0; i < count; i++)
total_len += strlen(foo[i]);
total_len += count - 1; // seperator
total_len++; // string terminator
out = malloc(total_len);
out[0] = '\0';
for (int i = 0; i < count; i++) {
strcat(out, foo[i]);
if (i < (count - 1))
strcat(out, " ");
}
return out;
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
for (int i = 1; i < argc; i++) { opt *opts = verify_options(argc, argv);
printf("%s\n", argv[i]); char *digest;
switch (opts->flag) {
case W_FLAG:
for (int i = 0; i < opts->extra_count; i++) {
digest = str_digest(opts->extra[i], opts->digest_method);
printf("%s\t%s\n", digest, opts->extra[i]);
free(digest);
}
break;
case F_FLAG:
for (int i = 0; i < opts->extra_count; i++) {
digest = file_digest(opts->extra[i], opts->digest_method);
printf("%s\t%s\n", digest, opts->extra[i]);
free(digest);
}
break;
case S_FLAG:
digest = file_digest(NULL, opts->digest_method);
printf("%s\n", digest);
free(digest);
break;
default:
char *foo = join(opts->extra, opts->extra_count);
digest = str_digest(foo, opts->digest_method);
printf("%s\t%s\n", digest, foo);
free(digest);
break;
} }
discard_options(opts);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
#include "opt.h"
//=========================
// PUBLIC
//=========================
opt *verify_options(int argc, char *argv[]) {
int option;
opt *verified = malloc(sizeof(opt));
verified->flag = 0;
verified->digest_method = NULL;
while ((option = getopt(argc, argv, "wfst:")) != -1) {
// Argument list too long
if (verified->flag != 0 && option != 't') {
printf("Cannot choose mulitple options.\n");
exit(E2BIG);
}
switch (option) {
case 'w':
verified->flag = 1 << 0;
break;
case 'f':
verified->flag = 1 << 1;
break;
case 's':
verified->flag = 1 << 2;
break;
case 't':
// optarg hold the value of the current option
verified->digest_method = optarg;
break;
// Invalid argument
default:
exit(EINVAL);
break;
}
}
if (verified->digest_method == NULL) {
verified->digest_method = "SHA1";
}
verified->extra_count = argc - optind;
verified->extra = malloc(sizeof(char *) * verified->extra_count);
// optind not found in vscode, but the variable simply store the index
// of the first non-argument term passed to the arguments list.
for (int i = optind; i < argc; i++) {
verified->extra[i - optind] = argv[i];
}
return verified;
}
void discard_options(opt *o) {
free(o->extra);
free(o);
}
#ifndef OPT_H #ifndef OPT_H
#define OPT_H #define OPT_H
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define W_FLAG 1 << 0
#define F_FLAG 1 << 1
#define S_FLAG 1 << 2
typedef struct _opt {
char flag;
char **extra;
int extra_count;
char *digest_method; // default SHA1
} opt;
/**
* @brief Verify passed options, and returns the corresponding flag.
*
* -w : 0x1
* -f : 0x2
* -s : 0x4
*
* other : error
*
* @param argc
* @param argv
* @return opt
*/
opt *verify_options(int argc, char *argv[]);
/**
* @brief Discard the given options
*
* @param o
*/
void discard_options(opt *o);
#endif // OPT_H #endif // OPT_H
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment