Repository: borgbackup/borg

Issue:
Borg (cygwin) 1.0.10 don't like smb paths
I know that cygwin is not really supported, but it worked with smb paths with no problems until version 1.0.10. 
I also tested the cygwin version from billyc [https://github.com/borgbackup/borg/issues/440](https://github.com/borgbackup/borg/issues/440)
Same result.

/cygdrive/x/abc still works

> borg list //synology/Backups/My-PC/Borg
> 
> usage: borg list [-h] [--critical] [--error] [--warning] [--info] [--debug]
> [--lock-wait N] [--show-rc] [--no-files-cache] [--umask M]
> [--remote-path PATH] [--short] [--list-format LISTFORMAT]
> [-P PREFIX]
> [REPOSITORY_OR_ARCHIVE]
> 
> borg list: error: argument REPOSITORY_OR_ARCHIVE: Invalid location format: "//synology/Backups/My-PC/Borg"

Discussion:

Patch:
diff --git a/src/borg/helpers.py b/src/borg/helpers.py
index 89b557e5..5d05b3ce 100644
--- a/src/borg/helpers.py
+++ b/src/borg/helpers.py
@@ -1004,10 +1004,17 @@ class Location:
 
     # path must not contain :: (it ends at :: or string end), but may contain single colons.
     # to avoid ambiguities with other regexes, it must also not start with ":" nor with "//" nor with "ssh://".
-    path_re = r"""
+    scp_path_re = r"""
         (?!(:|//|ssh://))                                   # not starting with ":" or // or ssh://
         (?P<path>([^:]|(:(?!:)))+)                          # any chars, but no "::"
         """
+
+    # file_path must not contain :: (it ends at :: or string end), but may contain single colons.
+    # it must start with a / and that slash is part of the path.
+    file_path_re = r"""
+        (?P<path>(([^/]*)/([^:]|(:(?!:)))+))                # start opt. servername, then /, then any chars, but no "::"
+        """
+
     # abs_path must not contain :: (it ends at :: or string end), but may contain single colons.
     # it must start with a / and that slash is part of the path.
     abs_path_re = r"""
@@ -1032,7 +1039,7 @@ class Location:
 
     file_re = re.compile(r"""
         (?P<proto>file)://                                  # file://
-        """ + path_re + optional_archive_re, re.VERBOSE)    # path or path::archive
+        """ + file_path_re + optional_archive_re, re.VERBOSE)  # servername/path, path or path::archive
 
     # note: scp_re is also use for local pathes
     scp_re = re.compile(r"""
@@ -1040,7 +1047,7 @@ class Location:
             """ + optional_user_re + r"""                   # user@  (optional)
             (?P<host>[^:/]+):                               # host: (don't match / in host to disambiguate from file:)
         )?                                                  # user@host: part is optional
-        """ + path_re + optional_archive_re, re.VERBOSE)    # path with optional archive
+        """ + scp_path_re + optional_archive_re, re.VERBOSE)  # path with optional archive
 
     # get the repo from BORG_REPO env and the optional archive from param.
     # if the syntax requires giving REPOSITORY (see "borg mount"),


Test patch:
diff --git a/src/borg/testsuite/helpers.py b/src/borg/testsuite/helpers.py
index 8dca6a39..57bf0175 100644
--- a/src/borg/testsuite/helpers.py
+++ b/src/borg/testsuite/helpers.py
@@ -60,6 +60,11 @@ def test_scp(self, monkeypatch):
         assert repr(Location('user@host:/some/path')) == \
             "Location(proto='ssh', user='user', host='host', port=None, path='/some/path', archive=None)"
 
+    def test_smb(self, monkeypatch):
+        monkeypatch.delenv('BORG_REPO', raising=False)
+        assert repr(Location('file:////server/share/path::archive')) == \
+            "Location(proto='file', user=None, host=None, port=None, path='//server/share/path', archive='archive')"
+
     def test_folder(self, monkeypatch):
         monkeypatch.delenv('BORG_REPO', raising=False)
         assert repr(Location('path::archive')) == \