libsqsh v1.5.1
Loading...
Searching...
No Matches
Working with Archives

Introduction

The SqshArchive struct represents a squashfs archive. It is created by calling sqsh_archive_open() and is destroyed by calling sqsh_archive_close().

Opening and cleaning up an archive is simple:

struct SqshArchive *archive = sqsh_archive_open("archive.squashfs", NULL, NULL);
assert(archive != NULL);
SQSH_NO_UNUSED struct SqshArchive * sqsh_archive_open(const void *source, const struct SqshConfig *config, int *err)
initializes a archive context in heap.
int sqsh_archive_close(struct SqshArchive *archive)
Frees the resources used by a Sqsh instance.

Opening with more control:

int err = 0;
struct SqshConfig config = {
// ...
};
struct SqshArchive *archive = sqsh_archive_open("archive.sqsh", &config, &err);
if (err != 0) {
sqsh_perror(err, NULL);
exit(1);
}
void sqsh_perror(int error_code, const char *msg)
Print the error message for the given error code.
The SqshConfig struct contains all the configuration options for a sqsh session.
size_t max_symlink_depth
the maximum depth of symlinks that will be followed. If unset or 0, the max symlink depth will be 100...

Reading files in the archive

Simple

The simplest way to read a file in the archive is to use sqsh_easy_file_content(). This function returns a pointer to the contents of the file in the archive. The pointer is heap allocated and must be free'd by the caller. The allocated buffer is null terminated. If the file itself contains null bytes, you can get the file size by calling sqsh_easy_file_size().

struct SqshArchive *archive = sqsh_archive_open("archive.squashfs", NULL, NULL);
assert(archive != NULL);
uint8_t *content = sqsh_easy_file_content(archive, "/path/to/file.txt", NULL);
uint64_t size = sqsh_easy_file_size2(archive, "/path/to/file.txt", NULL);
fwrite(content, 1, size, stdout);
free(content);
uint64_t sqsh_easy_file_size2(struct SqshArchive *archive, const char *path, int *err)
retrieves the size of a file.
uint8_t * sqsh_easy_file_content(struct SqshArchive *archive, const char *path, int *err)
retrieves the content of a file.

Advanced: File Iterators

The simple API is fine for small files, but for larger files it is better to use the SqshFileIterator. The iterator allows you to read the file in chunks, which is more efficient than reading the entire file into memory at once.

struct SqshArchive *archive = sqsh_archive_open("archive.squashfs", NULL, NULL);
int err = 0;
struct SqshFile *file = sqsh_open(archive, "/path/to/file.txt", &err);
assert(err == 0);
struct SqshFileIterator *it = sqsh_file_iterator_new(file, &err);
assert(err == 0);
while ((err = sqsh_file_iterator_next(it, SIZE_MAX, &err)) > 0) {
const uint8_t *data = sqsh_file_iterator_data(it);
size_t size = sqsh_file_iterator_size(it);
fwrite(data, 1, size, stdout);
}
assert(err == 0);
sqsh_close(file);
sqsh_archive_close(archive);
An iterator over the contents of a file.
SQSH_NO_UNUSED size_t sqsh_file_iterator_size(const struct SqshFileIterator *iterator)
Gets the size of the data currently in the file iterator.
SQSH_NO_UNUSED struct SqshFileIterator * sqsh_file_iterator_new(const struct SqshFile *file, int *err)
Creates a new SqshFileIterator struct and initializes it.
SQSH_NO_UNUSED bool sqsh_file_iterator_next(struct SqshFileIterator *iterator, size_t desired_size, int *err)
Reads a certain amount of data from the file iterator.
int sqsh_file_iterator_free(struct SqshFileIterator *iterator)
Frees the resources used by a SqshFileIterator struct.
SQSH_NO_UNUSED const uint8_t * sqsh_file_iterator_data(const struct SqshFileIterator *iterator)
Gets a pointer to the current data in the file iterator.
The Inode context.
SQSH_NO_UNUSED struct SqshFile * sqsh_open(struct SqshArchive *archive, const char *path, int *err)
Initialize the file context from a path.

Advanced: File Reader

If you need more control over the ranges to be read from the file, you can use the SqshFileReader API. This API allows you to read arbitrary ranges from the file.

struct SqshArchive *archive = sqsh_archive_open("archive.squashfs", NULL, NULL);
int err = 0;
struct SqshFile *file = sqsh_open(archive, "/path/to/file.txt", &err);
assert(err == 0);
struct SqshFileReader *reader = sqsh_file_reader_new(file, &err);
assert(err == 0);
err = sqsh_file_reader_advance2(reader, 0, 10);
assert(err == 0);
const uint8_t *data = sqsh_file_reader_data(reader);
size_t size = sqsh_file_reader_size(reader);
fwrite(data, 1, size, stdout);
sqsh_close(file);
sqsh_archive_close(archive);
A reader over the contents of a file.
const uint8_t * sqsh_file_reader_data(const struct SqshFileReader *reader)
Gets a pointer to the current data in the file reader.
int sqsh_file_reader_advance2(struct SqshFileReader *reader, uint64_t offset, size_t size)
Advances the file reader by a certain amount of data and presents size bytes of data to the user.
size_t sqsh_file_reader_size(const struct SqshFileReader *reader)
Gets the size of the current data in the file reader.
int sqsh_file_reader_free(struct SqshFileReader *reader)
Cleans up resources used by a SqshFileReader struct.
struct SqshFileReader * sqsh_file_reader_new(const struct SqshFile *file, int *err)
Initializes a SqshFileReader struct.

This example reads the first 10 bytes of the file.

Reading xattrs

libsqsh is able to handle handle xattrs of files in the archive.

Simple

The simple way to get an xattr is to use sqsh_easy_xattr_get().

int err = 0;
struct SqshArchive *archive = sqsh_archive_open("archive.squashfs", NULL, NULL);
assert(err == 0);
char *xattr = sqsh_easy_xattr_get(archive, "/path/to/file.txt", "user.myxattr", &err);
assert(err == 0);
puts(xattr);
free(xattr);
char * sqsh_easy_xattr_get(struct SqshArchive *archive, const char *path, const char *key, int *err)
retrieves the value of a xattr key of a file or directory.

To get a list of all xattr on a file you can use sqsh_easy_xattr_list "sqsh_easy_xattr_list()".

int err = 0;
struct SqshArchive *archive = sqsh_archive_open("archive.squashfs", NULL, NULL);
assert(err == 0);
char **list = sqsh_easy_xattr_keys(archive, "/path/to/file.txt", &err);
assert(err == 0);
for(int i = 0; list[i] != NULL; i++) {
puts(list[i]);
}
free(list);
char ** sqsh_easy_xattr_keys(struct SqshArchive *archive, const char *path, int *err)
retrieves all xattr keys of a file or directory.