]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
* grub-core/fs/jfs.c: Remove variable length arrays. Reduces jfs.mod
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sun, 20 Oct 2013 11:20:12 +0000 (13:20 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sun, 20 Oct 2013 11:20:12 +0000 (13:20 +0200)
by 364 bytes (169 compressed).

ChangeLog
grub-core/fs/jfs.c

index 916d43d8f4b30d7a07851fac57b65cecdb51f43b..d2336c5a7d6009e1acd84652f9bc6149389a19fd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2013-10-20  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       * grub-core/fs/jfs.c: Remove variable length arrays. Reduces jfs.mod
+       by 364 bytes (169 compressed).
+
 2013-10-20  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * grub-core/fs/bfs.c: Remove variable length arrays. Reduces afs.mod and
index 4122effc5256d437694b097e4a168432975bfe0c..26d77164716b76c1f3723fa3e016e7daf45c3b98 100644 (file)
@@ -639,136 +639,74 @@ static grub_err_t
 grub_jfs_find_file (struct grub_jfs_data *data, const char *path,
                    grub_uint32_t start_ino)
 {
-  char fpath[grub_strlen (path)];
-  char *name = fpath;
-  char *next;
-  struct grub_jfs_diropen *diro;
-
-  grub_strncpy (fpath, path, grub_strlen (path) + 1);
+  const char *name;
+  const char *next = path;
+  struct grub_jfs_diropen *diro = NULL;
 
   if (grub_jfs_read_inode (data, start_ino, &data->currinode))
     return grub_errno;
 
-  /* Skip the first slashes.  */
-  while (*name == '/')
-    {
-      name++;
-      if (!*name)
-       return 0;
-    }
-
-  /* Extract the actual part from the pathname.  */
-  next = grub_strchr (name, '/');
-  if (next)
-    {
-      while (*next == '/')
-       {
-         next[0] = '\0';
-         next++;
-       }
-    }
-  diro = grub_jfs_opendir (data, &data->currinode);
-  if (!diro)
-    return grub_errno;
-
-  for (;;)
+  while (1)
     {
+      name = next;
+      while (*name == '/')
+       name++;
       if (name[0] == 0)
        return GRUB_ERR_NONE;
+      for (next = name; *next && *next != '/'; next++);
 
-      if (name[0] == '.' && name[1] == 0)
-       {
-         if (!next)
-           return 0;
+      if (name[0] == '.' && name + 1 == next)
+       continue;
 
-         name = next;
-         next = grub_strchr (name, '/');
-         while (next && *next == '/')
-           {
-             next[0] = '\0';
-             next++;
-           }
-         continue;
-       }
-
-      if (name[0] == '.' && name[1] == '.' && name[2] == 0)
+      if (name[0] == '.' && name[1] == '.' && name + 2 == next)
        {
          grub_uint32_t ino = grub_le_to_cpu32 (data->currinode.dir.header.idotdot);
 
-         grub_jfs_closedir (diro);
-         diro = 0;
-
          if (grub_jfs_read_inode (data, ino, &data->currinode))
-           break;
-
-         if (!next)
-           return 0;
-
-         name = next;
-         next = grub_strchr (name, '/');
-         while (next && *next == '/')
-           {
-             next[0] = '\0';
-             next++;
-           }
-
-         /* Open this directory for reading dirents.  */
-         diro = grub_jfs_opendir (data, &data->currinode);
-         if (!diro)
            return grub_errno;
 
          continue;
        }
 
-      if (grub_jfs_getent (diro) == GRUB_ERR_OUT_OF_RANGE)
-       break;
+      diro = grub_jfs_opendir (data, &data->currinode);
+      if (!diro)
+       return grub_errno;
 
-      /* Check if the current direntry matches the current part of the
-        pathname.  */
-      if (data->caseins ? grub_strcasecmp (name, diro->name) == 0
-         : grub_strcmp (name, diro->name) == 0)
+      for (;;)
        {
-         grub_uint32_t ino = diro->ino;
-         grub_uint32_t dirino = grub_le_to_cpu32 (data->currinode.inode);
-
-         grub_jfs_closedir (diro);
-         diro = 0;
-
-         if (grub_jfs_read_inode (data, ino, &data->currinode))
-           break;
-
-         /* Check if this is a symlink.  */
-         if ((grub_le_to_cpu32 (data->currinode.mode)
-              & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_LNK)
+         if (grub_jfs_getent (diro) == GRUB_ERR_OUT_OF_RANGE)
            {
-             grub_jfs_lookup_symlink (data, dirino);
-             if (grub_errno)
-               return grub_errno;
+             grub_jfs_closedir (diro);
+             return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), path);
            }
 
-         if (!next)
-           return 0;
-
-         name = next;
-         next = grub_strchr (name, '/');
-         while (next && *next == '/')
+         /* Check if the current direntry matches the current part of the
+            pathname.  */
+         if ((data->caseins ? grub_strncasecmp (name, diro->name, next - name) == 0
+              : grub_strncmp (name, diro->name, next - name) == 0) && !diro->name[next - name])
            {
-             next[0] = '\0';
-             next++;
-           }
+             grub_uint32_t ino = diro->ino;
+             grub_uint32_t dirino = grub_le_to_cpu32 (data->currinode.inode);
 
-         /* Open this directory for reading dirents.  */
-         diro = grub_jfs_opendir (data, &data->currinode);
-         if (!diro)
-           return grub_errno;
+             grub_jfs_closedir (diro);
+             diro = 0;
 
-         continue;
+             if (grub_jfs_read_inode (data, ino, &data->currinode))
+               break;
+
+             /* Check if this is a symlink.  */
+             if ((grub_le_to_cpu32 (data->currinode.mode)
+                  & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_LNK)
+               {
+                 grub_jfs_lookup_symlink (data, dirino);
+                 if (grub_errno)
+                   return grub_errno;
+               }
+
+             break;
+           }
        }
     }
-
-  grub_jfs_closedir (diro);
-  grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), path);
-  return grub_errno;
 }
 
 
@@ -776,15 +714,21 @@ static grub_err_t
 grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint32_t ino)
 {
   grub_size_t size = grub_le_to_cpu64 (data->currinode.size);
-  char symlink[size + 1];
+  char *symlink;
 
   if (++data->linknest > GRUB_JFS_MAX_SYMLNK_CNT)
     return grub_error (GRUB_ERR_SYMLINK_LOOP, N_("too deep nesting of symlinks"));
 
+  symlink = grub_malloc (size + 1);
+  if (!symlink)
+    return grub_errno;
   if (size <= sizeof (data->currinode.symlink.path))
     grub_strncpy (symlink, (char *) (data->currinode.symlink.path), size);
   else if (grub_jfs_read_file (data, 0, 0, 0, size, symlink) < 0)
-    return grub_errno;
+    {
+      grub_free (symlink);
+      return grub_errno;
+    }
 
   symlink[size] = '\0';
 
@@ -794,6 +738,8 @@ grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint32_t ino)
 
   grub_jfs_find_file (data, symlink, ino);
 
+  grub_free (symlink);
+
   return grub_errno;
 }
 \f