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

@ -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);
}