Patch by Mike Lin on 2012-05-21 for:

1.) "Currently, the entire environment is included in the CDE package, and
then filtered at runtime against the list of variables to ignore. If the user
is saying to ignore certain environment variables, they might not want them
included in the package at all (for security or privacy reasons)."

2.) "At the moment I have just been trying to get cde-exec compiled on
[Ubuntu] Precise to run on Oneiric. It seems that the implementation of memcpy
in GLIBC changed recently (seriously...). These hacks seemed to get it to use
the old version, although I have to continue validating it today"

However, I don't have enough time to test more thoroughly, so I haven't merged
these yet. Initial testing hung with a seemingly infinite loop :(


diff --git a/strace-4.6/Makefile.in b/strace-4.6/Makefile.in
index 5b4e31c..e4c8ab0 100644
--- a/strace-4.6/Makefile.in
+++ b/strace-4.6/Makefile.in
@@ -280,7 +280,7 @@ OS = @opsys@
 # ARCH is `i386', `m68k', `sparc', etc.
 ARCH = @arch@
 ACLOCAL_AMFLAGS = -I m4
-AM_CFLAGS = $(WARN_CFLAGS) -Wl,--hash-style=both # pgbovine - for backwards-compatibility with RedHat 4.X-like distros
+AM_CFLAGS = $(WARN_CFLAGS) -Wl,--hash-style=both -Wl,--wrap=memcpy # pgbovine - for backwards-compatibility with RedHat 4.X-like distros
 AM_CPPFLAGS = -I$(srcdir)/$(OS)/$(ARCH) -I$(srcdir)/$(OS) -I$(builddir)/$(OS)
 # pgbovine - added more files:
 strace_SOURCES = strace.c syscall.c count.c util.c desc.c file.c ipc.c \
diff --git a/strace-4.6/cde.c b/strace-4.6/cde.c
index 347b3bd..bc3a749 100644
--- a/strace-4.6/cde.c
+++ b/strace-4.6/cde.c
@@ -57,6 +57,15 @@ CDE is currently licensed under GPL v3:
 #if defined (I386)
 __asm__(".symver shmctl,shmctl@GLIBC_2.0"); // hack to eliminate glibc 2.2 dependency
 #endif
+#if defined (X86_64)
+__asm__(".symver memcpy,memcpy@GLIBC_2.2.5");
+#endif
+
+// http://stackoverflow.com/questions/8823267/linking-against-older-symbol-version-in-a-so-file
+void *__wrap_memcpy(void *dest, const void *src, size_t n)
+{
+    return memcpy(dest, src, n);
+}
 
 
 // 1 if we are executing code in a CDE package,
@@ -224,10 +233,10 @@ static void CDE_init_options(void);
 static void CDE_create_convenience_scripts(char** argv, int optind);
 static void CDE_create_toplevel_symlink_dirs(void);
 static void CDE_create_path_symlink_dirs(void);
+static void CDE_dump_environment_vars(void);
 static void CDE_load_environment_vars(void);
 
 
-
 // returns a component within real_pwd that represents the part within
 // cde_pseudo_root_dir
 // the return value should NOT be mutated; otherwise we might be screwed!
@@ -3184,10 +3193,7 @@ void CDE_init(char** argv, int optind) {
     CDE_create_toplevel_symlink_dirs();
 
 
-    // copy /proc/self/environ to capture the FULL set of environment vars
-    char* fullenviron_fn = format("%s/cde.full-environment", CDE_PACKAGE_DIR);
-    copy_file((char*)"/proc/self/environ", fullenviron_fn, 0666);
-    free(fullenviron_fn);
+    CDE_dump_environment_vars();
   }
 
 
@@ -3564,6 +3570,73 @@ static void CDE_init_options() {
   cde_options_initialized = 1;
 }
 
+// Dump all environment variables to CDE_PACKAGE_DIR/cde.full_environment
+// except for those that cde.options says to ignore. 
+static void CDE_dump_environment_vars() {
+  // dump /proc/self/environ to a temporary file which we'll then mmap to
+  // process. (can't mmap procfs directly)
+  char* tmp_fn = format("/tmp/cde.full-environment.%d",(int)getpid());
+
+  copy_file((char*)"/proc/self/environ",tmp_fn,0600);
+
+  struct stat tmp_file_stat;
+  if (stat(tmp_fn, &tmp_file_stat)) {
+    perror(tmp_fn);
+    exit(1);
+  }
+  int tmp_fd = open(tmp_fn, O_RDONLY);
+  char* environ_start =
+    (char*)mmap(0, tmp_file_stat.st_size, PROT_READ, MAP_PRIVATE, tmp_fd, 0);
+
+  // open destination file
+  char* dest_fn = format("%s/cde.full-environment", CDE_PACKAGE_DIR);
+  int dest_fd = open(dest_fn, O_CREAT|O_TRUNC|O_WRONLY, 0664);
+
+  if (environ_start == MAP_FAILED || dest_fd < 0) {
+    fprintf(stderr, "Error dumping process environment to %s!\n", dest_fn);
+    exit(1);
+  }
+
+  // go through environment variables and write each to
+  // cde.full-environment UNLESS cde.options says to ignore it
+  char* environ_str = environ_start;
+  while (environ_str - environ_start < tmp_file_stat.st_size) {
+    int environ_strlen = strnlen(environ_str,tmp_file_stat.st_size - (environ_str - environ_start));
+    int i;
+    int include = 1;
+
+    for (i = 0; i < ignore_envvars_ind; i++) {
+      int ignored_strlen = strlen(ignore_envvars[i]);
+
+      if(environ_strlen >= ignored_strlen &&
+             strncmp(environ_str, ignore_envvars[i], ignored_strlen) == 0 &&
+             (environ_strlen == ignored_strlen || environ_str[ignored_strlen] == '='))
+      {
+        include = 0;
+        break;
+      }
+    }
+
+    if (environ_strlen > 0 && include) {
+      char null = 0;
+      if (write(dest_fd, environ_str, environ_strlen) < environ_strlen
+            || write(dest_fd, &null, 1) < 1) {
+        fprintf(stderr, "Error dumping process environment to %s!\n", dest_fn);
+        exit(1);
+      }
+    }
+
+    environ_str += (environ_strlen + 1);
+  }
+
+  close(dest_fd);
+  free(dest_fn);
+
+  munmap(environ_start, tmp_file_stat.st_size);
+  close(tmp_fd);
+  unlink(tmp_fn);
+  free(tmp_fn);
+}
 
 static void CDE_load_environment_vars() {
   static char cde_full_environment_abspath[MAXPATHLEN];
@@ -3615,6 +3688,8 @@ static void CDE_load_environment_vars() {
     }
 
     // make sure we're not ignoring this environment var:
+    // (this is here for backwards-compatibility- previous versions did not
+    // exclude them from cde.full_environment in the first place)
     int i;
     int ignore_me = 0;
     for (i = 0; i < ignore_envvars_ind; i++) {
diff --git a/strace-4.6/okapi.c b/strace-4.6/okapi.c
index cc0de55..fe7e42c 100644
--- a/strace-4.6/okapi.c
+++ b/strace-4.6/okapi.c
@@ -60,7 +60,9 @@ char OKAPI_VERBOSE = 1; // print out warning messages?
 // See: http://www.trevorpounds.com/blog/?p=103
 __asm__(".symver realpath,realpath@GLIBC_2.0");
 #endif
-
+#if defined (X86_64)
+__asm__(".symver realpath,realpath@GLIBC_2.2.5");
+#endif
 
 #include <stdarg.h>
 extern char* format(const char *format, ...);
