Advertisement
techno-

md5.c

Mar 3rd, 2023
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.00 KB | None | 0 0
  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <fcntl.h>
  4. #include <dirent.h>
  5. #include <stdlib.h>
  6. #include <unistd.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <errno.h>
  10. #include <openssl/evp.h>
  11. #include <threads.h>
  12.  
  13. #include "options.h"
  14. #include "queue.h"
  15.  
  16.  
  17. #define MAX_PATH 1024
  18. #define BLOCK_SIZE (10*1024*1024)
  19. #define MAX_LINE_LENGTH (MAX_PATH * 2)
  20.  
  21.  
  22. struct file_md5 {
  23.     char *file;
  24.     unsigned char *hash;
  25.     unsigned int hash_size;
  26. };
  27.  
  28. struct thread_get_entries_args{
  29.     int id;
  30.     char *dir;
  31.     queue q;
  32. };
  33.  
  34. struct thread_get_entries_info {
  35.     thrd_t id;
  36.     struct thread_get_entries_args * entries_args;
  37.     cnd_t condicion;
  38. };
  39.  
  40. thrd_t global;
  41.  
  42.  
  43. void get_entries(char *dir, queue q);
  44.  
  45.  
  46. void print_hash(struct file_md5 *md5) {
  47.     for(int i = 0; i < md5->hash_size; i++) {
  48.         printf("%02hhx", md5->hash[i]);
  49.     }
  50. }
  51.  
  52.  
  53. void read_hash_file(char *file, char *dir, queue q) {
  54.     FILE *fp;
  55.     char line[MAX_LINE_LENGTH];
  56.     char *file_name, *hash;
  57.     int hash_len;
  58.  
  59.     if((fp = fopen(file, "r")) == NULL) {
  60.         printf("Could not open %s : %s\n", file, strerror(errno));
  61.         exit(0);
  62.     }
  63.  
  64.     while(fgets(line, MAX_LINE_LENGTH, fp) != NULL) {
  65.         char *field_break;
  66.         struct file_md5 *md5 = malloc(sizeof(struct file_md5));
  67.  
  68.         if((field_break = strstr(line, ": ")) == NULL) {
  69.             printf("Malformed md5 file\n");
  70.             exit(0);
  71.         }
  72.         *field_break = '\0';
  73.  
  74.         file_name = line;
  75.         hash      = field_break + 2;
  76.         hash_len  = strlen(hash);
  77.  
  78.         md5->file      = malloc(strlen(file_name) + strlen(dir) + 2);
  79.         sprintf(md5->file, "%s/%s", dir, file_name);
  80.         md5->hash      = malloc(hash_len / 2);
  81.         md5->hash_size = hash_len / 2;
  82.  
  83.  
  84.         for(int i = 0; i < hash_len; i+=2)
  85.             sscanf(hash + i, "%02hhx", &md5->hash[i / 2]);
  86.         printf("Se llama a q_insert\n");
  87.         q_insert(q, md5);
  88.     }
  89.  
  90.     fclose(fp);
  91. }
  92.  
  93.  
  94. void sum_file(struct file_md5 *md5) {
  95.     EVP_MD_CTX *mdctx;
  96.     int nbytes;
  97.     FILE *fp;
  98.     char *buf;
  99.  
  100.     if((fp = fopen(md5->file, "r")) == NULL) {
  101.         printf("Could not open %s\n", md5->file);
  102.         return;
  103.     }
  104.  
  105.     buf = malloc(BLOCK_SIZE);
  106.     const EVP_MD *md = EVP_get_digestbyname("md5");
  107.  
  108.     mdctx = EVP_MD_CTX_create();
  109.     EVP_DigestInit_ex(mdctx, md, NULL);
  110.  
  111.     while((nbytes = fread(buf, 1, BLOCK_SIZE, fp)) >0)
  112.         EVP_DigestUpdate(mdctx, buf, nbytes);
  113.  
  114.     md5->hash = malloc(EVP_MAX_MD_SIZE);
  115.     EVP_DigestFinal_ex(mdctx, md5->hash, &md5->hash_size);
  116.  
  117.     EVP_MD_CTX_destroy(mdctx);
  118.     free(buf);
  119.     fclose(fp);
  120. }
  121.  
  122.  
  123. void recurse(char *entry, void *arg) {
  124.     queue q = * (queue *) arg;
  125.     struct stat st;
  126.  
  127.     stat(entry, &st);
  128.  
  129.     if(S_ISDIR(st.st_mode))/////
  130.  
  131.         get_entries(entry, q);
  132. }
  133.  
  134.  
  135. void add_files(char *entry, void *arg) {
  136.     queue q = * (queue *) arg;
  137.     struct stat st;
  138.  
  139.     stat(entry, &st);
  140.  
  141.     if(S_ISREG(st.st_mode)) {
  142.         printf("Se llama a q_insert\n");
  143.         q_insert(q, strdup(entry));
  144.  
  145.     }
  146. }
  147.  
  148.  
  149. void walk_dir(char *dir, void (*action)(char *entry, void *arg), void *arg) {
  150.     DIR *d;
  151.     struct dirent *ent;
  152.     char full_path[MAX_PATH];
  153.  
  154.     if((d = opendir(dir)) == NULL) {
  155.         printf("Could not open dir %s\n", dir);
  156.         return;
  157.     }
  158.  
  159.     while((ent = readdir(d)) != NULL) {
  160.         if(strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") ==0)
  161.             continue;
  162.  
  163.         snprintf(full_path, MAX_PATH, "%s/%s", dir, ent->d_name);
  164.  
  165.         action(full_path, arg);
  166.     }
  167.  
  168.     closedir(d);
  169. }
  170.  
  171.  
  172. void get_entries(char *dir, queue q) {
  173.     walk_dir(dir, add_files, &q);
  174.     walk_dir(dir, recurse, &q);
  175. }
  176.  
  177.  
  178. void check(struct options opt) {
  179.     queue in_q;
  180.     struct file_md5 *md5_in, md5_file;
  181.  
  182.     in_q  = q_create(opt.queue_size);
  183.  
  184.     read_hash_file(opt.file, opt.dir, in_q);
  185.  
  186.     while((md5_in = q_remove(in_q))) {
  187.         printf("Se llama a q_remove in en check\n");
  188.         md5_file.file = md5_in->file;
  189.  
  190.         sum_file(&md5_file);
  191.  
  192.         if(memcmp(md5_file.hash, md5_in->hash, md5_file.hash_size)!=0) {
  193.             printf("File %s doesn't match.\nFound:    ", md5_file.file);
  194.             print_hash(&md5_file);
  195.             printf("\nExpected: ");
  196.             print_hash(md5_in);
  197.             printf("\n");
  198.         }
  199.  
  200.         free(md5_file.hash);
  201.  
  202.         free(md5_in->file);
  203.         free(md5_in->hash);
  204.         free(md5_in);
  205.     }
  206.  
  207.     q_destroy(in_q);
  208. }
  209.  
  210. int get_entries_cast(void*ptr){
  211.     struct thread_get_entries_args * entries_args = ptr;
  212.     get_entries(entries_args->dir, entries_args->q);
  213.     printf("Llamada a q_terminar\n");
  214.     q_terminar(entries_args->q);
  215.     return 0;
  216. }
  217.  
  218. void start_get_entries_thread(char *dir, queue in_q){
  219.     struct thread_get_entries_info* thread;
  220.     thread = malloc(sizeof(struct thread_get_entries_info));
  221.     if(thread == NULL){
  222.         printf("Not enough memory available.\n");
  223.         exit(1);
  224.     }
  225.  
  226.     thread->entries_args = malloc(sizeof(struct thread_get_entries_args));
  227.     thread->entries_args->dir=dir;
  228.     thread->entries_args->q=in_q;
  229.     thread->entries_args->id=0;
  230.     if(0!= thrd_create(&thread->id, get_entries_cast, thread->entries_args)){
  231.         printf("FALLO AL CREAR\n");
  232.     }
  233.     global = thread->id;
  234. }
  235.  
  236.  
  237. void sum(struct options opt) {
  238.     queue in_q, out_q;
  239.     char *ent;
  240.     FILE *out;
  241.     struct file_md5 *md5;
  242.     int dirname_len;
  243.  
  244.  
  245.     in_q  = q_create(opt.queue_size);
  246.     out_q = q_create(opt.queue_size);
  247.     start_get_entries_thread(opt.dir, in_q); //////////////////////////////////////////////////////////////////////////////////////////////////////
  248.     printf("Va a entrar en remove\n");
  249.     while((ent = q_remove(in_q)) != NULL) {
  250.         md5 = malloc(sizeof(struct file_md5));
  251.  
  252.         md5->file = ent;
  253.         sum_file(md5);
  254.         printf("Se llama a q_insert\n");
  255.         q_insert(out_q, md5);
  256.     }
  257.     printf("Llamada a q_terminar\n");
  258.     q_terminar(out_q);
  259.  
  260.     if((out = fopen(opt.file, "w")) == NULL) {
  261.         printf("Could not open output file\n");
  262.         exit(0);
  263.     }
  264.  
  265.     dirname_len = strlen(opt.dir) + 1; // length of dir + /
  266.  
  267.     while((md5 = q_remove(out_q)) != NULL) {
  268.         printf("Se llama a q_remove out\n");
  269.         fprintf(out, "%s: ", md5->file + dirname_len);
  270.  
  271.         for(int i = 0; i < md5->hash_size; i++)
  272.             fprintf(out, "%02hhx", md5->hash[i]);
  273.         fprintf(out, "\n");
  274.  
  275.         free(md5->file);
  276.         free(md5->hash);
  277.         free(md5);
  278.     }
  279.     //if(thrd_join(thread->id, NULL)){
  280.       //printf("FALLO AL UNIR\n");
  281.     //}
  282.     fclose(out);
  283.     q_destroy(in_q);
  284.     q_destroy(out_q);
  285. }
  286.  
  287.  
  288. int main(int argc, char *argv[]) {
  289.     struct options opt;
  290.  
  291.     opt.num_threads = 5;
  292.     opt.queue_size  = 1;
  293.     opt.check       = true;
  294.     opt.file        = NULL;
  295.     opt.dir         = NULL;
  296.  
  297.     read_options (argc, argv, &opt);
  298.  
  299.     if(opt.check)
  300.         check(opt);
  301.     else
  302.         sum(opt);
  303.  
  304. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement