]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Added support to netdisk specified in the form (net,protocol,server_ip,username,password)
authorPaulo de Rezende Pinatti <ppinatti@linux.vnet.ibm.com>
Tue, 13 Jul 2010 14:22:35 +0000 (11:22 -0300)
committerPaulo de Rezende Pinatti <ppinatti@linux.vnet.ibm.com>
Tue, 13 Jul 2010 14:22:35 +0000 (11:22 -0300)
an to list its information with command ls.

* fs/ieee1275/ofnet.c (grub_ofnet_open): parse parameters to determine netdisk data
* fs/ieee1275/ofnet.c (grub_ofnet_close): dealloc netdisk data
* include/grub/disk.h: added struct grub_netdisk_data
* include/grub/ieee1275/ofnet.h: added newline
* kern/disk.c (grub_disk_open): ignore partition check for netdisk
* normal/misc.c (grub_normal_print_device_info): added support to list netdisk information

fs/ieee1275/ofnet.c
include/grub/disk.h
include/grub/ieee1275/ofnet.h
kern/disk.c
normal/misc.c

index a9d16e7e01429453e956adf7eeed07fd0fecca4f..9010317ba977754e0334914606624ab49a168b3a 100644 (file)
 
 //static grub_ieee1275_ihandle_t handle = 0;
 
+static const char *
+find_sep (const char *name)
+{
+  const char *p = name;
+  char c = *p;
+
+  if (c == '\0')
+    return NULL;
+
+  do
+    {
+      if (c == '\\' && *p == ',')
+    p++;
+      else if (c == ',')
+    return p - 1;
+    } while ((c = *p++) != '\0');
+  return p - 1;
+}
+
+static grub_err_t
+retrieve_field(const char *src, char **field, const char **rest)
+{
+  const char *p;
+  grub_size_t len;
+
+  p = find_sep(src);
+  if (! p)
+    {
+      *field = NULL;
+      *rest = src;
+      return 0;
+    }
+
+  len = p - src;
+  *field = grub_malloc (len + 1);
+  if (! *field)
+  {
+      return grub_error (GRUB_ERR_OUT_OF_MEMORY, "fail to alloc memory");
+  }
+
+  grub_memcpy (*field, src, len);
+  (*field)[len] = '\0';
+
+  if (*p == '\0')
+    *rest = p;
+  else
+    *rest = p + 1;
+  return 0;
+}
+
+static grub_err_t
+parse_ip (const char *val, grub_uint32_t *ip, const char **rest)
+{
+  grub_uint32_t newip = 0;
+  unsigned long t;
+  int i;
+  const char *ptr = val;
+
+  for (i = 0; i < 4; i++)
+    {
+      t = grub_strtoul (ptr, (char **) &ptr, 0);
+      if (grub_errno)
+       return grub_errno;
+      if (t & ~0xff)
+       return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP.");
+      newip >>= 8;
+      newip |= (t << 24);
+      if (i != 3 && *ptr != '.')
+       return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP.");
+      ptr++;
+    }
+  ptr = ptr - 1;
+  if ( *ptr != '\0' && *ptr != ',')
+       return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP.");
+  *ip = newip;
+  if (rest)
+    *rest = ptr;
+  return 0;
+}
 
 static int
 grub_ofnet_iterate (int (*hook) (const char *name))
@@ -54,23 +133,93 @@ grub_ofnet_iterate (int (*hook) (const char *name))
 static grub_err_t
 grub_ofnet_open (const char *name, grub_disk_t disk)
 {
-
+  grub_err_t err;
+  const char *p1, *p2;
+  char *user = NULL, *pwd = NULL;
+  grub_netdisk_data_t data;
+  grub_netdisk_protocol_t proto;
+  grub_uint32_t server_ip = 0;
 
   if (grub_strcmp (name, "net"))
-      return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a net disk");
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a net disk");
+
+  p1 = find_sep(disk->name);
+  if (! p1 || *p1 == '\0')
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "arguments missing");
+  p1++;
+
+  // parse protocol
+  p2 = find_sep(p1);
+  if (! p2)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no protocol specified");
+  if ((p2 - p1 == 4) && (! grub_strncasecmp(p1, "tftp", p2 - p1)))
+    proto = GRUB_NETDISK_PROTOCOL_TFTP;
+  else
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid protocol specified");
+
+  // parse server ip
+  if ( *p2 == '\0')
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no server ip specified");
+  p1 = p2 + 1;
+  err = parse_ip(p1, &server_ip, &p2);
+  if (err)
+    return err;
+
+  // parse username (optional)
+  if ( *p2 == ',')
+    p2++;
+  err = retrieve_field(p2, &user, &p1);
+  if (err)
+    return err;
+  if (user)
+  {
+    // parse password (optional)
+    err = retrieve_field(p1, &pwd, &p2);
+    if (err)
+    {
+      grub_free(user);
+      return err;
+    }
+  }
 
-  disk->total_sectors = U64MAXSIZE;
+  if (! disk->data)
+    {
+      data = grub_malloc (sizeof(*data));
+      disk->data = data;
+    }
+  else
+    {
+      data = disk->data;
+      if (data->username)
+        grub_free(data->username);
+      if (data->password)
+        grub_free(data->password);
+    }
+  data->protocol = proto;
+  data->server_ip = server_ip;
+  data->username = user;
+  data->password = pwd;
+
+  disk->total_sectors = 0;
   disk->id = (unsigned long) "net";
 
   disk->has_partitions = 0;
-  disk->data = 0;
 
   return GRUB_ERR_NONE;
 }
 
 static void
-grub_ofnet_close (grub_disk_t disk __attribute((unused)))
+grub_ofnet_close (grub_disk_t disk)
 {
+  grub_netdisk_data_t data = disk->data;
+  if (data)
+    {
+      if (data->username)
+        grub_free(data->username);
+      if (data->password)
+        grub_free(data->password);
+      grub_free(data);
+    }
 }
 
 static grub_err_t
index 1bdfb639b962396a20f9442ade1e14d14a50c649..dc8bc501886e9d6f2061c81a45b98d1a8da95854 100644 (file)
@@ -119,6 +119,23 @@ struct grub_disk
 };
 typedef struct grub_disk *grub_disk_t;
 
+/* Net Disk */
+enum grub_netdisk_protocol 
+{
+  GRUB_NETDISK_PROTOCOL_TFTP
+};
+typedef enum grub_netdisk_protocol grub_netdisk_protocol_t;
+
+struct grub_netdisk_data
+{
+  grub_netdisk_protocol_t protocol;
+  grub_uint32_t server_ip;
+  grub_uint32_t port;
+  char *username;
+  char *password;
+};
+typedef struct grub_netdisk_data *grub_netdisk_data_t;
+
 #ifdef GRUB_UTIL
 struct grub_disk_memberlist
 {
index 7daadf61d7b0db34bcae369b06486d2c00b2e715..a26c22235281fe2ec0dcc68f780f97c8817248a3 100644 (file)
@@ -25,6 +25,7 @@
 
 extern void grub_ofnet_init(void);
 extern void grub_ofnet_fini(void);
+
 /*
 struct grub_net;
 
index ccd5f200f9bb9a60858b9331a0ce2143860666e9..051e59acabbd2b125986228497e53aa33ba16dd2 100644 (file)
@@ -281,7 +281,7 @@ grub_disk_open (const char *name)
       goto fail;
     }
 
-  if (p && ! disk->has_partitions)
+  if (p && ! disk->has_partitions && grub_strcmp (raw, "net"))
     {
       grub_error (GRUB_ERR_BAD_DEVICE, "no partition on this disk");
       goto fail;
@@ -289,7 +289,7 @@ grub_disk_open (const char *name)
 
   disk->dev = dev;
 
-  if (p)
+  if (p && grub_strcmp (raw, "net"))
     {
       disk->partition = grub_partition_probe (disk, p + 1);
       if (! disk->partition)
index 17ba372ce816aa051d04335ab2664681967b663a..d53fe711c84dce040655602d752386cb69907a70 100644 (file)
@@ -32,8 +32,47 @@ grub_err_t
 grub_normal_print_device_info (const char *name)
 {
   grub_device_t dev;
+  grub_netdisk_data_t data;
   char *p;
 
+  if ((! grub_strcmp(name, "net")) || (! grub_strncmp(name, "net,", 4)))
+    {
+      grub_printf_ (N_("Device network:"));
+      grub_putchar (' ');
+
+      dev = grub_device_open (name);
+      if (! dev || ! dev->disk || ! dev->disk->data)
+        grub_printf ("%s", _("Network information not available"));
+      else
+        {
+          data = dev->disk->data;
+          grub_putchar ('\n');
+          grub_putchar ('\t');
+          if (data->protocol == GRUB_NETDISK_PROTOCOL_TFTP)
+            grub_printf_(N_("Protocol: %s"), "TFTP"); 
+          else
+            grub_printf_(N_("Protocol: %s"), "Unknown"); 
+          grub_putchar ('\n');
+          grub_putchar ('\t');
+          grub_printf_(N_("Server IP: %d.%d.%d.%d"), data->server_ip & 0xff, data->server_ip >> 8 & 0xff, data->server_ip >> 16 & 0xff, data->server_ip >> 24 & 0xff); 
+          if (data->username)
+            {
+              grub_putchar ('\n');
+              grub_putchar ('\t');
+              grub_printf_(N_("Username: %s"), data->username); 
+              if (data->password)
+                {
+                  grub_putchar ('\n');
+                  grub_putchar ('\t');
+                  grub_printf_(N_("Password: %s"), data->password); 
+                }
+            }
+        }
+      grub_putchar ('\n');
+
+      return GRUB_ERR_NONE;
+    }
+
   p = grub_strchr (name, ',');
   if (p)
     {