btrfs-progs: convert: Fix offset-by-one error in read_data_extent()
[platform/upstream/btrfs-progs.git] / bcp
diff --git a/bcp b/bcp
index 926d320..e7ca641 100755 (executable)
--- a/bcp
+++ b/bcp
 import sys, os, stat, fcntl
 from optparse import OptionParser
 
-def copylink(srcname, dst, filename, statinfo):
-    dstname = os.path.join(dst, filename)
+def copylink(srcname, dst, filename, statinfo, force_name):
+    dstname = os.path.join(dst, force_name or filename)
     if not os.path.exists(dstname):
         link_target = os.readlink(srcname)
         os.symlink(link_target, dstname)
 
-def copydev(srcname, dst, filename, statinfo):
+def copydev(srcname, dst, filename, statinfo, force_name):
     devbits = statinfo.st_mode & (stat.S_IFBLK | stat.S_IFCHR)
     mode = stat.S_IMODE(statinfo.st_mode) | devbits
-    dstname = os.path.join(dst, filename)
+    dstname = os.path.join(dst, force_name or filename)
     if not os.path.exists(dstname):
         os.mknod(dstname, mode, statinfo.st_rdev)
 
-def copyfile(srcname, dst, filename, statinfo):
+def copyfile(srcname, dst, filename, statinfo, force_name):
     written = 0
-    dstname = os.path.join(dst, filename)
+    dstname = os.path.join(dst, force_name or filename)
+
+    st_mode = statinfo.st_mode
+    if stat.S_ISLNK(st_mode):
+        copylink(srcname, dst, part, statinfo, None)
+        return
+    elif stat.S_ISBLK(st_mode) or stat.S_ISCHR(st_mode):
+        copydev(srcname, dst, part, statinfo, None)
+        return
+    elif not stat.S_ISREG(st_mode):
+        return
 
     try:
         os.unlink(dstname)
@@ -85,46 +95,65 @@ if options.link and options.copy:
     options.link = False
 
 
-src = args[0]
-dst = args[1]
-
-if not os.path.exists(dst):
-    os.makedirs(dst)
-
-iter = os.walk(src, topdown=True)
-
-for (dirpath, dirnames, filenames) in iter:
-    for x in dirnames:
-        srcname = os.path.join(dirpath, x)
-        statinfo = os.lstat(srcname)
-
-        if srcname.startswith(src):
-            part = srcname[len(src) + 1:]
-
-        if stat.S_ISLNK(statinfo.st_mode):
-            copylink(srcname, dst, part, statinfo)
-            continue
-
-        dst_dir = os.path.join(dst, part)
-        if not os.path.exists(dst_dir):
-            os.makedirs(dst_dir)
-
-        os.chmod(dst_dir, stat.S_IMODE(statinfo.st_mode))
-        os.chown(dst_dir, statinfo.st_uid, statinfo.st_gid)
-
-    for f in filenames:
-        srcname = os.path.join(dirpath, f)
-        if srcname.startswith(src):
-            part = srcname[len(src) + 1:]
-
-        statinfo = os.lstat(srcname)
-        st_mode = statinfo.st_mode
-
-        if stat.S_ISLNK(st_mode):
-            copylink(srcname, dst, part, statinfo)
+total_args = len(args)
+src_args = total_args - 1
+orig_dst = args[-1]
+
+if src_args > 1:
+    if not os.path.exists(orig_dst):
+        os.makedirs(orig_dst)
+    if not os.path.isdir(orig_dst):
+        sys.stderr.write("Destination %s is not a directory\n" % orig_dst)
+        exit(1)
+
+for srci in xrange(0, src_args):
+    src = args[srci]
+    if os.path.isfile(src):
+        statinfo = os.lstat(src)
+        force_name = None
+        if src_args == 1:
+            if not os.path.isdir(orig_dst):
+                force_name = os.path.basename(orig_dst)
+                orig_dst = os.path.dirname(orig_dst) or '.'
+        copyfile(src, orig_dst, os.path.basename(src), statinfo, force_name)
+        continue
+
+    if src_args > 1 or os.path.exists(orig_dst):
+        dst = os.path.join(orig_dst, os.path.basename(src))
+    else:
+        dst = orig_dst
+
+    if not os.path.exists(dst):
+        os.makedirs(dst)
+        statinfo = os.stat(src)
+        os.chmod(dst, stat.S_IMODE(statinfo.st_mode))
+        os.chown(dst, statinfo.st_uid, statinfo.st_gid)
+        
+    iter = os.walk(src, topdown=True)
+
+    for (dirpath, dirnames, filenames) in iter:
+        for x in dirnames:
+            srcname = os.path.join(dirpath, x)
+            statinfo = os.lstat(srcname)
+
+            part = os.path.relpath(srcname, src)
+
+            if stat.S_ISLNK(statinfo.st_mode):
+                copylink(srcname, dst, part, statinfo, None)
+                continue
+
+            dst_dir = os.path.join(dst, part)
+            if not os.path.exists(dst_dir):
+                os.makedirs(dst_dir)
+
+            os.chmod(dst_dir, stat.S_IMODE(statinfo.st_mode))
+            os.chown(dst_dir, statinfo.st_uid, statinfo.st_gid)
+
+        for f in filenames:
+            srcname = os.path.join(dirpath, f)
+            part = os.path.relpath(srcname, src)
+
+            statinfo = os.lstat(srcname)
+            copyfile(srcname, dst, part, statinfo, None)
 
-        elif stat.S_ISBLK(st_mode) or stat.S_ISCHR(st_mode):
-            copydev(srcname, dst, part, statinfo)
 
-        elif stat.S_ISREG(st_mode):
-            copyfile(srcname, dst, part, statinfo)