file mtime support for iso9660

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-12-10 11:12:59 +01:00
parent a2de6bf6ed
commit c50d99c5e5

View file

@ -54,6 +54,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
{ {
@ -63,7 +74,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;
@ -145,6 +156,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;
@ -188,14 +200,14 @@ grub_datetime2unixtime (const struct grub_datetime *datetime, grub_int32_t *nix)
/* In the period of validity of unixtime all years divisible by 4 /* In the period of validity of unixtime all years divisible by 4
are bissextile*/ are bissextile*/
/* Convenience: let's have 3 consecutive non-bissextile years /* Convenience: let's have 3 consecutive non-bissextile years
at the beginning of the epoch. So count from 1973 instead of 1970 */ at the beginning of the epoch. So count from 1971 instead of 1970 */
ret = 3*SECPERYEAR + SECPERDAY; ret = SECPERYEAR + SECPERDAY;
/* Transform C divisions and modulos to mathematical ones */ /* Transform C divisions and modulos to mathematical ones */
y4 = (datetime->year - 1973) / 4; y4 = (datetime->year - 1971) / 4;
if (datetime->year < 1973) if (datetime->year < 1971)
y4--; y4--;
ay = datetime->year - 1973 - 4 * y4; ay = datetime->year - 1971 - 4 * y4;
ret += y4 * SECPER4YEARS; ret += y4 * SECPER4YEARS;
ret += ay * SECPERYEAR; ret += ay * SECPERYEAR;
@ -256,6 +268,24 @@ iso9660_to_unixtime (const struct grub_iso9660_date *i, grub_int32_t *nix)
return err; return err;
} }
static grub_err_t
iso9660_to_unixtime2 (const struct grub_iso9660_date2 *i, grub_int32_t *nix)
{
grub_err_t err;
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;
err = grub_datetime2unixtime (&datetime, nix);
*nix -= i->offset * 60 * 15;
return err;
}
/* 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. */
@ -467,7 +497,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;
@ -545,13 +574,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)
@ -748,6 +774,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)
@ -784,8 +811,15 @@ grub_iso9660_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;
grub_err_t err;
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);
err = iso9660_to_unixtime2 (&node->dirent.mtime, &info.mtime);
if (err)
grub_errno = GRUB_ERR_NONE;
else
info.mtimeset = 1;
grub_free (node); grub_free (node);
return hook (filename, &info); return hook (filename, &info);
} }