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>
ROMFS support.

View file

@ -52,12 +52,20 @@ struct grub_affs_rblock
grub_uint32_t hashtable[1];
} __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. */
struct grub_affs_file
{
grub_uint8_t unused1[12];
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 name[30];
grub_uint8_t unused3[33];
@ -87,9 +95,9 @@ struct grub_affs_file
struct grub_fshelp_node
{
struct grub_affs_data *data;
int block;
int size;
int parent;
grub_disk_addr_t block;
struct grub_fshelp_node *parent;
struct grub_affs_file di;
};
/* 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,
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;
int checksum = 0;
int checksumr = 0;
int blocksize = 0;
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
itself. One way to determine it is reading blocks for the
rootblock until the checksum is correct. */
checksumr = grub_be_to_cpu32 (rblock->checksum);
rblock->checksum = 0;
for (blocksize = 0; blocksize < 8; 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++)
checksum += grub_be_to_cpu32 (currblock[i]);
if (checksumr == -checksum)
if (checksum == 0)
break;
}
if (-checksum != checksumr)
if (checksum != 0)
{
grub_error (GRUB_ERR_BAD_FS, "AFFS blocksize couldn't be determined");
goto fail;
@ -243,6 +248,8 @@ grub_affs_mount (grub_disk_t disk)
data->htsize = grub_be_to_cpu32 (rblock->htsize);
data->diropen.data = data;
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);
@ -293,12 +300,15 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
struct grub_affs_data *data = dir->data;
grub_uint32_t *hashtable;
auto int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, int block,
int size, int type);
auto int NESTED_FUNC_ATTR grub_affs_create_node (const char *name,
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 size, int type)
int NESTED_FUNC_ATTR grub_affs_create_node (const char *name,
grub_disk_addr_t block,
const struct grub_affs_file *fil)
{
int type;
node = grub_malloc (sizeof (*node));
if (!node)
{
@ -306,10 +316,19 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
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->size = size;
node->block = block;
node->parent = grub_be_to_cpu32 (file.parent);
node->di = *fil;
node->parent = dir;
if (hook (name, type, node))
{
@ -319,6 +338,24 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
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));
if (!hashtable)
return 1;
@ -328,16 +365,8 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
if (grub_errno)
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++)
{
enum grub_fshelp_filetype type;
grub_uint64_t next;
if (!hashtable[i])
@ -358,17 +387,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
file.name[file.namelen] = '\0';
if ((int) grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_DIR)
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))
if (grub_affs_create_node ((char *) (file.name), next, &file))
return 1;
next = grub_be_to_cpu32 (file.next);
@ -403,7 +422,7 @@ grub_affs_open (struct grub_file *file, const char *name)
if (grub_errno)
goto fail;
file->size = fdiro->size;
file->size = grub_be_to_cpu32 (fdiro->di.size);
data->diropen = *fdiro;
grub_free (fdiro);
@ -467,6 +486,11 @@ grub_affs_dir (grub_device_t device, const char *path,
struct grub_dirhook_info info;
grub_memset (&info, 0, sizeof (info));
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);
return hook (filename, &info);
}

View file

@ -80,7 +80,7 @@ static grub_dl_t my_mod;
static grub_err_t
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
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");
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)
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;
*ofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) &
~(GRUB_DISK_SECTOR_SIZE - 1));
if (mtime)
*mtime = grub_strtoul (hd.mtime, NULL, 8);
#endif
return GRUB_ERR_NONE;
}
@ -206,7 +210,9 @@ grub_cpio_dir (grub_device_t device, const char *path,
data->hofs = 0;
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;
if (!ofs)
@ -229,6 +235,8 @@ grub_cpio_dir (grub_device_t device, const char *path,
struct grub_dirhook_info info;
grub_memset (&info, 0, sizeof (info));
info.dir = (p != NULL);
info.mtime = mtime;
info.mtimeset = 1;
hook (name + len, &info);
if (prev)
@ -271,7 +279,7 @@ grub_cpio_open (grub_file_t file, const char *name)
data->hofs = 0;
while (1)
{
if (grub_cpio_find_file (data, &fn, &ofs))
if (grub_cpio_find_file (data, &fn, NULL, &ofs))
goto fail;
if (!ofs)

View file

@ -133,6 +133,8 @@ struct grub_hfs_dirrec
grub_uint8_t type;
grub_uint8_t unused[5];
grub_uint32_t dirid;
grub_uint32_t ctime;
grub_uint32_t mtime;
} __attribute__ ((packed));
/* Information about a file. */
@ -144,7 +146,9 @@ struct grub_hfs_filerec
grub_uint32_t fileid;
grub_uint8_t unused2[2];
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
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)
{
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_dirhook_info info;
grub_memset (&info, 0, sizeof (info));
grub_strncpy (fname, (char *) (ckey->str), ckey->strlen);
if (*filetype == GRUB_HFS_FILETYPE_DIR
|| *filetype == GRUB_HFS_FILETYPE_FILE)
if (drec->type == GRUB_HFS_FILETYPE_DIR)
{
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);
}
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;
}
@ -1074,6 +1088,22 @@ grub_hfs_label (grub_device_t device, char **label)
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
grub_hfs_uuid (grub_device_t device, char **uuid)
{
@ -1109,6 +1139,7 @@ static struct grub_fs grub_hfs_fs =
.close = grub_hfs_close,
.label = grub_hfs_label,
.uuid = grub_hfs_uuid,
.mtime = grub_hfs_mtime,
.next = 0
};

View file

@ -27,6 +27,7 @@
#include <grub/types.h>
#include <grub/fshelp.h>
#include <grub/charset.h>
#include <grub/datetime.h>
GRUB_MOD_LICENSE ("GPLv3+");
@ -55,6 +56,17 @@ struct grub_iso9660_voldesc
grub_uint8_t version;
} __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. */
struct grub_iso9660_dir
{
@ -64,7 +76,7 @@ struct grub_iso9660_dir
grub_uint32_t first_sector_be;
grub_uint32_t size;
grub_uint32_t size_be;
grub_uint8_t unused1[7];
struct grub_iso9660_date2 mtime;
grub_uint8_t flags;
grub_uint8_t unused2[6];
grub_uint8_t namelen;
@ -146,6 +158,7 @@ struct grub_iso9660_data
struct grub_fshelp_node
{
struct grub_iso9660_data *data;
struct grub_iso9660_dir dirent;
unsigned int size;
unsigned int blk;
unsigned int dir_blk;
@ -155,6 +168,52 @@ struct grub_fshelp_node
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
offset SUA_POS with a size of SUA_SIZE bytes. Hook is called for
every entry. */
@ -366,7 +425,6 @@ grub_iso9660_mount (grub_disk_t disk)
static char *
grub_iso9660_read_symlink (grub_fshelp_node_t node)
{
struct grub_iso9660_dir dirent;
int sua_off;
int sua_size;
char *symlink = 0;
@ -444,13 +502,10 @@ grub_iso9660_read_symlink (grub_fshelp_node_t node)
return 0;
}
if (grub_disk_read (node->data->disk, node->dir_blk, node->dir_off,
sizeof (dirent), (char *) &dirent))
return 0;
sua_off = (sizeof (dirent) + dirent.namelen + 1 - (dirent.namelen % 2)
sua_off = (sizeof (node->dirent) + node->dirent.namelen + 1
- (node->dirent.namelen % 2)
+ node->data->susp_skip);
sua_size = dirent.len - sua_off;
sua_size = node->dirent.len - sua_off;
symlink = grub_malloc (1);
if (!symlink)
@ -647,6 +702,7 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
filename_alloc = 1;
}
node->dirent = dirent;
if (hook (filename, type, node))
{
if (filename_alloc)
@ -685,6 +741,8 @@ grub_iso9660_dir (grub_device_t device, const char *path,
struct grub_dirhook_info info;
grub_memset (&info, 0, sizeof (info));
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
info.mtimeset = !!iso9660_to_unixtime2 (&node->dirent.mtime, &info.mtime);
grub_free (node);
return hook (filename, &info);
}
@ -882,6 +940,32 @@ grub_iso9660_uuid (grub_device_t device, char **uuid)
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 =
@ -893,6 +977,7 @@ static struct grub_fs grub_iso9660_fs =
.close = grub_iso9660_close,
.label = grub_iso9660_label,
.uuid = grub_iso9660_uuid,
.mtime = grub_iso9660_mtime,
.next = 0
};

View file

@ -155,6 +155,12 @@ struct grub_jfs_leaf_next_dirent
grub_uint16_t namepart[15];
} __attribute__ ((packed));
struct grub_jfs_time
{
grub_int32_t sec;
grub_int32_t nanosec;
} __attribute__ ((packed));
struct grub_jfs_inode
{
grub_uint32_t stamp;
@ -164,7 +170,10 @@ struct grub_jfs_inode
grub_uint64_t size;
grub_uint8_t unused2[20];
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];
union
@ -760,6 +769,8 @@ grub_jfs_dir (grub_device_t device, const char *path,
info.dir = (grub_le_to_cpu32 (inode.mode)
& 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))
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));
info.dir = ((GRUB_MINIX_INODE_MODE (data)
& 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)
break;

View file

@ -612,6 +612,10 @@ list_file (struct grub_ntfs_file *diro, char *pos,
fdiro->data = diro->data;
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);
if (ustr == NULL)
@ -882,6 +886,10 @@ grub_ntfs_dir (grub_device_t device, const char *path,
struct grub_dirhook_info info;
grub_memset (&info, 0, sizeof (info));
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);
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_uint16_t block_position;
grub_uint64_t next_offset;
grub_int32_t mtime;
enum grub_reiserfs_item_type type; /* To know how to read the 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.first_direct_byte);
#endif
entry_item->mtime = grub_le_to_cpu32 (entry_v1_stat.mtime);
if ((grub_le_to_cpu16 (entry_v1_stat.mode) & S_IFLNK)
== S_IFLNK)
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.first_direct_byte);
#endif
entry_item->mtime = grub_le_to_cpu32 (entry_v2_stat.mtime);
if ((grub_le_to_cpu16 (entry_v2_stat.mode) & S_IFLNK)
== S_IFLNK)
entry_type = GRUB_FSHELP_SYMLINK;
@ -1278,6 +1281,8 @@ grub_reiserfs_dir (grub_device_t device, const char *path,
struct grub_dirhook_info info;
grub_memset (&info, 0, sizeof (info));
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
info.mtimeset = 1;
info.mtime = node->mtime;
grub_free (node);
return hook (filename, &info);
}

View file

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

View file

@ -26,6 +26,7 @@
#include <grub/types.h>
#include <grub/fshelp.h>
#include <grub/charset.h>
#include <grub/datetime.h>
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) ?
(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,
dirent.file_ident_length,
@ -912,6 +915,25 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
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
grub_udf_dir (grub_device_t device, const char *path,
int (*hook) (const char *filename,
@ -930,8 +952,36 @@ grub_udf_dir (grub_device_t device, const char *path,
grub_fshelp_node_t node)
{
struct grub_dirhook_info info;
const struct grub_udf_timestamp *tstamp = NULL;
grub_memset (&info, 0, sizeof (info));
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);
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,
&foundnode,
grub_udf_iterate_dir, 0, GRUB_FSHELP_DIR))
grub_udf_iterate_dir, grub_ufs_read_symlink,
GRUB_FSHELP_DIR))
goto fail;
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,
&foundnode,
grub_udf_iterate_dir, 0, GRUB_FSHELP_REG))
grub_udf_iterate_dir, grub_ufs_read_symlink,
GRUB_FSHELP_REG))
goto fail;
file->data = foundnode;

View file

@ -100,13 +100,22 @@ struct grub_xfs_btree_root
grub_uint64_t keys[1];
} __attribute__ ((packed));
struct grub_xfs_time
{
grub_uint32_t sec;
grub_uint32_t nanosec;
} __attribute__ ((packed));
struct grub_xfs_inode
{
grub_uint8_t magic[2];
grub_uint16_t mode;
grub_uint8_t version;
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 nblocks;
grub_uint32_t extsize;
@ -654,6 +663,11 @@ grub_xfs_dir (grub_device_t device, const char *path,
{
struct grub_dirhook_info 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);
grub_free (node);
return hook (filename, &info);

View file

@ -39,7 +39,7 @@ struct grub_amiga_rdsk
grub_uint32_t partitionlst;
grub_uint32_t fslst;
/* The other information is not important for us. */
grub_uint32_t unused[128 - 9];
} __attribute__ ((packed));
struct grub_amiga_partition
@ -67,12 +67,24 @@ struct grub_amiga_partition
grub_uint32_t highcyl;
grub_uint32_t firstcyl;
grub_uint32_t unused[128 - 44];
} __attribute__ ((packed));
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
amiga_partition_map_iterate (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;
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. */
next = grub_be_to_cpu32 (rdsk.partitionlst);
@ -114,7 +127,8 @@ amiga_partition_map_iterate (grub_disk_t disk,
return grub_errno;
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,
"invalid Amiga partition map");
/* 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,
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 */

View file

@ -39,7 +39,9 @@ typedef struct grub_hfs_extent grub_hfs_datarecord_t[3];
struct grub_hfs_sblock
{
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_uint8_t unused2[4];
grub_uint16_t first_block;

View file

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