Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package partclone for openSUSE:Factory 
checked in at 2022-05-05 23:07:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/partclone (Old)
 and      /work/SRC/openSUSE:Factory/.partclone.new.1538 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "partclone"

Thu May  5 23:07:04 2022 rev:19 rq:975103 version:0.3.20

Changes:
--------
--- /work/SRC/openSUSE:Factory/partclone/partclone.changes      2022-03-28 
17:01:58.413084497 +0200
+++ /work/SRC/openSUSE:Factory/.partclone.new.1538/partclone.changes    
2022-05-05 23:07:43.617657182 +0200
@@ -1,0 +2,7 @@
+Tue May  3 18:10:04 UTC 2022 - Ferdinand Thiessen <[email protected]>
+
+- Update to version 0.3.20:
+  * Fix apfs support
+  * Add stdout support
+
+-------------------------------------------------------------------

Old:
----
  partclone-0.3.19.tar.gz

New:
----
  partclone-0.3.20.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ partclone.spec ++++++
--- /var/tmp/diff_new_pack.0H3Bnu/_old  2022-05-05 23:07:44.133657826 +0200
+++ /var/tmp/diff_new_pack.0H3Bnu/_new  2022-05-05 23:07:44.137657830 +0200
@@ -18,7 +18,7 @@
 
 
 Name:           partclone
-Version:        0.3.19
+Version:        0.3.20
 Release:        0
 Summary:        File System Clone Utilities
 License:        GPL-2.0-or-later

++++++ partclone-0.3.19.tar.gz -> partclone-0.3.20.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/partclone-0.3.19/README.md 
new/partclone-0.3.20/README.md
--- old/partclone-0.3.19/README.md      2022-03-18 05:25:33.000000000 +0100
+++ new/partclone-0.3.20/README.md      2022-04-27 08:56:42.000000000 +0200
@@ -48,4 +48,8 @@
 
     `partclone.chkimg -s sda1.img`
 
+Limitations:
+
+  - Filesystem being backedup must be unmounted and inaccessible to other 
programs.
+
 For more info about partclone, check our website http://partclone.org or 
github-wiki.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/partclone-0.3.19/configure.ac 
new/partclone-0.3.20/configure.ac
--- old/partclone-0.3.19/configure.ac   2022-03-18 05:25:33.000000000 +0100
+++ new/partclone-0.3.20/configure.ac   2022-04-27 08:56:42.000000000 +0200
@@ -1,4 +1,4 @@
-AC_INIT([Partclone],[0.3.19],[[email protected]])
+AC_INIT([Partclone],[0.3.20],[[email protected]])
 AM_INIT_AUTOMAKE([-Wall foreign])
 AM_GNU_GETTEXT_VERSION([0.16.1])
 AM_GNU_GETTEXT([external])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/partclone-0.3.19/src/apfsclone.c 
new/partclone-0.3.20/src/apfsclone.c
--- old/partclone-0.3.19/src/apfsclone.c        2022-03-18 05:25:33.000000000 
+0100
+++ new/partclone-0.3.20/src/apfsclone.c        2022-04-27 08:56:42.000000000 
+0200
@@ -29,13 +29,81 @@
 #include "progress.h"
 #include "fs_common.h"
 
+static void *get_spaceman_buf(int fd, const struct nx_superblock_t *nxsb)
+{
+    uint32_t block_size = nxsb->nx_block_size;
+    uint64_t base = nxsb->nx_xp_desc_base;
+    uint32_t blocks = nxsb->nx_xp_desc_blocks;
+    int found_nxsb = 0;
+    checkpoint_map_phys_t *cpm = NULL;
+    struct spaceman_phys_t *ret = NULL;
+    obj_phys_t *obj;
+    const uint32_t type_checkpoint_map =
+       (OBJ_PHYSICAL | OBJECT_TYPE_CHECKPOINT_MAP);
+    const uint32_t type_spaceman = (OBJ_EPHEMERAL | OBJECT_TYPE_SPACEMAN);
+    uint32_t i;
+
+    if (base >> 63 || blocks >> 31)
+       log_mesg(0, 1, 1, fs_opt.debug, "%s: B-tree checkpoint descriptor area 
not supported\n", __FILE__);
+    obj = malloc(block_size);
+    if (!obj)
+       log_mesg(0, 1, 1, fs_opt.debug, "%s: malloc error %s\n", __FILE__, 
strerror(errno));
+    for (; blocks > 0; base++, blocks--) {
+       if (pread(fd, obj, block_size, base * block_size) != block_size)
+           log_mesg(0, 1, 1, fs_opt.debug, "%s: pread error %s\n", __FILE__, 
strerror(errno));
+       if (obj->o_type == nxsb->nx_o.o_type) {
+           /* Sanity check: *nxsb has a copy of latest nx_superblock
+            * if the filesystem is unmounted cleanly. */
+           if (obj->o_xid < nxsb->nx_o.o_xid)
+               continue;
+           if (obj->o_xid > nxsb->nx_o.o_xid)
+               log_mesg(0, 1, 1, fs_opt.debug, "%s: newer nx_superblock found 
in descriptor\n", __FILE__);
+           found_nxsb = 1;
+       }
+       if (obj->o_type == type_checkpoint_map) {
+           /* Find latest checkpoint_map_phys_t */
+           if (!cpm || cpm->cpm_o.o_xid < obj->o_xid) {
+               if (!cpm)
+                   cpm = malloc(block_size);
+               if (!cpm)
+                   log_mesg(0, 1, 1, fs_opt.debug, "%s: malloc error %s\n", 
__FILE__, strerror(errno));
+               memcpy(cpm, obj, block_size);
+           }
+       }
+    }
+    free(obj);
+
+    if (!found_nxsb)
+       log_mesg(0, 1, 1, fs_opt.debug, "%s: nx_superblock not found in 
descriptor\n", __FILE__);
+    if (!cpm)
+       log_mesg(0, 1, 1, fs_opt.debug, "%s: checkpoint_map_phys not found in 
descriptor\n", __FILE__);
+    if (!(cpm->cpm_flags & CHECKPOINT_MAP_LAST))
+       log_mesg(0, 1, 1, fs_opt.debug, "%s: multiple checkpoint_map_phys not 
supported\n", __FILE__);
+    for (i = 0; i < cpm->cpm_count; i++) {
+       if (cpm->cpm_map[i].cpm_oid == nxsb->nx_spaceman_oid &&
+           cpm->cpm_map[i].cpm_type == type_spaceman) {
+           ret = malloc(cpm->cpm_map[i].cpm_size);
+           if (!ret)
+               log_mesg(0, 1, 1, fs_opt.debug, "%s: malloc error %s\n", 
__FILE__, strerror(errno));
+           if (pread(fd, ret, cpm->cpm_map[i].cpm_size,
+                     cpm->cpm_map[i].cpm_paddr * block_size) !=
+               cpm->cpm_map[i].cpm_size)
+               log_mesg(0, 1, 1, fs_opt.debug, "%s: pread error %s\n", 
__FILE__, strerror(errno));
+           break;
+       }
+    }
+    free(cpm);
+    if (!ret)
+       log_mesg(0, 1, 1, fs_opt.debug, "%s: spaceman not found\n", __FILE__);
+    return ret;
+}
+
 int APFSDEV;
 struct nx_superblock_t nxsb;
 
 /// get_apfs_free_count
 static uint64_t get_apfs_free_count(){
 
-    int block_size = 4096;
     size_t size = 0;
 
     struct spaceman_phys_t spaceman;
@@ -44,14 +112,12 @@
     int sd = 0;
     int cnt = 0;
     int total_cnt = 0;
-    uint64_t read_size = 0;
     uint64_t free_count = 0;
     uint64_t total_free_count = 0;
 
-    spaceman_buf = (char *)malloc(block_size*nxsb.nx_xp_data_len);
-    memset(spaceman_buf, 0, block_size*nxsb.nx_xp_data_len); // not sure what 
is real size
-    read_size = pread(APFSDEV, spaceman_buf,  block_size*nxsb.nx_xp_data_len, 
nxsb.nx_xp_data_base*block_size);
+    spaceman_buf = get_spaceman_buf(APFSDEV, &nxsb);
     memcpy(&spaceman, spaceman_buf, sizeof(spaceman));
+    free(spaceman_buf);
     log_mesg(2, 0, 0, fs_opt.debug, "%s: sm_block_size %x\n", __FILE__, 
spaceman.sm_block_size);
     log_mesg(2, 0, 0, fs_opt.debug, "%s: blocks_per_chunk %x\n", __FILE__, 
spaceman.sm_blocks_per_chunk);
     log_mesg(2, 0 ,0, fs_opt.debug, "%s: sd count=%i\n", __FILE__, sd);
@@ -109,7 +175,7 @@
     int start = 0;
     int bit_size = 1;
 
-    uint32_t block_size = 4096;
+    uint32_t block_size;
     size_t size = 0;
 
     struct spaceman_phys_t spaceman;
@@ -149,9 +215,7 @@
         pc_set_bit(block, bitmap, fs_info.totalblock);
     }
 
-    spaceman_buf = (char *)malloc(block_size);
-    memset(spaceman_buf, 0, block_size);
-    read_size = pread(APFSDEV, spaceman_buf, block_size, 
nxsb.nx_xp_data_base*block_size);
+    spaceman_buf = get_spaceman_buf(APFSDEV, &nxsb);
     memcpy(&spaceman, spaceman_buf, sizeof(spaceman));
 
     block_size = nxsb.nx_block_size;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/partclone-0.3.19/src/apfsclone.h 
new/partclone-0.3.20/src/apfsclone.h
--- old/partclone-0.3.19/src/apfsclone.h        2022-03-18 05:25:33.000000000 
+0100
+++ new/partclone-0.3.20/src/apfsclone.h        2022-04-27 08:56:42.000000000 
+0200
@@ -385,3 +385,23 @@
 };
 
 
+struct checkpoint_mapping {
+       le_uint32_t cpm_type;
+       le_uint32_t cpm_subtype;
+       le_uint32_t cpm_size;
+       le_uint32_t cpm_pad;
+       le_oid_t cpm_fs_oid;
+       le_oid_t cpm_oid;
+       le_oid_t cpm_paddr;
+};
+typedef struct checkpoint_mapping checkpoint_mapping_t;
+
+struct checkpoint_map_phys {
+       obj_phys_t cpm_o;
+       le_uint32_t cpm_flags;
+       le_uint32_t cpm_count;
+       checkpoint_mapping_t cpm_map[];
+};
+typedef struct checkpoint_map_phys checkpoint_map_phys_t;
+
+const uint32_t CHECKPOINT_MAP_LAST = 0x00000001;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/partclone-0.3.19/src/main.c 
new/partclone-0.3.20/src/main.c
--- old/partclone-0.3.19/src/main.c     2022-03-18 05:25:33.000000000 +0100
+++ new/partclone-0.3.20/src/main.c     2022-04-27 08:56:42.000000000 +0200
@@ -98,6 +98,8 @@
        file_system_info fs_info;   /// description of the file system
        image_options    img_opt;
 
+       int target_stdout = 0;
+
        init_fs_info(&fs_info);
        init_image_options(&img_opt);
 
@@ -170,6 +172,9 @@
                log_mesg(0, 1, 1, debug, "Error exit\n");
            }
        }
+       if (strcmp(target, "-") == 0) {
+               target_stdout = 1;
+       }
 #else
        dfw = -1;
 #endif
@@ -222,7 +227,7 @@
                update_used_blocks_count(&fs_info, bitmap);
 
                /* skip check free space while torrent_only on */
-               if ((opt.check) && (opt.torrent_only == 0)) {
+               if ((opt.check) && (opt.torrent_only == 0) && (!target_stdout)) 
{
 
                        unsigned long long needed_space = 0;
 
@@ -272,7 +277,9 @@
 
 #ifndef CHKIMG
                /// check the dest partition size.
-               if (opt.restore_raw_file)
+               if (target_stdout)
+                       ;
+               else if (opt.restore_raw_file)
                        check_free_space(target, fs_info.device_size);
                else if ((opt.check) && (opt.blockfile == 0))
                        check_size(&dfw, fs_info.device_size);
@@ -312,7 +319,7 @@
                read_bitmap(source, fs_info, bitmap, pui);
 
                /// check the dest partition size.
-               if (opt.dd && opt.check) {
+               if (opt.dd && opt.check && !target_stdout) {
                    if (!opt.restore_raw_file)
                        check_size(&dfw, fs_info.device_size);
                    else
@@ -327,6 +334,9 @@
                    fs_info.device_size = get_partition_size(&dfr);
                    read_super_blocks(source, &fs_info);
                }else{
+                   if (target_stdout) {
+                       log_mesg(0, 1, 1, debug, "%s, %i, stdout is not 
supported\n", __func__, __LINE__);
+                   }
                    if (stat(target, &st_dev) != -1) {
                        if (S_ISBLK(st_dev.st_mode)) 
                            fs_info.device_size = get_partition_size(&dfw);
@@ -357,7 +367,7 @@
 
                /// check the dest partition size.
                /* skip check free space while torrent_only on */
-               if ((opt.check) && (opt.torrent_only == 0)) {
+               if ((opt.check) && (opt.torrent_only == 0) && (!target_stdout)) 
{
                    struct stat target_stat;
                    if ((stat(opt.target, &target_stat) != -1) && 
(strcmp(opt.target, "-") != 0)) {
                        if (S_ISBLK(target_stat.st_mode)) 
@@ -620,6 +630,7 @@
                unsigned int blocks_in_cs, buffer_size, read_offset;
                unsigned char checksum[cs_size];
                char *read_buffer, *write_buffer;
+               char *empty_buffer = NULL;
                unsigned long long blocks_used_fix = 0, test_block = 0;
 
                // SHA1 for torrent info
@@ -652,10 +663,18 @@
                        log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", 
__func__, __LINE__);
                }
 
+               if (target_stdout) {
+                       empty_buffer = malloc(block_size);
+                       if (empty_buffer == NULL) {
+                               log_mesg(0, 1, 1, debug, "%s, %i, not enough 
memory\n", __func__, __LINE__);
+                       }
+                       memset(empty_buffer, 0, block_size);
+               }
+
 #ifndef CHKIMG
                /// seek to the first
                if (opt.blockfile == 0) {
-                   if (lseek(dfw, opt.offset, SEEK_SET) == (off_t)-1){
+                   if (skip_bytes(&dfw, empty_buffer, block_size, opt.offset, 
&opt) != opt.offset){
                        log_mesg(0, 1, 1, debug, "target seek ERROR:%s\n", 
strerror(errno));
                    }
                }
@@ -682,7 +701,7 @@
                block_id = 0;
                do {
                        unsigned int i;
-                       unsigned long long blocks_written, bytes_skip;
+                       unsigned long long blocks_written, blocks_skip;
                        unsigned int read_size;
                        // max chunk to read using one read(2) syscall
                        unsigned int blocks_read = copied + buffer_capacity < 
blocks_used ?
@@ -772,19 +791,22 @@
                                unsigned int blocks_write = 0;
 
                                /// count bytes to skip
-                               for (bytes_skip = 0;
-                                    block_id < blocks_total &&
-                                    !pc_test_bit(block_id, bitmap, 
fs_info.totalblock);
-                                    block_id++, bytes_skip += block_size);
+                               for (blocks_skip = 0;
+                                    block_id + blocks_skip < blocks_total &&
+                                    !pc_test_bit(block_id + blocks_skip, 
bitmap, fs_info.totalblock);
+                                    blocks_skip++);
 
 #ifndef CHKIMG
                                /// skip empty blocks
                                if (blocks_write == 0) {
-                                   if (opt.blockfile == 0 && bytes_skip > 0 && 
lseek(dfw, (off_t)bytes_skip, SEEK_CUR) == (off_t)-1) {
+                                   if (opt.blockfile == 0 && blocks_skip > 0 
&& skip_blocks(&dfw, empty_buffer, block_size, blocks_skip, &opt, &block_id) < 
0) {
                                        log_mesg(0, 1, 1, debug, "target seek 
ERROR:%s\n", strerror(errno));
                                    }
+                                   blocks_skip = 0;
                                }
 #endif
+                               if (blocks_skip > 0)
+                                   block_id += blocks_skip;
 
                                /// blocks to write
                                for (blocks_write = 0;
@@ -842,6 +864,15 @@
 
                free(write_buffer);
                free(read_buffer);
+               if (empty_buffer) {
+                   if (block_id < blocks_total && skip_blocks(&dfw, 
empty_buffer, block_size, blocks_total - block_id, &opt, &block_id) < 0) {
+                       log_mesg(0, 0, 1, debug, "target seek ERROR:%s\n", 
strerror(errno));
+                   }
+                   if (block_id * block_size < fs_info.device_size && 
skip_bytes(&dfw, empty_buffer, block_size, fs_info.device_size - block_id * 
block_size, &opt) != fs_info.device_size - block_id * block_size) {
+                       log_mesg(0, 0, 1, debug, "target seek ERROR:%s\n", 
strerror(errno));
+                   }
+                   free(empty_buffer);
+               }
 
 #ifndef CHKIMG
                /// restore_raw_file option
@@ -856,6 +887,7 @@
        } else if (opt.dd) {
 
                char *buffer;
+               char *empty_buffer = NULL;
                int block_size = fs_info.block_size;
                unsigned long long blocks_total = fs_info.totalblock;
                int buffer_capacity = block_size < opt.buffer_size ? 
opt.buffer_size / block_size : 1;
@@ -865,10 +897,21 @@
                        log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", 
__func__, __LINE__);
                }
 
+               if (target_stdout) {
+                       empty_buffer = malloc(block_size);
+                       if (empty_buffer == NULL) {
+                               log_mesg(0, 1, 1, debug, "%s, %i, not enough 
memory\n", __func__, __LINE__);
+                       }
+                       memset(empty_buffer, 0, block_size);
+               }
+
                block_id = 0;
 
                if (lseek(dfr, 0, SEEK_SET) == (off_t)-1)
                        log_mesg(0, 1, 1, debug, "source seek ERROR:%d\n", 
strerror(errno));
+               if (skip_bytes(&dfw, empty_buffer, block_size, opt.offset, 
&opt) != opt.offset) {
+                       log_mesg(0, 1, 1, debug, "target seek ERROR:%s\n", 
strerror(errno));
+               }
 
                log_mesg(0, 0, 0, debug, "Total block %llu\n", blocks_total);
 
@@ -888,8 +931,11 @@
                        if (block_id + blocks_skip == blocks_total)
                                break;
 
-                       if (blocks_skip)
-                               block_id += blocks_skip;
+                       if (blocks_skip) {
+                               if (skip_blocks(&dfw, empty_buffer, block_size, 
blocks_skip, &opt, &block_id) < 0) {
+                                       log_mesg(0, 1, 1, debug, "target seek 
ERROR:%s\n", strerror(errno));
+                               }
+                       }
 
                        /// read chunk from source
                        for (blocks_read = 0;
@@ -903,8 +949,6 @@
                        offset = (off_t)(block_id * block_size);
                        if (lseek(dfr, offset, SEEK_SET) == (off_t)-1)
                                log_mesg(0, 1, 1, debug, "source seek 
ERROR:%s\n", strerror(errno));
-                       if (lseek(dfw, offset + opt.offset, SEEK_SET) == 
(off_t)-1)
-                               log_mesg(0, 1, 1, debug, "target seek 
ERROR:%s\n", strerror(errno));
 
                        r_size = read_all(&dfr, buffer, blocks_read * 
block_size, &opt);
                        if (r_size != (int)(blocks_read * block_size)) {
@@ -944,6 +988,15 @@
                } while (1);
 
                free(buffer);
+               if (empty_buffer) {
+                       if (block_id < blocks_total && skip_blocks(&dfw, 
empty_buffer, block_size, blocks_total - block_id, &opt, &block_id) < 0) {
+                               log_mesg(0, 0, 1, debug, "write empty 
ERROR:%s\n", strerror(errno));
+                       }
+                       if (block_id * block_size < fs_info.device_size && 
skip_bytes(&dfw, empty_buffer, block_size, fs_info.device_size - block_id * 
block_size, &opt) != fs_info.device_size - block_id * block_size) {
+                               log_mesg(0, 0, 1, debug, "write empty 
ERROR:%s\n", strerror(errno));
+                       }
+                       free(empty_buffer);
+               }
 
                /// restore_raw_file option
                if (opt.restore_raw_file && !pc_test_bit(blocks_total - 1, 
bitmap, fs_info.totalblock)) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/partclone-0.3.19/src/partclone.c 
new/partclone-0.3.20/src/partclone.c
--- old/partclone-0.3.19/src/partclone.c        2022-03-18 05:25:33.000000000 
+0100
+++ new/partclone-0.3.20/src/partclone.c        2022-04-27 08:56:42.000000000 
+0200
@@ -611,15 +611,6 @@
                }
 
        }
-
-#ifndef CHKIMG
-       if (opt->restore) {
-               if ((!strcmp(opt->target, "-")) || (!opt->target)) {
-                       fprintf(stderr, "Partclone can't restore to 
stdout.\nFor help,type: %s -h\n", get_exec_name());
-                       exit(0);
-               }
-       }
-#endif
 }
 
 /**
@@ -1485,10 +1476,10 @@
                return -1;
        }
 
-       if (!realpath(device, real_file)) {
-               free(real_fsname); real_fsname = NULL;
-        if (real_file){ free(real_file); real_file = NULL;}
-               return -1;
+       if (realpath(device, real_file) == NULL) {
+           free(real_fsname); real_fsname = NULL;
+            if (real_file){ free(real_file); real_file = NULL;}
+           return -1;
        }
 
        if ((f = setmntent(MOUNTED, "r")) == 0) {
@@ -1616,13 +1607,16 @@
                                log_mesg(0, 0, 1, debug, "open target fail %s: 
%s (%i)\n", target, strerror(errno), errno);
                        }
                }
+       } else if (((opt->restore) || (opt->dd)) && (opt->blockfile == 0) && 
strcmp(target, "-") == 0) {
+           if ((ret = fileno(stdout)) == -1)
+               log_mesg(0, 1, 1, debug, "clone: open %s(stdout) error\n", 
target);
        } else if (((opt->restore) || (opt->dd) || (ddd_block_device == 1)) && 
(opt->blockfile == 0)) {    /// always is device, restore to device=target
 
                /// check mounted
                mp = malloc(PATH_MAX + 1);
                if (!mp)
                        log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", 
__func__, __LINE__);
-               if (check_mount(target, mp)) {
+               if (check_mount(target, mp) == 1) {
                        log_mesg(0, 0, 1, debug, "device (%s) is mounted at 
%s\n", target, mp);
                        free(mp); mp = NULL;
                        log_mesg(0, 1, 1, debug, "error exit\n");
@@ -1635,7 +1629,11 @@
                /// check block device
                stat(target, &st_dev);
                if (!S_ISBLK(st_dev.st_mode)) {
-                       log_mesg(1, 0, 1, debug, "Warning, did you restore to 
non-block device(%s)?\n", target);
+                    if ((opt->dd) && (!opt->overwrite)){
+                        log_mesg(1, 0, 1, debug, "Warning, device(%s) not 
exist?! Use option --overwrite if you want to CREATE special file\n", target);
+                       log_mesg(0, 1, 1, debug, "error exit\n");
+                    }
+                    log_mesg(1, 0, 1, debug, "Warning, you are doing restore 
to non-block device(%s)?\n", target);
                        flags |= O_CREAT;
                        if (!opt->overwrite)
                                flags |= O_EXCL;
@@ -1773,6 +1771,55 @@
        }
 }
 
+long long skip_bytes(int *fd, char *empty_buffer, unsigned long long 
empty_buffer_size, unsigned long long empty_count, cmd_opt *opt) {
+       long long completed = 0;
+       int w_size;
+       if (empty_count == 0)
+               return 0;
+       if (empty_buffer == NULL) {
+               if (lseek(*fd, empty_count, SEEK_CUR) == (off_t)-1)
+                       return -1;
+               return empty_count;
+       }
+       while (empty_buffer_size < empty_count - completed) {
+               w_size = write_all(fd, empty_buffer, empty_buffer_size, opt);
+               if (w_size < 0)
+                       return w_size;
+               completed += w_size;
+               if (w_size != empty_buffer_size)
+                       return completed;
+       }
+       w_size = write_all(fd, empty_buffer, empty_count - completed, opt);
+       if (w_size < 0)
+               return w_size;
+       completed += w_size;
+       return completed;
+}
+
+int skip_blocks(int *fd, char *empty_buffer, unsigned long long 
empty_buffer_size, unsigned long long empty_count, cmd_opt *opt, unsigned long 
long *block_id) {
+       int w_size;
+       if (empty_count == 0)
+               return 0;
+       if (empty_buffer == NULL) {
+               if (lseek(*fd, empty_count * empty_buffer_size, SEEK_CUR) ==
+                   (off_t)-1)
+                       return -1;
+               if (block_id)
+                       *block_id += empty_count;
+               return 0;
+       }
+       for (unsigned long long i = 0; i < empty_count; i++) {
+               w_size = write_all(fd, empty_buffer, empty_buffer_size, opt);
+               if (w_size < 0)
+                       return w_size;
+               if (w_size != empty_buffer_size)
+                       return -1;
+               if (block_id)
+                       ++*block_id;
+       }
+       return 0;
+}
+
 /// print options to log file
 void print_opt(cmd_opt opt) {
        int debug = opt.debug;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/partclone-0.3.19/src/partclone.h 
new/partclone-0.3.20/src/partclone.h
--- old/partclone-0.3.19/src/partclone.h        2022-03-18 05:25:33.000000000 
+0100
+++ new/partclone-0.3.20/src/partclone.h        2022-04-27 08:56:42.000000000 
+0200
@@ -286,6 +286,8 @@
 extern int io_all(int *fd, char *buffer, unsigned long long count, int 
do_write, cmd_opt *opt);
 extern void sync_data(int fd, cmd_opt* opt);
 extern void rescue_sector(int *fd, unsigned long long pos, char *buff, cmd_opt 
*opt);
+extern long long skip_bytes(int *fd, char *empty_buffer, unsigned long long 
empty_buffer_size, unsigned long long empty_count, cmd_opt *opt);
+extern int skip_blocks(int *fd, char *empty_buffer, unsigned long long 
empty_buffer_size, unsigned long long empty_count, cmd_opt *opt, unsigned long 
long *block_id);
 
 extern unsigned long long cnv_blocks_to_bytes(unsigned long long block_offset, 
unsigned int block_count, unsigned int block_size, const image_options* 
img_opt);
 extern unsigned long long get_bitmap_size_on_disk(const file_system_info* 
fs_info, const image_options* img_opt, cmd_opt* opt);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/partclone-0.3.19/src/version.h 
new/partclone-0.3.20/src/version.h
--- old/partclone-0.3.19/src/version.h  2022-03-18 05:25:33.000000000 +0100
+++ new/partclone-0.3.20/src/version.h  2022-04-27 08:56:42.000000000 +0200
@@ -3,5 +3,5 @@
  * WHETHER THEY ARE BUILT BY OTHERS OR DURING DEVELOPMENT OR FOR THE
  * OFFICIAL PARTCLONE RELEASES.
  */
-#define git_version  "ed1efc658df74e01a3d01bf7f9a617bf9917f8fd"
+#define git_version  "4fed91cb18cb147b139737d645c6ecc56256a87c"
 

Reply via email to