util-vserver 0.30.215.
[util-vserver.git] / src / vhashify.c
index 34e32a9..fb1172c 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: vhashify.c 2403 2006-11-24 23:06:08Z dhozac $    --*- c -*--
+// $Id: vhashify.c 2685 2008-02-21 23:22:23Z ensc $    --*- c -*--
 
 // Copyright (C) 2005 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
 //  
@@ -20,6 +20,8 @@
 #  include <config.h>
 #endif
 
+#define UTIL_VSERVER_UNIFY_MTIME_OPTIONAL
+
 #include "vhashify.h"
 #include "util.h"
 
@@ -28,7 +30,7 @@
 #include "lib_internal/unify.h"
 #include "ensc_vector/vector.h"
 
-#include <beecrypt/beecrypt.h>
+#include "lib_internal/crypto-wrapper.h"
 
 #include <setjmp.h>
 #include <unistd.h>
@@ -70,6 +72,7 @@
 #define CMD_SLEDGE             0x1002
 #define CMD_MANUALLY           0x1003
 #define CMD_REFRESH            0x1004
+#define CMD_NOMTIME            0x1005
 
 struct option const
 CMDLINE_OPTIONS[] = {
@@ -80,6 +83,7 @@ CMDLINE_OPTIONS[] = {
   { "sledgehammer", no_argument,       0, CMD_SLEDGE },
   { "manually",     no_argument,       0, CMD_MANUALLY },
   { "refresh",      no_argument,        0, CMD_REFRESH },
+  { "ignore-mtime", no_argument,        0, CMD_NOMTIME },
   { "dry-run",      no_argument,       0, 'n' },
   { "verbose",      no_argument,       0, 'v' },
   { 0,0,0,0 }
@@ -91,7 +95,7 @@ typedef char                  HashPath[HASH_MAXBITS/4 + (HASH_MAXBITS/4/2) +
 
 struct HashDirConfiguration
 {
-    hashFunction const                         *method;
+    ensc_hash_method const                     *method;
     enum { hshALL=0, hshSTART = 1, hshMIDDLE=2,
           hshEND = 4, hshINVALID = -1 }        blocks;
     size_t                                     blocksize;
@@ -105,7 +109,7 @@ struct WalkdownInfo
     HashDirCollection          hash_dirs;
     size_t                     hash_dirs_max_size;
 
-    hashFunctionContext                hash_context;
+    ensc_hash_context          hash_context;
 };
 
 int                            wrapper_exit_code = 1;
@@ -247,13 +251,13 @@ static bool
 convertDigest(HashPath d_path)
 {
   static char const            HEX_DIGIT[] = "0123456789abcdef";
-  hashFunctionContext * const  h_ctx    = &global_info.hash_context;
-  size_t                       d_size   = h_ctx->algo->digestsize;
-    
+  ensc_hash_context * const    h_ctx    = &global_info.hash_context;
+  size_t                       d_size   = ensc_crypto_hashctx_get_digestsize(h_ctx);
+
   unsigned char                        digest[d_size];
   size_t                       out = 0;
 
-  if (hashFunctionContextDigest(h_ctx, digest)==-1)
+  if (ensc_crypto_hashctx_get_digest(h_ctx, digest, NULL, d_size)==-1)
     return false;
   
   for (size_t in=0;
@@ -271,7 +275,7 @@ convertDigest(HashPath d_path)
 
 #ifndef ENSC_TESTSUITE
 static bool
-addStatHash(hashFunctionContext *h_ctx, struct stat const * const st)
+addStatHash(ensc_hash_context *h_ctx, struct stat const * const st)
 {
 #define DECL_ATTR(X)   __typeof__(st->st_##X)  X
 #define SET_ATTR(X)    .X = st->st_##X
@@ -289,18 +293,18 @@ addStatHash(hashFunctionContext *h_ctx, struct stat const * const st)
     SET_ATTR(gid),
     SET_ATTR(rdev),
     SET_ATTR(size),
-    SET_ATTR(mtime)
+    .mtime = (global_args->ignore_mtime ? 0 : st->st_mtime),
   };
 
 #undef SET_ATTR
 #undef DECL_ATTR
 
   
-  return hashFunctionContextUpdate(h_ctx, (void *)&tmp, sizeof tmp)!=-1;
+  return ensc_crypto_hashctx_update(h_ctx, (void *)&tmp, sizeof tmp)!=-1;
 }
 #else
 static bool
-addStatHash(hashFunctionContext UNUSED *h_ctx, struct stat const UNUSED * const st)
+addStatHash(ensc_hash_context UNUSED *h_ctx, struct stat const UNUSED * const st)
 {
   return true;
 }
@@ -309,13 +313,13 @@ addStatHash(hashFunctionContext UNUSED *h_ctx, struct stat const UNUSED * const
 static bool
 calculateHashFromFD(int fd, HashPath d_path, struct stat const * const st)
 {
-  hashFunctionContext * const  h_ctx    = &global_info.hash_context;
+  ensc_hash_context * const    h_ctx    = &global_info.hash_context;
   void const * volatile                buf      = 0;
   loff_t volatile              buf_size = 0;
   bool   volatile              res      = false;
 
 
-  if (hashFunctionContextReset(h_ctx)==-1 ||
+  if (ensc_crypto_hashctx_reset(h_ctx)==-1 ||
       !addStatHash(h_ctx, st))
     return false;
 
@@ -336,7 +340,7 @@ calculateHashFromFD(int fd, HashPath d_path, struct stat const * const st)
       offset += buf_size;
       madvise(const_cast(void *)(buf), buf_size, MADV_SEQUENTIAL);     // ignore error...
 
-      if (hashFunctionContextUpdate(h_ctx, buf, buf_size)==-1) goto out;
+      if (ensc_crypto_hashctx_update(h_ctx, buf, buf_size)==-1) goto out;
 
       munmap(const_cast(void *)(buf), buf_size);
       buf = 0;
@@ -389,69 +393,6 @@ calculateHash(PathInfo const *filename, HashPath d_path, struct stat const * con
   return res;
 }
 
-static enum { mkdirFAIL, mkdirSUCCESS, mkdirSKIP }
-mkdirSingle(char const *path, char *end_ptr, int good_err)
-{
-  *end_ptr = '\0';
-  if (mkdir(path, 0700)!=-1 || errno==EEXIST) {
-    *end_ptr = '/';
-    return mkdirSUCCESS;
-  }
-  else if (errno==good_err) {
-    *end_ptr = '/';
-    return mkdirSKIP;
-  }
-  else {
-    int                old_errno = errno;
-    WRITE_MSG(2, "mkdir('");
-    WRITE_STR(2, path);
-    errno = old_errno;
-    perror("')");
-    return mkdirFAIL;
-  }
-}
-
-static char *
-rstrchr(char *str, char c)
-{
-  while (*str!=c) --str;
-  return str;
-}
-
-static bool
-mkdirRecursive(char const *path)
-{
-  if (path[0]!='/')      return false; // only absolute paths
-
-  char                 buf[strlen(path)+1];
-  char *               ptr = buf + sizeof(buf) - 2;
-
-  strcpy(buf, path);
-
-  while (ptr>buf && (ptr = rstrchr(ptr, '/'))!=0) {
-    switch (mkdirSingle(buf, ptr, ENOENT)) {
-      case mkdirSUCCESS                :  break;
-      case mkdirSKIP           :  --ptr; continue;
-      case mkdirFAIL           :  return false;
-    }
-
-    break;     // implied by mkdirSUCCESS
-  }
-
-  assert(ptr!=0);
-  ++ptr;
-
-  while ((ptr=strchr(ptr, '/'))!=0) {
-    switch (mkdirSingle(buf, ptr, 0)) {
-      case mkdirSKIP           :
-      case mkdirFAIL           :  return false;
-      case mkdirSUCCESS                :  ++ptr; continue;
-    }
-  }
-
-  return true;
-}
-
 static bool
 resolveCollisions(char *result, PathInfo const *root, HashPath d_path,
                  struct stat *st, struct stat *hash_st)
@@ -493,18 +434,16 @@ resolveCollisions(char *result, PathInfo const *root, HashPath d_path,
 
     if (!global_args->dry_run) {
       *ptr = '\0';
-      if (!mkdirRecursive(result))
+      if (!mkdirRecursive(result)) {
+       PERROR_Q("mkdir", result);
        return false;
+      }
       *ptr = '-';
 
       int              fd = open(result, O_NOFOLLOW|O_EXCL|O_CREAT|O_WRONLY, 0200);
 
       if (fd==-1) {
-       int             old_errno = errno;
-       WRITE_MSG(2, "open('");
-       WRITE_STR(2, buf);
-       errno = old_errno;
-       perror("')");
+       PERROR_Q("open", buf);
        return false;
       }
 
@@ -688,6 +627,7 @@ int main(int argc, char *argv[])
     .insecure           =  0,
     .dry_run            =  false,
     .do_refresh         =  false,
+    .ignore_mtime      =  false,
   };
 
   Vector_init(&global_info.hash_dirs, sizeof(struct HashDirInfo));
@@ -706,6 +646,7 @@ int main(int argc, char *argv[])
       case CMD_INSECURE                :  args.insecure    = 1;    break;
       case CMD_SLEDGE          :  args.insecure    = 2;    break;
       case CMD_REFRESH         :  args.do_refresh  = true; break;
+      case CMD_NOMTIME         :  args.ignore_mtime = true; break;
       case 'n'                 :  args.dry_run     = true; break;
       case 'v'                 :  ++args.verbosity; break;
       default          :
@@ -727,14 +668,15 @@ int main(int argc, char *argv[])
     return EXIT_FAILURE;
   }
 
+  ensc_crypto_init();
   switch (args.mode) {
     case mdMANUALLY    :  initModeManually(&args, argc-optind, argv+optind); break;
     case mdVSERVER     :  initModeVserver (&args, argc-optind, argv+optind); break;
     default            :  assert(false); return EXIT_FAILURE;
   };
 
-  if (hashFunctionContextInit(&global_info.hash_context,
-                             global_info.hash_conf.method)==-1) {
+  if (ensc_crypto_hashctx_init(&global_info.hash_context,
+                              global_info.hash_conf.method)==-1) {
     WRITE_MSG(2, "Failed to initialize hash-context\n");
     return EXIT_FAILURE;
   }
@@ -750,7 +692,7 @@ int main(int argc, char *argv[])
 #ifndef NDEBUG
   MatchList_destroy(&global_info.dst_list);
   freeHashList(&global_info.hash_dirs);
-  hashFunctionContextFree(&global_info.hash_context);
+  ensc_crypto_hashctx_free(&global_info.hash_context);
 #endif
 
   return EXIT_SUCCESS;