diff --git a/example/udf1.c b/example/udf1.c index 70f1cd93..da0d1a79 100644 --- a/example/udf1.c +++ b/example/udf1.c @@ -1,5 +1,5 @@ /* - $Id: udf1.c,v 1.7 2005/10/26 02:05:53 rocky Exp $ + $Id: udf1.c,v 1.8 2005/10/27 01:23:48 rocky Exp $ Copyright (C) 2005 Rocky Bernstein @@ -50,14 +50,27 @@ #define udf_PATH_DELIMITERS "/\\" -static -udf_file_t * +static void +print_file_info(const udf_file_t *p_udf_file) +{ + time_t mod_time = udf_get_modification_time(p_udf_file); + udf_file_entry_t udf_fe; + if (udf_get_file_entry(p_udf_file, &udf_fe)) { + char perms[10]="invalid"; + /* Print directory attributes*/ + printf("%s ", udf_get_attr_str (udf_fe.permissions, perms)); + } + + printf("%s %s", udf_get_filename(p_udf_file), ctime(&mod_time)); +} + + +static udf_file_t * list_files(const udf_t *p_udf, udf_file_t *p_udf_file, char *psz_token) { if (!p_udf_file) return NULL; if (psz_token) { - time_t mod_time = udf_get_modification_time(p_udf_file); - printf("%s %s\n", psz_token, ctime(&mod_time)); + print_file_info(p_udf_file); } while (udf_get_next(p_udf, p_udf_file)) { @@ -74,7 +87,7 @@ list_files(const udf_t *p_udf, udf_file_t *p_udf_file, char *psz_token) udf_file_free(p_udf_file3); } } else { - printf("%s\n", udf_get_name(p_udf_file)); + print_file_info(p_udf_file); } } free(psz_token); @@ -119,8 +132,7 @@ main(int argc, const char *argv[]) } } - - list_files(p_udf, p_udf_file, strdup(udf_get_name(p_udf_file))); + list_files(p_udf, p_udf_file, strdup(udf_get_filename(p_udf_file))); udf_file_free(p_udf_file); } diff --git a/include/cdio/udf.h b/include/cdio/udf.h index d55a6392..7013b8f6 100644 --- a/include/cdio/udf.h +++ b/include/cdio/udf.h @@ -1,5 +1,5 @@ /* - $Id: udf.h,v 1.10 2005/10/26 02:05:54 rocky Exp $ + $Id: udf.h,v 1.11 2005/10/27 01:23:48 rocky Exp $ Copyright (C) 2005 Rocky Bernstein This program is free software; you can redistribute it and/or modify @@ -104,47 +104,58 @@ int udf_get_volume_id(udf_t *p_udf, /*out*/ char *psz_volid, * returns the size of the available volsetid information (128) * or 0 on error */ -int udf_get_volumeset_id(udf_t *p_udf, /*out*/ uint8_t *volsetid, - unsigned int i_volsetid); - + int udf_get_volumeset_id(udf_t *p_udf, /*out*/ uint8_t *volsetid, + unsigned int i_volsetid); + /*! Return a file pointer matching pzz_name. If b_any_partition is false then the root must be in the given partition. */ -udf_file_t *udf_find_file(udf_t *p_udf, const char *psz_name, - bool b_any_partition, - partition_num_t i_partition); + udf_file_t *udf_find_file(udf_t *p_udf, const char *psz_name, + bool b_any_partition, + partition_num_t i_partition); + + /*! + Returns a string which interpreting the extended attribute permissions + */ + const char *udf_get_attr_str(udf_Uint32_t permissions, char perms[]); + + /*! + Return the name of the file + */ + bool udf_get_file_entry(const udf_file_t *p_udf_file, + /*out*/ udf_file_entry_t *p_udf_fe); /*! Return the next subdirectory. */ -udf_file_t *udf_get_sub(const udf_t *p_udf, const udf_file_t *p_udf_file); + udf_file_t *udf_get_sub(const udf_t *p_udf, const udf_file_t *p_udf_file); -/*! + /*! Return the name of the file - */ -const char *udf_get_name(const udf_file_t *p_udf_file); - -/*! - Return the next file. - */ -udf_file_t *udf_get_next(const udf_t *p_udf, udf_file_t *p_udf_file); - -/*! - Close UDF and free resources associated with p_udf. -*/ -bool udf_close (udf_t *p_udf); - -/*! - free free resources associated with p_udf_file. -*/ -bool udf_file_free(udf_file_t *p_udf_file); - -/*! - Return true if the file is a directory. - */ -bool udf_is_dir(const udf_file_t *p_udf_file); + */ + const char *udf_get_filename(const udf_file_t *p_udf_file); + /*! + Return the next file. + */ + udf_file_t *udf_get_next(const udf_t *p_udf, udf_file_t *p_udf_file); + + /*! + Close UDF and free resources associated with p_udf. + */ + bool udf_close (udf_t *p_udf); + + /*! + free free resources associated with p_udf_file. + */ + bool udf_file_free(udf_file_t *p_udf_file); + + /*! + Return true if the file is a directory. + */ + bool udf_is_dir(const udf_file_t *p_udf_file); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/lib/udf/libudf.sym b/lib/udf/libudf.sym index aef51fba..b6dbc40a 100644 --- a/lib/udf/libudf.sym +++ b/lib/udf/libudf.sym @@ -10,7 +10,8 @@ VSD_STD_ID_NSR03 VSD_STD_ID_TEA01 udf_close udf_file_free -udf_get_name +udf_get_file_entry +udf_get_filename udf_get_next udf_get_sub udf_is_dir diff --git a/lib/udf/udf.c b/lib/udf/udf.c index 24379d06..23890f31 100644 --- a/lib/udf/udf.c +++ b/lib/udf/udf.c @@ -1,5 +1,5 @@ /* - $Id: udf.c,v 1.1 2005/10/24 10:14:58 rocky Exp $ + $Id: udf.c,v 1.2 2005/10/27 01:23:48 rocky Exp $ Copyright (C) 2005 Rocky Bernstein @@ -19,14 +19,53 @@ */ /* Access routines */ +#include #include "udf_private.h" +#ifdef HAVE_STRING_H +# include +#endif + +/*! + Returns a string which interpreting the extended attribute permissions +*/ const char * -udf_get_name(const udf_file_t *p_udf_file) +udf_get_attr_str(udf_Uint32_t permissions, char *result) { + uint32_t i_perms = uint32_from_le(permissions); + + result[ 0] = (i_perms & FE_PERM_U_READ) ? 'r' : '-'; + result[ 1] = (i_perms & FE_PERM_U_WRITE) ? 'w' : '-'; + result[ 2] = (i_perms & FE_PERM_U_EXEC) ? 'x' : '-'; + + result[ 3] = (i_perms & FE_PERM_G_READ) ? 'r' : '-'; + result[ 4] = (i_perms & FE_PERM_G_WRITE) ? 'w' : '-'; + result[ 5] = (i_perms & FE_PERM_G_EXEC) ? 'x' : '-'; + + result[ 6] = (i_perms & FE_PERM_O_READ) ? 'r' : '-'; + result[ 7] = (i_perms & FE_PERM_O_WRITE) ? 'w' : '-'; + result[ 8] = (i_perms & FE_PERM_O_EXEC) ? 'x' : '-'; + + result[ 9] = '\0'; + return result; +} + +const char * +udf_get_filename(const udf_file_t *p_udf_file) +{ + if (!p_udf_file) return NULL; return p_udf_file->psz_name; } +bool +udf_get_file_entry(const udf_file_t *p_udf_file, + /*out*/ udf_file_entry_t *p_udf_fe) +{ + if (!p_udf_file) return false; + memcpy(p_udf_fe, &p_udf_file->fe, sizeof(udf_file_entry_t)); + return true; +} + bool udf_is_dir(const udf_file_t *p_udf_file) { diff --git a/lib/udf/udf_fs.c b/lib/udf/udf_fs.c index 9e73990f..1162018b 100644 --- a/lib/udf/udf_fs.c +++ b/lib/udf/udf_fs.c @@ -1,5 +1,5 @@ /* - $Id: udf_fs.c,v 1.7 2005/10/26 02:05:54 rocky Exp $ + $Id: udf_fs.c,v 1.8 2005/10/27 01:23:48 rocky Exp $ Copyright (C) 2005 Rocky Bernstein @@ -150,17 +150,17 @@ udf_checktag(udf_tag_t *p_tag, udf_Uint16_t tag_id) } static bool -udf_get_lba(const udf_file_entry_t *p_fe, +udf_get_lba(const udf_file_entry_t *p_udf_fe, /*out*/ uint32_t *start, /*out*/ uint32_t *end) { - if (! p_fe->i_alloc_descs) + if (! p_udf_fe->i_alloc_descs) return false; - switch (p_fe->icb_tag.flags & ICBTAG_FLAG_AD_MASK) { + switch (p_udf_fe->icb_tag.flags & ICBTAG_FLAG_AD_MASK) { case ICBTAG_FLAG_AD_SHORT: { udf_short_ad_t *p_ad = (udf_short_ad_t *) - (p_fe->ext_attr + p_fe->i_extended_attr); + (p_udf_fe->ext_attr + p_udf_fe->i_extended_attr); *start = uint32_from_le(p_ad->pos); *end = *start + @@ -171,7 +171,7 @@ udf_get_lba(const udf_file_entry_t *p_fe, case ICBTAG_FLAG_AD_LONG: { udf_long_ad_t *p_ad = (udf_long_ad_t *) - (p_fe->ext_attr + p_fe->i_extended_attr); + (p_udf_fe->ext_attr + p_udf_fe->i_extended_attr); *start = uint32_from_le(p_ad->loc.lba); /* ignore partition number */ *end = *start + @@ -182,7 +182,7 @@ udf_get_lba(const udf_file_entry_t *p_fe, case ICBTAG_FLAG_AD_EXTENDED: { udf_ext_ad_t *p_ad = (udf_ext_ad_t *) - (p_fe->ext_attr + p_fe->i_extended_attr); + (p_udf_fe->ext_attr + p_udf_fe->i_extended_attr); *start = uint32_from_le(p_ad->ext_loc.lba); /* ignore partition number */ *end = *start + @@ -268,7 +268,7 @@ unicode16_decode( const uint8_t *data, int i_len, char *target ) static udf_file_t * -udf_new_file(udf_file_entry_t *p_fe, uint32_t i_part_start, +udf_new_file(udf_file_entry_t *p_udf_fe, uint32_t i_part_start, 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)); @@ -277,10 +277,10 @@ udf_new_file(udf_file_entry_t *p_fe, uint32_t i_part_start, p_udf_file->b_dir = b_dir; p_udf_file->b_parent = b_parent; p_udf_file->i_part_start = i_part_start; - p_udf_file->dir_left = uint64_from_le(p_fe->info_len); + p_udf_file->dir_left = uint64_from_le(p_udf_fe->info_len); - memcpy(&(p_udf_file->fe), p_fe, sizeof(udf_file_entry_t)); - udf_get_lba( p_fe, &(p_udf_file->dir_lba), &(p_udf_file->dir_end_lba) ); + memcpy(&(p_udf_file->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) ); return p_udf_file; } @@ -511,19 +511,20 @@ udf_get_root (udf_t *p_udf, bool b_any_partition, partition_num_t i_partition) 1); if (DRIVER_OP_SUCCESS == ret && !udf_checktag(&p_fsd->tag, TAGID_FSD)) { - udf_file_entry_t *p_fe = (udf_file_entry_t *) &data; + udf_file_entry_t *p_udf_fe = (udf_file_entry_t *) &data; const uint32_t parent_icb = uint32_from_le(p_fsd->root_icb.loc.lba); /* Check partition numbers match of last-read block? */ - ret = udf_read_sectors(p_udf, p_fe, p_udf->i_part_start + parent_icb, 1); + ret = udf_read_sectors(p_udf, p_udf_fe, + p_udf->i_part_start + parent_icb, 1); if (ret == DRIVER_OP_SUCCESS && - !udf_checktag(&p_fe->tag, TAGID_FILE_ENTRY)) { + !udf_checktag(&p_udf_fe->tag, TAGID_FILE_ENTRY)) { /* Check partition numbers match of last-read block? */ /* We win! - Save root directory information. */ - return udf_new_file(p_fe, p_udf->i_part_start, "/", true, false ); + return udf_new_file(p_udf_fe, p_udf->i_part_start, "/", true, false ); } } } @@ -559,19 +560,19 @@ udf_get_sub(const udf_t *p_udf, const udf_file_t *p_udf_file) { if (p_udf_file->b_dir && !p_udf_file->b_parent && p_udf_file->fid) { uint8_t data[UDF_BLOCKSIZE]; - udf_file_entry_t *p_fe = (udf_file_entry_t *) &data; + udf_file_entry_t *p_udf_fe = (udf_file_entry_t *) &data; driver_return_code_t i_ret = - udf_read_sectors(p_udf, p_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); if (DRIVER_OP_SUCCESS == i_ret - && !udf_checktag(&p_fe->tag, TAGID_FILE_ENTRY)) { + && !udf_checktag(&p_udf_fe->tag, TAGID_FILE_ENTRY)) { - if (ICBTAG_FILE_TYPE_DIRECTORY == p_fe->icb_tag.file_type) { - udf_file_t *p_udf_file_new = udf_new_file(p_fe, p_udf->i_part_start, - p_udf_file->psz_name, - true, true); + if (ICBTAG_FILE_TYPE_DIRECTORY == p_udf_fe->icb_tag.file_type) { + udf_file_t *p_udf_file_new = + udf_new_file(p_udf_fe, p_udf->i_part_start, p_udf_file->psz_name, + true, true); return p_udf_file_new; } } @@ -625,9 +626,17 @@ udf_get_next(const udf_t *p_udf, udf_file_t *p_udf_file) (p_udf_file->fid->file_characteristics & UDF_FILE_DIRECTORY) != 0; p_udf_file->b_parent = (p_udf_file->fid->file_characteristics & UDF_FILE_PARENT) != 0; - + { const unsigned int i_len = p_udf_file->fid->i_file_id; + uint8_t data[UDF_BLOCKSIZE] = {0}; + 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 + + p_udf_file->fid->icb.loc.lba, 1); + + memcpy(&(p_udf_file->fe), p_udf_fe, sizeof(udf_file_entry_t)); + if (strlen(p_udf_file->psz_name) < i_len) p_udf_file->psz_name = (char *) realloc(p_udf_file->psz_name, sizeof(char)*i_len+1); @@ -643,7 +652,7 @@ udf_get_next(const udf_t *p_udf, udf_file_t *p_udf_file) /*! - free free resources associated with p_fe. + free free resources associated with p_udf_file. */ bool udf_file_free(udf_file_t *p_udf_file)