Rename some functions to be more like POSIX file reading, i.e. add

udf_opendir() and udf_readdir(). udf_file_entry_t -> udf_dirent_t.
This commit is contained in:
rocky
2005-11-01 03:14:49 +00:00
parent c68faa94c1
commit 7de9d148bf
10 changed files with 181 additions and 170 deletions

View File

@@ -1,5 +1,5 @@
/* /*
$Id: udf1.c,v 1.13 2005/10/30 16:04:11 rocky Exp $ $Id: udf1.c,v 1.14 2005/11/01 03:14:49 rocky Exp $
Copyright (C) 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2005 Rocky Bernstein <rocky@panix.com>
@@ -51,47 +51,46 @@
#define udf_PATH_DELIMITERS "/\\" #define udf_PATH_DELIMITERS "/\\"
static void static void
print_file_info(const udf_file_t *p_udf_file, const char* psz_dirname) print_file_info(const udf_dirent_t *p_udf_dirent, const char* psz_dirname)
{ {
time_t mod_time = udf_get_modification_time(p_udf_file); time_t mod_time = udf_get_modification_time(p_udf_dirent);
char psz_mode[11]="invalid"; char psz_mode[11]="invalid";
const char *psz_fname= psz_dirname const char *psz_fname= psz_dirname
? psz_dirname : udf_get_filename(p_udf_file); ? psz_dirname : udf_get_filename(p_udf_dirent);
/* Print directory attributes*/ /* Print directory attributes*/
printf("%s ", udf_mode_string(udf_get_posix_filemode(p_udf_file), printf("%s ", udf_mode_string(udf_get_posix_filemode(p_udf_dirent),
psz_mode)); psz_mode));
printf("%4d ", udf_get_link_count(p_udf_file)); printf("%4d ", udf_get_link_count(p_udf_dirent));
printf("%s %s", *psz_fname ? psz_fname : "/", ctime(&mod_time)); printf("%s %s", *psz_fname ? psz_fname : "/", ctime(&mod_time));
} }
static udf_file_t * static udf_dirent_t *
list_files(const udf_t *p_udf, udf_file_t *p_udf_file, const char *psz_path) list_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const char *psz_path)
{ {
if (!p_udf_file) return NULL; if (!p_udf_dirent) return NULL;
print_file_info(p_udf_file, psz_path); print_file_info(p_udf_dirent, psz_path);
while (udf_get_next(p_udf, p_udf_file)) { while (udf_readdir(p_udf_dirent)) {
if (udf_is_dir(p_udf_file)) { if (udf_is_dir(p_udf_dirent)) {
udf_file_t *p_udf_file2 = udf_get_sub(p_udf, p_udf_file); udf_dirent_t *p_udf_dirent2 = udf_opendir(p_udf, p_udf_dirent);
if (p_udf_file2) { if (p_udf_dirent2) {
const char *psz_dirname = udf_get_filename(p_udf_file); const char *psz_dirname = udf_get_filename(p_udf_dirent);
const unsigned int i_newlen=2 + strlen(psz_path) + strlen(psz_dirname); const unsigned int i_newlen=2 + strlen(psz_path) + strlen(psz_dirname);
char *psz_newpath = calloc(1, sizeof(char)*i_newlen); char *psz_newpath = calloc(1, sizeof(char)*i_newlen);
snprintf(psz_newpath, i_newlen, "%s%s/", psz_path, psz_dirname); snprintf(psz_newpath, i_newlen, "%s%s/", psz_path, psz_dirname);
list_files(p_udf, p_udf_file2, psz_newpath); list_files(p_udf, p_udf_dirent2, psz_newpath);
free(psz_newpath); free(psz_newpath);
udf_file_free(p_udf_file2);
} }
} else { } else {
print_file_info(p_udf_file, NULL); print_file_info(p_udf_dirent, NULL);
} }
} }
return p_udf_file; return p_udf_dirent;
} }
int int
@@ -112,8 +111,8 @@ main(int argc, const char *argv[])
psz_fname); psz_fname);
return 1; return 1;
} else { } else {
udf_file_t *p_udf_file = udf_get_root(p_udf, true, 0); udf_dirent_t *p_udf_dirent = udf_get_root(p_udf, true, 0);
if (NULL == p_udf_file) { if (NULL == p_udf_dirent) {
fprintf(stderr, "Sorry, couldn't find / in %s\n", fprintf(stderr, "Sorry, couldn't find / in %s\n",
psz_fname); psz_fname);
return 1; return 1;
@@ -136,8 +135,7 @@ main(int argc, const char *argv[])
} }
list_files(p_udf, p_udf_file, ""); list_files(p_udf, p_udf_dirent, "");
udf_file_free(p_udf_file);
} }
udf_close(p_udf); udf_close(p_udf);

View File

@@ -1,5 +1,5 @@
/* /*
$Id: udf.h,v 1.15 2005/10/30 07:35:37 rocky Exp $ $Id: udf.h,v 1.16 2005/11/01 03:14:49 rocky Exp $
Copyright (C) 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2005 Rocky Bernstein <rocky@panix.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
@@ -43,6 +43,7 @@ typedef uint8_t ubyte;
/** Opaque structures. */ /** Opaque structures. */
typedef struct udf_s udf_t; typedef struct udf_s udf_t;
typedef struct udf_file_s udf_file_t; typedef struct udf_file_s udf_file_t;
typedef struct udf_dirent_s udf_dirent_t;
/** /**
Imagine the below a #define'd value rather than distinct values of Imagine the below a #define'd value rather than distinct values of
@@ -98,8 +99,8 @@ extern "C" {
Caller must free result - use udf_file_free for that. Caller must free result - use udf_file_free for that.
*/ */
udf_file_t *udf_get_root (udf_t *p_udf, bool b_any_partition, udf_dirent_t *udf_get_root (udf_t *p_udf, bool b_any_partition,
partition_num_t i_partition); partition_num_t i_partition);
/** /**
* Gets the Volume Identifier string, in 8bit unicode (latin-1) * Gets the Volume Identifier string, in 8bit unicode (latin-1)
@@ -126,9 +127,9 @@ extern "C" {
Return a file pointer matching pzz_name. If b_any_partition is false then Return a file pointer matching pzz_name. If b_any_partition is false then
the root must be in the given partition. the root must be in the given partition.
*/ */
udf_file_t *udf_find_file(udf_t *p_udf, const char *psz_name, udf_dirent_t *udf_find_file(udf_t *p_udf, const char *psz_name,
bool b_any_partition, bool b_any_partition,
partition_num_t i_partition); partition_num_t i_partition);
/*! udf_mode_string - fill in string PSZ_STR with an ls-style ASCII /*! udf_mode_string - fill in string PSZ_STR with an ls-style ASCII
representation of the i_mode. PSZ_STR is returned. representation of the i_mode. PSZ_STR is returned.

View File

@@ -1,5 +1,5 @@
/* /*
$Id: udf_file.h,v 1.1 2005/10/30 07:36:15 rocky Exp $ $Id: udf_file.h,v 1.2 2005/11/01 03:14:50 rocky Exp $
Copyright (C) 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2005 Rocky Bernstein <rocky@panix.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
@@ -34,49 +34,54 @@ extern "C" {
/*! /*!
Return the file id descriptor of the given file. Return the file id descriptor of the given file.
*/ */
bool udf_get_fileid_descriptor(const udf_file_t *p_udf_file, bool udf_get_fileid_descriptor(const udf_dirent_t *p_udf_dirent,
/*out*/ udf_fileid_desc_t *p_udf_fid); /*out*/ udf_fileid_desc_t *p_udf_fid);
/*! /*!
Return the name of the file Return the name of the file
*/ */
const char *udf_get_filename(const udf_file_t *p_udf_file); const char *udf_get_filename(const udf_dirent_t *p_udf_dirent);
/*! /*!
Return the name of the file Return the name of the file
*/ */
bool udf_get_file_entry(const udf_file_t *p_udf_file, bool udf_get_file_entry(const udf_dirent_t *p_udf_dirent,
/*out*/ udf_file_entry_t *p_udf_fe); /*out*/ udf_file_entry_t *p_udf_fe);
/*! /*!
Return the number of hard links of the file. Return 0 if error. Return the number of hard links of the file. Return 0 if error.
*/ */
uint16_t udf_get_link_count(const udf_file_t *p_udf_file); uint16_t udf_get_link_count(const udf_dirent_t *p_udf_dirent);
/*! /*!
Returns a POSIX mode for a given p_udf_file. Returns a POSIX mode for a given p_udf_dirent.
*/ */
mode_t udf_get_posix_filemode(const udf_file_t *p_udf_file); mode_t udf_get_posix_filemode(const udf_dirent_t *p_udf_dirent);
/*! /*!
Return the next subdirectory. Return the next subdirectory.
*/ */
udf_file_t *udf_get_sub(const udf_t *p_udf, const udf_file_t *p_udf_file); udf_dirent_t *udf_opendir(udf_t *p_udf, const udf_dirent_t *p_udf_dirent);
/*! /*!
Return the next file. Advances p_udf_direct to the the next directory entry in the
pointed to by p_udf_dir. It also returns this as the value. NULL
is returned on reaching the end-of-file or if an error. Also
p_udf_dirent is free'd. If the end of is not reached the caller
must call udf_dirent_free() with p_udf_dirent when done with it to
release resources.
*/ */
udf_file_t *udf_get_next(const udf_t *p_udf, udf_file_t *p_udf_file); udf_dirent_t *udf_readdir(udf_dirent_t *p_udf_dirent);
/*! /*!
free free resources associated with p_udf_file. free free resources associated with p_udf_dirent.
*/ */
bool udf_file_free(udf_file_t *p_udf_file); bool udf_dirent_free(udf_dirent_t *p_udf_dirent);
/*! /*!
Return true if the file is a directory. Return true if the file is a directory.
*/ */
bool udf_is_dir(const udf_file_t *p_udf_file); bool udf_is_dir(const udf_dirent_t *p_udf_dirent);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -1,5 +1,5 @@
/* /*
$Id: udf_time.h,v 1.3 2005/10/30 14:10:44 rocky Exp $ $Id: udf_time.h,v 1.4 2005/11/01 03:14:50 rocky Exp $
Copyright (C) 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2005 Rocky Bernstein <rocky@panix.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
@@ -36,33 +36,33 @@ extern "C" {
/*! /*!
Return the access time of the file. Return the access time of the file.
*/ */
time_t udf_get_access_time(const udf_file_t *p_udf_file); time_t udf_get_access_time(const udf_dirent_t *p_udf_dirent);
/*! /*!
Return the attribute (most recent create or access) time of the file Return the attribute (most recent create or access) time of the file
*/ */
time_t udf_get_attribute_time(const udf_file_t *p_udf_file); time_t udf_get_attribute_time(const udf_dirent_t *p_udf_dirent);
/*! /*!
Return the modification time of the file. Return the modification time of the file.
*/ */
time_t udf_get_modification_time(const udf_file_t *p_udf_file); time_t udf_get_modification_time(const udf_dirent_t *p_udf_dirent);
/*! /*!
Return the access timestamp of the file Return the access timestamp of the file
*/ */
udf_timestamp_t *udf_get_access_timestamp(const udf_file_t *p_udf_file); udf_timestamp_t *udf_get_access_timestamp(const udf_dirent_t *p_udf_dirent);
/*! /*!
Return the modification timestamp of the file Return the modification timestamp of the file
*/ */
udf_timestamp_t *udf_get_modification_timestamp(const udf_file_t udf_timestamp_t *udf_get_modification_timestamp(const udf_dirent_t
*p_udf_file); *p_udf_dirent);
/*! /*!
Return the attr timestamp of the file Return the attr timestamp of the file
*/ */
udf_timestamp_t *udf_get_attr_timestamp(const udf_file_t *p_udf_file); udf_timestamp_t *udf_get_attr_timestamp(const udf_dirent_t *p_udf_dirent);
/*! /*!
Convert a UDF timestamp to a time_t. If microseconds are desired, Convert a UDF timestamp to a time_t. If microseconds are desired,

View File

@@ -12,15 +12,15 @@ VSD_STD_ID_CDW01
VSD_STD_ID_NSR03 VSD_STD_ID_NSR03
VSD_STD_ID_TEA01 VSD_STD_ID_TEA01
udf_close udf_close
udf_file_free udf_dirent_free
udf_get_file_entry udf_get_file_entry
udf_get_fileid_descriptor udf_get_fileid_descriptor
udf_get_filename udf_get_filename
udf_get_link_count udf_get_link_count
udf_get_part_number udf_get_part_number
udf_get_posix_filemode udf_get_posix_filemode
udf_get_next udf_opendir
udf_get_sub udf_readdir
udf_is_dir udf_is_dir
udf_open udf_open
udf_read_sectors udf_read_sectors

View File

@@ -1,5 +1,5 @@
/* /*
$Id: udf.c,v 1.7 2005/10/30 07:35:37 rocky Exp $ $Id: udf.c,v 1.8 2005/11/01 03:14:50 rocky Exp $
Copyright (C) 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2005 Rocky Bernstein <rocky@panix.com>
@@ -46,12 +46,12 @@ ecma_167_timezone_enum_t debug_ecma_167_timezone_enum;
Returns POSIX mode bitstring for a given file. Returns POSIX mode bitstring for a given file.
*/ */
mode_t mode_t
udf_get_posix_filemode(const udf_file_t *p_udf_file) udf_get_posix_filemode(const udf_dirent_t *p_udf_dirent)
{ {
udf_file_entry_t udf_fe; udf_file_entry_t udf_fe;
mode_t mode = 0; mode_t mode = 0;
if (udf_get_file_entry(p_udf_file, &udf_fe)) { if (udf_get_file_entry(p_udf_dirent, &udf_fe)) {
uint16_t i_flags; uint16_t i_flags;
uint32_t i_perms; uint32_t i_perms;

View File

@@ -1,5 +1,5 @@
/* /*
$Id: udf_file.c,v 1.1 2005/10/30 07:35:37 rocky Exp $ $Id: udf_file.c,v 1.2 2005/11/01 03:14:50 rocky Exp $
Copyright (C) 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2005 Rocky Bernstein <rocky@panix.com>
@@ -27,34 +27,34 @@
#endif #endif
const char * const char *
udf_get_filename(const udf_file_t *p_udf_file) udf_get_filename(const udf_dirent_t *p_udf_dirent)
{ {
if (!p_udf_file) return NULL; if (!p_udf_dirent) return NULL;
return p_udf_file->psz_name; return p_udf_dirent->psz_name;
} }
bool bool
udf_get_file_entry(const udf_file_t *p_udf_file, udf_get_file_entry(const udf_dirent_t *p_udf_dirent,
/*out*/ udf_file_entry_t *p_udf_fe) /*out*/ udf_file_entry_t *p_udf_fe)
{ {
if (!p_udf_file) return false; if (!p_udf_dirent) return false;
memcpy(p_udf_fe, &p_udf_file->fe, sizeof(udf_file_entry_t)); memcpy(p_udf_fe, &p_udf_dirent->fe, sizeof(udf_file_entry_t));
return true; return true;
} }
/*! /*!
Return the file id descriptor of the given file. Return the file id descriptor of the given file.
*/ */
bool udf_get_fileid_descriptor(const udf_file_t *p_udf_file, bool udf_get_fileid_descriptor(const udf_dirent_t *p_udf_dirent,
/*out*/ udf_fileid_desc_t *p_udf_fid) /*out*/ udf_fileid_desc_t *p_udf_fid)
{ {
if (!p_udf_file) return false; if (!p_udf_dirent) return false;
if (!p_udf_file->fid) { if (!p_udf_dirent->fid) {
/* FIXME do something about trying to get the descriptor. */ /* FIXME do something about trying to get the descriptor. */
return false; return false;
} }
memcpy(p_udf_fid, p_udf_file->fid, sizeof(udf_fileid_desc_t)); memcpy(p_udf_fid, p_udf_dirent->fid, sizeof(udf_fileid_desc_t));
return true; return true;
} }
@@ -62,11 +62,11 @@ bool udf_get_fileid_descriptor(const udf_file_t *p_udf_file,
/*! /*!
Return the number of hard links of the file. Return 0 if error. Return the number of hard links of the file. Return 0 if error.
*/ */
uint16_t udf_get_link_count(const udf_file_t *p_udf_file) uint16_t udf_get_link_count(const udf_dirent_t *p_udf_dirent)
{ {
if (p_udf_file) { if (p_udf_dirent) {
udf_file_entry_t udf_fe; udf_file_entry_t udf_fe;
if (udf_get_file_entry(p_udf_file, &udf_fe)) { if (udf_get_file_entry(p_udf_dirent, &udf_fe)) {
return uint16_from_le(udf_fe.link_count); return uint16_from_le(udf_fe.link_count);
} }
} }
@@ -77,7 +77,7 @@ uint16_t udf_get_link_count(const udf_file_t *p_udf_file)
Return true if the file is a directory. Return true if the file is a directory.
*/ */
bool bool
udf_is_dir(const udf_file_t *p_udf_file) udf_is_dir(const udf_dirent_t *p_udf_dirent)
{ {
return p_udf_file->b_dir; return p_udf_dirent->b_dir;
} }

View File

@@ -1,5 +1,5 @@
/* /*
$Id: udf_fs.c,v 1.9 2005/10/27 11:18:57 rocky Exp $ $Id: udf_fs.c,v 1.10 2005/11/01 03:14:50 rocky Exp $
Copyright (C) 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2005 Rocky Bernstein <rocky@panix.com>
@@ -189,24 +189,24 @@ udf_get_lba(const udf_file_entry_t *p_udf_fe,
#define udf_PATH_DELIMITERS "/\\" #define udf_PATH_DELIMITERS "/\\"
static static
udf_file_t * udf_dirent_t *
udf_ff_traverse(udf_t *p_udf, udf_file_t *p_udf_file, char *psz_token) udf_ff_traverse(udf_t *p_udf, udf_dirent_t *p_udf_dirent, char *psz_token)
{ {
while (udf_get_next(p_udf, p_udf_file)) { while (udf_readdir(p_udf_dirent)) {
if (strcmp(psz_token, p_udf_file->psz_name) == 0) { if (strcmp(psz_token, p_udf_dirent->psz_name) == 0) {
char *next_tok = strtok(NULL, udf_PATH_DELIMITERS); char *next_tok = strtok(NULL, udf_PATH_DELIMITERS);
if (!next_tok) if (!next_tok)
return p_udf_file; /* found */ return p_udf_dirent; /* found */
else if (p_udf_file->b_dir) { else if (p_udf_dirent->b_dir) {
udf_file_t * p_udf_file2 = udf_get_sub(p_udf, p_udf_file); udf_dirent_t * p_udf_dirent2 = udf_opendir(p_udf, p_udf_dirent);
if (p_udf_file2) { if (p_udf_dirent2) {
udf_file_t * p_udf_file3 = udf_dirent_t * p_udf_dirent3 =
udf_ff_traverse(p_udf, p_udf_file2, next_tok); udf_ff_traverse(p_udf, p_udf_dirent2, next_tok);
if (!p_udf_file3) udf_file_free(p_udf_file2); if (!p_udf_dirent3) udf_dirent_free(p_udf_dirent2);
return p_udf_file3; return p_udf_dirent3;
} }
} }
} }
@@ -217,24 +217,25 @@ udf_ff_traverse(udf_t *p_udf, udf_file_t *p_udf_file, char *psz_token)
/* FIXME! */ /* FIXME! */
#define udf_MAX_PATHLEN 2048 #define udf_MAX_PATHLEN 2048
udf_file_t * udf_dirent_t *
udf_find_file(udf_t *p_udf, const char *psz_name, bool b_any_partition, udf_find_file(udf_t *p_udf, const char *psz_name, bool b_any_partition,
partition_num_t i_partition) partition_num_t i_partition)
{ {
udf_file_t *p_udf_file = udf_get_root(p_udf, b_any_partition, i_partition); udf_dirent_t *p_udf_dirent =
udf_file_t *p_udf_file2 = NULL; udf_get_root(p_udf, b_any_partition, i_partition);
udf_dirent_t *p_udf_dirent2 = NULL;
if (p_udf_file) { if (p_udf_dirent) {
char tokenline[udf_MAX_PATHLEN]; char tokenline[udf_MAX_PATHLEN];
char *psz_token; char *psz_token;
strcpy(tokenline, psz_name); strcpy(tokenline, psz_name);
psz_token = strtok(tokenline, udf_PATH_DELIMITERS); psz_token = strtok(tokenline, udf_PATH_DELIMITERS);
if (psz_token) if (psz_token)
p_udf_file2 = udf_ff_traverse(p_udf, p_udf_file, psz_token); p_udf_dirent2 = udf_ff_traverse(p_udf, p_udf_dirent, psz_token);
udf_file_free(p_udf_file); udf_dirent_free(p_udf_dirent);
} }
return p_udf_file2; return p_udf_dirent2;
} }
/* Convert unicode16 to 8-bit char by dripping MSB. /* Convert unicode16 to 8-bit char by dripping MSB.
@@ -257,21 +258,24 @@ unicode16_decode( const uint8_t *data, int i_len, char *target )
} }
static udf_file_t * static udf_dirent_t *
udf_new_file(udf_file_entry_t *p_udf_fe, uint32_t i_part_start, udf_new_dirent(udf_file_entry_t *p_udf_fe, udf_t *p_udf,
const char *psz_name, bool b_dir, bool b_parent) const char *psz_name, bool b_dir, bool b_parent)
{ {
udf_file_t *p_udf_file = (udf_file_t *) calloc(1, sizeof(udf_file_t)); udf_dirent_t *p_udf_dirent =
if (!p_udf_file) return NULL; (udf_dirent_t *) calloc(1, sizeof(udf_dirent_t));
p_udf_file->psz_name = strdup(psz_name); if (!p_udf_dirent) return NULL;
p_udf_file->b_dir = b_dir; p_udf_dirent->psz_name = strdup(psz_name);
p_udf_file->b_parent = b_parent; p_udf_dirent->b_dir = b_dir;
p_udf_file->i_part_start = i_part_start; p_udf_dirent->b_parent = b_parent;
p_udf_file->dir_left = uint64_from_le(p_udf_fe->info_len); p_udf_dirent->p_udf = p_udf;
p_udf_dirent->i_part_start = p_udf->i_part_start;
p_udf_dirent->dir_left = uint64_from_le(p_udf_fe->info_len);
memcpy(&(p_udf_file->fe), p_udf_fe, sizeof(udf_file_entry_t)); memcpy(&(p_udf_dirent->fe), p_udf_fe, sizeof(udf_file_entry_t));
udf_get_lba( p_udf_fe, &(p_udf_file->dir_lba), &(p_udf_file->dir_end_lba) ); udf_get_lba( p_udf_fe, &(p_udf_dirent->dir_lba),
return p_udf_file; &(p_udf_dirent->dir_end_lba) );
return p_udf_dirent;
} }
/*! /*!
@@ -444,7 +448,7 @@ udf_get_volumeset_id(udf_t *p_udf, /*out*/ uint8_t *volsetid,
Caller must free result - use udf_file_free for that. Caller must free result - use udf_file_free for that.
*/ */
udf_file_t * udf_dirent_t *
udf_get_root (udf_t *p_udf, bool b_any_partition, partition_num_t i_partition) udf_get_root (udf_t *p_udf, bool b_any_partition, partition_num_t i_partition)
{ {
const anchor_vol_desc_ptr_t *p_avdp = &p_udf->anchor_vol_desc_ptr; const anchor_vol_desc_ptr_t *p_avdp = &p_udf->anchor_vol_desc_ptr;
@@ -514,7 +518,7 @@ udf_get_root (udf_t *p_udf, bool b_any_partition, partition_num_t i_partition)
/* Check partition numbers match of last-read block? */ /* Check partition numbers match of last-read block? */
/* We win! - Save root directory information. */ /* We win! - Save root directory information. */
return udf_new_file(p_udf_fe, p_udf->i_part_start, "/", true, false ); return udf_new_dirent(p_udf_fe, p_udf, "/", true, false );
} }
} }
} }
@@ -545,112 +549,115 @@ udf_close (udf_t *p_udf)
return true; return true;
} }
udf_file_t * udf_dirent_t *
udf_get_sub(const udf_t *p_udf, const udf_file_t *p_udf_file) udf_opendir(udf_t *p_udf, const udf_dirent_t *p_udf_dirent)
{ {
if (p_udf_file->b_dir && !p_udf_file->b_parent && p_udf_file->fid) { if (p_udf_dirent->b_dir && !p_udf_dirent->b_parent && p_udf_dirent->fid) {
uint8_t data[UDF_BLOCKSIZE]; uint8_t data[UDF_BLOCKSIZE];
udf_file_entry_t *p_udf_fe = (udf_file_entry_t *) &data; udf_file_entry_t *p_udf_fe = (udf_file_entry_t *) &data;
driver_return_code_t i_ret = driver_return_code_t i_ret =
udf_read_sectors(p_udf, p_udf_fe, p_udf->i_part_start udf_read_sectors(p_udf, p_udf_fe, p_udf->i_part_start
+ p_udf_file->fid->icb.loc.lba, 1); + p_udf_dirent->fid->icb.loc.lba, 1);
if (DRIVER_OP_SUCCESS == i_ret if (DRIVER_OP_SUCCESS == i_ret
&& !udf_checktag(&p_udf_fe->tag, TAGID_FILE_ENTRY)) { && !udf_checktag(&p_udf_fe->tag, TAGID_FILE_ENTRY)) {
if (ICBTAG_FILE_TYPE_DIRECTORY == p_udf_fe->icb_tag.file_type) { if (ICBTAG_FILE_TYPE_DIRECTORY == p_udf_fe->icb_tag.file_type) {
udf_file_t *p_udf_file_new = udf_dirent_t *p_udf_dirent_new =
udf_new_file(p_udf_fe, p_udf->i_part_start, p_udf_file->psz_name, udf_new_dirent(p_udf_fe, p_udf, p_udf_dirent->psz_name, true, true);
true, true); return p_udf_dirent_new;
return p_udf_file_new;
} }
} }
} }
return NULL; return NULL;
} }
udf_file_t * udf_dirent_t *
udf_get_next(const udf_t *p_udf, udf_file_t *p_udf_file) udf_readdir(udf_dirent_t *p_udf_dirent)
{ {
udf_t *p_udf;
if (p_udf_file->dir_left <= 0) { if (p_udf_dirent->dir_left <= 0) {
p_udf_file->fid = NULL; udf_dirent_free(p_udf_dirent);
return NULL; return NULL;
} }
if (p_udf_file->fid) { p_udf = p_udf_dirent->p_udf;
if (p_udf_dirent->fid) {
/* advance to next File Identifier Descriptor */ /* advance to next File Identifier Descriptor */
/* FIXME: need to advance file entry (fe) as well. */ /* FIXME: need to advance file entry (fe) as well. */
uint32_t ofs = 4 * uint32_t ofs = 4 *
((sizeof(*(p_udf_file->fid)) + p_udf_file->fid->i_imp_use ((sizeof(*(p_udf_dirent->fid)) + p_udf_dirent->fid->i_imp_use
+ p_udf_file->fid->i_file_id + 3) / 4); + p_udf_dirent->fid->i_file_id + 3) / 4);
p_udf_file->fid = (udf_fileid_desc_t *)((uint8_t *)p_udf_file->fid + ofs); p_udf_dirent->fid =
(udf_fileid_desc_t *)((uint8_t *)p_udf_dirent->fid + ofs);
} }
if (!p_udf_file->fid) { if (!p_udf_dirent->fid) {
uint32_t i_sectors = (p_udf_file->dir_end_lba - p_udf_file->dir_lba + 1); uint32_t i_sectors =
(p_udf_dirent->dir_end_lba - p_udf_dirent->dir_lba + 1);
uint32_t size = UDF_BLOCKSIZE * i_sectors; uint32_t size = UDF_BLOCKSIZE * i_sectors;
driver_return_code_t i_ret; driver_return_code_t i_ret;
if (!p_udf_file->sector) if (!p_udf_dirent->sector)
p_udf_file->sector = (uint8_t*) malloc(size); p_udf_dirent->sector = (uint8_t*) malloc(size);
i_ret = udf_read_sectors(p_udf, p_udf_file->sector, i_ret = udf_read_sectors(p_udf, p_udf_dirent->sector,
p_udf_file->i_part_start + p_udf_file->dir_lba, p_udf_dirent->i_part_start+p_udf_dirent->dir_lba,
i_sectors); i_sectors);
if (DRIVER_OP_SUCCESS == i_ret) if (DRIVER_OP_SUCCESS == i_ret)
p_udf_file->fid = (udf_fileid_desc_t *) p_udf_file->sector; p_udf_dirent->fid = (udf_fileid_desc_t *) p_udf_dirent->sector;
else else
p_udf_file->fid = NULL; p_udf_dirent->fid = NULL;
} }
if (p_udf_file->fid && !udf_checktag(&(p_udf_file->fid->tag), TAGID_FID)) if (p_udf_dirent->fid && !udf_checktag(&(p_udf_dirent->fid->tag), TAGID_FID))
{ {
uint32_t ofs = uint32_t ofs =
4 * ((sizeof(*p_udf_file->fid) + p_udf_file->fid->i_imp_use 4 * ((sizeof(*p_udf_dirent->fid) + p_udf_dirent->fid->i_imp_use
+ p_udf_file->fid->i_file_id + 3) / 4); + p_udf_dirent->fid->i_file_id + 3) / 4);
p_udf_file->dir_left -= ofs; p_udf_dirent->dir_left -= ofs;
p_udf_file->b_dir = p_udf_dirent->b_dir =
(p_udf_file->fid->file_characteristics & UDF_FILE_DIRECTORY) != 0; (p_udf_dirent->fid->file_characteristics & UDF_FILE_DIRECTORY) != 0;
p_udf_file->b_parent = p_udf_dirent->b_parent =
(p_udf_file->fid->file_characteristics & UDF_FILE_PARENT) != 0; (p_udf_dirent->fid->file_characteristics & UDF_FILE_PARENT) != 0;
{ {
const unsigned int i_len = p_udf_file->fid->i_file_id; const unsigned int i_len = p_udf_dirent->fid->i_file_id;
uint8_t data[UDF_BLOCKSIZE] = {0}; uint8_t data[UDF_BLOCKSIZE] = {0};
udf_file_entry_t *p_udf_fe = (udf_file_entry_t *) &data; udf_file_entry_t *p_udf_fe = (udf_file_entry_t *) &data;
udf_read_sectors(p_udf, p_udf_fe, p_udf->i_part_start udf_read_sectors(p_udf, p_udf_fe, p_udf->i_part_start
+ p_udf_file->fid->icb.loc.lba, 1); + p_udf_dirent->fid->icb.loc.lba, 1);
memcpy(&(p_udf_file->fe), p_udf_fe, sizeof(udf_file_entry_t)); memcpy(&(p_udf_dirent->fe), p_udf_fe, sizeof(udf_file_entry_t));
if (strlen(p_udf_file->psz_name) < i_len) if (strlen(p_udf_dirent->psz_name) < i_len)
p_udf_file->psz_name = (char *) p_udf_dirent->psz_name = (char *)
realloc(p_udf_file->psz_name, sizeof(char)*i_len+1); realloc(p_udf_dirent->psz_name, sizeof(char)*i_len+1);
unicode16_decode(p_udf_file->fid->imp_use unicode16_decode(p_udf_dirent->fid->imp_use
+ p_udf_file->fid->i_imp_use, + p_udf_dirent->fid->i_imp_use,
i_len, p_udf_file->psz_name); i_len, p_udf_dirent->psz_name);
} }
return p_udf_file; return p_udf_dirent;
} }
return NULL; return NULL;
} }
/*! /*!
free free resources associated with p_udf_file. free free resources associated with p_udf_dirent.
*/ */
bool bool
udf_file_free(udf_file_t *p_udf_file) udf_dirent_free(udf_dirent_t *p_udf_dirent)
{ {
if (p_udf_file) { if (p_udf_dirent) {
free_and_null(p_udf_file->psz_name); p_udf_dirent->fid = NULL;
free_and_null(p_udf_file->sector); free_and_null(p_udf_dirent->psz_name);
free_and_null(p_udf_file); free_and_null(p_udf_dirent->sector);
free_and_null(p_udf_dirent);
} }
return true; return true;
} }

View File

@@ -1,5 +1,5 @@
/* /*
$Id: udf_private.h,v 1.3 2005/10/27 03:03:43 rocky Exp $ $Id: udf_private.h,v 1.4 2005/11/01 03:14:50 rocky Exp $
Copyright (C) 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2005 Rocky Bernstein <rocky@panix.com>
@@ -46,14 +46,14 @@ struct udf_s {
uint32_t fsd_offset; /* lba of fileset descriptor */ uint32_t fsd_offset; /* lba of fileset descriptor */
}; };
struct udf_file_s struct udf_dirent_s
{ {
char *psz_name; char *psz_name;
bool b_dir; /* true if this entry is a directory. */ bool b_dir; /* true if this entry is a directory. */
bool b_parent; /* True if has parent directory (e.g. not root bool b_parent; /* True if has parent directory (e.g. not root
directory). If not set b_dir will probably directory). If not set b_dir will probably
be true. */ be true. */
udf_t *p_udf;
uint32_t i_part_start; uint32_t i_part_start;
uint32_t dir_lba, dir_end_lba; uint32_t dir_lba, dir_end_lba;
uint64_t dir_left; uint64_t dir_left;

View File

@@ -210,12 +210,12 @@ udf_timespec_to_stamp(const struct timespec ts, udf_timestamp_t *dest)
Return the modification time of the file. Return the modification time of the file.
*/ */
time_t time_t
udf_get_modification_time(const udf_file_t *p_udf_file) udf_get_modification_time(const udf_dirent_t *p_udf_dirent)
{ {
if (p_udf_file) { if (p_udf_dirent) {
time_t ret_time; time_t ret_time;
long int usec; long int usec;
udf_stamp_to_time(&ret_time, &usec, p_udf_file->fe.modification_time); udf_stamp_to_time(&ret_time, &usec, p_udf_dirent->fe.modification_time);
return ret_time; return ret_time;
} }
return 0; return 0;
@@ -225,12 +225,12 @@ udf_get_modification_time(const udf_file_t *p_udf_file)
Return the access time of the file. Return the access time of the file.
*/ */
time_t time_t
udf_get_access_time(const udf_file_t *p_udf_file) udf_get_access_time(const udf_dirent_t *p_udf_dirent)
{ {
if (p_udf_file) { if (p_udf_dirent) {
time_t ret_time; time_t ret_time;
long int usec; long int usec;
udf_stamp_to_time(&ret_time, &usec, p_udf_file->fe.access_time); udf_stamp_to_time(&ret_time, &usec, p_udf_dirent->fe.access_time);
return ret_time; return ret_time;
} }
return 0; return 0;
@@ -240,12 +240,12 @@ udf_get_access_time(const udf_file_t *p_udf_file)
Return the attribute (most recent create or access) time of the file Return the attribute (most recent create or access) time of the file
*/ */
time_t time_t
udf_get_attribute_time(const udf_file_t *p_udf_file) udf_get_attribute_time(const udf_dirent_t *p_udf_dirent)
{ {
if (p_udf_file) { if (p_udf_dirent) {
time_t ret_time; time_t ret_time;
long int usec; long int usec;
udf_stamp_to_time(&ret_time, &usec, p_udf_file->fe.attribute_time); udf_stamp_to_time(&ret_time, &usec, p_udf_dirent->fe.attribute_time);
return ret_time; return ret_time;
} }
return 0; return 0;