meowsum.git

commit 45afc5fa5bbbd3b73cb069c2673a13b34a5a1a4c

Author: Adam <git@apiote.tk>

return results instead of errors

 meowsum.c | 95 +++++++++++++++++++++++++++++++++++---------------------


diff --git a/meowsum.c b/meowsum.c
index 0bd1788390e02a54b7f4f3ddb6b00fd3dd934f03..40c672ea9ed79e0c1b59202e6e0d3949299665ce 100644
--- a/meowsum.c
+++ b/meowsum.c
@@ -5,6 +5,7 @@ #define HASH_SIZE 128
 #define MODE_SUM 0
 #define MODE_CHECK 1
 
+#include <assert.h>
 #include <fcntl.h>
 #include <stdbool.h>
 #include <stdio.h>
@@ -66,27 +67,34 @@     }
   }
 }
 
-bool calculate_checksum(char *path, char *buffer, meow_u128 *hash,
-                        struct stat *stat) {
-  int fd, r;
+meow_u128 *calculate_checksum(char *path, unsigned long *size) {
+  assert(size != NULL);
+  assert(path != NULL);
+
+  int fd;
   meow_state state;
   ssize_t read_bytes;
+  char buffer[BUFFER_SIZE];
+  meow_u128 *hash;
 
   if (strcmp(path, "-") == 0) {
     fd = 0;
+  } else {
+    fd = open(path, 0);
   }
-  fd = open(path, 0);
   if (fd == -1) {
     perror("error: ");
     printf("error opening file %s\n", path);
-    return false;
+    return NULL;
   }
 
-  r = fstat(fd, stat);
-  if (r == -1) {
+  *size = 0;
+
+  hash = malloc(sizeof(meow_u128));
+  if (hash == NULL) {
     perror("error: ");
-    printf("error stating file %s\n", path);
-    return false;
+    printf("error mallocing hash for %s\n", path);
+    return NULL;
   }
 
   MeowBegin(&state, MeowDefaultSeed);
@@ -96,8 +104,9 @@     if (read_bytes == -1) {
       perror("error: ");
       printf("error reading file %s\n", path);
       close(fd);
-      return false;
+      return NULL;
     }
+    *size += read_bytes;
     if (read_bytes == 0) {
       break;
     }
@@ -108,47 +117,62 @@
   if (fd != 0) {
     close(fd);
   }
-  return true;
+
+  return hash;
+}
+
+char *format_sum(meow_u128 hash, int size) {
+  char *result;
+
+  result = malloc((size * 2 / 8 * sizeof(char)) + 1);
+
+  if (size == 32) {
+    sprintf(result, "%x", MeowU32From(hash, 0));
+  }
+  if (size == 64) {
+    sprintf(result, "%llx", MeowU64From(hash, 0));
+  }
+  if (size == 128) {
+    int64_t v64val[2];
+    memcpy(v64val, &hash, sizeof(v64val));
+    sprintf(result, "%lx%lx", v64val[1], v64val[0]);
+  }
+
+  return result;
 }
 
-bool sum_files(char *argv[], int start, int argc, char *buffer, int hash_size) {
-  bool r;
-  int64_t v64val[2];
-  struct stat stat;
+bool sum_files(char *argv[], int start, int argc, int hash_size) {
+  char *hex_hash;
+  meow_u128 *hash;
+  unsigned long size;
 
   for (int i = start; i < argc; ++i) {
-    meow_u128 hash;
-    r = calculate_checksum(argv[i], buffer, &hash, &stat);
-    if (!r) {
+    hash = calculate_checksum(argv[i], &size);
+    if (hash == NULL) {
       printf("error while calculating %s\n", argv[i]);
       return false;
     }
+    hex_hash = format_sum(*hash, hash_size);
+    if (hex_hash == NULL) {
+      printf("error while formating hex hash for %s\n", argv[i]);
+      return false;
+    }
 
-    memcpy(v64val, &hash, sizeof(v64val));
-    switch (hash_size) {
-    case 32:
-      printf("%x %ld %s\n", MeowU32From(hash, 0), stat.st_size, argv[i]);
-      break;
-    case 64:
-      printf("%llx %ld %s\n", MeowU64From(hash, 0), stat.st_size, argv[i]);
-      break;
-    case 128:
-      printf("%lx%lx %ld %s\n", v64val[1], v64val[0], stat.st_size, argv[i]);
-      break;
-    }
+    printf("%s %ld %s\n", hex_hash, size, argv[i]);
+    free(hex_hash);
+    free(hash);
   }
 
   return true;
 }
 
-bool check_files(char *args[], int start, int argc, int hash_size, bool quiet,
+bool check_files(char *args[], int start, int argc, bool quiet,
                  bool stric_errors) {
   // todo
 }
 
 int main(int argc, char *argv[]) {
   int hash_size = HASH_SIZE, mode = MODE_SUM, first_file_index = -1;
-  char *buffer = malloc(sizeof(char) * 8192);
   bool quiet = false, strict_error = false;
   int exit_status = 0;
 
@@ -171,16 +195,15 @@     return 1;
   }
 
   if (mode == MODE_SUM) {
-    sum_files(argv, first_file_index, argc, buffer, hash_size);
+    sum_files(argv, first_file_index, argc, hash_size);
   }
   if (mode == MODE_CHECK) {
-    bool check_result = check_files(argv, first_file_index, argc, hash_size,
-                                    quiet, strict_error);
+    bool check_result =
+        check_files(argv, first_file_index, argc, quiet, strict_error);
     if (!check_result) {
       exit_status = 1;
     }
   }
 
-  free(buffer);
   return exit_status;
 }