From dd83f85d093032db1f43c11781d0fa84fd413cc6 Mon Sep 17 00:00:00 2001 From: Vreixo Formoso Date: Sat, 15 Dec 2007 12:51:48 +0100 Subject: [PATCH] Support for identification of source Streams. We identify uniquelly a given source Stream by a triple of numbers: the filesystem id, the device id inside the filesystem, and the inode id. --- src/fs_local.c | 9 +++++++++ src/fsource.c | 5 +++++ src/fsource.h | 20 ++++++++++++++++++++ src/stream.c | 28 ++++++++++++++++++++++++++++ src/stream.h | 11 +++++++++++ 5 files changed, 73 insertions(+) diff --git a/src/fs_local.c b/src/fs_local.c index 738c9bc..598f5d0 100644 --- a/src/fs_local.c +++ b/src/fs_local.c @@ -24,6 +24,8 @@ #include #include +#define ISO_LOCAL_FS_ID 1 + /* * We can share a local filesystem object, as it has no private atts. */ @@ -471,6 +473,12 @@ int lfs_get_by_path(IsoFilesystem *fs, const char *path, IsoFileSource **file) return iso_file_source_new_lfs(path, file); } +static +unsigned int lfs_get_id(IsoFilesystem *fs) +{ + return ISO_LOCAL_FS_ID; +} + static void lfs_fs_free(IsoFilesystem *fs) { @@ -498,6 +506,7 @@ int iso_local_filesystem_new(IsoFilesystem **fs) lfs->data = NULL; /* we don't need private data */ lfs->get_root = lfs_get_root; lfs->get_by_path = lfs_get_by_path; + lfs->get_id = lfs_get_id; lfs->free = lfs_fs_free; } *fs = lfs; diff --git a/src/fsource.c b/src/fsource.c index 4f97a8a..3bd4480 100644 --- a/src/fsource.c +++ b/src/fsource.c @@ -9,6 +9,11 @@ #include "fsource.h" #include +/** + * Values belong 100 are reserved for out own usage + */ +unsigned int iso_fs_global_id = 100; + void iso_file_source_ref(IsoFileSource *src) { ++src->refcount; diff --git a/src/fsource.h b/src/fsource.h index ef533f3..b433ead 100644 --- a/src/fsource.h +++ b/src/fsource.h @@ -23,6 +23,11 @@ typedef struct Iso_File_Source IsoFileSource; typedef struct Iso_Filesystem IsoFilesystem; +/** + * See IsoFilesystem->get_id() for info about this. + */ +extern unsigned int iso_fs_global_id; + struct Iso_Filesystem { @@ -40,6 +45,21 @@ struct Iso_Filesystem */ int (*get_by_path)(IsoFilesystem *fs, const char *path, IsoFileSource **file); + + /** + * Get filesystem identifier. + * + * If the filesystem is able to generate correct values of the st_dev + * and st_ino fields for the struct stat of each file, this should + * return an unique number, greater than 0. + * + * To get a identifier for your filesystem implementation you should + * use iso_fs_global_id, incrementing it by one each time. + * + * Otherwise, if you can't ensure values in the struct stat are valid, + * this should return 0. + */ + unsigned int (*get_id)(IsoFilesystem *fs); void (*free)(IsoFilesystem *fs); diff --git a/src/stream.c b/src/stream.c index 7fc734c..d03278e 100644 --- a/src/stream.c +++ b/src/stream.c @@ -90,6 +90,33 @@ int fsrc_is_repeatable(IsoStream *stream) } } +static +int fsrc_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id, + ino_t *ino_id) +{ + int result; + struct stat info; + IsoFileSource *src; + IsoFilesystem *fs; + + if (stream == NULL || fs_id == NULL || dev_id == NULL || ino_id == NULL) { + return ISO_NULL_POINTER; + } + src = (IsoFileSource*)stream->data; + + result = src->stat(src, &info); + if (result < 0) { + return result; + } + + fs = src->get_filesystem(src); + + *fs_id = fs->get_id(fs); + *dev_id = info.st_dev; + *ino_id = info.st_ino; + return ISO_SUCCESS; +} + static void fsrc_free(IsoStream *stream) { @@ -127,6 +154,7 @@ int iso_file_source_stream_new(IsoFileSource *src, IsoStream **stream) str->get_size = fsrc_get_size; str->read = fsrc_read; str->is_repeatable = fsrc_is_repeatable; + str->get_id = fsrc_get_id; str->free = fsrc_free; *stream = str; diff --git a/src/stream.h b/src/stream.h index 52daa55..d068bf1 100644 --- a/src/stream.h +++ b/src/stream.h @@ -67,6 +67,17 @@ struct Iso_Stream * 1 if stream is repeatable, 0 if not, < 0 on error */ int (*is_repeatable)(IsoStream *stream); + + /** + * Get an unique identifier for the IsoStream. If your implementation + * is unable to return a valid identifier, this function should return + * 0. + * + * @return + * 1 on success, 0 if idenfier is not valid, < 0 error + */ + int (*get_id)(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id, + ino_t *ino_id); /** * Free implementation specific data. Should never be called by user.