[2066] 2009-04-05 Vladimir Serbinenko <[email protected]>

Vladimir Serbinenko <[email protected]>
Newsgroups gmane.comp.boot-loaders.grub.cvs
Message-ID <[email protected]>
Revision: 2066
          http://svn.sv.gnu.org/viewvc/?view=rev&root=grub&revision=2066
Author:   phcoder
Date:     2009-04-05 15:34:30 +0000 (Sun, 05 Apr 2009)
Log Message:
-----------
2009-04-05  Vladimir Serbinenko  <[email protected]>

	Trim trailing spaces in FAT label and support mtools-like labels
	
	* fs/fat.c (grub_fat_iterate_dir): New function based 
	on grub_fat_find_dir
	(grub_fat_find_dir): use grub_fat_iterate_dir
	(grub_fat_label): likewise

Modified Paths:
--------------
    trunk/grub2/ChangeLog
    trunk/grub2/fs/fat.c

Modified: trunk/grub2/ChangeLog
===================================================================
--- trunk/grub2/ChangeLog	2009-04-04 12:28:33 UTC (rev 2065)
+++ trunk/grub2/ChangeLog	2009-04-05 15:34:30 UTC (rev 2066)
@@ -1,3 +1,12 @@
+2009-04-05  Vladimir Serbinenko  <[email protected]>
+
+	Trim trailing spaces in FAT label and support mtools-like labels
+	
+	* fs/fat.c (grub_fat_iterate_dir): New function based 
+	on grub_fat_find_dir
+	(grub_fat_find_dir): use grub_fat_iterate_dir
+	(grub_fat_label): likewise
+
 2009-04-04  Vladimir Serbinenko  <[email protected]>
 
 	* conf/powerpc-ieee1275.rmk (kernel_elf_HEADERS): add list.h 

Modified: trunk/grub2/fs/fat.c
===================================================================
--- trunk/grub2/fs/fat.c	2009-04-04 12:28:33 UTC (rev 2065)
+++ trunk/grub2/fs/fat.c	2009-04-05 15:34:30 UTC (rev 2066)
@@ -45,7 +45,8 @@
 				 | GRUB_FAT_ATTR_HIDDEN \
 				 | GRUB_FAT_ATTR_SYSTEM \
 				 | GRUB_FAT_ATTR_DIRECTORY \
-				 | GRUB_FAT_ATTR_ARCHIVE)
+				 | GRUB_FAT_ATTR_ARCHIVE \
+				 | GRUB_FAT_ATTR_VOLUME_ID)
 
 struct grub_fat_bpb
 {
@@ -467,51 +468,21 @@
   return ret;
 }
 
-/* Find the underlying directory or file in PATH and return the
-   next path. If there is no next path or an error occurs, return NULL.
-   If HOOK is specified, call it with each file name.  */
-static char *
-grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data,
-		   const char *path,
-		   int (*hook) (const char *filename, int dir))
+static grub_err_t
+grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data,
+		      int (*hook) (const char *filename, 
+				   struct grub_fat_dir_entry *dir))
 {
   struct grub_fat_dir_entry dir;
-  char *dirname, *dirp;
   char *filename, *filep = 0;
   grub_uint16_t *unibuf;
   int slot = -1, slots = -1;
   int checksum = -1;
   grub_ssize_t offset = -sizeof(dir);
-  int call_hook;
   
   if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
-    {
-      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
-      return 0;
-    }
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
   
-  /* Extract a directory name.  */
-  while (*path == '/')
-    path++;
-
-  dirp = grub_strchr (path, '/');
-  if (dirp)
-    {
-      unsigned len = dirp - path;
-      
-      dirname = grub_malloc (len + 1);
-      if (! dirname)
-	return 0;
-
-      grub_memcpy (dirname, path, len);
-      dirname[len] = '\0';
-    }
-  else
-    /* This is actually a file.  */
-    dirname = grub_strdup (path);
-
-  call_hook = (! dirp && hook);
-  
   /* Allocate space enough to hold a long name.  */
   filename = grub_malloc (0x40 * 13 * 4 + 1);
   unibuf = (grub_uint16_t *) grub_malloc (0x40 * 13 * 2);
@@ -519,7 +490,6 @@
     {
       grub_free (filename);
       grub_free (unibuf);
-      grub_free (dirname);
       return 0;
     }
       
@@ -533,15 +503,8 @@
       /* Read a directory entry.  */
       if ((grub_fat_read_data (disk, data, 0,
 			       offset, sizeof (dir), (char *) &dir)
-	   != sizeof (dir))
-	  || dir.name[0] == 0)
-	{
-	  if (grub_errno == GRUB_ERR_NONE && ! call_hook)
-	    grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
-
-	  break;
-	}
-
+	   != sizeof (dir) || dir.name[0] == 0))
+	break;
       /* Handle long name entries.  */
       if (dir.attr == GRUB_FAT_ATTR_LONG_NAME)
 	{
@@ -594,22 +557,11 @@
 	      *grub_utf16_to_utf8 ((grub_uint8_t *) filename, unibuf,
 				   slots * 13) = '\0';
 	      
-	      if (*dirname == '\0' && call_hook)
-		{
-		  if (hook (filename, dir.attr & GRUB_FAT_ATTR_DIRECTORY))
-		    break;
-		  
-		  checksum = -1;
-		  continue;
-		}
-
-	      if (grub_strcmp (dirname, filename) == 0)
-		{
-		  if (call_hook)
-		    hook (filename, dir.attr & GRUB_FAT_ATTR_DIRECTORY);
-		  
-		  break;
-		}
+	      if (hook (filename, &dir))
+		break;
+	      
+	      checksum = -1;
+	      continue;
 	    }
 
 	  checksum = -1;
@@ -617,44 +569,109 @@
 
       /* Convert the 8.3 file name.  */
       filep = filename;
-      
-      for (i = 0; i < 8 && dir.name[i] && ! grub_isspace (dir.name[i]); i++)
-	*filep++ = grub_tolower (dir.name[i]);
-      
-      *filep = '.';
-      
-      for (i = 8; i < 11 && dir.name[i] && ! grub_isspace (dir.name[i]); i++)
-	*++filep = grub_tolower (dir.name[i]);
-
-      if (*filep != '.')
-	filep++;
-      
-      *filep = '\0';
-
-      if (*dirname == '\0' && call_hook)
+      if (dir.attr & GRUB_FAT_ATTR_VOLUME_ID)
 	{
-	  if (hook (filename, dir.attr & GRUB_FAT_ATTR_DIRECTORY))
-	    break;
+	  for (i = 0; i < sizeof (dir.name) && dir.name[i] 
+		 && ! grub_isspace (dir.name[i]); i++)
+	    *filep++ = dir.name[i];
 	}
-      else if (grub_strncasecmp (dirname, filename, GRUB_FAT_MAXFILE) == 0)
+      else
 	{
-	  if (call_hook)
-	    hook (filename, dir.attr & GRUB_FAT_ATTR_DIRECTORY);
+	  for (i = 0; i < 8 && dir.name[i] && ! grub_isspace (dir.name[i]); i++)
+	    *filep++ = grub_tolower (dir.name[i]);
+      
+	  *filep = '.';
+	  
+	  for (i = 8; i < 11 && dir.name[i] && ! grub_isspace (dir.name[i]); i++)
+	    *++filep = grub_tolower (dir.name[i]);
 
-	  break;
+	  if (*filep != '.')
+	    filep++;
 	}
+      *filep = '\0';
+
+      if (hook (filename, &dir))
+	break;
     }
 
   grub_free (filename);
-  grub_free (dirname);
 
-  data->attr = dir.attr;
-  data->file_size = grub_le_to_cpu32 (dir.file_size);
-  data->file_cluster = ((grub_le_to_cpu16 (dir.first_cluster_high) << 16)
-			| grub_le_to_cpu16 (dir.first_cluster_low));
-  data->cur_cluster_num = ~0U;
+  return grub_errno;
+}
+
+
+/* Find the underlying directory or file in PATH and return the
+   next path. If there is no next path or an error occurs, return NULL.
+   If HOOK is specified, call it with each file name.  */
+static char *
+grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data,
+		   const char *path,
+		   int (*hook) (const char *filename, int dir))
+{
+  char *dirname, *dirp;
+  int call_hook;
+  int found = 0;
+
+  auto int iter_hook (const char *filename, struct grub_fat_dir_entry *dir);
+  int iter_hook (const char *filename, struct grub_fat_dir_entry *dir)
+  {
+    if (dir->attr & GRUB_FAT_ATTR_VOLUME_ID)
+      return 0;
+    if (*dirname == '\0' && call_hook)
+      return hook (filename, dir->attr & GRUB_FAT_ATTR_DIRECTORY);
+
+    if (grub_strcasecmp (dirname, filename) == 0)
+      {
+	found = 1;
+	data->attr = dir->attr;
+	data->file_size = grub_le_to_cpu32 (dir->file_size);
+	data->file_cluster = ((grub_le_to_cpu16 (dir->first_cluster_high) << 16)
+			      | grub_le_to_cpu16 (dir->first_cluster_low));
+	data->cur_cluster_num = ~0U;
+
+	if (call_hook)
+	  hook (filename, dir->attr & GRUB_FAT_ATTR_DIRECTORY);
+	    
+	return 1;
+      }
+    return 0;
+  }
   
-  return dirp;
+  if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+      return 0;
+    }
+  
+  /* Extract a directory name.  */
+  while (*path == '/')
+    path++;
+
+  dirp = grub_strchr (path, '/');
+  if (dirp)
+    {
+      unsigned len = dirp - path;
+      
+      dirname = grub_malloc (len + 1);
+      if (! dirname)
+	return 0;
+
+      grub_memcpy (dirname, path, len);
+      dirname[len] = '\0';
+    }
+  else
+    /* This is actually a file.  */
+    dirname = grub_strdup (path);
+
+  call_hook = (! dirp && hook);
+  
+  grub_fat_iterate_dir (disk, data, iter_hook);
+  if (grub_errno == GRUB_ERR_NONE && ! found && !call_hook)
+    grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+
+  grub_free (dirname);
+
+  return found ? dirp : 0;
 }
 
 static grub_err_t
@@ -773,8 +790,17 @@
 {
   struct grub_fat_data *data;
   grub_disk_t disk = device->disk;
-  grub_ssize_t offset = -sizeof(struct grub_fat_dir_entry);
 
+  auto int iter_hook (const char *filename, struct grub_fat_dir_entry *dir);
+  int iter_hook (const char *filename, struct grub_fat_dir_entry *dir)
+  {
+    if (dir->attr == GRUB_FAT_ATTR_VOLUME_ID)
+      {
+	*label = grub_strdup (filename);
+	return 1;
+      }
+    return 0;
+  }
 
 #ifndef GRUB_UTIL
   grub_dl_ref (my_mod);
@@ -790,37 +816,10 @@
       return 0;
     }
 
-  while (1)
-    {
-      struct grub_fat_dir_entry dir;
-
-      /* Adjust the offset.  */
-      offset += sizeof (dir);
-      
-      /* Read a directory entry.  */
-      if ((grub_fat_read_data (disk, data, 0,
-			       offset, sizeof (dir), (char *) &dir)
-	   != sizeof (dir))
-	  || dir.name[0] == 0)
-	{
-	  if (grub_errno != GRUB_ERR_NONE)
-	    goto fail;
-	  else
-	    {
-	      *label = 0;
-	      return GRUB_ERR_NONE;
-	    }
-	}
-
-      if (dir.attr == GRUB_FAT_ATTR_VOLUME_ID)
-	{
-	  *label = grub_strndup ((char *) dir.name, 11);
-	  return GRUB_ERR_NONE;
-	}
-    }
-
   *label = 0;
   
+  grub_fat_iterate_dir (disk, data, iter_hook);
+
  fail:
 
 #ifndef GRUB_UTIL
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.