Compare commits

...

83 commits

Author SHA1 Message Date
Tim Visée
b6d7c6983a
Merge pull request #183 from defiling9046/patch-1
Update README.md
2025-09-18 09:45:10 +02:00
defiling9046
88bffdb79e
Update README.md
I thought it meant Arch Linux until i clicked on it so I changed the wording (arch to architecture). Sorry if I'm nitpicking.
2025-09-12 20:33:06 +01:00
timvisee
f5b606fca0
Remove and invalidate snapcraft credentials 2025-02-04 22:28:19 +01:00
timvisee
60b3df030e
Use new SNAPCRAFT_STORE_CREDENTIALS variable 2025-02-04 21:36:09 +01:00
timvisee
0b32f4f71b
Bump version to 0.2.76 2025-02-04 21:00:28 +01:00
Tim Visée
754735d2db
Merge pull request #151 from lnee94/patch-1
Update README.md
2025-02-04 20:56:44 +01:00
Tim Visée
92ed3eca9d
Update snap connect command 2025-02-04 20:56:21 +01:00
Tim Visée
a7143bb1ee Merge branch 'linux-libssl3' into 'master'
Upgrade to OpenSSL 3.x

See merge request timvisee/ffsend!43
2025-02-04 19:51:26 +00:00
Christian Sarre
0e7884d13a Update OpenSSL to version 3.0.15. 2025-02-01 22:24:08 +02:00
Christian Sarre
c87845770d Update OpenSSL to 3.0.14. 2025-02-01 22:24:08 +02:00
Christian Sarre
2c9d60d5c1 Change image to "rust:slim-bookworm" - continuation for previous commit. 2025-02-01 22:24:08 +02:00
Christian Sarre
27439fb72f Possible fix for "missing" OpenSSL libraries. 2025-02-01 22:24:08 +02:00
Tim Visée
07f3ff8777
Merge pull request #176 from Kramtoske/master
fix segmentation fault
2025-01-28 23:09:11 +01:00
Eitautas
1da996783f
fix segmentation fault 2025-01-28 10:54:20 +02:00
timvisee
238f1f54d7
Bump MSRV to 1.63.0 2023-08-20 17:48:39 +02:00
timvisee
5df8463b74
Bump dependencies 2023-08-20 17:37:36 +02:00
timvisee
8d8ad7fdb3
Revert "Upgrade to libssl3/openssl3."
This reverts commit 5fd2eac6eb.
2023-05-18 23:12:06 +02:00
timvisee
f06b639542
Merge branch 'sarrchri-linux-libssl3' into master
See https://github.com/timvisee/ffsend/pull/156
2023-05-18 23:00:57 +02:00
Christian Sarre
5fd2eac6eb Upgrade to libssl3/openssl3. 2023-04-12 13:59:56 +03:00
timvisee
e0821c751d
Merge branch 'alichtman-master' into master
See https://github.com/timvisee/ffsend/pull/154
2023-04-07 08:25:20 +02:00
Aaron Lichtman
3c1c2dc28c
Fix segfault
close  #153
2023-04-06 23:14:09 -07:00
lnee94
6fdc6ad85c
Update README.md 2023-02-25 16:18:38 -05:00
timvisee
13f9edd2ea
Bump MSRV to 1.60 2023-02-20 11:16:30 +01:00
timvisee
fd5b38f9ab
Update dependencies 2023-02-14 14:00:41 +01:00
timvisee
6661a58770
Revert "Use shorter passphrase words, make them less than 32-characters long"
This reverts commit fdf8ae9201.

This is reverted because the password length limit is now set much
higher, see: https://github.com/timvisee/send/pull/147
2023-02-14 13:59:44 +01:00
Tim Visée
b2b287e34f Merge branch 'prettytable-rs-features' into 'master'
Disable unused features in prettytable-rs crate

See merge request timvisee/ffsend!41
2022-11-14 17:49:35 +00:00
Jakub Jirutka
9b8dee12ea Disable unused features in prettytable-rs crate
ffsend doesn't use csv.
2022-10-09 21:57:19 +02:00
timvisee
a98c9d1ce4
Merge branch 'kianmeng-fix-typos' into master
See https://github.com/timvisee/ffsend/pull/144
2022-10-05 16:07:03 +02:00
Kian-Meng Ang
f77f9f116a Fix typos
Found via `codespell -S *.svg -L crate,ser`
2022-10-05 21:52:50 +08:00
timvisee
afb004680b
Update dependencies 2022-08-18 16:51:01 +02:00
timvisee
6edc0b1eac
Merge branch 'master' of gitlab.com:timvisee/ffsend 2022-07-04 18:38:44 +02:00
timvisee
7c94f265e2
Update Send link in README, point to repository instead 2022-07-04 18:38:35 +02:00
Tim Visée
d33c03cd2c Merge branch 'nautilus-script' into 'master'
Add script for Nautilus

See merge request timvisee/ffsend!39
2022-06-27 13:22:36 +00:00
getzze
ecc6bcf736 add script for Nautilus 2022-06-27 13:46:50 +01:00
timvisee
3e9a4d67f2
Bump version to 0.2.76 2022-06-20 10:09:01 +02:00
timvisee
ea87a778b3
Update dependencies 2022-06-20 10:08:45 +02:00
timvisee
91cf01ec75
Fix Snapcraft CI release, use new authentication method 2022-06-20 10:04:37 +02:00
timvisee
7598063e36
Bump version to 0.2.75 2022-06-19 02:01:33 +02:00
timvisee
6672891490
Update dependencies 2022-06-19 02:01:12 +02:00
timvisee
8139e3be01
Bump MSRV to 1.56.1 2022-06-19 01:42:32 +02:00
timvisee
ac9f56945b
Update dependencies 2022-06-19 01:41:03 +02:00
timvisee
b42225be76
Update dependencies 2022-06-07 10:29:32 +02:00
dependabot[bot]
1a5ec2de79
Bump regex from 1.5.4 to 1.5.5
Bumps [regex](https://github.com/rust-lang/regex) from 1.5.4 to 1.5.5.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.5.4...1.5.5)

---
updated-dependencies:
- dependency-name: regex
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-06 21:18:06 +00:00
timvisee
216772361a
Remove deprecated badges from Cargo.toml 2021-10-15 12:36:05 +02:00
timvisee
55c243a007
Update dependencies 2021-10-14 22:52:02 +02:00
timvisee
ccd489ce2e
Bump version to 0.2.74 2021-10-07 13:32:06 +02:00
timvisee
8026a79478
Update dependencies 2021-10-07 13:31:30 +02:00
Tim Visée
92ab75f837 Merge branch '113-update-static-openssl' into 'master'
Resolve "Update static OpenSSL"

Closes #113

See merge request timvisee/ffsend!38
2021-10-07 11:29:13 +00:00
timvisee
011d97f843
Compile OpenSSL with no-async 2021-10-07 13:09:39 +02:00
timvisee
3782996376
Update static OpenSSL version to 1.1.1k 2021-10-07 13:09:38 +02:00
timvisee
8f909b805b
Revert "Use latest ca-certificates for ffsend binary test against public instance"
This reverts commit 4c55145a07.
2021-10-07 13:09:24 +02:00
timvisee
178b73f210
Update dependencies 2021-10-06 13:51:38 +02:00
timvisee
4c55145a07
Use latest ca-certificates for ffsend binary test against public instance 2021-10-04 12:45:11 +02:00
timvisee
faa1141a2b
Further improve Arch AUR packages
Based on comments at:
10977f056d

Thanks @alerque
2021-08-31 16:03:38 +02:00
timvisee
10977f056d
Update Arch AUR packages to latest standards
Suggested by https://aur.archlinux.org/packages/ffsend/#comment-824438
2021-08-31 15:32:58 +02:00
timvisee
e2f9b75844
Bump version to 0.2.73 2021-08-30 14:19:44 +02:00
timvisee
e5fd4c237b
Update dependencies 2021-08-30 14:18:58 +02:00
timvisee
4593ece50f
Update dependencies 2021-08-26 20:37:43 +02:00
timvisee
cf8c13afa2
Merge branch 'a1346054-fixes' into master
See https://github.com/timvisee/ffsend/pull/129
2021-08-26 16:33:48 +02:00
a1346054
7e5c750340 Trim excess whitespace 2021-08-26 14:24:23 +00:00
a1346054
e2c20840e4 Fix spelling 2021-08-26 13:41:29 +00:00
a1346054
c7c53d8649 Fix issues in scripts identified using shellcheck 2021-08-25 22:31:38 +00:00
a1346054
1dcecbc281 Invoke bash using /usr/bin/env instead of hardcoded path 2021-08-25 22:30:17 +00:00
a1346054
485e5cd088 Use https links 2021-08-25 22:29:23 +00:00
a1346054
42dffc864d Use correct license file
The current file was missing the "How to Apply These Terms to Your New
Programs" section, which is an integral part of the GPL and is not
supposed to be removed:

https://www.gnu.org/licenses/gpl-faq.html#GPLOmitPreamble

Correct file was downloaded from:
https://www.gnu.org/licenses/gpl-3.0.txt
2021-08-25 22:23:37 +00:00
a1346054
abe52c831d Don't parse output of ls 2021-08-25 21:54:57 +00:00
timvisee
2322096927
Update README, link to issue explaining default host, remove old info 2021-06-24 16:40:35 +02:00
timvisee
22c53316ab
Replace use of deprecated URL to string function
See https://gitlab.com/timvisee/ffsend/-/issues/110
2021-05-09 17:37:20 +02:00
timvisee
e440f4b68a
Bump version to 0.2.72 2021-05-08 00:12:02 +02:00
timvisee
e96d2a7a0b
Update dependencies 2021-05-08 00:11:31 +02:00
timvisee
e03dec6d91
Add FFSEND_DOWNLOAD_LIMIT environment variable 2021-05-08 00:06:59 +02:00
timvisee
4ced2ea4d0
Change Firefox Send branding to Send 2021-05-05 22:33:41 +02:00
timvisee
924cfbeb95
Replace Mozilla's Send links with @timvisee's Send links in README
For more details see: https://gitlab.com/timvisee/ffsend/-/issues/101
2021-05-05 22:28:28 +02:00
timvisee
8266fcb633
Change CI AUR build image from archlinux/base to archlinux 2021-05-02 17:54:08 +02:00
timvisee
796098093b
Update dependencies 2021-04-21 19:13:07 +02:00
timvisee
8bd3efb1c4
Shell completion generation status should print to stderr, not stdout 2021-04-21 19:11:54 +02:00
timvisee
463130cdf8
Merge branch 'herbygillot-patch-1' into 'master' 2021-04-09 18:54:01 +02:00
Herby Gillot
2d7fd864b3
README: add MacPorts install info 2021-04-09 12:41:21 -04:00
timvisee
68a57b5ccc
Bump version to 0.2.71 2021-04-09 16:21:17 +02:00
timvisee
63faf51685
Fix compilation error due to missing imports 2021-04-09 16:20:42 +02:00
timvisee
37cdba8ddd
Add support to upload file from stdin
Fixes https://github.com/timvisee/ffsend/issues/39
2021-04-09 15:53:06 +02:00
timvisee
9908084745
Bump version to 0.2.70 2021-04-09 14:48:51 +02:00
timvisee
1070f1f297
Bump MSRV to 1.46
See https://github.com/rust-lang/rust/issues/49146
2021-04-09 14:48:06 +02:00
33 changed files with 1276 additions and 1077 deletions

1
.gitignore vendored
View file

@ -2,3 +2,4 @@
target/ target/
**/*.rs.bk **/*.rs.bk
.idea/ .idea/
snapcraft.login

View file

@ -5,7 +5,7 @@
# - export a build artifact from the new job # - export a build artifact from the new job
# - manually upload artifact to GitHub in the 'github-release' job # - manually upload artifact to GitHub in the 'github-release' job
image: "rust:slim" image: "rust:slim-bookworm"
stages: stages:
- check - check
@ -64,10 +64,10 @@ check-nightly:
<<: *check-base <<: *check-base
variables: variables:
RUST_VERSION: nightly RUST_VERSION: nightly
check-old: check-msrv:
<<: *check-base <<: *check-base
variables: variables:
RUST_VERSION: "1.43.0" RUST_VERSION: "1.63.0"
# Build using Rust stable # Build using Rust stable
build-x86_64-linux-gnu: build-x86_64-linux-gnu:
@ -95,17 +95,17 @@ build-x86_64-linux-musl:
# Build OpenSSL statically # Build OpenSSL statically
- apt-get install -y build-essential wget musl-tools - apt-get install -y build-essential wget musl-tools
- wget https://www.openssl.org/source/old/1.0.2/openssl-1.0.2o.tar.gz - wget https://github.com/openssl/openssl/releases/download/openssl-3.0.15/openssl-3.0.15.tar.gz
- tar xzvf openssl-1.0.2o.tar.gz - tar xzvf openssl-3.0.15.tar.gz
- cd openssl-1.0.2o - cd openssl-3.0.15
- ./config -fPIC --openssldir=/usr/local/ssl --prefix=/usr/local - ./config no-async -fPIC --openssldir=/usr/local/ssl --prefix=/usr/local
- make - make
- make install - make install
- cd .. - cd ..
# Statically build ffsend # Statically build ffsend
- export OPENSSL_STATIC=1 - export OPENSSL_STATIC=1
- export OPENSSL_LIB_DIR=/usr/local/lib - export OPENSSL_LIB_DIR=/usr/local/lib64
- export OPENSSL_INCLUDE_DIR=/usr/local/include - export OPENSSL_INCLUDE_DIR=/usr/local/include
- cargo build --target=$RUST_TARGET --release --verbose - cargo build --target=$RUST_TARGET --release --verbose
@ -187,8 +187,7 @@ release-snap:
# Publish snap package # Publish snap package
- echo "Publishing snap package..." - echo "Publishing snap package..."
- echo "$SNAPCRAFT_LOGIN" | base64 -d > snapcraft.login - snapcraft whoami
- snapcraft login --with snapcraft.login
- snapcraft push --release=stable ffsend_*_amd64.snap - snapcraft push --release=stable ffsend_*_amd64.snap
artifacts: artifacts:
name: ffsend-snap-x86_64 name: ffsend-snap-x86_64
@ -256,7 +255,7 @@ release-docker:
# AUR packages release # AUR packages release
package-aur: package-aur:
image: archlinux/base image: archlinux
stage: package stage: package
needs: needs:
- release-github - release-github
@ -301,7 +300,7 @@ package-aur:
- sed "s/^pkgver=.*\$/pkgver=$VERSION/" -i ffsend/PKGBUILD - sed "s/^pkgver=.*\$/pkgver=$VERSION/" -i ffsend/PKGBUILD
- sed "s/^pkgver=.*\$/pkgver=$VERSION/" -i ffsend-bin/PKGBUILD - sed "s/^pkgver=.*\$/pkgver=$VERSION/" -i ffsend-bin/PKGBUILD
- sed "s/^pkgver=.*\$/pkgver=$VERSION.$CI_COMMIT_SHORT_SHA/" -i ffsend-git/PKGBUILD - sed "s/^pkgver=.*\$/pkgver=$VERSION.$CI_COMMIT_SHORT_SHA/" -i ffsend-git/PKGBUILD
- sed "s/^source=(\"\(.*\)::.*\").*\$/source=(\"\1::$(echo $URL_SOURCE | sed 's/\//\\\//g')\")/" -i ffsend/PKGBUILD - sed "s/^source=(\".*\").*\$/source=(\"$(echo $URL_SOURCE | sed 's/\//\\\//g')\")/" -i ffsend/PKGBUILD
- sed "s/\(\"ffsend-v\$pkgver::\).*\"/\1$(echo $URL_BIN | sed 's/\//\\\//g')\"/" -i ffsend-bin/PKGBUILD - sed "s/\(\"ffsend-v\$pkgver::\).*\"/\1$(echo $URL_BIN | sed 's/\//\\\//g')\"/" -i ffsend-bin/PKGBUILD
- sed "s/\(\"ffsend-v\$pkgver.bash::\).*\"/\1$(echo $URL_BASH_COMPLETION | sed 's/\//\\\//g')\"/" -i ffsend-bin/PKGBUILD - sed "s/\(\"ffsend-v\$pkgver.bash::\).*\"/\1$(echo $URL_BASH_COMPLETION | sed 's/\//\\\//g')\"/" -i ffsend-bin/PKGBUILD
- sed "s/\(\"ffsend-v\$pkgver.zsh::\).*\"/\1$(echo $URL_ZSH_COMPLETION | sed 's/\//\\\//g')\"/" -i ffsend-bin/PKGBUILD - sed "s/\(\"ffsend-v\$pkgver.zsh::\).*\"/\1$(echo $URL_ZSH_COMPLETION | sed 's/\//\\\//g')\"/" -i ffsend-bin/PKGBUILD

View file

@ -115,7 +115,7 @@ members of the project's leadership.
### Attribution ### Attribution
This Code of Conduct is adapted from the [Contributor Covenant][coc-homepage], version 1.4, This Code of Conduct is adapted from the [Contributor Covenant][coc-homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][coc-version] available at [https://contributor-covenant.org/version/1/4][coc-version]
## License ## License
This project is released under the GNU GPL-3.0 license. This project is released under the GNU GPL-3.0 license.
@ -128,5 +128,5 @@ Check out the [LICENSE](LICENSE) file for more information.
[github]: https://github.com/timvisee/ffsend [github]: https://github.com/timvisee/ffsend
[github-issues]: https://github.com/timvisee/ffsend/issues [github-issues]: https://github.com/timvisee/ffsend/issues
[github-pr]: https://github.com/timvisee/ffsend/pulls [github-pr]: https://github.com/timvisee/ffsend/pulls
[coc-homepage]: http://contributor-covenant.org [coc-homepage]: https://contributor-covenant.org
[coc-version]: http://contributor-covenant.org/version/1/4/ [coc-version]: https://contributor-covenant.org/version/1/4/

1804
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,7 @@
[package] [package]
name = "ffsend" name = "ffsend"
version = "0.2.69" version = "0.2.77"
rust-version = "1.63.0"
authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"]
license = "GPL-3.0" license = "GPL-3.0"
readme = "README.md" readme = "README.md"
@ -8,7 +9,7 @@ homepage = "https://timvisee.com/projects/ffsend"
repository = "https://gitlab.com/timvisee/ffsend" repository = "https://gitlab.com/timvisee/ffsend"
description = """\ description = """\
Easily and securely share files from the command line.\n\ Easily and securely share files from the command line.\n\
A fully featured Firefox Send client.\ A fully featured Send client.\
""" """
keywords = ["send", "firefox", "cli"] keywords = ["send", "firefox", "cli"]
categories = [ categories = [
@ -49,24 +50,12 @@ license-file = ["LICENSE", "3"]
depends = "$auto, libssl1.1, ca-certificates, xclip" depends = "$auto, libssl1.1, ca-certificates, xclip"
maintainer-scripts = "pkg/deb" maintainer-scripts = "pkg/deb"
[badges]
gitlab = { repository = "timvisee/ffsend", branch = "master" }
[[bin]] [[bin]]
name = "ffsend" name = "ffsend"
path = "src/main.rs" path = "src/main.rs"
[features] [features]
default = [ default = ["archive", "clipboard", "crypto-ring", "history", "infer-command", "qrcode", "send3", "urlshorten"]
"archive",
"clipboard",
"crypto-ring",
"history",
"infer-command",
"qrcode",
"send3",
"urlshorten",
]
# Compile with file archiving support # Compile with file archiving support
archive = ["tar"] archive = ["tar"]
@ -77,10 +66,10 @@ clipboard = ["clip", "which"]
# Compile with file history support # Compile with file history support
history = [] history = []
# Support for Firefox Send v2 # Support for Send v2
send2 = ["ffsend-api/send2"] send2 = ["ffsend-api/send2"]
# Support for Firefox Send v3 # Support for Send v3
send3 = ["ffsend-api/send3"] send3 = ["ffsend-api/send3"]
# Use OpenSSL as cryptography backend # Use OpenSSL as cryptography backend
@ -113,19 +102,19 @@ chrono = "0.4"
clap = "2.33" clap = "2.33"
colored = "2.0" colored = "2.0"
derive_builder = "0.10" derive_builder = "0.10"
directories = "3.0" directories = "4.0"
failure = "0.1" failure = "0.1"
ffsend-api = { version = "0.7.2", default-features = false } ffsend-api = { version = "0.7.3", default-features = false }
fs2 = "0.4" fs2 = "0.4"
lazy_static = "1.4" lazy_static = "1.4"
open = "1" open = "2"
openssl-probe = "0.1" openssl-probe = "0.1"
pathdiff = "0.2" pathdiff = "0.2"
pbr = "1" pbr = "1"
prettytable-rs = "0.8" prettytable-rs = { version = "0.10.0", default-features = false }
qr2term = { version = "0.2", optional = true } qr2term = { version = "0.2", optional = true }
rand = "0.8" rand = "0.8"
regex = "1.3" regex = "1.5"
rpassword = "5" rpassword = "5"
serde = "1" serde = "1"
serde_derive = "1" serde_derive = "1"
@ -133,7 +122,7 @@ tar = { version = "0.4", optional = true }
tempfile = "3" tempfile = "3"
toml = "0.5" toml = "0.5"
urlshortener = { version = "3", optional = true } urlshortener = { version = "3", optional = true }
version-compare = "0.0.11" version-compare = "0.1"
[target.'cfg(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd", target_os = "netbsd"))'.dependencies] [target.'cfg(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd", target_os = "netbsd"))'.dependencies]
which = { version = "4.0", optional = true } which = { version = "4.0", optional = true }

55
LICENSE
View file

@ -1,7 +1,7 @@
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007 Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. of this license document, but changing it is not allowed.
@ -619,3 +619,56 @@ Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee. copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.

View file

@ -8,14 +8,14 @@
[gitlab-ci-link]: https://gitlab.com/timvisee/ffsend/pipelines [gitlab-ci-link]: https://gitlab.com/timvisee/ffsend/pipelines
[gitlab-ci-master-badge]: https://gitlab.com/timvisee/ffsend/badges/master/pipeline.svg [gitlab-ci-master-badge]: https://gitlab.com/timvisee/ffsend/badges/master/pipeline.svg
*Notice: the default Send host is provided by [@timvisee][timvisee], *Notice: the default Send host is provided by [@timvisee][timvisee]
[info](https://gitlab.com/timvisee/ffsend/-/issues/101). ([info](https://gitlab.com/timvisee/ffsend/-/issues/111)).
Please consider to [donate] and help keep it running.* Please consider to [donate] and help keep it running.*
# ffsend # ffsend
> Easily and securely share files from the command line. > Easily and securely share files from the command line.
> [Firefox Send][send] client ([annonymous only][issue116] at the moment). > A [Send][send] client.
Easily and securely share files and directories from the command line through a Easily and securely share files and directories from the command line through a
safe, private and encrypted link using a single simple command. safe, private and encrypted link using a single simple command.
@ -36,7 +36,7 @@ Find out more about security [here](#security).
- [Features](#features) - [Features](#features)
- [Usage](#usage) - [Usage](#usage)
- [Requirements](#requirements) - [Requirements](#requirements)
- [Install](#install) ([Linux](#linux-all-distributions), [macOS](#macos), [Windows](#windows), [FreeBSD](#freebsd), [Android](#android), [_Other OS/arch_](#other-os-or-architecture)) - [Install](#install) ([Linux](#linux-all-distributions), [macOS](#macos), [Windows](#windows), [FreeBSD](#freebsd), [Android](#android), [_Other OS/architecture_](#other-os-or-architecture))
- [Build](#build) - [Build](#build)
- [Configuration and environment](#configuration-and-environment) - [Configuration and environment](#configuration-and-environment)
- [Security](#security) - [Security](#security)
@ -45,9 +45,9 @@ Find out more about security [here](#security).
- [License](#license) - [License](#license)
The public [Send][send] service that is used as default host is provided by The public [Send][send] service that is used as default host is provided by
[@timvisee][timvisee]. [@timvisee][timvisee] ([info](https://gitlab.com/timvisee/ffsend/-/issues/111)).
This application is not affiliated with [Firefox][firefox] or This application is not affiliated with [Firefox][firefox] or
[Firefox Send][send] in any way. [Mozilla][mozilla] in any way.
_Note: this tool is currently in beta, as some extra desired features are yet to be implemented_ _Note: this tool is currently in beta, as some extra desired features are yet to be implemented_
@ -57,7 +57,7 @@ _Note: this tool is currently in beta, as some extra desired features are yet to
- Additional password protection, generation and configurable download limits - Additional password protection, generation and configurable download limits
- File and directory archiving and extraction - File and directory archiving and extraction
- Built-in share URL shortener and QR code generator - Built-in share URL shortener and QR code generator
- Supports Firefox Send v3 (current) and v2 - Supports Send v3 (current) and v2
- History tracking your files for easy management - History tracking your files for easy management
- Ability to use your own Send hosts - Ability to use your own Send hosts
- Inspect or delete shared files - Inspect or delete shared files
@ -74,7 +74,7 @@ Easily upload and download:
```bash ```bash
# Simple upload # Simple upload
$ ffsend upload my-file.txt $ ffsend upload my-file.txt
https://send.firefox.com/#sample-share-url https://send.vis.ee/#sample-share-url
# Advanced upload # Advanced upload
# - Specify a download limit of 1 # - Specify a download limit of 1
@ -85,25 +85,25 @@ https://send.firefox.com/#sample-share-url
# - Open the shareable link in your browser # - Open the shareable link in your browser
$ ffsend upload --downloads 1 --expiry-time 5m --password --archive --copy --open my-file.txt $ ffsend upload --downloads 1 --expiry-time 5m --password --archive --copy --open my-file.txt
Password: ****** Password: ******
https://send.firefox.com/#sample-share-url https://send.vis.ee/#sample-share-url
# Upload to your own host # Upload to your own host
$ ffsend u -h https://example.com/ my-file.txt $ ffsend u -h https://example.com/ my-file.txt
https://example.com/#sample-share-url https://example.com/#sample-share-url
# Simple download # Simple download
$ ffsend download https://send.firefox.com/#sample-share-url $ ffsend download https://send.vis.ee/#sample-share-url
``` ```
Inspect remote files: Inspect remote files:
```bash ```bash
# Check if a file exists # Check if a file exists
$ ffsend exists https://send.firefox.com/#sample-share-url $ ffsend exists https://send.vis.ee/#sample-share-url
Exists: yes Exists: yes
# Fetch remote file info # Fetch remote file info
$ ffsend info https://send.firefox.com/#sample-share-url $ ffsend info https://send.vis.ee/#sample-share-url
ID: b087066715 ID: b087066715
Name: my-file.txt Name: my-file.txt
Size: 12 KiB Size: 12 KiB
@ -118,16 +118,16 @@ Other commands include:
# View your file history # View your file history
$ ffsend history $ ffsend history
# LINK EXPIRE # LINK EXPIRE
1 https://send.firefox.com/#sample-share-url 23h57m 1 https://send.vis.ee/#sample-share-url 23h57m
2 https://send.firefox.com/#other-sample-url 17h38m 2 https://send.vis.ee/#other-sample-url 17h38m
3 https://example.com/#sample-share-url 37m30s 3 https://example.com/#sample-share-url 37m30s
# Change the password after uploading # Change the password after uploading
$ ffsend password https://send.firefox.com/#sample-share-url $ ffsend password https://send.vis.ee/#sample-share-url
Password: ****** Password: ******
# Delete a file # Delete a file
$ ffsend delete https://send.firefox.com/#sample-share-url $ ffsend delete https://send.vis.ee/#sample-share-url
``` ```
Use the `--help` flag, `help` subcommand, or see the [help](#help) section for Use the `--help` flag, `help` subcommand, or see the [help](#help) section for
@ -188,6 +188,7 @@ _Note: due to how `snap` is configured by default, you won't be able to use the
package from some contexts such as through SSH without manual modifications. If package from some contexts such as through SSH without manual modifications. If
you're experiencing problems, please refer to a different installation method you're experiencing problems, please refer to a different installation method
such as the [prebuilt binaries](#linux-prebuilt-binaries), or open an issue._ such as the [prebuilt binaries](#linux-prebuilt-binaries), or open an issue._
_Note: if you want to read/write to a flash drive run `snap connect ffsend:removable-media`
`ffsend`][snapcraft-ffsend] `ffsend`][snapcraft-ffsend]
@ -275,7 +276,7 @@ ffsend --help
### macOS ### macOS
Using the [`homebrew` package](#macos-homebrew-package) is recommended. Using the [`homebrew` package](#macos-homebrew-package) is recommended.
Alternatively you may install it manually using the Alternatively you may install it via [MacPorts](#macos-macports), or manually using the
[prebuilt binaries](#macos-prebuilt-binaries). [prebuilt binaries](#macos-prebuilt-binaries).
#### macOS: homebrew package #### macOS: homebrew package
@ -286,6 +287,17 @@ brew install ffsend
ffsend --help ffsend --help
``` ```
#### macOS: MacPorts
_Note: ffsend in MacPorts is currently not automatically updated, and might be
slightly outdated._
Once you have [MacPorts](https://www.macports.org) installed, you can run:
```bash
sudo port selfupdate
sudo port install ffsend
```
#### macOS: Nix package #### macOS: Nix package
_Note: The Nix package is currently not automatically updated, and might be _Note: The Nix package is currently not automatically updated, and might be
slightly outdated._ slightly outdated._
@ -351,7 +363,7 @@ You can use `ffsend` from the command line in the same directory:
.\ffsend.exe --help .\ffsend.exe --help
``` ```
To make it globally invokable as `ffsend`, you must make the binary available in To make it globally invocable as `ffsend`, you must make the binary available in
your systems `PATH`. The easiest solution is to move it into `System32`: your systems `PATH`. The easiest solution is to move it into `System32`:
```cmd ```cmd
move .\ffsend.exe C:\Windows\System32\ffsend.exe move .\ffsend.exe C:\Windows\System32\ffsend.exe
@ -407,7 +419,7 @@ docker run --rm -it -v $(pwd):/data timvisee/ffsend
docker run --rm -it -v $(pwd):/data timvisee/ffsend upload my-file.txt docker run --rm -it -v $(pwd):/data timvisee/ffsend upload my-file.txt
# Download from specified link # Download from specified link
docker run --rm -it -v $(pwd):/data timvisee/ffsend download https://send.firefox.com/#sample-share-url docker run --rm -it -v $(pwd):/data timvisee/ffsend download https://send.vis.ee/#sample-share-url
# Show help # Show help
docker run --rm -it -v $(pwd):/data timvisee/ffsend help docker run --rm -it -v $(pwd):/data timvisee/ffsend help
@ -417,7 +429,7 @@ docker pull timvisee/ffsend
``` ```
On Linux or macOS you might define a alias in your shell configuration, to make On Linux or macOS you might define a alias in your shell configuration, to make
it invokable as `ffsend`: it invocable as `ffsend`:
```bash ```bash
alias ffsend='docker run --rm -it -v "$(pwd):/data" timvisee/ffsend' alias ffsend='docker run --rm -it -v "$(pwd):/data" timvisee/ffsend'
@ -433,7 +445,7 @@ before proceeding:
### Build requirements ### Build requirements
- Runtime [requirements](#requirements) - Runtime [requirements](#requirements)
- [`git`][git] - [`git`][git]
- [`rust`][rust] `v1.40` or higher (install using [`rustup`][rustup]) - [`rust`][rust] `v1.63` (MSRV) or higher (install using [`rustup`][rustup])
- [OpenSSL][openssl] or [LibreSSL][libressl] libraries/headers: - [OpenSSL][openssl] or [LibreSSL][libressl] libraries/headers:
- Linux: - Linux:
- Ubuntu, Debian and derivatives: `apt install build-essential cmake pkg-config libssl-dev` - Ubuntu, Debian and derivatives: `apt install build-essential cmake pkg-config libssl-dev`
@ -501,8 +513,8 @@ The following features are available, some of which are enabled by default:
| Feature | Enabled | Description | | Feature | Enabled | Description |
| :-------------: | :-----: | :--------------------------------------------------------- | | :-------------: | :-----: | :--------------------------------------------------------- |
| `send2` | Default | Support for Firefox Send v2 servers | | `send2` | Default | Support for Send v2 servers |
| `send3` | Default | Support for Firefox Send v3 servers | | `send3` | Default | Support for Send v3 servers |
| `crypto-ring` | Default | Use ring as cryptography backend | | `crypto-ring` | Default | Use ring as cryptography backend |
| `crypto-openssl`| | Use OpenSSL as cryptography backend | | `crypto-openssl`| | Use OpenSSL as cryptography backend |
| `clipboard` | Default | Support for copying links to the clipboard | | `clipboard` | Default | Support for copying links to the clipboard |
@ -546,6 +558,7 @@ to command line arguments:
| `FFSEND_TIMEOUT` | `--timeout <SECONDS>` | Request timeout (0 to disable) | | `FFSEND_TIMEOUT` | `--timeout <SECONDS>` | Request timeout (0 to disable) |
| `FFSEND_TRANSFER_TIMEOUT` | `--transfer-timeout <SECONDS>` | Transfer timeout (0 to disable) | | `FFSEND_TRANSFER_TIMEOUT` | `--transfer-timeout <SECONDS>` | Transfer timeout (0 to disable) |
| `FFSEND_EXPIRY_TIME` | `--expiry-time <SECONDS>` | Default upload expiry time | | `FFSEND_EXPIRY_TIME` | `--expiry-time <SECONDS>` | Default upload expiry time |
| `FFSEND_DOWNLOAD_LIMIT` | `--download-limit <DOWNLOADS>` | Default download limit |
| `FFSEND_API` | `--api <VERSION>` | Server API version, `-` to lookup | | `FFSEND_API` | `--api <VERSION>` | Server API version, `-` to lookup |
| `FFSEND_BASIC_AUTH` | `--basic-auth <USER:PASSWORD>` | Basic HTTP authentication credentials to use. | | `FFSEND_BASIC_AUTH` | `--basic-auth <USER:PASSWORD>` | Basic HTTP authentication credentials to use. |
@ -583,7 +596,7 @@ having `ffput` and `ffget` just for to upload and download using `ffsend`.
This allows simple and direct commands like: This allows simple and direct commands like:
```bash ```bash
ffput my-file.txt ffput my-file.txt
ffget https://send.firefox.com/#sample-share-url ffget https://send.vis.ee/#sample-share-url
``` ```
This works for a predefined list of binary names: This works for a predefined list of binary names:
@ -732,10 +745,10 @@ documentation [here][send-encryption].
``` ```
$ ffsend help $ ffsend help
ffsend 0.2.69 ffsend 0.2.72
Tim Visee <3a4fb3964f@sinenomine.email> Tim Visee <3a4fb3964f@sinenomine.email>
Easily and securely share files from the command line. Easily and securely share files from the command line.
A fully featured Firefox Send client. A fully featured Send client.
The default public Send host is provided by Tim Visee, @timvisee. The default public Send host is provided by Tim Visee, @timvisee.
Please consider to donate and help keep it running: https://vis.ee/donate Please consider to donate and help keep it running: https://vis.ee/donate
@ -774,12 +787,12 @@ SUBCOMMANDS:
password Change the password of a shared file [aliases: pass, p] password Change the password of a shared file [aliases: pass, p]
version Determine the Send server version [aliases: v] version Determine the Send server version [aliases: v]
This application is not affiliated with Firefox or Firefox Send. This application is not affiliated with Firefox or Mozilla.
``` ```
## Special thanks ## Special thanks
- to all `ffsend` source/package contributors - to all `ffsend` source/package contributors
- to [Mozilla][mozilla] for building the amazing [Firefox Send][send] service - to [Mozilla][mozilla] for building the amazing [Firefox Send][mozilla-send] service ([fork][timvisee-send])
- to everyone involved with [asciinema][asciinema] and [svg-term][svg-term] for - to everyone involved with [asciinema][asciinema] and [svg-term][svg-term] for
providing tools to make great visual demos providing tools to make great visual demos
- to everyone involved in all crate dependencies used - to everyone involved in all crate dependencies used
@ -799,8 +812,10 @@ Check out the [LICENSE](LICENSE) file for more information.
[termux]: https://termux.com/ [termux]: https://termux.com/
[rust]: https://rust-lang.org/ [rust]: https://rust-lang.org/
[rustup]: https://rustup.rs/ [rustup]: https://rustup.rs/
[send]: https://send.firefox.com/ [send]: https://github.com/timvisee/send
[send-encryption]: https://github.com/mozilla/send/blob/master/docs/encryption.md [mozilla-send]: https://github.com/mozilla/send
[timvisee-send]: https://github.com/timvisee/send
[send-encryption]: https://github.com/timvisee/send/blob/master/docs/encryption.md
[asciinema]: https://asciinema.org/ [asciinema]: https://asciinema.org/
[svg-term]: https://github.com/marionebl/svg-term-cli [svg-term]: https://github.com/marionebl/svg-term-cli
[github-releases]: https://github.com/timvisee/ffsend/releases [github-releases]: https://github.com/timvisee/ffsend/releases
@ -817,6 +832,5 @@ Check out the [LICENSE](LICENSE) file for more information.
[docker-hub-ffsend]: https://hub.docker.com/r/timvisee/ffsend [docker-hub-ffsend]: https://hub.docker.com/r/timvisee/ffsend
[scoop-install]: https://scoop.sh/#installs-in-seconds [scoop-install]: https://scoop.sh/#installs-in-seconds
[freshports-ffsend]: https://www.freshports.org/www/ffsend [freshports-ffsend]: https://www.freshports.org/www/ffsend
[issue116]: https://github.com/timvisee/ffsend/issues/116
[timvisee]: https://timvisee.com/ [timvisee]: https://timvisee.com/
[donate]: https://timvisee.com/donate [donate]: https://timvisee.com/donate

View file

@ -4,5 +4,5 @@
set -e set -e
echo "Generating all completions using cargo debug binary..." echo "Generating all completions using cargo debug binary..."
cargo run -q -- generate completions all --output $PWD cargo run -q -- generate completions all --output "$PWD"
echo "Done." echo "Done."

View file

@ -0,0 +1,6 @@
`firefox-send` is a script for Nautilus/Nemo/Caja (maybe it needs some adaptation for Caja) to send files directly from the file browser, using the contextual menu.
* Copy the `firefox-send` file to ~/.local/share/nautilus/scripts/firefox-send
* Modify the default options to your use case: host server, download number, retention time.
* Make the file executable (`chmod +x firefox-send`).
* Restart Nautilus/Nemo/Caja.

View file

@ -0,0 +1,46 @@
#!/bin/bash
#CONSTANTS
#FILEPATH=`echo $NAUTILUS_SCRIPT_SELECTED_URIS | sed 's@file://@@g'`
# Quote the paths
IFS=$'\n' read -d '' -r -a FILEPATH <<< "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS"
FFSEND_BIN='/usr/bin/ffsend'
FFSEND_BIN_OPTS="upload --open --copy"
ZENITY='/usr/bin/zenity '
ZENITY_PROGRESS_OPTIONS='--auto-close --auto-kill' #you can remove this if you like
#sanity checks
for sanity_check in $FFSEND_BIN "${FILEPATH[@]}"
do
ZENITY_ERROR_SANITY="There is an error, it involved $sanity_check.\n Probably binary or file missing"
if [ ! -e $sanity_check ]
then
#zenity --error --text="$(eval "echo \"$ZENITY_ERROR_SANITY\"")"
zenity --error --text="$ZENITY_ERROR_SANITY"
exit
fi
done
# Use the following flags automatically from now on
# -I: no interaction
# -f: force
# -y: yes
# -q: quiet
export FFSEND_NO_INTERACT=1 FFSEND_FORCE=1 FFSEND_YES=1 FFSEND_QUIET=1
export FFSEND_HOST=https://send.boblorange.net
export FFSEND_EXPIRY_TIME=604800
export FFSEND_DOWNLOAD_LIMIT=5
#check whether copying file or directory
if [ ! -f "${FILEPATH[@]}" ]; then
FFSEND_BIN_OPTS="$FFSEND_BIN_OPTS --archive"
fi
# Upload a file
#zenity --info --text="Ready to send: $FFSEND_BIN $FFSEND_BIN_OPTS ${FILEPATH[@]}"
$FFSEND_BIN $FFSEND_BIN_OPTS "${FILEPATH[@]}" | $($ZENITY --progress --text="sending $(basename $FILEPATH)" --pulsate $ZENITY_PROGRESS_OPTIONS)
#echo -e "$FILEPATH" | xargs -i $FFSEND_BIN $FFSEND_BIN_OPTS {} | $($ZENITY --progress --text="sending $(basename $FILEPATH)" --pulsate $ZENITY_PROGRESS_OPTIONS)
# Upload a file
#echo -e "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" | xargs -i ffsend upload --open --copy {}

View file

@ -3,7 +3,7 @@
pkgname=ffsend pkgname=ffsend
pkgver=0.2.62 pkgver=0.2.62
pkgrel=0 pkgrel=0
pkgdesc=" A fully featured Firefox Send client" pkgdesc=" A fully featured Send client"
url="https://gitlab.com/timvisee/ffsend" url="https://gitlab.com/timvisee/ffsend"
arch="x86_64 x86 armhf armv7 aarch64 ppc64le" # limited by cargo arch="x86_64 x86 armhf armv7 aarch64 ppc64le" # limited by cargo
license="GPL-3.0-only" license="GPL-3.0-only"

View file

@ -8,7 +8,7 @@
pkgname=ffsend-bin pkgname=ffsend-bin
pkgver=0.0.0 # automatically set in CI, see: /.gitlab-ci.yml pkgver=0.0.0 # automatically set in CI, see: /.gitlab-ci.yml
pkgrel=1 pkgrel=1
pkgdesc="Easily and securely share files from the command line. A Firefox Send client." pkgdesc="Easily and securely share files from the command line. A Send client."
url="https://gitlab.com/timvisee/ffsend" url="https://gitlab.com/timvisee/ffsend"
license=('GPL3') license=('GPL3')
source=("ffsend-v$pkgver::https://github.com/timvisee/ffsend/releases/download/v$pkgver/ffsend-v$pkgver-linux-x64-static" source=("ffsend-v$pkgver::https://github.com/timvisee/ffsend/releases/download/v$pkgver/ffsend-v$pkgver-linux-x64-static"
@ -27,10 +27,9 @@ optdepends=('xclip: clipboard support'
package() { package() {
cd "$srcdir" cd "$srcdir"
# Install Binary
install -Dm755 "ffsend-v$pkgver" "$pkgdir/usr/bin/ffsend" install -Dm755 "ffsend-v$pkgver" "$pkgdir/usr/bin/ffsend"
# Install shell completions and LICENSE file # Shell completions and LICENSE file
install -Dm644 "ffsend-v$pkgver.bash" "$pkgdir/usr/share/bash-completion/completions/ffsend" install -Dm644 "ffsend-v$pkgver.bash" "$pkgdir/usr/share/bash-completion/completions/ffsend"
install -Dm644 "ffsend-v$pkgver.zsh" "$pkgdir/usr/share/zsh/site-functions/_ffsend" install -Dm644 "ffsend-v$pkgver.zsh" "$pkgdir/usr/share/zsh/site-functions/_ffsend"
install -Dm644 "ffsend-v$pkgver.fish" "$pkgdir/usr/share/fish/vendor_completions.d/ffsend.fish" install -Dm644 "ffsend-v$pkgver.fish" "$pkgdir/usr/share/fish/vendor_completions.d/ffsend.fish"

View file

@ -7,31 +7,45 @@
pkgname=ffsend-git pkgname=ffsend-git
pkgver=0.0.0 # automatically set in CI, see: /.gitlab-ci.yml pkgver=0.0.0 # automatically set in CI, see: /.gitlab-ci.yml
pkgrel=1 pkgrel=1
pkgdesc="Easily and securely share files from the command line. A Firefox Send client." pkgdesc="Easily and securely share files from the command line. A Send client."
url="https://gitlab.com/timvisee/ffsend" url="https://gitlab.com/timvisee/ffsend"
license=('GPL3') license=('GPL3')
source=("ffsend::git+$url.git") source=("git+${url}")
sha256sums=('SKIP') sha256sums=('SKIP')
arch=('x86_64' 'i686') arch=('x86_64' 'i686')
provides=('ffsend') provides=('ffsend')
conflicts=('ffsend') conflicts=('ffsend')
depends=('ca-certificates') depends=('ca-certificates')
makedepends=('openssl>=1.0' 'rust>=1.39' 'cargo' 'cmake') makedepends=('cargo' 'cmake' 'openssl>=1.0')
optdepends=('xclip: clipboard support' optdepends=('xclip: clipboard support')
'bash-completion: support auto completion for bash')
prepare() {
cd "${pkgname%-git}"
cargo fetch --locked --target "$CARCH-unknown-linux-gnu"
}
build() { build() {
cd ffsend cd "${pkgname%-git}"
env CARGO_INCREMENTAL=0 cargo build --release
export RUSTUP_TOOLCHAIN=stable
export CARGO_TARGET_DIR=target
cargo build --frozen --release
}
check() {
cd "${pkgname%-git}"
export RUSTUP_TOOLCHAIN=stable
cargo test --frozen
} }
package() { package() {
cd "$srcdir/ffsend" cd "${pkgname%-git}"
# Install Binary install -Dm0755 -t "$pkgdir/usr/bin/" "target/release/ffsend"
install -Dm755 "./target/release/ffsend" "$pkgdir/usr/bin/ffsend"
# Install shell completions and LICENSE file # Shell completions and LICENSE file
install -Dm644 "contrib/completions/ffsend.bash" \ install -Dm644 "contrib/completions/ffsend.bash" \
"$pkgdir/etc/bash_completion.d/ffsend" "$pkgdir/etc/bash_completion.d/ffsend"
install -Dm644 "contrib/completions/_ffsend" \ install -Dm644 "contrib/completions/_ffsend" \

View file

@ -7,30 +7,43 @@
pkgname=ffsend pkgname=ffsend
pkgver=0.0.0 # automatically set in CI, see: /.gitlab-ci.yml pkgver=0.0.0 # automatically set in CI, see: /.gitlab-ci.yml
pkgrel=1 pkgrel=1
pkgdesc="Easily and securely share files from the command line. A Firefox Send client." pkgdesc="Easily and securely share files from the command line. A Send client."
url="https://gitlab.com/timvisee/ffsend" url="https://gitlab.com/timvisee/ffsend"
license=('GPL3') license=('GPL3')
source=("ffsend-v$pkgver.tar.gz::$url/-/archive/v$pkgver/ffsend-v$pkgver.tar.gz") # automatically set in CI, see: /.gitlab-ci.yml source=("$url/-/archive/v$pkgver/ffsend-v$pkgver.tar.gz") # automatically set in CI, see: /.gitlab-ci.yml
sha256sums=('SKIP') # automatically set in CI, see: /.gitlab-ci.yml sha256sums=('SKIP') # automatically set in CI, see: /.gitlab-ci.yml
arch=('x86_64' 'i686') arch=('x86_64' 'i686')
provides=('ffsend')
depends=('ca-certificates') depends=('ca-certificates')
makedepends=('openssl>=1.0' 'rust>=1.39' 'cargo' 'cmake') makedepends=('cargo' 'cmake' 'openssl>=1.0')
optdepends=('xclip: clipboard support' optdepends=('xclip: clipboard support')
'bash-completion: support auto completion for bash')
prepare() {
cd "$pkgname-v$pkgver"
cargo fetch --locked --target "$CARCH-unknown-linux-gnu"
}
build() { build() {
cd "ffsend-v$pkgver" cd "$pkgname-v$pkgver"
env CARGO_INCREMENTAL=0 cargo build --release
export RUSTUP_TOOLCHAIN=stable
export CARGO_TARGET_DIR=target
cargo build --frozen --release
}
check() {
cd "$pkgname-v$pkgver"
export RUSTUP_TOOLCHAIN=stable
cargo test --frozen
} }
package() { package() {
cd "$srcdir/ffsend-v$pkgver" cd "$pkgname-v$pkgver"
# Install Binary install -Dm0755 -t "$pkgdir/usr/bin/" "target/release/$pkgname"
install -Dm755 "./target/release/ffsend" "$pkgdir/usr/bin/ffsend"
# Install shell completions and LICENSE file # Shell completions and LICENSE file
install -Dm644 "contrib/completions/ffsend.bash" \ install -Dm644 "contrib/completions/ffsend.bash" \
"$pkgdir/etc/bash_completion.d/ffsend" "$pkgdir/etc/bash_completion.d/ffsend"
install -Dm644 "contrib/completions/_ffsend" \ install -Dm644 "contrib/completions/_ffsend" \

View file

@ -45,8 +45,8 @@ This is a nuspec. It mostly adheres to https://docs.nuget.org/create/Nuspec-Refe
<docsUrl>https://github.com/timvisee/ffsend</docsUrl> <docsUrl>https://github.com/timvisee/ffsend</docsUrl>
<bugTrackerUrl>https://gitlab.com/timvisee/ffsend/issues</bugTrackerUrl> <bugTrackerUrl>https://gitlab.com/timvisee/ffsend/issues</bugTrackerUrl>
<tags>ffsend firefox-send cli file-sharing file-upload encryption rust</tags> <tags>ffsend firefox-send cli file-sharing file-upload encryption rust</tags>
<summary>Easily and securely share files from the command line. A fully featured Firefox Send client.</summary> <summary>Easily and securely share files from the command line. A fully featured Send client.</summary>
<description>Easily and securely share files from the command line. A fully featured Firefox Send client.</description> <description>Easily and securely share files from the command line. A fully featured Send client.</description>
<!-- =============================== --> <!-- =============================== -->
<!-- Specifying dependencies and version ranges? https://docs.nuget.org/create/versioning#specifying-version-ranges-in-.nuspec-files --> <!-- Specifying dependencies and version ranges? https://docs.nuget.org/create/versioning#specifying-version-ranges-in-.nuspec-files -->

View file

@ -9,13 +9,13 @@ if [[ ! $TRAVIS_TAG =~ ^v([0-9]+\.)*[0-9]+$ ]]; then
fi fi
# Ensure the debian architecture is set # Ensure the debian architecture is set
if [[ -z "$DEB_ARCH" ]]; then if [[ -z $DEB_ARCH ]]; then
echo "Error: debian architecture not configured in \$DEB_ARCH" echo "Error: debian architecture not configured in \$DEB_ARCH"
exit 1 exit 1
fi fi
# Define some useful variables # Define some useful variables
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
VERSION=${TRAVIS_TAG:1} VERSION=${TRAVIS_TAG:1}
# Ensure the binary file exists # Ensure the binary file exists
@ -25,23 +25,23 @@ if [[ ! -f "$DIR/../ffsend" ]]; then
fi fi
# Create an application directory, copy the binary into it # Create an application directory, copy the binary into it
mkdir -p $DIR/ffsend-$VERSION mkdir -p "$DIR/ffsend-$VERSION"
cp $DIR/../ffsend $DIR/ffsend-$VERSION/ffsend cp -- "$DIR/../ffsend" "$DIR/ffsend-$VERSION/ffsend"
# Create an application tarbal # Create an application tarball
cd $DIR/.. cd -- "$DIR/.."
git archive --format tar.gz -o $DIR/ffsend-$VERSION/ffsend-$VERSION.tar.gz $TRAVIS_TAG git archive --format tar.gz -o "$DIR/ffsend-$VERSION/ffsend-$VERSION.tar.gz" "$TRAVIS_TAG"
# Change into the app directory # Change into the app directory
cd $DIR/ffsend-$VERSION cd -- "$DIR/ffsend-$VERSION"
# Build the debian package # Build the debian package
# TODO: define GPG? # TODO: define GPG?
dh_make -e "timvisee@gmail.com" -c gpl3 -f ffsend-$VERSION.tar.gz -s -y dh_make -e "timvisee@gmail.com" -c gpl3 -f "ffsend-$VERSION.tar.gz" -s -y
rm *.ex README.Debian README.source rm -- *.ex README.Debian README.source
# Remove the project tar ball, we're not using it anymore # Remove the project tar ball, we're not using it anymore
rm $DIR/ffsend-$VERSION/ffsend-$VERSION.tar.gz rm -- "$DIR/ffsend-$VERSION/ffsend-$VERSION.tar.gz"
# TODO: configure the debian/control file # TODO: configure the debian/control file
# TODO: configure copyright file # TODO: configure copyright file

View file

@ -2,7 +2,7 @@
# Unlink the ffs alias if it links to ffsend # Unlink the ffs alias if it links to ffsend
if [[ -L /usr/bin/ffs ]] \ if [[ -L /usr/bin/ffs ]] \
&& [[ $(ls -l /usr/bin/ffs | sed -e 's/.* -> //') == "/usr/bin/ffsend" ]]; \ && [[ $(realpath /usr/bin/ffs) == "/usr/bin/ffsend" ]]; \
then then
echo "Removing ffs alias for ffsend..." echo "Removing ffs alias for ffsend..."
unlink /usr/bin/ffs unlink /usr/bin/ffs

View file

@ -1,6 +1,6 @@
{ {
"homepage": "https://github.com/timvisee/ffsend", "homepage": "https://github.com/timvisee/ffsend",
"description": "Easily and securely share files from the command line. A fully featured Firefox Send client.", "description": "Easily and securely share files from the command line. A fully featured Send client.",
"license": "GPL-3.0-only", "license": "GPL-3.0-only",
"version": "0.0.0", "version": "0.0.0",
"architecture": { "architecture": {

View file

@ -1,4 +1,4 @@
#!/bin/bash #!/usr/bin/env bash
# Ensure svg-term is installed # Ensure svg-term is installed
if ! [ -x "$(command -v svg-term)" ]; then if ! [ -x "$(command -v svg-term)" ]; then

View file

@ -139,7 +139,7 @@ impl<'a> Download<'a> {
{ {
// Allocate an archive file, and update the download and target paths // Allocate an archive file, and update the download and target paths
if extract { if extract {
// TODO: select the extention dynamically // TODO: select the extension dynamically
let archive_extention = ".tar"; let archive_extention = ".tar";
// Allocate a temporary file to download the archive to // Allocate a temporary file to download the archive to
@ -210,7 +210,7 @@ impl<'a> Download<'a> {
/// ///
/// The full path including the name is returned. /// The full path including the name is returned.
/// ///
/// This method will check whether a file is overwitten, and whether /// This method will check whether a file is overwritten, and whether
/// parent directories must be created. /// parent directories must be created.
/// ///
/// The program will quit with an error message if a problem occurs. /// The program will quit with an error message if a problem occurs.
@ -313,7 +313,7 @@ impl<'a> Download<'a> {
// Get the path string // Get the path string
let path = target.to_str(); let path = target.to_str();
// If the path is emtpy, use the working directory with the name hint // If the path is empty, use the working directory with the name hint
let use_workdir = path.map(|path| path.trim().is_empty()).unwrap_or(true); let use_workdir = path.map(|path| path.trim().is_empty()).unwrap_or(true);
if use_workdir { if use_workdir {
match current_dir() { match current_dir() {

View file

@ -24,7 +24,7 @@ impl<'a> Completions<'a> {
let matcher_main = MainMatcher::with(self.cmd_matches).unwrap(); let matcher_main = MainMatcher::with(self.cmd_matches).unwrap();
let matcher_completions = CompletionsMatcher::with(self.cmd_matches).unwrap(); let matcher_completions = CompletionsMatcher::with(self.cmd_matches).unwrap();
// Obtian shells to generate completions for, build application definition // Obtain shells to generate completions for, build application definition
let shells = matcher_completions.shells(); let shells = matcher_completions.shells();
let dir = matcher_completions.output(); let dir = matcher_completions.output();
let quiet = matcher_main.quiet(); let quiet = matcher_main.quiet();
@ -38,14 +38,14 @@ impl<'a> Completions<'a> {
// Generate completions // Generate completions
for shell in shells { for shell in shells {
if !quiet { if !quiet {
print!( eprint!(
"Generating completions for {}...", "Generating completions for {}...",
format!("{}", shell).to_lowercase() format!("{}", shell).to_lowercase()
); );
} }
app.gen_completions(crate_name!(), shell, &dir); app.gen_completions(crate_name!(), shell, &dir);
if !quiet { if !quiet {
println!(" done."); eprintln!(" done.");
} }
} }

View file

@ -63,7 +63,7 @@ impl<'a> History<'a> {
// Remove history item // Remove history item
if let Some(url) = matcher_history.rm() { if let Some(url) = matcher_history.rm() {
// Remove item, print error if no item with URL was foudn // Remove item, print error if no item with URL was found
match history.remove_url(url) { match history.remove_url(url) {
Ok(removed) if !removed => quit_error_msg( Ok(removed) if !removed => quit_error_msg(
"could not remove item from history, no item matches given URL", "could not remove item from history, no item matches given URL",
@ -120,11 +120,8 @@ impl<'a> History<'a> {
}; };
// Define the cell values // Define the cell values
let mut cells: Vec<String> = vec![ let mut cells: Vec<String> =
format!("{}", i + 1), vec![format!("{}", i + 1), file.download_url(true).into(), expiry];
file.download_url(true).into_string(),
expiry,
];
if matcher_main.verbose() { if matcher_main.verbose() {
cells.push(owner_token); cells.push(owner_token);
} }

View file

@ -50,7 +50,7 @@ fn select_api_version(
)); ));
} }
// Propegate other errors // Propagate other errors
Err(e) => return Err(e), Err(e) => return Err(e),
} }

View file

@ -1,6 +1,6 @@
use std::env::current_dir; use std::env::current_dir;
use std::fs; use std::fs;
use std::io::Error as IoError; use std::io::{Error as IoError, Write};
use std::path::Path; use std::path::Path;
#[cfg(feature = "archive")] #[cfg(feature = "archive")]
use std::path::PathBuf; use std::path::PathBuf;
@ -19,7 +19,6 @@ use pathdiff::diff_paths;
use prettytable::{format::FormatBuilder, Cell, Row, Table}; use prettytable::{format::FormatBuilder, Cell, Row, Table};
#[cfg(feature = "qrcode")] #[cfg(feature = "qrcode")]
use qr2term::print_qr; use qr2term::print_qr;
#[cfg(feature = "archive")]
use tempfile::{Builder as TempBuilder, NamedTempFile}; use tempfile::{Builder as TempBuilder, NamedTempFile};
use super::select_api_version; use super::select_api_version;
@ -36,7 +35,7 @@ use crate::urlshorten;
use crate::util::set_clipboard; use crate::util::set_clipboard;
use crate::util::{ use crate::util::{
format_bytes, open_url, print_error, print_error_msg, prompt_yes, quit, quit_error_msg, format_bytes, open_url, print_error, print_error_msg, prompt_yes, quit, quit_error_msg,
rand_alphanum_string, ErrorHintsBuilder, rand_alphanum_string, stdin_read_file, ErrorHintsBuilder, StdinErr,
}; };
/// A file upload action. /// A file upload action.
@ -57,20 +56,49 @@ impl<'a> Upload<'a> {
let matcher_main = MainMatcher::with(self.cmd_matches).unwrap(); let matcher_main = MainMatcher::with(self.cmd_matches).unwrap();
let matcher_upload = UploadMatcher::with(self.cmd_matches).unwrap(); let matcher_upload = UploadMatcher::with(self.cmd_matches).unwrap();
// The file name to use
#[allow(unused_mut)]
let mut file_name = matcher_upload.name().map(|s| s.to_owned());
// The selected files
let mut files = matcher_upload.files();
// If file is `-`, upload from stdin
// TODO: write stdin directly to file, or directly to upload buffer
let mut tmp_stdin: Option<NamedTempFile> = None;
if files.len() == 1 && files[0] == "-" {
// Obtain data from stdin
let data = stdin_read_file(!matcher_main.quiet()).map_err(Error::Stdin)?;
// Create temporary stdin buffer file
tmp_stdin = Some(
TempBuilder::new()
.prefix(&format!(".{}-stdin-", crate_name!()))
.tempfile()
.map_err(Error::StdinTempFile)?,
);
let file = tmp_stdin.as_ref().unwrap();
// Fill temporary file with data, update list of files we upload, suggest name
file.as_file()
.write_all(&data)
.map_err(Error::StdinTempFile)?;
files = vec![file
.path()
.to_str()
.expect("failed to obtain file name for stdin buffer file")];
file_name = file_name.or_else(|| Some("stdin.txt".into()));
}
// Get API parameters // Get API parameters
#[allow(unused_mut)] #[allow(unused_mut)]
let mut paths: Vec<_> = matcher_upload let mut paths: Vec<_> = files
.files()
.into_iter() .into_iter()
.map(|p| Path::new(p).to_path_buf()) .map(|p| Path::new(p).to_path_buf())
.collect(); .collect();
let mut path = Path::new(paths.first().unwrap()).to_path_buf(); let mut path = Path::new(paths.first().unwrap()).to_path_buf();
let host = matcher_upload.host(); let host = matcher_upload.host();
// The file name to use
#[allow(unused_mut)]
let mut file_name = matcher_upload.name().map(|s| s.to_owned());
// All paths must exist // All paths must exist
// TODO: ensure the file exists and is accessible // TODO: ensure the file exists and is accessible
for path in &paths { for path in &paths {
@ -196,7 +224,7 @@ impl<'a> Upload<'a> {
// Finish the archival process, writes the archive file // Finish the archival process, writes the archive file
archiver.finish().map_err(ArchiveError::Write)?; archiver.finish().map_err(ArchiveError::Write)?;
// Append archive extention to name, set to upload archived file // Append archive extension to name, set to upload archived file
if let Some(ref mut file_name) = file_name { if let Some(ref mut file_name) = file_name {
file_name.push_str(archive_extention); file_name.push_str(archive_extention);
} }
@ -247,7 +275,7 @@ impl<'a> Upload<'a> {
// TODO: set false parameter to authentication state // TODO: set false parameter to authentication state
let max_size = upload_size_max(api_version, auth); let max_size = upload_size_max(api_version, auth);
// Get the file size, fail on emtpy files, warn about large files // Get the file size, fail on empty files, warn about large files
if let Ok(size) = path.metadata().map(|m| m.len()) { if let Ok(size) = path.metadata().map(|m| m.len()) {
// Enforce files not being 0 bytes // Enforce files not being 0 bytes
if size == 0 && !matcher_main.force() { if size == 0 && !matcher_main.force() {
@ -454,6 +482,16 @@ impl<'a> Upload<'a> {
} }
} }
// Close the temporary stdin buffer file, to ensure it's removed
if let Some(tmp_stdin) = tmp_stdin.take() {
if let Err(err) = tmp_stdin.close() {
print_error(
err.context("failed to clean up temporary stdin buffer file, ignoring")
.compat(),
);
}
}
#[cfg(feature = "archive")] #[cfg(feature = "archive")]
{ {
// Close the temporary zip file, to ensure it's removed // Close the temporary zip file, to ensure it's removed
@ -581,6 +619,14 @@ pub enum Error {
/// An error occurred while deleting a local file after upload. /// An error occurred while deleting a local file after upload.
#[fail(display = "failed to delete local file")] #[fail(display = "failed to delete local file")]
Delete(#[cause] IoError), Delete(#[cause] IoError),
/// An error occurred while reading data from stdin.
#[fail(display = "failed to read data from stdin")]
Stdin(#[cause] StdinErr),
/// An error occurred while creating the temporary stdin file.
#[fail(display = "failed to create temporary stdin buffer file")]
StdinTempFile(#[cause] IoError),
} }
impl From<VersionError> for Error { impl From<VersionError> for Error {

View file

@ -24,7 +24,7 @@ impl CmdArg for ArgApi {
.help("Server API version to use, '-' to lookup") .help("Server API version to use, '-' to lookup")
.long_help( .long_help(
"Server API version to use, one of:\n\ "Server API version to use, one of:\n\
2, 3: Firefox Send API versions\n\ 2, 3: Send API versions\n\
auto, -: probe server to determine\ auto, -: probe server to determine\
", ",
) )

View file

@ -68,6 +68,7 @@ impl CmdArg for ArgDownloadLimit {
.alias("downloads") .alias("downloads")
.alias("download") .alias("download")
.value_name("COUNT") .value_name("COUNT")
.env("FFSEND_DOWNLOAD_LIMIT")
.help("The file download limit") .help("The file download limit")
} }
} }

View file

@ -1,22 +1,16 @@
use chbs::{config::BasicConfig, prelude::*, word::WordList}; use chbs;
use clap::Arg; use clap::Arg;
use super::{CmdArg, CmdArgFlag}; use super::{CmdArg, CmdArgFlag};
/// How many words the passphrase should consist of.
const PASSPHRASE_WORDS: usize = 5;
/// The passphrase generation argument. /// The passphrase generation argument.
pub struct ArgGenPassphrase {} pub struct ArgGenPassphrase {}
impl ArgGenPassphrase { impl ArgGenPassphrase {
/// Generate a cryptographically secure passphrase that is easily /// Generate a cryptographically secure passphrase that is easily
/// rememberable using diceware. /// remembered using diceware.
pub fn gen_passphrase() -> String { pub fn gen_passphrase() -> String {
let mut config = BasicConfig::default(); chbs::passphrase()
config.words = PASSPHRASE_WORDS;
config.word_provider = WordList::builtin_eff_general_short().sampler();
config.to_scheme().generate()
} }
} }

View file

@ -8,7 +8,7 @@ pub mod owner;
pub mod password; pub mod password;
pub mod url; pub mod url;
// Re-eexport to arg module // Re-export to arg module
pub use self::api::ArgApi; pub use self::api::ArgApi;
pub use self::basic_auth::ArgBasicAuth; pub use self::basic_auth::ArgBasicAuth;
pub use self::download_limit::ArgDownloadLimit; pub use self::download_limit::ArgDownloadLimit;

View file

@ -61,8 +61,8 @@ impl<'a: 'b, 'b> Handler<'a> {
let app = App::new(crate_name!()) let app = App::new(crate_name!())
.version(crate_version!()) .version(crate_version!())
.author(crate_authors!()) .author(crate_authors!())
.about(APP_ABOUT.as_ref()) .about(APP_ABOUT.as_str())
.after_help("This application is not affiliated with Firefox or Firefox Send.") .after_help("This application is not affiliated with Firefox or Mozilla.")
.global_setting(AppSettings::GlobalVersion) .global_setting(AppSettings::GlobalVersion)
.global_setting(AppSettings::VersionlessSubcommands) .global_setting(AppSettings::VersionlessSubcommands)
// TODO: enable below command when it doesn't break `p` anymore. // TODO: enable below command when it doesn't break `p` anymore.

View file

@ -35,7 +35,7 @@ impl<'a: 'b, 'b> UploadMatcher<'a> {
let name = self.matches.value_of("name")?; let name = self.matches.value_of("name")?;
// The file name must not be empty // The file name must not be empty
// TODO: allow to force an empty name here, and process emtpy names on downloading // TODO: allow to force an empty name here, and process empty names on downloading
if name.trim().is_empty() { if name.trim().is_empty() {
quit_error_msg( quit_error_msg(
"the file name must not be empty", "the file name must not be empty",
@ -171,7 +171,7 @@ pub enum CopyMode {
} }
impl CopyMode { impl CopyMode {
/// Build the string to copy, based on the given `url` and currend mode. /// Build the string to copy, based on the given `url` and current mode.
pub fn build(&self, url: &str) -> String { pub fn build(&self, url: &str) -> String {
match self { match self {
CopyMode::Url => url.into(), CopyMode::Url => url.into(),

View file

@ -8,7 +8,7 @@ use ffsend_api::{
url::Url, url::Url,
}; };
use toml::{de::Error as DeError, ser::Error as SerError}; use toml::{de::Error as DeError, ser::Error as SerError};
use version_compare::{CompOp, VersionCompare}; use version_compare::Cmp;
use crate::util::{print_error, print_warning}; use crate::util::{print_error, print_warning};
@ -21,7 +21,7 @@ const VERSION_MAX: &str = crate_version!();
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct History { pub struct History {
/// The application version the history file was built with. /// The application version the history file was built with.
/// Used for compatability checking. /// Used for compatibility checking.
version: Option<String>, version: Option<String>,
/// The file history. /// The file history.
@ -62,9 +62,9 @@ impl History {
// Get the version number from the file // Get the version number from the file
let version = history.version.as_ref().unwrap(); let version = history.version.as_ref().unwrap();
if let Ok(true) = VersionCompare::compare_to(version, VERSION_MIN, &CompOp::Lt) { if let Ok(true) = version_compare::compare_to(version, VERSION_MIN, Cmp::Lt) {
print_warning("history file version is too old, ignoring"); print_warning("history file version is too old, ignoring");
} else if let Ok(true) = VersionCompare::compare_to(version, VERSION_MAX, &CompOp::Gt) { } else if let Ok(true) = version_compare::compare_to(version, VERSION_MAX, Cmp::Gt) {
print_warning("history file has an unknown version, ignoring"); print_warning("history file has an unknown version, ignoring");
} }
} }
@ -224,7 +224,7 @@ impl History {
/// ///
/// If the expiry property is None (thus unknown), the file will be kept. /// If the expiry property is None (thus unknown), the file will be kept.
/// ///
/// The number of exired files is returned. /// The number of expired files is returned.
pub fn gc(&mut self) -> usize { pub fn gc(&mut self) -> usize {
// Get a list of expired files // Get a list of expired files
let expired: Vec<RemoteFile> = self let expired: Vec<RemoteFile> = self

View file

@ -76,7 +76,7 @@ pub enum Error {
#[fail(display = "failed to shorten URL, got bad response")] #[fail(display = "failed to shorten URL, got bad response")]
Response(#[cause] ResponseError), Response(#[cause] ResponseError),
/// The server resonded with a malformed repsonse. /// The server responded with a malformed response.
#[fail(display = "failed to shorten URL, got malformed response")] #[fail(display = "failed to shorten URL, got malformed response")]
Malformed(#[cause] reqwest::Error), Malformed(#[cause] reqwest::Error),

View file

@ -11,11 +11,12 @@ use std::fmt;
use std::fmt::{Debug, Display}; use std::fmt::{Debug, Display};
#[cfg(feature = "clipboard-bin")] #[cfg(feature = "clipboard-bin")]
use std::io::ErrorKind as IoErrorKind; use std::io::ErrorKind as IoErrorKind;
use std::io::{self, Read};
use std::io::{stderr, stdin, Error as IoError, Write}; use std::io::{stderr, stdin, Error as IoError, Write};
use std::iter; use std::iter;
use std::path::Path; use std::path::Path;
use std::path::PathBuf; use std::path::PathBuf;
use std::process::{exit, ExitStatus}; use std::process::exit;
#[cfg(feature = "clipboard-bin")] #[cfg(feature = "clipboard-bin")]
use std::process::{Command, Stdio}; use std::process::{Command, Stdio};
@ -290,14 +291,14 @@ pub fn highlight_info(msg: &str) -> ColoredString {
} }
/// Open the given URL in the users default browser. /// Open the given URL in the users default browser.
/// The browsers exit statis is returned. /// The browsers exit status is returned.
pub fn open_url(url: impl Borrow<Url>) -> Result<ExitStatus, IoError> { pub fn open_url(url: impl Borrow<Url>) -> Result<(), IoError> {
open_path(url.borrow().as_str()) open_path(url.borrow().as_str())
} }
/// Open the given path or URL using the program configured on the system. /// Open the given path or URL using the program configured on the system.
/// The program exit statis is returned. /// The program exit status is returned.
pub fn open_path(path: &str) -> Result<ExitStatus, IoError> { pub fn open_path(path: &str) -> Result<(), IoError> {
open::that(path) open::that(path)
} }
@ -317,7 +318,7 @@ pub fn set_clipboard(content: String) -> Result<(), ClipboardError> {
/// native clipboard interface only has a lifetime of the application. This means that the /// native clipboard interface only has a lifetime of the application. This means that the
/// clipboard is instantly cleared as soon as this application quits, which is always immediately. /// clipboard is instantly cleared as soon as this application quits, which is always immediately.
/// This limitation is due to security reasons as defined by X11. The alternative binaries we set /// This limitation is due to security reasons as defined by X11. The alternative binaries we set
/// the clipboard with spawn a daemon in the background to keep the clipboad alive until it's /// the clipboard with spawn a daemon in the background to keep the clipboard alive until it's
/// flushed. /// flushed.
#[cfg(feature = "clipboard")] #[cfg(feature = "clipboard")]
#[derive(Clone, Eq, PartialEq)] #[derive(Clone, Eq, PartialEq)]
@ -490,7 +491,7 @@ pub enum ClipboardError {
#[fail(display = "failed to access clipboard using {}", _0)] #[fail(display = "failed to access clipboard using {}", _0)]
BinaryIo(&'static str, #[cause] IoError), BinaryIo(&'static str, #[cause] IoError),
/// `xclip` or `xsel` unexpectetly exited with a non-successful status code. /// `xclip` or `xsel` unexpectedly exited with a non-successful status code.
#[cfg(feature = "clipboard-bin")] #[cfg(feature = "clipboard-bin")]
#[fail( #[fail(
display = "failed to use clipboard, {} exited with status code {}", display = "failed to use clipboard, {} exited with status code {}",
@ -499,8 +500,8 @@ pub enum ClipboardError {
BinaryStatus(&'static str, i32), BinaryStatus(&'static str, i32),
} }
/// Check for an emtpy password in the given `password`. /// Check for an empty password in the given `password`.
/// If the password is emtpy the program will quit with an error unless /// If the password is empty the program will quit with an error unless
/// forced. /// forced.
// TODO: move this to a better module // TODO: move this to a better module
pub fn check_empty_password(password: &str, matcher_main: &MainMatcher) { pub fn check_empty_password(password: &str, matcher_main: &MainMatcher) {
@ -518,7 +519,7 @@ pub fn check_empty_password(password: &str, matcher_main: &MainMatcher) {
/// Prompt the user to enter a password. /// Prompt the user to enter a password.
/// ///
/// If `empty` is `false`, emtpy passwords aren't allowed unless forced. /// If `empty` is `false`, empty passwords aren't allowed unless forced.
pub fn prompt_password(main_matcher: &MainMatcher, optional: bool) -> Option<String> { pub fn prompt_password(main_matcher: &MainMatcher, optional: bool) -> Option<String> {
// Quit with an error if we may not interact // Quit with an error if we may not interact
if !optional && main_matcher.no_interact() { if !optional && main_matcher.no_interact() {
@ -548,7 +549,7 @@ pub fn prompt_password(main_matcher: &MainMatcher, optional: bool) -> Option<Str
} }
} }
// On input error, propegate the error or don't use a password if optional // On input error, propagate the error or don't use a password if optional
Err(err) => { Err(err) => {
if !optional { if !optional {
quit_error( quit_error(
@ -591,7 +592,7 @@ pub fn ensure_password(
return false; return false;
} }
// Check whehter we allow interaction // Check whether we allow interaction
let interact = !main_matcher.no_interact(); let interact = !main_matcher.no_interact();
loop { loop {
@ -760,7 +761,7 @@ pub fn ensure_owner_token(
main_matcher: &MainMatcher, main_matcher: &MainMatcher,
optional: bool, optional: bool,
) -> bool { ) -> bool {
// Check whehter we allow interaction // Check whether we allow interaction
let interact = !main_matcher.no_interact(); let interact = !main_matcher.no_interact();
// Notify that an owner token is required // Notify that an owner token is required
@ -983,7 +984,7 @@ pub fn ensure_enough_space<P: AsRef<Path>>(path: P, size: u64) {
} }
}; };
// Return if enough disk space is avaiable // Return if enough disk space is available
if space >= size { if space >= size {
return; return;
} }
@ -1131,3 +1132,27 @@ pub fn rand_alphanum_string(len: usize) -> String {
.take(len) .take(len)
.collect() .collect()
} }
/// Read file from stdin.
pub fn stdin_read_file(prompt: bool) -> Result<Vec<u8>, StdinErr> {
if prompt {
#[cfg(not(windows))]
eprintln!("Enter input. Use [CTRL+D] to stop:");
#[cfg(windows)]
eprintln!("Enter input. Use [CTRL+Z] to stop:");
}
let mut data = vec![];
io::stdin()
.lock()
.read_to_end(&mut data)
.map_err(StdinErr::Stdin)?;
Ok(data)
}
/// URL following error.
#[derive(Debug, Fail)]
pub enum StdinErr {
#[fail(display = "failed to read from stdin")]
Stdin(#[cause] io::Error),
}