NULL
};
+static bool is_pxe;
+
/*
* Like getenv, but prints an error if envvar isn't defined in the
* environment. It always returns what getenv does, so it can be used in
uchar ethaddr[6];
if (outbuf_len < 21) {
- printf("outbuf is too small (%d < 21)\n", outbuf_len);
+ printf("outbuf is too small (%zd < 21)\n", outbuf_len);
return -EINVAL;
}
char *bootfile, *last_slash;
size_t path_len = 0;
- if (file_path[0] == '/')
+ /* Only syslinux allows absolute paths */
+ if (file_path[0] == '/' && !is_pxe)
goto ret;
bootfile = from_env("bootfile");
path_len = (last_slash - bootfile) + 1;
if (bootfile_path_size < path_len) {
- printf("bootfile_path too small. (%d < %d)\n",
+ printf("bootfile_path too small. (%zd < %zd)\n",
bootfile_path_size, path_len);
return -1;
return 1;
}
-static int (*do_getfile)(const char *file_path, char *file_addr);
+static int (*do_getfile)(cmd_tbl_t *cmdtp, const char *file_path, char *file_addr);
-static int do_get_tftp(const char *file_path, char *file_addr)
+static int do_get_tftp(cmd_tbl_t *cmdtp, const char *file_path, char *file_addr)
{
char *tftp_argv[] = {"tftp", NULL, NULL, NULL};
tftp_argv[1] = file_addr;
tftp_argv[2] = (void *)file_path;
- if (do_tftpb(NULL, 0, 3, tftp_argv))
+ if (do_tftpb(cmdtp, 0, 3, tftp_argv))
return -ENOENT;
return 1;
static char *fs_argv[5];
-static int do_get_ext2(const char *file_path, char *file_addr)
+static int do_get_ext2(cmd_tbl_t *cmdtp, const char *file_path, char *file_addr)
{
#ifdef CONFIG_CMD_EXT2
fs_argv[0] = "ext2load";
fs_argv[3] = file_addr;
fs_argv[4] = (void *)file_path;
- if (!do_ext2load(NULL, 0, 5, fs_argv))
+ if (!do_ext2load(cmdtp, 0, 5, fs_argv))
return 1;
#endif
return -ENOENT;
}
-static int do_get_fat(const char *file_path, char *file_addr)
+static int do_get_fat(cmd_tbl_t *cmdtp, const char *file_path, char *file_addr)
{
#ifdef CONFIG_CMD_FAT
fs_argv[0] = "fatload";
fs_argv[3] = file_addr;
fs_argv[4] = (void *)file_path;
- if (!do_fat_fsload(NULL, 0, 5, fs_argv))
+ if (!do_fat_fsload(cmdtp, 0, 5, fs_argv))
return 1;
#endif
return -ENOENT;
*
* Returns 1 for success, or < 0 on error.
*/
-static int get_relfile(const char *file_path, void *file_addr)
+static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr)
{
size_t path_len;
char relfile[MAX_TFTP_PATH_LEN+1];
sprintf(addr_buf, "%p", file_addr);
- return do_getfile(relfile, addr_buf);
+ return do_getfile(cmdtp, relfile, addr_buf);
}
/*
*
* Returns 1 on success, or < 0 for error.
*/
-static int get_pxe_file(const char *file_path, void *file_addr)
+static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr)
{
unsigned long config_file_size;
char *tftp_filesize;
int err;
- err = get_relfile(file_path, file_addr);
+ err = get_relfile(cmdtp, file_path, file_addr);
if (err < 0)
return err;
*
* Returns 1 on success or < 0 on error.
*/
-static int get_pxelinux_path(const char *file, void *pxefile_addr_r)
+static int get_pxelinux_path(cmd_tbl_t *cmdtp, const char *file, void *pxefile_addr_r)
{
size_t base_len = strlen(PXELINUX_DIR);
char path[MAX_TFTP_PATH_LEN+1];
sprintf(path, PXELINUX_DIR "%s", file);
- return get_pxe_file(path, pxefile_addr_r);
+ return get_pxe_file(cmdtp, path, pxefile_addr_r);
}
/*
*
* Returns 1 on success or < 0 on error.
*/
-static int pxe_uuid_path(void *pxefile_addr_r)
+static int pxe_uuid_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r)
{
char *uuid_str;
if (!uuid_str)
return -ENOENT;
- return get_pxelinux_path(uuid_str, pxefile_addr_r);
+ return get_pxelinux_path(cmdtp, uuid_str, pxefile_addr_r);
}
/*
*
* Returns 1 on success or < 0 on error.
*/
-static int pxe_mac_path(void *pxefile_addr_r)
+static int pxe_mac_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r)
{
char mac_str[21];
int err;
if (err < 0)
return err;
- return get_pxelinux_path(mac_str, pxefile_addr_r);
+ return get_pxelinux_path(cmdtp, mac_str, pxefile_addr_r);
}
/*
*
* Returns 1 on success or < 0 on error.
*/
-static int pxe_ipaddr_paths(void *pxefile_addr_r)
+static int pxe_ipaddr_paths(cmd_tbl_t *cmdtp, void *pxefile_addr_r)
{
char ip_addr[9];
int mask_pos, err;
sprintf(ip_addr, "%08X", ntohl(NetOurIP));
for (mask_pos = 7; mask_pos >= 0; mask_pos--) {
- err = get_pxelinux_path(ip_addr, pxefile_addr_r);
+ err = get_pxelinux_path(cmdtp, ip_addr, pxefile_addr_r);
if (err > 0)
return err;
* Keep trying paths until we successfully get a file we're looking
* for.
*/
- if (pxe_uuid_path((void *)pxefile_addr_r) > 0 ||
- pxe_mac_path((void *)pxefile_addr_r) > 0 ||
- pxe_ipaddr_paths((void *)pxefile_addr_r) > 0) {
+ if (pxe_uuid_path(cmdtp, (void *)pxefile_addr_r) > 0 ||
+ pxe_mac_path(cmdtp, (void *)pxefile_addr_r) > 0 ||
+ pxe_ipaddr_paths(cmdtp, (void *)pxefile_addr_r) > 0) {
printf("Config file found\n");
return 0;
}
while (pxe_default_paths[i]) {
- if (get_pxelinux_path(pxe_default_paths[i],
+ if (get_pxelinux_path(cmdtp, pxe_default_paths[i],
(void *)pxefile_addr_r) > 0) {
printf("Config file found\n");
return 0;
*
* Returns 1 on success or < 0 on error.
*/
-static int get_relfile_envaddr(const char *file_path, const char *envaddr_name)
+static int get_relfile_envaddr(cmd_tbl_t *cmdtp, const char *file_path, const char *envaddr_name)
{
unsigned long file_addr;
char *envaddr;
if (strict_strtoul(envaddr, 16, &file_addr) < 0)
return -EINVAL;
- return get_relfile(file_path, (void *)file_addr);
+ return get_relfile(cmdtp, file_path, (void *)file_addr);
}
/*
* If the label specifies an 'append' line, its contents will overwrite that
* of the 'bootargs' environment variable.
*/
-static int label_boot(struct pxe_label *label)
+static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
{
char *bootm_argv[] = { "bootm", NULL, NULL, NULL, NULL };
char initrd_str[22];
}
if (label->initrd) {
- if (get_relfile_envaddr(label->initrd, "ramdisk_addr_r") < 0) {
+ if (get_relfile_envaddr(cmdtp, label->initrd, "ramdisk_addr_r") < 0) {
printf("Skipping %s for failure retrieving initrd\n",
label->name);
return 1;
bootm_argv[2] = "-";
}
- if (get_relfile_envaddr(label->kernel, "kernel_addr_r") < 0) {
+ if (get_relfile_envaddr(cmdtp, label->kernel, "kernel_addr_r") < 0) {
printf("Skipping %s for failure retrieving kernel\n",
label->name);
return 1;
/* if fdt label is defined then get fdt from server */
if (bootm_argv[3] && label->fdt) {
- if (get_relfile_envaddr(label->fdt, "fdt_addr_r") < 0) {
+ if (get_relfile_envaddr(cmdtp, label->fdt, "fdt_addr_r") < 0) {
printf("Skipping %s for failure retrieving fdt\n",
label->name);
return 1;
if (bootm_argv[3])
bootm_argc = 4;
- do_bootm(NULL, 0, bootm_argc, bootm_argv);
+ do_bootm(cmdtp, 0, bootm_argc, bootm_argv);
#ifdef CONFIG_CMD_BOOTZ
/* Try booting a zImage if do_bootm returns */
- do_bootz(NULL, 0, bootm_argc, bootm_argv);
+ do_bootz(cmdtp, 0, bootm_argc, bootm_argv);
#endif
return 1;
}
return 1;
}
-static int parse_pxefile_top(char *p, struct pxe_menu *cfg, int nest_level);
+static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, int nest_level);
/*
* Parse an include statement, and retrieve and parse the file it mentions.
* include, nest_level has already been incremented and doesn't need to be
* incremented here.
*/
-static int handle_include(char **c, char *base,
+static int handle_include(cmd_tbl_t *cmdtp, char **c, char *base,
struct pxe_menu *cfg, int nest_level)
{
char *include_path;
return err;
}
- err = get_pxe_file(include_path, base);
+ err = get_pxe_file(cmdtp, include_path, base);
if (err < 0) {
printf("Couldn't retrieve %s\n", include_path);
return err;
}
- return parse_pxefile_top(base, cfg, nest_level);
+ return parse_pxefile_top(cmdtp, base, cfg, nest_level);
}
/*
* nest_level should be 1 when parsing the top level pxe file, 2 when parsing
* a file it includes, 3 when parsing a file included by that file, and so on.
*/
-static int parse_menu(char **c, struct pxe_menu *cfg, char *b, int nest_level)
+static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg, char *b, int nest_level)
{
struct token t;
char *s = *c;
break;
case T_INCLUDE:
- err = handle_include(c, b + strlen(b) + 1, cfg,
+ err = handle_include(cmdtp, c, b + strlen(b) + 1, cfg,
nest_level + 1);
break;
*
* Returns 1 on success, < 0 on error.
*/
-static int parse_pxefile_top(char *p, struct pxe_menu *cfg, int nest_level)
+static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, int nest_level)
{
struct token t;
char *s, *b, *label_name;
switch (t.type) {
case T_MENU:
cfg->prompt = 1;
- err = parse_menu(&p, cfg, b, nest_level);
+ err = parse_menu(cmdtp, &p, cfg, b, nest_level);
break;
case T_TIMEOUT:
break;
case T_INCLUDE:
- err = handle_include(&p, b + ALIGN(strlen(b), 4), cfg,
+ err = handle_include(cmdtp, &p, b + ALIGN(strlen(b), 4), cfg,
nest_level + 1);
break;
* files it includes). The resulting pxe_menu struct can be free()'d by using
* the destroy_pxe_menu() function.
*/
-static struct pxe_menu *parse_pxefile(char *menucfg)
+static struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, char *menucfg)
{
struct pxe_menu *cfg;
INIT_LIST_HEAD(&cfg->labels);
- if (parse_pxefile_top(menucfg, cfg, 1) < 0) {
+ if (parse_pxefile_top(cmdtp, menucfg, cfg, 1) < 0) {
destroy_pxe_menu(cfg);
return NULL;
}
/*
* Try to boot any labels we have yet to attempt to boot.
*/
-static void boot_unattempted_labels(struct pxe_menu *cfg)
+static void boot_unattempted_labels(cmd_tbl_t *cmdtp, struct pxe_menu *cfg)
{
struct list_head *pos;
struct pxe_label *label;
label = list_entry(pos, struct pxe_label, list);
if (!label->attempted)
- label_boot(label);
+ label_boot(cmdtp, label);
}
}
* If this function returns, there weren't any labels that successfully
* booted, or the user interrupted the menu selection via ctrl+c.
*/
-static void handle_pxe_menu(struct pxe_menu *cfg)
+static void handle_pxe_menu(cmd_tbl_t *cmdtp, struct pxe_menu *cfg)
{
void *choice;
struct menu *m;
*/
if (err == 1) {
- err = label_boot(choice);
+ err = label_boot(cmdtp, choice);
if (!err)
return;
} else if (err != -ENOENT) {
return;
}
- boot_unattempted_labels(cfg);
+ boot_unattempted_labels(cmdtp, cfg);
}
/*
return 1;
}
- cfg = parse_pxefile((char *)(pxefile_addr_r));
+ cfg = parse_pxefile(cmdtp, (char *)(pxefile_addr_r));
if (cfg == NULL) {
printf("Error parsing config file\n");
return 1;
}
- handle_pxe_menu(cfg);
+ handle_pxe_menu(cmdtp, cfg);
destroy_pxe_menu(cfg);
if (argc < 2)
return CMD_RET_USAGE;
+ is_pxe = true;
+
/* drop initial "pxe" arg */
argc--;
argv++;
char *filename;
int prompt = 0;
+ is_pxe = false;
+
if (strstr(argv[1], "-p")) {
prompt = 1;
argc--;
return 1;
}
- if (get_pxe_file(filename, (void *)pxefile_addr_r) < 0) {
+ if (get_pxe_file(cmdtp, filename, (void *)pxefile_addr_r) < 0) {
printf("Error reading config file\n");
return 1;
}
- cfg = parse_pxefile((char *)(pxefile_addr_r));
+ cfg = parse_pxefile(cmdtp, (char *)(pxefile_addr_r));
if (cfg == NULL) {
printf("Error parsing config file\n");
if (prompt)
cfg->prompt = 1;
- handle_pxe_menu(cfg);
+ handle_pxe_menu(cmdtp, cfg);
destroy_pxe_menu(cfg);