diff --git a/bin/mkpackage.pike b/bin/mkpackage.pike
new file mode 100644
index 0000000000000000000000000000000000000000..2ba217f6e710694188c06e003e6ed7fd6cbda9fb
--- /dev/null
+++ b/bin/mkpackage.pike
@@ -0,0 +1,161 @@
+/* Module for creating executable installation scripts based on Pike. */
+
+#define ERR(msg) throw(({ "(Install) "+sprintf msg+"\n", backtrace() }))
+
+int mkdirhier(string path, int|void mod)
+{
+  string a = "";
+  int r = 1;
+
+  if(Stdio.is_dir(path))
+    return query_num_arg() == 1 ? 1 : (chmod(path, mod),1);
+  
+  foreach(path/"/", string d)
+  {
+    a += d + "/";
+    if(sizeof(d))
+      if(query_num_arg() == 1)
+	r = mkdir(a);
+      else
+	r = mkdir(a, mod);
+  }
+  
+  return r || (query_num_arg() == 2 && (chmod(path, mod),1));
+}
+
+
+
+void rmrf(string ... path)
+{
+  Process.create_process(({ "rm","-rf", @path }))->wait();
+}
+
+class Package
+{
+  static private string install_filename, pike_filename;
+  static private mapping(array(string):string) options =
+  ([ ({ "-h", "--help" }):
+     "echo \"Usage: $TARFILE [options]\"\n"
+     "echo \n"
+     "echo 'Options:'\n"
+     "echo '  -h, --help              Display this help and exit.'\n"
+     "echo '  -l, --list              Display the contents of the package and exit.'\n"
+     "echo '  -v, --version           Display version information and exit.'\n"
+     "echo '  -a, --add <component>   Add a component to the package and exit.'\n"
+     "echo\n"
+     "echo 'When no arguments are given, the installation script will be started.'\n"
+     "exit",
+     ({ "-v", "--version" }):
+     "echo 'Package version unknown.'\n"
+     "exit",
+     ({ "-a", "--add-component" }):
+     "shift; ORIGINAL_WD=\"`pwd`\"\n"
+     "(cd `dirname \"$1\"` &&\n"
+     " tar rf \"$ORIGINAL_WD/$TARFILE\" `basename \"$1\"`)\n"
+     "exit",
+     ({ "-l", "--list" }):
+     "echo \"$CONTENTS\"\n"
+     "exit" ]);
+  static private array(string) packages = ({});
+  
+  static private string unique_name(int c)
+  {
+    return sprintf("%ctmP%07x", c, random(0xfffffff));
+  }
+
+  string make(string package_filename)
+  {
+    string setup_filename = unique_name('S')+".sh";
+    string unpack_directory = unique_name('D');
+
+    string setup = ("#!/bin/sh\n"
+		    "TARFILE=\"$1\"; shift; ARGS=''\n"
+		    "CONTENTS=`tar tf \"$TARFILE\" | sed -ne '/^"+
+		    replace(install_filename, ".", "\\.")+"/,$p'`\n"
+		    // Check all arguments for possible options.
+		    "while [ $# != 0 ]\n"
+		    "do\n"
+		    "  case \"$1\" in\n"
+		    +Array.map(sort(indices(options)),
+			       lambda(array(string) flags)
+			       {
+				 return flags*"|"+") "+options[flags]+" ;;\n";
+			       })*""+
+		    "  esac\n"
+		    "  ARGS=\"$ARGS '`echo \\\"$1\\\" | sed -e \\\"s/'/'\\\\\\\"'\\\\\\\"'/g\\\"`'\"\n"
+		    "  shift\n"
+		    "done\n"
+		    // Commence installation.
+		    "mkdir "+unpack_directory+"\n"
+		    "(cd "+unpack_directory+"\n"
+		    " tar xf ../\"$TARFILE\" $CONTENTS\n"
+		    " ./"+(pike_filename/"/")[-1]+" "
+		                "--script \"`pwd`\"/"+install_filename+")\n"
+		    "rm -rf "+setup_filename+" "+unpack_directory+"\n");
+    
+    string bootstrap = sprintf("#!/bin/sh\n"
+			       "tar xf \"$0\" %s\n"
+			       "exec ./%s \"$0\" \"$@\"\n",
+			       setup_filename,
+			       setup_filename,
+			       setup_filename);
+		    
+    rmrf("#!", setup_filename);
+    
+    if(!Stdio.write_file(setup_filename, setup))
+      ERR(("Failed to write setup script %O., ", setup_filename));
+    chmod(setup_filename, 0755);
+		   
+    if(!mkdirhier(bootstrap, 0755))
+      ERR(("Failed to create bootstrap %O., ", bootstrap));
+
+    Process.create_process(({ "tar", "cf",
+			      package_filename,
+			      bootstrap,
+			      setup_filename }))->wait();
+
+    packages = ({ install_filename, pike_filename }) + packages;
+    
+    string original_wd = getcwd();
+    foreach(packages, string package)
+    {
+      array(string) path_parts = package/"/";
+      
+      cd(path_parts[0..sizeof(path_parts)-2]*"/");
+      Process.create_process(({ "tar", "rf",
+				combine_path(original_wd, package_filename),
+				path_parts[-1] }))->wait();
+      cd(original_wd);
+    }
+
+    chmod(package_filename, 0755);
+
+    rmrf("#!", setup_filename);
+  }
+
+  Package add_packages(string ... _packages)
+  {
+    packages += _packages;
+    
+    return this_object();
+  }
+  
+  void create(string _pike_filename, string _install_filename)
+  {
+    pike_filename = _pike_filename;
+    install_filename = _install_filename;
+  }
+}
+
+int main(int argc, array(string) argv)
+{
+  if(argc < 4)
+  {
+    werror("Usage: make-package.pike <name> <pike binary> <install script> [packages ...]\n");
+    return 1;
+  }
+  
+  Package(argv[2], argv[3])->add_packages(@argv[4..])->make(argv[1]);
+  
+  return 0;
+}