aboutsummaryrefslogtreecommitdiff
path: root/lib/sqfshelper/sqfs_reader.c
blob: e9c9c3360ca07e2ad3c60333da11927dcc878426 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/* SPDX-License-Identifier: GPL-3.0-or-later */
/*
 * sqfs_reader.c
 *
 * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
 */
#include "config.h"

#include "highlevel.h"

#include <string.h>
#include <unistd.h>
#include <fcntl.h>

int sqfs_reader_open(sqfs_reader_t *rd, const char *filename, int rdtree_flags)
{
	sqfs_compressor_config_t cfg;

	memset(rd, 0, sizeof(*rd));

	rd->file = sqfs_open_file(filename, SQFS_FILE_OPEN_READ_ONLY);
	if (rd->file == NULL)
		return -1;

	if (sqfs_super_read(&rd->super, rd->file))
		goto fail_fd;

	if (!sqfs_compressor_exists(rd->super.compression_id)) {
		fprintf(stderr, "%s: unknown compressor used.\n", filename);
		goto fail_fd;
	}

	sqfs_compressor_config_init(&cfg, rd->super.compression_id,
				    rd->super.block_size,
				    SQFS_COMP_FLAG_UNCOMPRESS);

	rd->cmp = sqfs_compressor_create(&cfg);
	if (rd->cmp == NULL)
		goto fail_fd;

	if (rd->super.flags & SQFS_FLAG_COMPRESSOR_OPTIONS) {
		if (rd->cmp->read_options(rd->cmp, rd->file))
			goto fail_cmp;
	}

	if (rd->super.flags & SQFS_FLAG_NO_XATTRS)
		rdtree_flags &= ~RDTREE_READ_XATTR;

	if (deserialize_fstree(&rd->fs, &rd->super, rd->cmp, rd->file,
			       rdtree_flags)) {
		goto fail_cmp;
	}

	fstree_gen_file_list(&rd->fs);

	rd->data = data_reader_create(rd->file, &rd->super, rd->cmp);
	if (rd->data == NULL)
		goto fail_fs;

	return 0;
fail_fs:
	fstree_cleanup(&rd->fs);
fail_cmp:
	rd->cmp->destroy(rd->cmp);
fail_fd:
	rd->file->destroy(rd->file);
	memset(rd, 0, sizeof(*rd));
	return -1;
}

void sqfs_reader_close(sqfs_reader_t *rd)
{
	data_reader_destroy(rd->data);
	fstree_cleanup(&rd->fs);
	rd->cmp->destroy(rd->cmp);
	rd->file->destroy(rd->file);
	memset(rd, 0, sizeof(*rd));
}