From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1LXDz7-0000HB-4D for mharc-grub-devel@gnu.org; Wed, 11 Feb 2009 07:14:33 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LXDz4-0000H6-Of for grub-devel@gnu.org; Wed, 11 Feb 2009 07:14:30 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LXDz3-0000Gk-Kp for grub-devel@gnu.org; Wed, 11 Feb 2009 07:14:30 -0500 Received: from [199.232.76.173] (port=52813 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LXDz3-0000Gh-Ey for grub-devel@gnu.org; Wed, 11 Feb 2009 07:14:29 -0500 Received: from fg-out-1718.google.com ([72.14.220.156]:64552) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1LXDz2-0000ni-Qk for grub-devel@gnu.org; Wed, 11 Feb 2009 07:14:29 -0500 Received: by fg-out-1718.google.com with SMTP id l27so52958fgb.30 for ; Wed, 11 Feb 2009 04:14:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from :user-agent:mime-version:to:subject:content-type; bh=IRxToE6pkXV7sGRDq8TilJPSxPPuymeqdUEcut5GZxo=; b=I/tRZnkgBHWpyAS6WlNTkamWL1L8ygtg0dvgfKpmSePLgUZId5DkcX8xYPOf/jXifw +X/0h4G/gGkXnI/qHOdOBynq3L8H4HZcSsgoxnb2YUK18ZltjnkwQmU8e6IyT9a7RHHs YkK6RB2/a9S6fAWCW73Cdr9QYhep5e2dQ1md8= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:subject :content-type; b=OAT4Vf3gMZuTAEuBrJTZxVMuIKt9nkKIo6VzBNns8rVtPvXLOxWqb7Se2iVj1YzoV4 u1lU3c5vbjHsySDgliydHhMMy4y3lOTwrnPypxMT8Ce/8ZujM+YdPLR+CceTyXOlqUDD DFJGrkrwGAVpX3f+dugyrS4gA+cbFoH07+jFA= Received: by 10.86.91.3 with SMTP id o3mr90818fgb.35.1234354467848; Wed, 11 Feb 2009 04:14:27 -0800 (PST) Received: from ?192.168.1.25? (230-40.1-85.cust.bluewin.ch [85.1.40.230]) by mx.google.com with ESMTPS id 4sm4142071fge.44.2009.02.11.04.14.26 (version=SSLv3 cipher=RC4-MD5); Wed, 11 Feb 2009 04:14:27 -0800 (PST) Message-ID: <4992C121.4030501@gmail.com> Date: Wed, 11 Feb 2009 13:14:25 +0100 From: phcoder User-Agent: Thunderbird 2.0.0.19 (X11/20090105) MIME-Version: 1.0 To: The development of GRUB 2 Content-Type: multipart/mixed; boundary="------------010404070801030205000605" X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 2) Subject: [PATCH] mtools-like FAT-label behaviour X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GRUB 2 List-Id: The development of GRUB 2 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 11 Feb 2009 12:14:31 -0000 This is a multi-part message in MIME format. --------------010404070801030205000605 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hello. Now the handling of FAT-labels keeps the trailing spaces and ignores VFAT label generated by mlabel tool. Here is the patch to correct this. Unfortunately m$ when user set a mixed case label only uppercase one is saved to FS, moreover m$ keeps the mixed case label in the registry fooling the user. So no way to read these. To test mixed case labels be sure that mlabel reports it as mixed case. Thanks Vladimir 'phcoder' Serbinenko --------------010404070801030205000605 Content-Type: text/x-diff; name="fat.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="fat.diff" Index: ChangeLog =================================================================== --- ChangeLog (revision 1989) +++ ChangeLog (working copy) @@ -1,0 +1,8 @@ +2009-02-11 Vladimir Serbinenko + + 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 Index: fs/fat.c =================================================================== --- fs/fat.c (revision 1989) +++ fs/fat.c (working copy) @@ -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_strcmp (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 --------------010404070801030205000605--