summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/str.h45
-rw-r--r--netboot.c28
2 files changed, 66 insertions, 7 deletions
diff --git a/include/str.h b/include/str.h
new file mode 100644
index 00000000..0f3e003a
--- /dev/null
+++ b/include/str.h
@@ -0,0 +1,45 @@
+#ifndef SHIM_STR_H
+#define SHIM_STR_H
+
+static inline
+__attribute__((unused))
+unsigned long strnlena(const CHAR8 *s, unsigned long n)
+{
+ unsigned long i;
+ for (i = 0; i <= n; i++)
+ if (s[i] == '\0')
+ break;
+ return i;
+}
+
+static inline
+__attribute__((unused))
+CHAR8 *
+strncpya(CHAR8 *dest, const CHAR8 *src, unsigned long n)
+{
+ unsigned long i;
+
+ for (i = 0; i < n && src[i] != '\0'; i++)
+ dest[i] = src[i];
+ for (; i < n; i++)
+ dest[i] = '\0';
+
+ return dest;
+}
+
+static inline
+__attribute__((unused))
+CHAR8 *
+strcata(CHAR8 *dest, const CHAR8 *src)
+{
+ unsigned long dest_len = strlena(dest);
+ unsigned long i;
+
+ for (i = 0; src[i] != '\0'; i++)
+ dest[dest_len + i] = src[i];
+ dest[dest_len + i] = '\0';
+
+ return dest;
+}
+
+#endif /* SHIM_STR_H */
diff --git a/netboot.c b/netboot.c
index a83c82ae..1732dc71 100644
--- a/netboot.c
+++ b/netboot.c
@@ -38,6 +38,7 @@
#include <string.h>
#include "shim.h"
#include "netboot.h"
+#include "str.h"
static inline unsigned short int __swap16(unsigned short int x)
{
@@ -305,19 +306,32 @@ static EFI_STATUS parseDhcp6()
static EFI_STATUS parseDhcp4()
{
- CHAR8 *template = (CHAR8 *)DEFAULT_LOADER_CHAR;
- full_path = AllocateZeroPool(strlen(template)+1);
+ CHAR8 *template = (CHAR8 *)translate_slashes(DEFAULT_LOADER_CHAR);
+ UINTN template_len = strlen(template) + 1;
+
+ UINTN dir_len = strnlena(pxe->Mode->DhcpAck.Dhcpv4.BootpBootFile, 127);
+ UINTN i;
+ UINT8 *dir = pxe->Mode->DhcpAck.Dhcpv4.BootpBootFile;
+
+ for (i = dir_len; i >= 0; i--) {
+ if (dir[i] == '/')
+ break;
+ }
+ dir_len = (i >= 0) ? i + 1 : 0;
+
+ full_path = AllocateZeroPool(dir_len + template_len);
if (!full_path)
return EFI_OUT_OF_RESOURCES;
+ if (dir_len > 0) {
+ strncpya(full_path, dir, dir_len);
+ if (full_path[dir_len-1] == '/' && template[0] == '/')
+ full_path[dir_len-1] = '\0';
+ }
+ strcata(full_path, template);
memcpy(&tftp_addr.v4, pxe->Mode->DhcpAck.Dhcpv4.BootpSiAddr, 4);
- memcpy(full_path, template, strlen(template));
-
- /* Note we don't capture the filename option here because we know its shim.efi
- * We instead assume the filename at the end of the path is going to be grubx64.efi
- */
return EFI_SUCCESS;
}