]> git.sven.stormbind.net Git - sven/exfatprogs.git/blobdiff - exfat2img/exfat2img.c
releasing package exfatprogs version 1.2.3-1
[sven/exfatprogs.git] / exfat2img / exfat2img.c
index 81e86d2f12b4da5132e9b1e5b6fe54bcba53d104..bd9db444ca82bdea9561d8e2e67bbf1a8d31798b 100644 (file)
@@ -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;
        }
@@ -754,7 +736,7 @@ static ssize_t read_stream(int fd, void *buf, size_t len)
                } else if (ret == 0) {
                        return 0;
                }
-               buf += (size_t)ret;
+               buf = (char *)buf + (size_t)ret;
                read_len += (size_t)ret;
        }
        return read_len;
@@ -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;
 }