diff --git a/README.md b/README.md index d555df5c1..34517a8b0 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,9 @@ provides zero-copy interfaces to the squashfs archives. struct SqshArchive *archive = sqsh_archive_open("/path/to/archive.squashfs", NULL, NULL); -uint8_t *contents = sqsh_easy_file_content(archive, "/path/to/file"); +uint8_t *contents = sqsh_easy_file_content(archive, "/path/to/file", NULL); assert(contents != NULL); -const size_t size = sqsh_easy_file_size(archive, "/path/to/file"); +const size_t size = sqsh_easy_file_size(archive, "/path/to/file", NULL); fwrite(contents, 1, size, stdout); free(contents); diff --git a/examples/read_file.c b/examples/read_file.c index 29fb2e040..be28ab614 100644 --- a/examples/read_file.c +++ b/examples/read_file.c @@ -20,9 +20,9 @@ main(int argc, char *argv[]) { struct SqshArchive *archive = sqsh_archive_open(argv[1], NULL, NULL); assert(archive != NULL); - uint8_t *content = sqsh_easy_file_content(archive, argv[2]); + uint8_t *content = sqsh_easy_file_content(archive, argv[2], NULL); assert(content != NULL); - size_t size = sqsh_easy_file_size(archive, argv[2]); + size_t size = sqsh_easy_file_size(archive, argv[2], NULL); fwrite(content, size, 1, stdout); diff --git a/examples/readme_example.c b/examples/readme_example.c index d1bfac9ab..0f1b83c97 100644 --- a/examples/readme_example.c +++ b/examples/readme_example.c @@ -16,9 +16,9 @@ main(int argc, char *argv[]) { struct SqshArchive *archive = sqsh_archive_open("/path/to/archive.squashfs", NULL, NULL); - uint8_t *contents = sqsh_easy_file_content(archive, "/path/to/file"); + uint8_t *contents = sqsh_easy_file_content(archive, "/path/to/file", NULL); assert(contents != NULL); - const size_t size = sqsh_easy_file_size(archive, "/path/to/file"); + const size_t size = sqsh_easy_file_size(archive, "/path/to/file", NULL); fwrite(contents, 1, size, stdout); free(contents); diff --git a/include/sqsh_easy.h b/include/sqsh_easy.h index bb5717227..11e69068f 100644 --- a/include/sqsh_easy.h +++ b/include/sqsh_easy.h @@ -56,10 +56,11 @@ struct SqshFile; * * @param[in] archive The sqsh archive context. * @param[in] path The path the file or directory. + * @param[out] err Pointer to an int where the error code will be stored. * * @return true if the file exists, false otherwise. */ -bool sqsh_easy_file_exists(struct SqshArchive *archive, const char *path); +bool sqsh_easy_file_exists(struct SqshArchive *archive, const char *path, int *err); /** * @brief retrieves the content of a file. @@ -69,40 +70,44 @@ bool sqsh_easy_file_exists(struct SqshArchive *archive, const char *path); * * @param[in] archive The sqsh archive context. * @param[in] path The path the file or directory. + * @param[out] err Pointer to an int where the error code will be stored. * * @return The content of the file on success, NULL on error. */ -uint8_t *sqsh_easy_file_content(struct SqshArchive *archive, const char *path); +uint8_t *sqsh_easy_file_content(struct SqshArchive *archive, const char *path, int *err); /** * @brief retrieves the size of a file. * * @param[in] archive The sqsh archive context. * @param[in] path The path the file or directory. + * @param[out] err Pointer to an int where the error code will be stored. * * @return The size of the file on success, 0 on error. */ -size_t sqsh_easy_file_size(struct SqshArchive *archive, const char *path); +size_t sqsh_easy_file_size(struct SqshArchive *archive, const char *path, int *err); /** * @brief retrieves unix permissions of a file. * * @param[in] archive The sqsh archive context. * @param[in] path The path the file or directory. + * @param[out] err Pointer to an int where the error code will be stored. * * @return The unix permissions of the file on success, 0 on error. */ -mode_t sqsh_easy_file_permission(struct SqshArchive *archive, const char *path); +mode_t sqsh_easy_file_permission(struct SqshArchive *archive, const char *path, int *err); /** * @brief retrieves the modification time of a file. * * @param[in] archive The sqsh archive context. * @param[in] path The path the file or directory. + * @param[out] err Pointer to an int where the error code will be stored. * * @return The modification time of the file on success, 0 on error. */ -time_t sqsh_easy_file_mtime(struct SqshArchive *archive, const char *path); +time_t sqsh_easy_file_mtime(struct SqshArchive *archive, const char *path, int *err); /*************************************** * chrome/directory.c diff --git a/lib/easy/file.c b/lib/easy/file.c index 8aac5a54b..02f5338e7 100644 --- a/lib/easy/file.c +++ b/lib/easy/file.c @@ -46,25 +46,34 @@ #include "../../include/sqsh_tree_private.h" bool -sqsh_easy_file_exists(struct SqshArchive *archive, const char *path) { +sqsh_easy_file_exists(struct SqshArchive *archive, const char *path, int *err) { int rv = 0; - struct SqshFile *file = NULL; + struct SqshTreeWalker walker = {0}; bool exists = false; - file = sqsh_open(archive, path, &rv); + rv = sqsh__tree_walker_init(&walker, archive); + if (rv == -SQSH_ERROR_NO_SUCH_FILE) { + rv = 0; + goto out; + } else if (rv < 0) { + goto out; + } + rv = sqsh_tree_walker_resolve(&walker, path, true); if (rv < 0) { goto out; } - exists = true; - out: - sqsh_close(file); + sqsh__tree_walker_cleanup(&walker); + if (err != NULL) { + *err = rv; + } return exists; } uint8_t * -sqsh_easy_file_content(struct SqshArchive *archive, const char *path) { +sqsh_easy_file_content( + struct SqshArchive *archive, const char *path, int *err) { int rv = 0; struct SqshFileIterator iterator = {0}; struct SqshFile *file = NULL; @@ -102,11 +111,14 @@ sqsh_easy_file_content(struct SqshArchive *archive, const char *path) { free(content); content = NULL; } + if (err != NULL) { + *err = rv; + } return content; } size_t -sqsh_easy_file_size(struct SqshArchive *archive, const char *path) { +sqsh_easy_file_size(struct SqshArchive *archive, const char *path, int *err) { int rv = 0; struct SqshFile *file = NULL; size_t file_size = 0; @@ -120,11 +132,15 @@ sqsh_easy_file_size(struct SqshArchive *archive, const char *path) { out: sqsh_close(file); + if (err != NULL) { + *err = rv; + } return file_size; } mode_t -sqsh_easy_file_permission(struct SqshArchive *archive, const char *path) { +sqsh_easy_file_permission( + struct SqshArchive *archive, const char *path, int *err) { int rv = 0; struct SqshFile *file = NULL; mode_t permission = 0; @@ -138,11 +154,14 @@ sqsh_easy_file_permission(struct SqshArchive *archive, const char *path) { out: sqsh_close(file); + if (err != NULL) { + *err = rv; + } return permission; } time_t -sqsh_easy_file_mtime(struct SqshArchive *archive, const char *path) { +sqsh_easy_file_mtime(struct SqshArchive *archive, const char *path, int *err) { int rv = 0; struct SqshFile *file = NULL; time_t modified = 0; @@ -156,5 +175,8 @@ sqsh_easy_file_mtime(struct SqshArchive *archive, const char *path) { out: sqsh_close(file); + if (err != NULL) { + *err = rv; + } return modified; } diff --git a/test/easy/file.c b/test/easy/file.c index 7a7196f68..45521694a 100644 --- a/test/easy/file.c +++ b/test/easy/file.c @@ -70,7 +70,7 @@ test_file_get_content_through_symlink(void) { }; mk_stub(&archive, payload, sizeof(payload)); - uint8_t *content = sqsh_easy_file_content(&archive, "/src"); + uint8_t *content = sqsh_easy_file_content(&archive, "/src", NULL); assert(content != NULL); assert(strcmp((char *)content, "12345678") == 0); free(content); diff --git a/test/integration.c b/test/integration.c index 3d5ab1cca..df6be0221 100644 --- a/test/integration.c +++ b/test/integration.c @@ -181,7 +181,7 @@ sqsh_read_content(void) { rv = sqsh__archive_init(&archive, (char *)TEST_SQUASHFS_IMAGE, &config); assert(rv == 0); - data = (char *)sqsh_easy_file_content(&archive, "/a"); + data = (char *)sqsh_easy_file_content(&archive, "/a", NULL); assert(strcmp(data, "a\n") == 0); free(data);