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 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");
|
||||
|
||||
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->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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
extern void grub_ofnet_init(void);
|
||||
extern void grub_ofnet_fini(void);
|
||||
|
||||
/*
|
||||
struct grub_net;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue