--- hello.c.orig	2006-02-19 18:19:43.000000000 -0500
+++ hello.c	2006-02-19 18:22:56.000000000 -0500
@@ -233,6 +233,30 @@ parse_opt (int opt, char *arg, struct ar
   return 0;
 }
 
+/* escape the \, $ and " characters in SRC and put it in *DEST.  */
+static int
+ecapestr (char *src, char **dest)
+{
+  size_t dest_len = 0;
+  *dest = NULL;
+  for (;src[0];src++)
+    {
+      if (!(*dest = realloc (*dest, ++dest_len + 1)))
+	return -1;
+      (*dest)[dest_len - 1] = src[0];
+      if (strchr ("\\$\"", src[0])) /*escape these characters */
+	{
+	  if (!(*dest = realloc (*dest, ++dest_len + 1)))
+	    return -1;
+	  (*dest)[dest_len - 1] = (*dest)[dest_len - 1 - 1];
+	  (*dest)[dest_len - 1 - 1] = '\\';
+	}
+    }
+	  
+  (*dest)[dest_len] = '\0';
+  return 0;
+}
+
 /* This will be called from libtrivfs to help construct the answer
    to an fsys_get_options RPC.  */
 error_t
@@ -242,12 +266,19 @@ trivfs_append_args (struct trivfs_contro
   error_t err;
   char *opt;
 
-  if (asprintf (&opt, "--contents=%s", contents) < 0)
-    return ENOMEM;
-
-  err = argz_add (argz, argz_len, opt);
-
-  free (opt);
+  if (contents)
+    {
+      char *escaped_contents;
+      if (escapestr (contents, &escaped_contents) < 0)
+	return ENOMEM;
+      err = asprintf (&opt, "--contents=\"%s\"", escaped_contents);
+      free (escaped_contents);
+      if (err < 0)
+	return ENOMEM;
+
+      err = argz_add (argz, argz_len, opt);
+      free (opt);
+    }
 
   return err;
 }
