grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 3/7] android_bootimg: Implement open


From: Shea Levy
Subject: [PATCH 3/7] android_bootimg: Implement open
Date: Tue, 26 Jan 2016 13:51:18 -0500

---
 grub-core/fs/android_bootimg.c | 132 +++++++++++++++++++++++++++++++++++------
 1 file changed, 114 insertions(+), 18 deletions(-)

diff --git a/grub-core/fs/android_bootimg.c b/grub-core/fs/android_bootimg.c
index de49303..249f8ca 100644
--- a/grub-core/fs/android_bootimg.c
+++ b/grub-core/fs/android_bootimg.c
@@ -56,22 +56,87 @@ struct boot_img_hdr
   uint8_t extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
 } GRUB_PACKED;
 
+typedef enum
+  {
+    ROOT,
+    KERNEL,
+    RAMDISK,
+    NOT_FOUND,
+    BAD_NAME
+  }
+bootimg_file_t;
+
+static bootimg_file_t
+grub_android_bootimg_handle_path (const char * path)
+{
+  if (!path || path[0] != '/')
+    return BAD_NAME;
+  const char * path_iter;
+  for (path_iter = path + 1; *path_iter; ++path_iter) {
+    if (*path_iter == '/')
+      continue;
+    if (*path_iter == '.') {
+      if (*(++path_iter) == '/')
+       continue;
+      else if (*path_iter == '.' && *(++path_iter) == '/')
+       continue;
+      else
+       return NOT_FOUND;
+    }
+    break;
+  }
+
+  if (!*path_iter)
+    return ROOT;
+  else if (grub_strcmp (path_iter, "kernel") == 0)
+    return KERNEL;
+  else if (grub_strcmp (path_iter, "ramdisk") == 0)
+    return RAMDISK;
+  else
+    return NOT_FOUND;
+}
+
 static grub_err_t
-grub_android_bootimg_dir (grub_device_t device, const char *path_in,
-               grub_fs_dir_hook_t hook, void *hook_data)
+grub_android_bootimg_hdr (grub_disk_t disk, struct boot_img_hdr * hd)
 {
-  struct boot_img_hdr hd;
-  if (grub_disk_read (device->disk, 0, 0, sizeof hd, &hd))
+  if (grub_disk_read (disk, 0, 0, sizeof *hd, hd))
     goto fail;
 
-  if (grub_memcmp (hd.magic, BOOT_MAGIC, BOOT_MAGIC_SIZE))
+  if (grub_memcmp (hd->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE))
     goto fail;
 
-  if (hd.unused[0] || hd.unused[1])
+  if (hd->unused[0] || hd->unused[1])
     goto fail;
 
-  const struct grub_dirhook_info info = {
-    .dir = 0,
+  return GRUB_ERR_NONE;
+
+fail:
+  return grub_error (GRUB_ERR_BAD_FS, N_("%s not an android bootimg"),
+                     disk->name);
+}
+
+static grub_err_t
+grub_android_bootimg_dir (grub_device_t device, const char * path,
+               grub_fs_dir_hook_t hook, void *hook_data)
+{
+  struct boot_img_hdr hd;
+
+  if (grub_android_bootimg_hdr (device->disk, &hd))
+    return grub_errno;
+
+  bootimg_file_t file = grub_android_bootimg_handle_path (path);
+  if (file == NOT_FOUND)
+    return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("directory `%s' not found"),
+                       path);
+  else if (file == BAD_NAME)
+    return grub_error (GRUB_ERR_BAD_FILENAME, N_("invalid directory name 
`%s'"),
+                       path);
+  else if (file != ROOT)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("`%s' not a directory"),
+                       path);
+
+  struct grub_dirhook_info info = {
+    .dir = 1,
     .mtimeset = 0,
     .case_insensitive = 0,
     .inodeset = 0,
@@ -79,15 +144,17 @@ grub_android_bootimg_dir (grub_device_t device, const char 
*path_in,
     .inode = 0
   };
 
-  if (!grub_strcmp(path_in, "/")) {
-    return GRUB_ERR_FILE_NOT_FOUND;
+  if (hook (".", &info, hook_data)) {
+    return grub_errno;
   }
 
-  if (hook ("kernel", &info, hook_data)) {
+  if (hook ("..", &info, hook_data)) {
     return grub_errno;
   }
 
-  if (hook ("info", &info, hook_data)) {
+  info.dir = 0;
+
+  if (hook ("kernel", &info, hook_data)) {
     return grub_errno;
   }
 
@@ -98,16 +165,45 @@ grub_android_bootimg_dir (grub_device_t device, const char 
*path_in,
   }
 
   return GRUB_ERR_NONE;
-
-fail:
-  return grub_error (GRUB_ERR_BAD_FS, "%s is not an android bootimg",
-                     device->disk->name);
 }
 
 static grub_err_t
-grub_android_bootimg_open (grub_file_t file, const char *name_in)
+grub_android_bootimg_open (grub_file_t file, const char *name)
 {
-  return GRUB_ERR_NOT_IMPLEMENTED_YET;
+  struct boot_img_hdr hd;
+
+  if (grub_android_bootimg_hdr (file->device->disk, &hd))
+    return grub_errno;
+
+  grub_off_t * begin_offset;
+
+  bootimg_file_t fn = grub_android_bootimg_handle_path (name);
+  switch (fn)
+    {
+    case NOT_FOUND:
+      return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"),
+                         name);
+    case BAD_NAME:
+      return grub_error (GRUB_ERR_BAD_FILENAME, N_("bad file name `%s'"), 
name);
+    case ROOT:
+      return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("`%s' not a regular file"),
+                         name);
+    case KERNEL:
+      begin_offset = grub_malloc (sizeof *begin_offset);
+      *begin_offset = hd.page_size;
+      file->data = begin_offset;
+      file->size = hd.kernel_size;
+      break;
+    case RAMDISK:
+      begin_offset = grub_malloc (sizeof *begin_offset);
+      *begin_offset =
+        hd.page_size * (1 + (hd.kernel_size + hd.page_size - 1) / 
hd.page_size);
+      file->data = begin_offset;
+      file->size = hd.ramdisk_size;
+      break;
+    }
+
+  return GRUB_ERR_NONE;
 }
 
 static grub_ssize_t
-- 
2.7.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]