Added support to netdisk specified in the form (net,protocol,server_ip,username,password)
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
This commit is contained in:
parent
3ec6213b17
commit
f8795693f1
5 changed files with 213 additions and 7 deletions
|
@ -42,6 +42,85 @@
|
||||||
|
|
||||||
//static grub_ieee1275_ihandle_t handle = 0;
|
//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
|
static int
|
||||||
grub_ofnet_iterate (int (*hook) (const char *name))
|
grub_ofnet_iterate (int (*hook) (const char *name))
|
||||||
|
@ -54,23 +133,93 @@ grub_ofnet_iterate (int (*hook) (const char *name))
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_ofnet_open (const char *name, grub_disk_t disk)
|
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"))
|
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");
|
||||||
|
|
||||||
disk->total_sectors = U64MAXSIZE;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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->id = (unsigned long) "net";
|
||||||
|
|
||||||
disk->has_partitions = 0;
|
disk->has_partitions = 0;
|
||||||
disk->data = 0;
|
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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
|
static grub_err_t
|
||||||
|
|
|
@ -119,6 +119,23 @@ struct grub_disk
|
||||||
};
|
};
|
||||||
typedef struct grub_disk *grub_disk_t;
|
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
|
#ifdef GRUB_UTIL
|
||||||
struct grub_disk_memberlist
|
struct grub_disk_memberlist
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
extern void grub_ofnet_init(void);
|
extern void grub_ofnet_init(void);
|
||||||
extern void grub_ofnet_fini(void);
|
extern void grub_ofnet_fini(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
struct grub_net;
|
struct grub_net;
|
||||||
|
|
||||||
|
|
|
@ -281,7 +281,7 @@ grub_disk_open (const char *name)
|
||||||
goto fail;
|
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");
|
grub_error (GRUB_ERR_BAD_DEVICE, "no partition on this disk");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -289,7 +289,7 @@ grub_disk_open (const char *name)
|
||||||
|
|
||||||
disk->dev = dev;
|
disk->dev = dev;
|
||||||
|
|
||||||
if (p)
|
if (p && grub_strcmp (raw, "net"))
|
||||||
{
|
{
|
||||||
disk->partition = grub_partition_probe (disk, p + 1);
|
disk->partition = grub_partition_probe (disk, p + 1);
|
||||||
if (! disk->partition)
|
if (! disk->partition)
|
||||||
|
|
|
@ -32,8 +32,47 @@ grub_err_t
|
||||||
grub_normal_print_device_info (const char *name)
|
grub_normal_print_device_info (const char *name)
|
||||||
{
|
{
|
||||||
grub_device_t dev;
|
grub_device_t dev;
|
||||||
|
grub_netdisk_data_t data;
|
||||||
char *p;
|
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, ',');
|
p = grub_strchr (name, ',');
|
||||||
if (p)
|
if (p)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue