Several FS mtime support.

* grub-core/fs/affs.c (grub_affs_time): New struct.
	(grub_affs_file): New field mtime.
	(grub_fshelp_node): Changed 'block' and 'parent' to more appropriate
	type. Removed 'size'. New field 'di'. All users updated.
	(grub_affs_mount): Simplify checsum checking.
	(grub_affs_iterate_dir): New helper grub_affs_create_node.
	(grub_affs_dir): Handle mtime.
	* grub-core/fs/cpio.c (grub_cpio_find_file): Handle mtime.
	(grub_cpio_dir): Likewise.
	* grub-core/fs/hfs.c (grub_hfs_dirrec): New fields 'ctime' and 'mtime'.
	(grub_hfs_filerec): New field mtime.
	(grub_hfs_dir): Handle mtime.
	(grub_hfs_mtime): New function.
	(grub_hfs_fs): Register grub_hfs_mtime.
	* grub-core/fs/iso9660.c (grub_iso9660_date2): New struct.
	(grub_iso9660_dir): New field mtime.
	(grub_fshelp_node): New field dirent.
	(iso9660_to_unixtime): New function.
	(iso9660_to_unixtime2): Likewise.
	(grub_iso9660_read_symlink): Use node->dirent.
	(grub_iso9660_iterate_dir): Likewise.
	(grub_iso9660_dir): Set mtime.
	(grub_iso9660_mtime): New function.
	(grub_iso9660_fs): Register grub_iso9660_mtime.
	* grub-core/fs/jfs.c (grub_jfs_time): New struct.
	(grub_jfs_inode): New fields atime, ctime and mtime.
	(grub_jfs_dir): Set mtime.
	* grub-core/fs/minix.c (grub_minix_dir): Likewise.
	* grub-core/fs/ntfs.c (list_file): Set mtime.
	(grub_ntfs_dir): Likewise.
	* grub-core/fs/reiserfs.c (grub_fshelp_node): New field 'mtime'.
	(grub_reiserfs_iterate_dir): Set mtime.
	(grub_reiserfs_dir): Likewise.
	* grub-core/fs/sfs.c (grub_sfs_obj): New field mtime.
	(grub_fshelp_node): Likewise.
	(grub_sfs_iterate_dir): Set mtime.
	(grub_sfs_dir): Likewise.
	* grub-core/fs/udf.c (grub_udf_dir): Set mtime.
	* grub-core/fs/xfs.c (grub_xfs_time): New struct.
	(grub_xfs_inode): New fields atime, mtime, ctime.
	(grub_xfs_dir): Set mtime.
	* include/grub/datetime.h (grub_datetime2unixtime): New function.
	* include/grub/hfs.h (grub_hfs_sblock): New fields ctime and mtime.
	* include/grub/ntfs.h (grub_fshelp_node): New field mtime.

	Support UDF symlinks.

	* grub-core/fs/udf.c (grub_udf_iterate_dir): Handle symlinks.
	(grub_ufs_read_symlink): New function. All users updated.

	Check amiga partmap checksum.

	* grub-core/partmap/amiga.c (grub_amiga_rdsk): Pad to 128 bytes.
	(grub_amiga_partition): Likewise.
	(amiga_partition_map_checksum): New function.
	(amiga_partition_map_iterate): Check checksum.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-05-15 12:23:54 +02:00
commit b756f75f07
16 changed files with 466 additions and 64 deletions

View file

@ -1,3 +1,64 @@
2011-05-15 Vladimir Serbinenko <phcoder@gmail.com>
Several FS mtime support.
* grub-core/fs/affs.c (grub_affs_time): New struct.
(grub_affs_file): New field mtime.
(grub_fshelp_node): Changed 'block' and 'parent' to more appropriate
type. Removed 'size'. New field 'di'. All users updated.
(grub_affs_mount): Simplify checsum checking.
(grub_affs_iterate_dir): New helper grub_affs_create_node.
(grub_affs_dir): Handle mtime.
* grub-core/fs/cpio.c (grub_cpio_find_file): Handle mtime.
(grub_cpio_dir): Likewise.
* grub-core/fs/hfs.c (grub_hfs_dirrec): New fields 'ctime' and 'mtime'.
(grub_hfs_filerec): New field mtime.
(grub_hfs_dir): Handle mtime.
(grub_hfs_mtime): New function.
(grub_hfs_fs): Register grub_hfs_mtime.
* grub-core/fs/iso9660.c (grub_iso9660_date2): New struct.
(grub_iso9660_dir): New field mtime.
(grub_fshelp_node): New field dirent.
(iso9660_to_unixtime): New function.
(iso9660_to_unixtime2): Likewise.
(grub_iso9660_read_symlink): Use node->dirent.
(grub_iso9660_iterate_dir): Likewise.
(grub_iso9660_dir): Set mtime.
(grub_iso9660_mtime): New function.
(grub_iso9660_fs): Register grub_iso9660_mtime.
* grub-core/fs/jfs.c (grub_jfs_time): New struct.
(grub_jfs_inode): New fields atime, ctime and mtime.
(grub_jfs_dir): Set mtime.
* grub-core/fs/minix.c (grub_minix_dir): Likewise.
* grub-core/fs/ntfs.c (list_file): Set mtime.
(grub_ntfs_dir): Likewise.
* grub-core/fs/reiserfs.c (grub_fshelp_node): New field 'mtime'.
(grub_reiserfs_iterate_dir): Set mtime.
(grub_reiserfs_dir): Likewise.
* grub-core/fs/sfs.c (grub_sfs_obj): New field mtime.
(grub_fshelp_node): Likewise.
(grub_sfs_iterate_dir): Set mtime.
(grub_sfs_dir): Likewise.
* grub-core/fs/udf.c (grub_udf_dir): Set mtime.
* grub-core/fs/xfs.c (grub_xfs_time): New struct.
(grub_xfs_inode): New fields atime, mtime, ctime.
(grub_xfs_dir): Set mtime.
* include/grub/datetime.h (grub_datetime2unixtime): New function.
* include/grub/hfs.h (grub_hfs_sblock): New fields ctime and mtime.
* include/grub/ntfs.h (grub_fshelp_node): New field mtime.
Support UDF symlinks.
* grub-core/fs/udf.c (grub_udf_iterate_dir): Handle symlinks.
(grub_ufs_read_symlink): New function. All users updated.
Check amiga partmap checksum.
* grub-core/partmap/amiga.c (grub_amiga_rdsk): Pad to 128 bytes.
(grub_amiga_partition): Likewise.
(amiga_partition_map_checksum): New function.
(amiga_partition_map_iterate): Check checksum.
2011-05-15 Vladimir Serbinenko <phcoder@gmail.com> 2011-05-15 Vladimir Serbinenko <phcoder@gmail.com>
ROMFS support. ROMFS support.

View file

@ -52,12 +52,20 @@ struct grub_affs_rblock
grub_uint32_t hashtable[1]; grub_uint32_t hashtable[1];
} __attribute__ ((packed)); } __attribute__ ((packed));
struct grub_affs_time
{
grub_int32_t day;
grub_uint32_t min;
grub_uint32_t hz;
} __attribute__ ((packed));
/* The second part of a file header block. */ /* The second part of a file header block. */
struct grub_affs_file struct grub_affs_file
{ {
grub_uint8_t unused1[12]; grub_uint8_t unused1[12];
grub_uint32_t size; grub_uint32_t size;
grub_uint8_t unused2[104]; grub_uint8_t unused2[92];
struct grub_affs_time mtime;
grub_uint8_t namelen; grub_uint8_t namelen;
grub_uint8_t name[30]; grub_uint8_t name[30];
grub_uint8_t unused3[33]; grub_uint8_t unused3[33];
@ -87,9 +95,9 @@ struct grub_affs_file
struct grub_fshelp_node struct grub_fshelp_node
{ {
struct grub_affs_data *data; struct grub_affs_data *data;
int block; grub_disk_addr_t block;
int size; struct grub_fshelp_node *parent;
int parent; struct grub_affs_file di;
}; };
/* Information about a "mounted" affs filesystem. */ /* Information about a "mounted" affs filesystem. */
@ -156,7 +164,7 @@ grub_affs_read_file (grub_fshelp_node_t node,
{ {
return grub_fshelp_read_file (node->data->disk, node, read_hook, return grub_fshelp_read_file (node->data->disk, node, read_hook,
pos, len, buf, grub_affs_read_block, pos, len, buf, grub_affs_read_block,
node->size, 0); grub_be_to_cpu32 (node->di.size), 0);
} }
@ -168,7 +176,6 @@ grub_affs_mount (grub_disk_t disk)
struct grub_affs_rblock *rblock; struct grub_affs_rblock *rblock;
int checksum = 0; int checksum = 0;
int checksumr = 0;
int blocksize = 0; int blocksize = 0;
data = grub_malloc (sizeof (struct grub_affs_data)); data = grub_malloc (sizeof (struct grub_affs_data));
@ -218,8 +225,6 @@ grub_affs_mount (grub_disk_t disk)
/* The filesystem blocksize is not stored anywhere in the filesystem /* The filesystem blocksize is not stored anywhere in the filesystem
itself. One way to determine it is reading blocks for the itself. One way to determine it is reading blocks for the
rootblock until the checksum is correct. */ rootblock until the checksum is correct. */
checksumr = grub_be_to_cpu32 (rblock->checksum);
rblock->checksum = 0;
for (blocksize = 0; blocksize < 8; blocksize++) for (blocksize = 0; blocksize < 8; blocksize++)
{ {
grub_uint32_t *currblock = rootblock + GRUB_DISK_SECTOR_SIZE * blocksize; grub_uint32_t *currblock = rootblock + GRUB_DISK_SECTOR_SIZE * blocksize;
@ -228,10 +233,10 @@ grub_affs_mount (grub_disk_t disk)
for (i = 0; i < GRUB_DISK_SECTOR_SIZE / sizeof (*currblock); i++) for (i = 0; i < GRUB_DISK_SECTOR_SIZE / sizeof (*currblock); i++)
checksum += grub_be_to_cpu32 (currblock[i]); checksum += grub_be_to_cpu32 (currblock[i]);
if (checksumr == -checksum) if (checksum == 0)
break; break;
} }
if (-checksum != checksumr) if (checksum != 0)
{ {
grub_error (GRUB_ERR_BAD_FS, "AFFS blocksize couldn't be determined"); grub_error (GRUB_ERR_BAD_FS, "AFFS blocksize couldn't be determined");
goto fail; goto fail;
@ -243,6 +248,8 @@ grub_affs_mount (grub_disk_t disk)
data->htsize = grub_be_to_cpu32 (rblock->htsize); data->htsize = grub_be_to_cpu32 (rblock->htsize);
data->diropen.data = data; data->diropen.data = data;
data->diropen.block = grub_be_to_cpu32 (data->bblock.rootblock); data->diropen.block = grub_be_to_cpu32 (data->bblock.rootblock);
data->diropen.parent = NULL;
grub_memcpy (&data->diropen.di, rootblock, sizeof (data->diropen.di));
grub_free (rootblock); grub_free (rootblock);
@ -293,12 +300,15 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
struct grub_affs_data *data = dir->data; struct grub_affs_data *data = dir->data;
grub_uint32_t *hashtable; grub_uint32_t *hashtable;
auto int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, int block, auto int NESTED_FUNC_ATTR grub_affs_create_node (const char *name,
int size, int type); grub_disk_addr_t block,
const struct grub_affs_file *fil);
int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, int block, int NESTED_FUNC_ATTR grub_affs_create_node (const char *name,
int size, int type) grub_disk_addr_t block,
const struct grub_affs_file *fil)
{ {
int type;
node = grub_malloc (sizeof (*node)); node = grub_malloc (sizeof (*node));
if (!node) if (!node)
{ {
@ -306,10 +316,19 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
return 1; return 1;
} }
if ((int) grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_DIR)
type = GRUB_FSHELP_REG;
else if (grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_REG)
type = GRUB_FSHELP_DIR;
else if (grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_SYMLINK)
type = GRUB_FSHELP_SYMLINK;
else
type = GRUB_FSHELP_UNKNOWN;
node->data = data; node->data = data;
node->size = size;
node->block = block; node->block = block;
node->parent = grub_be_to_cpu32 (file.parent); node->di = *fil;
node->parent = dir;
if (hook (name, type, node)) if (hook (name, type, node))
{ {
@ -319,6 +338,24 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
return 0; return 0;
} }
/* Create the directory entries for `.' and `..'. */
node = grub_malloc (sizeof (*node));
if (!node)
return 1;
*node = *dir;
if (hook (".", GRUB_FSHELP_DIR, node))
return 1;
if (dir->parent)
{
node = grub_malloc (sizeof (*node));
if (!node)
return 1;
*node = *dir->parent;
if (hook ("..", GRUB_FSHELP_DIR, node))
return 1;
}
hashtable = grub_malloc (data->htsize * sizeof (*hashtable)); hashtable = grub_malloc (data->htsize * sizeof (*hashtable));
if (!hashtable) if (!hashtable)
return 1; return 1;
@ -328,16 +365,8 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
if (grub_errno) if (grub_errno)
goto fail; goto fail;
/* Create the directory entries for `.' and `..'. */
if (grub_affs_create_node (".", dir->block, dir->size, GRUB_FSHELP_DIR))
return 1;
if (grub_affs_create_node ("..", dir->parent ? dir->parent : dir->block,
dir->size, GRUB_FSHELP_DIR))
return 1;
for (i = 0; i < data->htsize; i++) for (i = 0; i < data->htsize; i++)
{ {
enum grub_fshelp_filetype type;
grub_uint64_t next; grub_uint64_t next;
if (!hashtable[i]) if (!hashtable[i])
@ -358,17 +387,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
file.name[file.namelen] = '\0'; file.name[file.namelen] = '\0';
if ((int) grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_DIR) if (grub_affs_create_node ((char *) (file.name), next, &file))
type = GRUB_FSHELP_REG;
else if (grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_REG)
type = GRUB_FSHELP_DIR;
else if (grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_SYMLINK)
type = GRUB_FSHELP_SYMLINK;
else
type = GRUB_FSHELP_UNKNOWN;
if (grub_affs_create_node ((char *) (file.name), next,
grub_be_to_cpu32 (file.size), type))
return 1; return 1;
next = grub_be_to_cpu32 (file.next); next = grub_be_to_cpu32 (file.next);
@ -403,7 +422,7 @@ grub_affs_open (struct grub_file *file, const char *name)
if (grub_errno) if (grub_errno)
goto fail; goto fail;
file->size = fdiro->size; file->size = grub_be_to_cpu32 (fdiro->di.size);
data->diropen = *fdiro; data->diropen = *fdiro;
grub_free (fdiro); grub_free (fdiro);
@ -467,6 +486,11 @@ grub_affs_dir (grub_device_t device, const char *path,
struct grub_dirhook_info info; struct grub_dirhook_info info;
grub_memset (&info, 0, sizeof (info)); grub_memset (&info, 0, sizeof (info));
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
info.mtimeset = 1;
info.mtime = grub_be_to_cpu32 (node->di.mtime.day) * 86400
+ grub_be_to_cpu32 (node->di.mtime.min) * 60
+ grub_be_to_cpu32 (node->di.mtime.hz) / 50
+ 8 * 365 * 86400 + 86400 * 2;
grub_free (node); grub_free (node);
return hook (filename, &info); return hook (filename, &info);
} }

View file

@ -80,7 +80,7 @@ static grub_dl_t my_mod;
static grub_err_t static grub_err_t
grub_cpio_find_file (struct grub_cpio_data *data, char **name, grub_cpio_find_file (struct grub_cpio_data *data, char **name,
grub_uint32_t * ofs) grub_int32_t *mtime, grub_uint32_t * ofs)
{ {
#ifndef MODE_USTAR #ifndef MODE_USTAR
struct head hd; struct head hd;
@ -93,6 +93,8 @@ grub_cpio_find_file (struct grub_cpio_data *data, char **name,
return grub_error (GRUB_ERR_BAD_FS, "invalid cpio archive"); return grub_error (GRUB_ERR_BAD_FS, "invalid cpio archive");
data->size = (((grub_uint32_t) hd.filesize_1) << 16) + hd.filesize_2; data->size = (((grub_uint32_t) hd.filesize_1) << 16) + hd.filesize_2;
if (mtime)
*mtime = (((grub_uint32_t) hd.mtime_1) << 16) + hd.mtime_2;
if (hd.namesize & 1) if (hd.namesize & 1)
hd.namesize++; hd.namesize++;
@ -141,6 +143,8 @@ grub_cpio_find_file (struct grub_cpio_data *data, char **name,
data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE; data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE;
*ofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) & *ofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) &
~(GRUB_DISK_SECTOR_SIZE - 1)); ~(GRUB_DISK_SECTOR_SIZE - 1));
if (mtime)
*mtime = grub_strtoul (hd.mtime, NULL, 8);
#endif #endif
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@ -206,7 +210,9 @@ grub_cpio_dir (grub_device_t device, const char *path,
data->hofs = 0; data->hofs = 0;
while (1) while (1)
{ {
if (grub_cpio_find_file (data, &name, &ofs)) grub_int32_t mtime;
if (grub_cpio_find_file (data, &name, &mtime, &ofs))
goto fail; goto fail;
if (!ofs) if (!ofs)
@ -229,6 +235,8 @@ grub_cpio_dir (grub_device_t device, const char *path,
struct grub_dirhook_info info; struct grub_dirhook_info info;
grub_memset (&info, 0, sizeof (info)); grub_memset (&info, 0, sizeof (info));
info.dir = (p != NULL); info.dir = (p != NULL);
info.mtime = mtime;
info.mtimeset = 1;
hook (name + len, &info); hook (name + len, &info);
if (prev) if (prev)
@ -271,7 +279,7 @@ grub_cpio_open (grub_file_t file, const char *name)
data->hofs = 0; data->hofs = 0;
while (1) while (1)
{ {
if (grub_cpio_find_file (data, &fn, &ofs)) if (grub_cpio_find_file (data, &fn, NULL, &ofs))
goto fail; goto fail;
if (!ofs) if (!ofs)

View file

@ -133,6 +133,8 @@ struct grub_hfs_dirrec
grub_uint8_t type; grub_uint8_t type;
grub_uint8_t unused[5]; grub_uint8_t unused[5];
grub_uint32_t dirid; grub_uint32_t dirid;
grub_uint32_t ctime;
grub_uint32_t mtime;
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Information about a file. */ /* Information about a file. */
@ -144,7 +146,9 @@ struct grub_hfs_filerec
grub_uint32_t fileid; grub_uint32_t fileid;
grub_uint8_t unused2[2]; grub_uint8_t unused2[2];
grub_uint32_t size; grub_uint32_t size;
grub_uint8_t unused3[44]; grub_uint8_t unused3[18];
grub_uint32_t mtime;
grub_uint8_t unused4[22];
/* The first 3 extents of the file. The other extents can be found /* The first 3 extents of the file. The other extents can be found
in the extent overflow file. */ in the extent overflow file. */
@ -953,19 +957,29 @@ grub_hfs_dir (grub_device_t device, const char *path,
int dir_hook (struct grub_hfs_record *rec) int dir_hook (struct grub_hfs_record *rec)
{ {
char fname[32] = { 0 }; char fname[32] = { 0 };
char *filetype = rec->data; struct grub_hfs_dirrec *drec = rec->data;
struct grub_hfs_filerec *frec = rec->data;
struct grub_hfs_catalog_key *ckey = rec->key; struct grub_hfs_catalog_key *ckey = rec->key;
struct grub_dirhook_info info; struct grub_dirhook_info info;
grub_memset (&info, 0, sizeof (info)); grub_memset (&info, 0, sizeof (info));
grub_strncpy (fname, (char *) (ckey->str), ckey->strlen); grub_strncpy (fname, (char *) (ckey->str), ckey->strlen);
if (*filetype == GRUB_HFS_FILETYPE_DIR if (drec->type == GRUB_HFS_FILETYPE_DIR)
|| *filetype == GRUB_HFS_FILETYPE_FILE)
{ {
info.dir = (*filetype == GRUB_HFS_FILETYPE_DIR); info.dir = 1;
info.mtimeset = 1;
info.mtime = grub_be_to_cpu32 (drec->mtime) - 2082844800;
return hook (fname, &info); return hook (fname, &info);
} }
if (frec->type == GRUB_HFS_FILETYPE_FILE)
{
info.dir = 0;
info.mtimeset = 1;
info.mtime = grub_be_to_cpu32 (frec->mtime) - 2082844800;
return hook (fname, &info);
}
return 0; return 0;
} }
@ -1074,6 +1088,22 @@ grub_hfs_label (grub_device_t device, char **label)
return grub_errno; return grub_errno;
} }
static grub_err_t
grub_hfs_mtime (grub_device_t device, grub_int32_t *tm)
{
struct grub_hfs_data *data;
data = grub_hfs_mount (device->disk);
if (data)
*tm = grub_be_to_cpu32 (data->sblock.mtime) - 2082844800;
else
*tm = 0;
grub_free (data);
return grub_errno;
}
static grub_err_t static grub_err_t
grub_hfs_uuid (grub_device_t device, char **uuid) grub_hfs_uuid (grub_device_t device, char **uuid)
{ {
@ -1109,6 +1139,7 @@ static struct grub_fs grub_hfs_fs =
.close = grub_hfs_close, .close = grub_hfs_close,
.label = grub_hfs_label, .label = grub_hfs_label,
.uuid = grub_hfs_uuid, .uuid = grub_hfs_uuid,
.mtime = grub_hfs_mtime,
.next = 0 .next = 0
}; };

View file

@ -27,6 +27,7 @@
#include <grub/types.h> #include <grub/types.h>
#include <grub/fshelp.h> #include <grub/fshelp.h>
#include <grub/charset.h> #include <grub/charset.h>
#include <grub/datetime.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -55,6 +56,17 @@ struct grub_iso9660_voldesc
grub_uint8_t version; grub_uint8_t version;
} __attribute__ ((packed)); } __attribute__ ((packed));
struct grub_iso9660_date2
{
grub_uint8_t year;
grub_uint8_t month;
grub_uint8_t day;
grub_uint8_t hour;
grub_uint8_t minute;
grub_uint8_t second;
grub_uint8_t offset;
} __attribute__ ((packed));
/* A directory entry. */ /* A directory entry. */
struct grub_iso9660_dir struct grub_iso9660_dir
{ {
@ -64,7 +76,7 @@ struct grub_iso9660_dir
grub_uint32_t first_sector_be; grub_uint32_t first_sector_be;
grub_uint32_t size; grub_uint32_t size;
grub_uint32_t size_be; grub_uint32_t size_be;
grub_uint8_t unused1[7]; struct grub_iso9660_date2 mtime;
grub_uint8_t flags; grub_uint8_t flags;
grub_uint8_t unused2[6]; grub_uint8_t unused2[6];
grub_uint8_t namelen; grub_uint8_t namelen;
@ -146,6 +158,7 @@ struct grub_iso9660_data
struct grub_fshelp_node struct grub_fshelp_node
{ {
struct grub_iso9660_data *data; struct grub_iso9660_data *data;
struct grub_iso9660_dir dirent;
unsigned int size; unsigned int size;
unsigned int blk; unsigned int blk;
unsigned int dir_blk; unsigned int dir_blk;
@ -155,6 +168,52 @@ struct grub_fshelp_node
static grub_dl_t my_mod; static grub_dl_t my_mod;
static grub_err_t
iso9660_to_unixtime (const struct grub_iso9660_date *i, grub_int32_t *nix)
{
struct grub_datetime datetime;
if (! i->year[0] && ! i->year[1]
&& ! i->year[2] && ! i->year[3]
&& ! i->month[0] && ! i->month[1]
&& ! i->day[0] && ! i->day[1]
&& ! i->hour[0] && ! i->hour[1]
&& ! i->minute[0] && ! i->minute[1]
&& ! i->second[0] && ! i->second[1]
&& ! i->hundredth[0] && ! i->hundredth[1])
return grub_error (GRUB_ERR_BAD_NUMBER, "empty date");
datetime.year = (i->year[0] - '0') * 1000 + (i->year[1] - '0') * 100
+ (i->year[2] - '0') * 10 + (i->year[3] - '0');
datetime.month = (i->month[0] - '0') * 10 + (i->month[1] - '0');
datetime.day = (i->day[0] - '0') * 10 + (i->day[1] - '0');
datetime.hour = (i->hour[0] - '0') * 10 + (i->hour[1] - '0');
datetime.minute = (i->minute[0] - '0') * 10 + (i->minute[1] - '0');
datetime.second = (i->second[0] - '0') * 10 + (i->second[1] - '0');
if (!grub_datetime2unixtime (&datetime, nix))
return grub_error (GRUB_ERR_BAD_NUMBER, "incorrect date");
*nix -= i->offset * 60 * 15;
return GRUB_ERR_NONE;
}
static int
iso9660_to_unixtime2 (const struct grub_iso9660_date2 *i, grub_int32_t *nix)
{
struct grub_datetime datetime;
datetime.year = i->year + 1900;
datetime.month = i->month;
datetime.day = i->day;
datetime.hour = i->hour;
datetime.minute = i->minute;
datetime.second = i->second;
if (!grub_datetime2unixtime (&datetime, nix))
return 0;
*nix -= i->offset * 60 * 15;
return 1;
}
/* Iterate over the susp entries, starting with block SUA_BLOCK on the /* Iterate over the susp entries, starting with block SUA_BLOCK on the
offset SUA_POS with a size of SUA_SIZE bytes. Hook is called for offset SUA_POS with a size of SUA_SIZE bytes. Hook is called for
every entry. */ every entry. */
@ -366,7 +425,6 @@ grub_iso9660_mount (grub_disk_t disk)
static char * static char *
grub_iso9660_read_symlink (grub_fshelp_node_t node) grub_iso9660_read_symlink (grub_fshelp_node_t node)
{ {
struct grub_iso9660_dir dirent;
int sua_off; int sua_off;
int sua_size; int sua_size;
char *symlink = 0; char *symlink = 0;
@ -444,13 +502,10 @@ grub_iso9660_read_symlink (grub_fshelp_node_t node)
return 0; return 0;
} }
if (grub_disk_read (node->data->disk, node->dir_blk, node->dir_off, sua_off = (sizeof (node->dirent) + node->dirent.namelen + 1
sizeof (dirent), (char *) &dirent)) - (node->dirent.namelen % 2)
return 0;
sua_off = (sizeof (dirent) + dirent.namelen + 1 - (dirent.namelen % 2)
+ node->data->susp_skip); + node->data->susp_skip);
sua_size = dirent.len - sua_off; sua_size = node->dirent.len - sua_off;
symlink = grub_malloc (1); symlink = grub_malloc (1);
if (!symlink) if (!symlink)
@ -647,6 +702,7 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
filename_alloc = 1; filename_alloc = 1;
} }
node->dirent = dirent;
if (hook (filename, type, node)) if (hook (filename, type, node))
{ {
if (filename_alloc) if (filename_alloc)
@ -685,6 +741,8 @@ grub_iso9660_dir (grub_device_t device, const char *path,
struct grub_dirhook_info info; struct grub_dirhook_info info;
grub_memset (&info, 0, sizeof (info)); grub_memset (&info, 0, sizeof (info));
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
info.mtimeset = !!iso9660_to_unixtime2 (&node->dirent.mtime, &info.mtime);
grub_free (node); grub_free (node);
return hook (filename, &info); return hook (filename, &info);
} }
@ -882,6 +940,32 @@ grub_iso9660_uuid (grub_device_t device, char **uuid)
return grub_errno; return grub_errno;
} }
/* Get writing time of filesystem. */
static grub_err_t
grub_iso9660_mtime (grub_device_t device, grub_int32_t *timebuf)
{
struct grub_iso9660_data *data;
grub_disk_t disk = device->disk;
grub_err_t err;
grub_dl_ref (my_mod);
data = grub_iso9660_mount (disk);
if (!data)
{
grub_dl_unref (my_mod);
return grub_errno;
}
err = iso9660_to_unixtime (&data->voldesc.modified, timebuf);
grub_dl_unref (my_mod);
grub_free (data);
return err;
}
static struct grub_fs grub_iso9660_fs = static struct grub_fs grub_iso9660_fs =
@ -893,6 +977,7 @@ static struct grub_fs grub_iso9660_fs =
.close = grub_iso9660_close, .close = grub_iso9660_close,
.label = grub_iso9660_label, .label = grub_iso9660_label,
.uuid = grub_iso9660_uuid, .uuid = grub_iso9660_uuid,
.mtime = grub_iso9660_mtime,
.next = 0 .next = 0
}; };

View file

@ -155,6 +155,12 @@ struct grub_jfs_leaf_next_dirent
grub_uint16_t namepart[15]; grub_uint16_t namepart[15];
} __attribute__ ((packed)); } __attribute__ ((packed));
struct grub_jfs_time
{
grub_int32_t sec;
grub_int32_t nanosec;
} __attribute__ ((packed));
struct grub_jfs_inode struct grub_jfs_inode
{ {
grub_uint32_t stamp; grub_uint32_t stamp;
@ -164,7 +170,10 @@ struct grub_jfs_inode
grub_uint64_t size; grub_uint64_t size;
grub_uint8_t unused2[20]; grub_uint8_t unused2[20];
grub_uint32_t mode; grub_uint32_t mode;
grub_uint8_t unused3[72]; struct grub_jfs_time atime;
struct grub_jfs_time ctime;
struct grub_jfs_time mtime;
grub_uint8_t unused3[48];
grub_uint8_t unused4[96]; grub_uint8_t unused4[96];
union union
@ -760,6 +769,8 @@ grub_jfs_dir (grub_device_t device, const char *path,
info.dir = (grub_le_to_cpu32 (inode.mode) info.dir = (grub_le_to_cpu32 (inode.mode)
& GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_DIR; & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_DIR;
info.mtimeset = 1;
info.mtime = grub_le_to_cpu32 (inode.mtime.sec);
if (hook (diro->name, &info)) if (hook (diro->name, &info))
goto fail; goto fail;
} }

View file

@ -535,6 +535,13 @@ grub_minix_dir (grub_device_t device, const char *path,
grub_minix_read_inode (data, grub_minix_le_to_cpu_ino (ino)); grub_minix_read_inode (data, grub_minix_le_to_cpu_ino (ino));
info.dir = ((GRUB_MINIX_INODE_MODE (data) info.dir = ((GRUB_MINIX_INODE_MODE (data)
& GRUB_MINIX_IFDIR) == GRUB_MINIX_IFDIR); & GRUB_MINIX_IFDIR) == GRUB_MINIX_IFDIR);
info.mtimeset = 1;
#ifndef MODE_MINIX2
info.mtime = grub_le_to_cpu32 (data->inode.ctime);
#else
info.mtime = grub_le_to_cpu32 (data->inode.mtime);
#endif
if (hook (filename, &info) ? 1 : 0) if (hook (filename, &info) ? 1 : 0)
break; break;

View file

@ -612,6 +612,10 @@ list_file (struct grub_ntfs_file *diro, char *pos,
fdiro->data = diro->data; fdiro->data = diro->data;
fdiro->ino = u32at (pos, 0); fdiro->ino = u32at (pos, 0);
if (u64at (pos, 0x20) > u64at (pos, 0x28))
fdiro->mtime = u64at (pos, 0x20);
else
fdiro->mtime = u64at (pos, 0x28);
ustr = grub_malloc (ns * 4 + 1); ustr = grub_malloc (ns * 4 + 1);
if (ustr == NULL) if (ustr == NULL)
@ -882,6 +886,10 @@ grub_ntfs_dir (grub_device_t device, const char *path,
struct grub_dirhook_info info; struct grub_dirhook_info info;
grub_memset (&info, 0, sizeof (info)); grub_memset (&info, 0, sizeof (info));
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
info.mtimeset = 1;
info.mtime = grub_divmod64 (node->mtime, 10000000, 0)
- 86400ULL * 365 * (1970 - 1601)
- 86400ULL * ((1970 - 1601) / 4) + 86400ULL * ((1970 - 1601) / 100);
grub_free (node); grub_free (node);
return hook (filename, &info); return hook (filename, &info);
} }

View file

@ -224,6 +224,7 @@ struct grub_fshelp_node
grub_uint32_t block_number; /* 0 if node is not found. */ grub_uint32_t block_number; /* 0 if node is not found. */
grub_uint16_t block_position; grub_uint16_t block_position;
grub_uint64_t next_offset; grub_uint64_t next_offset;
grub_int32_t mtime;
enum grub_reiserfs_item_type type; /* To know how to read the header. */ enum grub_reiserfs_item_type type; /* To know how to read the header. */
struct grub_reiserfs_item_header header; struct grub_reiserfs_item_header header;
}; };
@ -870,6 +871,7 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
entry_v1_stat.rdev, entry_v1_stat.rdev,
entry_v1_stat.first_direct_byte); entry_v1_stat.first_direct_byte);
#endif #endif
entry_item->mtime = grub_le_to_cpu32 (entry_v1_stat.mtime);
if ((grub_le_to_cpu16 (entry_v1_stat.mode) & S_IFLNK) if ((grub_le_to_cpu16 (entry_v1_stat.mode) & S_IFLNK)
== S_IFLNK) == S_IFLNK)
entry_type = GRUB_FSHELP_SYMLINK; entry_type = GRUB_FSHELP_SYMLINK;
@ -916,6 +918,7 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
entry_v2_stat.blocks, entry_v2_stat.blocks,
entry_v2_stat.first_direct_byte); entry_v2_stat.first_direct_byte);
#endif #endif
entry_item->mtime = grub_le_to_cpu32 (entry_v2_stat.mtime);
if ((grub_le_to_cpu16 (entry_v2_stat.mode) & S_IFLNK) if ((grub_le_to_cpu16 (entry_v2_stat.mode) & S_IFLNK)
== S_IFLNK) == S_IFLNK)
entry_type = GRUB_FSHELP_SYMLINK; entry_type = GRUB_FSHELP_SYMLINK;
@ -1278,6 +1281,8 @@ grub_reiserfs_dir (grub_device_t device, const char *path,
struct grub_dirhook_info info; struct grub_dirhook_info info;
grub_memset (&info, 0, sizeof (info)); grub_memset (&info, 0, sizeof (info));
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
info.mtimeset = 1;
info.mtime = node->mtime;
grub_free (node); grub_free (node);
return hook (filename, &info); return hook (filename, &info);
} }

View file

@ -68,7 +68,7 @@ struct grub_sfs_obj
grub_uint32_t dir_objc; grub_uint32_t dir_objc;
} dir __attribute__ ((packed)); } dir __attribute__ ((packed));
} file_dir; } file_dir;
grub_uint8_t unused3[4]; grub_uint32_t mtime;
grub_uint8_t type; grub_uint8_t type;
grub_uint8_t filename[1]; grub_uint8_t filename[1];
grub_uint8_t comment[1]; grub_uint8_t comment[1];
@ -121,6 +121,7 @@ struct grub_fshelp_node
struct grub_sfs_data *data; struct grub_sfs_data *data;
int block; int block;
int size; int size;
grub_uint32_t mtime;
}; };
/* Information about a "mounted" sfs filesystem. */ /* Information about a "mounted" sfs filesystem. */
@ -357,10 +358,12 @@ grub_sfs_iterate_dir (grub_fshelp_node_t dir,
int pos; int pos;
auto int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name, int block, auto int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name, int block,
int size, int type); int size, int type,
grub_uint32_t mtime);
int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name, int block, int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name, int block,
int size, int type) int size, int type,
grub_uint32_t mtime)
{ {
node = grub_malloc (sizeof (*node)); node = grub_malloc (sizeof (*node));
if (!node) if (!node)
@ -369,6 +372,7 @@ grub_sfs_iterate_dir (grub_fshelp_node_t dir,
node->data = data; node->data = data;
node->size = size; node->size = size;
node->block = block; node->block = block;
node->mtime = mtime;
return hook (name, type, node); return hook (name, type, node);
} }
@ -428,7 +432,7 @@ grub_sfs_iterate_dir (grub_fshelp_node_t dir,
if (grub_sfs_create_node (filename, block, if (grub_sfs_create_node (filename, block,
grub_be_to_cpu32 (obj->file_dir.file.size), grub_be_to_cpu32 (obj->file_dir.file.size),
type)) type, grub_be_to_cpu32 (obj->mtime)))
{ {
grub_free (objc_data); grub_free (objc_data);
return 1; return 1;
@ -527,6 +531,8 @@ grub_sfs_dir (grub_device_t device, const char *path,
struct grub_dirhook_info info; struct grub_dirhook_info info;
grub_memset (&info, 0, sizeof (info)); grub_memset (&info, 0, sizeof (info));
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
info.mtime = node->mtime + 8 * 365 * 86400 + 86400 * 2;
info.mtimeset = 1;
grub_free (node); grub_free (node);
return hook (filename, &info); return hook (filename, &info);
} }

View file

@ -26,6 +26,7 @@
#include <grub/types.h> #include <grub/types.h>
#include <grub/fshelp.h> #include <grub/fshelp.h>
#include <grub/charset.h> #include <grub/charset.h>
#include <grub/datetime.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -885,6 +886,8 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
type = ((dirent.characteristics & GRUB_UDF_FID_CHAR_DIRECTORY) ? type = ((dirent.characteristics & GRUB_UDF_FID_CHAR_DIRECTORY) ?
(GRUB_FSHELP_DIR) : (GRUB_FSHELP_REG)); (GRUB_FSHELP_DIR) : (GRUB_FSHELP_REG));
if (child->fe.icbtag.file_type == GRUB_UDF_ICBTAG_TYPE_SYMLINK)
type = GRUB_FSHELP_SYMLINK;
if ((grub_udf_read_file (dir, 0, offset, if ((grub_udf_read_file (dir, 0, offset,
dirent.file_ident_length, dirent.file_ident_length,
@ -912,6 +915,25 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
return 0; return 0;
} }
static char *
grub_ufs_read_symlink (grub_fshelp_node_t node)
{
grub_size_t sz = U64 (node->fe.file_size);
grub_uint8_t *raw;
char *ret;
if (sz < 4)
return NULL;
raw = grub_malloc (sz - 4);
if (!raw)
return NULL;
if (grub_udf_read_file (node, NULL, 4, sz - 4, (char *) raw) < 0)
return NULL;
ret = read_string (raw, sz - 4);
grub_free (raw);
return ret;
}
static grub_err_t static grub_err_t
grub_udf_dir (grub_device_t device, const char *path, grub_udf_dir (grub_device_t device, const char *path,
int (*hook) (const char *filename, int (*hook) (const char *filename,
@ -930,8 +952,36 @@ grub_udf_dir (grub_device_t device, const char *path,
grub_fshelp_node_t node) grub_fshelp_node_t node)
{ {
struct grub_dirhook_info info; struct grub_dirhook_info info;
const struct grub_udf_timestamp *tstamp = NULL;
grub_memset (&info, 0, sizeof (info)); grub_memset (&info, 0, sizeof (info));
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
if (U16 (node->fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_FE)
tstamp = &node->fe.modification_time;
else if (U16 (node->fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_EFE)
tstamp = &node->efe.modification_time;
if (tstamp && (U16 (tstamp->type_and_timezone) & 0xf000) == 0x1000)
{
grub_int16_t tz;
struct grub_datetime datetime;
datetime.year = U16 (tstamp->year);
datetime.month = tstamp->month;
datetime.day = tstamp->day;
datetime.hour = tstamp->hour;
datetime.minute = tstamp->minute;
datetime.second = tstamp->second;
tz = U16 (tstamp->type_and_timezone) & 0xfff;
if (tz & 0x800)
tz |= 0xf000;
if (tz == -2047)
tz = 0;
info.mtimeset = !!grub_datetime2unixtime (&datetime, &info.mtime);
info.mtime -= 60 * tz;
}
grub_free (node); grub_free (node);
return hook (filename, &info); return hook (filename, &info);
} }
@ -947,7 +997,8 @@ grub_udf_dir (grub_device_t device, const char *path,
if (grub_fshelp_find_file (path, &rootnode, if (grub_fshelp_find_file (path, &rootnode,
&foundnode, &foundnode,
grub_udf_iterate_dir, 0, GRUB_FSHELP_DIR)) grub_udf_iterate_dir, grub_ufs_read_symlink,
GRUB_FSHELP_DIR))
goto fail; goto fail;
grub_udf_iterate_dir (foundnode, iterate); grub_udf_iterate_dir (foundnode, iterate);
@ -981,7 +1032,8 @@ grub_udf_open (struct grub_file *file, const char *name)
if (grub_fshelp_find_file (name, &rootnode, if (grub_fshelp_find_file (name, &rootnode,
&foundnode, &foundnode,
grub_udf_iterate_dir, 0, GRUB_FSHELP_REG)) grub_udf_iterate_dir, grub_ufs_read_symlink,
GRUB_FSHELP_REG))
goto fail; goto fail;
file->data = foundnode; file->data = foundnode;

View file

@ -100,13 +100,22 @@ struct grub_xfs_btree_root
grub_uint64_t keys[1]; grub_uint64_t keys[1];
} __attribute__ ((packed)); } __attribute__ ((packed));
struct grub_xfs_time
{
grub_uint32_t sec;
grub_uint32_t nanosec;
} __attribute__ ((packed));
struct grub_xfs_inode struct grub_xfs_inode
{ {
grub_uint8_t magic[2]; grub_uint8_t magic[2];
grub_uint16_t mode; grub_uint16_t mode;
grub_uint8_t version; grub_uint8_t version;
grub_uint8_t format; grub_uint8_t format;
grub_uint8_t unused2[50]; grub_uint8_t unused2[26];
struct grub_xfs_time atime;
struct grub_xfs_time mtime;
struct grub_xfs_time ctime;
grub_uint64_t size; grub_uint64_t size;
grub_uint64_t nblocks; grub_uint64_t nblocks;
grub_uint32_t extsize; grub_uint32_t extsize;
@ -654,6 +663,11 @@ grub_xfs_dir (grub_device_t device, const char *path,
{ {
struct grub_dirhook_info info; struct grub_dirhook_info info;
grub_memset (&info, 0, sizeof (info)); grub_memset (&info, 0, sizeof (info));
if (node->inode_read)
{
info.mtimeset = 1;
info.mtime = grub_be_to_cpu32 (node->inode.mtime.sec);
}
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
grub_free (node); grub_free (node);
return hook (filename, &info); return hook (filename, &info);

View file

@ -39,7 +39,7 @@ struct grub_amiga_rdsk
grub_uint32_t partitionlst; grub_uint32_t partitionlst;
grub_uint32_t fslst; grub_uint32_t fslst;
/* The other information is not important for us. */ grub_uint32_t unused[128 - 9];
} __attribute__ ((packed)); } __attribute__ ((packed));
struct grub_amiga_partition struct grub_amiga_partition
@ -67,12 +67,24 @@ struct grub_amiga_partition
grub_uint32_t highcyl; grub_uint32_t highcyl;
grub_uint32_t firstcyl; grub_uint32_t firstcyl;
grub_uint32_t unused[128 - 44];
} __attribute__ ((packed)); } __attribute__ ((packed));
static struct grub_partition_map grub_amiga_partition_map; static struct grub_partition_map grub_amiga_partition_map;
static grub_uint32_t
amiga_partition_map_checksum (void *buf, grub_size_t sz)
{
grub_uint32_t *ptr = buf;
grub_uint32_t r = 0;
sz /= sizeof (grub_uint32_t);
for (; sz; sz--, ptr++)
r += grub_be_to_cpu32 (*ptr);
return r;
}
static grub_err_t static grub_err_t
amiga_partition_map_iterate (grub_disk_t disk, amiga_partition_map_iterate (grub_disk_t disk,
int (*hook) (grub_disk_t disk, int (*hook) (grub_disk_t disk,
@ -92,7 +104,8 @@ amiga_partition_map_iterate (grub_disk_t disk,
return grub_errno; return grub_errno;
if (grub_memcmp (rdsk.magic, GRUB_AMIGA_RDSK_MAGIC, if (grub_memcmp (rdsk.magic, GRUB_AMIGA_RDSK_MAGIC,
sizeof (rdsk.magic)) == 0) sizeof (rdsk.magic)) == 0
&& amiga_partition_map_checksum (&rdsk, sizeof (rdsk)) == 0)
{ {
/* Found the first PART block. */ /* Found the first PART block. */
next = grub_be_to_cpu32 (rdsk.partitionlst); next = grub_be_to_cpu32 (rdsk.partitionlst);
@ -114,7 +127,8 @@ amiga_partition_map_iterate (grub_disk_t disk,
return grub_errno; return grub_errno;
if (grub_memcmp (apart.magic, GRUB_AMIGA_PART_MAGIC, if (grub_memcmp (apart.magic, GRUB_AMIGA_PART_MAGIC,
sizeof (apart.magic)) != 0) sizeof (apart.magic)) != 0
|| amiga_partition_map_checksum (&apart, sizeof (apart)) != 0)
return grub_error (GRUB_ERR_BAD_PART_TABLE, return grub_error (GRUB_ERR_BAD_PART_TABLE,
"invalid Amiga partition map"); "invalid Amiga partition map");
/* Calculate the first block and the size of the partition. */ /* Calculate the first block and the size of the partition. */

View file

@ -51,5 +51,78 @@ char *grub_get_weekday_name (struct grub_datetime *datetime);
void grub_unixtime2datetime (grub_int32_t nix, void grub_unixtime2datetime (grub_int32_t nix,
struct grub_datetime *datetime); struct grub_datetime *datetime);
static inline int
grub_datetime2unixtime (const struct grub_datetime *datetime, grub_int32_t *nix)
{
grub_int32_t ret;
int y4, ay;
const grub_uint16_t monthssum[12]
= { 0,
31,
31 + 28,
31 + 28 + 31,
31 + 28 + 31 + 30,
31 + 28 + 31 + 30 + 31,
31 + 28 + 31 + 30 + 31 + 30,
31 + 28 + 31 + 30 + 31 + 30 + 31,
31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30};
const grub_uint8_t months[12] = {31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31};
const int SECPERMIN = 60;
const int SECPERHOUR = 60 * SECPERMIN;
const int SECPERDAY = 24 * SECPERHOUR;
const int SECPERYEAR = 365 * SECPERDAY;
const int SECPER4YEARS = 4 * SECPERYEAR + SECPERDAY;
if (datetime->year > 2038 || datetime->year < 1901)
return 0;
if (datetime->month > 12 || datetime->month < 1)
return 0;
/* In the period of validity of unixtime all years divisible by 4
are bissextile*/
/* Convenience: let's have 3 consecutive non-bissextile years
at the beginning of the epoch. So count from 1971 instead of 1970 */
ret = SECPERYEAR + SECPERDAY;
/* Transform C divisions and modulos to mathematical ones */
y4 = (datetime->year - 1971) / 4;
if (datetime->year < 1971)
y4--;
ay = datetime->year - 1971 - 4 * y4;
ret += y4 * SECPER4YEARS;
ret += ay * SECPERYEAR;
ret += monthssum[datetime->month - 1] * SECPERDAY;
if (ay == 0 && datetime->month >= 3)
ret += SECPERDAY;
ret += (datetime->day - 1) * SECPERDAY;
if ((datetime->day > months[datetime->month - 1]
&& (!ay || datetime->month != 2 || datetime->day != 29))
|| datetime->day < 1)
return 0;
ret += datetime->hour * SECPERHOUR;
if (datetime->hour > 23)
return 0;
ret += datetime->minute * 60;
if (datetime->minute > 59)
return 0;
ret += datetime->second;
/* Accept leap seconds. */
if (datetime->second > 60)
return 0;
if ((datetime->year > 1980 && ret < 0)
|| (datetime->year < 1960 && ret > 0))
return 0;
*nix = ret;
return 1;
}
#endif /* ! KERNEL_DATETIME_HEADER */ #endif /* ! KERNEL_DATETIME_HEADER */

View file

@ -39,7 +39,9 @@ typedef struct grub_hfs_extent grub_hfs_datarecord_t[3];
struct grub_hfs_sblock struct grub_hfs_sblock
{ {
grub_uint16_t magic; grub_uint16_t magic;
grub_uint8_t unused[18]; grub_uint32_t ctime;
grub_uint32_t mtime;
grub_uint8_t unused[10];
grub_uint32_t blksz; grub_uint32_t blksz;
grub_uint8_t unused2[4]; grub_uint8_t unused2[4];
grub_uint16_t first_block; grub_uint16_t first_block;

View file

@ -135,6 +135,7 @@ struct grub_fshelp_node
struct grub_ntfs_data *data; struct grub_ntfs_data *data;
char *buf; char *buf;
grub_uint64_t size; grub_uint64_t size;
grub_uint64_t mtime;
grub_uint32_t ino; grub_uint32_t ino;
int inode_read; int inode_read;
struct grub_ntfs_attr attr; struct grub_ntfs_attr attr;