if (outbuf_len < 21) {
printf("outbuf is too small (%zd < 21)\n", outbuf_len);
-
return -ENOSPC;
}
}
/**
- * get_bootfile_path() - Figure out the path of a file to read
- *
- * Returns the directory the file specified in the 'bootfile' env variable is
- * in. If bootfile isn't defined in the environment, return NULL, which should
- * be interpreted as "don't prepend anything to paths".
- *
- * @file_path: File path to read (relative to the PXE file)
- * @bootfile_path: Place to put the bootfile path
- * @bootfile_path_size: Size of @bootfile_path in bytes
- * @allow_abs_path: true to allow an absolute path (where @file_path starts with
- * '/', false to return an empty path (and success) in that case
- * Returns 1 for success, -ENOSPC if bootfile_path_size is to small to hold the
- * resulting path
- */
-static int get_bootfile_path(const char *file_path, char *bootfile_path,
- size_t bootfile_path_size, bool allow_abs_path)
-{
- char *bootfile, *last_slash;
- size_t path_len = 0;
-
- /* Only syslinux allows absolute paths */
- if (file_path[0] == '/' && allow_abs_path)
- goto ret;
-
- bootfile = from_env("bootfile");
-
- if (!bootfile)
- goto ret;
-
- last_slash = strrchr(bootfile, '/');
-
- if (!last_slash)
- goto ret;
-
- path_len = (last_slash - bootfile) + 1;
-
- if (bootfile_path_size < path_len) {
- printf("bootfile_path too small. (%zd < %zd)\n",
- bootfile_path_size, path_len);
-
- return -ENOSPC;
- }
-
- strncpy(bootfile_path, bootfile, path_len);
-
- ret:
- bootfile_path[path_len] = '\0';
-
- return 1;
-}
-
-/**
* get_relfile() - read a file relative to the PXE file
*
* As in pxelinux, paths to files referenced from files we retrieve are
size_t path_len;
char relfile[MAX_TFTP_PATH_LEN + 1];
char addr_buf[18];
- int err;
- err = get_bootfile_path(file_path, relfile, sizeof(relfile),
- ctx->allow_abs_path);
+ if (file_path[0] == '/' && ctx->allow_abs_path)
+ *relfile = '\0';
+ else
+ strncpy(relfile, ctx->bootdir, MAX_TFTP_PATH_LEN);
- if (err < 0)
- return err;
-
- path_len = strlen(file_path);
- path_len += strlen(relfile);
+ path_len = strlen(file_path) + strlen(relfile);
if (path_len > MAX_TFTP_PATH_LEN) {
printf("Base path too long (%s%s)\n", relfile, file_path);
char *buf;
err = get_relfile(ctx, file_path, file_addr);
-
if (err < 0)
return err;
* and add the NUL byte.
*/
tftp_filesize = from_env("filesize");
-
if (!tftp_filesize)
return -ENOENT;
char *envaddr;
envaddr = from_env(envaddr_name);
-
if (!envaddr)
return -ENOENT;
struct pxe_label *label;
label = malloc(sizeof(struct pxe_label));
-
if (!label)
return NULL;
*/
static void label_destroy(struct pxe_label *label)
{
- if (label->name)
- free(label->name);
-
- if (label->kernel)
- free(label->kernel);
-
- if (label->config)
- free(label->config);
-
- if (label->append)
- free(label->append);
-
- if (label->initrd)
- free(label->initrd);
-
- if (label->fdt)
- free(label->fdt);
-
- if (label->fdtdir)
- free(label->fdtdir);
-
- if (label->fdtoverlays)
- free(label->fdtoverlays);
-
+ free(label->name);
+ free(label->kernel);
+ free(label->config);
+ free(label->append);
+ free(label->initrd);
+ free(label->fdt);
+ free(label->fdtdir);
+ free(label->fdtoverlays);
free(label);
}
char *localcmd;
localcmd = from_env("localcmd");
-
if (!localcmd)
return -ENOENT;
unmap_sysmem(buf);
cleanup:
- if (fit_addr)
- free(fit_addr);
+ free(fit_addr);
+
return 1;
}
*/
b = *p;
e = *p;
-
while (*e) {
if ((delim == ' ' && isspace(*e)) || delim == *e)
break;
t->val[len] = '\0';
- /*
- * Update *p so the caller knows where to continue scanning.
- */
+ /* Update *p so the caller knows where to continue scanning */
*p = e;
-
t->type = T_STRING;
return t->val;
char *s = *c;
get_token(c, &t, L_SLITERAL);
-
if (t.type != T_STRING) {
printf("Expected string: %.*s\n", (int)(*c - s), s);
return -EINVAL;
int ret;
err = parse_sliteral(c, &include_path);
-
if (err < 0) {
printf("Expected include path: %.*s\n", (int)(*c - s), s);
return err;
}
err = get_pxe_file(ctx, include_path, base);
-
if (err < 0) {
printf("Couldn't retrieve %s\n", include_path);
return err;
printf("Ignoring malformed menu command: %.*s\n",
(int)(*c - s), s);
}
-
if (err < 0)
return err;
struct list_head *pos, *n;
struct pxe_label *label;
- if (cfg->title)
- free(cfg->title);
-
- if (cfg->default_label)
- free(cfg->default_label);
+ free(cfg->title);
+ free(cfg->default_label);
list_for_each_safe(pos, n, &cfg->labels) {
label = list_entry(pos, struct pxe_label, list);
int r;
cfg = malloc(sizeof(struct pxe_menu));
-
if (!cfg)
return NULL;
buf = map_sysmem(menucfg, 0);
r = parse_pxefile_top(ctx, buf, menucfg, cfg, 1);
unmap_sysmem(buf);
-
if (r < 0) {
destroy_pxe_menu(cfg);
return NULL;
*/
m = menu_create(cfg->title, DIV_ROUND_UP(cfg->timeout, 10),
cfg->prompt, NULL, label_print, NULL, NULL);
-
if (!m)
return NULL;
return;
err = menu_get_choice(m, &choice);
-
menu_destroy(m);
/*
boot_unattempted_labels(ctx, cfg);
}
-void pxe_setup_ctx(struct pxe_context *ctx, struct cmd_tbl *cmdtp,
- pxe_getfile_func getfile, void *userdata,
- bool allow_abs_path)
+int pxe_setup_ctx(struct pxe_context *ctx, struct cmd_tbl *cmdtp,
+ pxe_getfile_func getfile, void *userdata,
+ bool allow_abs_path, const char *bootfile)
{
+ const char *last_slash;
+ size_t path_len = 0;
+
+ memset(ctx, '\0', sizeof(*ctx));
ctx->cmdtp = cmdtp;
ctx->getfile = getfile;
ctx->userdata = userdata;
ctx->allow_abs_path = allow_abs_path;
+
+ /* figure out the boot directory, if there is one */
+ if (bootfile && strlen(bootfile) >= MAX_TFTP_PATH_LEN)
+ return -ENOSPC;
+ ctx->bootdir = strdup(bootfile ? bootfile : "");
+ if (!ctx->bootdir)
+ return -ENOMEM;
+
+ if (bootfile) {
+ last_slash = strrchr(bootfile, '/');
+ if (last_slash)
+ path_len = (last_slash - bootfile) + 1;
+ }
+ ctx->bootdir[path_len] = '\0';
+
+ return 0;
+}
+
+void pxe_destroy_ctx(struct pxe_context *ctx)
+{
+ free(ctx->bootdir);
+}
+
+int pxe_process(struct pxe_context *ctx, ulong pxefile_addr_r, bool prompt)
+{
+ struct pxe_menu *cfg;
+
+ cfg = parse_pxefile(ctx, pxefile_addr_r);
+ if (!cfg) {
+ printf("Error parsing config file\n");
+ return 1;
+ }
+
+ if (prompt)
+ cfg->prompt = 1;
+
+ handle_pxe_menu(ctx, cfg);
+
+ destroy_pxe_menu(cfg);
+
+ return 0;
}