Needed for Hurd 0.3

2008-08-19 Zheng Da <zhengda1936@gmail.com>

	* boot/boot.c: Add '-f' option.
	(dev_map): New structure.
	(dev_map_head): New variable.
	(add_dev_map): New function.
	(lookup_dev): New function.
	(parse_opt): Handle the '-f' option.
	(ds_device_open): Open the device from the device file.

diff -u boot.old/boot.c boot/boot.c
--- boot.old/boot.c	2008-08-17 18:38:02.000000000 +0200
+++ boot/boot.c	2008-08-18 00:19:40.830000000 +0200
@@ -432,14 +432,53 @@
     "Pause for user confirmation at various times during booting" },
   { "isig",      'I', 0, 0,
     "Do not disable terminal signals, so you can suspend and interrupt boot."},
+  { "device",	   'f', "device name=device file", 0,
+    "Specify the device file used by subhurd and its name."},
   { 0 }
 };
 static char args_doc[] = "BOOT-SCRIPT";
 static char doc[] = "Boot a second hurd";
 
+struct dev_map 
+{
+  char *name;
+  mach_port_t port;
+  struct dev_map *next;
+};
+
+static struct dev_map *dev_map_head;
+
+static struct dev_map *add_dev_map (char *dev_name, char *dev_file)
+{
+  struct dev_map *map = (struct dev_map *) malloc (sizeof (*map));
+
+  assert (map);
+  map->name = dev_name;
+  map->port = file_name_lookup (dev_file, 0, 0);
+  if (map->port == MACH_PORT_NULL)
+    error (1, errno, "file_name_lookup: %s", dev_file);
+  map->next = dev_map_head;
+  dev_map_head = map;
+  return map;
+}
+
+static struct dev_map *lookup_dev (char *dev_name)
+{
+  struct dev_map *map;
+
+  for (map = dev_map_head; map; map = map->next)
+    {
+      if (strcmp (map->name, dev_name) == 0)
+	return map;
+    }
+  return NULL;
+}
+
 static error_t
 parse_opt (int key, char *arg, struct argp_state *state)
 {
+  char *dev_file;
+
   switch (key)
     {
       size_t len;
@@ -458,6 +497,14 @@
       bootstrap_args[len] = '\0';
       break;
 
+    case 'f':
+      dev_file = strchr (arg, '=');
+      if (dev_file == NULL)
+	return ARGP_ERR_UNKNOWN;
+      *dev_file = 0;
+      add_dev_map (arg, dev_file+1);
+      break;
+
     case ARGP_KEY_ARG:
       if (state->arg_num == 0)
 	bootscript = arg;
@@ -942,6 +989,8 @@
 		mach_port_t *device,
 		mach_msg_type_name_t *devicetype)
 {
+  struct dev_map *map;
+
   if (master_port != pseudo_master_device_port)
     return D_INVALID_OPERATION;
 
@@ -965,6 +1014,13 @@
       return 0;
     }
 
+  map = lookup_dev (name);
+  if (map)
+    {
+      *devicetype = MACH_MSG_TYPE_MOVE_SEND;
+      return device_open (map->port, mode, "", device);
+    }
+
   *devicetype = MACH_MSG_TYPE_MOVE_SEND;
   return device_open (master_device_port, mode, name, device);
 }
