1
0
mirror of https://github.com/rclone/rclone.git synced 2025-12-11 22:03:17 +00:00

Compare commits

..

31 Commits

Author SHA1 Message Date
Nick Craig-Wood
bede3a5d48 fs: dump config for an Fs before creation - FIXME TESTING DO NOT MERGE
See: https://forum.rclone.org/t/authenticating-to-box-using-connection-strings-and-config-file-fails/23333/7
2021-04-08 12:39:03 +01:00
Nick Craig-Wood
f52ae75a51 rclone authorize: Send and receive extra config options to fix oauth
Before this change any backends which required extra config in the
oauth phase (like the `region` for zoho) didn't work with `rclone
authorize`.

This change serializes the extra config and passes it to `rclone
authorize` and returns new config items to be set from rclone
authorize.

`rclone authorize` will still accept its previous configuration
parameters for use with old rclones.

Fixes #5178
2021-04-08 12:34:15 +01:00
Nick Craig-Wood
9d5c5bf7ab fs: add Options.NonDefault to read options which aren't at their default #5178 2021-04-08 12:34:15 +01:00
Nick Craig-Wood
53573b4a09 configmap: Add Encode and Decode methods to Simple for command line encoding #5178 2021-04-08 12:34:15 +01:00
Nick Craig-Wood
3622e064f5 configmap: Add priorities to configmap Setters #5178 2021-04-08 12:34:15 +01:00
Nick Craig-Wood
6d28ea7ab5 fs: factor config override detection into its own function #5178 2021-04-08 12:34:15 +01:00
Nick Craig-Wood
b9fd02039b authorize: refactor to use new config interfaces #5178 2021-04-08 12:34:15 +01:00
Nick Craig-Wood
1a41c930f3 configmap: add ClearSetters to get rid of all setters #5178 2021-04-08 12:34:15 +01:00
albertony
ddb7eb6e0a docs: fixed some typos 2021-04-08 10:19:03 +02:00
buengese
c114695a66 zoho: do not ask for mountpoint twice when using headless setup 2021-04-08 00:23:27 +02:00
Nick Craig-Wood
fcba51557f dropbox: set visibility in link sharing when --expire is set
Note that due to a bug in the dropbox SDK you'll need to set --expire
to access this.

See: https://github.com/dropbox/dropbox-sdk-go-unofficial/issues/75
See: https://forum.rclone.org/t/rclone-link-dropbox-permissions/23211
2021-04-07 13:58:37 +01:00
Nick Craig-Wood
9393225a1d link: use "off" value for unset expiry 2021-04-07 13:58:37 +01:00
albertony
3d3ff61f74 docs: minor cleanup of space around code section 2021-04-07 08:47:29 +02:00
albertony
d98f192425 docs: WinFsp 2021 is out of beta 2021-04-07 08:13:40 +02:00
Nick Craig-Wood
54771e4402 sync: fix incorrect error reported by graceful cutoff - fixes #5203
Before this change, a sync which was finished with a graceful transfer
cutoff could return "context canceled" instead of the correct error.

This fixes the problem by ignoring "context canceled" errors if we
have done a graceful stop.
2021-04-06 13:08:42 +01:00
Nick Craig-Wood
dc286529bc drive: fix backend copyid of google doc to directory - fixes #5196
Before this change the google doc was being copied to the directory
without an extension.
2021-04-06 11:46:52 +01:00
Nick Craig-Wood
7dc7c021db sftp: fix Update ReadFrom failed: failed to send packet: EOF errors
In

a3fcadddc8 sftp: close idle connections after --sftp-idle-timeout (1m by default)

Idle SFTP connections were closed after 1 minute. However due to the
way SSH multiplexes connections over a single SSH connection this
meant that if uploads or downloads went on for more than one minute
they failed with "EOF errors" as their underlying connection was
closed.

This fixes the problem by not clearing idle connections if there are
any transfers in progress.

Fixes #5197
2021-04-06 10:01:49 +01:00
Nick Craig-Wood
fe1aa13069 sftp: revert sftp library to v1.12.0 from v1.13.0 to fix performance regression #5197
This reverts the library update done in this commit.

713f8f357d sftp: fix "file not found" errors for read once servers

Reverting this commit triples the performance to a far away sftp server.

See: https://github.com/pkg/sftp/issues/426
2021-04-06 10:01:49 +01:00
Nick Craig-Wood
5fa8e7d957 Add Nick Gaya to contributors 2021-04-06 10:01:49 +01:00
Nick Gaya
9db7c51eaa sync: don't warn about --no-traverse when --files-from is set 2021-04-05 20:36:39 +01:00
Ivan Andreev
3859fe2f52 cmd/version: print os/version, kernel and bitness (#5204)
Related to #5121

Note: OpenBSD is stub yet. This will be fixed after upstream PR gets resolved
https://github.com/shirou/gopsutil/pull/993
2021-04-05 21:53:09 +03:00
buengese
0caf417779 zoho: fix error when region isn't set 2021-04-05 15:11:30 +02:00
Ivan Andreev
9eab258ffb build: add build tag noselfupdate
Allow downstream packaging to build rclone without selfupdate command:
$ go build -tags noselfupdate

Fixes #5187
2021-04-04 11:22:09 +03:00
Nick Gaya
7df57cd625 contributing.md: update setup instructions for go1.16 2021-04-04 09:10:43 +01:00
Nick Gaya
1fd9b483c8 onedrive: add list_chunk option
Add --onedrive-list-chunk option similar to existing options for azureblob, drive, and s3.

Suggested as a workaround for a OneDrive pagination bug

See: https://forum.rclone.org/t/unexpected-duplicates-on-onedrive-with-0s-in-filename/23164/8
2021-04-04 09:08:16 +01:00
Ivan Andreev
93353c431b selfupdate: dont detect FUSE if build is static
Before this patch selfupdate detected ANY build with cmount tag as a build
having libFUSE capabilities. However, only dynamic builds really have it.
The official linux builds are static and have the cmount tag as of the time
of this writing. This results in inability to update official linux binaries.
This patch fixes that. The build can be fixed independently.
2021-04-03 21:54:15 +03:00
Nick Craig-Wood
886dfd23e2 fichier: check if more than one upload link is returned #5152 2021-04-03 15:00:50 +01:00
Nick Craig-Wood
116a8021bb drive: switch to the Drives API for looking up shared drives - fixes #3139
Before this change rclone used the deprecated teamdrives API. This
change uses the new drives API (which seems to be the teamdrives API
renames).
2021-04-03 14:21:20 +01:00
Nick Craig-Wood
9e2fbe0f1a install.sh: fix macOS arm64 download - fixes #5183 2021-03-31 21:48:31 +01:00
Nick Craig-Wood
6d65d116df Start v1.56.0-DEV development 2021-03-31 19:51:43 +01:00
Ivan Andreev
edaeb51ea9 backlog: ticket templates should recommend to update rclone
Aligns Bug and Feature github templates with rclone forum
and instructs submitter to proactively update rclone.
2021-03-31 19:13:50 +01:00
41 changed files with 862 additions and 516 deletions

View File

@@ -5,19 +5,31 @@ about: Report a problem with rclone
<!-- <!--
Welcome :-) We understand you are having a problem with rclone; we want to help you with that! We understand you are having a problem with rclone; we want to help you with that!
If you've just got a question or aren't sure if you've found a bug then please use the rclone forum: **STOP and READ**
**YOUR POST WILL BE REMOVED IF IT IS LOW QUALITY**:
Please show the effort you've put in to solving the problem and please be specific.
People are volunteering their time to help! Low effort posts are not likely to get good answers!
If you think you might have found a bug, try to replicate it with the latest beta (or stable).
The update instructions are available at https://rclone.org/commands/rclone_selfupdate/
If you can still replicate it or just got a question then please use the rclone forum:
https://forum.rclone.org/ https://forum.rclone.org/
instead of filing an issue for a quick response. for a quick response instead of filing an issue on this repo.
If you think you might have found a bug, please can you try to replicate it with the latest beta? If nothing else helps, then please fill in the info below which helps us help you.
https://beta.rclone.org/ **DO NOT REDACT** any information except passwords/keys/personal info.
If you can still replicate it with the latest beta, then please fill in the info below which makes our lives much easier. A log with -vv will make our day :-) You should use 3 backticks to begin and end your paste to make it readable.
Make sure to include a log obtained with '-vv'.
You can also use '-vv --log-file bug.log' and a service such as https://pastebin.com or https://gist.github.com/
Thank you Thank you
@@ -25,6 +37,11 @@ The Rclone Developers
--> -->
#### The associated forum post URL from `https://forum.rclone.org`
#### What is the problem you are having with rclone? #### What is the problem you are having with rclone?

View File

@@ -7,12 +7,16 @@ about: Suggest a new feature or enhancement for rclone
Welcome :-) Welcome :-)
So you've got an idea to improve rclone? We love that! You'll be glad to hear we've incorporated hundreds of ideas from contributors already. So you've got an idea to improve rclone? We love that!
You'll be glad to hear we've incorporated hundreds of ideas from contributors already.
Here is a checklist of things to do: Probably the latest beta (or stable) release has your feature, so try to update your rclone.
The update instructions are available at https://rclone.org/commands/rclone_selfupdate/
1. Please search the old issues first for your idea and +1 or comment on an existing issue if possible. If it still isn't there, here is a checklist of things to do:
2. Discuss on the forum first: https://forum.rclone.org/
1. Search the old issues for your idea and +1 or comment on an existing issue if possible.
2. Discuss on the forum: https://forum.rclone.org/
3. Make a feature request issue (this is the right place!). 3. Make a feature request issue (this is the right place!).
4. Be prepared to get involved making the feature :-) 4. Be prepared to get involved making the feature :-)
@@ -23,6 +27,10 @@ The Rclone Developers
--> -->
#### The associated forum post URL from `https://forum.rclone.org`
#### What is your current rclone version (output from `rclone version`)? #### What is your current rclone version (output from `rclone version`)?

View File

@@ -221,8 +221,6 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
with:
fetch-depth: 0
# Upgrade together with NDK version # Upgrade together with NDK version
- name: Set up Go 1.14 - name: Set up Go 1.14

69
MANUAL.html generated
View File

@@ -17,7 +17,7 @@
<header id="title-block-header"> <header id="title-block-header">
<h1 class="title">rclone(1) User Manual</h1> <h1 class="title">rclone(1) User Manual</h1>
<p class="author">Nick Craig-Wood</p> <p class="author">Nick Craig-Wood</p>
<p class="date">Apr 26, 2021</p> <p class="date">Mar 31, 2021</p>
</header> </header>
<h1 id="rclone-syncs-your-files-to-cloud-storage">Rclone syncs your files to cloud storage</h1> <h1 id="rclone-syncs-your-files-to-cloud-storage">Rclone syncs your files to cloud storage</h1>
<p><img width="50%" src="https://rclone.org/img/logo_on_light__horizontal_color.svg" alt="rclone logo" style="float:right; padding: 5px;" ></p> <p><img width="50%" src="https://rclone.org/img/logo_on_light__horizontal_color.svg" alt="rclone logo" style="float:right; padding: 5px;" ></p>
@@ -1475,7 +1475,7 @@ rclone mount remote:path/to/files * --volname \\cloud\remote</code></pre>
<p>The permissions on each entry will be set according to <a href="#options">options</a> <code>--dir-perms</code> and <code>--file-perms</code>, which takes a value in traditional <a href="https://en.wikipedia.org/wiki/File-system_permissions#Numeric_notation">numeric notation</a>, where the default corresponds to <code>--file-perms 0666 --dir-perms 0777</code>.</p> <p>The permissions on each entry will be set according to <a href="#options">options</a> <code>--dir-perms</code> and <code>--file-perms</code>, which takes a value in traditional <a href="https://en.wikipedia.org/wiki/File-system_permissions#Numeric_notation">numeric notation</a>, where the default corresponds to <code>--file-perms 0666 --dir-perms 0777</code>.</p>
<p>Note that the mapping of permissions is not always trivial, and the result you see in Windows Explorer may not be exactly like you expected. For example, when setting a value that includes write access, this will be mapped to individual permissions "write attributes", "write data" and "append data", but not "write extended attributes". Windows will then show this as basic permission "Special" instead of "Write", because "Write" includes the "write extended attributes" permission.</p> <p>Note that the mapping of permissions is not always trivial, and the result you see in Windows Explorer may not be exactly like you expected. For example, when setting a value that includes write access, this will be mapped to individual permissions "write attributes", "write data" and "append data", but not "write extended attributes". Windows will then show this as basic permission "Special" instead of "Write", because "Write" includes the "write extended attributes" permission.</p>
<p>If you set POSIX permissions for only allowing access to the owner, using <code>--file-perms 0600 --dir-perms 0700</code>, the user group and the built-in "Everyone" group will still be given some special permissions, such as "read attributes" and "read permissions", in Windows. This is done for compatibility reasons, e.g. to allow users without additional permissions to be able to read basic metadata about files like in UNIX. One case that may arise is that other programs (incorrectly) interprets this as the file being accessible by everyone. For example an SSH client may warn about "unprotected private key file".</p> <p>If you set POSIX permissions for only allowing access to the owner, using <code>--file-perms 0600 --dir-perms 0700</code>, the user group and the built-in "Everyone" group will still be given some special permissions, such as "read attributes" and "read permissions", in Windows. This is done for compatibility reasons, e.g. to allow users without additional permissions to be able to read basic metadata about files like in UNIX. One case that may arise is that other programs (incorrectly) interprets this as the file being accessible by everyone. For example an SSH client may warn about "unprotected private key file".</p>
<p>WinFsp 2021 (version 1.9) introduces a new FUSE option "FileSecurity", that allows the complete specification of file security descriptors using <a href="https://docs.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-string-format">SDDL</a>. With this you can work around issues such as the mentioned "unprotected private key file" by specifying <code>-o FileSecurity="D:P(A;;FA;;;OW)"</code>, for file all access (FA) to the owner (OW).</p> <p>WinFsp 2021 (version 1.9, still in beta) introduces a new FUSE option "FileSecurity", that allows the complete specification of file security descriptors using <a href="https://docs.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-string-format">SDDL</a>. With this you can work around issues such as the mentioned "unprotected private key file" by specifying <code>-o FileSecurity="D:P(A;;FA;;;OW)"</code>, for file all access (FA) to the owner (OW).</p>
<h3 id="windows-caveats">Windows caveats</h3> <h3 id="windows-caveats">Windows caveats</h3>
<p>Note that drives created as Administrator are not visible by other accounts (including the account that was elevated as Administrator). So if you start a Windows drive from an Administrative Command Prompt and then try to access the same drive from Explorer (which does not run as Administrator), you will not be able to see the new drive.</p> <p>Note that drives created as Administrator are not visible by other accounts (including the account that was elevated as Administrator). So if you start a Windows drive from an Administrative Command Prompt and then try to access the same drive from Explorer (which does not run as Administrator), you will not be able to see the new drive.</p>
<p>The easiest way around this is to start the drive from a normal command prompt. It is also possible to start a drive from the SYSTEM account (using <a href="https://github.com/billziss-gh/winfsp/wiki/WinFsp-Service-Architecture">the WinFsp.Launcher infrastructure</a>) which creates drives accessible for everyone on the system or alternatively using <a href="https://nssm.cc/usage">the nssm service manager</a>.</p> <p>The easiest way around this is to start the drive from a normal command prompt. It is also possible to start a drive from the SYSTEM account (using <a href="https://github.com/billziss-gh/winfsp/wiki/WinFsp-Service-Architecture">the WinFsp.Launcher infrastructure</a>) which creates drives accessible for everyone on the system or alternatively using <a href="https://nssm.cc/usage">the nssm service manager</a>.</p>
@@ -1805,7 +1805,7 @@ ffmpeg - | rclone rcat remote:path/to/file</code></pre>
<p>This command downloads the latest release of rclone and replaces the currently running binary. The download is verified with a hashsum and cryptographically signed signature.</p> <p>This command downloads the latest release of rclone and replaces the currently running binary. The download is verified with a hashsum and cryptographically signed signature.</p>
<p>If used without flags (or with implied <code>--stable</code> flag), this command will install the latest stable release. However, some issues may be fixed (or features added) only in the latest beta release. In such cases you should run the command with the <code>--beta</code> flag, i.e. <code>rclone selfupdate --beta</code>. You can check in advance what version would be installed by adding the <code>--check</code> flag, then repeat the command without it when you are satisfied.</p> <p>If used without flags (or with implied <code>--stable</code> flag), this command will install the latest stable release. However, some issues may be fixed (or features added) only in the latest beta release. In such cases you should run the command with the <code>--beta</code> flag, i.e. <code>rclone selfupdate --beta</code>. You can check in advance what version would be installed by adding the <code>--check</code> flag, then repeat the command without it when you are satisfied.</p>
<p>Sometimes the rclone team may recommend you a concrete beta or stable rclone release to troubleshoot your issue or add a bleeding edge feature. The <code>--version VER</code> flag, if given, will update to the concrete version instead of the latest one. If you omit micro version from <code>VER</code> (for example <code>1.53</code>), the latest matching micro version will be used.</p> <p>Sometimes the rclone team may recommend you a concrete beta or stable rclone release to troubleshoot your issue or add a bleeding edge feature. The <code>--version VER</code> flag, if given, will update to the concrete version instead of the latest one. If you omit micro version from <code>VER</code> (for example <code>1.53</code>), the latest matching micro version will be used.</p>
<p>Upon successful update rclone will print a message that contains a previous version number. You will need it if you later decide to revert your update for some reason. Then you'll have to note the previous version and run the following command: <code>rclone selfupdate [--beta] OLDVER</code>. If the old version contains only dots and digits (for example <code>v1.54.0</code>) then it's a stable release so you won't need the <code>--beta</code> flag. Beta releases have an additional information similar to <code>v1.54.0-beta.5111.06f1c0c61</code>. (if you are a developer and use a locally built rclone, the version number will end with <code>-DEV</code>, you will have to rebuild it as it obviously can't be distributed).</p> <p>Upon successful update rclone will print a message that contains a previous version number. You will need it if you later decide to revert your update for some reason. Then you'll have to note the previous version and run the following command: <code>rclone selfupdate [--beta] OLDVER</code>. If the old version contains only dots and digits (for example <code>v1.54.0</code>) then it's a stable release so you won't need the <code>--beta</code> flag. Beta releases have an additional information similar to <code>v1.54.0-beta.5111.06f1c0c61</code>. (if you are a developer and use a locally built rclone, the version number will end with <code>-DEV</code>, you will have to rebuild it as it obvisously can't be distributed).</p>
<p>If you previously installed rclone via a package manager, the package may include local documentation or configure services. You may wish to update with the flag <code>--package deb</code> or <code>--package rpm</code> (whichever is correct for your OS) to update these too. This command with the default <code>--package zip</code> will update only the rclone executable so the local manual may become inaccurate after it.</p> <p>If you previously installed rclone via a package manager, the package may include local documentation or configure services. You may wish to update with the flag <code>--package deb</code> or <code>--package rpm</code> (whichever is correct for your OS) to update these too. This command with the default <code>--package zip</code> will update only the rclone executable so the local manual may become inaccurate after it.</p>
<p>The <code>rclone mount</code> command (https://rclone.org/commands/rclone_mount/) may or may not support extended FUSE options depending on the build and OS. <code>selfupdate</code> will refuse to update if the capability would be discarded.</p> <p>The <code>rclone mount</code> command (https://rclone.org/commands/rclone_mount/) may or may not support extended FUSE options depending on the build and OS. <code>selfupdate</code> will refuse to update if the capability would be discarded.</p>
<p>Note: Windows forbids deletion of a currently running executable so this command will rename the old executable to 'rclone.old.exe' upon success.</p> <p>Note: Windows forbids deletion of a currently running executable so this command will rename the old executable to 'rclone.old.exe' upon success.</p>
@@ -3378,7 +3378,7 @@ rclone sync -i /path/to/files remote:current-backup</code></pre>
<p>Normally the config file is in your home directory as a file called <code>.config/rclone/rclone.conf</code> (or <code>.rclone.conf</code> if created with an older version). If <code>$XDG_CONFIG_HOME</code> is set it will be at <code>$XDG_CONFIG_HOME/rclone/rclone.conf</code>.</p> <p>Normally the config file is in your home directory as a file called <code>.config/rclone/rclone.conf</code> (or <code>.rclone.conf</code> if created with an older version). If <code>$XDG_CONFIG_HOME</code> is set it will be at <code>$XDG_CONFIG_HOME/rclone/rclone.conf</code>.</p>
<p>If there is a file <code>rclone.conf</code> in the same directory as the rclone executable it will be preferred. This file must be created manually for Rclone to use it, it will never be created automatically.</p> <p>If there is a file <code>rclone.conf</code> in the same directory as the rclone executable it will be preferred. This file must be created manually for Rclone to use it, it will never be created automatically.</p>
<p>If you run <code>rclone config file</code> you will see where the default location is for you.</p> <p>If you run <code>rclone config file</code> you will see where the default location is for you.</p>
<p>Use this flag to override the config location, e.g. <code>rclone --config=".myconfig" config</code>.</p> <p>Use this flag to override the config location, e.g. <code>rclone --config=".myconfig" .config</code>.</p>
<p>If the location is set to empty string <code>""</code> or the special value <code>/notfound</code>, or the os null device represented by value <code>NUL</code> on Windows and <code>/dev/null</code> on Unix systems, then rclone will keep the config file in memory only.</p> <p>If the location is set to empty string <code>""</code> or the special value <code>/notfound</code>, or the os null device represented by value <code>NUL</code> on Windows and <code>/dev/null</code> on Unix systems, then rclone will keep the config file in memory only.</p>
<p>The file format is basic <a href="https://en.wikipedia.org/wiki/INI_file#Format">INI</a>: Sections of text, led by a <code>[section]</code> header and followed by <code>key=value</code> entries on separate lines. In rclone each remote is represented by its own section, where the section name defines the name of the remote. Options are specified as the <code>key=value</code> entries, where the key is the option name without the <code>--backend-</code> prefix, in lowercase and with <code>_</code> instead of <code>-</code>. E.g. option <code>--mega-hard-delete</code> corresponds to key <code>hard_delete</code>. Only backend options can be specified. A special, and required, key <code>type</code> identifies the <a href="https://rclone.org/overview/">storage system</a>, where the value is the internal lowercase name as returned by command <code>rclone help backends</code>. Comments are indicated by <code>;</code> or <code>#</code> at the beginning of a line.</p> <p>The file format is basic <a href="https://en.wikipedia.org/wiki/INI_file#Format">INI</a>: Sections of text, led by a <code>[section]</code> header and followed by <code>key=value</code> entries on separate lines. In rclone each remote is represented by its own section, where the section name defines the name of the remote. Options are specified as the <code>key=value</code> entries, where the key is the option name without the <code>--backend-</code> prefix, in lowercase and with <code>_</code> instead of <code>-</code>. E.g. option <code>--mega-hard-delete</code> corresponds to key <code>hard_delete</code>. Only backend options can be specified. A special, and required, key <code>type</code> identifies the <a href="https://rclone.org/overview/">storage system</a>, where the value is the internal lowercase name as returned by command <code>rclone help backends</code>. Comments are indicated by <code>;</code> or <code>#</code> at the beginning of a line.</p>
<p>Example:</p> <p>Example:</p>
@@ -6806,7 +6806,7 @@ Showing nodes accounting for 1537.03kB, 100% of 1537.03kB total
--use-json-log Use json log format. --use-json-log Use json log format.
--use-mmap Use mmap allocator (see docs). --use-mmap Use mmap allocator (see docs).
--use-server-modtime Use server modified time instead of object metadata --use-server-modtime Use server modified time instead of object metadata
--user-agent string Set the user-agent to a specified string. The default is rclone/ version (default &quot;rclone/v1.55.1&quot;) --user-agent string Set the user-agent to a specified string. The default is rclone/ version (default &quot;rclone/v1.55.0&quot;)
-v, --verbose count Print lots more stuff (repeat for more)</code></pre> -v, --verbose count Print lots more stuff (repeat for more)</code></pre>
<h2 id="backend-flags">Backend Flags</h2> <h2 id="backend-flags">Backend Flags</h2>
<p>These flags are available for every command. They control the backends and may be set in the config file.</p> <p>These flags are available for every command. They control the backends and may be set in the config file.</p>
@@ -20355,65 +20355,6 @@ $ tree /tmp/b
<li>"error": return an error based on option value</li> <li>"error": return an error based on option value</li>
</ul> </ul>
<h1 id="changelog">Changelog</h1> <h1 id="changelog">Changelog</h1>
<h2 id="v1.55.1---2021-04-26">v1.55.1 - 2021-04-26</h2>
<p><a href="https://github.com/rclone/rclone/compare/v1.55.0...v1.55.1">See commits</a></p>
<ul>
<li>Bug Fixes
<ul>
<li>selfupdate
<ul>
<li>Dont detect FUSE if build is static (Ivan Andreev)</li>
<li>Add build tag noselfupdate (Ivan Andreev)</li>
</ul></li>
<li>sync: Fix incorrect error reported by graceful cutoff (Nick Craig-Wood)</li>
<li>install.sh: fix macOS arm64 download (Nick Craig-Wood)</li>
<li>build: Fix version numbers in android branch builds (Nick Craig-Wood)</li>
<li>docs
<ul>
<li>Contributing.md: update setup instructions for go1.16 (Nick Gaya)</li>
<li>WinFsp 2021 is out of beta (albertony)</li>
<li>Minor cleanup of space around code section (albertony)</li>
<li>Fixed some typos (albertony)</li>
</ul></li>
</ul></li>
<li>VFS
<ul>
<li>Fix a code path which allows dirty data to be removed causing data loss (Nick Craig-Wood)</li>
</ul></li>
<li>Compress
<ul>
<li>Fix compressed name regexp (buengese)</li>
</ul></li>
<li>Drive
<ul>
<li>Fix backend copyid of google doc to directory (Nick Craig-Wood)</li>
<li>Don't open browser when service account... (Ansh Mittal)</li>
</ul></li>
<li>Dropbox
<ul>
<li>Add missing team_data.member scope for use with --impersonate (Nick Craig-Wood)</li>
<li>Fix About after scopes changes - rclone config reconnect needed (Nick Craig-Wood)</li>
<li>Fix Unable to decrypt returned paths from changeNotify (Nick Craig-Wood)</li>
</ul></li>
<li>FTP
<ul>
<li>Fix implicit TLS (Ivan Andreev)</li>
</ul></li>
<li>Onedrive
<ul>
<li>Work around for random "Unable to initialize RPS" errors (OleFrost)</li>
</ul></li>
<li>SFTP
<ul>
<li>Revert sftp library to v1.12.0 from v1.13.0 to fix performance regression (Nick Craig-Wood)</li>
<li>Fix Update ReadFrom failed: failed to send packet: EOF errors (Nick Craig-Wood)</li>
</ul></li>
<li>Zoho
<ul>
<li>Fix error when region isn't set (buengese)</li>
<li>Do not ask for mountpoint twice when using headless setup (buengese)</li>
</ul></li>
</ul>
<h2 id="v1.55.0---2021-03-31">v1.55.0 - 2021-03-31</h2> <h2 id="v1.55.0---2021-03-31">v1.55.0 - 2021-03-31</h2>
<p><a href="https://github.com/rclone/rclone/compare/v1.54.0...v1.55.0">See commits</a></p> <p><a href="https://github.com/rclone/rclone/compare/v1.54.0...v1.55.0">See commits</a></p>
<ul> <ul>

48
MANUAL.md generated
View File

@@ -1,6 +1,6 @@
% rclone(1) User Manual % rclone(1) User Manual
% Nick Craig-Wood % Nick Craig-Wood
% Apr 26, 2021 % Mar 31, 2021
# Rclone syncs your files to cloud storage # Rclone syncs your files to cloud storage
@@ -2931,7 +2931,7 @@ metadata about files like in UNIX. One case that may arise is that other program
(incorrectly) interprets this as the file being accessible by everyone. For example (incorrectly) interprets this as the file being accessible by everyone. For example
an SSH client may warn about "unprotected private key file". an SSH client may warn about "unprotected private key file".
WinFsp 2021 (version 1.9) introduces a new FUSE option "FileSecurity", WinFsp 2021 (version 1.9, still in beta) introduces a new FUSE option "FileSecurity",
that allows the complete specification of file security descriptors using that allows the complete specification of file security descriptors using
[SDDL](https://docs.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-string-format). [SDDL](https://docs.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-string-format).
With this you can work around issues such as the mentioned "unprotected private key file" With this you can work around issues such as the mentioned "unprotected private key file"
@@ -3751,7 +3751,7 @@ If the old version contains only dots and digits (for example `v1.54.0`)
then it's a stable release so you won't need the `--beta` flag. Beta releases then it's a stable release so you won't need the `--beta` flag. Beta releases
have an additional information similar to `v1.54.0-beta.5111.06f1c0c61`. have an additional information similar to `v1.54.0-beta.5111.06f1c0c61`.
(if you are a developer and use a locally built rclone, the version number (if you are a developer and use a locally built rclone, the version number
will end with `-DEV`, you will have to rebuild it as it obviously can't will end with `-DEV`, you will have to rebuild it as it obvisously can't
be distributed). be distributed).
If you previously installed rclone via a package manager, the package may If you previously installed rclone via a package manager, the package may
@@ -6977,7 +6977,7 @@ If you run `rclone config file` you will see where the default
location is for you. location is for you.
Use this flag to override the config location, e.g. `rclone Use this flag to override the config location, e.g. `rclone
--config=".myconfig" config`. --config=".myconfig" .config`.
If the location is set to empty string `""` or the special value If the location is set to empty string `""` or the special value
`/notfound`, or the os null device represented by value `NUL` on `/notfound`, or the os null device represented by value `NUL` on
@@ -11750,7 +11750,7 @@ These flags are available for every command.
--use-json-log Use json log format. --use-json-log Use json log format.
--use-mmap Use mmap allocator (see docs). --use-mmap Use mmap allocator (see docs).
--use-server-modtime Use server modified time instead of object metadata --use-server-modtime Use server modified time instead of object metadata
--user-agent string Set the user-agent to a specified string. The default is rclone/ version (default "rclone/v1.55.1") --user-agent string Set the user-agent to a specified string. The default is rclone/ version (default "rclone/v1.55.0")
-v, --verbose count Print lots more stuff (repeat for more) -v, --verbose count Print lots more stuff (repeat for more)
``` ```
@@ -28837,44 +28837,6 @@ Options:
# Changelog # Changelog
## v1.55.1 - 2021-04-26
[See commits](https://github.com/rclone/rclone/compare/v1.55.0...v1.55.1)
* Bug Fixes
* selfupdate
* Dont detect FUSE if build is static (Ivan Andreev)
* Add build tag noselfupdate (Ivan Andreev)
* sync: Fix incorrect error reported by graceful cutoff (Nick Craig-Wood)
* install.sh: fix macOS arm64 download (Nick Craig-Wood)
* build: Fix version numbers in android branch builds (Nick Craig-Wood)
* docs
* Contributing.md: update setup instructions for go1.16 (Nick Gaya)
* WinFsp 2021 is out of beta (albertony)
* Minor cleanup of space around code section (albertony)
* Fixed some typos (albertony)
* VFS
* Fix a code path which allows dirty data to be removed causing data loss (Nick Craig-Wood)
* Compress
* Fix compressed name regexp (buengese)
* Drive
* Fix backend copyid of google doc to directory (Nick Craig-Wood)
* Don't open browser when service account... (Ansh Mittal)
* Dropbox
* Add missing team_data.member scope for use with --impersonate (Nick Craig-Wood)
* Fix About after scopes changes - rclone config reconnect needed (Nick Craig-Wood)
* Fix Unable to decrypt returned paths from changeNotify (Nick Craig-Wood)
* FTP
* Fix implicit TLS (Ivan Andreev)
* Onedrive
* Work around for random "Unable to initialize RPS" errors (OleFrost)
* SFTP
* Revert sftp library to v1.12.0 from v1.13.0 to fix performance regression (Nick Craig-Wood)
* Fix Update ReadFrom failed: failed to send packet: EOF errors (Nick Craig-Wood)
* Zoho
* Fix error when region isn't set (buengese)
* Do not ask for mountpoint twice when using headless setup (buengese)
## v1.55.0 - 2021-03-31 ## v1.55.0 - 2021-03-31
[See commits](https://github.com/rclone/rclone/compare/v1.54.0...v1.55.0) [See commits](https://github.com/rclone/rclone/compare/v1.54.0...v1.55.0)

73
MANUAL.txt generated
View File

@@ -1,6 +1,6 @@
rclone(1) User Manual rclone(1) User Manual
Nick Craig-Wood Nick Craig-Wood
Apr 26, 2021 Mar 31, 2021
@@ -2036,10 +2036,9 @@ Synopsis
Download a URL's content and copy it to the destination without saving Download a URL's content and copy it to the destination without saving
it in temporary storage. it in temporary storage.
Setting --auto-filename will cause the file name to be retrieved from Setting --auto-filenamewill cause the file name to be retrieved from the
the from URL (after any redirections) and used in the destination path. from URL (after any redirections) and used in the destination path. With
With --print-filename in addition, the resuling file name will be --print-filename in addition, the resuling file name will be printed.
printed.
Setting --no-clobber will prevent overwriting file on the destination if Setting --no-clobber will prevent overwriting file on the destination if
there is one with the same name. there is one with the same name.
@@ -2969,10 +2968,10 @@ One case that may arise is that other programs (incorrectly) interprets
this as the file being accessible by everyone. For example an SSH client this as the file being accessible by everyone. For example an SSH client
may warn about "unprotected private key file". may warn about "unprotected private key file".
WinFsp 2021 (version 1.9) introduces a new FUSE option "FileSecurity", WinFsp 2021 (version 1.9, still in beta) introduces a new FUSE option
that allows the complete specification of file security descriptors "FileSecurity", that allows the complete specification of file security
using SDDL. With this you can work around issues such as the mentioned descriptors using SDDL. With this you can work around issues such as the
"unprotected private key file" by specifying mentioned "unprotected private key file" by specifying
-o FileSecurity="D:P(A;;FA;;;OW)", for file all access (FA) to the owner -o FileSecurity="D:P(A;;FA;;;OW)", for file all access (FA) to the owner
(OW). (OW).
@@ -3798,7 +3797,7 @@ and digits (for example v1.54.0) then it's a stable release so you won't
need the --beta flag. Beta releases have an additional information need the --beta flag. Beta releases have an additional information
similar to v1.54.0-beta.5111.06f1c0c61. (if you are a developer and use similar to v1.54.0-beta.5111.06f1c0c61. (if you are a developer and use
a locally built rclone, the version number will end with -DEV, you will a locally built rclone, the version number will end with -DEV, you will
have to rebuild it as it obviously can't be distributed). have to rebuild it as it obvisously can't be distributed).
If you previously installed rclone via a package manager, the package If you previously installed rclone via a package manager, the package
may include local documentation or configure services. You may wish to may include local documentation or configure services. You may wish to
@@ -7124,7 +7123,7 @@ If you run rclone config file you will see where the default location is
for you. for you.
Use this flag to override the config location, e.g. Use this flag to override the config location, e.g.
rclone --config=".myconfig" config. rclone --config=".myconfig" .config.
If the location is set to empty string "" or the special value If the location is set to empty string "" or the special value
/notfound, or the os null device represented by value NUL on Windows and /notfound, or the os null device represented by value NUL on Windows and
@@ -11863,7 +11862,7 @@ These flags are available for every command.
--use-json-log Use json log format. --use-json-log Use json log format.
--use-mmap Use mmap allocator (see docs). --use-mmap Use mmap allocator (see docs).
--use-server-modtime Use server modified time instead of object metadata --use-server-modtime Use server modified time instead of object metadata
--user-agent string Set the user-agent to a specified string. The default is rclone/ version (default "rclone/v1.55.1") --user-agent string Set the user-agent to a specified string. The default is rclone/ version (default "rclone/v1.55.0")
-v, --verbose count Print lots more stuff (repeat for more) -v, --verbose count Print lots more stuff (repeat for more)
@@ -28815,56 +28814,6 @@ Options:
CHANGELOG CHANGELOG
v1.55.1 - 2021-04-26
See commits
- Bug Fixes
- selfupdate
- Dont detect FUSE if build is static (Ivan Andreev)
- Add build tag noselfupdate (Ivan Andreev)
- sync: Fix incorrect error reported by graceful cutoff (Nick
Craig-Wood)
- install.sh: fix macOS arm64 download (Nick Craig-Wood)
- build: Fix version numbers in android branch builds (Nick
Craig-Wood)
- docs
- Contributing.md: update setup instructions for go1.16 (Nick
Gaya)
- WinFsp 2021 is out of beta (albertony)
- Minor cleanup of space around code section (albertony)
- Fixed some typos (albertony)
- VFS
- Fix a code path which allows dirty data to be removed causing
data loss (Nick Craig-Wood)
- Compress
- Fix compressed name regexp (buengese)
- Drive
- Fix backend copyid of google doc to directory (Nick Craig-Wood)
- Don't open browser when service account... (Ansh Mittal)
- Dropbox
- Add missing team_data.member scope for use with --impersonate
(Nick Craig-Wood)
- Fix About after scopes changes - rclone config reconnect needed
(Nick Craig-Wood)
- Fix Unable to decrypt returned paths from changeNotify (Nick
Craig-Wood)
- FTP
- Fix implicit TLS (Ivan Andreev)
- Onedrive
- Work around for random "Unable to initialize RPS" errors
(OleFrost)
- SFTP
- Revert sftp library to v1.12.0 from v1.13.0 to fix performance
regression (Nick Craig-Wood)
- Fix Update ReadFrom failed: failed to send packet: EOF errors
(Nick Craig-Wood)
- Zoho
- Fix error when region isn't set (buengese)
- Do not ask for mountpoint twice when using headless setup
(buengese)
v1.55.0 - 2021-03-31 v1.55.0 - 2021-03-31
See commits See commits

View File

@@ -1 +1 @@
v1.55.1 v1.56.0

View File

@@ -53,7 +53,7 @@ const (
Gzip = 2 Gzip = 2
) )
var nameRegexp = regexp.MustCompile("^(.+?)\\.([A-Za-z0-9-_]{11})$") var nameRegexp = regexp.MustCompile("^(.+?)\\.([A-Za-z0-9+_]{11})$")
// Register with Fs // Register with Fs
func init() { func init() {

View File

@@ -199,7 +199,7 @@ func init() {
m.Set("root_folder_id", "appDataFolder") m.Set("root_folder_id", "appDataFolder")
} }
if opt.ServiceAccountFile == "" && opt.ServiceAccountCredentials == "" { if opt.ServiceAccountFile == "" {
err = oauthutil.Config(ctx, "drive", name, m, driveConfig, nil) err = oauthutil.Config(ctx, "drive", name, m, driveConfig, nil)
if err != nil { if err != nil {
log.Fatalf("Failed to configure token: %v", err) log.Fatalf("Failed to configure token: %v", err)
@@ -2959,12 +2959,12 @@ func (f *Fs) makeShortcut(ctx context.Context, srcPath string, dstFs *Fs, dstPat
} }
// List all team drives // List all team drives
func (f *Fs) listTeamDrives(ctx context.Context) (drives []*drive.TeamDrive, err error) { func (f *Fs) listTeamDrives(ctx context.Context) (drives []*drive.Drive, err error) {
drives = []*drive.TeamDrive{} drives = []*drive.Drive{}
listTeamDrives := f.svc.Teamdrives.List().PageSize(100) listTeamDrives := f.svc.Drives.List().PageSize(100)
var defaultFs Fs // default Fs with default Options var defaultFs Fs // default Fs with default Options
for { for {
var teamDrives *drive.TeamDriveList var teamDrives *drive.DriveList
err = f.pacer.Call(func() (bool, error) { err = f.pacer.Call(func() (bool, error) {
teamDrives, err = listTeamDrives.Context(ctx).Do() teamDrives, err = listTeamDrives.Context(ctx).Do()
return defaultFs.shouldRetry(ctx, err) return defaultFs.shouldRetry(ctx, err)
@@ -2972,7 +2972,7 @@ func (f *Fs) listTeamDrives(ctx context.Context) (drives []*drive.TeamDrive, err
if err != nil { if err != nil {
return drives, errors.Wrap(err, "listing Team Drives failed") return drives, errors.Wrap(err, "listing Team Drives failed")
} }
drives = append(drives, teamDrives.TeamDrives...) drives = append(drives, teamDrives.Drives...)
if teamDrives.NextPageToken == "" { if teamDrives.NextPageToken == "" {
break break
} }

View File

@@ -99,10 +99,8 @@ var (
"files.content.write", "files.content.write",
"files.content.read", "files.content.read",
"sharing.write", "sharing.write",
"account_info.read", // needed for About
// "file_requests.write", // "file_requests.write",
// "members.read", // needed for impersonate - but causes app to need to be approved by Dropbox Team Admin during the flow // "members.read", // needed for impersonate - but causes app to need to be approved by Dropbox Team Admin during the flow
// "team_data.member"
}, },
// Endpoint: oauth2.Endpoint{ // Endpoint: oauth2.Endpoint{
// AuthURL: "https://www.dropbox.com/1/oauth2/authorize", // AuthURL: "https://www.dropbox.com/1/oauth2/authorize",
@@ -132,8 +130,8 @@ func getOauthConfig(m configmap.Mapper) *oauth2.Config {
} }
// Make a copy of the config // Make a copy of the config
config := *dropboxConfig config := *dropboxConfig
// Make a copy of the scopes with extra scopes requires appended // Make a copy of the scopes with "members.read" appended
config.Scopes = append(config.Scopes, "members.read", "team_data.member") config.Scopes = append(config.Scopes, "members.read")
return &config return &config
} }
@@ -1086,13 +1084,30 @@ func (f *Fs) PublicLink(ctx context.Context, remote string, expire fs.Duration,
fs.Debugf(f, "attempting to share '%s' (absolute path: %s)", remote, absPath) fs.Debugf(f, "attempting to share '%s' (absolute path: %s)", remote, absPath)
createArg := sharing.CreateSharedLinkWithSettingsArg{ createArg := sharing.CreateSharedLinkWithSettingsArg{
Path: absPath, Path: absPath,
// FIXME this gives settings_error/not_authorized/.. errors Settings: &sharing.SharedLinkSettings{
// and the expires setting isn't in the documentation so remove RequestedVisibility: &sharing.RequestedVisibility{
// for now. Tagged: dropbox.Tagged{Tag: sharing.RequestedVisibilityPublic},
// Settings: &sharing.SharedLinkSettings{ },
// Expires: time.Now().Add(time.Duration(expire)).UTC().Round(time.Second), Audience: &sharing.LinkAudience{
// }, Tagged: dropbox.Tagged{Tag: sharing.LinkAudiencePublic},
},
Access: &sharing.RequestedLinkAccessLevel{
Tagged: dropbox.Tagged{Tag: sharing.RequestedLinkAccessLevelViewer},
},
},
} }
if expire < fs.DurationOff {
expiryTime := time.Now().Add(time.Duration(expire)).UTC().Round(time.Second)
createArg.Settings.Expires = expiryTime
}
// FIXME note we can't set Settings for non enterprise dropbox
// because of https://github.com/dropbox/dropbox-sdk-go-unofficial/issues/75
// however this only goes wrong when we set Expires, so as a
// work-around remove Settings unless expire is set.
if expire == fs.DurationOff {
createArg.Settings = nil
}
var linkRes sharing.IsSharedLinkMetadata var linkRes sharing.IsSharedLinkMetadata
err = f.pacer.Call(func() (bool, error) { err = f.pacer.Call(func() (bool, error) {
linkRes, err = f.sharing.CreateSharedLinkWithSettings(&createArg) linkRes, err = f.sharing.CreateSharedLinkWithSettings(&createArg)
@@ -1336,13 +1351,13 @@ func (f *Fs) changeNotifyRunner(ctx context.Context, notifyFunc func(string, fs.
switch info := entry.(type) { switch info := entry.(type) {
case *files.FolderMetadata: case *files.FolderMetadata:
entryType = fs.EntryDirectory entryType = fs.EntryDirectory
entryPath = strings.TrimPrefix(info.PathDisplay, f.slashRootSlash) entryPath = strings.TrimLeft(info.PathDisplay, f.slashRootSlash)
case *files.FileMetadata: case *files.FileMetadata:
entryType = fs.EntryObject entryType = fs.EntryObject
entryPath = strings.TrimPrefix(info.PathDisplay, f.slashRootSlash) entryPath = strings.TrimLeft(info.PathDisplay, f.slashRootSlash)
case *files.DeletedMetadata: case *files.DeletedMetadata:
entryType = fs.EntryObject entryType = fs.EntryObject
entryPath = strings.TrimPrefix(info.PathDisplay, f.slashRootSlash) entryPath = strings.TrimLeft(info.PathDisplay, f.slashRootSlash)
default: default:
fs.Errorf(entry, "dropbox ChangeNotify: ignoring unknown EntryType %T", entry) fs.Errorf(entry, "dropbox ChangeNotify: ignoring unknown EntryType %T", entry)
continue continue

View File

@@ -348,8 +348,10 @@ func (f *Fs) putUnchecked(ctx context.Context, in io.Reader, remote string, size
return nil, err return nil, err
} }
if len(fileUploadResponse.Links) != 1 { if len(fileUploadResponse.Links) == 0 {
return nil, errors.New("unexpected amount of files") return nil, errors.New("upload response not found")
} else if len(fileUploadResponse.Links) > 1 {
fs.Debugf(remote, "Multiple upload responses found, using the first")
} }
link := fileUploadResponse.Links[0] link := fileUploadResponse.Links[0]

View File

@@ -241,6 +241,23 @@ func (dl *debugLog) Write(p []byte) (n int, err error) {
return len(p), nil return len(p), nil
} }
type dialCtx struct {
f *Fs
ctx context.Context
}
// dial a new connection with fshttp dialer
func (d *dialCtx) dial(network, address string) (net.Conn, error) {
conn, err := fshttp.NewDialer(d.ctx).Dial(network, address)
if err != nil {
return nil, err
}
if d.f.tlsConf != nil {
conn = tls.Client(conn, d.f.tlsConf)
}
return conn, err
}
// shouldRetry returns a boolean as to whether this err deserve to be // shouldRetry returns a boolean as to whether this err deserve to be
// retried. It returns the err as a convenience // retried. It returns the err as a convenience
func shouldRetry(ctx context.Context, err error) (bool, error) { func shouldRetry(ctx context.Context, err error) (bool, error) {
@@ -260,22 +277,9 @@ func shouldRetry(ctx context.Context, err error) (bool, error) {
// Open a new connection to the FTP server. // Open a new connection to the FTP server.
func (f *Fs) ftpConnection(ctx context.Context) (c *ftp.ServerConn, err error) { func (f *Fs) ftpConnection(ctx context.Context) (c *ftp.ServerConn, err error) {
fs.Debugf(f, "Connecting to FTP server") fs.Debugf(f, "Connecting to FTP server")
dCtx := dialCtx{f, ctx}
// Make ftp library dial with fshttp dialer optionally using TLS ftpConfig := []ftp.DialOption{ftp.DialWithDialFunc(dCtx.dial)}
dial := func(network, address string) (conn net.Conn, err error) { if f.opt.ExplicitTLS {
conn, err = fshttp.NewDialer(ctx).Dial(network, address)
if f.tlsConf != nil && err == nil {
conn = tls.Client(conn, f.tlsConf)
}
return
}
ftpConfig := []ftp.DialOption{ftp.DialWithDialFunc(dial)}
if f.opt.TLS {
// Our dialer takes care of TLS but ftp library also needs tlsConf
// as a trigger for sending PSBZ and PROT options to server.
ftpConfig = append(ftpConfig, ftp.DialWithTLS(f.tlsConf))
} else if f.opt.ExplicitTLS {
ftpConfig = append(ftpConfig, ftp.DialWithExplicitTLS(f.tlsConf)) ftpConfig = append(ftpConfig, ftp.DialWithExplicitTLS(f.tlsConf))
// Initial connection needs to be cleartext for explicit TLS // Initial connection needs to be cleartext for explicit TLS
conn, err := fshttp.NewDialer(ctx).Dial("tcp", f.dialAddr) conn, err := fshttp.NewDialer(ctx).Dial("tcp", f.dialAddr)

View File

@@ -361,6 +361,11 @@ This will only work if you are copying between two OneDrive *Personal* drives AN
the files to copy are already shared between them. In other cases, rclone will the files to copy are already shared between them. In other cases, rclone will
fall back to normal copy (which will be slightly slower).`, fall back to normal copy (which will be slightly slower).`,
Advanced: true, Advanced: true,
}, {
Name: "list_chunk",
Help: "Size of listing chunk.",
Default: 1000,
Advanced: true,
}, { }, {
Name: "no_versions", Name: "no_versions",
Default: false, Default: false,
@@ -468,6 +473,7 @@ type Options struct {
DriveType string `config:"drive_type"` DriveType string `config:"drive_type"`
ExposeOneNoteFiles bool `config:"expose_onenote_files"` ExposeOneNoteFiles bool `config:"expose_onenote_files"`
ServerSideAcrossConfigs bool `config:"server_side_across_configs"` ServerSideAcrossConfigs bool `config:"server_side_across_configs"`
ListChunk int64 `config:"list_chunk"`
NoVersions bool `config:"no_versions"` NoVersions bool `config:"no_versions"`
LinkScope string `config:"link_scope"` LinkScope string `config:"link_scope"`
LinkType string `config:"link_type"` LinkType string `config:"link_type"`
@@ -560,9 +566,6 @@ func shouldRetry(ctx context.Context, resp *http.Response, err error) (bool, err
if len(resp.Header["Www-Authenticate"]) == 1 && strings.Index(resp.Header["Www-Authenticate"][0], "expired_token") >= 0 { if len(resp.Header["Www-Authenticate"]) == 1 && strings.Index(resp.Header["Www-Authenticate"][0], "expired_token") >= 0 {
retry = true retry = true
fs.Debugf(nil, "Should retry: %v", err) fs.Debugf(nil, "Should retry: %v", err)
} else if err != nil && strings.Contains(err.Error(), "Unable to initialize RPS") {
retry = true
fs.Debugf(nil, "HTTP 401: Unable to initialize RPS. Trying again.")
} }
case 429: // Too Many Requests. case 429: // Too Many Requests.
// see https://docs.microsoft.com/en-us/sharepoint/dev/general-development/how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online // see https://docs.microsoft.com/en-us/sharepoint/dev/general-development/how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online
@@ -899,7 +902,7 @@ type listAllFn func(*api.Item) bool
func (f *Fs) listAll(ctx context.Context, dirID string, directoriesOnly bool, filesOnly bool, fn listAllFn) (found bool, err error) { func (f *Fs) listAll(ctx context.Context, dirID string, directoriesOnly bool, filesOnly bool, fn listAllFn) (found bool, err error) {
// Top parameter asks for bigger pages of data // Top parameter asks for bigger pages of data
// https://dev.onedrive.com/odata/optional-query-parameters.htm // https://dev.onedrive.com/odata/optional-query-parameters.htm
opts := f.newOptsCall(dirID, "GET", "/children?$top=1000") opts := f.newOptsCall(dirID, "GET", fmt.Sprintf("/children?$top=%d", f.opt.ListChunk))
OUTER: OUTER:
for { for {
var result api.ListChildrenResponse var result api.ListChildrenResponse
@@ -1426,7 +1429,7 @@ func (f *Fs) PublicLink(ctx context.Context, remote string, expire fs.Duration,
Password: f.opt.LinkPassword, Password: f.opt.LinkPassword,
} }
if expire < fs.Duration(time.Hour*24*365*100) { if expire < fs.DurationOff {
expiry := time.Now().Add(time.Duration(expire)) expiry := time.Now().Add(time.Duration(expire))
share.Expiry = &expiry share.Expiry = &expiry
} }

View File

@@ -75,8 +75,19 @@ const (
// ShowVersion prints the version to stdout // ShowVersion prints the version to stdout
func ShowVersion() { func ShowVersion() {
osVersion, osKernel := buildinfo.GetOSVersion()
if osVersion == "" {
osVersion = "unknown"
}
if osKernel == "" {
osKernel = "unknown"
}
linking, tagString := buildinfo.GetLinkingAndTags() linking, tagString := buildinfo.GetLinkingAndTags()
fmt.Printf("rclone %s\n", fs.Version) fmt.Printf("rclone %s\n", fs.Version)
fmt.Printf("- os/version: %s\n", osVersion)
fmt.Printf("- os/kernel: %s\n", osKernel)
fmt.Printf("- os/type: %s\n", runtime.GOOS) fmt.Printf("- os/type: %s\n", runtime.GOOS)
fmt.Printf("- os/arch: %s\n", runtime.GOARCH) fmt.Printf("- os/arch: %s\n", runtime.GOARCH)
fmt.Printf("- go/version: %s\n", runtime.Version()) fmt.Printf("- go/version: %s\n", runtime.Version())

View File

@@ -3,7 +3,6 @@ package link
import ( import (
"context" "context"
"fmt" "fmt"
"time"
"github.com/rclone/rclone/cmd" "github.com/rclone/rclone/cmd"
"github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs"
@@ -13,7 +12,7 @@ import (
) )
var ( var (
expire = fs.Duration(time.Hour * 24 * 365 * 100) expire = fs.DurationOff
unlink = false unlink = false
) )

View File

@@ -29,13 +29,16 @@ var commandDefinition = &cobra.Command{
Use: "version", Use: "version",
Short: `Show the version number.`, Short: `Show the version number.`,
Long: ` Long: `
Show the rclone version number, the go version, the build target OS and Show the rclone version number, the go version, the build target
architecture, build tags and the type of executable (static or dynamic). OS and architecture, the runtime OS and kernel version and bitness,
build tags and the type of executable (static or dynamic).
For example: For example:
$ rclone version $ rclone version
rclone v1.54 rclone v1.55.0
- os/version: ubuntu 18.04 (64 bit)
- os/kernel: 4.15.0-136-generic (x86_64)
- os/type: linux - os/type: linux
- os/arch: amd64 - os/arch: amd64
- go/version: go1.16 - go/version: go1.16

View File

@@ -478,3 +478,4 @@ put them back in again.` >}}
* Manish Kumar <krmanish260@gmail.com> * Manish Kumar <krmanish260@gmail.com>
* x0b <x0bdev@gmail.com> * x0b <x0bdev@gmail.com>
* CERN through the CS3MESH4EOSC Project * CERN through the CS3MESH4EOSC Project
* Nick Gaya <nicholasgaya+github@gmail.com>

View File

@@ -5,44 +5,6 @@ description: "Rclone Changelog"
# Changelog # Changelog
## v1.55.1 - 2021-04-26
[See commits](https://github.com/rclone/rclone/compare/v1.55.0...v1.55.1)
* Bug Fixes
* selfupdate
* Dont detect FUSE if build is static (Ivan Andreev)
* Add build tag noselfupdate (Ivan Andreev)
* sync: Fix incorrect error reported by graceful cutoff (Nick Craig-Wood)
* install.sh: fix macOS arm64 download (Nick Craig-Wood)
* build: Fix version numbers in android branch builds (Nick Craig-Wood)
* docs
* Contributing.md: update setup instructions for go1.16 (Nick Gaya)
* WinFsp 2021 is out of beta (albertony)
* Minor cleanup of space around code section (albertony)
* Fixed some typos (albertony)
* VFS
* Fix a code path which allows dirty data to be removed causing data loss (Nick Craig-Wood)
* Compress
* Fix compressed name regexp (buengese)
* Drive
* Fix backend copyid of google doc to directory (Nick Craig-Wood)
* Don't open browser when service account... (Ansh Mittal)
* Dropbox
* Add missing team_data.member scope for use with --impersonate (Nick Craig-Wood)
* Fix About after scopes changes - rclone config reconnect needed (Nick Craig-Wood)
* Fix Unable to decrypt returned paths from changeNotify (Nick Craig-Wood)
* FTP
* Fix implicit TLS (Ivan Andreev)
* Onedrive
* Work around for random "Unable to initialize RPS" errors (OleFrost)
* SFTP
* Revert sftp library to v1.12.0 from v1.13.0 to fix performance regression (Nick Craig-Wood)
* Fix Update ReadFrom failed: failed to send packet: EOF errors (Nick Craig-Wood)
* Zoho
* Fix error when region isn't set (buengese)
* Do not ask for mountpoint twice when using headless setup (buengese)
## v1.55.0 - 2021-03-31 ## v1.55.0 - 2021-03-31
[See commits](https://github.com/rclone/rclone/compare/v1.54.0...v1.55.0) [See commits](https://github.com/rclone/rclone/compare/v1.54.0...v1.55.0)

View File

@@ -184,7 +184,7 @@ metadata about files like in UNIX. One case that may arise is that other program
(incorrectly) interprets this as the file being accessible by everyone. For example (incorrectly) interprets this as the file being accessible by everyone. For example
an SSH client may warn about "unprotected private key file". an SSH client may warn about "unprotected private key file".
WinFsp 2021 (version 1.9) introduces a new FUSE option "FileSecurity", WinFsp 2021 (version 1.9, still in beta) introduces a new FUSE option "FileSecurity",
that allows the complete specification of file security descriptors using that allows the complete specification of file security descriptors using
[SDDL](https://docs.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-string-format). [SDDL](https://docs.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-string-format).
With this you can work around issues such as the mentioned "unprotected private key file" With this you can work around issues such as the mentioned "unprotected private key file"

View File

@@ -37,7 +37,7 @@ If the old version contains only dots and digits (for example `v1.54.0`)
then it's a stable release so you won't need the `--beta` flag. Beta releases then it's a stable release so you won't need the `--beta` flag. Beta releases
have an additional information similar to `v1.54.0-beta.5111.06f1c0c61`. have an additional information similar to `v1.54.0-beta.5111.06f1c0c61`.
(if you are a developer and use a locally built rclone, the version number (if you are a developer and use a locally built rclone, the version number
will end with `-DEV`, you will have to rebuild it as it obviously can't will end with `-DEV`, you will have to rebuild it as it obvisously can't
be distributed). be distributed).
If you previously installed rclone via a package manager, the package may If you previously installed rclone via a package manager, the package may

View File

@@ -285,6 +285,12 @@ dropbox:dir` will return the error `Failed to purge: There are too
many files involved in this operation`. As a work-around do an many files involved in this operation`. As a work-around do an
`rclone delete dropbox:dir` followed by an `rclone rmdir dropbox:dir`. `rclone delete dropbox:dir` followed by an `rclone rmdir dropbox:dir`.
When using `rclone link` you'll need to set `--expire` if using a
non-personal account otherwise the visibility may not be correct.
(Note that `--expire` isn't supported on personal accounts). See the
[forum discussion](https://forum.rclone.org/t/rclone-link-dropbox-permissions/23211) and the
[dropbox SDK issue](https://github.com/dropbox/dropbox-sdk-go-unofficial/issues/75).
### Get your own Dropbox App ID ### ### Get your own Dropbox App ID ###
When you use rclone with Dropbox in its default configuration you are using rclone's App ID. This is shared between all the rclone users. When you use rclone with Dropbox in its default configuration you are using rclone's App ID. This is shared between all the rclone users.

View File

@@ -153,7 +153,7 @@ These flags are available for every command.
--use-json-log Use json log format. --use-json-log Use json log format.
--use-mmap Use mmap allocator (see docs). --use-mmap Use mmap allocator (see docs).
--use-server-modtime Use server modified time instead of object metadata --use-server-modtime Use server modified time instead of object metadata
--user-agent string Set the user-agent to a specified string. The default is rclone/ version (default "rclone/v1.55.1") --user-agent string Set the user-agent to a specified string. The default is rclone/ version (default "rclone/v1.55.0")
-v, --verbose count Print lots more stuff (repeat for more) -v, --verbose count Print lots more stuff (repeat for more)
``` ```
@@ -415,6 +415,7 @@ and may be set in the config file.
--onedrive-link-password string Set the password for links created by the link command. --onedrive-link-password string Set the password for links created by the link command.
--onedrive-link-scope string Set the scope of the links created by the link command. (default "anonymous") --onedrive-link-scope string Set the scope of the links created by the link command. (default "anonymous")
--onedrive-link-type string Set the type of the links created by the link command. (default "view") --onedrive-link-type string Set the type of the links created by the link command. (default "view")
--onedrive-list-chunk int Size of listing chunk. (default 1000)
--onedrive-no-versions Remove all versions on modifying operations --onedrive-no-versions Remove all versions on modifying operations
--onedrive-region string Choose national cloud region for OneDrive. (default "global") --onedrive-region string Choose national cloud region for OneDrive. (default "global")
--onedrive-server-side-across-configs Allow server-side operations (e.g. copy) to work across different onedrive configs. --onedrive-server-side-across-configs Allow server-side operations (e.g. copy) to work across different onedrive configs.

View File

@@ -325,6 +325,15 @@ fall back to normal copy (which will be slightly slower).
- Type: bool - Type: bool
- Default: false - Default: false
#### --onedrive-list-chunk
Size of listing chunk.
- Config: list_chunk
- Env Var: RCLONE_ONEDRIVE_LIST_CHUNK
- Type: int
- Default: 1000
#### --onedrive-no-versions #### --onedrive-no-versions
Remove all versions on modifying operations Remove all versions on modifying operations

View File

@@ -1 +1 @@
v1.55.1 v1.56.0

View File

@@ -2,9 +2,11 @@ package config
import ( import (
"context" "context"
"fmt"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs"
"github.com/rclone/rclone/fs/config/configmap"
) )
// Authorize is for remote authorization of headless machines. // Authorize is for remote authorization of headless machines.
@@ -16,33 +18,61 @@ import (
func Authorize(ctx context.Context, args []string, noAutoBrowser bool) error { func Authorize(ctx context.Context, args []string, noAutoBrowser bool) error {
ctx = suppressConfirm(ctx) ctx = suppressConfirm(ctx)
switch len(args) { switch len(args) {
case 1, 3: case 1, 2, 3:
default: default:
return errors.Errorf("invalid number of arguments: %d", len(args)) return errors.Errorf("invalid number of arguments: %d", len(args))
} }
newType := args[0] Type := args[0] // FIXME could read this from input
f := fs.MustFind(newType) ri, err := fs.Find(Type)
if f.Config == nil { if err != nil {
return errors.Errorf("can't authorize fs %q", newType) return err
}
if ri.Config == nil {
return errors.Errorf("can't authorize fs %q", Type)
} }
// Name used for temporary fs
name := "**temp-fs**"
// Make sure we delete it // Config map for remote
defer DeleteRemote(name) inM := configmap.Simple{}
// Indicate that we are running rclone authorize // Indicate that we are running rclone authorize
Data.SetValue(name, ConfigAuthorize, "true") inM[ConfigAuthorize] = "true"
if noAutoBrowser { if noAutoBrowser {
Data.SetValue(name, ConfigAuthNoBrowser, "true") inM[ConfigAuthNoBrowser] = "true"
} }
if len(args) == 3 { // Add extra parameters if supplied
Data.SetValue(name, ConfigClientID, args[1]) if len(args) == 2 {
Data.SetValue(name, ConfigClientSecret, args[2]) err := inM.Decode(args[1])
if err != nil {
return err
}
} else if len(args) == 3 {
inM[ConfigClientID] = args[1]
inM[ConfigClientSecret] = args[2]
} }
m := fs.ConfigMap(f, name, nil) // Name used for temporary remote
f.Config(ctx, name, m) name := "**temp-fs**"
m := fs.ConfigMap(ri, name, inM)
outM := configmap.Simple{}
m.ClearSetters()
m.AddSetter(outM)
m.AddGetter(outM, configmap.PriorityNormal)
ri.Config(ctx, name, m)
// Print the code for the user to paste
out := outM["token"]
// If received a config blob, then return one
if len(args) == 2 {
out, err = outM.Encode()
if err != nil {
return err
}
}
fmt.Printf("Paste the following into your remote machine --->\n%s\n<---End paste\n", out)
return nil return nil
} }

View File

@@ -2,8 +2,24 @@
package configmap package configmap
import ( import (
"encoding/base64"
"encoding/json"
"sort" "sort"
"strings" "strings"
"unicode"
"github.com/pkg/errors"
)
// Priority of getters
type Priority int8
// Priority levels for AddGetter
const (
PriorityNormal Priority = iota
PriorityConfig // use for reading from the config
PriorityDefault // use for default values
PriorityMax
) )
// Getter provides an interface to get config items // Getter provides an interface to get config items
@@ -30,8 +46,12 @@ type Mapper interface {
// Getter interfaces. // Getter interfaces.
type Map struct { type Map struct {
setters []Setter setters []Setter
getters []Getter getters []getprio
override []Getter }
type getprio struct {
getter Getter
priority Priority
} }
// New returns an empty Map // New returns an empty Map
@@ -39,18 +59,12 @@ func New() *Map {
return &Map{} return &Map{}
} }
// AddGetter appends a getter onto the end of the getters // AddGetter appends a getter onto the end of the getters in priority order
func (c *Map) AddGetter(getter Getter) *Map { func (c *Map) AddGetter(getter Getter, priority Priority) *Map {
c.getters = append(c.getters, getter) c.getters = append(c.getters, getprio{getter, priority})
return c sort.SliceStable(c.getters, func(i, j int) bool {
} return c.getters[i].priority < c.getters[j].priority
})
// AddOverrideGetter appends a getter onto the end of the getters
//
// It also appends it onto the override getters for GetOverride
func (c *Map) AddOverrideGetter(getter Getter) *Map {
c.getters = append(c.getters, getter)
c.override = append(c.override, getter)
return c return c
} }
@@ -60,12 +74,34 @@ func (c *Map) AddSetter(setter Setter) *Map {
return c return c
} }
// get gets an item with the key passed in and return the value from // ClearSetters removes all the setters set so far
// the first getter. If the item is found then it returns true, func (c *Map) ClearSetters() *Map {
// otherwise false. c.setters = nil
func (c *Map) get(key string, getters []Getter) (value string, ok bool) { return c
for _, do := range getters { }
value, ok = do.Get(key)
// ClearGetters removes all the getters with the priority given
func (c *Map) ClearGetters(priority Priority) *Map {
getters := c.getters[:0]
for _, item := range c.getters {
if item.priority != priority {
getters = append(getters, item)
}
}
c.getters = getters
return c
}
// GetPriority gets an item with the key passed in and return the
// value from the first getter to return a result with priority <=
// maxPriority. If the item is found then it returns true, otherwise
// false.
func (c *Map) GetPriority(key string, maxPriority Priority) (value string, ok bool) {
for _, item := range c.getters {
if item.priority > maxPriority {
break
}
value, ok = item.getter.Get(key)
if ok { if ok {
return value, ok return value, ok
} }
@@ -77,14 +113,7 @@ func (c *Map) get(key string, getters []Getter) (value string, ok bool) {
// the first getter. If the item is found then it returns true, // the first getter. If the item is found then it returns true,
// otherwise false. // otherwise false.
func (c *Map) Get(key string) (value string, ok bool) { func (c *Map) Get(key string) (value string, ok bool) {
return c.get(key, c.getters) return c.GetPriority(key, PriorityMax)
}
// GetOverride gets an item with the key passed in and return the
// value from the first override getter. If the item is found then it
// returns true, otherwise false.
func (c *Map) GetOverride(key string) (value string, ok bool) {
return c.get(key, c.override)
} }
// Set sets an item into all the stored setters. // Set sets an item into all the stored setters.
@@ -135,3 +164,38 @@ func (c Simple) String() string {
} }
return out.String() return out.String()
} }
// Encode from c into a string suitable for putting on the command line
func (c Simple) Encode() (string, error) {
if len(c) == 0 {
return "", nil
}
buf, err := json.Marshal(c)
if err != nil {
return "", errors.Wrap(err, "encode simple map")
}
return base64.RawStdEncoding.EncodeToString(buf), nil
}
// Decode an Encode~d string in into c
func (c Simple) Decode(in string) error {
// Remove all whitespace from the input string
in = strings.Map(func(r rune) rune {
if unicode.IsSpace(r) {
return -1
}
return r
}, in)
if len(in) == 0 {
return nil
}
decodedM, err := base64.RawStdEncoding.DecodeString(in)
if err != nil {
return errors.Wrap(err, "decode simple map")
}
err = json.Unmarshal(decodedM, &c)
if err != nil {
return errors.Wrap(err, "parse simple map")
}
return nil
}

View File

@@ -1,9 +1,11 @@
package configmap package configmap
import ( import (
"encoding/base64"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
) )
var ( var (
@@ -27,7 +29,7 @@ func TestConfigMapGet(t *testing.T) {
"config1": "one", "config1": "one",
} }
m.AddGetter(m1) m.AddGetter(m1, PriorityNormal)
value, found = m.Get("config1") value, found = m.Get("config1")
assert.Equal(t, "one", value) assert.Equal(t, "one", value)
@@ -42,7 +44,7 @@ func TestConfigMapGet(t *testing.T) {
"config2": "two2", "config2": "two2",
} }
m.AddGetter(m2) m.AddGetter(m2, PriorityNormal)
value, found = m.Get("config1") value, found = m.Get("config1")
assert.Equal(t, "one", value) assert.Equal(t, "one", value)
@@ -88,56 +90,160 @@ func TestConfigMapSet(t *testing.T) {
"config1": "beetroot", "config1": "beetroot",
"config2": "potato", "config2": "potato",
}, m2) }, m2)
m.ClearSetters()
// Check that nothing gets set
m.Set("config1", "BEETROOT")
assert.Equal(t, Simple{
"config1": "beetroot",
"config2": "potato",
}, m1)
assert.Equal(t, Simple{
"config1": "beetroot",
"config2": "potato",
}, m2)
} }
func TestConfigMapGetOverride(t *testing.T) { func TestConfigMapGetPriority(t *testing.T) {
m := New() m := New()
value, found := m.GetOverride("config1") value, found := m.GetPriority("config1", PriorityMax)
assert.Equal(t, "", value) assert.Equal(t, "", value)
assert.Equal(t, false, found) assert.Equal(t, false, found)
value, found = m.GetOverride("config2") value, found = m.GetPriority("config2", PriorityMax)
assert.Equal(t, "", value) assert.Equal(t, "", value)
assert.Equal(t, false, found) assert.Equal(t, false, found)
m1 := Simple{ m1 := Simple{
"config1": "one", "config1": "one",
"config3": "three",
} }
m.AddOverrideGetter(m1) m.AddGetter(m1, PriorityConfig)
value, found = m.GetOverride("config1") value, found = m.GetPriority("config1", PriorityNormal)
assert.Equal(t, "", value)
assert.Equal(t, false, found)
value, found = m.GetPriority("config2", PriorityNormal)
assert.Equal(t, "", value)
assert.Equal(t, false, found)
value, found = m.GetPriority("config3", PriorityNormal)
assert.Equal(t, "", value)
assert.Equal(t, false, found)
value, found = m.GetPriority("config1", PriorityConfig)
assert.Equal(t, "one", value) assert.Equal(t, "one", value)
assert.Equal(t, true, found) assert.Equal(t, true, found)
value, found = m.GetOverride("config2") value, found = m.GetPriority("config2", PriorityConfig)
assert.Equal(t, "", value) assert.Equal(t, "", value)
assert.Equal(t, false, found) assert.Equal(t, false, found)
value, found = m.GetPriority("config3", PriorityConfig)
assert.Equal(t, "three", value)
assert.Equal(t, true, found)
value, found = m.GetPriority("config1", PriorityMax)
assert.Equal(t, "one", value)
assert.Equal(t, true, found)
value, found = m.GetPriority("config2", PriorityMax)
assert.Equal(t, "", value)
assert.Equal(t, false, found)
value, found = m.GetPriority("config3", PriorityMax)
assert.Equal(t, "three", value)
assert.Equal(t, true, found)
m2 := Simple{ m2 := Simple{
"config1": "one2", "config1": "one2",
"config2": "two2", "config2": "two2",
} }
m.AddGetter(m2) m.AddGetter(m2, PriorityNormal)
value, found = m.GetOverride("config1") value, found = m.GetPriority("config1", PriorityNormal)
assert.Equal(t, "one", value) assert.Equal(t, "one2", value)
assert.Equal(t, true, found) assert.Equal(t, true, found)
value, found = m.GetOverride("config2") value, found = m.GetPriority("config2", PriorityNormal)
assert.Equal(t, "", value)
assert.Equal(t, false, found)
value, found = m.Get("config1")
assert.Equal(t, "one", value)
assert.Equal(t, true, found)
value, found = m.Get("config2")
assert.Equal(t, "two2", value) assert.Equal(t, "two2", value)
assert.Equal(t, true, found) assert.Equal(t, true, found)
value, found = m.GetPriority("config3", PriorityNormal)
assert.Equal(t, "", value)
assert.Equal(t, false, found)
value, found = m.GetPriority("config1", PriorityConfig)
assert.Equal(t, "one2", value)
assert.Equal(t, true, found)
value, found = m.GetPriority("config2", PriorityConfig)
assert.Equal(t, "two2", value)
assert.Equal(t, true, found)
value, found = m.GetPriority("config3", PriorityConfig)
assert.Equal(t, "three", value)
assert.Equal(t, true, found)
value, found = m.GetPriority("config1", PriorityMax)
assert.Equal(t, "one2", value)
assert.Equal(t, true, found)
value, found = m.GetPriority("config2", PriorityMax)
assert.Equal(t, "two2", value)
assert.Equal(t, true, found)
value, found = m.GetPriority("config3", PriorityMax)
assert.Equal(t, "three", value)
assert.Equal(t, true, found)
}
func TestConfigMapClearGetters(t *testing.T) {
m := New()
m1 := Simple{}
m2 := Simple{}
m3 := Simple{}
m.AddGetter(m1, PriorityNormal)
m.AddGetter(m2, PriorityDefault)
m.AddGetter(m3, PriorityConfig)
assert.Equal(t, []getprio{
{m1, PriorityNormal},
{m3, PriorityConfig},
{m2, PriorityDefault},
}, m.getters)
m.ClearGetters(PriorityConfig)
assert.Equal(t, []getprio{
{m1, PriorityNormal},
{m2, PriorityDefault},
}, m.getters)
m.ClearGetters(PriorityNormal)
assert.Equal(t, []getprio{
{m2, PriorityDefault},
}, m.getters)
m.ClearGetters(PriorityDefault)
assert.Equal(t, []getprio{}, m.getters)
m.ClearGetters(PriorityDefault)
assert.Equal(t, []getprio{}, m.getters)
}
func TestConfigMapClearSetters(t *testing.T) {
m := New()
m1 := Simple{}
m2 := Simple{}
m3 := Simple{}
m.AddSetter(m1)
m.AddSetter(m2)
m.AddSetter(m3)
assert.Equal(t, []Setter{m1, m2, m3}, m.setters)
m.ClearSetters()
assert.Equal(t, []Setter(nil), m.setters)
} }
func TestSimpleString(t *testing.T) { func TestSimpleString(t *testing.T) {
@@ -163,3 +269,91 @@ func TestSimpleString(t *testing.T) {
"apple": "", "apple": "",
}.String()) }.String())
} }
func TestSimpleEncode(t *testing.T) {
for _, test := range []struct {
in Simple
want string
}{
{
in: Simple{},
want: "",
},
{
in: Simple{
"one": "potato",
},
want: "eyJvbmUiOiJwb3RhdG8ifQ",
},
{
in: Simple{
"one": "potato",
"two": "",
},
want: "eyJvbmUiOiJwb3RhdG8iLCJ0d28iOiIifQ",
},
} {
got, err := test.in.Encode()
require.NoError(t, err)
assert.Equal(t, test.want, got)
gotM := Simple{}
err = gotM.Decode(got)
require.NoError(t, err)
assert.Equal(t, test.in, gotM)
}
}
func TestSimpleDecode(t *testing.T) {
for _, test := range []struct {
in string
want Simple
wantErr string
}{
{
in: "",
want: Simple{},
},
{
in: "eyJvbmUiOiJwb3RhdG8ifQ",
want: Simple{
"one": "potato",
},
},
{
in: " e yJvbm UiOiJwb\r\n 3Rhd\tG8ifQ\n\n ",
want: Simple{
"one": "potato",
},
},
{
in: "eyJvbmUiOiJwb3RhdG8iLCJ0d28iOiIifQ",
want: Simple{
"one": "potato",
"two": "",
},
},
{
in: "!!!!!",
want: Simple{},
wantErr: "decode simple map",
},
{
in: base64.RawStdEncoding.EncodeToString([]byte(`null`)),
want: Simple{},
},
{
in: base64.RawStdEncoding.EncodeToString([]byte(`rubbish`)),
want: Simple{},
wantErr: "parse simple map",
},
} {
got := Simple{}
err := got.Decode(test.in)
assert.Equal(t, test.want, got, test.in)
if test.wantErr == "" {
require.NoError(t, err, test.in)
} else {
assert.Contains(t, err.Error(), test.wantErr, test.in)
}
}
}

View File

@@ -125,6 +125,38 @@ func (os Options) Get(name string) *Option {
return nil return nil
} }
// Overridden discovers which config items have been overridden in the
// configmap passed in, either by the config string, command line
// flags or environment variables
func (os Options) Overridden(m *configmap.Map) configmap.Simple {
var overridden = configmap.Simple{}
for i := range os {
opt := &os[i]
value, isSet := m.GetPriority(opt.Name, configmap.PriorityNormal)
if isSet {
overridden.Set(opt.Name, value)
}
}
return overridden
}
// NonDefault discovers which config values aren't at their default
func (os Options) NonDefault(m configmap.Getter) configmap.Simple {
var nonDefault = configmap.Simple{}
for i := range os {
opt := &os[i]
value, isSet := m.Get(opt.Name)
if !isSet {
continue
}
defaultValue := fmt.Sprint(opt.Default)
if value != defaultValue {
nonDefault.Set(opt.Name, value)
}
}
return nonDefault
}
// OptionVisibility controls whether the options are visible in the // OptionVisibility controls whether the options are visible in the
// configurator or the command line. // configurator or the command line.
type OptionVisibility byte type OptionVisibility byte
@@ -1321,28 +1353,28 @@ func ConfigMap(fsInfo *RegInfo, configName string, connectionStringConfig config
// Config from connection string // Config from connection string
if len(connectionStringConfig) > 0 { if len(connectionStringConfig) > 0 {
config.AddOverrideGetter(connectionStringConfig) config.AddGetter(connectionStringConfig, configmap.PriorityNormal)
} }
// flag values // flag values
if fsInfo != nil { if fsInfo != nil {
config.AddOverrideGetter(&regInfoValues{fsInfo, false}) config.AddGetter(&regInfoValues{fsInfo, false}, configmap.PriorityNormal)
} }
// remote specific environment vars // remote specific environment vars
config.AddOverrideGetter(configEnvVars(configName)) config.AddGetter(configEnvVars(configName), configmap.PriorityNormal)
// backend specific environment vars // backend specific environment vars
if fsInfo != nil { if fsInfo != nil {
config.AddOverrideGetter(optionEnvVars{fsInfo: fsInfo}) config.AddGetter(optionEnvVars{fsInfo: fsInfo}, configmap.PriorityNormal)
} }
// config file // config file
config.AddGetter(getConfigFile(configName)) config.AddGetter(getConfigFile(configName), configmap.PriorityConfig)
// default values // default values
if fsInfo != nil { if fsInfo != nil {
config.AddGetter(&regInfoValues{fsInfo, true}) config.AddGetter(&regInfoValues{fsInfo, true}, configmap.PriorityDefault)
} }
// Set Config // Set Config
@@ -1381,17 +1413,7 @@ func NewFs(ctx context.Context, path string) (Fs, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Now discover which config items have been overridden, overridden := fsInfo.Options.Overridden(config)
// either by the config string, command line flags or
// environment variables
var overridden = configmap.Simple{}
for i := range fsInfo.Options {
opt := &fsInfo.Options[i]
value, isSet := config.GetOverride(opt.Name)
if isSet {
overridden.Set(opt.Name, value)
}
}
if len(overridden) > 0 { if len(overridden) > 0 {
extraConfig := overridden.String() extraConfig := overridden.String()
//Debugf(nil, "detected overriden config %q", extraConfig) //Debugf(nil, "detected overriden config %q", extraConfig)
@@ -1409,6 +1431,11 @@ func NewFs(ctx context.Context, path string) (Fs, error) {
// These need to work as filesystem names as the VFS cache will use them // These need to work as filesystem names as the VFS cache will use them
configName += suffix configName += suffix
} }
Debugf(nil, "Config dump:")
nonDefaultConfig := fsInfo.Options.NonDefault(config)
for k, v := range nonDefaultConfig {
Debugf(nil, " %s = %q", k, v)
}
return fsInfo.NewFs(ctx, configName, fsPath, config) return fsInfo.NewFs(ctx, configName, fsPath, config)
} }

View File

@@ -190,6 +190,43 @@ func TestOptionsGet(t *testing.T) {
assert.Nil(t, opt) assert.Nil(t, opt)
} }
func TestOptionsOveridden(t *testing.T) {
m := configmap.New()
m1 := configmap.Simple{
"nounc": "m1",
"copy_links": "m1",
}
m.AddGetter(m1, configmap.PriorityNormal)
m2 := configmap.Simple{
"nounc": "m2",
"case_insensitive": "m2",
}
m.AddGetter(m2, configmap.PriorityConfig)
m3 := configmap.Simple{
"nounc": "m3",
}
m.AddGetter(m3, configmap.PriorityDefault)
got := testOptions.Overridden(m)
assert.Equal(t, configmap.Simple{
"copy_links": "m1",
"nounc": "m1",
}, got)
}
func TestOptionsNonDefault(t *testing.T) {
m := configmap.Simple{}
got := testOptions.NonDefault(m)
assert.Equal(t, configmap.Simple{}, got)
m["case_insensitive"] = "false"
got = testOptions.NonDefault(m)
assert.Equal(t, configmap.Simple{}, got)
m["case_insensitive"] = "true"
got = testOptions.NonDefault(m)
assert.Equal(t, configmap.Simple{"case_insensitive": "true"}, got)
}
func TestOptionMarshalJSON(t *testing.T) { func TestOptionMarshalJSON(t *testing.T) {
out, err := json.MarshalIndent(&caseInsensitiveOption, "", "") out, err := json.MarshalIndent(&caseInsensitiveOption, "", "")
assert.NoError(t, err) assert.NoError(t, err)

View File

@@ -155,7 +155,9 @@ func newSyncCopyMove(ctx context.Context, fdst, fsrc fs.Fs, deleteMode fs.Delete
// Input context - cancel this for graceful stop // Input context - cancel this for graceful stop
s.inCtx, s.inCancel = context.WithCancel(s.ctx) s.inCtx, s.inCancel = context.WithCancel(s.ctx)
if s.noTraverse && s.deleteMode != fs.DeleteModeOff { if s.noTraverse && s.deleteMode != fs.DeleteModeOff {
if !fi.HaveFilesFrom() {
fs.Errorf(nil, "Ignoring --no-traverse with sync") fs.Errorf(nil, "Ignoring --no-traverse with sync")
}
s.noTraverse = false s.noTraverse = false
} }
s.trackRenamesStrategy, err = parseTrackRenamesStrategy(ci.TrackRenamesStrategy) s.trackRenamesStrategy, err = parseTrackRenamesStrategy(ci.TrackRenamesStrategy)

View File

@@ -1,4 +1,4 @@
package fs package fs
// Version of rclone // Version of rclone
var Version = "v1.55.1-DEV" var Version = "v1.56.0-DEV"

1
go.mod
View File

@@ -53,6 +53,7 @@ require (
github.com/rivo/uniseg v0.2.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sevlyar/go-daemon v0.1.5 github.com/sevlyar/go-daemon v0.1.5
github.com/shirou/gopsutil/v3 v3.21.3
github.com/sirupsen/logrus v1.7.0 github.com/sirupsen/logrus v1.7.0
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
github.com/spf13/cobra v1.1.1 github.com/spf13/cobra v1.1.1

13
go.sum
View File

@@ -67,6 +67,8 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE
github.com/RoaringBitmap/roaring v0.4.7/go.mod h1:8khRDP4HmeXns4xIj9oGrKSz7XTQiJx2zgh7AcNke4w= github.com/RoaringBitmap/roaring v0.4.7/go.mod h1:8khRDP4HmeXns4xIj9oGrKSz7XTQiJx2zgh7AcNke4w=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/Unknwon/goconfig v0.0.0-20200908083735-df7de6a44db8 h1:1TrMV1HmBApBbM+Hy7RCKZD6UlYWYIPPfoeXomG7+zE= github.com/Unknwon/goconfig v0.0.0-20200908083735-df7de6a44db8 h1:1TrMV1HmBApBbM+Hy7RCKZD6UlYWYIPPfoeXomG7+zE=
github.com/Unknwon/goconfig v0.0.0-20200908083735-df7de6a44db8/go.mod h1:wngxua9XCNjvHjDiTiV26DaKDT+0c63QR6H5hjVUUxw= github.com/Unknwon/goconfig v0.0.0-20200908083735-df7de6a44db8/go.mod h1:wngxua9XCNjvHjDiTiV26DaKDT+0c63QR6H5hjVUUxw=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
@@ -209,6 +211,8 @@ github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgO
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
@@ -502,6 +506,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pkg/sftp v1.12.0 h1:/f3b24xrDhkhddlaobPe2JgBqfdt+gC/NYl0QY9IOuI= github.com/pkg/sftp v1.12.0 h1:/f3b24xrDhkhddlaobPe2JgBqfdt+gC/NYl0QY9IOuI=
github.com/pkg/sftp v1.12.0/go.mod h1:fUqqXB5vEgVCZ131L+9say31RAri6aF6KDViawhxKK8= github.com/pkg/sftp v1.12.0/go.mod h1:fUqqXB5vEgVCZ131L+9say31RAri6aF6KDViawhxKK8=
github.com/pkg/sftp v1.13.0 h1:Riw6pgOKK41foc1I1Uu03CjvbLZDXeGpInycM4shXoI=
github.com/pkg/sftp v1.13.0/go.mod h1:41g+FIPlQUTDCveupEmEA65IoiQFrtgCeDopC4ajGIM=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
@@ -558,6 +564,8 @@ github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sevlyar/go-daemon v0.1.5 h1:Zy/6jLbM8CfqJ4x4RPr7MJlSKt90f00kNM1D401C+Qk= github.com/sevlyar/go-daemon v0.1.5 h1:Zy/6jLbM8CfqJ4x4RPr7MJlSKt90f00kNM1D401C+Qk=
github.com/sevlyar/go-daemon v0.1.5/go.mod h1:6dJpPatBT9eUwM5VCw9Bt6CdX9Tk6UWvhW3MebLDRKE= github.com/sevlyar/go-daemon v0.1.5/go.mod h1:6dJpPatBT9eUwM5VCw9Bt6CdX9Tk6UWvhW3MebLDRKE=
github.com/shirou/gopsutil/v3 v3.21.3 h1:wgcdAHZS2H6qy4JFewVTtqfiYxFzCeEJod/mLztdPG8=
github.com/shirou/gopsutil/v3 v3.21.3/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
@@ -610,6 +618,10 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69
github.com/t3rm1n4l/go-mega v0.0.0-20200416171014-ffad7fcb44b8 h1:IGJQmLBLYBdAknj21W3JsVof0yjEXfy1Q0K3YZebDOg= github.com/t3rm1n4l/go-mega v0.0.0-20200416171014-ffad7fcb44b8 h1:IGJQmLBLYBdAknj21W3JsVof0yjEXfy1Q0K3YZebDOg=
github.com/t3rm1n4l/go-mega v0.0.0-20200416171014-ffad7fcb44b8/go.mod h1:XWL4vDyd3JKmJx+hZWUVgCNmmhZ2dTBcaNDcxH465s0= github.com/t3rm1n4l/go-mega v0.0.0-20200416171014-ffad7fcb44b8/go.mod h1:XWL4vDyd3JKmJx+hZWUVgCNmmhZ2dTBcaNDcxH465s0=
github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
github.com/tklauser/go-sysconf v0.3.4 h1:HT8SVixZd3IzLdfs/xlpq0jeSfTX57g1v6wB1EuzV7M=
github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek=
github.com/tklauser/numcpus v0.2.1 h1:ct88eFm+Q7m2ZfXJdan1xYoXKlmwsfP+k88q05KvlZc=
github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ=
@@ -849,6 +861,7 @@ golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210112091331-59c308dcf3cc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112091331-59c308dcf3cc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210313110737-8e9fff1a3a18 h1:jxr7/dEo+rR29uEBoLSWJ1tRHCFAMwFbGUU9nRqzpds= golang.org/x/sys v0.0.0-20210313110737-8e9fff1a3a18 h1:jxr7/dEo+rR29uEBoLSWJ1tRHCFAMwFbGUU9nRqzpds=
golang.org/x/sys v0.0.0-20210313110737-8e9fff1a3a18/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210313110737-8e9fff1a3a18/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=

View File

@@ -0,0 +1,34 @@
// +build !openbsd,!windows
package buildinfo
import (
"strings"
"github.com/shirou/gopsutil/v3/host"
)
// GetOSVersion returns OS version, kernel and bitness
func GetOSVersion() (osVersion, osKernel string) {
if platform, _, version, err := host.PlatformInformation(); err == nil && platform != "" {
osVersion = platform
if version != "" {
osVersion += " " + version
}
}
if version, err := host.KernelVersion(); err == nil && version != "" {
osKernel = version
}
if arch, err := host.KernelArch(); err == nil && arch != "" {
if strings.HasSuffix(arch, "64") && osVersion != "" {
osVersion += " (64 bit)"
}
if osKernel != "" {
osKernel += " (" + arch + ")"
}
}
return
}

View File

@@ -0,0 +1,13 @@
// +build openbsd
package buildinfo
// gopsutil v3.21.3 fails to build on openbsd:
// Error: .../go/pkg/mod/github.com/tklauser/go-sysconf@v0.3.4/sysconf_openbsd.go:22:28: undefined: unix.RLIMIT_NPROC
// Error: .../go/pkg/mod/github.com/shirou/gopsutil/v3@v3.21.3/process/process.go:163:15: undefined: pidsWithContext
// and so on...
// GetOSVersion returns OS version, kernel and bitness
func GetOSVersion() (osVersion, osKernel string) {
return "OpenBSD", ""
}

View File

@@ -0,0 +1,131 @@
// +build !openbsd !windows
package buildinfo
import (
"fmt"
"regexp"
"strings"
"unsafe"
"github.com/shirou/gopsutil/v3/host"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
)
// GetOSVersion returns OS version, kernel and bitness
// On Windows it performs additional output enhancements.
func GetOSVersion() (osVersion, osKernel string) {
if platform, _, version, err := host.PlatformInformation(); err == nil && platform != "" {
osVersion = platform
if version != "" {
osVersion += " " + version
}
}
if version, err := host.KernelVersion(); err == nil && version != "" {
osKernel = version
// Prevent duplication of output on Windows
if strings.Contains(osVersion, osKernel) {
deduped := strings.TrimSpace(strings.Replace(osVersion, osKernel, "", 1))
if deduped != "" {
osVersion = deduped
}
}
// Simplify kernel output: `RELEASE.BUILD Build BUILD` -> `RELEASE.BUILD`
match := regexp.MustCompile(`^([\d\.]+?\.)(\d+) Build (\d+)$`).FindStringSubmatch(osKernel)
if len(match) == 4 && match[2] == match[3] {
osKernel = match[1] + match[2]
}
}
friendlyName := getRegistryVersionString("ReleaseId")
if osVersion != "" && friendlyName != "" {
osVersion += " " + friendlyName
}
updateRevision := getRegistryVersionInt("UBR")
if osKernel != "" && updateRevision != 0 {
osKernel += fmt.Sprintf(".%d", updateRevision)
}
if arch, err := host.KernelArch(); err == nil && arch != "" {
if strings.HasSuffix(arch, "64") && osVersion != "" {
osVersion += " (64 bit)"
}
if osKernel != "" {
osKernel += " (" + arch + ")"
}
}
return
}
var regVersionKeyUTF16 = windows.StringToUTF16Ptr(`SOFTWARE\Microsoft\Windows NT\CurrentVersion`)
func getRegistryVersionString(name string) string {
var (
err error
handle windows.Handle
bufLen uint32
valType uint32
)
err = windows.RegOpenKeyEx(windows.HKEY_LOCAL_MACHINE, regVersionKeyUTF16, 0, windows.KEY_READ|windows.KEY_WOW64_64KEY, &handle)
if err != nil {
return ""
}
defer func() {
_ = windows.RegCloseKey(handle)
}()
nameUTF16 := windows.StringToUTF16Ptr(name)
err = windows.RegQueryValueEx(handle, nameUTF16, nil, &valType, nil, &bufLen)
if err != nil {
return ""
}
regBuf := make([]uint16, bufLen/2+1)
err = windows.RegQueryValueEx(handle, nameUTF16, nil, &valType, (*byte)(unsafe.Pointer(&regBuf[0])), &bufLen)
if err != nil {
return ""
}
return windows.UTF16ToString(regBuf[:])
}
func getRegistryVersionInt(name string) int {
var (
err error
handle windows.Handle
bufLen uint32
valType uint32
)
err = windows.RegOpenKeyEx(windows.HKEY_LOCAL_MACHINE, regVersionKeyUTF16, 0, windows.KEY_READ|windows.KEY_WOW64_64KEY, &handle)
if err != nil {
return 0
}
defer func() {
_ = windows.RegCloseKey(handle)
}()
nameUTF16 := windows.StringToUTF16Ptr(name)
err = windows.RegQueryValueEx(handle, nameUTF16, nil, &valType, nil, &bufLen)
if err != nil {
return 0
}
if valType != registry.DWORD || bufLen != 4 {
return 0
}
var val32 uint32
err = windows.RegQueryValueEx(handle, nameUTF16, nil, &valType, (*byte)(unsafe.Pointer(&val32)), &bufLen)
if err != nil {
return 0
}
return int(val32)
}

View File

@@ -447,19 +447,46 @@ Execute the following on the machine with the web browser (same rclone
version recommended): version recommended):
`) `)
if changed { // Find the configuration
fmt.Printf("\trclone authorize %q -- %q %q\n", id, oauthConfig.ClientID, oauthConfig.ClientSecret) ri, err := fs.Find(id)
if err != nil {
return errors.Wrap(err, "oauthutil authorize")
}
// Find the overridden options
inM := ri.Options.NonDefault(m)
delete(inM, config.ConfigToken) // delete token as we are refreshing it
for k, v := range inM {
fs.Debugf(nil, "sending %s = %q", k, v)
}
// Encode them into a string
mCopyString, err := inM.Encode()
if err != nil {
return errors.Wrap(err, "oauthutil authorize encode")
}
// Write what the user has to do
if len(mCopyString) > 0 {
fmt.Printf("\trclone authorize %q %q\n", id, mCopyString)
} else { } else {
fmt.Printf("\trclone authorize %q\n", id) fmt.Printf("\trclone authorize %q\n", id)
} }
fmt.Println("\nThen paste the result below:") fmt.Println("\nThen paste the result below:")
// Read the updates to the config
var outM configmap.Simple
for {
outM = configmap.Simple{}
code := config.ReadNonEmptyLine("result> ") code := config.ReadNonEmptyLine("result> ")
token := &oauth2.Token{} err = outM.Decode(code)
err := json.Unmarshal([]byte(code), token) if err == nil {
if err != nil { break
return err
} }
return PutToken(name, m, token, true) fmt.Printf("Couldn't decode response - try again (make sure you are using a matching version of rclone on both sides: %v\n", err)
}
// Save the config updates
for k, v := range outM {
m.Set(k, v)
fs.Debugf(nil, "received %s = %q", k, v)
}
return nil
} }
} }
@@ -526,14 +553,6 @@ version recommended):
return errors.Wrap(err, "failed to get token") return errors.Wrap(err, "failed to get token")
} }
// Print code if we are doing a manual auth
if authorizeOnly {
result, err := json.Marshal(token)
if err != nil {
return errors.Wrap(err, "failed to marshal token")
}
fmt.Printf("Paste the following into your remote machine --->\n%s\n<---End paste\n", result)
}
return PutToken(name, m, token, true) return PutToken(name, m, token, true)
} }

109
rclone.1 generated
View File

@@ -1,7 +1,7 @@
.\"t .\"t
.\" Automatically generated by Pandoc 2.5 .\" Automatically generated by Pandoc 2.5
.\" .\"
.TH "rclone" "1" "Apr 26, 2021" "User Manual" "" .TH "rclone" "1" "Mar 31, 2021" "User Manual" ""
.hy .hy
.SH Rclone syncs your files to cloud storage .SH Rclone syncs your files to cloud storage
.PP .PP
@@ -3677,7 +3677,7 @@ this as the file being accessible by everyone.
For example an SSH client may warn about \[dq]unprotected private key For example an SSH client may warn about \[dq]unprotected private key
file\[dq]. file\[dq].
.PP .PP
WinFsp 2021 (version 1.9) introduces a new FUSE option WinFsp 2021 (version 1.9, still in beta) introduces a new FUSE option
\[dq]FileSecurity\[dq], that allows the complete specification of file \[dq]FileSecurity\[dq], that allows the complete specification of file
security descriptors using security descriptors using
SDDL (https://docs.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-string-format). SDDL (https://docs.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-string-format).
@@ -4632,7 +4632,7 @@ Beta releases have an additional information similar to
\f[C]v1.54.0\-beta.5111.06f1c0c61\f[R]. \f[C]v1.54.0\-beta.5111.06f1c0c61\f[R].
(if you are a developer and use a locally built rclone, the version (if you are a developer and use a locally built rclone, the version
number will end with \f[C]\-DEV\f[R], you will have to rebuild it as it number will end with \f[C]\-DEV\f[R], you will have to rebuild it as it
obviously can\[aq]t be distributed). obvisously can\[aq]t be distributed).
.PP .PP
If you previously installed rclone via a package manager, the package If you previously installed rclone via a package manager, the package
may include local documentation or configure services. may include local documentation or configure services.
@@ -8720,7 +8720,7 @@ If you run \f[C]rclone config file\f[R] you will see where the default
location is for you. location is for you.
.PP .PP
Use this flag to override the config location, e.g. Use this flag to override the config location, e.g.
\f[C]rclone \-\-config=\[dq].myconfig\[dq] config\f[R]. \f[C]rclone \-\-config=\[dq].myconfig\[dq] .config\f[R].
.PP .PP
If the location is set to empty string \f[C]\[dq]\[dq]\f[R] or the If the location is set to empty string \f[C]\[dq]\[dq]\f[R] or the
special value \f[C]/notfound\f[R], or the os null device represented by special value \f[C]/notfound\f[R], or the os null device represented by
@@ -15925,7 +15925,7 @@ These flags are available for every command.
\-\-use\-json\-log Use json log format. \-\-use\-json\-log Use json log format.
\-\-use\-mmap Use mmap allocator (see docs). \-\-use\-mmap Use mmap allocator (see docs).
\-\-use\-server\-modtime Use server modified time instead of object metadata \-\-use\-server\-modtime Use server modified time instead of object metadata
\-\-user\-agent string Set the user\-agent to a specified string. The default is rclone/ version (default \[dq]rclone/v1.55.1\[dq]) \-\-user\-agent string Set the user\-agent to a specified string. The default is rclone/ version (default \[dq]rclone/v1.55.0\[dq])
\-v, \-\-verbose count Print lots more stuff (repeat for more) \-v, \-\-verbose count Print lots more stuff (repeat for more)
\f[R] \f[R]
.fi .fi
@@ -39340,105 +39340,6 @@ Options:
.IP \[bu] 2 .IP \[bu] 2
\[dq]error\[dq]: return an error based on option value \[dq]error\[dq]: return an error based on option value
.SH Changelog .SH Changelog
.SS v1.55.1 \- 2021\-04\-26
.PP
See commits (https://github.com/rclone/rclone/compare/v1.55.0...v1.55.1)
.IP \[bu] 2
Bug Fixes
.RS 2
.IP \[bu] 2
selfupdate
.RS 2
.IP \[bu] 2
Dont detect FUSE if build is static (Ivan Andreev)
.IP \[bu] 2
Add build tag noselfupdate (Ivan Andreev)
.RE
.IP \[bu] 2
sync: Fix incorrect error reported by graceful cutoff (Nick Craig\-Wood)
.IP \[bu] 2
install.sh: fix macOS arm64 download (Nick Craig\-Wood)
.IP \[bu] 2
build: Fix version numbers in android branch builds (Nick Craig\-Wood)
.IP \[bu] 2
docs
.RS 2
.IP \[bu] 2
Contributing.md: update setup instructions for go1.16 (Nick Gaya)
.IP \[bu] 2
WinFsp 2021 is out of beta (albertony)
.IP \[bu] 2
Minor cleanup of space around code section (albertony)
.IP \[bu] 2
Fixed some typos (albertony)
.RE
.RE
.IP \[bu] 2
VFS
.RS 2
.IP \[bu] 2
Fix a code path which allows dirty data to be removed causing data loss
(Nick Craig\-Wood)
.RE
.IP \[bu] 2
Compress
.RS 2
.IP \[bu] 2
Fix compressed name regexp (buengese)
.RE
.IP \[bu] 2
Drive
.RS 2
.IP \[bu] 2
Fix backend copyid of google doc to directory (Nick Craig\-Wood)
.IP \[bu] 2
Don\[aq]t open browser when service account...
(Ansh Mittal)
.RE
.IP \[bu] 2
Dropbox
.RS 2
.IP \[bu] 2
Add missing team_data.member scope for use with \-\-impersonate (Nick
Craig\-Wood)
.IP \[bu] 2
Fix About after scopes changes \- rclone config reconnect needed (Nick
Craig\-Wood)
.IP \[bu] 2
Fix Unable to decrypt returned paths from changeNotify (Nick
Craig\-Wood)
.RE
.IP \[bu] 2
FTP
.RS 2
.IP \[bu] 2
Fix implicit TLS (Ivan Andreev)
.RE
.IP \[bu] 2
Onedrive
.RS 2
.IP \[bu] 2
Work around for random \[dq]Unable to initialize RPS\[dq] errors
(OleFrost)
.RE
.IP \[bu] 2
SFTP
.RS 2
.IP \[bu] 2
Revert sftp library to v1.12.0 from v1.13.0 to fix performance
regression (Nick Craig\-Wood)
.IP \[bu] 2
Fix Update ReadFrom failed: failed to send packet: EOF errors (Nick
Craig\-Wood)
.RE
.IP \[bu] 2
Zoho
.RS 2
.IP \[bu] 2
Fix error when region isn\[aq]t set (buengese)
.IP \[bu] 2
Do not ask for mountpoint twice when using headless setup (buengese)
.RE
.SS v1.55.0 \- 2021\-03\-31 .SS v1.55.0 \- 2021\-03\-31
.PP .PP
See commits (https://github.com/rclone/rclone/compare/v1.54.0...v1.55.0) See commits (https://github.com/rclone/rclone/compare/v1.54.0...v1.55.0)

View File

@@ -774,9 +774,6 @@ func (item *Item) reload(ctx context.Context) error {
// check the fingerprint of an object and update the item or delete // check the fingerprint of an object and update the item or delete
// the cached file accordingly // the cached file accordingly
// //
// If we have local modifications then they take precedence
// over a change in the remote
//
// It ensures the file is the correct size for the object // It ensures the file is the correct size for the object
// //
// call with lock held // call with lock held
@@ -784,12 +781,8 @@ func (item *Item) _checkObject(o fs.Object) error {
if o == nil { if o == nil {
if item.info.Fingerprint != "" { if item.info.Fingerprint != "" {
// no remote object && local object // no remote object && local object
// remove local object unless dirty // remove local object
if !item.info.Dirty {
item._remove("stale (remote deleted)") item._remove("stale (remote deleted)")
} else {
fs.Debugf(item.name, "vfs cache: remote object has gone but local object modified - keeping it")
}
} else { } else {
// no remote object && no local object // no remote object && no local object
// OK // OK
@@ -800,12 +793,8 @@ func (item *Item) _checkObject(o fs.Object) error {
if item.info.Fingerprint != "" { if item.info.Fingerprint != "" {
// remote object && local object // remote object && local object
if remoteFingerprint != item.info.Fingerprint { if remoteFingerprint != item.info.Fingerprint {
if !item.info.Dirty {
fs.Debugf(item.name, "vfs cache: removing cached entry as stale (remote fingerprint %q != cached fingerprint %q)", remoteFingerprint, item.info.Fingerprint) fs.Debugf(item.name, "vfs cache: removing cached entry as stale (remote fingerprint %q != cached fingerprint %q)", remoteFingerprint, item.info.Fingerprint)
item._remove("stale (remote is different)") item._remove("stale (remote is different)")
} else {
fs.Debugf(item.name, "vfs cache: remote object has changed but local object modified - keeping it (remote fingerprint %q != cached fingerprint %q)", remoteFingerprint, item.info.Fingerprint)
}
} }
} else { } else {
// remote object && no local object // remote object && no local object