[Fakeroot-commits] [SCM] fakeroot branch, upstream, updated. debian/1.14.3-200-gb232f8a

Timo Savola tsavola at movial.fi
Tue Aug 23 13:05:27 UTC 2011


The following commit has been merged in the upstream branch:
commit 75aecb32676c8537707ee53ccfd000a76d26221f
Author: Timo Savola <tsavola at movial.fi>
Date:   Thu Aug 19 06:41:12 2004 +0000

    Support for using paths (instead of inodes) in the database
    
    2004-08-17 14:05:04 GMT	Timo Savola <tsavola at movial.fi>	patch-7
    
        Summary:
          FAKEROOT_DB_SEARCH_PATHS and an -i change
        Revision:
          fakeroot--scratchbox--0.0--patch-7
    
        * searched paths can be listed in the FAKEROOT_DB_SEARCH_PATHS variable
        * a non-existent file name can be passed to --load (prints a warning)
    
        modified files:
         communicate.h faked.c scripts/fakeroot.in
    
    
    2004-08-17 09:38:31 GMT	Timo Savola <tsavola at movial.fi>	patch-6
    
        Summary:
    
        Revision:
          fakeroot--scratchbox--0.0--patch-6
    
    
    
        Patches applied:
    
         * fakeroot at packages.debian.org--fakeroot/fakeroot--main--0.0--patch-23
           patch from Robert Millan for GNU/k*BSD libc location
    
    
        removed files:
         .arch-ids/aclocal.m4.id aclocal.m4
         fake/.arch-ids/aclocal.m4.id fake/.arch-ids/configure.id
         fake/aclocal.m4 fake/configure
    
        modified files:
         configure.ac debian/changelog
    
        new patches:
         fakeroot at packages.debian.org--fakeroot/fakeroot--main--0.0--patch-23
    
    
    2004-08-16 14:42:58 GMT	Timo Savola <tsavola at movial.fi>	patch-5
    
        Summary:
          Fix conditional dirent inclusion
        Revision:
          fakeroot--scratchbox--0.0--patch-5
    
    
        modified files:
         faked.c
    
    
    2004-08-16 14:36:17 GMT	Timo Savola <tsavola at movial.fi>	patch-4
    
        Summary:
          Fixed bug in load_database()
        Revision:
          fakeroot--scratchbox--0.0--patch-4
    
    
        modified files:
         faked.c
    
    
    2004-08-16 13:30:23 GMT	Timo Savola <tsavola at movial.fi>	patch-3
    
        Summary:
          Make database path stuff optional
        Revision:
          fakeroot--scratchbox--0.0--patch-3
    
        * the database format can be selected with configure option --with-dbformat
    
        modified files:
         configure.ac faked.c
    
    
    2004-08-12 16:26:22 GMT	Timo Savola <tsavola at movial.fi>	patch-2
    
        Summary:
          Database uses path names
        Revision:
          fakeroot--scratchbox--0.0--patch-2
    
        * database file format changed: device and inode numbers are replaced with
          a path string (the implementation is very slow; it basically does 'find'
          many times...)
        * paths are checked for existence when loading the database
    
        modified files:
         faked.c
    
    
    2004-08-11 15:55:24 GMT	Timo Savola <tsavola at movial.fi>	patch-1
    
        Summary:
          Broke the database
        Revision:
          fakeroot--scratchbox--0.0--patch-1
    
        Began implementing database integrity checking...
    
        modified files:
         faked.c
    
    
    2004-08-11 11:05:31 GMT	Timo Savola <tsavola at movial.fi>	base-0
    
        Summary:
          tag of fakeroot at packages.debian.org--fakeroot/fakeroot--main--0.0--patch-22
        Revision:
          fakeroot--scratchbox--0.0--base-0
    
        (automatically generated log message)
    
    
    git-archimport-id: fakeroot at packages.debian.org--fakeroot/fakeroot--main--0.0--patch-24

diff --git a/communicate.h b/communicate.h
index b9c66f1..031afba 100644
--- a/communicate.h
+++ b/communicate.h
@@ -73,6 +73,9 @@
 #ifdef FAKEROOT_FAKENET
 #define FD_BASE_ENV               "FAKEROOT_FD_BASE"
 #endif /* FAKEROOT_FAKENET */
+#ifdef FAKEROOT_DB_PATH
+#define DB_SEARCH_PATHS_ENV       "FAKEROOT_DB_SEARCH_PATHS"
+#endif /* FAKEROOT_DB_PATH */
 
 #ifdef __GNUC__
 #  define UNUSED __attribute__((unused))
diff --git a/configure.ac b/configure.ac
index d518c5e..8c6772d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -19,6 +19,21 @@ AC_CACHE_CHECK([which IPC method to use],
 	       [ac_cv_use_ipc],
 	       [ac_cv_use_ipc=sysv])
 
+AC_ARG_WITH([dbformat],
+	    AS_HELP_STRING([--with-dbformat@<:@=DBFORMAT@:>@],
+			   [database format to use: either inode (default) or path]),
+	    [ac_cv_dbformat=$withval],
+	    [ac_cv_dbformat=inode])
+
+AC_CACHE_CHECK([which database format to use],
+	       [ac_cv_dbformat],
+	       [ac_cv_dbformat=inode])
+
+AH_TEMPLATE([FAKEROOT_DB_PATH], [store path in the database instead of inode and device])
+if test $ac_cv_dbformat = "path"; then
+AC_DEFINE_UNQUOTED(FAKEROOT_DB_PATH, [1])
+fi
+
 dnl Checks for programs.
 
 dnl Checks for libraries.
diff --git a/faked.c b/faked.c
index 70f4270..38cf226 100644
--- a/faked.c
+++ b/faked.c
@@ -29,7 +29,7 @@
 
     user program
        Any shell or other programme, run with 
-       LD_PRELOAD=libtricks.so.0.0, and FAKEROOTKEY=ipc-key,
+       LD_PRELOAD=libtricks.so.0.0, and FAKEROOT_DBKEY=ipc-key,
        thus the executed commands will communicate with
        faked. libtricks will wrap all file ownership etc modification
        calls, and send the info to faked. Also the stat() function
@@ -73,9 +73,8 @@
 #ifndef FAKEROOT_FAKENET
 # include <sys/ipc.h>
 # include <sys/msg.h>
-#else /* FAKEROOT_FAKENET */
-# include <sys/stat.h>
 #endif /* FAKEROOT_FAKENET */
+#include <sys/stat.h>
 #include <sys/wait.h>
 #ifndef FAKEROOT_FAKENET
 # include <sys/sem.h>
@@ -104,6 +103,9 @@
 #ifdef HAVE_SYS_SYSMACROS_H
 # include <sys/sysmacros.h>
 #endif
+#ifdef FAKEROOT_DB_PATH
+# include <dirent.h>
+#endif
 
 #ifndef FAKEROOT_FAKENET
 # define FAKE_KEY msg_key
@@ -358,14 +360,108 @@ static void faked_send_fakem(const struct fake_msg *buf)
 
 #endif /* FAKEROOT_FAKENET */
 
+#ifdef FAKEROOT_DB_PATH
+# define DB_PATH_LEN    4095
+# define DB_PATH_SCAN "%4095s"
+
+/*
+ * IN:  'path' contains the dir to scan recursively
+ * OUT: 'path' contains the matching file if 1 is returned
+ */
+static int scan_dir(const fake_dev_t dev, const fake_ino_t ino,
+                    char *const path)
+{
+  const size_t pathlen = strlen(path) + strlen("/");
+  if (pathlen >= DB_PATH_LEN)
+    return 0;
+  strcat(path, "/");
+
+  DIR *const dir = opendir(path);
+  if (!dir)
+    return 0;
+
+  struct dirent *ent;
+  while ((ent = readdir(dir))) {
+    if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
+      continue;
+
+    if (ent->d_ino == ino) {
+      struct stat buf;
+      strncpy(path + pathlen, ent->d_name, DB_PATH_LEN - pathlen);
+      if (lstat(path, &buf) == 0 && buf.st_dev == dev)
+        break;
+    } else if (ent->d_type == DT_DIR) {
+      strncpy(path + pathlen, ent->d_name, DB_PATH_LEN - pathlen);
+      if (scan_dir(dev, ino, path))
+        break;
+    }
+  }
+
+  closedir(dir);
+  return ent != 0;
+}
+
+/*
+ * Finds a path for inode/device pair--there can be several if bind mounts
+ * are used.  This should not be a problem if the bind mount configuration
+ * is the same when loading the database.
+ *
+ * IN:  'roots' contains the dirs to scan recursively (separated by colons)
+ * OUT: 'path' contains the matching file if 1 is returned
+ */
+static int find_path(const fake_dev_t dev, const fake_ino_t ino,
+                     const char *const roots, char *const path)
+{
+  unsigned int end = 0;
+
+  do {
+    unsigned int len, start = end;
+
+    while (roots[end] != '\0' && roots[end] != ':')
+      end++;
+
+    len = end - start;
+    if (len == 0)
+      continue;
+
+    if (roots[end - 1] == '/')
+      len--;
+
+    if (len > DB_PATH_LEN)
+      len = DB_PATH_LEN;
+
+    strncpy(path, roots + start, len);
+    path[len] = '\0';
+
+    if (scan_dir(dev, ino, path))
+      return 1;
+  } while (roots[end++] != '\0');
+
+  return 0;
+}
+
+#endif
+
 int save_database(const uint32_t remote)
 {
+#ifdef FAKEROOT_DB_PATH
+  char path[DB_PATH_LEN + 1];
+  const char *roots;
+#endif
   data_node_t *i;
   FILE *f;
 
   if(!save_file)
     return 1;
 
+#ifdef FAKEROOT_DB_PATH
+  path[DB_PATH_LEN] = '\0';
+
+  roots = getenv(DB_SEARCH_PATHS_ENV);
+  if (!roots)
+    roots = "/";
+#endif
+
   f=fopen(save_file, "w");
   if(!f)
     return 0;
@@ -374,10 +470,17 @@ int save_database(const uint32_t remote)
     if (i->remote != remote)
       continue;
 
+#ifdef FAKEROOT_DB_PATH
+    if (find_path(i->buf.dev, i->buf.ino, roots, path))
+      fprintf(f,"mode=%llo,uid=%llu,gid=%llu,nlink=%llu,rdev=%llu %s\n",
+              (uint64_t) i->buf.mode,(uint64_t) i->buf.uid,(uint64_t) i->buf.gid,
+              (uint64_t) i->buf.nlink,(uint64_t) i->buf.rdev,path);
+#else
     fprintf(f,"dev=%llx,ino=%llu,mode=%llo,uid=%llu,gid=%llu,nlink=%llu,rdev=%llu\n",
             (uint64_t) i->buf.dev,(uint64_t) i->buf.ino,(uint64_t) i->buf.mode,
             (uint64_t) i->buf.uid,(uint64_t) i->buf.gid,(uint64_t) i->buf.nlink,
             (uint64_t) i->buf.rdev);
+#endif
   }
 
   return fclose(f);
@@ -390,22 +493,45 @@ int load_database(const uint32_t remote)
 
   uint64_t stdev, stino, stmode, stuid, stgid, stnlink, strdev;
   struct fakestat st;
+
+#ifdef FAKEROOT_DB_PATH
+  char path[DB_PATH_LEN + 1];
+  struct stat path_st;
+
+  path[DB_PATH_LEN] = '\0';
+#endif
+
   while(1){
-    r=scanf("dev=%llx,ino=%llu,mode=%llo,uid=%llu,gid=%llu,nlink=%llu,rdev=%llu\n",
-            &stdev, &stino, &stmode, &stuid, &stgid, &stnlink, &strdev);
+#ifdef FAKEROOT_DB_PATH
+    r=scanf("mode=%llo,uid=%llu,gid=%llu,nlink=%llu,rdev=%llu "DB_PATH_SCAN"\n",
+            &stmode, &stuid, &stgid, &stnlink, &strdev, &path);
+    if (r != 6)
+      break;
 
-    if(r==7) {
-      st.dev = stdev;
-      st.ino = stino;
-      st.mode = stmode;
-      st.uid = stuid;
-      st.gid = stgid;
-      st.nlink = stnlink;
-      st.rdev = strdev;
-      data_insert(&st, remote);
+    if (stat(path, &path_st) < 0) {
+      fprintf(stderr, "%s: %s\n", path, strerror(errno));
+      if (errno == ENOENT || errno == EACCES)
+        continue;
+      else
+        break;
     }
-    else
+    stdev = path_st.st_dev;
+    stino = path_st.st_ino;
+#else
+    r=scanf("dev=%llx,ino=%llu,mode=%llo,uid=%llu,gid=%llu,nlink=%llu,rdev=%llu\n",
+            &stdev, &stino, &stmode, &stuid, &stgid, &stnlink, &strdev);
+    if (r != 7)
       break;
+#endif
+
+    st.dev = stdev;
+    st.ino = stino;
+    st.mode = stmode;
+    st.uid = stuid;
+    st.gid = stgid;
+    st.nlink = stnlink;
+    st.rdev = strdev;
+    data_insert(&st, remote);
   }
   if(!r||r==EOF)
     return 1;
diff --git a/scripts/fakeroot.in b/scripts/fakeroot.in
index eedc22e..4bf0f82 100755
--- a/scripts/fakeroot.in
+++ b/scripts/fakeroot.in
@@ -60,8 +60,12 @@ while test "X$1" != "X--"; do
        ;;
     -i)
        shift
-       FAKEDOPTS=$FAKEDOPTS" --load"
-       PIPEIN="<$1"
+       if test -f "$1"; then
+         FAKEDOPTS=$FAKEDOPTS" --load"
+         PIPEIN="<$1"
+       else
+         echo 1>&2 "fakeroot: database file \`$1' does not exist."
+       fi
        ;;
     -s)
        shift

-- 
fakeroot



More information about the Fakeroot-commits mailing list