[glick2] Add support for custom env vars set in bundles



commit e1609a6e8c76ce2fe1a92685d045d71e24c238cf
Author: Alexander Larsson <alexl redhat com>
Date:   Fri Dec 2 16:11:14 2011 +0100

    Add support for custom env vars set in bundles

 format.h   |    9 ++++++++-
 mkbundle.c |   37 +++++++++++++++++++++++++++++--------
 runner.c   |   57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 94 insertions(+), 9 deletions(-)
---
diff --git a/format.h b/format.h
index 811b9d3..19d786e 100644
--- a/format.h
+++ b/format.h
@@ -4,6 +4,10 @@
 #define GLICK_VERSION 1
 
 typedef enum {
+  GLICK_FLAGS_NONE = 0
+} GlickFlags;
+
+typedef enum {
   GLICK_SLICE_FLAGS_NONE = 0,
   GLICK_SLICE_FLAGS_EXPORT = 1<<0
 } GlickSliceFlags;
@@ -11,7 +15,7 @@ typedef enum {
 typedef struct {
   guint8 glick_magic[8];
   guint32 glick_version;
-  guint32 padding;
+  guint32 glick_flags;
   guint32 header_size;
   guint32 bundle_id_offset;
   guint32 bundle_id_size;
@@ -19,8 +23,11 @@ typedef struct {
   guint32 bundle_version_size;
   guint32 exec_offset;
   guint32 exec_size;
+  guint32 env_offset;
+  guint32 env_size;
   guint32 slices_offset;
   guint32 num_slices;
+  guint32 padding[32];
 } GlickBundleHeader;
 
 #define SHA1_CHECKSUM_SIZE 20
diff --git a/mkbundle.c b/mkbundle.c
index 459f9a7..f1f6fcf 100644
--- a/mkbundle.c
+++ b/mkbundle.c
@@ -613,6 +613,8 @@ typedef struct {
   char *id;
   char *version;
   char *default_executable;
+  char *env;
+  gsize env_size;
   GList *slices;
 } Bundle;
 
@@ -664,7 +666,7 @@ bundle_write (Bundle *bundle, GFile *dest, GError **error)
   gsize header_data_len;
   GlickBundleHeader *header;
   GlickSliceRef *slice_refs, *ref;
-  gsize id_offset, version_offset, exec_offset;
+  gsize id_offset, version_offset, exec_offset, env_offset;
   goffset offset, padding;
   char *exec;
   char pad[4096] = {0 };
@@ -682,7 +684,7 @@ bundle_write (Bundle *bundle, GFile *dest, GError **error)
   header_data_len =
     sizeof (GlickBundleHeader) +
     g_list_length (bundle->slices) * sizeof (GlickSliceRef) +
-    strlen (bundle->id) + strlen (bundle->version) + strlen (exec);
+    strlen (bundle->id) + strlen (bundle->version) + strlen (exec) + bundle->env_size;
   header_data = g_malloc0 (header_data_len);
   header = (GlickBundleHeader *)header_data;
   slice_refs = (GlickSliceRef *)(header_data + sizeof (GlickBundleHeader));
@@ -695,10 +697,13 @@ bundle_write (Bundle *bundle, GFile *dest, GError **error)
     g_list_length (bundle->slices) * sizeof (GlickSliceRef);
   version_offset = id_offset + strlen (bundle->id);
   exec_offset = version_offset + strlen (bundle->version);
+  env_offset = exec_offset + strlen (exec);
 
   memcpy (header_data + id_offset, bundle->id, strlen (bundle->id));
   memcpy (header_data + version_offset, bundle->version, strlen (bundle->version));
   memcpy (header_data + exec_offset, exec, strlen (exec));
+  if (bundle->env != NULL)
+    memcpy (header_data + env_offset, bundle->env, bundle->env_size);
   header->bundle_id_offset = GUINT32_TO_LE (id_offset);
   header->bundle_id_size = GUINT32_TO_LE (strlen (bundle->id));
   header->bundle_version_offset = GUINT32_TO_LE (version_offset);
@@ -708,6 +713,11 @@ bundle_write (Bundle *bundle, GFile *dest, GError **error)
       header->exec_offset = GUINT32_TO_LE (exec_offset);
       header->exec_size = GUINT32_TO_LE (strlen (exec));
     }
+  if (bundle->env != NULL)
+    {
+      header->env_offset = GUINT32_TO_LE (env_offset);
+      header->env_size = GUINT32_TO_LE (bundle->env_size);
+    }
   header->slices_offset = GUINT32_TO_LE (sizeof (GlickBundleHeader));
   header->num_slices = GUINT32_TO_LE (g_list_length (bundle->slices));
 
@@ -787,16 +797,11 @@ bundle_write (Bundle *bundle, GFile *dest, GError **error)
   return TRUE;
 }
 
-#define BUNDLE_GROUP_NAME "Bundle"
-#define BUNDLE_KEY_ID "Id"
-#define BUNDLE_KEY_VERSION "Version"
-#define BUNDLE_KEY_EXEC "Exec"
-#define BUNDLE_KEY_EXPORT "Export"
-
 static char *bundle_version;
 static char *bundle_id;
 static char *default_executable;
 static char **exports;
+static char **envs;
 
 static GOptionEntry entries[] =
 {
@@ -804,6 +809,7 @@ static GOptionEntry entries[] =
   { "bundle-version", 'v', 0, G_OPTION_ARG_STRING, &bundle_version, "Bundle Version (e.g 1.0)", "version" },
   { "default-executable", 'e', 0, G_OPTION_ARG_STRING, &default_executable, "Default executable path", "executable" },
   { "export", 'E', 0, G_OPTION_ARG_STRING_ARRAY, &exports, "Export file", "file" },
+  { "setenv", 's', 0, G_OPTION_ARG_STRING_ARRAY, &envs, "Set environmentvar", "value" },
   { NULL }
 };
 
@@ -851,6 +857,21 @@ main (int argc, char *argv[])
   if (default_executable)
     bundle_set_default_executable (bundle, default_executable);
 
+  if (envs != NULL)
+    {
+      GString *str;
+      int i;
+
+      str = g_string_new ("");
+      for (i = 0; envs[i] != NULL; i++)
+	{
+	  g_string_append (str, envs[i]);
+	  g_string_append_c (str, 0);
+	}
+      bundle->env_size = str->len;
+      bundle->env = g_string_free (str, FALSE);
+    }
+
   root = slurp_files (argv[1], "/", "/");
 
   exports_root = NULL;
diff --git a/runner.c b/runner.c
index a5ac2fe..4eebd6b 100644
--- a/runner.c
+++ b/runner.c
@@ -348,6 +348,8 @@ main (int argc, char *argv[])
   gsize header_size;
   char *default_executable;
   char *exec, *argv0;
+  char **extra_env;
+  size_t extra_env_size;
   char *bundle_path;
   char *custom_executable;
   int argc_offset;
@@ -394,6 +396,45 @@ main (int argc, char *argv[])
       g_strndup (data + GUINT32_FROM_LE (header->exec_offset),
 		 GUINT32_FROM_LE (header->exec_size));
 
+  extra_env = NULL;
+  if (header->env_offset != 0 && header->env_size != 0)
+    {
+      int count;
+      char *p, *v, *v_end, *end;
+
+      extra_env_size = GUINT32_FROM_LE (header->env_size);
+      p = data + GUINT32_FROM_LE (header->env_offset);
+      end = p + extra_env_size;
+
+      count = 0;
+      for (i = 0; i < extra_env_size; i++)
+	{
+	  if (p[i] == 0)
+	    count++;
+	}
+
+      extra_env = g_new0 (char *, count + 2);
+
+      count = 0;
+      v = p;
+      while (v < end)
+	{
+	  if (*v == 0)
+	    {
+	      v++;
+	      continue;
+	    }
+
+	  v_end = memchr (v, 0, end - v);
+	  if (v_end == NULL)
+	    v_end = end;
+
+	  extra_env[count++] = g_strndup (v, v_end - v);
+	  v = v_end + 1;
+	}
+      extra_env[count++] = NULL;
+    }
+
   munmap (data, header_size);
 
   homedir = g_get_home_dir ();
@@ -553,5 +594,21 @@ main (int argc, char *argv[])
   update_env_var ("XDG_DATA_DIRS",  BUNDLE_PREFIX "/data/share", "/usr/share");
   update_env_var ("PATH", BUNDLE_PREFIX "/data/bin", "/usr/bin:/bin");
 
+  if (extra_env != NULL)
+    {
+      for (i = 0; extra_env[i] != NULL; i++)
+	{
+	  char *val;
+	  val = strchr (extra_env[i], '=');
+	  if (val != NULL && val[1] != 0)
+	    {
+	      *val = 0;
+	      val = val + 1;
+
+	      setenv (extra_env[i], val, TRUE);
+	    }
+	}
+    }
+
   return execv (child_argv[0], child_argv);
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]