]> arthur.barton.de Git - bup.git/commitdiff
Stop forcing LC_CTYPE=ISO-8859-1
authorRob Browning <rlb@defaultvalue.org>
Mon, 25 May 2020 19:46:52 +0000 (14:46 -0500)
committerRob Browning <rlb@defaultvalue.org>
Sun, 5 Jul 2020 16:16:22 +0000 (11:16 -0500)
Now that we've made adjustments to work around all the Python 3
problems with non-Unicode data (argv, env vars, readline, acls, users,
groups, hostname, etc.), and added randomized binary path and argv
testing, stop overriding the LC_CTYPE since that should no longer be
necessary.

Thanks to Johannes Berg for nudging me to consider whether we might
now be in a position to do this (with a bit more work), and for quite
a bit of help getting all the precursors in place once we thought it
was feasible.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Tested-by: Rob Browning <rlb@defaultvalue.org>
60 files changed:
Makefile
README.md
bup [changed from symlink to file mode: 0755]
buptest.py
config/configure
dev/install-python-script [new file with mode: 0755]
dev/replace [deleted file]
lib/bup/compat.py
lib/bup/io.py
lib/bup/ls.py
lib/bup/path.py
lib/bup/t/thelpers.py
lib/cmd/bloom-cmd.py
lib/cmd/bup
lib/cmd/cat-file-cmd.py
lib/cmd/daemon-cmd.py
lib/cmd/damage-cmd.py
lib/cmd/drecurse-cmd.py
lib/cmd/fsck-cmd.py
lib/cmd/ftp-cmd.py
lib/cmd/fuse-cmd.py
lib/cmd/gc-cmd.py
lib/cmd/get-cmd.py
lib/cmd/help-cmd.py
lib/cmd/import-duplicity-cmd.py
lib/cmd/index-cmd.py
lib/cmd/init-cmd.py
lib/cmd/join-cmd.py
lib/cmd/list-idx-cmd.py
lib/cmd/ls-cmd.py
lib/cmd/margin-cmd.py
lib/cmd/memtest-cmd.py
lib/cmd/meta-cmd.py
lib/cmd/midx-cmd.py
lib/cmd/mux-cmd.py
lib/cmd/on--server-cmd.py
lib/cmd/on-cmd.py
lib/cmd/prune-older-cmd.py
lib/cmd/python-cmd.sh [deleted file]
lib/cmd/random-cmd.py
lib/cmd/restore-cmd.py
lib/cmd/rm-cmd.py
lib/cmd/save-cmd.py
lib/cmd/server-cmd.py
lib/cmd/split-cmd.py
lib/cmd/tag-cmd.py
lib/cmd/tick-cmd.py
lib/cmd/version-cmd.py
lib/cmd/web-cmd.py
lib/cmd/xstat-cmd.py
t/echo-argv-bytes
t/hardlink-sets
t/ns-timestamp-resolutions
t/sparse-test-data
t/subtree-hash
t/test-ftp
t/test-get
t/test-on.sh
t/test-prune-older
t/test-save-errors

index d7a076e8d4d588ab0fd338042a219d59722804ce..7dd7cdfa77d7d362c4c69803fefa844cd9fae553 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -72,15 +72,6 @@ all: $(bup_deps) Documentation/all $(current_sampledata)
 $(current_sampledata):
        t/configure-sampledata --setup
 
-
-bup_libdir="$script_home/../lib"  # bup_libdir will be adjusted during install
-
-define install-bup-python
-  set -e; \
-  sed -e 's|.*# bup_libdir will be adjusted during install|bup_libdir="$$script_home/.."|' $1 > $2; \
-  chmod 0755 $2;
-endef
-
 PANDOC ?= $(shell type -p pandoc)
 
 ifeq (,$(PANDOC))
@@ -113,9 +104,11 @@ install: all
        test -z "$(man_roff)" || $(INSTALL) -m 0644 $(man_roff) $(dest_mandir)/man1
        test -z "$(man_html)" || install -d $(dest_docdir)
        test -z "$(man_html)" || $(INSTALL) -m 0644 $(man_html) $(dest_docdir)
-       $(INSTALL) -pm 0755 cmd/bup $(dest_libdir)/cmd/
-       $(INSTALL) -pm 0755 cmd/bup-* $(dest_libdir)/cmd/
-       $(call install-bup-python,cmd/bup-python,"$(dest_libdir)/cmd/bup-python")
+       dev/install-python-script lib/cmd/bup "$(dest_libdir)/cmd/bup"
+       set -e; \
+       for cmd in $$(ls cmd/bup-* | grep -v cmd/bup-python); do \
+         dev/install-python-script "$$cmd" "$(dest_libdir)/$$cmd"; \
+       done
        cd "$(dest_bindir)" && \
          ln -sf "$$($(bup_python) -c 'import os; print(os.path.relpath("$(abspath $(dest_libdir))/cmd/bup"))')"
        set -e; \
@@ -260,12 +253,8 @@ check: test
 distcheck: all
        ./wvtest run t/test-release-archive.sh
 
-cmd/bup-python: cmd/python-cmd.sh config/config.var/bup-python
-       "$$(cat config/config.var/bup-python)" dev/replace -l '@bup_python@' \
-         "$$(dev/shquote < config/config.var/bup-python)" \
-         < "$<" > "$@".$$PPID.tmp
-       chmod +x "$@".$$PPID.tmp
-       mv "$@".$$PPID.tmp "$@"
+cmd/bup-python: config/config.var/bup-python
+       cd cmd && ln -sf "$$(< $(CURDIR)/config/config.var/bup-python)" bup-python
 
 long-test: export BUP_TEST_LEVEL=11
 long-test: test
index ae49cce765a82ceb4fc73ce60b8e564f6e25ff98..05fc56f2c1043bac1a6c79dcd66f8b59e2a66673 100644 (file)
--- a/README.md
+++ b/README.md
@@ -80,6 +80,10 @@ Reasons you might want to avoid bup
    Solaris, or Windows (with Cygwin, and maybe with WSL).  Patches to
    support other platforms are welcome.
 
+ - Until resolved, a [glibc bug](https://sourceware.org/bugzilla/show_bug.cgi?id=26034)
+   might cause bup to crash on startup for some (unusual) command line
+   argument values, when bup is configured to use Python 3.
+
  - Any items in "Things that are stupid" below.
 
 
diff --git a/bup b/bup
deleted file mode 120000 (symlink)
index e1c0ca8fe3c485d86ebd7ea8efda66974ccfb873..0000000000000000000000000000000000000000
--- a/bup
+++ /dev/null
@@ -1 +0,0 @@
-lib/cmd/bup
\ No newline at end of file
diff --git a/bup b/bup
new file mode 100755 (executable)
index 0000000000000000000000000000000000000000..0d15289694846be294784ae4a63c42dfbfae9e64
--- /dev/null
+++ b/bup
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# This is just a convenience wrapper.  It's not a symlink because bup
+# finds its code relative to dirname(__file__).
+
+exec $(dirname "$0")/cmd/bup "$@"
index 7c7cc2f37f1d04f13b5094edf285ee382dc1f823..2089fcf5650330a7353b7b29502cc5a46086a0f2 100644 (file)
@@ -11,7 +11,7 @@ import errno, os, subprocess, sys, tempfile
 from wvtest import WVPASSEQ, wvfailure_count
 
 from bup import helpers
-from bup.compat import str_type
+from bup.compat import fsencode, str_type
 from bup.io import byte_stream
 
 
@@ -35,7 +35,7 @@ def no_lingering_errors():
 
 
 # Assumes (of course) this file is at the top-level of the source tree
-_bup_tmp = realpath(dirname(__file__.encode('iso-8859-1')) + b'/t/tmp')
+_bup_tmp = realpath(dirname(fsencode(__file__))) + b'/t/tmp'
 try:
     os.makedirs(_bup_tmp)
 except OSError as e:
@@ -78,9 +78,8 @@ def logcmd(cmd):
     if isinstance(cmd, str_type):
         print(s, file=sys.stderr)
     else:
-        # bytes - for now just continue to pass it through given
-        # bup-python wrapper
-        print(s.decode('iso-8859-1'), file=sys.stderr)
+        # bytes - for now just escape it
+        print(s.decode(errors='backslashreplace'), file=sys.stderr)
 
 def ex(cmd, **kwargs):
     """Print cmd to stderr and then run it as per ex(...).
index 86ecd761a3057c94e51e99c2c2ccb25e6734efc4..3eab5d3b8281cbcecdd3a34df928810101c1202f 100755 (executable)
@@ -58,7 +58,7 @@ expr "$MAKE_VERSION" '>=' '3.81' || AC_FAIL "ERROR: $MAKE must be >= version 3.8
 
 AC_SUB bup_make "$MAKE"
 
-bup_python="$PYTHON"
+bup_python="$(type -p "$PYTHON")"
 test -z "$bup_python" && bup_python="$(bup_find_prog python2.7 '')"
 test -z "$bup_python" && bup_python="$(bup_find_prog python2.6 '')"
 test -z "$bup_python" && bup_python="$(bup_find_prog python2 '')"
diff --git a/dev/install-python-script b/dev/install-python-script
new file mode 100755 (executable)
index 0000000..251a9f8
--- /dev/null
@@ -0,0 +1,37 @@
+#!/bin/sh
+"""": # -*-python-*-
+exec env LC_CTYPE=iso-8859-1 python "$0" ${1+"$@"}
+"""
+
+from __future__ import absolute_import, print_function
+from tempfile import NamedTemporaryFile
+import os, shutil, sys
+
+if sys.version_info[0] >= 3:
+    from shlex import quote
+else:
+    from pipes import quote
+
+src_path, dest_path = sys.argv[1:]
+
+with open(b'config/config.var/bup-python', 'rb') as src:
+    python = src.read()
+
+with NamedTemporaryFile() as tmp:
+    # Replace the section between "Here to end..." and the end of the
+    # preamble with the correct 'exec PYTHON "$0"'.
+    with open(src_path, 'rb') as src:
+        for line in src:
+            if line.startswith(b'# Here to end of preamble replaced during install'):
+                break
+            tmp.write(line)
+        for line in src:
+            if line == b'"""\n':
+                break
+        tmp.write(b'exec %s "$0"\n' % python)
+        tmp.write(b'"""\n')
+        for line in src:
+            tmp.write(line)
+    tmp.flush()
+    shutil.copy(tmp.name, dest_path)
+    os.chmod(dest_path, 0o755)
diff --git a/dev/replace b/dev/replace
deleted file mode 100755 (executable)
index 4ac0c0e..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/sh
-"""": # -*-python-*-
-exec env LC_CTYPE=iso-8859-1 python "$0" ${1+"$@"}
-"""
-
-from __future__ import absolute_import, print_function
-import sys
-
-py_maj = sys.version_info[0]
-
-import argparse
-if py_maj > 2:
-    byte_stream = lambda x: x.buffer
-    from os import fsencode
-else:
-    byte_stream = lambda x: x
-    fsencode = lambda x: x
-
-parser = argparse.ArgumentParser()
-parser.add_argument('-l', nargs=2, metavar=('ORIG', 'NEW'), action='append',
-                    help='literally replace ORIG with NEW')
-opt = parser.parse_args()
-
-sys.stdout.flush()
-with byte_stream(sys.stdin) as stdin:
-    content = stdin.read()
-for orig, new in opt.l:
-    content = content.replace(fsencode(orig), fsencode(new))
-byte_stream(sys.stdout).write(content)
index 37b31f107806d08a37fdf094e0e415850253a4c7..1ed2d0f70c9fc18f7afc2011a2e55381aa047ca4 100644 (file)
@@ -14,17 +14,6 @@ py3 = py_maj >= 3
 if py3:
 
     from os import environb as environ
-
-    lc_ctype = environ.get(b'LC_CTYPE')
-    if lc_ctype and lc_ctype.lower() != b'iso-8859-1':
-        # Because of argv, options.py, pwd, grp, and any number of other issues
-        print('error: bup currently only works with ISO-8859-1, not LC_CTYPE=%s'
-              % lc_ctype.decode(),
-              file=sys.stderr)
-        print('error: this should already have been arranged, so indicates a bug',
-              file=sys.stderr)
-        sys.exit(2)
-
     from os import fsdecode, fsencode
     from shlex import quote
     input = input
@@ -179,24 +168,6 @@ def _configure_argv():
 _configure_argv()
 
 
-def restore_lc_env():
-    # Once we're up and running with iso-8859-1, undo the bup-python
-    # LC_CTYPE hackery, so we don't affect unrelated subprocesses.
-    bup_lc_all = environ.get(b'BUP_LC_ALL')
-    if bup_lc_all:
-        del environ[b'LC_COLLATE']
-        del environ[b'LC_CTYPE']
-        del environ[b'LC_MONETARY']
-        del environ[b'LC_NUMERIC']
-        del environ[b'LC_TIME']
-        del environ[b'LC_MESSAGES']
-        del environ[b'LC_MESSAGES']
-        environ[b'LC_ALL'] = bup_lc_all
-        return
-    bup_lc_ctype = environ.get(b'BUP_LC_CTYPE')
-    if bup_lc_ctype:
-        environ[b'LC_CTYPE'] = bup_lc_ctype
-
 def wrap_main(main):
     """Run main() and raise a SystemExit with the return value if it
     returns, pass along any SystemExit it raises, convert
index 571e9b9102d76fa43b42c7fb283d722b17b0f618..256f562451b4d12400f9ef44674997708f59d87c 100644 (file)
@@ -13,12 +13,6 @@ else:
 
 
 def path_msg(x):
-    """Return a string representation of a path.
-
-    For now, assume that the destination encoding is going to be
-    ISO-8859-1, which it should be, for the primary current
-    destination, stderr, given the current bup-python.
-
-    """
+    """Return a string representation of a path."""
     # FIXME: configurability (might git-config quotePath be involved?)
-    return x.decode(encoding='iso-8859-1')
+    return x.decode(errors='backslashreplace')
index bff04010f40382402c0b6cbbba1723e968f34a3f..8117bd76506eb66da342b4eb5dc9fe458c8e1fb8 100644 (file)
@@ -51,7 +51,7 @@ def item_info(item, name,
         if classification:
             cls = xstat.classification_str(vfs.item_mode(item),
                                            classification == 'all')
-            result += cls.encode('iso-8859-1')
+            result += cls.encode('ascii')
     return result
 
 
index 7dd3905a2ecf22196b333362c0d5e20cd22f455a..fd1c09bd72ab2cbd3c4884ec66742538150f483d 100644 (file)
@@ -1,12 +1,13 @@
 
 from __future__ import absolute_import
-import os
-
+import os, sys
 
 # Eventually, if we physically move the source tree cmd/ to lib/, then
 # we could use realpath here and save some stats...
 
-_libdir = os.path.abspath(os.path.dirname(__file__.encode('iso-8859-1')) + b'/..')
+fsencode = os.fsencode if sys.version_info[0] >= 3 else lambda x: x
+
+_libdir = os.path.abspath(os.path.dirname(fsencode(__file__)) + b'/..')
 _resdir = _libdir
 _exedir = os.path.abspath(_libdir + b'/cmd')
 _exe = os.path.join(_exedir, b'bup')
index 17ee6357debac8960c9130a2ce6a5f1856a4ee17..e05c1f65cc693dae859a4b14cceb91587ea8c008 100644 (file)
@@ -1,7 +1,7 @@
 
 from __future__ import absolute_import
 from time import tzset
-import helpers, math, os, os.path, re, subprocess
+import helpers, math, os, re, subprocess
 
 from wvtest import *
 
index 16d8f46d44d6ed3f6affd7bfbc2e019fee2b3419..fdf8145acb7caaf706446a392e55aa8ad2f7bfb0 100755 (executable)
@@ -17,6 +17,8 @@ exec "$bup_python" "$0"
 from __future__ import absolute_import
 import glob, os, sys, tempfile
 
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
+
 from bup import compat, options, git, bloom
 from bup.compat import argv_bytes, hexstr
 from bup.helpers import (add_error, debug1, handle_ctrl_c, log, progress, qprogress,
index 92807a50254ba244f904ff33628f4fde5bfbec8a..3e9b9190fd56188d7dfad2264728e24b3928d11b 100755 (executable)
@@ -26,10 +26,14 @@ exec "$script_home/bup-python" "$0"
 # end of bup preamble
 
 from __future__ import absolute_import, print_function
+
+import os, sys
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
+
 import errno, getopt, os, re, select, signal, subprocess, sys
 from subprocess import PIPE
 
-from bup.compat import environ, restore_lc_env
+from bup.compat import environ, fsdecode
 from bup.io import path_msg
 
 if sys.version_info[0] != 2 \
@@ -38,8 +42,6 @@ if sys.version_info[0] != 2 \
           file=sys.stderr)
     sys.exit(2)
 
-restore_lc_env()
-
 from bup import compat, path, helpers
 from bup.compat import add_ex_tb, add_ex_ctx, argv_bytes, wrap_main
 from bup.helpers import atoi, columnate, debug1, log, merge_dict, tty_width
@@ -76,7 +78,7 @@ def usage(msg=""):
     cmds = []
     for c in sorted(os.listdir(cmdpath)):
         if c.startswith(b'bup-') and c.find(b'.') < 0:
-            cname = c[4:].decode('iso-8859-1')
+            cname = fsdecode(c[4:])
             if cname not in common:
                 cmds.append(c[4:].decode(errors='backslashreplace'))
     log(columnate(cmds, '    '))
index 849cb45667410882d034a904b6c00d0b263815e6..7fbc256ecd3be9478b45c5e78c976bc0ad9fdc8b 100755 (executable)
@@ -15,7 +15,9 @@ exec "$bup_python" "$0"
 # end of bup preamble
 
 from __future__ import absolute_import
-import re, stat, sys
+import os.path, re, stat, sys
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import compat, options, git, vfs
 from bup.compat import argv_bytes
index d47638eec6074864db76e4eba3e671110eb04f66..5506ea10aa9e085ea4294f874b6277be325be6be 100755 (executable)
@@ -15,7 +15,9 @@ exec "$bup_python" "$0"
 # end of bup preamble
 
 from __future__ import absolute_import
-import sys, getopt, socket, subprocess, fcntl
+import os, sys, getopt, socket, subprocess, fcntl
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import compat, options, path
 from bup.helpers import *
index d9e46da55d25189751eee193b97e8442a29aa271..c7c712a138bf05a537b314f3776a7dfc60947e9a 100755 (executable)
@@ -15,7 +15,9 @@ exec "$bup_python" "$0"
 # end of bup preamble
 
 from __future__ import absolute_import
-import sys, os, random
+import os, random, sys
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import compat, options
 from bup.compat import argv_bytes, bytes_from_uint, range
index 22dc3e141a2ef544467b2c7700d26ca8a73542c8..6cb0fc494adac2a4b602ad03a916db58a3fcbf5e 100755 (executable)
@@ -16,7 +16,9 @@ exec "$bup_python" "$0"
 
 from __future__ import absolute_import, print_function
 from os.path import relpath
-import sys
+import os.path, sys
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import compat, options, drecurse
 from bup.compat import argv_bytes
index 035300d16d694e797f31879a16ff367a9c328bae..e5eea329d06e8dd303602c81ad66536b1b3bc9c0 100755 (executable)
@@ -15,12 +15,14 @@ exec "$bup_python" "$0"
 # end of bup preamble
 
 from __future__ import absolute_import, print_function
-import sys, os, glob, subprocess
+import os, glob, subprocess, sys
 from shutil import rmtree
 from subprocess import PIPE, Popen
 from tempfile import mkdtemp
 from binascii import hexlify
 
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
+
 from bup import compat, options, git
 from bup.compat import argv_bytes
 from bup.helpers import Sha1, chunkyreader, istty2, log, progress
index 87fd3cedf9446c41119341d0641a5eb102944f62..1aada9a10834d902b5ec7743b69c3617b4e2eefe 100755 (executable)
@@ -20,7 +20,9 @@ exec "$bup_python" "$0"
 # (e.g. ISO-8859-1).
 
 from __future__ import absolute_import, print_function
-import sys, os, stat, fnmatch
+import os, fnmatch, stat, sys
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import _helpers, compat, options, git, shquote, ls, vfs
 from bup.compat import argv_bytes
index eb5daf834548bee8360170f7021f0dd6b4e601f9..bb6d98d06f0e86b382f0a1d6f23a508c0aa57ebf 100755 (executable)
@@ -15,7 +15,7 @@ exec "$bup_python" "$0"
 # end of bup preamble
 
 from __future__ import absolute_import, print_function
-import sys, os, errno
+import errno, os, sys
 
 try:
     import fuse
@@ -41,6 +41,8 @@ if sys.version_info[0] > 2:
               file=sys.stderr)
         sys.exit(2)
 
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
+
 from bup import compat, options, git, vfs, xstat
 from bup.compat import argv_bytes, fsdecode, py_maj
 from bup.helpers import log
index d8f7bc9810e305e145cb6b29cb2543787c2db27c..7368eca4852666ed3be94c7843822c4aa6e5affd 100755 (executable)
@@ -15,7 +15,9 @@ exec "$bup_python" "$0"
 # end of bup preamble
 
 from __future__ import absolute_import
-import sys
+import os.path, sys
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import compat, git, options
 from bup.gc import bup_gc
index 88a919efa5e5e6430b786f8150b724bf4cf0a092..c3198241d3da46ef6fababc1e665e6a6a217b82c 100755 (executable)
@@ -21,6 +21,8 @@ from collections import namedtuple
 from functools import partial
 from stat import S_ISDIR
 
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
+
 from bup import compat, git, client, helpers, vfs
 from bup.compat import argv_bytes, environ, hexstr, items, wrap_main
 from bup.git import get_cat_data, parse_commit, walk_object
index c078e825c1f972afe5833196c65e1eaed5b4df2d..aeacc70dc41420ee30fa03d4df1eae7c8b4af967 100755 (executable)
@@ -15,9 +15,13 @@ exec "$bup_python" "$0"
 # end of bup preamble
 
 from __future__ import absolute_import
-import sys, os, glob
+import os, glob, sys
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
+
 from bup import compat, options, path
 
+
 optspec = """
 bup help <command>
 """
index bfb51831581b2e2c56f680af1fe16545175811da..77b53ebc7cbe3645bf20b1bae1f3c40f4adbcfc0 100755 (executable)
@@ -20,9 +20,12 @@ from pipes import quote
 from subprocess import check_call
 from time import strftime, strptime
 import os
+import os.path
 import sys
 import tempfile
 
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
+
 from bup import compat, git, helpers, options
 from bup.compat import argv_bytes, str_type
 from bup.helpers import (handle_ctrl_c,
@@ -40,7 +43,7 @@ n,dry-run  don't do anything; just print what would be done
 """
 
 def logcmd(cmd):
-    log(shstr(cmd).decode('iso-8859-1', errors='replace') + '\n')
+    log(shstr(cmd).decode(errors='backslashreplace') + '\n')
 
 def exc(cmd, shell=False):
     global opt
index 030451e1339d8bcb9392d9558dccf0848c0934be..a47e20888b583e616fc403b6eeb8fe3761a161e4 100755 (executable)
@@ -16,7 +16,9 @@ exec "$bup_python" "$0"
 
 from __future__ import absolute_import, print_function
 from binascii import hexlify
-import sys, stat, time, os, errno, re
+import errno, os, re, stat, sys, time
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import compat, metadata, options, git, index, drecurse, hlinkdb
 from bup.compat import argv_bytes
index cff5c5cdd7ac3ba07762ffa1362099010bbc011b..13bff7dcce24295d2b28945176113749bca8c85c 100755 (executable)
@@ -15,7 +15,9 @@ exec "$bup_python" "$0"
 # end of bup preamble
 
 from __future__ import absolute_import
-import sys
+import os.path, sys
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import compat, git, options, client
 from bup.helpers import log, saved_errors
index e17c3159bcd2ed487e5cbf7b73e1e0cd07247066..55d9eed48d7455243374558efebd6b0e1f92ba50 100755 (executable)
@@ -15,7 +15,9 @@ exec "$bup_python" "$0"
 # end of bup preamble
 
 from __future__ import absolute_import
-import sys
+import os.path, sys
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import compat, git, options
 from bup.compat import argv_bytes
index d9d318f4480361ac03fd27418c71346061f5ed38..ebafdfac0609b7338944f4815e4e32b804d37a82 100755 (executable)
@@ -16,7 +16,9 @@ exec "$bup_python" "$0"
 
 from __future__ import absolute_import, print_function
 from binascii import hexlify, unhexlify
-import sys, os
+import os, sys
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import compat, git, options
 from bup.compat import argv_bytes
index b6900b93d9d580b31ba4ba5960dbdef2cdfb825e..6cc047bbcdd89668968122e30cb23e535b0dae18 100755 (executable)
@@ -15,7 +15,9 @@ exec "$bup_python" "$0"
 # end of bup preamble
 
 from __future__ import absolute_import
-import sys
+import os.path, sys
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import compat, git, ls
 from bup.io import byte_stream
index 9dc854aaee57447607a93068bfb760029dcb37e4..825102b255c907f6824ee883fec157c38eb6bbac 100755 (executable)
@@ -15,7 +15,9 @@ exec "$bup_python" "$0"
 # end of bup preamble
 
 from __future__ import absolute_import
-import sys, struct, math
+import math, os.path, struct, sys
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import compat, options, git, _helpers
 from bup.helpers import log
index 85fd2f6e54dee1f738ec331b828ed6c2d1f0942e..6f4dfd0a564e147a4bff1e253873b20f61e6199f 100755 (executable)
@@ -15,7 +15,9 @@ exec "$bup_python" "$0"
 # end of bup preamble
 
 from __future__ import absolute_import, print_function
-import sys, re, struct, time, resource
+import os.path, re, resource, struct, sys, time
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import compat, git, bloom, midx, options, _helpers
 from bup.compat import range
index e006c0bc7421b59c50bacec2d16cdf9d6e3e2384..15eed439cf82ac1978bf984bb7930c8116943ff2 100755 (executable)
@@ -22,7 +22,10 @@ exec "$bup_python" "$0"
 # TODO: Add tar-like -C option.
 
 from __future__ import absolute_import
-import sys
+import os, sys
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
+
 from bup import compat, metadata
 from bup import options
 from bup.compat import argv_bytes
index 53ea79c8b4252955d687842e08b2150189e2916b..b5ed7c47a6146d6a054543b3bada8c9c65c482f4 100755 (executable)
@@ -18,6 +18,8 @@ from __future__ import absolute_import, print_function
 from binascii import hexlify
 import glob, math, os, resource, struct, sys, tempfile
 
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
+
 from bup import compat, options, git, midx, _helpers, xstat
 from bup.compat import argv_bytes, hexstr, range
 from bup.helpers import (Sha1, add_error, atomically_replaced_file, debug1, fdatasync,
index 53fe7e6aefadf165153de47fab48ede9e3d1d071..1050262ff3ee9c44a1f192ab4b968666dfc84c79 100755 (executable)
@@ -15,7 +15,9 @@ exec "$bup_python" "$0"
 # end of bup preamble
 
 from __future__ import absolute_import
-import os, sys, subprocess, struct
+import os, struct, subprocess, sys
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import compat, options
 from bup.helpers import debug1, debug2, mux
index 71ed4d1dc869bfdd3679ec88d71d37d469dae0a0..12fee0855c3f7bbb5022c22bda2fe63678e4034f 100755 (executable)
@@ -15,7 +15,9 @@ exec "$bup_python" "$0"
 # end of bup preamble
 
 from __future__ import absolute_import
-import sys, os, struct
+import os, struct, sys
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import compat, options, helpers, path
 from bup.compat import environ, py_maj
index fd89da4e8bc51c9653f1b2aa968a75c1fa9c25d6..0644a46a4e6cdc58abd1c3d6216ffd940eb8dec1 100755 (executable)
@@ -16,7 +16,9 @@ exec "$bup_python" "$0"
 
 from __future__ import absolute_import
 from subprocess import PIPE
-import sys, os, struct, getopt, subprocess, signal
+import getopt, os, signal, struct, subprocess, sys
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import compat, options, ssh, path
 from bup.compat import argv_bytes
index 478000984389a9798afb03d6b5b50fba8f538044..07bf7daf341fab42696c4de2131842f31f3fa7dc 100755 (executable)
@@ -20,7 +20,9 @@ from collections import defaultdict
 from itertools import groupby
 from sys import stderr
 from time import localtime, strftime, time
-import re, sys
+import os.path, re, sys
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import compat, git, options
 from bup.compat import argv_bytes, int_types
diff --git a/lib/cmd/python-cmd.sh b/lib/cmd/python-cmd.sh
deleted file mode 100644 (file)
index b0a8d3d..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/bin/sh
-
-set -e
-
-top="$(pwd)"
-cmdpath="$0"
-# loop because macos has no recursive resolution
-while test -L "$cmdpath"; do
-    link="$(readlink "$cmdpath")"
-    cd "$(dirname "$cmdpath")"
-    cmdpath="$link"
-done
-script_home="$(cd "$(dirname "$cmdpath")" && pwd -P)"
-cd "$top"
-
-bup_libdir="$script_home/.."  # bup_libdir will be adjusted during install
-export PYTHONPATH="$bup_libdir${PYTHONPATH:+:$PYTHONPATH}"
-
-# Force python to use ISO-8859-1 (aka Latin 1), a single-byte
-# encoding, to help avoid any manipulation of data from system APIs
-# (paths, users, groups, command line arguments, etc.)
-
-export PYTHONCOERCECLOCALE=0  # Perhaps not necessary, but shouldn't hurt
-
-# We can't just export LC_CTYPE directly here because the locale might
-# not exist outside python, and then bash (at least) may be cranky.
-
-if [ "${LC_ALL+x}" ]; then
-    unset LC_ALL
-    exec env \
-         BUP_LC_ALL="$LC_ALL" \
-         LC_COLLATE="$LC_ALL" \
-         LC_MONETARY="$LC_ALL" \
-         LC_NUMERIC="$LC_ALL" \
-         LC_TIME="$LC_ALL" \
-         LC_MESSAGES="$LC_ALL" \
-         LC_CTYPE=ISO-8859-1 \
-         @bup_python@ "$@"
-elif [ "${LC_CTYPE+x}" ]; then
-    exec env \
-         BUP_LC_CTYPE="$LC_CTYPE" \
-         LC_CTYPE=ISO-8859-1 \
-         @bup_python@ "$@"
-else
-    exec env \
-         LC_CTYPE=ISO-8859-1 \
-         @bup_python@ "$@"
-fi
index d939fb86ffcc9a59ea23fb275549b8302e3ffb41..086dfff382bba2f12ddcfd5ce86e85954989657a 100755 (executable)
@@ -17,6 +17,8 @@ exec "$bup_python" "$0"
 from __future__ import absolute_import
 import os, sys
 
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
+
 from bup import compat, options, _helpers
 from bup.helpers import atoi, handle_ctrl_c, log, parse_num
 
index f955cca743144dd83b6bfb1edf7b00694196f052..43071d1f0568a0dc0016f80e086887ccbe2f2cdf 100755 (executable)
@@ -16,7 +16,9 @@ exec "$bup_python" "$0"
 
 from __future__ import absolute_import
 from stat import S_ISDIR
-import copy, errno, os, sys, stat, re
+import copy, errno, os, re, stat, sys
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import compat, options, git, metadata, vfs
 from bup._helpers import write_sparsely
index 6c753e2a735c274327c3cf35fbd5db1a0902485e..4016c008722392af979bd49f0db1e375546b4e9c 100755 (executable)
@@ -15,7 +15,9 @@ exec "$bup_python" "$0"
 # end of bup preamble
 
 from __future__ import absolute_import
-import sys
+import os.path, sys
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import compat
 from bup.compat import argv_bytes
index 02e6841e33bd9dd100150656645c3022c3a2dcd6..c67e1ed89d61addef236a511ebb468ab3cb1259c 100755 (executable)
@@ -18,7 +18,9 @@ from __future__ import absolute_import, print_function
 from binascii import hexlify
 from errno import EACCES
 from io import BytesIO
-import os, sys, stat, time, math
+import math, os, stat, sys, time
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import compat, hashsplit, git, options, index, client, metadata
 from bup import hlinkdb
index 5b918140af4d98337d316865388a8e095e5a439b..a81844530aa0e07017fe35518bb4fe1d4472a663 100755 (executable)
@@ -16,7 +16,9 @@ exec "$bup_python" "$0"
 
 from __future__ import absolute_import
 from binascii import hexlify, unhexlify
-import os, sys, struct, subprocess
+import os, struct, subprocess, sys
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import compat, options, git, vfs, vint
 from bup.compat import environ, hexstr
index d9cdc7ed2b2934e55d23202476612c706c945c65..6735d70d1afca8a4e06f53baf583b09c6f7db28a 100755 (executable)
@@ -18,6 +18,8 @@ from __future__ import absolute_import, division, print_function
 from binascii import hexlify
 import os, sys, time
 
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
+
 from bup import compat, hashsplit, git, options, client
 from bup.compat import argv_bytes, environ
 from bup.helpers import (add_error, handle_ctrl_c, hostname, log, parse_num,
index 2561aba383633612ef072a14d42a94bb85f50f9b..c2b6fae93161a8c5dc57223ecbf424d73f9d75d0 100755 (executable)
@@ -18,6 +18,8 @@ from __future__ import absolute_import
 from binascii import hexlify
 import os, sys
 
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
+
 from bup import compat, git, options
 from bup.compat import argv_bytes
 from bup.helpers import debug1, handle_ctrl_c, log
index 1a76350f12d333776e5d38c951710b6365b872d0..dcafc815d56f789cb6df2b0555ae7ae47ba8dff7 100755 (executable)
@@ -15,10 +15,13 @@ exec "$bup_python" "$0"
 # end of bup preamble
 
 from __future__ import absolute_import
-import sys, time
+import os, sys, time
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import compat, options
 
+
 optspec = """
 bup tick
 """
index 20fd218c5fe83001436b4d6dec29836d18869184..7dcd27988939f65b272cb7dd527c101efcaf193f 100755 (executable)
@@ -15,7 +15,9 @@ exec "$bup_python" "$0"
 # end of bup preamble
 
 from __future__ import absolute_import, print_function
-import re, sys
+import os.path, re, sys
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import compat, options, version
 
index 8c084c17b771d64585805ad81013e5817ad564d1..7b8b7b6069cd04242f02467671536db4ed17c544 100755 (executable)
@@ -19,6 +19,8 @@ from collections import namedtuple
 import mimetypes, os, posixpath, signal, stat, sys, time, urllib, webbrowser
 from binascii import hexlify
 
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
+
 from bup import compat, options, git, vfs
 from bup.helpers import (chunkyreader, debug1, format_filesize, handle_ctrl_c,
                          log, saved_errors)
index 297df7225e201ad7c1239af6dd80165d5ea11868..8a56ba58deac41202ba069336767b3ad1cdd80f7 100755 (executable)
@@ -20,7 +20,9 @@ exec "$bup_python" "$0"
 # Public License as described in the bup LICENSE file.
 
 from __future__ import absolute_import, print_function
-import sys, stat, errno
+import errno, os.path, sys, stat
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..']
 
 from bup import compat, metadata, options, xstat
 from bup.compat import argv_bytes
index 66c5c6361cc122c70a8670957e04601e1b6245d9..127f85d85948c1f69b058b28d9512ff569caa35b 100755 (executable)
@@ -27,3 +27,4 @@ from bup import compat
 for arg in compat.argvb:
     os.write(stdout.fileno(), arg)
     os.write(stdout.fileno(), b'\0\n')
+    stdout.flush()
index 4769154c5b9f34ecb9a8dfdfd906d2d5da0d71a2..0e6458a1fed7829422b87562ac65f711e28ecca0 100755 (executable)
@@ -16,6 +16,8 @@ exec "$bup_python" "$0"
 from __future__ import absolute_import, print_function
 import os, stat, sys
 
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/../lib']
+
 from bup import compat
 from bup.io import byte_stream
 
index 574fad5bb6979918e265742e08b7292f98c1b5ee..b9970f8778c33e1a16bf95bc4a2fa4c11911db9b 100755 (executable)
@@ -14,7 +14,9 @@ exec "$bup_python" "$0"
 # end of bup preamble
 
 from __future__ import absolute_import
-import os, sys
+import os.path, sys
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/../lib']
 
 from bup.compat import argv_bytes
 from bup.helpers import handle_ctrl_c, saved_errors
index 8f982e003163894f1d2b121f1e8d86d5e028b7a9..d777f3cff94dc633f1bfd6186139b5e117c808eb 100755 (executable)
@@ -7,7 +7,9 @@ exec "$bup_python" "$0" ${1+"$@"}
 from __future__ import absolute_import, print_function
 from random import randint
 from sys import stderr, stdout
-import sys
+import os, sys
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/../lib']
 
 from bup.io import byte_stream
 
index 1ca9e869c84a0dab1e5ce1ee647cb391170b9947..bcc21bbb31fb4fb19cba772f6d08499115041f45 100755 (executable)
@@ -6,7 +6,9 @@ exec "$bup_python" "$0" ${1+"$@"}
 # end of bup preamble
 
 from __future__ import absolute_import, print_function
-import sys
+import os.path, sys
+
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/../lib']
 
 from bup.compat import argv_bytes
 from bup.helpers import handle_ctrl_c, readpipe
index aa4b0a5acdff80133ff9eca5c98d3f2df5759108..6aed72415494c2a8cef5e8034f600a65a970a4df 100755 (executable)
@@ -14,6 +14,7 @@ import os, sys
 
 # For buptest, wvtest, ...
 sys.path[:0] = (abspath(os.path.dirname(__file__) + '/..'),)
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/../lib']
 
 from buptest import ex, exo, logcmd, test_tempdir
 from wvtest import wvfail, wvpass, wvpasseq, wvpassne, wvstart
index 3f42a0c3a52a569db0484b0025bf0648b9a883bb..4c28fe58199f576afc9bd530d36e0fcc91008259 100755 (executable)
@@ -23,6 +23,8 @@ import os, re, sys
 
 # For buptest, wvtest, ...
 sys.path[:0] = (abspath(os.path.dirname(__file__) + '/..'),)
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/../lib']
+
 
 from bup import compat, path
 from bup.compat import environ, getcwd, items
index 24c2c383511363941c1ab263ef2836a56d0c55f2..871bf2e08496fb53f04b2102f2e2043d9c1ea674 100755 (executable)
@@ -47,7 +47,7 @@ WVSTART "index-cache"
 # the 'a-zA-Z0-9_' is '\w' from python,
 # the trailing _ is because there's no dir specified
 # and that should thus be empty
-hostname=$(bup python -c "from bup import helpers ; print(helpers.hostname().decode('iso8859-1'))")
+hostname=$(uname -n)
 idxcache=$(echo "$hostname" | sed 's/[^@a-zA-Z0-9_]/_/g')_
 # there should be an index-cache now
 for idx in "$tmpdir"/bup/objects/pack/*.idx ; do
index a2ea4df0f3216d84dcfb7cdd4d97f33aeecab8dc..5b079939b606f094d06893fd190d5c669cf68aff 100755 (executable)
@@ -20,6 +20,7 @@ import os, random, sys
 
 # For buptest, wvtest, ...
 sys.path[:0] = (abspath(os.path.dirname(__file__) + '/..'),)
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/../lib']
 
 from buptest import ex, exo, test_tempdir
 from wvtest import wvfail, wvpass, wvpasseq, wvpassne, wvstart
index cafc306104a1a077a548e64f60d76858c9ca48e4..312a9f578ef924c516c861e4d548cdf04c550d4d 100755 (executable)
@@ -34,7 +34,10 @@ WVPASS bup index "$tmpdir/save"
 # that gets an error for the .../5 file in metadata.from_path()
 cat > "$tmpdir/bup-save" << EOF
 #!/usr/bin/env $top/cmd/bup-python
+import os.path, sys
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/../../../lib']
 from bup import metadata
+
 orig_from_path = metadata.from_path
 def from_path(path, *args, **kw):
     if path.endswith(b'/5'):
@@ -70,7 +73,10 @@ WVPASS bup index "$tmpdir/save"
 
 cat > "$tmpdir/bup-save" << EOF
 #!/usr/bin/env $top/cmd/bup-python
+import os.path, sys
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/../../../lib']
 from bup import metadata
+
 orig_from_path = metadata.from_path
 def from_path(path, *args, **kw):
     if path.endswith(b'/a'):
@@ -102,6 +108,8 @@ WVPASS bup index "$tmpdir/save"
 
 cat > "$tmpdir/bup-save" << EOF
 #!/usr/bin/env $top/cmd/bup-python
+import os.path, sys
+sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/../../../lib']
 from bup import index
 
 Reader = index.Reader