X-Git-Url: https://git.sven.stormbind.net/?a=blobdiff_plain;f=exfat2img%2Fexfat2img.c;h=3f835889ad6baacc02dc9cf9b29ac5fd2c2b797f;hb=HEAD;hp=be1f0f3861857c4ad034546a9f9616ad3f8786b3;hpb=0a7a8b470671035ad0c2d8dc0d7714d06921273d;p=sven%2Fexfatprogs.git diff --git a/exfat2img/exfat2img.c b/exfat2img/exfat2img.c index be1f0f3..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, @@ -319,7 +313,7 @@ static int read_file_dentry_set(struct exfat_de_iter *iter, if (!node) return -ENOMEM; - for (i = 2; i <= file_de->file_num_ext; i++) { + for (i = 2; i <= MIN(file_de->file_num_ext, 1 + MAX_NAME_DENTRIES); i++) { ret = exfat_de_iter_get(iter, i, &dentry); if (ret || dentry->type != EXFAT_NAME) break; @@ -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; }