diff --git a/src/wormhole/cli/cli.py b/src/wormhole/cli/cli.py index ba5ec2c..46b6d68 100644 --- a/src/wormhole/cli/cli.py +++ b/src/wormhole/cli/cli.py @@ -10,7 +10,7 @@ from . import public_relay from .. import __version__ from ..timing import DebugTiming from ..errors import (WrongPasswordError, WelcomeError, KeyFormatError, - TransferError, NoTorError) + TransferError, NoTorError, UnsendableFileError) from twisted.internet.defer import inlineCallbacks, maybeDeferred from twisted.python.failure import Failure from twisted.internet.task import react @@ -109,7 +109,7 @@ def _dispatch_command(reactor, cfg, command): msg = fill("ERROR: " + dedent(e.__doc__)) print(msg, file=cfg.stderr) raise SystemExit(1) - except WelcomeError as e: + except (WelcomeError, UnsendableFileError) as e: msg = fill("ERROR: " + dedent(e.__doc__)) print(msg, file=cfg.stderr) print(six.u(""), file=cfg.stderr) @@ -173,6 +173,10 @@ TorArgs = _compose( "--text", default=None, metavar="MESSAGE", help="text message to send, instead of a file. Use '-' to read from stdin.", ) +@click.option( + "--ignore-unsendable-files", default=False, is_flag=True, + help="Don't raise an error if a file can't be read." +) @click.argument("what", required=False) @click.pass_obj def send(cfg, **kwargs): diff --git a/src/wormhole/cli/cmd_send.py b/src/wormhole/cli/cmd_send.py index 307494b..4c96d9b 100644 --- a/src/wormhole/cli/cmd_send.py +++ b/src/wormhole/cli/cmd_send.py @@ -6,7 +6,8 @@ from twisted.python import log from twisted.protocols import basic from twisted.internet import reactor from twisted.internet.defer import inlineCallbacks, returnValue -from ..errors import TransferError, WormholeClosedError, NoTorError +from ..errors import (TransferError, WormholeClosedError, NoTorError, + UnsendableFileError) from wormhole import create, __version__ from ..transit import TransitSender from ..util import dict_to_bytes, bytes_to_dict, bytes_to_hexstr @@ -274,9 +275,16 @@ class Sender: for fn in files: archivename = os.path.join(*tuple(localpath+[fn])) localfilename = os.path.join(path, fn) - zf.write(localfilename, archivename) - num_bytes += os.stat(localfilename).st_size - num_files += 1 + try: + zf.write(localfilename, archivename) + num_bytes += os.stat(localfilename).st_size + num_files += 1 + except OSError as e: + errmsg = u"{}: {}".format(fn, e.strerror) + if self._args.ignore_unsendable_files: + print(u"{} (ignoring error)".format(errmsg)) + else: + raise UnsendableFileError(errmsg) fd_to_send.seek(0,2) filesize = fd_to_send.tell() fd_to_send.seek(0,0) diff --git a/src/wormhole/errors.py b/src/wormhole/errors.py index 06f74d3..7763f73 100644 --- a/src/wormhole/errors.py +++ b/src/wormhole/errors.py @@ -3,6 +3,16 @@ from __future__ import unicode_literals class WormholeError(Exception): """Parent class for all wormhole-related errors""" +class UnsendableFileError(Exception): + """ + A file you wanted to send couldn't be read, maybe because it's not + a file, or because it's a symlink that points to something + that doesn't exist. + + To ignore this kind of error, you can run wormhole with the + --ignore-unsendable-files flag. + """ + class ServerError(WormholeError): """The relay server complained about something we did."""