From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1LXJVj-0007JY-8V for mharc-grub-devel@gnu.org; Wed, 11 Feb 2009 13:08:35 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LXJVh-0007Iv-Ib for grub-devel@gnu.org; Wed, 11 Feb 2009 13:08:33 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LXJVg-0007If-PW for grub-devel@gnu.org; Wed, 11 Feb 2009 13:08:33 -0500 Received: from [199.232.76.173] (port=47605 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LXJVg-0007Ic-HL for grub-devel@gnu.org; Wed, 11 Feb 2009 13:08:32 -0500 Received: from fg-out-1718.google.com ([72.14.220.158]:47561) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1LXJVf-0008Gp-To for grub-devel@gnu.org; Wed, 11 Feb 2009 13:08:32 -0500 Received: by fg-out-1718.google.com with SMTP id l27so109895fgb.30 for ; Wed, 11 Feb 2009 10:08:30 -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:references:in-reply-to :content-type; bh=/tHwdP0LvkIw9tf4Q1rCdSUedLxc8sIksb9hshy5pg0=; b=sbTphKxEAJ+5WYwWSRiFvfPTp/89YAKj5OdVzNqlRPrjUBnZLK2ispFpxqBOEU2WC4 u+kFjUgy29v03s0jzOlkbEQWqc0BYzkG7AA10rNxRdwZ/JsLYtVh6Gy1FWPRp+8sd9YJ IESKozElbJynwPoD6ec1GJDnlnQcIfnznohkY= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:subject:references :in-reply-to:content-type; b=AOh14fxbiTLAqBnR60l81CVdt/OSTYlciGOSpjbBU1JOkcYl94kMcuP84IH/9D73M0 ePCI8ZmMiODh8dl048hjCRmPAkJmc50Zg0hyTYVRohDiCmmzjPA6jE6X9nFQvR+UNsp6 Mas4fD3cSnNqmbfj9aKDyPzK7zI4274lG1PAA= Received: by 10.86.99.9 with SMTP id w9mr835656fgb.68.1234375710478; Wed, 11 Feb 2009 10:08:30 -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 e11sm4189538fga.40.2009.02.11.10.08.29 (version=SSLv3 cipher=RC4-MD5); Wed, 11 Feb 2009 10:08:30 -0800 (PST) Message-ID: <4993141D.20208@gmail.com> Date: Wed, 11 Feb 2009 19:08:29 +0100 From: phcoder User-Agent: Thunderbird 2.0.0.19 (X11/20090105) MIME-Version: 1.0 To: The development of GRUB 2 References: <4992C121.4030501@gmail.com> In-Reply-To: <4992C121.4030501@gmail.com> Content-Type: multipart/mixed; boundary="------------090104080304070903080609" X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 2) Subject: Re: [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 18:08:34 -0000 This is a multi-part message in MIME format. --------------090104080304070903080609 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit With this patch fat became case-sensitive which is probably wrong. Corrected version of patch attached Sorry Vladimir 'phcoder' Serbinenko phcoder wrote: > 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 > --------------090104080304070903080609 Content-Type: text/x-patch; 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_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 --------------090104080304070903080609--