From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1LXd94-0005AC-TO for mharc-grub-devel@gnu.org; Thu, 12 Feb 2009 10:06:30 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LXd92-00059W-N4 for grub-devel@gnu.org; Thu, 12 Feb 2009 10:06:28 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LXd90-00058R-8L for grub-devel@gnu.org; Thu, 12 Feb 2009 10:06:28 -0500 Received: from [199.232.76.173] (port=37818 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LXd90-00058L-4B for grub-devel@gnu.org; Thu, 12 Feb 2009 10:06:26 -0500 Received: from fg-out-1718.google.com ([72.14.220.154]:45289) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1LXd8v-0007Zo-EC for grub-devel@gnu.org; Thu, 12 Feb 2009 10:06:25 -0500 Received: by fg-out-1718.google.com with SMTP id l27so256851fgb.30 for ; Thu, 12 Feb 2009 07:06:15 -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=CgojNWSkwet+UFu3VLCGaMExrHUASgguJclYfVGzRGw=; b=HShN+nf/MYg/VOY19FjVrh386iWxlZi2Va7tRE4XUX/yyQe3vdo0qMHbHfg0Gu3ZS6 bdl+MKonVyKybuFLBqXrV9rwcs0SfT3JaV2JY97ZgJW63XgKzKVnh0IxgdY9fsAkT/mU TczJdfZDSUVJCVrB8UFoqG5AvZCm3zfQMM+tI= 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=hX0E8QOVaKgzaRx8PeTo+Msv9IC/VjYI429hWb+z50raeDPVe75KBA+ldxrOGSm96A Fg/5Z3X9GUsnQp9PGip5LvURyKDDr1J8cx8vV96zEYKXD4GQFhfm+/vUc+Mkr5Q4f6hX gZhEnBlmp42HHQuy5HtbqhG4IdF9eIOmhkUNk= Received: by 10.86.91.3 with SMTP id o3mr1448524fgb.77.1234451175079; Thu, 12 Feb 2009 07:06:15 -0800 (PST) Received: from ?192.168.1.25? (120-197.62-81.cust.bluewin.ch [81.62.197.120]) by mx.google.com with ESMTPS id d4sm738636fga.38.2009.02.12.07.06.12 (version=SSLv3 cipher=RC4-MD5); Thu, 12 Feb 2009 07:06:14 -0800 (PST) Message-ID: <49943AE4.5040008@gmail.com> Date: Thu, 12 Feb 2009 16:06:12 +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="------------030905070100000402000401" X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 2) Subject: [PATCH] mtime support 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: Thu, 12 Feb 2009 15:06:28 -0000 This is a multi-part message in MIME format. --------------030905070100000402000401 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hello. Here is the patch to support mtime. This is a prerequisite for -nt test which can be very useful for e.g. finding last compiled kernel Also in the same time it makes the dir call easily extendable Regards Vladimir 'phcoder' Serbinenko --------------030905070100000402000401 Content-Type: text/x-patch; name="mtime.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="mtime.diff" Index: conf/common.rmk =================================================================== --- conf/common.rmk (revision 1989) +++ conf/common.rmk (working copy) @@ -352,7 +358,7 @@ terminal_mod_CFLAGS = $(COMMON_CFLAGS) terminal_mod_LDFLAGS = $(COMMON_LDFLAGS) # For ls.mod. -ls_mod_SOURCES = commands/ls.c +ls_mod_SOURCES = commands/ls.c lib/datetime.c ls_mod_CFLAGS = $(COMMON_CFLAGS) ls_mod_LDFLAGS = $(COMMON_LDFLAGS) Index: conf/i386-coreboot.rmk =================================================================== --- conf/i386-coreboot.rmk (revision 1989) +++ conf/i386-coreboot.rmk (working copy) @@ -87,7 +87,7 @@ grub_emu_SOURCES = commands/boot.c commands/cat.c \ disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ - grub_emu_init.c + grub_emu_init.c lib/datetime.c grub_emu_LDFLAGS = $(LIBCURSES) @@ -127,7 +127,7 @@ normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/menu_viewer.c normal/menu_entry.c \ normal/misc.c grub_script.tab.c \ normal/script.c \ - normal/i386/setjmp.S + normal/i386/setjmp.S lib/datetime.c normal_mod_CFLAGS = $(COMMON_CFLAGS) normal_mod_ASFLAGS = $(COMMON_ASFLAGS) normal_mod_LDFLAGS = $(COMMON_LDFLAGS) Index: conf/i386-efi.rmk =================================================================== --- conf/i386-efi.rmk (revision 1989) +++ conf/i386-efi.rmk (working copy) @@ -64,7 +64,7 @@ grub_emu_SOURCES = commands/boot.c commands/cat.c \ disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ - grub_emu_init.c + grub_emu_init.c lib/datetime.c grub_emu_LDFLAGS = $(LIBCURSES) @@ -124,7 +124,7 @@ normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/menu_viewer.c normal/menu_entry.c \ normal/misc.c grub_script.tab.c \ normal/script.c \ - normal/i386/setjmp.S + normal/i386/setjmp.S lib/datetime.c normal_mod_CFLAGS = $(COMMON_CFLAGS) normal_mod_ASFLAGS = $(COMMON_ASFLAGS) normal_mod_LDFLAGS = $(COMMON_LDFLAGS) Index: conf/i386-ieee1275.rmk =================================================================== --- conf/i386-ieee1275.rmk (revision 1989) +++ conf/i386-ieee1275.rmk (working copy) @@ -117,8 +117,8 @@ normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/menu_viewer.c normal/menu_entry.c \ normal/misc.c grub_script.tab.c \ normal/script.c \ - normal/i386/setjmp.S + normal/i386/setjmp.S lib/datetime.c normal_mod_CFLAGS = $(COMMON_CFLAGS) normal_mod_ASFLAGS = $(COMMON_ASFLAGS) normal_mod_LDFLAGS = $(COMMON_LDFLAGS) Index: conf/i386-pc.rmk =================================================================== --- conf/i386-pc.rmk (revision 1989) +++ conf/i386-pc.rmk (working copy) @@ -145,8 +145,7 @@ grub_emu_SOURCES = commands/boot.c commands/cat.c \ disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ - grub_emu_init.c - + grub_emu_init.c lib/datetime.c grub_emu_LDFLAGS = $(LIBCURSES) ifeq ($(enable_grub_emu_usb), yes) Index: conf/powerpc-ieee1275.rmk =================================================================== --- conf/powerpc-ieee1275.rmk (revision 1989) +++ conf/powerpc-ieee1275.rmk (working copy) @@ -69,7 +69,7 @@ grub_emu_SOURCES = commands/boot.c commands/cat.c \ disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ - grub_script.tab.c grub_emu_init.c + grub_script.tab.c grub_emu_init.c lib/datetime.c grub_emu_LDFLAGS = $(LIBCURSES) @@ -137,7 +137,7 @@ normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/menu_viewer.c normal/menu_entry.c \ normal/misc.c grub_script.tab.c \ normal/script.c \ - normal/powerpc/setjmp.S + normal/powerpc/setjmp.S lib/datetime.c normal_mod_CFLAGS = $(COMMON_CFLAGS) normal_mod_ASFLAGS = $(COMMON_ASFLAGS) normal_mod_LDFLAGS = $(COMMON_LDFLAGS) Index: conf/sparc64-ieee1275.rmk =================================================================== --- conf/sparc64-ieee1275.rmk (revision 1989) +++ conf/sparc64-ieee1275.rmk (working copy) @@ -64,7 +64,7 @@ grub_mkimage_SOURCES = util/sparc64/ieee1275/grub- # partmap/acorn.c \ # util/console.c util/grub-emu.c util/misc.c \ # util/hostdisk.c util/getroot.c \ -# util/sparc64/ieee1275/misc.c +# util/sparc64/ieee1275/misc.c lib/datetime.c grub_emu_LDFLAGS = $(LIBCURSES) @@ -170,7 +170,7 @@ normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/menu_viewer.c normal/menu_entry.c \ normal/misc.c grub_script.tab.c \ normal/script.c \ - normal/sparc64/setjmp.S + normal/sparc64/setjmp.S lib/datetime.c normal_mod_CFLAGS = $(COMMON_CFLAGS) normal_mod_ASFLAGS = $(COMMON_ASFLAGS) normal_mod_LDFLAGS = $(COMMON_LDFLAGS) Index: conf/x86_64-efi.rmk =================================================================== --- conf/x86_64-efi.rmk (revision 1989) +++ conf/x86_64-efi.rmk (working copy) @@ -66,7 +66,7 @@ grub_emu_SOURCES = commands/boot.c commands/cat.c \ disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ - grub_emu_init.c + grub_emu_init.c lib/datetime.c grub_emu_LDFLAGS = $(LIBCURSES) @@ -126,7 +126,7 @@ normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/menu_viewer.c normal/menu_entry.c \ normal/misc.c grub_script.tab.c \ normal/script.c \ - normal/x86_64/setjmp.S + normal/x86_64/setjmp.S lib/datetime.c normal_mod_CFLAGS = $(COMMON_CFLAGS) normal_mod_ASFLAGS = $(COMMON_ASFLAGS) normal_mod_LDFLAGS = $(COMMON_LDFLAGS) Index: kern/fs.c =================================================================== --- kern/fs.c (revision 1989) +++ kern/fs.c (working copy) @@ -65,10 +65,10 @@ grub_fs_t grub_fs_probe (grub_device_t device) { grub_fs_t p; - auto int dummy_func (const char *filename, int dir); + auto int dummy_func (const char *filename, struct grub_dirhook_info info); int dummy_func (const char *filename __attribute__ ((unused)), - int dir __attribute__ ((unused))) + struct grub_dirhook_info info __attribute__ ((unused))) { return 1; } Index: kern/rescue.c =================================================================== --- kern/rescue.c (revision 1989) +++ kern/rescue.c (working copy) @@ -176,9 +176,9 @@ grub_rescue_print_devices (const char *name) } static int -grub_rescue_print_files (const char *filename, int dir) +grub_rescue_print_files (const char *filename, struct grub_dirhook_info info) { - grub_printf ("%s%s ", filename, dir ? "/" : ""); + grub_printf ("%s%s ", filename, info.dir ? "/" : ""); return 0; } Index: lib/datetime.c =================================================================== --- lib/datetime.c (revision 1989) +++ lib/datetime.c (working copy) @@ -47,3 +47,45 @@ grub_get_weekday_name (struct grub_datetime *datet { return grub_weekday_names[grub_get_weekday (datetime)]; } + +#define SECPERMIN 60 +#define SECPERHOUR (60*SECPERMIN) +#define SECPERDAY (24*SECPERHOUR) +#define SECPERYEAR (365*SECPERDAY) +#define SECPER4YEARS (4*SECPERYEAR+SECPERDAY) + + +void +grub_unixtime2datetime (grub_int32_t nix, struct grub_datetime *datetime) +{ + int i; + grub_uint8_t months[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + /* Convenience: let's have 3 consecutive non-bissextile years + at the begining of the epoch. So count from 1971 instead of 1970 */ + nix -= SECPERYEAR + SECPERDAY; + if (nix > 0) + { + datetime->year = 1971 + 4 * (nix / SECPER4YEARS); + nix %= SECPER4YEARS; + } + else + { + /* Transform C divisions and modulos to mathematical ones */ + datetime->year = 1971 + 4 * (nix / SECPER4YEARS) - 4; + nix = SECPER4YEARS + (nix % SECPER4YEARS); + } + datetime->year += nix / SECPERYEAR; + nix %= SECPERYEAR; + for (i = 0; i < 12 + && nix >= ((grub_int32_t) (i==1 && datetime->year % 4 == 0 + ? 29 : months[i]))*SECPERDAY; i++) + nix -= ((grub_int32_t) (i==1 && datetime->year % 4 == 0 + ? 29 : months[i]))*SECPERDAY; + datetime->month = i + 1; + datetime->day = 1 + (nix / SECPERDAY); + nix %= SECPERDAY; + datetime->hour = (nix / SECPERHOUR); + nix %= SECPERHOUR; + datetime->minute = nix / SECPERMIN; + datetime->second = nix % SECPERMIN; +} Index: fs/xfs.c =================================================================== --- fs/xfs.c (revision 1989) +++ fs/xfs.c (working copy) @@ -620,7 +620,7 @@ grub_xfs_mount (grub_disk_t disk) static grub_err_t grub_xfs_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, int dir)) + int (*hook) (const char *filename, struct grub_dirhook_info info)) { struct grub_xfs_data *data = 0;; struct grub_fshelp_node *fdiro = 0; @@ -633,14 +633,11 @@ grub_xfs_dir (grub_device_t device, const char *pa enum grub_fshelp_filetype filetype, grub_fshelp_node_t node) { + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); grub_free (node); - - if (filetype == GRUB_FSHELP_DIR) - return hook (filename, 1); - else - return hook (filename, 0); - - return 0; + return hook (filename, info); } #ifndef GRUB_UTIL Index: fs/afs.c =================================================================== --- fs/afs.c (revision 1989) +++ fs/afs.c (working copy) @@ -562,7 +562,7 @@ grub_afs_close (grub_file_t file) static grub_err_t grub_afs_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, int dir)) + int (*hook) (const char *filename, struct grub_dirhook_info info)) { struct grub_afs_data *data = 0;; struct grub_fshelp_node *fdiro = 0; @@ -575,14 +575,11 @@ grub_afs_dir (grub_device_t device, const char *pa enum grub_fshelp_filetype filetype, grub_fshelp_node_t node) { + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); grub_free (node); - - if (filetype == GRUB_FSHELP_DIR) - return hook (filename, 1); - else - return hook (filename, 0); - - return 0; + return hook (filename, info); } #ifndef GRUB_UTIL Index: fs/ntfs.c =================================================================== --- fs/ntfs.c (revision 1989) +++ fs/ntfs.c (working copy) @@ -864,7 +864,8 @@ fail: static grub_err_t grub_ntfs_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, int dir)) + int (*hook) (const char *filename, + struct grub_dirhook_info info)) { struct grub_ntfs_data *data = 0; struct grub_fshelp_node *fdiro = 0; @@ -877,14 +878,11 @@ grub_ntfs_dir (grub_device_t device, const char *p enum grub_fshelp_filetype filetype, grub_fshelp_node_t node) { - grub_free (node); - - if (filetype == GRUB_FSHELP_DIR) - return hook (filename, 1); - else - return hook (filename, 0); - - return 0; + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + grub_free (node); + return hook (filename, info); } #ifndef GRUB_UTIL 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 @@ grub_fat_read_data (grub_disk_t disk, struct grub_ 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_fat_read_data (grub_disk_t disk, struct grub_ { grub_free (filename); grub_free (unibuf); - grub_free (dirname); return 0; } @@ -533,15 +503,8 @@ grub_fat_read_data (grub_disk_t disk, struct grub_ /* 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_fat_read_data (grub_disk_t disk, struct grub_ *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,49 +569,121 @@ grub_fat_read_data (grub_disk_t disk, struct grub_ /* 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); + + 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, + struct grub_dirhook_info info)) +{ + 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) + { + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + + info.dir = (dir->attr & GRUB_FAT_ATTR_DIRECTORY); + + if (dir->attr & GRUB_FAT_ATTR_VOLUME_ID) + return 0; + if (*dirname == '\0' && call_hook) + return hook (filename, info); + + 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, info); + + return 1; + } + return 0; + } + + 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); - 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 dirp; + return found ? dirp : 0; } static grub_err_t grub_fat_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, int dir)) + int (*hook) (const char *filename, + struct grub_dirhook_info info)) { struct grub_fat_data *data = 0; grub_disk_t disk = device->disk; @@ -773,8 +797,17 @@ grub_fat_label (grub_device_t device, char **label { 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 +823,10 @@ grub_fat_label (grub_device_t device, char **label 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 Index: fs/udf.c =================================================================== --- fs/udf.c (revision 1989) +++ fs/udf.c (working copy) @@ -768,7 +768,7 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, static grub_err_t grub_udf_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, int dir)) + int (*hook) (const char *filename, struct grub_dirhook_info info)) { struct grub_udf_data *data = 0; struct grub_fshelp_node rootnode; @@ -782,14 +782,11 @@ grub_udf_dir (grub_device_t device, const char *pa enum grub_fshelp_filetype filetype, grub_fshelp_node_t node) { - grub_free (node); - - if (filetype == GRUB_FSHELP_DIR) - return hook (filename, 1); - else - return hook (filename, 0); - - return 0; + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + grub_free (node); + return hook (filename, info); } #ifndef GRUB_UTIL Index: fs/iso9660.c =================================================================== --- fs/iso9660.c (revision 1989) +++ fs/iso9660.c (working copy) @@ -666,7 +666,8 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, static grub_err_t grub_iso9660_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, int dir)) + int (*hook) (const char *filename, + struct grub_dirhook_info info)) { struct grub_iso9660_data *data = 0; struct grub_fshelp_node rootnode; @@ -680,14 +681,11 @@ grub_iso9660_dir (grub_device_t device, const char enum grub_fshelp_filetype filetype, grub_fshelp_node_t node) { + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); grub_free (node); - - if (filetype == GRUB_FSHELP_DIR) - return hook (filename, 1); - else - return hook (filename, 0); - - return 0; + return hook (filename, info); } #ifndef GRUB_UTIL Index: fs/affs.c =================================================================== --- fs/affs.c (revision 1989) +++ fs/affs.c (working copy) @@ -456,7 +456,8 @@ grub_affs_read (grub_file_t file, char *buf, grub_ static grub_err_t grub_affs_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, int dir)) + int (*hook) (const char *filename, + struct grub_dirhook_info info)) { struct grub_affs_data *data = 0; struct grub_fshelp_node *fdiro = 0; @@ -469,14 +470,11 @@ grub_affs_dir (grub_device_t device, const char *p enum grub_fshelp_filetype filetype, grub_fshelp_node_t node) { + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); grub_free (node); - - if (filetype == GRUB_FSHELP_DIR) - return hook (filename, 1); - else - return hook (filename, 0); - - return 0; + return hook (filename, info); } #ifndef GRUB_UTIL Index: fs/hfs.c =================================================================== --- fs/hfs.c (revision 1989) +++ fs/hfs.c (working copy) @@ -721,7 +721,8 @@ grub_hfs_find_dir (struct grub_hfs_data *data, con static grub_err_t grub_hfs_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, int dir)) + int (*hook) (const char *filename, + struct grub_dirhook_info info)) { int inode; @@ -732,13 +733,17 @@ grub_hfs_dir (grub_device_t device, const char *pa char fname[32] = { 0 }; char *filetype = rec->data; struct grub_hfs_catalog_key *ckey = rec->key; + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); grub_strncpy (fname, (char *) (ckey->str), ckey->strlen); - if (*filetype == GRUB_HFS_FILETYPE_DIR) - return hook (fname, 1); - else if (*filetype == GRUB_HFS_FILETYPE_FILE) - return hook (fname, 0); + if (*filetype == GRUB_HFS_FILETYPE_DIR + || *filetype == GRUB_HFS_FILETYPE_FILE) + { + info.dir = (*filetype == GRUB_HFS_FILETYPE_DIR); + return hook (fname, info); + } return 0; } Index: fs/reiserfs.c =================================================================== --- fs/reiserfs.c (revision 1989) +++ fs/reiserfs.c (working copy) @@ -1266,7 +1266,8 @@ grub_reiserfs_close (grub_file_t file) /* Call HOOK with each file under DIR. */ static grub_err_t grub_reiserfs_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, int dir)) + int (*hook) (const char *filename, + struct grub_dirhook_info info)) { struct grub_reiserfs_data *data = 0; struct grub_fshelp_node root, *found; @@ -1280,12 +1281,11 @@ grub_reiserfs_dir (grub_device_t device, const cha enum grub_fshelp_filetype filetype, grub_fshelp_node_t node) { + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); grub_free (node); - - if (filetype == GRUB_FSHELP_DIR) - return hook (filename, 1); - else - return hook (filename, 0); + return hook (filename, info); } #ifndef GRUB_UTIL grub_dl_ref (my_mod); Index: fs/jfs.c =================================================================== --- fs/jfs.c (revision 1989) +++ fs/jfs.c (working copy) @@ -728,7 +728,7 @@ grub_jfs_lookup_symlink (struct grub_jfs_data *dat static grub_err_t grub_jfs_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, int dir)) + int (*hook) (const char *filename, struct grub_dirhook_info info)) { struct grub_jfs_data *data = 0; struct grub_jfs_diropen *diro = 0; @@ -752,14 +752,15 @@ grub_jfs_dir (grub_device_t device, const char *pa while (grub_jfs_getent (diro) != GRUB_ERR_OUT_OF_RANGE) { struct grub_jfs_inode inode; - int isdir; + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); if (grub_jfs_read_inode (data, diro->ino, &inode)) goto fail; - isdir = (grub_le_to_cpu32 (inode.mode) - & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_DIR; - if (hook (diro->name, isdir)) + info.dir = (grub_le_to_cpu32 (inode.mode) + & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_DIR; + if (hook (diro->name, info)) goto fail; } Index: fs/ext2.c =================================================================== --- fs/ext2.c (revision 1989) +++ fs/ext2.c (working copy) @@ -662,11 +662,12 @@ grub_ext2_iterate_dir (grub_fshelp_node_t dir, fdiro = grub_malloc (sizeof (struct grub_fshelp_node)); if (! fdiro) return 0; - + fdiro->data = diro->data; fdiro->ino = grub_le_to_cpu32 (dirent.inode); filename[dirent.namelen] = '\0'; + if (dirent.filetype != FILETYPE_UNKNOWN) { @@ -682,9 +683,10 @@ grub_ext2_iterate_dir (grub_fshelp_node_t dir, else { /* The filetype can not be read from the dirent, read - the inode to get more information. */ + the inode to get more information. */ + grub_ext2_read_inode (diro->data, - grub_le_to_cpu32 (dirent.inode), + grub_le_to_cpu32 (dirent.inode), &fdiro->inode); if (grub_errno) { @@ -788,7 +790,8 @@ grub_ext2_read (grub_file_t file, char *buf, grub_ static grub_err_t grub_ext2_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, int dir)) + int (*hook) (const char *filename, + struct grub_dirhook_info info)) { struct grub_ext2_data *data = 0;; struct grub_fshelp_node *fdiro = 0; @@ -801,14 +804,24 @@ grub_ext2_dir (grub_device_t device, const char *p enum grub_fshelp_filetype filetype, grub_fshelp_node_t node) { + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + if (! node->inode_read) + { + grub_ext2_read_inode (data, node->ino, &node->inode); + if (!grub_errno) + node->inode_read = 1; + grub_errno = GRUB_ERR_NONE; + } + if (node->inode_read) + { + info.mtimeset = 1; + info.mtime = grub_le_to_cpu32 (node->inode.mtime); + } + + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); grub_free (node); - - if (filetype == GRUB_FSHELP_DIR) - return hook (filename, 1); - else - return hook (filename, 0); - - return 0; + return hook (filename, info); } #ifndef GRUB_UTIL @@ -895,6 +908,34 @@ grub_ext2_uuid (grub_device_t device, char **uuid) return grub_errno; } +/* Get mtime. */ +static grub_err_t +grub_ext2_mtime (grub_device_t device, grub_int32_t *tm) +{ + struct grub_ext2_data *data; + grub_disk_t disk = device->disk; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_ext2_mount (disk); + if (!data) + *tm = 0; + else + *tm = grub_le_to_cpu32 (data->sblock.utime); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + grub_free (data); + + return grub_errno; + +} + + static struct grub_fs grub_ext2_fs = { @@ -905,6 +946,7 @@ static struct grub_fs grub_ext2_fs = .close = grub_ext2_close, .label = grub_ext2_label, .uuid = grub_ext2_uuid, + .mtime = grub_ext2_mtime, .next = 0 }; Index: fs/minix.c =================================================================== --- fs/minix.c (revision 1989) +++ fs/minix.c (working copy) @@ -461,7 +461,8 @@ grub_minix_mount (grub_disk_t disk) static grub_err_t grub_minix_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, int dir)) + int (*hook) (const char *filename, + struct grub_dirhook_info info)) { struct grub_minix_data *data = 0; struct grub_minix_sblock *sblock; @@ -492,6 +493,9 @@ grub_minix_dir (grub_device_t device, const char * grub_uint16_t ino; char filename[data->filename_size + 1]; int dirino = data->ino; + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + if (grub_minix_read_file (data, 0, pos, sizeof (ino), (char *) &ino) < 0) @@ -506,8 +510,9 @@ grub_minix_dir (grub_device_t device, const char * /* The filetype is not stored in the dirent. Read the inode to find out the filetype. This *REALLY* sucks. */ grub_minix_read_inode (data, grub_le_to_cpu16 (ino)); - if (hook (filename, ((GRUB_MINIX_INODE_MODE (data) - & GRUB_MINIX_IFDIR) == GRUB_MINIX_IFDIR)) ? 1 : 0) + info.dir = ((GRUB_MINIX_INODE_MODE (data) + & GRUB_MINIX_IFDIR) == GRUB_MINIX_IFDIR); + if (hook (filename, info) ? 1 : 0) break; /* Load the old inode back in. */ Index: fs/hfsplus.c =================================================================== --- fs/hfsplus.c (revision 1989) +++ fs/hfsplus.c (working copy) @@ -885,7 +885,8 @@ grub_hfsplus_read (grub_file_t file, char *buf, gr static grub_err_t grub_hfsplus_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, int dir)) + int (*hook) (const char *filename, + struct grub_dirhook_info info)) { struct grub_hfsplus_data *data = 0; struct grub_fshelp_node *fdiro = 0; @@ -898,14 +899,11 @@ grub_hfsplus_dir (grub_device_t device, const char enum grub_fshelp_filetype filetype, grub_fshelp_node_t node) { + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); grub_free (node); - - if (filetype == GRUB_FSHELP_DIR) - return hook (filename, 1); - else - return hook (filename, 0); - - return 0; + return hook (filename, info); } #ifndef GRUB_UTIL Index: fs/cpio.c =================================================================== --- fs/cpio.c (revision 1989) +++ fs/cpio.c (working copy) @@ -183,7 +183,8 @@ fail: static grub_err_t grub_cpio_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, int dir)) + int (*hook) (const char *filename, + struct grub_dirhook_info info)) { struct grub_cpio_data *data; grub_uint32_t ofs; @@ -227,7 +228,11 @@ grub_cpio_dir (grub_device_t device, const char *p if ((!prev) || (grub_strcmp (prev, name) != 0)) { - hook (name + len, p != NULL); + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + info.dir = (p != NULL); + + hook (name + len, info); if (prev) grub_free (prev); prev = name; Index: fs/sfs.c =================================================================== --- fs/sfs.c (revision 1989) +++ fs/sfs.c (working copy) @@ -527,7 +527,8 @@ grub_sfs_read (grub_file_t file, char *buf, grub_s static grub_err_t grub_sfs_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, int dir)) + int (*hook) (const char *filename, + struct grub_dirhook_info info)) { struct grub_sfs_data *data = 0; struct grub_fshelp_node *fdiro = 0; @@ -540,14 +541,11 @@ grub_sfs_dir (grub_device_t device, const char *pa enum grub_fshelp_filetype filetype, grub_fshelp_node_t node) { + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); grub_free (node); - - if (filetype == GRUB_FSHELP_DIR) - return hook (filename, 1); - else - return hook (filename, 0); - - return 0; + return hook (filename, info); } #ifndef GRUB_UTIL Index: fs/ufs.c =================================================================== --- fs/ufs.c (revision 1989) +++ fs/ufs.c (working copy) @@ -544,7 +544,8 @@ grub_ufs_mount (grub_disk_t disk) static grub_err_t grub_ufs_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, int dir)) + int (*hook) (const char *filename, + struct grub_dirhook_info info)) { struct grub_ufs_data *data; struct grub_ufs_sblock *sblock; @@ -586,13 +587,16 @@ grub_ufs_dir (grub_device_t device, const char *pa { char filename[dirent.namelen + 1]; + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); if (grub_ufs_read_file (data, 0, pos + sizeof (dirent), dirent.namelen, filename) < 0) break; filename[dirent.namelen] = '\0'; - if (hook (filename, dirent.filetype == GRUB_UFS_FILETYPE_DIR)) + info.dir = (dirent.filetype == GRUB_UFS_FILETYPE_DIR); + if (hook (filename, info)) break; } Index: normal/completion.c =================================================================== --- normal/completion.c (revision 1989) +++ normal/completion.c (working copy) @@ -123,9 +123,9 @@ iterate_partition (grub_disk_t disk, const grub_pa } static int -iterate_dir (const char *filename, int dir) +iterate_dir (const char *filename, struct grub_dirhook_info info) { - if (! dir) + if (! info.dir) { const char *prefix; if (cmdline_state == GRUB_PARSER_STATE_DQUOTE) Index: normal/cmdline.c =================================================================== --- normal/cmdline.c (revision 1989) +++ normal/cmdline.c (working copy) @@ -304,7 +304,7 @@ grub_cmdline_get (const char *prompt, char cmdline if ((grub_getxy () >> 8) != 0) grub_putchar ('\n'); - grub_printf (prompt); + grub_printf ("%s", prompt); xpos = plen; ystart = ypos = (grub_getxy () & 0xFF); Index: normal/misc.c =================================================================== --- normal/misc.c (revision 1989) +++ normal/misc.c (working copy) @@ -23,6 +23,7 @@ #include #include #include +#include /* Print the information on the device NAME. */ grub_err_t @@ -63,6 +64,23 @@ grub_normal_print_device_info (const char *name) } grub_errno = GRUB_ERR_NONE; } + if (fs->mtime) + { + grub_int32_t tm; + struct grub_datetime datetime; + (fs->mtime) (dev, &tm); + if (grub_errno == GRUB_ERR_NONE) + { + grub_unixtime2datetime (tm, &datetime); + grub_printf (", Last modification time %d-%02d-%02d " + "%02d:%02d:%02d %s", + datetime.year, datetime.month, datetime.day, + datetime.hour, datetime.minute, datetime.second, + grub_get_weekday_name (&datetime)); + + } + grub_errno = GRUB_ERR_NONE; + } if (fs->uuid) { char *uuid; Index: commands/ls.c =================================================================== --- commands/ls.c (revision 1989) +++ commands/ls.c (working copy) @@ -29,6 +29,7 @@ #include #include #include +#include static const struct grub_arg_option options[] = { @@ -68,25 +69,27 @@ grub_ls_list_files (char *dirname, int longlist, i grub_fs_t fs; const char *path; grub_device_t dev; - auto int print_files (const char *filename, int dir); - auto int print_files_long (const char *filename, int dir); + + auto int print_files (const char *filename, struct grub_dirhook_info info); + auto int print_files_long (const char *filename, + struct grub_dirhook_info info); - int print_files (const char *filename, int dir) + int print_files (const char *filename, struct grub_dirhook_info info) { if (all || filename[0] != '.') - grub_printf ("%s%s ", filename, dir ? "/" : ""); + grub_printf ("%s%s ", filename, info.dir ? "/" : ""); return 0; } - int print_files_long (const char *filename, int dir) + int print_files_long (const char *filename, struct grub_dirhook_info info) { char pathname[grub_strlen (dirname) + grub_strlen (filename) + 1]; if ((! all) && (filename[0] == '.')) return 0; - if (! dir) + if (! info.dir) { grub_file_t file; @@ -138,7 +141,23 @@ grub_ls_list_files (char *dirname, int longlist, i else grub_printf ("%-12s", "DIR"); - grub_printf ("%s%s\n", filename, dir ? "/" : ""); + if (info.mtimeset) + { + struct grub_datetime datetime; + grub_unixtime2datetime (info.mtime, &datetime); + if (human) + grub_printf (" %d-%02d-%02d %02d:%02d:%02d %-11s ", + datetime.year, datetime.month, datetime.day, + datetime.hour, datetime.minute, + datetime.second, + grub_get_weekday_name (&datetime)); + else + grub_printf (" %04d%02d%02d%02d%02d%02d ", + datetime.year, datetime.month, + datetime.day, datetime.hour, + datetime.minute, datetime.second); + } + grub_printf ("%s%s\n", filename, info.dir ? "/" : ""); return 0; } @@ -181,7 +200,7 @@ grub_ls_list_files (char *dirname, int longlist, i /* PATH might be a regular file. */ char *p; grub_file_t file; - + struct grub_dirhook_info info; grub_errno = 0; file = grub_file_open (dirname); @@ -196,10 +215,11 @@ grub_ls_list_files (char *dirname, int longlist, i goto fail; all = 1; + grub_memset (&info, 0, sizeof (info)); if (longlist) - print_files_long (p, 0); + print_files_long (p, info); else - print_files (p, 0); + print_files (p, info); grub_free (dirname); } Index: util/hostfs.c =================================================================== --- util/hostfs.c (revision 1989) +++ util/hostfs.c (working copy) @@ -57,7 +57,8 @@ is_dir (const char *path, const char *name) static grub_err_t grub_hostfs_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, int dir)) + int (*hook) (const char *filename, + struct grub_dirhook_info info)) { DIR *dir; @@ -73,16 +74,20 @@ grub_hostfs_dir (grub_device_t device, const char while (1) { struct dirent *de; + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); de = readdir (dir); if (! de) break; #ifdef DT_DIR - hook (de->d_name, de->d_type == DT_DIR); + info.dir = (de->d_type == DT_DIR); #else - hook (de->d_name, is_dir (path, de->d_name)); + info.dir = is_dir (path, de->d_name); #endif + hook (de->d_name, info); + } closedir (dir); Index: include/grub/lib/datetime.h =================================================================== --- include/grub/lib/datetime.h (revision 1989) +++ include/grub/lib/datetime.h (working copy) @@ -41,4 +41,8 @@ grub_err_t grub_set_datetime (struct grub_datetime int grub_get_weekday (struct grub_datetime *datetime); char *grub_get_weekday_name (struct grub_datetime *datetime); +void grub_unixtime2datetime (grub_int32_t nix, + struct grub_datetime *datetime); + + #endif /* ! KERNEL_DATETIME_HEADER */ Index: include/grub/fs.h =================================================================== --- include/grub/fs.h (revision 1989) +++ include/grub/fs.h (working copy) @@ -27,6 +27,13 @@ /* Forward declaration is required, because of mutual reference. */ struct grub_file; +struct grub_dirhook_info +{ + int dir:1; + int mtimeset:1; + grub_int32_t mtime; +}; + /* Filesystem descriptor. */ struct grub_fs { @@ -35,7 +42,8 @@ struct grub_fs /* Call HOOK with each file under DIR. */ grub_err_t (*dir) (grub_device_t device, const char *path, - int (*hook) (const char *filename, int dir)); + int (*hook) (const char *filename, + struct grub_dirhook_info info)); /* Open a file named NAME and initialize FILE. */ grub_err_t (*open) (struct grub_file *file, const char *name); @@ -56,6 +64,9 @@ struct grub_fs caller. */ grub_err_t (*uuid) (grub_device_t device, char **uuid); + /* Get writing time of filesystem. */ + grub_err_t (*mtime) (grub_device_t device, grub_int32_t *timebuf); + /* The next filesystem. */ struct grub_fs *next; }; Index: include/grub/fshelp.h =================================================================== --- include/grub/fshelp.h (revision 1989) +++ include/grub/fshelp.h (working copy) @@ -27,6 +27,8 @@ typedef struct grub_fshelp_node *grub_fshelp_node_t; #define GRUB_FSHELP_CASE_INSENSITIVE 0x100 +#define GRUB_FSHELP_TYPE_MASK 0xff +#define GRUB_FSHELP_FLAGS_MASK 0x100 enum grub_fshelp_filetype { Index: ChangeLog =================================================================== --- ChangeLog (revision 1989) +++ ChangeLog (working copy) @@ -1,3 +1,63 @@ +2009-02-12 Vladimir Serbinenko + + Support for mtime and further expandability of dir command + + * include/grub/lib/datetime.h: declaration of grub_unixtime2datetime + * include/grub/fs.h: new syntax for dir and mtime functionin + struct grub_fs + * include/grub/fshelp.h: new declarations of GRUB_FSHELP_TYPE_MASK + and GRUB_FSHELP_FLAGS_MASK + * commands/ls.c (grub_ls_list_files): Write mtime in long format + * fs/ext2.c (grub_ext2_dir): use new dir syntax and supply mtime + (grub_ext2_mtime): new function + * fs/affs.c (grub_affs_dir): use new dir syntax + * fs/afs.c (grub_afs_dir): likewise + * fs/cpio.c (grub_cpio_dir): likewise + * fs/fat.c (grub_fat_find_dir): likewise + * fs/hfs.c (grub_hfs_dir): likewise + * fs/hfsplus.c (grub_hfsplus_dir): likewise + * fs/iso9660.c (grub_iso9660_dir): likewise + * fs/jfs.c (grub_jfs_dir): likewise + * fs/minix.c (grub_minix_dir): likewise + * fs/ntfs.c (grub_ntfs_dir): likewise + * fs/reiserfs.c (grub_reiserfs_dir): likewise + * fs/sfs.c (grub_sfs_dir): likewise + * fs/xfs.c (grub_xfs_dir): likewise + * fs/ufs.c (grub_ufs_dir): likewise + * util/hostfs.c (grub_hostfs_dir): likewise + * lib/datetime.c (grub_unixtime2datetime): new function + * kern/rescue.c (grub_rescue_print_files): use new dir syntax + * normal/completition.c (iterate_dir): use new dir syntax + * normal/misc.c (grub_normal_print_device_info): tell the + last modification time of a volume + * kern/fs.c (grub_fs_probe): updated dummy function to use new syntax + * conf/common.rmk: added lib/datetime.c to ls.mod + * conf/i386-coreboot.rmk: added lib/datetime.c to grub-emu + and normal.mod + * conf/i386-efi.rmk: likewise + * conf/i386-ieee1275.rmk: likewise + * conf/i386-pc.rmk: likewise + * conf/powerpc-ieee1275.rmk: likewise + * conf/sparc64-ieee1275.rmk: likewise + * conf/x86_64-efi.rmk: likewise + +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 + +2009-02-09 Vladimir Serbinenko + + Bugfix: directories not reported as such on case-insensitive hfs+ + + * include/grub/fshelp.h: included definition of GRUB_FSHELP_TYPE_MASK + and GRUB_FSHELP_FLAGS_MASK + * fs/hfsplus.c (grub_hfsplus_dir): ignore filetype flags + 2009-02-11 Robert Millan * util/grub.d/00_header.in: Update old reference to `font' command. --------------030905070100000402000401--