Advertisement
techno-

md5.c con productores

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