edify extensions for OTA package installation, part 1

Adds the following edify functions:

  mount unmount format show_progress delete delete_recursive
  package_extract symlink set_perm set_perm_recursive

This set is enough to extract and install the system part of a (full)
OTA package.

Adds the updater binary that extracts an edify script from the OTA
package and then executes it.  Minor changes to the edify core (adds a
sleep() builtin for debugging, adds "." to the set of characters that
can appear in an unquoted string).
diff --git a/edify/expr.h b/edify/expr.h
index ac5df18..cfbef90 100644
--- a/edify/expr.h
+++ b/edify/expr.h
@@ -57,6 +57,14 @@
 char* AssertFn(const char* name, void* cookie, int argc, Expr* argv[]);
 char* AbortFn(const char* name, void* cookie, int argc, Expr* argv[]);
 
+
+// For setting and getting the global error string (when returning
+// NULL from a function).
+void SetError(const char* message);  // makes a copy
+const char* GetError();              // retains ownership
+void ClearError();
+
+
 typedef struct {
   const char* name;
   Function fn;
@@ -77,4 +85,19 @@
 // exists.
 Function FindFunction(const char* name);
 
+
+// --- convenience functions for use in functions ---
+
+// Evaluate the expressions in argv, giving 'count' char* (the ... is
+// zero or more char** to put them in).  If any expression evaluates
+// to NULL, free the rest and return -1.  Return 0 on success.
+int ReadArgs(void* cookie, Expr* argv[], int count, ...);
+
+// Evaluate the expressions in argv, returning an array of char*
+// results.  If any evaluate to NULL, free the rest and return NULL.
+// The caller is responsible for freeing the returned array and the
+// strings it contains.
+char** ReadVarArgs(void* cookie, int argc, Expr* argv[]);
+
+
 #endif  // _EXPRESSION_H