summaryrefslogtreecommitdiffstats
path: root/exfat2img
diff options
context:
space:
mode:
Diffstat (limited to 'exfat2img')
-rw-r--r--exfat2img/exfat2img.c93
1 files changed, 39 insertions, 54 deletions
diff --git a/exfat2img/exfat2img.c b/exfat2img/exfat2img.c
index 3f83588..bd9db44 100644
--- a/exfat2img/exfat2img.c
+++ b/exfat2img/exfat2img.c
@@ -52,7 +52,7 @@ struct exfat2img {
bool save_cc;
struct exfat_blk_dev bdev;
struct exfat *exfat;
- struct buffer_desc *dump_bdesc;
+ void *dump_cluster;
struct buffer_desc *scan_bdesc;
struct exfat_de_iter de_iter;
};
@@ -96,12 +96,12 @@ static void usage(const char *name)
static void free_exfat2img(struct exfat2img *ei)
{
+ if (ei->scan_bdesc)
+ exfat_free_buffer(ei->exfat, ei->scan_bdesc);
if (ei->exfat)
exfat_free_exfat(ei->exfat);
- if (ei->dump_bdesc)
- exfat_free_buffer(ei->dump_bdesc, 2);
- if (ei->scan_bdesc)
- exfat_free_buffer(ei->scan_bdesc, 2);
+ if (ei->dump_cluster)
+ free(ei->dump_cluster);
if (ei->out_fd)
close(ei->out_fd);
if (ei->bdev.dev_fd)
@@ -118,17 +118,13 @@ static int create_exfat2img(struct exfat2img *ei,
if (!ei->exfat)
return -ENOMEM;
- ei->dump_bdesc = exfat_alloc_buffer(2,
- ei->exfat->clus_size,
- ei->exfat->sect_size);
- if (!ei->dump_bdesc) {
+ ei->dump_cluster = malloc(ei->exfat->clus_size);
+ if (!ei->dump_cluster) {
err = -ENOMEM;
goto err;
}
- ei->scan_bdesc = exfat_alloc_buffer(2,
- ei->exfat->clus_size,
- ei->exfat->sect_size);
+ ei->scan_bdesc = exfat_alloc_buffer(ei->exfat);
if (!ei->scan_bdesc) {
err = -ENOMEM;
goto err;
@@ -180,8 +176,7 @@ static ssize_t dump_range(struct exfat2img *ei, off_t start, off_t end)
len = (size_t)MIN(end - start, exfat->clus_size);
ret = exfat_read(exfat->blk_dev->dev_fd,
- ei->dump_bdesc[0].buffer,
- len, start);
+ ei->dump_cluster, len, start);
if (ret != (ssize_t)len) {
exfat_err("failed to read %llu bytes at %llu\n",
(unsigned long long)len,
@@ -189,8 +184,7 @@ static ssize_t dump_range(struct exfat2img *ei, off_t start, off_t end)
return -EIO;
}
- ret = pwrite(ei->out_fd, ei->dump_bdesc[0].buffer,
- len, start);
+ ret = pwrite(ei->out_fd, ei->dump_cluster, len, start);
if (ret != (ssize_t)len) {
exfat_err("failed to write %llu bytes at %llu\n",
(unsigned long long)len,
@@ -552,7 +546,7 @@ out:
}
static int dump_bytes_to_stdout(struct exfat2img *ei,
- off_t start, off_t end_excl, bool fill_zero)
+ off_t start, off_t end_excl)
{
struct exfat *exfat = ei->exfat;
size_t len;
@@ -567,32 +561,21 @@ static int dump_bytes_to_stdout(struct exfat2img *ei,
while (start < end_excl) {
len = (size_t)MIN(end_excl - start, exfat->clus_size);
- if (!fill_zero) {
- ret = exfat_read(exfat->blk_dev->dev_fd,
- ei->dump_bdesc[0].buffer,
- len, start);
- if (ret != (ssize_t)len) {
- exfat_err("failed to read %llu bytes at %llu\n",
- (unsigned long long)len,
- (unsigned long long)start);
- return -EIO;
- }
+ ret = exfat_read(exfat->blk_dev->dev_fd, ei->dump_cluster,
+ len, start);
+ if (ret != (ssize_t)len) {
+ exfat_err("failed to read %llu bytes at %llu\n",
+ (unsigned long long)len,
+ (unsigned long long)start);
+ return -EIO;
+ }
- ret = write(ei->out_fd, ei->dump_bdesc[0].buffer, len);
- if (ret != (ssize_t)len) {
- exfat_err("failed to write %llu bytes at %llu\n",
- (unsigned long long)len,
- (unsigned long long)start);
- return -EIO;
- }
- } else {
- ret = write(ei->out_fd, exfat->zero_cluster, len);
- if (ret != (ssize_t)len) {
- exfat_err("failed to write %llu bytes at %llu\n",
- (unsigned long long)len,
- (unsigned long long)start);
- return -EIO;
- }
+ ret = write(ei->out_fd, ei->dump_cluster, len);
+ if (ret != (ssize_t)len) {
+ exfat_err("failed to write %llu bytes at %llu\n",
+ (unsigned long long)len,
+ (unsigned long long)start);
+ return -EIO;
}
start += len;
@@ -644,8 +627,7 @@ static int dump_clusters_to_stdout(struct exfat2img *ei,
start_off = exfat_c2o(ei->exfat, clu);
end_off_excl = exfat_c2o(ei->exfat, clu + cc_clu_count);
- if (dump_bytes_to_stdout(ei, start_off, end_off_excl,
- false) < 0)
+ if (dump_bytes_to_stdout(ei, start_off, end_off_excl) < 0)
return -EIO;
} else {
ei->stdout_offset += (off_t)cc_clu_count * ei->exfat->clus_size;
@@ -665,7 +647,7 @@ static int dump_to_stdout(struct exfat2img *ei)
start_off = 0;
end_off = exfat_s2o(exfat, le32_to_cpu(exfat->bs->bsx.clu_offset));
- if (dump_bytes_to_stdout(ei, start_off, end_off, false) < 0) {
+ if (dump_bytes_to_stdout(ei, start_off, end_off) < 0) {
exfat_err("failed to dump boot sectors and FAT tables\n");
return -EIO;
}
@@ -762,7 +744,7 @@ static ssize_t read_stream(int fd, void *buf, size_t len)
static int restore_from_stdin(struct exfat2img *ei)
{
- int in_fd, ret;
+ int in_fd, ret = 0;
unsigned char cc;
unsigned int clu, end_clu;
unsigned int cc_clu_count;
@@ -792,8 +774,8 @@ static int restore_from_stdin(struct exfat2img *ei)
clus_size = le32_to_cpu(ei_hdr.cluster_size);
ei->out_fd = ei->bdev.dev_fd;
- ei->dump_bdesc = exfat_alloc_buffer(2, clus_size, 512);
- if (!ei->dump_bdesc)
+ ei->dump_cluster = malloc(clus_size);
+ if (!ei->dump_cluster)
return -ENOMEM;
/* restore boot regions, and FAT tables */
@@ -802,7 +784,7 @@ static int restore_from_stdin(struct exfat2img *ei)
out_end_off_excl = le32_to_cpu(ei_hdr.heap_clus_offset);
while (out_start_off < out_end_off_excl) {
len = MIN(out_end_off_excl - out_start_off, clus_size);
- if (read_stream(in_fd, ei->dump_bdesc[0].buffer, len) != (ssize_t)len) {
+ if (read_stream(in_fd, ei->dump_cluster, len) != (ssize_t)len) {
exfat_err("failed to read first meta region. %llu ~ %llu\n",
(unsigned long long)in_start_off,
(unsigned long long)in_start_off + len);
@@ -810,7 +792,7 @@ static int restore_from_stdin(struct exfat2img *ei)
goto out;
}
- if (pwrite(ei->out_fd, ei->dump_bdesc[0].buffer, len, out_start_off)
+ if (pwrite(ei->out_fd, ei->dump_cluster, len, out_start_off)
!= (ssize_t)len) {
exfat_err("failed to write first meta region. %llu ~ %llu\n",
(unsigned long long)out_start_off,
@@ -856,7 +838,7 @@ static int restore_from_stdin(struct exfat2img *ei)
if (cc == EI_CC_COPY_1 || cc == EI_CC_COPY_2) {
end_clu = clu + cc_clu_count;
while (clu < end_clu) {
- if (read_stream(in_fd, ei->dump_bdesc[0].buffer,
+ if (read_stream(in_fd, ei->dump_cluster,
clus_size) != (ssize_t)clus_size) {
exfat_err("failed to read range %llu ~ %llu\n",
(unsigned long long)in_start_off,
@@ -864,7 +846,7 @@ static int restore_from_stdin(struct exfat2img *ei)
ret = -EIO;
goto out;
}
- if (pwrite(ei->out_fd, ei->dump_bdesc[0].buffer,
+ if (pwrite(ei->out_fd, ei->dump_cluster,
clus_size, out_start_off) != (ssize_t)clus_size) {
exfat_err("failed to write range %llu ~ %llu\n",
(unsigned long long)out_start_off,
@@ -890,8 +872,11 @@ static int restore_from_stdin(struct exfat2img *ei)
}
}
out:
- fsync(ei->out_fd);
- exfat_free_buffer(ei->dump_bdesc, 2);
+ if (fsync(ei->out_fd)) {
+ exfat_err("failed to fsync: %d\n", errno);
+ ret = -EIO;
+ }
+ free(ei->dump_cluster);
return ret;
}